Compare commits
No commits in common. 'master' and 'chenzhen/feature-20251107115823-股票知识测评' have entirely different histories.
master
...
chenzhen/f
-
28.gitignore
-
24README.md
-
5babel.config.js
-
19jsconfig.json
-
19674package-lock.json
-
45package.json
-
BINpublic/favicon.ico
-
17public/index.html
-
66src/App.vue
-
BINsrc/assets/buy.jpg
-
BINsrc/assets/enter.jpg
-
BINsrc/assets/false.jpg
-
BINsrc/assets/home.jpg
-
BINsrc/assets/huiche.png
-
BINsrc/assets/logo.png
-
BINsrc/assets/result.jpg
-
BINsrc/assets/return.jpg
-
BINsrc/assets/square.jpg
-
BINsrc/assets/true.jpg
-
58src/components/HelloWorld.vue
-
18src/main.js
-
58src/router/index.js
-
42src/views/BuyView.vue
-
87src/views/HomeView.vue
-
0src/views/OneView.vue
-
435src/views/ProblemView.vue
-
350src/views/ReportView.vue
-
274src/views/ResultView.vue
-
275src/views/TestView.vue
-
1942src/views/TextHtml.html
-
761src/views/TextView.vue
-
32vue.config.js
@ -1,11 +1,23 @@ |
|||
# ---> Vue |
|||
# gitignore template for Vue.js projects |
|||
# |
|||
# Recommended template: Node.gitignore |
|||
.DS_Store |
|||
node_modules |
|||
/dist |
|||
|
|||
# TODO: where does this rule come from? |
|||
docs/_book |
|||
|
|||
# TODO: where does this rule come from? |
|||
test/ |
|||
# local env files |
|||
.env.local |
|||
.env.*.local |
|||
|
|||
# Log files |
|||
npm-debug.log* |
|||
yarn-debug.log* |
|||
yarn-error.log* |
|||
pnpm-debug.log* |
|||
|
|||
# Editor directories and files |
|||
.idea |
|||
.vscode |
|||
*.suo |
|||
*.ntvs* |
|||
*.njsproj |
|||
*.sln |
|||
*.sw? |
|||
@ -1,2 +1,24 @@ |
|||
# Knowledge_Test_Vue |
|||
# evaluation-system |
|||
|
|||
## Project setup |
|||
``` |
|||
npm install |
|||
``` |
|||
|
|||
### Compiles and hot-reloads for development |
|||
``` |
|||
npm run serve |
|||
``` |
|||
|
|||
### Compiles and minifies for production |
|||
``` |
|||
npm run build |
|||
``` |
|||
|
|||
### Lints and fixes files |
|||
``` |
|||
npm run lint |
|||
``` |
|||
|
|||
### Customize configuration |
|||
See [Configuration Reference](https://cli.vuejs.org/config/). |
|||
@ -0,0 +1,5 @@ |
|||
module.exports = { |
|||
presets: [ |
|||
'@vue/cli-plugin-babel/preset' |
|||
] |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
{ |
|||
"compilerOptions": { |
|||
"target": "es5", |
|||
"module": "esnext", |
|||
"baseUrl": "./", |
|||
"moduleResolution": "node", |
|||
"paths": { |
|||
"@/*": [ |
|||
"src/*" |
|||
] |
|||
}, |
|||
"lib": [ |
|||
"esnext", |
|||
"dom", |
|||
"dom.iterable", |
|||
"scripthost" |
|||
] |
|||
} |
|||
} |
|||
19674
package-lock.json
File diff suppressed because it is too large
View File
@ -0,0 +1,45 @@ |
|||
{ |
|||
"name": "evaluation-system", |
|||
"version": "0.1.0", |
|||
"private": true, |
|||
"scripts": { |
|||
"serve": "vue-cli-service serve", |
|||
"build": "vue-cli-service build", |
|||
"lint": "vue-cli-service lint" |
|||
}, |
|||
"dependencies": { |
|||
"axios": "^1.13.2", |
|||
"core-js": "^3.8.3", |
|||
"vue": "^2.6.14", |
|||
"vue-router": "^3.6.5" |
|||
}, |
|||
"devDependencies": { |
|||
"@babel/core": "^7.12.16", |
|||
"@babel/eslint-parser": "^7.12.16", |
|||
"@vue/cli-plugin-babel": "~5.0.0", |
|||
"@vue/cli-plugin-eslint": "~5.0.0", |
|||
"@vue/cli-service": "~5.0.0", |
|||
"eslint": "^7.32.0", |
|||
"eslint-plugin-vue": "^8.0.3", |
|||
"vue-template-compiler": "^2.6.14" |
|||
}, |
|||
"eslintConfig": { |
|||
"root": true, |
|||
"env": { |
|||
"node": true |
|||
}, |
|||
"extends": [ |
|||
"plugin:vue/essential", |
|||
"eslint:recommended" |
|||
], |
|||
"parserOptions": { |
|||
"parser": "@babel/eslint-parser" |
|||
}, |
|||
"rules": {} |
|||
}, |
|||
"browserslist": [ |
|||
"> 1%", |
|||
"last 2 versions", |
|||
"not dead" |
|||
] |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
<!DOCTYPE html> |
|||
<html lang=""> |
|||
<head> |
|||
<meta charset="utf-8"> |
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
|||
<meta name="viewport" content="width=device-width,initial-scale=1.0"> |
|||
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> |
|||
<title><%= htmlWebpackPlugin.options.title %></title> |
|||
</head> |
|||
<body> |
|||
<noscript> |
|||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> |
|||
</noscript> |
|||
<div id="app"></div> |
|||
<!-- built files will be auto injected --> |
|||
</body> |
|||
</html> |
|||
@ -0,0 +1,66 @@ |
|||
<template> |
|||
<div> |
|||
<!-- <router-link to="/test" class="center"> |
|||
<span class="text">进入测试系统</span> |
|||
</router-link> --> |
|||
<router-view></router-view> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'App', |
|||
data() { |
|||
return { |
|||
activeTab: 'question' |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
/* * { |
|||
margin: 0; |
|||
padding: 0; |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
div{ |
|||
min-height: 100vh; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
background: #f5f5f5; |
|||
} |
|||
|
|||
.center{ |
|||
width: 300px; |
|||
height: 120px; |
|||
background: linear-gradient(135deg, #667eea 0%, #000000 100%); |
|||
border-radius: 15px; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
cursor: pointer; |
|||
transition: all 0.3s ease; |
|||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); |
|||
border: 2px solid #2c3e50; |
|||
text-decoration: none; |
|||
} |
|||
|
|||
.center:hover { |
|||
transform: translateY(-5px); |
|||
box-shadow: 0 12px 35px rgba(0, 0, 0, 0.2); |
|||
background: linear-gradient(135deg, #764ba2 0%, #000000 100%); |
|||
text-decoration: none; |
|||
} |
|||
|
|||
.text { |
|||
color: white; |
|||
font-size: 20px; |
|||
font-weight: bold; |
|||
text-align: center; |
|||
text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5); |
|||
user-select: none; |
|||
} */ |
|||
</style> |
|||
|
After Width: 1920 | Height: 970 | Size: 593 KiB |
|
After Width: 792 | Height: 159 | Size: 54 KiB |
|
After Width: 518 | Height: 349 | Size: 33 KiB |
|
After Width: 1920 | Height: 1040 | Size: 713 KiB |
|
After Width: 45 | Height: 45 | Size: 3.2 KiB |
|
After Width: 200 | Height: 200 | Size: 6.7 KiB |
|
After Width: 485 | Height: 397 | Size: 34 KiB |
|
After Width: 102 | Height: 129 | Size: 5.2 KiB |
|
After Width: 452 | Height: 273 | Size: 34 KiB |
|
After Width: 490 | Height: 341 | Size: 31 KiB |
@ -0,0 +1,58 @@ |
|||
<template> |
|||
<div class="hello"> |
|||
<h1>{{ msg }}</h1> |
|||
<p> |
|||
For a guide and recipes on how to configure / customize this project,<br> |
|||
check out the |
|||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>. |
|||
</p> |
|||
<h3>Installed CLI Plugins</h3> |
|||
<ul> |
|||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li> |
|||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li> |
|||
</ul> |
|||
<h3>Essential Links</h3> |
|||
<ul> |
|||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li> |
|||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li> |
|||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li> |
|||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li> |
|||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li> |
|||
</ul> |
|||
<h3>Ecosystem</h3> |
|||
<ul> |
|||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li> |
|||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li> |
|||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li> |
|||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li> |
|||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li> |
|||
</ul> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'HelloWorld', |
|||
props: { |
|||
msg: String |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<!-- Add "scoped" attribute to limit CSS to this component only --> |
|||
<style scoped> |
|||
h3 { |
|||
margin: 40px 0 0; |
|||
} |
|||
ul { |
|||
list-style-type: none; |
|||
padding: 0; |
|||
} |
|||
li { |
|||
display: inline-block; |
|||
margin: 0 10px; |
|||
} |
|||
a { |
|||
color: #42b983; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,18 @@ |
|||
import Vue from 'vue' |
|||
import App from './App.vue' |
|||
// import router from '../src/router/index'
|
|||
import router from './router/index' |
|||
import axios from 'axios' |
|||
|
|||
// 配置 axios
|
|||
Vue.prototype.$axios = axios |
|||
|
|||
// 可选:配置默认 baseURL
|
|||
axios.defaults.baseURL = 'http://192.168.40.41:8000' |
|||
|
|||
Vue.config.productionTip = false |
|||
|
|||
new Vue({ |
|||
router, |
|||
render: h => h(App), |
|||
}).$mount('#app') |
|||
@ -0,0 +1,58 @@ |
|||
import Vue from 'vue' |
|||
import VueRouter from 'vue-router' |
|||
import TestView from '@/views/TestView.vue' |
|||
import TextView from '@/views/TextView.vue' |
|||
import ReportView from '@/views/ReportView.vue' |
|||
import ProblemView from '@/views/ProblemView.vue' |
|||
import ResultView from '@/views/ResultView.vue' |
|||
// import { component } from 'vue/types/umd'
|
|||
import HomeView from '@/views/HomeView.vue' |
|||
import BuyView from '@/views/BuyView.vue' |
|||
|
|||
Vue.use(VueRouter) |
|||
|
|||
const routes = [ |
|||
{ |
|||
path: '/', |
|||
name: 'HomeView', |
|||
component: HomeView |
|||
}, |
|||
{ |
|||
path: '/test', |
|||
name: 'TestView', |
|||
component: TestView |
|||
}, |
|||
{ |
|||
path: '/text', |
|||
name: 'TextView', |
|||
component: TextView |
|||
}, |
|||
{ |
|||
path: '/result', |
|||
name: 'ResultView', |
|||
component: ResultView |
|||
}, |
|||
{ |
|||
path: '/report', |
|||
name: 'ReportView', |
|||
component: ReportView |
|||
}, |
|||
{ |
|||
path: '/buy', |
|||
name: 'BuyView', |
|||
component: BuyView |
|||
}, |
|||
{ |
|||
path: '/problem', |
|||
name: 'ProblemView', |
|||
component: ProblemView |
|||
} |
|||
] |
|||
|
|||
const router = new VueRouter({ |
|||
mode: 'history', |
|||
base: process.env.BASE_URL, |
|||
routes |
|||
}) |
|||
|
|||
export default router |
|||
@ -0,0 +1,42 @@ |
|||
<template> |
|||
<div class="home"> |
|||
<div class="enter" @click="enter"> |
|||
<img src="../assets/huiche.png" alt="返回上一页" class="img1"> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script> |
|||
export default{ |
|||
name:'BuyView', |
|||
data(){ |
|||
return{ |
|||
|
|||
}; |
|||
}, |
|||
methods:{ |
|||
enter(){ |
|||
this.$router.push({ |
|||
name:'ReportView' |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
<style scoped> |
|||
.home{ |
|||
position: relative; |
|||
width: 100%; |
|||
height: 100%; |
|||
background-image: url('@/assets/buy.jpg'); |
|||
color: white; |
|||
padding: 20px; |
|||
background-size: cover; |
|||
} |
|||
.img1{ |
|||
position: absolute; |
|||
top: 6.5vh; |
|||
left: 39vh; |
|||
width: 8vh; |
|||
height: 7vh; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,87 @@ |
|||
<template> |
|||
<div class="home"> |
|||
<img src="../assets/enter.jpg" alt="进入测试" class="image" @click="jumpPage"> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import axios from 'axios'; |
|||
export default { |
|||
name: 'App', |
|||
data() { |
|||
return { |
|||
activeTab: 'question' |
|||
} |
|||
}, |
|||
methods:{ |
|||
async jumpPage(){ |
|||
const submissionData={ |
|||
// jwcode:91000001,//有成绩的 |
|||
// jwcode:90098888,//有成绩的 |
|||
// jwcode:90098889,//有成绩的 |
|||
// jwcode:90098890,//有成绩的 |
|||
// jwcode:90098891,//有成绩的 |
|||
// jwcode:90098892,//有成绩的 |
|||
// jwcode:90098893,//有成绩的 |
|||
// jwcode:90098894,//有成绩的 |
|||
// jwcode:90098898,//有成绩的 |
|||
jwcode:90098899,//有成绩的 |
|||
// jwcode:90098900,//没有成绩的 |
|||
// jwcode:90098901,//没有成绩的 |
|||
// jwcode:90098902,//没有成绩的 |
|||
// jwcode:90098903,//没有成绩的 |
|||
}; |
|||
localStorage.setItem('submissionData', JSON.stringify(submissionData)); |
|||
console.log('存储的数据:', localStorage.getItem('submissionData')); |
|||
try{ |
|||
const res = await axios.post('http://192.168.40.41:8000/api/knowledge/scores',submissionData); |
|||
this.score = res.data.data[0].score; |
|||
console.log(this.score); |
|||
if(this.score==null){ |
|||
this.$router.push('/text'); |
|||
} |
|||
else{ |
|||
this.$router.push('/report'); |
|||
} |
|||
}catch(err){ |
|||
this.$router.push('/text'); |
|||
} |
|||
} |
|||
}, |
|||
async mounted(){ |
|||
localStorage.removeItem('submissionData'); |
|||
}, |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
* { |
|||
margin: 0; |
|||
padding: 0; |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
.home { |
|||
position: relative; |
|||
min-height: 100vh; |
|||
display: flex; |
|||
background-image: url('@/assets/home.jpg'); |
|||
background-size: cover; |
|||
background-position: center; |
|||
} |
|||
|
|||
.image { |
|||
position: fixed; |
|||
width: 21vh; |
|||
height: 18vh; |
|||
object-fit: contain; |
|||
top: 76%; |
|||
left: 35.57%; |
|||
/* left: 35.5%; */ |
|||
} |
|||
|
|||
.image:hover { |
|||
transform: scale(1.2); |
|||
filter: brightness(1.1); |
|||
} |
|||
</style> |
|||
@ -0,0 +1,435 @@ |
|||
<script> |
|||
import axios from 'axios'; |
|||
export default { |
|||
data() { |
|||
return { |
|||
problems: [], |
|||
showDialog: false, |
|||
currentPage: 1, |
|||
answers:{}, |
|||
page:1, |
|||
} |
|||
}, |
|||
computed:{ |
|||
currentProblem() { |
|||
if (!this.problems || !this.problems.slice) { |
|||
return null; |
|||
} |
|||
const startIndex = (this.currentPage - 1) * 2; |
|||
return this.problems.slice(startIndex, startIndex + 2); |
|||
}, |
|||
}, |
|||
methods: { |
|||
jump() { |
|||
this.showDialog = true; |
|||
}, |
|||
closeDialog() { |
|||
this.showDialog = false; |
|||
}, |
|||
confirmExit() { |
|||
this.showDialog = false; |
|||
this.$router.push({ name: 'ReportView' }); |
|||
}, |
|||
async problemAnswers() { |
|||
const savedData = JSON.parse(localStorage.getItem('submissionData')); |
|||
console.log('第一个,存储的数据:', savedData.jwcode); |
|||
const submission = { |
|||
jwcode: savedData.jwcode |
|||
}; |
|||
try{ |
|||
const response = await axios.post('http://192.168.40.41:8000/api/knowledge/wrong-questions',submission); |
|||
this.problems = response.data.data.list; |
|||
console.log("完整响应:", response); |
|||
}catch(error){ |
|||
console.error('获取错误问题失败:', error); |
|||
} |
|||
}, |
|||
before(){ |
|||
if(this.currentPage > 1){ |
|||
this.currentPage--; |
|||
} |
|||
if(this.currentPage < 13){ |
|||
this.page=1; |
|||
} |
|||
}, |
|||
next(){ |
|||
if(this.currentPage < 25){ |
|||
this.currentPage++; |
|||
} |
|||
if(this.currentPage > 13){ |
|||
this.page=2; |
|||
} |
|||
}, |
|||
setAnswer(id, val) { |
|||
this.answers[id] = val; |
|||
}, |
|||
getAnswer(id) { |
|||
return this.answers[id]; |
|||
}, |
|||
rightBefore(){ |
|||
this.page=1; |
|||
}, |
|||
rightNext(){ |
|||
this.page=2; |
|||
}, |
|||
toQuestion(index){ |
|||
this.currentPage = Math.ceil(index/2); |
|||
}, |
|||
getOption(problem,option) { |
|||
const userAnswer = problem.userAnswer; |
|||
const correctAnswer = problem.correctAnswer; |
|||
if(userAnswer === option){ |
|||
if(correctAnswer !== option){ |
|||
return 'red'; |
|||
} |
|||
} |
|||
if (correctAnswer === option) { |
|||
return 'green'; |
|||
} |
|||
}, |
|||
getNumber(problem) { |
|||
if (!problem) return; |
|||
const userAnswer = problem.userAnswer; |
|||
const correctAnswer = problem.correctAnswer; |
|||
|
|||
if (correctAnswer !== userAnswer) { |
|||
return 'red'; |
|||
} |
|||
if (correctAnswer === userAnswer) { |
|||
return 'answered'; |
|||
} |
|||
} |
|||
}, |
|||
async mounted(){ |
|||
await this.problemAnswers(); |
|||
} |
|||
} |
|||
</script> |
|||
<template> |
|||
<div class="home"> |
|||
<div class="top"> |
|||
<div class="img-top" @click="jump"> |
|||
<img src="../assets/return.jpg" alt="返回" class="img1"> |
|||
</div> |
|||
<span> |
|||
<h1>📈股票知识评测系统</h1> |
|||
</span> |
|||
<p>全方面评估您的股票投资知识水平,获取个性化学习建议</p> |
|||
</div> |
|||
<div class="popup-all popup-background" v-if="showDialog"> |
|||
<div class="popup-content"> |
|||
<h3>确认提示</h3> |
|||
<p>确定返回报告吗?</p> |
|||
<div class="popup-buttons"> |
|||
<button class="cancel-btn" @click="closeDialog">取消</button> |
|||
<button class="confirm-btn" @click="confirmExit">确定</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="content"> |
|||
<div class="block"></div> |
|||
<div class="question-all"> |
|||
<div v-for="problem in currentProblem" :key="problem.id" class="left-question-card" > |
|||
<div class="question"> |
|||
<span class="text">{{problem.question.id}}、</span>{{ problem.question.stem }} |
|||
</div> |
|||
<div class="options"> |
|||
<label class="option" :class="[{ 'selected': getAnswer(problem.question.id) === 'A' }, getOption(problem, 'A')]"> |
|||
<input type="radio" :name="'answer' + problem.question.id" value="A"><span class="label">A. {{ problem.question.A }}</span> |
|||
</label> |
|||
<label class="option" :class="[{ 'selected': getAnswer(problem.question.id) === 'B' }, getOption(problem, 'B')]"> |
|||
<input type="radio" :name="'answer' + problem.question.id" value="B"><span class="label">B. {{ problem.question.B }}</span> |
|||
</label> |
|||
<label class="option" :class="[{ 'selected': getAnswer(problem.question.id) === 'C' }, getOption(problem, 'C')]"> |
|||
<input type="radio" :name="'answer' + problem.question.id" value="C"><span class="label">C. {{ problem.question.C }}</span> |
|||
</label> |
|||
<label class="option" :class="[{ 'selected': getAnswer(problem.question.id) === 'D' }, getOption(problem, 'D')]"> |
|||
<input type="radio" :name="'answer' + problem.question.id" value="D"><span class="label">D. {{ problem.question.D }}</span> |
|||
</label> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="buttons-left"> |
|||
<button class="before-btn" @click="before" :disabled="currentPage === 1"> |
|||
← 上一页 |
|||
</button> |
|||
<span class="page">第 {{ currentPage }} 页 / 共 25 页</span> |
|||
<button class="next-btn" @click="next" :disabled="currentPage === 25"> |
|||
下一页 → |
|||
</button> |
|||
</div> |
|||
</div> |
|||
<div class="right"> |
|||
<h3>📝 题目导航</h3> |
|||
<div class="right-question-card" v-show="page===1"> |
|||
<div class="question-number normal" v-for="i in 25" :key="i" @click="toQuestion(i)" :class="getNumber(problems[i - 1])"> |
|||
<span class="question-text">{{ i }}</span> |
|||
</div> |
|||
</div> |
|||
<div class="right-question-card" v-show="page===2"> |
|||
<div class="question-number normal" v-for="i in 25" :key="i+25" @click="toQuestion(i+25)" :class="getNumber(problems[i + 24])"> |
|||
<span class="question-text">{{ i+25 }}</span> |
|||
</div> |
|||
</div> |
|||
<div class="button-right"> |
|||
<button class="right-before-btn" @click="rightBefore">上一页</button> |
|||
<button class="right-next-btn" @click="rightNext">下一页</button> |
|||
</div> |
|||
</div> |
|||
<div class="button-right-bottom"> |
|||
<button class="right-bottom-btn" @click="jump">退出</button> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<style scoped> |
|||
* { |
|||
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; |
|||
} |
|||
.img-top{ |
|||
float: left; |
|||
} |
|||
.img-top:hover{ |
|||
transform: scale(1.1); |
|||
} |
|||
.img1{ |
|||
width: 30px; |
|||
height: 50px; |
|||
float: left; |
|||
} |
|||
h1{ |
|||
margin-bottom: 10px; |
|||
background: none; |
|||
font-size: 2.2em; |
|||
} |
|||
p{ |
|||
font-size: 1.2em; |
|||
margin-bottom: 10px; |
|||
background: none; |
|||
} |
|||
.popup-all{ |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
z-index: 1000; |
|||
} |
|||
.popup-background{ |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 125%; |
|||
background: rgba(0, 0, 0, 0.5); |
|||
backdrop-filter: blur(5px); |
|||
} |
|||
.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; |
|||
} |
|||
.popup-buttons{ |
|||
margin-top: 20px; |
|||
justify-content: center; |
|||
} |
|||
.cancel-btn,.confirm-btn{ |
|||
border-radius: 10px; |
|||
border: transparent 0px ; |
|||
margin: 5px; |
|||
padding: 12px 30px; |
|||
font-size: 1em; |
|||
font-weight: bold; |
|||
} |
|||
.cancel-btn{ |
|||
background: #f1f1f1; |
|||
color: #666; |
|||
} |
|||
.confirm-btn{ |
|||
background: #ff4757; |
|||
color: white; |
|||
} |
|||
.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; |
|||
} |
|||
.block { |
|||
background: #38bdf8; |
|||
width: 90%; |
|||
height: 10px; |
|||
border-radius: 5px; |
|||
margin: 0 auto 30px; |
|||
overflow: hidden; |
|||
position: relative; |
|||
box-shadow: inset 0 0 10px rgba(0,0,0,0.3); |
|||
} |
|||
.question-all{ |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 30px; |
|||
} |
|||
.left-question-card{ |
|||
border: #274779 solid 2px; |
|||
border-radius: 10px; |
|||
padding: 20px 40px; |
|||
background-color: #2f374d; |
|||
} |
|||
.question { |
|||
font-size: 1.3em; |
|||
line-height: 1.8; |
|||
margin-bottom: 25px; |
|||
color: #f1f5f9; |
|||
font-weight: 500; |
|||
} |
|||
.options { |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 15px; |
|||
} |
|||
.option { |
|||
border: #183954 solid 2px; |
|||
border-radius: 10px; |
|||
padding: 12px 15px; |
|||
display: flex; |
|||
align-items: center; |
|||
cursor: pointer; |
|||
transition: all 0.3s ease; |
|||
background-color: #374151; |
|||
} |
|||
.option.red{ |
|||
background-color: #ff4757; |
|||
} |
|||
.option.green{ |
|||
background-color: #10b981; |
|||
} |
|||
.option input { |
|||
margin-right: 15px; |
|||
width: 18px; |
|||
height: 18px; |
|||
} |
|||
.option .label { |
|||
font-size: 1.1em; |
|||
color: #e5e7eb; |
|||
} |
|||
.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:disabled,.next-btn:disabled { |
|||
background-color: #4b5563; |
|||
cursor: not-allowed; |
|||
} |
|||
.right { |
|||
float: right; |
|||
width: calc(35% - 20px); |
|||
border: #274779 solid 2px; |
|||
border-radius: 30px; |
|||
padding: 15px 0 15px 19px ; |
|||
margin-bottom: 20px; |
|||
background-color: #2f374d; |
|||
color: white; |
|||
} |
|||
.right h3{ |
|||
font-size: xx-large; |
|||
padding-bottom: 15px; |
|||
margin-bottom: 15px; |
|||
border-bottom: 2px solid #274779; |
|||
} |
|||
.right-question-card { |
|||
display: grid; |
|||
grid-template-columns: repeat(5, 1fr); |
|||
gap: 10px; |
|||
margin: auto 30px; |
|||
} |
|||
.question-number { |
|||
width: 60px; |
|||
height: 50px; |
|||
border-radius: 8px; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
font-weight: bold; |
|||
cursor: pointer; |
|||
position: relative; |
|||
} |
|||
.right-question-card .question-number.red { |
|||
background-color: #ff4757; |
|||
border: 1px solid #991b1b; |
|||
color: white; |
|||
} |
|||
.question-number.normal { |
|||
background-color: #374151; |
|||
border: 1px solid #4b5563; |
|||
color: #e5e7eb; |
|||
} |
|||
.button-right{ |
|||
display: flex; |
|||
margin: 30px 180px 5px; |
|||
gap: 20px; |
|||
} |
|||
.right-before-btn,.right-next-btn{ |
|||
padding: 8px 15px; |
|||
border-radius: 8px; |
|||
border: none; |
|||
background-color: #3b82f6; |
|||
color: white; |
|||
font-weight: bold; |
|||
cursor: pointer; |
|||
margin: auto 20px; |
|||
} |
|||
.right-bottom-btn{ |
|||
float: right; |
|||
height: 40px; |
|||
width: 100px; |
|||
border-radius: 8px; |
|||
background-color: #3b82f6; |
|||
color: white; |
|||
text-align: center; |
|||
line-height: 40px; |
|||
position:relative; |
|||
top: 350px; |
|||
} |
|||
|
|||
</style> |
|||
@ -0,0 +1,350 @@ |
|||
<template> |
|||
<div class="home"> |
|||
<div class="top"> |
|||
<div @click="showConfirmDialog" class="ret-top"> |
|||
<img src="../assets/return.jpg" alt="返回" class="ret"> |
|||
</div> |
|||
<h1>📈股票知识评测系统</h1> |
|||
<p>全方面评估您的股票投资知识水平,获取个性化学习建议</p> |
|||
</div> |
|||
<div class="popup-block" v-if="showDialog"> |
|||
<div class="popup-top" @click="closeDialog"></div> |
|||
<div class="popup-content"> |
|||
<h3>确认提示</h3> |
|||
<p>确定要退出吗?</p> |
|||
<div class="popup-buttons"> |
|||
<button class="cancel-btn" @click="closeDialog">取消</button> |
|||
<button class="confirm-btn" @click="confirmExit">确定</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="content"> |
|||
<h1>系统分析报告</h1> |
|||
|
|||
<div class="right"> |
|||
<div class="right-top"> |
|||
<img src="../assets/square.jpg" alt="柱状图展示....." class="img3"> |
|||
<div class="right-top-left"> |
|||
<div v-show="score!=100" > |
|||
<img src="../assets/false.jpg" alt="继续努力....." class="img1"> |
|||
</div> |
|||
<div v-show="score==100" > |
|||
<img src="../assets/true.jpg" alt="你真棒....." class="img2"> |
|||
</div> |
|||
<div> |
|||
<p style="font-size: 2.2em;text-align: center;">您的分数是:{{this.score}}分</p> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="left"> |
|||
<p>最好的投资是投资自己,而最好的课程是,是适合你的课程</p><br> |
|||
<p>人无法赚到认知以外的钱,请根据测试结果,聚焦你的核心短板进行强化,扩大你的认知边界</p> |
|||
</div> |
|||
<div class="right-down"> |
|||
<div v-show="score==100"> |
|||
<p>恭喜您全部回答正确</p> |
|||
<p>接下还需巩固知识</p> |
|||
<p>推荐课程是:量价时空综合、量能擒牛、价格破译</p> |
|||
</div> |
|||
<div v-show="score!=100"> |
|||
<p>接下还需巩固知识</p> |
|||
<p>推荐课程是:{{this.give}}</p> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="content-button"> |
|||
<button class="check-btn" @click="goCheck">查看错题</button> |
|||
<button class="buy-btn" @click="goBuy">前往购买</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script scoped> |
|||
import axios from 'axios'; |
|||
export default{ |
|||
name: 'ReportView', |
|||
data() { |
|||
return { |
|||
showDialog:false, |
|||
score:0, |
|||
give: [], |
|||
}; |
|||
}, |
|||
methods:{ |
|||
async getScore(){ |
|||
const submissionData = JSON.parse(localStorage.getItem('submissionData')); |
|||
console.log('第一个'+submissionData); |
|||
try{ |
|||
const res = await axios.post('http://192.168.40.41:8000/api/knowledge/scores',submissionData); |
|||
const resclass = await axios.post('http://192.168.40.41:8000/api/knowledge/course',submissionData); |
|||
this.give = resclass.data.data[0].cr_name.join('、'); |
|||
this.score = res.data.data[0].score; |
|||
console.log('第二个'+this.score); |
|||
}catch(err){ |
|||
console.log(err); |
|||
} |
|||
}, |
|||
showConfirmDialog() { |
|||
this.showDialog = true; |
|||
}, |
|||
closeDialog() { |
|||
this.showDialog = false; |
|||
}, |
|||
confirmExit() { |
|||
this.showDialog = false; |
|||
this.$router.push('/'); |
|||
}, |
|||
goBuy() { |
|||
this.$router.push('/buy'); |
|||
}, |
|||
goCheck() { |
|||
this.$router.push('/problem'); |
|||
}, |
|||
}, |
|||
async mounted(){ |
|||
await this.getScore(); |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
.ret{ |
|||
width: 30px; |
|||
height: 50px; |
|||
float: left; |
|||
} |
|||
* { |
|||
margin: 0; |
|||
padding: 0; |
|||
box-sizing: border-box; |
|||
} |
|||
.top { |
|||
background: linear-gradient(135deg, #0c4a6e 100%); |
|||
color: white; |
|||
padding: 30px; |
|||
margin-bottom: 30px; |
|||
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; |
|||
} |
|||
.home { |
|||
min-height: 100vh; |
|||
width: 100%; |
|||
background-color: #24293c; |
|||
overflow: auto; |
|||
padding: 20px; |
|||
} |
|||
.ret-top { |
|||
float: left; |
|||
cursor: pointer; |
|||
transition: transform 0.3s ease; |
|||
} |
|||
|
|||
.ret-top:hover { |
|||
transform: scale(1.1); |
|||
} |
|||
.content{ |
|||
border: #274779 solid 2px; |
|||
border-radius: 50px; |
|||
padding: 15px; |
|||
margin-bottom: 20px; |
|||
background-color: #2f374d; |
|||
padding: 30px; |
|||
color: white; |
|||
} |
|||
.left{ |
|||
border: #274779 solid 2px; |
|||
border-radius: 50px; |
|||
padding: 15px; |
|||
margin-bottom: 20px; |
|||
background-color: #2f374d; |
|||
width: 30%; |
|||
top: 200px; |
|||
float: right; |
|||
margin: 10px 0; |
|||
padding: 20px; |
|||
color: #65befc; |
|||
} |
|||
|
|||
.right-top{ |
|||
border: #274779 solid 2px; |
|||
border-radius: 50px; |
|||
padding: 15px; |
|||
margin-bottom: 20px; |
|||
background-color: #2f374d; |
|||
width: 65%; |
|||
margin: 10px; |
|||
padding: 30px 40px; |
|||
float: left; |
|||
} |
|||
.img3{ |
|||
width: 600px; |
|||
height: 400px; |
|||
float: left; |
|||
margin: auto; |
|||
} |
|||
.right-top-left{ |
|||
float: right; |
|||
margin-right: 50px; |
|||
margin-top: 30px; |
|||
} |
|||
.right-down{ |
|||
border: #274779 solid 2px; |
|||
border-radius: 50px; |
|||
padding: 15px; |
|||
margin-bottom: 20px; |
|||
background-color: #2f374d; |
|||
width: 65%; |
|||
height: 300px; |
|||
float: left; |
|||
margin: 10px; |
|||
padding-top: 40px; |
|||
padding-left: 60px; |
|||
clear: right; |
|||
} |
|||
.content::after { |
|||
content: ""; |
|||
display: table; |
|||
clear: both; |
|||
} |
|||
|
|||
.ret-top { |
|||
float: left; |
|||
cursor: pointer; |
|||
transition: transform 0.3s ease; |
|||
} |
|||
|
|||
.ret-top:hover { |
|||
transform: scale(1.1); |
|||
} |
|||
.popup-block { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
z-index: 1000; |
|||
} |
|||
|
|||
.popup-top { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
background: rgba(0, 0, 0, 0.5); |
|||
backdrop-filter: blur(5px); |
|||
} |
|||
|
|||
.popup-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%; |
|||
text-align: center; |
|||
z-index: 1001; |
|||
animation: dialogSlideIn 0.3s ease-out; |
|||
} |
|||
|
|||
.popup-content h3 { |
|||
color: #333; |
|||
margin-bottom: 15px; |
|||
font-size: 1.4em; |
|||
} |
|||
|
|||
.popup-content p { |
|||
color: #666; |
|||
margin-bottom: 25px; |
|||
font-size: 2.2em; |
|||
line-height: 1.5; |
|||
} |
|||
|
|||
.popup-buttons { |
|||
display: flex; |
|||
gap: 15px; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.cancel-btn, .confirm-btn { |
|||
padding: 12px 30px; |
|||
border: none; |
|||
border-radius: 8px; |
|||
font-size: 1em; |
|||
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); |
|||
} |
|||
.img1,.img2{ |
|||
width: 270px; |
|||
height: 180px; |
|||
float: left; |
|||
margin: auto; |
|||
} |
|||
.right-down p{ |
|||
font-size: 2.2em; |
|||
line-height: 1.5; |
|||
color: #65befc; |
|||
} |
|||
.left p{ |
|||
font-size: 2.2em; |
|||
line-height: 1.5; |
|||
} |
|||
.content-button{ |
|||
margin-top: 30px; |
|||
text-align: center; |
|||
} |
|||
.buy-btn,.check-btn{ |
|||
position: relative; |
|||
top:200px; |
|||
padding: 12px 30px; |
|||
border: none; |
|||
border-radius: 8px; |
|||
font-size: 2em; |
|||
font-weight: bold; |
|||
cursor: pointer; |
|||
transition: all 0.3s ease; |
|||
min-width: 100px; |
|||
background-color: #22608b; |
|||
color: white; |
|||
margin:40px; |
|||
float: right; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,274 @@ |
|||
<template> |
|||
<div class="home"> |
|||
<div class="top"> |
|||
<div @click="showConfirmDialog" class="ret-top"> |
|||
<img src="../assets/return.jpg" alt="返回" class="ret"> |
|||
</div> |
|||
<h1>📈股票知识评测系统</h1> |
|||
<p>全方面评估您的股票投资知识水平,获取个性化学习建议</p> |
|||
</div> |
|||
<div class="popup-block" v-if="showDialog"> |
|||
<div class="popup-top" @click="closeDialog"></div> |
|||
<div class="popup-content"> |
|||
<h3>确认提示</h3> |
|||
<p>还未查看分析报告,确定要退出吗?</p> |
|||
<div class="popup-buttons"> |
|||
<button class="cancel-btn" @click="closeDialog">取消</button> |
|||
<button class="confirm-btn" @click="confirmExit">确定</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="content"> |
|||
<div class="block"> |
|||
<div class="section"> |
|||
<p class="p1">恭喜您完成测评</p> |
|||
<img src="../assets/result.jpg" alt="完成测评" class="result"> |
|||
<div class="p2" @click="show"> |
|||
<p>查看分析报告</p> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script> |
|||
export default{ |
|||
name: 'ResultView', |
|||
data() { |
|||
return { |
|||
showDialog:false |
|||
}; |
|||
}, |
|||
methods:{ |
|||
show(){ |
|||
this.$router.push('/report'); |
|||
}, |
|||
// 显示确认弹框 |
|||
showConfirmDialog() { |
|||
this.showDialog = true; |
|||
}, |
|||
// 关闭弹框 |
|||
closeDialog() { |
|||
this.showDialog = false; |
|||
}, |
|||
|
|||
// 确认退出 |
|||
confirmExit() { |
|||
this.showDialog = false; |
|||
// 跳转到首页 |
|||
this.$router.push('/'); |
|||
}, |
|||
} |
|||
} |
|||
</script> |
|||
<style scoped> |
|||
* { |
|||
margin: 0; |
|||
padding: 0; |
|||
box-sizing: border-box; |
|||
} |
|||
|
|||
.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; |
|||
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; |
|||
} |
|||
|
|||
.ret { |
|||
width: 30px; |
|||
height: 50px; |
|||
float: left; |
|||
} |
|||
|
|||
.content { |
|||
height: 750px; |
|||
width: 100%; |
|||
min-height: 600px; |
|||
border: #274779 solid 2px; |
|||
border-radius: 10px; |
|||
color: #f1f5f9; |
|||
padding: 40px 20px; |
|||
background-color: #2a3147; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.block { |
|||
width: 100%; |
|||
max-width: 800px; |
|||
} |
|||
|
|||
.section { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
gap: 30px; |
|||
text-align: center; |
|||
} |
|||
|
|||
.p1 { |
|||
font-size: clamp(2rem, 5vw, 3.5rem); |
|||
font-weight: bold; |
|||
color: #f1f5f9; |
|||
text-align: center; |
|||
margin: 0; |
|||
text-shadow: 2px 2px 4px rgba(0,0,0,0.5); |
|||
} |
|||
|
|||
.result { |
|||
width: min(210px, 30vw); |
|||
height: auto; |
|||
max-width: 100%; |
|||
display: block; |
|||
margin: 0 auto; |
|||
} |
|||
|
|||
.p2 { |
|||
width: min(280px, 80vw); |
|||
height: 60px; |
|||
background: linear-gradient(135deg, #22608b, #2c7cb0); |
|||
color: white; |
|||
text-align: center; |
|||
border-radius: 12px; |
|||
font-size: 1.2rem; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
margin: 0 auto; |
|||
cursor: pointer; |
|||
transition: all 0.3s ease; |
|||
border: 2px solid rgba(255,255,255,0.1); |
|||
box-shadow: 0 4px 15px rgba(0,0,0,0.2); |
|||
} |
|||
|
|||
.p2:hover { |
|||
transform: translateY(-3px); |
|||
box-shadow: 0 6px 20px rgba(0,0,0,0.3); |
|||
background: linear-gradient(135deg, #2c7cb0, #3498db); |
|||
} |
|||
|
|||
.p2 p { |
|||
margin: 0; |
|||
font-weight: bold; |
|||
font-size: clamp(1rem, 3vw, 1.3rem); |
|||
} |
|||
.ret-top { |
|||
float: left; |
|||
cursor: pointer; |
|||
transition: transform 0.3s ease; |
|||
} |
|||
|
|||
.ret-top:hover { |
|||
transform: scale(1.1); |
|||
} |
|||
.popup-block { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
z-index: 1000; |
|||
} |
|||
|
|||
.popup-top { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
background: rgba(0, 0, 0, 0.5); |
|||
backdrop-filter: blur(5px); |
|||
} |
|||
|
|||
.popup-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%; |
|||
text-align: center; |
|||
z-index: 1001; |
|||
animation: dialogSlideIn 0.3s ease-out; |
|||
} |
|||
|
|||
.popup-content h3 { |
|||
color: #333; |
|||
margin-bottom: 15px; |
|||
font-size: 1.4em; |
|||
} |
|||
|
|||
.popup-content p { |
|||
color: #666; |
|||
margin-bottom: 25px; |
|||
font-size: 1.1em; |
|||
line-height: 1.5; |
|||
} |
|||
|
|||
.popup-buttons { |
|||
display: flex; |
|||
gap: 15px; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.cancel-btn, .confirm-btn { |
|||
padding: 12px 30px; |
|||
border: none; |
|||
border-radius: 8px; |
|||
font-size: 1em; |
|||
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); |
|||
} |
|||
</style> |
|||
@ -0,0 +1,275 @@ |
|||
<template> |
|||
<div class="home"> |
|||
<div class="top"> |
|||
<div class="img-top" @click="jump"> |
|||
<img src="../assets/return.jpg" alt="返回" class="img1"> |
|||
</div> |
|||
<span> |
|||
<h1>📈股票知识评测系统</h1> |
|||
</span> |
|||
<p>全方面评估您的股票投资知识水平,获取个性化学习建议</p> |
|||
</div> |
|||
<div class="popup-all" v-if="showDialog"> |
|||
<div class="popup-top" @click="closeDialog"></div> |
|||
<div class="popup-content"> |
|||
<h3>确认提示</h3> |
|||
<p>您还未提交,确定要退出吗?</p> |
|||
<div class="popup-buttons"> |
|||
<button class="cancel-btn" @click="closeDialog">取消</button> |
|||
<button class="confirm-btn" @click="confirmExit">确定</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="content"> |
|||
<div class="block"> |
|||
<div class="schedule" :style="{ width: progress + '%' }"></div> |
|||
</div> |
|||
<div class="text"> |
|||
<div class="question">1、以下哪项不是股票的基本特征?</div> |
|||
<div class="options"> |
|||
<label class="option"> |
|||
<input type="radio" name="answer1" value="A"> |
|||
<span class="label">A. 收益性</span> |
|||
</label> |
|||
<label class="option"> |
|||
<input type="radio" name="answer1" value="B"> |
|||
<span class="label">B. 风险性</span> |
|||
</label> |
|||
<label class="option"> |
|||
<input type="radio" name="answer1" value="C"> |
|||
<span class="label">C. 流动性</span> |
|||
</label> |
|||
<label class="option"> |
|||
<input type="radio" name="answer1" value="D"> |
|||
<span class="label">D. 固定性</span> |
|||
</label> |
|||
</div> |
|||
</div> |
|||
<div class="text"> |
|||
<div class="question">2、以下哪项不是股票的基本特征?</div> |
|||
<div class="options"> |
|||
<label class="option"> |
|||
<input type="radio" name="answer2" value="A"> |
|||
<span class="label">A. 收益性</span> |
|||
</label> |
|||
<label class="option"> |
|||
<input type="radio" name="answer2" value="B"> |
|||
<span class="label">B. 风险性</span> |
|||
</label> |
|||
<label class="option"> |
|||
<input type="radio" name="answer2" value="C"> |
|||
<span class="label">C. 流动性</span> |
|||
</label> |
|||
<label class="option"> |
|||
<input type="radio" name="answer2" value="D"> |
|||
<span class="label">D. 固定性</span> |
|||
</label> |
|||
</div> |
|||
</div> |
|||
<div> |
|||
<button onclick="nextPage" class="nextpage">下一页 -></button> |
|||
</div> |
|||
</div> |
|||
<div class="right"> |
|||
<div class="hour"> |
|||
|
|||
</div> |
|||
<div class="all"> |
|||
|
|||
</div> |
|||
<div class="statistics"> |
|||
|
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
showDialog: false |
|||
} |
|||
}, |
|||
methods: { |
|||
jump() { |
|||
this.showDialog = true; |
|||
}, |
|||
closeDialog() { |
|||
this.showDialog = false; |
|||
}, |
|||
confirmExit() { |
|||
this.showDialog = false; |
|||
this.$router.push({ name: 'HomeView' }); |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
<style scoped> |
|||
* { |
|||
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; |
|||
} |
|||
.img-top{ |
|||
float: left; |
|||
} |
|||
.img-top:hover{ |
|||
transform: scale(1.1); |
|||
} |
|||
.img1{ |
|||
width: 30px; |
|||
height: 50px; |
|||
float: left; |
|||
} |
|||
h1{ |
|||
margin-bottom: 10px; |
|||
background: none; |
|||
font-size: 2.2em; |
|||
} |
|||
p{ |
|||
font-size: 1.2em; |
|||
margin-bottom: 10px; |
|||
background: none; |
|||
} |
|||
.popup-all{ |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
z-index: 1000; |
|||
} |
|||
.popup-top{ |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
background: rgba(0, 0, 0, 0.5); |
|||
backdrop-filter: blur(5px); |
|||
} |
|||
.popup-content{ |
|||
background-color: #f1f5f9; |
|||
padding: 20px; |
|||
border-radius: 10px; |
|||
box-shadow: 0 0 10px rgba(0,0,0,0.3); |
|||
} |
|||
.popup-buttons{ |
|||
margin-top: 20px; |
|||
display: flex; |
|||
justify-content: flex-end; |
|||
} |
|||
.cancel-btn{ |
|||
background-color: #f1f5f9; |
|||
color: #24293c; |
|||
border-radius: 10px; |
|||
border: transparent 0px ; |
|||
margin: 5px; |
|||
padding: 5px 10px; |
|||
} |
|||
.confirm-btn{ |
|||
background-color: #22608b; |
|||
color: #f1f5f9; |
|||
border-radius: 10px; |
|||
border: transparent 0px ; |
|||
margin: 5px; |
|||
padding: 5px 10px; |
|||
} |
|||
|
|||
.block { |
|||
background: rgba(139, 141, 145, 0.7); |
|||
width: 90%; |
|||
height: 10px; |
|||
border-radius: 5px; |
|||
margin:auto; |
|||
overflow: hidden; |
|||
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%; |
|||
width: 15%; |
|||
transition: width 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); |
|||
position: relative; |
|||
} |
|||
.content{ |
|||
float: left; |
|||
height: 100%; |
|||
width: 60%; |
|||
border: #183954 solid 2px; |
|||
border-radius: 10px; |
|||
color: #f1f5f9; |
|||
padding: 20px 40px 50px; |
|||
margin: 30px; |
|||
} |
|||
.question{ |
|||
font-size: 1.3em; |
|||
line-height: 1.8; |
|||
margin-bottom: 25px; |
|||
color: #f1f5f9; |
|||
font-weight: 500; |
|||
} |
|||
.option{ |
|||
border: #183954 solid 2px; |
|||
border-radius: 10px; |
|||
width: 70%; |
|||
padding: 5px; |
|||
margin: 3px; |
|||
} |
|||
.options { |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 15px; |
|||
} |
|||
.text{ |
|||
border: #183954 solid 2px; |
|||
border-radius: 10px; |
|||
padding: 20px 40px; |
|||
margin: 30px; |
|||
} |
|||
.hour,.all,.statistics{ |
|||
width: 300px; |
|||
border: #183954 solid 2px; |
|||
border-radius: 10px; |
|||
padding: 5px; |
|||
margin: 3px; |
|||
} |
|||
.right{ |
|||
float: right; |
|||
height: 100%; |
|||
width: 30%; |
|||
border: #183954 solid 2px; |
|||
border-radius: 10px; |
|||
color: #f1f5f9; |
|||
padding: 20px 40px 50px; |
|||
margin: 30px; |
|||
} |
|||
.nextpage{ |
|||
width: 70px; |
|||
height: 30px; |
|||
background-color: #22608b; |
|||
color: #f1f5f9; |
|||
border-radius: 10px; |
|||
border: transparent 0px ; |
|||
margin: 5px; |
|||
float: right; |
|||
} |
|||
</style> |
|||
1942
src/views/TextHtml.html
File diff suppressed because it is too large
View File
@ -0,0 +1,761 @@ |
|||
<template> |
|||
<div class="home"> |
|||
<div class="top"> |
|||
<div class="img-top" @click="showConfirmDialog"> |
|||
<img src="../assets/return.jpg" alt="返回" class="img1"> |
|||
</div> |
|||
<h1>📈股票知识评测系统</h1> |
|||
<p>全方面评估您的股票投资知识水平,获取个性化学习建议</p> |
|||
</div> |
|||
|
|||
<div class="popup-all popup-background" v-if="showDialog"> |
|||
<div class="popup-content"> |
|||
<h3>确认提示</h3> |
|||
<p>您还未提交,确定要退出吗?</p> |
|||
<div class="popup-buttons"> |
|||
<button class="cancel-btn" @click="closeDialog">取消</button> |
|||
<button class="confirm-btn" @click="confirmExit">确定</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="popup-all popup-background" v-if="showTeam"> |
|||
<div class="popup-content"> |
|||
<h3>确认提示</h3> |
|||
<p>您确定要提交吗?</p> |
|||
<div class="popup-buttons"> |
|||
<button class="cancel-btn" @click="closeSubmit">取消</button> |
|||
<button class="confirm-btn" @click="submitAnswers">确定</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="content"> |
|||
<div class="block"> |
|||
<div class="schedule" :style="{ width: progress + '%' }"></div> |
|||
</div> |
|||
|
|||
<div class="question-all"> |
|||
<div v-for="question in currentQuestions" :key="question.id" class="left-question-card"> |
|||
<div class="question"> |
|||
<span class="text">{{ question.id }}、</span> |
|||
{{ question.stem }} |
|||
</div> |
|||
<div class="options"> |
|||
<label |
|||
class="option" |
|||
:class="{ 'selected': getAnswer(question.id) === 'A' }" |
|||
@click="setAnswer(question.id, 'A')" |
|||
> |
|||
<input |
|||
type="radio" |
|||
:name="'answer' + question.id" |
|||
value="A" |
|||
:checked="getAnswer(question.id) === 'A'" |
|||
@change="setAnswer(question.id, 'A')" |
|||
> |
|||
<span class="label">A. {{ question.A }}</span> |
|||
</label> |
|||
<label |
|||
class="option" |
|||
:class="{ 'selected': getAnswer(question.id) === 'B' }" |
|||
@click="setAnswer(question.id, 'B')" |
|||
> |
|||
<input |
|||
type="radio" |
|||
:name="'answer' + question.id" |
|||
value="B" |
|||
:checked="getAnswer(question.id) === 'B'" |
|||
@change="setAnswer(question.id, 'B')" |
|||
> |
|||
<span class="label">B. {{ question.B }}</span> |
|||
</label> |
|||
<label |
|||
class="option" |
|||
:class="{ 'selected': getAnswer(question.id) === 'C' }" |
|||
@click="setAnswer(question.id, 'C')" |
|||
> |
|||
<input |
|||
type="radio" |
|||
:name="'answer' + question.id" |
|||
value="C" |
|||
:checked="getAnswer(question.id) === 'C'" |
|||
@change="setAnswer(question.id, 'C')" |
|||
> |
|||
<span class="label">C. {{ question.C }}</span> |
|||
</label> |
|||
<label |
|||
class="option" |
|||
:class="{ 'selected': getAnswer(question.id) === 'D' }" |
|||
@click="setAnswer(question.id, 'D')" |
|||
> |
|||
<input |
|||
type="radio" |
|||
:name="'answer' + question.id" |
|||
value="D" |
|||
:checked="getAnswer(question.id) === 'D'" |
|||
@change="setAnswer(question.id, 'D')" |
|||
> |
|||
<span class="label">D. {{ question.D }}</span> |
|||
</label> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="buttons-left"> |
|||
<button |
|||
class="before-btn" |
|||
@click="before" |
|||
:disabled="currentPage === 1" |
|||
> |
|||
← 上一页 |
|||
</button> |
|||
<span class="page">第 {{ currentPage }} 页 / 共 {{ totalPages }} 页</span> |
|||
<button |
|||
class="next-btn" |
|||
@click="next" |
|||
:disabled="currentPage === totalPages" |
|||
> |
|||
下一页 → |
|||
</button> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="right"> |
|||
<h3>⏰ 倒计时</h3> |
|||
<div class="time-module"> |
|||
<div class="countdown">{{ countdown }}</div> |
|||
</div> |
|||
|
|||
<h3>📝 题目导航</h3> |
|||
<div class="right-question-card" v-show="page === 1"> |
|||
<div |
|||
class="question-number normal" |
|||
:class="getQuestionStatusClass(i)" |
|||
@click="goToPageByQuestion(i)" |
|||
v-for="i in 25" |
|||
:key="i" |
|||
> |
|||
<span class="question-text">{{ i }}</span> |
|||
</div> |
|||
</div> |
|||
<div class="right-question-card" v-show="page === 2"> |
|||
<div |
|||
class="question-number normal" |
|||
:class="getQuestionStatusClass(i + 25)" |
|||
@click="goToPageByQuestion(i + 25)" |
|||
v-for="i in 25" |
|||
:key="i + 25" |
|||
> |
|||
<span class="question-text">{{ i + 25 }}</span> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="button-right"> |
|||
<button |
|||
class="right-before-btn" |
|||
@click="changeNavPage(1)" |
|||
:class="{ active: page === 1 }" |
|||
> |
|||
上一页 |
|||
</button> |
|||
<button |
|||
class="right-next-btn" |
|||
@click="changeNavPage(2)" |
|||
:class="{ active: page === 2 }" |
|||
> |
|||
下一页 |
|||
</button> |
|||
</div> |
|||
|
|||
<h3>📊 答题统计</h3> |
|||
<div class="statistics"> |
|||
<div class="statistics-item"> |
|||
<span class="statistics-label">答题进度:</span> |
|||
<span class="statistics-value">{{ answeredCount }}/{{ totalQuestions }}</span> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="button-right-bottom"> |
|||
<button class="right-bottom-btn" @click="closeTeamPrompt">🚀 提交试卷</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import axios from 'axios'; |
|||
export default { |
|||
name: 'TextView', |
|||
data() { |
|||
return { |
|||
questions: [], |
|||
currentPage: 1, |
|||
page: 1, |
|||
questionsPerPage: 2, |
|||
answers: {}, |
|||
startTime: new Date(), |
|||
countdownMinutes: 30, |
|||
countdown: '', |
|||
timer: null, |
|||
isSubmitted: false, |
|||
totalQuestions: 50, |
|||
questionStates: {}, |
|||
showDialog: false, |
|||
showTeam: false, |
|||
}; |
|||
}, |
|||
created() { |
|||
for (let i = 1; i <= this.totalQuestions; i++) { |
|||
this.$set(this.answers, i, 0) |
|||
} |
|||
}, |
|||
computed: { |
|||
currentQuestions() { |
|||
const startIndex = (this.currentPage - 1) * this.questionsPerPage; |
|||
return [ |
|||
this.questions[startIndex], |
|||
this.questions[startIndex + 1] |
|||
].filter(Boolean); |
|||
}, |
|||
totalPages() { |
|||
return Math.ceil(this.questions.length / this.questionsPerPage); |
|||
}, |
|||
answeredCount() { |
|||
return Object.keys(this.answers).filter( |
|||
key => this.answers[key] !== 0 |
|||
).length |
|||
}, |
|||
completionRate() { |
|||
return (this.answeredCount / this.totalQuestions) * 100; |
|||
}, |
|||
progress() { |
|||
return this.completionRate; |
|||
}, |
|||
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'); |
|||
this.questions = response.data.data.list; |
|||
} catch (error) { |
|||
console.error('获取题目失败:', error); |
|||
} |
|||
}, |
|||
|
|||
showConfirmDialog() { |
|||
this.showDialog = true; |
|||
}, |
|||
|
|||
closeDialog() { |
|||
this.showDialog = false; |
|||
}, |
|||
|
|||
confirmExit() { |
|||
this.showDialog = false; |
|||
this.$router.push('/'); |
|||
}, |
|||
|
|||
closeTeamPrompt() { |
|||
this.showTeam = true; |
|||
}, |
|||
|
|||
closeSubmit() { |
|||
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]; |
|||
|
|||
if (isCurrent) { |
|||
return 'current'; |
|||
} else if (isAnswered) { |
|||
return 'answered'; |
|||
} else { |
|||
return 'normal'; |
|||
} |
|||
}, |
|||
|
|||
changeNavPage(newPage) { |
|||
this.page = newPage; |
|||
}, |
|||
|
|||
changePage(newPage) { |
|||
if (newPage >= 1 && newPage <= this.totalPages) { |
|||
this.currentPage = newPage; |
|||
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); |
|||
}, |
|||
|
|||
before() { |
|||
if (this.currentPage > 1) { |
|||
this.currentPage--; |
|||
} |
|||
if(this.currentPage < 13){ |
|||
this.page=1; |
|||
} |
|||
}, |
|||
|
|||
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); |
|||
const remainingMinutes = Math.max(0, this.countdownMinutes - elapsedMinutes); |
|||
|
|||
const minutes = Math.floor(remainingMinutes).toString().padStart(2, '0'); |
|||
const seconds = Math.floor((remainingMinutes % 1) * 60).toString().padStart(2, '0'); |
|||
|
|||
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')); |
|||
const submission = { |
|||
jwcode: savedData.jwcode, |
|||
answers: formattedAnswers |
|||
}; |
|||
|
|||
const response = await axios.post('http://192.168.40.41:8000/api/knowledge/submit', submission); |
|||
|
|||
this.$router.push({ |
|||
name: 'ResultView', |
|||
query: { |
|||
score: response.data.data.score || 80, |
|||
total: this.totalQuestions, |
|||
timeUsed: this.getTimeUsed() |
|||
} |
|||
}); |
|||
} catch (error) { |
|||
console.error('提交试卷失败:', error); |
|||
alert('提交失败,请重试'); |
|||
this.isSubmitted = false; |
|||
} |
|||
}, |
|||
|
|||
getTimeUsed() { |
|||
const now = new Date(); |
|||
const elapsedMinutes = (now - this.startTime) / (1000 * 60); |
|||
return Math.round(elapsedMinutes); |
|||
} |
|||
}, |
|||
async mounted() { |
|||
await this.fetchQuestions(); |
|||
this.timer = setInterval(() => { |
|||
this.updateCountdown(); |
|||
}, 1000); |
|||
}, |
|||
beforeDestroy() { |
|||
if (this.timer) { |
|||
clearInterval(this.timer); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
* { |
|||
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; |
|||
} |
|||
|
|||
.img-top { |
|||
float: left; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
.img-top:hover { |
|||
transform: scale(1.1); |
|||
} |
|||
|
|||
.img1 { |
|||
width: 30px; |
|||
height: 50px; |
|||
float: left; |
|||
} |
|||
|
|||
h1 { |
|||
margin-bottom: 10px; |
|||
background: none; |
|||
font-size: 2.2em; |
|||
} |
|||
|
|||
p { |
|||
font-size: 1.2em; |
|||
margin-bottom: 10px; |
|||
background: none; |
|||
} |
|||
|
|||
.popup-all { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
z-index: 1000; |
|||
} |
|||
|
|||
.popup-background { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 125%; |
|||
background: rgba(0, 0, 0, 0.5); |
|||
backdrop-filter: blur(5px); |
|||
} |
|||
|
|||
.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; |
|||
} |
|||
|
|||
.popup-buttons { |
|||
margin-top: 20px; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.cancel-btn, .confirm-btn { |
|||
border-radius: 10px; |
|||
border: transparent 0px ; |
|||
margin: 5px; |
|||
padding: 12px 30px; |
|||
font-size: 1em; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.cancel-btn { |
|||
background: #f1f1f1; |
|||
color: #666; |
|||
} |
|||
|
|||
.confirm-btn { |
|||
background: #ff4757; |
|||
color: white; |
|||
} |
|||
|
|||
.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; |
|||
} |
|||
|
|||
.block { |
|||
background: rgba(139, 141, 145, 0.7); |
|||
width: 90%; |
|||
height: 10px; |
|||
border-radius: 5px; |
|||
margin: 0 auto 30px; |
|||
overflow: hidden; |
|||
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%; |
|||
width: 15%; |
|||
transition: width 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); |
|||
position: relative; |
|||
} |
|||
|
|||
.question-all { |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 30px; |
|||
} |
|||
|
|||
.left-question-card { |
|||
border: #274779 solid 2px; |
|||
border-radius: 10px; |
|||
padding: 20px 40px; |
|||
background-color: #2f374d; |
|||
} |
|||
|
|||
.question { |
|||
font-size: 1.3em; |
|||
line-height: 1.8; |
|||
margin-bottom: 25px; |
|||
color: #f1f5f9; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.options { |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 15px; |
|||
} |
|||
|
|||
.option { |
|||
border: #183954 solid 2px; |
|||
border-radius: 10px; |
|||
padding: 12px 15px; |
|||
display: flex; |
|||
align-items: center; |
|||
cursor: pointer; |
|||
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); |
|||
border: #274779 solid 2px; |
|||
border-radius: 30px; |
|||
padding: 15px 0 15px 19px ; |
|||
margin-bottom: 20px; |
|||
background-color: #2f374d; |
|||
color: white; |
|||
} |
|||
|
|||
.right h3 { |
|||
font-size: 1.2em; |
|||
padding-bottom: 15px; |
|||
margin-bottom: 15px; |
|||
border-bottom: 2px solid #274779; |
|||
} |
|||
|
|||
.time-module { |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
.countdown { |
|||
font-size: 1.5em; |
|||
color: #f59e0b; |
|||
text-align: center; |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
.right-question-card { |
|||
display: grid; |
|||
grid-template-columns: repeat(5, 1fr); |
|||
gap: 10px; |
|||
margin: auto 30px; |
|||
} |
|||
|
|||
.question-number { |
|||
width: 60px; |
|||
height: 50px; |
|||
border-radius: 8px; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
font-weight: bold; |
|||
cursor: pointer; |
|||
position: relative; |
|||
} |
|||
|
|||
.question-number.normal { |
|||
background-color: #374151; |
|||
border: 1px solid #4b5563; |
|||
color: #e5e7eb; |
|||
} |
|||
|
|||
.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); |
|||
} |
|||
|
|||
.question-number:hover { |
|||
transform: scale(1.05); |
|||
} |
|||
|
|||
.button-right { |
|||
display: flex; |
|||
margin: 30px 180px 5px; |
|||
gap: 20px; |
|||
} |
|||
|
|||
.right-before-btn, .right-next-btn { |
|||
padding: 8px 15px; |
|||
border-radius: 8px; |
|||
border: none; |
|||
background-color: #3b82f6; |
|||
color: white; |
|||
font-weight: bold; |
|||
cursor: pointer; |
|||
margin: auto 20px; |
|||
} |
|||
|
|||
.right-before-btn:hover, .right-next-btn:hover { |
|||
background-color: #2563eb; |
|||
} |
|||
|
|||
.right-before-btn.active, .right-next-btn.active { |
|||
background-color: #2563eb; |
|||
transform: scale(1.05); |
|||
} |
|||
|
|||
.statistics { |
|||
margin-bottom: 20px; |
|||
} |
|||
|
|||
.statistics-item { |
|||
display: flex; |
|||
font-size: larger; |
|||
justify-content: space-between; |
|||
margin-top: 30px; |
|||
padding-top: 10px; |
|||
padding-bottom: 2px; |
|||
border-bottom: 2px solid #274779; |
|||
} |
|||
|
|||
.statistics-label { |
|||
color: #e5e7eb; |
|||
} |
|||
|
|||
.statistics-value { |
|||
font-weight: bold; |
|||
color: #3b82f6; |
|||
} |
|||
|
|||
.button-right-bottom { |
|||
margin-top: 20px; |
|||
} |
|||
|
|||
.right-bottom-btn { |
|||
width: 100%; |
|||
height: 40px; |
|||
border-radius: 8px; |
|||
background-color: #10b981; |
|||
color: white; |
|||
text-align: center; |
|||
line-height: 40px; |
|||
border: none; |
|||
font-size: 1.2em; |
|||
font-weight: bold; |
|||
cursor: pointer; |
|||
transition: all 0.3s ease; |
|||
} |
|||
|
|||
.right-bottom-btn:hover { |
|||
background-color: #059669; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,32 @@ |
|||
// const { defineConfig } = require('@vue/cli-service')
|
|||
// module.exports = defineConfig({
|
|||
// transpileDependencies: true
|
|||
// })
|
|||
const { defineConfig } = require('@vue/cli-service') |
|||
|
|||
module.exports = defineConfig({ |
|||
devServer: { |
|||
proxy: { |
|||
// 代理所有以 /api 开头的请求
|
|||
'/api': { |
|||
target: 'http://192.168.40.48:8081', // 你的后端地址
|
|||
changeOrigin: true, // 允许跨域
|
|||
pathRewrite: { |
|||
'^/api': '' // 重写路径,去掉 /api 前缀
|
|||
}, |
|||
secure: false, // 如果是https接口,需要配置这个参数
|
|||
logLevel: 'debug' // 查看代理日志
|
|||
}, |
|||
|
|||
// 可以配置多个代理
|
|||
'/upload': { |
|||
target: 'http://localhost:3000', |
|||
changeOrigin: true |
|||
} |
|||
}, |
|||
|
|||
// 允许外部访问
|
|||
host: '0.0.0.0', |
|||
port: 8080 |
|||
} |
|||
}) |
|||