dev
luotaiqian 2026-07-24 10:52:34 +08:00
parent 1b2f50e102
commit 860b96aab9
5 changed files with 171 additions and 10 deletions

View File

@ -1,22 +1,19 @@
package org.qinan.safetyeval.app.executor.institution; package org.qinan.safetyeval.app.executor.institution;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.qinan.safetyeval.app.executor.institution.support.EvalCmdCopy; import org.qinan.safetyeval.app.executor.institution.support.EvalCmdCopy;
import org.qinan.safetyeval.app.executor.institution.support.EvalNodeCoConverter; import org.qinan.safetyeval.app.executor.institution.support.EvalNodeCoConverter;
import org.qinan.safetyeval.app.executor.institution.support.EvalProjectNodeSupport; import org.qinan.safetyeval.app.executor.institution.support.EvalProjectNodeSupport;
import org.qinan.safetyeval.app.item.convertor.EvalReviewItemCmdConvertor; import org.qinan.safetyeval.app.item.convertor.EvalReviewItemCmdConvertor;
import org.qinan.safetyeval.client.api.institution.EvalProcessControlApi; import org.qinan.safetyeval.client.api.institution.EvalProcessControlApi;
import org.qinan.safetyeval.client.co.institution.EvalProcessControlCO; import org.qinan.safetyeval.client.co.institution.*;
import org.qinan.safetyeval.client.co.institution.EvalProcessControlDetailCO;
import org.qinan.safetyeval.client.co.institution.EvalProjectFileCO;
import org.qinan.safetyeval.client.co.institution.ProjectNodeCO;
import org.qinan.safetyeval.client.dto.SingleResponse; import org.qinan.safetyeval.client.dto.SingleResponse;
import org.qinan.safetyeval.client.dto.institution.EvalProcessArchiveCmd; import org.qinan.safetyeval.client.dto.institution.*;
import org.qinan.safetyeval.client.dto.institution.EvalProcessControlAssignCmd;
import org.qinan.safetyeval.client.dto.institution.EvalProcessControlConfirmCmd;
import org.qinan.safetyeval.client.dto.institution.EvalProcessControlSaveCmd;
import org.qinan.safetyeval.client.dto.institution.EvalProcessHandoverFormCmd;
import org.qinan.safetyeval.client.item.request.EvalReviewItemAddCmd; import org.qinan.safetyeval.client.item.request.EvalReviewItemAddCmd;
import org.qinan.safetyeval.client.item.response.EvalReviewItemCo; import org.qinan.safetyeval.client.item.response.EvalReviewItemCo;
import org.qinan.safetyeval.domain.constant.*; import org.qinan.safetyeval.domain.constant.*;
@ -39,12 +36,14 @@ import org.qinan.safetyeval.domain.waring.gateway.EvalProjectWaringGateway;
import org.qinan.safetyeval.domain.waring.model.EvalProjectWaringE; import org.qinan.safetyeval.domain.waring.model.EvalProjectWaringE;
import org.qinan.safetyeval.infrastructure.convertor.EvalProcessControlConvertor; import org.qinan.safetyeval.infrastructure.convertor.EvalProcessControlConvertor;
import org.qinan.safetyeval.infrastructure.convertor.EvalProjectMemberDoConvertor; import org.qinan.safetyeval.infrastructure.convertor.EvalProjectMemberDoConvertor;
import org.qinan.safetyeval.infrastructure.dataobject.EvalInternalReviewDO;
import org.qinan.safetyeval.infrastructure.dataobject.EvalProcessControlDO; import org.qinan.safetyeval.infrastructure.dataobject.EvalProcessControlDO;
import org.qinan.safetyeval.infrastructure.dataobject.EvalProjectDocDO;
import org.qinan.safetyeval.infrastructure.dataobject.EvalProjectMemberDO; import org.qinan.safetyeval.infrastructure.dataobject.EvalProjectMemberDO;
import org.qinan.safetyeval.infrastructure.mapper.EvalProcessControlMapper; import org.qinan.safetyeval.infrastructure.mapper.EvalProcessControlMapper;
import org.qinan.safetyeval.infrastructure.mapper.EvalProjectDocMapper;
import org.qinan.safetyeval.infrastructure.mapper.EvalProjectMemberMapper; import org.qinan.safetyeval.infrastructure.mapper.EvalProjectMemberMapper;
import org.qinan.safetyeval.infrastructure.persistence.queryservice.*; import org.qinan.safetyeval.infrastructure.persistence.queryservice.*;
import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@ -52,6 +51,7 @@ import org.springframework.util.StringUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -102,6 +102,8 @@ public class EvalProcessControlExecutor implements EvalProcessControlApi {
private EvalReportQueryService evalReportQueryService; private EvalReportQueryService evalReportQueryService;
@Resource @Resource
private EvalProcessControlMapper evalProcessControlMapper; private EvalProcessControlMapper evalProcessControlMapper;
@Resource
private EvalProjectDocMapper evalProjectDocMapper;
@Override @Override
public SingleResponse<EvalProcessControlCO> getOrSave(EvalProcessControlSaveCmd cmd) { public SingleResponse<EvalProcessControlCO> getOrSave(EvalProcessControlSaveCmd cmd) {
@ -303,6 +305,8 @@ public class EvalProcessControlExecutor implements EvalProcessControlApi {
projectStageSyncService.onArchived(projectId); projectStageSyncService.onArchived(projectId);
// 写入项目预警记录(存在则更新,不存在则新增) // 写入项目预警记录(存在则更新,不存在则新增)
upsertProjectWaring(project); upsertProjectWaring(project);
// 归档项目资料:将所有项目文件以 ARCHIVED 资料类型存入 eval_project_doc
upsertArchivedProjectDocs(projectId, project);
return SingleResponse.success(EvalNodeCoConverter.toProcessCO(entity)); return SingleResponse.success(EvalNodeCoConverter.toProcessCO(entity));
} }
@ -328,9 +332,68 @@ public class EvalProcessControlExecutor implements EvalProcessControlApi {
// 过程控制-归档报告 // 过程控制-归档报告
files.addAll(evalReportQueryService.listProjectFiles(projectId, orgId)); files.addAll(evalReportQueryService.listProjectFiles(projectId, orgId));
// 统一规范化 projectDocUrl 格式为 [{"url":"xxx","name":"xxx"}]
files.forEach(this::normalizeProjectDocUrl);
return SingleResponse.success(files); return SingleResponse.success(files);
} }
/**
* projectDocUrl [{"url":"xxx","name":"xxx"}]
*
* 1. URLhttps://xxx.com/file.pdf
* 2. JSON["url1","url2"]
* 3. JSON[{"url":"xxx","name":"xxx"}]
*/
private void normalizeProjectDocUrl(EvalProjectFileCO co) {
String raw = co.getProjectDocUrl();
if (!StringUtils.hasText(raw)) {
return;
}
String trimmed = raw.trim();
JSONArray result = new JSONArray();
if (trimmed.startsWith("[")) {
try {
JSONArray arr = JSON.parseArray(trimmed);
for (int i = 0; i < arr.size(); i++) {
Object item = arr.get(i);
if (item instanceof JSONObject) {
result.add(item);
} else {
result.add(buildUrlNameObj(String.valueOf(item)));
}
}
co.setProjectDocUrl(result.toJSONString());
return;
} catch (Exception ignored) {
// 非合法JSON数组按纯字符串处理
}
}
result.add(buildUrlNameObj(trimmed));
co.setProjectDocUrl(result.toJSONString());
}
private JSONObject buildUrlNameObj(String url) {
JSONObject obj = new JSONObject();
obj.put("url", url);
obj.put("name", extractFileName(url));
return obj;
}
private String extractFileName(String url) {
if (!StringUtils.hasText(url)) {
return "";
}
String noQuery = url;
int queryIdx = noQuery.indexOf('?');
if (queryIdx > 0) {
noQuery = noQuery.substring(0, queryIdx);
}
int slashIdx = noQuery.lastIndexOf('/');
String name = slashIdx >= 0 ? noQuery.substring(slashIdx + 1) : noQuery;
return StringUtils.hasText(name) ? name : url;
}
private EvalReportEntity buildReport(EvalProjectEntity project) { private EvalReportEntity buildReport(EvalProjectEntity project) {
EvalReportEntity report = new EvalReportEntity(); EvalReportEntity report = new EvalReportEntity();
report.setOrgId(project.getOrgId()); report.setOrgId(project.getOrgId());
@ -399,6 +462,53 @@ public class EvalProcessControlExecutor implements EvalProcessControlApi {
} }
} }
/**
* listProjectFiles ARCHIVED eval_project_doc.project_doc_url
* materialType=ARCHIVED
*/
private void upsertArchivedProjectDocs(Long projectId, EvalProjectEntity project) {
List<EvalProjectFileCO> files = listProjectFiles(projectId).getData();
List<EvalProjectDocMaterialItemCO> archivedItems = CollectionUtils.isEmpty(files)
? new ArrayList<>()
: files.stream().map(f -> {
EvalProjectDocMaterialItemCO item = new EvalProjectDocMaterialItemCO();
item.setMaterialName(f.getMaterialName());
item.setProjectDocUrl(f.getProjectDocUrl());
item.setMaterialType(MaterialCategory.ARCHIVED.getVal());
return item;
}).collect(Collectors.toList());
EvalProjectDocDO docDO = evalProjectDocMapper.selectOne(new LambdaQueryWrapper<EvalProjectDocDO>()
.select(EvalProjectDocDO::getId, EvalProjectDocDO::getProjectDocUrl)
.eq(EvalProjectDocDO::getProjectId, projectId));
if (docDO == null) {
docDO = new EvalProjectDocDO();
docDO.setOrgId(project.getOrgId());
docDO.setProjectId(projectId);
docDO.setProjectNo(project.getProjectNo());
docDO.setProjectName(project.getProjectName());
docDO.setEvalTypeCode(project.getEvalTypeCode());
docDO.setProjectDocUrl(JSON.toJSONString(archivedItems));
InsertFieldDefaults.apply(docDO);
evalProjectDocMapper.insert(docDO);
} else {
List<EvalProjectDocMaterialItemCO> existing = new ArrayList<>();
if (StringUtils.hasText(docDO.getProjectDocUrl())) {
List<EvalProjectDocMaterialItemCO> parsed = JSONUtil.toList(docDO.getProjectDocUrl(), EvalProjectDocMaterialItemCO.class);
if (parsed != null) {
existing.addAll(parsed);
}
}
// 先移除原有 ARCHIVED 类型的资料,再追加本次归档的文件
String archivedVal = MaterialCategory.ARCHIVED.getVal();
existing.removeIf(item -> archivedVal.equals(item.getMaterialType()));
existing.addAll(archivedItems);
evalProjectDocMapper.update(new LambdaUpdateWrapper<EvalProjectDocDO>()
.eq(EvalProjectDocDO::getId, docDO.getId())
.set(EvalProjectDocDO::getProjectDocUrl, JSON.toJSONString(existing)));
}
}
/** /**
* taskStatusCode=2 * taskStatusCode=2
* / * /

View File

@ -3,12 +3,23 @@ package org.qinan.safetyeval.client.dto.institution;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data @Data
public class EvalInternalReviewAssignCmd { public class EvalInternalReviewAssignCmd {
@ApiModelProperty("项目id") @ApiModelProperty("项目id")
@NotNull
private Long projectId; private Long projectId;
@ApiModelProperty("签字任务人员")
@NotNull
@Valid
private SignTaskPersonCmd signTaskPersonCmd;
@ApiModelProperty(value = "审核签字任务状态 dispatched 下发non_dispatched 未下发", example = "non_dispatched", hidden = true) @ApiModelProperty(value = "审核签字任务状态 dispatched 下发non_dispatched 未下发", example = "non_dispatched", hidden = true)
private String reviewerSignatureTaskStatus; private String reviewerSignatureTaskStatus;
} }

View File

@ -3,12 +3,21 @@ package org.qinan.safetyeval.client.dto.institution;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data @Data
public class EvalProcessControlAssignCmd { public class EvalProcessControlAssignCmd {
@ApiModelProperty("项目id") @ApiModelProperty("项目id")
private Long projectId; private Long projectId;
@ApiModelProperty("签字任务人员")
@NotNull
@Valid
private SignTaskPersonCmd signTaskPersonCmd;
@ApiModelProperty(value = "审核签字任务状态 dispatched 下发non_dispatched 未下发", example = "non_dispatched", hidden = true) @ApiModelProperty(value = "审核签字任务状态 dispatched 下发non_dispatched 未下发", example = "non_dispatched", hidden = true)
private String reviewerSignatureTaskStatus; private String reviewerSignatureTaskStatus;
} }

View File

@ -3,12 +3,22 @@ package org.qinan.safetyeval.client.dto.institution;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data @Data
public class EvalTechReviewAssignCmd { public class EvalTechReviewAssignCmd {
@ApiModelProperty("项目id") @ApiModelProperty("项目id")
@NotNull
private Long projectId; private Long projectId;
@ApiModelProperty("签字任务人员")
@NotNull
@Valid
private SignTaskPersonCmd signTaskPersonCmd;
@ApiModelProperty(value = "审核签字任务状态 dispatched 下发non_dispatched 未下发", example = "non_dispatched", hidden = true) @ApiModelProperty(value = "审核签字任务状态 dispatched 下发non_dispatched 未下发", example = "non_dispatched", hidden = true)
private String reviewerSignatureTaskStatus; private String reviewerSignatureTaskStatus;
} }

View File

@ -0,0 +1,21 @@
package org.qinan.safetyeval.client.dto.institution;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@Data
public class SignTaskPersonCmd {
@ApiModelProperty("待签人员id")
@NotNull
private Long signerPersonnelId;
@ApiModelProperty("待签人员姓名")
@NotBlank
@Size(max = 50)
private String signerName;
}