master
yujialong 4 years ago
parent 2904385193
commit 9c0ee6eb4a
  1. BIN
      src/assets/img/account.png
  2. BIN
      src/assets/img/ache.png
  3. BIN
      src/assets/img/download.png
  4. BIN
      src/assets/img/exam.png
  5. BIN
      src/assets/img/false.png
  6. BIN
      src/assets/img/home.png
  7. BIN
      src/assets/img/index/achievement.png
  8. BIN
      src/assets/img/index/assesment.png
  9. BIN
      src/assets/img/index/msg.png
  10. BIN
      src/assets/img/index/practice.png
  11. BIN
      src/assets/img/login_bg.png
  12. BIN
      src/assets/img/logo-full.png
  13. BIN
      src/assets/img/msg.png
  14. BIN
      src/assets/img/none.png
  15. BIN
      src/assets/img/password.png
  16. BIN
      src/assets/img/practise.png
  17. BIN
      src/assets/img/system-fullname.png
  18. BIN
      src/assets/img/system-name.png
  19. BIN
      src/assets/img/true.png
  20. BIN
      src/assets/img/upload.png
  21. BIN
      src/assets/img/wrong.png
  22. 30
      src/components/breadcrumb/index.vue
  23. 28
      src/layouts/footer/index.vue
  24. 95
      src/layouts/header/index.vue
  25. 51
      src/layouts/home/index.vue
  26. 171
      src/layouts/navbar/index.vue
  27. 13
      src/libs/util.js
  28. 135
      src/pages/account/login/index.vue
  29. 12
      src/pages/account/register/index.vue
  30. 36
      src/pages/achievement/assessment/index.vue
  31. 23
      src/pages/achievement/list/examResults.vue
  32. 24
      src/pages/achievement/list/index.vue
  33. 29
      src/pages/achievement/list/practiceResults.vue
  34. 38
      src/pages/achievement/practice/index.vue
  35. 1
      src/pages/exam/detail/index.vue
  36. 56
      src/pages/exam/do/index.vue
  37. 49
      src/pages/exam/list/index.vue
  38. 166
      src/pages/index/list/index.vue
  39. 83
      src/pages/messageBoard/list/index.vue
  40. 49
      src/pages/practice/do/index.vue
  41. 26
      src/pages/practice/list/index.vue
  42. 27
      src/pages/practice/list/myPractice.vue
  43. 31
      src/pages/practice/list/randomPractice.vue
  44. 39
      src/pages/practice/randomDo/index.vue
  45. 580
      src/pages/setting/person/index.vue
  46. 47
      src/pages/wrongBook/do/index.vue
  47. 89
      src/pages/wrongBook/list/index.vue
  48. 8
      src/plugins/requests/index.js
  49. 2
      src/setting.js
  50. 4
      src/store/modules/exam.js
  51. 2
      src/store/modules/practice.js
  52. 6
      src/store/modules/user.js
  53. 402
      src/styles/common.scss
  54. BIN
      src/styles/font/YouSheBiaoTiHei.ttf
  55. 3
      src/styles/layout/index.scss
  56. 108
      src/styles/pages/exam.scss
  57. 55
      src/styles/pages/messageBoard.scss
  58. 123
      src/styles/pages/testPaperDetail.scss
  59. 10
      vue.config.js

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 709 B

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 985 KiB

After

Width:  |  Height:  |  Size: 382 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 664 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 722 B

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

@ -0,0 +1,30 @@
<template>
<div class="breadcrumb">
<span class="cur">当前位置</span>
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">超竞学生端</el-breadcrumb-item>
<el-breadcrumb-item v-for="(item,index) in pages" :key="index" :to="{ path: index == pages.length - 1 ? curRoute : route }">{{item}}</el-breadcrumb-item>
</el-breadcrumb>
</div>
</template>
<script>
export default {
props: ['data','route'],
data() {
return {
pages: this.data.split('/'),
curRoute: this.$route.path
};
},
methods: {
update(data){
console.log(2222,data)
this.pages = data.split('/')
}
}
};
</script>
<style lang="scss" scoped>
</style>

@ -0,0 +1,28 @@
<template>
<div>
<div class="copyright">广州超竞教育投资有限公司版权所有</div>
</div>
</template>
<script>
export default {
data() {
return {
};
},
mounted(){
},
methods: {
},
};
</script>
<style lang="scss" scoped>
.copyright{
padding: 20px 0;
color: rgba(0, 0, 0, 0.45);
font-size: 12px;
text-align: center;
}
</style>

@ -1,18 +1,17 @@
<template>
<div class="header flex a-center j-between">
<div v-if="showBack" class="goBack" v-throttle @click="back"><i class="el-icon-arrow-left"></i>返回</div>
<div v-else class="logo">
<img src="../../assets/img/logo-fill.png">
</div>
<div class="header-right">
<div class="header-user-con">
<div class="user" @click="toPerson">
<div>
<div class="header">
<img class="system-name" src="../../assets/img/system-fullname.png">
<el-dropdown class="user-wrap" @command="userCommand">
<div class="user">
<el-avatar :size="40" :src="avatar"></el-avatar>
<span class="user-avator">{{userName}}</span>
</div>
<el-divider class="m-l-20" direction="vertical"></el-divider>
<el-button type="text" class="m-l-20" @click="loginout">退出</el-button>
<span class="username">{{userName}}</span>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="person">个人资料</el-dropdown-item>
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</template>
@ -42,79 +41,43 @@ export default {
...mapActions('user', [
'logout'
]),
toPerson(){
userCommand(command){
console.log(command)
if(command == 'person'){
this.$router.push('/setting/person')
},
loginout() {
}else{
this.logout()
},
back(){
this.$router.back()
}
}
},
};
</script>
<style lang="scss" scoped>
.goBack{
cursor: pointer;
line-height: 60px;
height: 60px;
font-size: 16px;
font-weight: bold;
margin-left: 20px;
i{
color: #cb221c;
font-size: 20px;
}
}
.header {
position: relative;
box-sizing: border-box;
width: 100%;
height: 60px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 40px 20px 24px;
font-size: 16px;
color: #333;
border-bottom: 1px solid #efefef;
box-shadow: 0 0 1.5625rem 0.125rem rgba(255, 45, 45, 0.14);
.logo {
float: left;
width: 170px;
height: 40px;
margin-left: 20px;
img{
height: 100%;
}
background-color: #fff;
box-sizing: border-box;
.system-name {
width: 326px;
}
.header-right {
float: right;
padding-right: 50px;
.header-user-con {
.user-wrap {
display: flex;
height: 70px;
align-items: center;
.user{
display: inline-flex;
align-items: center;
cursor: pointer;
}
}
.el-button--text{
color: #333;
}
.el-divider--vertical{
width: 2px;
height: 15px;
}
.el-divider{
background-color: #333;
}
.user-avator {
.username{
margin-left: 10px;
img {
display: block;
width: 40px;
height: 40px;
border-radius: 50%;
color: #000;
font-size: 16px;
}
}
}

@ -1,29 +1,27 @@
<template>
<div class="wrapper">
<div class="placeholder" :class="{mini: !hideNavbar}"></div>
<div class="fixed">
<div class="main">
<v-navbar class="nav"></v-navbar>
<div class="layout">
<v-head></v-head>
<v-navbar v-show="hideNavbar"></v-navbar>
</div>
<div class="content-box" :class="{'content-collapse':collapse}">
<div class="content">
<transition name="move" mode="out-in">
<keep-alive :include="tagsList">
<router-view></router-view>
<router-view class="view"></router-view>
</keep-alive>
</transition>
<el-backtop target=".content"></el-backtop>
<v-footer ref="footer"></v-footer>
</div>
</div>
</div>
</template>
<script>
import vHead from '../header/index.vue';
import vNavbar from '../navbar/index.vue';
import vTags from '../tags/index.vue';
import bus from '@/libs/bus';
import Setting from '@/setting';
import vHead from '../header/index.vue'
import vNavbar from '../navbar/index.vue'
import vFooter from '../footer'
import bus from '@/libs/bus'
import Setting from '@/setting'
export default {
data() {
return {
@ -35,7 +33,7 @@ export default {
components: {
vHead,
vNavbar,
vTags
vFooter
},
computed: {
hideNavbar() {
@ -61,17 +59,24 @@ export default {
};
</script>
<style lang="scss" scoped>
.fixed{
z-index: 10;
position: fixed;
top: 0;
width: 100%;
background-color: #fff;
.main{
display: flex;
min-width: 1300px;
height: 100%;
overflow: hidden;
.nav{
width: 220px;
}
.layout{
width: calc(100% - 220px);
.content{
height: calc(100vh - 80px);
padding: 24px 24px 0;
overflow: auto;
.view{
min-height: calc(100% - 60px);
}
}
.placeholder{
height: 120px;
&.mini{
height: 60px;
}
}
</style>

@ -1,70 +1,193 @@
<template>
<div class="header_tab" v-show="hideSidebar">
<el-tabs v-model="activeName" @tab-click="tabChange">
<el-tab-pane v-for="(tab,index) in tabList" :key="index" :label="tab.title" :name="tab.index"></el-tab-pane>
</el-tabs>
<div>
<div class="logo">
<img src="../../assets/img/logo-full.png" width="125">
</div>
<el-menu
class="sidebar-el-menu"
:default-active="onRoutes"
:collapse="collapse"
background-color="#141414"
text-color="#fff"
active-text-color="#fff"
unique-opened
router
>
<template v-for="item in menus">
<template v-if="item.subs">
<el-submenu :index="item.index" :key="item.index">
<template slot="title">
<i :class="item.icon"></i>
<span slot="title">{{ item.title }}</span>
</template>
<template v-for="subItem in item.subs">
<el-submenu
v-if="subItem.subs"
:index="subItem.index"
:key="subItem.index"
>
<template slot="title">{{ subItem.title }}</template>
<el-menu-item
v-for="(threeItem,i) in subItem.subs"
:key="i"
:index="threeItem.index"
>{{ threeItem.title }}</el-menu-item>
</el-submenu>
<el-menu-item
v-else
:index="subItem.index"
:key="subItem.index"
>{{ subItem.title }}</el-menu-item>
</template>
</el-submenu>
</template>
<template v-else>
<el-menu-item :index="item.index" :key="item.index">
<i :class="item.icon"></i>
<span slot="title">{{ item.title }}</span>
</el-menu-item>
</template>
</template>
</el-menu>
</div>
</template>
<script>
import { mapState } from 'vuex'
import bus from '@/libs/bus';
import Setting from '@/setting';
export default {
data() {
return {
activeName: this.$route.path,
tabList: [
collapse: false,
defaultMenus: [
{
icon: 'el-icon-folder-checked',
icon: 'menu-icon icon-index',
index: '/index/list',
title: '我的首页'
},
{
icon: 'el-icon-lx-home',
icon: 'menu-icon icon-practise',
index: '/practice/list',
title: '我的练习'
},
{
icon: 'el-icon-lx-cascades',
icon: 'menu-icon icon-exam',
index: '/exam/list',
title: '我的考试'
},
{
icon: 'el-icon-lx-copy',
icon: 'menu-icon icon-ache',
index: '/achievement/list',
title: '我的成绩'
},
{
icon: 'el-icon-lx-copy',
icon: 'menu-icon icon-wrong',
index: '/wrongBook/list',
title: '错题练习'
},
{
icon: 'el-icon-chat-dot-round',
icon: 'menu-icon icon-msg',
index: '/messageBoard/list',
title: '交流互动'
}
],
hideNavList: ['article','matchDetail','courseSection','personalCenter']
menus: [],
actives: {
index: ['index-add'],
}
};
},
computed: {
hideSidebar() {
let route = this.$route.name
if(this.hideNavList.includes(route)) return false
return true
onRoutes() {
let actives = this.actives
for(let i in this.actives){
if(actives[i].includes(this.$route.name)) return `/${i}`
}
return this.$route.path
},
methods: {
tabChange(tab){
location.hash = tab.name
this.$router.push(tab.name)
...mapState('auth', [
'routes'
])
},
created() {
this.initMenu()
// Event Bus
bus.$on('collapse', msg => {
this.collapse = msg;
bus.$emit('collapse-content', msg);
});
},
methods: {
initMenu(){
if(Setting.dynamicRoute){
let routes = this.routes
let menus = []
this.defaultMenus.map(e => {
routes.find(n => n.path == e.index) && menus.push(e)
})
this.menus = menus
this.active = menus[0].index
}else{
this.menus = this.defaultMenus
}
}
}
};
</script>
<style lang="scss" scoped>
/deep/.el-tabs__item:focus{
outline: none;
box-shadow: none !important;
.nav{
height: 100%;
background-color: #141414;
overflow: auto;
.logo{
padding: 20px 0;
text-align: center;
}
/deep/.el-menu{
border-right: 0 !important;
.el-menu-item{
display: flex;
align-items: center;
&.is-active{
background-color: #CC221C !important;
}
.menu-icon{
width: 24px;
height: 24px;
margin-right: 12px;
background: url(../../assets/img/home.png) no-repeat;
&.icon-practise{
background-image: url(../../assets/img/practise.png);
}
&.icon-exam{
background-image: url(../../assets/img/exam.png);
}
&.icon-ache{
background-image: url(../../assets/img/ache.png);
}
&.icon-wrong{
background-image: url(../../assets/img/wrong.png);
}
&.icon-msg{
background-image: url(../../assets/img/msg.png);
}
}
span{
font-size: 15px;
}
}
}
}
.sidebar::-webkit-scrollbar {
width: 0;
}
.sidebar-el-menu:not(.el-menu--collapse) {
width: 100%;
}
.sidebar > ul {
height: 100%;
}
</style>

@ -1,5 +1,6 @@
import cookies from './util.cookies'
import {_local,_session} from './util.db'
import { Message } from 'element-ui'
const util = {
cookies,
@ -103,6 +104,18 @@ const util = {
}
x.send()
},
// 成功提示
successMsg(message) {
Message.success({message,showClose: true,offset: (document.documentElement.clientHeight - 40) / 2,duration: 1500})
},
// 警告提示
warningMsg(message) {
Message.warning({message,showClose: true,offset: (document.documentElement.clientHeight - 40) / 2,duration: 1500})
},
// 错误提示
errorMsg(message) {
Message.error({message,showClose: true,offset: (document.documentElement.clientHeight - 40) / 2,duration: 1500})
},
}
export default util

@ -1,53 +1,23 @@
<template>
<div class="wrap">
<div class="header">
<div class="inner">
<img class="logo" src="../../../assets/img/logo.png" alt="">
<!-- <div class="reg" @click="toReg">注册</div> -->
</div>
</div>
<div class="main">
<div class="left">
<div class="text">
<p>欢迎进入</p>
<p>电子竞技<br>数字化考试系统<br><span>学生用户端</span></p>
</div>
<img class="logo" src="../../../assets/img/logo-full.png" alt="">
<img class="name" src="../../../assets/img/system-name.png" alt="">
</div>
<div class="right">
<div>
<div v-if="!isReg">
<h2>密码登录</h2>
<el-form :model="loginForm" :rules="loginRules" ref="login" label-width="0px">
<el-form-item prop="username">
<p class="label">用户名</p>
<label class="account"></label>
<el-input v-model="loginForm.username" placeholder="请输入账号/手机号" @keyup.enter.native="submitForm()"></el-input>
</el-form-item>
<el-form-item prop="password">
<p class="label">密码</p>
<el-input
type="password"
placeholder="请输入密码"
v-model="loginForm.password"
@keyup.enter.native="submitForm()"
>
</el-input>
<label class="password"></label>
<el-input type="password" placeholder="请输入密码" v-model="loginForm.password" @keyup.enter.native="submitForm()"></el-input>
</el-form-item>
<el-button class="submit" type="primary" @click="submitForm">登录</el-button>
<!-- <div class="links flex j-between">
<el-button type="text" class="ques" @click="toReg">前往注册</el-button>
<el-button type="text" class="forget">忘记密码</el-button>
</div> -->
<!-- <p class="login-tips">其他登陆方式</p>
<div class="thirdParty">
<div class="item">
<img src="../../../assets/img/icon_wechat.png" alt="">
微信扫码登录
</div>
<div class="item">
<img src="../../../assets/img/icon_qq.png" alt="">
QQ一键登录
</div>
</div> -->
</el-form>
</div>
<register v-else :isReg.sync="isReg" @updateInfo="updateInfo"></register>
@ -57,8 +27,8 @@
</template>
<script>
import register from '../register';
import { mapActions } from 'vuex';
import register from '../register'
import { mapActions } from 'vuex'
export default {
data: function() {
return {
@ -112,83 +82,38 @@ export default {
</script>
<style scoped lang="scss">
.header{
.wrap {
position: relative;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(51,51,51,.7);
.inner{
display: inline-flex;
justify-content: space-between;
align-items: center;
width: 65%;
padding: 5px 0;
font-size: 16px;
color: #fff;
.logo{
width: 200px;
}
.reg{
cursor: pointer;
}
}
}
.wrap {
position: relative;
width: 100%;
height: 100%;
background: url(../../../assets/img/login_bg.png) 0 0/100% 100% no-repeat;
overflow: hidden;
.mask{
z-index: -1;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: rgba(0,0,0,1);
}
.main{
height: calc(100% - 60px);
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(0,0,0,.4);
}
.left{
margin-top: -200px;
margin-right: 10%;
margin-right: 200px;
img{
width: 447px;;
margin-bottom: 30px;
}
.text{
font-size: 52px;
color: #fff;
p:first-child{
margin-bottom: 30px;
display: block;
}
span{
font-size: 36px;
.logo{
max-width: 242px;
margin-bottom: 60px;
}
.name{
max-width: 663px;
}
}
.right{
width: 580px;
padding: 40px 70px 50px;
background-color: #fff;
box-sizing: border-box;
box-shadow: 0 1px 20px rgba(0,0,0,0.16);
border-radius: 16px;
h2{
padding-bottom: 10px;
font-size: 24px;
font-weight: 400;
color: #303d4c;
color: #000;
text-align: center;
border-bottom: 1px solid #E5E5E5;
}
.el-form{
margin-top: 30px;
@ -197,11 +122,25 @@ export default {
color: #105CB2;
}
/deep/.el-input__inner{
position: relative;
width: 320px;
height: 46px;
padding: 0 23px;
padding: 0 20px 0 40px;
line-height: 46px;
border: 1px solid #AFB5BB;
border-radius: 23px !important;
border: 1px solid #E6E6E6;
border-radius: 8px !important;
}
.account,.password{
z-index: 10;
position: absolute;
top: 11px;
left: 12px;
width: 24px;
height: 24px;
background: url(../../../assets/img/account.png) 0 0/100% 100% no-repeat;
}
.password{
background-image: url(../../../assets/img/password.png);
}
/deep/.el-form-item__error{
top: 105%;
@ -212,7 +151,7 @@ export default {
.submit{
width: 100%;
height: 48px;
margin-top: 60px;
margin-top: 30px;
line-height: 48px;
padding: 0;
font-size: 20px;

@ -154,9 +154,9 @@ export default {
registerForm() {
this.$refs.reg.validate(valid => {
if (valid) {
if(this.phoneRepeat) return this.$message.warning('该手机号已存在')
if(this.workNumberReapeat) return this.$message.warning('该学生学号已存在')
if(this.regForm.password !== this.regForm.rePassword) return this.$message.warning('两次输入的密码不一致,请重新输入')
if(this.phoneRepeat) return util.warningMsg('该手机号已存在')
if(this.workNumberReapeat) return util.warningMsg('该学生学号已存在')
if(this.regForm.password !== this.regForm.rePassword) return util.warningMsg('两次输入的密码不一致,请重新输入')
let data = this.regForm
data.clientName = this.schoolList.find(n => n.id == this.regForm.clientId).clientName
@ -165,12 +165,12 @@ export default {
data.creationTime = this.core.formatDate("yyyy-MM-dd hh:mm:ss",new Date())
this.$post(this.api.save,data).then(res => {
if(res.success){
this.$message.success('注册成功')
util.successMsg('注册成功')
this.$emit('update:isReg',false)
this.$emit('updateInfo',{username: this.regForm.phone,password: this.regForm.password})
this.$refs.reg.resetFields()
}else{
this.$message.error('注册失败');
util.errorMsg('注册失败');
}
}).catch(res => {});
}
@ -179,7 +179,7 @@ export default {
async phoneChange(){
let res = await this.$get(this.api.queryPhone, { phone: this.regForm.phone });
if(res.message.length != 0){
this.$message.warning('该手机号已存在');
util.warningMsg('该手机号已存在');
this.phoneRepeat = true
}else{
this.phoneRepeat = false

@ -1,5 +1,8 @@
<template>
<div class="box">
<breadcrumb :data="'我的成绩/考试成绩'"></breadcrumb>
<div class="page">
<div class="page-content">
<h1 class="title">{{paperName }}</h1>
<div class="metas">
<div class="m-r-20">
@ -28,16 +31,11 @@
<div class="wrap">
<div class="item" v-for="(item,index) in curType" :key="index">
<div class="answer">
<div class="info">
<p class="key">序号</p>
<p class="val">{{index+1}}</p>
</div>
<div class="info">
<p class="key">得分</p>
<p class="val">{{item.question_score}}</p>
</div>
<div class="type" :class="{wrong: item.question_score == 0,yet: item.question_score == null}">
<span>序号{{index+1}}</span>
<span v-if="item.question_score != null">得分{{item.question_score}}</span>
</div>
<div class="inner">
<div class="meta">
<p class="key">题干</p>
<p class="val" v-html="item.question_stem"></p>
@ -48,8 +46,8 @@
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p>
</div>
</div>
<div class="meta ans">
<div class="info">
<div class="meta-mul">
<div class="info" v-if="active != 4">
<p class="key">正确答案</p>
<p class="val">{{item.answer}}</p>
</div>
@ -81,6 +79,7 @@
</div>
</div>
</div>
</div>
<div v-show="playAuth" class="el-image-viewer__wrapper" :class="{over: isDownload}" style="z-index: 2000">
<div class="el-image-viewer__mask"></div>
@ -91,14 +90,17 @@
<a ref="videoLink" style="display: none;" crossOrigin="anonymous" download="用户上传视频.mp4" :href="videoSrc">下载</a>
<a ref="picLink" style="display: none;" crossOrigin="anonymous" download="用户上传图片.jpg" :href="imgSrc">下载</a>
</div>
</div>
</div>
</template>
<script>
import setBackground from '@/mixins/setBackground'
import file from '@/mixins/file'
import { mapState } from 'vuex'
import pdf from '@/components/pdf'
import breadcrumb from '@/components/breadcrumb'
import util from '@/libs/util'
export default {
mixins: [ setBackground,file ],
mixins: [ file ],
data() {
return {
paperName: '',
@ -131,7 +133,7 @@ export default {
curType: []
};
},
components: { pdf },
components: { pdf,breadcrumb },
computed: {
...mapState('user', [
'userId'
@ -184,10 +186,16 @@ export default {
curType.forEach(n => {
if(!n.options){
let options = {}
let answer = []
for(let i in n){
if(i.includes('option') && n[i]){
options[i.replace('option_','')] = n[i]
if(n.typeName == '填空题') answer.push(n[i])
}
}
if(n.typeName == '填空题'){
n.answer = answer.join(',')
n.user_answer = n.user_answer ? n.user_answer.split('&lt;&gt;').filter(n => n).join(',') : ''
}
n.options = options
}

@ -1,19 +1,16 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div>
<div class="p-title m-b-20">筛选</div>
<div class="flex">
<div>
<el-input placeholder="请输入考核名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</div>
</div>
<div class="tool">
<ul class="filter">
<li>
<label>搜索</label>
<el-input placeholder="请输入考核名称" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
</div>
</el-card>
<el-card shadow="hover">
<el-table :data="listData" class="table" ref="table" stripe header-align="center" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center">
<template slot-scope="scope">
{{scope.$index + (page - 1) * pageSize + 1}}
@ -33,7 +30,7 @@
</el-table-column>
<el-table-column label="操作" align="center" width="180">
<template slot-scope="scope">
<el-button type="text" @click="show(scope.row)">查看详情</el-button>
<el-button type="text" @click="show(scope.row)">查看答卷</el-button>
</template>
</el-table-column>
</el-table>
@ -41,12 +38,12 @@
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" :current-page="page">
</el-pagination>
</div>
</el-card>
</div>
</template>
<script>
import { mapState,mapActions } from 'vuex'
import util from '@/libs/util'
export default {
data() {
return {

@ -1,35 +1,41 @@
<template>
<div class="box">
<div>
<breadcrumb :data="'我的成绩/' + tabs[active]" ref="breadcrumb"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == activeName}" @click="tabChange(index)">{{item}}</a>
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{item}}</a>
</div>
<practice-results v-if="activeName == 'first'"></practice-results>
<div class="page-content">
<practice-results v-if="active == 'first'"></practice-results>
<exam-results v-else></exam-results>
</div>
</div>
</div>
</template>
<script>
import practiceResults from './practiceResults.vue';
import examResults from './examResults.vue';
import practiceResults from './practiceResults.vue'
import examResults from './examResults.vue'
import breadcrumb from '@/components/breadcrumb'
export default {
name: 'index',
data() {
return {
activeName: 'first',
active: 'first',
tabs: {
first: '练习成绩',
second: '考试成绩'
}
};
},
components: {practiceResults,examResults},
components: {practiceResults,examResults,breadcrumb},
mounted() {
},
methods: {
tabChange(index){
this.activeName = index
this.active = index
this.$refs.breadcrumb.update('我的成绩/' + this.tabs[this.active])
}
}
};

@ -1,20 +1,16 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div>
<div class="p-title m-b-20">筛选</div>
<div class="flex">
<div>
<el-input placeholder="请输入练习名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</div>
</div>
<div class="tool">
<ul class="filter">
<li>
<label>搜索</label>
<el-input placeholder="请输入练习名称" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
</div>
</el-card>
<el-card shadow="hover">
<el-table :data="listData" class="table" ref="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center">
<template slot-scope="scope">
{{scope.$index + (page - 1) * pageSize + 1}}
@ -39,20 +35,19 @@
</el-table-column>
<el-table-column label="操作" align="center" width="180">
<template slot-scope="scope">
<el-button v-if="scope.row.practiseId" type="text" @click="show(scope.row)">查看详情</el-button>
<el-button v-if="scope.row.practiseId" type="text" @click="show(scope.row)">查看答卷</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" :current-page="page">
</el-pagination>
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" :current-page="page"></el-pagination>
</div>
</el-card>
</div>
</template>
<script>
import { mapState,mapActions } from 'vuex'
import util from '@/libs/util'
export default {
data() {
return {
@ -100,7 +95,7 @@ export default {
})
.then(() => {
this.$del(`${this.api.deleteCourse}/${row.id}`).then(res => {
this.$message.success('删除成功')
util.successMsg('删除成功')
this.getData()
}).catch(res => {})
}).catch(() => {})

@ -1,5 +1,8 @@
<template>
<div class="box">
<breadcrumb :data="'我的成绩/练习成绩'"></breadcrumb>
<div class="page">
<div class="page-content">
<h1 class="title">{{paperName }}</h1>
<div class="metas">
<div class="m-r-20">
@ -24,16 +27,11 @@
<div class="wrap">
<div class="item" v-for="(item,index) in curType" :key="index">
<div class="answer">
<div class="info">
<p class="key">序号</p>
<p class="val">{{index+1}}</p>
</div>
<div class="info">
<p class="key">得分</p>
<p class="val">{{item.questionScore}}</p>
</div>
<div class="type" :class="{wrong: item.questionScore == 0,yet: !item.isCorrecting}">
<span>序号{{index+1}}</span>
<span v-if="item.isCorrecting">得分{{item.questionScore}}</span>
</div>
<div class="inner">
<div class="meta">
<p class="key">题干</p>
<p class="val" v-html="item.questionStem"></p>
@ -44,8 +42,8 @@
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p>
</div>
</div>
<div class="meta ans">
<div class="info">
<div class="meta-mul">
<div class="info" v-if="active != 4">
<p class="key">正确答案</p>
<p class="val">{{item.answer}}</p>
</div>
@ -77,6 +75,7 @@
</div>
</div>
</div>
</div>
<div v-show="playAuth" class="el-image-viewer__wrapper" :class="{over: isDownload}" style="z-index: 2000">
<div class="el-image-viewer__mask"></div>
@ -85,14 +84,17 @@
</div>
<pdf :visible.sync="pdfVisible" :src.sync="pdfSrc"></pdf>
</div>
</div>
</div>
</template>
<script>
import setBackground from '@/mixins/setBackground'
import file from '@/mixins/file'
import { mapState } from 'vuex'
import pdf from '@/components/pdf'
import breadcrumb from '@/components/breadcrumb'
import util from '@/libs/util'
export default {
mixins: [ setBackground,file ],
mixins: [ file ],
data() {
return {
paperName: '',
@ -128,7 +130,7 @@ export default {
curType: []
};
},
components: { pdf },
components: { pdf,breadcrumb },
computed: {
...mapState('user', [
'userId'
@ -151,10 +153,10 @@ export default {
if(n.typeName == '填空题'){
let answer = []
for(let i in n){
if(i.includes('option')) answer.push(n[i])
if(i.includes('option') && n[i]) answer.push(n[i])
}
n.answer = answer.join('|')
n.userAnswer = n.userAnswer ? n.userAnswer.replace(/&lt;&gt;/g,'|') : ''
n.answer = answer.join('')
n.userAnswer = n.userAnswer ? n.userAnswer.split('&lt;&gt;').filter(n => n).join(',') : ''
}
if(n.fileUrl) n.fileUrl = JSON.parse(n.fileUrl)
if(n.videoAudio) n.videoAudio = JSON.parse(n.videoAudio)
@ -199,7 +201,7 @@ export default {
if(n.typeName == '填空题') answer.push(n[i])
}
}
if(n.typeName == '填空题') n.answer = answer.join('|')
if(n.typeName == '填空题') n.answer = answer.join('')
n.options = options
}
})

@ -65,6 +65,7 @@
<script>
import mixins from '@/mixins/setBackground'
import { mapState } from 'vuex'
import util from '@/libs/util'
export default {
mixins: [ mixins ],
data() {

@ -1,39 +1,41 @@
<template>
<div>
<breadcrumb :data="'我的考试/考试'"></breadcrumb>
<div class="box">
<div class="left">
<p class="title">答题卡</p>
<div class="page left">
<p class="title">{{assessmentName}}</p>
<p class="time" v-countdown="time">{{time}}</p>
<div class="progress">
<div class="ans">答题进度({{progress}}%)</div>
<el-progress :percentage="progress" :show-text="false"></el-progress>
</div>
<div>
<div class="item">
<p class="type">单选题</p>
<p class="total">{{singleCount}}合计{{singlePoint}}</p>
<p class="type">单选题({{singleCount}}合计{{singlePoint}})</p>
<div class="nums">
<span v-for="n in singleCount" :class="{active: n <= singleAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="item">
<p class="type">多选题</p>
<p class="total">{{multipleCount}}合计{{multipleChoiceScore}}</p>
<p class="type">多选题({{multipleCount}}合计{{multipleChoiceScore}})</p>
<div class="nums">
<span v-for="n in multipleCount" :class="{active: n <= multipleAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="item">
<p class="type">判断题</p>
<p class="total">{{judgeCount}}合计{{judgeScore}}</p>
<p class="type">判断题({{judgeCount}}合计{{judgeScore}})</p>
<div class="nums">
<span v-for="n in judgeCount" :class="{active: n <= judgeAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="item">
<p class="type">填空题</p>
<p class="total">{{fillBlankCount}}合计{{fillBlanksScore}}</p>
<p class="type">填空题({{fillBlankCount}}合计{{fillBlanksScore}})</p>
<div class="nums">
<span v-for="n in fillBlankCount" :class="{active: n <= fillBlankAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="item">
<p class="type">简答题</p>
<p class="total">{{briefAnswerCount}}合计{{briefAnswerScore}}</p>
<p class="type">简答题({{briefAnswerCount}}合计{{briefAnswerScore}})</p>
<div class="nums">
<span v-for="n in briefAnswerCount" :class="{active: n <= briefAnswerAnsweredCount}" :key="n">{{n}}</span>
</div>
@ -42,13 +44,14 @@
<el-button size="mini" type="primary" @click="save">提交考试</el-button>
</div>
</div>
</div>
<div class="middle">
<div class="ques">
<div class="page right">
<template v-for="(subject,k) in subjects">
<div class="item" v-if="subject.length" :key="k">
<p v-if="subjects[k].length" class="title">{{questionType[k]}}{{subjects[k].length}}合计{{scoreList[k]}}</p>
<div class="ques-wrap" v-for="(item,index) in subject" :key="index">
<div class="ques-wrap">
<div class="ques" v-for="(item,index) in subject" :key="index">
<div class="name-wrap">
<span class="index">{{index+1}}.</span>
<div class="name" :class="'stem' + k + index" v-html="item.questionStem"></div>
@ -89,25 +92,19 @@
</div>
</div>
</div>
</template>
</div>
</template>
</div>
<div class="right">
<p class="title">剩余时间</p>
<p class="time" v-countdown="time">{{time}}</p>
<div class="ans">答题进度</div>
<el-progress :percentage="progress"></el-progress>
</div>
</div>
</template>
<script>
import { mapState,mapGetters,mapActions } from 'vuex'
import setBackground from '@/mixins/setBackground'
import examDo from '@/mixins/examDo'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default {
mixins: [ setBackground,examDo ],
mixins: [ examDo ],
data() {
return {
subjects: [],
@ -141,12 +138,13 @@ export default {
submiting: false
};
},
components: {breadcrumb},
computed: {
...mapState('user', [
'userId'
]),
...mapState('exam', [
'testPaperId','assessmentId','teacherId','classId','countdown'
'testPaperId','assessmentId','teacherId','classId','countdown','assessmentName'
]),
},
directives: {
@ -307,7 +305,7 @@ export default {
}
})
.catch(err => {
this.$message.success('考试结束!')
util.successMsg('考试结束!')
this.$router.back()
})
},1000)
@ -320,7 +318,7 @@ export default {
if(n.uploading) uploading = true
})
})
if(uploading) return this.$message.warning('视频正在上传,请稍候再试')
if(uploading) return util.warningMsg('视频正在上传,请稍候再试')
if(this.submiting) return false
this.submiting = true
let data1 = []
@ -373,7 +371,7 @@ export default {
this.$post(`${this.api.calculationScore}`,data1)
.then(res => {
this.isSubmit = true
this.$message.success(this.isDone ? '考试已结束,已经自动为您提交考试!' : '提交成功')
util.successMsg(this.isDone ? '考试已结束,已经自动为您提交考试!' : '提交成功')
this.$router.back()
})
.catch(err => {})

@ -1,34 +1,35 @@
<template>
<div class="box">
<el-card shadow="hover" class="m-b-20">
<div>
<div class="p-title m-b-20">筛选</div>
<div class="flex j-between">
<el-form label-width="80px">
<el-form-item class="no-mb" label="考试类型">
<el-select v-model="type" clearable placeholder="请选择考试类型" @change="getData">
<breadcrumb :data="'我的考试/考试列表'"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item active">考试列表</a>
</div>
<div class="page-content">
<div class="tool">
<ul class="filter">
<li>
<label>考试类型</label>
<el-select v-model="type" clearable placeholder="请选择考试类型" size="small" @change="getData">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in typeList" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-form>
<div>
<el-input placeholder="请输入考试名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</div>
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入考试名称" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
</div>
</div>
</el-card>
<el-card shadow="hover">
<el-table :data="listData" class="table" ref="table" stripe header-align="center" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center">
<template slot-scope="scope">
{{scope.$index + (page - 1) * pageSize + 1}}
</template>
</el-table-column>
<el-table-column prop="assessmentName" label="考名称" align="center"></el-table-column>
<el-table-column prop="assessmentName" label="考名称" align="center"></el-table-column>
<el-table-column prop="courses" label="所属课程" align="center"></el-table-column>
<el-table-column prop="name" label="难易程度" align="center">
<template slot-scope="scope">
@ -56,7 +57,7 @@
<template slot-scope="scope">
<!-- 学生考试状态:考试状态 state: (0未考 1在考 2已考)
考核状态: state: 考核状态(1待开始 2进行中 3已结束) -->
<el-button type="text" @click="toExam(scope.row)" v-if="scope.row.assessmentState == 2" :disabled="scope.row.state == 2">进入考试</el-button>
<el-button type="text" @click="toExam(scope.row)" v-if="scope.row.assessmentState == 2" :disabled="scope.row.state == 2">{{scope.row.state == 2 ? '已经交卷' : '进入考试'}}</el-button>
<!-- <el-button type="text" @click="query(scope.row)" v-if="scope.row.state == 2">成绩查询</el-button> -->
</template>
</el-table-column>
@ -65,13 +66,15 @@
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" :current-page="page">
</el-pagination>
</div>
</el-card>
</div>
</div>
</div>
</template>
<script>
import { mapState,mapGetters,mapActions } from 'vuex'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default {
data() {
return {
@ -97,6 +100,9 @@ export default {
'getDegreeName','getTypeName','getAssessmentStateName'
])
},
components: {
breadcrumb
},
filters: {
transferScore(val){
return val !== 0 ? val : '--'
@ -144,7 +150,8 @@ export default {
assessmentId: row.assessmentId,
teacherId: row.teacherId,
classId: row.classId,
countdown: time
countdown: time,
assessmentName: row.assessmentName
})
this.$router.push('do')
},

@ -1,23 +1,22 @@
<template>
<div>
<el-card shadow="hover" class="m-b-10">
<div class="title m-b-20"><img src="../../../assets/img/index/assesment.png" alt=""> 我的考试安排</div>
<div>
<el-date-picker v-model="date" align="right" unlink-panels type="daterange" start-placeholder="开始日期" end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" clearable></el-date-picker>
<breadcrumb :data="'我的首页'"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item active">考试日历</a>
</div>
<div class="page-content">
<template v-if="listData.length">
<div class="tool">
<ul class="filter">
<li>
<label>创建时间</label>
<el-date-picker v-model="date" align="right" unlink-panels type="daterange" start-placeholder="开始日期" end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" clearable size="small"></el-date-picker>
</li>
</ul>
</div>
</el-card>
<el-card shadow="hover" class="m-b-30">
<div class="text-center text-grey m-b-10">待考试列表</div>
<el-table
:data="listData"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
>
<el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center">
<el-table-column type="index" width="100" label="序号" align="center">
<template
slot-scope="scope"
@ -33,33 +32,21 @@
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
background
@current-change="handleCurrentChange"
:current-page="page"
:page-size="pageSize"
layout="total,prev, pager, next"
:total="total"
></el-pagination>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</template>
<div class="none" v-else>暂无考试安排</div>
</div>
</div>
</el-card>
<el-card shadow="hover" class="m-b-10">
<div class="title"><img src="../../../assets/img/index/practice.png" alt=""> 我的练习</div>
</el-card>
<div class="flex m-b-30">
<el-card shadow="hover" class="flex-1 m-r-20">
<div class="text-center text-grey m-b-10">平均分 {{avgScore}}&emsp;&emsp;总时长 {{totalDuration}}h</div>
<el-table
:data="practiceData"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
>
<div class="page">
<div class="tabs">
<a class="item active">我的练习</a>
</div>
<div class="stat-text" v-if="practiceData.length">平均分 {{avgScore}}总时长 {{totalDuration}}h</div>
<div class="page-content">
<template v-if="practiceData.length">
<el-table :data="practiceData" ref="table" row-key="id" class="table" stripe header-align="center">
<el-table-column type="index" width="100" label="序号" align="center">
<template
slot-scope="scope"
@ -83,50 +70,58 @@
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
background
@current-change="handlePracticeCurrentChange"
:current-page="pagePractice"
:page-size="pageSizePractice"
layout="total,prev, pager, next"
:total="totalPractice"
></el-pagination>
<el-pagination background @current-change="handlePracticeCurrentChange" :current-page="pagePractice" :page-size="pageSizePractice" layout="total,prev, pager, next" :total="totalPractice"></el-pagination>
</div>
</template>
<div class="none" v-else>暂无练习安排</div>
</div>
</div>
</el-card>
<el-card shadow="hover" class="flex-1">
<div class="flex j-between">
<div class="page" style="width: calc(50% - 12px)">
<div class="tabs">
<a class="item active">练习时长</a>
</div>
<div class="page-content">
<!-- <template v-if="practiceDurationList.length"> -->
<div class="chart" id="practiceDuration"></div>
</el-card>
<!-- </template>
<div class="none" v-else>暂无图标数据</div> -->
</div>
<el-card shadow="hover" class="m-b-10">
<div class="title"><img src="../../../assets/img/index/achievement.png" alt=""> 我的成绩</div>
</el-card>
<el-card shadow="hover" class="m-b-30">
</div>
<div class="page" style="width: calc(50% - 12px)">
<div class="tabs">
<a class="item active">我的成绩</a>
</div>
<div class="page-content">
<template v-if="assesmentNameList.length">
<div class="chart" id="achievement"></div>
</el-card>
</template>
<div class="none" style="padding: 0;line-height: 400px;" v-else>暂无图标数据</div>
</div>
</div>
</div>
<el-card shadow="hover" class="m-b-10">
<div class="title"><img src="../../../assets/img/index/msg.png" alt=""> 回复反馈</div>
</el-card>
<el-card shadow="hover">
<div class="page">
<div class="tabs">
<a class="item active">教师回复</a>
</div>
<div class="page-content">
<template v-if="msgList.length">
<ul class="list">
<li v-for="(item,index) in msgList" :key="index">
<div class="item">
<div class="inner">
<img class="avatar" :src="item.userAvatars" alt="">
<div class="texts">
<div class="title">
<span class="username">{{item.userName}}</span>
<span class="publish">发表于</span>
<span class="date">{{item.createTime}}</span>
</div>
<div class="userName">{{item.userName}}</div>
<div class="desc" v-html="item.content"></div>
</div>
<div class="date">{{item.createTime}}</div>
</div>
<div class="action">
<button v-if="item.userId != userId" class="btn" @click="showReply(item)">回复</button>
<button v-else class="btn" @click="delMsg(item)">删除</button>
<button v-else class="btn del" @click="delMsg(item)">删除</button>
</div>
</div>
<div class="reply" v-if="item.showReply">
<quill :border="true" v-model="item.replyContent" :toTop="false" :height="150" />
@ -137,7 +132,10 @@
</div>
</li>
</ul>
</el-card>
</template>
<div class="none" v-else>暂无教师回复</div>
</div>
</div>
</div>
</template>
<script>
@ -145,6 +143,7 @@ import { mapState,mapGetters,mapActions } from 'vuex'
import quill from '@/components/quill'
import echarts from 'echarts'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default {
data() {
return {
@ -190,7 +189,8 @@ export default {
}
},
components: {
quill
quill,
breadcrumb
},
mounted() {
let now = util.formatDate('yyyy-MM-dd')
@ -331,7 +331,7 @@ export default {
},
delMsg(row){
this.$post(`${this.api.waitReplyDel}?userId=${this.userId}&bid=${row.bid}`).then(res => {
this.$message.success('删除成功')
util.successMsg('删除成功')
this.getMsg()
}).catch(res => {})
},
@ -343,7 +343,7 @@ export default {
schoolId: this.clientId,
}
this.$post(this.api.saveComment,data).then(res => {
this.$message.success('提交成功')
util.successMsg('提交成功')
row.replyContent = ''
this.getMsg()
}).catch(res => {})
@ -368,4 +368,24 @@ export default {
.chart{
height: 400px;
}
.page{
margin-bottom: 24px;
.none{
padding: 36px 0;
text-align: center;
color: rgba(0, 0, 0, 0.25);
font-size: 18px;
}
.stat-text{
position: absolute;
top: 0;
left: 0;
width: 100%;
padding: 20px 0;
text-align: center;
color: rgba(0, 0, 0, 0.85);
font-size: 16px;
font-weight: 500;
}
}
</style>

@ -1,26 +1,26 @@
<template>
<div>
<el-card shadow="hover">
<breadcrumb :data="'交流互动'"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item active">交流互动</a>
</div>
<div class="page-content">
<template v-if="listData.length">
<ul class="list">
<li v-for="(item,index) in listData" :key="index">
<div class="item">
<div class="inner">
<img class="avatar" :src="item.userAvatars" alt="">
<div class="texts">
<div class="title">
<span class="username">{{item.userName}}</span>
<span class="publish">发表于</span>
<span class="date">{{item.createTime}}</span>
</div>
<div class="userName">{{item.userName}}</div>
<div class="desc" v-html="item.content"></div>
</div>
<div class="right">
<p class="index">[ {{index+1}} # ]</p>
</div>
<div class="date">{{item.createTime}}</div>
</div>
<div class="action">
<button v-if="item.userId != userId" class="btn" @click="showReply(item)">回复</button>
<button v-else class="btn" @click="delMsg(item)">删除</button>
<button v-else class="btn del" @click="delMsg(item)">删除</button>
</div>
</div>
<div class="reply" v-if="item.showReply">
<quill :border="true" v-model="item.replyContent" :toTop="false" :height="150" />
@ -34,17 +34,14 @@
<div class="inner">
<img class="avatar" :src="reply.userAvatars" alt="">
<div class="texts">
<div class="title">
<span class="username">{{reply.userName}}</span>
<span class="publish">发表于</span>
<span class="date">{{reply.commentTime}}</span>
</div>
<div class="userName">{{reply.userName}}</div>
<div class="desc" v-html="reply.content"></div>
</div>
<div class="date">{{reply.commentTime}}</div>
</div>
<div class="action">
<button v-if="reply.commentUserId != userId" class="btn" @click="showReply(reply)">回复</button>
<button v-else class="btn" @click="delReply(reply,i,index)">删除</button>
<button v-else class="btn del" @click="delReply(reply,i,index)">删除</button>
</div>
</div>
<div class="reply" v-if="reply.showReply">
<quill :border="true" v-model="reply.replyContent" :toTop="false" :height="150" />
@ -59,14 +56,12 @@
</li>
</ul>
<div class="pagination">
<el-pagination
background
@current-change="handleCurrentChange"
:current-page="page"
:page-size="pageSize"
layout="total,prev, pager, next"
:total="total"
></el-pagination>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</template>
<div class="none" v-else>
<img src="../../../assets/img/none.png" alt="">
<p>暂无内容</p>
</div>
<div class="input-wrap">
<quill class="m-t-20" :border="true" v-model="content" :toTop="false" :height="150" />
@ -74,12 +69,15 @@
<el-button type="primary" size="mini" @click="submitMsg">提交</el-button>
</div>
</div>
</el-card>
</div>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import quill from '@/components/quill'
import breadcrumb from '@/components/breadcrumb'
import util from '@/libs/util'
export default {
data() {
return {
@ -96,7 +94,8 @@ export default {
])
},
components: {
quill
quill,
breadcrumb
},
mounted() {
this.getData()
@ -147,13 +146,13 @@ export default {
},
delMsg(row){
this.$post(`${this.api.delMessageBoard}?bid=${row.bid}`).then(res => {
this.$message.success('删除成功')
util.successMsg('删除成功')
this.getData()
}).catch(res => {})
},
submitComment(row){
let content = row.replyContent
if(!content) return this.$message.error('请填写内容')
if(!content) return util.errorMsg('请填写内容')
content = content.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g, "")
let data = {
bid: row.bid,
@ -162,7 +161,7 @@ export default {
schoolId: this.clientId,
}
this.$post(this.api.saveComment,data).then(res => {
this.$message.success('提交成功')
util.successMsg('提交成功')
row.replyContent = ''
this.getData()
}).catch(res => {})
@ -170,19 +169,19 @@ export default {
delReply(row,i,index){
if(row.identification == 1){
this.$post(`${this.api.delComment}?commentId=${row.commentId}`).then(res => {
this.$message.success('删除成功')
util.successMsg('删除成功')
this.listData[index].children.splice(i,1)
}).catch(res => {})
}else{
this.$post(`${this.api.delReply}?replyId=${row.replyId}`).then(res => {
this.$message.success('删除成功')
util.successMsg('删除成功')
this.listData[index].children.splice(i,1)
}).catch(res => {})
}
},
submitReply(row){
let content = row.replyContent
if(!content) return this.$message.error('请填写内容')
if(!content) return util.errorMsg('请填写内容')
content = content.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g, "")
let data = {
bid: row.bid,
@ -192,13 +191,13 @@ export default {
userId: this.userId,
}
this.$post(this.api.saveReply,data).then(res => {
this.$message.success('提交成功')
util.successMsg('提交成功')
row.replyContent = ''
this.getData()
}).catch(res => {})
},
submitMsg(){
if(!this.content) return this.$message.error('请填写内容')
if(!this.content) return util.errorMsg('请填写内容')
this.content = this.content.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g, "")
let data = {
content: this.content,
@ -206,7 +205,7 @@ export default {
userId: this.userId
}
this.$post(this.api.saveMessageBoard,data).then(res => {
this.$message.success('提交成功')
util.successMsg('提交成功')
this.content = ''
this.getData()
}).catch(res => {})
@ -217,4 +216,14 @@ export default {
<style lang="scss" scoped>
@import "@/styles/pages/messageBoard.scss";
.none{
padding: 50px 0;
text-align: center;
p{
margin-top: 40px;
color: rgba(0, 0, 0, 0.25);
font-size: 18px;
}
}
</style>

@ -1,39 +1,40 @@
<template>
<div>
<breadcrumb :data="'我的练习/练习'"></breadcrumb>
<div class="box">
<div class="left">
<p class="title">答题卡</p>
<div class="page left">
<p class="title">{{practiseName}}</p>
<div class="progress">
<div class="ans">答题进度({{progress}}%)</div>
<el-progress :percentage="progress" :show-text="false"></el-progress>
</div>
<div>
<div class="item">
<p class="type">单选题</p>
<p class="total">{{singleCount}}合计{{singlePoint}}</p>
<p class="type">单选题({{singleCount}}合计{{singlePoint}})</p>
<div class="nums">
<span v-for="n in singleCount" :class="{active: n <= singleAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="item">
<p class="type">多选题</p>
<p class="total">{{multipleCount}}合计{{multipleChoiceScore}}</p>
<p class="type">多选题({{multipleCount}}合计{{multipleChoiceScore}})</p>
<div class="nums">
<span v-for="n in multipleCount" :class="{active: n <= multipleAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="item">
<p class="type">判断题</p>
<p class="total">{{judgeCount}}合计{{judgeScore}}</p>
<p class="type">判断题({{judgeCount}}合计{{judgeScore}})</p>
<div class="nums">
<span v-for="n in judgeCount" :class="{active: n <= judgeAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="item">
<p class="type">填空题</p>
<p class="total">{{fillBlankCount}}合计{{fillBlanksScore}}</p>
<p class="type">填空题({{fillBlankCount}}合计{{fillBlanksScore}})</p>
<div class="nums">
<span v-for="n in fillBlankCount" :class="{active: n <= fillBlankAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="item">
<p class="type">简答题</p>
<p class="total">{{briefAnswerCount}}合计{{briefAnswerScore}}</p>
<p class="type">简答题({{briefAnswerCount}}合计{{briefAnswerScore}})</p>
<div class="nums">
<span v-for="n in briefAnswerCount" :class="{active: n <= briefAnswerAnsweredCount}" :key="n">{{n}}</span>
</div>
@ -42,13 +43,14 @@
<el-button size="mini" type="primary" @click="save">提交练习</el-button>
</div>
</div>
</div>
<div class="middle">
<div class="ques">
<div class="page right">
<template v-for="(subject,k) in subjects">
<div class="item" v-if="subject.length" :key="k">
<p v-if="subjects[k].length" class="title">{{questionType[k]}}{{subjects[k].length}}合计{{scoreList[k]}}</p>
<div class="ques-wrap" v-for="(item,index) in subject" :key="index">
<div class="ques-wrap">
<div class="ques" v-for="(item,index) in subject" :key="index">
<div class="name-wrap">
<span class="index">{{index+1}}.</span>
<div class="name" :class="'stem' + k + index" v-html="item.questionStem"></div>
@ -89,23 +91,19 @@
</div>
</div>
</div>
</template>
</div>
</template>
</div>
<div class="right">
<div class="ans">答题进度</div>
<el-progress :percentage="progress"></el-progress>
</div>
</div>
</template>
<script>
import { mapState,mapGetters,mapActions } from 'vuex'
import setBackground from '@/mixins/setBackground'
import examDo from '@/mixins/examDo'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default {
mixins: [ setBackground,examDo ],
mixins: [ examDo ],
data() {
return {
identification: this.$store.state.practice.identification,
@ -135,15 +133,16 @@ export default {
isSubmit: false,
isDone: false,
totalLen: 0,
submiting: false
submiting: false,
};
},
components: {breadcrumb},
computed: {
...mapState('user', [
'userId'
]),
...mapState('practice', [
'practiseId','paperId','isContinue'
'practiseId','paperId','isContinue','practiseName'
]),
},
mounted() {

@ -1,37 +1,43 @@
<template>
<div class="box">
<div>
<breadcrumb :data="'我的练习/' + tabs[active]" ref="breadcrumb"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == activeName}" @click="tabChange(index)">{{item}}</a>
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{item}}</a>
</div>
<my-practice v-if="activeName == 'first'"></my-practice>
<div class="page-content">
<my-practice v-if="active == 'first'"></my-practice>
<random-practice v-else></random-practice>
</div>
</div>
</div>
</template>
<script>
import { mapState,mapGetters,mapActions } from 'vuex'
import myPractice from './myPractice.vue';
import randomPractice from './randomPractice.vue';
import myPractice from './myPractice.vue'
import randomPractice from './randomPractice.vue'
import breadcrumb from '@/components/breadcrumb'
export default {
name: 'index',
data() {
return {
isRandom: this.$route.query.isRandom,
activeName: 'first',
active: 'first',
tabs: {
first: '我的练习',
second: '随机练习'
}
};
},
components: {myPractice,randomPractice},
components: {myPractice,randomPractice,breadcrumb},
mounted() {
if(this.isRandom) this.activeName = 'second'
if(this.isRandom) this.active = 'second'
},
methods: {
tabChange(index){
this.activeName = index
this.active = index
this.$refs.breadcrumb.update('我的练习/' + this.tabs[this.active])
},
}
};

@ -1,20 +1,16 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div>
<div class="p-title m-b-20">筛选</div>
<div class="flex">
<div>
<el-input placeholder="请输入练习名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</div>
</div>
<div class="tool">
<ul class="filter">
<li>
<label>搜索</label>
<el-input placeholder="请输入练习名称" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
</div>
</el-card>
<el-card shadow="hover">
<el-table :data="listData" class="table" ref="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center">
<template slot-scope="scope">
{{scope.$index + (page - 1) * pageSize + 1}}
@ -48,12 +44,12 @@
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" :current-page="page">
</el-pagination>
</div>
</el-card>
</div>
</template>
<script>
import { mapState,mapGetters,mapActions } from 'vuex'
import util from '@/libs/util'
export default {
data() {
return {
@ -102,7 +98,7 @@ export default {
})
.then(() => {
this.$del(`${this.api.deleteCourse}/${row.id}`).then(res => {
this.$message.success('删除成功');
util.successMsg('删除成功');
this.getData()
}).catch(res => {});
})
@ -117,7 +113,7 @@ export default {
},
practice(row){
if(row.isHava){
this.$confirm('是否要继续上次的练习?',{
this.$confirm('是否要继续上次未完成的练习?',{
title: '提示',
confirmButtonText: '是',
cancelButtonText: '否',
@ -135,6 +131,7 @@ export default {
this.setInfo({
practiseId: row.practiseId,
paperId: row.testPaperId,
practiseName: row.practiseName,
isContinue,
identification
})

@ -1,26 +1,17 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div class="tool">
<ul class="filter">
<li>
<label>搜索</label>
<el-input placeholder="请输入练习名称" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
<div>
<div class="p-title m-b-20">筛选</div>
<div class="flex">
<div>
<el-input placeholder="请输入练习名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
<el-button type="primary" size="small" round @click="practice">进入随机练习</el-button>
</div>
</div>
</div>
</el-card>
<el-card shadow="hover">
<div class="m-b-20">
<el-button
type="primary"
size="small"
round
@click="practice"
>进入随机练习</el-button>
</div>
<el-table :data="listData" class="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id">
<el-table-column type="index" width="100" label="序号" align="center">
<template slot-scope="scope">
@ -28,19 +19,19 @@
</template>
</el-table-column>
<el-table-column prop="practiceName" label="练习名称" align="center"></el-table-column>
<el-table-column prop="startTime" label="练习时间" align="center"></el-table-column>
<el-table-column prop="timeSpent" label="用时(分钟)" align="center"></el-table-column>
<el-table-column prop="score" label="得分" align="center"></el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" :current-page="page">
</el-pagination>
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" :current-page="page"></el-pagination>
</div>
</el-card>
</div>
</template>
<script>
import { mapState,mapGetters,mapActions } from 'vuex'
import util from '@/libs/util'
export default {
data() {
return {

@ -1,39 +1,35 @@
<template>
<div>
<breadcrumb :data="'我的练习/随机练习'"></breadcrumb>
<div class="box">
<div class="left">
<p class="title">答题卡</p>
<div class="item">
<p class="type">单选题</p>
<p class="total">{{singleCount}}合计{{singlePoint}}</p>
<div class="page left">
<div>
<div class="item" style="border-top: 0">
<p class="type">单选题({{singleCount}}合计{{singlePoint}})</p>
<div class="nums">
<span v-for="n in singleCount" :class="{active: n <= singleAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="item">
<p class="type">多选题</p>
<p class="total">{{multipleCount}}合计{{multipleChoiceScore}}</p>
<p class="type">多选题({{multipleCount}}合计{{multipleChoiceScore}})</p>
<div class="nums">
<span v-for="n in multipleCount" :class="{active: n <= multipleAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="item">
<p class="type">判断题</p>
<p class="total">{{judgeCount}}合计{{judgeScore}}</p>
<p class="type">判断题({{judgeCount}}合计{{judgeScore}})</p>
<div class="nums">
<span v-for="n in judgeCount" :class="{active: n <= judgeAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="item">
<p class="type">填空题</p>
<p class="total">{{fillBlankCount}}合计{{fillBlanksScore}}</p>
<p class="type">填空题({{fillBlankCount}}合计{{fillBlanksScore}})</p>
<div class="nums">
<span v-for="n in fillBlankCount" :class="{active: n <= fillBlankAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="item">
<p class="type">简答题</p>
<p class="total">{{briefAnswerCount}}合计{{briefAnswerScore}}</p>
<p class="type">简答题({{briefAnswerCount}}合计{{briefAnswerScore}})</p>
<div class="nums">
<span v-for="n in briefAnswerCount" :class="{active: n <= briefAnswerAnsweredCount}" :key="n">{{n}}</span>
</div>
@ -42,13 +38,14 @@
<el-button size="mini" type="primary" @click="save">提交练习</el-button>
</div>
</div>
</div>
<div class="middle">
<div class="ques">
<div class="page right">
<template v-for="(subject,k) in subjects">
<div class="item" v-if="subject.length" :key="k">
<p v-if="subjects[k].length" class="title">{{questionType[k]}}{{subjects[k].length}}合计{{scoreList[k]}}</p>
<div class="ques-wrap" v-for="(item,index) in subject" :key="index">
<div class="ques-wrap">
<div class="ques" v-for="(item,index) in subject" :key="index">
<div class="name-wrap">
<span class="index">{{index+1}}.</span>
<div class="name" :class="'stem' + k + index" v-html="item.questionStem"></div>
@ -77,6 +74,7 @@
</div>
</div>
</div>
</div>
</template>
</div>
</div>
@ -84,11 +82,11 @@
</template>
<script>
import { mapState,mapGetters,mapActions } from 'vuex'
import setBackground from '@/mixins/setBackground'
import examDo from '@/mixins/examDo'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default {
mixins: [ setBackground,examDo ],
mixins: [ examDo ],
data() {
return {
subjects: [],
@ -114,6 +112,7 @@ export default {
submiting: false
};
},
components: {breadcrumb},
computed: {
...mapState('user', [
'userId','clientId'
@ -212,7 +211,7 @@ export default {
this.$post(`${this.api.addPractiseRecordRandom}?userId=${this.userId}&randomId=${this.randomId}`)
.then(res => {
this.submiting = false
this.$message.success('提交成功')
util.successMsg('提交成功')
this.$router.push('list?isRandom=true')
})
.catch(err => {})

@ -1,54 +1,39 @@
<template>
<div style="width:100%;height:100%;display:flex;align-items: center;flex-direction:column">
<div class="header">
<img :src="avatar" class="HeadPortrait" />
<div style="color:#cb221c;font-size:14px;font-family:MicrosoftYaHei;margin-top:5px;">
<el-upload :action="this.api.fileupload" :on-success="changeAvatar">
<div>点击更改头像</div>
<div>
<div class="page">
<div class="tabs">
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{item}}</a>
</div>
<div class="page-content">
<div v-if="active == 'first'">
<el-form>
<ul class="list">
<li>
<label>头像</label>
<div class="avatar-wrap">
<img :src="avatar" class="avatar" />
<el-upload :action="this.api.fileupload" :data="{userId:this.userId}" name="file" :limit="1" :on-success="changeAvatar">
<el-button size="small"><img src="../../../assets/img/upload.png" alt=""> 上传头像</el-button>
</el-upload>
</div>
</div>
<div class="card">
<p class="block-title" style="display: flex;justify-content: space-between;align-items: center;">
用户信息
<el-button type="success" size="small" v-throttle @click="save">更新资料</el-button>
</p>
<p class="meta-title">个人信息</p>
<div class="information">
<div class="block">
<p class="block-left">姓名</p>
<div class="block-right">
<input
id="username"
type="text"
v-model="personalInformation.userName"
/>
<div class="ii">
<label for="username">
<i class="el-icon-edit" style="color:rgba(255, 255, 255, 1)"></i>
</label>
</div>
</div>
</div>
<div class="block">
<p class="block-left">性别</p>
<el-select
v-model="personalInformation.sex"
placeholder
>
<el-option
v-for="item in sexList"
:key="item.value"
:label="item.name"
:value="item.value"
></el-option>
</li>
<li>
<label>姓名</label>
<div>
<el-input v-model="personalInformation.userName" clearable></el-input>
</div>
</li>
<li>
<label>性别</label>
<div>
<el-select v-model="personalInformation.sex">
<el-option v-for="item in sexList" :key="item.value" :label="item.name" :value="item.value"></el-option>
</el-select>
</div>
<div class="block">
<p class="block-left">所在国家</p>
</li>
<li>
<label>所在国家</label>
<div>
<el-select
v-model="personalInformation.countries"
placeholder
@ -61,13 +46,14 @@
></el-option>
</el-select>
</div>
<div class="block">
<p class="block-left">所在省份</p>
</li>
<li>
<label>所在省份</label>
<div>
<el-select
v-model="personalInformation.provinceId"
placeholder
@change="id => getCity(id)"
@change="id => getCity(id,1)"
>
<el-option
v-for="item in provinceList"
@ -77,9 +63,10 @@
></el-option>
</el-select>
</div>
<div class="block">
<p class="block-left">所在省市</p>
</li>
<li>
<label>所在省市</label>
<div>
<el-select
v-model="personalInformation.cityId"
placeholder
@ -93,9 +80,10 @@
></el-option>
</el-select>
</div>
<div class="block">
<p class="block-left">出生年月日</p>
</li>
<li>
<label>出生年月日</label>
<div>
<el-date-picker
v-model="personalInformation.dateBirth"
:clearable="false"
@ -103,25 +91,16 @@
type="date">
</el-date-picker>
</div>
<div class="block">
<p class="block-left">证件</p>
<div class="block-right">
<input
id="idnumber"
type="text"
v-model="personalInformation.idnumber"
/>
<div class="ii">
<label for="idnumber">
<i class="el-icon-edit" style="color:rgba(255, 255, 255, 1)"></i>
</label>
</div>
</div>
</li>
<li>
<label>证件</label>
<div>
<el-input v-model="personalInformation.idnumber" clearable></el-input>
</div>
<div class="block">
<p class="block-left">教育程度</p>
</li>
<li>
<label>教育程度</label>
<div>
<el-select
v-model="personalInformation.educationDegree"
placeholder="请选择教育程度"
@ -134,107 +113,40 @@
></el-option>
</el-select>
</div>
<!-- <div class="block">
<p class="block-left">当前所在学校</p>
<el-select v-model="personalInformation.clientId" filterable placeholder="请选择学校">
<el-option v-for="(item,index) in schoolList" :key="index" :label="item.clientName" :value="item.id"></el-option>
</el-select>
</div> -->
</div>
</div>
<div class="card m-b-20">
<p class="block-title">账号信息</p>
<div class="information">
<div class="block">
<p class="block-left">用户账号</p>
<div class="block-right">
<input
id="account"
type="text"
v-model="personalInformation.account"
@change="accountChange"
/>
<div class="ii">
<label for="account">
<i class="el-icon-edit" style="color:rgba(255, 255, 255, 1)"></i>
</label>
</div>
</div>
</div>
<div class="block">
<p class="block-left">手机号</p>
<div class="block-right">
<input
id="phone"
type="text"
maxlength="11"
v-model="personalInformation.phone"
/>
<div class="ii">
<label for="phone">
<i class="el-icon-edit" style="color:rgba(255, 255, 255, 1)"></i>
</label>
</div>
</div>
<!-- <div class="near-right">
{{personalInformation.phone}}
<el-button size="small" @click="bindPhone">更换</el-button>
</div> -->
</div>
<div class="block">
<p class="block-left">邮箱</p>
<div class="block-right">
<input
id="email"
type="text"
v-model="personalInformation.email"
/>
<div class="ii">
<label for="email">
<i class="el-icon-edit" style="color:rgba(255, 255, 255, 1)"></i>
</label>
</div>
</div>
<!-- <div class="near-right"> -->
<!-- {{personalInformation.email}} -->
<!-- <el-button size="small" @click="bindEmail">绑定</el-button> -->
<!-- </div> -->
</div>
<!-- <div class="block">
<p class="block-left">微信</p> -->
<!-- <input
id="wechat"
type="text"
class="block-right"
v-model="personalInformation.weChatID"
/>
<div class="ii">
<label for="wechat">
<i class="el-icon-edit" style="color:rgba(255, 255, 255, 1)"></i>
</label>
</div> -->
<!-- <div class="near-right">
{{personalInformation.weChatID}}
<el-button size="small">绑定</el-button>
</li>
</ul>
</el-form>
</div>
</div> -->
<div class="block">
<p class="block-left">密码</p>
<div class="near-right">
<div v-else>
<ul class="list">
<li>
<label>用户账号</label>
<div>
<el-input v-model="personalInformation.account" clearable></el-input>
</div>
</li>
<li>
<label>手机号</label>
<div>
<el-input v-model="personalInformation.phone" clearable></el-input>
</div>
</li>
<li>
<label>邮箱</label>
<div>
<el-input v-model="personalInformation.email" clearable></el-input>
</div>
</li>
<li>
<label>密码</label>
<div>
<el-button size="small" @click="bindPassword">更换密码</el-button>
</div>
</li>
</ul>
</div>
<div class="block" style="margin-top: 5px">
<p class="block-left"></p>
<div class="near-right">
<el-button type="primary" size="small" @click="forgetPassword">忘记密码</el-button>
</div>
<div style="margin-top: 32px">
<el-button type="primary" size="small" v-throttle @click="save">更新</el-button>
</div>
</div>
</div>
@ -265,10 +177,18 @@
</template>
<script>
import { mapState,mapActions } from 'vuex';
import { mapState,mapActions } from 'vuex'
import _ from 'lodash';
import bus from '@/libs/bus'
import util from '@/libs/util'
export default {
data() {
return {
active: 'first',
tabs: {
first: '用户信息',
second: '账号信息'
},
personalInformation: {
name:'',
workNumber:'',
@ -302,9 +222,8 @@ export default {
}
],
form: {},
provinceList: this.$store.state.provinceList, //
cityList: [], //
//
provinceList:[],
cityList: [],
educationDegreeList: [
{
name: '专科',
@ -334,11 +253,10 @@ export default {
},
computed: {
...mapState('user', [
'userId','avatar'
'userId','avatar','userName'
]),
},
mounted() {
console.log(33,this.avatar)
this.getdata();
this.getProvince()
this.getSchoolData()
@ -347,6 +265,9 @@ export default {
...mapActions('user', [
'setAvatar','setUserName'
]),
tabChange(index){
this.active = index
},
getProvince(){
this.$get(this.api.queryProvince).then(res => {
this.provinceList = res.data.list
@ -378,7 +299,7 @@ export default {
this.$get(`${this.api.getAccount}?account=${this.form.account}`).then(res => {
if(res.data.userInfo){
this.accountRepeat = true
this.$message.warning('该账号已存在')
util.warningMsg('该账号已存在')
}else{
this.accountRepeat = false
}
@ -388,16 +309,18 @@ export default {
changeAvatar(res) {
this.setAvatar(res.data.filesResult.fileUrl)
},
uploadHeadImg: function() {
this.$el.querySelector('.hiddenInput').click();
},
getdata() {
this.$get(`${this.api.userinfo}?userId=${this.userId}`)
.then(res => {
this.personalInformation = res.data.userInfo
this.personalInformation.countries = '中国'
this.personalInformation.clientName = this.schoolList.find(n => n.id == this.personalInformation.clientId).clientName
this.curPassword = this.personalInformation.password
this.$nextTick(() => {
if(this.personalInformation.provinceId){
this.getCityData()
this.getCityData(1)
}
})
})
@ -408,16 +331,13 @@ export default {
bindPassword() {
this.passwordVisible = true
},
forgetPassword(){
this.$message.warning('请联系学校管理员重置密码')
},
editPassword() {
if(!this.passwordForm.password) return this.$message.warning('请输入原密码')
if(!this.passwordForm.newPassword) return this.$message.warning('请输入新密码')
if(!this.passwordForm.reNewPassword) return this.$message.warning('请确认新密码')
if(this.passwordForm.newPassword.length < 6 || this.passwordForm.reNewPassword.length < 6) return this.$message.warning('请输入6位数以上的密码')
if(this.passwordForm.newPassword !== this.passwordForm.reNewPassword) return this.$message.warning('输入的新密码不一致,请重新确认')
if(this.curPassword === this.passwordForm.newPassword) return this.$message.warning('原密码跟新密码不能一致')
if(!this.passwordForm.password) return util.warningMsg('请输入原密码')
if(!this.passwordForm.newPassword) return util.warningMsg('请输入新密码')
if(!this.passwordForm.reNewPassword) return util.warningMsg('请确认新密码')
if(this.passwordForm.newPassword.length < 6 || this.passwordForm.reNewPassword.length < 6) return util.warningMsg('请输入6位数以上的密码')
if(this.passwordForm.newPassword !== this.passwordForm.reNewPassword) return util.warningMsg('输入的新密码不一致,请重新确认')
if(this.curPassword === this.passwordForm.newPassword) return util.warningMsg('原密码跟新密码不能一致')
let data = {
userId: this.personalInformation.userId,
@ -426,11 +346,11 @@ export default {
this.$post(this.api.userinfoUpdate,data)
.then(res => {
if(res.success){
this.$message.success('更换成功')
util.successMsg('更换成功')
this.curPassword = this.passwordForm.newPassword
this.passwordVisible = false
}else{
this.$message.error('更换失败')
util.errorMsg('更换失败')
}
})
.catch(err => {
@ -445,10 +365,10 @@ export default {
}
},
save() {
if(this.personalInformation.idnumber && !/(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)/.test(this.personalInformation.idnumber)) return this.$message.warning('请输入正确的证件号码')
if(this.accountRepeat) return this.$message.warning('该账号已存在')
if(this.personalInformation.phone && !/^1[3456789]\d{9}$/.test(this.personalInformation.phone)) return this.$message.warning('请输入正确的手机号')
if(this.personalInformation.email && !/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(this.personalInformation.email)) return this.$message.warning('请输入正确的邮箱')
if(this.personalInformation.idnumber && !/(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)/.test(this.personalInformation.idnumber)) return util.warningMsg('请输入正确的证件号码')
if(this.accountRepeat) return util.warningMsg('该账号已存在')
if(this.personalInformation.phone && !/^1[3456789]\d{9}$/.test(this.personalInformation.phone)) return util.warningMsg('请输入正确的手机号')
if(this.personalInformation.email && !/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(this.personalInformation.email)) return util.warningMsg('请输入正确的邮箱')
let personalInformation = this.personalInformation
let userInfoEntity = {
idnumber: personalInformation.idnumber,
@ -470,273 +390,45 @@ export default {
this.$post(this.api.userinfoUpdate,data).then(res => {
if(res.success){
this.setUserName(personalInformation.userName)
this.$message.success('提交成功')
util.successMsg('提交成功')
this.$router.back()
}else{
this.$message.error('提交失败')
util.errorMsg('提交失败')
}
}).catch(res => {});
}).catch(res => {})
}
}
};
</script>
<style lang="scss" scoped>
.header{
text-align: center;
}
.header /deep/.el-upload-list__item-name {
display: none;
}
.header /deep/.el-icon-upload-success{
display: none;
}
.header /deep/.el-upload-list__item-status-label{
display: none;
}
.header /deep/ .el-upload-list{
display: none;
}
/deep/.el-input__inner{
height: 32px !important;
}
/deep/.el-select .el-input .el-select__caret{
line-height: 32px;
}
input:focus {
outline: 0;
}
.openfile {
cursor: pointer;
}
.HeadPortrait {
margin-top: 10px;
width: 80px;
height: 80px;
border-radius: 50%;
.head {
width: 34px;
height: 34px;
background: rgba(255, 255, 255, 1);
border-radius: 50%;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
position: relative;
.eee {
height: 10px;
width: 16px;
background-color: rgba(255, 255, 255, 1);
margin-bottom: -10px;
position: absolute;
top: 8px;
z-index: 2;
}
.Semicircle {
width: 12px;
height: 12px;
border: 2px solid #cb221c;
border-radius: 50px;
margin-bottom: 10px;
position: absolute;
}
}
.body {
color: #cb221c;
width: 30px;
height: 20px;
border: 3px solid #f5f5f5;
border-radius: 100%;
margin-top: 5px;
margin-bottom: -10px;
}
.body::after {
content: '';
width: 40px;
height: 30px;
display: inline-block;
background-color: #cb221c;
margin-top: 8px;
margin-left: -6px;
}
}
input {
height: 50px;
width: 300px;
border: 0;
text-align: right;
outline: none;
}
.card {
margin-top: 10px;
width: 750px;
padding: 20px;
background: rgba(255, 255, 255, 1);
box-shadow: 0px 0px 21px 0px rgba(48, 115, 248, 0.1);
border-radius: 10px;
position: relative;
.block-title{
font-weight: bold;
font-size: 20px;
}
.meta-title{
margin: 10px 0 0;
color: #cdbcec;
font-size: 15px;
}
.el-icon-document {
color: #cb221c;
font-size: 30px;
}
.el-icon-collection {
color: #cb221c;
position: absolute;
left: 31px;
top: 31px;
font-size: 30px;
}
span {
color: #333333;
font-size: 20px;
}
.plus{
display: flex;
justify-content: space-between;
i{
font-size: 22px;
color: #21d749;
cursor: pointer;
}
}
.archives{
padding: 10px 20px;
margin-top: 20px;
border: 1px dashed #bbb;
border-radius: 12px;
&.default-arch{
margin-bottom: 20px;
/deep/.el-select{
width: 10rem;
}
/deep/input{
background-color: transparent;
}
}
}
.archives-wrap{
.block{
display: flex;
align-items: center;
margin-bottom: 8px;
&:last-child{
margin-bottom: 0;
}
.block-left{
width: 30%;
font-family: MicrosoftYaHei;
font-size: 14px;
color: #101010;
}
/deep/.el-input__inner{
border-radius: 8px !important;
}
}
}
.information {
.block {
line-height: 38px;
position: relative;
/deep/.page{
.page-content{
padding-top: 0;
.list{
li{
display: flex;
justify-content: space-between;
align-items: center;
.block-left {
font-family: MicrosoftYaHei;
font-size: 14px;
color: #101010;
}
input{
padding: 16px 0;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
label{
width: 180px;
color: rgba(0, 0, 0, 0.85);
font-size: 16px;
}
/deep/.el-date-editor .el-input__prefix{
line-height: 32px;
}
/deep/.el-input__prefix,/deep/.el-input__suffix{
left: auto;
right: 0;
}
.block-right,.near-right {
.avatar-wrap{
display: inline-flex;
align-items: center;
margin: 0;
padding: 0;
color: #333333ff;
font-size: 18px;
}
.near-right{
right: 0;
font-size: 18px;
}
.ii {
display: flex;
justify-content: center;
align-items: center;
width: 22px;
height: 22px;
margin-left: 10px;
border-radius: 50%;
background-color: #cb221c;
i{
font-size: 12px;
}
}
/deep/.el-input__inner {
padding-right: 1.8rem;
margin-right: 5px;
color: #333333ff;
font-size: 16px;
text-align: right;
border: 0px;
}
/deep/.el-input__icon {
background: #cb221c;
width: 22px;
height: 22px;
line-height: 22px;
color: rgba(255, 255, 255, 1);
border-radius: 50%;
&.el-icon-date{
font-size: 14px;
}
}
/deep/.el-icon-arrow-up:before {
content: '\e6e1';
margin-top: 5px;
}
&.readonly .block-left{
color: #a5a7adff;
.avatar{
width: 64px;
height: 64px;
margin-right: 24px;
border-radius: 100%;
}
}
.el-input{
width: 320px;
}
.fold{
margin-top: 20px;
text-align: center;
i{
font-size: 22px;
color: #8e8e8e;
cursor: pointer;
&:hover{
opacity: .8;
}
}
}

@ -1,39 +1,35 @@
<template>
<div>
<breadcrumb :data="'我的练习/练习'"></breadcrumb>
<div class="box">
<div class="left">
<p class="title">答题卡</p>
<div class="item">
<p class="type">单选题</p>
<p class="total">{{singleCount}}合计{{singlePoint}}</p>
<div class="page left">
<div>
<div class="item" style="border-top: 0">
<p class="type">单选题({{singleCount}}合计{{singlePoint}})</p>
<div class="nums">
<span v-for="n in singleCount" :class="{active: n <= singleAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="item">
<p class="type">多选题</p>
<p class="total">{{multipleCount}}合计{{multipleChoiceScore}}</p>
<p class="type">多选题({{multipleCount}}合计{{multipleChoiceScore}})</p>
<div class="nums">
<span v-for="n in multipleCount" :class="{active: n <= multipleAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="item">
<p class="type">判断题</p>
<p class="total">{{judgeCount}}合计{{judgeScore}}</p>
<p class="type">判断题({{judgeCount}}合计{{judgeScore}})</p>
<div class="nums">
<span v-for="n in judgeCount" :class="{active: n <= judgeAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="item">
<p class="type">填空题</p>
<p class="total">{{fillBlankCount}}合计{{fillBlanksScore}}</p>
<p class="type">填空题({{fillBlankCount}}合计{{fillBlanksScore}})</p>
<div class="nums">
<span v-for="n in fillBlankCount" :class="{active: n <= fillBlankAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="item">
<p class="type">简答题</p>
<p class="total">{{briefAnswerCount}}合计{{briefAnswerScore}}</p>
<p class="type">简答题({{briefAnswerCount}}合计{{briefAnswerScore}})</p>
<div class="nums">
<span v-for="n in briefAnswerCount" :class="{active: n <= briefAnswerAnsweredCount}" :key="n">{{n}}</span>
</div>
@ -42,13 +38,14 @@
<el-button size="mini" type="primary" @click="save">提交练习</el-button>
</div>
</div>
</div>
<div class="middle">
<div class="ques">
<div class="page right">
<template v-for="(subject,k) in subjects">
<div class="item" v-if="subject.length" :key="k">
<p v-if="subjects[k].length" class="title">{{questionType[k]}}{{subjects[k].length}}合计{{scoreList[k]}}</p>
<div class="ques-wrap" v-for="(item,index) in subject" :key="index">
<div class="ques-wrap">
<div class="ques" v-for="(item,index) in subject" :key="index">
<div class="name-wrap">
<span class="index">{{index+1}}.</span>
<div class="name" :class="'stem' + k + index" v-html="item.questionStem"></div>
@ -77,17 +74,18 @@
</div>
</div>
</div>
</div>
</template>
</div>
</div>
<el-dialog title="成绩详情" :visible.sync="resultVisible" width="30%" center :close-on-click-modal="false" :show-close="false">
<el-table :data="resultData" border>
<el-dialog title="成绩详情" :visible.sync="resultVisible" width="30%" :close-on-click-modal="false" :show-close="false">
<el-table :data="resultData">
<el-table-column type="index" label="序号" width="60" align="center"></el-table-column>
<el-table-column label="正误" min-width="45" align="center">
<template slot-scope="scope">
<img v-if="scope.row.true" width="15" src="../../../assets/img/true.png" alt="">
<img v-else width="15" src="../../../assets/img/false.png" alt="">
<img v-if="scope.row.true" src="../../../assets/img/true.png" alt="">
<img v-else src="../../../assets/img/false.png" alt="">
</template>
</el-table-column>
<el-table-column prop="answer" label="正确答案" min-width="70" align="center"></el-table-column>
@ -95,18 +93,18 @@
<el-table-column prop="answerAnalysis" label="解析" min-width="80"></el-table-column>
</el-table>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="back">返回</el-button>
<el-button type="primary" size="small" @click="back">返回</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { mapState,mapGetters,mapActions } from 'vuex'
import setBackground from '@/mixins/setBackground'
import examDo from '@/mixins/examDo'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default {
mixins: [ setBackground,examDo ],
mixins: [ examDo ],
data() {
return {
subjects: [],
@ -133,6 +131,7 @@ export default {
resultData: []
};
},
components: {breadcrumb},
computed: {
...mapState('user', [
'userId','clientId'

@ -1,56 +1,43 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div class="p-title m-b-20">筛选</div>
<div class="flex j-between">
<el-form label-width="80px" inline>
<el-form-item class="no-mb" label="题库来源">
<el-select v-model="type" placeholder="请选择题库来源" @change="getName">
<breadcrumb :data="'错题练习/错题列表'"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item active">错题列表</a>
</div>
<div class="page-content">
<div class="tool">
<ul class="filter">
<li>
<label>题库来源</label>
<el-select v-model="type" placeholder="请选择题库来源" size="small" @change="getName">
<el-option v-for="(item,index) in sourceList" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item class="no-mb" label="试卷名称">
<el-select v-model="paperId" placeholder="请选择试卷名称" @change="getData">
</li>
<li>
<label>试卷名称</label>
<el-select v-model="paperId" placeholder="请选择试卷名称" size="small" @change="getData">
<el-option v-for="(item,index) in nameList" :key="index" :label="item.paperName" :value="item.paperId"></el-option>
</el-select>
</el-form-item>
<el-form-item class="no-mb" label="试题类型">
<el-select v-model="typeId" clearable placeholder="请选择试题类型" @change="getData">
</li>
<li>
<label>试题类型</label>
<el-select v-model="typeId" clearable placeholder="请选择试题类型" size="small" @change="getData">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in typeList" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-form>
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入知识点" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
<div>
<el-input
placeholder="请输入知识点"
prefix-icon="el-icon-search"
v-model="keyword"
clearable
></el-input>
</div>
<el-button type="primary" size="small" round @click="practice">错题练习</el-button>
</div>
</el-card>
<el-card shadow="hover" class="m-b-20">
<div class="m-b-20">
<el-button
type="primary"
size="small"
round
@click="practice"
>错题练习</el-button>
</div>
<el-table
:data="listData"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
@selection-change="handleSelectionChange"
>
<el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
<el-table-column type="index" width="100" label="序号" align="center">
<template
slot-scope="scope"
@ -73,16 +60,10 @@
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
background
@current-change="handleCurrentChange"
:current-page="page"
:page-size="pageSize"
layout="total,prev, pager, next"
:total="total"
></el-pagination>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</div>
</div>
</el-card>
<el-dialog title="错题详情" :visible.sync="detailVisible" width="40%">
<div class="ques">
@ -144,6 +125,7 @@
<script>
import { mapState,mapActions } from 'vuex'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default {
data() {
return {
@ -183,6 +165,7 @@ export default {
'userId','clientId'
]),
},
components: {breadcrumb},
mounted() {
console.log(process.env.NODE_ENV)
this.getType()
@ -289,22 +272,22 @@ export default {
}
if(right){
this.$post(`${this.api.removes}?qid=${quesInfo.id}&userId=${this.userId}&type=${this.type}`).then(res => {
this.$message.success('纠错成功')
util.successMsg('纠错成功')
this.correctVisible = false
this.getData()
}).catch(err => {})
}else{
this.$message.error('回答错误')
util.errorMsg('回答错误')
this.correctVisible = false
}
},
practice(){
if(!this.listData.length) return this.$message.warning('错题列表为空,无法练习')
if(!this.listData.length) return util.warningMsg('错题列表为空,无法练习')
let qid = []
this.listData.map(n => {
n.typeName != '简答题' && qid.push(n.questionId)
})
if(!qid.length) return this.$message.warning('未查询到客观题,无法练习')
if(!qid.length) return util.warningMsg('未查询到客观题,无法练习')
this.setInfo({
qid: qid.join(),
type: this.type

@ -1,5 +1,5 @@
import axios from 'axios';
import { Message } from 'element-ui'
import axios from 'axios'
import util from '@/libs/util'
import router from '@/router/index'
import Setting from '@/setting'
@ -19,7 +19,7 @@ service.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'
// }
// return config;
// }, err => {
// Message.error({
// util.errorMsg({
// message: '退出登陆',
// onClose: function () {
// router.push({name: 'login'});
@ -37,7 +37,7 @@ service.interceptors.response.use(
} else {
switch (res.code) {
case 201:
Message.error(res.message ? res.message : '数据请求异常')
util.errorMsg(res.message ? res.message : '数据请求异常')
break;
default:
Promise.reject(res).catch(e => {})

@ -16,7 +16,7 @@ const Setting = {
showProgressBar: true,
// 接口请求地址
// apiBaseURL: env === 'development' ? 'http://192.168.31.152:8001' : 'http://39.108.250.202:8000',
apiBaseURL: env === 'development' ? 'http://39.108.250.202:9000' : 'http://39.108.250.202:9000',
apiBaseURL: env === 'development' ? 'http://192.168.31.152:8001' : 'http://39.108.250.202:9000',
// 接口请求返回错误时,弹窗的持续时间,单位:秒
modalDuration: 3,
// 接口请求返回错误时,弹窗的类型,可选值为 Message 或 Notice

@ -61,7 +61,8 @@ export default {
teacherId: '',
classId: '',
paperName: '',
countdown: ''
countdown: '',
assessmentName: ''
},
getters: {
getDegreeName: state => id => {
@ -85,6 +86,7 @@ export default {
state.classId = info.classId
state.testPaperId = info.testPaperId
state.countdown = info.countdown
state.assessmentName = info.assessmentName
},
},
actions: {

@ -21,6 +21,7 @@ export default {
],
practiseId: '',
paperId: '',
practiseName: '',
isContinue: '',
identification: '',
},
@ -33,6 +34,7 @@ export default {
SET_INFO: (state, info) => {
state.practiseId = info.practiseId
state.paperId = info.paperId
state.practiseName = info.practiseName
state.isContinue = info.isContinue
state.identification = info.identification
},

@ -73,13 +73,13 @@ export default {
Setting.dynamicRoute && addRoutes(routes)
util.session.set(Setting.usernameKey, user.userName)
util.session.set(Setting.storeKey, JSON.stringify(state))
Message.success('登录成功');
util.successMsg('登录成功');
resolve()
}else{
Message.error('该用户没有权限')
util.errorMsg('该用户没有权限')
}
}else{
Message.error(res.message)
util.errorMsg(res.message)
}
}).catch(error => {
reject(error)

@ -1,154 +1,358 @@
@import "./default/index.scss";
.content-box {
-webkit-transition: left .3s ease-in-out;
transition: left .3s ease-in-out;
@font-face{
font-family: youshe;
src: url('font/YouSheBiaoTiHei.ttf');
}
.content {
width: auto;
height: 100%;
padding: 20px;
box-sizing: border-box;
[v-cloak] {
display: none;
}
.content-collapse {
left: 65px;
::-webkit-scrollbar {
width: 6px;
}
.container {
padding: 30px;
background: #fff;
border: 1px solid #ddd;
border-radius: 5px;
::-webkit-scrollbar-thumb {
border-radius: 10px;
background: rgba(0, 0, 0, 0.06);
}
.crumbs {
margin: 10px 0;
.required{
font-size: 16px;
color: #CC221C;
font-style: normal;
}
.pagination {
margin: 20px 0;
text-align: right;
.breadcrumb{
display: flex;
align-items: center;
margin-bottom: 20px;
.cur,.el-breadcrumb__inner,.el-breadcrumb__separator{
color: rgba(0,0,0,.45) !important;
font-weight: 400 !important;
font-size: 12px;
}
.el-breadcrumb__item:last-of-type .el-breadcrumb__inner{
color: rgba(0,0,0,.85) !important;
}
}
.el-button+.el-tooltip {
margin-left: 10px;
.el-button--primary.action-btn{
color: #CC221C !important;
font-size: 14px !important;
background-color: #fff !important;
border-radius: 4px !important;
}
.ql-snow .ql-tooltip {
transform: translateX(117.5px) translateY(10px) !important;
.el-input{
.el-input__inner{
border-color: rgba(0, 0, 0, 0.15);
}
}
.el-row {
margin-bottom: 20px;
.page{
position: relative;
background-color: #fff;
border-radius: 8px;
.p-title{
padding-left: 24px;
line-height: 56px;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
border-bottom: 1px solid rgba(0,0,0,.06);
}
.page-content{
padding: 24px;
.tool{
display: flex;
justify-content: space-between;
margin-bottom: 24px;
.filter{
display: inline-flex;
align-items: center;
flex: 1;
li{
display: inline-flex;
align-items: center;
margin-right: 30px;
label{
font-size: 14px;
line-height: 14px;
color: rgba(0,0,0,.65);
white-space: nowrap;
}
}
}
.single-choice{
dl {
display: flex;
line-height: 30px;
dt {
color: rgba(0,0,0,.65);
font-size: 14px;
white-space: nowrap;
}
dd {
display: inline-flex;
align-items: center;
flex-wrap: wrap;
span {
padding: 0 10px;
margin: 0 10px;
color: #333;
font-size: 14px;
line-height: 1.8;
white-space: nowrap;
#app .el-table thead{
cursor: pointer;
&:hover {
color: #CC221C;
}
&.active {
border-radius: 4px;
color: #fff;
background-color: #CC221C;
}
}
}
}
}
.el-button--primary{
@extend .action-btn;
}
}
#app .el-table th{
background-color: $--color-primary!important;
font-size: 16px;
font-weight: normal;
}
#app .el-select{
display: unset;
}
.required{
margin-right: 5px;
color: #F56C6C;
.pagination {
margin: 20px 0;
text-align: center;
button,.number{
color: rgba(0,0,0,.65) !important;
background-color: transparent !important;
border: 1px solid rgba(0, 0, 0, 0.15) !important;
border-radius: 4px !important;
}
.p-title{
display: flex;
align-items: center;
button i{
color: #333;
}
.active{
color: #fff !important;
background-color: #CC221C !important;
}
}
.el-table{
border-radius: 8px;
border: 1px solid rgba(0, 0, 0, 0.06);
border-bottom: 0;
.cell{
color: rgba(0, 0, 0, 0.85);
font-size: 14px;
.el-checkbox{
&:before{
content: '';
display: inline-block;
width: 3px;
height: 15px;
content: '全选';
margin-right: 5px;
background-color: $--color-primary;
color: rgba(0, 0, 0, 0.85);
font-size: 14px;
opacity: 0;
}
}
}
th{
background: rgba(0, 0, 0, 0.04)!important;
font-size: 14px;
color: rgba(0, 0, 0, 0.85);
font-weight: normal;
.cell{
.el-checkbox{
&:before{
opacity: 1;
}
}
}
[v-cloak] {
display: none;
}
.header_tab{
box-shadow:0px 0px 25px 2px rgba(255,45,45,0.14);
.el-tabs__nav-wrap::after{
background-color: #fff;
.el-checkbox__inner{
border-radius: 4px;
transition: none !important;
}
.el-tabs__header{
padding: 20px 60px 0;
margin: 0;
z-index: 999;
background-color: #fff;
.el-checkbox__input.is-indeterminate .el-checkbox__inner{
background-color: #FFFFFF;
border-color: #DCDFE6;
}
.el-switch__core{
background-color: #bfbfbf;
}
.el-tabs__item{
padding: 0 30px;
font-size: 15px;
.el-switch__label--right{
z-index: 2;
position: absolute;
right: 8px;
margin-left: 0;
color: #fff !important;
}
.el-switch__label--right.is-active{
left: 8px;
right: auto;
}
.el-switch__label--right span{
font-size: 12px;
}
}
.tabs{
display: flex;
align-items: center;
padding: 20px 1.5% 20px;
margin-bottom: 20px;
z-index: 999;
background-color: #fff;
padding: 0 24px;
border-bottom: 1px solid rgba(0,0,0,.06);
.item{
padding: 12px 20px;
margin-right: 10px;
color:#606266;
line-height: 1;
border-radius: 4px;
background-color: #fff;
border: 1px solid #dcdfe6;
position: relative;
padding: 20px 0;
margin-right: 40px;
font-size: 16px;
color: rgba(0, 0, 0, 0.65);
cursor: pointer;
&:after{
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 3px;
border-bottom: 3px solid transparent;
border-radius: 2px;
}
&.active{
color: #fff;
background-color: $--color-primary;
border-color: $--color-primary;
font-weight: 500;
color: rgba(0, 0, 0, 0.85);
}
&.active:after{
border-bottom-color: $--color-primary;
}
}
}
.btns{
display: flex;
justify-content: center;
margin-top: 20px;
button{
height: 30px;
padding: 0 30px;
margin: 0 15px;
.el-message{
padding: 11px 20px;
.el-message__icon{
font-size: 16px;
}
.el-message__content{
font-size: 14px;
color: #333;
line-height: 30px;
background-color: #fff;
border: 1px solid #ededed;
color: rgba(0, 0, 0, 0.65);
}
.el-icon-close{
font-size: 14px;
color: #92998d;
}
.el-message--success{
border: 1px solid #B7EB8F;
background: #F6FFED;
.el-message__icon{
color: #00c700;
}
}
.el-message--warning{
border: 1px solid #FFE58F;
background: #FFFBE6;
.el-message__icon{
color: #ffa900;
}
}
}
.el-message-box{
padding-bottom: 24px;
.el-message-box__header{
padding: 32px 32px 12px 50px;
span{
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
font-weight: 500;
}
}
.el-message-box__status{
top: -30px;
}
.el-message-box__status + .el-message-box__message{
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
}
.el-message-box__btns{
padding-right: 32px;
&.el-icon-warning{
color: #ffa900;
}
}
.el-button--primary,.el-button--primary:hover, .el-button--primary:focus{
background: #CC221C;
}
}
.el-dialog__wrapper{
.el-dialog{
border-radius: 4px;
cursor: pointer;
&.submit{
color: #fff;
background-color: #e80909;
border-color: #e80909;
.el-dialog__header{
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
.el-dialog__title{
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
}
}
.el-dialog__footer{
padding: 10px 16px;
border-top: 1px solid rgba(0, 0, 0, 0.06);
.el-button{
font-size: 14px;
border-radius: 4px;
border-color: rgba(0, 0, 0, 0.15);
}
&:hover{
opacity: .8;
}
&:focus{
outline: none;
}
}
.upload-wrap{
position: relative;
display: flex;
justify-content: center;
align-items: center;
padding: 34px 0;
.el-button{
span{
display: flex;
align-items: center;
color: rgba(0, 0, 0, 0.65);
font-size: 14px;
img{
margin-right: 8px;
}
}
}
&>.el-button{
margin-right: 32px;
}
.el-upload-list{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
}
.link{
position: absolute;
bottom: -20px;
left: 0;
width: 100%;
text-align: center;
}
&.lg{
padding-bottom: 50px;
}
}
@media(max-width: 1600px){
.el-table{
.el-switch__label--right.is-active{
left: 8px;
}
.userRadio .el-radio{
margin-right: 10px!important;
}
.userRadio .el-radio__input{
display: none!important;
}

@ -8,6 +8,7 @@ body,
}
body {
font-family: 'PingFang SC', "Helvetica Neue", Helvetica, "microsoft yahei", arial, STHeiTi, sans-serif;
font-size: 14px;
background: $bg-grey;
background: rgba(0, 0, 0, 0.02);
}

@ -1,52 +1,62 @@
$borderColor: #ececec;
$borderColor: rgba(0, 0, 0, 0.06);;
.box{
display: flex;
justify-content: space-between;
width: 90%;
margin: 0 auto;
.left,.middle,.right{
border: 1px solid $borderColor;
}
.left,.right{
width: 160px;
padding: 10px;
margin-right: 10px;
box-sizing: border-box;
.left{
width: 240px;
margin-right: 24px;
}
.left{
.title{
padding: 10px 0;
padding: 16px 24px;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
}
.time{
font-size: 14px;
color: #444;
color: #CC221C;
text-align: center;
}
.progress{
padding: 16px;
margin: 0 24px 24px;
box-shadow: 0px 0px 32px 0px rgba(0, 0, 0, 0.04);
.ans{
margin-bottom: 8px;
font-size: 14px;
color: rgba(0, 0, 0, 0.85);
text-align: center;
}
}
.item{
padding: 10px 0;
padding: 16px 24px;
margin-bottom: 10px;
border-bottom: 1px solid $borderColor;
.type,.total{
color: #444;
font-size: 12px;
&:first-child{
border-top: 1px solid $borderColor;
}
.total{
margin: 10px 0;
.type{
margin-bottom: 13px;
color: rgba(0, 0, 0, 0.85);
font-size: 14px;
}
.nums{
display: flex;
flex-wrap: wrap;
span{
width: 24px;
margin: 2px 1px;
line-height: 24px;
width: 32px;
margin: 0 8px 8px 0;
line-height: 30px;
text-align: center;
color: #888;
font-size: 10px;
color: rgba(0, 0, 0, 0.25);
font-size: 14px;
box-sizing: border-box;
border: 1px solid #e6e6e6;
border-radius: 50%;
}
.active{
color: #fff;
background-color: #e80909;
border-color: #e80909;
background-color: #CC221C;
border-color: #CC221C;
}
}
}
@ -55,36 +65,30 @@ $borderColor: #ececec;
text-align: center;
}
}
.middle{
flex: 1;
margin-right: 10px;
.right{
width: calc(100% - 264px);
height: calc(100vh - 164px);
overflow: auto;
.title{
padding: 10px;
margin-bottom: 10px;
font-size: 14px;
color: #444;
padding: 16px 24px;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
border-bottom: 1px solid $borderColor;
}
.ques{
.ques-wrap{
padding: 0 15px;
margin: 10px 0 20px;
}
.item{
margin: 10px 0 20px;
&:first-child{
margin-top: 0;
padding: 0 24px;
.ques{
margin: 16px 0;
}
.name-wrap{
display: flex;
align-items: center;
margin-bottom: 10px;
font-size: 13px;
color: #444;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
.index{
font-size: 13px;
color: #444;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
}
/deep/.input{
width: 100px;
@ -136,15 +140,3 @@ $borderColor: #ececec;
}
}
}
.right{
.time,.ans{
font-size: 14px;
color: #444;
text-align: center;
}
.ans{
margin: 20px 0 10px;
font-size: 15px;
}
}
}

@ -1,6 +1,5 @@
.list{
li{
padding-bottom: 10px;
border-top: 1px solid #f1f1f1;
&:first-child{
border-top: 0;
@ -9,43 +8,33 @@
position: relative;
display: flex;
justify-content: space-between;
padding: 10px 0 20px;
padding: 16px 0;
.avatar{
width: 40px;
height: 40px;
width: 48px;
height: 48px;
border-radius: 50%;
}
.texts{
flex: 1;
margin-left: 10px;
.title{
margin-bottom: 5px;
font-size: 14px;
margin-left: 24px;
.username{
color: $main-color;
color: rgba(0, 0, 0, 0.85);
font-size: 16px;
}
.publish{
margin: 0 5px;
color: #d6d6d6;
.desc{
margin: 8px 0;
}
.date{
color: #b5b5b5;
}
}
}
.right{
.index{
font-size: 12px;
color: #ccc;
}
color: rgba(0, 0, 0, 0.45);
font-size: 14px;
}
}
.action{
text-align: right;
margin-top: 15px;
.btn{
padding: 2px 4px;
padding: 5px 16px;
color: $main-color;
font-size: 12px;
font-size: 14px;
background-color: #fff;
border: 1px solid;
border-radius: 4px;
@ -56,6 +45,11 @@
&:first-child{
margin-right: 5px;
}
&.del{
color: rgba(0, 0, 0, 0.65);
border: 1px solid rgba(0, 0, 0, 0.15);
}
}
}
}
.reply{
@ -63,19 +57,20 @@
}
}
&.children{
padding: 0 10px 10px;
margin: 10px 0 0 30px;
background-color: #f3f4f6;
margin-left: 72px;
padding-left: 24px;
background-color: rgba(0, 0, 0, 0.02);
border-radius: 8px;
li{
border-top-color: #fff;
border-top-color: rgba(0, 0, 0, 0.06);
}
}
}
.toggle{
margin: 10px 0;
margin: 16px 0;
text-align: center;
color: $main-color;
font-size: 12px;
font-size: 14px;
span{
cursor: pointer;
}

@ -1,8 +1,5 @@
.box{
width: 90%;
margin: 0 auto;
}
.title{
margin: 0;
text-align: center;
font-size: 18px;
font-weight: 600;
@ -10,7 +7,9 @@
.metas{
display: flex;
justify-content: center;
margin: 20px 0 30px;
padding-bottom: 24px;
margin: 24px 0;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
.name{
font-size: 12px;
color: #717171;
@ -22,73 +21,103 @@
}
.tab{
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 10px;
li{
position: relative;
padding: 0 44px;
margin-right: 7px;
font-size: 13px;
line-height: 46px;
padding: 0 16px;
margin-right: 24px;
font-size: 14px;
line-height: 30px;
text-align: center;
color: #444;
border: 1px solid #ececec;
color: rgba(0, 0, 0, 0.65);
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
cursor: pointer;
&:hover{
opacity: .8;
}
&.active:after{
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 4px;
background-color: #e80909;
&.active{
color: #CC221C;
border: 1px solid #CC221C;
}
}
}
.wrap{
height: calc(100vh - 367px);
margin-top: 24px;
overflow: auto;
.item{
padding-bottom: 30px;
margin-bottom: 30px;
border-bottom: 1px dashed #f4f4f4;
.key{
font-weight: bold;
color: #333;
border: 1px solid rgba(0, 0, 0, 0.06);
border-radius: 8px;
.type{
padding: 0 24px;
margin-top: -1px;
color: rgba(0, 0, 0, 0.85);
line-height: 52px;
font-size: 14px;
background-color: #F6FFED;
border: 1px solid #B7EB8F;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
&.wrong{
border: 1px solid #FFA39E;
background: #FFF1F0;
}
&.yet{
border: 1px solid rgba(0, 0, 0, 0.06);
background: rgba(0, 0, 0, 0.04);
}
span{
margin-right: 24px;
}
}
.inner{
padding: 24px;
}
.name{
font-size: 14px;
color: #555555;
}
.meta{
margin-bottom: 16px;
}
.key{
margin-bottom: 8px;
color: rgba(0, 0, 0, 0.85);
font-size: 16px;
}
.val{
color: #757575;
color: rgba(0, 0, 0, 0.65);
font-size: 14px;
}
.answer{
.meta-mul{
display: flex;
align-items: center;
padding: 15px;
margin: 15px 0;
font-size: 12px;
border: 1px solid #e8e8e8;
background-color: #f3f2f2;
margin-bottom: 15px;
.info{
display: inline-flex;
align-items: center;
margin-right: 30px;
margin-right: 32px;
}
input{
width: 60px;
height: 28px;
padding: 0 5px;
margin-right: 5px;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
&:focus{
outline: none;
}
.meta{
padding-left: 10px;
margin: 20px 0;
font-size: 12px;
&.ans{
display: flex;
.info{
margin-right: 20px;
&:disabled{
background-color: rgba(0, 0, 0, 0.04);
color: rgba(0, 0, 0, 0.25);
cursor: not-allowed;
}
}
.key{
margin-bottom: 5px;
}
.point{
.meta{
margin: 0;
}
}
}

@ -17,11 +17,11 @@ module.exports = {
sass: {
prependData: `@import "@/styles/var.scss";`
},
postcss: {
plugins: [
postcss
]
}
// postcss: {
// plugins: [
// postcss
// ]
// }
}
},
publicPath: Setting.publicPath,

Loading…
Cancel
Save