From a67f80bec93771ebc0f344a6e1d82edeb9b2735c Mon Sep 17 00:00:00 2001 From: zhangrui Date: Thu, 10 Sep 2026 15:39:09 +0800 Subject: [PATCH] change --- .../ProposalUnderTakeReplyController.java | 1 + .../ProposalCaseFilingInterceptor.java | 13 ++-- .../ProposalUnderTakeInfoInterceptor.java | 44 ++++++++---- .../ProposalCaseTaskRevokeEventListener.java | 13 ++++ .../service/common/ProposalCommonService.java | 11 +++ .../common/ProposalCommonServiceImpl.java | 72 +++++++++++++++++++ 6 files changed, 132 insertions(+), 22 deletions(-) diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalUnderTakeReplyController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalUnderTakeReplyController.java index 97f6b8b1..546ff4b3 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalUnderTakeReplyController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalUnderTakeReplyController.java @@ -201,6 +201,7 @@ public class ProposalUnderTakeReplyController { @At @SaCheckPermission("proposal.unitReply") @ApiOperation("执行任务") + @Aop(TransAop.READ_COMMITTED) public Result executeTask(@Param("data") String data) { Dict args = Json.fromJson(Dict.class, data); String proposalId = args.getStr("proposalId"); diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/interceptor/ProposalCaseFilingInterceptor.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/interceptor/ProposalCaseFilingInterceptor.java index d1b0ab03..b32c10ca 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/interceptor/ProposalCaseFilingInterceptor.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/interceptor/ProposalCaseFilingInterceptor.java @@ -3,7 +3,6 @@ package com.budwk.app.zhgh.democratic.proposal.interceptor; import cn.hutool.core.lang.Dict; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; -import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.flow.constant.FlowConst; import com.budwk.app.flow.engine.FlowInterceptor; import com.budwk.app.flow.engine.core.Execution; @@ -11,19 +10,16 @@ import com.budwk.app.flow.engine.core.ServiceContext; import com.budwk.app.flow.engine.util.FlowUtil; import com.budwk.app.flow.entity.ProcessInstance; import com.budwk.app.flow.entity.ProcessTask; -import com.budwk.app.flow.entity.ProcessTaskActor; -import com.budwk.app.sys.models.Sys_role; -import com.budwk.app.sys.services.SysRoleService; import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; import com.budwk.app.zhgh.democratic.proposal.models.ProposalReplyUnit; import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake; +import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService; import org.nutz.aop.interceptor.ioc.TransAop; import org.nutz.dao.Chain; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; import org.nutz.ioc.aop.Aop; import org.nutz.json.Json; -import org.nutz.lang.util.NutMap; import java.util.List; @@ -36,6 +32,7 @@ public class ProposalCaseFilingInterceptor implements FlowInterceptor { @Aop(TransAop.READ_COMMITTED) public void intercept(Execution execution) { Dao dao = ServiceContext.find(Dao.class); + ProposalCommonService proposalCommonService = ServiceContext.find(ProposalCommonService.class); // 提案ID String proposalId = execution.getProcessInstance().getBusinessNo(); @@ -87,10 +84,8 @@ public class ProposalCaseFilingInterceptor implements FlowInterceptor { List processTaskList = execution.getProcessTaskList(); for (ProcessTask task : processTaskList) { - // 办理人 - ProcessTaskActor taskActor = dao.fetch(ProcessTaskActor.class, Cnd.where(ProcessTaskActor::getProcessTaskId, "=", task.getId())); - String actorUnitId = taskActor.getActorUnitId(); - ProposalReplyUnit replyUnit = dao.fetch(ProposalReplyUnit.class, Cnd.where(ProposalReplyUnit::getProposalId, "=", proposalId).and(ProposalReplyUnit::getUnitId, "=", actorUnitId)); + // 按办理人的角色承办单位匹配,系统所属单位可能与提案承办单位不同。 + ProposalReplyUnit replyUnit = proposalCommonService.getReplyUnitByTaskActorRole(proposalId, task.getId(), task.getTaskName()); Dict variable = FlowUtil.variableToDict(task.getVariable()); variable.set("underTakeName", replyUnit.getUnitName()); diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/interceptor/ProposalUnderTakeInfoInterceptor.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/interceptor/ProposalUnderTakeInfoInterceptor.java index 510d6f53..f9f8a703 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/interceptor/ProposalUnderTakeInfoInterceptor.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/interceptor/ProposalUnderTakeInfoInterceptor.java @@ -6,10 +6,11 @@ import com.budwk.app.flow.engine.core.Execution; import com.budwk.app.flow.engine.core.ServiceContext; import com.budwk.app.flow.engine.util.FlowUtil; import com.budwk.app.flow.entity.ProcessTask; -import com.budwk.app.flow.entity.ProcessTaskActor; import com.budwk.app.zhgh.democratic.proposal.models.ProposalReplyUnit; -import org.nutz.dao.Cnd; +import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService; +import org.nutz.aop.interceptor.ioc.TransAop; import org.nutz.dao.Dao; +import org.nutz.ioc.aop.Aop; import org.nutz.json.Json; import java.util.List; @@ -20,26 +21,43 @@ import java.util.List; */ public class ProposalUnderTakeInfoInterceptor implements FlowInterceptor { @Override + @Aop(TransAop.READ_COMMITTED) public void intercept(Execution execution) { Dao dao = ServiceContext.find(Dao.class); + ProposalCommonService proposalCommonService = ServiceContext.find(ProposalCommonService.class); // 提案ID String proposalId = execution.getProcessInstance().getBusinessNo(); - // 当前任务 + // 创建后续任务时 execution.processTask 会被替换,processTaskId 才始终指向本次办结的原任务。 + ProcessTask finishedTask = dao.fetch(ProcessTask.class, execution.getProcessTaskId()); + if (finishedTask != null && "slave_reply".equals(finishedTask.getTaskName())) { + setReplyUnitVariable(proposalCommonService, proposalId, finishedTask); + dao.update(finishedTask, "variable"); + } + + // 为本次流转新生成的主办答复任务设置承办单位。 List processTaskList = execution.getProcessTaskList(); for (ProcessTask task : processTaskList) { - // 办理人 - ProcessTaskActor taskActor = dao.fetch(ProcessTaskActor.class, Cnd.where(ProcessTaskActor::getProcessTaskId, "=", task.getId())); - String actorUnitId = taskActor.getActorUnitId(); - ProposalReplyUnit replyUnit = dao.fetch(ProposalReplyUnit.class, Cnd.where(ProposalReplyUnit::getProposalId, "=", proposalId).and(ProposalReplyUnit::getUnitId, "=", actorUnitId)); - - Dict variable = FlowUtil.variableToDict(task.getVariable()); - variable.set("underTakeName", replyUnit.getUnitName()); - variable.set("underTakeId", replyUnit.getUnitId()); - variable.set("underTakeIsMaster", replyUnit.getIsMaster()); - task.setVariable(Json.toJson(variable)); + setReplyUnitVariable(proposalCommonService, proposalId, task); } dao.update(processTaskList,"variable"); } + + /** + * 按任务全部办理人的负责人角色承办单位,补充任务显示所需的承办单位信息。 + * + * @param proposalCommonService 提案公共服务 + * @param proposalId 当前流程对应的提案 ID + * @param task 当前办结或本次新生成的承办答复任务 + */ + private void setReplyUnitVariable(ProposalCommonService proposalCommonService, String proposalId, ProcessTask task) { + ProposalReplyUnit replyUnit = proposalCommonService.getReplyUnitByTaskActorRole( + proposalId, task.getId(), task.getTaskName()); + Dict variable = FlowUtil.variableToDict(task.getVariable()); + variable.set("underTakeName", replyUnit.getUnitName()); + variable.set("underTakeId", replyUnit.getUnitId()); + variable.set("underTakeIsMaster", replyUnit.getIsMaster()); + task.setVariable(Json.toJson(variable)); + } } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/listenter/ProposalCaseTaskRevokeEventListener.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/listenter/ProposalCaseTaskRevokeEventListener.java index 32facb9a..7f0052e0 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/listenter/ProposalCaseTaskRevokeEventListener.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/listenter/ProposalCaseTaskRevokeEventListener.java @@ -7,8 +7,10 @@ import com.budwk.app.flow.entity.ProcessInstance; import com.budwk.app.flow.entity.ProcessTask; import com.budwk.app.flow.enums.ProcessEventTypeEnum; import com.budwk.app.zhgh.democratic.proposal.models.ProposalReplyUnit; +import org.nutz.aop.interceptor.ioc.TransAop; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; +import org.nutz.ioc.aop.Aop; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; @@ -22,10 +24,21 @@ public class ProposalCaseTaskRevokeEventListener implements ProcessEventListener private Dao dao; @Override + @Aop(TransAop.READ_COMMITTED) public void onEvent(ProcessEvent event) { if (event.getEventType() == ProcessEventTypeEnum.PROCESS_TASK_REVOKE) { Long taskId = event.getSourceId(); ProcessTask task = dao.fetch(ProcessTask.class, taskId); + if (task == null || task.getTaskParentId() == null) { + return; + } + + // 通用撤回事件传入的是被撤销的后续任务,只有其父任务为委员会立案时才清理承办单位。 + ProcessTask parentTask = dao.fetch(ProcessTask.class, task.getTaskParentId()); + if (parentTask == null || !"committeeFiling".equals(parentTask.getTaskName())) { + return; + } + ProcessInstance instance = dao.fetch(ProcessInstance.class, task.getProcessInstanceId()); String businessNo = instance.getBusinessNo(); dao.clear(ProposalReplyUnit.class, Cnd.where(ProposalReplyUnit::getProposalId, "=", businessNo)); diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java index eb8ad319..d2b959da 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java @@ -2,6 +2,7 @@ package com.budwk.app.zhgh.democratic.proposal.service.common; import com.budwk.app.base.service.BaseService; import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalReplyUnit; import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake; import org.nutz.lang.util.NutMap; @@ -11,6 +12,16 @@ import java.util.List; public interface ProposalCommonService extends BaseService { + /** + * 根据任务办理人的“提案承办单位领导”角色匹配提案承办单位。 + * + * @param proposalId 提案 ID,对应 proposal_reply_unit.proposalId + * @param taskId 流程任务 ID,用于获取该任务的全部办理人 + * @param taskName 任务节点名称;master_reply、opinion_master_reply 匹配主办单位,slave_reply 匹配协办单位 + * @return 当前任务对应的 ProposalReplyUnit,包含承办单位 ID、名称及主协办类型 + */ + ProposalReplyUnit getReplyUnitByTaskActorRole(String proposalId, Long taskId, String taskName); + /** * 查询提案信息 */ diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonServiceImpl.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonServiceImpl.java index 586fab31..8763c728 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonServiceImpl.java @@ -15,6 +15,7 @@ import com.budwk.app.flow.engine.FlowEngine; import com.budwk.app.flow.engine.util.FlowUtil; import com.budwk.app.flow.entity.ProcessInstance; import com.budwk.app.flow.entity.ProcessTask; +import com.budwk.app.flow.entity.ProcessTaskActor; import com.budwk.app.flow.enums.ProcessTaskStateEnum; import com.budwk.app.flow.vo.ProcessTaskVO; import com.budwk.app.sys.models.Sys_dict; @@ -28,6 +29,7 @@ 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.ProposalInfo; import com.budwk.app.zhgh.democratic.proposal.models.ProposalMerge; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalReplyUnit; import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake; import com.budwk.app.zhgh.democratic.teachercongress.prepare.models.Teacher_congress_session; import com.deepoove.poi.XWPFTemplate; @@ -74,6 +76,76 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp super(dao); } + /** + * 根据任务办理人的承办单位角色确定当前提案的主办或协办单位。 + * + * @param proposalId 提案 ID,不能为空 + * @param taskId 流程任务 ID,不能为空且任务必须存在办理人 + * @param taskName master_reply、opinion_master_reply 或 slave_reply + * @return 唯一匹配的提案承办单位记录 + */ + @Override + public ProposalReplyUnit getReplyUnitByTaskActorRole(String proposalId, Long taskId, String taskName) { + if (StrUtil.isBlank(proposalId) || taskId == null || StrUtil.isBlank(taskName)) { + throw new BaseException("提案承办单位匹配参数不完整"); + } + + boolean isMaster; + if (List.of("master_reply", "opinion_master_reply").contains(taskName)) { + isMaster = true; + } else if ("slave_reply".equals(taskName)) { + isMaster = false; + } else { + throw new BaseException("当前任务不是提案承办答复节点,任务ID:" + taskId); + } + + List taskActors = dao().query(ProcessTaskActor.class, + Cnd.where(ProcessTaskActor::getProcessTaskId, "=", taskId)); + if (taskActors.isEmpty()) { + throw new BaseException("提案承办答复任务没有配置办理人,任务ID:" + taskId); + } + + Sys_role leaderRole = sysRoleService.getByCode(RoleConstant.PROPOSAL_UNIT_LEADER.name()); + if (leaderRole == null) { + throw new BaseException("系统未配置提案承办单位领导角色"); + } + + List actorIds = taskActors.stream().map(ProcessTaskActor::getActorId).distinct().toList(); + List actorRoles = dao().query(Sys_user_role.class, + Cnd.where(Sys_user_role::getRoleId, "=", leaderRole.getId()) + .and(Sys_user_role::getUserId, "in", actorIds)); + Map> actorUnitIds = actorRoles.stream() + .filter(role -> StrUtil.isNotBlank(role.getUnderTakeId())) + .collect(Collectors.groupingBy(Sys_user_role::getUserId, + Collectors.mapping(Sys_user_role::getUnderTakeId, Collectors.toSet()))); + + // 同一流程任务的办理人应归属同一个角色承办单位,取全部办理人的共同承办单位避免误匹配。 + Set commonUnitIds = null; + for (String actorId : actorIds) { + Set unitIds = actorUnitIds.getOrDefault(actorId, Collections.emptySet()); + if (commonUnitIds == null) { + commonUnitIds = new HashSet<>(unitIds); + } else { + commonUnitIds.retainAll(unitIds); + } + } + if (commonUnitIds == null || commonUnitIds.isEmpty()) { + throw new BaseException("任务办理人的提案承办单位角色与当前任务不匹配,任务ID:" + taskId); + } + + List replyUnits = dao().query(ProposalReplyUnit.class, + Cnd.where(ProposalReplyUnit::getProposalId, "=", proposalId) + .and(ProposalReplyUnit::getUnitId, "in", commonUnitIds) + .and(ProposalReplyUnit::getIsMaster, "=", isMaster)); + if (replyUnits.isEmpty()) { + throw new BaseException("任务办理人的角色承办单位未包含在当前提案承办单位中,任务ID:" + taskId); + } + if (replyUnits.size() > 1) { + throw new BaseException("任务办理人匹配到多个提案承办单位,请检查角色配置,任务ID:" + taskId); + } + return replyUnits.get(0); + } + @Override public NutMap info(String id) { if (StrUtil.isBlank(id)) {