bug fix
parent
de1a164f54
commit
38546f6eb1
|
|
@ -1,9 +1,8 @@
|
|||
package org.qinan.safetyeval.app.executor.institution;
|
||||
|
||||
import org.qinan.safetyeval.app.executor.support.EvalProjectNodeOverviewAssembler;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import org.qinan.safetyeval.client.api.institution.InstitutionDashboardApi;
|
||||
import org.qinan.safetyeval.client.co.institution.EvalProjectNodeItemCO;
|
||||
import org.qinan.safetyeval.client.co.institution.EvalProjectNodeOverviewCO;
|
||||
import org.qinan.safetyeval.client.co.institution.ProjectNodeCO;
|
||||
import org.qinan.safetyeval.client.co.institution.dashboard.InstitutionDashboardEvalTypeRatioCO;
|
||||
import org.qinan.safetyeval.client.co.institution.dashboard.InstitutionDashboardIndustryStatCO;
|
||||
import org.qinan.safetyeval.client.co.institution.dashboard.InstitutionDashboardNoticeCO;
|
||||
|
|
@ -11,6 +10,7 @@ import org.qinan.safetyeval.client.co.institution.dashboard.InstitutionDashboard
|
|||
import org.qinan.safetyeval.client.co.institution.dashboard.InstitutionDashboardProjectNodeStatsCO;
|
||||
import org.qinan.safetyeval.client.dto.SingleResponse;
|
||||
import org.qinan.safetyeval.domain.constant.EvalTypeEnum;
|
||||
import org.qinan.safetyeval.domain.constant.ProjectStageEnum;
|
||||
import org.qinan.safetyeval.domain.constant.basic.IndustryEnum;
|
||||
import org.qinan.safetyeval.domain.entity.EvalCustomerEntity;
|
||||
import org.qinan.safetyeval.domain.entity.EvalProjectEntity;
|
||||
|
|
@ -27,11 +27,13 @@ import org.springframework.context.annotation.Lazy;
|
|||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
|
@ -47,9 +49,6 @@ public class InstitutionDashboardExecutor implements InstitutionDashboardApi {
|
|||
@Resource
|
||||
private EvalProjectGateway evalProjectGateway;
|
||||
|
||||
@Resource
|
||||
private EvalProjectNodeOverviewAssembler evalProjectNodeOverviewAssembler;
|
||||
|
||||
@Resource
|
||||
private SafetyMessageGateway safetyMessageGateway;
|
||||
|
||||
|
|
@ -82,51 +81,18 @@ public class InstitutionDashboardExecutor implements InstitutionDashboardApi {
|
|||
@Override
|
||||
public SingleResponse<InstitutionDashboardProjectNodeStatsCO> projectNodeStats() {
|
||||
Long orgId = ThreadLocalUserInfoAdapter.getOrgId() ;
|
||||
List<EvalProjectEntity> projects = listOrgProjects(orgId);
|
||||
|
||||
int total = projects.size();
|
||||
int statutory = (int) projects.stream().filter(p -> Boolean.TRUE.equals(p.getIsStatutory())).count();
|
||||
|
||||
// 节点待办数(待办=节点状态为「未开始」)
|
||||
LinkedHashMap<String, Integer> pending = new LinkedHashMap<>();
|
||||
for (String code : NODE_DISPLAY.keySet()) {
|
||||
pending.put(code, 0);
|
||||
if (orgId == null) {
|
||||
return SingleResponse.success(new InstitutionDashboardProjectNodeStatsCO());
|
||||
}
|
||||
for (EvalProjectEntity p : projects) {
|
||||
try {
|
||||
EvalProjectNodeOverviewCO ov = evalProjectNodeOverviewAssembler.buildForInstitution(p.getId());
|
||||
if (ov == null || ov.getNodes() == null) {
|
||||
continue;
|
||||
}
|
||||
for (EvalProjectNodeItemCO n : ov.getNodes()) {
|
||||
String code = n.getNodeCode();
|
||||
if (code != null && pending.containsKey(code) && "未开始".equals(n.getStatusName())) {
|
||||
pending.put(code, pending.get(code) + 1);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 单项目装配异常忽略,保证其余节点统计可用
|
||||
}
|
||||
}
|
||||
|
||||
List<InstitutionDashboardProjectNodeStatsCO.NodeStat> nodeStats = new ArrayList<>();
|
||||
for (Map.Entry<String, String> entry : NODE_DISPLAY.entrySet()) {
|
||||
InstitutionDashboardProjectNodeStatsCO.NodeStat ns = new InstitutionDashboardProjectNodeStatsCO.NodeStat();
|
||||
ns.setNodeCode(entry.getKey());
|
||||
ns.setNodeName(entry.getValue());
|
||||
ns.setPendingCount(pending.getOrDefault(entry.getKey(), 0));
|
||||
nodeStats.add(ns);
|
||||
}
|
||||
|
||||
int archived = (int) projects.stream().filter(p -> Boolean.TRUE.equals(p.getArchiveFlag())).count();
|
||||
int delayed = (int) evalProjectGateway.countByOrgIdAndProgressStatus(orgId, "DELAY");
|
||||
// 只查询统计所需最小字段:id、project_node、plan_end_date、archive_flag、is_statutory
|
||||
List<EvalProjectEntity> projects = evalProjectGateway.listNodeStatFieldsByOrgId(orgId);
|
||||
|
||||
InstitutionDashboardProjectNodeStatsCO co = new InstitutionDashboardProjectNodeStatsCO();
|
||||
co.setTotalProjects(total);
|
||||
co.setStatutoryProjects(statutory);
|
||||
co.setNodeStats(nodeStats);
|
||||
co.setArchivedProjectCount(archived);
|
||||
co.setDelayedProjectCount(delayed);
|
||||
co.setTotalProjects(projects.size());
|
||||
co.setStatutoryProjects((int) projects.stream().filter(p -> Boolean.TRUE.equals(p.getIsStatutory())).count());
|
||||
co.setArchivedProjectCount((int) projects.stream().filter(p -> Objects.equals(p.getArchiveFlag(), 1)).count());
|
||||
co.setDelayedProjectCount(countDelayed(projects));
|
||||
co.setNodeStats(buildNodeStats(projects));
|
||||
return SingleResponse.success(co);
|
||||
}
|
||||
|
||||
|
|
@ -249,6 +215,70 @@ public class InstitutionDashboardExecutor implements InstitutionDashboardApi {
|
|||
|
||||
// ============================ 通用方法 ============================
|
||||
|
||||
/**
|
||||
* 统计各流程节点待办数(待办=project_node JSON 中该节点 state=0 未完成)
|
||||
*
|
||||
* @param projects 机构项目列表
|
||||
* @return 8 个节点的待办统计
|
||||
*/
|
||||
private List<InstitutionDashboardProjectNodeStatsCO.NodeStat> buildNodeStats(List<EvalProjectEntity> projects) {
|
||||
LinkedHashMap<String, Integer> pending = new LinkedHashMap<>();
|
||||
for (String code : NODE_DISPLAY.keySet()) {
|
||||
pending.put(code, 0);
|
||||
}
|
||||
for (EvalProjectEntity p : projects) {
|
||||
for (ProjectNodeCO n : parseNodes(p.getProjectNode())) {
|
||||
ProjectStageEnum stage = ProjectStageEnum.fromVal(n.getType());
|
||||
if (stage != null && NODE_DISPLAY.containsKey(stage.getNode())
|
||||
&& Integer.valueOf(0).equals(n.getState())) {
|
||||
pending.put(stage.getNode(), pending.get(stage.getNode()) + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<InstitutionDashboardProjectNodeStatsCO.NodeStat> nodeStats = new ArrayList<>();
|
||||
for (Map.Entry<String, String> entry : NODE_DISPLAY.entrySet()) {
|
||||
InstitutionDashboardProjectNodeStatsCO.NodeStat ns = new InstitutionDashboardProjectNodeStatsCO.NodeStat();
|
||||
ns.setNodeCode(entry.getKey());
|
||||
ns.setNodeName(entry.getValue());
|
||||
ns.setPendingCount(pending.getOrDefault(entry.getKey(), 0));
|
||||
nodeStats.add(ns);
|
||||
}
|
||||
return nodeStats;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析 project_node JSON([{"type":"RISK_ANALYSIS","state":0}]),空值/异常返回空列表保证统计可用
|
||||
*
|
||||
* @param projectNodeJson 节点进度 JSON 字符串
|
||||
* @return 节点列表
|
||||
*/
|
||||
private List<ProjectNodeCO> parseNodes(String projectNodeJson) {
|
||||
if (projectNodeJson == null || projectNodeJson.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
try {
|
||||
List<ProjectNodeCO> nodes = JSON.parseArray(projectNodeJson, ProjectNodeCO.class);
|
||||
return nodes != null ? nodes : new ArrayList<>();
|
||||
} catch (Exception e) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计延期项目数(延期=计划结束日期早于今天且未归档)
|
||||
*
|
||||
* @param projects 机构项目列表
|
||||
* @return 延期项目数
|
||||
*/
|
||||
private int countDelayed(List<EvalProjectEntity> projects) {
|
||||
LocalDate today = LocalDate.now();
|
||||
return (int) projects.stream()
|
||||
.filter(p -> p.getPlanEndDate() != null && p.getPlanEndDate().isBefore(today)
|
||||
&& !Objects.equals(p.getArchiveFlag(), 1))
|
||||
.count();
|
||||
}
|
||||
|
||||
private List<EvalProjectEntity> listOrgProjects(Long orgId) {
|
||||
EvalProjectQuery q = new EvalProjectQuery();
|
||||
q.setOrgId(orgId);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import org.qinan.safetyeval.domain.entity.EvalProjectEntity;
|
|||
import org.qinan.safetyeval.domain.query.EvalProjectQuery;
|
||||
import org.qinan.safetyeval.domain.query.PageResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface EvalProjectGateway {
|
||||
|
||||
EvalProjectEntity save(EvalProjectEntity entity);
|
||||
|
|
@ -25,4 +27,12 @@ public interface EvalProjectGateway {
|
|||
void editProjectNode(Long projectId, String val);
|
||||
|
||||
EvalProjectEntity findByControlledNumber(String controlledNumber);
|
||||
|
||||
/**
|
||||
* 按机构查询节点统计所需的最小字段集合(id、project_node、plan_end_date、archive_flag、is_statutory)
|
||||
*
|
||||
* @param orgId 机构id
|
||||
* @return 项目实体列表(仅统计所需字段有值)
|
||||
*/
|
||||
List<EvalProjectEntity> listNodeStatFieldsByOrgId(Long orgId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,6 +142,21 @@ public class EvalProjectGatewayImpl implements EvalProjectGateway {
|
|||
return dataObject == null ? null : evalProjectDoConvertor.convertDoToE(dataObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EvalProjectEntity> listNodeStatFieldsByOrgId(Long orgId) {
|
||||
LambdaQueryWrapper<EvalProjectDO> wrapper = new LambdaQueryWrapper<>();
|
||||
// 只取统计所需最小字段,减少查询与转换开销
|
||||
wrapper.select(EvalProjectDO::getId, EvalProjectDO::getProjectNode, EvalProjectDO::getPlanEndDate,
|
||||
EvalProjectDO::getArchiveFlag, EvalProjectDO::getIsStatutory)
|
||||
.eq(EvalProjectDO::getDeleteEnum, "false");
|
||||
if (orgId != null) {
|
||||
wrapper.eq(EvalProjectDO::getOrgId, orgId);
|
||||
}
|
||||
return evalProjectMapper.selectList(wrapper).stream()
|
||||
.map(evalProjectDoConvertor::convertDoToE)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editProjectNode(Long projectId, String val) {
|
||||
EvalProjectDO evalProjectDO = evalProjectMapper.selectById(projectId);
|
||||
|
|
|
|||
Loading…
Reference in New Issue