diff --git a/platformapi/enterprise_wechat/create_group.go b/platformapi/enterprise_wechat/create_group.go new file mode 100644 index 00000000..9b5c6715 --- /dev/null +++ b/platformapi/enterprise_wechat/create_group.go @@ -0,0 +1,18 @@ +package enterprise_wechat + +type CreateGroup struct { + AccessToken string `json:"access_token"` // 调用接口凭证 [必填] + Scene int `json:"scene"` // 1 - 群的小程序插件, 2 - 群的二维码插件 [必填] + ChatIDList []string `json:"chat_id_list"` // 使用该配置的客户群ID列表,支持5个 [必填] + + Remark string `json:"remark"` // 联系方式的备注信息,用于助记,超过30个字符将被截断 + AutoCreateRoom int `json:"auto_create_room"` // 当群满了后,是否自动新建群。0-否;1-是。 默认为1 + RoomBaseName string `json:"room_base_name"` // 自动建群的群名前缀 + RoomBaseID int `json:"room_base_id"` // 自动建群的群起始序号 + State string `json:"state"` // 企业自定义的state参数,用于区分不同的入群渠道。 +} + +// 创建客户入群方式 +func (a *API) CreateUserGroup() { + +} diff --git a/platformapi/enterprise_wechat/enterprise_test.go b/platformapi/enterprise_wechat/enterprise_test.go new file mode 100644 index 00000000..b71d17e6 --- /dev/null +++ b/platformapi/enterprise_wechat/enterprise_test.go @@ -0,0 +1,40 @@ +package enterprise_wechat + +import ( + "fmt" + "git.rosy.net.cn/baseapi" + "go.uber.org/zap" + "testing" +) + +var ( + api *API + sugarLogger *zap.SugaredLogger +) + +func init() { + logger, _ := zap.NewDevelopment() + sugarLogger = logger.Sugar() + baseapi.Init(sugarLogger) + api = New("ww9a156bfa070e1857", "JQsEmSTltHhNgdPIT320YJFphiYmRs-YZa-rCBwplss") + //api = New("6705486294797503379", "c1e6c280-e618-4103-9d0a-673bc54fb22e", "5375691", "cabrXQf9eFMVWVYg4hNlwu") + //token, _ := api.GetAccessToken() + //api.accessToken = token.BusinessDataObj.AccessToken +} + +func TestGetToken(t *testing.T) { + api = New("ww9a156bfa070e1857", "JQsEmSTltHhNgdPIT320YJFphiYmRs-YZa-rCBwplss") + token, err := api.GetAccessToken() + if err != nil { + fmt.Println("err=", err) + } + fmt.Println("errmsg:=", token.ErrMsg) + fmt.Println("errmsg:=", token.AccessToken) + fmt.Println("errmsg:=", token.ExpiresIn) + fmt.Println("errmsg api token:=", api.accessToken) + fmt.Println("errmsg api expiresin time:=", api.expiresIn) +} + +func TestAPI_GetDepartmentList(t *testing.T) { + +} diff --git a/platformapi/enterprise_wechat/wechat_client.go b/platformapi/enterprise_wechat/wechat_client.go new file mode 100644 index 00000000..b20192b6 --- /dev/null +++ b/platformapi/enterprise_wechat/wechat_client.go @@ -0,0 +1,122 @@ +package enterprise_wechat + +import ( + "encoding/json" + "errors" + "fmt" + "git.rosy.net.cn/baseapi" + "git.rosy.net.cn/baseapi/platformapi" + "git.rosy.net.cn/baseapi/utils" + "net/http" + "strings" + "sync" + "time" +) + +func New(corpId, corpSecret string, config ...*platformapi.APIConfig) *API { + curConfig := platformapi.DefAPIConfig + if len(config) > 0 { + curConfig = *config[0] + } + + return &API{ + corpId: corpId, + corpSecret: corpSecret, + locker: sync.RWMutex{}, + client: &http.Client{Timeout: curConfig.ClientTimeout}, + config: &curConfig, + } +} + +// 获取token +type EnterpriseToken struct { + PublicCode + AccessToken string `json:"access_token"` // 权限说明 + ExpiresIn int64 `json:"expires_in"` // 过期时间 +} + +func (a *API) SetToken(token string) { + a.locker.Lock() + defer a.locker.Unlock() + a.accessToken = token +} + +func (a *API) SetExpiresInTime(int2 int64) { + a.locker.Lock() + defer a.locker.Unlock() + a.expiresIn = time.Now().Unix() + int2 +} + +// 获取access_token +func (a *API) GetAccessToken() (tokenInfo *EnterpriseToken, err error) { + parameter := make(map[string]interface{}, 2) + parameter["corpid"] = a.corpId + parameter["corpsecret"] = a.corpSecret + + result, err := a.AccessAPI(WeChatBaseApi, GetToken, http.MethodGet, parameter) + if err != nil { + return nil, err + } + + accessToken := &EnterpriseToken{} + if err := utils.Map2StructByJson(result, &accessToken, false); err != nil { + return nil, err + } + if accessToken.ErrCode != 0 { + return nil, errors.New(accessToken.ErrMsg) + } + a.SetToken(accessToken.AccessToken) + a.SetExpiresInTime(accessToken.ExpiresIn) + return accessToken, err +} + +// 数据发送 +func (a *API) AccessAPI(baseUrl, actionApi, method string, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) { + bizParams["access_token"] = a.accessToken + data, err := json.Marshal(bizParams) // 序列化 + if err != nil { + return nil, err + } + + // 全路径请求参数 + fullURL := utils.GenerateGetURL(baseUrl, actionApi, nil) + + // 发送请求 + sendUrl := func() *http.Request { + var request *http.Request + if http.MethodPost == method { + request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(string(data))) + } else { + request, _ = http.NewRequest(http.MethodGet, utils.GenerateGetURL(baseUrl, actionApi, bizParams), nil) + } + request.Header.Set("Content-Type", "application/json") + return request + } + + // 数据解析 + dataMarshal := func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) { + if jsonResult1 == nil { + return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil") + } + if err != nil { + return "", err + } + if utils.MustInterface2Int64(jsonResult1["errcode"]) != 0 { + errLevel = platformapi.ErrLevelGeneralFail + err = utils.NewErrorCode(jsonResult1["errmsg"].(string), utils.Int64ToStr(utils.MustInterface2Int64(jsonResult1["errcode"]))) + baseapi.SugarLogger.Debugf("enterprise wechat AccessAPI failed, jsonResult1:%s", utils.Format4Output(jsonResult1, true)) + } + retVal = jsonResult1 + return errLevel, err + } + + err = platformapi.AccessPlatformAPIWithRetry(a.client, sendUrl, a.config, dataMarshal) + return retVal, err +} + +func (a *API) CheckAccessTokenExpiresIn() { + if a.expiresIn == 0 || a.expiresIn <= time.Now().Unix() { + a.GetAccessToken() + } + return +} diff --git a/platformapi/enterprise_wechat/wechat_model.go b/platformapi/enterprise_wechat/wechat_model.go new file mode 100644 index 00000000..c5db8ac3 --- /dev/null +++ b/platformapi/enterprise_wechat/wechat_model.go @@ -0,0 +1,32 @@ +package enterprise_wechat + +import ( + "git.rosy.net.cn/baseapi/platformapi" + "net/http" + "sync" +) + +const ( + WeChatBaseApi = "https://qyapi.weixin.qq.com" // 企业微信基础访问链接 + + // api接口 + GetToken = "cgi-bin/gettoken" // 获取token +) + +// 注册请求api +type API struct { + corpId string // 企业号 + corpSecret string // 秘钥 + accessToken string // token + expiresIn int64 // token过期时间 + locker sync.RWMutex + client *http.Client + config *platformapi.APIConfig +} + +// 公共错误码 +type PublicCode struct { + ErrCode int `json:"errcode"` // 错误码 + ErrMsg string `json:"errmsg"` // 错误消息 + +} diff --git a/platformapi/mtpsapi/riderInfo.go b/platformapi/mtpsapi/riderInfo.go index cb697205..2ebaab96 100644 --- a/platformapi/mtpsapi/riderInfo.go +++ b/platformapi/mtpsapi/riderInfo.go @@ -1,10 +1,10 @@ package mtpsapi const ( - DaDaCode = 10002 // 达达配送 - FnPsCode = 10004 // 蜂鸟配送 - MTPsCode = 10032 // 美团配送 - MyselfPsCode = 10015 // 自送 + DaDaCode = "10002" // 达达配送 + FnPsCode = "10004" // 蜂鸟配送 + MTPsCode = "10032" // 美团配送 + MyselfPsCode = "10015" // 自送 ) type RiderInfo struct {