hookehuyr

完善功能

Showing 1 changed file with 247 additions and 87 deletions
...@@ -240,27 +240,24 @@ ...@@ -240,27 +240,24 @@
240 </div> 240 </div>
241 </div> 241 </div>
242 </div> 242 </div>
243 - <div 243 + <div class="flow-tab-search" @click="activeSearchBtn">
244 - class="flow-tab-search"
245 - @click="state.is_active_search = !state.is_active_search"
246 - >
247 <el-icon :size="15"><Search /></el-icon> &nbsp;搜索框 244 <el-icon :size="15"><Search /></el-icon> &nbsp;搜索框
248 </div> 245 </div>
249 </div> 246 </div>
250 <div v-else> 247 <div v-else>
251 <el-input 248 <el-input
252 v-model="state.search_input" 249 v-model="state.search_input"
253 - class="w-50 m-2" 250 + class="search-btn-wrapper"
254 placeholder="请输入关键字" 251 placeholder="请输入关键字"
255 > 252 >
256 <template #prefix> 253 <template #prefix>
257 <el-icon class="el-input__icon"><search /></el-icon> 254 <el-icon class="el-input__icon"><search /></el-icon>
258 </template> 255 </template>
259 <template #append> 256 <template #append>
260 - <el-button 257 + <div class="search-group">
261 - @click="state.is_active_search = !state.is_active_search" 258 + <div class="confirm-btn" @click="onSearch">搜索</div>
262 - >取消</el-button 259 + <div class="cancel-btn" @click="onClearSearch">取消</div>
263 - > 260 + </div>
264 </template> 261 </template>
265 </el-input> 262 </el-input>
266 </div> 263 </div>
...@@ -292,6 +289,7 @@ ...@@ -292,6 +289,7 @@
292 :key="idx" 289 :key="idx"
293 :label="user.id" 290 :label="user.id"
294 :disabled="user.disabled" 291 :disabled="user.disabled"
292 + @change="handleCheckedUserListChange(user, $event)"
295 >{{ user.label }}</el-checkbox 293 >{{ user.label }}</el-checkbox
296 > 294 >
297 </el-checkbox-group> 295 </el-checkbox-group>
...@@ -307,7 +305,11 @@ ...@@ -307,7 +305,11 @@
307 v-model="activeTabContent" 305 v-model="activeTabContent"
308 @tab-click="handleTabContentClick" 306 @tab-click="handleTabContentClick"
309 > 307 >
310 - <el-tab-pane v-for="(role, idx) in item.data" :key="idx" :label="role.label"> 308 + <el-tab-pane
309 + v-for="(role, idx) in item.data"
310 + :key="idx"
311 + :label="role.label"
312 + >
311 <el-checkbox-group 313 <el-checkbox-group
312 class="flow-checkbox-group" 314 class="flow-checkbox-group"
313 v-model="state.checkedUserList" 315 v-model="state.checkedUserList"
...@@ -317,6 +319,7 @@ ...@@ -317,6 +319,7 @@
317 :key="idx" 319 :key="idx"
318 :label="user.id" 320 :label="user.id"
319 :disabled="user.disabled" 321 :disabled="user.disabled"
322 + @change="handleCheckedUserListChange(user, $event)"
320 >{{ user.label }}</el-checkbox 323 >{{ user.label }}</el-checkbox
321 > 324 >
322 </el-checkbox-group> 325 </el-checkbox-group>
...@@ -330,13 +333,16 @@ ...@@ -330,13 +333,16 @@
330 <el-checkbox-group 333 <el-checkbox-group
331 class="flow-checkbox-group" 334 class="flow-checkbox-group"
332 style="padding-left: 10px;" 335 style="padding-left: 10px;"
333 - v-model="state.searchUserList" 336 + v-model="state.checkedSearchUserList"
337 + >
338 + <el-checkbox
339 + v-for="(user, idx) in state.searchUserList"
340 + :key="idx"
341 + :label="user.id"
342 + :disabled="user.disabled"
343 + @change="handleCheckedUserListChange(user, $event)"
344 + >{{ user.label }}</el-checkbox
334 > 345 >
335 - <el-checkbox label="1">选项 A</el-checkbox>
336 - <el-checkbox label="2">选项 B</el-checkbox>
337 - <el-checkbox label="3">选项 C</el-checkbox>
338 - <el-checkbox label="4" disabled>禁用</el-checkbox>
339 - <el-checkbox label="5" disabled>选中和禁用</el-checkbox>
340 </el-checkbox-group> 346 </el-checkbox-group>
341 </div> 347 </div>
342 </div> 348 </div>
...@@ -458,12 +464,7 @@ export default { ...@@ -458,12 +464,7 @@ export default {
458 } 464 }
459 } 465 }
460 ], 466 ],
461 - userTags: [ 467 + userTags: [],
462 - { name: "成员1", id: "1" },
463 - { name: "成员2", id: "2" },
464 - { name: "成员3", id: "3" },
465 - { name: "成员4", id: "4" }
466 - ],
467 activeTabId: "tab-1", // TODO: 需要获取默认第一个ID 468 activeTabId: "tab-1", // TODO: 需要获取默认第一个ID
468 userTabs: [ 469 userTabs: [
469 { 470 {
...@@ -548,13 +549,13 @@ export default { ...@@ -548,13 +549,13 @@ export default {
548 { 549 {
549 id: "role-1-2", 550 id: "role-1-2",
550 label: "选项 A", 551 label: "选项 A",
551 - checked: true, 552 + checked: false,
552 disabled: false 553 disabled: false
553 }, 554 },
554 { 555 {
555 id: "role-1-3", 556 id: "role-1-3",
556 label: "选项 B", 557 label: "选项 B",
557 - checked: false, 558 + checked: true,
558 disabled: false 559 disabled: false
559 }, 560 },
560 { 561 {
...@@ -564,21 +565,24 @@ export default { ...@@ -564,21 +565,24 @@ export default {
564 disabled: true 565 disabled: true
565 } 566 }
566 ] 567 ]
567 - }, { 568 + },
569 + {
568 id: "role-1-2", 570 id: "role-1-2",
569 label: "成员字段", 571 label: "成员字段",
570 children: [], 572 children: [],
571 - list: [], 573 + list: []
572 - }, { 574 + },
575 + {
573 id: "role-1-3", 576 id: "role-1-3",
574 label: "部门字段", 577 label: "部门字段",
575 children: [], 578 children: [],
576 - list: [], 579 + list: []
577 - }, { 580 + },
581 + {
578 id: "role-1-4", 582 id: "role-1-4",
579 label: "主管", 583 label: "主管",
580 children: [], 584 children: [],
581 - list: [], 585 + list: []
582 } 586 }
583 ] 587 ]
584 } 588 }
...@@ -591,51 +595,8 @@ export default { ...@@ -591,51 +595,8 @@ export default {
591 search_input: "", 595 search_input: "",
592 userList: [], 596 userList: [],
593 checkedUserList: [], 597 checkedUserList: [],
594 - checkedDeptUserList: [], // 选中部门用户ID
595 - deptUserList: [
596 - {
597 - id: "dept-1",
598 - label: "部门1",
599 - checked: false,
600 - disabled: false
601 - },
602 - {
603 - id: "dept-2",
604 - label: "部门2",
605 - checked: false,
606 - disabled: false
607 - },
608 - {
609 - id: "dept-3",
610 - label: "部门3",
611 - checked: false,
612 - disabled: true
613 - }
614 - ], // 组织架构框 选中 用户ID
615 - checkedRoleUserList: [], // 选中角色用户ID
616 - roleUserList: [], // 角色框 选中 用户ID
617 searchUserList: [], // 搜索框 选中 用户ID 598 searchUserList: [], // 搜索框 选中 用户ID
618 - userGroup: [], // 待选用户列表 599 + checkedSearchUserList: [],
619 - tree_data: [
620 - {
621 - label: "上级部门 1",
622 - children: [
623 - {
624 - label: "部门名称 1-1",
625 - children: []
626 - }
627 - ]
628 - },
629 - {
630 - label: "上级部门 2",
631 - children: [
632 - {
633 - label: "部门名称 2-1",
634 - children: []
635 - }
636 - ]
637 - }
638 - ],
639 defaultProps: { 600 defaultProps: {
640 children: "children", 601 children: "children",
641 label: "label" 602 label: "label"
...@@ -670,7 +631,7 @@ export default { ...@@ -670,7 +631,7 @@ export default {
670 state.tabSelectData = tab.data; // tab选中数据提供给list类型使用 631 state.tabSelectData = tab.data; // tab选中数据提供给list类型使用
671 state.userList = []; // 清空用户列表 632 state.userList = []; // 清空用户列表
672 state.checkedUserList = []; // 清空选中用户列表 633 state.checkedUserList = []; // 清空选中用户列表
673 - console.log(tab, event); 634 + // console.log(tab, event);
674 // 设置当前激活的tab 635 // 设置当前激活的tab
675 state.userTabType = tab.type; 636 state.userTabType = tab.type;
676 state.activeTabId = tab.id; 637 state.activeTabId = tab.id;
...@@ -686,45 +647,145 @@ export default { ...@@ -686,45 +647,145 @@ export default {
686 if (tab?.data[0]?.list) { 647 if (tab?.data[0]?.list) {
687 let list = tab.data[0].list; 648 let list = tab.data[0].list;
688 state.userList = list; 649 state.userList = list;
689 - state.checkedUserList = list.filter(ele => { 650 + state.checkedUserList = list
651 + .filter(ele => {
690 return ele.checked; 652 return ele.checked;
691 - }).map(ele => { 653 + })
654 + .map(ele => {
692 return ele.id; 655 return ele.id;
693 }); 656 });
694 } 657 }
695 }; 658 };
696 659
697 - const handleTabContentClick = (tab, event) => { // 侧边栏Tab点击回调 660 + const handleTabContentClick = (tab, event) => {
661 + // 侧边栏Tab点击回调
698 // console.log(event); 662 // console.log(event);
699 state.tabSelectData.forEach(ele => { 663 state.tabSelectData.forEach(ele => {
700 if (ele.label === tab.props.label) { 664 if (ele.label === tab.props.label) {
701 state.userList = ele.list; 665 state.userList = ele.list;
702 - state.checkedUserList = ele.list.filter(ele => { 666 + state.checkedUserList = ele.list
667 + .filter(ele => {
703 return ele.checked; 668 return ele.checked;
704 - }).map(ele => { 669 + })
670 + .map(ele => {
705 return ele.id; 671 return ele.id;
706 }); 672 });
707 } 673 }
708 - }) 674 + });
709 }; 675 };
710 676
711 const handleNodeClick = data => { 677 const handleNodeClick = data => {
712 - console.log(data); 678 + // console.log(data);
713 if (data.list) { 679 if (data.list) {
714 state.userList = data.list; 680 state.userList = data.list;
715 - state.checkedUserList = data.list.filter(ele => { 681 + state.checkedUserList = data.list
682 + .filter(ele => {
716 return ele.checked; 683 return ele.checked;
717 - }).map(ele => { 684 + })
685 + .map(ele => {
718 return ele.id; 686 return ele.id;
719 }); 687 });
720 - console.warn(state.checkedUserList); 688 + // console.warn(state.checkedUserList);
689 + }
690 + };
691 +
692 + function modifyFieldValue(obj, fieldName, targetValue, newValue) {
693 + // 遍历相应ID修改选中值
694 + // 检查当前层级的字段值是否匹配目标值
695 + if (obj[fieldName] === targetValue) {
696 + obj["checked"] = newValue;
697 + }
698 +
699 + // 遍历当前层级的子项(如果有)
700 + for (var key in obj) {
701 + if (typeof obj[key] === "object" && obj[key] !== null) {
702 + modifyFieldValue(obj[key], fieldName, targetValue, newValue);
703 + }
704 + }
721 } 705 }
706 +
707 + const handleCheckedUserListChange = (user, checked) => {
708 + // 勾选用户回调
709 + // 修改选中值状态
710 + modifyFieldValue(state.userTabs, "id", user.id, checked);
711 + };
712 +
713 + function getAllListItems(arr) {
714 + // 遍历递归获取list下面的数据
715 + var result = [];
716 +
717 + function recursiveGetListItems(subArr) {
718 + for (var i = 0; i < subArr.length; i++) {
719 + var item = subArr[i];
720 + if (item.list && Array.isArray(item.list)) {
721 + result = result.concat(item.list);
722 + }
723 + if (item.children && Array.isArray(item.children)) {
724 + recursiveGetListItems(item.children);
725 + }
726 + }
727 + }
728 +
729 + recursiveGetListItems(arr);
730 + return result;
731 + }
732 +
733 + const setTagsList = val => {
734 + let userList = [];
735 + val.forEach(ele => {
736 + let data = getAllListItems(ele.data);
737 + userList.push(data);
738 + });
739 + // 合并成一维数组列表
740 + userList = [...userList.flat()];
741 + // 勾选变化后同步到选中列表
742 + state.userTags = userList
743 + .filter(ele => {
744 + return ele.checked;
745 + })
746 + .map(ele => {
747 + return {
748 + id: ele.id,
749 + name: ele.label
750 + };
751 + });
722 }; 752 };
723 753
754 + // 监听数据结构选中值变化
755 + watch(
756 + () => state.userTabs,
757 + val => {
758 + if (val) {
759 + // 设置tag选中列表
760 + setTagsList(val);
761 + }
762 + },
763 + { deep: true }
764 + );
765 +
724 const handleTagClose = tag => { 766 const handleTagClose = tag => {
725 // 移除成员标签回调 767 // 移除成员标签回调
726 - state.userTags.splice(state.userTags.indexOf(tag), 1); 768 + state.userTags.splice(state.userTags.indexOf(tag), 1); // 删除标签列表中的项
727 - console.log(tag); 769 + // 移除数据结构中的选中值
770 + modifyFieldValue(state.userTabs, "id", tag.id, false);
771 + //
772 + let tagsId = state.userTags.map(ele => {
773 + return ele.id;
774 + });
775 + // console.warn(tagsId);
776 + // 获取tags中已删除的, 勾选列表中还勾选的值
777 + let result = state.checkedUserList.filter(
778 + value => !tagsId.includes(value)
779 + );
780 + // 选中列表中不存在勾选列表中项时,需要删除勾选列表中的项
781 + if (result.length) {
782 + result.forEach(ele => {
783 + state.checkedUserList.splice(state.checkedUserList.indexOf(ele), 1);
784 + });
785 + }
786 + // console.log(result);
787 + // console.log(state.userTags);
788 + // console.log(state.checkedUserList);
728 }; 789 };
729 790
730 const closeUserForm = () => { 791 const closeUserForm = () => {
...@@ -737,6 +798,74 @@ export default { ...@@ -737,6 +798,74 @@ export default {
737 console.log(state.userTags); 798 console.log(state.userTags);
738 }; 799 };
739 800
801 + const activeSearchBtn = () => {
802 + state.is_active_search = !state.is_active_search;
803 + state.searchUserList = [];
804 + };
805 +
806 + const checkSearchStatus = () => {
807 + // 在搜索框中同步显示tag框选中的用户
808 + state.userTags.forEach(ele => {
809 + state.searchUserList.forEach(item => {
810 + if (ele.id === item.id) {
811 + item.checked = true;
812 + }
813 + });
814 + });
815 + // 显示选中tags的用户
816 + state.checkedSearchUserList = state.searchUserList
817 + .filter(ele => ele.checked)
818 + .map(ele => ele.id);
819 + };
820 +
821 + const onClearSearch = () => {
822 + // 清空搜索回调
823 + state.is_active_search = !state.is_active_search;
824 + };
825 + const onSearch = () => {
826 + // 搜索回调
827 + state.searchUserList = [
828 + {
829 + id: "user-1-1",
830 + label: "用户1-1",
831 + checked: true,
832 + disabled: false
833 + },
834 + {
835 + id: "user-1-2",
836 + label: "用户1-2",
837 + checked: false,
838 + disabled: false
839 + },
840 + {
841 + id: "user-1-3",
842 + label: "用户1-3",
843 + checked: false,
844 + disabled: true
845 + },
846 + {
847 + id: "role-1-2",
848 + label: "选项 A",
849 + checked: false,
850 + disabled: false
851 + },
852 + {
853 + id: "role-1-3",
854 + label: "选项 B",
855 + checked: true,
856 + disabled: false
857 + },
858 + {
859 + id: "role-1-4",
860 + label: "选项 C",
861 + checked: false,
862 + disabled: true
863 + }
864 + ];
865 + // console.log(state.userTags);
866 + checkSearchStatus();
867 + };
868 +
740 onMounted(() => { 869 onMounted(() => {
741 // // 显示提示框的标志位 870 // // 显示提示框的标志位
742 // var showConfirmation = true; 871 // var showConfirmation = true;
...@@ -763,6 +892,8 @@ export default { ...@@ -763,6 +892,8 @@ export default {
763 // console.warn(res.data); 892 // console.warn(res.data);
764 // }); 893 // });
765 // $('.el-tabs__nav') 894 // $('.el-tabs__nav')
895 + // 根据数据获取选中的tag标签
896 + setTagsList(state.userTabs);
766 }); 897 });
767 898
768 watch( 899 watch(
...@@ -910,6 +1041,10 @@ export default { ...@@ -910,6 +1041,10 @@ export default {
910 handleTagClose, 1041 handleTagClose,
911 closeUserForm, 1042 closeUserForm,
912 confirmUserForm, 1043 confirmUserForm,
1044 + handleCheckedUserListChange,
1045 + onSearch,
1046 + onClearSearch,
1047 + activeSearchBtn,
913 1048
914 logData, 1049 logData,
915 1050
...@@ -1037,4 +1172,29 @@ body { ...@@ -1037,4 +1172,29 @@ body {
1037 display: flex !important; 1172 display: flex !important;
1038 } 1173 }
1039 } 1174 }
1175 +
1176 +.search-btn-wrapper {
1177 + .el-input-group__append {
1178 + width: 100px !important;
1179 + padding: 0 !important;
1180 + }
1181 + .search-group {
1182 + display: flex;
1183 + text-align: center;
1184 + .confirm-btn {
1185 + width: 50px;
1186 + color: #fff;
1187 + background-color: #409eff;
1188 + &:hover {
1189 + cursor: pointer;
1190 + }
1191 + }
1192 + .cancel-btn {
1193 + width: 50px;
1194 + &:hover {
1195 + cursor: pointer;
1196 + }
1197 + }
1198 + }
1199 +}
1040 </style> 1200 </style>
......