From 7a0790d8224db45a039bf33d0ef4e24ae879a243 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期二, 30 六月 2026 10:38:05 +0800
Subject: [PATCH] 采购退货重构,添加新增、删除功能;供应商管理新增修改删除功能
---
src/pages/basicData/supplierManage/index.vue | 35
src/pages/procurementManagement/purchaseReturnOrder/add.vue | 856 +++++++++++++++++++++++-------------------
src/pages/procurementManagement/purchaseReturnOrder/productList.vue | 50 ++
src/pages/procurementManagement/purchaseReturnOrder/view.vue | 33 +
src/pages/basicData/supplierManage/edit.vue | 110 +---
src/pages/procurementManagement/purchaseReturnOrder/index.vue | 75 ++
src/api/procurementManagement/purchaseReturnOrder.js | 8
7 files changed, 658 insertions(+), 509 deletions(-)
diff --git a/src/api/procurementManagement/purchaseReturnOrder.js b/src/api/procurementManagement/purchaseReturnOrder.js
index 80d171f..c140926 100644
--- a/src/api/procurementManagement/purchaseReturnOrder.js
+++ b/src/api/procurementManagement/purchaseReturnOrder.js
@@ -16,6 +16,14 @@
});
}
+export function getPurchaseReturnOrderByPurchaseLedgerId(query) {
+ return request({
+ url: "/purchaseReturnOrders/getByPurchaseLedgerId",
+ method: "get",
+ params: query,
+ });
+}
+
export function getPurchaseReturnOrderDetail(id) {
return request({
url: "/purchaseReturnOrders/selectById/" + id,
diff --git a/src/pages/basicData/supplierManage/edit.vue b/src/pages/basicData/supplierManage/edit.vue
index c890e88..ac6a440 100644
--- a/src/pages/basicData/supplierManage/edit.vue
+++ b/src/pages/basicData/supplierManage/edit.vue
@@ -1,56 +1,44 @@
<template>
<view class="account-detail">
<PageHeader :title="pageTitle" @back="goBack" />
- <up-form ref="formRef" :model="form" :rules="rules" label-width="120">
- <u-cell-group title="渚涘簲鍟嗕俊鎭�" class="form-section">
- <up-form-item label="渚涘簲鍟嗗悕绉�" prop="supplierName" required>
- <up-input v-model="form.supplierName" placeholder="璇疯緭鍏�" clearable />
- </up-form-item>
- <up-form-item label="绾崇◣浜鸿瘑鍒彿" prop="taxpayerIdentificationNum" required>
- <up-input v-model="form.taxpayerIdentificationNum" placeholder="璇疯緭鍏�" clearable />
- </up-form-item>
- <up-form-item label="鍏徃鍦板潃" prop="companyAddress" required>
- <up-input v-model="form.companyAddress" placeholder="璇疯緭鍏�" clearable />
- </up-form-item>
- <up-form-item label="鍏徃鐢佃瘽" prop="companyPhone" required>
- <up-input v-model="form.companyPhone" placeholder="璇疯緭鍏�" clearable />
- </up-form-item>
- <up-form-item label="寮�鎴疯" prop="bankAccountName" required>
- <up-input v-model="form.bankAccountName" placeholder="璇疯緭鍏�" clearable />
- </up-form-item>
- <up-form-item label="璐﹀彿" prop="bankAccountNum" required>
- <up-input v-model="form.bankAccountNum" placeholder="璇疯緭鍏�" clearable />
- </up-form-item>
- <up-form-item label="鑱旂郴浜�" prop="contactUserName">
- <up-input v-model="form.contactUserName" placeholder="璇疯緭鍏�" clearable />
- </up-form-item>
- <up-form-item label="鑱旂郴鐢佃瘽" prop="contactUserPhone">
- <up-input v-model="form.contactUserPhone" placeholder="璇疯緭鍏�" clearable />
- </up-form-item>
- <up-form-item label="渚涘簲鍟嗙被鍨�" prop="supplierType" required>
- <up-input
- v-model="supplierTypeText"
- placeholder="璇烽�夋嫨"
- readonly
- @click="showSupplierTypeSheet = true"
- />
- <template #right>
- <up-icon name="arrow-right" @click="showSupplierTypeSheet = true"></up-icon>
- </template>
- </up-form-item>
- <up-form-item label="鏄惁鐧藉悕鍗�" prop="isWhite" required>
- <up-input v-model="isWhiteText" placeholder="璇烽�夋嫨" readonly @click="showIsWhiteSheet = true" />
- <template #right>
- <up-icon name="arrow-right" @click="showIsWhiteSheet = true"></up-icon>
- </template>
- </up-form-item>
- <up-form-item label="缁存姢浜�" prop="maintainUserName">
- <up-input v-model="form.maintainUserName" disabled placeholder="鑷姩濉厖" />
- </up-form-item>
- <up-form-item label="缁存姢鏃堕棿" prop="maintainTime">
- <up-input v-model="form.maintainTime" disabled placeholder="鑷姩濉厖" />
- </up-form-item>
- </u-cell-group>
+ <up-form ref="formRef" :model="form" :rules="rules" label-width="110">
+ <up-form-item label="渚涘簲鍟嗗悕绉�" prop="supplierName" required>
+ <up-input v-model="form.supplierName" placeholder="璇疯緭鍏�" clearable />
+ </up-form-item>
+ <up-form-item label="绾崇◣浜鸿瘑鍒彿" prop="taxpayerIdentificationNum" required>
+ <up-input v-model="form.taxpayerIdentificationNum" placeholder="璇疯緭鍏�" clearable />
+ </up-form-item>
+ <up-form-item label="鍏徃鍦板潃" prop="companyAddress" required>
+ <up-input v-model="form.companyAddress" placeholder="璇疯緭鍏�" clearable />
+ </up-form-item>
+ <up-form-item label="渚涘簲鍟嗙被鍨�" prop="supplierType" required>
+ <up-input
+ v-model="supplierTypeText"
+ placeholder="璇烽�夋嫨"
+ readonly
+ @click="showSupplierTypeSheet = true"
+ />
+ <template #right>
+ <up-icon name="arrow-right" @click="showSupplierTypeSheet = true"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="鏄惁鐧藉悕鍗�" prop="isWhite" required>
+ <up-input
+ v-model="isWhiteText"
+ placeholder="璇烽�夋嫨"
+ readonly
+ @click="showIsWhiteSheet = true"
+ />
+ <template #right>
+ <up-icon name="arrow-right" @click="showIsWhiteSheet = true"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="缁存姢浜�" prop="maintainUserName">
+ <up-input v-model="form.maintainUserName" placeholder="鑷姩濉厖" disabled />
+ </up-form-item>
+ <up-form-item label="缁存姢鏃堕棿" prop="maintainTime">
+ <up-input v-model="form.maintainTime" placeholder="鑷姩濉厖" disabled />
+ </up-form-item>
</up-form>
<FooterButtons :loading="loading" confirmText="淇濆瓨" @cancel="goBack" @confirm="handleSubmit" />
@@ -88,11 +76,6 @@
supplierName: "",
taxpayerIdentificationNum: "",
companyAddress: "",
- companyPhone: "",
- bankAccountName: "",
- bankAccountNum: "",
- contactUserName: "",
- contactUserPhone: "",
maintainUserId: "",
maintainUserName: "",
maintainTime: "",
@@ -104,9 +87,6 @@
supplierName: [{ required: true, message: "璇疯緭鍏ヤ緵搴斿晢鍚嶇О", trigger: "blur" }],
taxpayerIdentificationNum: [{ required: true, message: "璇疯緭鍏ョ撼绋庝汉璇嗗埆鍙�", trigger: "blur" }],
companyAddress: [{ required: true, message: "璇疯緭鍏ュ叕鍙稿湴鍧�", trigger: "blur" }],
- companyPhone: [{ required: true, message: "璇疯緭鍏ュ叕鍙哥數璇�", trigger: "blur" }],
- bankAccountName: [{ required: true, message: "璇疯緭鍏ュ紑鎴疯", trigger: "blur" }],
- bankAccountNum: [{ required: true, message: "璇疯緭鍏ヨ处鍙�", trigger: "blur" }],
supplierType: [{ required: true, message: "璇烽�夋嫨渚涘簲鍟嗙被鍨�", trigger: "change" }],
isWhite: [{ required: true, message: "璇烽�夋嫨鐧藉悕鍗�", trigger: "change" }],
};
@@ -200,17 +180,5 @@
</script>
<style scoped lang="scss">
- @import "@/styles/procurement-common.scss";
-
- .account-detail {
- min-height: 100vh;
- background: #f8f9fa;
- padding-bottom: 90px;
- }
-
- .form-section {
- margin: 12px;
- border-radius: 12px;
- overflow: hidden;
- }
+ @import "@/static/scss/form-common.scss";
</style>
diff --git a/src/pages/basicData/supplierManage/index.vue b/src/pages/basicData/supplierManage/index.vue
index 24aadc8..b20f519 100644
--- a/src/pages/basicData/supplierManage/index.vue
+++ b/src/pages/basicData/supplierManage/index.vue
@@ -48,16 +48,8 @@
<text class="detail-value">{{ item.taxpayerIdentificationNum || "-" }}</text>
</view>
<view class="detail-row">
- <text class="detail-label">鍏徃鐢佃瘽</text>
- <text class="detail-value">{{ item.companyPhone || "-" }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鑱旂郴浜�</text>
- <text class="detail-value">{{ item.contactUserName || "-" }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鑱旂郴鐢佃瘽</text>
- <text class="detail-value">{{ item.contactUserPhone || "-" }}</text>
+ <text class="detail-label">鍏徃鍦板潃</text>
+ <text class="detail-value">{{ item.companyAddress || "-" }}</text>
</view>
<view class="detail-row">
<text class="detail-label">缁存姢浜�</text>
@@ -68,11 +60,18 @@
<text class="detail-value">{{ item.maintainTime || "-" }}</text>
</view>
</view>
+ <view class="action-buttons">
+ <u-button size="small" class="action-btn" @click="goEdit(item)">缂栬緫</u-button>
+ <u-button size="small" class="action-btn" type="error" @click="handleDelete(item)">鍒犻櫎</u-button>
+ </view>
</view>
</view>
</view>
<view v-else class="no-data">
<text>鏆傛棤渚涘簲鍟嗘暟鎹�</text>
+ </view>
+ <view class="fab-button" @click="goAdd">
+ <up-icon name="plus" size="24" color="#ffffff"></up-icon>
</view>
</view>
</template>
@@ -80,10 +79,8 @@
<script setup>
import { reactive, ref } from "vue";
import { onShow } from "@dcloudio/uni-app";
- import useUserStore from "@/store/modules/user";
import { delSupplier, listSupplier } from "@/api/basicData/supplierManageFile";
- const userStore = useUserStore();
const supplierName = ref("");
const list = ref([]);
@@ -123,7 +120,14 @@
isWhite: tabValue.value,
})
.then(res => {
- list.value = res?.data?.records || [];
+ const payload = res?.data;
+ if (Array.isArray(payload)) {
+ list.value = payload;
+ } else if (payload && typeof payload === "object") {
+ list.value = payload.records || payload.rows || [];
+ } else {
+ list.value = [];
+ }
})
.catch(() => {
uni.showToast({ title: "鏌ヨ澶辫触", icon: "error" });
@@ -135,10 +139,6 @@
const handleDelete = item => {
if (!item?.id) return;
- if (item.maintainUserName && item.maintainUserName !== userStore.nickName) {
- uni.showToast({ title: "涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�", icon: "none" });
- return;
- }
uni.showModal({
title: "鍒犻櫎鎻愮ず",
content: "纭畾瑕佸垹闄ゅ悧锛熷垹闄ゅ悗鏃犳硶鎭㈠",
@@ -161,7 +161,6 @@
};
onShow(() => {
- userStore.getInfo();
getList();
});
</script>
diff --git a/src/pages/procurementManagement/purchaseReturnOrder/add.vue b/src/pages/procurementManagement/purchaseReturnOrder/add.vue
index fd5591e..4d411d9 100644
--- a/src/pages/procurementManagement/purchaseReturnOrder/add.vue
+++ b/src/pages/procurementManagement/purchaseReturnOrder/add.vue
@@ -1,263 +1,269 @@
<template>
<view class="account-detail">
- <PageHeader title="鏂板閲囪喘閫�璐�" @back="goBack" />
- <up-form ref="formRef" :model="form" :rules="rules" label-width="120">
- <u-cell-group title="鍩烘湰淇℃伅" class="form-section">
- <up-form-item label="閫�鏂欏崟鍙�" prop="no">
- <up-input
- v-model="form.no"
- :disabled="form.isDefaultNo"
- :placeholder="form.isDefaultNo ? '浣跨敤绯荤粺缂栧彿' : '璇疯緭鍏ラ��鏂欏崟鍙�'"
- clearable
- />
- <template #right>
- <up-switch v-model="form.isDefaultNo" @change="onDefaultNoChange" />
- </template>
- </up-form-item>
- <up-form-item label="閫�璐ф柟寮�" prop="returnType" required>
- <up-input
- v-model="returnTypeText"
- placeholder="璇烽�夋嫨"
- readonly
- @click="showReturnTypeSheet = true"
- />
- <template #right>
- <up-icon name="arrow-right" @click="showReturnTypeSheet = true"></up-icon>
- </template>
- </up-form-item>
- <up-form-item label="渚涘簲鍟�" prop="supplierId" required>
- <up-input
- v-model="supplierText"
- placeholder="璇烽�夋嫨"
- readonly
- @click="showSupplierSheet = true"
- />
- <template #right>
- <up-icon name="arrow-right" @click="showSupplierSheet = true"></up-icon>
- </template>
- </up-form-item>
- <up-form-item label="椤圭洰闃舵" prop="projectPhase">
- <up-input
- v-model="projectPhaseText"
- placeholder="璇烽�夋嫨"
- readonly
- @click="showProjectPhaseSheet = true"
- />
- <template #right>
- <up-icon name="arrow-right" @click="showProjectPhaseSheet = true"></up-icon>
- </template>
- </up-form-item>
- <up-form-item label="鍒朵綔鏃ユ湡" prop="preparedAt" required>
- <up-input
- v-model="form.preparedAt"
- placeholder="璇烽�夋嫨"
- readonly
- @click="showPreparedAtPicker = true"
- />
- <template #right>
- <up-icon name="arrow-right" @click="showPreparedAtPicker = true"></up-icon>
- </template>
- </up-form-item>
- <up-form-item label="鍒跺崟浜�" prop="preparedUserId" required>
- <up-input
- v-model="preparedUserText"
- placeholder="璇烽�夋嫨"
- readonly
- @click="showPreparedUserSheet = true"
- />
- <template #right>
- <up-icon name="arrow-right" @click="showPreparedUserSheet = true"></up-icon>
- </template>
- </up-form-item>
- <up-form-item label="閫�鏂欎汉" prop="returnUserId" required>
- <up-input
- v-model="returnUserText"
- placeholder="璇烽�夋嫨"
- readonly
- @click="showReturnUserSheet = true"
- />
- <template #right>
- <up-icon name="arrow-right" @click="showReturnUserSheet = true"></up-icon>
- </template>
- </up-form-item>
- <up-form-item label="閲囪喘鍚堝悓鍙�" prop="purchaseLedgerId" required>
- <up-input
- v-model="purchaseContractText"
- placeholder="璇烽�夋嫨"
- readonly
- @click="showPurchaseLedgerSheet = true"
- />
- <template #right>
- <up-icon name="arrow-right" @click="showPurchaseLedgerSheet = true"></up-icon>
- </template>
- </up-form-item>
- <up-form-item label="澶囨敞" prop="remark">
- <up-textarea v-model="form.remark" placeholder="璇疯緭鍏�" auto-height />
- </up-form-item>
- </u-cell-group>
+ <PageHeader title="鏂板閲囪喘閫�璐�"
+ @back="goBack" />
+ <up-form ref="formRef"
+ :model="form"
+ :rules="rules"
+ label-width="110">
+ <up-form-item label="閫�鏂欏崟鍙�"
+ prop="no">
+ <up-input v-model="form.no"
+ :disabled="form.isDefaultNo"
+ :placeholder="form.isDefaultNo ? '浣跨敤绯荤粺缂栧彿' : '璇疯緭鍏ラ��鏂欏崟鍙�'"
+ clearable />
+ <template #right>
+ <up-switch v-model="form.isDefaultNo"
+ @change="onDefaultNoChange" />
+ </template>
+ </up-form-item>
+ <up-form-item label="閫�璐ф柟寮�"
+ prop="returnType"
+ required>
+ <up-input v-model="returnTypeText"
+ placeholder="璇烽�夋嫨"
+ readonly
+ @click="showReturnTypeSheet = true" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showReturnTypeSheet = true"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="渚涘簲鍟�"
+ prop="supplierName"
+ required>
+ <up-input v-model="form.supplierName"
+ placeholder="璇烽�夋嫨"
+ readonly
+ @click="showSupplierSheet = true" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showSupplierSheet = true"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="椤圭洰闃舵"
+ prop="projectPhase">
+ <up-input v-model="projectPhaseText"
+ placeholder="璇烽�夋嫨"
+ readonly
+ @click="showProjectPhaseSheet = true" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showProjectPhaseSheet = true"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="鍒朵綔鏃ユ湡"
+ prop="preparedAt"
+ required>
+ <up-input v-model="form.preparedAt"
+ placeholder="璇烽�夋嫨"
+ readonly
+ @click="showPreparedAtPicker = true" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showPreparedAtPicker = true"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="鍒跺崟浜�"
+ prop="preparedUserName"
+ required>
+ <up-input v-model="form.preparedUserName"
+ placeholder="璇烽�夋嫨"
+ readonly
+ @click="openPreparedUserSheet" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="openPreparedUserSheet"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="閫�鏂欎汉"
+ prop="returnUserName"
+ required>
+ <up-input v-model="form.returnUserName"
+ placeholder="璇烽�夋嫨"
+ readonly
+ @click="openReturnUserSheet" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="openReturnUserSheet"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="閲囪喘鍚堝悓鍙�"
+ prop="purchaseContractNumber"
+ required>
+ <up-input v-model="form.purchaseContractNumber"
+ placeholder="璇烽�夋嫨"
+ readonly
+ @click="showPurchaseLedgerSheet = true" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showPurchaseLedgerSheet = true"></up-icon>
+ </template>
+ </up-form-item>
+ <up-form-item label="澶囨敞"
+ prop="remark">
+ <up-textarea v-model="form.remark"
+ placeholder="璇疯緭鍏ュ娉�"
+ auto-height />
+ </up-form-item>
- <u-cell-group title="浜у搧鍒楄〃" class="form-section">
- <view class="product-actions">
- <up-button
- type="primary"
- size="small"
- text="閫夋嫨浜у搧"
- :disabled="!form.purchaseLedgerId"
- @click="goSelectProducts"
- />
- <view class="amount-summary">
+ <view class="product-section">
+ <view class="section-header">
+ <view>
+ <text class="section-title">浜у搧淇℃伅</text>
+ </view>
+ <view class="section-actions">
<text class="amount-text">鍚堣锛歿{ formatAmount(baseAmount) }}</text>
+ <up-button type="primary"
+ size="small"
+ class="add-btn"
+ :disabled="!form.purchaseLedgerId"
+ @click="goSelectProducts">
+ 閫夋嫨浜у搧
+ </up-button>
</view>
</view>
- <view v-if="form.purchaseReturnOrderProductsDtos.length === 0" class="empty-products">
+ <view v-if="form.purchaseReturnOrderProductsDtos.length === 0"
+ class="empty-products">
<text>鏆傛棤浜у搧锛岃鍏堥�夋嫨浜у搧</text>
</view>
- <view v-else class="product-list">
- <view
- v-for="(item, index) in form.purchaseReturnOrderProductsDtos"
- :key="item.salesLedgerProductId || item.id || index"
- class="product-card"
- >
+ <view v-else>
+ <view class="product-card"
+ v-for="(item, index) in form.purchaseReturnOrderProductsDtos"
+ :key="item.id || index">
<view class="product-header">
<view class="product-title">
- <view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
- </view>
- <text class="product-name">浜у搧 {{ index + 1 }}</text>
+ <up-icon name="file-text"
+ size="16"
+ color="#2979ff"></up-icon>
+ <text class="product-productCategory">浜у搧 {{ index + 1 }}</text>
</view>
- <up-icon name="trash" size="18" color="#ee0a24" @click="removeProduct(index)" />
+ <view>
+ <up-button type="error"
+ size="mini"
+ class="del-btn"
+ @click="removeProduct(index)">
+ 鍒犻櫎
+ </up-button>
+ </view>
</view>
- <up-divider></up-divider>
- <view class="product-body">
- <view class="detail-row">
- <text class="detail-label">浜у搧澶х被</text>
- <text class="detail-value">{{ item.productCategory || "-" }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">瑙勬牸鍨嬪彿</text>
- <text class="detail-value">{{ item.specificationModel || "-" }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鏁伴噺</text>
- <text class="detail-value">{{ item.quantity ?? "-" }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍚◣鍗曚环(鍏�)</text>
- <text class="detail-value">{{ formatAmount(item.taxInclusiveUnitPrice) }}</text>
- </view>
- <view class="qty-row">
- <text class="qty-label">閫�璐ф暟閲�</text>
- <up-number-box
- v-model="item.returnQuantity"
- :min="0"
- :max="getReturnQtyMax(item)"
- :step="1"
- @change="syncRowTotal(item)"
- />
- </view>
- <view class="detail-row">
- <text class="detail-label">閫�璐ф�讳环(鍏�)</text>
- <text class="detail-value highlight">{{ formatAmount(item.taxInclusiveTotalPrice) }}</text>
- </view>
+ <view class="product-form">
+ <up-form-item label="浜у搧澶х被">
+ <up-input :modelValue="item.productCategory || '-'"
+ disabled />
+ </up-form-item>
+ <up-form-item label="瑙勬牸鍨嬪彿">
+ <up-input :modelValue="item.specificationModel || '-'"
+ disabled />
+ </up-form-item>
+ <up-form-item label="鍏ュ簱鏁伴噺">
+ <up-input :modelValue="String(item.stockInNum ?? item.quantity ?? '-')"
+ disabled />
+ </up-form-item>
+ <up-form-item label="鍙��璐ф暟閲�">
+ <up-input :modelValue="String(item.unQuantity ?? '-')"
+ disabled />
+ </up-form-item>
+ <up-form-item label="鍚◣鍗曚环(鍏�)">
+ <up-input :modelValue="formatAmount(item.taxInclusiveUnitPrice)"
+ disabled />
+ </up-form-item>
+ <up-form-item label="閫�璐ф暟閲�">
+ <up-number-box v-model="item.returnQuantity"
+ :min="0"
+ :max="getReturnQtyMax(item)"
+ :step="1"
+ @change="syncRowTotal(item)" />
+ </up-form-item>
+ <up-form-item label="閫�璐ф�讳环(鍏�)">
+ <up-input :modelValue="formatAmount(item.taxInclusiveTotalPrice)"
+ disabled />
+ </up-form-item>
</view>
</view>
</view>
- </u-cell-group>
+ </view>
- <u-cell-group title="璐圭敤淇℃伅" class="form-section">
- <up-form-item label="鏁村崟鎶樻墸棰�" prop="totalDiscountAmount">
- <up-input
- v-model="form.totalDiscountAmount"
- type="number"
- placeholder="璇疯緭鍏�"
- @blur="onDiscountAmountBlur"
- clearable
- />
- </up-form-item>
- <up-form-item label="鏁村崟鎶樻墸鐜�(%)" prop="totalDiscountRate">
- <up-input
- v-model="form.totalDiscountRate"
- type="number"
- placeholder="璇疯緭鍏�"
- @blur="onDiscountRateBlur"
- clearable
- />
- </up-form-item>
- <up-form-item label="鎴愪氦閲戦" prop="totalAmount" required>
- <up-input v-model="form.totalAmount" disabled placeholder="鑷姩璁$畻" />
- </up-form-item>
- <up-form-item label="鏀舵鏂瑰紡" prop="incomeType" required>
- <up-input
- v-model="incomeTypeText"
- placeholder="璇烽�夋嫨"
- readonly
- @click="showIncomeTypeSheet = true"
- />
- <template #right>
- <up-icon name="arrow-right" @click="showIncomeTypeSheet = true"></up-icon>
- </template>
- </up-form-item>
- </u-cell-group>
+ <up-form-item label="鏁村崟鎶樻墸棰�"
+ prop="totalDiscountAmount">
+ <up-input v-model="form.totalDiscountAmount"
+ type="number"
+ placeholder="璇疯緭鍏�"
+ @blur="onDiscountAmountBlur"
+ clearable />
+ </up-form-item>
+ <up-form-item label="鏁村崟鎶樻墸鐜�(%)"
+ prop="totalDiscountRate">
+ <up-input v-model="form.totalDiscountRate"
+ type="number"
+ placeholder="璇疯緭鍏�"
+ @blur="onDiscountRateBlur"
+ clearable />
+ </up-form-item>
+ <up-form-item label="鎴愪氦閲戦"
+ prop="totalAmount"
+ required>
+ <up-input v-model="form.totalAmount"
+ disabled
+ placeholder="鑷姩璁$畻" />
+ </up-form-item>
+ <up-form-item label="鏀舵鏂瑰紡"
+ prop="incomeType"
+ required>
+ <up-input v-model="incomeTypeText"
+ placeholder="璇烽�夋嫨"
+ readonly
+ @click="showIncomeTypeSheet = true" />
+ <template #right>
+ <up-icon name="arrow-right"
+ @click="showIncomeTypeSheet = true"></up-icon>
+ </template>
+ </up-form-item>
</up-form>
-
- <FooterButtons :loading="loading" confirmText="鎻愪氦" @cancel="goBack" @confirm="handleSubmit" />
-
- <up-action-sheet
- :show="showReturnTypeSheet"
- title="閫夋嫨閫�璐ф柟寮�"
- :actions="returnTypeActions"
- @select="onSelectReturnType"
- @close="showReturnTypeSheet = false"
- />
- <up-action-sheet
- :show="showProjectPhaseSheet"
- title="閫夋嫨椤圭洰闃舵"
- :actions="projectPhaseActions"
- @select="onSelectProjectPhase"
- @close="showProjectPhaseSheet = false"
- />
- <up-action-sheet
- :show="showSupplierSheet"
- title="閫夋嫨渚涘簲鍟�"
- :actions="supplierActions"
- @select="onSelectSupplier"
- @close="showSupplierSheet = false"
- />
- <up-action-sheet
- :show="showPreparedUserSheet"
- title="閫夋嫨鍒跺崟浜�"
- :actions="userActions"
- @select="onSelectPreparedUser"
- @close="showPreparedUserSheet = false"
- />
- <up-action-sheet
- :show="showReturnUserSheet"
- title="閫夋嫨閫�鏂欎汉"
- :actions="userActions"
- @select="onSelectReturnUser"
- @close="showReturnUserSheet = false"
- />
- <up-action-sheet
- :show="showPurchaseLedgerSheet"
- title="閫夋嫨閲囪喘鍚堝悓鍙�"
- :actions="purchaseLedgerActions"
- @select="onSelectPurchaseLedger"
- @close="showPurchaseLedgerSheet = false"
- />
- <up-action-sheet
- :show="showIncomeTypeSheet"
- title="閫夋嫨鏀舵鏂瑰紡"
- :actions="incomeTypeActions"
- @select="onSelectIncomeType"
- @close="showIncomeTypeSheet = false"
- />
- <up-datetime-picker
- :show="showPreparedAtPicker"
- v-model="preparedAtPickerValue"
- mode="date"
- @confirm="onPreparedAtConfirm"
- @cancel="showPreparedAtPicker = false"
- />
+ <FooterButtons :loading="loading"
+ confirmText="鎻愪氦"
+ @cancel="goBack"
+ @confirm="handleSubmit" />
+ <up-action-sheet :show="showReturnTypeSheet"
+ title="閫夋嫨閫�璐ф柟寮�"
+ :actions="returnTypeActions"
+ @select="onSelectReturnType"
+ @close="showReturnTypeSheet = false" />
+ <up-action-sheet :show="showProjectPhaseSheet"
+ title="閫夋嫨椤圭洰闃舵"
+ :actions="projectPhaseActions"
+ @select="onSelectProjectPhase"
+ @close="showProjectPhaseSheet = false" />
+ <up-action-sheet :show="showSupplierSheet"
+ title="閫夋嫨渚涘簲鍟�"
+ :actions="supplierActions"
+ @select="onSelectSupplier"
+ @close="showSupplierSheet = false" />
+ <up-action-sheet :show="showPreparedUserSheet"
+ title="閫夋嫨鍒跺崟浜�"
+ :actions="userActions"
+ @select="onSelectPreparedUser"
+ @close="showPreparedUserSheet = false" />
+ <up-action-sheet :show="showReturnUserSheet"
+ title="閫夋嫨閫�鏂欎汉"
+ :actions="userActions"
+ @select="onSelectReturnUser"
+ @close="showReturnUserSheet = false" />
+ <up-action-sheet :show="showPurchaseLedgerSheet"
+ title="閫夋嫨閲囪喘鍚堝悓鍙�"
+ :actions="purchaseLedgerActions"
+ @select="onSelectPurchaseLedger"
+ @close="showPurchaseLedgerSheet = false" />
+ <up-action-sheet :show="showIncomeTypeSheet"
+ title="閫夋嫨鏀舵鏂瑰紡"
+ :actions="incomeTypeActions"
+ @select="onSelectIncomeType"
+ @close="showIncomeTypeSheet = false" />
+ <up-datetime-picker :show="showPreparedAtPicker"
+ v-model="preparedAtPickerValue"
+ mode="date"
+ @confirm="onPreparedAtConfirm"
+ @cancel="showPreparedAtPicker = false" />
</view>
</template>
@@ -267,8 +273,11 @@
import FooterButtons from "@/components/FooterButtons.vue";
import { formatDateToYMD } from "@/utils/ruoyi";
import { createPurchaseReturnOrder } from "@/api/procurementManagement/purchaseReturnOrder";
- import { getOptions, purchaseListPage, productList } from "@/api/procurementManagement/procurementLedger";
- import { userListNoPageByTenantId } from "@/api/system/user";
+ import {
+ getOptions,
+ purchaseList,
+ } from "@/api/procurementManagement/procurementLedger";
+ import { userListNoPage, userListNoPageByTenantId } from "@/api/system/user";
const formRef = ref();
const loading = ref(false);
@@ -296,14 +305,110 @@
});
const rules = {
- returnType: [{ required: true, message: "璇烽�夋嫨閫�璐ф柟寮�", trigger: "change" }],
- supplierId: [{ required: true, message: "璇烽�夋嫨渚涘簲鍟�", trigger: "change" }],
- preparedAt: [{ required: true, message: "璇烽�夋嫨鍒朵綔鏃ユ湡", trigger: "change" }],
- preparedUserId: [{ required: true, message: "璇烽�夋嫨鍒跺崟浜�", trigger: "change" }],
- returnUserId: [{ required: true, message: "璇烽�夋嫨閫�鏂欎汉", trigger: "change" }],
- purchaseLedgerId: [{ required: true, message: "璇烽�夋嫨閲囪喘鍚堝悓鍙�", trigger: "change" }],
- totalAmount: [{ required: true, message: "鎴愪氦閲戦涓嶈兘涓虹┖", trigger: "change" }],
- incomeType: [{ required: true, message: "璇烽�夋嫨鏀舵鏂瑰紡", trigger: "change" }],
+ returnType: [
+ {
+ validator: (_rule, value, callback) => {
+ if (
+ value === 0 ||
+ value === 1 ||
+ String(value) === "0" ||
+ String(value) === "1"
+ ) {
+ callback();
+ return;
+ }
+ callback(new Error("璇烽�夋嫨閫�璐ф柟寮�"));
+ },
+ trigger: ["change", "blur"],
+ },
+ ],
+ supplierName: [
+ {
+ validator: (_rule, value, callback) => {
+ if (value === null || value === undefined) {
+ callback(new Error("璇烽�夋嫨渚涘簲鍟�"));
+ return;
+ }
+ if (String(value).trim() === "") {
+ callback(new Error("璇烽�夋嫨渚涘簲鍟�"));
+ return;
+ }
+ callback();
+ },
+ trigger: ["change", "blur"],
+ },
+ ],
+ preparedAt: [
+ { required: true, message: "璇烽�夋嫨鍒朵綔鏃ユ湡", trigger: "change" },
+ ],
+ preparedUserName: [
+ {
+ validator: (_rule, value, callback) => {
+ if (value === null || value === undefined) {
+ callback(new Error("璇烽�夋嫨鍒跺崟浜�"));
+ return;
+ }
+ if (String(value).trim() === "") {
+ callback(new Error("璇烽�夋嫨鍒跺崟浜�"));
+ return;
+ }
+ callback();
+ },
+ trigger: ["change", "blur"],
+ },
+ ],
+ returnUserName: [
+ {
+ validator: (_rule, value, callback) => {
+ if (value === null || value === undefined) {
+ callback(new Error("璇烽�夋嫨閫�鏂欎汉"));
+ return;
+ }
+ if (String(value).trim() === "") {
+ callback(new Error("璇烽�夋嫨閫�鏂欎汉"));
+ return;
+ }
+ callback();
+ },
+ trigger: ["change", "blur"],
+ },
+ ],
+ purchaseContractNumber: [
+ {
+ validator: (_rule, value, callback) => {
+ if (value === null || value === undefined) {
+ callback(new Error("璇烽�夋嫨閲囪喘鍚堝悓鍙�"));
+ return;
+ }
+ if (String(value).trim() === "") {
+ callback(new Error("璇烽�夋嫨閲囪喘鍚堝悓鍙�"));
+ return;
+ }
+ callback();
+ },
+ trigger: ["change", "blur"],
+ },
+ ],
+ totalAmount: [
+ {
+ validator: (_rule, value, callback) => {
+ if (value === null || value === undefined || value === "") {
+ callback(new Error("鎴愪氦閲戦涓嶈兘涓虹┖"));
+ return;
+ }
+ const num = Number(value);
+ if (Number.isNaN(num)) {
+ callback(new Error("鎴愪氦閲戦鏍煎紡涓嶆纭�"));
+ return;
+ }
+ callback();
+ },
+ trigger: ["change", "blur"],
+ },
+ ],
+ incomeType: [
+ { required: true, message: "璇烽�夋嫨鏀舵鏂瑰紡", trigger: "change" },
+ ],
};
const showReturnTypeSheet = ref(false);
@@ -339,35 +444,69 @@
];
const returnTypeText = computed(() => {
- return returnTypeActions.find(i => String(i.value) === String(form.value.returnType))?.name || "";
+ return (
+ returnTypeActions.find(
+ i => String(i.value) === String(form.value.returnType)
+ )?.name || ""
+ );
});
const projectPhaseText = computed(() => {
- return projectPhaseActions.find(i => String(i.value) === String(form.value.projectPhase))?.name || "";
+ return (
+ projectPhaseActions.find(
+ i => String(i.value) === String(form.value.projectPhase)
+ )?.name || ""
+ );
});
const supplierText = computed(() => {
- return supplierOptions.value.find(i => String(i.id) === String(form.value.supplierId))?.supplierName || "";
+ return (
+ supplierOptions.value.find(
+ i => String(i.id) === String(form.value.supplierId)
+ )?.supplierName || ""
+ );
});
const preparedUserText = computed(() => {
- return userOptions.value.find(i => String(i.userId) === String(form.value.preparedUserId))?.nickName || "";
+ return (
+ userOptions.value.find(
+ i => String(i.userId) === String(form.value.preparedUserId)
+ )?.nickName || ""
+ );
});
const returnUserText = computed(() => {
- return userOptions.value.find(i => String(i.userId) === String(form.value.returnUserId))?.nickName || "";
+ return (
+ userOptions.value.find(
+ i => String(i.userId) === String(form.value.returnUserId)
+ )?.nickName || ""
+ );
});
const purchaseContractText = computed(() => {
- return purchaseLedgerOptions.value.find(i => String(i.id) === String(form.value.purchaseLedgerId))?.purchaseContractNumber || "";
+ return (
+ purchaseLedgerOptions.value.find(
+ i => String(i.id) === String(form.value.purchaseLedgerId)
+ )?.purchaseContractNumber || ""
+ );
});
const incomeTypeText = computed(() => {
- return incomeTypeActions.find(i => String(i.value) === String(form.value.incomeType))?.name || "";
+ return (
+ incomeTypeActions.find(
+ i => String(i.value) === String(form.value.incomeType)
+ )?.name || ""
+ );
});
const supplierActions = computed(() => {
- return supplierOptions.value.map(i => ({ name: i.supplierName, value: i.id }));
+ return supplierOptions.value.map(i => ({
+ name: i.supplierName,
+ value: i.id,
+ }));
});
const userActions = computed(() => {
return userOptions.value.map(i => ({ name: i.nickName, value: i.userId }));
});
const purchaseLedgerActions = computed(() => {
- return purchaseLedgerOptions.value.map(i => ({ name: i.purchaseContractNumber, value: i.id }));
+ return purchaseLedgerOptions.value.map(i => ({
+ name: i.purchaseContractNumber,
+ value: i.id,
+ }));
});
const toNumber = val => {
@@ -384,7 +523,10 @@
const baseAmount = computed(() => {
const rows = form.value.purchaseReturnOrderProductsDtos || [];
- return rows.reduce((sum, item) => sum + toNumber(item.taxInclusiveTotalPrice), 0);
+ return rows.reduce(
+ (sum, item) => sum + toNumber(item.taxInclusiveTotalPrice),
+ 0
+ );
});
const syncTotalAmount = () => {
@@ -393,7 +535,7 @@
};
const getReturnQtyMax = row => {
- const qty = Number(row?.quantity);
+ const qty = Number(row?.unQuantity ?? row?.quantity);
if (Number.isNaN(qty) || qty < 0) return 0;
return qty;
};
@@ -432,7 +574,9 @@
};
const onSelectSupplier = action => {
form.value.supplierId = action.value;
- form.value.supplierName = supplierOptions.value.find(i => String(i.id) === String(action.value))?.supplierName || "";
+ form.value.supplierName =
+ supplierOptions.value.find(i => String(i.id) === String(action.value))
+ ?.supplierName || "";
form.value.purchaseLedgerId = undefined;
form.value.purchaseContractNumber = "";
form.value.purchaseReturnOrderProductsDtos = [];
@@ -442,18 +586,23 @@
};
const onSelectPreparedUser = action => {
form.value.preparedUserId = action.value;
- form.value.preparedUserName = userOptions.value.find(i => String(i.userId) === String(action.value))?.nickName || "";
+ form.value.preparedUserName =
+ userOptions.value.find(i => String(i.userId) === String(action.value))
+ ?.nickName || "";
showPreparedUserSheet.value = false;
};
const onSelectReturnUser = action => {
form.value.returnUserId = action.value;
- form.value.returnUserName = userOptions.value.find(i => String(i.userId) === String(action.value))?.nickName || "";
+ form.value.returnUserName =
+ userOptions.value.find(i => String(i.userId) === String(action.value))
+ ?.nickName || "";
showReturnUserSheet.value = false;
};
const onSelectPurchaseLedger = action => {
form.value.purchaseLedgerId = action.value;
form.value.purchaseContractNumber =
- purchaseLedgerOptions.value.find(i => String(i.id) === String(action.value))?.purchaseContractNumber || "";
+ purchaseLedgerOptions.value.find(i => String(i.id) === String(action.value))
+ ?.purchaseContractNumber || "";
form.value.purchaseReturnOrderProductsDtos = [];
resetFeeInfo();
showPurchaseLedgerSheet.value = false;
@@ -474,7 +623,9 @@
uni.showToast({ title: "鎶樻墸鐜囬渶鍦�0-100", icon: "none" });
return;
}
- form.value.totalDiscountAmount = Number((baseAmount.value * (rate / 100)).toFixed(2));
+ form.value.totalDiscountAmount = Number(
+ (baseAmount.value * (rate / 100)).toFixed(2)
+ );
syncTotalAmount();
};
@@ -520,26 +671,45 @@
};
const fetchUserOptions = () => {
- userListNoPageByTenantId()
+ return userListNoPageByTenantId()
.then(res => {
- userOptions.value = res.data || [];
+ const rows = res?.data || res?.rows || [];
+ if (Array.isArray(rows) && rows.length > 0) {
+ userOptions.value = rows;
+ return;
+ }
+ return userListNoPage().then(res2 => {
+ const rows2 = res2?.data || res2?.rows || [];
+ userOptions.value = Array.isArray(rows2) ? rows2 : [];
+ });
})
.catch(() => {
userOptions.value = [];
});
};
+ const ensureUserOptions = async () => {
+ if (userOptions.value?.length) return;
+ await fetchUserOptions();
+ };
+
+ const openPreparedUserSheet = async () => {
+ await ensureUserOptions();
+ showPreparedUserSheet.value = true;
+ };
+
+ const openReturnUserSheet = async () => {
+ await ensureUserOptions();
+ showReturnUserSheet.value = true;
+ };
+
const fetchPurchaseLedgerOptions = () => {
purchaseLedgerOptions.value = [];
if (!form.value.supplierId) return;
- purchaseListPage({
- current: -1,
- size: -1,
- supplierId: form.value.supplierId,
- approvalStatus: 3,
- })
+ purchaseList({ supplierId: form.value.supplierId, approvalStatus: 3 })
.then(res => {
- purchaseLedgerOptions.value = res?.data?.records || [];
+ const rows = res?.rows || res?.data?.records || res?.data || [];
+ purchaseLedgerOptions.value = Array.isArray(rows) ? rows : [];
})
.catch(() => {
purchaseLedgerOptions.value = [];
@@ -547,33 +717,18 @@
};
const mergeSelectedProducts = selectedRows => {
- const existing = new Set((form.value.purchaseReturnOrderProductsDtos || []).map(i => String(i.salesLedgerProductId || i.id)));
+ const existing = new Set(
+ (form.value.purchaseReturnOrderProductsDtos || []).map(i => String(i.id))
+ );
const toAdd = (selectedRows || [])
.filter(i => !existing.has(String(i.id)))
.map(i => ({
...i,
- salesLedgerProductId: i.id,
returnQuantity: 0,
taxInclusiveTotalPrice: 0,
}));
form.value.purchaseReturnOrderProductsDtos.push(...toAdd);
syncTotalAmount();
- };
-
- const loadProductsFromPurchaseLedger = () => {
- if (!form.value.purchaseLedgerId) return;
- uni.showLoading({ title: "鍔犺浇浜у搧...", mask: true });
- productList({ salesLedgerId: form.value.purchaseLedgerId, type: 2 })
- .then(res => {
- const rows = res.data || [];
- mergeSelectedProducts(rows);
- })
- .catch(() => {
- uni.showToast({ title: "鍔犺浇浜у搧澶辫触", icon: "error" });
- })
- .finally(() => {
- uni.hideLoading();
- });
};
const validateProducts = () => {
@@ -607,7 +762,12 @@
});
const payload = {
...form.value,
- purchaseReturnOrderProductsDtos: rows.filter(i => toNumber(i.returnQuantity) > 0),
+ purchaseReturnOrderProductsDtos: rows
+ .filter(i => toNumber(i.returnQuantity) > 0)
+ .map(row => ({
+ ...row,
+ stockInRecordId: row.id,
+ })),
};
createPurchaseReturnOrder(payload)
.then(() => {
@@ -649,110 +809,26 @@
}
}
});
-
- const showAutoLoadModalOnceKey = "purchaseReturnOrderAutoLoadShown";
- watch(
- () => form.value.purchaseLedgerId,
- (val, oldVal) => {
- if (!val || String(val) === String(oldVal)) return;
- if (uni.getStorageSync(showAutoLoadModalOnceKey)) return;
- uni.setStorageSync(showAutoLoadModalOnceKey, "1");
- uni.showModal({
- title: "鎻愮ず",
- content: "鏄惁鑷姩鍔犺浇璇ラ噰璐悎鍚屼笅鍏ㄩ儴浜у搧锛�",
- success: res => {
- if (res.confirm) loadProductsFromPurchaseLedger();
- },
- });
- }
- );
</script>
<style scoped lang="scss">
- @import "@/styles/procurement-common.scss";
+ @import "@/static/scss/form-common.scss";
- .account-detail {
- min-height: 100vh;
- background: #f8f9fa;
- padding-bottom: 90px;
- }
-
- .form-section {
- margin: 12px;
- border-radius: 12px;
- overflow: hidden;
- }
-
- .product-actions {
+ .section-actions {
display: flex;
align-items: center;
- justify-content: space-between;
- padding: 12px 12px 0 12px;
- }
-
- .amount-summary {
- display: flex;
- align-items: center;
+ gap: 10px;
}
.amount-text {
- font-size: 14px;
- color: #333;
- font-weight: 600;
- }
-
- .empty-products {
- padding: 16px 12px;
- color: #999;
- font-size: 14px;
- }
-
- .product-list {
- padding: 12px;
- display: flex;
- flex-direction: column;
- gap: 12px;
- }
-
- .product-card {
- background: #fff;
- border-radius: 12px;
- padding: 0 12px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
- }
-
- .product-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 12px 0;
- }
-
- .product-title {
- display: flex;
- align-items: center;
- gap: 8px;
- }
-
- .product-name {
- font-size: 14px;
- color: #333;
+ font-size: 13px;
+ color: #2979ff;
font-weight: 500;
}
- .product-body {
- padding: 12px 0;
- }
-
- .qty-row {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 8px 0;
- }
-
- .qty-label {
- font-size: 12px;
- color: #777;
+ .empty-products {
+ padding: 8px 0 0 0;
+ color: #999;
+ font-size: 14px;
}
</style>
diff --git a/src/pages/procurementManagement/purchaseReturnOrder/index.vue b/src/pages/procurementManagement/purchaseReturnOrder/index.vue
index 31bda94..786cd56 100644
--- a/src/pages/procurementManagement/purchaseReturnOrder/index.vue
+++ b/src/pages/procurementManagement/purchaseReturnOrder/index.vue
@@ -1,29 +1,35 @@
<template>
<view class="sales-account">
- <PageHeader title="閲囪喘閫�璐у崟" @back="goBack"/>
+ <PageHeader title="閲囪喘閫�璐у崟"
+ @back="goBack" />
<view class="search-section">
<view class="search-bar">
<view class="search-input">
- <up-input
- class="search-text"
- placeholder="璇疯緭鍏ラ��鏂欏崟鍙�"
- v-model="searchNo"
- @change="getList"
- clearable
- />
+ <up-input class="search-text"
+ placeholder="璇疯緭鍏ラ��鏂欏崟鍙�"
+ v-model="searchNo"
+ @change="getList"
+ clearable />
</view>
- <view class="filter-button" @click="getList">
- <up-icon name="search" size="24" color="#999"></up-icon>
+ <view class="filter-button"
+ @click="getList">
+ <up-icon name="search"
+ size="24"
+ color="#999"></up-icon>
</view>
</view>
</view>
- <view class="ledger-list" v-if="list.length > 0">
- <view v-for="item in list" :key="item.id">
+ <view class="ledger-list"
+ v-if="list.length > 0">
+ <view v-for="item in list"
+ :key="item.id">
<view class="ledger-item">
<view class="item-header">
<view class="item-left">
<view class="document-icon">
- <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
+ <up-icon name="file-text"
+ size="16"
+ color="#ffffff"></up-icon>
</view>
<text class="item-id">{{ item.no || "-" }}</text>
</view>
@@ -43,8 +49,20 @@
<text class="detail-value">{{ getProjectPhaseLabel(item.projectPhase) }}</text>
</view>
<view class="detail-row">
+ <text class="detail-label">閲囪喘鍚堝悓鍙�</text>
+ <text class="detail-value">{{ item.purchaseContractNumber || "-" }}</text>
+ </view>
+ <view class="detail-row">
<text class="detail-label">鍒朵綔鏃ユ湡</text>
<text class="detail-value">{{ item.preparedAt || "-" }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍒跺崟浜�</text>
+ <text class="detail-value">{{ item.preparedUserName || "-" }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">閫�鏂欎汉</text>
+ <text class="detail-value">{{ item.returnUserName || "-" }}</text>
</view>
<view class="detail-row">
<text class="detail-label">鎴愪氦閲戦(鍏�)</text>
@@ -52,13 +70,26 @@
</view>
</view>
<view class="action-buttons">
- <u-button size="small" class="action-btn" @click="goView(item)">璇︽儏</u-button>
+ <u-button size="small"
+ class="action-btn"
+ @click="goView(item)">璇︽儏</u-button>
+ <u-button size="small"
+ class="action-btn"
+ type="error"
+ @click="handleDelete(item)">鍒犻櫎</u-button>
</view>
</view>
</view>
</view>
- <view v-else class="no-data">
+ <view v-else
+ class="no-data">
<text>鏆傛棤閲囪喘閫�璐у崟鏁版嵁</text>
+ </view>
+ <view class="fab-button"
+ @click="goAdd">
+ <up-icon name="plus"
+ size="24"
+ color="#ffffff"></up-icon>
</view>
</view>
</template>
@@ -66,7 +97,10 @@
<script setup>
import { ref } from "vue";
import { onShow } from "@dcloudio/uni-app";
- import { findPurchaseReturnOrderListPage, deletePurchaseReturnOrder } from "@/api/procurementManagement/purchaseReturnOrder";
+ import {
+ findPurchaseReturnOrderListPage,
+ deletePurchaseReturnOrder,
+ } from "@/api/procurementManagement/purchaseReturnOrder";
const searchNo = ref("");
const list = ref([]);
@@ -124,7 +158,14 @@
no: searchNo.value,
})
.then(res => {
- list.value = res?.data?.records || [];
+ const payload = res?.data;
+ if (Array.isArray(payload)) {
+ list.value = payload;
+ } else if (payload && typeof payload === "object") {
+ list.value = payload.records || payload.rows || [];
+ } else {
+ list.value = [];
+ }
})
.catch(() => {
uni.showToast({ title: "鏌ヨ澶辫触", icon: "error" });
diff --git a/src/pages/procurementManagement/purchaseReturnOrder/productList.vue b/src/pages/procurementManagement/purchaseReturnOrder/productList.vue
index 048d975..ca5975e 100644
--- a/src/pages/procurementManagement/purchaseReturnOrder/productList.vue
+++ b/src/pages/procurementManagement/purchaseReturnOrder/productList.vue
@@ -19,6 +19,14 @@
</view>
<up-divider></up-divider>
<view class="item-details">
+ <view class="detail-row">
+ <text class="detail-label">鍏ュ簱鍗曞彿</text>
+ <text class="detail-value">{{ item.inboundBatches || "-" }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鎵规鍙�</text>
+ <text class="detail-value">{{ item.batchNo || "-" }}</text>
+ </view>
<view class="detail-row">
<text class="detail-label">瑙勬牸鍨嬪彿</text>
<text class="detail-value">{{ item.specificationModel || "-" }}</text>
@@ -29,12 +37,24 @@
</view>
<view class="detail-row">
<text class="detail-label">鏁伴噺</text>
- <text class="detail-value">{{ item.quantity ?? "-" }}</text>
+ <text class="detail-value">{{ item.stockInNum ?? item.quantity ?? "-" }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙��璐ф暟閲�</text>
+ <text class="detail-value">{{ item.unQuantity ?? "-" }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">宸查��璐ф暟閲�</text>
+ <text class="detail-value">{{ calcAlreadyReturned(item) }}</text>
</view>
<view class="detail-row">
<text class="detail-label">鍚◣鍗曚环(鍏�)</text>
<text class="detail-value highlight">{{ formatAmount(item.taxInclusiveUnitPrice) }}</text>
</view>
+ <view class="detail-row">
+ <text class="detail-label">鏄惁璐ㄦ</text>
+ <text class="detail-value">{{ item.isChecked ? "鏄�" : "鍚�" }}</text>
+ </view>
</view>
</view>
</view>
@@ -52,7 +72,7 @@
<script setup>
import { onLoad } from "@dcloudio/uni-app";
import { ref } from "vue";
- import { productList } from "@/api/procurementManagement/procurementLedger";
+ import { getPurchaseReturnOrderByPurchaseLedgerId } from "@/api/procurementManagement/purchaseReturnOrder";
const purchaseLedgerId = ref(undefined);
const list = ref([]);
@@ -64,6 +84,13 @@
const num = Number(value);
if (Number.isNaN(num)) return "0.00";
return num.toFixed(2);
+ };
+
+ const calcAlreadyReturned = row => {
+ const total = Number(row?.stockInNum ?? row?.totalQuantity ?? row?.quantity ?? 0);
+ const un = Number(row?.unQuantity ?? 0);
+ if (!Number.isFinite(total) || !Number.isFinite(un)) return 0;
+ return Math.max(total - un, 0);
};
const isSelected = id => {
@@ -94,9 +121,24 @@
const loadList = () => {
if (!purchaseLedgerId.value) return;
uni.showLoading({ title: "鍔犺浇涓�...", mask: true });
- productList({ salesLedgerId: purchaseLedgerId.value, type: 2 })
+ getPurchaseReturnOrderByPurchaseLedgerId({
+ purchaseLedgerId: purchaseLedgerId.value,
+ })
.then(res => {
- list.value = res.data || [];
+ const payload = res?.data;
+ let rows = [];
+ if (Array.isArray(payload)) {
+ rows = payload;
+ } else if (payload && typeof payload === "object") {
+ const nested =
+ payload.purchaseReturnOrderProductsDtos ||
+ payload.purchaseReturnOrderProductsDetailVoList;
+ rows = Array.isArray(nested) ? nested : [];
+ if (rows.length && rows[0]?.salesLedgerProduct) {
+ rows = rows.map(item => ({ ...item, ...item.salesLedgerProduct }));
+ }
+ }
+ list.value = rows;
})
.catch(() => {
uni.showToast({ title: "鍔犺浇澶辫触", icon: "error" });
diff --git a/src/pages/procurementManagement/purchaseReturnOrder/view.vue b/src/pages/procurementManagement/purchaseReturnOrder/view.vue
index bc33f1c..3aa852d 100644
--- a/src/pages/procurementManagement/purchaseReturnOrder/view.vue
+++ b/src/pages/procurementManagement/purchaseReturnOrder/view.vue
@@ -80,6 +80,14 @@
<up-divider></up-divider>
<view class="item-details">
<view class="detail-row">
+ <text class="detail-label">鍏ュ簱鍗曞彿</text>
+ <text class="detail-value">{{ p.inboundBatches || "-" }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鎵规鍙�</text>
+ <text class="detail-value">{{ p.batchNo || "-" }}</text>
+ </view>
+ <view class="detail-row">
<text class="detail-label">浜у搧澶х被</text>
<text class="detail-value">{{ p.productCategory || "-" }}</text>
</view>
@@ -93,23 +101,23 @@
</view>
<view class="detail-row">
<text class="detail-label">鏁伴噺</text>
- <text class="detail-value">{{ p.quantity ?? "-" }}</text>
+ <text class="detail-value">{{ p.stockInNum ?? p.quantity ?? "-" }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">鍙��璐ф暟閲�</text>
+ <text class="detail-value">{{ p.unQuantity ?? "-" }}</text>
+ </view>
+ <view class="detail-row">
+ <text class="detail-label">宸查��璐ф暟閲�</text>
+ <text class="detail-value">{{ calcAlreadyReturned(p) }}</text>
</view>
<view class="detail-row">
<text class="detail-label">閫�璐ф暟閲�</text>
<text class="detail-value highlight">{{ p.returnQuantity ?? "-" }}</text>
</view>
<view class="detail-row">
- <text class="detail-label">绋庣巼(%)</text>
- <text class="detail-value">{{ p.taxRate ?? "-" }}</text>
- </view>
- <view class="detail-row">
<text class="detail-label">鍚◣鍗曚环(鍏�)</text>
<text class="detail-value">{{ formatAmount(p.taxInclusiveUnitPrice) }}</text>
- </view>
- <view class="detail-row">
- <text class="detail-label">鍚◣鎬讳环(鍏�)</text>
- <text class="detail-value">{{ formatAmount(p.taxInclusiveTotalPrice) }}</text>
</view>
<view class="detail-row">
<text class="detail-label">鏄惁璐ㄦ</text>
@@ -161,6 +169,13 @@
return num.toFixed(2);
};
+ const calcAlreadyReturned = row => {
+ const total = Number(row?.stockInNum ?? row?.totalQuantity ?? row?.quantity ?? 0);
+ const un = Number(row?.unQuantity ?? 0);
+ if (!Number.isFinite(total) || !Number.isFinite(un)) return 0;
+ return Math.max(total - un, 0);
+ };
+
const loadDetail = () => {
if (!id.value) return;
uni.showLoading({ title: "鍔犺浇涓�...", mask: true });
--
Gitblit v1.9.3