activiti采购申请-批准实例

以采购为例,说明采购申请–总经理审批的简单流程

工作流程图:采购申请并未设置为Task节点,但最好应该设为Task节点

activiti采购申请-批准实例_第1张图片

工作流核心问题:如何保证采购申请的审批人是应当的审批人?
1、若不用工作流:可以在申请表中第一个审批人都加入一个对应“审批是否通过”的字段,第一审批人直接查询所有申请表,第N审批人查询前面所有审批人对应“审批是否通过”字段为true的申请表
2、activiti思路:建立Task节点,第一个Task节点对应一个业务操作,每个Task都有一个Assignee(执行者),而采购申请表、上一级的审批表通过流程变量依次往下一Task节点传, 并且在下一节点获取,即可以知道Task对应的Assignee有哪些对应的采购申请的审批以及上一审批人的审批意见。

代码片段:

第一步:填写申请并启动流程

/**
 1. 采购提交:提交人user,采购申请表purchaseApply,采购申请物资列表purchaseApplyItems,一个采购申请表中有多项采购物资列表
 2. userAndRole表为用户Id和角色的对应表,可以通过用户的Id来查询用户的角色,而用户的角色在这里被设置为Task的Assignee(执行者)
 3. 需要将采购申请表、采购申请物资列表保存到自己的数据库
 */
public void submit(PurchaseApply purchaseApply,List purchaseApplyItems,String processDefinitionKey,User user) throws DAOException, BaseServiceException {
    //根据用户的id来查询出他所属的角色,角色信息保存在userAndRole表中
    UserAndRole userAndRole = new UserAndRole();
    userAndRole.setUserId(user.getId());
    List userAndRoleList = userAndRoleService.getEntity(userAndRole);
    if(!userAndRoleList.isEmpty()){
        UserAndRole userAndRole2 = userAndRoleList.get(0);
        String roleNumber = String.valueOf(userAndRole2.getRoleId());
        // 保存一个采购申请表
        purchaseApplyDAO.addEntity(purchaseApply);
        // 保存所有的采购申请物资列表
        for (PurchaseApplyItem temp : purchaseApplyItems) {
            purchaseApplyItemsDAO.addEntity(temp);
        }
        // 启动一个流程实例,设置流程变量,指定第一个办理人
        Map map = new HashMap();
        map.put("purchase", purchaseApply);
        //启动工作流,map为流程变量,将传到下一个节点,
        //在下一个节点通过PurchaseApply purchaseApply = (PurchaseApply) taskService.getVariable(id, "purchase")方法获取
        ProcessInstance pi = runtimeService.startProcessInstanceByKey(processDefinitionKey, map);
        // 查询在当前流程实例下的唯一的一个任务,办理第一个任务
        // 以下代码实际并不需要,因为在自己的流程设计中,申请步骤是没有Task节点的,因此并不需要taskService.complete()以完成Task节点。
        // 实际上Task task = query.singleResult()为第一个Task,即审批的Task,而审批Task的Assignee为审批人,roleNumber为申请人
        // task.getAssignee().equals(roleNumber)肯定是false,taskService.complete也不会执行
        TaskQuery query = taskService.createTaskQuery();
        query.processInstanceId(pi.getId());
        Task task = query.singleResult();
        if(task.getAssignee()!=null&&task.getAssignee().equals(roleNumber)){
            taskService.complete(task.getId());
        }
    }
}

第二步:审批人查询任务

/**
 * 查询当前用户需要审批的任务,结果封装成一个TaskView(Task,Object),其中Object即为上一节点传递到此任务中的流程变量
 * 例如:在采购申请的审批中,流程变量为申请对象purchaseApply
 * 这样就可以查询到对应角色的Task了,接下来将此TaskView中的Object(这里为PurchaseApply)显示到页面
 * 在这之后的操作为:同意或拒绝审批(当然得建新的数据表),task.complete将任务走到下一个节点
 * @param user 这里传入的user应该是审批者
 * @return 查询当前用户需要审批的任务
 * @throws BaseServiceException
 */
public List findTaskViewList(User user) throws BaseServiceException {
    List taskViewList = new ArrayList();
    //根据用户的id来查询出他所属的角色
    UserAndRole userAndRole = new UserAndRole();
    userAndRole.setUserId(user.getId());
    List userAndRoleList = userAndRoleService.getEntity(userAndRole);
    if(!userAndRoleList.isEmpty()){
        UserAndRole userAndRole2 = userAndRoleList.get(0);
        // roleNumber为角色Id,与Task中的Assignee相同
        String roleNumber = String.valueOf(userAndRole2.getRoleId());
        TaskQuery query = taskService.createTaskQuery();
        //根据Assignee查找到对应的Task,Task中保存有上一节点传入的流程变量,在这里为申请表
        query.taskAssignee(roleNumber);
        query.orderByTaskCreateTime().desc();
        List list = query.list();
        // 第一个采购申请,会产生一个流程,同样也会有一个Task传入到审批人这里
        // 每个Task中的Assignee都为审批人的roleId,每个Task中的流程变量都为每次申请的申请表
        for (Task task : list) {
            String id = task.getId();
            PurchaseApply purchaseApply = (PurchaseApply) taskService.getVariable(id, "purchase");
            TaskView taskView = new TaskView(task, purchaseApply);
            taskViewList.add(taskView);
        }
    }
    return taskViewList;
}

第三步:对第二步获得的taskView中的Object(这里为上一task传过来的审批表)审批

你可能感兴趣的