From 80774fdb0cea9998308da87d94c26169321a3d5a Mon Sep 17 00:00:00 2001 From: hongqiwei <1143662660@qq.com> Date: Tue, 15 Sep 2026 10:53:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=B0=E5=A4=A7bug=E6=95=B4=E6=94=B9,?= =?UTF-8?q?=E6=8F=90=E6=A1=88=E6=95=B0=E6=8D=AE=E7=9C=8B=E6=9D=BF=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E5=A2=9E=E5=8A=A0=E5=AD=97=E6=AE=B5=EF=BC=8C=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E9=87=8D=E7=82=B9=E6=8F=90=E6=A1=88=EF=BC=9B=E4=BC=9A?= =?UTF-8?q?=E5=91=98=E6=95=B0=E6=8D=AE=E7=9C=8B=E6=9D=BF=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=B9=B4=E5=90=8C=E6=AF=94=EF=BC=8C=E4=BF=AE=E5=A4=8D=E4=BC=9A?= =?UTF-8?q?=E5=91=98=E4=BA=BA=E5=91=98=E5=8D=A0=E6=AF=94=E6=95=B0=E5=AD=97?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E6=98=BE=E7=A4=BA=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProposalDashboardController.java | 194 ++------------ .../service/common/ProposalCommonService.java | 18 ++ .../common/ProposalCommonServiceImpl.java | 241 +++++++++++++++++- .../democratic/proposal/dashboard/index.html | 29 ++- .../staffmanage/member/info/board/index.html | 84 ++++-- 5 files changed, 351 insertions(+), 215 deletions(-) diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/dashboard/ProposalDashboardController.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/dashboard/ProposalDashboardController.java index 2cbd8a50..2ab6ff31 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/dashboard/ProposalDashboardController.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/controller/dashboard/ProposalDashboardController.java @@ -1,66 +1,23 @@ package com.budwk.app.zhgh.democratic.proposal.controller.dashboard; import cn.dev33.satoken.annotation.SaCheckPermission; -import cn.hutool.core.util.StrUtil; -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.flow.engine.model.ProcessModel; -import com.budwk.app.flow.engine.model.TaskModel; -import com.budwk.app.flow.entity.ProcessDefine; -import com.budwk.app.flow.enums.ProcessTaskStateEnum; -import com.budwk.app.flow.service.ProcessDefineService; -import com.budwk.app.sys.models.Sys_dict; -import com.budwk.app.sys.services.SysDictService; -import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo; import com.budwk.app.zhgh.democratic.proposal.service.common.ProposalCommonService; import io.swagger.annotations.Api; -import org.nutz.dao.Cnd; -import org.nutz.dao.Dao; -import org.nutz.dao.Sqls; -import org.nutz.dao.sql.Sql; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; -import org.nutz.lang.util.NutMap; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Param; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - @IocBean @At("/platform/proposal/dashboard") @Api("提案数据看板") @Ok("json:full") public class ProposalDashboardController { - - /** - * 工作台表格允许排序的字段映射,值为查询中的真实字段或安全别名。 - */ - private static final Map DASHBOARD_ORDER_COLUMNS = Map.ofEntries( - Map.entry("code", "info.code"), - Map.entry("name", "info.name"), - Map.entry("createUserName", "info.createUserName"), - Map.entry("typeName", "typeName"), - Map.entry("delegationName", "delegationName"), - Map.entry("caseFilingResult", "info.caseFilingResult"), - Map.entry("isConsolidation", "info.isConsolidation"), - Map.entry("masterUnitName", "masterUnitName"), - Map.entry("slaveUnitNames", "slaveUnitNames"), - Map.entry("curTaskName", "curTaskName"), - Map.entry("instanceState", "instanceState") - ); - @Inject private ProposalCommonService proposalCommonService; - @Inject - private ProcessDefineService processDefineService; - @Inject - private SysDictService sysDictService; - @Inject - private Dao dao; @At("") @Ok("beetl:/platform/zhgh/democratic/proposal/dashboard/index.html") @@ -68,147 +25,30 @@ public class ProposalDashboardController { public void index() { } + /** + * 接收届次ID查询卡片;Result.data 为卡片列表,含 count 或 todoCount/doneCount。 + * @param sessionId 教代会届次ID;为空时卡片数量为零 + * @return 统一结果对象,data 为各节点和立案结果统计 + */ @At @SaCheckPermission("proposal.dashboard") public Result listNode(@Param("sessionId") String sessionId) { - List nodes = new ArrayList<>(); - - // 提案总数 - nodes.add(NutMap.NEW().addv("name", "提案总数").addv("id", "total").addv("type", "total").addv("count", 0)); - - // 节点 - ProcessDefine define = processDefineService.getLastByName("JDHTA_NC"); - ProcessModel processModel = processDefineService.processDefineToModel(define); - // 按流程图的连线关系遍历任务节点,保证看板展示顺序与流程图一致。 - List taskModels = processModel.getModels(TaskModel.class); - - List excludeNodes = new ArrayList<>(3); - excludeNodes.add("撰写提案"); - excludeNodes.add("邀请附议人"); - excludeNodes.add("提案附议"); - - // opinion_unit_reply、two_unit_reply 为临时屏蔽的承办单位答复节点,不在看板展示。 - List hiddenNodeIds = List.of("opinion_unit_reply", "two_unit_reply"); - List taskNodes = new ArrayList<>(taskModels.stream() - .filter(taskModel -> !excludeNodes.contains(taskModel.getDisplayName())) - .filter(taskModel -> !hiddenNodeIds.contains(taskModel.getName())) - .map(taskModel -> NutMap.NEW() - .addv("name", taskModel.getDisplayName()) - .addv("id", taskModel.getName()) - .addv("type", "task") - .addv("count", 0) - .addv("todoCount", 0) - .addv("doneCount", 0) - ).toList()); - - // 立案结果 - List caseFilingResult = sysDictService.getSubListByCode("PROPOSAL_CASE_FILING_RESULT"); - List caseFilingResultNodes = new ArrayList<>(); - for (Sys_dict dict : caseFilingResult) { - caseFilingResultNodes.add(NutMap.NEW() - .addv("name", dict.getName()) - .addv("id", dict.getCode()) - .addv("type", "caseFilingResult") - .addv("count", 0)); - } - - // 立案结果需展示在委员会确认承办单位之前,反馈评价统一固定到看板末尾。 - List feedbackNodes = taskNodes.stream() - .filter(taskNode -> "feedback".equals(taskNode.getString("id"))) - .toList(); - taskNodes.removeIf(taskNode -> "feedback".equals(taskNode.getString("id"))); - int committeeFilingUnitIndex = taskNodes.size(); - for (int i = 0; i < taskNodes.size(); i++) { - if ("committeeFilingUnit".equals(taskNodes.get(i).getString("id"))) { - committeeFilingUnitIndex = i; - break; - } - } - taskNodes.addAll(committeeFilingUnitIndex, caseFilingResultNodes); - nodes.addAll(taskNodes); - nodes.addAll(feedbackNodes); - - Map taskProposalCounts = proposalCommonService.countDashboardTaskProposals(sessionId); - - for (NutMap node : nodes) { - if (node.getString("type").equals("task")) { - NutMap taskCount = taskProposalCounts.get(node.getString("id")); - node.put("todoCount", taskCount == null ? 0 : taskCount.getLong("todoCount", 0L)); - node.put("doneCount", taskCount == null ? 0 : taskCount.getLong("doneCount", 0L)); - } else if (node.getString("type").equals("total")) { - int count = dao.count(ProposalInfo.class, Cnd.where(ProposalInfo::getSessionId, "=", sessionId)); - node.put("count", count); - } else if (node.getString("type").equals("caseFilingResult")) { - int count = dao.count(ProposalInfo.class, Cnd.where(ProposalInfo::getSessionId, "=", sessionId).and(ProposalInfo::getCaseFilingResult, "=", node.getString("id"))); - node.put("count", count); - } - } - - return Result.success(nodes); + return Result.success(proposalCommonService.listDashboardNodes(sessionId)); } - + /** + * 接收看板筛选参数,返回与卡片统计范围一致的提案分页数据。 + * @param pageForm pageNumber/pageSize 为页码和每页条数,pageOrderName/pageOrderBy 为排序参数 + * @param sessionId 教代会届次ID;为空时返回空列表 + * @param selectNodeId task 节点编码或立案结果字典编码 + * @param selectNodeType task、total 或 caseFilingResult;为空时按总数查询 + * @param selectNodeMode done 表示已办,其余值表示待办 + * @return Result.data.list 为提案列表,Result.data.totalCount 为筛选后的总数 + */ @At @SaCheckPermission("proposal.dashboard") public Result pageData(PageForm pageForm, String sessionId, String selectNodeId, String selectNodeType, String selectNodeMode) { - Sql sql = Sqls.create(""" - SELECT - info.*, - type.name AS typeName, - tcs.fullName AS sessionName, - tcd.`name` AS delegationName, - ins.id AS instanceId, - ins.businessNo, - ins.state instanceState, - ins.variable instanceVariable, - ins.processDefineId instanceProcessDefineId, - t.displayName curTaskName, - GROUP_CONCAT(DISTINCT CASE WHEN pru.isMaster = 1 THEN pru.unitName END) AS masterUnitName, - GROUP_CONCAT(DISTINCT CASE WHEN pru.isMaster = 0 THEN pru.unitName END) AS slaveUnitNames - FROM - proposal_info info - LEFT JOIN proposal_type type on type.id = info.typeId - LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId - LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId - LEFT JOIN teacher_congress_delegate tcde on tcde.loginName = info.createUserLoginName - LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id - LEFT JOIN proposal_reply_unit pru ON pru.proposalId = info.id - LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id AND t.taskState = @taskState - $condition - """); - Cnd cnd = Cnd.NEW(); - cnd.and("info.sessionId", "=", sessionId); - cnd.groupBy("info.id"); - - // 默认显示进行中的任务 - sql.setParam("taskState", ProcessTaskStateEnum.DOING.getCode()); - - if (StrUtil.isNotBlank(selectNodeType) && StrUtil.isNotBlank(selectNodeId)) { - switch (selectNodeType) { - case "task": - cnd.and("t.taskName", "=", selectNodeId); - - if (selectNodeMode.equals("todo")) { - sql.setParam("taskState", ProcessTaskStateEnum.DOING.getCode()); - } else { - sql.setParam("taskState", ProcessTaskStateEnum.FINISHED.getCode()); - } - - break; - case "total": - break; - case "caseFilingResult": - cnd.and("info.caseFilingResult", "=", selectNodeId); - break; - } - } - - // 根据工作台字段白名单追加排序,未选择排序时保持原有查询顺序。 - proposalCommonService.applySafePageOrder(cnd, pageForm, DASHBOARD_ORDER_COLUMNS); - sql.setCondition(cnd); - Pagination pagination = proposalCommonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); - return Result.success(pagination); + return Result.success(proposalCommonService.pageDashboardData(pageForm, sessionId, + selectNodeId, selectNodeType, selectNodeMode)); } - - } diff --git a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java index 3ee2de78..d2ab48a7 100644 --- a/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java +++ b/src/main/java/com/budwk/app/zhgh/democratic/proposal/service/common/ProposalCommonService.java @@ -288,4 +288,22 @@ public interface ProposalCommonService extends BaseService { * @return 键为流程节点编码、值为待办和已办数量的统计结果 */ Map countDashboardTaskProposals(String sessionId); + /** + * 查询看板卡片,统计范围与列表一致。 + * @param sessionId 届次ID;为空时数量为零 + * @return 包含节点编码、类型、名称和统计数量的卡片列表 + */ + List listDashboardNodes(String sessionId); + + /** + * 查询看板提案分页数据。 + * @param pageForm 分页及排序参数 + * @param sessionId 届次ID;为空时返回空列表 + * @param selectNodeId 流程节点编码或立案结果编码 + * @param selectNodeType task、total 或 caseFilingResult + * @param selectNodeMode done 表示已办,其余值表示待办 + * @return 分页对象,list 为提案记录,totalCount 为相同条件下的提案总数 + */ + Pagination pageDashboardData(PageForm pageForm, String sessionId, String selectNodeId, + String selectNodeType, String selectNodeMode); } 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 c7b1ff71..dbc10798 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 @@ -23,6 +23,10 @@ import com.budwk.app.base.utils.PageUtil; import com.budwk.app.base.utils.SysOfficeTemplateUtil; import com.budwk.app.flow.constant.FlowConst; import com.budwk.app.flow.engine.FlowEngine; +import com.budwk.app.flow.engine.model.ProcessModel; +import com.budwk.app.flow.engine.model.TaskModel; +import com.budwk.app.flow.entity.ProcessDefine; +import com.budwk.app.flow.service.ProcessDefineService; import com.budwk.app.flow.engine.util.FlowUtil; import com.budwk.app.flow.entity.ProcessInstance; import com.budwk.app.flow.entity.ProcessTask; @@ -82,6 +86,24 @@ import java.util.stream.Collectors; @IocBean(args = {"refer:dao"}) public class ProposalCommonServiceImpl extends BaseServiceImpl implements ProposalCommonService { + /** + * 工作台表格允许排序的字段映射,值为查询中的真实字段或安全别名。 + */ + private static final Map DASHBOARD_ORDER_COLUMNS = Map.ofEntries( + Map.entry("code", "info.code"), + Map.entry("name", "info.name"), + Map.entry("createUserName", "info.createUserName"), + Map.entry("typeName", "typeName"), + Map.entry("delegationName", "delegationName"), + Map.entry("caseFilingResult", "info.caseFilingResult"), + Map.entry("caseFilingType", "info.caseFilingType"), + Map.entry("isConsolidation", "info.isConsolidation"), + Map.entry("masterUnitName", "masterUnitName"), + Map.entry("slaveUnitNames", "slaveUnitNames"), + Map.entry("curTaskName", "curTaskName"), + Map.entry("instanceState", "instanceState") + ); + /** 确定立案提案的 Word 模板编码。 */ private static final String PROPOSAL_CONFIRM_FILING_TEMPLATE_CODE = "proposal_confirm_filing"; @@ -187,6 +209,8 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp @Inject private SysDictService sysDictService; @Inject + private ProcessDefineService processDefineService; + @Inject private SysUserService sysUserService; @Inject private TeacherCongressDelegateService teacherCongressDelegateService; @@ -506,6 +530,216 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp return sql; } + /** + * 获取提案看板卡片,沿用现有节点顺序,数量与下方列表共用同一数据范围。 + * @param sessionId 教代会届次ID;为空时所有卡片数量为零 + * @return 卡片列表;任务卡片含 todoCount/doneCount,其他卡片含 count + */ + @Override + public List listDashboardNodes(String sessionId) { + List nodes = new ArrayList<>(); + + // 提案总数 + nodes.add(NutMap.NEW().addv("name", "提案总数").addv("id", "total").addv("type", "total").addv("count", 0)); + + // 节点 + ProcessDefine define = processDefineService.getLastByName("JDHTA_NC"); + ProcessModel processModel = processDefineService.processDefineToModel(define); + // 按流程图的连线关系遍历任务节点,保证看板展示顺序与流程图一致。 + List taskModels = processModel.getModels(TaskModel.class); + + List excludeNodes = new ArrayList<>(3); + excludeNodes.add("撰写提案"); + excludeNodes.add("邀请附议人"); + excludeNodes.add("提案附议"); + + // opinion_unit_reply、two_unit_reply 为临时屏蔽的承办单位答复节点,不在看板展示。 + List hiddenNodeIds = List.of("opinion_unit_reply", "two_unit_reply"); + List taskNodes = new ArrayList<>(taskModels.stream() + .filter(taskModel -> !excludeNodes.contains(taskModel.getDisplayName())) + .filter(taskModel -> !hiddenNodeIds.contains(taskModel.getName())) + .map(taskModel -> NutMap.NEW() + .addv("name", taskModel.getDisplayName()) + .addv("id", taskModel.getName()) + .addv("type", "task") + .addv("count", 0) + .addv("todoCount", 0) + .addv("doneCount", 0) + ).toList()); + + // 立案结果 + List caseFilingResult = sysDictService.getSubListByCode("PROPOSAL_CASE_FILING_RESULT"); + List caseFilingResultNodes = new ArrayList<>(); + for (Sys_dict dict : caseFilingResult) { + caseFilingResultNodes.add(NutMap.NEW() + .addv("name", dict.getName()) + .addv("id", dict.getCode()) + .addv("type", "caseFilingResult") + .addv("count", 0)); + } + + // 立案结果需展示在委员会确认承办单位之前,反馈评价统一固定到看板末尾。 + List feedbackNodes = taskNodes.stream() + .filter(taskNode -> "feedback".equals(taskNode.getString("id"))) + .toList(); + taskNodes.removeIf(taskNode -> "feedback".equals(taskNode.getString("id"))); + int committeeFilingUnitIndex = taskNodes.size(); + for (int i = 0; i < taskNodes.size(); i++) { + if ("committeeFilingUnit".equals(taskNodes.get(i).getString("id"))) { + committeeFilingUnitIndex = i; + break; + } + } + taskNodes.addAll(committeeFilingUnitIndex, caseFilingResultNodes); + nodes.addAll(taskNodes); + nodes.addAll(feedbackNodes); + + Map categoryCounts = countDashboardCategories(sessionId); + Map taskProposalCounts = countDashboardTaskProposals(sessionId); + + for (NutMap node : nodes) { + if (node.getString("type").equals("task")) { + NutMap taskCount = taskProposalCounts.get(node.getString("id")); + node.put("todoCount", taskCount == null ? 0 : taskCount.getLong("todoCount", 0L)); + node.put("doneCount", taskCount == null ? 0 : taskCount.getLong("doneCount", 0L)); + } else if (node.getString("type").equals("total")) { + node.put("count", categoryCounts.getOrDefault("total", 0L)); + } else if (node.getString("type").equals("caseFilingResult")) { + node.put("count", categoryCounts.getOrDefault(node.getString("id"), 0L)); + } + } + + return nodes; + } + + /** + * 查询看板提案列表,统一使用附议完成后的提案范围,按提案ID去重。 + * @param pageForm 分页和白名单排序参数 + * @param sessionId 教代会届次ID;为空时返回空列表 + * @param selectNodeId 节点编码或立案结果字典编码 + * @param selectNodeType task、total、caseFilingResult;为空时查询总数列表 + * @param selectNodeMode done 查询已办任务,其余值查询待办任务 + * @return 含 list 和 totalCount 的分页结果 + */ + @Override + public Pagination pageDashboardData(PageForm pageForm, String sessionId, String selectNodeId, + String selectNodeType, String selectNodeMode) { + Sql sql = Sqls.create(""" + SELECT + info.*, + type.name AS typeName, + tcs.fullName AS sessionName, + tcd.`name` AS delegationName, + ins.id AS instanceId, + ins.businessNo, + ins.state instanceState, + ins.variable instanceVariable, + ins.processDefineId instanceProcessDefineId, + t.displayName curTaskName, + GROUP_CONCAT(DISTINCT CASE WHEN pru.isMaster = 1 THEN pru.unitName END) AS masterUnitName, + GROUP_CONCAT(DISTINCT CASE WHEN pru.isMaster = 0 THEN pru.unitName END) AS slaveUnitNames + FROM + proposal_info info + LEFT JOIN proposal_type type on type.id = info.typeId + LEFT JOIN teacher_congress_session tcs on tcs.id = info.sessionId + LEFT JOIN teacher_congress_delegation tcd on tcd.id = info.delegationId + LEFT JOIN teacher_congress_delegate tcde on tcde.loginName = info.createUserLoginName + LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id + LEFT JOIN proposal_reply_unit pru ON pru.proposalId = info.id + LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id AND t.taskState = @taskState + $condition + """); + Cnd cnd = buildDashboardCondition(sessionId); + cnd.groupBy("info.id"); + + // 默认显示进行中的任务 + sql.setParam("taskState", ProcessTaskStateEnum.DOING.getCode()); + + if (StrUtil.isNotBlank(selectNodeType) && StrUtil.isNotBlank(selectNodeId)) { + switch (selectNodeType) { + case "task": + cnd.and("t.taskName", "=", selectNodeId); + + if (!"done".equals(selectNodeMode)) { + sql.setParam("taskState", ProcessTaskStateEnum.DOING.getCode()); + } else { + sql.setParam("taskState", ProcessTaskStateEnum.FINISHED.getCode()); + } + + break; + case "total": + break; + case "caseFilingResult": + cnd.and("info.caseFilingResult", "=", selectNodeId); + break; + } + } + + // 只接受白名单排序字段,复用现有分页能力。 + applySafePageOrder(cnd, pageForm, DASHBOARD_ORDER_COLUMNS); + sql.setCondition(cnd); + return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + } + + /** + * 统计看板总数及立案结果;一次按结果分组后求和,确保卡片与列表口径一致。 + * @param sessionId 教代会届次ID + * @return total 为提案总数,其他键为立案结果编码 + */ + private Map countDashboardCategories(String sessionId) { + Sql sql = Sqls.create("SELECT info.caseFilingResult, COUNT(1) AS proposalCount FROM proposal_info info $condition"); + Cnd cnd = buildDashboardCondition(sessionId); + cnd.groupBy("info.caseFilingResult"); + sql.setCondition(cnd); + Map counts = new HashMap<>(); + long total = 0L; + for (NutMap row : listMap(sql)) { + long count = row.getLong("proposalCount", 0L); + total += count; + if (StrUtil.isNotBlank(row.getString("caseFilingResult"))) { + counts.put(row.getString("caseFilingResult"), count); + } + } + counts.put("total", total); + return counts; + } + + /** + * 构建看板统一范围:迁入提案按参考业务阶段排除草稿、附议阶段;新提案按实际WF任务判断。 + * 历史迁入实例可能缺少当前任务,不能仅因缺任务而漏算已进入审核的历史提案。 + * 新WF提案的旧 stateCode 不随每个节点更新,必须读取有效审核任务,并排除已退回撰写/附议的实例。 + * @param sessionId 届次ID;清空选择时返回空范围,避免跨届次查询 + * @return 仅包含筛选条件、不包含排序和分组的 Cnd + */ + private Cnd buildDashboardCondition(String sessionId) { + Cnd cnd = Cnd.where("info.sessionId", "=", StrUtil.blankToDefault(sessionId, "")); + cnd.and(new Static(""" + EXISTS ( + SELECT 1 FROM wf_process_instance scopeIns + WHERE scopeIns.businessNo = info.id + AND ( + (JSON_UNQUOTE(JSON_EXTRACT(scopeIns.variable, '$.legacyV3')) = 'true' AND info.stateCode >= 200) + OR ( + COALESCE(JSON_UNQUOTE(JSON_EXTRACT(scopeIns.variable, '$.legacyV3')), 'false') <> 'true' + AND EXISTS ( + SELECT 1 FROM wf_process_task scopeTask + WHERE scopeTask.processInstanceId = scopeIns.id + AND scopeTask.taskName NOT IN ('startTask', 'invite', 'second') + AND scopeTask.taskState IN (10, 20) + ) + AND NOT EXISTS ( + SELECT 1 FROM wf_process_task earlyTask + WHERE earlyTask.processInstanceId = scopeIns.id + AND earlyTask.taskName IN ('startTask', 'invite', 'second') + AND earlyTask.taskState = 10 + ) + ) + ) + ) + """)); + return cnd; + } + /** * 按提案ID去重统计数据看板的流程节点数量。 * 同一提案因撤回、退回等再次经过同一节点时,任务表会保留多条已办记录; @@ -524,10 +758,11 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl imp FROM wf_process_task t INNER JOIN wf_process_instance ins ON ins.id = t.processInstanceId INNER JOIN proposal_info info ON info.id = ins.businessNo - WHERE info.sessionId = @sessionId - GROUP BY t.taskName + $condition """); - sql.setParam("sessionId", sessionId); + Cnd cnd = buildDashboardCondition(sessionId); + cnd.groupBy("t.taskName"); + sql.setCondition(cnd); sql.setParam("doingState", ProcessTaskStateEnum.DOING.getCode()); sql.setParam("finishedState", ProcessTaskStateEnum.FINISHED.getCode()); List taskCounts = listMap(sql); diff --git a/src/main/resources/views/platform/zhgh/democratic/proposal/dashboard/index.html b/src/main/resources/views/platform/zhgh/democratic/proposal/dashboard/index.html index ad0d6390..f5b4e880 100644 --- a/src/main/resources/views/platform/zhgh/democratic/proposal/dashboard/index.html +++ b/src/main/resources/views/platform/zhgh/democratic/proposal/dashboard/index.html @@ -206,6 +206,15 @@ layout("/layouts/platform.html"){ + + + +