提案承办单位转让不能按审核人所在单位人员查询,改为根据当前 WF 任务中负责人角色绑定的承办单位查询

This commit is contained in:
2026-09-15 14:33:06 +08:00
parent aa6a502b96
commit 5ffd2bbd96
6 changed files with 352 additions and 17 deletions
@@ -27,7 +27,6 @@ import org.nutz.dao.Cnd;
import org.nutz.dao.Dao; import org.nutz.dao.Dao;
import org.nutz.dao.Sqls; import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql; import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.aop.Aop; import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
@@ -230,21 +229,9 @@ public class ProposalUnderTakeReplyController {
@At @At
@SaCheckPermission("proposal.unitReply") @SaCheckPermission("proposal.unitReply")
@ApiOperation("查询本单位可转办用户") @ApiOperation("查询本单位可转办用户")
public Result selectViceUser(@Param("keyword") @Valid String keyword) { public Result selectViceUser(@Param("taskId") @Valid Long taskId,
Sql sql = Sqls.create("select id,loginname,username from vw_user $condition"); @Param("keyword") @Valid String keyword) {
Cnd cnd = Cnd.NEW(); return Result.success(proposalCommonService.queryTransferUsers(taskId, keyword));
cnd.andEX("unitId", "=", SecurityUtil.getUnitId());
cnd.andEX("id", "!=", SecurityUtil.getUserId());
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("username", keyword);
seg.orLike("loginname", keyword);
cnd.and(seg);
sql.setCondition(cnd);
sql.setParam("unitId", SecurityUtil.getUnitId());
sql.setParam("userId", SecurityUtil.getUserId());
Pagination pagination = proposalCommonService.listPageMap(1, 10, sql);
return Result.success(pagination.getList());
} }
@At @At
@@ -22,6 +22,15 @@ public interface ProposalCommonService extends BaseService<ProposalInfo> {
*/ */
ProposalReplyUnit getReplyUnitByTaskActorRole(String proposalId, Long taskId, String taskName); ProposalReplyUnit getReplyUnitByTaskActorRole(String proposalId, Long taskId, String taskName);
/**
* 查询当前 WF 承办答复任务可转交的本承办单位人员。
*
* @param taskId WF 流程任务 ID,任务必须处于待办理状态;系统根据任务办理人的承办角色确定单位
* @param keyword 姓名或工号搜索关键字,可为空
* @return 人员列表,每项包含 id、loginname、username,最多返回 10 条
*/
List<NutMap> queryTransferUsers(Long taskId, String keyword);
/** /**
* 查询提案信息 * 查询提案信息
*/ */
@@ -20,10 +20,12 @@ import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.flow.vo.ProcessTaskVO; import com.budwk.app.flow.vo.ProcessTaskVO;
import com.budwk.app.sys.models.Sys_dict; import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.models.Sys_role; import com.budwk.app.sys.models.Sys_role;
import com.budwk.app.sys.models.Sys_unit;
import com.budwk.app.sys.models.Sys_user; import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.models.Sys_user_role; import com.budwk.app.sys.models.Sys_user_role;
import com.budwk.app.sys.services.SysDictService; import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.sys.services.SysRoleService; import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.web.commons.base.Globals; import com.budwk.app.web.commons.base.Globals;
import com.budwk.app.zhgh.democratic.proposal.models.ProposalConsolidation; import com.budwk.app.zhgh.democratic.proposal.models.ProposalConsolidation;
@@ -43,6 +45,7 @@ import org.nutz.dao.FieldFilter;
import org.nutz.dao.Sqls; import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql; import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos; import org.nutz.dao.util.Daos;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.dao.util.cri.Static; import org.nutz.dao.util.cri.Static;
import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.ioc.loader.annotation.IocBean;
@@ -146,6 +149,57 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl<ProposalInfo> imp
return replyUnits.get(0); return replyUnits.get(0);
} }
/**
* 根据当前 WF 任务的承办角色单位查询可转交人员,避免负责人系统所属单位与承办单位不一致时串单位。
*/
@Override
public List<NutMap> queryTransferUsers(Long taskId, String keyword) {
if (taskId == null) {
throw new BaseException("流程任务不能为空");
}
ProcessTask task = dao().fetch(ProcessTask.class, taskId);
if (task == null || !Objects.equals(task.getTaskState(), ProcessTaskStateEnum.DOING.getCode())) {
throw new BaseException("当前任务不存在或已办理");
}
// 非超级管理员只能查询本人待办任务对应的承办单位人员。
if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) {
int actorCount = dao().count(ProcessTaskActor.class,
Cnd.where(ProcessTaskActor::getProcessTaskId, "=", taskId)
.and(ProcessTaskActor::getActorId, "=", SecurityUtil.getUserId()));
if (actorCount == 0) {
throw new BaseException("您不是当前任务办理人");
}
}
ProcessInstance instance = dao().fetch(ProcessInstance.class, task.getProcessInstanceId());
if (instance == null || StrUtil.isBlank(instance.getBusinessNo())) {
throw new BaseException("当前任务未关联提案");
}
ProposalReplyUnit replyUnit = getReplyUnitByTaskActorRole(
instance.getBusinessNo(), taskId, task.getTaskName());
String unitCode = StrUtil.blankToDefault(replyUnit.getUnitCode(), replyUnit.getUnitId());
Sys_unit systemUnit = dao().fetch(Sys_unit.class,
Cnd.where(Sys_unit::getUnitcode, "=", unitCode));
if (systemUnit == null) {
throw new BaseException("承办单位未匹配到系统单位,无法查询转交人员");
}
Sql sql = Sqls.create("select id, loginname, username from vw_user $condition");
Cnd cnd = Cnd.where("unitId", "=", systemUnit.getId())
.and("id", "!=", SecurityUtil.getUserId());
if (StrUtil.isNotBlank(keyword)) {
SqlExpressionGroup keywordGroup = new SqlExpressionGroup();
keywordGroup.orLike("username", keyword);
keywordGroup.orLike("loginname", keyword);
cnd.and(keywordGroup);
}
cnd.asc("loginname");
sql.setCondition(cnd);
return listPageMap(1, 10, sql).getList();
}
@Override @Override
public NutMap info(String id) { public NutMap info(String id) {
if (StrUtil.isBlank(id)) { if (StrUtil.isBlank(id)) {
@@ -0,0 +1,156 @@
-- 为当前届次提案流程补充遗漏的承办单位负责人待办任务。
-- 目标人员:医学院机关 石萍(070775)、体育学院 乔润华(067890)。
-- 处理范围:当前启用届次、JDHTA_NC 流程、仍处于待办理状态的承办单位答复任务。
-- 原任务办理人予以保留,NOT EXISTS 保证脚本可重复执行。
SET @now_ms := CAST(UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000 AS UNSIGNED);
-- 执行前校验:应返回两名有效用户,且角色承办单位分别为 4002 和 6200。
SELECT
target.account,
target.underTakeId,
target_user.id AS userId,
target_user.username,
undertake.name AS underTakeName,
leader_role.code AS roleCode
FROM (
SELECT '070775' AS account, '4002' AS underTakeId
UNION ALL
SELECT '067890' AS account, '6200' AS underTakeId
) target
INNER JOIN sys_user target_user
ON target_user.loginname = target.account
AND target_user.disabled = 0
AND target_user.delFlag = 0
INNER JOIN sys_role leader_role
ON leader_role.code = 'PROPOSAL_UNIT_LEADER'
INNER JOIN sys_user_role target_role
ON target_role.userId = target_user.id
AND target_role.roleId = leader_role.id
AND target_role.underTakeId = target.underTakeId
INNER JOIN proposal_undertake undertake
ON undertake.id = target_role.underTakeId
AND undertake.enable = 1
AND undertake.delFlag = 0
ORDER BY target.account;
START TRANSACTION;
-- 流程任务参与人在任务创建时固化;本次将当前负责人追加到本单位已有的活动任务中。
INSERT INTO wf_process_task_actor
(createdBy, createdAt, updatedBy, updatedAt, delFlag,
processTaskId, actorId, actorAccount, actorName, actorUnitName, actorUnitId)
SELECT
COALESCE(MIN(source_actor.createdBy), target_user.id) AS createdBy,
@now_ms AS createdAt,
COALESCE(MIN(source_actor.createdBy), target_user.id) AS updatedBy,
@now_ms AS updatedAt,
0 AS delFlag,
task.id AS processTaskId,
target_user.id AS actorId,
target_user.loginname AS actorAccount,
target_user.username AS actorName,
undertake.name AS actorUnitName,
undertake.id AS actorUnitId
FROM (
SELECT '070775' AS account, '4002' AS underTakeId
UNION ALL
SELECT '067890' AS account, '6200' AS underTakeId
) target
INNER JOIN sys_user target_user
ON target_user.loginname = target.account
AND target_user.disabled = 0
AND target_user.delFlag = 0
INNER JOIN sys_role leader_role
ON leader_role.code = 'PROPOSAL_UNIT_LEADER'
INNER JOIN sys_user_role target_role
ON target_role.userId = target_user.id
AND target_role.roleId = leader_role.id
AND target_role.underTakeId = target.underTakeId
INNER JOIN proposal_undertake undertake
ON undertake.id = target_role.underTakeId
AND undertake.enable = 1
AND undertake.delFlag = 0
INNER JOIN teacher_congress_session current_session
ON current_session.enable = 1
AND (current_session.delFlag = 0 OR current_session.delFlag IS NULL)
INNER JOIN proposal_info proposal
ON proposal.sessionId = current_session.id
AND proposal.delFlag = 0
INNER JOIN wf_process_instance instance
ON instance.businessNo = proposal.id
AND instance.delFlag = 0
INNER JOIN wf_process_define process_define
ON process_define.id = instance.processDefineId
AND process_define.name = 'JDHTA_NC'
AND process_define.delFlag = 0
INNER JOIN wf_process_task task
ON task.processInstanceId = instance.id
AND task.taskState = 10
AND task.delFlag = 0
AND task.taskName IN ('master_reply', 'opinion_master_reply', 'slave_reply')
INNER JOIN proposal_reply_unit reply_unit
ON reply_unit.proposalId = proposal.id
AND reply_unit.unitId = target.underTakeId
AND reply_unit.delFlag = 0
AND (
(task.taskName IN ('master_reply', 'opinion_master_reply') AND reply_unit.isMaster = 1)
OR (task.taskName = 'slave_reply' AND reply_unit.isMaster = 0)
)
INNER JOIN wf_process_task_actor source_actor
ON source_actor.processTaskId = task.id
AND source_actor.actorUnitId = target.underTakeId
AND source_actor.delFlag = 0
WHERE NOT EXISTS (
SELECT 1
FROM wf_process_task_actor existing_actor
WHERE existing_actor.processTaskId = task.id
AND existing_actor.actorId = target_user.id
AND existing_actor.delFlag = 0
)
GROUP BY
task.id,
target_user.id,
target_user.loginname,
target_user.username,
undertake.id,
undertake.name;
-- 当前开发环境预计为 5;线上以任务执行时的实际待办数量为准。
SELECT ROW_COUNT() AS insertedRows;
COMMIT;
-- 执行后核验:查看两名负责人当前届次下已获得的承办单位答复任务。
SELECT DISTINCT
actor.actorAccount,
actor.actorName,
actor.actorUnitName,
task.id AS taskId,
proposal.code AS proposalCode,
proposal.name AS proposalName,
task.displayName AS taskName
FROM wf_process_task_actor actor
INNER JOIN wf_process_task task
ON task.id = actor.processTaskId
AND task.taskState = 10
AND task.delFlag = 0
AND task.taskName IN ('master_reply', 'opinion_master_reply', 'slave_reply')
INNER JOIN wf_process_instance instance
ON instance.id = task.processInstanceId
AND instance.delFlag = 0
INNER JOIN wf_process_define process_define
ON process_define.id = instance.processDefineId
AND process_define.name = 'JDHTA_NC'
AND process_define.delFlag = 0
INNER JOIN proposal_info proposal
ON proposal.id = instance.businessNo
AND proposal.delFlag = 0
INNER JOIN teacher_congress_session current_session
ON current_session.id = proposal.sessionId
AND current_session.enable = 1
AND (current_session.delFlag = 0 OR current_session.delFlag IS NULL)
WHERE actor.actorAccount IN ('070775', '067890')
AND actor.actorUnitId IN ('4002', '6200')
AND actor.delFlag = 0
ORDER BY actor.actorAccount, task.id;
@@ -0,0 +1,126 @@
-- 为龚宁江(092108)补充研究生院(党委研究生工作部)的待办承办单位答复任务。
-- 适用范围:仅处理当前仍为待办理状态的主办、意见主办及协办单位答复任务。
-- 执行结果:保留任务原办理人,并追加龚宁江;使用 NOT EXISTS 保证脚本可重复执行。
SET @target_account := '092108';
SET @undertake_id := '2009';
SET @now_ms := CAST(UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000 AS UNSIGNED);
-- 执行前确认目标用户已绑定研究生院的提案承办单位领导角色。
SELECT
u.id AS userId,
u.loginname,
u.username,
pu.id AS underTakeId,
pu.name AS underTakeName,
r.code AS roleCode
FROM sys_user u
INNER JOIN sys_user_role ur ON ur.userId = u.id
INNER JOIN sys_role r ON r.id = ur.roleId
INNER JOIN proposal_undertake pu ON pu.id = ur.underTakeId
WHERE u.loginname = @target_account
AND u.disabled = 0
AND u.delFlag = 0
AND r.code = 'PROPOSAL_UNIT_LEADER'
AND ur.underTakeId = @undertake_id
AND pu.enable = 1
AND pu.delFlag = 0;
START TRANSACTION;
-- 流程任务创建后参与人不会随角色配置自动变化,因此为匹配承办单位的活动任务补充当前负责人。
INSERT INTO wf_process_task_actor
(createdBy, createdAt, updatedBy, updatedAt, delFlag,
processTaskId, actorId, actorAccount, actorName, actorUnitName, actorUnitId)
SELECT
COALESCE(MIN(source_actor.createdBy), target_user.id) AS createdBy,
@now_ms AS createdAt,
COALESCE(MIN(source_actor.createdBy), target_user.id) AS updatedBy,
@now_ms AS updatedAt,
0 AS delFlag,
task.id AS processTaskId,
target_user.id AS actorId,
target_user.loginname AS actorAccount,
target_user.username AS actorName,
undertake.name AS actorUnitName,
undertake.id AS actorUnitId
FROM wf_process_task task
INNER JOIN wf_process_instance instance
ON instance.id = task.processInstanceId
AND instance.delFlag = 0
INNER JOIN proposal_info proposal
ON proposal.id = instance.businessNo
AND proposal.delFlag = 0
INNER JOIN proposal_reply_unit reply_unit
ON reply_unit.proposalId = proposal.id
AND reply_unit.unitId = @undertake_id
AND reply_unit.delFlag = 0
AND (
(task.taskName IN ('master_reply', 'opinion_master_reply') AND reply_unit.isMaster = 1)
OR (task.taskName = 'slave_reply' AND reply_unit.isMaster = 0)
)
INNER JOIN wf_process_task_actor source_actor
ON source_actor.processTaskId = task.id
AND source_actor.actorUnitId = @undertake_id
AND source_actor.delFlag = 0
INNER JOIN sys_user target_user
ON target_user.loginname = @target_account
AND target_user.disabled = 0
AND target_user.delFlag = 0
INNER JOIN sys_role leader_role
ON leader_role.code = 'PROPOSAL_UNIT_LEADER'
INNER JOIN sys_user_role target_role
ON target_role.userId = target_user.id
AND target_role.roleId = leader_role.id
AND target_role.underTakeId = @undertake_id
INNER JOIN proposal_undertake undertake
ON undertake.id = target_role.underTakeId
AND undertake.enable = 1
AND undertake.delFlag = 0
WHERE task.taskState = 10
AND task.delFlag = 0
AND task.taskName IN ('master_reply', 'opinion_master_reply', 'slave_reply')
AND NOT EXISTS (
SELECT 1
FROM wf_process_task_actor existing_actor
WHERE existing_actor.processTaskId = task.id
AND existing_actor.actorId = target_user.id
AND existing_actor.delFlag = 0
)
GROUP BY
task.id,
target_user.id,
target_user.loginname,
target_user.username,
undertake.id,
undertake.name;
SELECT ROW_COUNT() AS insertedRows;
COMMIT;
-- 执行后核验:应返回龚宁江当前可以查看、办理的研究生院承办答复任务。
SELECT DISTINCT
task.id AS taskId,
proposal.code AS proposalCode,
proposal.name AS proposalName,
task.displayName AS taskName,
actor.actorAccount,
actor.actorName,
actor.actorUnitName
FROM wf_process_task_actor actor
INNER JOIN wf_process_task task
ON task.id = actor.processTaskId
AND task.taskState = 10
AND task.delFlag = 0
INNER JOIN wf_process_instance instance
ON instance.id = task.processInstanceId
AND instance.delFlag = 0
INNER JOIN proposal_info proposal
ON proposal.id = instance.businessNo
AND proposal.delFlag = 0
WHERE actor.actorAccount = @target_account
AND actor.actorUnitId = @undertake_id
AND actor.delFlag = 0
AND task.taskName IN ('master_reply', 'opinion_master_reply', 'slave_reply')
ORDER BY task.id;
@@ -406,7 +406,10 @@ layout("/layouts/platform.html"){
// 查询转办用户 // 查询转办用户
selectTransferUser(keyword) { selectTransferUser(keyword) {
this.$axios.post("/platform/proposal/unitReply/selectViceUser", {keyword}).then(res => { this.$axios.post("/platform/proposal/unitReply/selectViceUser", {
taskId: this.transferForm.taskId,
keyword
}).then(res => {
if (res.code === 0) { if (res.code === 0) {
this.transferUserOptions = res.data this.transferUserOptions = res.data
} }