mirror of
https://github.com/silenceper/wechat.git
synced 2026-03-01 00:35:26 +08:00
Compare commits
4 Commits
56d963e0ca
...
0e9bdfe1dd
| Author | SHA1 | Date | |
|---|---|---|---|
| 0e9bdfe1dd | |||
| 3bd886d7f2 | |||
| 35af33f0bc | |||
| de92dc0dcd |
@@ -0,0 +1,60 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
stdContext "context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/silenceper/wechat/v2/openplatform/context"
|
||||||
|
"github.com/silenceper/wechat/v2/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
code2SessionURL = "https://api.weixin.qq.com/sns/component/jscode2session?appid=%s&js_code=%s&grant_type=authorization_code&component_appid=%s&component_access_token=%s"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Auth 登录/用户信息
|
||||||
|
type Auth struct {
|
||||||
|
*context.Context
|
||||||
|
authorizerAppID string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAuth new auth (授权方appID)
|
||||||
|
func NewAuth(ctx *context.Context, appID string) *Auth {
|
||||||
|
return &Auth{ctx, appID}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResCode2Session 登录凭证校验的返回结果
|
||||||
|
type ResCode2Session struct {
|
||||||
|
util.CommonError
|
||||||
|
OpenID string `json:"openid"` // 用户唯一标识
|
||||||
|
SessionKey string `json:"session_key"` // 会话密钥
|
||||||
|
UnionID string `json:"unionid"` // 用户在开放平台的唯一标识符,在满足UnionID下发条件的情况下会返回
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code2Session 登录凭证校验。
|
||||||
|
func (auth *Auth) Code2Session(jsCode string) (result ResCode2Session, err error) {
|
||||||
|
return auth.Code2SessionContext(stdContext.Background(), jsCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code2SessionContext 登录凭证校验。
|
||||||
|
func (auth *Auth) Code2SessionContext(ctx stdContext.Context, jsCode string) (result ResCode2Session, err error) {
|
||||||
|
var response []byte
|
||||||
|
var componentAccessToken string
|
||||||
|
componentAccessToken, err = auth.GetComponentAccessToken()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
parse := fmt.Sprintf(code2SessionURL, auth.authorizerAppID, jsCode, auth.Context.AppID, componentAccessToken)
|
||||||
|
if response, err = util.HTTPGetContext(ctx, parse); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = json.Unmarshal(response, &result); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if result.ErrCode != 0 {
|
||||||
|
err = fmt.Errorf("Code2Session error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
miniContext "github.com/silenceper/wechat/v2/miniprogram/context"
|
miniContext "github.com/silenceper/wechat/v2/miniprogram/context"
|
||||||
"github.com/silenceper/wechat/v2/miniprogram/urllink"
|
"github.com/silenceper/wechat/v2/miniprogram/urllink"
|
||||||
openContext "github.com/silenceper/wechat/v2/openplatform/context"
|
openContext "github.com/silenceper/wechat/v2/openplatform/context"
|
||||||
|
"github.com/silenceper/wechat/v2/openplatform/miniprogram/auth"
|
||||||
"github.com/silenceper/wechat/v2/openplatform/miniprogram/basic"
|
"github.com/silenceper/wechat/v2/openplatform/miniprogram/basic"
|
||||||
"github.com/silenceper/wechat/v2/openplatform/miniprogram/component"
|
"github.com/silenceper/wechat/v2/openplatform/miniprogram/component"
|
||||||
)
|
)
|
||||||
@@ -72,6 +73,11 @@ func (miniProgram *MiniProgram) GetURLLink() *urllink.URLLink {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAuth 登录/用户信息相关接口
|
||||||
|
func (miniProgram *MiniProgram) GetAuth() *auth.Auth {
|
||||||
|
return auth.NewAuth(miniProgram.openContext, miniProgram.AppID)
|
||||||
|
}
|
||||||
|
|
||||||
// DefaultAuthrAccessToken 默认获取授权ak的方法
|
// DefaultAuthrAccessToken 默认获取授权ak的方法
|
||||||
type DefaultAuthrAccessToken struct {
|
type DefaultAuthrAccessToken struct {
|
||||||
opCtx *openContext.Context
|
opCtx *openContext.Context
|
||||||
|
|||||||
@@ -9,12 +9,16 @@ import (
|
|||||||
const (
|
const (
|
||||||
// departmentCreateURL 创建部门
|
// departmentCreateURL 创建部门
|
||||||
departmentCreateURL = "https://qyapi.weixin.qq.com/cgi-bin/department/create?access_token=%s"
|
departmentCreateURL = "https://qyapi.weixin.qq.com/cgi-bin/department/create?access_token=%s"
|
||||||
|
// departmentUpdateURL 更新部门
|
||||||
|
departmentUpdateURL = "https://qyapi.weixin.qq.com/cgi-bin/department/update?access_token=%s"
|
||||||
|
// departmentDeleteURL 删除部门
|
||||||
|
departmentDeleteURL = "https://qyapi.weixin.qq.com/cgi-bin/department/delete?access_token=%s&id=%d"
|
||||||
// departmentSimpleListURL 获取子部门ID列表
|
// departmentSimpleListURL 获取子部门ID列表
|
||||||
departmentSimpleListURL = "https://qyapi.weixin.qq.com/cgi-bin/department/simplelist?access_token=%s&id=%d"
|
departmentSimpleListURL = "https://qyapi.weixin.qq.com/cgi-bin/department/simplelist?access_token=%s&id=%d"
|
||||||
// departmentListURL 获取部门列表
|
// departmentListURL 获取部门列表
|
||||||
departmentListURL = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=%s"
|
departmentListURL = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=%s"
|
||||||
departmentListByIDURL = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=%s&id=%d"
|
departmentListByIDURL = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=%s&id=%d"
|
||||||
// departmentGetURL 获取单个部门详情 https://qyapi.weixin.qq.com/cgi-bin/department/get?access_token=ACCESS_TOKEN&id=ID
|
// departmentGetURL 获取单个部门详情
|
||||||
departmentGetURL = "https://qyapi.weixin.qq.com/cgi-bin/department/get?access_token=%s&id=%d"
|
departmentGetURL = "https://qyapi.weixin.qq.com/cgi-bin/department/get?access_token=%s&id=%d"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -85,6 +89,49 @@ func (r *Client) DepartmentCreate(req *DepartmentCreateRequest) (*DepartmentCrea
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DepartmentUpdateRequest 更新部门请求
|
||||||
|
type DepartmentUpdateRequest struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
NameEn string `json:"name_en,omitempty"`
|
||||||
|
ParentID int `json:"parentid,omitempty"`
|
||||||
|
Order int `json:"order,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DepartmentUpdate 更新部门
|
||||||
|
// see https://developer.work.weixin.qq.com/document/path/90206
|
||||||
|
func (r *Client) DepartmentUpdate(req *DepartmentUpdateRequest) error {
|
||||||
|
var (
|
||||||
|
accessToken string
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var response []byte
|
||||||
|
if response, err = util.PostJSON(fmt.Sprintf(departmentUpdateURL, accessToken), req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return util.DecodeWithCommonError(response, "DepartmentUpdate")
|
||||||
|
}
|
||||||
|
|
||||||
|
// DepartmentDelete 删除部门
|
||||||
|
// @see https://developer.work.weixin.qq.com/document/path/90207
|
||||||
|
func (r *Client) DepartmentDelete(departmentID int) error {
|
||||||
|
var (
|
||||||
|
accessToken string
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var response []byte
|
||||||
|
if response, err = util.HTTPGet(fmt.Sprintf(departmentDeleteURL, accessToken, departmentID)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return util.DecodeWithCommonError(response, "DepartmentDelete")
|
||||||
|
}
|
||||||
|
|
||||||
// DepartmentSimpleList 获取子部门ID列表
|
// DepartmentSimpleList 获取子部门ID列表
|
||||||
// see https://developer.work.weixin.qq.com/document/path/95350
|
// see https://developer.work.weixin.qq.com/document/path/95350
|
||||||
func (r *Client) DepartmentSimpleList(departmentID int) ([]*DepartmentID, error) {
|
func (r *Client) DepartmentSimpleList(departmentID int) ([]*DepartmentID, error) {
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ const (
|
|||||||
userSimpleListURL = "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist"
|
userSimpleListURL = "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist"
|
||||||
// userCreateURL 创建成员
|
// userCreateURL 创建成员
|
||||||
userCreateURL = "https://qyapi.weixin.qq.com/cgi-bin/user/create?access_token=%s"
|
userCreateURL = "https://qyapi.weixin.qq.com/cgi-bin/user/create?access_token=%s"
|
||||||
|
// userUpdateURL 更新成员
|
||||||
|
userUpdateURL = "https://qyapi.weixin.qq.com/cgi-bin/user/update?access_token=%s"
|
||||||
// userGetURL 读取成员
|
// userGetURL 读取成员
|
||||||
userGetURL = "https://qyapi.weixin.qq.com/cgi-bin/user/get"
|
userGetURL = "https://qyapi.weixin.qq.com/cgi-bin/user/get"
|
||||||
// userDeleteURL 删除成员
|
// userDeleteURL 删除成员
|
||||||
@@ -154,6 +156,51 @@ func (r *Client) UserCreate(req *UserCreateRequest) (*UserCreateResponse, error)
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UserUpdateRequest 更新成员请求
|
||||||
|
type UserUpdateRequest struct {
|
||||||
|
UserID string `json:"userid"`
|
||||||
|
NewUserID string `json:"new_userid"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Alias string `json:"alias"`
|
||||||
|
Mobile string `json:"mobile"`
|
||||||
|
Department []int `json:"department"`
|
||||||
|
Order []int `json:"order"`
|
||||||
|
Position string `json:"position"`
|
||||||
|
Gender int `json:"gender"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
BizMail string `json:"biz_mail"`
|
||||||
|
IsLeaderInDept []int `json:"is_leader_in_dept"`
|
||||||
|
DirectLeader []string `json:"direct_leader"`
|
||||||
|
Enable int `json:"enable"`
|
||||||
|
AvatarMediaid string `json:"avatar_mediaid"`
|
||||||
|
Telephone string `json:"telephone"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
MainDepartment int `json:"main_department"`
|
||||||
|
Extattr struct {
|
||||||
|
Attrs []ExtraAttr `json:"attrs"`
|
||||||
|
} `json:"extattr"`
|
||||||
|
ToInvite bool `json:"to_invite"`
|
||||||
|
ExternalPosition string `json:"external_position"`
|
||||||
|
ExternalProfile ExternalProfile `json:"external_profile"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserUpdate 更新成员
|
||||||
|
// see https://developer.work.weixin.qq.com/document/path/90197
|
||||||
|
func (r *Client) UserUpdate(req *UserUpdateRequest) error {
|
||||||
|
var (
|
||||||
|
accessToken string
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var response []byte
|
||||||
|
if response, err = util.PostJSON(fmt.Sprintf(userUpdateURL, accessToken), req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return util.DecodeWithCommonError(response, "UserUpdate")
|
||||||
|
}
|
||||||
|
|
||||||
// UserGetResponse 获取部门成员响应
|
// UserGetResponse 获取部门成员响应
|
||||||
type UserGetResponse struct {
|
type UserGetResponse struct {
|
||||||
util.CommonError
|
util.CommonError
|
||||||
|
|||||||
@@ -59,6 +59,30 @@ func (r *Client) UploadImg(filename string) (*UploadImgResponse, error) {
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UploadImgFromReader 从 io.Reader 上传图片
|
||||||
|
// @see https://developer.work.weixin.qq.com/document/path/90256
|
||||||
|
func (r *Client) UploadImgFromReader(filename string, reader io.Reader) (*UploadImgResponse, error) {
|
||||||
|
var (
|
||||||
|
accessToken string
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if accessToken, err = r.GetAccessToken(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var byteData []byte
|
||||||
|
byteData, err = io.ReadAll(reader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var response []byte
|
||||||
|
if response, err = util.PostFileByStream("media", filename, fmt.Sprintf(uploadImgURL, accessToken), byteData); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result := &UploadImgResponse{}
|
||||||
|
err = util.DecodeWithError(response, result, "UploadImg")
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
// UploadTempFile 上传临时素材
|
// UploadTempFile 上传临时素材
|
||||||
// @see https://developer.work.weixin.qq.com/document/path/90253
|
// @see https://developer.work.weixin.qq.com/document/path/90253
|
||||||
// @mediaType 媒体文件类型,分别有图片(image)、语音(voice)、视频(video),普通文件(file)
|
// @mediaType 媒体文件类型,分别有图片(image)、语音(voice)、视频(video),普通文件(file)
|
||||||
@@ -166,5 +190,13 @@ func (r *Client) GetTempFile(mediaID string) ([]byte, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查响应是否为错误信息
|
||||||
|
err = util.DecodeWithCommonError(response, "GetTempFile")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果不是错误响应,则返回原始数据
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user