diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalPositiveSecondedController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalPositiveSecondedController.java new file mode 100644 index 00000000..b598f46c --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalPositiveSecondedController.java @@ -0,0 +1,203 @@ +package com.budwk.app.zhgh.democratic.proposal.controller.transact; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.dev33.satoken.annotation.SaMode; +import com.budwk.app.base.annotation.SLog; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.result.Result; +import com.budwk.app.flow.entity.ProcessInstance; +import com.budwk.app.flow.entity.ProcessTask; +import com.budwk.app.flow.enums.ProcessTaskStateEnum; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.zhgh.democratic.proposal.models.ProposalSecond; +import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam; +import com.budwk.app.zhgh.democratic.proposal.service.ProposalSecondedService; +import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.nutz.aop.interceptor.ioc.TransAop; +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.ioc.aop.Aop; +import org.nutz.ioc.loader.annotation.Inject; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.mvc.annotation.At; +import org.nutz.mvc.annotation.Ok; +import org.nutz.mvc.annotation.Param; + +import javax.validation.Valid; +import java.util.List; + +@IocBean +@At("/platform/proposal/positiveSeconded") +@Slf4j +@Ok("json:full") +@Api(tags = "提案管理系统-提案主动附议") +public class ProposalPositiveSecondedController { + + @Inject + private Dao dao; + @Inject + private ProposalCommonService proposalCommonService; + @Inject + private ProposalSecondedService proposalSecondedService; + + @At("") + @Ok("beetl:/platform/zhgh/democratic/proposal/transact/positiveSeconded/index.html") + @SaCheckPermission(value = {"proposal.seconded", "h5.proposal.seconded"}, mode = SaMode.OR) + public void index() { + } + + @At("/h5") + @Ok("beetl:/platform/zhghh5/democratic/proposal/transact/positiveSeconded/index.html") + @SaCheckPermission(value = {"proposal.seconded", "h5.proposal.seconded"}, mode = SaMode.OR) + public void h5Index() { + } + + @At + @SaCheckPermission(value = {"proposal.seconded", "h5.proposal.seconded"}, mode = SaMode.OR) + public Result pageData(@Valid ProposalSearchParam pageForm, boolean approval) { + // 主动附议查询规则: + // 1. 受邀附议的提案不能出现在主动附议中; + // 2. 自己发起的提案不能出现在主动附议“未附议”中; + // 3. 主动附议“未附议”只展示:未被邀请、不是自己写、自己还没主动附议过的提案; + // 4. 主动附议“已附议”只展示:本人已经主动附议过的提案,不混入受邀附议记录; + // 5. 受邀附议识别同时兼容 proposal_second.mode=1 的新数据和 second 节点办理人的历史流程数据。 + Sql sql = Sqls.create(""" + SELECT + info.*, + type.name AS typeName, + tcs.fullName AS sessionName, + tcd.`name` AS delegationName, + ins.state instanceState, + t.displayName taskName, + IFNULL(GROUP_CONCAT(DISTINCT t.displayName),'结束') curTaskName, + sum( CASE WHEN ps.seconderId=@seconderId and ps.isAgree is not null THEN 1 ELSE 0 END ) as count + FROM + proposal_info info + LEFT JOIN proposal_second ps ON ps.proposalId = info.id + 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 + $condition + """); + Cnd cnd = Cnd.NEW(); + sql.setCondition(cnd); + sql.setParam("seconderId", SecurityUtil.getUserId()); + + cnd.and("ins.id", "is not", null); + + if (approval) { + // 已附议列表保留本人已主动附议过的提案,后续流转到委员会立案等节点后仍可查看。 + cnd.and("t.taskName", "in", List.of("invite", "second", "delegation", "committee")); + cnd.and("ps.seconderId", "=", SecurityUtil.getUserId()); + cnd.and("ps.mode", "=", false); + cnd.and("ps.isAgree", "is not", null); + // 已附议列表也排除“被邀请附议”的提案,保证这里只展示主动附议记录。 + cnd.and(new Static("info.id not in (select proposalId from proposal_second where seconderId = '%s' and mode = 1)".formatted(SecurityUtil.getUserId()))); + cnd.and(new Static(""" + info.id not in ( + select ins2.businessNo + from wf_process_instance ins2 + inner join wf_process_task t2 on t2.processInstanceId = ins2.id and t2.taskName = 'second' + inner join wf_process_task_actor ta2 on ta2.processTaskId = t2.id + where ta2.actorId = '%s' + ) + """.formatted(SecurityUtil.getUserId()))); + } else { + // 未附议列表只保留团长审核结束前的流程节点。 + // 一旦流转到提案委员会立案阶段,主动附议页面就不再展示该提案。 + cnd.and("t.taskName", "in", List.of("invite", "second", "delegation")); + // 未附议列表中排除自己发起的提案,已附议列表保留本人已主动附议记录。 + cnd.and("info.createdBy", "!=", SecurityUtil.getUserId()); + // 主动附议列表只查询当前用户可主动附议的提案。 + // 这里同时兼容两类受邀附议识别方式: + // 1. proposal_second.mode = 1 的新数据; + // 2. 流程中存在当前用户的 second 节点办理记录的历史数据。 + cnd.and(new Static("info.id not in (select proposalId from proposal_second where seconderId = '%s' and mode = 1)".formatted(SecurityUtil.getUserId()))); + cnd.and(new Static(""" + info.id not in ( + select ins2.businessNo + from wf_process_instance ins2 + inner join wf_process_task t2 on t2.processInstanceId = ins2.id and t2.taskName = 'second' + inner join wf_process_task_actor ta2 on ta2.processTaskId = t2.id + where ta2.actorId = '%s' + ) + """.formatted(SecurityUtil.getUserId()))); + cnd.and(new Static("info.id not in (select proposalId from proposal_second where seconderId = '%s' and isAgree is not null)".formatted(SecurityUtil.getUserId()))); + } + + cnd.groupBy("info.id"); + ProposalSearchParam.buildSearch(cnd, pageForm); + Pagination pagination = proposalCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + return Result.success(pagination); + } + + @At + @Aop(TransAop.READ_COMMITTED) + @ApiOperation("主动附议") + @SLog(tag = "提案管理系统-主动附议", msg = "主动附议") + @SaCheckPermission(value = {"proposal.seconded", "h5.proposal.seconded"}, mode = SaMode.OR) + public Result handle(@Param("proposalId") String proposalId, + @Param("opinion") String opinion, + @Param("submitType") Integer submitType) { + Result validateResult = validateBeforeDelegation(proposalId); + if (validateResult.getCode() != 0) { + return validateResult; + } + return proposalSecondedService.handlePositiveSecond(proposalId, opinion, submitType); + } + + @At + @SaCheckPermission(value = {"proposal.seconded", "h5.proposal.seconded"}, mode = SaMode.OR) + public Result listPositiveSeconded(String bizId) { + List list = dao.query( + ProposalSecond.class, + Cnd.where(ProposalSecond::getProposalId, "=", bizId).and(ProposalSecond::getMode, "=", false) + ); + return Result.success(list); + } + + @At + @SaCheckPermission(value = {"proposal.seconded", "h5.proposal.seconded"}, mode = SaMode.OR) + public Result validateCanSeconded(String proposalId) { + return validateBeforeDelegation(proposalId); + } + + /** + * 主动附议只允许发生在团长审核完成之前。 + */ + private Result validateBeforeDelegation(String proposalId) { + ProcessInstance processInstance = dao.fetch(ProcessInstance.class, Cnd.where("businessNo", "=", proposalId)); + if (processInstance == null) { + return Result.error(99, "未查询到提案流程信息"); + } + + int delegationFinishedCount = dao.count( + ProcessTask.class, + Cnd.where("processInstanceId", "=", processInstance.getId()) + .and("taskName", "=", "delegation") + .and("taskState", "=", ProcessTaskStateEnum.FINISHED.getCode()) + ); + if (delegationFinishedCount > 0) { + return Result.error(99, "团长已审核,不能再主动附议"); + } + + int availableTaskCount = dao.count( + ProcessTask.class, + Cnd.where("processInstanceId", "=", processInstance.getId()) + .and("taskState", "=", ProcessTaskStateEnum.DOING.getCode()) + .and("taskName", "in", List.of("invite", "second", "delegation")) + ); + if (availableTaskCount == 0) { + return Result.error(99, "当前提案不在主动附议阶段"); + } + return Result.success(); + } +} diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/positiveSeconded/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/positiveSeconded/index.html new file mode 100644 index 00000000..9b725e81 --- /dev/null +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/positiveSeconded/index.html @@ -0,0 +1,221 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + 已附议 + 未附议 + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/src/main/resources/views/platform/zhghh5/democratic/proposal/transact/positiveSeconded/index.html b/src/main/resources/views/platform/zhghh5/democratic/proposal/transact/positiveSeconded/index.html new file mode 100644 index 00000000..4f5342ea --- /dev/null +++ b/src/main/resources/views/platform/zhghh5/democratic/proposal/transact/positiveSeconded/index.html @@ -0,0 +1,220 @@ + +
+ + + + + + + + + + + + + + + + + + + +
+
主动附议
+ + + +
+ 不同意 + 同意 +
+
+
+ +
+ +