76 lines
1.9 KiB
Go
76 lines
1.9 KiB
Go
package qrcode
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"time"
|
|
|
|
"lone-services/pkg/utils"
|
|
"lone-services/pkg/wechat/auth"
|
|
)
|
|
|
|
// 小程序码(有数量限制):https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/qr-code/getQRCode.html
|
|
const wxaCodeURL = "https://api.weixin.qq.com/wxa/getwxacode"
|
|
|
|
// BuildPath 拼小程序 path,如 pagesB/userLogin/index?session_id=xxx
|
|
func BuildPath(page string, params map[string]string) string {
|
|
if len(params) == 0 {
|
|
return page
|
|
}
|
|
query := url.Values{}
|
|
for k, v := range params {
|
|
query.Add(k, v)
|
|
}
|
|
return page + "?" + query.Encode()
|
|
}
|
|
|
|
// GetWxaCode 使用已有 access_token 生成有限小程序码,成功返回图片二进制。
|
|
func (c *Client) GetWxaCode(accessToken string, req *WxaCodeRequest) ([]byte, error) {
|
|
if accessToken == utils.StringEmpty {
|
|
return nil, fmt.Errorf("wechat access_token empty")
|
|
}
|
|
if req == nil || req.Path == utils.StringEmpty {
|
|
return nil, fmt.Errorf("wechat qrcode path empty")
|
|
}
|
|
|
|
payload, err := json.Marshal(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
apiURL := fmt.Sprintf("%s?access_token=%s", wxaCodeURL, accessToken)
|
|
httpClient := &http.Client{Timeout: 15 * time.Second}
|
|
resp, err := httpClient.Post(apiURL, "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
|
|
}
|
|
|
|
// CreateWxaCode 通过 auth 拉取 access_token 后生成有限小程序码。
|
|
func (c *Client) CreateWxaCode(ctx context.Context, req *WxaCodeRequest) ([]byte, error) {
|
|
token, err := auth.NewClient(c.AppID, c.Secret).AccessToken(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return c.GetWxaCode(token.AccessToken, req)
|
|
}
|