| | |
| | | <div> |
| | | <el-dialog |
| | | v-model="dialogFormVisible" |
| | | :title="operationType === 'add' ? '新增审批流程' : '编辑审批流程'" |
| | | :title="operationType === 'approval' ? '审批' : '详情'" |
| | | width="700px" |
| | | @close="closeDia" |
| | | > |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row v-if="!isQuotationApproval"> |
| | | <el-row v-if="!isQuotationApproval && !isPurchaseApproval"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="审批事由:" prop="approveReason"> |
| | | <el-form-item :label="props.approveType == 5 ? '采购合同号:' : '审批事由:'" prop="approveReason"> |
| | | <el-input v-model="form.approveReason" placeholder="请输入" clearable type="textarea" disabled/> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | </el-row> |
| | | </el-form> |
| | | |
| | | <!-- 报价审批:展示报价详情(复用销售报价“查看详情对话框”内容结构) --> |
| | | <!-- 报价审批:展示报价详情(复用销售报价"查看详情对话框"内容结构) --> |
| | | <div v-if="isQuotationApproval" style="margin: 10px 0 18px;"> |
| | | <el-divider content-position="left">报价详情</el-divider> |
| | | <el-skeleton :loading="quotationLoading" animated> |
| | |
| | | <h4>备注</h4> |
| | | <p>{{ currentQuotation.remark }}</p> |
| | | </div> |
| | | |
| | | <div v-if="quotationAttachments.length > 0" style="margin-top: 20px;"> |
| | | <h4>附件</h4> |
| | | <el-table :data="quotationAttachments" border style="width: 100%"> |
| | | <el-table-column prop="name" label="附件名称" min-width="360" show-overflow-tooltip /> |
| | | <el-table-column label="操作" width="160" align="center"> |
| | | <template #default="{ row }"> |
| | | <el-button link type="primary" size="small" @click="downloadAttachment(row)">下载</el-button> |
| | | <el-button link type="primary" size="small" @click="previewAttachment(row)">预览</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </template> |
| | | </template> |
| | | </el-skeleton> |
| | | </div> |
| | | |
| | | <!-- 采购审批:展示采购详情 --> |
| | | <div v-if="isPurchaseApproval" style="margin: 10px 0 18px;"> |
| | | <el-divider content-position="left">采购详情</el-divider> |
| | | <el-skeleton :loading="purchaseLoading" animated> |
| | | <template #template> |
| | | <el-skeleton-item variant="h3" style="width: 30%" /> |
| | | <el-skeleton-item variant="text" style="width: 100%" /> |
| | | <el-skeleton-item variant="text" style="width: 100%" /> |
| | | </template> |
| | | <template #default> |
| | | <el-empty v-if="!currentPurchase || !currentPurchase.purchaseContractNumber" description="未查询到对应采购详情" /> |
| | | <template v-else> |
| | | <el-descriptions :column="2" border> |
| | | <el-descriptions-item label="采购合同号">{{ currentPurchase.purchaseContractNumber }}</el-descriptions-item> |
| | | <el-descriptions-item label="供应商名称">{{ currentPurchase.supplierName }}</el-descriptions-item> |
| | | <el-descriptions-item label="项目名称">{{ currentPurchase.projectName }}</el-descriptions-item> |
| | | <el-descriptions-item label="销售合同号">{{ currentPurchase.salesContractNo }}</el-descriptions-item> |
| | | <el-descriptions-item label="签订日期">{{ currentPurchase.executionDate }}</el-descriptions-item> |
| | | <el-descriptions-item label="录入日期">{{ currentPurchase.entryDate }}</el-descriptions-item> |
| | | <el-descriptions-item label="付款方式">{{ currentPurchase.paymentMethod }}</el-descriptions-item> |
| | | <el-descriptions-item label="合同金额" :span="2"> |
| | | <span style="font-size: 18px; color: #e6a23c; font-weight: bold;"> |
| | | ¥{{ Number(currentPurchase.contractAmount ?? 0).toFixed(2) }} |
| | | </span> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | |
| | | <div style="margin-top: 20px;"> |
| | | <h4>产品明细</h4> |
| | | <el-table :data="currentPurchase.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> |
| | | </template> |
| | | </template> |
| | | </el-skeleton> |
| | |
| | | <div v-if="!activity.isShen" class="node-reason"> |
| | | <span>审批意见:</span>{{ activity.approveNodeReason }} |
| | | </div> |
| | | <div v-if="!activity.isShen" class="node-reason"> |
| | | <span>签名:</span> |
| | | <img :src="activity.urlTem" class="signImg" alt="" v-if="activity.urlTem"/> |
| | | </div> |
| | | <div v-else-if="activity.isShen"> |
| | | <el-form-item |
| | | :prop="'activities.' + index + '.approveNodeReason'" |
| | |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <filePreview ref="filePreviewRef" /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | import useUserStore from "@/store/modules/user.js"; |
| | | import {userListNoPageByTenantId} from "@/api/system/user.js"; |
| | | import { WarningFilled, Edit, Check, MoreFilled } from '@element-plus/icons-vue' |
| | | import { getQuotationList } from "@/api/salesManagement/salesQuotation.js"; |
| | | import { getQuotationDetail, getQuotationList } from "@/api/salesManagement/salesQuotation.js"; |
| | | import { getPurchaseByCode } from "@/api/procurementManagement/procurementLedger.js"; |
| | | import filePreview from "@/components/filePreview/index.vue"; |
| | | const emit = defineEmits(['close']) |
| | | const { proxy } = getCurrentInstance() |
| | | |
| | |
| | | const userList = ref([]) |
| | | const quotationLoading = ref(false) |
| | | const currentQuotation = ref({}) |
| | | const purchaseLoading = ref(false) |
| | | const currentPurchase = ref({}) |
| | | const filePreviewRef = ref() |
| | | const isQuotationApproval = computed(() => Number(props.approveType) === 6) |
| | | const isPurchaseApproval = computed(() => Number(props.approveType) === 5) |
| | | |
| | | const normalizeQuotationFiles = (raw) => { |
| | | const list = |
| | | (raw && Array.isArray(raw.salesLedgerFiles) && raw.salesLedgerFiles) || |
| | | (raw && Array.isArray(raw.quotationFiles) && raw.quotationFiles) || |
| | | (raw && Array.isArray(raw.fileList) && raw.fileList) || |
| | | (raw && Array.isArray(raw.files) && raw.files) || |
| | | [] |
| | | return list |
| | | .map((item) => ({ |
| | | id: item?.id, |
| | | name: item?.fileName || item?.name || item?.originalName || item?.filename || "附件", |
| | | url: item?.fileUrl || item?.url || item?.path || item?.tempPath, |
| | | })) |
| | | .filter((i) => i.url) |
| | | } |
| | | |
| | | const quotationAttachments = computed(() => normalizeQuotationFiles(currentQuotation.value)) |
| | | |
| | | const downloadAttachment = (row) => { |
| | | proxy.$download.name(row.url) |
| | | } |
| | | const previewAttachment = (row) => { |
| | | filePreviewRef.value?.open?.(row.url) |
| | | } |
| | | |
| | | const data = reactive({ |
| | | form: { |
| | |
| | | operationType.value = type; |
| | | dialogFormVisible.value = true; |
| | | currentQuotation.value = {} |
| | | currentPurchase.value = {} |
| | | userListNoPageByTenantId().then((res) => { |
| | | userList.value = res.data; |
| | | }); |
| | |
| | | }); |
| | | }); |
| | | |
| | | // 报价审批:用审批事由字段承载的“报价单号”去查报价列表 |
| | | // 报价审批:用审批事由字段承载的"报价单号"去查报价列表 |
| | | if (isQuotationApproval.value) { |
| | | const quotationNo = row?.approveReason; |
| | | if (quotationNo) { |
| | | quotationLoading.value = true |
| | | getQuotationList({ quotationNo }).then((res) => { |
| | | getQuotationList({ quotationNo }).then(async (res) => { |
| | | const records = res?.data?.records || [] |
| | | currentQuotation.value = records[0] || {} |
| | | const first = records[0] || {} |
| | | currentQuotation.value = first |
| | | if (first?.id && normalizeQuotationFiles(first).length === 0) { |
| | | try { |
| | | const detailRes = await getQuotationDetail({ id: first.id }) |
| | | const detail = detailRes?.data || detailRes || {} |
| | | currentQuotation.value = { ...first, ...detail } |
| | | } catch (e) { |
| | | } |
| | | } |
| | | }).finally(() => { |
| | | quotationLoading.value = false |
| | | }) |
| | | } |
| | | } |
| | | |
| | | // 采购审批:用审批事由字段承载的"采购合同号"去查采购详情 |
| | | if (isPurchaseApproval.value) { |
| | | const purchaseContractNumber = row?.approveReason; |
| | | if (purchaseContractNumber) { |
| | | purchaseLoading.value = true |
| | | getPurchaseByCode({ purchaseContractNumber }).then((res) => { |
| | | currentPurchase.value = res |
| | | }).catch((err) => { |
| | | console.error('查询采购详情失败:', err) |
| | | proxy.$modal.msgError('查询采购详情失败') |
| | | }).finally(() => { |
| | | purchaseLoading.value = false |
| | | }) |
| | | } |
| | | } |
| | |
| | | dialogFormVisible.value = false; |
| | | quotationLoading.value = false |
| | | currentQuotation.value = {} |
| | | purchaseLoading.value = false |
| | | currentPurchase.value = {} |
| | | emit('close') |
| | | }; |
| | | defineExpose({ |
| | |
| | | width: 200px; |
| | | height: 60px; |
| | | } |
| | | </style> |
| | | </style> |