Activiti6在Springboot下的使用 7 自定義用戶分組

說明

一般在流程中也會存在指定一個組去完成某項事情,然後組裏的某一個人就會去完成該事項。在Activiti6裏還存在用戶和組的表(act_id_user和act_id_group)所以可以直接用,但在Activiti7裏用戶和組表就被刪了,官方建議我們自己創建組表並維護ヽ(ー_ー)ノ(確實用戶表、組表功能比較複雜,默認提供的功能可能不夠,還是自己創建的好)

快速開始

下面是我創建的用戶表和組表,以及產生的中間表(表比較簡單 不解釋了)

@Data
@Table(name = "user")
public class UserEntity {
    @Id
    private String userId;
    private String password;
    private String email;
}
@Data
@Table(name = "group_table")
public class GroupEntity {
    @Id
    private String id;
    private String name;
    private String description;
    private Date date;
    private String createUserId;
    private Integer status;
}
@Data
@Table(name = "user_group")
public class UserGroupEntity {
    private String id;
    private String userId;
    private String groupId;
    private String type;
}

流程圖假設長成下面的樣子

xml文件如下,主要是設置了candidateGroups屬性(組id),如果是直接指定人完成的話是assignee屬性,注意區分

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"  exporter="Activiti Modeler" exporterVersion="3.2.3">
  <bpmn:process id="Process_0h11oif" name="用戶組任務" isExecutable="true">
    <bpmn:startEvent id="StartEvent_1" name="Start">
      <bpmn:outgoing>SequenceFlow_1mfomlj</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:sequenceFlow id="SequenceFlow_1mfomlj" sourceRef="StartEvent_1" targetRef="Task_1odu8rn" />
    <bpmn:userTask id="Task_1odu8rn" name="用戶填寫申請" activiti:assignee="aaa">
      <bpmn:incoming>SequenceFlow_1mfomlj</bpmn:incoming>
      <bpmn:outgoing>SequenceFlow_017jj1v</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:userTask id="Task_0j8yxz2" name="group1用戶組操作" activiti:candidateGroups="8513a9e1-c327-11e9-ab1a-b0d59dfd767c">
      <bpmn:incoming>SequenceFlow_017jj1v</bpmn:incoming>
      <bpmn:incoming>SequenceFlow_1hxqo8k</bpmn:incoming>
      <bpmn:outgoing>SequenceFlow_1l4defy</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:sequenceFlow id="SequenceFlow_017jj1v" sourceRef="Task_1odu8rn" targetRef="Task_0j8yxz2" />
    <bpmn:sequenceFlow id="SequenceFlow_1l4defy" sourceRef="Task_0j8yxz2" targetRef="Task_1feu71t" />
    <bpmn:userTask id="Task_1feu71t" name="group2用戶組操作" activiti:candidateGroups="7213a961-df27-11w9-ab1a-b6d59dcd767c">
      <bpmn:incoming>SequenceFlow_1l4defy</bpmn:incoming>
      <bpmn:outgoing>SequenceFlow_07zhfop</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:endEvent id="EndEvent_06eelpv" name="End">
      <bpmn:incoming>SequenceFlow_0uxuouo</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="SequenceFlow_07zhfop" sourceRef="Task_1feu71t" targetRef="ExclusiveGateway_1ysk9j6" />
    <bpmn:exclusiveGateway id="ExclusiveGateway_1ysk9j6">
      <bpmn:incoming>SequenceFlow_07zhfop</bpmn:incoming>
      <bpmn:outgoing>SequenceFlow_0uxuouo</bpmn:outgoing>
      <bpmn:outgoing>SequenceFlow_1hxqo8k</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:sequenceFlow id="SequenceFlow_0uxuouo" name="同意" sourceRef="ExclusiveGateway_1ysk9j6" targetRef="EndEvent_06eelpv">
      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${status==1}</bpmn:conditionExpression>
    </bpmn:sequenceFlow>
    <bpmn:sequenceFlow id="SequenceFlow_1hxqo8k" name="駁回" sourceRef="ExclusiveGateway_1ysk9j6" targetRef="Task_0j8yxz2">
      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${status!=1}</bpmn:conditionExpression>
    </bpmn:sequenceFlow>
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0h11oif">
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
        <dc:Bounds x="152" y="172" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="158" y="215" width="25" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="SequenceFlow_1mfomlj_di" bpmnElement="SequenceFlow_1mfomlj">
        <di:waypoint x="188" y="190" />
        <di:waypoint x="240" y="190" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="UserTask_04js4mv_di" bpmnElement="Task_1odu8rn">
        <dc:Bounds x="240" y="150" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="UserTask_03hgfko_di" bpmnElement="Task_0j8yxz2">
        <dc:Bounds x="430" y="150" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="SequenceFlow_017jj1v_di" bpmnElement="SequenceFlow_017jj1v">
        <di:waypoint x="340" y="190" />
        <di:waypoint x="430" y="190" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="SequenceFlow_1l4defy_di" bpmnElement="SequenceFlow_1l4defy">
        <di:waypoint x="530" y="190" />
        <di:waypoint x="620" y="190" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="UserTask_15gy7q6_di" bpmnElement="Task_1feu71t">
        <dc:Bounds x="620" y="150" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="EndEvent_06eelpv_di" bpmnElement="EndEvent_06eelpv">
        <dc:Bounds x="922" y="172" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="930" y="215" width="20" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="SequenceFlow_07zhfop_di" bpmnElement="SequenceFlow_07zhfop">
        <di:waypoint x="720" y="190" />
        <di:waypoint x="795" y="190" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="ExclusiveGateway_1ysk9j6_di" bpmnElement="ExclusiveGateway_1ysk9j6" isMarkerVisible="true">
        <dc:Bounds x="795" y="165" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="SequenceFlow_0uxuouo_di" bpmnElement="SequenceFlow_0uxuouo">
        <di:waypoint x="845" y="190" />
        <di:waypoint x="922" y="190" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="873" y="172" width="22" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="SequenceFlow_1hxqo8k_di" bpmnElement="SequenceFlow_1hxqo8k">
        <di:waypoint x="820" y="190" />
        <di:waypoint x="820" y="100" />
        <di:waypoint x="480" y="100" />
        <di:waypoint x="480" y="150" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="639" y="82" width="22" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>

假設前端需要根據用戶名選出其待辦事項(用戶所在組也包括)比如用戶名叫aaa

那麼SQL可以這麼寫apply爲申請表信息記錄表(指定的用戶爲aaa或是aaa所在的組裏有任務)

	<select id="findTaskByUserId" parameterType="String">
        SELECT a.PROC_DEF_ID_ as proId, a.PROC_INST_ID_ as proInstanceId,a.ID_ as taskId,a.NAME_ as taskName, a.ASSIGNEE_ as userName, ap.api,ap.user_id as userId,ap.create_date as createDate, ap.id, arp.NAME_ as proName, ari.GROUP_ID_ as groupId, gt.name as groupName, CASE WHEN ari.GROUP_ID_ IS NULL then 0 else 1 end as isGroup
    	FROM act_ru_task a
		LEFT JOIN apply ap
		ON a.PROC_INST_ID_=ap.pro_instance_id
		LEFT JOIN act_re_procdef arp
		ON a.PROC_DEF_ID_=arp.ID_
		LEFT JOIN act_ru_identitylink ari
		ON a.ID_=ari.TASK_ID_
		LEFT JOIN group_table gt
		ON ari.GROUP_ID_=gt.id
		WHERE a.ASSIGNEE_ LIKE CONCAT('%','aaa','%') OR ari.GROUP_ID_ in
			(SELECT gt.id
			from user_group ug
			LEFT JOIN group_table gt
			on ug.group_id=gt.id
			WHERE ug.user_id='aaa')
		ORDER BY ap.create_date
	</select>

編寫complete方法的時候,可以設置具體是誰完成了這個組任務(CandidateUser)便於以後查看歷史,例如:

@Autowired
private TaskService taskService;

public BaseDTO complete(Task task, Integer status, Map<String, String> map) {
        System.out.println("組的service");
        /**
         * 用戶邏輯寫在這
         */
        HashMap<String, Object> variables = new HashMap<>();
        // 分支條件判斷 駁回或同意
        variables.put("status", status);
        setAssigneeOrCandidateUser(taskService, task, map.get("userId"));
        taskService.complete(task.getId(), variables);
        return null;
    }

private void setAssigneeOrCandidateUser(TaskService taskService, Task task, String userId) {
        // 設置執行人
        List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(task.getId());
        for (IdentityLink i : identityLinksForTask) {
            // 判斷是組任務還是個人任務
            if (null == i.getGroupId() || i.getGroupId().equals(""))
                task.setAssignee(userId);
            else
                taskService.addCandidateUser(task.getId(), userId);
        }
    }

到這裏activiti的流程算是走的差不多了(*^▽^*),挖坑結束,有新坑我再補充

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章