lifanagju_citu пре 6 месеци
родитељ
комит
e41f4700e3

+ 2 - 0
pages/activity/index.vue

@@ -125,12 +125,14 @@
       return;
     }
     // 拼接结算信息(营销)
+  if (sheep.$store('user').isLogin) { // 需要登录
     await OrderApi.getSettlementProduct(data.list.map((item) => item.id).join(',')).then((res) => {
       if (res.code !== 0) {
         return;
       }
       appendSettlementProduct(data.list, res.data);
     });
+  }
     state.pagination.list = _.concat(state.pagination.list, data.list);
     state.pagination.total = data.total;
     state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';

+ 9 - 6
pages/goods/index.vue

@@ -297,6 +297,9 @@
             categoryId: state.goodsInfo.categoryId,
           },
         ],
+        city: e.city,
+        goodsType: state.goodsInfo?.type || 0,
+        spuId: state.goodsInfo?.id
       }),
     });
   }
@@ -357,7 +360,7 @@
     data = data[0];
 
     // 补充 SKU 的价格信息
-    state.goodsInfo.skus.forEach((sku) => {
+    state?.goodsInfo?.skus?.forEach((sku) => {
       data.skus.forEach((item) => {
         if (sku.id === item.id) {
           sku.promotionType = item.promotionType;
@@ -369,10 +372,10 @@
     });
 
     // 选择有 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) {
       state.rewardActivity = data.rewardActivity;
@@ -430,7 +433,7 @@
       state.activityList = res.data;
     });
     //获取结算信息
-    getSettlementByIds(state.goodsId);
+    if (sheep.$store('user').isLogin) getSettlementByIds(state.goodsId);  // 需要登录
   });
 </script>
 

+ 2 - 0
pages/goods/list.vue

@@ -280,12 +280,14 @@
       return;
     }
     // 拼接结算信息(营销)
+  if (sheep.$store('user').isLogin) { // 需要登录
     await OrderApi.getSettlementProduct(data.list.map((item) => item.id).join(',')).then((res) => {
       if (res.code !== 0) {
         return;
       }
       appendSettlementProduct(data.list, res.data);
     });
+  }
     state.pagination.list = _.concat(state.pagination.list, data.list);
     state.pagination.total = data.total;
     state.loadStatus = state.pagination.list.length < state.pagination.total ? 'more' : 'noMore';

+ 2 - 20
pages/lucky/Grid.vue

@@ -13,14 +13,13 @@
       @start="startCallback"
       @end="endCallback"
     />
-    <view class="numberBox mt-5">您还剩余<span class="colorBase">{{ number }}</span>次抽奖机会</view>
+    <!-- <view class="numberBox mt-5">您还剩余<span class="colorBase">{{ number }}</span>次抽奖机会</view> -->
   </view>
 </template>
 
 <script setup>
 import LuckyGrid from '@lucky-canvas/uni/lucky-grid'
 import { ref } from 'vue'
-import sheep from '@/sheep';
 
 const myLucky = ref()
 const blocks = [
@@ -61,11 +60,6 @@ const defaultConfig = {
 }
 
 const startCallback = () => {
-  // if (!number.value) return Snackbar.warning('抽奖次数已用完!')
-  if (!number.value) {
-    sheep.$helper.toast('抽奖次数已用完')
-    return
-  }
   // 调用抽奖组件的play方法开始游戏
   myLucky.value.play()
   // 模拟调用接口异步抽奖
@@ -78,20 +72,8 @@ const startCallback = () => {
 }
 
 const endCallback  = (prize) => {
-  console.log(prize, 'end')
-  getData()
+  // getData()
 }
-
-
-// 获取抽奖次数
-const number = ref(3)
-const getData = async () => {
-  number.value--
-  // const data = await getProductDetail()
-  // number.value = data || 0
-}
-getData()
-
 </script>
 
 <style scoped lang="scss">

+ 27 - 15
pages/lucky/slotMachine.vue

@@ -1,25 +1,25 @@
 <!-- 老虎机 -->
 <template>
-  <view class="mb-n5" v-if="prizes?.length">
+  <view class="box" v-if="prizes?.length">
     <SlotMachine
       ref="myLucky"
       width="300px"
-      height="300px"
+      :height="props.height + 'px'"
       :prizes="prizes"
       :blocks="blocks"
       :slots="slots"
       accelerationTime="1000"
       decelerationTime="10000"
       :default-config="defaultConfig"
-      :disabled="true"
       class="prizeDraw"
       @start="startCallback"
       @end="endCallback"
     />
+    
     <image
+      v-if="!disabled"
       src="https://img1.baidu.com/it/u=3949019928,2138080900&fm=253&fmt=auto&app=138&f=PNG?w=300&h=300"
-      :width="100"
-      style="margin: 0 auto;"
+      style="margin: 0 auto; width: 180rpx; height: 180rpx;"
       @click="startCallback"
     />
   </view>
@@ -28,14 +28,23 @@
 <script setup>
 import PrizeApi from '@/sheep/api/prizeDraw'
 import SlotMachine from '@lucky-canvas/uni/slot-machine'
+// import { onLoad } from '@dcloudio/uni-app'
 import { ref } from 'vue'
 const emit = defineEmits(['start', 'end'])
-const props = defineProps({ lotteryId: [Number, String], disabled: [Number, Boolean] })
+const props = defineProps({
+  height: {
+    type: String,
+    default: '300px'
+  },
+  disabled: Boolean,
+  lotteryId: String,
+  orderId: String,
+})
 
 const myLucky = ref()
 // 背景样式
 const blocks = [
-  { padding: '10px', background: '#00897B', borderRadius: 6 },
+  { padding: '10px', background: '#00B760', borderRadius: 6 },
 ]
 // 转速与方向
 const slots = [
@@ -50,13 +59,11 @@ const defaultConfig = {
   accelerationTime: 1000, // 开始旋转时间
   decelerationTime: 5000, // 缓慢停止时间
 }
-debugger
 // 根据活动id获取奖品列表
-const getPrizeData = async (lotteryId) => {
-  let id = lotteryId || props.lotteryId
-  const data = await PrizeApi.getPrizeByLotteryId(id)
+const getPrizeData = async () => {
+  const res = await PrizeApi.getPrizeByLotteryId(props.lotteryId)
   prizes.value = []
-  debugger
+  const data = res?.data || []
   data.forEach(item => {
     prizes.value.push({
       prize: item,
@@ -70,16 +77,16 @@ const getPrizeData = async (lotteryId) => {
     })
   })
 }
-if (props.lotteryId) getPrizeData()
+getPrizeData()
 
 const startCallback = () => {
-  if (props.disabled) return sheep.$helper.toast('抽奖次数已用完')
+  // if (props.disabled) return sheep.$helper.toast('抽奖次数已用完')
   emit('start')
   // 调用抽奖组件的play方法开始游戏
   myLucky.value.play()
   // 模拟调用接口异步抽奖
   setTimeout(() => {
-    // 假设后端返回的中奖索引是0
+    // 中奖索引
     const index = 3
     // 调用stop停止旋转并传递中奖索引
     myLucky.value.stop(index)
@@ -92,4 +99,9 @@ const endCallback  = (value) => {
 
 </script>
 <style lang="scss" scoped>
+.box {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+}
 </style>

+ 44 - 3
pages/order/confirm.vue

@@ -1,7 +1,7 @@
 <template>
   <s-layout title="确认订单">
     <!-- 头部地址选择【配送地址】【自提地址】 -->
-    <AddressSelection v-model="addressState" />
+    <AddressSelection v-if="spuType === '0'" v-model="addressState" />
 
     <!-- 商品信息 -->
     <view class="order-card-box ss-m-b-14">
@@ -27,7 +27,7 @@
           />
         </view>
       </view>
-	  <view v-if="state.orderInfo?.items.every(k => k.spuType !== '0')" class="order-item ss-flex ss-col-center ss-row-between ss-p-x-20 bg-white ss-r-10">
+	  <view v-if="spuType !== '0'" class="order-item ss-flex ss-col-center ss-row-between ss-p-x-20 bg-white ss-r-10">
 	    <view class="item-title">接收邮箱</view>
 	    <view class="ss-flex ss-col-center">
 	      <uni-easyinput
@@ -36,9 +36,11 @@
 	        v-model="state.orderPayload.email"
 	        :inputBorder="false"
 	        :clearable="false"
+          @blur="emailChange"
 	      />
 	    </view>
 	  </view>
+    <view v-if="spuType !== '0' && emailErrorMessage " class="emailErrorMessage ss-p-b-20 ss-p-r-20">邮箱格式不正确</view>
     </view>
 
     <!-- 价格信息 -->
@@ -238,8 +240,10 @@
   import AddressSelection from '@/pages/order/addressSelection.vue';
   import sheep from '@/sheep';
   import OrderApi from '@/sheep/api/trade/order';
+  import PrizeApi from '@/sheep/api/prizeDraw';
   import TradeConfigApi from '@/sheep/api/trade/config';
   import { fen2yuan } from '@/sheep/hooks/useGoods';
+  import test from '@/sheep/helper/test.js';
 
   const state = reactive({
     orderPayload: {},
@@ -272,6 +276,13 @@
     await getOrderInfo();
   };
 
+  const emailErrorMessage = ref(false)
+  const emailChange = (e) => {
+    const email = e?.detail?.value
+    emailErrorMessage.value = Boolean(!email || !test.email(email))
+    if (emailErrorMessage.value) sheep.$helper.toast('邮箱格式不正确')
+  };
+
   // 选择优惠券
   async function onSelectCoupon(couponId) {
     state.orderPayload.couponId = couponId;
@@ -279,6 +290,20 @@
     state.showCoupon = false;
   }
 
+  // 创建用户期望奖品所在城市记录
+  const setTargetData = async (orderId) => {
+    try {
+      await PrizeApi.luckTargetCreate({
+        orderId,
+        spuId: state.orderPayload.spuId,
+        skuId: state.orderInfo.items?.length && state.orderInfo.items[0].skuId,
+        target: state.orderPayload.city,
+      })
+    } catch (error) {
+      console.log(error)
+    }
+  }
+
   // 提交订单
   function onConfirm() {
     if (addressState.value.deliveryType === 1 && !addressState.value.addressInfo.id) {
@@ -304,7 +329,8 @@
       }
     }
     console.log(state.orderPayload, 'submit-order-pay', state);
-    if (state.orderInfo.items.every(k => k.spuType !== '0') && !state.orderPayload.email) {
+    // 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
     }
@@ -334,6 +360,9 @@
     if (code !== 0) {
       return;
     }
+    
+    if (state.orderPayload?.city?.length) setTargetData(data.id)
+    
     // 更新购物车列表,如果来自购物车
     if (state.orderPayload.items[0].cartId > 0) {
       sheep.$store('cart').getList();
@@ -343,6 +372,7 @@
     if (data.payOrderId && data.payOrderId > 0) {
       sheep.$router.redirect('/pages/pay/index', {
         id: data.payOrderId,
+        salesLotterySpuId,
       });
     } else {
       sheep.$router.redirect('/pages/order/detail', {
@@ -351,6 +381,8 @@
     }
   }
 
+  const spuType = ref('')
+  let salesLotterySpuId = ''
   // 检查库存 & 计算订单价格
   async function getOrderInfo() {
     // 计算价格
@@ -372,6 +404,9 @@
       return code;
     }
     state.orderInfo = data;
+    spuType.value = state.orderInfo?.items?.length && state.orderInfo.items.every(k => k.spuType === '0') ? '0' : ''
+    salesLotterySpuId = Boolean(!spuType.value) ? state.orderPayload?.spuId : ''
+    
     state.couponInfo = data.coupons || [];
     // 设置收货地址
     if (state.orderInfo.address) {
@@ -545,4 +580,10 @@
     font-size: 36rpx;
     color: #999999;
   }
+  .emailErrorMessage {
+    background: #fff;
+    text-align: right;
+    color: #ff3000;
+    font-size: 24rpx;
+  }
 </style>

+ 5 - 2
pages/pay/index.vue

@@ -106,12 +106,12 @@
         content: '确定要支付吗?',
         success: function (res) {
           if (res.confirm) {
-            sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id);
+            sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id, salesLotterySpuId);
           }
         },
       });
     } else {
-      sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id);
+      sheep.$platform.pay(state.payment, state.orderType, state.orderInfo.id, salesLotterySpuId);
     }
   };
 
@@ -196,6 +196,7 @@
     state.payMethods = payMethods
   }
 
+  let salesLotterySpuId = ''
   onLoad((options) => {
     if (
       sheep.$platform.name === 'WechatOfficialAccount' &&
@@ -210,6 +211,8 @@
     if (options.orderType) {
       state.orderType = options.orderType;
     }
+    
+    salesLotterySpuId = options?.salesLotterySpuId || ''
     setOrder(id);
     // 刷新钱包的缓存
     sheep.$store('user').getWallet();

+ 3 - 45
pages/pay/prizeDraw.vue

@@ -1,53 +1,11 @@
 <template>
-  <view v-if="showPrizeDraw">
-    <!-- <luckyWheel></luckyWheel> -->
-    <luckyGrid></luckyGrid>
-    <!-- <slotMachine v-if="props.type === '2'" :lotteryId="lotteryId"></slotMachine> -->
-    <!-- <view class="numberBox mt-5">您还剩余<span class="colorBase">{{ luckyDrawsNum }}</span>次抽奖机会</view> -->
+  <view>
+    <SlotMachine v-bind="$attrs"></SlotMachine>
   </view>
 </template>
 <script setup>
-// import luckyWheel from '@/pages/lucky/Wheel'
-import luckyGrid from '@/pages/lucky/Grid'
-// import slotMachine from '@/pages/lucky/slotMachine'
-// import PrizeApi from '@/sheep/api/prizeDraw'
-import { ref } from 'vue'
-// const props = defineProps({
-//   skuId: [Number, String],
-//   type: {
-//     type:String,
-//     default: '1'
-//   }
-// })
-
-// // 获取抽奖次数
-// const luckyDrawsNum = ref(0)
-// const getLuckyNum = async () => {
-//   luckyDrawsNum.value = await PrizeApi.getNumByLotteryId(lotteryId.value)
-// }
-
-const showPrizeDraw = ref(true)
-// const lotteryId = ref('')
-// const getLottery = async () => {
-//   if (!props.skuId) return
-//   const data = await PrizeApi.getPrizeByGoodsId(props.skuId)
-//   lotteryId.value = data.id
-//   showPrizeDraw.value = data && Object.keys(data).length > 0
-//   if (showPrizeDraw.value) getLuckyNum()
-// }
-// getLottery()
+import SlotMachine from '@/pages/lucky/SlotMachine'
 
 </script>
 <style lang="scss" scoped>
-.numberBox {
-  font-size: 20px;
-  font-weight: bold;
-  padding: 2px 38px;
-  text-align: center;
-}
-.colorBase {
-  color: #00897B;
-  margin: 0 6px;
-  font-size: 22px;
-}
 </style>

+ 50 - 0
pages/pay/prizePage.vue

@@ -0,0 +1,50 @@
+<!--  -->
+<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 '@/view/mall/components/confirm_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>

+ 56 - 4
pages/pay/result.vue

@@ -50,16 +50,25 @@
       </view>
 
       <!-- #ifdef MP -->
-      <view
+      <!-- <view
         class="subscribe-box ss-flex ss-m-t-44"
         v-if="showSubscribeBtn && state.orderType === 'goods'"
       >
         <image class="subscribe-img" :src="sheep.$url.static('/static/img/shop/order/cargo.png')" />
         <view class="subscribe-title ss-m-r-48 ss-m-l-16">获取实时发货信息与订单状态</view>
         <view class="subscribe-start" @tap="subscribeMessage">立即订阅</view>
-      </view>
+      </view> -->
       <!-- #endif -->
-      <prizeDraw v-if="payResult === 'success'" class="prizeDraw"></prizeDraw>
+      <!-- 正常填写物流商品不参与抽奖 -->
+      <SlotMachine
+        v-if="showPrizeDraw"
+        class="prizeDraw"
+        height="120" 
+        :lotteryId="lotteryId"
+        @end="lotteryEnd"
+      ></SlotMachine>
+      <!-- 抽奖结果 -->
+      <prizePage v-if="showLotteryResult" :prizeData="prizeData"></prizePage>
     </view>
   </s-layout>
 </template>
@@ -73,7 +82,9 @@
   import { fen2yuan } from '@/sheep/hooks/useGoods';
   import OrderApi from '@/sheep/api/trade/order';
   import { WxaSubscribeTemplate } from '@/sheep/util/const';
-  import prizeDraw from './prizeDraw.vue'
+  import SlotMachine from '@/pages/lucky/SlotMachine'
+  import PrizeApi from '@/sheep/api/prizeDraw'
+  import prizePage from './prizePage'
 
   const state = reactive({
     id: 0, // 支付单号
@@ -105,6 +116,7 @@
     state.counter++;
     // 1. 加载订单信息
     const { data, code } = await PayOrderApi.getOrder(id);
+    // console.log('getOrder:', data)
     if (code === 0) {
       state.orderInfo = data;
       if (!state.orderInfo || state.orderInfo.status === 30) {
@@ -113,6 +125,7 @@
         return;
       }
       if (state.orderInfo.status !== 0) {
+        getRecord(state.orderInfo.merchantOrderId)
         // 非待支付,可能是已支付,可能是已退款
         state.result = 'paid';
         // #ifdef MP
@@ -191,7 +204,30 @@
     subscribeMessage();
   }
   // #endif
+  
+  const showLotteryResult = ref(false)
+  const lotteryEnd = () => {
+    const bool = Boolean(prizeData.value?.length)
+    uni.showModal({
+      title: bool ? '恭喜中奖' : '感谢参与',
+      showCancel: false, // 不要取消按钮
+      content: bool ? '恭喜您抽到一张房券,请尽快领取!' : '本次未中奖,欢迎继续关注后续活动。'
+    })
+    showPrizeDraw.value = false
+    if (!bool) return
+    showLotteryResult.value = true
+  }
+  
+  const lotteryId = ref('')
+  const showPrizeDraw = ref(false)
+  const getLottery = async () => {
+    if (!salesLotterySpuId) return
+    const res = await PrizeApi.getPrizeByGoodsId(salesLotterySpuId)
+    lotteryId.value = res?.data?.id
+    showPrizeDraw.value = Boolean(payResult.value === 'success' && lotteryId.value)
+  }
 
+  let salesLotterySpuId = '' // 正常填写物流商品不参与抽奖
   onLoad(async (options) => {
     // 支付订单号
     if (options.id) {
@@ -202,6 +238,10 @@
       state.orderType = options.orderType;
     }
 
+    // 虚拟商品参与抽奖
+    salesLotterySpuId = options?.salesLotterySpuId || false
+    getLottery()
+
     // 支付结果传值过来是失败,则直接显示失败界面
     if (options.payState === 'fail') {
       state.result = 'failed';
@@ -210,6 +250,18 @@
       await getOrderInfo(state.id);
     }
   });
+  
+  // 获取中奖记录
+  const prizeData = ref({})
+  const getRecord = async (orderId) => {
+    if (!orderId) return
+    const res = await PrizeApi.getLuckLotteryRecordByOrderId(orderId)
+    // console.log('prizeData:', res)
+    prizeData.value = res?.data || []
+    // 测试
+    // showPrizeDraw.value = false
+    // showLotteryResult.value = true
+  }
 
   onShow(() => {
     if (isEmpty(state.orderInfo)) {

+ 37 - 0
sheep/api/prizeDraw/index.js

@@ -27,6 +27,43 @@ const PrizeApi = {
       params: { lotteryId },
     });
   },
+
+  // 根据商品id活动对应的奖品区域信息
+  getPrizeAreaByGoodsId: (params) => {
+    return request({
+      url: '/promotion/luck-prize/get/extend/area',
+      method: 'GET',
+      params,
+    });
+  },
+
+  // 创建用户期望奖品记录
+  luckTargetCreate: (data) => {
+    return request({
+      url: '/promotion/luck-lottery/user-target/create',
+      method: 'POST',
+      data,
+    });
+  },
+
+  // 根据订单id获取中奖记录
+  getLuckLotteryRecordByOrderId: (orderId) => {
+    return request({
+      url: '/promotion/luck-lottery-record/get/by-order-id',
+      method: 'GET',
+      params: { orderId },
+    });
+  },
+
+  // 根据订单id组获取中奖记录
+  getLuckLotteryRecordByOrderIds: (orderIds) => {
+    return request({
+      url: '/promotion/luck-lottery-record/get/by-order-ids',
+      method: 'GET',
+      params: { orderIds },
+    });
+  },
+  
 };
 
 export default PrizeApi;

+ 3 - 0
sheep/components/s-goods-card/s-goods-card.vue

@@ -241,6 +241,8 @@
     // 加载商品列表
     state.goodsList = await getGoodsListByIds(spuIds.join(','));
     // 拼接结算信息(营销)
+    
+  if (sheep.$store('user').isLogin) { // 需要登录
     await OrderApi.getSettlementProduct(state.goodsList.map((item) => item.id).join(',')).then(
       (res) => {
         if (res.code !== 0) {
@@ -249,6 +251,7 @@
         appendSettlementProduct(state.goodsList, res.data);
       },
     );
+  }
     // 只有双列布局时需要
     if (layoutType === LayoutTypeEnum.TWO_COL) {
       // 分列

+ 105 - 2
sheep/components/s-select-sku/s-select-sku.vue

@@ -76,6 +76,38 @@
               @change="onNumberChange($event)"
             />
           </view>
+          <!-- 我要房券 -->
+          <view v-else class="ss-m-b-20">
+            <checkbox-group class="ss-m-b-10" @change="isGetPrizeChange">
+              <label>
+                <checkbox value="getPrize"  :checked="isGetPrize" />
+                我要房券
+              </label>
+            </checkbox-group>
+            <div v-if="noCity" style="color: gray;" class="ss-m-20">房券已被抢完啦</div>
+            <div v-show="isGetPrize" class="ss-m-20">
+              <div class="getPrizeTip ss-m-20">请勾选一到三个地点作为期望获赠房券的所在地,系统将随机抽取一张</div>
+              <view v-if="prizeAreaList?.length" class="ss-flex ss-col-center ss-flex-wrap">
+                <button
+                  class="ss-reset-button spec-btn"
+                  v-for="(item, index) of prizeAreaList"
+                  :key="item+index"
+                  :class="[
+                    {
+                      'ui-BG-Main-Gradient': item.active,
+                    },
+                    {
+                      'disabled-btn': item.total <= 0,
+                    },
+                  ]"
+                  :disabled="item.total <= 0"
+                  @tap="cityChange(index, item.active)"
+                >
+                  {{ item.label }}
+                </button>
+              </view>
+            </div>
+          </view>
         </scroll-view>
       </view>
 
@@ -93,9 +125,10 @@
 </template>
 
 <script setup>
-  import { computed, reactive, watch } from 'vue';
+  import { computed, reactive, watch, ref } from 'vue';
   import sheep from '@/sheep';
   import { formatStock, convertProductPropertyList, fen2yuan } from '@/sheep/hooks/useGoods';
+  import PrizeApi from '@/sheep/api/prizeDraw'
 
   const emits = defineEmits(['change', 'addCart', 'buy', 'close']);
   const props = defineProps({
@@ -171,7 +204,15 @@
       sheep.$helper.toast('库存不足');
       return;
     }
-    emits('buy', state.selectedSku);
+    if (isGetPrize.value && !checkList?.length) {
+      sheep.$helper.toast('请勾选期望获赠房券的所在地!');
+      return;
+    }
+    let city = []
+    if (isGetPrize.value && checkList?.length) {
+      checkList.forEach(index => city.push(prizeAreaList.value[index].label))
+    }
+    emits('buy', { ...state.selectedSku, city })
   }
 
   // 改变禁用状态:计算每个 property 属性值的按钮,是否禁用
@@ -317,10 +358,72 @@
       if (e.values && e.values.length) onSelectSku(e.id, e.values[0].id)
     })
   }
+  
+  function checkAllTotalsAreZero(obj) {
+    for (let city in obj) {
+      if (obj.hasOwnProperty(city) && obj[city].total !== 0) {
+        return false
+      }
+    }
+    return true
+  }
+
+  const isGetPrize = ref(false)
+  const noCity = ref(false)
+  const prizeAreaList = ref([])
+  // 根据商品id活动对应的奖品区域信息
+  const getAreaData = async () => {
+    const id = props.goodsInfo?.id
+    if (!id) return
+    const params = {
+      spuId: id,
+      type: 'city',
+    }
+    const res = await PrizeApi.getPrizeAreaByGoodsId(params)
+    const data = res?.data
+    if (!data || !Object.keys(data).length || checkAllTotalsAreZero(data)) {
+      noCity.value = true
+      isGetPrize.value = false
+      return
+    }
+
+    let list = [] // 只显示还有库存的城市
+    Object.keys(data).forEach(cityName => {
+      list.push({ label: cityName, total: data[cityName].total, active: false })
+    })
+    prizeAreaList.value = [...new Set(list)]
+    // getPrizeLoading.value = false
+  }
+
+  let checkList = []
+  const cityChange = (index, active) => {
+    if (active) { // 取消
+      checkList = checkList.filter(item => item !== index)
+    } else { // 选中
+      if (checkList.length > 2) return sheep.$helper.toast('最多只可选择三个')
+      
+      checkList.push(index)
+    }
+    prizeAreaList.value[index].active = !active
+  }
+  
+  const isGetPrizeChange = (e) => {
+    isGetPrize.value = Boolean(e?.detail?.value?.length)
+    if (!isGetPrize.value) {
+      // checkList = []
+      // prizeAreaList.value.forEach(e => e.active = false)
+      return
+    }
+    getAreaData()
+  }
 </script>
 
 <style lang="scss" scoped>
   // 购买
+  .getPrizeTip {
+    font-weight: bold;
+    text-decoration: underline;
+  }
   .buy-box {
     padding: 10rpx 0;
 

+ 2 - 2
sheep/platform/index.js

@@ -75,8 +75,8 @@ const useProvider = (_provider = '') => {
 };
 
 // 支付服务转发
-const pay = (payment, orderType, orderSN) => {
-  return new Pay(payment, orderType, orderSN);
+const pay = (payment, orderType, orderSN, salesLotterySpuId) => {
+  return new Pay(payment, orderType, orderSN, salesLotterySpuId);
 };
 
 /**

+ 6 - 3
sheep/platform/pay.js

@@ -11,13 +11,15 @@ import PayOrderApi from '@/sheep/api/pay/order';
  * @param {String} payment = ['wechat','alipay','wallet','mock']  	- 支付方式
  * @param {String} orderType = ['goods','recharge','groupon']  	- 订单类型
  * @param {String} id					- 订单号
+ * @param {Boolean} salesLotterySpuId - 房券抽奖
  */
 
 export default class SheepPay {
-  constructor(payment, orderType, id) {
+  constructor(payment, orderType, id, salesLotterySpuId) {
     this.payment = payment;
     this.id = id;
     this.orderType = orderType;
+    this.salesLotterySpuId = salesLotterySpuId;
     this.payAction();
   }
 
@@ -270,7 +272,7 @@ export default class SheepPay {
 
   // 支付结果跳转,success:成功,fail:失败
   payResult(resultType) {
-    goPayResult(this.id, this.orderType, resultType);
+    goPayResult(this.id, this.orderType, resultType,  this.salesLotterySpuId);
   }
 
   // 引导绑定微信
@@ -357,10 +359,11 @@ export function getPayMethods(channels) {
 }
 
 // 支付结果跳转,success:成功,fail:失败
-export function goPayResult(id, orderType, resultType) {
+export function goPayResult(id, orderType, resultType, salesLotterySpuId) {
   sheep.$router.redirect('/pages/pay/result', {
     id,
     orderType,
     payState: resultType,
+    salesLotterySpuId,
   });
 }