lifanagju_citu 6 mesiacov pred
rodič
commit
e30e013f7e

+ 1 - 3
pages/goods/index.vue

@@ -372,9 +372,7 @@
     });
 
     // 选择有 promotionPrice 且最小的
-    state.settlementSku = state?.goodsInfo?.skus
-      .filter((sku) => sku?.stock > 0 && sku?.promotionPrice > 0)
-      .reduce((prev, curr) => (prev?.promotionPrice < curr.promotionPrice ? prev : curr), []) || [];
+    state.settlementSku = state?.goodsInfo?.skus?.filter((sku) => sku?.stock > 0 && sku?.promotionPrice > 0)?.reduce((prev, curr) => (prev?.promotionPrice < curr.promotionPrice ? prev : curr), []) || [];
     
     // 设置满减送活动
     if (data.rewardActivity) {

+ 0 - 1
pages/order/confirm.vue

@@ -329,7 +329,6 @@
       }
     }
     console.log(state.orderPayload, 'submit-order-pay', state);
-    // if (spuType.value !== '0' && !state.orderPayload.email) state.orderPayload.email = '123@qq.com' // 测试
     if (spuType.value !== '0' && !state.orderPayload.email) {
       uni.showToast({ title: '请填写接收邮箱!', icon: 'none', duration: 2000 })
       return

+ 265 - 0
pages/pay/addressSelection.vue

@@ -0,0 +1,265 @@
+<!-- 下单界面,收货地址 or 自提门店的选择组件 -->
+<template>
+  <view class="allAddress">
+    <view
+      class="address flex flex-wrap flex-center ss-row-between"
+      @tap="onSelectAddress"
+      v-if="state.deliveryType === 1"
+    >
+      <view class="addressCon" v-if="state.addressInfo.name">
+        <view class="name"
+          >{{ state.addressInfo.name }}
+          <text class="phone">{{ state.addressInfo.mobile }}</text>
+        </view>
+        <view>
+          <text class="default font-color" v-if="state.addressInfo.defaultStatus">[默认]</text>
+          <text class="line2">
+            {{ state.addressInfo.areaName }} {{ state.addressInfo.detailAddress }}
+          </text>
+        </view>
+      </view>
+      <view class="addressCon" v-else>
+        <view class="setaddress">设置收货地址</view>
+      </view>
+      <view class="iconfont">
+        <view class="ss-rest-button">
+          <text class="_icon-forward" />
+        </view>
+      </view>
+    </view>
+    <!-- 情况二:门店的选择 -->
+    <view
+      class="address flex flex-wrap flex-center ss-row-between"
+      v-if="state.deliveryType === 2"
+      @tap="onSelectAddress"
+    >
+      <view class="addressCon" v-if="state.pickUpInfo.name">
+        <view class="name"
+          >{{ state.pickUpInfo.name }}
+          <text class="phone">{{ state.pickUpInfo.phone }}</text>
+        </view>
+        <view class="line1">
+          {{ state.pickUpInfo.areaName }}{{ ', ' + state.pickUpInfo.detailAddress }}
+        </view>
+      </view>
+      <view class="addressCon" v-else>
+        <view class="setaddress">选择自提门店</view>
+      </view>
+      <view class="iconfont">
+        <view class="ss-rest-button">
+          <text class="_icon-forward" />
+        </view>
+      </view>
+    </view>
+    <!-- <view class="line">
+      <image :src="sheep.$url.static('/static/images/line.png', 'local')" />
+    </view> -->
+  </view>
+</template>
+
+<script setup>
+  import { computed } from 'vue';
+  import sheep from '@/sheep';
+  import { isEmpty } from 'lodash-es';
+
+  const props = defineProps({
+    modelValue: {
+      type: Object,
+      default() {},
+    },
+  });
+  const emits = defineEmits(['update:modelValue']);
+
+  // computed 解决父子组件双向数据同步
+  const state = computed({
+    get() {
+      return new Proxy(props.modelValue, {
+        set(obj, name, val) {
+          emits('update:modelValue', {
+            ...obj,
+            [name]: val,
+          });
+          return true;
+        },
+      });
+    },
+    set(val) {
+      emits('update:modelValue', val);
+    },
+  });
+
+  // 选择地址
+  function onSelectAddress() {
+    let emitName = 'SELECT_ADDRESS';
+    let addressPage = '/pages/user/address/list?type=select';
+    if (state.value.deliveryType === 2) {
+      emitName = 'SELECT_PICK_UP_INFO';
+      addressPage = '/pages/user/goods_details_store/index';
+    }
+    uni.$once(emitName, (e) => {
+      changeConsignee(e.addressInfo);
+    });
+    sheep.$router.go(addressPage);
+  }
+
+  // 更改收货人地址&计算订单信息
+  async function changeConsignee(addressInfo = {}) {
+    if (!isEmpty(addressInfo)) {
+      if (state.value.deliveryType === 1) {
+        state.value.addressInfo = addressInfo;
+      }
+      if (state.value.deliveryType === 2) {
+        state.value.pickUpInfo = addressInfo;
+      }
+    }
+  }
+
+  // 收货方式切换
+  const switchDeliveryType = (type) => {
+    state.value.deliveryType = type;
+  };
+</script>
+
+<style scoped lang="scss">
+.allAddress .font-color {
+  color: #e93323 !important;
+}
+.line2 {
+  width: 458rpx;
+}
+.textR {
+  text-align: right;
+}
+
+.line {
+  width: 100%;
+  height: 3rpx;
+}
+
+.line image {
+  width: 100%;
+  height: 100%;
+  display: block;
+}
+
+.address {
+  padding: 28rpx;
+  background-color: #fff;
+  box-sizing: border-box;
+}
+
+.address .addressCon {
+  // width: 596rpx;
+  font-size: 26rpx;
+  color: #666;
+  flex: 1;
+}
+
+.address .addressCon .name {
+  font-size: 30rpx;
+  color: #282828;
+  font-weight: bold;
+  margin-bottom: 10rpx;
+}
+
+.address .addressCon .name .phone {
+  margin-left: 50rpx;
+}
+
+.address .addressCon .default {
+  margin-right: 12rpx;
+}
+
+.address .addressCon .setaddress {
+  color: #333;
+  font-size: 28rpx;
+}
+
+.address .iconfont {
+  font-size: 35rpx;
+  color: #707070;
+}
+
+.allAddress {
+  width: 100%;
+  background: #00B760;
+  // padding-bottom: 10rpx;
+  // padding-top: 50rpx;
+}
+
+.allAddress .nav {
+  width: 690rpx;
+  margin: 0 auto;
+}
+
+.allAddress .nav .item {
+  width: 334rpx;
+}
+
+.allAddress .nav .item.on {
+  position: relative;
+  width: 230rpx;
+}
+
+.allAddress .nav .item.on::before {
+  position: absolute;
+  bottom: 0;
+  content: '快递配送';
+  font-size: 28rpx;
+  display: block;
+  height: 0;
+  width: 336rpx;
+  border-width: 0 20rpx 80rpx 0;
+  border-style: none solid solid;
+  border-color: transparent transparent #fff;
+  z-index: 2;
+  border-radius: 14rpx 36rpx 0 0;
+  text-align: center;
+  line-height: 80rpx;
+}
+
+.allAddress .nav .item:nth-of-type(2).on::before {
+  content: '到店自提';
+  border-width: 0 0 80rpx 20rpx;
+  border-radius: 36rpx 14rpx 0 0;
+}
+
+.allAddress .nav .item.on2 {
+  position: relative;
+}
+
+.allAddress .nav .item.on2::before {
+  position: absolute;
+  bottom: 0;
+  content: '到店自提';
+  font-size: 28rpx;
+  display: block;
+  height: 0;
+  width: 401rpx;
+  border-width: 0 0 60rpx 60rpx;
+  border-style: none solid solid;
+  border-color: transparent transparent #f7c1bd;
+  border-radius: 36rpx 14rpx 0 0;
+  text-align: center;
+  line-height: 60rpx;
+}
+
+.allAddress .nav .item:nth-of-type(1).on2::before {
+  content: '快递配送';
+  border-width: 0 60rpx 60rpx 0;
+  border-radius: 14rpx 36rpx 0 0;
+}
+
+.allAddress .address {
+  // width: 690rpx;
+  width: calc(100% - 16rpx);
+  max-height: 180rpx;
+  margin: 0 auto;
+  margin-bottom: 15rpx;
+}
+
+.allAddress .line {
+  width: 100%;
+  margin: 0 auto;
+}
+</style>

+ 0 - 50
pages/pay/prizePage.vue

@@ -1,50 +0,0 @@
-<!--  -->
-<template>
-  <view class="box">
-    <p v-for="(k, i) in prizeData" :key="i" class="color-primary ss-m-t-20">
-      {{ k.prize.prompt }}
-    </p>
-    <view class="tip ss-m-t-10">凭此房券在规定有效期内可享受免费住宿一晚。</view>
-    <view class="tip ss-m-t-2">请提供收货地址,以便安排房券派送。</view>
-    <view class="color-999 ss-m-t-15">(注:10天内未领取的,则视为主动放弃当前奖品)</view>
-    <!-- 收货地址 -->
-    <AddressSelection v-model="addressState" class="addressBox" />
-  </view>
-</template>
-<script setup>
-import AddressSelection from '@/pages/order/addressSelection.vue'
-const props = defineProps({
-  prizeData: {
-    type: Array,
-    default: () => []
-  }
-})
-
-const addressState = ref({
-  addressInfo: {}, // 选择的收货地址
-  deliveryType: undefined, // 收货方式:1-快递配送,2-门店自提
-  isPickUp: true, // 门店自提是否开启
-  pickUpInfo: {}, // 选择的自提门店信息
-  receiverName: '', // 收件人名称
-  receiverMobile: '', // 收件人手机
-});
-</script>
-<style lang="scss" scoped>
-.color-primary {
-  color: #00B760;
-  font-size: 40rpx;
-}
-.color-999 {
-  color: #999;
-  font-size: 26rpx;
-}
-.box {
-  .tip {
-    font-size: 28rpx;
-    font-weight: bold;
-  }
-  .addressBox {
-    margin-bottom: 20px;
-  }
-}
-</style>

+ 134 - 14
pages/pay/result.vue

@@ -68,7 +68,30 @@
         @end="lotteryEnd"
       ></SlotMachine>
       <!-- 抽奖结果 -->
-      <prizePage v-if="showLotteryResult" :prizeData="prizeData"></prizePage>
+      <view v-if="showLotteryResult">
+        <view class="line">
+          <image class="ss-m-t-30" :src="sheep.$url.static('/static/images/line.png', 'local')" />
+        </view>
+        <uni-card class="lotteryResult ss-m-t-30">
+          <view>
+            <p v-for="(k, i) in prizeData" :key="i" class="color-primary ss-m-t-20">{{ k.prize.prompt }}</p>
+          </view>
+          <view class="tip ss-m-t-10">凭此房券在规定有效期内可享受免费住宿一晚。</view>
+          <view class="tip ss-m-t-2">请提供收货地址,以便安排房券派送。</view>
+          <!-- 收货地址 -->
+          <view class="addressBox">
+            <AddressSelection v-model="addressState"></AddressSelection>
+          </view>
+          <!-- button -->
+          <view class="footer-box ss-flex-col ss-row-between">
+            <view class="ss-m-b-20 ss-flex ss-row-center">
+              <!-- <button class="ss-reset-button tool-btn" @tap.stop="null">放弃</button> -->
+              <button class="ss-reset-button save-btn" @tap.stop="handleReceive">立即领取</button>
+            </view>
+          </view>
+          <view class="color-999 ss-m-15 text-center">(10天内未领取的,则视为主动放弃当前奖品)</view>
+        </uni-card>
+      </view>
     </view>
   </s-layout>
 </template>
@@ -84,7 +107,9 @@
   import { WxaSubscribeTemplate } from '@/sheep/util/const';
   import SlotMachine from '@/pages/lucky/SlotMachine'
   import PrizeApi from '@/sheep/api/prizeDraw'
-  import prizePage from './prizePage'
+  import AddressApi from '@/sheep/api/member/address'
+  import AddressSelection from './addressSelection.vue';
+  // import prizePage from './prizePage'
 
   const state = reactive({
     id: 0, // 支付单号
@@ -129,15 +154,15 @@
         // 非待支付,可能是已支付,可能是已退款
         state.result = 'paid';
         // #ifdef MP
-        uni.showModal({
-          title: '支付结果',
-          showCancel: false, // 不要取消按钮
-          content: '支付成功',
-          success: () => {
-            // 订阅只能由用户主动触发,只能包一层 showModal 诱导用户点击
-            autoSubscribeMessage();
-          },
-        });
+        // uni.showModal({
+        //   title: '支付结果',
+        //   showCancel: false, // 不要取消按钮
+        //   content: '支付成功',
+        //   success: () => {
+        //     // 订阅只能由用户主动触发,只能包一层 showModal 诱导用户点击
+        //     autoSubscribeMessage();
+        //   },
+        // });
 
         // #endif
         // 特殊:获得商品订单信息
@@ -258,9 +283,50 @@
     const res = await PrizeApi.getLuckLotteryRecordByOrderId(orderId)
     // console.log('prizeData:', res)
     prizeData.value = res?.data || []
-    // 测试
-    // showPrizeDraw.value = false
-    // showLotteryResult.value = true
+  }
+  
+  const addressState = ref({
+    addressInfo: {}, // 选择的收货地址
+    deliveryType: 1, // 收货方式:1-快递配送,2-门店自提
+    isPickUp: false, // 门店自提是否开启
+    pickUpInfo: {}, // 选择的自提门店信息
+    receiverName: '', // 门店自提收件人名称
+    receiverMobile: '', // 门店自提收件人手机
+  });
+
+  // 获取收货地址
+  const getAddressList = async () => {
+    const list = (await AddressApi.getAddressList()).data;
+    if (list?.length) {
+      const item = list.find(e => e.defaultStatus)
+      if (item) addressState.value.addressInfo = item
+      else addressState.value.addressInfo = list[0]
+    }
+  }
+  getAddressList()
+
+  // 领取
+  const handleReceive = async () => {
+    if (!addressState.value?.addressInfo && !Object.keys(addressState.value.addressInfo).length) {
+      uni.showToast({
+        title: '请选择收货地址',
+        icon: 'none',
+        duration: 2000
+      })
+      return
+    }
+    const { code } = await PrizeApi.luckyLotteryRecordReceive({ id: prizeData.value[0].record?.id, receiveInfo: JSON.stringify(addressState.value.addressInfo) })
+    if (code === 0) {
+      setTimeout(() => {
+        uni.showToast({
+          title: '领取成功',
+          icon: 'none',
+          duration: 2000
+        })
+      }, 500)
+      // sheep.$router.back();
+    }
+    sheep.$router.redirect('/pages/user/prize/index');
   }
 
   onShow(() => {
@@ -377,4 +443,58 @@
     border-top: 1px solid #b6b5c5;
     padding: 50rpx 0;
   }
+  .lotteryResult {
+    width: 100vw;
+    .color-primary {
+      color: #00B760;
+      font-size: 40rpx;
+    }
+    .color-999 {
+      color: #999;
+      font-size: 26rpx;
+    }
+    .tip {
+      font-size: 28rpx;
+      font-weight: bold;
+    }
+    .addressBox {
+      width: 100%;
+      margin: 20px 0;
+    }
+    .refresh-btn {
+      width: 200rpx;
+      height: 80rpx;
+      border-radius: 40rpx;
+    }
+    .footer-box {
+      margin-top: 30rpx;
+      .tool-btn {
+        width: calc(48vw - 40rpx);
+        height: 80rpx;
+        border-radius: 40rpx;
+        background: #f6f6f6;
+        color: #666;
+        font-size: 26rpx;
+        margin: 0 20rpx;
+      }
+      .save-btn {
+        width: calc(48vw - 40rpx);
+        height: 80rpx;
+        border-radius: 40rpx;
+        background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
+        color: $white;
+        margin: 0 20rpx;
+      }
+    }
+  }
+  .line {
+    width: 100%;
+    height: 3rpx;
+    margin: 0 auto;
+    image {
+      width: 100%;
+      height: 100%;
+      display: block;
+    }
+  }
 </style>