Ver código fonte

feat(cart): 优化购物车功能与界面细节

- 新增购物车清空按钮,方便用户快速删除选中商品
- 购物车商品列表中显示已选商品数量及总重量信息
- 添加计算当前门店购物车商品总数的接口getShopTotalNum
- 修正删除购物车商品逻辑,增强删除确认与提示流程
- 调整分类页商品数量显示,使用门店购物车商品总数替代总购物车数
- 优化优惠券页面和订单详情页,修正优惠券显示与有效期格式
- 新增优惠券使用跳转至分类页的状态控制逻辑
- 退货售后详情页修正退款金额与积分显示,增加跳转优惠券按钮
- 系统状态管理中新增分类页面打开状态标记isClassfiyPageOpen
- 修复多个界面细节样式及文本错误,提高用户体验
zhangtao 5 dias atrás
pai
commit
6c2460bef9

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

@@ -75,11 +75,20 @@ async function handleSelectAddress() {
           管理
         </view>
       </view>
+      <view v-if="cartList.length" class="mb20rpx flex items-center justify-end">
+        <view class="text-24rpx text-[#AAAAAA]" @click="cartStore.cartDeleteGoods">
+          <wd-icon name="delete" size="24rpx" /> 清空购物车
+        </view>
+      </view>
       <scroll-view scroll-y class="content box-border px-24rpx">
         <view v-for="shop in cartList" :key="shop.shopId" class="mb-24rpx rounded-16rpx bg-white px-24rpx pb-18rpx pt-28rpx">
           <wd-checkbox v-model="shop.AllShopGoods" size="large" @change="cartStore.cartStoreAllChecked($event, shop)">
             <view class="text-28rpx font-semibold">
-              {{ shop.shopName }}
+              {{ shop.shopName }} <text class="text-24rpx text-#AAAAAA">
+                已选 {{ shop.allGoods.length }} 件<text v-if="shop.allGoods.length">
+                  ,总重量约为 {{ totalProduct?.totalWeight || 0 }} kg
+                </text>
+              </text>
             </view>
           </wd-checkbox>
           <view class="mt-20rpx h-2rpx w-full bg-[#F0F0F0]" />

+ 17 - 6
src/store/cart.ts

@@ -28,6 +28,13 @@ export const useSmqjhCartStore = defineStore('smqjh-cart', {
     getTotalNum(): number {
       return this.cartList.map(it => it.skuList.map(its => its.num)).reduce((a, b) => a.concat(b), []).reduce((a, b) => a + b, 0)
     },
+    /**
+     * 计算星闪豹当前门店分类购物车商品总数量cartDeleteGoods
+     */
+    getShopTotalNum(): number {
+      const shopId = uni.getStorageSync('system-xsb').SelectShopInfo?.shopId
+      return this.cartList.find(it => it.shopId === shopId)?.skuList.map(its => its.num).reduce((a, b) => a + b, 0) || 0
+    },
   },
   actions: {
     /**
@@ -156,12 +163,17 @@ export const useSmqjhCartStore = defineStore('smqjh-cart', {
      * 购物车删除商品逻辑
      */
     cartDeleteGoods() {
+      const delGoods = this.cartList.filter(it => it.allGoods?.length > 0)
+      if (!delGoods.length) {
+        useGlobalToast().show({ msg: '请选择要删除的商品' })
+        return
+      }
       useGlobalMessage().confirm({
         title: '删除商品',
         msg: '是否删除选中的商品?',
-        success: async () => {
-          const delGoods = this.cartList.filter(it => it.allGoods?.length > 0)
-          if (delGoods.length) {
+        zIndex: 99999999999999,
+        success: async ({ action }) => {
+          if (action === 'confirm') {
             await Apis.common.deleteShoppingCart({
               pathParams: {
                 ids: delGoods.map(it => it.allGoods).join(','),
@@ -170,9 +182,6 @@ export const useSmqjhCartStore = defineStore('smqjh-cart', {
             this.getCartList('XSB')
             useGlobalToast().show({ msg: '删除成功!' })
           }
-          else {
-            useGlobalToast().show({ msg: '请选择要删除的商品' })
-          }
         },
       })
     },
@@ -242,6 +251,8 @@ export const useSmqjhCartStore = defineStore('smqjh-cart', {
       if (ids.length) {
         const shopIds = ids.map(it => it.allGoods).flat()
         const id = shopIds.join(',')
+        console.log(this.cartList, '==========================')
+
         const res = await this.getCartAddGoodsPrice(id)
         this.totalProduct = res
       }

+ 1 - 1
src/store/user.ts

@@ -185,7 +185,7 @@ export const useUserStore = defineStore('user', {
             shopId,
             orderItemList,
             remarks,
-            allowanceIds: [allowanceId],
+            allowanceIds: allowanceId ? [allowanceId] : [],
           },
         }).then((res) => {
           resolve(res.data)

+ 10 - 4
src/subPack-common/afterSalesDetail/index.vue

@@ -34,6 +34,12 @@ function copyToClipboard(text: string) {
     showToast: true,
   })
 }
+function handleGOCoupon() {
+  if (!refundOrderInfo.value?.couponBaseInfoDTO) {
+    return useGlobalToast().show('优惠券不存在')
+  }
+  router.push({ name: 'xsb-coupon', params: { couponId: refundOrderInfo.value?.couponBaseInfoDTO?.allowanceId, activeTab: refundOrderInfo.value?.isAll ? '0' : '1' } })
+}
 </script>
 
 <template>
@@ -135,7 +141,7 @@ function copyToClipboard(text: string) {
             退款金额
           </view>
           <view class="text-#FF4D3A font-semibold">
-            ¥{{ refundOrderInfo.refundAmount }}
+            ¥{{ refundOrderInfo.userRefundMoney }}
           </view>
         </view>
         <view class="ml20rpx flex items-center">
@@ -143,7 +149,7 @@ function copyToClipboard(text: string) {
             退还积分:
           </view>
           <view class="text-#FF4D3A font-semibold">
-            ¥{{ refundOrderInfo.omsOrderVo.offsetPoints }}
+            {{ refundOrderInfo.refundScore }}
           </view>
         </view>
         <view class="flex items-center">
@@ -192,8 +198,8 @@ function copyToClipboard(text: string) {
           </view>
         </template>
       </view>
-      <wd-button v-if="refundStatus.ReturnCompleted == refundOrderInfo.returnMoneySts" @click="router.push({ name: 'xsb-coupon', params: { couponId: refundOrderInfo.couponBaseInfoDTO.allowanceId, activeTab: refundOrderInfo.isAll ? '2' : '1' } })">
-        查看优惠
+      <wd-button v-if="refundStatus.ReturnCompleted == refundOrderInfo.returnMoneySts" @click="handleGOCoupon">
+        查看优惠
       </wd-button>
     </view>
     <view class="mt20rpx rounded-16rpx bg-white p24rpx">

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

@@ -35,11 +35,20 @@ onMounted(async () => {
     <view class="xsb-linear h406rpx" />
     <view class="-mt220rpx">
       <view class="content px24rpx">
+        <view v-if="cartList.length" class="mb20rpx flex items-center justify-end">
+          <view class="text-24rpx text-[#AAAAAA]" @click="cartStore.cartDeleteGoods">
+            <wd-icon name="delete" size="24rpx" /> 清空购物车
+          </view>
+        </view>
         <scroll-view scroll-y class="content">
           <view v-for="shop in cartList" :key="shop.shopId" class="mb24rpx rounded-16rpx bg-white px24rpx pb18rpx pt28rpx">
             <wd-checkbox v-model="shop.AllShopGoods" size="large" @change="cartStore.cartStoreAllChecked($event, shop)">
               <view class="text-28rpx font-semibold">
-                {{ shop.shopName }}
+                {{ shop.shopName }} <text class="text-24rpx text-#AAAAAA">
+                  已选 {{ shop.allGoods.length }} 件<text v-if="shop.allGoods.length">
+                    ,总重量约为 {{ totalProduct?.totalWeight || 0 }} kg
+                  </text>
+                </text>
               </view>
             </wd-checkbox>
             <view class="mt20rpx h2rpx w-full bg-#F0F0F0" />

+ 8 - 7
src/subPack-xsb/commonTab/components/classfiy.vue

@@ -8,7 +8,7 @@ const props = defineProps<{ categoryList: Api.xsbCategories[], hotText: Api.xsbS
 const { statusBarHeight, MenuButtonHeight } = storeToRefs(useSysStore())
 const { topNavActive, leftActive, SelectShopInfo } = storeToRefs(useSysXsbStore())
 const { userInfo, token } = storeToRefs(useUserStore())
-const { getTotalNum } = storeToRefs(useSmqjhCartStore())
+const { getShopTotalNum } = storeToRefs(useSmqjhCartStore())
 const classfiylist = computed(() => props.categoryList)
 const sortClassBtn = ref(1)
 const show = ref(false)
@@ -245,6 +245,7 @@ onMounted(async () => {
       leftActive.value = firstWithChildren.children![0].code
     }
   }
+
   goodsLoading.value = 'loading'
   if (leftActive.value) {
     handleChange({ value: leftActive.value })
@@ -383,7 +384,7 @@ function handlePay() {
   router.push({ name: 'xsb-confirmOrder', params: { data: JSON.stringify(totalProduct.value) } })
 }
 function handleOpen() {
-  if (!getTotalNum.value)
+  if (!getShopTotalNum.value)
     return
   cartPopup.value = true
   priceDetailPopup.value = false
@@ -651,12 +652,12 @@ export default {
       <view class="ios w-full flex items-center justify-between">
         <view class="flex items-center">
           <view class="flex items-center" @click="handleOpen">
-            <wd-badge :model-value="getTotalNum" :top="20">
-              <image v-if="getTotalNum" :src="`${StaticUrl}/cart-lanzi.png`" class="cart-box h100rpx w100rpx" />
+            <wd-badge :model-value="getShopTotalNum" :top="20">
+              <image v-if="getShopTotalNum" :src="`${StaticUrl}/cart-lanzi.png`" class="cart-box h100rpx w100rpx" />
               <image v-else :src="`${StaticUrl}/xsb-cart-disabled.png`" class="cart-box h100rpx w100rpx" />
             </wd-badge>
           </view>
-          <view v-if="getTotalNum" class="ml40rpx">
+          <view v-if="getShopTotalNum" class="ml40rpx">
             <view class="flex items-center">
               <view class="font-semibold">
                 ¥ {{ totalProduct?.amount || 0 }}
@@ -694,7 +695,7 @@ export default {
             </view>
           </view> -->
           <view class="ml20rpx w160rpx">
-            <wd-button block size="large" :disabled="!getTotalNum" :type="getTotalNum ? 'primary' : 'info'" @click="handlePay">
+            <wd-button block size="large" :disabled="!getShopTotalNum" :type="getShopTotalNum ? 'primary' : 'info'" @click="handlePay">
               结算
             </wd-button>
           </view>
@@ -766,7 +767,7 @@ export default {
               全选
             </wd-checkbox>
             <text class="ml-16rpx text-24rpx text-[#AAAAAA]">
-              已选{{ selectedCount }}件
+              已选{{ selectedCount }}件,总重量约为{{ totalProduct?.totalWeight || 0 }}kg
             </text>
           </view>
           <view class="text-24rpx text-[#AAAAAA]" @click="handleClearCart">

+ 7 - 0
src/subPack-xsb/commonTab/index.vue

@@ -30,6 +30,7 @@ const {
   SelectShopInfo,
   allShopHasPermission,
   xsbShopList,
+  isClassfiyPageOpen,
 } = storeToRefs(sysXsbStore)
 const { userInfo } = storeToRefs(useUserStore())
 const commonCategoryData = ref<Api.xsbCategories[]>([])
@@ -57,6 +58,12 @@ function handleTabbarChange({ value }: { value: string }) {
   setTabbarItemActive(value)
   tabbarName.value = value
 }
+watch(() => isClassfiyPageOpen.value, () => {
+  if (isClassfiyPageOpen.value) {
+    handleChange('xsb-classfiy')
+    isClassfiyPageOpen.value = false
+  }
+})
 function setTabbarItemActive(name: string) {
   tabbarItems.value.forEach((item) => {
     if (item.name === name) {

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

@@ -10,8 +10,13 @@ defineProps<{
   /** 隐藏所有操作按鈕(选券模式用) */
   hideAllBtn?: boolean
 }>()
+const {
+  isClassfiyPageOpen,
+} = storeToRefs(useSysXsbStore())
 function handleUseCoupon() {
-  router.replace({ name: 'xsb-homeTabbar', params: { name: 'xsb-classfiy' } })
+  isClassfiyPageOpen.value = true
+  // router.replace({ name: 'xsb-homeTabbar', params: { name: 'xsb-classfiy' } })
+  router.back()
 }
 </script>
 
@@ -42,14 +47,14 @@ function handleUseCoupon() {
             {{ Number(itemcoupon.amountMoney) > 0 ? `满${itemcoupon.amountMoney}可用` : '无门槛' }}
           </view>
         </view>
-        <view class="flex flex-1 items-center px-24rpx py-28rpx">
+        <view class="flex flex-1 items-center py-28rpx pr-24rpx">
           <view class="flex-1 pr-20rpx">
             <view class="text-28rpx text-[#333] font-semibold">
               {{ itemcoupon.activityName || itemcoupon.couponName || '优惠券' }}
             </view>
             <template v-if="[2, 5].includes(itemcoupon.useStatus || 2)">
               <view v-if="itemcoupon.expirationTime" class="mt-12rpx text-22rpx text-[#AAAAAA]">
-                有效期:{{ dayjs(itemcoupon.expirationTime).format('YYYY-MM-DD') }}
+                有效期:{{ dayjs(itemcoupon.expirationTime).format('YYYY-MM-DD HH:mm:ss') }}
               </view>
               <view v-if="itemcoupon.scopeDesc" class="mt-8rpx text-22rpx text-[#AAAAAA]">
                 限:{{ itemcoupon.scopeDesc }}
@@ -58,8 +63,11 @@ function handleUseCoupon() {
             <view v-if="itemcoupon.orderCreateTime" class="mt-8rpx text-22rpx text-[#AAAAAA]">
               使用时间: {{ itemcoupon.orderCreateTime }}
             </view>
+            <view v-if="itemcoupon.lockOrderId" class="mt-8rpx flex items-center text-22rpx text-[#AAAAAA]">
+              订单号:{{ itemcoupon.lockOrderId }}
+            </view>
             <view v-if="itemcoupon.useStatus === 1" class="mt-8rpx text-22rpx text-[#AAAAAA]">
-              说明:部分退款,优惠卷不退还
+              说明:部分退款,优惠不退还
             </view>
             <view v-if="itemcoupon.useStatus === 7" class="mt-8rpx text-22rpx text-[#AAAAAA]">
               冻结原因:该券已被占用,取消可恢复,有效期内可用。

+ 1 - 1
src/subPack-xsb/confirmOrder/index.vue

@@ -313,7 +313,7 @@ async function handlePay() {
               {{ getCouponDisplayName(draftCoupon) }},可减-¥{{ draftCoupon.discountMoney }}
             </view>
             <view v-else-if="currentCouponDiscount > 0 && currentCouponName" class="text-right text-[#FF4D3A]">
-              {{ currentCouponName }},可减-¥{{ currentCouponDiscount }}
+              {{ currentCouponName }},可减¥{{ currentCouponDiscount }}
             </view>
             <view v-else class="text-[#AAAAAA]">
               暂未选择

+ 2 - 2
src/subPack-xsb/orderDetaile/index.vue

@@ -473,10 +473,10 @@ function handleRefundDetail(item: any) {
             优惠券
           </view>
           <view class="text-[#FF4A39] font-semibold">
-            -¥{{ Number(orderInfo?.couponBaseInfoDTO?.discountMoney) }}
+            -¥{{ Number(orderInfo?.couponBaseInfoDTO?.discountMoney) || 0 }}
           </view>
         </view>
-        <view v-if="orderInfo.refundOrderList" class="mt10rpx rounded-16rpx bg-#ccc p24rpx text-24rpx">
+        <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>

+ 5 - 1
src/subPack-xsb/store-xsb/sys.ts

@@ -37,7 +37,10 @@ interface SysState {
    * 优惠券到账弹窗是否显示
    */
   couponArrivalPopupVisible: boolean
-
+  /**
+   * 是否打开分类页面
+   */
+  isClassfiyPageOpen: boolean
 }
 export const useSysXsbStore = defineStore('system-xsb', {
   state: (): SysState => ({
@@ -51,6 +54,7 @@ export const useSysXsbStore = defineStore('system-xsb', {
     selectAddressId: undefined,
     allShopHasPermission: false,
     couponArrivalPopupVisible: false,
+    isClassfiyPageOpen: false,
   }),
   actions: {
     getTabbarItemValue(name: string) {