代客下单问题修复,积分上传问题修复
This commit is contained in:
@@ -10,4 +10,27 @@ export const pointsShopList = (data) => {
|
||||
})
|
||||
}
|
||||
|
||||
export const pointsConfig = (data) => {
|
||||
return request({
|
||||
url: prveUrl + '/user/point/pointsConfig',
|
||||
method: 'get',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export const userPoints = (data) => {
|
||||
return request({
|
||||
url: prveUrl + '/user/point/userPoints',
|
||||
method: 'get',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export const userRecord = (data) => {
|
||||
return request({
|
||||
url: prveUrl + '/user/point/userRecord',
|
||||
method: 'get',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
>
|
||||
<image
|
||||
@click.stop="()=>{}"
|
||||
@click.stop="onBack"
|
||||
class="max-img"
|
||||
:src="item"
|
||||
:lazy-load="true"
|
||||
|
||||
0
lib/carts.ts
Normal file
0
lib/carts.ts
Normal file
852
lib/coupon.ts
Normal file
852
lib/coupon.ts
Normal file
@@ -0,0 +1,852 @@
|
||||
import { BigNumber } from "bignumber.js";
|
||||
import _ from "lodash";
|
||||
|
||||
import {
|
||||
ShopInfo,
|
||||
couponCalcParams,
|
||||
BaseCartItem,
|
||||
TimeLimitDiscountConfig,
|
||||
CanDikouGoodsArrArgs,
|
||||
Coupon,
|
||||
ShopUserInfo,
|
||||
GoodsType,
|
||||
BackendCoupon,
|
||||
ExchangeCalculationResult,
|
||||
PointDeductionRule,
|
||||
OrderCostSummary,
|
||||
} from "./types";
|
||||
|
||||
import { getCompatibleFieldValue } from "./utils";
|
||||
|
||||
/**
|
||||
* 返回商品单价
|
||||
* @param goods 商品
|
||||
* @param user 用户信息
|
||||
* @param {Object} shopInfo
|
||||
*/
|
||||
export function returnGoodsPrice(
|
||||
goods: BaseCartItem,
|
||||
user: ShopUserInfo,
|
||||
shopInfo: ShopInfo,
|
||||
limitTimeDiscount: TimeLimitDiscountConfig | null | undefined
|
||||
) {
|
||||
if (!goods) {
|
||||
return 0;
|
||||
}
|
||||
//是否可以使用会员价
|
||||
const canUseVipPrice =
|
||||
user &&
|
||||
user.isVip &&
|
||||
user.isMemberPrice &&
|
||||
goods.memberPrice * 1 > 0 &&
|
||||
shopInfo &&
|
||||
shopInfo.isMemberPrice;
|
||||
// 商家改价
|
||||
if (goods.discount_sale_amount && goods.discount_sale_amount * 1 > 0) {
|
||||
return goods.salePrice;
|
||||
}
|
||||
// 限时折扣
|
||||
if (limitTimeDiscount && limitTimeDiscount.id) {
|
||||
//优先使用
|
||||
// 兼容 isTimeDiscount/is_time_discount(这里顺便处理该字段的命名兼容)
|
||||
const isTimeDiscount = getCompatibleFieldValue(
|
||||
goods,
|
||||
"isTimeDiscount",
|
||||
"is_time_discount"
|
||||
);
|
||||
if (isTimeDiscount) {
|
||||
return new BigNumber(goods.salePrice)
|
||||
.times(limitTimeDiscount.discountRate / 100)
|
||||
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||
.toNumber();
|
||||
}
|
||||
const canUseFoods = limitTimeDiscount.foods.split(",");
|
||||
const canUseLimit =
|
||||
limitTimeDiscount.foodType == 1 ||
|
||||
canUseFoods.includes(`${goods.productId}`);
|
||||
if (canUseLimit && limitTimeDiscount.discountPriority == "limit-time") {
|
||||
return new BigNumber(goods.salePrice)
|
||||
.times(limitTimeDiscount.discountRate / 100)
|
||||
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||
.toNumber();
|
||||
}
|
||||
|
||||
if (canUseLimit && limitTimeDiscount.discountPriority == "vip-price") {
|
||||
if (canUseVipPrice) {
|
||||
return goods.memberPrice;
|
||||
} else {
|
||||
return new BigNumber(goods.salePrice)
|
||||
.times(limitTimeDiscount.discountRate / 100)
|
||||
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||
.toNumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (canUseVipPrice) {
|
||||
return goods.memberPrice;
|
||||
}
|
||||
return goods.salePrice;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回商品分组
|
||||
* @param arr 商品列表
|
||||
*/
|
||||
export function returnGoodsGroupMap(arr: BaseCartItem[]) {
|
||||
let map: { [key: string]: BaseCartItem[] } = {};
|
||||
arr.forEach((v) => {
|
||||
const key = v.productId + "_" + v.skuId;
|
||||
if (!map[key]) {
|
||||
map[key] = [];
|
||||
}
|
||||
map[key].push(v);
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
interface CouponTypes {
|
||||
1: "满减券";
|
||||
2: "商品券";
|
||||
3: "折扣券";
|
||||
4: "第二件半价券";
|
||||
5: "消费送券";
|
||||
6: "买一送一券";
|
||||
7: "固定价格券";
|
||||
8: "免配送费券";
|
||||
}
|
||||
/**
|
||||
* 优惠券类型:1-满减券,2-商品兑换券,3-折扣券,4-第二件半价券,5-消费送券,6-买一送一券,7-固定价格券,8-免配送费券
|
||||
* @param coupon
|
||||
*/
|
||||
export function returnCoupType(coupon: Coupon) {
|
||||
const couponTypes: CouponTypes = {
|
||||
1: "满减券",
|
||||
2: "商品券",
|
||||
3: "折扣券",
|
||||
4: "第二件半价券",
|
||||
5: "消费送券",
|
||||
6: "买一送一券",
|
||||
7: "固定价格券",
|
||||
8: "免配送费券",
|
||||
};
|
||||
return couponTypes[coupon.type as keyof CouponTypes] || "未知类型";
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回商品券抵扣后的商品列表
|
||||
* @param canDikouGoodsArr 可抵扣商品列表
|
||||
* @param selCoupon 已选择的优惠券列表
|
||||
* @param user 用户信息
|
||||
*/
|
||||
export function returnCanDikouGoodsArr(args: CanDikouGoodsArrArgs) {
|
||||
const { canDikouGoodsArr, selCoupon, user, shopInfo, limitTimeDiscount } =
|
||||
args;
|
||||
const types = [2, 4, 6];
|
||||
// 收集已抵扣商品并关联对应的优惠券类型
|
||||
const goodsCouponGoods = selCoupon
|
||||
.filter((v) => types.includes(v.type))
|
||||
.reduce((prev: BaseCartItem[], cur) => {
|
||||
// 给每个抵扣商品添加所属优惠券类型
|
||||
if (cur && cur.discount) {
|
||||
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) {
|
||||
// 根据优惠券类型判断扣减数量
|
||||
if ([4, 6].includes(findCart.couponType ?? 0)) {
|
||||
// 类型4(第二件半价)或6(买一送一),数量减2
|
||||
if (v.num) {
|
||||
v.num -= 2;
|
||||
}
|
||||
} else {
|
||||
// 其他类型(如类型2商品券),按原逻辑扣减对应数量
|
||||
if (v.num) {
|
||||
v.num -= findCart.num ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return v;
|
||||
})
|
||||
.filter((v) => {
|
||||
const canUseNum = (v.num ?? 0) - (v.returnNum || 0);
|
||||
// 兼容 is_temporary/isTemporary 和 is_gift/isGift
|
||||
const isTemporary = getCompatibleFieldValue(
|
||||
v,
|
||||
"isTemporary",
|
||||
"is_temporary"
|
||||
);
|
||||
const isGift = getCompatibleFieldValue(v, "isGift", "is_gift");
|
||||
|
||||
if (canUseNum <= 0 || isTemporary || isGift) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}); // 过滤掉数量<=0的商品,赠菜,临时菜
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回商品是否享用了会员价/会员折扣
|
||||
* @param {*} goods
|
||||
*/
|
||||
function returnGoodsIsUseVipPrice(
|
||||
shopInfo: ShopInfo,
|
||||
user: ShopUserInfo,
|
||||
goods: BaseCartItem
|
||||
) {
|
||||
// 兼容 isTimeDiscount/is_time_discount
|
||||
const isTimeDiscount = getCompatibleFieldValue(
|
||||
goods,
|
||||
"isTimeDiscount",
|
||||
"is_time_discount"
|
||||
);
|
||||
if (isTimeDiscount) {
|
||||
return false;
|
||||
}
|
||||
if (shopInfo.isMemberPrice != 1 || user.isVip != 1) {
|
||||
return false;
|
||||
}
|
||||
if (shopInfo.isMemberPrice == 1 && user.isVip == 1) {
|
||||
if (goods.memberPrice <= 0) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回可以计算抵扣金额的商品列表
|
||||
*/
|
||||
function returnCanCalcGoodsList(
|
||||
canCalcGoodsArr: BaseCartItem[],
|
||||
coupon: Coupon,
|
||||
shopInfo: ShopInfo,
|
||||
user: ShopUserInfo
|
||||
) {
|
||||
return canCalcGoodsArr.filter((goods) => {
|
||||
// 兼容 isTimeDiscount/is_time_discount
|
||||
const isTimeDiscount = getCompatibleFieldValue(
|
||||
goods,
|
||||
"isTimeDiscount",
|
||||
"is_time_discount"
|
||||
);
|
||||
if (!coupon.discountShare && isTimeDiscount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!coupon.vipPriceShare &&
|
||||
returnGoodsIsUseVipPrice(shopInfo, user, goods)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断优惠券是否可使用,并返回不可用原因
|
||||
*
|
||||
* @param {Object} args - 函数参数集合
|
||||
* @param {Array} args.canDikouGoodsArr - 可参与抵扣的商品列表
|
||||
* @param {Object} args.coupon - 优惠券信息对象
|
||||
* @param {boolean} args.coupon.use - 优惠券是否启用
|
||||
* @param {Array} args.coupon.useFoods - 优惠券适用的商品ID列表
|
||||
* @param {number} args.coupon.fullAmount - 优惠券使用门槛金额
|
||||
* @param {number} args.coupon.type - 优惠券类型
|
||||
* @param {number} args.goodsOrderPrice - 订单中所有商品的总金额
|
||||
* @param {Object} args.user - 用户信息对象
|
||||
* @param {Object} args.selCoupon - 已经选择的优惠券信息对象
|
||||
* @param {Object} args.shopInfo
|
||||
* @param {boolean} args.limitTimeDiscount - 限时折扣
|
||||
* @returns {Object} - { canUse: boolean, reason: string } 可用状态及不可用原因
|
||||
*/
|
||||
export function returnCouponCanUse(args: couponCalcParams) {
|
||||
let {
|
||||
canDikouGoodsArr,
|
||||
coupon,
|
||||
goodsOrderPrice,
|
||||
user,
|
||||
selCoupon,
|
||||
shopInfo,
|
||||
isMemberPrice,
|
||||
limitTimeDiscount,
|
||||
} = args;
|
||||
// 优惠券未启用
|
||||
if (!coupon.use) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: coupon.noUseRestrictions || "不在可用时间段内",
|
||||
};
|
||||
}
|
||||
if (
|
||||
limitTimeDiscount &&
|
||||
limitTimeDiscount.id &&
|
||||
limitTimeDiscount.foodType == 1 &&
|
||||
!coupon.discountShare
|
||||
) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: coupon.noUseRestrictions || "不可与限时折扣同享",
|
||||
};
|
||||
}
|
||||
|
||||
// 计算门槛金额
|
||||
let fullAmount = goodsOrderPrice;
|
||||
canDikouGoodsArr = returnCanDikouGoodsArr(args);
|
||||
//优惠券指定门槛商品列表
|
||||
let canCalcGoodsArr = [...canDikouGoodsArr];
|
||||
//部分商品参与门槛计算
|
||||
if (coupon.thresholdFoods.length) {
|
||||
canCalcGoodsArr = canDikouGoodsArr.filter((v) => {
|
||||
return coupon.thresholdFoods.find((food) => food.id == v.productId);
|
||||
});
|
||||
}
|
||||
|
||||
canCalcGoodsArr = returnCanCalcGoodsList(
|
||||
canCalcGoodsArr,
|
||||
coupon,
|
||||
shopInfo,
|
||||
user
|
||||
);
|
||||
|
||||
fullAmount = canCalcGoodsArr.reduce((pre, cur) => {
|
||||
return (
|
||||
pre +
|
||||
returnGoodsPrice(cur, user, shopInfo, limitTimeDiscount) * (cur.num || 0)
|
||||
);
|
||||
}, 0);
|
||||
|
||||
// 是否全部商品可用
|
||||
const isDikouAll = coupon.useFoods.length === 0;
|
||||
// 订单可用商品列表
|
||||
let canUseGoodsArr: BaseCartItem[] = [];
|
||||
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 || 0)) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: `满${coupon.fullAmount}元可用,当前可参与金额${fullAmount}元`,
|
||||
};
|
||||
}
|
||||
}
|
||||
// 商品兑换券,第二件半价和买一送一判断是否有可用商品
|
||||
if ([2, 4, 5].includes(coupon.type)) {
|
||||
// 没有符合条件的商品
|
||||
if (isDikouAll && canDikouGoodsArr.length === 0) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: "没有符合条件的商品",
|
||||
};
|
||||
}
|
||||
if (!isDikouAll && canUseGoodsArr.length === 0) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: "没有符合条件的商品",
|
||||
};
|
||||
}
|
||||
if (coupon.type == 2) {
|
||||
if (canCalcGoodsArr.length <= 0) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: "没有符合计算门槛条件的商品",
|
||||
};
|
||||
}
|
||||
if (fullAmount < (coupon.fullAmount || 0)) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: `满${coupon.fullAmount}元可用,当前可参与金额${fullAmount}元`,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
//商品兑换券是否达到门槛金额
|
||||
if (coupon.type == 2 && goodsOrderPrice < (coupon.fullAmount || 0)) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: `满${coupon.fullAmount}元可用,当前可参与金额${fullAmount}元`,
|
||||
};
|
||||
}
|
||||
|
||||
// 买一送一券特殊验证
|
||||
if (coupon.type === 6) {
|
||||
let canUse = false;
|
||||
if (isDikouAll) {
|
||||
canUse = canDikouGoodsArr.some((v) => (v.num || 0) >= 2);
|
||||
} else if (canUseGoodsArr.length > 0) {
|
||||
canUse = canUseGoodsArr.some((v) => (v.num || 0) >= 2);
|
||||
}
|
||||
|
||||
if (!canUse) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: "需要购买至少2件相同的商品才能使用",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 第二件半价券特殊验证
|
||||
if (coupon.type === 4) {
|
||||
let canUse = false;
|
||||
if (isDikouAll) {
|
||||
canUse = canDikouGoodsArr.some((v) => (v.num || 0) >= 2);
|
||||
} else if (canUseGoodsArr.length > 0) {
|
||||
canUse = canUseGoodsArr.some((v) => (v.num || 0) >= 2);
|
||||
}
|
||||
if (!canUse) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: "需要购买至少2件相同的商品才能使用",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 所有条件都满足
|
||||
return {
|
||||
canUse: true,
|
||||
reason: "",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算抵扣商品金额
|
||||
* @param discountGoodsArr 可抵扣商品列表
|
||||
* @param discountNum 抵扣数量
|
||||
* @param user 用户信息
|
||||
* @param {Object} shopInfo 店铺信息
|
||||
*/
|
||||
export function calcDiscountGoodsArrPrice(
|
||||
discountGoodsArr: BaseCartItem[],
|
||||
discountNum: number,
|
||||
user: ShopUserInfo,
|
||||
shopInfo: ShopInfo,
|
||||
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined
|
||||
) {
|
||||
let hasCountNum = 0;
|
||||
let discountPrice = 0;
|
||||
let hasDiscountGoodsArr:BaseCartItem[] = [];
|
||||
|
||||
for (let i = 0; i < discountGoodsArr.length; i++) {
|
||||
if (hasCountNum >= discountNum) {
|
||||
break;
|
||||
}
|
||||
const goods = discountGoodsArr[i];
|
||||
const shengyuNum = discountNum - hasCountNum;
|
||||
const num = Math.min(goods.num || 0, shengyuNum);
|
||||
const realPrice = returnGoodsPrice(
|
||||
goods,
|
||||
user,
|
||||
shopInfo,
|
||||
limitTimeDiscount
|
||||
);
|
||||
|
||||
discountPrice += realPrice * num;
|
||||
|
||||
hasCountNum += num;
|
||||
if(goods){
|
||||
hasDiscountGoodsArr.push({
|
||||
...goods,
|
||||
num,
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
discountPrice,
|
||||
hasDiscountGoodsArr,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算优惠券抵扣金额
|
||||
* @param arr 可抵扣商品列表
|
||||
* @param coupon 优惠券
|
||||
* @param user 用户信息
|
||||
* @param goodsOrderPrice 商品订单金额
|
||||
* @param selCoupon 已选择的优惠券列表
|
||||
* @param shopInfo 店铺信息
|
||||
* @param limitTimeDiscount 限时折扣
|
||||
*/
|
||||
export function returnCouponDiscount(
|
||||
arr: BaseCartItem[],
|
||||
coupon: Coupon,
|
||||
user: ShopUserInfo,
|
||||
goodsOrderPrice: number,
|
||||
selCoupon: Coupon[],
|
||||
shopInfo: ShopInfo,
|
||||
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined
|
||||
) {
|
||||
arr = returnCanDikouGoods(arr, user, shopInfo, limitTimeDiscount);
|
||||
const canDikouGoodsArr = returnCanDikouGoodsArr({
|
||||
canDikouGoodsArr: arr,
|
||||
selCoupon,
|
||||
user,
|
||||
shopInfo,
|
||||
limitTimeDiscount,
|
||||
});
|
||||
if (coupon.type == 2) {
|
||||
return returnCouponProductDiscount(
|
||||
canDikouGoodsArr,
|
||||
coupon,
|
||||
user,
|
||||
shopInfo,
|
||||
limitTimeDiscount
|
||||
);
|
||||
}
|
||||
if (coupon.type == 6) {
|
||||
const result = returnCouponBuyOneGiveOneDiscount(
|
||||
canDikouGoodsArr,
|
||||
coupon,
|
||||
user,
|
||||
shopInfo,
|
||||
limitTimeDiscount
|
||||
);
|
||||
return result;
|
||||
}
|
||||
if (coupon.type == 4) {
|
||||
return returnSecoendDiscount(
|
||||
canDikouGoodsArr,
|
||||
coupon,
|
||||
user,
|
||||
shopInfo,
|
||||
limitTimeDiscount
|
||||
);
|
||||
}
|
||||
if (coupon.type == 3) {
|
||||
return returnCouponZhekouDiscount(
|
||||
canDikouGoodsArr,
|
||||
coupon,
|
||||
user,
|
||||
goodsOrderPrice,
|
||||
selCoupon,
|
||||
limitTimeDiscount
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 折扣券抵扣金额
|
||||
* @param canDikouGoodsArr 可抵扣商品列表
|
||||
* @param coupon 优惠券
|
||||
* @param user 用户信息
|
||||
* @param goodsOrderPrice 商品订单金额
|
||||
* @param selCoupon 已选择的优惠券列表
|
||||
* @param limitTimeDiscount 限时折扣
|
||||
*/
|
||||
export function returnCouponZhekouDiscount(
|
||||
canDikouGoodsArr: BaseCartItem[],
|
||||
coupon: Coupon,
|
||||
user: ShopUserInfo,
|
||||
goodsOrderPrice: number,
|
||||
selCoupon: Coupon[],
|
||||
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined
|
||||
) {
|
||||
let { discountRate, maxDiscountAmount } = coupon;
|
||||
maxDiscountAmount = maxDiscountAmount || 0;
|
||||
// 计算商品优惠券折扣总和,使用BigNumber避免精度问题
|
||||
const goodsCouponDiscount = selCoupon
|
||||
.filter((v) => v.type == 2)
|
||||
.reduce((prve, cur) => {
|
||||
return new BigNumber(prve).plus(
|
||||
new BigNumber(cur?.discount?.discountPrice || 0)
|
||||
);
|
||||
}, new BigNumber(0));
|
||||
|
||||
// 将商品订单价格转换为BigNumber并减去优惠券折扣
|
||||
const adjustedGoodsOrderPrice = new BigNumber(goodsOrderPrice).minus(
|
||||
goodsCouponDiscount
|
||||
);
|
||||
|
||||
// 计算优惠比例:(100 - 折扣率) / 100
|
||||
const discountAmountRatio = new BigNumber(100)
|
||||
.minus(discountRate || 0)
|
||||
.dividedBy(100);
|
||||
|
||||
// 计算折扣金额:调整后的商品订单金额 × 优惠比例
|
||||
let discountPrice = adjustedGoodsOrderPrice
|
||||
.times(discountAmountRatio)
|
||||
.decimalPlaces(2, BigNumber.ROUND_FLOOR)
|
||||
.toNumber();
|
||||
|
||||
// 应用最大折扣金额限制
|
||||
if (maxDiscountAmount !== 0) {
|
||||
discountPrice =
|
||||
discountPrice >= maxDiscountAmount ? maxDiscountAmount : discountPrice;
|
||||
}
|
||||
|
||||
return {
|
||||
discountPrice, // 折扣抵扣金额(即优惠的金额)
|
||||
hasDiscountGoodsArr: [],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品券抵扣金额
|
||||
* @param canDikouGoodsArr 可抵扣商品列表
|
||||
* @param coupon 优惠券
|
||||
* @param user 用户信息
|
||||
* @param shopInfo 店铺信息
|
||||
*/
|
||||
export function returnCouponProductDiscount(
|
||||
canDikouGoodsArr: BaseCartItem[],
|
||||
coupon: Coupon,
|
||||
user: ShopUserInfo,
|
||||
shopInfo: ShopInfo,
|
||||
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined
|
||||
) {
|
||||
let { useFoods, discountNum, useRule } = coupon;
|
||||
discountNum = discountNum || 0;
|
||||
//抵扣商品数组
|
||||
let discountGoodsArr:BaseCartItem[] = [];
|
||||
|
||||
//抵扣全部商品
|
||||
if (useFoods.length === 0) {
|
||||
if (useRule == "price_asc") {
|
||||
discountGoodsArr = canDikouGoodsArr.slice(discountNum * -1).reverse();
|
||||
} else {
|
||||
discountGoodsArr = canDikouGoodsArr.slice(0, discountNum);
|
||||
}
|
||||
} else {
|
||||
//抵扣选中商品
|
||||
const discountSelGoodsArr = canDikouGoodsArr.filter((v) =>
|
||||
useFoods.find((food) => food.id == v.productId)
|
||||
);
|
||||
if (useRule == "price_asc") {
|
||||
discountGoodsArr = discountSelGoodsArr.slice(discountNum * -1).reverse();
|
||||
} else {
|
||||
discountGoodsArr = discountSelGoodsArr.slice(0, discountNum);
|
||||
}
|
||||
}
|
||||
|
||||
const result = calcDiscountGoodsArrPrice(
|
||||
discountGoodsArr,
|
||||
discountNum,
|
||||
user,
|
||||
shopInfo,
|
||||
limitTimeDiscount
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回买一送一券抵扣详情
|
||||
* @param canDikouGoodsArr 可抵扣商品列表
|
||||
* @param coupon 优惠券
|
||||
* @param user 用户信息
|
||||
* @param shopInfo 店铺信息
|
||||
*/
|
||||
function returnCouponBuyOneGiveOneDiscount(
|
||||
canDikouGoodsArr: BaseCartItem[],
|
||||
coupon: Coupon,
|
||||
user: ShopUserInfo,
|
||||
shopInfo: ShopInfo,
|
||||
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined
|
||||
) {
|
||||
const { useFoods, useRule } = coupon;
|
||||
//抵扣商品
|
||||
let discountGoods:BaseCartItem | undefined = undefined;
|
||||
//符合买一送一条件的商品(数量>=2 + 非临时/非赠品)
|
||||
const canUseGoods = canDikouGoodsArr.filter((v) => {
|
||||
const isTemporary = getCompatibleFieldValue(
|
||||
v,
|
||||
"isTemporary",
|
||||
"is_temporary"
|
||||
);
|
||||
const isGift = getCompatibleFieldValue(v, "isGift", "is_gift");
|
||||
return (v.num || 0) >= 2 && !isTemporary && !isGift;
|
||||
});
|
||||
//抵扣全部商品
|
||||
if (useFoods.length === 0) {
|
||||
if (useRule == "price_asc") {
|
||||
discountGoods = canUseGoods[canUseGoods.length - 1];
|
||||
} else {
|
||||
discountGoods = canUseGoods[0];
|
||||
}
|
||||
} else {
|
||||
//符合抵扣条件的商品
|
||||
const canUseGoods1 = canUseGoods.filter((v) =>
|
||||
useFoods.find((food) => food.id == v.productId)
|
||||
);
|
||||
if (useRule == "price_asc") {
|
||||
discountGoods = canUseGoods1[canUseGoods1.length - 1];
|
||||
} else {
|
||||
discountGoods = canUseGoods1[0];
|
||||
}
|
||||
}
|
||||
let discountPrice = 0;
|
||||
let hasDiscountGoodsArr: BaseCartItem[] = [];
|
||||
if (discountGoods) {
|
||||
discountPrice = returnGoodsPrice(
|
||||
discountGoods,
|
||||
user,
|
||||
shopInfo,
|
||||
limitTimeDiscount
|
||||
);
|
||||
hasDiscountGoodsArr = [discountGoods];
|
||||
}
|
||||
return {
|
||||
discountPrice: discountPrice <= 0 ? 0 : discountPrice,
|
||||
hasDiscountGoodsArr,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回第二件半价券抵扣详情
|
||||
* @param canDikouGoodsArr 可抵扣商品列表
|
||||
* @param coupon 优惠券
|
||||
* @param user 用户信息
|
||||
* @param shopInfo 店铺信息
|
||||
*/
|
||||
function returnSecoendDiscount(
|
||||
canDikouGoodsArr: BaseCartItem[],
|
||||
coupon: Coupon,
|
||||
user: ShopUserInfo,
|
||||
shopInfo: ShopInfo,
|
||||
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined
|
||||
) {
|
||||
const { useFoods, useRule } = coupon;
|
||||
//抵扣商品
|
||||
let discountGoods:BaseCartItem | undefined = undefined;
|
||||
//符合条件的商品(数量>=2 + 非临时/非赠品)
|
||||
const canUseGoods = canDikouGoodsArr.filter((v) => {
|
||||
const isTemporary = getCompatibleFieldValue(
|
||||
v,
|
||||
"isTemporary",
|
||||
"is_temporary"
|
||||
);
|
||||
const isGift = getCompatibleFieldValue(v, "isGift", "is_gift");
|
||||
return (v.num || 0) >= 2 && !isTemporary && !isGift;
|
||||
});
|
||||
//抵扣全部商品
|
||||
if (useFoods.length === 0) {
|
||||
if (useRule == "price_asc") {
|
||||
discountGoods = canUseGoods[canUseGoods.length - 1];
|
||||
} else {
|
||||
discountGoods = canUseGoods[0];
|
||||
}
|
||||
} else {
|
||||
//符合抵扣条件的商品
|
||||
const canUseGoods1 = canUseGoods.filter((v) =>
|
||||
useFoods.find((food) => food.id == v.productId)
|
||||
);
|
||||
if (useRule == "price_asc") {
|
||||
discountGoods = canUseGoods1[canUseGoods1.length - 1];
|
||||
} else {
|
||||
discountGoods = canUseGoods1[0];
|
||||
}
|
||||
}
|
||||
let discountPrice = 0;
|
||||
let hasDiscountGoodsArr: BaseCartItem[] = [];
|
||||
if (discountGoods) {
|
||||
discountPrice = returnGoodsPrice(
|
||||
discountGoods,
|
||||
user,
|
||||
shopInfo,
|
||||
limitTimeDiscount
|
||||
);
|
||||
hasDiscountGoodsArr = [discountGoods];
|
||||
}
|
||||
//返回半价价格
|
||||
return {
|
||||
discountPrice:
|
||||
discountPrice <= 0
|
||||
? 0
|
||||
: new BigNumber(discountPrice).dividedBy(2).toNumber(),
|
||||
hasDiscountGoodsArr,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回可以抵扣优惠券的商品列表,过滤掉赠品、临时商品,价格从高到低排序
|
||||
* @param arr 商品列表
|
||||
* @param user 用户信息
|
||||
* @param shopInfo 店铺信息
|
||||
* @param limitTimeDiscount 限时折扣
|
||||
*/
|
||||
export function returnCanDikouGoods(
|
||||
arr: BaseCartItem[],
|
||||
user: ShopUserInfo,
|
||||
shopInfo: ShopInfo,
|
||||
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined
|
||||
) {
|
||||
const result = arr
|
||||
.filter((v) => {
|
||||
// 兼容 is_temporary/isTemporary 和 is_gift/isGift
|
||||
const isTemporary = getCompatibleFieldValue(
|
||||
v,
|
||||
"isTemporary",
|
||||
"is_temporary"
|
||||
);
|
||||
const isGift = getCompatibleFieldValue(v, "isGift", "is_gift");
|
||||
return !isTemporary && !isGift;
|
||||
})
|
||||
.filter((v) => {
|
||||
return (v.num || 0) > 0;
|
||||
})
|
||||
.sort((a, b) => {
|
||||
return (
|
||||
returnGoodsPrice(b, user, shopInfo, limitTimeDiscount) -
|
||||
returnGoodsPrice(a, user, shopInfo, limitTimeDiscount)
|
||||
);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
export const utils = {
|
||||
returnGoodsPrice,
|
||||
returnGoodsGroupMap,
|
||||
returnCoupType,
|
||||
returnCanDikouGoods,
|
||||
returnCanDikouGoodsArr,
|
||||
returnCouponCanUse,
|
||||
calcDiscountGoodsArrPrice,
|
||||
returnCouponDiscount,
|
||||
returnCouponProductDiscount,
|
||||
returnCouponZhekouDiscount,
|
||||
};
|
||||
|
||||
export default utils;
|
||||
1275
lib/goods-1.0.47-back.ts
Normal file
1275
lib/goods-1.0.47-back.ts
Normal file
File diff suppressed because it is too large
Load Diff
1388
lib/goods.ts
Normal file
1388
lib/goods.ts
Normal file
File diff suppressed because it is too large
Load Diff
11
lib/index.ts
Normal file
11
lib/index.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export * from "./types";
|
||||
import OrderPriceCalculator from "./goods";
|
||||
import couponUtils from "./coupon";
|
||||
import limitUtils from "./limit";
|
||||
|
||||
export { OrderPriceCalculator, couponUtils, limitUtils };
|
||||
export default {
|
||||
OrderPriceCalculator,
|
||||
couponUtils,
|
||||
limitUtils,
|
||||
};
|
||||
216
lib/limit.ts
Normal file
216
lib/limit.ts
Normal file
@@ -0,0 +1,216 @@
|
||||
import BigNumber from "bignumber.js";
|
||||
|
||||
import _ from "lodash";
|
||||
|
||||
import {
|
||||
BaseCartItem,
|
||||
ShopUserInfo,
|
||||
ShopInfo,
|
||||
TimeLimitDiscountConfig,
|
||||
CanReturnMemberPriceArgs,
|
||||
returnPriceArgs,
|
||||
} from "./types";
|
||||
|
||||
/**
|
||||
* 判断商品是否可以使用限时折扣
|
||||
* @param goods 商品对象
|
||||
* @param limitTimeDiscountRes 限时折扣配置
|
||||
* @param shopInfo 店铺信息
|
||||
* @param shopUserInfo 店铺用户信息
|
||||
* @param idKey 商品ID键名,默认"id"
|
||||
* @returns
|
||||
*/
|
||||
export function canUseLimitTimeDiscount(
|
||||
goods: BaseCartItem,
|
||||
limitTimeDiscountRes: TimeLimitDiscountConfig | null | undefined,
|
||||
shopInfo: ShopInfo,
|
||||
shopUserInfo: ShopUserInfo,
|
||||
idKey = "id" as keyof BaseCartItem
|
||||
) {
|
||||
shopInfo = shopInfo || {};
|
||||
shopUserInfo = shopUserInfo || {};
|
||||
if(shopInfo.isMemberPrice){
|
||||
shopUserInfo.isMemberPrice=1
|
||||
}
|
||||
if (!limitTimeDiscountRes || !limitTimeDiscountRes.id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const canUseFoods = (limitTimeDiscountRes.foods || "").split(",");
|
||||
|
||||
const goodsCanUse =
|
||||
limitTimeDiscountRes.foodType == 1 ||
|
||||
canUseFoods.includes(`${goods[idKey]}`);
|
||||
if (!goodsCanUse) {
|
||||
return false;
|
||||
}
|
||||
if (limitTimeDiscountRes.discountPriority == "limit-time") {
|
||||
return true;
|
||||
}
|
||||
if (limitTimeDiscountRes.discountPriority == "vip-price") {
|
||||
if (
|
||||
shopUserInfo.isVip == 1 &&
|
||||
shopUserInfo.isMemberPrice == 1 &&
|
||||
goods.memberPrice * 1 > 0
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回商品显示价格
|
||||
* @params {*} args 参数对象
|
||||
* @params {*} args.goods 商品对象
|
||||
* @params {*} args.shopInfo 店铺信息
|
||||
* @params {*} args.limitTimeDiscountRes 限时折扣信息
|
||||
* @params {*} args.shopUserInfo 店铺用户信息
|
||||
* @returns
|
||||
*/
|
||||
export function returnPrice(args: returnPriceArgs) {
|
||||
let {
|
||||
goods,
|
||||
shopInfo,
|
||||
limitTimeDiscountRes,
|
||||
shopUserInfo,
|
||||
idKey = "product_id",
|
||||
} = args;
|
||||
limitTimeDiscountRes = limitTimeDiscountRes || {
|
||||
foods: "",
|
||||
foodType: 2,
|
||||
discountPriority: "",
|
||||
discountRate: 0,
|
||||
id: 0,
|
||||
shopId: 0,
|
||||
useType: "",
|
||||
};
|
||||
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 &&
|
||||
shopInfo.isMemberPrice == 1
|
||||
) {
|
||||
const memberPrice = goods.memberPrice || goods.salePrice;
|
||||
|
||||
//是会员而且启用会员价
|
||||
if (limitTimeDiscountRes) {
|
||||
//使用限时折扣
|
||||
//限时折扣优先
|
||||
if (limitTimeDiscountRes.discountPriority == "limit-time") {
|
||||
if (includesGoods) {
|
||||
return returnLimitPrice({
|
||||
price: goods.salePrice,
|
||||
limitTimeDiscountRes,
|
||||
});
|
||||
} else {
|
||||
return memberPrice;
|
||||
}
|
||||
}
|
||||
if (
|
||||
limitTimeDiscountRes.discountPriority == "vip-price" &&
|
||||
includesGoods
|
||||
) {
|
||||
if (goods.memberPrice * 1 > 0) {
|
||||
//会员优先
|
||||
return memberPrice;
|
||||
} else {
|
||||
const price = returnLimitPrice({
|
||||
price: goods.salePrice,
|
||||
limitTimeDiscountRes,
|
||||
goods: goods,
|
||||
});
|
||||
|
||||
return price;
|
||||
}
|
||||
} else {
|
||||
return memberPrice;
|
||||
}
|
||||
} else {
|
||||
//是会员没有限时折扣
|
||||
return memberPrice;
|
||||
}
|
||||
} else {
|
||||
//不是会员或者没有启用会员价
|
||||
if (limitTimeDiscountRes && limitTimeDiscountRes.id && includesGoods) {
|
||||
const price = returnLimitPrice({
|
||||
price: goods.salePrice,
|
||||
limitTimeDiscountRes,
|
||||
goods: goods,
|
||||
});
|
||||
|
||||
return price;
|
||||
} else {
|
||||
return goods.salePrice;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface returnLimitPriceArgs {
|
||||
limitTimeDiscountRes: TimeLimitDiscountConfig | null | undefined;
|
||||
price: number;
|
||||
goods?: BaseCartItem;
|
||||
}
|
||||
/**
|
||||
* 返回限时折扣价格
|
||||
* @params {*} args 参数对象
|
||||
* @params {*} args.limitTimeDiscountRes 限时折扣信息
|
||||
* @params {*} args.price 商品价格
|
||||
* @param {*} args.goods 商品对象
|
||||
* @returns
|
||||
*/
|
||||
export function returnLimitPrice(args: returnLimitPriceArgs) {
|
||||
const { limitTimeDiscountRes, price, goods } = args;
|
||||
const discountRate = new BigNumber(
|
||||
limitTimeDiscountRes ? limitTimeDiscountRes.discountRate : 100
|
||||
).dividedBy(100);
|
||||
|
||||
const result = BigNumber(price)
|
||||
.times(discountRate)
|
||||
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||
.toNumber();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否返回会员价
|
||||
* @param {*} args 参数对象
|
||||
* @param {*} args.shopInfo 店铺信息
|
||||
* @param {*} args.shopUserInfo 店铺用户信息
|
||||
* @returns
|
||||
*/
|
||||
export function canReturnMemberPrice(args: CanReturnMemberPriceArgs) {
|
||||
const { shopInfo, shopUserInfo } = args;
|
||||
if (shopUserInfo.isMemberPrice == 1 && shopUserInfo.isVip == 1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回会员价格
|
||||
* @param {*} goods
|
||||
* @returns
|
||||
*/
|
||||
export function returnMemberPrice(goods: BaseCartItem) {
|
||||
return goods.memberPrice || goods.salePrice;
|
||||
}
|
||||
|
||||
export const utils = {
|
||||
returnPrice,
|
||||
canUseLimitTimeDiscount,
|
||||
returnLimitPrice,
|
||||
canReturnMemberPrice,
|
||||
returnMemberPrice,
|
||||
};
|
||||
|
||||
export default utils;
|
||||
0
lib/socket.ts
Normal file
0
lib/socket.ts
Normal file
430
lib/types.ts
Normal file
430
lib/types.ts
Normal file
@@ -0,0 +1,430 @@
|
||||
/** 商品类型枚举 */
|
||||
export enum GoodsType {
|
||||
NORMAL = "normal", // 普通商品
|
||||
WEIGHT = "weight", // 称重商品
|
||||
GIFT = "gift", // 赠菜(继承普通商品逻辑,标记用)
|
||||
EMPTY = "", // 空字符串类型(后端未返回时默认归类为普通商品)
|
||||
PACKAGE = "package", // 打包商品(如套餐/预打包商品,按普通商品逻辑处理,可扩展特殊规则)
|
||||
}
|
||||
|
||||
/** 优惠券计算结果类型(新增细分字段) */
|
||||
export interface CouponResult {
|
||||
deductionAmount: number; // 抵扣金额
|
||||
excludedProductIds: string[]; // 不适用商品ID列表(注意:是商品ID,非购物车ID)
|
||||
usedCoupon: Coupon | undefined; // 实际使用的优惠券
|
||||
productCouponDeduction: number; // 新增:商品优惠券抵扣(兑换券等)
|
||||
fullCouponDeduction: number; // 新增:满减优惠券抵扣
|
||||
}
|
||||
|
||||
/** 兑换券计算结果类型(新增细分字段) */
|
||||
export interface ExchangeCalculationResult {
|
||||
deductionAmount: number;
|
||||
excludedProductIds: string[]; // 不适用商品ID列表(商品ID)
|
||||
productCouponDeduction: number; // 新增:兑换券属于商品券,同步记录
|
||||
}
|
||||
|
||||
export interface CouponTypes {
|
||||
1: "满减券";
|
||||
2: "商品券";
|
||||
3: "折扣券";
|
||||
4: "第二件半价券";
|
||||
5: "消费送券";
|
||||
6: "买一送一券";
|
||||
7: "固定价格券";
|
||||
8: "免配送费券";
|
||||
}
|
||||
|
||||
/** 优惠券类型枚举 */
|
||||
export enum CouponType {
|
||||
FULL_REDUCTION = "full_reduction", // 满减券
|
||||
DISCOUNT = "discount", // 折扣券
|
||||
SECOND_HALF = "second_half", // 第二件半价券
|
||||
BUY_ONE_GET_ONE = "buy_one_get_one", // 买一送一券
|
||||
EXCHANGE = "exchange", // 商品兑换券
|
||||
}
|
||||
|
||||
/** 后端返回的优惠券原始字段类型 */
|
||||
export interface BackendCoupon {
|
||||
id?: number; // 自增主键(int64)
|
||||
shopId?: number; // 店铺ID(int64)
|
||||
syncId?: number; // 同步Id(int64)
|
||||
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快递
|
||||
validType?: string; // 有效期类型:fixed(固定时间),custom(自定义时间)
|
||||
validDays?: number; // 有效期(天)
|
||||
validStartTime?: string; // 有效期开始时间(如"2024-01-01 00:00:00")
|
||||
validEndTime?: string; // 有效期结束时间
|
||||
daysToTakeEffect?: number; // 隔天生效
|
||||
useDays?: string; // 可用周期(如"周一,周二")
|
||||
useTimeType?: string; // 可用时间段类型:all-全时段,custom-指定时段
|
||||
useStartTime?: string; // 可用开始时间(每日)
|
||||
useEndTime?: string; // 可用结束时间(每日)
|
||||
getType?: string; // 发放设置:不可自行领取/no,可领取/yes
|
||||
getMode?: string; // 用户领取方式
|
||||
giveNum?: number; // 总发放数量,-10086为不限量
|
||||
getUserType?: string; // 可领取用户:全部/all,新用户一次/new,仅会员/vip
|
||||
getLimit?: number; // 每人领取限量,-10086为不限量
|
||||
useLimit?: number; // 每人每日使用限量,-10086为不限量
|
||||
discountShare?: number; // 与限时折扣同享:0-否,1-是
|
||||
vipPriceShare?: number; // 与会员价同享:0-否,1-是
|
||||
ruleDetails?: string; // 附加规则说明
|
||||
status?: number; // 状态:0-禁用,1-启用
|
||||
useNum?: number; // 已使用数量
|
||||
leftNum?: number; // 剩余数量
|
||||
foods?: string; // 指定门槛商品(逗号分隔字符串,如"101,102",此处为商品ID)
|
||||
fullAmount?: number; // 使用门槛:满多少金额(元)
|
||||
discountAmount?: number; // 使用门槛:减多少金额(元)
|
||||
discountRate?: number; // 折扣%(如90=9折)
|
||||
maxDiscountAmount?: number; // 可抵扣最大金额(元)
|
||||
useRule?: string; // 使用规则:price_asc-价格低到高,price_desc-高到低
|
||||
discountNum?: number; // 抵扣数量
|
||||
otherCouponShare?: number; // 与其它优惠共享:0-否,1-是
|
||||
createTime?: string; // 创建时间
|
||||
updateTime?: string; // 更新时间
|
||||
}
|
||||
|
||||
/** 营销活动类型枚举 */
|
||||
export enum ActivityType {
|
||||
TIME_LIMIT_DISCOUNT = "time_limit_discount", // 限时折扣
|
||||
}
|
||||
|
||||
/** 基础购物车商品项(核心修正:新增product_id,明确各ID含义) */
|
||||
export interface BaseCartItem {
|
||||
id: string | number; // 购物车ID(唯一标识购物车中的条目,如购物车项主键)
|
||||
product_id: string | number; // 商品ID(唯一标识商品,用于优惠券/活动匹配,必选)
|
||||
productId?: string | number; // 商品ID
|
||||
salePrice: number; // 商品原价(元)
|
||||
number: number; // 商品数量
|
||||
num?: number; // 商品数量
|
||||
isTimeDiscount?: boolean; // 是否限时折扣商品(默认false)
|
||||
is_time_discount?: boolean; // 是否限时折扣商品(默认false)
|
||||
product_type: GoodsType; // 商品类型
|
||||
is_temporary?: boolean; // 是否临时菜(默认false)
|
||||
isTemporary?: boolean; // 是否临时菜(默认false)
|
||||
is_gift?: boolean; // 是否赠菜(默认false)
|
||||
isGift?: boolean; // 是否赠菜(默认false)
|
||||
returnNum?: number; // 退货数量(历史订单用,默认0)
|
||||
memberPrice: number; // 商品会员价(元,优先级:商品会员价 > 会员折扣)
|
||||
discountSaleAmount?: number; // 商家改价后单价(元,优先级最高)
|
||||
discount_sale_amount?: number; // 商家改价后单价(元,优先级最高)
|
||||
packFee?: number; // 单份打包费(元,默认0)
|
||||
packNumber?: number; // 堂食打包数量(默认0)
|
||||
activityInfo?: {
|
||||
// 商品参与的营销活动(如限时折扣)
|
||||
type: ActivityType;
|
||||
discountRate: number; // 折扣率(如0.8=8折)
|
||||
vipPriceShare: boolean; // 是否与会员优惠同享(默认false)
|
||||
};
|
||||
skuData?: {
|
||||
// SKU扩展数据(可选)
|
||||
id: string | number; // SKU ID(唯一标识商品规格,如颜色/尺寸)
|
||||
memberPrice: number; // SKU会员价
|
||||
salePrice?: number; // SKU原价
|
||||
};
|
||||
skuId?: string | number; // SKU ID(唯一标识商品规格,如颜色/尺寸)
|
||||
couponType?: number; // 优惠券类型:1-满减券,2-商品兑换券,3-折扣券,4-第二件半价券,5-消费送券,6-买一送一券,7-固定价格券,8-免配送费券
|
||||
}
|
||||
|
||||
export interface CouponFoods {
|
||||
id: string;
|
||||
name: string;
|
||||
images: string;
|
||||
}
|
||||
|
||||
/** 基础优惠券接口(所有券类型继承,包含统一门槛商品字段) */
|
||||
export interface BaseCoupon {
|
||||
otherCouponShare?: number; // 与其它优惠共享:0-否,1-是
|
||||
id: string | number; // 优惠券ID
|
||||
type: number; // 工具库字符串枚举(由后端couponType转换)
|
||||
name: string; // 对应后端title
|
||||
available: boolean; // 基于BackendCoupon字段计算的可用性
|
||||
useShopType?: string; // only-仅本店;all-所有门店,custom-指定门店
|
||||
useShops: string[]; // 可用门店ID列表
|
||||
discountShare: boolean; // 与限时折扣同享:0-否,1-是(后端字段转换为布尔值)
|
||||
vipPriceShare: boolean; // 与会员价同享:0-否,1-是(后端字段转换为布尔值)
|
||||
useType?: string[]; // 可使用类型:dine堂食/pickup自取/deliv配送/express快递
|
||||
isValid: boolean; // 是否在有效期内
|
||||
discountAmount?: number; // 减免金额 (满减券有)
|
||||
fullAmount?: number; // 使用门槛:满多少金额
|
||||
maxDiscountAmount?: number; // 可抵扣最大金额 元
|
||||
use: boolean;
|
||||
discountNum?: number; // 抵扣数量
|
||||
useRule?: string; // 使用规则:price_asc-价格低到高,price_desc-高到低
|
||||
discountRate?: number; // 折扣%(如90=9折)
|
||||
noUseRestrictions?: boolean; // 是不可用原因
|
||||
thresholdFoods: CouponFoods[]; // 门槛商品ID列表(空数组=全部商品,非空=指定商品ID)
|
||||
useFoods: CouponFoods[]; // 可用商品ID列表(空数组=全部商品,非空=指定商品ID)
|
||||
}
|
||||
export interface couponDiscount {
|
||||
discountPrice: number;
|
||||
hasDiscountGoodsArr: BaseCartItem[];
|
||||
}
|
||||
/** 满减券(适配后端字段) */
|
||||
export interface FullReductionCoupon extends BaseCoupon {
|
||||
fullAmount: number; // 对应后端fullAmount(满减门槛)
|
||||
discountAmount: number; // 对应后端discountAmount(减免金额)
|
||||
maxDiscountAmount?: number; // 对应后端maxDiscountAmount(最大减免)
|
||||
discount?: couponDiscount;
|
||||
}
|
||||
|
||||
/** 折扣券(适配后端字段) */
|
||||
export interface DiscountCoupon extends BaseCoupon {
|
||||
discountRate: number; // 后端discountRate(%)转小数(如90→0.9)
|
||||
maxDiscountAmount: number; // 对应后端maxDiscountAmount(最大减免)
|
||||
discount?: couponDiscount;
|
||||
}
|
||||
|
||||
/** 第二件半价券(适配后端字段) */
|
||||
export interface SecondHalfPriceCoupon extends BaseCoupon {
|
||||
maxUseCountPerOrder?: number; // 对应后端useLimit(-10086=不限)
|
||||
discount?: couponDiscount;
|
||||
}
|
||||
|
||||
/** 买一送一券(适配后端字段) */
|
||||
export interface BuyOneGetOneCoupon extends BaseCoupon {
|
||||
maxUseCountPerOrder?: number; // 对应后端useLimit(-10086=不限)
|
||||
discount?: couponDiscount;
|
||||
}
|
||||
|
||||
/** 商品兑换券(适配后端字段) */
|
||||
export interface ExchangeCoupon extends BaseCoupon {
|
||||
deductCount: number; // 对应后端discountNum(抵扣数量)
|
||||
sortRule: "low_price_first" | "high_price_first"; // 后端useRule转换
|
||||
discount?: couponDiscount;
|
||||
}
|
||||
|
||||
/** 所有优惠券类型联合 */
|
||||
export type Coupon =
|
||||
| FullReductionCoupon
|
||||
| DiscountCoupon
|
||||
| SecondHalfPriceCoupon
|
||||
| BuyOneGetOneCoupon
|
||||
| ExchangeCoupon;
|
||||
|
||||
/** 营销活动配置(如限时折扣,applicableProductIds为商品ID列表) */
|
||||
export interface ActivityConfig {
|
||||
type: ActivityType;
|
||||
applicableProductIds?: string[]; // 适用商品ID列表(与BaseCartItem.product_id匹配)
|
||||
discountRate: number; // 折扣率(如0.8=8折)
|
||||
vipPriceShare: boolean; // 是否与会员优惠同享
|
||||
}
|
||||
|
||||
/** 积分抵扣规则 */
|
||||
export interface PointDeductionRule {
|
||||
pointsPerYuan: number; // X积分=1元(如100=100积分抵1元)
|
||||
maxDeductionAmount?: number; // 最大抵扣金额(元,默认不限)
|
||||
}
|
||||
|
||||
/** 餐位费配置 */
|
||||
export interface SeatFeeConfig {
|
||||
pricePerPerson: number; // 每人餐位费(元)
|
||||
personCount: number; // 用餐人数(默认1)
|
||||
isEnabled: boolean; // 是否启用餐位费(默认false)
|
||||
}
|
||||
/** 商家减免类型枚举 */
|
||||
export enum MerchantReductionType {
|
||||
FIXED_AMOUNT = "fixed_amount", // 固定金额减免(如直接减 10 元)
|
||||
DISCOUNT_RATE = "discount_rate", // 比例折扣减免(如打 9 折,即减免 10%)
|
||||
}
|
||||
|
||||
/** 商家减免配置(新增,替代原单一金额字段) */
|
||||
export interface MerchantReductionConfig {
|
||||
type: MerchantReductionType; // 减免类型(二选一)
|
||||
fixedAmount?: number; // 固定减免金额(元,仅 FIXED_AMOUNT 生效,≥0)
|
||||
discountRate?: number; // 折扣率(%,仅 DISCOUNT_RATE 生效,0-100,如 90 代表 9 折)
|
||||
}
|
||||
/**商家霸王餐配置 */
|
||||
export interface FreeDineConfig {
|
||||
enable: boolean; //是否开启
|
||||
rechargeThreshold: number; //订单满多少元可以使用
|
||||
rechargeTimes: number; //充值多少倍免单
|
||||
withCoupon: boolean; //与优惠券同享
|
||||
withPoints: boolean; //与积分同享
|
||||
useType?: string[]; //使用类型 dine-in店内 takeout 自取 post快递,takeaway外卖
|
||||
useShopType?: string; //all 全部 part部分
|
||||
shopIdList?: number[]; //可用门店id
|
||||
}
|
||||
|
||||
//限时折扣配置
|
||||
export interface TimeLimitDiscountConfig {
|
||||
/**
|
||||
* 折扣优先级 limit-time/vip-price
|
||||
*/
|
||||
discountPriority: string;
|
||||
/**
|
||||
* 折扣% 范围1-99
|
||||
*/
|
||||
discountRate: number;
|
||||
/**
|
||||
* 参与商品
|
||||
*/
|
||||
foods: string;
|
||||
/**
|
||||
* 参与商品 1全部 2部分
|
||||
*/
|
||||
foodType: number;
|
||||
/**
|
||||
* 自增主键
|
||||
*/
|
||||
id: number;
|
||||
/**
|
||||
* 店铺ID
|
||||
*/
|
||||
shopId: number;
|
||||
/**
|
||||
* 可使用类型:堂食 dine-in 外带 take-out 外卖 take-away 配送 post
|
||||
*/
|
||||
useType: string;
|
||||
[property: string]: any;
|
||||
}
|
||||
|
||||
//用户信息
|
||||
export interface ShopUserInfo {
|
||||
isVip: number | null; //是否会员
|
||||
discount: number | null; //用户折扣
|
||||
isMemberPrice: number | null; //会员折扣与会员价是否同时使用
|
||||
id?: number; //用户ID
|
||||
}
|
||||
/** 订单额外费用配置 */
|
||||
export interface OrderExtraConfig {
|
||||
// merchantReduction: number; // 商家减免金额(元,默认0)
|
||||
// 替换原单一金额字段,支持两种减免形式
|
||||
merchantReduction: MerchantReductionConfig;
|
||||
additionalFee: number; // 附加费(元,如余额充值、券包,默认0)
|
||||
pointDeductionRule: PointDeductionRule; // 积分抵扣规则
|
||||
seatFeeConfig: SeatFeeConfig; // 餐位费配置
|
||||
currentStoreId: string; // 当前门店ID(用于验证优惠券适用门店)
|
||||
userPoints: number; // 用户当前积分(用于积分抵扣)
|
||||
isMember: boolean; // 用户是否会员(用于会员优惠)
|
||||
memberDiscountRate?: number; // 会员折扣率(如0.95=95折,无会员价时用)
|
||||
newUserDiscount?: number; // 新用户减免金额(元,默认0)
|
||||
fullReductionActivities: FullReductionActivity[]; // 当前店铺的满减活动列表(后端返回结构)
|
||||
currentDinnerType: "dine-in" | "take-out" | "take-away" | "post"; // 当前就餐类型(匹配useType)
|
||||
isFreeDine?: boolean; //是否霸王餐
|
||||
freeDineConfig?: FreeDineConfig;
|
||||
limitTimeDiscount?: TimeLimitDiscountConfig; //限时折扣
|
||||
shopUserInfo: ShopUserInfo; // 用户信息
|
||||
}
|
||||
|
||||
/** 订单费用汇总(修改:补充商家减免类型和明细) */
|
||||
export interface OrderCostSummary {
|
||||
goodsList: BaseCartItem[];
|
||||
// 商品总件数
|
||||
goodsTotal: number;
|
||||
totalDiscountAmount: number;
|
||||
goodsRealAmount: number; // 商品真实原价总和
|
||||
goodsOriginalAmount: number; // 商品原价总和
|
||||
goodsDiscountAmount: number; // 商品折扣金额
|
||||
couponDeductionAmount: number; // 优惠券总抵扣
|
||||
productCouponDeduction: number; // 商品优惠券抵扣
|
||||
fullCouponDeduction: number; // 满减优惠券抵扣
|
||||
pointDeductionAmount: number; // 积分抵扣金额
|
||||
seatFee: number; // 餐位费
|
||||
packFee: number; // 打包费
|
||||
scoreMaxMoney: number; // 积分最大可抵扣金额
|
||||
// 新增:商家减免明细
|
||||
merchantReduction: {
|
||||
type: MerchantReductionType; // 实际使用的减免类型
|
||||
originalConfig: MerchantReductionConfig; // 原始配置(便于前端展示)
|
||||
actualAmount: number; // 实际减免金额(计算后的值,≥0)
|
||||
};
|
||||
additionalFee: number; // 附加费
|
||||
finalPayAmount: number; // 最终实付金额
|
||||
couponUsed?: Coupon; // 实际使用的优惠券
|
||||
pointUsed: number; // 实际使用的积分
|
||||
newUserDiscount: number; // 新用户减免金额(元,默认0)
|
||||
dinnerType?: "dine-in" | "take-out"; // 就餐类型(堂食/自取/配送/快递)
|
||||
config: OrderExtraConfig; // 订单额外费用配置
|
||||
//满减活动
|
||||
fullReduction: {
|
||||
usedFullReductionActivityFullAmount: number; // 计算出的满减活动的门槛金额
|
||||
usedActivity?: FullReductionActivity; // 实际使用的满减活动
|
||||
usedThreshold?: FullReductionThreshold; // 实际使用的满减阈值(多门槛中选最优)
|
||||
actualAmount: number; // 满减实际减免金额(元)
|
||||
};
|
||||
vipDiscountAmount: number; //会员折扣减免金额
|
||||
// 订单原支付金额
|
||||
orderOriginFinalPayAmount: number; //订单原金额(包含打包费+餐位费)
|
||||
}
|
||||
|
||||
/** 满减活动阈值(单条满减规则:满X减Y)- 对应 MkDiscountThresholdInsertGroupDefaultGroup */
|
||||
export interface FullReductionThreshold {
|
||||
activityId?: number; // 关联满减活动ID
|
||||
fullAmount?: number; // 满多少金额(元,必填)
|
||||
discountAmount?: number; // 减多少金额(元,必填)
|
||||
}
|
||||
|
||||
/** 满减活动主表 - 对应 Request 接口(后端真实字段) */
|
||||
export interface FullReductionActivity {
|
||||
id?: number; // 自增主键(后端字段:id)
|
||||
shopId?: number; // 店铺ID(后端字段:shopId)
|
||||
status?: number; // 活动状态:1=未开始,2=进行中,3=已结束(后端字段:status)
|
||||
sort?: number; // 排序值(越大优先级越高,后端字段:sort)
|
||||
createTime?: string; // 创建时间(后端字段:createTime,格式如"2025-10-14 13:56:07")
|
||||
updateTime?: string; // 最新修改时间(后端字段:updateTime,用于优先级排序)
|
||||
validStartTime?: string; // 有效期开始时间(后端字段:validStartTime,格式如"2025-10-14")
|
||||
validEndTime?: string; // 有效期结束时间(后端字段:validEndTime,格式如"2025-12-14")
|
||||
useType?: string; // 可使用类型(后端字段:useType,如"dine,pickup,deliv,express")
|
||||
useDays?: string; // 可用周期(后端字段:useDays,如"周一,周二,周三,周四,周五,周六,周日")
|
||||
useTimeType?: string; // 可用时间段类型(后端字段:useTimeType,all=全时段,custom=指定时段)
|
||||
useStartTime?: string; // 每日可用开始时间(后端字段:useStartTime,如"09:00:00",仅custom时有效)
|
||||
useEndTime?: string; // 每日可用结束时间(后端字段:useEndTime,如"22:00:00",仅custom时有效)
|
||||
couponShare?: number; // 与优惠券同享:0=否,1=是(后端字段:couponShare)
|
||||
discountShare?: number; // 与限时折扣同享:0=否,1=是(后端字段:discountShare)
|
||||
vipPriceShare?: number; // 与会员价同享:0=否,1=是(后端字段:vipPriceShare)
|
||||
pointsShare?: number; // 与积分抵扣同享:0=否,1=是(后端字段:pointsShare)
|
||||
thresholds?: FullReductionThreshold[]; // 满减阈值列表(多门槛,后端字段:thresholds)
|
||||
isDel?: boolean; // 是否删除:0=否,1=是(后端字段:isDel,默认false)
|
||||
}
|
||||
|
||||
// 辅助枚举:星期映射(用于useDays校验)
|
||||
export const WEEKDAY_MAP = {
|
||||
周一: 1,
|
||||
周二: 2,
|
||||
周三: 3,
|
||||
周四: 4,
|
||||
周五: 5,
|
||||
周六: 6,
|
||||
周日: 0, // JS中getDay()返回0=周日
|
||||
};
|
||||
|
||||
export interface ShopInfo {
|
||||
isMemberPrice: number; // 是否开启会员价 1是开启
|
||||
[property: string]: any;
|
||||
}
|
||||
|
||||
export interface couponCalcParams {
|
||||
canDikouGoodsArr: BaseCartItem[];
|
||||
coupon: Coupon;
|
||||
user: ShopUserInfo;
|
||||
shopInfo: ShopInfo;
|
||||
selCoupon: Coupon[];
|
||||
goodsOrderPrice: number; //商品订单总价
|
||||
isMemberPrice: number; // 是否开启会员价 1是开启
|
||||
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined;
|
||||
}
|
||||
export interface CanDikouGoodsArrArgs {
|
||||
canDikouGoodsArr: BaseCartItem[];
|
||||
selCoupon: Coupon[];
|
||||
user: ShopUserInfo;
|
||||
shopInfo: ShopInfo;
|
||||
limitTimeDiscount?: TimeLimitDiscountConfig | null | undefined;
|
||||
}
|
||||
export interface returnPriceArgs {
|
||||
goods: BaseCartItem;
|
||||
selCoupon: Coupon[];
|
||||
user: ShopUserInfo;
|
||||
shopInfo: ShopInfo;
|
||||
shopUserInfo: ShopUserInfo;
|
||||
limitTimeDiscountRes?: TimeLimitDiscountConfig | null | undefined;
|
||||
idKey?: keyof BaseCartItem;
|
||||
}
|
||||
|
||||
|
||||
export interface CanReturnMemberPriceArgs {
|
||||
shopInfo?: ShopInfo;
|
||||
shopUserInfo: ShopUserInfo;
|
||||
}
|
||||
33
lib/utils.ts
Normal file
33
lib/utils.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 通用字段兼容工具函数:处理驼峰/下划线命名的字段取值
|
||||
* @param obj 目标对象(如商品信息 BaseCartItem)
|
||||
* @param camelCaseKey 驼峰命名字段(如 'isTemporary')
|
||||
* @param snakeCaseKey 下划线命名字段(如 'is_temporary')
|
||||
* @param defaultValue 默认值(默认 false,适配布尔类型字段)
|
||||
* @returns 字段值(优先取存在的字段,无则返回默认值)
|
||||
*/
|
||||
export function getCompatibleFieldValue(
|
||||
obj: Record<string, any>,
|
||||
camelCaseKey: string,
|
||||
snakeCaseKey: string,
|
||||
defaultValue: boolean = false
|
||||
): boolean {
|
||||
// 优先判断驼峰字段(如果存在且不是 undefined/null)
|
||||
if (
|
||||
obj.hasOwnProperty(camelCaseKey) &&
|
||||
obj[camelCaseKey] !== undefined &&
|
||||
obj[camelCaseKey] !== null
|
||||
) {
|
||||
return Boolean(obj[camelCaseKey]);
|
||||
}
|
||||
// 再判断下划线字段
|
||||
if (
|
||||
obj.hasOwnProperty(snakeCaseKey) &&
|
||||
obj[snakeCaseKey] !== undefined &&
|
||||
obj[snakeCaseKey] !== null
|
||||
) {
|
||||
return Boolean(obj[snakeCaseKey]);
|
||||
}
|
||||
// 都不存在时返回默认值(布尔类型字段默认 false)
|
||||
return defaultValue;
|
||||
}
|
||||
@@ -69,6 +69,8 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -552,4 +554,9 @@ const showOldPrice = computed(() => {});
|
||||
text-decoration: line-through;
|
||||
text-align: right;
|
||||
}
|
||||
.total{
|
||||
padding-top: 32rpx;
|
||||
border-top: 1px solid #EDEDED;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -8,22 +8,13 @@
|
||||
<!-- 先付款 -->
|
||||
<view class="tabBox" v-if="listinfo.status == 'unpaid' || !listinfo.id">
|
||||
<view class="tab">
|
||||
<view
|
||||
v-for="(item, index) in tebtypeList"
|
||||
:key="index"
|
||||
:class="
|
||||
<view v-for="(item, index) in tebtypeList" :key="index" :class="
|
||||
is_type == index
|
||||
? 'tab_item' + (is_type + 1) + ' tab_item active '
|
||||
: 'tab_item'
|
||||
"
|
||||
@click="tabClick(item, index)"
|
||||
>
|
||||
" @click="tabClick(item, index)">
|
||||
<view></view>
|
||||
<image
|
||||
class="icon"
|
||||
:src="is_type == index ? item.url_active : item.url"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<image class="icon" :src="is_type == index ? item.url_active : item.url" mode="aspectFill" />
|
||||
<text class="title" :class="{ active: is_type == index }">{{
|
||||
item.title
|
||||
}}</text>
|
||||
@@ -31,11 +22,9 @@
|
||||
</view>
|
||||
<view class="table" v-if="is_type == 0">
|
||||
<view class="table_left">
|
||||
<image
|
||||
class="icon"
|
||||
<image class="icon"
|
||||
src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/confirmOrder/table.png"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
mode="aspectFill" />
|
||||
<text class="title">桌台</text>
|
||||
</view>
|
||||
<view class="value" v-if="listinfo.tableName">
|
||||
@@ -51,69 +40,25 @@
|
||||
:nowCarts="nowCarts"
|
||||
:limitDiscount="cartStore.limitTimeDiscount"
|
||||
></orderItemVue> -->
|
||||
<orderItemVue
|
||||
:useVipPrice="useVipPrice"
|
||||
v-if="cartStore.allGoods.length"
|
||||
:nowCarts="cartStore.allGoods"
|
||||
:limitDiscount="cartStore.limitTimeDiscount"
|
||||
></orderItemVue>
|
||||
<template v-if="false">
|
||||
<view
|
||||
class="card_item"
|
||||
v-for="(value, key) in listinfo.detailMap"
|
||||
:key="key"
|
||||
>
|
||||
<view class="shop-info">
|
||||
<view class="item" v-for="item in value" :key="item.id">
|
||||
<view class="cover">
|
||||
<up-image
|
||||
width="76"
|
||||
height="76"
|
||||
radius="6"
|
||||
:src="item.productImg"
|
||||
v-if="item.productId != -999"
|
||||
></up-image>
|
||||
<up-image
|
||||
width="76"
|
||||
height="76"
|
||||
radius="6"
|
||||
:src="'https://czg-qr-order.oss-cn-beijing.aliyuncs.com/confirmOrder/table.png'"
|
||||
mode="heightFix"
|
||||
v-else
|
||||
></up-image>
|
||||
</view>
|
||||
<view class="info">
|
||||
<text class="productName">{{ item.productName }}</text>
|
||||
<text class="productSkuName" v-if="item.skuName">{{
|
||||
item.skuName
|
||||
}}</text>
|
||||
</view>
|
||||
<view class="price">
|
||||
<view class="priceAmount">
|
||||
<text v-if="isBwc">{{ item.price }}</text>
|
||||
<text v-else>
|
||||
¥{{
|
||||
useVipPrice
|
||||
? item.memberPrice || item.price
|
||||
: item.price
|
||||
}}
|
||||
<orderItemVue :useVipPrice="useVipPrice" v-if="cartStore.allGoods.length" :nowCarts="cartStore.allGoods"
|
||||
:limitDiscount="cartStore.limitTimeDiscount"></orderItemVue>
|
||||
|
||||
|
||||
|
||||
<view class="total-wrap u-m-t-30" v-if="listinfo.status == 'unpaid' || !listinfo.id">
|
||||
<text>总计</text>
|
||||
<text class="u-font-32">¥</text>
|
||||
<text class="price">
|
||||
{{ cartStore.orderCostSummary.goodsRealAmount }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="num">x{{ item.num }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<view
|
||||
class="total-wrap u-m-t-30"
|
||||
v-if="listinfo.status == 'unpaid' || !listinfo.id"
|
||||
>
|
||||
<view>总计¥</view>
|
||||
<view class="price">
|
||||
<view class="total-wrap u-m-t-30" v-else>
|
||||
<text>总计</text>
|
||||
<text class="u-font-32">¥</text>
|
||||
<text class="price">
|
||||
{{ cartStore.orderCostSummary.goodsRealAmount }}
|
||||
</view>
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<!-- <view class="total-wrap" v-else>
|
||||
@@ -150,89 +95,54 @@
|
||||
</view> -->
|
||||
|
||||
<!-- 支付之前 -->
|
||||
<block
|
||||
v-if="
|
||||
<block v-if="
|
||||
listinfo.status == 'unpaid' ||
|
||||
listinfo.status == 'paying' ||
|
||||
!listinfo.id
|
||||
"
|
||||
>
|
||||
">
|
||||
<view class="u-m-t-40 u-p-l-20 u-p-r-20">
|
||||
<view
|
||||
class="youhui-item"
|
||||
v-if="cartStore.orderCostSummary.fullReduction.actualAmount"
|
||||
>
|
||||
<view class="youhui-item" v-if="cartStore.orderCostSummary.fullReduction.actualAmount">
|
||||
<view class="u-flex align-center">
|
||||
<image
|
||||
src="/static/icon/coup.png"
|
||||
bgColor="#fff"
|
||||
style="width: 50rpx; height: 50rpx"
|
||||
></image>
|
||||
<image src="/static/icon/coup.png" bgColor="#fff" style="width: 50rpx; height: 50rpx">
|
||||
</image>
|
||||
<text class="color-333 font-14 u-m-l-16 no-wrap">满减活动</text>
|
||||
</view>
|
||||
|
||||
<view class="red font-12 u-flex align-center"
|
||||
>-¥{{
|
||||
<view class="red font-12 u-flex align-center">-¥{{
|
||||
cartStore.orderCostSummary.fullReduction.actualAmount
|
||||
}}</view
|
||||
>
|
||||
}}</view>
|
||||
</view>
|
||||
<view
|
||||
class="youhui-item"
|
||||
v-if="cartStore.orderCostSummary.vipDiscountAmount"
|
||||
>
|
||||
<view class="youhui-item" v-if="cartStore.orderCostSummary.vipDiscountAmount">
|
||||
<view class="u-flex align-center">
|
||||
<image
|
||||
src="/static/icon/newUserDiscount.png"
|
||||
bgColor="#fff"
|
||||
style="width: 50rpx; height: 50rpx"
|
||||
></image>
|
||||
<image src="/static/icon/newUserDiscount.png" bgColor="#fff"
|
||||
style="width: 50rpx; height: 50rpx"></image>
|
||||
<text class="color-333 font-14 u-m-l-16 no-wrap">会员折扣</text>
|
||||
</view>
|
||||
|
||||
<view class="red font-12 u-flex align-center"
|
||||
>-¥{{ cartStore.orderCostSummary.vipDiscountAmount }}</view
|
||||
>
|
||||
<view class="red font-12 u-flex align-center">
|
||||
-¥{{ cartStore.orderCostSummary.vipDiscountAmount }}</view>
|
||||
</view>
|
||||
<view class="youhui-item" v-if="newUserDiscount">
|
||||
<view class="u-flex align-center">
|
||||
<image
|
||||
src="/static/icon/newUserDiscount.png"
|
||||
bgColor="#fff"
|
||||
style="width: 50rpx; height: 50rpx"
|
||||
></image>
|
||||
<image src="/static/icon/newUserDiscount.png" bgColor="#fff"
|
||||
style="width: 50rpx; height: 50rpx"></image>
|
||||
<text class="color-333 font-14 u-m-l-16 no-wrap">新客立减</text>
|
||||
</view>
|
||||
|
||||
<view class="red font-12 u-flex align-center"
|
||||
>-¥{{ newUserDiscount }}</view
|
||||
>
|
||||
<view class="red font-12 u-flex align-center">-¥{{ newUserDiscount }}</view>
|
||||
</view>
|
||||
<view
|
||||
class="favorable"
|
||||
v-for="(item, indexe) in favorablelist"
|
||||
:key="indexe"
|
||||
:class="{ column: item.type == 'product' }"
|
||||
@click="goUrl(item)"
|
||||
>
|
||||
<view class="favorable" v-for="(item, indexe) in favorablelist" :key="indexe"
|
||||
:class="{ column: item.type == 'product' }" @click="goUrl(item)">
|
||||
<view class="favorable_left">
|
||||
<view class="u-flex" style="width: 44rpx">
|
||||
<u-image
|
||||
bgColor="#fff"
|
||||
:width="item.width || '50rpx'"
|
||||
:height="item.height || '50rpx'"
|
||||
v-if="item.icon"
|
||||
:src="item.icon"
|
||||
mode=""
|
||||
></u-image>
|
||||
<u-image bgColor="#fff" :width="item.width || '50rpx'"
|
||||
:height="item.height || '50rpx'" v-if="item.icon" :src="item.icon"
|
||||
mode=""></u-image>
|
||||
</view>
|
||||
<text class="name u-m-l-16 no-wrap"> {{ item.name }} </text>
|
||||
<template v-if="item.type == 'points' && !pointObj.disabled">
|
||||
<text
|
||||
class="u-p-l-6"
|
||||
style="color: #666; max-width: 400rpx; font-size: 10px"
|
||||
>
|
||||
「可用积分{{ pointsRes.accountPoints }},最大可抵扣{{
|
||||
<text class="u-p-l-6" style="color: #666; max-width: 400rpx; font-size: 10px">
|
||||
「可用积分{{ cartStore.shopUserInfo.pointsUser?cartStore.shopUserInfo.pointsUser.pointBalance:0}},最大可抵扣{{
|
||||
maxPointDiscount
|
||||
}}元」
|
||||
</text>
|
||||
@@ -241,125 +151,87 @@
|
||||
|
||||
<!-- 优惠卷 -->
|
||||
<view class="favorable_right" v-if="item.type == 'coupon'">
|
||||
<template
|
||||
v-if="cartStore.orderCostSummary.couponDeductionAmount > 0"
|
||||
>
|
||||
<text class="favorable_right_text red"
|
||||
>-¥{{
|
||||
<template v-if="cartStore.orderCostSummary.couponDeductionAmount > 0">
|
||||
<text class="favorable_right_text red">-¥{{
|
||||
cartStore.orderCostSummary.couponDeductionAmount
|
||||
}}</text
|
||||
>
|
||||
}}</text>
|
||||
</template>
|
||||
<template v-else>
|
||||
<text
|
||||
class="favorable_right_text red"
|
||||
v-if="couponObj.disabled"
|
||||
>{{ couponObj.disabledReason }}</text
|
||||
>
|
||||
<text
|
||||
class="favorable_right_text red"
|
||||
v-else-if="hasCouponCanUse"
|
||||
>有可用优惠券</text
|
||||
>
|
||||
<text class="favorable_right_text" v-else
|
||||
>暂无可用优惠券</text
|
||||
>
|
||||
<text class="favorable_right_text red"
|
||||
v-if="couponObj.disabled">{{ couponObj.disabledReason }}</text>
|
||||
<text class="favorable_right_text red" v-else-if="hasCouponCanUse">有可用优惠券</text>
|
||||
<text class="favorable_right_text" v-else>暂无可用优惠券</text>
|
||||
</template>
|
||||
<template v-if="!couponObj.disabled">
|
||||
<up-icon
|
||||
name="arrow-right"
|
||||
color="#575B66"
|
||||
size="16"
|
||||
v-if="
|
||||
<up-icon name="arrow-right" color="#575B66" size="16" v-if="
|
||||
listinfo.status == 'unpaid' ||
|
||||
listinfo.status == 'paying' ||
|
||||
!listinfo.id
|
||||
"
|
||||
></up-icon>
|
||||
"></up-icon>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<!-- 新客立减 -->
|
||||
<view class="favorable_right" v-if="item.type == 'newUser'">
|
||||
<text
|
||||
class="favorable_right_text red"
|
||||
v-if="newUserDiscount > 0"
|
||||
>-¥{{ newUserDiscount }}</text
|
||||
>
|
||||
<text class="favorable_right_text red"
|
||||
v-if="newUserDiscount > 0">-¥{{ newUserDiscount }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 积分 -->
|
||||
<view
|
||||
class="favorable_right u-flex u-col-center"
|
||||
v-if="item.type == 'points'"
|
||||
>
|
||||
<text
|
||||
v-if="pointObj.disabled"
|
||||
class="u-p-l-6 red"
|
||||
style="max-width: 440rpx; font-size: 24rpx"
|
||||
>{{ pointObj.disabledReason }}</text
|
||||
>
|
||||
<template
|
||||
v-else-if="
|
||||
<view class="favorable_right u-flex u-col-center" v-if="item.type == 'points'">
|
||||
<text v-if="pointObj.disabled" class="u-p-l-6 red"
|
||||
style="max-width: 440rpx; font-size: 24rpx">{{ pointObj.disabledReason }}</text>
|
||||
<template v-else-if="
|
||||
usePoints && cartStore.orderCostSummary.pointDeductionAmount
|
||||
"
|
||||
>
|
||||
<up-icon
|
||||
name="checkmark-circle-fill"
|
||||
size="24rpx"
|
||||
color="#FE7E00"
|
||||
></up-icon>
|
||||
">
|
||||
<up-icon name="checkmark-circle-fill" size="24rpx" color="#FE7E00"></up-icon>
|
||||
<text class="red">
|
||||
-¥{{ cartStore.orderCostSummary.pointDeductionAmount }}
|
||||
</text>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<view
|
||||
v-if="maxPointDiscount > 0 && !pointObj.disabled"
|
||||
class="u-flex u-col-center"
|
||||
>
|
||||
<view v-if="maxPointDiscount > 0 && !pointObj.disabled" class="u-flex u-col-center">
|
||||
<view class="round"></view>
|
||||
<text class="color-333 font-12 no-wrap u-m-l-4"
|
||||
>使用抵扣</text
|
||||
>
|
||||
<text class="color-333 font-12 no-wrap u-m-l-4">使用抵扣</text>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-else>
|
||||
<view
|
||||
class="cell-item column"
|
||||
v-if="listinfo.discountInfo && listinfo.discountInfo != '{}'"
|
||||
>
|
||||
<view class="label">优惠折扣</view>
|
||||
<view class="val column">
|
||||
<view
|
||||
class="productCoupon"
|
||||
v-for="(item, index) in listinfo.discountInfo"
|
||||
:key="index"
|
||||
>
|
||||
<view class="name">{{ item.name }}</view>
|
||||
<!-- <view class="num">{{item.amount}}</view> -->
|
||||
<view class="amount" style="margin-left: 10rpx"
|
||||
>{{ item.amount }}元</view
|
||||
>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
<view class="disocunt " v-if="showDiscount">
|
||||
<view class="row" v-if="listinfo.productCouponDiscountAmount">
|
||||
<text class="t">商品券</text>
|
||||
<text class=" price">-{{listinfo.productCouponDiscountAmount}}</text>
|
||||
</view>
|
||||
</block>
|
||||
<view class="row" v-if="listinfo.otherCouponDiscountAmount">
|
||||
<text class="t">优惠券</text>
|
||||
<text class="price">-{{listinfo.otherCouponDiscountAmount}}</text>
|
||||
</view>
|
||||
<view class="row" v-if="listinfo.pointsDiscountAmount">
|
||||
<text class="t">积分抵扣</text>
|
||||
<text class="price">-{{listinfo.pointsDiscountAmount}}</text>
|
||||
</view>
|
||||
<view class="orderInfo">
|
||||
<view class="row" v-if="listinfo.discountActAmount">
|
||||
<text class="t">满减活动</text>
|
||||
<text class="price">-{{listinfo.discountActAmount}}</text>
|
||||
</view>
|
||||
<view class="row" v-if="listinfo.newCustomerDiscountAmount">
|
||||
<text class="t">新客立减</text>
|
||||
<text class="price">-{{listinfo.newCustomerDiscountAmount}}</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
<view class="orderInfo" v-if="listinfo.id&&listinfo.status=='done'">
|
||||
<view class="row" @click="copyHandle(listinfo.orderNo)">
|
||||
<text class="t">订单编号:</text>
|
||||
<text
|
||||
class="info"
|
||||
style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap"
|
||||
>{{ listinfo.orderNo }}(点击复制)</text
|
||||
>
|
||||
<text class="info"
|
||||
style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap">{{ listinfo.orderNo }}(点击复制)</text>
|
||||
</view>
|
||||
<view class="row">
|
||||
<text class="t">下单时间:</text>
|
||||
@@ -381,7 +253,7 @@
|
||||
<text class="info" v-if="listinfo.dineMod == 'take-out'">外带</text>
|
||||
<text class="info" v-if="listinfo.dineMod == 'take-away'">外卖</text>
|
||||
</view>
|
||||
<view class="row" v-if="listinfo.id && listinfo.satus != 'unpaid'">
|
||||
<view class="row">
|
||||
<text class="t">备注:</text>
|
||||
<text class="info u-line-5">{{ listinfo.remark || "" }}</text>
|
||||
</view>
|
||||
@@ -400,10 +272,14 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useCartsStore } from "@/stores/carts.js";
|
||||
import {
|
||||
useCartsStore
|
||||
} from "@/stores/carts.js";
|
||||
import * as discountActivityApi from "@/common/api/market/discountActivity";
|
||||
const cartStore = useCartsStore();
|
||||
import { consumeDiscount } from "@/common/api/market/index.js";
|
||||
import {
|
||||
consumeDiscount
|
||||
} from "@/common/api/market/index.js";
|
||||
import orderItemVue from "./order-item.vue";
|
||||
import {
|
||||
ref,
|
||||
@@ -419,7 +295,13 @@ import {
|
||||
provide,
|
||||
nextTick,
|
||||
} from "vue";
|
||||
import { returnHasCouponCanUse } from "@/utils/coupon.js";
|
||||
import {
|
||||
returnHasCouponCanUse
|
||||
} from "@/utils/coupon.js";
|
||||
import {
|
||||
BigNumber
|
||||
} from "bignumber.js";
|
||||
|
||||
let hasCouponCanUse = ref(false);
|
||||
|
||||
const usePoints = ref(false);
|
||||
@@ -442,15 +324,13 @@ import pointsIcon from "@/static/icon/jifen.png";
|
||||
const emits = defineEmits(["customevent", "istype", "learcoupons"]);
|
||||
|
||||
// teb 切换送餐和打包
|
||||
const tebtypeList = reactive([
|
||||
{
|
||||
const tebtypeList = reactive([{
|
||||
title: "送餐到桌",
|
||||
show: false,
|
||||
type: "table",
|
||||
val: "dine-in",
|
||||
url: "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/confirmOrder/tab1.png",
|
||||
url_active:
|
||||
"https://czg-qr-order.oss-cn-beijing.aliyuncs.com/confirmOrder/tab1_active.png",
|
||||
url_active: "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/confirmOrder/tab1_active.png",
|
||||
},
|
||||
{
|
||||
title: "打包外带",
|
||||
@@ -458,8 +338,7 @@ const tebtypeList = reactive([
|
||||
type: "takeself",
|
||||
val: "take-out",
|
||||
url: "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/confirmOrder/tab2.png",
|
||||
url_active:
|
||||
"https://czg-qr-order.oss-cn-beijing.aliyuncs.com/confirmOrder/tab2_active.png",
|
||||
url_active: "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/confirmOrder/tab2_active.png",
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -537,6 +416,47 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* 判断一个对象里的某些属性是否存在且值不等于0,满足其中一个就返回true,否则false
|
||||
* @param {Object} obj - 要检测的目标对象(若为非对象类型直接返回false)
|
||||
* @param {Array<string>} keys - 要检测的属性名数组(若为非数组/空数组直接返回false)
|
||||
* @returns {boolean} 满足条件返回true,否则返回false
|
||||
*/
|
||||
function isObjHasPropertyAndNotNull(obj, keys) {
|
||||
console.log(obj)
|
||||
// 1. 边界校验:obj必须是有效对象,keys必须是非空数组
|
||||
if (
|
||||
!obj || // 排除null/undefined
|
||||
typeof obj !== 'object' || // 排除字符串/数字/布尔等非对象类型
|
||||
!Array.isArray(keys) || // 确保keys是数组
|
||||
keys.length === 0 // 空数组直接返回false
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. 遍历所有要检测的属性
|
||||
for (const key of keys) {
|
||||
console.log(obj[key])
|
||||
// 检查属性是否是对象自身的(排除原型链上的属性) + 属性值不等于0
|
||||
if (obj.hasOwnProperty(key) && obj[key] !== 0) {
|
||||
return true; // 只要有一个满足,立即返回true
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 所有属性都不满足条件
|
||||
return false;
|
||||
}
|
||||
|
||||
const showDiscount = computed(() => {
|
||||
const keys = ['productCouponDiscountAmount', 'otherCouponDiscountAmount',
|
||||
'pointsDiscountAmount', 'discountActAmount', 'newCustomerDiscountAmount'
|
||||
]
|
||||
if (isObjHasPropertyAndNotNull(props.listinfo, keys)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
const is_type = ref(0);
|
||||
|
||||
//满减活动
|
||||
@@ -575,6 +495,14 @@ const couponObj = computed(() => {
|
||||
return obj;
|
||||
});
|
||||
|
||||
|
||||
//积分可抵扣最大金额
|
||||
const maxMoney = computed(() => {
|
||||
return (
|
||||
cartStore.orderCostSummary.orderOriginFinalPayAmount +
|
||||
cartStore.orderCostSummary.pointDeductionAmount
|
||||
);
|
||||
});
|
||||
const pointObj = computed(() => {
|
||||
const obj = {
|
||||
disabled: false,
|
||||
@@ -596,10 +524,11 @@ const pointObj = computed(() => {
|
||||
obj.disabledReason = "当前满减活动不可与积分同享";
|
||||
}
|
||||
}
|
||||
|
||||
//积分抵扣不足
|
||||
if (pointsRes && !pointsRes.usable) {
|
||||
obj.disabledReason = pointsRes.unusableReason || "积分抵扣不足或不可用";
|
||||
if (maxMoney.value * 1 < cartStore.pointDeductionRule.minPaymentAmount || !cartStore.pointDeductionRule
|
||||
.enableRewards) {
|
||||
obj.disabled = true;
|
||||
obj.disabledReason = "积分抵扣不足或不可用";
|
||||
}
|
||||
if (obj.disabled) {
|
||||
cartStore.setUserPoints(0);
|
||||
@@ -668,47 +597,45 @@ const calcUsablePointsData = reactive({
|
||||
integral: "",
|
||||
});
|
||||
|
||||
const pointsRes = reactive({
|
||||
accountPoints: 0,
|
||||
});
|
||||
|
||||
const maxPointDiscount = ref(0);
|
||||
//积分可抵扣最大金额
|
||||
const maxMoney = computed(() => {
|
||||
return (
|
||||
cartStore.orderCostSummary.orderOriginFinalPayAmount +
|
||||
cartStore.orderCostSummary.pointDeductionAmount
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
async function getMaxPointsDiscount() {
|
||||
if (!props.orderVIP.id) {
|
||||
return;
|
||||
}
|
||||
let res = await APImemberPointscalcUsablePoints({
|
||||
shopUserId: props.orderVIP.id,
|
||||
orderAmount: maxMoney.value,
|
||||
});
|
||||
if (res) {
|
||||
cartStore.setPointDeductionRule(
|
||||
res.equivalentPoints || 0,
|
||||
res.maxDeductionAmount || 0
|
||||
);
|
||||
Object.assign(pointsRes, res);
|
||||
maxPointDiscount.value = res.maxDeductionAmount || 0;
|
||||
console.log("积分可抵扣最大金额", maxPointDiscount.value);
|
||||
|
||||
if (usePoints.value && res.usable) {
|
||||
console.log("积分抵扣金额", res.maxDeductionAmount);
|
||||
cartStore.setUserPoints(res.maxUsablePoints || 0);
|
||||
let userPoints = cartStore.shopUserInfo.pointsUser ? cartStore.shopUserInfo.pointsUser.pointBalance : 0;
|
||||
|
||||
//1积分等于多少钱
|
||||
const onePointsMoney = cartStore.pointDeductionRule.pointsPerYuan ? ((1 || 0) / cartStore.pointDeductionRule
|
||||
.pointsPerYuan) : 0
|
||||
|
||||
|
||||
const calcMaxDiscount = Math.floor(maxMoney.value * (cartStore.pointDeductionRule.maxDeductionRatio / 100))
|
||||
const userMaxDiscount = BigNumber(userPoints).times(onePointsMoney).decimalPlaces(2, BigNumber.ROUND_DOWN)
|
||||
.toNumber()
|
||||
|
||||
maxPointDiscount.value = Math.min(calcMaxDiscount, userMaxDiscount)
|
||||
console.log('积分最大可抵扣金额', maxPointDiscount.value)
|
||||
cartStore.pointDeductionRule.maxDeductionAmount = maxPointDiscount.value || 0
|
||||
if (usePoints.value && cartStore.pointDeductionRule.enableRewards) {
|
||||
let num = (maxPointDiscount.value || 0) * cartStore.pointDeductionRule.pointsPerYuan
|
||||
if (num > userPoints) {
|
||||
num = userPoints
|
||||
}
|
||||
if (!res.usable) {
|
||||
console.log('积分使用数量', num)
|
||||
cartStore.setUserPoints(num);
|
||||
}
|
||||
if (!cartStore.pointDeductionRule.enableRewards) {
|
||||
cartStore.setUserPoints(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
watch(
|
||||
() => maxMoney.value,
|
||||
(newval) => {
|
||||
|
||||
getMaxPointsDiscount();
|
||||
}
|
||||
);
|
||||
@@ -723,26 +650,11 @@ watch(
|
||||
}
|
||||
);
|
||||
|
||||
// * 获取积分相关信息
|
||||
const getCalcUsablePoints = async (data) => {
|
||||
Object.assign(calcUsablePointsData, data);
|
||||
try {
|
||||
cartStore.setPointDeductionRule(
|
||||
data.equivalentPoints,
|
||||
data.maxDeductionAmount
|
||||
);
|
||||
calcUsablePointsData.minIntegral = data.minDeductionPoints;
|
||||
calcUsablePointsData.maxIntegral = data.maxUsablePoints;
|
||||
calcUsablePointsData.instructionText = `请输入 ${data.minDeductionPoints} - ${data.maxUsablePoints} 之间的积分`;
|
||||
} catch (error) {
|
||||
//TODO handle the exception
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 积分取消清空
|
||||
const IntegralInputclose = async () => {
|
||||
calcUsablePointsData.integral = null;
|
||||
props.listinfo.pointsDiscountAmount = 0;
|
||||
calcUsablePointsData.showModal = false;
|
||||
// cartStore.setUserPoints(0);
|
||||
};
|
||||
@@ -762,7 +674,6 @@ const copyHandle = (e) => {
|
||||
|
||||
// 将方法暴露给父组件
|
||||
defineExpose({
|
||||
getCalcUsablePoints,
|
||||
bwcclear,
|
||||
IntegralInputclose,
|
||||
});
|
||||
@@ -863,10 +774,7 @@ function calcDiscountActivity() {
|
||||
const usedFullReductionActivityFullAmount =
|
||||
cartStore.orderCostSummary.fullReduction
|
||||
.usedFullReductionActivityFullAmount;
|
||||
console.log(
|
||||
"usedFullReductionActivityFullAmount",
|
||||
usedFullReductionActivityFullAmount
|
||||
);
|
||||
|
||||
|
||||
if (res && res.thresholds && res.thresholds.length > 0) {
|
||||
const canUseThresholds = res.thresholds
|
||||
@@ -876,7 +784,6 @@ function calcDiscountActivity() {
|
||||
.sort((a, b) => {
|
||||
return b.discountAmount - a.discountAmount;
|
||||
});
|
||||
console.log("canUseThresholds", canUseThresholds);
|
||||
|
||||
if (canUseThresholds.length) {
|
||||
discountActivity.value = canUseThresholds[0];
|
||||
@@ -1478,11 +1385,11 @@ onMounted(async () => {
|
||||
margin: 0 30rpx;
|
||||
justify-content: flex-end;
|
||||
align-items: flex-end;
|
||||
padding: 0 0 30rpx 34rpx;
|
||||
padding: 32rpx 0 0 34rpx;
|
||||
font-weight: bold;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
border-bottom: 2rpx dashed #e5e5e5;
|
||||
border-top: 2rpx dashed #e5e5e5;
|
||||
|
||||
.price {
|
||||
font-weight: bold;
|
||||
@@ -1579,6 +1486,7 @@ onMounted(async () => {
|
||||
.red {
|
||||
color: #ff3232;
|
||||
}
|
||||
|
||||
.youhui-item {
|
||||
height: 60rpx;
|
||||
width: 100%;
|
||||
@@ -1586,9 +1494,11 @@ onMounted(async () => {
|
||||
justify-content: space-between;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.align-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.limitDiscount {
|
||||
background-color: #cc5617;
|
||||
padding: 2rpx 10rpx;
|
||||
@@ -1604,4 +1514,36 @@ onMounted(async () => {
|
||||
z-index: 9;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.disocunt {
|
||||
background: #FFFFFF;
|
||||
border-radius: 18rpx 18rpx 18rpx 18rpx;
|
||||
overflow: hidden;
|
||||
margin-top: 32rpx;
|
||||
|
||||
.price {
|
||||
color: #FF1C1C;
|
||||
font-size: 28rpx;
|
||||
line-height: 42rpx;
|
||||
}
|
||||
|
||||
.row {
|
||||
padding: 16rpx 24rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.t {
|
||||
font-weight: bold;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.info {
|
||||
font-weight: 400;
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,9 +1,6 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="card_box">
|
||||
<view class="card_head_box">
|
||||
<view class="card_head_item" v-for="(item,index) in 8" :key="index"></view>
|
||||
</view>
|
||||
|
||||
<!-- 先付款 -->
|
||||
<view class="tabBox" v-if="listinfo.status == 'unpaid'">
|
||||
@@ -44,6 +41,21 @@
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
|
||||
<view class="tabBox" v-else-if="listinfo.tableName">
|
||||
|
||||
<view class="table" >
|
||||
<view class="table_left">
|
||||
<image class="icon"
|
||||
src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/confirmOrder/table.png"
|
||||
mode="aspectFill" />
|
||||
<text class="title">桌台</text>
|
||||
</view>
|
||||
<view class="value" v-if="listinfo.tableName"> {{ listinfo.tableName || '' }} </view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
<view class="card">
|
||||
<!-- 订单头部 -->
|
||||
<view class="card_item" v-for="(value, key) in listinfo.detailMap" :key="key">
|
||||
@@ -162,31 +174,57 @@
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block v-else>
|
||||
<!-- <block v-else>
|
||||
<view class="cell-item column" v-if="listinfo.discountInfo">
|
||||
<view class="label">优惠折扣</view>
|
||||
<view class="val column">
|
||||
<view class="productCoupon" v-for="(item,index) in listinfo.discountInfo" :key="index">
|
||||
<view class="name">{{item.name}}</view>
|
||||
<!-- <view class="num">{{item.amount}}</view> -->
|
||||
<view class="amount" style="margin-left: 10rpx;">{{item.amount}}元</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</block> -->
|
||||
|
||||
<view class="total-wrap" v-if="listinfo.status == 'unpaid'">
|
||||
<view>总计¥</view>
|
||||
<view class="price"> {{listinfo.totalCost}} </view>
|
||||
<text>总计</text>
|
||||
<text class="u-font-32">¥</text>
|
||||
<text class="price"> {{listinfo.totalCost}} </text>
|
||||
</view>
|
||||
<view class="total-wrap" v-else>
|
||||
<view>实付¥</view>
|
||||
<view class="price"> {{listinfo.payAmount}} </view>
|
||||
<view>实付</view>
|
||||
<text class="u-font-32">¥</text>
|
||||
<text class="price"> {{listinfo.payAmount}} </text>
|
||||
</view>
|
||||
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="disocunt " v-if="showDiscount">
|
||||
<view class="row" v-if="listinfo.productCouponDiscountAmount">
|
||||
<text class="t">商品券</text>
|
||||
<text class="info price">-{{listinfo.productCouponDiscountAmount}}</text>
|
||||
</view>
|
||||
<view class="row" v-if="listinfo.otherCouponDiscountAmount">
|
||||
<text class="t">优惠券</text>
|
||||
<text class="price">-{{listinfo.otherCouponDiscountAmount}}</text>
|
||||
</view>
|
||||
<view class="row" v-if="listinfo.pointsDiscountAmount">
|
||||
<text class="t">积分抵扣</text>
|
||||
<text class="price">-{{listinfo.pointsDiscountAmount}}</text>
|
||||
</view>
|
||||
<view class="row" v-if="listinfo.discountActAmount">
|
||||
<text class="t">满减活动</text>
|
||||
<text class="price">-{{listinfo.discountActAmount}}</text>
|
||||
</view>
|
||||
<view class="row" v-if="listinfo.newCustomerDiscountAmount">
|
||||
<text class="t">新客立减</text>
|
||||
<text class="price">-{{listinfo.newCustomerDiscountAmount}}</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
<view class="orderInfo">
|
||||
<view class="row" @click="copyHandle(listinfo.orderNo)">
|
||||
<text class="t">订单编号:</text>
|
||||
@@ -295,6 +333,7 @@
|
||||
])
|
||||
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
freeCheck: {
|
||||
type: Boolean
|
||||
@@ -330,6 +369,47 @@
|
||||
|
||||
})
|
||||
|
||||
/**
|
||||
* 判断一个对象里的某些属性是否存在且值不等于0,满足其中一个就返回true,否则false
|
||||
* @param {Object} obj - 要检测的目标对象(若为非对象类型直接返回false)
|
||||
* @param {Array<string>} keys - 要检测的属性名数组(若为非数组/空数组直接返回false)
|
||||
* @returns {boolean} 满足条件返回true,否则返回false
|
||||
*/
|
||||
function isObjHasPropertyAndNotNull(obj, keys) {
|
||||
console.log(obj)
|
||||
// 1. 边界校验:obj必须是有效对象,keys必须是非空数组
|
||||
if (
|
||||
!obj || // 排除null/undefined
|
||||
typeof obj !== 'object' || // 排除字符串/数字/布尔等非对象类型
|
||||
!Array.isArray(keys) || // 确保keys是数组
|
||||
keys.length === 0 // 空数组直接返回false
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. 遍历所有要检测的属性
|
||||
for (const key of keys) {
|
||||
console.log(obj[key])
|
||||
// 检查属性是否是对象自身的(排除原型链上的属性) + 属性值不等于0
|
||||
if (obj.hasOwnProperty(key) && obj[key] !== 0) {
|
||||
return true; // 只要有一个满足,立即返回true
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 所有属性都不满足条件
|
||||
return false;
|
||||
}
|
||||
|
||||
const showDiscount = computed(() => {
|
||||
const keys = ['productCouponDiscountAmount', 'otherCouponDiscountAmount',
|
||||
'pointsDiscountAmount', 'discountActAmount', 'newCustomerDiscountAmount'
|
||||
]
|
||||
if (isObjHasPropertyAndNotNull(props.listinfo, keys)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
const is_type = ref(0)
|
||||
// 监听送餐/打包切换
|
||||
const tabClick = (item, index) => {
|
||||
@@ -477,11 +557,9 @@
|
||||
<style lang="scss" scoped>
|
||||
.card_box {
|
||||
background-color: #fff;
|
||||
// box-shadow: 0rpx 8rpx 12rpx 2rpx rgba(87,86,86,0.35);
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// box-shadow: 0rpx 4rpx 12rpx 2rpx rgba(87,86,86,0.35);
|
||||
border-radius: 18rpx;
|
||||
padding-bottom: 32rpx;
|
||||
|
||||
@@ -1050,7 +1128,31 @@
|
||||
|
||||
}
|
||||
}
|
||||
.disocunt{
|
||||
background: #FFFFFF;
|
||||
border-radius: 18rpx 18rpx 18rpx 18rpx;overflow: hidden;
|
||||
margin-top: 32rpx;
|
||||
.row{
|
||||
padding: 16rpx 24rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
.t {
|
||||
font-weight: bold;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.info {
|
||||
font-weight: 400;
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
.price {
|
||||
color: #FF1C1C;
|
||||
}
|
||||
}
|
||||
.orderInfo {
|
||||
background: #FFFFFF;
|
||||
border-radius: 18rpx 18rpx 18rpx 18rpx;
|
||||
@@ -1129,4 +1231,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
@@ -5,9 +5,7 @@
|
||||
<view class="left">
|
||||
<view class="icon">优惠</view>
|
||||
<view class="text">
|
||||
充值消费{{ freeDineConfig.rechargeTimes }}倍(订单满¥{{
|
||||
freeDineConfig.rechargeThreshold
|
||||
}}元可用),本单立享免单!</view
|
||||
充值消费{{ freeDineConfig.rechargeTimes }}倍,本单立享免单!</view
|
||||
>
|
||||
</view>
|
||||
<view @click.stop="()=>{}">
|
||||
@@ -92,12 +90,11 @@ const changeFree = (e) => {
|
||||
font-weight: 500;
|
||||
font-size: 20rpx;
|
||||
color: #ffffff;
|
||||
margin-right: 12rpx;
|
||||
margin-right: 18rpx;
|
||||
}
|
||||
|
||||
.text {
|
||||
width: 80%;
|
||||
font-weight: 500;
|
||||
font-weight: 700;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
@@ -3,41 +3,22 @@
|
||||
<up-navbar :title="navTitle" @leftClick="onback" placeholder></up-navbar>
|
||||
<view class="headStatus">
|
||||
<view class="status">
|
||||
<up-icon
|
||||
v-if="
|
||||
<up-icon v-if="
|
||||
listinfo.status == 'done' ||
|
||||
listinfo.status == 'unpaid' ||
|
||||
!listinfo.id
|
||||
"
|
||||
name="checkmark-circle-fill"
|
||||
color="#03C061"
|
||||
size="23"
|
||||
></up-icon>
|
||||
<view
|
||||
class="statusName"
|
||||
v-if="listinfo.status == 'unpaid' || !listinfo.id"
|
||||
>待支付</view
|
||||
>
|
||||
" name="checkmark-circle-fill" color="#03C061" size="23"></up-icon>
|
||||
<view class="statusName" v-if="listinfo.status == 'unpaid' || !listinfo.id">待支付</view>
|
||||
<view class="statusName" v-if="listinfo.status == 'done'">已完成</view>
|
||||
<view class="statusName" v-if="listinfo.status == 'refund'">退单</view>
|
||||
<view class="statusName" v-if="listinfo.status == 'part-refund'"
|
||||
>部分退单</view
|
||||
>
|
||||
<view class="statusName" v-if="listinfo.status == 'cancelled'"
|
||||
>取消订单</view
|
||||
>
|
||||
<view class="statusName" v-if="listinfo.status == 'part-refund'">部分退单</view>
|
||||
<view class="statusName" v-if="listinfo.status == 'cancelled'">取消订单</view>
|
||||
</view>
|
||||
<view class="time" v-if="listinfo.createTime"
|
||||
>下单时间:{{ listinfo.createTime }}</view
|
||||
>
|
||||
<view
|
||||
class="time"
|
||||
v-if="
|
||||
<view class="time" v-if="listinfo.createTime">下单时间:{{ listinfo.createTime }}</view>
|
||||
<view class="time" v-if="
|
||||
listinfo.paidTime &&
|
||||
(listinfo.status != 'cancelled' || listinfo.status != 'unpaid')
|
||||
"
|
||||
>付款时间:{{ listinfo.paidTime }}</view
|
||||
>
|
||||
">付款时间:{{ listinfo.paidTime }}</view>
|
||||
</view>
|
||||
|
||||
<view class="order-msg-list" v-if="listinfo.status=='done'">
|
||||
@@ -59,88 +40,50 @@
|
||||
<u-image width="152" height="152" radius="16" :src="shopQrcode"></u-image>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-ALIPAY -->
|
||||
<image
|
||||
style="height: 150rpx; width: 150rpx"
|
||||
:src="shopQrcode"
|
||||
@longpress="saveImage(shopQrcode)"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<image style="height: 150rpx; width: 150rpx" :src="shopQrcode" @longpress="saveImage(shopQrcode)"
|
||||
mode="aspectFill"></image>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
|
||||
<!-- {{cartStore.orderCostSummary}} -->
|
||||
|
||||
<!-- 详情 -->
|
||||
<orderInfo
|
||||
:useVipPrice="cartStore.useVipPrice"
|
||||
:packfee="packfee"
|
||||
:shifu="shifu"
|
||||
:nowCarts="cartStore.carts"
|
||||
ref="orderInfoAfterRef"
|
||||
:freeCheck="freeCheck"
|
||||
:listinfo="listinfo"
|
||||
:orderVIP="orderVIP"
|
||||
:ordershopUserInfo="ordershopUserInfo"
|
||||
@istype="istype"
|
||||
@clickPointsamount="clickPointsamount"
|
||||
:isBwc="isBwc"
|
||||
></orderInfo>
|
||||
<orderInfo :useVipPrice="cartStore.useVipPrice" :packfee="packfee" :shifu="shifu" :nowCarts="cartStore.carts"
|
||||
ref="orderInfoAfterRef" :freeCheck="freeCheck" :listinfo="listinfo" :orderVIP="orderVIP"
|
||||
:ordershopUserInfo="ordershopUserInfo" @istype="istype" :isBwc="isBwc"></orderInfo>
|
||||
<!-- 订单备注 -->
|
||||
<view class="orderInfo">
|
||||
<view class="orderInfo" v-if="listinfo.status!='done'">
|
||||
<view class="">
|
||||
<view class="t">订单备注:</view>
|
||||
<view class="u-m-t-18">
|
||||
<up-textarea
|
||||
border="none"
|
||||
placeholder="请填写口味、偏好等要求"
|
||||
type="textarea"
|
||||
v-model="orderRemarker"
|
||||
:clearable="true"
|
||||
/>
|
||||
<view class="u-m-t-18 textarea">
|
||||
<up-textarea border="none" placeholder="请填写口味、偏好等要求" type="textarea" v-model="orderRemarker"
|
||||
:clearable="true" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 霸王餐 -->
|
||||
<rechargeFree
|
||||
:freeDineConfig="orderVIP.freeDineConfig"
|
||||
:payAmount="listinfo.totalPrices"
|
||||
v-if="showFreeDine && (listinfo.status == 'unpaid' || !listinfo.id)"
|
||||
@changeFree="changeFree"
|
||||
></rechargeFree>
|
||||
<rechargeFree :freeDineConfig="orderVIP.freeDineConfig" :payAmount="listinfo.totalPrices"
|
||||
v-if="showFreeDine && (listinfo.status == 'unpaid' || !listinfo.id)" @changeFree="changeFree">
|
||||
</rechargeFree>
|
||||
|
||||
<!-- 支付方式 -->
|
||||
<paymentMethodes
|
||||
ref="paymentMethodref"
|
||||
:orderVIP="orderVIP"
|
||||
@groupChange="groupChange"
|
||||
:disablePayType="disablePayType"
|
||||
:changeFreeenable="isBwc"
|
||||
v-model="paymentmethod"
|
||||
v-if="listinfo.status == 'unpaid' || !listinfo.id"
|
||||
>
|
||||
<paymentMethodes ref="paymentMethodref" :orderVIP="orderVIP" @groupChange="groupChange"
|
||||
:disablePayType="disablePayType" :changeFreeenable="isBwc" v-model="paymentmethod"
|
||||
v-if="listinfo.status == 'unpaid' || !listinfo.id">
|
||||
<template #bottom>
|
||||
<!-- 充值享优惠 -->
|
||||
<view
|
||||
v-if="
|
||||
<view v-if="
|
||||
!showFreeDine &&
|
||||
(listinfo.status == 'unpaid' || !listinfo.id) &&
|
||||
cartStore.orderCostSummary.finalPayAmount > 0
|
||||
"
|
||||
>
|
||||
<ChargeVue
|
||||
@updateChargeSel="(e) => updateChargeSel(e)"
|
||||
@updateRechargeId="updateRechargeId"
|
||||
@updateIsShow="updateIsShow"
|
||||
v-if="listinfo.status == 'unpaid' || !listinfo.id"
|
||||
></ChargeVue>
|
||||
">
|
||||
<ChargeVue @updateChargeSel="(e) => updateChargeSel(e)" @updateRechargeId="updateRechargeId"
|
||||
@updateIsShow="updateIsShow" v-if="listinfo.status == 'unpaid' || !listinfo.id"></ChargeVue>
|
||||
</view>
|
||||
</template>
|
||||
</paymentMethodes>
|
||||
<view class="fixedview">
|
||||
<view
|
||||
class="flex-between"
|
||||
v-if="listinfo.status == 'unpaid' || !listinfo.id"
|
||||
>
|
||||
<view class="flex-between" v-if="listinfo.status == 'unpaid' || !listinfo.id">
|
||||
<view class="fixedview_one flex-start">
|
||||
<view class="fixedview_oneone">实付金额</view>
|
||||
<view class="fixedview_onetow" v-if="rechargeItem.id">
|
||||
@@ -155,60 +98,33 @@
|
||||
<view class="flex-colum-end u-flex u-flex-y-center">
|
||||
<view class="u-m-r-30 u-flex u-flex-y-center">
|
||||
<template v-if="ordershopUserInfo.registerType == 'before'">
|
||||
<up-button
|
||||
shape="circle"
|
||||
v-if="!listinfo.id"
|
||||
@click="toJiacai"
|
||||
plain
|
||||
:custom-style="customStyle"
|
||||
>
|
||||
<up-button shape="circle" v-if="!listinfo.id" @click="toJiacai" plain
|
||||
:custom-style="customStyle">
|
||||
<view class="u-flex u-flex-y-center">
|
||||
<image
|
||||
style="width: 40rpx; height: 40rpx"
|
||||
src="@/static/icon/add-goods.png"
|
||||
mode=""
|
||||
></image>
|
||||
<image style="width: 40rpx; height: 40rpx" src="@/static/icon/add-goods.png"
|
||||
mode=""></image>
|
||||
<text class="u-font-32 color-main u-m-l-16">加菜</text>
|
||||
</view>
|
||||
</up-button>
|
||||
<up-button
|
||||
shape="circle"
|
||||
v-if="listinfo.id && listinfo.status == 'unpaid'"
|
||||
plain
|
||||
@tap="cancelOrder()"
|
||||
:custom-style="customStyle"
|
||||
>
|
||||
<up-button shape="circle" v-if="listinfo.id && listinfo.status == 'unpaid'" plain
|
||||
@tap="cancelOrder()" :custom-style="customStyle">
|
||||
<view class="u-flex u-flex-y-center">
|
||||
<text class="u-font-32 color-main u-m-l-16">取消订单</text>
|
||||
</view>
|
||||
</up-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<up-button
|
||||
v-if="!cartStore.isEmpty"
|
||||
shape="circle"
|
||||
@click="onlyCreateOrder"
|
||||
plain
|
||||
:custom-style="customStyle"
|
||||
>
|
||||
<up-button v-if="!cartStore.isEmpty" shape="circle" @click="onlyCreateOrder" plain
|
||||
:custom-style="customStyle">
|
||||
<view class="u-flex u-flex-y-center">
|
||||
<!-- <image style="width: 40rpx;height: 40rpx;" src="@/static/icon/add-goods.png" mode=""></image> -->
|
||||
<text class="u-font-32 color-main">仅下单</text>
|
||||
</view>
|
||||
</up-button>
|
||||
<up-button
|
||||
v-else
|
||||
shape="circle"
|
||||
@click="toJiacai"
|
||||
plain
|
||||
:custom-style="customStyle"
|
||||
>
|
||||
<up-button v-else shape="circle" @click="toJiacai" plain :custom-style="customStyle">
|
||||
<view class="u-flex u-flex-y-center">
|
||||
<image
|
||||
style="width: 40rpx; height: 40rpx"
|
||||
src="@/static/icon/add-goods.png"
|
||||
mode=""
|
||||
></image>
|
||||
<image style="width: 40rpx; height: 40rpx" src="@/static/icon/add-goods.png"
|
||||
mode=""></image>
|
||||
<text class="u-font-32 color-main u-m-l-16">加菜</text>
|
||||
</view>
|
||||
</up-button>
|
||||
@@ -224,23 +140,28 @@
|
||||
</view>
|
||||
</view>
|
||||
<view style="width: 100%; height: 200rpx; color: #fff; color: #fff"></view>
|
||||
<payPassword
|
||||
ref="payPasswordref"
|
||||
:isShow="ispws"
|
||||
@inputComplete="(e) => accountPayevent(e)"
|
||||
@close="pwdClose"
|
||||
/>
|
||||
<payPassword ref="payPasswordref" :isShow="ispws" @inputComplete="(e) => accountPayevent(e)"
|
||||
@close="pwdClose" />
|
||||
<!-- 私域引流配置 -->
|
||||
<OrderFinshModal v-model="showDrainage"></OrderFinshModal>
|
||||
</view>
|
||||
</template>
|
||||
<script setup>
|
||||
import { back } from "@/utils/uniapp.js";
|
||||
import { onLoad, onUnload } from "@dcloudio/uni-app";
|
||||
import {
|
||||
back
|
||||
} from "@/utils/uniapp.js";
|
||||
import {
|
||||
onLoad,
|
||||
onUnload
|
||||
} from "@dcloudio/uni-app";
|
||||
import ChargeVue from "./components/charge.vue";
|
||||
import { pay } from "@/utils/pay.js";
|
||||
import {
|
||||
pay
|
||||
} from "@/utils/pay.js";
|
||||
import OrderFinshModal from "@/components/order-finish-modal.vue";
|
||||
import _ from "lodash";
|
||||
import * as pointsApi from '@/common/api/market/points.js'
|
||||
import yskUtils from '@/lib/index'
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
@@ -255,7 +176,9 @@ import {
|
||||
} from "vue";
|
||||
provide("shopUserInfo", ref(uni.cache.get("shopUserInfo")));
|
||||
provide("shopInfo", ref(uni.cache.get("shopInfo")));
|
||||
import { getTableInfo } from "@/common/api/shop/index.js";
|
||||
import {
|
||||
getTableInfo
|
||||
} from "@/common/api/shop/index.js";
|
||||
import {
|
||||
APIgetOrderById,
|
||||
APIputuserorder,
|
||||
@@ -263,13 +186,20 @@ import {
|
||||
rechargePayOrder,
|
||||
APIcancelOrder,
|
||||
} from "@/common/api/order/index.js";
|
||||
import { APIusershopInfodetail, APIshopUserInfo } from "@/common/api/member.js";
|
||||
import {
|
||||
APIusershopInfodetail,
|
||||
APIshopUserInfo
|
||||
} from "@/common/api/member.js";
|
||||
import {
|
||||
APImemberPointsmyPoints,
|
||||
APImemberPointscalcUsablePoints,
|
||||
} from "@/common/api/shop/index.js";
|
||||
import { useCartsStore } from "@/stores/carts.js";
|
||||
import { useWebSocket } from "@/stores/carts-websocket.js";
|
||||
import {
|
||||
useCartsStore
|
||||
} from "@/stores/carts.js";
|
||||
import {
|
||||
useWebSocket
|
||||
} from "@/stores/carts-websocket.js";
|
||||
import * as chatApi from "@/http/php/chat";
|
||||
|
||||
import MsgListItem from '@/components/msg-list-item/msg-list-item.vue'
|
||||
@@ -287,6 +217,7 @@ onBackPress(() => {
|
||||
console.log("返回拦截");
|
||||
closeSocket();
|
||||
});
|
||||
|
||||
function onback() {
|
||||
closeSocket();
|
||||
console.log("返回");
|
||||
@@ -305,6 +236,7 @@ const cartStore = useCartsStore();
|
||||
//充值相关start
|
||||
//充值和余额支付是否可用
|
||||
const isCanUseCharge = ref(true);
|
||||
|
||||
function updateIsShow(e) {
|
||||
isCanUseCharge.value = e;
|
||||
}
|
||||
@@ -330,16 +262,13 @@ async function onMessage(Message) {
|
||||
youhuiReset();
|
||||
}
|
||||
if (Message.operate_type == "cleanup") {
|
||||
console.log("onMessage:cleanup", Message);
|
||||
console.log("onMessage:options", options);
|
||||
console.log("onMessage:listinfo", listinfo);
|
||||
youhuiReset();
|
||||
if (listinfo.id || options.tableCode) {
|
||||
let res = listinfo.id
|
||||
? await APIgetOrderById({
|
||||
let res = listinfo.id ?
|
||||
await APIgetOrderById({
|
||||
orderId: listinfo.id,
|
||||
})
|
||||
: await APIhistoryOrder({
|
||||
}) :
|
||||
await APIhistoryOrder({
|
||||
tableCode: options.tableCode || "",
|
||||
});
|
||||
|
||||
@@ -377,8 +306,15 @@ async function onMessage(Message) {
|
||||
) {
|
||||
youhuiReset();
|
||||
}
|
||||
if (Message.operate_type == 'bulk_edit') {
|
||||
}
|
||||
return Message;
|
||||
}
|
||||
|
||||
function toDiancai() {
|
||||
uni.navigateBack()
|
||||
}
|
||||
|
||||
let cartsSocket = null;
|
||||
cartStore.goodsInit();
|
||||
const socketInitPar = {
|
||||
@@ -398,9 +334,7 @@ const noPayStatus = {
|
||||
};
|
||||
|
||||
function youhuiReset() {
|
||||
listinfo.pointsDiscountAmount = 0;
|
||||
listinfo.pointsNum = 0;
|
||||
listinfo.pointsDiscountAmount = 0;
|
||||
listinfo.Productroll = 0;
|
||||
try {
|
||||
orderInfoAfterRef.value?.IntegralInputclose();
|
||||
@@ -408,11 +342,15 @@ function youhuiReset() {
|
||||
}
|
||||
|
||||
// 结账管理
|
||||
import { Memberpay } from "@/stores/pay.js";
|
||||
import {
|
||||
Memberpay
|
||||
} from "@/stores/pay.js";
|
||||
|
||||
const storeMemberpay = Memberpay();
|
||||
|
||||
import { productStore } from "@/stores/user.js";
|
||||
import {
|
||||
productStore
|
||||
} from "@/stores/user.js";
|
||||
const storeuser = productStore();
|
||||
|
||||
import payPassword from "@/components/payPassword.vue";
|
||||
@@ -420,9 +358,16 @@ import orderInfo from "./components/orderInfo.vue";
|
||||
// import orderInfoBefore from '../components/orderInfoBefore.vue'
|
||||
import rechargeFree from "./components/rechargeFree.vue";
|
||||
import paymentMethodes from "@/components/paymentMethod.vue"; //支付方式
|
||||
import { onShow, onBackPress } from "@dcloudio/uni-app";
|
||||
import { onHide } from "@dcloudio/uni-app";
|
||||
import { getMsgByOrderIdReq } from "../../common/api/account/message";
|
||||
import {
|
||||
onShow,
|
||||
onBackPress
|
||||
} from "@dcloudio/uni-app";
|
||||
import {
|
||||
onHide
|
||||
} from "@dcloudio/uni-app";
|
||||
import {
|
||||
getMsgByOrderIdReq
|
||||
} from "../../common/api/account/message";
|
||||
// 输入支付密码
|
||||
const ispws = ref(false);
|
||||
let userInfo = uni.cache.get("userInfo");
|
||||
@@ -469,7 +414,6 @@ let backtimer = null;
|
||||
let historyTotalPrices = 0;
|
||||
// * 获取订单详情接口
|
||||
const orderorderInfo = async (isNpwGetOrderDetail = false) => {
|
||||
console.log("listinfo.id", listinfo.id);
|
||||
|
||||
if (!listinfo.id && !options.tableCode) {
|
||||
return;
|
||||
@@ -480,11 +424,11 @@ const orderorderInfo = async (isNpwGetOrderDetail = false) => {
|
||||
}
|
||||
}
|
||||
|
||||
let res = listinfo.id
|
||||
? await APIgetOrderById({
|
||||
let res = listinfo.id ?
|
||||
await APIgetOrderById({
|
||||
orderId: listinfo.id,
|
||||
})
|
||||
: await APIhistoryOrder({
|
||||
}) :
|
||||
await APIhistoryOrder({
|
||||
tableCode: options.tableCode || "",
|
||||
});
|
||||
orderRemarker.value = res.remark;
|
||||
@@ -565,8 +509,6 @@ function getOrderInfoAfterCalcInit(res) {
|
||||
}
|
||||
listinfo.discountInfo = tempArray;
|
||||
}
|
||||
// 回填先质控
|
||||
listinfo.pointsDiscountAmount = 0;
|
||||
// console.log(listinfo)
|
||||
} else {
|
||||
listinfo.totalPrices = cartStore.totalPrice * 1;
|
||||
@@ -695,16 +637,13 @@ const createOrder = async () => {
|
||||
orderId: listinfo.id || "",
|
||||
tableCode: options.tableCode || "",
|
||||
userId: uni.cache.get("userInfo").id || "", //
|
||||
limitRate:
|
||||
cartStore.limitTimeDiscount && cartStore.limitTimeDiscount.id
|
||||
? {
|
||||
limitRate: cartStore.limitTimeDiscount && cartStore.limitTimeDiscount.id ? {
|
||||
id: cartStore.limitTimeDiscount.id,
|
||||
discountRate: cartStore.limitTimeDiscount.discountRate,
|
||||
discountPriority: cartStore.limitTimeDiscount.discountPriority,
|
||||
foodType: cartStore.limitTimeDiscount.foodType,
|
||||
foods: cartStore.limitTimeDiscount.foods,
|
||||
}
|
||||
: null,
|
||||
} : null,
|
||||
});
|
||||
// 清空购物车
|
||||
if (res) {
|
||||
@@ -768,37 +707,30 @@ function returnPayParams() {
|
||||
originAmount: cartStore.orderCostSummary.goodsRealAmount, //订单原金额(不包含打包费+餐位费)
|
||||
discountRatio: 1, //折扣比例(计算时 向上取整保留 两位小数) 写死1
|
||||
discountAmount: 0, //手动优惠金额 写死0
|
||||
productCouponDiscountAmount:
|
||||
cartStore.orderCostSummary.productCouponDeduction, //商品优惠券抵扣金额
|
||||
productCouponDiscountAmount: cartStore.orderCostSummary.productCouponDeduction, //商品优惠券抵扣金额
|
||||
otherCouponDiscountAmount: cartStore.orderCostSummary.fullCouponDeduction, //其他优惠券抵扣金额
|
||||
couponList: cartStore.backendCoupons.map((v) => v.id), //用户使用的卡券
|
||||
orderAmount: isBwc.value
|
||||
? cartStore.orderCostSummary.orderOriginFinalPayAmount
|
||||
: cartStore.orderCostSummary.finalPayAmount, // 最终订单金额
|
||||
orderAmount: isBwc.value ?
|
||||
cartStore.orderCostSummary.orderOriginFinalPayAmount : cartStore.orderCostSummary
|
||||
.finalPayAmount, // 最终订单金额
|
||||
roundAmount: 0, //抹零金额 减免多少钱
|
||||
pointsDiscountAmount: cartStore.orderCostSummary.pointDeductionAmount, //积分抵扣金额(tb_points_basic_setting表)
|
||||
pointsNum: cartStore.orderCostSummary.pointUsed, //(扣除各类折扣 enable_deduction后使用)
|
||||
newCustomerDiscountAmount: cartStore.orderCostSummary.newUserDiscount, //新客立减
|
||||
newCustomerDiscountId:
|
||||
cartStore.orderCostSummary.newUserDiscount > 0
|
||||
? cartStore.consumeDiscount.id
|
||||
: "",
|
||||
newCustomerDiscountId: cartStore.orderCostSummary.newUserDiscount > 0 ?
|
||||
cartStore.consumeDiscount.id : "",
|
||||
remark: orderRemarker.value, //用户备注
|
||||
discountActAmount: cartStore.orderCostSummary.fullReduction.actualAmount, //满减抵扣金额
|
||||
discountActId: cartStore.orderCostSummary.fullReduction.usedActivity
|
||||
? cartStore.orderCostSummary.fullReduction.usedActivity.id
|
||||
: null,
|
||||
discountActId: cartStore.orderCostSummary.fullReduction.usedActivity ?
|
||||
cartStore.orderCostSummary.fullReduction.usedActivity.id : null,
|
||||
userId: uni.cache.get("userInfo").id || "", //
|
||||
limitRate:
|
||||
cartStore.limitTimeDiscount && cartStore.limitTimeDiscount.id
|
||||
? {
|
||||
limitRate: cartStore.limitTimeDiscount && cartStore.limitTimeDiscount.id ? {
|
||||
id: cartStore.limitTimeDiscount.id,
|
||||
discountRate: cartStore.limitTimeDiscount.discountRate,
|
||||
discountPriority: cartStore.limitTimeDiscount.discountPriority,
|
||||
foodType: cartStore.limitTimeDiscount.foodType,
|
||||
foods: cartStore.limitTimeDiscount.foods,
|
||||
}
|
||||
: null,
|
||||
} : null,
|
||||
vipDiscountAmount: cartStore.orderCostSummary.vipDiscountAmount, //会员折扣减免金额
|
||||
};
|
||||
return {
|
||||
@@ -813,9 +745,8 @@ function returnPayParams() {
|
||||
shopId: orderVIP.value.shopId,
|
||||
pwd: "",
|
||||
userId: uni.cache.get("userInfo").id || "", //
|
||||
discountActld: cartStore.orderCostSummary.fullReduction.usedActivity
|
||||
? cartStore.orderCostSummary.fullReduction.usedActivity.id
|
||||
: "", //满减活动id
|
||||
discountActld: cartStore.orderCostSummary.fullReduction.usedActivity ?
|
||||
cartStore.orderCostSummary.fullReduction.usedActivity.id : "", //满减活动id
|
||||
};
|
||||
}
|
||||
|
||||
@@ -868,6 +799,9 @@ const istoricalorders = async () => {
|
||||
combinedArray = [...combinedArray, ...subArray];
|
||||
}
|
||||
}
|
||||
|
||||
console.log('combinedArray', combinedArray)
|
||||
console.log('listinfo.combinedArray', listinfo.combinedArray)
|
||||
// 判断支付之前是是否还有新加订单
|
||||
if (listinfo.combinedArray.length === combinedArray.length) {
|
||||
goToPay(payParams);
|
||||
@@ -1008,15 +942,9 @@ const goToPay = async (payParams) => {
|
||||
}
|
||||
}
|
||||
pay_unlock();
|
||||
console.log("orderorderInfo");
|
||||
orderorderInfo();
|
||||
};
|
||||
|
||||
//
|
||||
const clickPointsamount = (Pointsamount) => {
|
||||
listinfo.pointsDiscountAmount = Pointsamount.pointsDiscountAmount;
|
||||
listinfo.pointsNum = Pointsamount.pointsNum;
|
||||
};
|
||||
|
||||
|
||||
const payPasswordref = ref(null);
|
||||
// 余额支付
|
||||
@@ -1045,7 +973,6 @@ const accountPayevent = async (pwd) => {
|
||||
//TODO handle the exception
|
||||
pay_unlock();
|
||||
}
|
||||
orderorderInfo();
|
||||
};
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
@@ -1128,6 +1055,7 @@ const navTitle = computed(() => {
|
||||
//支付成功后的处理
|
||||
async function paySucessCallback() {
|
||||
console.log("paySucessCallback");
|
||||
orderorderInfo(true);
|
||||
cartsSocket.closeSocket();
|
||||
showDrainage.value = true;
|
||||
// const groupinfo=await chatApi.groupShopinfo({shop_id:cartStore.shopInfo.id})
|
||||
@@ -1156,6 +1084,7 @@ function setOrder(res) {
|
||||
}
|
||||
orderRemarker.value = res.remark;
|
||||
Object.assign(listinfo, res);
|
||||
getOrderInfoAfterCalcInit(res);
|
||||
}
|
||||
async function init(opt) {
|
||||
await storeuser.actionsproductqueryProduct();
|
||||
@@ -1183,12 +1112,18 @@ async function init(opt) {
|
||||
const shopInfoRes = await APIusershopInfodetail({
|
||||
shopId: options.shopId,
|
||||
});
|
||||
//获取积分配置
|
||||
pointsApi.pointsConfig().then(res => {
|
||||
cartStore.setPointDeductionRule(res);
|
||||
})
|
||||
if (!isPayBefor() && options.tableCode) {
|
||||
const res = await APIhistoryOrder({
|
||||
tableCode: options.tableCode || "",
|
||||
});
|
||||
if (res && typeof res == "object") {
|
||||
setOrder(res);
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
if (shopInfoRes) {
|
||||
@@ -1254,8 +1189,7 @@ watch(
|
||||
) {
|
||||
showFreeDine.value = true;
|
||||
}
|
||||
},
|
||||
{
|
||||
}, {
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
@@ -1305,15 +1239,74 @@ const disablePayType = computed(() => {
|
||||
|
||||
return Array.from(arr);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f7f7f7;
|
||||
watch(() => cartStore.limitTimeDiscount, (newval, oldval) => {
|
||||
|
||||
})
|
||||
|
||||
/**
|
||||
* 更新购物车和历史订单数据
|
||||
*/
|
||||
function updateCartAndHistory() {
|
||||
let newData = {
|
||||
history: [],
|
||||
cart: [],
|
||||
};
|
||||
|
||||
// 扁平化历史订单商品
|
||||
const oldOrderGoods = listinfo.combinedArray
|
||||
for (let cart of oldOrderGoods) {
|
||||
const canUseLimitTimeDiscount = yskUtils.limitUtils.canUseLimitTimeDiscount(
|
||||
cart,
|
||||
cartStore.limitTimeDiscount,
|
||||
cartStore.shopInfo,
|
||||
cartStore.shopUserInfo,
|
||||
"productId"
|
||||
) ?
|
||||
1 :
|
||||
0;
|
||||
if (canUseLimitTimeDiscount != cart.isTimeDiscount) {
|
||||
newData.history.push({
|
||||
id: cart.id,
|
||||
is_time_discount: canUseLimitTimeDiscount,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (let cart of carts.value) {
|
||||
const canUseLimitTimeDiscount = yskUtils.limitUtils.canUseLimitTimeDiscount(
|
||||
cart,
|
||||
cartStore.limitTimeDiscount,
|
||||
cartStore.shopInfo,
|
||||
cartStore.shopUserInfo,
|
||||
"productId"
|
||||
) ?
|
||||
1 :
|
||||
0;
|
||||
if (canUseLimitTimeDiscount != cart.isTimeDiscount) {
|
||||
newData.cart.push({
|
||||
id: cart.id,
|
||||
is_time_discount: canUseLimitTimeDiscount,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (newData.history.length <= 0 && newData.cart.length <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
cartsSocket.sendMessage({
|
||||
...socketInitPar,
|
||||
operate_type: "bulk_edit",
|
||||
data: newData,
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
padding: 32rpx 28rpx 32rpx 28rpx;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
.headStatus {
|
||||
@@ -1509,8 +1502,7 @@ page {
|
||||
padding: 32rpx 0 !important;
|
||||
display: flex;
|
||||
|
||||
.cover {
|
||||
}
|
||||
.cover {}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
@@ -1792,4 +1784,14 @@ page {
|
||||
.order-msg-list {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.textarea {
|
||||
background-color: #F5F5F5;
|
||||
border-radius: 10rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:deep(.u-textarea) {
|
||||
background-color: #F5F5F5 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -16,51 +16,32 @@
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="status-wrap">
|
||||
<view
|
||||
class="item"
|
||||
:class="{ active: querForm.statusActiveIndex == 0 }"
|
||||
@click="tabChange(0)"
|
||||
>
|
||||
<view class="item" :class="{ active: querForm.statusActiveIndex == 0 }" @click="tabChange(0)">
|
||||
<text class="t">商品兑换券 {{ returnSelNumber(0) }}</text>
|
||||
</view>
|
||||
<view
|
||||
class="item"
|
||||
:class="{ active: querForm.statusActiveIndex == 1 }"
|
||||
@click="tabChange(1)"
|
||||
>
|
||||
<view class="item" :class="{ active: querForm.statusActiveIndex == 1 }" @click="tabChange(1)">
|
||||
<text class="t">折扣优惠券{{ returnSelNumber(1) }}</text>
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="icon-wrap"
|
||||
:style="{
|
||||
<view class="icon-wrap" :style="{
|
||||
width: `${100 / statusList.length}%`,
|
||||
left: `${(100 / statusList.length) * querForm.statusActiveIndex}%`,
|
||||
}"
|
||||
>
|
||||
<image
|
||||
class="active-icon"
|
||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAMCAYAAAB4MH11AAACKUlEQVR4AaRTS2sTURT+MpkxUzNtRpuYpBsrqbgQH6BYRHGllloQN+5cuNeV6MKfoj9BwYUgIsXHRqE+SluliFLbBqmENJNMMpMm87qecw1NglJse+HMPeee833nce8oIgpFq7wsGt/fCb9eFrtdfmNd1L+9Jc4Vog6E4jcqqM0/R+3zNOwv09jtshdfSx7mDJwKqAMfIvAAEaFVWkLgWjvOEbVdtNa+Epf4wxmFUNTkfqiDGUkqogDu8icKiKS9nQ9jnR8fqM5AwuJJE/G9JhRF05E8dAqIKeDlrsyiWVxg9f+Fum+uzsFZmtnEGIVxKHsGIFn1bAF6ZlQ6I28D9uIrmYSrkodbfETgw6GubZo9Yzk0kR4Fc7IuE8QUFebJKSTSB/kM4UYd1scnKL18QInm4Vk/6W6qiNoOwpZDuoX2elFWXHrzELW5Z+RzJVbPHca+09doIKq0ZQLW+C44iWbm2ZQSNMqozj5F5f1jWCSVGd4fwerstYUXCOplGcsfxponJqHS7Nlm2UyAWAza0AFkzt1A6uhFqEYaoHsR9BLCpg2vukZVr5IU4dV+yU7oRikkTrHDMI9PIHPhJrhQ9Kxugs6hkkhi8Mh5DI9flyCep6ImOt7uxnF6dgypYxMy1hg7S0/yH3FdSL+mpbIw6CVwVSNX7yM/eQfZS7eQu3wb+St3MTJ1D2nq1iicgZbK9YN7rL866PH1qfGBIWj0v/Do4rrR59vK+A0AAP//GfTndQAAAAZJREFUAwCu+SjIaSGpLwAAAABJRU5ErkJggg=="
|
||||
></image>
|
||||
}">
|
||||
<image class="active-icon"
|
||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAMCAYAAAB4MH11AAACKUlEQVR4AaRTS2sTURT+MpkxUzNtRpuYpBsrqbgQH6BYRHGllloQN+5cuNeV6MKfoj9BwYUgIsXHRqE+SluliFLbBqmENJNMMpMm87qecw1NglJse+HMPeee833nce8oIgpFq7wsGt/fCb9eFrtdfmNd1L+9Jc4Vog6E4jcqqM0/R+3zNOwv09jtshdfSx7mDJwKqAMfIvAAEaFVWkLgWjvOEbVdtNa+Epf4wxmFUNTkfqiDGUkqogDu8icKiKS9nQ9jnR8fqM5AwuJJE/G9JhRF05E8dAqIKeDlrsyiWVxg9f+Fum+uzsFZmtnEGIVxKHsGIFn1bAF6ZlQ6I28D9uIrmYSrkodbfETgw6GubZo9Yzk0kR4Fc7IuE8QUFebJKSTSB/kM4UYd1scnKL18QInm4Vk/6W6qiNoOwpZDuoX2elFWXHrzELW5Z+RzJVbPHca+09doIKq0ZQLW+C44iWbm2ZQSNMqozj5F5f1jWCSVGd4fwerstYUXCOplGcsfxponJqHS7Nlm2UyAWAza0AFkzt1A6uhFqEYaoHsR9BLCpg2vukZVr5IU4dV+yU7oRikkTrHDMI9PIHPhJrhQ9Kxugs6hkkhi8Mh5DI9flyCep6ImOt7uxnF6dgypYxMy1hg7S0/yH3FdSL+mpbIw6CVwVSNX7yM/eQfZS7eQu3wb+St3MTJ1D2nq1iicgZbK9YN7rL866PH1qfGBIWj0v/Do4rrR59vK+A0AAP//GfTndQAAAAZJREFUAwCu+SjIaSGpLwAAAABJRU5ErkJggg==">
|
||||
</image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="list-wrap">
|
||||
<view class="tips">
|
||||
<text class="t"
|
||||
>使用商品兑换券的商品,不再计入同享优惠券门槛和折扣计算。</text
|
||||
>
|
||||
<text class="t">使用商品兑换券的商品,不再计入同享优惠券门槛和折扣计算。</text>
|
||||
</view>
|
||||
<view class="title-wrap">
|
||||
<text class="t">可用红包</text>
|
||||
<text class="n">{{ list.canUseCoupons.length }}张</text>
|
||||
</view>
|
||||
<view
|
||||
class="item"
|
||||
v-for="item in list.canUseCoupons"
|
||||
:key="item.id"
|
||||
@click="changeSelCoupon(item)"
|
||||
>
|
||||
<view class="item" v-for="item in list.canUseCoupons" :key="item.id" @click="changeSelCoupon(item)">
|
||||
<view class="top">
|
||||
<view class="icon">
|
||||
<couponIcon :item="item" />
|
||||
@@ -70,29 +51,21 @@
|
||||
<text class="t">{{ item.name }}</text>
|
||||
</view>
|
||||
<view class="view time">
|
||||
<text class="t"
|
||||
>{{ dayjs(item.effectStartTime).format("YYYY.M.D") }} -
|
||||
{{ dayjs(item.effectEndTime).format("YYYY.M.D") }}</text
|
||||
>
|
||||
<text class="t">{{ dayjs(item.effectStartTime).format("YYYY.M.D") }} -
|
||||
{{ dayjs(item.effectEndTime).format("YYYY.M.D") }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn">
|
||||
<view class="active" v-if="isActive(item)">
|
||||
<up-icon
|
||||
name="checkmark-circle-fill"
|
||||
size="24"
|
||||
color="#FF3232"
|
||||
></up-icon>
|
||||
<up-icon name="checkmark-circle-fill" size="24" color="#FF3232"></up-icon>
|
||||
</view>
|
||||
<view class="round" v-else></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btm">
|
||||
<view class="left"
|
||||
>1、可适用门店:{{ item.useShops }} 2、可适用商品:{{
|
||||
<view class="left">1、可适用门店:{{ item.useShops }} 2、可适用商品:{{
|
||||
item.foods
|
||||
}}3、可使用类型:{{ convertValuesToLabels(item.useType) }}</view
|
||||
>
|
||||
}}3、可使用类型:{{ convertValuesToLabels(item.useType) }}</view>
|
||||
<view class="right" @click.stop="showDetailHandle(item)">
|
||||
<text class="t">查看详情</text>
|
||||
</view>
|
||||
@@ -102,11 +75,7 @@
|
||||
<text class="t">不可用红包</text>
|
||||
<text class="n">{{ list.noCanUseCoupons.length }}张</text>
|
||||
</view>
|
||||
<view
|
||||
class="item disabled"
|
||||
v-for="item in list.noCanUseCoupons"
|
||||
:key="item.id"
|
||||
>
|
||||
<view class="item disabled" v-for="item in list.noCanUseCoupons" :key="item.id">
|
||||
<view class="top">
|
||||
<view class="icon">
|
||||
<couponIcon :item="item" />
|
||||
@@ -116,10 +85,8 @@
|
||||
<text class="t">{{ item.name }}</text>
|
||||
</view>
|
||||
<view class="view time">
|
||||
<text class="t"
|
||||
>{{ dayjs(item.effectStartTime).format("YYYY.M.D") }} -
|
||||
{{ dayjs(item.effectEndTime).format("YYYY.M.D") }}</text
|
||||
>
|
||||
<text class="t">{{ dayjs(item.effectStartTime).format("YYYY.M.D") }} -
|
||||
{{ dayjs(item.effectEndTime).format("YYYY.M.D") }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn">
|
||||
@@ -144,17 +111,8 @@
|
||||
<view class="title">
|
||||
<text class="t">店铺列表</text>
|
||||
</view>
|
||||
<scroll-view
|
||||
class="popup-list"
|
||||
direction="vertical"
|
||||
@scrollend="scrollBottom"
|
||||
>
|
||||
<view
|
||||
class="item"
|
||||
v-for="item in shopList"
|
||||
:key="item.shopId"
|
||||
@click="selectShopHandle(item)"
|
||||
>
|
||||
<scroll-view class="popup-list" direction="vertical" @scrollend="scrollBottom">
|
||||
<view class="item" v-for="item in shopList" :key="item.shopId" @click="selectShopHandle(item)">
|
||||
<text class="t">{{ item.shopName }}</text>
|
||||
<text class="intro">地址:{{ item.shopAddress }}</text>
|
||||
</view>
|
||||
@@ -162,24 +120,16 @@
|
||||
</scroll-view>
|
||||
</view>
|
||||
</u-popup>
|
||||
<u-popup
|
||||
:show="showDetail"
|
||||
round="20"
|
||||
closeable
|
||||
@close="showDetail = false"
|
||||
>
|
||||
<u-popup :show="showDetail" round="20" closeable @close="showDetail = false">
|
||||
<view class="shoplist-popup">
|
||||
<view class="title">
|
||||
<text class="t">详情说明</text>
|
||||
</view>
|
||||
<scroll-view class="popup-list" direction="vertical">
|
||||
<view class="ul">
|
||||
<view
|
||||
class="li"
|
||||
v-for="(item, index) in selectListItemDetails"
|
||||
:key="index"
|
||||
>{{ index + 1 }}、{{ item }}</view
|
||||
>
|
||||
<view class="li" v-for="(item, index) in selectListItemDetails" :key="index">
|
||||
{{ index + 1 }}、{{ item }}
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
@@ -189,7 +139,13 @@
|
||||
|
||||
<script setup>
|
||||
import dayjs from "dayjs";
|
||||
import { ref, reactive, onMounted, computed, watch } from "vue";
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
onMounted,
|
||||
computed,
|
||||
watch
|
||||
} from "vue";
|
||||
import {
|
||||
onLoad,
|
||||
onReady,
|
||||
@@ -203,12 +159,16 @@ import {
|
||||
APIfindCoupon,
|
||||
getCouponShops,
|
||||
} from "@/common/api/member.js";
|
||||
import { findCoupon } from "@/common/api/market/coupon.js";
|
||||
import {
|
||||
findCoupon
|
||||
} from "@/common/api/market/coupon.js";
|
||||
import couponIcon from "@/components/coupon-icon/index";
|
||||
// import * as UTILS from '@/utils/goods-utils.js';
|
||||
import yskUtils from "ysk-utils";
|
||||
const UTILS = yskUtils.couponUtils;
|
||||
import { useCartsStore } from "@/stores/carts.js";
|
||||
import {
|
||||
useCartsStore
|
||||
} from "@/stores/carts.js";
|
||||
const cartStore = useCartsStore();
|
||||
|
||||
//返回不可用原因
|
||||
@@ -231,8 +191,7 @@ const querForm = ref({
|
||||
statusActiveIndex: 0,
|
||||
});
|
||||
|
||||
const statusList = ref([
|
||||
{
|
||||
const statusList = ref([{
|
||||
value: 0,
|
||||
label: "商品兑换券",
|
||||
bg: "#333333",
|
||||
@@ -265,22 +224,22 @@ function showDetailHandle(item) {
|
||||
const ruleList = [];
|
||||
|
||||
// 规则1:限时折扣同享(始终显示)
|
||||
const discountRule = item.discountShare
|
||||
? "与限时折扣同享"
|
||||
: "不与限时折扣同享";
|
||||
const discountRule = item.discountShare ?
|
||||
"与限时折扣同享" :
|
||||
"不与限时折扣同享";
|
||||
ruleList.push(discountRule);
|
||||
|
||||
// 规则2:会员价/会员折扣同享(始终显示)
|
||||
const vipRule = item.vipPriceShare
|
||||
? "与会员价/会员折扣同享"
|
||||
: "不与会员价/会员折扣同享";
|
||||
const vipRule = item.vipPriceShare ?
|
||||
"与会员价/会员折扣同享" :
|
||||
"不与会员价/会员折扣同享";
|
||||
ruleList.push(vipRule);
|
||||
|
||||
// 规则3:其他优惠券同享(仅item.type=2时显示)
|
||||
if (item.type === 2) {
|
||||
const otherCouponRule = item.otherCouponShare
|
||||
? "与其他优惠券同享"
|
||||
: "不与其他优惠券同享";
|
||||
const otherCouponRule = item.otherCouponShare ?
|
||||
"与其他优惠券同享" :
|
||||
"不与其他优惠券同享";
|
||||
ruleList.push(otherCouponRule);
|
||||
}
|
||||
const shareRuleText = `${ruleList.join("、")}`;
|
||||
@@ -389,6 +348,7 @@ watch(
|
||||
formatCoupon();
|
||||
}
|
||||
);
|
||||
|
||||
function isActive(item) {
|
||||
if (querForm.value.statusActiveIndex) {
|
||||
return couponSel.value.id == item.id;
|
||||
@@ -398,6 +358,7 @@ function isActive(item) {
|
||||
}
|
||||
|
||||
const couponList = ref([]);
|
||||
|
||||
function formatCoupon() {
|
||||
let canUseGoodsCoupon = [];
|
||||
let canUseDiscountCoupon = [];
|
||||
@@ -420,9 +381,9 @@ function formatCoupon() {
|
||||
for (let i = 0; i < couponList.value.length; i++) {
|
||||
const coupon = couponList.value[i];
|
||||
const selCoupon =
|
||||
querForm.value.statusActiveIndex != 1
|
||||
? quansSelArr.value.filter((v) => v.type != 2)
|
||||
: quansSelArr.value.filter((v) => v.type == 2);
|
||||
querForm.value.statusActiveIndex != 1 ?
|
||||
quansSelArr.value.filter((v) => v.type != 2) :
|
||||
quansSelArr.value.filter((v) => v.type == 2);
|
||||
const canuseResult = UTILS.returnCouponCanUse({
|
||||
canDikouGoodsArr,
|
||||
coupon,
|
||||
@@ -432,7 +393,10 @@ function formatCoupon() {
|
||||
shopInfo,
|
||||
limitTimeDiscount: cartStore.limitTimeDiscount,
|
||||
});
|
||||
const { canUse, reason } = canuseResult;
|
||||
const {
|
||||
canUse,
|
||||
reason
|
||||
} = canuseResult;
|
||||
if (coupon.type == 2) {
|
||||
if (canUse || goodsCouponSel.value.id == coupon.id) {
|
||||
canUseGoodsCoupon.push(coupon);
|
||||
@@ -460,7 +424,7 @@ function formatCoupon() {
|
||||
v,
|
||||
user,
|
||||
goodsOrderPrice,
|
||||
quansSelArr.value,
|
||||
quansSelArr.value.filter((v) => v.type != 2),
|
||||
shopInfo,
|
||||
cartStore.limitTimeDiscount
|
||||
);
|
||||
@@ -477,7 +441,7 @@ function formatCoupon() {
|
||||
v,
|
||||
user,
|
||||
goodsOrderPrice,
|
||||
quansSelArr.value,
|
||||
quansSelArr.value.filter((v) => v.type == 2),
|
||||
shopInfo,
|
||||
cartStore.limitTimeDiscount
|
||||
);
|
||||
@@ -534,8 +498,7 @@ function scrollBottom() {
|
||||
*/
|
||||
function convertValuesToLabels(valueStr, options, separator = "、") {
|
||||
try {
|
||||
options = [
|
||||
{
|
||||
options = [{
|
||||
value: "dine",
|
||||
label: "堂食",
|
||||
},
|
||||
@@ -661,6 +624,16 @@ watch(
|
||||
};
|
||||
});
|
||||
otherCoupon = otherCoupon.map((v) => {
|
||||
const canuseResult = UTILS.returnCouponCanUse({
|
||||
canDikouGoodsArr,
|
||||
coupon:v,
|
||||
goodsOrderPrice,
|
||||
user,
|
||||
selCoupon: goodsCoupon,
|
||||
shopInfo,
|
||||
limitTimeDiscount: cartStore.limitTimeDiscount,
|
||||
});
|
||||
|
||||
const discount = UTILS.returnCouponDiscount(
|
||||
canDikouGoodsArr,
|
||||
v,
|
||||
@@ -672,13 +645,40 @@ watch(
|
||||
);
|
||||
return {
|
||||
...v,
|
||||
canuseResult,
|
||||
discount,
|
||||
discountAmount: discount ? discount.discountPrice : v.discountAmount,
|
||||
};
|
||||
});
|
||||
uni.$emit("selCoupon", [...goodsCoupon, ...otherCoupon]);
|
||||
},
|
||||
{
|
||||
let noCanUseCoupon = null
|
||||
|
||||
for (let item of otherCoupon) {
|
||||
console.log('item',item)
|
||||
if (!item.canuseResult.canUse) {
|
||||
noCanUseCoupon = item
|
||||
couponSel.value={id:''}
|
||||
console.log('couponSel.value',couponSel.value)
|
||||
return uni.showModal({
|
||||
title: '提示',
|
||||
showCancel:false,
|
||||
content: '优惠券' + item.name + '已不满足使用门槛,已剔除',
|
||||
success() {
|
||||
|
||||
}
|
||||
})
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
if(noCanUseCoupon){
|
||||
return
|
||||
}
|
||||
|
||||
const newArr = [...goodsCoupon, ...otherCoupon]
|
||||
|
||||
uni.$emit("selCoupon", newArr);
|
||||
|
||||
}, {
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -217,7 +217,6 @@
|
||||
listinfo.discountInfo = tempArray;
|
||||
}
|
||||
// 回填先质控
|
||||
listinfo.pointsDiscountAmount = 0
|
||||
// console.log(listinfo)
|
||||
|
||||
console.log("orderorderInfo list info: ", listinfo);
|
||||
@@ -686,7 +685,6 @@
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-shadow: 0rpx 4rpx 12rpx 2rpx rgba(87, 86, 86, 0.35);
|
||||
border-radius: 18rpx;
|
||||
|
||||
.card_head_box {
|
||||
|
||||
@@ -73,16 +73,23 @@
|
||||
<view class="shop-amount">
|
||||
<text
|
||||
class="orderAmount">¥{{item.status == 'unpaid'?item.originAmount:item.orderAmount}}</text>
|
||||
<text class="totalNumber">共{{item.goods.length}}件</text>
|
||||
<text class="totalNumber">共{{totalGoodsNum(item.goods) }}件</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="footer-wrap">
|
||||
<view class="take_food_number u-m-b-16" v-if="item.takeCode">
|
||||
<text class="u-font-24 color-333"> 取餐号:</text>
|
||||
<text class="u-font-32 font-700 color-333">{{item.takeCode}}</text>
|
||||
|
||||
</view>
|
||||
<view class="footer-wrap">
|
||||
<view class="btn" @click.stop="$u.debounce(isRemoveOrder(item,index),1000)"
|
||||
v-if="item.status != 'unpaid' && item.status != 'paying'"> 删除订单 </view>
|
||||
v-if="item.status == 'done' || item.status == 'cancelled'"> 删除订单 </view>
|
||||
<view class="btn s" @click.stop="$u.debounce(showpopupclick(item),1000)"
|
||||
v-if="item.status == 'unpaid' || item.status == 'paying'"> 去付款 </view>
|
||||
</view> -->
|
||||
|
||||
<view class="btn s" @click.stop="agignOrder(item)" v-if="item.status == 'done'"> 再来一单 </view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="flex-colum" v-if="orderForm.list.length <= 0">
|
||||
@@ -116,14 +123,60 @@
|
||||
} from '@dcloudio/uni-app'
|
||||
import Nav from '@/components/CustomNavbar.vue'; //导航栏
|
||||
import {
|
||||
APIuserorder
|
||||
APIuserorder,
|
||||
APIputuserorder
|
||||
} from '@/common/api/order/index.js'
|
||||
// pinia管理
|
||||
import {
|
||||
useNavbarStore
|
||||
} from '@/stores/navbarStore';
|
||||
import {APIshopUserInfo} from '@/common/api/member.js'
|
||||
const store = useNavbarStore();
|
||||
|
||||
async function agignOrder(item){
|
||||
await APIshopUserInfo({
|
||||
shopId:item.shopId
|
||||
}).then(shopUserInfo=>{
|
||||
if(shopUserInfo){
|
||||
uni.cache.set("dinersNum", 1);
|
||||
uni.cache.set("tableCode", shopUserInfo.id);
|
||||
uni.cache.set("shopId", item.shopId);
|
||||
uni.navigateTo({
|
||||
url: "/pages/product/index?type=beforehand&order_id="+item.id+'&one_more_order=1',
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
function totalGoodsNum(arr){
|
||||
if(!arr){
|
||||
return 0
|
||||
}
|
||||
return arr.reduce((prve,cur)=>{
|
||||
return prve+cur.num
|
||||
},0)
|
||||
}
|
||||
function isRemoveOrder(item) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '订单一旦删除不可恢复,确认删除该订单吗?',
|
||||
showCancel: true,
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
APIputuserorder(item.id).then(res => {
|
||||
uni.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'none'
|
||||
})
|
||||
setTimeout(() => {
|
||||
init_fn()
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 导航栏
|
||||
const tabs = [{
|
||||
name: '全部',
|
||||
@@ -340,7 +393,7 @@
|
||||
}
|
||||
|
||||
.header-wrap {
|
||||
padding: 16rpx 18rpx;
|
||||
padding: 32rpx 24rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
@@ -378,7 +431,7 @@
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0 18rpx 18rpx 18rpx;
|
||||
padding: 0 24rpx 16rpx 30rpx;
|
||||
|
||||
.shop-info {
|
||||
display: flex;
|
||||
@@ -450,11 +503,9 @@
|
||||
padding: 0 18rpx 32rpx 18rpx;
|
||||
|
||||
.btn {
|
||||
width: 128rpx;
|
||||
height: 48rpx;
|
||||
line-height: 43rpx;
|
||||
text-align: center;
|
||||
background: #FFFFFF;
|
||||
padding: 6rpx 14rpx;
|
||||
border-radius: 10rpx 10rpx 10rpx 10rpx;
|
||||
border: 2rpx solid #EDEDED;
|
||||
font-weight: 400;
|
||||
@@ -527,4 +578,10 @@
|
||||
.ml-20 {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
.take_food_number{
|
||||
padding: 20rpx;
|
||||
background-color: #F8F8F8;
|
||||
margin-left: 36rpx;
|
||||
margin-right: 24rpx;
|
||||
}
|
||||
</style>
|
||||
43
pages/product/components/utils.js
Normal file
43
pages/product/components/utils.js
Normal file
@@ -0,0 +1,43 @@
|
||||
// 套餐比较两个对象是否相等
|
||||
export function isObjectEqual(obj1, obj2) {
|
||||
if (typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null) {
|
||||
return obj1 === obj2;
|
||||
}
|
||||
const keys1 = Object.keys(obj1);
|
||||
const keys2 = Object.keys(obj2);
|
||||
if (keys1.length !== keys2.length) {
|
||||
return false;
|
||||
}
|
||||
for (const key of keys1) {
|
||||
if (Array.isArray(obj1[key]) && Array.isArray(obj2[key])) {
|
||||
if (!isArrayEqual(obj1[key], obj2[key])) {
|
||||
return false;
|
||||
}
|
||||
} else if (!isObjectEqual(obj1[key], obj2[key])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 比较两个数组是否相等(忽略顺序)
|
||||
export function isArrayEqual(arr1, arr2) {
|
||||
if (arr1.length !== arr2.length) {
|
||||
return false;
|
||||
}
|
||||
const usedIndices = new Array(arr2.length).fill(false);
|
||||
for (const item1 of arr1) {
|
||||
let found = false;
|
||||
for (let i = 0; i < arr2.length; i++) {
|
||||
if (!usedIndices[i] && isObjectEqual(item1, arr2[i])) {
|
||||
usedIndices[i] = true;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@
|
||||
</view>
|
||||
<view class="bildRight">
|
||||
<text>我的积分</text>
|
||||
<view>{{shopUserInfo.accountPoints||0}}</view>
|
||||
<view>{{shopUserInfo.pointsUser?shopUserInfo.pointsUser.pointBalance:0}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bottom">
|
||||
@@ -109,7 +109,8 @@
|
||||
} from 'vue'
|
||||
|
||||
import {
|
||||
onReachBottom,onLoad
|
||||
onReachBottom,
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app'
|
||||
|
||||
import {
|
||||
@@ -208,20 +209,21 @@
|
||||
})
|
||||
if (res) {
|
||||
Object.assign(shopUserInfo, res)
|
||||
formData.id =res.pointsUser?res.pointsUser.id:''
|
||||
formData.shopId =res.pointsUser?res.pointsUser.shopId:''
|
||||
}
|
||||
}
|
||||
const options = reactive({})
|
||||
onLoad((opt)=>{
|
||||
onLoad(async (opt) => {
|
||||
Object.assign(options, opt)
|
||||
console.log('options', options);
|
||||
formData.shopId = options.shopId
|
||||
formData.active = options.type
|
||||
formData.id = options.id || ''
|
||||
console.log(formData.info)
|
||||
await getShopUserInfo()
|
||||
getlist()
|
||||
getShopUserInfo()
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
@@ -232,6 +234,7 @@
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.bg {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@@ -239,11 +242,13 @@
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: -1;
|
||||
|
||||
.image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.bildLeft,
|
||||
.bildRight {
|
||||
font-weight: 400;
|
||||
@@ -261,12 +266,14 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom {
|
||||
background-color: rgba(255, 255, 255, .3);
|
||||
padding: 40rpx 28rpx 0 28rpx;
|
||||
transform: translateY(-140rpx);
|
||||
border-radius: 74rpx 74rpx 0 0;
|
||||
}
|
||||
|
||||
.navTop {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<view class="u-flex">
|
||||
<view class="color-666 no-wrap">领取方式</view>
|
||||
<view class="u-m-l-16" v-if="item.goodsCategory=='优惠券'">系统发放</view>
|
||||
<view class="u-m-l-16" v-else>店内自取</view>
|
||||
<view class="u-m-l-16" v-else>需前往店铺自行兑换领取</view>
|
||||
</view>
|
||||
<view class="u-flex u-m-t-16 u-col-baseline" v-if="item.goodsCategory=='优惠券'">
|
||||
<view class="color-666 no-wrap">特别说明</view>
|
||||
@@ -53,9 +53,12 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view style="height: 100px"></view>
|
||||
<view style="height: 140px"></view>
|
||||
<view class="fixed-bottom u-flex u-row-center">
|
||||
<view class="btn" @click="exchangeClick" :class="[isCanExchange?'':'gray']">
|
||||
<view v-if="isCanExchange" class="btn" @click="exchangeClick" >
|
||||
{{returnBtmText}}
|
||||
</view>
|
||||
<view class="btn gray" v-else >
|
||||
{{returnBtmText}}
|
||||
</view>
|
||||
</view>
|
||||
@@ -77,7 +80,7 @@
|
||||
<view class="popup-content-top">
|
||||
<text class="color-666">领取方式</text>
|
||||
<text class="u-m-l-16" v-if="item.goodsCategory=='优惠券'">系统发放</text>
|
||||
<text class="u-m-l-16" v-else>店内自取</text>
|
||||
<text class="u-m-l-16" v-else>需前往店铺自行兑换领取</text>
|
||||
</view>
|
||||
<view class="goods-info">
|
||||
<view class="u-flex">
|
||||
@@ -414,7 +417,7 @@
|
||||
background-color: #fff;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 2rpx);
|
||||
padding-bottom: 40px;
|
||||
padding-top: 32rpx;
|
||||
background-color: #fff;
|
||||
bottom: 0;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<view v-for="(item, index) in list" :key="index" @click="toDetail(item)">
|
||||
<template v-if="layout === 'list'">
|
||||
<view class="item">
|
||||
<view class="img coupon" v-if="item.goodsCategory=='优惠券'&&item.couponInfo">
|
||||
<view class="img coupon" v-if="item.goodsCategory=='优惠券'&&item.couponInfo" style="width: 142rpx;">
|
||||
<couponIcon :item="item.couponInfo" typeKey="couponType" />
|
||||
</view>
|
||||
<image class="img" v-else lazy-load :src="item.goodsImageUrl" mode="aspectFill"></image>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</view>
|
||||
<view class="u-m-t-22 u-flex u-col-center">
|
||||
<up-image width="132rpx" height="132rpx" :src="item.goodsImageUrl" v-if="item.goodsCategory!='优惠券'"></up-image>
|
||||
<view class="img" v-else>
|
||||
<view class="img" style="width: 138rpx;" v-else>
|
||||
<couponIcon :item="item.couponInfo" typeKey="couponType" />
|
||||
</view>
|
||||
<view class="u-p-l-36">
|
||||
|
||||
@@ -10,13 +10,17 @@
|
||||
<view class="u-p-l-28 u-flex-1">
|
||||
<view class="font-bold">{{item.pointsGoodsName}}</view>
|
||||
<view class="u-flex u-row-between u-m-t-8">
|
||||
<text class="color1 font-bold">{{item.spendPoints}}积分</text>
|
||||
<view class="u-flex color1 font-bold">
|
||||
<text >{{item.spendPoints}}积分</text>
|
||||
<text v-if="item.extraPaymentAmount">+ {{item.extraPaymentAmount}}元</text>
|
||||
</view>
|
||||
|
||||
<text class="status " :class="[returnStatusClass(item)]">{{item.status}}</text>
|
||||
</view>
|
||||
<view class="u-m-t-8 font-bold color1"> X{{item.number}} </view>
|
||||
</view>
|
||||
</view>
|
||||
<template v-if="item.goodsCategory=='其它商品'&&item.status!='已退款'">
|
||||
<template v-if="item.goodsCategory=='其它商品'&&item.status!='已退款'&&item.status!='已完成'">
|
||||
<view class="u-m-t-16">
|
||||
<view class="u-flex u-row-center">
|
||||
<up-qrcode cid="ex1" :size="104" :val="qrcode"></up-qrcode>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<up-loadmore :status="isEnd?'nomore':'loadmore'"></up-loadmore>
|
||||
</view>
|
||||
|
||||
<modal v-model="modalData.show" title="立即兑换确认" :showBottom="false">
|
||||
<modal v-model="modalData.show" title="查看券码" :showBottom="false">
|
||||
<view class="u-p-28">
|
||||
<view class="u-flex u-row-center">
|
||||
<up-qrcode cid="ex1" :size="104" :val="qrcode"></up-qrcode>
|
||||
|
||||
@@ -93,6 +93,9 @@ export const useWebSocket = defineStore('socketTask', () => {
|
||||
function setOnMessage(onMessageBallBack){
|
||||
onMessage=onMessageBallBack
|
||||
}
|
||||
function chnageInitMessage(data){
|
||||
initMessage=data
|
||||
}
|
||||
// 连接 WebSocket
|
||||
const connect = async (connectMsg, onMessageBallBack) => {
|
||||
if (!isNetworkConnected.value) {
|
||||
@@ -363,6 +366,6 @@ export const useWebSocket = defineStore('socketTask', () => {
|
||||
initNetworkListener,
|
||||
connect,
|
||||
allowReconnect,
|
||||
socketTask,setOnMessage
|
||||
socketTask,setOnMessage,chnageInitMessage
|
||||
};
|
||||
})
|
||||
@@ -1,4 +1,6 @@
|
||||
import { defineStore } from "pinia";
|
||||
import {
|
||||
defineStore
|
||||
} from "pinia";
|
||||
// import yskUtils from 'ysk-utils'
|
||||
// const {
|
||||
// OrderPriceCalculator,
|
||||
@@ -10,11 +12,19 @@ import { defineStore } from "pinia";
|
||||
// MerchantReductionType,
|
||||
// GoodsType
|
||||
// } = yskUtils
|
||||
import yskUtils from '@/lib/index'
|
||||
// import yskUtils from 'ysk-utils'
|
||||
const {
|
||||
OrderPriceCalculator
|
||||
} = yskUtils
|
||||
|
||||
import yskUtils from 'ysk-utils'
|
||||
const {OrderPriceCalculator}=yskUtils
|
||||
|
||||
import { ref, computed, reactive, watchEffect, watch } from "vue";
|
||||
import {
|
||||
ref,
|
||||
computed,
|
||||
reactive,
|
||||
watchEffect,
|
||||
watch
|
||||
} from "vue";
|
||||
import {
|
||||
productminiApphotsquery,
|
||||
APIgroupquery,
|
||||
@@ -35,13 +45,12 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
|
||||
// 适配工具库 BaseCartItem 接口的商品数据转换函数
|
||||
const convertToBaseCartItem = (item) => {
|
||||
const skuData = item.skuData
|
||||
? {
|
||||
const skuData = item.skuData ? {
|
||||
id: item.skuData.id || item.sku_id,
|
||||
salePrice: item.skuData.salePrice || 0,
|
||||
memberPrice: item.skuData.memberPrice || 0,
|
||||
}
|
||||
: undefined;
|
||||
} :
|
||||
undefined;
|
||||
|
||||
const goods = getProductDetails({
|
||||
...item,
|
||||
@@ -49,7 +58,8 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
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)
|
||||
const discountSaleAmount = item.discount_sale_amount ? (item.discount_sale_amount * 1) : (item
|
||||
.discountSaleAmount ? item.discountSaleAmount * 1 : 0)
|
||||
return {
|
||||
...item,
|
||||
id: item.id,
|
||||
@@ -66,15 +76,13 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
discountSaleAmount: discountSaleAmount,
|
||||
packFee: item.packFee || (goods ? goods.packFee : 0) || 0,
|
||||
packNumber: item.pack_number || item.packNumber || 0,
|
||||
activityInfo: item.activityInfo
|
||||
? {
|
||||
activityInfo: item.activityInfo ? {
|
||||
type: item.activityInfo.type,
|
||||
discountRate: OrderPriceCalculator.formatDiscountRate(
|
||||
item.activityInfo.discountRate
|
||||
),
|
||||
vipPriceShare: !!item.activityInfo.vipPriceShare,
|
||||
}
|
||||
: undefined,
|
||||
} : undefined,
|
||||
skuData,
|
||||
};
|
||||
};
|
||||
@@ -117,8 +125,7 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
(newval) => {
|
||||
seatFeeConfig.value.isEnabled = !shopInfo.value.isTableFee;
|
||||
seatFeeConfig.value.pricePerPerson = shopInfo.value.tableFee || 0;
|
||||
},
|
||||
{
|
||||
}, {
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
@@ -130,21 +137,36 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
() => seatFeeConfig.value,
|
||||
(newval) => {
|
||||
console.log("seatFeeConfig", seatFeeConfig.value);
|
||||
},
|
||||
{
|
||||
}, {
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//积分规则
|
||||
const pointDeductionRule = ref({
|
||||
enableRewards: 0, //是否开启
|
||||
pointsPerYuan: 0,
|
||||
maxDeductionAmount: Infinity,
|
||||
maxDeductionRatio: 0 ,//积分抵扣比例
|
||||
minPaymentAmount:0,//门槛
|
||||
});
|
||||
|
||||
function setPointDeductionRule(pointsPerYuan, maxDeductionAmount) {
|
||||
pointDeductionRule.value.pointsPerYuan = pointsPerYuan;
|
||||
pointDeductionRule.value.maxDeductionAmount = maxDeductionAmount;
|
||||
function setPointDeductionRule(args) {
|
||||
const {
|
||||
equivalentPoints,
|
||||
maxDeductionAmount,enableRewards,minPaymentAmount,
|
||||
maxDeductionRatio
|
||||
} = args
|
||||
pointDeductionRule.value.pointsPerYuan =equivalentPoints||0;
|
||||
pointDeductionRule.value.maxDeductionAmount = maxDeductionAmount||0;
|
||||
pointDeductionRule.value.maxDeductionRatio = maxDeductionRatio||0;
|
||||
pointDeductionRule.value.enableRewards = enableRewards||0;
|
||||
pointDeductionRule.value.minPaymentAmount = minPaymentAmount||0;
|
||||
}
|
||||
|
||||
// 初始配置:默认无减免(固定金额 0 元)
|
||||
@@ -351,8 +373,7 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
}
|
||||
|
||||
// 历史订单
|
||||
if (Message.operate_type == "clearOrder") {
|
||||
}
|
||||
if (Message.operate_type == "clearOrder") {}
|
||||
|
||||
// 购物车数据更新从新请求
|
||||
if (
|
||||
@@ -431,9 +452,10 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
return false;
|
||||
}
|
||||
const isUse =
|
||||
shopUserInfo.value.isVip && shopUserInfo.value.isMemberPrice && shopInfo.value.isMemberPrice==1
|
||||
? true
|
||||
: false;
|
||||
shopUserInfo.value.isVip && shopUserInfo.value.isMemberPrice && shopInfo.value
|
||||
.isMemberPrice == 1 ?
|
||||
true :
|
||||
false;
|
||||
return isUse;
|
||||
});
|
||||
|
||||
@@ -648,7 +670,7 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
orderCostSummary,
|
||||
setCoupons,
|
||||
userPoints,
|
||||
setUserPoints,
|
||||
setUserPoints,pointDeductionRule,
|
||||
setPointDeductionRule,
|
||||
setOldOrder,
|
||||
//返回商品信息
|
||||
|
||||
Reference in New Issue
Block a user