@sy-common/organize-select-help 1.0.0-beta.62 → 1.0.0-beta.64

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/src/index.vue CHANGED
@@ -7,6 +7,7 @@
7
7
  width="1180"
8
8
  :mask-closable="false"
9
9
  class="modal-tree"
10
+ :fullscreen="true"
10
11
  >
11
12
  <div slot="header" class="header-text"><Icon type="md-information" class="icon-tip" />人员选择</div>
12
13
  <div class="content-container">
@@ -15,10 +16,14 @@
15
16
  <Tabs :value="tabName" @input="handleTabChange">
16
17
  <TabPane label="组织选择" name="org" v-if="name.includes('org')">
17
18
  <div class="tab">
18
- <span>组织搜索:</span>
19
- <Select v-model="orgSearch" filterable :remote-method="getOrgListBySearch" @on-change="getOrgOption" :loading="loadingOrg" placeholder="请输入组织名称" style="width: 600px;" clearable>
20
- <Option v-for="(option, index) in orgSearchList" :value="option.orgUnitId" :key="index">{{option.name}}</Option>
21
- </Select>
19
+ <div class="search-row">
20
+ <span class="search-label">组织搜索:</span>
21
+ <div class="search-input-wrapper">
22
+ <Select v-model="orgSearch" filterable :remote-method="getOrgListBySearch" @on-change="getOrgOption" :loading="loadingOrg" placeholder="请输入组织名称" style="width: 100%;" clearable>
23
+ <Option v-for="(option, index) in orgSearchList" :value="option.orgUnitId" :key="index">{{option.name}}</Option>
24
+ </Select>
25
+ </div>
26
+ </div>
22
27
  <div class="tag-content" v-if="isQuickOpen && orgTagList.length > 0">
23
28
  <span>快捷选择:</span>
24
29
  <div class="custom-select-wrapper">
@@ -48,7 +53,7 @@
48
53
  </div>
49
54
  </div>
50
55
  <div class="tree">
51
- <organizeTree @handleChange="getOrgList" ref="orgTree" :treeList="orgTree"></organizeTree>
56
+ <organizeTree v-if="orgTreeLoaded" @handleChange="getOrgList" ref="orgTree" :treeList="orgTree" :is-custom-tree="true" :disable-lazy-load="false"></organizeTree>
52
57
  </div>
53
58
  <div class="bottom-select">
54
59
  <CheckboxGroup v-model="includeLevelOrg">
@@ -74,10 +79,14 @@
74
79
  </div>
75
80
  </div>
76
81
  <div class="right">
77
- <span>组织搜索:</span>
78
- <Select v-model="postSearch" filterable :remote-method="getPostListBySearch" @on-change="getPostOption" placeholder="组织选择" :loading="loadingPost" clearable @on-clear="handlePostSearchClear" style="width: 365px;">
79
- <Option v-for="(option, index) in postSearchList" :value="option.orgUnitId" :key="index">{{option.name}}</Option>
80
- </Select>
82
+ <div class="search-row">
83
+ <span class="search-label">组织搜索:</span>
84
+ <div class="search-input-wrapper">
85
+ <Select v-model="postSearch" filterable :remote-method="getPostListBySearch" @on-change="getPostOption" placeholder="请输入组织名称" :loading="loadingPost" clearable @on-clear="handlePostSearchClear" style="width: 100%;">
86
+ <Option v-for="(option, index) in postSearchList" :value="option.orgUnitId" :key="index">{{option.name}}</Option>
87
+ </Select>
88
+ </div>
89
+ </div>
81
90
  <div class="tag-content" v-if="isQuickOpen && postTagList.length > 0">
82
91
  <span>快捷选择:</span>
83
92
  <div class="custom-select-wrapper">
@@ -107,7 +116,7 @@
107
116
  </div>
108
117
  </div>
109
118
  <div class="tree">
110
- <organizeTree @handleChange="getPostList" ref="postTree" :treeList="postTree"></organizeTree>
119
+ <organizeTree v-if="postTreeLoaded" @handleChange="getPostList" ref="postTree" :treeList="postTree" :is-custom-tree="true" :disable-lazy-load="false"></organizeTree>
111
120
  </div>
112
121
  <div class="bottom-select">
113
122
  <CheckboxGroup v-model="includeLevelPost">
@@ -128,6 +137,7 @@
128
137
  <div class="tree staff-org-tree">
129
138
  <div class="tree-scroll-force">
130
139
  <organizeTree
140
+ v-if="staffTreeLoaded"
131
141
  @handleChange="getStaffList"
132
142
  ref="staffTree"
133
143
  :treeList="staffTree"
@@ -142,7 +152,6 @@
142
152
  </div>
143
153
  </div>
144
154
  </div>
145
-
146
155
  <div class="staff-right-panel">
147
156
  <Input v-model="staffSearch" @on-enter="searchStaff" @on-search="searchStaff" search placeholder="搜索人员"/>
148
157
  <div style="position:relative;">
@@ -162,10 +171,10 @@
162
171
  </div>
163
172
  <Spin v-if="loadingStaff" size="large" fix />
164
173
  </div>
165
- <!-- <div class="bottom-select">-->
166
- <!-- <div>当前已选择 <span class="num">{{getCheckedStaff}}</span>人</div>-->
167
- <!-- <Button type="primary" icon="md-add" @click="addStaffList">添加人员</Button>-->
168
- <!-- </div>-->
174
+ <!-- <div class="bottom-select">-->
175
+ <!-- <div>当前已选择 <span class="num">{{getCheckedStaff}}</span>人</div>-->
176
+ <!-- <Button type="primary" icon="md-add" @click="addStaffList">添加人员</Button>-->
177
+ <!-- </div>-->
169
178
  </div>
170
179
  </div>
171
180
  </TabPane>
@@ -298,7 +307,14 @@ export default {
298
307
  selectedStaffOrgId: '', // 新增:选中的组织节点ID
299
308
  proStaffOrgList: [], // 新增:暂存选中的组织节点
300
309
  initialDefaultOrgUnitId: '', // 缓存初始defaultOrgUnitId
301
- staffTreeInited: false, // 组织树初始化完成标记(用于需求3)
310
+ // staffTreeInited: false, // 组织树初始化完成标记
311
+ // 树加载完成标记
312
+ orgTreeLoaded: false,
313
+ postTreeLoaded: false,
314
+ staffTreeLoaded: false,
315
+ // 缓存原始组织树/岗位树数据
316
+ originalOrgTree: [], // 组织Tab原始树缓存
317
+ originalPostTree: [], // 岗位Tab原始树缓存
302
318
  }
303
319
  },
304
320
  mounted() {
@@ -306,79 +322,260 @@ export default {
306
322
  this.queryPositionList()
307
323
  // this.loadMore()
308
324
  this.initialDefaultOrgUnitId = this.defaultOrgUnitId || ''; // 缓存初始值
325
+ this.initOrgOrgTree()
326
+ this.initPostOrgTree()
309
327
  this.initStaffOrgTree()
310
328
  },
311
329
 
312
330
  methods:{
331
+ async initOrgOrgTree() {
332
+ try {
333
+ this.proOrgList = [];
334
+ this.orgSearch = '';
335
+ this.orgSearchList = [];
336
+ this.orgTreeLoaded = false;
337
+
338
+ const orgDetailRes = await ajax.get(`/pub-manage-server/pub/organ/q/queryOrg`, {
339
+ params: { orgUnitId: '' }
340
+ });
341
+
342
+ if (orgDetailRes.data.code !== 1 || !orgDetailRes.data.data) {
343
+ this.$Message.warning("未查询到组织根节点,显示空树");
344
+ this.orgTree = [];
345
+ this.originalOrgTree = []; // 缓存空数据
346
+ this.orgTreeLoaded = true;
347
+ return;
348
+ }
349
+
350
+ const rootOrgData = orgDetailRes.data.data;
351
+ const leafNode = await this.judgeNodeLeafe(rootOrgData.orgUnitId);
352
+ const rootNode = this.safeDeepCopy({
353
+ orgUnitId: rootOrgData.orgUnitId,
354
+ orgUnitName: rootOrgData.orgUnitName,
355
+ parentOrgUnitId: rootOrgData.parentOrgUnitId,
356
+ leafNode: leafNode,
357
+ title: rootOrgData.orgUnitName || `未命名组织(${rootOrgData.orgUnitId})`,
358
+ expand: true,
359
+ orgChildrenList: [],
360
+ children: []
361
+ });
362
+
363
+ let parentsList = [];
364
+ try {
365
+ parentsList = await this.getParentOrgNodesByOrgUnitId(rootOrgData.orgUnitId);
366
+ } catch (e) {
367
+ console.warn('父节点查询失败,仅显示根节点:', e);
368
+ parentsList = [];
369
+ }
370
+
371
+ const safeParents = this.safeDeepCopy(parentsList).map(node => ({
372
+ orgUnitId: node.orgUnitId,
373
+ orgUnitName: node.orgUnitName || node.name,
374
+ parentOrgUnitId: node.parentOrgUnitId || node.parentId,
375
+ leafNode: false,
376
+ title: node.orgUnitName || node.name || `未命名组织(${node.orgUnitId})`,
377
+ expand: true,
378
+ orgChildrenList: [],
379
+ children: []
380
+ }));
381
+
382
+ const treeSourceData = [...safeParents, rootNode].filter(Boolean);
383
+ this.orgTree = this.buildTree(treeSourceData);
384
+ // 缓存原始树数据
385
+ this.originalOrgTree = this.safeDeepCopy(this.orgTree);
386
+
387
+ if (this.orgTree.length === 0) {
388
+ this.orgTree = [rootNode];
389
+ this.originalOrgTree = [rootNode]; // 同步缓存
390
+ }
391
+
392
+ this.orgTreeLoaded = true;
393
+
394
+ } catch (e) {
395
+ console.error("组织选择Tab树初始化失败:", e);
396
+ this.orgTree = [];
397
+ this.originalOrgTree = []; // 缓存空数据
398
+ this.orgTreeLoaded = true;
399
+ this.$Message.error("组织树初始化失败,请刷新重试");
400
+ }
401
+ },
402
+ async initPostOrgTree() {
403
+ try {
404
+ this.proPostList = [];
405
+ this.postSearch = '';
406
+ this.postSearchList = [];
407
+ this.selectedPositionId = null;
408
+ this.postTreeLoaded = false;
409
+
410
+ const orgDetailRes = await ajax.get(`/pub-manage-server/pub/organ/q/queryOrg`, {
411
+ params: { orgUnitId: '' }
412
+ });
413
+
414
+ if (orgDetailRes.data.code !== 1 || !orgDetailRes.data.data) {
415
+ this.$Message.warning("未查询到组织根节点,显示空树");
416
+ this.postTree = [];
417
+ this.originalPostTree = []; // 缓存空数据
418
+ this.postTreeLoaded = true;
419
+ return;
420
+ }
421
+
422
+ const rootOrgData = orgDetailRes.data.data;
423
+ const leafNode = await this.judgeNodeLeafe(rootOrgData.orgUnitId);
424
+ const rootNode = this.safeDeepCopy({
425
+ orgUnitId: rootOrgData.orgUnitId,
426
+ orgUnitName: rootOrgData.orgUnitName,
427
+ parentOrgUnitId: rootOrgData.parentOrgUnitId,
428
+ leafNode: leafNode,
429
+ title: rootOrgData.orgUnitName || `未命名组织(${rootOrgData.orgUnitId})`,
430
+ expand: true,
431
+ orgChildrenList: [],
432
+ children: []
433
+ });
434
+
435
+ let parentsList = [];
436
+ try {
437
+ parentsList = await this.getParentOrgNodesByOrgUnitId(rootOrgData.orgUnitId);
438
+ } catch (e) {
439
+ console.warn('岗位Tab父节点查询失败:', e);
440
+ parentsList = [];
441
+ }
442
+
443
+ const safeParents = this.safeDeepCopy(parentsList).map(node => ({
444
+ orgUnitId: node.orgUnitId,
445
+ orgUnitName: node.orgUnitName || node.name,
446
+ parentOrgUnitId: node.parentOrgUnitId || node.parentId,
447
+ leafNode: false,
448
+ title: node.orgUnitName || node.name || `未命名组织(${node.orgUnitId})`,
449
+ expand: true,
450
+ orgChildrenList: [],
451
+ children: []
452
+ }));
453
+
454
+ const treeSourceData = [...safeParents, rootNode].filter(Boolean);
455
+ this.postTree = this.buildTree(treeSourceData);
456
+ // 缓存原始树数据
457
+ this.originalPostTree = this.safeDeepCopy(this.postTree);
458
+
459
+ if (this.postTree.length === 0) {
460
+ this.postTree = [rootNode];
461
+ this.originalPostTree = [rootNode]; // 同步缓存
462
+ }
463
+
464
+ this.postTreeLoaded = true;
465
+
466
+ } catch (e) {
467
+ console.error("岗位选择Tab树初始化失败:", e);
468
+ this.postTree = [];
469
+ this.originalPostTree = []; // 缓存空数据
470
+ this.postTreeLoaded = true;
471
+ this.$Message.error("岗位组织树初始化失败,请刷新重试");
472
+ }
473
+ },
474
+
313
475
  async initStaffOrgTree() {
314
476
  try {
315
- // 关键修复:初始化时重置选中状态
477
+ // 初始化时重置选中状态
316
478
  this.$set(this, 'selectedStaffOrgId', '');
317
479
  this.proStaffOrgList = [];
318
-
480
+ this.staffTreeLoaded = false;
319
481
  const rootOrgId = this.defaultOrgUnitId || '';
320
482
  let rootNode = null;
321
483
  let treeSourceData = []; // 存储树原始数据,避免后续覆盖
322
484
 
323
- if (rootOrgId) {
324
- const orgDetailRes = await ajax.get(`/pub-manage-server/pub/organ/q/queryOrg`, {
325
- params: { orgUnitId: rootOrgId }
485
+ // if (rootOrgId) {
486
+ // const orgDetailRes = await ajax.get(`/pub-manage-server/pub/organ/q/queryOrg`, {
487
+ // params: { orgUnitId: rootOrgId }
488
+ // });
489
+ // if (orgDetailRes.data.code === 1 && orgDetailRes.data.data) {
490
+ // const orgData = orgDetailRes.data.data;
491
+ // const leafNode = await this.judgeNodeLeafe(rootOrgId);
492
+ // rootNode = this.safeDeepCopy({
493
+ // ...orgData,
494
+ // orgNodeName: orgData.orgUnitName || '',
495
+ // title: orgData.orgUnitName || `未命名组织(${orgData.orgUnitId || ''})`,
496
+ // leafNode,
497
+ // expand: true,
498
+ // parentOrgUnitId: orgData.parentOrgUnitId || orgData.parentId,
499
+ // orgChildrenList: [], // 初始化自定义子节点字段
500
+ // children: [] // 初始化 Tree 组件识别的 children 字段
501
+ // });
502
+ // // 父节点列表同样同步初始化 children 字段
503
+ // let parentsList = await this.getParentOrgNodesByOrgUnitId(rootOrgId);
504
+ // const safeParents = this.safeDeepCopy(parentsList);
505
+ // safeParents.forEach(node => {
506
+ // node.expand = true;
507
+ // node.parentOrgUnitId = node.parentId;
508
+ // node.orgNodeName = node.orgUnitName || node.orgNodeName || '';
509
+ // node.title = node.orgUnitName || node.name || `未命名组织(${node.orgUnitId || ''})`;
510
+ // node.orgChildrenList = [];
511
+ // node.children = []; // 父节点也初始化 children 字段
512
+ // node.leafNode = false;
513
+ // });
514
+ // treeSourceData = [...safeParents, rootNode];
515
+ // } else {
516
+ // this.$Message.error("根据默认组织ID查询根节点失败!");
517
+ // return;
518
+ // }
519
+ // } else {
520
+ // // defaultOrgUnitId为空时,沿用原有接口/pub/personHelpBox/q/getOrgUnitList
521
+ // const res = await ajax.get('/pub-manage-server/pub/personHelpBox/q/getOrgUnitList', {
522
+ // params: { containsCurLevel: true }
523
+ // });
524
+ // if (res.data.code === 1) {
525
+ // rootNode = res.data.data[0] || null;
526
+ // if (rootNode) {
527
+ // rootNode.expand = true;
528
+ // rootNode.parentOrgUnitId = rootNode.parentId;
529
+ // treeSourceData = [rootNode];
530
+ // }
531
+ // }
532
+ // }
533
+ const orgDetailRes = await ajax.get(`/pub-manage-server/pub/organ/q/queryOrg`, {
534
+ params: { orgUnitId: rootOrgId }
535
+ });
536
+ if (orgDetailRes.data.code === 1 && orgDetailRes.data.data) {
537
+ const orgData = orgDetailRes.data.data;
538
+ const leafNode = await this.judgeNodeLeafe(rootOrgId);
539
+ rootNode = this.safeDeepCopy({
540
+ ...orgData,
541
+ orgNodeName: orgData.orgUnitName || '',
542
+ title: orgData.orgUnitName || `未命名组织(${orgData.orgUnitId || ''})`,
543
+ leafNode,
544
+ expand: true,
545
+ parentOrgUnitId: orgData.parentOrgUnitId || orgData.parentId,
546
+ orgChildrenList: [], // 初始化自定义子节点字段
547
+ children: [] // 初始化 Tree 组件识别的 children 字段
326
548
  });
327
- if (orgDetailRes.data.code === 1 && orgDetailRes.data.data) {
328
- const orgData = orgDetailRes.data.data;
329
- const leafNode = await this.judgeNodeLeafe(rootOrgId);
330
- rootNode = this.safeDeepCopy({
331
- ...orgData,
332
- orgNodeName: orgData.orgUnitName || '',
333
- title: orgData.orgUnitName || `未命名组织(${orgData.orgUnitId || ''})`,
334
- leafNode,
335
- expand: true,
336
- parentOrgUnitId: orgData.parentOrgUnitId || orgData.parentId,
337
- orgChildrenList: [], // 初始化自定义子节点字段
338
- children: [] // 关键:初始化 Tree 组件识别的 children 字段
339
- });
340
- // 父节点列表同样同步初始化 children 字段
341
- let parentsList = await this.getParentOrgNodesByOrgUnitId(rootOrgId);
342
- const safeParents = this.safeDeepCopy(parentsList);
343
- safeParents.forEach(node => {
344
- node.expand = true;
345
- node.parentOrgUnitId = node.parentId;
346
- node.orgNodeName = node.orgUnitName || node.orgNodeName || '';
347
- node.title = node.orgUnitName || node.name || `未命名组织(${node.orgUnitId || ''})`;
348
- node.orgChildrenList = [];
349
- node.children = []; // 父节点也初始化 children 字段
350
- node.leafNode = false;
351
- });
352
- treeSourceData = [...safeParents, rootNode];
353
- } else {
354
- this.$Message.error("根据默认组织ID查询根节点失败!");
355
- return;
356
- }
357
- } else {
358
- // defaultOrgUnitId为空时,沿用原有接口/pub/personHelpBox/q/getOrgUnitList
359
- const res = await ajax.get('/pub-manage-server/pub/personHelpBox/q/getOrgUnitList', {
360
- params: { containsCurLevel: true }
549
+ // 父节点列表同样同步初始化 children 字段
550
+ let parentsList = await this.getParentOrgNodesByOrgUnitId(rootOrgId);
551
+ const safeParents = this.safeDeepCopy(parentsList);
552
+ safeParents.forEach(node => {
553
+ node.expand = true;
554
+ node.parentOrgUnitId = node.parentId;
555
+ node.orgNodeName = node.orgUnitName || node.orgNodeName || '';
556
+ node.title = node.orgUnitName || node.name || `未命名组织(${node.orgUnitId || ''})`;
557
+ node.orgChildrenList = [];
558
+ node.children = []; // 父节点也初始化 children 字段
559
+ node.leafNode = false;
361
560
  });
362
- if (res.data.code === 1) {
363
- rootNode = res.data.data[0] || null;
364
- if (rootNode) {
365
- rootNode.expand = true;
366
- rootNode.parentOrgUnitId = rootNode.parentId;
367
- treeSourceData = [rootNode];
368
- }
369
- }
561
+ treeSourceData = [...safeParents, rootNode];
562
+ } else {
563
+ this.$Message.error("根据默认组织ID查询根节点失败!");
564
+ this.staffTreeLoaded = true;
565
+ return;
370
566
  }
371
-
372
- // 构建组织树,且仅赋值一次,避免后续覆盖(需求3)
567
+ // 构建组织树,且仅赋值一次,避免后续覆盖
373
568
  if (treeSourceData.length > 0) {
374
569
  const tree = this.buildTree(treeSourceData);
375
570
  this.staffTree = this.safeDeepCopy(tree);
376
- // 关键:标记树已初始化完成,防止后续重复构建覆盖
377
- this.staffTreeInited = true;
571
+ // 标记树已初始化完成,防止后续重复构建覆盖
572
+ // this.staffTreeInited = true;
573
+ this.staffTreeLoaded = true;
378
574
  }
379
575
  } catch (e) {
380
576
  this.$Message.error("人员选择组织树初始化失败!");
381
577
  console.error(e);
578
+ this.staffTreeLoaded = true;
382
579
  }
383
580
  },
384
581
  handlePostTagSelect(quickPickKey) {
@@ -503,7 +700,6 @@ export default {
503
700
  this.loadingPost = false;
504
701
  if (res.data.code === 1) {
505
702
  let resp = res.data.data?.items ?? [];
506
- // 修复:岗位搜索结果深拷贝,避免引用污染
507
703
  this.postSearchList = this.safeDeepCopy(resp);
508
704
  } else {
509
705
  this.postSearchList = [];
@@ -511,13 +707,15 @@ export default {
511
707
  }
512
708
  });
513
709
  } else {
514
- // 修复:清空搜索时,同时清空树数据和暂存列表(与组织Tab一致)
710
+ // 仅清空搜索结果,不重置树数据
515
711
  this.postSearchList = [];
712
+ // 仅重置选中状态,保留树结构
516
713
  if (this.$refs.postTree) {
517
- this.$refs.postTree.initData();
714
+ this.$refs.postTree.initData(); // 清空选中状态
715
+ this.proPostList = []; // 清空暂存列表
518
716
  }
519
- this.proPostList = []; // 清空岗位暂存列表
520
- this.$set(this, 'postTree', []); // 清空岗位树数据
717
+ // 移除清空树数据的代码
718
+ // this.$set(this, 'postTree', []);
521
719
  }
522
720
  },
523
721
  getOrgUnitBySearchTerm(query,callback){
@@ -525,78 +723,138 @@ export default {
525
723
  },
526
724
  async getOrgOption(val) {
527
725
  this.selectedOrgTagKey = '';
528
- this.orgTagList.forEach(tag => {
529
- tag.checked = false;
530
- });
726
+ this.orgTagList.forEach(tag => tag.checked = false);
531
727
  this.proOrgList = [];
532
- if(!val) return this.$refs.orgTree.initData();
533
- let item = this.orgSearchList.filter((item)=> item.orgUnitId === val).shift();
534
- if (!item) return;
728
+ if (!val) {
729
+ // 清空搜索时恢复原始树数据,而非置空
730
+ this.orgTree = this.safeDeepCopy(this.originalOrgTree);
731
+ // 同步更新子组件数据
732
+ this.$nextTick(() => {
733
+ if (this.$refs.orgTree) {
734
+ this.$refs.orgTree.data = this.safeDeepCopy(this.orgTree);
735
+ // 重置树选中状态,但保留树结构
736
+ this.$refs.orgTree.initData();
737
+ }
738
+ });
739
+ return;
740
+ }
741
+ const orgDetailRes = await ajax.get(`/pub-manage-server/pub/organ/q/queryOrg`, {
742
+ params: { orgUnitId: val }
743
+ });
535
744
 
536
- const leafNode = await this.judgeNodeLeafe(item.orgUnitId);
537
- const ftem = this.safeDeepCopy({
538
- ...item,
539
- orgNodeName: item.name,
540
- parentOrgUnitId: item.parentId,
541
- leafNode: leafNode
745
+ if (orgDetailRes.data.code !== 1 || !orgDetailRes.data.data) {
746
+ this.$Message.error("获取组织节点详情失败!");
747
+ return;
748
+ }
749
+
750
+ const nodeData = orgDetailRes.data.data;
751
+ const currentNode = this.safeDeepCopy({
752
+ orgUnitId: nodeData.orgUnitId,
753
+ orgUnitName: nodeData.orgUnitName,
754
+ parentOrgUnitId: nodeData.parentOrgUnitId,
755
+ leafNode: nodeData.leafNode || await this.judgeNodeLeafe(nodeData.orgUnitId),
756
+ title: nodeData.orgUnitName || `未命名组织(${nodeData.orgUnitId})`,
757
+ expand: true,
758
+ orgChildrenList: [],
759
+ children: []
542
760
  });
543
761
 
544
- try{
762
+ try {
545
763
  let parentsList = await this.getParentOrgNodesByOrgUnitId(val);
546
- // 对父节点列表进行安全拷贝
547
- const safeParents = this.safeDeepCopy(parentsList);
548
- let tree = this.buildTree([...safeParents, ftem]);
549
- this.orgTree = this.safeDeepCopy(tree);
550
- }catch(e){
551
- this.$Message.error("获取组织节点列表失败!");
764
+ const safeParents = this.safeDeepCopy(parentsList).map(node => ({
765
+ orgUnitId: node.orgUnitId,
766
+ orgUnitName: node.orgUnitName || node.name,
767
+ parentOrgUnitId: node.parentOrgUnitId || node.parentId,
768
+ leafNode: false,
769
+ title: node.orgUnitName || node.name || `未命名组织(${node.orgUnitId})`,
770
+ expand: true,
771
+ orgChildrenList: [],
772
+ children: []
773
+ }));
774
+
775
+ const treeSourceData = [...safeParents, currentNode].filter(Boolean);
776
+ this.orgTree = this.buildTree(treeSourceData);
777
+
778
+ // 强制更新子组件数据
779
+ this.$nextTick(() => {
780
+ if (this.$refs.orgTree) {
781
+ this.$refs.orgTree.data = this.safeDeepCopy(this.orgTree);
782
+ }
783
+ });
784
+ } catch (e) {
785
+ this.$Message.error("更新组织树失败!");
552
786
  }
553
787
  },
554
788
  async getPostOption(val) {
555
- // 1. 重置选中的标签key
556
789
  this.selectedPostTagKey = '';
790
+ this.postTagList.forEach(tag => tag.checked = false);
557
791
 
558
- // 2. 重置所有标签的选中状态
559
- this.postTagList.forEach(tag => {
560
- tag.checked = false;
561
- });
562
792
  if (!val) {
563
- // 修复:岗位树清空时,同时清空暂存列表和搜索框
564
- if (this.$refs.postTree) {
565
- this.$refs.postTree.initData();
566
- }
567
- this.proPostList = []; // 清空岗位暂存列表(与组织Tab保持一致)
568
- this.postSearch = ''; // 清空搜索框
793
+ // 清空搜索时恢复原始树数据
794
+ this.postTree = this.safeDeepCopy(this.originalPostTree);
795
+ this.proPostList = [];
796
+ this.postSearch = '';
797
+ // 同步更新子组件数据
798
+ this.$nextTick(() => {
799
+ if (this.$refs.postTree) {
800
+ this.$refs.postTree.data = this.safeDeepCopy(this.postTree);
801
+ // 重置树选中状态,但保留树结构
802
+ this.$refs.postTree.initData();
803
+ }
804
+ });
569
805
  return;
570
806
  }
571
807
 
572
- let item = this.postSearchList.filter(item => item.orgUnitId === val).shift();
573
- if (!item) return;
808
+ // 原有逻辑保持不变
809
+ const orgDetailRes = await ajax.get(`/pub-manage-server/pub/organ/q/queryOrg`, {
810
+ params: { orgUnitId: val }
811
+ });
574
812
 
575
- const leafNode = await this.judgeNodeLeafe(item.orgUnitId);
576
- // 修复:岗位节点深拷贝,避免引用污染
577
- const ftem = this.safeDeepCopy({
578
- ...item,
579
- orgNodeName: item.name || `未命名组织(${item.orgUnitId})`,
580
- parentOrgUnitId: item.parentId,
581
- leafNode: leafNode
813
+ if (orgDetailRes.data.code !== 1 || !orgDetailRes.data.data) {
814
+ this.$Message.error("获取组织节点详情失败!");
815
+ return;
816
+ }
817
+
818
+ const nodeData = orgDetailRes.data.data;
819
+ const currentNode = this.safeDeepCopy({
820
+ orgUnitId: nodeData.orgUnitId,
821
+ orgUnitName: nodeData.orgUnitName,
822
+ parentOrgUnitId: nodeData.parentOrgUnitId,
823
+ leafNode: nodeData.leafNode || await this.judgeNodeLeafe(nodeData.orgUnitId),
824
+ title: nodeData.orgUnitName || `未命名组织(${nodeData.orgUnitId})`,
825
+ expand: true,
826
+ orgChildrenList: [],
827
+ children: []
582
828
  });
583
829
 
584
830
  try {
585
831
  let parentsList = await this.getParentOrgNodesByOrgUnitId(val);
586
- const safeParents = this.safeDeepCopy(parentsList);
587
- let tree = this.buildTree([...safeParents, ftem]);
588
- // 修复:用$set确保岗位树数据响应式更新
589
- this.$set(this, 'postTree', this.safeDeepCopy(tree));
832
+ const safeParents = this.safeDeepCopy(parentsList).map(node => ({
833
+ orgUnitId: node.orgUnitId,
834
+ orgUnitName: node.orgUnitName || node.name,
835
+ parentOrgUnitId: node.parentOrgUnitId || node.parentId,
836
+ leafNode: false,
837
+ title: node.orgUnitName || node.name || `未命名组织(${node.orgUnitId})`,
838
+ expand: true,
839
+ orgChildrenList: [],
840
+ children: []
841
+ }));
842
+
843
+ const treeSourceData = [...safeParents, currentNode].filter(Boolean);
844
+ this.postTree = this.buildTree(treeSourceData);
590
845
 
591
- // 修复:设置节点展开和选中(与组织Tab逻辑一致)
592
846
  this.$nextTick(() => {
593
847
  if (this.$refs.postTree && this.$refs.postTree.setCheckedNodes) {
594
- this.$refs.postTree.setCheckedNodes([val]); // 选中当前节点
595
- this.proPostList = [ftem]; // 同步暂存列表
848
+ this.$refs.postTree.setCheckedNodes([val]);
849
+ this.proPostList = [currentNode];
850
+ }
851
+ // 强制更新子组件数据
852
+ if (this.$refs.postTree) {
853
+ this.$refs.postTree.data = this.safeDeepCopy(this.postTree);
596
854
  }
597
855
  });
598
856
  } catch (e) {
599
- this.$Message.error("获取组织节点列表失败!");
857
+ this.$Message.error("更新岗位组织树失败!");
600
858
  }
601
859
  },
602
860
  async getStaffOption(val) {
@@ -623,67 +881,84 @@ export default {
623
881
  this.$Message.error("获取组织节点列表失败!");
624
882
  }
625
883
  },
626
- getParentOrgNodesByOrgUnitId(val){
627
- return new Promise((resolve,reject)=>{
628
- ajax.get('/pub-manage-server/pub/personHelpBox/q/getParentOrgNodesByOrgUnitId?orgUnitId='+val).then((res)=>{
629
- if(res.data.code === 1){
630
- let parentsList = res.data?.data?.items??[]
631
- resolve(parentsList)
632
- }else{
633
- reject(false)
634
- }
635
- })
636
- })
884
+ getParentOrgNodesByOrgUnitId(val) {
885
+ return new Promise((resolve) => {
886
+ ajax.get('/pub-manage-server/pub/personHelpBox/q/getParentOrgNodesByOrgUnitId?orgUnitId='+val)
887
+ .then((res) => {
888
+ if (res.data.code === 1) {
889
+ const parentsList = res.data?.data?.items ?? [];
890
+ resolve(parentsList); // 接口正常返回则取数据
891
+ } else {
892
+ resolve([]); // 接口报错返回空数组
893
+ }
894
+ })
895
+ .catch(() => {
896
+ resolve([]); // 网络/请求失败返回空数组
897
+ });
898
+ });
637
899
  },
638
- judgeNodeLeafe(orgUnitId){
639
- return new Promise((resolve,reject)=>{
640
- ajax.get('/pub-manage-server/pub/personHelpBox/q/getOrgUnitList', { params:{
641
- containsCurLevel:true,
642
- orgUnitId:orgUnitId,
900
+ judgeNodeLeafe(orgUnitId) {
901
+ return new Promise((resolve) => {
902
+ ajax.get('/pub-manage-server/pub/personHelpBox/q/getOrgUnitList', {
903
+ params: {
904
+ containsCurLevel: true,
905
+ orgUnitId: orgUnitId,
643
906
  }
644
- }).then((res)=>{
645
- if(res.data.code === 1){
646
- let treeList = res.data.data
647
- if(treeList && treeList.length){
648
- resolve(false)
649
- }else{
650
- resolve(true)
651
- }
652
- }else{
653
- resolve(false)
907
+ }).then((res) => {
908
+ if (res.data.code === 1) {
909
+ const treeList = res.data.data || [];
910
+ resolve(treeList.length === 0);
911
+ } else {
912
+ resolve(false); // 接口失败默认非叶子节点
654
913
  }
655
- })
656
- })
914
+ }).catch(() => {
915
+ resolve(false); // 网络错误默认非叶子节点
916
+ });
917
+ });
657
918
  },
658
919
  buildTree(items) {
659
- const map = {};
920
+ if (!Array.isArray(items) || items.length === 0) {
921
+ console.warn('构建树入参为空,返回空数组');
922
+ return [];
923
+ }
924
+
925
+ const map = new Map();
660
926
  const roots = [];
661
927
  const copiedItems = this.safeDeepCopy(items);
662
928
 
663
929
  copiedItems.forEach(item => {
664
930
  if (!item.orgUnitId) return;
665
- map[item.orgUnitId] = this.safeDeepCopy({
666
- ...item,
667
- orgChildrenList: [],
668
- children: [], // 强制初始化 children 空数组
669
- title: item.orgUnitName || item.orgNodeName || item.name || `未命名组织(${item.orgUnitId || ''})`
670
- });
931
+ map.set(item.orgUnitId, this.safeDeepCopy({
932
+ orgUnitId: item.orgUnitId,
933
+ orgUnitName: item.orgUnitName,
934
+ parentOrgUnitId: item.parentOrgUnitId,
935
+ leafNode: item.leafNode || false,
936
+ title: item.title || item.orgUnitName || `未命名组织(${item.orgUnitId})`,
937
+ expand: item.expand || true, // 保留展开状态
938
+ orgChildrenList: item.orgChildrenList || [],
939
+ children: item.children || []
940
+ }));
671
941
  });
672
942
 
673
943
  copiedItems.forEach(item => {
674
- if (!item.orgUnitId || !map[item.orgUnitId]) return;
944
+ if (!item.orgUnitId || !map.has(item.orgUnitId)) return;
675
945
 
676
- const node = map[item.orgUnitId];
677
- if (!item.parentOrgUnitId || !map[item.parentOrgUnitId]) {
946
+ const node = map.get(item.orgUnitId);
947
+ if (!item.parentOrgUnitId || !map.has(item.parentOrgUnitId)) {
678
948
  roots.push(node);
679
949
  } else {
680
- const parent = map[item.parentOrgUnitId];
950
+ const parent = map.get(item.parentOrgUnitId);
681
951
  parent.orgChildrenList.push(node);
682
- parent.children.push(node); // 同步 children 字段
683
- parent.leafNode = false;
684
- parent.expand = true;
952
+ parent.children.push(node);
953
+ parent.leafNode = false; // 有子节点则强制非叶子节点
954
+ parent.expand = true; // 有子节点则强制展开
685
955
  }
686
956
  });
957
+
958
+ if (roots.length === 0 && map.size > 0) {
959
+ roots.push(Array.from(map.values())[0]);
960
+ }
961
+
687
962
  return roots;
688
963
  },
689
964
 
@@ -691,7 +966,7 @@ export default {
691
966
  this.staffEnding = false;
692
967
  this.offset = 0;
693
968
  this.staffAllList = [];
694
- // 关键修复:50ms延迟,解决极端情况下的异步更新问题
969
+ // 50ms延迟,解决极端情况下的异步更新问题
695
970
  setTimeout(() => {
696
971
  this.loadMore();
697
972
  }, 50);
@@ -806,7 +1081,7 @@ export default {
806
1081
  return;
807
1082
  }
808
1083
 
809
- // 关键修复1:过滤仅含有效orgUnitId的节点,排除无效数据
1084
+ // 过滤仅含有效orgUnitId的节点,排除无效数据
810
1085
  const validNodes = data.filter(node =>
811
1086
  node.orgUnitId && typeof node.orgUnitId === 'string' // 确保orgUnitId存在且为字符串
812
1087
  );
@@ -820,7 +1095,7 @@ export default {
820
1095
  return;
821
1096
  }
822
1097
 
823
- // 关键修复2:单选逻辑强化,仅保留最后一个有效选中节点
1098
+ // 单选逻辑强化,仅保留最后一个有效选中节点
824
1099
  const currentNode = validNodes[validNodes.length - 1];
825
1100
  const currentOrgUnitId = currentNode.orgUnitId.trim(); // 去除空格,避免无效字符串
826
1101
 
@@ -835,11 +1110,11 @@ export default {
835
1110
  if (pureNode.orgChildrenList) pureNode.orgChildrenList = [];
836
1111
  if (pureNode.children) pureNode.children = [];
837
1112
 
838
- // 关键修复3:强制响应式更新,避免Vue数据延迟
1113
+ // 强制响应式更新,避免Vue数据延迟
839
1114
  this.$set(this, 'proStaffOrgList', [pureNode]);
840
1115
  this.$set(this, 'selectedStaffOrgId', currentOrgUnitId);
841
1116
 
842
- // 关键修复4:双重nextTick确保数据完全更新后再查询
1117
+ // 双重nextTick确保数据完全更新后再查询
843
1118
  this.$nextTick(() => {
844
1119
  if (this.selectedStaffOrgId !== currentOrgUnitId) {
845
1120
  this.$set(this, 'selectedStaffOrgId', currentOrgUnitId);
@@ -1049,15 +1324,14 @@ export default {
1049
1324
  this.offset = 0;
1050
1325
  this.staffAllList = [];
1051
1326
  this.loadingStaff = false;
1052
- this.loadMore().catch(err => console.log("同步加载失败:", err));
1053
- this.$nextTick(() => {
1054
- setTimeout(() => {
1055
- this.loadMore();
1056
- }, 100);
1057
- });
1058
- } else if (tabName === 'post' && this.$refs.postTree && this.proPostList.length === 0) {
1327
+ // 仅当树未初始化时才加载
1328
+ if (!this.staffTreeLoaded || this.staffTree.length === 0) {
1329
+ this.loadMore().catch(err => console.log("同步加载失败:", err));
1330
+ }
1331
+ } else if (tabName === 'post' && this.proPostList.length === 0) {
1059
1332
  this.proPostList = [];
1060
- this.$refs.postTree.initData();
1333
+ // 移除initData调用,避免重置树数据
1334
+ // this.$refs.postTree.initData();
1061
1335
  }
1062
1336
  },
1063
1337
  initStaffList() {
@@ -1081,7 +1355,8 @@ export default {
1081
1355
  const proListKey = 'proOrgList';
1082
1356
  const treeDataKey = 'orgTree';
1083
1357
  this[proListKey] = [];
1084
- if (treeRef) await treeRef.initData();
1358
+ // 移除initData调用
1359
+ // if (treeRef) await treeRef.initData();
1085
1360
  if (!treeRef) {
1086
1361
  this.$Message.error("组织树组件未初始化,请稍后再试");
1087
1362
  item.checked = !item.checked;
@@ -1125,7 +1400,8 @@ export default {
1125
1400
 
1126
1401
  this[proListKey] = [];
1127
1402
  const isCurrentlyChecked = item.checked;
1128
- if (treeRef) await treeRef.initData();
1403
+ // 移除initData调用,避免重置树数据
1404
+ // if (treeRef) await treeRef.initData();
1129
1405
 
1130
1406
  // 2. 清空岗位 Tab 标签选中状态(仅操作 postTagList)
1131
1407
  this.postTagList.forEach(tag => {
@@ -1322,7 +1598,6 @@ export default {
1322
1598
  }
1323
1599
  }
1324
1600
 
1325
- // 最终数据赋值(根据Tab类型区分,核心统一逻辑)
1326
1601
 
1327
1602
  if (matchedNodes.length > 0) {
1328
1603
  // 同步暂存列表(组织proOrgList/岗位proPostList)
@@ -1417,7 +1692,6 @@ export default {
1417
1692
  return obj;
1418
1693
  }
1419
1694
 
1420
- // 检测到循环引用时,保留核心字段(orgUnitId必选,其他字段尽可能保留)
1421
1695
  if (hash.has(obj)) {
1422
1696
  const safeObj = {
1423
1697
  orgUnitId: obj.orgUnitId,
@@ -1535,7 +1809,7 @@ export default {
1535
1809
  if (res.data.code === 1 && res.data.data && res.data.data.orgUnitId) {
1536
1810
  // 深拷贝并清理无效字段
1537
1811
  const node = this.safeDeepCopy(res.data.data);
1538
- // 核心修复:确保节点名称有默认值,避免空显示
1812
+ // 确保节点名称有默认值,避免空显示
1539
1813
  const nodeName = node.orgNodeName || node.orgUnitName || node.name || `未命名组织(${orgUnitId})`;
1540
1814
  node.orgNodeName = nodeName;
1541
1815
  node.orgUnitName = nodeName; // 同步更新orgUnitName,确保所有使用场景都有值
@@ -1661,29 +1935,59 @@ export default {
1661
1935
 
1662
1936
  .staff-left-right-layout {
1663
1937
  display: flex;
1664
- height: 650px !important;
1938
+ // 适配全屏:使用视口高度百分比 + 最小高度限制
1939
+ height: calc(100vh - 180px) !important;
1940
+ min-height: 500px !important;
1665
1941
  gap: 15px;
1666
1942
  padding: 0 5px;
1667
1943
  width: 100%;
1668
1944
  box-sizing: border-box;
1669
1945
  flex-wrap: nowrap !important;
1670
1946
 
1947
+ // 小屏幕 不改变左右结构
1948
+ @media (max-width: 1200px) {
1949
+ height: calc(100vh - 200px) !important;
1950
+
1951
+ & > .staff-left-panel {
1952
+ width: calc(60% - 7.5px) !important;
1953
+ min-width: 280px !important;
1954
+ max-width: none !important;
1955
+ }
1956
+ }
1957
+
1958
+ @media (max-width: 768px) {
1959
+ flex-wrap: wrap !important;
1960
+
1961
+ & > .staff-left-panel {
1962
+ width: 100% !important;
1963
+ min-width: 100% !important;
1964
+ max-width: 100% !important;
1965
+ height: 40% !important;
1966
+ margin-bottom: 10px;
1967
+ }
1968
+
1969
+ .staff-right-panel {
1970
+ width: 100% !important;
1971
+ height: 60% !important;
1972
+ }
1973
+ }
1974
+
1671
1975
  & > .staff-left-panel {
1672
- width: 320px !important;
1976
+ width: calc(60% - 7.5px) !important;
1673
1977
  min-width: 320px !important;
1674
- max-width: 320px !important;
1978
+ max-width: none !important;
1675
1979
  display: flex !important;
1676
1980
  flex-direction: column !important;
1677
1981
  box-sizing: border-box !important;
1678
1982
  flex-shrink: 0 !important;
1679
1983
  flex-grow: 0 !important;
1680
1984
  height: 100% !important;
1681
- position: relative !important; // 确保子元素 z-index 生效
1985
+ position: relative !important;
1682
1986
 
1683
1987
  ::v-deep(.panel-title) {
1684
1988
  all: unset !important;
1685
- display: flex !important; // 改为flex,方便对齐竖条和文字
1686
- align-items: center !important; // 文字垂直居中
1989
+ display: flex !important;
1990
+ align-items: center !important;
1687
1991
  visibility: visible !important;
1688
1992
  opacity: 1 !important;
1689
1993
  height: 20px !important;
@@ -1698,20 +2002,20 @@ export default {
1698
2002
  box-sizing: border-box !important;
1699
2003
  position: relative !important;
1700
2004
  width: 100% !important;
1701
- // 左侧竖条核心样式
2005
+ // 左侧竖条样式
1702
2006
  &::before {
1703
2007
  content: '' !important;
1704
2008
  display: inline-block !important;
1705
2009
  width: 5px !important; // 竖条宽度
1706
2010
  height: 16px !important; // 竖条高度(略小于文字行高)
1707
- background-color: #1890ff !important; // 蓝色竖条(可改颜色)
2011
+ background-color: #1890ff !important; // 蓝色竖条
1708
2012
  margin-right: 8px !important; // 竖条与文字间距
1709
2013
  //border-radius: 1.5px !important;
1710
2014
  }
1711
2015
  }
1712
2016
 
1713
2017
  .staff-org-tree {
1714
- height: calc(100% - 28px) !important; /* 28 = 标题高度20 + 间距8 */
2018
+ height: calc(100% - 28px - 10px) !important; /* 28=标题高度+间距 + 10px额外缩减,确保按钮可见 */
1715
2019
  border: 1px solid #EAECF0;
1716
2020
  border-radius: 4px;
1717
2021
  padding: 0 !important;
@@ -1748,9 +2052,8 @@ export default {
1748
2052
  }
1749
2053
 
1750
2054
  .staff-right-panel {
1751
- flex: 1 !important;
2055
+ width: calc(40% - 7.5px) !important;
1752
2056
  min-width: 0 !important;
1753
- width: calc(100% - 335px) !important;
1754
2057
  display: flex;
1755
2058
  flex-direction: column;
1756
2059
  box-sizing: border-box;
@@ -1764,9 +2067,10 @@ export default {
1764
2067
  flex-shrink: 0;
1765
2068
  }
1766
2069
 
1767
- // 右侧人员列表容器:高度 = 父容器高度 - 搜索框高度 - 底部选择栏高度 - 两次间距(8*2)
2070
+ // 右侧人员列表容器:适配全屏高度
1768
2071
  .staff-content {
1769
- height: calc(100% - 32px - 40px - 16px) !important; /* 40=底部选择栏高度,16=8*2间距 */
2072
+ height: calc(100% - 32px - 40px - 16px - 10px) !important;
2073
+ min-height: 200px !important; // 小屏幕最小高度限制
1770
2074
  border: 1px solid #EAECF0;
1771
2075
  border-radius: 4px;
1772
2076
  overflow-x: hidden !important;
@@ -1804,11 +2108,21 @@ export default {
1804
2108
  }
1805
2109
  }
1806
2110
 
2111
+
1807
2112
  .tab-content-pro {
1808
2113
  .tab {
2114
+ .search-row {
2115
+ display: flex;
2116
+ align-items: center;
2117
+ flex-wrap: nowrap; // 禁止换行
2118
+ width: 100%;
2119
+ gap: 8px; // 文字和搜索框之间的间距
2120
+ }
1809
2121
  .tree {
1810
- height: 500px !important;
1811
- max-height: 500px !important;
2122
+ // 全屏 使用百分比高度 + 最小高度
2123
+ height: calc(100vh - 340px) !important; // 从300px增加到340px,缩减40px高度
2124
+ min-height: 360px !important; // 降低最小高度,确保按钮可见
2125
+ max-height: none !important; // 移除最大高度限制
1812
2126
  margin-top:20px;
1813
2127
  overflow-y: auto !important;
1814
2128
  overflow-x: auto !important;
@@ -1829,8 +2143,10 @@ export default {
1829
2143
  }
1830
2144
 
1831
2145
  &.post .right .tree {
1832
- height: 380px !important;
1833
- max-height: 380px !important;
2146
+ // 岗位树适配全屏(缩减高度确保按钮可见)
2147
+ height: calc(100vh - 430px) !important; // 从400px增加到430px,缩减30px高度
2148
+ min-height: 270px !important; // 降低最小高度,确保按钮可见
2149
+ max-height: none !important;
1834
2150
  }
1835
2151
 
1836
2152
  .bottom-select {
@@ -1847,10 +2163,21 @@ export default {
1847
2163
  color:var(--primary-color);
1848
2164
  }
1849
2165
  }
2166
+ // 搜索标签样式(固定宽度,不换行)
2167
+ .search-label {
2168
+ white-space: nowrap; // 文字不换行
2169
+ flex-shrink: 0; // 不被压缩
2170
+ font-size: 14px;
2171
+ color: #333;
2172
+ }
2173
+ // 搜索框容器样式(自适应剩余宽度)
2174
+ .search-input-wrapper {
2175
+ flex: 1; // 占满剩余宽度
2176
+ min-width: 0; // 允许搜索框收缩
2177
+ }
1850
2178
  }
1851
2179
  }
1852
2180
 
1853
-
1854
2181
  /deep/ .ivu-tree {
1855
2182
  width: 100% !important;
1856
2183
  box-sizing: border-box;
@@ -1893,11 +2220,24 @@ export default {
1893
2220
  }
1894
2221
 
1895
2222
  .tab.post .left {
1896
- width: 200px;
1897
- height: 450px !important;
2223
+ width: calc(50% - 10px) !important;
2224
+ // 适配全屏高度
2225
+ height: calc(100vh - 380px) !important;
2226
+ min-height: 270px !important;
1898
2227
  overflow: hidden !important;
1899
2228
  padding-right: 10px;
1900
2229
  box-sizing: border-box;
2230
+
2231
+ // 小屏幕仅调整宽度,不改变左右结构
2232
+ @media (max-width: 1200px) {
2233
+ width: calc(50% - 10px) !important;
2234
+ }
2235
+
2236
+ // 超小屏幕
2237
+ @media (max-width: 768px) {
2238
+ width: 100%;
2239
+ margin-bottom: 10px;
2240
+ }
1901
2241
  }
1902
2242
 
1903
2243
  .scroll-container {
@@ -2010,6 +2350,12 @@ export default {
2010
2350
  }
2011
2351
 
2012
2352
  .modal-tree{
2353
+ // 全屏适配:移除固定宽度限制
2354
+ width: 100% !important;
2355
+ height: 100% !important;
2356
+ max-width: none !important;
2357
+ max-height: none !important;
2358
+
2013
2359
  .header-text{
2014
2360
  font-weight: bold;
2015
2361
  font-size: 16px;
@@ -2024,12 +2370,20 @@ export default {
2024
2370
  line-height: 16px;
2025
2371
  }
2026
2372
  .content-container{
2373
+ width: 100%;
2374
+ height: 100%;
2375
+ padding: 10px;
2376
+ box-sizing: border-box;
2027
2377
  }
2028
2378
  .tree-orig{
2029
2379
  width:100%;
2030
2380
  display: flex;
2031
- height: 700px;
2381
+ // 适配全屏高度
2382
+ height: calc(100vh - 80px) !important;
2383
+ min-height: 600px !important;
2032
2384
  background: #fff;
2385
+ // 强制保留左右结构,仅超小屏幕 换行
2386
+ flex-wrap: nowrap !important;
2033
2387
 
2034
2388
  :global(.ivu-tabs-ink-bar) {
2035
2389
  height: 0 !important;
@@ -2072,9 +2426,22 @@ export default {
2072
2426
  }
2073
2427
  }
2074
2428
  .tab-content-pro{
2075
- width: 720px;
2429
+ // 6:4比例 - 减去gap的一半
2430
+ width: calc(60% - 10px) !important;
2431
+ max-width: none !important; // 取消固定最大宽度,按比例适配
2432
+ flex-shrink: 0 !important; // 禁止压缩
2076
2433
  border-radius: 8px;
2077
2434
  border: 1px solid #EAECF0;
2435
+ // 小屏幕保持6:4比例
2436
+ @media (max-width: 1200px) {
2437
+ width: calc(60% - 10px) !important;
2438
+ }
2439
+ // 超小屏幕兜底
2440
+ @media (max-width: 768px) {
2441
+ width: 100% !important;
2442
+ margin-bottom: 10px;
2443
+ }
2444
+
2078
2445
  .tab{
2079
2446
  padding:20px;
2080
2447
  .tag-content{
@@ -2084,12 +2451,13 @@ export default {
2084
2451
  align-items: center;
2085
2452
  }
2086
2453
  .tree {
2087
- height: 500px !important; // 从450px下调,预留下方复选框空间
2088
- max-height: 500px !important; // 强制最大高度,禁止超出
2454
+ height: calc(100vh - 340px) !important; // 缩减40px确保按钮可见
2455
+ min-height: 360px !important; // 降低最小高度
2456
+ max-height: none !important; // 移除最大高度限制
2089
2457
  margin-top:20px;
2090
2458
  overflow-y: auto !important; // 纵向溢出时滚动,而非超出
2091
2459
  overflow-x: auto !important; // 横向溢出时滚动
2092
- border: 1px solid #EAECF0; // 明确容器边界(可选)
2460
+ border: 1px solid #EAECF0; // 明确容器边界
2093
2461
  border-radius: 4px;
2094
2462
  box-sizing: border-box; // 包含边框/内边距计算
2095
2463
  // 滚动条样式统一(与人员Tab保持一致)
@@ -2105,8 +2473,9 @@ export default {
2105
2473
  }
2106
2474
  }
2107
2475
  &.post .right .tree {
2108
- height: 380px !important;
2109
- max-height: 380px !important;
2476
+ height: calc(100vh - 430px) !important; // 缩减30px确保按钮可见
2477
+ min-height: 270px !important; // 降低最小高度
2478
+ max-height: none !important;
2110
2479
  }
2111
2480
  .staff-content{
2112
2481
  overflow:auto;
@@ -2120,7 +2489,7 @@ export default {
2120
2489
  background: #fff !important; // 白色背景覆盖树溢出内容
2121
2490
  position: relative;
2122
2491
  z-index: 10; // 层级高于树容器
2123
- border-top: 1px solid #f0f0f0; // 视觉分隔(可选)
2492
+ border-top: 1px solid #f0f0f0; // 视觉分隔
2124
2493
  .num{
2125
2494
  color:var(--primary-color);
2126
2495
  }
@@ -2163,8 +2532,29 @@ export default {
2163
2532
  .post{
2164
2533
  display: flex;
2165
2534
  height: 100%;
2535
+ // 小屏幕仅调整宽度,不改变左右结构
2536
+ @media (max-width: 1200px) {
2537
+ .left {
2538
+ width: calc(50% - 10px) !important; // 同步改为50%
2539
+ }
2540
+ }
2541
+ // 超小屏幕兜底
2542
+ @media (max-width: 768px) {
2543
+ flex-direction: column;
2544
+
2545
+ .left {
2546
+ width: 100%;
2547
+ margin-bottom: 10px;
2548
+ }
2549
+
2550
+ .right {
2551
+ margin-left: 0;
2552
+ width: 100%;
2553
+ }
2554
+ }
2555
+
2166
2556
  .left{
2167
- width:200px;
2557
+ width: calc(50% - 10px) !important;
2168
2558
  overflow: auto;
2169
2559
  >div{
2170
2560
  background: #FFFFFF;
@@ -2185,7 +2575,8 @@ export default {
2185
2575
  }
2186
2576
  .right{
2187
2577
  margin-left:20px;
2188
- flex: 1;
2578
+ width: calc(50% - 10px) !important;
2579
+ flex: none !important;
2189
2580
  }
2190
2581
  }
2191
2582
  .gust-item{
@@ -2235,12 +2626,23 @@ export default {
2235
2626
  //}
2236
2627
  }
2237
2628
  .form-content{
2238
- flex:1;
2629
+ // 6:4比例 - 减去gap的一半
2630
+ width: calc(40% - 10px) !important;
2631
+ min-width: 300px !important; // 最小宽度限制
2239
2632
  overflow: hidden;
2240
2633
  border-radius: 8px;
2241
2634
  border: 1px solid #EAECF0;
2242
2635
  margin-left:20px;
2243
2636
  padding:10px 20px;
2637
+ height: 100%;
2638
+ flex: none !important; // 取消弹性,固定比例
2639
+ // 超小屏幕
2640
+ @media (max-width: 768px) {
2641
+ margin-left: 0;
2642
+ width: 100%;
2643
+ margin-top: 10px;
2644
+ }
2645
+
2244
2646
  >p{
2245
2647
  font-weight: 500;
2246
2648
  font-size: 16px;
@@ -2300,4 +2702,28 @@ export default {
2300
2702
  }
2301
2703
  }
2302
2704
  }
2705
+
2706
+ // 超小屏幕适配(手机端)
2707
+ @media (max-width: 768px) {
2708
+ .modal-tree .tree-orig {
2709
+ flex-wrap: wrap !important; // 仅超小屏幕换行
2710
+ height: calc(100vh - 100px) !important;
2711
+ min-height: 400px !important;
2712
+ }
2713
+
2714
+ .tab-content-pro .tab .tree {
2715
+ height: calc(100vh - 380px) !important;
2716
+ min-height: 300px !important;
2717
+ }
2718
+
2719
+ .tab.post .left {
2720
+ height: calc(100vh - 480px) !important;
2721
+ min-height: 200px !important;
2722
+ }
2723
+
2724
+ .staff-left-right-layout {
2725
+ height: calc(100vh - 220px) !important;
2726
+ min-height: 400px !important;
2727
+ }
2728
+ }
2303
2729
  </style>