diff --git a/src/main/java/com/budwk/app/sys/controller/SysUnitController.java b/src/main/java/com/budwk/app/sys/controller/SysUnitController.java index 6aad02ab..49b0fca3 100644 --- a/src/main/java/com/budwk/app/sys/controller/SysUnitController.java +++ b/src/main/java/com/budwk/app/sys/controller/SysUnitController.java @@ -285,21 +285,28 @@ public class SysUnitController { @SaCheckLogin public Object tree(@Param("pid") String pid, HttpServletRequest req) { try { + String rootId = StrUtil.blankToDefault(pid, "0"); + String virtualRootId = "root"; Cnd cnd = Cnd.NEW(); - cnd.andEX("id", "=", pid); cnd.asc("unitcode"); List list = sysUnitService.query(cnd); List> nodeList = CollUtil.newArrayList(); for (int i = 0; i < list.size(); i++) { - nodeList.add(new TreeNode<>(list.get(i).getId(), list.get(i).getParentId(), list.get(i).getName(), i) + Sys_unit unit = list.get(i); + /* + * 单位根节点存在 id 与 parentId 都为 0 的自引用数据。 + * 构建树时把当前查询根挂到虚拟根下,避免“中国地质大学”和 parentId=0 的学院被构造成同级。 + */ + String parentId = rootId.equals(unit.getId()) ? virtualRootId : unit.getParentId(); + nodeList.add(new TreeNode<>(unit.getId(), parentId, unit.getName(), i) .setExtra( Map.of( - "unitTypeCode", list.get(i).getUnitTypeCode() + "unitTypeCode", unit.getUnitTypeCode() ) )); } - List> treeList = TreeUtil.build(nodeList, StrUtil.blankToDefault(pid, "0")); + List> treeList = TreeUtil.build(nodeList, virtualRootId); return Result.success(treeList); } catch (Exception e) { return Result.error(); diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/query/ProposalQueryAnalysisController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/query/ProposalQueryAnalysisController.java index 6bf7567c..f816b8aa 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/query/ProposalQueryAnalysisController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/query/ProposalQueryAnalysisController.java @@ -54,29 +54,41 @@ public class ProposalQueryAnalysisController { @At @ApiOperation("统计数据") @SaCheckPermission("proposal.query.analysis") - public Result statisticsData(String sessionId) { + public Result statisticsData(String sessionId, String dimension) { + /* + * 查询参数说明: + * sessionId:教代会届次ID,用于限定统计提案范围; + * dimension:统计维度,可传“提案人单位、提案类型、代表团、立案结果、满意度”,为空时返回全部维度。 + * 返回值:Result.data 为统计行列表,包含 dimension、itemName、count、rate。 + */ if (StrUtil.isBlank(sessionId)) { return Result.error("请先选择教代会届次"); } - return Result.success(buildStatisticsRows(sessionId)); + return Result.success(buildStatisticsRows(sessionId, dimension)); } @At @ApiOperation("分析数据") @SaCheckPermission("proposal.query.analysis") - public Result analysisData(String sessionId) { + public Result analysisData(String sessionId, String dimension) { + /* + * 查询参数说明: + * sessionId:教代会届次ID,用于限定分析提案范围; + * dimension:统计维度,可传“提案人单位、提案类型、代表团、立案结果、满意度”,为空时返回全部维度。 + * 返回值:Result.data 为分析行列表,包含 dimension、total、categoryCount、topItem、topCount、topRate、analysis。 + */ if (StrUtil.isBlank(sessionId)) { return Result.error("请先选择教代会届次"); } - return Result.success(buildAnalysisRows(sessionId)); + return Result.success(buildAnalysisRows(sessionId, dimension)); } @At @Ok("void") @ApiOperation("导出统计数据") @SaCheckPermission("proposal.query.analysis") - public void exportStatisticsData(String sessionId, HttpServletResponse response) { - List list = buildStatisticsRows(sessionId); + public void exportStatisticsData(String sessionId, String dimension, HttpServletResponse response) { + List list = buildStatisticsRows(sessionId, dimension); List entities = new ArrayList<>(); entities.add(new ExcelExportEntity("统计维度", "dimension", 20)); entities.add(new ExcelExportEntity("分类项", "itemName", 30)); @@ -92,8 +104,8 @@ public class ProposalQueryAnalysisController { @Ok("void") @ApiOperation("导出分析数据") @SaCheckPermission("proposal.query.analysis") - public void exportAnalysisData(String sessionId, HttpServletResponse response) { - List list = buildAnalysisRows(sessionId); + public void exportAnalysisData(String sessionId, String dimension, HttpServletResponse response) { + List list = buildAnalysisRows(sessionId, dimension); List entities = new ArrayList<>(); entities.add(new ExcelExportEntity("统计维度", "dimension", 20)); entities.add(new ExcelExportEntity("总量", "total", 12)); @@ -108,15 +120,15 @@ public class ProposalQueryAnalysisController { CommonDownloadUtil.download("提案分析数据.xlsx", workbook, response); } - private List buildStatisticsRows(String sessionId) { - Map> dataMap = loadDimensionData(sessionId); + private List buildStatisticsRows(String sessionId, String dimension) { + Map> dataMap = loadDimensionData(sessionId, dimension); List result = new ArrayList<>(); - dataMap.forEach((dimension, items) -> { + dataMap.forEach((dimensionName, items) -> { long total = items.stream().mapToLong(v -> v.getLong("count", 0L)).sum(); for (NutMap item : items) { long count = item.getLong("count", 0L); result.add(NutMap.NEW() - .addv("dimension", dimension) + .addv("dimension", dimensionName) .addv("itemName", item.getString("itemName", "未维护")) .addv("count", count) .addv("rate", formatPercent(count, total))); @@ -125,13 +137,13 @@ public class ProposalQueryAnalysisController { return result; } - private List buildAnalysisRows(String sessionId) { - Map> dataMap = loadDimensionData(sessionId); + private List buildAnalysisRows(String sessionId, String dimension) { + Map> dataMap = loadDimensionData(sessionId, dimension); List result = new ArrayList<>(); - dataMap.forEach((dimension, items) -> { + dataMap.forEach((dimensionName, items) -> { if (items.isEmpty()) { result.add(NutMap.NEW() - .addv("dimension", dimension) + .addv("dimension", dimensionName) .addv("total", 0) .addv("categoryCount", 0) .addv("topItem", "-") @@ -150,10 +162,10 @@ public class ProposalQueryAnalysisController { long topCount = top.getLong("count", 0L); String topItem = top.getString("itemName", "未维护"); String topRate = formatPercent(topCount, total); - String analysis = String.format("%s主要集中在【%s】,数量为%d,占比%s。", dimension, topItem, topCount, topRate); + String analysis = String.format("%s主要集中在【%s】,数量为%d,占比%s。", dimensionName, topItem, topCount, topRate); result.add(NutMap.NEW() - .addv("dimension", dimension) + .addv("dimension", dimensionName) .addv("total", total) .addv("categoryCount", sorted.size()) .addv("topItem", topItem) @@ -164,13 +176,23 @@ public class ProposalQueryAnalysisController { return result; } - private Map> loadDimensionData(String sessionId) { + private Map> loadDimensionData(String sessionId, String dimension) { Map> map = new LinkedHashMap<>(); - map.put("提案人单位", queryUnitStat(sessionId)); - map.put("提案类型", queryTypeStat(sessionId)); - map.put("代表团", queryDelegationStat(sessionId)); - map.put("立案结果", queryCaseFilingResultStat(sessionId)); - map.put("满意度", querySatisfactionStat(sessionId)); + if (StrUtil.isBlank(dimension) || "提案人单位".equals(dimension)) { + map.put("提案人单位", queryUnitStat(sessionId)); + } + if (StrUtil.isBlank(dimension) || "提案类型".equals(dimension)) { + map.put("提案类型", queryTypeStat(sessionId)); + } + if (StrUtil.isBlank(dimension) || "代表团".equals(dimension)) { + map.put("代表团", queryDelegationStat(sessionId)); + } + if (StrUtil.isBlank(dimension) || "立案结果".equals(dimension)) { + map.put("立案结果", queryCaseFilingResultStat(sessionId)); + } + if (StrUtil.isBlank(dimension) || "满意度".equals(dimension)) { + map.put("满意度", querySatisfactionStat(sessionId)); + } return map; } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/query/ProposalQueryComprehensiveController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/query/ProposalQueryComprehensiveController.java index 4e8aaa1d..28be5a7f 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/query/ProposalQueryComprehensiveController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/query/ProposalQueryComprehensiveController.java @@ -73,9 +73,10 @@ public class ProposalQueryComprehensiveController { 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_reply_unit pru ON pru.proposalId = info.id - LEFT JOIN wf_process_task replyTask on replyTask.processInstanceId = ins.id AND replyTask.taskState = 20 AND replyTask.taskName in ('master_reply','slave_reply','opinion_master_reply') + LEFT JOIN wf_process_task replyTask on replyTask.processInstanceId = ins.id $condition """); +// AND replyTask.taskState = 20 AND replyTask.taskName in ('master_reply','slave_reply','opinion_master_reply') Cnd cnd = Cnd.NEW(); if (ArrayUtil.isNotEmpty(pageForm.getOrigins()) && StrUtil.isNotBlank(pageForm.getCommonKeyword())) { SqlExpressionGroup seg = new SqlExpressionGroup(); diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/query/ProposalQueryUnitReplyController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/query/ProposalQueryUnitReplyController.java index c4d7cc88..811f3976 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/query/ProposalQueryUnitReplyController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/query/ProposalQueryUnitReplyController.java @@ -6,6 +6,7 @@ import com.budwk.app.flow.engine.util.FlowUtil; import com.budwk.app.flow.entity.ProcessTask; import com.budwk.app.flow.enums.ProcessTaskStateEnum; import com.budwk.app.zhgh.democratic.proposal.models.ProposalConfig; +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.service.common.ProposalCommonService; import lombok.extern.slf4j.Slf4j; @@ -44,16 +45,25 @@ public class ProposalQueryUnitReplyController { @At @SaCheckPermission("proposal.query.unitReply") - public Result data(String sessionId, String undertakeUnitId) { + public Result data(String sessionId, String undertakeUnitId, String caseFilingResult) { + /* + * 查询参数说明: + * sessionId:教代会届次ID,用于限定统计的提案范围; + * undertakeUnitId:承办单位ID,用于只统计某个承办单位,为空时统计全部承办单位; + * caseFilingResult:立案结果字典值,对应 proposal_info.caseFilingResult,为空时不限制立案结果。 + * 返回值:Result.data 中包含 tableData 统计行列表,以及 slaveNeedReply 协办单位是否需要答复配置。 + */ // 提案配置 协办是否需要答复 ProposalConfig proposalConfig = dao.fetch(ProposalConfig.class, Cnd.NEW()); boolean slaveNeedReply = proposalConfig.getSlaveUnitNeedReply(); // 当前届次所有的提案ID - Sql sql = Sqls.create("select id from proposal_info where sessionId = @sessionId").setParam("sessionId", sessionId); - sql.setCallback(Sqls.callback.strList()); - dao.execute(sql); - List proposalIds = sql.getList(String.class); + Cnd proposalCnd = Cnd.where(ProposalInfo::getSessionId, "=", sessionId); + proposalCnd.andEX(ProposalInfo::getCaseFilingResult, "=", caseFilingResult); + List proposalIds = dao.query(ProposalInfo.class, proposalCnd) + .stream() + .map(ProposalInfo::getId) + .collect(Collectors.toList()); if(proposalIds.isEmpty()){ return Result.success().addData(Map.of("tableData", Collections.EMPTY_LIST, "slaveNeedReply", slaveNeedReply)); @@ -73,7 +83,7 @@ public class ProposalQueryUnitReplyController { List replyUnits = dao.query(ProposalReplyUnit.class, cnd); // 承办单位答复记录 - List replyTasks = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "in", instIds).and(ProcessTask::getTaskName, "in", List.of("master_reply", "slave_reply", "opinion_master_reply")).and(ProcessTask::getTaskState, "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.DOING.getCode()))); + List replyTasks = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "in", instIds).and(ProcessTask::getTaskName, "in", List.of("two_unit_reply","unit_reply","master_reply", "slave_reply", "opinion_master_reply")).and(ProcessTask::getTaskState, "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.DOING.getCode()))); // 承办单位 List tableData = new ArrayList<>(); diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCaseCheckController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCaseCheckController.java index eb9f5661..069da813 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCaseCheckController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCaseCheckController.java @@ -45,7 +45,7 @@ public class ProposalCaseCheckController { @At("") @Ok("beetl:/platform/zhgh/democratic/proposal/transact/caseCheck/index.html") - @SaCheckPermission("proposal.mine") + @SaCheckPermission("proposal.caseCheck") public void index() { } @@ -83,6 +83,7 @@ public class ProposalCaseCheckController { LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10 LEFT JOIN proposal_info info ON info.id = ins.businessNo LEFT JOIN proposal_type type on type.id = info.typeId + LEFT JOIN vw_user vu ON vu.id = info.createUserId LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId $condition @@ -99,6 +100,8 @@ public class ProposalCaseCheckController { } else { cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); } + // 工会筛选按提案人所属工会口径处理,来源为 proposal_info.createUserId 关联 vw_user.unionId。 + cnd.andEX("vu.unionId", "=", pageForm.getUnionId()); ProposalSearchParam.buildSearch(cnd, pageForm); cnd.groupBy("t.id"); cnd.desc("t.createdAt"); 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 b8d2ae19..1da9b452 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 @@ -83,6 +83,7 @@ public class ProposalCommitteeFilingController { 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 vw_user vu ON vu.id = info.createUserId LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId $condition @@ -97,6 +98,8 @@ public class ProposalCommitteeFilingController { } else { cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); } + // 工会筛选按提案人所属工会口径处理,来源为 proposal_info.createUserId 关联 vw_user.unionId。 + cnd.andEX("vu.unionId", "=", pageForm.getUnionId()); ProposalSearchParam.buildSearch(cnd, pageForm); cnd.groupBy("t.id"); cnd.desc("t.createdAt"); diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingUnitController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingUnitController.java index c95f3fd5..dae7c618 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingUnitController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalCommitteeFilingUnitController.java @@ -99,6 +99,7 @@ public class ProposalCommitteeFilingUnitController { 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 vw_user vu ON vu.id = info.createUserId LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId $condition @@ -113,6 +114,8 @@ public class ProposalCommitteeFilingUnitController { } else { cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); } + // 工会筛选按提案人所属工会口径处理,来源为 proposal_info.createUserId 关联 vw_user.unionId。 + cnd.andEX("vu.unionId", "=", pageForm.getUnionId()); ProposalSearchParam.buildSearch(cnd, pageForm); cnd.groupBy("t.id"); cnd.desc("t.createdAt"); diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalPreAuditController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalPreAuditController.java index 1409bd6a..6a60c9e4 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalPreAuditController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalPreAuditController.java @@ -42,7 +42,7 @@ public class ProposalPreAuditController { @At("") @Ok("beetl:/platform/zhgh/democratic/proposal/transact/preAudit/index.html") - @SaCheckPermission("proposal.mine") + @SaCheckPermission("proposal.preAudit") public void index() { } @@ -81,6 +81,7 @@ public class ProposalPreAuditController { LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10 LEFT JOIN proposal_info info ON info.id = ins.businessNo LEFT JOIN proposal_type type on type.id = info.typeId + LEFT JOIN vw_user vu ON vu.id = info.createUserId LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId $condition @@ -97,6 +98,8 @@ public class ProposalPreAuditController { } else { cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); } + // 工会筛选按提案人所属工会口径处理,来源为 proposal_info.createUserId 关联 vw_user.unionId。 + cnd.andEX("vu.unionId", "=", pageForm.getUnionId()); ProposalSearchParam.buildSearch(cnd, pageForm); cnd.groupBy("t.id"); cnd.desc("t.createdAt"); 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 637535aa..dff9ab32 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 @@ -114,6 +114,7 @@ public class ProposalSchoolLeaderApprovalController { 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 = info.id + LEFT JOIN vw_user vu ON vu.id = info.createUserId LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId $condition @@ -130,6 +131,8 @@ public class ProposalSchoolLeaderApprovalController { } else { cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); } + // 工会筛选按提案人所属工会口径处理,来源为 proposal_info.createUserId 关联 vw_user.unionId。 + cnd.andEX("vu.unionId", "=", pageForm.getUnionId()); ProposalSearchParam.buildSearch(cnd, pageForm); cnd.groupBy("t.id"); cnd.desc("t.createdAt"); diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSecondedController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSecondedController.java index 5232dec5..cedcf17b 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSecondedController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalSecondedController.java @@ -2,24 +2,25 @@ package com.budwk.app.zhgh.democratic.proposal.controller.transact; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.lang.Dict; import cn.hutool.core.util.ObjectUtil; -import com.aspose.slides.internal.og.and; +import cn.hutool.json.JSONUtil; import com.budwk.app.base.annotation.SLog; 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.service.BaseService; -import com.budwk.app.bpm.service.BpmService; -import com.budwk.app.flow.entity.ProcessInstance; +import com.budwk.app.flow.service.FlowCommonService; import com.budwk.app.flow.entity.ProcessTask; +import com.budwk.app.flow.entity.ProcessTaskActor; import com.budwk.app.flow.enums.ProcessSubmitTypeEnum; import com.budwk.app.flow.enums.ProcessTaskStateEnum; +import com.budwk.app.sys.views.View_user; 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.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; @@ -28,11 +29,12 @@ 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 org.nutz.json.Json; +import org.nutz.lang.Strings; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Param; @@ -55,11 +57,9 @@ public class ProposalSecondedController { @Inject private BaseService baseService; @Inject - private ProposalCommonService proposalCommonService; - @Inject - private BpmService bpmService; - @Inject private ProposalSecondedService proposalSecondedService; + @Inject + private FlowCommonService flowCommonService; @At("") @Ok("beetl:/platform/zhgh/democratic/proposal/transact/seconded/index.html") @@ -96,6 +96,7 @@ public class ProposalSecondedController { t.finishTime, t.taskParentId, t.variable taskVariable, + nt.taskName curTaskCode, if(t.taskName = 'second', ta.actorId, ps.seconderId) taskActorUserId, if(t.taskName = 'second', ta.actorName, ps.userName) taskActorName, IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName, @@ -108,36 +109,40 @@ public class ProposalSecondedController { LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10 LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10 LEFT JOIN proposal_info info ON info.id = ins.businessNo - LEFT JOIN proposal_second ps ON ps.proposalId = info.id + LEFT JOIN proposal_second ps ON ps.proposalId = info.id AND ps.seconderId = @seconderId 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 $condition """); - sql.setParam("seconderId", SecurityUtil.getUserId()); + sql.setParam("seconderId", SecurityUtil.getUserId()); Cnd cnd = Cnd.NEW(); - cnd.and("t.taskName", "in", List.of("invite", "second", "delegation", "committee")); - cnd.and("ps.isAgree", "is", null); - if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) { - cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); - } + cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); if (approval) { + // 已附议页签只展示当前登录附议人已经处理过的记录。 + cnd.and("ps.isAgree", "is not", null); + cnd.and("t.taskName", "in", List.of("invite", "second", "delegation", "preAudit", "committee")); cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode())); } else { - cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode()); + // 未附议页签只展示当前登录附议人尚未处理的记录。 + cnd.and("ps.isAgree", "is", null); + // 待附议列表只展示两类任务: + // 1. invite / second 节点任务 + // 2. delegation / committee 节点,且任务状态必须是已废弃(99) + SqlExpressionGroup taskGroup = Cnd.exps("t.taskName", "in", List.of("invite", "second")); + SqlExpressionGroup delegationOrCommitteeGroup = Cnd.exps("t.taskName", "in", List.of("delegation", "preAudit", "committee")); + delegationOrCommitteeGroup.and("t.taskState", "=", ProcessTaskStateEnum.ABANDON.getCode()); + taskGroup.or(delegationOrCommitteeGroup); + cnd.and(taskGroup); } ProposalSearchParam.buildSearch(cnd, pageForm); cnd.groupBy("t.id"); cnd.desc("t.createdAt"); sql.setCondition(cnd); Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); - List list = pagination.getList(NutMap.class); - for (NutMap row : list) { -// String instanceId = row.getString("instanceId"); - } return Result.success(pagination); } @@ -146,37 +151,146 @@ public class ProposalSecondedController { @Aop(TransAop.READ_COMMITTED) @ApiOperation("修改提案附议信息") @SLog(tag = "提案管理系统-附议提案", msg = "修改提案附议信息") + /** + * 仅更新附议结果和附议任务状态,不调用流程引擎推进流程。 + * 参数说明: + * 1. proposalId:提案主键,用于定位 proposal_second 附议记录。 + * 2. taskId:当前页面点击的任务主键,用于定位本次需要完成的 wf_process_task。 + * 3. taskActorUserId:附议人用户ID,用于校验附议记录和任务参与人是否匹配。 + * 4. opinion:附议意见,写入 proposal_second.opinion。 + * 5. submitType:附议结果,1 表示同意,20 表示不同意。 + * 返回值: + * Result.success() 表示 proposal_second 和 wf_process_task 更新成功; + * Result.error(...) 表示参数错误或未找到对应业务数据。 + */ public Result updateInfo(@Param("proposalId") String proposalId, + @Param("taskId") Long taskId, @Param("taskActorUserId") String taskActorUserId, @Param("opinion") String opinion, @Param("submitType") Integer submitType) { - // 查询附议信息表 + if (Strings.isBlank(proposalId) || Strings.isBlank(taskActorUserId) || taskId == null || submitType == null) { + return Result.error("参数错误"); + } + + // 先定位 wf_process_task,确保本次请求能准确命中需要完成的附议任务,再更新两张业务表。 + ProcessTask processTask = this.getSecondTask(taskId, taskActorUserId); + if (processTask == null) { + return Result.error("未找到附议任务"); + } + + // 更新 proposal_second,记录当前附议人的最终附议结果、附议意见和附议时间。 ProposalSecond proposalSecond = dao.fetch( ProposalSecond.class, Cnd.where(ProposalSecond::getProposalId, "=", proposalId) .and(ProposalSecond::getSeconderId, "=", taskActorUserId) ); + if (proposalSecond == null) { + return Result.error("未找到附议记录"); + } proposalSecond.setIsAgree(ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.AGREE.getCode())); proposalSecond.setOpinion(opinion); + proposalSecond.setIsAgree(submitType == 1); proposalSecond.setSecondedTime(DateUtil.date()); dao.update(proposalSecond); - // 流程实例 - ProcessInstance processInstance = dao.fetch(ProcessInstance.class,Cnd.where(ProcessInstance::getBusinessNo, "=", proposalId)); - if(processInstance == null) return Result.success(); - - ProcessTask processTask = dao.fetch(ProcessTask.class,Cnd.where(ProcessTask::getProcessInstanceId, "=", processInstance.getId()) - .and(ProcessTask::getTaskName, "=", "second") - .and(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.ABANDON.getCode()) - .and(new Static("id in (select processTaskId from wf_process_task_actor where actorId='" + taskActorUserId + "')")) - .limit(1,1)); - if(processTask == null) return Result.success(); - + // 仅更新本次附议对应的 wf_process_task,不推动实例、也不创建后续任务。 + View_user user = dao.fetch(View_user.class, Cnd.where(View_user::getId, "=", taskActorUserId)); + Dict taskArgs = Json.fromJson(Dict.class, processTask.getVariable()); + taskArgs.set("u_userId", user.getId()); + taskArgs.set("initiator", user.getId()); + taskArgs.set("initiatorName", user.getUsername()); + taskArgs.set("initiatorAccount", user.getLoginname()); + taskArgs.set("initiatorUnitId", user.getUnitId()); + taskArgs.set("initiatorUnitName", user.getUnitName()); + taskArgs.set("initiatorUnionId", user.getUnionId()); + taskArgs.set("initiatorUnionName", user.getUnionName()); + taskArgs.set("tf_loginName", user.getLoginname()); + taskArgs.set("tf_unionId", user.getUnionId()); + taskArgs.set("tf_unitId", user.getUnitId()); + taskArgs.set("tf_unitName", user.getUnitName()); + taskArgs.set("tf_userId", user.getId()); + taskArgs.set("tf_userName", user.getUsername()); + processTask.setVariable(JSONUtil.toJsonStr(taskArgs)); processTask.setTaskState(ProcessTaskStateEnum.FINISHED.getCode()); processTask.setFinishTime(DateUtil.date()); + processTask.setOperator(taskActorUserId); dao.update(processTask); return Result.success(); } + /** + * second 节点审核专用接口。 + * 参数说明: + * 1. data:前端提交的 JSON 字符串,必须包含 processTaskId、proposalId、taskActorUserId、tf_opinion、submitType。 + * 2. processTaskId:wf_process_task 主键,公共流程执行服务依赖该参数定位当前审核任务。 + * 3. proposalId:提案主键,附议业务表 proposal_second 通过该字段定位当前提案记录。 + * 4. taskActorUserId:附议人用户ID,用于定位当前登录人的附议记录。 + * 5. tf_opinion:审核意见,会同步写入流程表单变量和附议业务表 opinion 字段。 + * 6. submitType:审核结果,1 表示同意,20 表示不同意。 + * 返回值: + * Result.success() 表示公共流程任务执行成功且 proposal_second 已同步更新; + * Result.error(...) 表示请求参数不完整。 + */ + @At + @SaCheckPermission("proposal.seconded") + @Aop(TransAop.READ_COMMITTED) + @ApiOperation("执行附议审核任务") + @SLog(tag = "提案管理系统-附议提案", msg = "执行附议审核任务") + public Result executeTask(@Param("data") String data) { + if (Strings.isBlank(data)) { + return Result.error("参数错误"); + } + Dict args = Json.fromJson(Dict.class, data); + String proposalId = args.getStr("proposalId"); + String taskActorUserId = args.getStr("taskActorUserId"); + String opinion = args.getStr("tf_opinion"); + Integer submitType = args.getInt("submitType"); + if (args.getLong("processTaskId") == null || Strings.isBlank(proposalId) || Strings.isBlank(taskActorUserId) || submitType == null) { + return Result.error("参数错误"); + } + flowCommonService.executeTask(args); + proposalSecondedService.updateSecondRecord(proposalId, taskActorUserId, opinion, submitType); + return Result.success(); + } + + /** + * 根据当前点击的任务和附议人,定位实际需要完成的 second 节点任务。 + * 处理规则: + * 1. 如果页面点击的就是 second 节点任务,则直接更新该任务。 + * 2. 如果页面点击的是 invite、delegation、committee 等关联节点,则回查同实例下当前附议人的 second 任务。 + */ + private ProcessTask getSecondTask(Long taskId, String taskActorUserId) { + ProcessTask currentTask = dao.fetch(ProcessTask.class, taskId); + if (currentTask == null) { + return null; + } + if ("second".equals(currentTask.getTaskName()) + && List.of(ProcessTaskStateEnum.DOING.getCode(), ProcessTaskStateEnum.ABANDON.getCode()).contains(currentTask.getTaskState()) + && this.isTaskActorMatched(currentTask.getId(), taskActorUserId)) { + return currentTask; + } + + List secondTaskList = dao.query(ProcessTask.class, + Cnd.where(ProcessTask::getProcessInstanceId, "=", currentTask.getProcessInstanceId()) + .and(ProcessTask::getTaskName, "=", "second") + .and(ProcessTask::getTaskState, "in", List.of(ProcessTaskStateEnum.DOING.getCode(), ProcessTaskStateEnum.ABANDON.getCode())) + .desc(ProcessTask::getCreatedAt)); + for (ProcessTask secondTask : secondTaskList) { + if (this.isTaskActorMatched(secondTask.getId(), taskActorUserId)) { + return secondTask; + } + } + return null; + } + + /** + * 校验任务参与人是否为当前附议人,避免误更新其他代表的 second 任务。 + */ + private boolean isTaskActorMatched(Long processTaskId, String taskActorUserId) { + return dao.count(ProcessTaskActor.class, + Cnd.where(ProcessTaskActor::getProcessTaskId, "=", processTaskId) + .and(ProcessTaskActor::getActorId, "=", taskActorUserId)) > 0; + } + } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalWriteController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalWriteController.java index 4b8e8956..52f0da5e 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalWriteController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/transact/ProposalWriteController.java @@ -83,6 +83,7 @@ public class ProposalWriteController { @ApiOperation("保存提案") @SLog(tag = "提案管理系统-我的提案", msg = "保存提案") public Result save(@Param("info") ProposalInfo proposalInfo) { + proposalWriteService.checkCurrentUserDelegate(proposalInfo.getSessionId()); if (StrUtil.isBlank(proposalInfo.getCode())) { proposalInfo.setCode(proposalWriteService.generateProposalCode(proposalInfo.getSessionId(), proposalInfo.getDelegationId())); } @@ -98,6 +99,7 @@ public class ProposalWriteController { @ApiOperation("提交提案") @SLog(tag = "提案管理系统-我的提案", msg = "提交提案") public Result submit(@Param("info") ProposalInfo proposalInfo) { + proposalWriteService.checkCurrentUserDelegate(proposalInfo.getSessionId()); if (StrUtil.isBlank(proposalInfo.getCode())) { proposalInfo.setCode(proposalWriteService.generateProposalCode(proposalInfo.getSessionId(), proposalInfo.getDelegationId())); } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/listenter/ProposalCommitteeFilingRevokeEventListener.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/listenter/ProposalCommitteeFilingRevokeEventListener.java index 39ddf560..b0a77181 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/listenter/ProposalCommitteeFilingRevokeEventListener.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/listenter/ProposalCommitteeFilingRevokeEventListener.java @@ -1,19 +1,9 @@ package com.budwk.app.zhgh.democratic.proposal.listenter; -import cn.hutool.json.JSONObject; -import cn.hutool.json.JSONUtil; import com.budwk.app.flow.engine.event.ProcessEvent; import com.budwk.app.flow.engine.event.ProcessEventListener; -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.flow.service.ProcessInstanceService; -import com.budwk.app.zhgh.democratic.proposal.models.ProposalMerge; -import org.nutz.dao.Cnd; -import org.nutz.dao.Dao; -import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; -import org.nutz.lang.Lang; /** * @version 1.0 @@ -25,27 +15,11 @@ import org.nutz.lang.Lang; @IocBean public class ProposalCommitteeFilingRevokeEventListener implements ProcessEventListener { - @Inject - private Dao dao; - @Inject - private ProcessInstanceService processInstanceService; - @Override public void onEvent(ProcessEvent event) { if (event.getEventType() == ProcessEventTypeEnum.PROCESS_TASK_REVOKE) { - Long taskId = event.getSourceId(); - ProcessTask task = dao.fetch(ProcessTask.class, taskId); - ProcessInstance processInstance = processInstanceService.getById(task.getProcessInstanceId()); - - // 处理并案信息撤回 - if ("committee".equals(task.getTaskName())) { - // 如果有并案,删掉并案数据(傻逼提的需求,nmsl) - ProposalMerge proposalMerge = dao.fetch(ProposalMerge.class, Cnd.where("proposalId", "=", processInstance.getBusinessNo())); - - if (Lang.isNotEmpty(proposalMerge)) { - dao.clear(ProposalMerge.class, Cnd.where(ProposalMerge::getProposalId, "=", proposalMerge.getProposalId())); - } - } + // proposal_merge 的删除逻辑已统一收口到 ProposalCommitteeFilingServiceImpl.revokeTask, + // 这里不再重复处理业务表,避免事件监听和 service 两处口径不一致。 } } } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/param/ProposalQueryComprehensiveParam.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/param/ProposalQueryComprehensiveParam.java index da9ff171..5315291a 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/param/ProposalQueryComprehensiveParam.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/param/ProposalQueryComprehensiveParam.java @@ -77,7 +77,7 @@ public class ProposalQueryComprehensiveParam extends PageForm { if (Lang.isNotEmpty(searchParam.getSessionIds())) { cnd.and("info.sessionId", "in", searchParam.getSessionIds()); } else { - cnd.andEX("info.sessionId", "=", searchParam.getSessionId()); +// cnd.andEX("info.sessionId", "=", searchParam.getSessionId()); } //提案名称 diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/param/ProposalSearchParam.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/param/ProposalSearchParam.java index 2cca39d7..4694ac8b 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/param/ProposalSearchParam.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/param/ProposalSearchParam.java @@ -19,6 +19,7 @@ public class ProposalSearchParam extends PageForm { private String code; private String sessionId; private String delegationId; + private String unionId; private String createUserName; private String createUserLoginName; private String createUserKeyword; diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalSecondedService.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalSecondedService.java index 2bc7b9ed..fcef3ce8 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalSecondedService.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalSecondedService.java @@ -5,5 +5,13 @@ import com.budwk.app.zhgh.democratic.proposal.models.ProposalSecond; public interface ProposalSecondedService extends BaseService { - + /** + * 仅更新附议表 proposal_second 中当前附议人的附议结果。 + * 参数说明: + * 1. proposalId:提案ID,用于定位当前提案的附议记录。 + * 2. taskActorUserId:附议人用户ID,用于定位当前登录人的附议记录。 + * 3. opinion:附议意见,写入附议记录的 opinion 字段。 + * 4. submitType:附议结果,1 表示同意,20 表示不同意。 + */ + void updateSecondRecord(String proposalId, String taskActorUserId, String opinion, Integer submitType); } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalWriteService.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalWriteService.java index 2dc013b2..10a932c4 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalWriteService.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/ProposalWriteService.java @@ -22,5 +22,15 @@ public interface ProposalWriteService extends BaseService { List listSourceByCode(@Valid String code); + /** + * 校验当前登录用户在指定教代会届次下是否具备代表身份。 + * 参数说明: + * 1. sessionId:教代会届次ID,保存和提交提案时通过该字段定位当前届次代表信息。 + * 返回值说明: + * 1. 校验通过时无返回值。 + * 2. 校验不通过时抛出业务异常,由上层统一返回提示信息。 + */ + void checkCurrentUserDelegate(String sessionId); + ProposalInfo importProposal(Map stringStringMap); } 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 14b5fc0f..00dc0c2f 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 @@ -234,10 +234,10 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp // 提案附议 List secondInfos = new ArrayList<>(); List secondTaskVos = taskGroups.get("提案附议"); - if(secondTaskVos != null && secondTaskVos.size() > 0) { + if (secondTaskVos != null && secondTaskVos.size() > 0) { for (ProcessTaskVO secondTaskVO : secondTaskVos) { Dict taskFormData = secondTaskVO.getTaskFormData(); - if(taskFormData == null) { + if (taskFormData == null) { continue; } NutMap secondInfo = new NutMap(); @@ -248,7 +248,7 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp taskUserSql.setCallback(Sqls.callback.map()); execute(taskUserSql); NutMap taskUserMap = (NutMap) taskUserSql.getResult(); - secondInfo.put("s_mobile", taskUserMap.getString("mobile")); + secondInfo.put("s_mobile", Objects.isNull(taskUserMap) ? "" : taskUserMap.getString("mobile")); secondInfos.add(secondInfo); } } @@ -256,10 +256,10 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp // 代表团意见 List delegationAuditList = new ArrayList<>(); List delegationTaskVos = taskGroups.get("团长审核"); - if(delegationTaskVos != null && delegationTaskVos.size() > 0) { + if (delegationTaskVos != null && delegationTaskVos.size() > 0) { for (ProcessTaskVO delegationTaskVO : delegationTaskVos) { Dict taskFormData = delegationTaskVO.getTaskFormData(); - if(taskFormData == null) { + if (taskFormData == null) { continue; } @@ -601,10 +601,10 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp List caseUnitList = listMap(caseUnitSql); for (NutMap v : caseUnitList) { String hostUnitName = v.getString("masterUnitName"); - if (StrUtil.isNotBlank(hostUnitName)){ + if (StrUtil.isNotBlank(hostUnitName)) { underTakeNames.add(hostUnitName); } - if (StrUtil.isNotBlank(v.getString("slaveUnitNames"))){ + if (StrUtil.isNotBlank(v.getString("slaveUnitNames"))) { List helpUnitNames = Arrays.asList(v.getString("slaveUnitNames").split("、")); underTakeNames.addAll(helpUnitNames); } @@ -725,73 +725,73 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp String proposalMeasures = MapUtil.getStr(dataMap, "建议措施", ""); // 工号 - if(StrUtil.isBlank(loginName)) { + if (StrUtil.isBlank(loginName)) { throw new RuntimeException("工号不能为空"); } Sys_user user = sysUserService.getByLoginName(loginName); - if(user == null){ + if (user == null) { throw new RuntimeException("工号不存在"); } - if(StrUtil.isNotBlank(username) && !username.equals(user.getUsername())) { + if (StrUtil.isNotBlank(username) && !username.equals(user.getUsername())) { throw new RuntimeException("工号和提案人不一致"); } // 提案时间 - if(StrUtil.isBlank(proposalDate)) { + if (StrUtil.isBlank(proposalDate)) { throw new RuntimeException("提案时间不能为空"); } // 提案类型 - if(StrUtil.isBlank(proposalType)) { + if (StrUtil.isBlank(proposalType)) { throw new RuntimeException("提案类型不能为空"); } ProposalType proposalTypeObj = dao().fetch(ProposalType.class, Cnd.where(ProposalType::getName, "=", proposalType)); - if(proposalTypeObj == null) { + if (proposalTypeObj == null) { throw new RuntimeException("提案类型不存在"); } // 提案方式 - if(StrUtil.isBlank(proposalSource)) { + if (StrUtil.isBlank(proposalSource)) { throw new RuntimeException("提案方式不能为空"); } Sys_dict dict = sysDictService.fetch(Cnd.where("code", "=", "PROPOSAL_SOURCE")); - if(dict == null) { + if (dict == null) { throw new RuntimeException("提案方式字典配置不存在"); } List sysDicts = sysDictService.query(Cnd.where("parentId", "=", Strings.sNull(dict.getId())).asc("location")); - if(sysDicts == null || sysDicts.size() == 0) { + if (sysDicts == null || sysDicts.size() == 0) { throw new RuntimeException("提案方式字典配置不存在"); } Sys_dict proposalSourceDict = sysDicts.stream().filter(v -> v.getName().equals(proposalSource)).findFirst().orElse(null); - if(proposalSourceDict == null) { + if (proposalSourceDict == null) { throw new RuntimeException("提案方式不存在"); } // 提案名称 - if(StrUtil.isBlank(proposalName)) { + if (StrUtil.isBlank(proposalName)) { throw new RuntimeException("提案名称不能为空"); } // 案由 - if(StrUtil.isBlank(proposalContent)) { + if (StrUtil.isBlank(proposalContent)) { throw new RuntimeException("案由不能为空"); } // 建议措施 - if(StrUtil.isBlank(proposalMeasures)) { + if (StrUtil.isBlank(proposalMeasures)) { throw new RuntimeException("建议措施不能为空"); } // 判断当前导入用户是否是代表 Teacher_congress_delegate delegate = teacherCongressDelegateService.fetch(Cnd.where(Teacher_congress_delegate::getUserId, "=", SecurityUtil.getUserId()) .and(Teacher_congress_delegate::getDelFlag, "!=", 1).limit(1)); - if(delegate == null) { + if (delegate == null) { throw new RuntimeException("当前用户不是代表"); } // 教代会 List teacherCongressSessions = this.dao().query(Teacher_congress_session.class, Cnd.where("enable", "=", 1).desc("startDate")); - if(teacherCongressSessions == null || teacherCongressSessions.size() <= 0) { + if (teacherCongressSessions == null || teacherCongressSessions.size() <= 0) { throw new RuntimeException("没有开启的教代会"); } Teacher_congress_session teacherCongressSession = teacherCongressSessions.get(0); 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 8adcdd63..34b0f4e5 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 @@ -83,6 +83,9 @@ public class ProposalCommitteeFilingServiceImpl extends BaseServiceImpl implements ProposalSecondedService { - @Inject - private CommonService commonService; - public ProposalSecondedServiceImpl(Dao dao) { super(dao); } + @Override + public void updateSecondRecord(String proposalId, String taskActorUserId, String opinion, Integer submitType) { + if (Strings.isBlank(proposalId) || Strings.isBlank(taskActorUserId) || submitType == null) { + return; + } + // 仅更新当前提案、当前附议人的附议结果,不处理流程任务表。 + ProposalSecond proposalSecond = this.fetch(Cnd.where(ProposalSecond::getProposalId, "=", proposalId) + .and(ProposalSecond::getSeconderId, "=", taskActorUserId)); + if (proposalSecond == null) { + return; + } + proposalSecond.setIsAgree(ObjectUtil.equals(submitType, ProcessSubmitTypeEnum.AGREE.getCode())); + proposalSecond.setOpinion(opinion); + proposalSecond.setSecondedTime(DateUtil.date()); + this.update(proposalSecond); + } } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalWriteServiceImpl.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalWriteServiceImpl.java index f28a1798..e559478f 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalWriteServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/impl/ProposalWriteServiceImpl.java @@ -121,6 +121,23 @@ public class ProposalWriteServiceImpl extends BaseServiceImpl impl return dict == null ? new ArrayList<>() : sysDictService.query(Cnd.where("parentId", "=", Strings.sNull(dict.getId())).asc("location")); } + @Override + public void checkCurrentUserDelegate(String sessionId) { + if (StrUtil.isBlank(sessionId)) { + throw new RuntimeException("所属教代会不能为空"); + } + // 撰写提案必须绑定当前届次代表身份,避免非代表用户保存或提交提案。 + Teacher_congress_delegate delegate = teacherCongressDelegateService.fetch( + Cnd.where(Teacher_congress_delegate::getSessionId, "=", sessionId) + .and(Teacher_congress_delegate::getUserId, "=", SecurityUtil.getUserId()) + .and(Teacher_congress_delegate::getDelFlag, "!=", 1) + .limit(1) + ); + if (delegate == null) { + throw new RuntimeException("当前用户不是代表,无法撰写提案"); + } + } + @Override public ProposalInfo importProposal(Map dataMap) { String loginName = MapUtil.getStr(dataMap, "工号", ""); diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundApplyController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundApplyController.java index 308241b0..e258993a 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundApplyController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundApplyController.java @@ -129,7 +129,8 @@ public class AidFundApplyController { } //如果有两个工号并且有一个工号已经是会员就不让他申请了 if (userList.size() >= 2) { - int size = userList.stream().filter(Sys_user::getAidFundMember).toList().size(); + // 历史用户数据中 aidFundMember 可能为空,这里只统计明确为基金会员的工号,避免空值自动拆箱报错 + int size = userList.stream().filter(sysUser -> Boolean.TRUE.equals(sysUser.getAidFundMember())).toList().size(); if (size > 0) { return Result.success(Map.of("disabled", true, "label", "请用新工号登陆办理申请业务!")); } @@ -149,7 +150,7 @@ public class AidFundApplyController { aidFundMemberChangeRecord.setUserId(SecurityUtil.getUserId()); Sys_user user = dao.fetch(Sys_user.class, SecurityUtil.getUserId()); if (StrUtil.isBlank(aidFundMemberChangeRecord.getId())) aidFundMemberChangeRecord.setApplyTime(new Date()); - if (user.getAidFundMember() == AidFundMemberMode.NORMAL.getCode()) { + if (Boolean.TRUE.equals(user.getAidFundMember())) { aidFundMemberChangeRecord.setChangeType("AIDFUND_MEMBER_CHANGE_TYPE_FOUR"); } else { aidFundMemberChangeRecord.setChangeType("AIDFUND_MEMBER_CHANGE_TYPE_ONE"); @@ -159,7 +160,8 @@ public class AidFundApplyController { Dict args = Dict.create(); args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode()); args.set(FlowConst.FORM_DATA, aidFundMemberChangeRecord); - args.set("aidFundMemberUserType", user.getAidFundMemberUserType()); + // 流程变量中的基金会员类型以本次申请提交值为准,避免继续使用用户表中的旧值。 + args.set("aidFundMemberUserType", aidFundMemberChangeRecord.getAidFundMemberUserType()); ProcessInstance instance = flowEngine.startProcessInstanceByKey("JJHY", aidFundMemberChangeRecord.getId(), SecurityUtil.getUserId(), args); // 自动完成第一个申请任务 @@ -194,7 +196,7 @@ public class AidFundApplyController { us.username, us.loginname, us.mobile, - us.aidFundMemberUserType, + IFNULL(info.aidFundMemberUserType, us.aidFundMemberUserType) aidFundMemberUserType, us.arrivalAtSchoolDate, us.sex, us.unitName, diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundApplyMineController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundApplyMineController.java index 5b6c73e2..c1ffc7ee 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundApplyMineController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundApplyMineController.java @@ -76,14 +76,17 @@ public class AidFundApplyMineController { @Param(value = "year") Integer year) { Sql sql = Sqls.create(""" SELECT - info.*, + info.id, + info.userId, + info.changeType, + info.applyTime, us.arrivalAtSchoolDate, us.mobile, us.loginname loginName, us.username userName, us.unitName, us.unionName, - us.aidFundMemberUserType, + IFNULL(info.aidFundMemberUserType, us.aidFundMemberUserType) aidFundMemberUserType, us.sex, ins.id AS instanceId, ins.businessNo, @@ -113,6 +116,8 @@ public class AidFundApplyMineController { cnd.andEX("year(info.applyTime)", "=", year); cnd.and("info.userId", "=", SecurityUtil.getUserId()); + // 管理端代操作产生的记录不属于“我的申请”,历史空值按普通申请处理。 + cnd.andEX("IFNULL(info.adminOperate, 0)", "=", 0); if (StrUtil.isNotBlank(pageForm.getPageOrderName()) && StrUtil.isNotBlank(pageForm.getPageOrderBy())) { cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundChangeRecordController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundChangeRecordController.java index 28e5ec28..b0f9a489 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundChangeRecordController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundChangeRecordController.java @@ -58,7 +58,6 @@ public class AidFundChangeRecordController { us.mobile, us.unitName, us.unionName, - us.aidFundMemberUserType, ins.id AS instanceId, ins.businessNo, ins.state instanceState, diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundFoundationAuditController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundFoundationAuditController.java index e0f9599f..ec1d646f 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundFoundationAuditController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundFoundationAuditController.java @@ -1,24 +1,24 @@ package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.controller; +import cn.afterturn.easypoi.excel.ExcelExportUtil; +import cn.afterturn.easypoi.excel.entity.ExportParams; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; +import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaMode; import cn.hutool.core.util.StrUtil; import com.budwk.app.base.annotation.SLog; 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.utils.PageUtil; -import com.budwk.app.flow.enums.ProcessTaskStateEnum; -import com.budwk.app.web.commons.auth.utils.SecurityUtil; +import com.budwk.app.base.utils.CommonDownloadUtil; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.param.AidFundPageForm; import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.service.AidFundMemberChangeRecordService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.Workbook; import org.nutz.aop.interceptor.ioc.TransAop; -import org.nutz.dao.Cnd; -import org.nutz.dao.Sqls; import org.nutz.dao.sql.Sql; -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; @@ -27,6 +27,8 @@ import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Param; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; import java.util.List; /** @@ -44,8 +46,6 @@ public class AidFundFoundationAuditController { @Inject private AidFundMemberChangeRecordService changeRecordService; - - @At("") @Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/aidFund/foundationAudit/index.html") @SaCheckPermission("medicalMutualAid.aidFund.foundationAudit") @@ -61,79 +61,8 @@ public class AidFundFoundationAuditController { @At @ApiOperation("分页查询") @SaCheckPermission(value = {"medicalMutualAid.aidFund.foundationAudit", "h5.medicalMutualAid.aidFund.foundationAudit"}, mode = SaMode.OR) - public Result pageData(PageForm pageForm, - @Param(value = "year") Integer year, - @Param(value = "aidFundMemberUserType") String aidFundMemberUserType, - @Param(value = "unionId") String unionId, - @Param(value = "unitId") String unitId, - @Param(value = "changeType") String changeType, - @Param(value = "approval") Boolean approval) { - Sql sql = Sqls.create(""" - SELECT - info.*, - us.arrivalAtSchoolDate, - us.mobile, - us.loginname loginName, - us.username userName, - us.unitName, - us.unionName, - us.aidFundMemberUserType, - us.sex, - ins.id AS instanceId, - ins.businessNo, - 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, - IF(rt.id IS NOT NULL, 1, 0) AS canRevoke - FROM - wf_process_task t - LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId - LEFT JOIN aid_fund_member_change_record info ON info.id = ins.businessNo - LEFT JOIN vw_user us ON us.id = info.userId - 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 wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10 - $condition - """); - Cnd cnd = Cnd.NEW(); - if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) { - SqlExpressionGroup seg = new SqlExpressionGroup(); - seg.or("us.loginname", "like", "%" + pageForm.getSearchKeyword() + "%"); - seg.or("us.username", "like", "%" + pageForm.getSearchKeyword() + "%"); - cnd.and(seg); - } - cnd.andEX("YEAR(info.applyTime)", "=", year); - cnd.andEX("us.aidFundMemberUserType", "=", aidFundMemberUserType); - cnd.andEX("us.unionId", "=", unionId); - cnd.andEX("us.unitId", "=", unitId); - cnd.andEX("info.changeType", "=", changeType); - - cnd.and("t.taskName", "=", "85c7d148-44f5-4333-b854-ab225357fd3e"); - 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()); - } - - if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) { - cnd.desc("info.applyTime"); - } else { - cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); - } - cnd.groupBy("t.id"); - sql.setCondition(cnd); + public Result pageData(AidFundPageForm pageForm) { + Sql sql = changeRecordService.getFoundationAuditSql(pageForm); Pagination pageVO = changeRecordService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); List list = pageVO.getList(); @@ -144,6 +73,39 @@ public class AidFundFoundationAuditController { return Result.success(pageVO); } + /** + * 导出互管会审核页面申请记录。 + * + * @param pageForm 页面筛选参数,和列表页查询条件保持一致 + * @param response HTTP 响应对象,用于输出 Excel 文件流 + */ + @At + @Ok("void") + @ApiOperation("导出申请记录") + @SaCheckPermission(value = {"medicalMutualAid.aidFund.foundationAudit", "h5.medicalMutualAid.aidFund.foundationAudit"}, mode = SaMode.OR) + public void exportApplyRecord(AidFundPageForm pageForm, HttpServletResponse response) { + List listMap = changeRecordService.getFoundationAuditExportList(pageForm); + List entityList = new ArrayList<>(); + entityList.add(new ExcelExportEntity("工号", "loginName", 20)); + entityList.add(new ExcelExportEntity("姓名", "userName", 20)); + entityList.add(new ExcelExportEntity("性别", "sex", 15)); + entityList.add(new ExcelExportEntity("电话", "mobile", 20)); + entityList.add(new ExcelExportEntity("工会", "unionName", 20)); + entityList.add(new ExcelExportEntity("单位", "unitName", 20)); + entityList.add(new ExcelExportEntity("入校时间", "arrivalAtSchoolDate", 20)); + entityList.add(new ExcelExportEntity("基金会员类型", "aidFundMemberUserType", 20)); + entityList.add(new ExcelExportEntity("缴纳金额", "money", 20)); + entityList.add(new ExcelExportEntity("变更类型", "changeType", 20)); + entityList.add(new ExcelExportEntity("申请时间", "applyTime", 20)); + entityList.add(new ExcelExportEntity("审核状态", "approvalStatus", 20)); + + ExportParams exportParams = new ExportParams(); + exportParams.setType(ExcelType.XSSF); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, listMap); + String fileName = (pageForm.getYear() == null ? "" : pageForm.getYear()) + "基金会员审核记录.xlsx"; + CommonDownloadUtil.download(fileName, workbook, response); + } + @At @ApiOperation("查询需要缴费多少") @SaCheckPermission(value = {"medicalMutualAid.aidFund.foundationAudit", "h5.medicalMutualAid.aidFund.foundationAudit"}, mode = SaMode.OR) @@ -163,4 +125,23 @@ public class AidFundFoundationAuditController { return Result.success(); } + /** + * 批量审核互管会待办记录。 + * + * @param param 统一的审批参数,包含审批意见和审核动作 + * @param ids 勾选的申请记录 ID 数组 + * @return 批量审核结果统计 + */ + @At + @SLog(tag = "基金会员", msg = "互管会批量审核基金会员记录") + @Aop(TransAop.READ_COMMITTED) + @ApiOperation("批量审核") + @SaCheckPermission(value = {"medicalMutualAid.aidFund.foundationAudit", "h5.medicalMutualAid.aidFund.foundationAudit"}, mode = SaMode.OR) + public Result batchExecuteTask(@Param("data") String param, @Param("ids") String[] ids) { + if (ids == null || ids.length == 0 || StrUtil.isBlank(param)) { + return Result.error("参数错误"); + } + return Result.success(changeRecordService.batchExecuteTask(param, ids)); + } + } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundManageController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundManageController.java index c16b2101..f18bbc1d 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundManageController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundManageController.java @@ -10,18 +10,12 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.budwk.app.base.annotation.SLog; -import com.budwk.app.base.constant.RoleConstant; 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.utils.CommonDownloadUtil; -import com.budwk.app.base.utils.PageUtil; import com.budwk.app.sys.models.Sys_user; -import com.budwk.app.sys.models.Sys_user_role; import com.budwk.app.sys.services.SysUserService; import com.budwk.app.sys.views.View_user; -import com.budwk.app.web.commons.auth.utils.AuthUtil; -import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.mode.AidFundMemberMode; import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.model.AidFundMemberChangeRecord; import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.param.AidFundPageForm; @@ -35,7 +29,6 @@ import org.nutz.dao.Chain; import org.nutz.dao.Cnd; import org.nutz.dao.Sqls; import org.nutz.dao.sql.Sql; -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; @@ -79,55 +72,32 @@ public class AidFundManageController { @ApiOperation("分页查询") @SaCheckPermission("medicalMutualAid.aidFund.manage") public Result pageData(AidFundPageForm pageForm) { - Sql sql = Sqls.create(""" - SELECT - id, - loginname, - username, - sex, - arrivalAtSchoolDate, - unitName, - unionName, - aidFundMemberUserType, - aidFundMemberJoinTime - FROM - vw_user - $condition - """); - Cnd cnd = Cnd.NEW(); - if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name())) { - if (AuthUtil.hasRole(RoleConstant.RETIREMENT_WORKPLACE.name())) { - cnd.and(Sys_user::getAidFundMemberUserType, "=", "离退休人员"); - } else { - cnd.and(View_user::getUnionId, "=", SecurityUtil.getUnionId()); - } - } - - if (pageForm.getNotPayedCurrentYear()) { - cnd.and("id", "in", Sqls.create("SELECT userid FROM `aid_fund_member_pay` where `year` = YEAR(CURDATE()) and isPayed = 0")); - } - cnd.andEX(Sys_user::getAidFundMemberUserType, "=", pageForm.getAidFundMemberUserType()); - cnd.andEX(View_user::getUnionId, "=", pageForm.getUnionId()); - cnd.andEX(View_user::getUnitId, "=", pageForm.getUnitId()); - sql.setCondition(cnd); - cnd.and(Sys_user::getAidFundMember, "=", AidFundMemberMode.NORMAL.getCode()); - - if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) { - SqlExpressionGroup seg = new SqlExpressionGroup(); - seg.orLike("loginname", pageForm.getSearchKeyword()); - seg.orLike("username", pageForm.getSearchKeyword()); - cnd.and(seg); - } - if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) { - cnd.desc("unitCode"); - } else { - cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); - } - sql.setCondition(cnd); - Pagination pagination = userService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + Sql sql = aidFundMemberService.getManageSql(pageForm); + Pagination pagination = aidFundMemberService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); return Result.success(pagination); } + @At + @SaCheckPermission("medicalMutualAid.aidFund.manage") + @Ok("void") + @ApiOperation("导出会员名单") + public void exportMemberList(AidFundPageForm pageForm, HttpServletResponse response) { + List listMap = aidFundMemberService.listMap(aidFundMemberService.getManageSql(pageForm)); + + List entityList = new ArrayList<>(); + entityList.add(new ExcelExportEntity("姓名", "username", 20)); + entityList.add(new ExcelExportEntity("工号", "loginname", 20)); + entityList.add(new ExcelExportEntity("性别", "sex", 20)); + entityList.add(new ExcelExportEntity("会员类型", "aidFundMemberUserType", 20)); + entityList.add(new ExcelExportEntity("单位", "unitName", 20)); + entityList.add(new ExcelExportEntity("工会", "unionName", 20)); + + ExportParams exportParams = new ExportParams(); + exportParams.setType(ExcelType.XSSF); + Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, listMap); + CommonDownloadUtil.download("会员名单.xlsx", workbook, response); + } + @At @SaCheckPermission("medicalMutualAid.aidFund.manage") @@ -198,9 +168,12 @@ public class AidFundManageController { return Result.error("请选择要退会的人员"); } List recordArrayList = new ArrayList<>(); + List sysUserList = userService.query(Cnd.where("id", "in", ids)); for (String id : ids) { + Sys_user user = sysUserList.stream().filter(sysUser -> sysUser.getId().equals(id)).findFirst().orElse(null); AidFundMemberChangeRecord record = new AidFundMemberChangeRecord() .setUserId(id) + .setAidFundMemberUserType(user.getAidFundMemberUserType()) .setApplyTime(new Date()) .setChangeType("AIDFUND_MEMBER_CHANGE_TYPE_SEVEN"); recordArrayList.add(record); @@ -220,25 +193,7 @@ public class AidFundManageController { if (ObjectUtil.isEmpty(ids) || StrUtil.isBlank(changeType)) { return Result.error("参数错误"); } - List recordArrayList = new ArrayList<>(); - for (String id : ids) { - AidFundMemberChangeRecord record = new AidFundMemberChangeRecord() - .setUserId(id) - .setApplyTime(new Date()) - .setChangeType(changeType); - recordArrayList.add(record); - } - Chain add; - if (changeType.equals("AIDFUND_MEMBER_CHANGE_TYPE_EIGTH")) { - //会员退休 - add = Chain.make("aidFundMemberUserType", "离退休人员"); - } else { - add = Chain.make("aidFundMember", AidFundMemberMode.NONE.getCode()) - .add("aidFundMemberQuitTime", new Date()); - } - - userService.update(add, Cnd.where("id", "in", ids)); - userService.insert(recordArrayList); + aidFundMemberService.doBatchChangeTypeByAdmin(ids, changeType); return Result.success(); } @@ -258,21 +213,10 @@ public class AidFundManageController { @ApiOperation("变更基金会员") @Aop(TransAop.READ_COMMITTED) public Result doEditChangeType(String userId, String changeType) { - AidFundMemberChangeRecord record = new AidFundMemberChangeRecord() - .setUserId(userId) - .setApplyTime(new Date()) - .setChangeType(changeType); - aidFundMemberService.insert(record); - Chain add; - if (changeType.equals("AIDFUND_MEMBER_CHANGE_TYPE_EIGTH")) { - //会员退休 - add = Chain.make("aidFundMemberUserType", "离退休人员"); - } else { - add = Chain.make("aidFundMember", AidFundMemberMode.NONE.getCode()) - .add("aidFundMemberQuitTime", new Date()); + if (StrUtil.isBlank(userId) || StrUtil.isBlank(changeType)) { + return Result.error("参数错误"); } - - userService.update(add, Cnd.where("id", "=", userId)); + aidFundMemberService.doEditChangeTypeByAdmin(userId, changeType); return Result.success(); } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundRetirementAuditController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundRetirementAuditController.java index 8f445701..57a2dc6c 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundRetirementAuditController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundRetirementAuditController.java @@ -63,14 +63,17 @@ public class AidFundRetirementAuditController { @Param(value = "approval") Boolean approval) { Sql sql = Sqls.create(""" SELECT - info.*, + info.id, + info.userId, + info.changeType, + info.applyTime, us.arrivalAtSchoolDate, us.mobile, us.loginname loginName, us.username userName, us.unitName, us.unionName, - us.aidFundMemberUserType, + IFNULL(info.aidFundMemberUserType, us.aidFundMemberUserType) aidFundMemberUserType, us.sex, ins.id AS instanceId, ins.businessNo, @@ -106,7 +109,7 @@ public class AidFundRetirementAuditController { cnd.and(seg); } cnd.andEX("YEAR(info.applyTime)", "=", year); - cnd.andEX("us.aidFundMemberUserType", "=", aidFundMemberUserType); + cnd.andEX("IFNULL(info.aidFundMemberUserType, us.aidFundMemberUserType)", "=", aidFundMemberUserType); cnd.andEX("info.changeType", "=", changeType); cnd.and("t.taskName", "=", "f756c818-6bb7-4f50-b8fa-24390fc7b0b8"); diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundUnionAuditController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundUnionAuditController.java index d051b2ff..b93013db 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundUnionAuditController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/controller/AidFundUnionAuditController.java @@ -65,14 +65,17 @@ public class AidFundUnionAuditController { @Param(value = "approval") Boolean approval) { Sql sql = Sqls.create(""" SELECT - info.*, + info.id, + info.userId, + info.changeType, + info.applyTime, us.arrivalAtSchoolDate, us.mobile, us.loginname loginName, us.username userName, us.unitName, us.unionName, - us.aidFundMemberUserType, + IFNULL(info.aidFundMemberUserType, us.aidFundMemberUserType) aidFundMemberUserType, us.sex, ins.id AS instanceId, ins.businessNo, @@ -108,7 +111,7 @@ public class AidFundUnionAuditController { cnd.and(seg); } cnd.andEX("YEAR(info.applyTime)", "=", year); - cnd.andEX("us.aidFundMemberUserType", "=", aidFundMemberUserType); + cnd.andEX("IFNULL(info.aidFundMemberUserType, us.aidFundMemberUserType)", "=", aidFundMemberUserType); cnd.andEX("info.changeType", "=", changeType); cnd.and("t.taskName", "=", "06ed1d6d-5f96-485f-9150-ed1ef4a082d6"); diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/model/AidFundMemberChangeRecord.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/model/AidFundMemberChangeRecord.java index 50fa6d65..fe7b555d 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/model/AidFundMemberChangeRecord.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/model/AidFundMemberChangeRecord.java @@ -38,10 +38,20 @@ public class AidFundMemberChangeRecord extends BaseModel { @ColDefine(type = ColType.VARCHAR, width = 50) private String changeType; + @Column + @Comment("申请时选择的基金会员类型(dict)") + @ColDefine(type = ColType.VARCHAR, width = 50) + private String aidFundMemberUserType; + @Column @Comment("申请时间") @ColDefine(type = ColType.DATETIME) private Date applyTime; + @Column + @Comment("是否系统管理员操作") + @ColDefine(type = ColType.BOOLEAN) + private Boolean adminOperate; + } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/param/AidFundPageForm.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/param/AidFundPageForm.java index 97dc5ab8..a7c89000 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/param/AidFundPageForm.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/param/AidFundPageForm.java @@ -22,6 +22,9 @@ public class AidFundPageForm extends PageForm { private String changeType; private Integer year; + //是否已审核 + private Boolean approval; + //是否扣款null全部、1已缴费、0未缴费 private Integer isPayed; } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/service/AidFundMemberChangeRecordService.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/service/AidFundMemberChangeRecordService.java index c4a58e38..eb1160ce 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/service/AidFundMemberChangeRecordService.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/service/AidFundMemberChangeRecordService.java @@ -1,6 +1,8 @@ package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.service; import com.budwk.app.base.service.BaseService; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.param.AidFundPageForm; +import org.nutz.dao.sql.Sql; import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.model.AidFundMemberChangeRecord; import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.model.AidFundMemberPay; import org.nutz.lang.util.NutMap; @@ -9,10 +11,53 @@ import java.util.List; public interface AidFundMemberChangeRecordService extends BaseService { + /** + * 构建互管会审核页面查询 SQL。 + * + * @param pageForm 页面筛选参数,包含年度、姓名/工号、工会、单位、会员类型、变更类型和审核状态 + * @return 可直接用于分页或导出的查询 SQL + */ + Sql getFoundationAuditSql(AidFundPageForm pageForm); + /** + * 查询互管会审核页面导出数据。 + * + * @param pageForm 页面筛选参数,和列表页保持一致 + * @return 导出所需的列表数据,每条记录对应一条基金会员变更申请 + */ + List getFoundationAuditExportList(AidFundPageForm pageForm); + + /** + * 执行流程审核动作。 + * + * @param param 流程提交参数 JSON,包含提交流程所需的任务、意见和业务字段 + * @param id 基金会员变更记录 ID + */ void executeTask( String param, String id); + /** + * 批量执行互管会审核任务。 + * + * @param param 流程提交参数 JSON,包含统一的审批意见和提交类型 + * @param ids 选中的基金会员变更记录 ID 数组 + * @return 批量审核结果,包含成功数、失败数和失败原因 + */ + NutMap batchExecuteTask(String param, String[] ids); + /** + * 计算基金会员应补缴金额。 + * + * @param arrivalAtSchoolDate 入校时间,格式为 yyyy-MM-dd + * @param userId 用户 ID,空值时默认取当前登录人 + * @return 当前规则下计算出的应缴金额 + */ int getPayMoney(String arrivalAtSchoolDate,String userId); + + /** + * 查询用户历年缴费记录。 + * + * @param userId 用户 ID,空值时默认取当前登录人 + * @return 用户及其旧工号对应的缴费记录列表 + */ List getUserPayRecordList(String userId); } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/service/AidFundMemberService.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/service/AidFundMemberService.java index 106c9699..1c96c372 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/service/AidFundMemberService.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/service/AidFundMemberService.java @@ -2,6 +2,8 @@ package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.service; import com.budwk.app.base.service.BaseService; import com.budwk.app.sys.models.Sys_user; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.param.AidFundPageForm; +import org.nutz.dao.sql.Sql; import org.nutz.lang.util.NutMap; import java.util.List; @@ -31,5 +33,30 @@ public interface AidFundMemberService extends BaseService { Double getPayMoney(Sys_user user, Integer year); + /** + * 获取基金会员台账列表查询SQL。 + * + * @param pageForm 页面查询条件,包含会员类型、工会、单位、关键字、排序及未缴费筛选参数 + * @return 与基金会员台账页面一致的查询SQL + */ + Sql getManageSql(AidFundPageForm pageForm); + + List findChangeRecordList(String userId); + + /** + * 管理端批量变更基金会员状态,并记录“系统管理员操作”来源。 + * + * @param ids 需要变更的用户ID数组,来自台账页面勾选行 + * @param changeType 变更类型字典值,对应 AIDFUND_MEMBER_CHANGE_TYPE + */ + void doBatchChangeTypeByAdmin(String[] ids, String changeType); + + /** + * 管理端对单个用户执行“变更”操作,并记录“系统管理员操作”来源。 + * + * @param userId 被变更的用户ID + * @param changeType 变更类型字典值,对应 AIDFUND_MEMBER_CHANGE_TYPE + */ + void doEditChangeTypeByAdmin(String userId, String changeType); } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/service/impl/AidFundMemberChangeRecordServiceImpl.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/service/impl/AidFundMemberChangeRecordServiceImpl.java index 9e0fb920..f34337a8 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/service/impl/AidFundMemberChangeRecordServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/service/impl/AidFundMemberChangeRecordServiceImpl.java @@ -3,20 +3,34 @@ package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.service.impl; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.base.service.impl.BaseServiceImpl; +import com.budwk.app.base.utils.PageUtil; +import com.budwk.app.flow.constant.FlowConst; +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.flow.service.FlowCommonService; +import com.budwk.app.flow.service.ProcessTaskService; import com.budwk.app.sys.models.Sys_user; +import com.budwk.app.sys.services.SysDictService; +import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.mode.AidFundMemberMode; import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.model.AidFundMemberChangeRecord; import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.model.AidFundMemberPay; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.param.AidFundPageForm; import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.service.AidFundMemberChangeRecordService; 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.SqlExpressionGroup; import org.nutz.ioc.aop.Aop; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; @@ -33,6 +47,9 @@ import java.util.*; */ @IocBean(args = {"refer:dao"}) public class AidFundMemberChangeRecordServiceImpl extends BaseServiceImpl implements AidFundMemberChangeRecordService { + private static final String FOUNDATION_AUDIT_TASK_NAME = "85c7d148-44f5-4333-b854-ab225357fd3e"; + private static final String CHANGE_TYPE_JOIN = "AIDFUND_MEMBER_CHANGE_TYPE_ONE"; + public AidFundMemberChangeRecordServiceImpl(Dao dao) { super(dao); } @@ -41,21 +58,228 @@ public class AidFundMemberChangeRecordServiceImpl extends BaseServiceImpl getFoundationAuditExportList(AidFundPageForm pageForm) { + List list = listMap(getFoundationAuditSql(pageForm)); + Map memberTypeMap = getDictNameMap("AIDFUND_MEMBER_USER_TYPE"); + Map changeTypeMap = getDictNameMap("AIDFUND_MEMBER_CHANGE_TYPE"); + list.forEach(map -> { + String arrivalAtSchoolDate = map.getString("arrivalAtSchoolDate"); + String changeType = map.getString("changeType"); + map.put("approvalStatus", ObjectUtil.equals(map.getInt("taskState"), ProcessTaskStateEnum.DOING.getCode()) ? "未审核" : "已审核"); + map.put("aidFundMemberUserType", memberTypeMap.getOrDefault(map.getString("aidFundMemberUserType"), map.getString("aidFundMemberUserType"))); + map.put("changeType", changeTypeMap.getOrDefault(changeType, changeType)); + map.put("arrivalAtSchoolDate", StrUtil.isBlank(arrivalAtSchoolDate) ? "" : DateUtil.format(DateUtil.parse(arrivalAtSchoolDate), "yyyy-MM-dd")); + map.put("applyTime", map.getTime("applyTime") == null ? "" : DateUtil.formatDateTime(map.getTime("applyTime"))); + // 仅加入基金时需要计算补缴金额,其他变更类型保持空白,避免误导为固定收费。 + map.put("money", ObjectUtil.equals(changeType, CHANGE_TYPE_JOIN) && StrUtil.isNotBlank(arrivalAtSchoolDate) + ? getPayMoney(arrivalAtSchoolDate, map.getString("userId")) : ""); + }); + return list; + } + + private Map getDictNameMap(String dictCode) { + return sysDictService.getSubListByCode(dictCode).stream().collect(HashMap::new, (map, dict) -> map.put(dict.getCode(), dict.getName()), HashMap::putAll); + } + @Override @Aop(TransAop.READ_COMMITTED) public void executeTask(String param, String id) { Dict args = Json.fromJson(Dict.class, param); + executeTask(args, id); + } + + @Override + @Aop(TransAop.READ_COMMITTED) + public NutMap batchExecuteTask(String param, String[] ids) { + NutMap result = NutMap.NEW(); + if (ArrayUtil.isEmpty(ids)) { + return result.setv("successCount", 0).setv("failCount", 0).setv("failMessages", List.of("请选择需要审核的记录")); + } + Dict baseArgs = Json.fromJson(Dict.class, param); + List doingTasks = processTaskService.getDoingTaskByBizIdTaskName(Arrays.asList(ids), FOUNDATION_AUDIT_TASK_NAME); + Map taskMap = new HashMap<>(); + List instanceIds = doingTasks.stream().map(ProcessTask::getProcessInstanceId).filter(Objects::nonNull).distinct().toList(); + Map businessNoMap = new HashMap<>(); + if (CollectionUtil.isNotEmpty(instanceIds)) { + List instances = dao().query(ProcessInstance.class, Cnd.where(ProcessInstance::getId, "in", instanceIds)); + instances.forEach(instance -> businessNoMap.put(instance.getId(), instance.getBusinessNo())); + } + doingTasks.forEach(task -> { + String businessNo = businessNoMap.get(task.getProcessInstanceId()); + if (StrUtil.isNotBlank(businessNo)) { + taskMap.put(businessNo, task); + } + }); + List failMessages = new ArrayList<>(); + int successCount = 0; + for (String id : ids) { + AidFundMemberChangeRecord changeRecord = fetch(id); + if (changeRecord == null) { + failMessages.add(id + ":申请记录不存在"); + continue; + } + ProcessTask processTask = taskMap.get(id); + if (processTask == null) { + failMessages.add(resolveRecordName(changeRecord) + ":审核任务不存在或已处理"); + continue; + } + if (!processTaskService.isAllowed(processTask, SecurityUtil.getUserId())) { + failMessages.add(resolveRecordName(changeRecord) + ":当前账号无权审核该记录"); + continue; + } + try { + Dict args = buildBatchTaskArgs(baseArgs, changeRecord, processTask); + executeTask(args, id); + successCount++; + } catch (Exception e) { + failMessages.add(resolveRecordName(changeRecord) + ":" + e.getMessage()); + } + } + result.setv("successCount", successCount); + result.setv("failCount", failMessages.size()); + result.setv("failMessages", failMessages); + return result; + } + + /** + * 批量审核沿用单条审核逻辑,但需要为每条记录补齐流程任务 ID 和加入基金时的入校时间。 + */ + private Dict buildBatchTaskArgs(Dict baseArgs, AidFundMemberChangeRecord changeRecord, ProcessTask processTask) { + Dict args = baseArgs.clone(); + args.set(FlowConst.PROCESS_TASK_ID_KEY, processTask.getId()); + args.set("changeType", changeRecord.getChangeType()); + if (ObjectUtil.equals(args.getInt("submitType"), 1) && ObjectUtil.equals(changeRecord.getChangeType(), CHANGE_TYPE_JOIN)) { + Sys_user user = dao().fetch(Sys_user.class, changeRecord.getUserId()); + if (user == null || StrUtil.isBlank(user.getArrivalAtSchoolDate())) { + throw new IllegalArgumentException("缺少入校时间,无法批量通过"); + } + args.set("arrivalAtSchoolDate", user.getArrivalAtSchoolDate()); + } + return args; + } + + private String resolveRecordName(AidFundMemberChangeRecord changeRecord) { + Sys_user user = dao().fetch(Sys_user.class, changeRecord.getUserId()); + if (user == null || StrUtil.isBlank(user.getUsername())) { + return changeRecord.getId(); + } + return user.getUsername(); + } + + /** + * 统一处理互管会审核通过后的用户状态同步,并继续推进流程任务。 + */ + private void executeTask(Dict args, String id) { AidFundMemberChangeRecord changeRecord = fetch(id); + if (changeRecord == null) { + throw new IllegalArgumentException("申请记录不存在"); + } if (args.getInt("submitType") == 1) { - //如果是通过 - if (ObjectUtil.equals(args.getStr("changeType"), "AIDFUND_MEMBER_CHANGE_TYPE_ONE")) { - //如果是加入基金 - dao().update(Sys_user.class, Chain.make("arrivalAtSchoolDate", args.getStr("arrivalAtSchoolDate")).add("aidFundMemberJoinTime", new Date()) - .add("aidFundMember", AidFundMemberMode.NORMAL.getCode()), + // 审核通过后需要把本次申请的基金会员类型同步回用户表,历史空值则保留用户原值不覆盖。 + String aidFundMemberUserType = changeRecord.getAidFundMemberUserType(); + // 如果是通过,加入基金需要回写入校时间和入会状态,其他类型按退会逻辑处理。 + if (ObjectUtil.equals(args.getStr("changeType"), CHANGE_TYPE_JOIN)) { + if (StrUtil.isBlank(args.getStr("arrivalAtSchoolDate"))) { + throw new IllegalArgumentException("缺少入校时间,无法通过审核"); + } + Chain chain = Chain.make("arrivalAtSchoolDate", args.getStr("arrivalAtSchoolDate")) + .add("aidFundMemberJoinTime", new Date()) + .add("aidFundMember", AidFundMemberMode.NORMAL.getCode()); + if (StrUtil.isNotBlank(aidFundMemberUserType)) { + chain.add("aidFundMemberUserType", aidFundMemberUserType); + } + dao().update(Sys_user.class, chain, Cnd.where(Sys_user::getId, "=", changeRecord.getUserId())); } else { - dao().update(Sys_user.class, Chain.make("aidFundMember", AidFundMemberMode.NONE.getCode()) - .add("aidFundMemberQuitTime", new Date()), + Chain chain = Chain.make("aidFundMember", AidFundMemberMode.NONE.getCode()) + .add("aidFundMemberQuitTime", new Date()); + if (StrUtil.isNotBlank(aidFundMemberUserType)) { + chain.add("aidFundMemberUserType", aidFundMemberUserType); + } + dao().update(Sys_user.class, chain, Cnd.where(Sys_user::getId, "=", changeRecord.getUserId())); } } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/service/impl/AidFundMemberServiceImpl.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/service/impl/AidFundMemberServiceImpl.java index 618afc44..5ae7baf2 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/service/impl/AidFundMemberServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/aidFund/service/impl/AidFundMemberServiceImpl.java @@ -2,18 +2,28 @@ package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.service.impl; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.base.service.impl.BaseServiceImpl; +import com.budwk.app.base.utils.PageUtil; import com.budwk.app.sys.models.Sys_user; import com.budwk.app.sys.views.View_user; +import com.budwk.app.web.commons.auth.utils.AuthUtil; +import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.mode.AidFundMemberMode; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.model.AidFundMemberChangeRecord; import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.model.AidFundMemberHistory; import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.model.AidFundMemberPay; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.param.AidFundPageForm; import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.aidFund.service.AidFundMemberService; +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.SqlExpressionGroup; +import org.nutz.ioc.aop.Aop; import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.lang.Strings; import org.nutz.lang.util.NutMap; @@ -121,6 +131,62 @@ public class AidFundMemberServiceImpl extends BaseServiceImpl implements AidFund return (year + 1 - beforeYear) * money + (year - beforeYear) * money * 0.1; } + /** + * 统一封装基金会员台账列表查询口径,分页查询和导出都复用这里,避免“所见”和“所得”不一致。 + * + * @param pageForm 页面查询条件,包含会员类型、工会、单位、关键字、排序及未缴费筛选参数 + * @return 基金会员台账查询SQL + */ + @Override + public Sql getManageSql(AidFundPageForm pageForm) { + Sql sql = Sqls.create(""" + SELECT + id, + loginname, + username, + sex, + arrivalAtSchoolDate, + unitName, + unionName, + aidFundMemberUserType, + aidFundMemberJoinTime + FROM + vw_user + $condition + """); + Cnd cnd = Cnd.NEW(); + // 非系统管理员按现有页面权限口径控制数据范围,确保导出结果与列表展示一致。 + if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name())) { + if (AuthUtil.hasRole(RoleConstant.RETIREMENT_WORKPLACE.name())) { + cnd.and(Sys_user::getAidFundMemberUserType, "=", "离退休人员"); + } else { + cnd.and(View_user::getUnionId, "=", SecurityUtil.getUnionId()); + } + } + + if (pageForm.getNotPayedCurrentYear()) { + cnd.and("id", "in", Sqls.create("SELECT userid FROM `aid_fund_member_pay` where `year` = YEAR(CURDATE()) and isPayed = 0")); + } + cnd.andEX(Sys_user::getAidFundMemberUserType, "=", pageForm.getAidFundMemberUserType()); + cnd.andEX(View_user::getUnionId, "=", pageForm.getUnionId()); + cnd.andEX(View_user::getUnitId, "=", pageForm.getUnitId()); + cnd.and(Sys_user::getAidFundMember, "=", AidFundMemberMode.NORMAL.getCode()); + + if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) { + SqlExpressionGroup seg = new SqlExpressionGroup(); + seg.orLike("loginname", pageForm.getSearchKeyword()); + seg.orLike("username", pageForm.getSearchKeyword()); + cnd.and(seg); + } + if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) { + cnd.desc("unitCode"); + } else { + cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy())); + } + sql.setCondition(cnd); + return sql; + } + @Override public List findChangeRecordList(String userId) { Sql sql = Sqls.create(""" @@ -168,5 +234,93 @@ public class AidFundMemberServiceImpl extends BaseServiceImpl implements AidFund return listMap(sql); } + /** + * 管理端批量变更基金会员状态时,统一同步用户表并记录“系统管理员操作”的变更记录。 + * + * @param ids 需要变更的用户ID数组,来自台账页面勾选结果 + * @param changeType 变更类型字典值,对应 AIDFUND_MEMBER_CHANGE_TYPE + */ + @Override + @Aop(TransAop.READ_COMMITTED) + public void doBatchChangeTypeByAdmin(String[] ids, String changeType) { + List sysUserList = dao().query(Sys_user.class, Cnd.where("id", "in", ids)); + List recordArrayList = new ArrayList<>(); + for (String id : ids) { + Sys_user user = sysUserList.stream().filter(sysUser -> sysUser.getId().equals(id)).findFirst().orElse(null); + if (user == null) { + continue; + } + recordArrayList.add(buildAdminChangeRecord(user, changeType)); + } + updateUserChangeType(ids, changeType); + if (!recordArrayList.isEmpty()) { + dao().insert(recordArrayList); + } + } + + /** + * 管理端单个“变更”操作时,统一同步用户表并记录“系统管理员操作”的变更记录。 + * + * @param userId 被变更的用户ID + * @param changeType 变更类型字典值,对应 AIDFUND_MEMBER_CHANGE_TYPE + */ + @Override + @Aop(TransAop.READ_COMMITTED) + public void doEditChangeTypeByAdmin(String userId, String changeType) { + Sys_user user = dao().fetch(Sys_user.class, userId); + if (user == null) { + return; + } + dao().insert(buildAdminChangeRecord(user, changeType)); + updateUserChangeType(new String[]{userId}, changeType); + } + + /** + * 管理端变更落记录时,需要明确标记记录来源,避免被“我的申请”误识别为本人发起。 + * + * @param user 当前被操作的用户 + * @param changeType 变更类型字典值 + * @return 已补齐管理员操作标记和会员类型快照的变更记录 + */ + private AidFundMemberChangeRecord buildAdminChangeRecord(Sys_user user, String changeType) { + return new AidFundMemberChangeRecord() + .setUserId(user.getId()) + .setAidFundMemberUserType(resolveChangeRecordMemberType(user, changeType)) + .setApplyTime(new Date()) + .setChangeType(changeType) + .setAdminOperate(true); + } + + /** + * 退休变更需要把记录中的会员类型同步成退休类型,其余情况沿用当前用户档案中的会员类型。 + * + * @param user 当前被操作的用户 + * @param changeType 变更类型字典值 + * @return 变更记录中应保存的基金会员类型 + */ + private String resolveChangeRecordMemberType(Sys_user user, String changeType) { + if (ObjectUtil.equals(changeType, "AIDFUND_MEMBER_CHANGE_TYPE_EIGTH")) { + return "离退休人员"; + } + return user.getAidFundMemberUserType(); + } + + /** + * 管理端“变更”与“批量变更”共用同一套用户表更新规则,确保页面操作口径一致。 + * + * @param ids 需要更新的用户ID数组 + * @param changeType 变更类型字典值 + */ + private void updateUserChangeType(String[] ids, String changeType) { + Chain add; + if (ObjectUtil.equals(changeType, "AIDFUND_MEMBER_CHANGE_TYPE_EIGTH")) { + add = Chain.make("aidFundMemberUserType", "离退休人员"); + } else { + add = Chain.make("aidFundMember", AidFundMemberMode.NONE.getCode()) + .add("aidFundMemberQuitTime", new Date()); + } + dao().update(Sys_user.class, add, Cnd.where("id", "in", ids)); + } + } diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/controller/MedicalCalculateMoneyController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/controller/MedicalCalculateMoneyController.java index 250b00de..909c53f3 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/controller/MedicalCalculateMoneyController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/controller/MedicalCalculateMoneyController.java @@ -73,6 +73,29 @@ public class MedicalCalculateMoneyController { return Result.success(applyData); } + @At + @ApiOperation("更新医疗互助补助金额明细") + @SaCheckPermission("medicalMutualAid.medical.calculateMoney") + public Object setGrantsOrUnionInto(String keys, double value) { + //获取申请最新年份 + Sql yearSql = Sqls.create("SELECT MAX(YEAR(applyTime)) AS currentYear FROM medical_apply"); + yearSql.setCallback(Sqls.callback.longs()); + medicalCalculateMoneyService.execute(yearSql); + long year = yearSql.getLong(); + MedicalMoneyDetail moneyDetail = medicalCalculateMoneyService.dao().fetch(MedicalMoneyDetail.class, Cnd.where("year", "=", year)); + if (Lang.isEmpty(moneyDetail)) { + moneyDetail = new MedicalMoneyDetail(); + moneyDetail.setYear((int) year); + } + if (keys.equals("grants")) { + moneyDetail.setSchoolGrants(new BigDecimal(value)); + } else if (keys.equals("into")) { + moneyDetail.setUnionInto(new BigDecimal(value)); + } + medicalCalculateMoneyService.insertOrUpdate(moneyDetail); + return null; + } + @At @ApiOperation("按比例修改补助金额") diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/controller/MedicalDashBoardController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/controller/MedicalDashBoardController.java new file mode 100644 index 00000000..e6d4b996 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/controller/MedicalDashBoardController.java @@ -0,0 +1,126 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.budwk.app.base.result.Result; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service.MedicalDashBoardService; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.vo.MedicalDashboardCategoryStatVO; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.vo.MedicalDashboardOverviewVO; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.vo.MedicalDashboardUnionResultVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +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 java.util.List; + +/** + * @author Codex + * @description 医疗互助数据看板 + */ +@IocBean +@At("/platform/medicalMutualAid/medical/dashboard") +@Api("医疗互助数据看板") +@Ok("json:full") +public class MedicalDashBoardController { + + @Inject + private MedicalDashBoardService medicalDashBoardService; + + @At("") + @Ok("beetl:/platform/zhgh/staffbenefit/medicalMutualAid/medical/dashboard/index.html") + @SaCheckPermission("medicalMutualAid.medical.dashboard") + public void index() { + } + + /** + * 查询医疗互助总览统计。 + * 返回值字段说明: + * 1. fundMemberCount:当前基金会员总数 + * 2. currentYearApplyCount:本年度已办结申请数 + * 3. majorDiseaseApplyCount:重疾已办结申请数 + * 4. commonDiseaseApplyCount:普通疾病已办结申请数 + * 5. totalSubsidyMoney:补助金额合计 + * 6. totalLoveSubsidyMoney:爱心基金金额合计 + * + * @return 医疗互助总览统计 VO + */ + @At + @ApiOperation("查询医疗互助总览统计") + @SaCheckPermission("medicalMutualAid.medical.dashboard") + public Result overview() { + MedicalDashboardOverviewVO vo = medicalDashBoardService.getOverview(); + return Result.success(vo); + } + + /** + * 按工会统计医疗互助已办结申请数据。 + * 返回值字段说明: + * 1. tableData:表格使用的工会统计列表 + * 2. 列表元素中 applyCount 为已办结申请数,subsidyMoney 为补助金额合计 + * + * @return 工会统计结果 VO + */ + @At + @ApiOperation("按工会统计医疗互助数据") + @SaCheckPermission("medicalMutualAid.medical.dashboard") + public Result unionStat() { + MedicalDashboardUnionResultVO vo = medicalDashBoardService.getUnionStat(); + return Result.success(vo); + } + + /** + * 按在职状态统计医疗互助已办结申请数据。 + * 返回列表字段说明: + * 1. code:在职状态编码 + * 2. name:在职状态名称 + * 3. applyCount:该状态下已办结申请数 + * 4. subsidyMoney:该状态下补助金额合计 + * + * @return 在职状态统计 VO 列表 + */ + @At + @ApiOperation("按在职状态统计医疗互助数据") + @SaCheckPermission("medicalMutualAid.medical.dashboard") + public Result userStateStat() { + List list = medicalDashBoardService.getUserStateStat(); + return Result.success(list); + } + + /** + * 按人员类型统计医疗互助已办结申请数据。 + * 返回列表字段说明: + * 1. code:人员类型编码 + * 2. name:人员类型名称 + * 3. applyCount:该类型下已办结申请数 + * 4. subsidyMoney:该类型下补助金额合计 + * + * @return 人员类型统计 VO 列表 + */ + @At + @ApiOperation("按人员类型统计医疗互助数据") + @SaCheckPermission("medicalMutualAid.medical.dashboard") + public Result personTypeStat() { + List list = medicalDashBoardService.getPersonTypeStat(); + return Result.success(list); + } + + /** + * 按疾病类型统计医疗互助已办结申请数据。 + * 返回列表字段说明: + * 1. code:疾病类型 ID + * 2. name:疾病名称 + * 3. applyCount:该疾病下已办结申请数 + * 4. subsidyMoney:该疾病下补助金额合计 + * + * @return 疾病类型统计 VO 列表 + */ + @At + @ApiOperation("按疾病类型统计医疗互助数据") + @SaCheckPermission("medicalMutualAid.medical.dashboard") + public Result diseaseTypeStat() { + List list = medicalDashBoardService.getDiseaseTypeStat(); + return Result.success(list); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/controller/MedicalUnionAuditController.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/controller/MedicalUnionAuditController.java index f8453d41..178a9491 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/controller/MedicalUnionAuditController.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/controller/MedicalUnionAuditController.java @@ -55,6 +55,7 @@ public class MedicalUnionAuditController { @SaCheckPermission("medicalMutualAid.medical.unionAudit") public Result pageData(MedicalPageForm pageForm) { Cnd cnd = Cnd.NEW(); + cnd.and("t.taskName", "=", "a9bbf69c-5edf-4161-a364-47996d212472"); Sql sql = medicalAuditService.getAuditSql(pageForm, cnd); sql.setCondition(cnd); diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/MedicalDashBoardService.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/MedicalDashBoardService.java new file mode 100644 index 00000000..74c2e447 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/MedicalDashBoardService.java @@ -0,0 +1,61 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service; + +import com.budwk.app.base.service.BaseService; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalApply; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.vo.MedicalDashboardCategoryStatVO; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.vo.MedicalDashboardOverviewVO; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.vo.MedicalDashboardUnionResultVO; + +import java.util.List; + +/** + * @author Codex + * @description 医疗互助数据看板 service + */ +public interface MedicalDashBoardService extends BaseService { + + /** + * 查询医疗互助数据看板总览数据。 + * 返回值包含: + * 1. 已办结申请总数 + * 2. 本年度已办结申请数 + * 3. 重疾/普通疾病申请数 + * 4. 补助金额与爱心基金金额汇总 + * + * @return 医疗互助总览统计 VO + */ + MedicalDashboardOverviewVO getOverview(); + + /** + * 按工会统计医疗互助已办结申请数据。 + * 返回值中的 chartData 与 tableData 当前来源相同, + * 便于前端图表和表格按既有字段直接取值。 + * + * @return 工会统计结果 VO + */ + MedicalDashboardUnionResultVO getUnionStat(); + + /** + * 按人员在职状态统计医疗互助已办结申请数据。 + * code 为在职状态编码,name 为字典名称。 + * + * @return 在职状态统计列表 + */ + List getUserStateStat(); + + /** + * 按人员类型统计医疗互助已办结申请数据。 + * code 为人员类型编码,name 为字典名称。 + * + * @return 人员类型统计列表 + */ + List getPersonTypeStat(); + + /** + * 按疾病类型统计医疗互助已办结申请数据。 + * code 为疾病类型 ID,name 为疾病名称。 + * + * @return 疾病类型统计列表 + */ + List getDiseaseTypeStat(); +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/impl/MedicalApplyServiceImpl.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/impl/MedicalApplyServiceImpl.java index 56fd8e7c..db5256b0 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/impl/MedicalApplyServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/impl/MedicalApplyServiceImpl.java @@ -186,6 +186,7 @@ public class MedicalApplyServiceImpl extends BaseServiceImpl imple // 查询申请成功的记录 List applyRecords = getApplyRecord(allUserIds); + applyRecords.removeIf(item -> applyId.equals(item.getString("id"))); //是否首次申请 爱心互助基金 重大疾病 boolean isFirstApply = applyRecords.stream().filter(v -> v.getBoolean("isMajorDiseases")).toList().isEmpty(); @@ -230,7 +231,7 @@ public class MedicalApplyServiceImpl extends BaseServiceImpl imple Boolean isBeyondAllMoney = allMoney.compareTo(medicalSetting.getPreviousYearMaxMoney()) > 0; - Sys_user user = dao().fetch(Sys_user.class, SecurityUtil.getUserId()); + Sys_user user = dao().fetch(Sys_user.class, applyInfo.getString("userId")); boolean fullTenYears = DateUtil.thisYear() - Integer.parseInt(user.getAidFundDeductTime()) >= 10; boolean fullFifYears = DateUtil.thisYear() - Integer.parseInt(user.getAidFundDeductTime()) >= 15; diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/impl/MedicalAuditServiceImpl.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/impl/MedicalAuditServiceImpl.java index bf577404..2dbf0673 100644 --- a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/impl/MedicalAuditServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/impl/MedicalAuditServiceImpl.java @@ -72,7 +72,9 @@ public class MedicalAuditServiceImpl extends BaseServiceImpl imple seg.orLike("us.username", pageForm.getSearchKeyword()); cnd.and(seg); } - cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); + if(!SecurityUtil.getUserLoginname().equals("superadmin")){ + cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId())); + } cnd.andEX("year(info.applyTime)", "=", pageForm.getYear()); cnd.andEX("info.diseaseId", "=", pageForm.getDiseaseId()); cnd.andEX("us.unionid", "=", pageForm.getUnionId()); diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/impl/MedicalDashBoardServiceImpl.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/impl/MedicalDashBoardServiceImpl.java new file mode 100644 index 00000000..6bca8157 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/service/impl/MedicalDashBoardServiceImpl.java @@ -0,0 +1,248 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service.impl; + +import com.budwk.app.base.service.impl.BaseServiceImpl; +import com.budwk.app.flow.enums.ProcessInstanceStateEnum; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.model.MedicalApply; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.service.MedicalDashBoardService; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.vo.MedicalDashboardCategoryStatVO; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.vo.MedicalDashboardOverviewVO; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.vo.MedicalDashboardUnionResultVO; +import com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.vo.MedicalDashboardUnionStatVO; +import org.nutz.dao.Dao; +import org.nutz.dao.Sqls; +import org.nutz.dao.sql.Sql; +import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.lang.util.NutMap; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Codex + * @description 医疗互助数据看板 service 实现 + */ +@IocBean(args = {"refer:dao"}) +public class MedicalDashBoardServiceImpl extends BaseServiceImpl implements MedicalDashBoardService { + + public MedicalDashBoardServiceImpl(Dao dao) { + super(dao); + } + + @Override + public MedicalDashboardOverviewVO getOverview() { + Sql sql = Sqls.create(""" + SELECT + (SELECT COUNT(1) FROM sys_user WHERE aidFundMember = 1) AS fundMemberCount, + COUNT(DISTINCT CASE WHEN YEAR(info.applyTime) = YEAR(NOW()) THEN info.id END) AS currentYearApplyCount, + COUNT(DISTINCT CASE WHEN type.isMajorDiseases = 1 THEN info.id END) AS majorDiseaseApplyCount, + COUNT(DISTINCT CASE WHEN type.isMajorDiseases = 0 THEN info.id END) AS commonDiseaseApplyCount, + COALESCE(SUM(info.subsidyMoney), 0) AS totalSubsidyMoney, + COALESCE(SUM(info.loveSubsidyMoney), 0) AS totalLoveSubsidyMoney + FROM + medical_apply info + INNER JOIN wf_process_instance ins ON ins.businessNo = info.id + LEFT JOIN medical_disease_type type ON type.id = info.diseaseId + WHERE + ins.state = @state + """); + sql.setParam("state", ProcessInstanceStateEnum.FINISHED.getCode()); + NutMap data = fetchOne(sql); + + MedicalDashboardOverviewVO vo = new MedicalDashboardOverviewVO(); + vo.setFundMemberCount(data.getLong("fundMemberCount", 0L)); + vo.setCurrentYearApplyCount(data.getLong("currentYearApplyCount", 0L)); + vo.setMajorDiseaseApplyCount(data.getLong("majorDiseaseApplyCount", 0L)); + vo.setCommonDiseaseApplyCount(data.getLong("commonDiseaseApplyCount", 0L)); + vo.setTotalSubsidyMoney(getBigDecimalValue(data, "totalSubsidyMoney")); + vo.setTotalLoveSubsidyMoney(getBigDecimalValue(data, "totalLoveSubsidyMoney")); + return vo; + } + + @Override + public MedicalDashboardUnionResultVO getUnionStat() { + Sql sql = Sqls.create(""" + SELECT + un.id AS unionId, + un.`name` AS unionName, + un.unionCode AS unionCode, + COUNT(applyInfo.id) AS applyCount, + COALESCE(SUM(applyInfo.subsidyMoney), 0) AS subsidyMoney + FROM + sys_union un + LEFT JOIN vw_user us ON us.unionId = un.id + LEFT JOIN ( + SELECT + info.id, + info.userId, + info.subsidyMoney + FROM + medical_apply info + INNER JOIN wf_process_instance ins ON ins.businessNo = info.id + WHERE + ins.state = @state + ) applyInfo ON applyInfo.userId = us.id + GROUP BY + un.id, un.`name`, un.unionCode + ORDER BY + un.unionCode + """); + sql.setParam("state", ProcessInstanceStateEnum.FINISHED.getCode()); + List list = toUnionStatList(listMap(sql)); + + MedicalDashboardUnionResultVO resultVO = new MedicalDashboardUnionResultVO(); + resultVO.setTableData(new ArrayList<>(list)); + return resultVO; + } + + @Override + public List getUserStateStat() { + Sql sql = Sqls.create(""" + SELECT + dict.`code` AS code, + dict.`name` AS name, + COUNT(info.id) AS applyCount, + COALESCE(SUM(info.subsidyMoney), 0) AS subsidyMoney + FROM + sys_dict dict + LEFT JOIN sys_dict parent ON parent.id = dict.parentId + LEFT JOIN vw_user us ON us.userState = dict.`code` + LEFT JOIN medical_apply info ON info.userId = us.id + LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id AND ins.state = @state + WHERE + parent.`code` = 'USER_STATE' + AND ins.id IS NOT NULL + GROUP BY + dict.`code`, dict.`name`, dict.location + ORDER BY + dict.location + """); + sql.setParam("state", ProcessInstanceStateEnum.FINISHED.getCode()); + return toCategoryStatList(listMap(sql)); + } + + @Override + public List getPersonTypeStat() { + Sql sql = Sqls.create(""" + SELECT + dict.`code` AS code, + dict.`name` AS name, + COUNT(info.id) AS applyCount, + COALESCE(SUM(info.subsidyMoney), 0) AS subsidyMoney + FROM + sys_dict dict + LEFT JOIN sys_dict parent ON parent.id = dict.parentId + LEFT JOIN vw_user us ON us.personType = dict.`code` + LEFT JOIN medical_apply info ON info.userId = us.id + LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id AND ins.state = @state + WHERE + parent.`code` = 'USER_PERSON_TYPE' + AND ins.id IS NOT NULL + GROUP BY + dict.`code`, dict.`name`, dict.location + ORDER BY + dict.location + """); + sql.setParam("state", ProcessInstanceStateEnum.FINISHED.getCode()); + return toCategoryStatList(listMap(sql)); + } + + @Override + public List getDiseaseTypeStat() { + Sql sql = Sqls.create(""" + SELECT + type.id AS code, + type.diseaseName AS name, + COUNT(info.id) AS applyCount, + COALESCE(SUM(info.subsidyMoney), 0) AS subsidyMoney + FROM + medical_disease_type type + LEFT JOIN medical_apply info ON info.diseaseId = type.id + LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id AND ins.state = @state + WHERE + ins.id IS NOT NULL + GROUP BY + type.id, type.diseaseName, type.diseaseCode + ORDER BY + type.diseaseCode + """); + sql.setParam("state", ProcessInstanceStateEnum.FINISHED.getCode()); + return toCategoryStatList(listMap(sql)); + } + + /** + * 执行单行统计 SQL。 + * 该方法用于处理总览类统计,返回结果仅一行。 + * + * @param sql 已设置好查询参数的 SQL 对象 + * @return 单行统计数据,字段不存在时返回空 NutMap,避免上层空指针 + */ + private NutMap fetchOne(Sql sql) { + sql.setCallback(Sqls.callback.map()); + dao().execute(sql); + Object result = sql.getResult(); + if (result instanceof NutMap) { + return (NutMap) result; + } + return NutMap.NEW(); + } + + /** + * 将工会统计查询结果转换为 VO。 + * + * @param dataList SQL 查询返回的 map 列表,字段需包含 unionId、unionName、unionCode、applyCount、subsidyMoney + * @return 工会统计 VO 列表 + */ + private List toUnionStatList(List dataList) { + List list = new ArrayList<>(); + for (NutMap data : dataList) { + MedicalDashboardUnionStatVO vo = new MedicalDashboardUnionStatVO(); + vo.setUnionId(data.getString("unionId")); + vo.setUnionName(data.getString("unionName")); + vo.setUnionCode(data.getString("unionCode")); + vo.setApplyCount(data.getLong("applyCount", 0L)); + vo.setSubsidyMoney(getBigDecimalValue(data, "subsidyMoney")); + list.add(vo); + } + return list; + } + + /** + * 将通用分类统计查询结果转换为 VO。 + * + * @param dataList SQL 查询返回的 map 列表,字段需包含 code、name、applyCount、subsidyMoney + * @return 分类统计 VO 列表 + */ + private List toCategoryStatList(List dataList) { + List list = new ArrayList<>(); + for (NutMap data : dataList) { + MedicalDashboardCategoryStatVO vo = new MedicalDashboardCategoryStatVO(); + vo.setCode(data.getString("code")); + vo.setName(data.getString("name")); + vo.setApplyCount(data.getLong("applyCount", 0L)); + vo.setSubsidyMoney(getBigDecimalValue(data, "subsidyMoney")); + list.add(vo); + } + return list; + } + + /** + * 从 NutMap 中安全读取金额字段。 + * SQL 聚合查询返回的金额字段有时会是 BigDecimal、Double、Long 或字符串, + * 因此这里统一做一次转换,避免 controller/service 层重复判空和类型判断。 + * + * @param data NutMap 查询结果对象 + * @param key 金额字段名 + * @return 对应金额,字段为空时返回 0 + */ + private BigDecimal getBigDecimalValue(NutMap data, String key) { + Object value = data.get(key); + if (value == null) { + return BigDecimal.ZERO; + } + if (value instanceof BigDecimal) { + return (BigDecimal) value; + } + return new BigDecimal(String.valueOf(value)); + } +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/vo/MedicalDashboardCategoryStatVO.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/vo/MedicalDashboardCategoryStatVO.java new file mode 100644 index 00000000..9f2cd8b8 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/vo/MedicalDashboardCategoryStatVO.java @@ -0,0 +1,34 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.vo; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * @author Codex + * @description 医疗互助分类统计返回值 + */ +@Data +public class MedicalDashboardCategoryStatVO { + + /** + * 分类编码。 + * 不同接口场景下可能表示在职状态编码、人员类型编码、疾病ID 等。 + */ + private String code; + + /** + * 分类名称,用于前端直接展示图表/表格标题。 + */ + private String name; + + /** + * 当前分类下的已办结申请数 + */ + private Long applyCount; + + /** + * 当前分类下的已办结补助金额合计 + */ + private BigDecimal subsidyMoney; +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/vo/MedicalDashboardOverviewVO.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/vo/MedicalDashboardOverviewVO.java new file mode 100644 index 00000000..1e52ab2e --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/vo/MedicalDashboardOverviewVO.java @@ -0,0 +1,43 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.vo; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * @author Codex + * @description 医疗互助数据看板总览统计返回值 + */ +@Data +public class MedicalDashboardOverviewVO { + + /** + * 当前基金会员总数 + */ + private Long fundMemberCount; + + /** + * 本年度已办结申请数 + */ + private Long currentYearApplyCount; + + /** + * 已办结重疾申请数 + */ + private Long majorDiseaseApplyCount; + + /** + * 已办结普通疾病申请数 + */ + private Long commonDiseaseApplyCount; + + /** + * 已办结补助金额合计 + */ + private BigDecimal totalSubsidyMoney; + + /** + * 已办结爱心基金金额合计 + */ + private BigDecimal totalLoveSubsidyMoney; +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/vo/MedicalDashboardUnionResultVO.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/vo/MedicalDashboardUnionResultVO.java new file mode 100644 index 00000000..2b96dbca --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/vo/MedicalDashboardUnionResultVO.java @@ -0,0 +1,19 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.vo; + +import lombok.Data; + +import java.util.List; + +/** + * @author Codex + * @description 医疗互助按工会统计返回值 + */ +@Data +public class MedicalDashboardUnionResultVO { + + /** + * 表格数据。 + * 当前页面仅保留工会统计表格,因此只返回表格所需列表。 + */ + private List tableData; +} diff --git a/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/vo/MedicalDashboardUnionStatVO.java b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/vo/MedicalDashboardUnionStatVO.java new file mode 100644 index 00000000..4f8621e4 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/staffbenefit/medicalMutualAid/medical/vo/MedicalDashboardUnionStatVO.java @@ -0,0 +1,38 @@ +package com.budwk.app.zhgh.staffbenefit.medicalMutualAid.medical.vo; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * @author Codex + * @description 医疗互助按工会统计返回值 + */ +@Data +public class MedicalDashboardUnionStatVO { + + /** + * 工会ID + */ + private String unionId; + + /** + * 工会名称 + */ + private String unionName; + + /** + * 工会编码 + */ + private String unionCode; + + /** + * 已办结申请数 + */ + private Long applyCount; + + /** + * 已办结补助金额合计 + */ + private BigDecimal subsidyMoney; +} diff --git a/src/main/resources/views/platform/sys/unit/index.html b/src/main/resources/views/platform/sys/unit/index.html index a186709e..22d5377d 100644 --- a/src/main/resources/views/platform/sys/unit/index.html +++ b/src/main/resources/views/platform/sys/unit/index.html @@ -82,6 +82,7 @@ layout("/layouts/platform.html"){ :expand-on-click-node="false" :props="{ children: 'children', label: 'name' }" node-key="id" + :default-expanded-keys="defaultExpandedKeys" @node-click="treeNodeClick" :filter-node-method="filterNode" highlight-current @@ -156,6 +157,7 @@ layout("/layouts/platform.html"){ filterText: null, currentTreeNode: null, currentTreeData: null, + defaultExpandedKeys: [], treeData: [] } }, @@ -175,6 +177,7 @@ layout("/layouts/platform.html"){ this.treeData = res.data if (this.treeData) { this.currentTreeData = this.treeData[0] + this.defaultExpandedKeys = this.treeData.length > 0 ? [this.treeData[0].id] : [] } }) }, diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/export/comprehensive/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/export/comprehensive/index.html index b1baf488..ddf49fbc 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/export/comprehensive/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/export/comprehensive/index.html @@ -232,7 +232,7 @@ layout("/layouts/platform.html"){ return masterUnitNames || slaveUnitNames } if (row.caseFilingResult === "CONFIRM_FILING") { - return [masterUnitNames ? "主办:" + masterUnitNames : "", slaveUnitNames ? "协办:" + slaveUnitNames : ""].filter(function(item) { + return [masterUnitNames ? "主办:" + masterUnitNames : "", slaveUnitNames ? "协办:" + slaveUnitNames : ""].filter(function (item) { return item }).join(";") } @@ -243,7 +243,7 @@ layout("/layouts/platform.html"){ return "" } if (Array.isArray(unitNames)) { - return unitNames.filter(function(item) { + return unitNames.filter(function (item) { return item }).join(",") } @@ -363,6 +363,10 @@ layout("/layouts/platform.html"){ }) .then((res) => { if (res.code === 0) { + res.data.list.map((item) => { + item.brief = removeHTMLTag(item.brief) + item.measures = removeHTMLTag(item.measures) + }) this.tableData = res.data.list this.pageForm.totalCount = res.data.totalCount } diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/query/analysis/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/query/analysis/index.html index 4e005d04..6ce00192 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/query/analysis/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/query/analysis/index.html @@ -25,9 +25,56 @@ layout("/layouts/platform.html"){ .dimension-pills { display: flex; flex-wrap: wrap; + align-items: center; gap: 6px; } + .analysis-toolbar { + display: flex; + align-items: center; + justify-content: space-between; + flex-wrap: wrap; + gap: 12px; + } + + .analysis-toolbar-main { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 12px 18px; + flex: 1; + min-width: 0; + } + + .analysis-field { + display: flex; + align-items: center; + gap: 8px; + min-width: 330px; + } + + .analysis-field-label { + flex: 0 0 auto; + color: #4b617f; + font-size: 13px; + font-weight: 600; + } + + .analysis-field-select { + width: 240px; + } + + .analysis-dimension-box { + display: flex; + align-items: center; + gap: 10px; + min-width: 420px; + } + + .analysis-view-switch { + flex: 0 0 auto; + } + .dimension-pill { padding: 3px 10px; border-radius: 999px; @@ -36,6 +83,14 @@ layout("/layouts/platform.html"){ background: #edf4ff; border: 1px solid #cfe1ff; line-height: 1.4; + cursor: pointer; + transition: all 0.2s; + } + + .dimension-pill.is-active { + color: #ffffff; + background: #2f7df6; + border-color: #2f7df6; } .analysis-tip { @@ -112,15 +167,28 @@ layout("/layouts/platform.html"){
-
- - - +
+
+
+ 教代会届次 + - - - +
+
+ 统计维度 +
+ {{ item.label }} +
+
+
+ {{ showChart ? '切换表格展示' : '切换图形化展示' }}
@@ -133,17 +201,10 @@ layout("/layouts/platform.html"){ 统计数据
-
- 提案人单位 - 提案类型 - 代表团 - 立案结果 - 满意度 -
导出统计数据 - + @@ -159,7 +220,7 @@ layout("/layouts/platform.html"){ 导出分析数据 - + @@ -177,13 +238,6 @@ layout("/layouts/platform.html"){ 图形化统计展示(混合图) -
- 提案人单位 - 提案类型 - 代表团 - 立案结果 - 满意度 -
导出统计数据 @@ -228,11 +282,20 @@ layout("/layouts/platform.html"){ data() { return { pageForm: { - sessionId: "" + sessionId: "", + dimension: "" }, + dimensionOptions: [ + {label: "提案人单位", value: "提案人单位"}, + {label: "提案类型", value: "提案类型"}, + {label: "代表团", value: "代表团"}, + {label: "立案结果", value: "立案结果"}, + {label: "满意度", value: "满意度"} + ], sessionOptions: [], statisticsRows: [], analysisRows: [], + tableLoading: false, showChart: false, chartMap: {} } @@ -276,6 +339,10 @@ layout("/layouts/platform.html"){ isPieDimension(dimension) { return ["立案结果", "满意度"].includes(dimension) }, + toggleDimension(dimension) { + this.pageForm.dimension = this.pageForm.dimension === dimension ? "" : dimension + this.doSearch() + }, renderCharts() { this.destroyCharts() this.chartGroups.forEach(group => { @@ -343,18 +410,24 @@ layout("/layouts/platform.html"){ this.destroyCharts() return } - this.$axios.post(loc() + "/statisticsData", this.pageForm).then((res) => { - if (res.code === 0) { - this.statisticsRows = res.data || [] + this.tableLoading = true + Promise.all([ + this.$axios.post(loc() + "/statisticsData", this.pageForm), + this.$axios.post(loc() + "/analysisData", this.pageForm) + ]).then((resList) => { + const statisticsRes = resList[0] + const analysisRes = resList[1] + if (statisticsRes.code === 0) { + this.statisticsRows = statisticsRes.data || [] if (this.showChart) { this.$nextTick(() => this.renderCharts()) } } - }) - this.$axios.post(loc() + "/analysisData", this.pageForm).then((res) => { - if (res.code === 0) { - this.analysisRows = res.data || [] + if (analysisRes.code === 0) { + this.analysisRows = analysisRes.data || [] } + }).finally(() => { + this.tableLoading = false }) }, exportStatistics() { @@ -376,4 +449,4 @@ layout("/layouts/platform.html"){ \ No newline at end of file +#--> diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/query/comprehensive/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/query/comprehensive/index.html index d6322515..2a325432 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/query/comprehensive/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/query/comprehensive/index.html @@ -368,7 +368,7 @@ layout("/layouts/platform.html"){ }, listSession() { this.$axios.post("/platform/proposal/common/listSession", { - orderBy: "asc" + orderBy: "desc" }).then((res) => { if (res.code === 0) { this.sessionOptions = res.data diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/query/underTakeReply/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/query/underTakeReply/index.html index f362a588..a13745e7 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/query/underTakeReply/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/query/underTakeReply/index.html @@ -15,6 +15,11 @@ layout("/layouts/platform.html"){ + + + + + @@ -42,6 +47,7 @@ layout("/layouts/platform.html"){ new Vue({ el: "#app", + dicts: ["PROPOSAL_CASE_FILING_RESULT"], mixins: [initTableMixins], components: { "proposal-info": PROPOSAL_INFO diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/caseCheck/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/caseCheck/index.html index e41a5acf..49e97b01 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/caseCheck/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/caseCheck/index.html @@ -12,6 +12,18 @@ layout("/layouts/platform.html"){ v-for="item in sessionOptions"> + + + + + + + + + + @@ -149,11 +161,14 @@ layout("/layouts/platform.html"){ showApprovalForm: false, replyUnitOptions: [], sessionOptions: [], + delegationOptions: [], + unionOptions: [], } }, created() { this.pageData() this.listOpenSession() + this.listUnion() }, methods: { openView(row) { @@ -179,10 +194,40 @@ layout("/layouts/platform.html"){ this.$refs.proposalInfoRef.onOpen(row) }) }, - // 教代会 - async meetingChange(val) { + /** + * 教代会切换后需要同步刷新代表团下拉,避免上一届次代表团条件残留。 + */ + meetingChange() { + this.listDelegation() this.doSearch() }, + + /** + * 根据当前教代会加载代表团筛选项,没有选教代会时代表团下拉置空。 + */ + listDelegation() { + this.delegationOptions = [] + this.$set(this.pageForm, "delegationId", null) + if (!this.pageForm.sessionId) { + return + } + this.$axios.post("/platform/proposal/common/listDelegation", { + sessionId: this.pageForm.sessionId + }).then((res) => { + if (res.code === 0) { + this.delegationOptions = res.data + } + }) + }, + + /** + * 工会下拉按系统分工会列表加载,用于按提案人所属工会筛选当前页面列表。 + */ + listUnion() { + this.$businessTool.listUnion().then((res) => { + this.unionOptions = res + }) + }, // 查询开启的教代会 listOpenSession() { this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => { @@ -190,8 +235,8 @@ layout("/layouts/platform.html"){ this.sessionOptions = res.data if (this.sessionOptions) { this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id) - this.pageData() this.listDelegation() + this.pageData() } } }) 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 ada8c1aa..54b78d3c 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 @@ -13,6 +13,18 @@ layout("/layouts/platform.html"){ v-for="item in sessionOptions"> + + + + + + + + + + @@ -53,7 +65,7 @@ layout("/layouts/platform.html"){ 未审核 - + @@ -164,7 +176,7 @@ layout("/layouts/platform.html"){
@@ -210,6 +222,7 @@ layout("/layouts/platform.html"){ showApprovalForm: false, sessionOptions: [], delegationOptions: [], + unionOptions: [], underTakeOptions: [] } }, @@ -316,6 +329,22 @@ layout("/layouts/platform.html"){ }) }, + /** + * 并案审核完成后由父页面统一收口处理: + * 1. 关闭弹层 + * 2. 清空左侧勾选框 + * 3. 刷新父列表,避免仍显示审核前数据 + */ + handleMergeClose() { + this.$refs.guava.index() + this.$nextTick(() => { + if (this.$refs.tableRef) { + this.$refs.tableRef.clearSelection() + } + }) + this.doSearch() + }, + onRevoke(row) { this.$confirm("您确定要撤回吗?", "提示", { confirmButtonText: "确定", @@ -332,11 +361,42 @@ layout("/layouts/platform.html"){ }) }, - // 教代会 - async meetingChange(val) { + /** + * 教代会切换后重新加载当前届次代表团,并清空旧的代表团筛选条件, + * 避免跨届次继续沿用旧代表团数据。 + */ + meetingChange() { + this.listDelegation() this.doSearch() }, + /** + * 代表团下拉按教代会联动查询,没有选教代会时保持空列表。 + */ + listDelegation() { + this.delegationOptions = [] + this.$set(this.pageForm, "delegationId", null) + if (!this.pageForm.sessionId) { + return + } + this.$axios.post("/platform/proposal/common/listDelegation", { + sessionId: this.pageForm.sessionId + }).then((res) => { + if (res.code === 0) { + this.delegationOptions = res.data + } + }) + }, + + /** + * 工会下拉按系统分工会列表加载,用于按提案人所属工会筛选当前页面列表。 + */ + listUnion() { + this.$businessTool.listUnion().then((res) => { + this.unionOptions = res + }) + }, + // 查询开启的教代会 listOpenSession() { this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => { @@ -344,6 +404,7 @@ layout("/layouts/platform.html"){ this.sessionOptions = res.data if (this.sessionOptions) { this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id) + this.listDelegation() this.pageData() } } @@ -362,6 +423,7 @@ layout("/layouts/platform.html"){ created() { this.pageData() this.listOpenSession() + this.listUnion() this.listUnderTake() } }) 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 e6906dab..a9cfac4f 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 @@ -180,7 +180,6 @@ const merge = { if (res.code === 0) { this.$emit('close') this.$message.success(res.msg) - this.doSearch() } }).finally(() => { loading.close() diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/committeeFilingUnit/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/committeeFilingUnit/index.html index e0738e89..6b80c011 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/committeeFilingUnit/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/committeeFilingUnit/index.html @@ -13,6 +13,18 @@ layout("/layouts/platform.html"){ v-for="item in sessionOptions"> + + + + + + + + + + @@ -205,6 +217,7 @@ layout("/layouts/platform.html"){ showApprovalForm: false, sessionOptions: [], delegationOptions: [], + unionOptions: [], underTakeOptions: [], } }, @@ -373,11 +386,42 @@ layout("/layouts/platform.html"){ }) }, - // 教代会 - async meetingChange(val) { + /** + * 教代会变更后,按当前届次联动刷新代表团下拉并清空旧值, + * 避免查询条件串到其他届次。 + */ + meetingChange() { + this.listDelegation() this.doSearch() }, + /** + * 根据教代会查询代表团列表,未选教代会时不加载代表团数据。 + */ + listDelegation() { + this.delegationOptions = [] + this.$set(this.pageForm, "delegationId", null) + if (!this.pageForm.sessionId) { + return + } + this.$axios.post("/platform/proposal/common/listDelegation", { + sessionId: this.pageForm.sessionId + }).then((res) => { + if (res.code === 0) { + this.delegationOptions = res.data + } + }) + }, + + /** + * 工会下拉按系统分工会列表加载,用于按提案人所属工会筛选当前页面列表。 + */ + listUnion() { + this.$businessTool.listUnion().then((res) => { + this.unionOptions = res + }) + }, + // 查询开启的教代会 listOpenSession() { this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => { @@ -385,6 +429,7 @@ layout("/layouts/platform.html"){ this.sessionOptions = res.data if (this.sessionOptions) { this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id) + this.listDelegation() this.pageData() } } @@ -403,6 +448,7 @@ layout("/layouts/platform.html"){ created() { this.pageData() this.listOpenSession() + this.listUnion() this.listUnderTake() } }) diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/preAudit/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/preAudit/index.html index 88df62c2..4766d29e 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/preAudit/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/preAudit/index.html @@ -12,6 +12,18 @@ layout("/layouts/platform.html"){ v-for="item in sessionOptions"> + + + + + + + + + + @@ -109,12 +121,16 @@ layout("/layouts/platform.html"){ pageForm: { approval: false }, - showApprovalForm: false + showApprovalForm: false, + sessionOptions: [], + delegationOptions: [], + unionOptions: [] } }, created() { this.pageData() this.listOpenSession() + this.listUnion() }, methods: { openView(row) { @@ -143,12 +159,49 @@ layout("/layouts/platform.html"){ this.sessionOptions = res.data if (this.sessionOptions) { this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id) + this.listDelegation() this.pageData() } } }) }, + /** + * 根据当前教代会加载代表团下拉,切换教代会时同步清空已选代表团, + * 避免把上一届教代会的代表团条件带到当前查询里。 + */ + listDelegation() { + this.delegationOptions = [] + this.$set(this.pageForm, "delegationId", null) + if (!this.pageForm.sessionId) { + return + } + this.$axios.post("/platform/proposal/common/listDelegation", { + sessionId: this.pageForm.sessionId + }).then((res) => { + if (res.code === 0) { + this.delegationOptions = res.data + } + }) + }, + + /** + * 教代会切换后,先联动刷新代表团下拉,再按新的筛选条件重新查询列表。 + */ + meetingChange() { + this.listDelegation() + this.doSearch() + }, + + /** + * 工会下拉按系统分工会列表加载,用于按提案人所属工会筛选当前页面列表。 + */ + listUnion() { + this.$businessTool.listUnion().then((res) => { + this.unionOptions = res + }) + }, + handleTaskAction(val) { this.$refs.formRef.validate(valid => { if (!valid) return 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 3684ea98..6fdb0abb 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 @@ -13,6 +13,18 @@ layout("/layouts/platform.html"){ v-for="item in sessionOptions"> + + + + + + + + + + @@ -147,6 +159,7 @@ layout("/layouts/platform.html"){ showApprovalForm: false, sessionOptions: [], delegationOptions: [], + unionOptions: [], } }, methods: { @@ -242,11 +255,42 @@ layout("/layouts/platform.html"){ }) }, - // 教代会 - async meetingChange(val) { + /** + * 教代会切换时重新联动查询代表团,并清空上一届次已选代表团, + * 保证列表始终按当前教代会范围查询。 + */ + meetingChange() { + this.listDelegation() this.doSearch() }, + /** + * 代表团下拉只展示当前教代会下的数据,未选教代会时保持空列表。 + */ + listDelegation() { + this.delegationOptions = [] + this.$set(this.pageForm, "delegationId", null) + if (!this.pageForm.sessionId) { + return + } + this.$axios.post("/platform/proposal/common/listDelegation", { + sessionId: this.pageForm.sessionId + }).then((res) => { + if (res.code === 0) { + this.delegationOptions = res.data + } + }) + }, + + /** + * 工会下拉按系统分工会列表加载,用于按提案人所属工会筛选当前页面列表。 + */ + listUnion() { + this.$businessTool.listUnion().then((res) => { + this.unionOptions = res + }) + }, + // 查询开启的教代会 listOpenSession() { this.$axios.post("/platform/proposal/common/listOpenSession").then((res) => { @@ -254,6 +298,7 @@ layout("/layouts/platform.html"){ this.sessionOptions = res.data if (this.sessionOptions) { this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id) + this.listDelegation() this.pageData() } } @@ -263,6 +308,7 @@ layout("/layouts/platform.html"){ created() { this.pageData() this.listOpenSession() + this.listUnion() } }) diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/seconded/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/seconded/index.html index 7a0ad084..fd6dde05 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/seconded/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/seconded/index.html @@ -28,7 +28,8 @@ layout("/layouts/platform.html"){ - + @@ -68,7 +70,8 @@ layout("/layouts/platform.html"){
- {{formData.taskName}} + + 提案附议
@@ -77,16 +80,16 @@ layout("/layouts/platform.html"){ - + 取消 不同意 同意 - - 取消 - 不同意 - 同意 - + + 取消 + 不同意 + 同意 +
@@ -124,6 +127,12 @@ layout("/layouts/platform.html"){ } }, methods: { + // 附议按钮显示规则: + // 1. 当前任务进行中(taskState=10)时显示 + // 2. 当前任务已废弃(taskState=99)时,仅 invite、second、delegation、committee 节点显示 + showSecondAction(row) { + return row.taskState === 10 || (row.taskState === 99 && ["invite", "second", "delegation", "preAudit", "committee"].includes(row.taskKey)) + }, openView(row) { this.$refs.guava.edit(() => { this.showApprovalForm = false @@ -131,11 +140,13 @@ layout("/layouts/platform.html"){ }) }, openAudit(row) { - this.row = row + this.row = row this.$refs.guava.edit(() => { this.showApprovalForm = true this.formData = { processTaskId: row.taskId, + proposalId: row.id, + taskActorUserId: row.taskActorUserId, taskName: row.curTaskName, tf_opinion: "同意该提案" } @@ -151,7 +162,7 @@ layout("/layouts/platform.html"){ cancelButtonText: "取消", type: "warning" }).then(() => { - this.$axios.post("/flow/common/executeTask", { + this.$axios.post("/platform/proposal/seconded/executeTask", { data: JSON.stringify({ ...this.formData, submitType: val @@ -161,27 +172,34 @@ layout("/layouts/platform.html"){ this.$refs.guava.index() this.$message.success(res.msg) this.doSearch() - this.updateSecond(val, false) } }) }) }) }, - updateSecond(submitType, flag = true) { - this.$axios.post("/platform/proposal/seconded/updateInfo", { - proposalId: this.row.id, - taskActorUserId: this.row.taskActorUserId, - opinion: this.formData.tf_opinion, - submitType: submitType, - }).then((res) => { - if (res.code === 0) { - this.$refs.guava.index() - if(flag) this.$message.success(res.msg) - this.doSearch() - } - }) - }, + updateSecond(submitType) { + this.$confirm("您确定要提交吗?", "提示", { + confirmButtonText: "确定", + cancelButtonText: "取消", + type: "warning" + }).then(() => { + this.$axios.post("/platform/proposal/seconded/updateInfo", { + proposalId: this.row.id, + taskId: this.row.taskId, + taskActorUserId: this.row.taskActorUserId, + opinion: this.formData.tf_opinion, + submitType: submitType, + }).then((res) => { + if (res.code === 0) { + this.$refs.guava.index() + this.$message.success(res.msg) + this.doSearch() + } + }) + }) + + }, onRevoke(row) { this.$confirm("您确定要撤回吗?", "提示", { diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/unitReply/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/unitReply/index.html index cac5e072..aa7c94be 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/transact/unitReply/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/transact/unitReply/index.html @@ -144,7 +144,7 @@ layout("/layouts/platform.html"){ 编辑答复 + @click="openReplyEdit(row)" size="mini" type="primary">编辑答复 撤回 diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/aidFund/common/applyInfo.js b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/aidFund/common/applyInfo.js index 0458e777..bb536b08 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/aidFund/common/applyInfo.js +++ b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/aidFund/common/applyInfo.js @@ -9,6 +9,10 @@ const APPLY_INFO = { {{viewData.loginname}} {{viewData.mobile}} {{viewData.sex}} + + + {{$moment(viewData.arrivalAtSchoolDate).format('YYYY-MM-DD')}} {{viewData.unitName}} diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/aidFund/foundationAudit/index.html b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/aidFund/foundationAudit/index.html index 74ede38f..49de5ac7 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/aidFund/foundationAudit/index.html +++ b/src/main/resources/views/platform/zhgh/staffbenefit/medicalMutualAid/aidFund/foundationAudit/index.html @@ -60,6 +60,16 @@ layout("/layouts/platform.html"){ + 批量审核 + + 导出 + 已审核 未审核 @@ -68,6 +78,11 @@ layout("/layouts/platform.html"){ + +