hookehuyr

单选模式下,角色列表的控制

1 <!-- 1 <!--
2 * @Date: 2022-08-29 14:31:20 2 * @Date: 2022-08-29 14:31:20
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2024-08-05 14:40:59 4 + * @LastEditTime: 2024-08-05 16:53:52
5 * @FilePath: /data-table/src/components/OrgPickerField/MyComponent.vue 5 * @FilePath: /data-table/src/components/OrgPickerField/MyComponent.vue
6 * @Description: 树形组件 6 * @Description: 树形组件
7 --> 7 -->
...@@ -89,6 +89,7 @@ ...@@ -89,6 +89,7 @@
89 :showFooter="false" 89 :showFooter="false"
90 :cascade="false" 90 :cascade="false"
91 :defaultExpandAll="false" 91 :defaultExpandAll="false"
92 + :disableAll="deptTreeDisableAll"
92 @check="deptTreeCheck" 93 @check="deptTreeCheck"
93 @uncheck="deptTreeUncheck" 94 @uncheck="deptTreeUncheck"
94 @checked-change="deptTreeCheckedChange" 95 @checked-change="deptTreeCheckedChange"
...@@ -98,19 +99,22 @@ ...@@ -98,19 +99,22 @@
98 </Vtree> 99 </Vtree>
99 </div> 100 </div>
100 101
101 - <div v-if="tabActive === 1" style="padding: 0 0 0 1rem; overflow: scroll; height: 60vh;"> 102 + <div v-if="tabActive === 1" style="padding: 0 0 0 1rem; overflow: scroll; height: 60vh;" @click.stop>
102 <van-checkbox-group 103 <van-checkbox-group
103 v-model="role_checked" 104 v-model="role_checked"
104 @change="roleChangeMethod" 105 @change="roleChangeMethod"
105 > 106 >
106 <van-checkbox 107 <van-checkbox
107 v-for="(role, index) in roleList" 108 v-for="(role, index) in roleList"
109 + :id="role.id"
108 :key="index" 110 :key="index"
109 :name="role.id" 111 :name="role.id"
110 shape="square" 112 shape="square"
111 icon-size="13px" 113 icon-size="13px"
112 :checked-color="styleColor.baseColor" 114 :checked-color="styleColor.baseColor"
115 + :disabled="role.disabled"
113 style="margin-bottom: 0.5rem;" 116 style="margin-bottom: 0.5rem;"
117 + @click="onRoleClick(role, $event)"
114 >{{ role.name }}</van-checkbox> 118 >{{ role.name }}</van-checkbox>
115 </van-checkbox-group> 119 </van-checkbox-group>
116 <div style="height: 10vh;"></div> 120 <div style="height: 10vh;"></div>
...@@ -278,19 +282,6 @@ let role_list = []; ...@@ -278,19 +282,6 @@ let role_list = [];
278 let dept_list = []; 282 let dept_list = [];
279 283
280 let check_type = ref(''); // 单选/多选模式 284 let check_type = ref(''); // 单选/多选模式
281 -const validateGroupObject = (obj) => {
282 - let flag = false;
283 -
284 - // 获取有值的数组属性
285 - const nonEmptyArrays = [...obj.dept, ...obj.user, ...obj.role];
286 -
287 - // 确保只有一个数组属性有值
288 - if (nonEmptyArrays.length > 1) {
289 - flag = true;
290 - }
291 -
292 - return flag
293 -}
294 285
295 // 处理Tab显示问题 286 // 处理Tab显示问题
296 const tree_tabs = ['dept', 'role', 'user']; 287 const tree_tabs = ['dept', 'role', 'user'];
...@@ -359,7 +350,9 @@ const openTree = () => { ...@@ -359,7 +350,9 @@ const openTree = () => {
359 showPopover.value = true; 350 showPopover.value = true;
360 // 获取数据 351 // 获取数据
361 nextTick(() => { 352 nextTick(() => {
362 - getDeptTreeData(); 353 + // 动态判断点击显示的tab,默认点击第一个
354 + onClickTab({ title: tabList.value[0]['title'] })
355 + // getDeptTreeData();
363 // 获取已选择的数据 356 // 获取已选择的数据
364 checkedGroup.value = _.cloneDeep(emitCheckedGroup.value); 357 checkedGroup.value = _.cloneDeep(emitCheckedGroup.value);
365 syncResultToList(); // 同步勾选状态 358 syncResultToList(); // 同步勾选状态
...@@ -485,6 +478,15 @@ const checkedGroup = ref({ ...@@ -485,6 +478,15 @@ const checkedGroup = ref({
485 user: [] // 成员 478 user: [] // 成员
486 }); 479 });
487 480
481 +const resetRoleDisabled = () => {
482 + // 如果角色没有选中,解除禁用
483 + if (!role_checked.value.length) {
484 + roleList.value.forEach(item => {
485 + item.disabled = false;
486 + });
487 + }
488 +}
489 +
488 const onRemoveDeptTag = (dept) => { // 移除部门标签 490 const onRemoveDeptTag = (dept) => { // 移除部门标签
489 // 移除选中框显示 491 // 移除选中框显示
490 const index = checkedGroup.value.dept.findIndex(item => JSON.stringify(item) === JSON.stringify(dept)); 492 const index = checkedGroup.value.dept.findIndex(item => JSON.stringify(item) === JSON.stringify(dept));
...@@ -494,6 +496,10 @@ const onRemoveDeptTag = (dept) => { // 移除部门标签 ...@@ -494,6 +496,10 @@ const onRemoveDeptTag = (dept) => { // 移除部门标签
494 // 移除搜索结果选中显示 496 // 移除搜索结果选中显示
495 const idx = search_result_checked.value.findIndex(item => JSON.stringify(item) === JSON.stringify(dept)); 497 const idx = search_result_checked.value.findIndex(item => JSON.stringify(item) === JSON.stringify(dept));
496 search_result_checked.value.splice(idx, 1); 498 search_result_checked.value.splice(idx, 1);
499 + // 单选模式
500 + if (check_type.value === 'single') {
501 + resetRoleDisabled();
502 + }
497 } 503 }
498 504
499 const onRemoveRoleTag = (role) => { // 移除角色标签 505 const onRemoveRoleTag = (role) => { // 移除角色标签
...@@ -505,6 +511,10 @@ const onRemoveRoleTag = (role) => { // 移除角色标签 ...@@ -505,6 +511,10 @@ const onRemoveRoleTag = (role) => { // 移除角色标签
505 // 移除搜索结果选中显示 511 // 移除搜索结果选中显示
506 const i = search_result_checked.value.findIndex(item => JSON.stringify(item) === JSON.stringify(role)); 512 const i = search_result_checked.value.findIndex(item => JSON.stringify(item) === JSON.stringify(role));
507 search_result_checked.value.splice(i, 1); 513 search_result_checked.value.splice(i, 1);
514 + // 单选模式
515 + if (check_type.value === 'single') {
516 + resetRoleDisabled();
517 + }
508 } 518 }
509 519
510 const onRemoveUserTag = (user) => { // 移除成员标签 520 const onRemoveUserTag = (user) => { // 移除成员标签
...@@ -516,6 +526,10 @@ const onRemoveUserTag = (user) => { // 移除成员标签 ...@@ -516,6 +526,10 @@ const onRemoveUserTag = (user) => { // 移除成员标签
516 // 移除搜索结果选中显示 526 // 移除搜索结果选中显示
517 const i = search_result_checked.value.findIndex(item => JSON.stringify(item) === JSON.stringify(user)); 527 const i = search_result_checked.value.findIndex(item => JSON.stringify(item) === JSON.stringify(user));
518 search_result_checked.value.splice(i, 1); 528 search_result_checked.value.splice(i, 1);
529 + // 单选模式
530 + if (check_type.value === 'single') {
531 + resetRoleDisabled();
532 + }
519 } 533 }
520 534
521 /*************** Tab 功能模块 ****************/ 535 /*************** Tab 功能模块 ****************/
...@@ -551,6 +565,23 @@ const deptListReset = () => { // 组织重置列表 ...@@ -551,6 +565,23 @@ const deptListReset = () => { // 组织重置列表
551 565
552 const roleListReset = () => { // 角色重置列表 566 const roleListReset = () => { // 角色重置列表
553 roleList.value = dept_list; 567 roleList.value = dept_list;
568 + // 单选模式下,勾选项目操作一个时,角色选项不可勾选
569 + if (check_type.value === 'single') {
570 + if (treeCheckedCount.value) {
571 + roleList.value.forEach(item => {
572 + item.disabled = true;
573 + checkedGroup.value.role.forEach(role => {
574 + if (role.id === item.id) {
575 + item.disabled = false;
576 + }
577 + })
578 + });
579 + } else {
580 + roleList.value.forEach(item => {
581 + item.disabled = false;
582 + })
583 + }
584 + }
554 } 585 }
555 586
556 const userListReset = () => { // 成员重置列表 587 const userListReset = () => { // 成员重置列表
...@@ -561,6 +592,7 @@ const userListReset = () => { // 成员重置列表 ...@@ -561,6 +592,7 @@ const userListReset = () => { // 成员重置列表
561 592
562 /************* 组织结构模块 ***************/ 593 /************* 组织结构模块 ***************/
563 const select_dept_value = ref(); // 组织结构树形选中值 594 const select_dept_value = ref(); // 组织结构树形选中值
595 +const deptTreeDisableAll = ref(false); // 组织结构树形禁用
564 596
565 const getDeptTreeData = () => { // 获取组织结构数据 597 const getDeptTreeData = () => { // 获取组织结构数据
566 deptTreeRef.value.setData(role_list); 598 deptTreeRef.value.setData(role_list);
...@@ -569,10 +601,12 @@ const getDeptTreeData = () => { // 获取组织结构数据 ...@@ -569,10 +601,12 @@ const getDeptTreeData = () => { // 获取组织结构数据
569 } 601 }
570 602
571 const deptTreeCheck = (node) => { // 组织结构单选勾中 603 const deptTreeCheck = (node) => { // 组织结构单选勾中
572 - if (check_type.value === 'single' && treeCheckedCount.value) { 604 + if (check_type.value === 'single') {
573 - showToast('单选模式下,只能勾选一个') 605 + if (treeCheckedCount.value) {
574 - // 移除树结构选中的项 606 + showToast('单选模式下,只能勾选一个')
575 - deptTreeRef.value?.setChecked(node.id, false); 607 + // 移除树结构选中的项
608 + deptTreeRef.value?.setChecked(node.id, false);
609 + }
576 } 610 }
577 } 611 }
578 612
...@@ -593,8 +627,10 @@ const treeCheckedCount = computed(() => { // 选中框的数量是否大于一 ...@@ -593,8 +627,10 @@ const treeCheckedCount = computed(() => { // 选中框的数量是否大于一
593 }); 627 });
594 628
595 const deptTreeCheckedChange = (arr) => { // 组织结构勾选回调 629 const deptTreeCheckedChange = (arr) => { // 组织结构勾选回调
596 - if (check_type.value === 'single' && treeCheckedCount.value) { 630 + if (check_type.value === 'single') {
597 - return false 631 + if (treeCheckedCount.value) {
632 + return false
633 + }
598 } 634 }
599 635
600 checkedGroup.value.dept = arr.map((item) => { 636 checkedGroup.value.dept = arr.map((item) => {
...@@ -612,10 +648,40 @@ const role_checked = ref([]); // 角色多选选中值 ...@@ -612,10 +648,40 @@ const role_checked = ref([]); // 角色多选选中值
612 const roleList = ref([]); 648 const roleList = ref([]);
613 649
614 const roleChangeMethod = (val) => { // 角色多选组点击回调 650 const roleChangeMethod = (val) => { // 角色多选组点击回调
651 + if (check_type.value === 'single') {
652 + if (treeCheckedCount.value) {
653 + return;
654 + }
655 + }
656 +
615 let result = val.map(id => roleList.value.find(obj => obj.id === id)); 657 let result = val.map(id => roleList.value.find(obj => obj.id === id));
616 // 过滤掉未找到的项(即返回undefined的项) 658 // 过滤掉未找到的项(即返回undefined的项)
617 checkedGroup.value.role = result.filter(item => item !== undefined); 659 checkedGroup.value.role = result.filter(item => item !== undefined);
618 } 660 }
661 +
662 +const onRoleClick = (role, evt) => { // 角色单击回调
663 + if (role.disabled) { // 节点禁用时不能操作
664 + showToast('单选模式下,只能勾选一个')
665 + return;
666 + }
667 + if (check_type.value === 'single') {
668 + // 移除选中框显示
669 + const index = checkedGroup.value['role'].findIndex(item => item === role.id);
670 + checkedGroup.value['role'].splice(index, 1);
671 + // 超出选中1个,禁用其他选中
672 + if (!treeCheckedCount.value) {
673 + roleList.value.forEach(item => {
674 + if (item.id === role.id) {
675 + item.disabled = false;
676 + } else {
677 + item.disabled = true;
678 + }
679 + });
680 + }
681 + // 如果没有选中,解除禁用
682 + resetRoleDisabled();
683 + }
684 +}
619 /**************** END *****************/ 685 /**************** END *****************/
620 686
621 /************* 成员模块 ***************/ 687 /************* 成员模块 ***************/
......