【X3上的大型企业综合应用系统开发实战案例分享系列】一、X3平台外的流程控制纯SQL语句实现:流程启动、向下流转、回退、中止,流程结束。
以下是完整源代码:
{ TFlowControlService }
TFlowControlService = class
public
{ 启动流程 }
static procedure StartupFlow(AProcURL, AEntryUnitID, AFlowID, AFlowSubject,
ASenderURL, AReceiverURL, ATaskSubject: string); overload;
static procedure StartupFlow(AProcURL, AEntryUnitID, AFlowID, AFlowSubject,
ATaskSubject, ASenderURL: string; AReceiverURLs: TStrings;
AExecuteMode: TTaskExecuteMode; APreemptMode: TTaskPreemptMode); overload;
{ 流程向下流转 }
static procedure FlowOut(ACurrentTaskGUID, ANextProcUnitID, ANextProcUnitName,
ATaskSubject, ATaskFuncURL: string; AReceiverURLs: TStrings;
AExecuteMode: TTaskExecuteMode; APreemptMode: TTaskPreemptMode); overload;
static procedure FlowOut(ACurrentTaskGUID, ANextProcUnitID, ANextProcUnitName,
ATaskSubject, ATaskFuncURL, AReceiverURL: string); overload;
{ 流程回退 }
static procedure FlowBack(ACurrentTaskGUID, APrevProcUnitID, APrevProcUnitName,
ATaskSubject, ATaskFuncURL: string; AReceiverURLs: TStrings;
AExecuteMode: TTaskExecuteMode; APreemptMode: TTaskPreemptMode); overload;
static procedure FlowBack(ACurrentTaskGUID, APrevProcUnitID, APrevProcUnitName,
ATaskSubject, ATaskFuncURL, AReceiverURL: string); overload;
{ 流程中止 }
static procedure FlowAbort(ACurrentTaskGUID: string);
{ 流程结束 }
static procedure FlowFinish(ACurrentTaskGUID: string);
end;
{ TFlowControlService }
static procedure TFlowControlService.StartupFlow(AProcURL, AEntryUnitID, AFlowID, AFlowSubject,
ASenderURL, AReceiverURL, ATaskSubject: string);
var
lReceiverURLs: TStrings;
begin
lReceiverURLs := TStringList.Create;
try
lReceiverURLs.Add(AReceiverURL);
TFlowControlService.StartupFlow(AProcURL, AEntryUnitID, AFlowID, AFlowSubject,
ATaskSubject, ASenderURL, lReceiverURLs, TTaskExecuteMode.emExclusive,
TTaskPreemptMode.omFirstProcess);
finally
lReceiverURLs.Free;
end;
end;
static procedure TFlowControlService.StartupFlow(AProcURL, AEntryUnitID, AFlowID,
AFlowSubject, ATaskSubject, ASenderURL: string; AReceiverURLs: TStrings;
AExecuteMode: TTaskExecuteMode; APreemptMode: TTaskPreemptMode);
const
c_Insert_TFlow = 'insert into TFLOW(FGUID, FID, FSUBJECT, FCREATETIME, FSTATE, FPROCURL, FFLOWFIELDURL) values(:GUID, :FlowID, :Subject, :CreateTime, :State, rocURL, :FlowFieldURL)';
c_Insert_TFlowID = 'insert into TFLOWID values(:FlowGUID, :FlowID)';
c_Insert_TTask = 'insert into TTASK(FGUID, FFLOWGUID, FPARENTGUID, FPREVGUID, FNEXTGUID, FGROUPGUID, FPROCURL, FPROCUNITID, FSUBJECT, FKIND, FSOGN, FSOGNNAME, FSDEPT, FSDEPTNAME, FSPOSITION, FSPOSITIONNAME, FSPERSON, FSPERSONNAME, FSORGURL, FPRIORITY, FCREATETIME, FSTARTTIME, FDESCRIPTION, FSTATE, FFUNCURL, FTYPENAME, FEXECUTEMODE, FPREEMPTMODE, FLASTCHANGETIME, FNEEDPROCESS, FRPERSONNAMES) ' +
'values(:GUID, :FlowGUID, arentGUID, REVGUID, :NextGUID, :GroupGUID, rocURL, rocUnitID, :Subject, :Kind, :SOGN, :SOGNNAME, :SDept, :SDeptName, :SPosition, :SPositionName, :SPerson, :SPersonName, :SOrgURL, riority, :CreateTime, :StartTime, escription, :State, :FuncURL, :TypeName, :ExecuteMode, reemptMode, astChangeTime, :NeedProcess, :RPersonNames)';
c_Insert_TTaskMessage = 'insert into TTASKMESSAGE(FGUID, FPARENTGUID, FTASKGUID, FROGN, FROGNNAME, FRDEPT, FRDEPTNAME, FRPOSITION, FRPOSITIONNAME, FRPERSON, FRPERSONNAME, FRORGURL, FRECEIVETIME, FSTATE) ' +
'values(:GUID, ARENTGUID, :TASKGUID, :ROGN, :ROGNNAME, :RDEPT, :RDEPTNAME, :RPOSITION, :RPOSITIONNAME, :RPERSON, :RPERSONNAME, :RORGURL, :RECEIVETIME, :STATE)';
c_Insert_TTaskBizData = 'insert into TTASKBIZDATA(FGUID, FTASKGUID, FKEY0, FKEYVALUE0) ' +
'values(:GUID, :TaskGUID, :Key0, :KeyValue0)';
var
lProcURL: TBizURL;
lProc: TProc;
lEntryUnit: TProcUnit;
lFlowFieldURL, lTaskFuncURL: string;
lFlowGUID, lTaskGUID, lTaskMessageGUID, lTaskBizDataGUID: string;
lQuery: TQuery;
lTransactionHandle: TTransactionHandle;
I: integer;
lReceiverURL: string;
lSenderOrgan, lSenderOrganName, lSenderDept, lSenderDeptName, lSenderPosition,
lSenderPositionName, lSender, lSenderName: string;
lReceiverOrgan, lReceiverOrganName, lReceiverDept, lReceiverDeptName,
lReceiverPosition, lReceiverPositionName, lReceiver, lReceiverName: string;
lReceiverPersonNames: string;
begin
{ 一、从流程获取所需信息、变量赋值 }
lProcURL := TBizURL.Create;
try
lProcURL.URL := AProcURL;
lProc := BizSys.BizSystem.GetBizObject(lProcURL) as TProc;
lFlowFieldURL := lProc.FlowField.URL;
lEntryUnit := lProc.GetUnit(AEntryUnitID);
lTaskFuncURL := (lEntryUnit as TProcActivity).FuncURL.URL;
finally
lProcURL.Free;
end;
TOrgUtils.GetOrganDeptPositionPersonIDName(ASenderURL, lSenderOrgan,
lSenderOrganName, lSenderDept, lSenderDeptName, lSenderPosition,
lSenderPositionName, lSender, lSenderName);
lReceiverPersonNames := TOrgUtils.GetOrgURLsDisplayName(AReceiverURLs, -1);
lFlowGUID := jsCommon.CreateGUIDStr;
lTaskGUID := jsCommon.CreateGUIDStr;
{ 二、生成流程任务数据到数据库相关表 }
lQuery := TQuery.Create(nil);
try
lQuery.ConnectionString := BizObjConsts.cSysDatabaseConnectionString;
lTransactionHandle := lQuery.Connection.Transaction.Start(True); //启动事务
try
{ 1、TFlow }
lQuery.CommandText := c_Insert_TFlow;
lQuery.Params.ParamByName('GUID').AsString := lFlowGUID;
lQuery.Params.ParamByName('FlowID').AsBlob := AFlowID;
lQuery.Params.ParamByName('Subject').AsString := AFlowSubject;
lQuery.Params.ParamByName('CreateTime').AsDateTime := SysSrv.SysService.Time;
lQuery.Params.ParamByName('State').AsString := Flow.FlowStateToStr(TFlowState.fsProcessing);
lQuery.Params.ParamByName('ProcURL').AsString := AProcURL;
lQuery.Params.ParamByName('FlowFieldURL').AsString := lFlowFieldURL;
lQuery.Execute;
{ 2、TFlowID }
lQuery.CommandText := c_Insert_TFlowID;
lQuery.Params.ParamByName('FlowGUID').AsString := lFlowGUID;
lQuery.Params.ParamByName('FlowID').AsString := AFlowID;
lQuery.Execute;
{ 3、TTask }
lQuery.CommandText := c_Insert_TTask;
lQuery.Params.ParamByName('GUID').AsString := lTaskGUID;
lQuery.Params.ParamByName('FlowGUID').AsString := lFlowGUID;
lQuery.Params.ParamByName('ParentGUID').AsString := '-1';
lQuery.Params.ParamByName('PREVGUID').AsString := '-1';
lQuery.Params.ParamByName('NextGUID').AsString := '-1';
lQuery.Params.ParamByName('GroupGUID').AsString := '-1';
lQuery.Params.ParamByName('ProcURL').AsString := AProcURL;
lQuery.Params.ParamByName('ProcUnitID').AsString := AEntryUnitID;
lQuery.Params.ParamByName('Subject').AsString := ATaskSubject;
lQuery.Params.ParamByName('Kind').AsString := Flow.FlowTaskKindToStr(TFlowTaskKind.ftkActivity);// 'ftkActivity';
lQuery.Params.ParamByName('SOGN').AsString := lSenderOrgan;
lQuery.Params.ParamByName('SOGNNAME').AsString := lSenderOrganName;
lQuery.Params.ParamByName('SDept').AsString := lSenderDept;
lQuery.Params.ParamByName('SDeptName').AsString := lSenderDeptName;
lQuery.Params.ParamByName('SPosition').AsString := lSenderPosition;
lQuery.Params.ParamByName('SPositionName').AsString := lSenderPositionName;
lQuery.Params.ParamByName('SPerson').AsString := lSender;
lQuery.Params.ParamByName('SPersonName').AsString := lSenderName;
lQuery.Params.ParamByName('SOrgURL').AsString := FileSys.FileUtils.RemoveFilePrefix(ASenderURL);
lQuery.Params.ParamByName('Priority').AsString := 'tpNormal';
lQuery.Params.ParamByName('CreateTime').AsDateTime := SysSrv.SysService.Time;
lQuery.Params.ParamByName('StartTime').AsDateTime := SysSrv.SysService.Time;
lQuery.Params.ParamByName('Description').AsString := '';
lQuery.Params.ParamByName('State').AsString := Task.TaskStateToStr(TTaskState.tsStarted);
lQuery.Params.ParamByName('FuncURL').AsString := lTaskFuncURL;
lQuery.Params.ParamByName('TypeName').AsString := lEntryUnit.DisplayName;
lQuery.Params.ParamByName('ExecuteMode').AsString := TFlowTaskUtils.TaskExecuteModeToStr(AExecuteMode);
lQuery.Params.ParamByName('PreemptMode').AsString := TFlowTaskUtils.TaskPreemptModeToStr(APreemptMode);
lQuery.Params.ParamByName('LastChangeTime').AsDateTime := SysSrv.SysService.Time;
lQuery.Params.ParamByName('NeedProcess').AsString := 'Y';
lQuery.Params.ParamByName('RPersonNames').AsString := lReceiverPersonNames;
lQuery.Execute;
{ 4、TTaskMessage }
for I := 0 to AReceiverURLs.Count - 1 do
begin
lReceiverURL := AReceiverURLs[I];
TOrgUtils.GetOrganDeptPositionPersonIDName(lReceiverURL, lReceiverOrgan,
lReceiverOrganName, lReceiverDept, lReceiverDeptName, lReceiverPosition,
lReceiverPositionName, lReceiver, lReceiverName);
lTaskMessageGUID := jsCommon.CreateGUIDStr;
lQuery.CommandText := c_Insert_TTaskMessage;
lQuery.Params.ParamByName('GUID').AsString := lTaskMessageGUID;
lQuery.Params.ParamByName('PARENTGUID').AsString := '-1';
lQuery.Params.ParamByName('TASKGUID').AsString := lTaskGUID;
lQuery.Params.ParamByName('ROGN').AsString := lReceiverOrgan;
lQuery.Params.ParamByName('ROGNNAME').AsString := lReceiverOrganName;
lQuery.Params.ParamByName('RDEPT').AsString := lReceiverDept;
lQuery.Params.ParamByName('RDEPTNAME').AsString := lReceiverDeptName;
lQuery.Params.ParamByName('RPOSITION').AsString := lReceiverPosition;
lQuery.Params.ParamByName('RPOSITIONNAME').AsString := lReceiverPositionName;
lQuery.Params.ParamByName('RPERSON').AsString := lReceiver;
lQuery.Params.ParamByName('RPERSONNAME').AsString := lReceiverName;
lQuery.Params.ParamByName('RORGURL').AsString := FileSys.FileUtils.RemoveFilePrefix(lReceiverURL);
lQuery.Params.ParamByName('RECEIVETIME').AsDateTime := SysSrv.SysService.Time;
lQuery.Params.ParamByName('STATE').AsString := Task.TaskMessageStateToStr(TTaskMessageState.tmsReceived);
lQuery.Execute;
end;
{ 5、TTaskBizData }
lTaskBizDataGUID := jsCommon.CreateGUIDStr;
lQuery.CommandText := c_Insert_TTaskBizData;
lQuery.Params.ParamByName('GUID').AsString := lTaskBizDataGUID;
lQuery.Params.ParamByName('TaskGUID').AsString := lTaskGUID;
lQuery.Params.ParamByName('Key0').AsString := lFlowFieldURL;
lQuery.Params.ParamByName('KeyValue0').AsString := AFlowID;
lQuery.Execute;
lQuery.Connection.Transaction.Commit(lTransactionHandle); //提交事务
except
lQuery.Connection.Transaction.Rollback(lTransactionHandle); //回滚事务
raise;
end;
finally
lQuery.Free;
end;
end;
static procedure TFlowControlService.FlowOut(ACurrentTaskGUID, ANextProcUnitID,
ANextProcUnitName, ATaskSubject, ATaskFuncURL: string; AReceiverURLs: TStrings;
AExecuteMode: TTaskExecuteMode; APreemptMode: TTaskPreemptMode);
const
c_Select_TTask = 'select * from TTASK where FGUID = :TaskGUID';
c_Select_TTaskMessage = 'select * from TTASKMESSAGE where FTASKGUID = :TaskGUID';
c_Select_TFlow = 'select * from TFLOW where FGUID = :FlowGUID';
c_Select_TFlowID = 'select * from TFLOWID where FFLOWGUID = :FlowGUID';
c_Update_TTask = 'update TTASK set FNEXTGUID = null, FSTATE = :TaskState, FFINISHTIME = :FinishTime, FLASTCHANGETIME = astChangeTime where FGUID = :TaskGUID';
c_Update_TTaskMessage = 'update TTASKMESSAGE set FSTATE = :TaskMeesageState, FFINISHTIME = :FinishTime where FTASKGUID = :TaskGUID';
c_Insert_TTask = 'insert into TTASK(FGUID, FFLOWGUID, FPARENTGUID, FPREVGUID, FNEXTGUID, FGROUPGUID, FPROCURL, FPROCUNITID, FSUBJECT, FKIND, FSOGN, FSOGNNAME, FSDEPT, FSDEPTNAME, FSPOSITION, FSPOSITIONNAME, FSPERSON, FSPERSONNAME, FSORGURL, FPRIORITY, FCREATETIME, FSTARTTIME, FDESCRIPTION, FSTATE, FFUNCURL, FTYPENAME, FEXECUTEMODE, FPREEMPTMODE, FLASTCHANGETIME, FNEEDPROCESS, FRPERSONNAMES) ' +
'values(:GUID, :FlowGUID, arentGUID, REVGUID, :NextGUID, :GroupGUID, :ProcURL, :ProcUnitID, :Subject, :Kind, :SOGN, :SOGNNAME, :SDept, :SDeptName, :SPosition, :SPositionName, :SPerson, :SPersonName, :SOrgURL, :Priority, :CreateTime, :StartTime, escription, :State, :FuncURL, :TypeName, :ExecuteMode, :PreemptMode, astChangeTime, :NeedProcess, :RPersonNames)';
c_Insert_TTaskMessage = 'insert into TTASKMESSAGE(FGUID, FPARENTGUID, FTASKGUID, FROGN, FROGNNAME, FRDEPT, FRDEPTNAME, FRPOSITION, FRPOSITIONNAME, FRPERSON, FRPERSONNAME, FRORGURL, FRECEIVETIME, FSTATE) ' +
'values(:GUID, :PARENTGUID, :TASKGUID, :ROGN, :ROGNNAME, :RDEPT, :RDEPTNAME, :RPOSITION, :RPOSITIONNAME, :RPERSON, :RPERSONNAME, :RORGURL, :RECEIVETIME, :STATE)';
c_Insert_TTaskBizData = 'insert into TTASKBIZDATA(FGUID, FTASKGUID, FKEY0, FKEYVALUE0) ' +
'values(:GUID, :TaskGUID, :Key0, :KeyValue0)';
var
lQuery: TQuery;
lTransactionHandle: TTransactionHandle;
lProcURL, lFlowFieldURL, lFlowID: string;
lFlowGUID, lTaskGUID, lTaskMessageGUID, lTaskBizDataGUID: string;
lSenderURL, lReceiverURL: string;
lSenderOrgan, lSenderOrganName, lSenderDept, lSenderDeptName, lSenderPosition,
lSenderPositionName, lSender, lSenderName: string;
lReceiverOrgan, lReceiverOrganName, lReceiverDept, lReceiverDeptName,
lReceiverPosition, lReceiverPositionName, lReceiver, lReceiverName: string;
lReceiverPersonNames: string;
I: integer;
begin
lQuery := TQuery.Create(nil);
try
lQuery.ConnectionString := BizObjConsts.cSysDatabaseConnectionString;
{ 一、根据当前任务获取所需任务信息、变量赋值 }
{ 1、任务表 }
lQuery.CommandText := c_Select_TTask;
lQuery.Params.ParamByName('TaskGUID').AsString := ACurrentTaskGUID;
lQuery.Open;
Assert(lQuery.RecordCount > 0, '找不到指定GUID的任务。');
lFlowGUID := lQuery.FieldByName('FFlowGUID').AsString;
lQuery.Close;
{ 2、任务消息表 }
lQuery.CommandText := c_Select_TTaskMessage;
lQuery.Params.ParamByName('TaskGUID').AsString := ACurrentTaskGUID;
lQuery.Open;
Assert(lQuery.RecordCount > 0, '找不到指定GUID的任务消息。');
lSenderURL := 'Org:' + lQuery.FieldByName('FRORGURL').AsString;
lQuery.Close;
{ 3、流程表 }
lQuery.CommandText := c_Select_TFlow;
lQuery.Params.ParamByName('FlowGUID').AsString := lFlowGUID;
lQuery.Open;
Assert(lQuery.RecordCount > 0, '找不到指定GUID的流程。');
lProcURL := lQuery.FieldByName('FPROCURL').AsString;
lFlowFieldURL := lQuery.FieldByName('FFLOWFIELDURL').AsString;
lQuery.Close;
{ 4、流程ID表 }
lQuery.CommandText := c_Select_TFlowID;
lQuery.Params.ParamByName('FlowGUID').AsString := lFlowGUID;
lQuery.Open;
Assert(lQuery.RecordCount > 0, '找不到指定GUID的流程ID记录。');
lFlowID := lQuery.FieldByName('FID').AsString;
lQuery.Close;
lTransactionHandle := lQuery.Connection.Transaction.Start(True); //启动事务
try
{ 二、更新当前流程任务 }
{ 1、Update TTask }
lQuery.CommandText := c_Update_TTask;
lQuery.Params.ParamByName('TaskState').AsString := Task.TaskStateToStr(TTaskState.tsFinished);
lQuery.Params.ParamByName('FinishTime').AsDateTime := Business.Data.SysSrv.SysService.Time;
lQuery.Params.ParamByName('LastChangeTime').AsDateTime := Business.Data.SysSrv.SysService.Time;
lQuery.Params.ParamByName('TaskGUID').AsString := ACurrentTaskGUID;
lQuery.Execute;
{ 2、Update TTaskMessage }
lQuery.CommandText := c_Update_TTaskMessage;
lQuery.Params.ParamByName('TaskMeesageState').AsString := Task.TaskMessageStateToStr(TTaskMessageState.tmsFinished);
lQuery.Params.ParamByName('FinishTime').AsDateTime := Business.Data.SysSrv.SysService.Time;
lQuery.Params.ParamByName('TaskGUID').AsString := ACurrentTaskGUID;
lQuery.Execute;
{ 三、生成下一步流程任务数据到数据库相关表 }
{ 1、Add To TTask }
TOrgUtils.GetOrganDeptPositionPersonIDName(lSenderURL, lSenderOrgan,
lSenderOrganName, lSenderDept, lSenderDeptName, lSenderPosition,
lSenderPositionName, lSender, lSenderName);
lReceiverPersonNames := TOrgUtils.GetOrgURLsDisplayName(AReceiverURLs, -1);
lTaskGUID := jsCommon.CreateGUIDStr;
lQuery.CommandText := c_Insert_TTask;
lQuery.Params.ParamByName('GUID').AsString := lTaskGUID;
lQuery.Params.ParamByName('FlowGUID').AsString := lFlowGUID;
lQuery.Params.ParamByName('ParentGUID').AsString := '-1';
lQuery.Params.ParamByName('PREVGUID').AsString := ACurrentTaskGUID; //新建任务的上一任务关联到当前任务
lQuery.Params.ParamByName('NextGUID').AsString := '-1';
lQuery.Params.ParamByName('GroupGUID').AsString := '-1';
lQuery.Params.ParamByName('ProcURL').AsString := SysUtils.UpperCase(lProcURL);
lQuery.Params.ParamByName('ProcUnitID').AsString := ANextProcUnitID;
lQuery.Params.ParamByName('Subject').AsString := ATaskSubject;
lQuery.Params.ParamByName('Kind').AsString := Flow.FlowTaskKindToStr(TFlowTaskKind.ftkActivity); //'ftkActivity';
lQuery.Params.ParamByName('SOGN').AsString := lSenderOrgan;
lQuery.Params.ParamByName('SOGNNAME').AsString := lSenderOrganName;
lQuery.Params.ParamByName('SDept').AsString := lSenderDept;
lQuery.Params.ParamByName('SDeptName').AsString := lSenderDeptName;
lQuery.Params.ParamByName('SPosition').AsString := lSenderPosition;
lQuery.Params.ParamByName('SPositionName').AsString := lSenderPositionName;
lQuery.Params.ParamByName('SPerson').AsString := FileSys.FileUtils.RemoveFilePrefix(lSender);
lQuery.Params.ParamByName('SPersonName').AsString := lSenderName;
lQuery.Params.ParamByName('SOrgURL').AsString := FileSys.FileUtils.RemoveFilePrefix(lSenderURL);
lQuery.Params.ParamByName('Priority').AsString := 'tpNormal';
lQuery.Params.ParamByName('CreateTime').AsDateTime := SysSrv.SysService.Time;
lQuery.Params.ParamByName('StartTime').AsDateTime := SysSrv.SysService.Time;
lQuery.Params.ParamByName('Description').AsString := '';
lQuery.Params.ParamByName('State').AsString := Task.TaskStateToStr(TTaskState.tsStarted);
lQuery.Params.ParamByName('FuncURL').AsString := ATaskFuncURL;
lQuery.Params.ParamByName('TypeName').AsString := ANextProcUnitName;
lQuery.Params.ParamByName('ExecuteMode').AsString := TFlowTaskUtils.TaskExecuteModeToStr(AExecuteMode);
lQuery.Params.ParamByName('PreemptMode').AsString := TFlowTaskUtils.TaskPreemptModeToStr(APreemptMode);
lQuery.Params.ParamByName('LastChangeTime').AsDateTime := SysSrv.SysService.Time;
lQuery.Params.ParamByName('NeedProcess').AsString := 'Y';
lQuery.Params.ParamByName('RPersonNames').AsString := lReceiverPersonNames;
lQuery.Execute;
{ 2、Add TTaskMessage }
for I := 0 to AReceiverURLs.Count - 1 do
begin
lReceiverURL := AReceiverURLs[I];
TOrgUtils.GetOrganDeptPositionPersonIDName(lReceiverURL, lReceiverOrgan,
lReceiverOrganName, lReceiverDept, lReceiverDeptName, lReceiverPosition,
lReceiverPositionName, lReceiver, lReceiverName);
lTaskMessageGUID := jsCommon.CreateGUIDStr;
lQuery.CommandText := c_Insert_TTaskMessage;
lQuery.Params.ParamByName('GUID').AsString := lTaskMessageGUID;
lQuery.Params.ParamByName('PARENTGUID').AsString := '-1';
lQuery.Params.ParamByName('TASKGUID').AsString := lTaskGUID;
lQuery.Params.ParamByName('ROGN').AsString := lReceiverOrgan;
lQuery.Params.ParamByName('ROGNNAME').AsString := lReceiverOrganName;
lQuery.Params.ParamByName('RDEPT').AsString := lReceiverDept;
lQuery.Params.ParamByName('RDEPTNAME').AsString := lReceiverDeptName;
lQuery.Params.ParamByName('RPOSITION').AsString := lReceiverPosition;
lQuery.Params.ParamByName('RPOSITIONNAME').AsString := lReceiverPositionName;
lQuery.Params.ParamByName('RPERSON').AsString := lReceiver;
lQuery.Params.ParamByName('RPERSONNAME').AsString := lReceiverName;
lQuery.Params.ParamByName('RORGURL').AsString := FileSys.FileUtils.RemoveFilePrefix(lReceiverURL);
lQuery.Params.ParamByName('RECEIVETIME').AsDateTime := SysSrv.SysService.Time;
lQuery.Params.ParamByName('STATE').AsString := Task.TaskMessageStateToStr(TTaskMessageState.tmsReceived);
lQuery.Execute;
end;
{ 3、Add TTaskBizData }
lTaskBizDataGUID := jsCommon.CreateGUIDStr;
lQuery.CommandText := c_Insert_TTaskBizData;
lQuery.Params.ParamByName('GUID').AsString := lTaskBizDataGUID;
lQuery.Params.ParamByName('TaskGUID').AsString := lTaskGUID;
lQuery.Params.ParamByName('Key0').AsString := lFlowFieldURL;
lQuery.Params.ParamByName('KeyValue0').AsString := lFlowID;
lQuery.Execute;
lQuery.Connection.Transaction.Commit(lTransactionHandle); //提交事务
except
lQuery.Connection.Transaction.Rollback(lTransactionHandle); //回滚事务
raise;
end;
finally
lQuery.Free;
end;
end;
static procedure TFlowControlService.FlowOut(ACurrentTaskGUID, ANextProcUnitID, ANextProcUnitName,
ATaskSubject, ATaskFuncURL, AReceiverURL: string);
var
lReceiverURLs: TStrings;
begin
lReceiverURLs := TStringList.Create;
try
lReceiverURLs.Add(AReceiverURL);
TFlowControlService.FlowOut(ACurrentTaskGUID, ANextProcUnitID, ANextProcUnitName,
ATaskSubject, ATaskFuncURL, lReceiverURLs, TTaskExecuteMode.emExclusive,
TTaskPreemptMode.omFirstProcess);
finally
lReceiverURLs.Free;
end;
end;
static procedure TFlowControlService.FlowBack(ACurrentTaskGUID, APrevProcUnitID, APrevProcUnitName,
ATaskSubject, ATaskFuncURL: string; AReceiverURLs: TStrings;
AExecuteMode: TTaskExecuteMode; APreemptMode: TTaskPreemptMode);
const
c_Select_TTask = 'select * from TTASK where FGUID = :TaskGUID';
c_Select_TTaskMessage = 'select * from TTASKMESSAGE where FTASKGUID = :TaskGUID';
c_Select_TFlow = 'select * from TFLOW where FGUID = :FlowGUID';
c_Select_TFlowID = 'select * from TFLOWID where FFLOWGUID = :FlowGUID';
c_Update_TTask = 'update TTASK set FNEXTGUID = null, FSTATE = :TaskState, FFINISHTIME = :FinishTime, FLASTCHANGETIME = astChangeTime where FGUID = :TaskGUID';
c_Update_TTaskMessage = 'update TTASKMESSAGE set FSTATE = :TaskMeesageState, FFINISHTIME = :FinishTime where FTASKGUID = :TaskGUID';
c_Insert_TTask = 'insert into TTASK(FGUID, FFLOWGUID, FPARENTGUID, FPREVGUID, FNEXTGUID, FGROUPGUID, FPROCURL, FPROCUNITID, FSUBJECT, FKIND, FSOGN, FSOGNNAME, FSDEPT, FSDEPTNAME, FSPOSITION, FSPOSITIONNAME, FSPERSON, FSPERSONNAME, FSORGURL, FPRIORITY, FCREATETIME, FSTARTTIME, FDESCRIPTION, FSTATE, FFUNCURL, FTYPENAME, FEXECUTEMODE, FPREEMPTMODE, FLASTCHANGETIME, FNEEDPROCESS, FRPERSONNAMES) ' +
'values(:GUID, :FlowGUID, :ParentGUID, :PREVGUID, :NextGUID, :GroupGUID, :ProcURL, :ProcUnitID, :Subject, :Kind, :SOGN, :SOGNNAME, :SDept, :SDeptName, :SPosition, :SPositionName, :SPerson, :SPersonName, :SOrgURL, :Priority, :CreateTime, :StartTime, escription, :State, :FuncURL, :TypeName, :ExecuteMode, :PreemptMode, astChangeTime, :NeedProcess, :RPersonNames)';
c_Insert_TTaskMessage = 'insert into TTASKMESSAGE(FGUID, FPARENTGUID, FTASKGUID, FROGN, FROGNNAME, FRDEPT, FRDEPTNAME, FRPOSITION, FRPOSITIONNAME, FRPERSON, FRPERSONNAME, FRORGURL, FRECEIVETIME, FSTATE) ' +
'values(:GUID, :PARENTGUID, :TASKGUID, :ROGN, :ROGNNAME, :RDEPT, :RDEPTNAME, :RPOSITION, :RPOSITIONNAME, :RPERSON, :RPERSONNAME, :RORGURL, :RECEIVETIME, :STATE)';
c_Insert_TTaskBizData = 'insert into TTASKBIZDATA(FGUID, FTASKGUID, FKEY0, FKEYVALUE0) ' +
'values(:GUID, :TaskGUID, :Key0, :KeyValue0)';
var
lQuery: TQuery;
lTransactionHandle: TTransactionHandle;
lProcURL, lFlowFieldURL, lFlowID: string;
lFlowGUID, lTaskGUID, lTaskMessageGUID, lTaskBizDataGUID: string;
lSenderURL, lReceiverURL: string;
lSenderOrgan, lSenderOrganName, lSenderDept, lSenderDeptName, lSenderPosition,
lSenderPositionName, lSender, lSenderName: string;
lReceiverOrgan, lReceiverOrganName, lReceiverDept, lReceiverDeptName,
lReceiverPosition, lReceiverPositionName, lReceiver, lReceiverName: string;
lReceiverPersonNames: string;
I: integer;
begin
lQuery := TQuery.Create(nil);
try
lQuery.ConnectionString := BizObjConsts.cSysDatabaseConnectionString;
{ 一、根据当前任务获取所需任务信息、变量赋值 }
{ 1、任务表 }
lQuery.CommandText := c_Select_TTask;
lQuery.Params.ParamByName('TaskGUID').AsString := ACurrentTaskGUID;
lQuery.Open;
Assert(lQuery.RecordCount > 0, '找不到指定GUID的任务。');
lFlowGUID := lQuery.FieldByName('FFlowGUID').AsString;
lQuery.Close;
{ 2、任务消息表 }
lQuery.CommandText := c_Select_TTaskMessage;
lQuery.Params.ParamByName('TaskGUID').AsString := ACurrentTaskGUID;
lQuery.Open;
Assert(lQuery.RecordCount > 0, '找不到指定GUID的任务消息。');
lSenderURL := 'Org:' + lQuery.FieldByName('FRORGURL').AsString;
lQuery.Close;
{ 3、流程表 }
lQuery.CommandText := c_Select_TFlow;
lQuery.Params.ParamByName('FlowGUID').AsString := lFlowGUID;
lQuery.Open;
Assert(lQuery.RecordCount > 0, '找不到指定GUID的流程。');
lProcURL := lQuery.FieldByName('FPROCURL').AsString;
lFlowFieldURL := lQuery.FieldByName('FFLOWFIELDURL').AsString;
lQuery.Close;
{ 4、流程ID表 }
lQuery.CommandText := c_Select_TFlowID;
lQuery.Params.ParamByName('FlowGUID').AsString := lFlowGUID;
lQuery.Open;
Assert(lQuery.RecordCount > 0, '找不到指定GUID的流程ID记录。');
lFlowID := lQuery.FieldByName('FID').AsString;
lQuery.Close;
lTransactionHandle := lQuery.Connection.Transaction.Start(True); //启动事务
try
{ 二、更新当前流程任务 }
{ 1、Update TTask }
lQuery.CommandText := c_Update_TTask;
lQuery.Params.ParamByName('TaskState').AsString := Task.TaskStateToStr(TTaskState.tsReturned); //已回退
lQuery.Params.ParamByName('FinishTime').AsDateTime := Business.Data.SysSrv.SysService.Time;
lQuery.Params.ParamByName('LastChangeTime').AsDateTime := Business.Data.SysSrv.SysService.Time;
lQuery.Params.ParamByName('TaskGUID').AsString := ACurrentTaskGUID;
lQuery.Execute;
{ 2、Update TTaskMessage }
lQuery.CommandText := c_Update_TTaskMessage;
lQuery.Params.ParamByName('TaskMeesageState').AsString := Task.TaskMessageStateToStr(TTaskMessageState.tmsReturned); //已回退
lQuery.Params.ParamByName('FinishTime').AsDateTime := Business.Data.SysSrv.SysService.Time;
lQuery.Params.ParamByName('TaskGUID').AsString := ACurrentTaskGUID;
lQuery.Execute;
{ 三、生成下一步流程任务数据到数据库相关表 }
{ 1、Add To TTask }
TOrgUtils.GetOrganDeptPositionPersonIDName(lSenderURL, lSenderOrgan,
lSenderOrganName, lSenderDept, lSenderDeptName, lSenderPosition,
lSenderPositionName, lSender, lSenderName);
lReceiverPersonNames := TOrgUtils.GetOrgURLsDisplayName(AReceiverURLs, -1);
lTaskGUID := jsCommon.CreateGUIDStr;
lQuery.CommandText := c_Insert_TTask;
lQuery.Params.ParamByName('GUID').AsString := lTaskGUID;
lQuery.Params.ParamByName('FlowGUID').AsString := lFlowGUID;
lQuery.Params.ParamByName('ParentGUID').AsString := '-1';
lQuery.Params.ParamByName('PREVGUID').AsString := ACurrentTaskGUID; //新建任务的上一任务关联到当前任务
lQuery.Params.ParamByName('NextGUID').AsString := '-1';
lQuery.Params.ParamByName('GroupGUID').AsString := '-1';
lQuery.Params.ParamByName('ProcURL').AsString := SysUtils.UpperCase(lProcURL);
lQuery.Params.ParamByName('ProcUnitID').AsString := APrevProcUnitID;
lQuery.Params.ParamByName('Subject').AsString := ATaskSubject;
lQuery.Params.ParamByName('Kind').AsString := Flow.FlowTaskKindToStr(TFlowTaskKind.ftkReturn); //'ftkReturn';
lQuery.Params.ParamByName('SOGN').AsString := lSenderOrgan;
lQuery.Params.ParamByName('SOGNNAME').AsString := lSenderOrganName;
lQuery.Params.ParamByName('SDept').AsString := lSenderDept;
lQuery.Params.ParamByName('SDeptName').AsString := lSenderDeptName;
lQuery.Params.ParamByName('SPosition').AsString := lSenderPosition;
lQuery.Params.ParamByName('SPositionName').AsString := lSenderPositionName;
lQuery.Params.ParamByName('SPerson').AsString := FileSys.FileUtils.RemoveFilePrefix(lSender);
lQuery.Params.ParamByName('SPersonName').AsString := lSenderName;
lQuery.Params.ParamByName('SOrgURL').AsString := FileSys.FileUtils.RemoveFilePrefix(lSenderURL);
lQuery.Params.ParamByName('Priority').AsString := 'tpNormal';
lQuery.Params.ParamByName('CreateTime').AsDateTime := SysSrv.SysService.Time;
lQuery.Params.ParamByName('StartTime').AsDateTime := SysSrv.SysService.Time;
lQuery.Params.ParamByName('Description').AsString := '';
lQuery.Params.ParamByName('State').AsString := Task.TaskStateToStr(TTaskState.tsStarted);
lQuery.Params.ParamByName('FuncURL').AsString := ATaskFuncURL;
lQuery.Params.ParamByName('TypeName').AsString := APrevProcUnitName;
lQuery.Params.ParamByName('ExecuteMode').AsString := TFlowTaskUtils.TaskExecuteModeToStr(AExecuteMode);
lQuery.Params.ParamByName('PreemptMode').AsString := TFlowTaskUtils.TaskPreemptModeToStr(APreemptMode);
lQuery.Params.ParamByName('LastChangeTime').AsDateTime := SysSrv.SysService.Time;
lQuery.Params.ParamByName('NeedProcess').AsString := 'Y';
lQuery.Params.ParamByName('RPersonNames').AsString := lReceiverPersonNames;
lQuery.Execute;
{ 2、Add TTaskMessage }
for I := 0 to AReceiverURLs.Count - 1 do
begin
lReceiverURL := AReceiverURLs[I];
TOrgUtils.GetOrganDeptPositionPersonIDName(lReceiverURL, lReceiverOrgan,
lReceiverOrganName, lReceiverDept, lReceiverDeptName, lReceiverPosition,
lReceiverPositionName, lReceiver, lReceiverName);
lTaskMessageGUID := jsCommon.CreateGUIDStr;
lQuery.CommandText := c_Insert_TTaskMessage;
lQuery.Params.ParamByName('GUID').AsString := lTaskMessageGUID;
lQuery.Params.ParamByName('PARENTGUID').AsString := '-1';
lQuery.Params.ParamByName('TASKGUID').AsString := lTaskGUID;
lQuery.Params.ParamByName('ROGN').AsString := lReceiverOrgan;
lQuery.Params.ParamByName('ROGNNAME').AsString := lReceiverOrganName;
lQuery.Params.ParamByName('RDEPT').AsString := lReceiverDept;
lQuery.Params.ParamByName('RDEPTNAME').AsString := lReceiverDeptName;
lQuery.Params.ParamByName('RPOSITION').AsString := lReceiverPosition;
lQuery.Params.ParamByName('RPOSITIONNAME').AsString := lReceiverPositionName;
lQuery.Params.ParamByName('RPERSON').AsString := lReceiver;
lQuery.Params.ParamByName('RPERSONNAME').AsString := lReceiverName;
lQuery.Params.ParamByName('RORGURL').AsString := FileSys.FileUtils.RemoveFilePrefix(lReceiverURL);
lQuery.Params.ParamByName('RECEIVETIME').AsDateTime := SysSrv.SysService.Time;
lQuery.Params.ParamByName('STATE').AsString := Task.TaskMessageStateToStr(TTaskMessageState.tmsReceived);
lQuery.Execute;
end;
{ 3、Add TTaskBizData }
lTaskBizDataGUID := jsCommon.CreateGUIDStr;
lQuery.CommandText := c_Insert_TTaskBizData;
lQuery.Params.ParamByName('GUID').AsString := lTaskBizDataGUID;
lQuery.Params.ParamByName('TaskGUID').AsString := lTaskGUID;
lQuery.Params.ParamByName('Key0').AsString := lFlowFieldURL;
lQuery.Params.ParamByName('KeyValue0').AsString := lFlowID;
lQuery.Execute;
lQuery.Connection.Transaction.Commit(lTransactionHandle); //提交事务
except
lQuery.Connection.Transaction.Rollback(lTransactionHandle); //回滚事务
raise;
end;
finally
lQuery.Free;
end;
end;
static procedure TFlowControlService.FlowBack(ACurrentTaskGUID, APrevProcUnitID, APrevProcUnitName,
ATaskSubject, ATaskFuncURL, AReceiverURL: string);
var
lReceiverURLs: TStrings;
begin
lReceiverURLs := TStringList.Create;
try
lReceiverURLs.Add(AReceiverURL);
TFlowControlService.FlowBack(ACurrentTaskGUID, APrevProcUnitID, APrevProcUnitName,
ATaskSubject, ATaskFuncURL, lReceiverURLs, TTaskExecuteMode.emExclusive,
TTaskPreemptMode.omFirstProcess);
finally
lReceiverURLs.Free;
end;
end;
static procedure TFlowControlService.FlowAbort(ACurrentTaskGUID: string);
const
c_Select_FlowGUID = 'select FFLOWGUID from TTASK where FGUID = :TaskGUID';
c_Update_TTask = 'update TTASK set FNEXTGUID = ''-1'', FSTATE = :TaskState, FLASTCHANGETIME = astChangeTime where FGUID = :TaskGUID';
c_Update_TTaskMessage = 'update TTASKMESSAGE set FSTATE = :TaskMeesageState where FTASKGUID = :TaskGUID';
c_Update_TFlow = 'update TFLOW set FSTATE = :FlowState where FGUID = :FlowGUID';
var
lQuery: TQuery;
lFlowGUID: string;
lTransactionHandle: TTransactionHandle;
begin
lQuery := TQuery.Create(nil);
try
lQuery.ConnectionString := BizObjConsts.cSysDatabaseConnectionString;
{ 一、根据当前任务获取所需流程信息、变量赋值 }
lQuery.CommandText := c_Select_FlowGUID;
lQuery.Params.ParamByName('TaskGUID').AsString := ACurrentTaskGUID;
lQuery.Open;
lFlowGUID := lQuery.FieldByName('FFLOWGUID').AsString;
Assert(lFlowGUID <> '', 'FlowGUID不允许为空');
{ 二、更新当前任务流程状态、时间信息 }
lTransactionHandle := lQuery.Connection.Transaction.Start(True); //启动事务
try
{ 1、更新 TFlow 表 }
lQuery.CommandText := c_Update_TFlow;
lQuery.Params.ParamByName('FlowGUID').AsString := lFlowGUID;
lQuery.Params.ParamByName('FlowState').AsString := Flow.FlowStateToStr(TFlowState.fsAborted);
lQuery.Execute;
{ 2、更新 TTask 表 }
lQuery.CommandText := c_Update_TTask;
lQuery.Params.ParamByName('TaskGUID').AsString := ACurrentTaskGUID;
lQuery.Params.ParamByName('TaskState').AsString := Task.TaskStateToStr(TTaskState.tsAborted);
lQuery.Params.ParamByName('LastChangeTime').AsDateTime := SysSrv.SysService.Time;
lQuery.Execute;
{ 3、更新 TTaskMessage 表 }
lQuery.CommandText := c_Update_TTaskMessage;
lQuery.Params.ParamByName('TaskGUID').AsString := ACurrentTaskGUID;
lQuery.Params.ParamByName('TaskMeesageState').AsString := Task.TaskMessageStateToStr(TTaskMessageState.tmsAborted);
lQuery.Execute;
lQuery.Connection.Transaction.Commit(lTransactionHandle); //提交事务
except
lQuery.Connection.Transaction.Rollback(lTransactionHandle); //回滚事务
raise;
end;
finally
lQuery.Free;
end;
end;
static procedure TFlowControlService.FlowFinish(ACurrentTaskGUID: string);
const
c_Select_FlowGUID = 'select FFLOWGUID from TTASK where FGUID = :TaskGUID';
c_Update_TFlow = 'update TFLOW set FSTATE = :FlowState FFINISHTIME = :FinishTime where FGUID = :FlowGUID';
c_Update_TTask = 'update TTASK set FSTATE = :TaskState, FFINISHTIME = :FinishTime, FLASTCHANGETIME = astChangeTime where FGUID = :TaskGUID';
c_Update_TTaskMessage = 'update TTASKMESSAGE set FSTATE = :TaskMeesageState, FFINISHTIME = :FinishTime where FTASKGUID = :TaskGUID';
var
lQuery: TQuery;
lFlowGUID: string;
lTransactionHandle: TTransactionHandle;
begin
lQuery := TQuery.Create(nil);
try
lQuery.ConnectionString := BizObjConsts.cSysDatabaseConnectionString;
{ 一、根据当前任务获取所需流程信息、变量赋值 }
lQuery.CommandText := c_Select_FlowGUID;
lQuery.Params.ParamByName('TaskGUID').AsString := ACurrentTaskGUID;
lQuery.Open;
lFlowGUID := lQuery.FieldByName('FFLOWGUID').AsString;
Assert(lFlowGUID <> '', 'FlowGUID不允许为空');
{ 二、更新当前任务流程状态、时间信息 }
lTransactionHandle := lQuery.Connection.Transaction.Start(True); //启动事务
try
{ 1、更新 TFlow 表 }
lQuery.CommandText := c_Update_TFlow;
lQuery.Params.ParamByName('FlowGUID').AsString := lFlowGUID;
lQuery.Params.ParamByName('FlowState').AsString := Flow.FlowStateToStr(TFlowState.fsFinished);
lQuery.Params.ParamByName('FinishTime').AsDateTime := SysSrv.SysService.Time;
lQuery.Execute;
{ 2、更新 TTask 表 }
lQuery.CommandText := c_Update_TTask;
lQuery.Params.ParamByName('TaskGUID').AsString := ACurrentTaskGUID;
lQuery.Params.ParamByName('TaskState').AsString := Task.TaskStateToStr(TTaskState.tsFinished);
lQuery.Params.ParamByName('LastChangeTime').AsDateTime := SysSrv.SysService.Time;
lQuery.Params.ParamByName('FinishTime').AsDateTime := SysSrv.SysService.Time;
lQuery.Execute;
{ 3、更新 TTaskMessage 表 }
lQuery.CommandText := c_Update_TTaskMessage;
lQuery.Params.ParamByName('TaskGUID').AsString := ACurrentTaskGUID;
lQuery.Params.ParamByName('TaskMeesageState').AsString := Task.TaskMessageStateToStr(TTaskMessageState.tmsFinished);
lQuery.Params.ParamByName('FinishTime').AsDateTime := SysSrv.SysService.Time;
lQuery.Execute;
lQuery.Connection.Transaction.Commit(lTransactionHandle); //提交事务
except
lQuery.Connection.Transaction.Rollback(lTransactionHandle); //回滚事务
raise;
end;
finally
lQuery.Free;
end;
end; |