刘光辉
8 小时以前 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
97
98
99
100
101
102
103
104
105
106
107
108
109
package jnpf.base.service;
 
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jnpf.base.entity.VisualdevEntity;
import jnpf.base.mapper.UploadEditReadMapper;
import jnpf.base.model.ColumnDataModel;
import jnpf.base.model.form.ModuleFormModel;
import jnpf.base.model.uploadedit.UploadEditContext;
import jnpf.base.util.UploadEditStateMachine;
import jnpf.exception.DataException;
import jnpf.permissions.PermissionInterfaceImpl;
import jnpf.util.JsonUtil;
import jnpf.util.UserProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.*;
 
/** Narrow shared-load reads; native detail rendering and persistence remain unchanged. */
@Service
@RequiredArgsConstructor
public class UploadEditReadService {
    private static final ObjectMapper JSON = new ObjectMapper();
    private final UploadEditReadMapper mapper;
 
    public VisualdevEntity model(String id) {
        VisualdevEntity model = mapper.releasedModel(id);
        return model == null ? mapper.designModel(id) : model;
    }
 
    /** Null means the published mapping needs the original native reader, never a failed query. */
    public Map<String, Object> dmsAttachment(VisualdevEntity model, UploadEditContext context, Map<?, ?> fieldConfig) {
        String table = supportedTable(model, context, fieldConfig);
        if (table == null) return null;
        boolean child = StringUtils.hasText(context.getParentField());
        if (child && !StringUtils.hasText(context.getRowId())) throw new DataException("子表行尚无跟踪 ID");
        // Preserve the native menu field boundary; denied/missing fields must not become empty attachments.
        ColumnDataModel columns = JsonUtil.getJsonToBean(model.getColumnData(), ColumnDataModel.class);
        if (columns != null && Boolean.TRUE.equals(columns.getUseFormPermission()) && StringUtils.hasText(context.getMenuId())) {
            Object granted = PermissionInterfaceImpl.getFormMap().get(context.getMenuId());
            String key = child ? context.getParentField() + "-" + context.getField() : context.getField();
            if (granted == null || JsonUtil.getJsonToList(granted, ModuleFormModel.class).stream()
                    .noneMatch(item -> key.equals(item.getEnCode()))) throw new DataException("没有附件字段查看权限");
        }
        String tenant = UserProvider.getUser().getTenantId();
        Map<String, Object> row = mapper.dmsAttachment(table, StringUtils.hasText(tenant) ? tenant : "0",
                context.getRecordId(), child ? context.getRowId() : null);
        if (row == null) throw new DataException("原生表单记录不存在");
        Map<String, Object> data = new HashMap<>();
        data.put("id", row.get("id")); data.put("flowTaskId", row.get("flowTaskId"));
        List<Map<String, Object>> files = UploadEditStateMachine.files(row.get("fileJson"));
        if (child) {
            if (!Objects.equals(context.getRowId(), row.get("rowId"))) throw new DataException("附件所属子表行不存在");
            data.put(context.getParentField(), List.of(Map.of("id", row.get("rowId"), context.getField(), files)));
        } else data.put(context.getField(), files);
        return data;
    }
 
    /** Only optimize the verified default-source DMS schema; changed mappings retain native support. */
    String supportedTable(VisualdevEntity model, UploadEditContext context, Map<?, ?> fieldConfig) {
        if (!"0".equals(model.getDbLinkId()) || Boolean.TRUE.equals(fieldConfig.get("isVirtualField"))) return null;
        try {
            JsonNode form = JSON.readTree(model.getFormData());
            String table = form.path("tableName").asText();
            if (!Set.of("dms_wenjian_xinzeng_shenhe", "dms_wenjian_xiuding_shenhe").contains(table)
                    || !form.path("logicalDelete").asBoolean() || form.path("primaryKeyPolicy").asInt() != 1
                    || !table.equals(fieldConfig.get("tableName"))) return null;
            boolean child = StringUtils.hasText(context.getParentField());
            if (child ? !"jilu_mingxi".equals(context.getParentField()) || !"jilu_wenjian".equals(context.getField())
                    || !(table + "_jilu_mingxi").equals(fieldConfig.get("relationTable"))
                    : !"wenjian".equals(context.getField()) || Boolean.TRUE.equals(fieldConfig.get("isSubTable"))) return null;
            JsonNode tables = JSON.readTree(model.getVisualTables());
            if (tables == null || !tables.isArray()) return null;
            JsonNode main = null, detail = null;
            for (JsonNode item : tables) {
                if ("1".equals(item.path("typeId").asText())) {
                    if (main != null) return null;
                    main = item;
                }
                if ((table + "_jilu_mingxi").equals(item.path("table").asText())) detail = item;
            }
            if (main == null || !table.equals(main.path("table").asText()) || !standardPrimaryKey(main)
                    || !hasColumns(main, "f_id", "f_tenant_id", "f_delete_mark", "f_flow_task_id", "wenjian")) return null;
            if (child && (detail == null || !standardPrimaryKey(detail)
                    || !hasColumns(detail, "f_id", "f_tenant_id", "f_delete_mark", "f_foreign_id", "jilu_wenjian")
                    || !"f_foreign_id".equals(detail.path("tableField").asText())
                    || !"f_id".equals(detail.path("relationField").asText()))) return null;
            return table;
        } catch (Exception malformedMapping) {
            return null; // The existing native reader owns unsupported/malformed metadata errors.
        }
    }
 
    private boolean standardPrimaryKey(JsonNode table) {
        List<String> keys = new ArrayList<>();
        for (JsonNode field : table.path("fields")) {
            if (field.path("primaryKey").asInt() == 1 && !"f_tenant_id".equals(field.path("field").asText()))
                keys.add(field.path("field").asText());
        }
        return keys.equals(List.of("f_id"));
    }
 
    private boolean hasColumns(JsonNode table, String... required) {
        Set<String> columns = new HashSet<>();
        for (JsonNode field : table.path("fields")) columns.add(field.path("field").asText());
        return columns.containsAll(Arrays.asList(required));
    }
}