Commit aa3aa56140fdb1462ffb94443084ff8340ee389e

Authored by xingyu
1 parent 4e415486

feat: add vxe-table

yudao-ui-admin-vue3/src/components/ProTable/src/ProTable.vue
1 1 <script setup lang="ts">
2 2 import { PropType, reactive, ref } from 'vue'
3   -import { VxeGrid, VxeGridProps, VxeTableInstance } from 'vxe-table'
  3 +import { propTypes } from '@/utils/propTypes'
  4 +import { VxeGrid, VxeGridProps, VXETable, VxeTableInstance } from 'vxe-table'
  5 +import XEUtils from 'xe-utils'
4 6  
5 7 const props = defineProps({
6   - options: {
7   - type: Object as PropType<VxeGridProps>,
8   - default: () => ({})
9   - }
  8 + columns: {
  9 + type: Array as PropType<any[]>,
  10 + default: () => []
  11 + },
  12 + form: {
  13 + type: Array as PropType<any[]>,
  14 + default: () => []
  15 + },
  16 + api: propTypes.string.def('')
10 17 })
11 18 const xGrid = ref<VxeTableInstance>()
12 19  
13 20 const gridOptions = reactive<VxeGridProps>({
14   - height: 300,
  21 + id: 'crud',
  22 + height: 600,
  23 + showHeaderOverflow: true,
  24 + showOverflow: true,
15 25 align: null,
  26 + loading: true,
16 27 columnConfig: {
17 28 resizable: true
18 29 },
  30 + formConfig: {
  31 + titleWidth: 100,
  32 + titleAlign: 'right',
  33 + items: []
  34 + },
  35 + pagerConfig: {
  36 + pageSize: 10,
  37 + pageSizes: [5, 10, 15, 20, 50, 100, 200, 500]
  38 + },
19 39 columns: [],
20   - toolbarConfig: {},
21   - data: []
  40 + toolbarConfig: {
  41 + buttons: [
  42 + { code: 'insert', name: '新增' },
  43 + { code: 'delete', name: '删除' },
  44 + { code: 'save', name: '保存', status: 'success' }
  45 + ],
  46 + refresh: true,
  47 + import: true,
  48 + export: true,
  49 + print: true,
  50 + zoom: true,
  51 + custom: true
  52 + },
  53 + importConfig: {
  54 + remote: true,
  55 + types: ['xlsx'],
  56 + modes: ['insert'],
  57 + // 自定义服务端导入
  58 + async importMethod({ file }) {
  59 + const formBody = new FormData()
  60 + formBody.append('file', file)
  61 + try {
  62 + const response = await fetch(`/api/pub/import`, {
  63 + method: 'POST',
  64 + body: formBody
  65 + })
  66 + const data = await response.json()
  67 + VXETable.modal.message({
  68 + content: `成功导入 ${data.result.insertRows} 条记录!`,
  69 + status: 'success'
  70 + })
  71 + // 导入完成,刷新表格
  72 + xGrid.value.commitProxy('query')
  73 + } catch {
  74 + VXETable.modal.message({ content: '导入失败,请检查数据是否正确!', status: 'error' })
  75 + }
  76 + }
  77 + },
  78 + proxyConfig: {
  79 + seq: true, // 启用动态序号代理,每一页的序号会根据当前页数变化
  80 + sort: true, // 启用排序代理,当点击排序时会自动触发 query 行为
  81 + filter: true, // 启用筛选代理,当点击筛选时会自动触发 query 行为
  82 + form: true, // 启用表单代理,当点击表单提交按钮时会自动触发 reload 行为
  83 + // 对应响应结果 { result: [], page: { total: 100 } }
  84 + props: {
  85 + result: 'result', // 配置响应结果列表字段
  86 + total: 'page.total' // 配置响应结果总页数字段
  87 + },
  88 + // 只接收Promise,具体实现自由发挥
  89 + ajax: {
  90 + // 当点击工具栏查询按钮或者手动提交指令 query或reload 时会被触发
  91 + query: ({ page, sorts, filters, form }) => {
  92 + const queryParams: any = Object.assign({}, form)
  93 + // 处理排序条件
  94 + const firstSort = sorts[0]
  95 + if (firstSort) {
  96 + queryParams.sort = firstSort.field
  97 + queryParams.order = firstSort.order
  98 + }
  99 + // 处理筛选条件
  100 + filters.forEach(({ field, values }) => {
  101 + queryParams[field] = values.join(',')
  102 + })
  103 + return fetch(
  104 + props.api + `/list${page.pageSize}/${page.currentPage}?${XEUtils.serialize(queryParams)}`
  105 + ).then((response) => response.json())
  106 + },
  107 + // 当点击工具栏删除按钮或者手动提交指令 delete 时会被触发
  108 + delete: ({ body }) => {
  109 + return fetch(props.api + `/save`, {
  110 + method: 'POST',
  111 + headers: { 'Content-Type': 'application/json' },
  112 + body: JSON.stringify(body)
  113 + }).then((response) => response.json())
  114 + },
  115 + // 当点击工具栏保存按钮或者手动提交指令 save 时会被触发
  116 + save: ({ body }) => {
  117 + return fetch(props.api + `/save`, {
  118 + method: 'POST',
  119 + headers: { 'Content-Type': 'application/json' },
  120 + body: JSON.stringify(body)
  121 + }).then((response) => response.json())
  122 + }
  123 + }
  124 + },
  125 + exportConfig: {
  126 + remote: true,
  127 + types: ['xlsx'],
  128 + modes: ['current', 'selected', 'all'],
  129 + // 自定义服务端导出
  130 + async exportMethod({ options }) {
  131 + const $grid = xGrid.value
  132 + const proxyInfo = $grid.getProxyInfo()
  133 + // 传给服务端的参数
  134 + const body = {
  135 + filename: options.filename,
  136 + sheetName: options.sheetName,
  137 + isHeader: options.isHeader,
  138 + original: options.original,
  139 + mode: options.mode,
  140 + pager: proxyInfo ? proxyInfo.pager : null,
  141 + ids: options.mode === 'selected' ? options.data.map((item) => item.id) : [],
  142 + fields: options.columns.map((column) => {
  143 + return {
  144 + field: column.field,
  145 + title: column.title
  146 + }
  147 + })
  148 + }
  149 + // 开始服务端导出
  150 + try {
  151 + const response = await fetch(`/api/pub/export`, {
  152 + method: 'POST',
  153 + headers: { 'Content-Type': 'application/json' },
  154 + body: JSON.stringify(body)
  155 + })
  156 + const data = await response.json()
  157 + if (data.id) {
  158 + VXETable.modal.message({ content: '导出成功,开始下载', status: 'success' })
  159 + // 读取路径,请求文件
  160 + fetch(`/api/pub/export/download/${data.id}`).then((response_1) => {
  161 + response_1.blob().then((blob) => {
  162 + // 开始下载
  163 + VXETable.saveFile({ filename: '导出数据', type: 'xlsx', content: blob })
  164 + })
  165 + })
  166 + }
  167 + } catch {
  168 + VXETable.modal.message({ content: '导出失败!', status: 'error' })
  169 + }
  170 + }
  171 + }
22 172 })
23 173 const init = () => {
24   - console.log(props.options)
  174 + gridOptions.columns = props.columns
  175 + gridOptions.formConfig.items = props.form
  176 + gridOptions.loading = false
25 177 }
26 178 init()
27 179 </script>
28 180  
29 181 <template>
30   - <ContentWrap>
31   - <vxe-grid ref="xGrid" v-bind="gridOptions" show-footer class="pro-table-scrollbar" />
32   - </ContentWrap>
  182 + <vxe-grid ref="xGrid" v-bind="gridOptions" class="pro-table-scrollbar" />
33 183 </template>
34 184  
35 185 <style scoped>
... ...
yudao-ui-admin-vue3/src/plugins/vxeTable/index.ts
... ... @@ -72,7 +72,7 @@ VXETable.setup({
72 72 clearable: true
73 73 },
74 74 i18n: (key, args) => {
75   - return unref(i18n.global.locale) === 'zh'
  75 + return unref(i18n.global.locale) === 'zh-CN'
76 76 ? XEUtils.toFormatString(XEUtils.get(zhCN, key), args)
77 77 : XEUtils.toFormatString(XEUtils.get(enUS, key), args)
78 78 }
... ...