Explorar el Código

feat: 优化 `PureTableBar` 组件,添加列展示功能

xiaoxian521 hace 2 años
padre
commit
723cb46eaf

+ 1 - 1
.github/workflows/gitee.yml

@@ -26,7 +26,7 @@ jobs:
 
       - name: Deploy 🔧
         run: |
-          pnpm install
+          pnpm install --no-frozen-lockfile
           sed -i "s#VITE_PUBLIC_PATH = /#VITE_PUBLIC_PATH = /vue-pure-admin/#g" $(pwd)/.env.production
           pnpm build
           cd dist

+ 3 - 3
package.json

@@ -34,7 +34,7 @@
     "@logicflow/core": "^1.2.5",
     "@logicflow/extension": "^1.2.5",
     "@pureadmin/descriptions": "^1.1.1",
-    "@pureadmin/table": "^2.0.0",
+    "@pureadmin/table": "^2.1.0",
     "@pureadmin/utils": "^1.8.9",
     "@vueuse/core": "^10.1.2",
     "@vueuse/motion": "2.0.0-beta.12",
@@ -57,12 +57,12 @@
     "mockjs": "^1.1.0",
     "nprogress": "^0.2.0",
     "path": "^0.12.7",
-    "pinia": "^2.0.35",
+    "pinia": "^2.0.36",
     "qrcode": "^1.5.3",
     "qs": "^6.11.1",
     "responsive-storage": "^2.2.0",
     "sortablejs": "^1.15.0",
-    "swiper": "^9.2.4",
+    "swiper": "^9.3.0",
     "typeit": "^8.7.1",
     "v-contextmenu": "3.0.0",
     "vue": "^3.2.47",

+ 12 - 12
pnpm-lock.yaml

@@ -12,7 +12,7 @@ specifiers:
   "@logicflow/core": ^1.2.5
   "@logicflow/extension": ^1.2.5
   "@pureadmin/descriptions": ^1.1.1
-  "@pureadmin/table": ^2.0.0
+  "@pureadmin/table": ^2.1.0
   "@pureadmin/theme": ^3.0.0
   "@pureadmin/utils": ^1.8.9
   "@types/element-resize-detector": 1.1.3
@@ -60,7 +60,7 @@ specifiers:
   nprogress: ^0.2.0
   path: ^0.12.7
   picocolors: ^1.0.0
-  pinia: ^2.0.35
+  pinia: ^2.0.36
   postcss: ^8.4.23
   postcss-html: ^1.5.0
   postcss-import: ^15.1.0
@@ -87,7 +87,7 @@ specifiers:
   stylelint-prettier: ^3.0.0
   stylelint-scss: ^5.0.0
   svgo: ^3.0.2
-  swiper: ^9.2.4
+  swiper: ^9.3.0
   tailwindcss: ^3.3.2
   terser: ^5.17.1
   typeit: ^8.7.1
@@ -120,7 +120,7 @@ dependencies:
   "@logicflow/core": 1.2.5
   "@logicflow/extension": 1.2.5
   "@pureadmin/descriptions": 1.1.1_element-plus@2.3.4
-  "@pureadmin/table": 2.0.0_element-plus@2.3.4
+  "@pureadmin/table": 2.1.0_element-plus@2.3.4
   "@pureadmin/utils": 1.8.9_echarts@5.4.2+vue@3.2.47
   "@vueuse/core": 10.1.2_vue@3.2.47
   "@vueuse/motion": 2.0.0-beta.12_vue@3.2.47
@@ -143,12 +143,12 @@ dependencies:
   mockjs: 1.1.0
   nprogress: 0.2.0
   path: 0.12.7
-  pinia: 2.0.35_dtjfskxukdxv24psui2m5c75zy
+  pinia: 2.0.36_dtjfskxukdxv24psui2m5c75zy
   qrcode: 1.5.3
   qs: 6.11.1
   responsive-storage: 2.2.0
   sortablejs: 1.15.0
-  swiper: 9.2.4
+  swiper: 9.3.0
   typeit: 8.7.1
   v-contextmenu: 3.0.0_vue@3.2.47
   vue: 3.2.47
@@ -2495,10 +2495,10 @@ packages:
       vue: 3.2.47
     dev: false
 
-  /@pureadmin/table/2.0.0_element-plus@2.3.4:
+  /@pureadmin/table/2.1.0_element-plus@2.3.4:
     resolution:
       {
-        integrity: sha512-B5+vniSskCOjXLbQA+quPtySoOdwrhQOV93ruSwaUUZvRXxbfro1C3tAhUk/xYSeg8CbGrjoKdXYtN+yGjn6YA==
+        integrity: sha512-svPWYqT/7XScfaM/LFYd1bXIq/kMbOeRQ/5pi79XvxtO4CyA9Y6uiFxQzW1m8rwPDGc2wfs5DiiayyS53Bdv9A==
       }
     peerDependencies:
       element-plus: ^2.0.0
@@ -9464,10 +9464,10 @@ packages:
     engines: { node: ">=0.10.0" }
     dev: true
 
-  /pinia/2.0.35_dtjfskxukdxv24psui2m5c75zy:
+  /pinia/2.0.36_dtjfskxukdxv24psui2m5c75zy:
     resolution:
       {
-        integrity: sha512-P1IKKQWhxGXiiZ3atOaNI75bYlFUbRxtJdhPLX059Z7+b9Z04rnTZdSY8Aph1LA+/4QEMAYHsTQ638Wfe+6K5g==
+        integrity: sha512-4UKApwjlmJH+VuHKgA+zQMddcCb3ezYnyewQ9NVrsDqZ/j9dMv5+rh+1r48whKNdpFkZAWVxhBp5ewYaYX9JcQ==
       }
     peerDependencies:
       "@vue/composition-api": ^1.4.0
@@ -11763,10 +11763,10 @@ packages:
       picocolors: 1.0.0
     dev: true
 
-  /swiper/9.2.4:
+  /swiper/9.3.0:
     resolution:
       {
-        integrity: sha512-L7y3K/iiMXNYQ94FbfcJn7jex4QPnS4+voXGupTdC+UHW4XrR40QDdm4c9hXJ+Br0Il7PP0vP1W3goM9/Ly6Sg==
+        integrity: sha512-iELlQVvWLdyfUjQSfhg8UTKBvgfm3uCfv3wJ3f9wbSWP6spzoOTLcob87A8ywPS2FRc552JmrnyL5+LYfN8j9Q==
       }
     engines: { node: ">= 4.7.0" }
     dependencies:

+ 105 - 8
src/components/RePureTableBar/src/bar.tsx

@@ -1,5 +1,5 @@
-import { delay } from "@pureadmin/utils";
 import { useEpThemeStoreHook } from "@/store/modules/epTheme";
+import { delay, getKeyList, cloneDeep } from "@pureadmin/utils";
 import { defineComponent, ref, computed, type PropType } from "vue";
 import ExpandIcon from "./svg/expand.svg?component";
 import RefreshIcon from "./svg/refresh.svg?component";
@@ -15,6 +15,11 @@ const props = {
   /** 对于树形表格,如果想启用展开和折叠功能,传入当前表格的ref即可 */
   tableRef: {
     type: Object as PropType<any>
+  },
+  /** 需要展示的列 */
+  columns: {
+    type: Array as PropType<TableColumnList>,
+    default: () => []
   }
 };
 
@@ -24,10 +29,14 @@ export default defineComponent({
   emits: ["refresh"],
   setup(props, { emit, slots, attrs }) {
     const buttonRef = ref();
-    const checkList = ref([]);
     const size = ref("default");
     const isExpandAll = ref(true);
     const loading = ref(false);
+    const checkAll = ref(true);
+    const isIndeterminate = ref(false);
+    let checkColumnList = getKeyList(cloneDeep(props?.columns), "label");
+    const checkedColumns = ref(checkColumnList);
+    const dynamicColumns = ref(cloneDeep(props?.columns));
 
     const getDropdownItemStyle = computed(() => {
       return s => {
@@ -50,6 +59,19 @@ export default defineComponent({
       ];
     });
 
+    const topClass = computed(() => {
+      return [
+        "flex",
+        "justify-between",
+        "pt-[3px]",
+        "px-[11px]",
+        "border-b-[1px]",
+        "border-solid",
+        "border-[#dcdfe6]",
+        "dark:border-[#303030]"
+      ];
+    });
+
     function onReFresh() {
       loading.value = true;
       emit("refresh");
@@ -70,6 +92,33 @@ export default defineComponent({
       });
     }
 
+    function handleCheckAllChange(val: boolean) {
+      checkedColumns.value = val ? checkColumnList : [];
+      isIndeterminate.value = false;
+      dynamicColumns.value.map(column =>
+        val ? (column.hide = false) : (column.hide = true)
+      );
+    }
+
+    function handleCheckedColumnsChange(value: string[]) {
+      const checkedCount = value.length;
+      checkAll.value = checkedCount === checkColumnList.length;
+      isIndeterminate.value =
+        checkedCount > 0 && checkedCount < checkColumnList.length;
+    }
+
+    function handleCheckColumnListChange(val: boolean, index: number) {
+      dynamicColumns.value[index].hide = !val;
+    }
+
+    function onReset() {
+      checkAll.value = true;
+      isIndeterminate.value = false;
+      checkColumnList = getKeyList(cloneDeep(props?.columns), "label");
+      checkedColumns.value = checkColumnList;
+      dynamicColumns.value = cloneDeep(props?.columns);
+    }
+
     const dropdown = {
       dropdown: () => (
         <el-dropdown-menu class="translation">
@@ -150,11 +199,56 @@ export default defineComponent({
               </el-tooltip>
               <el-divider direction="vertical" />
 
-              <el-popover v-slots={reference} width="200" trigger="click">
-                <el-checkbox-group v-model={checkList.value}>
-                  <el-checkbox label="序号列" />
-                  <el-checkbox label="勾选列" />
-                </el-checkbox-group>
+              <el-popover
+                v-slots={reference}
+                popper-style={{ padding: 0 }}
+                width="160"
+                trigger="click"
+              >
+                <div class={[topClass.value]}>
+                  <el-checkbox
+                    class="!-mr-1"
+                    label="列展示"
+                    v-model={checkAll.value}
+                    indeterminate={isIndeterminate.value}
+                    onChange={value => handleCheckAllChange(value)}
+                  />
+                  <el-button type="primary" link onClick={() => onReset()}>
+                    重置
+                  </el-button>
+                </div>
+
+                <div class="pt-[6px] pl-[11px]">
+                  <el-checkbox-group
+                    v-model={checkedColumns.value}
+                    onChange={value => handleCheckedColumnsChange(value)}
+                  >
+                    <el-space
+                      direction="vertical"
+                      alignment="flex-start"
+                      size={0}
+                    >
+                      {checkColumnList.map((item, index) => {
+                        return (
+                          <el-checkbox
+                            key={item}
+                            label={item}
+                            onChange={value =>
+                              handleCheckColumnListChange(value, index)
+                            }
+                          >
+                            <span
+                              title={item}
+                              class="inline-block w-[120px] truncate hover:text-text_color_primary"
+                            >
+                              {item}
+                            </span>
+                          </el-checkbox>
+                        );
+                      })}
+                    </el-space>
+                  </el-checkbox-group>
+                </div>
               </el-popover>
             </div>
 
@@ -177,7 +271,10 @@ export default defineComponent({
               content="列设置"
             />
           </div>
-          {slots.default({ size: size.value, checkList: checkList.value })}
+          {slots.default({
+            size: size.value,
+            dynamicColumns: dynamicColumns.value
+          })}
         </div>
       </>
     );

+ 1 - 1
src/views/pure-table/high/page/index.vue

@@ -54,7 +54,7 @@ const {
       row-key="id"
       alignWhole="center"
       showOverflowTooltip
-      :size="tableSize"
+      :size="tableSize as any"
       :loading="loading"
       :loading-config="loadingConfig"
       :height="tableSize === 'small' ? 352 : 440"

+ 1 - 8
src/views/system/dept/hook.tsx

@@ -12,17 +12,10 @@ export function useDept() {
   const loading = ref(true);
 
   const columns: TableColumnList = [
-    {
-      type: "selection",
-      width: 55,
-      align: "left",
-      hide: ({ checkList }) => !checkList.includes("勾选列")
-    },
     {
       label: "序号",
       type: "index",
-      minWidth: 70,
-      hide: ({ checkList }) => !checkList.includes("序号列")
+      minWidth: 70
     },
     {
       label: "部门名称",

+ 3 - 3
src/views/system/dept/index.vue

@@ -73,6 +73,7 @@ const {
 
     <PureTableBar
       title="部门列表"
+      :columns="columns"
       :tableRef="tableRef?.getTableRef()"
       @refresh="onSearch"
     >
@@ -81,7 +82,7 @@ const {
           新增部门
         </el-button>
       </template>
-      <template v-slot="{ size, checkList }">
+      <template v-slot="{ size, dynamicColumns }">
         <pure-table
           ref="tableRef"
           border
@@ -93,8 +94,7 @@ const {
           :loading="loading"
           :size="size"
           :data="dataList"
-          :columns="columns"
-          :checkList="checkList"
+          :columns="dynamicColumns"
           :header-cell-style="{
             background: 'var(--el-table-row-hover-bg-color)',
             color: 'var(--el-text-color-primary)'

+ 3 - 4
src/views/system/role/hook.tsx

@@ -22,16 +22,15 @@ export function useRole() {
   });
   const columns: TableColumnList = [
     {
+      label: "勾选列", // 如果需要表格多选,此处label必须设置
       type: "selection",
       width: 55,
-      align: "left",
-      hide: ({ checkList }) => !checkList.includes("勾选列")
+      align: "left"
     },
     {
       label: "序号",
       type: "index",
-      width: 70,
-      hide: ({ checkList }) => !checkList.includes("序号列")
+      width: 70
     },
     {
       label: "角色编号",

+ 3 - 4
src/views/system/role/index.vue

@@ -85,13 +85,13 @@ const {
       </el-form-item>
     </el-form>
 
-    <PureTableBar title="角色列表" @refresh="onSearch">
+    <PureTableBar title="角色列表" :columns="columns" @refresh="onSearch">
       <template #buttons>
         <el-button type="primary" :icon="useRenderIcon(AddFill)">
           新增角色
         </el-button>
       </template>
-      <template v-slot="{ size, checkList }">
+      <template v-slot="{ size, dynamicColumns }">
         <pure-table
           border
           align-whole="center"
@@ -100,8 +100,7 @@ const {
           :loading="loading"
           :size="size"
           :data="dataList"
-          :columns="columns"
-          :checkList="checkList"
+          :columns="dynamicColumns"
           :pagination="pagination"
           :paginationSmall="size === 'small' ? true : false"
           :header-cell-style="{

+ 1 - 8
src/views/system/user/hook.tsx

@@ -21,17 +21,10 @@ export function useUser() {
     background: true
   });
   const columns: TableColumnList = [
-    {
-      type: "selection",
-      width: 55,
-      align: "left",
-      hide: ({ checkList }) => !checkList.includes("勾选列")
-    },
     {
       label: "序号",
       type: "index",
-      width: 70,
-      hide: ({ checkList }) => !checkList.includes("序号列")
+      width: 70
     },
     {
       label: "用户编号",

+ 3 - 4
src/views/system/user/index.vue

@@ -88,13 +88,13 @@ const {
         </el-form-item>
       </el-form>
 
-      <PureTableBar title="用户管理" @refresh="onSearch">
+      <PureTableBar title="用户管理" :columns="columns" @refresh="onSearch">
         <template #buttons>
           <el-button type="primary" :icon="useRenderIcon(AddFill)">
             新增用户
           </el-button>
         </template>
-        <template v-slot="{ size, checkList }">
+        <template v-slot="{ size, dynamicColumns }">
           <pure-table
             border
             align-whole="center"
@@ -102,8 +102,7 @@ const {
             :loading="loading"
             :size="size"
             :data="dataList"
-            :columns="columns"
-            :checkList="checkList"
+            :columns="dynamicColumns"
             :pagination="pagination"
             :paginationSmall="size === 'small' ? true : false"
             :header-cell-style="{

+ 1 - 3
tailwind.config.js

@@ -10,10 +10,8 @@ module.exports = {
       colors: {
         bg_color: "var(--el-bg-color)",
         primary: "var(--el-color-primary)",
-        primary_light_9: "var(--el-color-primary-light-9)",
         text_color_primary: "var(--el-text-color-primary)",
-        text_color_regular: "var(--el-text-color-regular)",
-        text_color_disabled: "var(--el-text-color-disabled)"
+        text_color_regular: "var(--el-text-color-regular)"
       }
     }
   }