package wechat import ( "encoding/json" "fmt" "net/http" "bindbox-game/internal/pkg/httpclient" ) // SchemeRequest 获取小程序 Scheme 码请求参数 type SchemeRequest struct { JumpWxa JumpWxa `json:"jump_wxa,omitempty"` IsExpire bool `json:"is_expire,omitempty"` // false:永久有效,true:到期失效 ExpireTime int64 `json:"expire_time,omitempty"` // 到期失效的 scheme 码的失效时间,为 Unix 时间戳 ExpireType int `json:"expire_type,omitempty"` // 失效时间类型,0-失效时间,1-失效间隔天数 ExpireInterval int `json:"expire_interval,omitempty"` // 失效间隔天数 } type JumpWxa struct { Path string `json:"path"` Query string `json:"query"` EnvVersion string `json:"env_version,omitempty"` // release, trial, develop } // SchemeResponse 获取小程序 Scheme 码响应 type SchemeResponse struct { OpenLink string `json:"openlink"` ErrCode int `json:"errcode"` ErrMsg string `json:"errmsg"` } // GenerateScheme 获取小程序 Scheme 码 // path: 页面路径,如 "pages/index/index" // query: 参数,如 "id=1" (可为空) // envVersion: 要打开的小程序版本,默认 release func GenerateScheme(accessToken string, path string, query string, envVersion string) (string, error) { if accessToken == "" { return "", fmt.Errorf("access_token 不能为空") } url := fmt.Sprintf("https://api.weixin.qq.com/wxa/generatescheme?access_token=%s", accessToken) if envVersion == "" { envVersion = "release" } reqBody := SchemeRequest{ JumpWxa: JumpWxa{ Path: path, Query: query, EnvVersion: envVersion, }, IsExpire: false, // 默认生成永久有效的(注意:永久有效每天有上限,短期有效无上限但需设置过期) // 如果需要生成短期,可以改为 true 并设置 ExpireInterval/ExpireTime } // 强制使用短期有效以避免消耗额度(如果需要)? // 官方文档:永久有效 Scheme 每天上限 50w,短期无上限。 // 为了稳健,默认使用短期(30天)?或者让调用者决定。 // 这里先简单实现为默认短期(30天),避免额度问题。 reqBody.IsExpire = true reqBody.ExpireType = 1 reqBody.ExpireInterval = 30 requestBody, err := json.Marshal(reqBody) if err != nil { return "", fmt.Errorf("序列化请求参数失败: %v", err) } resp, err := httpclient.GetHttpClient().R(). SetHeader("Content-Type", "application/json"). SetBody(requestBody). Post(url) if err != nil { return "", fmt.Errorf("发送HTTP请求失败: %v", err) } if resp.StatusCode() != http.StatusOK { return "", fmt.Errorf("HTTP请求失败,状态码: %d", resp.StatusCode()) } var sResp SchemeResponse if err := json.Unmarshal(resp.Body(), &sResp); err != nil { return "", fmt.Errorf("解析响应失败: %v", err) } if sResp.ErrCode != 0 { return "", fmt.Errorf("获取Scheme失败: errcode=%d, errmsg=%s", sResp.ErrCode, sResp.ErrMsg) } return sResp.OpenLink, nil }