| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 | <template>  <div class="prizeDrawBox">    <div class="d-flex flex-column align-center">      <CtDialog :visible="showDialog" :widthType="3" :footer="false" titleClass="text-h6" title="房券抽奖" @close="showDialog = false">        <div class="d-flex flex-column align-center">          <div class="numberBox mb-5">房券抽奖</div>          <gridPage v-if="props.type === '1'" :lotteryId="props.lotteryId" :disabled="disabled" @start="disabled = true" @end="endCallback"></gridPage>          <slotMachinePage v-if="props.type === '2'" :lotteryId="props.lotteryId" height="120" :class="{'mb-3': disabled}" :disabled="disabled" @start="disabled = true" @end="endCallback"></slotMachinePage>        </div>      </CtDialog>      <v-card min-height="300" width="700" class="pa-5" :class="{'mt-3': !disabled}" style="position: relative;">        <div v-if="showPrize">          <p v-for="(k, i) in prizeData" :key="i" class="color-primary">            {{ k.prize.prompt }}            <span class="color-999">(10天内未领取的,则视为主动放弃当前奖品)</span>          </p>          <p>凭此房券在规定有效期内可享受免费住宿一晚。</p>          <p class="mb-5">请提供收货地址,以便安排房券派送。</p>          <!-- 收货地址 -->          <div>            <v-radio-group v-model="addressSelect" color="primary">              <v-radio v-for="val in address" :key="val.id" :label="val.id === 9999 ? val.label : (val.name + ',' + val.mobile + ',' + val.areaName + val.detailAddress)" :value="val.id"></v-radio>            </v-radio-group>            <v-form v-if="addressSelect === 9999" ref="addressFormRef">              <v-row>                <v-col :cols="6">                  <v-text-field v-model="newAddress.name" label="收货人名称 *" color="primary" density="compact" variant="outlined"></v-text-field>                </v-col>                <v-col :cols="6">                  <v-text-field v-model="newAddress.mobile" :rules="phoneRules" label="收货人手机号码 *" color="primary" density="compact" variant="outlined"></v-text-field>                </v-col>              </v-row>              <div class="d-flex" style="width: 100%;">                <div class="mt-2" style="color: #777; width: 100px;">省市区 *</div>                <el-cascader                  ref="cascaderAddr"                  v-model="newAddress.areaId"                  size="large"                  clearable                  class="mb-5"                  placeholder="省市区 *"                  style="flex: 1;"                  :props="{ value: 'id', label: 'name', emitPath: false }"                  :options="areaTreeData"                  @change="handleChangeArea(item)"                ></el-cascader>              </div>              <v-text-field v-model="newAddress.detailAddress" label="详情地址 *" color="primary" density="compact" variant="outlined"></v-text-field>            </v-form>            <div class="text-center mt-3">              <v-btn color="primary" class="elevation-5" width="180" @click.stop="handleSubmit">确 认</v-btn>            </div>          </div>        </div>        <div v-else class="color-warning text-center" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">请先进行抽奖</div>      </v-card>    </div>  </div></template><script setup>defineOptions({ name: 'prizeDraw'})import gridPage from './prizeDraw/grid.vue'import slotMachinePage from './prizeDraw/slotMachine.vue'import { onMounted, ref } from 'vue'import { getLuckLotteryRecordByOrderId } from '@/api/mall/prize'import { getMallUserAddressList } from '@/api/mall/address'import Snackbar from '@/plugins/snackbar'import { luckyLotteryRecordReceive } from '@/api/mall/prize'import { useRouter } from 'vue-router'import { getDict } from '@/hooks/web/useDictionaries'const emit = defineEmits(['success'])const props = defineProps({  lotteryId: [Number, String],  orderId: [Number, String],  type: {    type: String,    default: '1'  }})const showDialog = ref(false)onMounted(() =>{  if (localStorage.getItem('showLotteryBefore')) {    // 已经点击过抽奖按钮,直接展示奖品。例如刷新支付完成页面    showPrize.value = true  } else {    // 刚进入支付完成页面    showDialog.value = true  }})const router = useRouter()const newAddress = ref({  name: '',  areaId: '',  areaName: '',  mobile: '',  detailAddress: ''})const addressSelect = ref()const disabled = ref(false)const addressFormRef = ref()const cascaderAddr = ref()const areaTreeData = ref([])getDict('areaTreeData', null, 'areaTreeData').then(({ data }) => {  data = data?.length && data || []  areaTreeData.value = data})const phoneRules = ref([  value => {    if (value) return true    return t('login.mobileNumberPlaceholder')  },  value => {    if (value?.length <= 11 && /^1[3456789]\d{9}$/.test(value)) return true    return t('login.correctPhoneNumber')  }])// 地区选择const handleChangeArea = () => {  const node = cascaderAddr.value.getCheckedNodes() ? cascaderAddr.value.getCheckedNodes()[0] : null  if (!node) return  newAddress.value.areaName = node.pathLabels.join(' ')}// 获取中奖记录、收货地址const address = ref([])const prizeData = ref({})const getRecord = async () => {  const data = await getLuckLotteryRecordByOrderId(props.orderId)  prizeData.value = data || []  if (!data || !data.length) disabled.value = true  const addressData = await getMallUserAddressList()  address.value = [...addressData, { id: 9999, label: '使用新地址' }] || []  if (addressData && addressData.length) addressSelect.value = addressData[0].id}if (props.orderId) getRecord()const showPrize = ref(false)const endCallback = () => {  localStorage.setItem('showLotteryBefore', true) // 标记已抽奖  showDialog.value = false  showPrize.value = true}function checkValue(obj) {  for (let key in obj) {    if (obj.hasOwnProperty(key) && !obj[key]) {      return false    }  }  return true}// 领取const handleSubmit = async () => {  let query = {}  if (addressSelect.value === 9999) {    if (!checkValue(newAddress.value)) return Snackbar.warning('请完善收货信息')    query = newAddress.value  } else query = address.value.find(item => item.id === addressSelect.value)  await luckyLotteryRecordReceive({ id: prizeData.value[0].record.id, receiveInfo: JSON.stringify(query) })  localStorage.removeItem('showLotteryBefore') // 清空已抽奖痕迹  Snackbar.success('奖品领取成功,待商家发货')  router.replace('/recruit/personal/personalCenter/tradeOrder?key=1')}</script><style scoped lang="scss">.prizeDrawBox {  padding: 20px 40px;  background-color: var(--default-bgc);}.prizeDraw {  margin: 0 auto; }.numberBox {  font-size: 20px;  font-weight: bold;  padding: 2px 38px;  border-bottom: 3px solid var(--v-primary-base);}.colorBase {  color: var(--v-primary-base);  margin: 0 6px;  font-size: 22px;}</style>
 |