问题修复,下单优化,订单结算问题修复
This commit is contained in:
@@ -69,7 +69,7 @@
|
||||
<text class="color-666" v-if="item.status == 'success'"
|
||||
>已入账</text
|
||||
>
|
||||
<text class="color-666" v-if="item.status == 'REFUND'"
|
||||
<text class="color-666" v-if="item.status == 'refund'"
|
||||
>已退款</text
|
||||
>
|
||||
</view>
|
||||
@@ -80,12 +80,12 @@
|
||||
<text class="color-333 font-700">{{ item.orderNo }}</text>
|
||||
</view>
|
||||
<view class="money">
|
||||
<text class="money reduce" v-if="item.status == 'REFUND'"
|
||||
<text class="money reduce" v-if="item.status == 'refund'"
|
||||
>-{{ item.rewardAmount }}</text
|
||||
>
|
||||
|
||||
<text class="money" v-else>+{{ item.rewardAmount }}</text>
|
||||
<text class="tag" v-if="item.status == 'REFUND'">订单退款</text>
|
||||
<text class="tag" v-if="item.status == 'refund'">订单退款</text>
|
||||
<text class="tag" v-else-if="item.level == 1"
|
||||
>(订单一级分成)</text
|
||||
>
|
||||
@@ -205,7 +205,7 @@ const statusList = ref([
|
||||
fontSize: "16",
|
||||
},
|
||||
{
|
||||
value: "REFUND",
|
||||
value: "refund",
|
||||
name: "已退款",
|
||||
color: "#333",
|
||||
fontSize: "16",
|
||||
|
||||
@@ -54,7 +54,14 @@
|
||||
@click="questionClick('等级升级条件')"
|
||||
/>
|
||||
</view>
|
||||
<view class="u-m-t-28 u-flex align-center" v-if="juNextLvMoney&&state.distributionUser&&!state.distributionUser.IsAssignLevel">
|
||||
<view
|
||||
class="u-m-t-28 u-flex align-center"
|
||||
v-if="
|
||||
juNextLvMoney &&
|
||||
state.distributionUser &&
|
||||
state.distributionUser.isAssignLevel == 0
|
||||
"
|
||||
>
|
||||
<text class="color-666">距离下一级还差:</text>
|
||||
<text class="color-333 font-700 u-m-r-18"
|
||||
>{{ juNextLvMoney }}
|
||||
@@ -72,7 +79,11 @@
|
||||
<view class="u-flex u-m-t-28">
|
||||
<view class="u-flex-1">
|
||||
<view class="u-flex align-center">
|
||||
<text class="u-m-r-10 font-12 color-666" @click="toShouyiDetail('')">总收益</text>
|
||||
<text
|
||||
class="u-m-r-10 font-12 color-666"
|
||||
@click="toShouyiDetail('')"
|
||||
>总收益</text
|
||||
>
|
||||
<up-icon
|
||||
name="question-circle"
|
||||
size="24rpx"
|
||||
@@ -80,13 +91,20 @@
|
||||
@click="questionClick('总收益')"
|
||||
/>
|
||||
</view>
|
||||
<view class="u-m-t-16 price" @click="toShouyiDetail('')" v-if="state.distributionUser">{{
|
||||
state.distributionUser.totalIncome
|
||||
}}</view>
|
||||
<view
|
||||
class="u-m-t-16 price"
|
||||
@click="toShouyiDetail('')"
|
||||
v-if="state.distributionUser"
|
||||
>{{ state.distributionUser.totalIncome }}</view
|
||||
>
|
||||
</view>
|
||||
<view class="u-flex-1">
|
||||
<view class="u-flex align-center">
|
||||
<text class="u-m-r-10 font-12 color-666" @click="toShouyiDetail('待入账')">待入账</text>
|
||||
<text
|
||||
class="u-m-r-10 font-12 color-666"
|
||||
@click="toShouyiDetail('待入账')"
|
||||
>待入账</text
|
||||
>
|
||||
<up-icon
|
||||
name="question-circle"
|
||||
size="24rpx"
|
||||
@@ -94,9 +112,12 @@
|
||||
@click="questionClick('待入账')"
|
||||
/>
|
||||
</view>
|
||||
<view class="u-m-t-16 price" @click="toShouyiDetail('待入账')" v-if="state.distributionUser">{{
|
||||
state.distributionUser.pendingIncome
|
||||
}}</view>
|
||||
<view
|
||||
class="u-m-t-16 price"
|
||||
@click="toShouyiDetail('待入账')"
|
||||
v-if="state.distributionUser"
|
||||
>{{ state.distributionUser.pendingIncome }}</view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -219,9 +240,7 @@
|
||||
<text v-if="item.inviteTime">{{
|
||||
item.inviteTime.split(" ")[0]
|
||||
}}</text>
|
||||
<text style="color: #fff" v-else>{{
|
||||
"yyyy-MM-dd"
|
||||
}}</text>
|
||||
<text style="color: #fff" v-else>{{ "yyyy-MM-dd" }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -358,7 +377,11 @@ const commissionTipsType = ref("");
|
||||
|
||||
function toShouyiDetail(name) {
|
||||
uni.navigateTo({
|
||||
url: "/distribution/income-details/index?name="+name+'&shopId='+options.shopId,
|
||||
url:
|
||||
"/distribution/income-details/index?name=" +
|
||||
name +
|
||||
"&shopId=" +
|
||||
options.shopId,
|
||||
});
|
||||
}
|
||||
function questionClick(title) {
|
||||
|
||||
@@ -891,7 +891,7 @@ async function getDiscountActivity() {
|
||||
}
|
||||
onMounted(async () => {
|
||||
await getConsumeDiscount();
|
||||
// getDiscountActivity();
|
||||
getDiscountActivity();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
></goodsPrice>
|
||||
|
||||
<text
|
||||
class="originalprice"
|
||||
class="originalprice" v-if="showLimitDiscount(item)"
|
||||
>{{ item.salePrice }}</text
|
||||
>
|
||||
|
||||
|
||||
@@ -58,7 +58,10 @@
|
||||
v-for="(item, index) in shopProductList.hots"
|
||||
:key="index"
|
||||
>
|
||||
<view class="limitDiscount" v-if="showLimitDiscount(item)"
|
||||
<!-- <view class="limitDiscount" v-if="showLimitDiscount(item)"
|
||||
>限时折扣</view
|
||||
> -->
|
||||
<view class="limitDiscount" v-if="item.is_time_discount"
|
||||
>限时折扣</view
|
||||
>
|
||||
<image
|
||||
@@ -441,7 +444,12 @@
|
||||
<text class="money_num" v-if="item1.unitName"
|
||||
>/{{ item1.unitName }}</text
|
||||
>
|
||||
<text class="old-price">¥{{ item1.salePrice }}</text>
|
||||
<!-- <text class="old-price" v-if=" showLimitDiscount(item1)"
|
||||
>¥{{ item1.salePrice }}</text
|
||||
> -->
|
||||
<text class="old-price" v-if="item1.is_time_discount"
|
||||
>¥{{ item1.salePrice }}</text
|
||||
>
|
||||
|
||||
<!-- <text v-if="item1.suitNum>1 && item1.type!= 'sku'"
|
||||
style="font-size: 14rpx;">
|
||||
@@ -706,7 +714,6 @@
|
||||
</view>
|
||||
|
||||
<text class="num" v-if="false">
|
||||
|
||||
{{
|
||||
shopInfo.isVip == 1 && shopInfo.isMemberPrice == 1
|
||||
? specifications.item.result.memberPrice ||
|
||||
@@ -1440,6 +1447,8 @@ const submitSelection = async () => {
|
||||
memberPrice: specifications.item.memberPrice,
|
||||
is_print: 1,
|
||||
product_type: specifications.item.type,
|
||||
is_time_discount:specifications.item.is_time_discount
|
||||
|
||||
});
|
||||
// 清空套餐选中
|
||||
selectedGroupSnap.value = [];
|
||||
@@ -1587,6 +1596,7 @@ const singleclick = async (item, i) => {
|
||||
number: await calculateValue(item.cartNumber, i, suitNum),
|
||||
is_print: 1,
|
||||
product_type: item.type,
|
||||
is_time_discount:item.is_time_discount
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1663,23 +1673,9 @@ const updateProductQuantities = () => {
|
||||
//websocket产值
|
||||
const websocketsendMessage = (data) => {
|
||||
console.log("websocketsendMessage", data);
|
||||
const sendData = { ...data, is_time_discount: 0 };
|
||||
if (cartStore.limitTimeDiscount && cartStore.limitTimeDiscount.id) {
|
||||
const canUse = orderUtils.canUseLimitTimeDiscount(
|
||||
data,
|
||||
cartStore.limitTimeDiscount,
|
||||
shopInfo,
|
||||
shopUserInfo.value,
|
||||
"product_id"
|
||||
);
|
||||
console.log("canUse", canUse);
|
||||
if (canUse) {
|
||||
sendData.is_time_discount = 1;
|
||||
}
|
||||
}
|
||||
delete sendData.memberPrice;
|
||||
delete data.memberPrice;
|
||||
uni.$u.debounce(() => {
|
||||
useSocket.sendMessage(sendData);
|
||||
useSocket.sendMessage(data);
|
||||
}, 500);
|
||||
};
|
||||
|
||||
@@ -1792,7 +1788,11 @@ async function onMessage(Message) {
|
||||
}
|
||||
|
||||
// 提示
|
||||
if (Message.status == 0 && Message.type != "no_suit_num") {
|
||||
if (
|
||||
Message.status == 0 &&
|
||||
Message.type != "no_suit_num" &&
|
||||
Message.type != "time_discount"
|
||||
) {
|
||||
uni.showToast({
|
||||
title: Message.msg,
|
||||
icon: "none",
|
||||
@@ -2038,29 +2038,6 @@ function ifcartNumber(item) {
|
||||
// 如果类型不匹配,返回原始值
|
||||
return item.cartNumber;
|
||||
}
|
||||
// const ifcartNumber = computed(() => {
|
||||
// return (item) => {
|
||||
// // 如果 item 为空或者 cartNumber 不是字符串类型,返回 0
|
||||
// if (!item || typeof item.cartNumber !== 'string') {
|
||||
// return 0;
|
||||
// }
|
||||
// let numValue = parseFloat(item.cartNumber);
|
||||
// if (isNaN(numValue)) {
|
||||
// // 如果转换结果是 NaN,说明 cartNumber 不是有效的数字字符串,返回 0
|
||||
// return 0;
|
||||
// }
|
||||
// // type string 商品类型 single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券
|
||||
// if (item.type === 'weight') {
|
||||
// // 如果类型是称重重量,将值保留两位小数
|
||||
// return parseFloat(numValue.toFixed(2));
|
||||
// } else {
|
||||
// // 如果类型是整数,将值转换为整数
|
||||
// return Math.round(numValue);
|
||||
// }
|
||||
// // 如果类型不匹配,返回原始值
|
||||
// return item.cartNumber;
|
||||
// };
|
||||
// })
|
||||
|
||||
// 计算处理后的购物车列表 // 用于筛选后的购物车数组
|
||||
const cartListFilter = computed(() => {
|
||||
@@ -2146,6 +2123,9 @@ const productqueryProduct = async () => {
|
||||
product.startTime,
|
||||
product.endTime
|
||||
);
|
||||
product.is_time_discount = showLimitDiscount(product)?1:0;
|
||||
product.limitSalePrice = returnLimitPrice(product);
|
||||
|
||||
cartStore.setGoodsMap(product.id, product);
|
||||
});
|
||||
});
|
||||
@@ -2156,6 +2136,8 @@ const productqueryProduct = async () => {
|
||||
i.startTime,
|
||||
i.endTime
|
||||
);
|
||||
i.is_time_discount = showLimitDiscount(i)?1:0;
|
||||
i.limitSalePrice = returnLimitPrice(i);
|
||||
cartStore.setGoodsMap(i.id, i);
|
||||
});
|
||||
|
||||
@@ -2204,6 +2186,16 @@ function showLimitDiscount(item) {
|
||||
);
|
||||
}
|
||||
|
||||
function returnLimitPrice(item) {
|
||||
return orderUtils.returnPrice({
|
||||
goods: item,
|
||||
limitTimeDiscountRes: cartStore.limitTimeDiscount,
|
||||
shopInfo: shopInfo,
|
||||
shopUserInfo: shopUserInfo.value,
|
||||
idKey: "id",
|
||||
});
|
||||
}
|
||||
|
||||
onShow(async () => {
|
||||
// 监听页面显示和隐藏
|
||||
useSocket.setOnMessage(onMessage);
|
||||
@@ -2242,6 +2234,7 @@ onMounted(async () => {
|
||||
});
|
||||
if (limitRes && typeof limitRes == "object") {
|
||||
limitTimeDiscountRes.value = limitRes;
|
||||
cartStore.limitTimeDiscount = limitRes;
|
||||
websocketsendMessage({
|
||||
type: "shopping",
|
||||
operate_type: "time_discount_save",
|
||||
@@ -2251,6 +2244,7 @@ onMounted(async () => {
|
||||
data: limitRes,
|
||||
});
|
||||
} else {
|
||||
cartStore.limitTimeDiscount = null;
|
||||
websocketsendMessage({
|
||||
type: "shopping",
|
||||
operate_type: "time_discount_save",
|
||||
@@ -2259,6 +2253,7 @@ onMounted(async () => {
|
||||
operate_type: "time_discount_save",
|
||||
data: null,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
await productqueryProduct();
|
||||
|
||||
@@ -47,6 +47,7 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
product_id: item.product_id || item.productId,
|
||||
sku_id: item.skuId || item.sku_id,
|
||||
});
|
||||
console.log('convertToBaseCartItem',item)
|
||||
const discountSaleAmount=item.discount_sale_amount?(item.discount_sale_amount*1) : (item.discountSaleAmount?item.discountSaleAmount*1:0)
|
||||
return {
|
||||
...item,
|
||||
|
||||
@@ -268,6 +268,12 @@ export interface TimeLimitDiscountConfig {
|
||||
[property: string]: any;
|
||||
}
|
||||
|
||||
//用户信息
|
||||
interface ShopUserInfo {
|
||||
isVip: number | null; //是否会员
|
||||
discount: number | null; //用户折扣
|
||||
isMemberPrice: number | null; //会员折扣与会员价是否同时使用
|
||||
}
|
||||
/** 订单额外费用配置 */
|
||||
export interface OrderExtraConfig {
|
||||
// merchantReduction: number; // 商家减免金额(元,默认0)
|
||||
@@ -286,6 +292,7 @@ export interface OrderExtraConfig {
|
||||
isFreeDine?: boolean; //是否霸王餐
|
||||
freeDineConfig?: FreeDineConfig;
|
||||
limitTimeDiscount?: TimeLimitDiscountConfig; //限时折扣
|
||||
shopUserInfo: ShopUserInfo; // 用户信息
|
||||
}
|
||||
|
||||
/** 订单费用汇总(修改:补充商家减免类型和明细) */
|
||||
@@ -318,10 +325,12 @@ export interface OrderCostSummary {
|
||||
config: OrderExtraConfig; // 订单额外费用配置
|
||||
//满减活动
|
||||
fullReduction: {
|
||||
usedFullReductionActivityFullAmount: number; // 计算出的满减活动的门槛金额
|
||||
usedActivity?: FullReductionActivity; // 实际使用的满减活动
|
||||
usedThreshold?: FullReductionThreshold; // 实际使用的满减阈值(多门槛中选最优)
|
||||
actualAmount: number; // 满减实际减免金额(元)
|
||||
};
|
||||
vipDiscountAmount: number; //会员折扣减免金额
|
||||
// 订单原支付金额
|
||||
orderOriginFinalPayAmount: number; //订单原金额(包含打包费+餐位费)
|
||||
}
|
||||
@@ -437,58 +446,190 @@ function isDinnerTypeMatch(
|
||||
|
||||
//判断商品是否可以使用限时折扣
|
||||
export function returnCanUseLimitTimeDiscount(
|
||||
goods:BaseCartItem,
|
||||
limitTimeDiscountRes:TimeLimitDiscountConfig|null|undefined,
|
||||
useVipPrice:boolean,
|
||||
goods: BaseCartItem,
|
||||
limitTimeDiscount: TimeLimitDiscountConfig | null | undefined,
|
||||
useVipPrice: boolean,
|
||||
idKey = "product_id"
|
||||
) {
|
||||
if (!limitTimeDiscountRes || !limitTimeDiscountRes.id) {
|
||||
if (!limitTimeDiscount || !limitTimeDiscount.id) {
|
||||
return false;
|
||||
}
|
||||
const canUseFoods = (limitTimeDiscountRes.foods || "").split(",");
|
||||
if (limitTimeDiscountRes.discountPriority == "limit-time") {
|
||||
if (
|
||||
limitTimeDiscountRes.foodType == 1 ||
|
||||
canUseFoods.includes("" + goods[idKey])
|
||||
) {
|
||||
const canUseFoods = (limitTimeDiscount.foods || "").split(",");
|
||||
const goodsCanUse =
|
||||
limitTimeDiscount.foodType == 1 || canUseFoods.includes("" + goods[idKey]);
|
||||
if (!goodsCanUse) {
|
||||
return false;
|
||||
}
|
||||
if (limitTimeDiscount.discountPriority == "limit-time") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (
|
||||
limitTimeDiscountRes.discountPriority == "vip-price"
|
||||
|
||||
) {
|
||||
|
||||
if(!useVipPrice){
|
||||
if (limitTimeDiscount.discountPriority == "vip-price") {
|
||||
if (!useVipPrice) {
|
||||
return true;
|
||||
}
|
||||
if (useVipPrice && goods.hasOwnProperty("memberPrice")) {
|
||||
if (goods.memberPrice && goods.memberPrice * 1 <= 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function returnMemberPrice(useVipPrice: boolean, goods: BaseCartItem) {
|
||||
if (useVipPrice) {
|
||||
return goods.memberPrice || goods.salePrice;
|
||||
} else {
|
||||
return goods.salePrice;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回商品限时折扣价格
|
||||
*/
|
||||
function returnLimitPrice(
|
||||
goods: BaseCartItem,
|
||||
limitTimeDiscount: TimeLimitDiscountConfig | null | undefined,
|
||||
useVipPrice
|
||||
) {
|
||||
if (!limitTimeDiscount) {
|
||||
return 0;
|
||||
}
|
||||
const discountRate = new BigNumber(limitTimeDiscount.discountRate).dividedBy(
|
||||
100
|
||||
);
|
||||
|
||||
const canuseLimit = returnCanUseLimitTimeDiscount(
|
||||
goods,
|
||||
limitTimeDiscount,
|
||||
useVipPrice
|
||||
);
|
||||
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) {
|
||||
//使用会员价
|
||||
return returnMemberPrice(useVipPrice, goods);
|
||||
} else {
|
||||
return goods.salePrice;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算商品计算门槛时的金额
|
||||
*/
|
||||
|
||||
export function returnCalcPrice(
|
||||
goods: BaseCartItem,
|
||||
fullReductionActivitie: FullReductionActivity | undefined,
|
||||
limitTimeDiscount: TimeLimitDiscountConfig | null | undefined,
|
||||
useVipPrice: boolean,
|
||||
idKey = "product_id"
|
||||
) {
|
||||
if (goods.discountSaleAmount && goods.discountSaleAmount * 1 > 0) {
|
||||
return goods.salePrice;
|
||||
}
|
||||
//限时折扣和满减活动都有
|
||||
if (fullReductionActivitie && limitTimeDiscount) {
|
||||
if (
|
||||
fullReductionActivitie.discountShare == 1 &&
|
||||
fullReductionActivitie.vipPriceShare == 1
|
||||
) {
|
||||
//与限时折扣同享,与会员价不同享
|
||||
return returnLimitPrice(goods, limitTimeDiscount, useVipPrice);
|
||||
}
|
||||
if (
|
||||
fullReductionActivitie.discountShare != 1 &&
|
||||
fullReductionActivitie.vipPriceShare == 1
|
||||
) {
|
||||
//与限时折扣不同享,与会员价同享
|
||||
return returnMemberPrice(useVipPrice, goods);
|
||||
}
|
||||
if (fullReductionActivitie.vipPriceShare != 1) {
|
||||
//与会员价不同享
|
||||
return goods.salePrice;
|
||||
}
|
||||
return goods.salePrice;
|
||||
}
|
||||
//只有满减活动
|
||||
if (fullReductionActivitie) {
|
||||
if (fullReductionActivitie.vipPriceShare == 1) {
|
||||
return returnMemberPrice(useVipPrice, goods);
|
||||
} else {
|
||||
return goods.salePrice;
|
||||
}
|
||||
}
|
||||
//只有限时折扣
|
||||
if (limitTimeDiscount) {
|
||||
return returnLimitPrice(goods, limitTimeDiscount, useVipPrice);
|
||||
}
|
||||
|
||||
if (useVipPrice) {
|
||||
return returnMemberPrice(useVipPrice, goods);
|
||||
}
|
||||
return goods.salePrice;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算满减活动门槛
|
||||
*/
|
||||
export function calcFullReductionActivityFullAmount(goodsList: BaseCartItem[],fullReductionActivitie:FullReductionActivity|undefined,limitTimeDiscount:TimeLimitDiscountConfig|null|undefined
|
||||
,useVipPrice:boolean
|
||||
|
||||
) {
|
||||
if(!fullReductionActivitie){
|
||||
return 0
|
||||
export function calcFullReductionActivityFullAmount(
|
||||
goodsList: BaseCartItem[],
|
||||
fullReductionActivitie: FullReductionActivity | undefined,
|
||||
limitTimeDiscount: TimeLimitDiscountConfig | null | undefined,
|
||||
useVipPrice: boolean,
|
||||
seatFee: number,
|
||||
packFee: number
|
||||
): number {
|
||||
if (!fullReductionActivitie) {
|
||||
return 0;
|
||||
}
|
||||
let amount=0;
|
||||
console.log('calcFullReductionActivityFullAmount')
|
||||
console.log('fullReductionActivitie',fullReductionActivitie)
|
||||
console.log('limitTimeDiscount',limitTimeDiscount)
|
||||
for(let goods of goodsList){
|
||||
const canuseLimit=returnCanUseLimitTimeDiscount(goods,limitTimeDiscount,useVipPrice,"product_id")
|
||||
console.log('canuseLimit',canuseLimit)
|
||||
if(!fullReductionActivitie.discountShare){
|
||||
let amount = 0;
|
||||
for (let goods of goodsList) {
|
||||
const availableNum = Math.max(0, goods.number - (goods.returnNum || 0));
|
||||
amount+=goods.salePrice*availableNum
|
||||
if (goods.is_temporary || goods.is_gift || availableNum <= 0) {
|
||||
//临时菜,赠菜,数量<=0的商品不计算
|
||||
continue;
|
||||
}
|
||||
const calcPrice = returnCalcPrice(
|
||||
goods,
|
||||
fullReductionActivitie,
|
||||
limitTimeDiscount,
|
||||
useVipPrice,
|
||||
"product_id"
|
||||
);
|
||||
if (calcPrice !== undefined) {
|
||||
amount += calcPrice * availableNum;
|
||||
}
|
||||
}
|
||||
return amount + seatFee + packFee;
|
||||
console.log("amount", amount);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -516,6 +657,8 @@ export function filterOptimalFullReductionActivity(
|
||||
activity.thresholds?.length // 至少有一个满减阈值
|
||||
);
|
||||
});
|
||||
console.log("baseEligible", baseEligible);
|
||||
|
||||
if (!baseEligible.length) return undefined;
|
||||
|
||||
// 第二步:时间筛选(有效期内+周期内+时段内)
|
||||
@@ -766,6 +909,7 @@ export function calcSingleGoodsRealPrice(
|
||||
>
|
||||
): number {
|
||||
const { isMember, memberDiscountRate, limitTimeDiscount: activity } = config;
|
||||
console.log("activity", activity);
|
||||
|
||||
//如果是增菜价格为0
|
||||
if (goods.is_gift) {
|
||||
@@ -776,7 +920,6 @@ export function calcSingleGoodsRealPrice(
|
||||
if (goods.discountSaleAmount && goods.discountSaleAmount > 0) {
|
||||
return truncateToTwoDecimals(goods.discountSaleAmount);
|
||||
}
|
||||
console.log("calcSingleGoodsRealPrice:goods", goods);
|
||||
|
||||
// 2. 优先级2:会员价(含会员折扣率,SKU会员价优先)
|
||||
const memberPrice = new BigNumber(
|
||||
@@ -798,15 +941,18 @@ export function calcSingleGoodsRealPrice(
|
||||
if (!activity || !isActivityApplicable) {
|
||||
return memberPrice.toNumber();
|
||||
}
|
||||
console.log("isMember", isMember);
|
||||
//限时折扣优先或者会员价优先但是不是会员或者未开启会员价格时限时折扣优先
|
||||
if (
|
||||
activity.discountPriority == "limit-time" ||
|
||||
(activity.discountPriority == "vip-price" && !isMember)
|
||||
(activity.discountPriority == "vip-price" && !isMember) ||
|
||||
(activity.discountPriority == "vip-price" && isMember && !goods.memberPrice)
|
||||
) {
|
||||
//限时折扣优先
|
||||
return truncateToTwoDecimals(
|
||||
new BigNumber(goods.salePrice)
|
||||
.multipliedBy(activity.discountRate / 100)
|
||||
.times(activity.discountRate / 100)
|
||||
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||
.toNumber()
|
||||
);
|
||||
}
|
||||
@@ -881,6 +1027,7 @@ export function calcGoodsRealAmount(
|
||||
for (const goods of goodsList) {
|
||||
const availableNum = Math.max(0, goods.number - (goods.returnNum || 0));
|
||||
if (availableNum <= 0) continue;
|
||||
console.log("goods", goods);
|
||||
const realPrice = new BigNumber(calcSingleGoodsRealPrice(goods, config));
|
||||
total = total.plus(realPrice.multipliedBy(availableNum));
|
||||
}
|
||||
@@ -929,11 +1076,15 @@ export function selectOptimalThreshold(
|
||||
const validThresholds = thresholds.filter((threshold) => {
|
||||
const fullAmount = new BigNumber(threshold.fullAmount || 0);
|
||||
const discountAmount = new BigNumber(threshold.discountAmount || 0);
|
||||
console.log("fullAmount", fullAmount);
|
||||
console.log("discountAmount", discountAmount);
|
||||
|
||||
return (
|
||||
fullAmount.isLessThanOrEqualTo(thresholdBase) &&
|
||||
discountAmount.isGreaterThan(0)
|
||||
);
|
||||
});
|
||||
console.log("validThresholds", validThresholds);
|
||||
|
||||
if (!validThresholds.length) return undefined;
|
||||
|
||||
@@ -1154,6 +1305,24 @@ export function calcPointDeduction(
|
||||
};
|
||||
}
|
||||
|
||||
function calcVipDiscountAmount(
|
||||
goodsRealAmount: number,
|
||||
shopUserInfo: ShopUserInfo
|
||||
): number {
|
||||
if (!shopUserInfo.isVip || shopUserInfo.discount === 0) return 0;
|
||||
if (shopUserInfo.isVip == 1 && shopUserInfo.isMemberPrice != 1) {
|
||||
return 0;
|
||||
}
|
||||
console.log("goodsRealAmount", goodsRealAmount);
|
||||
console.log("discount", (100 - (shopUserInfo.discount || 0)) / 100);
|
||||
return truncateToTwoDecimals(
|
||||
new BigNumber(goodsRealAmount)
|
||||
.times((100 - (shopUserInfo.discount || 0)) / 100)
|
||||
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||
.toNumber()
|
||||
);
|
||||
}
|
||||
|
||||
// ============================ 6. 订单总费用汇总与实付金额计算(核心入口,补充细分字段) ============================
|
||||
/**
|
||||
* 计算订单所有费用子项并汇总(核心入口函数)
|
||||
@@ -1175,14 +1344,15 @@ export function calculateOrderCostSummary(
|
||||
cartOrder: Record<string, number> = {},
|
||||
currentTime: Date = new Date()
|
||||
): OrderCostSummary {
|
||||
|
||||
//是否使用霸王餐,霸王餐配置
|
||||
const {
|
||||
isFreeDine,
|
||||
freeDineConfig,
|
||||
limitTimeDiscount,
|
||||
fullReductionActivities,
|
||||
shopUserInfo,
|
||||
} = config;
|
||||
console.log("shopUserInfo", shopUserInfo);
|
||||
|
||||
// ------------------------------ 1. 基础费用计算 ------------------------------
|
||||
const goodsOriginalAmount = calcGoodsOriginalAmount(goodsList); // 商品原价总和
|
||||
@@ -1199,12 +1369,28 @@ export function calculateOrderCostSummary(
|
||||
goodsOriginalAmount,
|
||||
goodsRealAmount
|
||||
); // 商品折扣金额
|
||||
|
||||
const newUserDiscount = config.newUserDiscount || 0; // 新客立减
|
||||
|
||||
// 其他费用计算(原有逻辑不变) ------------------------------
|
||||
const packFee = calcTotalPackFee(goodsList, dinnerType); // 打包费
|
||||
let seatFee = calcSeatFee(config.seatFeeConfig); // 餐位费
|
||||
seatFee = dinnerType === "dine-in" ? seatFee : 0; // 外卖不收餐位费
|
||||
const additionalFee = Math.max(0, config.additionalFee); // 附加费
|
||||
|
||||
// ------------------------------ 2. 满减活动计算(核心步骤) ------------------------------
|
||||
let usedFullReductionActivity: FullReductionActivity | undefined;
|
||||
let usedFullReductionThreshold: FullReductionThreshold | undefined;
|
||||
let fullReductionAmount = 0;
|
||||
let usedFullReductionActivityFullAmount = calcFullReductionActivityFullAmount(
|
||||
goodsList,
|
||||
usedFullReductionActivity,
|
||||
config.limitTimeDiscount,
|
||||
config.isMember,
|
||||
seatFee,
|
||||
packFee
|
||||
);
|
||||
|
||||
// 2.1 筛选最优满减活动(后端活动列表、当前店铺、就餐类型、时间)
|
||||
usedFullReductionActivity = filterOptimalFullReductionActivity(
|
||||
config.fullReductionActivities,
|
||||
@@ -1213,17 +1399,6 @@ export function calculateOrderCostSummary(
|
||||
currentTime
|
||||
);
|
||||
|
||||
calcFullReductionActivityFullAmount(goodsList,usedFullReductionActivity,config.limitTimeDiscount,config.isMember);
|
||||
|
||||
|
||||
console.log("usedFullReductionActivity", usedFullReductionActivity);
|
||||
|
||||
// 其他费用计算(原有逻辑不变) ------------------------------
|
||||
const packFee = calcTotalPackFee(goodsList, dinnerType); // 打包费
|
||||
let seatFee = calcSeatFee(config.seatFeeConfig); // 餐位费
|
||||
seatFee = dinnerType === "dine-in" ? seatFee : 0; // 外卖不收餐位费
|
||||
const additionalFee = Math.max(0, config.additionalFee); // 附加费
|
||||
|
||||
// 2.2 计算满减基数(先扣新客立减)
|
||||
let baseAfterNewUserDiscount = new BigNumber(
|
||||
limitTimeDiscount &&
|
||||
@@ -1243,9 +1418,19 @@ export function calculateOrderCostSummary(
|
||||
|
||||
// 2.3 选择最优满减阈值(多门槛场景)
|
||||
if (usedFullReductionActivity) {
|
||||
//计算当前满减活动的门槛金额
|
||||
usedFullReductionActivityFullAmount = calcFullReductionActivityFullAmount(
|
||||
goodsList,
|
||||
usedFullReductionActivity,
|
||||
config.limitTimeDiscount,
|
||||
config.isMember,
|
||||
seatFee,
|
||||
packFee
|
||||
);
|
||||
|
||||
usedFullReductionThreshold = selectOptimalThreshold(
|
||||
usedFullReductionActivity.thresholds,
|
||||
baseAfterNewUserDiscount,
|
||||
usedFullReductionActivityFullAmount,
|
||||
goodsOriginalAmount,
|
||||
goodsRealAmount,
|
||||
usedFullReductionActivity.discountShare || 0 // 与限时折扣同享规则
|
||||
@@ -1258,6 +1443,7 @@ export function calculateOrderCostSummary(
|
||||
usedFullReductionThreshold
|
||||
);
|
||||
}
|
||||
|
||||
// ------------------------------ 3. 优惠券抵扣(适配满减同享规则) ------------------------------
|
||||
let couponDeductionAmount = 0;
|
||||
let productCouponDeduction = 0;
|
||||
@@ -1279,6 +1465,7 @@ export function calculateOrderCostSummary(
|
||||
currentTime,
|
||||
}
|
||||
);
|
||||
console.log("couponResult", couponResult);
|
||||
couponDeductionAmount = couponResult.deductionAmount;
|
||||
productCouponDeduction = couponResult.productCouponDeduction;
|
||||
fullCouponDeduction = couponResult.fullCouponDeduction;
|
||||
@@ -1286,7 +1473,10 @@ export function calculateOrderCostSummary(
|
||||
excludedProductIds = couponResult.excludedProductIds;
|
||||
|
||||
// 若满减与优惠券同享(couponShare=1),才计算优惠券;否则优惠券抵扣为0
|
||||
if (usedFullReductionActivity && !usedFullReductionActivity.couponShare) {
|
||||
if (
|
||||
usedFullReductionThreshold &&
|
||||
(!usedFullReductionActivity || !usedFullReductionActivity.couponShare)
|
||||
) {
|
||||
couponDeductionAmount = 0;
|
||||
productCouponDeduction = 0;
|
||||
fullCouponDeduction = 0;
|
||||
@@ -1315,20 +1505,20 @@ export function calculateOrderCostSummary(
|
||||
config.pointDeductionRule,
|
||||
maxPointDeductionLimit
|
||||
);
|
||||
console.log("积分抵扣结果:", pointResult);
|
||||
|
||||
pointDeductionAmount = pointResult.deductionAmount;
|
||||
usedPoints = pointResult.usedPoints;
|
||||
// 若满减与积分不同享(pointsShare=1)积分抵扣为0
|
||||
if (usedFullReductionActivity && !usedFullReductionActivity.pointsShare) {
|
||||
console.log("满减与积分不同享:积分抵扣为0");
|
||||
if (
|
||||
usedFullReductionThreshold &&
|
||||
(!usedFullReductionActivity || !usedFullReductionActivity.pointsShare)
|
||||
) {
|
||||
pointDeductionAmount = 0;
|
||||
usedPoints = 0;
|
||||
}
|
||||
|
||||
//使用霸王餐
|
||||
if (isFreeDine && freeDineConfig && freeDineConfig.enable) {
|
||||
console.log("使用霸王餐");
|
||||
fullReductionAmount = 0;
|
||||
//不与优惠券同享
|
||||
if (!freeDineConfig.withCoupon) {
|
||||
@@ -1386,9 +1576,21 @@ export function calculateOrderCostSummary(
|
||||
truncateToTwoDecimals(merchantReductionActualAmount)
|
||||
);
|
||||
|
||||
// 会员折扣减免
|
||||
const vipDiscountAmount = calcVipDiscountAmount(
|
||||
new BigNumber(goodsRealAmount)
|
||||
.minus(couponDeductionAmount)
|
||||
.plus(packFee)
|
||||
.plus(seatFee)
|
||||
.minus(newUserDiscount)
|
||||
.minus(fullReductionAmount)
|
||||
.toNumber(),
|
||||
shopUserInfo
|
||||
); // 会员折扣减免金额
|
||||
// ------------------------------ 6. 最终实付金额计算 ------------------------------
|
||||
const finalPayAmountBn = new BigNumber(goodsRealAmount)
|
||||
.minus(newUserDiscount)
|
||||
.minus(vipDiscountAmount)
|
||||
.minus(fullReductionAmount)
|
||||
.minus(couponDeductionAmount)
|
||||
.minus(pointDeductionAmount)
|
||||
@@ -1416,6 +1618,7 @@ export function calculateOrderCostSummary(
|
||||
.plus(couponDeductionAmount)
|
||||
.plus(pointDeductionAmount)
|
||||
.plus(merchantReductionActualAmount)
|
||||
.plus(vipDiscountAmount)
|
||||
.toNumber()
|
||||
);
|
||||
//积分可抵扣最大金额 最终支付金额+积分抵扣-商家减免
|
||||
@@ -1424,8 +1627,6 @@ export function calculateOrderCostSummary(
|
||||
.minus(merchantReductionActualAmount)
|
||||
.toNumber();
|
||||
|
||||
console.log("限时折扣:", config.limitTimeDiscount);
|
||||
|
||||
// ------------------------------ 8. 返回完整结果 ------------------------------
|
||||
return {
|
||||
goodsTotal: goodsList.reduce(
|
||||
@@ -1448,10 +1649,12 @@ export function calculateOrderCostSummary(
|
||||
scoreMaxMoney,
|
||||
// 满减活动明细(后端字段)
|
||||
fullReduction: {
|
||||
usedFullReductionActivityFullAmount: usedFullReductionActivityFullAmount,
|
||||
usedActivity: usedFullReductionActivity,
|
||||
usedThreshold: usedFullReductionThreshold,
|
||||
actualAmount: truncateToTwoDecimals(fullReductionAmount),
|
||||
},
|
||||
vipDiscountAmount: vipDiscountAmount, //会员折扣减免金额
|
||||
merchantReduction: {
|
||||
type: merchantReductionConfig.type,
|
||||
originalConfig: merchantReductionConfig,
|
||||
|
||||
@@ -31,11 +31,8 @@ export function returnGoodsPrice(goods, user, shopInfo, limitTimeDiscount) {
|
||||
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||
.toNumber();
|
||||
}
|
||||
if (
|
||||
canUseLimit &&
|
||||
limitTimeDiscount.discountPriority == "vip-price" &&
|
||||
!canUseVipPrice
|
||||
) {
|
||||
|
||||
if (canUseLimit && limitTimeDiscount.discountPriority == "vip-price") {
|
||||
if (canUseVipPrice) {
|
||||
return goods.memberPrice;
|
||||
} else {
|
||||
@@ -161,7 +158,10 @@ function returnCanCalcGoodsList(canCalcGoodsArr, coupon, shopInfo, user) {
|
||||
return canCalcGoodsArr.filter((goods) => {
|
||||
console.log("goods");
|
||||
console.log(goods);
|
||||
if (!coupon.discountShare && (goods.is_time_discount||goods.isTimeDiscount)) {
|
||||
if (
|
||||
!coupon.discountShare &&
|
||||
(goods.is_time_discount || goods.isTimeDiscount)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
@@ -391,6 +391,7 @@ export function calcDiscountGoodsArrPrice(
|
||||
let hasCountNum = 0;
|
||||
let discountPrice = 0;
|
||||
let hasDiscountGoodsArr = [];
|
||||
|
||||
for (let i = 0; i < discountGoodsArr.length; i++) {
|
||||
if (hasCountNum >= discountNum) {
|
||||
break;
|
||||
@@ -398,8 +399,14 @@ export function calcDiscountGoodsArrPrice(
|
||||
const goods = discountGoodsArr[i];
|
||||
const shengyuNum = discountNum - hasCountNum;
|
||||
const num = Math.min(goods.num, shengyuNum);
|
||||
discountPrice +=
|
||||
returnGoodsPrice(goods, user, shopInfo, limitTimeDiscount) * num;
|
||||
const realPrice = returnGoodsPrice(
|
||||
goods,
|
||||
user,
|
||||
shopInfo,
|
||||
limitTimeDiscount
|
||||
);
|
||||
|
||||
discountPrice += realPrice * num;
|
||||
|
||||
hasCountNum += num;
|
||||
hasDiscountGoodsArr.push({
|
||||
@@ -433,7 +440,7 @@ export function returnCouponDiscount(
|
||||
shopInfo,
|
||||
limitTimeDiscount
|
||||
) {
|
||||
arr = returnCanDikouGoods(arr, user, shopInfo);
|
||||
arr = returnCanDikouGoods(arr, user, shopInfo,limitTimeDiscount);
|
||||
const canDikouGoodsArr = returnCanDikouGoodsArr({
|
||||
canDikouGoodsArr: arr,
|
||||
selCoupon,
|
||||
@@ -554,8 +561,10 @@ export function returnCouponProductDiscount(
|
||||
limitTimeDiscount
|
||||
) {
|
||||
const { useFoods, discountNum, useRule } = coupon;
|
||||
|
||||
//抵扣商品数组
|
||||
let discountGoodsArr = [];
|
||||
|
||||
//抵扣全部商品
|
||||
if (useFoods.length === 0) {
|
||||
if (useRule == "price_asc") {
|
||||
@@ -574,6 +583,8 @@ export function returnCouponProductDiscount(
|
||||
discountGoodsArr = discountSelGoodsArr.slice(0, discountNum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const result = calcDiscountGoodsArrPrice(
|
||||
discountGoodsArr,
|
||||
discountNum,
|
||||
|
||||
@@ -758,9 +758,7 @@ export function calcMemberPrice(
|
||||
if (!isMember) return truncateToTwoDecimals(goods.salePrice);
|
||||
|
||||
// 优先级:SKU会员价 > 商品会员价 > 商品原价(无会员价时用会员折扣)
|
||||
const basePrice =
|
||||
goods.skuData?.memberPrice ?? goods.memberPrice ?? goods.salePrice;
|
||||
|
||||
const basePrice = goods.memberPrice || goods.salePrice;
|
||||
// 仅当无SKU会员价、无商品会员价时,才应用会员折扣率
|
||||
if (memberDiscountRate && !goods.skuData?.memberPrice && !goods.memberPrice) {
|
||||
return truncateToTwoDecimals(
|
||||
|
||||
@@ -15,9 +15,10 @@ export function canUseLimitTimeDiscount(
|
||||
}
|
||||
|
||||
const canUseFoods = (limitTimeDiscountRes.foods || "").split(",");
|
||||
|
||||
const goodsCanUse =
|
||||
limitTimeDiscountRes.foodType == 1 ||
|
||||
canUseFoods.includes("" + goods[idKey]);
|
||||
canUseFoods.includes(`${goods[idKey]}`);
|
||||
if (!goodsCanUse) {
|
||||
return false;
|
||||
}
|
||||
@@ -59,10 +60,12 @@ export function returnPrice(args) {
|
||||
idKey = "product_id",
|
||||
} = args;
|
||||
const canUseFoods = (limitTimeDiscountRes.foods || "").split(",");
|
||||
const includesGoods =
|
||||
limitTimeDiscountRes.foodType == 1 ||
|
||||
canUseFoods.includes("" + goods[idKey]);
|
||||
shopInfo = shopInfo || {};
|
||||
shopUserInfo = shopUserInfo || {};
|
||||
|
||||
if (shopUserInfo.isMemberPrice == 1 && shopUserInfo.isVip == 1) {
|
||||
if (shopUserInfo.isMemberPrice == 1 && shopUserInfo.isVip == 1 && shopInfo.isMemberPrice==1) {
|
||||
const memberPrice = goods.memberPrice || goods.salePrice;
|
||||
|
||||
//是会员而且启用会员价
|
||||
@@ -70,10 +73,7 @@ export function returnPrice(args) {
|
||||
//使用限时折扣
|
||||
//限时折扣优先
|
||||
if (limitTimeDiscountRes.discountPriority == "limit-time") {
|
||||
if (
|
||||
limitTimeDiscountRes.foodType == 1 ||
|
||||
canUseFoods.includes("" + goods[idKey])
|
||||
) {
|
||||
if (includesGoods) {
|
||||
return returnLimitPrice({
|
||||
price: goods.salePrice,
|
||||
limitTimeDiscountRes,
|
||||
@@ -82,7 +82,10 @@ export function returnPrice(args) {
|
||||
return memberPrice;
|
||||
}
|
||||
}
|
||||
if (limitTimeDiscountRes.discountPriority == "vip-price") {
|
||||
if (
|
||||
limitTimeDiscountRes.discountPriority == "vip-price" &&
|
||||
includesGoods
|
||||
) {
|
||||
if (goods.memberPrice * 1 > 0) {
|
||||
//会员优先
|
||||
return memberPrice;
|
||||
@@ -95,6 +98,8 @@ export function returnPrice(args) {
|
||||
|
||||
return price;
|
||||
}
|
||||
} else {
|
||||
return memberPrice;
|
||||
}
|
||||
} else {
|
||||
//是会员没有限时折扣
|
||||
@@ -103,12 +108,7 @@ export function returnPrice(args) {
|
||||
} else {
|
||||
// console.log('不是会员或者没有启用会员价',goods,limitTimeDiscountRes);
|
||||
//不是会员或者没有启用会员价
|
||||
if (
|
||||
limitTimeDiscountRes &&
|
||||
limitTimeDiscountRes.id &&
|
||||
(limitTimeDiscountRes.foodType == 1 ||
|
||||
canUseFoods.includes("" + goods[idKey]))
|
||||
) {
|
||||
if (limitTimeDiscountRes && limitTimeDiscountRes.id && includesGoods) {
|
||||
const price = returnLimitPrice({
|
||||
price: goods.salePrice,
|
||||
limitTimeDiscountRes,
|
||||
|
||||
Reference in New Issue
Block a user