package jnpf.dmsService;
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import jnpf.exception.DataException;
|
import java.util.*;
|
|
/** Native organizeSelect values; deliberately rejects users, positions and unresolved dynamic parameters. */
|
public final class DmsApprovedDepartmentScope {
|
private static final ObjectMapper JSON = new ObjectMapper();
|
public record Department(String id, String scope) {}
|
private DmsApprovedDepartmentScope() {}
|
|
public static List<Department> parse(String value) {
|
if (value == null || value.isBlank()) return List.of();
|
try {
|
JsonNode array = JSON.readTree(value);
|
// Native empty selections can be SQL NULL or serialized JSON null.
|
if (array == null || array.isNull()) return List.of();
|
if (!array.isArray()) throw new DataException("查阅授权部门必须为数组");
|
Map<String, Department> departments = new TreeMap<>();
|
for (JsonNode node : array) {
|
if (!node.isTextual()) throw new DataException("查阅授权部门必须为ID字符串");
|
String token = node.textValue().trim();
|
String id = token, scope = "SELF";
|
int separator = token.indexOf("--");
|
if (separator >= 0) {
|
id = token.substring(0, separator);
|
scope = switch (token.substring(separator + 2)) {
|
case "org" -> "SELF";
|
case "subOrg" -> "CHILDREN";
|
case "progenyOrg" -> "DESCENDANTS";
|
default -> throw new DataException("查阅授权仅支持部门及部门下级范围");
|
};
|
}
|
if (id.isBlank() || id.length() > 100 || id.startsWith("@") || !id.equals(id.trim())
|
|| id.chars().anyMatch(Character::isWhitespace))
|
throw new DataException("查阅授权部门ID无效");
|
Department candidate = new Department(id, scope);
|
Department old = departments.get(id);
|
if (old == null || rank(candidate.scope()) > rank(old.scope())) departments.put(id, candidate);
|
}
|
return List.copyOf(departments.values());
|
} catch (DataException ex) { throw ex; }
|
catch (Exception ex) { throw new DataException("查阅授权部门格式无效"); }
|
}
|
|
public static String normalize(String value) {
|
List<Department> departments = parse(value);
|
try {
|
return JSON.writeValueAsString(departments.stream().map(d -> d.id() + switch (d.scope()) {
|
case "CHILDREN" -> "--subOrg";
|
case "DESCENDANTS" -> "--progenyOrg";
|
default -> "";
|
}).toList());
|
} catch (Exception ex) { throw new DataException("无法保存查阅授权部门快照"); }
|
}
|
private static int rank(String scope) {
|
return switch (scope) { case "CHILDREN" -> 1; case "DESCENDANTS" -> 2; default -> 0; };
|
}
|
}
|