commit
This commit is contained in:
@@ -134,6 +134,15 @@ public interface ProcessTaskService extends BaseService<ProcessTask> {
|
||||
*/
|
||||
void removeTaskActor(Long processTaskId, List<String> actors);
|
||||
|
||||
/**
|
||||
* 按最新办理人配置覆盖同步指定流程任务的参与者。
|
||||
*
|
||||
* @param processTaskId 流程任务id
|
||||
* @param actors 最新办理人用户id集合;为空时不处理,避免误清空任务办理人
|
||||
* @return 新增和移除的参与者数量合计
|
||||
*/
|
||||
int syncTaskActors(Long processTaskId, List<String> actors);
|
||||
|
||||
/**
|
||||
* 根据taskId、operator,判断操作人operator是否允许执行任务
|
||||
*
|
||||
|
||||
@@ -279,6 +279,31 @@ public class ProcessTaskServiceImpl extends BaseServiceImpl<ProcessTask> impleme
|
||||
dao().clear(ProcessTaskActor.class, Cnd.where(ProcessTaskActor::getProcessTaskId, "=", processTaskId).and(ProcessTaskActor::getActorId, "in", actors));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public int syncTaskActors(Long processTaskId, List<String> actors) {
|
||||
if (CollectionUtil.isEmpty(actors)) {
|
||||
return 0;
|
||||
}
|
||||
List<String> latestActors = actors.stream().filter(StrUtil::isNotBlank).distinct().toList();
|
||||
if (CollectionUtil.isEmpty(latestActors)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 以最新负责人配置为准:缺失的办理人补上,不再是负责人的办理人移除。
|
||||
List<String> dbActors = getTaskActors(processTaskId);
|
||||
List<String> addActors = latestActors.stream().filter(actor -> !dbActors.contains(actor)).toList();
|
||||
List<String> removeActors = dbActors.stream().filter(actor -> !latestActors.contains(actor)).toList();
|
||||
|
||||
if (CollectionUtil.isNotEmpty(removeActors)) {
|
||||
removeTaskActor(processTaskId, removeActors);
|
||||
}
|
||||
if (CollectionUtil.isNotEmpty(addActors)) {
|
||||
addTaskActor(processTaskId, addActors);
|
||||
}
|
||||
return addActors.size() + removeActors.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowed(ProcessTask task, String operator) {
|
||||
// 执行者为超级管理员或自动执行用户
|
||||
|
||||
+81
@@ -13,6 +13,9 @@ import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.flow.entity.ProcessTask;
|
||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||
import com.budwk.app.flow.service.ProcessTaskService;
|
||||
import com.budwk.app.sys.models.Sys_role;
|
||||
import com.budwk.app.sys.models.Sys_unit;
|
||||
import com.budwk.app.sys.models.Sys_user_role;
|
||||
@@ -57,6 +60,8 @@ public class ProposalConfigUnitController {
|
||||
private BaseService baseService;
|
||||
@Inject
|
||||
private SysRoleService sysRoleService;
|
||||
@Inject
|
||||
private ProcessTaskService processTaskService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/zhgh/democratic/proposal/config/unit/index.html")
|
||||
@@ -146,6 +151,82 @@ public class ProposalConfigUnitController {
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步当前进行中的承办单位答复任务办理人。
|
||||
*
|
||||
* 按承办单位当前配置的单位负责人覆盖同步 wf_process_task_actor:
|
||||
* 1. 参数:无参数,系统自动扫描所有启用承办单位。
|
||||
* 2. 单位负责人来源:PROPOSAL_UNIT_LEADER 角色且 underTakeId 等于承办单位id。
|
||||
* 3. 同步范围:当前进行中的主办答复、协办答复、意见主办答复任务。
|
||||
* 4. 返回值:Result,msg 中说明同步任务数、办理人变更数、未配置负责人单位数。
|
||||
*/
|
||||
@At
|
||||
@SaCheckPermission("proposal.config.unit")
|
||||
@SLog(tag = "提案", msg = "同步承办单位答复人")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public Result syncUnitReplyActors() {
|
||||
Sys_role sysRole = sysRoleService.getByCode(RoleConstant.PROPOSAL_UNIT_LEADER);
|
||||
List<ProposalUndertake> undertakes = dao.query(ProposalUndertake.class, Cnd.where(ProposalUndertake::getEnable, "=", true));
|
||||
int scanTaskCount = 0;
|
||||
int syncTaskCount = 0;
|
||||
int syncActorCount = 0;
|
||||
int skipUnitCount = 0;
|
||||
|
||||
for (ProposalUndertake undertake : undertakes) {
|
||||
List<Sys_user_role> sysUserRoles = dao.query(Sys_user_role.class, Cnd.where(Sys_user_role::getRoleId, "=", sysRole.getId())
|
||||
.and(Sys_user_role::getUnderTakeId, "=", undertake.getId()));
|
||||
List<String> userIds = sysUserRoles.stream().map(Sys_user_role::getUserId).distinct().toList();
|
||||
if (CollectionUtil.isEmpty(userIds)) {
|
||||
skipUnitCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
List<ProcessTask> tasks = queryDoingUnitReplyTasks(undertake.getId());
|
||||
scanTaskCount += tasks.size();
|
||||
for (ProcessTask task : tasks) {
|
||||
int syncCount = processTaskService.syncTaskActors(task.getId(), userIds);
|
||||
if (syncCount > 0) {
|
||||
syncTaskCount++;
|
||||
syncActorCount += syncCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Result.success("同步完成,扫描任务" + scanTaskCount + "个,更新任务" + syncTaskCount + "个,办理人变更" + syncActorCount + "人次,跳过未配置负责人单位" + skipUnitCount + "个。");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据承办单位和提案承办单位记录查询正在办理中的答复任务。
|
||||
*
|
||||
* 说明:
|
||||
* 1. 参数 underTakeId 为 proposal_undertake.id,即当前承办单位配置ID。
|
||||
* 2. 不依赖 wf_process_task.variable 中的 underTakeId,避免历史任务变量和承办单位配置不一致导致漏同步。
|
||||
* 3. 主办单位只匹配 master_reply、opinion_master_reply,协办单位只匹配 slave_reply。
|
||||
* 4. 返回值为当前仍在办理中的流程任务列表。
|
||||
*/
|
||||
private List<ProcessTask> queryDoingUnitReplyTasks(String underTakeId) {
|
||||
Sql sql = Sqls.queryEntity("""
|
||||
SELECT DISTINCT
|
||||
t.*
|
||||
FROM
|
||||
wf_process_task t
|
||||
INNER JOIN wf_process_instance ins ON ins.id = t.processInstanceId
|
||||
INNER JOIN proposal_reply_unit pru ON pru.proposalId = ins.businessNo
|
||||
AND pru.unitId = @underTakeId
|
||||
WHERE
|
||||
t.taskState = @taskState
|
||||
AND (
|
||||
(t.taskName IN ('master_reply', 'opinion_master_reply') AND pru.isMaster = 1)
|
||||
OR (t.taskName = 'slave_reply' AND pru.isMaster = 0)
|
||||
)
|
||||
""");
|
||||
sql.setParam("underTakeId", underTakeId);
|
||||
sql.setParam("taskState", ProcessTaskStateEnum.DOING.getCode());
|
||||
sql.setEntity(dao.getEntity(ProcessTask.class));
|
||||
dao.execute(sql);
|
||||
return sql.getList(ProcessTask.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置分管校领导
|
||||
*
|
||||
|
||||
+8
-3
@@ -101,8 +101,8 @@ public class ProposalUnderTakeReplyController {
|
||||
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
|
||||
IFNULL(GROUP_CONCAT(DISTINCT nt.taskName),'结束') curTaskKey,
|
||||
CASE WHEN t.taskState = 20 AND ( rt.id IS NULL OR rt.taskState = 10 ) THEN 1 ELSE 0 END AS canRevoke,
|
||||
t.variable->>'$.underTakeName' AS underTakeName,
|
||||
IF(JSON_EXTRACT(t.variable, '$.underTakeIsMaster') = true, 1, 0) AS underTakeIsMaster,
|
||||
IFNULL(pru.unitName, t.variable->>'$.underTakeName') AS underTakeName,
|
||||
IFNULL(pru.isMaster, IF(JSON_EXTRACT(t.variable, '$.underTakeIsMaster') = true, 1, 0)) AS underTakeIsMaster,
|
||||
t.variable->>'$.tf_transferUserId' AS tf_transferUserId,
|
||||
transferUser.username AS transferUserName
|
||||
FROM
|
||||
@@ -114,6 +114,11 @@ public class ProposalUnderTakeReplyController {
|
||||
LEFT JOIN proposal_info info ON info.id = ins.businessNo
|
||||
LEFT JOIN proposal_type type on type.id = info.typeId
|
||||
LEFT JOIN proposal_merge mer ON mer.proposalId = info.id
|
||||
LEFT JOIN proposal_reply_unit pru ON pru.proposalId = ins.businessNo
|
||||
AND (
|
||||
(t.taskName IN ('master_reply', 'opinion_master_reply') AND pru.isMaster = 1)
|
||||
OR (t.taskName = 'slave_reply' AND pru.isMaster = 0)
|
||||
)
|
||||
LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId
|
||||
LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId
|
||||
LEFT JOIN sys_user transferUser on transferUser.id = t.variable->>'$.tf_transferUserId'
|
||||
@@ -132,7 +137,7 @@ public class ProposalUnderTakeReplyController {
|
||||
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
|
||||
}
|
||||
ProposalSearchParam.buildSearch(cnd, pageForm);
|
||||
cnd.groupBy("t.id");
|
||||
cnd.groupBy("t.id", "pru.unitId", "pru.unitName", "pru.isMaster");
|
||||
cnd.desc("t.createdAt");
|
||||
sql.setCondition(cnd);
|
||||
Pagination pagination = proposalCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
|
||||
@@ -22,6 +22,7 @@ layout("/layouts/platform.html"){
|
||||
<el-card shadow="never" style="border: 1px solid var(--border-color-lighter);flex: 1;" :body-style="{ height: '100%', display: 'flex' , 'flex-direction': 'column' }">
|
||||
<table-tool>
|
||||
<el-button type="primary" size="small" icon="el-icon-refresh" @click="syncSysUnit">同步系统单位</el-button>
|
||||
<el-button type="primary" size="small" icon="el-icon-refresh" :loading="syncUnitReplyActorsLoading" @click="syncUnitReplyActors">同步承办单位答复人</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" border ref="tableRef" height="100%">
|
||||
<el-table-column label="序号" type="index" :index="indexMethod" width="60"></el-table-column>
|
||||
@@ -69,7 +70,8 @@ layout("/layouts/platform.html"){
|
||||
data() {
|
||||
return {
|
||||
currentTreeNode: null,
|
||||
currentTreeData: null
|
||||
currentTreeData: null,
|
||||
syncUnitReplyActorsLoading: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -85,6 +87,23 @@ layout("/layouts/platform.html"){
|
||||
this.$refs.treeRef.listTree()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
syncUnitReplyActors() {
|
||||
this.$confirm("确定要按当前单位领导配置同步进行中的承办单位答复待办吗?", "提示", {
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.syncUnitReplyActorsLoading = true
|
||||
this.$axios.post(loc() + "/syncUnitReplyActors")
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.syncUnitReplyActorsLoading = false
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
Reference in New Issue
Block a user