mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
synced 2026-08-06 02:47:25 +08:00
feat: 增加礼品卡选择功能及相关逻辑
- 在 api/trade.js 中新增 selectGiftCard 函数以支持礼品卡选择 - 更新多个组件以集成礼品卡功能,包括购物车和订单页面 - 优化商品页面和订单详情展示,支持礼品卡抵扣信息 - 调整相关逻辑以确保礼品卡与其他促销活动的兼容性
This commit is contained in:
14
api/trade.js
14
api/trade.js
@@ -169,6 +169,20 @@ export function setAddressId(addressId,way) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选择礼品卡
|
||||||
|
* @param way 购物车购买:CART/立即购买:BUY_NOW/拼团:PINTUAN / 积分:POINTS / 砍价:KANJIA
|
||||||
|
* @param credentialId 礼品卡凭证 id;used=false 且不传则清空全部
|
||||||
|
*/
|
||||||
|
export function selectGiftCard(params) {
|
||||||
|
return http.request({
|
||||||
|
url: `/trade/carts/select/giftCard`,
|
||||||
|
method: Method.GET,
|
||||||
|
needToken: true,
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建交易
|
* 创建交易
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ const formatList = ref<any[]>([])
|
|||||||
const currentSelected = ref<string[]>([])
|
const currentSelected = ref<string[]>([])
|
||||||
const skuList = ref('')
|
const skuList = ref('')
|
||||||
|
|
||||||
// E_COUPON 库存来自卡池 poolStock,上限 min(poolStock, 999)
|
// E_COUPON 库存读 SKU quantity,上限 min(quantity, 999)
|
||||||
const availableStock = computed(() => {
|
const availableStock = computed(() => {
|
||||||
if (isECoupon(props.goodsDetail?.goodsType)) {
|
if (isECoupon(props.goodsDetail?.goodsType)) {
|
||||||
return getECouponStock(props.goodsDetail)
|
return getECouponStock(props.goodsDetail)
|
||||||
@@ -189,9 +189,9 @@ watch(num, (val) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(() => props.buyType, (val) => {
|
watch(() => props.isGroup, (val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
buyType.value = val as string
|
buyType.value = 'PINTUAN'
|
||||||
}
|
}
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
||||||
@@ -273,18 +273,36 @@ const handleClickSpec = (val: any, index: number, specValue: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 直接购买
|
* 活动页/父组件直接调用购买(POINTS / KANJIA 等显式 cartType)
|
||||||
*/
|
*/
|
||||||
const buy = (data: any) => {
|
const buy = (data: any) => {
|
||||||
API_trade.addToCart(data).then(res => {
|
uni.hideLoading()
|
||||||
|
API_trade.addToCart(data).then((res) => {
|
||||||
if (res.data.success) {
|
if (res.data.success) {
|
||||||
|
const way = data.cartType || 'BUY_NOW'
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: `/pages/order/fillorder?way=${data.cartType}&addr=${''}&parentOrder=${encodeURIComponent(JSON.stringify(parentOrder.value))}`
|
url: `/pages/order/fillorder?way=${way}&addr=${''}&parentOrder=${encodeURIComponent(JSON.stringify(parentOrder.value || ''))}`,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: res.data.message || '购买失败',
|
||||||
|
icon: 'none',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 解析 cartType:拼团 PINTUAN;核销 VIRTUAL;其余含 E_COUPON 为 BUY_NOW */
|
||||||
|
function resolveCartType() {
|
||||||
|
if (buyType.value === 'PINTUAN') {
|
||||||
|
return 'PINTUAN'
|
||||||
|
}
|
||||||
|
if (isVirtualGoods(props.goodsDetail?.goodsType)) {
|
||||||
|
return 'VIRTUAL'
|
||||||
|
}
|
||||||
|
return 'BUY_NOW'
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加到购物车或购买
|
* 添加到购物车或购买
|
||||||
*/
|
*/
|
||||||
@@ -292,13 +310,13 @@ const addToCartOrBuy = (val: string) => {
|
|||||||
if (!selectSkuList.value) {
|
if (!selectSkuList.value) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '请选择规格商品',
|
title: '请选择规格商品',
|
||||||
icon: 'none'
|
icon: 'none',
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let data = {
|
const data: Record<string, any> = {
|
||||||
skuId: props.goodsDetail.id,
|
skuId: props.goodsDetail.id,
|
||||||
num: num.value
|
num: num.value,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val == 'cart') {
|
if (val == 'cart') {
|
||||||
@@ -310,24 +328,24 @@ const addToCartOrBuy = (val: string) => {
|
|||||||
})
|
})
|
||||||
emit('queryCart')
|
emit('queryCart')
|
||||||
closeMask()
|
closeMask()
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: res.data.message || '加购失败',
|
||||||
|
icon: 'none',
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
if (buyType.value) {
|
data.cartType = resolveCartType()
|
||||||
data.cartType = 'PINTUAN'
|
|
||||||
} else if (isECoupon(props.goodsDetail.goodsType)) {
|
|
||||||
// 与 VIRTUAL 核销区分:E_COUPON 必须 BUY_NOW,支付后 COMPLETED + cardKeys
|
|
||||||
data.cartType = 'BUY_NOW'
|
|
||||||
} else if (isVirtualGoods(props.goodsDetail.goodsType)) {
|
|
||||||
data.cartType = 'VIRTUAL'
|
|
||||||
} else {
|
|
||||||
data.cartType = 'BUY_NOW'
|
|
||||||
}
|
|
||||||
|
|
||||||
API_trade.addToCart(data).then((res) => {
|
API_trade.addToCart(data).then((res) => {
|
||||||
if (res.data.success) {
|
if (res.data.success) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: `/pages/order/fillorder?way=${data.cartType}&addr=${props.addr?.id || ''}&parentOrder=${encodeURIComponent(JSON.stringify(parentOrder.value))}`,
|
url: `/pages/order/fillorder?way=${data.cartType}&addr=${props.addr?.id || ''}&parentOrder=${encodeURIComponent(JSON.stringify(parentOrder.value || ''))}`,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: res.data.message || '购买失败',
|
||||||
|
icon: 'none',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -405,6 +423,12 @@ const formatSku = (list: any[]) => {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
formatSku(props.goodsSpec)
|
formatSku(props.goodsSpec)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
buy,
|
||||||
|
buyType,
|
||||||
|
parentOrder,
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
<div class="bar"></div>
|
<div class="bar"></div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 选择自提点 -->
|
<!-- 选择自提点 -->
|
||||||
<div class="address-box" v-if="shippingText == 'SELF_PICK_UP' && !isECouponCheckout">
|
<div class="address-box" v-if="shippingText == 'SELF_PICK_UP' && !hidePhysicalCheckout">
|
||||||
<div @click="clickToStoreAddress()">
|
<div @click="clickToStoreAddress()">
|
||||||
<div class="user-box flex">
|
<div class="user-box flex">
|
||||||
<div class="flex-8">
|
<div class="flex-8">
|
||||||
@@ -283,7 +283,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<u-row
|
<u-row
|
||||||
v-if="
|
v-if="
|
||||||
!isECouponCheckout &&
|
|
||||||
orderMessage.priceDetailDTO.goodsPrice != 0 &&
|
orderMessage.priceDetailDTO.goodsPrice != 0 &&
|
||||||
orderMessage.priceDetailDTO.goodsPrice != null
|
orderMessage.priceDetailDTO.goodsPrice != null
|
||||||
"
|
"
|
||||||
@@ -310,7 +309,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</u-col>
|
</u-col>
|
||||||
</u-row>
|
</u-row>
|
||||||
<div v-if="!isECouponCheckout">
|
<div>
|
||||||
<u-row>
|
<u-row>
|
||||||
<u-col :span="9">优惠金额</u-col>
|
<u-col :span="9">优惠金额</u-col>
|
||||||
<u-col
|
<u-col
|
||||||
@@ -325,7 +324,7 @@
|
|||||||
<u-col :span="3" textAlign="right" v-else>0.00</u-col>
|
<u-col :span="3" textAlign="right" v-else>0.00</u-col>
|
||||||
</u-row>
|
</u-row>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!isECouponCheckout">
|
<div>
|
||||||
<u-row>
|
<u-row>
|
||||||
<u-col :span="6">活动优惠</u-col>
|
<u-col :span="6">活动优惠</u-col>
|
||||||
<u-col :span="6" class="tr tipsColor" textAlign="right">
|
<u-col :span="6" class="tr tipsColor" textAlign="right">
|
||||||
@@ -337,6 +336,34 @@
|
|||||||
</u-col>
|
</u-col>
|
||||||
</u-row>
|
</u-row>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="giftCardList.length || giftCardDeductAmount > 0">
|
||||||
|
<u-row>
|
||||||
|
<u-col :span="6">礼品卡</u-col>
|
||||||
|
<u-col :span="6" class="tr tipsColor" textAlign="right">
|
||||||
|
<span v-if="giftCardDeductAmount > 0" class="main-color"
|
||||||
|
>-¥{{ unitPrice(giftCardDeductAmount) }}</span
|
||||||
|
>
|
||||||
|
<span v-else @click="giftCardExpanded = !giftCardExpanded"
|
||||||
|
>{{ giftCardList.length }} 张可用</span
|
||||||
|
>
|
||||||
|
</u-col>
|
||||||
|
</u-row>
|
||||||
|
<view v-if="giftCardExpanded && giftCardList.length" class="gift-card-list">
|
||||||
|
<view
|
||||||
|
class="gift-card-item"
|
||||||
|
:class="{ 'gift-card-item--selected': isGiftCardSelected(item) }"
|
||||||
|
v-for="item in giftCardList"
|
||||||
|
:key="item.id"
|
||||||
|
@click="toggleGiftCard(item)"
|
||||||
|
>
|
||||||
|
<view class="gift-card-item__name">{{ item.giftCardName || '礼品卡' }}</view>
|
||||||
|
<view class="gift-card-item__meta">
|
||||||
|
<text>余额 ¥{{ unitPrice(item.balance) }}</text>
|
||||||
|
<text class="gift-card-item__no">{{ item.cardNo }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 配送地区没有提示 -->
|
<!-- 配送地区没有提示 -->
|
||||||
@@ -445,13 +472,25 @@ const notSupportFreightNoticeText = ref('')
|
|||||||
const storeAddress = ref<any>('')
|
const storeAddress = ref<any>('')
|
||||||
const originOrderData = ref<any>('')
|
const originOrderData = ref<any>('')
|
||||||
|
|
||||||
// E_COUPON 结算:免地址、无运费/优惠券/促销(O-11);与 VIRTUAL 共用 hidePhysicalCheckout
|
// E_COUPON 结算:免地址/免配送(hidePhysicalCheckout);优惠券/活动/礼品卡可用(M-02)
|
||||||
const isECouponCheckout = computed(() => hasECouponInCheckout(orderMessage.value))
|
const isECouponCheckout = computed(() => hasECouponInCheckout(orderMessage.value))
|
||||||
const isVirtualCheckout = computed(() => orderMessage.value?.cartTypeEnum === 'VIRTUAL')
|
const isVirtualCheckout = computed(() => orderMessage.value?.cartTypeEnum === 'VIRTUAL')
|
||||||
const hidePhysicalCheckout = computed(
|
const hidePhysicalCheckout = computed(
|
||||||
() => isVirtualCheckout.value || isECouponCheckout.value
|
() => isVirtualCheckout.value || isECouponCheckout.value
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const giftCardList = computed(() => orderMessage.value?.canUseGiftCards || [])
|
||||||
|
const giftCardDeductAmount = computed(() => {
|
||||||
|
const dto = orderMessage.value?.priceDetailDTO
|
||||||
|
if (!dto) return 0
|
||||||
|
if (orderMessage.value?.giftCardDeductTotal != null) {
|
||||||
|
return Number(orderMessage.value.giftCardDeductTotal) || 0
|
||||||
|
}
|
||||||
|
return Number(dto.giftCardPrice) || 0
|
||||||
|
})
|
||||||
|
const selectedGiftCardIds = computed(() => orderMessage.value?.selectedGiftCardIds || [])
|
||||||
|
const giftCardExpanded = ref(false)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
remarkVal,
|
remarkVal,
|
||||||
(val) => {
|
(val) => {
|
||||||
@@ -566,6 +605,29 @@ function invoice() {
|
|||||||
invoiceFlag.value = true
|
invoiceFlag.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isGiftCardSelected(item: any) {
|
||||||
|
if (!item?.id) return false
|
||||||
|
return (selectedGiftCardIds.value || []).map(String).includes(String(item.id))
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleGiftCard(item: any) {
|
||||||
|
if (!item?.id) return
|
||||||
|
API_Trade.selectGiftCard({
|
||||||
|
way: routerVal.value.way,
|
||||||
|
credentialId: String(item.id),
|
||||||
|
used: !isGiftCardSelected(item),
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.data.success) {
|
||||||
|
getOrderList()
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: res.data.message || '礼品卡选择失败',
|
||||||
|
icon: 'none',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function GET_Discount() {
|
function GET_Discount() {
|
||||||
let storeIds: any[] = []
|
let storeIds: any[] = []
|
||||||
let skus: any[] = []
|
let skus: any[] = []
|
||||||
@@ -1187,4 +1249,40 @@ page {
|
|||||||
.goods-item {
|
.goods-item {
|
||||||
margin: 20rpx 0;
|
margin: 20rpx 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gift-card-list {
|
||||||
|
margin-top: 16rpx;
|
||||||
|
padding: 0 8rpx 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-card-item {
|
||||||
|
border: 1rpx solid #eceef2;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 20rpx 24rpx;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
&--selected {
|
||||||
|
border-color: $main-color;
|
||||||
|
background: rgba($main-color, 0.04);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-card-item__name {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-card-item__meta {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-card-item__no {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -116,14 +116,18 @@
|
|||||||
<view class="title">运费:</view>
|
<view class="title">运费:</view>
|
||||||
<view class="value">¥{{unitPrice(order.freightPrice) }}</view>
|
<view class="value">¥{{unitPrice(order.freightPrice) }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="order-info-view" v-if="!isECouponOrder && order.priceDetailDTO">
|
<view class="order-info-view" v-if="order.priceDetailDTO && Number(order.priceDetailDTO.couponPrice) > 0">
|
||||||
<view class="title">优惠券:</view>
|
<view class="title">优惠券:</view>
|
||||||
<view class="value main-color">-¥{{unitPrice(order.priceDetailDTO.couponPrice) }}</view>
|
<view class="value main-color">-¥{{unitPrice(order.priceDetailDTO.couponPrice) }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="order-info-view" v-if="!isECouponOrder">
|
<view class="order-info-view" v-if="Number(order.discountPrice) > 0">
|
||||||
<view class="title">活动优惠:</view>
|
<view class="title">活动优惠:</view>
|
||||||
<view class="value main-color">-¥{{unitPrice(order.discountPrice) }}</view>
|
<view class="value main-color">-¥{{unitPrice(order.discountPrice) }}</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="order-info-view" v-if="order.priceDetailDTO && Number(order.priceDetailDTO.giftCardPrice) > 0">
|
||||||
|
<view class="title">礼品卡抵扣:</view>
|
||||||
|
<view class="value main-color">-¥{{unitPrice(order.priceDetailDTO.giftCardPrice) }}</view>
|
||||||
|
</view>
|
||||||
<!-- <view class="order-info-view" v-if="order.use_point">
|
<!-- <view class="order-info-view" v-if="order.use_point">
|
||||||
<view class="title">使用积分:</view>
|
<view class="title">使用积分:</view>
|
||||||
<view class="value">{{ order.use_point }}</view>
|
<view class="value">{{ order.use_point }}</view>
|
||||||
|
|||||||
@@ -90,8 +90,8 @@
|
|||||||
|
|
||||||
<GoodsSwiper id="main1" :res="imgList" :video="goodsDetail.goodsVideo" />
|
<GoodsSwiper id="main1" :res="imgList" :video="goodsDetail.goodsVideo" />
|
||||||
|
|
||||||
<!-- 促销活动条(E_COUPON 不参与促销 M-01) -->
|
<!-- 促销活动条(秒杀/限时直降/拼团等,M-02 含 E_COUPON) -->
|
||||||
<PromotionAssembleLayout v-if="PromotionList && !isECouponGoods" :detail="goodsDetail" :res="PromotionList" />
|
<PromotionAssembleLayout v-if="PromotionList" :detail="goodsDetail" :res="PromotionList" />
|
||||||
|
|
||||||
<view class="card-box top-radius-0" id="main2">
|
<view class="card-box top-radius-0" id="main2">
|
||||||
<!-- 活动不显示价钱 -->
|
<!-- 活动不显示价钱 -->
|
||||||
@@ -172,8 +172,8 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 促销/领券入口(E_COUPON 隐藏) -->
|
<!-- 促销/领券入口 -->
|
||||||
<view class="card-box" v-if="!isECouponGoods">
|
<view class="card-box">
|
||||||
<view class="card-flex" @click="shutMask(1)">
|
<view class="card-flex" @click="shutMask(1)">
|
||||||
<view class="card-title"> 促销 </view>
|
<view class="card-title"> 促销 </view>
|
||||||
<view class="card-content">
|
<view class="card-content">
|
||||||
@@ -187,7 +187,7 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 拼团用户列表 -->
|
<!-- 拼团用户列表 -->
|
||||||
<PromotionAssembleListLayout v-if="isGroup && !isECouponGoods" @to-assemble-buy-now="toAssembleBuyNow" :res="PromotionList" />
|
<PromotionAssembleListLayout v-if="isGroup" @to-assemble-buy-now="toAssembleBuyNow" :res="PromotionList" />
|
||||||
|
|
||||||
<!-- 实物配送地址;E_COUPON / VIRTUAL_GOODS 均不展示 -->
|
<!-- 实物配送地址;E_COUPON / VIRTUAL_GOODS 均不展示 -->
|
||||||
<view class="card-box" v-if="!isNonPhysicalGoodsType">
|
<view class="card-box" v-if="!isNonPhysicalGoodsType">
|
||||||
@@ -262,7 +262,7 @@
|
|||||||
<view class="detail-btn" v-if="!isGroup && !takeDownFromSale">
|
<view class="detail-btn" v-if="!isGroup && !takeDownFromSale">
|
||||||
<view class="to-store-car to-store-btn" v-if="showAddToCart" @click="shutMask(4)">
|
<view class="to-store-car to-store-btn" v-if="showAddToCart" @click="shutMask(4)">
|
||||||
加入购物车</view>
|
加入购物车</view>
|
||||||
<view class="to-buy to-store-btn" :class="{ 'to-buy--full': isECouponGoods }" @click="shutMask(4, 'buy')">立即购买</view>
|
<view class="to-buy to-store-btn" @click="shutMask(4, 'buy')">立即购买</view>
|
||||||
<view class="to-store-car to-store-btn" v-if="startTimer">暂未开始</view>
|
<view class="to-store-car to-store-btn" v-if="startTimer">暂未开始</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- 拼团结算 -->
|
<!-- 拼团结算 -->
|
||||||
@@ -329,7 +329,7 @@ import storage from '@/utils/storage.js'
|
|||||||
/************工具函数***************/
|
/************工具函数***************/
|
||||||
import { useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
import { unitPrice, goodsFormatPrice, isLogin, parseGoodsImageUrl, clearStrComma, talkIm } from '@/utils/filters.js'
|
import { unitPrice, goodsFormatPrice, isLogin, parseGoodsImageUrl, clearStrComma, talkIm } from '@/utils/filters.js'
|
||||||
import { isECoupon, isNonPhysicalGoods } from '@/utils/goodsType.js'
|
import { isNonPhysicalGoods } from '@/utils/goodsType.js'
|
||||||
|
|
||||||
/************组件***************/
|
/************组件***************/
|
||||||
import PromotionLayout from './product/promotion/-promotion'
|
import PromotionLayout from './product/promotion/-promotion'
|
||||||
@@ -430,11 +430,10 @@ const IM = computed(() => {
|
|||||||
return IMLink.value + storeDetail.value.merchantEuid
|
return IMLink.value + storeDetail.value.merchantEuid
|
||||||
})
|
})
|
||||||
|
|
||||||
// E_COUPON:仅立即购买,隐藏促销/地址/加购(FR-B-01 / P-08)
|
// E_COUPON:禁加购、免地址;促销展示与 VIRTUAL 对齐(M-02)
|
||||||
const isECouponGoods = computed(() => isECoupon(goodsDetail.value?.goodsType))
|
|
||||||
const isNonPhysicalGoodsType = computed(() => isNonPhysicalGoods(goodsDetail.value?.goodsType))
|
const isNonPhysicalGoodsType = computed(() => isNonPhysicalGoods(goodsDetail.value?.goodsType))
|
||||||
const showAddToCart = computed(() => {
|
const showAddToCart = computed(() => {
|
||||||
return !isNonPhysicalGoodsType.value && !isECouponGoods.value
|
return !isNonPhysicalGoodsType.value
|
||||||
})
|
})
|
||||||
|
|
||||||
// watch
|
// watch
|
||||||
@@ -547,10 +546,6 @@ async function init(id: any, goodsId: any, distributionId = "") {
|
|||||||
|
|
||||||
PromotionList.value &&
|
PromotionList.value &&
|
||||||
Object.keys(PromotionList.value).forEach((item: string) => {
|
Object.keys(PromotionList.value).forEach((item: string) => {
|
||||||
// E_COUPON 不参与拼团/秒杀(M-01),避免底部出现拼团双按钮
|
|
||||||
if (isECoupon(goodsDetail.value?.goodsType)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (item.indexOf("PINTUAN") == 0) {
|
if (item.indexOf("PINTUAN") == 0) {
|
||||||
isGroup.value = true
|
isGroup.value = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
class="showBox"
|
class="showBox"
|
||||||
v-if="
|
v-if="
|
||||||
promotion.__key == 'SECKILL' ||
|
promotion.__key == 'SECKILL' ||
|
||||||
|
promotion.__key == 'FLASH_DISCOUNT' ||
|
||||||
promotion.__key == 'GROUPBUY' ||
|
promotion.__key == 'GROUPBUY' ||
|
||||||
promotion.__key == 'PINTUAN'
|
promotion.__key == 'PINTUAN'
|
||||||
"
|
"
|
||||||
@@ -36,6 +37,29 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 限时直降 -->
|
||||||
|
<view class="u-group-flex-left" v-if="promotion.__key == 'FLASH_DISCOUNT'">
|
||||||
|
<span
|
||||||
|
class="u-group-flex-left-span"
|
||||||
|
v-if="detail.promotionPrice != undefined"
|
||||||
|
>
|
||||||
|
¥
|
||||||
|
<span class="flex-price">
|
||||||
|
{{ goodsFormatPrice(detail.promotionPrice)[0] }}.{{
|
||||||
|
goodsFormatPrice(detail.promotionPrice)[1]
|
||||||
|
}}</span
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
<view class="u-group-flex" v-if="detail.price != undefined">
|
||||||
|
<span class="old-price"
|
||||||
|
>¥{{ goodsFormatPrice(detail.price)[0] }}.{{
|
||||||
|
goodsFormatPrice(detail.price)[1]
|
||||||
|
}}</span
|
||||||
|
>
|
||||||
|
<view class="promotion">限时直降</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 团购 -->
|
<!-- 团购 -->
|
||||||
<view class="u-group-flex-left" v-if="promotion.__key == 'GROUPBUY'">
|
<view class="u-group-flex-left" v-if="promotion.__key == 'GROUPBUY'">
|
||||||
<span class="u-group-flex-left-span">
|
<span class="u-group-flex-left-span">
|
||||||
|
|||||||
@@ -40,6 +40,26 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<view v-if="getPromType(prom) == 'FLASH_DISCOUNT'">
|
||||||
|
<view class="res_prom_item">
|
||||||
|
<view class="deg_tag">限时直降</view>
|
||||||
|
<text class="pro-text">{{ props.res[prom].promotionName || props.res[prom].title || '限时直降活动' }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="getPromType(prom) == 'NTH_ITEM_DISCOUNT'">
|
||||||
|
<view class="res_prom_item">
|
||||||
|
<view class="deg_tag">第N件优惠</view>
|
||||||
|
<text class="pro-text">
|
||||||
|
第{{ props.res[prom].nthNum || 'N' }}件
|
||||||
|
<text v-if="props.res[prom].discountType === 'FREE'">免费</text>
|
||||||
|
<text v-else-if="props.res[prom].discountType === 'HALF'">半价</text>
|
||||||
|
<text v-else-if="props.res[prom].discountValue">享{{ props.res[prom].discountValue }}折</text>
|
||||||
|
<text v-else>优惠</text>
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
<view v-if="getPromType(prom) == 'POINTS_GOODS'">
|
<view v-if="getPromType(prom) == 'POINTS_GOODS'">
|
||||||
<view class="res_prom_item">
|
<view class="res_prom_item">
|
||||||
<view class="deg_tag">积分活动</view>
|
<view class="deg_tag">积分活动</view>
|
||||||
|
|||||||
@@ -2,6 +2,18 @@
|
|||||||
<view>
|
<view>
|
||||||
<view v-for="(promotionItem, promotionIndex) in promotion" :key="promotionIndex" class="promotion_row" @click="shutMask(1)">
|
<view v-for="(promotionItem, promotionIndex) in promotion" :key="promotionIndex" class="promotion_row" @click="shutMask(1)">
|
||||||
<view v-if="res != null" v-for="(item, index) in Object.keys(res)" :key="index">
|
<view v-if="res != null" v-for="(item, index) in Object.keys(res)" :key="index">
|
||||||
|
<div class="promotion_col" v-if="item.split('-')[0] == promotionItem.value && item.split('-')[0] == 'FLASH_DISCOUNT'">
|
||||||
|
<div class="flex">
|
||||||
|
<view class="deg_tag">{{ promotionItem.title }}</view>
|
||||||
|
<div class="text proText">{{ res[item].promotionName || res[item].title || '限时直降' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="promotion_col" v-if="item.split('-')[0] == promotionItem.value && item.split('-')[0] == 'NTH_ITEM_DISCOUNT'">
|
||||||
|
<div class="flex">
|
||||||
|
<view class="deg_tag">{{ promotionItem.title }}</view>
|
||||||
|
<div class="text proText">{{ res[item].promotionName || res[item].title || '第N件优惠' }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="promotion_col" v-if="item.split('-')[0] == promotionItem.value && item.split('-')[0] == 'FULL_DISCOUNT'">
|
<div class="promotion_col" v-if="item.split('-')[0] == promotionItem.value && item.split('-')[0] == 'FULL_DISCOUNT'">
|
||||||
<!-- 满减,折扣 -->
|
<!-- 满减,折扣 -->
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
|
|||||||
@@ -8,21 +8,17 @@ const promotion = [
|
|||||||
value: "KANJIA",
|
value: "KANJIA",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "单品立减",
|
title: "限时直降",
|
||||||
value: "MINUS",
|
value: "FLASH_DISCOUNT",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "第N件优惠",
|
||||||
|
value: "NTH_ITEM_DISCOUNT",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "团购",
|
title: "团购",
|
||||||
value: "GROUPBUY",
|
value: "GROUPBUY",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: "积分换购",
|
|
||||||
value: "EXCHANGE",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "第二件半价",
|
|
||||||
value: "HALF_PRICE",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: "满减优惠",
|
title: "满减优惠",
|
||||||
value: "FULL_DISCOUNT",
|
value: "FULL_DISCOUNT",
|
||||||
|
|||||||
@@ -4,15 +4,16 @@
|
|||||||
*
|
*
|
||||||
* 卡密商品(电子卡券 E_COUPON)类型与订单工具。
|
* 卡密商品(电子卡券 E_COUPON)类型与订单工具。
|
||||||
*
|
*
|
||||||
* 与 VIRTUAL_GOODS / VIRTUAL 核销商品区分:E_COUPON 走 BUY_NOW、支付后 COMPLETED + cardKeys,
|
* 与 VIRTUAL_GOODS / VIRTUAL 核销商品区分:E_COUPON 走 BUY_NOW/PINTUAN/POINTS/KANJIA,
|
||||||
* 不支持加购、促销与买家售后。需求见 lilishop/docs/requirements/card-key-goods-v4.md
|
* 支付后 COMPLETED + cardKeys;禁加购、免地址;M-02 支持全量促销;不支持买家售后。
|
||||||
|
* 需求见 lilishop/docs/requirements/card-key-goods-v4.md
|
||||||
*/
|
*/
|
||||||
export const E_COUPON_GOODS_TYPE = 'E_COUPON'
|
export const E_COUPON_GOODS_TYPE = 'E_COUPON'
|
||||||
export const E_COUPON_ORDER_TYPE = 'E_COUPON'
|
export const E_COUPON_ORDER_TYPE = 'E_COUPON'
|
||||||
export const VIRTUAL_GOODS_TYPE = 'VIRTUAL_GOODS'
|
export const VIRTUAL_GOODS_TYPE = 'VIRTUAL_GOODS'
|
||||||
export const VIRTUAL_ORDER_TYPE = 'VIRTUAL'
|
export const VIRTUAL_ORDER_TYPE = 'VIRTUAL'
|
||||||
|
|
||||||
/** 单次购买数量上限(O-09 默认:min(poolStock, 999)) */
|
/** 单次购买数量上限(O-09 默认:min(quantity, 999)) */
|
||||||
export const E_COUPON_MAX_BUY_NUM = 999
|
export const E_COUPON_MAX_BUY_NUM = 999
|
||||||
|
|
||||||
export function isECoupon(goodsType) {
|
export function isECoupon(goodsType) {
|
||||||
@@ -40,13 +41,9 @@ export function isNonPhysicalOrder(orderType) {
|
|||||||
return isECouponOrder(orderType) || isVirtualOrder(orderType)
|
return isECouponOrder(orderType) || isVirtualOrder(orderType)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 可售库存:E_COUPON 以卡池 poolStock 为准,quantity 仅为镜像回退 */
|
/** 可售库存:E_COUPON 读 SKU quantity(由卡池 syncSkuStock 同步) */
|
||||||
export function getECouponStock(sku) {
|
export function getECouponStock(sku) {
|
||||||
if (!sku) return 0
|
if (!sku) return 0
|
||||||
const pool = sku.poolStock
|
|
||||||
if (pool !== undefined && pool !== null) {
|
|
||||||
return Number(pool) || 0
|
|
||||||
}
|
|
||||||
return Number(sku.quantity) || 0
|
return Number(sku.quantity) || 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +54,7 @@ export function getECouponMaxBuyNum(sku) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 结算页识别当前交易是否含 E_COUPON SKU。
|
* 结算页识别当前交易是否含 E_COUPON SKU(用于免地址/免配送,不用于促销屏蔽)。
|
||||||
* 须从 goodsSku.goodsType 判断,不能依赖 cartTypeEnum=VIRTUAL(E_COUPON 仍是 BUY_NOW)。
|
* 须从 goodsSku.goodsType 判断,不能依赖 cartTypeEnum=VIRTUAL(E_COUPON 仍是 BUY_NOW)。
|
||||||
*/
|
*/
|
||||||
export function hasECouponInCheckout(orderMessage) {
|
export function hasECouponInCheckout(orderMessage) {
|
||||||
|
|||||||
Reference in New Issue
Block a user