Commit 1852220c by Lays-lzq

Merge branch 'feature/newDraw' into dev

parents 86d1aa33 e91fcc9b
......@@ -2,6 +2,13 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [1.3.1](https://gitlab.aodianyun.com/activities/web-lottery/compare/v1.3.0...v1.3.1) (2022-08-04)
### Features
* 新增手动设置抽奖 ([12bae56](https://gitlab.aodianyun.com/activities/web-lottery/commit/12bae567615aad29ef744b78cccf9f23cd2ea0af))
## [1.3.0](https://gitlab.aodianyun.com/activities/web-lottery/compare/v1.2.2...v1.3.0) (2022-04-26)
......
......@@ -13,6 +13,7 @@ export default {
data() {
return {
color: '',
bgColor: '',
entry: null,
body: null
}
......@@ -23,8 +24,9 @@ export default {
})
},
mounted() {
Bus.$on('initDeal', color => {
Bus.$on('initDeal', (color, bgColor) => {
this.color = color
this.bgColor = bgColor
this.init()
this.dealAnimation()
})
......@@ -44,7 +46,7 @@ export default {
height: '0.62667rem',
right: '0.13333rem',
bottom: '0.33333rem',
zIndex: 6,
zIndex: 51,
background: '#fff',
iconColor: '#80411a',
transition: 'all 0.25s cubic-bezier(0.55, 0, 0.1, 1)'
......@@ -52,6 +54,9 @@ export default {
if (this.color) {
Object.assign(defaultEntryStyle, { iconColor: this.color })
}
if (this.bgColor) {
Object.assign(defaultEntryStyle, { background: this.bgColor })
}
// eslint-disable-next-line no-undef
complaintsDeal({
......@@ -59,7 +64,7 @@ export default {
props: {
// rootFontSize: '.62667rem',
defaultEntryStyle,
zIndex: 999,
zIndex: 51,
uin,
url: window.location.href,
company: '管理员',
......@@ -94,14 +99,20 @@ export default {
dealAnimation() {
setTimeout(() => {
this.entry = document.querySelector('.entry')
this.entry.classList.add('sidebar-hidden-scroll')
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()
// this.dealScrollOff()
})
this.entry.addEventListener('click', () => {
if (this.entry && this.entry.classList.contains('sidebar-hidden-scroll')) {
this.entry.classList.remove('sidebar-hidden-scroll')
return false
}
})
}, 500)
},
......
......@@ -58,6 +58,10 @@ export default {
methods: {
...mapActions({ jumpToLogin: 'users/jumpToLogin' }),
openRecord() {
if (this.recordsLayouts && this.recordsLayouts.classList.contains('sidebar-hidden-scroll')) {
this.recordsLayouts.classList.remove('sidebar-hidden-scroll')
return false
}
if (!this.isLogin) {
this.$toast({
message: '请先登录,正在为您转跳',
......@@ -71,6 +75,10 @@ export default {
}
},
openRecordPopup(type) {
if (this.recordsLayouts && this.recordsLayouts.classList.contains('sidebar-hidden-scroll')) {
this.recordsLayouts.classList.remove('sidebar-hidden-scroll')
return false
}
this.activeTab = type
this.isShowRecordsPopup = true
},
......@@ -79,12 +87,13 @@ export default {
},
recordsAnimation() {
setTimeout(() => {
this.recordsLayouts.classList.add('sidebar-hidden-scroll')
this.body.addEventListener('touchstart', () => {
this.body.addEventListener('touchmove', this.recordsScrollOn)
// this.recordsScrollOff()
})
this.body.addEventListener('touchend', () => {
this.body.removeEventListener('touchmove', this.recordsScrollOn)
this.recordsScrollOff()
})
}, 500)
},
......@@ -108,7 +117,7 @@ export default {
.records {
&__layouts {
position: fixed;
z-index: 50;
z-index: 51;
right: 10px;
bottom: 90px;
transition: all 0.25s cubic-bezier(0.55, 0, 0.1, 1);
......
......@@ -13,23 +13,23 @@
<div class="records-popup__list-wrapper">
<div class="records-popup__personal-record">
<div class="records-popup__record-content">
<div class="records-popup__phone">
<!-- <div class="records-popup__phone">
领奖手机号:
<span v-if="isBindPhone">{{ userInfo.phone }}</span>
<span v-else class="records-popup__bind-phone" @click="bindMobile">绑定手机号</span>
</div>
</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__session-info">
<div class="records-popup__info-wrap">
<div v-if="session.length > 1" class="records-popup__session">
{{ NUMBER_LIST[index + 1] }}场次
</div>
<div class="records-popup__time">
<span>{{ (item.drawTime * 1000) | formatDate('MM-DD HH:mm:ss') }}</span>
<div style="display: flex; align-items: center">
<div style="margin: 0" class="records-popup__time">
{{ (session.drawTime * 1000) | formatDate('MM-DD') }}
</div>
<div class="records-popup__session">{{ session.drawPlay }}场直播福袋</div>
</div>
<div class="records-popup__prize-name">{{ session.prizeName }}</div>
</div>
<div class="records-popup__prize-name">{{ item.prizeName }}</div>
</div>
</li>
</ul>
......@@ -47,7 +47,16 @@
<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">
{{ item.userNick }} 获得 <span class="records-popup__prize-name">{{ item.prizeName }}</span>
<div class="records-popup__time">
{{ (item.startTime * 1000) | formatDate('MM-DD HH:mm') }}
<span v-if="item.showType === 6">福袋</span>
<span v-if="item.showType === 7">宝箱</span>
</div>
<div v-for="(i, ind) in item.data" :key="ind" class="records-popup__item-user">
<div style="margin-bottom: 13px; width: 84.5px">{{ i.userNick }}</div>
<div style="margin-bottom: 13px; margin-left: 16px">获得了</div>
<div style="margin-bottom: 13px; margin-left: 16px; color: #fe3924">{{ i.prizeName }}</div>
</div>
</div>
<div v-if="winnersList.length === 0" class="records-popup__no-data">暂无数据</div>
</div>
......@@ -95,7 +104,8 @@ export default {
...mapGetters({
uin: 'users/uin',
userInfo: 'users/userInfo',
isBindPhone: 'users/isBindPhone'
isBindPhone: 'users/isBindPhone',
lotteryInfo: 'lottery/lotteryInfo',
}),
visible: {
get() {
......@@ -177,8 +187,8 @@ export default {
<style lang='less' scoped>
.records-popup {
width: 258px;
height: 291px;
width: 251.5px;
height: 292px;
background: #ffe9d8;
border-radius: 15px;
overflow: visible;
......@@ -249,7 +259,7 @@ export default {
.van-tab__pane {
width: 100%;
height: 100%;
padding: 15px 0;
padding: 5px 0;
}
}
}
......@@ -287,6 +297,7 @@ export default {
color: #f57641;
}
&__record-list {
margin-top: 12px;
li {
margin-bottom: 15px;
&:last-child {
......@@ -306,21 +317,43 @@ export default {
&__info-wrap {
display: flex;
align-items: center;
font-size: 13px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
line-height: 18.5px;
justify-content: space-between;
}
&__session {
margin-right: 5px;
margin-left: 20px;
font-size: 13px;
color: #333;
}
&__time {
color: #666;
font-size: 13px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 18.5px;
margin-bottom: 13px;
}
&__prize-name {
margin: 8px 0 15px;
color: #666;
margin: 0 0 15px;
font-size: 13px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #fe3924;
line-height: 18.5px;
}
&__item {
margin-bottom: 8px;
&-user {
display: flex;
font-size: 13px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
line-height: 18.5px;
}
}
&__winners-record {
width: 100%;
......
<template>
<section class="join-button">
<div class="btn-box">
<section class="join-button" :class="lotteryInfo.showType === 7 ? 'treasure' : 'luckybag'">
<div class="btn-box" :style="{ '--btnBottom': btnBottom }">
<template v-if="+lotteryInfo.status === LOTTERY_STATUS.teaser">
<button v-if="lotteryInfo.condition === 1" class="join-btn pre">未开始</button>
<button v-if="lotteryInfo.condition === 2" class="join-btn pre countdown">
......@@ -10,22 +10,22 @@
</template>
<template v-if="+lotteryInfo.status === LOTTERY_STATUS.start">
<template v-if="lotteryInfo.userTimes === 0 && lotteryInfo.isDraw">
<button class="join-btn pre">待开奖</button>
<button class="join-btn pre">待开奖</button>
</template>
<template v-else>
<div class="btn-mask"></div>
<button class="join-btn" @click="lottery">点击参加</button>
<button class="join-btn" @click="lottery">立即参与</button>
</template>
</template>
<template v-if="+lotteryInfo.status === LOTTERY_STATUS.end">
<template v-if="isLogin && lotteryInfo.isDraw && lotteryInfo.isWin">
<div class="win-result-box">
<p class="win-result">恭喜您中奖!</p>
<button class="join-btn">恭喜您中奖!</button>
</div>
</template>
<template v-if="isLogin && lotteryInfo.isDraw && !lotteryInfo.isWin">
<div class="win-result-box">
<p class="win-result">很遗憾,您没有中奖</p>
<button class="join-btn end">很遗憾,您没有中奖</button>
</div>
</template>
<template v-if="!isLogin || !lotteryInfo.isDraw">
......@@ -33,9 +33,9 @@
</template>
</template>
</div>
<div v-if="+lotteryInfo.status !== LOTTERY_STATUS.end ? true : !isLogin || !lotteryInfo.isDraw" class="join-num">
<!-- <div v-if="+lotteryInfo.status !== LOTTERY_STATUS.end ? true : !isLogin || !lotteryInfo.isDraw" class="join-num">
已有 {{ lotteryInfo.activeNum }} 人参与
</div>
</div> -->
</section>
</template>
<script>
......@@ -54,13 +54,14 @@ export default {
data() {
return {
LOTTERY_STATUS,
timer: null
timer: null,
btnBottom: '' // 按钮下边距 为适应不同背景图
}
},
computed: {
...mapGetters({
isLogin: 'users/isLogin',
lotteryInfo: 'lottery/lotteryInfo'
lotteryInfo: 'lottery/lotteryInfo',
})
},
watch: {
......@@ -73,6 +74,11 @@ export default {
},
mounted() {
this.dateInit()
if (this.lotteryInfo.showType === 6) {
this.btnBottom = '-10px'
} else {
this.btnBottom = '20px'
}
},
methods: {
dateInit() {
......@@ -94,28 +100,29 @@ export default {
}
}
</script>
<style lang="less">
@--box-width: 100px;
@--box-height: @--box-width;
<style lang="less" scoped>
@--box-width: 194px;
@--box-height: 78px;
@keyframes wave {
0% {
opacity: 0.5;
}
100% {
opacity: 1;
transform: scale(1.1);
}
}
@keyframes wavetwo {
0% {
opacity: 1;
}
100% {
opacity: 0.5;
}
}
// @keyframes wave {
// 0% {
// opacity: 0.5;
// }
// 100% {
// opacity: 1;
// transform: scale(1.1);
// }
// }
// @keyframes wavetwo {
// 0% {
// opacity: 1;
// }
// 100% {
// opacity: 0.5;
// }
// }
.join-button {
height: 310px;
.btn-box {
width: @--box-width;
min-height: @--box-height;
......@@ -123,7 +130,7 @@ export default {
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
align-items: flex-end;
position: relative;
flex-wrap: wrap;
.btn-mask {
......@@ -137,32 +144,6 @@ export default {
margin: auto;
width: @--box-width - 16px;
height: @--box-height - 16px;
&::before {
content: '';
border-radius: 50%;
opacity: 0.5;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #fbaca6;
animation: wave 1s ease-out infinite;
}
&:after {
content: '';
border-radius: 50%;
opacity: 0.5;
position: absolute;
top: 0;
left: 0;
width: @--box-width - 16px;
height: @--box-height - 16px;
background-color: #fbaca6;
transform: scale(1.1);
animation: wavetwo 1s ease-out infinite;
// animation-delay: 0.5s;
}
}
.join-btn {
border: 0;
......@@ -173,16 +154,22 @@ export default {
width: @--box-width - 16px;
height: @--box-height - 16px;
line-height: @--box-height - 16px;
border-radius: 50%;
background-color: #e85c52;
margin-bottom: var(--btnBottom);
background: url(./img/button-light.png) no-repeat top;
outline: none;
position: relative;
z-index: 1;
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #db0000;
line-height: 70px;
&.pre {
background-color: #e77e7b;
color: #ffffff;
background: url(./img/button-dark.png) no-repeat top;
}
&.end {
background-color: #999;
color: #ffffff;
background: url(./img/button-dark.png) no-repeat top;
}
&.countdown {
font-size: 12px;
......@@ -219,4 +206,12 @@ export default {
text-align: center;
}
}
.treasure {
background: url(img/treasure.png) no-repeat center;
background-size: contain;
}
.luckybag {
background: url(img/luckybag.png) no-repeat center;
background-size: contain;
}
</style>
<template>
<section class="main-timing">
<TimingBanner class="timing-banner" :info="config[0]"></TimingBanner>
<div class="prize-info">
<label>奖品:</label>
<p>
<span class="text-name">{{ config[0].name }}</span>
<span class="text-num">x {{ config[0].sum }}</span>
</p>
</div>
<TimingStatus class="timing-status-box"></TimingStatus>
<JoinButton class="join-button-box" @lottery="lotteryCallback"></JoinButton>
<BackButton v-if="backUrl" class="back-box" :url="backUrl"></BackButton>
<Records></Records>
<WinPopup v-model="isShowWin" :info="winInfo"></WinPopup>
<BindPhoneDialog v-model="isShowBindPhone"></BindPhoneDialog>
</section>
<div class="main-timing">
<LuckyBag
v-if="lotteryInfo.showType === 6"
:is-btn-loading="isBtnLoading"
:is-show-win="isShowWin"
:is-show-bind-phone="isShowBindPhone"
:win-info="winInfo"
@lotteryCallback="lotteryCallback"
></LuckyBag>
<Treasure
v-if="lotteryInfo.showType === 7"
:is-btn-loading="isBtnLoading"
:is-show-win="isShowWin"
:is-show-bind-phone="isShowBindPhone"
:win-info="winInfo"
@lotteryCallback="lotteryCallback"
></Treasure>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
import { setLottery, getUserRecord } from '@/api/modules/lottery'
import Bus from '@/utils/Bus'
// banner
import TimingBanner from '@/components/Lottery/Timing/TimingBanner'
// 状态信息
import TimingStatus from '@/components/Lottery/Timing/TimingStatus'
// 参加按钮
import JoinButton from '@/components/Lottery/Timing/JoinButton'
// 返回直播间按钮
import BackButton from '@/components/Lottery/Timing/BackButton'
// 中奖弹窗
import WinPopup from '@/components/Lottery/Instant/WinPopup'
export default {
components: {
TimingBanner,
TimingStatus,
JoinButton,
BackButton,
WinPopup,
BindPhoneDialog: () => import('@/components/Common/BindPhoneDialog'),
Records: () => import('@/components/Lottery/Instant/Records')
LuckyBag: () => import('@/components/Lottery/Timing/type/LuckyBag'),
Treasure: () => import('@/components/Lottery/Timing/type/Treasure'),
// Records: () => import('@/components/Lottery/Instant/Records')
},
data() {
return {
......@@ -50,7 +37,8 @@ export default {
playId: this.$route.query.sessionId,
isShowWin: false,
isShowBindPhone: false, // 是否显示绑定手机号提示
winInfo: this.winInfoTranslator()
winInfo: this.winInfoTranslator(),
isShowIntro: false
}
},
computed: {
......@@ -98,7 +86,7 @@ export default {
})
},
// 中奖后, 关闭窗口回调
winCloseCallback(){
winCloseCallback() {
this.isShowWin = false
if (this.winInfo.id !== 0 && !this.isBindPhone) {
this.isShowBindPhone = true
......@@ -167,7 +155,7 @@ export default {
getUserRecord({
id: this.$route?.query?.id || '',
uin: this.$route?.query?.uin || '',
nowPlay: 1
nowPlay: this.lotteryInfo.nowPlay
}).then(res => {
const { code, errorCode, errorMessage, data } = res
if (code === 200 && errorCode === 0) {
......@@ -184,57 +172,16 @@ export default {
id: data?.prizeId || '',
name: data?.prizeName || ''
}
},
goRule() {
this.isShowIntro = true
}
}
}
</script>
<style lang="less">
<style lang="less" scoped>
.main-timing {
height: 100%;
position: relative;
.timing-banner {
padding-top: 115 / 330 * 100%;
position: relative;
}
.prize-info {
margin-top: 10px;
padding-left: 16px;
min-height: 20px;
line-height: 20px;
font-size: 16px;
display: flex;
align-items: center;
justify-content: left;
label {
min-width: 50px;
}
p {
flex: 1;
span {
color: #000;
&.text-num {
margin-left: 4px;
color: #999;
}
}
}
}
.timing-status-box {
padding-left: 16px;
margin-top: 10px;
height: 20px;
line-height: 20px;
font-size: 14px;
}
.join-button-box {
margin-top: 50px;
}
.back-box {
position: absolute;
bottom: 16px;
left: 0;
width: 100%;
border-radius: 22px;
}
}
</style>
<template>
<div class="main-timing">
<LuckyBag
v-if="lotteryInfo.showType === 6"
:is-mini="true"
:is-btn-loading="isBtnLoading"
:is-show-win="isShowWin"
:is-show-bind-phone="isShowBindPhone"
:win-info="winInfo"
:is-show-intro="isShowIntro"
class="bgluckybag"
@lotteryCallback="lotteryCallback"
@goRule="goRule"
></LuckyBag>
<Treasure
v-if="lotteryInfo.showType === 7"
:is-mini="true"
:is-btn-loading="isBtnLoading"
:is-show-win="isShowWin"
:is-show-bind-phone="isShowBindPhone"
:win-info="winInfo"
:is-show-intro="isShowIntro"
class="bgtreasure"
@lotteryCallback="lotteryCallback"
@goRule="goRule"
></Treasure>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
import { setLottery, getUserRecord } from '@/api/modules/lottery'
import Bus from '@/utils/Bus'
export default {
components: {
LuckyBag: () => import('@/components/Lottery/Timing/type/LuckyBag'),
Treasure: () => import('@/components/Lottery/Timing/type/Treasure'),
},
data() {
return {
isBtnLoading: false,
id: this.$route.query.id || '',
stype: this.$route.query.stype || null, // 引用类型
playId: this.$route.query.sessionId,
isShowWin: false,
isShowBindPhone: false, // 是否显示绑定手机号提示
winInfo: this.winInfoTranslator(),
isShowIntro: false
}
},
computed: {
...mapGetters({
uin: 'users/uin',
isLogin: 'users/isLogin',
lotteryInfo: 'lottery/lotteryInfo',
isBindPhone: 'users/isBindPhone'
}),
backUrl() {
return this.$route.query.backUrl || ''
},
config() {
const list =
typeof this.lotteryInfo.prizeConfigs === 'object'
? Object.values(this.lotteryInfo.prizeConfigs)
: this.lotteryInfo.prizeConfigs
return list
}
},
watch: {
'lotteryInfo.isWin': {
handler(val) {
if (val) {
this.loadWinInfo()
}
},
deep: true
}
},
mounted() {
this.eventHubInit()
Bus.$emit('initDeal', '#db0000', '#ffdccb')
// this.loadWinInfo()
},
methods: {
...mapActions({ jumpToLogin: 'users/jumpToLogin', updateInfo: 'lottery/updateInfo' }),
eventHubInit() {
Bus.$on('updateMain', data => {
for (const [key, value] of Object.entries(data)) {
if (key === 'func') {
this[value]()
} else {
this[key] = value
}
}
})
},
// 中奖后, 关闭窗口回调
winCloseCallback() {
this.isShowWin = false
if (this.winInfo.id !== 0 && !this.isBindPhone) {
this.isShowBindPhone = true
}
},
// 中奖后, "查看奖品详情"回调
winCallback() {
this.isShowWin = false
if (this.winInfo.id !== 0) {
this.$router.push({
path: '/recordDetail',
query: {
tempId: this.winInfo.tempId,
uin: this.uin
}
})
}
},
// 抽奖回调
lotteryCallback() {
// 抽奖点击事件
if (!this.isLogin) {
this.$toast({
message: '请先登录',
duration: 1500,
onClose: () => {
this.jumpToLogin()
}
})
} else if (this.lotteryInfo.status !== 1) {
// 抽奖不在活动日期内
} else if (this.isBtnLoading) {
// 正在抽奖动画过程中或正在加载数据
} else if (this.lotteryInfo.userTimes <= 0) {
this.$toast('抽奖次数已用完')
} else {
this.isBtnLoading = true
const params = {
id: this.id,
uin: this.uin,
playId: this.playId,
type: this.stype || 'link',
sourceId: this.sid || this.id
}
setLottery(params).then(res => {
const { code, errorCode, errorMessage } = res
if (code === 200 && errorCode === 0) {
let times = this.lotteryInfo.userTimes
times--
let num = this.lotteryInfo.activeNum
num++
this.updateInfo({
userTimes: times,
isDraw: 1,
activeNum: num
})
this.$toast.success('参与成功')
this.isBtnLoading = false
} else {
this.$toast.fail(errorMessage)
}
})
}
},
loadWinInfo() {
getUserRecord({
id: this.$route?.query?.id || '',
uin: this.$route?.query?.uin || '',
nowPlay: this.lotteryInfo.nowPlay
}).then(res => {
const { code, errorCode, errorMessage, data } = res
if (code === 200 && errorCode === 0) {
this.winInfo = this.winInfoTranslator(data)
this.isShowWin = true
} else {
this.$toast(errorMessage)
}
})
},
winInfoTranslator(data) {
return {
...data,
id: data?.prizeId || '',
name: data?.prizeName || ''
}
},
goRule() {
this.isShowIntro = true
}
}
}
</script>
<style lang="less" scoped>
.main-timing {
height: 100%;
position: relative;
}
</style>
<template>
<div
class="main"
:style="{
height: this.$route.path === '/mini/index' ? '65.5vh' : lotteryInfo.showType === 7 ? '46.5vh' : '37.5vh'
}"
>
<div class="intro">
<div class="intro__title">活动介绍</div>
<div class="intro__sub">本场活动奖品:</div>
<div class="intro__rewards">
<div v-for="item in lotteryInfo.prizeConfigs" :key="item.id" class="intro__rewards-item">
<img :src="item.icon" alt="" />
<div>{{ item.name }}</div>
</div>
</div>
</div>
<div class="rule">
<div class="intro__title">活动规则</div>
<div class="rule__detail">
<div>1.每位用户每场有1次抽奖机会</div>
<div>2.活动时间到达后自动开奖,逾期未参与兑奖概不负责</div>
<div>3.违反平台用户规则的用户默认放弃抽奖机会</div>
<div>4.通过抽奖活的的礼物不可兑换成现金</div>
<div>5.本活动最终解释权归平台所有</div>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import { LOTTERY_STATUS } from '@/utils/constant'
// 倒计时逻辑处理
import CountDown from '@/mixins/CountDown'
export default {
mixins: [CountDown],
data() {
return {
LOTTERY_STATUS,
timer: null
}
},
computed: {
...mapGetters({
isLogin: 'users/isLogin',
lotteryInfo: 'lottery/lotteryInfo'
})
},
}
</script>
<style lang="less" scoped>
.main {
display: flex;
flex-direction: column;
justify-content: space-around;
.intro {
// margin-bottom: 24px;
height: 46.5%;
display: flex;
flex-direction: column;
justify-content: space-around;
&__title {
font-size: 16px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #fff6da;
line-height: 22.5px;
text-align: center;
}
&__sub {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #fff6da;
line-height: 20px;
// margin-top: 4%;
margin-left: 16px;
}
&__rewards {
width: 100%;
display: flex;
align-items: center;
justify-content: space-around;
margin-top: 15px;
&-item {
font-size: 13px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #fff6da;
line-height: 18.5px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
img {
width: 48px;
height: 48px;
}
div {
margin-top: 4px;
text-align: center;
}
}
}
}
.rule {
height: 48.5%;
display: flex;
flex-direction: column;
justify-content: space-around;
&__detail {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #fff6da;
line-height: 20px;
// margin-top: 15px;
margin-left: 16px;
}
}
}
</style>
<template>
<van-popup
v-model="visible"
:overlay="false"
position="bottom"
transition="van-fade"
class="introduction-popup"
z-index="49"
:class="lotteryInfo.showType === 7 ? 'bgtreasureColor' : 'bgluckybagColor'"
>
<div class="introduction-popup__main">
<Rewards></Rewards>
<div class="main-link" @click="visible = false">返回活动</div>
</div>
</van-popup>
</template>
<script>
import { mapGetters } from 'vuex'
import img from '@/assets/images/lottery/gift.png'
import Bus from '@/utils/Bus'
// 奖品介绍
import Rewards from '@/components/Lottery/Timing/Rewards'
export default {
name: 'Introduction',
components: {
Rewards
},
props: {
value: {
type: Boolean,
default: false
},
rulePosition: {
type: String,
default: 'top'
},
},
data() {
return {
img
}
},
computed: {
...mapGetters({ lotteryInfo: 'lottery/lotteryInfo' }),
visible: {
get() {
return this.value
},
set(val) {
Bus.$emit('updateMain', { isShowIntro: val })
}
}
},
methods: {
getContainer() {
return document.querySelector('.lottery-instant')
}
}
}
</script>
<style lang="less" scoped>
.introduction-popup {
width: 100%;
height: calc(100% - 46px);
&__main {
width: 100%;
border-radius: 6px;
padding: 13px;
position: relative;
padding-top: 44px;
.main-link {
width: 24px;
height: 74px;
font-size: 12px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #db0000;
line-height: 13px;
writing-mode: tb-rl;
text-align: center;
background: url(img/link.png) no-repeat center;
background-size: cover;
position: absolute;
right: 0;
top: 20px;
padding-right: 3px;
}
}
}
.bgtreasureColor {
background-color: #ed112f;
}
.bgluckybagColor {
background-color: #fb3f42;
}
</style>
......@@ -30,7 +30,7 @@ export default {
}
}
</script>
<style lang="less">
<style lang="less" scoped>
.banner-box {
padding: 10px;
position: absolute;
......
<template>
<section class="timing-status">
<template v-if="type === 1">
<div v-if="state !== 2" class="countdown-box">
<label>倒计时:</label>
<p>
<span class="text-time">
<template v-if="hours > 0">{{ hours | filterNum }} : </template>{{ minutes | filterNum }} :
{{ seconds | filterNum }}
<template v-if="state === 0">后开始</template>
<template v-else-if="state === 1">后结束</template>
<div class="countdown-box">
<div v-if="state !== 2" class="countdown-box__time">
<label v-if="state === 0">抽奖倒计时:</label>
<label v-else-if="state === 1">开奖倒计时:</label>
<span v-if="lotteryInfo.startModel === 'manual' && state === 0">
00:{{ lotteryInfo.countDown | filterNum }}:00
</span>
</p>
<span v-else>
<template v-if="hours > 0">{{ hours | filterNum }}:</template>{{ minutes | filterNum }}:{{
seconds | filterNum
}}
</span>
</div>
<div v-else class="countdown-box__time">抽奖已结束</div>
</div>
<span v-else class="end-lottery">抽奖已结束</span>
</template>
<template v-if="type === 2">
<div class="joinnum-box">
......@@ -72,7 +75,7 @@ export default {
methods: {
dateInit() {
// 倒计时开始
if (this.state === 0) {
if (this.state === 0 && this.lotteryInfo.startModel !== 'manual') {
this.lotteryInfo.startTime && this.reloadTime(this.lotteryInfo.startTime * 1000)
} else if (this.state === 1) {
this.lotteryInfo.endTime && this.reloadTime(this.lotteryInfo.endTime * 1000)
......@@ -89,14 +92,30 @@ export default {
}
</script>
<style lang="less">
<style lang="less" scoped>
.timing-status {
position: relative;
z-index: 2;
.countdown-box {
display: flex;
align-items: center;
justify-content: left;
justify-content: center;
font-size: 13px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #fff6da;
line-height: 18.5px;
&__time {
display: flex;
align-items: center;
justify-content: center;
width: 144px;
height: 23px;
background: rgba(0, 0, 0, 0.21);
border-radius: 11.5px;
}
label {
color: #999999;
// color: #999999;
min-width: 58px;
}
p {
......
<template>
<van-popup
v-model="visible"
class="win-popup"
closeable
close-icon="close"
:style="{ background: 'transparent' }"
@click-close-icon="onClose"
>
<div v-if="type === 'luckybag'" class="lucky-popup__container">
<div class="lucky-popup__wrap">
<div class="lucky-popup__content">
<slot v-if="isWin" name="title-bg"></slot>
<div v-if="isWin" class="lucky-popup__win-info">
<div class="lucky-popup__title">恭喜获得</div>
<div class="lucky-popup__prize-img">
<img v-if="info.prizeIcon" :src="info.prizeIcon" alt="" />
<img v-else src="@/assets/images/lottery/gift.png" alt="" />
</div>
<div class="lucky-popup__prize-name">
{{ info.name }}
</div>
</div>
<div v-else class="lucky-popup__thanks">
<slot name="thanks">
<div
style="
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #fd0c2a;
line-height: 25px;
margin-bottom: 10px;
"
>
很遗憾
</div>
<div
style="
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #fd0c2a;
line-height: 20px;
"
>
您未抽中福袋
</div>
</slot>
</div>
</div>
<div class="lucky-popup__footer">
<van-button
class="lucky-popup__sure"
color="linear-gradient(180deg, #FEDF96, #FF8A42)"
round
@click="visible = false"
>我知道了</van-button
>
</div>
</div>
</div>
<div v-if="type === 'treasure'" class="treasure-popup__container">
<div class="treasure-popup__wrap">
<div class="treasure-popup__content">
<slot v-if="isWin" name="title-bg"></slot>
<div v-if="isWin" class="treasure-popup__win-info">
<div class="treasure-popup__title">恭喜获得</div>
<div class="treasure-popup__prize-img">
<img v-if="info.prizeIcon" :src="info.prizeIcon" alt="" />
<img v-else src="@/assets/images/lottery/gift.png" alt="" />
</div>
<div class="treasure-popup__prize-name">
{{ info.name }}
</div>
</div>
<div v-else class="treasure-popup__thanks">
<slot name="thanks">
<div
style="
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #fd0c2a;
line-height: 25px;
margin-bottom: 10px;
"
>
很遗憾
</div>
<div
style="
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #fd0c2a;
line-height: 20px;
"
>
您未抽中宝箱
</div>
</slot>
</div>
</div>
<div class="treasure-popup__footer">
<van-button
class="treasure-popup__sure"
color="linear-gradient(180deg, #FEDF96, #FF8A42)"
round
@click="visible = false"
>我知道了</van-button
>
</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: () => ({})
},
type: {
type: String,
default: ''
}
},
computed: {
visible: {
get() {
return this.value
},
set(val) {
Bus.$emit('updateMain', { isShowWin: val })
}
},
isWin() {
return !!+this.info.id
}
},
methods: {
know() {
Bus.$emit('updateMain', { func: 'winCallback' })
},
onClose() {
Bus.$emit('updateMain', { func: 'winCloseCallback' })
}
}
}
</script>
<style lang="less" scoped>
@containerWidth: 326px;
@wrapWidth: 275px;
@wrapHeight: 292px;
.win-popup {
overflow: visible;
/deep/ .van-popup__close-icon {
right: 10px;
top: -16px;
font-size: 22px;
color: #fff;
}
}
.lucky-popup {
&__container {
width: 100%;
height: 100%;
position: relative;
width: @containerWidth;
}
&__wrap {
margin: 0 auto;
width: 275px;
height: 321px;
overflow: hidden;
background-image: url('img/luckybag-popup.png');
background-size: cover;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
&__content {
color: #fff;
font-size: 16px;
height: 175px;
width: 100%;
overflow: hidden;
}
&__win-info {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
}
&__title {
width: 100%;
text-align: center;
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #fd0c2a;
line-height: 25px;
height: 18px;
margin: 7px 0 13px;
}
&__prize-img {
img {
display: block;
width: 65px;
}
}
&__prize-name {
width: 100%;
padding: 0 10px;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #fd0c2a;
line-height: 16.5px;
margin-top: 11px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-align: center;
}
&__thanks {
margin-top: -24px;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
&__footer {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 65px;
}
&__sure {
width: 126px;
height: 33px;
line-height: 33px;
border: 0;
outline: none;
/deep/ .van-button__text {
font-size: 14px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #c10000;
line-height: 20px;
}
}
&__win-msg {
margin: 13px 0 20px;
font-size: 12px;
color: #fff;
}
}
.treasure-popup {
overflow: visible;
/deep/ .van-popup__close-icon {
right: 10px;
top: -16px;
font-size: 22px;
color: #fff;
}
&__container {
width: 100%;
height: 100%;
position: relative;
width: @containerWidth;
}
&__wrap {
margin: 0 auto;
width: 275px;
height: 321px;
overflow: hidden;
background-image: url('img/treasure-popup.png');
background-size: cover;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
}
&__content {
color: #fff;
font-size: 16px;
height: 142px;
width: 100%;
overflow: hidden;
}
&__win-info {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
}
&__title {
width: 100%;
text-align: center;
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #fd0c2a;
line-height: 25px;
height: 18px;
margin: 7px 0 13px;
}
&__prize-img {
img {
display: block;
width: 65px;
}
}
&__prize-name {
width: 100%;
padding: 0 10px;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #fd0c2a;
line-height: 16.5px;
margin-top: 11px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-align: center;
}
&__thanks {
margin-top: 0;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
&__footer {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
min-height: 65px;
}
&__sure {
width: 126px;
height: 33px;
line-height: 33px;
border: 0;
outline: none;
/deep/ .van-button__text {
font-size: 14px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #c10000;
line-height: 20px;
}
}
&__win-msg {
margin: 13px 0 20px;
font-size: 12px;
color: #fff;
}
}
</style>
<template>
<section class="main-timing" :style="{ backgroundPosition: isMini ? '0 0' : '' }">
<div v-if="isMini" class="main-link" @click="goRule">活动介绍</div>
<TimingStatus class="timing-status-box"></TimingStatus>
<JoinButton
class="join-button-box"
:style="{ bottom: isMini ? '26%' : '51%' }"
@lottery="lotteryCallback"
></JoinButton>
<Rewards v-if="!isMini" :style="{ height: isMini ? '65.5vh' : '37.5vh' }" class="reward-box"></Rewards>
<BackButton v-if="backUrl" class="back-box" :url="backUrl"></BackButton>
<Records v-if="isMini"></Records>
<RulePopup :value="isShowIntro"></RulePopup>
<WinPopup :value="isShowWin" :info="winInfo" type="luckybag"></WinPopup>
<BindPhoneDialog :value="isShowBindPhone"></BindPhoneDialog>
</section>
</template>
<script>
import { mapGetters } from 'vuex'
// banner
// import TimingBanner from '@/components/Lottery/Timing/TimingBanner'
// 状态信息
import TimingStatus from '@/components/Lottery/Timing/TimingStatus'
// 参加按钮
import JoinButton from '@/components/Lottery/Timing/JoinButton'
// 奖品介绍
import Rewards from '@/components/Lottery/Timing/Rewards'
// 返回直播间按钮
import BackButton from '@/components/Lottery/Timing/BackButton'
// 中奖弹窗
import WinPopup from '@/components/Lottery/Timing/WinPopup'
export default {
components: {
// TimingBanner,
TimingStatus,
JoinButton,
Rewards,
BackButton,
WinPopup,
BindPhoneDialog: () => import('@/components/Common/BindPhoneDialog'),
RulePopup: () => import('@/components/Lottery/Timing/RulePopup'),
Records: () => import('@/components/Lottery/Instant/Records')
},
props: {
isMini: {
type: Boolean,
default: false
},
isBtnLoading: {
type: Boolean,
default: false
},
isShowWin: {
type: Boolean,
default: false
},
isShowBindPhone: {
type: Boolean,
default: false
},
winInfo: {
type: Object,
default: () => {
return {}
}
},
isShowIntro: {
type: Boolean,
default: false
}
},
data() {
return {
}
},
computed: {
...mapGetters({
uin: 'users/uin',
isLogin: 'users/isLogin',
lotteryInfo: 'lottery/lotteryInfo',
isBindPhone: 'users/isBindPhone'
}),
backUrl() {
return this.$route.query.backUrl || ''
},
config() {
const list =
typeof this.lotteryInfo.prizeConfigs === 'object'
? Object.values(this.lotteryInfo.prizeConfigs)
: this.lotteryInfo.prizeConfigs
return list
}
},
methods: {
lotteryCallback() {
this.$emit('lotteryCallback')
},
goRule() {
this.$emit('goRule')
// this.isShowIntro = true
}
}
}
</script>
<style lang="less" scoped>
.main-timing {
height: 100%;
position: relative;
padding-top: 20px;
background: url(../img/background-luckybag.png) no-repeat center;
background-size: cover;
.main-link {
width: 24px;
height: 74px;
font-size: 12px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #db0000;
line-height: 13px;
writing-mode: tb-rl;
text-align: center;
background: url(../img/link.png) no-repeat center;
background-size: cover;
position: absolute;
right: 0;
top: 20px;
padding-right: 3px;
}
.timing-status-box {
// padding-left: 16px;
// margin-top: 10px;
height: 20px;
line-height: 20px;
font-size: 14px;
}
.join-button-box {
position: absolute;
width: 92%;
left: 50%;
transform: translateX(-50%);
bottom: 51%;
}
.back-box {
position: absolute;
bottom: 16px;
left: 0;
width: 100%;
border-radius: 22px;
}
.reward-box {
width: 100%;
position: absolute;
bottom: 3%;
}
}
// 样式穿透
.main-timing {
// records
/deep/ .records {
&__entry {
width: 48px;
height: 48px;
background: #ffdccb;
box-shadow: 0px 2px 8px 0px rgba(254, 35, 23, 0.5);
}
&__entry-wrap p {
font-size: 13px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #db0000;
line-height: 17px;
}
}
}
</style>
<template>
<section class="main-timing" :style="{ backgroundPosition: isMini ? '0 0' : '' }">
<div v-if="isMini" class="main-link" @click="goRule">活动介绍</div>
<TimingStatus class="timing-status-box"></TimingStatus>
<JoinButton
class="join-button-box"
:style="{ bottom: isMini ? '32%' : '49%' }"
@lottery="lotteryCallback"
></JoinButton>
<Rewards v-if="!isMini" :style="{ height: isMini ? '65.5vh' : '46.5vh' }" class="reward-box"></Rewards>
<BackButton v-if="backUrl" class="back-box" :url="backUrl"></BackButton>
<Records v-if="isMini"></Records>
<RulePopup :value="isShowIntro"></RulePopup>
<WinPopup :value="isShowWin" :info="winInfo" type="treasure"></WinPopup>
<BindPhoneDialog :value="isShowBindPhone"></BindPhoneDialog>
</section>
</template>
<script>
import { mapGetters } from 'vuex'
// banner
// import TimingBanner from '@/components/Lottery/Timing/TimingBanner'
// 状态信息
import TimingStatus from '@/components/Lottery/Timing/TimingStatus'
// 参加按钮
import JoinButton from '@/components/Lottery/Timing/JoinButton'
// 奖品介绍
import Rewards from '@/components/Lottery/Timing/Rewards'
// 返回直播间按钮
import BackButton from '@/components/Lottery/Timing/BackButton'
// 中奖弹窗
import WinPopup from '@/components/Lottery/Timing/WinPopup'
export default {
components: {
// TimingBanner,
TimingStatus,
JoinButton,
Rewards,
BackButton,
WinPopup,
BindPhoneDialog: () => import('@/components/Common/BindPhoneDialog'),
RulePopup: () => import('@/components/Lottery/Timing/RulePopup'),
Records: () => import('@/components/Lottery/Instant/Records')
},
props: {
isMini: {
type: Boolean,
default: false
},
isBtnLoading: {
type: Boolean,
default: false
},
isShowWin: {
type: Boolean,
default: false
},
isShowBindPhone: {
type: Boolean,
default: false
},
winInfo: {
type: Object,
default: () => {
return {}
}
},
isShowIntro: {
type: Boolean,
default: false
}
},
data() {
return {
}
},
computed: {
...mapGetters({
uin: 'users/uin',
isLogin: 'users/isLogin',
lotteryInfo: 'lottery/lotteryInfo',
isBindPhone: 'users/isBindPhone'
}),
backUrl() {
return this.$route.query.backUrl || ''
},
config() {
const list =
typeof this.lotteryInfo.prizeConfigs === 'object'
? Object.values(this.lotteryInfo.prizeConfigs)
: this.lotteryInfo.prizeConfigs
return list
}
},
methods: {
lotteryCallback() {
this.$emit('lotteryCallback')
},
goRule() {
this.$emit('goRule')
}
}
}
</script>
<style lang="less" scoped>
.main-timing {
height: 100%;
position: relative;
padding-top: 20px;
background: url(../img/background-treasure.png) no-repeat center;
background-size: cover;
.main-link {
width: 24px;
height: 74px;
font-size: 12px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #db0000;
line-height: 13px;
writing-mode: tb-rl;
text-align: center;
background: url(../img/link.png) no-repeat center;
background-size: cover;
position: absolute;
right: 0;
top: 20px;
padding-right: 3px;
}
.timing-status-box {
// padding-left: 16px;
// margin-top: 10px;
height: 20px;
line-height: 20px;
font-size: 14px;
}
.join-button-box {
position: absolute;
width: 92%;
left: 50%;
bottom: 49%;
transform: translateX(-50%);
}
.back-box {
position: absolute;
bottom: 16px;
left: 0;
width: 100%;
border-radius: 22px;
}
.reward-box {
width: 100%;
position: absolute;
bottom: 3%;
}
}
// 样式穿透
.main-timing {
// records
/deep/ .records {
&__entry {
width: 48px;
height: 48px;
background: #ffdccb;
box-shadow: 0px 2px 8px 0px rgba(254, 35, 23, 0.5);
}
&__entry-wrap p {
font-size: 13px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #db0000;
line-height: 17px;
}
}
}
</style>
{
"name": "web-lottery",
"version": "1.3.0",
"version": "1.3.1",
"private": true,
"license": "UNLICENSED",
"scripts": {
......@@ -82,4 +82,4 @@
"postcss-pxtorem": "^5.1.1",
"prettier": "^2.3.2"
}
}
}
\ No newline at end of file
<template>
<section class="lottery-box">
<component
:is="lotteryComponents[+lotteryInfo.type]"
v-if="'type' in lotteryInfo && lotteryInfo.type"
></component>
<component :is="lotteryComponents[+lotteryInfo.type]" v-if="'type' in lotteryInfo && lotteryInfo.type"></component>
<ComplaintsDeal></ComplaintsDeal>
<Loading v-model="isLoading" class="lottery-box__loading"></Loading>
</section>
</template>
......@@ -14,9 +12,11 @@ import { LOTTERY_TYPE } from '@/utils/constant'
import Bus from '@/utils/Bus'
import UserAgents from '@/utils/UserAgents'
import CONFIG from '@/config'
import ComplaintsDeal from '@/components/Common/ComplaintsDeal'
export default {
components: {
ComplaintsDeal,
Loading: () => import('@/components/Loading')
},
layout: 'miniNavBar',
......@@ -25,7 +25,7 @@ export default {
isLoading: true,
lotteryComponents: {
[LOTTERY_TYPE.instant]: () => import('@/components/Lottery/Instant/MiniMain'),
[LOTTERY_TYPE.timing]: () => import('@/components/Lottery/Timing/Main')
[LOTTERY_TYPE.timing]: () => import('@/components/Lottery/Timing/MiniMain')
},
id: this.$route.query.id || null, // 接收抽奖id
sessionId: this.$route.query.sessionId || null, // 接收抽奖场次id
......@@ -71,7 +71,7 @@ export default {
}, 1000)
}
},
connectionListener() {},
connectionListener() { },
// 页面进入初始化
dataInit() {
const { id, sessionId: playId, uin } = this.$route.query
......@@ -115,6 +115,7 @@ export default {
const { id, playId } = data
const { sessionId: currentPlayId, id: currentId } = this
if (+id === +currentId && +playId === +currentPlayId) {
// eslint-disable-next-line no-unused-vars
const { status, startTime, endTime, userTimes } = data
// 状态
this.updateInfo({
......
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