初始化端午项目

This commit is contained in:
梁泽军
2025-05-20 18:28:02 +08:00
parent d239b3f8fb
commit 749a61f00b
95 changed files with 1399 additions and 1387 deletions

View File

@@ -5,51 +5,32 @@ import { data } from "@/data";
import { debounceTap, FYShuffle, mostValue, judgeBigScreen } from "@/plugins";
import { useMainStore } from "@/store";
import { subAnswer } from "@/api";
import Preloader from "@/plugins/Preloader";
import { pageResultImg } from "@/data/imgList";
// 页面配置初始化
const emit = defineEmits(["QuestionPage"]);
const emit = defineEmits([ "QuestionPage"]);
const userStore = useMainStore();
// 当前题目
const currentId = ref(0); //当前id 0~11
// const currentId = ref(props.questionId); //当前id 0~4
const currentId = ref(0); //当前id 0~3
const questionList = ref(data); //随机打乱题库
const answerList = ref([]); // 答案库统计
const activeId = ref(""); // 当前题目所选答案选项
const showResultBtn = ref(false);
const isChecked = ref(false);
const checkedOption = ref("");
const QaResult = ref(1); //当前答题结果
// 答题事件
const answerFn = (item, event) => {
let e = event.target.parentElement;
activeId.value = item.aid; //更新选中状态
// console.log("选项", item);
debounceTap(e, () => {
let cid = questionList.value[currentId.value].id;
let has = answerList.value.findIndex((obj) => obj.id === cid);
// 答案库中未存在该题的结果则新增,存在则更新最新选项
if (has == -1) {
answerList.value.push({
id: cid,
aid: item.aid,
answer: item.text,
});
} else {
answerList.value[has].aid = item.aid;
answerList.value[has].answer = item.text;
}
gsap.set(".option-tips,.analysis", { autoAlpha: 1 });
debounceTap(e, () => {
gsap.set(".answer-box", { pointerEvents: "none" });
isChecked.value = true;
// console.log("currentId.value", currentId.value);
if (currentId.value == 2) {
// console.log("over");
gsap.set(".create-btn", { autoAlpha: 1 });
} else {
gsap.set(".next-btn", { autoAlpha: 1 });
}
checkedOption.value = item;
console.log("checkedOption", checkedOption.value);
QaResult.value = item.result;
gsap.to(".qp-result ", { duration: 0.5, autoAlpha: 1, delay: 1 });
});
};
@@ -57,12 +38,16 @@ const answerFn = (item, event) => {
const nextQuestion = (event) => {
let e = event.target;
debounceTap(e, () => {
isChecked.value = false;
gsap.set(".option-tips,.analysis", { autoAlpha: 0 });
currentId.value++;
activeId.value = "";
gsap.set(".answer-box", { pointerEvents: "initial" });
gsap.set(".next-btn", { autoAlpha: 0 });
gsap.to(".qp-result", {
duration: 0.5,
autoAlpha: 0,
onComplete: () => {
isChecked.value = false;
checkedOption.value = "";
gsap.set(".answer-box", { pointerEvents: "auto" });
currentId.value++;
},
});
});
};
@@ -70,8 +55,9 @@ const nextQuestion = (event) => {
const viewResult = (event) => {
let e = event.target;
debounceTap(e, () => {
// 随机生成海报id
userStore.updatePosterId(getRandomNumber([1, 2, 3]));
// 更新海报id
userStore.posterId = currentId.value + 1;
gsap.set(".question-box", { pointerEvents: "none" });
Toast("答题结束");
Toast.loading({
@@ -94,7 +80,7 @@ const viewResult = (event) => {
duration: 0.5,
autoAlpha: 0,
onComplete: () => {
emit("QuestionPage", { action: "showResult" });
emit("showResult", { action: "showResult" });
},
});
}, 1000);
@@ -102,11 +88,11 @@ const viewResult = (event) => {
} else {
setTimeout(() => {
Toast.clear();
gsap.to(".QuestionPage", {
gsap.to(".QuestionPage,.qp-result", {
duration: 0.5,
autoAlpha: 0,
onComplete: () => {
emit("QuestionPage", { action: "showResult" });
emit("QuestionPage", { action: 'showResult' });
},
});
}, 1000);
@@ -114,41 +100,18 @@ const viewResult = (event) => {
});
};
// 从数组中随机生成一个数字
const getRandomNumber = (arr) => {
var randomIndex = Math.floor(Math.random() * arr.length);
return arr[randomIndex];
};
onMounted(() => {
gsap.from(".question-bg", { duration: 0.5, autoAlpha: 0 });
gsap.from(".question-box", { duration: 0.5, y: 30, autoAlpha: 0 });
gsap.from(".answer-box", {
duration: 0.5,
y: 30,
autoAlpha: 0,
onComplete: () => {
// 开始加载答题页面资源
Preloader({
name: "加载结果页资源",
imgs: pageResultImg,
callback: (progress) => {
// console.log("进度:", progress);
},
}).then((res) => {
console.log("done!");
});
},
});
gsap.to(".question-tree", {
duration: 3,
transformOrigin: "0% 70%",
rotation: "-10deg",
repeat: -1,
yoyo: true,
ease: "none",
});
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>
@@ -156,12 +119,15 @@ onMounted(() => {
<div class="question-bg"></div>
<div class="question-container">
<div class="question-box">
<div class="question-tree"></div>
<div class="question-con">
<!-- 问题序号 -->
<div class="qa-number">{{ questionList[currentId].id }}</div>
<div class="qa-question-box">
<!-- 问题 -->
<div class="question-serial">
<div>
<div class="serial-icon"></div>
<div class="serial-text">{{ currentId + 1 }}</div>
</div>
<div class="serial-num">{{ currentId+1 }}/{{ questionList.length }}</div>
</div>
<div class="qa-question-box">
<div class="question">
<div
class="question-text"
v-for="item in questionList[currentId].question"
@@ -170,242 +136,254 @@ onMounted(() => {
{{ item }}
</div>
</div>
</div>
</div>
<!-- 选项 -->
<div class="answer-box">
<div
class="answer"
v-for="(item, index) in questionList[currentId].answer"
:class="[
isChecked ? item.result + '-text' : '',
isChecked ? item.result + '-box' : '',
]"
:key="item.aid"
>
<div class="answer-text" v-for="a in item.text" :key="a">
{{ item.aid }}.{{ a }}
<!-- 选项 -->
<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="option-tips">
<div :class="item.result"></div>
</div>
<!-- 对话框气泡 -->
<div class="bubble-1"></div>
<div :class="index == 0 ? 'bubble-left' : 'bubble-right'"></div>
<!-- 可点击区域 -->
<div class="click-area" @click="answerFn(item, $event)"></div>
<!-- <div class="question-tips" v-for="(t, i) in questionList[currentId].tips" :key="i">
<div v-if='questionList[currentId].tips.length == 1'>
{{ isChecked ? `${['回答错误!', '回答正确!'][checkedOption.result]}` : `提示:${t}` }}
</div>
<div v-else>
{{ isChecked ? `${i == 0 ? ['回答错误', '回答正确'][checkedOption.result] : ''}` : `${i == 0 ? '提示' : ''}${t}` }}
</div>
</div> -->
</div>
<div class="return-btn" @click="nextQuestion($event)"></div>
<div class="create-btn" @click="viewResult($event)"></div>
</div>
<!-- 解析 -->
<!-- <div class="analysis">
<div v-for="li in questionList[currentId].analysis" :key="li">
<span class="analysis-icon"></span>
{{ li }}
</div>
</div> -->
<div class="next-btn" @click="nextQuestion($event)"></div>
<div class="create-btn" @click="viewResult($event)"></div>
<div class="question-gold-icon-1"></div>
</div>
</div>
<div class="qp-result">
<div class="qp-result-box">
<div
class="qp-result-icon"
:class="!QaResult ? 'is-incorrect' : ''"
></div>
<div class="qp-result-text">{{ QaResult ? "答对啦" : "答错啦" }}</div>
<div class="qp-tips-text">{{ questionList[currentId].tips[0] }}</div>
<div class="qp-result-btn"></div>
</div>
<div
class="next-btn"
@click="
currentId == questionList.length - 1
? viewResult($event)
: nextQuestion($event)
"
>
{{ currentId == questionList.length - 1 ? "查看结果" : "下一题" }}
</div>
<!-- 进度条 -->
<Progress
:percentage="((currentId + 1) / 3) * 100"
pivot-color="#7232dd"
:show-pivot="false"
color="linear-gradient(to right, rgb(49, 116, 246), rgb(83, 131, 227))"
/>
</div>
</template>
<style lang='scss' scope>
<style lang="scss" scope>
.QuestionPage {
@include pos(100%, 100%, 0px, 0px);
@include pos(100%, 1624px, 0px, 0px);
overflow: hidden;
.question-bg {
@include pos(750px, 1624px, 0px, 50%);
transform: translateY(-50%);
@include bg_pos("qa/bg.jpg");
@include pos(750px, 1624px, 0px, 0px);
background-image: -webkit-linear-gradient(
-90deg,
#ffffff 15%,
#4ebbe5 100%
);
}
.question-container {
@include pos(750px, 1180px, 0px, 50%);
transform: translateY(-50%);
@include pos(750px, 1624px, 0px, 0px);
@include flexCen();
justify-content: space-around;
background-color: rgba($color: #000000, $alpha: 0.3);
.question-box {
@include box(696px, 441px);
@include bg_pos("qa/question-box.png");
position: relative;
@include pos(727px, 769px, 22px, 308px);
@include bg_pos("qa/paper.png");
.question-tree {
@include pos(277px, 232px, -100px, -141px);
@include bg_pos("qa/tree.png");
}
.question-con {
@include pos(696px, 441px, 0px, 0px);
@include bg_pos("qa/question-box.png");
.qa-number {
@include pos(696px, 86px, 0px, 0px);
font-size: 40px;
color: #ffffff;
font-weight: 700;
display: flex;
justify-content: center;
align-items: center;
text-align: justifyLeft;
text-shadow: 0px 6px 6px rgba(49, 116, 246, 0.9);
}
.qa-question-box {
@include pos(626px, 243px, 37px, 177px);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
// 问题样式
.question-text {
width: 100%;
font-family: "HarmonyOS_Sans_SC_Regular";
font-size: 30px;
letter-spacing: 1.5px;
color: #065ac6;
text-align: center;
padding: 40px;
text-align: justify;
line-height: 55px;
}
}
}
}
// 选项样式
.answer-box {
@include box(750px, 205px);
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
color: #065ac6;
font-size: 26px;
line-height: 80px;
margin-top: 40px;
padding: 0 50px;
font-family: "HarmonyOS_Sans_SC_Regular";
.answer {
.question-serial {
@include pos(560px, 90px, 110px, 34px);
display: flex;
flex-direction: row;
justify-content: space-around;
line-height: 75px;
height: 74px;
padding: 0px 30px;
border-radius: 50px;
border: 1px solid rgb(255, 255, 255);
background-color: rgba(255, 255, 255, 0.361);
position: relative;
box-shadow: 0px 0px 5px rgba(255, 255, 255, 0.361) inset;
.answer-text {
white-space: nowrap;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
.serial-text {
color: #ffffff;
font-size: 40px;
}
.bubble-1 {
@include pos(55px, 5px, 88px, 7px);
@include bg_pos("qa/bubble-1.png");
}
.bubble-left {
@include pos(26px, 15px, 88px, 72px);
border: 10px solid transparent;
border-top-color: rgba(255, 255, 255, 0.9);
border-bottom: 0;
margin-left: -10px;
margin-bottom: -10px;
// @include bg_pos("qa/jiao-1.png");
}
.bubble-right {
@include box(26px, 15px);
border: 10px solid transparent;
border-top-color: rgba(255, 255, 255, 0.9);
border-bottom: 0;
margin-left: -5px;
margin-bottom: -5px;
position: absolute;
top: 72px;
right: 88px;
}
.click-area {
@include pos(100%, 100%, 0px, 0px);
border-radius: 47.5px;
// background: rgba($color: #000000, $alpha: 0.5);
.serial-num {
font-size: 60px;
padding-right: 20px;
color: transparent;
-webkit-text-stroke: 3px #ffffff; /* 控制描边粗细和颜色 */
text-stroke: 3px #ffffff;
}
}
.correct-text {
color: #e74c00;
// background-color: rgba(255, 255, 255, 0.471);
box-shadow: 5px 5px 5px rgba(255, 240, 192, 0.471) inset;
}
.qa-question-box {
@include pos(563px, 660px, 74px, 116px);
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
.option-tips {
@include box(40px, 40px);
visibility: hidden;
// 问题样式
.question {
margin: 40px auto;
.correct {
@include box(74px, 74px);
@include bg_pos("qa/correct.png");
position: absolute;
right: -20px;
top: 0px;
.question-text {
font-family: "FZZY_Regular";
font-size: 34px;
color: #55240d;
line-height: 50px;
text-align: justify;
font-weight: 700;
}
}
.incorrect {
@include box(74px, 74px);
@include bg_pos("qa/incorrect.png");
position: absolute;
right: -20px;
top: 0px;
// 选项样式
.answer-box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
// height: 200px;
// 选项通用样式
.answer {
width: 504px;
position: relative;
border-radius: 32.5px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #fff;
color: #9e4b00;
background-color: #fff2b9;
margin-bottom: 30px;
padding: 10px 20px;
.answer-text {
font-size: 30px;
line-height: 40px;
@include flexCen();
}
.click-area {
width: 100%;
height: 100%;
border-radius: 32.5px;
position: absolute;
}
.result-icon {
position: absolute;
@include box(504px, 45px);
top: 50%;
transform: translateY(-55%);
left: 460px;
.icon-correct {
@include box(76px, 56px);
@include bg_pos("qa/correct.png");
}
.icon-incorrect {
@include box(52px, 54px);
@include bg_pos("qa/incorrect.png");
}
}
}
.correct {
color: #ffe8b4;
font-weight: 700;
// background: linear-gradient(-45deg, #facc22, #f83600);
background-color: #f83600;
border: 2px solid #f0d0ad;
// 外发光效果
box-shadow: 0px 5px 10px rgba($color: #0188d5, $alpha: 0.5);
border-radius: 32.5px;
}
.incorrect {
color: #f83600;
font-weight: 700;
}
}
.question-tips {
font-size: 25px;
width: 100%;
font-family: "FZZY_Regular";
color: #ab7133;
text-align: center;
padding: 5px;
}
}
}
// 解析样式
.analysis {
visibility: hidden;
width: 95%;
font-family: "HarmonyOS_Sans_SC_Regular";
font-size: 25px;
color: #e74c00;
text-align: justify;
padding: 10px 50px;
// height: 100px;
.analysis-icon {
display: inline-block;
@include box(32px, 31px);
@include bg_pos("qa/analysis-icon.png");
}
}
.next-btn {
@include box(256px, 70px);
@include bg_pos("qa/next-btn.png");
// display: none;
visibility: hidden;
}
.create-btn {
@include box(256px, 70px);
@include bg_pos("qa/create-btn.png");
// display: none;
visibility: hidden;
}
}
}
</style>
.qp-result {
@include pos(100%, 1624px, 0px, 0px);
overflow: hidden;
@include flexCen();
background-color: rgba($color: #000000, $alpha: 0.6);
visibility: hidden;
.qp-result-box {
@include box(569px, 399px);
@include bg_pos("qa/result-box.png");
position: relative;
.qp-result-icon {
@include pos(112px, 112px, 222px, -28px);
@include bg_pos("qa/correct-icon.png");
}
.is-incorrect {
@include bg_pos("qa/incorrect-icon.png");
}
.qp-result-text {
@include pos(569px, 50px, 0px, 104px);
@include flexCen();
font-size: 35px;
color: #ffffff;
}
.qp-tips-text {
@include pos(569px, 220px, 0px, 150px);
padding: 20px;
font-size: 25px;
line-height: 35px;
text-align: justify;
color: #b3640d;
}
}
.next-btn {
@include box(190px, 65px);
border: 1px solid #ffffff;
@include flexCen();
font-size: 35px;
color: #ffffff;
border-radius: 31px;
margin-top: 50px;
}
}
</style>