實現目的:
新增供應商保存后,觸發釘釘審批流程,并根據釘釘審批結果回寫是否合格供應商。
實現思路:
通過BOS平臺供在應商管理界面新增兩個復選框字段:是否釘釘審批、是否合格供應商,若在新建供應商檔案時勾選是否釘釘審批,在保存供應商信息的時候調用二開插件傳遞釘釘審批,同時啟動子線程定時任務,定時獲取釘釘審批結果,若釘釘審批通過則需要自動回寫合格供應商。
實現過程:
1、新建.net framework項目,引入金蝶插件,引入釘釘插件(TopSdk)。
2、新建釘釘幫助類,用于獲取token、userid等信息:
using DingTalk.Api;
using DingTalk.Api.Request;
using DingTalk.Api.Response;
using System.Collections.Generic;namespace K3Cloud.BasicData.Supply.SupplySendDing
{public class DingtalkHelper{public static string GetToken() {DefaultDingTalkClient defaultDingTalkClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");OapiGettokenRequest OapiGettokenRequest = new OapiGettokenRequest();OapiGettokenRequest.Appkey = "你的appkey";OapiGettokenRequest.Appsecret = "你的appsecret";OapiGettokenRequest.SetHttpMethod("GET");OapiGettokenResponse oapiGettokenResponse = defaultDingTalkClient.Execute(OapiGettokenRequest);return oapiGettokenResponse.AccessToken;}public static string GetUserId(string token,string name) {DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/simplelist");OapiUserSimplelistRequest req = new OapiUserSimplelistRequest();req.Lang = "zh_CN";req.DepartmentId = 51236588;//采購部門id,在釘釘后臺查看req.SetHttpMethod("GET");OapiUserSimplelistResponse rsp = client.Execute(req, token);Dictionary<string, string> map = new Dictionary<string, string>();rsp.Userlist.ForEach(x =>{map[x.Name] = x.Userid;});return map[name];}}
}
3、新建釘釘流程創建操作類:
using DingTalk.Api.Request;
using DingTalk.Api.Response;
using DingTalk.Api;
using System;
using System.Collections.Generic;namespace K3Cloud.BasicData.Supply.SupplySendDing
{public class DingtalkStart{public static string StartSupplyNew(string token,string userId,string code,string name,string supplyCate,string address) {DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/processinstance/create");OapiProcessinstanceCreateRequest req = new OapiProcessinstanceCreateRequest();req.AgentId = 39568215863;req.ProcessCode = "表單code";req.OriginatorUserId = userId;req.DeptId = 50212358; //采購部id//單行輸入框List<OapiProcessinstanceCreateRequest.FormComponentValueVoDomain> formComponentValueVoList = new List<OapiProcessinstanceCreateRequest.FormComponentValueVoDomain>();OapiProcessinstanceCreateRequest.FormComponentValueVoDomain formComponentValueVo = new OapiProcessinstanceCreateRequest.FormComponentValueVoDomain();formComponentValueVoList.Add(formComponentValueVo);formComponentValueVo.Name = "編碼";formComponentValueVo.Value = code;OapiProcessinstanceCreateRequest.FormComponentValueVoDomain formComponentValueVo1 = new OapiProcessinstanceCreateRequest.FormComponentValueVoDomain();formComponentValueVoList.Add(formComponentValueVo1);formComponentValueVo1.Name = "名稱";formComponentValueVo1.Value = name;OapiProcessinstanceCreateRequest.FormComponentValueVoDomain formComponentValueVo2 = new OapiProcessinstanceCreateRequest.FormComponentValueVoDomain();formComponentValueVoList.Add(formComponentValueVo2);formComponentValueVo2.Name = "日期";formComponentValueVo2.Value = DateTime.Now.ToString("yyyy-MM-dd");OapiProcessinstanceCreateRequest.FormComponentValueVoDomain formComponentValueVo3 = new OapiProcessinstanceCreateRequest.FormComponentValueVoDomain();formComponentValueVoList.Add(formComponentValueVo3);formComponentValueVo3.Name = "供應商分組";formComponentValueVo3.Value = supplyCate;OapiProcessinstanceCreateRequest.FormComponentValueVoDomain formComponentValueVo4 = new OapiProcessinstanceCreateRequest.FormComponentValueVoDomain();formComponentValueVoList.Add(formComponentValueVo4);formComponentValueVo4.Name = "注冊地址";formComponentValueVo4.Value = address;req.FormComponentValues_ = formComponentValueVoList;OapiProcessinstanceCreateResponse rsp = client.Execute(req, token);return rsp.ProcessInstanceId;}}
}
4、封裝獲取釘釘審批狀態類:
using DingTalk.Api.Request;
using DingTalk.Api.Response;
using DingTalk.Api;namespace K3Cloud.BasicData.Supply.SupplySendDing
{public class DingtalkGet{public static string GetSupplyNewField(string processId) {DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/processinstance/get");OapiProcessinstanceGetRequest req = new OapiProcessinstanceGetRequest();req.ProcessInstanceId = processId;OapiProcessinstanceGetResponse rsp = client.Execute(req, DingtalkHelper.GetToken());if (rsp.ProcessInstance.Status == "TERMINATED" || rsp.ProcessInstance.Status == "CANCELED") {return "否";}if (rsp.ProcessInstance.Result == "refuse"){return "否";}if (rsp.ProcessInstance.Status == "COMPLETED" && rsp.ProcessInstance.Result == "agree"){foreach (var item in rsp.ProcessInstance.FormComponentValues){if (item.Name == "是否轉批產"){return item.Value;}}}return null;}}
}
5、金蝶插件開發:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using Kingdee.BOS.Core.Bill.PlugIn;
using Kingdee.BOS.Core.Bill.PlugIn.Args;
using Kingdee.BOS.Util;
using Kingdee.BOS.Log;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.App.Data;
using Kingdee.BOS;
using System.Timers;namespace K3Cloud.BasicData.Supply.SupplySendDing
{/// <summary>/// 新增供應商觸發釘釘審批/// </summary>[Description("新增供應商觸發釘釘審批")][HotUpdate]public class SupplySendDingAfterSaveEventBillPlugIn : AbstractBillPlugIn{private string token;private string instanceId;private System.Timers.Timer timer;private string isOk;private string supplierCode; // 保存供應商編碼用于線程中使用public override void AfterSave(AfterSaveEventArgs e){base.AfterSave(e);//是否發送釘釘審批var IsSend = this.Model.DataObject["F_UNW_CheckBox_qtr"].ToString();if (IsSend == "True"){//供應商編碼supplierCode = this.Model.GetValue("FNUMBER").ToString();//供應商名稱var name = this.Model.GetValue("FName").ToString();//創建人姓名DynamicObject creatorId = (DynamicObject)this.Model.GetValue("FCREATORID");var createtorName = creatorId["NAME"].ToString();//供應商分組var fGroup = (DynamicObject)this.Model.DataObject["FGroup"];var fGroupId = fGroup["ID"];var sql = "SELECT FNAME FROM T_BD_SUPPLIERGROUP_L WHERE FID= @fid";var sqlParam = new SqlParam("@fid", KDDbType.Int64, Convert.ToInt64(fGroupId));string fGroupName = "";using (var fReader = DBUtils.ExecuteReader(this.Context, sql, sqlParam)){while (fReader.Read()){fGroupName = fReader["FNAME"].ToString();}}//注冊地址var subEntity = this.View.BillBusinessInfo.GetEntity("FBaseInfo");var subObjs = this.Model.GetEntityDataObject(subEntity);var address = subObjs[0]["RegisterAddress"].ToString();token = DingtalkHelper.GetToken();string uid = DingtalkHelper.GetUserId(token, createtorName);//觸發釘釘流程instanceId = DingtalkStart.StartSupplyNew(token, uid, supplierCode, name, fGroupName, address);Logger.Error("TEST", "釘釘流程發送成功!", new Exception("無錯誤"));//啟動新線程執行定時任務Thread timerThread = new Thread(StartTimerTask);timerThread.IsBackground = true; // 設置為后臺線程timerThread.Start();}}/// <summary>/// 在新線程中啟動定時任務/// </summary>private void StartTimerTask(){try{//1分鐘檢查一次timer = new System.Timers.Timer(60000);timer.Elapsed += TimerElapsed;timer.AutoReset = true;timer.Enabled = true;//循環等待審批結果while (string.IsNullOrEmpty(isOk)){Thread.Sleep(1000); // 減少CPU占用}//處理審批結果if (isOk == "是"){var usql = "UPDATE T_BD_SUPPLIER SET F_UNW_CHECKBOX_83G='1' WHERE FNUMBER=@FNo";var sqlParameterList = new List<SqlParam>{new SqlParam("@FNo", KDDbType.AnsiString, supplierCode)};DBUtils.Execute(this.Context, usql, sqlParameterList);}//清理定時器timer.Stop();timer.Dispose();}catch (Exception ex){Logger.Error("定時任務處理異常", ex.Message, ex);}}private void TimerElapsed(object sender, ElapsedEventArgs e){try{var res = DingtalkGet.GetSupplyNewField(instanceId);if (!string.IsNullOrEmpty(res)){isOk = res;}}catch (Exception ex){Logger.Error("獲取審批結果異常", ex.Message, ex);isOk = "異常"; // 標記異常狀態,退出循環}}}
}
6、將上述代碼編譯成dll文件,并在bos平臺進行注冊,重啟IIS服務。