起步软件技术论坛-X3

 找回密码
 立即注册
搜索
查看: 626|回复: 4

[分享]根据业务数据生成流程控制数据**

[复制链接]
发表于 2007-11-30 13:34:49 | 显示全部楼层 |阅读模式
对于已有系统,可能已经存在了业务数据,而且有些流程已经执行了一半,还没有结束,当用X3平台开发系统替代这些旧系统时候,旧需要考虑如何把旧系统执行中的流程放到X3系统中来继续执行。

有两种做法:
一种是直接往系统数据库中增加流程数据的方式(当然,这种方法对表的依赖非常严重,强烈不推荐使用)
第二种方法是调用平台中的方法,用代码创建这些流程控制数据

有关流程控制数据,请参考 http://bbs.justep.com/forum.php?mod=viewthread&tid=19485
回复

使用道具 举报

 楼主| 发表于 2007-11-30 13:45:22 | 显示全部楼层
以下介绍第二种方法

用到两个类(TFlow、TTask),分别对这两个对象赋值,然后调用SaveToDB保存到系统数据库中

TFlow
  property GUID: string;   //流程GUID,不用赋值,在任务中引用
  property Subject: string;  //主题
  property ProcURL: string;    //过程URL
  property DisplayName: string;  //显示名称
  property Description: string;  //描述
  property FlowField: string;   //流程字段URL
  property ID: string;   //流程ID,流程字段的值
  property IDs: Business.System.TStrings;  //流程ID,当一个流程实例对应多个业务数据时,这里有多个
  property CreateTime: Double;  //创建时间
  property FinishTime: Double;   //结束时间
  property LimitTime: Double;  //限定时间
  property State: TFlowState;  //状态
  procedure SaveToDB;  //保存到数据库

比如:
    lFlow := TFlow.Create;
    lFlow.ProcURL := 'Biz:\LZ\LCSJJCLC.PROC';
    lFlow.DisplayName := '流程事件检查流程';
    lFlow.FlowField := 'Biz:\OPERATION\OPERATIONDB.DATABASE\CRM_PRODUCT.TABLE\PRODUCTID.Field';
    lFlow.ID := ADataSet.FieldByName('PRODUCTID').AsString;
    lFlow.State := TFlowState.fsProcessing;
    lFlow.ParentGUID := JSConst.cRootID;
    lFlow.PrevGUID := JSConst.cRootID;
    lFlow.NextGUID := JSConst.cRootID;
    lFlow.CreateTime := SysUtils.Now();
    lFlow.SaveToDB;
执行上述代码会在系统数据库的流程表、流程ID表中增加相应的记录
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-11-30 13:59:51 | 显示全部楼层
TTask
  property GUID: string;  //任务GUID,不用赋值,自动填充的
  property FlowGUID: string;  //任务所属流程的GUID,用TFlow.Guid赋值
  property ProcURL: string;  //过程URL
  property ProcUnitID: string;  //环节ID
  property FuncURL: string;  //对应的功能URL
  property PrevGUID: string;  //前驱任务的GUID,通过这个字段来确定任务的先后关系
  property NextGUID: string;  //后继任务的GUID,必须为空字符串,否则流程监控中不显示了
  property TaskTypeName: string;  //业务类型,缺省填环节显示名称
  property Subject: string;  //主题
  property Description: string;  //描述
  property Priority: TTaskPriority;   //优先级
  property SenderDeptID: string;   //任务提交人部门ID
  property SenderPositionID: string;   //任务提交人岗位ID
  property SenderID: string;   //任务提交人ID
  property CreateTime: TDateTime;  //创建时间
  property StartTime: TDateTime;  //任务开始时间
  property FinishTime: TDateTime;  //结束时间
  property State: TTaskState;  //状态
  property TaskMessages: TTaskMessages;  //任务处理人信息,每一个处理人一条TaskMessage,保存到任务消息表中
  property BizDatas: TTaskBizDataList;  //任务对应业务数据,保存到任务业务数据表中
  procedure SaveToDB;  //保存到系统数据库

例如:
  lTask := TTask.Create;
  lTask.Kind := 'ftkActivity';
  lTask.FlowGUID := AFlow.GUID;
  lTask.ProcURL := AFlow.ProcURL;
  lTask.ProcUnitID := AFlowPath.ProcUnitID;
  lTask.FuncURL := AFlowPath.FuncURL;
  lTask.NextGUID := '';
  lTask.Subject := '我的流程'+ADataSet.FieldByName('PRODUCTID').AsString;
  if Assigned(preTask) then
    lTask.PrevGUID := preTask.GUID;
  lTask.SenderDeptID := 'XSB';
  lTask.SenderPositionID := 'XSY';
  lTask.SenderID := 'ZS';
  lBizData := TTaskBizData.Create;
  lBizDataRec := TTaskBizDataRec.Create;
  lBizDataRec.BizField := AFlow.FlowField;
  lBizDataRec.Value := AFlow.ID;
  lBizData.BizDataKeys.Add(lBizDataRec);
  lTask.BizDatas.Add(lBizData);
  lTaskMessage := lTask.TaskMessages.AddTaskMessage(nil, 'XSB', 'XSY', 'ZS');
  lTask.TaskTypeName := AFlowPath.TaskTypeName;
  if AFinished then
  begin
    lTask.State := TTaskState.tsFinished;
    lTaskMessage.State := TTaskMessageState.tmsFinished;
    lTaskMessage.FinishTime := SysUtils.Now();
    lTaskMessage.ReceiveTime := SysUtils.Now();
  end
  else
  begin
    lTask.State := TTaskState.tsProcessing;
    lTaskMessage.State := TTaskMessageState.tmsProcessing;
    lTaskMessage.FinishTime := SysUtils.Now();
    lTaskMessage.ReceiveTime := SysUtils.Now();
  end;
  lTask.SaveToDB;
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-11-30 14:02:22 | 显示全部楼层
以下是我根据一个数据集生成流程控制数据的完整代码

unit MainForm;

interface

uses
  Business.System, Business.Model, Business.Forms, Business.Data, Business.Model.Flow;

type
  TMainForm = class(TForm)
    FuncBroker: TFuncBroker;
    InfoBroker: TInfoBroker;
    ControlBar: TControlBar;
    DataNavigator: TDataNavigator;
    DocViewBar: TDocViewBar;
    Panel: TPanel;
    DocViewDTYWSJXX_SJWG1: TDocView;
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    {private declarations}
    FPath: TStrings;
    procedure InitFlowPaths;
    procedure UnInitFlowPaths;
    function AddAFlow(ADataSet: TDataSet): TFlow;
    function CreateATask(ADataSet: TDataSet; AFlowPath: TFlowPath; AFlow: TFlow; preTask: TTask; AFinished: Boolean): TTask;
  public
    {public declarations}
  end;

implementation

procedure TMainForm.Button1Click(Sender: TObject);
var
  i: Integer;
  lDataSet: TDataSet;
begin
  lDataSet := InfoBroker.Info.DataSetByID('BZSJJ1');

  InitFlowPaths;
  lDataSet.DisableControls;
  try
    lDataSet.First;
    while not lDataSet.Eof do
    begin
      AddAFlow(lDataSet);
      lDataSet.Next;
    end;
  finally
    lDataSet.EnableControls;
  end;
  UnInitFlowPaths;
end;

type
  TFlowPath = class(TObject)
  public
    ProcUnitID: String;
    TaskTypeName: String;
    FuncURL: String;
    PrevUnitID: String;
    Path: String;
  end;

procedure TMainForm.InitFlowPaths;
var
  lPath: TFlowPath;
begin
  if not Assigned(FPath) then FPath := TStringList.Create;
  lPath := TFlowPath.Create;
  lPath.ProcUnitID := 'LCSJRKHJ';
  lPath.TaskTypeName := '流程事件入口环节-控制条件';
  lPath.FuncURL := 'Biz:\LZ\LCSJRKHJ.Func';
  lPath.PrevUnitID := '';
  lPath.Path := ';LCSJZJHJ;ZJHJ1;ZJHJ5;ZJHJ2;ZJHJ3;ZJHJ4;';
  FPath.AddObject(lPath.ProcUnitID, lPath);
  lPath := TFlowPath.Create;
  lPath.ProcUnitID := 'LCSJZJHJ';
  lPath.TaskTypeName := '流程事件中间环节';
  lPath.FuncURL := 'Biz:\LZ\LCSJZJHJ.Func';
  lPath.PrevUnitID := 'LCSJRKHJ';
  lPath.Path := '';
  FPath.AddObject(lPath.ProcUnitID, lPath);
  lPath := TFlowPath.Create;
  lPath.ProcUnitID := 'ZJHJ1';
  lPath.TaskTypeName := '流转控制环节';
  lPath.FuncURL := 'Biz:\LZ\CLSJHJ.Func';
  lPath.PrevUnitID := 'LCSJRKHJ';
  lPath.Path := ';ZJHJ4;ZJHJ5;';
  FPath.AddObject(lPath.ProcUnitID, lPath);
  lPath := TFlowPath.Create;
  lPath.ProcUnitID := 'ZJHJ2';
  lPath.TaskTypeName := '中间环节2';
  lPath.FuncURL := 'Biz:\LZ\LCSJZJHJ.Func';
  lPath.PrevUnitID := 'LCSJRKHJ';
  lPath.Path := ';ZJHJ4;';
  FPath.AddObject(lPath.ProcUnitID, lPath);
  lPath := TFlowPath.Create;
  lPath.ProcUnitID := 'ZJHJ3';
  lPath.TaskTypeName := '中间环节3';
  lPath.FuncURL := 'Biz:\LZ\LCSJZJHJ.Func';
  lPath.PrevUnitID := 'LCSJRKHJ';
  lPath.Path := ';ZJHJ4;';
  FPath.AddObject(lPath.ProcUnitID, lPath);
  lPath := TFlowPath.Create;
  lPath.ProcUnitID := 'ZJHJ5';
  lPath.TaskTypeName := '修改任务控制者';
  lPath.FuncURL := 'Biz:\LZ\CLSJHJ.Func';
  lPath.PrevUnitID := 'ZJHJ1';
  lPath.Path := ';ZJHJ4;';
  FPath.AddObject(lPath.ProcUnitID, lPath);
  lPath := TFlowPath.Create;
  lPath.ProcUnitID := 'ZJHJ4';
  lPath.TaskTypeName := '代码控制回退环节';
  lPath.FuncURL := 'Biz:\LZ\DMKZHTGN.Func';
  lPath.PrevUnitID := ';ZJHJ1;ZJHJ2;ZJHJ3;ZJHJ5;';
  lPath.Path := '';
  FPath.AddObject(lPath.ProcUnitID, lPath);
end;

procedure TMainForm.UnInitFlowPaths;
begin
  while FPath.Count>0 do
  begin
    TFlowPath(FPath.Objects[0]).Free;
    FPath.Delete(0);
  end;
end;

function TMainForm.AddAFlow(ADataSet: TDataSet): TFlow;
var
  i, j: Integer;
  lUnitID: String;
  lFlowPath: TFlowPath;
  lFlow: TFlow;
  lTask: TTask;
  lFreeobjs: TList;
begin
  lFreeobjs := TList.Create;
  try
    lUnitID := SysUtils.UpperCase(ADataSet.FieldByName('PRODUCTTYPE').AsString);
    //环节ID是否存在
    if (Length(lUnitID)=0) or (FPath.IndexOf(lUnitID)=-1) then
      Exit;

    lFlow := TFlow.Create;
    lFlow.ProcURL := 'Biz:\LZ\LCSJJCLC.PROC';
    lFlow.DisplayName := '流程事件检查流程';
    lFlow.FlowField := 'Biz:\OPERATION\OPERATIONDB.DATABASE\CRM_PRODUCT.TABLE\PRODUCTID.Field';
    lFlow.ID := ADataSet.FieldByName('PRODUCTID').AsString;
    lFlow.State := TFlowState.fsProcessing;
    lFlow.ParentGUID := JSConst.cRootID;
    lFlow.PrevGUID := JSConst.cRootID;
    lFlow.NextGUID := JSConst.cRootID;
    lFlow.CreateTime := SysUtils.Now();
    lFlow.SaveToDB;
    lFreeObjs.Add(lFlow);
    lTask := nil;
    for i:=0 to FPath.Count-1 do
    begin
      lFlowPath := FPath.Objects as TFlowPath;
      if StringUtils.Pos(';'+lUnitID+';', lFlowPath.Path)>0 then
      begin
        if Length(lFlowPath.PrevUnitID)=0 then
          lTask := nil
        else if StringUtils.Pos(';', lFlowPath.PrevUnitID)=0 then
          for j:=1 to lFreeObjs.Count-1 do
          try
            lTask := lFreeObjs[j] as TTask;
            if lTask.ProcUnitID=lFlowPath.PrevUnitID then
              Break;
          except
            Continue;
          end
        else
          for j:=1 to lFreeObjs.Count-1 do
          try
            lTask := lFreeObjs[j] as TTask;
            if StringUtils.Pos(';'+lTask.ProcUnitID+';', lFlowPath.PrevUnitID)>0 then
              Break;
          except
          end;
        lTask := CreateATask(ADataSet, lFlowPath, lFlow, lTask, True);
        lFreeObjs.Add(lTask);
      end;
    end;
    i := FPath.IndexOf(lUnitID);
    lFlowPath := FPath.Objects as TFlowPath;
    lTask := CreateATask(ADataSet, lFlowPath, lFlow, lTask, False);
    lFreeObjs.Add(lTask);
  finally
    for i:=lFreeObjs.Count-1 downto 0 do
      lFreeObjs.Free;
    lFreeObjs.Free;
  end;
end;

function TMainForm.CreateATask(ADataSet: TDataSet; AFlowPath: TFlowPath; AFlow: TFlow; preTask: TTask; AFinished: Boolean): TTask;
var
  lBizData: TTaskBizData;
  lBizDataRec: TTaskBizDataRec;
  lTaskMessage: TTaskMessage;
begin
  Result := TTask.Create;
  Result.Kind := 'ftkActivity';
  Result.FlowGUID := AFlow.GUID;
  Result.ProcURL := AFlow.ProcURL;
  Result.ProcUnitID := AFlowPath.ProcUnitID;
  Result.FuncURL := AFlowPath.FuncURL;
  Result.NextGUID := '';
  Result.Subject := '我的流程'+ADataSet.FieldByName('PRODUCTID').AsString;
  if Assigned(preTask) then
    Result.PrevGUID := preTask.GUID;
  Result.SenderDeptID := 'XSB';
  Result.SenderPositionID := 'XSY';
  Result.SenderID := 'ZS';
  lBizData := TTaskBizData.Create;
  lBizDataRec := TTaskBizDataRec.Create;
  lBizDataRec.BizField := AFlow.FlowField;
  lBizDataRec.Value := AFlow.ID;
  lBizData.BizDataKeys.Add(lBizDataRec);
  Result.BizDatas.Add(lBizData);
  lTaskMessage := Result.TaskMessages.AddTaskMessage(nil, 'XSB', 'XSY', 'ZS');
  Result.TaskTypeName := AFlowPath.TaskTypeName;
  if AFinished then
  begin
    Result.State := TTaskState.tsFinished;
    lTaskMessage.State := TTaskMessageState.tmsFinished;
    lTaskMessage.FinishTime := SysUtils.Now();
    lTaskMessage.ReceiveTime := SysUtils.Now();
  end
  else
  begin
    Result.State := TTaskState.tsProcessing;
    lTaskMessage.State := TTaskMessageState.tmsProcessing;
    lTaskMessage.FinishTime := SysUtils.Now();
    lTaskMessage.ReceiveTime := SysUtils.Now();
  end;
  Result.SaveToDB;
end;

end.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-12-3 10:09:25 | 显示全部楼层
每一个流程实例都要产生一个TFlow的流程实例,象2楼的代码
流程中的每一个环节都要产生一个TTask的任务,象3楼的代码
如下图所示,首先创建一个流程实例TFlow
这个流程实例中每一个环节都要指定FlowGuid等于流程实例的GUID
入口环节(环节1)的提交人和处理人是同一个人,是流程的发起人
中间环节的提交人是上一个环节的处理人
例如:环节2的提交人就是环节1的处理人,环节3的提交人就是环节2的处理人
任务的PrevGUID是上一个环节任务的GUID
例如:环节2的PrevGUID是环节1的GUID,环节3的PrevGUID是环节2的GUID
任务的NextGUID必须是空字符串,(注意:必须赋值,而且必须是空字符串)

1.png

7.94 KB, 下载次数: 397

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Justep Inc.

GMT+8, 2025-7-1 07:38 , Processed in 0.045737 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表