feat/合同模板管理
This commit is contained in:
parent
a19f48034d
commit
5fb095f392
3296
Swagger.json
3296
Swagger.json
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,100 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 合同模板列表
|
||||
export function listContractTemplates(query) {
|
||||
return request({
|
||||
url: '/api/v1/contract-template',
|
||||
method: 'get',
|
||||
params: {
|
||||
contractType: query.contractType,
|
||||
templateName: query.templateName,
|
||||
pageSize: query.pageSize,
|
||||
pageIndex: query.pageNum
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取单个合同模板详情
|
||||
export function getContractTemplate(id) {
|
||||
return request({
|
||||
url: `/api/v1/contract-template/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增合同模板(文件必填)
|
||||
export function createContractTemplate(data) {
|
||||
const formData = new FormData()
|
||||
formData.append('contractType', data.contractType)
|
||||
formData.append('templateName', data.templateName)
|
||||
formData.append('publishDate', data.publishDate)
|
||||
if (data.file) {
|
||||
formData.append('file', data.file)
|
||||
}
|
||||
|
||||
return request({
|
||||
url: '/api/v1/contract-template',
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
repeatSubmit: false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 修改合同模板(文件可选)
|
||||
export function updateContractTemplate(data) {
|
||||
const formData = new FormData()
|
||||
if (data.contractType) {
|
||||
formData.append('contractType', data.contractType)
|
||||
}
|
||||
if (data.templateName) {
|
||||
formData.append('templateName', data.templateName)
|
||||
}
|
||||
if (data.publishDate) {
|
||||
formData.append('publishDate', data.publishDate)
|
||||
}
|
||||
if (data.file) {
|
||||
formData.append('file', data.file)
|
||||
}
|
||||
|
||||
return request({
|
||||
url: `/api/v1/contract-template/${data.id}`,
|
||||
method: 'put',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
repeatSubmit: false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 仅更新模板文件
|
||||
export function updateContractTemplateFile(id, file) {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
|
||||
return request({
|
||||
url: `/api/v1/contract-template/${id}/file`,
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
repeatSubmit: false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 删除合同模板(支持批量)
|
||||
export function deleteContractTemplates(ids) {
|
||||
return request({
|
||||
url: '/api/v1/contract-template',
|
||||
method: 'delete',
|
||||
data: {
|
||||
ids
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -86,25 +86,7 @@ export const constantRoutes = [
|
|||
]
|
||||
},
|
||||
// ==================== 采购管理 ====================
|
||||
{
|
||||
path: '/purchase',
|
||||
component: Layout,
|
||||
redirect: 'noRedirect',
|
||||
alwaysShow: true,
|
||||
name: 'Purchase',
|
||||
meta: {
|
||||
title: '采购管理',
|
||||
icon: 'shopping'
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'task-management',
|
||||
component: () => import('@/views/purchase/task-management'),
|
||||
name: 'PurchaseTaskManagement',
|
||||
meta: { title: '采购任务管理', icon: 'list' }
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// {
|
||||
// path: '/purchase',
|
||||
// component: Layout,
|
||||
|
|
@ -117,6 +99,12 @@ export const constantRoutes = [
|
|||
// },
|
||||
// children: [
|
||||
// {
|
||||
// path: 'task-management',
|
||||
// component: () => import('@/views/purchase/task-management'),
|
||||
// name: 'PurchaseTaskManagement',
|
||||
// meta: { title: '采购任务管理', icon: 'list' }
|
||||
// }
|
||||
// {
|
||||
// path: 'order-list',
|
||||
// component: () => import('@/views/purchase/order-list'),
|
||||
// name: 'PurchaseOrderList',
|
||||
|
|
|
|||
|
|
@ -3,6 +3,14 @@
|
|||
<el-card>
|
||||
<div class="filter-toolbar">
|
||||
<el-form :model="queryParams" ref="queryForm" :inline="true">
|
||||
<el-form-item label="模板名称" prop="templateName">
|
||||
<el-input
|
||||
v-model="queryParams.templateName"
|
||||
placeholder="请输入模板名称"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="合同类型" prop="contractType">
|
||||
<el-select v-model="queryParams.contractType" placeholder="全部" clearable style="width: 150px">
|
||||
<el-option label="全部" value="" />
|
||||
|
|
@ -19,13 +27,13 @@
|
|||
</div>
|
||||
|
||||
<el-table v-loading="loading" :data="templateList" border style="width: 100%; margin-top: 20px;">
|
||||
<el-table-column prop="contractCode" label="合同编号" />
|
||||
<el-table-column prop="contractName" label="合同名称" />
|
||||
<el-table-column prop="templateName" label="模板名称" />
|
||||
<el-table-column prop="contractType" label="合同类型">
|
||||
<template #default="scope">
|
||||
{{ getContractTypeName(scope.row.contractType) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="publishDate" label="发布日期" />
|
||||
<el-table-column label="操作" width="280" fixed="right" align="center">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
|
|
@ -58,18 +66,10 @@
|
|||
:rules="templateFormRules"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="合同编号" prop="contractCode">
|
||||
<el-form-item label="模板名称" prop="templateName">
|
||||
<el-input
|
||||
v-model="templateForm.contractCode"
|
||||
placeholder="请输入合同编号"
|
||||
:disabled="isEdit"
|
||||
maxlength="50"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="合同名称" prop="contractName">
|
||||
<el-input
|
||||
v-model="templateForm.contractName"
|
||||
placeholder="请输入合同名称"
|
||||
v-model="templateForm.templateName"
|
||||
placeholder="请输入模板名称"
|
||||
maxlength="100"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
|
@ -83,14 +83,22 @@
|
|||
<el-option label="销售合同" value="sales" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="发布日期" prop="publishDate">
|
||||
<el-date-picker
|
||||
v-model="templateForm.publishDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择发布日期"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="合同模板" prop="templateFile">
|
||||
<el-upload
|
||||
ref="formUploadRef"
|
||||
:file-list="formFileList"
|
||||
:auto-upload="false"
|
||||
:on-change="handleFormFileChange"
|
||||
:on-remove="handleFormFileRemove"
|
||||
:limit="1"
|
||||
@change="handleFormFileChange"
|
||||
@remove="handleFormFileRemove"
|
||||
accept=".doc,.docx,.xls,.xlsx,.pdf"
|
||||
>
|
||||
<el-button type="primary">选择文件</el-button>
|
||||
|
|
@ -100,11 +108,15 @@
|
|||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<div v-if="templateForm.templateFile" style="margin-top: 10px;">
|
||||
<el-button link type="primary" size="small" @click="handlePreviewFile(templateForm.templateFile)">
|
||||
{{ templateForm.templateFile.name }}
|
||||
<div v-if="templateForm.templateFilePath && !templateForm.file" style="margin-top: 10px;">
|
||||
<span style="margin-right: 10px;">当前文件:</span>
|
||||
<el-button link type="primary" size="small" @click="handlePreviewFile(templateForm.templateFilePath)">
|
||||
{{ getFileName(templateForm.templateFilePath) }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="templateForm.file" style="margin-top: 10px; color: #409eff;">
|
||||
<span>已选择新文件:{{ templateForm.file.name }}</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
|
|
@ -123,6 +135,7 @@
|
|||
<script setup name="ContractTemplate">
|
||||
import { ref, reactive, computed, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { listContractTemplates, createContractTemplate, updateContractTemplate, deleteContractTemplates } from '@/api/contractTemplate'
|
||||
import Pagination from '@/components/Pagination'
|
||||
|
||||
const loading = ref(false)
|
||||
|
|
@ -138,28 +151,41 @@ const formFileList = ref([])
|
|||
const queryParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
templateName: '',
|
||||
contractType: ''
|
||||
})
|
||||
|
||||
const templateForm = reactive({
|
||||
id: null,
|
||||
contractCode: '',
|
||||
contractName: '',
|
||||
templateName: '',
|
||||
contractType: '',
|
||||
templateFile: null
|
||||
publishDate: '',
|
||||
templateFile: '',
|
||||
file: null,
|
||||
templateFilePath: ''
|
||||
})
|
||||
|
||||
const validateTemplateFile = (rule, value, callback) => {
|
||||
if (!templateForm.file && !templateForm.templateFilePath) {
|
||||
callback(new Error('请上传合同模板文件'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
const templateFormRules = {
|
||||
contractCode: [
|
||||
{ required: true, message: '请输入合同编号', trigger: 'blur' },
|
||||
{ min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
|
||||
],
|
||||
contractName: [
|
||||
{ required: true, message: '请输入合同名称', trigger: 'blur' },
|
||||
templateName: [
|
||||
{ required: true, message: '请输入模板名称', trigger: 'blur' },
|
||||
{ min: 2, max: 100, message: '长度在 2 到 100 个字符', trigger: 'blur' }
|
||||
],
|
||||
contractType: [
|
||||
{ required: true, message: '请选择合同类型', trigger: 'change' }
|
||||
],
|
||||
publishDate: [
|
||||
{ required: true, message: '请选择发布日期', trigger: 'change' }
|
||||
],
|
||||
templateFile: [
|
||||
{ required: true, validator: validateTemplateFile, trigger: 'change' }
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -176,60 +202,58 @@ const getContractTypeName = (type) => {
|
|||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const mockData = JSON.parse(localStorage.getItem('mock_contract_templates') || '[]')
|
||||
// 过滤掉贸易合同类型的数据,只保留采购合同和销售合同
|
||||
let filtered = mockData.filter(item => {
|
||||
// 移除贸易合同类型的数据
|
||||
if (item.contractType === 'trade') return false
|
||||
// 根据查询条件过滤
|
||||
if (queryParams.contractType && item.contractType !== queryParams.contractType) return false
|
||||
return true
|
||||
})
|
||||
const res = await listContractTemplates(queryParams)
|
||||
const pageData = res.data || {}
|
||||
const list = pageData.list || []
|
||||
total.value = pageData.count || 0
|
||||
|
||||
// 如果有被过滤掉的贸易合同数据,更新localStorage
|
||||
if (filtered.length !== mockData.length) {
|
||||
localStorage.setItem('mock_contract_templates', JSON.stringify(filtered))
|
||||
}
|
||||
|
||||
const start = (queryParams.pageNum - 1) * queryParams.pageSize
|
||||
const end = start + queryParams.pageSize
|
||||
templateList.value = filtered.slice(start, end)
|
||||
total.value = filtered.length
|
||||
|
||||
if (filtered.length === 0) {
|
||||
generateMockData()
|
||||
}
|
||||
templateList.value = list.map(item => ({
|
||||
...item,
|
||||
publishDate: formatPublishDate(item.publishDate)
|
||||
}))
|
||||
} catch (error) {
|
||||
ElMessage.error('获取合同模板列表失败:' + error.message)
|
||||
ElMessage.error('获取合同模板列表失败:' + (error.message || '未知错误'))
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const generateMockData = () => {
|
||||
setTimeout(() => {
|
||||
const contractTypes = ['purchase', 'sales']
|
||||
const contractTypeNames = {
|
||||
'purchase': '采购合同',
|
||||
'sales': '销售合同'
|
||||
// 将后端返回的时间(例如 2026-01-13T00:00:00+08:00)
|
||||
// 格式化为 YYYY-MM-DD,效果等价于 moment(value).format('YYYY-MM-DD')
|
||||
const formatPublishDate = (value) => {
|
||||
if (!value) return ''
|
||||
// 如果本身已经是 YYYY-MM-DD 形式,直接返回
|
||||
if (/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
||||
return value
|
||||
}
|
||||
const newTemplates = []
|
||||
const now = Date.now()
|
||||
for (let i = 1; i <= 10; i++) {
|
||||
const contractType = contractTypes[Math.floor(Math.random() * contractTypes.length)]
|
||||
newTemplates.push({
|
||||
id: i,
|
||||
contractCode: 'HT' + String(i).padStart(4, '0'),
|
||||
contractName: contractTypeNames[contractType] + '模板_' + i,
|
||||
contractType: contractType,
|
||||
templateFile: i <= 3 ? { name: `合同模板_${i}.docx`, url: '#', type: 'file' } : null,
|
||||
createTime: new Date(now - i * 30 * 86400000).toISOString(),
|
||||
updateTime: new Date(now - i * 30 * 86400000).toISOString()
|
||||
})
|
||||
// 优先截取前 10 位(2026-01-13)
|
||||
if (value.length >= 10) {
|
||||
return value.substring(0, 10)
|
||||
}
|
||||
localStorage.setItem('mock_contract_templates', JSON.stringify(newTemplates))
|
||||
getList()
|
||||
}, 10)
|
||||
// 兜底:尝试用 Date 解析再转成 YYYY-MM-DD
|
||||
const d = new Date(value)
|
||||
if (!isNaN(d.getTime())) {
|
||||
const y = d.getFullYear()
|
||||
const m = String(d.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(d.getDate()).padStart(2, '0')
|
||||
return `${y}-${m}-${day}`
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
const getFileName = (path) => {
|
||||
if (!path) return ''
|
||||
const parts = path.split('/')
|
||||
return parts[parts.length - 1]
|
||||
}
|
||||
|
||||
const getFileUrl = (path) => {
|
||||
if (!path) return ''
|
||||
if (/^https?:\/\//.test(path)) {
|
||||
return path
|
||||
}
|
||||
const base = import.meta.env.VITE_APP_BASE_API || ''
|
||||
return `${base.replace(/\/+$/, '')}/${path.replace(/^\/+/, '')}`
|
||||
}
|
||||
|
||||
const handleQuery = () => {
|
||||
|
|
@ -238,29 +262,14 @@ const handleQuery = () => {
|
|||
}
|
||||
|
||||
const resetQuery = () => {
|
||||
queryParams.templateName = ''
|
||||
queryParams.contractType = ''
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
const generateContractCode = () => {
|
||||
const mockData = JSON.parse(localStorage.getItem('mock_contract_templates') || '[]')
|
||||
let maxCode = 0
|
||||
mockData.forEach(item => {
|
||||
const match = item.contractCode.match(/^HT(\d+)$/)
|
||||
if (match) {
|
||||
const num = parseInt(match[1])
|
||||
if (num > maxCode) {
|
||||
maxCode = num
|
||||
}
|
||||
}
|
||||
})
|
||||
return 'HT' + String(maxCode + 1).padStart(4, '0')
|
||||
}
|
||||
|
||||
const handleAdd = () => {
|
||||
isEdit.value = false
|
||||
resetForm()
|
||||
templateForm.contractCode = generateContractCode()
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
|
|
@ -268,17 +277,19 @@ const handleEdit = (row) => {
|
|||
isEdit.value = true
|
||||
Object.assign(templateForm, {
|
||||
id: row.id,
|
||||
contractCode: row.contractCode,
|
||||
contractName: row.contractName,
|
||||
templateName: row.templateName,
|
||||
contractType: row.contractType,
|
||||
templateFile: row.templateFile || null
|
||||
publishDate: formatPublishDate(row.publishDate),
|
||||
templateFile: row.templateFile ? '1' : '',
|
||||
file: null,
|
||||
templateFilePath: row.templateFile || ''
|
||||
})
|
||||
|
||||
// 设置文件列表
|
||||
if (row.templateFile) {
|
||||
formFileList.value = [{
|
||||
name: row.templateFile.name,
|
||||
url: row.templateFile.url
|
||||
name: getFileName(row.templateFile),
|
||||
url: getFileUrl(row.templateFile)
|
||||
}]
|
||||
} else {
|
||||
formFileList.value = []
|
||||
|
|
@ -288,10 +299,10 @@ const handleEdit = (row) => {
|
|||
}
|
||||
|
||||
const handleDownload = (row) => {
|
||||
if (row.templateFile && row.templateFile.url && row.templateFile.url !== '#') {
|
||||
if (row.templateFile) {
|
||||
const link = document.createElement('a')
|
||||
link.href = row.templateFile.url
|
||||
link.download = row.templateFile.name
|
||||
link.href = getFileUrl(row.templateFile)
|
||||
link.download = getFileName(row.templateFile)
|
||||
link.click()
|
||||
ElMessage.success('下载成功')
|
||||
} else {
|
||||
|
|
@ -304,57 +315,54 @@ const handleDelete = (row) => {
|
|||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const templates = JSON.parse(localStorage.getItem('mock_contract_templates') || '[]')
|
||||
const filtered = templates.filter(t => t.id != row.id)
|
||||
localStorage.setItem('mock_contract_templates', JSON.stringify(filtered))
|
||||
}).then(async () => {
|
||||
try {
|
||||
await deleteContractTemplates([row.id])
|
||||
ElMessage.success('删除成功')
|
||||
getList()
|
||||
} catch (error) {
|
||||
ElMessage.error('删除失败:' + (error.message || '未知错误'))
|
||||
}
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
const handleFormFileChange = (file) => {
|
||||
const handleFormFileChange = (uploadFile, uploadFiles) => {
|
||||
const rawFile = uploadFile?.raw
|
||||
|
||||
// 检查文件大小(10MB)
|
||||
const maxSize = 10 * 1024 * 1024
|
||||
if (file.raw && file.raw.size > maxSize) {
|
||||
if (rawFile && rawFile.size > maxSize) {
|
||||
ElMessage.warning('文件大小不能超过 10MB')
|
||||
formUploadRef.value?.handleRemove(file)
|
||||
formUploadRef.value?.clearFiles()
|
||||
return
|
||||
}
|
||||
|
||||
// 读取文件并转换为 base64
|
||||
if (file.raw) {
|
||||
const reader = new FileReader()
|
||||
reader.onload = (e) => {
|
||||
const fileType = file.raw.type
|
||||
let type = 'file'
|
||||
if (fileType.includes('pdf')) {
|
||||
type = 'pdf'
|
||||
} else if (fileType.includes('word') || fileType.includes('document')) {
|
||||
type = 'doc'
|
||||
} else if (fileType.includes('sheet') || fileType.includes('excel')) {
|
||||
type = 'xls'
|
||||
}
|
||||
// 每次选择都只保留当前这一个文件,覆盖之前的
|
||||
formFileList.value = uploadFile ? [uploadFile] : []
|
||||
|
||||
templateForm.templateFile = {
|
||||
name: file.name,
|
||||
url: e.target.result,
|
||||
type: type,
|
||||
size: file.raw.size
|
||||
// 直接保存原始文件,用于表单提交
|
||||
if (rawFile) {
|
||||
templateForm.file = rawFile
|
||||
templateForm.templateFile = '1'
|
||||
// 编辑模式下重新选择文件时,清除旧文件路径的展示
|
||||
if (isEdit.value) {
|
||||
templateForm.templateFilePath = ''
|
||||
}
|
||||
}
|
||||
reader.readAsDataURL(file.raw)
|
||||
templateFormRef.value?.validateField('templateFile')
|
||||
}
|
||||
}
|
||||
|
||||
const handleFormFileRemove = () => {
|
||||
templateForm.templateFile = null
|
||||
templateForm.file = null
|
||||
templateForm.templateFilePath = ''
|
||||
templateForm.templateFile = ''
|
||||
formFileList.value = []
|
||||
templateFormRef.value?.validateField('templateFile')
|
||||
}
|
||||
|
||||
const handlePreviewFile = (file) => {
|
||||
if (file && file.url && file.url !== '#') {
|
||||
window.open(file.url, '_blank')
|
||||
if (file) {
|
||||
window.open(getFileUrl(file), '_blank')
|
||||
} else {
|
||||
ElMessage.warning('文件不存在')
|
||||
}
|
||||
|
|
@ -363,10 +371,12 @@ const handlePreviewFile = (file) => {
|
|||
const resetForm = () => {
|
||||
Object.assign(templateForm, {
|
||||
id: null,
|
||||
contractCode: '',
|
||||
contractName: '',
|
||||
templateName: '',
|
||||
contractType: '',
|
||||
templateFile: null
|
||||
publishDate: '',
|
||||
templateFile: '',
|
||||
file: null,
|
||||
templateFilePath: ''
|
||||
})
|
||||
formFileList.value = []
|
||||
templateFormRef.value?.clearValidate()
|
||||
|
|
@ -380,65 +390,36 @@ const handleSubmit = async () => {
|
|||
if (!valid) return
|
||||
|
||||
submitLoading.value = true
|
||||
;(async () => {
|
||||
try {
|
||||
const mockData = JSON.parse(localStorage.getItem('mock_contract_templates') || '[]')
|
||||
const now = new Date().toISOString()
|
||||
|
||||
if (isEdit.value) {
|
||||
// 编辑
|
||||
const index = mockData.findIndex(item => item.id === templateForm.id)
|
||||
if (index !== -1) {
|
||||
// 检查合同编号是否重复(排除当前编辑的项)
|
||||
const codeExists = mockData.find(item =>
|
||||
item.id !== templateForm.id &&
|
||||
item.contractCode === templateForm.contractCode
|
||||
)
|
||||
if (codeExists) {
|
||||
ElMessage.warning('合同编号已存在')
|
||||
submitLoading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
mockData[index] = {
|
||||
...mockData[index],
|
||||
contractCode: templateForm.contractCode,
|
||||
contractName: templateForm.contractName,
|
||||
// 编辑:一个接口同时更新基本信息和(可选)文件
|
||||
await updateContractTemplate({
|
||||
id: templateForm.id,
|
||||
contractType: templateForm.contractType,
|
||||
templateFile: templateForm.templateFile,
|
||||
updateTime: now
|
||||
}
|
||||
}
|
||||
templateName: templateForm.templateName,
|
||||
publishDate: templateForm.publishDate,
|
||||
file: templateForm.file || undefined
|
||||
})
|
||||
} else {
|
||||
// 新增
|
||||
// 检查合同编号是否重复
|
||||
const codeExists = mockData.find(item => item.contractCode === templateForm.contractCode)
|
||||
if (codeExists) {
|
||||
ElMessage.warning('合同编号已存在')
|
||||
submitLoading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
const newId = mockData.length > 0 ? Math.max(...mockData.map(item => item.id)) + 1 : 1
|
||||
mockData.push({
|
||||
id: newId,
|
||||
contractCode: templateForm.contractCode,
|
||||
contractName: templateForm.contractName,
|
||||
// 新增:必须上传文件
|
||||
await createContractTemplate({
|
||||
contractType: templateForm.contractType,
|
||||
templateFile: templateForm.templateFile,
|
||||
createTime: now,
|
||||
updateTime: now
|
||||
templateName: templateForm.templateName,
|
||||
publishDate: templateForm.publishDate,
|
||||
file: templateForm.file
|
||||
})
|
||||
}
|
||||
|
||||
localStorage.setItem('mock_contract_templates', JSON.stringify(mockData))
|
||||
ElMessage.success(isEdit.value ? '编辑成功' : '新增成功')
|
||||
dialogVisible.value = false
|
||||
getList()
|
||||
} catch (error) {
|
||||
ElMessage.error('操作失败:' + error.message)
|
||||
ElMessage.error('操作失败:' + (error.message || '未知错误'))
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
})()
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue