Просмотр исходного кода

feat(member): 优化会员相关功能及赠品订单展示

- 在购物车和分类页价格显示中,新增会员激活状态区分,显示会员价及原价
- 赠品订单确认页面根据是否为赠品订单分别更新商品列表和配送信息
- 赠品订单确认页新增会员权益和赠品价格展示样式
- 优化订单详情页,调整退款、优惠券、积分显示逻辑,区分赠品订单显示
- 会员优惠券页面支持路由类型参数,VIP路由跳转逻辑调整
- 会员中心新增领取赠品逻辑,防止重复领取并提示
- 订单列表页售后申请禁止赠品订单操作
- 修正赠品订单状态显示为“待自提”与“待配送”区分
- 调整部分样式及增加控制台日志便于调试会员状态变化
zouzexu 1 неделя назад
Родитель
Сommit
2d0de45900

+ 10 - 1
src/pages/cart/index.vue

@@ -4,6 +4,7 @@ import router from '@/router'
 
 import selectAddressTemplate from '@/subPack-smqjh/components/selectAddress/index.vue?async'
 
+const { userMemberInfo } = storeToRefs(useUserStore())
 definePage({
   name: 'smqjh-cart',
   layout: 'tabbar',
@@ -118,7 +119,15 @@ async function handleSelectAddress() {
                     规格:{{ item.spec }}
                   </view>
                   <view class="mt-14rpx flex items-center justify-between">
-                    <view class="text-36rpx text-[#FF4A39] font-semibold">
+                    <view v-if="userMemberInfo.active" class="flex items-center gap-20rpx">
+                      <view class="text-36rpx text-[#FF4A39] font-semibold">
+                        ¥{{ item.memberPrice }}
+                      </view>
+                      <view class="text-26rpx text-#AAAAAA line-through">
+                        ¥{{ item.price }}
+                      </view>
+                    </view>
+                    <view v-else class="text-36rpx text-[#FF4A39] font-semibold">
                       ¥{{ item.price }}
                     </view>
                     <!-- <wd-input-number v-model="item.num" disable-input @change="handleChangeNum($event, item)" /> -->

+ 1 - 1
src/subPack-smqjh/components/xsb-orderList/xsb-orderList.vue

@@ -168,7 +168,7 @@ async function handleLogistics(_order: Api.xsbOrderList) {
           </wd-button>
         </view>
       </template>
-      <template v-if="order.refundStatus != 2 && [OrderStatus.OrderWaitDelivery, OrderStatus.OrderAccepted].includes(order.hbOrderStatus) ">
+      <template v-if="!order.giftOrder && order.refundStatus != 2 && [OrderStatus.OrderWaitDelivery, OrderStatus.OrderAccepted].includes(order.hbOrderStatus) ">
         <view class="mr-20rpx">
           <wd-button size="small" plain type="info" @click.stop="() => handleAfterSale(order)">
             申请售后

+ 3 - 3
src/subPack-smqjh/giveawaysVip/giveawaysVip.vue

@@ -61,9 +61,9 @@ async function pickUp() {
         channelId: item.channelId!,
       }
     })
-    const totalGoodsPrice = giveawaysList.value.reduce((sum, item) => {
-      return sum + Number(item.price || 0) * Number(item.quantity || 1)
-    }, 0)
+    const totalGoodsPrice = Number(giveawaysList.value.reduce((sum, item) => {
+      return sum + Math.round(Number(item.price || 0) * 100) * Number(item.quantity || 1)
+    }, 0) / 100)
     const orderInfo = {
       totalPrice: 0,
       transfee: 0,

+ 12 - 3
src/subPack-smqjh/userVip/userVip.vue

@@ -15,6 +15,7 @@ definePage({
 const { userMemberInfo } = storeToRefs(useUserStore())
 const rightsInfo = ref()
 onMounted(() => {
+  useUserStore().getUserInfo()
   opcity.value = 0
   rightsInfo.value = JSON.parse(userMemberInfo.value.benefitConfigJson || '')
   console.log(JSON.parse(userMemberInfo.value.benefitConfigJson || ''), '解析出的json')
@@ -30,6 +31,14 @@ function toUse() {
     url: 'https://mp.weixin.qq.com/s/lxpdZ6DUhgqg00AT9klu5Q',
   })
 }
+function toShoppingList() {
+  if (!userMemberInfo?.value.giftReceived) {
+    router.push({ name: 'smqjh-giveaways-vip' })
+  }
+  else {
+    useGlobalToast().show({ msg: '您已经领取过咯~~' })
+  }
+}
 </script>
 
 <template>
@@ -167,7 +176,7 @@ function toUse() {
               <view class="text-28rpx text-#b5b5b5">
                 优惠券{{ userMemberInfo?.couponCount }}张
               </view>
-              <view class="mt-16rpx h-42rpx w-108rpx rounded-22rpx bg-#F4E5BD text-center text-24rpx text-#7F5935 line-height-42rpx" @click="router.push({ name: 'xsb-coupon' })">
+              <view class="mt-16rpx h-42rpx w-108rpx rounded-22rpx bg-#F4E5BD text-center text-24rpx text-#7F5935 line-height-42rpx" @click="router.push({ name: 'xsb-coupon', params: { type: 'VIP' } })">
                 去查看
               </view>
             </view>
@@ -183,8 +192,8 @@ function toUse() {
               <view class="text-28rpx text-#b5b5b5">
                 自选赠品{{ userMemberInfo?.giftCount }}个
               </view>
-              <view class="mt-16rpx h-42rpx w-108rpx rounded-22rpx bg-#F4E5BD text-center text-24rpx text-#7F5935 line-height-42rpx" @click="router.push({ name: 'smqjh-giveaways-vip' })">
-                {{ userMemberInfo?.giftCount > 0 ? '待领取' : '已领取' }}
+              <view class="mt-16rpx h-42rpx w-108rpx rounded-22rpx bg-#F4E5BD text-center text-24rpx text-#7F5935 line-height-42rpx" @click="toShoppingList">
+                {{ userMemberInfo?.giftReceived ? '已领取' : '待领取' }}
               </view>
             </view>
             <image :src="userMemberInfo?.giftConfig[0].icon" class="h-80rpx w-80rpx" />

+ 10 - 2
src/subPack-xsb/commonTab/components/cart.vue

@@ -4,7 +4,7 @@ import router from '@/router'
 import { useSmqjhCartStore } from '@/store/cart'
 
 const emit = defineEmits(['changeTab'])
-
+const { userMemberInfo } = storeToRefs(useUserStore())
 const { cartList, isCartAllChecked, totalProduct } = storeToRefs(useSmqjhCartStore())
 const cartStore = useSmqjhCartStore()
 const priceDetailPopup = ref(false)
@@ -84,7 +84,15 @@ onMounted(async () => {
                       规格:{{ item.spec }}
                     </view>
                     <view class="mt14rpx flex items-center justify-between">
-                      <view class="text-36rpx text-#FF4A39 font-semibold">
+                      <view v-if="userMemberInfo.active" class="flex items-center gap-20rpx">
+                        <view class="text-36rpx text-[#FF4A39] font-semibold">
+                          ¥{{ item.memberPrice }}
+                        </view>
+                        <view class="text-26rpx text-#AAAAAA line-through">
+                          ¥{{ item.price }}
+                        </view>
+                      </view>
+                      <view v-else class="text-36rpx text-[#FF4A39] font-semibold">
                         ¥{{ item.price }}
                       </view>
                       <!-- <wd-input-number v-model="item.num" disable-input @change="handleChangeNum($event, item)" /> -->

+ 3 - 3
src/subPack-xsb/commonTab/components/classfiy.vue

@@ -576,9 +576,9 @@ export default {
                         </text> <text class="text-30rpx">
                           {{ item.memberPrice }}
                         </text>
-                        <view class="rounded-8rpx bg-#FF4A39 px-8rpx py-4rpx text-22rpx text-#FFF">
-                          会员价
-                        </view>
+                        <!--                        <view class="rounded-8rpx bg-#FF4A39 px-8rpx py-4rpx text-22rpx text-#FFF"> -->
+                        <!--                          会员价 -->
+                        <!--                        </view> -->
                         <text class="text-24rpx text-#AAA line-through">
                           {{ item.channelProdPrice }}
                         </text>

+ 2 - 1
src/subPack-xsb/commonTab/index.vue

@@ -59,11 +59,12 @@ function handleTabbarChange({ value }: { value: string }) {
   tabbarName.value = value
 }
 watch(() => isClassfiyPageOpen.value, () => {
+  console.log('isClassfiyPageOpen')
   if (isClassfiyPageOpen.value) {
     handleChange('xsb-classfiy')
     isClassfiyPageOpen.value = false
   }
-})
+}, { deep: true, immediate: true })
 function setTabbarItemActive(name: string) {
   tabbarItems.value.forEach((item) => {
     if (item.name === name) {

+ 10 - 4
src/subPack-xsb/components/coupon/index.vue

@@ -3,20 +3,26 @@ import { dayjs } from 'wot-design-uni'
 import { StaticUrl } from '@/config'
 import router from '@/router'
 
-defineProps<{
+const props = defineProps<{
   itemcoupon: Api.AppMemberCouponVO
   /** 是否显示"去使用"按鈕,默认 true */
   showUseBtn?: boolean
   /** 隐藏所有操作按鈕(选券模式用) */
   hideAllBtn?: boolean
+  /** 路由参数类型 */
+  routeType?: string
 }>()
 const {
   isClassfiyPageOpen,
 } = storeToRefs(useSysXsbStore())
 function handleUseCoupon() {
-  isClassfiyPageOpen.value = true
-  // router.replace({ name: 'xsb-homeTabbar', params: { name: 'xsb-classfiy' } })
-  router.back()
+  if (props.routeType === 'VIP') {
+    router.replace({ name: 'xsb-homeTabbar', params: { name: 'xsb-classfiy' } })
+  }
+  else {
+    isClassfiyPageOpen.value = true
+    router.back()
+  }
 }
 </script>
 

+ 52 - 13
src/subPack-xsb/confirmOrder/index.vue

@@ -2,6 +2,7 @@
 import CouponItem from '../components/coupon/index.vue'
 import router from '@/router'
 
+const { userMemberInfo } = storeToRefs(useUserStore())
 definePage({
   name: 'xsb-confirmOrder',
   islogin: true,
@@ -89,9 +90,15 @@ const displayTotalPrice = computed(() => {
   return Math.max(0, Number((goodsPrice + freight - currentCouponDiscount.value - pointsDiscount).toFixed(2)))
 })
 const displayDiscountTotal = computed(() => Number((currentCouponDiscount.value + offsetPoints.value / 100).toFixed(2)))
+const giftOriginalTotal = computed(() => {
+  if (!isMemberGiftOrder.value)
+    return 0
+  return Number((Number(orderInfo.value?.price || 0) + Number(orderInfo.value?.transfee || 0)).toFixed(2))
+})
 
 onLoad((options: any) => {
   orderInfo.value = JSON.parse(options.data)
+  console.log(orderInfo.value, '===商品数据===')
   syncCouponState()
   deliveryType.value = current.value === '自提' ? 2 : 3
   // model.value1 = userInfo.value?.nickName || ''
@@ -99,14 +106,14 @@ onLoad((options: any) => {
 })
 onShow(() => {
   useUserStore().getuserAddresslist()
-  if (orderInfo.value && current.value === '即时配送' && isSingleSkuOrder.value) {
+  if (orderInfo.value && current.value === '即时配送' && (isSingleSkuOrder.value || isMemberGiftOrder.value)) {
     getConfirmOrder()
   }
 })
 
 watch(current, async (value) => {
   deliveryType.value = value === '自提' ? 2 : 3
-  if (orderInfo.value && isSingleSkuOrder.value) {
+  if (orderInfo.value && (isSingleSkuOrder.value || isMemberGiftOrder.value)) {
     await getConfirmOrder()
   }
 })
@@ -150,15 +157,25 @@ async function getConfirmOrder() {
   const res = await Apis.xsb.skuOrderConfirm({
     data: params,
   })
-  const skuList = res.data.sku
-    ? [{ ...res.data.sku, num: params.num, shopId: params.shopId }]
-    : (orderInfo.value?.skuList || [])
-  orderInfo.value = {
-    ...orderInfo.value,
-    ...res.data,
-    skuList,
-  } as ConfirmOrderInfo
-  syncCouponState()
+  if (isMemberGiftOrder.value) {
+    // 赠品订单仅更新配送费和店铺地址信息,保留原始商品数据
+    orderInfo.value = {
+      ...orderInfo.value,
+      transfee: res.data.transfee ?? orderInfo.value?.transfee ?? 0,
+      shopAddressDTO: res.data.shopAddressDTO ?? orderInfo.value?.shopAddressDTO,
+    } as ConfirmOrderInfo
+  }
+  else {
+    const skuList = res.data.sku
+      ? [{ ...res.data.sku, num: params.num, shopId: params.shopId }]
+      : (orderInfo.value?.skuList || [])
+    orderInfo.value = {
+      ...orderInfo.value,
+      ...res.data,
+      skuList,
+    } as ConfirmOrderInfo
+    syncCouponState()
+  }
 }
 
 function openShopLocation() {
@@ -401,6 +418,12 @@ async function handlePay() {
           ¥{{ orderInfo?.transfee }}
         </view>
       </view>
+      <view v-if="!isMemberGiftOrder && userMemberInfo.active" class="mb28rpx flex items-center justify-between text-28rpx">
+        <view>{{ orderInfo?.memberBenefitDesc }}</view>
+        <view class="text-#FF4D3A font-semibold">
+          -¥{{ orderInfo?.memberDiscountAmount }}
+        </view>
+      </view>
       <view v-if="!isMemberGiftOrder" class="mb28rpx flex items-center justify-between text-28rpx" @click="openCouponPopup">
         <view>优惠券</view>
         <view class="flex items-center">
@@ -424,7 +447,15 @@ async function handlePay() {
         <view class="font-semibold">
           总计:
         </view>
-        <view class="text-#FF4D3A font-semibold">
+        <view v-if="isMemberGiftOrder" class="flex items-center">
+          <text class="mr-8rpx rounded-8rpx bg-#FF4D3A px-12rpx py-4rpx text-22rpx text-#FFF">
+            赠品
+          </text>
+          <text class="text-#AAAAAA line-through">
+            ¥{{ giftOriginalTotal }}
+          </text>
+        </view>
+        <view v-else class="text-#FF4D3A font-semibold">
           ¥ {{ displayTotalPrice }}
         </view>
       </view>
@@ -521,7 +552,15 @@ async function handlePay() {
     </Zpopup>
     <view class="ios footer fixed bottom-0 left-0 z-1000 box-border w-full rounded-t-16rpx bg-white px24rpx">
       <view class="box-border w-full flex items-center justify-between py20rpx">
-        <view class="flex items-center text-#FF4D3A">
+        <view v-if="isMemberGiftOrder" class="flex items-center">
+          <text class="mr-8rpx rounded-8rpx bg-#FF4D3A px-12rpx py-4rpx text-22rpx text-#FFF">
+            赠品
+          </text>
+          <text class="text-32rpx text-#AAAAAA line-through">
+            ¥{{ giftOriginalTotal }}
+          </text>
+        </view>
+        <view v-else class="flex items-center text-#FF4D3A">
           <view class="font-semibold10 flex items-baseline text-36rpx">
             <text class="text-24rpx">

+ 5 - 0
src/subPack-xsb/coupon/index.vue

@@ -12,6 +12,7 @@ const tabList = [
 
 const activeTab = ref(0)
 const activeCoupon = ref(null)
+const routeType = ref('')
 
 const { data: couponList, isLastPage, page, reload } = usePagination(
   (pageNum, pageSize) => Apis.xsb.memberCouponPage({
@@ -32,6 +33,9 @@ const { data: couponList, isLastPage, page, reload } = usePagination(
 )
 onLoad((options: any) => {
   console.log(options)
+  if (options.type) {
+    routeType.value = options.type
+  }
   if (options.couponId) {
     activeCoupon.value = options.couponId
     switchTab(Number(options.activeTab))
@@ -69,6 +73,7 @@ onReachBottom(() => {
           <CouponItem
             :itemcoupon="item"
             :show-use-btn="item.useStatus === 2"
+            :route-type="routeType"
           />
         </view>
       </view>

+ 32 - 30
src/subPack-xsb/orderDetaile/index.vue

@@ -322,7 +322,7 @@ function handleRefundDetail(item: any) {
               商家拣货中
             </view>
             <view v-if="orderInfo.hbOrderStatus === OrderStatus.OrderWaitDelivery" class="mr-10rpx">
-              订单待配送
+              {{ orderInfo.dvyType === 2 ? '订单待自提' : '订单待配送' }}
             </view>
             <view v-if="orderInfo.hbOrderStatus === OrderStatus.OrderDelivering" class="mr-10rpx">
               订单配送中
@@ -510,39 +510,41 @@ function handleRefundDetail(item: any) {
             ¥{{ orderInfo?.freightAmount }}
           </view>
         </view>
-        <view v-if="orderInfo?.giftOrder" class="mt-24rpx flex items-center justify-between">
-          <view class="text-28rpx">
-            会员权益({{ userMemberInfo?.benefitConfig.mallDiscountRate }}折)
-          </view>
-          <view class="text-[#FF4A39] font-semibold">
-            ¥{{ orderInfo?.memberDiscountAmount }}
-          </view>
-        </view>
-        <view class="mt-24rpx flex items-center justify-between">
-          <view class="text-28rpx">
-            优惠券
-          </view>
-          <view class="text-[#FF4A39] font-semibold">
-            -¥{{ Number(orderInfo?.couponBaseInfoDTO?.discountMoney) || 0 }}
-          </view>
-        </view>
-        <view v-if="orderInfo.refundOrderList && orderInfo.refundOrderList.some((it) => it.refundOrderStatus == 1) " class="mt10rpx rounded-16rpx bg-#ccc p24rpx text-24rpx">
-          <view v-if="orderInfo?.isAll">
-            已退还优惠券:{{ orderInfo.couponBaseInfoDTO?.activityName }}
-            <view>优惠券已退回您的账户,可在“我的-优惠券”中查看</view>
+        <template v-if="!orderInfo?.giftOrder">
+          <view v-if="orderInfo?.giftOrder" class="mt-24rpx flex items-center justify-between">
+            <view class="text-28rpx">
+              会员权益({{ userMemberInfo?.benefitConfig.mallDiscountRate || '-' }}折)
+            </view>
+            <view class="text-[#FF4A39] font-semibold">
+              -¥{{ orderInfo?.memberDiscountAmount }}
+            </view>
           </view>
-          <view v-else>
-            注:部分退款不退还优惠券
+          <view class="mt-24rpx flex items-center justify-between">
+            <view class="text-28rpx">
+              优惠券
+            </view>
+            <view class="text-[#FF4A39] font-semibold">
+              -¥{{ Number(orderInfo?.couponBaseInfoDTO?.discountMoney) || 0 }}
+            </view>
           </view>
-        </view>
-        <view class="mt-24rpx flex items-center justify-between">
-          <view class="text-28rpx">
-            积分
+          <view v-if="orderInfo.refundOrderList && orderInfo.refundOrderList.some((it) => it.refundOrderStatus == 1) " class="mt10rpx rounded-16rpx bg-#ccc p24rpx text-24rpx">
+            <view v-if="orderInfo?.isAll">
+              已退还优惠券:{{ orderInfo.couponBaseInfoDTO?.activityName }}
+              <view>优惠券已退回您的账户,可在“我的-优惠券”中查看</view>
+            </view>
+            <view v-else>
+              注:部分退款不退还优惠券
+            </view>
           </view>
-          <view class="text-[#FF4A39] font-semibold">
-            -¥{{ Number(orderInfo?.offsetPoints) / 100 }}
+          <view class="mt-24rpx flex items-center justify-between">
+            <view class="text-28rpx">
+              积分
+            </view>
+            <view class="text-[#FF4A39] font-semibold">
+              -¥{{ Number(orderInfo?.offsetPoints) / 100 }}
+            </view>
           </view>
-        </view>
+        </template>
         <view class="my-24rpx h-2rpx w-full bg-[#F0F0F0]" />
         <view class="flex items-center justify-end">
           <view class="text-28rpx">