From c0d6fe2638379e6fb23f1af5eff27355cb565e9d Mon Sep 17 00:00:00 2001
From: ZN <zhang_12370@163.com>
Date: 星期六, 28 三月 2026 15:34:06 +0800
Subject: [PATCH] feat(采购管理): 优化高级价格管理与采购台账功能
---
src/views/procurementManagement/procurementLedger/index.vue | 208 +++++++++++++++++++++++++++++++++--------
src/views/procurementManagement/advancedPriceManagement/index.vue | 44 +++-----
2 files changed, 187 insertions(+), 65 deletions(-)
diff --git a/src/views/procurementManagement/advancedPriceManagement/index.vue b/src/views/procurementManagement/advancedPriceManagement/index.vue
index 5af8311..d66c2c8 100644
--- a/src/views/procurementManagement/advancedPriceManagement/index.vue
+++ b/src/views/procurementManagement/advancedPriceManagement/index.vue
@@ -31,10 +31,10 @@
<el-icon><Plus /></el-icon>
鏂板浠锋牸
</el-button>
- <el-button type="success" @click="openBatchDiscountDialog">
+ <!-- <el-button type="success" @click="openBatchDiscountDialog">
<el-icon><Discount /></el-icon>
鎵归噺鎶樻墸
- </el-button>
+ </el-button> -->
<el-button type="info" @click="exportData">
<el-icon><Download /></el-icon>
瀵煎嚭鏁版嵁
@@ -62,17 +62,16 @@
<div class="product-info">
<div class="product-name">{{ row.productName }}</div>
<div class="product-spec">{{ row.specification }}</div>
- <!-- <div class="product-code">缂栫爜: {{ row.productCode }}</div> -->
</div>
</template>
</el-table-column>
<el-table-column label="渚涘簲鍟�" prop="supplierName" width="200" />
- <el-table-column label="鍩虹浠锋牸" width="120" align="right">
+ <el-table-column label="鍩虹浠锋牸(涓嶅惈绋�)" width="150" align="right">
<template #default="{ row }">
<span class="price-text">楼{{ row.basePrice }}</span>
</template>
</el-table-column>
- <el-table-column label="鎶樻墸淇℃伅" width="150">
+ <el-table-column label="鎶樻墸淇℃伅" width="120" align="center">
<template #default="{ row }">
<div v-if="row.discountType">
<el-tag :type="getDiscountTagType(row.discountType)" size="small">
@@ -83,9 +82,12 @@
<span v-else class="no-discount">鏃犳姌鎵�</span>
</template>
</el-table-column>
- <el-table-column label="瀹為檯浠锋牸" width="120" align="right">
+ <!-- <el-table-column label="瀹為檯浠锋牸(涓嶅惈绋�)" prop="actuallyPrice" width="150" align="right"> -->
+ <!-- </el-table-column> -->
+ <el-table-column label="瀹為檯浠锋牸(涓嶅惈绋�)" width="150" align="right">
<template #default="{ row }">
- <span class="final-price">楼{{ calculateFinalPrice(row) }}</span>
+ <!-- <span class="final-price">楼{{ calculateFinalPrice(row) }}</span> -->
+ <span class="final-price" >楼{{ row.actuallyPrice?row.actuallyPrice:row.basePrice }}</span>
</template>
</el-table-column>
<el-table-column label="浠锋牸鎺у埗" width="120">
@@ -108,8 +110,9 @@
</div> -->
</template>
</el-table-column>
- <el-table-column label="鐢熸晥鏃堕棿" prop="effectiveTime" width="180" />
- <el-table-column label="鏇存柊鏃堕棿" prop="updateTime" width="180" sortable />
+ <el-table-column label="鐢熸晥鏃堕棿" prop="effectiveTime" width="100" align="center" />
+ <el-table-column label="鏇存柊鏃堕棿" prop="updateTime" width="160" sortable align="center" />
+ <el-table-column label="澶囨敞" width="200" prop="remark" align="center" show-overflow-tooltip />
<el-table-column label="鎿嶄綔" width="250" align="center" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="openDialog('edit', row)">
@@ -160,13 +163,6 @@
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item label="鍟嗗搧缂栫爜" prop="productCode">
- <el-input v-model="formData.productCode" placeholder="璇疯緭鍏ュ晢鍝佺紪鐮�" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
<el-form-item label="瑙勬牸鍨嬪彿" prop="specification">
<el-select
v-model="formData.specification"
@@ -183,6 +179,8 @@
</el-select>
</el-form-item>
</el-col>
+ </el-row>
+ <el-row :gutter="20">
<el-col :span="12">
<el-form-item label="渚涘簲鍟�" prop="supplierId">
<el-select
@@ -200,13 +198,13 @@
</el-select>
</el-form-item>
</el-col>
- </el-row>
- <el-row :gutter="20">
<el-col :span="12">
<el-form-item label="鍩虹浠锋牸" prop="basePrice">
<el-input-number v-model="formData.basePrice" :min="0" :precision="2" placeholder="璇疯緭鍏ュ熀纭�浠锋牸" style="width: 100%" />
</el-form-item>
</el-col>
+ </el-row>
+ <el-row :gutter="20">
<el-col :span="12">
<el-form-item label="鍗曚綅">
<el-input v-model="formData.unit" placeholder="璇疯緭鍏ュ崟浣�" />
@@ -402,7 +400,6 @@
const formData = reactive({
productId: null,
productName: '',
- productCode: '',
specification: '',
supplierId: null,
supplierName: '',
@@ -442,7 +439,6 @@
// 琛ㄥ崟楠岃瘉瑙勫垯
const formRules = {
productId: [{ required: true, message: '璇烽�夋嫨鍟嗗搧鍚嶇О', trigger: 'change' }],
- productCode: [{ required: true, message: '璇疯緭鍏ュ晢鍝佺紪鐮�', trigger: 'blur' }],
supplierId: [{ required: true, message: '璇烽�夋嫨渚涘簲鍟�', trigger: 'change' }],
basePrice: [{ required: true, message: '璇疯緭鍏ュ熀纭�浠锋牸', trigger: 'blur' }],
effectiveTime: [{ required: true, message: '璇烽�夋嫨鐢熸晥鏃堕棿', trigger: 'change' }],
@@ -508,14 +504,13 @@
const selectedProduct = findNodeById(productOptions.value, value);
if (selectedProduct) {
formData.productName = selectedProduct.productName;
- formData.productCode = selectedProduct.productCode;
}
modelList({ id: value }).then((res) => {
modelOptions.value = res;
});
+ formData.specification = "";
} else {
formData.productName = "";
- formData.productCode = "";
modelOptions.value = [];
}
};
@@ -601,7 +596,6 @@
Object.assign(formData, {
productId: null,
productName: '',
- productCode: '',
specification: '',
supplierId: null,
supplierName: '',
@@ -631,11 +625,11 @@
const handleSubmit = async () => {
if (!formRef.value) return
- formData.actualPrice = calculateFinalPrice(formData)
+ formData.actuallyPrice = Number(calculateFinalPrice(formData))
if( formData.discountType === ''){
formData.discountEndTime = '2099-12-31 23:59:59'
}
-
+
try {
await formRef.value.validate()
submitLoading.value = true
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index 400f061..b8fd556 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -250,6 +250,7 @@
v-model="form.supplierId"
placeholder="璇烽�夋嫨"
clearable
+ @change="handleSupplierChange"
>
<el-option
v-for="item in supplierList"
@@ -647,39 +648,60 @@
<!-- 鍘嗗彶閲囪喘浠锋牸鍙傝�冨脊绐� -->
<el-dialog
v-model="priceReferenceVisible"
- title="鍘嗗彶閲囪喘浠锋牸鍙傝��"
+ :title="`鍘嗗彶閲囪喘浠锋牸鍙傝�� ${productForm.supplierName}-${productForm.productName}-${productForm.productModel}`"
width="1000px"
append-to-body
>
<el-table
- v-loading="priceReferenceLoading"
:data="priceReferenceData"
border
- style="width: 100%"
+ v-loading="priceReferenceLoading"
+ :default-sort="{ prop: 'updateTime', order: 'descending' }"
>
- <el-table-column label="鍟嗗搧鍚嶇О" prop="productName" min-width="150" show-overflow-tooltip />
- <el-table-column label="瑙勬牸鍨嬪彿" prop="specification" width="150" show-overflow-tooltip />
- <el-table-column label="渚涘簲鍟�" prop="supplierName" width="200" show-overflow-tooltip />
- <el-table-column label="鍩虹浠锋牸" width="120" align="right">
+ <!-- <el-table-column label="鍟嗗搧淇℃伅" min-width="200">
<template #default="{ row }">
- <span style="color: #f56c6c; font-weight: bold;">楼{{ row.basePrice }}</span>
+ <div class="product-info">
+ <div class="product-name">{{ row.productName }}</div>
+ <div class="product-spec">{{ row.specification }}</div>
+ <div class="product-code">缂栫爜: {{ row.productCode }}</div>
+ </div>
+ </template>
+ </el-table-column> -->
+ <!-- <el-table-column label="渚涘簲鍟�" prop="supplierName" width="200" /> -->
+ <el-table-column label="鍩虹浠锋牸(涓嶅惈绋�)" width="150" align="right">
+ <template #default="{ row }">
+ <span class="price-text">楼{{ row.basePrice }}</span>
</template>
</el-table-column>
+ <el-table-column label="瀹為檯浠锋牸(涓嶅惈绋�)" prop="actuallyPrice" width="150" align="right"/>
<el-table-column label="鎶樻墸淇℃伅" width="120" align="center">
<template #default="{ row }">
- <el-tag v-if="row.discountType === 'percentage'" type="success">
- {{ row.discountValue }}%
- </el-tag>
- <el-tag v-else-if="row.discountType === 'fixed'" type="warning">
- -楼{{ row.discountValue }}
- </el-tag>
- <span v-else>鏃犳姌鎵�</span>
+ <div v-if="row.discountType">
+ <el-tag :type="getDiscountTagType(row.discountType)" size="small">
+ {{ getDiscountText(row.discountType) }}
+ </el-tag>
+ <div class="discount-value">{{ row.discountValue }}{{ row.discountType === 'percentage' ? '%' : '鍏�' }}</div>
+ </div>
+ <span v-else class="no-discount">鏃犳姌鎵�</span>
</template>
</el-table-column>
- <el-table-column label="鐢熸晥鏃堕棿" prop="effectiveTime" width="180" align="center" />
+ <el-table-column label="鐘舵��" width="100" align="center">
+ <template #default="{ row }">
+ <el-tag :type="getStatusType(row.status)">{{ getStatusText(row.status) }}</el-tag>
+ <!-- <div v-if="isPriceWarning(row)" class="warning-indicator">
+ <el-icon color="#F56C6C"><Warning /></el-icon>
+ </div> -->
+ </template>
+ </el-table-column>
+ <el-table-column label="鐢熸晥鏃堕棿" prop="effectiveTime" width="100" align="center" />
+ <el-table-column label="鏇存柊鏃堕棿" prop="updateTime" width="160" sortable align="center" />
+ <el-table-column label="澶囨敞" width="200" prop="remark" align="center" show-overflow-tooltip />
<el-table-column label="鎿嶄綔" width="100" align="center" fixed="right">
<template #default="{ row }">
- <el-button type="primary" link @click="selectPriceReference(row)">閫夋嫨</el-button>
+ <el-button type="success" link @click="selectPriceReference(row)">
+ <el-icon><Check /></el-icon>
+ 寮曠敤
+ </el-button>
</template>
</el-table-column>
</el-table>
@@ -921,7 +943,7 @@
import { getToken } from "@/utils/auth";
import pagination from "@/components/PIMTable/Pagination.vue";
import { ref, onMounted, reactive, toRefs, getCurrentInstance, nextTick } from "vue";
-import { Search } from "@element-plus/icons-vue";
+import { Search, Check } from "@element-plus/icons-vue";
import { ElMessageBox } from "element-plus";
import { userListNoPage } from "@/api/system/user.js";
import {
@@ -1037,6 +1059,9 @@
taxExclusiveTotalPrice: "",
invoiceType: "",
warnNum: "",
+ supplierName: "",
+ productName: "",
+ productModel: "",
},
productRules: {
productId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
@@ -1069,7 +1094,59 @@
size: 10
});
+const calculateFinalPrice = (row) => {
+ let finalPrice = row.basePrice;
+ if (row.discountType === "percentage") {
+ finalPrice = row.basePrice * (1 - row.discountValue / 100);
+ } else if (row.discountType === "fixed") {
+ finalPrice = row.basePrice - row.discountValue;
+ }
+ let man = Math.max(finalPrice, 0);
+ return man.toFixed(2);
+};
+
+const getDiscountTagType = (discountType) => {
+ const typeMap = {
+ percentage: "success",
+ fixed: "warning",
+ tiered: "info",
+ };
+ return typeMap[discountType] || "info";
+};
+
+const getDiscountText = (discountType) => {
+ const textMap = {
+ percentage: "鐧惧垎姣�",
+ fixed: "鍥哄畾閲戦",
+ };
+ return textMap[discountType] || "鏈煡";
+};
+
+const getStatusType = (status) => {
+ const statusMap = {
+ active: "success",
+ pending: "warning",
+ expired: "info",
+ };
+ return statusMap[status] || "info";
+};
+
+const getStatusText = (status) => {
+ const statusMap = {
+ active: "鏈夋晥",
+ pending: "寰呯敓鏁�",
+ expired: "宸茶繃鏈�",
+ };
+ return statusMap[status] || "鏈煡";
+};
+
const showPriceReference = () => {
+ if (form.value.supplierId) {
+ const supplier = supplierList.value.find((item) => item.id === form.value.supplierId);
+ if (supplier) {
+ productForm.value.supplierName = supplier.supplierName;
+ }
+ }
priceReferenceVisible.value = true;
handlePriceReferenceSearch();
};
@@ -1080,11 +1157,12 @@
// 鍋囪楂樼骇浠锋牸绠$悊鐨� listPage 鎺ユ敹 productId
const query = {
productId: productForm.value.productId,
- specificationId: productForm.value.productModelId,
+ supplierId: form.value.supplierId,
current: priceReferencePagination.current,
size: priceReferencePagination.size
};
listAdvancedPrice(query).then(res => {
+ console.log(res);
priceReferenceData.value = res.data.records;
priceReferenceTotal.value = res.data.total;
priceReferenceLoading.value = false;
@@ -1104,25 +1182,39 @@
};
const selectPriceReference = (row) => {
- // 璁$畻瀹為檯浠锋牸锛氬熀纭�浠锋牸 - 鎶樻墸
- let actualPrice = row.basePrice;
- if (row.discountType === 'percentage') {
- actualPrice = row.basePrice * (1 - row.discountValue / 100);
- } else if (row.discountType === 'fixed') {
- actualPrice = row.basePrice - row.discountValue;
- }
-
- // 濉厖鍚◣鍗曚环锛屼繚鐣欎袱浣嶅皬鏁�
- productForm.value.taxInclusiveUnitPrice = Number(Math.max(actualPrice, 0)).toFixed(2);
-
- // 濡傛灉宸茬粡杈撳叆浜嗘暟閲忥紝鍒欒嚜鍔ㄨ绠楁�讳环
- if (productForm.value.quantity) {
- mathNum();
- }
-
- priceReferenceVisible.value = false;
- proxy.$modal.msgSuccess("宸插紩鐢ㄥ巻鍙蹭环鏍�");
- };
+ // 璁$畻鍘嗗彶浠锋牸锛堜綔涓轰笉鍚◣鍗曚环锛夛細鍩虹浠锋牸 - 鎶樻墸
+ let taxExclusivePrice = row.basePrice;
+ if (row.discountType === "percentage") {
+ taxExclusivePrice = row.basePrice * (1 - row.discountValue / 100);
+ } else if (row.discountType === "fixed") {
+ taxExclusivePrice = row.basePrice - row.discountValue;
+ }
+ taxExclusivePrice = Number(Math.max(taxExclusivePrice, 0));
+
+ // 璁剧疆鏁伴噺涓� 1
+ if (!productForm.value.quantity) {
+ productForm.value.quantity = 1;
+ }
+
+ // 濡傛灉宸叉湁绋庣巼锛屽垯璁$畻鍚◣鍗曚环
+ if (productForm.value.taxRate) {
+ const taxRate = Number(productForm.value.taxRate);
+ productForm.value.taxInclusiveUnitPrice = (
+ taxExclusivePrice *
+ (1 + taxRate / 100)
+ ).toFixed(2);
+ } else {
+ // 濡傛灉娌℃湁绋庣巼锛屾殏鏃跺皢鍚◣鍗曚环璁句负涓嶅惈绋庝环鏍硷紝鎻愮ず鐢ㄦ埛閫夋嫨绋庣巼
+ productForm.value.taxInclusiveUnitPrice = taxExclusivePrice.toFixed(2);
+ proxy.$modal.msgWarning("璇烽�夋嫨绋庣巼浠ュ噯纭绠楀惈绋庝环鏍�");
+ }
+
+ // 鑷姩瑙﹀彂璁$畻閫昏緫锛堣绠楁�讳环绛夛級
+ mathNum();
+
+ priceReferenceVisible.value = false;
+ proxy.$modal.msgSuccess("宸插紩鐢ㄥ巻鍙蹭环鏍硷紙涓嶅惈绋庯級");
+};
const upload = reactive({
// 涓婁紶鐨勫湴鍧�
@@ -1364,11 +1456,32 @@
}
productOperationType.value = type;
productOperationIndex.value = index;
- productForm.value = {};
+ productForm.value = {
+ supplierName: "",
+ productName: "",
+ productModel: "",
+ };
proxy.resetForm("productFormRef");
if (type === "edit") {
- productForm.value = { ...row };
+ productForm.value = {
+ ...row,
+ productName: row.productCategory || "",
+ productModel: row.specificationModel || ""
+ };
+ // 缂栬緫鏃讹紝鏍规嵁 productId 棰勫姞杞借鏍煎瀷鍙峰垪琛紝纭繚涓嬫媺妗嗘樉绀哄悕绉拌�岄潪 ID
+ if (productForm.value.productId) {
+ modelList({ id: productForm.value.productId }).then((res) => {
+ modelOptions.value = res;
+ });
+ }
}
+
+ // 纭繚渚涘簲鍟嗗悕绉板缁堝悓姝�
+ const supplier = supplierList.value.find((item) => item.id === form.value.supplierId);
+ if (supplier) {
+ productForm.value.supplierName = supplier.supplierName;
+ }
+
productFormVisible.value = true;
getProductOptions();
};
@@ -1380,11 +1493,14 @@
const getModels = (value) => {
if (value) {
productForm.value.productCategory = findNodeById(productOptions.value, value) || "";
+ productForm.value.productName = productForm.value.productCategory;
+ productForm.value.productModelId = "";
modelList({ id: value }).then((res) => {
modelOptions.value = res;
});
} else {
productForm.value.productCategory = "";
+ productForm.value.productName = "";
modelOptions.value = [];
}
};
@@ -1392,12 +1508,24 @@
const index = modelOptions.value.findIndex((item) => item.id === value);
if (index !== -1) {
productForm.value.specificationModel = modelOptions.value[index].model;
+ productForm.value.productModel = modelOptions.value[index].model;
productForm.value.unit = modelOptions.value[index].unit;
} else {
productForm.value.specificationModel = null;
+ productForm.value.productModel = null;
productForm.value.unit = null;
}
};
+const handleSupplierChange = (value) => {
+ const supplier = supplierList.value.find((item) => item.id === value);
+ if (supplier) {
+ form.value.supplierName = supplier.supplierName;
+ productForm.value.supplierName = supplier.supplierName;
+ } else {
+ form.value.supplierName = "";
+ productForm.value.supplierName = "";
+ }
+};
const findNodeById = (nodes, productId) => {
for (let i = 0; i < nodes.length; i++) {
if (nodes[i].value === productId) {
--
Gitblit v1.9.3