刘光辉
3 小时以前 06f314545ac3514d7ce28939920866ae8188d31c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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("修订来源已失效或不属于本人,请重新选择有效的修订申请"); }
}