采购更新
This commit is contained in:
@@ -41,33 +41,63 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-alert>
|
</el-alert>
|
||||||
|
|
||||||
<!-- 文件上传 -->
|
<!-- 已上传的采购文件列表 -->
|
||||||
<el-upload
|
<div v-if="uploadedDocList.length > 0" class="uploaded-docs mb-4">
|
||||||
ref="uploadRef"
|
<div class="section-title">已上传的采购文件</div>
|
||||||
:action="uploadAction"
|
<el-table :data="uploadedDocList" stripe size="small">
|
||||||
:headers="uploadHeaders"
|
<el-table-column type="index" label="序号" width="70" align="center" />
|
||||||
:on-success="handleUploadSuccess"
|
<el-table-column prop="fileName" label="文件名称" min-width="200" show-overflow-tooltip />
|
||||||
:on-error="handleUploadError"
|
<el-table-column prop="version" label="版本" width="80" align="center" />
|
||||||
:before-upload="beforeUpload"
|
<el-table-column prop="uploadByName" label="上传人" width="100" align="center" />
|
||||||
:file-list="fileList"
|
<el-table-column prop="uploadTime" label="上传时间" width="160" align="center" />
|
||||||
:auto-upload="false"
|
<el-table-column label="状态" width="120" align="center">
|
||||||
:limit="1"
|
<template #default="scope">
|
||||||
accept=".doc,.docx,.pdf"
|
<el-tag :type="getStatusType(scope.row.status)" size="small">
|
||||||
class="upload-demo">
|
{{ getStatusLabel(scope.row.status) }}
|
||||||
<el-button type="primary">选择文件</el-button>
|
</el-tag>
|
||||||
<template #tip>
|
</template>
|
||||||
<div class="el-upload__tip">支持 .doc, .docx, .pdf 格式,文件大小不超过 50MB</div>
|
</el-table-column>
|
||||||
</template>
|
<el-table-column label="操作" width="100" align="center">
|
||||||
</el-upload>
|
<template #default="scope">
|
||||||
|
<el-button type="primary" link icon="Download" @click="handleDownloadDoc(scope.row)">下载</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
<el-button
|
<!-- 文件上传区域 -->
|
||||||
type="success"
|
<div v-if="canUpload" class="upload-area">
|
||||||
:loading="uploadSubmitting"
|
<div class="section-title">{{ projectInfo.status === 'RETURNED' ? '重新上传招标文件' : '上传招标文件' }}</div>
|
||||||
:disabled="fileList.length === 0 || !canUpload"
|
<el-upload
|
||||||
@click="handleUploadSubmit"
|
ref="uploadRef"
|
||||||
class="mt-4">
|
:action="uploadAction"
|
||||||
{{ projectInfo.status === 'RETURNED' ? '重新上传招标文件' : '上传招标文件' }}
|
:headers="uploadHeaders"
|
||||||
</el-button>
|
:data="uploadData"
|
||||||
|
:on-success="handleUploadSuccess"
|
||||||
|
:on-error="handleUploadError"
|
||||||
|
:before-upload="beforeUpload"
|
||||||
|
:on-change="handleFileChange"
|
||||||
|
:file-list="fileList"
|
||||||
|
:auto-upload="false"
|
||||||
|
:limit="1"
|
||||||
|
accept=".doc,.docx,.pdf"
|
||||||
|
class="upload-demo">
|
||||||
|
<el-button type="primary">选择文件</el-button>
|
||||||
|
<template #tip>
|
||||||
|
<div class="el-upload__tip">支持 .doc, .docx, .pdf 格式,文件大小不超过 50MB</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
|
||||||
|
<div class="action-buttons mt-4">
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
:loading="uploadSubmitting"
|
||||||
|
:disabled="fileList.length === 0"
|
||||||
|
@click="handleUploadSubmit">
|
||||||
|
{{ projectInfo.status === 'RETURNED' ? '重新上传并提交' : '上传并提交' }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<el-alert v-if="!canUpload" type="warning" :closable="false" class="mt-4">
|
<el-alert v-if="!canUpload" type="warning" :closable="false" class="mt-4">
|
||||||
<template #title>
|
<template #title>
|
||||||
@@ -93,7 +123,7 @@
|
|||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import { useMessage } from '/@/hooks/message'
|
import { useMessage } from '/@/hooks/message'
|
||||||
import { Session } from '/@/utils/storage'
|
import { Session } from '/@/utils/storage'
|
||||||
import { getAgentRequirementFiles, getAgentApplyDetail, uploadAgentDoc, reuploadAgentDoc, getDocList, downloadFileById } from '/@/api/purchase/purchasingrequisition'
|
import { getAgentRequirementFiles, getAgentApplyDetail, getDocList, downloadFileById, uploadAgentDoc, reuploadAgentDoc } from '/@/api/purchase/purchasingrequisition'
|
||||||
import type { UploadInstance, UploadProps, UploadUserFile } from 'element-plus'
|
import type { UploadInstance, UploadProps, UploadUserFile } from 'element-plus'
|
||||||
|
|
||||||
const emit = defineEmits(['refresh'])
|
const emit = defineEmits(['refresh'])
|
||||||
@@ -106,11 +136,13 @@ const requirementLoading = ref(false)
|
|||||||
const uploadSubmitting = ref(false)
|
const uploadSubmitting = ref(false)
|
||||||
const uploadRef = ref<UploadInstance>()
|
const uploadRef = ref<UploadInstance>()
|
||||||
const fileList = ref<UploadUserFile[]>([])
|
const fileList = ref<UploadUserFile[]>([])
|
||||||
|
const uploadedDocList = ref<any[]>([])
|
||||||
|
const docListLoading = ref(false)
|
||||||
|
|
||||||
// 上传配置
|
// 上传配置 - 使用采购文件上传接口
|
||||||
const uploadAction = computed(() => {
|
const uploadAction = computed(() => {
|
||||||
const baseUrl = import.meta.env.VITE_API_URL || ''
|
const baseUrl = import.meta.env.VITE_API_URL || ''
|
||||||
return `${baseUrl}/admin/sys-file/upload`
|
return `${baseUrl}/purchase/purchasingfiles/upload`
|
||||||
})
|
})
|
||||||
|
|
||||||
const uploadHeaders = computed(() => {
|
const uploadHeaders = computed(() => {
|
||||||
@@ -121,6 +153,12 @@ const uploadHeaders = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 上传时附带的额外参数
|
||||||
|
const uploadData = computed(() => ({
|
||||||
|
fileType: '130', // 招标文件类型
|
||||||
|
purchaseId: projectInfo.value.applyId || ''
|
||||||
|
}))
|
||||||
|
|
||||||
// 是否可以上传
|
// 是否可以上传
|
||||||
const canUpload = computed(() => {
|
const canUpload = computed(() => {
|
||||||
const status = projectInfo.value.status
|
const status = projectInfo.value.status
|
||||||
@@ -132,8 +170,10 @@ const open = async (row: any) => {
|
|||||||
visible.value = true
|
visible.value = true
|
||||||
activeTab.value = 'info'
|
activeTab.value = 'info'
|
||||||
fileList.value = []
|
fileList.value = []
|
||||||
|
uploadedDocList.value = []
|
||||||
await loadProjectDetail()
|
await loadProjectDetail()
|
||||||
await loadRequirementFiles()
|
await loadRequirementFiles()
|
||||||
|
await loadUploadedDocList()
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadProjectDetail = async () => {
|
const loadProjectDetail = async () => {
|
||||||
@@ -159,12 +199,22 @@ const loadRequirementFiles = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const loadUploadedDocList = async () => {
|
||||||
|
docListLoading.value = true
|
||||||
|
try {
|
||||||
|
const res = await getDocList(projectInfo.value.applyId)
|
||||||
|
uploadedDocList.value = res?.data || []
|
||||||
|
} catch (e: any) {
|
||||||
|
uploadedDocList.value = []
|
||||||
|
} finally {
|
||||||
|
docListLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleDownload = async (row: any) => {
|
const handleDownload = async (row: any) => {
|
||||||
try {
|
try {
|
||||||
const res = await downloadFileById(row.id)
|
const res = await downloadFileById(row.id)
|
||||||
// 从响应头获取文件名,或使用原始文件名
|
|
||||||
const fileName = row.fileName || row.fileTitle || 'download'
|
const fileName = row.fileName || row.fileTitle || 'download'
|
||||||
// 创建 blob 并下载
|
|
||||||
const blob = new Blob([res])
|
const blob = new Blob([res])
|
||||||
const url = window.URL.createObjectURL(blob)
|
const url = window.URL.createObjectURL(blob)
|
||||||
const link = document.createElement('a')
|
const link = document.createElement('a')
|
||||||
@@ -179,6 +229,19 @@ const handleDownload = async (row: any) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleDownloadDoc = async (row: any) => {
|
||||||
|
try {
|
||||||
|
// 使用采购文件下载接口
|
||||||
|
const baseUrl = import.meta.env.VITE_API_URL || ''
|
||||||
|
const token = Session.getToken()
|
||||||
|
const tenantId = Session.getTenant() || '1'
|
||||||
|
const url = `${baseUrl}/purchase/purchasingdoc/download/${row.id}?Authorization=Bearer ${token}&TENANT-ID=${tenantId}`
|
||||||
|
window.open(url, '_blank')
|
||||||
|
} catch (e: any) {
|
||||||
|
useMessage().error(e?.msg || '下载失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
|
const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
|
||||||
const allowedTypes = ['application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/pdf']
|
const allowedTypes = ['application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/pdf']
|
||||||
const allowedExtensions = ['.doc', '.docx', '.pdf']
|
const allowedExtensions = ['.doc', '.docx', '.pdf']
|
||||||
@@ -197,11 +260,40 @@ const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleUploadSuccess: UploadProps['onSuccess'] = (response: any, uploadFile: any) => {
|
const handleFileChange: UploadProps['onChange'] = (uploadFile, uploadFiles) => {
|
||||||
|
fileList.value = uploadFiles
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleUploadSuccess: UploadProps['onSuccess'] = async (response: any, uploadFile: any) => {
|
||||||
if (response?.code === 0 || response?.code === 200) {
|
if (response?.code === 0 || response?.code === 200) {
|
||||||
const fileUrl = response.data?.url || response.data?.fileUrl || response.data?.filePath
|
// 文件上传成功后,调用采购文件提交接口
|
||||||
const fileName = uploadFile.name
|
const fileData = response.data
|
||||||
submitUpload(fileName, fileUrl)
|
try {
|
||||||
|
const submitData = {
|
||||||
|
applyId: projectInfo.value.applyId,
|
||||||
|
fileName: fileData.fileTitle || uploadFile.name,
|
||||||
|
filePath: fileData.remark || fileData.filePath
|
||||||
|
}
|
||||||
|
let submitRes
|
||||||
|
if (projectInfo.value.status === 'RETURNED') {
|
||||||
|
submitRes = await reuploadAgentDoc(submitData)
|
||||||
|
} else {
|
||||||
|
submitRes = await uploadAgentDoc(submitData)
|
||||||
|
}
|
||||||
|
if (submitRes?.code === 0 || submitRes?.code === 200) {
|
||||||
|
useMessage().success('招标文件提交成功')
|
||||||
|
emit('refresh')
|
||||||
|
await loadProjectDetail()
|
||||||
|
await loadUploadedDocList()
|
||||||
|
fileList.value = []
|
||||||
|
} else {
|
||||||
|
useMessage().error(submitRes?.msg || '提交失败')
|
||||||
|
}
|
||||||
|
} catch (e: any) {
|
||||||
|
useMessage().error(e?.msg || '提交失败')
|
||||||
|
} finally {
|
||||||
|
uploadSubmitting.value = false
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
useMessage().error(response?.msg || '上传失败')
|
useMessage().error(response?.msg || '上传失败')
|
||||||
uploadSubmitting.value = false
|
uploadSubmitting.value = false
|
||||||
@@ -213,31 +305,6 @@ const handleUploadError: UploadProps['onError'] = (error: any) => {
|
|||||||
uploadSubmitting.value = false
|
uploadSubmitting.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const submitUpload = async (fileName: string, filePath: string) => {
|
|
||||||
try {
|
|
||||||
const data = {
|
|
||||||
applyId: projectInfo.value.applyId,
|
|
||||||
fileName,
|
|
||||||
filePath
|
|
||||||
}
|
|
||||||
|
|
||||||
if (projectInfo.value.status === 'RETURNED') {
|
|
||||||
await reuploadAgentDoc(data)
|
|
||||||
} else {
|
|
||||||
await uploadAgentDoc(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
useMessage().success('招标文件上传成功')
|
|
||||||
emit('refresh')
|
|
||||||
await loadProjectDetail()
|
|
||||||
fileList.value = []
|
|
||||||
} catch (e: any) {
|
|
||||||
useMessage().error(e?.msg || '上传失败')
|
|
||||||
} finally {
|
|
||||||
uploadSubmitting.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleUploadSubmit = async () => {
|
const handleUploadSubmit = async () => {
|
||||||
if (fileList.value.length === 0) {
|
if (fileList.value.length === 0) {
|
||||||
useMessage().warning('请先选择文件')
|
useMessage().warning('请先选择文件')
|
||||||
@@ -299,4 +366,32 @@ defineExpose({ open })
|
|||||||
.mt-4 {
|
.mt-4 {
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
padding-left: 8px;
|
||||||
|
border-left: 3px solid #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploaded-docs {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-area {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px dashed #dcdfe6;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user