完成抽奖页面,结果页面事件逻辑,待给到设计稿更新页面

This commit is contained in:
Andy Leong 2024-01-15 18:44:31 +08:00
parent 96ad18a766
commit 1024c33440
21 changed files with 385 additions and 50 deletions

View File

@ -1,14 +1,16 @@
import axios from 'axios'
import QS from 'qs';
import { Toast } from 'vant'
let url = import.meta.env.VITE_HOST + import.meta.env.VITE_API
// 创建axios
const service = axios.create({
baseURL: import.meta.env.VITE_API,
baseURL: url,
timeout: 50000,
});
// 添加请求拦截器
service.interceptors.request.use((config) => {
// 在发送请求之前做些什么
@ -22,11 +24,10 @@ service.interceptors.request.use((config) => {
// 添加响应拦截器
service.interceptors.response.use(
(response) => {
return response.data;
return response.data || {};
}, (error) => {
Toast('网络繁忙')
console.log('请求错误:', error.message);
return Promise.reject(error);
});

View File

@ -1,6 +1,6 @@
import http from './http'
export function addSurveyed(data, authorization) {
export function drawApi(data, authorization) {
return http.post("/api/user/addSurveyed",
data,
true,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@ -1,21 +1,200 @@
<template>
<div class="DrawPage">
抽奖页面
</div>
</template>
<script setup>
import { debounceTap } from '@/plugins'
import gsap from 'gsap'
import { addPoint, debounceTap } from '@/plugins'
import { Toast } from "vant";
import { Clipboard } from "v-clipboard";
import { useMainStore } from "@/store";
import { drawApi } from '@/api'
//
const emit = defineEmits(["DrawPage"]);
const userStore = useMainStore()
const money = ref('8.88')
const code = ref('sss')
const showResult = ref(false)
const hasPrize = ref(true)
const drawFn = (event) => {
let e = event.target.parentElement
debounceTap(e, async () => {
console.log('抽奖');
Toast.loading({
message: '抽奖中',
forbidClick: true,
duration: 0
})
gsap.fromTo(e, { rotation: '-30' }, { rotation: '+30', repeat: -1, yoyo: true, ease: 'none', duration: 0.3 })
// const res = await drawApi({})
setTimeout(() => {
hasPrize.value = false // true || false
showResult.value = true
console.log("showResult:", showResult.value);
Toast.clear()
gsap.from('.result-container', { duration: 0.5, scale: 0.7, autoAlpha: 0 })
gsap.killTweensOf('.draw-light,.draw')
}, 3000)
})
}
const hide = (event) => {
let e = event.target;
debounceTap(e, () => {
gsap.to('.DrawPage', { duration: 0.3, autoAlpha: 0, onComplete: () => { emit('DrawPage', 'hide') } })
});
}
const copyFn = (event) => {
let e = event.target;
debounceTap(e, () => {
Clipboard.copy(code.value);
Toast(`复制成功:${code.value}`);
});
}
const entryAni = () => {
gsap.from(".DrawPage", { duration: 0.2, autoAlpha: 0 });
gsap.from(".draw-container", { duration: 0.5, autoAlpha: 0, scale: 0.7 });
gsap.from(".draw-light", { duration: 3, rotation: '+=360', ease: 'none', repeat: -1 });
};
onMounted(() => {
entryAni();
});
</script>
<template>
<div class="DrawPage" @touchmove.prevent>
<!-- 抽奖容器 -->
<div v-show="!showResult" class="draw-container">
<div class="draw-light"></div>
<div class="draw-box">
<div class="draw" @click="drawFn($event)"></div>
</div>
<div class="draw-star"></div>
<div class="draw-tips"></div>
</div>
<div v-show="showResult" class="result-container">
<!-- 有奖品 -->
<div class="draw-has" v-show="hasPrize">
<div class="money">¥{{ money }}</div>
<div class="code-box">
<div class="code">{{ code }}</div>
<div class="copy-btn" @click="copyFn($event)"></div>
</div>
<div class="cls-btn" @click="hide($event)"></div>
</div>
<!-- 没有奖品 -->
<div class="draw-none" v-show="!hasPrize">
<div class="none-prize"></div>
<div class="cls-btn" @click="hide($event)"></div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.DrawPage {
@include fixed();
background-color: azure;
@include flexCen();
background-color: rgba($color: #000000, $alpha: 0.8);
//
.draw-container {
@include box(685px, 694px);
position: relative;
.draw-light {
pointer-events: none;
@include pos(685px, 694px, 0px, 0px);
@include bg_pos("prize/light.png");
}
.draw-star {
pointer-events: none;
@include pos(515px, 551px, 89px, 56px);
@include bg_pos("prize/star.png");
}
.draw-box {
@include pos(690px, 680px, 0px, 0px);
@include bg_pos("prize/draw-box.png");
.draw {
@include pos(350px, 347px, 164px, 172px);
}
}
.draw-tips {
pointer-events: none;
@include pos(187px, 34px, 250px, 605px);
@include bg_pos("prize/tips.png");
}
}
//
.draw-has {
position: relative;
@include box(665px, 731px);
@include bg_pos("prize/myPrize-box.png");
.money {
@include pos(370px, 81px, 139px, 239px);
display: flex;
justify-content: center;
align-items: center;
color: #e95b46;
font-weight: 700;
font-size: 58px;
letter-spacing: 4px;
}
.code-box {
@include pos(312px, 52px, 197px, 508px);
display: flex;
flex-direction: row;
align-items: center;
.code {
font-size: 25px;
font-weight: 700;
margin-right: 10px;
color: #fff6cc;
}
.copy-btn {
@include box(77px, 39px);
@include bg_pos("prize/copy-btn.png");
}
}
.cls-btn {
@include pos(82px, 82px, 517px, 114px);
@include bg_pos("prize/cls-btn.png");
}
}
//
.draw-none {
@include flexCen();
.none-prize {
@include box(521px, 447px);
@include bg_pos("prize/no-prize.png");
}
.cls-btn {
@include box(82px, 82px);
@include bg_pos("prize/cls-btn.png");
margin-top: 40px;
}
}
}
</style>

View File

@ -61,7 +61,8 @@ onMounted(() => {
.MyPrizePage {
@include fixed();
@include flexCen();
background-color: rgba($color: #000000, $alpha: 0.7);
background-color: rgba($color: #000000, $alpha: 0.8);
.myPrize-container {
position: relative;
@include box(665px, 731px);
@ -83,6 +84,7 @@ onMounted(() => {
display: flex;
flex-direction: row;
align-items: center;
.code {
font-size: 25px;
font-weight: 700;
@ -97,7 +99,7 @@ onMounted(() => {
}
.myPrize-cls-btn {
@include pos(57px, 57px, 517px, 114px);
@include pos(82px, 82px, 517px, 114px);
@include bg_pos("prize/cls-btn.png");
}
}

View File

@ -1,7 +1,7 @@
<script setup name="Question">
import { Button, Toast } from "vant";
import gsap from "gsap";
import data from "@/data";
import { data } from "@/data";
import { debounceTap, FYShuffle, mostValue } from "@/plugins";
import { onMounted } from "vue";
@ -190,16 +190,9 @@ onMounted(() => {
</div>
</div>
<div class="answer-box">
<div
class="answer"
v-for="(item, index) in questionList[currentId].answer"
:class="'answer-' + index"
:key="index"
>
<div
class="answer-bg"
:class="activeId == item.aid ? 'active' : ''"
></div>
<div class="answer" v-for="(item, index) in questionList[currentId].answer" :class="'answer-' + index"
:key="index">
<div class="answer-bg" :class="activeId == item.aid ? 'active' : ''"></div>
<div class="answer-text">
<div class="content-before"></div>
<div class="content-after"></div>
@ -245,6 +238,7 @@ onMounted(() => {
@include bg_pos("qa/question.png");
font-family: "alimama";
color: #c6672c;
.question-order {
@include pos(544px, 75px, 87px, 112px);
display: flex;
@ -254,6 +248,7 @@ onMounted(() => {
font-weight: 700;
line-height: 80px;
}
.question-text {
@include pos(544px, 150px, 87px, 192px);
box-sizing: border-box;
@ -264,6 +259,7 @@ onMounted(() => {
font-size: 40px;
font-weight: 700;
line-height: 50px;
.text {
width: 80%;
// height: 100%;
@ -286,11 +282,13 @@ onMounted(() => {
position: absolute;
// font-family: "alimama";
color: #c6672c;
.answer-bg {
@include pos(481px, 471px, 0px, 0px);
@include bg_pos("qa/answer-box-1.png");
pointer-events: none;
}
.active {
@include bg_pos("qa/answer-box-2.png");
@ -350,6 +348,7 @@ onMounted(() => {
top: 0px;
left: 6px;
}
.answer:nth-child(2) {
top: 414px;
left: 258px;

View File

@ -1,21 +1,83 @@
<template>
<div class="ResultPage">
结果页
</div>
</template>
<script setup>
import { gsap } from 'gsap'
import { debounceTap } from '@/plugins'
import { useMainStore } from '@/store'
import { mbtiList } from '@/data'
//
const emit = defineEmits(["ResultPage"]);
const userStore = useMainStore()
let bgId = ref(1)
const bgPic = computed(() => {
return new URL(`../assets/images/result/bg-${bgId.value}.jpg`, import.meta.url).href
})
const mbti = ref(mbtiList.find((item) => item.type == 'INFJ') || '没结果')
console.log('mbti', mbti.value);
const changBg = (event, number) => {
let e = event.target
if (number == bgId.value) return
debounceTap(e, () => {
bgId.value = number
console.log('bgId', bgId.value);
})
}
</script>
<template>
<div class="ResultPage">
<div class="result-bg">
<img :src="bgPic" alt="" srcset="">
</div>
<div class="result-container">
结果页:{{ mbti.type || '没结果' }}
<div class="bg-tab">
<div v-for="item in 4" class="li" @click="changBg($event, item)">{{ item }}</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.ResultPage {
@include fixed();
background-color: azure;
.result-bg {
@include pos(750px, 100%, 0px, 50%);
transform: translateY(-50%);
pointer-events: none;
img {
@include box(100%, 100%);
}
}
.result-container {
@include pos(750px, 100%, 0px, 50%);
transform: translateY(-50%);
.bg-tab {
width: 90%;
display: flex;
flex-direction: row;
justify-content: space-around;
.li {
@include box(80px, 80px);
background-color: aquamarine;
@include flexCen();
}
}
}
}
</style>

View File

@ -1,21 +1,21 @@
<template>
<div class="RulePage">
规则页面
</div>
</template>
<script setup>
import { debounceTap } from '@/plugins'
//
const emit = defineEmits(["RulePage"]);
</script>
<template>
<div class="RulePage">
规则页面
</div>
</template>
<style lang="scss" scoped>
.RulePage {
@include fixed();
background-color: azure;
@include flexCen();
background-color: rgba($color: #000000, $alpha: 0.7);
}
</style>

View File

@ -1,4 +1,4 @@
export default [
export const data = [
{
id: 1,
type: 'mbti',
@ -203,4 +203,67 @@ export default [
},
],
},
]
export const mbtiList = [
{
type: 'INTJ',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
},
{
type: 'INTP',
spe: '富有创造力的发明家,对知识有着止不住的渴望',
},
{
type: 'ENTJ',
spe: '大胆,富有想象力且',
},
{
type: 'ENTP',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
},
{
type: 'INFJ',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
},
{
type: 'INFP',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
},
{
type: 'ENFJ',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
},
{
type: 'ENFP',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
},
{
type: 'ISTJ',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
},
{
type: 'ISFJ',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
},
{
type: 'ESTJ',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
},
{
type: 'ISTP',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
},
{
type: 'ISFP',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
},
{
type: 'ESTP',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
},
{
type: 'ESFP',
spe: '富有想象力和战略性的思想家,一切皆在计划之中',
},
]

View File

@ -2,8 +2,10 @@
<div class="home">
<Index v-if="showIndex" @IndexPage="indexFn"></Index>
<Question v-if="showQuestion" @QuestionPage="questionFn"></Question>
<Loading v-if="showLoad" @LoadPage="loadFn"></Loading>
<Result v-if="showResult" @ResultPage="resultFn"></Result>
<MyPrize v-if="showMyPrize" @MyPrizePage="myPrizeFn"></MyPrize>
<Draw v-if="showDraw" @DrawPage="drawFn"></Draw>
<Loading v-if="showLoad" @LoadPage="loadFn"></Loading>
</div>
</template>
@ -13,6 +15,8 @@ import Loading from "@/components/Loading";
import Index from "@/components/Index";
import Question from "@/components/Question";
import MyPrize from "@/components/MyPrize";
import Draw from "@/components/Draw";
import Result from "@/components/Result";
import { createBGM } from "@/plugins";
const showLoad = ref(true);
@ -50,6 +54,20 @@ const myPrizeFn = (item) => {
}
};
const showDraw = ref(false);
const drawFn = (item) => {
if (item.action == "hide") {
showDraw.value = false;
}
};
const showResult = ref(true);
const resultFn = (item) => {
if (item.action == "hide") {
showResult.value = false;
}
};
onMounted(() => {
// createBGM();
});

View File

@ -1,17 +1,28 @@
// pinia仓库
import { defineStore } from "pinia"
export const useMainStore = defineStore("counter", {
state: () => {
return {
name: '超级管理员',
prizeCode: 'DKS18',
prizeMoney: '8.88',
token: '',
MBTI: '', //测试结果
prizeCode: 'DKS18', //兑换码
prizeMoney: '8.88', //金额
}
},
// 相当于computed属性对state进行二次加工
getters: {},
// 异步处理方法
actions: {},
actions: {
updateToken(token) {
this.token = token
},
updatePrize(code, money) {
this.prizeCode = code
this.prizeMoney = money
},
updateMBTI(type) {
this.MBTI = type
}
},
})