前言
Activiti 自身提供了一套用戶管理,但是在開發中業務系統本身就有一套用戶管理系統,這時候就要把業務系統中的部分用戶數據同步到 Activiti 用戶表管理中。那麼,如果不同步呢?不少開發者一開始以爲必須要有用戶纔可以運行,其實 Task 的 Assignee,Candidate Users,Candidate Groups 信息已經以字符串形式保存在 act_ru_tak 和 ACT_RU_IDENTITYLINK 表中。只有少部分的查詢 API 會用到 ACT_ID_* 表中的數據進行關聯查詢。
環境
軟件 | 版本 |
---|---|
SpringBoot | 1.5.10 |
activiti-spring-boot-starter-basic | 6.0 |
查詢
taskAssignee
按照指派人查詢,直接查詢表 ACT_RU_TASK。
API:
taskService.createTaskQuery().taskAssignee(userId);
SQL:
select distinct RES.* from ACT_RU_TASK RES WHERE RES.ASSIGNEE_ = ?
taskCandidateGroup
按照分配組查詢,沒有用到 ACT_ID_* 表的數據。
API:
taskService.createTaskQuery().taskCandidateGroup("部門經理");
SQL:
SELECT DISTINCT
RES.*
FROM ACT_RU_TASK RES
INNER JOIN ACT_RU_IDENTITYLINK I
ON I.TASK_ID_ = RES.ID_
WHERE RES.ASSIGNEE_ IS NULL
AND I.TYPE_ = 'candidate'
AND (I.GROUP_ID_ IN(?))
taskCandidateGroupIn
按照分配組查詢,沒有用到 ACT_ID_*表的數據。
API:
List<String> candidateGroups = new ArrayList<String>();
candidateGroups.add("部門經理");
candidateGroups.add("總裁");
taskService.createTaskQuery().taskCandidateGroupIn (candidateGroups);
SQL:
SELECT DISTINCT
RES.*
FROM ACT_RU_TASK RES
INNER JOIN ACT_RU_IDENTITYLINK I
ON I.TASK_ID_ = RES.ID_
WHERE RES.ASSIGNEE_ IS NULL
AND I.TYPE_ = 'candidate'
AND (I.GROUP_ID_ IN(?))
taskCandidateOrAssigned
按照分配組 OR 指派人查詢,用到了 ACT_ID_*表的數據,傳入userId查詢其所在權限組。
API:
taskService.createTaskQuery().taskCandidateOrAssigned(userId);
SQL:
首先查詢用戶所在組權限
SELECT
g.*
FROM ACT_ID_GROUP g,
ACT_ID_MEMBERSHIP membership
WHERE g.ID_ = membership.GROUP_ID_
AND membership.USER_ID_ = ?
然後查詢指派人任務或者指派人爲空並且用戶所在權限組的任務
SELECT DISTINCT
RES.*
FROM ACT_RU_TASK RES
LEFT JOIN ACT_RU_IDENTITYLINK I
ON I.TASK_ID_ = RES.ID_
WHERE (RES.ASSIGNEE_ = ?
OR (RES.ASSIGNEE_ IS NULL
AND (I.USER_ID_ = ?
OR I.GROUP_ID_ IN(SELECT
g.GROUP_ID_
FROM ACT_ID_MEMBERSHIP g
WHERE g.USER_ID_ = ?))))
taskCandidateUser
API:
taskService.createTaskQuery().taskCandidateUser(userId);
- 先查找用戶所屬的組(用戶所屬用戶組的信息從 Activiti 的 ACT_ID_*表獲取)
SELECT
g.*
FROM ACT_ID_GROUP g,
ACT_ID_MEMBERSHIP membership
WHERE g.ID_ = membership.GROUP_ID_
AND membership.USER_ID_ = ?
- 如果找到了用戶組信息
SELECT DISTINCT
RES.*
FROM ACT_RU_TASK RES
INNER JOIN ACT_RU_IDENTITYLINK I
ON I.TASK_ID_ = RES.ID_
WHERE RES.ASSIGNEE_ IS NULL
AND I.TYPE_ = 'candidate'
AND (I.USER_ID_ = ?
OR I.GROUP_ID_ IN(?))
- 如果找不到用戶所屬的組
SELECT DISTINCT
RES.*
FROM ACT_RU_TASK RES
INNER JOIN ACT_RU_IDENTITYLINK I
ON I.TASK_ID_ = RES.ID_
WHERE RES.ASSIGNEE_ IS NULL
AND I.TYPE_ = 'candidate'
AND (I.USER_ID_ = ?)
按照所屬人查詢 taskOwner
API:
taskService.createTaskQuery().taskOwner(userId);
SQL:
SELECT DISTINCT
RES.*
FROM ACT_RU_TASK RES
WHERE RES.OWNER_ = ?
日誌
在 logback.xml 追加以下配置,就可以輸出 Activiti 查詢語句。
<!-- Activiti日誌 -->
<logger name="org.activiti" level="INFO" />
<logger name="org.activiti.engine.impl.persistence.entity" level="DEBUG" />
說明
有些查詢使用到 Activiti 自帶的用戶信息的,比如 taskCandidateOrAssigned,如果項目中使用了自己的權限系統,這些 API 是不靈光的,這裏提供三種方案,僅供參考:
-
同步系統用戶權限信息到 Activiti 自帶用戶組,不推薦。
-
修改源代碼 Task.xml 中的查詢SQL,把 Activiti 自帶的用戶表替換成業務系統用戶表,不推薦。
-
用視圖覆蓋同名的ACT_ID_系列表,創建的視圖要保證數據類型,推薦。