fix: 代客下单优惠券显示调整

This commit is contained in:
2025-10-10 15:24:34 +08:00
parent 89a23613b0
commit d6cc5a00cc
5 changed files with 207 additions and 122 deletions

View File

@@ -7,14 +7,14 @@ VITE_APP_BASE_API=/dev-api
# 接口地址
# VITE_APP_API_URL=https://tapi.cashier.sxczgkj.cn/ # 测试
VITE_APP_API_URL=https://cashier.sxczgkj.com/ # 正式
# VITE_APP_API_URL=http://192.168.1.42/ # 本地
# VITE_APP_API_URL=https://cashier.sxczgkj.com/ # 正式
VITE_APP_API_URL=http://192.168.1.42/ # 本地
# WebSocket 端点(不配置则关闭),线上 ws://api.youlai.tech/ws ,本地 ws://localhost:8989/ws
# VITE_APP_WS_ENDPOINT=wss://sockets.sxczgkj.com/wss
VITE_APP_WS_ENDPOINT=wss://czgeatws.sxczgkj.com/wss # 正式
# VITE_APP_WS_ENDPOINT=ws://192.168.1.42:2348 # 本地
# VITE_APP_WS_ENDPOINT=wss://czgeatws.sxczgkj.com/wss # 正式
VITE_APP_WS_ENDPOINT=ws://192.168.1.42:2348 # 本地
# 启用 Mock 服务

View File

@@ -31,6 +31,7 @@ interface PointDeductionRule {
maxDeductionAmount: number;
}
export const useCartsStore = defineStore("carts", () => {
// ------------------------------ 1. 移到内部的工具函数(核心修复) ------------------------------
// 适配工具库 BaseCartItem 接口的商品数据转换函数(原外部函数,现在内部)

View File

@@ -77,7 +77,6 @@ export function returnCanDikouGoodsArr(canDikouGoodsArr, selCoupon, user) {
prev.push(...goodsWithType);
return prev;
}, []);
const arr = _.cloneDeep(canDikouGoodsArr)
.map((v) => {
const findCart = goodsCouponGoods.find((carts) => carts.id == v.id);
@@ -116,19 +115,17 @@ export function returnCanDikouGoodsArr(canDikouGoodsArr, selCoupon, user) {
*/
export function returnCouponCanUse(args) {
let { canDikouGoodsArr, coupon, goodsOrderPrice, user, selCoupon, shopInfo } = args;
// 优惠券未启用
if (!coupon.use) {
return {
canUse: false,
reason: "优惠券未启用",
reason: coupon.noUseRestrictions || "不在可用时间段内",
};
}
// 计算门槛金额
let fullAmount = goodsOrderPrice;
canDikouGoodsArr = returnCanDikouGoodsArr(canDikouGoodsArr, selCoupon, user, shopInfo);
//优惠券指定门槛商品列表
let canCalcGoodsArr = [...canDikouGoodsArr];
//部分商品参与门槛计算
@@ -187,7 +184,13 @@ export function returnCouponCanUse(args) {
// 商品兑换券,第二件半价和买一送一判断是否有可用商品
if ([2, 4, 5].includes(coupon.type)) {
// 没有符合条件的商品
if (!isDikouAll && canCalcGoodsArr.length === 0) {
if (isDikouAll && canDikouGoodsArr.length === 0) {
return {
canUse: false,
reason: "没有符合条件的商品",
};
}
if (!isDikouAll && canUseGoodsArr.length === 0) {
return {
canUse: false,
reason: "没有符合条件的商品",
@@ -289,7 +292,8 @@ export function returnCouponDiscount(arr, coupon, user, goodsOrderPrice, selCoup
return returnCouponProductDiscount(canDikouGoodsArr, coupon, user, shopInfo);
}
if (coupon.type == 6) {
return returnCouponBuyOneGiveOneDiscount(canDikouGoodsArr, coupon, user, shopInfo);
const result = returnCouponBuyOneGiveOneDiscount(canDikouGoodsArr, coupon, user, shopInfo);
return result;
}
if (coupon.type == 4) {
return returnSecoendDiscount(canDikouGoodsArr, coupon, user, shopInfo);
@@ -403,7 +407,7 @@ function returnCouponBuyOneGiveOneDiscount(canDikouGoodsArr, coupon, user, shopI
if (useRule == "price_asc") {
discountGoods = canUseGoods[canUseGoods.length - 1];
} else {
discountGoods = canUseGoods.slice(0, 1);
discountGoods = canUseGoods[0];
}
} else {
//符合抵扣条件的商品
@@ -411,13 +415,18 @@ function returnCouponBuyOneGiveOneDiscount(canDikouGoodsArr, coupon, user, shopI
if (useRule == "price_asc") {
discountGoods = canUseGoods1[canUseGoods1.length - 1];
} else {
discountGoods = canUseGoods1.slice(0, 1);
discountGoods = canUseGoods1[0];
}
}
const discountPrice = returnGoodsPrice(discountGoods, user, shopInfo);
const hasDiscountGoodsArr = [discountGoods];
let discountPrice = 0;
let hasDiscountGoodsArr = [];
console.log("returnCouponBuyOneGiveOneDiscount:discountGoods", discountGoods);
if (discountGoods) {
discountPrice = returnGoodsPrice(discountGoods, user, shopInfo);
hasDiscountGoodsArr = [discountGoods];
}
return {
discountPrice,
discountPrice: discountPrice <= 0 ? 0 : discountPrice,
hasDiscountGoodsArr,
};
}
@@ -433,14 +442,14 @@ function returnSecoendDiscount(canDikouGoodsArr, coupon, user, shopInfo) {
const { useFoods, useRule } = coupon;
//抵扣商品
let discountGoods = undefined;
//符合买一送一条件的商品
//符合条件的商品
const canUseGoods = canDikouGoodsArr.filter((v) => v.num >= 2);
//抵扣全部商品
if (useFoods.length === 0) {
if (useRule == "price_asc") {
discountGoods = canUseGoods[canUseGoods.length - 1];
} else {
discountGoods = canUseGoods.slice(0, 1);
discountGoods = canUseGoods[0];
}
} else {
//符合抵扣条件的商品
@@ -448,16 +457,18 @@ function returnSecoendDiscount(canDikouGoodsArr, coupon, user, shopInfo) {
if (useRule == "price_asc") {
discountGoods = canUseGoods1[canUseGoods1.length - 1];
} else {
discountGoods = canUseGoods1.slice(0, 1);
discountGoods = canUseGoods1[0];
}
}
console.log("returnSecoendDiscount:discountGoods", discountGoods);
const discountPrice = returnGoodsPrice(discountGoods[0], user, shopInfo);
console.log("returnSecoendDiscount:discountPrice", discountPrice);
const hasDiscountGoodsArr = [discountGoods];
let discountPrice = 0;
let hasDiscountGoodsArr = [];
if (discountGoods) {
discountPrice = returnGoodsPrice(discountGoods, user, shopInfo);
hasDiscountGoodsArr = [discountGoods];
}
//返回半价价格
return {
discountPrice: new BigNumber(discountPrice).dividedBy(2).toNumber(),
discountPrice: discountPrice <= 0 ? 0 : new BigNumber(discountPrice).dividedBy(2).toNumber(),
hasDiscountGoodsArr,
};
}

View File

@@ -81,15 +81,14 @@
<el-icon><ArrowDown /></el-icon>
</div>
</div>
{{ carts.orderCostSummary }}
<div class="u-m-t-20" v-if="carts.coupons.length > 0">
<div class="u-m-t-20" v-if="quansSelArr.length > 0">
<div class="font-bold u-m-b-10">已选优惠券</div>
<el-table empty-text="未选择优惠券" :data="carts.coupons">
<el-table empty-text="未选择优惠券" :data="quansSelArr">
<el-table-column type="index" width="50" label="#"></el-table-column>
<el-table-column prop="name" label="券名称"></el-table-column>
<el-table-column label="券类型" width="80">
<template v-slot="scope">
{{ scope.row.type == 1 ? "优惠券" : "商品券" }}
{{ UTILS.returnCoupType(scope.row.type) }}
</template>
</el-table-column>
<el-table-column label="商品信息">
@@ -232,6 +231,8 @@
</template>
<script setup>
import * as UTILS from "@/utils/coupon-utils.js";
import * as quanUtil from "../quan_util.js";
import { OrderPriceCalculator } from "@/utils/goods";
import { useCartsStore } from "@/store/modules/carts";
@@ -302,6 +303,7 @@ function delQuan(row) {
if (index != -1) {
quansSelArr.value.splice(index, 1);
}
carts.setCoupons(quansSelArr.value);
}
function couponChange(data) {}

View File

@@ -32,7 +32,11 @@
</el-table-column>
<el-table-column prop="discountAmount" label="最大抵扣金额" align="center">
<template v-slot="scope">
<span class="color-red">{{ scope.row.maxDiscountAmount }}</span>
<span class="color-red">
{{
!scope.row.maxDiscountAmount ? "无上限" : "¥" + scope.row.maxDiscountAmount
}}
</span>
</template>
</el-table-column>
<el-table-column prop="discountAmount" label="限制" width="180">
@@ -70,21 +74,9 @@
<el-table-column label="商品信息" width="220">
<template v-slot="scope">
<div class="u-flex" v-if="scope.row.useFoods.length">
<div class="u-flex">
<el-image
:src="scope.row.productImg"
fit="cover"
style="width: 40px; height: 40px"
:preview-src-list="[scope.row.productImg]"
></el-image>
</div>
<div class="u-p-l-10">
<!-- <div class="">{{ scope.row.productName }}</div> -->
<div class="">x{{ scope.row.discountNum || 1 }}</div>
</div>
<div class="u-flex">
{{ scope.row.foods }}
</div>
<div class="u-flex" v-else>任意商品 x{{ scope.row.discountNum || 1 }}</div>
</template>
</el-table-column>
<el-table-column prop="discountAmount" label="抵扣">
@@ -107,9 +99,9 @@
</el-table>
</el-tab-pane>
</el-tabs>
<div v-if="quansSelArr.length > 0">
<div class="font-bold u-m-b-10">已选优惠券</div>
<el-table empty-text="未选择优惠券" :data="quansSelArr" max-height="20vh">
<div class="u-m-t-10" v-if="noUseCoupon.length > 0">
<div class="font-bold u-m-b-10">不可用优惠券</div>
<el-table empty-text="" :data="noUseCoupon" max-height="30vh">
<el-table-column type="index" width="50" label="#"></el-table-column>
<el-table-column prop="name" label="券名称"></el-table-column>
<el-table-column label="券类型" width="80">
@@ -119,21 +111,38 @@
</el-table-column>
<el-table-column label="商品信息" width="120">
<template v-slot="scope">
<div class="u-flex" v-if="scope.row.type == 2">
<div v-if="scope.row.useFoods.length">
<div class="u-flex">
<el-image
:src="scope.row.productImg"
fit="cover"
style="width: 40px; height: 40px"
></el-image>
</div>
<div class="u-p-l-10">
<div class="">{{ scope.row.productName }}</div>
<div class="">x{{ scope.row.discountNum || 1 }}</div>
</div>
</div>
<div v-else>任意商品 x{{ scope.row.discountNum || 1 }}</div>
<div class="u-flex">
{{ scope.row.foods }}
</div>
</template>
</el-table-column>
<el-table-column prop="discountAmount" label="抵扣">
<template v-slot="scope">
<span class="color-red">{{ scope.row.discountAmount }}</span>
</template>
</el-table-column>
<el-table-column prop="useRestrictions" label="描述"></el-table-column>
<el-table-column label="不可用原因">
<template v-slot="scope">
<span class="color-red">{{ scope.row.canuseResult.reason }}</span>
</template>
</el-table-column>
</el-table>
</div>
<div class="u-m-t-10" v-if="quansSelArr.length > 0">
<div class="font-bold u-m-b-10">已选优惠券</div>
<el-table empty-text="" :data="quansSelArr" max-height="20vh">
<el-table-column type="index" width="50" label="#"></el-table-column>
<el-table-column prop="name" label="券名称"></el-table-column>
<el-table-column label="券类型" width="80">
<template v-slot="scope">
{{ UTILS.returnCoupType(scope.row) }}
</template>
</el-table-column>
<el-table-column label="商品信息" width="120">
<template v-slot="scope">
<div class="u-flex">
{{ scope.row.foods }}
</div>
</template>
</el-table-column>
@@ -237,7 +246,7 @@ const {
isSetProductCoup,
} = toRefs(state);
const quansSelArr = computed(() => {
return [couponSel.value, goodsCouponSel.value].filter((v) => v.id);
return [goodsCouponSel.value, couponSel.value].filter((v) => v.id);
});
const refTable = ref();
const refTable1 = ref();
@@ -246,6 +255,8 @@ let orderPrice = ref(0);
//可以抵扣的商品列表
let canDikouGoodsArr = [];
let goodsArr = [];
//不可用优惠券列表
const noUseCoupon = ref([]);
function open(money, orderInfo) {
let arr = [];
@@ -260,70 +271,93 @@ function open(money, orderInfo) {
show.value = true;
}
let couponList = [];
async function getcoup() {
const res = await couponApi.findCoupon({ shopUserId: props.user.id });
console.log(res);
couponList = res || [];
let canUseGoodsCoupon = [];
let canUseDiscountCoupon = [];
let noUseGoodsCoupon = [];
let noUseDiscountCoupon = [];
for (let i = 0; i < couponList.length; i++) {
const coupon = couponList[i];
const selCoupon =
activeName.value == "goods"
? quansSelArr.value.filter((v) => v.type != 2)
: quansSelArr.value.filter((v) => v.type == 2);
const canuseResult = UTILS.returnCouponCanUse({
canDikouGoodsArr,
coupon,
orderPrice: orderPrice.value,
user: props.user,
selCoupon,
shopInfo: shopUser.userInfo,
});
const { canUse, reason } = canuseResult;
if (coupon.type == 2) {
if (canUse || goodsCouponSel.value.id == coupon.id) {
canUseGoodsCoupon.push(coupon);
} else {
noUseGoodsCoupon.push({
...coupon,
canuseResult,
});
}
} else {
if (canUse || couponSel.value.id == coupon.id) {
canUseDiscountCoupon.push(coupon);
} else {
noUseDiscountCoupon.push({
...coupon,
canuseResult,
});
}
}
}
//商品券
canUseGoodsCoupon = canUseGoodsCoupon.map((v) => {
const discount = UTILS.returnCouponDiscount(
canDikouGoodsArr,
v,
props.user,
orderPrice.value,
quansSelArr.value,
shopUser.userInfo
);
return {
...v,
discount,
discountAmount: discount ? discount.discountPrice : v.discountAmount,
};
});
//非商品券
quans.value.coupon = res
.filter((v) => v.type != 2)
.filter((coupon) => {
const { canUse, msg } = UTILS.returnCouponCanUse({
canDikouGoodsArr,
coupon,
orderPrice: orderPrice.value,
user: props.user,
selCoupon: quansSelArr.value,
shopInfo: shopUser.userInfo,
});
return canUse;
})
.map((v) => {
const discount = UTILS.returnCouponDiscount(
canDikouGoodsArr,
v,
props.user,
orderPrice.value,
quansSelArr.value,
shopUser.userInfo
);
return {
...v,
discount,
discountAmount: discount ? discount.discountPrice : v.discountAmount,
};
});
quans.value.productCoupon = res
.filter((v) => v.type == 2)
.filter((coupon) => {
const { canUse, msg } = UTILS.returnCouponCanUse({
canDikouGoodsArr,
coupon,
orderPrice: orderPrice.value,
user: props.user,
selCoupon: quansSelArr.value,
shopInfo: shopUser.userInfo,
});
return canUse;
})
.map((v) => {
const findGoods = goodsArr.find((goods) => goods.productId == v.proId);
const discount = UTILS.returnCouponDiscount(
canDikouGoodsArr,
v,
props.user,
orderPrice.value,
quansSelArr.value,
shopUser.userInfo
);
return {
...v,
productImg: findGoods ? findGoods.productImg : "",
productName: findGoods ? findGoods.productName : "",
discount,
discountAmount: discount ? discount.discountPrice : v.discountAmount,
};
});
canUseDiscountCoupon = canUseDiscountCoupon.map((v) => {
const discount = UTILS.returnCouponDiscount(
canDikouGoodsArr,
v,
props.user,
orderPrice.value,
quansSelArr.value,
shopUser.userInfo
);
return {
...v,
discount,
discountAmount: discount ? discount.discountPrice : v.discountAmount,
};
});
quans.value.productCoupon = canUseGoodsCoupon;
quans.value.coupon = canUseDiscountCoupon;
if (activeName.value == "goods") {
noUseCoupon.value = [...noUseGoodsCoupon];
} else {
noUseCoupon.value = [...noUseDiscountCoupon];
}
}
function couponClick(checked, row) {
couponSel.value = checked ? row : { id: "" };
}
@@ -371,7 +405,44 @@ watch(
);
watch(
() => quansSelArr.value,
() => {
(newval) => {
console.log("quansSelArr", newval);
if (newval.length >= 2) {
let goodsCoupon = newval.filter((v) => v.type == 2);
let otherCoupon = newval.filter((v) => v.type != 2);
goodsCoupon = goodsCoupon.map((v) => {
const discount = UTILS.returnCouponDiscount(
canDikouGoodsArr,
v,
props.user,
orderPrice.value,
[],
shopUser.userInfo
);
return {
...v,
discount,
discountAmount: discount ? discount.discountPrice : v.discountAmount,
};
});
otherCoupon = otherCoupon.map((v) => {
const discount = UTILS.returnCouponDiscount(
canDikouGoodsArr,
v,
props.user,
orderPrice.value,
goodsCoupon,
shopUser.userInfo
);
return {
...v,
discount,
discountAmount: discount ? discount.discountPrice : v.discountAmount,
};
});
couponSel.value = otherCoupon[0];
goodsCouponSel.value = goodsCoupon[0];
}
getcoup();
}
);