网通的sms平台项目版本已经提交,负责的产品模块开发,趁着今天的空闲时间来给它总结下。
面向电信运营商的管理系统,主要分CP/SP和OP两大子系统,其实两者之间主要区别主要是权限分配的不同,简单一点理解:SP/OP操作员或运营商操作员提交产品开通申请,修改申请,产品暂停申请,恢复暂停申请或产品注销申请。运营商管理员查看申请信息,接着由管理员(包括不同角色)对相应的申请进行审批,整改,配置和测试等工作步骤,工作成功走完后,产品即生效,中间任一工作流步骤失败则直接通知申请者申请驳回(整改步骤初外,其可以给申请者一次修改申请信息的机会)。
关键字 工作流引擎 业务表分析与设计
工作流引擎,从开始的理论理解,现在,通过对每一步的数据跟踪后,现对其有了一个比较清晰的认识。其实所谓的工作流引擎,我们可以把它理解为一套组件,其包括:业务逻辑代码,xml配置文件和数据库表支持。业务逻辑代码将终端相关数据记录到引擎表,同时控制工作流中的每一个步骤的准确定位并解析xml文件数据并将其注册到工作流引擎表中。
工作流相关字段介绍
工作流流程状态workflowlife
//表示工作流执行过程中的每一个步骤,整个工作流走完后workflowlife还原为0
0-未启动,
1-审核中,
2-配置中,
3-测试中,
4-整改中,
5-割接中
工作流状态,workflow
//表示当前是哪一个状态发起的工作流
0-未启动,
1-申请,
2-修改,
3-暂停,
4-恢复,
5-预注销,
6-注销
产品状态,status
//相应状态下发起的工作流对应的产品的状态
0-申请
1-正常
11-申请待生效
2-暂停
5-预注销
6-注销
工作流引擎配置文件 product_create.wkfw(产品申请流程...)


<?xml version="1.0" encoding="gb2312"?>
<workflow name="myproduct_create" show_name="产品申请流程" group_name="" >
<str_name seq="0" name="cpindex" ><![CDATA[]]></str_name>
<str_name seq="1" name="cpid" ><![CDATA[CPSP代码]]></str_name>
<str_name seq="2" name="cpname" ><![CDATA[]]></str_name>
<str_name seq="3" name="service_code" ><![CDATA[业务能力代码]]></str_name>
<str_name seq="4" name="serviceindex"><![CDATA[]]></str_name>
<str_name seq="5" name="serviceid"><![CDATA[业务代码]]></str_name>
<str_name seq="6" name="servicename"><![CDATA[业务名称]]></str_name>
<str_name seq="7" name="productindex"><![CDATA[]]></str_name>
<str_name seq="8" name="productid" ><![CDATA[产品代码]]></str_name>
<str_name seq="9" name="productname" ><![CDATA[产品名称]]></str_name>

<actions>
<action id="1" name="提交申请" caller="" >
<step_str_name seq="0" ><![CDATA[]]></step_str_name>
<step_str_name seq="1" ><![CDATA[]]></step_str_name>
<step_str_name seq="2" ><![CDATA[]]></step_str_name>
<step_str_name seq="3" ><![CDATA[]]></step_str_name>
<step_str_name seq="4" ><![CDATA[]]></step_str_name>
<step_str_name seq="5" ><![CDATA[]]></step_str_name>
<step_str_name seq="6" ><![CDATA[]]></step_str_name>
<step_str_name seq="7" ><![CDATA[]]></step_str_name>
<step_str_name seq="8" ><![CDATA[]]></step_str_name>
<step_str_name seq="9" ><![CDATA[]]></step_str_name>
</action>
<action id="2" name="待审核" caller="5010">
</action>
<action id="3" name="待整改" caller="">
<action_str_name seq="0" name="laststep"><![CDATA[]]></action_str_name>
</action>
<action id="4" name="待配置" caller="5012" >
</action>
<action id="5" name="待测试" caller="5011" >
</action>
</actions>
<script><
int action_id,laststep;
string action_result;
string process_page;
string serviceshort;
//下面三个变量从jsp页面中或pro返回值获得的
action_id = get_int_param("action_id");//之前就从数据库引擎表中查询出来了
action_result = get_str_param("action_result");
serviceshort = get_str_param("serviceshort");

process_page ="/"+ serviceshort + "/product/product_create.jsp";

set_param("process_page", process_page);

switch(action_id)
{ //
case 1: // 申请提交
{
set_param("status", 0);
set_param("workflowlife", 1);//转为待审核中
return 2; //
}
break;
case 2: // 审核
{
if (action_result=="success")
{
set_param("status", 0);
set_param("workflowlife", 2);//转为待配置中
set_param("workflow", 1);//申请流程
return 4;
}
else if (action_result=="fail")
{
set_param("status", 0);
set_param("workflowlife", 0);//转为待未启动
set_param("workflow", 0);//未启动 1? 实际product表中是1?
return 0;
}
else if (action_result=="modify")
{
set_param("status", 0);
set_param("workflowlife", 4);//转为待整改中
set_param("caller", get_str_param("cpindex"));
out_log("cpspid is:"+get_str_param("cpindex"));
set_param("workflow", 1);//申请流程
set_param("next_action_str0",2);

return 3;
}
}
break;
case 3: //待整改
{if (action_result=="success")
{
laststep= get_int_param("laststep");
out_log("zengai ----- pass tonext for audit laststep is:"+laststep);
set_param("status", 0);
set_param("workflowlife", 1);//转为待审核中
set_param("workflow", 1);//申请流程
return laststep;
}else
{
set_param("status", 0);
set_param("workflowlife", 0);//转为待未启动
set_param("workflow", 0);//未启动 流程结束
return 0;
}
}
break;
case 4: // 配置
{if (action_result=="success")
{
set_param("status", 0);
set_param("workflowlife", 3);//转为待测试
set_param("workflow", 1);//申请流程
return 5;
}else if (action_result=="fail")
{
set_param("status", 0); //审核不通过
set_param("workflowlife", 0);
set_param("workflow", 0);//申请流程结束
return 0;
}
else
{// zengai
set_param("status", 0);
set_param("workflowlife", 4);//转为待整改中
set_param("caller", get_str_param("cpindex"));
out_log("cpspid is:"+get_str_param("cpindex"));
set_param("workflow", 1);//申请流程
set_param("next_action_str0",4);

return 3;
}
}
break;
case 5: // 测试
{
if (action_result=="success")
{
set_param("status", 1);
set_param("workflowlife", 0);//转为结束流程
set_param("workflow", 0);//未启动
return 0;
}else if (action_result=="fail")
{
set_param("status", 0); //审核不通过
set_param("workflowlife", 0);
set_param("workflow", 0);//申请流程结束
return 0;
}
else
{// zengai
set_param("status", 0);
set_param("workflowlife", 4);//转为待整改中
set_param("caller", get_str_param("cpindex"));
out_log("cpspid is:"+get_str_param("cpindex"));
set_param("workflow", 1);//申请流程
set_param("next_action_str0",5);

return 3;
}
return 0;
}
break;
}

return 0;

]]></script>
</workflow>

注:以上配置文件中的<script>结点中的流程由c进行解析并控制流程的
引擎表类图描绘:

引擎表的设计如下:
wkfw_reg 表 :
create table WKFW_REG
(
WKFW_ID NUMBER(10) not null,
WKFW_NAME VARCHAR2(64) not null, --对应工作流配置文件*.wkfw
SHOW_NAME VARCHAR2(64),
GROUP_NAME VARCHAR2(64),
WKFW_TYPE NUMBER(5),
STR0_NAME VARCHAR2(64),
STR1_NAME VARCHAR2(64),
STR2_NAME VARCHAR2(64),
STR3_NAME VARCHAR2(64),
STR4_NAME VARCHAR2(64),
STR5_NAME VARCHAR2(64),
STR6_NAME VARCHAR2(64),
STR7_NAME VARCHAR2(64),
STR8_NAME VARCHAR2(64),
STR9_NAME VARCHAR2(64),
STR0_SHOW_NAME VARCHAR2(64),
STR1_SHOW_NAME VARCHAR2(64),
STR2_SHOW_NAME VARCHAR2(64),
STR3_SHOW_NAME VARCHAR2(64),
STR4_SHOW_NAME VARCHAR2(64),
STR5_SHOW_NAME VARCHAR2(64),
STR6_SHOW_NAME VARCHAR2(64),
STR7_SHOW_NAME VARCHAR2(64),
STR8_SHOW_NAME VARCHAR2(64),
STR9_SHOW_NAME VARCHAR2(64)
)
wkfw_action_reg 表:
create table WKFW_ACTION_REG
(
WKFW_ID NUMBER(10) not null,
ACTION_ID NUMBER(5) not null,
ACTION_NAME VARCHAR2(64),
ACTION_TYPE NUMBER(5),
ACTION_STR0_NAME VARCHAR2(64),
ACTION_STR1_NAME VARCHAR2(64),
ACTION_STR2_NAME VARCHAR2(64),
ACTION_STR3_NAME VARCHAR2(64),
ACTION_STR4_NAME VARCHAR2(64),
ACTION_STR5_NAME VARCHAR2(64),
ACTION_STR6_NAME VARCHAR2(64),
ACTION_STR7_NAME VARCHAR2(64),
ACTION_STR8_NAME VARCHAR2(64),
ACTION_STR9_NAME VARCHAR2(64),
ACTION_STR0_SHOW_NAME VARCHAR2(64),
ACTION_STR1_SHOW_NAME VARCHAR2(64),
ACTION_STR2_SHOW_NAME VARCHAR2(64),
ACTION_STR3_SHOW_NAME VARCHAR2(64),
ACTION_STR4_SHOW_NAME VARCHAR2(64),
ACTION_STR5_SHOW_NAME VARCHAR2(64),
ACTION_STR6_SHOW_NAME VARCHAR2(64),
ACTION_STR7_SHOW_NAME VARCHAR2(64),
ACTION_STR8_SHOW_NAME VARCHAR2(64),
ACTION_STR9_SHOW_NAME VARCHAR2(64)
)
wkfw_session表:
//wkfw_session_history表结构一样
create table WKFW_SESSION
(
WKFW_SID VARCHAR2(28) not null,---开始由引擎初始化值
WKFW_ID NUMBER(10) not null,
NEXT_ACTION_ID NUMBER(10), -- 和product_workflowlife的actionindex对应
NEXT_ACTION_SID NUMBER(10), --和product_workflowlife的actionsid对应
START_TIME CHAR(19),
END_TIME CHAR(19),
STATE NUMBER(5),
STATE_CAUSE VARCHAR2(255),
STR0 VARCHAR2(255), --stro到str9对应product表中的字段,在*.wkfw中有映射
STR1 VARCHAR2(255),
STR2 VARCHAR2(255),
STR3 VARCHAR2(255),
STR4 VARCHAR2(255),
STR5 VARCHAR2(255),
STR6 VARCHAR2(255),
STR7 VARCHAR2(255),
STR8 VARCHAR2(255),
STR9 VARCHAR2(255),
WKFW_PRIORITY NUMBER(5) default 0 --工作流优先级
)
wkfw_action表:
//wkfw_action_history表结构一样
create table WKFW_ACTION
(
WKFW_ID NUMBER(10) not null,
ACTION_ID NUMBER(5) not null,
WKFW_SID VARCHAR2(28) not null, ---开始由引擎初始化值
ACTION_SID NUMBER(10),
CALLER VARCHAR2(255),
CALLER1 VARCHAR2(255),
RESERVED_HANDLER VARCHAR2(255),
RESERVE_EXPIRE_TIME CHAR(19),
HANDLER VARCHAR2(64), --对应登录用户名,根据handler可以查当前用户的工单和历史工单
START_TIME CHAR(19),
END_TIME CHAR(19),
ACTION_RESULT VARCHAR2(255), --执行结果,success或fail
RESULT_CAUSE VARCHAR2(255),
IS_AUTO NUMBER(1),
ACTION_STR0 VARCHAR2(255),
ACTION_STR1 VARCHAR2(255),
ACTION_STR2 VARCHAR2(255),
ACTION_STR3 VARCHAR2(255),
ACTION_STR4 VARCHAR2(255),
ACTION_STR5 VARCHAR2(255),
ACTION_STR6 VARCHAR2(255),
ACTION_STR7 VARCHAR2(255),
ACTION_STR8 VARCHAR2(255),
ACTION_STR9 VARCHAR2(255),
PROCESS_PAGE VARCHAR2(1024)
)
说明:
wkfw_reg表存放的是具体每个工作流状态(workflow)下的信息,用wkfw_id唯一标识,wkfw_name为相应配置文件名称,SHOW_NAME,GROUP_NAME,STR0_NAME -- STR9_NAME,STR0_SHOW_NAME -STR9_SHOW_NAME字段从配置文件结点属性解析而得.
wkfw_action_reg表存放的是在每个工作流流程状态(workflowlife)下的信息,用action_id和wkfw_id共同约束记录,action_id和action_name字段从配置文件中的结点action的两个属性id和name解析而得,ACTION_STR0_NAME -- ACTION_STR9_NAME,ACTION_STR0_SHOW_NAME -- ACTION_STR9_SHOW_NAME为扩展字段.
wkfw_session表存放的是当工作流开启到结束的过程当中,每个工作流状态workflow下的工作流流程的变化记录(由next_action_id和next_action_sid标记变化),同时由wkfw_id和wkfw_sid约束当前工作流和工作流流程的定位,涉及到的业务信息(str0-str9字段),工作流开始和结束时间以及此工作流下一步骤的状态字段(next_action_id和next_action_sid)的值定位。
业务信息形如: cp/sp序号cpindex 、cp/sp编号cpid、cp/sp名称cpcnshortname、业务能力类型名srvtypeshortname()、业务序号serviceindex、业务编号serviceid、业务名称servicename、产品序号productindex、产品编号productid、产品名称productname.
wkfw_session_history表存放的是wkfw_session中的历史信息,因为当工作流走完后,产品在引擎表wkfw_session注册的信息就会注销,但会在此history表中留下历史记录作为以后的历史工单(工作流)查询.
wkfw_action表存放的是每个工作流状态(workflow)下的各个工作流流程(workflowlife)步骤的记录的集合,并用wkfw_id和action_id来实现具体的工作流状态(workflow)下的工作流流程状态(workflowlife)的唯一性确定.同时,wkfw_action中的action_id和action_sid状态值和wkfw_session中的next_action_id,next_action_sid对应.即,next_action_id和next_action_sid对应wkfw_action中工作流步骤处理中待处理(审核,配置,测试)状态的action_id和action_sid值.
wkfw_action_history表存放的是wkfw_action中的历史信息,因为当工作流走完后,产品在引擎表wkfw_action注册的信息就会注销,但会在此history表中留下历史记录作为以后的历史工单(工作流)查询.
注:
wkfw_reg和wkfw_action_reg表中的数据是在系统启动时由引擎程序一次性解析所有的*.wkfw文件并将其中的节点值全部注册到此两表中.
业务表设计(短信产品):
product buf表
buf表可以理解为临时表,主要是在对产品的修改(此产品已经走完工作流)申请后,进入工作流的下一步审核时,要是审核没有通过,则产品表中的数据无法还原到初始状态。所以,这里是这样实现的:在产品修改申请提交后,将修改后的数据insert先存到buf表中,待修改的申请成功走完工作流的每一个步骤后,在最后一步时,再将buf的数据insert到产品表中,此时修改的数据才真正在产品表中生效!
product workflowhist表
产品工作流历史表和产品表相比较,就是在前面多了workflowindex,actionindex,actionsid,wkfwsid字段,用来标记其工作流每个步骤的历史记录,这里主要是在"产品审核"时有"跟踪产品流程"需要查询每个阶段的产品相关详细信息的需求.
同时,对于指令的工作流历史表,也是需要的,因为在"跟踪产品流程"时,点击详细的时候也需要把每个工作流阶段的指令信息分别显示出来.(因为在审核和配置步骤都可以对指令的信息进行修改)
产品查询的详细信息页面中的workflow,workflowlife,status值,是根据product表中的workflow,workflowlife,status值读取资源文件中对应的name值来显示,而在产品审核信息一览页面中的产品状态信息则是联合查询引擎表中wkfw_session,wkfw_action_wkfw_reg和wkfw_action_reg表得到的.
ex: 产品申请工作流程分析
[1]产品申请工作流步骤
产品信息add到product 表中(status,workflow和workflowlife字段值可在produce中init)--------(产品信息和配置文件解析信息)add到wkfw_session(next_action_id和next_action_sid为2,2)--------(产品信息和配置文件中解析信息)wkfw_action(action_id和action_sid为1,1;同时生成"待审核"记录,其action_id和action_sid为2,2,starttime字段和申请时的endtime字段相等,endtime字段为null,表示这条记录是待审核状态)--------(产品信息和配置文件解析信息)add到productworkflowlife(actionsid和actionindex为1,1).
注:产品配置,测试等步骤和申请一样,只是status,workflow和workflowlife字段值是由解析*.wkfw得到。wkfw_action中的"待"记录的starttime字段值和上一步的endtime对应。
action_id的初值为1,解析*.wkfw文件时和其文件中的action_id匹配并执行配置文件相应的代码段,同时将此步骤对应的action_id值注册到wkfw_action表中,下一个工作流步骤的action_id从引擎表中查询出来跟*.wkfw配置文件中的action_id匹配...
[2产品工作流步骤成功走完
(配置文件解析信息)update到proudct表中status,workflow和workflowlife字段--------(next_action_id和next_action_sid字段)update表wkfw_session_history中对应字段--------wkfw_session表中对应记录(delete) ----------(action_id和action_sid字段)update表wkfw_action_history中对应字段(action_result变为'success',handler为登录userName) ------- wkfw_action表中对应记录(delete)---------(产品信息和配置文件解析信息)add到productworkflowlife .
[3]工作流走失败(如审核)
(配置文件解析信息)update到proudct表中status,workflow和workflowlife字段-------(next_action_id和next_action_sid字段)update表wkfw_session_history中对应字段------wkfw_session表中记录(delete) ----------(action_id和action_sid字段)update表wkfw_action_history中对应字段(action_result变为'fail',handler为登录userName)--------wkfw_action表中对应记录(delete) ---------wkfw_action_history()。
其余如配置,测试等每一个工作流流程步骤和审核一样,只是相关工作流状态的字段的值不同而已.
posted on 2007-08-22 14:08
cheng 阅读(1751)
评论(1) 编辑 收藏 所属分类:
WorkFlow