| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- package exchange
- import (
- "encoding/json"
- "fmt"
- "github.com/demdxx/gocast"
- "strings"
- "time"
- )
- // doc: https://dsgxajqzhgq3.sg.larksuite.com/wiki/Xxp0wsLKmiZFB3kRqJYl3cqlgHb
- // 平台授权链接
- // 正式环境跳转地址为配置项目 为兼容测试环境/web环境 当无法获得指定跳转地址则使用默认root_url
- // root_url
- func AuthRoot() string {
- return conf().RootUrl
- }
- // 测试环境使用
- func AuthUrl(redirectUri string, args ...string) string {
- uri := AuthUri(redirectUri, args...)
- return ToPath(conf().RootUrl, uri)
- }
- func NoDomainAuthUrl(redirectUri string, args ...string) string {
- realRedirect := conf().RedirectUrl
- if redirectUri != "" {
- realRedirect = redirectUri
- }
- // 自动跳转 scope=snsapi_base
- //uri := fmt.Sprintf("/zh-CN/application-center/authorize?scope=snsapi_base&appid=%s&redirect_uri=%s", conf().Appid, realRedirect)
- uri := fmt.Sprintf("/zh-CN/application-center/authorize?appid=%s&redirect_uri=%s", conf().Appid, realRedirect)
- if len(args) > 0 {
- //uri = fmt.Sprintf("/zh-CN/application-center/authorize?scope=snsapi_base&appid=%s&redirect_uri=%s&state=%s", conf().Appid, realRedirect, strings.Join(args, ""))
- uri = fmt.Sprintf("/zh-CN/application-center/authorize?appid=%s&redirect_uri=%s&state=%s", conf().Appid, realRedirect, strings.Join(args, ""))
- }
- return uri
- }
- // uri
- func AuthUri(redirectUri string, args ...string) string {
- realRedirect := conf().RedirectUrl
- if redirectUri != "" {
- realRedirect = redirectUri
- }
- // 自动跳转 scope=snsapi_base
- //uri := fmt.Sprintf("/zh-CN/application-center/authorize?scope=snsapi_base&appid=%s&redirect_uri=%s", conf().Appid, realRedirect)
- uri := fmt.Sprintf("/zh-CN/application-center/authorize?appid=%s&redirect_uri=%s", conf().Appid, realRedirect)
- if len(args) > 0 {
- //uri = fmt.Sprintf("/zh-CN/application-center/authorize?scope=snsapi_base&appid=%s&redirect_uri=%s&state=%s", conf().Appid, realRedirect, strings.Join(args, ""))
- uri = fmt.Sprintf("/zh-CN/application-center/authorize?appid=%s&redirect_uri=%s&state=%s", conf().Appid, realRedirect, strings.Join(args, ""))
- }
- return uri
- }
- // ToPath 转化成路径
- func ToPath(args ...string) string {
- if len(args) == 0 {
- return ""
- }
- strList := make([]string, 0)
- for i, p := range args {
- if strings.TrimSpace(p) == "" {
- continue
- }
- if i == 0 {
- strList = append(strList, strings.TrimRight(strings.TrimSpace(p), "/"))
- continue
- }
- strList = append(strList, strings.Trim(strings.TrimSpace(p), "/"))
- }
- return strings.Join(strList, "/")
- }
- // 通过code换取授权access_token
- type AccessTokenResp struct {
- Code int `json:"code"`
- Msg string `json:"msg"`
- Data struct {
- AccessToken string `json:"accessToken"`
- OpenId string `json:"openId"`
- NickName string `json:"nickName"`
- AvatarUrl string `json:"avatarUrl"`
- RefreshToken string `json:"refreshToken"`
- UserId int64 `json:"userId"`
- } `json:"data"`
- }
- func AccessToken(code string) (*AccessTokenResp, error) {
- uri := "/v1/third/open/oauth2/access_token"
- uri = fmt.Sprintf("%s?appId=%s&appSecret=%s&code=%s", uri, conf().Appid, conf().Secret, code)
- // get request
- uri = ToPath(conf().RootUrl, uri)
- return get[AccessTokenResp](uri)
- }
- type GetUserInfoReq struct {
- AppId string `json:"appId"`
- //OpenId string `json:"openId"`
- UserId string `json:"userId"`
- Timestamp string `json:"timestamp"`
- Sign string `json:"sign"`
- }
- type ExchangeUserInfo struct {
- InviteCode string `json:"inviteCode"`
- ParentInviteCode string `json:"parentInviteCode"`
- ParentUserId int64 `json:"parentUserId"`
- }
- type UserInfoResp struct {
- Code int `json:"code"`
- Msg string `json:"msg"`
- Data *ExchangeUserInfo `json:"data"`
- }
- func GetUserInviteInfo(userID string) (*ExchangeUserInfo, error) {
- uri := "/v1/act/public/application/third/invite-info"
- url := ToPath(conf().RootUrl, uri)
- req := &GetUserInfoReq{
- AppId: conf().Appid,
- UserId: userID,
- Timestamp: fmt.Sprintf("%d", time.Now().UnixMilli()),
- }
- reqMap, err := structToJSONMap(req)
- if err != nil {
- return nil, err
- }
- sign := signMd5(reqMap)
- req.Sign = sign
- data, _ := json.Marshal(&req)
- t, err := post[UserInfoResp](url, data)
- if err != nil {
- return nil, err
- }
- if t != nil && t.Data != nil && t.Code == 200 {
- return t.Data, nil
- }
- return nil, fmt.Errorf("exchange msg:%s code:%d", t.Msg, t.Code)
- }
- // 刷新access_token(如果需要) get
- type RefreshTokenResp struct {
- Code int `json:"code"`
- Msg string `json:"msg"`
- Data struct {
- AccessToken string `json:"accessToken"`
- OpenId string `json:"openId"`
- RefreshToken string `json:"refreshToken"`
- } `json:"data"`
- }
- func RefreshToken(refreshToken string) (*RefreshTokenResp, error) {
- uri := "/v1/third/open/oauth2/refresh_token"
- uri = fmt.Sprintf("%s?appId=%s&refresh_token=%s", uri, conf().Appid, refreshToken)
- uri = ToPath(conf().RootUrl, uri)
- return get[RefreshTokenResp](uri)
- }
- // 检验access_token是否有效 get
- type CheckAccessTokenResp struct {
- Code int `json:"code"`
- Msg string `json:"msg"`
- Data bool `json:"data"`
- }
- func Auth(token string) (*CheckAccessTokenResp, error) {
- uri := "/v1/third/open/oauth2/auth"
- uri = fmt.Sprintf("%s?accessToken=%s", uri, token)
- uri = ToPath(conf().RootUrl, uri)
- return get[CheckAccessTokenResp](uri)
- }
- // 获取用户推荐码
- type UserInviteInfoResp struct {
- Code int `json:"code"`
- Msg string `json:"msg"`
- Data struct {
- InviteCode string `json:"inviteCode"`
- } `json:"data"`
- }
- // openId 查询邀请码
- // 通过openId 获取上级信息 openId 查询邀请码以及上级邀请码和openId
- // /v1/act/public/application/third/invite-info-by-openid
- type SignParam struct {
- AppId string `json:"appId,omitempty"`
- OpenId string `json:"openId,omitempty"`
- Timestamp string `json:"timestamp,omitempty"`
- }
- type GetUserInviteInfoReq struct {
- AppId string `json:"appId,omitempty"`
- OpenId string `json:"openId,omitempty"`
- Timestamp string `json:"timestamp,omitempty"`
- Sign string `json:"sign,omitempty"`
- }
- type GetInviteInfoByOpenIdResp struct {
- Code int `json:"code"`
- Msg string `json:"msg"`
- Data struct {
- InviteCode string `json:"inviteCode"`
- ParentInviteCode string `json:"parentInviteCode"`
- ParentOpenId string `json:"parentOpenId"`
- } `json:"data"`
- }
- func GetInviteInfoByOpenId(openId string) (*GetInviteInfoByOpenIdResp, error) {
- uri := "/v1/act/public/application/third/invite-info-by-openid"
- uri = ToPath(conf().RootUrl, uri)
- timestamp := time.Now().UnixMilli()
- req := new(GetUserInviteInfoReq)
- req.Timestamp = gocast.ToString(timestamp)
- req.AppId = conf().Appid
- req.OpenId = openId
- reqMap, err := structToJSONMap(req)
- if err != nil {
- return nil, err
- }
- sign := signMd5(reqMap)
- req.Sign = sign
- data, _ := json.Marshal(&req)
- return post[GetInviteInfoByOpenIdResp](uri, data)
- }
|