最近看到一个配置反审核操作触发工作流的教程,就想能不能插件中直接调用生成工作流方法直接触发工作流,于是便反编译大佬代码尝试了一下,结果还真有方法,下面分享给大家:
设计采购申请单工作流正向流程
设计采购申请单工作流反向流程
设计流程设置中心流程启动条件
4.代码部分
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Transactions;
using Kingdee.BOS;
using Kingdee.BOS.App;
using Kingdee.BOS.App.Core;
using Kingdee.BOS.App.Core.ScheduleService;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Business.Bill.Operation;
using Kingdee.BOS.Business.Bill.Operation.Workflow;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.Core.DependencyRules;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.List;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.StatusElement;
using Kingdee.BOS.Core.Schedules;
using Kingdee.BOS.KDThread;
using Kingdee.BOS.Log;
using Kingdee.BOS.Orm;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Resource;
using Kingdee.BOS.Scripting;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using Kingdee.BOS.Workflow.App.Core;
using Kingdee.BOS.Workflow.App.Core.Repositories;
using Kingdee.BOS.Workflow.Assignment;
using Kingdee.BOS.Workflow.Engine;
using Kingdee.BOS.Workflow.Enums;
using Kingdee.BOS.Workflow.Hosting;
using Kingdee.BOS.Workflow.Models;
using Kingdee.BOS.Workflow.Models.EnumStatus;
using Kingdee.BOS.Workflow.Models.Template;
using Kingdee.BOS.Workflow.Providers;
using Kingdee.BOS.Workflow.ServiceHelper;
namespace MyTestProject
{
[Kingdee.BOS.Util.HotUpdate]
[Description("反审核操作触发工作流")]
public class AuditSPL : AbstractOperationServicePlugIn
{
public override void OnPreparePropertys(PreparePropertysEventArgs e)
{
base.OnPreparePropertys(e);
e.FieldKeys.Add("F_YOL_LC");//是否生成流程
}
public override void BeginOperationTransaction(BeginOperationTransactionArgs e)
{
// BillTools datas = new BillTools();
base.BeginOperationTransaction(e);
if (this.FormOperation.Operation=="UnAudit")
{
foreach (var bill in e.DataEntitys)
{
if (Convert.ToBoolean( bill["F_YOL_LC"])==true)
{
bill["F_YOL_LC"] = false;
Kingdee.BOS.ServiceHelper.BusinessDataServiceHelper.Save(this.Context, bill);
}
else
{
List<DynamicObject> lists = new List<DynamicObject>();
//创建流程实例 select a.FTMPID 100003 ,FTMPDETAILID 100007 ,FVERSIONID 6041c6395a2034 from t_WF_Template a inner join t_wf_PrcLaunchConfig b on a.FTmpID=b.FTmpID--流程配置中心表
var sl = this.CreateProcessInstance(this.Context, this.BusinessInfo, "100003", "100007", "6041c6395a2034", bill["Id"], false, lists, 0, null, "");
bool result = this.StartWorkflow(this.Context, false, sl, this.GetMessageSendMode(this.Context));
// bool result = datas.TiggerWorkFlow(this.Context, this.BusinessInfo, "100003", "100007", "6041c6395a2034", bill["Id"].ToString(), 0);
if (result == true)
{
bill["F_YOL_LC"] = true;
Kingdee.BOS.ServiceHelper.BusinessDataServiceHelper.Save(this.Context, bill);
e.CancelOperation = true;
}
}
}
}
}
private ProcessInstance CreateProcessInstance(Context ctx, BusinessInfo info, string templeteId, string tempDetailId, string verId, object pkValue, bool writeProcessLog, List<DynamicObject> storeList, int? originatorPostId = null, string submitOpinion = null, string submitStatusKey = "")
{
WorkflowModelService workflowModelService = new WorkflowModelService();
CacheProcess cacheProcessByVersionId = workflowModelService.GetCacheProcessByVersionId(ctx, verId);
if (cacheProcessByVersionId == null)
{
throw new Exception(ResManager.LoadKDString("未找到对应的流程定义,版本Id:", "002525030016300", SubSystemType.BOS, new object[0]) + verId);
}
if (info == null)
{
throw new Exception(ResManager.LoadKDString("_businessInfo 未赋值。", "002525030021211", SubSystemType.BOS, new object[0]));
}
BOSFlowRepository bosflowRepository = new BOSFlowRepository(ctx);
WorkflowEngine workflowEngine = new WorkflowEngine(cacheProcessByVersionId.Process, ctx, bosflowRepository);
ProcessInstance processInstance = workflowEngine.CreateProcessInstance();
processInstance.TrySetMember("FormId", info.GetForm().Id);
processInstance.TrySetMember("FormName", info.GetForm().Name.ToString());
processInstance.TrySetMember("KeyValue", pkValue.ToString());
processInstance.ProcDefId = cacheProcessByVersionId.ProcDefId;
processInstance.VersionId = verId;
processInstance.OriginatorId = ctx.UserId;
processInstance.TempleteId = templeteId;
processInstance.TempDetailId = tempDetailId;
ProcessInstance processInstance2 = processInstance;
int? num = originatorPostId;
processInstance2.OriginatorPostId = ((num != null) ? new long?((long)num.GetValueOrDefault()) : null);
processInstance.CreatedTime = DateTime.Now;
processInstance.Summary = "123";
processInstance.SubmitOpinion = submitOpinion;
processInstance.SubmitStatusKey = ((submitStatusKey == null) ? "" : submitStatusKey);
this.InitProcInst(processInstance, ctx);
bosflowRepository.CreateProcessInstance(processInstance);
string workflowStartActivityCheckId = this.GetWorkflowStartActivityCheckId(info.GetForm().Id, pkValue);
this.AddStartBackMqStore(ctx, processInstance, workflowStartActivityCheckId, storeList);
return processInstance;
}
public string GetWorkflowStartActivityCheckId(string formId, object pkValue)
{
return formId + "_" + pkValue.ToString();
}
public void InitProcInst(ProcessInstance procInst, Context ctx)
{
object obj;
procInst.TryGetMember("FormId", out obj);
object obj2;
procInst.TryGetMember("KeyValue", out obj2);
if (obj == null || string.IsNullOrWhiteSpace(obj.ToString()) || obj2 == null || string.IsNullOrWhiteSpace(obj2.ToString()))
{
throw new Exception(ResManager.LoadKDString("流程实例的单据变量和单据编码变量不能为空", "002525030016507", SubSystemType.BOS, new object[0]));
}
procInst.Number = "CGSSD" + "_" + DateTime.Now.ToString("yyyy_MM_dd");//实例名称,一定要包含"_"
string strSQL = "\r\n insert into T_WF_PIBIMap(FId, FProcInstId, FObjectTypeId, FKeyValue)\r\n values(@FId, @FProcInstId, @FObjectTypeId, @FKeyValue)";
IDBService service = ServiceHelper.GetService<IDBService>();
List<SqlParam> list = new List<SqlParam>();
list.Add(new SqlParam("@FId", KDDbType.AnsiString, service.GetSequenceString(1)[0]));
list.Add(new SqlParam("@FProcInstId", KDDbType.AnsiString, procInst.MapInstanceId));
list.Add(new SqlParam("@FObjectTypeId", KDDbType.AnsiString, obj.ToString()));
list.Add(new SqlParam("@FKeyValue", KDDbType.AnsiString, obj2.ToString()));
DBUtils.Execute(ctx, strSQL, list);
}
public bool StartWorkflow(Context ctx, bool writeProcessLog, ProcessInstance pi, MessageSendMode messageSendMode)
{
if (messageSendMode == MessageSendMode.Sync || messageSendMode == MessageSendMode.Async)
{
try
{
this.SendSyncMessage<StartBackJobService>(ctx, pi, null, true);
}
catch (Exception)
{
return false;
}
return true;
}
else
{
try
{
this.SendAsyncMessage<StartBackJobService>(ctx, messageSendMode, pi, null);
}
catch (Exception)
{
return false;
}
return true;
}
}
public void AddStartBackMqStore(Context ctx, ProcessInstance pi, string startActivityInstId, List<DynamicObject> storeList)
{
AsyncMessage msg = new AsyncMessage
{
Context = ctx,
ServiceType = typeof(StartBackJobService).AssemblyQualifiedName,
DataInfo = pi
};
this.AddMqStoreList(ctx, pi.CreatedTime, storeList, startActivityInstId, msg);
}
public void AddMqStoreList(Context ctx, DateTime executedTime, List<DynamicObject> storeList, string actInstId, AsyncMessage msg)
{
storeList.Add(new MapStateMqStore
{
MsgData = SerializatonUtil.Serialize(msg),
SendUserId = ctx.UserId,
CREATEDATE = executedTime,
ActInstId = actInstId,
Status = MapStateMqStatus.Untreated
}.DataEntity);
}
public Exception SendAsyncMessage<T>(Context ctx, MessageSendMode mode, object dataInfo, Action method)
{
AsyncMessage msg = new AsyncMessage
{
Context = ctx,
DataInfo = dataInfo,
ServiceType = typeof(T).AssemblyQualifiedName
};
return this.SendAsyncMessage(msg, mode, method);
}
public Exception SendAsyncMessage(AsyncMessage msg, MessageSendMode mode, Action method)
{
Exception result = null;
if (method != null)
{
method();
}
try
{
MessageQueueAsyncService messageQueueAsyncService = new MessageQueueAsyncService();
messageQueueAsyncService.Send(msg);
}
catch (Exception ex)
{
result = ex;
Logger.Error("WF", ex.Message, ex);
}
return result;
}
public void SendSyncMessage<T>(Context ctx, object dataInfo, Action method, bool startNewThread = true)
{
if (startNewThread)
{
MainWorker.QuequeTask(ctx, delegate ()
{
T t2 = Activator.CreateInstance<T>();
if (method != null)
{
method();
}
((IAsyncService)((object)t2)).Excute(ctx, dataInfo);
}, delegate (AsynResult result)
{
if (!result.Success && result.Exception != null)
{
}
});
return;
}
try
{
T t = Activator.CreateInstance<T>();
using (KDTransactionScope kdtransactionScope = new KDTransactionScope(TransactionScopeOption.Required))
{
if (method != null)
{
method();
}
((IAsyncService)((object)t)).Excute(ctx, dataInfo);
kdtransactionScope.Complete();
}
}
catch (Exception)
{
throw;
}
}
public MessageSendMode GetMessageSendMode(Context ctx)
{
bool sysParaWriteProcessLogger = this.GetSysParaWriteProcessLogger(ctx);
// LogRepository.WriteBOSWorkflowLog(ctx, "GetMessageSendMode", 10, "begin GetMessageSendMode", sysParaWriteProcessLogger);
SystemParameterService systemParameterService = new SystemParameterService();
object paramter = systemParameterService.GetParamter(ctx, 0L, 0L, "WF_SystemParameter", "FlowProcMode", 0L);
// LogRepository.WriteBOSWorkflowLog(ctx, "GetMessageSendMode", 20, string.Format("FlowProcMode = {0}", paramter), sysParaWriteProcessLogger);
MessageSendMode messageSendMode = (MessageSendMode)Convert.ToInt32(paramter);
if (messageSendMode != MessageSendMode.MSMQ)
{
return messageSendMode;
}
else
{
return MessageSendMode.Async;
}
}
public bool GetSysParaWriteProcessLogger(Context ctx)
{
return ObjectUtils.Object2Bool(ServiceHelper.GetService<ISystemParameterService>().GetParamter(ctx, 0L, 0L, "WF_SystemParameter", "FWriteLog", 0L), false);
}
public class StartBackJobService : IAsyncService
{
public void Excute(Context ctx, object arg)
{
this.StartWorkflowExecute(ctx, (ProcessInstance)arg);
}
public string GetDataInfo(object arg)
{
ProcessInstance processInstance = (ProcessInstance)arg;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendFormat(ResManager.LoadKDString("流程实例Id:{0}, 流程编码:{1}, 发起人Id:{2}", "002525030023196", SubSystemType.BOS, new object[0]), processInstance.MapInstanceId, processInstance.Number, processInstance.OriginatorId.ToString());
stringBuilder.Append(" \r\n");
foreach (VariableInstance variableInstance in processInstance.VariableInstances)
{
stringBuilder.AppendFormat(ResManager.LoadKDString("变量名:{0}, 值:{1}", "002525030023199", SubSystemType.BOS, new object[0]), variableInstance.Name, variableInstance.Value);
stringBuilder.Append(" \r\n");
}
return stringBuilder.ToString();
}
public void StartWorkflowExecute(Context ctx, ProcessInstance procInst)
{
WorkflowModelService workflowModelService = new WorkflowModelService();
CacheProcess cacheProcessByVersionId = workflowModelService.GetCacheProcessByVersionId(ctx, procInst.VersionId);
BOSFlowRepository repository = new BOSFlowRepository(ctx);
object obj = "";
procInst.TryGetMember("FormId", out obj);
object obj2 = "";
procInst.TryGetMember("KeyValue", out obj2);
using (KDTransactionScope kdtransactionScope = new KDTransactionScope(TransactionScopeOption.Required))
{
WorkflowEngine workflowEngine = new WorkflowEngine(cacheProcessByVersionId.Process, ctx, repository);
IDictionary<string, object> variables = null;
workflowEngine.Start(procInst, variables);
kdtransactionScope.Complete();
}
}
}
}
}
5.说明
1.审批流审批项处表单操作灰色锁定,没办法绑定反审核操作,所以使用的是工作流;2.代码只是单张单据测试,实际情况适当进行更改;3.很多方法也不知道什么意思就是无脑调用;4.在BeginOperationTransaction事件中生成单据的工作流,如果生成成功,则 e.CancelOperation = true;取消本次操作,由生成的工作流去完成反审核操作,所以代码里判断是是否生成工作流;6.如何取消还不知道。
推荐阅读