Browse Source

feat: add vxe-table

xingyu 2 years ago
parent
commit
aa3aa56140

+ 162 - 12
yudao-ui-admin-vue3/src/components/ProTable/src/ProTable.vue

@@ -1,35 +1,185 @@
 <script setup lang="ts">
 import { PropType, reactive, ref } from 'vue'
-import { VxeGrid, VxeGridProps, VxeTableInstance } from 'vxe-table'
+import { propTypes } from '@/utils/propTypes'
+import { VxeGrid, VxeGridProps, VXETable, VxeTableInstance } from 'vxe-table'
+import XEUtils from 'xe-utils'
 
 const props = defineProps({
-  options: {
-    type: Object as PropType<VxeGridProps>,
-    default: () => ({})
-  }
+  columns: {
+    type: Array as PropType<any[]>,
+    default: () => []
+  },
+  form: {
+    type: Array as PropType<any[]>,
+    default: () => []
+  },
+  api: propTypes.string.def('')
 })
 const xGrid = ref<VxeTableInstance>()
 
 const gridOptions = reactive<VxeGridProps>({
-  height: 300,
+  id: 'crud',
+  height: 600,
+  showHeaderOverflow: true,
+  showOverflow: true,
   align: null,
+  loading: true,
   columnConfig: {
     resizable: true
   },
+  formConfig: {
+    titleWidth: 100,
+    titleAlign: 'right',
+    items: []
+  },
+  pagerConfig: {
+    pageSize: 10,
+    pageSizes: [5, 10, 15, 20, 50, 100, 200, 500]
+  },
   columns: [],
-  toolbarConfig: {},
-  data: []
+  toolbarConfig: {
+    buttons: [
+      { code: 'insert', name: '新增' },
+      { code: 'delete', name: '删除' },
+      { code: 'save', name: '保存', status: 'success' }
+    ],
+    refresh: true,
+    import: true,
+    export: true,
+    print: true,
+    zoom: true,
+    custom: true
+  },
+  importConfig: {
+    remote: true,
+    types: ['xlsx'],
+    modes: ['insert'],
+    // 自定义服务端导入
+    async importMethod({ file }) {
+      const formBody = new FormData()
+      formBody.append('file', file)
+      try {
+        const response = await fetch(`/api/pub/import`, {
+          method: 'POST',
+          body: formBody
+        })
+        const data = await response.json()
+        VXETable.modal.message({
+          content: `成功导入 ${data.result.insertRows} 条记录!`,
+          status: 'success'
+        })
+        // 导入完成,刷新表格
+        xGrid.value.commitProxy('query')
+      } catch {
+        VXETable.modal.message({ content: '导入失败,请检查数据是否正确!', status: 'error' })
+      }
+    }
+  },
+  proxyConfig: {
+    seq: true, // 启用动态序号代理,每一页的序号会根据当前页数变化
+    sort: true, // 启用排序代理,当点击排序时会自动触发 query 行为
+    filter: true, // 启用筛选代理,当点击筛选时会自动触发 query 行为
+    form: true, // 启用表单代理,当点击表单提交按钮时会自动触发 reload 行为
+    // 对应响应结果 { result: [], page: { total: 100 } }
+    props: {
+      result: 'result', // 配置响应结果列表字段
+      total: 'page.total' // 配置响应结果总页数字段
+    },
+    // 只接收Promise,具体实现自由发挥
+    ajax: {
+      // 当点击工具栏查询按钮或者手动提交指令 query或reload 时会被触发
+      query: ({ page, sorts, filters, form }) => {
+        const queryParams: any = Object.assign({}, form)
+        // 处理排序条件
+        const firstSort = sorts[0]
+        if (firstSort) {
+          queryParams.sort = firstSort.field
+          queryParams.order = firstSort.order
+        }
+        // 处理筛选条件
+        filters.forEach(({ field, values }) => {
+          queryParams[field] = values.join(',')
+        })
+        return fetch(
+          props.api + `/list${page.pageSize}/${page.currentPage}?${XEUtils.serialize(queryParams)}`
+        ).then((response) => response.json())
+      },
+      // 当点击工具栏删除按钮或者手动提交指令 delete 时会被触发
+      delete: ({ body }) => {
+        return fetch(props.api + `/save`, {
+          method: 'POST',
+          headers: { 'Content-Type': 'application/json' },
+          body: JSON.stringify(body)
+        }).then((response) => response.json())
+      },
+      // 当点击工具栏保存按钮或者手动提交指令 save 时会被触发
+      save: ({ body }) => {
+        return fetch(props.api + `/save`, {
+          method: 'POST',
+          headers: { 'Content-Type': 'application/json' },
+          body: JSON.stringify(body)
+        }).then((response) => response.json())
+      }
+    }
+  },
+  exportConfig: {
+    remote: true,
+    types: ['xlsx'],
+    modes: ['current', 'selected', 'all'],
+    // 自定义服务端导出
+    async exportMethod({ options }) {
+      const $grid = xGrid.value
+      const proxyInfo = $grid.getProxyInfo()
+      // 传给服务端的参数
+      const body = {
+        filename: options.filename,
+        sheetName: options.sheetName,
+        isHeader: options.isHeader,
+        original: options.original,
+        mode: options.mode,
+        pager: proxyInfo ? proxyInfo.pager : null,
+        ids: options.mode === 'selected' ? options.data.map((item) => item.id) : [],
+        fields: options.columns.map((column) => {
+          return {
+            field: column.field,
+            title: column.title
+          }
+        })
+      }
+      // 开始服务端导出
+      try {
+        const response = await fetch(`/api/pub/export`, {
+          method: 'POST',
+          headers: { 'Content-Type': 'application/json' },
+          body: JSON.stringify(body)
+        })
+        const data = await response.json()
+        if (data.id) {
+          VXETable.modal.message({ content: '导出成功,开始下载', status: 'success' })
+          // 读取路径,请求文件
+          fetch(`/api/pub/export/download/${data.id}`).then((response_1) => {
+            response_1.blob().then((blob) => {
+              // 开始下载
+              VXETable.saveFile({ filename: '导出数据', type: 'xlsx', content: blob })
+            })
+          })
+        }
+      } catch {
+        VXETable.modal.message({ content: '导出失败!', status: 'error' })
+      }
+    }
+  }
 })
 const init = () => {
-  console.log(props.options)
+  gridOptions.columns = props.columns
+  gridOptions.formConfig.items = props.form
+  gridOptions.loading = false
 }
 init()
 </script>
 
 <template>
-  <ContentWrap>
-    <vxe-grid ref="xGrid" v-bind="gridOptions" show-footer class="pro-table-scrollbar" />
-  </ContentWrap>
+  <vxe-grid ref="xGrid" v-bind="gridOptions" class="pro-table-scrollbar" />
 </template>
 
 <style scoped>

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

@@ -72,7 +72,7 @@ VXETable.setup({
     clearable: true
   },
   i18n: (key, args) => {
-    return unref(i18n.global.locale) === 'zh'
+    return unref(i18n.global.locale) === 'zh-CN'
       ? XEUtils.toFormatString(XEUtils.get(zhCN, key), args)
       : XEUtils.toFormatString(XEUtils.get(enUS, key), args)
   }