Bläddra i källkod

fix: BsUi-选人控件逻辑修改

hanxiaohui 5 månader sedan
förälder
incheckning
ba0a3a1494

+ 8 - 2
src/components/BsUi/OrgUserSelector/components/ModalSelector.vue

@@ -13,7 +13,7 @@
         <div class="cb-content">
           <div class="cb-c-top">
             <div class="tree" v-show="isEmpty(keyWord)">
-              <org-tree ref="treeRef" />
+              <org-tree ref="treeRef"  />
             </div>
             <org-user-list
               :keyWord="keyWord"
@@ -25,6 +25,7 @@
               :oldSelectData="selectedOldData"
               @change="handleSelectChange"
               :selected-tree-id="selectedTreeId"
+              :selected-data="selectedData"
             />
           </div>
 
@@ -49,7 +50,7 @@
   import OrgTree from '/@/components/BsUi/OrgUserSelector/components/OrgTree.vue';
   import OrgUserList from '/@/components/BsUi/OrgUserSelector/components/OrgUserList.vue';
   import SelectedData from '/@/components/BsUi/OrgUserSelector/components/SelectedData.vue';
-  import { computed, nextTick, ref, watch } from 'vue';
+  import {computed, nextTick, onMounted, ref, watch} from 'vue';
   import { isEmpty } from 'lodash';
   import {SCENE_TYPE, SELECT_MULTIPLE} from '/@/components/BsUi/constant.js';
 
@@ -77,6 +78,10 @@
       required: false,
       default: 'name',
     },
+    selectedData: {
+      required: true,
+      default: undefined
+    }
   });
 
   const {
@@ -103,6 +108,7 @@
   const keyWord = ref('');
   const orgUserListRef = ref(null);
 
+
   const handleRemove = (node) => {
     orgUserListRef.value.handleRemove(node);
   };

+ 4 - 4
src/components/BsUi/OrgUserSelector/components/OrgTree.vue

@@ -142,15 +142,15 @@
   departmentEmitter.on('selectTree', selectTree);
 
   function selectTree(id) {
-
-    console.log("selectTree", id);
-
-
     selectedKeys.value = [id];
     treeSelectChange(selectedKeys.value);
   }
 
   function treeSelectChange(idList) {
+
+
+
+
     if (_.isEmpty(idList)) {
       breadcrumb.value = [];
       selectedDepartmentChildren.value = [];

+ 87 - 119
src/components/BsUi/OrgUserSelector/components/OrgUserList.vue

@@ -3,7 +3,7 @@
     <bs-empty v-if="searchData.length === 0" />
     <div v-else class="org-user-content">
       <div class="top">
-        <div class="top-left"  v-if="isEmpty(keyWord)">
+        <div class="top-left" v-if="isEmpty(keyWord)">
           <a-space>
             <a-checkbox
               @change="handleSelectAllChange"
@@ -66,16 +66,21 @@
 </template>
 
 <script setup>
-  import { cloneDeep, isEmpty } from 'lodash';
+  import { cloneDeep, isArray, isEmpty } from 'lodash';
   import { queryListByParams } from '/@/api/system/table-api.js';
   import BsEmpty from '/@/components/BsUi/Empty/index.vue';
   import { computed, nextTick, onMounted, reactive, ref, toRefs, watch } from 'vue';
   import { SCENE_TYPE, SELECT_MULTIPLE } from '/@/components/BsUi/constant.js';
+  import { removeElement } from '/@/components/BsUi/uitl.js';
 
-  const emit = defineEmits(['change']);
-
-  const isLoaded = ref(false);
+  const testData = Array.from({ length: 100 }, (value, index) => ({
+    name: `韩晓辉${index}`,
+    id: index,
+    parentId: 1,
+    parentName: '青岛无限畅联科技有限公司',
+  }));
 
+  const emit = defineEmits(['change']);
   const props = defineProps({
     multiple: {
       required: false,
@@ -110,12 +115,16 @@
       required: false,
       default: '',
     },
+    selectedData: {
+      required: true,
+      default: undefined,
+    },
   });
-
   const isLoading = ref(false);
   const isSelectAll = ref(false);
   const isInclude = ref(false);
   const isIndeterminate = ref(false);
+  const isInit = ref(true);
 
   const pageInfo = reactive({
     pageNum: 1,
@@ -132,27 +141,14 @@
   };
 
   const handleRemove = (node) => {
-    searchData.value.forEach((v) => {
-      if (node[props.idKey] === v[props.idKey]) {
-        v.isSelected = false;
-      }
-    });
-
-    props.oldSelectData.forEach((v) => {
-      if (node[props.idKey] === v[props.idKey]) {
-        v.isSelected = false;
-      }
-    });
+    const delIdx = currentSelectedData.value.findIndex((v) => v[props.idKey] === node[props.idKey]);
+    if (delIdx > -1) {
+      currentSelectedData.value.splice(delIdx, 1);
+    }
   };
 
   const handleReset = () => {
-    searchData.value.forEach((v) => {
-      v.isSelected = false;
-    });
-
-    props.oldSelectData.forEach((v) => {
-      v.isSelected = false;
-    });
+    currentSelectedData.value = [];
   };
 
   const handlePagerChange = (pageNum, pageSize) => {
@@ -165,35 +161,28 @@
     if (props.disabled) {
       return false;
     }
-
     if (props.multiple === SELECT_MULTIPLE.ONE) {
-      handleReset();
-      node.isSelected = true;
+      currentSelectedData.value = [node];
     } else {
-      props.oldSelectData.forEach((v) => {
-        if (v[props.idKey] === node[props.idKey]) {
-          v.isSelected = !v.isSelected;
-        }
-      });
-      node.isSelected = !node.isSelected;
+      const delIdx = currentSelectedData.value.findIndex((v) => v[props.idKey] === node[props.idKey]);
+      if (delIdx > -1) {
+        currentSelectedData.value.splice(delIdx, 1);
+      } else {
+        currentSelectedData.value.push(node);
+      }
     }
   };
 
   const handleSelectAllChange = (event) => {
     const checked = event.target.checked;
-    searchData.value.forEach((v) => {
-      v.isSelected = checked;
-    });
-
-    currentSelectedData.value.forEach((v) => {
-      v.isSelected = checked;
-    });
-
-    props.oldSelectData.forEach((v) => {
-      if (searchData.value.findIndex((vv) => vv[props.idKey] === v[props.idKey]) > -1) {
-        v.isSelected = checked;
-      }
-    });
+    const cSelData = cloneDeep(currentSelectedData.value);
+    if (checked) {
+      currentSelectedData.value = uniqueByIdKey([...cSelData, ...searchData.value]);
+    } else {
+      searchData.value.forEach((node) => {
+        removeElement(currentSelectedData.value, node, props.idKey);
+      });
+    }
   };
 
   const fetchData = (data) => {
@@ -209,13 +198,21 @@
       queryListByParams(params).then((res) => {
         isLoading.value = false;
         if (res?.code === 0) {
-          searchData.value = res?.data;
+          searchData.value = !isEmpty(res?.data) ? res?.data : [];
           pageInfo.total = searchData.value.length;
-          resolve();
         } else {
-          reject("数据获取失败")
+          searchData.value = [];
+          pageInfo.total = 0;
         }
+        resolve();
       });
+
+      // setTimeout(() => {
+      //   isLoading.value = false;
+      //   searchData.value = props.keyWord ? testData.filter((v) => v.name.includes(props.keyWord)) : testData.slice(0, 18);
+      //   pageInfo.total = searchData.value.length;
+      //   resolve();
+      // }, 1000);
     });
   };
 
@@ -227,49 +224,16 @@
     { deep: true }
   );
 
-  watch(
-    [searchData],
-    ([value]) => {
-      const cloneDeepCurSelData = cloneDeep(currentSelectedData.value);
-      const currentSelData = cloneDeep(value.filter((v) => v.isSelected));
-      let newArr = [];
-      cloneDeepCurSelData.forEach((v) => {
-        const it = value.find((vv) => vv[props.idKey] === v[props.idKey]);
-        if (isEmpty(it)) {
-          newArr.push(v);
-        } else if (it?.isSelected) {
-          newArr.push(it);
-        }
-      });
-
-      if (props.multiple === SELECT_MULTIPLE.MORE) {
-        currentSelectedData.value = uniqueByIdKey([...currentSelData, ...newArr]);
-      } else {
-        currentSelectedData.value = currentSelData;
-      }
-      // 全选,反选逻辑
-      if (value.every((v) => v?.isSelected)) {
-        isSelectAll.value = true;
-        isIndeterminate.value = false;
-      } else if (value.some((v) => v?.isSelected)) {
-        isSelectAll.value = false;
-        isIndeterminate.value = true;
-      } else {
-        isSelectAll.value = false;
-        isIndeterminate.value = false;
-      }
-    },
-    { deep: true }
-  );
+  watch([searchData], ([value, allKeys]) => {}, { deep: true });
 
   const changeInclude = (event) => {
     const checked = event.target.checked;
     init(false, {
-      keyword: "",
+      keyword: '',
       parentId: props.selectedTreeId,
-      include: checked
+      include: checked,
     });
-  }
+  };
 
   watch(
     () => props.keyWord,
@@ -278,15 +242,15 @@
       isInclude.value = false;
       init(false, {
         keyword: value,
-        include: false
+        include: false,
       });
     }
   );
   watch(
     () => props.selectedTreeId,
     (val) => {
-      init(false, {
-        parentId: val
+      init(isInit.value, {
+        parentId: val,
       });
     },
     {
@@ -294,52 +258,56 @@
     }
   );
 
-  const init = (isInit = true, params = {}) => {
-    isLoaded.value = false;
+  onMounted(() => {
+    // init(true, {
+    //   parentId: props.selectedTreeId,
+    // });
+  });
+
+  const init = (isInitVal = true, params = {}) => {
+    isInit.value = isInitVal;
     searchData.value = [];
     const curSelData = cloneDeep(currentSelectedData.value);
-    const oldSelectData = cloneDeep(props.oldSelectData);
     return new Promise((resolve, reject) => {
       fetchData(params).then((res) => {
-        currentSelectedKeys.value = Array.from(new Set([...curSelData.map((v) => v[props.idKey]), ...oldSelectData.map((v) => v[props.idKey])]));
-        // 数据的回显
-        searchData.value.forEach((a) => {
-          if (currentSelectedKeys.value.findIndex((v) => v === a[props.idKey]) > -1) {
-            a.isSelected = true;
+        if (props.multiple === SELECT_MULTIPLE.ONE) {
+          if (!isEmpty(curSelData)) {
+            currentSelectedData.value = curSelData;
+          } else {
+            currentSelectedData.value = !isEmpty(props.selectedData) ? [props.selectedData] : [];
           }
-        });
-
-        isLoaded.value = true;
+        } else {
+          if (isInitVal) {
+            currentSelectedData.value = uniqueByIdKey([...curSelData, ...props.selectedData]);
+          } else {
+            currentSelectedData.value = uniqueByIdKey([...curSelData]);
+          }
+        }
         resolve();
       });
     });
   };
 
-  const getOldSelectData = () => {
-    if (props.oldSelectData.length === 0) {
-      return [];
-    }
-
-    return cloneDeep(props.oldSelectData).filter((v) => v.isSelected);
-  };
-
   const allSelectedData = computed(() => {
-    return uniqueByIdKey([...currentSelectedData.value, ...getOldSelectData()]);
+    return uniqueByIdKey([...currentSelectedData.value]);
   });
 
   const allSelectedKeys = computed(() => {
-    return allSelectedData.value.map((v) => v[props.idKey]);
-  });
-
-  watch(allSelectedKeys, (val) => {
-    isLoaded.value &&
-      emit('change', {
-        selectedKeys: val,
-        selectedData: allSelectedData.value,
-      });
+    const allKeys = allSelectedData.value.map((v) => v[props.idKey]);
+    // 全选,反选逻辑
+    if (searchData.value.every((v) => allKeys.includes(v[props.idKey]))) {
+      isSelectAll.value = true;
+      isIndeterminate.value = false;
+    } else if (searchData.value.some((v) => allKeys.includes(v[props.idKey]))) {
+      isSelectAll.value = false;
+      isIndeterminate.value = true;
+    } else {
+      isSelectAll.value = false;
+      isIndeterminate.value = false;
+    }
+    return allKeys;
   });
 
-
   defineExpose({
     fetchData,
     init,

+ 10 - 5
src/components/BsUi/OrgUserSelector/index.vue

@@ -25,6 +25,7 @@
           <UserOutlined />
         </template>
       </a-button>
+      {{ selectedData }}
     </div>
     <modal-selector
       ref="modalSelectorRef"
@@ -34,6 +35,7 @@
       :label-key="labelKey"
       @change="selectChange"
       @ok="confirm"
+      :selected-data="selectedData"
     />
   </div>
 </template>
@@ -52,7 +54,7 @@
   const props = defineProps({
     selectedData: {
       required: true,
-      default: null,
+      default: undefined,
     },
     multiple: {
       required: false,
@@ -71,11 +73,10 @@
       default: 'name',
     },
   });
+  const emit = defineEmits(['update:selectedData']);
 
   const modalSelectorRef = ref(null);
 
-  const emit = defineEmits();
-
   const selectChange = (value) => {};
 
   const setOptions = (valObj) => {
@@ -95,7 +96,11 @@
   };
 
   const closeTags = (onClose, val, option, label) => {
-    selVal.value = selVal.value.filter((v) => v !== val);
+    if (isArray(selVal.value)) {
+      selVal.value = selVal.value.filter((v) => v !== val);
+    } else {
+      selVal.value = undefined;
+    }
     const valObj = oldSelectedData.value.filter((v) => v[props.idKey] !== val);
     setOptions(valObj);
     emit('update:selectedData', valObj);
@@ -117,7 +122,7 @@
 
   const confirm = ({ selectedKeys, selectedData }) => {
     setOptions(selectedData);
-    if (selectedKeys.length === 1) {
+    if (props.multiple === SELECT_MULTIPLE.ONE && selectedData.length === 1) {
       selVal.value = selectedKeys[0];
       emit('update:selectedData', selectedData[0]);
     } else {

+ 8 - 1
src/components/BsUi/uitl.js

@@ -1,4 +1,4 @@
-import { isEmpty, isNumber } from 'lodash';
+import { cloneDeep, isEmpty, isNumber } from 'lodash';
 
 export function formatMoney(num, decimalPlaces = 2) {
   if (isEmpty(num)) {
@@ -48,3 +48,10 @@ export const getPathName = (params) => {
 
   return getPath(childId);
 };
+
+export const removeElement = (arr, node, idKey) => {
+  const delIdx = arr.findIndex((v) => v[idKey] === node[idKey]);
+  if (delIdx > -1) {
+    arr.splice(delIdx, 1);
+  }
+};