Selaa lähdekoodia

同步升级前端vben框架

zuohuaijun 3 vuotta sitten
vanhempi
commit
a6a1ce9527
30 muutettua tiedostoa jossa 407 lisäystä ja 239 poistoa
  1. 1 1
      Vben2/.vscode/extensions.json
  2. 3 1
      Vben2/build/script/buildConf.ts
  3. 9 0
      Vben2/src/components/Excel/src/ImportExcel.vue
  4. 14 3
      Vben2/src/components/Markdown/src/Markdown.vue
  5. 52 13
      Vben2/src/components/Markdown/src/MarkdownViewer.vue
  6. 19 0
      Vben2/src/components/Markdown/src/getTheme.ts
  7. 3 3
      Vben2/src/components/Table/src/BasicTable.vue
  8. 23 4
      Vben2/src/components/Table/src/components/editable/EditableCell.vue
  9. 2 3
      Vben2/src/components/Table/src/hooks/useTableFooter.ts
  10. 1 1
      Vben2/src/components/Table/src/hooks/useTableScroll.ts
  11. 2 0
      Vben2/src/components/Table/src/types/table.ts
  12. 2 2
      Vben2/src/hooks/web/usePage.ts
  13. 3 3
      Vben2/src/utils/http/axios/Axios.ts
  14. 2 2
      Vben2/src/utils/http/axios/axiosTransform.ts
  15. 3 3
      Vben2/src/utils/http/axios/index.ts
  16. 1 1
      Vben2/src/utils/is.ts
  17. 40 3
      Vben2/src/views/demo/editor/markdown/index.vue
  18. 5 3
      Vben2/src/views/demo/page/form/high/PersonTable.vue
  19. 27 25
      Vben2/src/views/demo/system/account/index.vue
  20. 20 18
      Vben2/src/views/demo/system/dept/index.vue
  21. 20 18
      Vben2/src/views/demo/system/menu/index.vue
  22. 20 18
      Vben2/src/views/demo/system/role/index.vue
  23. 47 45
      Vben2/src/views/demo/table/AuthColumn.vue
  24. 7 5
      Vben2/src/views/demo/table/CustomerCell.vue
  25. 5 3
      Vben2/src/views/demo/table/EditRowTable.vue
  26. 24 20
      Vben2/src/views/demo/table/ExpandTable.vue
  27. 20 18
      Vben2/src/views/demo/table/FixedColumn.vue
  28. 16 10
      Vben2/src/views/demo/table/FixedHeight.vue
  29. 3 5
      Vben2/src/views/demo/table/tableData.tsx
  30. 13 8
      Vben2/src/views/sys/error-log/index.vue

+ 1 - 1
Vben2/.vscode/extensions.json

@@ -1,6 +1,6 @@
 {
   "recommendations": [
-    "johnsoncodehk.volar",
+    "vue.volar",
     "dbaeumer.vscode-eslint",
     "stylelint.vscode-stylelint",
     "esbenp.prettier-vscode",

+ 3 - 1
Vben2/build/script/buildConf.ts

@@ -21,13 +21,15 @@ function createConfig(params: CreateConfigParams) {
   try {
     const windowConf = `window.${configName}`;
     // Ensure that the variable will not be modified
-    const configStr = `${windowConf}=${JSON.stringify(config)};
+    let configStr = `${windowConf}=${JSON.stringify(config)};`;
+    configStr += `
       Object.freeze(${windowConf});
       Object.defineProperty(window, "${configName}", {
         configurable: false,
         writable: false,
       });
     `.replace(/\s/g, '');
+
     fs.mkdirp(getRootPath(OUTPUT_DIR));
     writeFileSync(getRootPath(`${OUTPUT_DIR}/${configFileName}`), configStr);
 

+ 9 - 0
Vben2/src/components/Excel/src/ImportExcel.vue

@@ -31,6 +31,11 @@
         type: Number,
         default: 8,
       },
+      // 是否直接返回选中文件
+      isReturnFile: {
+        type: Boolean,
+        default: false,
+      },
     },
     emits: ['success', 'error'],
     setup(props, { emit }) {
@@ -140,6 +145,10 @@
         const files = e && (e.target as HTMLInputElement).files;
         const rawFile = files && files[0]; // only setting files[0]
         if (!rawFile) return;
+        if (props.isReturnFile) {
+          emit('success', rawFile);
+          return;
+        }
         upload(rawFile);
       }
 

+ 14 - 3
Vben2/src/components/Markdown/src/Markdown.vue

@@ -19,6 +19,7 @@
   import { useModalContext } from '../../Modal';
   import { useRootSetting } from '/@/hooks/setting/useRootSetting';
   import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated';
+  import { getTheme } from './getTheme';
 
   type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined;
 
@@ -46,8 +47,9 @@
           if (!inited) {
             return;
           }
-          const theme = val === 'dark' ? 'dark' : 'classic';
-          instance.getVditor()?.setTheme(theme);
+          instance
+            .getVditor()
+            ?.setTheme(getTheme(val) as any, getTheme(val, 'content'), getTheme(val, 'code'));
         },
         {
           immediate: true,
@@ -87,13 +89,22 @@
         if (!wrapEl) return;
         const bindValue = { ...attrs, ...props };
         const insEditor = new Vditor(wrapEl, {
-          theme: getDarkMode.value === 'dark' ? 'dark' : 'classic',
+          // 设置外观主题
+          theme: getTheme(getDarkMode.value) as any,
           lang: unref(getCurrentLang),
           mode: 'sv',
           fullscreen: {
             index: 520,
           },
           preview: {
+            theme: {
+              // 设置内容主题
+              current: getTheme(getDarkMode.value, 'content'),
+            },
+            hljs: {
+              // 设置代码块主题
+              style: getTheme(getDarkMode.value, 'code'),
+            },
             actions: [],
           },
           input: (v) => {

+ 52 - 13
Vben2/src/components/Markdown/src/MarkdownViewer.vue

@@ -1,23 +1,62 @@
 <template>
-  <!-- eslint-disable vue/no-v-html -->
-  <div v-html="getHtmlData" :class="$props.class" class="markdown-viewer"></div>
+  <div ref="viewerRef" id="markdownViewer" :class="$props.class"></div>
 </template>
 
 <script lang="ts" setup>
-  import { computed, defineProps } from 'vue';
-  import showdown from 'showdown';
-
-  const converter = new showdown.Converter();
-  converter.setOption('tables', true);
+  import { defineProps, onBeforeUnmount, onDeactivated, Ref, ref, unref, watch } from 'vue';
+  import VditorPreview from 'vditor/dist/method.min';
+  import { onMountedOrActivated } from '/@/hooks/core/onMountedOrActivated';
+  import { useRootSetting } from '/@/hooks/setting/useRootSetting';
+  import { getTheme } from './getTheme';
   const props = defineProps({
     value: { type: String },
     class: { type: String },
   });
-  const getHtmlData = computed(() => converter.makeHtml(props.value || ''));
-</script>
+  const viewerRef = ref<ElRef>(null);
+  const vditorPreviewRef = ref(null) as Ref<Nullable<VditorPreview>>;
+  const { getDarkMode } = useRootSetting();
+
+  function init() {
+    const viewerEl = unref(viewerRef) as HTMLElement;
+    vditorPreviewRef.value = VditorPreview.preview(viewerEl, props.value, {
+      mode: getTheme(getDarkMode.value, 'content'),
+      theme: {
+        // 设置内容主题
+        current: getTheme(getDarkMode.value, 'content'),
+      },
+      hljs: {
+        // 设置代码块主题
+        style: getTheme(getDarkMode.value, 'code'),
+      },
+    });
+  }
+  watch(
+    () => getDarkMode.value,
+    (val) => {
+      VditorPreview.setContentTheme(getTheme(val, 'content'));
+      VditorPreview.setCodeTheme(getTheme(val, 'code'));
+      init();
+    },
+  );
 
-<style scoped>
-  .markdown-viewer {
-    width: 100%;
+  watch(
+    () => props.value,
+    (v, oldValue) => {
+      v !== oldValue && init();
+    },
+  );
+
+  function destroy() {
+    const vditorInstance = unref(vditorPreviewRef);
+    if (!vditorInstance) return;
+    try {
+      vditorInstance?.destroy?.();
+    } catch (error) {}
+    vditorPreviewRef.value = null;
   }
-</style>
+
+  onMountedOrActivated(init);
+
+  onBeforeUnmount(destroy);
+  onDeactivated(destroy);
+</script>

+ 19 - 0
Vben2/src/components/Markdown/src/getTheme.ts

@@ -0,0 +1,19 @@
+/**
+ * 获取主题类型 深色浅色模式 对应的值
+ * @param darkModeVal 深色模式值
+ * @param themeMode 主题类型——外观(默认), 内容, 代码块
+ */
+export const getTheme = (
+  darkModeVal: 'light' | 'dark' | string,
+  themeMode: 'default' | 'content' | 'code' = 'default',
+) => {
+  const isDark = darkModeVal === 'dark';
+  switch (themeMode) {
+    case 'default':
+      return isDark ? 'dark' : 'classic';
+    case 'content':
+      return isDark ? 'dark' : 'light';
+    case 'code':
+      return isDark ? 'dracula' : 'github';
+  }
+};

+ 3 - 3
Vben2/src/components/Table/src/BasicTable.vue

@@ -253,9 +253,9 @@
           footer: unref(getFooterProps),
           ...unref(getExpandOption),
         };
-        if (slots.expandedRowRender) {
-          propsData = omit(propsData, 'scroll');
-        }
+        // if (slots.expandedRowRender) {
+        //   propsData = omit(propsData, 'scroll');
+        // }
 
         propsData = omit(propsData, ['class', 'onChange']);
         return propsData;

+ 23 - 4
Vben2/src/components/Table/src/components/editable/EditableCell.vue

@@ -82,17 +82,36 @@
         if (component === 'ApiSelect') {
           apiSelectProps.cache = true;
         }
-
+        upEditDynamicDisabled(record, column, value);
         return {
           size: 'small',
           getPopupContainer: () => unref(table?.wrapRef.value) ?? document.body,
           placeholder: createPlaceholderMessage(unref(getComponent)),
           ...apiSelectProps,
-          ...omit(compProps, 'onChange'),
+          ...compProps,
           [valueField]: value,
+          disabled: unref(getDisable),
         } as any;
       });
-
+      function upEditDynamicDisabled(record, column, value) {
+        if (!record) return false;
+        const { key, dataIndex } = column;
+        if (!key && !dataIndex) return;
+        const dataKey = (dataIndex || key) as string;
+        set(record, dataKey, value);
+      }
+      const getDisable = computed(() => {
+        const { editDynamicDisabled } = props.column;
+        let disabled = false;
+        if (isBoolean(editDynamicDisabled)) {
+          disabled = editDynamicDisabled;
+        }
+        if (isFunction(editDynamicDisabled)) {
+          const { record } = props;
+          disabled = editDynamicDisabled({ record });
+        }
+        return disabled;
+      });
       const getValues = computed(() => {
         const { editValueMap } = props.column;
 
@@ -165,7 +184,7 @@
           currentValueRef.value = e;
         } else if (e?.target && Reflect.has(e.target, 'value')) {
           currentValueRef.value = (e as ChangeEvent).target.value;
-        } else if (isString(e) || isBoolean(e) || isNumber(e)) {
+        } else if (isString(e) || isBoolean(e) || isNumber(e) || isArray(e)) {
           currentValueRef.value = e;
         }
         const onChange = unref(getComponentProps)?.onChange;

+ 2 - 3
Vben2/src/components/Table/src/hooks/useTableFooter.ts

@@ -36,14 +36,13 @@ export function useTableFooter(
     nextTick(() => {
       const tableEl = unref(tableElRef);
       if (!tableEl) return;
-      const bodyDomList = tableEl.$el.querySelectorAll('.ant-table-body');
-      const bodyDom = bodyDomList[0];
+      const bodyDom = tableEl.$el.querySelector('.ant-table-content');
       useEventListener({
         el: bodyDom,
         name: 'scroll',
         listener: () => {
           const footerBodyDom = tableEl.$el.querySelector(
-            '.ant-table-footer .ant-table-body',
+            '.ant-table-footer .ant-table-content',
           ) as HTMLDivElement;
           if (!footerBodyDom || !bodyDom) return;
           footerBodyDom.scrollLeft = bodyDom.scrollLeft;

+ 1 - 1
Vben2/src/components/Table/src/hooks/useTableScroll.ts

@@ -90,7 +90,7 @@ export function useTableScroll(
 
     bodyEl!.style.height = 'unset';
 
-    if (!unref(getCanResize) || tableData.length === 0) return;
+    if (!unref(getCanResize) || !unref(tableData) || tableData.length === 0) return;
 
     await nextTick();
     // Add a delay to get the correct bottomIncludeBody paginationHeight footerHeight headerHeight

+ 2 - 0
Vben2/src/components/Table/src/types/table.ts

@@ -463,6 +463,8 @@ export interface BasicColumn extends ColumnProps<Recordable> {
     column: BasicColumn;
     index: number;
   }) => VNodeChild | JSX.Element;
+  // 动态 Disabled
+  editDynamicDisabled?: boolean | ((record: Recordable) => boolean);
 }
 
 export type ColumnChangeParam = {

+ 2 - 2
Vben2/src/hooks/web/usePage.ts

@@ -31,7 +31,7 @@ export function useGo(_router?: Router) {
  * @description: redo current page
  */
 export const useRedo = (_router?: Router) => {
-  const { push, currentRoute } = _router || useRouter();
+  const { replace, currentRoute } = _router || useRouter();
   const { query, params = {}, name, fullPath } = unref(currentRoute.value);
   function redo(): Promise<boolean> {
     return new Promise((resolve) => {
@@ -46,7 +46,7 @@ export const useRedo = (_router?: Router) => {
         params['_redirect_type'] = 'path';
         params['path'] = fullPath;
       }
-      push({ name: REDIRECT_NAME, params, query }).then(() => resolve(true));
+      replace({ name: REDIRECT_NAME, params, query }).then(() => resolve(true));
     });
   }
   return redo;

+ 3 - 3
Vben2/src/utils/http/axios/Axios.ts

@@ -199,7 +199,7 @@ export class VAxios {
 
     const opt: RequestOptions = Object.assign({}, requestOptions, options);
 
-    const { beforeRequestHook, requestCatchHook, transformRequestHook } = transform || {};
+    const { beforeRequestHook, requestCatchHook, transformResponseHook } = transform || {};
     if (beforeRequestHook && isFunction(beforeRequestHook)) {
       conf = beforeRequestHook(conf, opt);
     }
@@ -211,9 +211,9 @@ export class VAxios {
       this.axiosInstance
         .request<any, AxiosResponse<Result>>(conf)
         .then((res: AxiosResponse<Result>) => {
-          if (transformRequestHook && isFunction(transformRequestHook)) {
+          if (transformResponseHook && isFunction(transformResponseHook)) {
             try {
-              const ret = transformRequestHook(res, opt);
+              const ret = transformResponseHook(res, opt);
               resolve(ret);
             } catch (err) {
               reject(err || new Error('request error!'));

+ 2 - 2
Vben2/src/utils/http/axios/axiosTransform.ts

@@ -18,9 +18,9 @@ export abstract class AxiosTransform {
   beforeRequestHook?: (config: AxiosRequestConfig, options: RequestOptions) => AxiosRequestConfig;
 
   /**
-   * @description: Request successfully processed
+   * @description: 处理响应数据
    */
-  transformRequestHook?: (res: AxiosResponse<Result>, options: RequestOptions) => any;
+  transformResponseHook?: (res: AxiosResponse<Result>, options: RequestOptions) => any;
 
   /**
    * @description: 请求失败处理

+ 3 - 3
Vben2/src/utils/http/axios/index.ts

@@ -28,9 +28,9 @@ const { createMessage, createErrorModal } = useMessage();
  */
 const transform: AxiosTransform = {
   /**
-   * @description: 处理请求数据。如果数据不是预期格式,可直接抛出错误
+   * @description: 处理响应数据。如果数据不是预期格式,可直接抛出错误
    */
-  transformRequestHook: (res: AxiosResponse<Result>, options: RequestOptions) => {
+  transformResponseHook: (res: AxiosResponse<Result>, options: RequestOptions) => {
     const { t } = useI18n();
     const { isTransformResponse, isReturnNativeResponse } = options;
     // 是否返回原生响应头 比如:需要获取响应头时使用该属性
@@ -209,8 +209,8 @@ function createAxios(opt?: Partial<CreateAxiosOptions>) {
       {
         // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes
         // authentication schemes,e.g: Bearer
-        // authenticationScheme: 'Bearer',
         authenticationScheme: 'Bearer',
+        //authenticationScheme: '',
         timeout: 10 * 1000,
         // 基础接口地址
         // baseURL: globSetting.apiUrl,

+ 1 - 1
Vben2/src/utils/is.ts

@@ -94,6 +94,6 @@ export const isClient = !isServer;
 
 export function isUrl(path: string): boolean {
   const reg =
-    /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
+    /^(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?(\/#\/)?(?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
   return reg.test(path);
 }

+ 40 - 3
Vben2/src/views/demo/editor/markdown/index.vue

@@ -28,16 +28,53 @@
     setup() {
       const markDownRef = ref<Nullable<MarkDownActionType>>(null);
       const valueRef = ref(`
-# title
+# 标题h1
 
-# content
+##### 标题h5
+
+**加粗**
+*斜体*
+~~删除线~~
+[链接](https://github.com/vbenjs/vue-vben-admin)
+↓分割线↓
+
+---
+
+
+* 无序列表1
+  * 无序列表1.1
+
+1. 有序列表1
+2. 有序列表2
+
+* [ ] 任务列表1
+* [x] 任务列表2
+
+> 引用示例
+
+\`\`\`js
+// 代码块:
+(() => {
+  var htmlRoot = document.getElementById('htmlRoot');
+  var theme = window.localStorage.getItem('__APP__DARK__MODE__');
+  if (htmlRoot && theme) {
+    htmlRoot.setAttribute('data-theme', theme);
+    theme = htmlRoot = null;
+  }
+})();
+\`\`\`
+
+| 表格 | 示例 | 🎉️ |
+| --- | --- | --- |
+| 1 | 2 | 3 |
+| 4 | 5 | 6 |
 `);
 
       function toggleTheme() {
         const markDown = unref(markDownRef);
         if (!markDown) return;
         const vditor = markDown.getVditor();
-        vditor.setTheme('dark');
+        vditor.setTheme('dark', 'dark', 'dracula');
       }
 
       function handleChange(v: string) {

+ 5 - 3
Vben2/src/views/demo/page/form/high/PersonTable.vue

@@ -1,8 +1,10 @@
 <template>
   <div>
     <BasicTable @register="registerTable" @edit-change="handleEditChange">
-      <template #action="{ record, column }">
-        <TableAction :actions="createActions(record, column)" />
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'action'">
+          <TableAction :actions="createActions(record, column)" />
+        </template>
       </template>
     </BasicTable>
     <a-button block class="mt-5" type="dashed" @click="handleAdd"> 新增成员 </a-button>
@@ -65,7 +67,7 @@
           width: 160,
           title: '操作',
           dataIndex: 'action',
-          slots: { customRender: 'action' },
+          // slots: { customRender: 'action' },
         },
         pagination: false,
       });

+ 27 - 25
Vben2/src/views/demo/system/account/index.vue

@@ -5,31 +5,33 @@
       <template #toolbar>
         <a-button type="primary" @click="handleCreate">新增账号</a-button>
       </template>
-      <template #action="{ record }">
-        <TableAction
-          :actions="[
-            {
-              icon: 'clarity:info-standard-line',
-              tooltip: '查看用户详情',
-              onClick: handleView.bind(null, record),
-            },
-            {
-              icon: 'clarity:note-edit-line',
-              tooltip: '编辑用户资料',
-              onClick: handleEdit.bind(null, record),
-            },
-            {
-              icon: 'ant-design:delete-outlined',
-              color: 'error',
-              tooltip: '删除此账号',
-              popConfirm: {
-                title: '是否确认删除',
-                placement: 'left',
-                confirm: handleDelete.bind(null, record),
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'action'">
+          <TableAction
+            :actions="[
+              {
+                icon: 'clarity:info-standard-line',
+                tooltip: '查看用户详情',
+                onClick: handleView.bind(null, record),
               },
-            },
-          ]"
-        />
+              {
+                icon: 'clarity:note-edit-line',
+                tooltip: '编辑用户资料',
+                onClick: handleEdit.bind(null, record),
+              },
+              {
+                icon: 'ant-design:delete-outlined',
+                color: 'error',
+                tooltip: '删除此账号',
+                popConfirm: {
+                  title: '是否确认删除',
+                  placement: 'left',
+                  confirm: handleDelete.bind(null, record),
+                },
+              },
+            ]"
+          />
+        </template>
       </template>
     </BasicTable>
     <AccountModal @register="registerModal" @success="handleSuccess" />
@@ -77,7 +79,7 @@
           width: 120,
           title: '操作',
           dataIndex: 'action',
-          slots: { customRender: 'action' },
+          // slots: { customRender: 'action' },
         },
       });
 

+ 20 - 18
Vben2/src/views/demo/system/dept/index.vue

@@ -4,24 +4,26 @@
       <template #toolbar>
         <a-button type="primary" @click="handleCreate"> 新增部门 </a-button>
       </template>
-      <template #action="{ record }">
-        <TableAction
-          :actions="[
-            {
-              icon: 'clarity:note-edit-line',
-              onClick: handleEdit.bind(null, record),
-            },
-            {
-              icon: 'ant-design:delete-outlined',
-              color: 'error',
-              popConfirm: {
-                title: '是否确认删除',
-                placement: 'left',
-                confirm: handleDelete.bind(null, record),
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'action'">
+          <TableAction
+            :actions="[
+              {
+                icon: 'clarity:note-edit-line',
+                onClick: handleEdit.bind(null, record),
               },
-            },
-          ]"
-        />
+              {
+                icon: 'ant-design:delete-outlined',
+                color: 'error',
+                popConfirm: {
+                  title: '是否确认删除',
+                  placement: 'left',
+                  confirm: handleDelete.bind(null, record),
+                },
+              },
+            ]"
+          />
+        </template>
       </template>
     </BasicTable>
     <DeptModal @register="registerModal" @success="handleSuccess" />
@@ -62,7 +64,7 @@
           width: 80,
           title: '操作',
           dataIndex: 'action',
-          slots: { customRender: 'action' },
+          // slots: { customRender: 'action' },
           fixed: undefined,
         },
       });

+ 20 - 18
Vben2/src/views/demo/system/menu/index.vue

@@ -4,24 +4,26 @@
       <template #toolbar>
         <a-button type="primary" @click="handleCreate"> 新增菜单 </a-button>
       </template>
-      <template #action="{ record }">
-        <TableAction
-          :actions="[
-            {
-              icon: 'clarity:note-edit-line',
-              onClick: handleEdit.bind(null, record),
-            },
-            {
-              icon: 'ant-design:delete-outlined',
-              color: 'error',
-              popConfirm: {
-                title: '是否确认删除',
-                placement: 'left',
-                confirm: handleDelete.bind(null, record),
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'action'">
+          <TableAction
+            :actions="[
+              {
+                icon: 'clarity:note-edit-line',
+                onClick: handleEdit.bind(null, record),
               },
-            },
-          ]"
-        />
+              {
+                icon: 'ant-design:delete-outlined',
+                color: 'error',
+                popConfirm: {
+                  title: '是否确认删除',
+                  placement: 'left',
+                  confirm: handleDelete.bind(null, record),
+                },
+              },
+            ]"
+          />
+        </template>
       </template>
     </BasicTable>
     <MenuDrawer @register="registerDrawer" @success="handleSuccess" />
@@ -63,7 +65,7 @@
           width: 80,
           title: '操作',
           dataIndex: 'action',
-          slots: { customRender: 'action' },
+          // slots: { customRender: 'action' },
           fixed: undefined,
         },
       });

+ 20 - 18
Vben2/src/views/demo/system/role/index.vue

@@ -4,24 +4,26 @@
       <template #toolbar>
         <a-button type="primary" @click="handleCreate"> 新增角色 </a-button>
       </template>
-      <template #action="{ record }">
-        <TableAction
-          :actions="[
-            {
-              icon: 'clarity:note-edit-line',
-              onClick: handleEdit.bind(null, record),
-            },
-            {
-              icon: 'ant-design:delete-outlined',
-              color: 'error',
-              popConfirm: {
-                title: '是否确认删除',
-                placement: 'left',
-                confirm: handleDelete.bind(null, record),
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'action'">
+          <TableAction
+            :actions="[
+              {
+                icon: 'clarity:note-edit-line',
+                onClick: handleEdit.bind(null, record),
               },
-            },
-          ]"
-        />
+              {
+                icon: 'ant-design:delete-outlined',
+                color: 'error',
+                popConfirm: {
+                  title: '是否确认删除',
+                  placement: 'left',
+                  confirm: handleDelete.bind(null, record),
+                },
+              },
+            ]"
+          />
+        </template>
       </template>
     </BasicTable>
     <RoleDrawer @register="registerDrawer" @success="handleSuccess" />
@@ -59,7 +61,7 @@
           width: 80,
           title: '操作',
           dataIndex: 'action',
-          slots: { customRender: 'action' },
+          // slots: { customRender: 'action' },
           fixed: undefined,
         },
       });

+ 47 - 45
Vben2/src/views/demo/table/AuthColumn.vue

@@ -1,55 +1,57 @@
 <template>
   <div class="p-4">
     <BasicTable @register="registerTable">
-      <template #action="{ record }">
-        <TableAction
-          :actions="[
-            {
-              label: '编辑',
-              onClick: handleEdit.bind(null, record),
-              auth: 'other', // 根据权限控制是否显示: 无权限,不显示
-            },
-            {
-              label: '删除',
-              icon: 'ic:outline-delete-outline',
-              onClick: handleDelete.bind(null, record),
-              auth: 'super', // 根据权限控制是否显示: 有权限,会显示
-            },
-          ]"
-          :dropDownActions="[
-            {
-              label: '启用',
-              popConfirm: {
-                title: '是否启用?',
-                confirm: handleOpen.bind(null, record),
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'action'">
+          <TableAction
+            :actions="[
+              {
+                label: '编辑',
+                onClick: handleEdit.bind(null, record),
+                auth: 'other', // 根据权限控制是否显示: 无权限,不显示
               },
-              ifShow: (_action) => {
-                return record.status !== 'enable'; // 根据业务控制是否显示: 非enable状态的不显示启用按钮
+              {
+                label: '删除',
+                icon: 'ic:outline-delete-outline',
+                onClick: handleDelete.bind(null, record),
+                auth: 'super', // 根据权限控制是否显示: 有权限,会显示
               },
-            },
-            {
-              label: '禁用',
-              popConfirm: {
-                title: '是否禁用?',
-                confirm: handleOpen.bind(null, record),
+            ]"
+            :dropDownActions="[
+              {
+                label: '启用',
+                popConfirm: {
+                  title: '是否启用?',
+                  confirm: handleOpen.bind(null, record),
+                },
+                ifShow: (_action) => {
+                  return record.status !== 'enable'; // 根据业务控制是否显示: 非enable状态的不显示启用按钮
+                },
               },
-              ifShow: () => {
-                return record.status === 'enable'; // 根据业务控制是否显示: enable状态的显示禁用按钮
+              {
+                label: '禁用',
+                popConfirm: {
+                  title: '是否禁用?',
+                  confirm: handleOpen.bind(null, record),
+                },
+                ifShow: () => {
+                  return record.status === 'enable'; // 根据业务控制是否显示: enable状态的显示禁用按钮
+                },
               },
-            },
-            {
-              label: '同时控制',
-              popConfirm: {
-                title: '是否动态显示?',
-                confirm: handleOpen.bind(null, record),
+              {
+                label: '同时控制',
+                popConfirm: {
+                  title: '是否动态显示?',
+                  confirm: handleOpen.bind(null, record),
+                },
+                auth: 'super', // 同时根据权限和业务控制是否显示
+                ifShow: () => {
+                  return true;
+                },
               },
-              auth: 'super', // 同时根据权限和业务控制是否显示
-              ifShow: () => {
-                return true;
-              },
-            },
-          ]"
-        />
+            ]"
+          />
+        </template>
       </template>
     </BasicTable>
   </div>
@@ -104,7 +106,7 @@
           width: 250,
           title: 'Action',
           dataIndex: 'action',
-          slots: { customRender: 'action' },
+          // slots: { customRender: 'action' },
         },
       });
       function handleEdit(record: Recordable) {

+ 7 - 5
Vben2/src/views/demo/table/CustomerCell.vue

@@ -3,20 +3,22 @@
     <BasicTable @register="registerTable">
       <template #bodyCell="{ column, record, text }">
         <template v-if="column.key === 'id'"> ID: {{ record.id }} </template>
-        <template v-if="column.key === 'no'">
+        <template v-else-if="column.key === 'no'">
           <Tag color="green">
             {{ record.no }}
           </Tag>
         </template>
-        <template v-if="column.key === 'avatar'">
+        <template v-else-if="column.key === 'avatar'">
           <Avatar :size="60" :src="record.avatar" />
         </template>
-        <template v-if="column.key === 'imgArr'">
+        <template v-else-if="column.key === 'imgArr'">
           <TableImg :size="60" :simpleShow="true" :imgList="text" />
         </template>
-        <template v-if="column.key === 'imgs'"> <TableImg :size="60" :imgList="text" /> </template>
+        <template v-else-if="column.key === 'imgs'">
+          <TableImg :size="60" :imgList="text" />
+        </template>
 
-        <template v-if="column.key === 'category'">
+        <template v-else-if="column.key === 'category'">
           <Tag color="green">
             {{ record.no }}
           </Tag>

+ 5 - 3
Vben2/src/views/demo/table/EditRowTable.vue

@@ -1,8 +1,10 @@
 <template>
   <div class="p-4">
     <BasicTable @register="registerTable" @edit-change="onEditChange">
-      <template #action="{ record, column }">
-        <TableAction :actions="createActions(record, column)" />
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'action'">
+          <TableAction :actions="createActions(record, column)" />
+        </template>
       </template>
     </BasicTable>
   </div>
@@ -180,7 +182,7 @@
           width: 160,
           title: 'Action',
           dataIndex: 'action',
-          slots: { customRender: 'action' },
+          // slots: { customRender: 'action' },
         },
       });
 

+ 24 - 20
Vben2/src/views/demo/table/ExpandTable.vue

@@ -1,32 +1,34 @@
 <template>
   <PageWrapper
     title="可展开表格"
-    content="不可与scroll共用。TableAction组件可配置stopButtonPropagation来阻止操作按钮的点击事件冒泡,以便配合Table组件的expandRowByClick"
+    content="TableAction组件可配置stopButtonPropagation来阻止操作按钮的点击事件冒泡,以便配合Table组件的expandRowByClick"
   >
     <BasicTable @register="registerTable">
       <template #expandedRowRender="{ record }">
         <span>No: {{ record.no }} </span>
       </template>
-      <template #action="{ record }">
-        <TableAction
-          stopButtonPropagation
-          :actions="[
-            {
-              label: '删除',
-              icon: 'ic:outline-delete-outline',
-              onClick: handleDelete.bind(null, record),
-            },
-          ]"
-          :dropDownActions="[
-            {
-              label: '启用',
-              popConfirm: {
-                title: '是否启用?',
-                confirm: handleOpen.bind(null, record),
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'action'">
+          <TableAction
+            stopButtonPropagation
+            :actions="[
+              {
+                label: '删除',
+                icon: 'ic:outline-delete-outline',
+                onClick: handleDelete.bind(null, record),
               },
-            },
-          ]"
-        />
+            ]"
+            :dropDownActions="[
+              {
+                label: '启用',
+                popConfirm: {
+                  title: '是否启用?',
+                  confirm: handleOpen.bind(null, record),
+                },
+              },
+            ]"
+          />
+        </template>
       </template>
     </BasicTable>
   </PageWrapper>
@@ -53,6 +55,8 @@
         actionColumn: {
           width: 160,
           title: 'Action',
+          dataIndex: 'action',
+          fixed: 'right',
           // slots: { customRender: 'action' },
         },
       });

+ 20 - 18
Vben2/src/views/demo/table/FixedColumn.vue

@@ -1,25 +1,27 @@
 <template>
   <div class="p-4">
     <BasicTable @register="registerTable">
-      <template #action="{ record }">
-        <TableAction
-          :actions="[
-            {
-              label: '删除',
-              icon: 'ic:outline-delete-outline',
-              onClick: handleDelete.bind(null, record),
-            },
-          ]"
-          :dropDownActions="[
-            {
-              label: '启用',
-              popConfirm: {
-                title: '是否启用?',
-                confirm: handleOpen.bind(null, record),
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'action'">
+          <TableAction
+            :actions="[
+              {
+                label: '删除',
+                icon: 'ic:outline-delete-outline',
+                onClick: handleDelete.bind(null, record),
               },
-            },
-          ]"
-        />
+            ]"
+            :dropDownActions="[
+              {
+                label: '启用',
+                popConfirm: {
+                  title: '是否启用?',
+                  confirm: handleOpen.bind(null, record),
+                },
+              },
+            ]"
+          />
+        </template>
       </template>
     </BasicTable>
   </div>

+ 16 - 10
Vben2/src/views/demo/table/FixedHeight.vue

@@ -1,15 +1,20 @@
 <template>
   <div class="p-4">
     <BasicTable @register="registerTable">
-      <template #customTitle>
-        <span>
-          姓名
-          <BasicHelp class="ml-2" text="姓名" />
-        </span>
-      </template>
-      <template #customAddress>
-        地址
-        <FormOutlined class="ml-2" />
+      <template #headerCell="{ column }">
+        <template v-if="column.key === 'name'">
+          <span>
+            姓名
+            <BasicHelp class="ml-2" text="headerHelpMessage方式2" />
+          </span>
+        </template>
+        <template v-else-if="column.key === 'address'">
+          地址
+          <FormOutlined class="ml-2" />
+        </template>
+        <template v-else>
+          <HeaderCell :column="column" />
+        </template>
       </template>
     </BasicTable>
   </div>
@@ -21,9 +26,10 @@
   import { FormOutlined } from '@ant-design/icons-vue';
   import { demoListApi } from '/@/api/demo/table';
   import { BasicHelp } from '/@/components/Basic';
+  import HeaderCell from '/@/components/Table/src/components/HeaderCell.vue';
 
   export default defineComponent({
-    components: { BasicTable, FormOutlined, BasicHelp },
+    components: { BasicTable, FormOutlined, BasicHelp, HeaderCell },
     setup() {
       const [registerTable] = useTable({
         title: '定高/头部自定义',

+ 3 - 5
Vben2/src/views/demo/table/tableData.tsx

@@ -117,6 +117,7 @@ export function getCustomHeaderColumns(): BasicColumn[] {
     {
       title: 'ID',
       dataIndex: 'id',
+      helpMessage: 'headerHelpMessage方式1',
       width: 200,
     },
     {
@@ -256,7 +257,7 @@ export function getFormConfig(): Partial<FormProps> {
   };
 }
 export function getBasicData() {
-  const data: any = (() => {
+  return (() => {
     const arr: any = [];
     for (let index = 0; index < 40; index++) {
       arr.push({
@@ -271,11 +272,10 @@ export function getBasicData() {
     }
     return arr;
   })();
-  return data;
 }
 
 export function getTreeTableData() {
-  const data: any = (() => {
+  return (() => {
     const arr: any = [];
     for (let index = 0; index < 40; index++) {
       arr.push({
@@ -301,6 +301,4 @@ export function getTreeTableData() {
     }
     return arr;
   })();
-
-  return data;
 }

+ 13 - 8
Vben2/src/views/sys/error-log/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="p-4">
     <template v-for="src in imgList" :key="src">
-      <img :src="src" v-show="false" />
+      <img :src="src" v-show="false" alt="" />
     </template>
     <DetailModal :info="rowInfo" @register="registerModal" />
     <BasicTable @register="register" class="error-handle-table">
@@ -16,12 +16,17 @@
           {{ t('sys.errorLog.fireAjaxError') }}
         </a-button>
       </template>
-      <template #action="{ record }">
-        <TableAction
-          :actions="[
-            { label: t('sys.errorLog.tableActionDesc'), onClick: handleDetail.bind(null, record) },
-          ]"
-        />
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'action'">
+          <TableAction
+            :actions="[
+              {
+                label: t('sys.errorLog.tableActionDesc'),
+                onClick: handleDetail.bind(null, record),
+              },
+            ]"
+          />
+        </template>
       </template>
     </BasicTable>
   </div>
@@ -52,7 +57,7 @@
       width: 80,
       title: 'Action',
       dataIndex: 'action',
-      slots: { customRender: 'action' },
+      // slots: { customRender: 'action' },
     },
   });
   const [registerModal, { openModal }] = useModal();