学校端界面优化

This commit is contained in:
jiangzhe 2024-04-15 17:33:01 +08:00
parent bc7556bd4d
commit 5e65fd4b71
18 changed files with 308 additions and 117 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

View File

@ -3,6 +3,7 @@ import { createRouter, createWebHistory } from 'vue-router'
import Login from '@/views/Login/index.vue'
import Exam from '@/views/Exam/index.vue'
import ScaleList from '@/views/ScaleList/index.vue'
import ExamDetail from '@/views/ExamDetail/index.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
@ -18,6 +19,10 @@ const router = createRouter({
{
path: '/exam',
component: Exam
},
{
path:'/examDetail',
component: ExamDetail
}
],
// 路由滚动行为定制

View File

@ -1,6 +1,6 @@
/* 只需要重写你需要的即可 */
@forward 'element-plus/theme-chalk/src/common/var.scss' with ($colors: ('primary': ( // 主色
'base': #1CC19A,
'base': #18C8FF,
),
'success': ( // 成功色
'base': #1dc779,

View File

@ -4,46 +4,72 @@
<img src="@/assets/images/fenxiang.png" alt="">
<span class="desc">本平台提供专业的自评量表请仔细地阅读每一条根据近期内您的实际感受点击适合您的选项请注意不要漏题答题完成后您将获得一份专业的分析报告</span>
</el-header>
<el-main class="main">
<el-card class="card">
<template #header>
<div class="card-header">
{{ scaleName }}
</div>
</template>
<el-progress :percentage="10" :format="format" />
<div class="content">
<el-container>
<el-aside class="aside">
<el-card class="aside-card">
<template #header>
<div class="card-header">
<span>答题卡</span>
</div>
</template>
<div class="answer">
<div v-for="(item, index) in questionList" :key="item">
<el-button circle type="danger" v-if="item.answerId" @click="handleAnswer(index)">
{{ index + 1 }}
</el-button>
<el-button v-else circle @click="handleAnswer(index)">{{ index + 1 }}</el-button>
</div>
</div>
<template #footer>
<el-countdown title="剩余时间" :value="timeLeft" value-style="color: #F56C6C;" />
</template>
</el-card>
</el-aside>
<div class="subject-content">
<div class="subject-title">{{ currentQuestion.questionContent }}</div>
<el-radio-group v-model="currentQuestion.answerId" @change="handleChange">
<el-radio :value="item.answerId" v-for="item in currentQuestion.answerList" :key="item.answerId">
{{ item.answerOption }}
</el-radio>
</el-radio-group>
</div>
<el-main class="main">
<el-card class="card">
<template #header>
<div class="card-header">
{{ scaleName }}
</div>
</template>
<div class="subject-content">
<div class="subject-title">{{ currentQuestion.questionContent }}</div>
<el-radio-group v-model="currentQuestion.answerId" @change="handleChange">
<el-radio size="large" border :value="item.answerId" v-for="item in currentQuestion.answerList"
:key="item.answerId">
{{ item.answerOption }}
</el-radio>
</el-radio-group>
</div>
<div class="subject-btn">
<el-button-group>
<el-button type="primary" size="large" @click="previous" :disabled="preDisable">
<el-icon class="el-icon--left">
<ArrowLeft />
</el-icon>
</el-button>
<el-button v-if="finishNum" type="primary" size="large" @click="submit">
提交<el-icon class="el-icon--right">
<ArrowRight />
</el-icon>
</el-button>
<el-button v-else type="primary" size="large" @click="next">
下一题<el-icon class="el-icon--right">
<ArrowRight />
</el-icon>
</el-button>
</el-button-group>
</div>
</el-card>
</el-main>
</el-container>
</div>
<div class="subject-btn">
<el-button-group>
<el-button type="primary" size="large" @click="previous" :disabled="preDisable">
<el-icon class="el-icon--left">
<ArrowLeft />
</el-icon>
</el-button>
<el-button v-if="nextDisable" type="primary" size="large" @click="submit">
提交<el-icon class="el-icon--right">
<ArrowRight />
</el-icon>
</el-button>
<el-button v-else type="primary" size="large" @click="next">
下一题<el-icon class="el-icon--right">
<ArrowRight />
</el-icon>
</el-button>
</el-button-group>
</div>
</el-card>
</el-main>
</el-container>
</template>
@ -55,20 +81,22 @@ import { getAnswerAPI, addAnswerAPI } from '@/apis/user'
const route = useRoute()
const scaleId = route.query.scaleId
const scaleName = route.query.scaleName
const scaleTime = route.query.scaleTime
const recordId = route.query.recordId
const router = useRouter()
const format = (percentage) => (percentage === 100 ? '90题' : `10/90题`)
const timeLeft = ref(Date.now() + 1000 * 60 * scaleTime)
const questionList = ref([])
const questionNum = ref(0)
const currentQuestion = ref({})
const questionTotal = ref(0)
async function getAnswer() {
const res = await getAnswerAPI(scaleId)
questionList.value = res.data
currentQuestion.value = questionList.value[0]
questionTotal.value = questionList.value.length
}
const preDisable = computed(() => {
@ -85,7 +113,12 @@ function previous() {
}
const nextDisable = computed(() => {
return questionNum.value === questionList.value.length - 1
return questionNum.value === questionTotal.value
})
const finishNum = computed(() => {
const data = questionList.value.filter(item => item.answerId != null)
return data.length == questionTotal.value
})
function next() {
@ -98,8 +131,15 @@ function next() {
currentQuestion.value = questionList.value[questionNum.value]
}
function handleChange() {
function handleAnswer(index) {
questionNum.value = index
currentQuestion.value = questionList.value[questionNum.value]
}
function handleChange(e) {
setTimeout(() => {
next()
}, 500)
}
onMounted(() => {
@ -113,7 +153,7 @@ async function submit() {
}
})
const res = await addAnswerAPI(data)
const res = await addAnswerAPI({ scaleId, answerList: data })
if (res.code == 200) {
ElMessage({
message: '提交成功',
@ -141,57 +181,84 @@ async function submit() {
}
}
.main {
width: 60%;
height: calc(100vh - 60px);
.content {
width: 1200px;
margin: 0 auto;
.card {
height: 100%;
.aside {
width: 400px;
padding-top: 20px;
margin: 0 auto;
.card-header {
text-align: center;
font-size: 30px;
font-weight: bold;
line-height: 60px;
}
.aside-card {
width: 100%;
margin: 0 auto;
.subject-btn {
text-align: center;
}
.answer {
display: grid;
grid-template-columns: repeat(8, 1fr);
.submit-footer {
text-align: center;
.submit-btn {
width: 200px;
.el-button {
margin: 7px;
}
}
}
}
.subject-content {
margin-left: 50px;
margin-top: 30px;
height: 400px;
.main {
width: 800px;
height: calc(100vh - 60px);
margin: 0 auto;
::v-deep .el-radio-group {
display: block;
}
.card {
height: 100%;
::v-deep .el-radio {
display: block;
margin: 10px;
}
.subject-title {
color: #FF5A72;
font-size: 18px;
.card-header {
text-align: center;
font-size: 30px;
font-weight: bold;
line-height: 60px;
}
::v-deep .el-radio__label {
font-size: 18px;
font-weight: bold;
padding-left: 8px;
.subject-btn {
text-align: center;
}
.submit-footer {
text-align: center;
.submit-btn {
width: 200px;
}
}
.subject-content {
margin-left: 50px;
margin-top: 30px;
height: 400px;
.subject-title {
text-align: center;
color: #F56C6C;
font-size: 30px;
font-weight: bold;
}
::v-deep(.el-radio-group) {
display: block;
}
::v-deep(.el-radio) {
display: block;
margin: 25px;
font-size: 25px;
}
::v-deep(.el-radio__label) {
font-size: 20px;
font-weight: bold;
padding-left: 20px;
}
}
}
}

View File

@ -0,0 +1,110 @@
<template>
<div class="header"></div>
<div class="content">
<el-card style="margin-top: 20px;height: 100%;">
<template #header>
<div class="card-header">
<img src="@/assets/images/answer-element-1.png" alt="">
<div class="text">测评完成</div>
</div>
<div class="score">
总分{{ des.totalScore }}
</div>
</template>
<el-descriptions :title="`测评项:${item.evalItemName}`" direction="vertical" column="1" v-for="item in des.list">
<el-descriptions-item :label="`结果分析:${item.evalDesc}`">
{{ item.evalPropose }}
</el-descriptions-item>
</el-descriptions>
<template #footer>
<div class="footer">
<el-button type="primary" round @click="$router.push('/')">返回首页</el-button>
</div>
</template>
</el-card>
</div>
</template>
<script setup>
import { ref } from 'vue'
const des = ref({
"evalRecordId": 2734431927582720,
"scaleName": "人际交往心理测试",
"list": [
{
"id": 2734431927779328,
"evalRecordId": 2734431927582720,
"evalItem": 28,
"score": 1.0,
"scoreRate": 3.33,
"scaleItemRangeId": 2606988724994048,
"status": 1,
"scaleRecordId": 2715976035876864,
"evalItemName": "人际关系",
"evalDesc": "善于人际交往",
"evalPropose": "对于性格外向、喜欢人际交往的人,以下是一些建议可以帮助你更好地发挥自己的优势和提升人际交往能力:主动参与社交活动:利用你的外向性格,积极主动参与各种社交活动和事件,如聚会、社团活动、志愿者工作等。这样可以扩大你的社交圈子,结识更多的人,并与他们建立联系;倾听和关心他人:在交流中,注重倾听他人的观点和感受。表现出对他人的关心和尊重,积极表达理解和同理心。这样可以建立良好的互动和亲密关系;保持积极的态度:以积极、乐观的态度面对人际交往。相信自己的能力,对他人持开放的心态。这样能够吸引更多的人与你交往,并建立良好的人际关系。",
"situation": 402,
"situationName": "低风险"
},
{
"id": 2734431927779328,
"evalRecordId": 2734431927582720,
"evalItem": 28,
"score": 1.0,
"scoreRate": 3.33,
"scaleItemRangeId": 2606988724994048,
"status": 1,
"scaleRecordId": 2715976035876864,
"evalItemName": "人际关系",
"evalDesc": "善于人际交往",
"evalPropose": "对于性格外向、喜欢人际交往的人,以下是一些建议可以帮助你更好地发挥自己的优势和提升人际交往能力:主动参与社交活动:利用你的外向性格,积极主动参与各种社交活动和事件,如聚会、社团活动、志愿者工作等。这样可以扩大你的社交圈子,结识更多的人,并与他们建立联系;倾听和关心他人:在交流中,注重倾听他人的观点和感受。表现出对他人的关心和尊重,积极表达理解和同理心。这样可以建立良好的互动和亲密关系;保持积极的态度:以积极、乐观的态度面对人际交往。相信自己的能力,对他人持开放的心态。这样能够吸引更多的人与你交往,并建立良好的人际关系。",
"situation": 402,
"situationName": "低风险"
}
],
"totalScore": 1.0
})
</script>
<style lang="scss" scoped>
.header {
width: 100%;
height: 501px;
background: url(../../assets/images/banner.png) no-repeat;
background-size: cover;
}
.content {
width: 1200px;
min-height: calc(100vh - 550px);
margin: 0 auto;
.card-header {
text-align: center;
img {
width: 300px;
}
.text {
color: #1A91FF;
font-size: 35px;
font-weight: bold;
margin: 20px 0;
}
}
.score {
color: #1A91FF;
font-size: 25px;
font-weight: bold;
}
.footer {
text-align: center;
}
}
</style>

View File

@ -1,18 +1,21 @@
<template>
<div class="login-container">
<div class="logo" />
<div class="logo">
<div class="second_bg"></div>
</div>
<div class="form">
<h1 style="color: #A2A2A3;">云舒 心理健康平台</h1>
<h1>云舒心理健康平台</h1>
<el-card shadow="never" class="login-card">
<el-form ref="formRef" :model="loginForm" :rules="loginRules">
<el-form ref="formRef" :model="loginForm" :rules="loginRules" v-loading="loading" element-loading-text="登录中...">
<el-form-item prop="username">
<el-input :prefix-icon="User" v-model="loginForm.username" placeholder="请输入学号" />
<el-input :prefix-icon="User" v-model="loginForm.username" placeholder="请输入学号" @keyup.enter="login" />
</el-form-item>
<el-form-item prop="password">
<el-input :prefix-icon="Lock" v-model="loginForm.password" show-password placeholder="请输入密码" />
<el-input :prefix-icon="Lock" v-model="loginForm.password" show-password placeholder="请输入密码"
@keyup.enter="login" />
</el-form-item>
<el-form-item>
<el-button style="width:350px" type="primary" @click="login">登录</el-button>
<el-button round style="width:350px" type="primary" @click="login">登录</el-button>
</el-form-item>
</el-form>
</el-card>
@ -34,6 +37,8 @@ const loginForm = ref({
grantType: 'password'
})
const loading = ref(false)
const loginRules = ref({
username: [
{ required: true, message: '请输入学号', trigger: 'blur' },
@ -47,22 +52,19 @@ const formRef = ref(null)
async function login() {
formRef.value.validate(async (valid) => {
if (valid) {
loading.value = true
const res = await loginAPI(loginForm.value)
if (res.code == 200) {
localStorage.setItem('token', res.data.access_token)
router.push('/')
} else {
ElMessage.error(res.msg)
}
loading.value = false
}
})
}
onMounted(() => {
})
</script>
<style lang="scss" scoped>
@ -70,42 +72,37 @@ onMounted(() => {
display: flex;
align-items: stretch;
height: 100vh;
background-color: #fff;
.logo {
flex: 3;
background: rgba(38, 72, 176) url(../../assets/images/login_back.png) no-repeat center / cover;
border-top-right-radius: 60px;
flex: 4;
background: rgba(38, 72, 176) url(../../assets/images/bg1.png) no-repeat center / cover;
display: flex;
flex-direction: column;
align-items: flex-end;
justify-content: center;
padding: 0 100px;
align-items: stretch;
.icon {
background: url(../../assets/images/logo.png) no-repeat 70px center / contain;
width: 300px;
height: 50px;
margin-bottom: 50px;
}
p {
color: #fff;
font-size: 18px;
margin-top: 20px;
width: 300px;
text-align: center;
.second_bg {
width: 100%;
height: 100%;
background: url(../../assets/images/bg2.png) 50% no-repeat;
background-size: cover;
}
}
.form {
flex: 2;
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
padding-left: 176px;
padding-left: 100px;
background-color: #fff;
h1 {
color: #A2A2A3;
letter-spacing: 16px;
font-weight: normal;
}
.el-card {
border: none;
padding: 0;

View File

@ -8,10 +8,11 @@
<div class="title">国际标准抑郁与焦虑自评量表</div>
<div class="content">
<el-card shadow="hover" style="max-width: 520px; margin-bottom: 10px;" v-for="item in scaleList"
:key="item.scaleId" @click="gotoExam(item)">
<el-card shadow="hover" style="max-width: 520px; margin-bottom: 10px; position: relative;"
v-for="item in scaleList" :key="item.scaleId" @click="gotoExam(item)">
<img :src="item.coverUrl" alt="">
<div class="title">{{ item.scaleName }}</div>
<div v-if="item.used" class="desc">已测评</div>
<template #footer>
<div class="footer">
<div>
@ -44,12 +45,17 @@ async function getScaleList() {
}
async function gotoExam(item) {
if(item.used) {
ElMessage.error('当前量表已测评,无法再测评!')
return
}
const res = await addRecordAPI({ scaleId: item.scaleId, batchNo })
router.push({
path: '/exam',
query: {
scaleId: item.scaleId,
scaleName: item.scaleName,
scaleTime: item.scaleTime,
recordId: res.data
}
})
@ -79,8 +85,7 @@ onMounted(() => {
}
.main {
width: 70%;
height: calc(100vh - 60px);
width: 1200px;
margin: 0 auto;
text-align: center;
@ -107,6 +112,13 @@ onMounted(() => {
margin-top: 10px;
}
.desc {
margin-top: 20px;
color: red;
font-size: 20px;
font-weight: bold;
}
.footer {
display: flex;
justify-content: space-between;