金蝶云星空插件开发记录(一)

实现目的:

新增供应商保存后,触发钉钉审批流程,并根据钉钉审批结果回写是否合格供应商。

实现思路:

通过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服务。

相关推荐
大飞pkz7 小时前
【设计模式】题目小练1
开发语言·设计模式·c#·题目小练
lljss20208 小时前
C# 每个chartArea显示最小值、平均值、最大值
开发语言·c#
wearegogog1239 小时前
C#与Twincat 2 实现上位机控制软PLC功能
开发语言·c#
军训猫猫头9 小时前
12.NModbus4在C#上的部署与使用 C#例子 WPF例子
开发语言·c#·wpf
Eiceblue10 小时前
使用 C# 设置 Excel 单元格格式
开发语言·后端·c#·.net·excel
LostXerxes11 小时前
C#的继承和多态
c#
薄荷撞~可乐12 小时前
C#高并发与并行理解处理
开发语言·c#
sali-tec12 小时前
C# 基于halcon的视觉工作流-章33-矩状测量
开发语言·人工智能·算法·计算机视觉·c#
王维志13 小时前
Unity Embedded Browser文档翻译
unity·c#