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. 216
      src/components/testPaperDetail/index.vue
  39. 28
      src/layouts/footer/index.vue
  40. 111
      src/layouts/header/index.vue
  41. 54
      src/layouts/home/index.vue
  42. 97
      src/layouts/navbar/index.vue
  43. 18
      src/libs/util.js
  44. 136
      src/pages/account/login/index.vue
  45. 151
      src/pages/achievement/list/examResults.vue
  46. 21
      src/pages/achievement/list/index.vue
  47. 172
      src/pages/achievement/list/practiceResults.vue
  48. 152
      src/pages/achievement/list/wrongBook.vue
  49. 203
      src/pages/achievement/statistics/index.vue
  50. 272
      src/pages/assessment/detail/index.vue
  51. 356
      src/pages/assessment/doReview/index.vue
  52. 374
      src/pages/assessment/list/index.vue
  53. 45
      src/pages/assessment/list/studentTree.vue
  54. 242
      src/pages/assessment/monitor/index.vue
  55. 197
      src/pages/assessment/review/index.vue
  56. 164
      src/pages/assessment/scoreQuery/index.vue
  57. 1
      src/pages/assessment/show/index.vue
  58. 404
      src/pages/index/list/index.vue
  59. 159
      src/pages/messageBoard/list/index.vue
  60. 269
      src/pages/practice/detail/index.vue
  61. 311
      src/pages/practice/doReview/index.vue
  62. 195
      src/pages/practice/list/index.vue
  63. 35
      src/pages/practice/list/studentTree.vue
  64. 109
      src/pages/practice/result/index.vue
  65. 109
      src/pages/practice/review/index.vue
  66. 189
      src/pages/practice/scoreQuery/index.vue
  67. 222
      src/pages/quesBank/list/globalQuesBank.vue
  68. 31
      src/pages/quesBank/list/index.vue
  69. 331
      src/pages/quesBank/list/myQuesBank.vue
  70. 92
      src/pages/quesBank/list/quesBankType.vue
  71. 137
      src/pages/quesBank/list/quesDialog.vue
  72. 714
      src/pages/setting/person/index.vue
  73. 332
      src/pages/student/list/index.vue
  74. 414
      src/pages/student/list/studentSide.vue
  75. 155
      src/pages/student/list/studentTree.vue
  76. 43
      src/pages/system/list/index.vue
  77. 277
      src/pages/system/list/organization.vue
  78. 94
      src/pages/system/list/role.vue
  79. 344
      src/pages/system/list/staff.vue
  80. 301
      src/pages/system/list/staffSide.vue
  81. 480
      src/pages/testPaper/add/index.vue
  82. 178
      src/pages/testPaper/list/allTestPaper.vue
  83. 19
      src/pages/testPaper/list/index.vue
  84. 207
      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. 435
      src/styles/common.scss
  93. BIN
      src/styles/font/YouSheBiaoTiHei.ttf
  94. 3
      src/styles/layout/index.scss
  95. 83
      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,53 +1,55 @@
<template> <template>
<div class="box"> <div class="box">
<h1 class="title">{{paperName}}</h1> <breadcrumb :data="'试卷管理/试卷预览'"></breadcrumb>
<div class="metas"> <div class="page">
<div style="margin-right: 20px;"> <div class="page-content">
<span class="name">总分</span> <h1 class="title">{{paperName}}</h1>
<span class="val">100</span> <div class="metas">
</div> <div class="m-r-20">
<div v-if="totalDuration !== ''"> <span class="name">总分</span>
<span class="name">考试时长</span> <span class="val">100</span>
<span class="val">{{totalDuration}}分钟</span> </div>
</div> <div v-if="totalDuration !== ''">
</div> <span class="name">考试时长</span>
<span class="val">{{totalDuration}}分钟</span>
<ul class="tab">
<template v-for="(item,index) in tabs">
<li v-if="item.show" :key="index" :class="{active: active == item.id}" @click="tabChange(item.id)">{{item.name}}</li>
</template>
</ul>
<div class="wrap">
<div class="item" v-for="(item,index) in curType" :key="index">
<div class="answer">
<div class="info">
<p class="key">序号</p>
<p class="val">{{index+1}}</p>
</div> </div>
</div> </div>
<div class="meta">
<p class="key">题干</p> <ul class="tab">
<p class="val" v-html="item.questionStem"></p> <template v-for="(item,index) in tabs">
<div class="media" :id="item.mediaEleId"></div> <li v-if="item.show" :key="index" :class="{active: active == item.id}" @click="tabChange(item.id)">{{item.name}}</li>
</div> </template>
<template v-if="active != 5"> </ul>
<div class="meta" v-if="active != 3">
<p class="key">选项</p> <div class="wrap">
<div class="val"> <div class="item" v-for="(item,index) in curType" :key="index">
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p> <div class="type">
<span>序号{{index+1}}</span>
</div> </div>
</div> <div class="inner">
<div class="meta ans"> <div class="meta">
<div class="info"> <p class="key">题干</p>
<p class="key">正确答案</p> <p class="val" v-html="item.questionStem"></p>
<p class="val">{{item.answer}}</p> <div class="media" :id="item.mediaEleId"></div>
</div>
<template v-if="active != 5">
<div class="meta" v-if="active != 3">
<p class="key">选项</p>
<div class="val">
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p>
</div>
</div>
<div class="meta">
<p class="key">正确答案</p>
<p class="val">{{item.answer}}</p>
</div>
</template>
<div class="meta">
<p class="key">答案解析</p>
<p class="val" v-html="item.answerAnalysis"></p>
</div>
</div> </div>
</div> </div>
</template>
<div class="meta">
<p class="key">答案解析</p>
<p class="val" v-html="item.answerAnalysis"></p>
</div> </div>
</div> </div>
</div> </div>
@ -56,6 +58,7 @@
<script> <script>
import mixins from '@/mixins/setBackground' import mixins from '@/mixins/setBackground'
import { mapState } from 'vuex' import { mapState } from 'vuex'
import breadcrumb from '@/components/breadcrumb'
export default { export default {
props: ['data'], props: ['data'],
mixins: [ mixins ], mixins: [ mixins ],
@ -92,6 +95,7 @@ export default {
curType: [], curType: [],
}; };
}, },
components: { breadcrumb },
computed: { computed: {
...mapState('user', [ ...mapState('user', [
'userId' 'userId'
@ -209,129 +213,5 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.box{ @import "@/styles/pages/testPaperDetail.scss";
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;
}
}
}
</style> </style>

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

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

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

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

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

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

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

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

@ -1,114 +1,70 @@
<template> <template>
<div> <div>
<el-card shadow="hover" class="m-b-20"> <div class="tool">
<div class="p-title m-b-20">筛选</div> <ul class="filter">
<div class="flex j-between"> <li>
<el-form label-width="80px" inline> <label>教学班级</label>
<el-form-item class="no-mb" label="教学班级"> <el-select v-model="classId" clearable placeholder="请选择教学班级" size="small" @change="getPrac">
<el-select v-model="classId" clearable placeholder="请选择教学班级" @change="getPrac"> <el-option v-for="(item,index) in classList" :key="index" :label="item.className" :value="item.classId"></el-option>
<el-option v-for="(item,index) in classList" :key="index" :label="item.className" :value="item.classId"></el-option> </el-select>
</el-select> </li>
</el-form-item> <li>
<el-form-item class="no-mb" label="练习名称"> <label>练习名称</label>
<el-select v-model="practiseId" clearable placeholder="请选择练习名称" @change="getData"> <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-option v-for="(item,index) in practiceNameList" :key="index" :label="item.practiseName" :value="item.practiseId"></el-option>
</el-select> </el-select>
</el-form-item> </li>
</el-form> <li>
<div> <label>搜索</label>
<el-input <el-input placeholder="请输入学生姓名或学号" suffix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
placeholder="请输入学生姓名或学号" </li>
prefix-icon="el-icon-search" </ul>
v-model="keyword" <div>
clearable <el-button type="primary" size="small" round @click="exportData" v-auth="'/achievement/list:练习成绩:导出'">导出成绩表</el-button>
></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>
<div>
<el-button
type="primary"
size="small"
round
@click="exportData"
v-auth="'/achievement/list:练习成绩:导出'"
>导出</el-button>
</div>
</div> </div>
</div>
<el-table <el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
:data="listData" <el-table-column type="index" width="100" label="序号" align="center">
ref="table" <template
row-key="id" slot-scope="scope"
class="table" >{{scope.$index + (page - 1) * pageSize + 1}}</template>
stripe </el-table-column>
header-align="center" <el-table-column prop="userName" label="姓名" align="center"></el-table-column>
@selection-change="handleSelectionChange" <el-table-column prop="workNumber" label="学号" align="center"></el-table-column>
> <el-table-column prop="max" label="最高分" align="center">
<el-table-column type="index" width="100" label="序号" align="center"> <template slot-scope="scope">
<template <p>{{scope.row.max | defaultShow}}</p>
slot-scope="scope" </template>
>{{scope.$index + (page - 1) * pageSize + 1}}</template> </el-table-column>
</el-table-column> <el-table-column prop="min" label="最低分" align="center">
<el-table-column prop="userName" label="真实姓名" align="center"></el-table-column> <template slot-scope="scope">
<el-table-column prop="workNumber" label="学号" align="center"></el-table-column> <p>{{scope.row.min | defaultShow}}</p>
<el-table-column prop="max" label="最高分" align="center"> </template>
<template slot-scope="scope"> </el-table-column>
<p>{{scope.row.max | defaultShow}}</p> <el-table-column prop="avg" label="平均分" align="center">
</template> <template slot-scope="scope">
</el-table-column> <p>{{scope.row.avg | defaultShow}}</p>
<el-table-column prop="min" label="最低分" align="center"> </template>
<template slot-scope="scope"> </el-table-column>
<p>{{scope.row.min | defaultShow}}</p> <el-table-column label="操作" align="center">
</template> <template slot-scope="scope">
</el-table-column> <el-button type="text" @click="showDetail(scope.row)" v-auth="'/achievement/list:练习成绩:查看详情'">查看练习历史</el-button>
<el-table-column prop="avg" label="平均分" align="center"> </template>
<template slot-scope="scope"> </el-table-column>
<p>{{scope.row.avg | defaultShow}}</p> </el-table>
</template> <div class="pagination">
</el-table-column> <el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
<el-table-column label="操作" align="center"> </div>
<template slot-scope="scope">
<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>
</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="flex flex-j-e">
<div class="m-b-20"> <div class="m-b-20">
<el-input <el-input placeholder="请输入练习项目名称" prefix-icon="el-icon-search" v-model="keywordAch" clearable></el-input>
placeholder="请输入练习项目名称"
prefix-icon="el-icon-search"
v-model="keywordAch"
clearable
></el-input>
</div> </div>
</div> </div>
<el-table <el-table :data="achiList" ref="table" row-key="id" class="table" stripe header-align="center">
:data="achiList"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
>
<el-table-column type="index" width="100" label="序号" align="center"> <el-table-column type="index" width="100" label="序号" align="center">
<template <template
slot-scope="scope" slot-scope="scope"
@ -127,19 +83,12 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center"> <el-table-column label="操作" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click="show(scope.row)">查看</el-button> <el-button type="text" @click="show(scope.row)">查看练习卷</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination <el-pagination background @current-change="handleAchCurrentChange" :current-page="pageAch" :page-size="pageSizeAch" layout="total,prev, pager, next" :total="totalAch"></el-pagination>
background
@current-change="handleAchCurrentChange"
:current-page="pageAch"
:page-size="pageSizeAch"
layout="total,prev, pager, next"
:total="totalAch"
></el-pagination>
</div> </div>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
@ -152,6 +101,7 @@
<script> <script>
import { mapState,mapActions } from 'vuex' import { mapState,mapActions } from 'vuex'
import Setting from '@/setting' import Setting from '@/setting'
import util from '@/libs/util'
export default { export default {
data() { data() {
return { return {
@ -254,7 +204,7 @@ export default {
this.getData() this.getData()
}, },
exportData(){ 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,93 +1,60 @@
<template> <template>
<div> <div>
<el-card shadow="hover" class="m-b-20"> <div class="tool">
<div class="p-title m-b-20">筛选</div> <ul class="filter">
<div class="flex j-between"> <li>
<el-form label-width="80px" inline> <label>错题来源</label>
<el-form-item class="no-mb" label="错题来源"> <el-select v-model="type" clearable placeholder="请选择错题来源" size="small" @change="getName">
<el-select v-model="type" clearable placeholder="请选择错题来源" @change="getName"> <el-option v-for="(item,index) in typeList" :key="index" :label="item.name" :value="item.id"></el-option>
<el-option v-for="(item,index) in typeList" :key="index" :label="item.name" :value="item.id"></el-option> </el-select>
</el-select> </li>
</el-form-item> <li v-if="type == 2">
<el-form-item class="no-mb" label="练习名称" v-if="type == 2"> <label>练习名称</label>
<el-select v-model="name" clearable placeholder="请选择练习名称" @change="getData"> <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-option v-for="(item,index) in nameList" :key="index" :label="item.practiseName" :value="item.practiseId"></el-option>
</el-select> </el-select>
</el-form-item> </li>
<el-form-item class="no-mb" label="考核名称" v-else> <li v-else>
<el-select v-model="name" clearable placeholder="请选择考核名称" @change="getData"> <label>考试名称</label>
<el-option v-for="(item,index) in nameList" :key="index" :label="item.assessmentName" :value="item.id"></el-option> <el-select v-model="name" clearable placeholder="请选择考试名称" size="small" @change="getData">
</el-select> <el-option v-for="(item,index) in nameList" :key="index" :label="item.assessmentName" :value="item.id"></el-option>
</el-form-item> </el-select>
</el-form> </li>
<div> <li>
<el-input <label>搜索</label>
placeholder="请输入题干" <el-input placeholder="请输入题干" suffix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
prefix-icon="el-icon-search" </li>
v-model="keyword" </ul>
clearable </div>
></el-input>
</div>
</div>
</el-card>
<el-card shadow="hover" class="m-b-20">
<div class="p-title m-b-20">错题收藏</div>
<el-table <el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
:data="listData" <el-table-column type="index" width="100" label="序号" align="center">
ref="table" <template
row-key="id" slot-scope="scope"
class="table" >{{scope.$index + (page - 1) * pageSize + 1}}</template>
stripe </el-table-column>
header-align="center" <el-table-column label="错题来源" align="center">
@selection-change="handleSelectionChange" <template>
> {{type == 1 ? '考试试卷' : '练习试卷'}}
<el-table-column type="index" width="100" label="序号" align="center"> </template>
<template </el-table-column>
slot-scope="scope" <el-table-column prop="paperName" label="试卷名称" align="center"></el-table-column>
>{{scope.$index + (page - 1) * pageSize + 1}}</template> <el-table-column prop="knowledgePoints" label="所需知识点" align="center"></el-table-column>
</el-table-column> <el-table-column prop="questionStem" label="题干" align="center" :show-overflow-tooltip="true"></el-table-column>
<el-table-column label="错题来源" align="center"> <el-table-column prop="wrongNum" label="错题次数" align="center"></el-table-column>
<template> <el-table-column label="操作" align="center">
{{type == 1 ? '考核试卷' : '练习试卷'}} <template slot-scope="scope">
</template> <el-button type="text" @click="show(scope.row,1)" v-auth="'/achievement/list:错题收藏:查看'">查看题目</el-button>
</el-table-column> <el-button type="text" @click="showNum(scope.row)">历史统计</el-button>
<el-table-column prop="paperName" label="试卷名称" align="center"></el-table-column> </template>
<el-table-column prop="knowledgePoints" label="所需知识点" align="center"></el-table-column> </el-table-column>
<el-table-column prop="questionStem" label="题干" align="center" :show-overflow-tooltip="true"></el-table-column> </el-table>
<el-table-column label="错题次数" align="center"> <div class="pagination">
<template slot-scope="scope"> <el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
<el-button type="primary" size="mini" @click="showNum(scope.row)">{{scope.row.wrongNum}}</el-button> </div>
</template>
</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>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
background
@current-change="handleCurrentChange"
:current-page="page"
:page-size="pageSize"
layout="total,prev, pager, next"
:total="total"
></el-pagination>
</div>
</el-card>
<el-dialog title="错题人数" :visible.sync="numVisible" width="50%"> <el-dialog title="历史统计" :visible.sync="numVisible" width="50%">
<el-table <el-table :data="numList" ref="table" row-key="id" class="table" stripe header-align="center">
:data="numList"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
>
<el-table-column type="index" width="100" label="序号" align="center"> <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>
@ -103,18 +70,11 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination <el-pagination background @current-change="handleNumCurrentChange" :current-page="pageNum" :page-size="pageSizeNum" layout="total,prev, pager, next" :total="totalNum"></el-pagination>
background
@current-change="handleNumCurrentChange"
:current-page="pageNum"
:page-size="pageSizeNum"
layout="total,prev, pager, next"
:total="totalNum"
></el-pagination>
</div> </div>
</el-dialog> </el-dialog>
<el-dialog title="题详情" :visible.sync="detailVisible" width="40%"> <el-dialog title="题目详情" :visible.sync="detailVisible" width="540px">
<div class="ques"> <div class="ques">
<div class="meta"> <div class="meta">
<p class="key">题干</p> <p class="key">题干</p>
@ -152,7 +112,7 @@ export default {
typeList: [ typeList: [
{ {
id: 1, id: 1,
name: '考试卷' name: '考试卷'
},{ },{
id: 2, id: 2,
name: '练习试卷' name: '练习试卷'

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

@ -1,102 +1,104 @@
<template> <template>
<div class="box"> <div class="box">
<h1 class="title">{{paperName }}</h1> <breadcrumb :data="'考试管理/成绩详情'"></breadcrumb>
<div class="metas"> <div class="page">
<div class="m-r-20"> <div class="page-content">
<span class="name">总分</span> <h1 class="title">{{paperName }}</h1>
<span class="val">100</span> <div class="metas">
</div> <div class="m-r-20">
<div class="m-r-20" v-if="thisScore != null"> <span class="name">总分</span>
<span class="name">得分</span> <span class="val">100</span>
<span class="val">{{thisScore}}</span>
</div>
<div class="m-r-20">
<span class="name">考试时长</span>
<span class="val">{{timeSpent != null && timeSpent != '--' ? (timeSpent / 60).toFixed(2) + '分钟' : timeSpent}}</span>
</div>
<div>
<span class="name">排名</span>
<span class="val">{{ranking === 0 ? 1 : ranking}}</span>
</div>
</div>
<ul class="tab">
<template v-for="(item,index) in tabs">
<li v-if="item.show" :key="index" :class="{active: active == item.id}" @click="tabChange(item.id)">{{item.name}}</li>
</template>
</ul>
<div class="wrap">
<div class="item" v-for="(item,index) in curType" :key="index">
<div class="answer">
<div class="info">
<p class="key">序号</p>
<p class="val">{{index+1}}</p>
</div> </div>
<div class="info"> <div class="m-r-20" v-if="thisScore != null">
<p class="key">得分</p> <span class="name">得分</span>
<p class="val">{{item.question_score}}</p> <span class="val">{{thisScore}}</span>
</div> </div>
</div> <div class="m-r-20">
<div class="meta"> <span class="name">考试时长</span>
<p class="key">题干</p> <span class="val">{{timeSpent != null && timeSpent != '--' ? (timeSpent / 60).toFixed(2) + '分钟' : timeSpent}}</span>
<p class="val" v-html="item.question_stem"></p>
</div>
<div class="meta" v-if="active != 4 && active != 5">
<p class="key">选项</p>
<div class="val">
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p>
</div>
</div>
<div class="meta ans">
<div class="info" v-if="active != 4">
<p class="key">正确答案</p>
<p class="val">{{item.answer}}</p>
</div> </div>
<div class="info"> <div>
<p class="key">学生答案</p> <span class="name">排名</span>
<p class="val">{{item.user_answer}}</p> <span class="val">{{ranking === 0 ? 1 : ranking}}</span>
</div> </div>
</div> </div>
<div class="meta" v-if="active == 4">
<p class="key">附件</p> <ul class="tab">
<div class="val"> <template v-for="(item,index) in tabs">
<template v-if="item.fileUrl"> <li v-if="item.show" :key="index" :class="{active: active == item.id}" @click="tabChange(item.id)">{{item.name}}</li>
<div v-for="(url,fileName) in item.fileUrl" :key="fileName"> </template>
<el-button type="text" @click="preview(url,0)">{{fileName}}</el-button> </ul>
<el-button type="primary" size="mini" @click="download(fileName,url,0)">下载</el-button>
<div class="wrap">
<div class="item" v-for="(item,index) in curType" :key="index">
<div class="type" :class="{wrong: item.question_score == 0,yet: item.question_score == null}">
<span>序号{{index+1}}</span>
<span>得分{{item.question_score}}</span>
</div>
<div class="inner">
<div class="meta">
<p class="key">题干</p>
<p class="val" v-html="item.question_stem"></p>
</div>
<div class="meta" v-if="active != 4 && active != 5">
<p class="key">选项</p>
<div class="val">
<p v-for="(option,i) in item.options" :key="i">{{i}}.{{item.options[i]}}</p>
</div>
</div>
<div class="meta-mul">
<div class="info" v-if="active != 4">
<p class="key">正确答案</p>
<p class="val">{{item.answer}}</p>
</div>
<div class="info">
<p class="key">学生答案</p>
<p class="val">{{item.user_answer}}</p>
</div>
</div> </div>
</template> <div class="meta" v-if="active == 4">
<template v-if="item.videoAudio"> <p class="key">附件</p>
<div v-for="(url,fileName) in item.videoAudio" :key="fileName"> <div class="val">
<el-button type="text" @click="preview(url,1)">{{fileName}}</el-button> <template v-if="item.fileUrl">
<el-button type="primary" size="mini" @click="download(fileName,url,1)">下载</el-button> <div v-for="(url,fileName) in item.fileUrl" :key="fileName">
<el-button type="text" @click="preview(url,0)">{{fileName}}</el-button>
<el-button type="primary" size="mini" @click="download(fileName,url,0)">下载</el-button>
</div>
</template>
<template v-if="item.videoAudio">
<div v-for="(url,fileName) in item.videoAudio" :key="fileName">
<el-button type="text" @click="preview(url,1)">{{fileName}}</el-button>
<el-button type="primary" size="mini" @click="download(fileName,url,1)">下载</el-button>
</div>
</template>
</div>
</div> </div>
</template> <div class="meta">
<p class="key">答案解析</p>
<p class="val" v-html="item.answer_analysis"></p>
</div>
</div>
</div> </div>
</div> </div>
<div class="meta">
<p class="key">答案解析</p> <div v-show="playAuth" class="el-image-viewer__wrapper" :class="{over: isDownload}" style="z-index: 2000">
<p class="val" v-html="item.answer_analysis"></p> <div class="el-image-viewer__mask"></div>
<span class="el-image-viewer__btn el-image-viewer__close" @click="closePlayer"><i class="el-icon-circle-close" style="color: #fff"></i></span>
<div class="player" id="player"></div>
</div> </div>
<pdf :visible.sync="pdfVisible" :src.sync="pdfSrc"></pdf>
</div> </div>
</div> </div>
<div v-show="playAuth" class="el-image-viewer__wrapper" :class="{over: isDownload}" style="z-index: 2000">
<div class="el-image-viewer__mask"></div>
<span class="el-image-viewer__btn el-image-viewer__close" @click="closePlayer"><i class="el-icon-circle-close" style="color: #fff"></i></span>
<div class="player" id="player"></div>
</div>
<pdf :visible.sync="pdfVisible" :src.sync="pdfSrc"></pdf>
</div> </div>
</template> </template>
<script> <script>
import setBackground from '@/mixins/setBackground'
import file from '@/mixins/file' import file from '@/mixins/file'
import { mapState } from 'vuex' import { mapState } from 'vuex'
import pdf from '@/components/pdf' import pdf from '@/components/pdf'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default { export default {
mixins: [ setBackground,file ], mixins: [ file ],
data() { data() {
return { return {
paperName: '', paperName: '',
@ -130,7 +132,7 @@ export default {
curType: [] curType: []
}; };
}, },
components: { pdf }, components: { pdf,breadcrumb },
computed: { computed: {
...mapState('user', [ ...mapState('user', [
'userId' 'userId'
@ -188,7 +190,10 @@ export default {
if(n.typeName == '填空题') answer.push(n[i]) if(n.typeName == '填空题') answer.push(n[i])
} }
} }
if(n.typeName == '填空题') n.answer = answer.join('|') if(n.typeName == '填空题'){
n.answer = answer.join(',')
n.user_answer = n.user_answer ? n.user_answer.split('&lt;&gt;').filter(n => n).join(',') : ''
}
n.options = options n.options = options
} }
}) })
@ -199,110 +204,5 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.box{ @import "@/styles/pages/testPaperDetail.scss";
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;
}
</style> </style>

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

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

@ -1,12 +1,12 @@
<template> <template>
<div class="side_view"> <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-if="keyword" class="side_tree">
<div v-for="(item,index) in classList" :key="index"> <div v-for="(item,index) in classList" :key="index">
<div class="item" @click.stop="open(item)"> <div class="item" @click.stop="open(item)">
<i class="empty"></i> <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> <span>{{item.label}}</span>
</div> </div>
</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 v-else class="side_tree" @click.stop="open(item)" v-for="(item,index) in data" :key="index">
<div class="item" @click.stop="open(item)"> <div class="item" @click.stop="open(item)">
<img <img
v-if="item.children&&item.children.length!=0" v-if="item.children&&item.children.length!=0" :class="{ 'arrowTransform': !item.ifVisible, 'arrowTransformReturn': item.ifVisible}" src="../../../assets/img/arrow-down.png" alt/>
:class="{ 'arrowTransform': !item.ifVisible, 'arrowTransformReturn': item.ifVisible}"
src="../../../assets/img/icon-xiangyou.png"
alt
/>
<i v-else class="empty"></i> <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> <span>{{item.label}}</span>
</div> </div>
<div v-show="item.ifVisible" v-if="item.children&&item.children.length!=0"> <div v-show="item.ifVisible" v-if="item.children&&item.children.length!=0">
<div v-for="(item1,index1) in item.children" :key="index1"> <div v-for="(item1,index1) in item.children" :key="index1">
<div class="item1" @click.stop="open(item1)"> <div class="item1" @click.stop="open(item1)">
<img <img v-if="item1.children&&item1.children.length!=0" :class="{ 'arrowTransform': !item1.ifVisible, 'arrowTransformReturn': item1.ifVisible}" src="../../../assets/img/arrow-down.png" alt/>
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 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> <span>{{item1.label}}年级</span>
</div> </div>
<div v-show="item1.ifVisible" v-if="item1.children&&item1.children.length!=0"> <div v-show="item1.ifVisible" v-if="item1.children&&item1.children.length!=0">
<div v-for="(item2,index2) in item1.children" :key="index2"> <div v-for="(item2,index2) in item1.children" :key="index2">
<div class="item2" @click.stop="open(item2)"> <div class="item2" @click.stop="open(item2)">
<img <img v-if="item2.children&&item2.children.length!=0" :class="{ 'arrowTransform': !item2.ifVisible, 'arrowTransformReturn': item2.ifVisible}" src="../../../assets/img/arrow-down.png" alt/>
v-if="item2.children&&item2.children.length!=0"
:class="{ 'arrowTransform': !item2.ifVisible, 'arrowTransformReturn': item2.ifVisible}"
src="../../../assets/img/icon-xiangyou.png"
alt
/>
<i v-else class="empty"></i> <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> <span>{{item2.label}}</span>
</div> </div>
<div v-show="item2.ifVisible" v-if="item2.children&&item2.children.length!=0"> <div v-show="item2.ifVisible" v-if="item2.children&&item2.children.length!=0">
<div v-for="(item3,index3) in item2.children" :key="index3"> <div v-for="(item3,index3) in item2.children" :key="index3">
<div class="item3" @click.stop="open(item3)"> <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> <span>{{item3.label}}</span>
</div> </div>
</div> </div>
@ -164,20 +150,9 @@ export default {
@import '../../../styles/pages/tree.scss'; @import '../../../styles/pages/tree.scss';
.side_view{ .side_view{
max-height: 300px;
height: auto;
padding: 0 20px 20px;
.side_tree{ .side_tree{
.item{
padding: 5px 0;
margin-top: 10px;
}
.item2 { .item2 {
margin-left: 43px margin-left: 46px
}
.item1,.item2,.item3{
padding: 0;
margin-top: 0;
} }
} }
} }

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

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

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

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

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

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

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

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

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

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

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

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

@ -1,121 +1,76 @@
<template> <template>
<div> <div>
<el-card shadow="hover" class="m-b-20"> <breadcrumb :data="'练习管理/成绩列表'"></breadcrumb>
<div class="p-title m-b-20">筛选</div> <div class="page">
<div class="tabs">
<div class="flex j-between"> <a class="item active">成绩列表</a>
<el-form label-width="80px" inline>
<el-form-item class="no-mb" label="教学班级">
<el-select v-model="classId" clearable placeholder="请选择教学班级" @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> </div>
</el-card> <div class="page-content">
<div class="tool">
<el-card shadow="hover" class="m-b-20"> <ul class="filter">
<div class="flex j-between m-b-20"> <li>
<div class="p-title">练习成绩</div> <label>教学班级</label>
<el-select v-model="classId" clearable placeholder="请选择教学班级" size="small" @change="getData">
<div> <el-option v-for="(item,index) in classList" :key="index" :label="item.className" :value="item.classId"></el-option>
<el-button </el-select>
type="primary" </li>
size="small" <li>
round <label>搜索</label>
@click="exportData" <el-input placeholder="请输入学生姓名或学号" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
>导出</el-button> </li>
</ul>
<div>
<el-button type="primary" size="small" round @click="exportData">导出</el-button>
</div>
</div> </div>
</div>
<el-table <el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
:data="listData" <el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
ref="table" <el-table-column type="index" width="100" label="序号" align="center">
row-key="id" <template
class="table" slot-scope="scope"
stripe >{{scope.$index + (page - 1) * pageSize + 1}}</template>
header-align="center" </el-table-column>
@selection-change="handleSelectionChange" <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 <el-table-column prop="max" label="最高分" align="center">
type="selection" <template slot-scope="scope">
width="55" <p>{{scope.row.max | defaultShow}}</p>
align="center" </template>
:reserve-selection="true" </el-table-column>
></el-table-column> <el-table-column prop="min" label="最低分" align="center">
<el-table-column type="index" width="100" label="序号" align="center"> <template slot-scope="scope">
<template <p>{{scope.row.min | defaultShow}}</p>
slot-scope="scope" </template>
>{{scope.$index + (page - 1) * pageSize + 1}}</template> </el-table-column>
</el-table-column> <el-table-column prop="avg" label="平均分" align="center">
<el-table-column prop="userName" label="真实姓名" align="center"></el-table-column> <template slot-scope="scope">
<el-table-column prop="workNumber" label="学号" align="center"></el-table-column> <p>{{scope.row.avg | defaultShow}}</p>
<el-table-column prop="max" label="最高分" align="center"> </template>
<template slot-scope="scope"> </el-table-column>
<p>{{scope.row.max | defaultShow}}</p> <el-table-column label="操作" align="center">
</template> <template slot-scope="scope">
</el-table-column> <el-button type="text" @click="showDetail(scope.row)">查看详情</el-button>
<el-table-column prop="min" label="最低分" align="center"> </template>
<template slot-scope="scope"> </el-table-column>
<p>{{scope.row.min | defaultShow}}</p> </el-table>
</template> <div class="pagination">
</el-table-column> <el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
<el-table-column prop="avg" label="平均分" align="center"> </div>
<template slot-scope="scope">
<p>{{scope.row.avg | defaultShow}}</p>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="text" @click="showDetail(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>
</div> </div>
</el-card> </div>
<el-dialog title="练习成绩详情" :visible.sync="detailVisible" width="40%" :close-on-click-modal="false"> <el-dialog title="练习成绩详情" :visible.sync="detailVisible" width="800px" :close-on-click-modal="false">
<div class="flex flex-j-e"> <div class="tool">
<div class="m-b-20"> <ul class="filter">
<el-input <li>
placeholder="请输入练习项目名称" <label>搜索</label>
prefix-icon="el-icon-search" <el-input placeholder="请输入练习项目名称" prefix-icon="el-icon-search" v-model="keywordAch" clearable size="small"></el-input>
v-model="keywordAch" </li>
clearable </ul>
></el-input>
</div>
</div> </div>
<el-table <el-table :data="achiList" ref="table" row-key="id" class="table" stripe header-align="center">
:data="achiList"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
>
<el-table-column type="index" width="100" label="序号" align="center"> <el-table-column type="index" width="100" label="序号" align="center">
<template <template
slot-scope="scope" slot-scope="scope"
@ -135,14 +90,7 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination <el-pagination background @current-change="handleAchCurrentChange" :current-page="pageAch" :page-size="pageSizeAch" layout="total,prev, pager, next" :total="totalAch"></el-pagination>
background
@current-change="handleAchCurrentChange"
:current-page="pageAch"
:page-size="pageSizeAch"
layout="total,prev, pager, next"
:total="totalAch"
></el-pagination>
</div> </div>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
@ -155,6 +103,8 @@
<script> <script>
import { mapState,mapActions } from 'vuex' import { mapState,mapActions } from 'vuex'
import Setting from '@/setting' import Setting from '@/setting'
import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default { export default {
data() { data() {
return { return {
@ -177,6 +127,9 @@ export default {
totalAch: 0, totalAch: 0,
}; };
}, },
components: {
breadcrumb
},
computed: { computed: {
...mapState('user', [ ...mapState('user', [
'userId' 'userId'
@ -262,7 +215,7 @@ export default {
this.getData() this.getData()
}, },
exportData(){ 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,64 +1,84 @@
<template> <template>
<div> <div>
<el-card shadow="hover" class="m-b-20"> <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>
</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>
</li>
<li>
<label>搜索</label>
<el-input placeholder="请输入题干/知识点" suffix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</li>
</ul>
<div> <div>
<div class="p-title m-b-20">筛选</div> <el-button type="primary" size="small" round @click="delAllData" v-auth="'/quesBank/list:校企公共题库:批量取消共享'">批量取消共享</el-button>
<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">
<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">
<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>
<div>
<el-input placeholder="请输入题干/知识点" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</div>
</div>
</div> </div>
</el-card> </div>
<el-card shadow="hover"> <el-table :data="listData" class="table" stripe header-align="center" row-key="id" @selection-change="handleSelectionChange">
<div class="flex j-between m-b-20"> <el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
<div class="p-title">公共题库</div> <el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<div> <el-table-column prop="questionStem" :show-overflow-tooltip="true" label="题干" align="center"></el-table-column>
<el-button type="primary" size="small" round @click="delAllData" v-auth="'/quesBank/list:公共题库:批量取消共享'">批量取消共享</el-button> <el-table-column prop="name" label="试题类型" width="100" align="center"></el-table-column>
</div> <el-table-column prop="courses" label="对应课程" width="140" align="center"></el-table-column>
</div> <el-table-column prop="typeName" label="所属题库" width="140" align="center"></el-table-column>
<el-table :data="listData" class="table" stripe header-align="center" row-key="id" @selection-change="handleSelectionChange"> <el-table-column prop="knowledgePoints" label="知识点" width="140" align="center"></el-table-column>
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> <el-table-column prop="useNum" label="使用次数" width="100" align="center"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column> <el-table-column prop="createTime" label="共享时间" width="140" align="center"></el-table-column>
<el-table-column prop="questionStem" :show-overflow-tooltip="true" label="题干" align="center"></el-table-column> <el-table-column prop="createUser" label="创建人" width="100" align="center"></el-table-column>
<el-table-column prop="name" label="试题类型" width="100" align="center"></el-table-column> <el-table-column label="操作" align="center" width="120">
<el-table-column prop="courses" label="对应课程" width="140" align="center"></el-table-column> <template slot-scope="scope">
<el-table-column prop="typeName" label="所属题库" width="140" align="center"></el-table-column> <el-button type="text" @click="show(scope.row)" v-auth="'/quesBank/list:校企公共题库:查看'">查看</el-button>
<el-table-column prop="knowledgePoints" label="知识点" width="140" align="center"></el-table-column> <el-button v-if="scope.row.createUser != '系统内置'" type="text" @click="delData(scope.row)" v-auth="'/quesBank/list:校企公共题库:取消共享'">取消共享</el-button>
<el-table-column prop="useNum" label="使用次数" width="100" align="center"></el-table-column> </template>
<el-table-column prop="createTime" label="共享时间" width="140" align="center"></el-table-column> </el-table-column>
<el-table-column prop="createUser" label="创建人" width="100" align="center"></el-table-column> </el-table>
<el-table-column label="操作" align="center" width="120"> <div class="pagination">
<template slot-scope="scope"> <el-pagination background @current-change="handleCurrentChange" :current-page="page" layout="total, prev, pager, next" :total="total">
<el-button type="text" @click="show(scope.row)" v-auth="'/quesBank/list:公共题库:查看'">查看</el-button> </el-pagination>
<el-button v-if="scope.row.createUser != '系统内置'" type="text" @click="delData(scope.row)" v-auth="'/quesBank/list:公共题库:取消共享'">取消共享</el-button> </div>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<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> </div>
</template> </template>
@ -88,7 +108,9 @@ export default {
searchTimer: null, searchTimer: null,
isDetail: false, isDetail: false,
visible: false, visible: false,
topicsTitle: '' topicsTitle: '',
quesBankList: [],
topicForm: {}
}; };
}, },
computed: { computed: {
@ -100,6 +122,7 @@ export default {
mounted() { mounted() {
this.getData() this.getData()
this.getType() this.getType()
this.getQuesBank()
}, },
watch: { watch: {
keyword: function(val) { keyword: function(val) {
@ -126,11 +149,9 @@ export default {
.catch(err => {}) .catch(err => {})
}, },
getType() { getType() {
this.$get(this.api.typesList) this.$get(this.api.typesList).then(res => {
.then(res => {
this.typeList = res.data.list this.typeList = res.data.list
}) }).catch(err => {})
.catch(err => {})
}, },
handleCurrentChange(val) { handleCurrentChange(val) {
this.page = val; this.page = val;
@ -140,12 +161,12 @@ export default {
this.multipleSelection = val; this.multipleSelection = val;
}, },
delData(row) { delData(row) {
this.$confirm('确定要取消共享吗?', '提示', { this.$confirm('确定要取消共享该选中的题目吗?', '提示', {
type: 'warning' type: 'warning'
}) })
.then(() => { .then(() => {
this.$post(`${this.api.deleteByMeSubjectBySharing}?identification=2&ids=${row.id}`).then(res => { this.$post(`${this.api.deleteByMeSubjectBySharing}?identification=2&ids=${row.id}`).then(res => {
this.$message.success('取消共享成功') util.successMsg('取消共享成功')
this.getData() this.getData()
}).catch(res => {}); }).catch(res => {});
}) })
@ -158,19 +179,19 @@ export default {
return item.id return item.id
}) })
this.$confirm('确定要取消共享吗?', '提示', { this.$confirm(`是否确认取消共享${util.ellipsisStr(newArr[0].questionStem)}${newArr.length}个选中的题目?`, '提示', {
type: 'warning' type: 'warning'
}) })
.then(() => { .then(() => {
this.$post(`${this.api.deleteByMeSubjectBySharing}?identification=2&ids=${delList.join()}`).then(res => { this.$post(`${this.api.deleteByMeSubjectBySharing}?identification=2&ids=${delList.join()}`).then(res => {
this.multipleSelection = []; this.multipleSelection = [];
this.$message.success('取消共享成功') util.successMsg('取消共享成功')
this.getData() this.getData()
}).catch(res => {}); }).catch(res => {})
}) })
.catch(() => {}); .catch(() => {});
}else{ }else{
this.$message.error('请先选择数据!'); util.errorMsg('请先选择数据!')
} }
}, },
dialogGetData(){ dialogGetData(){
@ -182,8 +203,56 @@ export default {
this.visible = true this.visible = true
this.isDetail = false 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) { 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) { edit(row) {
this.topicsTitle = '编辑题目' this.topicsTitle = '编辑题目'
@ -204,7 +273,22 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
/deep/.no-mb.el-form-item{ .list{
margin-bottom: 0; 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> </style>

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

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

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

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

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

@ -1,65 +1,63 @@
<template> <template>
<div> <div>
<el-container> <breadcrumb :data="'学生管理/学生列表'"></breadcrumb>
<el-aside width="350px"> <div class="page">
<StudentSide ref="getSelectData" @fircheck="fircheck" @twocheck="twocheck" @threecheck="threecheck" @getData="getData"></StudentSide> <div class="tabs">
</el-aside> <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 @click="batchImport" v-auth>批量导入</el-button>
<el-button type="primary" size="small" round @click="delAllSelection" v-auth>批量删除</el-button>
</div>
</div>
<!-- <StudentSide ref="getSelectData" @fircheck="fircheck" @twocheck="twocheck" @threecheck="threecheck" @getData="getData"></StudentSide> -->
<el-main style="padding-top: 0"> <el-table :data="listData" class="table" ref="table" stripe header-align="center" @selection-change="handleSelectionChange">
<el-col :span="24"> <el-table-column type="selection" width="80" align="center"></el-table-column>
<el-card shadow="hover" class="m-b-20 student_tab"> <el-table-column type="index" label="序号" width="55" align="center">
<div class="flex j-between m-b-20"> </el-table-column>
<div> <el-table-column prop="studentName" label="学生姓名" align="center">
<el-input placeholder="请输入学生名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input> </el-table-column>
</div> <el-table-column prop="workNumber" label="学生学号" align="center">
<div> </el-table-column>
<el-button type="primary" size="small" round @click="addstudent" v-auth>新增学生</el-button> <el-table-column prop="stuProfessionalArchitectureName" label="专业" align="center">
<el-button type="primary" size="small" round class="mag" @click="batchImport" v-auth>批量导入</el-button> </el-table-column>
<el-button type="primary" size="small" round @click="delAllSelection" v-auth>批量删除</el-button> <el-table-column prop="gradeName" label="年级" align="center">
</div> </el-table-column>
</div> <el-table-column prop="className" label="班级" align="center">
<el-table :data="listData" class="table" stripe header-align="center" @selection-change="handleSelectionChange"> </el-table-column>
<el-table-column type="selection" width="55" align="center"></el-table-column> <el-table-column prop="loginNumber" label="登录次数" align="center">
<el-table-column type="index" label="序号" width="55" align="center"> </el-table-column>
</el-table-column> <el-table-column prop="lastLoginTime" label="上次登录时间" width="150" align="center">
<el-table-column prop="studentName" label="学生姓名" align="center"> </el-table-column>
</el-table-column> <el-table-column label="操作" width="180" align="center">
<el-table-column prop="workNumber" label="学生学号" align="center"> <template slot-scope="scope">
</el-table-column> <el-button type="text" @click="editstudent(scope.row)" v-auth>编辑</el-button>
<el-table-column prop="stuProfessionalArchitectureName" label="专业" align="center"> <el-button type="text" @click="resetPassword(scope.row)" v-auth>重置密码</el-button>
</el-table-column> <el-button type="text" @click="delstudent(scope.row)" v-auth>删除</el-button>
<el-table-column prop="gradeName" label="年级" align="center"> </template>
</el-table-column> </el-table-column>
<el-table-column prop="className" label="班级" align="center"> </el-table>
</el-table-column> <div class="pagination">
<el-table-column prop="roleId" label="账号角色" align="center"> <el-pagination background layout="total,prev, pager, next" :current-page="page" @current-change="handleCurrentChange" :total="total"></el-pagination>
<template slot-scope="scope"> </div>
学生 </div>
</template> </div>
</el-table-column>
<el-table-column prop="loginNumber" label="登录次数" align="center">
</el-table-column>
<el-table-column prop="lastLoginTime" label="上次登录时间" width="150" align="center">
</el-table-column>
<el-table-column label="操作" width="180" align="center">
<template slot-scope="scope">
<el-button type="text" @click="editstudent(scope.row)" v-auth>编辑</el-button>
<el-button type="text" @click="resetPassword(scope.row)" v-auth>重置密码</el-button>
<el-button type="text" @click="delstudent(scope.row)" v-auth>删除</el-button>
</template>
</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>
</div>
</el-card>
</el-col>
</el-main>
</el-container>
<el-dialog :title="isAdd ? '新增学生' : '编辑学生'" :visible.sync="studentVisible" <el-dialog :title="isAdd ? '新增学生' : '编辑学生'" :visible.sync="studentVisible" width="30%" @close="closestudent" class="dialog" :close-on-click-modal="false">
width="30%" center @close="closestudent" class="dialog" :close-on-click-modal="false">
<el-form ref="studentForm" :model="studentForm" :rules="rules" label-width="90px"> <el-form ref="studentForm" :model="studentForm" :rules="rules" label-width="90px">
<el-form-item prop="account" label="账号"> <el-form-item prop="account" label="账号">
<el-input v-model="studentForm.account" placeholder="请输入学生账号" @change="accountChange"></el-input> <el-input v-model="studentForm.account" placeholder="请输入学生账号" @change="accountChange"></el-input>
@ -67,9 +65,6 @@
<el-form-item prop="userName" label="学生姓名"> <el-form-item prop="userName" label="学生姓名">
<el-input v-model="studentForm.userName" placeholder="请输入学生姓名"></el-input> <el-input v-model="studentForm.userName" placeholder="请输入学生姓名"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="账号角色">
学生
</el-form-item>
<el-form-item prop="uniqueIdentificationAccount" label="唯一标识"> <el-form-item prop="uniqueIdentificationAccount" label="唯一标识">
<el-input disabled v-model="studentForm.uniqueIdentificationAccount" placeholder="请输入学生学号获取唯一标识"></el-input> <el-input disabled v-model="studentForm.uniqueIdentificationAccount" placeholder="请输入学生学号获取唯一标识"></el-input>
</el-form-item> </el-form-item>
@ -78,7 +73,7 @@
</el-form-item> </el-form-item>
<el-form-item prop="professionalId" label="专业"> <el-form-item prop="professionalId" label="专业">
<el-select v-model="studentForm.professionalId" placeholder="请选择专业" @change="getGrade"> <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> :label="item.stuProfessionalArchitectureName" :value="item.stuProfessionalArchitectureId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -107,41 +102,34 @@
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="批量导入" :visible.sync="importVisible" width="24%" center :close-on-click-modal="false"> <el-dialog title="批量导入" :visible.sync="importVisible" width="400px" :close-on-click-modal="false">
<div style="text-align: center"> <div class="upload-wrap" :class="{lg: uploadFaild}">
<div style="margin-bottom: 10px;"><el-button type="primary" @click="downLoad">模板下载<i class="el-icon-download el-icon--right"></i></el-button></div> <el-button class="download" size="small" @click="downLoad"><img src="../../../assets/img/download.png" alt=""> 模板下载</el-button>
<el-upload <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">
accept=".xls,.xlsx" <el-button size="small"><img src="../../../assets/img/upload.png" alt=""> 上传文件</el-button>
: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-upload> </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> </div>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button @click="importVisible = false">取消</el-button> <el-button size="small" @click="importVisible = false"> </el-button>
<el-button type="primary" @click="uploadSure">确定</el-button> <el-button size="small" type="primary" @click="uploadSure"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script> <script>
import StudentSide from './studentSide'
import { mapState,mapGetters } from 'vuex' import { mapState,mapGetters } from 'vuex'
import util from '@/libs/util' import util from '@/libs/util'
import Setting from '@/setting' import Setting from '@/setting'
import breadcrumb from '@/components/breadcrumb'
export default { export default {
data() { data() {
return { return {
props: { multiple: true },
orgList: [],
twoDepartmentIds: '',
studentVisible: false, studentVisible: false,
studentForm: { studentForm: {
clientId: this.clientId, clientId: this.clientId,
@ -209,7 +197,6 @@ export default {
pageSize: 10, pageSize: 10,
total: 0, total: 0,
searchTimer: null, searchTimer: null,
majorList: [],
gradeList: [], gradeList: [],
classList: [], classList: [],
professionalIds: '', professionalIds: '',
@ -235,12 +222,7 @@ export default {
]) ])
}, },
components: { components: {
StudentSide breadcrumb
},
mounted(){
this.studentForm.clientId = this.clientId
this.studentForm.clientName = this.clientName
this.getData()
}, },
watch: { watch: {
keyword: function(val) { keyword: function(val) {
@ -250,7 +232,51 @@ export default {
},500) },500)
} }
}, },
mounted(){
this.getOrg()
this.studentForm.clientId = this.clientId
this.studentForm.clientName = this.clientName
this.getData()
},
methods: { 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(){ getData(){
let data = { let data = {
searchContent: this.keyword, searchContent: this.keyword,
@ -264,82 +290,10 @@ export default {
this.total = res.data.total this.total = res.data.total
}).catch(res => {}) }).catch(res => {})
}, },
handleCheck(data){ orgChange(node){
let professionalStudentIds = [] this.classIds = node.map(n => n[2]).toString()
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()
this.getData() 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(){ closestudent(){
this.$refs.studentForm.resetFields() this.$refs.studentForm.resetFields()
}, },
@ -347,14 +301,12 @@ export default {
this.studentForm.studentId = '' this.studentForm.studentId = ''
this.studentVisible = true this.studentVisible = true
this.isAdd = true this.isAdd = true
this.majorList = this.$refs.getSelectData.majorList
}, },
editstudent(row){ editstudent(row){
this.studentVisible = true this.studentVisible = true
this.isAdd = false this.isAdd = false
this.studentForm.studentId = row.studentId this.studentForm.studentId = row.studentId
this.studentForm.userId = row.userId this.studentForm.userId = row.userId
this.majorList = this.$refs.getSelectData.majorList
this.$get(`${this.api.getStudent}/${row.studentId}`).then(res => { this.$get(`${this.api.getStudent}/${row.studentId}`).then(res => {
let student = res.data.student let student = res.data.student
let userInfo = res.data.userInfo let userInfo = res.data.userInfo
@ -381,9 +333,9 @@ export default {
} }
this.$post(this.api.userinfoUpdate,data).then(res => { this.$post(this.api.userinfoUpdate,data).then(res => {
if(res.success){ if(res.success){
this.$message.success('重置成功') util.successMsg('重置成功')
}else{ }else{
this.$message.error('重置失败') util.errorMsg('重置失败')
} }
}).catch(res => {}) }).catch(res => {})
}).catch(() => {}) }).catch(() => {})
@ -420,7 +372,7 @@ export default {
this.$get(`${this.api.getAccount}?account=${this.studentForm.account}`).then(res => { this.$get(`${this.api.getAccount}?account=${this.studentForm.account}`).then(res => {
if(res.data.userInfo){ if(res.data.userInfo){
this.accountRepeat = true this.accountRepeat = true
this.$message.warning('该账号已存在') util.warningMsg('该账号已存在')
}else{ }else{
this.accountRepeat = false this.accountRepeat = false
} }
@ -434,7 +386,7 @@ export default {
this.$get(`${this.api.studentGetWorkNumber}?workNumber=${this.studentForm.workNumber}`).then(res => { this.$get(`${this.api.studentGetWorkNumber}?workNumber=${this.studentForm.workNumber}`).then(res => {
if(res.data.student){ if(res.data.student){
this.workNumberRepeat = true this.workNumberRepeat = true
this.$message.warning('该学号已存在') util.warningMsg('该学号已存在')
}else{ }else{
this.workNumberRepeat = false this.workNumberRepeat = false
} }
@ -446,8 +398,8 @@ export default {
saveSure(studentForm){ saveSure(studentForm){
this.$refs[studentForm].validate((valid) => { this.$refs[studentForm].validate((valid) => {
if (valid) { if (valid) {
if(this.accountRepeat) return this.$message.warning('该账号已存在') if(this.accountRepeat) return util.warningMsg('该账号已存在')
if(this.workNumberRepeat) return this.$message.warning('该学号已存在') if(this.workNumberRepeat) return util.warningMsg('该学号已存在')
let data = { let data = {
userInfo: { userInfo: {
isPort: 2, isPort: 2,
@ -477,13 +429,13 @@ export default {
if(this.studentForm.studentId){ if(this.studentForm.studentId){
this.$post(this.api.updateStudent,data).then(res => { this.$post(this.api.updateStudent,data).then(res => {
this.studentVisible = false this.studentVisible = false
this.$message.success('编辑成功') util.successMsg('编辑成功')
this.getData() this.getData()
}).catch(res => {}); }).catch(res => {});
}else{ }else{
this.$post(this.api.addStudent,data).then(res => { this.$post(this.api.addStudent,data).then(res => {
this.studentVisible = false this.studentVisible = false
this.$message.success('添加成功') util.successMsg('添加成功')
this.getData() this.getData()
}).catch(res => {}); }).catch(res => {});
} }
@ -493,7 +445,7 @@ export default {
}) })
}, },
delstudent(row){ delstudent(row){
this.$confirm('确定要删除吗?', '提示', { this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', {
type: 'warning' type: 'warning'
}) })
.then(() => { .then(() => {
@ -501,7 +453,7 @@ export default {
studentIds: row.studentId studentIds: row.studentId
} }
this.$del(this.api.deleteStudents,data).then(res => { this.$del(this.api.deleteStudents,data).then(res => {
this.$message.success('删除成功') util.successMsg('删除成功')
this.getData() this.getData()
}).catch(res => {}); }).catch(res => {});
}) })
@ -517,7 +469,7 @@ export default {
return item.studentId return item.studentId
}) })
// //
this.$confirm('确定要删除吗?', '提示', { this.$confirm(`此批量删除操作不可逆,是否确认删除${util.ellipsisStr(newArr[0].studentName)}${newArr.length}个选中项?`, '提示', {
type: 'warning' type: 'warning'
}) })
.then(() => { .then(() => {
@ -526,12 +478,12 @@ export default {
} }
this.$del(this.api.deleteStudents,data).then(res => { this.$del(this.api.deleteStudents,data).then(res => {
this.multipleSelection = [] this.multipleSelection = []
this.$message.success('删除成功') util.successMsg('删除成功')
this.getData() this.getData()
}).catch(res => {}); }).catch(res => {});
}).catch(() => {}); }).catch(() => {});
}else{ }else{
this.$message.error('请先选择学生') util.errorMsg('请先选择学生')
} }
}, },
batchImport(){ batchImport(){
@ -550,7 +502,7 @@ export default {
}, },
// //
handleExceed(files, fileList) { handleExceed(files, fileList) {
this.$message.warning( util.warningMsg(
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!` `当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
); );
}, },
@ -564,10 +516,10 @@ export default {
this.token = res.data.data.token this.token = res.data.data.token
this.uploadFaild = true this.uploadFaild = true
}else{ }else{
this.$message.success('上传成功') util.successMsg('上传成功')
} }
}else{ }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) { uploadError(err, file, fileList) {
@ -595,5 +547,19 @@ export default {
}; };
</script> </script>
<style lang="scss" scoped> <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> </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> <template>
<div> <div>
<div class="tabs m-b-20" v-if="showTabs"> <breadcrumb :data="'系统分管设置/' + tabs[active]" ref="breadcrumb"></breadcrumb>
<a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == activeName}" @click="tabChange(index)">{{item}}</a> <div class="page">
</div> <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 class="score-table" v-if="activeName == 'staff'" v-auth="'系统设置:员工管理'"> </div>
<staff></staff> <div class="page-content">
</div> <staff v-if="active == 'staff'" v-auth="'系统分管设置:员工管理'"></staff>
<div class="score-table" v-else v-auth="'系统设置:角色权限'"> <role v-else-if="active == 'role'" v-auth="'系统分管设置:角色权限'"></role>
<role></role> <organization v-else v-auth="'系统分管设置:架构管理'"></organization>
</div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import Setting from '@/setting'; import Setting from '@/setting'
import staff from './staff.vue'; import staff from './staff.vue'
import role from './role.vue'; import role from './role.vue'
import organization from './organization.vue'
import breadcrumb from '@/components/breadcrumb'
export default { export default {
data() { data() {
return { return {
activeName: 'staff', active: 'staff',
tabs: { tabs: {
staff: '员工管理', staff: '员工管理',
role: '角色权限' role: '角色权限',
organization: '架构管理'
}, },
showTabs: true showTabs: true
}; };
}, },
components: { components: {
staff, staff,
role role,
organization,
breadcrumb
}, },
computed: { computed: {
...mapState('auth', [ ...mapState('auth', [
@ -43,11 +49,12 @@ export default {
}, },
methods: { methods: {
tabChange(index){ tabChange(index){
this.activeName = index this.active = index
this.$refs.breadcrumb.update('系统分管设置/' + this.tabs[this.active])
}, },
initTabs(){ initTabs(){
let showStaff = this.btns.includes('系统设置:员工管理') let showStaff = this.btns.includes('系统分管设置:员工管理')
let showRole = this.btns.includes('系统设置:角色权限') let showRole = this.btns.includes('系统分管设置:角色权限')
if(!showStaff || !showRole){ if(!showStaff || !showRole){
this.showTabs = false 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,50 +1,43 @@
<template> <template>
<div> <div>
<el-card shadow="hover" class="m-b-20"> <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> <div>
<div class="p-title m-b-20">筛选</div> <el-button type="primary" size="small" round @click="addRole" v-auth="'/system/list:角色权限:新增角色'">新增角色</el-button>
<div class="flex"> <el-button type="primary" size="small" round @click="delAllSelection" v-auth="'/system/list:角色权限:批量删除'">批量删除</el-button>
<div>
<el-input placeholder="请输入角色名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</div>
</div>
</div> </div>
</el-card> </div>
<el-card shadow="hover"> <el-table :data="roleData" class="table" stripe header-align="center" @selection-change="handleSelectionChange" :row-key="getRowKeys">
<div class="flex j-between m-b-20"> <el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
<div class="p-title">角色列表</div> <el-table-column type="index" width="100" label="序号" align="center">
<div> </el-table-column>
<el-button type="primary" size="small" round @click="addRole" v-auth="'/system/list:角色权限:新增角色'">新增角色</el-button> <el-table-column prop="roleName" label="角色名称" align="center" width="100">
<el-button type="primary" size="small" round @click="delAllSelection" v-auth="'/system/list:角色权限:批量删除'">批量删除</el-button> </el-table-column>
</div> <el-table-column label="角色描述" align="center">
</div> <template slot-scope="scope">
<el-table :data="roleData" class="table" stripe header-align="center" @selection-change="handleSelectionChange" :row-key="getRowKeys"> <el-input disabled placeholder="该角色用于管理全部功能权限" v-model="scope.row.remark "></el-input>
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> </template>
<el-table-column type="index" width="100" label="序号" align="center"> </el-table-column>
</el-table-column> <el-table-column label="操作" width="180">
<el-table-column prop="roleName" label="角色名称" align="center" width="100"> <template slot-scope="scope">
</el-table-column> <el-button type="text" @click="showRole(scope.row)" v-auth="'/system/list:角色权限:查看'">查看</el-button>
<el-table-column label="角色描述" align="center"> <!-- <template v-if="scope.row.id != 1"> -->
<template slot-scope="scope"> <el-button type="text" @click="editRole(scope.row)" v-auth="'/system/list:角色权限:编辑'">编辑</el-button>
<el-input disabled placeholder="该角色用于管理全部功能权限" v-model="scope.row.remark "></el-input> <el-button type="text" @click="handleDelete(scope.row)" v-auth="'/system/list:角色权限:删除'">删除</el-button>
</template> <!-- </template> -->
</el-table-column> </template>
<el-table-column label="操作" width="180"> </el-table-column>
<template slot-scope="scope"> </el-table>
<el-button type="text" @click="showRole(scope.row)" v-auth="'/system/list:角色权限:查看'">查看</el-button> <div class="pagination">
<template v-if="scope.row.id != 1"> <el-pagination background @current-change="currentChange" :current-page="pageNo" layout="total, prev, pager, next" :total="totals">
<el-button type="text" @click="editRole(scope.row)" v-auth="'/system/list:角色权限:编辑'">编辑</el-button> </el-pagination>
<el-button type="text" @click="handleDelete(scope.row)" v-auth="'/system/list:角色权限:删除'">删除</el-button> </div>
</template>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<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" <el-dialog :title="isDetail ? '查看角色' : (isAdd ? '新增角色' : '编辑角色')" :visible.sync="roleVisible"
width="30%" center @close="closeRole" class="dialog" :close-on-click-modal="false"> width="30%" center @close="closeRole" class="dialog" :close-on-click-modal="false">
@ -79,6 +72,7 @@
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import util from '@/libs/util'
export default { export default {
name: 'role', name: 'role',
data() { data() {
@ -200,9 +194,9 @@ export default {
this.roleVisible = true this.roleVisible = true
}, },
async saveData() { async saveData() {
if(!this.form.roleName) return this.$message.warning('请填写角色名称') if(!this.form.roleName) return util.warningMsg('请填写角色名称')
if(!this.form.remark) return this.$message.warning('请填写角色描述') if(!this.form.remark) return util.warningMsg('请填写角色描述')
// if(!this.$refs.per.getCheckedKeys().length) return this.$message.warning('') // if(!this.$refs.per.getCheckedKeys().length) return util.warningMsg('')
let roleData = { let roleData = {
clientId: this.clientId, clientId: this.clientId,
id: this.form.id, id: this.form.id,
@ -221,7 +215,7 @@ export default {
} }
let perRes = await this.$post(this.api.doAssign,perData) let perRes = await this.$post(this.api.doAssign,perData)
if(perRes.success){ if(perRes.success){
this.$message.success('新增成功') util.successMsg('新增成功')
this.getData() this.getData()
this.roleVisible = false this.roleVisible = false
} }
@ -234,7 +228,7 @@ export default {
.then(() => { .then(() => {
this.$del(`${this.api.removeRole}?roleIds=${row.id}`).then(res => { this.$del(`${this.api.removeRole}?roleIds=${row.id}`).then(res => {
if(res.success){ if(res.success){
this.$message.success('删除成功'); util.successMsg('删除成功');
this.getData() this.getData()
} }
}).catch(res => {}) }).catch(res => {})
@ -254,19 +248,19 @@ export default {
return item.id return item.id
}) })
// //
this.$confirm('确定要删除选中角色吗?', '提示', { this.$confirm(`此批量删除操作不可逆,是否确认删除${util.ellipsisStr(newArr[0].roleName)}${newArr.length}个选中项?`, '提示', {
type: 'warning' type: 'warning'
}) })
.then(() => { .then(() => {
this.$del(`${this.api.removeRole}?roleIds=${delList.join()}`).then(res => { this.$del(`${this.api.removeRole}?roleIds=${delList.join()}`).then(res => {
if(res.success){ if(res.success){
this.$message.success('删除成功'); util.successMsg('删除成功');
this.getData() this.getData()
} }
}).catch(res => {}) }).catch(res => {})
}).catch(() => {}); }).catch(() => {});
}else{ }else{
this.$message.error('请先选择数据 !'); util.errorMsg('请先选择数据 !');
} }
} }
} }

@ -1,67 +1,61 @@
<template> <template>
<div> <div>
<el-container> <div class="tool">
<el-aside width="350px"> <ul class="filter">
<TeacherSide ref="getSelectData" @fircheck="fircheck" @twocheck="twocheck" @getData="getData"></TeacherSide> <li>
</el-aside> <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-main style="padding-top: 0"> <el-table :data="listData" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
<el-col :span="24"> <el-table-column type="selection" width="80" align="center"></el-table-column>
<el-card shadow="hover" class="m-b-20 teacher_tab"> <el-table-column type="index" label="序号" width="55" align="center">
<div class="flex j-between m-b-20"> </el-table-column>
<div> <el-table-column prop="userName" label="职工姓名" align="center">
<el-input style="width: 250px" placeholder="请输入员工姓名/工号/角色名称" v-model="keyword" prefix-icon="el-icon-search" clearable></el-input> </el-table-column>
</div> <el-table-column prop="account" label="账号" align="center">
<div> </el-table-column>
<el-button type="primary" size="small" round @click="addTeacher" v-auth="'/system/list:员工管理:新增员工'">新增员工</el-button> <el-table-column prop="workNumber" label="职工工号" align="center">
<el-button type="primary" size="small" round @click="batchImport" v-auth="'/system/list:员工管理:批量导入'">批量导入</el-button> </el-table-column>
<el-button type="primary" size="small" round @click="delAllSelection" v-auth="'/system/list:员工管理:批量删除'">批量删除</el-button> <el-table-column prop="staffProfessionalArchitectureName" label="一级部门" align="center">
</div> </el-table-column>
</div> <el-table-column prop="staffGradeName" label="二级部门" align="center">
<el-table :data="listData" class="table" stripe header-align="center" @selection-change="handleSelectionChange"> </el-table-column>
<el-table-column type="selection" width="55" align="center"></el-table-column> <el-table-column prop="roleName" label="账号角色" align="center">
<el-table-column type="index" label="序号" width="55" align="center"> </el-table-column>
</el-table-column> <el-table-column prop="loginNumber" label="登录次数" align="center">
<el-table-column prop="userName" label="职工姓名" align="center"> <template slot-scope="scope">
</el-table-column> {{scope.row.loginNumber ? scope.row.loginNumber : 0}}
<el-table-column prop="account" label="账号" align="center"> </template>
</el-table-column> </el-table-column>
<el-table-column prop="workNumber" label="职工工号" align="center"> <el-table-column prop="lastLoginTime" label="上次登录时间" width="160" align="center">
</el-table-column> </el-table-column>
<el-table-column prop="staffProfessionalArchitectureName" label="一级部门" align="center"> <el-table-column label="操作" align="center" width="200">
</el-table-column> <template slot-scope="scope">
<el-table-column prop="staffGradeName" label="二级部门" align="center"> <el-button type="text" @click="showTeacher(scope.row)" v-auth="'/system/list:员工管理:查看'">查看</el-button>
</el-table-column> <el-button type="text" @click="editTeacher(scope.row)" v-auth="'/system/list:员工管理:编辑'">编辑</el-button>
<el-table-column prop="roleName" label="账号角色" align="center"> <el-button type="text" @click="resetPassword(scope.row)" v-auth="'/system/list:员工管理:重置密码'">重置密码</el-button>
</el-table-column> <el-button type="text" @click="delTeacher(scope.row)" v-auth="'/system/list:员工管理:删除'">删除</el-button>
<el-table-column prop="loginNumber" label="登录次数" align="center"> </template>
<template slot-scope="scope"> </el-table-column>
{{scope.row.loginNumber ? scope.row.loginNumber : 0}} </el-table>
</template> <div class="pagination">
</el-table-column> <el-pagination background layout="total,prev, pager, next" :current-page="pageNo" @current-change="handleCurrentChange" :total="total">
<el-table-column prop="lastLoginTime" label="上次登录时间" width="160" align="center"> </el-pagination>
</el-table-column> </div>
<el-table-column label="操作" align="center" width="200">
<template slot-scope="scope">
<el-button type="text" @click="showTeacher(scope.row)" v-auth="'/system/list:员工管理:查看'">查看</el-button>
<el-button type="text" @click="editTeacher(scope.row)" v-auth="'/system/list:员工管理:编辑'">编辑</el-button>
<el-button type="text" @click="resetPassword(scope.row)" v-auth="'/system/list:员工管理:重置密码'">重置密码</el-button>
<el-button type="text" @click="delTeacher(scope.row)" v-auth="'/system/list:员工管理:删除'">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<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="500px" @close="closeTeacher" class="dialog" :close-on-click-modal="false">
<el-dialog :title="isDetail ? '查看员工' : (isAddteacher ? '新增员工' : '编辑员工')" :visible.sync="teacherVisible"
width="30%" :center="!isIE" @close="closeTeacher" class="dialog" :close-on-click-modal="false">
<el-form ref="teacherForm" :model="teacherForm" :rules="rules" label-width="100px" :disabled="isDetail"> <el-form ref="teacherForm" :model="teacherForm" :rules="rules" label-width="100px" :disabled="isDetail">
<el-form-item prop="userAccount" label="账号"> <el-form-item prop="userAccount" label="账号">
<el-input v-model="teacherForm.userAccount" ref="account" placeholder="请输入职工账号" @change="accountChange"></el-input> <el-input v-model="teacherForm.userAccount" ref="account" placeholder="请输入职工账号" @change="accountChange"></el-input>
@ -82,7 +76,7 @@
</el-form-item> </el-form-item>
<el-form-item prop="major" label="一级部门"> <el-form-item prop="major" label="一级部门">
<el-select v-model="teacherForm.major" placeholder="请选择一级部门" @change="getDepartment"> <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> :label="item.staffProfessionalArchitectureName" :value="item.staffProfessionalArchitectureId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@ -108,45 +102,82 @@
</span> </span>
</el-dialog> </el-dialog>
<!-- 批量导入 --> <el-dialog title="查看员工" :visible.sync="staffShowVisible" width="500px" :close-on-click-modal="false">
<el-dialog title="批量导入" :visible.sync="importVisible" width="24%" center :close-on-click-modal="false"> <ul class="list">
<div style="text-align: center"> <li>
<div style="margin-bottom: 10px;"><el-button type="primary" @click="downLoad">模板下载<i class="el-icon-download el-icon--right"></i></el-button></div> <span class="name"><i class="required">*</i>账号</span>
<el-upload <span class="val">{{teacherForm.userAccount}}</span>
accept=".xls,.xlsx" </li>
:on-remove="handleRemove" <li>
:on-error="uploadError" <span class="name"><i class="required">*</i>用户姓名</span>
:on-success="uploadSuccess" <span class="val">{{teacherForm.userName}}</span>
:before-remove="beforeRemove" </li>
:limit="1" <li>
:data="{schoolId: this.clientId}" <span class="name">账号角色</span>
:on-exceed="handleExceed" <span class="val">{{teacherForm.roleValue ? roleList.find(n => n.id == teacherForm.roleValue).roleName : ''}}</span>
:action="this.api.uploadFileStaff" </li>
:file-list="uploadList" <li>
name="file" <span class="name">唯一标识</span>
> <span class="val">{{teacherForm.uniqueIdentificationAccount}}</span>
<el-button type="primary" class="ml20">上传文件<i class="el-icon-upload2 el-icon--right"></i></el-button> </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-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> </div>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button @click="importVisible = false"> </el-button> <el-button size="small" @click="importVisible = false"> </el-button>
<el-button type="primary" @click="uploadSure"> </el-button> <el-button size="small" type="primary" @click="uploadSure"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script> <script>
import TeacherSide from './staffSide.vue';
import Setting from '@/setting'; import Setting from '@/setting';
import { mapState } from 'vuex'; import { mapState } from 'vuex';
import util from '@/libs/util' import util from '@/libs/util'
export default { export default {
data() { data() {
return { return {
pages: 10,
isDetail: false, isDetail: false,
props: { multiple: true },
orgList: [],
isAddteacher: false, isAddteacher: false,
teacherVisible: false, teacherVisible: false,
staffShowVisible: false,
roleList: [], roleList: [],
teacherForm: { teacherForm: {
teacherId: '', teacherId: '',
@ -215,7 +246,6 @@ export default {
// { required: true, message: '', trigger: 'change' } // { required: true, message: '', trigger: 'change' }
// ], // ],
}, },
majorList: [],
listData: [], listData: [],
importVisible: false, importVisible: false,
keyword: '', keyword: '',
@ -258,9 +288,6 @@ export default {
'isIE' 'isIE'
]) ])
}, },
components: {
TeacherSide
},
watch: { watch: {
keyword: function(val) { keyword: function(val) {
clearTimeout(this.searchTimer) clearTimeout(this.searchTimer)
@ -270,41 +297,40 @@ export default {
} }
}, },
mounted(){ mounted(){
this.getOrg()
this.teacherForm.clientId = this.clientId this.teacherForm.clientId = this.clientId
this.teacherForm.clientName = this.clientName this.teacherForm.clientName = this.clientName
this.getData() this.getData()
this.getRoles() this.getRoles()
}, },
methods: { methods: {
handleCheck(data){ getOrg(){
let oneDepartmentIds = [] let data = {
let twoDepartmentIds = [] schoolId: this.clientId
}
data.forEach( e => { this.$get(this.api.queryStaffPro,data).then(res => {
if(e.ischeck){ let firList = res.data.StaffProfessionalArchitectureList
oneDepartmentIds.push(e.staffProfessionalArchitectureId) if(firList){
}else{ firList.map(e => {
util.removeByValue(oneDepartmentIds, e.staffProfessionalArchitectureId); 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 => {})
})
setTimeout(() => {
this.orgList = firList
},500)
} }
e.children.forEach( r => { }).catch(res => {})
if(r.ischeck){
twoDepartmentIds.push(r.staffGradeId)
}else{
util.removeByValue(twoDepartmentIds, r.staffGradeId);
}
})
})
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)
}, },
getData(){ getData(){
let totalPage = Math.ceil((this.total - 1) / this.pageSize) let totalPage = Math.ceil((this.total - 1) / this.pageSize)
@ -331,6 +357,10 @@ export default {
this.pageNo = 1 this.pageNo = 1
this.getData() this.getData()
}, },
orgChange(node){
this.twoDepartmentIds = node.map(n => n[1]).toString()
this.getData()
},
getRoles(){ getRoles(){
let data = { let data = {
clientId: this.clientId clientId: this.clientId
@ -348,9 +378,9 @@ export default {
} }
this.$post(this.api.userinfoUpdate,data).then(res => { this.$post(this.api.userinfoUpdate,data).then(res => {
if(res.success){ if(res.success){
this.$message.success('重置成功') util.successMsg('重置成功')
}else{ }else{
this.$message.error('重置失败') util.errorMsg('重置失败')
} }
}).catch(res => {}); }).catch(res => {});
}).catch(() => { }).catch(() => {
@ -361,7 +391,7 @@ export default {
this.$get(`${this.api.getAccount}?account=${this.teacherForm.userAccount}`).then(res => { this.$get(`${this.api.getAccount}?account=${this.teacherForm.userAccount}`).then(res => {
if(res.data.userInfo){ if(res.data.userInfo){
this.accountRepeat = true this.accountRepeat = true
this.$message.warning('该账号已存在') util.warningMsg('该账号已存在')
}else{ }else{
this.accountRepeat = false this.accountRepeat = false
} }
@ -375,7 +405,7 @@ export default {
this.$get(`${this.api.getWorkNumber}?workNumber=${this.teacherForm.workNumber}`).then(res => { this.$get(`${this.api.getWorkNumber}?workNumber=${this.teacherForm.workNumber}`).then(res => {
if(res.data.staff){ if(res.data.staff){
this.workNumberRepeat = true this.workNumberRepeat = true
this.$message.warning('该工号已存在') util.warningMsg('该工号已存在')
}else{ }else{
this.workNumberRepeat = false this.workNumberRepeat = false
} }
@ -399,7 +429,6 @@ export default {
this.teacherVisible = true this.teacherVisible = true
this.isAddteacher = true this.isAddteacher = true
this.teacherForm.teacherId = '' this.teacherForm.teacherId = ''
this.majorList = this.$refs.getSelectData.majorList
}, },
getStaffDetail(userId){ getStaffDetail(userId){
this.$get(`${this.api.getStaff}/${userId}`).then(res => { this.$get(`${this.api.getStaff}/${userId}`).then(res => {
@ -432,16 +461,14 @@ export default {
this.isAddteacher = false this.isAddteacher = false
this.AccountNoAdd = false this.AccountNoAdd = false
this.teacherForm.teacherId = row.staffId this.teacherForm.teacherId = row.staffId
this.majorList = this.$refs.getSelectData.majorList
this.getStaffDetail(row.staffId) this.getStaffDetail(row.staffId)
}, },
showTeacher(row){ showTeacher(row){
this.staffShowVisible = true
this.isDetail = true this.isDetail = true
this.teacherVisible = true this.isAddManage = false
this.isAddteacher = false
this.AccountNoAdd = false this.AccountNoAdd = false
this.teacherForm.teacherId = row.staffId this.teacherForm.manageId = row.staffId
this.majorList = this.$refs.getSelectData.majorList
this.getStaffDetail(row.staffId) this.getStaffDetail(row.staffId)
}, },
getDepartment(){ getDepartment(){
@ -455,8 +482,8 @@ export default {
async saveSure(teacherForm){ async saveSure(teacherForm){
this.$refs[teacherForm].validate((valid) => { this.$refs[teacherForm].validate((valid) => {
if (valid) { if (valid) {
if(this.accountRepeat) return this.$message.warning('该账号已存在') if(this.accountRepeat) return util.warningMsg('该账号已存在')
if(this.workNumberRepeat) return this.$message.warning('该工号已存在') if(this.workNumberRepeat) return util.warningMsg('该工号已存在')
let isTeacher = false let isTeacher = false
let isManager = false let isManager = false
let data = { let data = {
@ -474,9 +501,9 @@ export default {
} }
} }
let oneDepartmentName = ''; let oneDepartmentName = '';
for(let i in this.majorList){ for(let i in this.orgList){
if(this.majorList[i].staffProfessionalArchitectureId == this.teacherForm.major) { if(this.orgList[i].staffProfessionalArchitectureId == this.teacherForm.major) {
oneDepartmentName = this.majorList[i].staffProfessionalArchitectureName oneDepartmentName = this.orgList[i].staffProfessionalArchitectureName
break; break;
} }
} }
@ -498,13 +525,13 @@ export default {
if(this.teacherForm.teacherId){ if(this.teacherForm.teacherId){
this.$post(this.api.updateStaff,data).then(res => { this.$post(this.api.updateStaff,data).then(res => {
this.teacherVisible = false this.teacherVisible = false
this.$message.success('编辑成功'); util.successMsg('编辑成功');
this.getData() this.getData()
}).catch(res => {}); }).catch(res => {});
}else{ }else{
this.$post(this.api.addStaff,data).then(res => { this.$post(this.api.addStaff,data).then(res => {
this.teacherVisible = false this.teacherVisible = false
this.$message.success('添加成功'); util.successMsg('添加成功');
this.getData() this.getData()
}).catch(res => {}); }).catch(res => {});
} }
@ -514,7 +541,7 @@ export default {
}) })
}, },
delTeacher(row){ delTeacher(row){
this.$confirm('确定要删除吗?', '提示', { this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', {
type: 'warning' type: 'warning'
}) })
.then(() => { .then(() => {
@ -522,7 +549,7 @@ export default {
staffIds: row.staffId staffIds: row.staffId
} }
this.$del(this.api.deleteStaffs,data).then(res => { this.$del(this.api.deleteStaffs,data).then(res => {
this.$message.success('删除成功') util.successMsg('删除成功')
this.getData() this.getData()
}).catch(res => {}); }).catch(res => {});
}) })
@ -538,7 +565,7 @@ export default {
return item.staffId return item.staffId
}) })
// //
this.$confirm('确定要删除吗?', '提示', { this.$confirm(`此批量删除操作不可逆,是否确认删除${util.ellipsisStr(newArr[0].userName)}${newArr.length}个选中项?`, '提示', {
type: 'warning' type: 'warning'
}) })
.then(() => { .then(() => {
@ -547,12 +574,12 @@ export default {
} }
this.$del(this.api.deleteStaffs,data).then(res => { this.$del(this.api.deleteStaffs,data).then(res => {
this.multipleSelection = []; this.multipleSelection = [];
this.$message.success('删除成功') util.successMsg('删除成功')
this.getData() this.getData()
}).catch(res => {}); }).catch(res => {});
}).catch(() => {}); }).catch(() => {});
}else{ }else{
this.$message.error('请先选择数据 !') util.errorMsg('请先选择数据 !')
} }
}, },
batchImport(){ batchImport(){
@ -576,7 +603,7 @@ export default {
}, },
// //
handleExceed(files, fileList) { handleExceed(files, fileList) {
this.$message.warning( util.warningMsg(
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!` `当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
); );
}, },
@ -587,10 +614,10 @@ export default {
this.token = res.data.data.token this.token = res.data.data.token
this.uploadFaild = true this.uploadFaild = true
}else{ }else{
this.$message.success('上传成功') util.successMsg('上传成功')
} }
}else{ }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) { uploadError(err, file, fileList) {
@ -617,11 +644,38 @@ export default {
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.el-container{ /deep/.dialog{
background-color: #f0f0f0; .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%;
}
} }
.mag{ .list{
margin-right: 20px; li{
margin-left: 20px; 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%;
}
}
} }
</style> </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,169 +1,160 @@
<template> <template>
<div class="box"> <div>
<div class="form"> <breadcrumb :data="'试卷管理/创建试卷'"></breadcrumb>
<div class="line"> <div class="page">
<div class="item"> <div class="page-content">
<p class="key">试卷名称</p> <div class="form">
<el-input v-model="name"></el-input>
</div>
</div>
<div class="line">
<div class="item">
<p class="key">试卷用途</p>
<el-select v-model="effect" placeholder="请选择试卷用途">
<el-option v-for="(item,index) in effectList" :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="courses"></el-input>
</div>
</div>
<div class="line">
<div class="item">
<p class="key">难易程度</p>
<el-select v-model="degree" placeholder="请选择难易程度">
<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>
</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>
</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>
</div>
</div>
</div>
</div>
<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="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>
<el-table-column prop="name" label="试题类型" width="100" align="center"></el-table-column>
<el-table-column prop="courses" label="对应课程" width="120" align="center"></el-table-column>
<el-table-column prop="knowledgePoints" label="知识点" width="120" 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="150" align="center"></el-table-column>
<el-table-column prop="createUser" label="创建人" width="80" align="center"></el-table-column>
</el-table>
<div class="point">
<p class="key">设置分值</p>
<div class="inputs">
<div class="line"> <div class="line">
<div class="item"> <div class="item">
<p class="label">单选题</p> <p class="key">试卷名称</p>
<input type="text" disabled v-model.number="singleCount"> <el-input v-model="name" size="small"></el-input>
<input type="text" :disabled="singleDisabled" v-model.number="singleChoiceScore" v-disabled="'单项选择'"> /
</div> </div>
</div>
<div class="line">
<div class="item"> <div class="item">
<p class="label">多选题</p> <p class="key">试卷用途</p>
<input type="text" disabled v-model.number="multipleCount" v-disabled="'多项选择'"> <el-select v-model="effect" placeholder="请选择试卷用途" size="small">
<input type="text" :disabled="multipleDisabled" v-model.number="multipleChoiceScore" v-disabled="'多项选择'"> / <el-option v-for="(item,index) in effectList" :key="index" :label="item.label" :value="item.id"></el-option>
</el-select>
</div> </div>
<div class="item"> <div class="item lg">
<p class="label">填空题</p> <p class="key">所属课程</p>
<input type="text" disabled v-model.number="fillBlankCount" v-disabled="'填空题'"> <el-input v-model="courses"></el-input>
<input type="text" :disabled="fillBlankDisabled" v-model.number="fillBlanksScore" v-disabled="'填空题'"> /
</div> </div>
</div> </div>
<div class="line"> <div class="line">
<div class="item"> <div class="item">
<p class="label">判断题</p> <p class="key">难易程度</p>
<input type="text" disabled v-model.number="judgeCount" v-disabled="'判断题'"> <el-select v-model="degree" placeholder="请选择难易程度" size="small">
<input type="text" :disabled="judgeDisabled" v-model.number="judgeScore" v-disabled="'判断题'"> / <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" size="small"></el-input>
</div> </div>
</div>
<div class="line">
<div class="item"> <div class="item">
<p class="label">简答题</p> <p class="key">组卷方式</p>
<input type="text" disabled v-model.number="briefCount" v-disabled="'简答题'"> <div>
<input type="text" :disabled="briefDisabled" v-model.number="briefAnswerScore" v-disabled="'简答题'"> / <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>
<div class="line">
<div class="item"> <div class="item">
<p class="label">总分</p> <p class="key">组卷操作</p>
<input type="text" disabled v-model.number="totalScore"> <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>
</div>
<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="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>
<el-table-column prop="name" label="试题类型" width="100" align="center"></el-table-column>
<el-table-column prop="courses" label="对应课程" width="120" align="center"></el-table-column>
<el-table-column prop="knowledgePoints" label="知识点" width="120" 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="150" align="center"></el-table-column>
<el-table-column prop="createUser" label="创建人" width="80" align="center"></el-table-column>
</el-table>
<div class="point">
<p class="key">设置分值</p>
<div class="inputs">
<div class="line">
<div class="item">
<p class="label">单选题</p>
<input type="text" disabled v-model.number="singleCount">
<input type="text" :disabled="singleDisabled" v-model.number="singleChoiceScore" v-disabled="'单项选择'"> /
</div>
<div class="item">
<p class="label">多选题</p>
<input type="text" disabled v-model.number="multipleCount" v-disabled="'多项选择'">
<input type="text" :disabled="multipleDisabled" v-model.number="multipleChoiceScore" v-disabled="'多项选择'"> /
</div>
<div class="item">
<p class="label">填空题</p>
<input type="text" disabled v-model.number="fillBlankCount" v-disabled="'填空题'">
<input type="text" :disabled="fillBlankDisabled" v-model.number="fillBlanksScore" v-disabled="'填空题'"> /
</div>
</div>
<div class="line">
<div class="item">
<p class="label">判断题</p>
<input type="text" disabled v-model.number="judgeCount" v-disabled="'判断题'">
<input type="text" :disabled="judgeDisabled" v-model.number="judgeScore" v-disabled="'判断题'"> /
</div>
<div class="item">
<p class="label">简答题</p>
<input type="text" disabled v-model.number="briefCount" v-disabled="'简答题'">
<input type="text" :disabled="briefDisabled" v-model.number="briefAnswerScore" v-disabled="'简答题'"> /
</div>
<div class="item">
<p class="label">总分</p>
<input type="text" disabled v-model.number="totalScore">
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
<div class="btns"> <div class="btns">
<button type="button" v-throttle @click="save(0)" v-if="!state">保存</button> <button type="button" v-throttle @click="save(0)" v-if="!state">保存</button>
<button type="button" v-throttle class="submit" @click="save(1)">完成并发布</button> <button type="button" v-throttle class="submit" @click="save(1)">完成并发布</button>
</div>
</div>
</div> </div>
<el-dialog title="选择试题" :visible.sync="manualVisible" width="60%" @close="closeManual" :close-on-click-modal="false"> <el-dialog title="选择试题" :visible.sync="manualVisible" width="60%" @close="closeManual" :close-on-click-modal="false">
<div class="mini-form"> <div class="tool">
<el-form label-width="80px" inline size="mini"> <ul class="filter">
<el-form-item class="no-mb" label="课程名称"> <li>
<el-select v-model="selectManual.courses" clearable placeholder="请选择课程名称" @change="getManualData"> <label>课程名称</label>
<el-select v-model="selectManual.courses" clearable placeholder="请选择课程名称" size="small" @change="getManualData">
<el-option label="不限" value=""></el-option> <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-option v-for="(item,index) in courseList" :key="index" :label="item.courses" :value="item.courses"></el-option>
</el-select> </el-select>
</el-form-item> </li>
<el-form-item class="no-mb" label="知识点"> <li>
<el-select v-model="selectManual.knowledgePoints" clearable placeholder="请选择知识点" @change="getManualData"> <label>知识点</label>
<el-select v-model="selectManual.knowledgePoints" clearable placeholder="请选择知识点" size="small" @change="getManualData">
<el-option label="不限" value=""></el-option> <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-option v-for="(item,index) in pointList" :key="index" :label="item.knowledgePoint" :value="item.knowledgePoint"></el-option>
</el-select> </el-select>
</el-form-item> </li>
</el-form> <li>
<div class="flex j-between" style="align-items: flex-start"> <label>试题类型</label>
<el-form label-width="80px" inline size="mini"> <el-select v-model="selectManual.name" clearable placeholder="请选择试题类型" size="small" @change="getManualData">
<el-form-item class="no-mb" label="试题类型"> <el-option label="不限" value=""></el-option>
<el-select v-model="selectManual.name" clearable placeholder="请选择试题类型" @change="getManualData"> <el-option v-for="(item,index) in nameList" :key="index" :label="item.name" :value="item.name"></el-option>
<el-option label="不限" value=""></el-option> </el-select>
<el-option v-for="(item,index) in nameList" :key="index" :label="item.name" :value="item.name"></el-option> </li>
</el-select> <li>
</el-form-item> <label>所属题库</label>
<el-form-item class="no-mb" label="所属题库"> <el-select v-model="selectManual.typeName" clearable placeholder="请选择所属题库" size="small" @change="getManualData">
<el-select v-model="selectManual.typeName" clearable placeholder="请选择所属题库" @change="getManualData"> <el-option label="不限" value=""></el-option>
<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-option v-for="(item,index) in quesBankList" :key="index" :label="item.typeName" :value="item.typeName"></el-option> </el-select>
</el-select> </li>
</el-form-item> <li>
</el-form> <label>搜索</label>
<div> <el-input placeholder="请输入题干名称" prefix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
<el-input </li>
size="mini" </ul>
placeholder="请输入题干名称"
prefix-icon="el-icon-search"
v-model="keyword"
clearable
></el-input>
</div>
</div>
</div> </div>
<el-table <el-table :data="listData" max-height="400" ref="listTable" row-key="id" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
:data="listData" <el-table-column type="selection" width="80" align="center" :reserve-selection="true" :selectable="disabledSelection"></el-table-column>
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-column type="index" width="60" label="序号" align="center"> <el-table-column type="index" width="60" label="序号" align="center">
<template <template
slot-scope="scope" slot-scope="scope"
@ -195,22 +186,28 @@
</span> </span>
</el-dialog> </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="select-wrap">
<div class="block" style="margin-bottom: 30px;"> <div class="block" style="margin-bottom: 30px;">
<!-- <p class="key">试题课程</p> --> <p class="key">筛选</p>
<div class="m-r-10" style="width: 100px"> <div style="display: inline-flex;align-items: flex-start;">
<el-select v-model="inteType" placeholder="请选择" size="mini"> <el-select class="m-r-20" v-model="inteType" placeholder="请选择" size="mini">
<el-option label="试题课程" value="1"></el-option> <el-option label="试题课程" value="1"></el-option>
<el-option label="知识点" value="2"></el-option> <el-option label="知识点" value="2"></el-option>
</el-select> </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> </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-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-else v-model="kn" :data="knListData" :props="knProps" filterable filter-placeholder="请输入知识点名称" :titles="['未选', '已选']" @change="knChange"></el-transfer> -->
</div> </div>
<div class="block"> <div class="block">
<p class="key">题型配置</p> <p class="key">配置题型</p>
<div class="types"> <div class="types">
<div class="item"> <div class="item">
<el-checkbox v-model="countCheck.countCheck1">单选题</el-checkbox> <el-checkbox v-model="countCheck.countCheck1">单选题</el-checkbox>
@ -248,12 +245,11 @@
</div> </div>
</template> </template>
<script> <script>
import mixins from '@/mixins/setBackground'
import { mapState,mapActions } from 'vuex' import { mapState,mapActions } from 'vuex'
import testPaper from '@/components/testPaperDetail' import testPaper from '@/components/testPaperDetail'
import util from '@/libs/util' import util from '@/libs/util'
import breadcrumb from '@/components/breadcrumb'
export default { export default {
mixins: [ mixins ],
data() { data() {
return { return {
id: this.$route.query.id, id: this.$route.query.id,
@ -340,7 +336,7 @@ export default {
selectedData: [] selectedData: []
}; };
}, },
components: {testPaper}, components: {testPaper,breadcrumb},
directives: { directives: {
disabled: function(el,binding,vnode){ disabled: function(el,binding,vnode){
let that = vnode.context let that = vnode.context
@ -433,18 +429,18 @@ export default {
return val === '' ? 0 : val return val === '' ? 0 : val
}, },
save(status) { save(status) {
if(!this.name) return this.$message.warning('请填写试卷名称') if(!this.name) return util.warningMsg('请填写试卷名称')
let qid = this.selectedData.map(n => n.id).join() let qid = this.selectedData.map(n => n.id).join()
if(status == 1){ if(status == 1){
if(this.effect === '') return this.$message.warning('请选择试卷用途') if(this.effect === '') return util.warningMsg('请选择试卷用途')
if(this.courses === '') return this.$message.warning('请填写所属课程') if(this.courses === '') return util.warningMsg('请填写所属课程')
if(this.degree === '') return this.$message.warning('请选择难易程度') if(this.degree === '') return util.warningMsg('请选择难易程度')
if(this.duration === '') return this.$message.warning('请填写建议时长') if(this.duration === '') return util.warningMsg('请填写建议时长')
} }
if(qid === '') return this.$message.warning('请选择试题') if(qid === '') return util.warningMsg('请选择试题')
if(status == 1){ if(status == 1){
if(this.totalScore < 100) return this.$message.warning('总分值未满100分,请重新设置') if(this.totalScore < 100) return util.warningMsg('总分值未满100分,请重新设置')
if(this.totalScore > 100) return this.$message.warning('总分值超过100分,请重新设置') if(this.totalScore > 100) return util.warningMsg('总分值超过100分,请重新设置')
} }
let data = { let data = {
@ -472,13 +468,13 @@ export default {
} }
if(this.id){ if(this.id){
this.$post(this.api.saveOrUpdatetestPaper, data).then(res => { this.$post(this.api.saveOrUpdatetestPaper, data).then(res => {
this.$message.success('修改成功') util.successMsg('修改成功')
this.$router.back() this.$router.back()
}) })
.catch(err => {}) .catch(err => {})
}else{ }else{
this.$post(this.api.saveOrUpdatetestPaper, data).then(res => { this.$post(this.api.saveOrUpdatetestPaper, data).then(res => {
this.$message.success('创建成功') util.successMsg('创建成功')
this.$router.back() this.$router.back()
}) })
.catch(err => {}) .catch(err => {})
@ -523,12 +519,11 @@ export default {
this.multipleSelected = val this.multipleSelected = val
}, },
removeQues(){ removeQues(){
if(!this.selectedData.length) return this.$message.error('请先添加试题') if(!this.selectedData.length) return util.errorMsg('请先添加试题')
if(this.multipleSelected.length){ if(this.multipleSelected.length){
this.$confirm('确定要移除吗?', '提示', { this.$confirm('确定要移除吗?', '提示', {
type: 'warning' type: 'warning'
}) }).then(() => {
.then(() => {
let newData = [] let newData = []
this.selectedData.forEach((n,i) => { this.selectedData.forEach((n,i) => {
this.multipleSelected.every(e => e.id != n.id) && newData.push(n) this.multipleSelected.every(e => e.id != n.id) && newData.push(n)
@ -536,15 +531,14 @@ export default {
this.selectedData = newData this.selectedData = newData
this.computeTypeCount() this.computeTypeCount()
this.$refs.selectedTable.clearSelection() this.$refs.selectedTable.clearSelection()
this.$message.success('移除成功') util.successMsg('移除成功')
}) }).catch(() => {})
.catch(() => {})
}else{ }else{
this.$message.error('请先选择数据') util.errorMsg('请先选择数据')
} }
}, },
preview(){ 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(',')}`) this.$post(`${this.api.previewPaper}?qid=${this.selectedData.map(n => n.id).join(',')}`)
.then(res => { .then(res => {
this.setInfo({ this.setInfo({
@ -572,8 +566,7 @@ export default {
this.$post(`${this.api.getSelectInfo}?type=2`) this.$post(`${this.api.getSelectInfo}?type=2`)
.then(res => { .then(res => {
this.courseList = res.data.pointList this.courseList = res.data.pointList
}) }).catch(err => {})
.catch(err => {})
}, },
getType() { getType() {
this.$get(this.api.typesList) this.$get(this.api.typesList)
@ -598,8 +591,7 @@ export default {
result = result.concat(n.secondColumn) result = result.concat(n.secondColumn)
}) })
this.quesBankList = result this.quesBankList = result
}) }).catch(err => {})
.catch(err => {})
}, },
computeTypeCount(){ computeTypeCount(){
let selected = this.selectedData let selected = this.selectedData
@ -636,7 +628,7 @@ export default {
this.computeTypeCount() this.computeTypeCount()
this.manualVisible = false this.manualVisible = false
}else{ }else{
this.$message.error('请选择试题') util.errorMsg('请选择试题')
} }
}, },
closeManual(){ closeManual(){
@ -708,7 +700,7 @@ export default {
}, },
countValid(index){ countValid(index){
if(this[`countNumberInput${index}`] > this[`countNumber${index}`]){ if(this[`countNumberInput${index}`] > this[`countNumber${index}`]){
this.$message.error(`${this.typeNameList[index-1]}输入题数不能大于可选题数`) util.errorMsg(`${this.typeNameList[index-1]}输入题数不能大于可选题数`)
return false return false
} }
return true return true
@ -727,7 +719,7 @@ export default {
// if(this[`countNumberInput${index}`] < this.pointRules[index-1]){ // if(this[`countNumberInput${index}`] < this.pointRules[index-1]){
// invalid = true // invalid = true
// }else if(this[`countNumberInput${index}`] > this.pointRules[index-1]){ // }else if(this[`countNumberInput${index}`] > this.pointRules[index-1]){
// this.$message.error('') // util.errorMsg('')
// return false // return false
// } // }
} }
@ -735,8 +727,8 @@ export default {
invalid = true invalid = true
} }
} }
if(everyUnchecked) return this.$message.error('请选择题型') if(everyUnchecked) return util.errorMsg('请选择题型')
if(everyIsZero) return this.$message.error('请输入题目数量') if(everyIsZero) return util.errorMsg('请输入题目数量')
let totalCount = 0 let totalCount = 0
if(invalid){ if(invalid){
for(let i in this.countCheck){ for(let i in this.countCheck){
@ -916,107 +908,105 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.box{ .form{
width: 90%; .line{
margin: 0 auto; display: flex;
.form{ align-items: center;
margin-bottom: 20px;
.item{
display: inline-flex;
align-items: center;
.key{
white-space: nowrap;
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
}
&.lg .key{
width: 160px;
margin-right: 10px;
text-align: right;
}
.el-input,.el-select{
width: 216px;
}
}
}
}
.testpaper{
.point{
display: flex;
margin-top: 20px;
.key{
margin: 8px 20px 0 10px;
font-size: 13px;
color: #444;
}
.line{ .line{
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 20px; margin-bottom: 13px;
.item{ .item{
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
flex: 1; margin-right: 30px;
/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;
}
}
}
}
.testpaper{
padding: 10px;
background-color: #f7f7f7;
.point{
display: flex;
margin-top: 20px;
.key{
margin: 8px 20px 0 10px;
font-size: 13px;
color: #444; color: #444;
} font-size: 12px;
.line{ input{
display: flex; width: 80px;
align-items: center; height: 30px;
margin-bottom: 13px; padding: 0 10px;
.item{ margin: 0 10px;
display: inline-flex; line-height: 30px;
align-items: center; border: 1px solid #e8e8e8;
margin-right: 30px; background-color: #fff;
color: #444; box-sizing: border-box;
font-size: 12px; &:focus{
input{ outline: none;
width: 80px; }
height: 30px; &:disabled{
padding: 0 10px; width: 56px;
margin: 0 10px; background-color: rgba(0, 0, 0, 0.04);
line-height: 30px; border: 1px solid rgba(0, 0, 0, 0.15);
border: 1px solid #e8e8e8; border-radius: 4px;
background-color: #fff; cursor: not-allowed;
box-sizing: border-box;
&:focus{
outline: none;
}
&:disabled{
background-color: #e8e8e8;
cursor: not-allowed;
}
} }
} }
} }
} }
} }
} }
.mini-form{ /deep/.mini-form{
/deep/.el-form-item__content{ .el-form-item__content{
width: 150px; width: 150px;
} }
} }
.select-wrap{ /deep/.select-wrap{
width: 90%;
margin: 0 auto;
.block{ .block{
display: flex; display: flex;
.key{ .key{
margin-right: 20px; margin-right: 20px;
font-size: 14px; font-size: 16px;
color: #555; color: rgba(0, 0, 0, 0.65);
white-space: nowrap;
} }
.types{ .types{
display: flex;
flex-wrap: wrap;
.item{ .item{
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 10px; margin-bottom: 10px;
color: #444; margin-right: 16px;
color: rgba(0, 0, 0, 0.65);
font-size: 12px; font-size: 12px;
/deep/.el-checkbox__label{ .el-checkbox__label{
color: #444; color: #444;
font-size: 12px; font-size: 12px;
} }
input{ input{
width: 80px; width: 56px;
height: 24px; height: 24px;
padding: 0 10px; padding: 0 10px;
margin: 0 10px; margin: 0 10px;
@ -1024,12 +1014,14 @@ export default {
color: #333; color: #333;
font-size: 12px; font-size: 12px;
background-color: #fff; background-color: #fff;
border: 1px solid #eaeaea; border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
&:focus{ &:focus{
outline: none; outline: none;
} }
&:disabled{ &:disabled{
background-color: #e8e8e8; background-color: #e8e8e8;
border-color: #e8e8e8;
cursor: not-allowed; cursor: not-allowed;
} }
} }

@ -1,92 +1,83 @@
<template> <template>
<div> <div>
<el-card shadow="hover" class="m-b-20"> <div class="tool">
<div> <ul class="filter">
<div class="p-title m-b-20">筛选</div> <li>
<div> <label>所属课程</label>
<div class="no-mb"> <el-select v-model="cid" clearable placeholder="请选择所属课程" size="small" @change="getData">
<el-form label-width="80px" inline> <el-option label="不限" value=""></el-option>
<el-form-item label="所属课程" class="userRadio"> <el-option v-for="(item,index) in courseList" :key="index" :label="item.courses" :value="item.courses"></el-option>
<el-select v-model="cid" clearable placeholder="请选择所属课程" @change="getData"> </el-select>
<el-option label="不限" value=""></el-option> </li>
<el-option v-for="(item,index) in courseList" :key="index" :label="item.courses" :value="item.courses"></el-option> <li>
</el-select> <label>试卷状态</label>
</el-form-item> <el-select v-model="state" clearable placeholder="请选择试卷状态" size="small" @change="getData">
<el-form-item label="试卷状态" class="userRadio"> <el-option label="不限" value=""></el-option>
<el-radio-group v-model="state" @change="getData"> <el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.id"></el-option>
<el-radio label="" border>全部</el-radio> </el-select>
<el-radio v-for="(item,index) in statusList" :key="index" :label="item.id" border>{{item.name}}</el-radio> </li>
</el-radio-group> <li>
</el-form-item> <label>试卷用途</label>
</el-form> <el-select v-model="effect" clearable placeholder="请选择试卷用途" size="small" @change="getData">
<div class="flex j-between"> <el-option label="不限" value=""></el-option>
<el-form label-width="80px" inline> <el-option v-for="(item,index) in effectList" :key="index" :label="item.label" :value="item.id"></el-option>
<el-form-item label="试卷用途" class="userRadio no-mb"> </el-select>
<el-radio-group v-model="effect" @change="getData"> </li>
<el-radio label="" border>全部</el-radio> <li>
<el-radio v-for="(item,index) in effectList" :key="index" :label="item.id" border>用于{{item.label}}</el-radio> <label>创建时间</label>
</el-radio-group> <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>
</el-form-item> </li>
<el-form-item label="创建时间" class="userRadio no-mb"> <li>
<el-date-picker v-model="date" align="right" unlink-panels type="daterange" <label>搜索</label>
start-placeholder="开始日期" end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" clearable></el-date-picker> <el-input placeholder="请输入试卷名称" suffix-icon="el-icon-search" v-model="keyword" clearable size="small"></el-input>
</el-form-item> </li>
</el-form> </ul>
<div> </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"> <el-table :data="listData" class="table" stripe header-align="center" row-key="id" @selection-change="handleSelecteChange">
<div class="p-title m-b-20">所有试卷</div> <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table :data="listData" class="table" stripe header-align="center" row-key="id" @selection-change="handleSelecteChange"> <el-table-column prop="name" label="试卷名称" align="center"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column> <el-table-column prop="courses" label="所属课程" align="center"></el-table-column>
<el-table-column prop="name" label="试卷名称" align="center"></el-table-column> <el-table-column prop="name" label="试卷用途" align="center">
<el-table-column prop="courses" label="所属课程" align="center"></el-table-column> <template slot-scope="scope">
<el-table-column prop="name" label="试卷用途" align="center"> {{getEffectName(scope.row.effect)}}
<template slot-scope="scope"> </template>
{{getEffectName(scope.row.effect)}} </el-table-column>
</template> <el-table-column prop="name" label="难易程度" align="center">
</el-table-column> <template slot-scope="scope">
<el-table-column prop="name" label="难易程度" align="center"> {{getDegreeName(scope.row.degree)}}
<template slot-scope="scope"> </template>
{{getDegreeName(scope.row.degree)}} </el-table-column>
</template> <el-table-column prop="name" label="组卷方式" align="center">
</el-table-column> <template slot-scope="scope">
<el-table-column prop="name" label="组卷方式" align="center"> {{getTypeName(scope.row.type)}}
<template slot-scope="scope"> </template>
{{getTypeName(scope.row.type)}} </el-table-column>
</template> <el-table-column prop="duration" label="时长(分钟)" width="110" align="center"></el-table-column>
</el-table-column> <el-table-column prop="createTime" label="创建时间" width="140" align="center"></el-table-column>
<el-table-column prop="duration" label="时长(分钟)" align="center"></el-table-column> <el-table-column prop="releaseTime" label="发布时间" width="140" align="center"></el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center"></el-table-column> <el-table-column prop="name" label="试卷状态" align="center">
<el-table-column prop="releaseTime" label="发布时间" align="center"></el-table-column> <template slot-scope="scope">
<el-table-column prop="name" label="试卷状态" align="center"> {{getStatusName(scope.row.state)}}
<template slot-scope="scope"> </template>
{{getStatusName(scope.row.state)}} </el-table-column>
</template> <el-table-column label="操作" width="120">
</el-table-column> <template slot-scope="scope">
<el-table-column label="操作" width="120"> <el-button type="text" v-if="scope.row.state == 0 && userId == scope.row.userId" @click="publish(scope.row)" v-auth="'/testPaper/list:所有试卷:发布'">发布</el-button>
<template slot-scope="scope"> <el-button type="text" @click="preview(scope.row)" v-auth="'/testPaper/list:所有试卷:预览'">预览</el-button>
<el-button type="text" v-if="scope.row.state == 0 && userId == scope.row.userId" @click="publish(scope.row)" v-auth="'/testPaper/list:所有试卷:发布'">发布</el-button> </template>
<el-button type="text" @click="preview(scope.row)" v-auth="'/testPaper/list:所有试卷:预览'">预览</el-button> </el-table-column>
</template> </el-table>
</el-table-column> <div class="pagination">
</el-table> <el-pagination background @current-change="handleCurrentChange" :current-page="page" layout="total, prev, pager, next" :total="total">
<div class="pagination"> </el-pagination>
<el-pagination background @current-change="handleCurrentChange" :current-page="page" layout="total, prev, pager, next" :total="total"> </div>
</el-pagination>
</div>
</el-card>
</div> </div>
</template> </template>
<script> <script>
import { mapState,mapGetters,mapActions } from 'vuex' import { mapState,mapGetters,mapActions } from 'vuex'
import util from '@/libs/util'
export default { export default {
data() { data() {
return { return {
@ -197,8 +188,8 @@ export default {
let briefCount = selected.filter(n => n.name == '简答题').length 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 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 util.warningMsg('总分值未满100分,请重新设置')
if(totalScore > 100) return this.$message.warning('总分值超过100分,请重新设置') if(totalScore > 100) return util.warningMsg('总分值超过100分,请重新设置')
let data = row let data = row
data.state = 1 data.state = 1
@ -208,12 +199,16 @@ export default {
data.fillBlanksNum = fillBlankCount data.fillBlanksNum = fillBlankCount
data.briefAnswerNum = briefCount data.briefAnswerNum = briefCount
this.$post(this.api.modifyState,data).then(res => { 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() this.getData()
}).catch(res => {}) }).catch(res => {})
}).catch(err => {}) }).catch(err => {})
}else{ }else{
this.$message.warning('请先选择试题') util.warningMsg('请先选择试题')
} }
}).catch(err => {}) }).catch(err => {})
}, },
@ -232,7 +227,16 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
/deep/.no-mb.el-form-item{ @media(max-width: 1860px){
margin-bottom: 0; .tool{
margin-bottom: 0;
.filter{
flex-wrap: wrap;
li{
width: 30%;
margin-bottom: 16px;
}
}
}
} }
</style> </style>

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

@ -78,101 +78,87 @@
</div> </div>
</el-dialog> </el-dialog>
<el-card shadow="hover" class="m-b-20"> <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>
</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> <div>
<div class="p-title m-b-20">筛选</div> <el-button type="primary" size="small" round @click="addTestPaper" v-auth="'/testPaper/list:我的试卷:创建试卷'">创建试卷</el-button>
<div> <el-button type="primary" size="small" round @click="delAllSelection" v-auth="'/testPaper/list:我的试卷:批量删除'">批量删除</el-button>
<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">
<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> </div>
</el-card> </div>
<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="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="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>
<el-table-column prop="name" label="试卷用途" align="center">
<template slot-scope="scope">
{{getEffectName(scope.row.effect)}}
</template>
</el-table-column>
<el-table-column prop="name" label="难易程度" align="center">
<template slot-scope="scope">
{{getDegreeName(scope.row.degree)}}
</template>
</el-table-column>
<el-table-column prop="name" 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="createTime" label="创建时间" align="center"></el-table-column>
<el-table-column prop="releaseTime" label="发布时间" align="center"></el-table-column>
<el-table-column prop="name" label="试卷状态" align="center">
<template slot-scope="scope">
{{getStatusName(scope.row.state)}}
</template>
</el-table-column>
<el-table-column label="操作" width="250">
<template slot-scope="scope">
<el-button type="text" v-if="scope.row.state == 0" @click="publish(scope.row)" v-auth="'/testPaper/list:我的试卷:发布'">发布</el-button>
<el-button type="text" @click="preview(scope.row)" v-auth="'/testPaper/list:我的试卷:预览'" :disabled="!scope.row.qid">预览</el-button>
<el-button type="text" @click="copy(scope.row)" v-auth="'/testPaper/list:我的试卷:复制'">复制</el-button>
<el-button type="text" @click="edit(scope.row)" v-auth="'/testPaper/list:我的试卷:修改'">修改</el-button>
<el-button type="text" @click="delData(scope.row)" v-auth="'/testPaper/list:我的试卷:删除'">删除</el-button>
<el-button type="text" @click="exportData(scope.row)" v-auth="'/testPaper/list:我的试卷:导出'">导出</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background @current-change="handleCurrentChange" :current-page="page" layout="total, prev, pager, next" :total="total">
</el-pagination>
</div>
</el-card>
<el-table :data="listData" class="table" stripe header-align="center" row-key="id" @selection-change="handleSelecteChange">
<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>
<el-table-column prop="name" label="试卷用途" align="center">
<template slot-scope="scope">
{{getEffectName(scope.row.effect)}}
</template>
</el-table-column>
<el-table-column prop="name" label="难易程度" align="center">
<template slot-scope="scope">
{{getDegreeName(scope.row.degree)}}
</template>
</el-table-column>
<el-table-column prop="name" label="组卷方式" align="center">
<template slot-scope="scope">
{{getTypeName(scope.row.type)}}
</template>
</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)}}
</template>
</el-table-column>
<el-table-column label="操作" width="250">
<template slot-scope="scope">
<el-button type="text" v-if="scope.row.state == 0" @click="publish(scope.row)" v-auth="'/testPaper/list:我的试卷:发布'">发布</el-button>
<el-button type="text" @click="preview(scope.row)" v-auth="'/testPaper/list:我的试卷:预览'" :disabled="!scope.row.qid">预览</el-button>
<el-button type="text" @click="copy(scope.row)" v-auth="'/testPaper/list:我的试卷:复制'">复制</el-button>
<el-button type="text" @click="edit(scope.row)" v-auth="'/testPaper/list:我的试卷:修改'">修改</el-button>
<el-button type="text" @click="delData(scope.row)" v-auth="'/testPaper/list:我的试卷:删除'">删除</el-button>
<el-button type="text" @click="exportData(scope.row)" v-auth="'/testPaper/list:我的试卷:导出'">导出</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background @current-change="handleCurrentChange" :current-page="page" layout="total, prev, pager, next" :total="total">
</el-pagination>
</div>
</div> </div>
</template> </template>
@ -180,6 +166,7 @@
import { mapState,mapGetters,mapActions } from 'vuex' import { mapState,mapGetters,mapActions } from 'vuex'
import html2Canvas from 'html2canvas' import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf' import JsPDF from 'jspdf'
import util from '@/libs/util'
function getUrlBase64(url, ext, callback) { function getUrlBase64(url, ext, callback) {
var canvas = document.createElement("canvas"); //canvas DOM var canvas = document.createElement("canvas"); //canvas DOM
@ -299,12 +286,12 @@ export default {
this.getData() this.getData()
}, },
delData(row) { delData(row) {
this.$confirm('确定要删除吗?', '提示', { this.$confirm('此删除操作不可逆,是否确认删除选中项?', '提示', {
type: 'warning' type: 'warning'
}) })
.then(() => { .then(() => {
this.$post(`${this.api.delByMyTestPaper}?ids=${row.id}`).then(res => { this.$post(`${this.api.delByMyTestPaper}?ids=${row.id}`).then(res => {
this.$message.success('删除成功') util.successMsg('删除成功')
this.getData() this.getData()
}).catch(res => {}) }).catch(res => {})
}).catch(() => {}) }).catch(() => {})
@ -396,18 +383,18 @@ export default {
return item.id return item.id
}) })
this.$confirm('确定要删除吗?', '提示', { this.$confirm(`此批量删除操作不可逆,是否确认删除${util.ellipsisStr(newArr[0].name)}${newArr.length}个选中项?`, '提示', {
type: 'warning' type: 'warning'
}) })
.then(() => { .then(() => {
this.$post(`${this.api.delByMyTestPaper}?ids=${delList.join()}`).then(res => { this.$post(`${this.api.delByMyTestPaper}?ids=${delList.join()}`).then(res => {
this.multipleSelection = [] this.multipleSelection = []
this.$message.success('删除成功') util.successMsg('删除成功')
this.getData() this.getData()
}).catch(res => {}) }).catch(res => {})
}).catch(() => {}) }).catch(() => {})
}else{ }else{
this.$message.error('请先选择数据 !') util.errorMsg('请先选择数据 !')
} }
}, },
publish(row){ publish(row){
@ -429,8 +416,8 @@ export default {
let briefCount = selected.filter(n => n.name == '简答题').length 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 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 util.warningMsg('总分值未满100分,请重新设置')
if(totalScore > 100) return this.$message.warning('总分值超过100分,请重新设置') if(totalScore > 100) return util.warningMsg('总分值超过100分,请重新设置')
let data = row let data = row
data.state = 1 data.state = 1
@ -440,12 +427,16 @@ export default {
data.fillBlanksNum = fillBlankCount data.fillBlanksNum = fillBlankCount
data.briefAnswerNum = briefCount data.briefAnswerNum = briefCount
this.$post(this.api.modifyState,data).then(res => { 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() this.getData()
}).catch(res => {}) }).catch(res => {})
}).catch(err => {}) }).catch(err => {})
}else{ }else{
this.$message.warning('请先选择试题') util.warningMsg('请先选择试题')
} }
}).catch(err => {}) }).catch(err => {})
}, },
@ -459,7 +450,7 @@ export default {
}, },
copy(row){ copy(row){
this.$post(`${this.api.copyPaper}?id=${row.id}`).then(res => { this.$post(`${this.api.copyPaper}?id=${row.id}`).then(res => {
this.$message.success('复制成功'); util.successMsg('复制成功');
this.getData() this.getData()
}).catch(res => {}) }).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> </style>

@ -19,12 +19,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<div> <div>
<el-input <el-input placeholder="请输入真实姓名/学号" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
placeholder="请输入真实姓名/学号"
prefix-icon="el-icon-search"
v-model="keyword"
clearable
></el-input>
</div> </div>
</div> </div>
</el-card> </el-card>
@ -34,15 +29,7 @@
<el-card shadow="hover" class="m-b-20"> <el-card shadow="hover" class="m-b-20">
<div class="p-title m-b-20">练习批阅</div> <div class="p-title m-b-20">练习批阅</div>
<el-table <el-table :data="listData" ref="table" row-key="id" class="table" stripe header-align="center" @selection-change="handleSelectionChange">
:data="listData"
ref="table"
row-key="id"
class="table"
stripe
header-align="center"
@selection-change="handleSelectionChange"
>
<el-table-column <el-table-column
type="selection" type="selection"
width="55" width="55"
@ -82,6 +69,7 @@
</div> </div>
</template> </template>
<script> <script>
import util from '@/libs/util'
export default { export default {
data() { data() {
return { return {

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

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

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

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

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

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

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

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

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

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

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

Loading…
Cancel
Save