实现目的:
新增供应商保存后,触发钉钉审批流程,并根据钉钉审批结果回写是否合格供应商。
实现思路:
通过BOS平台供在应商管理界面新增两个复选框字段:是否钉钉审批、是否合格供应商,若在新建供应商档案时勾选是否钉钉审批,在保存供应商信息的时候调用二开插件传递钉钉审批,同时启动子线程定时任务,定时获取钉钉审批结果,若钉钉审批通过则需要自动回写合格供应商。
实现过程:
1、新建.net framework项目,引入金蝶插件,引入钉钉插件(TopSdk)。
2、新建钉钉帮助类,用于获取token、userid等信息:
cs
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、新建钉钉流程创建操作类:
cs
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、封装获取钉钉审批状态类:
cs
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、金蝶插件开发:
cs
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服务。