package qrcode import ( "bytes" "context" "encoding/base64" "encoding/json" "errors" "fmt" "io" "net/http" "strings" "time" "lone-services/pkg/utils" "lone-services/pkg/wechat/auth" ) const unlimitedURL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit" func (c *Client) GetUnlimited(accessToken string, req *UnlimitedRequest) ([]byte, error) { if accessToken == utils.StringEmpty { return nil, fmt.Errorf("wechat access_token empty") } if req == nil || req.Scene == utils.StringEmpty { return nil, fmt.Errorf("wechat qrcode scene empty") } payload, err := json.Marshal(req) if err != nil { return nil, err } url := fmt.Sprintf("%s?access_token=%s", unlimitedURL, accessToken) httpClient := &http.Client{Timeout: 15 * time.Second} resp, err := httpClient.Post(url, "application/json", bytes.NewReader(payload)) if err != nil { return nil, err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return nil, err } if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("wechat qrcode http status %d", resp.StatusCode) } if err := parseImageOrError(body); err != nil { return nil, err } return body, nil } func (c *Client) CreateUnlimited(ctx context.Context, req *UnlimitedRequest) ([]byte, error) { token, err := auth.NewClient(c.AppID, c.Secret).AccessToken(ctx) if err != nil { return nil, err } return c.GetUnlimited(token.AccessToken, req) } func (c *Client) CreateUnlimitedBase64(ctx context.Context, req *UnlimitedRequest) (string, error) { img, err := c.CreateUnlimited(ctx, req) if err != nil { return "", err } return base64.StdEncoding.EncodeToString(img), nil } func parseImageOrError(body []byte) error { trim := bytes.TrimSpace(body) if len(trim) == 0 { return fmt.Errorf("wechat qrcode empty response") } if trim[0] == '{' || strings.HasPrefix(string(trim), "{\"errcode\"") { var errBody apiErrorBody if err := json.Unmarshal(trim, &errBody); err != nil { return fmt.Errorf("wechat qrcode invalid error body: %w", err) } if errBody.ErrCode != utils.NumberZero { return errors.New(errBody.ErrMsg) } return fmt.Errorf("wechat qrcode unexpected json response") } return nil }