工作流引擎实现

1.工作流引擎实现


mysql> select * from workflow_list;
+----+------+---------------+--------------+-------------+---------------------+--------+-------------+
| id | name | first_step_id | last_step_id | total_steps | insert_time         | type   | delete_flag |
+----+------+---------------+--------------+-------------+---------------------+--------+-------------+
|  1 | 流程 |             1 |            5 |           5 | 2013-07-22 19:22:52 | change |           0 |
+----+------+---------------+--------------+-------------+---------------------+--------+-------------+


name 流程名称
first_step_id 第一步的stepID
last_step_id 最后一步的stepID
total_steps  流程步骤总数
insert_time  插入时间
type 流程类别(根据实际情况而定,存数据的时候做区别用)
delete_flag  删除标示




mysql> select * from workflow_steps;
+----+---------+--------------+--------------+---------------------+---------+-----------+--------------+
| id | name    | prev_step_id | next_step_id | insert_time         | role_id | role_type | type         |
+----+---------+--------------+--------------+---------------------+---------+-----------+--------------+
|  1 | ?????   |            0 |            2 | 2013-07-22 19:23:23 |       9 |         1 | cost_enginer |
|  2 | ??????? |            1 |            3 | 2013-07-22 19:23:53 |      10 |         1 | simple       |
|  3 | ??????  |            2 |            4 | 2013-07-22 19:24:15 |      11 |         1 | simple       |
|  4 | ??????  |            3 |            0 | 2013-07-22 19:24:27 |      12 |         1 | simple       |
+----+---------+--------------+--------------+---------------------+---------+-----------+--------------+
name 步骤名称
prev_step_id 上一步骤ID
next_step_id 下一步骤ID
insert_time 插入时间
role_id,role_type  步骤执行者(role_type=1,role_id 标示明确指定需要user_id=role_id 这个人执行;role_type=2,role_id 标示user角色=role_id 的这群人都能执行)
type 步骤类型(根据实际情况而定,主要是存数据的时候做区别)


--------------------------------------------------------------------------------------------------------------------------------------------------------------


通过以上两个表可以构建流程模板,下面是流程实例:
mysql> select * from workflow_detail;
+--------------------+-------------+----------------+---------------+--------------+--------------+----------------+---------------------+---------------------+------------+------------+--------+------------+
| id                 | workflow_id | name           | first_step_id | next_step_id | next_role_id | next_role_type | insert_time         | update_time         | other_data | create_uid | type   | is_success |
+--------------------+-------------+----------------+---------------+--------------+--------------+----------------+---------------------+---------------------+------------+------------+--------+------------+
| 201307231823122925 |           1 | 1????????????? |             1 |            0 |            0 |              0 | 2013-07-23 18:23:12 | 2013-07-24 10:10:58 | 18         |          1 | change |          2 |
| 201307231856468212 |           1 | ffghh          |             1 |            1 |            2 |              2 | 2013-07-23 18:56:46 | 2013-07-23 18:56:46 | 19         |          3 | change |          0 |
| 201307231901039901 |           1 | ??????         |             1 |            0 |            0 |              0 | 2013-07-23 19:01:03 | 2013-07-24 12:44:10 | 20         |          1 | change |          2 |
| 201307231929236393 |           1 | ??????????     |             1 |            0 |            0 |              0 | 2013-07-23 19:29:23 | 2013-07-23 19:32:50 | 21         |          1 | change |          1 |
| 201307231938558609 |           1 | ????           |             1 |            1 |            2 |              2 | 2013-07-23 19:38:55 | 2013-07-23 19:38:55 | 22         |          1 | change |          0 |
| 201307241008212636 |           1 | ??13?????????? |             1 |            0 |            0 |              0 | 2013-07-24 10:08:21 | 2013-07-24 10:41:00 | 23         |          4 | change |         -1 |
| 201307241124085112 |           1 | ???????        |             1 |            2 |           10 |              1 | 2013-07-24 11:24:08 | 2013-07-24 11:29:14 | 24         |          5 | change |          0 |
| 201307241126026204 |           1 | 9?????????     |             1 |            2 |           10 |              1 | 2013-07-24 11:26:02 | 2013-07-24 11:30:21 | 25         |          4 | change |          0 |
| 201307241228356005 |           1 | ddddfnbgvv     |             1 |            3 |           11 |              1 | 2013-07-24 12:28:35 | 2013-07-24 12:32:07 | 26         |          4 | change |          0 |
| 201307241258155752 |           1 | 13????         |             1 |            0 |            0 |              0 | 2013-07-24 12:58:15 | 2013-07-24 13:28:18 | 27         |          4 | change |          2 |
+--------------------+-------------+----------------+---------------+--------------+--------------+----------------+---------------------+---------------------+------------+------------+--------+------------+
ID 实例ID
workflow_id 实例管理的模板
name 实例名称
first_step_id 第一步骤ID,生成实例的时候通过模板clone过来,方便以后操作
next_step_id  下一个步骤需要执行的步骤,如果是0标示没有下一步了,流程执行成功或者失败
next_role_id,next_role_type 下一个步骤执行的角色
insert_time 插入时间 update_time 更新时间
other_data 绑定工作流的具体数据单编号(例如请假需要绑定工作流,直接把请假单编号放到other_data中,具体审批工作流引擎去完成)
create_uid 创建工作流的人
type clone模板过来的,方便以后分类查询使用,不用再去读模板去了
is_success 实例审批状态 0.审批中 -1.失败 1.成功


每个步骤处理的结果
mysql> desc workflow_step_log;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | int(11)     | NO   | PRI | NULL    | auto_increment |
| log_id      | varchar(50) | YES  |     | NULL    |                |
| step_id     | int(11)     | YES  |     | NULL    |                |
| uid         | int(11)     | YES  |     | NULL    |                |
| result      | int(11)     | YES  |     | NULL    |                |
| remark      | text        | YES  |     | NULL    |                |
| insert_time | datetime    | YES  |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+
log_id 实例ID
step_id 步骤ID
uid 处理人
insert_time 处理时间
result 处理结果 1.同意 -1.拒绝 2.打回
remark 说明
可以再添加一个打回到哪一步的字段


PS:以上是个人原创,有许多地方还欠稳妥,望大牛们多多指教!!!

实现原理是链表的原理,每个节点有前一个节点和后一个节点的标示,将节点串联起来形成一个链

PYTHON 实现的审批:

def simple_approve(log_id,uid,result,remark='',step_id=None):
    user = User.query.get(uid)
    '''
                批准当前步骤
                log_id  当前流程实例
                uid 当前处理人
                result 处理结果
                remark 说明
                step_id 如果是退回,退回步骤ID
    '''
    if not log_id:
        return False,'log_id为空'
    elif not uid:
        return False,'处理人ID不存在'
    elif result!=0 and result!=1 and result!=-1 and result!=2:
        return False,'未能识别处理结果'
    elif result==2 and not step_id:
        return False,'请选择打回位置'
    else:
        log_workflow = WorkFlowDetail.query.get(log_id)
        if not log_workflow or log_workflow.is_success!=0:
            return False,'当前流程不存在'
        else:
            step = WorkFlowStep.query.get(log_workflow.next_step_id)
            #判断处理人是否能处理此步骤
            if (step.role_id==uid and step.role_type==1) or (step.role_type==2 and step.role_id==user.role_id):
                if result==1:       #同意
                    #流程步骤需要向下走
                    log_workflow.next_step_id = step.next_step_id
                    if step.next_step_id ==0:
                        log_workflow.is_success=1
                        log_workflow.next_role_id =0
                        log_workflow.next_role_type =0
                    else:
                        next_step = WorkFlowStep.query.get(step.next_step_id)
                        log_workflow.next_role_id = next_step.role_id
                        log_workflow.next_role_type = next_step.role_type
                elif result==-1:    #拒绝
                    log_workflow.is_success = -1
                    log_workflow.next_step_id = 0
                    log_workflow.next_role_id = 0
                    log_workflow.next_role_type = 0
                elif result== 2:    #打回
                    #查询提供的step_id是否是处理过的,如果是才能允许打回到这步骤
                    log_step = StepLog.query.filter(StepLog.step_id==step_id).filter(StepLog.log_id==log_workflow.id).first()
                    if log_step:
                        log_workflow.next_step_id =step_id
                        rollback_step = WorkFlowStep.query.get(step_id)
                        log_workflow.next_role_id = rollback_step.role_id
                        log_workflow.next_role_type = rollback_step.role_type
                        next_step = WorkFlowStep.query.get(step_id)
                        log_workflow.next_role_id = next_step.role_id
                        log_workflow.next_role_type = next_step.role_type
                    else:
                        return False,'此流程不允许打回到当前步骤'
                #记录处理步骤日志
                step_log = StepLog(log_id =log_id,result=result,remark=remark,step_id=step.id,uid=uid)
                step_log.save()
                log_workflow.save()
            else:
                return False,'您没有处理当前流程步骤权限'
            
            return True,'处理成功'

你可能感兴趣的:(工作流,审批流程)