点餐页面限时折扣回显问题修复
This commit is contained in:
@@ -91,6 +91,10 @@
|
||||
<script setup>
|
||||
import * as distributionApi from "@/common/api/market/distribution.js";
|
||||
import { productStore } from "@/stores/user.js";
|
||||
import {
|
||||
APIuserlogin,
|
||||
APIuser
|
||||
} from "@/common/api/api.js";
|
||||
const storeuser = productStore();
|
||||
import { ref, onMounted, reactive } from "vue";
|
||||
import { onLoad, onReachBottom, onShow } from "@dcloudio/uni-app";
|
||||
@@ -222,7 +226,7 @@ onLoad(() => {
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
storeuser.actionsAPIuser().then((res) => {
|
||||
APIuser.then((res) => {
|
||||
userinfo.value = res;
|
||||
});
|
||||
});
|
||||
|
||||
307
lib/goods.ts
307
lib/goods.ts
@@ -49,9 +49,9 @@ import {
|
||||
* @returns 是否在时段内
|
||||
*/
|
||||
function isInDailyTimeRange(
|
||||
activity: FullReductionActivity,
|
||||
currentTime: Date
|
||||
): boolean {
|
||||
activity : FullReductionActivity,
|
||||
currentTime : Date
|
||||
) : boolean {
|
||||
// 全时段无需校验
|
||||
if (activity.useTimeType === "all") return true;
|
||||
// 无时段配置则不通过
|
||||
@@ -82,9 +82,9 @@ function isInDailyTimeRange(
|
||||
* @returns 是否在周期内
|
||||
*/
|
||||
function isInWeeklyCycle(
|
||||
activity: FullReductionActivity,
|
||||
currentTime: Date
|
||||
): boolean {
|
||||
activity : FullReductionActivity,
|
||||
currentTime : Date
|
||||
) : boolean {
|
||||
// 无周期配置则不通过
|
||||
if (!activity.useDays) return false;
|
||||
const currentWeekday = currentTime.getDay(); // 0=周日,1=周一...6=周六
|
||||
@@ -101,9 +101,9 @@ function isInWeeklyCycle(
|
||||
* @returns 是否匹配
|
||||
*/
|
||||
function isDinnerTypeMatch(
|
||||
activity: FullReductionActivity,
|
||||
currentDinnerType: string
|
||||
): boolean {
|
||||
activity : FullReductionActivity,
|
||||
currentDinnerType : string
|
||||
) : boolean {
|
||||
if (!activity.useType) return false;
|
||||
const allowedTypes = activity.useType.split(",");
|
||||
//满减活动的就餐类型和当前券类型字段值不一样,暂时返回true
|
||||
@@ -112,12 +112,12 @@ function isDinnerTypeMatch(
|
||||
|
||||
//判断商品是否可以使用限时折扣
|
||||
export function returnCanUseLimitTimeDiscount(
|
||||
goods: BaseCartItem,
|
||||
limitTimeDiscount: TimeLimitDiscountConfig | null | undefined,
|
||||
useVipPrice: boolean,
|
||||
goods : BaseCartItem,
|
||||
limitTimeDiscount : TimeLimitDiscountConfig | null | undefined,
|
||||
useVipPrice : boolean,
|
||||
idKey = "product_id"
|
||||
) {
|
||||
goods={...goods,product_id:goods.product_id||goods.productId|| goods.id|| ''}
|
||||
goods = { ...goods, product_id: goods.product_id || goods.productId || goods.id || '' }
|
||||
if (!limitTimeDiscount || !limitTimeDiscount.id) {
|
||||
return false;
|
||||
}
|
||||
@@ -137,10 +137,10 @@ export function returnCanUseLimitTimeDiscount(
|
||||
}
|
||||
if (useVipPrice && goods.hasOwnProperty("memberPrice")) {
|
||||
|
||||
if ( goods.memberPrice * 1 <= 0) {
|
||||
if (goods.memberPrice * 1 <= 0) {
|
||||
|
||||
return true;
|
||||
}else{
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -149,7 +149,7 @@ export function returnCanUseLimitTimeDiscount(
|
||||
return false;
|
||||
}
|
||||
|
||||
function returnMemberPrice(useVipPrice: boolean, goods: BaseCartItem) {
|
||||
function returnMemberPrice(useVipPrice : boolean, goods : BaseCartItem) {
|
||||
if (useVipPrice) {
|
||||
return goods.memberPrice || goods.salePrice;
|
||||
} else {
|
||||
@@ -161,9 +161,9 @@ function returnMemberPrice(useVipPrice: boolean, goods: BaseCartItem) {
|
||||
* 返回商品限时折扣价格
|
||||
*/
|
||||
function returnLimitPrice(
|
||||
goods: BaseCartItem,
|
||||
limitTimeDiscount: TimeLimitDiscountConfig | null | undefined,
|
||||
useVipPrice: boolean
|
||||
goods : BaseCartItem,
|
||||
limitTimeDiscount : TimeLimitDiscountConfig | null | undefined,
|
||||
useVipPrice : boolean
|
||||
) {
|
||||
if (!limitTimeDiscount) {
|
||||
return 0;
|
||||
@@ -171,10 +171,10 @@ function returnLimitPrice(
|
||||
const discountRate = new BigNumber(limitTimeDiscount.discountRate).dividedBy(
|
||||
100
|
||||
);
|
||||
let canuseLimit=false;
|
||||
if(goods.hasOwnProperty('isTimeDiscount')||goods.hasOwnProperty('is_time_discount')){
|
||||
canuseLimit=goods.isTimeDiscount?true:goods.is_time_discount?true:false;
|
||||
}else{
|
||||
let canuseLimit = false;
|
||||
if (goods.hasOwnProperty('isTimeDiscount') || goods.hasOwnProperty('is_time_discount')) {
|
||||
canuseLimit = goods.isTimeDiscount ? true : goods.is_time_discount ? true : false;
|
||||
} else {
|
||||
canuseLimit = returnCanUseLimitTimeDiscount(
|
||||
goods,
|
||||
limitTimeDiscount,
|
||||
@@ -182,33 +182,15 @@ function returnLimitPrice(
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (canuseLimit) {
|
||||
//可以使用限时折扣
|
||||
if (limitTimeDiscount.discountPriority == "limit-time") {
|
||||
//限时价优先
|
||||
const result = BigNumber(goods.salePrice)
|
||||
.times(discountRate)
|
||||
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||
.toNumber();
|
||||
return result;
|
||||
}
|
||||
if (limitTimeDiscount.discountPriority == "vip-price") {
|
||||
|
||||
//会员价优先
|
||||
if (useVipPrice && goods.memberPrice && goods.memberPrice * 1 > 0) {
|
||||
//使用会员价
|
||||
return returnMemberPrice(useVipPrice, goods);
|
||||
} else {
|
||||
//不使用会员价
|
||||
const result = BigNumber(goods.salePrice)
|
||||
.times(discountRate)
|
||||
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||
.toNumber();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//不可以使用限时折扣
|
||||
//会员价优先
|
||||
if (useVipPrice) {
|
||||
//使用会员价
|
||||
@@ -216,7 +198,6 @@ function returnLimitPrice(
|
||||
} else {
|
||||
return goods.salePrice;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -224,10 +205,10 @@ function returnLimitPrice(
|
||||
*/
|
||||
|
||||
export function returnCalcPrice(
|
||||
goods: BaseCartItem,
|
||||
fullReductionActivitie: FullReductionActivity | undefined,
|
||||
limitTimeDiscount: TimeLimitDiscountConfig | null | undefined,
|
||||
useVipPrice: boolean,
|
||||
goods : BaseCartItem,
|
||||
fullReductionActivitie : FullReductionActivity | undefined,
|
||||
limitTimeDiscount : TimeLimitDiscountConfig | null | undefined,
|
||||
useVipPrice : boolean,
|
||||
idKey = "product_id"
|
||||
) {
|
||||
if (goods.discountSaleAmount && goods.discountSaleAmount * 1 > 0) {
|
||||
@@ -278,20 +259,20 @@ export function returnCalcPrice(
|
||||
* 计算满减活动门槛
|
||||
*/
|
||||
export function calcFullReductionActivityFullAmount(
|
||||
goodsList: BaseCartItem[],
|
||||
fullReductionActivitie: FullReductionActivity | undefined,
|
||||
limitTimeDiscount: TimeLimitDiscountConfig | null | undefined,
|
||||
useVipPrice: boolean,
|
||||
seatFee: number,
|
||||
packFee: number
|
||||
): number {
|
||||
goodsList : BaseCartItem[],
|
||||
fullReductionActivitie : FullReductionActivity | undefined,
|
||||
limitTimeDiscount : TimeLimitDiscountConfig | null | undefined,
|
||||
useVipPrice : boolean,
|
||||
seatFee : number,
|
||||
packFee : number
|
||||
) : number {
|
||||
if (!fullReductionActivitie) {
|
||||
return 0;
|
||||
}
|
||||
let amount = 0;
|
||||
for (let goods of goodsList) {
|
||||
const availableNum = Math.max(0, goods.number - (goods.returnNum || 0));
|
||||
if (goods.is_temporary ||goods.isTemporary || goods.is_gift ||goods.isGift || availableNum <= 0) {
|
||||
if (goods.is_temporary || goods.isTemporary || goods.is_gift || goods.isGift || availableNum <= 0) {
|
||||
//临时菜,赠菜,数量<=0的商品不计算
|
||||
continue;
|
||||
}
|
||||
@@ -302,6 +283,8 @@ export function calcFullReductionActivityFullAmount(
|
||||
useVipPrice,
|
||||
"product_id"
|
||||
);
|
||||
console.log('calcPrice', calcPrice);
|
||||
console.log('goods', goods);
|
||||
if (calcPrice !== undefined) {
|
||||
amount += calcPrice * availableNum;
|
||||
}
|
||||
@@ -318,11 +301,11 @@ export function calcFullReductionActivityFullAmount(
|
||||
* @returns 最优满减活动(无符合条件则返回undefined)
|
||||
*/
|
||||
export function filterOptimalFullReductionActivity(
|
||||
activities: FullReductionActivity[],
|
||||
currentShopId: number,
|
||||
currentDinnerType: string,
|
||||
currentTime: Date = new Date()
|
||||
): FullReductionActivity | undefined {
|
||||
activities : FullReductionActivity[],
|
||||
currentShopId : number,
|
||||
currentDinnerType : string,
|
||||
currentTime : Date = new Date()
|
||||
) : FullReductionActivity | undefined {
|
||||
if (!activities || !activities.length) return undefined;
|
||||
// 第一步:基础筛选(未删除+当前店铺+活动进行中+就餐类型匹配)
|
||||
const baseEligible = activities.filter((activity) => {
|
||||
@@ -376,7 +359,7 @@ export function filterOptimalFullReductionActivity(
|
||||
/**
|
||||
* 折扣率格式化:后端discountRate(%)→ 工具库小数(如90→0.9)
|
||||
*/
|
||||
export function formatDiscountRate(backendDiscountRate?: number): number {
|
||||
export function formatDiscountRate(backendDiscountRate ?: number) : number {
|
||||
if (!backendDiscountRate || backendDiscountRate <= 0) return 1; // 默认无折扣(1=100%)
|
||||
// 后端若为百分比(如90=9折),除以100;若已为小数(如0.9)直接返回
|
||||
return backendDiscountRate >= 1
|
||||
@@ -390,7 +373,7 @@ export function formatDiscountRate(backendDiscountRate?: number): number {
|
||||
* @param num 待处理数字
|
||||
* @returns 处理后保留两位小数的数字
|
||||
*/
|
||||
export function truncateToTwoDecimals(num: number | string): number {
|
||||
export function truncateToTwoDecimals(num : number | string) : number {
|
||||
return new BigNumber(num).decimalPlaces(2, BigNumber.ROUND_DOWN).toNumber();
|
||||
}
|
||||
|
||||
@@ -399,8 +382,8 @@ export function truncateToTwoDecimals(num: number | string): number {
|
||||
* @param goods 商品项
|
||||
* @returns 是否临时菜
|
||||
*/
|
||||
export function isTemporaryGoods(goods: BaseCartItem): boolean {
|
||||
return !!goods.is_temporary|| !!goods.isTemporary;
|
||||
export function isTemporaryGoods(goods : BaseCartItem) : boolean {
|
||||
return !!goods.is_temporary || !!goods.isTemporary;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -408,13 +391,13 @@ export function isTemporaryGoods(goods: BaseCartItem): boolean {
|
||||
* @param goods 商品项
|
||||
* @returns 是否赠菜
|
||||
*/
|
||||
export function isGiftGoods(goods: BaseCartItem): boolean {
|
||||
export function isGiftGoods(goods : BaseCartItem) : boolean {
|
||||
return !!goods.is_gift || !!goods.isGift;
|
||||
}
|
||||
/**
|
||||
* 判断可用类型是否可用
|
||||
*/
|
||||
export function useTypeCanUse(useType: string[]) {
|
||||
export function useTypeCanUse(useType : string[]) {
|
||||
const arr = ["all", "dine-in", "take-out", "take-away", "post"];
|
||||
return useType.some((item) => arr.includes(item));
|
||||
}
|
||||
@@ -427,10 +410,10 @@ export function useTypeCanUse(useType: string[]) {
|
||||
* @returns 会员价(元)
|
||||
*/
|
||||
export function calcMemberPrice(
|
||||
goods: BaseCartItem,
|
||||
isMember: boolean,
|
||||
memberDiscountRate?: number
|
||||
): number {
|
||||
goods : BaseCartItem,
|
||||
isMember : boolean,
|
||||
memberDiscountRate ?: number
|
||||
) : number {
|
||||
if (!isMember) return truncateToTwoDecimals(goods.salePrice);
|
||||
|
||||
// 优先级:SKU会员价 > 商品会员价 > 商品原价(无会员价时用会员折扣)
|
||||
@@ -452,9 +435,9 @@ export function calcMemberPrice(
|
||||
* @returns 可参与优惠券计算的商品列表
|
||||
*/
|
||||
export function filterCouponEligibleGoods(
|
||||
goodsList: BaseCartItem[],
|
||||
excludedProductIds: string[] = []
|
||||
): BaseCartItem[] {
|
||||
goodsList : BaseCartItem[],
|
||||
excludedProductIds : string[] = []
|
||||
) : BaseCartItem[] {
|
||||
return goodsList.filter(
|
||||
(goods) =>
|
||||
!isTemporaryGoods(goods) &&
|
||||
@@ -470,9 +453,9 @@ export function filterCouponEligibleGoods(
|
||||
* @returns 最终参与优惠券计算的商品列表
|
||||
*/
|
||||
export function filterThresholdGoods(
|
||||
baseEligibleGoods: BaseCartItem[],
|
||||
applicableProductIds: string[]
|
||||
): BaseCartItem[] {
|
||||
baseEligibleGoods : BaseCartItem[],
|
||||
applicableProductIds : string[]
|
||||
) : BaseCartItem[] {
|
||||
// 空数组=全部基础合格商品;非空=仅商品ID匹配的商品(转字符串兼容类型)
|
||||
return applicableProductIds.length === 0
|
||||
? baseEligibleGoods
|
||||
@@ -489,10 +472,10 @@ export function filterThresholdGoods(
|
||||
* @returns 排序后的商品列表
|
||||
*/
|
||||
export function sortGoodsForCoupon(
|
||||
goodsList: BaseCartItem[],
|
||||
sortRule: "low_price_first" | "high_price_first",
|
||||
cartOrder: Record<string, number> = {}
|
||||
): BaseCartItem[] {
|
||||
goodsList : BaseCartItem[],
|
||||
sortRule : "low_price_first" | "high_price_first",
|
||||
cartOrder : Record<string, number> = {}
|
||||
) : BaseCartItem[] {
|
||||
return [...goodsList].sort((a, b) => {
|
||||
// 1. 按商品单价排序(优先级最高)
|
||||
const priceA = a.skuData?.salePrice ?? a.salePrice;
|
||||
@@ -522,11 +505,11 @@ export function sortGoodsForCoupon(
|
||||
* @returns 满足优惠券门槛的金额基数
|
||||
*/
|
||||
export function calcCouponThresholdAmount(
|
||||
eligibleGoods: BaseCartItem[],
|
||||
coupon: BaseCoupon,
|
||||
config: Pick<OrderExtraConfig, "isMember" | "memberDiscountRate">,
|
||||
activities: ActivityConfig[] = []
|
||||
): number {
|
||||
eligibleGoods : BaseCartItem[],
|
||||
coupon : BaseCoupon,
|
||||
config : Pick<OrderExtraConfig, "isMember" | "memberDiscountRate">,
|
||||
activities : ActivityConfig[] = []
|
||||
) : number {
|
||||
let total = new BigNumber(0);
|
||||
|
||||
for (const goods of eligibleGoods) {
|
||||
@@ -576,16 +559,16 @@ export function calcCouponThresholdAmount(
|
||||
* @returns 单个商品实际单价(元)
|
||||
*/
|
||||
export function calcSingleGoodsRealPrice(
|
||||
goods: BaseCartItem,
|
||||
config: Pick<
|
||||
goods : BaseCartItem,
|
||||
config : Pick<
|
||||
OrderExtraConfig,
|
||||
"isMember" | "memberDiscountRate" | "limitTimeDiscount"
|
||||
>
|
||||
): number {
|
||||
) : number {
|
||||
const { isMember, memberDiscountRate, limitTimeDiscount: activity } = config;
|
||||
|
||||
//如果是增菜价格为0
|
||||
if (goods.is_gift||goods.isGift) {
|
||||
if (goods.is_gift || goods.isGift) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -599,17 +582,17 @@ export function calcSingleGoodsRealPrice(
|
||||
calcMemberPrice(goods, isMember, memberDiscountRate)
|
||||
);
|
||||
|
||||
if(goods.is_time_discount||goods.isTimeDiscount){
|
||||
console.log('限时折扣',activity)
|
||||
console.log('goods',goods)
|
||||
if (goods.is_time_discount || goods.isTimeDiscount) {
|
||||
console.log('限时折扣', activity)
|
||||
console.log('goods', goods)
|
||||
//限时折扣优先
|
||||
const limitPrice= truncateToTwoDecimals(
|
||||
const limitPrice = truncateToTwoDecimals(
|
||||
new BigNumber(goods.salePrice)
|
||||
.times((activity?activity.discountRate:100) / 100)
|
||||
.times((activity ? activity.discountRate : 100) / 100)
|
||||
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||
.toNumber()
|
||||
);
|
||||
console.log('limitPrice',limitPrice)
|
||||
console.log('limitPrice', limitPrice)
|
||||
return limitPrice;
|
||||
}
|
||||
// 3. 优先级3:营销活动折扣(如限时折扣,需按商品ID匹配活动)
|
||||
@@ -676,15 +659,15 @@ export function calcSingleGoodsRealPrice(
|
||||
* @param goodsList 商品列表
|
||||
* @returns 商品原价总和(元)
|
||||
*/
|
||||
export function calcGoodsOriginalAmount(goodsList: BaseCartItem[]): number {
|
||||
export function calcGoodsOriginalAmount(goodsList : BaseCartItem[]) : number {
|
||||
let total = new BigNumber(0);
|
||||
|
||||
for (const goods of goodsList) {
|
||||
const availableNum = Math.max(0, goods.number - (goods.returnNum || 0));
|
||||
let basePrice = new BigNumber(0);
|
||||
if (goods.is_temporary||goods.isTemporary) {
|
||||
if (goods.is_temporary || goods.isTemporary) {
|
||||
basePrice = new BigNumber(goods?.discountSaleAmount ?? 0);
|
||||
} else if (goods.is_gift||goods.isGift) {
|
||||
} else if (goods.is_gift || goods.isGift) {
|
||||
basePrice = new BigNumber(0);
|
||||
} else {
|
||||
basePrice = new BigNumber(goods.skuData?.salePrice ?? goods.salePrice); // SKU原价优先
|
||||
@@ -704,20 +687,20 @@ export function calcGoodsOriginalAmount(goodsList: BaseCartItem[]): number {
|
||||
* @returns 商品实际总价(元)
|
||||
*/
|
||||
export function calcGoodsRealAmount(
|
||||
goodsList: BaseCartItem[],
|
||||
config: Pick<
|
||||
goodsList : BaseCartItem[],
|
||||
config : Pick<
|
||||
OrderExtraConfig,
|
||||
"isMember" | "memberDiscountRate" | "limitTimeDiscount"
|
||||
>
|
||||
): number {
|
||||
) : number {
|
||||
let total = new BigNumber(0);
|
||||
|
||||
for (const goods of goodsList) {
|
||||
const availableNum = Math.max(0, goods.number - (goods.returnNum || 0));
|
||||
if (availableNum <= 0) continue;
|
||||
const realPrice = new BigNumber(calcSingleGoodsRealPrice(goods, config));
|
||||
console.log('goods',goods);
|
||||
console.log('realPrice',realPrice.toNumber());
|
||||
console.log('goods', goods);
|
||||
console.log('realPrice', realPrice.toNumber());
|
||||
total = total.plus(realPrice.multipliedBy(availableNum));
|
||||
}
|
||||
|
||||
@@ -731,9 +714,9 @@ export function calcGoodsRealAmount(
|
||||
* @returns 商品折扣总金额(元,≥0)
|
||||
*/
|
||||
export function calcGoodsDiscountAmount(
|
||||
goodsOriginalAmount: number,
|
||||
goodsRealAmount: number
|
||||
): number {
|
||||
goodsOriginalAmount : number,
|
||||
goodsRealAmount : number
|
||||
) : number {
|
||||
const original = new BigNumber(goodsOriginalAmount);
|
||||
const real = new BigNumber(goodsRealAmount);
|
||||
const discount = original.minus(real);
|
||||
@@ -750,12 +733,12 @@ export function calcGoodsDiscountAmount(
|
||||
* @returns 最优阈值(无符合条件则返回undefined)
|
||||
*/
|
||||
export function selectOptimalThreshold(
|
||||
thresholds: FullReductionThreshold[] = [],
|
||||
baseAmount: number,
|
||||
goodsOriginalAmount: number,
|
||||
goodsRealAmount: number,
|
||||
discountShare: number = 0
|
||||
): FullReductionThreshold | undefined {
|
||||
thresholds : FullReductionThreshold[] = [],
|
||||
baseAmount : number,
|
||||
goodsOriginalAmount : number,
|
||||
goodsRealAmount : number,
|
||||
discountShare : number = 0
|
||||
) : FullReductionThreshold | undefined {
|
||||
if (!thresholds.length) return undefined;
|
||||
|
||||
// 第一步:确定满减门槛基数(根据discountShare规则)
|
||||
@@ -797,10 +780,10 @@ export function selectOptimalThreshold(
|
||||
* @returns 实际减免金额(元,未达门槛则0)
|
||||
*/
|
||||
export function calcFullReductionAmount(
|
||||
baseAmount: number,
|
||||
optimalActivity?: FullReductionActivity,
|
||||
optimalThreshold?: FullReductionThreshold
|
||||
): number {
|
||||
baseAmount : number,
|
||||
optimalActivity ?: FullReductionActivity,
|
||||
optimalThreshold ?: FullReductionThreshold
|
||||
) : number {
|
||||
if (!optimalActivity || !optimalThreshold) return 0;
|
||||
|
||||
const baseAmountBn = new BigNumber(baseAmount);
|
||||
@@ -823,9 +806,9 @@ export function calcFullReductionAmount(
|
||||
* 根据优惠券useShops列表判断门店是否匹配(适配BaseCoupon的useShops字段)
|
||||
*/
|
||||
function isStoreMatchByList(
|
||||
useShops: string[],
|
||||
currentStoreId: string
|
||||
): boolean {
|
||||
useShops : string[],
|
||||
currentStoreId : string
|
||||
) : boolean {
|
||||
// 适用门店为空数组 → 无限制(所有门店适用)
|
||||
if (useShops.length === 0) return true;
|
||||
// 匹配当前门店ID(字符串比较,避免类型问题)
|
||||
@@ -840,30 +823,30 @@ function isStoreMatchByList(
|
||||
* @returns 最优优惠券的抵扣结果(含商品券/满减券细分)
|
||||
*/
|
||||
export function calcCouponDeduction(
|
||||
backendCoupons: BackendCoupon[],
|
||||
goodsList: BaseCartItem[],
|
||||
config: Pick<
|
||||
backendCoupons : BackendCoupon[],
|
||||
goodsList : BaseCartItem[],
|
||||
config : Pick<
|
||||
OrderExtraConfig,
|
||||
"currentStoreId" | "isMember" | "memberDiscountRate"
|
||||
> & {
|
||||
activities: ActivityConfig[];
|
||||
cartOrder: Record<string, number>;
|
||||
dinnerType: "dine-in" | "take-out";
|
||||
currentTime?: Date;
|
||||
activities : ActivityConfig[];
|
||||
cartOrder : Record<string, number>;
|
||||
dinnerType : "dine-in" | "take-out";
|
||||
currentTime ?: Date;
|
||||
}
|
||||
): {
|
||||
deductionAmount: number;
|
||||
productCouponDeduction: number; // 新增:商品优惠券抵扣(兑换券/折扣券/买一送一等)
|
||||
fullCouponDeduction: number; // 新增:满减优惠券抵扣
|
||||
usedCoupon?: Coupon;
|
||||
excludedProductIds: string[]; // 排除的商品ID列表(商品ID)
|
||||
) : {
|
||||
deductionAmount : number;
|
||||
productCouponDeduction : number; // 新增:商品优惠券抵扣(兑换券/折扣券/买一送一等)
|
||||
fullCouponDeduction : number; // 新增:满减优惠券抵扣
|
||||
usedCoupon ?: Coupon;
|
||||
excludedProductIds : string[]; // 排除的商品ID列表(商品ID)
|
||||
} {
|
||||
const goodsCoupon = backendCoupons.filter((v) => v.type == 2);
|
||||
const discountCoupon = backendCoupons.filter((v) => v.type != 2);
|
||||
|
||||
// 3. 计算非兑换券最优抵扣(传递已抵扣商品ID,避免重复,统计细分字段)
|
||||
let nonExchangeResult: CouponResult = {
|
||||
deductionAmount: discountCoupon.reduce((prve, cur): number => {
|
||||
let nonExchangeResult : CouponResult = {
|
||||
deductionAmount: discountCoupon.reduce((prve, cur) : number => {
|
||||
return prve + (cur.discountAmount || 0);
|
||||
}, 0),
|
||||
excludedProductIds: [],
|
||||
@@ -873,8 +856,8 @@ export function calcCouponDeduction(
|
||||
};
|
||||
|
||||
// 4. 计算兑换券抵扣(排除非兑换券已抵扣的商品ID,统计商品券细分)
|
||||
let exchangeResult: ExchangeCalculationResult = {
|
||||
deductionAmount: goodsCoupon.reduce((prve, cur): number => {
|
||||
let exchangeResult : ExchangeCalculationResult = {
|
||||
deductionAmount: goodsCoupon.reduce((prve, cur) : number => {
|
||||
return prve + (cur.discountAmount || 0);
|
||||
}, 0),
|
||||
excludedProductIds: [],
|
||||
@@ -905,9 +888,9 @@ export function calcCouponDeduction(
|
||||
* @returns 总打包费(元)
|
||||
*/
|
||||
export function calcTotalPackFee(
|
||||
goodsList: BaseCartItem[],
|
||||
dinnerType: "dine-in" | "take-out"
|
||||
): number {
|
||||
goodsList : BaseCartItem[],
|
||||
dinnerType : "dine-in" | "take-out"
|
||||
) : number {
|
||||
// if (dinnerType !== "take-out") return 0;
|
||||
let total = new BigNumber(0);
|
||||
|
||||
@@ -937,7 +920,7 @@ export function calcTotalPackFee(
|
||||
* @param config 餐位费配置
|
||||
* @returns 餐位费(元,未启用则0)
|
||||
*/
|
||||
export function calcSeatFee(config: SeatFeeConfig): number {
|
||||
export function calcSeatFee(config : SeatFeeConfig) : number {
|
||||
if (!config.isEnabled || config.personCount == 0) return 0;
|
||||
const personCount = Math.max(1, config.personCount); // 至少1人
|
||||
return truncateToTwoDecimals(
|
||||
@@ -953,12 +936,12 @@ export function calcSeatFee(config: SeatFeeConfig): number {
|
||||
* @returns 积分抵扣金额 + 实际使用积分
|
||||
*/
|
||||
export function calcPointDeduction(
|
||||
userPoints: number,
|
||||
rule: PointDeductionRule,
|
||||
maxDeductionLimit: number
|
||||
): {
|
||||
deductionAmount: number;
|
||||
usedPoints: number;
|
||||
userPoints : number,
|
||||
rule : PointDeductionRule,
|
||||
maxDeductionLimit : number
|
||||
) : {
|
||||
deductionAmount : number;
|
||||
usedPoints : number;
|
||||
} {
|
||||
if (rule.pointsPerYuan <= 0 || userPoints <= 0) {
|
||||
return { deductionAmount: 0, usedPoints: 0 };
|
||||
@@ -990,9 +973,9 @@ export function calcPointDeduction(
|
||||
}
|
||||
|
||||
function calcVipDiscountAmount(
|
||||
goodsRealAmount: number,
|
||||
shopUserInfo: ShopUserInfo
|
||||
): number {
|
||||
goodsRealAmount : number,
|
||||
shopUserInfo : ShopUserInfo
|
||||
) : number {
|
||||
if (!shopUserInfo.isVip || shopUserInfo.discount === 0) return 0;
|
||||
if (shopUserInfo.isVip == 1 && shopUserInfo.isMemberPrice != 1) {
|
||||
return 0;
|
||||
@@ -1018,14 +1001,14 @@ function calcVipDiscountAmount(
|
||||
* @returns 订单费用汇总(含所有子项和实付金额,新增商品券/满减券细分)
|
||||
*/
|
||||
export function calculateOrderCostSummary(
|
||||
goodsList: BaseCartItem[],
|
||||
dinnerType: "dine-in" | "take-out", // 前端就餐类型
|
||||
backendCoupons: BackendCoupon[] = [],
|
||||
activities: ActivityConfig[] = [],
|
||||
config: OrderExtraConfig, // 含后端满减活动、currentDinnerType
|
||||
cartOrder: Record<string, number> = {},
|
||||
currentTime: Date = new Date()
|
||||
): OrderCostSummary {
|
||||
goodsList : BaseCartItem[],
|
||||
dinnerType : "dine-in" | "take-out", // 前端就餐类型
|
||||
backendCoupons : BackendCoupon[] = [],
|
||||
activities : ActivityConfig[] = [],
|
||||
config : OrderExtraConfig, // 含后端满减活动、currentDinnerType
|
||||
cartOrder : Record<string, number> = {},
|
||||
currentTime : Date = new Date()
|
||||
) : OrderCostSummary {
|
||||
//是否使用霸王餐,霸王餐配置
|
||||
const {
|
||||
isFreeDine,
|
||||
@@ -1060,8 +1043,8 @@ export function calculateOrderCostSummary(
|
||||
const additionalFee = Math.max(0, config.additionalFee); // 附加费
|
||||
|
||||
// ------------------------------ 2. 满减活动计算(核心步骤) ------------------------------
|
||||
let usedFullReductionActivity: FullReductionActivity | undefined;
|
||||
let usedFullReductionThreshold: FullReductionThreshold | undefined;
|
||||
let usedFullReductionActivity : FullReductionActivity | undefined;
|
||||
let usedFullReductionThreshold : FullReductionThreshold | undefined;
|
||||
let fullReductionAmount = 0;
|
||||
let usedFullReductionActivityFullAmount = calcFullReductionActivityFullAmount(
|
||||
goodsList,
|
||||
@@ -1127,8 +1110,8 @@ export function calculateOrderCostSummary(
|
||||
let couponDeductionAmount = 0;
|
||||
let productCouponDeduction = 0;
|
||||
let fullCouponDeduction = 0;
|
||||
let usedCoupon: Coupon | undefined;
|
||||
let excludedProductIds: string[] = [];
|
||||
let usedCoupon : Coupon | undefined;
|
||||
let excludedProductIds : string[] = [];
|
||||
|
||||
const couponResult = calcCouponDeduction(
|
||||
// 原有优惠券计算函数
|
||||
@@ -1349,7 +1332,7 @@ export function calculateOrderCostSummary(
|
||||
};
|
||||
}
|
||||
|
||||
export function isWeightGoods(goods: BaseCartItem): boolean {
|
||||
export function isWeightGoods(goods : BaseCartItem) : boolean {
|
||||
return goods.product_type === GoodsType.WEIGHT;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,9 +54,8 @@
|
||||
<view class="relative">
|
||||
<image @click.stop="getImgs(item)" class="panelfiveitemimage" :src="item.coverImg"
|
||||
mode="aspectFill"></image>
|
||||
<view class="limitDiscount" v-if="showLimitDiscount(item)"
|
||||
>限时折扣{{ limitDiscountCountdown }}</view
|
||||
>
|
||||
<view class="limitDiscount" v-if="showLimitDiscount(item)">
|
||||
限时折扣{{ limitDiscountCountdown }}</view>
|
||||
<!-- <view class="limitDiscount" v-if="item.is_time_discount">
|
||||
限时折扣{{ limitDiscountCountdown }}</view> -->
|
||||
<view class="stock_warning" v-if="item.isStock&&item.stockNumber<=10">
|
||||
@@ -204,9 +203,8 @@
|
||||
<image class="goodsImg"
|
||||
src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/index/1.gif" mode=""
|
||||
v-else :lazy-load="true"></image>
|
||||
<view class="limitDiscount" v-if="showLimitDiscount(item1)"
|
||||
>限时折扣{{ limitDiscountCountdown }}</view
|
||||
>
|
||||
<view class="limitDiscount" v-if="showLimitDiscount(item1)">
|
||||
限时折扣{{ limitDiscountCountdown }}</view>
|
||||
|
||||
<!-- <view class="limitDiscount" v-if="item1.is_time_discount">
|
||||
限时折扣{{ limitDiscountCountdown }}</view> -->
|
||||
@@ -327,9 +325,9 @@
|
||||
<shopindex ref="showShopInfoRef"></shopindex>
|
||||
<!-- 购物车 -->
|
||||
<shoppingCartes :cartLists_count="cartLists_count" :cartList="matchedProducts" :showCart="showCart"
|
||||
:limitDiscount="cartStore.limitTimeDiscount" @customevent="websocketsendMessage" @close="showCart = !showCart"
|
||||
:orderinfo="orderinfo" @clickcancelOrder="clickcancelOrder" v-if="cartLists_count > 0"
|
||||
:nextFullAmountActivty="nextFullAmountActivty"></shoppingCartes>
|
||||
:limitDiscount="cartStore.limitTimeDiscount" @customevent="websocketsendMessage"
|
||||
@close="showCart = !showCart" :orderinfo="orderinfo" @clickcancelOrder="clickcancelOrder"
|
||||
v-if="cartLists_count > 0" :nextFullAmountActivty="nextFullAmountActivty"></shoppingCartes>
|
||||
|
||||
<!-- 显示购物车栏 -->
|
||||
<view class="cart-wrap" v-if="cartLists_count > 0 && !confirmordershow && isBusinessTime">
|
||||
@@ -446,8 +444,9 @@
|
||||
v-if="specifications.item.type != 'package' && specifications.item.result">
|
||||
<text class="i">¥</text>
|
||||
<view class="num">
|
||||
<GoodsPrice :limitDiscount="cartStore.limitTimeDiscount" :cart="specifications.item.result"
|
||||
:shopUserInfo="shopUserInfo" :shopInfo="shopInfo"></GoodsPrice>
|
||||
<GoodsPrice :limitDiscount="cartStore.limitTimeDiscount"
|
||||
:cart="specifications.item.result" :shopUserInfo="shopUserInfo"
|
||||
:shopInfo="shopInfo"></GoodsPrice>
|
||||
</view>
|
||||
|
||||
<text class="num" v-if="false">
|
||||
@@ -481,7 +480,8 @@
|
||||
v-if="specifications.item.suitNum > 1">「{{ specifications.item.suitNum }}{{ specifications.item.unitName }}起点」</text>
|
||||
</view>
|
||||
|
||||
<view class="operation-wrap" v-if="specifications.item.type != 'package'&&stockNumberIsFull(specifications.item)">
|
||||
<view class="operation-wrap"
|
||||
v-if="specifications.item.type != 'package'&&stockNumberIsFull(specifications.item)">
|
||||
<view class="btn">
|
||||
<up-icon name="minus-circle-fill" color="#E9AB7A" size="25"
|
||||
v-if="shopCartNumber > 0"></up-icon>
|
||||
@@ -1103,8 +1103,8 @@
|
||||
};
|
||||
|
||||
//返回是否是热销商品
|
||||
function returnIsHot(item,category,index){
|
||||
return item.isHot&& category.name=='热销' &&index==0 && shopProductList.hots.find(v=>v.id==item.id)
|
||||
function returnIsHot(item, category, index) {
|
||||
return item.isHot && category.name == '热销' && index == 0 && shopProductList.hots.find(v => v.id == item.id)
|
||||
}
|
||||
|
||||
|
||||
@@ -1362,8 +1362,8 @@
|
||||
};
|
||||
|
||||
|
||||
function stockNumberIsFull(item){
|
||||
if(item.isStock && item.stockNumber < item.suitNum){
|
||||
function stockNumberIsFull(item) {
|
||||
if (item.isStock && item.stockNumber < item.suitNum) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@@ -1380,7 +1380,7 @@
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if ( item.isStock && item.stockNumber < item.suitNum && i == '+') {
|
||||
if (item.isStock && item.stockNumber < item.suitNum && i == '+') {
|
||||
uni.showToast({
|
||||
title: '库存不足',
|
||||
icon: 'none'
|
||||
@@ -1608,7 +1608,7 @@
|
||||
// 初始化
|
||||
if (Message.operate_type == 'init') {
|
||||
cartStore.limitTimeDiscount = Message.time_dis_info;
|
||||
console.log('onMessage:限时折扣',cartStore.limitTimeDiscount)
|
||||
console.log('onMessage:限时折扣', cartStore.limitTimeDiscount)
|
||||
cartInit(Message.data)
|
||||
|
||||
uni.hideLoading();
|
||||
@@ -1629,7 +1629,7 @@
|
||||
cancelText: '舍弃',
|
||||
confirmText: '合并',
|
||||
success(res) {
|
||||
showTableInfoPeopleNumPopup.value=false;
|
||||
showTableInfoPeopleNumPopup.value = false;
|
||||
if (res.confirm) {
|
||||
startUseTable({
|
||||
is_hb: 2
|
||||
@@ -1669,7 +1669,7 @@
|
||||
shop_id: uni.cache.get('shopId'),
|
||||
time_dis_info: cartStore.limitTimeDiscount
|
||||
};
|
||||
|
||||
console.log('cartStore.limitTimeDiscount', cartStore.limitTimeDiscount)
|
||||
useSocket.sendMessage({
|
||||
type: 'shopping',
|
||||
operate_type: 'time_discount_save',
|
||||
@@ -1890,8 +1890,9 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
console.log('limitTimeDiscountRes',item)
|
||||
if (cartStore.limitTimeDiscount && cartStore.limitTimeDiscount.id && item.cartListinfo.is_time_discount ==
|
||||
console.log('limitTimeDiscountRes', item)
|
||||
if (cartStore.limitTimeDiscount && cartStore.limitTimeDiscount.id && item.cartListinfo
|
||||
.is_time_discount ==
|
||||
1) {
|
||||
//限时折扣
|
||||
const price = limitUtils.returnPrice({
|
||||
@@ -1901,7 +1902,7 @@
|
||||
shopUserInfo: shopUserInfo.value,
|
||||
idKey: 'id'
|
||||
});
|
||||
console.log('限时折扣',price)
|
||||
console.log('限时折扣', price)
|
||||
return total + parseFloat(price) * parseFloat(item.cartNumber);
|
||||
}
|
||||
// 是否启用会员价 0否1是
|
||||
@@ -2302,9 +2303,12 @@
|
||||
extraInitPar.user_id = uni.cache.get('userInfo').id || ''
|
||||
}
|
||||
|
||||
const time_dis_info= await getLimitDiscount()
|
||||
|
||||
useSocket.connect({
|
||||
...options.initMessage,
|
||||
...extraInitPar
|
||||
...extraInitPar,
|
||||
time_dis_info
|
||||
}, onMessage);
|
||||
|
||||
|
||||
@@ -2351,9 +2355,9 @@
|
||||
|
||||
function showLimitDiscount(item) {
|
||||
if (!cartStore.limitTimeDiscount || !cartStore.limitTimeDiscount.id) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
return limitUtils.canUseLimitTimeDiscount(item, cartStore.limitTimeDiscount, shopInfo, shopUserInfo.value, 'id');
|
||||
return limitUtils.canUseLimitTimeDiscount(item, cartStore.limitTimeDiscount, shopInfo, shopUserInfo.value, 'id')?1:0;
|
||||
}
|
||||
|
||||
function returnLimitPrice(item) {
|
||||
@@ -2471,6 +2475,29 @@
|
||||
return 0
|
||||
})
|
||||
const oldOrder = ref(null);
|
||||
|
||||
// 限时折扣
|
||||
async function getLimitDiscount(){
|
||||
|
||||
const limitRes = await limitTimeDiscountapi.getConfig({
|
||||
shopId: uni.cache.get('shopId')
|
||||
});
|
||||
if (limitRes && typeof limitRes == 'object') {
|
||||
cartStore.limitTimeDiscount = limitRes;
|
||||
} else {
|
||||
cartStore.limitTimeDiscount = null;
|
||||
}
|
||||
return cartStore.limitTimeDiscount
|
||||
websocketsendMessage({
|
||||
type: 'shopping',
|
||||
operate_type: 'time_discount_save',
|
||||
table_code: uni.cache.get('tableCode'),
|
||||
shop_id: uni.cache.get('shopId'),
|
||||
operate_type: 'time_discount_save',
|
||||
data: cartStore.limitTimeDiscount
|
||||
});
|
||||
console.log('onMounted:限时折扣', cartStore.limitTimeDiscount);
|
||||
}
|
||||
onMounted(async () => {
|
||||
await proxy.$onLaunched;
|
||||
// 获取当前页面栈
|
||||
@@ -2484,37 +2511,11 @@
|
||||
getNewUserDiscount();
|
||||
// 满减活动
|
||||
getDiscountActivity();
|
||||
|
||||
let res = await APIhistoryOrder({
|
||||
tableCode: uni.cache.get('tableCode')
|
||||
});
|
||||
oldOrder.value = res;
|
||||
const limitRes = await limitTimeDiscountapi.getConfig({
|
||||
shopId: uni.cache.get('shopId')
|
||||
});
|
||||
if (limitRes && typeof limitRes == 'object') {
|
||||
cartStore.limitTimeDiscount = limitRes;
|
||||
console.log('onMounted:限时折扣',cartStore.limitTimeDiscount );
|
||||
websocketsendMessage({
|
||||
type: 'shopping',
|
||||
operate_type: 'time_discount_save',
|
||||
table_code: uni.cache.get('tableCode'),
|
||||
shop_id: uni.cache.get('shopId'),
|
||||
operate_type: 'time_discount_save',
|
||||
data: limitRes
|
||||
});
|
||||
} else {
|
||||
cartStore.limitTimeDiscount = null;
|
||||
console.log('onMounted:限时折扣',cartStore.limitTimeDiscount );
|
||||
websocketsendMessage({
|
||||
type: 'shopping',
|
||||
operate_type: 'time_discount_save',
|
||||
table_code: uni.cache.get('tableCode'),
|
||||
shop_id: uni.cache.get('shopId'),
|
||||
operate_type: 'time_discount_save',
|
||||
data: null
|
||||
});
|
||||
}
|
||||
|
||||
await productqueryProduct();
|
||||
if (res && res.id && shopInfo.registerType == 'after') {
|
||||
toHistory();
|
||||
|
||||
@@ -319,6 +319,9 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
//购物车商品信息补全初始化
|
||||
function cartsGoodsInfoInit(arr) {
|
||||
console.log('cartsGoodsInfoInit', arr)
|
||||
if(oldOrder.value&&oldOrder.value.status=='done'){
|
||||
return ''
|
||||
}
|
||||
carts.value = arr
|
||||
.map((v) => {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user