bug fix
parent
de1a164f54
commit
38546f6eb1
|
|
@ -1,9 +1,8 @@
|
||||||
package org.qinan.safetyeval.app.executor.institution;
|
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.api.institution.InstitutionDashboardApi;
|
||||||
import org.qinan.safetyeval.client.co.institution.EvalProjectNodeItemCO;
|
import org.qinan.safetyeval.client.co.institution.ProjectNodeCO;
|
||||||
import org.qinan.safetyeval.client.co.institution.EvalProjectNodeOverviewCO;
|
|
||||||
import org.qinan.safetyeval.client.co.institution.dashboard.InstitutionDashboardEvalTypeRatioCO;
|
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.InstitutionDashboardIndustryStatCO;
|
||||||
import org.qinan.safetyeval.client.co.institution.dashboard.InstitutionDashboardNoticeCO;
|
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.co.institution.dashboard.InstitutionDashboardProjectNodeStatsCO;
|
||||||
import org.qinan.safetyeval.client.dto.SingleResponse;
|
import org.qinan.safetyeval.client.dto.SingleResponse;
|
||||||
import org.qinan.safetyeval.domain.constant.EvalTypeEnum;
|
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.constant.basic.IndustryEnum;
|
||||||
import org.qinan.safetyeval.domain.entity.EvalCustomerEntity;
|
import org.qinan.safetyeval.domain.entity.EvalCustomerEntity;
|
||||||
import org.qinan.safetyeval.domain.entity.EvalProjectEntity;
|
import org.qinan.safetyeval.domain.entity.EvalProjectEntity;
|
||||||
|
|
@ -27,11 +27,13 @@ import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -47,9 +49,6 @@ public class InstitutionDashboardExecutor implements InstitutionDashboardApi {
|
||||||
@Resource
|
@Resource
|
||||||
private EvalProjectGateway evalProjectGateway;
|
private EvalProjectGateway evalProjectGateway;
|
||||||
|
|
||||||
@Resource
|
|
||||||
private EvalProjectNodeOverviewAssembler evalProjectNodeOverviewAssembler;
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private SafetyMessageGateway safetyMessageGateway;
|
private SafetyMessageGateway safetyMessageGateway;
|
||||||
|
|
||||||
|
|
@ -82,51 +81,18 @@ public class InstitutionDashboardExecutor implements InstitutionDashboardApi {
|
||||||
@Override
|
@Override
|
||||||
public SingleResponse<InstitutionDashboardProjectNodeStatsCO> projectNodeStats() {
|
public SingleResponse<InstitutionDashboardProjectNodeStatsCO> projectNodeStats() {
|
||||||
Long orgId = ThreadLocalUserInfoAdapter.getOrgId() ;
|
Long orgId = ThreadLocalUserInfoAdapter.getOrgId() ;
|
||||||
List<EvalProjectEntity> projects = listOrgProjects(orgId);
|
if (orgId == null) {
|
||||||
|
return SingleResponse.success(new InstitutionDashboardProjectNodeStatsCO());
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
for (EvalProjectEntity p : projects) {
|
// 只查询统计所需最小字段:id、project_node、plan_end_date、archive_flag、is_statutory
|
||||||
try {
|
List<EvalProjectEntity> projects = evalProjectGateway.listNodeStatFieldsByOrgId(orgId);
|
||||||
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");
|
|
||||||
|
|
||||||
InstitutionDashboardProjectNodeStatsCO co = new InstitutionDashboardProjectNodeStatsCO();
|
InstitutionDashboardProjectNodeStatsCO co = new InstitutionDashboardProjectNodeStatsCO();
|
||||||
co.setTotalProjects(total);
|
co.setTotalProjects(projects.size());
|
||||||
co.setStatutoryProjects(statutory);
|
co.setStatutoryProjects((int) projects.stream().filter(p -> Boolean.TRUE.equals(p.getIsStatutory())).count());
|
||||||
co.setNodeStats(nodeStats);
|
co.setArchivedProjectCount((int) projects.stream().filter(p -> Objects.equals(p.getArchiveFlag(), 1)).count());
|
||||||
co.setArchivedProjectCount(archived);
|
co.setDelayedProjectCount(countDelayed(projects));
|
||||||
co.setDelayedProjectCount(delayed);
|
co.setNodeStats(buildNodeStats(projects));
|
||||||
return SingleResponse.success(co);
|
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) {
|
private List<EvalProjectEntity> listOrgProjects(Long orgId) {
|
||||||
EvalProjectQuery q = new EvalProjectQuery();
|
EvalProjectQuery q = new EvalProjectQuery();
|
||||||
q.setOrgId(orgId);
|
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.EvalProjectQuery;
|
||||||
import org.qinan.safetyeval.domain.query.PageResult;
|
import org.qinan.safetyeval.domain.query.PageResult;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface EvalProjectGateway {
|
public interface EvalProjectGateway {
|
||||||
|
|
||||||
EvalProjectEntity save(EvalProjectEntity entity);
|
EvalProjectEntity save(EvalProjectEntity entity);
|
||||||
|
|
@ -25,4 +27,12 @@ public interface EvalProjectGateway {
|
||||||
void editProjectNode(Long projectId, String val);
|
void editProjectNode(Long projectId, String val);
|
||||||
|
|
||||||
EvalProjectEntity findByControlledNumber(String controlledNumber);
|
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);
|
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
|
@Override
|
||||||
public void editProjectNode(Long projectId, String val) {
|
public void editProjectNode(Long projectId, String val) {
|
||||||
EvalProjectDO evalProjectDO = evalProjectMapper.selectById(projectId);
|
EvalProjectDO evalProjectDO = evalProjectMapper.selectById(projectId);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue