增加模版

This commit is contained in:
wuweihua
2026-10-22 14:46:52 +08:00
parent c064d925ca
commit f07386f4aa
16 changed files with 1129 additions and 26 deletions
@@ -0,0 +1,300 @@
<template>
<div class="app-container">
<basic-table
ref="tableRef"
:columns="columns"
:search-columns="searchColumns"
:query="queryList"
row-key="templateId"
selection
>
<template #toolbar="{ selection, ids }">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" v-hasPermi="['system:fileTemplate:add']" @click="handleAdd">{{ labAdd }}</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="selection.length !== 1" v-hasPermi="['system:fileTemplate:edit']" @click="handleUpdate(selection[0])">{{ labEdit }}</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="!selection.length" v-hasPermi="['system:fileTemplate:remove']" @click="handleDelete(ids)">{{ labRemove }}</el-button>
</el-col>
</template>
<template #col-status="{ row }">
<el-tag size="small" :type="row.status === '0' ? 'success' : 'info'">{{ row.status === '0' ? labOn : labOff }}</el-tag>
</template>
<template #col-filePath="{ row }">
<span>{{ row.filePath ? labUploaded : labEmpty }}</span>
</template>
<template #col-action="{ row }">
<el-button link type="primary" :disabled="!row.filePath" v-hasPermi="['system:fileTemplate:download']" @click="handleDownload(row)">{{ labDown }}</el-button>
<el-button link type="primary" v-hasPermi="['system:fileTemplate:edit']" @click="handleUpdate(row)">{{ labEdit }}</el-button>
<el-button link type="primary" v-hasPermi="['system:fileTemplate:remove']" @click="handleDelete(row.templateId)">{{ labRemove }}</el-button>
</template>
</basic-table>
<el-dialog :title="title" v-model="open" width="560px" append-to-body @closed="onFormClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
<el-form-item :label="labType" prop="templateType">
<el-select v-model="form.templateType" clearable :placeholder="phType" style="width: 100%;">
<el-option v-for="d in sys_file_template_type" :key="d.value" :label="d.label" :value="d.value" />
</el-select>
</el-form-item>
<el-form-item :label="labCode" prop="fileCode">
<el-input v-model="form.fileCode" :placeholder="phCode" maxlength="64" />
</el-form-item>
<el-form-item :label="labName" prop="templateName">
<el-input v-model="form.templateName" maxlength="100" />
</el-form-item>
<el-form-item :label="labFile" prop="uploadFile">
<div class="tpl-upload">
<el-upload
ref="uploadRef"
drag
:auto-upload="false"
:limit="1"
accept=".xlsx,.xls"
:on-change="onUploadChange"
:on-remove="onUploadRemove"
:on-exceed="onUploadExceed"
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">{{ labDrop }}</div>
<template #tip>
<div class="el-upload__tip">
<span v-if="form.fileName">{{ labCurrentFile }}{{ form.fileName }}</span>
<span v-else>{{ labFileTip }}</span>
</div>
</template>
</el-upload>
</div>
</el-form-item>
<el-form-item :label="labStatus" prop="status">
<el-radio-group v-model="form.status">
<el-radio value="0">{{ labOn }}</el-radio>
<el-radio value="1">{{ labOff }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="labRemark">
<el-input v-model="form.remark" type="textarea" :rows="2" maxlength="500" />
</el-form-item>
</el-form>
<template #footer>
<el-button type="primary" :loading="saving" @click="submitForm">{{ labOk }}</el-button>
<el-button @click="open = false">{{ labCancel }}</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup name="FileTemplate">
import { UploadFilled } from '@element-plus/icons-vue'
import {
listFileTemplate, getFileTemplate, addFileTemplate, updateFileTemplate,
delFileTemplate, uploadFileTemplate, downloadFileTemplate
} from '@/api/system/fileTemplate'
const { proxy } = getCurrentInstance()
const { sys_file_template_type } = useDict('sys_file_template_type')
const tableRef = ref()
const formRef = ref()
const uploadRef = ref()
const open = ref(false)
const title = ref('')
const saving = ref(false)
const pendingFile = ref(null)
const labAdd = '新增'
const labEdit = '修改'
const labRemove = '删除'
const labDown = '下载'
const labType = '类型'
const labCode = '文件代码'
const labName = '模板名称'
const labFile = '模板文件'
const labStatus = '状态'
const labRemark = '备注'
const labOn = '正常'
const labOff = '停用'
const labOk = '确定'
const labCancel = '取消'
const labUploaded = '已上传'
const labEmpty = '未上传'
const labDrop = '将 xlsx/xls 拖到此处,或点击上传'
const labCurrentFile = '当前文件:'
const labFileTip = '仅支持 .xlsx / .xls'
const phType = '请选择类型'
const phCode = 'PRODUCT_ALL'
const searchColumns = [
{ label: labType, prop: 'templateType', component: 'select', dict: 'sys_file_template_type', placeholder: labType },
{ label: labCode, prop: 'fileCode', component: 'input', placeholder: labCode },
{ label: labName, prop: 'templateName', component: 'input', placeholder: labName },
{ label: labStatus, prop: 'status', component: 'select', options: [
{ value: '0', label: labOn }, { value: '1', label: labOff }
] }
]
const columns = [
{ label: labType, prop: 'templateType', width: 140, dict: 'sys_file_template_type' },
{ label: labCode, prop: 'fileCode', minWidth: 160 },
{ label: labName, prop: 'templateName', minWidth: 180 },
{ label: '文件', prop: 'fileName', minWidth: 160, showOverflowTooltip: true },
{ label: '附件', prop: 'filePath', width: 100 },
{ label: labStatus, prop: 'status', width: 90 },
{ label: '更新时间', prop: 'updateTime', width: 170 },
{ label: '操作', prop: 'action', width: 180, fixed: 'right' }
]
const form = reactive({
templateId: undefined,
templateType: undefined,
fileCode: '',
templateName: '',
fileName: '',
filePath: '',
status: '0',
remark: ''
})
const rules = {
templateType: [{ required: true, message: phType, trigger: 'change' }],
fileCode: [{ required: true, message: labCode, trigger: 'blur' }],
templateName: [{ required: true, message: labName, trigger: 'blur' }]
}
function queryList(params) {
return listFileTemplate(params)
}
function resetForm() {
form.templateId = undefined
form.templateType = undefined
form.fileCode = ''
form.templateName = ''
form.fileName = ''
form.filePath = ''
form.status = '0'
form.remark = ''
pendingFile.value = null
nextTick(() => {
uploadRef.value?.clearFiles?.()
formRef.value?.clearValidate?.()
})
}
function onFormClosed() {
resetForm()
}
function handleAdd() {
resetForm()
title.value = labAdd
open.value = true
}
function handleUpdate(row) {
resetForm()
getFileTemplate(row.templateId).then(res => {
const data = res.data || {}
form.templateId = data.templateId
form.templateType = data.templateType || undefined
form.fileCode = data.fileCode || ''
form.templateName = data.templateName || ''
form.fileName = data.fileName || ''
form.filePath = data.filePath || ''
form.status = data.status || '0'
form.remark = data.remark || ''
title.value = labEdit
open.value = true
})
}
function onUploadChange(file) {
pendingFile.value = file?.raw || null
}
function onUploadRemove() {
pendingFile.value = null
}
function onUploadExceed(files) {
uploadRef.value?.clearFiles?.()
const raw = files?.[0]
if (raw) {
uploadRef.value?.handleStart?.(raw)
pendingFile.value = raw
}
}
async function submitForm() {
const valid = await formRef.value.validate().catch(() => false)
if (!valid) return
saving.value = true
try {
let templateId = form.templateId
if (templateId) {
await updateFileTemplate({
templateId: form.templateId,
templateType: form.templateType,
fileCode: form.fileCode,
templateName: form.templateName,
status: form.status,
remark: form.remark
})
} else {
const res = await addFileTemplate({
templateType: form.templateType,
fileCode: form.fileCode,
templateName: form.templateName,
status: form.status,
remark: form.remark
})
templateId = res?.data?.templateId
if (!templateId) {
throw new Error('保存成功但未返回模板ID')
}
}
if (pendingFile.value) {
await uploadFileTemplate(templateId, pendingFile.value)
}
proxy.$modal.msgSuccess('保存成功')
open.value = false
tableRef.value?.refresh?.()
} catch (e) {
if (e?.message) proxy.$modal.msgError(e.message)
} finally {
saving.value = false
}
}
function handleDelete(ids) {
const idList = Array.isArray(ids) ? ids : [ids]
proxy.$modal.confirm('确认删除选中模板?').then(() => {
return delFileTemplate(idList.join(','))
}).then(() => {
proxy.$modal.msgSuccess('删除成功')
tableRef.value?.refresh?.()
}).catch(() => {})
}
async function handleDownload(row) {
try {
await downloadFileTemplate(row.fileCode, row.templateName || row.fileCode)
} catch (e) {
proxy.$modal.msgError(e?.message || '下载失败')
}
}
</script>
<style scoped>
.tpl-upload {
width: 100%;
}
.tpl-upload :deep(.el-upload) {
width: 100%;
}
.tpl-upload :deep(.el-upload-dragger) {
width: 100%;
padding: 16px 12px;
}
</style>