refactor: file vxe

plp
xingyu4j 4 years ago
parent e6acf9e8dc
commit 562282b2ad

@ -15,7 +15,7 @@ export type FileConfigVO = {
id: number id: number
name: string name: string
storage: string storage: string
primary: number master: boolean
visible: boolean visible: boolean
config: ConfigType config: ConfigType
remark: string remark: string

@ -1,7 +1,21 @@
import request from '@/config/axios' import request from '@/config/axios'
export type FileVO = {
id: number
path: string
url: string
size: string
type: string
createTime: string
}
export interface FilePageReqVO extends PageParam {
name?: string
createTime?: string[]
}
// 查询文件列表 // 查询文件列表
export const getFilePageApi = (params) => { export const getFilePageApi = (params: FilePageReqVO) => {
return request.get({ url: '/infra/file/page', params }) return request.get({ url: '/infra/file/page', params })
} }

@ -1,8 +0,0 @@
export type FileVO = {
id: number
path: string
url: string
size: string
type: string
createTime: string
}

@ -1,4 +1,5 @@
import { VXETable } from 'vxe-table' import { VXETable } from 'vxe-table'
import { ElImage } from 'element-plus'
// 图片渲染 // 图片渲染
VXETable.renderer.add('XImg', { VXETable.renderer.add('XImg', {
@ -6,13 +7,13 @@ VXETable.renderer.add('XImg', {
renderDefault(_renderOpts, params) { renderDefault(_renderOpts, params) {
const { row, column } = params const { row, column } = params
return ( return (
<el-image <ElImage
style="width: 80px; height: 50px" style="width: 80px; height: 50px"
src={row[column.field]} src={row[column.field]}
key={row[column.field]} key={row[column.field]}
fit="contain" fit="contain"
lazy lazy
></el-image> ></ElImage>
) )
} }
}) })

@ -1,8 +1,8 @@
import { reactive } from 'vue' import { reactive } from 'vue'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { required } from '@/utils/formRules' import { required } from '@/utils/formRules'
import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
import { DICT_TYPE } from '@/utils/dict' import { DICT_TYPE } from '@/utils/dict'
import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
const { t } = useI18n() // 国际化 const { t } = useI18n() // 国际化
// 表单校验 // 表单校验
@ -25,80 +25,56 @@ export const rules = reactive({
}) })
// CrudSchema // CrudSchema
const crudSchemas = reactive<CrudSchema[]>([ const crudSchemas = reactive<VxeCrudSchema>({
{ primaryKey: 'id',
label: t('common.index'), primaryType: 'seq',
field: 'id', action: true,
type: 'index', actionWidth: '400px',
form: { columns: [
show: false {
title: '配置名',
field: 'name',
isSearch: true
}, },
detail: { {
show: false title: '存储器',
} field: 'storage',
}, dictType: DICT_TYPE.INFRA_FILE_STORAGE,
{ dictClass: 'number',
label: '配置名', isSearch: true
field: 'name',
search: {
show: true
}
},
{
label: '存储器',
field: 'storage',
dictType: DICT_TYPE.INFRA_FILE_STORAGE,
dictClass: 'number',
search: {
show: true
}
},
{
label: '主配置',
field: 'primary',
dictType: DICT_TYPE.INFRA_BOOLEAN_STRING,
dictClass: 'number'
},
{
label: t('form.remark'),
field: 'remark',
form: {
component: 'Input',
componentProps: {
type: 'textarea',
rows: 4
},
colProps: {
span: 24
}
}
},
{
label: t('common.createTime'),
field: 'createTime',
form: {
show: false
}, },
search: { {
show: true, title: '主配置',
component: 'DatePicker', field: 'master',
componentProps: { dictType: DICT_TYPE.INFRA_BOOLEAN_STRING,
type: 'datetimerange', dictClass: 'boolean'
valueFormat: 'YYYY-MM-DD HH:mm:ss', },
defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)] {
title: t('form.remark'),
field: 'remark',
form: {
component: 'Input',
componentProps: {
type: 'textarea',
rows: 4
},
colProps: {
span: 24
}
} }
}
},
{
label: t('table.action'),
field: 'action',
width: '400px',
form: {
show: false
}, },
detail: { {
show: false title: t('common.createTime'),
field: 'createTime',
formatter: 'formatDate',
isForm: false,
search: {
show: true,
itemRender: {
name: 'XDataTimePicker'
}
}
} }
} ]
]) })
export const { allSchemas } = useCrudSchemas(crudSchemas) export const { allSchemas } = useVxeCrudSchemas(crudSchemas)

@ -1,23 +1,103 @@
<template>
<ContentWrap>
<!-- 列表 -->
<vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar">
<template #toolbar_buttons>
<!-- 操作新增 -->
<XButton
type="primary"
preIcon="ep:zoom-in"
:title="t('action.add')"
v-hasPermi="['infra:file-config:create']"
@click="handleCreate()"
/>
</template>
<template #actionbtns_default="{ row }">
<XTextButton
preIcon="ep:edit"
:title="t('action.edit')"
v-hasPermi="['infra:file-config:update']"
@click="handleUpdate(row.id)"
/>
<XTextButton
preIcon="ep:view"
:title="t('action.detail')"
v-hasPermi="['infra:file-config:query']"
@click="handleDetail(row.id)"
/>
<XTextButton
preIcon="ep:flag"
title="主配置"
v-hasPermi="['infra:file-config:update']"
@click="handleMaster(row)"
/>
<XTextButton
preIcon="ep:share"
:title="t('action.test')"
v-hasPermi="['infra:file-config:update']"
@click="handleUpdate(row.id)"
/>
<XTextButton
preIcon="ep:delete"
:title="t('action.del')"
v-hasPermi="['infra:file-config:delete']"
@click="handleDelete(row.id)"
/>
</template>
</vxe-grid>
</ContentWrap>
<XModal v-model="dialogVisible" :title="dialogTitle">
<!-- 对话框(添加 / 修改) -->
<Form
v-if="['create', 'update'].includes(actionType)"
:schema="allSchemas.formSchema"
:rules="rules"
ref="formRef"
/>
<!-- 对话框(详情) -->
<Descriptions
v-if="actionType === 'detail'"
:schema="allSchemas.detailSchema"
:data="detailData"
/>
<!-- 操作按钮 -->
<template #footer>
<!-- 按钮保存 -->
<XButton
v-if="['create', 'update'].includes(actionType)"
type="primary"
:title="t('action.save')"
:loading="actionLoading"
@click="submitForm()"
/>
<!-- 按钮关闭 -->
<XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
</template>
</XModal>
</template>
<script setup lang="ts"> <script setup lang="ts">
// import
import { ref, unref } from 'vue' import { ref, unref } from 'vue'
import dayjs from 'dayjs'
import { DICT_TYPE } from '@/utils/dict'
import { useTable } from '@/hooks/web/useTable'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage'
import { useVxeGrid } from '@/hooks/web/useVxeGrid'
import { VxeGridInstance } from 'vxe-table'
import { FormExpose } from '@/components/Form' import { FormExpose } from '@/components/Form'
// import
import * as FileConfigApi from '@/api/infra/fileConfig'
import type { FileConfigVO } from '@/api/infra/fileConfig/types' import type { FileConfigVO } from '@/api/infra/fileConfig/types'
import { rules, allSchemas } from './fileConfig.data' import { rules, allSchemas } from './fileConfig.data'
import * as FileConfigApi from '@/api/infra/fileConfig'
import { useMessage } from '@/hooks/web/useMessage'
const message = useMessage()
const { t } = useI18n() //
// ========== ========== const { t } = useI18n() //
const { register, tableObject, methods } = useTable<FileConfigVO>({ const message = useMessage() //
//
const xGrid = ref<VxeGridInstance>() // Grid Ref
const { gridOptions, getList, deleteData } = useVxeGrid<FileConfigVO>({
allSchemas: allSchemas,
getListApi: FileConfigApi.getFileConfigPageApi, getListApi: FileConfigApi.getFileConfigPageApi,
delListApi: FileConfigApi.deleteFileConfigApi deleteApi: FileConfigApi.deleteFileConfigApi
}) })
const { getList, setSearchParams, delList } = methods
// ========== CRUD ========== // ========== CRUD ==========
const actionLoading = ref(false) // const actionLoading = ref(false) //
@ -25,7 +105,7 @@ const actionType = ref('') // 操作按钮的类型
const dialogVisible = ref(false) // const dialogVisible = ref(false) //
const dialogTitle = ref('edit') // const dialogTitle = ref('edit') //
const formRef = ref<FormExpose>() // Ref const formRef = ref<FormExpose>() // Ref
const detailData = ref() // Ref
// //
const setDialogTile = (type: string) => { const setDialogTile = (type: string) => {
dialogTitle.value = t('action.' + type) dialogTitle.value = t('action.' + type)
@ -39,23 +119,36 @@ const handleCreate = () => {
} }
// //
const handleUpdate = async (row: FileConfigVO) => { const handleUpdate = async (rowId: number) => {
setDialogTile('update') setDialogTile('update')
// //
const res = await FileConfigApi.getFileConfigApi(row.id) const res = await FileConfigApi.getFileConfigApi(rowId)
unref(formRef)?.setValues(res) unref(formRef)?.setValues(res)
} }
//
const handleDetail = async (rowId: number) => {
setDialogTile('detail')
//
const res = await FileConfigApi.getFileConfigApi(rowId)
detailData.value = res
}
// //
const handleMaster = (row: FileConfigVO) => { const handleMaster = (row: FileConfigVO) => {
message message
.confirm('是否确认修改配置【 ' + row.name + ' 】为主配置?', t('common.reminder')) .confirm('是否确认修改配置【 ' + row.name + ' 】为主配置?', t('common.reminder'))
.then(async () => { .then(async () => {
await FileConfigApi.updateFileConfigMasterApi(row.id) await FileConfigApi.updateFileConfigMasterApi(row.id)
await getList() await getList(xGrid)
}) })
} }
//
const handleDelete = async (rowId: number) => {
await deleteData(xGrid, rowId)
}
// //
const submitForm = async () => { const submitForm = async () => {
const elForm = unref(formRef)?.getElFormRef() const elForm = unref(formRef)?.getElFormRef()
@ -73,135 +166,12 @@ const submitForm = async () => {
await FileConfigApi.updateFileConfigApi(data) await FileConfigApi.updateFileConfigApi(data)
message.success(t('common.updateSuccess')) message.success(t('common.updateSuccess'))
} }
//
dialogVisible.value = false dialogVisible.value = false
await getList()
} finally { } finally {
actionLoading.value = false actionLoading.value = false
await getList(xGrid)
} }
} }
}) })
} }
// ========== ==========
const detailRef = ref() // Ref
//
const handleDetail = async (row: FileConfigVO) => {
//
detailRef.value = row
setDialogTile('detail')
}
// ========== ==========
getList()
</script> </script>
<template>
<!-- 搜索工作区 -->
<ContentWrap>
<Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
</ContentWrap>
<ContentWrap>
<!-- 操作工具栏 -->
<div class="mb-10px">
<el-button type="primary" v-hasPermi="['infra:file-config:create']" @click="handleCreate">
<Icon icon="ep:zoom-in" class="mr-5px" /> {{ t('action.add') }}
</el-button>
</div>
<!-- 列表 -->
<Table
:columns="allSchemas.tableColumns"
:selection="false"
:data="tableObject.tableList"
:loading="tableObject.loading"
:pagination="{
total: tableObject.total
}"
v-model:pageSize="tableObject.pageSize"
v-model:currentPage="tableObject.currentPage"
@register="register"
>
<template #storage="{ row }">
<DictTag :type="DICT_TYPE.INFRA_FILE_STORAGE" :value="row.storage" />
</template>
<template #primary="{ row }">
<DictTag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="row.master" />
</template>
<template #createTime="{ row }">
<span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
</template>
<template #action="{ row }">
<el-button
link
type="primary"
v-hasPermi="['infra:file-config:update']"
@click="handleUpdate(row)"
>
<Icon icon="ep:edit" class="mr-1px" /> {{ t('action.edit') }}
</el-button>
<el-button
link
type="primary"
v-hasPermi="['infra:file-config:update']"
@click="handleDetail(row)"
>
<Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}
</el-button>
<el-button
link
type="primary"
v-hasPermi="['infra:file-config:update']"
@click="handleMaster(row)"
>
<Icon icon="ep:flag" class="mr-1px" /> 主配置
</el-button>
<el-button
link
type="primary"
v-hasPermi="['infra:file-config:update']"
@click="handleUpdate(row)"
>
<Icon icon="ep:share" class="mr-1px" /> {{ t('action.test') }}
</el-button>
<el-button
link
type="primary"
v-hasPermi="['infra:file-config:delete']"
@click="delList(row.id, false)"
>
<Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}
</el-button>
</template>
</Table>
</ContentWrap>
<XModal v-model="dialogVisible" :title="dialogTitle">
<!-- 对话框(添加 / 修改) -->
<Form
v-if="['create', 'update'].includes(actionType)"
:schema="allSchemas.formSchema"
:rules="rules"
ref="formRef"
/>
<!-- 对话框(详情) -->
<Descriptions
v-if="actionType === 'detail'"
:schema="allSchemas.detailSchema"
:data="detailRef"
/>
<!-- 操作按钮 -->
<template #footer>
<!-- 按钮保存 -->
<XButton
v-if="['create', 'update'].includes(actionType)"
type="primary"
:title="t('action.save')"
:loading="actionLoading"
@click="submitForm()"
/>
<!-- 按钮关闭 -->
<XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
</template>
</XModal>
</template>

@ -1,62 +1,46 @@
import { reactive } from 'vue' import { reactive } from 'vue'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas' import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
const { t } = useI18n() // 国际化 const { t } = useI18n() // 国际化
// CrudSchema // CrudSchema
const crudSchemas = reactive<CrudSchema[]>([ const crudSchemas = reactive<VxeCrudSchema>({
{ primaryKey: 'id',
label: t('common.index'), primaryType: 'seq',
field: 'id', action: true,
type: 'index', columns: [
form: { {
show: false title: '文件名',
}, field: 'path',
detail: { search: {
show: false show: true
} }
},
{
label: '文件名',
field: 'path',
search: {
show: true
}
},
{
label: 'URL',
field: 'url'
},
{
label: '文件类型',
field: 'type'
},
{
label: t('common.createTime'),
field: 'createTime',
form: {
show: false
}, },
search: { {
show: true, title: 'URL',
component: 'DatePicker', field: 'url',
componentProps: { table: {
type: 'datetimerange', cellRender: {
valueFormat: 'YYYY-MM-DD HH:mm:ss', name: 'XImg'
defaultTime: [new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)] }
} }
}
},
{
label: t('table.action'),
field: 'action',
width: '300px',
form: {
show: false
}, },
detail: { {
show: false title: '文件类型',
field: 'type'
},
{
title: t('common.createTime'),
field: 'createTime',
formatter: 'formatDate',
isForm: false,
search: {
show: true,
itemRender: {
name: 'XDataTimePicker'
}
}
} }
} ]
]) })
export const { allSchemas } = useCrudSchemas(crudSchemas) export const { allSchemas } = useVxeCrudSchemas(crudSchemas)

@ -1,24 +1,109 @@
<template>
<ContentWrap>
<!-- 列表 -->
<vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar">
<template #toolbar_buttons>
<XButton
type="primary"
preIcon="ep:upload"
title="上传文件"
@click="uploadDialogVisible = true"
/>
</template>
<template #actionbtns_default="{ row }">
<XTextButton
preIcon="ep:copy-document"
:title="t('common.copy')"
@click="handleCopy(row.url)"
/>
<XTextButton preIcon="ep:view" :title="t('action.detail')" @click="handleDetail(row)" />
<XTextButton
preIcon="ep:delete"
:title="t('action.del')"
v-hasPermi="['infra:file:delete']"
@click="handleDelete(row.id)"
/>
</template>
</vxe-grid>
</ContentWrap>
<XModal v-model="dialogVisible" :title="dialogTitle">
<!-- 对话框(详情) -->
<Descriptions :schema="allSchemas.detailSchema" :data="detailData">
<template #url="{ row }">
<el-image
v-if="row.type === 'jpg' || 'png' || 'gif'"
style="width: 100px; height: 100px"
:src="row.url"
:key="row.url"
lazy
/>
<span>{{ row.url }}</span>
</template>
</Descriptions>
<!-- 操作按钮 -->
<template #footer>
<el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>
</template>
</XModal>
<XModal v-model="uploadDialogVisible" :title="uploadDialogTitle">
<el-upload
ref="uploadRef"
:action="updateUrl + '?updateSupport=' + updateSupport"
:headers="uploadHeaders"
:drag="true"
:limit="1"
:multiple="true"
:show-file-list="true"
:disabled="uploadDisabled"
:before-upload="beforeUpload"
:on-exceed="handleExceed"
:on-success="handleFileSuccess"
:on-error="excelUploadError"
:auto-upload="false"
accept=".jpg, .png, .gif"
>
<Icon icon="ep:upload-filled" />
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<template #tip>
<div class="el-upload__tip">请上传 .jpg, .png, .gif 标准格式文件</div>
</template>
</el-upload>
<template #footer>
<el-button type="primary" @click="submitFileForm">
<Icon icon="ep:upload-filled" />
{{ t('action.save') }}
</el-button>
<el-button @click="uploadDialogVisible = false">{{ t('dialog.close') }}</el-button>
</template>
</XModal>
</template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, unref } from 'vue' import { ref, unref } from 'vue'
import dayjs from 'dayjs'
import { ElMessage, ElUpload, UploadInstance, UploadRawFile, ElImage } from 'element-plus'
import { useTable } from '@/hooks/web/useTable'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import type { FileVO } from '@/api/infra/fileList/types' import { useMessage } from '@/hooks/web/useMessage'
import { useVxeGrid } from '@/hooks/web/useVxeGrid'
import { VxeGridInstance } from 'vxe-table'
import { ElUpload, ElImage, UploadInstance, UploadRawFile } from 'element-plus'
import { allSchemas } from './fileList.data' import { allSchemas } from './fileList.data'
import * as FileApi from '@/api/infra/fileList' import * as FileApi from '@/api/infra/fileList'
import { getAccessToken, getTenantId } from '@/utils/auth' import { getAccessToken, getTenantId } from '@/utils/auth'
import { useClipboard } from '@vueuse/core' import { useClipboard } from '@vueuse/core'
const { t } = useI18n() // const { t } = useI18n() //
const message = useMessage() //
// ========== ========== //
const { register, tableObject, methods } = useTable<FileVO>({ const xGrid = ref<VxeGridInstance>() // Grid Ref
const { gridOptions, getList, deleteData } = useVxeGrid<FileApi.FileVO>({
allSchemas: allSchemas,
getListApi: FileApi.getFilePageApi, getListApi: FileApi.getFilePageApi,
delListApi: FileApi.deleteFileApi deleteApi: FileApi.deleteFileApi
}) })
const { getList, setSearchParams, delList } = methods
// ========== ========== const detailData = ref() // Ref
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const uploadDialogVisible = ref(false) const uploadDialogVisible = ref(false)
const uploadDialogTitle = ref('上传') const uploadDialogTitle = ref('上传')
const updateSupport = ref(0) const updateSupport = ref(0)
@ -30,8 +115,8 @@ const uploadHeaders = ref()
const beforeUpload = (file: UploadRawFile) => { const beforeUpload = (file: UploadRawFile) => {
const isImg = file.type === 'image/jpeg' || 'image/gif' || 'image/png' const isImg = file.type === 'image/jpeg' || 'image/gif' || 'image/png'
const isLt5M = file.size / 1024 / 1024 < 5 const isLt5M = file.size / 1024 / 1024 < 5
if (!isImg) ElMessage.error('上传文件只能是 jpeg / gif / png 格式!') if (!isImg) message.error('上传文件只能是 jpeg / gif / png 格式!')
if (!isLt5M) ElMessage.error('上传文件大小不能超过 5MB!') if (!isLt5M) message.error('上传文件大小不能超过 5MB!')
return isImg && isLt5M return isImg && isLt5M
} }
// //
@ -48,154 +133,48 @@ const submitFileForm = () => {
uploadRef.value!.submit() uploadRef.value!.submit()
} }
// //
const handleFileSuccess = (response: any): void => { const handleFileSuccess = async (response: any): Promise<void> => {
if (response.code !== 0) { if (response.code !== 0) {
ElMessage.error(response.msg) message.error(response.msg)
return return
} }
ElMessage.success('上传成功') message.success('上传成功')
getList()
uploadDialogVisible.value = false uploadDialogVisible.value = false
uploadDisabled.value = false uploadDisabled.value = false
await getList(xGrid)
} }
// //
const handleExceed = (): void => { const handleExceed = (): void => {
ElMessage.error('最多只能上传一个文件!') message.error('最多只能上传一个文件!')
} }
// //
const excelUploadError = (): void => { const excelUploadError = (): void => {
ElMessage.error('导入数据失败,请您重新上传!') message.error('导入数据失败,请您重新上传!')
} }
// ========== ==========
const detailRef = ref() // Ref
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
// //
const handleDetail = (row: FileVO) => { const handleDetail = (row: FileApi.FileVO) => {
// //
detailRef.value = row detailData.value = row
dialogTitle.value = t('action.detail') dialogTitle.value = t('action.detail')
dialogVisible.value = true dialogVisible.value = true
} }
//
const handleDelete = async (rowId: number) => {
await deleteData(xGrid, rowId)
}
// ========== ========== // ========== ==========
const handleCopy = async (text: string) => { const handleCopy = async (text: string) => {
const { copy, copied, isSupported } = useClipboard({ source: text }) const { copy, copied, isSupported } = useClipboard({ source: text })
if (!isSupported) { if (!isSupported) {
ElMessage.error(t('common.copyError')) message.error(t('common.copyError'))
} else { } else {
await copy() await copy()
if (unref(copied)) { if (unref(copied)) {
ElMessage.success(t('common.copySuccess')) message.success(t('common.copySuccess'))
} }
} }
} }
// ========== ==========
getList()
</script> </script>
<template>
<!-- 搜索工作区 -->
<ContentWrap>
<Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
</ContentWrap>
<ContentWrap>
<el-button type="primary" @click="uploadDialogVisible = true">
<Icon icon="ep:upload" class="mr-5px" /> 上传文件
</el-button>
<!-- 列表 -->
<Table
:columns="allSchemas.tableColumns"
:selection="false"
:data="tableObject.tableList"
:loading="tableObject.loading"
:pagination="{
total: tableObject.total
}"
v-model:pageSize="tableObject.pageSize"
v-model:currentPage="tableObject.currentPage"
@register="register"
>
<template #url="{ row }">
<el-image
v-if="row.type === 'jpg' || 'png' || 'gif'"
style="width: 80px; height: 50px"
:src="row.url"
:key="row.url"
fit="contain"
lazy
/>
<span v-else>{{ row.url }}</span>
</template>
<template #createTime="{ row }">
<span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
</template>
<template #action="{ row }">
<el-button link type="primary" @click="handleCopy(row.url)">
<Icon icon="ep:copy-document" class="mr-1px" /> {{ t('common.copy') }}
</el-button>
<el-button link type="primary" @click="handleDetail(row)">
<Icon icon="ep:view" class="mr-1px" /> {{ t('action.detail') }}
</el-button>
<el-button
link
type="primary"
v-hasPermi="['infra:file:delete']"
@click="delList(row.id, false)"
>
<Icon icon="ep:delete" class="mr-1px" /> {{ t('action.del') }}
</el-button>
</template>
</Table>
</ContentWrap>
<XModal v-model="dialogVisible" :title="dialogTitle">
<!-- 对话框(详情) -->
<Descriptions :schema="allSchemas.detailSchema" :data="detailRef">
<template #url="{ row }">
<el-image
v-if="row.type === 'jpg' || 'png' || 'gif'"
style="width: 100px; height: 100px"
:src="row.url"
:key="row.url"
lazy
/>
<span>{{ row.url }}</span>
</template>
</Descriptions>
<!-- 操作按钮 -->
<template #footer>
<el-button @click="dialogVisible = false">{{ t('dialog.close') }}</el-button>
</template>
</XModal>
<XModal v-model="uploadDialogVisible" :title="uploadDialogTitle">
<el-upload
ref="uploadRef"
:action="updateUrl + '?updateSupport=' + updateSupport"
:headers="uploadHeaders"
:drag="true"
:limit="1"
:multiple="true"
:show-file-list="true"
:disabled="uploadDisabled"
:before-upload="beforeUpload"
:on-exceed="handleExceed"
:on-success="handleFileSuccess"
:on-error="excelUploadError"
:auto-upload="false"
accept=".jpg, .png, .gif"
>
<Icon icon="ep:upload-filled" />
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<template #tip>
<div class="el-upload__tip">请上传 .jpg, .png, .gif 标准格式文件</div>
</template>
</el-upload>
<template #footer>
<el-button type="primary" @click="submitFileForm">
<Icon icon="ep:upload-filled" />
{{ t('action.save') }}
</el-button>
<el-button @click="uploadDialogVisible = false">{{ t('dialog.close') }}</el-button>
</template>
</XModal>
</template>

Loading…
Cancel
Save