| | |
| | | @change="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="销售合同号:"> |
| | | <el-form-item label="订单号:"> |
| | | <el-input |
| | | v-model="searchForm.salesContractNo" |
| | | placeholder="请输入" |
| | |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="销售合同号" |
| | | label="订单号" |
| | | prop="salesContractNo" |
| | | width="180" |
| | | show-overflow-tooltip |
| | |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column fixed="right" label="操作" width="220" align="center"> |
| | | <el-table-column fixed="right" label="操作" width="280" align="center"> |
| | | <template #default="scope"> |
| | | <el-button |
| | | link |
| | |
| | | </el-button> |
| | | <el-button link type="primary" @click="openFileDialog(scope.row)" |
| | | >附件 |
| | | </el-button> |
| | | <el-button |
| | | link |
| | | type="primary" |
| | | v-if="scope.row.masterContractNo" |
| | | @click="openContractFileDialog(scope.row)" |
| | | >总合同附件 |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="总合同号:"> |
| | | <el-input |
| | | v-model="form.masterContractNo" |
| | | placeholder="请输入" |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="销售合同号:" prop="salesContractNo"> |
| | | <el-form-item label="订单号:" prop="salesContractNo"> |
| | | <div |
| | | style=" |
| | | display: flex; |
| | |
| | | clearable |
| | | :disabled="operationType === 'view'" |
| | | filterable |
| | | @change="handleCustomerChange" |
| | | > |
| | | <el-option |
| | | v-for="item in customerOption" |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="总合同号:"> |
| | | <el-select |
| | | v-model="form.masterContractNo" |
| | | placeholder="请先选择客户" |
| | | clearable |
| | | filterable |
| | | :disabled="operationType === 'view' || !form.customerId" |
| | | > |
| | | <el-option |
| | | v-for="item in contractList" |
| | | :key="item.id" |
| | | :label="item.masterContractNo" |
| | | :value="item.masterContractNo" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="项目名称:" prop="projectName"> |
| | | <el-input |
| | | v-model="form.projectName" |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="签订日期:" prop="executionDate"> |
| | | <el-date-picker |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="付款方式"> |
| | | <el-select |
| | |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="30"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="采购合同号:" prop="purchaseContractNumber"> |
| | | <el-select |
| | |
| | | record-type="sales_ledger" |
| | | :record-id="recordId" |
| | | /> |
| | | <!-- 总合同附件弹窗 --> |
| | | <el-dialog |
| | | v-model="contractFileDialogVisible" |
| | | title="总合同附件" |
| | | width="700px" |
| | | :close-on-click-modal="false" |
| | | > |
| | | <el-table :data="contractFileList" border v-if="contractFileList.length"> |
| | | <el-table-column prop="name" label="文件名称" show-overflow-tooltip /> |
| | | <el-table-column prop="byteSize" label="文件大小" width="120"> |
| | | <template #default="{ row }"> |
| | | {{ formatFileSize(row.byteSize) }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="操作" width="150"> |
| | | <template #default="{ row }"> |
| | | <el-link type="primary" :href="row.previewURL" target="_blank">预览</el-link> |
| | | <el-link type="primary" :href="row.downloadURL" style="margin-left: 10px">下载</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <el-empty v-else description="暂无附件" /> |
| | | </el-dialog> |
| | | <!-- 打印预览弹窗 --> |
| | | <el-dialog |
| | | v-model="printPreviewVisible" |
| | |
| | | import ImageUpload from "@/components/AttachmentUpload/image/index.vue"; |
| | | import { getCurrentDate } from "@/utils/index.js"; |
| | | import { listCustomer } from "@/api/basicData/customer.js"; |
| | | import { getCustomerContractList, getContractFilesByNo } from "@/api/basicData/customerContract.js"; |
| | | |
| | | const FileList = defineAsyncComponent(() => |
| | | import("@/components/Dialog/FileList.vue") |
| | |
| | | const total = ref(0); |
| | | const fileList = ref([]); |
| | | const deliveryFileList = ref([]); |
| | | // 合同列表(供下拉选择) |
| | | const contractList = ref([]); |
| | | // 总合同附件弹窗 |
| | | const contractFileDialogVisible = ref(false); |
| | | const contractFileList = ref([]); |
| | | |
| | | // 用户信息表单弹框数据 |
| | | const operationType = ref(""); |
| | |
| | | form.value.executionDate = getCurrentDate(); |
| | | // 创建时间默认为当天 |
| | | form.value.createTime = dayjs().format("YYYY-MM-DD HH:mm:ss"); |
| | | // 默认自动生成销售合同号 |
| | | // 默认自动生成订单号 |
| | | form.value.autoGenerateContractNo = true; |
| | | } else { |
| | | currentId.value = row.id; |
| | | getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => { |
| | | getSalesLedgerWithProducts({ id: row.id, type: 1 }).then(async (res) => { |
| | | form.value = { ...res }; |
| | | form.value.entryPerson = Number(res.entryPerson); |
| | | productData.value = form.value.productData; |
| | | fileList.value = form.value.storageBlobVOs; |
| | | // 编辑时设置自动生成为false,允许手动修改 |
| | | form.value.autoGenerateContractNo = false; |
| | | // 编辑时加载客户的合同列表以便回显总合同号 |
| | | if (res.customerId) { |
| | | try { |
| | | const contractRes = await getCustomerContractList(res.customerId); |
| | | if (contractRes.code === 200) { |
| | | contractList.value = contractRes.data || []; |
| | | } |
| | | } catch (error) { |
| | | console.error('获取客户合同列表失败:', error); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | // let userAll = await userStore.getInfo() |
| | |
| | | return status === "已发货" || status === "审核通过"; |
| | | }; |
| | | |
| | | /** 判断销售订单下是否存在已发货/发货完成的产品(不可删除) */ |
| | | /** 判断订单号下是否存在已发货/发货完成的产品(不可删除) */ |
| | | const hasShippedProducts = (products) => { |
| | | if (!products || !products.length) return false; |
| | | return products.some((p) => { |
| | |
| | | } |
| | | const ids = selectedRows.value.map((item) => item.id); |
| | | |
| | | // 检查是否有已进行发货或发货完成的销售订单,若有则不允许删除 |
| | | // 检查是否有已进行发货或发货完成的订单号,若有则不允许删除 |
| | | const cannotDeleteNames = []; |
| | | for (const row of selectedRows.value) { |
| | | let products = |
| | |
| | | } |
| | | if (cannotDeleteNames.length > 0) { |
| | | proxy.$modal.msgWarning( |
| | | "已进行发货或发货完成的销售订单不能删除:" + cannotDeleteNames.join("、") |
| | | "已进行发货或发货完成的订单号不能删除:" + cannotDeleteNames.join("、") |
| | | ); |
| | | return; |
| | | } |
| | |
| | | return statusMap[returnStatus] || 'info'; |
| | | }; |
| | | |
| | | // 客户选择变化时,加载该客户的合同列表 |
| | | const handleCustomerChange = async (customerId) => { |
| | | form.value.masterContractNo = ''; |
| | | contractList.value = []; |
| | | if (!customerId) return; |
| | | |
| | | try { |
| | | const res = await getCustomerContractList(customerId); |
| | | if (res.code === 200) { |
| | | contractList.value = res.data || []; |
| | | } |
| | | } catch (error) { |
| | | console.error('获取客户合同列表失败:', error); |
| | | } |
| | | }; |
| | | |
| | | // 查看总合同附件 |
| | | const openContractFileDialog = async (row) => { |
| | | if (!row.masterContractNo) { |
| | | proxy.$modal.msgWarning('该记录没有总合同号'); |
| | | return; |
| | | } |
| | | try { |
| | | const res = await getContractFilesByNo(row.masterContractNo); |
| | | if (res.code === 200) { |
| | | contractFileList.value = res.data || []; |
| | | contractFileDialogVisible.value = true; |
| | | } |
| | | } catch (error) { |
| | | console.error('获取合同附件失败:', error); |
| | | } |
| | | }; |
| | | |
| | | // 格式化文件大小 |
| | | const formatFileSize = (bytes) => { |
| | | if (!bytes) return '0 B'; |
| | | const k = 1024; |
| | | const sizes = ['B', 'KB', 'MB', 'GB']; |
| | | const i = Math.floor(Math.log(bytes) / Math.log(k)); |
| | | return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | searchForm.salesContractNo = route.query.salesContractNo; |
| | | getList(); |