| | |
| | | <div class="approve-detail-panel"> |
| | | <div class="detail-block"> |
| | | <div class="detail-block-title">基本信息</div> |
| | | <el-descriptions :column="2" border> |
| | | <el-descriptions :column="2" |
| | | border> |
| | | <el-descriptions-item label="业务单号">{{ row.bizId || row.id || "—" }}</el-descriptions-item> |
| | | <el-descriptions-item label="审批状态"> |
| | | <el-tag :type="approvalStatusTagType(row.approvalStatus)" size="small" effect="plain"> |
| | | <el-tag :type="approvalStatusTagType(row.approvalStatus)" |
| | | size="small" |
| | | effect="plain"> |
| | | {{ approvalStatusLabel(row.approvalStatus) }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="审批类型"> |
| | | <span class="approve-type-cell" :style="approvalTypeStyle(row.approvalType)"> |
| | | <span class="approve-type-cell" |
| | | :style="approvalTypeStyle(row.approvalType)"> |
| | | {{ approvalTypeLabel(row.approvalType) }} |
| | | </span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="申请人编号">{{ row.applicantNo || "—" }}</el-descriptions-item> |
| | | <el-descriptions-item label="申请人名称">{{ row.applicantName || "—" }}</el-descriptions-item> |
| | | <el-descriptions-item label="申请摘要">{{ row.summary || "—" }}</el-descriptions-item> |
| | | <el-descriptions-item v-if="row.rejectReason" label="驳回原因" :span="2"> |
| | | <el-descriptions-item v-if="row.rejectReason" |
| | | label="驳回原因" |
| | | :span="2"> |
| | | <span class="reject-text">{{ row.rejectReason }}</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="创建时间" :span="2"> |
| | | <el-descriptions-item label="创建时间" |
| | | :span="2"> |
| | | {{ formatDisplayTime(row.createTime) }} |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | </div> |
| | | |
| | | <div class="detail-block"> |
| | | <div class="detail-block-title">填报内容</div> |
| | | <FormPayloadFields |
| | | :fields="formResolved.fields" |
| | | :form-payload="formResolved.formPayload" |
| | | readonly |
| | | /> |
| | | <!-- 默认表单展示 --> |
| | | <FormPayloadFields v-if="!isSpecialApprovalType" |
| | | :fields="formResolved.fields" |
| | | :form-payload="formResolved.formPayload" |
| | | readonly /> |
| | | |
| | | <!-- 发货审批详情 --> |
| | | <template v-else-if="row.businessType === 7"> |
| | | <div v-if="detailData.shippingInfo" class="shipment-detail"> |
| | | <el-divider content-position="left">发货详情</el-divider> |
| | | <el-descriptions :column="2" border> |
| | | <el-descriptions-item label="销售订单">{{ detailData.shippingInfo.salesContractNo || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="发货订单号">{{ detailData.shippingInfo.shippingNo || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="客户名称">{{ detailData.shippingInfo.customerName || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="发货类型">{{ detailData.shippingInfo.type || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="发货日期">{{ detailData.shippingInfo.shippingDateDate || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="审核状态">{{ detailData.shippingInfo.status || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="发货车牌号">{{ detailData.shippingInfo.shippingCarNumber || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="快递公司">{{ detailData.shippingInfo.expressCompany || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="快递单号" :span="2">{{ detailData.shippingInfo.expressNumber || "--" }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | <div v-if="detailData.shippingProductDetailDtoList.length" style="margin-top: 20px;"> |
| | | <h4>产品明细</h4> |
| | | <el-table :data="detailData.shippingProductDetailDtoList" |
| | | border |
| | | size="small" |
| | | style="width: 100%"> |
| | | <el-table-column label="批号" prop="batchNo" min-width="160" show-overflow-tooltip /> |
| | | <el-table-column label="产品名称" prop="productName" min-width="160" show-overflow-tooltip /> |
| | | <el-table-column label="规格型号" prop="specificationModel" min-width="160" show-overflow-tooltip /> |
| | | <el-table-column label="发货数量" prop="deliveryQuantity" min-width="120" align="center" /> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <!-- 采购审批详情 --> |
| | | <template v-else-if="row.businessType === 5"> |
| | | <div v-if="detailData" class="procurement-detail"> |
| | | <el-divider content-position="left">采购详情</el-divider> |
| | | <el-descriptions :column="2" border> |
| | | <el-descriptions-item label="采购合同号">{{ detailData.purchaseContractNumber || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="供应商名称">{{ detailData.supplierName || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="项目名称">{{ detailData.projectName || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="销售合同号">{{ detailData.salesContractNo || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="签订日期">{{ detailData.executionDate || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="录入日期">{{ detailData.entryDate || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="付款方式">{{ detailData.paymentMethod || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="合同金额" :span="2"> |
| | | <span style="font-size: 18px; color: #e6a23c; font-weight: bold;"> |
| | | ¥{{ Number(detailData.contractAmount ?? 0).toFixed(2) }} |
| | | </span> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | <div v-if="detailData.productData.length" style="margin-top: 20px;"> |
| | | <h4>产品明细</h4> |
| | | <el-table :data="detailData.productData" |
| | | border |
| | | style="width: 100%"> |
| | | <el-table-column prop="productCategory" label="产品名称" /> |
| | | <el-table-column prop="specificationModel" label="规格型号" /> |
| | | <el-table-column prop="unit" label="单位" /> |
| | | <el-table-column prop="quantity" label="数量" /> |
| | | <el-table-column prop="taxInclusiveUnitPrice" label="含税单价"> |
| | | <template #default="scope">¥{{ Number(scope.row.taxInclusiveUnitPrice ?? 0).toFixed(2) }}</template> |
| | | </el-table-column> |
| | | <el-table-column prop="taxInclusiveTotalPrice" label="含税总价"> |
| | | <template #default="scope">¥{{ Number(scope.row.taxInclusiveTotalPrice ?? 0).toFixed(2) }}</template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <!-- 报价审批详情 --> |
| | | <template v-else-if="row.businessType === 6"> |
| | | <div v-if="detailData" class="quotation-detail"> |
| | | <el-divider content-position="left">报价详情</el-divider> |
| | | <el-descriptions :column="2" border> |
| | | <el-descriptions-item label="报价单号">{{ detailData.quotationNo || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="客户名称">{{ detailData.customer || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="业务员">{{ detailData.salesperson || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="报价日期">{{ detailData.quotationDate || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="有效期至">{{ detailData.validDate || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="付款方式">{{ detailData.paymentMethod || "--" }}</el-descriptions-item> |
| | | <el-descriptions-item label="报价总额" :span="2"> |
| | | <span style="font-size: 18px; color: #e6a23c; font-weight: bold;"> |
| | | ¥{{ Number(detailData.totalAmount ?? 0).toFixed(2) }} |
| | | </span> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | <div v-if="detailData.products.length" style="margin-top: 20px;"> |
| | | <h4>产品明细</h4> |
| | | <el-table :data="detailData.products" |
| | | border |
| | | style="width: 100%"> |
| | | <el-table-column prop="product" label="产品名称" /> |
| | | <el-table-column prop="specification" label="规格型号" /> |
| | | <el-table-column prop="unit" label="单位" /> |
| | | <el-table-column prop="unitPrice" label="单价"> |
| | | <template #default="scope">¥{{ Number(scope.row.unitPrice ?? 0).toFixed(2) }}</template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | <div v-if="detailData.remark" style="margin-top: 20px;"> |
| | | <h4>备注</h4> |
| | | <p>{{ detailData.remark }}</p> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </div> |
| | | <div v-if="attachmentList.length" |
| | | class="detail-block"> |
| | | <div class="detail-block-title">附件列表</div> |
| | | <div class="attachment-list"> |
| | | <div v-for="file in attachmentList" |
| | | :key="file.id" |
| | | class="attachment-item"> |
| | | <el-icon class="file-icon"> |
| | | <Paperclip /> |
| | | </el-icon> |
| | | <span class="file-name" |
| | | :title="file.name || file.originalFilename"> |
| | | {{ file.name || file.originalFilename }} |
| | | </span> |
| | | <div class="file-actions"> |
| | | <el-link v-if="file.previewURL || file.url" |
| | | type="primary" |
| | | :underline="false" |
| | | @click="openFile(file.previewURL || file.url)">预览</el-link> |
| | | <el-divider v-if="(file.previewURL || file.url) && file.downloadURL" |
| | | direction="vertical" /> |
| | | <el-link v-if="file.downloadURL" |
| | | type="primary" |
| | | :underline="false" |
| | | @click="openFile(file.downloadURL)">下载</el-link> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed } from "vue"; |
| | | import { formatDisplayTime } from "../../approve-template/approveTemplateConstants.js"; |
| | | import { |
| | | approvalTypeLabel, |
| | | approvalTypeStyle, |
| | | approvalStatusLabel, |
| | | approvalStatusTagType, |
| | | resolveInstanceFormFields, |
| | | } from "../approveListConstants.js"; |
| | | import FormPayloadFields from "./FormPayloadFields.vue"; |
| | | import { computed } from "vue"; |
| | | import { Paperclip } from "@element-plus/icons-vue"; |
| | | import { formatDisplayTime } from "../../approve-template/approveTemplateConstants.js"; |
| | | import { |
| | | approvalTypeLabel, |
| | | approvalTypeStyle, |
| | | approvalStatusLabel, |
| | | approvalStatusTagType, |
| | | resolveInstanceFormFields, |
| | | } from "../approveListConstants.js"; |
| | | import FormPayloadFields from "./FormPayloadFields.vue"; |
| | | |
| | | const props = defineProps({ |
| | | row: { type: Object, default: () => ({}) }, |
| | | }); |
| | | const props = defineProps({ |
| | | row: { type: Object, default: () => ({}) }, |
| | | detailData: { type: Object, default: () => ({}) }, |
| | | }); |
| | | |
| | | const formResolved = computed(() => resolveInstanceFormFields(props.row)); |
| | | const formResolved = computed(() => resolveInstanceFormFields(props.row)); |
| | | |
| | | |
| | | // 是否为特殊审批类型(采购、发货、报价) |
| | | const isSpecialApprovalType = computed(() => { |
| | | return [5, 7, 6].includes(props.row.businessType); |
| | | }); |
| | | |
| | | // 详情数据(直接使用传入的 detail-data 参数) |
| | | const detailData = computed(() => { |
| | | return props.detailData || {}; |
| | | }); |
| | | |
| | | const attachmentList = computed(() => { |
| | | const list = props.row.storageBlobVOList || props.row.storageBlobDTOs || []; |
| | | return Array.isArray(list) ? list : []; |
| | | }); |
| | | |
| | | function openFile(url) { |
| | | if (!url) return; |
| | | window.open(url, "_blank"); |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .approve-detail-panel { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 20px; |
| | | } |
| | | .detail-block-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: var(--el-text-color-primary); |
| | | margin: 0 0 12px; |
| | | padding-left: 10px; |
| | | border-left: 3px solid var(--el-color-primary); |
| | | line-height: 1.4; |
| | | } |
| | | .approve-type-cell { |
| | | display: inline-block; |
| | | padding: 2px 10px; |
| | | border-radius: 4px; |
| | | font-size: 13px; |
| | | line-height: 1.5; |
| | | } |
| | | .reject-text { |
| | | color: var(--el-color-danger); |
| | | } |
| | | </style> |
| | | .approve-detail-panel { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 20px; |
| | | } |
| | | .detail-block-title { |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: var(--el-text-color-primary); |
| | | margin: 0 0 12px; |
| | | padding-left: 10px; |
| | | border-left: 3px solid var(--el-color-primary); |
| | | line-height: 1.4; |
| | | } |
| | | .approve-type-cell { |
| | | display: inline-block; |
| | | padding: 2px 10px; |
| | | border-radius: 4px; |
| | | font-size: 13px; |
| | | line-height: 1.5; |
| | | } |
| | | .reject-text { |
| | | color: var(--el-color-danger); |
| | | } |
| | | |
| | | .attachment-list { |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); |
| | | gap: 12px; |
| | | } |
| | | .attachment-item { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 10px 12px; |
| | | background-color: var(--el-fill-color-light); |
| | | border-radius: 6px; |
| | | border: 1px solid var(--el-border-color-lighter); |
| | | transition: all 0.3s; |
| | | } |
| | | .attachment-item:hover { |
| | | border-color: var(--el-color-primary-light-5); |
| | | background-color: var(--el-color-primary-light-9); |
| | | } |
| | | .file-icon { |
| | | font-size: 18px; |
| | | color: var(--el-text-color-secondary); |
| | | margin-right: 10px; |
| | | } |
| | | .file-name { |
| | | flex: 1; |
| | | font-size: 13px; |
| | | color: var(--el-text-color-primary); |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | margin-right: 12px; |
| | | } |
| | | .file-actions { |
| | | display: flex; |
| | | align-items: center; |
| | | flex-shrink: 0; |
| | | } |
| | | </style> |