fix: 代客下单修改
This commit is contained in:
parent
5cd5265ffb
commit
4b9fc0ad3f
|
|
@ -68,7 +68,7 @@
|
|||
"vue-clipboard3": "^2.0.0",
|
||||
"vue-i18n": "^11.1.0",
|
||||
"vue-router": "^4.5.0",
|
||||
"ysk-utils": "^1.0.12"
|
||||
"ysk-utils": "^1.0.35"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^19.7.1",
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ import WebSocketManager, { type ApifoxModel, msgType } from "@/utils/websocket";
|
|||
import orderApi from "@/api/order/order";
|
||||
import { useUserStoreHook } from "@/store/modules/user";
|
||||
import productApi from "@/api/product/index";
|
||||
|
||||
import * as UTILS from "@/utils/coupon-utils.js";
|
||||
import { BigNumber } from "bignumber.js";
|
||||
import _ from "lodash";
|
||||
// 导入工具库及相关类型
|
||||
import {
|
||||
OrderPriceCalculator,
|
||||
|
|
@ -212,6 +214,7 @@ export const useCartsStore = defineStore("carts", () => {
|
|||
pointsPerYuan: 100,
|
||||
maxDeductionAmount: Infinity
|
||||
})
|
||||
//使用积分数量
|
||||
const userPoints = ref(0);
|
||||
// 订单额外配置(现在依赖响应式的 merchantReduction)
|
||||
const orderExtraConfig = computed<OrderExtraConfig>(() => ({
|
||||
|
|
@ -231,26 +234,50 @@ export const useCartsStore = defineStore("carts", () => {
|
|||
return [];
|
||||
});
|
||||
|
||||
const coupons = ref<BackendCoupon[]>([]);
|
||||
function setCoupons(cps: BackendCoupon[]) {
|
||||
console.log('setCoupons', cps);
|
||||
let goodsCoupon = cps.filter((v) => v.type == 2);
|
||||
let otherCoupon = cps.filter((v) => v.type != 2);
|
||||
const canDikouGoodsArr = UTILS.returnCanDikouGoods(allGoods.value, [], vipUser.value);
|
||||
//商品订单金额
|
||||
const goodsOrderPrice = new BigNumber(orderCostSummary.value.goodsOriginalAmount)
|
||||
.minus(orderCostSummary.value.goodsDiscountAmount)
|
||||
.toFixed(2);
|
||||
goodsCoupon = goodsCoupon.map((v) => {
|
||||
const discount = UTILS.returnCouponDiscount(canDikouGoodsArr, v, vipUser.value, goodsOrderPrice, [], shopUser.userInfo);
|
||||
return {
|
||||
...v,
|
||||
discount,
|
||||
discountAmount: discount ? discount.discountPrice : v.discountAmount
|
||||
};
|
||||
});
|
||||
otherCoupon = otherCoupon.map((v) => {
|
||||
const discount = UTILS.returnCouponDiscount(canDikouGoodsArr, v, vipUser.value, goodsOrderPrice, goodsCoupon, shopUser.userInfo);
|
||||
return {
|
||||
...v,
|
||||
discount,
|
||||
discountAmount: discount ? discount.discountPrice : v.discountAmount
|
||||
};
|
||||
});
|
||||
coupons.value = cps;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 优惠券列表
|
||||
const backendCoupons = computed<BackendCoupon[]>(() => {
|
||||
return coupons.value;
|
||||
});
|
||||
const coupons = ref<BackendCoupon[]>([]);
|
||||
|
||||
|
||||
// 商品加入购物车顺序
|
||||
const cartOrder = ref<Record<string, number>>({});
|
||||
|
||||
let allGoods = ref<BaseCartItem[]>([]);
|
||||
// 订单费用汇总(调用内部的 getAllGoodsList)
|
||||
const orderCostSummary = computed(() => {
|
||||
const allGoods = getAllGoodsList();
|
||||
allGoods.value = getAllGoodsList();
|
||||
const costSummary = OrderPriceCalculator.calculateOrderCostSummary(
|
||||
allGoods,
|
||||
allGoods.value,
|
||||
dinnerType.value,
|
||||
backendCoupons.value,
|
||||
coupons.value,
|
||||
activityList.value,
|
||||
orderExtraConfig.value,
|
||||
cartOrder.value,
|
||||
|
|
@ -714,6 +741,12 @@ export const useCartsStore = defineStore("carts", () => {
|
|||
WebSocketManager.sendMessage(msg);
|
||||
}
|
||||
|
||||
function payParamsInit() {
|
||||
coupons.value = []
|
||||
clearMerchantReduction()
|
||||
userPoints.value = 0;
|
||||
}
|
||||
|
||||
return {
|
||||
disconnect,
|
||||
dinnerType,
|
||||
|
|
@ -764,8 +797,11 @@ export const useCartsStore = defineStore("carts", () => {
|
|||
clearMerchantReduction,
|
||||
seatFeeConfig,
|
||||
pointDeductionRule,
|
||||
//使用积分数量
|
||||
userPoints,
|
||||
setCoupons
|
||||
coupons,
|
||||
setCoupons,
|
||||
payParamsInit
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,33 +1,22 @@
|
|||
import { BigNumber } from "bignumber.js";
|
||||
import _ from "lodash";
|
||||
|
||||
/**
|
||||
* 返回可以抵扣优惠券的商品列表,过滤掉赠品、临时商品,价格从高到低排序
|
||||
* @param arr 商品列表
|
||||
* @param user 用户信息
|
||||
*/
|
||||
export function returnCanDikouGoods(arr, user) {
|
||||
return arr
|
||||
.filter((v) => {
|
||||
return v.is_temporary != 1 && v.is_gift != 1;
|
||||
})
|
||||
.filter((v) => {
|
||||
return v.num > 0;
|
||||
})
|
||||
.sort((a, b) => {
|
||||
return returnGoodsPrice(b, user) - returnGoodsPrice(a, user);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回商品单价
|
||||
* @param goods 商品
|
||||
* @param user 用户信息
|
||||
* @param {Object} shopInfo
|
||||
*/
|
||||
export function returnGoodsPrice(goods, user) {
|
||||
export function returnGoodsPrice(goods, user, shopInfo) {
|
||||
if (!goods) {
|
||||
return 0;
|
||||
}
|
||||
if (goods.discount_sale_amount * 1 > 0) {
|
||||
return goods.discount_sale_amount;
|
||||
}
|
||||
if (shopInfo && !shopInfo.isMemberPrice) {
|
||||
return goods.salePrice;
|
||||
}
|
||||
if (user.isVip && goods.memberPrice * 1 <= goods.salePrice * 1 && goods.memberPrice * 1 > 0) {
|
||||
return goods.memberPrice;
|
||||
}
|
||||
|
|
@ -75,116 +64,183 @@ export function returnCoupType(coupon) {
|
|||
* @param user 用户信息
|
||||
*/
|
||||
export function returnCanDikouGoodsArr(canDikouGoodsArr, selCoupon, user) {
|
||||
const types = [2, 4, 6];
|
||||
// 收集已抵扣商品并关联对应的优惠券类型
|
||||
const goodsCouponGoods = selCoupon
|
||||
.filter((v) => v.type == 2)
|
||||
.reduce((prve, cur) => {
|
||||
prve.push(...cur.discount.hasDiscountGoodsArr);
|
||||
return prve;
|
||||
.filter((v) => types.includes(v.type))
|
||||
.reduce((prev, cur) => {
|
||||
// 给每个抵扣商品添加所属优惠券类型
|
||||
const goodsWithType = cur.discount.hasDiscountGoodsArr.map((goods) => ({
|
||||
...goods,
|
||||
couponType: cur.type, // 记录该商品是被哪种类型的优惠券抵扣的
|
||||
}));
|
||||
prev.push(...goodsWithType);
|
||||
return prev;
|
||||
}, []);
|
||||
|
||||
const arr = _.cloneDeep(canDikouGoodsArr)
|
||||
.map((v) => {
|
||||
const findCart = goodsCouponGoods.find((carts) => carts.id == v.id);
|
||||
if (findCart) {
|
||||
v.num -= findCart.num;
|
||||
// 根据优惠券类型判断扣减数量
|
||||
if ([4, 6].includes(findCart.couponType)) {
|
||||
// 类型4(第二件半价)或6(买一送一),数量减2
|
||||
v.num -= 2;
|
||||
} else {
|
||||
// 其他类型(如类型2商品券),按原逻辑扣减对应数量
|
||||
v.num -= findCart.num;
|
||||
}
|
||||
}
|
||||
return v;
|
||||
})
|
||||
.filter((v) => v.num > 0);
|
||||
.filter((v) => v.num > 0); // 过滤掉数量<=0的商品
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断优惠券是否可使用
|
||||
* 判断优惠券是否可使用,并返回不可用原因
|
||||
*
|
||||
* @param {Object} args - 函数参数集合
|
||||
* @param {Array} args.canDikouGoodsArr - 可参与抵扣的商品列表,每个元素包含商品信息(productId、num等)
|
||||
* @param {Array} args.canDikouGoodsArr - 可参与抵扣的商品列表
|
||||
* @param {Object} args.coupon - 优惠券信息对象
|
||||
* @param {boolean} args.coupon.use - 优惠券是否启用(true为启用,false为禁用)
|
||||
* @param {Array} args.coupon.useFoods - 优惠券适用的商品ID列表(空数组表示适用全部商品)
|
||||
* @param {boolean} args.coupon.use - 优惠券是否启用
|
||||
* @param {Array} args.coupon.useFoods - 优惠券适用的商品ID列表
|
||||
* @param {number} args.coupon.fullAmount - 优惠券使用门槛金额
|
||||
* @param {number} args.coupon.type - 优惠券类型(1:满减券, 2:商品券, 3:折扣券, 4:第二件半价券, 6:买一送一券)
|
||||
* @param {number} args.goodsOrderPrice - 订单中所有商品的总金额(未筛选时的初始金额)
|
||||
* @param {Object} args.user - 用户信息对象(用于计算商品价格,如会员价等)
|
||||
* @param {Object} args.user - 用户信息对象(用于计算商品价格,如会员价等)
|
||||
* @param {number} args.coupon.type - 优惠券类型
|
||||
* @param {number} args.goodsOrderPrice - 订单中所有商品的总金额
|
||||
* @param {Object} args.user - 用户信息对象
|
||||
* @param {Object} args.selCoupon - 已经选择的优惠券信息对象
|
||||
* @returns {boolean} - 优惠券是否可用(true可用,false不可用)
|
||||
* @param {Object} args.shopInfo
|
||||
* @returns {Object} - { canUse: boolean, reason: string } 可用状态及不可用原因
|
||||
*/
|
||||
export function returnCouponCanUse(args) {
|
||||
let { canDikouGoodsArr, coupon, goodsOrderPrice, user, selCoupon } = args;
|
||||
let { canDikouGoodsArr, coupon, goodsOrderPrice, user, selCoupon, shopInfo } = args;
|
||||
|
||||
// 优惠券未启用
|
||||
if (!coupon.use) {
|
||||
return false;
|
||||
return {
|
||||
canUse: false,
|
||||
reason: "优惠券未启用",
|
||||
};
|
||||
}
|
||||
|
||||
canDikouGoodsArr = returnCanDikouGoodsArr(canDikouGoodsArr, selCoupon, user);
|
||||
// 计算门槛金额
|
||||
let fullAmount = goodsOrderPrice;
|
||||
//是否抵扣全部商品
|
||||
const isDikouAll = coupon.useFoods.length === 0;
|
||||
let canCalcGoodsArr = [];
|
||||
// 订单里参与门槛计算的商品
|
||||
if (!isDikouAll) {
|
||||
canDikouGoodsArr = returnCanDikouGoodsArr(canDikouGoodsArr, selCoupon, user, shopInfo);
|
||||
|
||||
//优惠券指定门槛商品列表
|
||||
let canCalcGoodsArr = [...canDikouGoodsArr];
|
||||
//部分商品参与门槛计算
|
||||
if (coupon.thresholdFoods.length) {
|
||||
canCalcGoodsArr = canDikouGoodsArr.filter((v) => {
|
||||
return coupon.useFoods.find((food) => food.id == v.productId);
|
||||
return coupon.thresholdFoods.find((food) => food.id == v.productId);
|
||||
});
|
||||
fullAmount = canCalcGoodsArr.reduce((pre, cur) => {
|
||||
return pre + returnGoodsPrice(cur, user) * cur.num;
|
||||
return pre + returnGoodsPrice(cur, user, shopInfo) * cur.num;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
//没有符合商品
|
||||
if (!isDikouAll && canCalcGoodsArr.length == 0) {
|
||||
return false;
|
||||
// 是否全部商品可用
|
||||
const isDikouAll = coupon.useFoods.length === 0;
|
||||
// 订单可用商品列表
|
||||
let canUseGoodsArr = [];
|
||||
if (!isDikouAll) {
|
||||
canUseGoodsArr = canDikouGoodsArr.filter((v) => {
|
||||
return coupon.useFoods.find((food) => food.id == v.productId);
|
||||
});
|
||||
}
|
||||
if (user.isVip && !coupon.vipPriceShare) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: "非会员可用",
|
||||
};
|
||||
}
|
||||
if (selCoupon.length > 0 && !selCoupon[0].otherCouponShare) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: "当前选中的券不可与其他券同享",
|
||||
};
|
||||
}
|
||||
if (selCoupon.length > 0 && !coupon.otherCouponShare) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: "当前选中的券不可与其他券同享",
|
||||
};
|
||||
}
|
||||
// 满减券和折扣券计算门槛金额是否满足
|
||||
if ([1, 3].includes(coupon.type)) {
|
||||
if (canCalcGoodsArr.length <= 0) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: "没有可参与计算门槛的商品",
|
||||
};
|
||||
}
|
||||
// 不满足门槛金额
|
||||
if (fullAmount < coupon.fullAmount) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: `满${coupon.fullAmount}元可用,当前可参与金额${fullAmount}元`,
|
||||
};
|
||||
}
|
||||
}
|
||||
// 商品兑换券,第二件半价和买一送一判断是否有可用商品
|
||||
if ([2, 4, 5].includes(coupon.type)) {
|
||||
// 没有符合条件的商品
|
||||
if (!isDikouAll && canCalcGoodsArr.length === 0) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: "没有符合条件的商品",
|
||||
};
|
||||
}
|
||||
}
|
||||
//商品兑换券是否达到门槛金额
|
||||
if (coupon.type == 2 && goodsOrderPrice < coupon.fullAmount) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: `满${coupon.fullAmount}元可用,当前可参与金额${fullAmount}元`,
|
||||
};
|
||||
}
|
||||
|
||||
//不满足门槛金额
|
||||
if (fullAmount < coupon.fullAmount) {
|
||||
console.log("不满足门槛金额");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (coupon.type == 2) {
|
||||
//商品券
|
||||
return isDikouAll || canCalcGoodsArr.length > 0;
|
||||
}
|
||||
if (coupon.type == 1) {
|
||||
//满减券
|
||||
return fullAmount >= coupon.fullAmount;
|
||||
}
|
||||
if (coupon.type == 6) {
|
||||
//买一送一券
|
||||
|
||||
// 买一送一券特殊验证
|
||||
if (coupon.type === 6) {
|
||||
let canUse = false;
|
||||
if (isDikouAll) {
|
||||
canUse = canDikouGoodsArr.some((v) => v.num >= 2);
|
||||
} else if (canCalcGoodsArr.length > 0) {
|
||||
canUse = canCalcGoodsArr.some((v) => v.num >= 2);
|
||||
}
|
||||
if (canCalcGoodsArr.length > 0) {
|
||||
canUse = canDikouGoodsArr
|
||||
.filter((v) => {
|
||||
return coupon.useFoods.find((food) => food.id == v.productId);
|
||||
})
|
||||
.some((v) => v.num >= 2);
|
||||
|
||||
if (!canUse) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: "需要购买至少2件相同的商品才能使用",
|
||||
};
|
||||
}
|
||||
return canUse;
|
||||
}
|
||||
if (coupon.type == 4) {
|
||||
//第二件半价券
|
||||
|
||||
// 第二件半价券特殊验证
|
||||
if (coupon.type === 4) {
|
||||
let canUse = false;
|
||||
if (isDikouAll) {
|
||||
canUse = canDikouGoodsArr.some((v) => v.num >= 2);
|
||||
} else if (canCalcGoodsArr.length > 0) {
|
||||
canUse = canCalcGoodsArr.some((v) => v.num >= 2);
|
||||
}
|
||||
if (canCalcGoodsArr.length > 0) {
|
||||
canUse = canDikouGoodsArr
|
||||
.filter((v) => {
|
||||
return coupon.useFoods.find((food) => food.id == v.productId);
|
||||
})
|
||||
.some((v) => v.num >= 2);
|
||||
|
||||
if (!canUse) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: "需要购买至少2件相同的商品才能使用",
|
||||
};
|
||||
}
|
||||
return canUse;
|
||||
}
|
||||
if (coupon.type == 3) {
|
||||
//折扣券
|
||||
return true;
|
||||
}
|
||||
|
||||
// 所有条件都满足
|
||||
return {
|
||||
canUse: true,
|
||||
reason: "",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -192,8 +248,9 @@ export function returnCouponCanUse(args) {
|
|||
* @param discountGoodsArr 可抵扣商品列表
|
||||
* @param discountNum 抵扣数量
|
||||
* @param user 用户信息
|
||||
* @param {Object} shopInfo 店铺信息
|
||||
*/
|
||||
export function calcDiscountGoodsArrPrice(discountGoodsArr, discountNum, user) {
|
||||
export function calcDiscountGoodsArrPrice(discountGoodsArr, discountNum, user, shopInfo) {
|
||||
let hasCountNum = 0;
|
||||
let discountPrice = 0;
|
||||
let hasDiscountGoodsArr = [];
|
||||
|
|
@ -204,31 +261,38 @@ export function calcDiscountGoodsArrPrice(discountGoodsArr, discountNum, user) {
|
|||
const goods = discountGoodsArr[i];
|
||||
const shengyuNum = discountNum - hasCountNum;
|
||||
const num = Math.min(goods.num, shengyuNum);
|
||||
discountPrice += returnGoodsPrice(goods, user) * num;
|
||||
discountPrice += returnGoodsPrice(goods, user, shopInfo) * num;
|
||||
hasCountNum += num;
|
||||
hasDiscountGoodsArr.push({ ...goods, num });
|
||||
hasDiscountGoodsArr.push({
|
||||
...goods,
|
||||
num,
|
||||
});
|
||||
}
|
||||
return { discountPrice, hasDiscountGoodsArr };
|
||||
return {
|
||||
discountPrice,
|
||||
hasDiscountGoodsArr,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算优惠券抵扣金额
|
||||
* @param canDikouGoodsArr 可抵扣商品列表
|
||||
* @param arr 可抵扣商品列表
|
||||
* @param coupon 优惠券
|
||||
* @param user 用户信息
|
||||
* @param goodsOrderPrice 商品订单金额
|
||||
* @param selCoupon 已选择的优惠券列表
|
||||
* @param shopInfo 店铺信息
|
||||
*/
|
||||
export function returnCouponDiscount(canDikouGoodsArr, coupon, user, goodsOrderPrice, selCoupon) {
|
||||
canDikouGoodsArr = returnCanDikouGoodsArr(canDikouGoodsArr, selCoupon, user);
|
||||
export function returnCouponDiscount(arr, coupon, user, goodsOrderPrice, selCoupon, shopInfo) {
|
||||
const canDikouGoodsArr = returnCanDikouGoodsArr(arr, selCoupon, user);
|
||||
if (coupon.type == 2) {
|
||||
return returnCouponProductDiscount(canDikouGoodsArr, coupon, user, goodsOrderPrice);
|
||||
return returnCouponProductDiscount(canDikouGoodsArr, coupon, user, shopInfo);
|
||||
}
|
||||
if (coupon.type == 6) {
|
||||
return returnCouponBuyOneGiveOneDiscount(canDikouGoodsArr, coupon, user, goodsOrderPrice);
|
||||
return returnCouponBuyOneGiveOneDiscount(canDikouGoodsArr, coupon, user, shopInfo);
|
||||
}
|
||||
if (coupon.type == 4) {
|
||||
return returnSecoendDiscount(canDikouGoodsArr, coupon, user, goodsOrderPrice);
|
||||
return returnSecoendDiscount(canDikouGoodsArr, coupon, user, shopInfo);
|
||||
}
|
||||
if (coupon.type == 3) {
|
||||
return returnCouponZhekouDiscount(canDikouGoodsArr, coupon, user, goodsOrderPrice, selCoupon);
|
||||
|
|
@ -253,21 +317,28 @@ export function returnCouponZhekouDiscount(
|
|||
) {
|
||||
const { discountRate, maxDiscountAmount } = coupon;
|
||||
|
||||
// 计算商品优惠券折扣总和,使用BigNumber避免精度问题
|
||||
const goodsCouponDiscount = selCoupon
|
||||
.filter((v) => v.type == 2)
|
||||
.reduce((prve, cur) => {
|
||||
return prve + cur.discount.discountPrice;
|
||||
}, 0);
|
||||
goodsOrderPrice -= goodsCouponDiscount;
|
||||
return new BigNumber(prve).plus(new BigNumber(cur.discount.discountPrice));
|
||||
}, new BigNumber(0));
|
||||
|
||||
// 使用bignumber处理高精度计算
|
||||
// 1. 计算折扣率(百分比转小数):discountRate / 100
|
||||
const discountRatio = new BigNumber(discountRate).dividedBy(100);
|
||||
// 2. 计算优惠比例:1 - 折扣率(例如:8折的优惠比例是 1 - 0.8 = 0.2)
|
||||
const discountAmountRatio = new BigNumber(1).minus(discountRatio);
|
||||
// 3. 计算折扣金额:商品订单金额 × 优惠比例
|
||||
let discountPrice = new BigNumber(goodsOrderPrice).times(discountAmountRatio).toNumber();
|
||||
if (maxDiscountAmount != 0) {
|
||||
// 将商品订单价格转换为BigNumber并减去优惠券折扣
|
||||
const adjustedGoodsOrderPrice = new BigNumber(goodsOrderPrice).minus(goodsCouponDiscount);
|
||||
console.log("adjustedGoodsOrderPrice", adjustedGoodsOrderPrice.toNumber());
|
||||
|
||||
// 计算优惠比例:(100 - 折扣率) / 100
|
||||
const discountAmountRatio = new BigNumber(100).minus(discountRate).dividedBy(100);
|
||||
|
||||
// 计算折扣金额:调整后的商品订单金额 × 优惠比例
|
||||
let discountPrice = adjustedGoodsOrderPrice
|
||||
.times(discountAmountRatio)
|
||||
.decimalPlaces(2, BigNumber.ROUND_FLOOR)
|
||||
.toNumber();
|
||||
|
||||
// 应用最大折扣金额限制
|
||||
if (maxDiscountAmount !== 0) {
|
||||
discountPrice = discountPrice >= maxDiscountAmount ? maxDiscountAmount : discountPrice;
|
||||
}
|
||||
|
||||
|
|
@ -282,13 +353,12 @@ export function returnCouponZhekouDiscount(
|
|||
* @param canDikouGoodsArr 可抵扣商品列表
|
||||
* @param coupon 优惠券
|
||||
* @param user 用户信息
|
||||
* @param shopInfo 店铺信息
|
||||
*/
|
||||
export function returnCouponProductDiscount(canDikouGoodsArr, coupon, user) {
|
||||
export function returnCouponProductDiscount(canDikouGoodsArr, coupon, user, shopInfo) {
|
||||
const { useFoods, discountNum, useRule } = coupon;
|
||||
|
||||
//抵扣商品数组
|
||||
let discountGoodsArr = [];
|
||||
|
||||
//抵扣全部商品
|
||||
if (useFoods.length === 0) {
|
||||
if (useRule == "price_asc") {
|
||||
|
|
@ -311,8 +381,7 @@ export function returnCouponProductDiscount(canDikouGoodsArr, coupon, user) {
|
|||
discountGoodsArr = discountSelGoodsArr.slice(0, discountNum);
|
||||
}
|
||||
}
|
||||
const result = calcDiscountGoodsArrPrice(discountGoodsArr, discountNum, user);
|
||||
console.log(result);
|
||||
const result = calcDiscountGoodsArrPrice(discountGoodsArr, discountNum, user, shopInfo);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -321,8 +390,9 @@ export function returnCouponProductDiscount(canDikouGoodsArr, coupon, user) {
|
|||
* @param canDikouGoodsArr 可抵扣商品列表
|
||||
* @param coupon 优惠券
|
||||
* @param user 用户信息
|
||||
* @param shopInfo 店铺信息
|
||||
*/
|
||||
function returnCouponBuyOneGiveOneDiscount(canDikouGoodsArr, coupon, user) {
|
||||
function returnCouponBuyOneGiveOneDiscount(canDikouGoodsArr, coupon, user, shopInfo) {
|
||||
const { useFoods, useRule } = coupon;
|
||||
//抵扣商品
|
||||
let discountGoods = undefined;
|
||||
|
|
@ -338,18 +408,18 @@ function returnCouponBuyOneGiveOneDiscount(canDikouGoodsArr, coupon, user) {
|
|||
} else {
|
||||
//符合抵扣条件的商品
|
||||
const canUseGoods1 = canUseGoods.filter((v) => useFoods.find((food) => food.id == v.productId));
|
||||
console.log(canUseGoods1);
|
||||
if (useRule == "price_asc") {
|
||||
discountGoods = canUseGoods1[canUseGoods1.length - 1];
|
||||
} else {
|
||||
discountGoods = canUseGoods1.slice(0, 1);
|
||||
}
|
||||
}
|
||||
console.log("discountGoods");
|
||||
console.log(discountGoods);
|
||||
const discountPrice = returnGoodsPrice(discountGoods, user);
|
||||
const discountPrice = returnGoodsPrice(discountGoods, user, shopInfo);
|
||||
const hasDiscountGoodsArr = [discountGoods];
|
||||
return { discountPrice, hasDiscountGoodsArr };
|
||||
return {
|
||||
discountPrice,
|
||||
hasDiscountGoodsArr,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -357,8 +427,9 @@ function returnCouponBuyOneGiveOneDiscount(canDikouGoodsArr, coupon, user) {
|
|||
* @param canDikouGoodsArr 可抵扣商品列表
|
||||
* @param coupon 优惠券
|
||||
* @param user 用户信息
|
||||
* @param shopInfo 店铺信息
|
||||
*/
|
||||
function returnSecoendDiscount(canDikouGoodsArr, coupon, user) {
|
||||
function returnSecoendDiscount(canDikouGoodsArr, coupon, user, shopInfo) {
|
||||
const { useFoods, useRule } = coupon;
|
||||
//抵扣商品
|
||||
let discountGoods = undefined;
|
||||
|
|
@ -374,14 +445,15 @@ function returnSecoendDiscount(canDikouGoodsArr, coupon, user) {
|
|||
} else {
|
||||
//符合抵扣条件的商品
|
||||
const canUseGoods1 = canUseGoods.filter((v) => useFoods.find((food) => food.id == v.productId));
|
||||
console.log(canUseGoods1);
|
||||
if (useRule == "price_asc") {
|
||||
discountGoods = canUseGoods1[canUseGoods1.length - 1];
|
||||
} else {
|
||||
discountGoods = canUseGoods1.slice(0, 1);
|
||||
}
|
||||
}
|
||||
const discountPrice = returnGoodsPrice(discountGoods, user);
|
||||
console.log("returnSecoendDiscount:discountGoods", discountGoods);
|
||||
const discountPrice = returnGoodsPrice(discountGoods[0], user, shopInfo);
|
||||
console.log("returnSecoendDiscount:discountPrice", discountPrice);
|
||||
const hasDiscountGoodsArr = [discountGoods];
|
||||
//返回半价价格
|
||||
return {
|
||||
|
|
@ -389,3 +461,23 @@ function returnSecoendDiscount(canDikouGoodsArr, coupon, user) {
|
|||
hasDiscountGoodsArr,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回可以抵扣优惠券的商品列表,过滤掉赠品、临时商品,价格从高到低排序
|
||||
* @param arr 商品列表
|
||||
* @param user 用户信息
|
||||
* @param shopInfo 店铺信息
|
||||
*/
|
||||
export function returnCanDikouGoods(arr, user, shopInfo) {
|
||||
const result = arr
|
||||
.filter((v) => {
|
||||
return v.is_temporary != 1 && v.is_gift != 1;
|
||||
})
|
||||
.filter((v) => {
|
||||
return v.num > 0;
|
||||
})
|
||||
.sort((a, b) => {
|
||||
return returnGoodsPrice(b, user, shopInfo) - returnGoodsPrice(a, user, shopInfo);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
|
@ -60,8 +60,8 @@ export interface BackendCoupon {
|
|||
id?: number; // 自增主键(int64)
|
||||
shopId?: number; // 店铺ID(int64)
|
||||
syncId?: number; // 同步Id(int64)
|
||||
couponType?: number; // 优惠券类型:1-满减券,2-商品兑换券,3-折扣券,4-第二件半价券,5-消费送券,6-买一送一券,7-固定价格券,8-免配送费券
|
||||
title?: string; // 券名称
|
||||
type?: number; // 优惠券类型:1-满减券,2-商品兑换券,3-折扣券,4-第二件半价券,5-消费送券,6-买一送一券,7-固定价格券,8-免配送费券
|
||||
name?: string; // 券名称
|
||||
useShopType?: string; // 可用门店类型:only-仅本店;all-所有门店,custom-指定门店
|
||||
useShops?: string; // 可用门店(逗号分隔字符串,如"1,2,3")
|
||||
useType?: string; // 可使用类型:dine堂食/pickup自取/deliv配送/express快递
|
||||
|
|
@ -228,6 +228,7 @@ export interface OrderExtraConfig {
|
|||
userPoints: number; // 用户当前积分(用于积分抵扣)
|
||||
isMember: boolean; // 用户是否会员(用于会员优惠)
|
||||
memberDiscountRate?: number; // 会员折扣率(如0.95=95折,无会员价时用)
|
||||
newUserDiscount?: number; // 新用户减免金额(元,默认0)
|
||||
}
|
||||
|
||||
/** 订单费用汇总(修改:补充商家减免类型和明细) */
|
||||
|
|
@ -251,6 +252,9 @@ export interface OrderCostSummary {
|
|||
finalPayAmount: number; // 最终实付金额
|
||||
couponUsed?: Coupon; // 实际使用的优惠券
|
||||
pointUsed: number; // 实际使用的积分
|
||||
newUserDiscount: number; // 新用户减免金额(元,默认0)
|
||||
dinnerType?: 'dine-in' | 'take-out'; // 就餐类型(堂食/自取/配送/快递)
|
||||
|
||||
}
|
||||
|
||||
// ============================ 2. 基础工具函数(核心修正:所有商品ID匹配用product_id) ============================
|
||||
|
|
@ -269,15 +273,15 @@ export function convertBackendCouponToToolCoupon(
|
|||
currentTime: Date = new Date()
|
||||
): Coupon | null {
|
||||
// 1. 基础校验:必选字段缺失直接返回null
|
||||
if (!backendCoupon.id || backendCoupon.type === undefined || !backendCoupon.title) {
|
||||
if (!backendCoupon.id || backendCoupon.type === undefined) {
|
||||
console.warn('优惠券必选字段缺失', backendCoupon);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 2. 转换券类型:后端数字枚举 → 工具库字符串枚举
|
||||
const couponType = mapBackendCouponTypeToTool(backendCoupon.couponType);
|
||||
const couponType = mapBackendCouponTypeToTool(backendCoupon.type);
|
||||
if (!couponType) {
|
||||
console.warn(`不支持的优惠券类型:${backendCoupon.couponType}(券ID:${backendCoupon.id})`);
|
||||
console.warn(`不支持的优惠券类型:${backendCoupon.type}(券ID:${backendCoupon.id})`);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -286,16 +290,17 @@ export function convertBackendCouponToToolCoupon(
|
|||
? [] // 空字符串/undefined → 全部商品(按商品ID匹配)
|
||||
: backendCoupon.foods.split(',').map(id => id.trim()); // 逗号分隔 → 指定商品ID数组
|
||||
|
||||
const useType = backendCoupon?.useType?.split(',')?.map(v => v.replace(/[\[\]]/g, '').replace(/""/g, '"').replace(/["']/g, '')) || [];
|
||||
// 4. 计算基础公共字段(含多维度可用性校验)
|
||||
const baseCoupon: BaseCoupon = {
|
||||
id: backendCoupon.id,
|
||||
type: couponType,
|
||||
name: backendCoupon.title,
|
||||
name: backendCoupon.name || '',
|
||||
available: isCouponAvailable(backendCoupon, currentStoreId, dinnerType, currentTime),
|
||||
useShops: getApplicableStoreIds(backendCoupon, currentStoreId),
|
||||
discountShare: backendCoupon.discountShare === 1,
|
||||
vipPriceShare: backendCoupon.vipPriceShare === 1,
|
||||
useType: backendCoupon.useType ? backendCoupon.useType.split(',') : [],
|
||||
useType: useType,
|
||||
isValid: isCouponInValidPeriod(backendCoupon, currentTime),
|
||||
applicableProductIds: applicableProductIds,
|
||||
};
|
||||
|
|
@ -365,7 +370,7 @@ function isCouponAvailable(
|
|||
currentTime: Date = new Date()
|
||||
): boolean {
|
||||
// 1. 状态校验:必须启用(status=1)
|
||||
if (backendCoupon.status !== 1) return false;
|
||||
if (backendCoupon.status === 0) return false;
|
||||
|
||||
// 3. 有效期校验:必须在有效期内
|
||||
if (!isCouponInValidPeriod(backendCoupon, currentTime)) return false;
|
||||
|
|
@ -377,13 +382,13 @@ function isCouponAvailable(
|
|||
if (!isCouponInDailyTimeRange(backendCoupon, currentTime)) return false;
|
||||
|
||||
// 6. 每周周期校验:当前星期几需在可用周期内(useDays非空时生效)
|
||||
if (!isCouponInWeekDays(backendCoupon, currentTime)) return false;
|
||||
// if (!isCouponInWeekDays(backendCoupon, currentTime)) return false;
|
||||
|
||||
// 7. 门店匹配校验:当前门店需在适用门店范围内
|
||||
if (!isStoreMatch(backendCoupon, currentStoreId)) return false;
|
||||
// if (!isStoreMatch(backendCoupon, currentStoreId)) return false;
|
||||
|
||||
// 8. 就餐类型校验:当前就餐类型需在可用类型范围内
|
||||
if (!isDinnerTypeMatch(backendCoupon, dinnerType)) return false;
|
||||
// if (!isDinnerTypeMatch(backendCoupon, dinnerType)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1188,81 +1193,29 @@ export function calcCouponDeduction(
|
|||
usedCoupon?: Coupon;
|
||||
excludedProductIds: string[]; // 排除的商品ID列表(商品ID)
|
||||
} {
|
||||
// 1. 后端优惠券转工具库Coupon(过滤无效/不支持的券)
|
||||
const toolCoupons = backendCoupons
|
||||
.map(coupon => convertBackendCouponToToolCoupon(
|
||||
coupon,
|
||||
config.currentStoreId,
|
||||
config.dinnerType,
|
||||
config.currentTime
|
||||
))
|
||||
.filter(Boolean) as Coupon[];
|
||||
if (toolCoupons.length === 0) {
|
||||
return {
|
||||
deductionAmount: 0,
|
||||
productCouponDeduction: 0,
|
||||
fullCouponDeduction: 0,
|
||||
excludedProductIds: []
|
||||
};
|
||||
}
|
||||
console.log('toolCoupons', toolCoupons)
|
||||
|
||||
// 2. 优惠券互斥逻辑:兑换券与其他券互斥,优先选最优
|
||||
const exchangeCoupons = toolCoupons.filter(c => c.type === CouponType.EXCHANGE);
|
||||
const nonExchangeCoupons = toolCoupons.filter(c => c.type !== CouponType.EXCHANGE);
|
||||
const goodsCoupon = backendCoupons.filter(v => v.type == 2)
|
||||
const discountCoupon = backendCoupons.filter(v => v.type != 2)
|
||||
|
||||
// 3. 计算非兑换券最优抵扣(传递已抵扣商品ID,避免重复,统计细分字段)
|
||||
let nonExchangeResult: CouponResult = {
|
||||
deductionAmount: 0,
|
||||
deductionAmount: discountCoupon.reduce((prve, cur): number => {
|
||||
return prve + (cur.discountAmount || 0)
|
||||
}, 0),
|
||||
excludedProductIds: [],
|
||||
usedCoupon: undefined,
|
||||
productCouponDeduction: 0,
|
||||
fullCouponDeduction: 0
|
||||
};
|
||||
if (nonExchangeCoupons.length > 0) {
|
||||
nonExchangeResult = nonExchangeCoupons.reduce((best, coupon) => {
|
||||
const strategy = getCouponStrategy(coupon.type);
|
||||
const result = strategy.calculate(coupon, goodsList, {
|
||||
...config,
|
||||
excludedProductIds: best.excludedProductIds // 传递已排除的商品ID(商品ID)
|
||||
});
|
||||
const currentResult: CouponResult = {
|
||||
deductionAmount: result.deductionAmount,
|
||||
excludedProductIds: result.excludedProductIds,
|
||||
usedCoupon: coupon,
|
||||
// 按策略返回的字段赋值细分抵扣
|
||||
productCouponDeduction: result.productCouponDeduction || 0,
|
||||
fullCouponDeduction: result.fullCouponDeduction || 0
|
||||
};
|
||||
// 按总抵扣金额选择最优
|
||||
return new BigNumber(currentResult.deductionAmount).isGreaterThan(best.deductionAmount)
|
||||
? currentResult
|
||||
: best;
|
||||
}, nonExchangeResult);
|
||||
}
|
||||
|
||||
// 4. 计算兑换券抵扣(排除非兑换券已抵扣的商品ID,统计商品券细分)
|
||||
let exchangeResult: ExchangeCalculationResult = {
|
||||
deductionAmount: 0,
|
||||
deductionAmount: goodsCoupon.reduce((prve, cur): number => {
|
||||
return prve + (cur.discountAmount || 0)
|
||||
}, 0),
|
||||
excludedProductIds: [],
|
||||
productCouponDeduction: 0
|
||||
};
|
||||
if (exchangeCoupons.length > 0) {
|
||||
exchangeResult = exchangeCoupons.reduce((best, coupon) => {
|
||||
const strategy = getCouponStrategy(coupon.type);
|
||||
const result = strategy.calculate(coupon, goodsList, {
|
||||
...config,
|
||||
excludedProductIds: [...nonExchangeResult.excludedProductIds, ...best.excludedProductIds] // 合并排除的商品ID
|
||||
});
|
||||
return new BigNumber(result.deductionAmount).isGreaterThan(best.deductionAmount)
|
||||
? {
|
||||
deductionAmount: result.deductionAmount,
|
||||
excludedProductIds: result.excludedProductIds,
|
||||
productCouponDeduction: result.productCouponDeduction || 0 // 兑换券属于商品券
|
||||
}
|
||||
: best;
|
||||
}, exchangeResult);
|
||||
}
|
||||
|
||||
|
||||
// 5. 汇总结果:兑换券与非兑换券不可同时使用,取抵扣金额大的
|
||||
const exchangeBn = new BigNumber(exchangeResult.deductionAmount);
|
||||
|
|
@ -1270,9 +1223,9 @@ export function calcCouponDeduction(
|
|||
const isExchangeBetter = exchangeBn.isGreaterThan(nonExchangeBn);
|
||||
|
||||
return {
|
||||
deductionAmount: truncateToTwoDecimals(isExchangeBetter ? exchangeResult.deductionAmount : nonExchangeResult.deductionAmount),
|
||||
productCouponDeduction: isExchangeBetter ? exchangeResult.productCouponDeduction : nonExchangeResult.productCouponDeduction,
|
||||
fullCouponDeduction: isExchangeBetter ? 0 : nonExchangeResult.fullCouponDeduction, // 兑换券与满减券互斥,满减券抵扣置0
|
||||
deductionAmount: exchangeBn.plus(nonExchangeBn).toNumber(),
|
||||
productCouponDeduction: exchangeResult.deductionAmount,
|
||||
fullCouponDeduction: nonExchangeResult.deductionAmount, // 兑换券与满减券互斥,满减券抵扣置0
|
||||
usedCoupon: isExchangeBetter ? undefined : nonExchangeResult.usedCoupon,
|
||||
excludedProductIds: isExchangeBetter ? exchangeResult.excludedProductIds : nonExchangeResult.excludedProductIds
|
||||
};
|
||||
|
|
@ -1289,6 +1242,7 @@ export function calcTotalPackFee(
|
|||
goodsList: BaseCartItem[],
|
||||
dinnerType: 'dine-in' | 'take-out'
|
||||
): number {
|
||||
if (dinnerType !== 'take-out') return 0;
|
||||
let total = new BigNumber(0);
|
||||
|
||||
for (const goods of goodsList) {
|
||||
|
|
@ -1298,7 +1252,7 @@ export function calcTotalPackFee(
|
|||
// 计算单个商品打包数量(外卖全打包,堂食按配置,称重商品≤1)
|
||||
let packNum = dinnerType === 'take-out'
|
||||
? availableNum
|
||||
: (goods.packNumber || 0);
|
||||
: (0);
|
||||
if (goods.product_type === GoodsType.WEIGHT) {
|
||||
packNum = Math.min(packNum, 1);
|
||||
}
|
||||
|
|
@ -1415,8 +1369,11 @@ export function calculateOrderCostSummary(
|
|||
);
|
||||
|
||||
// 3. 其他费用计算(原有逻辑不变)
|
||||
// 新客立减
|
||||
const newUserDiscount = config.newUserDiscount || 0;
|
||||
const packFee = calcTotalPackFee(goodsList, dinnerType);
|
||||
const seatFee = calcSeatFee(config.seatFeeConfig);
|
||||
let seatFee = calcSeatFee(config.seatFeeConfig);
|
||||
seatFee = dinnerType === 'dine-in' ? seatFee : 0; // 外卖不收餐位费
|
||||
const additionalFee = Math.max(0, config.additionalFee);
|
||||
|
||||
// 4. 积分抵扣(原有逻辑不变,先于商家减免计算)
|
||||
|
|
@ -1475,6 +1432,7 @@ export function calculateOrderCostSummary(
|
|||
const finalPayAmount = new BigNumber(goodsOriginalAmount) // 商品原价总和
|
||||
.minus(goodsDiscountAmount) // 减去商品折扣
|
||||
.minus(couponDeductionAmount) // 减去优惠券抵扣
|
||||
.minus(newUserDiscount) // 新客立减
|
||||
.minus(pointDeductionAmount) // 减去积分抵扣
|
||||
.minus(merchantReductionActualAmount) // 减去商家实际减免金额
|
||||
.plus(seatFee) // 加上餐位费(不参与减免)
|
||||
|
|
@ -1503,7 +1461,9 @@ export function calculateOrderCostSummary(
|
|||
additionalFee,
|
||||
finalPayAmount: truncateToTwoDecimals(finalPayAmountNonNegative),
|
||||
couponUsed: usedCoupon,
|
||||
pointUsed: usedPoints
|
||||
pointUsed: usedPoints,
|
||||
newUserDiscount,
|
||||
dinnerType
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -1522,6 +1482,7 @@ export const OrderPriceCalculator = {
|
|||
isWeightGoods,
|
||||
// 优惠券转换
|
||||
convertBackendCouponToToolCoupon,
|
||||
mapBackendCouponTypeToTool,
|
||||
// 商品价格计算
|
||||
calcSingleGoodsRealPrice,
|
||||
calcGoodsOriginalAmount,
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ function handleSubmit() {
|
|||
} else {
|
||||
delete formData.id;
|
||||
|
||||
RoleApi.add({ ...formData, menuIdList: checkedMenuIds })
|
||||
RoleApi.add({ ...formData, menuIdList: [] })
|
||||
.then(() => {
|
||||
ElMessage.success("新增成功");
|
||||
handleCloseDialog();
|
||||
|
|
|
|||
|
|
@ -125,7 +125,9 @@
|
|||
<el-button
|
||||
type="primary"
|
||||
size="large"
|
||||
:disabled="!carts.isLinkFinshed || showOrder"
|
||||
:disabled="
|
||||
!carts.isLinkFinshed || showOrder || (carts.oldOrder.detailMap.length && !showOrder)
|
||||
"
|
||||
@click="createOrder('more-pay')"
|
||||
>
|
||||
更多支付
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-table ref="refTable" empty-text="无可用优惠券" :data="data" max-height="40vh">
|
||||
<el-table-column type="index" label="">
|
||||
<template v-slot="scope">
|
||||
<el-checkbox
|
||||
@change="couponClick($event, scope.row)"
|
||||
:model-value="scope.row.id == couponSel.id"
|
||||
></el-checkbox>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column type="index" 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 prop="discountAmount" label="抵扣" align="center">
|
||||
<template v-slot="scope">
|
||||
<span class="color-red">¥{{ scope.row.discountAmount }}</span>
|
||||
</template>
|
||||
</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>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="discountAmount" label="最大抵扣金额" align="center">
|
||||
<template v-slot="scope">
|
||||
<span class="color-red">¥{{ scope.row.maxDiscountAmount }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="discountAmount" label="限制" width="180">
|
||||
<template v-slot="scope">
|
||||
<div class="u-flex">
|
||||
<span>支付满</span>
|
||||
<span class="color-red no-wrap">
|
||||
{{ scope.row.fullAmount }}
|
||||
</span>
|
||||
<span>元可用</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="useRestrictions" label="描述"></el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import * as UTILS from "@/utils/coupon-utils.js";
|
||||
|
||||
defineProps({
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
couponSel: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const emits = defineEmits(["couponClick"]);
|
||||
|
||||
function couponClick(checked, row) {
|
||||
emit("couponClick", checked, row);
|
||||
}
|
||||
</script>
|
||||
|
|
@ -148,11 +148,12 @@ function init(key) {
|
|||
const emits = defineEmits(["confirm"]);
|
||||
function confirm() {
|
||||
console.log(form.value);
|
||||
if (discountType.value == 1) {
|
||||
emits("confirm", { discount: form.value.discount });
|
||||
} else {
|
||||
emits("confirm", { discountAmount: form.value.reduceMoney });
|
||||
}
|
||||
// if (discountType.value == 1) {
|
||||
// emits("confirm", { discount: form.value.discount });
|
||||
// } else {
|
||||
// }
|
||||
emits("confirm", { discountAmount: form.value.reduceMoney });
|
||||
|
||||
close();
|
||||
}
|
||||
function open(data) {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
v-if="score.sel == 1"
|
||||
v-model="usePointsNumber"
|
||||
step-strictly
|
||||
:step="pointsRes.equivalentPoints"
|
||||
placeholder="请输入积分抵扣数量"
|
||||
:min="pointsRes.minDeductionPoints"
|
||||
:max="pointsRes.maxUsablePoints"
|
||||
|
|
@ -80,9 +81,10 @@
|
|||
<el-icon><ArrowDown /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="u-m-t-20" v-if="quansSelArr.length > 0">
|
||||
{{ carts.orderCostSummary }}
|
||||
<div class="u-m-t-20" v-if="carts.coupons.length > 0">
|
||||
<div class="font-bold u-m-b-10">已选优惠券</div>
|
||||
<el-table empty-text="未选择优惠券" :data="quansSelArr">
|
||||
<el-table empty-text="未选择优惠券" :data="carts.coupons">
|
||||
<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">
|
||||
|
|
@ -294,8 +296,6 @@ function refCouponConfirm(e, goodsList) {
|
|||
quansSelArr.value = e;
|
||||
checkOrderPay.discountAmount = 0;
|
||||
checkOrderPay.discount = 0;
|
||||
score.sel = -1;
|
||||
usePointsNumber.value = 0;
|
||||
}
|
||||
function delQuan(row) {
|
||||
const index = quansSelArr.value.findIndex((v) => v.id == row.id);
|
||||
|
|
@ -340,8 +340,7 @@ function returnMerchantReductionDiscount() {
|
|||
const total =
|
||||
goodsOriginalAmount - // 商品原价总和
|
||||
goodsDiscountAmount - // 减去商品折扣
|
||||
couponDeductionAmount - // 减去优惠券抵扣
|
||||
pointDeductionAmount; // 减去积分抵扣
|
||||
couponDeductionAmount; // 减去优惠券抵扣
|
||||
|
||||
return total <= 0 ? 0 : total;
|
||||
}
|
||||
|
|
@ -436,7 +435,6 @@ async function pointsInit() {
|
|||
carts.pointDeductionRule.pointsPerYuan = res.equivalentPoints;
|
||||
|
||||
usePointsNumber.value = res.usable ? res.maxUsablePoints : 0;
|
||||
carts.userPoints = usePointsNumber.value;
|
||||
if (res.usable) {
|
||||
pointsToMoney();
|
||||
} else {
|
||||
|
|
@ -491,6 +489,12 @@ watch(
|
|||
pointsInit();
|
||||
}
|
||||
);
|
||||
watch(
|
||||
() => usePointsNumber.value,
|
||||
(newval) => {
|
||||
carts.userPoints = newval;
|
||||
}
|
||||
);
|
||||
function canUsePayType(item) {
|
||||
if (currentpayMoney.value * 1 == 0) {
|
||||
return item.payType == "cash" ? false : true;
|
||||
|
|
@ -512,6 +516,7 @@ function changePayType(i) {
|
|||
}
|
||||
|
||||
function returnPayParams() {
|
||||
console.log("carts.orderCostSummary", carts.orderCostSummary);
|
||||
return {
|
||||
money: currentpayMoney.value * 1,
|
||||
shopId: localStorage.getItem("shopId"),
|
||||
|
|
@ -522,17 +527,15 @@ function returnPayParams() {
|
|||
// discountRatio: (checkOrderPay.discount / 100).toFixed(2),
|
||||
discountRatio: 0,
|
||||
seatNum: props.perpole * 1,
|
||||
originAmount: carts.payMoney * 1 + seatAmount.value * 1,
|
||||
originAmount: carts.orderCostSummary.goodsRealAmount,
|
||||
discountAmount: discountAmount.value,
|
||||
productCouponDiscountAmount: productCouponDiscountAmount.value * 1,
|
||||
otherCouponDiscountAmount:
|
||||
carts.orderCostSummary.couponDeductionAmount - productCouponDiscountAmount.value * 1,
|
||||
orderAmount: currentpayMoney.value * 1,
|
||||
productCouponDiscountAmount: carts.orderCostSummary.productCouponDeduction,
|
||||
otherCouponDiscountAmount: carts.orderCostSummary.fullCouponDeduction,
|
||||
orderAmount: carts.orderCostSummary.finalPayAmount, // 最终订单金额
|
||||
roundAmount: props.orderInfo.roundAmount,
|
||||
pointsDiscountAmount: pointsDiscountAmount.value * 1,
|
||||
pointsNum: usePointsNumber.value * 1,
|
||||
fullCouponDiscountAmount: fullCouponDiscountAmount.value * 1,
|
||||
couponList: quansSelArr.value.map((v) => v.id),
|
||||
pointsDiscountAmount: carts.orderCostSummary.pointDeductionAmount, //积分抵扣金额
|
||||
pointsNum: carts.orderCostSummary.pointUsed,
|
||||
couponList: carts.coupons.map((v) => v.id),
|
||||
userId: props.user.userId || "",
|
||||
allPack: carts.dinnerType == "take-out" ? 1 : 0,
|
||||
},
|
||||
|
|
@ -667,11 +670,7 @@ const fullCouponDiscountAmount = computed(() => {
|
|||
//商品券抵扣金额
|
||||
const productCouponDiscountAmount = computed(() => {
|
||||
// 优先从 Store 扩展字段取,若无则用 props 数据(过渡方案)
|
||||
return (
|
||||
carts.orderCostSummary.productCouponDeduction ||
|
||||
props.orderInfo.productCouponDiscountAmount ||
|
||||
0
|
||||
);
|
||||
return carts.orderCostSummary.productCouponDeduction;
|
||||
});
|
||||
//除开客座费,打包费总金额
|
||||
const totalMoney = computed(() => {
|
||||
|
|
@ -717,6 +716,7 @@ watch(
|
|||
}
|
||||
);
|
||||
onMounted(() => {
|
||||
carts.payParamsInit();
|
||||
getPaytype();
|
||||
});
|
||||
defineExpose({
|
||||
|
|
|
|||
|
|
@ -4,7 +4,12 @@
|
|||
<div class="">
|
||||
<el-tabs v-model="activeName" @tab-click="tabClick">
|
||||
<el-tab-pane label="优惠券(单选)" name="youhui">
|
||||
<el-table ref="refTable" empty-text="无可用优惠券" :data="quans.coupon">
|
||||
<el-table
|
||||
ref="refTable"
|
||||
empty-text="无可用优惠券"
|
||||
:data="quans.coupon"
|
||||
max-height="40vh"
|
||||
>
|
||||
<el-table-column type="index" label="">
|
||||
<template v-slot="scope">
|
||||
<el-checkbox
|
||||
|
|
@ -50,6 +55,7 @@
|
|||
empty-text="无可用商品券"
|
||||
:data="quans.productCoupon"
|
||||
style="width: 100%"
|
||||
max-height="40vh"
|
||||
>
|
||||
<el-table-column width="80">
|
||||
<template v-slot="scope">
|
||||
|
|
@ -103,7 +109,7 @@
|
|||
</el-tabs>
|
||||
<div v-if="quansSelArr.length > 0">
|
||||
<div class="font-bold u-m-b-10">已选优惠券</div>
|
||||
<el-table empty-text="未选择优惠券" :data="quansSelArr">
|
||||
<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">
|
||||
|
|
@ -171,11 +177,12 @@
|
|||
</template>
|
||||
<script setup>
|
||||
import couponApi from "@/api/account/coupon";
|
||||
import { OrderPriceCalculator } from "@/utils/goods";
|
||||
import { BigNumber } from "bignumber.js";
|
||||
import * as UTILS from "@/utils/goods-utils.js";
|
||||
import * as UTILS from "@/utils/coupon-utils.js";
|
||||
import { ElMessageBox } from "element-plus";
|
||||
import * as quanUtil from "../quan_util.js";
|
||||
import { useUserStoreHook } from "@/store/modules/user";
|
||||
const shopUser = useUserStoreHook();
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
|
|
@ -260,13 +267,15 @@ async function getcoup() {
|
|||
quans.value.coupon = res
|
||||
.filter((v) => v.type != 2)
|
||||
.filter((coupon) => {
|
||||
return UTILS.returnCouponCanUse({
|
||||
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(
|
||||
|
|
@ -274,7 +283,8 @@ async function getcoup() {
|
|||
v,
|
||||
props.user,
|
||||
orderPrice.value,
|
||||
quansSelArr.value
|
||||
quansSelArr.value,
|
||||
shopUser.userInfo
|
||||
);
|
||||
return {
|
||||
...v,
|
||||
|
|
@ -285,13 +295,15 @@ async function getcoup() {
|
|||
quans.value.productCoupon = res
|
||||
.filter((v) => v.type == 2)
|
||||
.filter((coupon) => {
|
||||
return UTILS.returnCouponCanUse({
|
||||
const { canUse, msg } = UTILS.returnCouponCanUse({
|
||||
canDikouGoodsArr,
|
||||
coupon,
|
||||
orderPrice: orderPrice.value,
|
||||
user: props.user,
|
||||
selCoupon: [],
|
||||
selCoupon: quansSelArr.value,
|
||||
shopInfo: shopUser.userInfo,
|
||||
});
|
||||
return canUse;
|
||||
})
|
||||
.map((v) => {
|
||||
const findGoods = goodsArr.find((goods) => goods.productId == v.proId);
|
||||
|
|
@ -300,7 +312,8 @@ async function getcoup() {
|
|||
v,
|
||||
props.user,
|
||||
orderPrice.value,
|
||||
[]
|
||||
quansSelArr.value,
|
||||
shopUser.userInfo
|
||||
);
|
||||
return {
|
||||
...v,
|
||||
|
|
|
|||
|
|
@ -495,6 +495,7 @@ async function clearOldOrder(params) {
|
|||
type: res1 ? "success" : "error",
|
||||
message: res1 ? "删除成功" : "删除失败",
|
||||
});
|
||||
showOrder.value = false;
|
||||
clearOldOrderCallback();
|
||||
} catch (error) {
|
||||
clearOldOrderCallback();
|
||||
|
|
|
|||
Loading…
Reference in New Issue