二开案例.工作流插件.参与人插件.自定义参与人
【应用场景】
工作流,流程设计器,参与人配置,当系统内置的参与人类型无法满足需求时,可增加自定义参与人类型。
【案例演示】
新增两个自定义参与人:销售员,操作员。
【实现步骤】
<1>编写参与人插件,代码如下。
using Kingdee.BOS; using Kingdee.BOS.App.Data; using Kingdee.BOS.Util; using Kingdee.BOS.Workflow.App.Core.Participant.MemberWrapper; using Kingdee.BOS.Workflow.Models.Member; using Kingdee.BOS.WorkflowMember; using System; using System.Collections.Generic; using System.Linq; namespace Jac.XkDemo.BOS.App.PlugIn { /// <summary> /// 销售员 /// </summary> public class SalerCustomizeMemberPlugIn : CustomizeMemberPlugIn { /// <summary> /// 用户在流程节点上设置自定义参与人时,可选的基础资料FormId /// </summary> public override List<string> ParticipantFormIds { get { // TODO 按需求设置可选的基础资料FormID,比如允许用户选择“销售员”类型的基础资料 return new List<string>() { "BD_Saler" }; // 销售员 } } /// <summary> /// 把参与人基础资料解析成具体用户ID /// </summary> /// <param name="ctx">BOS上下文</param> /// <param name="members">已经解析好的基础资料常量</param> /// <returns>作为参与人的具体用户ID</returns> public override List<long> GetCustomUser(Context ctx, List<IMember> members) { // 获取销售员内码 var operatorIds = members.Where(member => ((CustomPartiMember)member).ParticipantFormId.EqualsIgnoreCase("BD_Saler")).Select(member => int.Parse(member.Id)).ToList(); // 通过销售员内码,获取其绑定的用户的内码 var userIds = new List<long>(); if (operatorIds.Count > 0) { string sql = @"SELECT U.FUSERID FROM T_BD_OPERATORENTRY OPERA INNER JOIN T_BD_STAFF STAFF ON OPERA.FSTAFFID = STAFF.FSTAFFID AND STAFF.FDOCUMENTSTATUS = 'C' AND STAFF.FFORBIDSTATUS = 'A' INNER JOIN V_BD_CONTACTOBJECT CONTACT ON STAFF.FPERSONID = CONTACT.fid AND CONTACT.FDOCUMENTSTATUS = 'C' AND CONTACT.FFORBIDSTATUS = 'A' INNER JOIN T_SEC_USER U ON U.FLINKOBJECT = CONTACT.fid AND U.FFORBIDSTATUS = 'A' WHERE OPERA.FISUSE = '1' AND OPERA.FENTRYID IN (SELECT FID FROM TABLE(fn_StrSplit(@OperatorIds,',',1)))"; var parameters = new SqlParam[] { new SqlParam("@OperatorIds", KDDbType.udt_inttable, operatorIds.ToArray()) }; var userObjs = DBUtils.ExecuteDynamicObject(ctx, sql, paramList: parameters); userIds.AddRange(userObjs.Select(i => Convert.ToInt64(i["FUSERID"]))); } return userIds; } } /// <summary> /// 操作员 /// </summary> public class OperatorCustomizeMemberPlugIn : CustomizeMemberPlugIn { /// <summary> /// 用户在流程节点上设置自定义参与人时,可选的基础资料FormId /// </summary> public override List<string> ParticipantFormIds { get { return new List<string>() { "BD_Saler", "BD_BUYER", "BD_Inspector" }; // 销售员、采购员、质检员 } } /// <summary> /// 把参与人基础资料解析成具体用户ID /// </summary> /// <param name="ctx">BOS上下文</param> /// <param name="members">已经解析好的基础资料常量</param> /// <returns>作为参与人的具体用户ID</returns> public override List<long> GetCustomUser(Context ctx, List<IMember> members) { // 基础资料类型是业务员,先获取业务员内码集合,再获取其对应的用户的内码集合 var operatorIds = members.Select(member => int.Parse(member.Id)).ToList(); // 通过销售员内码,获取其绑定的用户的内码 var userIds = new List<long>(); if (operatorIds.Count > 0) { string sql = @"SELECT U.FUSERID FROM T_BD_OPERATORENTRY OPERA INNER JOIN T_BD_STAFF STAFF ON OPERA.FSTAFFID = STAFF.FSTAFFID AND STAFF.FDOCUMENTSTATUS = 'C' AND STAFF.FFORBIDSTATUS = 'A' INNER JOIN V_BD_CONTACTOBJECT CONTACT ON STAFF.FPERSONID = CONTACT.fid AND CONTACT.FDOCUMENTSTATUS = 'C' AND CONTACT.FFORBIDSTATUS = 'A' INNER JOIN T_SEC_USER U ON U.FLINKOBJECT = CONTACT.fid AND U.FFORBIDSTATUS = 'A' WHERE OPERA.FISUSE = '1' AND OPERA.FENTRYID IN (SELECT FID FROM TABLE(fn_StrSplit(@OperatorIds,',',1)))"; var parameters = new SqlParam[] { new SqlParam("@OperatorIds", KDDbType.udt_inttable, operatorIds.ToArray()) }; var userObjs = DBUtils.ExecuteDynamicObject(ctx, sql, paramList: parameters); userIds.AddRange(userObjs.Select(i => Convert.ToInt64(i["FUSERID"]))); } return userIds; } } }
<2>连接数据库,执行以下SQL脚本,注册参与人插件。
-- 注册自定义参与人类型:销售员 DELETE T_WF_ParticipantType WHERE FID='SalerCustomizeMemberPlugIn'; INSERT INTO T_WF_ParticipantType(FID,FNAME,FGROUP,FTREENODEKEY,FHANDLERCLASS,FORDER,FWRAPPERCLASS,FSUPPORTSCENE) VALUES ('SalerCustomizeMemberPlugIn',N'销售员',N'自定义','FPanelSaler','Kingdee.BOS.Workflow.PlugIns.ParticipantMember.CustomPartiHandler,Kingdee.BOS.Workflow.PlugIns',200 ,'Jac.XkDemo.BOS.App.PlugIn.SalerCustomizeMemberPlugIn,Jac.XkDemo.BOS.App.PlugIn',251); DELETE T_WF_ParticipantType_L WHERE FID='SalerCustomizeMemberPlugIn' AND FLOCALEID = 2052; INSERT INTO T_WF_ParticipantType_L(FPKID,FID,FLOCALEID,FNAME,FGROUP) VALUES ((SELECT MAX(FPKID)+1 FROM T_WF_ParticipantType_L),'SalerCustomizeMemberPlugIn',2052,N'销售员',N'自定义'); -- 注册自定义参与人类型:操作员 DELETE T_WF_ParticipantType WHERE FID='OperatorCustomizeMemberPlugIn'; INSERT INTO T_WF_ParticipantType(FID,FNAME,FGROUP,FTREENODEKEY,FHANDLERCLASS,FORDER,FWRAPPERCLASS,FSUPPORTSCENE) VALUES ('OperatorCustomizeMemberPlugIn',N'操作员',N'自定义','FPanelOperator','Kingdee.BOS.Workflow.PlugIns.ParticipantMember.CustomPartiHandler,Kingdee.BOS.Workflow.PlugIns',201 ,'Jac.XkDemo.BOS.App.PlugIn.OperatorCustomizeMemberPlugIn,Jac.XkDemo.BOS.App.PlugIn',251); DELETE T_WF_ParticipantType_L WHERE FID='OperatorCustomizeMemberPlugIn' AND FLOCALEID = 2052; INSERT INTO T_WF_ParticipantType_L(FPKID,FID,FLOCALEID,FNAME,FGROUP) VALUES ((SELECT MAX(FPKID)+1 FROM T_WF_ParticipantType_L),'OperatorCustomizeMemberPlugIn',2052,N'操作员',N'自定义');
<3>拷贝插件组件到应用站点的WebSite\Bin目录下,重启IIS,开发完毕。
【功能验证】
<1>登录业务站点,进入流程设计中心,打开流程设计器,进入到参与人页签,此时,已经可以看到自定义的参与人类型,在这里配置好参与人后,运行时就能正确解析到对应的用户啦。
设计时:
运行时:
【注意事项】
<1>使用SQL脚本注册插件时,表T_WF_ParticipantType的字段FTREENODEKEY的值不能重复,如果有重复值,流程设计器会报错。
<2>自定义参与人插件中的属性ParticipantFormIds返回的基础资料类型,必须有单据状态字段和禁用状态字段,如果不存在这两个字段,流程设计器在打开列表选择参与人时会报错。
单据状态字段:字段标识必须是FDOCUMENTSTATUS,属性名必须是:DocumentStatus
禁用状态字段:字段标识必须是FFORBIDSTATUS,属性名必须是:ForbidStatus
【参考资料】
【工作流服务插件-自定义参与人】https://vip.kingdee.com/article/469469895499856896
---------------------------------------------------------------------------------------------------------
【金蝶云星空BOS二次开发案例演示】https://vip.kingdee.com/article/94751030918525696
二开案例.工作流插件.参与人插件.自定义参与人
本文2024-09-23 03:35:59发表“云星空知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-k3cloud-159889.html