| | |
| | | <template> |
| | | <el-dialog |
| | | class="gd-dialog" |
| | | v-model="visible" |
| | | :title="'查看申请'" |
| | | @closed="visible = false" |
| | | destroy-on-close |
| | | > |
| | | <div class="detail-container"> |
| | | <!-- 左侧步骤条 --> |
| | | <div class="detail-left"> |
| | | <el-steps :active="activeStep" direction="vertical" align-center> |
| | | <el-step v-for="(step, index) in steps" :key="index" :title="step.title"> |
| | | <template #description> |
| | | <div class="step-person">{{ step.person }}</div> |
| | | <div class="step-time">{{ step.time }}</div> |
| | | </template> |
| | | </el-step> |
| | | </el-steps> |
| | | </div> |
| | | <!-- 右侧表单数据 --> |
| | | <div class="detail-right"> |
| | | <div> |
| | | <div class="label">需求详情</div> |
| | | <div class="requirementsDetailsBox"> |
| | | <div class="detail-table"> |
| | | <div class="detail-row"> |
| | | <div class="detail-cell"> |
| | | <span class="cell-label">需求名称</span> |
| | | <span class="cell-value">{{ formData.demandName }}</span> |
| | | </div> |
| | | <div class="detail-cell"> |
| | | <span class="cell-label">需求类型</span> |
| | | <span class="cell-value">{{ getDictLabel(formData.demandType, dictObj.requirementType) }}</span> |
| | | </div> |
| | | <el-dialog width="80%" 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 class="detail-row"> |
| | | <div class="detail-cell"> |
| | | <span class="cell-label">需求联系人</span> |
| | | <span class="cell-value">{{ formData.contactPerson }}</span> |
| | | </div> |
| | | <div class="detail-cell"> |
| | | <span class="cell-label">需求联系人电话</span> |
| | | <span class="cell-value">{{ formData.contactPhone }}</span> |
| | | </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' && (permissionList.approvedBtn || permissionList.rejectBtn)"> |
| | | <div class="detail-title" :style="{ marginTop:pxToRem(10)}">数据上传</div> |
| | | <div class="upload-container"> |
| | | <el-upload |
| | | :http-request="handleHttpRequest" |
| | | :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 class="detail-row"> |
| | | <div class="detail-cell"> |
| | | <span class="cell-label">需求邮箱</span> |
| | | <span class="cell-value">{{ formData.contactEmail }}</span> |
| | | </div> |
| | | <div class="detail-cell"> |
| | | <span class="cell-label">更新周期</span> |
| | | <span class="cell-value">{{ formData.updateCycle }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <div class="detail-cell"> |
| | | <span class="cell-label">申请依据</span> |
| | | <span class="cell-value">{{ formData.applyBasis }}</span> |
| | | </div> |
| | | <div class="detail-cell"> |
| | | <span class="cell-label">共享类型</span> |
| | | <span class="cell-value">{{ getDictLabel(formData.shareType, dictObj.sharedType) }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <div class="detail-cell"> |
| | | <span class="cell-label">应用场景类型</span> |
| | | <span class="cell-value">{{ getDictLabel(formData.applicationScene, dictObj.appSceneType) }}</span> |
| | | </div> |
| | | <div class="detail-cell"> |
| | | <span class="cell-label">责任部门</span> |
| | | <span class="cell-value">{{ formData.responsibleDeptName }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="detail-row"> |
| | | <div class="detail-cell"> |
| | | <span class="cell-label">数据来源依据</span> |
| | | <span class="cell-value">{{ formData.dataSource }}</span> |
| | | </div> |
| | | <div class="detail-cell"> |
| | | <span class="cell-label">需求信息项</span> |
| | | <span class="cell-value">{{ formData.demandInfo }}</span> |
| | | </div> |
| | | </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-link type="primary" @click="downloadFileFromTable(scope.row)">下载</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div> |
| | | <div class="label">数据上传</div> |
| | | <div class="upload-container"> |
| | | <el-upload |
| | | ref="uploadRef" |
| | | :auto-upload="false" |
| | | :limit="1" |
| | | :on-change="handleFileChange" |
| | | :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> |
| | | <el-button |
| | | type="success" |
| | | :disabled="!selectedFile" |
| | | @click="handleUpload" |
| | | style="margin-top: 10px;" |
| | | > |
| | | 上传文件 |
| | | </el-button> |
| | | |
| | | <!-- 已上传文件列表 --> |
| | | <div v-if="uploadedFiles.length > 0" class="uploaded-files"> |
| | | <h4>已上传文件:</h4> |
| | | <div v-for="(file, index) in uploadedFiles" :key="index" class="file-item"> |
| | | <span>{{ file.originalName }}</span> |
| | | <el-button type="text" @click="viewFile(file)" style="margin-left: 10px;">查看</el-button> |
| | | <el-button type="text" @click="downloadFile(file)" style="margin-left: 5px;">下载</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | </div> |
| | | |
| | | </div> |
| | | <template #footer> |
| | | <el-button |
| | | class="save-btn" |
| | | color="#4C34FF" |
| | | |
| | | |
| | | @click="rejectTheApplication" |
| | | > |
| | | 拒绝申请 |
| | | </el-button> |
| | | <el-button color="#F2F3F5" @click="approvedByTheReview">审核通过</el-button> |
| | | |
| | | <template v-if="detailDemandStatus === '1' "> |
| | | <el-button v-if="permissionList.rejectBtn" color="#F2F3F5" :loading="submitting || uploading" :disabled="submitting || uploading" @click="rejectTheApplication">拒绝申请</el-button> |
| | | <el-button v-if="permissionList.approvedBtn" class="" color="#4C34FF" :loading="submitting || uploading" :disabled="submitting || uploading" @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 { ref, inject } from 'vue' |
| | | import { pxToRem } from '@/utils/rem' |
| | | import { getDictLabel } from '@ztzf/utils' |
| | | import { gdSupplyDemandDetailApi, putFileAttachApi,gdSupplyDemandAuditPassApi,gdSupplyDemandAuditRejectApi } from '@/views/orderView/orderDataManage/supplyAdd/supplyAddApi' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | |
| | | 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 permission = computed(() => store.state.user.permission); |
| | | 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 uploadRef = ref() // 上传组件引用 |
| | | const selectedFile = ref(null) // 选择的文件 |
| | | const fileList = ref([]) // 上传文件列表 |
| | | const uploadedFiles = ref([]) // 已上传文件列表 |
| | | const uploadLoading = ref(false) // 上传加载状态 |
| | | const responseData = ref([]) |
| | | // 步骤条数据 |
| | | const steps = ref([ |
| | | { title: '需求申请', person: '张三', time: '2025-03-31 12:23:30' }, |
| | | { title: '审核通过', person: '', time: '' }, |
| | | ]) |
| | | // 当前激活步骤 |
| | | const activeStep = ref(0) |
| | | |
| | | // 文件选择变化 |
| | | const handleFileChange = (file, fileList) => { |
| | | if (fileList.length > 0) { |
| | | selectedFile.value = file.raw |
| | | } else { |
| | | selectedFile.value = null |
| | | } |
| | | const responseData = ref(null) |
| | | const submitting = ref(false) // 提交中状态 |
| | | const uploading = ref(false) // 文件上传中状态 |
| | | function validData(value, defaultValue) { |
| | | return value !== undefined ? value : defaultValue |
| | | } |
| | | const permissionList = computed(() => { |
| | | return { |
| | | addBtn: validData(permission.value.orderData_addDemand, false), |
| | | rejectBtn: validData(permission.value.orderData_rejectApplication, false), |
| | | approvedBtn: validData(permission.value.orderData_approved, false), |
| | | } |
| | | }) |
| | | // 自定义上传请求函数 |
| | | const handleHttpRequest = async (options) => { |
| | | uploading.value = true |
| | | try { |
| | | // 创建FormData对象 |
| | | const formData = new FormData() |
| | | formData.append('file', options.file) |
| | | |
| | | // 调用导入的API函数 |
| | | const response = await putFileAttachApi(formData) |
| | | 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) |
| | | } finally { |
| | | uploading.value = false |
| | | } |
| | | } |
| | | // 拒绝申请弹框控制 |
| | | const rejectionDialogVisible = ref(false) // 拒绝申请弹框显隐 |
| | | const tableData = ref([]) // 附件表格数据 |
| | | // 文件移除 |
| | | const handleFileRemove = () => { |
| | | selectedFile.value = null |
| | | 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 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 handleUpload = async () => { |
| | | if (!selectedFile.value) { |
| | | ElMessage.warning('请先选择文件') |
| | | return |
| | | } |
| | | // 上传成功处理函数 |
| | | const handleUploadSuccess = (response, file, fileList) => { |
| | | // 添加更严格的检查,确保response不是undefined |
| | | if (response && response?.data && response?.data?.success) { |
| | | const fileData = response.data.data |
| | | responseData.value = fileData |
| | | // 添加到已上传文件列表 |
| | | uploadedFiles.value.push({ |
| | | name: fileData.name, |
| | | originalName: fileData.originalName, |
| | | link: fileData.link, |
| | | attachId: fileData.attachId, |
| | | }) |
| | | |
| | | // 再次验证文件类型 |
| | | if (!beforeFileUpload(selectedFile.value)) { |
| | | return |
| | | } |
| | | |
| | | try { |
| | | uploadLoading.value = true |
| | | |
| | | // 创建FormData对象 |
| | | const formData = new FormData() |
| | | formData.append('file', selectedFile.value) |
| | | |
| | | // 调用上传接口 |
| | | const response = await putFileAttachApi(formData) |
| | | |
| | | if (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('文件上传成功!') |
| | | |
| | | // 清空上传列表 |
| | | uploadRef.value.clearFiles() |
| | | selectedFile.value = null |
| | | |
| | | // 这里可以将附件ID保存到表单数据中,供后续提交使用 |
| | | // formData.value.attachmentId = fileData.attachId |
| | | |
| | | } else { |
| | | ElMessage.error(response.data?.msg || '文件上传失败') |
| | | } |
| | | } catch (error) { |
| | | console.error('文件上传失败:', error) |
| | | ElMessage.error('文件上传失败,请重试') |
| | | } finally { |
| | | uploadLoading.value = false |
| | | } |
| | | ElMessage.success('文件上传成功!') |
| | | } |
| | | } |
| | | |
| | | // 查看文件 |
| | | const viewFile = (file) => { |
| | | if (file.link) { |
| | | window.open(file.link, '_blank') |
| | | } else { |
| | | // 上传失败处理函数 |
| | | const handleUploadError = (error, file, fileList) => { |
| | | ElMessage.error(error?.message || '文件上传失败,请重试') |
| | | } |
| | | |
| | | // 从表格下载文件 - 使用 fetch API |
| | | const downloadFileFromTable = async (file) => { |
| | | if (!file.fileUrl) { |
| | | ElMessage.warning('文件链接无效') |
| | | return |
| | | } |
| | | } |
| | | |
| | | // 下载文件 |
| | | const downloadFile = (file) => { |
| | | if (file.link) { |
| | | // 创建一个隐藏的a标签来触发下载 |
| | | try { |
| | | const response = await fetch(file.fileUrl) |
| | | const blob = await response.blob() |
| | | const url = window.URL.createObjectURL(blob) |
| | | const a = document.createElement('a') |
| | | a.href = file.link |
| | | a.download = file.originalName || file.name |
| | | a.href = url |
| | | |
| | | // 获取原始文件名,处理中文和特殊字符 |
| | | const originalName = file.fileOriginalName || 'download-file.zip' |
| | | // 确保文件名有正确的扩展名 |
| | | let fileName = originalName |
| | | if (!fileName.includes('.')) { |
| | | // 从 Content-Type 推断扩展名 |
| | | const contentType = response.headers.get('content-type') |
| | | if (contentType === 'application/zip') { |
| | | fileName += '.zip' |
| | | } else if (contentType === 'application/x-rar-compressed') { |
| | | fileName += '.rar' |
| | | } |
| | | } |
| | | |
| | | a.download = fileName |
| | | a.style.display = 'none' |
| | | document.body.appendChild(a) |
| | | a.click() |
| | | document.body.removeChild(a) |
| | | } else { |
| | | ElMessage.warning('文件链接无效') |
| | | |
| | | // 清理 |
| | | setTimeout(() => { |
| | | window.URL.revokeObjectURL(url) |
| | | document.body.removeChild(a) |
| | | }, 100) |
| | | |
| | | } catch (error) { |
| | | console.error('下载失败:', error) |
| | | } |
| | | } |
| | | |
| | | // 下载所有文件 |
| | | const downloadAllFiles =async () => { |
| | | 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 |
| | | } |
| | | // 顺序下载每个文件 |
| | | for (let i = 0; i < validFiles.length; i++) { |
| | | const file = validFiles[i] |
| | | |
| | | try { |
| | | const response = await fetch(file.fileUrl) |
| | | const blob = await response.blob() |
| | | const url = window.URL.createObjectURL(blob) |
| | | const a = document.createElement('a') |
| | | a.href = url |
| | | |
| | | // 设置文件名,优先使用原始文件名 |
| | | let fileName = file.fileOriginalName || `附件_${i + 1}` |
| | | |
| | | // 确保文件名有扩展名 |
| | | if (!fileName.includes('.')) { |
| | | const contentType = response.headers.get('content-type') |
| | | if (contentType === 'application/zip') { |
| | | fileName += '.zip' |
| | | } else if (contentType === 'application/x-rar-compressed') { |
| | | fileName += '.rar' |
| | | } else if (contentType === 'application/x-7z-compressed') { |
| | | fileName += '.7z' |
| | | } else { |
| | | fileName += '.zip' |
| | | } |
| | | } |
| | | |
| | | a.download = fileName |
| | | a.style.display = 'none' |
| | | document.body.appendChild(a) |
| | | a.click() |
| | | |
| | | // 清理资源 |
| | | setTimeout(() => { |
| | | window.URL.revokeObjectURL(url) |
| | | document.body.removeChild(a) |
| | | }, 100) |
| | | |
| | | // 文件间添加延迟(除了最后一个文件) |
| | | if (i < validFiles.length - 1) { |
| | | await new Promise(resolve => setTimeout(resolve, 500)) |
| | | } |
| | | |
| | | } catch (error) { |
| | | console.error(`文件下载失败: ${file.fileOriginalName || '未知文件'}`, error) |
| | | // 继续下载下一个文件 |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | // 根据部门ID获取部门名称 |
| | | function getDeptNameById(deptId, deptList) { |
| | | // 处理类型转换,确保比较的是相同类型 |
| | | const targetId = String(deptId) |
| | | |
| | | |
| | | // 递归遍历部门树 |
| | | function findDept(deptList) { |
| | | for (const dept of deptList) { |
| | |
| | | } |
| | | return '' |
| | | } |
| | | |
| | | |
| | | if (!targetId || !Array.isArray(deptList) || deptList.length === 0) { |
| | | return '' |
| | | } |
| | | |
| | | |
| | | return findDept(deptList) |
| | | } |
| | | |
| | |
| | | async function open({ row }) { |
| | | if (row?.id) { |
| | | await loadDetail(row.id) |
| | | // 可以在这里加载已上传的文件列表 |
| | | // loadUploadedFiles(row.id) |
| | | demandId.value = row.id |
| | | } |
| | | visible.value = true |
| | | } |
| | |
| | | data.responsibleDeptName = getDeptNameById(data.responsibleDeptId, deptTree.value) |
| | | } |
| | | formData.value = data |
| | | |
| | | // 加载附件数据 |
| | | await loadAttachments(id) |
| | | } |
| | | |
| | | // 如果需要加载已上传的文件列表 |
| | | const loadUploadedFiles = async (id) => { |
| | | try { |
| | | // 这里根据实际情况调用接口获取已上传的文件列表 |
| | | // const response = await getFileListApi({ id }) |
| | | // if (response.data?.success) { |
| | | // uploadedFiles.value = response.data.data || [] |
| | | // } |
| | | } catch (error) { |
| | | console.error('加载已上传文件失败:', error) |
| | | } |
| | | // 加载附件数据 |
| | | 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(responseData.value.length === 0){ |
| | | return ElMessage.warning('请上传数据') |
| | | } |
| | | const id = [responseData.value.attachId] |
| | | console.log('responseData.value',responseData.value) |
| | | gdSupplyDemandAuditRejectApi({ attachIds:id }).then(() => { |
| | | ElMessage.success('拒绝申请成功') |
| | | visible.value = false |
| | | }) |
| | | // 打开拒绝申请弹框 |
| | | 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(responseData.value.length === 0){ |
| | | if (uploadedFiles.value.length === 0) { |
| | | return ElMessage.warning('请上传数据') |
| | | } |
| | | const id = [responseData.value.attachId] |
| | | gdSupplyDemandAuditPassApi({ id }).then(() => { |
| | | ElMessage.success('审核通过成功') |
| | | visible.value = false |
| | | }) |
| | | } |
| | | // 从 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-container { |
| | | padding: 20px; |
| | | display: flex; |
| | | align-items: flex-start; |
| | | gap: 30px; |
| | | } |
| | | |
| | | /* 左侧步骤条 */ |
| | | .detail-left { |
| | | width: 25%; |
| | | width: 35%; |
| | | padding-right: 20px; |
| | | border-right: 1px solid #e8e8e8; |
| | | } |
| | | |
| | | /* 右侧表单 */ |
| | | .detail-right { |
| | | width: 75%; |
| | | .requirementsDetailsBox { |
| | | background: #F2F3F5; |
| | | width: 65%; |
| | | .reject-reason { |
| | | margin-bottom: 20px; |
| | | background: #f2f3f5; |
| | | border-radius: 2px 2px 2px 2px; |
| | | padding: 15px; |
| | | height: 100px; |
| | | } |
| | | |
| | | /* 详情表格样式 */ |
| | | .detail-table { |
| | | width: 100%; |
| | | } |
| | | |
| | | .detail-row { |
| | | display: flex; |
| | | &:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | } |
| | | |
| | | .detail-cell { |
| | | flex: 1; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | padding: 5px 12px; |
| | | margin-right: 8px; |
| | | &:last-child { |
| | | margin-right: 0; |
| | | } |
| | | } |
| | | |
| | | .cell-label { |
| | | font-weight: 500; |
| | | color: #333333; |
| | | margin-right: 8px; |
| | | text-align: right; |
| | | min-width: 100px; |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | .cell-value { |
| | | color: #666666; |
| | | flex: 1; |
| | | text-align: left; |
| | | } |
| | | } |
| | | |
| | | /* 步骤条样式 */ |
| | | :deep(.el-steps) { |
| | | align-items: flex-start; |
| | | } |
| | | |
| | | :deep(.el-step) { |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | :deep(.el-step__title) { |
| | | font-size: 14px; |
| | | font-weight: 500; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | /* 步骤描述 */ |
| | | .step-person { |
| | | font-size: 13px; |
| | | color: #333; |
| | | margin-bottom: 4px; |
| | | } |
| | | |
| | | .step-time { |
| | | font-size: 12px; |
| | | color: #909399; |
| | | } |
| | | |
| | | /* 表单样式 */ |
| | | .label { |
| | | font-weight: 500; |
| | | margin-bottom: 8px; |
| | | color: #333; |
| | | .label { |
| | | width: 130px !important;} |
| | | } |
| | | |
| | | /* 上传容器样式 */ |
| | | .upload-container { |
| | | padding: 15px; |
| | | background: #F2F3F5; |
| | | 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; |
| | |
| | | background: white; |
| | | border-radius: 4px; |
| | | margin-bottom: 5px; |
| | | |
| | | |
| | | span { |
| | | flex: 1; |
| | | color: #333; |
| | |
| | | } |
| | | } |
| | | |
| | | .val { |
| | | padding: 8px; |
| | | background-color: #f5f7fa; |
| | | border-radius: 4px; |
| | | min-height: 32px; |
| | | word-break: break-all; |
| | | margin-bottom: 16px; |
| | | .el-upload__tip { |
| | | display: inline; |
| | | } |
| | | |
| | | |
| | | |
| | | /* 上传按钮样式 */ |
| | | :deep(.el-upload) { |
| | |
| | | :deep(.el-upload-list) { |
| | | margin-top: 10px; |
| | | } |
| | | </style> |
| | | |
| | | </style> |