Files
Smart-Farm/uniapp/uni-app/shop/pages/luck.vue
2025-12-22 17:13:05 +08:00

571 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="shop-luck" v-if="isLoad">
<block v-if="detail.atv_id">
<uni-nav-bar :fixed="true" :shadow="false" :statusBar="true" color="#fff"
:backgroundColor="color == '#ffffff' ?``:primaryColor" leftIcon="icon-left"
:title="color == '#ffffff' ?``:`积分抽奖`">
</uni-nav-bar>
<image mode="aspectFill" lazy-load class="luck-bg abs" :src="detail.cover"> </image>
<view class="my-integral flex-center abs">
<view class="flex-y-baseline">
<view class="integral-num f-big-title icon-font-color mr-sm">{{detail.user_integral}}</view>
<view class="f-title c-base">积分</view>
</view>
</view>
<view @tap="$refs.show_rule_item.open()" class="rule-btn-info flex-center abs">
<view class="rule-btn flex-center radius">
<i class="iconfont icon-wenhao mr-sm"></i>
规则说明
</view>
</view>
<view @tap.stop="getList('record',1)" class="record-btn flex-center f-caption c-base abs">抽奖记录</view>
<view class="luck-dialog-info flex-center abs">
<view class="dialog-info" :style="'-webkit-transform:rotate(' + deg + 'deg) translateZ(0);transform:rotate(' + deg
+ 'deg) translateZ(0)'">
<image class="dialog-img" src="https://lbqny.migugu.com/admin/farm/luck-dialog.png"> </image>
<view class="item-luck flex-center flex-column abs" :class="[`luck-${index}`]"
v-for="(item,index) in detail.data" :key="index">
<view class="flex-center f-icontext text-bold c-warning mb-sm">{{item.title}}</view>
<image mode="aspectFill"
:class="[{'thank-you-img':!item.is_luck},{'icon-img radius-10':item.is_luck}]"
:src="item.icon || thank_you_img">
</image>
</view>
</view>
<image @tap="toLuck" class="pointer-img abs" src="https://lbqny.migugu.com/admin/farm/luck-pointer.png">
</image>
<view class="use-integral flex-center f-icontext c-base abs">{{`${detail.integral}积分`}}</view>
</view>
<image class="num-img abs" src="https://lbqny.migugu.com/admin/farm/luck-num.png">
</image>
<view class="have-change abs flex-center f-caption c-base">还有<view class="num">{{detail.user_num}}</view>
抽奖机会
</view>
<view class="user-list abs">
<image class="user-list-img abs" src="https://lbqny.migugu.com/admin/farm/luck-user-list.png">
</image>
<view class="title flex-center f-sm-title text-bold">中奖信息</view>
<scroll-view scroll-y @scrolltolower="scrolltolower($event,'user')" :scroll-with-animation="true"
lower-threshold="100" class="luck-user">
<view class="mt-sm mb-sm" :style="{color:primaryColor}" v-for="(item,index) in list.user.data"
:key="index">
恭喜<span
class="text ml-sm mr-sm">{{item.nickName.length > 5 ? `${item.nickName.substring(0,5)}...` : item.nickName}}</span>抽中了<span
class="text ml-sm">
{{item.type == 1? `1张卡券`:`${item.integral}积分`}}
</span>
</view>
<view class="flex-center f-paragraph c-caption mt-sm" v-if="list.user.data.length ==0 ">
暂无中奖信息快来参加抽奖吧</view>
</scroll-view>
</view>
<image class="squirrel-img abs" src="https://lbqny.migugu.com/admin/farm/squirrel.png">
</image>
</block>
<block v-else>
<uni-nav-bar :fixed="true" :shadow="false" :statusBar="true" color="#fff" :backgroundColor="primaryColor"
leftIcon="icon-left" title="积分抽奖">
</uni-nav-bar>
<abnor></abnor>
</block>
<uni-popup ref="show_rule_item">
<view class="popup-rule">
<view class="rule-info pd-lg fill-base radius-24">
<view class="flex-center f-title c-title text-bold">规则说明</view>
<view class="rule-text mt-lg f-paragraph">
<text decode="emsp" style="word-break:break-all;">{{detail.text}}</text>
</view>
</view>
<i @tap="$refs.show_rule_item.close()" class="flex-center mt-lg iconfont icon-close c-base"></i>
</view>
</uni-popup>
<uni-popup ref="show_record_item" type="center" :custom="true">
<view class="popup-record rel">
<image class="record-img abs" src="https://lbqny.migugu.com/admin/farm/luck-record.png"></image>
<view class="record-title flex-center f-lg-title text-bold c-base abs">我的抽奖纪录</view>
<view class="record-content fill-base abs">
<scroll-view scroll-y @scrolltolower="scrolltolower($event,'record')" :scroll-with-animation="true"
lower-threshold="100" class="luck-record">
<view class="flex-center pt-md pb-md b-1px-b" v-for="(item,index) in list.record.data"
:key="index">
<image mode="aspectFill" class="icon-img" :class="[{'radius-4':item.is_luck}]"
:src="item.icon || thank_you_img"></image>
<view class="flex-1 flex-between ml-sm">
<view :style="{color:item.is_luck?primaryColor: '#777'}">
{{!item.is_luck ? item.title : item.type == 1? `1张卡券`:`${item.integral}积分`}}
</view>
<view class="f-caption c-caption">{{item.create_time}}</view>
</view>
</view>
<view class="flex-center f-paragraph c-caption mt-sm" v-if="list.record.data.length ==0 ">
暂无抽奖记录快来参加抽奖吧</view>
</scroll-view>
<view @tap.stop="$refs.show_record_item.close()"
class="confirm-btn flex-center f-sm-title text-bold c-base radius"
:style="{background:primaryColor}">确定</view>
<view class="space-lg"></view>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import {
mapState,
} from "vuex"
export default {
components: {},
data() {
return {
isLoad: false,
options: {},
color: '#ffffff',
detail: {},
param: {
record: {
page: 1
},
user: {
page: 1
}
},
list: {
record: {
data: []
},
user: {
data: []
}
},
loading: true,
// 抽奖信息
thank_you_img: 'https://lbqny.migugu.com/admin/farm/thank-you.png',
luckInd: 0,
areaNumber: 9, //划分区域
speed: 16, //速度
deg: 0,
singleAngle: '', // 每片扇形的角度
isStart: false
}
},
computed: mapState({
primaryColor: state => state.config.configInfo.primaryColor,
subColor: state => state.config.configInfo.subColor,
userInfo: state => state.user.userInfo,
}),
onLoad(options) {
this.$util.showLoading()
this.options = options
this.initIndex()
},
onPageScroll(e) {
let color = e.scrollTop < 20 ? '#ffffff' : '#000000'
if (this.color == color) return
this.color = color
},
methods: {
async initIndex(refresh = false) {
let {
areaNumber
} = this
this.singleAngle = 360 / areaNumber
await this.getDetail(refresh)
this.isLoad = true
},
initRefresh() {
this.initIndex(true)
},
async getDetail(refresh) {
let data = await this.$api.shop.luckInfo()
data.integral = parseInt(data.integral)
this.detail = data
if (refresh) {
this.$util.hideAll()
return
}
this.getList('user', 1)
this.$util.hideAll()
},
async getList(type, page) {
let {
atv_id
} = this.detail
if (page) this.param[type].page = 1
let param = this.param[type]
param.id = atv_id
let oldList = this.list[type]
let methodModel = type == 'record' ? 'userLuckRecord' : 'luckRecord'
let newList = await this.$api.shop[methodModel](param);
if (this.param[type].page == 1) {
this.list[type] = newList
} else {
newList.data = oldList.data.concat(newList.data)
this.list[type] = newList
}
this.loading = false
this.$util.hideAll()
if (type == 'record') {
this.$refs.show_record_item.open()
}
},
scrolltolower(e, type) {
if (this.list[type].current_page >= this.list[type].last_page || this.loading) return
this.param[type].page = this.param[type].page + 1
this.loading = true
this.getList(type)
},
// 用户点击开始抽奖
async toLuck() {
let {
atv_id,
} = this.detail
let {
id
} = await this.$api.shop.luckDraw({
id: atv_id
})
let index = this.detail.data.findIndex(item => {
return item.id == id
})
this.luckInd = index
this.toBegin()
await this.initRefresh()
},
// 开始抽奖
toBegin() {
let {
deg,
singleAngle,
speed,
isStart,
luckInd
} = this
if (isStart) return
this.isStart = true
let endAddAngle = 360 - (luckInd * singleAngle + singleAngle / 2); //中奖角度
let rangeAngle = (Math.floor(Math.random() * 4) + 4) * 360; // 随机旋转几圈再停止
let cAngle;
deg = 0;
this.timer = setInterval(() => {
if (deg < rangeAngle) {
deg += speed;
} else {
cAngle = (endAddAngle + rangeAngle - deg) / speed;
cAngle = cAngle > speed ? speed : cAngle < 1 ? 1 : cAngle;
deg += cAngle;
if (deg >= endAddAngle + rangeAngle) {
deg = endAddAngle + rangeAngle;
this.isStart = false;
clearInterval(this.timer);
this.toSuccess()
}
}
this.deg = deg
}, 1000 / 60)
},
// 抽奖完成后操作
toSuccess() {
let {
luckInd
} = this
let {
title = '',
is_luck = 0,
type = 1,
coupon_title = '',
integral = 0
} = this.detail.data[luckInd]
let msg = !is_luck ? title : type == 1 ? `恭喜您获得1张卡券(${coupon_title})` : `恭喜您获得${integral}积分`
this.$util.showToast({
title: msg
})
this.getList('user', 1)
},
}
}
</script>
<style lang="scss">
.shop-luck {
.luck-bg {
top: 0;
left: 0;
width: 100%;
height: 1912rpx;
}
.my-integral {
top: 145rpx;
width: 100%;
height: 100rpx;
.integral-num {
font-weight: bold;
color: #FFFFFF;
letter-spacing: 2rpx;
background: -webkit-linear-gradient(90deg, #FFFBCD, #F4F56F);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.rule-btn-info {
top: 351rpx;
left: 0;
width: 100%;
height: 59rpx;
.rule-btn {
width: 204rpx;
height: 59rpx;
color: #0879CE;
background: rgba(255, 255, 255, 0.6);
.iconfont {
color: rgba(8, 121, 206, 0.6);
}
}
}
.record-btn {
top: 450rpx;
right: 0;
width: 150rpx;
height: 53rpx;
background: rgba(0, 107, 191, 0.48);
border-radius: 100rpx 0 0 100rpx;
}
.luck-dialog-info {
top: 451rpx;
left: 102rpx;
width: 545rpx;
.dialog-info {
.dialog-img {
width: 545rpx;
height: 541rpx;
transform: rotate(-23deg);
}
.item-luck {
width: 150rpx;
height: 120rpx;
.thank-you-img {
width: 46rpx;
height: 46rpx;
margin-top: 3rpx;
}
.icon-img {
width: 56rpx;
height: 52rpx;
}
}
.luck-0 {
top: 60rpx;
left: 250rpx;
transform: rotate(20deg);
}
.luck-1 {
top: 129rpx;
left: 335rpx;
transform: rotate(61deg);
}
.luck-2 {
top: 238rpx;
left: 352rpx;
transform: rotate(101deg);
}
.luck-3 {
top: 331rpx;
left: 298rpx;
transform: rotate(141deg);
}
.luck-4 {
top: 368rpx;
left: 196rpx;
transform: rotate(180deg);
}
.luck-5 {
top: 330rpx;
left: 96rpx;
transform: rotate(220deg);
}
.luck-6 {
top: 238rpx;
left: 42rpx;
transform: rotate(260deg);
}
.luck-7 {
top: 130rpx;
left: 58rpx;
transform: rotate(300deg);
}
.luck-8 {
top: 60rpx;
left: 141rpx;
transform: rotate(340deg);
}
}
.pointer-img {
top: 174rpx;
left: 183rpx;
width: 179rpx;
height: 210rpx;
}
.use-integral {
top: 305rpx;
left: 205rpx;
width: 135rpx;
transform: scale(0.7);
}
}
.num-img {
top: 903rpx;
left: 124rpx;
width: 502rpx;
height: 236rpx;
}
.have-change {
top: 1060rpx;
left: 0;
width: 100%;
height: 50rpx;
.num {
color: #FFEA8F;
}
}
.user-list {
top: 1187rpx;
left: 45rpx;
width: 660rpx;
height: 616rpx;
z-index: 2;
.user-list-img {
top: 0;
left: 0;
width: 660rpx;
height: 616rpx;
z-index: -1;
}
.title {
height: 68rpx;
color: #AB5D10;
}
.luck-user {
width: 560rpx;
height: 480rpx;
padding: 20rpx 50rpx;
.text {
color: #FF8A00;
}
}
}
.squirrel-img {
top: 1730rpx;
right: 30rpx;
width: 141rpx;
height: 141rpx;
z-index: 2;
}
.popup-rule {
width: 596rpx;
margin: 0 auto;
.rule-info {
margin-top: 10vh;
.rule-text {
color: #4A4A4A;
line-height: 1.4;
min-height: 100rpx;
max-height: 60vh;
overflow: auto;
}
}
.icon-close {
font-size: 70rpx;
}
}
.popup-record {
width: 715rpx;
height: 800rpx;
.record-img {
top: 0;
left: 0;
width: 715rpx;
height: 163rpx;
}
.record-title {
top: 0;
left: 0;
width: 100%;
height: 100rpx;
}
.record-content {
top: 99rpx;
left: 55rpx;
width: 608rpx;
border-radius: 0 0 24rpx 24rpx;
.luck-record {
min-height: 100rpx;
max-height: 50vh;
width: 546rpx;
padding: 30rpx;
.icon-img {
width: 61rpx;
height: 61rpx;
}
}
.confirm-btn {
width: 415rpx;
height: 80rpx;
margin: 0 auto;
}
}
}
}
</style>