// Package activitylanding 生成活动模板的稳定 H5 落地页地址。 package activitylanding import ( "fmt" "net/url" "strings" ) // Builder 只保存通用 H5 壳地址;模板内容始终由 activity-service 的已发布 // 运行态提供,避免模板编辑时覆盖 COS 对象并引入 CDN 缓存竞态。 type Builder struct { base *url.URL } func New(baseURL string) (*Builder, error) { parsed, err := url.Parse(strings.TrimSpace(baseURL)) if err != nil || parsed.Scheme == "" || parsed.Host == "" || (parsed.Scheme != "http" && parsed.Scheme != "https") { return nil, fmt.Errorf("activity template h5 base url is invalid") } return &Builder{base: parsed}, nil } // URL 使用不可变 template_code 作为页面身份;已有 env/token/lang 参数由 App // 打开 WebView 时继续追加,生成器不替运营端伪造用户运行环境。 func (b *Builder) URL(appCode string, templateCode string) (string, error) { if b == nil || b.base == nil { return "", fmt.Errorf("activity template h5 url builder is unavailable") } appCode = strings.ToLower(strings.TrimSpace(appCode)) templateCode = strings.ToLower(strings.TrimSpace(templateCode)) if appCode == "" || templateCode == "" { return "", fmt.Errorf("activity template h5 identity is incomplete") } landing := *b.base query := landing.Query() query.Set("app_code", appCode) query.Set("template_code", templateCode) landing.RawQuery = query.Encode() return landing.String(), nil }