Commit ed69d04d by 赖慧粮

Merge branch 'test' of gitlab.aodianyun.com:activities/web-lottery into test

parents d4d609b4 85dd5eb2
...@@ -19,3 +19,8 @@ body { ...@@ -19,3 +19,8 @@ body {
opacity: 0; opacity: 0;
transform: translate(-30px, 0); transform: translate(-30px, 0);
} }
.sidebar-hidden-scroll {
right: -0.2rem !important;
opacity: 0.7;
}
\ No newline at end of file
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
<script> <script>
import { mapActions } from 'vuex' import { mapActions } from 'vuex'
import Bus from '@/utils/Bus'
export default { export default {
name: 'BindPhoneDialog', name: 'BindPhoneDialog',
props: { props: {
...@@ -24,7 +25,7 @@ export default { ...@@ -24,7 +25,7 @@ export default {
return this.value return this.value
}, },
set (val) { set (val) {
this.$emit('input', val) Bus.$emit('updateMain', { isShowBindPhone: val })
} }
} }
}, },
......
...@@ -7,15 +7,31 @@ import CONFIG from '@/config' ...@@ -7,15 +7,31 @@ import CONFIG from '@/config'
import { mapGetters, mapActions } from 'vuex' import { mapGetters, mapActions } from 'vuex'
import { CUSTOM_SOURCE_TYPE } from '@/utils/constant' import { CUSTOM_SOURCE_TYPE } from '@/utils/constant'
import Bus from '@/utils/Bus'
export default { export default {
name: 'ComplaintsDeal', name: 'ComplaintsDeal',
data() {
return {
color: '',
entry: null,
body: null
}
},
computed: { computed: {
...mapGetters({ ...mapGetters({
isLogin: 'users/isLogin' isLogin: 'users/isLogin'
}) })
}, },
mounted() { mounted() {
this.init() Bus.$on('initDeal', color => {
this.color = color
this.init()
this.dealAnimation()
})
},
destroyed() {
Bus.$off('initDeal')
}, },
methods: { methods: {
...mapActions({ jumpToLogin: 'users/jumpToLogin' }), ...mapActions({ jumpToLogin: 'users/jumpToLogin' }),
...@@ -24,20 +40,26 @@ export default { ...@@ -24,20 +40,26 @@ export default {
if (typeof complaintsDeal === 'undefined') { if (typeof complaintsDeal === 'undefined') {
return null return null
} }
const defaultEntryStyle = {
width: '0.62667rem',
height: '0.62667rem',
right: '0.13333rem',
bottom: '0.33333rem',
zIndex: 6,
background: '#fff',
iconColor: '#80411a',
transition: 'all 0.25s cubic-bezier(0.55, 0, 0.1, 1)'
}
if (this.color) {
Object.assign(defaultEntryStyle, { iconColor: this.color })
}
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
complaintsDeal({ complaintsDeal({
target: document.body, target: document.body,
props: { props: {
// rootFontSize: '.62667rem', // rootFontSize: '.62667rem',
defaultEntryStyle: { defaultEntryStyle,
width: '0.62667rem',
height: '0.62667rem',
right: '0.13333rem',
bottom: '0.13333rem',
zIndex: 6,
background: '#fff',
iconColor: '#80411a'
},
zIndex: 999, zIndex: 999,
uin, uin,
url: window.location.href, url: window.location.href,
...@@ -69,10 +91,35 @@ export default { ...@@ -69,10 +91,35 @@ export default {
} }
} }
}) })
},
dealAnimation() {
setTimeout(() => {
this.entry = document.querySelector('.entry')
this.body = document.body
this.body.addEventListener('touchstart', () => {
this.body.addEventListener('touchmove', this.dealScrollOn)
})
this.body.addEventListener('touchend', () => {
this.body.removeEventListener('touchmove', this.dealScrollOn)
this.dealScrollOff()
})
}, 500)
},
dealScrollOn() {
if (this.entry && !this.entry.classList.contains('sidebar-hidden-scroll')) {
this.entry.classList.add('sidebar-hidden-scroll')
}
},
dealScrollOff() {
if (this.entry && this.entry.classList.contains('sidebar-hidden-scroll')) {
setTimeout(() => {
this.entry.classList.remove('sidebar-hidden-scroll')
}, 500)
}
} }
} }
} }
</script> </script>
<style lang='less' scoped> <style lang="less" scoped></style>
</style>
<template> <template>
<section v-if="'startTime' in lotteryInfo" class="countdown-bar"> <section v-if="'startTime' in lotteryInfo" class="countdown-bar">
<div class="countdown-bar__status"> <div
class="countdown-bar__status"
:style="barStyle"
>
<template v-if="parseInt(status, 10) !== LOTTERY_STATUS.end"> <template v-if="parseInt(status, 10) !== LOTTERY_STATUS.end">
<div class="countdown-bar__text">{{ LOTTERY_STATUS_TXT[parseInt(status, 10)].actionLabel }}倒计时:</div> <div class="countdown-bar__text">{{ LOTTERY_STATUS_TXT[parseInt(status, 10)].actionLabel }}倒计时:</div>
<van-count-down millisecond :time="time"> <van-count-down millisecond :time="time" :style="{ color: barStyle.color }">
<template #default="timeData"> <template #default="timeData">
<span v-if="timeData.days" class="time-item"> <span v-if="timeData.days" class="time-item">
{{ timeData.days | limitNum }} {{ timeData.days | limitNum }}
...@@ -51,6 +54,12 @@ export default { ...@@ -51,6 +54,12 @@ export default {
return value return value
} }
}, },
props: {
barStyle: {
type: Object,
default: () => ({})
}
},
data() { data() {
return { return {
LOTTERY_STATUS, LOTTERY_STATUS,
...@@ -95,7 +104,7 @@ export default { ...@@ -95,7 +104,7 @@ export default {
font-size: 13px; font-size: 13px;
// text-align: center; // text-align: center;
display: flex; display: flex;
// justify-content: center; justify-content: center;
align-items: center; align-items: center;
color: #fff; color: #fff;
font-weight: 400; font-weight: 400;
...@@ -113,7 +122,7 @@ export default { ...@@ -113,7 +122,7 @@ export default {
font-size: 13px; font-size: 13px;
font-weight: 400; font-weight: 400;
} }
&__end{ &__end {
width: 100%; width: 100%;
text-align: center; text-align: center;
} }
......
<template> <template>
<div class="introduction"> <div class="introduction" :style="introBoxStyle">
<div class="introduction__sec-title"></div> <div class="introduction__sec-title" :style="titleStyle">{{ titleText }}</div>
<div class="introduction__wrap"> <div class="introduction__wrap" :style="wrapStyle">
<div class="introduction__content"> <div class="introduction__content" :style="contentStyle">
<p class="introduction__intro">{{ lotteryInfo.intro }}</p> <p v-if="rule.position === 'top'" class="introduction__intro" :style="rule.style">{{ lotteryInfo.intro }}</p>
<template v-if="!!lotteryInfo.isShowPrize"> <template v-if="!!lotteryInfo.isShowPrize">
<div class="introduction__title">本场活动奖品:</div> <div class="introduction__title">本场活动奖品:</div>
<div class="introduction__prize"> <div class="introduction__prize">
...@@ -19,6 +19,10 @@ ...@@ -19,6 +19,10 @@
</ul> </ul>
</div> </div>
</template> </template>
<div v-if="rule.position === 'bottom'" class="introduction__intro" :style="rule.style">
<p class="introduction__intro-rule">活动规则</p>
<p>{{ lotteryInfo.intro }}</p>
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -30,6 +34,35 @@ import img from '@/assets/images/lottery/gift.png' ...@@ -30,6 +34,35 @@ import img from '@/assets/images/lottery/gift.png'
export default { export default {
name: 'Introduction', name: 'Introduction',
props: {
rule: {
type: Object,
default: () => ({
position: 'top',
style: {}
})
},
titleStyle: {
type: Object,
default: () => ({})
},
titleText: {
type: String,
default: ''
},
wrapStyle: {
type: Object,
default: () => ({})
},
contentStyle: {
type: Object,
default: () => ({})
},
introBoxStyle: {
type: Object,
default: () => ({})
}
},
data() { data() {
return { return {
img img
...@@ -79,6 +112,12 @@ export default { ...@@ -79,6 +112,12 @@ export default {
font-size: 12px; font-size: 12px;
line-height: 18px; line-height: 18px;
white-space: pre-line; white-space: pre-line;
&-rule {
text-align: center;
font-size: 14px;
margin: 30px 0 20px 0;
}
} }
&__title { &__title {
margin: 14px 0 10px; margin: 14px 0 10px;
......
<template> <template>
<van-popup v-model="visible" :overlay="false" position="bottom" transition="van-fade" class="introduction-popup"> <van-popup
v-model="visible"
:overlay="false"
position="bottom"
transition="van-fade"
class="introduction-popup"
:style="popupStyle"
>
<div class="introduction-popup__main"> <div class="introduction-popup__main">
<div class="introduction-popup__sec-title">活动介绍</div> <div class="introduction-popup__sec-title" :style="titleStyle">活动介绍</div>
<div class="introduction-popup__wrap"> <div class="introduction-popup__wrap" :style="wrapStyle">
<div class="introduction-popup__content"> <div class="introduction-popup__content" :style="contentStyle">
<p class="introduction-popup__intro">{{ lotteryInfo.intro }}</p> <p v-if="rule.position === 'top'" class="introduction-popup__intro" :style="rule.style">{{ lotteryInfo.intro }}</p>
<template v-if="!!lotteryInfo.isShowPrize"> <template v-if="!!lotteryInfo.isShowPrize">
<div class="introduction-popup__title">本场活动奖品:</div> <div class="introduction-popup__box" :style="contentBoxStyle">
<div class="introduction-popup__prize"> <div class="introduction-popup__title">本场活动奖品:</div>
<ul <div class="introduction-popup__prize">
class="introduction-popup__list" <ul
:class="{ 'introduction-popup__list--center': lotteryInfo.prizeConfigs.length < 3 }" class="introduction-popup__list"
> :class="{ 'introduction-popup__list--center': lotteryInfo.prizeConfigs.length < 3 }"
<li v-for="(item, index) in lotteryInfo.prizeConfigs" :key="index"> >
<img v-lazy="item.icon || img" class="introduction-popup__item-img" alt /> <li v-for="(item, index) in lotteryInfo.prizeConfigs" :key="index">
<p v-if="item.prizeAlias" class="introduction-popup__item-level">{{ item.prizeAlias }}</p> <img v-lazy="item.icon || img" class="introduction-popup__item-img" alt />
<p class="introduction-popup__item-name">{{ item.name }}</p> <p v-if="item.prizeAlias" class="introduction-popup__item-level">{{ item.prizeAlias }}</p>
</li> <p class="introduction-popup__item-name">{{ item.name }}</p>
</ul> </li>
</ul>
</div>
</div> </div>
</template> </template>
<div v-if="rule.position === 'bottom'" class="introduction-popup__intro" :style="rule.style">
<p class="introduction-popup__intro-rule">活动规则</p>
<p>{{ lotteryInfo.intro }}</p>
</div>
</div> </div>
</div> </div>
<div class="introduction-popup__back" @click="visible = false">返回活动</div> <div class="introduction-popup__back" :style="backStyle" @click="visible = false">返回活动</div>
</div> </div>
</van-popup> </van-popup>
</template> </template>
...@@ -30,6 +43,7 @@ ...@@ -30,6 +43,7 @@
<script> <script>
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import img from '@/assets/images/lottery/gift.png' import img from '@/assets/images/lottery/gift.png'
import Bus from '@/utils/Bus'
export default { export default {
name: 'Introduction', name: 'Introduction',
...@@ -37,6 +51,37 @@ export default { ...@@ -37,6 +51,37 @@ export default {
value: { value: {
type: Boolean, type: Boolean,
default: false default: false
},
rule: {
type: Object,
default: () => ({
position: 'top',
style: {}
})
},
contentBoxStyle: {
type: Object,
default: () => ({})
},
titleStyle: {
type: Object,
default: () => ({})
},
wrapStyle: {
type: Object,
default: () => ({})
},
contentStyle: {
type: Object,
default: () => ({})
},
popupStyle: {
type: Object,
default: () => ({})
},
backStyle: {
type: Object,
default: () => ({})
} }
}, },
data() { data() {
...@@ -51,13 +96,13 @@ export default { ...@@ -51,13 +96,13 @@ export default {
return this.value return this.value
}, },
set(val) { set(val) {
this.$emit('input', val) Bus.$emit('updateMain', { isShowIntro: val })
} }
} }
}, },
methods: { methods: {
getContainer(){ getContainer() {
return document.querySelector('.lottery-instant'); return document.querySelector('.lottery-instant')
} }
} }
} }
...@@ -123,6 +168,10 @@ export default { ...@@ -123,6 +168,10 @@ export default {
font-size: 12px; font-size: 12px;
line-height: 18px; line-height: 18px;
white-space: pre-line; white-space: pre-line;
&-rule {
text-align: center;
margin-top: 30px;
}
} }
&__title { &__title {
margin: 14px 0 10px; margin: 14px 0 10px;
......
<template> <template>
<div class="records"> <div class="records">
<div class="records__layouts"> <div ref="recordsLayouts" class="records__layouts">
<div class="records__entry" @click="openRecord"> <div class="records__entry" @click="openRecord">
<div class="records__entry-wrap"> <div class="records__entry-wrap">
<p>抽奖</p> <p :style="textColor">抽奖</p>
<p>记录</p> <p :style="textColor">记录</p>
</div> </div>
</div> </div>
<div v-if="isShowWinnersList" class="records__entry records__entry--winners" @click="openRecordPopup('winners')"> <div v-if="isShowWinnersList" class="records__entry records__entry--winners" @click="openRecordPopup('winners')">
<div class="records__entry-wrap"> <div class="records__entry-wrap">
<p>中奖</p> <p :style="textColor">中奖</p>
<p>名单</p> <p :style="textColor">名单</p>
</div> </div>
</div> </div>
</div> </div>
<RecordsPupup v-model="isShowRecordsPopup" :active-tab="activeTab" :is-show-winners-list="isShowWinnersList"></RecordsPupup> <RecordsPupup
v-model="pupupVisible"
:active-tab="activeTab"
:is-show-winners-list="isShowWinnersList"
@setIsShowRecordsPopup="setIsShowRecordsPopup"
></RecordsPupup>
<RecordsPupupNew
v-model="pupupNewVisible"
:active-tab="activeTab"
:is-show-winners-list="isShowWinnersList"
:records-config="recordsConfig"
@setIsShowRecordsPopup="setIsShowRecordsPopup"
></RecordsPupupNew>
</div> </div>
</template> </template>
<script> <script>
import { mapGetters, mapActions } from 'vuex' import { mapGetters, mapActions } from 'vuex'
import RecordsPupup from '@/components/Lottery/Instant/RecordsPupup' import RecordsPupup from '@/components/Lottery/Instant/RecordsPupup'
import RecordsPupupNew from '@/components/Lottery/Instant/RecordsPupupNew'
import Bus from '@/utils/Bus'
export default { export default {
name: 'Records', name: 'Records',
components: { components: {
RecordsPupup RecordsPupup,
RecordsPupupNew
},
props: {
recordsConfig: {
type: Object,
default: () => ({
mode: 'old'
})
}
}, },
data() { data() {
return { return {
isShowRecordsPopup: false, isShowRecordsPopup: false,
activeTab: 'personal' activeTab: 'personal',
recordsLayouts: null,
body: null
} }
}, },
computed: { computed: {
...@@ -38,8 +64,36 @@ export default { ...@@ -38,8 +64,36 @@ export default {
isShowWinnersList() { isShowWinnersList() {
const { lotteryInfo } = this const { lotteryInfo } = this
return !!lotteryInfo.showResult return !!lotteryInfo.showResult
},
pupupVisible() {
return this.isShowRecordsPopup && this.recordsConfig.mode === 'old'
},
pupupNewVisible() {
return this.isShowRecordsPopup && this.recordsConfig.mode === 'new'
},
textColor() {
if (this.recordsConfig.mode === 'new') {
return {
color: this.recordsConfig.textColor
}
} else {
return {}
}
}
},
watch: {
'recordsConfig.textColor': {
handler(val) {
val ? Bus.$emit('initDeal', val) : Bus.$emit('initDeal', '')
},
immediate: true
} }
}, },
mounted() {
this.recordsLayouts = this.$refs.recordsLayouts
this.body = document.body
this.recordsAnimation()
},
methods: { methods: {
...mapActions({ jumpToLogin: 'users/jumpToLogin' }), ...mapActions({ jumpToLogin: 'users/jumpToLogin' }),
openRecord() { openRecord() {
...@@ -55,9 +109,36 @@ export default { ...@@ -55,9 +109,36 @@ export default {
this.openRecordPopup('personal') this.openRecordPopup('personal')
} }
}, },
openRecordPopup(type){ openRecordPopup(type) {
this.activeTab = type this.activeTab = type
this.isShowRecordsPopup = true this.isShowRecordsPopup = true
},
setIsShowRecordsPopup(val) {
this.isShowRecordsPopup = val
},
recordsAnimation() {
setTimeout(() => {
this.body.addEventListener('touchstart', () => {
this.body.addEventListener('touchmove', this.recordsScrollOn)
})
this.body.addEventListener('touchend', () => {
this.body.removeEventListener('touchmove', this.recordsScrollOn)
this.recordsScrollOff()
})
}, 500)
},
recordsScrollOn() {
if (this.recordsLayouts && !this.recordsLayouts.classList.contains('sidebar-hidden-scroll')) {
this.recordsLayouts.classList.add('sidebar-hidden-scroll')
}
},
recordsScrollOff() {
if (this.recordsLayouts && this.recordsLayouts.classList.contains('sidebar-hidden-scroll')) {
setTimeout(() => {
this.recordsLayouts.classList.remove('sidebar-hidden-scroll')
}, 500)
}
} }
} }
} }
...@@ -67,9 +148,10 @@ export default { ...@@ -67,9 +148,10 @@ export default {
.records { .records {
&__layouts { &__layouts {
position: fixed; position: fixed;
z-index: 5; z-index: 50;
right: 10px; right: 10px;
bottom: 75px; bottom: 90px;
transition: all 0.25s cubic-bezier(0.55, 0, 0.1, 1);
} }
&__entry { &__entry {
width: 47px; width: 47px;
......
...@@ -84,7 +84,7 @@ export default { ...@@ -84,7 +84,7 @@ export default {
return this.value return this.value
}, },
set(val) { set(val) {
this.$emit('input', val) this.$emit('setIsShowRecordsPopup', val)
} }
} }
}, },
......
<template>
<van-popup v-model="visible" class="records-popup" swipeable>
<div class="records-popup__close" :style="closeBg" @click="closePopup"></div>
<div class="records-popup__title">
<div class="records-popup__title-personal" :style="personalBg" @click="changeActive('personal')"></div>
<div class="records-popup__title-winners" :style="winnersBg" @click="changeActive('winners')"></div>
</div>
<div class="records-popup__main" :style="mainBg">
<div v-show="active === 'personal'" class="records-popup__personal-record">
<div class="records-popup__record-content">
<div class="records-popup__phone" :style="normalTextColor">
领奖手机号:
<span v-if="isBindPhone" :style="normalTextColor">{{ userInfo.phone }}</span>
<span v-else class="records-popup__bind-phone" :style="prizebindTextColor" @click="bindMobile">绑定手机号</span>
</div>
<ul v-if="Object.keys(recordList).length !== 0" class="records-popup__record-list">
<li v-for="(session, key, index) in recordList" :key="index">
<div v-for="(item, itemIndex) in session" :key="itemIndex" class="records-popup__session-info">
<div class="records-popup__info-wrap">
<div v-if="session.length > 1" class="records-popup__session" :style="normalTextColor">{{ NUMBER_LIST[index + 1] }}场次</div>
<div class="records-popup__time" :style="normalTextColor">
<span>{{ (item.drawTime * 1000) | formatDate('MM-DD HH:mm:ss') }}</span>
</div>
</div>
<div class="records-popup__prize-name" :style="normalTextColor">{{ item.prizeName }}</div>
</div>
</li>
</ul>
<div v-if="Object.keys(recordList).length === 0" class="records-popup__no-data" :style="noDataColor">暂无记录</div>
</div>
</div>
<div v-show="active === 'winners' && isShowWinnersList" class="records-popup__winners-record">
<div class="records-popup__record-content">
<div class="records-popup__winners-list">
<div v-for="(item, index) in winnersList" :key="index" class="records-popup__item" :style="normalTextColor">
{{ item.userNick }} 获得 <span class="records-popup__prize-name">{{ item.prizeName }}</span>
</div>
<div v-if="winnersList.length === 0" class="records-popup__no-data" :style="noDataColor">暂无数据</div>
</div>
</div>
</div>
</div>
</van-popup>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
import { getLotteryRecordList, getWinnersList } from '@/api/modules/lottery'
import { NUMBER_LIST } from '@/utils/constant'
export default {
name: 'RecordsPupup',
props: {
value: {
type: Boolean,
default: false
},
isShowWinnersList: {
type: Boolean,
default: false
},
activeTab: {
type: String,
default: 'personal'
},
recordsConfig: {
type: Object,
default: () => ({
mode: 'old'
})
}
},
data() {
return {
NUMBER_LIST,
recordList: {},
winnersList: [],
active: ''
}
},
computed: {
...mapGetters({
uin: 'users/uin',
userInfo: 'users/userInfo',
isBindPhone: 'users/isBindPhone'
}),
visible: {
get() {
return this.value
},
set(val) {
this.$emit('setIsShowRecordsPopup', val)
}
},
mainBg() {
return {
backgroundImage: `url(${this.recordsConfig.bg})`
}
},
personalBg() {
return {
backgroundImage:
this.active === 'personal'
? `url(${this.recordsConfig.personalBg})`
: `url(${this.recordsConfig.personalBgDisabled})`
}
},
winnersBg() {
return {
backgroundImage:
this.active === 'winners'
? `url(${this.recordsConfig.winnersBg})`
: `url(${this.recordsConfig.winnersBgDisabled})`
}
},
closeBg() {
return {
backgroundImage: `url(${this.recordsConfig.closeIcon})`
}
},
noDataColor() {
return {
color: this.recordsConfig.noDataColor
}
},
normalTextColor() {
return {
color: this.recordsConfig.normalTextColor
}
},
prizebindTextColor() {
return {
color: this.recordsConfig.prizebindTextColor
}
}
},
watch: {
visible: {
handler(val) {
if (val) {
this.active = this.activeTab
this.dataInit()
}
},
immediate: true
}
},
methods: {
...mapActions({ jumpToBinding: 'users/jumpToBinding' }),
dataInit() {
if (this.active === 'personal') {
getLotteryRecordList({
id: this.$route.query.id,
uin: this.uin,
playId: this.$route.query.sessionId
}).then(res => {
const { code, errorCode, errorMessage, data } = res
if (code === 200 && errorCode === 0) {
this.recordList = data
} else {
this.$toast(errorMessage)
}
})
}
if (this.active === 'winners') {
getWinnersList({
id: this.$route.query.id,
uin: this.$route.query.uin
}).then(res => {
const { code, errorCode, errorMessage, data } = res
if (code === 200 && errorCode === 0) {
this.winnersList = data
} else {
this.$toast(errorMessage)
}
})
}
},
onChange() {
if (!Object.keys(this.recordList).length || !this.winnersList.length) {
this.dataInit()
}
},
bindMobile() {
this.$toast({
message: '正在为您转跳,请完成绑定手机操作',
duration: 1500,
onClose: () => {
this.jumpToBinding()
}
})
},
changeActive(val) {
this.active = val
this.onChange()
},
closePopup() {
this.$emit('setIsShowRecordsPopup', false)
}
}
}
</script>
<style lang="less" scoped>
.records-popup {
top: 48%;
width: 258px;
height: 291px;
background-color: transparent;
border-radius: 15px;
overflow: visible;
font-size: 12px;
&__close {
position: absolute;
right: -8px;
top: 15px;
width: 25px;
height: 25px;
background-size: 100% 100%;
}
&__main {
position: relative;
height: 100%;
background-size: 100% 100%;
padding: 24px 16px;
transition: all 0.2s;
}
&__title {
color: #fff;
display: flex;
justify-content: center;
&-personal,
&-winners {
width: 83px;
height: 29px;
background-size: 100% 100%;
margin: 0 3px;
transition: all 0.2s;
}
}
/deep/ .van-popup__close-icon {
right: -22px;
top: -20px;
font-size: 22px;
color: #fff;
}
&__tabs {
padding: 8px 0 0;
height: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
::v-deep .van-tabs__wrap {
display: flex;
justify-content: center;
height: 34px;
}
::v-deep .van-tabs__nav {
background-color: transparent;
justify-content: center;
width: 160px;
.van-tab--active {
.van-tab__text {
color: #333;
font-weight: 500;
font-size: 14px;
}
}
}
::v-deep .van-tabs__line {
background-color: #d92e32;
border-radius: 1px;
}
::v-deep .van-tabs__content {
flex: 1;
overflow: hidden;
.van-tab__pane {
width: 100%;
height: 100%;
padding: 15px 0;
}
}
}
&__personal-record {
width: 100%;
height: 100%;
overflow: hidden auto;
padding: 0 15px;
}
&__phone {
color: #000;
margin-bottom: 12px;
}
&__bind-phone {
color: #d92e32;
}
&__record-list {
li {
margin-bottom: 15px;
&:last-child {
margin-bottom: 0;
}
}
}
&__session-info {
display: flex;
flex-direction: column;
&:last-child {
.records-popup__prize-name {
margin-bottom: 0;
}
}
}
&__info-wrap {
display: flex;
align-items: center;
}
&__session {
margin-right: 5px;
font-size: 13px;
color: #000;
}
&__time {
color: #000;
}
&__prize-name {
margin: 8px 0 15px;
color: #000;
}
&__item {
margin-bottom: 8px;
}
&__winners-record {
width: 100%;
height: 100%;
overflow: hidden auto;
padding: 0 15px;
.records-popup__prize-name {
color: #d92e32;
}
}
&__no-data {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #999;
text-align: center;
// padding-top: 40px;
}
}
</style>
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
</template> </template>
<script> <script>
import Bus from '@/utils/Bus'
export default { export default {
name: 'WinPopup', name: 'WinPopup',
components: {}, components: {},
...@@ -47,7 +49,7 @@ export default { ...@@ -47,7 +49,7 @@ export default {
return this.value return this.value
}, },
set(val) { set(val) {
this.$emit('input', val) Bus.$emit('updateMain', { isShowWin: val })
} }
}, },
isWin() { isWin() {
...@@ -56,7 +58,7 @@ export default { ...@@ -56,7 +58,7 @@ export default {
}, },
methods: { methods: {
know() { know() {
this.$emit('winCallback') Bus.$emit('updateMain', { func: 'winCallback' })
} }
} }
} }
......
<template>
<van-popup v-model="visible" class="win-popup" :style="{ background: 'transparent' }">
<div class="win-popup__container">
<div class="win-popup__close" :style="closeBg" @click="closePopup"></div>
<div class="win-popup__wrap" :style="wrapBg">
<div class="win-popup__content">
<div v-if="isWin" class="win-popup__header">
<img :src="winConfig.winTitle" />
</div>
<div v-if="isWin" class="win-popup__win-info">
<div class="win-popup__title">恭喜获得</div>
<div class="win-popup__prize-img" :style="prizeBg">
<img src="@/assets/images/lottery/gift.png" alt="" />
</div>
<div class="win-popup__prize-name">
{{ info.name }}
</div>
</div>
<div v-else class="win-popup__thanks">
<p>很遗憾</p>
<slot name="thanks"></slot>
</div>
</div>
<div class="win-popup__footer" @click="know">
<img :src="winConfig.winKnow" />
</div>
</div>
</div>
</van-popup>
</template>
<script>
import Bus from '@/utils/Bus'
export default {
name: 'WinPopup',
components: {},
props: {
value: {
type: Boolean,
default: false
},
info: {
type: Object,
default: () => ({})
},
winConfig: {
type: Object,
default: () => ({})
}
},
computed: {
visible: {
get() {
return this.value
},
set(val) {
Bus.$emit('updateMain', { isShowWin: val })
}
},
isWin() {
return !!+this.info.id
},
wrapBg() {
return {
backgroundImage: `url(${this.winConfig.bg})`
}
},
closeBg() {
return {
backgroundImage: `url(${this.winConfig.winClose})`
}
},
prizeBg() {
return {
backgroundImage: `url(${this.winConfig.winPrizeBg})`
}
}
},
methods: {
know() {
Bus.$emit('updateMain', { func: 'winCallback' })
},
closePopup() {
Bus.$emit('updateMain', { isShowWin: false })
}
}
}
</script>
<style lang="less" scoped>
@containerWidth: 326px;
@wrapWidth: 275px;
@wrapHeight: 292px;
.win-popup {
width: 263px;
height: 309px;
overflow: visible;
&__close {
position: absolute;
right: -20px;
top: -10px;
width: 25px;
height: 25px;
background-size: 100% 100%;
}
&__container {
width: 100%;
height: 100%;
position: relative;
}
&__wrap {
position: relative;
margin: 0 auto;
width: 100%;
height: 100%;
overflow: hidden;
background-size: cover;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
&__content {
color: #fff;
font-size: 16px;
width: 100%;
overflow: hidden;
}
&__win-info {
position: absolute;
top: 47%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #0000001a;
width: 80%;
margin: 0 auto;
border-radius: 20px;
padding: 12px 0;
z-index: 20;
}
&__title {
width: 100%;
text-align: center;
color: #fff;
font-weight: 500;
font-size: 14px;
height: 18px;
margin-bottom: 7px;
}
&__prize-img {
margin-bottom: 7px;
background-size: 100% 100%;
width: 65px;
height: 65px;
display: flex;
justify-content: center;
align-items: center;
img {
display: block;
width: 60%;
height: 60%;
}
}
&__prize-name {
width: 100%;
padding: 0 10px;
font-size: 12px;
color: #fff;
margin-top: 11px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-align: center;
}
&__thanks {
position: absolute;
top: 47%;
left: 50%;
transform: translate(-50%, -50%);
height: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
p {
margin-bottom: 10px;
font-size: 18px;
}
}
&__footer {
position: absolute;
bottom: 14%;
left: 50%;
transform: translateX(-50%);
width: 157px;
height: 49px;
img {
width: 100%;
height: 100%;
}
}
&__header {
position: absolute;
top: 12%;
left: 50%;
transform: translateX(-50%);
width: 100%;
height: 27px;
text-align: center;
img {
height: 100%;
}
}
&__sure {
width: 126px;
height: 33px;
line-height: 33px;
border: 0;
outline: none;
/deep/ .van-button__text {
font-size: 13px;
color: #fb1f34;
font-weight: 500;
}
}
&__win-msg {
margin: 13px 0 20px;
font-size: 12px;
color: #fff;
}
}
</style>
<template>
<section class="lottery-instant">
<div class="lottery-instant__main">
<CountdownBar class="lottery-instant__countdown" :bar-style="barStyle"></CountdownBar>
<div class="lottery-instant__layout-gashapon">
<div class="content-main">
<PrizeGashapon ref="prizeGashaponRef" :ball-list-gashapon="ballListGashapon" @endCallBack="endCallBack" />
</div>
<div class="lottery-instant__content-gashapon">
<div class="game-bg">
<img src="@/assets/images/lottery/gashapon/game-bg.png" />
</div>
<div class="on-start" @click="startLottery">
<div class="lottery-instant__times" :style="btnTextColor">
抽奖次数:<span>{{ lotteryInfo.userTimes }}</span
>
</div>
<img :src="btnImg" />
</div>
</div>
</div>
</div>
<WinPopupNew :value="isShowWin" :info="winInfo" :win-config="winConfig">
<template #thanks>
<div class="slot-thanks">你没有扭到奖品</div>
</template>
</WinPopupNew>
<BindPhoneDialog :value="isShowBindPhone"></BindPhoneDialog>
<Records :records-config="recordsConfig"></Records>
<Introduction
class="lottery-instant__intro"
:title-text="introConfig.titleText"
:rule="introConfig.rule"
:title-style="introConfig.introTitleStyle"
:wrap-style="introConfig.introWrapStyle"
:content-style="introConfig.introContentStyle"
:intro-box-style="introConfig.introBoxStyle"
></Introduction>
</section>
</template>
<script>
import { PrizeGashapon } from 'lotteries'
import onStartImg from '@/assets/images/lottery/gashapon/on-start.png'
import onStartDidabledImg from '@/assets/images/lottery/gashapon/on-start-disabled.png'
import { mapGetters } from 'vuex'
import { LOTTERY_STATUS } from '@/utils/constant'
import Bus from '@/utils/Bus'
import {
introductionConfigGashapon,
winConfigGashapon,
recordsConfigGashapon,
ballListGashapon,
countDownBarPurple
} from './config'
export default {
components: {
CountdownBar: () => import('@/components/Lottery/Instant/CountdownBar'),
WinPopupNew: () => import('@/components/Lottery/Instant/WinPopupNew'),
BindPhoneDialog: () => import('@/components/Common/BindPhoneDialog'),
Introduction: () => import('@/components/Lottery/Instant/Introduction'),
Records: () => import('@/components/Lottery/Instant/Records'),
PrizeGashapon
},
props: {
winInfo: {
type: Object,
default: () => ({})
},
isShowWin: {
type: Boolean,
default: false
},
isShowBindPhone: {
type: Boolean,
default: false
},
isLottering: {
type: Boolean,
default: false
},
isLoading: {
type: Boolean,
default: false
}
},
data() {
return {
id: this.$route.query.id || null, // 抽奖id
playId: this.$route.query.sessionId || null, // 场次id
sid: this.$route.query.sid || null, // 引用id
stype: this.$route.query.stype || null, // 引用类型
recordsConfig: recordsConfigGashapon, // 中奖记录样式配置
winConfig: winConfigGashapon, // 开奖样式
introConfig: introductionConfigGashapon,
barStyle: countDownBarPurple,
ballListGashapon // 扭蛋球图片
}
},
computed: {
...mapGetters({
uin: 'users/uin',
isLogin: 'users/isLogin',
lotteryInfo: 'lottery/lotteryInfo',
isBindPhone: 'users/isBindPhone'
}),
isNotStart() {
// 抽奖不在活动日期内
const { status } = this.lotteryInfo
return +status !== LOTTERY_STATUS.start
},
// 按钮图片样式
btnImg() {
if (!this.lotteryInfo.userTimes || this.isNotStart) {
return onStartDidabledImg
}
return onStartImg
},
btnTextColor() {
if (!this.lotteryInfo.userTimes || this.isNotStart) {
return {
color: '#6d6d6d'
}
}
return {
color: '#610ca1'
}
}
},
methods: {
startLottery() {
Bus.$emit('updateMain', { func: 'startLottery' })
},
drawAnimation() {
this.$refs.prizeGashaponRef.onStart()
},
endCallBack() {
Bus.$emit('updateMain', { isLottering: false })
setTimeout(() => {
Bus.$emit('updateMain', { isShowWin: true })
}, 400)
}
}
}
</script>
<style lang="less" scoped>
.lottery-instant {
position: relative;
height: 100%;
background-color: #631e88 !important;
background-image: url('@/assets/images/lottery/gashapon/page-bg.png') !important;
background-size: cover;
background-position: top center;
background-repeat: no-repeat;
padding: 0;
overflow: auto;
-webkit-overflow-scrolling: touch;
&__countdown {
padding-top: 18px;
}
&__layout-gashapon {
position: relative;
// background-image: url('@/assets/images/lottery/gashapon/game-bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
width: 100%;
height: 0;
padding-top: 398 / 375 * 100%;
margin-top: 7px;
.content-main {
position: absolute;
top: 2%;
left: 52%;
width: 210px;
height: 210px;
transform: translateX(-50%);
z-index: 10;
}
}
&__content-gashapon {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
font-size: 20px;
text-align: center;
z-index: 20;
.game-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
img {
width: 100%;
object-fit: cover;
}
}
.on-start {
position: absolute;
right: 20%;
bottom: 3.5%;
width: 32%;
height: 19%;
img {
width: 100%;
object-fit: cover;
}
}
}
&__times {
position: absolute;
bottom: 29%;
left: 50%;
transform: translateX(-50%);
font-size: 12px;
white-space: nowrap;
}
}
</style>
<template>
<section class="lottery-instant">
<div class="lottery-instant__title">
<img src="@/assets/images/lottery/gashapon2/page-title.png" />
</div>
<div class="lottery-instant__main">
<div class="lottery-instant__countdown">
<CountdownBar :bar-style="barStyle"></CountdownBar>
</div>
<div class="lottery-instant__layout-gashapon">
<div class="content-main">
<PrizeGashapon ref="prizeGashaponRef" :ball-list-gashapon="ballListGashapon" @endCallBack="endCallBack" />
</div>
<div class="lottery-instant__content-gashapon">
<div class="on-start" @click="startLottery">
<div class="lottery-instant__times">
抽奖次数:<span>{{ lotteryInfo.userTimes }}</span
>
</div>
<img :src="buttonImg" />
</div>
</div>
</div>
</div>
<WinPopupNew :value="isShowWin" :info="winInfo" :win-config="winConfig">
<template #thanks>
<div class="slot-thanks">你没有扭到奖品</div>
</template>
</WinPopupNew>
<BindPhoneDialog :value="isShowBindPhone"></BindPhoneDialog>
<Records :records-config="recordsConfig"></Records>
<Introduction
class="lottery-instant__intro"
:title-text="introConfig.titleText"
:rule="introConfig.rule"
:title-style="introConfig.introTitleStyle"
:wrap-style="introConfig.introWrapStyle"
:content-style="introConfig.introContentStyle"
:intro-box-style="introConfig.introBoxStyle"
></Introduction>
</section>
</template>
<script>
import { PrizeGashapon } from 'lotteries'
import onStartImg from '@/assets/images/lottery/gashapon2/on-start.png'
import onStartDidabledImg from '@/assets/images/lottery/gashapon2/on-start-disabled.png'
import { mapGetters } from 'vuex'
import { LOTTERY_STATUS } from '@/utils/constant'
import Bus from '@/utils/Bus'
import {
introductionConfigGashapon2 as introductionConfigGashapon,
winConfigGashapon2 as winConfigGashapon,
recordsConfigGashapon2 as recordsConfigGashapon,
ballListGashapon,
countDownBarNone
} from './config'
export default {
components: {
CountdownBar: () => import('@/components/Lottery/Instant/CountdownBar'),
WinPopupNew: () => import('@/components/Lottery/Instant/WinPopupNew'),
BindPhoneDialog: () => import('@/components/Common/BindPhoneDialog'),
Introduction: () => import('@/components/Lottery/Instant/Introduction'),
Records: () => import('@/components/Lottery/Instant/Records'),
PrizeGashapon
},
props: {
winInfo: {
type: Object,
default: () => ({})
},
isShowWin: {
type: Boolean,
default: false
},
isShowBindPhone: {
type: Boolean,
default: false
},
isLottering: {
type: Boolean,
default: false
},
isLoading: {
type: Boolean,
default: false
}
},
data() {
return {
id: this.$route.query.id || null, // 抽奖id
playId: this.$route.query.sessionId || null, // 场次id
sid: this.$route.query.sid || null, // 引用id
stype: this.$route.query.stype || null, // 引用类型
recordsConfig: recordsConfigGashapon, // 中奖记录样式配置
winConfig: winConfigGashapon, // 开奖样式
introConfig: introductionConfigGashapon,
barStyle: countDownBarNone,
ballListGashapon // 扭蛋球图片
}
},
computed: {
...mapGetters({
uin: 'users/uin',
isLogin: 'users/isLogin',
lotteryInfo: 'lottery/lotteryInfo',
isBindPhone: 'users/isBindPhone'
}),
isNotStart() {
// 抽奖不在活动日期内
const { status } = this.lotteryInfo
return +status !== LOTTERY_STATUS.start
},
// 按钮图片样式
buttonImg() {
if (!this.lotteryInfo.userTimes || this.isNotStart) {
return onStartDidabledImg
}
return onStartImg
}
},
methods: {
startLottery() {
Bus.$emit('updateMain', { func: 'startLottery' })
},
drawAnimation() {
this.$refs.prizeGashaponRef.onStart()
},
endCallBack() {
Bus.$emit('updateMain', { isLottering: false })
setTimeout(() => {
Bus.$emit('updateMain', { isShowWin: true })
}, 400)
}
}
}
</script>
<style lang="less" scoped>
.lottery-instant {
position: relative;
height: 100%;
background-color: #631e88 !important;
background-image: url('@/assets/images/lottery/gashapon2/page-bg.png') !important;
background-size: cover;
background-position: top center;
background-repeat: no-repeat;
padding: 0;
overflow: auto;
-webkit-overflow-scrolling: touch;
&__countdown {
position: absolute;
top: 16px;
left: 50%;
transform: translateX(-50%);
z-index: 2;
}
&__times {
position: absolute;
bottom: 12%;
left: 50%;
transform: translateX(-50%);
font-size: 13px;
color: #fff;
}
&__layout-gashapon {
position: relative;
background-image: url('@/assets/images/lottery/gashapon2/game-bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
width: 100%;
height: 0;
padding-top: 416 / 375 * 100%;
margin-top: 7px;
.content-main {
position: absolute;
top: 11.5%;
left: 50%;
width: 180px;
height: 180px;
transform: translateX(-50%);
z-index: 10;
}
}
&__content-gashapon {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
font-size: 20px;
text-align: center;
z-index: 20;
.on-start {
position: absolute;
left: 50%;
bottom: 34%;
transform: translateX(-50%);
width: 51%;
height: 17.6%;
img {
width: 100%;
object-fit: cover;
}
}
}
&__main {
position: relative;
}
&__title {
width: 80%;
height: 6%;
margin: 32px auto 26px auto;
line-height: 0;
img {
width: 100%;
height: 100%;
}
}
}
</style>
<template>
<section class="lottery-instant">
<div class="lottery-instant__main">
<CountdownBar class="lottery-instant__countdown" :bar-style="barStyle"></CountdownBar>
<div class="lottery-instant__layout-gashapon">
<div class="content-main">
<PrizeGashapon ref="prizeGashaponRef" :ball-list-gashapon="ballListGashapon" @endCallBack="endCallBack" />
</div>
<div class="lottery-instant__content-gashapon">
<div class="game-bg">
<img src="@/assets/images/lottery/gashapon/game-bg.png" />
</div>
<div class="on-start" @click="startLottery">
<div class="lottery-instant__times" :style="btnTextColor">
抽奖次数:<span>{{ lotteryInfo.userTimes }}</span
>
</div>
<img :src="btnImg" />
</div>
</div>
</div>
</div>
<div class="lottery-instant__intro-entry" @click="changeIsShowIntro">活动介绍</div>
<WinPopupNew :value="isShowWin" :info="winInfo" :win-config="winConfig">
<template #thanks>
<div class="slot-thanks">你没有扭到奖品</div>
</template>
</WinPopupNew>
<BindPhoneDialog :value="isShowBindPhone"></BindPhoneDialog>
<Records :records-config="recordsConfig"></Records>
<IntroductionPopup
:value="isShowIntro"
:wrap-style="introConfig.introWrapStyle"
:content-style="introConfig.introContentStyle"
:popup-style="introConfig.introPopupStyle"
:content-box-style="introConfig.contentBoxStyle"
:back-style="introConfig.backStyle"
:rule="introConfig.rule"
></IntroductionPopup>
</section>
</template>
<script>
import { PrizeGashapon } from 'lotteries'
import onStartImg from '@/assets/images/lottery/gashapon/on-start.png'
import onStartDidabledImg from '@/assets/images/lottery/gashapon/on-start-disabled.png'
import { mapGetters } from 'vuex'
import { LOTTERY_STATUS } from '@/utils/constant'
import Bus from '@/utils/Bus'
import {
introductionConfigGashaponMini,
winConfigGashapon,
recordsConfigGashapon,
ballListGashapon,
countDownBarPurple
} from './config'
export default {
components: {
CountdownBar: () => import('@/components/Lottery/Instant/CountdownBar'),
WinPopupNew: () => import('@/components/Lottery/Instant/WinPopupNew'),
BindPhoneDialog: () => import('@/components/Common/BindPhoneDialog'),
Records: () => import('@/components/Lottery/Instant/Records'),
IntroductionPopup: () => import('@/components/Lottery/Instant/IntroductionPopup'),
PrizeGashapon
},
props: {
winInfo: {
type: Object,
default: () => ({})
},
isShowWin: {
type: Boolean,
default: false
},
isShowBindPhone: {
type: Boolean,
default: false
},
isLottering: {
type: Boolean,
default: false
},
isLoading: {
type: Boolean,
default: false
},
isShowIntro: {
type: Boolean,
default: false
}
},
data() {
return {
id: this.$route.query.id || null, // 抽奖id
playId: this.$route.query.sessionId || null, // 场次id
sid: this.$route.query.sid || null, // 引用id
stype: this.$route.query.stype || null, // 引用类型
recordsConfig: recordsConfigGashapon, // 中奖记录样式配置
winConfig: winConfigGashapon, // 开奖样式
introConfig: introductionConfigGashaponMini,
barStyle: countDownBarPurple,
ballListGashapon // 扭蛋球图片
}
},
computed: {
...mapGetters({
uin: 'users/uin',
isLogin: 'users/isLogin',
lotteryInfo: 'lottery/lotteryInfo',
isBindPhone: 'users/isBindPhone'
}),
isNotStart() {
// 抽奖不在活动日期内
const { status } = this.lotteryInfo
return +status !== LOTTERY_STATUS.start
},
// 按钮图片样式
btnImg() {
if (!this.lotteryInfo.userTimes || this.isNotStart) {
return onStartDidabledImg
}
return onStartImg
},
btnTextColor() {
if (!this.lotteryInfo.userTimes || this.isNotStart) {
return {
color: '#6d6d6d'
}
}
return {
color: '#610ca1'
}
}
},
methods: {
startLottery() {
Bus.$emit('updateMain', { func: 'startLottery' })
},
drawAnimation() {
this.$refs.prizeGashaponRef.onStart()
},
endCallBack() {
Bus.$emit('updateMain', { isLottering: false })
setTimeout(() => {
Bus.$emit('updateMain', { isShowWin: true })
}, 400)
},
changeIsShowIntro() {
Bus.$emit('updateMain', { isShowIntro: true })
}
}
}
</script>
<style lang="less" scoped>
.lottery-instant {
position: relative;
height: 100%;
background-color: #631e88 !important;
background-image: url('@/assets/images/lottery/gashapon/page-bg.png') !important;
background-size: cover;
background-position: top center;
background-repeat: no-repeat;
padding: 0;
overflow: auto;
-webkit-overflow-scrolling: touch;
&__countdown {
padding-top: 18px;
}
&__layout-gashapon {
position: relative;
// background-image: url('@/assets/images/lottery/gashapon/game-bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
width: 100%;
height: 0;
padding-top: 398 / 375 * 100%;
margin-top: 7px;
.content-main {
position: absolute;
top: 4%;
left: 52%;
width: 210px;
height: 210px;
transform: translateX(-50%);
z-index: 10;
}
}
&__content-gashapon {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
font-size: 20px;
text-align: center;
z-index: 20;
.game-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
img {
width: 100%;
object-fit: cover;
}
}
.on-start {
position: absolute;
right: 20%;
bottom: 3.5%;
width: 32%;
height: 19%;
img {
width: 100%;
object-fit: cover;
}
}
}
&__times {
position: absolute;
bottom: 29%;
left: 50%;
transform: translateX(-50%);
font-size: 12px;
white-space: nowrap;
}
&__intro-entry {
position: fixed;
top: 56px;
right: 0;
background: linear-gradient(180deg, #ffd63e 0%, #fca60d 100%);
box-shadow: 0px 1px 2px 0px rgba(202, 146, 46, 1);
color: #9c5c00;
font-size: 12px;
writing-mode: vertical-lr;
padding: 6px 3px;
border-radius: 10px 0 0 10px;
}
}
</style>
<template>
<section class="lottery-instant">
<div class="lottery-instant__countdown">
<CountdownBar :bar-style="barStyle"></CountdownBar>
</div>
<div class="lottery-instant__main">
<div class="lottery-instant__layout-gashapon">
<div class="content-main">
<PrizeGashapon ref="prizeGashaponRef" :ball-list-gashapon="ballListGashapon" @endCallBack="endCallBack" />
</div>
<div class="lottery-instant__content-gashapon">
<div class="on-start" @click="startLottery">
<div class="lottery-instant__times">
抽奖次数:<span>{{ lotteryInfo.userTimes }}</span
>
</div>
<img :src="buttonImg" />
</div>
</div>
</div>
</div>
<div class="lottery-instant__intro-entry" @click="changeIsShowIntro">活动介绍</div>
<WinPopupNew :value="isShowWin" :info="winInfo" :win-config="winConfig">
<template #thanks>
<div class="slot-thanks">你没有扭到奖品</div>
</template>
</WinPopupNew>
<BindPhoneDialog :value="isShowBindPhone"></BindPhoneDialog>
<Records :records-config="recordsConfig"></Records>
<IntroductionPopup
:value="isShowIntro"
:wrap-style="introConfig.introWrapStyle"
:content-style="introConfig.introContentStyle"
:popup-style="introConfig.introPopupStyle"
:content-box-style="introConfig.contentBoxStyle"
:back-style="introConfig.backStyle"
:rule="introConfig.rule"
></IntroductionPopup>
</section>
</template>
<script>
import { PrizeGashapon } from 'lotteries'
import onStartImg from '@/assets/images/lottery/gashapon2/on-start.png'
import onStartDidabledImg from '@/assets/images/lottery/gashapon2/on-start-disabled.png'
import { mapGetters } from 'vuex'
import { LOTTERY_STATUS } from '@/utils/constant'
import Bus from '@/utils/Bus'
import {
introductionConfigGashaponMini2 as introductionConfigGashaponMini,
winConfigGashapon2 as winConfigGashapon,
recordsConfigGashapon2 as recordsConfigGashapon,
ballListGashapon,
countDownBarWhite
} from './config'
export default {
components: {
CountdownBar: () => import('@/components/Lottery/Instant/CountdownBar'),
WinPopupNew: () => import('@/components/Lottery/Instant/WinPopupNew'),
BindPhoneDialog: () => import('@/components/Common/BindPhoneDialog'),
Records: () => import('@/components/Lottery/Instant/Records'),
IntroductionPopup: () => import('@/components/Lottery/Instant/IntroductionPopup'),
PrizeGashapon,
},
props: {
winInfo: {
type: Object,
default: () => ({})
},
isShowWin: {
type: Boolean,
default: false
},
isShowBindPhone: {
type: Boolean,
default: false
},
isLottering: {
type: Boolean,
default: false
},
isLoading: {
type: Boolean,
default: false
},
isShowIntro: {
type: Boolean,
default: false
}
},
data() {
return {
id: this.$route.query.id || null, // 抽奖id
playId: this.$route.query.sessionId || null, // 场次id
sid: this.$route.query.sid || null, // 引用id
stype: this.$route.query.stype || null, // 引用类型
recordsConfig: recordsConfigGashapon, // 中奖记录样式配置
winConfig: winConfigGashapon, // 开奖样式
introConfig: introductionConfigGashaponMini,
barStyle: countDownBarWhite,
ballListGashapon // 扭蛋球图片
}
},
computed: {
...mapGetters({
uin: 'users/uin',
isLogin: 'users/isLogin',
lotteryInfo: 'lottery/lotteryInfo',
isBindPhone: 'users/isBindPhone'
}),
isNotStart() {
// 抽奖不在活动日期内
const { status } = this.lotteryInfo
return +status !== LOTTERY_STATUS.start
},
// 按钮图片样式
buttonImg() {
if (!this.lotteryInfo.userTimes || this.isNotStart) {
return onStartDidabledImg
}
return onStartImg
}
},
methods: {
startLottery() {
Bus.$emit('updateMain', { func: 'startLottery' })
},
drawAnimation() {
this.$refs.prizeGashaponRef.onStart()
},
endCallBack() {
Bus.$emit('updateMain', { isLottering: false })
setTimeout(() => {
Bus.$emit('updateMain', { isShowWin: true })
}, 400)
},
changeIsShowIntro() {
Bus.$emit('updateMain', { isShowIntro: true })
}
}
}
</script>
<style lang="less" scoped>
.lottery-instant {
position: relative;
height: 100%;
background-color: #631e88 !important;
background-image: url('@/assets/images/lottery/gashapon2/page-bg.png') !important;
background-size: cover;
background-position: top center;
background-repeat: no-repeat;
padding: 0;
overflow: auto;
-webkit-overflow-scrolling: touch;
&__countdown {
padding-top: 14px;
}
&__times {
position: absolute;
bottom: 12%;
left: 50%;
transform: translateX(-50%);
font-size: 13px;
color: #fff;
}
&__layout-gashapon {
position: relative;
background-image: url('@/assets/images/lottery/gashapon2/game-bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
width: 100%;
height: 0;
padding-top: 416 / 375 * 100%;
margin-top: 7px;
.content-main {
position: absolute;
top: 11.5%;
left: 50%;
width: 180px;
height: 180px;
transform: translateX(-50%);
z-index: 10;
}
}
&__content-gashapon {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
font-size: 20px;
text-align: center;
z-index: 20;
.on-start {
position: absolute;
left: 50%;
bottom: 34%;
transform: translateX(-50%);
width: 51%;
height: 17.6%;
img {
width: 100%;
object-fit: cover;
}
}
}
&__main {
position: relative;
}
&__intro-entry {
position: fixed;
top: 56px;
right: 0;
background: linear-gradient(180deg, #ffd63e 0%, #fca60d 100%);
box-shadow: 0px 1px 2px 0px rgba(202, 146, 46, 1);
color: #9c5c00;
font-size: 12px;
writing-mode: vertical-lr;
padding: 6px 3px;
border-radius: 10px 0 0 10px;
}
}
</style>
<template>
<section class="lottery-instant">
<div class="lottery-instant__main">
<img class="lottery-instant__title" src="@/assets/images/lottery/guess/game-title.png" />
<CountdownBar class="lottery-instant__countdown" :bar-style="barStyle"></CountdownBar>
<div class="lottery-instant__layout-guess">
<div class="content-img">
<div v-for="(item, index) in starConfig" :key="index" class="content-img--star" :style="item">
<img src="@/assets/images/lottery/guess/star.png" />
</div>
<img src="@/assets/images/lottery/guess/gift-main.png" />
</div>
<div class="content-main">
<div class="content-main-times">
抽奖次数:<span>{{ lotteryInfo.userTimes }}</span
>
</div>
<div class="content-main-box">
<PrizeGuess :blind-box-list="blindBoxList" @startLottery="startLottery">
<template #choose="{ index }">
<transition name="choose-fade">
<div v-show="chooseIndex === index" class="choose">选我</div>
</transition>
</template>
</PrizeGuess>
</div>
</div>
</div>
</div>
<WinPopupNew :value="isShowWin" :info="winInfo" :win-config="winConfig">
<template #thanks>
<div class="slot-thanks">你没有猜中</div>
</template>
</WinPopupNew>
<BindPhoneDialog :value="isShowBindPhone"></BindPhoneDialog>
<Records :records-config="recordsConfig"></Records>
<Introduction
class="lottery-instant__intro"
:title-text="introConfig.titleText"
:rule="introConfig.rule"
:title-style="introConfig.introTitleStyle"
:wrap-style="introConfig.introWrapStyle"
:content-style="introConfig.introContentStyle"
:intro-box-style="introConfig.introBoxStyle"
></Introduction>
</section>
</template>
<script>
import { PrizeGuess } from 'lotteries'
import { mapGetters } from 'vuex'
import Bus from '@/utils/Bus'
import {
blindBoxListGuess,
recordsConfigGuess,
winConfigGuess,
introductionConfigGuess,
countDownBarDeepPurple,
starConfig
} from './config'
export default {
components: {
CountdownBar: () => import('@/components/Lottery/Instant/CountdownBar'),
PrizeGuess,
WinPopupNew: () => import('@/components/Lottery/Instant/WinPopupNew'),
BindPhoneDialog: () => import('@/components/Common/BindPhoneDialog'),
Introduction: () => import('@/components/Lottery/Instant/Introduction'),
Records: () => import('@/components/Lottery/Instant/Records')
},
props: {
winInfo: {
type: Object,
default: () => ({})
},
isShowWin: {
type: Boolean,
default: false
},
isShowBindPhone: {
type: Boolean,
default: false
},
isLottering: {
type: Boolean,
default: false
},
isLoading: {
type: Boolean,
default: false
}
},
data() {
return {
id: this.$route.query.id || null, // 抽奖id
playId: this.$route.query.sessionId || null, // 场次id
sid: this.$route.query.sid || null, // 引用id
stype: this.$route.query.stype || null, // 引用类型
chooseIndex: 0,
timer: null,
blindBoxList: blindBoxListGuess,
recordsConfig: recordsConfigGuess, // 中奖记录样式配置
winConfig: winConfigGuess, // 开奖样式
introConfig: introductionConfigGuess,
barStyle: countDownBarDeepPurple,
starConfig
}
},
computed: {
...mapGetters({
uin: 'users/uin',
isLogin: 'users/isLogin',
lotteryInfo: 'lottery/lotteryInfo',
isBindPhone: 'users/isBindPhone'
})
},
mounted() {
this.startChooseScroll()
},
beforeDestroy() {
this.endChooseScroll()
},
methods: {
startChooseScroll() {
this.chooseIndex = 0
this.timer = setInterval(() => {
const indexTemp = Math.floor(Math.random() * (3 - 0 + 1)) + 0
if (indexTemp === this.chooseIndex && this.chooseIndex === 3) {
this.chooseIndex = 0
} else if (indexTemp === this.chooseIndex && this.chooseIndex !== 3) {
this.chooseIndex = indexTemp + 1
} else {
this.chooseIndex = indexTemp
}
}, 1000)
},
endChooseScroll() {
clearInterval(this.timer)
},
startLottery() {
Bus.$emit('updateMain', { func: 'startLottery' })
},
drawAnimation() {
Bus.$emit('updateMain', { isLottering: false })
setTimeout(() => {
Bus.$emit('updateMain', { isShowWin: true })
}, 400)
}
}
}
</script>
<style lang="less" scoped>
.lottery-instant {
position: relative;
height: 100%;
background-color: #631e88 !important;
background-image: url('@/assets/images/lottery/guess/page-bg.png') !important;
background-size: cover;
background-position: top center;
background-repeat: no-repeat;
padding: 0;
overflow: auto;
-webkit-overflow-scrolling: touch;
&__main {
text-align: center;
}
&__title {
width: 66.7%;
object-fit: cover;
margin-top: 28px;
}
&__countdown {
padding-top: 6px;
}
&__layout-guess {
padding: 0 15px;
.content-img {
position: relative;
width: 152px;
height: 154px;
margin: 10px auto 0 auto;
img {
width: 100%;
}
&--star {
position: absolute;
}
}
.content-main {
position: relative;
background-image: url('@/assets/images/lottery/guess/game-bg.png');
background-size: 100% 100%;
background-position: center;
width: 100%;
height: 0;
padding-top: 156 / 367 * 100%;
margin-top: 16px;
&-box {
position: absolute;
bottom: 20%;
left: 50%;
transform: translateX(-50%);
width: 90%;
height: 38%;
z-index: 20;
.choose {
position: absolute;
top: -40%;
left: 50%;
transform: translateX(-50%);
font-size: 12px;
background-color: #ffffffcc;
padding: 2px 6px;
white-space: nowrap;
border-radius: 9px;
z-index: -1;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translate(-50%, 100%);
width: 0;
height: 0;
border-top: 4px solid #ffffffcc;
border-bottom: 4px solid transparent;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
}
}
}
&-times {
position: absolute;
top: 20%;
left: 50%;
transform: translateX(-50%);
font-size: 12px;
color: #fff;
z-index: 10;
}
}
}
}
.choose-fade-enter-active {
transition: all 0.1s ease-in;
}
.choose-fade-leave-active {
transition: all 0.1s ease-out;
}
.choose-fade-enter,
.choose-fade-leave-to {
opacity: 0;
top: 0 !important;
}
</style>
<template>
<section class="lottery-instant">
<div class="lottery-instant__main">
<img class="lottery-instant__title" src="@/assets/images/lottery/guess/game-title.png" />
<CountdownBar class="lottery-instant__countdown" :bar-style="barStyle"></CountdownBar>
<div class="lottery-instant__layout-guess">
<div class="content-img">
<div v-for="(item, index) in starConfig" :key="index" class="content-img--star" :style="item">
<img src="@/assets/images/lottery/guess/star.png" />
</div>
<img src="@/assets/images/lottery/guess2/gift-main.png" />
</div>
<div class="content-main">
<div class="content-main-times">
抽奖次数:<span>{{ lotteryInfo.userTimes }}</span
>
</div>
<div class="content-main-box">
<PrizeGuess :blind-box-list="blindBoxList" @startLottery="startLottery">
<!-- <template #choose="{ index }">
<transition name="choose-fade">
<div v-show="chooseIndex === index" class="choose">选我</div>
</transition>
</template> -->
</PrizeGuess>
</div>
</div>
</div>
</div>
<WinPopupNew :value="isShowWin" :info="winInfo" :win-config="winConfig">
<template #thanks>
<div class="slot-thanks">你没有猜中</div>
</template>
</WinPopupNew>
<BindPhoneDialog :value="isShowBindPhone"></BindPhoneDialog>
<Records :records-config="recordsConfig"></Records>
<Introduction
class="lottery-instant__intro"
:title-text="introConfig.titleText"
:rule="introConfig.rule"
:title-style="introConfig.introTitleStyle"
:wrap-style="introConfig.introWrapStyle"
:content-style="introConfig.introContentStyle"
:intro-box-style="introConfig.introBoxStyle"
></Introduction>
</section>
</template>
<script>
import { PrizeGuess } from 'lotteries'
import { mapGetters } from 'vuex'
import Bus from '@/utils/Bus'
import {
blindBoxListGuess2,
recordsConfigGuess,
winConfigGuess,
introductionConfigGuess2 as introductionConfigGuess,
countDownBarDeepPurple,
starConfig
} from './config'
export default {
components: {
CountdownBar: () => import('@/components/Lottery/Instant/CountdownBar'),
PrizeGuess,
WinPopupNew: () => import('@/components/Lottery/Instant/WinPopupNew'),
BindPhoneDialog: () => import('@/components/Common/BindPhoneDialog'),
Introduction: () => import('@/components/Lottery/Instant/Introduction'),
Records: () => import('@/components/Lottery/Instant/Records')
},
props: {
winInfo: {
type: Object,
default: () => ({})
},
isShowWin: {
type: Boolean,
default: false
},
isShowBindPhone: {
type: Boolean,
default: false
},
isLottering: {
type: Boolean,
default: false
},
isLoading: {
type: Boolean,
default: false
}
},
data() {
return {
id: this.$route.query.id || null, // 抽奖id
playId: this.$route.query.sessionId || null, // 场次id
sid: this.$route.query.sid || null, // 引用id
stype: this.$route.query.stype || null, // 引用类型
chooseIndex: 0,
timer: null,
blindBoxList: blindBoxListGuess2,
recordsConfig: recordsConfigGuess, // 中奖记录样式配置
winConfig: winConfigGuess, // 开奖样式
introConfig: introductionConfigGuess,
barStyle: countDownBarDeepPurple,
starConfig
}
},
computed: {
...mapGetters({
uin: 'users/uin',
isLogin: 'users/isLogin',
lotteryInfo: 'lottery/lotteryInfo',
isBindPhone: 'users/isBindPhone'
})
},
// mounted() {
// this.startChooseScroll()
// },
// beforeDestroy() {
// this.endChooseScroll()
// },
methods: {
startChooseScroll() {
this.chooseIndex = 0
this.timer = setInterval(() => {
const indexTemp = Math.floor(Math.random() * (3 - 0 + 1)) + 0
if (indexTemp === this.chooseIndex && this.chooseIndex === 3) {
this.chooseIndex = 0
} else if (indexTemp === this.chooseIndex && this.chooseIndex !== 3) {
this.chooseIndex = indexTemp + 1
} else {
this.chooseIndex = indexTemp
}
}, 1000)
},
endChooseScroll() {
clearInterval(this.timer)
},
startLottery() {
Bus.$emit('updateMain', { func: 'startLottery' })
},
drawAnimation() {
Bus.$emit('updateMain', { isLottering: false })
setTimeout(() => {
Bus.$emit('updateMain', { isShowWin: true })
}, 400)
}
}
}
</script>
<style lang="less" scoped>
.lottery-instant {
position: relative;
height: 100%;
background-color: #631e88 !important;
background-image: url('@/assets/images/lottery/guess/page-bg.png') !important;
background-size: cover;
background-position: top center;
background-repeat: no-repeat;
padding: 0;
overflow: auto;
-webkit-overflow-scrolling: touch;
&__main {
text-align: center;
}
&__title {
width: 66.7%;
object-fit: cover;
margin-top: 28px;
}
&__countdown {
padding-top: 6px;
}
&__layout-guess {
padding: 0 15px;
.content-img {
position: relative;
width: 218px;
height: 205px;
margin: -10px auto 0 auto;
img {
width: 100%;
}
&--star {
position: absolute;
}
}
.content-main {
position: relative;
background-image: url('@/assets/images/lottery/guess/game-bg.png');
background-size: 100% 100%;
background-position: center;
width: 100%;
height: 0;
padding-top: 156 / 367 * 100%;
margin-top: 16px;
&-box {
position: absolute;
bottom: 20%;
left: 50%;
transform: translateX(-50%);
width: 90%;
height: 47%;
z-index: 20;
.choose {
position: absolute;
top: -40%;
left: 50%;
transform: translateX(-50%);
font-size: 12px;
background-color: #ffffffcc;
padding: 2px 6px;
white-space: nowrap;
border-radius: 9px;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translate(-50%, 100%);
width: 0;
height: 0;
border-top: 4px solid #ffffffcc;
border-bottom: 4px solid transparent;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
}
}
}
&-times {
position: absolute;
top: 20%;
left: 50%;
transform: translateX(-50%);
font-size: 12px;
color: #fff;
z-index: 10;
}
}
}
}
.choose-fade-enter-active {
transition: all 0.1s ease-in;
}
.choose-fade-leave-active {
transition: all 0.1s ease-out;
}
.choose-fade-enter,
.choose-fade-leave-to {
opacity: 0;
}
</style>
<template>
<section class="lottery-instant">
<div class="lottery-instant__main">
<img class="lottery-instant__title" src="@/assets/images/lottery/guess/game-title.png" />
<CountdownBar class="lottery-instant__countdown" :bar-style="barStyle"></CountdownBar>
<div class="lottery-instant__layout-guess">
<div class="content-img">
<div v-for="(item, index) in starConfig" :key="index" class="content-img--star" :style="item">
<img src="@/assets/images/lottery/guess/star.png" />
</div>
<img src="@/assets/images/lottery/guess/gift-main.png" />
</div>
<div class="content-main">
<div class="content-main-times">
抽奖次数:<span>{{ lotteryInfo.userTimes }}</span
>
</div>
<div class="content-main-box">
<PrizeGuess :blind-box-list="blindBoxList" @startLottery="startLottery">
<template #choose="{ index }">
<transition name="choose-fade">
<div v-show="chooseIndex === index" class="choose">选我</div>
</transition>
</template>
</PrizeGuess>
</div>
</div>
</div>
</div>
<div class="lottery-instant__intro-entry" @click="changeIsShowIntro">活动介绍</div>
<WinPopupNew :value="isShowWin" :info="winInfo" :win-config="winConfig">
<template #thanks>
<div class="slot-thanks">你没有猜中</div>
</template>
</WinPopupNew>
<BindPhoneDialog :value="isShowBindPhone"></BindPhoneDialog>
<Records :records-config="recordsConfig"></Records>
<IntroductionPopup
:value="isShowIntro"
:wrap-style="introConfig.introWrapStyle"
:content-style="introConfig.introContentStyle"
:popup-style="introConfig.introPopupStyle"
:content-box-style="introConfig.contentBoxStyle"
:back-style="introConfig.backStyle"
:rule="introConfig.rule"
></IntroductionPopup>
</section>
</template>
<script>
import { PrizeGuess } from 'lotteries'
import { mapGetters } from 'vuex'
import Bus from '@/utils/Bus'
import {
blindBoxListGuess,
recordsConfigGuess,
winConfigGuess,
introductionConfigGuessMini,
countDownBarDeepPurple,
starConfig
} from './config'
export default {
components: {
CountdownBar: () => import('@/components/Lottery/Instant/CountdownBar'),
PrizeGuess,
WinPopupNew: () => import('@/components/Lottery/Instant/WinPopupNew'),
BindPhoneDialog: () => import('@/components/Common/BindPhoneDialog'),
Records: () => import('@/components/Lottery/Instant/Records'),
IntroductionPopup: () => import('@/components/Lottery/Instant/IntroductionPopup')
},
props: {
winInfo: {
type: Object,
default: () => ({})
},
isShowWin: {
type: Boolean,
default: false
},
isShowBindPhone: {
type: Boolean,
default: false
},
isLottering: {
type: Boolean,
default: false
},
isLoading: {
type: Boolean,
default: false
},
isShowIntro: {
type: Boolean,
default: false
}
},
data() {
return {
id: this.$route.query.id || null, // 抽奖id
playId: this.$route.query.sessionId || null, // 场次id
sid: this.$route.query.sid || null, // 引用id
stype: this.$route.query.stype || null, // 引用类型
chooseIndex: 0,
timer: null,
blindBoxList: blindBoxListGuess,
recordsConfig: recordsConfigGuess, // 中奖记录样式配置
winConfig: winConfigGuess, // 开奖样式
introConfig: introductionConfigGuessMini,
barStyle: countDownBarDeepPurple,
starConfig
}
},
computed: {
...mapGetters({
uin: 'users/uin',
isLogin: 'users/isLogin',
lotteryInfo: 'lottery/lotteryInfo',
isBindPhone: 'users/isBindPhone'
})
},
mounted() {
this.startChooseScroll()
},
beforeDestroy() {
this.endChooseScroll()
},
methods: {
startChooseScroll() {
this.chooseIndex = 0
this.timer = setInterval(() => {
const indexTemp = Math.floor(Math.random() * (3 - 0 + 1)) + 0
if (indexTemp === this.chooseIndex && this.chooseIndex === 3) {
this.chooseIndex = 0
} else if (indexTemp === this.chooseIndex && this.chooseIndex !== 3) {
this.chooseIndex = indexTemp + 1
} else {
this.chooseIndex = indexTemp
}
}, 1000)
},
endChooseScroll() {
clearInterval(this.timer)
},
startLottery() {
Bus.$emit('updateMain', { func: 'startLottery' })
},
drawAnimation() {
Bus.$emit('updateMain', { isLottering: false })
setTimeout(() => {
Bus.$emit('updateMain', { isShowWin: true })
}, 400)
},
changeIsShowIntro() {
Bus.$emit('updateMain', { isShowIntro: true })
}
}
}
</script>
<style lang="less" scoped>
.lottery-instant {
position: relative;
height: 100%;
background-color: #631e88 !important;
background-image: url('@/assets/images/lottery/guess/page-bg-mini.png') !important;
background-size: cover;
background-position: top center;
background-repeat: no-repeat;
padding: 0 15px 22px;
overflow: auto;
-webkit-overflow-scrolling: touch;
&__main {
text-align: center;
}
&__title {
width: 66.7%;
object-fit: cover;
margin-top: 28px;
}
&__countdown {
padding-top: 6px;
}
&__layout-guess {
.content-img {
position: relative;
width: 152px;
height: 154px;
margin: 10px auto 0 auto;
img {
width: 100%;
}
&--star {
position: absolute;
}
}
.content-main {
position: relative;
background-image: url('@/assets/images/lottery/guess/game-bg.png');
background-size: 100% 100%;
background-position: center;
width: 100%;
height: 0;
padding-top: 156 / 367 * 100%;
margin-top: 16px;
&-box {
position: absolute;
bottom: 20%;
left: 50%;
transform: translateX(-50%);
width: 90%;
height: 38%;
z-index: 20;
.choose {
position: absolute;
top: -40%;
left: 50%;
transform: translateX(-50%);
font-size: 12px;
background-color: #ffffffcc;
padding: 2px 6px;
white-space: nowrap;
border-radius: 9px;
z-index: -1;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translate(-50%, 100%);
width: 0;
height: 0;
border-top: 4px solid #ffffffcc;
border-bottom: 4px solid transparent;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
}
}
}
&-times {
position: absolute;
top: 20%;
left: 50%;
transform: translateX(-50%);
font-size: 12px;
color: #fff;
z-index: 10;
}
}
}
&__intro-entry {
position: fixed;
top: 56px;
right: 0;
background: linear-gradient(180deg, #ffd63e 0%, #fca60d 100%);
box-shadow: 0px 1px 2px 0px rgba(202, 146, 46, 1);
color: #9c5c00;
font-size: 12px;
writing-mode: vertical-lr;
padding: 6px 3px;
border-radius: 10px 0 0 10px;
}
}
.slot-thanks {
font-size: 14px;
}
.choose-fade-enter-active {
transition: all 0.1s ease-in;
}
.choose-fade-leave-active {
transition: all 0.1s ease-out;
}
.choose-fade-enter,
.choose-fade-leave-to {
opacity: 0;
top: 0 !important;
}
</style>
<template>
<section class="lottery-instant">
<div class="lottery-instant__main">
<img class="lottery-instant__title" src="@/assets/images/lottery/guess/game-title.png" />
<CountdownBar class="lottery-instant__countdown" :bar-style="barStyle"></CountdownBar>
<div class="lottery-instant__layout-guess">
<div class="content-img">
<div v-for="(item, index) in starConfig" :key="index" class="content-img--star" :style="item">
<img src="@/assets/images/lottery/guess/star.png" />
</div>
<img src="@/assets/images/lottery/guess2/gift-main.png" />
</div>
<div class="content-main">
<div class="content-main-times">
抽奖次数:<span>{{ lotteryInfo.userTimes }}</span
>
</div>
<div class="content-main-box">
<PrizeGuess :blind-box-list="blindBoxList" @startLottery="startLottery">
<!-- <template #choose="{ index }">
<transition name="choose-fade">
<div v-show="chooseIndex === index" class="choose">选我</div>
</transition>
</template> -->
</PrizeGuess>
</div>
</div>
</div>
</div>
<div class="lottery-instant__intro-entry" @click="changeIsShowIntro">活动介绍</div>
<WinPopupNew :value="isShowWin" :info="winInfo" :win-config="winConfig">
<template #thanks>
<div class="slot-thanks">你没有猜中</div>
</template>
</WinPopupNew>
<BindPhoneDialog :value="isShowBindPhone"></BindPhoneDialog>
<Records :records-config="recordsConfig"></Records>
<IntroductionPopup
:value="isShowIntro"
:wrap-style="introConfig.introWrapStyle"
:content-style="introConfig.introContentStyle"
:popup-style="introConfig.introPopupStyle"
:content-box-style="introConfig.contentBoxStyle"
:back-style="introConfig.backStyle"
:rule="introConfig.rule"
></IntroductionPopup>
</section>
</template>
<script>
import { PrizeGuess } from 'lotteries'
import { mapGetters } from 'vuex'
import Bus from '@/utils/Bus'
import {
blindBoxListGuess2 as blindBoxListGuess,
recordsConfigGuess,
winConfigGuess,
introductionConfigGuessMini,
countDownBarDeepPurple,
starConfig
} from './config'
export default {
components: {
CountdownBar: () => import('@/components/Lottery/Instant/CountdownBar'),
PrizeGuess,
WinPopupNew: () => import('@/components/Lottery/Instant/WinPopupNew'),
BindPhoneDialog: () => import('@/components/Common/BindPhoneDialog'),
Records: () => import('@/components/Lottery/Instant/Records'),
IntroductionPopup: () => import('@/components/Lottery/Instant/IntroductionPopup')
},
props: {
winInfo: {
type: Object,
default: () => ({})
},
isShowWin: {
type: Boolean,
default: false
},
isShowBindPhone: {
type: Boolean,
default: false
},
isLottering: {
type: Boolean,
default: false
},
isLoading: {
type: Boolean,
default: false
},
isShowIntro: {
type: Boolean,
default: false
}
},
data() {
return {
id: this.$route.query.id || null, // 抽奖id
playId: this.$route.query.sessionId || null, // 场次id
sid: this.$route.query.sid || null, // 引用id
stype: this.$route.query.stype || null, // 引用类型
chooseIndex: 0,
timer: null,
blindBoxList: blindBoxListGuess,
recordsConfig: recordsConfigGuess, // 中奖记录样式配置
winConfig: winConfigGuess, // 开奖样式
introConfig: introductionConfigGuessMini,
barStyle: countDownBarDeepPurple,
starConfig
}
},
computed: {
...mapGetters({
uin: 'users/uin',
isLogin: 'users/isLogin',
lotteryInfo: 'lottery/lotteryInfo',
isBindPhone: 'users/isBindPhone'
})
},
// mounted() {
// this.startChooseScroll()
// },
// beforeDestroy() {
// this.endChooseScroll()
// },
methods: {
startChooseScroll() {
this.chooseIndex = 0
this.timer = setInterval(() => {
const indexTemp = Math.floor(Math.random() * (3 - 0 + 1)) + 0
if (indexTemp === this.chooseIndex && this.chooseIndex === 3) {
this.chooseIndex = 0
} else if (indexTemp === this.chooseIndex && this.chooseIndex !== 3) {
this.chooseIndex = indexTemp + 1
} else {
this.chooseIndex = indexTemp
}
}, 1000)
},
endChooseScroll() {
clearInterval(this.timer)
},
startLottery() {
Bus.$emit('updateMain', { func: 'startLottery' })
},
drawAnimation() {
Bus.$emit('updateMain', { isLottering: false })
setTimeout(() => {
Bus.$emit('updateMain', { isShowWin: true })
}, 400)
},
changeIsShowIntro() {
Bus.$emit('updateMain', { isShowIntro: true })
}
}
}
</script>
<style lang="less" scoped>
.lottery-instant {
position: relative;
height: 100%;
background-color: #631e88 !important;
background-image: url('@/assets/images/lottery/guess/page-bg-mini.png') !important;
background-size: cover;
background-position: top center;
background-repeat: no-repeat;
padding: 0 15px 22px;
overflow: auto;
-webkit-overflow-scrolling: touch;
&__main {
text-align: center;
}
&__title {
width: 66.7%;
object-fit: cover;
margin-top: 28px;
}
&__countdown {
padding-top: 6px;
}
&__layout-guess {
.content-img {
position: relative;
width: 218px;
height: 205px;
margin: -10px auto 0 auto;
img {
width: 100%;
}
&--star {
position: absolute;
}
}
.content-main {
position: relative;
background-image: url('@/assets/images/lottery/guess/game-bg.png');
background-size: 100% 100%;
background-position: center;
width: 100%;
height: 0;
padding-top: 156 / 367 * 100%;
margin-top: 16px;
&-box {
position: absolute;
bottom: 20%;
left: 50%;
transform: translateX(-50%);
width: 90%;
height: 47%;
z-index: 20;
.choose {
position: absolute;
top: -40%;
left: 50%;
transform: translateX(-50%);
font-size: 12px;
background-color: #ffffffcc;
padding: 2px 6px;
white-space: nowrap;
border-radius: 9px;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translate(-50%, 100%);
width: 0;
height: 0;
border-top: 4px solid #ffffffcc;
border-bottom: 4px solid transparent;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
}
}
}
&-times {
position: absolute;
top: 20%;
left: 50%;
transform: translateX(-50%);
font-size: 12px;
color: #fff;
z-index: 10;
}
}
}
&__intro-entry {
position: fixed;
top: 56px;
right: 0;
background: linear-gradient(180deg, #ffd63e 0%, #fca60d 100%);
box-shadow: 0px 1px 2px 0px rgba(202, 146, 46, 1);
color: #9c5c00;
font-size: 12px;
writing-mode: vertical-lr;
padding: 6px 3px;
border-radius: 10px 0 0 10px;
}
}
.slot-thanks {
font-size: 14px;
}
.choose-fade-enter-active {
transition: all 0.1s ease-in;
}
.choose-fade-leave-active {
transition: all 0.1s ease-out;
}
.choose-fade-enter,
.choose-fade-leave-to {
opacity: 0;
}
</style>
<template>
<section class="lottery-instant">
<div class="lottery-instant__main">
<CountdownBar class="lottery-instant__countdown" :bar-style="barStyle"></CountdownBar>
<div class="lottery-instant__layout-scratch">
<div class="lottery-instant__content-scratch">
<img class="content-title" src="@/assets/images/lottery/scratch/game-title.png" alt="" />
<div class="content-main">
<PrizeScratch ref="prizeScratchRef" :cover-img="coverImg" @endCallBack="endCallBack">
<template #item>
<div class="win__wrap">
<div class="win__content">
<div v-if="isWin" class="win__content-win">
<div class="win__content-win-title">恭喜获得</div>
<div class="win__content-win-img">
<img src="@/assets/images/lottery/gift.png" alt="" />
</div>
<div class="win__content-win-name">
{{ winInfo.name }}
</div>
</div>
<div v-else class="win__content-thanks">谢谢参与,再接再厉</div>
</div>
</div>
</template>
<template #button>
<div v-show="!isLottering" class="lottery-instant__button-wrap">
<div class="lottery-instant__button-mask">
<div v-show="firstTimeLottering" class="lottery-instant__button-img">
<img :src="buttonImg" @click="startLottery" />
<div class="times">
今日次数<span>{{ lotteryInfo.userTimes }}</span
>
</div>
</div>
<div v-show="!firstTimeLottering" class="lottery-instant__button-continue">
<span @click="continueScratch"
>今日次数<span>{{ lotteryInfo.userTimes }}</span
>次,继续刮奖</span
>
</div>
</div>
</div>
</template>
</PrizeScratch>
</div>
</div>
</div>
</div>
<Records :records-config="recordsConfig"></Records>
<Introduction
class="lottery-instant__intro"
:rule="introConfig.rule"
:title-style="introConfig.introTitleStyle"
:wrap-style="introConfig.introWrapStyle"
:content-style="introConfig.introContentStyle"
:intro-box-style="introConfig.introBoxStyle"
></Introduction>
</section>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
import { PrizeScratch } from 'lotteries'
import { LOTTERY_STATUS } from '@/utils/constant'
import coverImg from '@/assets/images/lottery/scratch/mask.png'
import onStartImg from '@/assets/images/lottery/scratch/on-start.png'
import onStartDidabledImg from '@/assets/images/lottery/scratch/on-start-disabled.png'
import Bus from '@/utils/Bus'
import { introductionConfigScratch, recordsConfigScratch, countDownBarBlue } from './config'
export default {
components: {
CountdownBar: () => import('@/components/Lottery/Instant/CountdownBar'),
Introduction: () => import('@/components/Lottery/Instant/Introduction'),
Records: () => import('@/components/Lottery/Instant/Records'),
PrizeScratch
},
props: {
winInfo: {
type: Object,
default: () => ({})
},
isShowWin: {
type: Boolean,
default: false
},
isShowBindPhone: {
type: Boolean,
default: false
},
isLottering: {
type: Boolean,
default: false
},
isLoading: {
type: Boolean,
default: false
}
},
data() {
return {
coverImg,
firstTimeLottering: true,
id: this.$route.query.id || null, // 抽奖id
playId: this.$route.query.sessionId || null, // 场次id
sid: this.$route.query.sid || null, // 引用id
stype: this.$route.query.stype || null, // 引用类型
recordsConfig: recordsConfigScratch, // 中奖记录样式配置
introConfig: introductionConfigScratch,
barStyle: countDownBarBlue
}
},
computed: {
...mapGetters({
uin: 'users/uin',
isLogin: 'users/isLogin',
lotteryInfo: 'lottery/lotteryInfo',
isBindPhone: 'users/isBindPhone'
}),
isNotStart() {
// 抽奖不在活动日期内
const { status } = this.lotteryInfo
return +status !== LOTTERY_STATUS.start
},
// 按钮图片样式
buttonImg() {
if (!this.lotteryInfo.userTimes || this.isNotStart) {
return onStartDidabledImg
}
return onStartImg
},
isWin() {
return !!+this.winInfo.id
}
},
methods: {
...mapActions({ jumpToLogin: 'users/jumpToLogin', updateInfo: 'lottery/updateInfo' }),
// 开始抽奖
startLottery() {
Bus.$emit('updateMain', { func: 'startLottery' })
},
drawAnimation() {
//
},
// 刮奖结束回调
endCallBack() {
this.$toast({
message: '刮奖结束',
duration: 1500
})
Bus.$emit('updateMain', { isLottering: false })
if (this.lotteryInfo.userTimes === 0) {
this.$refs.prizeScratchRef.tryAgain()
this.firstTimeLottering = true
} else {
this.firstTimeLottering = false
}
},
// 继续刮奖
continueScratch() {
this.$refs.prizeScratchRef.tryAgain()
this.startLottery()
}
}
}
</script>
<style lang="less" scoped>
.lottery-instant {
position: relative;
height: 100%;
background-color: #83d4fd !important;
background-image: url('@/assets/images/lottery/scratch/page-bg.png') !important;
background-size: cover;
background-position: top center;
background-repeat: no-repeat;
padding: 0;
overflow: auto;
-webkit-overflow-scrolling: touch;
&__countdown {
padding-top: 18px;
}
&__main {
padding: 0 0.13rem;
}
&__layout-scratch {
position: relative;
background-image: url('@/assets/images/lottery/scratch/game-bg.png');
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
width: 100%;
height: 0;
padding-top: 363 / 355 * 100%;
margin-top: 7px;
}
&__content-scratch {
position: absolute;
left: 0;
top: 0;
padding: 90px 20px 30px 20px;
width: 100%;
height: 100%;
font-size: 20px;
text-align: center;
.content-title {
width: 74%;
object-fit: cover;
margin: 10px 0;
}
.content-prize {
font-size: 12px;
}
}
&__button {
&-wrap {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 40;
}
&-mask {
width: 100%;
height: 100%;
}
&-img {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
img {
width: 40%;
object-fit: cover;
}
.times {
position: absolute;
top: 70%;
left: 50%;
transform: translateX(-50%);
font-size: 12px;
color: #666;
}
}
&-continue {
position: absolute;
bottom: 6%;
left: 50%;
transform: translateX(-50%);
font-size: 12px;
color: #666;
}
}
.win {
&__wrap {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
&__content {
width: 90%;
height: 90%;
display: flex;
flex-direction: column;
justify-content: center;
background-color: #fff;
&-win {
&-title {
font-size: 16px;
margin-bottom: 3px;
color: #333;
}
&-img {
margin-bottom: 3px;
img {
width: 60px;
}
}
&-name {
font-size: 12px;
color: #666;
}
}
&-thanks {
font-size: 16px;
}
}
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment