archive file
parent
a8db7ee59c
commit
c71b875c4d
|
|
@ -7,7 +7,6 @@ import cn.hutool.json.JSONObject;
|
|||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.qinan.safetyeval.app.executor.institution.support.EvalCmdCopy;
|
||||
import org.qinan.safetyeval.app.executor.institution.support.EvalProjectNodeSupport;
|
||||
|
|
@ -37,9 +36,10 @@ import org.qinan.safetyeval.infrastructure.convertor.EvalProcessControlConvertor
|
|||
import org.qinan.safetyeval.infrastructure.convertor.EvalProjectMemberDoConvertor;
|
||||
import org.qinan.safetyeval.infrastructure.dataobject.*;
|
||||
import org.qinan.safetyeval.infrastructure.mapper.*;
|
||||
import org.qinan.safetyeval.infrastructure.persistence.domainobject.EvalProjectArchiveFileDO;
|
||||
import org.qinan.safetyeval.infrastructure.persistence.mapper.EvalProjectArchiveFileMapper;
|
||||
import org.qinan.safetyeval.infrastructure.persistence.queryservice.*;
|
||||
import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults;
|
||||
import org.qinan.safetyeval.infrastructure.utils.CommonUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
|
@ -99,12 +99,12 @@ public class EvalProcessControlExecutor implements EvalProcessControlApi {
|
|||
@Resource
|
||||
private EvalProcessControlMapper evalProcessControlMapper;
|
||||
@Resource
|
||||
private EvalProjectDocMapper evalProjectDocMapper;
|
||||
private EvalRiskParticipantMapper evalRiskParticipantMapper;
|
||||
@Resource
|
||||
private EvalProjectArchiveFileMapper evalProjectArchiveFileMapper;
|
||||
@Resource
|
||||
private EvalSignTaskMapper evalSignTaskMapper;
|
||||
@Resource
|
||||
private EvalCustomerMapper evalCustomerMapper;
|
||||
@Resource
|
||||
private WpsDocQueryService wpsDocQueryService;
|
||||
@Resource
|
||||
private SafetyMessageGateway safetyMessageGateway;
|
||||
|
|
@ -370,7 +370,8 @@ public class EvalProcessControlExecutor implements EvalProcessControlApi {
|
|||
projectStageSyncService.onArchived(projectId, cmd.getArchiveTransferorName(), cmd.getArchiveArchivistName());
|
||||
// 写入项目预警记录(存在则更新,不存在则新增)
|
||||
upsertProjectWaring(project);
|
||||
|
||||
// 归档项目资料:将所有项目文件以流程自动记录来源存入 eval_project_archive_file
|
||||
saveAutoArchiveFiles(projectId, project);
|
||||
projectStageSyncService.onNodeCompleted(projectId, ProjectStageEnum.ARCHIVE.getNode());
|
||||
return SingleResponse.success(evalProcessControlConvertor.toProcessCO(entity));
|
||||
}
|
||||
|
|
@ -381,6 +382,8 @@ public class EvalProcessControlExecutor implements EvalProcessControlApi {
|
|||
Long orgId = project.getOrgId();
|
||||
List<EvalProjectFileCO> files = new java.util.ArrayList<>();
|
||||
|
||||
// 风险分析/项目组-参与人签字(eval_risk_participant:risk_id 非空为风险分析,为空为项目组)
|
||||
files.addAll(listRiskParticipantFiles(projectId));
|
||||
// 业务合同-合同扫描件
|
||||
files.addAll(evalContractQueryService.listProjectFiles(projectId, orgId));
|
||||
// 现场踏勘-附件
|
||||
|
|
@ -528,63 +531,115 @@ public class EvalProcessControlExecutor implements EvalProcessControlApi {
|
|||
}
|
||||
|
||||
/**
|
||||
* 归档时将 listProjectFiles 查询出的所有项目文件以 ARCHIVED 资料类型合并写入 eval_project_doc.project_doc_url。
|
||||
* 写入前先移除原有 materialType=ARCHIVED 的记录,再追加本次归档的文件后更新。
|
||||
* 归档项目资料:将 listProjectFiles 查询出的所有项目文件写入 eval_project_archive_file(来源:流程自动记录)。
|
||||
* 写入前先删除该项目 record_source=auto_process_record 的旧记录,再逐文件构建新增数据。
|
||||
*/
|
||||
private void upsertArchivedProjectDocs(Long projectId, EvalProjectEntity project) {
|
||||
private void saveAutoArchiveFiles(Long projectId, EvalProjectEntity project) {
|
||||
// 先删除该项目流程自动记录来源的旧档案文件,避免重复归档产生脏数据
|
||||
evalProjectArchiveFileMapper.delete(new LambdaQueryWrapper<EvalProjectArchiveFileDO>()
|
||||
.eq(EvalProjectArchiveFileDO::getProjectId, String.valueOf(projectId))
|
||||
.eq(EvalProjectArchiveFileDO::getRecordSource, ProjectArchiveFileSourceEnum.AUTO_PROCESS_RECORD.getCode()));
|
||||
|
||||
List<EvalProjectFileCO> files = listProjectFiles(projectId).getData();
|
||||
// 将每个文件 projectDocUrl 中的 JSON 数组扁平化:数组内每个文件对象拆分为独立的资料条目
|
||||
List<EvalProjectDocMaterialItemCO> archivedItems = new ArrayList<>();
|
||||
if (!CollectionUtils.isEmpty(files)) {
|
||||
for (EvalProjectFileCO f : files) {
|
||||
List<JSONObject> urlObjects = parseFileUrlObjects(f.getProjectDocUrl());
|
||||
String itemName = f.getItemName();
|
||||
for (JSONObject obj : urlObjects) {
|
||||
EvalProjectDocMaterialItemCO item = new EvalProjectDocMaterialItemCO();
|
||||
String name = obj.getStr("name");
|
||||
String fName = StringUtils.hasText(name) ? CommonUtil.EMPTY : name;
|
||||
item.setMaterialName(itemName + fName);
|
||||
item.setProjectDocUrl(obj.getStr("url"));
|
||||
item.setMaterialType(MaterialCategory.ARCHIVED.getMsg());
|
||||
archivedItems.add(item);
|
||||
if (CollectionUtils.isEmpty(files)) {
|
||||
return;
|
||||
}
|
||||
for (EvalProjectFileCO file : files) {
|
||||
ProjectStageEnum stage = resolveStageByMsg(file.getProcessName());
|
||||
for (JSONObject obj : parseFileUrlObjects(file.getProjectDocUrl())) {
|
||||
if (!StringUtils.hasText(obj.getStr("url"))) {
|
||||
continue;
|
||||
}
|
||||
evalProjectArchiveFileMapper.insert(buildArchiveFileDO(projectId, project, file, stage, obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EvalProjectDocDO docDO = evalProjectDocMapper.selectOne(new LambdaQueryWrapper<EvalProjectDocDO>()
|
||||
.select(EvalProjectDocDO::getId, EvalProjectDocDO::getProjectDocUrl)
|
||||
.eq(EvalProjectDocDO::getProjectId, projectId));
|
||||
if (docDO == null) {
|
||||
EvalCustomerDO evalCustomerDO = evalCustomerMapper.selectOne(new LambdaQueryWrapper<EvalCustomerDO>()
|
||||
.select(EvalCustomerDO::getCustomerName)
|
||||
.eq(EvalCustomerDO::getId, project.getCustomerId()));
|
||||
docDO = new EvalProjectDocDO();
|
||||
docDO.setOrgId(project.getOrgId());
|
||||
docDO.setProjectId(projectId);
|
||||
docDO.setProjectNo(project.getProjectNo());
|
||||
docDO.setCustomerName(evalCustomerDO.getCustomerName());
|
||||
docDO.setProjectName(project.getProjectName());
|
||||
docDO.setEvalTypeCode(project.getEvalTypeCode());
|
||||
docDO.setProjectDocUrl(JSON.toJSONString(archivedItems));
|
||||
docDO.setRemarks(MaterialCategory.ARCHIVED.getMsg());
|
||||
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);
|
||||
/**
|
||||
* 构建单条档案文件记录:archiveType 按业务节点映射 ArchiveTypeEnum,businessNode 存 ProjectStageEnum 英文标识。
|
||||
*/
|
||||
private EvalProjectArchiveFileDO buildArchiveFileDO(Long projectId, EvalProjectEntity project,
|
||||
EvalProjectFileCO file, ProjectStageEnum stage, JSONObject obj) {
|
||||
String urlName = obj.getStr("name");
|
||||
EvalProjectArchiveFileDO archiveFileDO = new EvalProjectArchiveFileDO();
|
||||
archiveFileDO.setOrgId(project.getOrgId());
|
||||
archiveFileDO.setProjectId(String.valueOf(projectId));
|
||||
archiveFileDO.setFileUrl(obj.getStr("url"));
|
||||
archiveFileDO.setFileName(StringUtils.hasText(urlName) ? urlName : file.getItemName());
|
||||
archiveFileDO.setArchiveType(resolveArchiveType(stage).getCode());
|
||||
archiveFileDO.setBusinessNode(stage != null ? stage.getVal() : file.getProcessName());
|
||||
archiveFileDO.setRecordSource(ProjectArchiveFileSourceEnum.AUTO_PROCESS_RECORD.getCode());
|
||||
InsertFieldDefaults.apply(archiveFileDO);
|
||||
return archiveFileDO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据流程中文名(ProjectStageEnum.msg,如 业务合同/现场踏勘)查找对应阶段枚举,未匹配返回 null。
|
||||
*/
|
||||
private ProjectStageEnum resolveStageByMsg(String processName) {
|
||||
if (!StringUtils.hasText(processName)) {
|
||||
return null;
|
||||
}
|
||||
for (ProjectStageEnum stage : ProjectStageEnum.values()) {
|
||||
if (stage.getMsg().equals(processName)) {
|
||||
return stage;
|
||||
}
|
||||
}
|
||||
// 先移除原有 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)));
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按业务节点映射档案类型:风险分析→项目风险分析,业务合同→技术服务合同,项目组→项目组织文件,
|
||||
* 现场踏勘→现场勘察资料,报告编制→评价报告,内部审核/技术审核→审核记录,过程控制→过程控制文件,
|
||||
* 其余→其他。
|
||||
*/
|
||||
private ArchiveTypeEnum resolveArchiveType(ProjectStageEnum stage) {
|
||||
if (stage == null) {
|
||||
return ArchiveTypeEnum.OTHER;
|
||||
}
|
||||
switch (stage) {
|
||||
case RISK_ANALYSIS:
|
||||
return ArchiveTypeEnum.RISK_ANALYSIS;
|
||||
case BUSINESS_CONTRACT:
|
||||
return ArchiveTypeEnum.TECH_SERVICE_CONTRACT;
|
||||
case PROJECT_GROUP:
|
||||
return ArchiveTypeEnum.PROJECT_ORG_FILE;
|
||||
case SITE_SURVEY:
|
||||
return ArchiveTypeEnum.SITE_SURVEY;
|
||||
case REPORT_PREPARATION:
|
||||
return ArchiveTypeEnum.EVALUATION_REPORT;
|
||||
case INTERNAL_REVIEW:
|
||||
case TECHNICAL_REVIEW:
|
||||
return ArchiveTypeEnum.REVIEW_RECORD;
|
||||
case PROCESS_CONTROL:
|
||||
return ArchiveTypeEnum.PROCESS_CONTROL;
|
||||
default:
|
||||
return ArchiveTypeEnum.OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询 eval_risk_participant 参与人签字文件:risk_id 非空为风险分析参与人,为空为项目组成员。
|
||||
*/
|
||||
private List<EvalProjectFileCO> listRiskParticipantFiles(Long projectId) {
|
||||
List<EvalProjectFileCO> files = new ArrayList<>();
|
||||
List<EvalRiskParticipantDO> participants = evalRiskParticipantMapper.selectList(
|
||||
new LambdaQueryWrapper<EvalRiskParticipantDO>()
|
||||
.eq(EvalRiskParticipantDO::getProjectId, projectId)
|
||||
.isNotNull(EvalRiskParticipantDO::getSignFileUrl));
|
||||
if (CollectionUtils.isEmpty(participants)) {
|
||||
return files;
|
||||
}
|
||||
for (EvalRiskParticipantDO participant : participants) {
|
||||
ProjectStageEnum stage = participant.getRiskId() != null
|
||||
? ProjectStageEnum.RISK_ANALYSIS : ProjectStageEnum.PROJECT_GROUP;
|
||||
EvalProjectFileCO co = new EvalProjectFileCO();
|
||||
co.setProcessName(stage.getMsg());
|
||||
co.setItemName(stage.getMsg() + "签字");
|
||||
co.setProjectDocUrl(participant.getSignFileUrl());
|
||||
files.add(co);
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import lombok.Data;
|
|||
import org.qinan.safetyeval.domain.constant.ArchiveTypeEnum;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
|
|
@ -17,47 +18,34 @@ import java.io.Serializable;
|
|||
public class EvalProjectArchiveFileAddCmd implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 项目ID
|
||||
*/
|
||||
@ApiModelProperty(value = "项目ID", required = true)
|
||||
@NotBlank(message = "项目ID不能为空")
|
||||
private String projectId;
|
||||
/**
|
||||
* 文件地址
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "文件地址", required = true)
|
||||
@NotBlank(message = "文件地址不能为空")
|
||||
private String fileUrl;
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "文件名称", required = true)
|
||||
@NotBlank(message = "文件名称不能为空")
|
||||
@Size(max = 100, message = "文件名称长度不能超过100")
|
||||
private String fileName;
|
||||
/**
|
||||
* ArchiveTypeEnum.REMARKS
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = ArchiveTypeEnum.REMARKS, required = true)
|
||||
@NotBlank(message = ArchiveTypeEnum.REMARKS + "不能为空")
|
||||
@Size(max = 100, message = "档案类型长度不能超过100")
|
||||
private String archiveType;
|
||||
|
||||
/**
|
||||
* 业务节点
|
||||
*/
|
||||
@ApiModelProperty(value = "业务节点", required = true)
|
||||
@NotBlank(message = "业务节点不能为空")
|
||||
@Size(max = 32, message = "业务节点长度不能超过32")
|
||||
private String businessNode;
|
||||
/**
|
||||
* 来源 auto_process_record流程自动记录,upload_additional_files 补充上传
|
||||
*/
|
||||
|
||||
@ApiModelProperty(value = "来源 auto_process_record流程自动记录,upload_additional_files 补充上传", required = true)
|
||||
@NotBlank(message = "来源 auto_process_record流程自动记录,upload_additional_files 补充上传不能为空")
|
||||
@Size(max = 32, message = "来源长度不能超过32")
|
||||
private String recordSource;
|
||||
/**
|
||||
* 环境
|
||||
*/
|
||||
@ApiModelProperty(value = "环境")
|
||||
private String env;
|
||||
|
||||
@ApiModelProperty(value = "备注")
|
||||
@Size(max = 200, message = "备注长度不能超过200")
|
||||
private String remarks;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import org.qinan.safetyeval.domain.constant.ArchiveTypeEnum;
|
|||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
|
|
@ -56,4 +57,8 @@ public class EvalProjectArchiveFileUpdateCmd implements Serializable {
|
|||
@ApiModelProperty(value = "来源 auto_process_record流程自动记录,upload_additional_files 补充上传", required = true)
|
||||
@NotBlank(message = "来源 auto_process_record流程自动记录,upload_additional_files 补充上传不能为空")
|
||||
private String recordSource;
|
||||
|
||||
@ApiModelProperty(value = "备注")
|
||||
@Size(max = 200, message = "备注长度不能超过200")
|
||||
private String remarks;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,4 +54,7 @@ public class EvalProjectArchiveFileCo extends ClientObject {
|
|||
|
||||
@ApiModelProperty(value = "创建人")
|
||||
protected String createName;
|
||||
|
||||
@ApiModelProperty(value = "备注")
|
||||
private String remarks;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue