package jnpf.fileStorage.dms;
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import jnpf.audit.sdk.annotation.AuditLog;
|
import jnpf.base.ActionResult;
|
import jnpf.dms.DmsResourceApi;
|
import jnpf.dmsEntity.storage.approval.DmsApprovedBatch;
|
import jnpf.dmsEntity.storage.approval.DmsApprovedItem;
|
import jnpf.dmsEntity.storage.form.DmsApprovedRegistrationForm;
|
import jnpf.dmsEntity.storage.form.DmsApprovedRegistrationCallback;
|
import jnpf.dmsEntity.storage.form.DmsApprovedRegistrationCallback.StoredFile;
|
import jnpf.dmsEntity.storage.form.DmsFileUploadRegisterForm;
|
import jnpf.exception.DataException;
|
import lombok.RequiredArgsConstructor;
|
import org.springframework.stereotype.Service;
|
import org.springframework.web.multipart.MultipartFile;
|
|
import java.util.Objects;
|
|
@Service
|
@RequiredArgsConstructor
|
public class DmsWorkflowFileCreateService {
|
private static final String SERVICE_ID = "jnpf-file";
|
private final DmsResourceApi dmsResourceApi;
|
private final DmsFileStorageService fileStorageService;
|
private final DmsCommonFileReader commonFileReader;
|
private final DmsApprovalPageMergeService approvalPageMergeService;
|
private final DmsQianpiyeDocxWriter qianpiyeDocxWriter;
|
private final ObjectMapper json;
|
|
/** DMS owns source data and registration progress; file only consumes the pushed set. */
|
@AuditLog(action = "DMS_WORKFLOW_REGISTER_APPROVED", bizCodeExpr = "#form.taskId")
|
public DmsApprovedBatch process(DmsApprovedRegistrationForm form, String auditBizSign) {
|
if (form.getBatchId() == null || form.getSourceDigest() == null || form.getFiles() == null || form.getFiles().isEmpty())
|
throw new DataException("DMS推送的登记批次不完整");
|
DmsApprovedRegistrationCallback callback = new DmsApprovedRegistrationCallback();
|
callback.setTenantId(form.getTenantId());
|
callback.setAttemptToken(form.getAttemptToken());
|
callback.setBatchId(form.getBatchId());
|
callback.setSourceDigest(form.getSourceDigest());
|
for (DmsApprovedItem item : form.getFiles()) {
|
if (item == null || item.getDocumentId() == null || item.getFileVersionId() == null)
|
throw new DataException("DMS推送的文件缺少登记ID");
|
if ("REUSE".equals(item.getChangeType())) continue;
|
if (!"CREATE".equals(item.getChangeType()) && !"REVISE".equals(item.getChangeType()))
|
throw new DataException("DMS推送的文件操作类型无效");
|
StoredFile stored = new StoredFile();
|
stored.setSourceKey(item.getSourceKey());
|
stored.setFileJson(item.getFileJson());
|
stored.setContent(commonFileReader.withFile(singleFileUrl(item.getFileJson()), item.getFileJson(),
|
item.getDocumentName(), file -> store(item, file)));
|
callback.getFiles().add(stored);
|
}
|
DmsApprovedBatch accepted = requireBatch(dmsResourceApi.registerWorkflowUpload(
|
SERVICE_ID, auditBizSign, callback), form);
|
if (!form.getBatchId().equals(accepted.getId()) || !Objects.equals(form.getSourceDigest(), accepted.getSourceDigest())
|
|| !("WAITING".equals(accepted.getStatus()) || "APPLIED".equals(accepted.getStatus())))
|
throw new DataException("DMS未返回完整的登记确认结果");
|
return accepted;
|
}
|
|
private DmsFileUploadRegisterForm store(DmsApprovedItem item, MultipartFile file) {
|
String approvalPage = item.getQianpiyeFiles() == null || item.getQianpiyeFiles().isBlank()
|
? item.getApprovalPageFileJson() : item.getQianpiyeFiles();
|
MultipartFile source = isDocx(file) && item.getApprovalValuesByTag() != null
|
&& approvalPage != null && !approvalPage.isBlank()
|
? approvalPageMergeService.withoutApprovalPages(file) : file;
|
MultipartFile renderedFile = isDocx(file) && item.getApprovalValuesByTag() != null
|
? qianpiyeDocxWriter.render(source, item.getApprovalValuesByTag(),
|
item.getApprovalFlowVersionId()) : file;
|
if (approvalPage == null || approvalPage.isBlank() || !isDocx(file)) {
|
return fileStorageService.storeWorkflowContent(
|
item.getDocumentId(), item.getFileVersionId(), renderedFile);
|
}
|
return commonFileReader.withFile(singleFileUrl(approvalPage), approvalPage, "签批页",
|
page -> {
|
MultipartFile rendered = isDocx(page) ? qianpiyeDocxWriter.render(
|
page, item.getApprovalValuesByTag(), item.getApprovalFlowVersionId()) : page;
|
return fileStorageService.storeWorkflowContent(item.getDocumentId(),
|
item.getFileVersionId(), approvalPageMergeService.replaceOrPrepend(renderedFile, rendered));
|
});
|
}
|
|
private boolean isDocx(MultipartFile file) {
|
String name = file == null ? null : file.getOriginalFilename();
|
return name != null && name.toLowerCase(java.util.Locale.ROOT).endsWith(".docx");
|
}
|
|
private DmsApprovedBatch requireBatch(ActionResult<DmsApprovedBatch> result, DmsApprovedRegistrationForm form) {
|
if (result == null || !Integer.valueOf(200).equals(result.getCode()) || result.getData() == null)
|
throw new DataException(result == null ? "DMS文件登记无响应" : result.getMsg());
|
DmsApprovedBatch batch = result.getData();
|
if (!form.getSourceId().trim().equals(batch.getFlowId()) || !form.getTaskId().trim().equals(batch.getTaskId())
|
|| !Objects.equals(form.getAuditType(), batch.getAuditType()))
|
throw new DataException("DMS返回的批准批次与请求不匹配");
|
return batch;
|
}
|
|
String singleFileUrl(String fileJson) {
|
try {
|
JsonNode value = json.readTree(fileJson);
|
if (value.isArray()) {
|
if (value.size() != 1) throw new DataException("每个主文件或记录必须有且只有一个文件");
|
value = value.get(0);
|
}
|
String url = value.path("url").asText(null);
|
if (url == null || url.isBlank()) throw new DataException("审核附件缺少URL");
|
return url;
|
} catch (DataException e) { throw e; }
|
catch (Exception e) { throw new DataException("审核附件格式不正确"); }
|
}
|
}
|