Files
palc-newyear2024/src/components/Question.vue
2025-12-17 18:04:09 +08:00

449 lines
12 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.
<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";
// 页面配置初始化
const emit = defineEmits(["QuestionPage"]);
const userStore = useMainStore();
// 当前题目
// const currentId = ref(props.questionId); //当前id 0~4
const currentId = ref(0); //当前id 0~3
const questionList = ref(data); //随机打乱题库
const isChecked = ref(false);
const checkedOption = ref("");
const QaResult = ref(1); //当前答题结果
const correctObj = 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);
QaResult.value = item.result;
// 设置正确选项
correctObj.value = questionList.value[currentId.value].answer.find(
(item) => item.result == 1
);
console.log("correctObj", correctObj.value);
gsap.to(".qp-result ", { duration: 0.5, autoAlpha: 1, delay: 1 });
});
};
// 下一题
const nextQuestion = (event) => {
let e = event.target;
debounceTap(e, () => {
gsap.to(".qp-result", {
duration: 0.5,
autoAlpha: 0,
onComplete: () => {
isChecked.value = false;
checkedOption.value = "";
gsap.set(".answer-box", { pointerEvents: "auto" });
currentId.value++;
},
});
});
};
// 查看结果事件
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,
});
let dev = "dev";
if (dev != "dev") {
// 提交完成记录
subAnswer({}, userStore.token).then((res) => {
console.log("key:", res);
if (res.code == 0) {
userStore.updateDrawKey(res.data);
}
setTimeout(() => {
Toast.clear();
gsap.to(".QuestionPage,.qp-result", {
duration: 0.5,
autoAlpha: 0,
onComplete: () => {
emit("QuestionPage", { action: "showResult" });
},
});
}, 1000);
});
} else {
setTimeout(() => {
Toast.clear();
gsap.to(".QuestionPage,.qp-result", {
duration: 0.5,
autoAlpha: 0,
onComplete: () => {
emit("QuestionPage", { action: "showResult" });
},
});
}, 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="question-serial">
<div>
<div class="serial-icon"></div>
<div class="serial-text">
{{ ["题目一", "题目二", "题目三", "题目四"][currentId] }}
</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"
: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">
<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="question-gold-icon-1"></div>
</div>
</div>
<div class="qp-result">
<div
class="qp-result-box"
:class="!QaResult ? 'qp-result-box-0' : 'qp-result-box-1'"
>
<div
class="qp-result-icon"
:class="!QaResult ? 'is-incorrect' : ''"
></div>
<div class="qp-result-content">
<div
class="qp-result-text"
:class="!QaResult ? 'text-bg-2' : 'text-bg-1'"
>
{{ QaResult ? "答对啦" : "答错啦" }}
</div>
<div class="qp-tips" v-if="!QaResult">
答案:{{ correctObj.aid }}.{{ correctObj.text }}
</div>
<div class="qp-tips-text">解析{{ questionList[currentId].tips[0] }}</div>
</div>
</div>
<div
class="next-btn"
@click="
currentId == questionList.length - 1
? viewResult($event)
: nextQuestion($event)
"
>
{{ currentId == questionList.length - 1 ? "查看结果" : "下一题" }}
</div>
</div>
</template>
<style lang="scss" scope>
.QuestionPage {
@include pos(100%, 1624px, 0px, 0px);
overflow: hidden;
.question-bg {
@include pos(750px, 1624px, 0px, 0px);
background-image: -webkit-linear-gradient(
-90deg,
#ffffff 15%,
#4ebbe5 100%
);
}
.question-container {
@include pos(750px, 1624px, 0px, 0px);
@include flexCen();
background-color: rgba($color: #000000, $alpha: 0.3);
.question-box {
@include pos(727px, 769px, 22px, 308px);
@include bg_pos("qa/paper.png");
.question-serial {
@include pos(560px, 90px, 110px, 34px);
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
.serial-text {
color: #ffffff;
font-size: 40px;
}
.serial-num {
font-size: 60px;
padding-right: 20px;
color: transparent;
-webkit-text-stroke: 3px #ffffff; /* 控制描边粗细和颜色 */
text-stroke: 3px #ffffff;
opacity: 0.5;
}
}
.qa-question-box {
@include pos(563px, 660px, 74px, 116px);
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
// 问题样式
.question {
margin: 40px auto;
.question-text {
font-family: "FZZY_Regular";
font-size: 34px;
color: #55240d;
line-height: 50px;
text-align: justify;
font-weight: 700;
}
}
// 选项样式
.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;
}
}
}
}
}
.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, 526px);
position: relative;
.qp-result-icon {
@include pos(112px, 112px, 223px, -30px);
@include bg_pos("qa/correct-icon.png");
}
.is-incorrect {
@include bg_pos("qa/incorrect-icon.png");
}
.qp-result-content {
@include pos(569px, 430px, 0px, 95px);
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
.qp-result-text {
@include box(319px, 47px);
text-align: center;
width: 100%;
font-size: 35px;
color: #ffffff;
margin: 20px auto;
}
.text-bg-1 {
@include bg_pos("qa/tips-bg.png");
}
.text-bg-2 {
@include bg_pos("qa/tips-bg-2.png");
}
.qp-tips {
width: 80%;
text-align: center;
font-size: 25px;
color: #ff0000;
}
.qp-tips-text {
width: 100%;
padding: 10px 20px;
font-size: 25px;
line-height: 40px;
text-align: justify;
color: #b3640d;
}
}
}
.qp-result-box-1 {
@include bg_pos("qa/result-box.png");
}
.qp-result-box-0 {
@include bg_pos("qa/result-box-2.png");
}
.next-btn {
@include box(190px, 65px);
border: 1px solid #ffffff;
@include flexCen();
font-size: 35px;
color: #ffffff;
border-radius: 31px;
margin-top: 50px;
}
}
</style>