踩坑,一肚子火,记录下过程!

001.获取审批使用的Secret(并非企业使用的CorpSecret)

java 企业微信审批 企业微信审批api_json

java 企业微信审批 企业微信审批api_控件_02

 

java 企业微信审批 企业微信审批api_控件_03

 

java 企业微信审批 企业微信审批api_json_04

 

java 企业微信审批 企业微信审批api_xml_05

 

java 企业微信审批 企业微信审批api_json_06

 

 002.设置接收事件服务器并勾选需要订阅的应用

java 企业微信审批 企业微信审批api_控件_07

java 企业微信审批 企业微信审批api_xml_08

 

003.订阅事件接入(golang代码)

v1.GET("/oa_event", verifyurl.Check) //审批接入
package verifyurl

import (
	"net/http"
	"wx_chat/src/global"
	"wx_chat/src/utils/bind"

	"github.com/gin-gonic/gin"
)

type P_VerifyUrl struct {
	Signature string `form:"msg_signature" binding:"required"`
	Timestamp string `form:"timestamp" binding:"required"`
	Nonce     string `form:"nonce" binding:"required"`
	Echostr   string `form:"echostr" binding:"required"`
}

func Check(c *gin.Context) {
	var p P_VerifyUrl
	if bind.Bind(c, &p, true) == nil {
		if echostr, err := global.Wxcpt.VerifyURL(p.Signature, p.Timestamp, p.Nonce, p.Echostr); err != nil {
			c.String(http.StatusForbidden, err.ErrMsg)
		} else {
			c.String(http.StatusOK, string(echostr))
		}
	}
}

004.解析消息(golang)

v1.POST("/oa_event", wxoa.Events)    //消息订阅
package wxoa

import (
	"encoding/xml"
	"errors"
	"fmt"
	"io/ioutil"
	"wx_chat/src/global"
	"wx_chat/src/response"
	"wx_chat/src/utils/bind"

	"github.com/gin-gonic/gin"
)

type P_Events struct {
	Signature string `form:"msg_signature" binding:"required"`
	Timestamp string `form:"timestamp" binding:"required"`
	Nonce     string `form:"nonce" binding:"required"`
}

type D_Events struct {
	ToUserName   string       `xml:"ToUserName"`
	CreateTime   string       `xml:"CreateTime"`
	MsgType      string       `xml:"MsgType"`
	Event        string       `xml:"Event"` //事件名称:sys_approval_change
	AgentID      string       `xml:"AgentID"`
	ApprovalInfo ApprovalInfo `xml:"ApprovalInfo"`
}

type ApprovalInfo struct {
	SpNo       string         `xml:"SpNo"`       //审批编号
	SpName     string         `xml:"SpName"`     //审批申请类型名称(审批模板名称)
	SpStatus   string         `xml:"SpStatus"`   //申请单状态:1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付
	TemplateId string         `xml:"TemplateId"` //审批模板id。可在“获取审批申请详情”、“审批状态变化回调通知”中获得,也可在审批模板的模板编辑页面链接中获得。
	ApplyTime  string         `xml:"ApplyTime"`  //审批申请提交时间,Unix时间戳
	Applyer    ApplyerInfo    `xml:"Applyer"`    //申请人信息
	SpRecord   []SpRecordInfo `xml:"SpRecord"`   //审批流程信息,可能有多个审批节点。
	Notifyer   []NotifyerInfo `xml:"Notifyer"`   //抄送信息,可能有多个抄送节点
	Comments   []CommentsInfo `xml:"Comments"`   //审批申请备注信息,可能有多个备注节点
}

type ApplyerInfo struct {
	UserId string `xml:"UserId"` //申请人userid
	Party  string `xml:"Party"`  //申请人所在部门pid
}

type SpRecordInfo struct {
	SpStatus     string          `xml:"SpStatus"`     //审批节点状态:1-审批中;2-已同意;3-已驳回;4-已转审
	ApproverAttr string          `xml:"ApproverAttr"` //节点审批方式:1-或签;2-会签
	Details      SpRecordDetails `xml:"Details"`      //审批节点详情。当节点为标签或上级时,一个节点可能有多个分支
}

type SpRecordDetails struct {
	Approver SpRecordApprover `xml:"Approver"` //分支审批人
	Speech   string           `xml:"Speech"`   //审批意见字段
	SpStatus string           `xml:"SpStatus"` //分支审批人审批状态:1-审批中;2-已同意;3-已驳回;4-已转审
	SpTime   string           `xml:"SpTime"`   //节点分支审批人审批操作时间,0为尚未操作
	Attach   string           `xml:"Attach"`   //节点分支审批人审批意见附件,赋值为media_id具体使用请参考:文档-获取临时素材
}

type SpRecordApprover struct {
	UserId string `xml:"UserId"` //分支审批人userid
}

type NotifyerInfo struct {
	UserId string `xml:"UserId"` //节点抄送人userid
}

type CommentsInfo struct {
	UserId string `xml:"UserId"` //备注人userid
}

func Events(c *gin.Context) {
	var p P_Events
	if bind.Bind(c, &p, true) == nil {
		var res D_Events
		if buf, err := ioutil.ReadAll(c.Request.Body); err != nil {
			response.ServerError(c, err)
			return
		} else if msg, err := global.Wxcpt.DecryptMsg(p.Signature, p.Timestamp, p.Nonce, buf); err != nil {
			response.ServerError(c, errors.New(err.ErrMsg))
			return
		} else if err := xml.Unmarshal(msg, &res); err != nil {
			response.ServerError(c, err)
			return
		} else if res.MsgType == "event" && res.Event == "sys_approval_change" {
			//处理消息

			fmt.Println(res)
		}
	}
}

005.提交审批(golang)

package wxoa

import (
	"fmt"
	"wx_chat/src/modules/accesstoken"
	"wx_chat/src/utils/http"
)

type P_ApplyOrder struct {
	CreatorUserid       string `json:"creator_userid"`        //申请人userid,此审批申请将以此员工身份提交,申请人需在应用可见范围内
	TemplateId          string `json:"template_id"`           //模板id。可在“获取审批申请详情”、“审批状态变化回调通知”中获得,也可在审批模板的模板编辑页面链接中获得。暂不支持通过接口提交[打卡补卡][调班]模板审批单。
	UseTemplateApprover int    `json:"use_template_approver"` //审批人模式:0-通过接口指定审批人、抄送人(此时approver、notifyer等参数可用); 1-使用此模板在管理后台设置的审批流程(需要保证审批流程中没有“申请人自选”节点),支持条件审批。默认为0
	ChooseDepartment    int            `json:"choose_department"`     //提单者提单部门id,不填默认为主部门
	//Approver            []ApproverInfo `json:"approver"`              //审批流程信息,用于指定审批申请的审批流程,支持单人审批、多人会签、多人或签,可能有多个审批节点,仅use_template_approver为0时生效。
	//Notifyer            []string       `json:"notifyer"`              //抄送人节点userid列表,仅use_template_approver为0时生效。
	NotifyType int           `json:"notify_type"`          //抄送方式:1-提单时抄送(默认值); 2-单据通过后抄送;3-提单和单据通过后抄送。仅use_template_approver为0时生效。
	ApplyData  ApplyDataInfo `json:"apply_data,omitempty"` //审批申请数据,可定义审批申请中各个控件的值,其中必填项必须有值,选填项可为空,数据结构同“获取审批申请详情”接口返回值中同名参数“apply_data”
}

type ApproverInfo struct {
	Userid []string `json:"userid"` //审批节点审批人userid列表,若为多人会签、多人或签,需填写每个人的userid
	Attr   int      `json:"attr"`   //节点审批方式:1-或签;2-会签,仅在节点为多人审批时有效
}

type ApplyDataInfo struct {
	Contents []ContentsInfo `json:"contents"` //审批申请详情,由多个表单控件及其内容组成,其中包含需要对控件赋值的信息
}

type ContentsInfo struct {
	Control string    `json:"control"` //控件类型:Text-文本;Textarea-多行文本;Number-数字;Money-金额;Date-日期/日期+时间;Selector-单选/多选;;Contact-成员/部门;Tips-说明文字;File-附件;Table-明细;Location-位置;RelatedApproval-关联审批单;Formula-公式;DateRange-时长;
	Id      string    `json:"id"`      //控件id:控件的唯一id,可通过“获取审批模板详情”接口获取
	Value   ValueInfo `json:"value"`   //控件值 ,需在此为申请人在各个控件中填写内容不同控件有不同的赋值参数,具体说明详见附录。模板配置的控件属性为必填时,对应value值需要有值。
}

type ValueInfo struct {
	Text string `json:"text"` //
	//"text": "文本填写的内容"
	//"new_number": "700"
	//"new_money": "700"
	//"date": {"type": "day","s_timestamp": "1569859200"}
	//"selector": {"type": "multi","options": [{"key": "option-15111111111"},{"key": "option-15222222222"}]}
	//"members": [{"userid": "WuJunJie","name": "Jackie"},{"userid": "WangXiaoMing","name": "Tom"}]
	//"departments": [{"openapi_id": "2","name": "销售部"},{"openapi_id": "3","name": "生产部"}]
	//"files": [{"file_id": "1G6nrLmr5EC3MMb_-zK1dDdzmd0p7cNliYu9V5w7o8K1aaa"}]
	//"children": [控件]

}

func ApplyOrder() (err error) {
	//获取token
	var token string
	if token, err = accesstoken.GetOA(); err != nil {
		return
	}
	//请求消息
	url := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/oa/applyevent?access_token=%s", token)
	var body []byte
	if body, err = http.Post(url, P_ApplyOrder{
		CreatorUserid:       "CreatorUserid",
		TemplateId:          "TemplateId",
		UseTemplateApprover: 1, //后台自带审批
		ChooseDepartment:    2, //微信商城部门ID
		//Notifyer:            []string{},
		NotifyType: 1,
		//Approver:            []ApproverInfo{},
		ApplyData: ApplyDataInfo{
			Contents: []ContentsInfo{
				{
					Control: "Text",
					Id:      "Text-1681803392383",
					Value: ValueInfo{
						Text: "我是测试的审批啊啊啊啊啊",
					},
				},
			},
		},
	}); err != nil {
		return
	}
	//Text-1681803392383

	fmt.Println(string(body))
	return
}