@sy-common/organize-select-help 1.0.0-beta.54 → 1.0.0-beta.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.vue +73 -48
- package/src/organize-tree.vue +182 -57
package/package.json
CHANGED
package/src/index.vue
CHANGED
|
@@ -135,6 +135,9 @@
|
|
|
135
135
|
:checkStrictly="true"
|
|
136
136
|
:autoExpandParent="true"
|
|
137
137
|
:isSingleSelect="true"
|
|
138
|
+
:default-org-unit-id="defaultOrgUnitId"
|
|
139
|
+
:is-custom-tree="!!defaultOrgUnitId"
|
|
140
|
+
:disable-lazy-load="false"
|
|
138
141
|
></organizeTree>
|
|
139
142
|
</div>
|
|
140
143
|
</div>
|
|
@@ -294,15 +297,19 @@ export default {
|
|
|
294
297
|
staffOrgList:[],
|
|
295
298
|
staffSearchList:[],
|
|
296
299
|
selectedStaffOrgId: '', // 新增:选中的组织节点ID
|
|
297
|
-
proStaffOrgList: [] // 新增:暂存选中的组织节点
|
|
300
|
+
proStaffOrgList: [], // 新增:暂存选中的组织节点
|
|
301
|
+
initialDefaultOrgUnitId: '', // 缓存初始defaultOrgUnitId
|
|
302
|
+
staffTreeInited: false, // 组织树初始化完成标记(用于需求3)
|
|
298
303
|
}
|
|
299
304
|
},
|
|
300
305
|
mounted() {
|
|
301
306
|
this.queryTagList()
|
|
302
307
|
this.queryPositionList()
|
|
303
308
|
// this.loadMore()
|
|
309
|
+
this.initialDefaultOrgUnitId = this.defaultOrgUnitId || ''; // 缓存初始值
|
|
304
310
|
this.initStaffOrgTree()
|
|
305
311
|
},
|
|
312
|
+
|
|
306
313
|
methods:{
|
|
307
314
|
async initStaffOrgTree() {
|
|
308
315
|
try {
|
|
@@ -312,18 +319,44 @@ export default {
|
|
|
312
319
|
|
|
313
320
|
const rootOrgId = this.defaultOrgUnitId || '';
|
|
314
321
|
let rootNode = null;
|
|
322
|
+
let treeSourceData = []; // 存储树原始数据,避免后续覆盖
|
|
315
323
|
|
|
316
324
|
if (rootOrgId) {
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
rootNode = this.safeDeepCopy({
|
|
320
|
-
...orgDetail,
|
|
321
|
-
orgNodeName: orgDetail.orgNodeName || orgDetail.name,
|
|
322
|
-
leafNode,
|
|
323
|
-
expand: true,
|
|
324
|
-
parentOrgUnitId: orgDetail.parentOrgUnitId || orgDetail.parentId
|
|
325
|
+
const orgDetailRes = await ajax.get(`/pub-manage-server/pub/organ/q/queryOrg`, {
|
|
326
|
+
params: { orgUnitId: rootOrgId }
|
|
325
327
|
});
|
|
328
|
+
if (orgDetailRes.data.code === 1 && orgDetailRes.data.data) {
|
|
329
|
+
const orgData = orgDetailRes.data.data;
|
|
330
|
+
const leafNode = await this.judgeNodeLeafe(rootOrgId);
|
|
331
|
+
rootNode = this.safeDeepCopy({
|
|
332
|
+
...orgData,
|
|
333
|
+
orgNodeName: orgData.orgUnitName || '',
|
|
334
|
+
title: orgData.orgUnitName || `未命名组织(${orgData.orgUnitId || ''})`,
|
|
335
|
+
leafNode,
|
|
336
|
+
expand: true,
|
|
337
|
+
parentOrgUnitId: orgData.parentOrgUnitId || orgData.parentId,
|
|
338
|
+
orgChildrenList: [], // 初始化自定义子节点字段
|
|
339
|
+
children: [] // 关键:初始化 Tree 组件识别的 children 字段
|
|
340
|
+
});
|
|
341
|
+
// 父节点列表同样同步初始化 children 字段
|
|
342
|
+
let parentsList = await this.getParentOrgNodesByOrgUnitId(rootOrgId);
|
|
343
|
+
const safeParents = this.safeDeepCopy(parentsList);
|
|
344
|
+
safeParents.forEach(node => {
|
|
345
|
+
node.expand = true;
|
|
346
|
+
node.parentOrgUnitId = node.parentId;
|
|
347
|
+
node.orgNodeName = node.orgUnitName || node.orgNodeName || '';
|
|
348
|
+
node.title = node.orgUnitName || node.name || `未命名组织(${node.orgUnitId || ''})`;
|
|
349
|
+
node.orgChildrenList = [];
|
|
350
|
+
node.children = []; // 父节点也初始化 children 字段
|
|
351
|
+
node.leafNode = false;
|
|
352
|
+
});
|
|
353
|
+
treeSourceData = [...safeParents, rootNode];
|
|
354
|
+
} else {
|
|
355
|
+
this.$Message.error("根据默认组织ID查询根节点失败!");
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
326
358
|
} else {
|
|
359
|
+
// defaultOrgUnitId为空时,沿用原有接口/pub/personHelpBox/q/getOrgUnitList
|
|
327
360
|
const res = await ajax.get('/pub-manage-server/pub/personHelpBox/q/getOrgUnitList', {
|
|
328
361
|
params: { containsCurLevel: true }
|
|
329
362
|
});
|
|
@@ -332,19 +365,17 @@ export default {
|
|
|
332
365
|
if (rootNode) {
|
|
333
366
|
rootNode.expand = true;
|
|
334
367
|
rootNode.parentOrgUnitId = rootNode.parentId;
|
|
368
|
+
treeSourceData = [rootNode];
|
|
335
369
|
}
|
|
336
370
|
}
|
|
337
371
|
}
|
|
338
372
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
const
|
|
342
|
-
safeParents.forEach(node => {
|
|
343
|
-
node.expand = true;
|
|
344
|
-
node.parentOrgUnitId = node.parentId;
|
|
345
|
-
});
|
|
346
|
-
const tree = this.buildTree([...safeParents, rootNode]);
|
|
373
|
+
// 构建组织树,且仅赋值一次,避免后续覆盖(需求3)
|
|
374
|
+
if (treeSourceData.length > 0) {
|
|
375
|
+
const tree = this.buildTree(treeSourceData);
|
|
347
376
|
this.staffTree = this.safeDeepCopy(tree);
|
|
377
|
+
// 关键:标记树已初始化完成,防止后续重复构建覆盖
|
|
378
|
+
this.staffTreeInited = true;
|
|
348
379
|
}
|
|
349
380
|
} catch (e) {
|
|
350
381
|
this.$Message.error("人员选择组织树初始化失败!");
|
|
@@ -628,14 +659,15 @@ export default {
|
|
|
628
659
|
buildTree(items) {
|
|
629
660
|
const map = {};
|
|
630
661
|
const roots = [];
|
|
631
|
-
// 对输入数据进行安全拷贝
|
|
632
662
|
const copiedItems = this.safeDeepCopy(items);
|
|
633
663
|
|
|
634
664
|
copiedItems.forEach(item => {
|
|
635
|
-
if (!item.orgUnitId) return;
|
|
665
|
+
if (!item.orgUnitId) return;
|
|
636
666
|
map[item.orgUnitId] = this.safeDeepCopy({
|
|
637
667
|
...item,
|
|
638
|
-
orgChildrenList: []
|
|
668
|
+
orgChildrenList: [],
|
|
669
|
+
children: [], // 强制初始化 children 空数组
|
|
670
|
+
title: item.orgUnitName || item.orgNodeName || item.name || `未命名组织(${item.orgUnitId || ''})`
|
|
639
671
|
});
|
|
640
672
|
});
|
|
641
673
|
|
|
@@ -648,6 +680,9 @@ export default {
|
|
|
648
680
|
} else {
|
|
649
681
|
const parent = map[item.parentOrgUnitId];
|
|
650
682
|
parent.orgChildrenList.push(node);
|
|
683
|
+
parent.children.push(node); // 同步 children 字段
|
|
684
|
+
parent.leafNode = false;
|
|
685
|
+
parent.expand = true;
|
|
651
686
|
}
|
|
652
687
|
});
|
|
653
688
|
return roots;
|
|
@@ -669,15 +704,15 @@ export default {
|
|
|
669
704
|
limit: 10
|
|
670
705
|
};
|
|
671
706
|
|
|
672
|
-
// 关键优化:实时监测选中状态,未选中时显式传递空字符串(而非不传递)
|
|
673
707
|
if (this.selectedStaffOrgId && typeof this.selectedStaffOrgId === 'string' && this.selectedStaffOrgId.trim()) {
|
|
674
708
|
params.orgUnitId = this.selectedStaffOrgId.trim();
|
|
709
|
+
} else if (this.initialDefaultOrgUnitId && this.initialDefaultOrgUnitId.trim()) {
|
|
710
|
+
// 初始化及未选中节点时,使用传入的defaultOrgUnitId
|
|
711
|
+
params.orgUnitId = this.initialDefaultOrgUnitId.trim();
|
|
675
712
|
} else {
|
|
676
|
-
// 未选中任何节点时,显式设置orgUnitId为空字符串
|
|
677
713
|
params.orgUnitId = '';
|
|
678
714
|
}
|
|
679
715
|
|
|
680
|
-
// 调试日志:查看最终传递的参数
|
|
681
716
|
console.log('人员查询接口参数:', params);
|
|
682
717
|
|
|
683
718
|
return new Promise((resolve, reject) => {
|
|
@@ -722,9 +757,8 @@ export default {
|
|
|
722
757
|
}
|
|
723
758
|
},
|
|
724
759
|
getOrgList(data) {
|
|
725
|
-
// 过滤有效节点:仅要求orgUnitId(orgNodeName可选,用默认值兜底)
|
|
726
760
|
const validNodes = Array.isArray(data)
|
|
727
|
-
? data.filter(node => node.orgUnitId)
|
|
761
|
+
? data.filter(node => node.orgUnitId)
|
|
728
762
|
: [];
|
|
729
763
|
|
|
730
764
|
// 去重:基于orgUnitId避免重复
|
|
@@ -732,14 +766,13 @@ export default {
|
|
|
732
766
|
self.findIndex(item => item.orgUnitId === node.orgUnitId) === index
|
|
733
767
|
);
|
|
734
768
|
|
|
735
|
-
|
|
769
|
+
|
|
736
770
|
const completeNodes = uniqueNodes.map(node => ({
|
|
737
771
|
...node,
|
|
738
772
|
orgNodeName: node.orgNodeName || node.name || `未命名组织(${node.orgUnitId})`,
|
|
739
773
|
orgUnitName: node.orgNodeName || node.name || `未命名组织(${node.orgUnitId})`
|
|
740
774
|
}));
|
|
741
775
|
|
|
742
|
-
// 安全深拷贝,确保数据响应式
|
|
743
776
|
this.proOrgList = this.safeDeepCopy(completeNodes);
|
|
744
777
|
},
|
|
745
778
|
|
|
@@ -974,9 +1007,6 @@ export default {
|
|
|
974
1007
|
if (this.$refs.staffTree) {
|
|
975
1008
|
this.$refs.staffTree.clearAllChecked(this.$refs.staffTree.data);
|
|
976
1009
|
this.$refs.staffTree.$emit('handleChange', []);
|
|
977
|
-
if (this.$refs.staffTree.initData) {
|
|
978
|
-
this.$refs.staffTree.initData();
|
|
979
|
-
}
|
|
980
1010
|
}
|
|
981
1011
|
if (this.tabName === 'staff') {
|
|
982
1012
|
this.$nextTick(() => {
|
|
@@ -984,43 +1014,38 @@ export default {
|
|
|
984
1014
|
});
|
|
985
1015
|
}
|
|
986
1016
|
},
|
|
987
|
-
|
|
988
|
-
this.staffEnding = false;
|
|
989
|
-
this.offset = 0;
|
|
990
|
-
this.staffAllList = [];
|
|
991
|
-
// 小幅延迟,确保树重置完成后再发起查询(避免时序差)
|
|
992
|
-
this.$nextTick(() => {
|
|
993
|
-
setTimeout(() => {
|
|
994
|
-
this.loadMore();
|
|
995
|
-
}, 50); // 50ms足够,可根据实际情况调整
|
|
996
|
-
});
|
|
997
|
-
},
|
|
998
|
-
// 处理Tab切换,同步更新tabName
|
|
1017
|
+
|
|
999
1018
|
handleTabChange(tabName) {
|
|
1000
1019
|
this.tabName = tabName;
|
|
1001
1020
|
|
|
1002
|
-
// 仅修改人员Tab相关逻辑,不影响其他Tab
|
|
1003
1021
|
if (tabName === 'staff') {
|
|
1004
1022
|
this.resetStaffTreeChecked();
|
|
1005
|
-
// 第一步:同步重置查询参数(确保参数干净)
|
|
1006
1023
|
this.staffEnding = false;
|
|
1007
1024
|
this.offset = 0;
|
|
1008
1025
|
this.staffAllList = [];
|
|
1009
|
-
this.loadingStaff = false;
|
|
1010
|
-
// 第二步:立即同步调用(优先执行)
|
|
1026
|
+
this.loadingStaff = false;
|
|
1011
1027
|
this.loadMore().catch(err => console.log("同步加载失败:", err));
|
|
1012
|
-
// 第三步:异步兜底调用(防止同步调用被阻塞)
|
|
1013
1028
|
this.$nextTick(() => {
|
|
1014
1029
|
setTimeout(() => {
|
|
1015
1030
|
this.loadMore();
|
|
1016
1031
|
}, 100);
|
|
1017
1032
|
});
|
|
1018
1033
|
} else if (tabName === 'post' && this.$refs.postTree && this.proPostList.length === 0) {
|
|
1019
|
-
// 保留原有岗位Tab逻辑,不修改
|
|
1020
1034
|
this.proPostList = [];
|
|
1021
1035
|
this.$refs.postTree.initData();
|
|
1022
1036
|
}
|
|
1023
1037
|
},
|
|
1038
|
+
initStaffList() {
|
|
1039
|
+
this.staffEnding = false;
|
|
1040
|
+
this.offset = 0;
|
|
1041
|
+
this.staffAllList = [];
|
|
1042
|
+
// 小幅延迟,确保树重置完成后再发起查询(避免时序差)
|
|
1043
|
+
this.$nextTick(() => {
|
|
1044
|
+
setTimeout(() => {
|
|
1045
|
+
this.loadMore();
|
|
1046
|
+
}, 50); // 50ms足够,可根据实际情况调整
|
|
1047
|
+
});
|
|
1048
|
+
},
|
|
1024
1049
|
async fastChedkOrg(item) {
|
|
1025
1050
|
// 1. 改用组织 Tab 专属标签列表判断
|
|
1026
1051
|
if (!this.orgTagList.length) {
|
package/src/organize-tree.vue
CHANGED
|
@@ -33,6 +33,21 @@ export default {
|
|
|
33
33
|
isSingleSelect: {
|
|
34
34
|
type: Boolean,
|
|
35
35
|
default: false
|
|
36
|
+
},
|
|
37
|
+
// 新增1:接收父组件的 defaultOrgUnitId(自定义根节点ID)
|
|
38
|
+
defaultOrgUnitId: {
|
|
39
|
+
type: String,
|
|
40
|
+
default: ''
|
|
41
|
+
},
|
|
42
|
+
// 新增2:标记是否使用父组件构建的自定义树(禁用子组件自身的接口调用)
|
|
43
|
+
isCustomTree: {
|
|
44
|
+
type: Boolean,
|
|
45
|
+
default: false
|
|
46
|
+
},
|
|
47
|
+
// 新增3:禁用懒加载(避免触发子组件的旧接口)
|
|
48
|
+
disableLazyLoad: {
|
|
49
|
+
type: Boolean,
|
|
50
|
+
default: false
|
|
36
51
|
}
|
|
37
52
|
},
|
|
38
53
|
data() {
|
|
@@ -46,13 +61,66 @@ export default {
|
|
|
46
61
|
this.initData();
|
|
47
62
|
},
|
|
48
63
|
methods: {
|
|
64
|
+
safeDeepCopy(obj, hash = new WeakMap()) {
|
|
65
|
+
if (obj === null || typeof obj !== 'object') {
|
|
66
|
+
return obj;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// 检测循环引用,返回核心业务字段
|
|
70
|
+
if (hash.has(obj)) {
|
|
71
|
+
const safeObj = {
|
|
72
|
+
orgUnitId: obj.orgUnitId,
|
|
73
|
+
orgNodeName: obj.orgNodeName || obj.name || `未命名组织(${obj.orgUnitId || 'unknown'})`,
|
|
74
|
+
orgUnitName: obj.orgUnitName || obj.orgNodeName || obj.name || `未命名组织(${obj.orgUnitId || 'unknown'})`,
|
|
75
|
+
parentOrgUnitId: obj.parentOrgUnitId || obj.parentId || null
|
|
76
|
+
};
|
|
77
|
+
hash.set(obj, safeObj);
|
|
78
|
+
return safeObj;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let copy;
|
|
82
|
+
if (obj instanceof Array) {
|
|
83
|
+
copy = [];
|
|
84
|
+
hash.set(obj, copy);
|
|
85
|
+
for (let i = 0; i < obj.length; i++) {
|
|
86
|
+
copy[i] = this.safeDeepCopy(obj[i], hash);
|
|
87
|
+
}
|
|
88
|
+
} else if (obj instanceof Object) {
|
|
89
|
+
copy = {};
|
|
90
|
+
hash.set(obj, copy);
|
|
91
|
+
for (let key in obj) {
|
|
92
|
+
if (obj.hasOwnProperty(key)) {
|
|
93
|
+
// 过滤Vue内部无效字段,保留业务字段
|
|
94
|
+
if (['__vue__', '__ob__', '$parent', '$children'].includes(key)) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
// 子节点数组特殊处理
|
|
98
|
+
if (['orgChildrenList', 'children'].includes(key) && Array.isArray(obj[key])) {
|
|
99
|
+
copy[key] = obj[key].map(child => this.safeDeepCopy(child, hash));
|
|
100
|
+
} else {
|
|
101
|
+
copy[key] = this.safeDeepCopy(obj[key], hash);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
copy = obj;
|
|
107
|
+
}
|
|
108
|
+
return copy;
|
|
109
|
+
},
|
|
49
110
|
async initData() {
|
|
111
|
+
if (this.isCustomTree) {
|
|
112
|
+
this.loading = false;
|
|
113
|
+
let tree = deepCopy(this.treeList);
|
|
114
|
+
this.initTree(tree);
|
|
115
|
+
this.data = tree;
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
// 仅在非自定义树场景下生效
|
|
50
119
|
let data = await this.getOrgChildren();
|
|
51
120
|
this.loading = false;
|
|
52
121
|
this.data = data;
|
|
53
122
|
},
|
|
54
123
|
|
|
55
|
-
// 树组件内的 handleChange 方法修改(仅保留核心逻辑,移除冗余触发)
|
|
56
124
|
handleChange(data) {
|
|
57
125
|
// 仅处理复选框触发的选中数据,过滤空数据
|
|
58
126
|
if (!data || (Array.isArray(data) && data.length === 0)) {
|
|
@@ -105,18 +173,73 @@ export default {
|
|
|
105
173
|
if (node.checked !== shouldBeChecked) {
|
|
106
174
|
this.$set(node, 'checked', shouldBeChecked);
|
|
107
175
|
}
|
|
108
|
-
// 彻底删除子节点递归逻辑
|
|
109
176
|
});
|
|
110
177
|
};
|
|
111
178
|
updateNodeState(this.data);
|
|
112
179
|
},
|
|
113
180
|
|
|
114
181
|
async loadData(item, callback) {
|
|
182
|
+
// 自定义树场景(defaultOrgUnitId 不为空):原有逻辑不变
|
|
183
|
+
if (this.isCustomTree) {
|
|
184
|
+
let children = item.orgChildrenList || item.children || [];
|
|
185
|
+
const formattedChildren = this.safeDeepCopy(children).map(child => ({
|
|
186
|
+
...child,
|
|
187
|
+
title: child.orgUnitName || child.orgNodeName || child.name || `未命名组织(${child.orgUnitId || child.id || ''})`,
|
|
188
|
+
checked: false,
|
|
189
|
+
expand: false,
|
|
190
|
+
leafNode: child.leafNode || false,
|
|
191
|
+
orgChildrenList: child.orgChildrenList || [],
|
|
192
|
+
children: child.children || []
|
|
193
|
+
}));
|
|
194
|
+
if (formattedChildren.length === 0 && item.orgUnitId) {
|
|
195
|
+
try {
|
|
196
|
+
const res = await ajax.get('/pub-manage-server/pub/personHelpBox/q/getOrgUnitList', {
|
|
197
|
+
params: {
|
|
198
|
+
containsCurLevel: true,
|
|
199
|
+
orgUnitId: item.orgUnitId
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
if (res.data.code === 1) {
|
|
203
|
+
const apiChildren = res.data.data || [];
|
|
204
|
+
// 关键:对接口返回的二级节点进行 initTree 初始化
|
|
205
|
+
const initializedApiChildren = this.initTree(apiChildren);
|
|
206
|
+
const apiFormattedChildren = initializedApiChildren.map(child => ({
|
|
207
|
+
...child,
|
|
208
|
+
title: child.orgUnitName || child.orgNodeName || child.name || `未命名组织(${child.orgUnitId || ''})`,
|
|
209
|
+
checked: false,
|
|
210
|
+
expand: false,
|
|
211
|
+
leafNode: child.leafNode || false,
|
|
212
|
+
orgChildrenList: [],
|
|
213
|
+
children: []
|
|
214
|
+
}));
|
|
215
|
+
item.orgChildrenList = apiFormattedChildren;
|
|
216
|
+
item.children = apiFormattedChildren;
|
|
217
|
+
callback(apiFormattedChildren);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
} catch (e) {
|
|
221
|
+
console.error("加载自定义树子节点失败:", e);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
callback(formattedChildren);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// 非自定义树场景(defaultOrgUnitId 为空):补充子节点初始化
|
|
229
|
+
if (this.disableLazyLoad) {
|
|
230
|
+
callback([]);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
// 加载子节点后,先经过 initTree 处理再返回
|
|
115
234
|
let children = await this.getOrgChildren(item.orgUnitId);
|
|
116
|
-
|
|
235
|
+
const initializedChildren = this.initTree(children);
|
|
236
|
+
callback(initializedChildren);
|
|
117
237
|
},
|
|
118
238
|
|
|
119
239
|
getOrgChildren(orgUnitId = '') {
|
|
240
|
+
if (this.isCustomTree) {
|
|
241
|
+
return Promise.resolve([]);
|
|
242
|
+
}
|
|
120
243
|
return new Promise((resolve, reject) => {
|
|
121
244
|
ajax.get('/pub-manage-server/pub/personHelpBox/q/getOrgUnitList', {
|
|
122
245
|
params: {
|
|
@@ -125,9 +248,10 @@ export default {
|
|
|
125
248
|
}
|
|
126
249
|
}).then((res) => {
|
|
127
250
|
if (res.data.code === 1) {
|
|
128
|
-
let treeList = res.data.data;
|
|
129
|
-
|
|
130
|
-
|
|
251
|
+
let treeList = res.data.data || [];
|
|
252
|
+
// 关键修改:调用重构后的 initTree,递归初始化所有层级节点
|
|
253
|
+
const initializedTree = this.initTree(treeList);
|
|
254
|
+
resolve(initializedTree);
|
|
131
255
|
} else {
|
|
132
256
|
resolve([]);
|
|
133
257
|
}
|
|
@@ -253,61 +377,58 @@ export default {
|
|
|
253
377
|
}
|
|
254
378
|
return null;
|
|
255
379
|
},
|
|
256
|
-
|
|
380
|
+
// organize-tree.vue - 重构 initTree 方法,确保递归处理所有层级
|
|
257
381
|
initTree(treeList) {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
item.children = defineTree(item.orgChildrenList);
|
|
272
|
-
item.expand = true;
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
return list;
|
|
276
|
-
};
|
|
277
|
-
treeList.forEach(item => {
|
|
278
|
-
item.title = item.orgNodeName;
|
|
279
|
-
item.loading = false;
|
|
280
|
-
item.children = [];
|
|
281
|
-
item.expand = false;
|
|
282
|
-
item.checked = false; // 初始化Checkbox绑定的checked属性
|
|
283
|
-
if (item.orgChildrenList && item.orgChildrenList.length) {
|
|
284
|
-
item.children = defineTree(item.orgChildrenList);
|
|
285
|
-
item.expand = true;
|
|
286
|
-
}
|
|
382
|
+
// 递归处理节点的内部方法
|
|
383
|
+
const recursiveInitNode = (node) => {
|
|
384
|
+
// 1. 统一节点标题(优先级:orgUnitName > orgNodeName > name > 兜底)
|
|
385
|
+
node.title = node.orgUnitName || node.orgNodeName || node.name || `未命名组织(${node.orgUnitId || node.id || ''})`;
|
|
386
|
+
// 2. 初始化基础字段
|
|
387
|
+
node.loading = false;
|
|
388
|
+
node.expand = false;
|
|
389
|
+
node.checked = false;
|
|
390
|
+
// 3. 关键:无论是否有子节点,先初始化 children 空数组(让 Tree 组件识别可懒加载)
|
|
391
|
+
node.children = node.children || [];
|
|
392
|
+
// 4. 同步 orgChildrenList 和 children(双向绑定,避免字段不一致)
|
|
393
|
+
node.orgChildrenList = node.orgChildrenList || node.children || [];
|
|
394
|
+
// 5. 禁用状态处理
|
|
287
395
|
if (this.disabled) {
|
|
288
|
-
|
|
396
|
+
node.disabled = true;
|
|
289
397
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
delete
|
|
398
|
+
// 6. 叶子节点判断:如果明确标记为 leafNode,删除 loading 和 children(禁止展开)
|
|
399
|
+
if (node.leafNode) {
|
|
400
|
+
delete node.loading;
|
|
401
|
+
delete node.children;
|
|
402
|
+
delete node.orgChildrenList;
|
|
403
|
+
} else {
|
|
404
|
+
// 7. 非叶子节点:递归处理已有子节点(确保下级节点也完成初始化)
|
|
405
|
+
if (Array.isArray(node.orgChildrenList) && node.orgChildrenList.length > 0) {
|
|
406
|
+
node.children = node.orgChildrenList.map(child => recursiveInitNode(child));
|
|
407
|
+
node.expand = true; // 默认展开已有子节点的节点
|
|
408
|
+
}
|
|
293
409
|
}
|
|
294
|
-
|
|
410
|
+
return node;
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
// 处理根节点列表
|
|
414
|
+
if (Array.isArray(treeList)) {
|
|
415
|
+
return treeList.map(node => recursiveInitNode(node));
|
|
416
|
+
}
|
|
417
|
+
return treeList;
|
|
295
418
|
},
|
|
296
419
|
|
|
297
|
-
//renderContent添加Checkbox组件
|
|
298
420
|
renderContent(h, {root, node, data}) {
|
|
421
|
+
const nodeText = data.orgUnitName || data.title || data.orgNodeName || data.name || `未命名组织(${data.orgUnitId || data.id || ''})`;
|
|
299
422
|
return h('div', {
|
|
300
423
|
style: {
|
|
301
424
|
width: '100%',
|
|
302
425
|
overflow: 'hidden',
|
|
303
426
|
display: 'flex',
|
|
304
427
|
alignItems: 'center',
|
|
305
|
-
cursor: 'default'
|
|
428
|
+
cursor: 'default'
|
|
306
429
|
},
|
|
307
|
-
// 阻断整个节点容器的点击事件(仅复选框除外)
|
|
308
430
|
on: {
|
|
309
431
|
click: (e) => {
|
|
310
|
-
// 仅当点击复选框时放行,其他区域阻断
|
|
311
432
|
const isCheckbox = e.target.closest('.ivu-checkbox') || e.target.closest('.ivu-checkbox-icon');
|
|
312
433
|
if (!isCheckbox) {
|
|
313
434
|
e.stopPropagation();
|
|
@@ -324,22 +445,17 @@ export default {
|
|
|
324
445
|
},
|
|
325
446
|
style: {
|
|
326
447
|
marginRight: '8px',
|
|
327
|
-
cursor: 'pointer'
|
|
448
|
+
cursor: 'pointer'
|
|
328
449
|
},
|
|
329
450
|
on: {
|
|
330
451
|
'on-change': (checked) => {
|
|
331
452
|
this.$set(data, 'checked', checked);
|
|
332
|
-
|
|
333
|
-
// 单选逻辑:勾选当前节点时,清空其他所有节点
|
|
334
453
|
if (this.isSingleSelect && checked) {
|
|
335
454
|
this.clearOtherCheckedNodes([data.orgUnitId]);
|
|
336
455
|
}
|
|
337
|
-
|
|
338
|
-
// 收集选中节点(单选时仅返回当前节点)
|
|
339
456
|
const checkedNodes = this.isSingleSelect
|
|
340
457
|
? (checked ? [data] : [])
|
|
341
458
|
: this.collectCurrentCheckedNodes(this.data);
|
|
342
|
-
|
|
343
459
|
this.handleChange(checkedNodes);
|
|
344
460
|
}
|
|
345
461
|
}
|
|
@@ -350,18 +466,19 @@ export default {
|
|
|
350
466
|
marginRight: '8px',
|
|
351
467
|
width: '14px',
|
|
352
468
|
height: '14px',
|
|
353
|
-
pointerEvents: 'none'
|
|
469
|
+
pointerEvents: 'none'
|
|
354
470
|
}
|
|
355
471
|
}),
|
|
356
472
|
h('span', {
|
|
357
473
|
style: {
|
|
358
|
-
// overflow: 'hidden',
|
|
359
|
-
// textOverflow: 'ellipsis',
|
|
360
474
|
flex: 1,
|
|
361
|
-
pointerEvents: 'none',
|
|
362
|
-
userSelect: 'none'
|
|
475
|
+
pointerEvents: 'none',
|
|
476
|
+
userSelect: 'none',
|
|
477
|
+
// 新增:防止文字溢出导致的截断(可选,解决orgUnitId显示不全问题)
|
|
478
|
+
whiteSpace: 'normal',
|
|
479
|
+
wordWrap: 'break-word'
|
|
363
480
|
}
|
|
364
|
-
},
|
|
481
|
+
}, nodeText) // 使用调整优先级后的节点文字
|
|
365
482
|
]);
|
|
366
483
|
},
|
|
367
484
|
collectCurrentCheckedNodes(nodeList) {
|
|
@@ -399,6 +516,14 @@ export default {
|
|
|
399
516
|
watch: {
|
|
400
517
|
'treeList': {
|
|
401
518
|
handler(val) {
|
|
519
|
+
// 自定义树场景:直接使用父组件传递的树数据,不初始化旧接口
|
|
520
|
+
if (this.isCustomTree) {
|
|
521
|
+
let tree = deepCopy(val);
|
|
522
|
+
this.initTree(tree);
|
|
523
|
+
this.data = tree;
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
// 原有逻辑
|
|
402
527
|
let tree = deepCopy(val);
|
|
403
528
|
this.initTree(tree);
|
|
404
529
|
this.data = tree;
|