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));
|
}
|
}
|