Files
school-developer/src/views/purchase/purchasingtemplate/index.vue
2026-03-01 16:21:26 +08:00

272 lines
8.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="modern-page-container">
<div class="page-wrapper">
<el-card class="content-card" shadow="never">
<template #header>
<div class="card-header">
<div class="header-actions">
<el-button
type="primary"
icon="FolderAdd"
@click="openUploadDialog()"
v-auth="'purchase_template_add'">
新增模板
</el-button>
<el-alert type="info" :closable="false" class="mb3 mt-3" show-icon>
此处模版中的模版编码对应用户端下载模版匹配请勿随意修改或删除正常情况下如有发生模版变化重新上传即可如有新增模版请联系管理员进行处理
</el-alert>
</div>
</div>
</template>
<el-table :data="tableData" v-loading="loading" stripe class="modern-table">
<el-table-column type="index" label="序号" width="70" align="center">
<template #header>
<el-icon><List /></el-icon>
</template>
</el-table-column>
<el-table-column prop="templateTitle" label="模板类型名称" min-width="180" show-overflow-tooltip />
<el-table-column prop="templateType" label="模板类型编码" min-width="180" show-overflow-tooltip />
<el-table-column prop="templateName" label="模板名称" min-width="220" show-overflow-tooltip />
<el-table-column prop="updateTime" label="更新时间" width="180" show-overflow-tooltip />
<el-table-column label="操作" width="260" align="center" fixed="right">
<template #default="{ row }">
<el-button
type="primary"
link
icon="Download"
@click="handleDownload(row)"
v-auth="'purchase_template_view'">
下载
</el-button>
<el-button
type="primary"
link
icon="UploadFilled"
@click="openUploadDialog(row)"
v-auth="'purchase_template_add'">
重新上传
</el-button>
<el-button
type="primary"
link
icon="Edit"
@click="openEditDialog(row)"
v-auth="'purchase_template_add'">
编辑
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<el-dialog v-model="uploadDialogVisible" title="上传模板" width="450px" destroy-on-close>
<el-form :model="uploadForm" label-width="100px">
<el-form-item label="模板类型编码" required>
<el-input
v-model="uploadForm.templateType"
placeholder="例如: business_negotiation, inquiry"
:disabled="!!uploadForm.lockType"
/>
</el-form-item>
<el-form-item label="模板类型名称">
<el-input
v-model="uploadForm.templateTitle"
placeholder="例如: 部门采购询价模版"
/>
</el-form-item>
<el-form-item label="模板文件" required>
<el-upload
class="upload-block"
:auto-upload="false"
:limit="1"
:file-list="fileList"
:on-change="handleFileChange"
:on-remove="handleFileRemove"
>
<el-button type="primary" icon="UploadFilled">选择文件</el-button>
<template #tip>
<div class="el-upload__tip">支持 docdocx Word 模板文件上传后前端下载将使用该文件</div>
</template>
</el-upload>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="uploadDialogVisible = false"> </el-button>
<el-button type="primary" :loading="uploading" @click="handleUploadConfirm"> </el-button>
</template>
</el-dialog>
<el-dialog v-model="editDialogVisible" title="编辑模板" width="420px" destroy-on-close>
<el-form :model="editForm" label-width="100px">
<el-form-item label="模板类型编码">
<el-input v-model="editForm.templateType" disabled />
</el-form-item>
<el-form-item label="模板类型名称" required>
<el-input v-model="editForm.templateTitle" placeholder="请输入模板类型名称" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="editDialogVisible = false"> </el-button>
<el-button type="primary" :loading="editing" @click="handleEditConfirm"> </el-button>
</template>
</el-dialog>
</div>
</div>
</template>
<script setup lang="ts" name="PurchasingTemplateManage">
import { ref, reactive, onMounted } from 'vue';
import { Document, List, UploadFilled, Download, Edit } from '@element-plus/icons-vue';
import { listTemplates, uploadTemplate, getTemplateDownloadUrl, updateTemplateTitle } from '/@/api/purchase/purchasingtemplate';
import { useMessage } from '/@/hooks/message';
const loading = ref(false);
const tableData = ref<any[]>([]);
const uploadDialogVisible = ref(false);
const uploading = ref(false);
const uploadForm = reactive<{
templateType: string;
templateTitle: string;
lockType?: boolean;
}>({
templateType: '',
templateTitle: '',
lockType: false,
});
const editDialogVisible = ref(false);
const editing = ref(false);
const editForm = reactive<{
id: number | null;
templateType: string;
templateTitle: string;
}>({
id: null,
templateType: '',
templateTitle: '',
});
const fileList = ref<any[]>([]);
const currentFile = ref<File | null>(null);
const fetchData = async () => {
loading.value = true;
try {
const res = await listTemplates();
tableData.value = (res && res.data) || [];
} catch (e) {
tableData.value = [];
} finally {
loading.value = false;
}
};
onMounted(fetchData);
const openUploadDialog = (row?: any) => {
uploadDialogVisible.value = true;
uploadForm.templateType = row?.templateType || '';
uploadForm.templateTitle = row?.templateTitle || '';
uploadForm.lockType = !!row?.templateType;
fileList.value = [];
currentFile.value = null;
};
const handleFileChange = (file: any, files: any[]) => {
fileList.value = files.slice(-1);
currentFile.value = file.raw || null;
};
const handleFileRemove = () => {
fileList.value = [];
currentFile.value = null;
};
const handleUploadConfirm = async () => {
if (!uploadForm.templateType || !uploadForm.templateType.trim()) {
useMessage().error('请填写模板类型编码');
return;
}
if (!currentFile.value) {
useMessage().error('请选择要上传的模板文件');
return;
}
uploading.value = true;
try {
const formData = new FormData();
formData.append('type', uploadForm.templateType.trim());
if (uploadForm.templateTitle && uploadForm.templateTitle.trim()) {
formData.append('title', uploadForm.templateTitle.trim());
}
formData.append('file', currentFile.value);
await uploadTemplate(formData);
useMessage().success('模板上传成功');
uploadDialogVisible.value = false;
await fetchData();
} catch (e) {
useMessage().error('模板上传失败');
} finally {
uploading.value = false;
}
};
const handleDownload = async (row: any) => {
if (!row?.templateType) {
useMessage().error('缺少模板类型编码');
return;
}
const url = getTemplateDownloadUrl(row.templateType);
const fileName = row.templateName || row.templateTitle || row.templateType;
try {
await (window as any).other?.downBlobFile?.(url, {}, fileName) ||
// 兼容直接使用工具函数
(await import('/@/utils/other')).default.downBlobFile(url, {}, fileName);
} catch (e) {
// 如果工具函数不可用,则退回 window.open
window.open(url, '_blank');
}
};
const openEditDialog = (row: any) => {
editDialogVisible.value = true;
editForm.id = row?.id ?? null;
editForm.templateType = row?.templateType || '';
editForm.templateTitle = row?.templateTitle || '';
};
const handleEditConfirm = async () => {
if (!editForm.id) {
useMessage().error('缺少模板ID');
return;
}
if (!editForm.templateTitle || !editForm.templateTitle.trim()) {
useMessage().error('请输入模板类型名称');
return;
}
editing.value = true;
try {
await updateTemplateTitle({
id: editForm.id,
templateTitle: editForm.templateTitle.trim(),
});
useMessage().success('保存成功');
editDialogVisible.value = false;
await fetchData();
} catch (e) {
useMessage().error('保存失败');
} finally {
editing.value = false;
}
};
</script>
<style scoped>
.upload-block {
display: inline-block;
}
</style>