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. 111
      src/layouts/header/index.vue
  25. 53
      src/layouts/home/index.vue
  26. 173
      src/layouts/navbar/index.vue
  27. 13
      src/libs/util.js
  28. 141
      src/pages/account/login/index.vue
  29. 12
      src/pages/account/register/index.vue
  30. 170
      src/pages/achievement/assessment/index.vue
  31. 79
      src/pages/achievement/list/examResults.vue
  32. 28
      src/pages/achievement/list/index.vue
  33. 91
      src/pages/achievement/list/practiceResults.vue
  34. 162
      src/pages/achievement/practice/index.vue
  35. 1
      src/pages/exam/detail/index.vue
  36. 182
      src/pages/exam/do/index.vue
  37. 131
      src/pages/exam/list/index.vue
  38. 282
      src/pages/index/list/index.vue
  39. 159
      src/pages/messageBoard/list/index.vue
  40. 175
      src/pages/practice/do/index.vue
  41. 30
      src/pages/practice/list/index.vue
  42. 97
      src/pages/practice/list/myPractice.vue
  43. 57
      src/pages/practice/list/randomPractice.vue
  44. 141
      src/pages/practice/randomDo/index.vue
  45. 722
      src/pages/setting/person/index.vue
  46. 149
      src/pages/wrongBook/do/index.vue
  47. 151
      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. 418
      src/styles/common.scss
  54. BIN
      src/styles/font/YouSheBiaoTiHei.ttf
  55. 3
      src/styles/layout/index.scss
  56. 196
      src/styles/pages/exam.scss
  57. 83
      src/styles/pages/messageBoard.scss
  58. 125
      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> <template>
<div class="header flex a-center j-between"> <div>
<div v-if="showBack" class="goBack" v-throttle @click="back"><i class="el-icon-arrow-left"></i>返回</div> <div class="header">
<div v-else class="logo"> <img class="system-name" src="../../assets/img/system-fullname.png">
<img src="../../assets/img/logo-fill.png"> <el-dropdown class="user-wrap" @command="userCommand">
</div> <div class="user">
<div class="header-right">
<div class="header-user-con">
<div class="user" @click="toPerson">
<el-avatar :size="40" :src="avatar"></el-avatar> <el-avatar :size="40" :src="avatar"></el-avatar>
<span class="user-avator">{{userName}}</span> <span class="username">{{userName}}</span>
</div> </div>
<el-divider class="m-l-20" direction="vertical"></el-divider> <el-dropdown-menu slot="dropdown">
<el-button type="text" class="m-l-20" @click="loginout">退出</el-button> <el-dropdown-item command="person">个人资料</el-dropdown-item>
</div> <el-dropdown-item command="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div> </div>
</div> </div>
</template> </template>
@ -42,79 +41,43 @@ export default {
...mapActions('user', [ ...mapActions('user', [
'logout' 'logout'
]), ]),
toPerson(){ userCommand(command){
this.$router.push('/setting/person') console.log(command)
}, if(command == 'person'){
loginout() { this.$router.push('/setting/person')
this.logout() }else{
}, this.logout()
back(){ }
this.$router.back()
} }
}, },
}; };
</script> </script>
<style lang="scss" scoped> <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 { .header {
position: relative; position: relative;
box-sizing: border-box; display: flex;
width: 100%; justify-content: space-between;
height: 60px; align-items: center;
padding: 20px 40px 20px 24px;
font-size: 16px; font-size: 16px;
color: #333; color: #333;
border-bottom: 1px solid #efefef; background-color: #fff;
box-shadow: 0 0 1.5625rem 0.125rem rgba(255, 45, 45, 0.14); box-sizing: border-box;
.logo { .system-name {
float: left; width: 326px;
width: 170px;
height: 40px;
margin-left: 20px;
img{
height: 100%;
}
} }
.header-right { .user-wrap {
float: right; display: flex;
padding-right: 50px; align-items: center;
.header-user-con {
display: flex; .user{
height: 70px; display: inline-flex;
align-items: center; align-items: center;
.user{ cursor: pointer;
display: inline-flex; .username{
align-items: center; margin-left: 10px;
cursor: pointer; color: #000;
} font-size: 16px;
}
.el-button--text{
color: #333;
}
.el-divider--vertical{
width: 2px;
height: 15px;
}
.el-divider{
background-color: #333;
}
.user-avator {
margin-left: 10px;
img {
display: block;
width: 40px;
height: 40px;
border-radius: 50%;
} }
} }
} }

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

@ -1,70 +1,193 @@
<template> <template>
<div class="header_tab" v-show="hideSidebar"> <div>
<el-tabs v-model="activeName" @tab-click="tabChange"> <div class="logo">
<el-tab-pane v-for="(tab,index) in tabList" :key="index" :label="tab.title" :name="tab.index"></el-tab-pane> <img src="../../assets/img/logo-full.png" width="125">
</el-tabs> </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> </div>
</template> </template>
<script> <script>
import { mapState } from 'vuex'
import bus from '@/libs/bus';
import Setting from '@/setting';
export default { export default {
data() { data() {
return { return {
activeName: this.$route.path, collapse: false,
tabList: [ defaultMenus: [
{ {
icon: 'el-icon-folder-checked', icon: 'menu-icon icon-index',
index: '/index/list', index: '/index/list',
title: '我的首页' title: '我的首页'
}, },
{ {
icon: 'el-icon-lx-home', icon: 'menu-icon icon-practise',
index: '/practice/list', index: '/practice/list',
title: '我的练习' title: '我的练习'
}, },
{ {
icon: 'el-icon-lx-cascades', icon: 'menu-icon icon-exam',
index: '/exam/list', index: '/exam/list',
title: '我的考试' title: '我的考试'
}, },
{ {
icon: 'el-icon-lx-copy', icon: 'menu-icon icon-ache',
index: '/achievement/list', index: '/achievement/list',
title: '我的成绩' title: '我的成绩'
}, },
{ {
icon: 'el-icon-lx-copy', icon: 'menu-icon icon-wrong',
index: '/wrongBook/list', index: '/wrongBook/list',
title: '错题练习' title: '错题练习'
}, },
{ {
icon: 'el-icon-chat-dot-round', icon: 'menu-icon icon-msg',
index: '/messageBoard/list', index: '/messageBoard/list',
title: '交流互动' title: '交流互动'
} }
], ],
hideNavList: ['article','matchDetail','courseSection','personalCenter'] menus: [],
actives: {
index: ['index-add'],
}
}; };
}, },
computed: { computed: {
hideSidebar() { onRoutes() {
let route = this.$route.name let actives = this.actives
if(this.hideNavList.includes(route)) return false for(let i in this.actives){
return true if(actives[i].includes(this.$route.name)) return `/${i}`
} }
return this.$route.path
},
...mapState('auth', [
'routes'
])
},
created() {
this.initMenu()
// Event Bus
bus.$on('collapse', msg => {
this.collapse = msg;
bus.$emit('collapse-content', msg);
});
}, },
methods: { methods: {
tabChange(tab){ initMenu(){
location.hash = tab.name if(Setting.dynamicRoute){
this.$router.push(tab.name) 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> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
/deep/.el-tabs__item:focus{ .nav{
outline: none; height: 100%;
box-shadow: none !important; 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> </style>

@ -1,5 +1,6 @@
import cookies from './util.cookies' import cookies from './util.cookies'
import {_local,_session} from './util.db' import {_local,_session} from './util.db'
import { Message } from 'element-ui'
const util = { const util = {
cookies, cookies,
@ -103,6 +104,18 @@ const util = {
} }
x.send() 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 export default util

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

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

@ -1,104 +1,106 @@
<template> <template>
<div class="box"> <div class="box">
<h1 class="title">{{paperName }}</h1> <breadcrumb :data="'我的成绩/考试成绩'"></breadcrumb>
<div class="metas"> <div class="page">
<div class="m-r-20"> <div class="page-content">
<span class="name">总分</span> <h1 class="title">{{paperName }}</h1>
<span class="val">100</span> <div class="metas">
</div> <div class="m-r-20">
<div class="m-r-20" v-if="score != null"> <span class="name">总分</span>
<span class="name">得分</span> <span class="val">100</span>
<span class="val">{{score}}</span>
</div>
<div class="m-r-20">
<span class="name">考试时长</span>
<span class="val">{{timeSpent != null && timeSpent != '--' ? (timeSpent / 60).toFixed(2) + '分钟' : timeSpent}}</span>
</div>
<div>
<span class="name">排名</span>
<span class="val">{{ranking === 0 ? 1 : ranking}}</span>
</div>
</div>
<ul class="tab">
<template v-for="(item,index) in tabs">
<li v-if="item.show" :key="index" :class="{active: active == item.id}" @click="tabChange(item.id)">{{item.name}}</li>
</template>
</ul>
<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>
</div> <div class="m-r-20" v-if="score != null">
<div class="meta"> <span class="name">得分</span>
<p class="key">题干</p> <span class="val">{{score}}</span>
<p class="val" v-html="item.question_stem"></p>
</div>
<div class="meta">
<p class="key">选项</p>
<div class="val">
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p>
</div> </div>
</div> <div class="m-r-20">
<div class="meta ans"> <span class="name">考试时长</span>
<div class="info"> <span class="val">{{timeSpent != null && timeSpent != '--' ? (timeSpent / 60).toFixed(2) + '分钟' : timeSpent}}</span>
<p class="key">正确答案</p>
<p class="val">{{item.answer}}</p>
</div> </div>
<div class="info"> <div>
<p class="key">学生答案</p> <span class="name">排名</span>
<p class="val">{{item.user_answer}}</p> <span class="val">{{ranking === 0 ? 1 : ranking}}</span>
</div> </div>
</div> </div>
<div class="meta" v-if="item.typeName == '简答题'">
<p class="key">附件</p> <ul class="tab">
<div class="val"> <template v-for="(item,index) in tabs">
<template v-if="item.fileUrl"> <li v-if="item.show" :key="index" :class="{active: active == item.id}" @click="tabChange(item.id)">{{item.name}}</li>
<div v-for="(url,fileName) in item.fileUrl" :key="fileName"> </template>
<el-button type="text" @click="preview(url,0)">{{fileName}}</el-button> </ul>
<el-button type="primary" size="mini" @click="download(fileName,url,0)">下载</el-button>
<div class="wrap">
<div class="item" v-for="(item,index) in curType" :key="index">
<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>
</div>
<div class="meta">
<p class="key">选项</p>
<div class="val">
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p>
</div>
</div>
<div class="meta-mul">
<div class="info" v-if="active != 4">
<p class="key">正确答案</p>
<p class="val">{{item.answer}}</p>
</div>
<div class="info">
<p class="key">学生答案</p>
<p class="val">{{item.user_answer}}</p>
</div>
</div> </div>
</template> <div class="meta" v-if="item.typeName == '简答题'">
<template v-if="item.videoAudio"> <p class="key">附件</p>
<div v-for="(url,fileName) in item.videoAudio" :key="fileName"> <div class="val">
<el-button type="text" @click="preview(url,1)">{{fileName}}</el-button> <template v-if="item.fileUrl">
<el-button type="primary" size="mini" @click="download(fileName,url,1)">下载</el-button> <div v-for="(url,fileName) in item.fileUrl" :key="fileName">
<el-button type="text" @click="preview(url,0)">{{fileName}}</el-button>
<el-button type="primary" size="mini" @click="download(fileName,url,0)">下载</el-button>
</div>
</template>
<template v-if="item.videoAudio">
<div v-for="(url,fileName) in item.videoAudio" :key="fileName">
<el-button type="text" @click="preview(url,1)">{{fileName}}</el-button>
<el-button type="primary" size="mini" @click="download(fileName,url,1)">下载</el-button>
</div>
</template>
</div>
</div> </div>
</template> <div class="meta">
<p class="key">答案解析</p>
<p class="val" v-html="item.answer_analysis"></p>
</div>
</div>
</div> </div>
</div> </div>
<div class="meta">
<p class="key">答案解析</p> <div v-show="playAuth" class="el-image-viewer__wrapper" :class="{over: isDownload}" style="z-index: 2000">
<p class="val" v-html="item.answer_analysis"></p> <div class="el-image-viewer__mask"></div>
<span class="el-image-viewer__btn el-image-viewer__close" @click="closePlayer"><i class="el-icon-circle-close" style="color: #fff"></i></span>
<div class="player" id="player"></div>
</div> </div>
<pdf :visible.sync="pdfVisible" :src.sync="pdfSrc"></pdf>
<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> </div>
<div v-show="playAuth" class="el-image-viewer__wrapper" :class="{over: isDownload}" style="z-index: 2000">
<div class="el-image-viewer__mask"></div>
<span class="el-image-viewer__btn el-image-viewer__close" @click="closePlayer"><i class="el-icon-circle-close" style="color: #fff"></i></span>
<div class="player" id="player"></div>
</div>
<pdf :visible.sync="pdfVisible" :src.sync="pdfSrc"></pdf>
<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>
</template> </template>
<script> <script>
import setBackground from '@/mixins/setBackground'
import file from '@/mixins/file' import file from '@/mixins/file'
import { mapState } from 'vuex' import { mapState } from 'vuex'
import pdf from '@/components/pdf' import pdf from '@/components/pdf'
import breadcrumb from '@/components/breadcrumb'
import util from '@/libs/util'
export default { export default {
mixins: [ setBackground,file ], mixins: [ file ],
data() { data() {
return { return {
paperName: '', paperName: '',
@ -131,7 +133,7 @@ export default {
curType: [] curType: []
}; };
}, },
components: { pdf }, components: { pdf,breadcrumb },
computed: { computed: {
...mapState('user', [ ...mapState('user', [
'userId' 'userId'
@ -184,11 +186,17 @@ export default {
curType.forEach(n => { curType.forEach(n => {
if(!n.options){ if(!n.options){
let options = {} let options = {}
let answer = []
for(let i in n){ for(let i in n){
if(i.includes('option') && n[i]){ if(i.includes('option') && n[i]){
options[i.replace('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 n.options = options
} }
}) })

@ -1,52 +1,49 @@
<template> <template>
<div> <div>
<el-card shadow="hover" class="m-b-20"> <div class="tool">
<div> <ul class="filter">
<div class="p-title m-b-20">筛选</div> <li>
<div class="flex"> <label>搜索</label>
<div> <el-input placeholder="请输入考核名称" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
<el-input placeholder="请输入考核名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input> </li>
</div> </ul>
</div> </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 :data="listData" class="table" ref="table" stripe header-align="center" row-key="id"> <el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> <el-table-column type="index" width="100" label="序号" align="center">
<el-table-column type="index" width="100" label="序号" align="center"> <template slot-scope="scope">
<template slot-scope="scope"> {{scope.$index + (page - 1) * pageSize + 1}}
{{scope.$index + (page - 1) * pageSize + 1}} </template>
</template> </el-table-column>
</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="timeSpent" label="用时(分钟)" align="center">
<el-table-column prop="timeSpent" label="用时(分钟)" align="center"> <template slot-scope="scope">
<template slot-scope="scope"> {{scope.row.timeSpent != '--' ? (scope.row.timeSpent / 60).toFixed(2) : scope.row.timeSpent}}
{{scope.row.timeSpent != '--' ? (scope.row.timeSpent / 60).toFixed(2) : scope.row.timeSpent}} </template>
</template> </el-table-column>
</el-table-column> <el-table-column prop="submitTime" label="考试时间" align="center"></el-table-column>
<el-table-column prop="submitTime" label="考试时间" align="center"></el-table-column> <el-table-column prop="thisScore" label="得分" align="center">
<el-table-column prop="thisScore" label="得分" align="center"> <template slot-scope="scope">
<template slot-scope="scope"> {{scope.row.thisScore == null ? '未批阅' : scope.row.thisScore}}
{{scope.row.thisScore == null ? '未批阅' : scope.row.thisScore}} </template>
</template> </el-table-column>
</el-table-column> <el-table-column label="操作" align="center" width="180">
<el-table-column label="操作" align="center" width="180"> <template slot-scope="scope">
<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>
</template> </el-table-column>
</el-table-column> </el-table>
</el-table> <div class="pagination">
<div class="pagination"> <el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" :current-page="page">
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" :current-page="page"> </el-pagination>
</el-pagination> </div>
</div>
</el-card>
</div> </div>
</template> </template>
<script> <script>
import { mapState,mapActions } from 'vuex' import { mapState,mapActions } from 'vuex'
import util from '@/libs/util'
export default { export default {
data() { data() {
return { return {

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

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

@ -1,98 +1,100 @@
<template> <template>
<div class="box"> <div class="box">
<h1 class="title">{{paperName }}</h1> <breadcrumb :data="'我的成绩/练习成绩'"></breadcrumb>
<div class="metas"> <div class="page">
<div class="m-r-20"> <div class="page-content">
<span class="name">总分</span> <h1 class="title">{{paperName }}</h1>
<span class="val">100</span> <div class="metas">
</div> <div class="m-r-20">
<div class="m-r-20" v-if="score != 'null'"> <span class="name">总分</span>
<span class="name">得分</span> <span class="val">100</span>
<span class="val">{{score}}</span>
</div>
<div>
<span class="name">考试时长</span>
<span class="val">{{duration}}分钟</span>
</div>
</div>
<ul class="tab">
<template v-for="(item,index) in tabs">
<li v-if="item.show" :key="index" :class="{active: active == item.id}" @click="tabChange(item.id)">{{item.name}}</li>
</template>
</ul>
<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>
<div class="info"> <div class="m-r-20" v-if="score != 'null'">
<p class="key">得分</p> <span class="name">得分</span>
<p class="val">{{item.questionScore}}</p> <span class="val">{{score}}</span>
</div> </div>
</div> <div>
<div class="meta"> <span class="name">考试时长</span>
<p class="key">题干</p> <span class="val">{{duration}}分钟</span>
<p class="val" v-html="item.questionStem"></p>
</div>
<div class="meta">
<p class="key">选项</p>
<div class="val">
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p>
</div> </div>
</div> </div>
<div class="meta ans">
<div class="info"> <ul class="tab">
<p class="key">正确答案</p> <template v-for="(item,index) in tabs">
<p class="val">{{item.answer}}</p> <li v-if="item.show" :key="index" :class="{active: active == item.id}" @click="tabChange(item.id)">{{item.name}}</li>
</div> </template>
<div class="info"> </ul>
<p class="key">学生答案</p>
<p class="val">{{item.userAnswer}}</p> <div class="wrap">
</div> <div class="item" v-for="(item,index) in curType" :key="index">
</div> <div class="type" :class="{wrong: item.questionScore == 0,yet: !item.isCorrecting}">
<div class="meta" v-if="item.isSub"> <span>序号{{index+1}}</span>
<p class="key">附件</p> <span v-if="item.isCorrecting">得分{{item.questionScore}}</span>
<div class="val"> </div>
<template v-if="item.fileUrl"> <div class="inner">
<div v-for="(url,fileName) in item.fileUrl" :key="fileName"> <div class="meta">
<el-button type="text" @click="preview(url,0)">{{fileName}}</el-button> <p class="key">题干</p>
<el-button type="primary" size="mini" @click="download(fileName,url,0)">下载</el-button> <p class="val" v-html="item.questionStem"></p>
</div>
<div class="meta">
<p class="key">选项</p>
<div class="val">
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p>
</div>
</div>
<div class="meta-mul">
<div class="info" v-if="active != 4">
<p class="key">正确答案</p>
<p class="val">{{item.answer}}</p>
</div>
<div class="info">
<p class="key">学生答案</p>
<p class="val">{{item.userAnswer}}</p>
</div>
</div> </div>
</template> <div class="meta" v-if="item.isSub">
<template v-if="item.videoAudio"> <p class="key">附件</p>
<div v-for="(url,fileName) in item.videoAudio" :key="fileName"> <div class="val">
<el-button type="text" @click="preview(url,1)">{{fileName}}</el-button> <template v-if="item.fileUrl">
<el-button type="primary" size="mini" @click="download(fileName,url,1)">下载</el-button> <div v-for="(url,fileName) in item.fileUrl" :key="fileName">
<el-button type="text" @click="preview(url,0)">{{fileName}}</el-button>
<el-button type="primary" size="mini" @click="download(fileName,url,0)">下载</el-button>
</div>
</template>
<template v-if="item.videoAudio">
<div v-for="(url,fileName) in item.videoAudio" :key="fileName">
<el-button type="text" @click="preview(url,1)">{{fileName}}</el-button>
<el-button type="primary" size="mini" @click="download(fileName,url,1)">下载</el-button>
</div>
</template>
</div>
</div> </div>
</template> <div class="meta">
<p class="key">答案解析</p>
<p class="val" v-html="item.answerAnalysis"></p>
</div>
</div>
</div> </div>
</div> </div>
<div class="meta">
<p class="key">答案解析</p> <div v-show="playAuth" class="el-image-viewer__wrapper" :class="{over: isDownload}" style="z-index: 2000">
<p class="val" v-html="item.answerAnalysis"></p> <div class="el-image-viewer__mask"></div>
<span class="el-image-viewer__btn el-image-viewer__close" @click="closePlayer"><i class="el-icon-circle-close" style="color: #fff"></i></span>
<div class="player" id="player"></div>
</div> </div>
<pdf :visible.sync="pdfVisible" :src.sync="pdfSrc"></pdf>
</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>
<span class="el-image-viewer__btn el-image-viewer__close" @click="closePlayer"><i class="el-icon-circle-close" style="color: #fff"></i></span>
<div class="player" id="player"></div>
</div>
<pdf :visible.sync="pdfVisible" :src.sync="pdfSrc"></pdf>
</div> </div>
</template> </template>
<script> <script>
import setBackground from '@/mixins/setBackground'
import file from '@/mixins/file' import file from '@/mixins/file'
import { mapState } from 'vuex' import { mapState } from 'vuex'
import pdf from '@/components/pdf' import pdf from '@/components/pdf'
import breadcrumb from '@/components/breadcrumb'
import util from '@/libs/util'
export default { export default {
mixins: [ setBackground,file ], mixins: [ file ],
data() { data() {
return { return {
paperName: '', paperName: '',
@ -128,7 +130,7 @@ export default {
curType: [] curType: []
}; };
}, },
components: { pdf }, components: { pdf,breadcrumb },
computed: { computed: {
...mapState('user', [ ...mapState('user', [
'userId' 'userId'
@ -151,10 +153,10 @@ export default {
if(n.typeName == '填空题'){ if(n.typeName == '填空题'){
let answer = [] let answer = []
for(let i in n){ 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.answer = answer.join('')
n.userAnswer = n.userAnswer ? n.userAnswer.replace(/&lt;&gt;/g,'|') : '' n.userAnswer = n.userAnswer ? n.userAnswer.split('&lt;&gt;').filter(n => n).join(',') : ''
} }
if(n.fileUrl) n.fileUrl = JSON.parse(n.fileUrl) if(n.fileUrl) n.fileUrl = JSON.parse(n.fileUrl)
if(n.videoAudio) n.videoAudio = JSON.parse(n.videoAudio) 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 == '填空题') answer.push(n[i])
} }
} }
if(n.typeName == '填空题') n.answer = answer.join('|') if(n.typeName == '填空题') n.answer = answer.join('')
n.options = options n.options = options
} }
}) })

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

@ -1,113 +1,110 @@
<template> <template>
<div class="box"> <div>
<div class="left"> <breadcrumb :data="'我的考试/考试'"></breadcrumb>
<p class="title">答题卡</p> <div class="box">
<div class="page left">
<div class="item"> <p class="title">{{assessmentName}}</p>
<p class="type">单选题</p> <p class="time" v-countdown="time">{{time}}</p>
<p class="total">{{singleCount}}合计{{singlePoint}}</p> <div class="progress">
<div class="nums"> <div class="ans">答题进度({{progress}}%)</div>
<span v-for="n in singleCount" :class="{active: n <= singleAnsweredCount}" :key="n">{{n}}</span> <el-progress :percentage="progress" :show-text="false"></el-progress>
</div>
</div>
<div class="item">
<p class="type">多选题</p>
<p class="total">{{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>
<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>
<div class="nums">
<span v-for="n in fillBlankCount" :class="{active: n <= fillBlankAnsweredCount}" :key="n">{{n}}</span>
</div> </div>
</div> <div>
<div class="item"> <div class="item">
<p class="type">简答题</p> <p class="type">单选题({{singleCount}}合计{{singlePoint}})</p>
<p class="total">{{briefAnswerCount}}合计{{briefAnswerScore}}</p> <div class="nums">
<div class="nums"> <span v-for="n in singleCount" :class="{active: n <= singleAnsweredCount}" :key="n">{{n}}</span>
<span v-for="n in briefAnswerCount" :class="{active: n <= briefAnswerAnsweredCount}" :key="n">{{n}}</span> </div>
</div>
<div class="item">
<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">判断题({{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">填空题({{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">简答题({{briefAnswerCount}}合计{{briefAnswerScore}})</p>
<div class="nums">
<span v-for="n in briefAnswerCount" :class="{active: n <= briefAnswerAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="btn">
<el-button size="mini" type="primary" @click="save">提交考试</el-button>
</div>
</div> </div>
</div> </div>
<div class="btn">
<el-button size="mini" type="primary" @click="save">提交考试</el-button>
</div>
</div>
<div class="middle"> <div class="page right">
<div class="ques">
<template v-for="(subject,k) in subjects"> <template v-for="(subject,k) in subjects">
<div class="item" v-if="subject.length" :key="k"> <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> <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="name-wrap"> <div class="ques" v-for="(item,index) in subject" :key="index">
<span class="index">{{index+1}}.</span> <div class="name-wrap">
<div class="name" :class="'stem' + k + index" v-html="item.questionStem"></div> <span class="index">{{index+1}}.</span>
</div> <div class="name" :class="'stem' + k + index" v-html="item.questionStem"></div>
<div class="media" :id="item.mediaEleId"></div> </div>
<div class="options"> <div class="media" :id="item.mediaEleId"></div>
<template v-if="item.typeId == 1 || item.typeId == 3"> <div class="options">
<div class="option"> <template v-if="item.typeId == 1 || item.typeId == 3">
<el-radio-group v-model="item.val" @change.once="updateProgress"> <div class="option">
<el-radio v-for="(option,i) in item.options" :key="i" :label="i"> <el-radio-group v-model="item.val" @change.once="updateProgress">
<el-radio v-for="(option,i) in item.options" :key="i" :label="i">
{{i}}.{{item.options[i]}}
</el-radio>
</el-radio-group>
</div>
</template>
<template v-if="item.typeId == 2">
<el-checkbox-group v-model="item.val" @change="updateProgress">
<el-checkbox class="option-check" :label="i" v-for="(option,i) in item.options" :key="i">
{{i}}.{{item.options[i]}} {{i}}.{{item.options[i]}}
</el-radio> </el-checkbox>
</el-radio-group> </el-checkbox-group>
</div> </template>
</template> <template v-if="item.typeId == 4">
<template v-if="item.typeId == 2"> <el-upload
<el-checkbox-group v-model="item.val" @change="updateProgress"> class="upload"
<el-checkbox class="option-check" :label="i" v-for="(option,i) in item.options" :key="i"> :before-upload="file => beforeUpload(file,item)"
{{i}}.{{item.options[i]}} :on-remove="(file, fileList) => handleRemove(file, fileList, item)"
</el-checkbox> :on-error="uploadError"
</el-checkbox-group> :on-success="(res, file, fileList) => uploadSuccess(res, file, fileList, item)"
</template> :before-remove="beforeRemove"
<template v-if="item.typeId == 4"> :on-exceed="handleExceed"
<el-upload :action="api.fileupload"
class="upload" >
:before-upload="file => beforeUpload(file,item)" <el-button type="primary" class="ml20">上传文件</el-button>
:on-remove="(file, fileList) => handleRemove(file, fileList, item)" </el-upload>
:on-error="uploadError" <el-input type="textarea" rows="5" v-model="item.val" @input="updateProgress"></el-input>
:on-success="(res, file, fileList) => uploadSuccess(res, file, fileList, item)" </template>
:before-remove="beforeRemove" </div>
:on-exceed="handleExceed"
:action="api.fileupload"
>
<el-button type="primary" class="ml20">上传文件</el-button>
</el-upload>
<el-input type="textarea" rows="5" v-model="item.val" @input="updateProgress"></el-input>
</template>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
</div> </div>
</div> </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> </div>
</template> </template>
<script> <script>
import { mapState,mapGetters,mapActions } from 'vuex' import { mapState,mapGetters,mapActions } from 'vuex'
import setBackground from '@/mixins/setBackground'
import examDo from '@/mixins/examDo' import examDo from '@/mixins/examDo'
import util from '@/libs/util' import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default { export default {
mixins: [ setBackground,examDo ], mixins: [ examDo ],
data() { data() {
return { return {
subjects: [], subjects: [],
@ -141,12 +138,13 @@ export default {
submiting: false submiting: false
}; };
}, },
components: {breadcrumb},
computed: { computed: {
...mapState('user', [ ...mapState('user', [
'userId' 'userId'
]), ]),
...mapState('exam', [ ...mapState('exam', [
'testPaperId','assessmentId','teacherId','classId','countdown' 'testPaperId','assessmentId','teacherId','classId','countdown','assessmentName'
]), ]),
}, },
directives: { directives: {
@ -307,7 +305,7 @@ export default {
} }
}) })
.catch(err => { .catch(err => {
this.$message.success('考试结束!') util.successMsg('考试结束!')
this.$router.back() this.$router.back()
}) })
},1000) },1000)
@ -320,7 +318,7 @@ export default {
if(n.uploading) uploading = true if(n.uploading) uploading = true
}) })
}) })
if(uploading) return this.$message.warning('视频正在上传,请稍候再试') if(uploading) return util.warningMsg('视频正在上传,请稍候再试')
if(this.submiting) return false if(this.submiting) return false
this.submiting = true this.submiting = true
let data1 = [] let data1 = []
@ -373,7 +371,7 @@ export default {
this.$post(`${this.api.calculationScore}`,data1) this.$post(`${this.api.calculationScore}`,data1)
.then(res => { .then(res => {
this.isSubmit = true this.isSubmit = true
this.$message.success(this.isDone ? '考试已结束,已经自动为您提交考试!' : '提交成功') util.successMsg(this.isDone ? '考试已结束,已经自动为您提交考试!' : '提交成功')
this.$router.back() this.$router.back()
}) })
.catch(err => {}) .catch(err => {})

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

@ -1,143 +1,141 @@
<template> <template>
<div> <div>
<el-card shadow="hover" class="m-b-10"> <breadcrumb :data="'我的首页'"></breadcrumb>
<div class="title m-b-20"><img src="../../../assets/img/index/assesment.png" alt=""> 我的考试安排</div> <div class="page">
<div> <div class="tabs">
<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> <a class="item active">考试日历</a>
</div> </div>
</el-card> <div class="page-content">
<template v-if="listData.length">
<el-card shadow="hover" class="m-b-30"> <div class="tool">
<div class="text-center text-grey m-b-10">待考试列表</div> <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-table <el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center">
:data="listData" <el-table-column type="index" width="100" label="序号" align="center">
ref="table" <template
row-key="id" slot-scope="scope"
class="table" >{{scope.$index + (page - 1) * pageSize + 1}}</template>
stripe </el-table-column>
header-align="center" <el-table-column prop="assessmentName" label="考试名称" align="center"></el-table-column>
> <el-table-column prop="startTime" label="考试开始时间" align="center"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center"> <el-table-column prop="endTime" label="考试结束时间" align="center"></el-table-column>
<template <el-table-column label="操作" width="200">
slot-scope="scope" <template slot-scope="scope">
>{{scope.$index + (page - 1) * pageSize + 1}}</template> <el-button type="text" @click="toExam(scope.row)" v-if="scope.row.assessmentState == 2" :disabled="scope.row.studentState == 2">进入考试</el-button>
</el-table-column> </template>
<el-table-column prop="assessmentName" label="考试名称" align="center"></el-table-column> </el-table-column>
<el-table-column prop="startTime" label="考试开始时间" align="center"></el-table-column> </el-table>
<el-table-column prop="endTime" label="考试结束时间" align="center"></el-table-column> <div class="pagination">
<el-table-column label="操作" width="200"> <el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
<template slot-scope="scope"> </div>
<el-button type="text" @click="toExam(scope.row)" v-if="scope.row.assessmentState == 2" :disabled="scope.row.studentState == 2">进入考试</el-button> </template>
</template> <div class="none" v-else>暂无考试安排</div>
</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>
</div> </div>
</el-card> </div>
<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"> <div class="page">
<el-card shadow="hover" class="flex-1 m-r-20"> <div class="tabs">
<div class="text-center text-grey m-b-10">平均分 {{avgScore}}&emsp;&emsp;总时长 {{totalDuration}}h</div> <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"
>{{scope.$index + (page - 1) * pageSize + 1}}</template>
</el-table-column>
<el-table-column prop="practiseName" label="练习试卷名称" align="center"></el-table-column>
<el-table-column prop="startTime" label="开始时间" align="center">
<template slot-scope="scope">
<p>{{scope.row.startTime | defaultShow}}</p>
</template>
</el-table-column>
<el-table-column prop="duration" label="练习时长(分钟)" align="center">
<template slot-scope="scope">
<p>{{scope.row.duration | defaultShow}}</p>
</template>
</el-table-column>
<el-table-column prop="lastScore" label="得分" align="center">
<template slot-scope="scope">
<p>{{scope.row.lastScore | defaultShow}}</p>
</template>
</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>
</div>
</template>
<div class="none" v-else>暂无练习安排</div>
</div>
</div>
<el-table <div class="flex j-between">
:data="practiceData" <div class="page" style="width: calc(50% - 12px)">
ref="table" <div class="tabs">
row-key="id" <a class="item active">练习时长</a>
class="table"
stripe
header-align="center"
>
<el-table-column type="index" width="100" label="序号" align="center">
<template
slot-scope="scope"
>{{scope.$index + (page - 1) * pageSize + 1}}</template>
</el-table-column>
<el-table-column prop="practiseName" label="练习试卷名称" align="center"></el-table-column>
<el-table-column prop="startTime" label="开始时间" align="center">
<template slot-scope="scope">
<p>{{scope.row.startTime | defaultShow}}</p>
</template>
</el-table-column>
<el-table-column prop="duration" label="练习时长(分钟)" align="center">
<template slot-scope="scope">
<p>{{scope.row.duration | defaultShow}}</p>
</template>
</el-table-column>
<el-table-column prop="lastScore" label="得分" align="center">
<template slot-scope="scope">
<p>{{scope.row.lastScore | defaultShow}}</p>
</template>
</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>
</div> </div>
</el-card> <div class="page-content">
<!-- <template v-if="practiceDurationList.length"> -->
<el-card shadow="hover" class="flex-1"> <div class="chart" id="practiceDuration"></div>
<div class="chart" id="practiceDuration"></div> <!-- </template>
</el-card> <div class="none" v-else>暂无图标数据</div> -->
</div>
</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>
</template>
<div class="none" style="padding: 0;line-height: 400px;" v-else>暂无图标数据</div>
</div>
</div>
</div> </div>
<el-card shadow="hover" class="m-b-10"> <div class="page">
<div class="title"><img src="../../../assets/img/index/achievement.png" alt=""> 我的成绩</div> <div class="tabs">
</el-card> <a class="item active">教师回复</a>
<el-card shadow="hover" class="m-b-30"> </div>
<div class="chart" id="achievement"></div> <div class="page-content">
</el-card> <template v-if="msgList.length">
<ul class="list">
<el-card shadow="hover" class="m-b-10"> <li v-for="(item,index) in msgList" :key="index">
<div class="title"><img src="../../../assets/img/index/msg.png" alt=""> 回复反馈</div> <div class="item">
</el-card> <div class="inner">
<el-card shadow="hover"> <img class="avatar" :src="item.userAvatars" alt="">
<ul class="list"> <div class="texts">
<li v-for="(item,index) in msgList" :key="index"> <div class="userName">{{item.userName}}</div>
<div class="item"> <div class="desc" v-html="item.content"></div>
<div class="inner"> <div class="date">{{item.createTime}}</div>
<img class="avatar" :src="item.userAvatars" alt=""> </div>
<div class="texts"> <div class="action">
<div class="title"> <button v-if="item.userId != userId" class="btn" @click="showReply(item)">回复</button>
<span class="username">{{item.userName}}</span> <button v-else class="btn del" @click="delMsg(item)">删除</button>
<span class="publish">发表于</span> </div>
<span class="date">{{item.createTime}}</span> </div>
<div class="reply" v-if="item.showReply">
<quill :border="true" v-model="item.replyContent" :toTop="false" :height="150" />
<div class="m-t-10 text-right">
<el-button type="primary" size="mini" @click="submitComment(item)">提交</el-button>
</div>
</div> </div>
<div class="desc" v-html="item.content"></div>
</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>
</div>
<div class="reply" v-if="item.showReply">
<quill :border="true" v-model="item.replyContent" :toTop="false" :height="150" />
<div class="m-t-10 text-right">
<el-button type="primary" size="mini" @click="submitComment(item)">提交</el-button>
</div> </div>
</div> </li>
</div> </ul>
</li> </template>
</ul> <div class="none" v-else>暂无教师回复</div>
</el-card> </div>
</div>
</div> </div>
</template> </template>
<script> <script>
@ -145,6 +143,7 @@ import { mapState,mapGetters,mapActions } from 'vuex'
import quill from '@/components/quill' import quill from '@/components/quill'
import echarts from 'echarts' import echarts from 'echarts'
import util from '@/libs/util' import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default { export default {
data() { data() {
return { return {
@ -190,7 +189,8 @@ export default {
} }
}, },
components: { components: {
quill quill,
breadcrumb
}, },
mounted() { mounted() {
let now = util.formatDate('yyyy-MM-dd') let now = util.formatDate('yyyy-MM-dd')
@ -331,7 +331,7 @@ export default {
}, },
delMsg(row){ delMsg(row){
this.$post(`${this.api.waitReplyDel}?userId=${this.userId}&bid=${row.bid}`).then(res => { this.$post(`${this.api.waitReplyDel}?userId=${this.userId}&bid=${row.bid}`).then(res => {
this.$message.success('删除成功') util.successMsg('删除成功')
this.getMsg() this.getMsg()
}).catch(res => {}) }).catch(res => {})
}, },
@ -343,7 +343,7 @@ export default {
schoolId: this.clientId, schoolId: this.clientId,
} }
this.$post(this.api.saveComment,data).then(res => { this.$post(this.api.saveComment,data).then(res => {
this.$message.success('提交成功') util.successMsg('提交成功')
row.replyContent = '' row.replyContent = ''
this.getMsg() this.getMsg()
}).catch(res => {}) }).catch(res => {})
@ -368,4 +368,24 @@ export default {
.chart{ .chart{
height: 400px; 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> </style>

@ -1,85 +1,83 @@
<template> <template>
<div> <div>
<el-card shadow="hover"> <breadcrumb :data="'交流互动'"></breadcrumb>
<ul class="list"> <div class="page">
<li v-for="(item,index) in listData" :key="index"> <div class="tabs">
<div class="item"> <a class="item active">交流互动</a>
<div class="inner"> </div>
<img class="avatar" :src="item.userAvatars" alt=""> <div class="page-content">
<div class="texts"> <template v-if="listData.length">
<div class="title"> <ul class="list">
<span class="username">{{item.userName}}</span> <li v-for="(item,index) in listData" :key="index">
<span class="publish">发表于</span> <div class="item">
<span class="date">{{item.createTime}}</span>
</div>
<div class="desc" v-html="item.content"></div>
</div>
<div class="right">
<p class="index">[ {{index+1}} # ]</p>
</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>
</div>
<div class="reply" v-if="item.showReply">
<quill :border="true" v-model="item.replyContent" :toTop="false" :height="150" />
<div class="m-t-10 text-right">
<el-button type="primary" size="mini" @click="submitComment(item)">提交</el-button>
</div>
</div>
<ul class="list children" v-if="item.showChildren">
<li v-for="(reply,i) in item.children" :key="i">
<div class="inner"> <div class="inner">
<img class="avatar" :src="reply.userAvatars" alt=""> <img class="avatar" :src="item.userAvatars" alt="">
<div class="texts"> <div class="texts">
<div class="title"> <div class="userName">{{item.userName}}</div>
<span class="username">{{reply.userName}}</span> <div class="desc" v-html="item.content"></div>
<span class="publish">发表于</span> <div class="date">{{item.createTime}}</div>
<span class="date">{{reply.commentTime}}</span> </div>
</div> <div class="action">
<div class="desc" v-html="reply.content"></div> <button v-if="item.userId != userId" class="btn" @click="showReply(item)">回复</button>
<button v-else class="btn del" @click="delMsg(item)">删除</button>
</div> </div>
</div> </div>
<div class="action"> <div class="reply" v-if="item.showReply">
<button v-if="reply.commentUserId != userId" class="btn" @click="showReply(reply)">回复</button> <quill :border="true" v-model="item.replyContent" :toTop="false" :height="150" />
<button v-else class="btn" @click="delReply(reply,i,index)">删除</button>
</div>
<div class="reply" v-if="reply.showReply">
<quill :border="true" v-model="reply.replyContent" :toTop="false" :height="150" />
<div class="m-t-10 text-right"> <div class="m-t-10 text-right">
<el-button type="primary" size="mini" @click="submitReply(reply)">提交</el-button> <el-button type="primary" size="mini" @click="submitComment(item)">提交</el-button>
</div> </div>
</div> </div>
</li>
</ul> <ul class="list children" v-if="item.showChildren">
<div v-if="item.getCommentReplyNum" class="toggle"><span @click="toggleReply(item)">{{item.showChildren ? '收起所有回复' : `查看所有${item.getCommentReplyNum}条回复`}} <i class="el-icon-arrow-down"></i></span></div> <li v-for="(reply,i) in item.children" :key="i">
<div class="inner">
<img class="avatar" :src="reply.userAvatars" alt="">
<div class="texts">
<div class="userName">{{reply.userName}}</div>
<div class="desc" v-html="reply.content"></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 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" />
<div class="m-t-10 text-right">
<el-button type="primary" size="mini" @click="submitReply(reply)">提交</el-button>
</div>
</div>
</li>
</ul>
<div v-if="item.getCommentReplyNum" class="toggle"><span @click="toggleReply(item)">{{item.showChildren ? '收起所有回复' : `查看所有${item.getCommentReplyNum}条回复`}} <i class="el-icon-arrow-down"></i></span></div>
</div>
</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>
</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" />
<div class="m-t-10 text-right">
<el-button type="primary" size="mini" @click="submitMsg">提交</el-button>
</div> </div>
</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>
</div>
<div class="input-wrap">
<quill class="m-t-20" :border="true" v-model="content" :toTop="false" :height="150" />
<div class="m-t-10 text-right">
<el-button type="primary" size="mini" @click="submitMsg">提交</el-button>
</div> </div>
</div> </div>
</el-card> </div>
</div> </div>
</template> </template>
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import quill from '@/components/quill' import quill from '@/components/quill'
import breadcrumb from '@/components/breadcrumb'
import util from '@/libs/util'
export default { export default {
data() { data() {
return { return {
@ -96,7 +94,8 @@ export default {
]) ])
}, },
components: { components: {
quill quill,
breadcrumb
}, },
mounted() { mounted() {
this.getData() this.getData()
@ -147,13 +146,13 @@ export default {
}, },
delMsg(row){ delMsg(row){
this.$post(`${this.api.delMessageBoard}?bid=${row.bid}`).then(res => { this.$post(`${this.api.delMessageBoard}?bid=${row.bid}`).then(res => {
this.$message.success('删除成功') util.successMsg('删除成功')
this.getData() this.getData()
}).catch(res => {}) }).catch(res => {})
}, },
submitComment(row){ submitComment(row){
let content = row.replyContent 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, "") content = content.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g, "")
let data = { let data = {
bid: row.bid, bid: row.bid,
@ -162,7 +161,7 @@ export default {
schoolId: this.clientId, schoolId: this.clientId,
} }
this.$post(this.api.saveComment,data).then(res => { this.$post(this.api.saveComment,data).then(res => {
this.$message.success('提交成功') util.successMsg('提交成功')
row.replyContent = '' row.replyContent = ''
this.getData() this.getData()
}).catch(res => {}) }).catch(res => {})
@ -170,19 +169,19 @@ export default {
delReply(row,i,index){ delReply(row,i,index){
if(row.identification == 1){ if(row.identification == 1){
this.$post(`${this.api.delComment}?commentId=${row.commentId}`).then(res => { this.$post(`${this.api.delComment}?commentId=${row.commentId}`).then(res => {
this.$message.success('删除成功') util.successMsg('删除成功')
this.listData[index].children.splice(i,1) this.listData[index].children.splice(i,1)
}).catch(res => {}) }).catch(res => {})
}else{ }else{
this.$post(`${this.api.delReply}?replyId=${row.replyId}`).then(res => { this.$post(`${this.api.delReply}?replyId=${row.replyId}`).then(res => {
this.$message.success('删除成功') util.successMsg('删除成功')
this.listData[index].children.splice(i,1) this.listData[index].children.splice(i,1)
}).catch(res => {}) }).catch(res => {})
} }
}, },
submitReply(row){ submitReply(row){
let content = row.replyContent 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, "") content = content.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g, "")
let data = { let data = {
bid: row.bid, bid: row.bid,
@ -192,13 +191,13 @@ export default {
userId: this.userId, userId: this.userId,
} }
this.$post(this.api.saveReply,data).then(res => { this.$post(this.api.saveReply,data).then(res => {
this.$message.success('提交成功') util.successMsg('提交成功')
row.replyContent = '' row.replyContent = ''
this.getData() this.getData()
}).catch(res => {}) }).catch(res => {})
}, },
submitMsg(){ 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, "") this.content = this.content.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g, "")
let data = { let data = {
content: this.content, content: this.content,
@ -206,7 +205,7 @@ export default {
userId: this.userId userId: this.userId
} }
this.$post(this.api.saveMessageBoard,data).then(res => { this.$post(this.api.saveMessageBoard,data).then(res => {
this.$message.success('提交成功') util.successMsg('提交成功')
this.content = '' this.content = ''
this.getData() this.getData()
}).catch(res => {}) }).catch(res => {})
@ -217,4 +216,14 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
@import "@/styles/pages/messageBoard.scss"; @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> </style>

@ -1,111 +1,109 @@
<template> <template>
<div class="box"> <div>
<div class="left"> <breadcrumb :data="'我的练习/练习'"></breadcrumb>
<p class="title">答题卡</p> <div class="box">
<div class="page left">
<div class="item"> <p class="title">{{practiseName}}</p>
<p class="type">单选题</p> <div class="progress">
<p class="total">{{singleCount}}合计{{singlePoint}}</p> <div class="ans">答题进度({{progress}}%)</div>
<div class="nums"> <el-progress :percentage="progress" :show-text="false"></el-progress>
<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>
<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>
<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>
<div class="nums">
<span v-for="n in fillBlankCount" :class="{active: n <= fillBlankAnsweredCount}" :key="n">{{n}}</span>
</div> </div>
</div> <div>
<div class="item"> <div class="item">
<p class="type">简答题</p> <p class="type">单选题({{singleCount}}合计{{singlePoint}})</p>
<p class="total">{{briefAnswerCount}}合计{{briefAnswerScore}}</p> <div class="nums">
<div class="nums"> <span v-for="n in singleCount" :class="{active: n <= singleAnsweredCount}" :key="n">{{n}}</span>
<span v-for="n in briefAnswerCount" :class="{active: n <= briefAnswerAnsweredCount}" :key="n">{{n}}</span> </div>
</div>
<div class="item">
<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">判断题({{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">填空题({{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">简答题({{briefAnswerCount}}合计{{briefAnswerScore}})</p>
<div class="nums">
<span v-for="n in briefAnswerCount" :class="{active: n <= briefAnswerAnsweredCount}" :key="n">{{n}}</span>
</div>
</div>
<div class="btn">
<el-button size="mini" type="primary" @click="save">提交练习</el-button>
</div>
</div> </div>
</div> </div>
<div class="btn">
<el-button size="mini" type="primary" @click="save">提交练习</el-button>
</div>
</div>
<div class="middle"> <div class="page right">
<div class="ques">
<template v-for="(subject,k) in subjects"> <template v-for="(subject,k) in subjects">
<div class="item" v-if="subject.length" :key="k"> <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> <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="name-wrap"> <div class="ques" v-for="(item,index) in subject" :key="index">
<span class="index">{{index+1}}.</span> <div class="name-wrap">
<div class="name" :class="'stem' + k + index" v-html="item.questionStem"></div> <span class="index">{{index+1}}.</span>
</div> <div class="name" :class="'stem' + k + index" v-html="item.questionStem"></div>
<div class="media" :id="item.mediaEleId"></div> </div>
<div class="options"> <div class="media" :id="item.mediaEleId"></div>
<template v-if="item.name == '单项选择' || item.name == '判断题'"> <div class="options">
<div class="option"> <template v-if="item.name == '单项选择' || item.name == '判断题'">
<el-radio-group v-model="item.val" @change.once="updateProgress"> <div class="option">
<el-radio v-for="(option,i) in item.options" :key="i" :label="i"> <el-radio-group v-model="item.val" @change.once="updateProgress">
<el-radio v-for="(option,i) in item.options" :key="i" :label="i">
{{i}}.{{item.options[i]}}
</el-radio>
</el-radio-group>
</div>
</template>
<template v-if="item.name == '多项选择'">
<el-checkbox-group v-model="item.val" @change="updateProgress">
<el-checkbox class="option-check" :label="i" v-for="(option,i) in item.options" :key="i">
{{i}}.{{item.options[i]}} {{i}}.{{item.options[i]}}
</el-radio> </el-checkbox>
</el-radio-group> </el-checkbox-group>
</div> </template>
</template> <template v-if="item.name == '简答题'">
<template v-if="item.name == '多项选择'"> <el-upload
<el-checkbox-group v-model="item.val" @change="updateProgress"> class="upload"
<el-checkbox class="option-check" :label="i" v-for="(option,i) in item.options" :key="i"> :before-upload="file => beforeUpload(file,item)"
{{i}}.{{item.options[i]}} :on-remove="(file, fileList) => handleRemove(file, fileList, item)"
</el-checkbox> :on-error="uploadError"
</el-checkbox-group> :on-success="(res, file, fileList) => uploadSuccess(res, file, fileList, item)"
</template> :before-remove="beforeRemove"
<template v-if="item.name == '简答题'"> :on-exceed="handleExceed"
<el-upload :action="api.fileupload"
class="upload" >
:before-upload="file => beforeUpload(file,item)" <el-button type="primary" class="ml20">上传文件</el-button>
:on-remove="(file, fileList) => handleRemove(file, fileList, item)" </el-upload>
:on-error="uploadError" <el-input type="textarea" rows="5" v-model="item.val" @input="updateProgress"></el-input>
:on-success="(res, file, fileList) => uploadSuccess(res, file, fileList, item)" </template>
:before-remove="beforeRemove" </div>
:on-exceed="handleExceed"
:action="api.fileupload"
>
<el-button type="primary" class="ml20">上传文件</el-button>
</el-upload>
<el-input type="textarea" rows="5" v-model="item.val" @input="updateProgress"></el-input>
</template>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
</div> </div>
</div> </div>
<div class="right">
<div class="ans">答题进度</div>
<el-progress :percentage="progress"></el-progress>
</div>
</div> </div>
</template> </template>
<script> <script>
import { mapState,mapGetters,mapActions } from 'vuex' import { mapState,mapGetters,mapActions } from 'vuex'
import setBackground from '@/mixins/setBackground'
import examDo from '@/mixins/examDo' import examDo from '@/mixins/examDo'
import util from '@/libs/util' import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default { export default {
mixins: [ setBackground,examDo ], mixins: [ examDo ],
data() { data() {
return { return {
identification: this.$store.state.practice.identification, identification: this.$store.state.practice.identification,
@ -135,15 +133,16 @@ export default {
isSubmit: false, isSubmit: false,
isDone: false, isDone: false,
totalLen: 0, totalLen: 0,
submiting: false submiting: false,
}; };
}, },
components: {breadcrumb},
computed: { computed: {
...mapState('user', [ ...mapState('user', [
'userId' 'userId'
]), ]),
...mapState('practice', [ ...mapState('practice', [
'practiseId','paperId','isContinue' 'practiseId','paperId','isContinue','practiseName'
]), ]),
}, },
mounted() { mounted() {

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

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

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

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

@ -1,240 +1,152 @@
<template> <template>
<div style="width:100%;height:100%;display:flex;align-items: center;flex-direction:column"> <div>
<div class="header"> <div class="page">
<img :src="avatar" class="HeadPortrait" /> <div class="tabs">
<div style="color:#cb221c;font-size:14px;font-family:MicrosoftYaHei;margin-top:5px;"> <a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{item}}</a>
<el-upload :action="this.api.fileupload" :on-success="changeAvatar">
<div>点击更改头像</div>
</el-upload>
</div> </div>
</div> <div class="page-content">
<div v-if="active == 'first'">
<div class="card"> <el-form>
<p class="block-title" style="display: flex;justify-content: space-between;align-items: center;"> <ul class="list">
用户信息 <li>
<el-button type="success" size="small" v-throttle @click="save">更新资料</el-button> <label>头像</label>
</p> <div class="avatar-wrap">
<p class="meta-title">个人信息</p> <img :src="avatar" class="avatar" />
<div class="information"> <el-upload :action="this.api.fileupload" :data="{userId:this.userId}" name="file" :limit="1" :on-success="changeAvatar">
<div class="block"> <el-button size="small"><img src="../../../assets/img/upload.png" alt=""> 上传头像</el-button>
<p class="block-left">姓名</p> </el-upload>
<div class="block-right"> </div>
<input </li>
id="username" <li>
type="text" <label>姓名</label>
v-model="personalInformation.userName" <div>
/> <el-input v-model="personalInformation.userName" clearable></el-input>
<div class="ii"> </div>
<label for="username"> </li>
<i class="el-icon-edit" style="color:rgba(255, 255, 255, 1)"></i> <li>
</label> <label>性别</label>
</div> <div>
</div> <el-select v-model="personalInformation.sex">
</div> <el-option v-for="item in sexList" :key="item.value" :label="item.name" :value="item.value"></el-option>
</el-select>
<div class="block"> </div>
<p class="block-left">性别</p> </li>
<el-select <li>
v-model="personalInformation.sex" <label>所在国家</label>
placeholder <div>
> <el-select
<el-option v-model="personalInformation.countries"
v-for="item in sexList" placeholder
:key="item.value" >
:label="item.name" <el-option
:value="item.value" v-for="item in countryList"
></el-option> :key="item.value"
</el-select> :label="item.label"
</div> :value="item.value"
></el-option>
<div class="block"> </el-select>
<p class="block-left">所在国家</p> </div>
<el-select </li>
v-model="personalInformation.countries" <li>
placeholder <label>所在省份</label>
> <div>
<el-option <el-select
v-for="item in countryList" v-model="personalInformation.provinceId"
:key="item.value" placeholder
:label="item.label" @change="id => getCity(id,1)"
:value="item.value" >
></el-option> <el-option
</el-select> v-for="item in provinceList"
</div> :key="item.provinceId"
:label="item.provinceName"
<div class="block"> :value="item.provinceId"
<p class="block-left">所在省份</p> ></el-option>
<el-select </el-select>
v-model="personalInformation.provinceId" </div>
placeholder </li>
@change="id => getCity(id)" <li>
> <label>所在省市</label>
<el-option <div>
v-for="item in provinceList" <el-select
:key="item.provinceId" v-model="personalInformation.cityId"
:label="item.provinceName" placeholder
:value="item.provinceId" :disabled="personalInformation.provinceId ? false : true"
></el-option> >
</el-select> <el-option
</div> v-for="item in cityList"
:key="item.cityId"
<div class="block"> :label="item.cityName"
<p class="block-left">所在省市</p> :value="item.cityId"
<el-select ></el-option>
v-model="personalInformation.cityId" </el-select>
placeholder </div>
:disabled="personalInformation.provinceId ? false : true" </li>
> <li>
<el-option <label>出生年月日</label>
v-for="item in cityList" <div>
:key="item.cityId" <el-date-picker
:label="item.cityName" v-model="personalInformation.dateBirth"
:value="item.cityId" :clearable="false"
></el-option> class="block-right"
</el-select> type="date">
</el-date-picker>
</div>
</li>
<li>
<label>证件</label>
<div>
<el-input v-model="personalInformation.idnumber" clearable></el-input>
</div>
</li>
<li>
<label>教育程度</label>
<div>
<el-select
v-model="personalInformation.educationDegree"
placeholder="请选择教育程度"
>
<el-option
v-for="(item,index) in educationDegreeList"
:key="index"
:label="item.name"
:value="item.value"
></el-option>
</el-select>
</div>
</li>
</ul>
</el-form>
</div> </div>
<div v-else>
<div class="block"> <ul class="list">
<p class="block-left">出生年月日</p> <li>
<el-date-picker <label>用户账号</label>
v-model="personalInformation.dateBirth" <div>
:clearable="false" <el-input v-model="personalInformation.account" clearable></el-input>
class="block-right" </div>
type="date"> </li>
</el-date-picker> <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>
<div style="margin-top: 32px">
<div class="block"> <el-button type="primary" size="small" v-throttle @click="save">更新</el-button>
<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>
</div>
<div class="block">
<p class="block-left">教育程度</p>
<el-select
v-model="personalInformation.educationDegree"
placeholder="请选择教育程度"
>
<el-option
v-for="(item,index) in educationDegreeList"
:key="index"
:label="item.name"
:value="item.value"
></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>
</div>
</div> -->
<div class="block">
<p class="block-left">密码</p>
<div class="near-right">
<el-button size="small" @click="bindPassword">更换密码</el-button>
</div>
</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> </div>
</div> </div>
</div> </div>
@ -265,10 +177,18 @@
</template> </template>
<script> <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 { export default {
data() { data() {
return { return {
active: 'first',
tabs: {
first: '用户信息',
second: '账号信息'
},
personalInformation: { personalInformation: {
name:'', name:'',
workNumber:'', workNumber:'',
@ -302,9 +222,8 @@ export default {
} }
], ],
form: {}, form: {},
provinceList: this.$store.state.provinceList, // provinceList:[],
cityList: [], // cityList: [],
//
educationDegreeList: [ educationDegreeList: [
{ {
name: '专科', name: '专科',
@ -334,11 +253,10 @@ export default {
}, },
computed: { computed: {
...mapState('user', [ ...mapState('user', [
'userId','avatar' 'userId','avatar','userName'
]), ]),
}, },
mounted() { mounted() {
console.log(33,this.avatar)
this.getdata(); this.getdata();
this.getProvince() this.getProvince()
this.getSchoolData() this.getSchoolData()
@ -347,6 +265,9 @@ export default {
...mapActions('user', [ ...mapActions('user', [
'setAvatar','setUserName' 'setAvatar','setUserName'
]), ]),
tabChange(index){
this.active = index
},
getProvince(){ getProvince(){
this.$get(this.api.queryProvince).then(res => { this.$get(this.api.queryProvince).then(res => {
this.provinceList = res.data.list this.provinceList = res.data.list
@ -378,7 +299,7 @@ export default {
this.$get(`${this.api.getAccount}?account=${this.form.account}`).then(res => { this.$get(`${this.api.getAccount}?account=${this.form.account}`).then(res => {
if(res.data.userInfo){ if(res.data.userInfo){
this.accountRepeat = true this.accountRepeat = true
this.$message.warning('该账号已存在') util.warningMsg('该账号已存在')
}else{ }else{
this.accountRepeat = false this.accountRepeat = false
} }
@ -388,16 +309,18 @@ export default {
changeAvatar(res) { changeAvatar(res) {
this.setAvatar(res.data.filesResult.fileUrl) this.setAvatar(res.data.filesResult.fileUrl)
}, },
uploadHeadImg: function() {
this.$el.querySelector('.hiddenInput').click();
},
getdata() { getdata() {
this.$get(`${this.api.userinfo}?userId=${this.userId}`) this.$get(`${this.api.userinfo}?userId=${this.userId}`)
.then(res => { .then(res => {
this.personalInformation = res.data.userInfo this.personalInformation = res.data.userInfo
this.personalInformation.countries = '中国' this.personalInformation.countries = '中国'
this.personalInformation.clientName = this.schoolList.find(n => n.id == this.personalInformation.clientId).clientName
this.curPassword = this.personalInformation.password this.curPassword = this.personalInformation.password
this.$nextTick(() => { this.$nextTick(() => {
if(this.personalInformation.provinceId){ if(this.personalInformation.provinceId){
this.getCityData() this.getCityData(1)
} }
}) })
}) })
@ -408,16 +331,13 @@ export default {
bindPassword() { bindPassword() {
this.passwordVisible = true this.passwordVisible = true
}, },
forgetPassword(){
this.$message.warning('请联系学校管理员重置密码')
},
editPassword() { editPassword() {
if(!this.passwordForm.password) return this.$message.warning('请输入原密码') if(!this.passwordForm.password) return util.warningMsg('请输入原密码')
if(!this.passwordForm.newPassword) return this.$message.warning('请输入新密码') if(!this.passwordForm.newPassword) return util.warningMsg('请输入新密码')
if(!this.passwordForm.reNewPassword) return this.$message.warning('请确认新密码') if(!this.passwordForm.reNewPassword) return util.warningMsg('请确认新密码')
if(this.passwordForm.newPassword.length < 6 || this.passwordForm.reNewPassword.length < 6) return this.$message.warning('请输入6位数以上的密码') if(this.passwordForm.newPassword.length < 6 || this.passwordForm.reNewPassword.length < 6) return util.warningMsg('请输入6位数以上的密码')
if(this.passwordForm.newPassword !== this.passwordForm.reNewPassword) return this.$message.warning('输入的新密码不一致,请重新确认') if(this.passwordForm.newPassword !== this.passwordForm.reNewPassword) return util.warningMsg('输入的新密码不一致,请重新确认')
if(this.curPassword === this.passwordForm.newPassword) return this.$message.warning('原密码跟新密码不能一致') if(this.curPassword === this.passwordForm.newPassword) return util.warningMsg('原密码跟新密码不能一致')
let data = { let data = {
userId: this.personalInformation.userId, userId: this.personalInformation.userId,
@ -426,11 +346,11 @@ export default {
this.$post(this.api.userinfoUpdate,data) this.$post(this.api.userinfoUpdate,data)
.then(res => { .then(res => {
if(res.success){ if(res.success){
this.$message.success('更换成功') util.successMsg('更换成功')
this.curPassword = this.passwordForm.newPassword this.curPassword = this.passwordForm.newPassword
this.passwordVisible = false this.passwordVisible = false
}else{ }else{
this.$message.error('更换失败') util.errorMsg('更换失败')
} }
}) })
.catch(err => { .catch(err => {
@ -445,10 +365,10 @@ export default {
} }
}, },
save() { 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.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 this.$message.warning('该账号已存在') if(this.accountRepeat) return util.warningMsg('该账号已存在')
if(this.personalInformation.phone && !/^1[3456789]\d{9}$/.test(this.personalInformation.phone)) return this.$message.warning('请输入正确的手机号') 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 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 util.warningMsg('请输入正确的邮箱')
let personalInformation = this.personalInformation let personalInformation = this.personalInformation
let userInfoEntity = { let userInfoEntity = {
idnumber: personalInformation.idnumber, idnumber: personalInformation.idnumber,
@ -470,275 +390,47 @@ export default {
this.$post(this.api.userinfoUpdate,data).then(res => { this.$post(this.api.userinfoUpdate,data).then(res => {
if(res.success){ if(res.success){
this.setUserName(personalInformation.userName) this.setUserName(personalInformation.userName)
this.$message.success('提交成功') util.successMsg('提交成功')
this.$router.back() this.$router.back()
}else{ }else{
this.$message.error('提交失败') util.errorMsg('提交失败')
} }
}).catch(res => {}); }).catch(res => {})
} }
} }
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.header{ /deep/.page{
text-align: center; .page-content{
} padding-top: 0;
.header /deep/.el-upload-list__item-name { .list{
display: none; li{
} display: flex;
align-items: center;
.header /deep/.el-icon-upload-success{ padding: 16px 0;
display: none; border-bottom: 1px solid rgba(0, 0, 0, 0.06);
} label{
width: 180px;
.header /deep/.el-upload-list__item-status-label{ color: rgba(0, 0, 0, 0.85);
display: none; font-size: 16px;
} }
.header /deep/ .el-upload-list{ .avatar-wrap{
display: none; display: inline-flex;
} align-items: center;
.avatar{
/deep/.el-input__inner{ width: 64px;
height: 32px !important; height: 64px;
} margin-right: 24px;
/deep/.el-select .el-input .el-select__caret{ border-radius: 100%;
line-height: 32px; }
} }
input:focus { .el-input{
outline: 0; width: 320px;
} }
.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;
display: flex;
justify-content: space-between;
align-items: center;
.block-left {
font-family: MicrosoftYaHei;
font-size: 14px;
color: #101010;
}
input{
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 {
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;
}
} }
} }
.fold{
margin-top: 20px;
text-align: center;
i{
font-size: 22px;
color: #8e8e8e;
cursor: pointer;
&:hover{
opacity: .8;
}
}
}
}
</style> </style>

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

@ -1,88 +1,69 @@
<template> <template>
<div> <div>
<el-card shadow="hover" class="m-b-20"> <breadcrumb :data="'错题练习/错题列表'"></breadcrumb>
<div class="p-title m-b-20">筛选</div> <div class="page">
<div class="flex j-between"> <div class="tabs">
<el-form label-width="80px" inline> <a class="item active">错题列表</a>
<el-form-item class="no-mb" label="题库来源">
<el-select v-model="type" placeholder="请选择题库来源" @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">
<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">
<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>
</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> </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>
</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>
</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>
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入知识点" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
<div>
<el-button type="primary" size="small" round @click="practice">错题练习</el-button>
</div>
</div>
<el-table <el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
:data="listData" <el-table-column type="index" width="100" label="序号" align="center">
ref="table" <template
row-key="id" slot-scope="scope"
class="table" >{{scope.$index + (page - 1) * pageSize + 1}}</template>
stripe </el-table-column>
header-align="center" <el-table-column prop="questionStem" label="错题题干名称" align="center" :show-overflow-tooltip="true"></el-table-column>
@selection-change="handleSelectionChange" <el-table-column label="题目来源" width="120" align="center">
> <template>
<el-table-column type="index" width="100" label="序号" align="center"> {{type == 1 ? '考试' : '练习'}}
<template </template>
slot-scope="scope" </el-table-column>
>{{scope.$index + (page - 1) * pageSize + 1}}</template> <el-table-column prop="courses" label="对应课程" width="140" align="center"></el-table-column>
</el-table-column> <el-table-column prop="knowledgePoints" label="对应知识点" width="140" align="center"></el-table-column>
<el-table-column prop="questionStem" label="错题题干名称" align="center" :show-overflow-tooltip="true"></el-table-column> <el-table-column prop="wrongNum" label="错题次数" width="100" align="center"></el-table-column>
<el-table-column label="题目来源" width="120" align="center"> <el-table-column label="操作" width="140" align="center">
<template> <template slot-scope="scope">
{{type == 1 ? '考试' : '练习'}} <el-button type="text" @click="show(scope.row)">查看</el-button>
</template> <!-- <el-button type="text" @click="correct(scope.row)" v-if="scope.row.typeId != 4">去纠错</el-button> -->
</el-table-column> </template>
<el-table-column prop="courses" label="对应课程" width="140" align="center"></el-table-column> </el-table-column>
<el-table-column prop="knowledgePoints" label="对应知识点" width="140" align="center"></el-table-column> </el-table>
<el-table-column prop="wrongNum" label="错题次数" width="100" align="center"></el-table-column> <div class="pagination">
<el-table-column label="操作" width="140" align="center"> <el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
<template slot-scope="scope"> </div>
<el-button type="text" @click="show(scope.row)">查看</el-button>
<!-- <el-button type="text" @click="correct(scope.row)" v-if="scope.row.typeId != 4">去纠错</el-button> -->
</template>
</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>
</div> </div>
</el-card> </div>
<el-dialog title="错题详情" :visible.sync="detailVisible" width="40%"> <el-dialog title="错题详情" :visible.sync="detailVisible" width="40%">
<div class="ques"> <div class="ques">
@ -144,6 +125,7 @@
<script> <script>
import { mapState,mapActions } from 'vuex' import { mapState,mapActions } from 'vuex'
import util from '@/libs/util' import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default { export default {
data() { data() {
return { return {
@ -183,6 +165,7 @@ export default {
'userId','clientId' 'userId','clientId'
]), ]),
}, },
components: {breadcrumb},
mounted() { mounted() {
console.log(process.env.NODE_ENV) console.log(process.env.NODE_ENV)
this.getType() this.getType()
@ -289,22 +272,22 @@ export default {
} }
if(right){ if(right){
this.$post(`${this.api.removes}?qid=${quesInfo.id}&userId=${this.userId}&type=${this.type}`).then(res => { 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.correctVisible = false
this.getData() this.getData()
}).catch(err => {}) }).catch(err => {})
}else{ }else{
this.$message.error('回答错误') util.errorMsg('回答错误')
this.correctVisible = false this.correctVisible = false
} }
}, },
practice(){ practice(){
if(!this.listData.length) return this.$message.warning('错题列表为空,无法练习') if(!this.listData.length) return util.warningMsg('错题列表为空,无法练习')
let qid = [] let qid = []
this.listData.map(n => { this.listData.map(n => {
n.typeName != '简答题' && qid.push(n.questionId) n.typeName != '简答题' && qid.push(n.questionId)
}) })
if(!qid.length) return this.$message.warning('未查询到客观题,无法练习') if(!qid.length) return util.warningMsg('未查询到客观题,无法练习')
this.setInfo({ this.setInfo({
qid: qid.join(), qid: qid.join(),
type: this.type type: this.type

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

@ -16,7 +16,7 @@ const Setting = {
showProgressBar: true, showProgressBar: true,
// 接口请求地址 // 接口请求地址
// apiBaseURL: env === 'development' ? 'http://192.168.31.152:8001' : 'http://39.108.250.202:8000', // 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, modalDuration: 3,
// 接口请求返回错误时,弹窗的类型,可选值为 Message 或 Notice // 接口请求返回错误时,弹窗的类型,可选值为 Message 或 Notice

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

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

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

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

@ -8,6 +8,7 @@ body,
} }
body { body {
font-family: 'PingFang SC', "Helvetica Neue", Helvetica, "microsoft yahei", arial, STHeiTi, sans-serif;
font-size: 14px; 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{ .box{
display: flex; display: flex;
justify-content: space-between; .left{
width: 90%; width: 240px;
margin: 0 auto; margin-right: 24px;
.left,.middle,.right{
border: 1px solid $borderColor;
} }
.left,.right{ .left{
width: 160px;
padding: 10px;
margin-right: 10px;
box-sizing: border-box;
.title{ .title{
padding: 10px 0; padding: 16px 24px;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
}
.time{
font-size: 14px; font-size: 14px;
color: #444; color: #CC221C;
text-align: center; 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{ .item{
padding: 10px 0; padding: 16px 24px;
margin-bottom: 10px; margin-bottom: 10px;
border-bottom: 1px solid $borderColor; border-bottom: 1px solid $borderColor;
.type,.total{ &:first-child{
color: #444; border-top: 1px solid $borderColor;
font-size: 12px;
} }
.total{ .type{
margin: 10px 0; margin-bottom: 13px;
color: rgba(0, 0, 0, 0.85);
font-size: 14px;
} }
.nums{ .nums{
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
span{ span{
width: 24px; width: 32px;
margin: 2px 1px; margin: 0 8px 8px 0;
line-height: 24px; line-height: 30px;
text-align: center; text-align: center;
color: #888; color: rgba(0, 0, 0, 0.25);
font-size: 10px; font-size: 14px;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid #e6e6e6; border: 1px solid #e6e6e6;
border-radius: 50%; border-radius: 50%;
} }
.active{ .active{
color: #fff; color: #fff;
background-color: #e80909; background-color: #CC221C;
border-color: #e80909; border-color: #CC221C;
} }
} }
} }
@ -55,96 +65,78 @@ $borderColor: #ececec;
text-align: center; text-align: center;
} }
} }
.middle{ .right{
flex: 1; width: calc(100% - 264px);
margin-right: 10px; height: calc(100vh - 164px);
overflow: auto; overflow: auto;
.title{ .title{
padding: 10px; padding: 16px 24px;
margin-bottom: 10px; font-size: 16px;
font-size: 14px; color: rgba(0, 0, 0, 0.85);
color: #444;
border-bottom: 1px solid $borderColor; border-bottom: 1px solid $borderColor;
} }
.ques{ .ques-wrap{
.ques-wrap{ padding: 0 24px;
padding: 0 15px; .ques{
margin: 10px 0 20px; margin: 16px 0;
} }
.item{ .name-wrap{
margin: 10px 0 20px; display: flex;
&:first-child{ align-items: center;
margin-top: 0; margin-bottom: 10px;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
.index{
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
} }
.name-wrap{ /deep/.input{
display: flex; width: 100px;
align-items: center; height: 28px;
margin-bottom: 10px; padding: 0 5px;
font-size: 13px; margin: 0 5px;
color: #444; color: #444;
.index{ background-color: #fff;
font-size: 13px; border: 1px solid #ebebeb;
color: #444; box-sizing: border-box;
&:focus{
outline: none;
} }
/deep/.input{ &:disabled{
width: 100px; background-color: #e8e8e8;
height: 28px; cursor: not-allowed;
padding: 0 5px;
margin: 0 5px;
color: #444;
background-color: #fff;
border: 1px solid #ebebeb;
box-sizing: border-box;
&:focus{
outline: none;
}
&:disabled{
background-color: #e8e8e8;
cursor: not-allowed;
}
} }
} }
.options{ }
margin-top: 10px; .options{
font-size: 14px; margin-top: 10px;
color: #8b8b8b; font-size: 14px;
.option{ color: #8b8b8b;
margin: 5px 0; .option{
&.selected{ margin: 5px 0;
font-weight: bold; &.selected{
color: #555; font-weight: bold;
} color: #555;
.el-radio-group{
display: flex;
flex-direction: column;
.el-radio{
margin: 3px 0;
}
}
}
.option-check{
display: block;
margin-right: 6px;
}
/deep/.el-radio__label{
padding-left: 6px;
} }
.upload{ .el-radio-group{
margin: 20px 0 10px; display: flex;
flex-direction: column;
.el-radio{
margin: 3px 0;
}
} }
} }
.option-check{
display: block;
margin-right: 6px;
}
/deep/.el-radio__label{
padding-left: 6px;
}
.upload{
margin: 20px 0 10px;
}
} }
} }
} }
.right{
.time,.ans{
font-size: 14px;
color: #444;
text-align: center;
}
.ans{
margin: 20px 0 10px;
font-size: 15px;
}
}
} }

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

@ -1,8 +1,5 @@
.box{
width: 90%;
margin: 0 auto;
}
.title{ .title{
margin: 0;
text-align: center; text-align: center;
font-size: 18px; font-size: 18px;
font-weight: 600; font-weight: 600;
@ -10,7 +7,9 @@
.metas{ .metas{
display: flex; display: flex;
justify-content: center; justify-content: center;
margin: 20px 0 30px; padding-bottom: 24px;
margin: 24px 0;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
.name{ .name{
font-size: 12px; font-size: 12px;
color: #717171; color: #717171;
@ -22,73 +21,103 @@
} }
.tab{ .tab{
display: flex; display: flex;
justify-content: center;
align-items: center; align-items: center;
margin-bottom: 10px;
li{ li{
position: relative; position: relative;
padding: 0 44px; padding: 0 16px;
margin-right: 7px; margin-right: 24px;
font-size: 13px; font-size: 14px;
line-height: 46px; line-height: 30px;
text-align: center; text-align: center;
color: #444; color: rgba(0, 0, 0, 0.65);
border: 1px solid #ececec; border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
cursor: pointer; cursor: pointer;
&:hover{ &:hover{
opacity: .8; opacity: .8;
} }
&.active:after{ &.active{
content: ''; color: #CC221C;
position: absolute; border: 1px solid #CC221C;
top: 0;
left: 0;
width: 100%;
height: 4px;
background-color: #e80909;
} }
} }
} }
.wrap{ .wrap{
height: calc(100vh - 367px);
margin-top: 24px;
overflow: auto;
.item{ .item{
padding-bottom: 30px;
margin-bottom: 30px; margin-bottom: 30px;
border-bottom: 1px dashed #f4f4f4; border: 1px solid rgba(0, 0, 0, 0.06);
border-radius: 8px;
.key{ .type{
font-weight: bold; padding: 0 24px;
color: #333; 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; font-size: 14px;
color: #555555;
}
.meta{
margin-bottom: 16px;
}
.key{
margin-bottom: 8px;
color: rgba(0, 0, 0, 0.85);
font-size: 16px;
} }
.val{ .val{
color: #757575; color: rgba(0, 0, 0, 0.65);
font-size: 14px; font-size: 14px;
} }
.answer{ .meta-mul{
display: flex; display: flex;
align-items: center; margin-bottom: 15px;
padding: 15px;
margin: 15px 0;
font-size: 12px;
border: 1px solid #e8e8e8;
background-color: #f3f2f2;
.info{ .info{
display: inline-flex; margin-right: 32px;
align-items: center;
margin-right: 30px;
} }
} input{
.meta{ width: 60px;
padding-left: 10px; height: 28px;
margin: 20px 0; padding: 0 5px;
font-size: 12px; margin-right: 5px;
&.ans{ border: 1px solid rgba(0, 0, 0, 0.15);
display: flex; border-radius: 4px;
.info{ &:focus{
margin-right: 20px; outline: none;
}
&: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: { sass: {
prependData: `@import "@/styles/var.scss";` prependData: `@import "@/styles/var.scss";`
}, },
postcss: { // postcss: {
plugins: [ // plugins: [
postcss // postcss
] // ]
} // }
} }
}, },
publicPath: Setting.publicPath, publicPath: Setting.publicPath,

Loading…
Cancel
Save