企业微信开发实战(二、OA审批之获取审批模版详情&提交审批申请) 您所在的位置:网站首页 oa怎么创建模板 企业微信开发实战(二、OA审批之获取审批模版详情&提交审批申请)

企业微信开发实战(二、OA审批之获取审批模版详情&提交审批申请)

2023-11-27 20:27| 来源: 网络整理| 查看: 265

文章目录 三、OA-审批1.概述1.1场景描述1.2与“审批流程引擎”的区别 2.获取审批模板详情2.1线上调试2.2代码实战2.2.1获取access_token2.2.2试错2.2.3获取模版详情2.2.4试错 3.提交审批申请3.1代码实战3.2试错 源码赞赏

三、OA-审批 1.概述

目前,企业微信审批应用对企业内部提供了以下接口和能力:

获取审批模板详情提交审批申请审批申请状态变化回调通知批量获取审批编号获取审批申请详情 1.1场景描述

(1)企业可通过审批应用或自建应用secret换取access_token,用于企业微信审批应用相关接口调用。

(2)首先,可通过“获取审批模板详情”接口,了解模板内的控件构成及控件id。 (3)然后,可通过“提交审批申请”,利用模板id和控件id,代员工发起和填写审批申请,自定义审批流程。 (4)审批前后,可通过“审批申请状态变化回调通知”,订阅审批单据流转的变化,进行各项拓展动作。 (5)此外,还可通过“批量获取审批编号”、“获取审批申请详情”接口,随时获取审批申请的内容详情和流程状态。

审批开放接口场景描述

1.2与“审批流程引擎”的区别

(1)企业微信审批应用相关接口,是围绕“审批应用”的开放,数据的写入、读取对象都为企业微信“审批应用”。

(2)“审批流程引擎”相关接口,是在“自建应用”或“第三方应用”中增加流程相关功能,使用和作用对象都为“自建应用”或“第三方应用”,不会影响企业微信“审批应用”。

(3)注:如下图所示指向的"审批"和"自建审批应用"都属于是企业内部开发,其获取AccessToken的方式参考“获取access_token”。而第三方应用获取AccessToken的方式参考参考“获取企业凭证”。这里有个概念就行,后面主要讲企业内部开发的两种方式。 在这里插入图片描述

2.获取审批模板详情

企业可通过审批应用或自建应用Secret调用本接口,获取企业微信“审批应用”内指定审批模板的详情。官方文档链接

企业微信官方线上调试:调试工具

**请求方式:**POST(HTTPS) **请求地址:**https://qyapi.weixin.qq.com/cgi-bin/oa/gettemplatedetail?access_token=ACCESS_TOKEN

请求示例:

{ "template_id" : "ZLqk8pcsAoXZ1eYa6vpAgfX28MPdYU3ayMaSPHaaa"}//请求体(body)中的内容

较早时间创建的模板,id为类似“1910324946027731_1688852032423522_1808577376_15111111111”的数字串。

参数说明:

参数必须说明access_token是调用接口凭证。必须使用审批应用或企业内自建应用的secret获取,获取方式参考:文档-获取access_tokentemplate_id是模板的唯一标识id。可在“获取审批单据详情”、“审批状态变化回调通知”中获得,也可在审批模板的模板编辑页面浏览器Url链接中获得。

1.审批应用的Secret可获取企业自建模板及第三方服务商添加的模板详情;自建应用的Secret可获取企业自建模板的模板详情。 2.接口调用频率限制为600次/分钟。 在这里插入图片描述

2.1线上调试

1、找到"应用管理"->“审批”->“API”->“查看”->“发送”,此时企业微信将会收到该应用的密钥,自己保存好即可。 在这里插入图片描述

2、点击调试工具,进入官方提供的调试界面,其中corpid指的是企业id(在后台"我的企业"可看到),corpsecret指的是上一步中在企业微信客户端收到的secret,填写完后,点击"获取access_token"按钮,即可看到输出的token,如下图: 在这里插入图片描述 在这里插入图片描述

3、找到"应用管理"->“审批”->“请假"模版,最后一个”/“中的字符串为该模版的id,复制即可。 在这里插入图片描述 4、将第"3’'步中的id替换掉下图的"template_id”,点击"调用接口"按钮即可。 在这里插入图片描述

5、将滚动条拖到底部,可看到如下图所示输出该模版的详情信息。 在这里插入图片描述

2.2代码实战 2.2.1获取access_token

1、创建一个ASP.NET Core Web(Razor)项目。

2、具体代码如下:

[Route("api/[controller]")] public class SampleDataController : Controller { //控制器中注入缓存中间件 private MemoryCacheHelper _cahce; public SampleDataController(IMemoryCache cahce) { _cahce = cahce; } #region 1、获取accessToken /// /// 请求企业微信accessToken /// /// private async Task RequireAccessToken() { var result = new AccessTokenModel(); try { string corpid = "你的企业微信id"; string secret = "你的审批应用密钥"; string url = $"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpi}&corpsecret={secret}"; using (HttpClient client = new HttpClient()) { result = JsonConvert.DeserializeObject(await client.GetStringAsync(url));//将请求到的json序列化为模型类 } } catch (Exception ex) { throw; } return result; } /// /// 获取内存中的accessToken /// /// [Route("CacheTryGetToken")] public IActionResult CacheTryGetToken() { return Json(GetAccessToken()); } /// /// 获取缓存中的accesstoken /// /// private AccessTokenModel GetAccessToken() { var accessToken = _cahce.Get(PublicParam.accessTokenKey); if (accessToken == null) { accessToken = RequireAccessToken().Result; _cahce.Set(PublicParam.accessTokenKey, accessToken, TimeSpan.FromSeconds(PublicParam.sleepTime)); } return accessToken; } #endregion /// /// AccessToken模型类 /// public class AccessTokenModel { /// /// 错误码 /// public string errcode { get; set; } /// /// 错误信息 /// public string errmsg { get; set; } /// /// access_token /// public string access_token { get; set; } /// /// 超时时间 /// public long expires_in { get; set; } } public class JsonContent : StringContent { public JsonContent(object obj) : base(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json") { } } }

3、运行项目,并访问https://localhost:5001/api/SampleData/CacheTryGetToken ,可看到如下的token数据: 在这里插入图片描述

2.2.2试错

1、此时给请求access_token的corpi(企业id)后面随意加个字符,会出现如下所示错误,意思是企业id有误,故需排查一下密钥是否填写错误。

{ "access_token": null, "expires_in": 0, "errcode": "40013", "errmsg": "invalid corpid, hint: [1619103786_194_2ee3fb91c5238be28588ceed7a444d23], from ip: 119.129.123.127, more info at https://open.work.weixin.qq.com/devtool/query?e=40013" }

2、在请求access_token的corpsecret(应用密钥)后面随意加个字符,会出现如下所示错误,提示错误的凭据,原因是密钥有误,故需排查一下密钥是否填写错误。

{ "access_token": null, "expires_in": 0, "errcode": "40001", "errmsg": "invalid credential, hint: [1619103952_195_a01894928bf0bce72d1467131c09363f], from ip: 119.129.123.127, more info at https://open.work.weixin.qq.com/devtool/query?e=40001" } 2.2.3获取模版详情

1、请求"请假"模版详情数据的代码如下:

#region 2、获取模版详情 /// /// 获取模版详情 /// /// [Route("TemplateDetails")] public async Task TemplateDetails() { //获取token var model = GetAccessToken(); string accessToken = ""; if (model != null) accessToken = model.access_token; string url = "https://qyapi.weixin.qq.com/cgi-bin/oa/gettemplatedetail?access_token=" + accessToken;//构建请求url using (HttpClient client = new HttpClient()) { //template_id(请看“线上调试”篇章) var response = await client.PostAsync(url, new JsonContent(new { template_id = "你的模版id" })); //获取请求到数据,并转化为字符串 var res = response.Content.ReadAsStringAsync().Result; return Content(res); } } #endregion

2、运行项目,并访问https://localhost:5001/api/SampleData/TemplateDetails,可看到如下的"请假"模版数据: 在这里插入图片描述

3、模版参数参考官方文档:https://open.work.weixin.qq.com/api/doc/90000/90135/91982

2.2.4试错

1、在上述TemplateDetails接口的url后随意加一个字符(让token与缓存中的不一致),会出现如下错误,提示无效的access_token。

{ "errcode": 40014, "errmsg": "invalid access_token", "template_names": [] }

2、在上述TemplateDetails接口的templateid后随意加一个字符(让templateid不存在),会出现如下错误,提示"提交审批单请求参数错误",因为请求体(body)只有一个参数,故此时应排查templateid是否有误。

{ "errcode": 301025, "errmsg": "get approval param error, hint: [1619104495_170_e21873150fdc0119da67c4fe98dafe69], from ip: 119.129.123.127, more info at https://open.work.weixin.qq.com/devtool/query?e=301025", "template_names": [] } 3.提交审批申请

企业可通过审批应用或自建应用Secret调用本接口,代应用可见范围内员工在企业微信“审批应用”内提交指定类型的审批申请。

企业微信官方线上调试:调试工具

**请求方式:**POST(HTTPS) 请求地址: https://qyapi.weixin.qq.com/cgi-bin/oa/applyevent?access_token=ACCESS_TOKEN

请求示例(请假模版):(参数说明请看官方文档)

注:json数据是根据请求过的"请假审批申请"构建的,后面会介绍到如何请求审批申请详情数据。

{ "creator_userid": "发起申请的用户id", "template_id": "请假模版id", "use_template_approver": 0, "approver": [ { "attr": 1, "userid": [ "审批人id" ] } ], "notify_type": 1, "apply_data": { "contents": [ { "control": "Vacation", "id": "vacation-1563793073898", "title": [ { "text": "请假类型", "lang": "zh_CN" }, { "text": "Leave Type", "lang": "en" } ], "value": { "tips": [], "members": [], "departments": [], "files": [], "children": [], "stat_field": [], "vacation": { "selector": { "type": "single", "options": [ { "key": "1", "value": [ { "text": "年假", "lang": "zh_CN" } ] } ] }, "attendance": { "date_range": { "type": "halfday", "new_begin": 1618848000, "new_end": 1618891200, "new_duration": 86400 }, "type": 1, "slice_info": { "day_items": [ { "daytime": 1618848000, "time_sections": [], "duration": 28800 } ], "duration": 28800 } } }, "sum_field": [], "related_approval": [], "students": [], "classes": [] } }, { "control": "Textarea", "id": "item-1497581399901", "title": [ { "text": "请假事由", "lang": "zh_CN" }, { "text": "Leave Reason", "lang": "en" } ], "value": { "text": "你猜猜看", "tips": [], "members": [], "departments": [], "files": [], "children": [], "stat_field": [], "sum_field": [], "related_approval": [], "students": [], "classes": [] } }, { "control": "File", "id": "item-1497581426169", "title": [ { "text": "说明附件", "lang": "zh_CN" }, { "text": "Attachment", "lang": "en" } ], "value": { "tips": [], "members": [], "departments": [], "files": [], "children": [], "stat_field": [], "sum_field": [], "related_approval": [], "students": [], "classes": [] } } ] }, "summary_list": [ { "summary_info": [ { "text": "请假类型:年假", "lang": "zh_CN" } ] }, { "summary_info": [ { "text": "开始时间:2021/4/21 上午", "lang": "zh_CN" } ] }, { "summary_info": [ { "text": "结束时间:2021/4/21 下午", "lang": "zh_CN" } ] } ] } 3.1代码实战

1、用户id对应的是"通讯录"->“xxx成员”->“账号”,如下图所示: 在这里插入图片描述 2、执行上述json之前,请先手动在企业微信客户端进行"请假"申请的发起,了解具体有哪些控件,会做哪些操作。

3、大致请求代码如下(其他帮助类存放在代码的ApplyEventModel中,具体看git仓库),请思路是A(发起人)发起一个请假申请,B(审批人)对该请假申请进行审批:

#region 3、提交审批申请 /// /// 提交审批申请 /// /// 审批人id,如果不填写,就默认推送给的另一个微信号 /// [Route("ApplyEvent")] public async Task ApplyEvent(string approver= "审批人id") { //get token var model = GetAccessToken(); string accessToken = ""; if (model != null) accessToken = model.access_token; //build request url string url = "https://qyapi.weixin.qq.com/cgi-bin/oa/applyevent?access_token=" + accessToken;//构建请求url //request using (HttpClient client = new HttpClient()) { var response = await client.PostAsync(url, new JsonContent(BuildApplyEventModel(approver))); //获取请求到数据,并转化为字符串 var res = response.Content.ReadAsStringAsync().Result; return Content(res); } } /// /// 构建ApplyEventModel /// /// 审批人id /// private ApplyEventModel BuildApplyEventModel(string approver) { ApplyEventModel model = new ApplyEventModel(); model.creator_userid = "创建人id"; model.template_id = "请假模版id"; model.use_template_approver = 0; model.approver = new List() { //审批人id数据,可以有多个审批人 new ApproverModel(){ userid=new List(){ approver },attr=1 } }; model.notify_type = 1; model.apply_data = BuildApplyData(); model.summary_list = BuildSummaryList(); var jsonModel = JsonConvert.SerializeObject(model); return model; } /// /// 构建apply_data /// /// private ApplyData BuildApplyData() { var contentsList = new List() { new Contents(){ control="Vacation", id="vacation-1563793073898", title = new List() { new Title(){ text="请假类型",lang="zh_CN"}, new Title(){ text="Leave Type",lang="en"} }, value=new Value { tips = new List(), members = new List(), departments = new List(), files = new List(), children = new List(), stat_field = new List(), vacation = new Vacation() { selector = new Selector() { type = "single", options = new List() { new Options(){ key="1", value = new List() { new Title(){text="年假",lang="zh_CN"} } } } }, attendance = new Attendance() { date_range = new Date_range() { type = "halfday", new_begin= 1618848000, new_end = 1618891200, new_duration=86400 }, type = 1, slice_info = new Slice_info() { day_items = new List() { new Day_items() { daytime = 1618848000, time_sections = new List(), duration = 28800 } }, duration = 28800 }, }, }, sum_field = new List(), related_approval = new List(), students = new List(), classes = new List() } }, new Contents() { control = "Textarea", id = "item-1497581399901", title = new List() { new Title() { text = "请假事由", lang = "zh_CN" }, new Title() { text="Leave Reason", lang = "en" } }, value = new Value() { text = "你猜猜看" } }, new Contents() { control = "File", id = "item-1497581426169", title = new List() { new Title() { text = "说明附件", lang = "zh_CN" }, new Title() { text="Attachment", lang = "en" } }, value = new Value() } }; ApplyData model = new ApplyData(); model.contents = contentsList; return model; } /// /// 构建Summary_list(客户端收到的推送显示的内容) /// /// private List BuildSummaryList() { List list = new List() { new Summary_list() { summary_info = new List() { new Summary_info() { text = "请假类型:年假", lang = "zh_CN" } }, }, new Summary_list() { summary_info = new List() { new Summary_info() { text = "开始时间:2021/4/21 上午", lang = "zh_CN" } }, }, new Summary_list() { summary_info = new List() { new Summary_info() { text = "结束时间:2021/4/21 下午", lang = "zh_CN" } }, }, }; return list; } #endregion

4、请求结果如下,errmsg为ok则表示成功,其中sp_no是提交成功后返回的表单编号: 在这里插入图片描述

3.2试错

1、此时,将用户id改为当前企业微信不存在的用户id,则会出现如下错误,提示"审批参数有误,无效的用户id"

{ "errcode": 301025, "errmsg": "get approval param error:invalid userid:" }

2、在上述BuildApplyEventModel方法中的templateid后随意加一个字符(让templateid不存在),会出现如下错误,提示"提交审批单请求参数错误,操作的模版id",故此时应排查templateid是否有误。

{ "errcode": 301025, "errmsg": "get approval param error:invalid template_id" } 源码

地址:https://gitee.com/wusuoweixgy/QiYeWeiXinCode 克隆:git clone https://gitee.com/wusuoweixgy/QiYeWeiXinCode.git

赞赏

​ 如果您觉得文章还不错,那就请作者喝杯咖啡吧! 在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有