diff --git a/src/main/java/com/budwk/app/base/constant/RoleConstant.java b/src/main/java/com/budwk/app/base/constant/RoleConstant.java index 0b5138a..a982733 100644 --- a/src/main/java/com/budwk/app/base/constant/RoleConstant.java +++ b/src/main/java/com/budwk/app/base/constant/RoleConstant.java @@ -64,6 +64,7 @@ RoleConstant { PROPOSAL_COMMITTEE_DIRECTOR("提案委员会主任"), PROPOSAL_COMMITTEE_DEPUTY_DIRECTOR("提案委员会副主任"), + PROPOSAL_COMMITTEE_MEMBER("提案委员会委员"), PROPOSAL_BRANCH_SCHOOL_LEADER("提案分管校领导"), PROPOSAL_UNIT_LEADER("提案承办单位领导"), PROPOSAL_UNIT_PROXY("提案承办单位代理答复人"), diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommissionerController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommissionerController.java index ec5d51c..58b34de 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommissionerController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommissionerController.java @@ -2,9 +2,16 @@ package com.budwk.app.zhgh.democratic.proposal.controller.transact; import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.lang.Dict; import com.budwk.app.base.annotation.SLog; +import com.budwk.app.base.constant.RoleConstant; +import com.budwk.app.base.exception.BaseException; import com.budwk.app.base.page.Pagination; import com.budwk.app.base.result.Result; +import com.budwk.app.flow.constant.FlowConst; +import com.budwk.app.flow.enums.ProcessTaskStateEnum; +import com.budwk.app.flow.service.FlowCommonService; +import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.zhgh.democratic.proposal.models.ProposalCommissionerOpinion; import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam; @@ -24,6 +31,7 @@ import org.nutz.mvc.annotation.Ok; import javax.validation.Valid; import java.util.Date; +import java.util.List; @IocBean @At("/platform/proposal/commissioner") @@ -32,10 +40,14 @@ import java.util.Date; @Api(tags = "提案委员会委员查询") public class ProposalCommissionerController { + private static final String COMMITTEE_OPINION_TASK_NAME = "committee_member_review"; + @Inject private Dao dao; @Inject private ProposalCommonService proposalCommonService; + @Inject + private FlowCommonService flowCommonService; @At("") @Ok("beetl:/platform/zhgh/democratic/proposal/transact/commissioner/index.html") @@ -64,26 +76,46 @@ public class ProposalCommissionerController { ins.state instanceState, ins.variable instanceVariable, ins.processDefineId instanceProcessDefineId, + t.id taskId, + t.taskName AS taskKey, t.displayName taskName, + t.taskType, + t.performType taskPerformType, + t.taskState, + t.finishTime, + t.taskParentId, + t.variable taskVariable, + IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName, + GROUP_CONCAT(DISTINCT ta.actorName, '(', ta.actorAccount, ')' ) AS auditUser, (SELECT count(1) FROM proposal_commissioner_opinion WHERE proposalId = info.id AND caseFilingResult = 'CONFIRM_FILING') CONFIRM_FILING_COUNT, (SELECT count(1) FROM proposal_commissioner_opinion WHERE proposalId = info.id AND caseFilingResult = 'SUGGESTION') SUGGESTION_COUNT, (SELECT count(1) FROM proposal_commissioner_opinion WHERE proposalId = info.id AND caseFilingResult = 'NOT') NOT_COUNT, pco.id pcoId FROM - proposal_info info + wf_process_task t + LEFT JOIN `wf_process_instance` ins ON ins.id = t.processInstanceId + LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id + LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10 + LEFT JOIN proposal_info info ON info.id = ins.businessNo LEFT JOIN proposal_type type ON type.id = info.typeId LEFT JOIN teacher_congress_session tcs ON tcs.id = info.sessionId LEFT JOIN teacher_congress_delegation tcd ON tcd.id = info.delegationId - LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id - LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id AND t.taskState = 10 LEFT JOIN proposal_commissioner_opinion pco on pco.proposalId = info.id and pco.commissioner = @userId $condition """); sql.setParam("userId", SecurityUtil.getUserId()); Cnd cnd = Cnd.NEW(); + cnd.and("t.taskName", "=", COMMITTEE_OPINION_TASK_NAME); + if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) { + cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); + } + if (approval) { + cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode())); + } else { + cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); + } ProposalSearchParam.buildSearch(cnd, pageForm); - cnd.and("pco.id", approval ? "is not" : "is", null); cnd.groupBy("t.id"); cnd.desc("t.createdAt"); sql.setCondition(cnd); @@ -95,7 +127,10 @@ public class ProposalCommissionerController { @SaCheckPermission("proposal.commissioner") @SLog(tag = "提案委员会委员意见", msg = "") @Aop(TransAop.READ_COMMITTED) - public Result doApproval(String proposalId, String opinion, String caseFilingResult, String caseFilingType) { + public Result doApproval(Long processTaskId, String proposalId, String opinion, String caseFilingResult, String caseFilingType) { + if (processTaskId == null) { + throw new BaseException("缺少流程任务ID,无法提交提案委员会委员意见。"); + } dao.clear(ProposalCommissionerOpinion.class, Cnd.where(ProposalCommissionerOpinion::getProposalId, "=", proposalId).and(ProposalCommissionerOpinion::getCommissioner, "=", SecurityUtil.getUserId())); ProposalCommissionerOpinion commissionerOpinion = new ProposalCommissionerOpinion(); @@ -107,6 +142,15 @@ public class ProposalCommissionerController { commissionerOpinion.setOpinionTime(new Date()); dao.insert(commissionerOpinion); + // 保存委员意见后完成当前会签任务;并行会签由流程引擎判断全部成员是否已完成。 + Dict args = Dict.create() + .set(FlowConst.PROCESS_TASK_ID_KEY, processTaskId) + .set(FlowConst.TASK_FORM_DATA_PREFIX + "proposalId", proposalId) + .set(FlowConst.TASK_FORM_DATA_PREFIX + "caseFilingResult", caseFilingResult) + .set(FlowConst.TASK_FORM_DATA_PREFIX + "caseFilingType", caseFilingType) + .set(FlowConst.TASK_FORM_DATA_PREFIX + "opinion", opinion); + flowCommonService.executeTask(args); + return Result.success(); } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingController.java index 544084b..bf6f3c5 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingController.java @@ -40,6 +40,8 @@ import java.util.List; @Api(tags = "提案委员会立案审核") public class ProposalCommitteeFilingController { + private static final List TASK_NAMES = List.of("committee", "committee_director_opinion"); + @Inject private Dao dao; @Inject @@ -79,6 +81,11 @@ public class ProposalCommitteeFilingController { t.finishTime, t.taskParentId, t.variable taskVariable, + CASE + WHEN t.taskName = 'committee' THEN 1 + WHEN t.taskName = 'committee_director_opinion' THEN 2 + ELSE 99 + END AS taskSort, IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName, IF(rt.id IS NOT NULL OR (ins.state = 20 AND info.caseFilingResult = 'NOT'), 1, 0) AS canRevoke, (select count(DISTINCT seconderId) from proposal_second where proposalId = info.id and isAgree = true) as agreeCount @@ -96,7 +103,7 @@ public class ProposalCommitteeFilingController { $condition """); Cnd cnd = Cnd.NEW(); - cnd.and("t.taskName", "=", "committee"); + cnd.and("t.taskName", "in", TASK_NAMES); if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) { cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); } @@ -107,12 +114,20 @@ public class ProposalCommitteeFilingController { } ProposalSearchParam.buildSearch(cnd, pageForm); cnd.groupBy("t.id"); + cnd.asc("taskSort"); cnd.desc("t.createdAt"); sql.setCondition(cnd); Pagination pagination = proposalCommitteeFilingService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); return Result.success(pagination); } + @At + @SaCheckPermission("proposal.committeeFiling") + @ApiOperation("查询提案分管校领导") + public Result listBranchSchoolLeader(String keyword) { + return Result.success(proposalCommitteeFilingService.listBranchSchoolLeader(keyword)); + } + @At @SaCheckPermission("proposal.committeeFiling") @ApiOperation("并案审核") diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSchoolLeaderApprovalController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSchoolLeaderApprovalController.java index 5983925..f3826ed 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSchoolLeaderApprovalController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSchoolLeaderApprovalController.java @@ -2,16 +2,10 @@ package com.budwk.app.zhgh.democratic.proposal.controller.transact; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.lang.Dict; -import cn.hutool.core.util.ObjectUtil; import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.base.page.Pagination; import com.budwk.app.base.result.Result; -import com.budwk.app.base.vo.LabelValueVO; -import com.budwk.app.flow.constant.FlowConst; -import com.budwk.app.flow.entity.ProcessTask; import com.budwk.app.flow.enums.ProcessTaskStateEnum; -import com.budwk.app.flow.service.FlowCommonService; -import com.budwk.app.flow.service.ProcessTaskService; import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam; @@ -41,16 +35,14 @@ import java.util.List; @Api(tags = "提案分管领导审批") public class ProposalSchoolLeaderApprovalController { + private static final List TASK_NAMES = List.of("school_leader", "school_leader_instruction"); + @Inject private Dao dao; @Inject private ProposalSchoolLeaderApprovalService proposalSchoolLeaderApprovalService; @Inject private ProposalCommonService proposalCommonService; - @Inject - private ProcessTaskService processTaskService; - @Inject - private FlowCommonService flowCommonService; @At("") @Ok("beetl:/platform/zhgh/democratic/proposal/transact/schoolLeaderApproval/index.html") @@ -92,6 +84,11 @@ public class ProposalSchoolLeaderApprovalController { t.finishTime, t.taskParentId, t.variable taskVariable, + CASE + WHEN t.taskName = 'school_leader_instruction' THEN 1 + WHEN t.taskName = 'school_leader' THEN 2 + ELSE 99 + END AS taskSort, IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName, IF(rt.id IS NOT NULL, 1, 0) AS canRevoke, GROUP_CONCAT(DISTINCT ta.actorName, '(', ta.actorAccount, ')' ) AS auditUser @@ -109,7 +106,7 @@ public class ProposalSchoolLeaderApprovalController { $condition """); Cnd cnd = Cnd.NEW(); - cnd.and("t.taskName", "=", "school_leader"); + cnd.and("t.taskName", "in", TASK_NAMES); if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) { cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); @@ -122,6 +119,7 @@ public class ProposalSchoolLeaderApprovalController { } ProposalSearchParam.buildSearch(cnd, pageForm); cnd.groupBy("t.id"); + cnd.asc("taskSort"); cnd.desc("t.createdAt"); sql.setCondition(cnd); Pagination pagination = proposalCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); @@ -143,23 +141,7 @@ public class ProposalSchoolLeaderApprovalController { @ApiOperation("执行任务") public Result executeTask(@Param("data") String data) { Dict args = Json.fromJson(Dict.class, data); - String proposalId = args.getStr("proposalId"); - - // 单条审核 - List mergeProposalIds = proposalCommonService.mergeProposal(proposalId); - if (ObjectUtil.isEmpty(mergeProposalIds)) { - flowCommonService.executeTask(args); - return Result.success(); - } - - // 并案审核 - ProcessTask thisTask = dao.fetch(ProcessTask.class, args.getLong(FlowConst.PROCESS_TASK_ID_KEY)); - List mergeTasks = processTaskService.getDoingTaskByBizIdTaskName(mergeProposalIds, thisTask.getTaskName()); - for (ProcessTask mergeTask : mergeTasks) { - Dict cloneArgs = args.clone(); - cloneArgs.put(FlowConst.PROCESS_TASK_ID_KEY, mergeTask.getId()); - flowCommonService.executeTask(cloneArgs); - } + proposalSchoolLeaderApprovalService.executeTask(args); return Result.success(); } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/handler/ProposalCommitteeAssignmentHandler.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/handler/ProposalCommitteeAssignmentHandler.java new file mode 100644 index 0000000..0fcc192 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/handler/ProposalCommitteeAssignmentHandler.java @@ -0,0 +1,57 @@ +package com.budwk.app.zhgh.democratic.proposal.handler; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.constant.RoleConstant; +import com.budwk.app.base.exception.BaseException; +import com.budwk.app.flow.engine.AssignmentHandler; +import com.budwk.app.flow.engine.core.Execution; +import com.budwk.app.flow.engine.core.ServiceContext; +import com.budwk.app.flow.engine.model.TaskModel; +import com.budwk.app.sys.models.Sys_role; +import com.budwk.app.sys.models.Sys_user_role; +import com.budwk.app.sys.services.SysRoleService; +import org.nutz.dao.Cnd; +import org.nutz.dao.Dao; + +import java.util.List; + +/** + * 提案委员会委员 + */ +public class ProposalCommitteeAssignmentHandler implements AssignmentHandler { + + @Override + public List assign(TaskModel model, Execution execution) { + Dao dao = ServiceContext.find(Dao.class); + SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class); + + // 根据角色维护的用户生成委员审议任务,保证流程参与人与角色授权保持一致。 + Sys_role role = sysRoleService.getByCode(RoleConstant.PROPOSAL_COMMITTEE_MEMBER); + if (role == null) { + throw new BaseException("没有设置提案委员会委员,无法流转到下一步,请联系校工会进行设置。"); + } + + List userRoles = dao.query(Sys_user_role.class, Cnd.where(Sys_user_role::getRoleId, "=", role.getId())); + List userIds = userRoles.stream().map(Sys_user_role::getUserId) + .filter(StrUtil::isNotBlank) + .distinct() + .toList(); + if (ObjectUtil.isEmpty(userIds)) { + throw new BaseException("没有设置提案委员会委员,无法流转到下一步,请联系校工会进行设置。"); + } + + return userIds; + } + + @Override + public String getMessage() { + return "提案委员会委员"; + } + + @Override + public int getOrder() { + return 190; + } + +} 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 d1b0ab0..77f8037 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,6 +3,7 @@ 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.exception.BaseException; import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.flow.constant.FlowConst; import com.budwk.app.flow.engine.FlowInterceptor; @@ -87,10 +88,20 @@ public class ProposalCaseFilingInterceptor implements FlowInterceptor { List processTaskList = execution.getProcessTaskList(); for (ProcessTask task : processTaskList) { + // 只有承办单位答复节点需要写入承办单位变量;分管校领导节点的办理人单位不是承办单位,不能按承办单位匹配。 + if (!List.of("master_reply", "slave_reply", "opinion_master_reply").contains(task.getTaskName())) { + continue; + } // 办理人 ProcessTaskActor taskActor = dao.fetch(ProcessTaskActor.class, Cnd.where(ProcessTaskActor::getProcessTaskId, "=", task.getId())); + if (taskActor == null) { + throw new BaseException("承办单位任务没有办理人,无法写入承办单位变量。"); + } String actorUnitId = taskActor.getActorUnitId(); ProposalReplyUnit replyUnit = dao.fetch(ProposalReplyUnit.class, Cnd.where(ProposalReplyUnit::getProposalId, "=", proposalId).and(ProposalReplyUnit::getUnitId, "=", actorUnitId)); + if (replyUnit == null) { + throw new BaseException("承办单位任务未找到对应承办单位,无法写入承办单位变量。"); + } Dict variable = FlowUtil.variableToDict(task.getVariable()); variable.set("underTakeName", replyUnit.getUnitName()); diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalCommitteeFilingService.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalCommitteeFilingService.java index e90ed23..a715e84 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalCommitteeFilingService.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalCommitteeFilingService.java @@ -3,10 +3,21 @@ package com.budwk.app.zhgh.democratic.proposal.service; import com.budwk.app.base.service.BaseService; import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; import com.budwk.app.zhgh.democratic.proposal.param.ProposalCommitteeFilingApprovalParam; +import org.nutz.lang.util.NutMap; + +import java.util.List; public interface ProposalCommitteeFilingService extends BaseService { void approval(ProposalCommitteeFilingApprovalParam approvalParam); void revoke(String taskId); + + /** + * 查询提案分管校领导角色关联的用户,供提案委主任选择下一步办理人。 + * + * @param keyword 用户姓名或登录名搜索关键字 + * @return 分管校领导用户列表 + */ + List listBranchSchoolLeader(String keyword); } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalSchoolLeaderApprovalService.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalSchoolLeaderApprovalService.java index dd1b9b7..921bf85 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalSchoolLeaderApprovalService.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalSchoolLeaderApprovalService.java @@ -1,5 +1,6 @@ package com.budwk.app.zhgh.democratic.proposal.service; +import cn.hutool.core.lang.Dict; import com.budwk.app.base.service.BaseService; import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; import com.budwk.app.zhgh.democratic.proposal.param.ProposalUnderTakeSchoolLeaderApprovalParam; @@ -8,6 +9,13 @@ import javax.validation.Valid; public interface ProposalSchoolLeaderApprovalService extends BaseService { + /** + * 执行分管校领导页面的流程任务,并根据当前节点补充分管校领导批示后续流转所需参数。 + * + * @param args 页面提交的流程参数 + */ + void executeTask(Dict args); + void approval(ProposalUnderTakeSchoolLeaderApprovalParam param); void revoke(@Valid String taskId); diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalCommitteeFilingServiceImpl.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalCommitteeFilingServiceImpl.java index 9b64e29..cffbaa3 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalCommitteeFilingServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalCommitteeFilingServiceImpl.java @@ -12,6 +12,7 @@ import com.budwk.app.bpm.enums.BpmTaskApprovalTypeEnum; import com.budwk.app.bpm.models.BpmProcessInstance; import com.budwk.app.bpm.models.BpmProcessTask; import com.budwk.app.bpm.service.BpmService; +import com.budwk.app.sys.models.Sys_role; import com.budwk.app.sys.models.Sys_user_role; import com.budwk.app.sys.services.SysMsgService; import com.budwk.app.web.commons.auth.utils.SecurityUtil; @@ -26,10 +27,14 @@ 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.dao.Sqls; +import org.nutz.dao.sql.Sql; import org.nutz.dao.util.cri.Static; +import org.nutz.dao.util.cri.SqlExpressionGroup; import org.nutz.ioc.aop.Aop; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.util.NutMap; import java.util.ArrayList; import java.util.Arrays; @@ -170,6 +175,39 @@ public class ProposalCommitteeFilingServiceImpl extends BaseServiceImpl listBranchSchoolLeader(String keyword) { + Sys_role role = dao().fetch(Sys_role.class, Cnd.where(Sys_role::getCode, "=", RoleConstant.PROPOSAL_BRANCH_SCHOOL_LEADER.name())); + if (role == null) { + return List.of(); + } + + // 分管校领导节点使用“指定下一个流程人”处理类,这里只返回可被传递的 userId。 + Sql sql = Sqls.create(""" + SELECT + u.id, + u.username, + u.loginname, + u.unitName, + CONCAT(u.username, '(', u.loginname, ')') AS label + FROM + sys_user_role ur + LEFT JOIN vw_user u ON u.id = ur.userId + $condition + """); + Cnd cnd = Cnd.where("ur.roleId", "=", role.getId()); + if (StrUtil.isNotBlank(keyword)) { + SqlExpressionGroup group = new SqlExpressionGroup(); + group.orLike("u.username", keyword); + group.orLike("u.loginname", keyword); + cnd.and(group); + } + cnd.groupBy("u.id"); + cnd.asc("u.username"); + sql.setCondition(cnd); + return listMap(sql); + } + @Override @Aop(TransAop.READ_COMMITTED) public void revoke(String taskId) { diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalSchoolLeaderApprovalServiceImpl.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalSchoolLeaderApprovalServiceImpl.java index 5e330a9..16fbe0f 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalSchoolLeaderApprovalServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalSchoolLeaderApprovalServiceImpl.java @@ -1,6 +1,7 @@ package com.budwk.app.zhgh.democratic.proposal.service.impl; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.lang.Dict; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; @@ -13,6 +14,11 @@ import com.budwk.app.bpm.enums.BpmTaskApprovalTypeEnum; import com.budwk.app.bpm.models.BpmProcessInstance; import com.budwk.app.bpm.models.BpmProcessTask; import com.budwk.app.bpm.service.BpmService; +import com.budwk.app.flow.constant.FlowConst; +import com.budwk.app.flow.engine.util.FlowUtil; +import com.budwk.app.flow.entity.ProcessTask; +import com.budwk.app.flow.service.FlowCommonService; +import com.budwk.app.flow.service.ProcessTaskService; import com.budwk.app.sys.models.Sys_user_role; import com.budwk.app.web.controllers.open.commons.service.CommonService; import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; @@ -32,17 +38,81 @@ import java.util.Map; @IocBean(args = {"refer:dao"}) public class ProposalSchoolLeaderApprovalServiceImpl extends BaseServiceImpl implements ProposalSchoolLeaderApprovalService { + private static final String SCHOOL_LEADER_INSTRUCTION_TASK = "school_leader_instruction"; + private static final List INSTRUCTION_VARIABLE_KEYS = List.of( + "tf_helpunitreply", + "tf_masterUnitId", + "tf_slaveUnitIds", + "tf_masterUnitName", + "tf_slaveUnitNames", + "tf_slaveUnitNameStr", + "tf_caseFilingResult", + "tf_caseFilingType" + ); + @Inject private BpmService bpmService; @Inject private CommonService commonService; @Inject private ProposalCommonService proposalCommonService; + @Inject + private FlowCommonService flowCommonService; + @Inject + private ProcessTaskService processTaskService; public ProposalSchoolLeaderApprovalServiceImpl(Dao dao) { super(dao); } + @Override + public void executeTask(Dict args) { + String proposalId = args.getStr("proposalId"); + + List mergeProposalIds = proposalCommonService.mergeProposal(proposalId); + if (ObjectUtil.isEmpty(mergeProposalIds)) { + fillInstructionNodeArgs(args); + flowCommonService.executeTask(args); + return; + } + + ProcessTask thisTask = dao().fetch(ProcessTask.class, args.getLong(FlowConst.PROCESS_TASK_ID_KEY)); + List mergeTasks = processTaskService.getDoingTaskByBizIdTaskName(mergeProposalIds, thisTask.getTaskName()); + for (ProcessTask mergeTask : mergeTasks) { + Dict cloneArgs = args.clone(); + cloneArgs.put(FlowConst.PROCESS_TASK_ID_KEY, mergeTask.getId()); + fillInstructionNodeArgs(cloneArgs); + flowCommonService.executeTask(cloneArgs); + } + } + + /** + * 分管校领导批示节点后面要继续按主办/协办单位分支流转,需要沿用提案委主任立案时写入当前任务的单位变量。 + */ + private void fillInstructionNodeArgs(Dict args) { + Long processTaskId = args.getLong(FlowConst.PROCESS_TASK_ID_KEY); + if (processTaskId == null) { + return; + } + + ProcessTask task = dao().fetch(ProcessTask.class, processTaskId); + if (task == null || !SCHOOL_LEADER_INSTRUCTION_TASK.equals(task.getTaskName())) { + return; + } + + Dict variable = FlowUtil.variableToDict(task.getVariable()); + for (String key : INSTRUCTION_VARIABLE_KEYS) { + Object value = variable.get(key); + if (!args.containsKey(key) && ObjectUtil.isNotNull(value)) { + args.put(key, value); + } + } + if (!args.containsKey("tf_helpunitreply")) { + List slaveUnitIds = (List) args.getObj("tf_slaveUnitIds"); + args.put("tf_helpunitreply", ObjectUtil.isNotEmpty(slaveUnitIds) ? "HAS_HELP_UNIT" : "NO_HELP_UNIT"); + } + } + @Override public void approval(ProposalUnderTakeSchoolLeaderApprovalParam approvalParam) { approvalParam.getBpmTaskApprovalTypeEnum(); diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/commissioner/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/commissioner/index.html index ac492fa..ead3041 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/commissioner/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/commissioner/index.html @@ -63,7 +63,7 @@ layout("/layouts/platform.html"){ @@ -132,7 +132,8 @@ layout("/layouts/platform.html"){ {label: "立案票数", prop: "CONFIRM_FILING_COUNT"}, {label: "作为建议票数", prop: "SUGGESTION_COUNT"}, {label: "不予立案票数", prop: "NOT_COUNT"}, - {label: "当前节点", prop: "taskName"}, + {label: "当前节点", prop: "curTaskName"}, + {label: "审核人", prop: "auditUser", width: "160px"}, {label: "流程状态", prop: "instanceState"} ], pageForm: { @@ -160,18 +161,19 @@ layout("/layouts/platform.html"){ openAudit(row) { this.$refs.guava.edit(() => { this.showApprovalForm = true - this.formData = { + this.$set(this, "formData", { + processTaskId: row.taskId, proposalId: row.id, caseFilingResult: null, caseFilingType: null, opinion: null - } + }) this.$refs.proposalInfoRef.onOpen(row) }) }, doSubmit() { - this.$refs.formRef.validate(async (valid) => { + this.$refs.formRef.validate((valid) => { if (!valid) return this.$confirm("您确定要提交吗?", "提示", { confirmButtonText: "确定", @@ -190,7 +192,7 @@ layout("/layouts/platform.html"){ }, // 教代会 - async meetingChange(val) { + meetingChange(val) { this.doSearch() }, diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/committeeFiling/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/committeeFiling/index.html index 45439a9..2f1b590 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/committeeFiling/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/committeeFiling/index.html @@ -100,7 +100,7 @@ layout("/layouts/platform.html"){ {{formData.taskName}} - - @@ -119,7 +119,7 @@ layout("/layouts/platform.html"){ @@ -134,7 +134,7 @@ layout("/layouts/platform.html"){ + + + + + @@ -210,10 +234,21 @@ layout("/layouts/platform.html"){ showApprovalForm: false, sessionOptions: [], delegationOptions: [], - underTakeOptions: [] + underTakeOptions: [], + branchSchoolLeaderOptions: [], + branchSchoolLeaderLoading: false } }, methods: { + isCommitteeTask() { + return this.formData.taskKey === "committee" + }, + isCommitteeDirectorOpinionTask() { + return this.formData.taskKey === "committee_director_opinion" + }, + isBranchSchoolLeaderRequired() { + return this.isCommitteeDirectorOpinionTask() || (this.isCommitteeTask() && this.formData.tf_caseFilingResult === "CONFIRM_FILING") + }, openView(row) { this.$refs.guava.edit(() => { this.showApprovalForm = false @@ -223,17 +258,24 @@ layout("/layouts/platform.html"){ openAudit(row) { this.$refs.guava.edit(() => { this.showApprovalForm = true - this.formData = { + this.$set(this, "formData", { processTaskId: row.taskId, + taskKey: row.taskKey, taskName: row.curTaskName, + userId: null, tf_masterUnitId: null, tf_slaveUnitIds: [] - } + }) + this.listBranchSchoolLeader("") this.$refs.proposalInfoRef.onOpen(row) }) }, handleTaskAction(val) { + if (val === 1 && this.isBranchSchoolLeaderRequired() && !this.formData.userId) { + this.$message.warning("请选择分管校领导") + return + } this.$refs.formRef.validate(valid => { if (valid) { this.$confirm("您确定要提交吗?", "提示", { @@ -243,7 +285,7 @@ layout("/layouts/platform.html"){ }).then(() => { // 是否有协办单位 let tf_helpunitreply - if (this.formData.tf_slaveUnitIds && this.formData.tf_slaveUnitIds.length > 0) { + if (this.isCommitteeTask() && this.formData.tf_slaveUnitIds && this.formData.tf_slaveUnitIds.length > 0) { tf_helpunitreply = "HAS_HELP_UNIT" } else { tf_helpunitreply = "NO_HELP_UNIT" @@ -273,6 +315,18 @@ layout("/layouts/platform.html"){ }) }, + // 查询提案分管校领导 + listBranchSchoolLeader(keyword) { + this.$set(this, "branchSchoolLeaderLoading", true) + this.$axios.post("/platform/proposal/committeeFiling/listBranchSchoolLeader", { keyword }).then((res) => { + if (res.code === 0) { + this.$set(this, "branchSchoolLeaderOptions", res.data) + } + }).finally(() => { + this.$set(this, "branchSchoolLeaderLoading", false) + }) + }, + // 打开并案审核 openMerge() { const selection = this.$refs.tableRef.selection @@ -280,10 +334,16 @@ layout("/layouts/platform.html"){ this.$message.warning("请先勾选需要并案审核的提案,至少需要两条提案") return } + if (selection.some(v => v.taskKey !== "committee")) { + this.$message.warning("只有提案委委员主任审核节点可以并案审核") + return + } this.$refs.guava.public(() => { this.$refs.mergeRef.onOpen(selection, { processTaskIds: selection.map(v => v.taskId), + taskKey: selection[0].taskKey, taskName: selection[0].curTaskName, + userId: null, tf_masterUnitId: null, tf_slaveUnitIds: [] }) @@ -327,7 +387,7 @@ layout("/layouts/platform.html"){ listUnderTake() { this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => { if (res.code === 0) { - this.underTakeOptions = res.data + this.$set(this, "underTakeOptions", res.data) } }) } diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/committeeFiling/merge.js b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/committeeFiling/merge.js index a574a9c..30afdfe 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/committeeFiling/merge.js +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/committeeFiling/merge.js @@ -71,6 +71,30 @@ const merge = { > + + + + + @@ -98,14 +122,20 @@ const merge = { tf_masterUnitId: [{ required: true, message: "请选择主办单位", trigger: "blur" }], approvalOpinion: [{ required: true, message: "请填写审核意见", trigger: "blur" }], }, - underTakeOptions: [] + underTakeOptions: [], + branchSchoolLeaderOptions: [], + branchSchoolLeaderLoading: false } }, methods: { + isBranchSchoolLeaderRequired() { + return this.formData.taskKey === "committee_director_opinion" || this.formData.tf_caseFilingResult === "CONFIRM_FILING" + }, onOpen(selection, formData) { - this.selection = selection - this.formData = formData + this.$set(this, "selection", selection) + this.$set(this, "formData", formData) this.listUnderTake() + this.listBranchSchoolLeader("") }, // 移除 onRemove(index) { @@ -119,11 +149,26 @@ const merge = { listUnderTake() { this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => { if (res.code === 0) { - this.underTakeOptions = res.data + this.$set(this, "underTakeOptions", res.data) } }) }, + // 查询提案分管校领导 + listBranchSchoolLeader(keyword) { + this.$set(this, "branchSchoolLeaderLoading", true) + this.$axios.post("/platform/proposal/committeeFiling/listBranchSchoolLeader", { keyword }).then((res) => { + if (res.code === 0) { + this.$set(this, "branchSchoolLeaderOptions", res.data) + } + }).finally(() => { + this.$set(this, "branchSchoolLeaderLoading", false) + }) + }, handleTaskAction(val) { + if (val === 1 && this.isBranchSchoolLeaderRequired() && !this.formData.userId) { + this.$message.warning("请选择分管校领导") + return + } this.$confirm("您确定要提交吗?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/schoolLeaderApproval/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/schoolLeaderApproval/index.html index 838d7e2..65715f0 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/schoolLeaderApproval/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/schoolLeaderApproval/index.html @@ -108,9 +108,9 @@ layout("/layouts/platform.html"){ 取消 - 退回重新答复 + 退回重新答复 - 同意答复 + {{submitButtonText()}} @@ -145,31 +145,44 @@ layout("/layouts/platform.html"){ }, formData: {}, showApprovalForm: false, + submitLoading: false, sessionOptions: [], delegationOptions: [], } }, methods: { + isInstructionTask() { + return this.formData.taskKey === "school_leader_instruction" + }, + isSchoolLeaderTask() { + return this.formData.taskKey === "school_leader" + }, + submitButtonText() { + return this.isInstructionTask() ? "提交批示" : "同意答复" + }, openView(row) { this.$refs.guava.edit(() => { - this.showApprovalForm = false + this.$set(this, "showApprovalForm", false) this.$refs.proposalInfoRef.onOpen(row) }) }, openAudit(row) { this.$refs.guava.edit(() => { - this.showApprovalForm = true - this.formData = { + this.$set(this, "showApprovalForm", true) + this.$set(this, "formData", { processTaskId: row.taskId, taskKey: row.taskKey, taskName: row.taskName, proposalId: row.id - } + }) this.$refs.proposalInfoRef.onOpen(row) }) }, handleTaskAction(val) { + if (this.submitLoading) { + return + } this.$refs.formRef.validate(valid => { if (!valid) return @@ -185,6 +198,7 @@ layout("/layouts/platform.html"){ delete formData.taskKey delete formData.taskName + this.$set(this, "submitLoading", true) this.$axios.post("/platform/proposal/schoolLeaderApproval/executeTask", { data: JSON.stringify(formData) }).then((res) => { @@ -193,6 +207,8 @@ layout("/layouts/platform.html"){ this.$message.success(res.msg) this.doSearch() } + }).finally(() => { + this.$set(this, "submitLoading", false) }) }) }) diff --git a/src/main/resources/views/platform/zhghh5/democratic/proposal/transact/commissioner/index.html b/src/main/resources/views/platform/zhghh5/democratic/proposal/transact/commissioner/index.html index bf86f61..9492419 100644 --- a/src/main/resources/views/platform/zhghh5/democratic/proposal/transact/commissioner/index.html +++ b/src/main/resources/views/platform/zhghh5/democratic/proposal/transact/commissioner/index.html @@ -32,7 +32,7 @@ layout("/layouts/platform_h5.html"){ {{row.typeName}} {{row.createUserName}} {{row.delegationName}} - {{row.taskName}} + {{row.curTaskName}} 立案:{{row.CONFIRM_FILING_COUNT}} 建议:{{row.SUGGESTION_COUNT}} @@ -44,7 +44,7 @@ layout("/layouts/platform_h5.html"){ 查看 -
+
审核
@@ -187,12 +187,13 @@ layout("/layouts/platform_h5.html"){ onApproval(row) { this.showApprovalForm = true this.$refs.proposalInfoRef.onOpen(row) - this.formData = { + this.$set(this, "formData", { + processTaskId: row.taskId, proposalId: row.id, caseFilingResult: null, caseFilingType: null, opinion: null - } + }) }, async doSubmit() { diff --git a/src/main/resources/views/platform/zhghh5/democratic/proposal/transact/schoolLeaderApproval/index.html b/src/main/resources/views/platform/zhghh5/democratic/proposal/transact/schoolLeaderApproval/index.html index b0ef1f7..507c5d1 100644 --- a/src/main/resources/views/platform/zhghh5/democratic/proposal/transact/schoolLeaderApproval/index.html +++ b/src/main/resources/views/platform/zhghh5/democratic/proposal/transact/schoolLeaderApproval/index.html @@ -65,8 +65,8 @@ layout("/layouts/platform_h5.html"){ >
- 退回答复 - 同意答复 + 退回答复 + {{submitButtonText()}}
@@ -92,6 +92,7 @@ layout("/layouts/platform_h5.html"){ sessionOptions: [], formData: {}, + submitLoading: false, showApprovalForm: false } }, @@ -120,22 +121,37 @@ layout("/layouts/platform_h5.html"){ }, onView(row) { - this.showApprovalForm = false + this.$set(this, "showApprovalForm", false) this.$refs.proposalInfoRef.onOpen(row) }, onApproval(row) { - this.showApprovalForm = true + this.$set(this, "showApprovalForm", true) this.$refs.proposalInfoRef.onOpen(row) - this.formData = { + this.$set(this, "formData", { processTaskId: row.taskId, taskKey: row.taskKey, taskName: row.taskName, proposalId: row.id - } + }) + }, + + isInstructionTask() { + return this.formData.taskKey === "school_leader_instruction" + }, + + isSchoolLeaderTask() { + return this.formData.taskKey === "school_leader" + }, + + submitButtonText() { + return this.isInstructionTask() ? "提交批示" : "同意答复" }, async handleTaskAction(val) { + if (this.submitLoading) { + return + } try { await this.$refs.formRef.validate(); this.$dialog.confirm({ @@ -150,8 +166,8 @@ layout("/layouts/platform_h5.html"){ delete formData.taskKey delete formData.taskName - - this.$axios.post("/flow/common/executeTask", { + this.$set(this, "submitLoading", true) + this.$axios.post("/platform/proposal/schoolLeaderApproval/executeTask", { data: JSON.stringify(formData) }).then((res) => { if (res.code === 0) { @@ -159,6 +175,8 @@ layout("/layouts/platform_h5.html"){ this.$toast.success(res.msg) this.doSearch() } + }).finally(() => { + this.$set(this, "submitLoading", false) }) }).catch(() => {