Browse Source

feat: 完善xtable组件

xingyu 2 years ago
parent
commit
a984eac965

+ 157 - 43
yudao-ui-admin-vue3/src/components/XTable/src/XTable.vue

@@ -12,6 +12,12 @@ import { useAppStore } from '@/store/modules/app'
 import { useDesign } from '@/hooks/web/useDesign'
 import { XTableProps } from './type'
 import { isBoolean, isFunction } from '@/utils/is'
+import { useMessage } from '@/hooks/web/useMessage'
+import download from '@/utils/download'
+import { useI18n } from '@/hooks/web/useI18n'
+
+const { t } = useI18n()
+const message = useMessage() // 消息弹窗
 
 const appStore = useAppStore()
 
@@ -21,30 +27,6 @@ const prefixCls = getPrefixCls('x-vxe-table')
 const attrs = useAttrs()
 const emit = defineEmits(['register'])
 
-const props = defineProps({
-  options: {
-    type: Object as PropType<XTableProps>,
-    default: () => {}
-  }
-})
-const innerProps = ref<Partial<XTableProps>>()
-
-const getProps = computed(() => {
-  const options = innerProps.value || props.options
-  options.size = currentSize as any
-  options.height = 700
-  getColumnsConfig(options)
-  getProxyConfig(options)
-  getPageConfig(options)
-  getToolBarConfig(options)
-  // console.log(options);
-  return {
-    ...options,
-    ...attrs
-  }
-})
-
-const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
 watch(
   () => appStore.getIsDark,
   () => {
@@ -57,6 +39,7 @@ watch(
   },
   { immediate: true }
 )
+
 const currentSize = computed(() => {
   let resSize: SizeType = 'small'
   const appsize = appStore.getCurrentSize
@@ -74,25 +57,42 @@ const currentSize = computed(() => {
   return resSize
 })
 
-const reload = () => {
-  const g = unref(xGrid)
-  if (!g) {
-    return
+const props = defineProps({
+  options: {
+    type: Object as PropType<XTableProps>,
+    default: () => {}
   }
-  g.commitProxy('query')
-}
+})
+const innerProps = ref<Partial<XTableProps>>()
 
-const getSearchData = () => {
-  const g = unref(xGrid)
-  if (!g) {
-    return
+const getProps = computed(() => {
+  const options = innerProps.value || props.options
+  options.size = currentSize as any
+  options.height = 700
+  getOptionInitConfig(options)
+  getColumnsConfig(options)
+  getProxyConfig(options)
+  getPageConfig(options)
+  getToolBarConfig(options)
+  // console.log(options);
+  return {
+    ...options,
+    ...attrs
   }
-  const queryParams = Object.assign({}, JSON.parse(JSON.stringify(g.getProxyInfo()?.form)))
-  return queryParams
-}
+})
+
+const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
 
 let proxyForm = false
 
+const getOptionInitConfig = (options: XTableProps) => {
+  options.size = currentSize as any
+  options.rowConfig = {
+    isCurrent: true, // 当鼠标点击行时,是否要高亮当前行
+    isHover: true // 当鼠标移到行时,是否要高亮当前行
+  }
+}
+
 // columns
 const getColumnsConfig = (options: XTableProps) => {
   const { allSchemas } = options
@@ -131,21 +131,55 @@ const getProxyConfig = (options: XTableProps) => {
           if (options.params) {
             queryParams = Object.assign(queryParams, options.params)
           }
-          queryParams.pageSize = page.currentPage
-          queryParams.page = page.pageSize
-
+          if (!options?.treeConfig) {
+            queryParams.pageSize = page.pageSize
+            queryParams.pageNo = page.currentPage
+          }
           return new Promise(async (resolve) => {
             resolve(await getListApi(queryParams))
           })
+        },
+        delete: ({ body }) => {
+          return new Promise(async (resolve) => {
+            if (options.deleteApi) {
+              resolve(await options.deleteApi(JSON.stringify(body)))
+            } else {
+              Promise.reject('未设置deleteApi')
+            }
+          })
+        },
+        queryAll: ({ form }) => {
+          const queryParams = Object.assign({}, JSON.parse(JSON.stringify(form)))
+          return new Promise(async (resolve) => {
+            if (options.getAllListApi) {
+              resolve(await options.getAllListApi(queryParams))
+            } else {
+              resolve(await getListApi(queryParams))
+            }
+          })
         }
       }
     }
   }
+  if (options.exportListApi) {
+    options.exportConfig = {
+      filename: options?.exportName,
+      // 默认选中类型
+      type: 'csv',
+      // 自定义数据量列表
+      modes: options?.getAllListApi ? ['current', 'all'] : ['current'],
+      columns: options?.allSchemas?.printSchema
+    }
+  }
 }
 
 // 分页
 const getPageConfig = (options: XTableProps) => {
-  const { pagination, pagerConfig } = options
+  const { pagination, pagerConfig, treeConfig } = options
+  if (treeConfig) {
+    options.treeConfig = options.treeConfig
+    return
+  }
   if (pagerConfig) return
   if (pagination) {
     if (isBoolean(pagination)) {
@@ -171,6 +205,28 @@ const getPageConfig = (options: XTableProps) => {
       return
     }
     options.pagerConfig = pagination
+  } else {
+    if (pagination != false) {
+      options.pagerConfig = {
+        border: false, // 带边框
+        background: true, // 带背景颜色
+        perfect: false, // 配套的样式
+        pageSize: 10, // 每页大小
+        pagerCount: 7, // 显示页码按钮的数量
+        autoHidden: false, // 当只有一页时自动隐藏
+        pageSizes: [5, 10, 20, 30, 50, 100], // 每页大小选项列表
+        layouts: [
+          'PrevJump',
+          'PrevPage',
+          'JumpNumber',
+          'NextPage',
+          'NextJump',
+          'Sizes',
+          'FullJump',
+          'Total'
+        ]
+      }
+    }
   }
 }
 
@@ -190,12 +246,70 @@ const getToolBarConfig = (options: XTableProps) => {
   }
 }
 
+// 刷新列表
+const reload = () => {
+  const g = unref(xGrid)
+  if (!g) {
+    return
+  }
+  g.commitProxy('query')
+}
+
+// 删除
+const deleteData = async (ids: string | number) => {
+  const g = unref(xGrid)
+  if (!g) {
+    return
+  }
+  const options = innerProps.value || props.options
+  if (!options.deleteApi) {
+    console.error('未传入delListApi')
+    return
+  }
+  return new Promise(async () => {
+    message.delConfirm().then(async () => {
+      await (options?.deleteApi && options?.deleteApi(ids))
+      message.success(t('common.delSuccess'))
+      // 刷新列表
+      reload()
+    })
+  })
+}
+
+// 导出
+const exportList = async (fileName?: string) => {
+  const g = unref(xGrid)
+  if (!g) {
+    return
+  }
+  const options = innerProps.value || props.options
+  if (!options?.exportListApi) {
+    console.error('未传入exportListApi')
+    return
+  }
+  const queryParams = Object.assign({}, JSON.parse(JSON.stringify(g.getProxyInfo()?.form)))
+  message.exportConfirm().then(async () => {
+    const res = await (options?.exportListApi && options?.exportListApi(queryParams))
+    download.excel(res as unknown as Blob, fileName ? fileName : 'excel.xls')
+  })
+}
+
+// 获取查询参数
+const getSearchData = () => {
+  const g = unref(xGrid)
+  if (!g) {
+    return
+  }
+  const queryParams = Object.assign({}, JSON.parse(JSON.stringify(g.getProxyInfo()?.form)))
+  return queryParams
+}
+
 const setProps = (prop: Partial<XTableProps>) => {
   innerProps.value = { ...unref(innerProps), ...prop }
 }
 
-defineExpose({ reload, Ref: xGrid, getSearchData })
-emit('register', { reload, getSearchData, setProps })
+defineExpose({ reload, Ref: xGrid, getSearchData, deleteData, exportList })
+emit('register', { reload, getSearchData, setProps, deleteData, exportList })
 </script>
 <style lang="scss">
 @import './style/index.scss';

+ 6 - 1
yudao-ui-admin-vue3/src/components/XTable/src/type.ts

@@ -1,11 +1,16 @@
 import { CrudSchema } from '@/hooks/web/useCrudSchemas'
-import type { VxeGridProps, VxeGridPropTypes } from 'vxe-table'
+import type { VxeGridProps, VxeGridPropTypes, VxeTablePropTypes } from 'vxe-table'
 
 export type XTableProps<D = any> = VxeGridProps<D> & {
   allSchemas?: CrudSchema
+  height?: number // 高度 默认730
+  topActionSlots?: boolean // 是否开启表格内顶部操作栏插槽
+  treeConfig?: VxeTablePropTypes.TreeConfig // 树形表单配置
   getListApi?: Function
+  getAllListApi?: Function
   deleteApi?: Function
   exportListApi?: Function
+  exportName?: string // 导出文件夹名称
   params?: any
   pagination?: boolean | VxeGridPropTypes.PagerConfig
   toolBar?: boolean | VxeGridPropTypes.ToolbarConfig

+ 5 - 1
yudao-ui-admin-vue3/src/hooks/web/useXTable.ts

@@ -4,6 +4,8 @@ import { XTableProps } from '@/components/XTable/src/type'
 export interface tableMethod {
   reload: () => void
   setProps: (props: XTableProps) => void
+  deleteData: (ids: string | number) => void
+  exportList: (fileName?: string) => void
 }
 
 export function useXTable(props: XTableProps): [Function, tableMethod] {
@@ -22,7 +24,9 @@ export function useXTable(props: XTableProps): [Function, tableMethod] {
   }
   const methods: tableMethod = {
     reload: () => getInstance().reload(),
-    setProps: (props) => getInstance().setProps(props)
+    setProps: (props) => getInstance().setProps(props),
+    deleteData: (ids: string | number) => getInstance().deleteData(ids),
+    exportList: (fileName?: string) => getInstance().exportList(fileName)
   }
   return [register, methods]
 }

+ 1 - 18
yudao-ui-admin-vue3/src/plugins/vxeTable/index.ts

@@ -1,9 +1,7 @@
-import { App, unref, watch } from 'vue'
+import { App, unref } from 'vue'
 import XEUtils from 'xe-utils'
-import './index.scss'
 import './renderer'
 import { i18n } from '@/plugins/vueI18n'
-import { useAppStore } from '@/store/modules/app'
 import zhCN from 'vxe-table/lib/locale/lang/zh-CN'
 import enUS from 'vxe-table/lib/locale/lang/en-US'
 import {
@@ -46,21 +44,6 @@ import {
   Table
 } from 'vxe-table'
 
-const appStore = useAppStore()
-watch(
-  () => appStore.getIsDark,
-  () => {
-    if (appStore.getIsDark) {
-      import('./theme/dark.scss')
-    } else {
-      import('./theme/light.scss')
-    }
-  },
-  {
-    deep: true,
-    immediate: true
-  }
-)
 // 全局默认参数
 VXETable.setup({
   size: 'medium', // 全局尺寸