mdm-client 1.0.2 → 1.0.3

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.
@@ -73,6 +73,31 @@
73
73
  </template>
74
74
  </vue-virtual-tree>
75
75
 
76
+ <!-- volte树 -->
77
+ <vue-virtual-tree
78
+ v-show="activeTab === 'volte'"
79
+ ref="volteTreeRef"
80
+ :data="volteTreeData"
81
+ :props="{ children: 'children', label: 'label' }"
82
+ node-key="id"
83
+ show-checkbox
84
+ :height="dynamicTreeHeight"
85
+ :item-height="36"
86
+ @check="handleNodeCheck"
87
+ :filter-node-method="filterNode"
88
+ >
89
+ <template #default="{ node, data }">
90
+ <span class="custom-tree-node">
91
+ <span class="custom-tree-node-label" :title="node.label" v-if="data.isDept">{{
92
+ node.label
93
+ }}</span>
94
+ <span class="custom-tree-node-user" v-else>
95
+ <span :class="['custom-tree-node-icon']"></span>
96
+ <span class="custom-tree-node-label" :title="node.label">{{ node.label }}</span>
97
+ </span>
98
+ </span>
99
+ </template>
100
+ </vue-virtual-tree>
76
101
  <!-- 常用分组树 -->
77
102
  <vue-virtual-tree
78
103
  v-show="activeTab === '常用分组'"
@@ -165,7 +190,9 @@
165
190
  <div class="checkutl">
166
191
  <div v-for="item of tempInviteList" :key="item.id" class="userFlex">
167
192
  <div class="label">
168
- <span :class="['custom-item-icon', getInviteItemIconClass(item)]"></span> {{ item.label }}
193
+ <span :class="['custom-item-icon', getInviteItemIconClass(item)]"></span>
194
+ <span>{{ item.label }}</span>
195
+ <span :class="getChosenItemPlatformClass(item)"></span>
169
196
  </div>
170
197
  <div class="close" @click="removeInviteItem(item)"></div>
171
198
  </div>
@@ -207,7 +234,7 @@
207
234
 
208
235
  <script>
209
236
  import { debounce } from "lodash-es";
210
- import { mittBus, ShowMessage, deleteCommonGroupAndUser, getAddressOrgTree, getAddressAppTree, getCommonOrgTree, queryEquipmentAddressBook, queryMonitorAddressBook } from "../../utils/index";
237
+ import { mittBus, ShowMessage, deleteCommonGroupAndUser, getAddressOrgTree, getAddressAppTree, getCommonOrgTree, queryEquipmentAddressBook, queryMonitorAddressBook, getVolteAddressBook } from "../../utils/index";
211
238
  import VueVirtualTree from "@fit2cloud-ui/vue-virtual-tree";
212
239
  import CustomGroupDialog from "./customGroupDialog.vue";
213
240
  import EditGroupDialog from "./editGroupDialog.vue";
@@ -244,13 +271,14 @@ export default {
244
271
  // 树数据
245
272
  treeData: [],
246
273
  appTreeData: [],
274
+ volteTreeData: [],
247
275
  groupTreeData: [],
248
276
  equipmentTreeData: [],
249
277
  monitorTreeData: [],
250
278
 
251
279
  // 标签页相关
252
280
  activeTab: "组织架构",
253
- tabList: ["组织架构", "人员", "设备", "监控", "常用分组"],
281
+ tabList: ["组织架构", "人员", "volte", "设备", "监控", "常用分组"],
254
282
 
255
283
  // 搜索相关
256
284
  filterText: "",
@@ -341,6 +369,8 @@ export default {
341
369
  this.$refs.orgTreeRef.filter(val);
342
370
  } else if (this.activeTab === "人员" && this.$refs.appTreeRef) {
343
371
  this.$refs.appTreeRef.filter(val);
372
+ } else if (this.activeTab === "volte" && this.$refs.volteTreeRef) {
373
+ this.$refs.volteTreeRef.filter(val);
344
374
  } else if (this.activeTab === "常用分组" && this.$refs.groupTreeRef) {
345
375
  this.$refs.groupTreeRef.filter(val);
346
376
  } else if (this.activeTab === "设备" && this.$refs.equipmentTreeRef) {
@@ -354,10 +384,11 @@ export default {
354
384
  mittBus.on("getaddressBookUser", (e) => {
355
385
  this.filterText = "";
356
386
  // 转换props.inviteList的数据格式以适配新的tree结构
357
- this.tempInviteList = this.inviteList.map((item) => {
358
- // 如果已经是新格式,直接使用
359
- return item;
360
- });
387
+ // this.tempInviteList = this.inviteList.map((item) => {
388
+ // // 如果已经是新格式,直接使用
389
+ // return item;
390
+ // });
391
+ this.tempInviteList = []
361
392
  this.isaddressShow = true;
362
393
  if (e) {
363
394
  this.isInner = e.isInner;
@@ -397,6 +428,14 @@ export default {
397
428
  this.appTreeData = res.data.data;
398
429
  }
399
430
  },
431
+
432
+ // 获取volte树数据
433
+ async getVolteTreeData() {
434
+ const res = await getVolteAddressBook({}, { baseUrl: this.baseUrl, token: this.token });
435
+ if(res.data?.code == 200) {
436
+ this.volteTreeData = res.data.data;
437
+ }
438
+ },
400
439
 
401
440
  // 获取常用分组树数据
402
441
  async getGroupTreeData() {
@@ -426,6 +465,7 @@ export default {
426
465
  async getAllTreeData() {
427
466
  await this.getOrgTreeData();
428
467
  await this.getAppTreeData();
468
+ await this.getVolteTreeData();
429
469
  await this.getGroupTreeData();
430
470
  await this.getEquipmentTreeData();
431
471
  await this.getMonitorTreeData();
@@ -474,13 +514,39 @@ export default {
474
514
  // 将当前树的新叶子节点添加进来
475
515
  const mergedList = [...otherTreeNodes];
476
516
 
477
- // 添加新节点,避免重复
517
+ // 添加新节点,避免重复(基于source+id组合判断)
518
+ const validNewNodes = [];
478
519
  newLeafNodes.forEach((node) => {
479
- if (!mergedList.some((item) => item.id === node.id)) {
480
- mergedList.push(node);
520
+ if (!mergedList.some((item) => item.id === node.id && item.source === node.source)) {
521
+ validNewNodes.push(node);
481
522
  }
482
523
  });
483
-
524
+ // 检查 volte 用户数量限制(限制volte用户总数,不限于当前标签页)
525
+ const currentVolteCount = mergedList.filter(user => user.source === 'volte').length;
526
+ const newVolteNodes = validNewNodes.filter(node => node.source === 'volte');
527
+
528
+ if (currentVolteCount + newVolteNodes.length > 10) {
529
+ // 超出限制,需要处理
530
+ if (this.activeTab === 'volte') {
531
+ // 如果当前在volte标签页,清空当前树的选中状态并提示
532
+ this.$refs.volteTreeRef && this.$refs.volteTreeRef.setCheckedKeys([]);
533
+ this.showMessage.message('warning', '单次VoLTE呼叫仅支持选择10人');
534
+ // 只保留其他树的选中状态,不添加新的volte节点
535
+ this.chosenList = otherTreeNodes;
536
+ return;
537
+ } else {
538
+ // 如果不在volte标签页,只添加非volte节点,并提示volte限制
539
+ const nonVolteNodes = validNewNodes.filter(node => node.source !== 'volte');
540
+ if (newVolteNodes.length > 0) {
541
+ this.showMessage.message('warning', '单次VoLTE呼叫仅支持选择10人,VoLTE用户未添加');
542
+ }
543
+ mergedList.push(...nonVolteNodes);
544
+ this.chosenList = mergedList;
545
+ return;
546
+ }
547
+ }
548
+ // 添加所有有效的新节点
549
+ mergedList.push(...validNewNodes);
484
550
  this.chosenList = mergedList;
485
551
  },
486
552
 
@@ -491,6 +557,8 @@ export default {
491
557
  this.$refs.orgTreeRef.setCheckedKeys([]);
492
558
  } else if (this.activeTab === "人员" && this.$refs.appTreeRef) {
493
559
  this.$refs.appTreeRef.setCheckedKeys([]);
560
+ } else if (this.activeTab === "volte" && this.$refs.volteTreeRef) {
561
+ this.$refs.volteTreeRef.setCheckedKeys([]);
494
562
  } else if (this.activeTab === "常用分组" && this.$refs.groupTreeRef) {
495
563
  this.$refs.groupTreeRef.setCheckedKeys([]);
496
564
  } else if (this.activeTab === "设备" && this.$refs.equipmentTreeRef) {
@@ -500,7 +568,7 @@ export default {
500
568
  }
501
569
 
502
570
  // 然后根据chosenList设置选中状态
503
- const selectedIds = this.chosenList.map((user) => user.id);
571
+ const selectedIds = this.chosenList.filter(user => user.source === this.activeTab).map((user) => user.id);
504
572
 
505
573
  if (this.activeTab === "组织架构" && this.$refs.orgTreeRef) {
506
574
  selectedIds.forEach((id) => {
@@ -510,6 +578,10 @@ export default {
510
578
  selectedIds.forEach((id) => {
511
579
  this.$refs.appTreeRef.setChecked(id, true, false);
512
580
  });
581
+ } else if (this.activeTab === "volte" && this.$refs.volteTreeRef) {
582
+ selectedIds.forEach((id) => {
583
+ this.$refs.volteTreeRef.setChecked(id, true, false);
584
+ });
513
585
  } else if (this.activeTab === "常用分组" && this.$refs.groupTreeRef) {
514
586
  selectedIds.forEach((id) => {
515
587
  this.$refs.groupTreeRef.setChecked(id, true, false);
@@ -541,17 +613,40 @@ export default {
541
613
 
542
614
  // 根据邀请列表项类型获取图标类名
543
615
  getInviteItemIconClass(item) {
544
- if (item.source !== '设备' && item.source !== '监控') return 'custom-item-icon-person';
545
- return item.source === '设备' ? 'custom-item-icon-device' : 'custom-item-icon-monitor';
616
+ if (item.source !== '设备' && item.source !== '监控' && item.source !== 'volte') return 'custom-item-icon-person';
617
+ if (item.source === '设备') return 'custom-item-icon-device';
618
+ if (item.source === '监控') return 'custom-item-icon-monitor';
619
+ if (item.source === 'volte') return 'custom-item-icon-person'; // volte 使用人员图标
620
+ return 'custom-item-icon-person';
621
+ },
622
+ getChosenItemPlatformClass(item) {
623
+ if(item.source === "组织架构") {
624
+ return 'platform platform-mini'
625
+ } else if(item.source === "人员") {
626
+ return 'platform platform-application'
627
+ } else if(item.source === "常用分组") {
628
+ if(item.original === '组织架构') {
629
+ return 'platform platform-mini'
630
+ } else if(item.original === '人员') {
631
+ return 'platform platform-application'
632
+ } else if(item.original === 'volte') {
633
+ return 'platform platform-volte'
634
+ } else {
635
+ return 'platform platform-unknown'
636
+ }
637
+ } else if(item.source === "volte") {
638
+ return 'platform platform-volte'
639
+ } else {
640
+ return 'platform platform-unknown'
641
+ }
546
642
  },
547
-
548
643
  getinvitation() {
549
644
  this.$refs.inviteNonContactDialogRef.open();
550
645
  },
551
646
 
552
647
  addOutterContactToChosenList(outterContact) {
553
- // 检查是否已存在
554
- if (this.tempInviteList.find((item) => item.id === outterContact.id)) {
648
+ // 改进的存在性检查:结合source和手机号进行查找
649
+ if (this.tempInviteList.find((item) => item.phone === outterContact.phone && item.source === outterContact.source)) {
555
650
  this.showMessage.message("error", "该人员已存在");
556
651
  return;
557
652
  }
@@ -612,13 +707,13 @@ export default {
612
707
  },
613
708
 
614
709
  removeInviteItem(item) {
615
- const index = this.tempInviteList.findIndex((user) => user.id === item.id);
710
+ const index = this.tempInviteList.findIndex((user) => user.id === item.id && user.source === item.source);
616
711
  if (index !== -1) {
617
712
  this.isSyncing = true;
618
713
  this.tempInviteList.splice(index, 1);
619
714
 
620
715
  // 同步到chosenList
621
- const chosenIndex = this.chosenList.findIndex((user) => user.id === item.id);
716
+ const chosenIndex = this.chosenList.findIndex((user) => user.id === item.id && user.source === item.source);
622
717
  if (chosenIndex !== -1) {
623
718
  this.chosenList.splice(chosenIndex, 1);
624
719
  }
@@ -639,6 +734,9 @@ export default {
639
734
  if (this.$refs.monitorTreeRef) {
640
735
  this.$refs.monitorTreeRef.setChecked(item.id, false);
641
736
  }
737
+ if( this.$refs.volteTreeRef) {
738
+ this.$refs.volteTreeRef.setChecked(item.id, false);
739
+ }
642
740
  this.$nextTick(() => {
643
741
  this.isSyncing = false;
644
742
  });
@@ -1055,6 +1153,18 @@ export default {
1055
1153
  100%;
1056
1154
  }
1057
1155
  }
1156
+ .platform {
1157
+ display: none;
1158
+ width: 16px;
1159
+ height: 16px;
1160
+ margin-left: 5px;
1161
+ &-mini {
1162
+ background: url("../../assets/image/common/platform_mini_icon.png") no-repeat center / 100% 100%;
1163
+ }
1164
+ &-volte {
1165
+ background: url("../../assets/image/common/platform_volte_icon.png") no-repeat center / 100% 100%;
1166
+ }
1167
+ }
1058
1168
  }
1059
1169
 
1060
1170
  .close {
@@ -1063,6 +1173,16 @@ export default {
1063
1173
  height: 16px;
1064
1174
  background: var(--close-icon) no-repeat center / 100% 100%;
1065
1175
  }
1176
+
1177
+ &:hover {
1178
+ .platform {
1179
+ display: inline-block;
1180
+ &-unknown,
1181
+ &-application {
1182
+ display: none;
1183
+ }
1184
+ }
1185
+ }
1066
1186
  }
1067
1187
  }
1068
1188
  }
@@ -81,7 +81,8 @@ export default {
81
81
  userID: item.id,
82
82
  userName: item.label,
83
83
  phone: item.phone,
84
- loginCode: item?.loginCode ? item.loginCode : ""
84
+ loginCode: item?.loginCode ? item.loginCode : "",
85
+ source: item.source,
85
86
  }
86
87
  }),
87
88
  }, {
@@ -97,6 +97,7 @@ export default {
97
97
  avatar: item?.avatar ?? "",
98
98
  phone: item.phone,
99
99
  loginCode: item?.loginCode ? item.loginCode : "",
100
+ source: item.original ?? ""
100
101
  }
101
102
  });
102
103
  }
@@ -134,6 +135,7 @@ export default {
134
135
  userName: item.label,
135
136
  phone: item.phone,
136
137
  loginCode: item?.loginCode ? item.loginCode : "",
138
+ source: item.source,
137
139
  }
138
140
  })
139
141
  }, {
@@ -23,6 +23,7 @@
23
23
  <span class="name">{{ item.name }}</span>
24
24
  <span class="host" v-if="item.metadata?.isOwner">主持人</span>
25
25
  <span class="host-co" v-else-if="item.metadata?.isCoHost">联席主持人</span>
26
+ <div :class="getPlatformClass(item.metadata?.platformID)"></div>
26
27
  </div>
27
28
  <div class="member-list-item-group">
28
29
  <div
@@ -70,6 +71,7 @@
70
71
  <span class="name">{{ item.userName }}</span>
71
72
  <span class="host" v-if="item.metadata?.isOwner">主持人</span>
72
73
  <span class="host-co" v-else-if="item.metadata?.isCoHost">联席主持人</span>
74
+ <div :class="getPlatformClass(item?.platformID)"></div>
73
75
  </div>
74
76
  <div class="member-list-item-group">
75
77
  <div class="text-btn text-btn-remove" @click="removeUnjoinItem(item)">移除</div>
@@ -177,7 +179,31 @@ export default {
177
179
  return false;
178
180
  }
179
181
  },
180
-
182
+ // 根据平台ID获取对应的图标样式
183
+ getPlatformClass(platformID) {
184
+ let className = "";
185
+ switch (platformID) {
186
+ case 0:
187
+ className = "platform platform-pc";
188
+ break;
189
+ case 1:
190
+ className = "platform platform-app";
191
+ break;
192
+ case 4:
193
+ className = "platform platform-volte";
194
+ break;
195
+ case 7:
196
+ className = "platform platform-mini";
197
+ break;
198
+ case 30:
199
+ className = "platform platform-application";
200
+ break;
201
+ default:
202
+ className = "platform platform-unknown";
203
+ break;
204
+ }
205
+ return className;
206
+ },
181
207
  switchMemberCameraStatus(identity, isMute) {
182
208
  this.$emit("participantCameraSwitch", {
183
209
  identity,
@@ -399,6 +425,28 @@ export default {
399
425
  border: 1px solid #0CFE3D;
400
426
  }
401
427
  }
428
+ .platform {
429
+ width: 20px;
430
+ height: 20px;
431
+ margin-left: 8px;
432
+ display: none;
433
+ &-pc {
434
+ background: url("../../assets/image/common/platform_pc_icon.png") no-repeat center /
435
+ 100% 100%;
436
+ }
437
+ &-app {
438
+ background: url("../../assets/image/common/platform_app_icon.png") no-repeat center /
439
+ 100% 100%;
440
+ }
441
+ &-volte {
442
+ background: url("../../assets/image/common/platform_volte_icon.png") no-repeat center /
443
+ 100% 100%;
444
+ }
445
+ &-mini {
446
+ background: url("../../assets/image/common/platform_mini_icon.png") no-repeat center /
447
+ 100% 100%;
448
+ }
449
+ }
402
450
  .icon-btn {
403
451
  width: 16px;
404
452
  height: 16px;
@@ -425,9 +473,9 @@ export default {
425
473
  }
426
474
  }
427
475
  .text-btn {
428
- width: 80px;
429
- height: 32px;
430
- line-height: 32px;
476
+ width: 60px;
477
+ height: 28px;
478
+ line-height: 28px;
431
479
  text-align: center;
432
480
  border-radius: 8px;
433
481
  cursor: pointer;
@@ -445,6 +493,15 @@ export default {
445
493
  color: #ffffff;
446
494
  }
447
495
  }
496
+ &:hover {
497
+ .platform {
498
+ display: block;
499
+ &-application,
500
+ &-unkown {
501
+ display: none;
502
+ }
503
+ }
504
+ }
448
505
  }
449
506
  }
450
507
  &-expand {
package/src/main.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import Vue from 'vue'
2
2
  import App from './App.vue'
3
3
  // 测试
4
- // import liveComponent from '../index'
4
+ import liveComponent from '../index'
5
5
  // npm
6
- import MDMClient from "mdm-client"
6
+ // import MDMClient from "mdm-client"
7
7
  import ElementUI from 'element-ui'
8
8
  import 'element-ui/lib/theme-chalk/index.css';
9
9
 
@@ -11,9 +11,9 @@ import 'element-ui/lib/theme-chalk/index.css';
11
11
  Vue.config.productionTip = false
12
12
  Vue.use(ElementUI)
13
13
  // 测试
14
- // Vue.use(liveComponent)
14
+ Vue.use(liveComponent)
15
15
  // npm
16
- Vue.use(MDMClient)
16
+ // Vue.use(MDMClient)
17
17
 
18
18
 
19
19
  new Vue({
package/src/utils/api.js CHANGED
@@ -80,3 +80,12 @@ export const queryMonitorAddressBook = (params = {}, { baseUrl, token } = {}) =>
80
80
  },
81
81
  });
82
82
  };
83
+ // 获取volte用户树
84
+ export const getVolteAddressBook = (params = {}, { baseUrl, token } = {}) => {
85
+ return http.post("/api/v1/meeting/queryVolteAddressBook", params, {
86
+ baseURL: baseUrl,
87
+ headers: {
88
+ satoken: token,
89
+ },
90
+ });
91
+ }