6
0
Fork 0
jiqu-library-miniprogram/src/pageB/lucky/index.vue

455 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="h-full">
<loading-view v-if="isFirstLoading && isLogin "></loading-view>
<view
class="bg min-h-full overflow-hidden"
v-else-if="isLogin"
:style="{ backgroundImage: `url(${draw_activity.bg_image})`, backgroundColor: draw_activity.bg_color }"
>
<view class="">
<view class="fixed top-0 left-0 w-full bg z-10" :style="{ backgroundImage: `url(${draw_activity.bg_image})` }">
<view :style="{ height: statusBarHeight + 'px' }"></view>
<view class="px-30rpx py-20rpx flex h-50px flex items-center relative">
<image
@click="onBack"
class="h-56rpx w-56rpx"
src="https://ystmp.oss-cn-beijing.aliyuncs.com/wechart/lucky/back.png"
alt=""
srcset=""
></image>
<view class="absolute left-100rpx right-100rpx text-center text-52rpx text-white">{{draw_activity.name}}</view>
</view>
</view>
<view class="w-full" :style="{ height: 50 + statusBarHeight + 'px' }"> </view>
</view>
<view class="h-300rpx w-full"></view>
<view class="w-full relative">
<view class="h-100rpx"></view>
<view class="absolute top-0 z-9 left-0 px-30rpx message w-full">
<view class="h-180rpx">
<swiper
vertical="vertical"
autoplay="play"
class="h-full"
previous-margin="60rpx"
next-margin="60rpx"
disable-touch
@change="change"
circular
:current="current"
>
<swiper-item v-for="(item, index) in logsAll" :key="index" class="h-full flex items-start flex-col justify-center">
<view
class="bg-hex-000 bg-opacity-30 text-white rounded-full px-20px h-44rpx leading-44rpx text-28rpx inline-block"
:class="index == current ? 'opacity1' : index + 1 == current ? 'opacity0' : index - 1 == current ? 'opacity2' :(current==logsAll.length-1 && index==0)?'opacity2' : 'opacity3'"
>
<text
>恭喜{{ item.user.nickname }}抽中<text class="text-hex-ffde58">{{ item.prize.name }}</text></text
>
</view>
</swiper-item>
</swiper>
</view>
<!-- <view v-for="item in logs" :key="item.id" class="opacity">
<view class="bg-hex-000 bg-opacity-30 text-white rounded-full px-20px h-44rpx leading-44rpx text-28rpx mb-10rpx inline-block">
<text
>恭喜{{ item.user.nickname }}抽中<text class="text-hex-ffde58">{{ item.prize.name }}</text></text
>
</view>
</view> -->
</view>
<almost-lottery
pointer-position="edge"
:lottery-size="lotteryConfig.lotterySize"
:action-size="lotteryConfig.actionSize"
:ring-count="8"
:duration="8"
:prize-list="prizeList"
:prize-index="prizeIndex"
@reset-index="prizeIndex = -1"
@draw-start="handleDrawStart"
@draw-end="handleDrawEnd"
@finish="handleDrawFinish"
v-if="prizeList.length"
stroke-color="#ffffff"
:strFontSize="28"
:strMaxLen="10"
:strFontColors="['#fb6056']"
:colors="['#ffeaa7', '#ffeaa7']"
:stroked="true"
:img-width="120"
:img-height="120"
:imgMarginStr="30"
:strMarginOutside="32"
:canvasCached="true"
:lotteryBg="lotteryBg"
:actionBg="actionBg"
/>
<view class="text-center mt-40rpx"
>今天还可以抽 <text class="text-error">{{ freeNum }}</text> 次</view
>
</view>
<view class="p-30rpx">
<u-parse :html="draw_activity.desc"></u-parse>
</view>
</block>
<u-mask :show="show">
<view class="flex items-center justify-center h-full">
<view class="">
<view class="pr-30rpx text-right">
<image src="/static/images/app/app_update_close.png" alt="" srcset="" class="w-48rpx h-48rpx" @click="show = false"></image>
</view>
<view class="w-600rpx h-600rpx relative" v-if="prizeData.prize">
<image :src="prizeData.prize.type==0?results.goods:tips_image" class="w-full h-full"></image>
<block v-if="prizeData.prize.type!=0">
<view class="absolute top-178rpx left-0 right-0 text-center mx-auto mx-auto w-300rpx h-290rpx">
<image :src="results.goods" alt="" class="w-full h-full"></image>
</view>
<view
class="absolute top-136rpx left-0 right-0 text-center h-42rpx leading-40rpx text-30rpx text-hex-f74a2c bg-gradient-to-t to-hex-fff4e5 from-hex-ffd4b2 w-240rpx rounded-full mx-auto"
>
{{ results.name }}
</view>
<view
v-if="!!results.btn"
@click="onResults"
class="absolute top-466rpx left-0 right-0 text-center h-54rpx leading-54rpx text-28rpx text-white bg-img w-280rpx mx-auto"
>
{{ results.btn }}
</view>
</block>
</view>
</view>
</view>
</u-mask>
<u-popup v-model="showAddress" mode="center" :border-radius="20" :mask-close-able="false">
<view class="p-30rpx w-600rpx">
<u-form :model="form" ref="uForm" label-width="130rpx" :error-type="['toast']">
<u-form-item label="收件人" prop="consignee_name">
<u-input v-model="form.consignee_name" cursor-spacing="50rpx" />
</u-form-item>
<u-form-item label="联系方式" prop="consignee_phone">
<u-input v-model="form.consignee_phone" cursor-spacing="50rpx" />
</u-form-item>
<u-form-item label="收货地址" prop="consignee_address">
<u-input v-model="form.consignee_address" cursor-spacing="50rpx" />
</u-form-item>
</u-form>
<view class="bg-primary rounded-full h-64rpx leading-64rpx text-center text-white" @click="submit"> </view>
</view>
</u-popup>
</view>
</view>
</template>
<script>
let systemInfo = uni.getSystemInfoSync();
import AlmostLottery from '../components/almost-lottery/components/almost-lottery/almost-lottery.vue';
export default {
name: 'Home',
components: {
AlmostLottery,
},
data() {
return {
isFirstLoading: true,
id: '',
config: {},
current: 1,
statusBarHeight: systemInfo.statusBarHeight,
form: {
consignee_name: '',
consignee_phone: '',
consignee_address: '',
},
show: false,
prizeData: {},
results: {
name: '50元消费体验价',
btn: '充值账户余额内',
goods: 'https://ystmp.oss-cn-beijing.aliyuncs.com/wechart/lucky/hb.png',
},
// 开启调试模式
isDev: process.env.NODE_ENV === 'development',
// 以下是转盘配置相关数据
lotteryConfig: {
// 抽奖转盘的整体尺寸单位rpx
lotterySize: 680,
// 抽奖按钮的尺寸单位rpx
actionSize: 200,
},
// 以下是转盘 UI 配置
// 转盘外环图,如有需要,请参考替换为自己的设计稿
lotteryBg: 'https://ystmp.oss-cn-beijing.aliyuncs.com/wechart/lucky/lottery-bg.png',
// 抽奖按钮图
actionBg: 'https://ystmp.oss-cn-beijing.aliyuncs.com/wechart/lucky/action-bg.png',
// 奖品数据
prizeList: [],
// 奖品是否设有库存
onStock: true,
// 中奖下标
prizeIndex: -1,
// 是否正在抽奖中,避免重复触发
prizeing: false,
// 当日免费抽奖次数余额
freeNum: 0,
logsAll: [],
logsIndex: 0,
logs: [],
timer: null,
showAddress: false,
draw_log_id: null,
rules: {
consignee_name: [
{
required: true,
message: '请输入收件人',
trigger: 'change',
},
],
consignee_phone: [
{
required: true,
message: '请输入连续方式',
trigger: 'change',
},
],
consignee_address: [
{
required: true,
message: '请输入收货地址',
trigger: 'change',
},
],
},
};
},
computed: {
user() {
return this.$store.getters.user ?? {};
},
isApple() {
return uni.getSystemInfoSync().platform === 'ios';
},
draw_activity() {
return this.config.draw_activity;
},
tips_image(){
return this.draw_activity?.tips_image ?? 'https://ystmp.oss-cn-beijing.aliyuncs.com/wechart/lucky/lucky-jg.png'
}
},
async onLoad({ id }) {
this.id = id;
setTimeout(()=>{
if(!this.isLogin){
this.$u.route({
type:'redirectTo',
url:`/pages/login/index?redirec=${encodeURIComponent(`/pageB/lucky/index?id=${id}`)}`
})
}else{
this.getConfig();
this.getLuckyLog();
}
},300)
},
//微信分享
onShareAppMessage(res) {
let code = this.user.code ? this.user.code : '';
let shareObj = {
title: this.draw_activity.name,
path: `/pageB/lucky/index?id=${this.id}&invite_code=${code}`,
imageUrl: this.draw_activity.bg_image,
};
return shareObj;
},
methods: {
change(e) {
this.current = e.detail.current;
},
onBack() {
const pages = getCurrentPages()
const prevPage = pages[pages.length - 2]
if(prevPage){
uni.navigateBack({})
}else{
uni.switchTab({
url:'/pages/index/index'
})
}
// uni.navigateBack();
},
async getConfig() {
try {
const resData = await this.$api.get(`/v1/draw-activities/${this.id}`);
this.config = resData;
this.handleInitCanvas();
} catch (error) {
console.log(error);
} finally {
this.isFirstLoading = false;
}
},
onResults() {
const { prize } = this.prizeData;
if (prize.type == 1) {
this.show = false;
this.showAddress = true;
} else {
this.show = false;
}
},
submit() {
this.$refs.uForm.validate(async (valid) => {
if (valid) {
await this.$api.put(`/v1/draw-activities/${this.id}/logs/${this.draw_log_id}`, this.form);
this.$refs.uForm.resetFields();
this.showAddress = false;
}
});
},
// 获取抽奖记录
async getLuckyLog() {
const resData = await this.$api.get(`/v1/draw-activities/${this.id}/logs`, {
params: {
page: 1,
per_page: 4,
},
});
this.logsAll = resData.data.reverse();
},
// 重新生成
handleInitCanvas() {
this.prizeList = [];
this.getPrizeList();
},
// 获取奖品列表
async getPrizeList() {
this.freeNum = this.config.draw_tickets_number;
const data = this.draw_activity.prizes.map((e) => {
return { prizeId: e.id, prizeName: e.name, prizeStock: 10, prizeWeight: 200, prizeImage: e.icon, ...e };
});
this.draw_log_id = this.config.draw_log_id;
this.prizeList = data;
if (!!this.draw_log_id && !this.showAddress) {
this.showAddress = true;
this.$nextTick(() => {
this.$refs.uForm.setRules(this.rules);
});
}
},
// 本次抽奖开始
handleDrawStart() {
if(this.draw_activity.status == 4){
return this.$u.toast('活动已结束');
}
if(this.draw_activity.status == 2){
return this.$u.toast('活动未开始');
}
if(this.draw_activity.status != 3){
return;
}
if (this.prizeing) return;
this.prizeing = true;
// 还有免费数次或者剩余金币足够抽一次
if (this.freeNum > 0) {
// 更新免费次数或金币余额
if (this.freeNum > 0) {
this.freeNum--;
}
this.tryLotteryDraw();
} else {
this.$u.toast('抽奖次数不足');
this.prizeing = false;
}
},
// 尝试发起抽奖
tryLotteryDraw() {
this.remoteGetPrizeIndex();
},
// 获取中奖下标
async remoteGetPrizeIndex() {
const resData = await this.$api.post(`/v1/draw-activities/${this.id}/draw`);
this.prizeData = resData;
const { prize } = resData;
let _prizeId = prize.id;
this.prizeIndex = this.prizeList.findIndex(({ prizeId }) => prizeId == _prizeId);
},
// 本次抽奖结束
handleDrawEnd() {
// 旋转结束后,开始处理拿到结果后的逻辑
let prize = this.prizeList[this.prizeIndex];
const { type, prizeImage, name, amount } = prize;
this.draw_log_id = this.prizeData.id;
this.results.name = name;
this.results.btn = '';
if (type == 1) {
// this.showAddress = true
this.results.btn = '填写地址';
}
this.results.goods = prizeImage;
this.show = true;
this.prizeing = false;
this.getLuckyLog();
},
// 抽奖转盘绘制完成
handleDrawFinish(res) {
let stoTimer = setTimeout(() => {
clearTimeout(stoTimer);
stoTimer = null;
uni.showToast({
title: res.msg,
mask: true,
icon: 'none',
});
}, 50);
},
},
onUnload() {
uni.hideLoading();
clearTimeout(this.timer);
},
};
</script>
<style>
page {
height: 100%;
}
</style>
<style lang="scss" scoped>
.bg {
// background-image: url('https://ystmp.oss-cn-beijing.aliyuncs.com/wechart/lucky/luckywheel.png');
background-size: 100% auto;
background-position: top;
background-repeat: no-repeat;
}
.bg-img {
background: url('https://ystmp.oss-cn-beijing.aliyuncs.com/wechart/lucky/btn.png') no-repeat;
background-size: 100% auto;
}
.opacity0 {
@apply opacity-60;
}
.opacity1 {
@apply opacity-80;
}
.opacity2 {
@apply opacity-100;
}
.opacity3 {
@apply opacity-80;
}
</style>