Browse Source

可以进行测试

chenzhen/feature-20251107115823-股票知识测评
chenzhen 2 months ago
parent
commit
86ea21b18b
  1. 6
      src/views/HomeView.vue
  2. 608
      src/views/TextView.vue
  3. 2
      vue.config.js

6
src/views/HomeView.vue

@ -21,9 +21,9 @@ export default {
// jwcode:90098889,//
// jwcode:90098890,//
// jwcode:90098891,//
jwcode:90098892,//
// jwcode:90098892,//
// jwcode:90098893,//
// jwcode:90098894,//
jwcode:90098894,//
};
localStorage.setItem('submissionData', JSON.stringify(submissionData));
console.log('存储的数据:', localStorage.getItem('submissionData'));
@ -65,7 +65,7 @@ export default {
}
.image {
position: absolute;
position: fixed;
width: 200px;
min-height: 160px;
max-height: 160px;

608
src/views/TextView.vue

@ -1,47 +1,46 @@
<template>
<div class="home">
<div class="top">
<div @click="showConfirmDialog" class="ret-container">
<img src="../assets/return.jpg" alt="返回" class="ret">
<div class="img-top" @click="showConfirmDialog">
<img src="../assets/return.jpg" alt="返回" class="img1">
</div>
<h1>📈股票知识评测系统</h1>
<p>全方面评估您的股票投资知识水平获取个性化学习建议</p>
</div>
<div class="confirm-dialog dialog-overlay" v-if="showDialog">
<div class="dialog-content">
<div class="popup-all popup-background" v-if="showDialog">
<div class="popup-content">
<h3>确认提示</h3>
<p>您还未提交确定要退出吗</p>
<div class="dialog-buttons">
<div class="popup-buttons">
<button class="cancel-btn" @click="closeDialog">取消</button>
<button class="confirm-btn" @click="confirmExit">确定</button>
</div>
</div>
</div>
<div class="confirm-dialog dialog-overlay" v-if="showTeam">
<div class="dialog-content">
<div class="popup-all popup-background" v-if="showTeam">
<div class="popup-content">
<h3>确认提示</h3>
<p>您确定要提交吗</p>
<div class="dialog-buttons">
<div class="popup-buttons">
<button class="cancel-btn" @click="closeSubmit">取消</button>
<button class="confirm-btn" @click="submitAnswers">确定</button>
</div>
</div>
</div>
<div class="clearfix">
<div class="content">
<div class="block">
<div class="schedule" :style="{ width: progress + '%' }"></div>
</div>
<div class="questions-container">
<div v-for="question in currentQuestions" :key="question.id" class="question-card">
<div class="question-header">
<div class="question-all">
<div v-for="question in currentQuestions" :key="question.id" class="left-question-card">
<div class="question">
<span class="text-lg font-bold mr-2">{{ question.id }}</span>
<span class="text">{{ question.id }}</span>
{{ question.stem }}
</div>
</div>
<div class="options">
<label
class="option"
@ -102,18 +101,19 @@
</div>
</div>
</div>
<div class="nav-buttons">
<div class="buttons-left">
<button
class="nav-btn prev"
@click="prevPage"
class="before-btn"
@click="before"
:disabled="currentPage === 1"
>
上一页
</button>
<span class="page-info"> {{ currentPage }} / {{ totalPages }} </span>
<span class="page"> {{ currentPage }} / {{ totalPages }} </span>
<button
class="nav-btn next"
@click="nextPage"
class="next-btn"
@click="next"
:disabled="currentPage === totalPages"
>
下一页
@ -122,15 +122,15 @@
</div>
<div class="right">
<h3> 倒计时</h3>
<div class="time-module">
<div class="countdown"> {{ countdown }}</div>
<div class="countdown">{{ countdown }}</div>
</div>
<div class="question-nav">
<h3>📝 题目导航</h3>
<div class="question-grid" v-show="page === 1">
<div class="right-question-card" v-show="page === 1">
<div
class="question-number"
class="question-number normal"
:class="getQuestionStatusClass(i)"
@click="goToPageByQuestion(i)"
v-for="i in 25"
@ -139,9 +139,9 @@
<span class="question-text">{{ i }}</span>
</div>
</div>
<div class="question-grid" v-show="page === 2">
<div class="right-question-card" v-show="page === 2">
<div
class="question-number"
class="question-number normal"
:class="getQuestionStatusClass(i + 25)"
@click="goToPageByQuestion(i + 25)"
v-for="i in 25"
@ -151,33 +151,33 @@
</div>
</div>
<div class="pagination">
<div class="button-right">
<button
class="pagination-btn"
class="right-before-btn"
@click="changeNavPage(1)"
:class="{ active: page === 1 }"
>
上一页
</button>
<button
class="pagination-btn"
class="right-next-btn"
@click="changeNavPage(2)"
:class="{ active: page === 2 }"
>
下一页
</button>
</div>
</div>
<div class="statistics">
<h3>📊 答题统计</h3>
<div class="statistics">
<div class="statistics-item">
<span class="statistics-label">答题进度:</span>
<span class="statistics-value">{{ answeredCount }}/{{ totalQuestions }}</span>
</div>
</div>
<button class="submit-btn" @click="closeTeamPrompt">🚀 提交试卷</button>
<div class="button-right-bottom">
<button class="right-bottom-btn" @click="closeTeamPrompt">🚀 提交试卷</button>
</div>
</div>
</div>
@ -189,17 +189,17 @@ export default {
name: 'TextView',
data() {
return {
questions: [], //
questions: [],
currentPage: 1,
page: 1,
questionsPerPage: 2, // 2
questionsPerPage: 2,
answers: {},
startTime: new Date(),
countdownMinutes: 30,
countdown: '',
timer: null,
isSubmitted: false,
totalQuestions: 50, // 50
totalQuestions: 50,
questionStates: {},
showDialog: false,
showTeam: false,
@ -211,7 +211,6 @@ export default {
}
},
computed: {
//
currentQuestions() {
const startIndex = (this.currentPage - 1) * this.questionsPerPage;
return [
@ -233,13 +232,11 @@ export default {
progress() {
return this.completionRate;
},
// ID
currentQuestionIds() {
return this.currentQuestions.map(q => q ? q.id : null).filter(Boolean);
}
},
methods: {
//
async fetchQuestions() {
try {
const response = await axios.post('http://192.168.40.41:8000/api/knowledge/questions');
@ -249,70 +246,35 @@ export default {
}
},
// - 50
getDefaultQuestions() {
//
const defaultQuestions = [];
for (let i = 1; i <= 50; i++) {
defaultQuestions.push({
id: i,
stem: `这是第${i}个股票知识测试题目`,
A: `选项A - 第${i}`,
B: `选项B - 第${i}`,
C: `选项C - 第${i}`,
D: `选项D - 第${i}`
});
}
return defaultQuestions;
},
//
getQuestionIndex(questionId) {
// questions
const index = this.questions.findIndex(q => q.id === questionId);
return index !== -1 ? index + 1 : questionId;
},
//
showConfirmDialog() {
this.showDialog = true;
},
//
closeDialog() {
this.showDialog = false;
},
// 退
confirmExit() {
this.showDialog = false;
//
this.$router.push('/');
},
//
closeTeamPrompt() {
this.showTeam = true;
},
closeSubmit() {
this.showTeam = false;
},
// submitAnswers() {
// this.showTeam = false;
// },
//
getAnswer(questionId) {
return this.answers[questionId] || '';
},
//
setAnswer(questionId, answer) {
this.$set(this.answers, questionId, answer);
},
//
getQuestionStatusClass(questionNumber) {
const isCurrent = this.currentQuestionIds.includes(questionNumber);
const isAnswered = !!this.answers[questionNumber];
@ -326,46 +288,42 @@ export default {
}
},
//
changeNavPage(newPage) {
this.page = newPage;
},
//
changePage(newPage) {
if (newPage >= 1 && newPage <= this.totalPages) {
this.currentPage = newPage;
// 25
const startQuestion = (newPage - 1) * this.questionsPerPage + 1;
this.page = Math.ceil(startQuestion / 25);
}
},
//
goToPageByQuestion(questionNumber) {
const page = Math.ceil(questionNumber / this.questionsPerPage);
this.changePage(page);
//
this.page = Math.ceil(questionNumber / 25);
},
//
prevPage() {
before() {
if (this.currentPage > 1) {
this.currentPage--;
}
if(this.currentPage < 13){
this.page=1;
}
},
//
nextPage() {
if (this.currentPage < this.totalPages) {
next() {
if (this.currentPage < 25) {
this.currentPage++;
}
if(this.currentPage > 13){
this.page=2;
}
},
//
updateCountdown() {
const now = new Date();
const elapsedMinutes = (now - this.startTime) / (1000 * 60);
@ -376,35 +334,30 @@ export default {
this.countdown = `${minutes}:${seconds}`;
//
if (remainingMinutes <= 0 && !this.isSubmitted) {
this.isSubmitted = true;
this.submitAnswers();
}
},
//
async submitAnswers() {
try {
if (Object.keys(this.answers).length === 0) {
this.showTeam=false;
return;
}
//
const formattedAnswers = Object.keys(this.answers).map(questionId => ({
questionId: parseInt(questionId),
userAnswer: this.answers[questionId]
}));
const savedData = JSON.parse(localStorage.getItem('submissionData'));
console.log('第一个,存储的数据:', localStorage.getItem('submissionData'));
const submission = {
jwcode: savedData.jwcode,
answers: formattedAnswers
};
console.log(submission);
//
const response = await axios.post('http://192.168.40.41:8000/api/knowledge/submit', submission);
console.log(submission);
//
this.$router.push({
name: 'ResultView',
query: {
@ -420,7 +373,6 @@ export default {
}
},
//
getTimeUsed() {
const now = new Date();
const elapsedMinutes = (now - this.startTime) / (1000 * 60);
@ -428,10 +380,7 @@ export default {
}
},
async mounted() {
//
await this.fetchQuestions();
//
this.timer = setInterval(() => {
this.updateCountdown();
}, 1000);
@ -445,109 +394,122 @@ export default {
</script>
<style scoped>
.questions-container {
display: flex;
flex-direction: column;
gap: 30px;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.home {
min-height: 100vh;
width: 100%;
background-color: #24293c;
overflow: auto;
padding: 10px;
}
.top {
background: #0c4a6e;
color: white;
padding: 30px;
margin-bottom: 10px;
position: relative;
}
.ret{
.img-top {
float: left;
cursor: pointer;
}
.img-top:hover {
transform: scale(1.1);
}
.img1 {
width: 30px;
height: 50px;
float: left;
}
.page-info {
color: #e5e7eb;
font-weight: bold;
padding: 0 20px;
h1 {
margin-bottom: 10px;
background: none;
font-size: 2.2em;
}
.question-grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 10px;
margin: auto 30px;
p {
font-size: 1.2em;
margin-bottom: 10px;
background: none;
}
.question-number {
width: 60px;
height: 50px;
border-radius: 8px;
.popup-all {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
cursor: pointer;
position: relative;
align-items: center;
z-index: 1000;
}
.question-number.normal {
background-color: #374151;
border: 1px solid #4b5563;
color: #e5e7eb;
.popup-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 125%;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(5px);
}
.question-number.answered {
background-color: #10b981;
border: 1px solid #059669;
color: white;
.popup-content {
background-color: #f1f5f9;
padding: 30px;
border-radius: 15px;
box-shadow: 0 20px 40px rgba(0,0,0,0.3);
width: 90%;
text-align: center;
}
.question-number.current {
background-color: #3b82f6;
border: 2px solid #2563eb;
color: white;
transform: scale(1.1);
.popup-buttons {
margin-top: 20px;
justify-content: center;
}
.question-number:hover {
transform: scale(1.05);
.cancel-btn, .confirm-btn {
border-radius: 10px;
border: transparent 0px ;
margin: 5px;
padding: 12px 30px;
font-size: 1em;
font-weight: bold;
}
.question-text {
z-index: 1;
.cancel-btn {
background: #f1f1f1;
color: #666;
}
.pagination-btn.active {
background-color: #2563eb;
transform: scale(1.05);
.confirm-btn {
background: #ff4757;
color: white;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f5f7fa;
}
.home {
min-height: 100vh;
width: 100%;
background-color: #24293c;
overflow: auto;
padding: 20px;
}
.top {
background: linear-gradient(135deg, #0c4a6e 100%);
color: white;
padding: 30px;
margin-bottom: 30px;
.content {
float: left;
width: calc(65% - 20px);
min-height: 920px;
border: #274779 solid 2px;
border-radius: 10px;
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
position: relative;
overflow: hidden;
}
.top h1 {
font-size: 2.2em;
margin-bottom: 10px;
background: none;
}
.top p {
font-size: 1.1em;
opacity: 0.9;
background: none;
color: #f1f5f9;
padding: 20px 40px 50px;
margin-right: 20px;
background-color: #2a3147;
}
.block {
background: rgba(139, 141, 145, 0.7);
width: 90%;
@ -558,6 +520,7 @@ body {
position: relative;
box-shadow: inset 0 0 10px rgba(0,0,0,0.3);
}
.schedule {
background: linear-gradient(90deg, #0ea5e9 0%, #38bdf8 100%);
height: 100%;
@ -565,26 +528,20 @@ body {
transition: width 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
position: relative;
}
.content {
float: left;
width: calc(65% - 20px);
min-height: 920px;
border: #274779 solid 2px;
border-radius: 10px;
color: #f1f5f9;
padding: 20px 40px 50px;
margin-right: 20px;
background-color: #2a3147;
.question-all {
display: flex;
flex-direction: column;
gap: 30px;
}
.question-card {
.left-question-card {
border: #274779 solid 2px;
border-radius: 10px;
padding: 20px 40px;
background-color: #2f374d;
}
.question-header {
margin-bottom: 20px;
}
.question {
font-size: 1.3em;
line-height: 1.8;
@ -592,11 +549,13 @@ body {
color: #f1f5f9;
font-weight: 500;
}
.options {
display: flex;
flex-direction: column;
gap: 15px;
}
.option {
border: #183954 solid 2px;
border-radius: 10px;
@ -607,116 +566,157 @@ body {
transition: all 0.3s ease;
background-color: #374151;
}
.option:hover {
border-color: #3b82f6;
background-color: #4b5563;
}
.option input {
margin-right: 15px;
width: 18px;
height: 18px;
}
.option .label {
font-size: 1.1em;
color: #e5e7eb;
}
.option.selected {
border-color: #3b82f6;
background-color: rgba(59, 130, 246, 0.2);
}
.buttons-left {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 30px;
}
.before-btn, .next-btn {
padding: 10px 20px;
border-radius: 8px;
border: none;
background-color: #3b82f6;
color: white;
font-weight: bold;
display: flex;
align-items: center;
gap: 5px;
}
.before-btn:hover, .next-btn:hover {
background-color: #2563eb;
}
.before-btn:disabled, .next-btn:disabled {
background-color: #4b5563;
cursor: not-allowed;
}
.right {
float: right;
width: calc(35% - 20px);
color: #f1f5f9;
padding: 20px;
}
.time-module {
border: #274779 solid 2px;
border-radius: 30px;
padding: 15px;
margin-bottom: 20px;
background-color: #2f374d;
}
.question-nav {
border: #274779 solid 2px;
border-radius: 30px;
padding: 15px 0 15px 19px ;
margin-bottom: 20px;
background-color: #2f374d;
color: white;
}
.statistics {
height: 150px;
border: #274779 solid 2px;
border-radius: 30px;
padding: 15px;
margin-bottom: 20px;
background-color: #2f374d;
}
.time-module h3, .question-nav h3, .statistics h3 {
margin-bottom: 15px;
color: #f1f5f9;
.right h3 {
font-size: 1.2em;
padding-bottom: 15px;
margin-bottom: 15px;
border-bottom: 2px solid #274779;
padding-bottom: 10px;
}
.time-module {
margin-bottom: 20px;
}
.countdown {
font-size: 1.5em;
color: #f59e0b;
text-align: center;
margin-bottom: 20px;
}
.pagination {
display: flex;
/* justify-content: center; */
margin: 30px 148px 5px;
gap: 20px;
.right-question-card {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 10px;
margin: auto 30px;
}
.pagination-btn {
padding: 8px 15px;
.question-number {
width: 60px;
height: 50px;
border-radius: 8px;
border: none;
background-color: #3b82f6;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
cursor: pointer;
transition: all 0.3s ease;
margin: auto 20px;
position: relative;
}
.pagination-btn:hover {
background-color: #2563eb;
.question-number.normal {
background-color: #374151;
border: 1px solid #4b5563;
color: #e5e7eb;
}
.pagination-btn:disabled {
background-color: #4b5563;
.question-number.answered {
background-color: #10b981;
border: 1px solid #059669;
color: white;
}
.question-number.current {
background-color: #3b82f6;
border: 2px solid #2563eb;
color: white;
transform: scale(1.1);
}
.nav-buttons {
.question-number:hover {
transform: scale(1.05);
}
.button-right {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 30px;
margin: 30px 180px 5px;
gap: 20px;
}
.nav-btn {
padding: 10px 20px;
.right-before-btn, .right-next-btn {
padding: 8px 15px;
border-radius: 8px;
border: none;
background-color: #3b82f6;
color: white;
font-weight: bold;
display: flex;
align-items: center;
gap: 5px;
cursor: pointer;
margin: auto 20px;
}
.nav-btn:hover {
.right-before-btn:hover, .right-next-btn:hover {
background-color: #2563eb;
}
.nav-btn.prev {
background-color: #3b82f6;;
}
.nav-btn.prev:hover {
.right-before-btn.active, .right-next-btn.active {
background-color: #2563eb;
transform: scale(1.05);
}
.nav-btn:disabled {
background-color: #4b5563;
cursor: not-allowed;
.statistics {
margin-bottom: 20px;
}
.statistics-item {
display: flex;
font-size: larger;
@ -726,126 +726,36 @@ body {
padding-bottom: 2px;
border-bottom: 2px solid #274779;
}
.statistics-label {
color: #e5e7eb;
}
.statistics-value {
font-weight: bold;
color: #3b82f6;
}
.submit-btn {
width: 100%;
padding: 15px;
border-radius: 10px;
border: none;
background-color: #10b981;
color: white;
font-size: 1.2em;
font-weight: bold;
cursor: pointer;
transition: all 0.3s ease;
margin-top: 20px;
display: block;
text-align: center;
text-decoration: none;
}
.submit-btn:hover {
background-color: #059669;
}
.clearfix::after {
content: "";
clear: both;
display: table;
}
.ret-container {
float: left;
cursor: pointer;
transition: transform 0.3s ease;
.button-right-bottom {
margin-top: 20px;
}
.ret-container:hover {
transform: scale(1.1);
}
.confirm-dialog {
position: fixed;
top: 0;
left: 0;
.right-bottom-btn {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.dialog-content {
position: relative;
background: white;
padding: 30px;
border-radius: 15px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
max-width: 400px;
width: 90%;
height: 40px;
border-radius: 8px;
background-color: #10b981;
color: white;
text-align: center;
z-index: 1001;
}
.dialog-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(5px);
}
.dialog-content h3 {
color: #333;
margin-bottom: 15px;
font-size: 1.4em;
}
.dialog-content p {
color: #666;
margin-bottom: 25px;
font-size: 1.1em;
line-height: 1.5;
}
.dialog-buttons {
display: flex;
gap: 15px;
justify-content: center;
}
.cancel-btn, .confirm-btn {
padding: 12px 30px;
line-height: 40px;
border: none;
border-radius: 8px;
font-size: 1em;
font-size: 1.2em;
font-weight: bold;
cursor: pointer;
transition: all 0.3s ease;
min-width: 100px;
}
.cancel-btn {
background: #f1f1f1;
color: #666;
}
.cancel-btn:hover {
background: #e0e0e0;
}
.confirm-btn {
background: #ff4757;
color: white;
}
.confirm-btn:hover {
background: #ff3742;
transform: translateY(-2px);
.right-bottom-btn:hover {
background-color: #059669;
}
</style>

2
vue.config.js

@ -9,7 +9,7 @@ module.exports = defineConfig({
proxy: {
// 代理所有以 /api 开头的请求
'/api': {
target: 'http://192.168.40.41:8000', // 你的后端地址
target: 'http://192.168.40.48:8081', // 你的后端地址
changeOrigin: true, // 允许跨域
pathRewrite: {
'^/api': '' // 重写路径,去掉 /api 前缀

Loading…
Cancel
Save