master
yujialong 4 years ago
parent c76069a722
commit 1c1c28a93a
  1. BIN
      src/assets/img/account.png
  2. BIN
      src/assets/img/ache.png
  3. BIN
      src/assets/img/arrow-down.png
  4. BIN
      src/assets/img/checkbox.png
  5. BIN
      src/assets/img/checked.png
  6. BIN
      src/assets/img/download.png
  7. BIN
      src/assets/img/exam.png
  8. BIN
      src/assets/img/home.png
  9. BIN
      src/assets/img/index/bg.png
  10. BIN
      src/assets/img/index/bg1.png
  11. BIN
      src/assets/img/index/bg2.png
  12. BIN
      src/assets/img/index/bg3.png
  13. BIN
      src/assets/img/index/bg4.png
  14. BIN
      src/assets/img/index/bg5.png
  15. BIN
      src/assets/img/index/class.png
  16. BIN
      src/assets/img/index/del.png
  17. BIN
      src/assets/img/index/edit.png
  18. BIN
      src/assets/img/index/msg.png
  19. BIN
      src/assets/img/index/pen.png
  20. BIN
      src/assets/img/index/plan.png
  21. BIN
      src/assets/img/index/testPaper.png
  22. BIN
      src/assets/img/login_bg.png
  23. BIN
      src/assets/img/logo-full.png
  24. BIN
      src/assets/img/msg.png
  25. BIN
      src/assets/img/none.png
  26. BIN
      src/assets/img/paper.png
  27. BIN
      src/assets/img/password.png
  28. BIN
      src/assets/img/practise.png
  29. BIN
      src/assets/img/ques.png
  30. BIN
      src/assets/img/student.png
  31. BIN
      src/assets/img/system-fullname.png
  32. BIN
      src/assets/img/system-name.png
  33. BIN
      src/assets/img/system.png
  34. 0
      src/assets/img/testPaper-icon.png
  35. BIN
      src/assets/img/testPaper.png
  36. BIN
      src/assets/img/upload.png
  37. 29
      src/components/breadcrumb/index.vue
  38. 148
      src/components/testPaperDetail/index.vue
  39. 28
      src/layouts/footer/index.vue
  40. 97
      src/layouts/header/index.vue
  41. 52
      src/layouts/home/index.vue
  42. 97
      src/layouts/navbar/index.vue
  43. 18
      src/libs/util.js
  44. 130
      src/pages/account/login/index.vue
  45. 89
      src/pages/achievement/list/examResults.vue
  46. 13
      src/pages/achievement/list/index.vue
  47. 104
      src/pages/achievement/list/practiceResults.vue
  48. 100
      src/pages/achievement/list/wrongBook.vue
  49. 109
      src/pages/achievement/statistics/index.vue
  50. 140
      src/pages/assessment/detail/index.vue
  51. 260
      src/pages/assessment/doReview/index.vue
  52. 260
      src/pages/assessment/list/index.vue
  53. 45
      src/pages/assessment/list/studentTree.vue
  54. 136
      src/pages/assessment/monitor/index.vue
  55. 139
      src/pages/assessment/review/index.vue
  56. 96
      src/pages/assessment/scoreQuery/index.vue
  57. 1
      src/pages/assessment/show/index.vue
  58. 314
      src/pages/index/list/index.vue
  59. 83
      src/pages/messageBoard/list/index.vue
  60. 143
      src/pages/practice/detail/index.vue
  61. 225
      src/pages/practice/doReview/index.vue
  62. 163
      src/pages/practice/list/index.vue
  63. 35
      src/pages/practice/list/studentTree.vue
  64. 59
      src/pages/practice/result/index.vue
  65. 67
      src/pages/practice/review/index.vue
  66. 125
      src/pages/practice/scoreQuery/index.vue
  67. 170
      src/pages/quesBank/list/globalQuesBank.vue
  68. 29
      src/pages/quesBank/list/index.vue
  69. 275
      src/pages/quesBank/list/myQuesBank.vue
  70. 54
      src/pages/quesBank/list/quesBankType.vue
  71. 105
      src/pages/quesBank/list/quesDialog.vue
  72. 564
      src/pages/setting/person/index.vue
  73. 270
      src/pages/student/list/index.vue
  74. 414
      src/pages/student/list/studentSide.vue
  75. 155
      src/pages/student/list/studentTree.vue
  76. 39
      src/pages/system/list/index.vue
  77. 277
      src/pages/system/list/organization.vue
  78. 46
      src/pages/system/list/role.vue
  79. 260
      src/pages/system/list/staff.vue
  80. 301
      src/pages/system/list/staffSide.vue
  81. 218
      src/pages/testPaper/add/index.vue
  82. 98
      src/pages/testPaper/list/allTestPaper.vue
  83. 13
      src/pages/testPaper/list/index.vue
  84. 119
      src/pages/testPaper/list/myTestPaper.vue
  85. 18
      src/pages/testPaper/review/index.vue
  86. 10
      src/plugins/requests/index.js
  87. 4
      src/setting.js
  88. 10
      src/store/modules/assessment.js
  89. 4
      src/store/modules/practice.js
  90. 2
      src/store/modules/testpaper.js
  91. 6
      src/store/modules/user.js
  92. 421
      src/styles/common.scss
  93. BIN
      src/styles/font/YouSheBiaoTiHei.ttf
  94. 3
      src/styles/layout/index.scss
  95. 55
      src/styles/pages/messageBoard.scss
  96. 135
      src/styles/pages/testPaperDetail.scss
  97. 63
      src/styles/pages/tree.scss
  98. 10
      vue.config.js

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 482 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 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: 468 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 754 B

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

@ -0,0 +1,29 @@
<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){
this.pages = data.split('/')
}
}
};
</script>
<style lang="scss" scoped>
</style>

@ -1,8 +1,11 @@
<template>
<div class="box">
<breadcrumb :data="'试卷管理/试卷预览'"></breadcrumb>
<div class="page">
<div class="page-content">
<h1 class="title">{{paperName}}</h1>
<div class="metas">
<div style="margin-right: 20px;">
<div class="m-r-20">
<span class="name">总分</span>
<span class="val">100</span>
</div>
@ -20,12 +23,10 @@
<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="type">
<span>序号{{index+1}}</span>
</div>
<div class="inner">
<div class="meta">
<p class="key">题干</p>
<p class="val" v-html="item.questionStem"></p>
@ -38,12 +39,10 @@
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p>
</div>
</div>
<div class="meta ans">
<div class="info">
<div class="meta">
<p class="key">正确答案</p>
<p class="val">{{item.answer}}</p>
</div>
</div>
</template>
<div class="meta">
<p class="key">答案解析</p>
@ -52,10 +51,14 @@
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import mixins from '@/mixins/setBackground'
import { mapState } from 'vuex'
import breadcrumb from '@/components/breadcrumb'
export default {
props: ['data'],
mixins: [ mixins ],
@ -92,6 +95,7 @@ export default {
curType: [],
};
},
components: { breadcrumb },
computed: {
...mapState('user', [
'userId'
@ -209,129 +213,5 @@ export default {
</script>
<style lang="scss" scoped>
.box{
width: 90%;
margin: 0 auto;
}
.title{
text-align: center;
font-size: 18px;
font-weight: 600;
}
.metas{
display: flex;
justify-content: center;
margin: 20px 0 30px;
.name{
font-size: 12px;
color: #717171;
}
.val{
font-size: 12px;
color: #929292;
}
}
.tab{
display: flex;
align-items: center;
margin-bottom: 10px;
li{
position: relative;
padding: 0 44px;
margin-right: 7px;
font-size: 13px;
line-height: 46px;
text-align: center;
color: #444;
border: 1px solid #ececec;
cursor: pointer;
&:hover{
opacity: .8;
}
&.active:after{
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 4px;
background-color: $main-color;
}
}
}
.wrap{
.item{
padding-bottom: 30px;
margin-bottom: 30px;
border-bottom: 1px dashed #f4f4f4;
.key{
font-weight: bold;
color: #333;
font-size: 14px;
}
.val{
line-height: 1.6;
color: #757575;
font-size: 14px;
}
.answer{
display: flex;
align-items: center;
padding: 15px;
margin: 15px 0;
font-size: 12px;
border: 1px solid #e8e8e8;
background-color: #f3f2f2;
.info{
display: inline-flex;
align-items: center;
margin-right: 30px;
}
}
.meta{
padding-left: 10px;
margin: 20px 0;
font-size: 12px;
&.ans{
display: flex;
align-items: center;
.info{
margin-right: 20px;
}
}
.key{
margin-bottom: 5px;
}
.media{
margin-top: 10px;
}
}
}
}
.btns{
display: flex;
justify-content: center;
margin-top: 20px;
button{
height: 30px;
padding: 0 30px;
margin: 0 15px;
font-size: 14px;
color: #333;
line-height: 30px;
background-color: #fff;
border: 1px solid #ededed;
border-radius: 4px;
cursor: pointer;
&.submit{
color: #fff;
background-color: $main-color;
border-color: $main-color;
}
&:hover{
opacity: .8;
}
}
}
@import "@/styles/pages/testPaperDetail.scss";
</style>

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

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

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

@ -1,15 +1,16 @@
<template>
<div>
<div class="logo">
<img src="../../assets/img/logo-full.png" width="125">
</div>
<el-menu
class="sidebar-el-menu"
:default-active="onRoutes"
:collapse="collapse"
background-color="#324157"
text-color="#bfcbd9"
active-text-color="#cb221c"
background-color="#141414"
text-color="#fff"
active-text-color="#fff"
unique-opened
mode="horizontal"
router
>
<template v-for="item in menus">
@ -61,56 +62,63 @@ export default {
collapse: false,
defaultMenus: [
{
icon: 'el-icon-folder-checked',
icon: 'menu-icon icon-index',
index: '/index/list',
title: '我的首页'
},
{
icon: 'el-icon-notebook-1',
icon: 'menu-icon icon-ques',
index: '/quesBank/list',
title: '题库管理'
},
{
icon: 'el-icon-receiving',
icon: 'menu-icon icon-testpaper',
index: '/testPaper/list',
title: '试卷管理'
},
{
icon: 'el-icon-s-order',
icon: 'menu-icon icon-practise',
index: '/practice/list',
title: '练习管理'
},
{
icon: 'el-icon-data-analysis',
icon: 'menu-icon icon-exam',
index: '/assessment/list',
title: '考管理'
title: '考管理'
},
{
icon: 'el-icon-suitcase-1',
icon: 'menu-icon icon-ache',
index: '/achievement/list',
title: '成绩管理'
},
{
icon: 'el-icon-chat-dot-round',
icon: 'menu-icon icon-msg',
index: '/messageBoard/list',
title: '交流互动'
},
{
icon: 'el-icon-user',
icon: 'menu-icon icon-student',
index: '/student/list',
title: '学生管理'
},
{
icon: 'el-icon-setting',
icon: 'menu-icon icon-system',
index: '/system/list',
title: '系统设置'
}
],
menus: []
menus: [],
actives: {
index: ['index-add'],
}
};
},
computed: {
onRoutes() {
let actives = this.actives
for(let i in this.actives){
if(actives[i].includes(this.$route.name)) return `/${i}`
}
return this.$route.path
},
...mapState('auth', [
@ -122,8 +130,8 @@ export default {
// Event Bus
bus.$on('collapse', msg => {
this.collapse = msg;
bus.$emit('collapse-content', msg)
})
bus.$emit('collapse-content', msg);
});
},
methods: {
initMenu(){
@ -144,6 +152,59 @@ export default {
</script>
<style lang="scss" scoped>
.nav{
height: 100%;
background-color: #141414;
overflow: auto;
.logo{
padding: 20px 0;
text-align: center;
}
/deep/.el-menu{
border-right: 0 !important;
.el-menu-item{
display: flex;
align-items: center;
&.is-active{
background-color: #CC221C !important;
}
.menu-icon{
width: 24px;
height: 24px;
margin-right: 12px;
background: url(../../assets/img/home.png) no-repeat;
&.icon-ques{
background-image: url(../../assets/img/ques.png);
}
&.icon-testpaper{
background-image: url(../../assets/img/paper.png);
}
&.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-msg{
background-image: url(../../assets/img/msg.png);
}
&.icon-student{
background-image: url(../../assets/img/student.png);
}
&.icon-system{
background-image: url(../../assets/img/system.png);
}
}
span{
font-size: 15px;
}
}
}
}
.sidebar::-webkit-scrollbar {
width: 0;
}

@ -1,5 +1,6 @@
import cookies from './util.cookies'
import {_local,_session} from './util.db'
import { Message } from 'element-ui'
const util = {
cookies,
@ -103,6 +104,23 @@ const util = {
}
x.send()
},
// 成功提示
successMsg(message) {
Message.success({message,showClose: true,offset: (document.documentElement.clientHeight - 40) / 2,duration: 1500})
},
// 警告提示
warningMsg(message) {
Message.warning({message,showClose: true,offset: (document.documentElement.clientHeight - 40) / 2,duration: 1500})
},
// 错误提示
errorMsg(message) {
Message.error({message,showClose: true,offset: (document.documentElement.clientHeight - 40) / 2,duration: 1500})
},
// 给超过给定长度的字符串加省略号
ellipsisStr(str) {
if(str.length > 14) str = str.substr(0,14) + '……'
return str
},
}
export default util

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

@ -1,67 +1,35 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div class="p-title m-b-20">筛选</div>
<div class="flex j-between">
<el-form label-width="80px" inline>
<el-form-item class="no-mb" label="教学班级">
<el-select v-model="classId" placeholder="请选择教学班级" @change="getAssess">
<div class="tool">
<ul class="filter">
<li>
<label>考试班级</label>
<el-select v-model="classId" clearable placeholder="请选择考试班级" size="small" @change="getAssess">
<el-option v-for="(item,index) in classList" :key="index" :label="item.className" :value="item.classId"></el-option>
</el-select>
</el-form-item>
<el-form-item class="no-mb" label="考试名称">
<el-select v-model="assessmentId" placeholder="请选择考试名称" @change="getData">
</li>
<li>
<label>考试名称</label>
<el-select v-model="assessmentId" placeholder="请选择考试名称" size="small" @change="getData">
<el-option v-for="(item,index) in assessmentNameList" :key="index" :label="item.assessmentName" :value="item.assessmentId"></el-option>
</el-select>
</el-form-item>
</el-form>
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入学生姓名或学号" suffix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
<div>
<el-input
placeholder="请输入学生姓名或学号"
prefix-icon="el-icon-search"
v-model="keyword"
clearable
></el-input>
<el-button type="primary" size="small" round @click="toStat" v-auth="'/achievement/list:考试成绩:成绩统计'">班级成绩分析报告</el-button>
<el-button type="primary" size="small" round @click="exportData" v-auth="'/achievement/list:考试成绩:导出'">导出成绩表</el-button>
</div>
</div>
</el-card>
<el-card shadow="hover" class="m-b-20">
<div class="flex j-between m-b-20">
<div class="p-title">考试成绩</div>
<div>
<el-button
type="primary"
size="small"
round
@click="toStat"
v-auth="'/achievement/list:考试成绩:成绩统计'"
>成绩统计</el-button>
<el-button
type="primary"
size="small"
round
@click="exportData"
v-auth="'/achievement/list:考试成绩:导出'"
>导出</el-button>
</div>
</div>
<el-table
:data="listData"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
@selection-change="handleSelectionChange"
>
<el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
<el-table-column type="index" width="100" label="序号" align="center">
<template
slot-scope="scope"
>{{scope.$index + (page - 1) * pageSize + 1}}</template>
<template slot-scope="scope">{{scope.$index + (page - 1) * pageSize + 1}}</template>
</el-table-column>
<el-table-column prop="stuName" label="真实姓名" align="center"></el-table-column>
<el-table-column prop="stuName" label="姓名" align="center"></el-table-column>
<el-table-column prop="stuNo" label="学号" align="center"></el-table-column>
<el-table-column prop="thisScore" label="得分" align="center">
<template slot-scope="scope">
@ -80,26 +48,19 @@
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="text" @click="show(scope.row)" v-auth="'/achievement/list:考试成绩:查看详情'">查看详情</el-button>
<el-button type="text" @click="show(scope.row)" v-auth="'/achievement/list:考试成绩:查看详情'">查看答卷</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>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</el-card>
</div>
</template>
<script>
import { mapState,mapActions } from 'vuex'
import Setting from '@/setting'
import util from '@/libs/util'
export default {
data() {
return {
@ -200,7 +161,7 @@ export default {
this.listData.map(n => {
if(n.thisScore == null) invalid = true
})
if(invalid) return this.$message.warning('考核未全部批阅完,无法统计成绩,请先批阅')
if(invalid) return util.warningMsg('考核未全部批阅完,无法统计成绩,请先批阅')
this.assessmentName = this.assessmentNameList.find(n => n.assessmentId == this.assessmentId).assessmentName
this.setAssDetailInfo({
id: this.listData[0].paperId,
@ -211,7 +172,7 @@ export default {
})
this.$router.push('statistics')
}else{
this.$message.warning('没有考试成绩')
util.warningMsg('没有考试成绩')
}
},
exportData(){

@ -1,13 +1,17 @@
<template>
<div>
<div class="tabs m-b-20">
<breadcrumb :data="'成绩管理/' + tabs[active]" ref="breadcrumb"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{item}}</a>
</div>
<div class="page-content">
<practice-results v-if="active == 'practice'" v-auth="'成绩管理:练习成绩'"></practice-results>
<exam-results v-else-if="active == 'exam'" v-auth="'成绩管理:考试成绩'"></exam-results>
<wrong-book v-else v-auth="'成绩管理:错题收藏'"></wrong-book>
</div>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
@ -15,6 +19,7 @@ import Setting from '@/setting'
import practiceResults from './practiceResults'
import examResults from './examResults'
import wrongBook from './wrongBook'
import breadcrumb from '@/components/breadcrumb'
export default {
data() {
return {
@ -22,7 +27,7 @@ export default {
tabs: {
practice: '练习成绩',
exam: '考试成绩',
wrong: '错题收藏'
wrong: '错题合集'
}
};
},
@ -30,6 +35,7 @@ export default {
practiceResults,
examResults,
wrongBook,
breadcrumb
},
computed: {
...mapState('auth', [
@ -42,6 +48,7 @@ export default {
methods: {
tabChange(index){
this.active = index
this.$refs.breadcrumb.update('成绩管理/' + this.tabs[this.active])
},
initTabs(){
let tab1 = this.btns.includes('成绩管理:练习成绩')

@ -1,60 +1,36 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div class="p-title m-b-20">筛选</div>
<div class="flex j-between">
<el-form label-width="80px" inline>
<el-form-item class="no-mb" label="教学班级">
<el-select v-model="classId" clearable placeholder="请选择教学班级" @change="getPrac">
<div class="tool">
<ul class="filter">
<li>
<label>教学班级</label>
<el-select v-model="classId" clearable placeholder="请选择教学班级" size="small" @change="getPrac">
<el-option v-for="(item,index) in classList" :key="index" :label="item.className" :value="item.classId"></el-option>
</el-select>
</el-form-item>
<el-form-item class="no-mb" label="练习名称">
<el-select v-model="practiseId" clearable placeholder="请选择练习名称" @change="getData">
</li>
<li>
<label>练习名称</label>
<el-select v-model="practiseId" clearable placeholder="请选择练习名称" size="small" @change="getData">
<el-option v-for="(item,index) in practiceNameList" :key="index" :label="item.practiseName" :value="item.practiseId"></el-option>
</el-select>
</el-form-item>
</el-form>
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入学生姓名或学号" suffix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
<div>
<el-input
placeholder="请输入学生姓名或学号"
prefix-icon="el-icon-search"
v-model="keyword"
clearable
></el-input>
<el-button type="primary" size="small" round @click="exportData" v-auth="'/achievement/list:练习成绩:导出'">导出成绩表</el-button>
</div>
</div>
</el-card>
<el-card shadow="hover" class="m-b-20">
<div class="flex j-between m-b-20">
<div class="p-title">练习成绩</div>
<div>
<el-button
type="primary"
size="small"
round
@click="exportData"
v-auth="'/achievement/list:练习成绩:导出'"
>导出</el-button>
</div>
</div>
<el-table
:data="listData"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
@selection-change="handleSelectionChange"
>
<el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
<el-table-column type="index" width="100" label="序号" align="center">
<template
slot-scope="scope"
>{{scope.$index + (page - 1) * pageSize + 1}}</template>
</el-table-column>
<el-table-column prop="userName" label="真实姓名" align="center"></el-table-column>
<el-table-column prop="userName" label="姓名" align="center"></el-table-column>
<el-table-column prop="workNumber" label="学号" align="center"></el-table-column>
<el-table-column prop="max" label="最高分" align="center">
<template slot-scope="scope">
@ -73,42 +49,22 @@
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="text" @click="showDetail(scope.row)" v-auth="'/achievement/list:练习成绩:查看详情'">查看详情</el-button>
<el-button type="text" @click="showDetail(scope.row)" v-auth="'/achievement/list:练习成绩:查看详情'">查看练习历史</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>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</el-card>
<el-dialog title="练习成绩详情" :visible.sync="detailVisible" width="40%" :close-on-click-modal="false">
<el-dialog title="练习历史" :visible.sync="detailVisible" width="40%" :close-on-click-modal="false">
<div class="flex flex-j-e">
<div class="m-b-20">
<el-input
placeholder="请输入练习项目名称"
prefix-icon="el-icon-search"
v-model="keywordAch"
clearable
></el-input>
<el-input placeholder="请输入练习项目名称" prefix-icon="el-icon-search" v-model="keywordAch" clearable></el-input>
</div>
</div>
<el-table
:data="achiList"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
>
<el-table :data="achiList" 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"
@ -127,19 +83,12 @@
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="text" @click="show(scope.row)">查看</el-button>
<el-button type="text" @click="show(scope.row)">查看练习卷</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
background
@current-change="handleAchCurrentChange"
:current-page="pageAch"
:page-size="pageSizeAch"
layout="total,prev, pager, next"
:total="totalAch"
></el-pagination>
<el-pagination background @current-change="handleAchCurrentChange" :current-page="pageAch" :page-size="pageSizeAch" layout="total,prev, pager, next" :total="totalAch"></el-pagination>
</div>
<span slot="footer" class="dialog-footer">
@ -152,6 +101,7 @@
<script>
import { mapState,mapActions } from 'vuex'
import Setting from '@/setting'
import util from '@/libs/util'
export default {
data() {
return {
@ -254,7 +204,7 @@ export default {
this.getData()
},
exportData(){
location.href = `${Setting.apiBaseURL}${this.api.exportPractice}?practiseId=${this.practiseId}&classId=${this.classId}`
location.href = `${Setting.apiBaseURL}${this.api.exportPractice}?practiseId=${this.practiseId}&classId=${this.classId}&className=${this.classList.find(n => n.classId == this.classId).className}`
},
}
};

@ -1,48 +1,33 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div class="p-title m-b-20">筛选</div>
<div class="flex j-between">
<el-form label-width="80px" inline>
<el-form-item class="no-mb" label="错题来源">
<el-select v-model="type" clearable placeholder="请选择错题来源" @change="getName">
<div class="tool">
<ul class="filter">
<li>
<label>错题来源</label>
<el-select v-model="type" clearable placeholder="请选择错题来源" size="small" @change="getName">
<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-item class="no-mb" label="练习名称" v-if="type == 2">
<el-select v-model="name" clearable placeholder="请选择练习名称" @change="getData">
</li>
<li v-if="type == 2">
<label>练习名称</label>
<el-select v-model="name" clearable placeholder="请选择练习名称" size="small" @change="getData">
<el-option v-for="(item,index) in nameList" :key="index" :label="item.practiseName" :value="item.practiseId"></el-option>
</el-select>
</el-form-item>
<el-form-item class="no-mb" label="考核名称" v-else>
<el-select v-model="name" clearable placeholder="请选择考核名称" @change="getData">
</li>
<li v-else>
<label>考试名称</label>
<el-select v-model="name" clearable placeholder="请选择考试名称" size="small" @change="getData">
<el-option v-for="(item,index) in nameList" :key="index" :label="item.assessmentName" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-form>
<div>
<el-input
placeholder="请输入题干"
prefix-icon="el-icon-search"
v-model="keyword"
clearable
></el-input>
</div>
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入题干" suffix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
</div>
</el-card>
<el-card shadow="hover" class="m-b-20">
<div class="p-title m-b-20">错题收藏</div>
<el-table
:data="listData"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
@selection-change="handleSelectionChange"
>
<el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
<el-table-column type="index" width="100" label="序号" align="center">
<template
slot-scope="scope"
@ -50,44 +35,26 @@
</el-table-column>
<el-table-column label="错题来源" align="center">
<template>
{{type == 1 ? '考试卷' : '练习试卷'}}
{{type == 1 ? '考试卷' : '练习试卷'}}
</template>
</el-table-column>
<el-table-column prop="paperName" label="试卷名称" align="center"></el-table-column>
<el-table-column prop="knowledgePoints" label="所需知识点" align="center"></el-table-column>
<el-table-column prop="questionStem" label="题干" align="center" :show-overflow-tooltip="true"></el-table-column>
<el-table-column label="错题次数" align="center">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="showNum(scope.row)">{{scope.row.wrongNum}}</el-button>
</template>
</el-table-column>
<el-table-column prop="wrongNum" label="错题次数" align="center"></el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="text" @click="show(scope.row,1)" v-auth="'/achievement/list:错题收藏:查看'">查看</el-button>
<el-button type="text" @click="show(scope.row,1)" v-auth="'/achievement/list:错题收藏:查看'">查看题目</el-button>
<el-button type="text" @click="showNum(scope.row)">历史统计</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>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</el-card>
<el-dialog title="错题人数" :visible.sync="numVisible" width="50%">
<el-table
:data="numList"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
>
<el-dialog title="历史统计" :visible.sync="numVisible" width="50%">
<el-table :data="numList" 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>
@ -103,18 +70,11 @@
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
background
@current-change="handleNumCurrentChange"
:current-page="pageNum"
:page-size="pageSizeNum"
layout="total,prev, pager, next"
:total="totalNum"
></el-pagination>
<el-pagination background @current-change="handleNumCurrentChange" :current-page="pageNum" :page-size="pageSizeNum" layout="total,prev, pager, next" :total="totalNum"></el-pagination>
</div>
</el-dialog>
<el-dialog title="题详情" :visible.sync="detailVisible" width="40%">
<el-dialog title="题目详情" :visible.sync="detailVisible" width="540px">
<div class="ques">
<div class="meta">
<p class="key">题干</p>
@ -152,7 +112,7 @@ export default {
typeList: [
{
id: 1,
name: '考试卷'
name: '考试卷'
},{
id: 2,
name: '练习试卷'

@ -1,8 +1,12 @@
<template>
<div>
<breadcrumb :data="'成绩管理/成绩统计'"></breadcrumb>
<div class="box">
<div class="left">
<div class="title">基本信息</div>
<div class="page left">
<div class="tabs">
<a class="item active">基本信息</a>
</div>
<div class="page-content">
<div class="info">
<div class="item">
<p class="key">考试名称</p>
@ -16,7 +20,6 @@
<p class="key">总分</p>
<p class="val">{{info.totalScore}}</p>
</div>
<div class="items">
<div class="item">
<p class="key">最高分</p>
<p class="val">{{info.highestScore}}</p>
@ -25,8 +28,6 @@
<p class="key">应考人数</p>
<p class="val">{{info.shouldPeople}}</p>
</div>
</div>
<div class="items">
<div class="item">
<p class="key">最低分</p>
<p class="val">{{info.lowestScore}}</p>
@ -35,43 +36,39 @@
<p class="key">实考人数</p>
<p class="val">{{info.actualPeople}}</p>
</div>
</div>
<div class="item">
<p class="key">平均分</p>
<p class="val">{{info.averageScore}}</p>
</div>
</div>
</div>
</div>
<div class="right">
<div class="title">成绩分布图</div>
<div class="page right">
<div class="tabs">
<a class="item active">成绩分布图</a>
</div>
<div class="page-content">
<div class="info">
<div class="chart" id="chart"></div>
</div>
</div>
</div>
</div>
<el-card shadow="hover" class="m-b-20">
<div class="flex j-between m-b-20">
<div class="p-title">考试成绩</div>
<div class="page">
<div class="tabs">
<a class="item active">考试成绩</a>
</div>
<div class="page-content">
<div class="tool">
<ul class="filter"></ul>
<div>
<el-button
type="primary"
size="small"
round
@click="exportData"
>导出</el-button>
<el-button type="primary" size="small" round @click="exportData">导出</el-button>
</div>
</div>
<el-table
:data="listData"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
>
<el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center">
<el-table-column type="index" width="100" label="序号" align="center">
<template
slot-scope="scope"
@ -84,25 +81,19 @@
<el-table-column prop="rank" label="名次" align="center"></el-table-column>
</el-table>
<div class="pagination">
<el-pagination
background
@current-change="handleCurrentChange"
:current-page="page"
:page-size="pageSize"
layout="total,prev, pager, next"
:total="total"
></el-pagination>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</div>
</div>
</el-card>
</div>
</template>
<script>
import { mapState,mapGetters } from 'vuex'
import mixins from '@/mixins/setBackground';
import echarts from 'echarts'
import breadcrumb from '@/components/breadcrumb'
import util from '@/libs/util'
export default {
mixins: [ mixins ],
data() {
return {
info: {
@ -123,6 +114,9 @@ export default {
total: 0,
};
},
components: {
breadcrumb
},
computed: {
...mapState('user', [
'userId'
@ -206,47 +200,28 @@ export default {
<style lang="scss" scoped>
.box{
display: flex;
justify-content: space-between;
width: 90%;
margin: 0 auto 20px;
.title{
padding-left: 5px;
border-left: 5px solid #cb221c;
margin: 20px 0;
line-height: 1;
font-size: 16px;
margin-bottom: 24px;
.left{
width: 320px;
}
.left,.right{
width: 48%;
box-sizing: border-box;
.right{
width: calc(80% - 344px);
margin-left: 24px;
}
.info{
height: 450px;
padding: 30px 30px;
background-color: #efefef;
box-sizing: border-box;
.item,.items{
.item{
display: flex;
align-items: center;
margin: 20px 0;
font-size: 14px;
}
.key{
color: #333;
font-weight: bold;
font-size: 14px;
}
.val{
font-size: #757575;
.key,.val{
color: rgba(0, 0, 0, 0.65);
font-size: 14px;
}
.items{
.item{
margin: 0;
}
.item:first-child{
margin-right: 20px;
}
.key{
width: 130px;
text-align: right;
}
}
.chart{

@ -1,5 +1,8 @@
<template>
<div class="box">
<breadcrumb :data="'考试管理/成绩详情'"></breadcrumb>
<div class="page">
<div class="page-content">
<h1 class="title">{{paperName }}</h1>
<div class="metas">
<div class="m-r-20">
@ -28,16 +31,11 @@
<div class="wrap">
<div class="item" v-for="(item,index) in curType" :key="index">
<div class="answer">
<div class="info">
<p class="key">序号</p>
<p class="val">{{index+1}}</p>
</div>
<div class="info">
<p class="key">得分</p>
<p class="val">{{item.question_score}}</p>
</div>
<div class="type" :class="{wrong: item.question_score == 0,yet: item.question_score == null}">
<span>序号{{index+1}}</span>
<span>得分{{item.question_score}}</span>
</div>
<div class="inner">
<div class="meta">
<p class="key">题干</p>
<p class="val" v-html="item.question_stem"></p>
@ -48,7 +46,7 @@
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p>
</div>
</div>
<div class="meta ans">
<div class="meta-mul">
<div class="info" v-if="active != 4">
<p class="key">正确答案</p>
<p class="val">{{item.answer}}</p>
@ -81,6 +79,7 @@
</div>
</div>
</div>
</div>
<div v-show="playAuth" class="el-image-viewer__wrapper" :class="{over: isDownload}" style="z-index: 2000">
<div class="el-image-viewer__mask"></div>
@ -89,14 +88,17 @@
</div>
<pdf :visible.sync="pdfVisible" :src.sync="pdfSrc"></pdf>
</div>
</div>
</div>
</template>
<script>
import setBackground from '@/mixins/setBackground'
import file from '@/mixins/file'
import { mapState } from 'vuex'
import pdf from '@/components/pdf'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default {
mixins: [ setBackground,file ],
mixins: [ file ],
data() {
return {
paperName: '',
@ -130,7 +132,7 @@ export default {
curType: []
};
},
components: { pdf },
components: { pdf,breadcrumb },
computed: {
...mapState('user', [
'userId'
@ -188,7 +190,10 @@ export default {
if(n.typeName == '填空题') answer.push(n[i])
}
}
if(n.typeName == '填空题') n.answer = answer.join('|')
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
}
})
@ -199,110 +204,5 @@ export default {
</script>
<style lang="scss" scoped>
.box{
width: 90%;
margin: 0 auto;
}
.title{
text-align: center;
font-size: 18px;
font-weight: 600;
}
.metas{
display: flex;
justify-content: center;
margin: 20px 0 30px;
.name{
font-size: 12px;
color: #717171;
}
.val{
font-size: 12px;
color: #929292;
}
}
.tab{
display: flex;
align-items: center;
margin-bottom: 10px;
li{
position: relative;
padding: 0 44px;
margin-right: 7px;
font-size: 13px;
line-height: 46px;
text-align: center;
color: #444;
border: 1px solid #ececec;
cursor: pointer;
&:hover{
opacity: .8;
}
&.active:after{
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 4px;
background-color: $main-color;
}
}
}
.wrap{
.item{
padding-bottom: 30px;
margin-bottom: 30px;
border-bottom: 1px dashed #f4f4f4;
.key{
font-weight: bold;
color: #333;
font-size: 14px;
}
.val{
color: #757575;
font-size: 14px;
}
.answer{
display: flex;
align-items: center;
padding: 15px;
margin: 15px 0;
font-size: 12px;
border: 1px solid #e8e8e8;
background-color: #f3f2f2;
.info{
display: inline-flex;
align-items: center;
margin-right: 30px;
}
}
.meta{
padding-left: 10px;
margin: 20px 0;
font-size: 12px;
&.ans{
display: flex;
.info{
margin-right: 20px;
}
}
.key{
margin-bottom: 5px;
}
}
}
}
.over{
top: 5000px;
}
.player{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 1200px !important;
height: 600px !important;
}
@import "@/styles/pages/testPaperDetail.scss";
</style>

@ -1,35 +1,43 @@
<template>
<div class="box">
<breadcrumb :data="'考核管理/查看试题'"></breadcrumb>
<div class="page">
<div class="page-content">
<h1 class="title">{{paperName}}</h1>
<div class="metas">
<div>
<span class="name">学生姓名</span>
<span class="val">{{userName}}</span>
<ul class="metas">
<li>学生姓名{{userName}}</li>
<li>学生得分{{(reviewStatus == 2 || reviewStatus == 3) ? this_score : '--'}}</li>
<li>试卷总分100</li>
<li>考试时长{{timeSpent != null && timeSpent != '--' ? (timeSpent / 60).toFixed(2) + '分钟' : timeSpent}}</li>
</ul>
<div class="btn-wrap" v-if="reviewStatus == 2 || reviewStatus == 3">
<button :class="{active: look == 1}" @click="look = 1">查看全部</button>
<button :class="{active: look == 2}" v-if="reviewStatus == 2 || reviewStatus == 3" @click="look = 2">错误题</button>
</div>
<div>
<span class="name">学生得分</span>
<span class="val">{{(reviewStatus == 2 || reviewStatus == 3) ? this_score : '--'}}</span>
<div class="wrap">
<div class="item" v-for="(item,index) in list" :key="index">
<!-- <div class="status" :class="{done: item.isCorrecting}">{{item.isSub ? '简答题' : '客观题'}}{{getCorrectingName(item.isCorrecting)}}</div> -->
<div class="type" :class="{wrong: item.question_score == 0,yet: !item.isCorrecting}">
<span>题目类型{{item.typeName}}</span>
<span>题目分数{{item.question_points}}</span>
<span v-if="item.isCorrecting">考试得分{{item.question_score}}</span>
</div>
<div>
<span class="name">试卷总分</span>
<span class="val">100</span>
<div class="inner">
<div class="meta">
<p class="key">题干:</p>
<div class="val">
<div class="name" v-html="item.question_stem"></div>
</div>
<div>
<span class="name">考试时长</span>
<span class="val">{{timeSpent != null && timeSpent != '--' ? (timeSpent / 60).toFixed(2) + '分钟' : timeSpent}}</span>
</div>
<div class="meta" v-if="item.typeName != '简答题' && item.typeName != '填空题'">
<p class="key">选项</p>
<div class="val">
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p>
</div>
<div class="wrap">
<div class="select">
<el-radio v-model="look" label="1">查看全部</el-radio>
<el-radio v-model="look" label="2" v-if="reviewStatus == 2 || reviewStatus == 3">只看错题</el-radio>
</div>
<div class="item" v-for="(item,index) in list" :key="index">
<div class="status" :class="{done: item.isCorrecting}">{{item.isSub ? '简答题' : '客观题'}}{{getCorrectingName(item.isCorrecting)}}</div>
<div class="name" v-html="item.question_stem"></div>
<div class="answer">
<div class="meta-mul">
<div class="info" v-if="!item.isSub">
<p class="key">正确答案</p>
<p class="val">{{item.answer}}</p>
@ -39,10 +47,6 @@
<p class="val">{{item.user_answer}}</p>
</div>
</div>
<div class="meta">
<span class="key">知识点</span>
<span class="val">{{item.knowledge_points}}</span>
</div>
<div class="meta" v-if="item.isSub">
<p class="key">附件</p>
<div class="val">
@ -61,16 +65,16 @@
</div>
</div>
<div class="meta">
<span class="key">答案解析</span>
<span class="val">{{item.answer_analysis}}</span>
<p class="key">答案解析</p>
<p class="val">{{item.answer_analysis}}</p>
</div>
<div class="flex a-center point">
<div class="meta">
<span class="key">题目分数</span>
<div class="meta-mul" v-if="(reviewStatus == 0 || reviewStatus == 1) && !item.isCorrecting">
<div class="info">
<p class="key">题目分数</p>
<div class="val">{{item.question_points}} </div>
</div>
<div class="meta">
<span class="key">考试得分</span>
<div class="info">
<p class="key">考试得分</p>
<div class="val">
<input type="text" v-model.number="item.question_score" :disabled="!isReview || !item.isSub">
</div>
@ -78,6 +82,7 @@
</div>
</div>
</div>
</div>
<div class="btns" v-if="isReview">
<button type="button" class="submit" @click="save(1)">提交</button>
@ -91,14 +96,17 @@
</div>
<pdf :visible.sync="pdfVisible" :src.sync="pdfSrc"></pdf>
</div>
</div>
</div>
</template>
<script>
import setBackground from '@/mixins/setBackground'
import file from '@/mixins/file'
import { mapState,mapGetters,mapActions } from 'vuex'
import pdf from '@/components/pdf'
import breadcrumb from '@/components/breadcrumb'
import util from '@/libs/util'
export default {
mixins: [ setBackground,file ],
mixins: [ file ],
data() {
return {
paperName: '',
@ -125,7 +133,7 @@ export default {
val == 1 ? this.getData() : this.getWrong()
}
},
components: { pdf },
components: { pdf,breadcrumb },
mounted() {
this.getData()
},
@ -137,14 +145,6 @@ export default {
list.map(n => {
n.isCorrecting == 0 && (n.question_score = '')
n.isSub = n.typeName == '简答题'
if(n.typeName == '填空题'){
let answer = []
for(let i in n){
if(i.includes('option_')) answer.push(n[i])
}
n.answer = answer.join('|')
n.user_answer = n.user_answer.replace(/&lt;&gt;/g,'|')
}
if(n.fileUrl) n.fileUrl = JSON.parse(n.fileUrl)
if(n.videoAudio) n.videoAudio = JSON.parse(n.videoAudio)
})
@ -152,8 +152,8 @@ export default {
this.paperName = list[0].name
this.userName = list[0].userName
this.this_score = list[0].this_score
})
.catch(err => {})
this.handleOptions()
}).catch(err => {})
},
getWrong(){
this.$post(`${this.api.getWrong}?assessmentId=${this.reviewId}&userId=${this.stuId}&paperId=${this.paperId}`)
@ -162,19 +162,33 @@ export default {
list.map(n => {
n.isCorrecting == 0 && (n.question_score = '')
n.isSub = n.typeName == '简答题'
if(n.typeName == '填空题'){
if(n.fileUrl) n.fileUrl = JSON.parse(n.fileUrl)
if(n.videoAudio) n.videoAudio = JSON.parse(n.videoAudio)
})
this.list = list
this.handleOptions()
}).catch(err => {})
},
handleOptions(){
let list = this.list
list.forEach(n => {
if(!n.options){
let options = {}
let answer = []
for(let i in n){
if(i.includes('option_')) answer.push(n[i])
if(i.includes('option') && n[i]){
options[i.replace('option_','')] = n[i]
if(n.typeName == '填空题') answer.push(n[i])
}
n.answer = answer.join('|')
n.user_answer = n.user_answer.replace(/&lt;&gt;/g,'|')
}
if(n.fileUrl) n.fileUrl = JSON.parse(n.fileUrl)
if(n.videoAudio) n.videoAudio = JSON.parse(n.videoAudio)
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
}
})
this.list = list
}).catch(err => {})
},
save(status) {
let isEmpty = false
@ -186,10 +200,10 @@ export default {
if(Number(n.question_score) > Number(n.question_points)) invalid = true
})
if(status){
if(isEmpty) return this.$message.warning('请批阅完所有题目')
if(isNotNum) return this.$message.warning('考试得分请输入数字')
if(isEmpty) return util.warningMsg('请批阅完所有题目')
if(isNotNum) return util.warningMsg('考试得分请输入数字')
}
if(invalid) return this.$message.warning('考试得分不得大于题目分数')
if(invalid) return util.warningMsg('考试得分不得大于题目分数')
let data = {
review: [],
assessmentId: this.reviewId,
@ -205,13 +219,13 @@ export default {
})
totalScore += Number(n.question_score)
})
if(!data.review.length) return this.$message.warning('请至少批阅一道题目')
if(!data.review.length) return util.warningMsg('请至少批阅一道题目')
if(status || this.list.filter(n => n.isSub).length == data.review.length){
data.totalScore = totalScore
}
this.$post(this.api.reviewByid,data).then(res => {
this.$message.success(status ? '提交成功' : '保存成功')
util.successMsg(status ? '提交成功' : '保存成功')
this.$router.back()
}).catch(err => {})
},
@ -222,98 +236,106 @@ export default {
<style lang="scss" scoped>
.title{
text-align: center;
font-size: 18px;
font-weight: 600;
font-size: 20px;
color: rgba(0, 0, 0, 0.85);
}
.metas{
display: flex;
justify-content: space-between;
margin: 20px 0 30px;
.name{
font-size: 12px;
color: #717171;
justify-content: center;
padding-bottom: 24px;
margin: 24px 0;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
li{
margin-right: 40px;
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
}
.val{
font-size: 12px;
color: #929292;
}
.btn-wrap{
display: flex;
justify-content: center;
button{
padding: 0 16px;
margin-right: 16px;
line-height: 30px;
color: rgba(0, 0, 0, 0.65);
font-size: 14px;
background-color: #fff;
border: 1px solid;
border-radius: 4px;
cursor: pointer;
&.active{
color: #CC221C;
}
.wrap{
padding: 20px;
background-color: #fbfbfb;
.select{
padding: 10px;
margin-bottom: 20px;
border-bottom: 1px solid #f4f4f4;
}
}
.wrap{
margin-top: 24px;
.item{
padding-bottom: 30px;
margin-bottom: 30px;
border-bottom: 1px dashed #d2d2d2;
&:last-child{
border-bottom: 0;
border: 1px solid rgba(0, 0, 0, 0.06);
border-radius: 8px;
.type{
padding: 0 24px;
margin-top: -1px;
color: rgba(0, 0, 0, 0.85);
line-height: 52px;
font-size: 14px;
background-color: #F6FFED;
border: 1px solid #B7EB8F;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
&.wrong{
border: 1px solid #FFA39E;
background: #FFF1F0;
}
.status{
color: #cb221c;
&.done{
color: #56d5bf;
&.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{
margin-top: 15px;
font-size: 14px;
color: #555555;
}
.meta{
margin-bottom: 16px;
}
.key{
font-weight: bold;
color: #333;
margin-bottom: 8px;
color: rgba(0, 0, 0, 0.85);
font-size: 16px;
}
.val{
color: #757575;
color: rgba(0, 0, 0, 0.65);
font-size: 14px;
}
.answer{
.meta-mul{
display: flex;
align-items: center;
padding: 15px;
margin: 15px 0;
font-size: 12px;
border: 1px solid #e8e8e8;
background-color: #f3f2f2;
margin-bottom: 15px;
.info{
display: inline-flex;
align-items: center;
margin-right: 30px;
}
}
.meta{
display: flex;
align-items: center;
padding-left: 10px;
margin: 10px 0;
font-size: 12px;
.key{
width: 80px;
margin-right: 10px;
text-align: right;
white-space: nowrap;
margin-right: 32px;
}
input{
width: 60px;
height: 28px;
padding: 0 5px;
margin-right: 5px;
color: #444;
background-color: #fff;
border: 1px solid #ebebeb;
box-sizing: border-box;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
&:focus{
outline: none;
}
&:disabled{
background-color: #e8e8e8;
background-color: rgba(0, 0, 0, 0.04);
color: rgba(0, 0, 0, 0.25);
cursor: not-allowed;
}
}

@ -1,50 +1,49 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div>
<div class="p-title m-b-20">筛选</div>
<div class="flex j-between no-mb">
<div>
<el-form label-width="80px" inline>
<el-form-item label="考试类型" class="no-mb">
<el-select v-model="type" clearable placeholder="请选择考试类型" @change="getData">
<breadcrumb :data="'考试管理/考试列表'"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item active">考试列表</a>
</div>
<div class="page-content">
<div class="tool">
<ul class="filter">
<li>
<label>考试类型</label>
<el-select v-model="type" clearable placeholder="请选择考试类型" size="small" @change="getData">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in typeList" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="考试状态" class="no-mb">
<el-select v-model="state" clearable placeholder="请选择考试状态" @change="getData">
</li>
<li>
<label>考试状态</label>
<el-select v-model="state" clearable placeholder="请选择考试状态" size="small" @change="getData">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in stateList" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-form>
</div>
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入考试名称" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
<div>
<el-input placeholder="请输入考核名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</div>
<!-- <el-button type="primary" size="small" round @click="addAss" v-auth>创建考试</el-button> -->
<el-button type="primary" size="small" round @click="addAss">创建考试</el-button>
</div>
</div>
</el-card>
<el-card shadow="hover">
<div class="flex j-between m-b-20">
<div class="p-title">考核列表</div>
<div>
<el-button type="primary" size="small" round @click="addAss" v-auth>创建考核</el-button>
</div>
</div>
<el-table :data="listData" class="table" stripe header-align="center" row-key="id">
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="assessmentName" label="考名称" align="center"></el-table-column>
<el-table-column prop="name" label="考类型" align="center">
<el-table-column prop="assessmentName" label="考试名称" align="center"></el-table-column>
<el-table-column label="考试类型" align="center">
<template slot-scope="scope">
{{getTypeName(scope.row.type)}}
</template>
</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="name" label="考核状态" align="center">
<el-table-column label="考试进度" align="center">
<template slot-scope="scope">
{{getStateName(scope.row.state)}}
</template>
@ -58,20 +57,20 @@
trigger="click">
<div class="details">
<div class="line">
<span class="key">核内容</span>
<span class="key">试用卷</span>
<p class="val">{{assContent}}</p>
</div>
<div class="line">
<span class="key">题数</span>
<span class="key">题数</span>
<p class="val">{{quesNum}}</p>
</div>
<div class="line">
<span class="key">考核人数</span>
<p class="val">{{assPeopleNum}}</p>
<span class="key">试卷总分</span>
<p class="val">100</p>
</div>
<div class="line">
<span class="key">考核总分</span>
<p class="val">100</p>
<span class="key">参考人数</span>
<p class="val">{{assPeopleNum}}</p>
</div>
</div>
<el-button type="text" slot="reference" @click="show(scope.row)" v-auth>查看</el-button>
@ -96,86 +95,59 @@
<el-pagination background @current-change="handleCurrentChange" :current-page="page" layout="total, prev, pager, next" :total="total">
</el-pagination>
</div>
</el-card>
</div>
</div>
<el-dialog :title="isAdd ? '创建考核' : '修改考核'" :visible.sync="addVisible" width="50%" @close="closeAdd" :close-on-click-modal="false">
<el-form ref="form" label-width="100px">
<el-form-item label="考名称">
<el-input v-model="form.assessmentName" size="small" placeholder="请输入考名称" @change="nameChange"></el-input>
<el-dialog :title="isAdd ? '创建考试' : '修改考试'" :visible.sync="addVisible" width="540px" @close="closeAdd" class="dialog" :close-on-click-modal="false">
<el-form ref="form" label-width="100px" label-suffix="">
<el-form-item label="考名称">
<el-input v-model="form.assessmentName" size="small" placeholder="请输入考名称" @change="nameChange"></el-input>
</el-form-item>
<el-form-item label="考核类型">
<div class="w-p-30">
<el-select v-model="form.type" size="small" placeholder="请选择考核类型">
<el-option
v-for="item in typeList"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
<el-form-item label="考试类型">
<el-select v-model="form.type" size="small" placeholder="请选择考试类型">
<el-option v-for="item in typeList" :key="item.id" :value="item.id"></el-option>
</el-select>
</div>
</el-form-item>
<el-form-item label="考核时间">
<el-date-picker
size="small"
v-model="time"
value-format="yyyy-MM-dd HH:mm:ss"
type="datetimerange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:picker-options="pickerOptions"
></el-date-picker>
<el-form-item label="考试时间">
<el-date-picker size="small" v-model="time" value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :picker-options="pickerOptions"></el-date-picker>
</el-form-item>
<el-form-item label="试卷选择">
<el-button type="primary" size="small" @click="openSelect">试卷选择</el-button>
<el-tag
class="m-l-10"
v-if="testPaperName"
closable
@close="removeTestPaper">
{{testPaperName}}
</el-tag>
<el-form-item label="考试试卷">
<div class="btn-wrap">
<div class="paper-name" v-if="testPaperName">
<img src="../../../assets/img/testPaper.png" alt="">
<span>{{testPaperName}}</span>
</div>
<button type="button" @click="openSelect">选择试卷</button>
</div>
</el-form-item>
<el-form-item label="发布班级">
<el-form-item label="考试班级">
<studentSide ref="getSelectData" :classId="form.classId" :studentId="form.studentId" :key="stuCompKey" @fircheck="fircheck" @twocheck="twocheck" @threecheck="threecheck" @fourcheck="fourcheck"></studentSide>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="addVisible = false">取消</el-button>
<el-button type="primary" @click="save">确定</el-button>
<el-button size="small" @click="addVisible = false">取消</el-button>
<el-button size="small" type="primary" @click="save">确定</el-button>
</span>
</el-dialog>
<el-dialog title="试卷选择" :visible.sync="selectVisible" width="40%" @close="closeSelect" :close-on-click-modal="false">
<div class="flex j-end m-b-20">
<el-form label-width="80px" inline>
<el-form-item class="no-mb" label="所属课程">
<el-select v-model="cid" clearable placeholder="请选择所属课程" @change="getPapers">
<el-dialog title="试卷选择" :visible.sync="selectVisible" width="800px" @close="closeSelect" :close-on-click-modal="false">
<div class="tool">
<ul class="filter">
<li>
<label>所属课程</label>
<el-select v-model="cid" clearable placeholder="请选择所属课程" size="small" @change="getPapers">
<el-option v-for="(item,index) in coursesList" :key="index" :label="item" :value="item"></el-option>
</el-select>
</el-form-item>
<el-form-item class="no-mb">
<el-input
placeholder="请输入试卷名称"
prefix-icon="el-icon-search"
v-model="keywordPaper"
clearable
></el-input>
</el-form-item>
</el-form>
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入试卷名称" prefix-icon="el-icon-search" v-model="keywordPaper" clearable size="small"></el-input>
</li>
</ul>
</div>
<el-table
:data="testPaperData"
max-height="400"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
>
<el-table :data="testPaperData" max-height="400" ref="table" row-key="id" class="table" stripe header-align="center">
<el-table-column width="60" label="选择" align="center">
<template slot-scope="scope">
<el-radio v-model="testPaperId" :label="scope.row.id">&nbsp;</el-radio>
@ -194,16 +166,6 @@
</template>
</el-table-column>
</el-table>
<!-- <div class="pagination">
<el-pagination
background
@current-change="handleCurrentChange"
:current-page="pagePaper"
:page-size="pageSizePaper"
layout="total,prev, pager, next"
:total="totalPaper"
></el-pagination>
</div> -->
<span slot="footer" class="dialog-footer">
<el-button @click="selectVisible = false">取消</el-button>
@ -222,6 +184,7 @@ import { mapState,mapGetters,mapActions } from 'vuex'
import studentSide from './studentSide'
import testPaperDetail from '@/components/testPaperDetail'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default {
data() {
return {
@ -281,7 +244,7 @@ export default {
};
},
components: {
studentSide,testPaperDetail
studentSide,testPaperDetail,breadcrumb
},
computed: {
...mapState('user', [
@ -296,7 +259,7 @@ export default {
},
mounted() {
this.getData()
this.addInterval()
// this.addInterval()
},
watch: {
keyword: function(val) {
@ -480,16 +443,14 @@ export default {
this.getData();
},
delData(row) {
this.$confirm('确定要删除吗?', '提示', {
this.$confirm('确定要取消该考试计划吗?', '提示', {
type: 'warning'
})
.then(() => {
}).then(() => {
this.$post(`${this.api.deleteAssessment}?assessmentIds=${row.id}`).then(res => {
this.$message.success('删除成功')
util.successMsg('删除成功')
this.getData()
}).catch(res => {})
})
.catch(() => {})
}).catch(() => {})
},
edit(row){
this.$get(`${this.api.queryAssessmentNumber}?id=${row.id}`).then(res => {
@ -508,11 +469,11 @@ export default {
this.$get(`${this.api.queryAssessmentName}?userId=${this.userId}&assessmentName=${this.form.assessmentName}`).then(res => {
if(res.data.Assessment){
this.nameRepeat = true
this.$message.warning('该考名称已存在')
util.warningMsg('该考名称已存在')
}else{
this.nameRepeat = false
}
}).catch(res => {});
}).catch(res => {})
}else{
this.nameRepeat = false
}
@ -525,12 +486,14 @@ export default {
this.$router.push('monitor')
},
finish(row){
this.$post(`${this.api.compulsory}?id=${row.id}`)
.then(res => {
this.$message.success('结束成功')
this.$confirm('是否结束此次考试?', '提示', {
type: 'warning'
}).then(() => {
this.$post(`${this.api.compulsory}?id=${row.id}`).then(res => {
util.successMsg('结束成功')
this.getData()
})
.catch(err => {})
}).catch(err => {})
}).catch(() => {})
},
scoreQuery(row){
this.setAssListInfo({
@ -543,7 +506,12 @@ export default {
},
review(row){
this.setAssInfo({
id: row.id
id: row.id,
assessmentName: row.assessmentName,
type: this.getTypeName(row.type),
startTime: row.startTime,
endTime: row.endTime,
status: this.getStateName(row.state)
})
this.$router.push('review')
},
@ -559,15 +527,15 @@ export default {
},
save(){
let form = this.form
if(form.assessmentName === '') return this.$message.warning('请填写考名称')
if(this.nameRepeat) return this.$message.warning('该考名称已存在')
if(form.type === '') return this.$message.warning('请选择考类型')
if(form.startTime === '') return this.$message.warning('请选择考时间')
if(new Date(this.form.startTime).getTime() < new Date().getTime()) return this.$message.warning('考试开始时间不能小于当前时间')
if((new Date(this.form.endTime).getTime() - new Date(this.form.startTime).getTime()) / 1000 <= 60) return this.$message.warning('考开始时间和结束时间间隔不得小于1分钟')
if(form.testPaperId === '') return this.$message.warning('请选择试卷')
if(form.classId === '') return this.$message.warning('请选择发布班级')
if(!form.studentId.length) return this.$message.warning('请选择学生')
if(form.assessmentName === '') return util.warningMsg('请填写考名称')
if(this.nameRepeat) return util.warningMsg('该考名称已存在')
if(form.type === '') return util.warningMsg('请选择考类型')
if(form.startTime === '') return util.warningMsg('请选择考时间')
if(new Date(this.form.startTime).getTime() < new Date().getTime()) return util.warningMsg('考试开始时间不能小于当前时间')
if((new Date(this.form.endTime).getTime() - new Date(this.form.startTime).getTime()) / 1000 <= 60) return util.warningMsg('考开始时间和结束时间间隔不得小于1分钟')
if(form.testPaperId === '') return util.warningMsg('请选择试卷')
if(form.classId === '') return util.warningMsg('请选择发布班级')
if(!form.studentId.length) return util.warningMsg('请选择学生')
if(new Date(this.form.startTime).getTime() < new Date().getTime()) form.state = 2
let data = {
@ -584,14 +552,14 @@ export default {
}
if(this.form.id){
this.$post(this.api.updateAssessment, data).then(res => {
this.$message.success('修改成功')
util.successMsg('修改成功')
this.addVisible = false
this.getData()
})
.catch(err => {})
}else{
this.$post(this.api.addAssessment, data).then(res => {
this.$message.success('创建成功')
util.successMsg('创建成功')
this.addVisible = false
this.getData()
})
@ -649,7 +617,7 @@ export default {
this.previewVisible = true
},
savePaper(){
if(this.testPaperId === '') return this.$message.error('请选择试卷')
if(this.testPaperId === '') return util.errorMsg('请选择试卷')
this.form.testPaperId = this.testPaperId
this.testPaperName = this.testPaperData.find(n => n.id == this.testPaperId).name
this.selectVisible = false
@ -671,8 +639,30 @@ export default {
}
</script>
<style lang="scss" scoped>
/deep/.no-mb.el-form-item{
margin-bottom: 0;
/deep/.dialog{
.el-form-item{
.el-form-item__label{
font-size: 16px;
color: rgba(0, 0, 0, 0.65);
&:before{
margin-right: 0;
color: #CC221C;
}
}
}
.el-input,.el-select{
width: 100%;
}
.paper-name{
display: inline-flex;
align-items: center;
margin-right: 16px;
color: rgba(0, 0, 0, 0.65);
font-size: 16px;
img{
margin-right: 4px;
}
}
}
.details{
.line{

@ -1,12 +1,12 @@
<template>
<div class="side_view">
<el-input placeholder="请输入班级名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
<el-input placeholder="请输入班级名称" v-model="keyword" clearable></el-input>
<div v-if="keyword" class="side_tree">
<div v-for="(item,index) in classList" :key="index">
<div class="item" @click.stop="open(item)">
<i class="empty"></i>
<i :class="item.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="fircheckitem(item)"></i>
<i :class="item.ischeck ? 'checked' : 'checkbox'" @click.stop="fircheckitem(item)"></i>
<span>{{item.label}}</span>
</div>
</div>
@ -15,48 +15,34 @@
<div v-else class="side_tree" @click.stop="open(item)" v-for="(item,index) in data" :key="index">
<div class="item" @click.stop="open(item)">
<img
v-if="item.children&&item.children.length!=0"
:class="{ 'arrowTransform': !item.ifVisible, 'arrowTransformReturn': item.ifVisible}"
src="../../../assets/img/icon-xiangyou.png"
alt
/>
v-if="item.children&&item.children.length!=0" :class="{ 'arrowTransform': !item.ifVisible, 'arrowTransformReturn': item.ifVisible}" src="../../../assets/img/arrow-down.png" alt/>
<i v-else class="empty"></i>
<i :class="item.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="fircheckitem(item)"></i>
<i :class="item.ischeck ? 'checked' : 'checkbox'" @click.stop="fircheckitem(item)"></i>
<span>{{item.label}}</span>
</div>
<div v-show="item.ifVisible" v-if="item.children&&item.children.length!=0">
<div v-for="(item1,index1) in item.children" :key="index1">
<div class="item1" @click.stop="open(item1)">
<img
v-if="item1.children&&item1.children.length!=0"
:class="{ 'arrowTransform': !item1.ifVisible, 'arrowTransformReturn': item1.ifVisible}"
src="../../../assets/img/icon-xiangyou.png"
alt
/>
<img v-if="item1.children&&item1.children.length!=0" :class="{ 'arrowTransform': !item1.ifVisible, 'arrowTransformReturn': item1.ifVisible}" src="../../../assets/img/arrow-down.png" alt/>
<i v-else class="empty"></i>
<i :class="item1.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="twocheckitem(item1)"></i>
<i :class="item1.ischeck ? 'checked' : 'checkbox'" @click.stop="twocheckitem(item1)"></i>
<span>{{item1.label}}年级</span>
</div>
<div v-show="item1.ifVisible" v-if="item1.children&&item1.children.length!=0">
<div v-for="(item2,index2) in item1.children" :key="index2">
<div class="item2" @click.stop="open(item2)">
<img
v-if="item2.children&&item2.children.length!=0"
:class="{ 'arrowTransform': !item2.ifVisible, 'arrowTransformReturn': item2.ifVisible}"
src="../../../assets/img/icon-xiangyou.png"
alt
/>
<img v-if="item2.children&&item2.children.length!=0" :class="{ 'arrowTransform': !item2.ifVisible, 'arrowTransformReturn': item2.ifVisible}" src="../../../assets/img/arrow-down.png" alt/>
<i v-else class="empty"></i>
<i :class="item2.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="threecheckitem(item2)"></i>
<i :class="item2.ischeck ? 'checked' : 'checkbox'" @click.stop="threecheckitem(item2)"></i>
<span>{{item2.label}}</span>
</div>
<div v-show="item2.ifVisible" v-if="item2.children&&item2.children.length!=0">
<div v-for="(item3,index3) in item2.children" :key="index3">
<div class="item3" @click.stop="open(item3)">
<i :class="item3.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="fourcheckitem(item3)"></i>
<i :class="item3.ischeck ? 'checked' : 'checkbox'" @click.stop="fourcheckitem(item3)"></i>
<span>{{item3.label}}</span>
</div>
</div>
@ -164,20 +150,9 @@ export default {
@import '../../../styles/pages/tree.scss';
.side_view{
max-height: 300px;
height: auto;
padding: 0 20px 20px;
.side_tree{
.item{
padding: 5px 0;
margin-top: 10px;
}
.item2 {
margin-left: 43px
}
.item1,.item2,.item3{
padding: 0;
margin-top: 0;
margin-left: 46px
}
}
}

@ -1,7 +1,12 @@
<template>
<div>
<breadcrumb :data="'考核管理/考试监控'"></breadcrumb>
<div class="box">
<div class="left">
<div class="title">考试信息</div>
<div class="page left">
<div class="tabs">
<a class="item active">考试信息</a>
</div>
<div class="page-content">
<div class="info">
<div class="item">
<p class="key">试卷名称</p>
@ -33,32 +38,31 @@
</div>
</div>
</div>
<div class="right">
<div class="filter">
<div class="item">
<p class="key">考试状态</p>
</div>
<div class="page right">
<div class="tabs">
<a class="item active">考试实况</a>
</div>
<div class="page-content">
<div class="tool">
<ul class="filter">
<li>
<label>考试状态</label>
<el-select v-model="state" clearable placeholder="请选择考试状态" @change="getData" size="small">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in studentStateList" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</div>
<div class="item">
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入学生姓名/学号" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</div>
</div>
<div class="table">
<div class="flex-justify-end m-b-10">
</li>
</ul>
<div>
<el-button type="primary" size="small" round @click="rollUp">强制收卷</el-button>
</div>
<el-table
:data="listData"
ref="table"
row-key="id"
stripe
header-align="center"
@selection-change="handleSelectionChange"
>
</div>
<el-table :data="listData" ref="table" row-key="id" stripe header-align="center" @selection-change="handleSelectionChange">
<el-table-column type="index" width="100" label="序号" align="center">
<template
slot-scope="scope"
@ -76,25 +80,18 @@
<el-table-column prop="submit_time" label="提交时间" align="center"></el-table-column>
</el-table>
<div class="pagination">
<el-pagination
background
@current-change="handleCurrentChange"
:current-page="page"
:page-size="pageSize"
layout="total,prev, pager, next"
:total="total"
></el-pagination>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import mixins from '@/mixins/setBackground'
import { mapState,mapGetters } from 'vuex'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default {
mixins: [ mixins ],
data() {
return {
keyword: '',
@ -115,6 +112,9 @@ export default {
timer: null
};
},
components: {
breadcrumb
},
computed: {
...mapState('user', [
'userId','clientId'
@ -205,14 +205,16 @@ export default {
},
rollUp(){
if(this.listData.length){
this.$post(`${this.api.compulsory}?id=${this.id}`)
.then(res => {
this.$message.success('强制收卷成功')
this.$confirm('是否强制终止此次考试?', '提示', {
type: 'warning'
}).then(() => {
this.$post(`${this.api.compulsory}?id=${this.id}`).then(res => {
util.successMsg('强制收卷成功')
this.$router.back()
})
.catch(err => {})
}).catch(err => {})
}).catch(() => {})
}else{
this.$message.warning('没有学生在考中')
util.warningMsg('没有学生在考中')
}
}
},
@ -222,14 +224,8 @@ export default {
<style lang="scss" scoped>
.box{
display: flex;
width: 90%;
margin: 0 auto;
border: 1px solid #e8e8e8;
.left{
width: 25%;
padding: 30px;
border-right: 1px solid #e8e8e8;
box-sizing: border-box;
width: 20%;
.title{
font-size: 14px;
color: #444;
@ -239,60 +235,18 @@ export default {
display: flex;
align-items: center;
margin: 10px 0;
.key{
color: #555;
font-size: 14px;
}
.val{
flex: 1;
margin-left: 20px;
color: #333;
text-align: center;
height: 36px;
line-height: 36px;
line-height: 30px;
.key,.val{
color: rgba(0, 0, 0, 0.65);
font-size: 14px;
background-color: #f4f4f4;
border: 1px solid #e8e8e8;
box-sizing: border-box;
}
}
}
}
.right{
width: 70%;
padding: 20px;
box-sizing: border-box;
.filter{
display: flex;
justify-content: flex-end;
padding: 10px;
background-color: #efefef;
.item{
display: inline-flex;
align-items: center;
margin-left: 20px;
/deep/.el-select{
flex: 1;
}
.key{
margin-right: 20px;
white-space: nowrap;
font-size: 14px;
color: #555;
}
&.lg .key{
width: 220px;
margin-right: 10px;
text-align: right;
}
}
}
.table{
padding: 15px;
margin-top: 10px;
background-color: #efefef;
}
width: calc(80% - 24px);
margin-left: 24px;
}
}
</style>

@ -1,45 +1,74 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div class="p-title m-b-20">筛选</div>
<breadcrumb :data="'考核管理/批阅列表'"></breadcrumb>
<div class="page" style="margin-bottom: 24px">
<div class="tabs">
<a class="item active">考试信息</a>
</div>
<div class="page-content">
<ul class="list">
<li>
<div class="item">
<span class="name">考核名称</span>
<span class="val">{{assessmentName}}</span>
</div>
<div class="item">
<span class="name">考试开始时间</span>
<span class="val">{{startTime}}</span>
</div>
</li>
<li>
<div class="item">
<span class="name">考核类型</span>
<span class="val">{{type}}</span>
</div>
<div class="item">
<span class="name">考试结束时间</span>
<span class="val">{{endTime}}</span>
</div>
</li>
<li>
<div class="item">
<span class="name">考核状态</span>
<span class="val">{{status}}</span>
</div>
<div class="item">
<span class="name">考核总分</span>
<span class="val">100</span>
</div>
</li>
</ul>
</div>
</div>
<div class="flex j-between">
<el-form label-width="80px" inline>
<el-form-item class="no-mb" label="批阅状态">
<el-select v-model="state" clearable placeholder="请选择批阅状态" @change="getData">
<div class="page">
<div class="tabs">
<a class="item active">批阅列表</a>
</div>
<div class="page-content">
<div class="tool">
<ul class="filter">
<li>
<label>批阅状态</label>
<el-select v-model="state" clearable placeholder="请选择批阅状态" size="small" @change="getData">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in reviewStatusList" :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>
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入真实姓名/学号" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
</div>
</div>
</el-card>
<el-card shadow="hover" class="m-b-20">
<div class="p-title m-b-20">考试批阅</div>
<el-table
:data="listData"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
>
<el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center">
<el-table-column type="index" width="100" label="序号" align="center">
<template
slot-scope="scope"
>{{scope.$index + (page - 1) * pageSize + 1}}</template>
</el-table-column>
<el-table-column prop="stuName" label="真实姓名" align="center"></el-table-column>
<el-table-column prop="stuName" label="姓名" align="center"></el-table-column>
<el-table-column prop="stuNo" label="学号" align="center"></el-table-column>
<el-table-column prop="handPaperTime" label="交卷时间" align="center"></el-table-column>
<el-table-column prop="timeSpent" label="答题用时(分钟)" align="center">
@ -49,36 +78,32 @@
</el-table-column>
<el-table-column prop="name" label="考试状态" align="center">
<template slot-scope="scope">
{{scope.row.examinationStatus == 1 ? '已' : getExamStatusName(scope.row.examinationStatus)}}
{{scope.row.examinationStatus == 1 ? '已提交' : getExamStatusName(scope.row.examinationStatus)}}
</template>
</el-table-column>
<el-table-column prop="name" label="批阅状态" align="center">
<template slot-scope="scope">
{{getReviewStatusName(scope.row.reviewStatus)}}
{{(!scope.row.examinationStatus && !scope.row.reviewStatus) ? '--' : getReviewStatusName(scope.row.reviewStatus)}}
</template>
</el-table-column>
<el-table-column label="操作">
<el-table-column label="操作" width="100">
<template slot-scope="scope">
<el-button type="text" @click="review(scope.row,false)">查看</el-button>
<el-button type="text" @click="review(scope.row,false)" v-if="scope.row.reviewStatus == 2 || scope.row.reviewStatus == 3">查看</el-button>
<el-button type="text" @click="review(scope.row,true)" v-if="(scope.row.reviewStatus == 0 || scope.row.reviewStatus == 1) && scope.row.examinationStatus == 2">批阅</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>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</div>
</div>
</el-card>
</div>
</template>
<script>
import { mapState,mapGetters,mapActions } from 'vuex'
import breadcrumb from '@/components/breadcrumb'
import util from '@/libs/util'
export default {
data() {
return {
@ -103,6 +128,9 @@ export default {
searchTimer: null,
};
},
components: {
breadcrumb
},
filters: {
transferToMinutes(val){
return isNaN(val) ? val : (val / 60).toFixed(2)
@ -113,7 +141,7 @@ export default {
'userId','clientId'
]),
...mapState('assessment', [
'id','examStatusList'
'id','examStatusList','assessmentName','type','startTime','endTime','status'
]),
...mapGetters('assessment', [
'getReviewStatusName','getExamStatusName'
@ -162,7 +190,28 @@ export default {
</script>
<style lang="scss" scoped>
/deep/.no-mb.el-form-item{
margin-bottom: 0;
.list{
display: flex;
justify-content: center;
li{
margin-right: 100px;
&:last-child{
margin-right: 0;
}
.item{
margin: 32px 0;
.name{
display: inline-block;
width: 115px;
text-align: right;
color: rgba(0, 0, 0, 0.85);
font-size: 16px;
}
.val{
font-size: 16px;
color: rgba(0, 0, 0, 0.65);
}
}
}
}
</style>

@ -1,67 +1,38 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div class="p-title m-b-20">筛选</div>
<div class="flex j-between">
<el-form label-width="80px" inline>
<el-form-item class="no-mb" label="教学班级">
<el-select v-model="classId" clearable placeholder="请选择教学班级" @change="getData">
<breadcrumb :data="'练习管理/成绩列表'"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item active">成绩列表</a>
</div>
<div class="page-content">
<div class="tool">
<ul class="filter">
<li>
<label>教学班级</label>
<el-select v-model="classId" clearable placeholder="请选择教学班级" size="small" @change="getData">
<el-option v-for="(item,index) in classList" :key="index" :label="item.className" :value="item.classId"></el-option>
</el-select>
</el-form-item>
<el-form-item class="no-mb" label="考试名称">
<el-select v-model="assessmentName" clearable placeholder="请选择考试名称" @change="getData" disabled>
</li>
<li>
<label>考试名称</label>
<el-select v-model="assessmentName" clearable placeholder="请选择考试名称" size="small" @change="getData" disabled>
<el-option v-for="(item,index) in assessmentNameList" :key="index" :label="item.assessmentName" :value="item.assessmentName"></el-option>
</el-select>
</el-form-item>
</el-form>
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入学生姓名或学号" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
<div>
<el-input
placeholder="请输入学生姓名或学号"
prefix-icon="el-icon-search"
v-model="keyword"
clearable
></el-input>
<el-button type="primary" size="small" round @click="toStat">成绩统计</el-button>
<el-button type="primary" size="small" round @click="exportData">导出</el-button>
</div>
</div>
</el-card>
<el-card shadow="hover" class="m-b-20">
<div class="flex j-between m-b-20">
<div class="p-title">考试成绩</div>
<div>
<el-button
type="primary"
size="small"
round
@click="toStat"
>成绩统计</el-button>
<el-button
type="primary"
size="small"
round
@click="exportData"
>导出</el-button>
</div>
</div>
<el-table
:data="listData"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55"
align="center"
:reserve-selection="true"
></el-table-column>
<el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center">
<template
slot-scope="scope"
@ -91,20 +62,15 @@
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
background
@current-change="handleCurrentChange"
:current-page="page"
:page-size="pageSize"
layout="total,prev, pager, next"
:total="total"
></el-pagination>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</div>
</div>
</el-card>
</div>
</template>
<script>
import { mapState,mapActions } from 'vuex'
import util from '@/libs/util'
export default {
data() {
return {
@ -205,7 +171,7 @@ export default {
this.listData.map(n => {
if(n.thisScore == null) invalid = true
})
if(invalid) return this.$message.warning('考核未全部批阅完,无法统计成绩,请先批阅')
if(invalid) return util.warningMsg('考核未全部批阅完,无法统计成绩,请先批阅')
this.setAssDetailInfo({
id: this.listData[0].paperId,
assessmentId: this.assessmentId,
@ -215,7 +181,7 @@ export default {
})
this.$router.push('/achievement/statistics')
}else{
this.$message.warning('没有考试成绩')
util.warningMsg('没有考试成绩')
}
},
exportData(){

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

@ -1,135 +1,117 @@
<template>
<div>
<el-card shadow="hover" class="m-b-10">
<div class="title m-b-20"><img src="../../../assets/img/index/plan.png" alt=""> 我的考试计划</div>
<div>
<el-date-picker v-model="date" align="right" unlink-panels type="daterange" start-placeholder="开始日期" end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" clearable></el-date-picker>
<breadcrumb :data="'我的首页'"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item active">我的考试计划</a>
</div>
<div class="page-content">
<template v-if="listData.length">
<div class="tool">
<ul class="filter">
<li>
<label>创建时间</label>
<el-date-picker v-model="date" align="right" unlink-panels type="daterange" start-placeholder="开始日期" end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" clearable size="small"></el-date-picker>
</li>
</ul>
</div>
</el-card>
<el-card shadow="hover" class="m-b-30">
<div class="text-center text-grey m-b-10">考试计划表</div>
<el-table
:data="listData"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
>
<el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center">
<el-table-column type="index" width="100" label="序号" align="center">
<template
slot-scope="scope"
>{{scope.$index + (page - 1) * pageSize + 1}}</template>
</el-table-column>
<el-table-column prop="assessmentName" label="考名称" align="center"></el-table-column>
<el-table-column label="考类型" align="center">
<el-table-column prop="assessmentName" label="考试名称" align="center"></el-table-column>
<el-table-column label="考试类型" align="center">
<template slot-scope="scope">
{{getTypeName(scope.row.type)}}
</template>
</el-table-column>
<el-table-column prop="duration" label="考时长(分钟)" align="center"></el-table-column>
<el-table-column prop="duration" 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="name" label="考核状态" align="center">
<el-table-column prop="name" label="考试进程" align="center">
<template slot-scope="scope">
{{getStateName(scope.row.state)}}
</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>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</template>
<div class="none" v-else>暂无考试计划</div>
</div>
</div>
</el-card>
<el-card shadow="hover" class="m-b-10">
<div class="title"><img src="../../../assets/img/index/testPaper.png" alt=""> 待批阅的试卷</div>
</el-card>
<el-card shadow="hover" class="m-b-30">
<div class="page">
<div class="tabs">
<a class="item active">待批阅的试卷</a>
</div>
<div class="page-content">
<template v-if="reviewList.length">
<ul class="review">
<li v-for="(item,index) in reviewList" :key="index">
<div class="btn flex j-end">
<button type="button" @click="review(item)"><img src="../../../assets/img/index/edit.png" alt=""> 批阅</button>
</div>
<div class="text-wrap">
<p class="text">考试名称{{item.assessmentName}}</p>
<p class="text">{{item.startTime}} {{item.endTime}}</p>
<div class="member flex">
<p class="m-r-20">应试人数<span>{{item.shouldArrive}}</span></p>
<p>已考试人数<span>{{item.alreadyExam}}</span></p>
<p>已交卷人数<span>{{item.alreadyExam}}</span></p>
</div>
</div>
<button type="button" @click="review(item)">批阅</button>
</li>
</ul>
<div class="pagination">
<el-pagination
background
@current-change="handleReviewCurrentChange"
:current-page="pageReview"
:page-size="pageSizeReview"
layout="total,prev, pager, next"
:total="totalReview"
></el-pagination>
<el-pagination background @current-change="handleReviewCurrentChange" :current-page="pageReview" :page-size="pageSizeReview" layout="total,prev, pager, next" :total="totalReview"></el-pagination>
</div>
</template>
<div class="none" v-else>暂无待批阅的试卷</div>
</div>
</div>
</el-card>
<el-card shadow="hover" class="m-b-10">
<div class="title"><img src="../../../assets/img/index/class.png" alt=""> 我的班级</div>
</el-card>
<el-card shadow="hover" class="m-b-30">
<ul class="class">
<li v-for="(item,index) in classList" :key="index" :class="'index' + index" @click="toPractice(item)">
<p class="name">{{item.className}}</p>
<p class="text">班级{{item.className}}</p>
<!-- <p class="text">人数30</p> -->
<!-- <p class="text">创建时间测试</p> -->
<!-- <div class="action flex j-end">
<button class="edit" @click.stop="editClass(item)"></button>
<button class="del" @click.stop="delClass(item)"></button>
</div> -->
</li>
</ul>
<div class="page">
<div class="tabs">
<a class="item active">我开放的练习</a>
</div>
<div class="page-content">
<template v-if="practiceList.length">
<el-table :data="practiceList" class="table" stripe header-align="center" row-key="id">
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="practiseName" label="练习名称" align="center"></el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center"></el-table-column>
<el-table-column prop="className" label="练习班级" align="center"></el-table-column>
</el-table>
<div class="pagination">
<el-pagination
background
@current-change="handleClassCurrentChange"
:current-page="pageClass"
:page-size="pageSizeClass"
layout="total,prev, pager, next"
:total="totalClass"
></el-pagination>
<el-pagination background @current-change="handlePracticeCurrentChange" :current-page="pagePractice" :page-size="pageSizePractice" layout="total,prev, pager, next" :total="totalPractice"></el-pagination>
</div>
</template>
<div class="none" v-else>暂无开放的练习</div>
</div>
</div>
</el-card>
<el-card shadow="hover" class="m-b-10">
<div class="title"><img src="../../../assets/img/index/msg.png" alt=""> 待回复提问</div>
</el-card>
<el-card shadow="hover">
<div class="page">
<div class="tabs">
<a class="item active">待回复的提问</a>
</div>
<div class="page-content">
<template v-if="msgList.length">
<ul class="list">
<li v-for="(item,index) in msgList" :key="index">
<div class="item">
<div class="inner">
<img class="avatar" :src="item.userAvatars" alt="">
<div class="texts">
<div class="title">
<span class="username">{{item.userName}}</span>
<span class="publish">发表于</span>
<span class="date">{{item.createTime}}</span>
</div>
<div class="userName">{{item.userName}}</div>
<div class="desc" v-html="item.content"></div>
</div>
<div class="date">{{item.createTime}}</div>
</div>
<div class="action">
<button v-if="item.userId != userId" class="btn" @click="showReply(item)">回复</button>
<button v-else class="btn" @click="delMsg(item)">删除</button>
<button v-else class="btn del" @click="delMsg(item)">删除</button>
</div>
</div>
<div class="reply" v-if="item.showReply">
<quill :border="true" v-model="item.replyContent" :toTop="false" :height="150" />
@ -140,7 +122,10 @@
</div>
</li>
</ul>
</el-card>
</template>
<div class="none" v-else>暂无待回复的提问</div>
</div>
</div>
<el-dialog title="编辑班级" :visible.sync="classVisible" width="24%" center :close-on-click-modal="false">
<el-input placeholder="请输入班级名称" v-model="curClass.className"></el-input>
@ -155,6 +140,7 @@
import { mapState,mapGetters,mapActions } from 'vuex'
import quill from '@/components/quill'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default {
data() {
return {
@ -167,14 +153,13 @@ export default {
total: 0,
listData: [],
pageReview: 1,
pageSizeReview: 3,
pageSizeReview: 6,
totalReview: 0,
reviewList: [],
pageClass: 1,
pageSizeClass: 5,
totalClass: 0,
classList: [],
classListAll: [],
pagePractice: 1,
pageSizePractice: 5,
totalPractice: 0,
practiceList: [],
msgList: [],
curClass: {},
classVisible: false,
@ -201,7 +186,8 @@ export default {
}
},
components: {
quill
quill,
breadcrumb
},
mounted() {
let now = util.formatDate('yyyy-MM-dd')
@ -212,7 +198,7 @@ export default {
this.addInterval()
this.getData()
this.getReview()
this.getClass()
this.getPractice()
this.getMsg()
},
methods: {
@ -256,20 +242,16 @@ export default {
})
this.$router.push('/assessment/review')
},
getClass() {
this.$post(`${this.api.getMineClass}?userId=${this.userId}`)
getPractice() {
this.$post(`${this.api.pageByName}?pageNum=${this.pagePractice}&pageSize=${this.pageSizePractice}&userId=${this.userId}&practiseName=&classId=`)
.then(res => {
this.classListAll = res.data.list
this.totalClass = res.data.list.length
this.handleClassPage()
this.practiceList = res.data.list.list
this.totalPractice = res.data.list.totalCount
}).catch(err => {})
},
handleClassPage(){
this.classList = this.classListAll.slice((this.pageClass - 1) * this.pageSizeClass,this.pageClass * this.pageSizeClass)
},
handleClassCurrentChange(val) {
this.pageClass = val
this.handleClassPage()
handlePracticeCurrentChange(val) {
this.pagePractice = val
this.getPractice()
},
toPractice(row){
this.setClassInfo({
@ -283,25 +265,25 @@ export default {
this.curClass = JSON.parse(JSON.stringify(row))
},
delClass(item){
this.$confirm('确定要删除吗?', '提示', {
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', {
type: 'warning'
}).then(() => {
this.$post(`${this.api.deleteClass}?classIds=${item.classId}`).then(res => {
this.$message.success('删除成功')
this.getClass()
util.successMsg('删除成功')
this.getPractice()
}).catch(res => {})
}).catch(() => {})
},
saveClass(){
if(!this.curClass.className) return this.$message.warning('请输入班级名称')
if(isNaN(this.curClass.className)) return this.$message.warning('班级名称必须为数字')
if(!this.curClass.className) return util.warningMsg('请输入班级名称')
if(isNaN(this.curClass.className)) return util.warningMsg('班级名称必须为数字')
let data = {
className: this.curClass.className,
classId: this.curClass.classId,
gradeId: ''
}
this.$post(this.api.updateClass,data).then(res => {
this.$message.success('编辑成功')
util.successMsg('编辑成功')
this.classVisible = false
}).catch(res => {})
},
@ -326,7 +308,7 @@ export default {
},
delMsg(row){
this.$post(`${this.api.waitReplyDel}?userId=${this.userId}&bid=${row.bid}`).then(res => {
this.$message.success('删除成功')
util.successMsg('删除成功')
this.getMsg()
}).catch(res => {})
},
@ -338,7 +320,7 @@ export default {
schoolId: this.clientId,
}
this.$post(this.api.saveComment,data).then(res => {
this.$message.success('提交成功')
util.successMsg('提交成功')
row.replyContent = ''
this.getMsg()
}).catch(res => {})
@ -350,34 +332,45 @@ export default {
<style lang="scss" scoped>
@import "@/styles/pages/messageBoard.scss";
.title{
display: flex;
align-items: center;
font-size: 16px;
color: #6f6f6f;
img{
width: 20px;
margin-right: 5px;
.page{
margin-bottom: 24px;
.none{
padding: 36px 0;
text-align: center;
color: rgba(0, 0, 0, 0.25);
font-size: 18px;
}
}
.review{
display: flex;
flex-wrap: wrap;
li{
width: 32%;
min-height: 180px;
padding: 20px 30px;
margin-right: 10px;
background: url(../../../assets/img/index/testPaper-icon.png) 90% 70% no-repeat,url(../../../assets/img/index/bg.png) 0 0/100% 100% no-repeat;
display: inline-flex;
justify-content: space-between;
align-items: center;
width: calc(33.33% - 24px);
padding: 20px 30px 20px 88px;
margin: 0 24px 24px 0;
background: url(../../../assets/img/testPaper-icon.png) 16px 16px/56px 56px no-repeat;
box-shadow: 0px 12px 48px 16px rgba(0, 0, 0, 0.03), 0px 9px 28px 0px rgba(0, 0, 0, 0.05), 0px 6px 16px -8px rgba(0, 0, 0, 0.08);
border-radius: 8px;
&:nth-child(3n){
margin-right: 0;
}
.text-wrap{
display: inline-flex;
flex-direction: column;
justify-content: space-between;
flex: 1;
}
button{
color: #198cff;
font-size: 12px;
padding: 5px 16px;
color: #CC221C;
font-size: 14px;
background-color: transparent;
border: 0;
border: 1px solid;
border-radius: 4px;
cursor: pointer;
img{
width: 15px;
margin-right: 5px;
}
}
.text{
margin-bottom: 20px;
@ -388,63 +381,10 @@ export default {
font-size: 14px;
color: #444;
span{
color: #198cff;
font-weight: bold;
}
}
}
}
.class{
display: flex;
li{
width: 19.5%;
padding: 15px 20px;
margin-right: .5%;
background: url(../../../assets/img/index/bg1.png) 0 0/100% 100% no-repeat;
cursor: pointer;
&.index1{
background-image: url(../../../assets/img/index/bg2.png);
}
&.index2{
background-image: url(../../../assets/img/index/bg3.png);
}
&.index3{
background-image: url(../../../assets/img/index/bg4.png);
}
&.index4{
background-image: url(../../../assets/img/index/bg5.png);
}
.name{
padding-bottom: 5px;
margin-bottom: 10px;
text-align: center;
color: #fff;
font-size: 16px;
font-weight: bold;
border-bottom: 1px solid #fff;
}
.text{
font-size: 14px;
color: #fff;
line-height: 1.8;
}
.action{
margin-bottom: 20px;
.edit{
width: 20px;
height: 20px;
margin-right: 15px;
background-color: transparent;
border: 0;
background: url(../../../assets/img/index/pen.png) 0 0/100% 100% no-repeat;
cursor: pointer;
}
.del{
@extend .edit;
width: 16px;
background-image: url(../../../assets/img/index/del.png);
color: #CC221C;
}
}
}
}
</style>

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

@ -1,5 +1,8 @@
<template>
<div class="box">
<breadcrumb :data="'练习管理/成绩详情'"></breadcrumb>
<div class="page">
<div class="page-content">
<h1 class="title">{{paperName }}</h1>
<div class="metas">
<div class="m-r-20">
@ -24,16 +27,11 @@
<div class="wrap">
<div class="item" v-for="(item,index) in curType" :key="index">
<div class="answer">
<div class="info">
<p class="key">序号</p>
<p class="val">{{index+1}}</p>
</div>
<div class="info">
<p class="key">得分</p>
<p class="val">{{item.questionScore}}</p>
</div>
<div class="type" :class="{wrong: item.questionScore == 0,yet: !item.isCorrecting}">
<span>序号{{index+1}}</span>
<span>得分{{item.questionScore}}</span>
</div>
<div class="inner">
<div class="meta">
<p class="key">题干</p>
<p class="val" v-html="item.questionStem"></p>
@ -44,7 +42,7 @@
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p>
</div>
</div>
<div class="meta ans">
<div class="meta-mul">
<div class="info" v-if="active != 4">
<p class="key">正确答案</p>
<p class="val">{{item.answer}}</p>
@ -77,6 +75,7 @@
</div>
</div>
</div>
</div>
<div v-show="playAuth" class="el-image-viewer__wrapper" :class="{over: isDownload}" style="z-index: 2000">
<div class="el-image-viewer__mask"></div>
@ -85,14 +84,17 @@
</div>
<pdf :visible.sync="pdfVisible" :src.sync="pdfSrc"></pdf>
</div>
</div>
</div>
</template>
<script>
import setBackground from '@/mixins/setBackground'
import file from '@/mixins/file'
import { mapState } from 'vuex'
import pdf from '@/components/pdf'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default {
mixins: [ setBackground,file ],
mixins: [ file ],
data() {
return {
paperName: '',
@ -127,7 +129,7 @@ export default {
curType: []
};
},
components: { pdf },
components: { pdf,breadcrumb },
computed: {
...mapState('user', [
'userId'
@ -150,10 +152,10 @@ export default {
if(n.typeName == '填空题'){
let answer = []
for(let i in n){
if(i.includes('option')) answer.push(n[i])
if(i.includes('option') && n[i]) answer.push(n[i])
}
n.answer = answer.join('|')
n.userAnswer = n.userAnswer ? n.userAnswer.replace(/&lt;&gt;/g,'|') : ''
n.answer = answer.join('')
n.userAnswer = n.userAnswer ? n.userAnswer.split('&lt;&gt;').filter(n => n).join(',') : ''
}
if(n.typeName == '简答题'){
if(n.fileUrl) n.fileUrl = JSON.parse(n.fileUrl)
@ -199,7 +201,7 @@ export default {
if(n.typeName == '填空题') answer.push(n[i])
}
}
if(n.typeName == '填空题') n.answer = answer.join('|')
if(n.typeName == '填空题') n.answer = answer.join('')
n.options = options
}
})
@ -210,110 +212,5 @@ export default {
</script>
<style lang="scss" scoped>
.box{
width: 90%;
margin: 0 auto;
}
.title{
text-align: center;
font-size: 18px;
font-weight: 600;
}
.metas{
display: flex;
justify-content: center;
margin: 20px 0 30px;
.name{
font-size: 12px;
color: #717171;
}
.val{
font-size: 12px;
color: #929292;
}
}
.tab{
display: flex;
align-items: center;
margin-bottom: 10px;
li{
position: relative;
padding: 0 44px;
margin-right: 7px;
font-size: 13px;
line-height: 46px;
text-align: center;
color: #444;
border: 1px solid #ececec;
cursor: pointer;
&:hover{
opacity: .8;
}
&.active:after{
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 4px;
background-color: $main-color;
}
}
}
.wrap{
.item{
padding-bottom: 30px;
margin-bottom: 30px;
border-bottom: 1px dashed #f4f4f4;
.key{
font-weight: bold;
color: #333;
font-size: 14px;
}
.val{
color: #757575;
font-size: 14px;
}
.answer{
display: flex;
align-items: center;
padding: 15px;
margin: 15px 0;
font-size: 12px;
border: 1px solid #e8e8e8;
background-color: #f3f2f2;
.info{
display: inline-flex;
align-items: center;
margin-right: 30px;
}
}
.meta{
padding-left: 10px;
margin: 20px 0;
font-size: 12px;
&.ans{
display: flex;
.info{
margin-right: 20px;
}
}
.key{
margin-bottom: 5px;
}
}
}
}
.over{
top: 5000px;
}
.player{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 1200px !important;
height: 600px !important;
}
@import "@/styles/pages/testPaperDetail.scss";
</style>

@ -1,35 +1,42 @@
<template>
<div class="box">
<breadcrumb :data="'练习管理/批阅'"></breadcrumb>
<div class="page">
<div class="page-content">
<h1 class="title">{{paperName}}</h1>
<div class="metas">
<div>
<span class="name">学生姓名</span>
<span class="val">{{userName}}</span>
<ul class="metas">
<li>学生姓名{{userName}}</li>
<li>学生得分{{(reviewStatus == 2 || reviewStatus == 3) ? this_score : '--'}}</li>
<li>试卷总分100</li>
<li>练习时长{{duration}}</li>
</ul>
<div class="btn-wrap" v-if="reviewStatus == 2 || reviewStatus == 3">
<button :class="{active: look == 1}" @click="look = 1">查看全部</button>
<button :class="{active: look == 2}" v-if="reviewStatus == 2 || reviewStatus == 3" @click="look = 2">错误题</button>
</div>
<div>
<span class="name">学生得分</span>
<span class="val">{{(reviewStatus == 2 || reviewStatus == 3) ? this_score : '--'}}</span>
<div class="wrap">
<div class="item" v-for="(item,index) in list" :key="index">
<div class="type" :class="{wrong: item.questionScore == 0,yet: !item.isCorrecting}">
<span>题目类型{{item.typeName}}</span>
<span>题目分数{{item.questionPoints}}</span>
<span v-if="item.isCorrecting">考试得分{{item.questionScore}}</span>
</div>
<div>
<span class="name">试卷总分</span>
<span class="val">100</span>
<div class="inner">
<div class="meta">
<p class="key">题干:</p>
<div class="val">
<div class="name" v-html="item.questionStem"></div>
</div>
<div>
<span class="name">练习时长</span>
<span class="val">{{duration}}</span>
</div>
<div class="meta" v-if="item.typeName != '简答题' && item.typeName != '填空题'">
<p class="key">选项</p>
<div class="val">
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p>
</div>
<div class="wrap">
<div class="select">
<el-radio v-model="look" label="1">查看全部</el-radio>
<el-radio v-model="look" label="2" v-if="reviewStatus == 2 || reviewStatus == 3">只看错题</el-radio>
</div>
<div class="item" v-for="(item,index) in list" :key="index">
<div class="status" :class="{done: item.isCorrecting}">{{item.isSub ? '简答题' : '客观题'}}{{getCorrectingName(item.isCorrecting)}}</div>
<div class="name" v-html="item.questionStem"></div>
<div class="answer">
<div class="meta-mul">
<div class="info" v-if="!item.isSub">
<p class="key">正确答案</p>
<p class="val">{{item.answer}}</p>
@ -39,10 +46,6 @@
<p class="val">{{item.userAnswer}}</p>
</div>
</div>
<div class="meta">
<span class="key">知识点</span>
<span class="val">{{item.knowledgePoints}}</span>
</div>
<div class="meta" v-if="item.isSub">
<p class="key">附件</p>
<div class="val">
@ -64,13 +67,13 @@
<span class="key">答案解析</span>
<span class="val">{{item.answerAnalysis}}</span>
</div>
<div class="flex a-center point">
<div class="meta">
<span class="key">题目分数</span>
<div class="meta-mul" v-if="(reviewStatus == 0 || reviewStatus == 1) && !item.isCorrecting">
<div class="info">
<p class="key">题目分数</p>
<div class="val">{{item.questionPoints}} </div>
</div>
<div class="meta">
<span class="key">考试得分</span>
<div class="info">
<p class="key">考试得分</p>
<div class="val">
<input type="number" v-model.number="item.questionScore" :disabled="!isReview || !item.isSub">
</div>
@ -78,12 +81,14 @@
</div>
</div>
</div>
</div>
<div class="btns" v-if="isReview">
<button type="button" class="submit" @click="save(1)">提交</button>
<button type="button" @click="save(0)">保存</button>
</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>
@ -93,12 +98,13 @@
</div>
</template>
<script>
import setBackground from '@/mixins/setBackground'
import file from '@/mixins/file'
import { mapState,mapGetters,mapActions } from 'vuex'
import pdf from '@/components/pdf'
import breadcrumb from '@/components/breadcrumb'
import util from '@/libs/util'
export default {
mixins: [ setBackground,file ],
mixins: [ file ],
data() {
return {
paperName: '',
@ -125,7 +131,7 @@ export default {
val == 1 ? this.getData() : this.getWrong()
}
},
components: { pdf },
components: { pdf,breadcrumb },
mounted() {
this.getData()
},
@ -140,10 +146,10 @@ export default {
if(n.typeName == '填空题'){
let answer = []
for(let i in n){
if(i.includes('option')) answer.push(n[i])
if(i.includes('option') && n[i]) answer.push(n[i])
}
n.answer = answer.join('|')
n.userAnswer = n.userAnswer ? n.userAnswer.replace(/&lt;&gt;/g,'|') : ''
n.answer = answer.join('')
n.userAnswer = n.userAnswer ? n.userAnswer.split('&lt;&gt;').filter(n => n).join(',') : ''
}
if(n.fileUrl) n.fileUrl = JSON.parse(n.fileUrl)
if(n.videoAudio) n.videoAudio = JSON.parse(n.videoAudio)
@ -156,8 +162,7 @@ export default {
}).catch(err => {})
},
getWrong(){
this.$post(`${this.api.getWrongPractice}?practiseId=${this.practiseId}&userId=${this.stuId}&identification=${this.identification}`)
.then(res => {
this.$post(`${this.api.getWrongPractice}?practiseId=${this.practiseId}&userId=${this.stuId}&identification=${this.identification}`).then(res => {
let list = res.data.list
list.map(n => {
n.userAnswer = n.user_answer
@ -182,10 +187,10 @@ export default {
if(Number(n.questionScore) > Number(n.questionPoints)) invalid = true
})
if(status){
if(isEmpty) return this.$message.warning('请批阅完所有题目')
if(isNotNum) return this.$message.warning('考试得分请输入数字')
if(isEmpty) return util.warningMsg('请批阅完所有题目')
if(isNotNum) return util.warningMsg('考试得分请输入数字')
}
if(invalid) return this.$message.warning('考试得分不得大于题目分数')
if(invalid) return util.warningMsg('考试得分不得大于题目分数')
let data = {
identification: this.identification,
review: [],
@ -200,13 +205,13 @@ export default {
})
totalScore += Number(n.questionScore)
})
if(!data.review.length) return this.$message.warning('请至少批阅一道题目')
if(!data.review.length) return util.warningMsg('请至少批阅一道题目')
if(status || this.list.filter(n => n.isSub).length == data.review.length){
data.totalScore = totalScore
}
this.$post(this.api.reviewByidPractice,data).then(res => {
this.$message.success(status ? '提交成功' : '保存成功')
util.successMsg(status ? '提交成功' : '保存成功')
this.$router.back()
}).catch(err => {})
},
@ -217,98 +222,106 @@ export default {
<style lang="scss" scoped>
.title{
text-align: center;
font-size: 18px;
font-weight: 600;
font-size: 20px;
color: rgba(0, 0, 0, 0.85);
}
.metas{
display: flex;
justify-content: space-between;
margin: 20px 0 30px;
.name{
font-size: 12px;
color: #717171;
justify-content: center;
padding-bottom: 24px;
margin: 24px 0;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
li{
margin-right: 40px;
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
}
.val{
font-size: 12px;
color: #929292;
}
.btn-wrap{
display: flex;
justify-content: center;
button{
padding: 0 16px;
margin-right: 16px;
line-height: 30px;
color: rgba(0, 0, 0, 0.65);
font-size: 14px;
background-color: #fff;
border: 1px solid;
border-radius: 4px;
cursor: pointer;
&.active{
color: #CC221C;
}
}
.wrap{
padding: 20px;
background-color: #fbfbfb;
.select{
padding: 10px;
margin-bottom: 20px;
border-bottom: 1px solid #f4f4f4;
}
.wrap{
margin-top: 24px;
.item{
padding-bottom: 30px;
margin-bottom: 30px;
border-bottom: 1px dashed #d2d2d2;
&:last-child{
border-bottom: 0;
border: 1px solid rgba(0, 0, 0, 0.06);
border-radius: 8px;
.type{
padding: 0 24px;
margin-top: -1px;
color: rgba(0, 0, 0, 0.85);
line-height: 52px;
font-size: 14px;
background-color: #F6FFED;
border: 1px solid #B7EB8F;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
&.wrong{
border: 1px solid #FFA39E;
background: #FFF1F0;
}
&.yet{
border: 1px solid rgba(0, 0, 0, 0.06);
background: rgba(0, 0, 0, 0.04);
}
span{
margin-right: 24px;
}
.status{
color: #cb221c;
&.done{
color: #56d5bf;
}
.inner{
padding: 24px;
}
.name{
margin-top: 15px;
font-size: 14px;
color: #555555;
}
.meta{
margin-bottom: 16px;
}
.key{
font-weight: bold;
color: #333;
margin-bottom: 8px;
color: rgba(0, 0, 0, 0.85);
font-size: 16px;
}
.val{
color: #757575;
color: rgba(0, 0, 0, 0.65);
font-size: 14px;
}
.answer{
.meta-mul{
display: flex;
align-items: center;
padding: 15px;
margin: 15px 0;
font-size: 12px;
border: 1px solid #e8e8e8;
background-color: #f3f2f2;
margin-bottom: 15px;
.info{
display: inline-flex;
align-items: center;
margin-right: 30px;
}
}
.meta{
display: flex;
align-items: center;
padding-left: 10px;
margin: 10px 0;
font-size: 12px;
.key{
width: 80px;
margin-right: 10px;
text-align: right;
white-space: nowrap;
margin-right: 32px;
}
input{
width: 60px;
height: 28px;
padding: 0 5px;
margin-right: 5px;
color: #444;
background-color: #fff;
border: 1px solid #ebebeb;
box-sizing: border-box;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
&:focus{
outline: none;
}
&:disabled{
background-color: #e8e8e8;
background-color: rgba(0, 0, 0, 0.04);
color: rgba(0, 0, 0, 0.25);
cursor: not-allowed;
}
}

@ -1,55 +1,38 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div>
<div class="p-title m-b-20">筛选</div>
<p class="class-name m-b-10" v-if="className">班级名称{{className}}</p>
<div class="flex">
<div>
<el-input placeholder="请输入练习名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</div>
<breadcrumb :data="'练习管理/练习列表'"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item active">练习列表</a>
</div>
</div>
</el-card>
<el-card shadow="hover">
<div class="flex j-between m-b-20">
<div class="p-title">练习列表</div>
<div class="page-content">
<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>
<li v-if="className">
<label>班级名称</label>
<p class="class-name">{{className}}</p>
</li>
</ul>
<div>
<el-button type="primary" size="small" round @click="addAss" v-auth>创建练习</el-button>
</div>
</div>
<el-table :data="listData" class="table" stripe header-align="center" row-key="id">
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="practiseName" label="练习名称" align="center"></el-table-column>
<el-table-column prop="paperName" label="练习内容" align="center"></el-table-column>
<el-table-column prop="questionsNum" label="练习题数" align="center"></el-table-column>
<el-table-column prop="peopleNum" label="练习人数" align="center"></el-table-column>
<el-table-column prop="totalScore" label="练习总分" align="center"></el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center"></el-table-column>
<el-table-column prop="className" label="练习班级" align="center"></el-table-column>
<el-table-column label="操作" width="280">
<el-table-column label="操作" width="220">
<template slot-scope="scope">
<el-popover
placement="bottom"
width="400"
trigger="click">
<div class="details">
<div class="line">
<span class="key">练习内容</span>
<p class="val">{{assContent}}</p>
</div>
<div class="line">
<span class="key">练习题数</span>
<p class="val">{{quesNum}}</p>
</div>
<div class="line">
<span class="key">练习人数</span>
<p class="val">{{assPeopleNum}}</p>
</div>
<div class="line">
<span class="key">练习总分</span>
<p class="val">100</p>
</div>
</div>
<el-button type="text" slot="reference" @click="show(scope.row)" v-auth>查看</el-button>
</el-popover>&nbsp;
<el-button type="text" @click="edit(scope.row)" v-auth>修改</el-button>
<el-button type="text" @click="delData(scope.row)" v-auth>删除</el-button>
<el-button type="text" @click="review(scope.row)" v-auth>批阅</el-button>
@ -61,62 +44,51 @@
<el-pagination background @current-change="handleCurrentChange" :current-page="page" layout="total, prev, pager, next" :total="total">
</el-pagination>
</div>
</el-card>
</div>
</div>
<el-dialog :title="isAdd ? '创建练习' : '修改练习'" :visible.sync="addVisible" width="50%" @close="closeAdd" :close-on-click-modal="false">
<el-dialog :title="isAdd ? '创建练习' : '修改练习'" :visible.sync="addVisible" width="540px" @close="closeAdd" :close-on-click-modal="false">
<el-form ref="form" label-width="100px">
<el-form-item label="练习名称">
<el-input v-model="form.practiseName" size="small" placeholder="请输入练习名称"></el-input>
</el-form-item>
<el-form-item label="试卷选择">
<el-button type="primary" size="small" @click="openSelect">试卷选择</el-button>
<el-tag
class="m-l-10"
v-if="testPaperName"
closable
@close="removeTestPaper">
{{testPaperName}}
</el-tag>
<div class="btn-wrap">
<div class="paper-name" v-if="testPaperName">
<img src="../../../assets/img/testPaper.png" alt="">
<span>{{testPaperName}}</span>
</div>
<button type="button" @click="openSelect">选择试卷</button>
</div>
</el-form-item>
<el-form-item label="发布班级">
<el-form-item label="练习班级">
<studentSide ref="getSelectData" :classId="form.classId" :key="stuCompKey" @fircheck="fircheck" @twocheck="twocheck" @threecheck="threecheck"></studentSide>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="addVisible = false">取消</el-button>
<el-button type="primary" @click="save">确定</el-button>
<el-button size="small" @click="addVisible = false">取消</el-button>
<el-button size="small" type="primary" @click="save">确定</el-button>
</span>
</el-dialog>
<el-dialog title="试卷选择" :visible.sync="selectVisible" width="40%" @close="closeSelect" :close-on-click-modal="false">
<div class="flex j-end m-b-20">
<el-form label-width="80px" inline>
<el-form-item class="no-mb" label="所属课程">
<el-select v-model="cid" clearable placeholder="请选择所属课程" @change="getPapers">
<el-dialog title="选择试卷" :visible.sync="selectVisible" width="800px" @close="closeSelect" :close-on-click-modal="false">
<div class="tool">
<ul class="filter">
<li>
<label>所属课程</label>
<el-select v-model="cid" clearable placeholder="请选择所属课程" size="small" @change="getPapers">
<el-option v-for="(item,index) in coursesList" :key="index" :label="item" :value="item"></el-option>
</el-select>
</el-form-item>
<el-form-item class="no-mb">
<el-input
placeholder="请输入试卷名称"
prefix-icon="el-icon-search"
v-model="keywordPaper"
clearable
></el-input>
</el-form-item>
</el-form>
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入试卷名称" prefix-icon="el-icon-search" v-model="keywordPaper" clearable size="small"></el-input>
</li>
</ul>
</div>
<el-table
:data="testPaperData"
max-height="400"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
>
<el-table :data="testPaperData" max-height="400" ref="table" row-key="id" class="table" stripe header-align="center">
<el-table-column width="60" label="选择" align="center">
<template slot-scope="scope">
<el-radio v-model="testPaperId" :label="scope.row.id">&nbsp;</el-radio>
@ -135,16 +107,6 @@
</template>
</el-table-column>
</el-table>
<!-- <div class="pagination">
<el-pagination
background
@current-change="handleCurrentChange"
:current-page="pagePaper"
:page-size="pageSizePaper"
layout="total,prev, pager, next"
:total="totalPaper"
></el-pagination>
</div> -->
<span slot="footer" class="dialog-footer">
<el-button @click="selectVisible = false">取消</el-button>
@ -163,6 +125,7 @@ import { mapState,mapGetters,mapActions } from 'vuex'
import studentSide from './studentSide'
import testPaperDetail from '@/components/testPaperDetail'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default {
data() {
return {
@ -208,7 +171,7 @@ export default {
};
},
components: {
studentSide,testPaperDetail
studentSide,testPaperDetail,breadcrumb
},
computed: {
...mapState('user', [
@ -325,12 +288,12 @@ export default {
this.getData();
},
delData(row) {
this.$confirm('确定要删除吗?', '提示', {
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', {
type: 'warning'
})
.then(() => {
this.$post(`${this.api.cancelPractise}?practiseId=${row.practiseId}`).then(res => {
this.$message.success('删除成功')
util.successMsg('删除成功')
this.getData()
}).catch(res => {})
})
@ -365,9 +328,9 @@ export default {
},
save(){
let form = this.form
if(form.practiseName === '') return this.$message.warning('请填写练习名称')
if(form.testPaperId === '') return this.$message.warning('请选择试卷')
if(form.classId === '') return this.$message.warning('请选择发布班级')
if(form.practiseName === '') return util.warningMsg('请填写练习名称')
if(form.testPaperId === '') return util.warningMsg('请选择试卷')
if(form.classId === '') return util.warningMsg('请选择发布班级')
let data = {
practiseId: form.practiseId,
@ -378,14 +341,14 @@ export default {
}
if(this.form.practiseId){
this.$post(this.api.updatePractise, data).then(res => {
this.$message.success('修改成功')
util.successMsg('修改成功')
this.addVisible = false
this.getData()
})
.catch(err => {})
}else{
this.$post(this.api.createPractise, data).then(res => {
this.$message.success('创建成功')
util.successMsg('创建成功')
this.addVisible = false
this.getData()
})
@ -439,7 +402,7 @@ export default {
this.previewVisible = true
},
savePaper(){
if(this.testPaperId === '') return this.$message.error('请选择试卷')
if(this.testPaperId === '') return util.errorMsg('请选择试卷')
this.form.testPaperId = this.testPaperId
this.testPaperName = this.testPaperData.find(n => n.id == this.testPaperId).name
this.selectVisible = false
@ -470,6 +433,16 @@ export default {
}
</script>
<style lang="scss" scoped>
.paper-name{
display: inline-flex;
align-items: center;
margin-right: 16px;
color: rgba(0, 0, 0, 0.65);
font-size: 16px;
img{
margin-right: 4px;
}
}
.class-name{
font-size: 12px;
color: #444;

@ -5,42 +5,32 @@
<div v-if="keyword" class="side_tree" @click.stop="open(item)">
<div v-for="(item,index) in classList" :key="index">
<div class="item" @click.stop="open(item)">
<i :class="item.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="fircheckitem(item)"></i>
<i :class="item.ischeck ? 'checked' : 'checkbox'" @click.stop="fircheckitem(item)"></i>
<span>{{item.label}}</span>
</div>
</div>
</div>
<div v-else class="side_tree" @click.stop="open(item)" v-for="(item,index) in data" :key="index">
<div class="item" @click.stop="open(item)">
<img
v-if="item.children&&item.children.length!=0"
:class="{ 'arrowTransform': !item.ifVisible, 'arrowTransformReturn': item.ifVisible}"
src="../../../assets/img/icon-xiangyou.png"
alt
/>
<img v-if="item.children&&item.children.length!=0" :class="{ 'arrowTransform': !item.ifVisible, 'arrowTransformReturn': item.ifVisible}" src="../../../assets/img/arrow-down.png" alt/>
<i v-else class="empty"></i>
<i :class="item.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="fircheckitem(item)"></i>
<i :class="item.ischeck ? 'checked' : 'checkbox'" @click.stop="fircheckitem(item)"></i>
<span>{{item.label}}</span>
</div>
<div v-show="item.ifVisible" v-if="item.children&&item.children.length!=0">
<div v-for="(item1,index1) in item.children" :key="index1">
<div class="item1" @click.stop="open(item1)">
<img
v-if="item1.children&&item1.children.length!=0"
:class="{ 'arrowTransform': !item1.ifVisible, 'arrowTransformReturn': item1.ifVisible}"
src="../../../assets/img/icon-xiangyou.png"
alt
/>
<img v-if="item1.children&&item1.children.length!=0" :class="{ 'arrowTransform': !item1.ifVisible, 'arrowTransformReturn': item1.ifVisible}" src="../../../assets/img/arrow-down.png" alt/>
<i v-else class="empty"></i>
<i :class="item1.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="twocheckitem(item1)"></i>
<i :class="item1.ischeck ? 'checked' : 'checkbox'" @click.stop="twocheckitem(item1)"></i>
<span>{{item1.label}}年级</span>
</div>
<div v-show="item1.ifVisible" v-if="item1.children&&item1.children.length!=0">
<div v-for="(item2,index2) in item1.children" :key="index2">
<div class="item2" @click.stop="open(item2)">
<i :class="item2.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="threecheckitem(item2)"></i>
<i :class="item2.ischeck ? 'checked' : 'checkbox'" @click.stop="threecheckitem(item2)"></i>
<span>{{item2.label}}</span>
</div>
</div>
@ -145,20 +135,9 @@ export default {
@import '../../../styles/pages/tree.scss';
.side_view{
max-height: 300px;
height: auto;
padding: 0 20px 20px;
.side_tree{
.item{
padding: 5px 0;
margin-top: 10px;
}
.item2 {
margin-left: 80px
}
.item1,.item2{
padding: 0;
margin-top: 0;
margin-left: 76px
}
}
}

@ -1,71 +1,61 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div class="p-title m-b-20">筛选</div>
<div class="flex j-between">
<el-form label-width="80px" inline>
<el-form-item class="no-mb" label="批阅状态">
<el-select v-model="state" clearable placeholder="请选择批阅状态" @change="getData">
<breadcrumb :data="'练习管理/批阅列表'"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item active">批阅列表</a>
</div>
<div class="page-content">
<div class="tool">
<ul class="filter">
<li>
<label>批阅状态</label>
<el-select v-model="state" clearable placeholder="请选择批阅状态" size="small" @change="getData">
<el-option label="不限" value="3"></el-option>
<el-option v-for="(item,index) in reviewStatusList" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-form>
</li>
</ul>
</div>
</el-card>
<el-card shadow="hover" class="m-b-20">
<el-table
:data="listData"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
>
<el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center">
<el-table-column type="index" width="100" label="序号" align="center">
<template
slot-scope="scope"
>{{scope.$index + (page - 1) * pageSize + 1}}</template>
</el-table-column>
<el-table-column prop="userName" label="真实姓名" align="center"></el-table-column>
<el-table-column prop="userName" label="姓名" align="center"></el-table-column>
<el-table-column prop="workNumber" label="学号" align="center"></el-table-column>
<el-table-column prop="examTime" label="开始时间" align="center"></el-table-column>
<el-table-column prop="timeCost" label="答题用时(分钟)" align="center"></el-table-column>
<el-table-column prop="workNumber" label="练习状态" align="center">
<el-table-column prop="workNumber" label="练习进度" align="center">
<template slot-scope="scope">
{{getExamStatusName(scope.row.state)}}
</template>
</el-table-column>
<el-table-column label="批阅状态" align="center">
<template slot-scope="scope">
{{getReviewStatusName(scope.row.reviewStatus)}}
{{(!scope.row.state && !scope.row.reviewStatus) ? '--' : getReviewStatusName(scope.row.reviewStatus)}}
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<el-table-column label="操作" width="100" align="center">
<template slot-scope="scope">
<el-button type="text" @click="review(scope.row,false)">查看</el-button>
<el-button type="text" @click="review(scope.row,false)" v-if="scope.row.reviewStatus == 2 || scope.row.reviewStatus == 3">查看</el-button>
<el-button type="text" @click="review(scope.row,true)" v-if="(scope.row.reviewStatus == 0 || scope.row.reviewStatus == 1) && scope.row.state == 2">批阅</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>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</div>
</div>
</el-card>
</div>
</template>
<script>
import { mapState,mapGetters,mapActions } from 'vuex'
import breadcrumb from '@/components/breadcrumb'
import util from '@/libs/util'
export default {
data() {
return {
@ -90,6 +80,7 @@ export default {
searchTimer: null,
};
},
components: {breadcrumb},
computed: {
...mapState('practice', [
'practiseId','userId'

@ -1,46 +1,34 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div class="p-title m-b-20">筛选</div>
<div class="flex j-between">
<el-form label-width="80px" inline>
<el-form-item class="no-mb" label="批阅状态">
<el-select v-model="state" clearable placeholder="请选择批阅状态" @change="getData">
<breadcrumb :data="'练习管理/批阅列表'"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item active">批阅列表</a>
</div>
<div class="page-content">
<div class="tool">
<ul class="filter">
<li>
<label>批阅状态</label>
<el-select v-model="state" clearable placeholder="请选择批阅状态" size="small" @change="getData">
<el-option label="不限" value="3"></el-option>
<el-option v-for="(item,index) in reviewStatusList" :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>
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入学生姓名/学号" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
</div>
</div>
</el-card>
<el-card shadow="hover" class="m-b-20">
<div class="p-title m-b-20">练习批阅</div>
<el-table
:data="listData"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
>
<el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center">
<el-table-column type="index" width="100" label="序号" align="center">
<template
slot-scope="scope"
>{{scope.$index + (page - 1) * pageSize + 1}}</template>
</el-table-column>
<el-table-column prop="userName" label="真实姓名" align="center"></el-table-column>
<el-table-column prop="userName" label="姓名" align="center"></el-table-column>
<el-table-column prop="workNumber" label="学号" align="center"></el-table-column>
<el-table-column label="批阅状态" align="center">
<template slot-scope="scope">
@ -49,26 +37,22 @@
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="text" @click="review(scope.row,false)">查看</el-button>
<el-button type="text" @click="review(scope.row,false)">查看练习历史</el-button>
<el-button type="text" @click="review(scope.row,true)" v-if="(scope.row.reviewStatus == 0 || scope.row.reviewStatus == 1) && scope.row.examinationStatus == 2">批阅</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>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</div>
</div>
</el-card>
</div>
</template>
<script>
import { mapState,mapGetters,mapActions } from 'vuex'
import breadcrumb from '@/components/breadcrumb'
import util from '@/libs/util'
export default {
data() {
return {
@ -93,6 +77,7 @@ export default {
searchTimer: null,
};
},
components: {breadcrumb},
computed: {
...mapState('user', [
'userId','clientId'

@ -1,61 +1,31 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div class="p-title m-b-20">筛选</div>
<div class="flex j-between">
<el-form label-width="80px" inline>
<el-form-item class="no-mb" label="教学班级">
<el-select v-model="classId" clearable placeholder="请选择教学班级" @change="getData">
<breadcrumb :data="'练习管理/成绩列表'"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item active">成绩列表</a>
</div>
<div class="page-content">
<div class="tool">
<ul class="filter">
<li>
<label>教学班级</label>
<el-select v-model="classId" clearable placeholder="请选择教学班级" size="small" @change="getData">
<el-option v-for="(item,index) in classList" :key="index" :label="item.className" :value="item.classId"></el-option>
</el-select>
</el-form-item>
<el-form-item class="no-mb" label="练习名称">
<el-select v-model="practiseId" clearable placeholder="请选择练习名称" @change="getData" :disabled="classIdAss ? true : classId == ''">
<el-option v-for="(item,index) in practiceNameList" :key="index" :label="item.practiseName" :value="item.practiseId"></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="flex j-between m-b-20">
<div class="p-title">练习成绩</div>
</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="exportData"
>导出</el-button>
<el-button type="primary" size="small" round @click="exportData">导出</el-button>
</div>
</div>
<el-table
:data="listData"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55"
align="center"
:reserve-selection="true"
></el-table-column>
<el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center">
<template
slot-scope="scope"
@ -85,37 +55,22 @@
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
background
@current-change="handleCurrentChange"
:current-page="page"
:page-size="pageSize"
layout="total,prev, pager, next"
:total="total"
></el-pagination>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</el-card>
<el-dialog title="练习成绩详情" :visible.sync="detailVisible" width="40%" :close-on-click-modal="false">
<div class="flex flex-j-e">
<div class="m-b-20">
<el-input
placeholder="请输入练习项目名称"
prefix-icon="el-icon-search"
v-model="keywordAch"
clearable
></el-input>
</div>
</div>
<el-table
:data="achiList"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
>
<el-dialog title="练习成绩详情" :visible.sync="detailVisible" width="800px" :close-on-click-modal="false">
<div class="tool">
<ul class="filter">
<li>
<label>搜索</label>
<el-input placeholder="请输入练习项目名称" prefix-icon="el-icon-search" v-model="keywordAch" clearable size="small"></el-input>
</li>
</ul>
</div>
<el-table :data="achiList" 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"
@ -135,14 +90,7 @@
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
background
@current-change="handleAchCurrentChange"
:current-page="pageAch"
:page-size="pageSizeAch"
layout="total,prev, pager, next"
:total="totalAch"
></el-pagination>
<el-pagination background @current-change="handleAchCurrentChange" :current-page="pageAch" :page-size="pageSizeAch" layout="total,prev, pager, next" :total="totalAch"></el-pagination>
</div>
<span slot="footer" class="dialog-footer">
@ -155,6 +103,8 @@
<script>
import { mapState,mapActions } from 'vuex'
import Setting from '@/setting'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default {
data() {
return {
@ -177,6 +127,9 @@ export default {
totalAch: 0,
};
},
components: {
breadcrumb
},
computed: {
...mapState('user', [
'userId'
@ -262,7 +215,7 @@ export default {
this.getData()
},
exportData(){
location.href = `${Setting.apiBaseURL}${this.api.exportPractice}?practiseId=${this.practiseId}&classId=${this.classId}`
location.href = `${Setting.apiBaseURL}${this.api.exportPractice}?practiseId=${this.practiseId}&classId=${this.classId}&className=${this.classList.find(n => n.classId == this.classId).className}`
},
}
};

@ -1,41 +1,33 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div>
<div class="p-title m-b-20">筛选</div>
<div class="flex j-between no-mb">
<div>
<el-form label-width="80px" inline>
<el-form-item class="no-mb" label="创建人">
<el-select v-model="createUser" clearable placeholder="请选择创建人" @change="getData">
<div class="tool">
<ul class="filter">
<li>
<label>创建人</label>
<el-select v-model="createUser" clearable placeholder="请选择创建人" size="small" @change="getData">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in createUserList" :key="index" :label="item.name" :value="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item class="no-mb" label="试题类型">
<el-select v-model="name" clearable placeholder="请选择试题类型" @change="getData">
</li>
<li>
<label>题目类型</label>
<el-select v-model="name" 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.name"></el-option>
</el-select>
</el-form-item>
</el-form>
</div>
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入题干/知识点" suffix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
<div>
<el-input placeholder="请输入题干/知识点" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
<el-button type="primary" size="small" round @click="delAllData" v-auth="'/quesBank/list:校企公共题库:批量取消共享'">批量取消共享</el-button>
</div>
</div>
</div>
</el-card>
<el-card shadow="hover">
<div class="flex j-between m-b-20">
<div class="p-title">公共题库</div>
<div>
<el-button type="primary" size="small" round @click="delAllData" v-auth="'/quesBank/list:公共题库:批量取消共享'">批量取消共享</el-button>
</div>
</div>
<el-table :data="listData" class="table" stripe header-align="center" row-key="id" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="questionStem" :show-overflow-tooltip="true" label="题干" align="center"></el-table-column>
<el-table-column prop="name" label="试题类型" width="100" align="center"></el-table-column>
@ -47,8 +39,8 @@
<el-table-column prop="createUser" label="创建人" width="100" align="center"></el-table-column>
<el-table-column label="操作" align="center" width="120">
<template slot-scope="scope">
<el-button type="text" @click="show(scope.row)" v-auth="'/quesBank/list:公共题库:查看'">查看</el-button>
<el-button v-if="scope.row.createUser != '系统内置'" type="text" @click="delData(scope.row)" v-auth="'/quesBank/list:公共题库:取消共享'">取消共享</el-button>
<el-button type="text" @click="show(scope.row)" v-auth="'/quesBank/list:校企公共题库:查看'">查看</el-button>
<el-button v-if="scope.row.createUser != '系统内置'" type="text" @click="delData(scope.row)" v-auth="'/quesBank/list:校企公共题库:取消共享'">取消共享</el-button>
</template>
</el-table-column>
</el-table>
@ -56,9 +48,37 @@
<el-pagination background @current-change="handleCurrentChange" :current-page="page" layout="total, prev, pager, next" :total="total">
</el-pagination>
</div>
</el-card>
<ques-dialog ref="quesDialog" :title="topicsTitle" :visible.sync="visible" :isDetail.sync="isDetail" @getData="dialogGetData" @closeTopics="closeTopics"></ques-dialog>
<el-dialog title="查看题目" :visible.sync="visible" width="870px" class="dialog" :close-on-click-modal="false">
<ul class="list">
<li>
<span class="name">所属题库</span>
<span class="val">{{topicForm.cid ? quesBankList.find(n => n.cid == topicForm.cid).typeName : ''}}</span>
</li>
<li>
<span class="name">所属课程</span>
<span class="val">{{topicForm.courses}}</span>
</li>
<li>
<span class="name">知识点</span>
<span class="val">{{topicForm.knowledgePoints}}</span>
</li>
<li>
<span class="name">题型</span>
<span class="val">{{topicForm.questionType}}</span>
</li>
<li>
<span class="name">题干</span>
<div class="val">
<div v-html="topicForm.questionStem"></div>
</div>
</li>
<li>
<span class="name">答案解析</span>
<span class="val">{{topicForm.answerAnalysis}}</span>
</li>
</ul>
</el-dialog>
</div>
</template>
@ -88,7 +108,9 @@ export default {
searchTimer: null,
isDetail: false,
visible: false,
topicsTitle: ''
topicsTitle: '',
quesBankList: [],
topicForm: {}
};
},
computed: {
@ -100,6 +122,7 @@ export default {
mounted() {
this.getData()
this.getType()
this.getQuesBank()
},
watch: {
keyword: function(val) {
@ -126,11 +149,9 @@ export default {
.catch(err => {})
},
getType() {
this.$get(this.api.typesList)
.then(res => {
this.$get(this.api.typesList).then(res => {
this.typeList = res.data.list
})
.catch(err => {})
}).catch(err => {})
},
handleCurrentChange(val) {
this.page = val;
@ -140,12 +161,12 @@ export default {
this.multipleSelection = val;
},
delData(row) {
this.$confirm('确定要取消共享吗?', '提示', {
this.$confirm('确定要取消共享该选中的题目吗?', '提示', {
type: 'warning'
})
.then(() => {
this.$post(`${this.api.deleteByMeSubjectBySharing}?identification=2&ids=${row.id}`).then(res => {
this.$message.success('取消共享成功')
util.successMsg('取消共享成功')
this.getData()
}).catch(res => {});
})
@ -158,19 +179,19 @@ export default {
return item.id
})
this.$confirm('确定要取消共享吗?', '提示', {
this.$confirm(`是否确认取消共享${util.ellipsisStr(newArr[0].questionStem)}${newArr.length}个选中的题目?`, '提示', {
type: 'warning'
})
.then(() => {
this.$post(`${this.api.deleteByMeSubjectBySharing}?identification=2&ids=${delList.join()}`).then(res => {
this.multipleSelection = [];
this.$message.success('取消共享成功')
util.successMsg('取消共享成功')
this.getData()
}).catch(res => {});
}).catch(res => {})
})
.catch(() => {});
}else{
this.$message.error('请先选择数据!');
util.errorMsg('请先选择数据!')
}
},
dialogGetData(){
@ -182,8 +203,56 @@ export default {
this.visible = true
this.isDetail = false
},
getQuesBank() {
let data = {
pageNum: 1,
pageSize: 10000,
schoolId: this.clientId,
source: 2
}
this.$post(this.api.listByPage,data).then(res => {
let list = res.data.list.list
let result = []
list.map(n => {
result.push(n)
if(n.secondColumn.length) result = result.concat(n.secondColumn)
})
this.quesBankList = result
}).catch(err => {})
},
getDetail(id) {
this.$refs.quesDialog.getData(id)
this.$post(`${this.api.findById}?id=${id}`).then(res => {
let list = res.data.list
this.topicForm = {
id: list.id,
userId: list.userId,
schoolId: this.clientId,
cid : list.cid,
typeId: list.typeId,
courses: list.courses,
knowledgePoints: list.knowledgePoints,
answer: list.answer,
questionType: '',
questionStem: list.questionStem,
optionA: list.optionA,
optionB: list.optionB,
optionC: list.optionC,
optionD: list.optionD,
optionE: list.optionE,
optionF: list.optionF,
aisTrue: false,
bisTrue: false,
cisTrue: false,
disTrue: false,
eisTrue: false,
fisTrue: false,
judgeOptionA: '正确',
judgeOptionB: '错误',
answerAnalysis: list.answerAnalysis,
videoAudio: list.videoAudio
}
console.log(this.topicForm,this.quesBankList)
}).catch(err => {})
},
edit(row) {
this.topicsTitle = '编辑题目'
@ -204,7 +273,22 @@ export default {
}
</script>
<style lang="scss" scoped>
/deep/.no-mb.el-form-item{
margin-bottom: 0;
.list{
li{
display: flex;
margin-bottom: 16px;
.name{
width: 80px;
text-align: right;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
white-space: nowrap;
}
.val{
max-width: calc(100% - 80px);
font-size: 16px;
color: rgba(0, 0, 0, 0.65);
}
}
}
</style>

@ -1,12 +1,16 @@
<template>
<div>
<div class="tabs m-b-20">
<breadcrumb :data="'题库资源管理/' + tabs[active]" ref="breadcrumb"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{item}}</a>
</div>
<ques-bank-type v-if="active == 'type'" v-auth="'题库管理:题库分类'"></ques-bank-type>
<my-ques-bank v-else-if="active == 'my'" v-auth="'题库管理:我上传的题库'"></my-ques-bank>
<global-ques-bank v-else v-auth="'题库管理:公共题库'"></global-ques-bank>
<div class="page-content">
<ques-bank-type v-if="active == 'type'" v-auth="'题库资源管理:题库分类'"></ques-bank-type>
<my-ques-bank v-else-if="active == 'my'" v-auth="'题库资源管理:我上传的题库'"></my-ques-bank>
<global-ques-bank v-else v-auth="'题库资源管理:校企公共题库'"></global-ques-bank>
</div>
</div>
</div>
</template>
<script>
@ -15,14 +19,15 @@ import Setting from '@/setting'
import quesBankType from './quesBankType'
import myQuesBank from './myQuesBank'
import globalQuesBank from './globalQuesBank'
import breadcrumb from '@/components/breadcrumb'
export default {
data() {
return {
active: 'type',
active: 'my',
tabs: {
type: '题库分类',
my: '我上传的题库',
global: '公共题库'
global: '校企公共题库',
type: '题库分类',
},
};
},
@ -30,6 +35,7 @@ export default {
quesBankType,
myQuesBank,
globalQuesBank,
breadcrumb
},
computed: {
...mapState('auth', [
@ -42,11 +48,12 @@ export default {
methods: {
tabChange(index){
this.active = index
this.$refs.breadcrumb.update('题库资源管理/' + this.tabs[this.active])
},
initTabs(){
let tab1 = this.btns.includes('题库管理:题库分类')
let tab2 = this.btns.includes('题库管理:我上传的题库')
let tab3 = this.btns.includes('题库管理:公共题库')
let tab1 = this.btns.includes('题库资源管理:题库分类')
let tab2 = this.btns.includes('题库资源管理:我上传的题库')
let tab3 = this.btns.includes('题库资源管理:校企公共题库')
if(!tab1 && tab2){
this.active = 'my'

@ -1,60 +1,31 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div class="p-title m-b-20">测评题库</div>
<div class="flex j-between">
<el-form label-width="80px">
<el-form-item class="no-mb" label="试题类型">
<el-select v-model="typeId" clearable placeholder="请选择试题类型" @change="getData">
<div class="tool">
<ul class="filter">
<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.name"></el-option>
</el-select>
</el-form-item>
</el-form>
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入题干/知识点" suffix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
<div>
<el-input
placeholder="请输入题干/知识点"
prefix-icon="el-icon-search"
v-model="keyword"
clearable
></el-input>
</div>
</div>
</el-card>
<el-card shadow="hover" class="m-b-20">
<div class="flex j-between m-b-20">
<div class="p-title m-b-20">题目列表</div>
<div>
<el-button type="primary" size="small" round @click="addTopics" v-auth="'/quesBank/list:我上传的题库:单题上传'">单题上传</el-button>
<el-button type="primary" size="small" round @click="addTopics" v-auth="'/quesBank/list:我上传的题库:单题上传'">单题创建</el-button>
<el-button type="primary" size="small" round @click="showimportVisible" v-auth="'/quesBank/list:我上传的题库:批量上传'">批量上传</el-button>
<el-button type="primary" size="small" round @click="shareDataBatch" v-auth="'/quesBank/list:我上传的题库:批量共享'">批量共享</el-button>
<el-button type="primary" size="small" round @click="delAllData" v-auth="'/quesBank/list:我上传的题库:批量删除'">批量删除</el-button>
</div>
</div>
<el-table
:data="listData"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55"
align="center"
:reserve-selection="true"
:selectable="disabledSelection"
></el-table-column>
<el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="80" align="center" :reserve-selection="true" :selectable="disabledSelection"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center">
<template
slot-scope="scope"
>{{scope.$index + (page - 1) * pageSize + 1}}</template>
<template slot-scope="scope">{{scope.$index + (page - 1) * pageSize + 1}}</template>
</el-table-column>
<el-table-column prop="questionStem" :show-overflow-tooltip="true" label="题干" align="center"></el-table-column>
<el-table-column prop="name" label="试题类型" width="100" align="center"></el-table-column>
@ -63,6 +34,11 @@
<el-table-column prop="knowledgePoints" label="知识点" width="140" align="center"></el-table-column>
<el-table-column prop="useNum" label="使用次数" width="100" align="center"></el-table-column>
<el-table-column prop="createTime" label="上传时间" width="140" align="center"></el-table-column>
<el-table-column label="共享状态" width="140" align="center">
<template slot-scope="scope">
{{scope.row.myShare ? '已共享' : '未共享'}}
</template>
</el-table-column>
<el-table-column label="操作" width="230">
<template slot-scope="scope">
<el-button type="text" @click="show(scope.row)" v-auth="'/quesBank/list:我上传的题库:查看'">查看</el-button>
@ -73,45 +49,55 @@
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
background
@current-change="handleCurrentChange"
:current-page="page"
:page-size="pageSize"
layout="total,prev, pager, next"
:total="total"
></el-pagination>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</el-card>
<ques-dialog ref="quesDialog" :title="topicsTitle" :visible.sync="visible" :isDetail.sync="isDetail" @getData="dialogGetData" @closeTopics="closeTopics"></ques-dialog>
<el-dialog title="批量导入" :visible.sync="importVisible" width="24%" center @close="closeImport" :close-on-click-modal="false">
<div style="text-align: center">
<div style="margin-bottom: 10px;"><el-button type="primary" @click="downLoad">模板下载<i class="el-icon-download el-icon--right"></i></el-button></div>
<el-upload
ref="upload"
accept=".xls,.xlsx"
:on-remove="handleRemove"
:on-error="uploadError"
:on-success="uploadSuccess"
:before-remove="beforeRemove"
:on-progress="handleProgress"
:limit="1"
:on-exceed="handleExceed"
:action="this.api.impExcel"
:file-list="uploadList"
:data="{userId: this.userId,schoolId: this.clientId}"
name="file"
:auto-upload="false"
>
<el-button type="primary" class="ml20">上传文件<i class="el-icon-upload2 el-icon--right"></i></el-button>
<el-dialog title="查看题目" :visible.sync="detailVisible" width="870px" class="dialog" :close-on-click-modal="false">
<ul class="list">
<li>
<span class="name">所属题库</span>
<span class="val">{{topicForm.cid ? quesBankList.find(n => n.cid == topicForm.cid).typeName : ''}}</span>
</li>
<li>
<span class="name">所属课程</span>
<span class="val">{{topicForm.courses}}</span>
</li>
<li>
<span class="name">知识点</span>
<span class="val">{{topicForm.knowledgePoints}}</span>
</li>
<li>
<span class="name">题型</span>
<span class="val">{{topicForm.questionType}}</span>
</li>
<li>
<span class="name">题干</span>
<div class="val">
<div v-html="topicForm.questionStem"></div>
</div>
</li>
<li>
<span class="name">答案解析</span>
<span class="val">{{topicForm.answerAnalysis}}</span>
</li>
</ul>
</el-dialog>
<el-dialog title="批量导入" :visible.sync="importVisible" width="400px" :close-on-click-modal="false">
<div class="upload-wrap" :class="{lg: uploadFaild}">
<el-button class="download" size="small" @click="downLoad"><img src="../../../assets/img/download.png" alt=""> 模板下载</el-button>
<el-upload accept=".xls,.xlsx" :on-remove="handleRemove" :on-error="uploadError" :on-success="uploadSuccess" :before-remove="beforeRemove" :limit="1" :on-exceed="handleExceed" :action="this.api.impExcel" :file-list="uploadList" :data="{userId: this.userId,schoolId: this.clientId}" name="file">
<el-button size="small"><img src="../../../assets/img/upload.png" alt=""> 上传文件</el-button>
</el-upload>
<el-link v-if="uploadFaild" type="primary" @click="showFaild">导入失败查看原因</el-link>
<div class="link" v-if="uploadFaild">
<el-link type="primary" @click="showFaild">导入失败查看原因</el-link>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="importVisible = false"> </el-button>
<el-button type="primary" @click="uploadSure"> </el-button>
<el-button size="small" @click="importVisible = false"> </el-button>
<el-button size="small" type="primary" @click="uploadSure"> </el-button>
</span>
</el-dialog>
</div>
@ -140,6 +126,9 @@ export default {
searchTimer: null,
uploadFaild: false,
token: '',
detailVisible: false,
quesBankList: [],
topicForm: {}
};
},
computed: {
@ -150,6 +139,7 @@ export default {
mounted() {
this.getData()
this.getType()
this.getQuesBank()
},
components: {quesDialog},
watch: {
@ -196,31 +186,79 @@ export default {
this.visible = true
this.isDetail = false
},
getDetail(id) {
this.$refs.quesDialog.getData(id)
},
edit(row) {
this.topicsTitle = '编辑题目'
this.visible = true
this.isDetail = false
this.getDetail(row.id)
this.$refs.quesDialog.getData(row.id)
},
getQuesBank() {
let data = {
pageNum: 1,
pageSize: 10000,
schoolId: this.clientId,
source: 2
}
this.$post(this.api.listByPage,data).then(res => {
let list = res.data.list.list
let result = []
list.map(n => {
result.push(n)
if(n.secondColumn.length) result = result.concat(n.secondColumn)
})
this.quesBankList = result
}).catch(err => {})
},
getDetail(id) {
this.$post(`${this.api.findById}?id=${id}`).then(res => {
let list = res.data.list
this.topicForm = {
id: list.id,
userId: list.userId,
schoolId: this.clientId,
cid : list.cid,
typeId: list.typeId,
courses: list.courses,
knowledgePoints: list.knowledgePoints,
answer: list.answer,
questionType: '',
questionStem: list.questionStem,
optionA: list.optionA,
optionB: list.optionB,
optionC: list.optionC,
optionD: list.optionD,
optionE: list.optionE,
optionF: list.optionF,
aisTrue: false,
bisTrue: false,
cisTrue: false,
disTrue: false,
eisTrue: false,
fisTrue: false,
judgeOptionA: '正确',
judgeOptionB: '错误',
answerAnalysis: list.answerAnalysis,
videoAudio: list.videoAudio
}
console.log(this.topicForm,this.quesBankList)
}).catch(err => {})
},
show(row) {
this.topicsTitle = '查看题目'
this.isDetail = true
this.visible = true
this.detailVisible = true
this.getDetail(row.id)
},
closeTopics() {
this.isDetail = false
},
delData(row) {
this.$confirm('确定要删除吗?', '提示', {
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', {
type: 'warning'
})
.then(() => {
this.$post(`${this.api.deleteByMeSubject}?ids=${row.id}`).then(res => {
this.$message.success('删除成功')
util.successMsg('删除成功')
this.getData()
}).catch(res => {})
if(row.videoAudio){
@ -229,7 +267,7 @@ export default {
}).catch(() => {})
},
share(row) {
this.$confirm('确定要共享吗?', '提示', {
this.$confirm('该题将共享至公共题库,是否确认共享?', '提示', {
type: 'info'
})
.then(() => {
@ -238,7 +276,7 @@ export default {
qid: row.id
}
this.$post(this.api.saveSharing,data).then(res => {
this.$message.success('共享成功')
util.successMsg('此题已成功共享至校企公共题库')
this.getData()
}).catch(res => {})
}).catch(() => {})
@ -249,7 +287,7 @@ export default {
})
.then(() => {
this.$post(`${this.api.cancelByMySharing}?ids=${row.id}`).then(res => {
this.$message.success('取消共享成功');
util.successMsg('取消共享成功');
this.getData()
}).catch(res => {})
}).catch(() => {})
@ -269,7 +307,7 @@ export default {
return item.id
})
this.$confirm('确定要共享吗?', '提示', {
this.$confirm(`是否确认共享${util.ellipsisStr(newArr[0].questionStem)}${newArr.length}个选中的题目?`, '提示', {
type: 'info'
})
.then(() => {
@ -280,7 +318,7 @@ export default {
}
this.$post(this.api.batchSave,data).then(res => {
this.multipleSelection = [];
this.$message.success('共享成功')
util.successMsg('此题已成功共享至校企公共题库')
this.getData()
this.$refs.table.clearSelection()
}).catch(res => {
@ -289,33 +327,7 @@ export default {
})
.catch(() => {});
}else{
this.$message.error('请先选择数据')
}
},
cancelShareBatch() {
if(this.multipleSelection.length){
let newArr = this.multipleSelection
let shareList = newArr.map(item => {
return item.id
})
this.$confirm('确定要取消共享吗?', '提示', {
type: 'info'
})
.then(() => {
let data = {
userId: this.userId,
qid: shareList
}
this.$post(this.api.saveSharing,data).then(res => {
this.multipleSelection = [];
this.$message.success('取消共享成功');
this.getData()
}).catch(res => {})
})
.catch(() => {})
}else{
this.$message.error('请先选择数据!')
util.errorMsg('请先选择数据')
}
},
delAllData() {
@ -325,20 +337,20 @@ export default {
return item.id
})
this.$confirm('确定要删除吗?', '提示', {
this.$confirm(`此删除操作不可逆,是否确认删除${util.ellipsisStr(newArr[0].questionStem)}${newArr.length}个选中的题目?`, '提示', {
type: 'warning'
})
.then(() => {
this.$post(`${this.api.deleteByMeSubject}?ids=${delList.join()}`).then(res => {
this.multipleSelection = [];
this.$message.success('删除成功');
util.successMsg('删除成功');
this.getData()
this.$refs.table.clearSelection()
}).catch(res => {})
})
.catch(() => {})
}else{
this.$message.error('请先选择数据!')
util.errorMsg('请先选择数据!')
}
},
downLoad() {
@ -348,7 +360,7 @@ export default {
this.importVisible = true
},
handleExceed(files, fileList) {
this.$message.warning(
util.warningMsg(
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
);
},
@ -359,15 +371,15 @@ export default {
// this.token = res.data.data.token
// this.uploadFaild = true
// }else{
this.$message.success('上传成功')
util.successMsg('上传成功')
this.importVisible = false
this.page = 1
this.keyword = ''
this.getData()
// }
}else{
// res.message ? this.$message.error(res.message) : this.$message.error('')
res.message && this.$message.error(res.message)
// res.message ? util.errorMsg(res.message) : util.errorMsg('')
res.message && util.errorMsg(res.message)
}
},
showFaild(){
@ -403,8 +415,23 @@ export default {
</script>
<style lang="scss" scoped>
/deep/.no-mb.el-form-item{
margin-bottom: 0;
.list{
li{
display: flex;
margin-bottom: 16px;
.name{
width: 80px;
text-align: right;
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
white-space: nowrap;
}
.val{
max-width: calc(100% - 80px);
font-size: 16px;
color: rgba(0, 0, 0, 0.65);
}
}
}
</style>

@ -1,25 +1,17 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div>
<div class="p-title m-b-20">筛选</div>
<div class="flex">
<div>
<el-input placeholder="请输入分类名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</div>
</div>
</div>
</el-card>
<el-card shadow="hover">
<div class="flex j-between m-b-20">
<div class="p-title">分类管理</div>
<div class="tool">
<ul class="filter">
<li>
<label>搜索</label>
<el-input placeholder="请输入题库分类名称" suffix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
<div>
<el-button type="primary" size="small" round @click="addFirst" v-auth="'/quesBank/list:题库分类:添加一级分类'">添加一级分类</el-button>
</div>
</div>
<el-table :data="listData" class="table" stripe header-align="center" row-key="cid" :tree-props="treeProps" :indent="9">
<el-table-column prop="typeName" label="分类名称">
<template slot-scope="scope">
@ -38,12 +30,11 @@
<el-pagination background @current-change="handleCurrentChange" :current-page="page" layout="total, prev, pager, next" :total="total">
</el-pagination>
</div>
</el-card>
<el-dialog :title="isAddFirst ? '添加一级分类' : '编辑一级分类'" :visible.sync="firstVisible" width="24%" center @close="closeFirst" :close-on-click-modal="false">
<el-dialog :title="isAddFirst ? '添加一级分类名称' : '编辑一级分类名称'" :visible.sync="firstVisible" width="460px" @close="closeFirst" :close-on-click-modal="false">
<el-form>
<el-form-item>
<el-input placeholder="请输入题库分类名称" v-model="firstName" maxlength="15"></el-input>
<el-input placeholder="请输入一级分类名称" v-model="firstName" maxlength="15"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
@ -52,10 +43,10 @@
</span>
</el-dialog>
<el-dialog :title="isAddSecond ? '添加二级分类' : '编辑二级分类'" :visible.sync="secondVisible" width="24%" center @close="closeSecond" :close-on-click-modal="false">
<el-dialog :title="isAddSecond ? '添加二级分类名称' : '编辑二级分类名称'" :visible.sync="secondVisible" width="460px" @close="closeSecond" :close-on-click-modal="false">
<el-form>
<el-form-item>
<el-input placeholder="请输入题库分类名称" v-model="secondName" maxlength="15"></el-input>
<el-input placeholder="请输入二级分类名称" v-model="secondName" maxlength="15"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
@ -68,6 +59,7 @@
<script>
import { mapState } from 'vuex'
import util from '@/libs/util'
export default {
data() {
return {
@ -151,12 +143,12 @@ export default {
this.getData()
},
handleDelete(row) {
this.$confirm('确定要删除吗?', '提示', {
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', {
type: 'warning'
})
.then(() => {
this.$post(`${this.api.deleteById}?cid=${row.cid}`).then(res => {
this.$message.success('删除成功')
util.successMsg('删除成功')
this.getData()
}).catch(res => {})
})
@ -167,7 +159,7 @@ export default {
this.firstVisible = true
},
firstSubmit(){
if(!this.firstName) return this.$message.warning('请填写题库分类名称')
if(!this.firstName) return util.warningMsg('请填写题库分类名称')
let data = {
userId: this.userId,
typeName: this.firstName,
@ -178,7 +170,7 @@ export default {
data.cid = this.curRow.cid
this.$post(this.api.modifyLevel, data).then(res => {
if(res.success){
this.$message.success('修改成功');
util.successMsg('修改成功');
this.firstVisible = false
this.getData()
}
@ -186,7 +178,7 @@ export default {
}else{
this.$post(this.api.AddOneLevel, data).then(res => {
if(res.success){
this.$message.success('添加成功');
util.successMsg('添加成功');
this.firstVisible = false
this.getData()
}
@ -219,7 +211,7 @@ export default {
}
},
secondSubmit(){
if(!this.secondName) return this.$message.warning('请填写题库分类名称')
if(!this.secondName) return util.warningMsg('请填写题库分类名称')
let data = {
typeName: this.secondName,
@ -230,26 +222,26 @@ export default {
if(this.curRow.parentId == 0){
data.parentId = this.curRow.cid
this.$post(this.api.AddSecondLevel, data).then(res => {
this.$message.success('添加成功');
util.successMsg('添加成功');
this.secondVisible = false
this.getData()
}).catch(err => {})
}else{
data.cid = this.curRow.cid
this.$post(this.api.modifyLevel, data).then(res => {
this.$message.success('修改成功');
util.successMsg('修改成功');
this.secondVisible = false
this.getData()
}).catch(err => {})
}
},
delData(row) {
this.$confirm('确定要删除吗?', '提示', {
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', {
type: 'warning'
})
.then(() => {
this.$del(`${this.api.deleteColumn}/${row.id}`).then(res => {
this.$message.success('删除成功');
util.successMsg('删除成功');
this.getData()
}).catch(res => {})
}).catch(() => {})

@ -1,6 +1,6 @@
<template>
<div>
<el-dialog :title="title" :visible.sync="visible" width="40%" @close="closeTopics" center :close-on-click-modal="false">
<el-dialog :title="title" :visible.sync="visible" width="1160px" @close="closeTopics" :close-on-click-modal="false">
<el-form
:model="topicForm"
:rules="rules"
@ -57,44 +57,44 @@
<el-form-item label="选项" prop="optionA" v-if="topicForm.questionType != '填空题' && topicForm.questionType != '简答题'">
<template v-if="topicForm.questionType == '判断题'">
<div class="input flex j-around a-center m-b-15">
<div class="option">
<span>A</span>
<el-input placeholder="请输入题目" v-model="topicForm.judgeOptionA" disabled></el-input>
<el-radio v-model="topicForm.aisTrue" label="1">设为正确答案</el-radio>
</div>
<div class="input flex j-around a-center m-b-15">
<div class="option">
<span>B</span>
<el-input placeholder="请输入题目" v-model="topicForm.judgeOptionB" disabled></el-input>
<el-radio v-model="topicForm.aisTrue" label="2">设为正确答案</el-radio>
</div>
</template>
<template v-else>
<div class="input flex j-around a-center m-b-15">
<div class="option">
<span>A</span>
<el-input placeholder="请输入题目" v-model="topicForm.optionA"></el-input>
<el-checkbox v-model="topicForm.aisTrue">设为正确答案</el-checkbox>
</div>
<div class="input flex j-around a-center m-b-15">
<div class="option">
<span>B</span>
<el-input placeholder="请输入题目" v-model="topicForm.optionB"></el-input>
<el-checkbox v-model="topicForm.bisTrue">设为正确答案</el-checkbox>
</div>
<div class="input flex j-around a-center m-b-15">
<div class="option">
<span>C</span>
<el-input placeholder="请输入题目" v-model="topicForm.optionC"></el-input>
<el-checkbox v-model="topicForm.cisTrue">设为正确答案</el-checkbox>
</div>
<div class="input flex j-around a-center m-b-15">
<div class="option">
<span>D</span>
<el-input placeholder="请输入题目" v-model="topicForm.optionD"></el-input>
<el-checkbox v-model="topicForm.disTrue">设为正确答案</el-checkbox>
</div>
<div class="input flex j-around a-center m-b-15">
<div class="option">
<span>E</span>
<el-input placeholder="请输入题目" v-model="topicForm.optionE"></el-input>
<el-checkbox v-model="topicForm.eisTrue">设为正确答案</el-checkbox>
</div>
<div class="input flex j-around a-center">
<div class="option">
<span>F</span>
<el-input placeholder="请输入题目" v-model="topicForm.optionF"></el-input>
<el-checkbox v-model="topicForm.fisTrue">设为正确答案</el-checkbox>
@ -133,6 +133,7 @@
<script>
import quill from '@/components/quill'
import { mapState } from 'vuex'
import util from '@/libs/util'
export default {
props: ['visible','title','isDetail'],
data() {
@ -193,8 +194,7 @@ export default {
},
methods: {
getData(id) {
this.$post(`${this.api.findById}?id=${id}`)
.then(res => {
this.$post(`${this.api.findById}?id=${id}`).then(res => {
let list = res.data.list
this.topicForm = {
id: list.id,
@ -248,8 +248,7 @@ export default {
}
this.$refs.topicForm.clearValidate()
this.toTop()
})
.catch(err => {})
}).catch(err => {})
},
getQuesBank() {
let data = {
@ -258,8 +257,7 @@ export default {
schoolId: this.clientId,
source: 2
}
this.$post(this.api.listByPage,data)
.then(res => {
this.$post(this.api.listByPage,data).then(res => {
let list = res.data.list.list
let result = []
list.map(n => {
@ -274,8 +272,7 @@ export default {
}
})
this.quesBankList = result
})
.catch(err => {})
}).catch(err => {})
},
questionTypeChange() {
for(let i in this.topicForm){
@ -308,16 +305,16 @@ export default {
if(!topicForm[`option${curOpt.toUpperCase()}`].length) isInvalidAnswer = true
}
}
if((topicForm.typeId == 1 || topicForm.typeId == 3) && optionCount < 2) return this.$message.warning('请至少添加两个选项!')
if(topicForm.typeId == 2 && optionCount < 3) return this.$message.warning('请至少添加三个选项!')
if(!answer) return this.$message.warning('请设置正确答案!')
if(topicForm.questionType == '单选题' && answer.length > 1) return this.$message.warning('单选题只能设置一个正确选项!')
if(topicForm.questionType == '多选题' && answer.length < 2) return this.$message.warning('多选题必须设置至少两个正确选项!')
if(isInvalidAnswer) return this.$message.warning('正确答案选项为空,请重新设置!');
if((topicForm.typeId == 1 || topicForm.typeId == 3) && optionCount < 2) return util.warningMsg('请至少添加两个选项!')
if(topicForm.typeId == 2 && optionCount < 3) return util.warningMsg('请至少添加三个选项!')
if(!answer) return util.warningMsg('请设置正确答案!')
if(topicForm.questionType == '单选题' && answer.length > 1) return util.warningMsg('单选题只能设置一个正确选项!')
if(topicForm.questionType == '多选题' && answer.length < 2) return util.warningMsg('多选题必须设置至少两个正确选项!')
if(isInvalidAnswer) return util.warningMsg('正确答案选项为空,请重新设置!');
if(topicForm.typeId == 3) answer = topicForm.aisTrue == 1 ? 'a' : 'b'
this.topicForm.answer = answer.toUpperCase()
}else if(this.topicForm.typeId == 5){
if(!this.fillList.length || this.fillList.every(n => n === '')) return this.$message.warning('请至少添加一个正确答案!')
if(!this.fillList.length || this.fillList.every(n => n === '')) return util.warningMsg('请至少添加一个正确答案!')
this.options.split('').map((n,i) => {
this.topicForm[`option${this.options[i]}`] = ''
})
@ -325,24 +322,24 @@ export default {
this.topicForm[`option${this.options[i]}`] = n
})
}
if(this.uploading) return this.$message.warning('视频正在上传,请稍等')
if(this.uploading) return util.warningMsg('视频正在上传,请稍等')
this.topicForm.userId = this.userId
if(this.topicForm.id) {
this.$post(this.api.updateQuestions,this.topicForm).then(res => {
if(res.success) {
this.$message.success('修改成功')
util.successMsg('修改成功')
this.$emit('getData')
}else{
this.$message.error(res.data.message)
util.errorMsg(res.data.message)
}
}).catch(res => {})
}else{
this.$post(this.api.addQuestions,this.topicForm).then(res => {
if(res.success) {
this.$message.success('新增成功')
util.successMsg('新增成功')
this.$emit('getData')
}else{
this.$message.error(res.data.message)
util.errorMsg(res.data.message)
}
}).catch(res => {})
}
@ -396,14 +393,14 @@ export default {
}).catch(res => {})
},
addFill(){
if(this.fillList.some(n => n === '')) return this.$message.warning('请先填写当前答案')
this.fillList.length < 5 ? this.fillList.push('') : this.$message.warning('最多添加5个')
if(this.fillList.some(n => n === '')) return util.warningMsg('请先填写当前答案')
this.fillList.length < 5 ? this.fillList.push('') : util.warningMsg('最多添加5个')
},
delFill(index){
this.fillList.splice(index,1)
},
handleExceed(files, fileList) {
this.$message.warning(
util.warningMsg(
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
)
},
@ -445,24 +442,21 @@ export default {
</script>
<style lang="scss" scoped>
/deep/.no-mb.el-form-item{
/deep/.topic-form{
height: 500px;
padding-right: 20px;
overflow: auto;
.no-mb.el-form-item{
margin-bottom: 0;
}
/deep/.el-radio{
margin-right: 15px;
}
::v-deep .el-checkbox-group{
font-size: 2px;
}
.second{
padding-left: 46px !important;
}
.input ::v-deep .el-input {
width: 50%;
.option{
display: flex;
align-items: center;
margin-bottom: 15px;
.el-input {
width: 320px;
margin: 0 24px 0 8px;
}
.radio {
margin: 0 15px 0 30px;
font-weight: 600;
}
.input-wrap{
display: flex;
@ -479,9 +473,18 @@ export default {
cursor: pointer;
}
}
.topic-form{
height: 500px;
padding-right: 20px;
overflow: auto;
.el-radio{
margin-right: 15px;
}
.radio {
margin: 0 15px 0 30px;
font-weight: 600;
}
.el-checkbox-group{
font-size: 2px;
}
.second{
padding-left: 46px !important;
}
}
</style>

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

@ -1,25 +1,32 @@
<template>
<div>
<el-container>
<el-aside width="350px">
<StudentSide ref="getSelectData" @fircheck="fircheck" @twocheck="twocheck" @threecheck="threecheck" @getData="getData"></StudentSide>
</el-aside>
<el-main style="padding-top: 0">
<el-col :span="24">
<el-card shadow="hover" class="m-b-20 student_tab">
<div class="flex j-between m-b-20">
<div>
<el-input placeholder="请输入学生名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
<breadcrumb :data="'学生管理/学生列表'"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item active">学生列表</a>
</div>
<div class="page-content">
<div class="tool">
<ul class="filter">
<li>
<label>筛选</label>
<el-cascader :options="orgList" :props="props" collapse-tags clearable size="small" @change="orgChange"></el-cascader>
</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="addstudent" v-auth>新增学生</el-button>
<el-button type="primary" size="small" round class="mag" @click="batchImport" v-auth>批量导入</el-button>
<el-button type="primary" size="small" round @click="batchImport" v-auth>批量导入</el-button>
<el-button type="primary" size="small" round @click="delAllSelection" v-auth>批量删除</el-button>
</div>
</div>
<el-table :data="listData" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"></el-table-column>
<!-- <StudentSide ref="getSelectData" @fircheck="fircheck" @twocheck="twocheck" @threecheck="threecheck" @getData="getData"></StudentSide> -->
<el-table :data="listData" class="table" ref="table" stripe header-align="center" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="80" align="center"></el-table-column>
<el-table-column type="index" label="序号" width="55" align="center">
</el-table-column>
<el-table-column prop="studentName" label="学生姓名" align="center">
@ -32,11 +39,6 @@
</el-table-column>
<el-table-column prop="className" label="班级" align="center">
</el-table-column>
<el-table-column prop="roleId" label="账号角色" align="center">
<template slot-scope="scope">
学生
</template>
</el-table-column>
<el-table-column prop="loginNumber" label="登录次数" align="center">
</el-table-column>
<el-table-column prop="lastLoginTime" label="上次登录时间" width="150" align="center">
@ -50,16 +52,12 @@
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total,prev, pager, next" :current-page="page" @current-change="handleCurrentChange" :total="total">
</el-pagination>
<el-pagination background layout="total,prev, pager, next" :current-page="page" @current-change="handleCurrentChange" :total="total"></el-pagination>
</div>
</div>
</div>
</el-card>
</el-col>
</el-main>
</el-container>
<el-dialog :title="isAdd ? '新增学生' : '编辑学生'" :visible.sync="studentVisible"
width="30%" center @close="closestudent" class="dialog" :close-on-click-modal="false">
<el-dialog :title="isAdd ? '新增学生' : '编辑学生'" :visible.sync="studentVisible" width="30%" @close="closestudent" class="dialog" :close-on-click-modal="false">
<el-form ref="studentForm" :model="studentForm" :rules="rules" label-width="90px">
<el-form-item prop="account" label="账号">
<el-input v-model="studentForm.account" placeholder="请输入学生账号" @change="accountChange"></el-input>
@ -67,9 +65,6 @@
<el-form-item prop="userName" label="学生姓名">
<el-input v-model="studentForm.userName" placeholder="请输入学生姓名"></el-input>
</el-form-item>
<el-form-item label="账号角色">
学生
</el-form-item>
<el-form-item prop="uniqueIdentificationAccount" label="唯一标识">
<el-input disabled v-model="studentForm.uniqueIdentificationAccount" placeholder="请输入学生学号获取唯一标识"></el-input>
</el-form-item>
@ -78,7 +73,7 @@
</el-form-item>
<el-form-item prop="professionalId" label="专业">
<el-select v-model="studentForm.professionalId" placeholder="请选择专业" @change="getGrade">
<el-option v-for="(item,index) in majorList" :key="index"
<el-option v-for="(item,index) in orgList" :key="index"
:label="item.stuProfessionalArchitectureName" :value="item.stuProfessionalArchitectureId"></el-option>
</el-select>
</el-form-item>
@ -107,41 +102,34 @@
</span>
</el-dialog>
<el-dialog title="批量导入" :visible.sync="importVisible" width="24%" center :close-on-click-modal="false">
<div style="text-align: center">
<div style="margin-bottom: 10px;"><el-button type="primary" @click="downLoad">模板下载<i class="el-icon-download el-icon--right"></i></el-button></div>
<el-upload
accept=".xls,.xlsx"
:on-remove="handleRemove"
:on-error="uploadError"
:on-success="uploadSuccess"
:before-remove="beforeRemove"
:limit="1"
:on-exceed="handleExceed"
:data="{schoolId: this.clientId}"
:action="this.api.uploadFileStudent"
:file-list="uploadList"
name="file"
>
<el-button type="primary" class="ml20">上传文件<i class="el-icon-upload2 el-icon--right"></i></el-button>
<el-dialog title="批量导入" :visible.sync="importVisible" width="400px" :close-on-click-modal="false">
<div class="upload-wrap" :class="{lg: uploadFaild}">
<el-button class="download" size="small" @click="downLoad"><img src="../../../assets/img/download.png" alt=""> 模板下载</el-button>
<el-upload accept=".xls,.xlsx" :on-remove="handleRemove" :on-error="uploadError" :on-success="uploadSuccess" :before-remove="beforeRemove" :limit="1" :on-exceed="handleExceed" :action="this.api.uploadFileStudent" :file-list="uploadList" :data="{schoolId: this.clientId}" name="file">
<el-button size="small"><img src="../../../assets/img/upload.png" alt=""> 上传文件</el-button>
</el-upload>
<el-link v-if="uploadFaild" type="primary" @click="showFaild">导入失败查看原因</el-link>
<div class="link" v-if="uploadFaild">
<el-link type="primary" @click="showFaild">导入失败查看原因</el-link>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="importVisible = false">取消</el-button>
<el-button type="primary" @click="uploadSure">确定</el-button>
<el-button size="small" @click="importVisible = false"> </el-button>
<el-button size="small" type="primary" @click="uploadSure"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import StudentSide from './studentSide'
import { mapState,mapGetters } from 'vuex'
import util from '@/libs/util'
import Setting from '@/setting'
import breadcrumb from '@/components/breadcrumb'
export default {
data() {
return {
props: { multiple: true },
orgList: [],
twoDepartmentIds: '',
studentVisible: false,
studentForm: {
clientId: this.clientId,
@ -209,7 +197,6 @@ export default {
pageSize: 10,
total: 0,
searchTimer: null,
majorList: [],
gradeList: [],
classList: [],
professionalIds: '',
@ -235,12 +222,7 @@ export default {
])
},
components: {
StudentSide
},
mounted(){
this.studentForm.clientId = this.clientId
this.studentForm.clientName = this.clientName
this.getData()
breadcrumb
},
watch: {
keyword: function(val) {
@ -250,7 +232,51 @@ export default {
},500)
}
},
mounted(){
this.getOrg()
this.studentForm.clientId = this.clientId
this.studentForm.clientName = this.clientName
this.getData()
},
methods: {
getOrg(){
let data = {
schoolId: this.clientId
}
this.$get(this.api.queryStudentProfessionalArchitecture,data).then(res => {
let StaffProfessionalArchitectureList = res.data.StaffProfessionalArchitectureList
if(StaffProfessionalArchitectureList){
StaffProfessionalArchitectureList.map(e => {
e.isParent = true
e.value = e.stuProfessionalArchitectureId
e.label = e.stuProfessionalArchitectureName
let data = {
stuProfessionalArchitectureId: e.stuProfessionalArchitectureId
}
this.$get(this.api.queryGrade,data).then(res => {
e.children = res.data.Grade
e.children.map(e => {
e.value = e.gradeId
e.label = e.gradeName
let data = {
gradeId: e.gradeId
}
this.$get(this.api.queryClass,data).then(res => {
res.data.Class.map(e => {
e.value = e.classId
e.label = e.className
})
e.children = res.data.Class
}).catch(res => {})
})
}).catch(res => {})
})
setTimeout(() => {
this.orgList = StaffProfessionalArchitectureList
}, 500)
}
}).catch(res => {})
},
getData(){
let data = {
searchContent: this.keyword,
@ -264,82 +290,10 @@ export default {
this.total = res.data.total
}).catch(res => {})
},
handleCheck(data){
let professionalStudentIds = []
let gradeIds = []
let classIds = []
data.forEach( e => {
if(e.ischeck){
professionalStudentIds.push(e.stuProfessionalArchitectureId)
}else{
util.removeByValue(professionalStudentIds, e.stuProfessionalArchitectureId);
}
e.children.forEach( r => {
if(r.ischeck){
gradeIds.push(r.gradeId)
}else{
util.removeByValue(gradeIds, r.gradeId);
}
r.children.forEach( n => {
if(n.ischeck){
classIds.push(n.classId)
}else{
util.removeByValue(classIds, n.classId);
}
})
})
})
this.professionalStudentIds = professionalStudentIds.toString()
this.gradeIds = gradeIds.toString()
this.classIds = classIds.toString()
orgChange(node){
this.classIds = node.map(n => n[2]).toString()
this.getData()
},
fircheck(val,val2){
val.ischeck = !val.ischeck
val.children.map( e => e.ischeck = val.ischeck)
val.children.map( e => e.children.map(n => n.ischeck = e.ischeck))
this.handleCheck(val2)
},
twocheck(val,val2){
val.ischeck = !val.ischeck
val.children.map( e => e.ischeck = val.ischeck)
val2.forEach( e => {
e.children.forEach( r => {
if(r.gradeId == val.gradeId){
if(e.children.every(i => i.ischeck)){
e.ischeck = true
}else{
e.ischeck = false
}
}
})
})
this.handleCheck(val2)
},
threecheck(val,val2){
val.ischeck = !val.ischeck
val2.forEach( e => {
e.children.forEach( r => {
r.children.forEach( n => {
if(n.classId == val.classId){
if(r.children.every(i => i.ischeck)){
r.ischeck = true
}else{
r.ischeck = false
}
}
})
if(e.children.every(i => i.ischeck)){
e.ischeck = true
}else{
e.ischeck = false
}
})
})
this.handleCheck(val2)
},
closestudent(){
this.$refs.studentForm.resetFields()
},
@ -347,14 +301,12 @@ export default {
this.studentForm.studentId = ''
this.studentVisible = true
this.isAdd = true
this.majorList = this.$refs.getSelectData.majorList
},
editstudent(row){
this.studentVisible = true
this.isAdd = false
this.studentForm.studentId = row.studentId
this.studentForm.userId = row.userId
this.majorList = this.$refs.getSelectData.majorList
this.$get(`${this.api.getStudent}/${row.studentId}`).then(res => {
let student = res.data.student
let userInfo = res.data.userInfo
@ -381,9 +333,9 @@ export default {
}
this.$post(this.api.userinfoUpdate,data).then(res => {
if(res.success){
this.$message.success('重置成功')
util.successMsg('重置成功')
}else{
this.$message.error('重置失败')
util.errorMsg('重置失败')
}
}).catch(res => {})
}).catch(() => {})
@ -420,7 +372,7 @@ export default {
this.$get(`${this.api.getAccount}?account=${this.studentForm.account}`).then(res => {
if(res.data.userInfo){
this.accountRepeat = true
this.$message.warning('该账号已存在')
util.warningMsg('该账号已存在')
}else{
this.accountRepeat = false
}
@ -434,7 +386,7 @@ export default {
this.$get(`${this.api.studentGetWorkNumber}?workNumber=${this.studentForm.workNumber}`).then(res => {
if(res.data.student){
this.workNumberRepeat = true
this.$message.warning('该学号已存在')
util.warningMsg('该学号已存在')
}else{
this.workNumberRepeat = false
}
@ -446,8 +398,8 @@ export default {
saveSure(studentForm){
this.$refs[studentForm].validate((valid) => {
if (valid) {
if(this.accountRepeat) return this.$message.warning('该账号已存在')
if(this.workNumberRepeat) return this.$message.warning('该学号已存在')
if(this.accountRepeat) return util.warningMsg('该账号已存在')
if(this.workNumberRepeat) return util.warningMsg('该学号已存在')
let data = {
userInfo: {
isPort: 2,
@ -477,13 +429,13 @@ export default {
if(this.studentForm.studentId){
this.$post(this.api.updateStudent,data).then(res => {
this.studentVisible = false
this.$message.success('编辑成功')
util.successMsg('编辑成功')
this.getData()
}).catch(res => {});
}else{
this.$post(this.api.addStudent,data).then(res => {
this.studentVisible = false
this.$message.success('添加成功')
util.successMsg('添加成功')
this.getData()
}).catch(res => {});
}
@ -493,7 +445,7 @@ export default {
})
},
delstudent(row){
this.$confirm('确定要删除吗?', '提示', {
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', {
type: 'warning'
})
.then(() => {
@ -501,7 +453,7 @@ export default {
studentIds: row.studentId
}
this.$del(this.api.deleteStudents,data).then(res => {
this.$message.success('删除成功')
util.successMsg('删除成功')
this.getData()
}).catch(res => {});
})
@ -517,7 +469,7 @@ export default {
return item.studentId
})
//
this.$confirm('确定要删除吗?', '提示', {
this.$confirm(`此批量删除操作不可逆,是否确认删除${util.ellipsisStr(newArr[0].studentName)}${newArr.length}个选中项?`, '提示', {
type: 'warning'
})
.then(() => {
@ -526,12 +478,12 @@ export default {
}
this.$del(this.api.deleteStudents,data).then(res => {
this.multipleSelection = []
this.$message.success('删除成功')
util.successMsg('删除成功')
this.getData()
}).catch(res => {});
}).catch(() => {});
}else{
this.$message.error('请先选择学生')
util.errorMsg('请先选择学生')
}
},
batchImport(){
@ -550,7 +502,7 @@ export default {
},
//
handleExceed(files, fileList) {
this.$message.warning(
util.warningMsg(
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
);
},
@ -564,10 +516,10 @@ export default {
this.token = res.data.data.token
this.uploadFaild = true
}else{
this.$message.success('上传成功')
util.successMsg('上传成功')
}
}else{
res.data.message ? this.$message.error(res.data.message) : this.$message.error('上传失败,请检查数据')
res.data.message ? util.errorMsg(res.data.message) : util.errorMsg('上传失败,请检查数据')
}
},
uploadError(err, file, fileList) {
@ -595,5 +547,19 @@ export default {
};
</script>
<style lang="scss" scoped>
/deep/.dialog{
.el-form-item{
.el-form-item__label{
font-size: 16px;
color: rgba(0, 0, 0, 0.65);
&:before{
margin-right: 0;
color: #CC221C;
}
}
}
.el-input,.el-select{
width: 100%;
}
}
</style>

@ -1,414 +0,0 @@
<template>
<div>
<div>
<!-- <p class="side_icon mab20">
<i class="icon-jiahao mar20" @click="addMajor()"></i> -->
<!-- <i class="icon-delete"></i> -->
<!-- </p> -->
<lctree :data="majorList"
@addMajor="addMajor" @editmajorClass="editmajorClass" @delClassDepartment="delClassDepartment"
@addClassDepartment="addClassDepartment" @editDepartment="editDepartment" @delDepart="delDepart"
@addClass="addClass" @editClass="editClass" @delClass="delClass"
@fircheckitem="fircheckitem" @twocheckitem="twocheckitem" @threecheckitem="threecheckitem"
></lctree>
</div>
<!-- 添加专业 -->
<el-dialog :title="Form.classmajorId ? '编辑专业' : '新增专业'" :visible.sync="isaddClassMajor" width="24%" center @close="closeAddClass" :close-on-click-modal="false">
<el-form ref="Form" :model="Form">
<el-form-item prop="classmajorName">
<el-input placeholder="请输入专业名称" v-model="Form.classmajorName" @change="majorChange"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="isaddClassMajor = false">取消</el-button>
<el-button type="primary" @click="sure">确定</el-button>
</span>
</el-dialog>
<!-- 添加年级 -->
<el-dialog :title="Form2.departmentId ? '编辑年级' : '新增年级'" :visible.sync="isAddDepartment" width="24%" center @close="closeAddClass2" :close-on-click-modal="false">
<el-form ref="Form2" :model="Form2">
<el-form-item prop="departmentName">
<el-input placeholder="请输入年级名称" v-model.number="Form2.departmentName"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="isAddDepartment = false">取消</el-button>
<el-button type="primary" @click="sureDepartment">确定</el-button>
</span>
</el-dialog>
<!-- 添加班级 -->
<el-dialog :title="Form3.classId ? '编辑班级' : '新增班级'" :visible.sync="isAddClass" width="24%" center @close="closeAddClass3" :close-on-click-modal="false">
<el-form ref="Form3" :model="Form3">
<el-form-item prop="className">
<el-input placeholder="请输入班级名称" v-model.number="Form3.className"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="isAddClass = false">取消</el-button>
<el-button type="primary" @click="sureClass('Form3')">确定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import lctree from './studentTree'
import { mapState } from 'vuex'
export default {
props:["Data"],
data() {
return {
majorList: [],
firactive: 0,
twoactive: 0,
threeactive: 0,
isaddClassMajor: false,
isAddDepartment: false,
isAddClass: false,
Form: {
classmajorId: '',
classmajorName: '',
},
Form2: {
departmentId: '',
departmentName: '',
},
Form3: {
classId: '',
className: ''
},
majorNoAdd: true,
};
},
computed: {
...mapState('user', [
'userId','clientId'
])
},
components: {
lctree
},
mounted(){
this.getStaff()
},
methods: {
getStaff(){
let data = {
schoolId: this.clientId
}
this.$get(this.api.queryStudentProfessionalArchitecture,data).then(res => {
let StaffProfessionalArchitectureList = res.data.StaffProfessionalArchitectureList
StaffProfessionalArchitectureList.map(e => {
(e.ifVisible = false), (e.ischeck = false), (e.label = e.stuProfessionalArchitectureName);
let data = {
stuProfessionalArchitectureId: e.stuProfessionalArchitectureId
}
this.$get(this.api.queryGrade,data).then(res => {
e.children = res.data.Grade
e.children.map(e => {
(e.ifVisible = false), (e.ischeck = false), (e.label = e.gradeName);
let data = {
gradeId: e.gradeId
}
this.$get(this.api.queryClass,data).then(res => {
res.data.Class.map(e => {
(e.ifVisible = false), (e.ischeck = false), (e.label = e.className);
})
e.children = res.data.Class
}).catch(res => {});
})
}).catch(res => {});
})
setTimeout(() => {
this.majorList = StaffProfessionalArchitectureList
this.majorList[0].ifVisible = true
}, 500)
}).catch(res => {})
},
//
fircheckitem(item){
this.$emit("fircheck",item,this.majorList)
},
//
twocheckitem(item){
this.$emit("twocheck",item,this.majorList)
},
threeClick(index){
this.threeactive = index
},
//
threecheckitem(three){
this.$emit("threecheck",three,this.majorList)
},
closeAddClass(){
this.$refs.Form.resetFields()
},
closeAddClass2(){
this.$refs.Form2.resetFields()
},
closeAddClass3(){
this.$refs.Form3.resetFields()
},
//
addMajor(){
this.Form.classmajorId = ''
this.Form.classmajorName = ''
this.isaddClassMajor = true
},
editmajorClass(item){
console.log(item)
this.Form.classmajorId = item.stuProfessionalArchitectureId,
this.Form.classmajorName = item.stuProfessionalArchitectureName
this.isaddClassMajor = true
},
delClassDepartment(item,index){
this.$confirm('确定要删除该专业吗?', '提示', {
type: 'warning'
})
.then(() => {
this.$post(`${this.api.deleteStudentProfessionalArchitecture}?studentProfessionalArchitectureIds=${item.stuProfessionalArchitectureId}`).then(res => {
this.$message.success('删除成功');
this.majorList.splice(index, 1)
}).catch(res => {})
})
.catch(() => {})
},
sure(){
if(!this.Form.classmajorName) return this.$message.warning('请输入专业名称');
if(!this.majorNoAdd) return this.$message.warning('该专业名称已存在');
let data = {
stuProfessionalArchitectureName: this.Form.classmajorName,
stuProfessionalArchitectureId: this.Form.classmajorId,
schoolId: this.clientId
}
if(this.Form.classmajorId){
this.$post(this.api.updateStudentProfessionalArchitecture,data).then(res => {
this.$message.success('编辑成功');
this.isaddClassMajor = false
this.majorList.map(e =>{
if(e.stuProfessionalArchitectureId == this.Form.classmajorId){
e.stuProfessionalArchitectureName = this.Form.classmajorName
e.label = this.Form.classmajorName
}
})
this.$emit('getData')
}).catch(res => {})
}else{
this.$post(this.api.addStudentProfessionalArchitecture,data).then(res => {
this.$message.success('添加成功');
this.isaddClassMajor = false
let newData = {
stuProfessionalArchitectureId: res.data.studentProfessionalArchitectureId,
stuProfessionalArchitectureName : this.Form.classmajorName,
label: this.Form.classmajorName,
ifVisible: false,
ischeck: false,
children: []
}
this.majorList.push(newData)
}).catch(res => {})
}
},
//
addClassDepartment(item){
this.Form2.departmentId = ''
this.Form2.departmentName = ''
this.isAddDepartment = true
this.Form.classmajorId = item.stuProfessionalArchitectureId
},
editDepartment(item){
this.Form2.departmentId = item.gradeId,
this.Form2.departmentName = item.gradeName
this.isAddDepartment = true
for (let j = 0; j < this.majorList.length; j++) {
for (let k = 0; k < this.majorList[j].children.length; k++) {
if(this.majorList[j].children[k].gradeName == item.gradeName){
this.Form.classmajorId = this.majorList[j].stuProfessionalArchitectureId
}
}
}
},
delDepart(item,index){
console.log(item)
this.$confirm('确定要删除该年级吗?', '提示', {
type: 'warning'
})
.then(() => {
this.$post(`${this.api.deleteGrade}?gradeIds=${item.gradeId}`).then(res => {
this.$message.success('删除成功');
this.majorList.map(e =>{
e.children.map(r =>{
if(r.gradeId == item.gradeId){
e.children.splice(index,1)
if(e.children.length == 0){
e.ifVisible = false
}
}
})
})
}).catch(res => {})
})
.catch(() => {});
},
sureDepartment(){
if(!this.Form2.departmentName) return this.$message.warning('请输入年级名称')
if(isNaN(this.Form2.departmentName)) return this.$message.warning('年级名称必须为数字')
let data = {
gradeName: this.Form2.departmentName,
gradeId: this.Form2.departmentId,
stuProfessionalArchitectureId: this.Form.classmajorId,
}
if(this.Form2.departmentId){
this.$post(this.api.updateGrade,data).then(res => {
this.$message.success('编辑成功');
this.isAddDepartment = false
this.majorList.map(e =>{
e.children.map(r =>{
if(r.gradeId == this.Form2.departmentId){
r.gradeName = this.Form2.departmentName
r.label = this.Form2.departmentName
}
})
})
this.$emit('getData')
}).catch(res => {})
}else{
this.$post(this.api.addGrade,data).then(res => {
this.$message.success('添加成功');
this.isAddDepartment = false
let newData = {
gradeId: res.data.gradeId,
gradeName: this.Form2.departmentName,
label: this.Form2.departmentName,
ifVisible: false,
ischeck: false,
children: []
}
this.majorList.map(e =>{
if(e.stuProfessionalArchitectureId == this.Form.classmajorId){
e.ifVisible = true
e.children.push(newData)
}
})
}).catch(res => {})
}
},
async majorChange(){
let res = await this.$get(this.api.queryStudentPAN, { name: this.Form.classmajorName,schoolId: this.clientId });
if(res.data.StaffProfessionalArchitecture != null){
this.$message.warning('该专业组织已存在');
this.majorNoAdd = false
}else{
this.majorNoAdd = true
}
},
//
addClass(two){
this.Form3.classId = ''
this.Form3.className = ''
this.isAddClass = true
this.Form2.departmentId = two.gradeId
},
editClass(three){
console.log(33,three)
this.Form3.classId = three.classId,
this.Form3.className = three.className
this.isAddClass = true
for (let j = 0; j < this.majorList.length; j++) {
for (let k = 0; k < this.majorList[j].children.length; k++) {
for(let l = 0; l < this.majorList[j].children[k].children.length; l++){
if(this.majorList[j].children[k].children[l].className == three.className){
this.Form2.departmentId = this.majorList[j].gradeId
}
}
}
}
},
delClass(item,index){
console.log(item)
this.$confirm('确定要删除该班级吗?', '提示', {
type: 'warning'
})
.then(() => {
this.$post(`${this.api.deleteClass}?classIds=${item.classId}`).then(res => {
this.$message.success('删除成功');
this.majorList.map(e =>{
e.children.map(r =>{
r.children.map(c =>{
if(c.classId == item.classId){
r.children.splice(index,1)
if(r.children.length == 0){
r.ifVisible = false
}
}
})
})
})
}).catch(res => {})
})
.catch(() => {});
},
sureClass(){
if(!this.Form3.className) return this.$message.warning('请输入班级名称')
// if(isNaN(this.Form3.className)) return this.$message.warning('')
let data = {
className: this.Form3.className,
classId: this.Form3.classId,
gradeId: this.Form2.departmentId
}
if(this.Form3.classId){
this.$post(this.api.updateClass,data).then(res => {
this.$message.success('编辑成功');
this.isAddClass = false
this.majorList.map(e =>{
e.children.map(r =>{
r.children.map(c =>{
if(c.classId == this.Form3.classId){
c.className = this.Form3.className
c.label = this.Form3.className
}
})
})
})
this.$emit('getData')
}).catch(res => {})
}else{
this.$post(this.api.addClass,data).then(res => {
this.$message.success('添加成功');
this.isAddClass = false
let newData = {
classId: res.data.classId,
className: this.Form3.className,
label: this.Form3.className,
ifVisible: false,
ischeck: false
}
this.majorList.map(e =>{
e.children.map(r =>{
if(r.gradeId == this.Form2.departmentId){
r.ifVisible = true
if(r.children.length == 0){
let arr = []
arr.push(newData)
r.children = arr
}else{
r.children.push(newData)
}
}
})
})
}).catch(res => {})
}
}
}
};
</script>
<style lang="scss" scoped>
</style>

@ -1,155 +0,0 @@
<template>
<div class="side_view">
<p class="side_icon mab20">
<i class="icon-jiahao mar20" @click="addMajor()"></i>
</p>
<div class="side_tree" @click.stop="open(item)" v-for="(item,index) in data" :key="index">
<div class="item" @click.stop="open(item)">
<img
v-if="item.children&&item.children.length!=0"
:class="{ 'arrowTransform': !item.ifVisible, 'arrowTransformReturn': item.ifVisible}"
src="../../../assets/img/icon-xiangyou.png"
alt
/>
<i v-else class="empty"></i>
<i :class="item.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="fircheckitem(item)"></i>
<span>{{item.label}}</span>
<i class="edit ft" @click.stop="editmajorClass(item)"></i>
<i class="el-icon-circle-plus ft" @click.stop="addClassDepartment(item)"></i>
<i class="icon-delete ft" @click.stop="delClassDepartment(item,index)"></i>
</div>
<div v-show="item.ifVisible" v-if="item.children&&item.children.length!=0">
<div v-for="(item1,index1) in item.children" :key="index1">
<div class="item1" @click.stop="open(item1)">
<img
v-if="item1.children&&item1.children.length!=0"
:class="{ 'arrowTransform': !item1.ifVisible, 'arrowTransformReturn': item1.ifVisible}"
src="../../../assets/img/icon-xiangyou.png"
alt
/>
<i v-else class="empty"></i>
<i :class="item1.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="twocheckitem(item1)"></i>
<span>{{item1.label}}年级</span>
<i class="edit ft" @click.stop="editDepartment(item1)"></i>
<i class="el-icon-circle-plus ft" @click.stop="addClass(item1)"></i>
<i class="icon-delete ft" @click.stop="delDepart(item1,index1)"></i>
</div>
<div v-show="item1.ifVisible" v-if="item1.children&&item1.children.length!=0">
<div v-for="(item2,index2) in item1.children" :key="index2">
<div class="item2" @click.stop="open(item2)">
<i :class="item2.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="threecheckitem(item2)"></i>
<span>{{item2.label}}</span>
<i class="edit ft" @click.stop="editClass(item2)"></i>
<i class="icon-delete ft" @click.stop="delClass(item2,index2)"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
Array.prototype.removeByValue = function (val) {
for (var i = 0; i < this.length; i++) {
if (JSON.stringify(this[i]).indexOf(JSON.stringify(val)) != -1) {
this.splice(i, 1);
break;
}
}
};
export default {
data() {
return {
chooseList: []
};
},
watch: {
chooseList(n, o) {
this.$emit('chooseNode', n);
}
},
props: {
data: {
type: Array
}
},
methods: {
//
open(item) {
item.ifVisible = !item.ifVisible;
},
//removeByvaluemain.js
choose(item) {
item.ifVisible = !item.ifVisible;
if (item.ifVisible) {
this.chooseList.push(item);
} else {
this.chooseList.removeByValue(item);
}
},
fircheckitem(item){
this.$emit('fircheckitem',item);
},
twocheckitem(item){
this.$emit('twocheckitem',item);
},
threecheckitem(item){
this.$emit('threecheckitem',item);
},
//
addMajor(){
this.$emit('addMajor');
},
editmajorClass(item){
this.$emit('editmajorClass',item);
},
delClassDepartment(item,index){
this.$emit('delClassDepartment',item,index);
},
//
addClassDepartment(item){
this.$emit('addClassDepartment',item);
},
editDepartment(item){
this.$emit('editDepartment',item);
},
delDepart(item,index){
this.$emit('delDepart',item,index);
},
//
addClass(item){
this.$emit('addClass',item);
},
editClass(item){
this.$emit('editClass',item);
},
delClass(item,index){
this.$emit('delClass',item,index);
},
//
isHasObj(arr, val) {
var flag = 0; //1 0
for (var i = 0; i < arr.length; i++) {
if (JSON.stringify(arr[i]).indexOf(JSON.stringify(val)) != -1) {
flag = 1;
}
}
if (flag == 1) {
return true;
} else {
return false;
}
}
}
};
</script>
<style lang="scss" scoped>
@import '../../../styles/pages/tree.scss';
</style>

@ -1,37 +1,43 @@
<template>
<div>
<div class="tabs m-b-20" v-if="showTabs">
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == activeName}" @click="tabChange(index)">{{item}}</a>
<breadcrumb :data="'系统分管设置/' + tabs[active]" ref="breadcrumb"></breadcrumb>
<div class="page">
<div class="tabs" v-if="showTabs">
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{item}}</a>
</div>
<div class="score-table" v-if="activeName == 'staff'" v-auth="'系统设置:员工管理'">
<staff></staff>
<div class="page-content">
<staff v-if="active == 'staff'" v-auth="'系统分管设置:员工管理'"></staff>
<role v-else-if="active == 'role'" v-auth="'系统分管设置:角色权限'"></role>
<organization v-else v-auth="'系统分管设置:架构管理'"></organization>
</div>
<div class="score-table" v-else v-auth="'系统设置:角色权限'">
<role></role>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import Setting from '@/setting';
import staff from './staff.vue';
import role from './role.vue';
import Setting from '@/setting'
import staff from './staff.vue'
import role from './role.vue'
import organization from './organization.vue'
import breadcrumb from '@/components/breadcrumb'
export default {
data() {
return {
activeName: 'staff',
active: 'staff',
tabs: {
staff: '员工管理',
role: '角色权限'
role: '角色权限',
organization: '架构管理'
},
showTabs: true
};
},
components: {
staff,
role
role,
organization,
breadcrumb
},
computed: {
...mapState('auth', [
@ -43,11 +49,12 @@ export default {
},
methods: {
tabChange(index){
this.activeName = index
this.active = index
this.$refs.breadcrumb.update('系统分管设置/' + this.tabs[this.active])
},
initTabs(){
let showStaff = this.btns.includes('系统设置:员工管理')
let showRole = this.btns.includes('系统设置:角色权限')
let showStaff = this.btns.includes('系统分管设置:员工管理')
let showRole = this.btns.includes('系统分管设置:角色权限')
if(!showStaff || !showRole){
this.showTabs = false

@ -0,0 +1,277 @@
<template>
<div>
<div class="tool">
<ul class="filter"></ul>
<div>
<el-button type="primary" size="small" round @click="addMajor" v-auth="'/system/list:架构管理:新增架构'">新增架构</el-button>
</div>
</div>
<el-table :data="listData" stripe header-align="center" row-key="id" :tree-props="treeProps" :indent="9">
<el-table-column prop="label" label="架构名称">
<template slot-scope="scope">
<span class="text">{{scope.row.label}}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button type="text" @click="edit(scope.row)" v-auth="'/system/list:架构管理:编辑'">编辑</el-button>
<el-button v-if="scope.row.isParent" type="text" @click="addDepartment(scope.row)" v-auth="'/system/list:架构管理:添加'">添加</el-button>
<el-button type="text" @click="del(scope.row)" v-auth="'/system/list:架构管理:删除'">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog :title="Form.MajorId ? '编辑名称' : '新增架构'" :visible.sync="isaddMajor" width="460px" @close="closeAdd" :close-on-click-modal="false">
<el-form ref="Form" :model="Form">
<el-form-item prop="majorName">
<el-input :placeholder="Form.MajorId ? '请编辑架构名称' : '请输入架构名称'" v-model="Form.majorName" @change="majorChange"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button size="small" @click="isaddMajor = false"> </el-button>
<el-button size="small" type="primary" @click="sure('Form')"> </el-button>
</span>
</el-dialog>
<el-dialog :title="Form.departmentId ? '编辑部门' : '新增部门'" :visible.sync="isAddDepartment" width="460px" @close="closeAdd" :close-on-click-modal="false">
<el-form ref="Form" :model="Form">
<el-form-item prop="departmentName">
<el-input placeholder="请输入部门名称" v-model="Form.departmentName" @change="depChange"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button size="small" @click="isAddDepartment = false"> </el-button>
<el-button size="small" type="primary" @click="sureDepartment('Form')"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { mapState } from 'vuex'
import util from '@/libs/util'
export default {
name: 'organization',
data() {
return {
treeProps: {children: 'children', hasChildren: 'hasChildren'},
listData: [],
isaddMajor: false,
isAddDepartment: false,
Form: {
MajorId: '',
majorName: '',
departmentId: '',
departmentName: ''
},
staffstateProfessId: '',
staffstateId: '',
majorNoAdd: true,
depNoAdd: true
};
},
computed: {
...mapState('user', [
'clientId','clientName'
]),
},
mounted() {
this.getData()
},
methods: {
getData(){
let data = {
schoolId: this.clientId
}
this.$get(this.api.queryStaffPro,data).then(res => {
let firList = res.data.StaffProfessionalArchitectureList
if(firList){
firList.map(e => {
e.isParent = true
e.id = e.staffProfessionalArchitectureId
e.label = e.staffProfessionalArchitectureName
let data = {
staffProfessionalArchitectureId: e.staffProfessionalArchitectureId
}
this.$get(this.api.queryStaffGrade,data).then(res1 => {
res1.data.staffGradeList.map(e => {
e.id = e.staffGradeId
e.label = e.staffGradeName
})
e.children = res1.data.staffGradeList
}).catch(res => {})
})
setTimeout(() => {
this.listData = firList
},500)
}
}).catch(res => {})
},
addMajor(){
this.Form.MajorId = ''
this.Form.majorName = ''
this.isaddMajor = true
},
edit(item){
if(item.isParent){
this.Form.MajorId = item.staffProfessionalArchitectureId,
this.Form.majorName = item.staffProfessionalArchitectureName
this.isaddMajor = true
}else{
this.Form.departmentId = item.staffGradeId,
this.Form.departmentName = item.staffGradeName
this.isAddDepartment = true
for (let j = 0; j < this.listData.length; j++) {
for (let k = 0; k < this.listData[j].children.length; k++) {
if(this.listData[j].children[k].staffGradeId == item.staffGradeId){
this.Form.MajorId = this.listData[j].staffProfessionalArchitectureId
}
}
}
}
},
async majorChange(){
let res = await this.$get(this.api.queryStaffPAN, { name: this.Form.majorName,schoolId: this.schoolId });
if(res.data.StaffProfessionalArchitecture != null){
util.warningMsg('该一级部门已存在');
this.majorNoAdd = false
}else{
this.majorNoAdd = true
}
},
async depChange(){
let res = await this.$get(this.api.queryStaffName, { staffGradeName: this.Form.departmentName,staffProfessionalArchitectureId: this.Form.MajorId });
if(res.data.staffGrade != null){
util.warningMsg('该二级部门已存在');
this.depNoAdd = false
}else{
this.depNoAdd = true
}
},
sure(){
if(!this.Form.majorName) return util.warningMsg('请输入专业名称')
if(!this.majorNoAdd) return util.warningMsg('该一级部门已存在')
let data = {
staffProfessionalArchitectureName: this.Form.majorName,
staffProfessionalArchitectureId: this.Form.MajorId,
schoolId: this.schoolId,
}
if(this.Form.MajorId){
this.$post(this.api.updateStaffPro,data).then(res => {
util.successMsg('编辑成功')
this.isaddMajor = false
this.getData()
}).catch(res => {})
}else{
this.$post(this.api.addStaffPro,data).then(res => {
util.successMsg('添加成功')
this.isaddMajor = false
this.getData()
}).catch(res => {})
}
},
//
addDepartment(item){
this.Form.departmentId = ''
this.Form.departmentName = ''
this.isAddDepartment = true
this.Form.MajorId = item.staffProfessionalArchitectureId
},
sureDepartment(Form){
if(!this.Form.departmentName) return util.warningMsg('请输入部门名称');
if(!this.depNoAdd) return util.warningMsg('该二级部门已存在');
let data = {
schoolId: this.schoolId,
staffGradeName: this.Form.departmentName,
staffProfessionalArchitectureId: this.Form.MajorId,
staffGradeId: this.Form.departmentId
}
if(this.Form.departmentId){
this.$post(this.api.updateStaffGrade,data).then(res => {
util.successMsg('编辑成功')
this.isAddDepartment = false
this.getData()
}).catch(res => {})
}else{
this.$post(this.api.addStaffGrade,data).then(res => {
util.successMsg('添加成功')
this.isAddDepartment = false
this.getData()
}).catch(res => {})
}
},
closeAdd(){
this.$refs.Form.resetFields()
},
del(item){
if(item.isParent){
this.$confirm('确定要删除该专业吗?', '提示', {
type: 'warning'
})
.then(() => {
this.$post(`${this.api.deleteStaffPro}?staffProfessionalArchitectureIds=${item.staffProfessionalArchitectureId}`).then(res => {
this.getData()
util.successMsg('删除成功')
}).catch(res => {})
}).catch(() => {})
}else{
this.$confirm('确定要删除该部门吗?', '提示', {
type: 'warning'
})
.then(() => {
this.$post(`${this.api.deleteStaffGrade}?staffGradeIds=${item.staffGradeId}`).then(res => {
this.getData()
util.successMsg('删除成功')
}).catch(res => {})
}).catch(() => {})
}
}
}
};
</script>
<style lang="scss" scoped>
/deep/.el-table{
th:first-child{
.cell{
&:before{
content: '';
display: inline-block;
padding-left: 25vw;
}
}
}
.el-table__body-wrapper{
td:first-child{
.cell{
display: flex;
justify-content: flex-end;
align-items: center;
flex-direction: row-reverse;
i{
font-size: 16px;
}
.text{
&:before{
content: '';
display: inline-block;
padding-left: 25vw;
}
}
.el-table__placeholder + .text{
&:before{
padding-left: 26vw;
}
}
.el-table__expand-icon{
transform: rotate(90deg);
&.el-table__expand-icon--expanded{
transform: rotate(-90deg);
}
}
}
}
}
}
</style>

@ -1,26 +1,20 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div>
<div class="p-title m-b-20">筛选</div>
<div class="flex">
<div>
<el-input placeholder="请输入角色名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</div>
</div>
</div>
</el-card>
<el-card shadow="hover">
<div class="flex j-between m-b-20">
<div class="p-title">角色列表</div>
<div class="tool">
<ul class="filter">
<li>
<label>搜索</label>
<el-input placeholder="请输入角色名称" v-model="keyword" suffix-icon="el-icon-search" clearable size="small"></el-input>
</li>
</ul>
<div>
<el-button type="primary" size="small" round @click="addRole" v-auth="'/system/list:角色权限:新增角色'">新增角色</el-button>
<el-button type="primary" size="small" round @click="delAllSelection" v-auth="'/system/list:角色权限:批量删除'">批量删除</el-button>
</div>
</div>
<el-table :data="roleData" class="table" stripe header-align="center" @selection-change="handleSelectionChange" :row-key="getRowKeys">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center">
</el-table-column>
<el-table-column prop="roleName" label="角色名称" align="center" width="100">
@ -33,10 +27,10 @@
<el-table-column label="操作" width="180">
<template slot-scope="scope">
<el-button type="text" @click="showRole(scope.row)" v-auth="'/system/list:角色权限:查看'">查看</el-button>
<template v-if="scope.row.id != 1">
<!-- <template v-if="scope.row.id != 1"> -->
<el-button type="text" @click="editRole(scope.row)" v-auth="'/system/list:角色权限:编辑'">编辑</el-button>
<el-button type="text" @click="handleDelete(scope.row)" v-auth="'/system/list:角色权限:删除'">删除</el-button>
</template>
<!-- </template> -->
</template>
</el-table-column>
</el-table>
@ -44,7 +38,6 @@
<el-pagination background @current-change="currentChange" :current-page="pageNo" layout="total, prev, pager, next" :total="totals">
</el-pagination>
</div>
</el-card>
<el-dialog :title="isDetail ? '查看角色' : (isAdd ? '新增角色' : '编辑角色')" :visible.sync="roleVisible"
width="30%" center @close="closeRole" class="dialog" :close-on-click-modal="false">
@ -79,6 +72,7 @@
<script>
import { mapState } from 'vuex'
import util from '@/libs/util'
export default {
name: 'role',
data() {
@ -200,9 +194,9 @@ export default {
this.roleVisible = true
},
async saveData() {
if(!this.form.roleName) return this.$message.warning('请填写角色名称')
if(!this.form.remark) return this.$message.warning('请填写角色描述')
// if(!this.$refs.per.getCheckedKeys().length) return this.$message.warning('')
if(!this.form.roleName) return util.warningMsg('请填写角色名称')
if(!this.form.remark) return util.warningMsg('请填写角色描述')
// if(!this.$refs.per.getCheckedKeys().length) return util.warningMsg('')
let roleData = {
clientId: this.clientId,
id: this.form.id,
@ -221,7 +215,7 @@ export default {
}
let perRes = await this.$post(this.api.doAssign,perData)
if(perRes.success){
this.$message.success('新增成功')
util.successMsg('新增成功')
this.getData()
this.roleVisible = false
}
@ -234,7 +228,7 @@ export default {
.then(() => {
this.$del(`${this.api.removeRole}?roleIds=${row.id}`).then(res => {
if(res.success){
this.$message.success('删除成功');
util.successMsg('删除成功');
this.getData()
}
}).catch(res => {})
@ -254,19 +248,19 @@ export default {
return item.id
})
//
this.$confirm('确定要删除选中角色吗?', '提示', {
this.$confirm(`此批量删除操作不可逆,是否确认删除${util.ellipsisStr(newArr[0].roleName)}${newArr.length}个选中项?`, '提示', {
type: 'warning'
})
.then(() => {
this.$del(`${this.api.removeRole}?roleIds=${delList.join()}`).then(res => {
if(res.success){
this.$message.success('删除成功');
util.successMsg('删除成功');
this.getData()
}
}).catch(res => {})
}).catch(() => {});
}else{
this.$message.error('请先选择数据 !');
util.errorMsg('请先选择数据 !');
}
}
}

@ -1,25 +1,25 @@
<template>
<div>
<el-container>
<el-aside width="350px">
<TeacherSide ref="getSelectData" @fircheck="fircheck" @twocheck="twocheck" @getData="getData"></TeacherSide>
</el-aside>
<el-main style="padding-top: 0">
<el-col :span="24">
<el-card shadow="hover" class="m-b-20 teacher_tab">
<div class="flex j-between m-b-20">
<div>
<el-input style="width: 250px" placeholder="请输入员工姓名/工号/角色名称" v-model="keyword" prefix-icon="el-icon-search" clearable></el-input>
</div>
<div class="tool">
<ul class="filter">
<li>
<label>筛选</label>
<el-cascader :options="orgList" :props="props" collapse-tags clearable size="small" @change="orgChange"></el-cascader>
</li>
<li>
<label>搜索</label>
<el-input style="width: 250px" placeholder="请输入员工姓名/工号/角色名称" v-model="keyword" suffix-icon="el-icon-search" clearable size="small"></el-input>
</li>
</ul>
<div>
<el-button type="primary" size="small" round @click="addTeacher" v-auth="'/system/list:员工管理:新增员工'">新增员工</el-button>
<el-button type="primary" size="small" round @click="batchImport" v-auth="'/system/list:员工管理:批量导入'">批量导入</el-button>
<el-button type="primary" size="small" round @click="delAllSelection" v-auth="'/system/list:员工管理:批量删除'">批量删除</el-button>
</div>
</div>
<el-table :data="listData" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center"></el-table-column>
<el-table-column type="selection" width="80" align="center"></el-table-column>
<el-table-column type="index" label="序号" width="55" align="center">
</el-table-column>
<el-table-column prop="userName" label="职工姓名" align="center">
@ -54,14 +54,8 @@
<el-pagination background layout="total,prev, pager, next" :current-page="pageNo" @current-change="handleCurrentChange" :total="total">
</el-pagination>
</div>
</el-card>
</el-col>
</el-main>
</el-container>
<!-- 新增用户 -->
<el-dialog :title="isDetail ? '查看员工' : (isAddteacher ? '新增员工' : '编辑员工')" :visible.sync="teacherVisible"
width="30%" :center="!isIE" @close="closeTeacher" class="dialog" :close-on-click-modal="false">
<el-dialog :title="isDetail ? '查看员工' : (isAddteacher ? '新增员工' : '编辑员工')" :visible.sync="teacherVisible" width="500px" @close="closeTeacher" class="dialog" :close-on-click-modal="false">
<el-form ref="teacherForm" :model="teacherForm" :rules="rules" label-width="100px" :disabled="isDetail">
<el-form-item prop="userAccount" label="账号">
<el-input v-model="teacherForm.userAccount" ref="account" placeholder="请输入职工账号" @change="accountChange"></el-input>
@ -82,7 +76,7 @@
</el-form-item>
<el-form-item prop="major" label="一级部门">
<el-select v-model="teacherForm.major" placeholder="请选择一级部门" @change="getDepartment">
<el-option v-for="(item,index) in majorList" :key="index"
<el-option v-for="(item,index) in orgList" :key="index"
:label="item.staffProfessionalArchitectureName" :value="item.staffProfessionalArchitectureId"></el-option>
</el-select>
</el-form-item>
@ -108,45 +102,82 @@
</span>
</el-dialog>
<!-- 批量导入 -->
<el-dialog title="批量导入" :visible.sync="importVisible" width="24%" center :close-on-click-modal="false">
<div style="text-align: center">
<div style="margin-bottom: 10px;"><el-button type="primary" @click="downLoad">模板下载<i class="el-icon-download el-icon--right"></i></el-button></div>
<el-upload
accept=".xls,.xlsx"
:on-remove="handleRemove"
:on-error="uploadError"
:on-success="uploadSuccess"
:before-remove="beforeRemove"
:limit="1"
:data="{schoolId: this.clientId}"
:on-exceed="handleExceed"
:action="this.api.uploadFileStaff"
:file-list="uploadList"
name="file"
>
<el-button type="primary" class="ml20">上传文件<i class="el-icon-upload2 el-icon--right"></i></el-button>
<el-dialog title="查看员工" :visible.sync="staffShowVisible" width="500px" :close-on-click-modal="false">
<ul class="list">
<li>
<span class="name"><i class="required">*</i>账号</span>
<span class="val">{{teacherForm.userAccount}}</span>
</li>
<li>
<span class="name"><i class="required">*</i>用户姓名</span>
<span class="val">{{teacherForm.userName}}</span>
</li>
<li>
<span class="name">账号角色</span>
<span class="val">{{teacherForm.roleValue ? roleList.find(n => n.id == teacherForm.roleValue).roleName : ''}}</span>
</li>
<li>
<span class="name">唯一标识</span>
<span class="val">{{teacherForm.uniqueIdentificationAccount}}</span>
</li>
<li>
<span class="name"><i class="required">*</i>职工工号</span>
<span class="val">{{teacherForm.workNumber}}</span>
</li>
<li>
<span class="name"><i class="required">*</i>一级部门</span>
<span class="val">{{teacherForm.major ? orgList.find(n => n.staffProfessionalArchitectureId == teacherForm.major).staffProfessionalArchitectureName : ''}}</span>
</li>
<li>
<span class="name"><i class="required">*</i>二级部门</span>
<span class="val">{{teacherForm.managerDepartment ? managerDepartmentList.find(n => n.staffGradeId == teacherForm.managerDepartment).staffGradeName : ''}}</span>
</li>
<li>
<span class="name">手机号</span>
<span class="val">{{teacherForm.phone}}</span>
</li>
<li>
<span class="name">邮箱</span>
<span class="val">{{teacherForm.email}}</span>
</li>
<li>
<span class="name">默认密码</span>
<span class="val">{{password}}</span>
</li>
</ul>
</el-dialog>
<el-dialog title="批量导入" :visible.sync="importVisible" width="400px" :close-on-click-modal="false">
<div class="upload-wrap" :class="{lg: uploadFaild}">
<el-button class="download" size="small" @click="downLoad"><img src="../../../assets/img/download.png" alt=""> 模板下载</el-button>
<el-upload accept=".xls,.xlsx" :on-remove="handleRemove" :on-error="uploadError" :on-success="uploadSuccess" :before-remove="beforeRemove" :limit="1" :on-exceed="handleExceed" :action="this.api.uploadFileStaff" :file-list="uploadList" :data="{schoolId: this.clientId}" name="file">
<el-button size="small"><img src="../../../assets/img/upload.png" alt=""> 上传文件</el-button>
</el-upload>
<el-link v-if="uploadFaild" type="primary" @click="showFaild">导入失败查看原因</el-link>
<div class="link" v-if="uploadFaild">
<el-link type="primary" @click="showFaild">导入失败查看原因</el-link>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="importVisible = false"> </el-button>
<el-button type="primary" @click="uploadSure"> </el-button>
<el-button size="small" @click="importVisible = false"> </el-button>
<el-button size="small" type="primary" @click="uploadSure"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import TeacherSide from './staffSide.vue';
import Setting from '@/setting';
import { mapState } from 'vuex';
import util from '@/libs/util'
export default {
data() {
return {
pages: 10,
isDetail: false,
props: { multiple: true },
orgList: [],
isAddteacher: false,
teacherVisible: false,
staffShowVisible: false,
roleList: [],
teacherForm: {
teacherId: '',
@ -215,7 +246,6 @@ export default {
// { required: true, message: '', trigger: 'change' }
// ],
},
majorList: [],
listData: [],
importVisible: false,
keyword: '',
@ -258,9 +288,6 @@ export default {
'isIE'
])
},
components: {
TeacherSide
},
watch: {
keyword: function(val) {
clearTimeout(this.searchTimer)
@ -270,41 +297,40 @@ export default {
}
},
mounted(){
this.getOrg()
this.teacherForm.clientId = this.clientId
this.teacherForm.clientName = this.clientName
this.getData()
this.getRoles()
},
methods: {
handleCheck(data){
let oneDepartmentIds = []
let twoDepartmentIds = []
data.forEach( e => {
if(e.ischeck){
oneDepartmentIds.push(e.staffProfessionalArchitectureId)
}else{
util.removeByValue(oneDepartmentIds, e.staffProfessionalArchitectureId);
}
e.children.forEach( r => {
if(r.ischeck){
twoDepartmentIds.push(r.staffGradeId)
}else{
util.removeByValue(twoDepartmentIds, r.staffGradeId);
getOrg(){
let data = {
schoolId: this.clientId
}
this.$get(this.api.queryStaffPro,data).then(res => {
let firList = res.data.StaffProfessionalArchitectureList
if(firList){
firList.map(e => {
e.isParent = true
e.value = e.staffProfessionalArchitectureId
e.label = e.staffProfessionalArchitectureName
let data = {
staffProfessionalArchitectureId: e.staffProfessionalArchitectureId
}
this.$get(this.api.queryStaffGrade,data).then(res1 => {
res1.data.staffGradeList.map(e => {
e.value = e.staffGradeId
e.label = e.staffGradeName
})
e.children = res1.data.staffGradeList
}).catch(res => {})
})
this.oneDepartmentIds = oneDepartmentIds.toString()
this.twoDepartmentIds = twoDepartmentIds.toString()
this.getData()
},
fircheck(val,val2){
val.ischeck = !val.ischeck
val.children.map( e => e.ischeck = val.ischeck)
this.handleCheck(val2)
},
twocheck(val,val2){
this.handleCheck(val2)
setTimeout(() => {
this.orgList = firList
},500)
}
}).catch(res => {})
},
getData(){
let totalPage = Math.ceil((this.total - 1) / this.pageSize)
@ -331,6 +357,10 @@ export default {
this.pageNo = 1
this.getData()
},
orgChange(node){
this.twoDepartmentIds = node.map(n => n[1]).toString()
this.getData()
},
getRoles(){
let data = {
clientId: this.clientId
@ -348,9 +378,9 @@ export default {
}
this.$post(this.api.userinfoUpdate,data).then(res => {
if(res.success){
this.$message.success('重置成功')
util.successMsg('重置成功')
}else{
this.$message.error('重置失败')
util.errorMsg('重置失败')
}
}).catch(res => {});
}).catch(() => {
@ -361,7 +391,7 @@ export default {
this.$get(`${this.api.getAccount}?account=${this.teacherForm.userAccount}`).then(res => {
if(res.data.userInfo){
this.accountRepeat = true
this.$message.warning('该账号已存在')
util.warningMsg('该账号已存在')
}else{
this.accountRepeat = false
}
@ -375,7 +405,7 @@ export default {
this.$get(`${this.api.getWorkNumber}?workNumber=${this.teacherForm.workNumber}`).then(res => {
if(res.data.staff){
this.workNumberRepeat = true
this.$message.warning('该工号已存在')
util.warningMsg('该工号已存在')
}else{
this.workNumberRepeat = false
}
@ -399,7 +429,6 @@ export default {
this.teacherVisible = true
this.isAddteacher = true
this.teacherForm.teacherId = ''
this.majorList = this.$refs.getSelectData.majorList
},
getStaffDetail(userId){
this.$get(`${this.api.getStaff}/${userId}`).then(res => {
@ -432,16 +461,14 @@ export default {
this.isAddteacher = false
this.AccountNoAdd = false
this.teacherForm.teacherId = row.staffId
this.majorList = this.$refs.getSelectData.majorList
this.getStaffDetail(row.staffId)
},
showTeacher(row){
this.staffShowVisible = true
this.isDetail = true
this.teacherVisible = true
this.isAddteacher = false
this.isAddManage = false
this.AccountNoAdd = false
this.teacherForm.teacherId = row.staffId
this.majorList = this.$refs.getSelectData.majorList
this.teacherForm.manageId = row.staffId
this.getStaffDetail(row.staffId)
},
getDepartment(){
@ -455,8 +482,8 @@ export default {
async saveSure(teacherForm){
this.$refs[teacherForm].validate((valid) => {
if (valid) {
if(this.accountRepeat) return this.$message.warning('该账号已存在')
if(this.workNumberRepeat) return this.$message.warning('该工号已存在')
if(this.accountRepeat) return util.warningMsg('该账号已存在')
if(this.workNumberRepeat) return util.warningMsg('该工号已存在')
let isTeacher = false
let isManager = false
let data = {
@ -474,9 +501,9 @@ export default {
}
}
let oneDepartmentName = '';
for(let i in this.majorList){
if(this.majorList[i].staffProfessionalArchitectureId == this.teacherForm.major) {
oneDepartmentName = this.majorList[i].staffProfessionalArchitectureName
for(let i in this.orgList){
if(this.orgList[i].staffProfessionalArchitectureId == this.teacherForm.major) {
oneDepartmentName = this.orgList[i].staffProfessionalArchitectureName
break;
}
}
@ -498,13 +525,13 @@ export default {
if(this.teacherForm.teacherId){
this.$post(this.api.updateStaff,data).then(res => {
this.teacherVisible = false
this.$message.success('编辑成功');
util.successMsg('编辑成功');
this.getData()
}).catch(res => {});
}else{
this.$post(this.api.addStaff,data).then(res => {
this.teacherVisible = false
this.$message.success('添加成功');
util.successMsg('添加成功');
this.getData()
}).catch(res => {});
}
@ -514,7 +541,7 @@ export default {
})
},
delTeacher(row){
this.$confirm('确定要删除吗?', '提示', {
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', {
type: 'warning'
})
.then(() => {
@ -522,7 +549,7 @@ export default {
staffIds: row.staffId
}
this.$del(this.api.deleteStaffs,data).then(res => {
this.$message.success('删除成功')
util.successMsg('删除成功')
this.getData()
}).catch(res => {});
})
@ -538,7 +565,7 @@ export default {
return item.staffId
})
//
this.$confirm('确定要删除吗?', '提示', {
this.$confirm(`此批量删除操作不可逆,是否确认删除${util.ellipsisStr(newArr[0].userName)}${newArr.length}个选中项?`, '提示', {
type: 'warning'
})
.then(() => {
@ -547,12 +574,12 @@ export default {
}
this.$del(this.api.deleteStaffs,data).then(res => {
this.multipleSelection = [];
this.$message.success('删除成功')
util.successMsg('删除成功')
this.getData()
}).catch(res => {});
}).catch(() => {});
}else{
this.$message.error('请先选择数据 !')
util.errorMsg('请先选择数据 !')
}
},
batchImport(){
@ -576,7 +603,7 @@ export default {
},
//
handleExceed(files, fileList) {
this.$message.warning(
util.warningMsg(
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
);
},
@ -587,10 +614,10 @@ export default {
this.token = res.data.data.token
this.uploadFaild = true
}else{
this.$message.success('上传成功')
util.successMsg('上传成功')
}
}else{
res.data.message ? this.$message.error(res.data.message) : this.$message.error('上传失败,请检查数据')
res.data.message ? util.errorMsg(res.data.message) : util.errorMsg('上传失败,请检查数据')
}
},
uploadError(err, file, fileList) {
@ -617,11 +644,38 @@ export default {
};
</script>
<style lang="scss" scoped>
.el-container{
background-color: #f0f0f0;
/deep/.dialog{
.el-form-item{
.el-form-item__label{
font-size: 16px;
color: rgba(0, 0, 0, 0.65);
&:before{
margin-right: 0;
color: #CC221C;
}
}
}
.el-input,.el-select{
width: 100%;
}
}
.list{
li{
display: flex;
justify-content: center;
align-items: center;
margin: 32px 0;
.name,.val{
font-size: 16px;
color: rgba(0, 0, 0, 0.65);
}
.name{
width: 45%;
text-align: right;
}
.val{
width: 55%;
}
}
.mag{
margin-right: 20px;
margin-left: 20px;
}
</style>

@ -1,301 +0,0 @@
<template>
<div>
<div class="side_view second">
<p class="side_icon">
<i class="icon-jiahao" @click="addMajor"></i>
<!-- <i class="icon-delete"></i> -->
</p>
<div class="side_tree" @click.stop="open(item)" v-for="(item,index) in majorList" :key="index">
<div class="item" @click.stop="open(item)">
<!-- <i :class="{ 'arrowTransform': !item.ifVisible, 'arrowTransformReturn': item.ifVisible}" class="icon-shixiangyoujiantou-"></i> -->
<img
v-if="item.children&&item.children.length!=0"
:class="{ 'arrowTransform': !item.ifVisible, 'arrowTransformReturn': item.ifVisible}"
src="../../../assets/img/icon-xiangyou.png"
alt
/>
<i v-else class="empty"></i>
<i :class="item.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="fircheckitem(item)"></i>
<span @click.stop="fircheckitem(item)">{{item.staffProfessionalArchitectureName}}</span>
<i class="edit ft" @click.stop="editMajor(item)"></i>
<i class="el-icon-circle-plus ft" @click.stop="addDepartment(item)"></i>
<i class="icon-delete ft" @click.stop="delMajor(item,index)"></i>
</div>
<div v-show="item.ifVisible" v-if="item.children&&item.children.length!=0">
<div v-for="(item1,index1) in item.children" :key="index1">
<div class="item2" @click.stop="open(item1)">
<i :class="item1.ischeck ? 'icon-yigouxuan' : 'icon-weigouxuan'" @click.stop="twocheckitem(item1)"></i>
<span @click.stop="twocheckitem(item1)">{{item1.label}}</span>
<i class="edit ft" @click.stop="editDepartment(item1)"></i>
<i class="icon-delete ft" @click.stop="delDepartment(item1,index1)"></i>
</div>
</div>
</div>
</div>
</div>
<!-- 添加专业 -->
<el-dialog :title="Form.MajorId ? '编辑专业' : '新增专业'" :visible.sync="isaddMajor" width="24%" center @close="closeAdd" :close-on-click-modal="false">
<el-form ref="Form" :model="Form">
<el-form-item prop="majorName">
<el-input placeholder="请输入专业名称" v-model="Form.majorName" @change="majorChange"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="isaddMajor = false"> </el-button>
<el-button type="primary" @click="sure('Form')"> </el-button>
</span>
</el-dialog>
<!-- 添加部门 -->
<el-dialog :title="Form.departmentId ? '编辑部门' : '新增部门'" :visible.sync="isAddDepartment" width="24%" center @close="closeAdd" :close-on-click-modal="false">
<el-form ref="Form" :model="Form">
<el-form-item prop="departmentName">
<el-input placeholder="请输入部门名称" v-model="Form.departmentName" @change="depChange"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="isAddDepartment = false"> </el-button>
<el-button type="primary" @click="sureDepartment('Form')"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { mapState } from 'vuex';
export default {
props:["Data"],
data() {
return {
majorList: [],
firactive: 0,
twoactive: 0,
isaddMajor: false,
isAddDepartment: false,
Form: {
MajorId: '',
majorName: '',
departmentId: '',
departmentName: ''
},
staffstateProfessId: '',
staffstateId: '',
majorNoAdd: true,
depNoAdd: true
};
},
computed: {
...mapState('user', [
'clientId','clientName'
])
},
mounted(){
this.getStaff()
},
methods: {
getStaff(majorIds){
let data = {
schoolId: this.clientId
}
this.$get(this.api.queryStaffPro,data).then(res => {
let firList = res.data.StaffProfessionalArchitectureList
if(firList){
firList.map(e => {
(e.ifVisible = false), (e.ischeck = false), (e.label = e.staffProfessionalArchitectureName);
majorIds && majorIds.includes(e.staffProfessionalArchitectureId) && (e.ifVisible = true)
let data = {
staffProfessionalArchitectureId: e.staffProfessionalArchitectureId
}
this.$get(this.api.queryStaffGrade,data).then(res1 => {
res1.data.staffGradeList.map(e => {
(e.ischeck = false), (e.label = e.staffGradeName);
})
e.children = res1.data.staffGradeList
}).catch(res1 => {});
})
}
setTimeout(() => {
this.majorList = firList
majorIds || (this.majorList[0].ifVisible = true)
}, 500);
}).catch(res => {});
},
//
open(item) {
item.ifVisible = !item.ifVisible;
},
//removeByvaluemain.js
choose(item) {
item.ifVisible = !item.ifVisible;
if (item.ifVisible) {
this.chooseList.push(item);
} else {
this.chooseList.removeByValue(item);
}
},
//
fircheckitem(item){
this.$emit("fircheck",item,this.majorList)
},
//
twocheckitem(item){
item.ischeck = !item.ischeck
this.majorList.forEach( e => {
e.children.forEach( r => {
if(r.staffGradeId == item.staffGradeId){
if(e.children.every(i => i.ischeck)){
e.ischeck = true
}else{
e.ischeck = false
}
}
})
})
this.$emit("twocheck",item,this.majorList)
},
closeAdd(){
this.$refs.Form.resetFields()
},
//
addMajor(){
this.Form.MajorId = ''
this.Form.majorName = ''
this.isaddMajor = true
},
editMajor(item){
this.Form.MajorId = item.staffProfessionalArchitectureId,
this.Form.majorName = item.staffProfessionalArchitectureName
this.isaddMajor = true
},
async majorChange(){
let res = await this.$get(this.api.queryStaffPAN, { name: this.Form.majorName,schoolId: this.clientId });
if(res.data.StaffProfessionalArchitecture != null){
this.$message.warning('该一级部门已存在');
this.majorNoAdd = false
}else{
this.majorNoAdd = true
}
},
async depChange(){
let res = await this.$get(this.api.queryStaffName, { staffGradeName: this.Form.departmentName,staffProfessionalArchitectureId: this.Form.MajorId });
if(res.data.staffGrade != null){
this.$message.warning('该二级部门已存在');
this.depNoAdd = false
}else{
this.depNoAdd = true
}
},
sure(Form){
if(!this.Form.majorName) return this.$message.warning('请输入专业名称');
if(!this.majorNoAdd) return this.$message.warning('该一级部门已存在');
let data = {
staffProfessionalArchitectureName: this.Form.majorName,
staffProfessionalArchitectureId: this.Form.MajorId,
schoolId: this.clientId,
}
if(this.Form.MajorId){
this.$post(this.api.updateStaffPro,data).then(res => {
this.$message.success('编辑成功');
this.isaddMajor = false
this.getStaff()
this.$emit('getData')
}).catch(res => {});
}else{
this.$post(this.api.addStaffPro,data).then(res => {
this.$message.success('添加成功');
this.isaddMajor = false
this.getStaff()
}).catch(res => {});
}
},
//
addDepartment(item){
this.Form.departmentId = ''
this.Form.departmentName = ''
this.isAddDepartment = true
this.Form.MajorId = item.staffProfessionalArchitectureId
},
editDepartment(item){
this.Form.departmentId = item.staffGradeId,
this.Form.departmentName = item.staffGradeName
this.isAddDepartment = true
for (let j = 0; j < this.majorList.length; j++) {
for (let k = 0; k < this.majorList[j].children.length; k++) {
if(this.majorList[j].children[k].staffGradeId == item.staffGradeId){
this.Form.MajorId = this.majorList[j].staffProfessionalArchitectureId
}
}
}
},
sureDepartment(Form){
if(!this.Form.departmentName) return this.$message.warning('请输入部门名称');
if(!this.depNoAdd) return this.$message.warning('该二级部门已存在');
let data = {
schoolId: this.clientId,
staffGradeName: this.Form.departmentName,
staffProfessionalArchitectureId: this.Form.MajorId,
staffGradeId: this.Form.departmentId
}
if(this.Form.departmentId){
this.$post(this.api.updateStaffGrade,data).then(res => {
this.$message.success('编辑成功');
this.isAddDepartment = false
this.majorList.map(e =>{
e.children.map(r =>{
if(r.staffGradeId == this.Form.departmentId){
r.staffGradeName = this.Form.departmentName
r.label = this.Form.departmentName
}
})
})
}).catch(res => {});
}else{
let showMajorIds = this.majorList.map(e => {if(e.ifVisible) return e.staffProfessionalArchitectureId}).filter(n => n)
this.$post(this.api.addStaffGrade,data).then(res => {
this.$message.success('添加成功');
this.isAddDepartment = false
this.getStaff(showMajorIds)
}).catch(res => {});
}
},
delMajor(item,index){
this.$confirm('确定要删除该专业吗?', '提示', {
type: 'warning'
})
.then(() => {
this.$post(`${this.api.deleteStaffPro}?staffProfessionalArchitectureIds=${item.staffProfessionalArchitectureId}`).then(res => {
this.$message.success('删除成功');
this.majorList.splice(index, 1)
}).catch(res => {});
})
.catch(() => {});
},
delDepartment(item,indx){
this.$confirm('确定要删除该部门吗?', '提示', {
type: 'warning'
})
.then(() => {
this.$post(`${this.api.deleteStaffGrade}?staffGradeIds=${item.staffGradeId}`).then(res => {
this.$message.success('删除成功');
this.majorList.map(e =>{
e.children.map(r =>{
if(r.staffGradeId == item.staffGradeId){
e.children.splice(indx,1)
if(e.children.length == 0){
e.ifVisible = false
}
}
})
})
}).catch(res => {})
})
.catch(() => {})
}
}
};
</script>
<style lang="scss" scoped>
@import '../../../styles/pages/tree.scss';
</style>

@ -1,16 +1,19 @@
<template>
<div class="box">
<div>
<breadcrumb :data="'试卷管理/创建试卷'"></breadcrumb>
<div class="page">
<div class="page-content">
<div class="form">
<div class="line">
<div class="item">
<p class="key">试卷名称</p>
<el-input v-model="name"></el-input>
<el-input v-model="name" size="small"></el-input>
</div>
</div>
<div class="line">
<div class="item">
<p class="key">试卷用途</p>
<el-select v-model="effect" placeholder="请选择试卷用途">
<el-select v-model="effect" placeholder="请选择试卷用途" size="small">
<el-option v-for="(item,index) in effectList" :key="index" :label="item.label" :value="item.id"></el-option>
</el-select>
</div>
@ -22,30 +25,30 @@
<div class="line">
<div class="item">
<p class="key">难易程度</p>
<el-select v-model="degree" placeholder="请选择难易程度">
<el-select v-model="degree" placeholder="请选择难易程度" size="small">
<el-option v-for="(item,index) in degreeList" :key="index" :label="item.label" :value="item.id"></el-option>
</el-select>
</div>
<div class="item lg">
<p class="key">建议时长分钟</p>
<el-input v-model.number="duration" type="number" min="0"></el-input>
<el-input v-model.number="duration" type="number" min="0" size="small"></el-input>
</div>
</div>
<div class="line">
<div class="item">
<p class="key">组卷方式</p>
<div>
<el-radio v-for="(item,index) in typeList" :key="index" v-model="type" :label="item.id">{{item.label}}</el-radio>
<el-radio v-for="(item,index) in typeList" :key="index" v-model="type" :label="item.id" size="small">{{item.label}}</el-radio>
</div>
</div>
</div>
<div class="line">
<div class="item">
<p class="key">组卷方式</p>
<div>
<el-button type="primary" @click="selectQues">选择试题</el-button>
<el-button type="primary" @click="removeQues">移除试题</el-button>
<el-button type="primary" @click="preview">试卷预览</el-button>
<p class="key">组卷操作</p>
<div class="btn-wrap">
<button type="button" @click="selectQues">选择试题</button>
<button type="button" @click="removeQues">移除试题</button>
<button type="button" @click="preview">试卷预览</button>
</div>
</div>
</div>
@ -53,7 +56,7 @@
<div class="testpaper">
<el-table :data="selectedData" ref="selectedTable" class="table" stripe header-align="center" row-key="id" @selection-change="handleSelecteChange">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="questionSource" label="题库来源" width="120" align="center"></el-table-column>
<el-table-column prop="questionStem" label="题干" align="center" :show-overflow-tooltip="true"></el-table-column>
@ -109,61 +112,49 @@
<button type="button" v-throttle @click="save(0)" v-if="!state">保存</button>
<button type="button" v-throttle class="submit" @click="save(1)">完成并发布</button>
</div>
</div>
</div>
<el-dialog title="选择试题" :visible.sync="manualVisible" width="60%" @close="closeManual" :close-on-click-modal="false">
<div class="mini-form">
<el-form label-width="80px" inline size="mini">
<el-form-item class="no-mb" label="课程名称">
<el-select v-model="selectManual.courses" clearable placeholder="请选择课程名称" @change="getManualData">
<div class="tool">
<ul class="filter">
<li>
<label>课程名称</label>
<el-select v-model="selectManual.courses" clearable placeholder="请选择课程名称" size="small" @change="getManualData">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in courseList" :key="index" :label="item.courses" :value="item.courses"></el-option>
</el-select>
</el-form-item>
<el-form-item class="no-mb" label="知识点">
<el-select v-model="selectManual.knowledgePoints" clearable placeholder="请选择知识点" @change="getManualData">
</li>
<li>
<label>知识点</label>
<el-select v-model="selectManual.knowledgePoints" clearable placeholder="请选择知识点" size="small" @change="getManualData">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in pointList" :key="index" :label="item.knowledgePoint" :value="item.knowledgePoint"></el-option>
</el-select>
</el-form-item>
</el-form>
<div class="flex j-between" style="align-items: flex-start">
<el-form label-width="80px" inline size="mini">
<el-form-item class="no-mb" label="试题类型">
<el-select v-model="selectManual.name" clearable placeholder="请选择试题类型" @change="getManualData">
</li>
<li>
<label>试题类型</label>
<el-select v-model="selectManual.name" clearable placeholder="请选择试题类型" size="small" @change="getManualData">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in nameList" :key="index" :label="item.name" :value="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item class="no-mb" label="所属题库">
<el-select v-model="selectManual.typeName" clearable placeholder="请选择所属题库" @change="getManualData">
</li>
<li>
<label>所属题库</label>
<el-select v-model="selectManual.typeName" clearable placeholder="请选择所属题库" size="small" @change="getManualData">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in quesBankList" :key="index" :label="item.typeName" :value="item.typeName"></el-option>
</el-select>
</el-form-item>
</el-form>
<div>
<el-input
size="mini"
placeholder="请输入题干名称"
prefix-icon="el-icon-search"
v-model="keyword"
clearable
></el-input>
</div>
</div>
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入题干名称" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
</div>
<el-table
:data="listData"
max-height="400"
ref="listTable"
row-key="id"
class="table"
stripe
header-align="center"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" :reserve-selection="true" :selectable="disabledSelection"></el-table-column>
<el-table :data="listData" max-height="400" ref="listTable" row-key="id" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="80" align="center" :reserve-selection="true" :selectable="disabledSelection"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center">
<template
slot-scope="scope"
@ -195,22 +186,28 @@
</span>
</el-dialog>
<el-dialog title="选择试题" :visible.sync="inteVisible" width="60%" @close="closeInte" :close-on-click-modal="false">
<el-dialog title="选择试题" :visible.sync="inteVisible" width="870px" @close="closeInte" :close-on-click-modal="false">
<div class="select-wrap">
<div class="block" style="margin-bottom: 30px;">
<!-- <p class="key">试题课程</p> -->
<div class="m-r-10" style="width: 100px">
<el-select v-model="inteType" placeholder="请选择" size="mini">
<p class="key">筛选</p>
<div style="display: inline-flex;align-items: flex-start;">
<el-select class="m-r-20" v-model="inteType" placeholder="请选择" size="mini">
<el-option label="试题课程" value="1"></el-option>
<el-option label="知识点" value="2"></el-option>
</el-select>
<el-select v-if="inteType == 1" v-model="course" placeholder="请选择试题课程" size="mini" multiple filterable @change="courseChange">
<el-option v-for="(item,index) in inteListData" :key="index" :label="item.courses" :value="item.courses"></el-option>
</el-select>
<el-select v-else v-model="kn" placeholder="请选择知识点" size="mini" multiple filterable @change="knChange">
<el-option v-for="(item,index) in knListData" :key="index" :label="item.knowledgePoint" :value="item.knowledgePoint"></el-option>
</el-select>
</div>
<el-transfer v-if="inteType == 1" v-model="course" :data="inteListData" :props="courseProps" filterable filter-placeholder="请输入课程名称" :titles="['未选', '已选']" @change="courseChange"></el-transfer>
<el-transfer v-else v-model="kn" :data="knListData" :props="knProps" filterable filter-placeholder="请输入知识点名称" :titles="['未选', '已选']" @change="knChange"></el-transfer>
<!-- <el-transfer v-if="inteType == 1" v-model="course" :data="inteListData" :props="courseProps" filterable filter-placeholder="请输入课程名称" :titles="['未选', '已选']" @change="courseChange"></el-transfer>
<el-transfer v-else v-model="kn" :data="knListData" :props="knProps" filterable filter-placeholder="请输入知识点名称" :titles="['未选', '已选']" @change="knChange"></el-transfer> -->
</div>
<div class="block">
<p class="key">题型配置</p>
<p class="key">配置题型</p>
<div class="types">
<div class="item">
<el-checkbox v-model="countCheck.countCheck1">单选题</el-checkbox>
@ -248,12 +245,11 @@
</div>
</template>
<script>
import mixins from '@/mixins/setBackground'
import { mapState,mapActions } from 'vuex'
import testPaper from '@/components/testPaperDetail'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default {
mixins: [ mixins ],
data() {
return {
id: this.$route.query.id,
@ -340,7 +336,7 @@ export default {
selectedData: []
};
},
components: {testPaper},
components: {testPaper,breadcrumb},
directives: {
disabled: function(el,binding,vnode){
let that = vnode.context
@ -433,18 +429,18 @@ export default {
return val === '' ? 0 : val
},
save(status) {
if(!this.name) return this.$message.warning('请填写试卷名称')
if(!this.name) return util.warningMsg('请填写试卷名称')
let qid = this.selectedData.map(n => n.id).join()
if(status == 1){
if(this.effect === '') return this.$message.warning('请选择试卷用途')
if(this.courses === '') return this.$message.warning('请填写所属课程')
if(this.degree === '') return this.$message.warning('请选择难易程度')
if(this.duration === '') return this.$message.warning('请填写建议时长')
if(this.effect === '') return util.warningMsg('请选择试卷用途')
if(this.courses === '') return util.warningMsg('请填写所属课程')
if(this.degree === '') return util.warningMsg('请选择难易程度')
if(this.duration === '') return util.warningMsg('请填写建议时长')
}
if(qid === '') return this.$message.warning('请选择试题')
if(qid === '') return util.warningMsg('请选择试题')
if(status == 1){
if(this.totalScore < 100) return this.$message.warning('总分值未满100分,请重新设置')
if(this.totalScore > 100) return this.$message.warning('总分值超过100分,请重新设置')
if(this.totalScore < 100) return util.warningMsg('总分值未满100分,请重新设置')
if(this.totalScore > 100) return util.warningMsg('总分值超过100分,请重新设置')
}
let data = {
@ -472,13 +468,13 @@ export default {
}
if(this.id){
this.$post(this.api.saveOrUpdatetestPaper, data).then(res => {
this.$message.success('修改成功')
util.successMsg('修改成功')
this.$router.back()
})
.catch(err => {})
}else{
this.$post(this.api.saveOrUpdatetestPaper, data).then(res => {
this.$message.success('创建成功')
util.successMsg('创建成功')
this.$router.back()
})
.catch(err => {})
@ -523,12 +519,11 @@ export default {
this.multipleSelected = val
},
removeQues(){
if(!this.selectedData.length) return this.$message.error('请先添加试题')
if(!this.selectedData.length) return util.errorMsg('请先添加试题')
if(this.multipleSelected.length){
this.$confirm('确定要移除吗?', '提示', {
type: 'warning'
})
.then(() => {
}).then(() => {
let newData = []
this.selectedData.forEach((n,i) => {
this.multipleSelected.every(e => e.id != n.id) && newData.push(n)
@ -536,15 +531,14 @@ export default {
this.selectedData = newData
this.computeTypeCount()
this.$refs.selectedTable.clearSelection()
this.$message.success('移除成功')
})
.catch(() => {})
util.successMsg('移除成功')
}).catch(() => {})
}else{
this.$message.error('请先选择数据')
util.errorMsg('请先选择数据')
}
},
preview(){
if(!this.selectedData.length) return this.$message.error('请先添加试题')
if(!this.selectedData.length) return util.errorMsg('请先添加试题')
this.$post(`${this.api.previewPaper}?qid=${this.selectedData.map(n => n.id).join(',')}`)
.then(res => {
this.setInfo({
@ -572,8 +566,7 @@ export default {
this.$post(`${this.api.getSelectInfo}?type=2`)
.then(res => {
this.courseList = res.data.pointList
})
.catch(err => {})
}).catch(err => {})
},
getType() {
this.$get(this.api.typesList)
@ -598,8 +591,7 @@ export default {
result = result.concat(n.secondColumn)
})
this.quesBankList = result
})
.catch(err => {})
}).catch(err => {})
},
computeTypeCount(){
let selected = this.selectedData
@ -636,7 +628,7 @@ export default {
this.computeTypeCount()
this.manualVisible = false
}else{
this.$message.error('请选择试题')
util.errorMsg('请选择试题')
}
},
closeManual(){
@ -708,7 +700,7 @@ export default {
},
countValid(index){
if(this[`countNumberInput${index}`] > this[`countNumber${index}`]){
this.$message.error(`${this.typeNameList[index-1]}输入题数不能大于可选题数`)
util.errorMsg(`${this.typeNameList[index-1]}输入题数不能大于可选题数`)
return false
}
return true
@ -727,7 +719,7 @@ export default {
// if(this[`countNumberInput${index}`] < this.pointRules[index-1]){
// invalid = true
// }else if(this[`countNumberInput${index}`] > this.pointRules[index-1]){
// this.$message.error('')
// util.errorMsg('')
// return false
// }
}
@ -735,8 +727,8 @@ export default {
invalid = true
}
}
if(everyUnchecked) return this.$message.error('请选择题型')
if(everyIsZero) return this.$message.error('请输入题目数量')
if(everyUnchecked) return util.errorMsg('请选择题型')
if(everyIsZero) return util.errorMsg('请输入题目数量')
let totalCount = 0
if(invalid){
for(let i in this.countCheck){
@ -916,9 +908,6 @@ export default {
</script>
<style lang="scss" scoped>
.box{
width: 90%;
margin: 0 auto;
.form{
.line{
display: flex;
@ -927,27 +916,23 @@ export default {
.item{
display: inline-flex;
align-items: center;
flex: 1;
/deep/.el-select{
flex: 1;
}
.key{
margin-right: 20px;
white-space: nowrap;
font-size: 14px;
color: #555;
color: rgba(0, 0, 0, 0.65);
}
&.lg .key{
width: 220px;
width: 160px;
margin-right: 10px;
text-align: right;
}
.el-input,.el-select{
width: 216px;
}
}
}
}
.testpaper{
padding: 10px;
background-color: #f7f7f7;
.point{
display: flex;
margin-top: 20px;
@ -979,7 +964,10 @@ export default {
outline: none;
}
&:disabled{
background-color: #e8e8e8;
width: 56px;
background-color: rgba(0, 0, 0, 0.04);
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
cursor: not-allowed;
}
}
@ -987,36 +975,38 @@ export default {
}
}
}
}
.mini-form{
/deep/.el-form-item__content{
/deep/.mini-form{
.el-form-item__content{
width: 150px;
}
}
.select-wrap{
width: 90%;
margin: 0 auto;
/deep/.select-wrap{
.block{
display: flex;
.key{
margin-right: 20px;
font-size: 14px;
color: #555;
font-size: 16px;
color: rgba(0, 0, 0, 0.65);
white-space: nowrap;
}
.types{
display: flex;
flex-wrap: wrap;
.item{
display: flex;
align-items: center;
margin-bottom: 10px;
color: #444;
margin-right: 16px;
color: rgba(0, 0, 0, 0.65);
font-size: 12px;
/deep/.el-checkbox__label{
.el-checkbox__label{
color: #444;
font-size: 12px;
}
input{
width: 80px;
width: 56px;
height: 24px;
padding: 0 10px;
margin: 0 10px;
@ -1024,12 +1014,14 @@ export default {
color: #333;
font-size: 12px;
background-color: #fff;
border: 1px solid #eaeaea;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
&:focus{
outline: none;
}
&:disabled{
background-color: #e8e8e8;
border-color: #e8e8e8;
cursor: not-allowed;
}
}

@ -1,48 +1,39 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div>
<div class="p-title m-b-20">筛选</div>
<div>
<div class="no-mb">
<el-form label-width="80px" inline>
<el-form-item label="所属课程" class="userRadio">
<el-select v-model="cid" clearable placeholder="请选择所属课程" @change="getData">
<div class="tool">
<ul class="filter">
<li>
<label>所属课程</label>
<el-select v-model="cid" clearable placeholder="请选择所属课程" size="small" @change="getData">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in courseList" :key="index" :label="item.courses" :value="item.courses"></el-option>
</el-select>
</el-form-item>
<el-form-item label="试卷状态" class="userRadio">
<el-radio-group v-model="state" @change="getData">
<el-radio label="" border>全部</el-radio>
<el-radio v-for="(item,index) in statusList" :key="index" :label="item.id" border>{{item.name}}</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div class="flex j-between">
<el-form label-width="80px" inline>
<el-form-item label="试卷用途" class="userRadio no-mb">
<el-radio-group v-model="effect" @change="getData">
<el-radio label="" border>全部</el-radio>
<el-radio v-for="(item,index) in effectList" :key="index" :label="item.id" border>用于{{item.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="创建时间" class="userRadio no-mb">
<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>
</el-form-item>
</el-form>
<div>
<el-input placeholder="请输入试卷名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</div>
</div>
</div>
</div>
</li>
<li>
<label>试卷状态</label>
<el-select v-model="state" clearable placeholder="请选择试卷状态" size="small" @change="getData">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
<li>
<label>试卷用途</label>
<el-select v-model="effect" clearable placeholder="请选择试卷用途" size="small" @change="getData">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in effectList" :key="index" :label="item.label" :value="item.id"></el-option>
</el-select>
</li>
<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>
<li>
<label>搜索</label>
<el-input placeholder="请输入试卷名称" suffix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
</div>
</el-card>
<el-card shadow="hover">
<div class="p-title m-b-20">所有试卷</div>
<el-table :data="listData" class="table" stripe header-align="center" row-key="id" @selection-change="handleSelecteChange">
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="name" label="试卷名称" align="center"></el-table-column>
@ -62,9 +53,9 @@
{{getTypeName(scope.row.type)}}
</template>
</el-table-column>
<el-table-column prop="duration" label="时长(分钟)" align="center"></el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center"></el-table-column>
<el-table-column prop="releaseTime" label="发布时间" align="center"></el-table-column>
<el-table-column prop="duration" label="时长(分钟)" width="110" align="center"></el-table-column>
<el-table-column prop="createTime" label="创建时间" width="140" align="center"></el-table-column>
<el-table-column prop="releaseTime" label="发布时间" width="140" align="center"></el-table-column>
<el-table-column prop="name" label="试卷状态" align="center">
<template slot-scope="scope">
{{getStatusName(scope.row.state)}}
@ -81,12 +72,12 @@
<el-pagination background @current-change="handleCurrentChange" :current-page="page" layout="total, prev, pager, next" :total="total">
</el-pagination>
</div>
</el-card>
</div>
</template>
<script>
import { mapState,mapGetters,mapActions } from 'vuex'
import util from '@/libs/util'
export default {
data() {
return {
@ -197,8 +188,8 @@ export default {
let briefCount = selected.filter(n => n.name == '简答题').length
let totalScore = singleCount * row.singleChoiceScore + multipleCount * row.multipleChoiceScore + fillBlankCount * row.fillBlanksScore + judgeCount * row.judgeScore + briefCount * row.briefAnswerScore
if(totalScore < 100) return this.$message.warning('总分值未满100分,请重新设置')
if(totalScore > 100) return this.$message.warning('总分值超过100分,请重新设置')
if(totalScore < 100) return util.warningMsg('总分值未满100分,请重新设置')
if(totalScore > 100) return util.warningMsg('总分值超过100分,请重新设置')
let data = row
data.state = 1
@ -208,12 +199,16 @@ export default {
data.fillBlanksNum = fillBlankCount
data.briefAnswerNum = briefCount
this.$post(this.api.modifyState,data).then(res => {
this.$message.success('发布成功')
if(row.effect){
util.successMsg(`练习“${row.name}”已成功发布,请于练习管理列表中查看`)
}else{
util.successMsg(`考试“${row.name}”已成功发布,请于考试管理列表中查看`)
}
this.getData()
}).catch(res => {})
}).catch(err => {})
}else{
this.$message.warning('请先选择试题')
util.warningMsg('请先选择试题')
}
}).catch(err => {})
},
@ -232,7 +227,16 @@ export default {
}
</script>
<style lang="scss" scoped>
/deep/.no-mb.el-form-item{
@media(max-width: 1860px){
.tool{
margin-bottom: 0;
.filter{
flex-wrap: wrap;
li{
width: 30%;
margin-bottom: 16px;
}
}
}
}
</style>

@ -1,31 +1,37 @@
<template>
<div>
<div class="tabs m-b-20">
<breadcrumb :data="'试卷管理/' + tabs[active]" ref="breadcrumb"></breadcrumb>
<div class="page">
<div class="tabs">
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{item}}</a>
</div>
<div class="page-content">
<my-test-paper v-if="active == 'my'" v-auth="'试卷管理:我的试卷'"></my-test-paper>
<all-test-paper v-else v-auth="'试卷管理:所有试卷'"></all-test-paper>
</div>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import Setting from '@/setting'
import myTestPaper from './myTestPaper'
import allTestPaper from './allTestPaper'
import breadcrumb from '@/components/breadcrumb'
export default {
data() {
return {
active: 'my',
tabs: {
my: '我的试卷',
all: '所有试卷'
all: '本校卷库'
}
};
},
components: {
myTestPaper,
allTestPaper,
breadcrumb
},
computed: {
...mapState('auth', [
@ -38,6 +44,7 @@ export default {
methods: {
tabChange(index){
this.active = index
this.$refs.breadcrumb.update('试卷管理/' + this.tabs[this.active])
},
initTabs(){
let tab1 = this.btns.includes('试卷管理:我的试卷')

@ -78,57 +78,46 @@
</div>
</el-dialog>
<el-card shadow="hover" class="m-b-20">
<div>
<div class="p-title m-b-20">筛选</div>
<div>
<div class="no-mb">
<el-form label-width="80px" inline>
<el-form-item label="所属课程" class="userRadio">
<el-select v-model="cid" clearable placeholder="请选择所属课程" @change="getData">
<div class="tool">
<ul class="filter">
<li>
<label>所属课程</label>
<el-select v-model="cid" clearable placeholder="请选择所属课程" size="small" @change="getData">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in courseList" :key="index" :label="item.courses" :value="item.courses"></el-option>
</el-select>
</el-form-item>
<el-form-item label="试卷状态" class="userRadio">
<el-radio-group v-model="state" @change="getData">
<el-radio label="" border>全部</el-radio>
<el-radio v-for="(item,index) in statusList" :key="index" :label="item.id" border>{{item.name}}</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div class="flex j-between">
<el-form label-width="80px" inline>
<el-form-item label="试卷用途" class="userRadio no-mb">
<el-radio-group v-model="effect" @change="getData">
<el-radio label="" border>全部</el-radio>
<el-radio v-for="(item,index) in effectList" :key="index" :label="item.id" border>用于{{item.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="创建时间" class="userRadio no-mb">
<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>
</el-form-item>
</el-form>
<div>
<el-input placeholder="请输入试卷名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</div>
</div>
</div>
</div>
</div>
</el-card>
<el-card shadow="hover">
<div class="flex j-between m-b-20">
<div class="p-title">我的试卷</div>
</li>
<li>
<label>试卷状态</label>
<el-select v-model="state" clearable placeholder="请选择试卷状态" size="small" @change="getData">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
<li>
<label>试卷用途</label>
<el-select v-model="effect" clearable placeholder="请选择试卷用途" size="small" @change="getData">
<el-option label="不限" value=""></el-option>
<el-option v-for="(item,index) in effectList" :key="index" :label="item.label" :value="item.id"></el-option>
</el-select>
</li>
<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>
<li>
<label>搜索</label>
<el-input placeholder="请输入试卷名称" suffix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
<div>
<el-button type="primary" size="small" round @click="addTestPaper" v-auth="'/testPaper/list:我的试卷:创建试卷'">创建试卷</el-button>
<el-button type="primary" size="small" round @click="delAllSelection" v-auth="'/testPaper/list:我的试卷:批量删除'">批量删除</el-button>
</div>
</div>
<el-table :data="listData" class="table" stripe header-align="center" row-key="id" @selection-change="handleSelecteChange">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="name" label="试卷名称" align="center"></el-table-column>
<el-table-column prop="courses" label="所属课程" align="center"></el-table-column>
@ -147,9 +136,9 @@
{{getTypeName(scope.row.type)}}
</template>
</el-table-column>
<el-table-column prop="duration" label="时长(分钟)" align="center"></el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center"></el-table-column>
<el-table-column prop="releaseTime" label="发布时间" align="center"></el-table-column>
<el-table-column prop="duration" label="时长(分钟)" width="110" align="center"></el-table-column>
<el-table-column prop="createTime" label="创建时间" width="140" align="center"></el-table-column>
<el-table-column prop="releaseTime" label="发布时间" width="140" align="center"></el-table-column>
<el-table-column prop="name" label="试卷状态" align="center">
<template slot-scope="scope">
{{getStatusName(scope.row.state)}}
@ -170,9 +159,6 @@
<el-pagination background @current-change="handleCurrentChange" :current-page="page" layout="total, prev, pager, next" :total="total">
</el-pagination>
</div>
</el-card>
</div>
</template>
@ -180,6 +166,7 @@
import { mapState,mapGetters,mapActions } from 'vuex'
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
import util from '@/libs/util'
function getUrlBase64(url, ext, callback) {
var canvas = document.createElement("canvas"); //canvas DOM
@ -299,12 +286,12 @@ export default {
this.getData()
},
delData(row) {
this.$confirm('确定要删除吗?', '提示', {
this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', {
type: 'warning'
})
.then(() => {
this.$post(`${this.api.delByMyTestPaper}?ids=${row.id}`).then(res => {
this.$message.success('删除成功')
util.successMsg('删除成功')
this.getData()
}).catch(res => {})
}).catch(() => {})
@ -396,18 +383,18 @@ export default {
return item.id
})
this.$confirm('确定要删除吗?', '提示', {
this.$confirm(`此批量删除操作不可逆,是否确认删除${util.ellipsisStr(newArr[0].name)}${newArr.length}个选中项?`, '提示', {
type: 'warning'
})
.then(() => {
this.$post(`${this.api.delByMyTestPaper}?ids=${delList.join()}`).then(res => {
this.multipleSelection = []
this.$message.success('删除成功')
util.successMsg('删除成功')
this.getData()
}).catch(res => {})
}).catch(() => {})
}else{
this.$message.error('请先选择数据 !')
util.errorMsg('请先选择数据 !')
}
},
publish(row){
@ -429,8 +416,8 @@ export default {
let briefCount = selected.filter(n => n.name == '简答题').length
let totalScore = singleCount * row.singleChoiceScore + multipleCount * row.multipleChoiceScore + fillBlankCount * row.fillBlanksScore + judgeCount * row.judgeScore + briefCount * row.briefAnswerScore
if(totalScore < 100) return this.$message.warning('总分值未满100分,请重新设置')
if(totalScore > 100) return this.$message.warning('总分值超过100分,请重新设置')
if(totalScore < 100) return util.warningMsg('总分值未满100分,请重新设置')
if(totalScore > 100) return util.warningMsg('总分值超过100分,请重新设置')
let data = row
data.state = 1
@ -440,12 +427,16 @@ export default {
data.fillBlanksNum = fillBlankCount
data.briefAnswerNum = briefCount
this.$post(this.api.modifyState,data).then(res => {
this.$message.success('发布成功')
if(row.effect){
util.successMsg(`练习“${row.name}”已成功发布,请于练习管理列表中查看`)
}else{
util.successMsg(`考试“${row.name}”已成功发布,请于考试管理列表中查看`)
}
this.getData()
}).catch(res => {})
}).catch(err => {})
}else{
this.$message.warning('请先选择试题')
util.warningMsg('请先选择试题')
}
}).catch(err => {})
},
@ -459,7 +450,7 @@ export default {
},
copy(row){
this.$post(`${this.api.copyPaper}?id=${row.id}`).then(res => {
this.$message.success('复制成功');
util.successMsg('复制成功');
this.getData()
}).catch(res => {})
},
@ -516,4 +507,16 @@ export default {
}
}
}
@media(max-width: 1860px){
.tool{
margin-bottom: 0;
.filter{
flex-wrap: wrap;
li{
width: 30%;
margin-bottom: 16px;
}
}
}
}
</style>

@ -19,12 +19,7 @@
</el-form-item>
</el-form>
<div>
<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></el-input>
</div>
</div>
</el-card>
@ -34,15 +29,7 @@
<el-card shadow="hover" class="m-b-20">
<div class="p-title m-b-20">练习批阅</div>
<el-table
:data="listData"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
@selection-change="handleSelectionChange"
>
<el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
<el-table-column
type="selection"
width="55"
@ -82,6 +69,7 @@
</div>
</template>
<script>
import util from '@/libs/util'
export default {
data() {
return {

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

@ -16,7 +16,7 @@ const Setting = {
showProgressBar: true,
// 接口请求地址
// apiBaseURL: env === 'development' ? 'http://192.168.31.152:8001' : 'http://39.108.250.202:8000/',
apiBaseURL: env === 'development' ? 'http://39.108.250.202:9000' : 'http://39.108.250.202:9000',
apiBaseURL: env === 'development' ? 'http://192.168.31.152:8001' : 'http://39.108.250.202:9000',
// 接口请求返回错误时,弹窗的持续时间,单位:秒
modalDuration: 3,
// 接口请求返回错误时,弹窗的类型,可选值为 Message 或 Notice
@ -62,7 +62,7 @@ const Setting = {
maxSize: 30,
},
// 是否使用动态路由
dynamicRoute: true
dynamicRoute: false
};
export default Setting;

@ -5,6 +5,10 @@ export default {
namespaced: true,
state: {
id: '',
assessmentName: '',
status: '',
type: '',
startTime: '',
endTime: '',
reviewId: '',
paperId: '',
@ -72,7 +76,7 @@ export default {
name: '在考'
},{
id: 2,
name: '已'
name: '已提交'
}
],
correctingList: [
@ -108,7 +112,11 @@ export default {
mutations: {
SET_INFO: (state, info) => {
state.id = info.id
state.assessmentName = info.assessmentName
state.type = info.type
state.startTime = info.startTime
state.endTime = info.endTime
state.status = info.status
},
SET_REVIEW_INFO: (state, info) => {
state.reviewId = info.id

@ -47,10 +47,10 @@ export default {
name: '未考'
},{
id: 1,
name: '在考'
name: '练习中'
},{
id: 2,
name: '已'
name: '已提交'
}
],
correctingList: [

@ -19,7 +19,7 @@ export default {
label: '考试'
},{
id: 1,
label: '习'
label: '习'
}
],
degreeList: [

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

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

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

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

@ -0,0 +1,135 @@
.title{
margin: 0;
text-align: center;
font-size: 18px;
font-weight: 600;
}
.metas{
display: flex;
justify-content: center;
padding-bottom: 24px;
margin: 24px 0;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
.name{
font-size: 12px;
color: #717171;
}
.val{
font-size: 12px;
color: #929292;
}
}
.tab{
display: flex;
justify-content: center;
align-items: center;
li{
position: relative;
padding: 0 16px;
margin-right: 24px;
font-size: 14px;
line-height: 30px;
text-align: center;
color: rgba(0, 0, 0, 0.65);
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
cursor: pointer;
&:hover{
opacity: .8;
}
&.active{
color: #CC221C;
border: 1px solid #CC221C;
}
}
}
.wrap{
height: calc(100vh - 367px);
margin-top: 24px;
overflow: auto;
.item{
margin-bottom: 30px;
border: 1px solid rgba(0, 0, 0, 0.06);
border-radius: 8px;
.type{
padding: 0 24px;
margin-top: -1px;
color: rgba(0, 0, 0, 0.85);
line-height: 52px;
font-size: 14px;
background-color: #F6FFED;
border: 1px solid #B7EB8F;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
&.wrong{
border: 1px solid #FFA39E;
background: #FFF1F0;
}
&.yet{
border: 1px solid rgba(0, 0, 0, 0.06);
background: rgba(0, 0, 0, 0.04);
}
span{
margin-right: 24px;
}
}
.inner{
padding: 24px;
}
.name{
font-size: 14px;
color: #555555;
}
.meta{
margin-bottom: 16px;
}
.key{
margin-bottom: 8px;
color: rgba(0, 0, 0, 0.85);
font-size: 16px;
}
.val{
color: rgba(0, 0, 0, 0.65);
font-size: 14px;
}
.meta-mul{
display: flex;
margin-bottom: 15px;
.info{
margin-right: 32px;
}
input{
width: 60px;
height: 28px;
padding: 0 5px;
margin-right: 5px;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
&:focus{
outline: none;
}
&:disabled{
background-color: rgba(0, 0, 0, 0.04);
color: rgba(0, 0, 0, 0.25);
cursor: not-allowed;
}
}
}
.point{
.meta{
margin: 0;
}
}
}
}
.over{
top: 5000px;
}
.player{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
width: 1200px !important;
height: 600px !important;
}

@ -1,34 +1,43 @@
@import "../default/index.scss";
$insideColor: rgba(245, 242, 255, 0.8); //内部节点的边框颜色
$outColor: rgba(255, 255, 255, 0.8); //外部节点的边框颜色
@mixin public {
cursor: pointer;
font-size: 14px;
color: #333333;
display: flex;
align-items: center;
padding: 3px 0;
margin-bottom: 8px;
cursor: pointer;
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
line-height: 1;
border-radius: 4px;
&:hover{
background-color: rgba(0, 0, 0, 0.02);
}
img {
height: 20px;
width: 20px;
margin-left: 10px;
margin-left: 8px;
}
.checkbox,.checked{
width: 16px;
height: 16px;
background: url('../../../assets/img/checkbox.png') no-repeat;
}
.checked{
background-image: url('../../../assets/img/checked.png');
}
}
.side_view{
height: 600px;
padding: 40px 20px;
background-color: #fff;
max-height: 300px;
overflow: auto;
i{
margin-left: 5px;
font-size: 17px;
color: $--color-primary;
margin-left: 8px;
font-size: 15px;
color: #d9d9d9;
}
span{
margin-left: 5px;
margin-left: 8px;
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
}
.side_icon{
text-align: right;
@ -38,39 +47,23 @@ $outColor: rgba(255, 255, 255, 0.8); //外部节点的边框颜色
}
}
.side_tree{
width: 100%;
font-size: 14px;
color: #333;
margin-top: 16px;
.item {
@include public;
width: 100%;
padding: 15px 0;
background:rgba(255,255,255,1);
box-shadow:1px 14px 29px 0px rgba(255,69,69,0.19);
border-radius:10px;
text-align: left;
margin-top: 20px;
}
.empty{
width: 25px;
}
.item:first{
margin-top: 0;
}
.item1 {
@include public;
margin-top: 20px;
margin-left: 23px;
}
.item2 {
@include public;
margin-top: 20px;
margin-left:80px
}
.item3 {
@include public;
margin-top: 20px;
margin-left:95px
}
.item2:hover{
@ -85,12 +78,12 @@ $outColor: rgba(255, 255, 255, 0.8); //外部节点的边框颜色
.arrowTransform {
transition: 0.4s;
transform-origin: center;
transform: rotateZ(0deg);
transform: rotateZ(180deg);
}
.arrowTransformReturn {
transition: 0.4s;
transform-origin: center;
transform: rotateZ(90deg);
transform: rotateZ(0deg);
}
.checkBox {

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

Loading…
Cancel
Save