Showing
1 changed file
with
84 additions
and
18 deletions
| 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,11 +601,13 @@ const getDeptTreeData = () => { // 获取组织结构数据 | ... | @@ -569,11 +601,13 @@ 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') { |
| 605 | + if (treeCheckedCount.value) { | ||
| 573 | showToast('单选模式下,只能勾选一个') | 606 | showToast('单选模式下,只能勾选一个') |
| 574 | // 移除树结构选中的项 | 607 | // 移除树结构选中的项 |
| 575 | deptTreeRef.value?.setChecked(node.id, false); | 608 | deptTreeRef.value?.setChecked(node.id, false); |
| 576 | } | 609 | } |
| 610 | + } | ||
| 577 | } | 611 | } |
| 578 | 612 | ||
| 579 | const deptTreeUncheck = (node) => { // 组织结构单选取消 | 613 | const deptTreeUncheck = (node) => { // 组织结构单选取消 |
| ... | @@ -593,9 +627,11 @@ const treeCheckedCount = computed(() => { // 选中框的数量是否大于一 | ... | @@ -593,9 +627,11 @@ 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') { |
| 631 | + if (treeCheckedCount.value) { | ||
| 597 | return false | 632 | return false |
| 598 | } | 633 | } |
| 634 | + } | ||
| 599 | 635 | ||
| 600 | checkedGroup.value.dept = arr.map((item) => { | 636 | checkedGroup.value.dept = arr.map((item) => { |
| 601 | return { | 637 | return { |
| ... | @@ -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 | /************* 成员模块 ***************/ | ... | ... |
-
Please register or login to post a comment