palc-newyear2024/字体压缩.txt
2025-04-16 17:29:16 +08:00

1923 lines
52 KiB
Plaintext
Raw Permalink 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.

<script setup>
import { Toast } from "vant";
import { debounceTap } from "@/plugins";
import gsap from "gsap";
import { useMainStore } from "@/store";
const emit = defineEmits(["IndexPage"]);
const userStore = useMainStore();
const start = (event) => {
debounceTap(event.target, () => {
gsap.to(".IndexPage", {
duration: 0.5,
autoAlpha: 0,
onComplete: () => {
emit("IndexPage", { action: "start" });
},
});
});
};
const showMyPrize = (event) => {
let e = event.target;
debounceTap(e, () => {
emit("IndexPage", { action: "showMyPrize" });
});
};
const showRule = (event) => {
let e = event.target;
debounceTap(e, () => {
emit("IndexPage", { action: "showRule" });
});
};
onMounted(() => {
gsap.from(".index-bg", { duration: 1, scale: 1.2, autoAlpha: 0 });
gsap.from(".index-paper", { duration: 1, y: 20, autoAlpha: 0, delay: 0.3, });
gsap.from(".index-card-1", { duration: 1, scale: 1.2, autoAlpha: 0, delay: 0.5, });
gsap.from(".index-card-2", { duration: 1, scale: 1.2, autoAlpha: 0, delay: 0.7, });
gsap.from(".index-card-3", { duration: 1, scale: 1.2, autoAlpha: 0, delay: 0.5, });
gsap.from(".index-card-4", { duration: 1, scale: 1.2, autoAlpha: 0, delay: 0.7, });
gsap.from(".index-card-5", { duration: 1, scale: 1.2, autoAlpha: 0, delay: 0.5, });
gsap.from(".index-title", { duration: 1, y: 20, autoAlpha: 0, delay: 1 });
gsap.from(".index-time", { duration: 1, x: 40, autoAlpha: 0, delay: 1 });
gsap.from(".index-text", { duration: 1, scale: 2, autoAlpha: 0, delay: 1 });
gsap.from(".index-megaphone", { duration: 1, x: 140, autoAlpha: 0, delay: 1 });
gsap.from(".index-logo", { duration: 1, y: 20, autoAlpha: 0, delay: 0.75 });
gsap.from(".index-rule-btn", { duration: 1, x: -100, autoAlpha: 0, delay: 1.3 });
gsap.from(".index-prize-btn", {
duration: 1,
x: -100,
autoAlpha: 0,
delay: 1.5,
});
gsap.from(".index-start-btn", {
duration: 1,
y: 30,
autoAlpha: 0,
delay: 1.5,
});
gsap.from(".index-agreement", {
duration: 1,
scale: 0.4,
autoAlpha: 0,
delay: 0.5,
onComplete: () => {
gsap.to('.index-start-btn', { duration: 1, scale: '0.95', repeat: -1, yoyo: true, ease: 'bounce.out' })
}
});
});
const vcNum = ref(false);
const showVC = () => {
vcNum.value++;
if (vcNum.value >= 20) {
gsap.set("#__vconsole", { autoAlpha: 1 });
}
};
</script>
<template>
<div class="IndexPage" @touchmove.prevent>
<div class="index-bg"></div>
<div class="index-container">
<div class="index-logo"></div>
<div class="index-paper">
<div class="index-title" @click="showVC"></div>
<div class="index-time"></div>
<div class="index-card-1"></div>
<div class="index-card-2"></div>
<div class="index-card-3"></div>
<div class="index-card-4"></div>
<div class="index-card-5"></div>
<div class="index-line"></div>
<div class="index-text"></div>
</div>
<div class="index-megaphone"></div>
<div class="index-rule-btn index-left-btn" @click="showRule($event)">活动规则</div>
<div class="index-prize-btn index-left-btn" v-if="userStore.hasPrize" @click="showMyPrize($event)">我的奖品</div>
<div class="index-start-btn" @click="start"></div>
<div class="index-agreement">
<div class="tips">数据来源平安理财数据截至2025年4月11日产品历史业绩不代表未来表现</div>
<span>风险提示:本材料由平安理财有限责任公司(以下简称“平安理财”)制作并提供。</span>
<span class="b">本资料内容及观点仅供参考,不构成对任何人的投资建议。</span>
<span>以上产品投资管理机构/管理人为平安理财,代理销售机构不承担产品的投资、兑付和风险管理的责任。以上产品通过代理销售机构渠道销售的,产品风险评级应当以代理销售机构最终披露的评级结果为准。以上产品为非保本浮动收益理财产品,具体以产品说明书或产品公告披露为准。产品的业绩比较基准指管理人基于过往投资经验以及对产品存续期投资市场波动的预判而对本产品所设定的投资目标,业绩比较基准不是预期收益率,不代表产品的未来表现和实际收益,不构成对产品收益的承诺。</span>
<span class="b">理财产品过往业绩不代表其未来表现,不等于理财产品实际收益,投资须谨慎。过往业绩相关数据已经托管人核对。</span><span
class="orange">理财非存款,产品有风险,投资须谨慎。</span>
<span>
金融消费者不得利用金融产品和服务从事违法活动。
</span>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.IndexPage {
@include pos(100%, 1624px, 0px, 0px);
overflow: hidden;
background: linear-gradient(135deg, #d6d1ca, #e5dccf);
.index-bg {
@include pos(750px, 1624px, 0px, 50%);
transform: translateY(-50%);
@include bg_pos("index/bg.jpg");
}
.index-container {
@include pos(750px, 1624px, 0px, 0px);
// transform: translateY(-50%);
.index-logo {
pointer-events: none;
@include pos(632px, 94px, 59px, 180px);
@include bg_pos("index/logo.png");
}
.index-paper {
@include pos(706px, 777px, 19px, 394px);
@include bg_pos("index/paper.png");
.index-title {
// pointer-events: none;
@include pos(611px, 233px, 59px, -56px);
@include bg_pos("index/title.png");
}
.index-time {
@include pos(385px, 70px, 257px, 161px);
@include bg_pos("index/time.png");
}
.index-card-1 {
@include pos(207px, 182px, 45px, 194px);
@include bg_pos("index/card-1.png");
}
.index-card-2 {
@include pos(227px, 159px, 275px, 260px);
@include bg_pos("index/card-2.png");
}
.index-card-3 {
@include pos(208px, 180px, 496px, 237px);
@include bg_pos("index/card-3.png");
}
.index-card-4 {
@include pos(204px, 168px, 77px, 460px);
@include bg_pos("index/card-4.png");
}
.index-card-5 {
@include pos(215px, 162px, 358px, 524px);
@include bg_pos("index/card-5.png");
}
.index-text {
@include pos(325px, 74px, 307px, 448px);
@include bg_pos("index/text.png");
}
.index-line {
@include pos(661px, 359px, 22px, 346px);
@include bg_pos("index/line.png");
}
}
.index-megaphone {
@include pos(104px, 113px, 646px, 540px);
@include bg_pos("index/megaphone.png");
}
.index-left-btn{
border: 2px solid rgb(255, 255, 255);
background-color: rgb(243, 87, 4);
box-shadow: 0px 6px 11px 0px rgba(155, 122, 68, 0.4);
font-size: 25px;
display: flex;
align-items: center;
justify-content:center;
padding-left: 20px;
color: #ffffff;
letter-spacing: 1.5px;
border-radius: 21px;
}
.index-rule-btn {
@include pos(184px, 49px, -37px, 578px);
}
.index-prize-btn {
@include pos(184px, 49px, -37px, 642px);
}
.index-start-btn {
@include pos(339px, 117px, 203px, 1077px);
@include bg_pos("index/btn.png");
}
.index-agreement {
font-family: "HarmonyOS_Sans_SC_Regular";
pointer-events: none;
@include pos(736px, 182px, 7px, 1258px);
font-size: 14px;
text-align: justify;
letter-spacing: 0.1px;
color: #815e3c;
padding: 10px;
box-sizing: border-box;
border-radius: 10px;
line-height: 20px;
.tips {
text-align: center;
margin: 10px;
color: #ab7133;
}
.b {
font-weight: 700;
}
.orange {
color: #ff7127;
font-weight: 700;
}
}
}
}
</style>
<script setup>
import gsap from "gsap";
import { addPoint, debounceTap } from "@/plugins";
import { Toast } from "vant";
import useClipboard from 'vue-clipboard3'
import { useMainStore } from "@/store";
import { drawApi } from "@/api";
// 页面配置初始化
const emit = defineEmits(["DrawPage"]);
const userStore = useMainStore();
const { toClipboard } = useClipboard()
const money = ref("1.88");
const code = ref("sss");
const showResult = ref(false);
const hasPrize = ref(false);
const drawFn = (event) => {
let e = event.target.parentElement;
debounceTap(e, async () => {
console.log("抽奖");
if (userStore.hasDraw) {
Toast.loading({
message: "抽奖中",
forbidClick: true,
duration: 0,
});
gsap.fromTo(
e,
{ rotation: "-30" },
{ rotation: "+30", repeat: -1, yoyo: true, ease: "none", duration: 0.3 }
);
drawApi(
{ subAnswerKey: userStore.drawKey },
userStore.token
).then(res => {
if (res.code == 0) {
console.log('正常抽奖');
// isDrawn后端判断有没有中奖
hasPrize.value = res.data.isDrawn == 1 ? true : false; // true 中奖 || false 未中奖
userStore.updateDraw(); // 更新抽奖机会
// 有奖品的话更新奖品信息
if (res.data.isDrawn == 1) {
money.value = res.data.prizeAmount;
code.value = res.data.prizeCode;
userStore.updatePrize(res.data);
}
setTimeout(() => {
Toast.clear();
showResult.value = true;
gsap.from(".result-container", {
duration: 0.5,
scale: 0.7,
autoAlpha: 0,
});
gsap.killTweensOf(".draw-light,.draw");
}, 1000);
} else {
console.log('抽奖异常');
if (res.code == 6003) {
console.log('6003', res);
Toast(res.msg)
userStore.updateDraw();
} else {
console.log('eroor', res);
hasPrize.value = false; // true 中奖 || false 未中奖
userStore.updateDraw();
setTimeout(() => {
Toast.clear();
showResult.value = true;
gsap.from(".result-container", {
duration: 0.5,
scale: 0.7,
autoAlpha: 0,
});
gsap.killTweensOf(".draw-light,.draw");
}, 1000);
}
}
})
} else {
Toast('今日抽奖次数已用完!')
}
});
};
const hide = (event) => {
let e = event.target;
debounceTap(e, () => {
gsap.to(".DrawPage", {
duration: 0.3,
autoAlpha: 0,
onComplete: () => {
emit("DrawPage", {action:"hide"});
},
});
});
};
const copyFn = (event) => {
let e = event.target;
toClipboard(code.value)
debounceTap(e, async() => {
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 class="draw-cls-btn" @click="hide($event)"></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();
@include flexCen();
background-color: rgba($color: #000000, $alpha: 0.8);
// 抽奖弹窗样式
.draw-container {
@include box(685px, 694px);
position: relative;
.draw-cls-btn {
@include pos(82px, 82px, 300.5px, 670px);
@include bg_pos("prize/cls-btn.png");
}
.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><script setup>
import { Toast } from "vant";
import gsap from "gsap";
import Preloader from "@/plugins/Preloader";
import { loadImg, pageImg } from "@/data/imgList";
import { getMyPrize } from "@/api";
import { useMainStore } from "@/store";
// 页面配置初始化
const emit = defineEmits(["LoadPage"]);
const userStore = useMainStore();
const loadNum = ref(0);
onMounted(() => {
Preloader({
name: "加载页资源",
imgs: loadImg,
callback: (progress) => {
// console.log('进度:', progress);
},
}).then((res) => {
gsap.to(".LoadPage", {
duration: 0.2,
autoAlpha: 1,
onComplete: () => {
if (import.meta.env.VITE_MODE != "dev") {
getMyPrize({}, userStore.token).then((res) => {
if (res.code == 0) {
console.log("我的奖品", res);
if (res.data) {
console.log("有奖品");
userStore.updatePrize(res.data);
}
}
});
}
Preloader({
name: "内页资源",
imgs: pageImg,
callback: (progress) => {
gsap.set(".bar", { width: progress + "%" });
loadNum.value = progress;
},
}).then((res) => {
console.log("加载完成");
gsap.to(".LoadPage", {
duration: 1,
autoAlpha: 0,
onComplete: () => {
emit("LoadPage", { action: "hide" });
},
});
});
},
});
});
});
</script>
<template>
<div class="LoadPage" @touchmove.prevent>
<div class="load-bg"></div>
<div class="load-container">
<div class="load-icon"></div>
<div class="load-box">
<div class="bar"></div>
</div>
<div class="load-num">
<span class="num">{{ loadNum }}%</span>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.LoadPage {
@include pos(100%, 100%, 0px, 0px);
overflow: hidden;
@include flexCen();
.load-bg {
@include pos(750px, 100%, 0px, 50%);
transform: translateY(-50%);
@include bg_pos("index/bg.jpg");
}
.load-container {
position: relative;
@include box(750px, 1180px);
// transform: translateY(-50%);
.load-icon {
@include pos(363px, 136px, 335px, 320px);
@include bg_pos("load/icon.png");
}
.load-box {
@include pos(582px, 45px, 83px, 450px);
border-radius: 25px;
padding: 1px;
border: 1px solid rgb(243, 87, 4);
.bar {
@include box(0%, 38px);
border-radius: 20px;
border: 1px solid rgb(255, 255, 255);
background-image: -webkit-linear-gradient(0deg, #f7c86f 0%, #f25501 100%);
}
}
.load-num {
@include pos(235px, 80px, 256px, 511px);
@include bg_pos("load/icon-2.png");
@include flexCen();
.num {
font-size: 40px;
color: #f25501;
font-weight: 700;
/* 文字填充色 */
text-shadow:
-1px -1px 0 #ffffff,
1px -1px 0 #ffffff,
-1px 1px 0 #ffffff,
1px 1px 0 #ffffff;
/* 四个方向阴影叠加 */
}
}
<script setup>
import { debounceTap } from "@/plugins";
import gsap from "gsap";
import { Toast } from "vant";
import useClipboard from 'vue-clipboard3'
import { useMainStore } from "@/store";
import { onMounted } from "vue";
// 页面配置初始化
const emit = defineEmits(["MyPrizePage"]);
const userStore = useMainStore();
const { toClipboard } = useClipboard()
const money = ref(userStore.prizeMoney);
const code = ref(userStore.prizeCode);
const copyFn = (event) => {
let e = event.target;
toClipboard(code.value)
debounceTap(e, () => {
Toast(`复制成功:${code.value}`);
});
};
const hide = (event) => {
let e = event.target;
debounceTap(e, () => {
gsap.to(".MyPrizePage", {
duration: 0.4,
autoAlpha: 0,
onComplete: () => {
emit("MyPrizePage", { action: "hide" });
},
});
});
};
const entryAni = () => {
gsap.from(".MyPrizePage", { duration: 0.2, autoAlpha: 0 });
gsap.from(".myPrize-container", { duration: 1, autoAlpha: 0, scale: 0.7 });
};
onMounted(() => {
entryAni();
});
</script>
<template>
<div class="MyPrizePage">
<div class="myPrize-container">
<div class="myPrize-money">¥{{ money }}元</div>
<div class="myPrize-code-box">
<div class="code">{{ code }}</div>
<div class="myPrize-copy-btn" @click="copyFn($event)"></div>
</div>
<div class="myPrize-cls-btn" @click="hide($event)"></div>
</div>
</div>
</template>
<style lang="scss" scoped>
.MyPrizePage {
@include fixed();
@include flexCen();
background-color: rgba($color: #000000, $alpha: 0.8);
.myPrize-container {
position: relative;
@include box(665px, 731px);
@include bg_pos("prize/myPrize-box.png");
.myPrize-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;
}
.myPrize-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;
}
.myPrize-copy-btn {
@include box(77px, 39px);
@include bg_pos("prize/copy-btn.png");
}
}
.myPrize-cls-btn {
@include pos(82px, 82px, 517px, 114px);
@include bg_pos("prize/cls-btn.png");
}
}
}
</style><script setup name="Question">
import gsap from "gsap";
import { Toast, Progress } from "vant";
import { data } from "@/data";
import { debounceTap, FYShuffle, mostValue, judgeBigScreen } from "@/plugins";
import { useMainStore } from "@/store";
import { subAnswer } from "@/api";
import { computed } from "vue";
// 页面配置初始化
const emit = defineEmits(["hide", "showResult", "QuestionPage"]);
const userStore = useMainStore();
const props = defineProps({
questionId: {
default: 0,
required: true,
}
})
// 当前题目
const currentId = ref(props.questionId); //当前id 0~11
const questionList = ref(data); //随机打乱题库
const isChecked = ref(false)
const checkedOption = ref('')
// 答题事件
const answerFn = (item, event) => {
let e = event.target.parentElement;
debounceTap(e, () => {
gsap.set('.answer-box', { pointerEvents: 'none' })
isChecked.value = true
checkedOption.value = item
console.log('checkedOption', checkedOption.value);
if (item.result) {
gsap.set('.create-btn', { display: 'block' })
} else {
gsap.set('.return-btn', { display: 'block' })
}
})
}
// 下一题
const nextQuestion = (event) => {
let e = event.target;
debounceTap(e, () => {
gsap.to('.question-box', {
duration: 0.5, autoAlpha: 0, scale: 0.3, onComplete: () => {
emit('hide')
}
})
})
}
// 查看结果事件
const viewResult = (event) => {
let e = event.target;
debounceTap(e, () => {
// 更新海报id
userStore.posterId = currentId.value + 1
gsap.set('.question-box', { pointerEvents: 'none' })
Toast('答题结束')
Toast.loading({
message: '结果生成中',
duration: 0,
forbidClick: true,
})
if (import.meta.env.VITE_MODE != "dev") {
// 提交完成记录
subAnswer({}, userStore.token).then((res) => {
console.log("key:", res);
if (res.code == 0) {
userStore.updateDrawKey(res.data);
}
setTimeout(() => {
Toast.clear()
gsap.to('.QuestionPage', {
duration: 0.5, autoAlpha: 0, onComplete: () => {
emit("showResult", { action: "showResult" });
}
})
}, 1000)
});
} else {
setTimeout(() => {
Toast.clear()
gsap.to('.QuestionPage', {
duration: 0.5, autoAlpha: 0, onComplete: () => {
emit("showResult", { pid: currentId.value });
}
})
}, 1000)
}
})
}
onMounted(() => {
gsap.from('.question-bg', { duration: 0.5, autoAlpha: 0, })
gsap.from('.question-box', { duration: 0.5, scale: 0.4, autoAlpha: 0, })
});
const getClass = (item) => {
if (isChecked.value) {
if (checkedOption.value.aid == item.aid) {
return item.result ? 'correct' : 'incorrect'
}
}
}
</script>
<template>
<div class="QuestionPage" @touchmove.prevent>
<div class="question-bg"></div>
<div class="question-container">
<div class="question-box">
<!-- 问题序号 -->
<div class="qa-question-box">
<!-- 问题 -->
<div class="question">
<div class="question-text" v-for="item in questionList[currentId].question" :key="item">
{{ item }}
</div>
</div>
<!-- 选项 -->
<div class="answer-box">
<div class="answer" :class="getClass(item)" v-for="item in questionList[currentId].answer" :key="item.aid">
<div class="answer-text">
{{ item.aid }}.{{ item.text }}
</div>
<div class="result-icon" v-if="isChecked && (item.aid == checkedOption.aid)">
<div :class="item.result ? 'icon-correct' : 'icon-incorrect'"></div>
</div>
<!-- 可点击区域 -->
<div class="click-area" @click="answerFn(item, $event)"></div>
</div>
</div>
<div class="question-tips" v-for="(t, i) in questionList[currentId].tips" :key="i">
{{ isChecked ? `${['回答错误!', '回答正确!'][checkedOption.result]}` : `提示:${t}` }}
</div>
</div>
<div class="return-btn" @click="nextQuestion($event)"></div>
<div class="create-btn" @click="viewResult($event)"></div>
<div class="qa-megaphone"></div>
</div>
<div class="question-gold-icon-1"></div>
</div>
</div>
</template>
<style lang='scss' scope>
.QuestionPage {
@include pos(100%, 1624px, 0px, 0px);
overflow: hidden;
.question-bg {
@include pos(750px, 1624px, 0px, 0px);
// transform: translateY(-50%);
@include bg_pos("index/bg.jpg");
}
.question-container {
@include pos(750px, 1624px, 0px, 0px);
@include flexCen();
background-color: rgba($color: #000000, $alpha: 0.3);
.question-box {
@include pos(721px, 857px, 20px, 340px);
@include bg_pos("qa/paper.png");
.qa-question-box {
@include pos(563px, 660px, 74px, 126px);
display: flex;
flex-direction: column;
justify-content: space-around;
// justify-content: flex-start;
align-items: center;
// 问题样式
.question {
.question-text {
font-family: 'HarmonyOS_Sans_SC_Regular';
font-size: 34px;
color: #9e4b00;
line-height: 50px;
}
}
// 选项样式
.answer-box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
height: 200px;
// 选项通用样式
.answer {
@include box(350px, 65px);
position: relative;
border-radius: 32.5px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #fff;
color: #9e4b00;
background-color: #fff2b9;
font-weight: 700;
.answer-text {
font-size: 30px;
@include flexCen()
}
.click-area {
@include pos(350px, 65px, 0px, 0px);
border-radius: 32.5px;
}
.result-icon {
@include box(49px, 45px);
margin-left: 20px;
.icon-correct {
@include box(100%, 100%);
@include bg_pos("qa/correct.png");
}
.icon-incorrect {
@include box(49px, 45px);
@include bg_pos("qa/incorrect.png");
}
}
}
.correct {
color: #d42122;
}
.incorrect {
color: #fff2b9;
background-color: #d42122;
}
}
.question-tips {
font-size: 25px;
width: 100%;
font-family: 'HarmonyOS_Sans_SC_Regular';
color: #ab7133;
text-align: center;
padding: 10px;
}
}
}
.return-btn {
@include pos(363px, 113px, 179px, 887px);
@include bg_pos("qa/cls-btn.png");
display: none;
}
.create-btn {
@include pos(363px, 113px, 179px, 887px);
@include bg_pos("qa/create-btn.png");
display: none;
}
.qa-megaphone {
@include pos(171px, 208px, 562px, 512px);
@include bg_pos("qa/megaphone.png");
pointer-events: none;
}
}
}
</style><template>
<div class="QuestionList">
<div class="question-list-bg"></div>
<div class="question-list-container">
<div class="ql-logo"></div>
<div class="ql-swiper-box">
<swiper class="card-swiper" :slides-per-view="1" :space-between="30" navigation :loop="true">
<swiper-slide v-for="item in 3"
:style="{ width: '100%', display: 'flex', justifyContent: 'center', }">
<div class="card-slide" :class="'card-slide-' + item">
<img class="card-img" :class="'card-img-' + item" :src="getCardImg(item)" alt="" srcset="">
</div>
</swiper-slide>
</swiper>
</div>
<div class="ql-icon"></div>
<div class="ql-start-btn" @click="onShowQuestion($event)"></div>
</div>
</div>
<Question v-if="showQuestion" :question-id="questionId" @showResult="onShowResult" @hide="showQuestion = false" />
</template>
<script setup>
import { register } from 'swiper/element/bundle';
import { Swiper, SwiperSlide } from 'swiper/vue';
import 'swiper/css';
import 'swiper/css/navigation';
import Question from './Question.vue';
import { debounceTap } from "@/plugins";
import gsap from "gsap"
const emit = defineEmits(['QuestionList', "showResult"]);
const showQuestion = ref(false)
const questionId = ref(1)
// 获取灯笼图片
function getCardImg(item) {
return new URL(`../assets/images/question-list/card-${item}.png`, import.meta.url).href
}
const onShowQuestion = (event) => {
let e = event.target;
debounceTap(e, () => {
// 获取当前选中灯笼的序号 1-11
const swiper = document.querySelector('.card-swiper').swiper;
// swiper开启了loop
const activeIndex = swiper.realIndex + 1;
console.log('activeIndex', activeIndex);
questionId.value = activeIndex - 1
showQuestion.value = true
// emit('QuestionList', activeIndex);
})
}
onMounted(() => {
entryAnimation()
})
const entryAnimation = () => {
gsap.from(".QuestionList", {
duration: 0.5,
autoAlpha: 0,
});
gsap.from(".ql-swiper-box", {
duration: 0.75,
autoAlpha: 0,
y: -50,
delay: 0.2,
});
gsap.from(".ql-icon", {
duration: 0.75,
autoAlpha: 0,
x: 50,
delay: 0.2,
});
gsap.from(".ql-start-btn", {
duration: 0.75,
autoAlpha: 0,
y: 50,
delay: 0.5,
onComplete: () => {
gsap.fromTo('.ql-icon', { x: 0 }, { duration: 1, scale: 1.1, x: 25, repeat: -1, yoyo: true, ease: 'bount.in' })
}
});
}
// 展示结果
const onShowResult = (result) => {
emit('showResult', result)
showQuestion.value = false
}
register();
</script>
<style lang='scss' scoped>
.QuestionList {
@include pos(100%, 1624px, 0px, 0px);
overflow: hidden;
background: linear-gradient(135deg, #a11b15, #f80c00);
// visibility: hidden;
.question-list-bg {
@include pos(750px, 1624px, 0px, 0px);
// transform: translateY(-50%);
@include bg_pos("index/bg.jpg");
}
.question-list-container {
@include pos(750px, 1624px, 0px, 50%);
transform: translateY(-50%);
.ql-logo {
pointer-events: none;
@include pos(632px, 94px, 59px, 180px);
@include bg_pos("index/logo.png");
}
.ql-icon {
@include pos(213px, 121px, 558px, 453px);
@include bg_pos("question-list/megaphone.png");
pointer-events: none;
z-index: 9;
}
.ql-swiper-box {
@include pos(689px, 522px, 31px, 514px);
// background-color: aliceblue;
// overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
// pointer-events: none;
.card-swiper {
@include box(689px, 522px);
position: relative;
.card-slide {
pointer-events: none;
@include box(555px, 522px);
}
.card-img {
@include box(100%, 100%);
pointer-events: none;
}
}
}
.ql-start-btn {
@include pos(376px, 114px, 188px, 1129px);
@include bg_pos("index/btn.png");
z-index: 99;
}
}
/* 自定义 Swiper 左右按钮样式 */
::v-deep .swiper-button-next,
::v-deep .swiper-button-prev {
color: white;
/* 设置按钮颜色 */
// background-color: rgba(0, 0, 0, 0.5); /* 设置按钮背景颜色 */
// border-radius: 50%; /* 设置按钮圆角 */
@include box(44px, 54px);
display: flex;
align-items: center;
justify-content: center;
position: absolute;
// top: 50%;
transform: translateY(-50%);
}
::v-deep .swiper-button-next::after,
::v-deep .swiper-button-prev::after {
font-size: 24px;
/* 设置按钮图标大小 */
opacity: 0;
}
::v-deep .swiper-button-prev {
// left: 20px; /* 设置按钮位置 */
@include bg_pos("question-list/arrow-l.png");
}
::v-deep .swiper-button-next {
// right: 20px; /* 设置按钮位置 */
@include bg_pos("question-list/arrow-l.png");
// right: 0px;
}
<script setup>
import { gsap } from "gsap";
import { debounceTap } from "@/plugins";
import { useMainStore } from "@/store";
import { Toast } from "vant";
import QRCode from "qrcode";
import { reactive } from "vue";
// 页面配置初始化
const emit = defineEmits(["ResultPage"]);
const userStore = useMainStore();
const posterId = ref(userStore.posterId); //海报背景id111
console.log('海报id', posterId.value);
const posterImgList = reactive([
new URL(`../assets/images/result/poster-1.jpg`, import.meta.url).href,
new URL(`../assets/images/result/poster-1.jpg`, import.meta.url).href,
new URL(`../assets/images/result/poster-1.jpg`, import.meta.url).href,
new URL(`../assets/images/result/poster-1.jpg`, import.meta.url).href,
])
// 生成二维码逻辑
const eqcodePic = ref();
onMounted(async () => {
// 执行任务队列
await executeTasks();
});
// 这是新加的函数封装异步任务
const executeTasks = async () => {
console.log("二维码生成中...");
// 生成二维码
const eqCodeUrl = import.meta.env.VITE_URL;
eqcodePic.value = await QRCode.toDataURL(eqCodeUrl);
console.log("生成海报中...");
// 生成海报
console.log('pid', posterImgList[posterId.value - 1]);
if (posterImgList[posterId.value - 1] && eqcodePic.value) {
posterCreate(
{ width: 750, height: 2106 },
[
{ name: "bg", src: posterImgList[posterId.value - 1], pos: { w: 750, h: 2106, x: 0, y: 0 } },
{ name: "eqcode", src: eqcodePic.value, pos: { w: 178, h: 178, x: 532, y: 1887 } },
]
);
} else {
Toast.fail({ message: '生成失败' })
emit("ResultPage", { action: 'hide' })
}
};
const showPoster = () => {
gsap.to(".posterPop", {
duration: 0.3,
autoAlpha: 1,
});
gsap.from(".cls-btn-box", {
duration: 0.7,
scale: 1.2,
autoAlpha: 0,
});
gsap.from(".poster-box", {
duration: 0.7,
scale: 0.6,
autoAlpha: 0,
});
gsap.from(".save-tips", {
duration: 0.7,
scale: 0.7,
autoAlpha: 0,
delay: 0.3
});
gsap.from(".go-draw", {
duration: 0.7,
y: -30,
autoAlpha: 0,
delay: 0.5
});
gsap.from(".go-share", {
duration: 0.7,
y: -30,
autoAlpha: 0,
delay: 0.7
});
}
// 去抽奖
const goDraw = (event) => {
let e = event.target;
debounceTap(e, () => {
if (userStore.hasDraw) {
emit("ResultPage", { action: "showDraw" });
} else {
Toast("今日暂无抽奖机会");
}
});
};
// 隐藏海报弹窗
const hidePop = (event) => {
let e = event.target;
debounceTap(e, () => {
gsap.to(".posterPop", {
duration: 0.5, autoAlpha: 0,
onComplete: () => {
emit('ResultPage', { action: 'hide' })
}
});
});
};
// 展示分享
const goShare = (event) => {
let e = event.target;
debounceTap(e, () => {
gsap.to(".sharePop", { duration: 0.5, autoAlpha: 1 });
});
};
// 隐藏分享提示
const hideShare = () => {
gsap.to(".sharePop", { duration: 0.5, autoAlpha: 0 });
};
// 海报生成
const posterCreate = (option, imageArr) => {
let posterUrl = ''
const { width, height } = option
Toast.loading({
message: '海报生成中',
duration: 0,
forbidClick: true
})
let mycanvas = document.createElement('canvas') // 创建一个canvas画布元素
let ctx = mycanvas.getContext('2d')
mycanvas.style.width = `${width}px`; //设置canvas的宽
mycanvas.style.height = `${height}px`; //设置canvas的高
mycanvas.width = width
mycanvas.height = height
//Promise对象加载资源
let loader_p = [];
imageArr.map((item) => {
const _p = new Promise(resolve => {
const img = new Image();
img.crossOrigin = 'Anonymous'
img.onload = () => {
resolve(img)
};
img.src = item.src;
});
loader_p.push(_p);
})
//Promise的.all方法当所有预加载的图像加载好的回调函数
Promise.all(loader_p)
.then(imgList => {
console.log('imgList', imgList);
// 图片素材遍历绘制
imgList.map((item, index) => {
ctx.drawImage(item, imageArr[index].pos.x, imageArr[index].pos.y, imageArr[index].pos.w, imageArr[index].pos.h); //原生canvas的绘制图片方法直接百度搜索 `js drawImage`查看方法的参数
})
//海报绘制完 ,转成图片对象
return mycanvas.toDataURL('image/jpeg', 1);
})
.then(baseURL => {
//返回的图片地址就是最后海报的地址可以放在DOM显示
let posterImg = document.querySelector('#posterSrc')
posterImg.src = baseURL
setTimeout(() => {
// 展示海报
showPoster();
Toast.success({ message: '生成成功!' })
}, 500)
})
.catch(error => {
console.error("生成海报失败");
gsap.to(".posterPop", {
duration: 0.5,
autoAlpha: 0,
onComplete: () => {
emit('ResultPage', { action: 'hide' })
}
});
Toast.fail({ message: '生成失败,请重试!' });
});
// return posterUrl
}
</script>
<template>
<div class="posterPop" @touchmove.prevent>
<div class="poster-bg"></div>
<div class="poster-container">
<div class="cls-btn-box">
<div class="cls-btn" @click="hidePop($event)"></div>
</div>
<div class="poster-box">
<div class="poster" :class="'poster-' + posterId">
<img id="posterSrc" src="" alt="" srcset="">
</div>
<!-- <div class="poster-cls-btn"></div> -->
</div>
<div class="save-tips">*长按保存海报</div>
<div class="btn-box">
<div class="go-draw" @click="goDraw($event)"></div>
<div class="go-share" @click="goShare($event)"></div>
</div>
</div>
</div>
<!-- 分享提示 -->
<div class="sharePop" @click="hideShare">
<div class="tips-pic"></div>
<div class="tips-text">点击右上角分享给你的好友!</div>
</div>
</template>
<style lang="scss" scoped>
.posterPop {
@include pos(100%, 1624px, 0px, 0px);
overflow: hidden;
background: linear-gradient(135deg, #d6d1ca, #e5dccf);
visibility: hidden;
.poster-bg {
@include pos(750px, 1624px, 0px, 0px);
// transform: translateY(-50%);
@include bg_pos("index/bg.jpg");
}
.poster-container {
@include pos(750px, 1624px, 0px, 0px);
// transform: translateY(-50%);
@include flexCen();
background-color: rgba($color: #000000, $alpha: 0.3);
.cls-btn-box {
width: 617px;
display: flex;
justify-content: flex-end;
.cls-btn {
@include box(49px, 49px);
@include bg_pos("question-list/cls-btn.png");
margin-right: -20px;
}
}
.save-tips {
font-size: 20px;
line-height: 20px;
margin-top: 20px;
color: #9e4b00;
letter-spacing: 2px;
}
.poster-box {
@include box(713px, 995px);
margin-top: 20px;
overflow: hidden;
position: relative;
.poster-cls-btn{
@include pos(53px, 53px,660px,10px);
@include bg_pos("result/cls-btn.png");
}
.poster {
@include box(100%, 100%);
overflow: hidden;
#posterSrc {
@include box(100%, 100%);
opacity: 0;
}
}
.poster-1 {
@include bg_pos("result/card-1.png");
}
.poster-2 {
@include bg_pos("result/card-1.png");
}
.poster-3 {
@include bg_pos("result/card-1.png");
}
}
.btn-box {
@include box(550px, 99px);
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 20px;
.go-draw {
@include box(264px, 99px);
@include bg_pos("result/go-draw-btn.png");
}
.go-share {
@include box(274px, 95px);
@include bg_pos("result/go-share-btn.png");
}
}
}
}
.sharePop {
@include fixed();
background-color: rgba($color: #000000, $alpha: 0.54);
visibility: hidden;
.tips-pic {
@include pos(100px, 100px, 600px, 140px);
@include bg_pos("result/share-tips.svg");
stroke: #ffffff;
}
.tips-text {
font-size: 25px;
@include pos(750px, 100px, 0px, 260px);
color: #ffffff;
text-align: right;
}
}
</style><script setup>
import { debounceTap } from "@/plugins";
import gsap from "gsap";
import BScroll from '@better-scroll/core'
// 页面配置初始化
const emit = defineEmits(["RulePage"]);
const hide = (event) => {
debounceTap(event.target, () => {
scroll.value.destroy()
emit("RulePage", { action: "hide" });
});
};
let scroll = ref()
onMounted(() => {
let wrapper = document.querySelector('.wrapper')
scroll.value = new BScroll(wrapper)
gsap.from(".RulePage", { duration: 0.2, autoAlpha: 0 });
gsap.from(".rule-container", { duration: 0.5, autoAlpha: 0, scale: 0.7 });
gsap.to(".rule-arrow", { duration: 2.5, y: 10, repeat: -1, yoyo: true });
});
</script>
<template>
<div class="RulePage" @touchmove.prevent>
<div class="rule-container">
<div class="content">
<div class="rule-content">
<div class="rule-text-area wrapper">
<div>
<div class="part">
<div>活动时间2025年2月12日——2月14日</div>
<div>活动奖励:微信红包</div>
</div>
<div class="part">
<div>活动攻略:</div>
<div>
1、【猜灯谜赢红包
欢欢喜喜闹元宵】活动共设计11道题目首页进入后左右滑动选择您喜欢的花灯点击进行猜灯谜答对后即可获取专属花灯海报并参与抽奖答错时将跳转回选择花灯的页面重新答题。
</div>
<div>2、活动期间不限制参与猜灯谜次数每人每日有1次抽奖机会。</div>
</div>
<div class="part">
<div>领奖说明:</div>
<div>
1、中奖后在中奖页面复制兑换码前往<span
class="blod">[平安理财服务号]</span>消息框输入“元宵快乐”获取兑换链接,进入链接输入兑换码兑换奖品。如关闭了中奖界面,可在首页-[我的奖品]
内查看兑换码;
</div>
<div>2、成功领奖后奖品将会在24小时内自动到账请耐心等候</div>
<div>3、中奖人请在活动结束前进行兑换逾期视为弃权。</div>
<div class="part">其他:</div>
<div>
活动期间如遇到任何问题,请在<span class="blod">[平安理财服务号]</span>后台咨询,我们会在一个工作日内回复。
</div>
<div class="part">说明:平安理财有权对活动规则进行解释</div>
</div>
<div class="part">
<div>活动说明:</div>
<div>
1本活动由平安理财有限责任公司主办为保证活动的公平公正活动结束后主办方将对中奖用户信息进行核对用户若有下列任何一种行为或情况的主办方有权不经另行通知取消其参与活动以及获奖资格收回奖品权益并保留追究其法律责任的权利
</div>
<div>
(2)以任何机器人软件、蜘蛛软件、爬虫软件、刷奖软件或其它任何自动方式、不正当手段等参与本活动;同一用户(包含相同手机号、相同收货信息、相同移动设备号、相同IP地址等单日内恶意切换微信账号参加活动扰乱正常抽奖秩序影响活动公平性的
</div>
<div>
(3)有任何违反法律法规、诚实信用、公序良俗、公平公正、平安理财平台规则等行为;
</div>
<div>
(4)平安理财保留调整、暂停和终止本活动的权利,并经公告后生效;
</div>
<div>
(5)用户参与本活动,即视为理解并同意本活动细则。在法律法规及监管规定的范围内,平安理财有权对活动规则进行解释,并根据活动实际情况对本活动的规则进行变动或调整,相关变动或调整将公布在规则页面,并于公布时即时生效。
</div>
</div>
<div class="margin-bottom-area"></div>
</div>
</div>
</div>
<div class="rule-bottom-bg"></div>
<div class="rule-arrow"></div>
<div class="rule-icon"></div>
</div>
</div>
<div class="rule-cls-btn" @click="hide($event)"></div>
</div>
</template>
<style lang="scss" scoped>
.RulePage {
@include fixed();
@include flexCen();
background-color: rgba($color: #000000, $alpha: 0.3);
.rule-container {
position: relative;
@include box(685px, 876px);
overflow: hidden;
.content {
.rule-content {
@include box(685px, 876px);
@include bg_pos("rule/rule-box.png");
position: relative;
overflow: hidden;
.rule-text-area {
@include pos(635px, 709px, 25px, 83px);
overflow: hidden;
// overflow-y: scroll;
padding: 0px 20px;
.part {
color: #a74f00;
font-size: 20px;
line-height: 35px;
margin-top: 30px;
text-align: justify;
padding: 0 10px;
font-family: 'HarmonyOS_Sans_SC_Regular';
}
.blod {
font-weight: 700;
color: #a74f00;
}
.margin-bottom-area {
// margin-bottom: 100px;
height: 100px;
}
}
}
.rule-arrow {
@include pos(161px, 102px, 262px, 682px);
@include bg_pos("rule/arrow.png");
pointer-events: none;
}
.rule-bottom-bg {
// @include pos(685px, 102px, 0px, 712px);
// border-radius: 10px;
// pointer-events: none;
// background-image: -webkit-linear-gradient(90deg, rgba(255, 238, 186, 0.7), rgba(255, 255, 255, 0.1) 100%);
}
.rule-icon {
@include pos(97px, 120px, 561px, 25px);
@include bg_pos("rule/icon.png");
pointer-events: none;
}
}
}
.rule-cls-btn {
@include box(49px, 49px);
@include bg_pos("rule/cls-btn.png");
margin-top: 0px;
}
}
</style>export const data = [
{
id: 1,
question: ["欢迎你打卡这座8D魔幻山城轨道交通在楼宇腹中游走立交桥如基因链螺旋攀升万家灯火在悬崖上生长出十三层吊脚楼。这座将三维空间玩到极致的城市是"],
answer: [
{
aid: "A",
text: "重庆",
result: 1,
},
{
aid: "B",
text: "成都",
result: 0,
},
],
tips: [
`一座被火锅”包围“的城市`,
],
},
{
id: 2,
question: ["欢迎你来到这处塞上秘境:沙海与翡翠绿洲相拥而眠,千年岩画镌刻着骆驼商队的丝路密码。母亲河在此织就翡翠腰带,烽燧残垣与星空共同丈量着天地琴弦。这处同时拥有流动史诗与永恒星辰的秘境是?"],
answer: [
{
aid: "A",
text: "宁夏",
result: 1,
},
{
aid: "B",
text: "新疆",
result: 0,
},
],
tips: [
`有”塞上江南“美称的少数民族自治区`,
],
},
{
id: 3,
question: ["欢迎你打卡这座『四季如春』的童话城:鲜花在冬天抢了春天的戏,海鸥与彩云齐飞,石头森林藏着万年奇景,蓝花雨巷把街道染成紫色星河。问:这座被春天永久收藏的城市是?"],
answer: [
{
aid: "A",
text: "贵阳",
result: 0,
},
{
aid: "B",
text: "昆明",
result: 1,
},
],
tips: [
`”彩云之南“的首府`,
],
},
{
id: 4,
question: ["欢迎你闯入这座通宵狂欢的『古今混搭城』唐代楼阁挂满灯笼网红不倒翁小姐姐在人群中飘摇。猜猜这是哪座古都的网红步行街能把长安城的盛世繁华变成24小时不打烊的嘉年华的城市是"],
answer: [
{
aid: "A",
text: "太原",
result: 0,
},
{
aid: "B",
text: "西安",
result: 1,
},
],
tips: [
`拥有被成为”世界第八大奇迹“的秦始皇陵兵马俑`,
],
},
{
id: 5,
question: ["欢迎你来到这座『科技主题乐园』——摩天大楼间闪着AI电子屏瀑布无人机表演在夜空中拼出会动的二维码华强北的电子零件能拼出太空卫星哪座城市用代码写诗让城市灯光秀变成通往未来的动画片"],
answer: [
{
aid: "A",
text: "深圳",
result: 1,
},
{
aid: "B",
text: "广州",
result: 0,
},
],
tips: [
`全国最早实行对外开放的四个经济特区之一`,
],
},
];
}
</style>
.btn {
@include box(200px, 40px);
line-height: 40px;
text-align: center;
background-color: aliceblue;
}
}
}
</style>
1234567890.,/'