| | |
| | | }); |
| | | } |
| | | |
| | | // 根据采购台账 ID 查询可退产品等信息 |
| | | export function getPurchaseReturnOrderByPurchaseLedgerId(query) { |
| | | return request({ |
| | | url: "/purchaseReturnOrders/getByPurchaseLedgerId", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | // 查看详情 |
| | | // purchaseReturnOrders/selectById/xxx |
| | | export function getPurchaseReturnOrderDetail(id) { |
| | |
| | | <span class="title-text">产品列表</span> |
| | | </div> |
| | | <el-button type="primary" size="small" style="margin-bottom: 20px" @click="isShowProductsModal = true" :disabled="!formState.purchaseLedgerId">添加产品</el-button> |
| | | <el-table :data="formState.purchaseReturnOrderProductsDtos" |
| | | <div class="product-table-scroll"> |
| | | <el-table class="product-table-inner" |
| | | :data="formState.purchaseReturnOrderProductsDtos" |
| | | border |
| | | max-height="400" |
| | | :scroll-y="true" |
| | | show-summary |
| | | :summary-method="summarizeChildrenTable"> |
| | | <el-table-column align="center" |
| | |
| | | label="序号" |
| | | type="index" |
| | | width="60" /> |
| | | <el-table-column label="入库单号" |
| | | prop="inboundBatches" |
| | | width="150" /> |
| | | <el-table-column label="批次号" |
| | | prop="batchNo" |
| | | width="150" /> |
| | | <el-table-column label="产品大类" |
| | | prop="productCategory" /> |
| | | <el-table-column label="规格型号" |
| | |
| | | prop="unit" |
| | | width="70" /> |
| | | <el-table-column label="数量" |
| | | prop="quantity" |
| | | prop="stockInNum" |
| | | width="100" /> |
| | | <el-table-column label="可退货数量" |
| | | prop="availableQuality" |
| | | prop="unQuantity" |
| | | width="130" /> |
| | | <el-table-column label="已退货数量" |
| | | prop="totalReturnNum" |
| | | width="130" /> |
| | | <el-table-column label="退货数量" |
| | | prop="returnQuantity" |
| | |
| | | placeholder="请输入退货数量" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="库存预警数量" |
| | | <!-- <el-table-column label="库存预警数量" |
| | | prop="warnNum" |
| | | width="120" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="税率(%)" |
| | | prop="taxRate" |
| | | width="80" /> |
| | | width="80" /> --> |
| | | <el-table-column label="含税单价(元)" |
| | | prop="taxInclusiveUnitPrice" |
| | | :formatter="formattedNumber" |
| | | width="150" /> |
| | | width="120" /> |
| | | <el-table-column label="退货总价(元)" |
| | | prop="taxInclusiveTotalPrice" |
| | | width="180"> |
| | | width="120"> |
| | | <template #default="scope"> |
| | | {{ formatAmount(getReturnTotal(scope.row)) || '--' }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="是否质检" |
| | | prop="isChecked" |
| | | width="150"> |
| | | width="100"> |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.isChecked ? 'success' : 'info'"> |
| | | {{ scope.row.isChecked ? '是' : '否' }} |
| | |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="section-title"> |
| | |
| | | import {getOptions, purchaseList} from "@/api/procurementManagement/procurementLedger.js"; |
| | | import {userListNoPageByTenantId} from "@/api/system/user.js"; |
| | | const ProductList = defineAsyncComponent(() => import("@/views/procurementManagement/purchaseReturnOrder/ProductList.vue")); |
| | | import { |
| | | productList, |
| | | } from "@/api/procurementManagement/procurementLedger.js"; |
| | | const props = defineProps({ |
| | | visible: { |
| | | type: Boolean, |
| | |
| | | } |
| | | |
| | | const getReturnQtyMax = (row) => { |
| | | const max = Number(row?.availableQuality) |
| | | const max = Number(row?.unQuantity) |
| | | if (Number.isNaN(max) || max < 0) { |
| | | return 0 |
| | | } |
| | |
| | | return proxy.summarizeTable( |
| | | param, |
| | | [ |
| | | "quantity", |
| | | "availableQuality", |
| | | "stockInNum", |
| | | "unQuantity", |
| | | "returnQuantity", |
| | | "taxInclusiveUnitPrice", |
| | | "taxInclusiveTotalPrice", |
| | | "taxExclusiveTotalPrice", |
| | | ], |
| | | { |
| | | quantity: { noDecimal: true }, // 不保留小数 |
| | | stockInNum: { noDecimal: true }, // 不保留小数 |
| | | returnQuantity: { noDecimal: true }, // 不保留小数 |
| | | availableQuality: { noDecimal: true }, // 不保留小数 |
| | | unQuantity: { noDecimal: true }, // 不保留小数 |
| | | } |
| | | ); |
| | | }; |
| | |
| | | } |
| | | } |
| | | |
| | | // 处理改变采购台账数据 |
| | | const handleChangePurchaseLedgerId = async () => { |
| | | // 处理改变采购台账数据(不请求接口回显产品,产品仅在「添加产品」弹窗勾选后写入) |
| | | const handleChangePurchaseLedgerId = () => { |
| | | resetFeeInfo() |
| | | if (!formState.value.purchaseLedgerId) { |
| | | formState.value.purchaseReturnOrderProductsDtos = [] |
| | | return |
| | | } |
| | | const res = await productList({ salesLedgerId: formState.value.purchaseLedgerId, type: 2 }); |
| | | formState.value.purchaseReturnOrderProductsDtos = res.data.map(item => ({ |
| | | ...item, |
| | | returnQuantity: undefined, |
| | | taxInclusiveTotalPrice: 0, |
| | | salesLedgerProductId: item.id, |
| | | })) |
| | | formState.value.purchaseReturnOrderProductsDtos = [] |
| | | syncTotalAmount() |
| | | } |
| | | |
| | |
| | | ...item, |
| | | returnQuantity: undefined, |
| | | taxInclusiveTotalPrice: 0, |
| | | salesLedgerProductId: item.id, |
| | | salesLedgerProductId: item.salesLedgerProductId ?? item.id, |
| | | })); |
| | | formState.value.purchaseReturnOrderProductsDtos.push(...newProducts); |
| | | syncTotalAmount() |
| | |
| | | // 逐行校验退货数量:任意一行未填/非法/超限都不允许提交 |
| | | const invalidRowIndex = productList.findIndex((item) => { |
| | | const qty = Number(item.returnQuantity) |
| | | const maxQty = Number(item.availableQuality) |
| | | const maxQty = Number(item.unQuantity) |
| | | |
| | | if (item.returnQuantity === null || item.returnQuantity === undefined || item.returnQuantity === "") { |
| | | return true |
| | |
| | | |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (valid) { |
| | | createPurchaseReturnOrder(formState.value).then(res => { |
| | | console.log(productList) |
| | | const submitPayload = { |
| | | ...formState.value, |
| | | purchaseReturnOrderProductsDtos: productList.map((row) => ({ |
| | | ...row, |
| | | stockInRecordId: row.id, |
| | | })), |
| | | } |
| | | createPurchaseReturnOrder(submitPayload).then(res => { |
| | | // 关闭模态框 |
| | | isShow.value = false; |
| | | // 告知父组件已完成 |
| | |
| | | border-radius: 50%; |
| | | margin-right: 8px; |
| | | } |
| | | |
| | | .product-table-scroll { |
| | | width: 100%; |
| | | overflow-x: auto; |
| | | } |
| | | |
| | | .product-table-inner { |
| | | min-width: 1280px; |
| | | } |
| | | </style> |
| | |
| | | width="1200" |
| | | @close="closeModal" |
| | | > |
| | | <div class="table_list"> |
| | | <div class="table_list" v-loading="tableLoading"> |
| | | <el-table :data="tableData" |
| | | border |
| | | row-key="id" |
| | | @selection-change="handleChangeSelection"> |
| | | <el-table-column align="center" |
| | | type="selection" |
| | |
| | | label="序号" |
| | | type="index" |
| | | width="60" /> |
| | | <el-table-column label="入库单号" |
| | | prop="inboundBatches" |
| | | width="150" /> |
| | | <el-table-column label="批次号" |
| | | prop="batchNo" |
| | | width="150" /> |
| | | <el-table-column label="产品大类" |
| | | prop="productCategory" /> |
| | | <el-table-column label="规格型号" |
| | |
| | | prop="unit" |
| | | width="70" /> |
| | | <el-table-column label="数量" |
| | | prop="quantity" |
| | | prop="stockInNum" |
| | | width="70" /> |
| | | <el-table-column label="库存预警数量" |
| | | <el-table-column label="可退货数量" |
| | | prop="unQuantity" |
| | | width="130" /> |
| | | <el-table-column label="已退货数量" |
| | | prop="totalReturnNum" |
| | | width="130" /> |
| | | <!-- <el-table-column label="库存预警数量" |
| | | prop="warnNum" |
| | | width="120" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="税率(%)" |
| | | prop="taxRate" |
| | | width="80" /> |
| | | width="80" /> --> |
| | | <el-table-column label="含税单价(元)" |
| | | prop="taxInclusiveUnitPrice" |
| | | :formatter="formattedNumber" |
| | | width="150" /> |
| | | <el-table-column label="含税总价(元)" |
| | | <!-- <el-table-column label="含税总价(元)" |
| | | prop="taxInclusiveTotalPrice" |
| | | :formatter="formattedNumber" |
| | | width="150" /> |
| | | <el-table-column label="不含税总价(元)" |
| | | prop="taxExclusiveTotalPrice" |
| | | :formatter="formattedNumber" |
| | | width="150" /> |
| | | width="150" /> --> |
| | | <el-table-column label="是否质检" |
| | | prop="isChecked" |
| | | width="150"> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" |
| | | :page="page.current" :limit="page.size" @pagination="paginationChange" /> |
| | | </div> |
| | | |
| | | <template #footer> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {computed, reactive, ref, onMounted} from "vue"; |
| | | import {productList} from "@/api/procurementManagement/procurementLedger.js"; |
| | | import {computed, ref, onMounted} from "vue"; |
| | | import {getPurchaseReturnOrderByPurchaseLedgerId} from "@/api/procurementManagement/purchase_return_order.js"; |
| | | import {ElMessage} from "element-plus"; |
| | | |
| | | const props = defineProps({ |
| | |
| | | }, |
| | | |
| | | purchaseLedgerId: { |
| | | type: Number, |
| | | type: [Number, String], |
| | | required: true, |
| | | } |
| | | }); |
| | |
| | | const tableData = ref([]) |
| | | const selectedRows = ref([]) |
| | | const tableLoading = ref(false) |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | }) |
| | | const total = ref(0) |
| | | const formattedNumber = (row, column, cellValue) => { |
| | | return parseFloat(cellValue).toFixed(2); |
| | | }; |
| | | |
| | | const paginationChange = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList() |
| | | } |
| | | |
| | | const handleChangeSelection = (val) => { |
| | | selectedRows.value = val; |
| | | } |
| | | |
| | | /** 与 New.vue 中采购台账变更时解析 getByPurchaseLedgerId 的规则一致 */ |
| | | const parseProductRowsFromLedgerResponse = (res) => { |
| | | const payload = res?.data |
| | | let list = [] |
| | | if (Array.isArray(payload)) { |
| | | list = payload |
| | | } else if (payload && typeof payload === 'object') { |
| | | const nested = |
| | | payload.purchaseReturnOrderProductsDtos || |
| | | payload.purchaseReturnOrderProductsDetailVoList |
| | | list = Array.isArray(nested) ? nested : [] |
| | | if (list.length && list[0]?.salesLedgerProduct) { |
| | | list = list.map((item) => ({ ...item, ...item.salesLedgerProduct })) |
| | | } |
| | | } |
| | | return list |
| | | } |
| | | |
| | | const fetchData = () => { |
| | | tableLoading.value = true; |
| | | productList({salesLedgerId: props.purchaseLedgerId, type: 2}).then((res) => { |
| | | tableData.value = res.data; |
| | | }).finally(() => { |
| | | tableLoading.value = false; |
| | | if (props.purchaseLedgerId === undefined || props.purchaseLedgerId === null || props.purchaseLedgerId === '') { |
| | | tableData.value = [] |
| | | return |
| | | } |
| | | tableLoading.value = true |
| | | getPurchaseReturnOrderByPurchaseLedgerId({ |
| | | purchaseLedgerId: props.purchaseLedgerId, |
| | | }) |
| | | .then((res) => { |
| | | const list = parseProductRowsFromLedgerResponse(res) |
| | | tableData.value = list |
| | | }) |
| | | .catch(() => { |
| | | tableData.value = [] |
| | | }) |
| | | .finally(() => { |
| | | tableLoading.value = false |
| | | }) |
| | | } |
| | | |
| | | const handleSubmit = () => { |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <el-form :model="searchForm" |
| | | :inline="true"> |
| | | <el-form :model="searchForm" :inline="true"> |
| | | <el-form-item label="退料单号:"> |
| | | <el-input v-model="searchForm.no" |
| | | placeholder="请输入" |
| | | clearable |
| | | prefix-icon="Search" |
| | | @change="handleQuery" /> |
| | | <el-input |
| | | v-model="searchForm.no" |
| | | placeholder="请输入" |
| | | clearable |
| | | prefix-icon="Search" |
| | | @change="handleQuery" |
| | | /> |
| | | </el-form-item> |
| | | |
| | | <el-form-item> |
| | | <el-button type="primary" |
| | | @click="handleQuery"> 搜索 </el-button> |
| | | <el-button type="primary" @click="handleQuery"> 搜索 </el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <div> |
| | | <el-button type="primary" @click="isShowNewModal = true">新增</el-button> |
| | | <el-button type="primary" @click="isShowNewModal = true" |
| | | >新增</el-button |
| | | > |
| | | </div> |
| | | </div> |
| | | |
| | |
| | | @pagination="paginationChange" |
| | | > |
| | | <template #operation="{ row }"> |
| | | <el-button link type="primary" size="small" style="color: #67C23A" @click="handleDetail(row)">详情</el-button> |
| | | <el-button link size="small" @click="handleDelete(row)">删除</el-button> |
| | | <el-button |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | style="color: #67c23a" |
| | | @click="handleDetail(row)" |
| | | >详情</el-button |
| | | > |
| | | <el-button link size="small" @click="handleDelete(row)" |
| | | >删除</el-button |
| | | > |
| | | </template> |
| | | </PIMTable> |
| | | </div> |
| | | <new v-if="isShowNewModal" |
| | | v-model:visible="isShowNewModal" |
| | | @completed="handleQuery" /> |
| | | <new |
| | | v-if="isShowNewModal" |
| | | v-model:visible="isShowNewModal" |
| | | @completed="handleQuery" |
| | | /> |
| | | |
| | | <el-dialog |
| | | v-model="detailVisible" |
| | |
| | | > |
| | | <div v-loading="detailLoading"> |
| | | <el-descriptions :column="3" border> |
| | | <el-descriptions-item label="退料单号">{{ detailData.no || '--' }}</el-descriptions-item> |
| | | <el-descriptions-item label="退货方式">{{ getReturnTypeLabel(detailData.returnType) }}</el-descriptions-item> |
| | | <el-descriptions-item label="供应商名称">{{ detailData.supplierName || '--' }}</el-descriptions-item> |
| | | <el-descriptions-item label="项目阶段">{{ getProjectPhaseLabel(detailData.projectPhase) }}</el-descriptions-item> |
| | | <el-descriptions-item label="关联单号">{{ detailData.purchaseContractNumber || '--' }}</el-descriptions-item> |
| | | <el-descriptions-item label="制作日期">{{ detailData.preparedAt || '--' }}</el-descriptions-item> |
| | | <el-descriptions-item label="制单人">{{ detailData.preparedUserName || '--' }}</el-descriptions-item> |
| | | <el-descriptions-item label="退料人">{{ detailData.returnUserName || '--' }}</el-descriptions-item> |
| | | <el-descriptions-item label="整单折扣额">{{ formatAmount(detailData.totalDiscountAmount) }}</el-descriptions-item> |
| | | <el-descriptions-item label="整单折扣率">{{ detailData.totalDiscountRate ?? '--' }}</el-descriptions-item> |
| | | <el-descriptions-item label="成交金额">{{ formatAmount(detailData.totalAmount) }}</el-descriptions-item> |
| | | <el-descriptions-item label="创建人">{{ detailData.createUserName || '--' }}</el-descriptions-item> |
| | | <el-descriptions-item label="创建时间">{{ detailData.createTime || '--' }}</el-descriptions-item> |
| | | <el-descriptions-item label="最近更新时间">{{ detailData.updateTime || '--' }}</el-descriptions-item> |
| | | <el-descriptions-item label="备注" :span="3">{{ detailData.remark || '--' }}</el-descriptions-item> |
| | | <el-descriptions-item label="退料单号">{{ |
| | | detailData.no || "--" |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="退货方式">{{ |
| | | getReturnTypeLabel(detailData.returnType) |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="供应商名称">{{ |
| | | detailData.supplierName || "--" |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="项目阶段">{{ |
| | | getProjectPhaseLabel(detailData.projectPhase) |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="关联的采购订单号">{{ |
| | | detailData.purchaseContractNumber || "--" |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="制作日期">{{ |
| | | detailData.preparedAt || "--" |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="制单人">{{ |
| | | detailData.preparedUserName || "--" |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="退料人">{{ |
| | | detailData.returnUserName || "--" |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="整单折扣额">{{ |
| | | formatAmount(detailData.totalDiscountAmount) |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="整单折扣率">{{ |
| | | detailData.totalDiscountRate ?? "--" |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="成交金额">{{ |
| | | formatAmount(detailData.totalAmount) |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="创建人">{{ |
| | | detailData.createUserName || "--" |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="创建时间">{{ |
| | | detailData.createTime || "--" |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="最近更新时间">{{ |
| | | detailData.updateTime || "--" |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="备注" :span="3">{{ |
| | | detailData.remark || "--" |
| | | }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | |
| | | <el-divider content-position="left">产品列表</el-divider> |
| | |
| | | max-height="420" |
| | | style="width: 100%" |
| | | > |
| | | <el-table-column align="center" label="序号" type="index" width="60" /> |
| | | <el-table-column label="产品大类" prop="productCategory" min-width="120" show-overflow-tooltip /> |
| | | <el-table-column label="规格型号" prop="specificationModel" min-width="140" show-overflow-tooltip /> |
| | | <el-table-column |
| | | align="center" |
| | | label="序号" |
| | | type="index" |
| | | width="60" |
| | | /> |
| | | <el-table-column label="入库单号" prop="inboundBatches" width="150" /> |
| | | <el-table-column label="批次号" prop="batchNo" width="150" /> |
| | | <el-table-column |
| | | label="产品大类" |
| | | prop="productCategory" |
| | | min-width="120" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column |
| | | label="规格型号" |
| | | prop="specificationModel" |
| | | min-width="140" |
| | | show-overflow-tooltip |
| | | /> |
| | | <el-table-column label="单位" prop="unit" width="80" /> |
| | | <el-table-column label="数量" prop="quantity" width="80" /> |
| | | <el-table-column label="退货数量" prop="returnQuantity" width="100" /> |
| | | <el-table-column label="库存预警数量" prop="warnNum" width="120" /> |
| | | <el-table-column label="税率(%)" prop="taxRate" width="90" /> |
| | | <el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" width="130"> |
| | | <template #default="scope">{{ formatAmount(scope.row.taxInclusiveUnitPrice) }}</template> |
| | | <el-table-column label="数量" prop="stockInNum" width="80" /> |
| | | <el-table-column label="可退货数量" |
| | | prop="unQuantity" |
| | | width="100" /> |
| | | <el-table-column label="已退货数量" |
| | | prop="totalReturnNum" |
| | | width="100" /> |
| | | <!-- <el-table-column label="库存预警数量" prop="warnNum" width="120" /> --> |
| | | <!-- <el-table-column label="税率(%)" prop="taxRate" width="90" /> --> |
| | | <el-table-column |
| | | label="含税单价(元)" |
| | | prop="taxInclusiveUnitPrice" |
| | | width="130" |
| | | > |
| | | <template #default="scope">{{ |
| | | formatAmount(scope.row.taxInclusiveUnitPrice) |
| | | }}</template> |
| | | </el-table-column> |
| | | <el-table-column label="退货总价(元)" prop="taxInclusiveTotalPrice" width="130"> |
| | | <template #default="scope">{{ formatAmount(scope.row.taxInclusiveTotalPrice) }}</template> |
| | | <!-- <el-table-column |
| | | label="退货总价(元)" |
| | | prop="taxInclusiveTotalPrice" |
| | | width="130" |
| | | > |
| | | <template #default="scope">{{ |
| | | formatAmount(scope.row.taxInclusiveTotalPrice) |
| | | }}</template> |
| | | </el-table-column> |
| | | <el-table-column label="不退货总价(元)" prop="taxExclusiveTotalPrice" width="140"> |
| | | <template #default="scope">{{ formatAmount(scope.row.taxExclusiveTotalPrice) }}</template> |
| | | </el-table-column> |
| | | <el-table-column label="是否质检" prop="isChecked" width="100" align="center"> |
| | | <el-table-column |
| | | label="不退货总价(元)" |
| | | prop="taxExclusiveTotalPrice" |
| | | width="140" |
| | | > |
| | | <template #default="scope">{{ |
| | | formatAmount(scope.row.taxExclusiveTotalPrice) |
| | | }}</template> |
| | | </el-table-column> --> |
| | | <el-table-column |
| | | label="是否质检" |
| | | prop="isChecked" |
| | | width="100" |
| | | align="center" |
| | | > |
| | | <template #default="scope"> |
| | | <el-tag :type="scope.row.isChecked ? 'success' : 'info'"> |
| | | {{ scope.row.isChecked ? '是' : '否' }} |
| | | {{ scope.row.isChecked ? "是" : "否" }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import PIMTable from '@/components/PIMTable/PIMTable.vue' |
| | | import { ref, reactive, toRefs, onMounted, defineAsyncComponent, getCurrentInstance } from 'vue' |
| | | const { proxy } = getCurrentInstance() |
| | | import {findPurchaseReturnOrderListPage, getPurchaseReturnOrderDetail, deletePurchaseReturnOrder} from "@/api/procurementManagement/purchase_return_order.js"; |
| | | const New = defineAsyncComponent(() => import("@/views/procurementManagement/purchaseReturnOrder/New.vue")); |
| | | const tableData = ref([]) |
| | | const selectedRows = ref([]) |
| | | const tableLoading = ref(false) |
| | | import PIMTable from "@/components/PIMTable/PIMTable.vue"; |
| | | import { |
| | | ref, |
| | | reactive, |
| | | toRefs, |
| | | onMounted, |
| | | defineAsyncComponent, |
| | | getCurrentInstance, |
| | | } from "vue"; |
| | | const { proxy } = getCurrentInstance(); |
| | | import { |
| | | findPurchaseReturnOrderListPage, |
| | | getPurchaseReturnOrderDetail, |
| | | deletePurchaseReturnOrder, |
| | | } from "@/api/procurementManagement/purchase_return_order.js"; |
| | | const New = defineAsyncComponent(() => |
| | | import("@/views/procurementManagement/purchaseReturnOrder/New.vue") |
| | | ); |
| | | const tableData = ref([]); |
| | | const selectedRows = ref([]); |
| | | const tableLoading = ref(false); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0, |
| | | }) |
| | | const detailVisible = ref(false) |
| | | const detailLoading = ref(false) |
| | | const detailData = ref({}) |
| | | const detailProducts = ref([]) |
| | | }); |
| | | const detailVisible = ref(false); |
| | | const detailLoading = ref(false); |
| | | const detailData = ref({}); |
| | | const detailProducts = ref([]); |
| | | // 是否显示新增弹框 |
| | | const isShowNewModal = ref(false) |
| | | const isShowNewModal = ref(false); |
| | | const returnTypeOptions = [ |
| | | { label: '退货退款', value: 0 }, |
| | | { label: '拒收', value: 1 }, |
| | | ] |
| | | { label: "退货退款", value: 0 }, |
| | | { label: "拒收", value: 1 }, |
| | | ]; |
| | | const projectPhaseOptions = [ |
| | | { label: '立项', value: 0 }, |
| | | { label: '设计', value: 1 }, |
| | | { label: '采购', value: 2 }, |
| | | { label: '生产', value: 3 }, |
| | | { label: '出货', value: 4 }, |
| | | ] |
| | | { label: "立项", value: 0 }, |
| | | { label: "设计", value: 1 }, |
| | | { label: "采购", value: 2 }, |
| | | { label: "生产", value: 3 }, |
| | | { label: "出货", value: 4 }, |
| | | ]; |
| | | const tableColumn = ref([ |
| | | { |
| | | label: '退料单号', |
| | | prop: 'no', |
| | | label: "退料单号", |
| | | prop: "no", |
| | | }, |
| | | { |
| | | label: '退货方式', |
| | | prop: 'returnType', |
| | | formatData: (val) => returnTypeOptions.find(item => item.value === val)?.label || '--', |
| | | label: "退货方式", |
| | | prop: "returnType", |
| | | formatData: (val) => |
| | | returnTypeOptions.find((item) => item.value === val)?.label || "--", |
| | | }, |
| | | { |
| | | label: '供应商名称', |
| | | prop: 'supplierName', |
| | | label: "供应商名称", |
| | | prop: "supplierName", |
| | | width: 180, |
| | | }, |
| | | { |
| | | label: '项目阶段', |
| | | prop: 'projectPhase', |
| | | label: "项目阶段", |
| | | prop: "projectPhase", |
| | | width: 100, |
| | | formatData: (val) => projectPhaseOptions.find(item => String(item.value) === String(val))?.label || '--', |
| | | formatData: (val) => |
| | | projectPhaseOptions.find((item) => String(item.value) === String(val)) |
| | | ?.label || "--", |
| | | }, |
| | | { |
| | | label: '关联单号', |
| | | prop: 'purchaseContractNumber', |
| | | label: "关联的采购订单号", |
| | | prop: "purchaseContractNumber", |
| | | width: 160, |
| | | }, |
| | | { |
| | | label: '制作日期', |
| | | prop: 'preparedAt', |
| | | label: "制作日期", |
| | | prop: "preparedAt", |
| | | width: 130, |
| | | }, |
| | | { |
| | | label: '制单人', |
| | | prop: 'preparedUserName', |
| | | label: "制单人", |
| | | prop: "preparedUserName", |
| | | width: 110, |
| | | }, |
| | | { |
| | | label: '退料人', |
| | | prop: 'returnUserName', |
| | | label: "退料人", |
| | | prop: "returnUserName", |
| | | width: 110, |
| | | }, |
| | | |
| | | { |
| | | label: '整单折扣额', |
| | | prop: 'totalDiscountAmount', |
| | | label: "整单折扣额", |
| | | prop: "totalDiscountAmount", |
| | | width: 120, |
| | | }, |
| | | { |
| | | label: '整单折扣率', |
| | | prop: 'totalDiscountRate', |
| | | label: "整单折扣率", |
| | | prop: "totalDiscountRate", |
| | | width: 120, |
| | | }, |
| | | { |
| | | label: '成交金额', |
| | | prop: 'totalAmount', |
| | | label: "成交金额", |
| | | prop: "totalAmount", |
| | | width: 120, |
| | | }, |
| | | { |
| | | label: '创建人', |
| | | prop: 'createUserName', |
| | | label: "创建人", |
| | | prop: "createUserName", |
| | | width: 110, |
| | | }, |
| | | { |
| | | label: '创建时间', |
| | | prop: 'createTime', |
| | | label: "创建时间", |
| | | prop: "createTime", |
| | | width: 170, |
| | | }, |
| | | { |
| | | label: '最近更新时间', |
| | | prop: 'updateTime', |
| | | label: "最近更新时间", |
| | | prop: "updateTime", |
| | | width: 170, |
| | | }, |
| | | { |
| | | label: '备注', |
| | | prop: 'remark', |
| | | label: "备注", |
| | | prop: "remark", |
| | | width: 180, |
| | | }, |
| | | { |
| | | dataType: "action", |
| | | width: 120, |
| | | label: "操作", |
| | | align: "center", |
| | | fixed: "right", |
| | | label: "操作", |
| | | align: "center", |
| | | fixed: "right", |
| | | operation: [ |
| | | { |
| | | name: "详情", |
| | | type: "text", |
| | | clickFun: row => {handleDetail(row);}, |
| | | }, |
| | | name: "详情", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | handleDetail(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "删除", |
| | | clickFun: row => {handleDelete(row)}, |
| | | clickFun: (row) => { |
| | | handleDelete(row); |
| | | }, |
| | | }, |
| | | ], |
| | | ], |
| | | }, |
| | | |
| | | ]) |
| | | ]); |
| | | const data = reactive({ |
| | | searchForm: { |
| | | no: '', |
| | | } |
| | | }) |
| | | const { searchForm } = toRefs(data) |
| | | no: "", |
| | | }, |
| | | }); |
| | | const { searchForm } = toRefs(data); |
| | | |
| | | // 查询列表 |
| | | /** 搜索按钮操作 */ |
| | | const handleQuery = () => { |
| | | page.current = 1 |
| | | getList() |
| | | } |
| | | page.current = 1; |
| | | getList(); |
| | | }; |
| | | |
| | | // 删除操作 |
| | | const handleDelete = (row) => { |
| | | console.log('删除行数据:', row) |
| | | proxy?.$modal?.confirm('确定要删除吗?删除将无法恢复').then(() => { |
| | | // 这里调用删除接口,传入 row.id |
| | | deletePurchaseReturnOrder(row.id).then(() => { |
| | | proxy?.$modal?.msgSuccess?.("删除成功"); |
| | | getList() |
| | | }).catch(() => { |
| | | proxy?.$modal?.msgError?.('删除失败') |
| | | console.log("删除行数据:", row); |
| | | proxy?.$modal |
| | | ?.confirm("确定要删除吗?删除将无法恢复") |
| | | .then(() => { |
| | | // 这里调用删除接口,传入 row.id |
| | | deletePurchaseReturnOrder(row.id) |
| | | .then(() => { |
| | | proxy?.$modal?.msgSuccess?.("删除成功"); |
| | | getList(); |
| | | }) |
| | | .catch(() => { |
| | | proxy?.$modal?.msgError?.("删除失败"); |
| | | }); |
| | | }) |
| | | }).catch(() => { |
| | | // 取消删除 |
| | | proxy?.$modal?.msgInfo?.('已取消删除') |
| | | |
| | | }) |
| | | } |
| | | .catch(() => { |
| | | // 取消删除 |
| | | proxy?.$modal?.msgInfo?.("已取消删除"); |
| | | }); |
| | | }; |
| | | // 查看详情 |
| | | const handleDetail = (row) => { |
| | | if (!row?.id) { |
| | | proxy?.$modal?.msgWarning?.('未获取到单据ID') |
| | | return |
| | | proxy?.$modal?.msgWarning?.("未获取到单据ID"); |
| | | return; |
| | | } |
| | | detailVisible.value = true |
| | | detailLoading.value = true |
| | | getPurchaseReturnOrderDetail(row.id).then(res => { |
| | | const payload = res?.data || {} |
| | | detailData.value = payload |
| | | // 拼接连个对象成一个对象,方便展示 item 和 item.salesLedgerProduct 里的字段 |
| | | detailVisible.value = true; |
| | | detailLoading.value = true; |
| | | getPurchaseReturnOrderDetail(row.id) |
| | | .then((res) => { |
| | | const payload = res?.data || {}; |
| | | detailData.value = payload; |
| | | // 拼接连个对象成一个对象,方便展示 item 和 item.salesLedgerProduct 里的字段 |
| | | |
| | | |
| | | detailProducts.value = |
| | | payload.purchaseReturnOrderProductsDetailVoList.map(item => ({ ...item, ...item.salesLedgerProduct })) || |
| | | [] |
| | | }).catch(() => { |
| | | proxy?.$modal?.msgError?.('获取详情失败') |
| | | }).finally(() => { |
| | | detailLoading.value = false |
| | | }) |
| | | } |
| | | |
| | | detailProducts.value = |
| | | payload.purchaseReturnOrderProductsDetailVoList.map((item) => ({ |
| | | ...item, |
| | | ...item.salesLedgerProduct, |
| | | })) || []; |
| | | }) |
| | | .catch(() => { |
| | | proxy?.$modal?.msgError?.("获取详情失败"); |
| | | }) |
| | | .finally(() => { |
| | | detailLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | const paginationChange = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getList() |
| | | } |
| | | getList(); |
| | | }; |
| | | |
| | | const getList = () => { |
| | | tableLoading.value = true |
| | | findPurchaseReturnOrderListPage({ ...searchForm.value, ...page }).then(res => { |
| | | tableLoading.value = false |
| | | tableData.value = res.data.records |
| | | page.total = res.data.total |
| | | }).catch(() => { |
| | | tableLoading.value = false |
| | | }) |
| | | } |
| | | tableLoading.value = true; |
| | | findPurchaseReturnOrderListPage({ ...searchForm.value, ...page }) |
| | | .then((res) => { |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records; |
| | | page.total = res.data.total; |
| | | }) |
| | | .catch(() => { |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | // 表格选择数据 |
| | | const handleSelectionChange = (selection) => { |
| | | // 过滤掉子数据 |
| | | selectedRows.value = selection.filter(item => item.id); |
| | | } |
| | | selectedRows.value = selection.filter((item) => item.id); |
| | | }; |
| | | |
| | | const getReturnTypeLabel = (value) => { |
| | | return returnTypeOptions.find(item => String(item.value) === String(value))?.label || '--' |
| | | } |
| | | return ( |
| | | returnTypeOptions.find((item) => String(item.value) === String(value)) |
| | | ?.label || "--" |
| | | ); |
| | | }; |
| | | |
| | | const getProjectPhaseLabel = (value) => { |
| | | return projectPhaseOptions.find(item => String(item.value) === String(value))?.label || '--' |
| | | } |
| | | return ( |
| | | projectPhaseOptions.find((item) => String(item.value) === String(value)) |
| | | ?.label || "--" |
| | | ); |
| | | }; |
| | | |
| | | const formatAmount = (value) => { |
| | | if (value === null || value === undefined || value === '') { |
| | | return '--' |
| | | if (value === null || value === undefined || value === "") { |
| | | return "--"; |
| | | } |
| | | const num = Number(value) |
| | | const num = Number(value); |
| | | if (Number.isNaN(num)) { |
| | | return value |
| | | return value; |
| | | } |
| | | return num.toFixed(2) |
| | | } |
| | | return num.toFixed(2); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList() |
| | | }) |
| | | getList(); |
| | | }); |
| | | </script> |
| | | <style scoped> |
| | | .table_list { |
| | | margin-top: unset; |
| | | margin-top: unset; |
| | | } |
| | | </style> |
| | | |
| | |
| | | <el-descriptions-item label="客户名称">{{ detail.customerName }}</el-descriptions-item> |
| | | <el-descriptions-item label="销售单号">{{ detail.salesContractNo }}</el-descriptions-item> |
| | | <el-descriptions-item label="业务员">{{ detail.salesman }}</el-descriptions-item> |
| | | <el-descriptions-item label="关联出库单号">{{ detail.shippingNo }}</el-descriptions-item> |
| | | <el-descriptions-item label="项目名称">{{ detail.projectName }}</el-descriptions-item> |
| | | <el-descriptions-item label="关联发货单号">{{ detail.shippingNo }}</el-descriptions-item> |
| | | <!-- <el-descriptions-item label="项目名称">{{ detail.projectName }}</el-descriptions-item> --> |
| | | <el-descriptions-item label="制单人">{{ detail.maker }}</el-descriptions-item> |
| | | <el-descriptions-item label="制单时间">{{ detail.makeTime }}</el-descriptions-item> |
| | | <el-descriptions-item label="退货原因">{{ detail.returnReason }}</el-descriptions-item> |
| | |
| | | const availableProducts = ref([]); |
| | | |
| | | const tableColumn = [ |
| | | {align: "center", label: "产品大类", prop: "productCategory"}, |
| | | {align: "center", label: "规格型号", prop: "specificationModel"}, |
| | | {align: "center", label: "出库单号", prop: "outboundBatches"}, |
| | | {align: "center", label: "批次号", prop: "batchNo"}, |
| | | {align: "center", label: "产品大类", prop: "productName"}, |
| | | {align: "center", label: "规格型号", prop: "model"}, |
| | | {align: "center", label: "单位", prop: "unit", width: 80}, |
| | | {align: "center", label: "总数量", prop: "quantity", width: 120}, |
| | | {align: "center", label: "总数量", prop: "stockOutNum", width: 120}, |
| | | {align: "center", label: "已退货数量", prop: "totalReturnNum", width: 120}, |
| | | {align: "center", label: "未退货数量", prop: "unQuantity", width: 120}, |
| | | {align: "center", label: "退货数量", prop: "returnQuantity", width: 120}, |
| | |
| | | row-key="id" |
| | | > |
| | | <el-table-column align="center" type="selection" width="55" /> |
| | | <el-table-column align="center" prop="outboundBatches" label="出库单号" /> |
| | | <el-table-column align="center" prop="batchNo" label="批次号" /> |
| | | <el-table-column align="center" prop="productCategory" label="产品大类" /> |
| | | <el-table-column align="center" prop="specificationModel" label="规格型号" /> |
| | | <el-table-column align="center" prop="unit" label="单位" /> |
| | | <el-table-column align="center" prop="quantity" label="总数量" /> |
| | | <el-table-column align="center" prop="stockOutNum" label="总数量" /> |
| | | <el-table-column align="center" prop="unQuantity" label="未退货数量" /> |
| | | <el-table-column align="center" label="已退货数量"> |
| | | <template #default="{ row }">{{ calcAlreadyReturned(row) }}</template> |
| | |
| | | const { form, rules } = toRefs(data); |
| | | |
| | | const calcAlreadyReturned = (row) => { |
| | | const total = Number(row?.quantity ?? row?.totalQuantity ?? row?.totalReturnNum ?? 0); |
| | | const total = Number(row?.stockOutNum ?? row?.totalQuantity ?? row?.totalReturnNum ?? 0); |
| | | const un = Number(row?.unQuantity ?? 0); |
| | | if (!Number.isFinite(total) || !Number.isFinite(un)) return 0; |
| | | return Math.max(total - un, 0); |
| | | }; |
| | | |
| | | const tableColumn = ref([ |
| | | {align: "center", label: "出库单号", prop: "outboundBatches" }, |
| | | {align: "center", label: "批次号", prop: "batchNo" }, |
| | | {align: "center", label: "产品大类", prop: "productCategory" }, |
| | | {align: "center", label: "规格型号", prop: "specificationModel" }, |
| | | {align: "center", label: "单位", prop: "unit", width: 80 }, |
| | | {align: "center", label: "总数量", prop: "quantity", width: 120 }, |
| | | {align: "center", label: "总数量", prop: "stockOutNum", width: 120 }, |
| | | {align: "center", label: "已退货数量", prop: "totalReturnNum", width: 120 }, |
| | | {align: "center", label: "未退货数量", prop: "unQuantity", width: 120 }, |
| | | {align: "center", label: "退货数量", prop: "returnQuantity", dataType: "slot", slot: "returnQuantity", width: 120 }, |
| | |
| | | proxy.$refs["formRef"].validate(valid => { |
| | | if (!valid) return; |
| | | const returnSaleProducts = (tableData.value || []).map(el => ({ |
| | | returnSaleLedgerProductId: el.returnSaleLedgerProductId ?? el.id, |
| | | stockOutRecordId: el.returnSaleLedgerProductId ?? el.id, |
| | | productModelId: el.productModelId, |
| | | unit: el.unit, |
| | | num: Number(el.num ?? el.returnQuantity ?? 0), |
| | |
| | | // If backend returns project info, set it |
| | | if (res.data.projectId) form.value.projectId = res.data.projectId; |
| | | |
| | | // Store available products for selection |
| | | availableProducts.value = res.data.productDtoData || []; |
| | | availableProducts.value = |
| | | res.data.shippingProductVoList || []; |
| | | if (clearTable) tableData.value = []; |
| | | } |
| | | }; |
| | |
| | | }; |
| | | |
| | | const calculateRowAmount = (row) => { |
| | | const quantity = Number(row.returnQuantity || 0); |
| | | const stockOutNum = Number(row.returnQuantity || 0); |
| | | const price = Number(row.price || 0); |
| | | row.amount = (quantity * price).toFixed(2); |
| | | row.amount = (stockOutNum * price).toFixed(2); |
| | | }; |
| | | |
| | | const calculateTotalRefund = () => { |
| | |
| | | productName: product.productName, |
| | | specificationModel: product.specificationModel, |
| | | unit: product.unit, |
| | | quantity: product.quantity, |
| | | stockOutNum: product.stockOutNum, |
| | | totalReturnNum: product.totalReturnNum, |
| | | unQuantity: product.unQuantity |
| | | }); |
| | |
| | | <el-form-item label="销售单号"> |
| | | <el-input v-model="searchForm.salesContractNo" placeholder="销售单号" clearable /> |
| | | </el-form-item> |
| | | <el-form-item label="关联出库单号"> |
| | | <el-input v-model="searchForm.shippingNo" placeholder="关联出库单号" clearable /> |
| | | <el-form-item label="关联发货单号"> |
| | | <el-input v-model="searchForm.shippingNo" placeholder="关联发货单号" clearable /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" @click="handleQuery">搜索</el-button> |
| | |
| | | ]); |
| | | |
| | | const defaultColumns = [ |
| | | { label: "退货单号", prop: "returnNo", width: 160 }, |
| | | { label: "单据状态", prop: "status", width: 90, dataType: "slot", slot: "status" }, |
| | | { label: "制单时间", prop: "makeTime", width: 170 }, |
| | | { label: "客户名称", prop: "customerName", width: 220 }, |
| | | { label: "销售单号", prop: "salesContractNo", width: 160 }, |
| | | { label: "业务员", prop: "salesman", width: 120 }, |
| | | { label: "关联出库单号", prop: "shippingNo", width: 170 }, |
| | | { label: "项目名称", prop: "projectName", width: 180 }, |
| | | { label: "制单人", prop: "maker", width: 120 }, |
| | | { label: "退货单号", prop: "returnNo", minWidth: 160 }, |
| | | { label: "单据状态", prop: "status", minWidth: 90, dataType: "slot", slot: "status" }, |
| | | { label: "制单时间", prop: "makeTime", minWidth: 170 }, |
| | | { label: "客户名称", prop: "customerName", minWidth: 220 }, |
| | | { label: "销售单号", prop: "salesContractNo", minWidth: 160 }, |
| | | { label: "业务员", prop: "salesman", minWidth: 120 }, |
| | | { label: "关联发货单号", prop: "shippingNo", minWidth: 170 }, |
| | | { label: "项目名称", prop: "projectName", minWidth: 180 }, |
| | | { label: "制单人", prop: "maker", minWidth: 120 }, |
| | | { |
| | | label: "操作", |
| | | prop: "operation", |
| | | dataType: "action", |
| | | align: "center", |
| | | fixed: "right", |
| | | width: 240, |
| | | minWidth: 240, |
| | | operation: [ |
| | | { name: "编辑", disabled: (row) => row.status !== 0, type: "text", clickFun: (row) => openForm("edit", row) }, |
| | | { name: "退款处理", disabled: (row) => row.status !== 0, type: "text", clickFun: (row) => handleRowHandle(row) }, |