<template>
|
<el-dialog class="gd-dialog" :close-on-click-modal="false" v-model="visible" :title="'查看'" @closed="visible = false" destroy-on-close>
|
<div class="detail-container">
|
<!-- 左侧审批记录 -->
|
<div class="detail-left">
|
<AuditRecord :demand-id="demandId" />
|
</div>
|
<!-- 右侧表单数据 -->
|
<div class="detail-right">
|
<!-- 拒绝申请-->
|
<div class="reject-reason-container" v-if="detailDemandStatus === '3'">
|
<div class="detail-title">拒绝原因</div>
|
<div class="reject-reason">
|
{{reasonForRejection}}
|
</div>
|
</div>
|
<div>
|
<div class="detail-title">需求详情</div>
|
<el-row class="detail-row-view">
|
<el-col :span="12">
|
<div class="label">需求名称</div>
|
<div class="val">{{ formData.demandName }}</div>
|
</el-col>
|
<el-col :span="12">
|
<div class="label">需求类型</div>
|
<div class="val">{{ getDictLabel(formData.demandType, dictObj.requirementType) }}</div>
|
</el-col>
|
<el-col :span="12">
|
<div class="label">需求联系人</div>
|
<div class="val">{{ formData.contactPerson }}</div>
|
</el-col>
|
<el-col :span="12">
|
<div class="label" >需求联系人电话</div>
|
<div class="val">{{ formData.contactPhone }}</div>
|
</el-col>
|
<el-col :span="12">
|
<div class="label">需求邮箱</div>
|
<div class="val">{{ formData.contactEmail }}</div>
|
</el-col>
|
<el-col :span="12">
|
<div class="label">更新周期</div>
|
<div class="val">{{ formData.updateCycle }}</div>
|
</el-col>
|
<el-col :span="12">
|
<div class="label">申请依据</div>
|
<div class="val">{{ formData.applyBasis }}</div>
|
</el-col>
|
<el-col :span="12">
|
<div class="label">共享类型</div>
|
<div class="val">{{ getDictLabel(formData.shareType, dictObj.sharedType) }}</div>
|
</el-col>
|
<el-col :span="12">
|
<div class="label">应用场景类型</div>
|
<div class="val">{{ getDictLabel(formData.applicationScene, dictObj.appSceneType) }}</div>
|
</el-col>
|
<el-col :span="12">
|
<div class="label">责任部门</div>
|
<div class="val">{{ formData.responsibleDeptName }}</div>
|
</el-col>
|
<el-col :span="12">
|
<div class="label">数据来源依据</div>
|
<div class="val">{{ formData.dataSource }}</div>
|
</el-col>
|
<el-col :span="12">
|
<div class="label">需求信息项</div>
|
<div class="val">{{ formData.demandInfo }}</div>
|
</el-col>
|
</el-row>
|
</div>
|
<!-- 申请中-->
|
<div v-if="detailDemandStatus === '1' && !requesterProvider">
|
<div class="detail-title">数据上传</div>
|
<div class="upload-container">
|
<el-upload
|
:http-request="handleHttpRequest"
|
:limit="3"
|
:on-success="handleUploadSuccess"
|
:on-error="handleUploadError"
|
:on-remove="handleFileRemove"
|
:before-upload="beforeFileUpload"
|
:file-list="fileList"
|
accept=".zip,.rar,.7z,.tar,.gz"
|
class="upload-demo"
|
>
|
<template #trigger>
|
<el-button type="primary">选择文件</el-button>
|
</template>
|
<template #tip>
|
<div class="el-upload__tip">支持上传 (.zip/.rar/.7z/.tar/.gz)格式文件</div>
|
</template>
|
</el-upload>
|
</div>
|
</div>
|
<div v-if="detailDemandStatus === '2'">
|
<div class="detail-title" :style="{ marginTop:pxToRem(20)}">数据详情</div>
|
<el-table :data="tableData" style="width: 100%">
|
<el-table-column prop="fileOriginalName" label="文件名称" />
|
<el-table-column prop="fileSize" label="文件大小" />
|
<el-table-column fixed="right" label="操作" min-width="100">
|
<template #default="scope">
|
<el-button link type="text" @click="downloadFileFromTable(scope.row)">下载</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
</div>
|
</div>
|
<template #footer>
|
<template v-if="detailDemandStatus === '1' && !requesterProvider">
|
<el-button color="#F2F3F5" :loading="submitting" :disabled="submitting" @click="rejectTheApplication">拒绝申请</el-button>
|
<el-button class="" color="#4C34FF" :loading="submitting" :disabled="submitting" @click="approvedByTheReview">审核通过</el-button>
|
</template>
|
<template v-if="detailDemandStatus === '2'">
|
<el-button class="" color="#4C34FF" @click="downloadAllFiles">全部下载</el-button>
|
</template>
|
<template v-if="detailDemandStatus === '3'">
|
<el-button class="" color="#4C34FF" @click="visible =false">关闭</el-button>
|
</template>
|
</template>
|
</el-dialog>
|
|
<!-- 拒绝申请弹框 -->
|
<reasonForRejectionDialog
|
v-if="rejectionDialogVisible"
|
v-model="rejectionDialogVisible"
|
@confirm="handleRejectionConfirm"
|
/>
|
</template>
|
|
<script setup>
|
import { pxToRem } from '@/utils/rem'
|
import { getDictLabel } from '@ztzf/utils'
|
import {
|
gdSupplyDemandDetailApi,
|
putFileAttachApi,
|
gdSupplyDemandAuditPassApi,
|
gdSupplyDemandAuditRejectApi,
|
gdSupplyDemandAuditAttachmentListApi,
|
} from '@/views/orderView/orderDataManage/supplyAdd/supplyAddApi'
|
import { ElMessage } from 'element-plus'
|
import reasonForRejectionDialog from '@/views/orderView/orderDataManage/supplyAdd/reasonForRejectionDialog.vue'
|
import AuditRecord from '@/views/orderView/orderDataManage/supplyAdd/auditRecord.vue' // 导入新组件
|
import { useStore } from 'vuex'
|
const store = useStore()
|
const requesterProvider = computed(() => store.state.user.userInfo?.role_id === '2014158512610869250')
|
const emit = defineEmits(['success'])
|
const dictObj = inject('dictObj')
|
const deptTree = inject('deptTree')
|
const detailDemandStatus = inject('detailDemandStatus')
|
const reasonForRejection = inject('reasonForRejection')
|
const demandId = ref('')
|
const visible = defineModel() // 弹框显隐
|
const formData = ref({}) // 表单数据
|
const fileList = ref([]) // 上传文件列表
|
const uploadedFiles = ref([]) // 已上传文件列表
|
const responseData = ref(null)
|
const submitting = ref(false) // 提交中状态
|
// 自定义上传请求函数
|
const handleHttpRequest = async (options) => {
|
try {
|
// 创建FormData对象
|
const formData = new FormData()
|
formData.append('file', options.file)
|
|
// 调用导入的API函数
|
const response = await putFileAttachApi(formData)
|
console.log('response',response)
|
if (response.data && response.data.success) {
|
// 调用上传成功的回调
|
options.onSuccess(response)
|
} else {
|
// 调用上传失败的回调
|
options.onError(new Error(response.data?.msg || '文件上传失败'))
|
}
|
} catch (error) {
|
// 调用上传失败的回调
|
options.onError(error)
|
console.error('文件上传失败:', error)
|
}
|
}
|
// 拒绝申请弹框控制
|
const rejectionDialogVisible = ref(false) // 拒绝申请弹框显隐
|
const tableData = ref([]) // 附件表格数据
|
// 文件移除
|
const handleFileRemove = (file, fileList) => {
|
uploadedFiles.value = fileList
|
// 清空响应数据
|
if (responseData.value && responseData.value.attachId === file.response?.attachId) {
|
responseData.value = null
|
}
|
}
|
|
// 上传前验证
|
const beforeFileUpload = file => {
|
const allowedExtensions = ['.zip', '.rar', '.7z', '.tar', '.gz']
|
const fileExtension = '.' + file.name.split('.').pop().toLowerCase()
|
|
if (!allowedExtensions.includes(fileExtension)) {
|
ElMessage.error('只能上传压缩文件格式:.zip/.rar/.7z/.tar/.gz')
|
return false
|
}
|
|
// 文件大小限制,这里限制为100MB
|
const maxSize = 100 * 1024 * 1024 // 100MB
|
if (file.size > maxSize) {
|
ElMessage.error('文件大小不能超过100MB')
|
return false
|
}
|
|
return true
|
}
|
|
// 上传成功处理函数
|
const handleUploadSuccess = (response, file, fileList) => {
|
// 添加更严格的检查,确保response不是undefined
|
if (response && response?.data && response?.data?.success) {
|
const fileData = response.data.data
|
console.log('成功数据', fileData)
|
responseData.value = fileData
|
// 添加到已上传文件列表
|
uploadedFiles.value.push({
|
name: fileData.name,
|
originalName: fileData.originalName,
|
link: fileData.link,
|
attachId: fileData.attachId,
|
})
|
|
ElMessage.success('文件上传成功!')
|
}
|
}
|
|
// 上传失败处理函数
|
const handleUploadError = (error, file, fileList) => {
|
ElMessage.error(error?.message || '文件上传失败,请重试')
|
}
|
|
// 查看文件
|
const viewFile = file => {
|
if (file.link) {
|
window.open(file.link, '_blank')
|
} else {
|
ElMessage.warning('文件链接无效')
|
}
|
}
|
|
// 下载文件
|
const downloadFile = file => {
|
if (file.link) {
|
// 创建一个隐藏的a标签来触发下载
|
const a = document.createElement('a')
|
a.href = file.link
|
a.download = file.originalName || file.name
|
document.body.appendChild(a)
|
a.click()
|
document.body.removeChild(a)
|
} else {
|
ElMessage.warning('文件链接无效')
|
}
|
}
|
|
// 从表格下载文件
|
const downloadFileFromTable = file => {
|
if (file.fileUrl) {
|
// 创建一个隐藏的a标签来触发下载
|
const a = document.createElement('a')
|
a.href = file.fileUrl
|
a.download = file.name || 'attachment'
|
document.body.appendChild(a)
|
a.click()
|
document.body.removeChild(a)
|
} else {
|
ElMessage.warning('文件链接无效')
|
}
|
}
|
|
// 下载所有文件
|
const downloadAllFiles = () => {
|
if (!tableData.value || tableData.value.length === 0) {
|
ElMessage.warning('没有可下载的文件')
|
return
|
}
|
|
// 统计有效文件数量
|
const validFiles = tableData.value.filter(file => file.fileUrl)
|
if (validFiles.length === 0) {
|
ElMessage.warning('所有文件链接均无效')
|
return
|
}
|
|
ElMessage.success(`开始下载${validFiles.length}个文件`)
|
|
// 依次下载每个文件(添加延迟以避免浏览器限制)
|
validFiles.forEach((file, index) => {
|
setTimeout(() => {
|
if (file.fileUrl) {
|
const a = document.createElement('a')
|
a.href = file.fileUrl
|
a.download = file.name || `attachment_${index + 1}`
|
document.body.appendChild(a)
|
a.click()
|
document.body.removeChild(a)
|
}
|
}, index * 300) // 300ms delay between downloads
|
})
|
}
|
|
// 根据部门ID获取部门名称
|
function getDeptNameById(deptId, deptList) {
|
// 处理类型转换,确保比较的是相同类型
|
const targetId = String(deptId)
|
|
// 递归遍历部门树
|
function findDept(deptList) {
|
for (const dept of deptList) {
|
if (String(dept.id) === targetId) {
|
return dept.name
|
}
|
if (Array.isArray(dept.children) && dept.children.length > 0) {
|
const name = findDept(dept.children)
|
if (name) return name
|
}
|
}
|
return ''
|
}
|
|
if (!targetId || !Array.isArray(deptList) || deptList.length === 0) {
|
return ''
|
}
|
|
return findDept(deptList)
|
}
|
|
// 打开弹框
|
async function open({ row }) {
|
if (row?.id) {
|
await loadDetail(row.id)
|
demandId.value = row.id
|
}
|
visible.value = true
|
}
|
|
// 加载详情
|
async function loadDetail(id) {
|
const res = await gdSupplyDemandDetailApi({ id })
|
const data = res?.data?.data ?? {}
|
// 如果没有部门名称,根据部门ID从部门树中获取
|
if (data.responsibleDeptId && !data.responsibleDeptName) {
|
data.responsibleDeptName = getDeptNameById(data.responsibleDeptId, deptTree.value)
|
}
|
formData.value = data
|
|
// 加载附件数据
|
await loadAttachments(id)
|
}
|
|
// 加载附件数据
|
async function loadAttachments(demandId) {
|
try {
|
const res = await gdSupplyDemandAuditAttachmentListApi({ demandId: demandId })
|
const attachments = res?.data?.data ?? []
|
|
// 格式化附件数据以匹配表格结构
|
tableData.value = attachments.map(attachment => ({
|
fileOriginalName: attachment.fileOriginalName ,
|
fileSize: attachment.fileSize ? `${attachment.fileSize}M` : '',
|
fileUrl: attachment.fileUrl,
|
id: attachment.id,
|
}))
|
} catch (error) {
|
console.error('加载附件数据失败:', error)
|
ElMessage.error('加载附件数据失败,请重试')
|
tableData.value = []
|
}
|
}
|
|
// 拒绝申请
|
const rejectTheApplication = () => {
|
// if (uploadedFiles.value.length === 0) {
|
// return ElMessage.warning('请上传数据')
|
// }
|
// 打开拒绝申请弹框
|
rejectionDialogVisible.value = true
|
}
|
|
// 处理拒绝申请确认
|
const handleRejectionConfirm = reason => {
|
// 从 uploadedFiles.value 中提取所有 attachId
|
const id = uploadedFiles.value.map(file => file.attachId)
|
|
submitting.value = true
|
gdSupplyDemandAuditRejectApi({ attachIds: id, auditOpinion: reason, demandId: demandId.value })
|
.then(() => {
|
ElMessage.success('拒绝申请成功')
|
visible.value = false
|
emit('success')
|
})
|
.catch(error => {
|
console.error('拒绝申请失败:', error)
|
ElMessage.error('拒绝申请失败,请重试')
|
emit('success')
|
})
|
.finally(() => {
|
submitting.value = false
|
})
|
}
|
// 审核通过
|
const approvedByTheReview = () => {
|
if (uploadedFiles.value.length === 0) {
|
return ElMessage.warning('请上传数据')
|
}
|
// 从 uploadedFiles.value 中提取所有 attachId
|
const id = uploadedFiles.value.map(file => file.attachId)
|
submitting.value = true
|
gdSupplyDemandAuditPassApi({ attachIds: id, demandId: demandId.value })
|
.then(() => {
|
ElMessage.success('审核通过成功')
|
visible.value = false
|
emit('success')
|
})
|
.finally(() => {
|
submitting.value = false
|
})
|
}
|
|
defineExpose({ open })
|
</script>
|
|
<style scoped lang="scss">
|
/* 左侧步骤条 */
|
.detail-left {
|
width: 35%;
|
padding-right: 20px;
|
border-right: 1px solid #e8e8e8;
|
}
|
|
/* 右侧表单 */
|
.detail-right {
|
width: 65%;
|
.reject-reason {
|
margin-bottom: 20px;
|
background: #f2f3f5;
|
border-radius: 2px 2px 2px 2px;
|
padding: 15px;
|
height: 100px;
|
}
|
.label {
|
width: 130px !important;}
|
}
|
|
/* 上传容器样式 */
|
.upload-container {
|
padding: 15px;
|
background: #f2f3f5;
|
border-radius: 2px 2px 2px 2px;
|
}
|
|
.uploaded-files {
|
margin-top: 15px;
|
|
h4 {
|
margin-bottom: 10px;
|
font-size: 14px;
|
color: #333333;
|
font-weight: 500;
|
}
|
|
.file-item {
|
display: flex;
|
align-items: center;
|
padding: 8px;
|
background: white;
|
border-radius: 4px;
|
margin-bottom: 5px;
|
|
span {
|
flex: 1;
|
color: #333;
|
}
|
}
|
}
|
|
|
|
/* 上传按钮样式 */
|
:deep(.el-upload) {
|
display: inline-block;
|
}
|
|
:deep(.el-upload-list) {
|
margin-top: 10px;
|
}
|
.el-upload-list__item.is-success:focus .el-upload-list__item-status-label, .el-upload-list__item.is-success:hover .el-upload-list__item-status-label{
|
display: none !important;}
|
</style>
|