Commit 562282b2ad6c608abf257bd7d3ada3e22dc1abed

Authored by xingyu4j
1 parent e6acf9e8

refactor: file vxe

yudao-ui-admin-vue3/src/api/infra/fileConfig/types.ts
... ... @@ -15,7 +15,7 @@ export type FileConfigVO = {
15 15 id: number
16 16 name: string
17 17 storage: string
18   - primary: number
  18 + master: boolean
19 19 visible: boolean
20 20 config: ConfigType
21 21 remark: string
... ...
yudao-ui-admin-vue3/src/api/infra/fileList/index.ts
1 1 import request from '@/config/axios'
2 2  
  3 +export type FileVO = {
  4 + id: number
  5 + path: string
  6 + url: string
  7 + size: string
  8 + type: string
  9 + createTime: string
  10 +}
  11 +
  12 +export interface FilePageReqVO extends PageParam {
  13 + name?: string
  14 + createTime?: string[]
  15 +}
  16 +
3 17 // 查询文件列表
4   -export const getFilePageApi = (params) => {
  18 +export const getFilePageApi = (params: FilePageReqVO) => {
5 19 return request.get({ url: '/infra/file/page', params })
6 20 }
7 21  
... ...
yudao-ui-admin-vue3/src/api/infra/fileList/types.ts deleted
1   -export type FileVO = {
2   - id: number
3   - path: string
4   - url: string
5   - size: string
6   - type: string
7   - createTime: string
8   -}
yudao-ui-admin-vue3/src/plugins/vxeTable/renderer/img.tsx
1 1 import { VXETable } from 'vxe-table'
  2 +import { ElImage } from 'element-plus'
2 3  
3 4 // 图片渲染
4 5 VXETable.renderer.add('XImg', {
... ... @@ -6,13 +7,13 @@ VXETable.renderer.add('XImg', {
6 7 renderDefault(_renderOpts, params) {
7 8 const { row, column } = params
8 9 return (
9   - <el-image
  10 + <ElImage
10 11 style="width: 80px; height: 50px"
11 12 src={row[column.field]}
12 13 key={row[column.field]}
13 14 fit="contain"
14 15 lazy
15   - ></el-image>
  16 + ></ElImage>
16 17 )
17 18 }
18 19 })
... ...
yudao-ui-admin-vue3/src/views/infra/fileConfig/fileConfig.data.ts
1 1 import { reactive } from 'vue'
2 2 import { useI18n } from '@/hooks/web/useI18n'
3 3 import { required } from '@/utils/formRules'
4   -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
5 4 import { DICT_TYPE } from '@/utils/dict'
  5 +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
6 6 const { t } = useI18n() // 国际化
7 7  
8 8 // 表单校验
... ... @@ -25,80 +25,56 @@ export const rules = reactive({
25 25 })
26 26  
27 27 // CrudSchema
28   -const crudSchemas = reactive<CrudSchema[]>([
29   - {
30   - label: t('common.index'),
31   - field: 'id',
32   - type: 'index',
33   - form: {
34   - show: false
  28 +const crudSchemas = reactive<VxeCrudSchema>({
  29 + primaryKey: 'id',
  30 + primaryType: 'seq',
  31 + action: true,
  32 + actionWidth: '400px',
  33 + columns: [
  34 + {
  35 + title: '配置名',
  36 + field: 'name',
  37 + isSearch: true
35 38 },
36   - detail: {
37   - show: false
38   - }
39   - },
40   - {
41   - label: '配置名',
42   - field: 'name',
43   - search: {
44   - show: true
45   - }
46   - },
47   - {
48   - label: '存储器',
49   - field: 'storage',
50   - dictType: DICT_TYPE.INFRA_FILE_STORAGE,
51   - dictClass: 'number',
52   - search: {
53   - show: true
54   - }
55   - },
56   - {
57   - label: '主配置',
58   - field: 'primary',
59   - dictType: DICT_TYPE.INFRA_BOOLEAN_STRING,
60   - dictClass: 'number'
61   - },
62   - {
63   - label: t('form.remark'),
64   - field: 'remark',
65   - form: {
66   - component: 'Input',
67   - componentProps: {
68   - type: 'textarea',
69   - rows: 4
70   - },
71   - colProps: {
72   - span: 24
73   - }
74   - }
75   - },
76   - {
77   - label: t('common.createTime'),
78   - field: 'createTime',
79   - form: {
80   - show: false
  39 + {
  40 + title: '存储器',
  41 + field: 'storage',
  42 + dictType: DICT_TYPE.INFRA_FILE_STORAGE,
  43 + dictClass: 'number',
  44 + isSearch: true
81 45 },
82   - search: {
83   - show: true,
84   - component: 'DatePicker',
85   - componentProps: {
86   - type: 'datetimerange',
87   - valueFormat: 'YYYY-MM-DD HH:mm:ss',
88   - defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
  46 + {
  47 + title: '主配置',
  48 + field: 'master',
  49 + dictType: DICT_TYPE.INFRA_BOOLEAN_STRING,
  50 + dictClass: 'boolean'
  51 + },
  52 + {
  53 + title: t('form.remark'),
  54 + field: 'remark',
  55 + form: {
  56 + component: 'Input',
  57 + componentProps: {
  58 + type: 'textarea',
  59 + rows: 4
  60 + },
  61 + colProps: {
  62 + span: 24
  63 + }
89 64 }
90   - }
91   - },
92   - {
93   - label: t('table.action'),
94   - field: 'action',
95   - width: '400px',
96   - form: {
97   - show: false
98 65 },
99   - detail: {
100   - show: false
  66 + {
  67 + title: t('common.createTime'),
  68 + field: 'createTime',
  69 + formatter: 'formatDate',
  70 + isForm: false,
  71 + search: {
  72 + show: true,
  73 + itemRender: {
  74 + name: 'XDataTimePicker'
  75 + }
  76 + }
101 77 }
102   - }
103   -])
104   -export const { allSchemas } = useCrudSchemas(crudSchemas)
  78 + ]
  79 +})
  80 +export const { allSchemas } = useVxeCrudSchemas(crudSchemas)
... ...
yudao-ui-admin-vue3/src/views/infra/fileConfig/index.vue
  1 +<template>
  2 + <ContentWrap>
  3 + <!-- 列表 -->
  4 + <vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar">
  5 + <template #toolbar_buttons>
  6 + <!-- 操作:新增 -->
  7 + <XButton
  8 + type="primary"
  9 + preIcon="ep:zoom-in"
  10 + :title="t('action.add')"
  11 + v-hasPermi="['infra:file-config:create']"
  12 + @click="handleCreate()"
  13 + />
  14 + </template>
  15 + <template #actionbtns_default="{ row }">
  16 + <XTextButton
  17 + preIcon="ep:edit"
  18 + :title="t('action.edit')"
  19 + v-hasPermi="['infra:file-config:update']"
  20 + @click="handleUpdate(row.id)"
  21 + />
  22 + <XTextButton
  23 + preIcon="ep:view"
  24 + :title="t('action.detail')"
  25 + v-hasPermi="['infra:file-config:query']"
  26 + @click="handleDetail(row.id)"
  27 + />
  28 + <XTextButton
  29 + preIcon="ep:flag"
  30 + title="主配置"
  31 + v-hasPermi="['infra:file-config:update']"
  32 + @click="handleMaster(row)"
  33 + />
  34 + <XTextButton
  35 + preIcon="ep:share"
  36 + :title="t('action.test')"
  37 + v-hasPermi="['infra:file-config:update']"
  38 + @click="handleUpdate(row.id)"
  39 + />
  40 + <XTextButton
  41 + preIcon="ep:delete"
  42 + :title="t('action.del')"
  43 + v-hasPermi="['infra:file-config:delete']"
  44 + @click="handleDelete(row.id)"
  45 + />
  46 + </template>
  47 + </vxe-grid>
  48 + </ContentWrap>
  49 +
  50 + <XModal v-model="dialogVisible" :title="dialogTitle">
  51 + <!-- 对话框(添加 / 修改) -->
  52 + <Form
  53 + v-if="['create', 'update'].includes(actionType)"
  54 + :schema="allSchemas.formSchema"
  55 + :rules="rules"
  56 + ref="formRef"
  57 + />
  58 + <!-- 对话框(详情) -->
  59 + <Descriptions
  60 + v-if="actionType === 'detail'"
  61 + :schema="allSchemas.detailSchema"
  62 + :data="detailData"
  63 + />
  64 + <!-- 操作按钮 -->
  65 + <template #footer>
  66 + <!-- 按钮:保存 -->
  67 + <XButton
  68 + v-if="['create', 'update'].includes(actionType)"
  69 + type="primary"
  70 + :title="t('action.save')"
  71 + :loading="actionLoading"
  72 + @click="submitForm()"
  73 + />
  74 + <!-- 按钮:关闭 -->
  75 + <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
  76 + </template>
  77 + </XModal>
  78 +</template>
1 79 <script setup lang="ts">
  80 +// 全局相关的 import
2 81 import { ref, unref } from 'vue'
3   -import dayjs from 'dayjs'
4   -import { DICT_TYPE } from '@/utils/dict'
5   -import { useTable } from '@/hooks/web/useTable'
6 82 import { useI18n } from '@/hooks/web/useI18n'
  83 +import { useMessage } from '@/hooks/web/useMessage'
  84 +import { useVxeGrid } from '@/hooks/web/useVxeGrid'
  85 +import { VxeGridInstance } from 'vxe-table'
7 86 import { FormExpose } from '@/components/Form'
  87 +// 业务相关的 import
  88 +import * as FileConfigApi from '@/api/infra/fileConfig'
8 89 import type { FileConfigVO } from '@/api/infra/fileConfig/types'
9 90 import { rules, allSchemas } from './fileConfig.data'
10   -import * as FileConfigApi from '@/api/infra/fileConfig'
11   -import { useMessage } from '@/hooks/web/useMessage'
12   -const message = useMessage()
13   -const { t } = useI18n() // 国际化
14 91  
15   -// ========== 列表相关 ==========
16   -const { register, tableObject, methods } = useTable<FileConfigVO>({
  92 +const { t } = useI18n() // 国际化
  93 +const message = useMessage() // 消息弹窗
  94 +// 列表相关的变量
  95 +const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
  96 +const { gridOptions, getList, deleteData } = useVxeGrid<FileConfigVO>({
  97 + allSchemas: allSchemas,
17 98 getListApi: FileConfigApi.getFileConfigPageApi,
18   - delListApi: FileConfigApi.deleteFileConfigApi
  99 + deleteApi: FileConfigApi.deleteFileConfigApi
19 100 })
20   -const { getList, setSearchParams, delList } = methods
21 101  
22 102 // ========== CRUD 相关 ==========
23 103 const actionLoading = ref(false) // 遮罩层
... ... @@ -25,7 +105,7 @@ const actionType = ref(&#39;&#39;) // 操作按钮的类型
25 105 const dialogVisible = ref(false) // 是否显示弹出层
26 106 const dialogTitle = ref('edit') // 弹出层标题
27 107 const formRef = ref<FormExpose>() // 表单 Ref
28   -
  108 +const detailData = ref() // 详情 Ref
29 109 // 设置标题
30 110 const setDialogTile = (type: string) => {
31 111 dialogTitle.value = t('action.' + type)
... ... @@ -39,23 +119,36 @@ const handleCreate = () =&gt; {
39 119 }
40 120  
41 121 // 修改操作
42   -const handleUpdate = async (row: FileConfigVO) => {
  122 +const handleUpdate = async (rowId: number) => {
43 123 setDialogTile('update')
44 124 // 设置数据
45   - const res = await FileConfigApi.getFileConfigApi(row.id)
  125 + const res = await FileConfigApi.getFileConfigApi(rowId)
46 126 unref(formRef)?.setValues(res)
47 127 }
48 128  
  129 +// 详情操作
  130 +const handleDetail = async (rowId: number) => {
  131 + setDialogTile('detail')
  132 + // 设置数据
  133 + const res = await FileConfigApi.getFileConfigApi(rowId)
  134 + detailData.value = res
  135 +}
  136 +
49 137 // 主配置操作
50 138 const handleMaster = (row: FileConfigVO) => {
51 139 message
52 140 .confirm('是否确认修改配置【 ' + row.name + ' 】为主配置?', t('common.reminder'))
53 141 .then(async () => {
54 142 await FileConfigApi.updateFileConfigMasterApi(row.id)
55   - await getList()
  143 + await getList(xGrid)
56 144 })
57 145 }
58 146  
  147 +// 删除操作
  148 +const handleDelete = async (rowId: number) => {
  149 + await deleteData(xGrid, rowId)
  150 +}
  151 +
59 152 // 提交按钮
60 153 const submitForm = async () => {
61 154 const elForm = unref(formRef)?.getElFormRef()
... ... @@ -73,135 +166,12 @@ const submitForm = async () =&gt; {
73 166 await FileConfigApi.updateFileConfigApi(data)
74 167 message.success(t('common.updateSuccess'))
75 168 }
76   - // 操作成功,重新加载列表
77 169 dialogVisible.value = false
78   - await getList()
79 170 } finally {
80 171 actionLoading.value = false
  172 + await getList(xGrid)
81 173 }
82 174 }
83 175 })
84 176 }
85   -
86   -// ========== 详情相关 ==========
87   -const detailRef = ref() // 详情 Ref
88   -
89   -// 详情操作
90   -const handleDetail = async (row: FileConfigVO) => {
91   - // 设置数据
92   - detailRef.value = row
93   - setDialogTile('detail')
94   -}
95   -
96   -// ========== 初始化 ==========
97   -getList()
98 177 </script>
99   -
100   -<template>
101   - <!-- 搜索工作区 -->
102   - <ContentWrap>
103   - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
104   - </ContentWrap>
105   - <ContentWrap>
106   - <!-- 操作工具栏 -->
107   - <div class="mb-10px">
108   - <el-button type="primary" v-hasPermi="['infra:file-config:create']" @click="handleCreate">
109   - <Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}
110   - </el-button>
111   - </div>
112   - <!-- 列表 -->
113   - <Table
114   - :columns="allSchemas.tableColumns"
115   - :selection="false"
116   - :data="tableObject.tableList"
117   - :loading="tableObject.loading"
118   - :pagination="{
119   - total: tableObject.total
120   - }"
121   - v-model:pageSize="tableObject.pageSize"
122   - v-model:currentPage="tableObject.currentPage"
123   - @register="register"
124   - >
125   - <template #storage="{ row }">
126   - <DictTag :type="DICT_TYPE.INFRA_FILE_STORAGE" :value="row.storage" />
127   - </template>
128   - <template #primary="{ row }">
129   - <DictTag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="row.master" />
130   - </template>
131   - <template #createTime="{ row }">
132   - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
133   - </template>
134   - <template #action="{ row }">
135   - <el-button
136   - link
137   - type="primary"
138   - v-hasPermi="['infra:file-config:update']"
139   - @click="handleUpdate(row)"
140   - >
141   - <Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }}
142   - </el-button>
143   - <el-button
144   - link
145   - type="primary"
146   - v-hasPermi="['infra:file-config:update']"
147   - @click="handleDetail(row)"
148   - >
149   - <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}
150   - </el-button>
151   - <el-button
152   - link
153   - type="primary"
154   - v-hasPermi="['infra:file-config:update']"
155   - @click="handleMaster(row)"
156   - >
157   - <Icon icon="ep:flag" class="mr-1px" /> 主配置
158   - </el-button>
159   - <el-button
160   - link
161   - type="primary"
162   - v-hasPermi="['infra:file-config:update']"
163   - @click="handleUpdate(row)"
164   - >
165   - <Icon icon="ep:share" class="mr-1px" /> {{ t('action.test') }}
166   - </el-button>
167   - <el-button
168   - link
169   - type="primary"
170   - v-hasPermi="['infra:file-config:delete']"
171   - @click="delList(row.id, false)"
172   - >
173   - <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}
174   - </el-button>
175   - </template>
176   - </Table>
177   - </ContentWrap>
178   -
179   - <XModal v-model="dialogVisible" :title="dialogTitle">
180   - <!-- 对话框(添加 / 修改) -->
181   - <Form
182   - v-if="['create', 'update'].includes(actionType)"
183   - :schema="allSchemas.formSchema"
184   - :rules="rules"
185   - ref="formRef"
186   - />
187   - <!-- 对话框(详情) -->
188   - <Descriptions
189   - v-if="actionType === 'detail'"
190   - :schema="allSchemas.detailSchema"
191   - :data="detailRef"
192   - />
193   - <!-- 操作按钮 -->
194   - <template #footer>
195   - <!-- 按钮:保存 -->
196   - <XButton
197   - v-if="['create', 'update'].includes(actionType)"
198   - type="primary"
199   - :title="t('action.save')"
200   - :loading="actionLoading"
201   - @click="submitForm()"
202   - />
203   - <!-- 按钮:关闭 -->
204   - <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
205   - </template>
206   - </XModal>
207   -</template>
... ...
yudao-ui-admin-vue3/src/views/infra/fileList/fileList.data.ts
1 1 import { reactive } from 'vue'
2 2 import { useI18n } from '@/hooks/web/useI18n'
3   -import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
  3 +import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
4 4 const { t } = useI18n() // 国际化
5 5  
6 6 // CrudSchema
7   -const crudSchemas = reactive<CrudSchema[]>([
8   - {
9   - label: t('common.index'),
10   - field: 'id',
11   - type: 'index',
12   - form: {
13   - show: false
14   - },
15   - detail: {
16   - show: false
17   - }
18   - },
19   - {
20   - label: '文件名',
21   - field: 'path',
22   - search: {
23   - show: true
24   - }
25   - },
26   - {
27   - label: 'URL',
28   - field: 'url'
29   - },
30   - {
31   - label: '文件类型',
32   - field: 'type'
33   - },
34   - {
35   - label: t('common.createTime'),
36   - field: 'createTime',
37   - form: {
38   - show: false
  7 +const crudSchemas = reactive<VxeCrudSchema>({
  8 + primaryKey: 'id',
  9 + primaryType: 'seq',
  10 + action: true,
  11 + columns: [
  12 + {
  13 + title: '文件名',
  14 + field: 'path',
  15 + search: {
  16 + show: true
  17 + }
39 18 },
40   - search: {
41   - show: true,
42   - component: 'DatePicker',
43   - componentProps: {
44   - type: 'datetimerange',
45   - valueFormat: 'YYYY-MM-DD HH:mm:ss',
46   - defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]
  19 + {
  20 + title: 'URL',
  21 + field: 'url',
  22 + table: {
  23 + cellRender: {
  24 + name: 'XImg'
  25 + }
47 26 }
48   - }
49   - },
50   - {
51   - label: t('table.action'),
52   - field: 'action',
53   - width: '300px',
54   - form: {
55   - show: false
56 27 },
57   - detail: {
58   - show: false
  28 + {
  29 + title: '文件类型',
  30 + field: 'type'
  31 + },
  32 + {
  33 + title: t('common.createTime'),
  34 + field: 'createTime',
  35 + formatter: 'formatDate',
  36 + isForm: false,
  37 + search: {
  38 + show: true,
  39 + itemRender: {
  40 + name: 'XDataTimePicker'
  41 + }
  42 + }
59 43 }
60   - }
61   -])
62   -export const { allSchemas } = useCrudSchemas(crudSchemas)
  44 + ]
  45 +})
  46 +export const { allSchemas } = useVxeCrudSchemas(crudSchemas)
... ...
yudao-ui-admin-vue3/src/views/infra/fileList/index.vue
  1 +<template>
  2 + <ContentWrap>
  3 + <!-- 列表 -->
  4 + <vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar">
  5 + <template #toolbar_buttons>
  6 + <XButton
  7 + type="primary"
  8 + preIcon="ep:upload"
  9 + title="上传文件"
  10 + @click="uploadDialogVisible = true"
  11 + />
  12 + </template>
  13 + <template #actionbtns_default="{ row }">
  14 + <XTextButton
  15 + preIcon="ep:copy-document"
  16 + :title="t('common.copy')"
  17 + @click="handleCopy(row.url)"
  18 + />
  19 + <XTextButton preIcon="ep:view" :title="t('action.detail')" @click="handleDetail(row)" />
  20 + <XTextButton
  21 + preIcon="ep:delete"
  22 + :title="t('action.del')"
  23 + v-hasPermi="['infra:file:delete']"
  24 + @click="handleDelete(row.id)"
  25 + />
  26 + </template>
  27 + </vxe-grid>
  28 + </ContentWrap>
  29 +
  30 + <XModal v-model="dialogVisible" :title="dialogTitle">
  31 + <!-- 对话框(详情) -->
  32 + <Descriptions :schema="allSchemas.detailSchema" :data="detailData">
  33 + <template #url="{ row }">
  34 + <el-image
  35 + v-if="row.type === 'jpg' || 'png' || 'gif'"
  36 + style="width: 100px; height: 100px"
  37 + :src="row.url"
  38 + :key="row.url"
  39 + lazy
  40 + />
  41 + <span>{{ row.url }}</span>
  42 + </template>
  43 + </Descriptions>
  44 + <!-- 操作按钮 -->
  45 + <template #footer>
  46 + <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>
  47 + </template>
  48 + </XModal>
  49 + <XModal v-model="uploadDialogVisible" :title="uploadDialogTitle">
  50 + <el-upload
  51 + ref="uploadRef"
  52 + :action="updateUrl + '?updateSupport=' + updateSupport"
  53 + :headers="uploadHeaders"
  54 + :drag="true"
  55 + :limit="1"
  56 + :multiple="true"
  57 + :show-file-list="true"
  58 + :disabled="uploadDisabled"
  59 + :before-upload="beforeUpload"
  60 + :on-exceed="handleExceed"
  61 + :on-success="handleFileSuccess"
  62 + :on-error="excelUploadError"
  63 + :auto-upload="false"
  64 + accept=".jpg, .png, .gif"
  65 + >
  66 + <Icon icon="ep:upload-filled" />
  67 + <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  68 + <template #tip>
  69 + <div class="el-upload__tip">请上传 .jpg, .png, .gif 标准格式文件</div>
  70 + </template>
  71 + </el-upload>
  72 + <template #footer>
  73 + <el-button type="primary" @click="submitFileForm">
  74 + <Icon icon="ep:upload-filled" />
  75 + {{ t('action.save') }}
  76 + </el-button>
  77 + <el-button @click="uploadDialogVisible = false">{{ t('dialog.close') }}</el-button>
  78 + </template>
  79 + </XModal>
  80 +</template>
1 81 <script setup lang="ts">
2 82 import { ref, unref } from 'vue'
3   -import dayjs from 'dayjs'
4   -import { ElMessage, ElUpload, UploadInstance, UploadRawFile, ElImage } from 'element-plus'
5   -import { useTable } from '@/hooks/web/useTable'
6 83 import { useI18n } from '@/hooks/web/useI18n'
7   -import type { FileVO } from '@/api/infra/fileList/types'
  84 +import { useMessage } from '@/hooks/web/useMessage'
  85 +import { useVxeGrid } from '@/hooks/web/useVxeGrid'
  86 +import { VxeGridInstance } from 'vxe-table'
  87 +import { ElUpload, ElImage, UploadInstance, UploadRawFile } from 'element-plus'
8 88 import { allSchemas } from './fileList.data'
9 89 import * as FileApi from '@/api/infra/fileList'
10 90 import { getAccessToken, getTenantId } from '@/utils/auth'
11 91 import { useClipboard } from '@vueuse/core'
12 92  
13 93 const { t } = useI18n() // 国际化
  94 +const message = useMessage() // 消息弹窗
14 95  
15   -// ========== 列表相关 ==========
16   -const { register, tableObject, methods } = useTable<FileVO>({
  96 +// 列表相关的变量
  97 +const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
  98 +const { gridOptions, getList, deleteData } = useVxeGrid<FileApi.FileVO>({
  99 + allSchemas: allSchemas,
17 100 getListApi: FileApi.getFilePageApi,
18   - delListApi: FileApi.deleteFileApi
  101 + deleteApi: FileApi.deleteFileApi
19 102 })
20   -const { getList, setSearchParams, delList } = methods
21   -// ========== 上传相关 ==========
  103 +
  104 +const detailData = ref() // 详情 Ref
  105 +const dialogVisible = ref(false) // 是否显示弹出层
  106 +const dialogTitle = ref('') // 弹出层标题
22 107 const uploadDialogVisible = ref(false)
23 108 const uploadDialogTitle = ref('上传')
24 109 const updateSupport = ref(0)
... ... @@ -30,8 +115,8 @@ const uploadHeaders = ref()
30 115 const beforeUpload = (file: UploadRawFile) => {
31 116 const isImg = file.type === 'image/jpeg' || 'image/gif' || 'image/png'
32 117 const isLt5M = file.size / 1024 / 1024 < 5
33   - if (!isImg) ElMessage.error('上传文件只能是 jpeg / gif / png 格式!')
34   - if (!isLt5M) ElMessage.error('上传文件大小不能超过 5MB!')
  118 + if (!isImg) message.error('上传文件只能是 jpeg / gif / png 格式!')
  119 + if (!isLt5M) message.error('上传文件大小不能超过 5MB!')
35 120 return isImg && isLt5M
36 121 }
37 122 // 处理上传的文件发生变化
... ... @@ -48,154 +133,48 @@ const submitFileForm = () =&gt; {
48 133 uploadRef.value!.submit()
49 134 }
50 135 // 文件上传成功
51   -const handleFileSuccess = (response: any): void => {
  136 +const handleFileSuccess = async (response: any): Promise<void> => {
52 137 if (response.code !== 0) {
53   - ElMessage.error(response.msg)
  138 + message.error(response.msg)
54 139 return
55 140 }
56   - ElMessage.success('上传成功')
57   - getList()
  141 + message.success('上传成功')
58 142 uploadDialogVisible.value = false
59 143 uploadDisabled.value = false
  144 + await getList(xGrid)
60 145 }
61 146 // 文件数超出提示
62 147 const handleExceed = (): void => {
63   - ElMessage.error('最多只能上传一个文件!')
  148 + message.error('最多只能上传一个文件!')
64 149 }
65 150 // 上传错误提示
66 151 const excelUploadError = (): void => {
67   - ElMessage.error('导入数据失败,请您重新上传!')
  152 + message.error('导入数据失败,请您重新上传!')
68 153 }
69   -// ========== 详情相关 ==========
70   -const detailRef = ref() // 详情 Ref
71   -const dialogVisible = ref(false) // 是否显示弹出层
72   -const dialogTitle = ref('') // 弹出层标题
  154 +
73 155 // 详情操作
74   -const handleDetail = (row: FileVO) => {
  156 +const handleDetail = (row: FileApi.FileVO) => {
75 157 // 设置数据
76   - detailRef.value = row
  158 + detailData.value = row
77 159 dialogTitle.value = t('action.detail')
78 160 dialogVisible.value = true
79 161 }
  162 +
  163 +// 删除操作
  164 +const handleDelete = async (rowId: number) => {
  165 + await deleteData(xGrid, rowId)
  166 +}
  167 +
80 168 // ========== 复制相关 ==========
81 169 const handleCopy = async (text: string) => {
82 170 const { copy, copied, isSupported } = useClipboard({ source: text })
83 171 if (!isSupported) {
84   - ElMessage.error(t('common.copyError'))
  172 + message.error(t('common.copyError'))
85 173 } else {
86 174 await copy()
87 175 if (unref(copied)) {
88   - ElMessage.success(t('common.copySuccess'))
  176 + message.success(t('common.copySuccess'))
89 177 }
90 178 }
91 179 }
92   -// ========== 初始化 ==========
93   -getList()
94 180 </script>
95   -
96   -<template>
97   - <!-- 搜索工作区 -->
98   - <ContentWrap>
99   - <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
100   - </ContentWrap>
101   - <ContentWrap>
102   - <el-button type="primary" @click="uploadDialogVisible = true">
103   - <Icon icon="ep:upload" class="mr-5px" /> 上传文件
104   - </el-button>
105   - <!-- 列表 -->
106   - <Table
107   - :columns="allSchemas.tableColumns"
108   - :selection="false"
109   - :data="tableObject.tableList"
110   - :loading="tableObject.loading"
111   - :pagination="{
112   - total: tableObject.total
113   - }"
114   - v-model:pageSize="tableObject.pageSize"
115   - v-model:currentPage="tableObject.currentPage"
116   - @register="register"
117   - >
118   - <template #url="{ row }">
119   - <el-image
120   - v-if="row.type === 'jpg' || 'png' || 'gif'"
121   - style="width: 80px; height: 50px"
122   - :src="row.url"
123   - :key="row.url"
124   - fit="contain"
125   - lazy
126   - />
127   - <span v-else>{{ row.url }}</span>
128   - </template>
129   - <template #createTime="{ row }">
130   - <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
131   - </template>
132   - <template #action="{ row }">
133   - <el-button link type="primary" @click="handleCopy(row.url)">
134   - <Icon icon="ep:copy-document" class="mr-1px" /> {{ t('common.copy') }}
135   - </el-button>
136   - <el-button link type="primary" @click="handleDetail(row)">
137   - <Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}
138   - </el-button>
139   - <el-button
140   - link
141   - type="primary"
142   - v-hasPermi="['infra:file:delete']"
143   - @click="delList(row.id, false)"
144   - >
145   - <Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}
146   - </el-button>
147   - </template>
148   - </Table>
149   - </ContentWrap>
150   -
151   - <XModal v-model="dialogVisible" :title="dialogTitle">
152   - <!-- 对话框(详情) -->
153   - <Descriptions :schema="allSchemas.detailSchema" :data="detailRef">
154   - <template #url="{ row }">
155   - <el-image
156   - v-if="row.type === 'jpg' || 'png' || 'gif'"
157   - style="width: 100px; height: 100px"
158   - :src="row.url"
159   - :key="row.url"
160   - lazy
161   - />
162   - <span>{{ row.url }}</span>
163   - </template>
164   - </Descriptions>
165   - <!-- 操作按钮 -->
166   - <template #footer>
167   - <el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>
168   - </template>
169   - </XModal>
170   - <XModal v-model="uploadDialogVisible" :title="uploadDialogTitle">
171   - <el-upload
172   - ref="uploadRef"
173   - :action="updateUrl + '?updateSupport=' + updateSupport"
174   - :headers="uploadHeaders"
175   - :drag="true"
176   - :limit="1"
177   - :multiple="true"
178   - :show-file-list="true"
179   - :disabled="uploadDisabled"
180   - :before-upload="beforeUpload"
181   - :on-exceed="handleExceed"
182   - :on-success="handleFileSuccess"
183   - :on-error="excelUploadError"
184   - :auto-upload="false"
185   - accept=".jpg, .png, .gif"
186   - >
187   - <Icon icon="ep:upload-filled" />
188   - <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
189   - <template #tip>
190   - <div class="el-upload__tip">请上传 .jpg, .png, .gif 标准格式文件</div>
191   - </template>
192   - </el-upload>
193   - <template #footer>
194   - <el-button type="primary" @click="submitFileForm">
195   - <Icon icon="ep:upload-filled" />
196   - {{ t('action.save') }}
197   - </el-button>
198   - <el-button @click="uploadDialogVisible = false">{{ t('dialog.close') }}</el-button>
199   - </template>
200   - </XModal>
201   -</template>
... ...