diff --git a/service/oauth/gitee/api_user.go b/service/gitee/api.v5.user.go similarity index 59% rename from service/oauth/gitee/api_user.go rename to service/gitee/api.v5.user.go index 65df36d9..8babe13c 100644 --- a/service/oauth/gitee/api_user.go +++ b/service/gitee/api.v5.user.go @@ -3,11 +3,12 @@ package gitee import ( "encoding/json" "fmt" + "go.dtapp.net/library/utils/gorequest" + "net/http" "time" ) -// UserResult 返回参数 -type UserResult struct { +type ApiV5UserResponse struct { Id int64 `json:"id"` Login string `json:"login"` Name string `json:"name"` @@ -38,16 +39,26 @@ type UserResult struct { Email string `json:"email"` } -// User 获取授权用户的资料 https://gitee.com/api/v5/swagger#/getV5User -func (app *App) User() (result UserResult, err error) { - // request - body, err := app.request(fmt.Sprintf("https://gitee.com/api/v5/user?access_token=%s", app.AccessToken), map[string]interface{}{}, "GET") +type ApiV5UserResult struct { + Result ApiV5UserResponse // 结果 + Body []byte // 内容 + Http gorequest.Response // 请求 + Err error // 错误 +} + +func newApiV5UserResult(result ApiV5UserResponse, body []byte, http gorequest.Response, err error) *ApiV5UserResult { + return &ApiV5UserResult{Result: result, Body: body, Http: http, Err: err} +} - if err != nil { - return - } - if err = json.Unmarshal(body, &result); err != nil { - return - } - return +// ApiV5User 获取授权用户的资料 +// https://gitee.com/api/v5/swagger#/getV5User +func (c *Client) ApiV5User(accessToken string) *ApiV5UserResult { + // 参数 + params := gorequest.NewParamsWith() + // 请求 + request, err := c.request(apiUrl+fmt.Sprintf("/api/v5/user?access_token=%s", accessToken), params, http.MethodGet) + // 定义 + var response ApiV5UserResponse + err = json.Unmarshal(request.ResponseBody, &response) + return newApiV5UserResult(response, request.ResponseBody, request, err) } diff --git a/service/gitee/client.go b/service/gitee/client.go new file mode 100644 index 00000000..6f5c30e3 --- /dev/null +++ b/service/gitee/client.go @@ -0,0 +1,40 @@ +package gitee + +import ( + "go.dtapp.net/library/utils/golog" + "go.dtapp.net/library/utils/gorequest" + "gorm.io/gorm" +) + +type ConfigClient struct { + ClientID string + ClientSecret string + RedirectUri string + PgsqlDb *gorm.DB // 日志数据库 +} + +type Client struct { + client *gorequest.App // 请求客户端 + log *golog.ApiClient // 日志服务 + config *ConfigClient // 配置 +} + +func NewClient(config *ConfigClient) (*Client, error) { + + var err error + c := &Client{config: config} + + c.client = gorequest.NewHttp() + + if c.config.PgsqlDb != nil { + c.log, err = golog.NewApiClient( + golog.WithGormClient(c.config.PgsqlDb), + golog.WithTableName(logTable), + ) + if err != nil { + return nil, err + } + } + + return c, nil +} diff --git a/service/gitee/const.go b/service/gitee/const.go new file mode 100644 index 00000000..6b1be744 --- /dev/null +++ b/service/gitee/const.go @@ -0,0 +1,9 @@ +package gitee + +const ( + apiUrl = "https://gitee.com" +) + +const ( + logTable = "gitee" +) diff --git a/service/gitee/oauth.authorize.go b/service/gitee/oauth.authorize.go new file mode 100644 index 00000000..3ee18b15 --- /dev/null +++ b/service/gitee/oauth.authorize.go @@ -0,0 +1,10 @@ +package gitee + +import ( + "fmt" +) + +// OauthAuthorize 获取登录地址 +func (c *Client) OauthAuthorize() string { + return fmt.Sprintf(apiUrl+"/oauth/authorize?client_id=%s&redirect_uri=%s&response_type=code", c.config.ClientID, c.config.RedirectUri) +} diff --git a/service/gitee/oauth.token.go b/service/gitee/oauth.token.go new file mode 100644 index 00000000..29761e23 --- /dev/null +++ b/service/gitee/oauth.token.go @@ -0,0 +1,36 @@ +package gitee + +import ( + "encoding/json" + "fmt" + "go.dtapp.net/library/utils/gorequest" + "net/http" +) + +type OauthTokenResponse struct { + AccessToken string `json:"access_token"` +} + +type OauthTokenResult struct { + Result OauthTokenResponse // 结果 + Body []byte // 内容 + Http gorequest.Response // 请求 + Err error // 错误 +} + +func newOauthTokenResult(result OauthTokenResponse, body []byte, http gorequest.Response, err error) *OauthTokenResult { + return &OauthTokenResult{Result: result, Body: body, Http: http, Err: err} +} + +// OauthToken OAuth2 获取 AccessToken 认证步骤 +// https://gitee.com/api/v5/oauth_doc#/list-item-2 +func (c *Client) OauthToken(code string) *OauthTokenResult { + // 参数 + params := gorequest.NewParamsWith() + // 请求 + request, err := c.request(apiUrl+fmt.Sprintf("/oauth/token?grant_type=authorization_code&code=%s&client_id=%s&redirect_uri=%s&client_secret=%s", code, c.config.ClientID, c.config.RedirectUri, c.config.ClientSecret), params, http.MethodPost) + // 定义 + var response OauthTokenResponse + err = json.Unmarshal(request.ResponseBody, &response) + return newOauthTokenResult(response, request.ResponseBody, request, err) +} diff --git a/service/gitee/request.go b/service/gitee/request.go new file mode 100644 index 00000000..0613dc9f --- /dev/null +++ b/service/gitee/request.go @@ -0,0 +1,34 @@ +package gitee + +import "go.dtapp.net/library/utils/gorequest" + +func (c *Client) request(url string, params map[string]interface{}, method string) (gorequest.Response, error) { + + // 创建请求 + client := c.client + + // 设置请求地址 + client.SetUri(url) + + // 设置方式 + client.SetMethod(method) + + // 设置格式 + client.SetContentTypeJson() + + // 设置参数 + client.SetParams(params) + + // 发起请求 + request, err := client.Request() + if err != nil { + return gorequest.Response{}, err + } + + // 日志 + if c.config.PgsqlDb != nil { + go c.log.GormMiddleware(request) + } + + return request, err +} diff --git a/service/oauth/gitee/access_token.go b/service/oauth/gitee/access_token.go deleted file mode 100644 index 202522a4..00000000 --- a/service/oauth/gitee/access_token.go +++ /dev/null @@ -1,36 +0,0 @@ -package gitee - -import ( - "encoding/json" - "fmt" -) - -// GetAccessToken 请求参数 -type GetAccessToken struct { - Code string -} - -// GetAccessTokenResult 返回参数 -type GetAccessTokenResult struct { - AccessToken string `json:"access_token"` -} - -// GetAccessToken OAuth2 获取 AccessToken 认证步骤 https://gitee.com/api/v5/oauth_doc#/list-item-2 -func (app *App) GetAccessToken(param GetAccessToken) (result GetAccessTokenResult, err error) { - url := fmt.Sprintf("https://gitee.com/oauth/token?grant_type=authorization_code&code=%s&client_id=%s&redirect_uri=%s&client_secret=%s", param.Code, app.ClientID, app.RedirectUri, app.ClientSecret) - - // api params - params := map[string]interface{}{} - - // common params - - // request - body, err := app.request(url, params, "POST") - if err != nil { - return - } - if err = json.Unmarshal(body, &result); err != nil { - return - } - return -} diff --git a/service/oauth/gitee/app.go b/service/oauth/gitee/app.go deleted file mode 100644 index 10390fb3..00000000 --- a/service/oauth/gitee/app.go +++ /dev/null @@ -1,42 +0,0 @@ -package gitee - -import ( - "bytes" - "encoding/json" - "io/ioutil" - - "net/http" - // "strconv" -) - -// App 基本配置 -type App struct { - ClientID string - ClientSecret string - RedirectUri string - AccessToken string -} - -func (app *App) request(url string, params map[string]interface{}, method string) (resp []byte, err error) { - // 请求参数 - marshal, _ := json.Marshal(params) - var req *http.Request - req, err = http.NewRequest(method, url, bytes.NewReader(marshal)) - if err != nil { - return nil, err - } - - httpClient := &http.Client{} - var response *http.Response - response, err = httpClient.Do(req) - - if err != nil { - return nil, err - } - - // 处理成功 - defer response.Body.Close() - resp, err = ioutil.ReadAll(response.Body) - - return resp, err -} diff --git a/service/oauth/gitee/authorize.go b/service/oauth/gitee/authorize.go deleted file mode 100644 index 1ee3abdf..00000000 --- a/service/oauth/gitee/authorize.go +++ /dev/null @@ -1,8 +0,0 @@ -package gitee - -import "fmt" - -// GetRedirectUri 获取登录地址 -func (app *App) GetRedirectUri() string { - return fmt.Sprintf("https://gitee.com/oauth/authorize?client_id=%s&redirect_uri=%s&response_type=code", app.ClientID, app.RedirectUri) -} diff --git a/service/oauth/gitee/config.go b/service/oauth/gitee/config.go deleted file mode 100644 index 27ba881d..00000000 --- a/service/oauth/gitee/config.go +++ /dev/null @@ -1,6 +0,0 @@ -package gitee - -const ( - GiteeOAuth2AuthorizeServer = "https://gitee.com/oauth/authorize" - GiteeOAuth2TokenServer = "https://gitee.com/oauth/token" -) diff --git a/service/oauth/workwechat/access_token.go b/service/oauth/workwechat/access_token.go deleted file mode 100644 index 5f7d3159..00000000 --- a/service/oauth/workwechat/access_token.go +++ /dev/null @@ -1,29 +0,0 @@ -package workwechat - -import ( - "encoding/json" - "fmt" -) - -// AuthAccessTokenResult 返回参数 -type AuthAccessTokenResult struct { - Errcode int `json:"errcode"` - Errmsg string `json:"errmsg"` - AccessToken string `json:"access_token"` - ExpiresIn int `json:"expires_in"` -} - -// AuthAccessToken 获取access_token https://open.work.weixin.qq.com/api/doc/90000/90135/91039 -func (app *App) AuthAccessToken() (result AuthAccessTokenResult, err error) { - url := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s", app.AppID, app.Secret) - - // request - body, err := app.request(url, map[string]interface{}{}, "GET") - if err != nil { - return - } - if err = json.Unmarshal(body, &result); err != nil { - return - } - return -} diff --git a/service/oauth/workwechat/app.go b/service/oauth/workwechat/app.go deleted file mode 100644 index 1c3bd630..00000000 --- a/service/oauth/workwechat/app.go +++ /dev/null @@ -1,41 +0,0 @@ -package workwechat - -import ( - "bytes" - "encoding/json" - "io/ioutil" - "net/http" -) - -// App 基本配置 -type App struct { - AppID string - AgentID int - Secret string - RedirectUri string - AccessToken string -} - -func (app *App) request(url string, params map[string]interface{}, method string) (resp []byte, err error) { - // 请求参数 - marshal, _ := json.Marshal(params) - var req *http.Request - req, err = http.NewRequest(method, url, bytes.NewReader(marshal)) - if err != nil { - return nil, err - } - - httpClient := &http.Client{} - var response *http.Response - response, err = httpClient.Do(req) - - if err != nil { - return nil, err - } - - // 处理成功 - defer response.Body.Close() - resp, err = ioutil.ReadAll(response.Body) - - return resp, err -} diff --git a/service/oauth/workwechat/authorize.go b/service/oauth/workwechat/authorize.go deleted file mode 100644 index 9d69fcd7..00000000 --- a/service/oauth/workwechat/authorize.go +++ /dev/null @@ -1,8 +0,0 @@ -package workwechat - -import "fmt" - -// GetRedirectUri 构造网页授权链接 https://work.weixin.qq.com/api/doc/90000/90135/91022 -func (app *App) GetRedirectUri() string { - return fmt.Sprintf("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect", app.AppID, app.RedirectUri) -} diff --git a/service/oauth/workwechat/get_user_info.go b/service/oauth/workwechat/get_user_info.go deleted file mode 100644 index 205dd41a..00000000 --- a/service/oauth/workwechat/get_user_info.go +++ /dev/null @@ -1,35 +0,0 @@ -package workwechat - -import ( - "encoding/json" - "fmt" -) - -type GetUserInfo struct { - Code string `json:"code"` -} - -// GetUserInfoResult 返回参数 -type GetUserInfoResult struct { - Errcode int `json:"errcode"` // 返回码 - Errmsg string `json:"errmsg"` // 对返回码的文本描述内容 - UserId string `json:"userId"` // 成员UserID。若需要获得用户详情信息 - OpenId string `json:"OpenId"` // 非企业成员的标识,对当前企业唯一。不超过64字节 - DeviceId string `json:"DeviceId"` // 手机设备号(由企业微信在安装时随机生成,删除重装会改变,升级不受影响) - ExternalUserid string `json:"external_userid"` // 外部联系人id,当且仅当用户是企业的客户,且跟进人在应用的可见范围内时返回。如果是第三方应用调用,针对同一个客户,同一个服务商不同应用获取到的id相同 -} - -// GetUserInfo 获取访问用户身份 https://open.work.weixin.qq.com/api/doc/90000/90135/91023 -func (app *App) GetUserInfo(param GetUserInfo) (result GetUserInfoResult, err error) { - url := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=%s&code=%s", app.AccessToken, param.Code) - - // request - body, err := app.request(url, map[string]interface{}{}, "GET") - if err != nil { - return - } - if err = json.Unmarshal(body, &result); err != nil { - return - } - return -} diff --git a/service/oauth/workwechat/qr_connect.go b/service/oauth/workwechat/qr_connect.go deleted file mode 100644 index 120f8a3d..00000000 --- a/service/oauth/workwechat/qr_connect.go +++ /dev/null @@ -1,8 +0,0 @@ -package workwechat - -import "fmt" - -// QrConnect 构造独立窗口登录二维码 https://open.work.weixin.qq.com/api/doc/90000/90135/91019 -func (app *App) QrConnect() string { - return fmt.Sprintf("https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid=%s&agentid=%d&redirect_uri=%s&state=STATE&lang=zh", app.AppID, app.AgentID, app.RedirectUri) -} diff --git a/service/wechatqy/cgi-bin.gettoken.go b/service/wechatqy/cgi-bin.gettoken.go new file mode 100644 index 00000000..9b8c1efe --- /dev/null +++ b/service/wechatqy/cgi-bin.gettoken.go @@ -0,0 +1,39 @@ +package wechatqy + +import ( + "encoding/json" + "fmt" + "go.dtapp.net/library/utils/gorequest" + "net/http" +) + +type CgiBinGetTokenResponse struct { + Errcode int `json:"errcode"` + Errmsg string `json:"errmsg"` + AccessToken string `json:"access_token"` + ExpiresIn int `json:"expires_in"` +} + +type CgiBinGetTokenResult struct { + Result CgiBinGetTokenResponse // 结果 + Body []byte // 内容 + Http gorequest.Response // 请求 + Err error // 错误 +} + +func newCgiBinGetTokenResult(result CgiBinGetTokenResponse, body []byte, http gorequest.Response, err error) *CgiBinGetTokenResult { + return &CgiBinGetTokenResult{Result: result, Body: body, Http: http, Err: err} +} + +// CgiBinGetToken 获取access_token +// https://open.work.weixin.qq.com/api/doc/90000/90135/91039 +func (c *Client) CgiBinGetToken(notMustParams ...gorequest.Params) *CgiBinGetTokenResult { + // 参数 + params := gorequest.NewParamsWith(notMustParams...) + // 请求 + request, err := c.request(apiUrl+fmt.Sprintf("/cgi-bin/gettoken?corpid=%s&corpsecret=%s", c.config.AppID, c.config.Secret), params, http.MethodGet) + // 定义 + var response CgiBinGetTokenResponse + err = json.Unmarshal(request.ResponseBody, &response) + return newCgiBinGetTokenResult(response, request.ResponseBody, request, err) +} diff --git a/service/wechatqy/cgi-bin.user.getuserinfo.go b/service/wechatqy/cgi-bin.user.getuserinfo.go new file mode 100644 index 00000000..127cd369 --- /dev/null +++ b/service/wechatqy/cgi-bin.user.getuserinfo.go @@ -0,0 +1,41 @@ +package wechatqy + +import ( + "encoding/json" + "fmt" + "go.dtapp.net/library/utils/gorequest" + "net/http" +) + +type CgiBinUserGetUserInfoResponse struct { + Errcode int `json:"errcode"` // 返回码 + Errmsg string `json:"errmsg"` // 对返回码的文本描述内容 + UserId string `json:"userId"` // 成员UserID。若需要获得用户详情信息 + OpenId string `json:"OpenId"` // 非企业成员的标识,对当前企业唯一。不超过64字节 + DeviceId string `json:"DeviceId"` // 手机设备号(由企业微信在安装时随机生成,删除重装会改变,升级不受影响) + ExternalUserid string `json:"external_userid"` // 外部联系人id,当且仅当用户是企业的客户,且跟进人在应用的可见范围内时返回。如果是第三方应用调用,针对同一个客户,同一个服务商不同应用获取到的id相同 +} + +type CgiBinUserGetUserInfoResult struct { + Result CgiBinUserGetUserInfoResponse // 结果 + Body []byte // 内容 + Http gorequest.Response // 请求 + Err error // 错误 +} + +func newCgiBinUserGetUserInfoResult(result CgiBinUserGetUserInfoResponse, body []byte, http gorequest.Response, err error) *CgiBinUserGetUserInfoResult { + return &CgiBinUserGetUserInfoResult{Result: result, Body: body, Http: http, Err: err} +} + +// CgiBinUserGetUserInfo 获取访问用户身份 +// https://open.work.weixin.qq.com/api/doc/90000/90135/91023 +func (c *Client) CgiBinUserGetUserInfo(code, accessToken string) *CgiBinUserGetUserInfoResult { + // 参数 + params := gorequest.NewParamsWith() + // 请求 + request, err := c.request(apiUrl+fmt.Sprintf("/cgi-bin/user/getuserinfo?access_token=%s&code=%s", accessToken, code), params, http.MethodGet) + // 定义 + var response CgiBinUserGetUserInfoResponse + err = json.Unmarshal(request.ResponseBody, &response) + return newCgiBinUserGetUserInfoResult(response, request.ResponseBody, request, err) +} diff --git a/service/wechatqy/client.go b/service/wechatqy/client.go index adc6797c..ad2ed232 100644 --- a/service/wechatqy/client.go +++ b/service/wechatqy/client.go @@ -8,6 +8,10 @@ import ( ) type ConfigClient struct { + AppID string + AgentID int + Secret string + RedirectUri string Key string // key MongoDb *dorm.MongoClient // 日志数据库 PgsqlDb *gorm.DB // 日志数据库 diff --git a/service/wechatqy/connect.oauth2.authorize.go b/service/wechatqy/connect.oauth2.authorize.go new file mode 100644 index 00000000..9d490ade --- /dev/null +++ b/service/wechatqy/connect.oauth2.authorize.go @@ -0,0 +1,11 @@ +package wechatqy + +import ( + "fmt" +) + +// ConnectOauth2Authorize 构造网页授权链接 +// https://work.weixin.qq.com/api/doc/90000/90135/91022 +func (c *Client) ConnectOauth2Authorize() string { + return fmt.Sprintf("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect", c.config.AppID, c.config.RedirectUri) +} diff --git a/service/wechatqy/request.go b/service/wechatqy/request.go index acbe9ab0..3c128d0f 100644 --- a/service/wechatqy/request.go +++ b/service/wechatqy/request.go @@ -2,13 +2,16 @@ package wechatqy import "go.dtapp.net/library/utils/gorequest" -func (c *Client) request(url string, params map[string]interface{}) (gorequest.Response, error) { +func (c *Client) request(url string, params map[string]interface{}, method string) (gorequest.Response, error) { // 创建请求 client := c.client // 设置请求地址 client.SetUri(url) + // 设置方式 + client.SetMethod(method) + // 设置FORM格式 client.SetContentTypeJson() @@ -16,7 +19,7 @@ func (c *Client) request(url string, params map[string]interface{}) (gorequest.R client.SetParams(params) // 发起请求 - request, err := client.Post() + request, err := client.Request() if err != nil { return gorequest.Response{}, err } diff --git a/service/wechatqy/webhook.send.go b/service/wechatqy/webhook.send.go index 525b05b2..55600bfd 100644 --- a/service/wechatqy/webhook.send.go +++ b/service/wechatqy/webhook.send.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "go.dtapp.net/library/utils/gorequest" + "net/http" ) type WebhookSendResponse struct { @@ -31,7 +32,7 @@ func (c *Client) WebhookSend(notMustParams ...gorequest.Params) *WebhookSendResu // 参数 params := gorequest.NewParamsWith(notMustParams...) // 请求 - request, err := c.request(apiUrl+fmt.Sprintf("/cgi-bin/webhook/send?key=%s&type=%s", c.GetKey(), "text"), params) + request, err := c.request(apiUrl+fmt.Sprintf("/cgi-bin/webhook/send?key=%s&type=%s", c.GetKey(), "text"), params, http.MethodPost) // 定义 var response WebhookSendResponse err = json.Unmarshal(request.ResponseBody, &response) diff --git a/service/wechatqy/wwopen.sso.qrConnect.go b/service/wechatqy/wwopen.sso.qrConnect.go new file mode 100644 index 00000000..bfa17104 --- /dev/null +++ b/service/wechatqy/wwopen.sso.qrConnect.go @@ -0,0 +1,11 @@ +package wechatqy + +import ( + "fmt" +) + +// WwOpenSsoQrConnect 构造独立窗口登录二维码 +// https://open.work.weixin.qq.com/api/doc/90000/90135/91019 +func (c *Client) WwOpenSsoQrConnect() string { + return fmt.Sprintf("https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid=%s&agentid=%d&redirect_uri=%s&state=STATE&lang=zh", c.config.AppID, c.config.AgentID, c.config.RedirectUri) +}