package svc import ( "crypto/aes" "crypto/cipher" "encoding/base64" "encoding/json" "fmt" "time" "git.i2edu.net/i2/i2-bill-api/internal/config" "git.i2edu.net/i2/i2-bill-api/internal/utils" "git.i2edu.net/i2/i2-bill-api/model" ) // Wechat defined type Wechat struct { RdCli Cache c config.Config } // WechatPhonedecrypt defined TODO type WechatPhonedecrypt struct { PhoneNumber string `json:"phoneNumber"` PurePhoneNumber string `json:"purePhoneNumber"` CountryCode string `json:"countryCode"` Watermark struct { Appid string `json:"appid"` Timestamp int32 `json:"timestamp"` } `json:"watermark"` } // GetAccessToken defined TODO func (wc *Wechat) GetAccessToken() (string, error) { token := "" err := wc.RdCli.GetCache(cacheWechatTokenPrefix, &token) if err == model.ErrRdsNotFound || token == "" { req := utils.Get("https://api.weixin.qq.com/cgi-bin/token") req.Param("grant_type", "client_credential") req.Param("secret", wc.c.Weixin.Secret) req.Param("appid", wc.c.Weixin.Appid) var res = struct { AccessToken string `json:"access_token"` ExpiresIn int `json:"expires_in"` }{} err = req.ToJSON(&res) if err != nil { return "", err } token = res.AccessToken err := wc.RdCli.SetWithExpire(cacheWechatTokenPrefix, res.AccessToken, time.Duration((res.ExpiresIn-60*2))*time.Second) if err != nil { return "", err } } return token, nil } // GenQrId defined TODO func (wc *Wechat) GenQrId(prefix string, params interface{}) (string, error) { ube, err := json.Marshal(params) hashCode := utils.HashCode(string(ube)) if err != nil { return "", err } err = wc.RdCli.SetWithExpire(fmt.Sprintf(prefix, hashCode), string(ube), time.Duration(1)*time.Hour) return fmt.Sprintf("%v", hashCode), err } // GenUserQrId defined TODO func (wc *Wechat) GenUserQrId(prefix string, userId int64, params interface{}) (string, error) { ube, err := json.Marshal(params) hashCode := utils.HashCode(string(ube)) if err != nil { return "", err } qrId := fmt.Sprintf("u%v-%v", userId, hashCode) err = wc.RdCli.SetWithExpire(fmt.Sprintf(prefix, qrId), string(ube), time.Duration(1)*time.Hour) return qrId, err } // GetQrParams defined TODO func (wc *Wechat) GetQrParams(prefix string, id string, params interface{}) error { ube := "" err := wc.RdCli.GetCache(fmt.Sprintf(prefix, id), &ube) if err != nil { return err } err = json.Unmarshal([]byte(ube), params) if err != nil { return err } return err } // GetQrParams defined TODO func (wc *Wechat) DecryptMobile(sessionKey, encryptedData, iv string) (string, error) { key, err := base64.StdEncoding.DecodeString(sessionKey) if err != nil { return "", err } bIv, err := base64.StdEncoding.DecodeString(iv) if err != nil { return "", err } bEncryptedData, err := base64.StdEncoding.DecodeString(encryptedData) if err != nil { return "", err } block, err := aes.NewCipher(key) if err != nil { return "", err } var decrypt = bEncryptedData blockMode := cipher.NewCBCDecrypter(block, bIv) blockMode.CryptBlocks(decrypt, bEncryptedData) length := len(decrypt) unpadding := int(decrypt[length-1]) decData := decrypt[:(length - unpadding)] decryptData := WechatPhonedecrypt{} err = json.Unmarshal(decData, &decryptData) if err != nil { return "", err } return decryptData.PhoneNumber, err } // GenQrCode defined TODO func (wc *Wechat) GenQrCode(scene, page string) (*model.I2billSysAttachment, error) { token, err := wc.GetAccessToken() if err != nil { return nil, err } req := utils.Post("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + token) req.JSONBody(map[string]interface{}{"scene": scene, "page": page, "is_hyaline": true}) resp, err := req.Response() if err != nil { return nil, err } defer resp.Body.Close() oss, err := GetAliYunOssInstance() if err != nil { return nil, err } return oss.UploadRead(resp.Body, ".png") }