feat: 积分商品新接口对接

This commit is contained in:
lzhizhao 2025-08-17 00:57:55 +08:00
parent 45ba73ebae
commit a171d541a3
5 changed files with 202 additions and 231 deletions

View File

@ -215,6 +215,15 @@ export const marketing = {
});
},
// 积分商品启用状态切换
reverseEnableMemberUnitPointsProduct: data => {
return $http.request({
url: `/merchant-api/memberUnitPointsProduct/reverseEnable`,
method: "post",
data
});
},
// 修改积分商品
updateMembershipPointsProduct: data => {
return $http.request({

View File

@ -51,6 +51,10 @@ export const mer_admin = {
data
);
},
//商品规格分页
getProductSpecificationPage: data => {
return $http.post(`/merchant-api/product/specification/page`, data);
},
//商品概况
getProductOverview: data => {
return $http.post(`/merchant-api/product/overview`, data);

View File

@ -172,6 +172,21 @@ export default {
: [];
this.$refs.productSelector.show(shopIdList);
},
handleEnableChange(row) {
//
this.$api.marketing
.reverseEnableMemberUnitPointsProduct({ id: row.id })
.then(() => {
this.$message.success("状态切换成功");
this.$refs.oTable.reload();
})
.catch(err => {
console.error("状态切换失败:", err);
this.$message.error("状态切换失败");
//
row.enable = !row.enable;
});
},
reset() {
this.formInline = {
unitType:
@ -258,7 +273,16 @@ export default {
{
title: "启用状态",
align: "center",
field: "enable"
field: "enable",
type: "jsx",
render: ({ row }) => {
return (
<el-switch
v-model={row.enable}
onChange={() => this.handleEnableChange(row)}
></el-switch>
);
}
},
{
title: "操作",
@ -273,7 +297,11 @@ export default {
productId: row.productId,
productName: row.productName,
shopName: row.shopName,
productSpecName: row.productSpecName
productSpecName: row.productSpecName,
productSpecId: row.productSpecId,
attributeValue: row.productSpecName,
marketPrice: row.marketPrice,
surplusInventory: row.surplusInventory
};
// 使
@ -282,6 +310,8 @@ export default {
shopId: row.shopId,
productId: row.productId,
productSpecId: row.productSpecId,
attributeValue: row.productSpecName,
marketPrice: row.marketPrice,
exchangeRequiredPoints: row.exchangeRequiredPoints,
exchangeInventory: row.exchangeInventory,
exchangeRestrictions: row.exchangeRestrictions,

View File

@ -12,39 +12,31 @@
<div class="product-info">
<div class="info-item">
<span class="label">商品ID</span>
<span class="value">{{
isEdit ? editProductData.productId : productData.id
}}</span>
<span class="value">{{ productData.productId }}</span>
</div>
<div class="info-item">
<span class="label">商品名称</span>
<span class="value">{{
isEdit ? editProductData.productName : productData.name
}}</span>
<span class="value">{{ productData.productName }}</span>
</div>
<div class="info-item">
<span class="label">归属摊位</span>
<span class="value">{{
isEdit ? editProductData.shopName : productData.shopId
}}</span>
<span class="value">{{ productData.shopName }}</span>
</div>
<div class="info-item" v-if="!isEdit && productData.description">
<span class="label">商品描述</span>
<span class="value">{{ productData.description }}</span>
<div class="info-item">
<span class="label">规格名称</span>
<span class="value">{{ productData.attributeValue }}</span>
</div>
<div class="info-item" v-if="!isEdit">
<span class="label">价格范围</span>
<span class="value"
>¥{{ productData.minSalePrice }} - ¥{{
productData.maxSalePrice
}}</span
>
<div class="info-item">
<span class="label">SKU-ID</span>
<span class="value">{{ productData.productSpecId }}</span>
</div>
<div class="info-item">
<span class="label">商品原价</span>
<span class="value">¥{{ productData.marketPrice }}</span>
</div>
<div class="info-item" v-if="isEdit">
<span class="label">商品规格</span>
<span class="value">{{
editProductData.productSpecName || "默认规格"
}}</span>
<span class="label">当前剩余库存</span>
<span class="value">{{ productData.surplusInventory }}</span>
</div>
</div>
</div>
@ -53,38 +45,45 @@
<el-form
ref="configForm"
:model="configForm"
:rules="dynamicRules"
:rules="configRules"
label-width="140px"
style="margin-top: 20px"
>
<!-- 商品规格选择 -->
<el-form-item
label="商品规格"
prop="productSpecId"
:label="isEdit ? '添加库存(负数代表减少库存)' : '库存设置'"
prop="exchangeInventory"
required
v-if="!isEdit && productSpecificationList.length > 0"
>
<el-select
v-model="configForm.productSpecId"
placeholder="请选择商品规格"
style="width: 100%"
@change="handleSpecChange"
>
<el-option
v-for="spec in productSpecificationList"
:key="spec.id"
:label="`${spec.attributeValue} - ¥${spec.salePrice}`"
:value="spec.id"
<div class="inventory-input">
<el-button
@click="decreaseInventory"
:disabled="!isEdit && configForm.exchangeInventory <= 1"
>-</el-button
>
<span style="float: left">{{ spec.attributeValue }}</span>
<span style="float: right; color: #8492a6; font-size: 13px"
>¥{{ spec.salePrice }}</span
>
</el-option>
</el-select>
<el-input-number
v-model="configForm.exchangeInventory"
:min="isEdit ? -99999 : 1"
:max="99999"
controls-position="right"
style="width: 200px; margin: 0 10px"
></el-input-number>
<el-button @click="increaseInventory">+</el-button>
</div>
</el-form-item>
<el-form-item label="兑换所需积分" prop="exchangeRequiredPoints" required>
<el-form-item label="积分类型" prop="exchangePointsType" required>
<el-radio-group v-model="configForm.exchangePointsType">
<el-radio :label="2">积分优惠购</el-radio>
<el-radio :label="1">积分换购</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
v-if="configForm.exchangePointsType === 1"
label="兑换所需积分设置"
prop="exchangeRequiredPoints"
required
>
<div class="points-input">
<el-button
@click="decreasePoints"
@ -102,55 +101,40 @@
</div>
</el-form-item>
<el-form-item label="兑换库存" prop="exchangeInventory" required>
<div class="inventory-input">
<el-form-item
v-if="configForm.exchangePointsType === 2"
label="优惠购所需积分"
prop="exchangeRequiredPoints"
required
>
<div class="points-input">
<el-button
@click="decreaseInventory"
:disabled="configForm.exchangeInventory <= 1"
@click="decreasePoints"
:disabled="configForm.exchangeRequiredPoints <= 1"
>-</el-button
>
<el-input-number
v-model="configForm.exchangeInventory"
v-model="configForm.exchangeRequiredPoints"
:min="1"
:max="99999"
controls-position="right"
style="width: 200px; margin: 0 10px"
></el-input-number>
<el-button @click="increaseInventory">+</el-button>
</div>
</el-form-item>
<el-form-item label="兑换限制" prop="exchangeRestrictions" required>
<div class="limit-input">
<el-button
@click="decreaseLimitQuantity"
:disabled="configForm.exchangeRestrictions <= 0"
>-</el-button
>
<el-input-number
v-model="configForm.exchangeRestrictions"
:min="0"
:max="99999"
controls-position="right"
style="width: 200px; margin: 0 10px"
></el-input-number>
<el-button @click="increaseLimitQuantity">+</el-button>
<el-button @click="increasePoints">+</el-button>
</div>
</el-form-item>
<el-form-item
label="兑换限制类型"
prop="exchangeRestrictionsType"
v-if="configForm.exchangePointsType === 2"
label="优惠购商品价格"
prop="exchangeRequiredAmount"
required
>
<el-select
v-model="configForm.exchangeRestrictionsType"
placeholder="请选择限制类型"
<el-input
v-model="configForm.exchangeRequiredAmount"
placeholder="请输入优惠购价格"
style="width: 200px"
>
<el-option label="每日" :value="1"></el-option>
<el-option label="永久" :value="2"></el-option>
</el-select>
></el-input>
</el-form-item>
</el-form>
@ -172,8 +156,6 @@ export default {
isEdit: false,
submitting: false,
productData: {},
editProductData: {}, //
productSpecificationList: [],
configForm: {
id: undefined,
shopId: undefined,
@ -181,98 +163,66 @@ export default {
productSpecId: undefined,
exchangeRequiredPoints: 1,
exchangeInventory: 10,
exchangeRestrictions: 0,
exchangeRestrictionsType: 1
exchangePointsType: 1, // 1: , 2:
exchangeRequiredAmount: ""
},
configRules: {
exchangeRequiredPoints: [
{ required: true, message: "请设置兑换所需积分", trigger: "blur" }
{ required: true, message: "请设置所需积分", trigger: "blur" }
],
exchangeInventory: [
{ required: true, message: "请设置兑换库存", trigger: "blur" }
{ required: true, message: "请设置库存", trigger: "blur" }
],
exchangeRestrictions: [
{ required: true, message: "请设置兑换限制", trigger: "blur" }
exchangePointsType: [
{ required: true, message: "请选择积分类型", trigger: "change" }
],
exchangeRestrictionsType: [
{ required: true, message: "请选择兑换限制类型", trigger: "change" }
exchangeRequiredAmount: [
{
required: true,
message: "请输入优惠购价格",
trigger: "blur",
validator: (rule, value, callback) => {
if (this.configForm.exchangePointsType === 2 && !value) {
callback(new Error("请输入优惠购价格"));
} else {
callback();
}
}
}
]
}
};
},
computed: {
//
dynamicRules() {
const rules = {
exchangeRequiredPoints: [
{ required: true, message: "请设置兑换所需积分", trigger: "blur" }
],
exchangeInventory: [
{ required: true, message: "请设置兑换库存", trigger: "blur" }
],
exchangeRestrictions: [
{ required: true, message: "请设置兑换限制", trigger: "blur" }
],
exchangeRestrictionsType: [
{ required: true, message: "请选择兑换限制类型", trigger: "change" }
]
};
//
if (!this.isEdit && this.productSpecificationList.length > 1) {
rules.productSpecId = [
{ required: true, message: "请选择商品规格", trigger: "change" }
];
}
return rules;
}
},
methods: {
show(productData, editData = null) {
show(productData, editData = null, exchangeType = 1) {
this.visible = true;
this.isEdit = !!editData;
this.productData = productData;
//
this.productSpecificationList =
productData.productSpecificationList || [];
if (editData) {
//
this.editProductData = {
productId: productData.productId,
productName: productData.productName,
shopName: productData.shopName,
productSpecName: productData.productSpecName
};
this.configForm = {
id: editData.id || undefined,
shopId: editData.shopId || undefined,
productId: editData.productId || undefined,
productSpecId: editData.productSpecId || undefined,
exchangeRequiredPoints: editData.exchangeRequiredPoints || 1,
exchangeInventory: editData.exchangeInventory || 10,
exchangeRestrictions: editData.exchangeRestrictions || 0,
exchangeRestrictionsType: editData.exchangeRestrictionsType || 1
exchangeInventory: 0, // 0
exchangePointsType: editData.exchangePointsType || 1,
exchangeRequiredAmount: editData.exchangeRequiredAmount || ""
};
} else {
// 使
const defaultSpecId =
this.productSpecificationList.length === 1
? this.productSpecificationList[0].id
: undefined;
this.configForm = {
id: undefined,
shopId: productData.shopId || undefined,
productId: productData.id || undefined,
productSpecId: defaultSpecId,
productId: productData.productId || undefined,
productSpecId: productData.id || undefined, // 使ID
exchangeRequiredPoints: 1,
exchangeInventory: 10,
exchangeRestrictions: 0,
exchangeRestrictionsType: 1
exchangePointsType: exchangeType, // 使
exchangeRequiredAmount: ""
};
}
},
@ -282,8 +232,6 @@ export default {
},
resetForm() {
this.productData = {};
this.editProductData = {};
this.productSpecificationList = [];
this.configForm = {
id: undefined,
shopId: undefined,
@ -291,8 +239,8 @@ export default {
productSpecId: undefined,
exchangeRequiredPoints: 1,
exchangeInventory: 10,
exchangeRestrictions: 0,
exchangeRestrictionsType: 1
exchangePointsType: 1,
exchangeRequiredAmount: ""
};
this.isEdit = false;
this.$refs.configForm && this.$refs.configForm.clearValidate();
@ -302,9 +250,23 @@ export default {
if (valid) {
this.submitting = true;
const submitData = {
...this.configForm
};
let submitData;
if (this.isEdit) {
// 使
submitData = {
id: this.configForm.id,
exchangeRequiredPoints: this.configForm.exchangeRequiredPoints,
increaseInventory: this.configForm.exchangeInventory, //
exchangeRequiredAmount:
this.configForm.exchangeRequiredAmount || 0,
enable: true //
};
} else {
// 使
submitData = {
...this.configForm
};
}
console.log(submitData);
// API
@ -336,7 +298,9 @@ export default {
this.configForm.exchangeRequiredPoints++;
},
decreaseInventory() {
if (this.configForm.exchangeInventory > 1) {
if (this.isEdit) {
this.configForm.exchangeInventory--;
} else if (this.configForm.exchangeInventory > 1) {
this.configForm.exchangeInventory--;
}
},
@ -350,18 +314,6 @@ export default {
},
increaseLimitQuantity() {
this.configForm.exchangeRestrictions++;
},
//
handleSpecChange(specId) {
const selectedSpec = this.productSpecificationList.find(
spec => spec.id === specId
);
if (selectedSpec) {
//
console.log("选中的规格:", selectedSpec);
//
// this.configForm.exchangeInventory = Math.min(selectedSpec.stockNum, 10);
}
}
}
};

View File

@ -9,16 +9,12 @@
<!-- 查询条件 -->
<div class="search-form">
<el-form :inline="true" :model="searchForm" class="demo-form-inline">
<el-form-item label="店铺" v-if="storeList.length">
<el-select v-model="searchForm.shopId" placeholder="请选择店铺">
<el-option
v-for="item in storeList"
:key="item.shopId"
:label="item.shopName"
:value="item.shopId"
>
</el-option>
</el-select>
<el-form-item label="店铺名称">
<el-input
v-model="searchForm.shopName"
placeholder="请输入店铺名称搜索"
clearable
></el-input>
</el-form-item>
<el-form-item label="商品名称">
<el-input
@ -49,47 +45,31 @@
style="width: 100%"
v-loading="loading"
>
<el-table-column prop="shopId" label="商品店铺" align="center">
<el-table-column prop="productId" label="商品ID" align="center">
</el-table-column>
<el-table-column prop="name" label="商品名称" align="center">
<el-table-column prop="shopName" label="商品店铺" align="center">
</el-table-column>
<el-table-column prop="id" label="商品ID" align="center">
<el-table-column prop="attributeValue" label="商品规格" align="center">
</el-table-column>
<el-table-column prop="salePrice" label="商品价格" align="center">
<template slot-scope="scope"> ¥{{ scope.row.salePrice }} </template>
<el-table-column prop="marketPrice" label="商品价格" align="center">
<template slot-scope="scope"> ¥{{ scope.row.marketPrice }} </template>
</el-table-column>
<el-table-column label="规格" align="center" width="120">
<template slot-scope="scope">
<span
v-if="
scope.row.productSpecificationList &&
scope.row.productSpecificationList.length <= 1
"
>
{{
scope.row.productSpecificationList[0]?.attributeValue ||
"默认规格"
}}
</span>
<span
v-else-if="
scope.row.productSpecificationList &&
scope.row.productSpecificationList.length > 1
"
>
多规格
</span>
<span v-else>默认规格</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="150">
<el-table-column label="操作" align="center" width="350">
<template slot-scope="scope">
<el-button
type="primary"
size="small"
@click="addToPointsMall(scope.row)"
@click="addToPointsMall(scope.row, 1)"
style="margin-right: 10px"
>
添加为积分商品
添加为积分换购商品
</el-button>
<el-button
type="success"
size="small"
@click="addToPointsMall(scope.row, 2)"
>
添加为积分优惠购商品
</el-button>
</template>
</el-table-column>
@ -140,7 +120,7 @@ export default {
visible: false,
loading: false,
searchForm: {
shopId: "",
shopName: "",
productName: "",
productId: ""
},
@ -155,12 +135,6 @@ export default {
methods: {
show(shopIdList) {
this.visible = true;
// 使
if (Array.isArray(shopIdList) && shopIdList.length > 0) {
this.searchForm.shopId = shopIdList[0];
} else if (shopIdList) {
this.searchForm.shopId = shopIdList;
}
this.loadProducts();
},
handleClose() {
@ -169,7 +143,7 @@ export default {
},
resetData() {
this.searchForm = {
shopId: "",
shopName: "",
productName: "",
productId: ""
};
@ -185,38 +159,33 @@ export default {
this.loadProducts();
},
resetSearch() {
this.searchForm.shopName = "";
this.searchForm.productName = "";
this.searchForm.productId = "";
this.searchProducts();
},
loadProducts() {
this.loading = true;
// API
//
this.$api.mer_admin
.getProductPage({
p: {
pageNumber: this.pagination.currentPage,
pageSize: this.pagination.pageSize
},
shopId: this.searchForm.shopId,
productName: this.searchForm.productName,
productId: this.searchForm.productId,
productFilterType: "SALE",
merchantId: JSON.parse(sessionStorage.getItem("userInfo")).merchantId,
productQuerySortParam: []
.getProductSpecificationPage({
shopIdList: [], //
shopName: this.searchForm.shopName || "",
productName: this.searchForm.productName || "",
productId: this.searchForm.productId || ""
})
.then(res => {
console.log("商品列表:", res);
console.log("商品规格列表:", res);
this.productList = res.data.data.data || [];
this.pagination.total = Number(res.data.data.total || 0);
this.pagination.total = this.productList.length; // 使
this.loading = false;
})
.catch(err => {
console.error("获取商品列表失败:", err);
console.error("获取商品规格列表失败:", err);
this.productList = [];
this.pagination.total = 0;
this.loading = false;
this.$message.error("获取商品列表失败");
this.$message.error("获取商品规格列表失败");
});
},
handleSizeChange(val) {
@ -227,9 +196,16 @@ export default {
this.pagination.currentPage = val;
this.loadProducts();
},
addToPointsMall(product) {
//
this.$refs.pointsProductConfig.show(product);
addToPointsMall(product, exchangeType) {
//
this.$refs.pointsProductConfig.show(
{
...product,
productSpecId: product.id
},
null,
exchangeType
);
},
handleConfigSuccess() {
this.$emit("success");