Merge branch 'dev_NEW_pro' into dev_pro_山西_晋和园
# Conflicts:
# multiple/config.json
| | |
| | | </div> |
| | | </template> |
| | | |
| | | |
| | | <!-- 用印申请管理 --> |
| | | <div class="tab-content"> |
| | | <el-row :gutter="20" class="mb-20 "> |
| | |
| | | :isShowPagination="true" |
| | | @pagination="paginationChange" |
| | | /> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | |
| | | <!-- 用印申请对话框 --> |
| | |
| | | const sealFormRef = ref() |
| | | const userList = ref([]) |
| | | const sealForm = reactive({ |
| | | id: null, |
| | | applicationNum: '', |
| | | title: '', |
| | | sealType: '', |
| | |
| | | |
| | | // 用印申请表格列配置(需在 getStatusText/getSealTypeText 等之后定义) |
| | | const sealTableColumn = ref([ |
| | | { label: '申请编号', prop: 'applicationNum',}, |
| | | { label: '申请编号', prop: 'applicationNum' }, |
| | | { label: '申请标题', prop: 'title', showOverflowTooltip: true }, |
| | | { label: '申请人', prop: 'createUserName', }, |
| | | { label: '申请人', prop: 'createUserName' }, |
| | | { label: '所属部门', prop: 'department', width: 150 }, |
| | | { |
| | | label: '用印类型', |
| | |
| | | formatData: (v) => getStatusText(v), |
| | | formatType: (v) => getStatusType(v) |
| | | }, |
| | | { label: '审批人', prop: 'approveUserName', width: 100 }, |
| | | { |
| | | dataType: 'action', |
| | | label: '操作', |
| | | width: 200, |
| | | width: 250, |
| | | fixed: 'right', |
| | | align: 'center', |
| | | operation: [ |
| | | { |
| | | name: '审批', |
| | | clickFun: (row) => approveSeal(row), |
| | | showHide: (row) => row.status === 'pending' |
| | | showHide: (row) => row.status === 'pending' && Number(userStore.id) === row.approveUserId |
| | | }, |
| | | { |
| | | name: '拒绝', |
| | | clickFun: (row) => rejectSeal(row), |
| | | showHide: (row) => row.status === 'pending' |
| | | showHide: (row) => row.status === 'pending' && Number(userStore.id) === row.approveUserId |
| | | }, |
| | | { name: '详情', clickFun: (row) => viewSealDetail(row) } |
| | | { |
| | | name: '重新申请', |
| | | clickFun: (row) => reapplySeal(row), |
| | | showHide: (row) => row.status === 'rejected' && Number(userStore.id) === row.createUser |
| | | }, |
| | | { name: '详情', clickFun: (row) => viewSealDetail(row) } |
| | | ] |
| | | } |
| | | ]) |
| | | |
| | | // 搜索印章申请 |
| | | const searchSealApplications = () => { |
| | | page.current=1 |
| | | page.current = 1 |
| | | getSealApplicationList() |
| | | |
| | | // ElMessage.success('搜索完成') |
| | | } |
| | | // 重置印章申请搜索 |
| | | const resetSealSearch = () => { |
| | |
| | | sealSearchForm.applicationNum = '' |
| | | searchSealApplications() |
| | | } |
| | | |
| | | // 重新申请用印 |
| | | const reapplySeal = (row) => { |
| | | // 预填表单数据 |
| | | Object.assign(sealForm, { |
| | | id: row.id, |
| | | applicationNum: row.applicationNum, |
| | | title: row.title, |
| | | sealType: row.sealType, |
| | | reason: row.reason, |
| | | approveUserId: row.approveUserId, |
| | | urgency: row.urgency || 'normal', |
| | | status: 'pending', |
| | | storageBlobDTOs: row.storageBlobVOList || [] |
| | | }) |
| | | showSealApplyDialog.value = true |
| | | } |
| | | |
| | | // 提交用印申请 |
| | | const submitSealApplication = async () => { |
| | | try { |
| | | await sealFormRef.value.validate() |
| | | addSealApplication(sealForm).then(res => { |
| | | if(res.code == 200){ |
| | | ElMessage.success('申请提交成功') |
| | | const request = sealForm.id ? updateSealApplication : addSealApplication |
| | | request(sealForm).then(res => { |
| | | if (res.code == 200) { |
| | | ElMessage.success(sealForm.id ? '重新申请成功' : '申请提交成功') |
| | | closeSealApplyDialog() |
| | | getSealApplicationList() |
| | | Object.assign(sealForm, { |
| | | applicationNum: '', |
| | | title: '', |
| | | sealType: '', |
| | | reason: '', |
| | | approveUserId: '', |
| | | urgency: 'normal', |
| | | status: 'pending', |
| | | storageBlobDTOs: [] |
| | | }) |
| | | id: null, |
| | | applicationNum: '', |
| | | title: '', |
| | | sealType: '', |
| | | reason: '', |
| | | approveUserId: '', |
| | | urgency: 'normal', |
| | | status: 'pending', |
| | | storageBlobDTOs: [] |
| | | }) |
| | | } |
| | | }).catch(err => { |
| | | console.log(err.msg) |
| | | }) |
| | | |
| | | } catch (error) { |
| | | } |
| | | } |
| | | |
| | | // 关闭用印申请对话框 |
| | | const closeSealApplyDialog = () => { |
| | | // 清空表单数据 |
| | | Object.assign(sealForm, { |
| | | id: null, |
| | | applicationNum: '', |
| | | title: '', |
| | | sealType: '', |
| | |
| | | }).then(() => { |
| | | row.status = 'approved' |
| | | updateSealApplication(row).then(res => { |
| | | if(res.code == 200){ |
| | | if (res.code == 200) { |
| | | ElMessage.success('审批通过') |
| | | getSealApplicationList() |
| | | } |
| | |
| | | inputErrorMessage: '拒绝原因不能为空' |
| | | }).then(({ value }) => { |
| | | row.status = 'rejected' |
| | | row.reason = value |
| | | updateSealApplication(row).then(res => { |
| | | if(res.code == 200){ |
| | | if (res.code == 200) { |
| | | ElMessage.success('已拒绝申请') |
| | | getSealApplicationList() |
| | | } |
| | |
| | | const getSealApplicationList = async () => { |
| | | tableLoading.value = true |
| | | listSealApplication(page, sealSearchForm) |
| | | .then(res => { |
| | | sealApplications.value = res.data.records |
| | | page.total = res.data.total |
| | | tableLoading.value = false |
| | | }).catch(err => { |
| | | tableLoading.value = false |
| | | }) |
| | | .then(res => { |
| | | sealApplications.value = res.data.records |
| | | page.total = res.data.total |
| | | tableLoading.value = false |
| | | }).catch(err => { |
| | | tableLoading.value = false |
| | | }) |
| | | } |
| | | // 分页变化处理 |
| | | const paginationChange = (obj) => { |
| | |
| | | .attachment-table { |
| | | border-radius: 4px; |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | currentNodeIndex: 0, |
| | | approvalRecords, |
| | | rejectReason: approvalRecords.find(r => r.result === "rejected")?.opinion || "", |
| | | purchaseContractNumber: row.purchaseContractNumber || "", |
| | | quotationNo: row.quotationNo || "", |
| | | shippingNo: row.shippingNo || "", |
| | | }; |
| | | } |
| | | |
| | |
| | | </div> |
| | | <div class="detail-block"> |
| | | <div class="detail-block-title">填报内容</div> |
| | | <FormPayloadFields :fields="formResolved.fields" |
| | | <!-- 默认表单展示 --> |
| | | <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"> |
| | |
| | | |
| | | const props = defineProps({ |
| | | row: { type: Object, default: () => ({}) }, |
| | | detailData: { type: Object, default: () => ({}) }, |
| | | }); |
| | | |
| | | 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 || []; |
| | |
| | | align-items: center; |
| | | flex-shrink: 0; |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | class="approve-detail-dialog" |
| | | > |
| | | <div class="approve-detail-body"> |
| | | <ApproveDetailPanel :row="detailRow" /> |
| | | <ApproveDetailPanel :row="detailRow" :detail-data="detailData" /> |
| | | <div class="detail-block"> |
| | | <div class="detail-block-title"> |
| | | 审批流程({{ detailRow.tasks?.length || detailRow.flowNodes?.length || 0 }} 项) |
| | |
| | | destroy-on-close |
| | | @closed="approveOpinion = ''" |
| | | > |
| | | <ApproveDetailPanel :row="approveDialog.row" /> |
| | | <ApproveDetailPanel :row="approveDialog.row" :detail-data="detailData" /> |
| | | <div class="detail-block mt16"> |
| | | <div class="detail-block-title"> |
| | | 审批流程({{ approveDialog.row?.tasks?.length || approveDialog.row?.flowNodes?.length || 0 }} 项) |
| | |
| | | tableColumn, |
| | | detailDialog, |
| | | detailRow, |
| | | detailData, |
| | | reimburseDialog, |
| | | approveDialog, |
| | | approveOpinion, |
| | |
| | | border-left: 3px solid var(--el-color-primary); |
| | | line-height: 1.4; |
| | | } |
| | | </style> |
| | | </style> |
| | |
| | | saveApprovalInstance, |
| | | updateApprovalInstance, |
| | | } from "@/api/officeProcessAutomation/approvalInstance.js"; |
| | | import { getQuotationList } from "@/api/salesManagement/salesQuotation.js"; |
| | | import { getPurchaseByCode } from "@/api/procurementManagement/procurementLedger.js"; |
| | | import { getDeliveryDetailByShippingNo } from "@/api/salesManagement/deliveryLedger.js"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { Search } from "@element-plus/icons-vue"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | |
| | | |
| | | const detailDialog = reactive({ visible: false }); |
| | | const detailRow = ref({}); |
| | | const detailData = ref({}); |
| | | |
| | | const approveDialog = reactive({ visible: false, row: null }); |
| | | const approveOpinion = ref(""); |
| | |
| | | fetchBusinessTypeOptions(), |
| | | listApprovalTemplate(TEMPLATE_TYPE_CUSTOM), |
| | | ]); |
| | | submitBusinessTypeOptions.value = typeOptions; |
| | | submitBusinessTypeOptions.value = typeOptions.filter((x) => ![5, 6, 7].includes(x.value)); |
| | | allSubmitTemplates.value = unwrapTemplateList(customRes) |
| | | .filter((row) => mapEnabledFromApi(row.enabled)) |
| | | .map(mapSubmitTemplateCard); |
| | |
| | | await openReimburseDetail(row, "detail"); |
| | | return; |
| | | } |
| | | |
| | | detailRow.value = { ...row }; |
| | | // 报价审批:用审批事由字段承载的"报价单号"去查报价列表 |
| | | if (row.businessType === 6) { |
| | | const quotationNo = row?.quotationNo; |
| | | if (quotationNo) { |
| | | const res = await getQuotationList({ quotationNo }); |
| | | const records = res?.data?.records || []; |
| | | detailData.value = records[0] || {}; |
| | | } |
| | | } |
| | | |
| | | // 采购审批:用审批事由字段承载的"采购合同号"去查采购详情 |
| | | else if (row.businessType === 5) { |
| | | const purchaseContractNumber = row?.purchaseContractNumber; |
| | | if (purchaseContractNumber) { |
| | | const res = await getPurchaseByCode({ purchaseContractNumber }); |
| | | detailData.value = res || {}; |
| | | } |
| | | } |
| | | |
| | | // 发货审批:用审批事由字段承载的"发货单号"去查发货详情 |
| | | else if (row.businessType === 7) { |
| | | const shippingNo = row?.shippingNo; |
| | | if (shippingNo) { |
| | | const res = await getDeliveryDetailByShippingNo({ shippingNo }); |
| | | detailData.value = res?.data || res || {}; |
| | | } |
| | | } |
| | | |
| | | // 其他审批类型 |
| | | else { |
| | | detailData.value = {}; |
| | | } |
| | | |
| | | detailDialog.visible = true; |
| | | } |
| | | |
| | | async function openApprove(row) { |
| | | |
| | | if (inferReimburseModuleKeyFromInstance(row)) { |
| | | approveOpinion.value = ""; |
| | | await openReimburseDetail(row, "approve"); |
| | |
| | | } |
| | | approveDialog.row = { ...row }; |
| | | approveOpinion.value = ""; |
| | | // 报价审批:用审批事由字段承载的"报价单号"去查报价列表 |
| | | if (row.businessType === 6) { |
| | | const quotationNo = row?.quotationNo; |
| | | if (quotationNo) { |
| | | const res = await getQuotationList({ quotationNo }); |
| | | const records = res?.data?.records || []; |
| | | detailData.value = records[0] || {}; |
| | | } |
| | | } |
| | | |
| | | // 采购审批:用审批事由字段承载的"采购合同号"去查采购详情 |
| | | else if (row.businessType === 5) { |
| | | const purchaseContractNumber = row?.purchaseContractNumber; |
| | | if (purchaseContractNumber) { |
| | | const res = await getPurchaseByCode({ purchaseContractNumber }); |
| | | detailData.value = res || {}; |
| | | } |
| | | } |
| | | |
| | | // 发货审批:用审批事由字段承载的"发货单号"去查发货详情 |
| | | else if (row.businessType === 7) { |
| | | const shippingNo = row?.shippingNo; |
| | | if (shippingNo) { |
| | | const res = await getDeliveryDetailByShippingNo({ shippingNo }); |
| | | detailData.value = res?.data || res || {}; |
| | | } |
| | | } |
| | | |
| | | // 其他审批类型 |
| | | else { |
| | | detailData.value = {}; |
| | | } |
| | | approveDialog.visible = true; |
| | | } |
| | | |
| | |
| | | tableColumn, |
| | | detailDialog, |
| | | detailRow, |
| | | detailData, |
| | | reimburseDialog, |
| | | approveDialog, |
| | | approveOpinion, |
| | |
| | | openApprove, |
| | | fetchApprovalList, |
| | | }; |
| | | } |
| | | } |
| | |
| | | |
| | | <template v-if="detailAttachments.length"> |
| | | |
| | | <el-tag |
| | | |
| | | v-for="(f, i) in detailAttachments" |
| | | |
| | | :key="i" |
| | | |
| | | class="detail-attachment-tag" |
| | | |
| | | type="info" |
| | | |
| | | effect="plain" |
| | | |
| | | > |
| | | |
| | | {{ attachmentDisplayName(f) }} |
| | | |
| | | </el-tag> |
| | | <div class="detail-attachment-list"> |
| | | <div |
| | | v-for="(f, i) in detailAttachments" |
| | | :key="i" |
| | | class="detail-attachment-item" |
| | | @click="openAttachmentFile(f)" |
| | | > |
| | | <el-icon class="attachment-icon"><Document /></el-icon> |
| | | <span class="attachment-name">{{ attachmentDisplayName(f) }}</span> |
| | | <el-icon class="attachment-download"><Download /></el-icon> |
| | | </div> |
| | | </div> |
| | | |
| | | </template> |
| | | |
| | |
| | | |
| | | <script setup> |
| | | |
| | | import { ArrowRight, Plus, RefreshRight } from "@element-plus/icons-vue"; |
| | | import { ArrowRight, Document, Download, Plus, RefreshRight } from "@element-plus/icons-vue"; |
| | | |
| | | import { ElMessage } from "element-plus"; |
| | | |
| | |
| | | |
| | | } |
| | | |
| | | function openAttachmentFile(file) { |
| | | const url = file?.url || file?.previewURL || file?.downloadURL || file?.previewUrl || ""; |
| | | if (url) { |
| | | window.open(url, "_blank"); |
| | | } else { |
| | | ElMessage.warning("无法打开该附件"); |
| | | } |
| | | } |
| | | |
| | | |
| | | function unwrapArray(payload) { |
| | |
| | | |
| | | } |
| | | |
| | | .detail-attachment-tag { |
| | | .detail-attachment-list { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 8px; |
| | | } |
| | | |
| | | margin: 0 8px 8px 0; |
| | | .detail-attachment-item { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 6px; |
| | | padding: 8px 12px; |
| | | background: var(--el-fill-color-light); |
| | | border-radius: 6px; |
| | | cursor: pointer; |
| | | transition: background 0.2s; |
| | | } |
| | | |
| | | .detail-attachment-item:hover { |
| | | background: var(--el-fill-color); |
| | | } |
| | | |
| | | .attachment-icon { |
| | | font-size: 16px; |
| | | color: var(--el-text-color-regular); |
| | | } |
| | | |
| | | .attachment-name { |
| | | font-size: 14px; |
| | | color: var(--el-text-color-primary); |
| | | } |
| | | |
| | | .attachment-download { |
| | | font-size: 14px; |
| | | color: var(--el-text-color-secondary); |
| | | } |
| | | |
| | | .text-muted { |
| | |
| | | }); |
| | | } |
| | | |
| | | function openFormDialog(mode, row) { |
| | | async function openFormDialog(mode, row) { |
| | | formDialog.mode = mode; |
| | | formDialog.title = mode === "add" ? "新建审批模板" : "编辑审批模板"; |
| | | resetForm(mode === "edit" ? row : null); |
| | | if (mode === "edit" && row?.id) { |
| | | // 编辑时先查询详情获取完整数据(包含附件) |
| | | try { |
| | | const res = await getApprovalTemplateDetail(row.id); |
| | | const detailData = mapTemplateFromApi(unwrapTemplateDetail(res)); |
| | | resetForm(detailData); |
| | | } catch { |
| | | resetForm(row); |
| | | } |
| | | } else { |
| | | resetForm(mode === "edit" ? row : null); |
| | | } |
| | | formDialog.visible = true; |
| | | } |
| | | |
| | |
| | | mergeForm.totalAssignedQuantity = totalAssignedQuantity; |
| | | mergeForm.planCompleteTime = firstRow.requiredDate || ""; |
| | | mergeForm.productId = firstRow.productId || ""; |
| | | mergeForm.createTime = dayjs().format("YYYY-MM-DD HH:mm:ss"); |
| | | mergeForm.ids = selectedRows.value.map(row => row.id); |
| | | |
| | | // 打开弹窗 |