package jnpf.dmsService;
|
|
import jnpf.dmsEntity.storage.*;
|
import jnpf.dmsMapper.DmsRevisionEditMapper;
|
import jnpf.exception.DataException;
|
import jnpf.util.JsonUtil;
|
import jnpf.util.TicketUtil;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import java.util.function.Function;
|
import java.util.function.BiFunction;
|
import org.springframework.stereotype.Service;
|
import java.util.*;
|
|
/** 核验本人有效修订来源,供原生保存与副本编辑使用,不修改原版本或业务单据。 */
|
@Service
|
public class DmsRevisionEditService {
|
private static final com.fasterxml.jackson.databind.ObjectMapper SOURCE_JSON = new com.fasterxml.jackson.databind.ObjectMapper();
|
private final DmsRevisionEditMapper mapper;
|
private final Function<String,String> parseTicket;
|
private final BiFunction<String,Long,String> issueTicket;
|
@Autowired
|
public DmsRevisionEditService(DmsRevisionEditMapper mapper) {
|
this(mapper, TicketUtil::parseTicket, TicketUtil::createTicket);
|
}
|
DmsRevisionEditService(DmsRevisionEditMapper mapper, Function<String,String> parseTicket,
|
BiFunction<String,Long,String> issueTicket) {
|
this.mapper = mapper; this.parseTicket = parseTicket; this.issueTicket = issueTicket;
|
}
|
public List<Map<String,Object>> prepare(DmsRevisionEditRequest request, String tenant, String owner) {
|
List<DmsRevisionEditSource> sources=mapper.sources(tenant, owner, request.getSourceItemId(), request.getModelId());
|
if (sources.isEmpty()) throw denied();
|
List<Map<String,Object>> result=new ArrayList<>();
|
for (DmsRevisionEditSource source:sources) {
|
List<Map<String,Object>> files=new ArrayList<>();
|
for (Map<String,Object> original:files(source.getFiles())) {
|
Map<String,Object> file=canonical(original);
|
if ("wenjian".equals(source.getField()) && Objects.toString(source.getParentField(), "").isEmpty()
|
&& original.get("laiyuan_muban_id") instanceof String
|
&& !((String) original.get("laiyuan_muban_id")).isBlank())
|
file.put("laiyuan_muban_id", original.get("laiyuan_muban_id"));
|
// 来源凭据也用于原生暂存,不能只覆盖可在线编辑的 DOC/DOCX。
|
if (hasFileId(file)) {
|
Map<String,Object> proof=new LinkedHashMap<>();
|
proof.put("purpose","dms-revision-edit"); proof.put("tenantId",tenant); proof.put("ownerId",owner);
|
proof.put("modelId",request.getModelId()); proof.put("sourceItemId",request.getSourceItemId());
|
proof.put("parentField",source.getParentField()); proof.put("field",source.getField());
|
proof.put("versionId",source.getVersionId()); proof.put("originFileId",file.get("fileId"));
|
proof.put("expiresAt",System.currentTimeMillis()+14400000L); proof.put("file",new LinkedHashMap<>(file));
|
file.put("revisionEditReceipt",issueTicket.apply(JsonUtil.getObjectToString(proof),14400L));
|
}
|
files.add(file);
|
}
|
Map<String,Object> row=new LinkedHashMap<>();
|
row.put("versionId",source.getVersionId()); row.put("parentField",source.getParentField());
|
row.put("field",source.getField()); row.put("files",files); result.add(row);
|
}
|
return result;
|
}
|
public Map<String,Object> verify(DmsRevisionEditRequest request) {
|
String raw=request.getReceipt()==null?null:parseTicket.apply(request.getReceipt());
|
Map<String,Object> proof=raw==null?Collections.emptyMap():JsonUtil.getJsonToBean(raw,Map.class);
|
if (!"dms-revision-edit".equals(proof.get("purpose")) || !Objects.equals(request.getTenantId(),proof.get("tenantId"))
|
|| !Objects.equals(request.getOwnerId(),proof.get("ownerId")) || !Objects.equals(request.getModelId(),proof.get("modelId"))
|
|| !Objects.equals(request.getField(),proof.get("field"))
|
|| !Objects.toString(request.getParentField(),"").equals(Objects.toString(proof.get("parentField"),""))
|
|| !(proof.get("expiresAt") instanceof Number) || ((Number)proof.get("expiresAt")).longValue()<=System.currentTimeMillis()
|
|| !(proof.get("file") instanceof Map) || !hasFileId((Map<String,Object>)proof.get("file"))) throw denied();
|
Map<String,Object> original=mapper.sources(request.getTenantId(),request.getOwnerId(),Objects.toString(proof.get("sourceItemId"),""),request.getModelId())
|
.stream().filter(source -> Objects.equals(source.getVersionId(),proof.get("versionId"))
|
&& Objects.equals(source.getField(),proof.get("field")) && Objects.equals(source.getParentField(),proof.get("parentField"))
|
).flatMap(source -> files(source.getFiles()).stream())
|
.filter(file -> Objects.equals(file.get("fileId"),proof.get("originFileId"))).findFirst().orElse(null);
|
if (original == null) throw denied();
|
// 历史来源凭据不代表模板。未编辑附件保留数据库原值,不能用五字段副本覆盖沿用数据。
|
// 使用 JSON 文本跨服务携带,避免空属性(如 fileVersionId:null)被响应序列化省略。
|
proof.remove("sourceFileJson");
|
if (Objects.equals(((Map<?,?>)proof.get("file")).get("fileId"), proof.get("originFileId"))) {
|
try { proof.put("sourceFileJson", SOURCE_JSON.writeValueAsString(original)); }
|
catch (com.fasterxml.jackson.core.JsonProcessingException e) { throw denied(); }
|
}
|
return proof;
|
}
|
private static boolean hasFileId(Map<String,Object> file) {
|
return file.get("fileId") instanceof String && !((String)file.get("fileId")).isBlank();
|
}
|
private static Map<String,Object> canonical(Map<String,Object> original) {
|
Map<String,Object> result=new LinkedHashMap<>();
|
for(String key:List.of("fileId","name","fileSize","fileExtension","url")) result.put(key,original.get(key));
|
return result;
|
}
|
private static List<Map<String,Object>> files(String json) {
|
if (json==null || json.isBlank()) return Collections.emptyList();
|
return (List)JsonUtil.getJsonToList(json,Map.class);
|
}
|
private static DataException denied() { return new DataException("修订来源已失效或不属于本人,请重新选择有效的修订申请"); }
|
}
|