package jnpf.base.util; import jnpf.exception.DataException; import jnpf.util.JsonUtil; import jnpf.util.TicketUtil; import java.util.*; /** 当前附件的可信模板来源;不从文件名推断,不追踪记录子表。 */ public final class UploadTemplateSource { public static final String FIELD = "laiyuan_muban_id"; private UploadTemplateSource() { } public static void inherit(Map target, Map source) { Object id = source.get(FIELD); Object savedAt = source.get("contentSavedAt"); target.remove(FIELD); target.remove("contentSavedAt"); if (savedAt instanceof Number time && time.longValue() > 0) target.put("contentSavedAt", time.longValue()); if (id instanceof String && !((String) id).isBlank()) target.put(FIELD, id); } public static Map uploaded(Map file, String tenant, String owner) { Object receipt = file.get("uploadReceipt"); String raw = receipt instanceof String ? TicketUtil.parseTicket((String) receipt) : null; Map proof = raw == null ? Collections.emptyMap() : JsonUtil.getJsonToBean(raw, Map.class); if (!"upload-edit-source".equals(proof.get("purpose")) || !tenant.equals(proof.get("tenantId")) || !owner.equals(proof.get("ownerId")) || !Objects.equals(file.get("fileId"), proof.get("fileId"))) throw new DataException("无法核验附件来源,请重新选择模板或上传文件"); Map result = new LinkedHashMap<>(); for (String key : List.of("fileId", "name", "fileSize", "fileExtension", "url", "contentSavedAt")) result.put(key, proof.get(key)); inherit(result, proof); return result; } /** 新凭据优先于同fileId的旧关联;未携带新凭据时仅继承服务器已保存/已核验的附件。 */ public static void normalize(List> files, List> trusted, String tenant, String owner) { for (Map file : files) { Map previous = trusted.stream() .filter(old -> Objects.equals(old.get("fileId"), file.get("fileId"))).findFirst().orElse(null); if (file.containsKey("uploadReceipt") && (previous == null || !Objects.equals(file.get("uploadReceipt"), previous.get("uploadReceipt")))) { inherit(file, uploaded(file, tenant, owner)); } else inherit(file, previous == null ? Collections.emptyMap() : previous); } } }