| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341 |
- package work
- import (
- "encoding/json"
- "encoding/xml"
- "fmt"
- "github.com/gogf/gf/util/gconv"
- "github.com/silenceper/wechat/v2/credential"
- "github.com/silenceper/wechat/v2/util"
- "github.com/silenceper/wechat/v2/work/config"
- "github.com/silenceper/wechat/v2/work/context"
- "github.com/silenceper/wechat/v2/work/kf"
- "strconv"
- "time"
- )
- const (
- getTemplateDetailURL = "https://qyapi.weixin.qq.com/cgi-bin/oa/gettemplatedetail?access_token=%s"
- applyEventURL = "https://qyapi.weixin.qq.com/cgi-bin/oa/applyevent?access_token=%s"
- getApprovalInfoURL = "https://qyapi.weixin.qq.com/cgi-bin/oa/getapprovalinfo?access_token=%s"
- getApprovalDetailURL = "https://qyapi.weixin.qq.com/cgi-bin/oa/getapprovaldetail?access_token=%s"
- )
- // Work 企业微信
- type Work struct {
- ctx *context.Context
- }
- // NewWork init work
- func NewWork(cfg *config.Config) *Work {
- defaultAkHandle := credential.NewWorkAccessToken(cfg.CorpID, cfg.CorpSecret, credential.CacheKeyWorkPrefix, cfg.Cache)
- ctx := &context.Context{
- Config: cfg,
- AccessTokenHandle: defaultAkHandle,
- }
- return &Work{ctx: ctx}
- }
- // GetOATemplateDetail 获取审批模板详情
- func (work *Work) GetOATemplateDetail(templateID string) (*OATemplateDetail, error) {
- accessToken, err := work.ctx.GetAccessToken()
- if err != nil {
- return nil, err
- }
- response, err := util.PostJSON(fmt.Sprintf(getTemplateDetailURL, accessToken), reqOAGetTemplateDetail{
- TemplateID: templateID,
- })
- if err != nil {
- return nil, err
- }
- var result respOAGetTemplateDetail
- err = json.Unmarshal(response, &result)
- if err != nil {
- return nil, err
- }
- if result.ErrCode != 0 {
- return nil, kf.NewSDKErr(result.ErrCode, result.ErrMsg)
- }
- return &result.OATemplateDetail, nil
- }
- // ApplyOAEvent 提交审批申请
- func (work *Work) ApplyOAEvent(applyInfo OAApplyEvent) (string, error) {
- accessToken, err := work.ctx.GetAccessToken()
- if err != nil {
- return "", err
- }
- fmt.Println("-------------企业微信审批流对接【提交审批申请】请求---------------", gconv.String(applyInfo))
- response, err := util.PostJSON(fmt.Sprintf(applyEventURL, accessToken), applyInfo)
- if err != nil {
- return "", err
- }
- var result respOAApplyEvent
- err = json.Unmarshal(response, &result)
- if err != nil {
- return "", err
- }
- fmt.Println("-------------企业微信审批流对接【提交审批申请】返回---------------", gconv.String(result))
- if result.ErrCode != 0 {
- return "", kf.NewSDKErr(result.ErrCode, result.ErrMsg)
- }
- return result.SpNo, nil
- }
- // GetOAApprovalInfo 批量获取审批单号
- func (work *Work) GetOAApprovalInfo(req GetOAApprovalInfoReq) ([]string, error) {
- accessToken, err := work.ctx.GetAccessToken()
- if err != nil {
- return nil, err
- }
- response, err := util.PostJSON(fmt.Sprintf(getApprovalInfoURL, accessToken), reqOAGetApprovalInfo{
- StartTime: strconv.FormatInt(req.StartTime.Unix(), 10),
- EndTime: strconv.FormatInt(req.EndTime.Unix(), 10),
- Cursor: req.Cursor,
- Size: req.Size,
- Filters: req.Filters,
- })
- if err != nil {
- return nil, err
- }
- var result respOAGetApprovalInfo
- err = json.Unmarshal(response, &result)
- if err != nil {
- return nil, err
- }
- if result.ErrCode != 0 {
- return nil, kf.NewSDKErr(result.ErrCode, result.ErrMsg)
- }
- return result.SpNoList, nil
- }
- // GetOAApprovalDetail 获取审批申请详情
- func (work *Work) GetOAApprovalDetail(spNo string) (*OAApprovalDetail, error) {
- accessToken, err := work.ctx.GetAccessToken()
- if err != nil {
- return nil, err
- }
- fmt.Println("-------------企业微信审批流对接【获取审批申请详情】请求---------------", spNo)
- response, err := util.PostJSON(fmt.Sprintf(getApprovalDetailURL, accessToken), reqOAGetApprovalDetail{
- SpNo: spNo,
- })
- if err != nil {
- return nil, err
- }
- var result respOAGetApprovalDetail
- err = json.Unmarshal(response, &result)
- if err != nil {
- return nil, err
- }
- fmt.Println("-------------企业微信审批流对接【获取审批申请详情】请求---------------", gconv.String(result))
- if result.ErrCode != 0 {
- return nil, kf.NewSDKErr(result.ErrCode, result.ErrMsg)
- }
- return &result.Info, nil
- }
- // GetOAApprovalInfoReq 批量获取审批单号请求
- type GetOAApprovalInfoReq struct {
- // StartTime 审批单提交的时间范围,开始时间,UNix时间戳
- StartTime time.Time
- // EndTime 审批单提交的时间范围,结束时间,Unix时间戳
- EndTime time.Time
- // Cursor 分页查询游标,默认为0,后续使用返回的next_cursor进行分页拉取
- Cursor int
- // Size 一次请求拉取审批单数量,默认值为100,上限值为100
- Size uint32
- // Filters 筛选条件,可对批量拉取的审批申请设置约束条件,支持设置多个条件
- Filters []OAApprovalInfoFilter
- }
- // OAApprovalInfo 审批申请状态变化回调通知
- type OAApprovalInfo struct {
- // SpNo 审批编号
- SpNo string `xml:"SpNo"`
- // SpName 审批申请类型名称(审批模板名称)
- SpName string `xml:"SpName"`
- // SpStatus 申请单状态:1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付
- SpStatus string `xml:"SpStatus"`
- // TemplateID 审批模板id。可在“获取审批申请详情”、“审批状态变化回调通知”中获得,也可在审批模板的模板编辑页面链接中获得。
- TemplateID string `xml:"TemplateId"`
- // ApplyTime 审批申请提交时间,Unix时间戳
- ApplyTime string `xml:"ApplyTime"`
- // Applicant 申请人信息
- Applicant OAApprovalInfoApplicant `xml:"Applyer"`
- // SpRecord 审批流程信息,可能有多个审批节点。
- SpRecord []OAApprovalInfoSpRecord `xml:"SpRecord"`
- // Notifier 抄送信息,可能有多个抄送节点
- Notifier OAApprovalInfoNotifier `xml:"Notifyer"`
- // Comments 审批申请备注信息,可能有多个备注节点
- Comments []OAApprovalInfoComment `xml:"Comments"`
- // StatusChangeEvent 审批申请状态变化类型:1-提单;2-同意;3-驳回;4-转审;5-催办;6-撤销;8-通过后撤销;10-添加备注
- StatusChangeEvent string `xml:"StatuChangeEvent"`
- }
- // OAApprovalInfoApplicant 申请人信息
- type OAApprovalInfoApplicant struct {
- // UserID 申请人userid
- UserID string `xml:"UserId"`
- // Party 申请人所在部门pid
- Party string `xml:"Party"`
- }
- // OAApprovalInfoSpRecord 审批流程信息,可能有多个审批节点。
- type OAApprovalInfoSpRecord struct {
- // SpStatus 审批节点状态:1-审批中;2-已同意;3-已驳回;4-已转审
- SpStatus string `xml:"SpStatus"`
- // ApproverAttr 节点审批方式:1-或签;2-会签
- ApproverAttr string `xml:"ApproverAttr"`
- // Details 审批节点详情。当节点为标签或上级时,一个节点可能有多个分支
- Details []OAApprovalInfoSpRecordDetail `xml:"Details"`
- }
- // OAApprovalInfoSpRecordDetail 审批节点详情。当节点为标签或上级时,一个节点可能有多个分支
- type OAApprovalInfoSpRecordDetail struct {
- // Approver 分支审批人
- Approver OAApprovalInfoSpRecordDetailApprover `xml:"Approver"`
- // Speech 审批意见字段
- Speech string `xml:"Speech"`
- // SpStatus 分支审批人审批状态:1-审批中;2-已同意;3-已驳回;4-已转审
- SpStatus string `xml:"SpStatus"`
- // SpTime 节点分支审批人审批操作时间,0为尚未操作
- SpTime string `xml:"SpTime"`
- // Attach 节点分支审批人审批意见附件,赋值为media_id具体使用请参考:文档-获取临时素材
- Attach []string `xml:"Attach"`
- }
- // OAApprovalInfoSpRecordDetailApprover 分支审批人
- type OAApprovalInfoSpRecordDetailApprover struct {
- // UserID 分支审批人userid
- UserID string `xml:"UserId"`
- }
- // OAApprovalInfoNotifier 抄送信息,可能有多个抄送节点
- type OAApprovalInfoNotifier struct {
- // UserID 节点抄送人userid
- UserID string `xml:"UserId"`
- }
- // OAApprovalInfoComment 审批申请备注信息,可能有多个备注节点
- type OAApprovalInfoComment struct {
- // CommentUserInfo 备注人信息
- CommentUserInfo OAApprovalInfoCommentUserInfo `xml:"CommentUserInfo"`
- // CommentTime 备注提交时间
- CommentTime string `xml:"CommentTime"`
- // CommentContent 备注文本内容
- CommentContent string `xml:"CommentContent"`
- // CommentID 备注id
- CommentID string `xml:"CommentId"`
- // Attach 备注意见附件,值是附件media_id具体使用请参考:文档-获取临时素材
- Attach []string `xml:"Attach"`
- }
- // OAApprovalInfoCommentUserInfo 备注人信息
- type OAApprovalInfoCommentUserInfo struct {
- // UserID 备注人userid
- UserID string `xml:"UserId"`
- }
- type SysApprovalChangeMessage struct {
- XMLName xml.Name `xml:"xml"`
- Text string `xml:",chardata"`
- ToUserName struct {
- Text string `xml:",chardata"`
- } `xml:"ToUserName"`
- FromUserName struct {
- Text string `xml:",chardata"`
- } `xml:"FromUserName"`
- CreateTime struct {
- Text string `xml:",chardata"`
- } `xml:"CreateTime"`
- MsgType struct {
- Text string `xml:",chardata"`
- } `xml:"MsgType"`
- Event struct {
- Text string `xml:",chardata"`
- } `xml:"Event"`
- AgentID struct {
- Text string `xml:",chardata"`
- } `xml:"AgentID"`
- ApprovalInfo struct {
- Text string `xml:",chardata"`
- SpNo struct {
- Text string `xml:",chardata"`
- } `xml:"SpNo"`
- SpName struct {
- Text string `xml:",chardata"`
- } `xml:"SpName"`
- SpStatus struct {
- Text string `xml:",chardata"`
- } `xml:"SpStatus"`
- TemplateId struct {
- Text string `xml:",chardata"`
- } `xml:"TemplateId"`
- ApplyTime struct {
- Text string `xml:",chardata"`
- } `xml:"ApplyTime"`
- Applyer struct {
- Text string `xml:",chardata"`
- UserId struct {
- Text string `xml:",chardata"`
- } `xml:"UserId"`
- Party struct {
- Text string `xml:",chardata"`
- } `xml:"Party"`
- } `xml:"Applyer"`
- SpRecord []struct {
- Text string `xml:",chardata"`
- SpStatus struct {
- Text string `xml:",chardata"`
- } `xml:"SpStatus"`
- ApproverAttr struct {
- Text string `xml:",chardata"`
- } `xml:"ApproverAttr"`
- Details []struct {
- Text string `xml:",chardata"`
- Approver struct {
- Text string `xml:",chardata"`
- UserId struct {
- Text string `xml:",chardata"`
- } `xml:"UserId"`
- } `xml:"Approver"`
- Speech struct {
- Text string `xml:",chardata"`
- } `xml:"Speech"`
- SpStatus struct {
- Text string `xml:",chardata"`
- } `xml:"SpStatus"`
- SpTime struct {
- Text string `xml:",chardata"`
- } `xml:"SpTime"`
- } `xml:"Details"`
- } `xml:"SpRecord"`
- Notifyer struct {
- Text string `xml:",chardata"`
- UserId struct {
- Text string `xml:",chardata"`
- } `xml:"UserId"`
- } `xml:"Notifyer"`
- Comments struct {
- Text string `xml:",chardata"`
- CommentUserInfo struct {
- Text string `xml:",chardata"`
- UserId struct {
- Text string `xml:",chardata"`
- } `xml:"UserId"`
- } `xml:"CommentUserInfo"`
- CommentTime struct {
- Text string `xml:",chardata"`
- } `xml:"CommentTime"`
- CommentContent struct {
- Text string `xml:",chardata"`
- } `xml:"CommentContent"`
- CommentId struct {
- Text string `xml:",chardata"`
- } `xml:"CommentId"`
- } `xml:"Comments"`
- StatuChangeEvent struct {
- Text string `xml:",chardata"`
- } `xml:"StatuChangeEvent"`
- } `xml:"ApprovalInfo"`
- }
|