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
/**
 * 标准库树通用工具
 *
 * 标准库固定两级:code=[1] 为行业,code=[2] 为标准。
 * 兼容没有 code 的旧接口数据时,再回退到 children 判断叶子。
 * 树路径统一由 " - " 连接,格式与历史实现逐字节保持一致:
 * 顶层真实节点的 parent 是 Element UI 的虚拟根,因此根节点会进入路径。
 */
 
// 是否叶子(标准)
export function isLeaf(data) {
  if (!data) return true;
  if (data.code === '[1]') return false;
  if (data.code === '[2]') return true;
  const children = data.children;
  return children === null || children === undefined || children.length === 0;
}
 
// 祖先 label 列表:含根,顺序为 根 -> 叶
export function getAncestorLabels(node) {
  const labels = [];
  let cur = node;
  while (cur && cur.parent) {
    labels.push(cur.label);
    cur = cur.parent;
  }
  labels.reverse();
  return labels;
}
 
// 复刻原 getNodeParent 的路径格式
// leafMarker:标准库传 'null',下单侧传 ''
// 叶子判定必须与 isLeaf 一致,否则 children 为 undefined / 空数组的叶子会丢失标记段
export function buildSelectTree(node, leafMarker = '') {
  const tokens = [];
  let cur = node;
  while (cur && cur.parent) {
    if (isLeaf(cur.data)) {
      tokens.push(cur.label, leafMarker);
    } else {
      tokens.push(cur.label);
    }
    cur = cur.parent;
  }
  tokens.reverse();
  return tokens.join(' - ');
}
 
// 路径末段是否为叶子(标准):buildSelectTree 会在叶子前插入标记段
// 用它判断无需依赖 el-tree 节点对象,模板回填路径后同样适用
export function isLeafPath(path) {
  if (!path) return false;
  const tokens = path.split(' - ');
  if (tokens.length < 2) return false;
  const marker = tokens[tokens.length - 2];
  return marker === '' || marker === 'null';
}
 
// 按祖先位置映射订单实体字段
// 缺失的非叶子层级填空串,model 取叶子 label(叶子即标准)
export function deriveTreeFields(node) {
  const labels = getAncestorLabels(node);
  const n = labels.length;
  const at = (i) => (i < n - 1 ? labels[i] : '');
  return {
    labels,
    factory: at(0),
    laboratory: at(1),
    sampleType: at(2),
    sample: at(3),
    model: n ? labels[n - 1] : '',
  };
}
 
// 去掉路径末段,用于「当前是叶子但查不到标准」时回退到父级查询
export function dropLastLabel(path) {
  if (!path) return '';
  const idx = path.lastIndexOf(' - ');
  return idx === -1 ? '' : path.slice(0, idx);
}