Compare commits

...

41 Commits

Author SHA1 Message Date
yujialong 24b60d7468 fix 1 week ago
yujialong 796f802fc5 fix 2 weeks ago
yujialong 2af18aa23c fix 2 weeks ago
yujialong fe4a1b7900 fix 2 weeks ago
yujialong 66b4c21343 fix 2 weeks ago
yujialong 40327a423f fix 1 month ago
yujialong a089ad2943 fix 1 month ago
yujialong 734524aab2 赛事修复 1 month ago
yujialong 4779595867 fix 1 month ago
yujialong df33b0b5eb fix 1 month ago
yujialong b692519c5d fix 1 month ago
yujialong 996a611e03 fix 1 month ago
yujialong 37eb678280 fix 1 month ago
yujialong 46eaca3745 fix 2 months ago
yujialong 56361bdd11 fix 2 months ago
yujialong f3e795125d 竞赛修复 2 months ago
yujialong d0764a64a0 赛事成绩列表实训跟理论合并,线下单独一个页面 2 months ago
yujialong a033ef3565 fix 2 months ago
yujialong f07e4ccdb2 fix 2 months ago
yujialong bf8f4093f6 评阅中心 2 months ago
yujialong dabd2f9871 fix 3 months ago
yujialong 02b22578a4 赛事修复 3 months ago
yujialong e44b2ad9b9 fix 3 months ago
yujialong 0d952de033 fix 3 months ago
yujialong 45ff98f698 fix 3 months ago
yujialong 6747314cc9 fix 3 months ago
yujialong 645e52a679 fix 3 months ago
yujialong 5a21e78cac 赛事成绩相关 3 months ago
yujialong 5c7bb7eba0 fix 3 months ago
yujialong 8eb83be7c7 赛事列表、赛事理论成绩列表 3 months ago
yujialong 89a1a63f71 理论考试实验报告联调完成 3 months ago
yujialong 3668825847 赛事选择试卷相关 3 months ago
yujialong b8a41a5e23 登录调整 4 months ago
yujialong a2b4e242b4 fix 4 months ago
yujialong 58f007cfc9 oss上传秘钥加密 4 months ago
yujialong 812f1c916a 考试平台iframe,订单、客户修复 4 months ago
yujialong b831b14302 知识点、题库分类 4 months ago
yujialong 2669f15962 理论考试系统列表、题库管理 4 months ago
yujialong 300e917d1e 订单修复 5 months ago
yujialong 6fe4a41fa1 订单:一键发货、批量修改期限、试用默认1月 5 months ago
yujialong d611d682a2 fix 5 months ago
  1. 10
      package-lock.json
  2. 2
      package.json
  3. 22
      src/App.vue
  4. 54
      src/assets/css/main.css
  5. BIN
      src/assets/img/ach1.png
  6. BIN
      src/assets/img/ach2.png
  7. 1
      src/assets/img/right.svg
  8. 1
      src/assets/img/shrink.svg
  9. 1
      src/assets/img/tag-active.svg
  10. 1
      src/assets/img/tag.svg
  11. 1
      src/assets/img/wrong.svg
  12. 53
      src/components/Header.vue
  13. 47
      src/components/Sidebar.vue
  14. 57
      src/components/quill/index.vue
  15. 23
      src/components/upload/config.js
  16. 34
      src/components/upload/index.vue
  17. 11
      src/components/upload/upload.js
  18. 50
      src/const/ques.js
  19. 34
      src/const/testPaper.js
  20. 37
      src/libs/util.js
  21. 62
      src/router/index.js
  22. 8
      src/setting.js
  23. 22
      src/utils/api.js
  24. 6
      src/utils/editor.js
  25. 18
      src/utils/http.js
  26. 5
      src/views/Home.vue
  27. 277
      src/views/Login.vue
  28. 432
      src/views/course/AddCurriculum.vue
  29. 287
      src/views/course/contentSettings.vue
  30. 81
      src/views/customer/AddCustomer.vue
  31. 193
      src/views/devLogin.vue
  32. 21
      src/views/match/add/index.vue
  33. 271
      src/views/match/add/set.vue
  34. 60
      src/views/match/add/step1.vue
  35. 14
      src/views/match/add/step2.vue
  36. 58
      src/views/match/add/step3.vue
  37. 211
      src/views/match/add/template.vue
  38. 185
      src/views/match/list/index.vue
  39. 16
      src/views/match/manage/index.vue
  40. 95
      src/views/match/manage/matchArch.vue
  41. 728
      src/views/match/manage/matchArchList.vue
  42. 32
      src/views/match/manage/matchInfo.vue
  43. 95
      src/views/match/manage/matchRank.vue
  44. 449
      src/views/match/manage/matchReport.vue
  45. 21
      src/views/match/manage/matchSignup.vue
  46. 675
      src/views/match/manage/otherArchList.vue
  47. 1059
      src/views/match/manage/theoryReport.vue
  48. 413
      src/views/match/manage/trialReport.vue
  49. 401
      src/views/order/AddOrder.vue
  50. 143
      src/views/order/Order.vue
  51. 113
      src/views/parner/staff.vue
  52. 50
      src/views/review/index.vue
  53. 96
      src/views/serve/Configure.vue
  54. 284
      src/views/serve/projectAdd.vue
  55. 107
      src/views/setting/info.vue
  56. 703
      src/views/shop/addProduct/index.vue
  57. 262
      src/views/system/staff.vue
  58. 2
      src/views/theoreticalCourse/contentSettings/index.vue
  59. 142
      src/views/theoreticalCourse/list/buildPlatform/index.vue
  60. 10
      src/views/theoreticalCourse/list/index.vue
  61. 175
      src/views/theoreticalCourse/preview/index.vue
  62. 39
      src/views/theoryExam/index.vue
  63. 57
      src/views/theoryExam/list/index.vue
  64. 139
      src/views/theoryExam/list/program.vue
  65. 321
      src/views/theoryExam/list/system.vue

10
package-lock.json generated

@ -3871,6 +3871,11 @@
"randomfill": "^1.0.3" "randomfill": "^1.0.3"
} }
}, },
"crypto-js": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
},
"css": { "css": {
"version": "2.2.4", "version": "2.2.4",
"resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
@ -9509,6 +9514,11 @@
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
}, },
"jsencrypt": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/jsencrypt/-/jsencrypt-3.3.2.tgz",
"integrity": "sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A=="
},
"jsesc": { "jsesc": {
"version": "2.5.2", "version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",

@ -14,6 +14,7 @@
"babel-polyfill": "^6.26.0", "babel-polyfill": "^6.26.0",
"blueimp-md5": "^2.19.0", "blueimp-md5": "^2.19.0",
"clipboard": "^2.0.11", "clipboard": "^2.0.11",
"crypto-js": "^4.2.0",
"decimal.js": "^10.4.3", "decimal.js": "^10.4.3",
"echarts": "^5.4.1", "echarts": "^5.4.1",
"element-theme": "^2.0.1", "element-theme": "^2.0.1",
@ -22,6 +23,7 @@
"image-conversion": "^2.1.1", "image-conversion": "^2.1.1",
"image-webpack-loader": "^8.1.0", "image-webpack-loader": "^8.1.0",
"js-cookie": "^3.0.1", "js-cookie": "^3.0.1",
"jsencrypt": "^3.3.2",
"jszip": "^3.10.1", "jszip": "^3.10.1",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mavon-editor": "^2.10.4", "mavon-editor": "^2.10.4",

@ -1,13 +1,29 @@
<template> <template>
<div id="app"> <div id="app">
<el-radio-group v-if="Setting.isDev" class="ip" v-model="ip" @change="ipChange">
<el-radio :label="0">刘榕ip</el-radio>
<el-radio :label="1">陈赓ip</el-radio>
<el-radio :label="2">测试服ip</el-radio>
</el-radio-group>
<router-view></router-view> <router-view></router-view>
</div> </div>
</template> </template>
<script> <script>
import Setting from '@/setting'
export default { export default {
name: 'App', name: 'App',
data () {
return {
Setting,
ip: localStorage.getItem('ip') ? +localStorage.getItem('ip') : 0,
};
},
created () { created () {
window.exitSystem = () => {
sessionStorage.removeItem('token')
location.reload()
}
//sessionStorage //sessionStorage
if (sessionStorage.getItem("store")) { if (sessionStorage.getItem("store")) {
this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem("store")))) this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem("store"))))
@ -17,6 +33,12 @@
window.addEventListener("beforeunload", () => { window.addEventListener("beforeunload", () => {
sessionStorage.getItem("token") && sessionStorage.setItem("store", JSON.stringify(this.$store.state)) sessionStorage.getItem("token") && sessionStorage.setItem("store", JSON.stringify(this.$store.state))
}) })
},
methods: {
ipChange (val) {
localStorage.setItem('ip', val)
location.reload()
},
} }
} }
</script> </script>

@ -19,6 +19,12 @@ body {
font-size: 14px; font-size: 14px;
} }
.ip {
z-index: 1;
position: fixed;
top: 0;
left: 0;
}
a { a {
text-decoration: none; text-decoration: none;
} }
@ -442,12 +448,15 @@ li {
.el-switch__label span { .el-switch__label span {
font-size: 12px; font-size: 12px;
} }
.m-b-20 { .m-r-5 {
margin-bottom: 20px; margin-right: 5px;
} }
.m-r-10 { .m-r-10 {
margin-right: 10px; margin-right: 10px;
} }
.m-b-20 {
margin-bottom: 20px;
}
@media (max-width: 720px) { @media (max-width: 720px) {
.el-message { .el-message {
min-width: auto !important; min-width: auto !important;
@ -455,7 +464,7 @@ li {
} }
} }
.el-tooltip__popper { .el-tooltip__popper {
max-width: 500px !important; max-width: 100% !important;
} }
.no-atTheMoment > .el-picker-panel__footer > .el-button--text:first-child { .no-atTheMoment > .el-picker-panel__footer > .el-button--text:first-child {
display: none; display: none;
@ -479,3 +488,42 @@ li {
.search-wrap .el-input__inner { .search-wrap .el-input__inner {
border-radius: 0; border-radius: 0;
} }
.edui-default {
line-height: normal;
}
.html-parse {
table {
display: table;
margin-bottom: 10px;
border-collapse: collapse;
th,
td {
padding: 5px 10px;
border: 1px solid #DDD;
}
}
ol {
padding-left: 30px;
li {
list-style-type: decimal;
}
}
ul {
padding-left: 30px;
li {
list-style-type: disc;
}
}
}
.files-tip {
li {
line-height: 1.8;
cursor: pointer;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1723792589398" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5839" width="20" height="20" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M874 150C674.09-50 349.91-50 150 150s-200 524.09 0 724 524.09 200 724 0 200-524.09 0-724zM760.57 440.57l-256 256a80 80 0 0 1-113.14 0l-128-128a80 80 0 0 1 113.14-113.14L448 526.86l199.43-199.43a80 80 0 0 1 113.14 113.14z" fill="#2abd8c" p-id="5840"></path></svg>

After

Width:  |  Height:  |  Size: 593 B

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1723535697263" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5903" width="18" height="18" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M877.5 565.9l-367.6-340-367.6 340c-22.5 14.5-52.5 14.5-67.5 0-15-21.7-15-50.7 0-65.1L495 117.5c0-7.2 7.5-7.2 15-7.2s7.5 0 15 7.2l420.2 383.3c22.5 21.7 15 50.6 0 65.1-22.7 14.5-52.7 14.5-67.7 0zM494.8 450.1c0-7.2 7.5-7.2 15-7.2s15 0 15 7.2L945 833.4c22.5 21.7 15 50.6 0 65.1-22.5 14.4-52.5 14.4-67.5 0L509.8 558.6 142.2 905.8c-22.5 14.5-52.5 14.5-67.5 0-15-21.7-15-50.7 0-65.1l420.1-390.6z m0 0" fill="#666666" p-id="5904"></path></svg>

After

Width:  |  Height:  |  Size: 766 B

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1723619200843" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7128" width="18" height="18" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M695.7 118.6H326.9c-58.2 0-105.4 47.2-105.4 105.4v579.6c0 58.2 47.2 105.4 105.4 105.4l184.4-184.4L695.7 909c58.2 0 105.4-47.2 105.4-105.4V224c0-58.2-47.1-105.4-105.4-105.4z" fill="#d81e06" p-id="7129"></path></svg>

After

Width:  |  Height:  |  Size: 545 B

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1723619200843" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7128" width="18" height="18" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M695.7 118.6H326.9c-58.2 0-105.4 47.2-105.4 105.4v579.6c0 58.2 47.2 105.4 105.4 105.4l184.4-184.4L695.7 909c58.2 0 105.4-47.2 105.4-105.4V224c0-58.2-47.1-105.4-105.4-105.4z" fill="#bfbfbf" p-id="7129"></path></svg>

After

Width:  |  Height:  |  Size: 545 B

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1723792667165" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7415" width="20" height="20" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M480 64C217.6 64 0 281.6 0 544s217.6 480 480 480 480-217.6 480-480S742.4 64 480 64z m204.8 614.4c19.2 19.2 19.2 44.8 0 64-19.2 19.2-44.8 19.2-64 0L486.4 608 345.6 748.8c-19.2 19.2-51.2 19.2-70.4 0-19.2-19.2-19.2-51.2 0-70.4L416 537.6 281.6 403.2c-19.2-19.2-19.2-44.8 0-64 19.2-19.2 44.8-19.2 64 0L480 473.6l140.8-140.8c19.2-19.2 51.2-19.2 70.4 0 19.2 19.2 19.2 51.2 0 70.4L550.4 544l134.4 134.4z" fill="#e75050" p-id="7416"></path></svg>

After

Width:  |  Height:  |  Size: 768 B

@ -1,29 +1,16 @@
<template> <template>
<div class="header flex-between"> <div class="header flex-between">
<div class="logo"> <div class="logo">
<img class="cursor" <img class="cursor" @click="goHome" src="../assets/img/logo.png">
@click="goHome"
src="../assets/img/logo.png">
</div> </div>
<el-radio-group v-if="Setting.isDev"
v-model="ip"
@change="ipChange">
<el-radio :label="0">刘榕ip</el-radio>
<el-radio :label="1">陈赓ip</el-radio>
</el-radio-group>
<div class="header-right"> <div class="header-right">
<div class="header-user-con"> <div class="header-user-con">
<div class="user" <div class="user" @click="toPerson">
@click="toPerson"> <el-avatar :size="40" :src="$store.state.avatar"></el-avatar>
<el-avatar :size="40"
:src="$store.state.avatar"></el-avatar>
<span class="user-avator">{{ userName }}</span> <span class="user-avator">{{ userName }}</span>
</div> </div>
<el-divider class="ml20" <el-divider class="ml20" direction="vertical"></el-divider>
direction="vertical"></el-divider> <el-button type="text" class="ml20" @click="logout">退出</el-button>
<el-button type="text"
class="ml20"
@click="loginout">退出</el-button>
</div> </div>
</div> </div>
</div> </div>
@ -34,9 +21,9 @@ import Setting from '@/setting'
export default { export default {
data () { data () {
return { return {
timer: null,
Setting, Setting,
userName: '', userName: '',
ip: localStorage.getItem('nakadaiIp') ? +localStorage.getItem('nakadaiIp') : 0,
}; };
}, },
mounted () { mounted () {
@ -48,9 +35,10 @@ export default {
this.$router.push('/person') this.$router.push('/person')
} }
}, },
loginout () { async logout () {
localStorage.removeItem('ms_username'); await this.$post(this.api.logout)
localStorage.removeItem('token'); localStorage.removeItem('ms_username')
localStorage.removeItem('token')
sessionStorage.clear() sessionStorage.clear()
location.reload() location.reload()
}, },
@ -94,8 +82,8 @@ export default {
}, },
// //
heartbeatDetection () { heartbeatDetection () {
setInterval(async () => { this.timer = setInterval(async () => {
await this.$get(this.api.heartbeatDetection) sessionStorage.getItem('token') ? await this.$get(this.api.heartbeatDetection) : clearInterval(this.timer)
}, 58 * 1000) }, 58 * 1000)
}, },
@ -112,11 +100,6 @@ export default {
Setting.isPro && this.heartbeatDetection() Setting.isPro && this.heartbeatDetection()
}).catch(err => { }) }).catch(err => { })
}, },
ipChange (val) {
localStorage.setItem('nakadaiIp', val)
location.reload()
},
}, },
}; };
</script> </script>
@ -129,54 +112,66 @@ export default {
font-size: 16px; font-size: 16px;
color: #333; color: #333;
} }
.header .logo { .header .logo {
float: left; float: left;
width: 170px; width: 170px;
height: 40px; height: 40px;
margin-left: 20px; margin-left: 20px;
} }
.header .logo img { .header .logo img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.header-right { .header-right {
float: right; float: right;
padding-right: 50px; padding-right: 50px;
} }
.header-user-con { .header-user-con {
display: flex; display: flex;
height: 70px; height: 70px;
align-items: center; align-items: center;
} }
.header-user-con .user { .header-user-con .user {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
cursor: pointer; cursor: pointer;
} }
.user-avator { .user-avator {
cursor: pointer; cursor: pointer;
margin-left: 10px; margin-left: 10px;
font-size: 12px; font-size: 12px;
} }
.ml20 { .ml20 {
margin-left: 20px; margin-left: 20px;
} }
.user-avator img { .user-avator img {
display: block; display: block;
width: 40px; width: 40px;
height: 40px; height: 40px;
border-radius: 50%; border-radius: 50%;
} }
/deep/.header-right .el-button--text { /deep/.header-right .el-button--text {
color: #333; color: #333;
span { span {
font-size: 12px; font-size: 12px;
} }
} }
.header-right .el-divider--vertical { .header-right .el-divider--vertical {
width: 2px; width: 2px;
height: 15px; height: 15px;
} }
.header-right .el-divider { .header-right .el-divider {
background-color: #333; background-color: #333;
} }

@ -1,40 +1,27 @@
<template> <template>
<div> <div>
<el-menu class="sidebar-el-menu" <el-menu class="sidebar-el-menu" :default-active="onRoutes" background-color="#324157" text-color="#bfcbd9"
:default-active="onRoutes" active-text-color="#9278FF" unique-opened mode="horizontal" router @select="handleSelect">
background-color="#324157"
text-color="#bfcbd9"
active-text-color="#9278FF"
unique-opened
mode="horizontal"
router
@select="handleSelect">
<template v-for="item in menus"> <template v-for="item in menus">
<template v-if="item.subs"> <template v-if="item.subs">
<el-submenu :index="item.index" <el-submenu :index="item.index" :key="item.index">
:key="item.index">
<template slot="title"> <template slot="title">
<i :class="item.icon"></i> <i :class="item.icon"></i>
<span slot="title">{{ item.title }}</span> <span slot="title">{{ item.title }}</span>
</template> </template>
<template v-for="subItem in item.subs"> <template v-for="subItem in item.subs">
<el-submenu v-if="subItem.subs" <el-submenu v-if="subItem.subs" :index="subItem.index" :key="subItem.index">
:index="subItem.index"
:key="subItem.index">
<template slot="title">{{ subItem.title }}</template> <template slot="title">{{ subItem.title }}</template>
<el-menu-item v-for="(threeItem,i) in subItem.subs" <el-menu-item v-for="(threeItem, i) in subItem.subs" :key="i" :index="threeItem.index">{{
:key="i" threeItem.title
:index="threeItem.index">{{ threeItem.title }}</el-menu-item> }}</el-menu-item>
</el-submenu> </el-submenu>
<el-menu-item v-else <el-menu-item v-else :index="subItem.index" :key="subItem.index">{{ subItem.title }}</el-menu-item>
:index="subItem.index"
:key="subItem.index">{{ subItem.title }}</el-menu-item>
</template> </template>
</el-submenu> </el-submenu>
</template> </template>
<template v-else> <template v-else>
<el-menu-item :index="item.index" <el-menu-item :index="item.index" :key="item.index">
:key="item.index">
<i :class="item.icon"></i> <i :class="item.icon"></i>
<span slot="title">{{ item.title }}</span> <span slot="title">{{ item.title }}</span>
</el-menu-item> </el-menu-item>
@ -102,7 +89,7 @@ export default {
title: '系统配置' title: '系统配置'
}, },
{ {
icon: 'el-icon-s-check', icon: 'el-icon-box',
index: '/parner', index: '/parner',
title: '合伙管理' title: '合伙管理'
}, },
@ -112,10 +99,20 @@ export default {
title: '合伙运营' title: '合伙运营'
}, },
{ {
icon: 'el-icon-s-shop', icon: 'el-icon-shopping-cart-2',
index: '/shop', index: '/shop',
title: '商城管理' title: '商城管理'
}, },
{
icon: 'el-icon-data-board',
index: '/theoryExam',
title: '考试平台'
},
{
icon: 'el-icon-document-copy',
index: '/review',
title: '评阅平台'
},
], ],
menus: [], menus: [],
onRoutes: this.$route.path onRoutes: this.$route.path
@ -178,9 +175,11 @@ export default {
.sidebar::-webkit-scrollbar { .sidebar::-webkit-scrollbar {
width: 0; width: 0;
} }
.sidebar-el-menu:not(.el-menu--collapse) { .sidebar-el-menu:not(.el-menu--collapse) {
width: 100%; width: 100%;
} }
.sidebar>ul { .sidebar>ul {
height: 100%; height: 100%;
} }

@ -1,39 +1,21 @@
<template> <template>
<div> <div>
<el-radio-group v-if="!readonly && radio" <el-radio-group v-if="!readonly && radio" class="type-radio" v-model="editorType" @change="typeChange">
class="type-radio"
v-model="editorType"
@change="typeChange">
<el-radio label="0">富文本</el-radio> <el-radio label="0">富文本</el-radio>
<el-radio label="1">markdown</el-radio> <el-radio label="1">markdown</el-radio>
</el-radio-group> </el-radio-group>
<div v-show="editorType == 0" <div v-show="editorType == 0" class="quill" ref="quill" :class="classes">
class="quill" <div ref="editor" :style="styles" v-loading="loading"></div>
ref="quill" <Upload :max-size="1000" :limit="100" @beforeUpload="beforeUpload" @onSuccess="editorUploadSuccess"
:class="classes">
<div ref="editor"
:style="styles"
v-loading="loading"></div>
<Upload :max-size="1000"
:limit="100"
@beforeUpload="beforeUpload"
@onSuccess="editorUploadSuccess"
style="display: none"> style="display: none">
<div slot="trigger"> <div slot="trigger">
<el-button :id="'editorUpload' + index" <el-button :id="'editorUpload' + index" type="primary">点击上传</el-button>
type="primary">点击上传</el-button>
</div> </div>
</Upload> </Upload>
</div> </div>
<mavon-editor class="md" <mavon-editor class="md" v-model="mdVal" v-show="editorType == 1" ref="md" :ishljs="true" :subfield="false"
v-model="mdVal" @change="mdChange" @imgAdd="imgAdd" />
v-show="editorType == 1"
ref="md"
:ishljs="true"
:subfield="false"
@change="mdChange"
@imgAdd="imgAdd" />
</div> </div>
</template> </template>
@ -302,15 +284,18 @@ export default {
.type-radio { .type-radio {
margin-bottom: 20px; margin-bottom: 20px;
} }
.quill-no-border { .quill-no-border {
.ql-toolbar.ql-snow { .ql-toolbar.ql-snow {
border: none; border: none;
border-bottom: 1px solid #e8eaec; border-bottom: 1px solid #e8eaec;
} }
.ql-container.ql-snow { .ql-container.ql-snow {
border: none; border: none;
} }
} }
.else { .else {
.ql-toolbar.ql-snow { .ql-toolbar.ql-snow {
height: 0; height: 0;
@ -319,8 +304,10 @@ export default {
border-top: 0; border-top: 0;
} }
} }
/deep/.ql-snow { /deep/.ql-snow {
position: relative; position: relative;
.ql-tooltip { .ql-tooltip {
position: absolute !important; position: absolute !important;
top: 0 !important; top: 0 !important;
@ -328,10 +315,30 @@ export default {
transform: translateY(10px); transform: translateY(10px);
} }
} }
.md { .md {
max-height: 300px; max-height: 300px;
} }
/deep/.v-note-wrapper .v-note-panel { /deep/.v-note-wrapper .v-note-panel {
min-height: 200px; min-height: 200px;
} }
/deep/.markdown-body {
ul {
list-style: disc;
li {
list-style: inherit;
}
}
ol {
list-style: decimal;
li {
list-style: inherit;
}
}
}
</style> </style>

@ -2,14 +2,31 @@
* 阿里云oss配置 * 阿里云oss配置
* */ * */
export default { import router from '@/router/index'
import { Message } from 'element-ui'
export default async function () {
try {
let RE = localStorage.getItem('osc')
if (RE) {
RE = JSON.parse(RE)
} else {
sessionStorage.removeItem('token')
Message.error('登录过期,请重新登录!')
setTimeout(() => {
router.replace('/login')
}, 1500)
return false
}
return {
// oss账号信息 // oss账号信息
config: { config: {
region: 'oss-cn-shenzhen', region: 'oss-cn-shenzhen',
accessKeyId: 'LTAI4FzqQHnk4rozqLZ8jCNj', accessKeyId: RE[0],
accessKeySecret: 'mveW7B1OyFoKUkHm8WsxmrjHmkJWHq', accessKeySecret: RE[1],
bucket: 'huoran' bucket: 'huoran'
}, },
// 上传成功url前置部分(成功回调没有返回url) // 上传成功url前置部分(成功回调没有返回url)
preUrl: 'https://huoran.oss-cn-shenzhen.aliyuncs.com/' preUrl: 'https://huoran.oss-cn-shenzhen.aliyuncs.com/'
} }
} catch (e) { }
}

@ -1,24 +1,12 @@
<template> <template>
<el-upload :disabled="uploading" <el-upload :disabled="uploading" :before-upload="beforeUpload" :on-remove="onRemove" :on-error="uploadError"
:before-upload="beforeUpload" :limit="limit" action="" :on-exceed="handleExceed" :show-file-list="showFiles" :file-list="fileList"
:on-remove="onRemove" :http-request="handleRequest" name="file">
:on-error="uploadError"
:limit="limit"
action=""
:on-exceed="handleExceed"
:show-file-list="showFiles"
:file-list="fileList"
:http-request="handleRequest"
name="file">
<slot name="trigger"> <slot name="trigger">
<el-button size="small" <el-button size="small" :loading="uploading">{{ uploading ? '正在上传' : '上传文件' }}</el-button>
:loading="uploading">{{ uploading ? '正在上传' : '上传文件' }}</el-button>
</slot> </slot>
<div slot="tip" <div slot="tip" class="el-upload__tip">
class="el-upload__tip"> <el-progress v-if="uploading" class="upload-progress" :stroke-width="3"
<el-progress v-if="uploading"
class="upload-progress"
:stroke-width="3"
:percentage="uploadProgress"></el-progress> :percentage="uploadProgress"></el-progress>
<slot name="tip"> <slot name="tip">
<p>支持扩展名.rar .zip .doc .docx .pdf .jpg...</p> <p>支持扩展名.rar .zip .doc .docx .pdf .jpg...</p>
@ -69,7 +57,8 @@ export default {
client: null, client: null,
uploading: false, uploading: false,
uploadProgress: 0, uploadProgress: 0,
showFiles: this.showFileList showFiles: this.showFileList,
Oss: {},
}; };
}, },
mounted () { mounted () {
@ -77,8 +66,9 @@ export default {
}, },
methods: { methods: {
// oss // oss
initOss () { async initOss () {
this.client = new OSS(OssConfig.config) this.Oss = await OssConfig()
this.client = new OSS(this.Oss.config)
}, },
// //
beforeUpload (file) { beforeUpload (file) {
@ -107,7 +97,7 @@ export default {
}); });
this.uploading = false this.uploading = false
const url = OssConfig.preUrl + name const url = this.Oss.preUrl + name
this.changeFileList && this.$emit('update:fileList', [ this.changeFileList && this.$emit('update:fileList', [
...this.fileList, ...this.fileList,
{ {

@ -5,10 +5,13 @@ import OssConfig from './config'
import Util from '@/libs/util' import Util from '@/libs/util'
let client = null let client = null
let Oss
// 初始化oss // 初始化oss
const initOss = () => { const initOss = async () => {
if (!client) client = new OSS(OssConfig.config) Oss = await OssConfig()
if (!client) client = new OSS(Oss.config)
} }
initOss()
export default { export default {
// 上传文件 // 上传文件
@ -21,7 +24,7 @@ export default {
resolve({ resolve({
format: Util.getFileExt(file.name), format: Util.getFileExt(file.name),
name: file.name, name: file.name,
url: OssConfig.preUrl + res.name, url: Oss.preUrl + res.name,
size: file.size, size: file.size,
}) })
} catch (error) { } catch (error) {
@ -32,6 +35,6 @@ export default {
// 删除文件(传完整url,不是没有https的name,因为很多接口没有存name,只存url,所以统一使用url) // 删除文件(传完整url,不是没有https的name,因为很多接口没有存name,只存url,所以统一使用url)
async del (url) { async del (url) {
initOss() initOss()
await client.delete(url.replace(OssConfig.preUrl, '')); await client.delete(url.replace(Oss.preUrl, ''));
} }
} }

@ -0,0 +1,50 @@
export default {
difficults: [
{
id: 'basic',
name: '基础',
coefficient: 0.2, // 难度系数,试卷里计算试卷难度专用
theme: 'success',
},
{
id: 'easy',
name: '普通',
coefficient: 0.4,
theme: '',
},
{
id: 'medium',
name: '较难',
coefficient: 0.6,
theme: 'warning',
},
{
id: 'hard',
name: '难',
coefficient: 0.8,
theme: 'danger',
},
],
questionTypes: [
{
id: 'single_choice',
name: '单选题'
},
{
id: 'multiple_choice',
name: '多选题'
},
{
id: 'judgement',
name: '判断题'
},
{
id: 'fill_blank',
name: '填空题'
},
{
id: 'essay',
name: '问答题'
},
],
}

@ -0,0 +1,34 @@
export default {
difficults: [
{
id: 1,
name: '简单'
},
{
id: 2,
name: '普通'
},
{
id: 3,
name: '较难'
},
{
id: 4,
name: '难'
},
],
paperTypes: [
{
id: 0,
name: '练习'
},
{
id: 1,
name: '考核'
},
{
id: 2,
name: '竞赛'
},
],
}

@ -172,6 +172,43 @@ const util = {
resolve(new Date(data.currentTime)) resolve(new Date(data.currentTime))
}) })
}, },
// 阿拉伯数字转化为中文数字
arabicToChinese (num) {
const arr1 = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
const arr2 = ['', '十', '百', '千', '万', '亿', '点', ''];
const a = `${num}`.replace(/(^0*)/g, '').split('.');
let k = 0;
let re = '';
for (let i = a[0].length - 1; i >= 0; i--) {
switch (k) {
case 0:
re = arr2[7] + re;
break;
case 4:
if (!new RegExp(`0{4}//d{${a[0].length - i - 1}}$`).test(a[0])) re = arr2[4] + re;
break;
case 8:
re = arr2[5] + re;
arr2[7] = arr2[5];
k = 0;
break;
default:
}
if (k % 4 == 2 && a[0].charAt(i + 2) != 0 && a[0].charAt(i + 1) == 0) re = arr1[0] + re;
if (a[0].charAt(i) != 0) re = arr1[a[0].charAt(i)] + arr2[k % 4] + re;
k++;
}
return num > 9 && num < 20 ? re.slice(1) : re;
},
// 阿拉伯数字转化为英文字母
numToLetter (num) {
let result = ''
if (num > 26) {
result += numberToLetter((num / 26) >> 0 - 1)
}
result += String.fromCharCode(65 + (num % 26))
return result
},
} }
export default util export default util

@ -19,143 +19,123 @@ let router = new Router({
{ {
path: '/customer', path: '/customer',
component: () => import('../views/customer/customer.vue'), component: () => import('../views/customer/customer.vue'),
// meta: { title: '客户管理' }
}, },
{ {
path: '/addcustomer', path: '/addcustomer',
component: () => import('../views/customer/AddCustomer.vue'), component: () => import('../views/customer/AddCustomer.vue'),
// meta: { title: '新增客户' }
}, },
{ {
path: '/bmOrder', path: '/bmOrder',
component: () => import('../views/customer/Order.vue'), component: () => import('../views/customer/Order.vue'),
// meta: { title: '新增客户' }
}, },
{ {
path: '/user', path: '/user',
component: () => import('../views/user/User.vue'), component: () => import('../views/user/User.vue'),
// meta: { title: '用户管理' }
}, },
{ {
path: '/adduser', path: '/adduser',
component: () => import('../views/user/AddUser.vue'), component: () => import('../views/user/AddUser.vue'),
// meta: { title: '新增用户' }
}, },
{ {
path: '/info', path: '/info',
component: () => import('../views/user/Info.vue'), component: () => import('../views/user/Info.vue'),
// meta: { title: '新增用户' }
}, },
{ {
path: '/order', path: '/order',
component: () => import('../views/order/Order.vue'), component: () => import('../views/order/Order.vue'),
// meta: { title: '订单管理' }
}, },
{ {
path: '/addorder', path: '/addorder',
component: () => import('../views/order/AddOrder.vue'), component: () => import('../views/order/AddOrder.vue'),
// meta: { title: '新增订单' }
}, },
{ {
path: '/selectClient', path: '/selectClient',
component: () => import('../views/order/selectClient.vue'), component: () => import('../views/order/selectClient.vue'),
// meta: { title: '选择订单客户' }
}, },
{ {
path: '/configure', path: '/configure',
component: () => import('../views/serve/Configure.vue'), component: () => import('../views/serve/Configure.vue'),
// meta: { title: '服务配置' }
}, },
{ {
path: '/backstage', path: '/backstage',
component: () => import('../views/serve/backstage'), component: () => import('../views/serve/backstage'),
// meta: { title: '服务配置' }
}, },
{ {
path: '/addModel', path: '/addModel',
component: () => import('../views/serve/addModel'), component: () => import('../views/serve/addModel'),
// meta: { title: '服务配置' }
}, },
{ {
path: '/addconfigure', path: '/addconfigure',
component: () => import('../views/serve/AddConfigure.vue'), component: () => import('../views/serve/AddConfigure.vue'),
// meta: { title: '新增配置' }
}, },
{ {
path: '/projectList', path: '/projectList',
component: () => import('../views/serve/projectList.vue'), component: () => import('../views/serve/projectList.vue'),
// meta: { title: '项目管理' }
}, },
{ {
path: '/projectAdd', path: '/projectAdd',
component: () => import('../views/serve/projectAdd.vue'), component: () => import('../views/serve/projectAdd.vue'),
// meta: { title: '项目配置' }
}, },
{ {
path: '/curriculum', path: '/curriculum',
component: () => import('../views/course/Curriculum.vue'), component: () => import('../views/course/Curriculum.vue'),
// meta: { title: '课程管理' }
}, },
{ {
path: '/addcurriculum', path: '/addcurriculum',
component: () => import('../views/course/AddCurriculum.vue'), component: () => import('../views/course/AddCurriculum.vue'),
// meta: { title: '新建课程' }
}, },
{ {
path: '/contentSettings', path: '/contentSettings',
component: () => import('../views/course/contentSettings.vue'), component: () => import('../views/course/contentSettings.vue'),
// meta: { title: '内容设置' }
}, },
{ {
path: '/addlink', path: '/addlink',
component: () => import('../views/course/AddLink.vue'), component: () => import('../views/course/AddLink.vue'),
// meta: { title: '添加环节' }
}, },
{ {
path: '/data', path: '/data',
component: () => import('../views/data/Data.vue'), component: () => import('../views/data/Data.vue'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/match', path: '/match',
component: () => import('../views/match/list'), component: () => import('../views/match/list'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/addMatch', path: '/addMatch',
component: () => import('../views/match/add'), component: () => import('../views/match/add'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/matchManage', path: '/matchManage',
component: () => import('../views/match/manage'), component: () => import('../views/match/manage'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/noticeDetail', path: '/noticeDetail',
component: () => import('../views/match/manage/noticeDetail'), component: () => import('../views/match/manage/noticeDetail'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/matchArchList', path: '/otherArchList',
component: () => import( '../views/match/manage/matchArchList'), component: () => import('../views/match/manage/otherArchList'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/matchRank', path: '/matchRank',
component: () => import('../views/match/manage/matchRank'), component: () => import('../views/match/manage/matchRank'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/matchReport', path: '/trialReport',
component: () => import( '../views/match/manage/matchReport'), component: () => import('../views/match/manage/trialReport'),
// meta: { title: '数据管理' } },
{
path: '/matchArchList',
component: () => import('../views/match/manage/matchArchList'),
},
{
path: '/theoryReport',
component: () => import('../views/match/manage/theoryReport'),
}, },
{ {
path: '/matchInfo', path: '/matchInfo',
component: () => import('../views/match/manage/matchInfo'), component: () => import('../views/match/manage/matchInfo'),
// meta: { title: '数据管理' }
}, },
{ {
path: `/theoreticalCourse`, path: `/theoreticalCourse`,
@ -190,32 +170,26 @@ let router = new Router({
{ {
path: '/system', path: '/system',
component: () => import('../views/system'), component: () => import('../views/system'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/manageLog', path: '/manageLog',
component: () => import('../views/system/manageLog'), component: () => import('../views/system/manageLog'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/addLog', path: '/addLog',
component: () => import('../views/system/addLog'), component: () => import('../views/system/addLog'),
// meta: { title: '数据管理' }
}, },
{ {
path: '/permission', path: '/permission',
component: () => import('../views/customer/Permission.vue'), component: () => import('../views/customer/Permission.vue'),
// meta: { title: '应用权限', permission: true }
}, },
{ {
path: '/person', path: '/person',
component: () => import('../views/setting'), component: () => import('../views/setting'),
// meta: { title: '个人中心' }
}, },
{ {
path: '/parner', path: '/parner',
component: () => import('../views/parner'), component: () => import('../views/parner'),
// meta: { title: '个人中心' }
}, },
{ {
path: '/parnerOperation', path: '/parnerOperation',
@ -237,6 +211,18 @@ let router = new Router({
path: '/shop/addProduct', path: '/shop/addProduct',
component: () => import('../views/shop/addProduct'), component: () => import('../views/shop/addProduct'),
}, },
{
path: '/theoryExam/list',
component: () => import('../views/theoryExam/list/index'),
},
{
path: '/theoryExam',
component: () => import('../views/theoryExam'),
},
{
path: '/review',
component: () => import('../views/review'),
},
{ {
path: '/404', path: '/404',
component: () => import('../views/404.vue'), component: () => import('../views/404.vue'),

@ -5,20 +5,20 @@ const url = location.host;
const isDev = process.env.NODE_ENV === 'development' // 开发环境 const isDev = process.env.NODE_ENV === 'development' // 开发环境
const isPro = url.includes('huorantech.cn') //正式服 const isPro = url.includes('huorantech.cn') //正式服
let jumpPath = `${location.origin}/judgmentPoint/` let jumpPath = `${location.origin}/panfen/`
let sandPath = `http://121.37.12.51/sandbox` // 沙盘地址 let sandPath = `http://121.37.12.51/sandbox` // 沙盘地址
let host = `${location.origin}/` let host = `${location.origin}/`
if (isDev) { if (isDev) {
console.log("🚀 ~ localStorage.getItem('nakadaiIp'):",localStorage.getItem('nakadaiIp'))
jumpPath = 'http://192.168.31.125:8087/' // 本地调试-需要启动本地判分点系统 jumpPath = 'http://192.168.31.125:8087/' // 本地调试-需要启动本地判分点系统
// jumpPath = 'https://judgment.huorantech.cn/' // jumpPath = 'https://judgment.huorantech.cn/'
sandPath = `http://${location.hostname}:9520` sandPath = `http://${location.hostname}:9520`
host = 'http://121.37.12.51/' host = 'http://121.37.12.51/'
// host = 'https://huorantech.cn/' // host = 'https://huorantech.cn/'
host = localStorage.getItem('nakadaiIp') == 1 ? 'http://192.168.31.51:9000/' : 'http://192.168.31.217:9000/' const ips = ['http://192.168.31.217:9000/', 'http://192.168.31.51:9000/', 'http://121.37.12.51/']
host = ips[+localStorage.getItem('ip')]
} else if (isPro) { } else if (isPro) {
sandPath = `https://izhixinyun.com/sandbox` sandPath = `https://izhixinyun.com/sandbox`
jumpPath = 'https://judgment.huorantech.cn/' // jumpPath = 'https://judgment.huorantech.cn/'
} }

@ -13,9 +13,12 @@ export default {
refreshPageNotification: `nakadai/message/refreshPageNotification`, refreshPageNotification: `nakadai/message/refreshPageNotification`,
heartbeatDetection: `nakadai/message/heartbeatDetection`, heartbeatDetection: `nakadai/message/heartbeatDetection`,
getCurrentTime: `competition/competition/management/getCurrentTime`, getCurrentTime: `competition/competition/management/getCurrentTime`,
getToken: `users/users/user/getToken`,
logout: `users/users/user/logout`,
// 阿里云文件/视频管理 // 阿里云文件/视频管理
getPlayAuth: `${uploadURL}oss/manage/getPlayAuth`, // 获取播放凭证 getPlayAuth: `nakadai/nakadai/oss/getPlayAuth`, // 获取播放凭证
encrypt: `nakadai/data/encrypt`,
staffTemplate: `https://occupationlab.com/template/%E6%89%B9%E9%87%8F%E5%AF%BC%E5%85%A5%E5%91%98%E5%B7%A5%E6%A8%A1%E6%9D%BF.xlsx`, // 后台账号模板 staffTemplate: `https://occupationlab.com/template/%E6%89%B9%E9%87%8F%E5%AF%BC%E5%85%A5%E5%91%98%E5%B7%A5%E6%A8%A1%E6%9D%BF.xlsx`, // 后台账号模板
competionPersonTemplate: `https://huoran.oss-cn-shenzhen.aliyuncs.com/%E4%B8%AD%E5%8F%B0%E4%B8%AA%E4%BA%BA%E8%B5%9B%E6%8A%A5%E5%90%8D%E4%BA%BA%E5%91%98%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xlsx`, // 中台个人报名人员模板 competionPersonTemplate: `https://huoran.oss-cn-shenzhen.aliyuncs.com/%E4%B8%AD%E5%8F%B0%E4%B8%AA%E4%BA%BA%E8%B5%9B%E6%8A%A5%E5%90%8D%E4%BA%BA%E5%91%98%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xlsx`, // 中台个人报名人员模板
@ -36,6 +39,7 @@ export default {
getOrderOtherTime: `nakadai/nakadai/orderOther/getOrderOtherTime`, getOrderOtherTime: `nakadai/nakadai/orderOther/getOrderOtherTime`,
refreshCache: `data/data/myDate/refreshCache`, refreshCache: `data/data/myDate/refreshCache`,
getPartnerTeamRates: `nakadai/nakadai/partner-team/getPartnerTeamRates`, getPartnerTeamRates: `nakadai/nakadai/partner-team/getPartnerTeamRates`,
getCustomerOrderRecord: `nakadai/nakadai/order/getCustomerOrderRecord`,
// 客户管理 // 客户管理
delCustomers: `nakadai/nakadai/customer/delCustomers`, delCustomers: `nakadai/nakadai/customer/delCustomers`,
@ -102,8 +106,8 @@ export default {
editProjectDraft: `occupationlab/occupationlab/projectManage/editProjectDraft`, // 修改项目管理 editProjectDraft: `occupationlab/occupationlab/projectManage/editProjectDraft`, // 修改项目管理
copyProjectManage: `occupationlab/occupationlab/projectManage/copyProjectManage`, // 复制项目管理 copyProjectManage: `occupationlab/occupationlab/projectManage/copyProjectManage`, // 复制项目管理
// 判分点 // 判分点
getBcJudgmentPoint: `${jumpApi}judgment/judgment/bcJudgmentPoint/getBcJudgmentPoint`, // 获取编程类判分点列表(分页) getBcJudgmentPoint: `${host}judgment/judgment/bcJudgmentPoint/getBcJudgmentPoint`, // 获取编程类判分点列表(分页)
getLcJudgmentPoint: `${jumpApi}judgment/judgment/lcJudgmentPoint/queryAllJudgmentPoint`, // 获取流程类判分点列表(分页) getLcJudgmentPoint: `${host}judgment/judgment/lcJudgmentPoint/queryAllJudgmentPoint`, // 获取流程类判分点列表(分页)
addProjectJudgment: `occupationlab/occupationlab/projectJudgment/addProjectJudgment`, // 添加项目管理、判分点中间表 addProjectJudgment: `occupationlab/occupationlab/projectJudgment/addProjectJudgment`, // 添加项目管理、判分点中间表
updateProjectJudgment: `occupationlab/occupationlab/projectJudgment/updateProjectJudgment`, // 判分点中间表批量更新 updateProjectJudgment: `occupationlab/occupationlab/projectJudgment/updateProjectJudgment`, // 判分点中间表批量更新
deleteProjectJudgment: `occupationlab/occupationlab/projectJudgment/deleteProjectJudgment`, // 判分点中间表批量删除 deleteProjectJudgment: `occupationlab/occupationlab/projectJudgment/deleteProjectJudgment`, // 判分点中间表批量删除
@ -337,6 +341,14 @@ export default {
checkTeamStatus: `competition/teamAbnormalInformation/checkTeamStatus`, checkTeamStatus: `competition/teamAbnormalInformation/checkTeamStatus`,
queryAbnormalTeam: `competition/teamAbnormalInformation/queryAbnormalTeam`, queryAbnormalTeam: `competition/teamAbnormalInformation/queryAbnormalTeam`,
viewEventAllocationInformation: `competition/competitionAutomaticAllocationRecord/viewEventAllocationInformation`, viewEventAllocationInformation: `competition/competitionAutomaticAllocationRecord/viewEventAllocationInformation`,
getCompetitionProjectByMiddleGround: `occupationlab/occupationlab/projectManage/getCompetitionProjectByMiddleGround`,
libraryList: `exam/exam/paperLibrary/libraryList`,
examPaperList: `exam/exam/paper/examPaperList`,
copyExamPaper: `exam/exam/paper/copyExamPaper`,
getDetailedExamScores: `exam/exam/paper/getDetailedExamScores`,
exportExamPaperReport: `exam/exam/paper/exportExamPaperReport`,
exportLabReport: `occupationlab/occupationlab/achievement/exportLabReport`,
exportBankExperimentReport: `occupationlab/occupationlab/achievement/exportBankExperimentReport`,
// 赛事内容 // 赛事内容
addCompetitionContent: `competition/competition/content/addCompetitionContent`, addCompetitionContent: `competition/competition/content/addCompetitionContent`,
@ -404,9 +416,12 @@ export default {
batchDeleteContestGrade: `competition/competition/performance/batchDeleteContestGrade`, batchDeleteContestGrade: `competition/competition/performance/batchDeleteContestGrade`,
batchImportGrades: `${host}competition/competition/performance/batchImportGrades`, batchImportGrades: `${host}competition/competition/performance/batchImportGrades`,
exportExperimentalResultsInBatch: `${host}competition/competition/performance/exportExperimentalResultsInBatch`, exportExperimentalResultsInBatch: `${host}competition/competition/performance/exportExperimentalResultsInBatch`,
exportExamPaperReports: `${host}exam/exam/paper/exportExamPaperReports`,
batchExportReportsAsZip: `${host}occupationlab/occupationlab/achievement/batchExportReportsAsZip`,
performanceExportFailure: `${host}competition/competition/performance/exportFailure`, performanceExportFailure: `${host}competition/competition/performance/exportFailure`,
rankExportFailure: `${host}competition/competition/rank/exportFailure`, rankExportFailure: `${host}competition/competition/rank/exportFailure`,
batchImportRanking: `${host}competition/competition/rank/batchImportRanking`, batchImportRanking: `${host}competition/competition/rank/batchImportRanking`,
getPaperUploadFileZip: `${host}exam/exam/paper/question/userAnswer/getPaperUploadFileZip`,
stageGradeManagementList: `competition/competition/performance/stageGradeManagementList`, stageGradeManagementList: `competition/competition/performance/stageGradeManagementList`,
stageRaceRanking: `competition/competition/rank/stageRaceRanking`, stageRaceRanking: `competition/competition/rank/stageRaceRanking`,
overallStandingsInThePointsRace: `competition/competition/rank/overallStandingsInThePointsRace`, overallStandingsInThePointsRace: `competition/competition/rank/overallStandingsInThePointsRace`,
@ -432,6 +447,7 @@ export default {
getCompetitionStageRankingTime: `competition/competitionReleaseTime/getCompetitionStageRankingTime`, getCompetitionStageRankingTime: `competition/competitionReleaseTime/getCompetitionStageRankingTime`,
frontOfficeCompetitionRanking: `competition/competition/rank/frontOfficeCompetitionRanking`, frontOfficeCompetitionRanking: `competition/competition/rank/frontOfficeCompetitionRanking`,
cCompetitionStageFileList: `competition/cCompetitionStageFile/listByEntity`, cCompetitionStageFileList: `competition/cCompetitionStageFile/listByEntity`,
getPaperUploadFile: `exam/exam/paper/question/userAnswer/getPaperUploadFile`,
derive: `${host}competition/cCompetitionStageFile/deriveAll`, derive: `${host}competition/cCompetitionStageFile/deriveAll`,
allExperimentalResultsAreDerived: `${host}competition/competition/performance/allExperimentalResultsAreDerived`, allExperimentalResultsAreDerived: `${host}competition/competition/performance/allExperimentalResultsAreDerived`,
derivedRanking: `${host}competition/competition/rank/derivedRanking`, derivedRanking: `${host}competition/competition/rank/derivedRanking`,

@ -5,10 +5,10 @@ export default {
//skin:'oxide-dark', //skin:'oxide-dark',
language: 'zh_CN', language: 'zh_CN',
language_url: './styles/tinymce/langs/zh_CN.js', language_url: './styles/tinymce/langs/zh_CN.js',
plugins: 'print powerpaste preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template advcode codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help emoticons autosave autoresize formatpainter', plugins: 'print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help emoticons autoresize',
toolbar: 'code undo redo restoredraft | cut copy powerpaste pastetext | forecolor backcolor headings fontsize lineHeight bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify | \ toolbar: 'code undo redo restoredraft | cut copy pastetext | forecolor backcolor headings fontsize lineHeight bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify | \
styleselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \ styleselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \
table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | indent2em formatpainter', table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | indent2em',
style_formats: [ style_formats: [
//新增 首行缩进与行高 配置 //新增 首行缩进与行高 配置
{ {

@ -35,7 +35,7 @@ let logouted = 0;
axios.interceptors.response.use( axios.interceptors.response.use(
response => { response => {
if (response.status === 200) { if (response.status === 200) {
const { status } = response.data const { status, code, msg } = response.data
if (status) { if (status) {
// 接口定义的非正常返回的时候,应当处于报错状态 // 接口定义的非正常返回的时候,应当处于报错状态
if (status === 10020) { if (status === 10020) {
@ -47,6 +47,22 @@ axios.interceptors.response.use(
} else { } else {
return Promise.resolve(response) return Promise.resolve(response)
} }
} else if (code === 401) {
// 账号互踢
if (!logouted) {
sessionStorage.removeItem('token')
Message.error(msg.includes('顶') ? '您的账号已在其他设备登录,您已被迫下线!' : '登录过期,请重新登录!')
setTimeout(() => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
})
logouted = 0
}, 1500)
logouted = 1
}
} else { } else {
return Promise.resolve(response) return Promise.resolve(response)
} }

@ -4,8 +4,7 @@
<v-sidebar></v-sidebar> <v-sidebar></v-sidebar>
<div class="content-box"> <div class="content-box">
<div class="content"> <div class="content">
<transition name="move" <transition name="move" mode="out-in">
mode="out-in">
<!-- <keep-alive> --> <!-- <keep-alive> -->
<router-view></router-view> <router-view></router-view>
<!-- </keep-alive> --> <!-- </keep-alive> -->
@ -32,7 +31,7 @@ export default {
vSidebar, vSidebar,
}, },
created () { created () {
this.autoLogout() // this.autoLogout()
}, },
methods: { methods: {
// ,退 // ,退

@ -9,125 +9,93 @@
<div class="ms-login"> <div class="ms-login">
<div class="ms-title"> <div class="ms-title">
<!-- <p class="title">账号登录</p> --> <!-- <p class="title">账号登录</p> -->
<el-menu :default-active="activeIndex" <el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
class="el-menu-demo"
mode="horizontal"
@select="handleSelect">
<el-menu-item index="1">账号登录</el-menu-item> <el-menu-item index="1">账号登录</el-menu-item>
<el-menu-item index="2">手机号/邮箱登录</el-menu-item> <el-menu-item index="2">手机号/邮箱登录</el-menu-item>
</el-menu> </el-menu>
<el-form v-show="activeIndex==='1'" <el-form v-show="activeIndex === '1'" :model="param" :rules="rules" ref="login" label-width="0px"
:model="param"
:rules="rules"
ref="login"
label-width="0px"
style="margin-top: 20px"> style="margin-top: 20px">
<el-form-item prop="account"> <el-form-item prop="account">
<el-input @blur="blur" <el-input @blur="blur" v-model="param.account" placeholder="请输入账号"></el-input>
v-model="param.account"
placeholder="请输入账号"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
<el-input type="password" <el-input type="password" placeholder="请输入密码" v-model="param.password">
placeholder="请输入密码"
v-model="param.password">
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="code" <el-form-item prop="code" v-if="showVerify">
v-if="showVerify"> <el-input placeholder="请输入验证码" v-model="param.code" @keyup.enter.native="submitForm()">
<el-input placeholder="请输入验证码"
v-model="param.code"
@keyup.enter.native="submitForm()">
</el-input> </el-input>
<img @click="blur" <img @click="blur" :src="verificationIMG" class="verification" alt="">
:src="verificationIMG"
class="verification"
alt="">
</el-form-item> </el-form-item>
<div style="width:100%;display:flex;justify-content: flex-end;"> <div style="width:100%;display:flex;justify-content: flex-end;">
<el-button type="text" <el-button type="text" class="forget">忘记密码?</el-button>
class="forget">忘记密码?</el-button>
</div> </div>
<div class="login-btn"> <div class="login-btn">
<el-button type="primary" <el-button type="primary" @click="submitForm()">马上登录</el-button>
@click="submitForm()">马上登录</el-button>
</div> </div>
</el-form> </el-form>
<el-form v-show="activeIndex==='2'" <el-form v-show="activeIndex === '2'" :model="phoneOrEmail" :rules="phoneOrEmailrules" ref="phoneOrEmail"
:model="phoneOrEmail" label-width="0px" style="margin-top: 20px">
:rules="phoneOrEmailrules"
ref="phoneOrEmail"
label-width="0px"
style="margin-top: 20px">
<el-form-item prop="account"> <el-form-item prop="account">
<el-input @blur="phoneBlur" <el-input @blur="phoneBlur" v-model="phoneOrEmail.workNumber" placeholder="请输入电话/邮箱"></el-input>
v-model="phoneOrEmail.account"
placeholder="请输入电话/邮箱"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
<el-input type="password" <el-input type="password" placeholder="请输入密码" v-model="phoneOrEmail.password">
placeholder="请输入密码"
v-model="phoneOrEmail.password">
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="code" <el-form-item prop="code" v-if="showPhoneVerify">
v-if="showPhoneVerify"> <el-input placeholder="请输入验证码" v-model="phoneOrEmail.code" @keyup.enter.native="submitForm('phone')">
<el-input placeholder="请输入验证码"
v-model="phoneOrEmail.code"
@keyup.enter.native="submitForm('phone')">
</el-input> </el-input>
<img @click="phoneBlur" <img @click="phoneBlur" :src="PhoneVerificationIMG" class="verification" alt="">
:src="PhoneVerificationIMG"
class="verification"
alt="">
</el-form-item> </el-form-item>
<div style="width:100%;display:flex;justify-content: flex-end;"> <div style="width:100%;display:flex;justify-content: flex-end;">
<el-button type="text" <el-button type="text" class="forget">忘记密码?</el-button>
class="forget">忘记密码?</el-button>
</div> </div>
<div class="login-btn"> <div class="login-btn">
<el-button type="primary" <el-button type="primary" @click="submitForm('phone')">马上登录</el-button>
@click="submitForm('phone')">马上登录</el-button>
</div> </div>
</el-form> </el-form>
</div> </div>
</div> </div>
<el-dialog title="绑定手机号" <el-dialog title="绑定手机号" :visible.sync="phoneVisible" :close-on-click-modal="false" width="576px">
:visible.sync="phoneVisible"
:close-on-click-modal="false"
width="576px">
<p class="tips">依据国家政策法规需绑定手机号进行网络实名才可登录使用本平台</p> <p class="tips">依据国家政策法规需绑定手机号进行网络实名才可登录使用本平台</p>
<el-form ref="form" <el-form ref="form" label-width="60px">
label-width="60px">
<el-form-item label="手机号"> <el-form-item label="手机号">
<el-input placeholder="请输入手机号" <el-input placeholder="请输入手机号" v-model="phone" maxlength="11"></el-input>
v-model="phone"
maxlength="11"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="验证码"> <el-form-item label="验证码">
<div style="display:flex;"> <div style="display:flex;">
<el-input v-model="phoneCode" <el-input v-model="phoneCode" placeholder="请输入验证码" maxlength="6"></el-input>
placeholder="请输入验证码" <el-button style="margin-left:10px" @click="sendPhoneCode" :disabled="phoneDisabled">{{ phoneBtnText
maxlength="6"></el-input> }}</el-button>
<el-button style="margin-left:10px"
@click="sendPhoneCode"
:disabled="phoneDisabled">{{phoneBtnText}}</el-button>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="phoneVisible = false"> </el-button> <el-button @click="phoneVisible = false"> </el-button>
<el-button type="primary" <el-button type="primary" @click="phoneSubmit"> </el-button>
@click="phoneSubmit"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
<v-footer class="footer"
ref="footer"></v-footer>
<el-dialog title="请选择您要登录的用户" :visible.sync="userVisible" :close-on-click-modal="false" custom-class="user-dia"
width="500px">
<p class="tips">该手机号已绑定以下用户信息</p>
<ul class="users">
<li :class="{ isEnable: !user.isEnable }" v-for="(user, i) in users" :key="i" @click="chooseUser(user)">
<span>{{ user.schoolName }}{{ user.userName }}{{ user.workNumber }}{{
user.isEnable
? ''
: '(已禁用)' }}</span>
<i class="el-icon-right"></i>
</li>
</ul>
</el-dialog>
<v-footer class="footer" ref="footer"></v-footer>
</div> </div>
</template> </template>
@ -135,6 +103,8 @@
import vFooter from '../components/Footer' import vFooter from '../components/Footer'
import Setting from '@/setting' import Setting from '@/setting'
import addRoutes from '@/libs/route/addRoutes' import addRoutes from '@/libs/route/addRoutes'
import CryptoJS from 'crypto-js'
import JSEncrypt from 'jsencrypt'
export default { export default {
data: function () { data: function () {
var regPhoneOrEmail = (rule, value, callback) => {// var regPhoneOrEmail = (rule, value, callback) => {//
@ -162,7 +132,6 @@ export default {
platform: 3, platform: 3,
random: '', random: '',
distinguish: 1, distinguish: 1,
type: 2
}, },
rules: { rules: {
account: [{ required: true, message: '请输入账号', trigger: 'blur' }], account: [{ required: true, message: '请输入账号', trigger: 'blur' }],
@ -174,16 +143,15 @@ export default {
showPhoneVerify: true,// - showPhoneVerify: true,// -
PhoneVerificationIMG: '',// PhoneVerificationIMG: '',//
phoneOrEmail: { phoneOrEmail: {
account: '', workNumber: '',
password: '', password: '',
code: '', code: '',
platform: 3, platform: 3,
random: '', random: '',
distinguish: 2, distinguish: 1,
type: 2
}, },
phoneOrEmailrules: { phoneOrEmailrules: {
account: [{ validator: regPhoneOrEmail, trigger: 'blur' }], workNumber: [{ validator: regPhoneOrEmail, trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }], password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
code: [{ required: true, message: '请输入验证码', trigger: 'blur' }], code: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
}, },
@ -194,8 +162,11 @@ export default {
phoneDisabled: false, phoneDisabled: false,
phoneBtnText: '发送验证码', phoneBtnText: '发送验证码',
phoneTimer: '', phoneTimer: '',
phoneOpener: '' phoneOpener: '',
userVisible: false,
users: [],
}; };
}, },
components: { components: {
@ -229,27 +200,29 @@ export default {
let param = val === 'phone' ? this.phoneOrEmail : this.param let param = val === 'phone' ? this.phoneOrEmail : this.param
this.$refs[ref].validate(valid => { this.$refs[ref].validate(valid => {
if (valid) { if (valid) {
this.$post(this.api.logins, param).then(res => { this.$post(this.api.logins, param).then(({ status, data, message }) => {
const { message } = res localStorage.removeItem('examPath')
sessionStorage.setItem('token', res.data.token) localStorage.removeItem('reviewPath')
this.$get(`${this.api.getUserRolesPermissionMenu}?platformId=${Setting.platformId}`).then(res => { this.getOss()
const list = res.permissionMenu if (status == 200) {
addRoutes(res.permissionMenu[0].children) const accounts = data.userAccounts
this.$store.commit('setDataPer', res.dataPermissionList) //
this.$message.success(message); if (accounts instanceof Array) {
this.$router.push({ this.users = accounts
path: list[0].children[0].path this.userVisible = true
}); } else {
localStorage.setItem('ms_username', this.param.username); sessionStorage.setItem('token', data.token)
}).catch(err => { this.setLogin()
if (err.status === 500) { }
sessionStorage.clear() } else {
param.code = ''
this.$message.error(message)
} }
})
}).catch(err => { }).catch(err => {
if (err.status === 30001) { if (err.status === 30001) {
this.phoneVisible = true this.phoneVisible = true
} else if (err.status == 10004) { } else if (err.status == 10004 || err.status == 10005) {
param.code = ''
this.blur() this.blur()
} }
}); });
@ -258,7 +231,54 @@ export default {
return false; return false;
} }
}); });
},
// oss
async getOss () {
const A = (key, encryptedData) => {
const keyHex = CryptoJS.enc.Base64.parse(key)
const decrypted = CryptoJS.AES.decrypt(encryptedData, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
})
return decrypted.toString(CryptoJS.enc.Utf8)
}
const R = (encryptedKey, privateKey) => {
const decrypt = new JSEncrypt()
decrypt.setPrivateKey(privateKey)
const decryptedKey = decrypt.decrypt(encryptedKey)
return decryptedKey
}
const res = await this.$get(this.api.encrypt)
const RE = A(R(res.encryptedKey, res.privateKey), res.encryptedData).split('/')
localStorage.setItem('osc', JSON.stringify(RE))
},
//
chooseUser (user) {
user.isEnable && this.$post(`${this.api.getToken}?id=${user.id}`).then(({ data }) => {
sessionStorage.setItem('token', data.token)
this.token = data.token
this.setLogin()
}).catch(res => { })
},
//
async setLogin () {
try {
const res = await this.$get(`${this.api.getUserRolesPermissionMenu}?platformId=${Setting.platformId}`)
const list = res.permissionMenu
addRoutes(res.permissionMenu[0].children)
this.$store.commit('setDataPer', res.dataPermissionList)
this.$message.success('登录成功!')
this.$router.push({
path: list[0].children[0].path
});
localStorage.setItem('ms_username', this.param.username);
} catch (e) {
if (e.status === 500) {
sessionStorage.clear()
}
}
}, },
blur () { blur () {
this.param.random = Math.floor(Math.random() * 999999999) this.param.random = Math.floor(Math.random() * 999999999)
@ -348,6 +368,7 @@ export default {
background-image: url(../assets/img/login-bg.png); background-image: url(../assets/img/login-bg.png);
background-size: 100%; background-size: 100%;
} }
.ms-title { .ms-title {
width: 548px; width: 548px;
position: absolute; position: absolute;
@ -355,6 +376,7 @@ export default {
top: 30px; top: 30px;
transform: translate(-50%, 0); transform: translate(-50%, 0);
} }
/deep/ .ms-login { /deep/ .ms-login {
position: relative; position: relative;
width: 1200px; width: 1200px;
@ -364,12 +386,14 @@ export default {
box-shadow: 0px 0px 79px 0px rgba(11, 15, 65, 0.36); box-shadow: 0px 0px 79px 0px rgba(11, 15, 65, 0.36);
background-repeat: no-repeat; background-repeat: no-repeat;
overflow: hidden; overflow: hidden;
.el-input__inner { .el-input__inner {
height: 80px; height: 80px;
line-height: 80px; line-height: 80px;
border: 1px solid rgba(220, 220, 220, 1); border: 1px solid rgba(220, 220, 220, 1);
border-radius: 2px; border-radius: 2px;
} }
.verification { .verification {
position: absolute; position: absolute;
top: 1px; top: 1px;
@ -379,14 +403,17 @@ export default {
cursor: pointer; cursor: pointer;
} }
} }
.title { .title {
font-size: 16px; font-size: 16px;
text-align: center; text-align: center;
font-weight: bold; font-weight: bold;
} }
.login-btn { .login-btn {
text-align: center; text-align: center;
} }
.login-btn button { .login-btn button {
width: 100%; width: 100%;
height: 88px; height: 88px;
@ -396,20 +423,24 @@ export default {
box-shadow: 0px 7px 27px 0px rgba(50, 129, 255, 0.51); box-shadow: 0px 7px 27px 0px rgba(50, 129, 255, 0.51);
border-radius: 10px; border-radius: 10px;
} }
.login-tips { .login-tips {
text-align: center; text-align: center;
color: #999; color: #999;
font-weight: bold; font-weight: bold;
} }
.forget { .forget {
margin-bottom: 28px; margin-bottom: 28px;
text-align: right; text-align: right;
color: #999; color: #999;
font-weight: bold; font-weight: bold;
&:hover { &:hover {
color: #0092ff; color: #0092ff;
} }
} }
.thirdParty { .thirdParty {
width: 100%; width: 100%;
display: flex; display: flex;
@ -426,27 +457,33 @@ export default {
align-items: center; align-items: center;
font-size: 18px; font-size: 18px;
} }
.logo { .logo {
width: 171px; width: 171px;
height: 40px; height: 40px;
margin-left: 20px; margin-left: 20px;
} }
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.header_title { .header_title {
width: 33%; width: 33%;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
} }
.header_title a { .header_title a {
cursor: pointer; cursor: pointer;
} }
.header_title a:hover { .header_title a:hover {
color: blueviolet; color: blueviolet;
} }
.nul { .nul {
width: 80px; width: 80px;
margin-right: 30px; margin-right: 30px;
@ -458,26 +495,72 @@ img {
border-bottom: 0; border-bottom: 0;
background-color: transparent; background-color: transparent;
} }
.tips { .tips {
margin: -20px 0 20px 5px; margin: -20px 0 20px 5px;
font-size: 14px; font-size: 14px;
text-align: center; text-align: center;
color: #666; color: #666;
} }
/deep/.user-dia {
.tips {
margin-bottom: 20px;
text-align: center;
color: #666;
}
.users {
li {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 15px;
margin-bottom: 10px;
line-height: 40px;
font-size: 14px;
background-color: #ebeef5;
cursor: pointer;
&.isEnable {
color: #c0c4cc;
background-color: #f5f7fa;
cursor: not-allowed;
}
&:last-child {
margin-bottom: 0;
}
&:hover {
background-color: #d3e0ff;
}
i {
font-size: 16px;
}
}
}
}
@media (max-width: 1600px) { @media (max-width: 1600px) {
/deep/.ms-login { /deep/.ms-login {
width: 1000px; width: 1000px;
.el-input__inner { .el-input__inner {
height: 50px; height: 50px;
line-height: 50px; line-height: 50px;
} }
.verification { .verification {
height: 48px; height: 48px;
} }
} }
.ms-title { .ms-title {
width: 480px; width: 480px;
} }
.login-btn button { .login-btn button {
height: 60px; height: 60px;
} }

@ -2,28 +2,19 @@
<div> <div>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="24"> <el-col :span="24">
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="flex-between"> <div class="flex-between">
<div class="per_title" <div class="per_title" v-preventReClick @click="back">
v-preventReClick
@click="back">
<i class="el-icon-arrow-left"></i> <i class="el-icon-arrow-left"></i>
<span class="per_back">返回</span> <span class="per_back">返回</span>
<span class="per_school" <span class="per_school" v-text="form.cid ? '编辑课程' : '新建课程'"></span>
v-text="form.cid ? '编辑课程' : '新建课程'"></span>
</div> </div>
<el-button type="primary" <el-button type="primary" round class="mag" v-preventReClick @click="saveAdd">确定
round
class="mag"
v-preventReClick
@click="saveAdd">确定
</el-button> </el-button>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20 ">
class="mgb20 ">
<div class="flex-center mgb20"> <div class="flex-center mgb20">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>课程信息</span> <span>课程信息</span>
@ -31,112 +22,65 @@
<div class="border-b-dashed"></div> <div class="border-b-dashed"></div>
<div> <div>
<el-form :model="form" <el-form :model="form" :rules="rules" ref="form" label-width="100px">
:rules="rules" <el-col :span="6" :offset="5">
ref="form" <el-form-item label="课程名称" prop="curriculumName">
label-width="100px"> <el-input placeholder="请输入课程名称" v-model.trim="form.curriculumName"></el-input>
<el-col :span="6"
:offset="5">
<el-form-item label="课程名称"
prop="curriculumName">
<el-input placeholder="请输入课程名称"
v-model.trim="form.curriculumName"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="学科类别" <el-form-item label="学科类别" prop="categoryId">
prop="categoryId"> <el-select v-model="form.categoryId" clearable placeholder="请选择学科类别" @change="getProfessionalClass()"
<el-select v-model="form.categoryId"
clearable
placeholder="请选择学科类别"
@change="getProfessionalClass()"
@clear="clearsubjectType()"> @clear="clearsubjectType()">
<el-option v-for="(item,index) in subjectList" <el-option v-for="(item, index) in subjectList" :key="index" :label="item.disciplineName"
:key="index"
:label="item.disciplineName"
:value="item.disciplineId"></el-option> :value="item.disciplineId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="专业" <el-form-item label="专业" prop="professionalId">
prop="professionalId"> <el-select v-model="form.professionalId" clearable placeholder="请选择专业"
<el-select v-model="form.professionalId"
clearable
placeholder="请选择专业"
:disabled="form.professionalCategoryId ? false : true"> :disabled="form.professionalCategoryId ? false : true">
<el-option v-for="(item,index) in ProfessionalList" <el-option v-for="(item, index) in ProfessionalList" :key="index" :label="item.professionalName"
:key="index"
:label="item.professionalName"
:value="item.professionalId"></el-option> :value="item.professionalId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="供应厂商" <el-form-item label="供应厂商" prop="supplier">
prop="supplier"> <el-select v-model="form.supplier" clearable placeholder="请选择供应厂商" multiple>
<el-select v-model="form.supplier" <el-option v-for="(item, i) in suppliers" :key="i" :label="item.supplierName"
clearable
placeholder="请选择供应厂商"
multiple>
<el-option v-for="(item, i) in suppliers"
:key="i"
:label="item.supplierName"
:value="item.supplierId"></el-option> :value="item.supplierId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6" <el-col :span="6" :offset="2">
:offset="2"> <el-form-item label="课程类别" prop="curriculumType">
<el-form-item label="课程类别" <el-select v-model="form.curriculumType" clearable placeholder="请选择课程类型">
prop="curriculumType"> <el-option label="理论课程" :value="0"></el-option>
<el-select v-model="form.curriculumType" <el-option label="实训课程" :value="1"></el-option>
clearable
placeholder="请选择课程类型">
<el-option label="理论课程"
:value="0"></el-option>
<el-option label="实训课程"
:value="1"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="专业类" <el-form-item label="专业类" prop="professionalCategoryId">
prop="professionalCategoryId"> <el-select v-model="form.professionalCategoryId" clearable placeholder="请选择专业类"
<el-select v-model="form.professionalCategoryId" :disabled="form.categoryId ? false : true" @change="getProfessional()"
clearable
placeholder="请选择专业类"
:disabled="form.categoryId ? false : true"
@change="getProfessional()"
@clear="clearProfessionalClass()"> @clear="clearProfessionalClass()">
<el-option v-for="(item,index) in ProfessionalClassList" <el-option v-for="(item, index) in ProfessionalClassList" :key="index"
:key="index" :label="item.professionalClassName" :value="item.professionalClassId"></el-option>
:label="item.professionalClassName"
:value="item.professionalClassId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="预计课时" <el-form-item label="预计课时" prop="expectedCourse">
prop="expectedCourse"> <el-select v-model="form.expectedCourse" clearable placeholder="请选择预计课时">
<el-select v-model="form.expectedCourse" <el-option label="32课时" value="32课时"></el-option>
clearable <el-option label="64课时" value="64课时"></el-option>
placeholder="请选择预计课时">
<el-option label="32课时"
value="32课时"></el-option>
<el-option label="64课时"
value="64课时"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="14" <el-col :span="14" :offset="5">
:offset="5"> <el-form-item label="课程简介" prop="briefIntroduction">
<el-form-item label="课程简介" <el-input type="textarea" :autosize="{ minRows: 4 }" placeholder="请输入课程简介"
prop="briefIntroduction">
<el-input type="textarea"
:autosize="{ minRows: 4 }"
placeholder="请输入课程简介"
v-model.trim="form.briefIntroduction"></el-input> v-model.trim="form.briefIntroduction"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="教学目标" <el-form-item label="教学目标" prop="teachingObjectives">
prop="teachingObjectives"> <el-input type="textarea" :autosize="{ minRows: 4 }" placeholder="请输入教学目标"
<el-input type="textarea"
:autosize="{ minRows: 4 }"
placeholder="请输入教学目标"
v-model.trim="form.teachingObjectives"></el-input> v-model.trim="form.teachingObjectives"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -145,8 +89,7 @@
</el-card> </el-card>
<!-- 练习项目配置 --> <!-- 练习项目配置 -->
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="mgb20 flex-between"> <div class="mgb20 flex-between">
<div class="flex-center "> <div class="flex-center ">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
@ -154,61 +97,36 @@
</div> </div>
<div> <div>
<el-button @click="handleBatchDelete(0)">批量移除</el-button> <el-button @click="handleBatchDelete(0)">批量移除</el-button>
<el-button @click="handleConfig(0)" <el-button @click="handleConfig(0)" icon="el-icon-plus" circle></el-button>
icon="el-icon-plus"
circle></el-button>
</div> </div>
</div> </div>
<div class="border-b-dashed"></div> <div class="border-b-dashed"></div>
<div> <div>
<el-table :data="practiceData" <el-table :data="practiceData" class="table" stripe header-align="center" max-height="400"
class="table"
stripe
header-align="center"
max-height="400"
@selection-change="handleSelectionPractice"> @selection-change="handleSelectionPractice">
<el-table-column type="selection" <el-table-column type="selection" width="55" align="center"></el-table-column>
width="55" <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
align="center"></el-table-column> <el-table-column prop="projectName" label="项目名称" align="center">
<el-table-column type="index"
width="100"
label="序号"
align="center"></el-table-column>
<el-table-column prop="projectName"
label="项目名称"
align="center"></el-table-column>
<el-table-column prop="remark"
label="备注名称"
align="center"></el-table-column>
<el-table-column prop="applicationName"
label="系统名称"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }} {{ scope.row.projectName || scope.row.paperName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="排序" <el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
align="center" <el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
width="100"> <el-table-column label="排序" align="center" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-model.trim="scope.row.sort" <el-input v-model.trim="scope.row.sort"
@input="practiceSortChange(scope.row, scope.$index)"></el-input> @input="practiceSortChange(scope.row, scope.$index)"></el-input>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="展示控制" <el-table-column label="展示控制" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch v-model="scope.row.isShow" <el-switch v-model="scope.row.isShow" :active-value="0" :inactive-value="1"
:active-value="0"
:inactive-value="1"
:disabled="scope.row.disabled"> :disabled="scope.row.disabled">
</el-switch> </el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button :disabled="scope.row.disabled" <el-button :disabled="scope.row.disabled"
@click.native.prevent="handleDelete(scope.$index, practiceData)">移除 @click.native.prevent="handleDelete(scope.$index, practiceData)">移除
@ -220,8 +138,7 @@
</el-card> </el-card>
<!-- 考核项目配置 --> <!-- 考核项目配置 -->
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="mgb20 flex-between"> <div class="mgb20 flex-between">
<div class="flex-center "> <div class="flex-center ">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
@ -229,62 +146,37 @@
</div> </div>
<div> <div>
<el-button @click="handleBatchDelete(1)">批量移除</el-button> <el-button @click="handleBatchDelete(1)">批量移除</el-button>
<el-button @click="handleConfig(1)" <el-button @click="handleConfig(1)" icon="el-icon-plus" circle></el-button>
icon="el-icon-plus"
circle></el-button>
</div> </div>
</div> </div>
<div class="border-b-dashed"></div> <div class="border-b-dashed"></div>
<!-- 实训配置 --> <!-- 实训配置 -->
<div> <div>
<el-table :data="assessmentData" <el-table :data="assessmentData" class="table" stripe header-align="center" max-height="400"
class="table"
stripe
header-align="center"
max-height="400"
@selection-change="handleSelectionAssessment"> @selection-change="handleSelectionAssessment">
<el-table-column type="selection" <el-table-column type="selection" width="55" align="center"></el-table-column>
width="55" <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
align="center"></el-table-column> <el-table-column prop="projectName" label="项目名称" align="center">
<el-table-column type="index"
width="100"
label="序号"
align="center"></el-table-column>
<el-table-column prop="projectName"
label="项目名称"
align="center"></el-table-column>
<el-table-column prop="remark"
label="备注名称"
align="center"></el-table-column>
<el-table-column prop="applicationName"
label="系统名称"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }} {{ scope.row.projectName || scope.row.paperName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="排序" <el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
align="center" <el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
width="100"> <el-table-column label="排序" align="center" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-model.trim="scope.row.sort" <el-input v-model.trim="scope.row.sort"
@input="assessmentSortChange(scope.row, scope.$index)"></el-input> @input="assessmentSortChange(scope.row, scope.$index)"></el-input>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="展示控制" <el-table-column label="展示控制" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch v-model="scope.row.isShow" <el-switch v-model="scope.row.isShow" :active-value="0" :inactive-value="1"
:active-value="0"
:inactive-value="1"
:disabled="scope.row.disabled"> :disabled="scope.row.disabled">
</el-switch> </el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button :disabled="scope.row.disabled" <el-button :disabled="scope.row.disabled"
@click.native.prevent="handleDelete(scope.$index, assessmentData)">移除</el-button> @click.native.prevent="handleDelete(scope.$index, assessmentData)">移除</el-button>
@ -295,8 +187,7 @@
</el-card> </el-card>
<!-- 大赛项目配置 --> <!-- 大赛项目配置 -->
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="mgb20 flex-between"> <div class="mgb20 flex-between">
<div class="flex-center "> <div class="flex-center ">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
@ -304,59 +195,36 @@
</div> </div>
<div> <div>
<el-button @click="handleBatchDelete(2)">批量移除</el-button> <el-button @click="handleBatchDelete(2)">批量移除</el-button>
<el-button @click="handleConfig(2)" <el-button @click="handleConfig(2)" icon="el-icon-plus" circle></el-button>
icon="el-icon-plus"
circle></el-button>
</div> </div>
</div> </div>
<div class="border-b-dashed"></div> <div class="border-b-dashed"></div>
<!-- 实训配置 --> <!-- 实训配置 -->
<div> <div>
<el-table :data="matches" <el-table :data="matches" class="table" stripe header-align="center" max-height="400"
class="table"
stripe
header-align="center"
max-height="400"
@selection-change="handleSelectionMatch"> @selection-change="handleSelectionMatch">
<el-table-column type="selection" <el-table-column type="selection" width="55" align="center"></el-table-column>
width="55" <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
align="center"></el-table-column> <el-table-column prop="projectName" label="项目名称" align="center">
<el-table-column type="index"
width="100"
label="序号"
align="center"></el-table-column>
<el-table-column prop="projectName"
label="项目名称"
align="center"></el-table-column>
<el-table-column prop="applicationName"
label="系统名称"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }} {{ scope.row.projectName || scope.row.paperName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="排序" <el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
align="center" <el-table-column label="排序" align="center" width="100">
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-model.trim="scope.row.sort" <el-input v-model.trim="scope.row.sort"
@input="assessmentSortChange(scope.row, scope.$index)"></el-input> @input="assessmentSortChange(scope.row, scope.$index)"></el-input>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="展示控制" <el-table-column label="展示控制" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch v-model="scope.row.isShow" <el-switch v-model="scope.row.isShow" :active-value="0" :inactive-value="1"
:active-value="0"
:inactive-value="1"
:disabled="scope.row.disabled"> :disabled="scope.row.disabled">
</el-switch> </el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button :disabled="scope.row.disabled" <el-button :disabled="scope.row.disabled"
@click.native.prevent="handleDelete(scope.$index, matches)">移除</el-button> @click.native.prevent="handleDelete(scope.$index, matches)">移除</el-button>
@ -370,29 +238,20 @@
</el-row> </el-row>
<!-- 配置弹窗 --> <!-- 配置弹窗 -->
<el-dialog :visible.sync="configVisible" <el-dialog :visible.sync="configVisible" width="1200px" center custom-class="config-dia">
width="1200px"
center
custom-class="config-dia">
<div class="config-wrap"> <div class="config-wrap">
<div class="item system"> <div class="item system">
<div class="title-wrap flex-center"> <div class="title-wrap flex-center">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>系统列表</span> <span>系统列表</span>
</div> </div>
<el-input placeholder="请输入系统名称" <el-input placeholder="请输入系统名称" prefix-icon="el-icon-search" v-model.trim="systemKeyword"
prefix-icon="el-icon-search"
v-model.trim="systemKeyword"
clearable></el-input> clearable></el-input>
<ul class="systems"> <ul class="systems">
<li v-for="(item, i) in systems" <li v-for="(item, i) in systems" :key="i" :title="item.systemName">
:key="i" <el-checkbox v-model="item.check" @change="val => systemChange(val, item)"></el-checkbox>
:title="item.systemName"> <div :class="['name', { active: curSystem == item.systemId }]" @click="getProject(item)">
<el-checkbox v-model="item.check"
@change="val => systemChange(val, item)"></el-checkbox>
<div :class="['name', {active: curSystem == item.systemId}]"
@click="getProject(item)">
<span>{{ item.systemName }}</span> <span>{{ item.systemName }}</span>
<i class="el-icon-arrow-right"></i> <i class="el-icon-arrow-right"></i>
</div> </div>
@ -405,21 +264,15 @@
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>项目列表</span> <span>项目列表</span>
</div> </div>
<el-input placeholder="请输入项目名称" <el-input placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model.trim="projectKeyword"
prefix-icon="el-icon-search"
v-model.trim="projectKeyword"
clearable></el-input> clearable></el-input>
<ul class="systems"> <ul class="systems">
<el-checkbox v-if="projects.length" <el-checkbox v-if="projects.length" v-model="checkAll" label="全选"
v-model="checkAll"
label="全选"
@change="val => checkAllChange(val, projects[0].systemId)"></el-checkbox> @change="val => checkAllChange(val, projects[0].systemId)"></el-checkbox>
<li v-for="(item, i) in projects" <li v-for="(item, i) in projects" :key="i" :title="item.projectName">
:key="i"
:title="item.projectName">
<el-checkbox v-model="item.check" <el-checkbox v-model="item.check"
:label="item.remark ? item.remark + '(' + item.projectName + ')' : item.projectName" :label="item.remark ? item.remark + '(' + item.projectName + ')' : (item.projectName || item.paperName)"
@change="val => projectChange(val, item)"></el-checkbox> @change="val => projectChange(val, item)"></el-checkbox>
</li> </li>
</ul> </ul>
@ -430,44 +283,23 @@
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>已选择项目{{ checkeds.length }}</span> <span>已选择项目{{ checkeds.length }}</span>
</div> </div>
<el-input style="width: 200px;margin-bottom: 20px;" <el-input style="width: 200px;margin-bottom: 20px;" placeholder="请输入项目名称" prefix-icon="el-icon-search"
placeholder="请输入项目名称" v-model.trim="checkedKeyword" clearable></el-input>
prefix-icon="el-icon-search" <el-table :data="checkeds" class="table" stripe header-align="center" max-height="470">
v-model.trim="checkedKeyword" <el-table-column type="index" width="55" label="序号" align="center"></el-table-column>
clearable></el-input> <el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
<el-table :data="checkeds" <el-table-column prop="projectName" width="80" label="系统类型" align="center">
class="table"
stripe
header-align="center"
max-height="470">
<el-table-column type="index"
width="55"
label="序号"
align="center"></el-table-column>
<el-table-column prop="applicationName"
label="系统名称"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }} {{ scope.row.type === 1 ? '流程类' : scope.row.type === 3 ? '理论' : '编程类' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="projectName" <el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
width="80" <el-table-column prop="projectName" label="项目名称" align="center">
label="系统类型"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.type ? '流程类' : '编程类' }} {{ scope.row.projectName || scope.row.paperName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="remark" <el-table-column label="操作" align="center" width="55">
label="备注名称"
align="center"></el-table-column>
<el-table-column prop="projectName"
label="项目名称"
align="center"></el-table-column>
<el-table-column label="操作"
align="center"
width="55">
<template slot-scope="scope"> <template slot-scope="scope">
<i :class="['el-icon-delete rm', { disabled: scope.row.disabled }]" <i :class="['el-icon-delete rm', { disabled: scope.row.disabled }]"
@click="delProject(scope.$index, scope.row)"></i> @click="delProject(scope.$index, scope.row)"></i>
@ -477,11 +309,9 @@
</div> </div>
</div> </div>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="configVisible = false"> </el-button> <el-button @click="configVisible = false"> </el-button>
<el-button type="primary" <el-button type="primary" @click="handleConfirm"> </el-button>
@click="handleConfirm"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
@ -585,7 +415,6 @@ export default {
systemChecked: [], systemChecked: [],
curSystem: '', curSystem: '',
projects: [], projects: [],
projectAll: [],
projectKeyword: '', projectKeyword: '',
checkedKeyword: '', checkedKeyword: '',
checkeds: [], checkeds: [],
@ -612,7 +441,7 @@ export default {
projectKeyword: function (val) { projectKeyword: function (val) {
clearTimeout(this.searchTimer); clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => { this.searchTimer = setTimeout(() => {
this.filterProject(); this.getProject();
}, 500); }, 500);
}, },
checkedKeyword: function (val) { checkedKeyword: function (val) {
@ -747,6 +576,7 @@ export default {
this.pageNo = 1; this.pageNo = 1;
this.getConfig(); this.getConfig();
this.checkeds = JSON.parse(JSON.stringify(type == 1 ? this.assessmentData : type == 2 ? this.matches : this.practiceData)) this.checkeds = JSON.parse(JSON.stringify(type == 1 ? this.assessmentData : type == 2 ? this.matches : this.practiceData))
this.checkedAll = JSON.parse(JSON.stringify(this.checkeds))
}, },
// //
getConfig () { getConfig () {
@ -779,26 +609,23 @@ export default {
}).catch(err => { }) }).catch(err => { })
}, },
// //
getProject (item) { async getProject (item, fromSystemChange) {
const checked = this.checkeds const checked = this.checkeds
this.curSystem = item.systemId if (item) this.curSystem = item.systemId
this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${item.systemId}`).then(res => { let res
this.projectAll = JSON.parse(JSON.stringify(res)) // if (!fromSystemChange) {
res = await this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${this.curSystem}&keyword=${this.projectKeyword}`)
}
const result = [] const result = []
res.map(e => { const projects = fromSystemChange ? this.projects : res
projects.map(e => {
// //
const include = checked.some(n => n.projectId == e.projectId && n.systemId == e.systemId) const include = checked.some(n => (e.projectId && n.projectId == e.projectId && n.systemId == e.systemId) || (e.paperId && n.paperId == e.paperId))
e.check = include e.check = include
result.push(e) result.push(e)
}) })
this.checkAll = !result.filter(e => !e.check).length this.checkAll = !result.filter(e => !e.check).length
this.projects = result this.projects = result
}).catch(err => { })
},
//
filterProject () {
const val = this.projectKeyword
this.projects = this.projectAll.filter(e => e.projectName.includes(val))
}, },
// //
systemChange (val, item) { systemChange (val, item) {
@ -810,7 +637,7 @@ export default {
}) })
} }
this.projectKeyword = '' this.projectKeyword = ''
this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${item.systemId}`).then(res => { this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${item.systemId}&keyword=${this.projectKeyword}`).then(res => {
if (val) { if (val) {
// //
if (!this.mulSystem) { if (!this.mulSystem) {
@ -818,18 +645,18 @@ export default {
item.check = true item.check = true
} }
res.map(e => { res.map(e => {
if (!checkeds.find(n => n.projectId == e.projectId && n.systemId == e.systemId)) { if (!checkeds.find(n => (e.projectId && n.projectId == e.projectId && n.systemId == e.systemId) || (e.paperId && e.paperId == n.paperId))) {
checkeds.push(e) checkeds.push(e)
} }
}) })
} else { } else {
res.map(e => { res.map(e => {
const i = checkeds.findIndex(n => n.projectId == e.projectId && n.systemId == e.systemId) const i = checkeds.findIndex(n => (e.projectId && n.projectId == e.projectId && n.systemId == e.systemId) || (e.paperId && e.paperId == n.paperId))
i === -1 || checkeds.splice(i, 1) i === -1 || checkeds.splice(i, 1)
}) })
} }
this.checkedAll = JSON.parse(JSON.stringify(checkeds)) // this.checkedAll = JSON.parse(JSON.stringify(checkeds)) //
this.getProject(item) this.getProject(item, 1)
}).catch(err => { }) }).catch(err => { })
}, },
// //
@ -841,8 +668,8 @@ export default {
}, },
// //
projectChange (val, item) { projectChange (val, item) {
const { systemId } = item const { systemId, paperId } = item
const i = this.checkeds.findIndex(e => e.projectId == item.projectId && e.systemId == systemId) const i = this.checkeds.findIndex(e => (item.projectId && e.projectId == item.projectId && e.systemId == systemId) || (paperId && paperId == e.paperId))
// push // push
if (val) { if (val) {
this.checkeds.push(item) this.checkeds.push(item)
@ -855,12 +682,11 @@ export default {
}) })
this.checkAll = !this.projects.find(e => !e.check) // this.checkAll = !this.projects.find(e => !e.check) //
this.checkedAll = JSON.parse(JSON.stringify(this.checkeds)) // this.checkedAll = JSON.parse(JSON.stringify(this.checkeds)) //
console.log("🚀 ~ file: AddCurriculum.vue ~ line 728 ~ projectChange ~ checkedAll", this.checkeds, item)
}, },
// //
filterChecked () { filterChecked () {
const val = this.checkedKeyword const val = this.checkedKeyword
this.checkeds = this.checkedAll.filter(e => e.projectName.includes(val)) this.checkeds = this.checkedAll.filter(e => (e.projectName && e.projectName.includes(val)) || (e.paperName && e.paperName.includes(val)))
}, },
// //
delProject (i, e) { delProject (i, e) {
@ -871,9 +697,9 @@ export default {
this.checkeds.splice(i, 1) this.checkeds.splice(i, 1)
// checkdisabled // checkdisabled
if (e.systemId == this.curSystem) { if (e.systemId == this.curSystem) {
const { projectId } = e const { projectId, paperId } = e
this.projects.map(n => { this.projects.map(n => {
if (n.projectId == projectId) { if ((projectId && n.projectId == projectId) || (paperId && n.paperId == paperId)) {
n.check = false n.check = false
} }
}) })
@ -992,7 +818,8 @@ export default {
form.systemIdByPractice = this.practiceData.map(i => { form.systemIdByPractice = this.practiceData.map(i => {
let obj = { let obj = {
isShow: i.isShow, isShow: i.isShow,
projectId: i.projectId, projectId: i.projectId || '',
paperId: i.paperId || '',
sort: Number(i.sort), sort: Number(i.sort),
systemId: i.systemId systemId: i.systemId
}; };
@ -1008,6 +835,7 @@ export default {
let obj = { let obj = {
isShow: i.isShow, isShow: i.isShow,
projectId: i.projectId, projectId: i.projectId,
paperId: i.paperId || '',
sort: Number(i.sort), sort: Number(i.sort),
systemId: i.systemId systemId: i.systemId
}; };
@ -1020,6 +848,7 @@ export default {
let obj = { let obj = {
isShow: i.isShow, isShow: i.isShow,
projectId: i.projectId, projectId: i.projectId,
paperId: i.paperId || '',
sort: Number(i.sort), sort: Number(i.sort),
systemId: i.systemId systemId: i.systemId
}; };
@ -1034,6 +863,7 @@ export default {
spinner: 'el-icon-loading', spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)' background: 'rgba(0, 0, 0, 0.7)'
}) })
debugger
if (form.cid) { if (form.cid) {
this.$post(this.api.modifyCourse, form).then((res) => { this.$post(this.api.modifyCourse, form).then((res) => {
this.$message.success("编辑成功"); this.$message.success("编辑成功");
@ -1093,6 +923,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
$avatar-width: 104px; $avatar-width: 104px;
/deep/ .avatar-uploader { /deep/ .avatar-uploader {
.el-upload { .el-upload {
position: relative; position: relative;
@ -1151,28 +982,34 @@ $avatar-width: 104px;
} }
} }
} }
.settlement { .settlement {
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 10px; margin-bottom: 10px;
.label { .label {
margin-right: 10px; margin-right: 10px;
white-space: nowrap; white-space: nowrap;
color: #606266; color: #606266;
font-size: 14px; font-size: 14px;
} }
.el-input { .el-input {
width: 150px; width: 150px;
margin-right: 30px; margin-right: 30px;
} }
} }
/deep/.config-dia { /deep/.config-dia {
.config-wrap { .config-wrap {
display: flex; display: flex;
} }
.title-wrap { .title-wrap {
margin-bottom: 15px; margin-bottom: 15px;
} }
.item { .item {
width: 250px; width: 250px;
max-height: 600px; max-height: 600px;
@ -1180,18 +1017,22 @@ $avatar-width: 104px;
margin-right: 20px; margin-right: 20px;
overflow: hidden; overflow: hidden;
} }
.system { .system {
background-color: #f9f9f9; background-color: #f9f9f9;
} }
.systems { .systems {
margin-top: 10px; margin-top: 10px;
max-height: 520px; max-height: 520px;
overflow: auto; overflow: auto;
li { li {
display: flex; display: flex;
align-items: center; align-items: center;
margin: 10px 0; margin: 10px 0;
} }
.name { .name {
display: inline-flex; display: inline-flex;
flex: 1; flex: 1;
@ -1199,10 +1040,12 @@ $avatar-width: 104px;
align-items: center; align-items: center;
margin-left: 5px; margin-left: 5px;
cursor: pointer; cursor: pointer;
&.active, &.active,
&:hover { &:hover {
color: #9076ff; color: #9076ff;
} }
span { span {
max-width: 200px; max-width: 200px;
text-overflow: ellipsis; text-overflow: ellipsis;
@ -1211,20 +1054,25 @@ $avatar-width: 104px;
} }
} }
} }
.checked { .checked {
flex: 1; flex: 1;
width: auto; width: auto;
.el-table .cell { .el-table .cell {
font-size: 12px; font-size: 12px;
} }
} }
.rm { .rm {
font-size: 14px; font-size: 14px;
cursor: pointer; cursor: pointer;
&.disabled { &.disabled {
color: #ccc; color: #ccc;
cursor: not-allowed; cursor: not-allowed;
} }
&:hover { &:hover {
color: #17161f; color: #17161f;
} }

@ -1,127 +1,78 @@
<template> <template>
<div> <div>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="flex-between"> <div class="flex-between">
<el-page-header @back="back" <el-page-header @back="back" :content="name + '/' + (sorting ? '编辑排序' : '内容设置')"></el-page-header>
:content="name + '/' + (sorting? '编辑排序' : '内容设置')"></el-page-header>
</div> </div>
</el-card> </el-card>
<!--内容设置--> <!--内容设置-->
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="page"> <div class="page">
<div class="relative"> <div class="relative">
<div class="p-title">内容设置</div> <div class="p-title">内容设置</div>
<div class="btns"> <div class="btns">
<template v-if="!sorting"> <template v-if="!sorting">
<el-button type="primary" <el-button type="primary" round @click="addChapter" v-auth="'/curriculum:内容设置:添加章节'">添加章节</el-button>
round <el-button type="primary" round @click="sort" v-auth="'/curriculum:内容设置:编辑排序'">编辑顺序</el-button>
@click="addChapter"
v-auth="'/curriculum:内容设置:添加章节'">添加章节</el-button>
<el-button type="primary"
round
@click="sort"
v-auth="'/curriculum:内容设置:编辑排序'">编辑顺序</el-button>
</template> </template>
<template v-else> <template v-else>
<el-button type="primary" <el-button type="primary" round @click="move">批量移动</el-button>
round <el-button type="primary" round @click="cancelSort">取消</el-button>
@click="move">批量移动</el-button> <el-button type="primary" round @click="saveSort">保存</el-button>
<el-button type="primary"
round
@click="cancelSort">取消</el-button>
<el-button type="primary"
round
@click="saveSort">保存</el-button>
</template> </template>
</div> </div>
</div> </div>
<el-divider></el-divider> <el-divider></el-divider>
<div class="page-content"> <div class="page-content">
<div class="mgb20" <div class="mgb20" v-for="(chapter, index) in chapters" :key="chapter.id">
v-for="(chapter,index) in chapters"
:key="chapter.id">
<div class="flex-between mgb10"> <div class="flex-between mgb10">
<div>{{ chapter.name }}</div> <div>{{ chapter.name }}</div>
<div> <div>
<template v-if="!sorting"> <template v-if="!sorting">
<el-button class="action-btn" <el-button class="action-btn" plain @click="editChapter(chapter)"
plain
@click="editChapter(chapter)"
v-auth="'/curriculum:内容设置:修改章节名称'">修改章节名称</el-button> v-auth="'/curriculum:内容设置:修改章节名称'">修改章节名称</el-button>
<el-button class="action-btn" <el-button class="action-btn" plain @click="addSection(chapter.id)"
plain
@click="addSection(chapter.id)"
v-auth="'/curriculum:内容设置:添加小节'">添加小节</el-button> v-auth="'/curriculum:内容设置:添加小节'">添加小节</el-button>
<el-button class="action-btn" <el-button class="action-btn" plain @click="delChapter(chapter.id)"
plain
@click="delChapter(chapter.id)"
v-auth="'/curriculum:内容设置:删除章节'">删除</el-button> v-auth="'/curriculum:内容设置:删除章节'">删除</el-button>
</template> </template>
<template v-else> <template v-else>
<i class="el-icon-top sort-icon" <i class="el-icon-top sort-icon" :class="{ disabled: index == 0 }" style="margin-right: 5px"
:class="{disabled: index == 0}"
style="margin-right: 5px"
@click="sortChapter(chapter, 'up', index == 0, index)"></i> @click="sortChapter(chapter, 'up', index == 0, index)"></i>
<i class="el-icon-bottom sort-icon" <i class="el-icon-bottom sort-icon" :class="{ disabled: index == chapters.length - 1 }"
:class="{disabled: index == chapters.length-1}"
@click="sortChapter(chapter, 'down', index == chapter.length - 1, index)"></i> @click="sortChapter(chapter, 'down', index == chapter.length - 1, index)"></i>
</template> </template>
</div> </div>
</div> </div>
<el-table :data="chapter.subsectionList" <el-table :data="chapter.subsectionList" class="table" stripe header-align="center" row-key="id">
class="table" <el-table-column v-if="sorting" width="55" align="center">
stripe
header-align="center"
row-key="id">
<el-table-column v-if="sorting"
width="55"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-checkbox v-model="scope.row.check"></el-checkbox> <el-checkbox v-model="scope.row.check"></el-checkbox>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column type="index" <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
width="100" <el-table-column prop="name" label="资源名称">
label="序号"
align="center"></el-table-column>
<el-table-column prop="name"
label="资源名称">
</el-table-column> </el-table-column>
<el-table-column prop="fileType" <el-table-column prop="fileType" label="资源类型" align="center">
label="资源类型"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ transferType(scope.row.fileType) }} {{ transferType(scope.row.fileType) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" align="center" width="300">
align="center"
width="300">
<template slot-scope="scope"> <template slot-scope="scope">
<template v-if="!sorting"> <template v-if="!sorting">
<el-button type="text" <el-button type="text" @click="download(scope.row)" v-auth="'/curriculum:内容设置:下载'">下载</el-button>
@click="download(scope.row)" <el-button type="text" @click="preview(scope.row)" v-auth="'/curriculum:内容设置:查看'">查看</el-button>
v-auth="'/curriculum:内容设置:下载'">下载</el-button> <el-button type="text" @click="delSection(scope.row)"
<el-button type="text"
@click="preview(scope.row)"
v-auth="'/curriculum:内容设置:查看'">查看</el-button>
<el-button type="text"
@click="delSection(scope.row)"
v-auth="'/curriculum:内容设置:删除小节'">删除</el-button> v-auth="'/curriculum:内容设置:删除小节'">删除</el-button>
<el-button type="text" <el-button type="text" @click="editSectionName(scope.row, chapter.id)"
@click="editSectionName(scope.row,chapter.id)"
v-auth="'/curriculum:内容设置:修改小节名称'">修改小节名称</el-button> v-auth="'/curriculum:内容设置:修改小节名称'">修改小节名称</el-button>
<el-button type="text" <el-button type="text" @click="switchFile(scope.row, chapter.id)"
@click="switchFile(scope.row,chapter.id)"
v-auth="'/curriculum:内容设置:更换文件'">更换文件</el-button> v-auth="'/curriculum:内容设置:更换文件'">更换文件</el-button>
</template> </template>
<template v-else> <template v-else>
<i class="el-icon-top sort-icon" <i class="el-icon-top sort-icon" :class="{ disabled: scope.$index == 0 }" style="margin-right: 5px"
:class="{disabled: scope.$index == 0}"
style="margin-right: 5px"
@click="sortSection(index, 'up', scope.$index == 0, scope.$index)"></i> @click="sortSection(index, 'up', scope.$index == 0, scope.$index)"></i>
<i class="el-icon-bottom sort-icon" <i class="el-icon-bottom sort-icon"
:class="{ disabled: scope.$index == chapter.subsectionList.length - 1 }" :class="{ disabled: scope.$index == chapter.subsectionList.length - 1 }"
@ -132,212 +83,133 @@
</el-table> </el-table>
</div> </div>
<el-dialog :title="chapterId ? '编辑章节' : '新增章节'" <el-dialog :title="chapterId ? '编辑章节' : '新增章节'" :visible.sync="chapterVisible" width="540px"
:visible.sync="chapterVisible"
width="540px"
:close-on-click-modal="false"> :close-on-click-modal="false">
<el-form> <el-form>
<el-form-item> <el-form-item>
<el-input placeholder="请输入章节名称,便于对小节归类" <el-input placeholder="请输入章节名称,便于对小节归类" v-model="chapterName" maxlength="50"></el-input>
v-model="chapterName"
maxlength="50"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="chapterVisible = false">取消</el-button> <el-button @click="chapterVisible = false">取消</el-button>
<el-button type="primary" <el-button type="primary" @click="chapterSubmit">确定</el-button>
@click="chapterSubmit">确定</el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="添加小节" <el-dialog title="添加小节" :visible.sync="sectionVisible" width="540px" @close="closeSection"
:visible.sync="sectionVisible"
width="540px"
@close="closeSection"
:close-on-click-modal="false"> :close-on-click-modal="false">
<el-form ref="form" <el-form ref="form" :model="sectionForm" label-width="80px" @submit.native.prevent>
:model="sectionForm"
label-width="80px"
@submit.native.prevent>
<el-form-item label="资源添加"> <el-form-item label="资源添加">
<Upload :max-size="100000" <Upload :max-size="100000" :file-list="uploadList" :on-remove="handleRemove"
:file-list="uploadList" @beforeUpload="beforeUpload" @onSuccess="uploadSuccess">
:on-remove="handleRemove"
@beforeUpload="beforeUpload"
@onSuccess="uploadSuccess">
<template slot="tip"> <template slot="tip">
<p>视频请上传MP4格式大小不超过150Moffice文件大小不要超过10M</p> <p>视频请上传MP4格式大小不超过150Moffice文件大小不要超过10M</p>
</template> </template>
</Upload> </Upload>
</el-form-item> </el-form-item>
<el-form-item label="小节名称"> <el-form-item label="小节名称">
<el-input placeholder="请输入小节名称" <el-input placeholder="请输入小节名称" v-model.trim="sectionForm.sectionName" maxlength="50"
v-model.trim="sectionForm.sectionName"
maxlength="50"
@keyup.enter.native="sectionSubmit()"></el-input> @keyup.enter.native="sectionSubmit()"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="sectionVisible = false">取消</el-button> <el-button @click="sectionVisible = false">取消</el-button>
<el-button type="primary" <el-button type="primary" @click="sectionSubmit">确定</el-button>
@click="sectionSubmit">确定</el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="更换文件" <el-dialog title="更换文件" :visible.sync="switchVisible" width="540px" :close-on-click-modal="false"
:visible.sync="switchVisible"
width="540px"
:close-on-click-modal="false"
@close="closeSwitch"> @close="closeSwitch">
<div style="text-align: center"> <div style="text-align: center">
<Upload :max-size="100000" <Upload :max-size="100000" :file-list="uploadList" :on-remove="handleRemove" @beforeUpload="beforeUpload"
:file-list="uploadList"
:on-remove="handleRemove"
@beforeUpload="beforeUpload"
@onSuccess="uploadSuccess"> @onSuccess="uploadSuccess">
<div slot="tip"></div> <div slot="tip"></div>
</Upload> </Upload>
</div> </div>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="switchVisible = false">取消</el-button> <el-button @click="switchVisible = false">取消</el-button>
<el-button type="primary" <el-button type="primary" @click="switchSubmit">确定</el-button>
@click="switchSubmit">确定</el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="修改小节名称" <el-dialog title="修改小节名称" :visible.sync="sectionNameVisible" width="540px" :close-on-click-modal="false">
:visible.sync="sectionNameVisible"
width="540px"
:close-on-click-modal="false">
<el-form @submit.native.prevent> <el-form @submit.native.prevent>
<el-form-item> <el-form-item>
<el-input placeholder="请输入小节名称" <el-input placeholder="请输入小节名称" v-model="sectionForm.sectionName" maxlength="50"
v-model="sectionForm.sectionName"
maxlength="50"
@keyup.enter.native="sectionNameSubmit()"></el-input> @keyup.enter.native="sectionNameSubmit()"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="sectionNameVisible = false">取消</el-button> <el-button @click="sectionNameVisible = false">取消</el-button>
<el-button type="primary" <el-button type="primary" @click="sectionNameSubmit">确定</el-button>
@click="sectionNameSubmit">确定</el-button>
</span> </span>
</el-dialog> </el-dialog>
<div v-show="previewImg" <div v-show="previewImg" class="el-image-viewer__wrapper" :class="{ active: previewImg }"
class="el-image-viewer__wrapper"
:class="{active: previewImg}"
style="z-index: 2000"> 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" <span class="el-image-viewer__btn el-image-viewer__close" @click="previewImg = ''"><i
@click="previewImg = ''"><i class="el-icon-circle-close" class="el-icon-circle-close" style="color: #fff"></i></span>
style="color: #fff"></i></span>
<div class="el-image-viewer__canvas"> <div class="el-image-viewer__canvas">
<img :src="previewImg" <img :src="previewImg" class="el-image-viewer__img"
class="el-image-viewer__img"
style="transform: scale(1) rotate(0deg);margin-top: -1px; max-height: 100%; max-width: 100%;"> style="transform: scale(1) rotate(0deg);margin-top: -1px; max-height: 100%; max-width: 100%;">
</div> </div>
</div> </div>
<div v-show="iframeSrc || videoSrc" <div v-show="iframeSrc || videoSrc" class="el-image-viewer__wrapper" :class="{ active: iframeSrc }"
class="el-image-viewer__wrapper"
:class="{active: iframeSrc}"
style="z-index: 2000"> 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" <span class="el-image-viewer__btn el-image-viewer__close" :class="{ 'doc-close': isWord }"
:class="{'doc-close': isWord}" :style="{ top: isWord ? '50px' : '5px' }" @click="closeIframe"><i class="el-icon-circle-close"
:style="{top: isWord ? '50px' : '5px'}"
@click="closeIframe"><i class="el-icon-circle-close"
style="color: #fff"></i></span> style="color: #fff"></i></span>
<div class="el-image-viewer__canvas"> <div class="el-image-viewer__canvas">
<iframe v-if="iframeSrc" <iframe v-if="iframeSrc" class="fileIframe" id="fileIframe" :src="iframeSrc" frameborder="0"></iframe>
class="fileIframe" <video v-if="videoSrc" class="video" width="1200" height="600" autoplay controls>
id="fileIframe" <source :src="videoSrc" type="video/mp4">
:src="iframeSrc"
frameborder="0"></iframe>
<video v-if="videoSrc"
class="video"
width="1200"
height="600"
autoplay
controls>
<source :src="videoSrc"
type="video/mp4">
您的浏览器不支持 video 标签 您的浏览器不支持 video 标签
</video> </video>
<template v-if="showMask"> <template v-if="showMask">
<div class="mask" <div class="mask" style="width: 200px;height: 30px;top: 53px;right: 320px"></div>
style="width: 200px;height: 30px;top: 53px;right: 320px"></div> <div class="mask" style="width: 175px;height: 30px;top: 53px;right: 5px"></div>
<div class="mask"
style="width: 175px;height: 30px;top: 53px;right: 5px"></div>
</template> </template>
<template v-if="showMask1"> <template v-if="showMask1">
<div class="word-mask1" <div class="word-mask1" style="width: 200px;height: 50px;"></div>
style="width: 200px;height: 50px;"></div> <div class="word-mask" style="height: 40px;top: 48px;"></div>
<div class="word-mask" <div class="word-mask2" style="top: 55px;left: 28%;width: 44%;height: calc(100% - 80px);"></div>
style="height: 40px;top: 48px;"></div>
<div class="word-mask2"
style="top: 55px;left: 28%;width: 44%;height: calc(100% - 80px);"></div>
</template> </template>
<template v-if="showMask2 && iframeSrc"> <template v-if="showMask2 && iframeSrc">
<div class="excel-mask1" <div class="excel-mask1" style="height: 48px;"></div>
style="height: 48px;"></div>
</template> </template>
</div> </div>
</div> </div>
<div v-show="playAuth" <div v-show="playAuth" class="el-image-viewer__wrapper" :class="{ active: playAuth }" style="z-index: 2000">
class="el-image-viewer__wrapper"
:class="{active: playAuth}"
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" <span class="el-image-viewer__btn el-image-viewer__close" @click="closePlayer"><i
@click="closePlayer"><i class="el-icon-circle-close" class="el-icon-circle-close" style="color: #fff"></i></span>
style="color: #fff"></i></span> <div class="player" id="player"></div>
<div class="player"
id="player"></div>
</div> </div>
<Pdf :visible.sync="pdfVisible" <Pdf :visible.sync="pdfVisible" :src.sync="pdfSrc" />
:src.sync="pdfSrc" />
</div> </div>
</div> </div>
</el-card> </el-card>
<div class="player-download" <div class="player-download" id="playerDownload"></div>
id="playerDownload"></div>
<el-dialog title="资源移动" <el-dialog title="资源移动" :visible.sync="moveVisible" :close-on-click-modal="false" width="330px">
:visible.sync="moveVisible"
:close-on-click-modal="false"
width="330px">
<el-form> <el-form>
<el-form-item label="目标章节"> <el-form-item label="目标章节">
<el-select v-model="moveForm.id" <el-select v-model="moveForm.id" placeholder="请选择目标章节" @change="chapterChange">
placeholder="请选择目标章节" <el-option v-for="(item, i) in chapters" :key="i" :label="item.name" :value="item.id"></el-option>
@change="chapterChange">
<el-option v-for="(item, i) in chapters"
:key="i"
:label="item.name"
:value="item.id"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="目标排序"> <el-form-item label="目标排序">
<el-select v-model="moveForm.sort" <el-select v-model="moveForm.sort" placeholder="请选择目标排序">
placeholder="请选择目标排序"> <el-option v-for="(item, i) in sortList" :key="i" :label="item.name" :value="item.id"></el-option>
<el-option v-for="(item, i) in sortList"
:key="i"
:label="item.name"
:value="item.id"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="moveVisible = false">取消</el-button> <el-button @click="moveVisible = false">取消</el-button>
<el-button type="primary" <el-button type="primary" @click="moveConfirm">确定</el-button>
@click="moveConfirm">确定</el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
@ -753,7 +625,7 @@ export default {
const { fileType, fileId } = row const { fileType, fileId } = row
// ppt // ppt
if (fileType === 'pptx') { if (fileType === 'pptx') {
this.downloadFile(row.name, row.fileUrl) this.downloadFile(row.originalFileName || row.name, row.fileUrl)
} else if (fileId) { } else if (fileId) {
// //
this.$get(`${this.api.getPlayAuth}/${fileId}`).then(res => { this.$get(`${this.api.getPlayAuth}/${fileId}`).then(res => {
@ -762,7 +634,7 @@ export default {
width: "100%", width: "100%",
autoplay: false, autoplay: false,
vid: fileId, vid: fileId,
playauth: res.data.playAuth, playauth: res.playAuth,
encryptType: 1 // encryptType: 1 //
}, player => { }, player => {
this.downloadFile(row.name, player._urls[0].Url) this.downloadFile(row.name, player._urls[0].Url)
@ -777,7 +649,7 @@ export default {
// //
if (row.fileId) { if (row.fileId) {
this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => { this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => {
this.playAuth = res.data.playAuth; this.playAuth = res.playAuth;
if (this.player) { if (this.player) {
this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth); this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth);
} else { } else {
@ -952,6 +824,7 @@ export default {
max-height: calc(100vh - 420px); max-height: calc(100vh - 420px);
overflow: auto; overflow: auto;
} }
.action-btn { .action-btn {
color: #9076ff; color: #9076ff;
font-size: 14px; font-size: 14px;
@ -979,10 +852,12 @@ export default {
cursor: not-allowed; cursor: not-allowed;
} }
} }
/deep/.el-progress-bar { /deep/.el-progress-bar {
padding-right: 70px; padding-right: 70px;
margin-right: -70px; margin-right: -70px;
} }
.el-upload__tip { .el-upload__tip {
position: absolute; position: absolute;
top: -4px; top: -4px;
@ -990,6 +865,7 @@ export default {
width: 300px; width: 300px;
line-height: 1.4; line-height: 1.4;
} }
.el-image-viewer__wrapper { .el-image-viewer__wrapper {
transform: translateY(-10px); transform: translateY(-10px);
transition: transform 0.5s; transition: transform 0.5s;
@ -1019,6 +895,7 @@ export default {
width: 1200px !important; width: 1200px !important;
height: 600px !important; height: 600px !important;
} }
.player-download { .player-download {
position: absolute; position: absolute;
top: -9999px; top: -9999px;

@ -139,7 +139,7 @@
<el-table-column prop="productTypeName" label="产品分类" align="center"></el-table-column> <el-table-column prop="productTypeName" label="产品分类" align="center"></el-table-column>
<el-table-column label="起止日期" align="center"> <el-table-column label="起止日期" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.status === '已过期' ? '' : scope.row.startAndEndTime }} {{ scope.row.status === '已过期' ? '-' : scope.row.startAndEndTime }}
<el-tooltip v-if="scope.row.other" class="item" effect="dark" placement="top"> <el-tooltip v-if="scope.row.other" class="item" effect="dark" placement="top">
<div slot="content"> <div slot="content">
还有<span v-html="scope.row.other"></span><br>的订单还未生效 还有<span v-html="scope.row.other"></span><br>的订单还未生效
@ -173,14 +173,14 @@
<ul class="filter"> <ul class="filter">
<li> <li>
<label>订单类型</label> <label>订单类型</label>
<el-select v-model="form3.orderType" clearable placeholder="请选择订单类型" @change="getOrder"> <el-select v-model="form3.orderType" clearable placeholder="请选择订单类型" @change="initOrder">
<el-option v-for="(item, index) in orderTypeList" :key="index" :label="item.name" <el-option v-for="(item, index) in orderTypeList" :key="index" :label="item.name"
:value="item.value"></el-option> :value="item.value"></el-option>
</el-select> </el-select>
</li> </li>
<li> <li>
<label>订单状态</label> <label>订单状态</label>
<el-select v-model="form3.orderStatus" clearable placeholder="请选择订单状态" @change="getOrder"> <el-select v-model="form3.orderStatus" clearable placeholder="请选择订单状态" @change="initOrder">
<el-option v-for="(item, index) in orderStatusList" :key="index" :label="item.name" <el-option v-for="(item, index) in orderStatusList" :key="index" :label="item.name"
:value="item.id"></el-option> :value="item.id"></el-option>
</el-select> </el-select>
@ -200,7 +200,7 @@
<el-table-column prop="orderContent" label="订单内容" align="center"> <el-table-column prop="orderContent" label="订单内容" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-popover trigger="hover" placement="top" style='width: 500px' <el-popover trigger="hover" placement="top" style='width: 500px'
v-if='scope.row.orderContent.length > 14'> v-if='scope.row.orderContent && scope.row.orderContent.length > 14'>
<p> {{ scope.row.orderContent }}</p> <p> {{ scope.row.orderContent }}</p>
<div slot="reference" class="name-wrapper"> <div slot="reference" class="name-wrapper">
<el-tag size="medium" class='tags'>{{ scope.row.orderContent }}</el-tag> <el-tag size="medium" class='tags'>{{ scope.row.orderContent }}</el-tag>
@ -401,8 +401,8 @@ export default {
customerId: "", customerId: "",
customerName: '', customerName: '',
countries: '中国', countries: '中国',
industryClassId: '', industryClassId: 16,
industryId: '', industryId: 83,
provinceId: '', provinceId: '',
account: '', account: '',
name: '', name: '',
@ -526,6 +526,7 @@ export default {
], ],
products: [], products: [],
productAll: [], productAll: [],
productAllOrigin: [],
pageProduct: this.$route.query.type === 'tab2' ? (+this.$route.query.page || 1) : 1, pageProduct: this.$route.query.type === 'tab2' ? (+this.$route.query.page || 1) : 1,
pageSizeProduct: 10, pageSizeProduct: 10,
totalProduct: 0, totalProduct: 0,
@ -565,7 +566,6 @@ export default {
pageSizeOrder: 10, pageSizeOrder: 10,
totalOrder: 0, totalOrder: 0,
orders: [], orders: [],
orderAll: [],
bmsKeyword: '', bmsKeyword: '',
bms: [], bms: [],
@ -625,7 +625,7 @@ export default {
this.pageOrder = 1 this.pageOrder = 1
clearTimeout(this.searchTimer) clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => { this.searchTimer = setTimeout(() => {
this.handlePageOrder() this.initOrder()
}, 500) }, 500)
}, },
bmsKeyword: function (val) { bmsKeyword: function (val) {
@ -677,6 +677,7 @@ export default {
this.getSchool() this.getSchool()
}).catch((res) => { }) }).catch((res) => { })
} else { } else {
this.changIndustryData()
this.getSchool() this.getSchool()
} }
}, },
@ -702,7 +703,7 @@ export default {
}) })
// //
// if (list[0].startTime && list[0].endTime) { // if (list[0].startTime && list[0].endTime) {
if (list[0].startTime && now < new Date(list[0].startTime).getTime()) { if (list[0].startTime && now < new Date(list[0].startTime)) {
e.startTime = list[0].startTime e.startTime = list[0].startTime
e.endTime = connect ? list[list.length - 1].endTime : list[0].endTime e.endTime = connect ? list[list.length - 1].endTime : list[0].endTime
e.status = '未生效' e.status = '未生效'
@ -716,7 +717,7 @@ export default {
e.other += `<br>${j.startTime} ~ ${j.endTime}` e.other += `<br>${j.startTime} ~ ${j.endTime}`
}) })
} }
} else if (list[list.length - 1].endTime && now > new Date(list[list.length - 1].endTime).getTime()) { } else if (list[list.length - 1].endTime && now > new Date(list[list.length - 1].endTime)) {
e.status = '已过期' e.status = '已过期'
} else { } else {
// //
@ -729,7 +730,7 @@ export default {
for (const j in list) { for (const j in list) {
const i = +j const i = +j
const n = list[i] const n = list[i]
if (n.startTime && n.endTime && now >= new Date(n.startTime).getTime() && now <= new Date(n.endTime).getTime()) { if (n.startTime && n.endTime && now >= new Date(n.startTime) && now <= new Date(n.endTime)) {
// //
e.startTime = n.startTime e.startTime = n.startTime
e.endTime = n.endTime e.endTime = n.endTime
@ -744,7 +745,7 @@ export default {
}) })
} }
break break
} else if (i != 0 && list[i - 1].endTime && n.startTime && n.endTime && now > new Date(list[i - 1].endTime).getTime() && now < new Date(n.startTime).getTime()) { } else if (i != 0 && list[i - 1].endTime && n.startTime && n.endTime && now > new Date(list[i - 1].endTime) && now < new Date(n.startTime)) {
// //
e.startTime = n.startTime e.startTime = n.startTime
e.endTime = n.endTime e.endTime = n.endTime
@ -775,13 +776,14 @@ export default {
} }
}) })
this.productAll = data this.productAll = data
this.productAllOrigin = data
this.totalProduct = data.length this.totalProduct = data.length
this.handlePage() this.handlePage()
}).catch(res => { }) }).catch(res => { })
}, },
// //
getRemain (startTime, endTime) { getRemain (startTime, endTime) {
return parseInt(((new Date(endTime).getTime() - new Date(startTime).getTime()) / 86400000)) return parseInt(((new Date(endTime) - new Date(startTime)) / 86400000))
}, },
// //
handlePage () { handlePage () {
@ -792,6 +794,15 @@ export default {
this.handlePage() this.handlePage()
this.$router.push(`addcustomer?id=${this.customerId}&type=tab2&page=${val}`) this.$router.push(`addcustomer?id=${this.customerId}&type=tab2&page=${val}`)
}, },
//
filterForm2 () {
const list = this.productAllOrigin
const { productType, status, keyword } = this.form2
this.productAll = list.filter(e => (productType === '' || productType === e.productType) && (e.status === status || status === '全部') && (!e.goodsName || (e.goodsName && e.goodsName.includes(keyword))))
this.pageProduct = 1
this.totalProduct = this.productAll.length
this.handlePage()
},
// //
setCustomer () { setCustomer () {
this.initCustomer() this.initCustomer()
@ -894,7 +905,7 @@ export default {
this.customerVisible = false this.customerVisible = false
this.$message.success('添加成功') this.$message.success('添加成功')
this.getCustomer() this.getCustomer()
this.getSchool(res.schoolId || '') this.getSchool(!this.customerId ? res.schoolId || '' : '') //
}, },
// //
getCategory () { getCategory () {
@ -902,12 +913,6 @@ export default {
this.productTypeList = res.classificationList this.productTypeList = res.classificationList
}).catch(err => { }) }).catch(err => { })
}, },
//
filterForm2 () {
const list = this.productAll
const { productType, status, keyword } = this.form2
this.products = list.filter(e => (productType === '' || productType === e.productType) && (e.status === status || status === '全部') && (!e.goodsName || (e.goodsName && e.goodsName.includes(keyword))))
},
// //
exportList () { exportList () {
let list = this.productAll let list = this.productAll
@ -935,36 +940,32 @@ export default {
// //
getOrder () { getOrder () {
const { orderStatus, orderType } = this.form3 const { orderStatus, orderType, keyword } = this.form3
this.$post(this.api.orderList, { this.$post(this.api.getCustomerOrderRecord, {
customerId: this.customerId,
cityId: '', cityId: '',
customerName: this.form.customerName, orderContent: keyword,
orderStatus, orderStatus,
orderType, orderType,
pageNo: 1, pageNo: this.pageOrder,
pageSize: 10000, pageSize: this.pageSizeOrder,
provinceId: '' provinceId: ''
}).then(({ orderPage }) => { }).then(({ orders }) => {
orderPage.orders.forEach(e => { orders.records.forEach(e => {
e.orderType = this.orderTypeFn(e.orderType) e.orderType = this.orderTypeFn(e.orderType)
e.orderStatus = this.orderStatusFn(e.orderStatus) e.orderStatus = this.orderStatusFn(e.orderStatus)
e.orderNature = this.orderNatureFn(e.orderNature)
}); });
this.orderAll = orderPage.orders this.orders = orders.records
this.totalOrder = orderPage.total this.totalOrder = orders.total
this.handlePageOrder()
}).catch(res => { }) }).catch(res => { })
}, },
// initOrder () {
handlePageOrder () { this.pageOrder = 1
const { keyword } = this.form3 this.getOrder()
const list = keyword ? this.orderAll.filter(e => e.orderNumber.includes(keyword) || e.orderContent.includes(keyword)) : this.orderAll
this.totalOrder = list.length
this.orders = list.slice((this.pageOrder - 1) * this.pageSizeOrder, this.pageOrder * this.pageSizeOrder)
}, },
handleCurrentChangeOrder (val) { handleCurrentChangeOrder (val) {
this.pageOrder = val this.pageOrder = val
this.handlePageOrder() this.getOrder()
this.$router.push(`addcustomer?id=${this.customerId}&type=tab3&page=${val}`) this.$router.push(`addcustomer?id=${this.customerId}&type=tab3&page=${val}`)
}, },
// //
@ -1013,7 +1014,7 @@ export default {
this.pageProduct = 1 this.pageProduct = 1
this.pageOrder = 1 this.pageOrder = 1
this.pageBm = 1 this.pageBm = 1
index === 'tab3' && this.handlePageOrder() index === 'tab3' && this.initOrder()
this.updateTime = this.form.customerId ? 1 : 0 this.updateTime = this.form.customerId ? 1 : 0
} }
}, },
@ -1036,7 +1037,7 @@ export default {
this.$get(this.api.querySchoolData).then(({ list }) => { this.$get(this.api.querySchoolData).then(({ list }) => {
this.schoolList = list this.schoolList = list
// schoolId // schoolId
if (schoolId) { if (schoolId && !this.customerId) {
const item = list.find(e => e.schoolId == schoolId) const item = list.find(e => e.schoolId == schoolId)
if (item) { if (item) {
this.form.schoolId = schoolId this.form.schoolId = schoolId

@ -6,26 +6,19 @@
<h1>欢迎使用开发者平台</h1> <h1>欢迎使用开发者平台</h1>
<div class="form"> <div class="form">
<ul class="tab"> <ul class="tab">
<li v-for="(item, i) in tabList" :key="i" :class="{active: activeIndex == item.id}" @click="handleSelect(item.id)">{{item.label}}</li> <li v-for="(item, i) in tabList" :key="i" :class="{ active: activeIndex == item.id }"
@click="handleSelect(item.id)">{{ item.label }}</li>
</ul> </ul>
<el-form v-show="activeIndex === '1'" :model="param" :rules="rules" ref="login" label-width="0px"> <el-form v-show="activeIndex === '1'" :model="param" :rules="rules" ref="login" label-width="0px">
<el-form-item prop="account"> <el-form-item prop="account">
<el-input @blur="blur" v-model="param.account" placeholder="请输入账号"></el-input> <el-input @blur="blur" v-model="param.account" placeholder="请输入账号"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
<el-input <el-input type="password" placeholder="请输入密码" v-model="param.password">
type="password"
placeholder="请输入密码"
v-model="param.password"
>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="code" v-if="showVerify"> <el-form-item prop="code" v-if="showVerify">
<el-input <el-input placeholder="请输入验证码" v-model="param.code" @keyup.enter.native="submitForm()">
placeholder="请输入验证码"
v-model="param.code"
@keyup.enter.native="submitForm()"
>
</el-input> </el-input>
<img @click="blur" :src="verificationIMG" class="verification" alt=""> <img @click="blur" :src="verificationIMG" class="verification" alt="">
</el-form-item> </el-form-item>
@ -34,24 +27,17 @@
</div> </div>
</el-form> </el-form>
<el-form v-show="activeIndex==='2'" :model="phoneOrEmail" :rules="phoneOrEmailrules" ref="phoneOrEmail" label-width="0px"> <el-form v-show="activeIndex === '2'" :model="phoneOrEmail" :rules="phoneOrEmailrules" ref="phoneOrEmail"
label-width="0px">
<el-form-item prop="account"> <el-form-item prop="account">
<el-input @blur="phoneBlur" v-model="phoneOrEmail.account" placeholder="请输入电话/邮箱"></el-input> <el-input @blur="phoneBlur" v-model="phoneOrEmail.account" placeholder="请输入电话/邮箱"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
<el-input <el-input type="password" placeholder="请输入密码" v-model="phoneOrEmail.password">
type="password"
placeholder="请输入密码"
v-model="phoneOrEmail.password"
>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="code" v-if="showPhoneVerify"> <el-form-item prop="code" v-if="showPhoneVerify">
<el-input <el-input placeholder="请输入验证码" v-model="phoneOrEmail.code" @keyup.enter.native="submitForm('phone')">
placeholder="请输入验证码"
v-model="phoneOrEmail.code"
@keyup.enter.native="submitForm('phone')"
>
</el-input> </el-input>
<img @click="phoneBlur" :src="PhoneVerificationIMG" class="verification" alt=""> <img @click="phoneBlur" :src="PhoneVerificationIMG" class="verification" alt="">
</el-form-item> </el-form-item>
@ -71,7 +57,8 @@
<el-form-item label="验证码"> <el-form-item label="验证码">
<div style="display:flex;"> <div style="display:flex;">
<el-input v-model="phoneCode" placeholder="请输入验证码" maxlength="6"></el-input> <el-input v-model="phoneCode" placeholder="请输入验证码" maxlength="6"></el-input>
<el-button style="margin-left:10px" @click="sendPhoneCode" :disabled="phoneDisabled">{{phoneBtnText}}</el-button> <el-button style="margin-left:10px" @click="sendPhoneCode" :disabled="phoneDisabled">{{ phoneBtnText
}}</el-button>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -80,6 +67,20 @@
<el-button type="primary" @click="phoneSubmit"> </el-button> <el-button type="primary" @click="phoneSubmit"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="请选择您要登录的用户" :visible.sync="userVisible" :close-on-click-modal="false" custom-class="user-dia"
width="500px">
<p class="tips">该手机号已绑定以下用户信息</p>
<ul class="users">
<li :class="{ isEnable: !user.isEnable }" v-for="(user, i) in users" :key="i" @click="chooseUser(user)">
<span>{{ user.schoolName }}{{ user.userName }}{{ user.workNumber }}{{
user.isEnable
? ''
: '(已禁用)' }}</span>
<i class="el-icon-right"></i>
</li>
</ul>
</el-dialog>
<v-footer class="footer" ref="footer"></v-footer> <v-footer class="footer" ref="footer"></v-footer>
</div> </div>
</template> </template>
@ -87,6 +88,9 @@
<script> <script>
import vFooter from '../components/Footer' import vFooter from '../components/Footer'
import Setting from '@/setting' import Setting from '@/setting'
import addRoutes from '@/libs/route/addRoutes'
import CryptoJS from 'crypto-js'
import JSEncrypt from 'jsencrypt'
export default { export default {
data: function () { data: function () {
var regPhoneOrEmail = (rule, value, callback) => {// var regPhoneOrEmail = (rule, value, callback) => {//
@ -155,8 +159,10 @@ export default {
phoneDisabled: false, phoneDisabled: false,
phoneBtnText: '发送验证码', phoneBtnText: '发送验证码',
phoneTimer: '', phoneTimer: '',
phoneOpener:'' phoneOpener: '',
userVisible: false,
users: [],
}; };
}, },
components: { components: {
@ -190,26 +196,29 @@ export default {
let param = val === 'phone' ? this.phoneOrEmail : this.param let param = val === 'phone' ? this.phoneOrEmail : this.param
this.$refs[ref].validate(valid => { this.$refs[ref].validate(valid => {
if (valid) { if (valid) {
this.$post(this.api.logins,param).then(res => { this.$post(this.api.logins, param).then(({ status, data, message }) => {
const { message } = res localStorage.removeItem('examPath')
sessionStorage.setItem('token',res.data.token) localStorage.removeItem('reviewPath')
this.$get(`${this.api.getUserRolesPermissionMenu}?platformId=${Setting.platformId}`).then(res => { this.getOss()
const list = res.permissionMenu if (status == 200) {
this.$store.commit('setDataPer', res.dataPermissionList) const accounts = data.userAccounts
this.$message.success(message); //
this.$router.push({ if (accounts instanceof Array) {
path: list[0].children[0].path this.users = accounts
}); this.userVisible = true
localStorage.setItem('ms_username', this.param.username); } else {
}).catch(err => { sessionStorage.setItem('token', data.token)
if (err.status === 500) { this.setLogin()
sessionStorage.clear() }
} else {
param.code = ''
this.$message.error(message)
} }
})
}).catch(err => { }).catch(err => {
if (err.status === 30001) { if (err.status === 30001) {
this.phoneVisible = true this.phoneVisible = true
}else if(err.status == 10004){ } else if (err.status == 10004 || err.status == 10005) {
param.code = ''
this.blur() this.blur()
} }
}); });
@ -218,7 +227,54 @@ export default {
return false; return false;
} }
}); });
},
// oss
async getOss () {
const A = (key, encryptedData) => {
const keyHex = CryptoJS.enc.Base64.parse(key)
const decrypted = CryptoJS.AES.decrypt(encryptedData, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
})
return decrypted.toString(CryptoJS.enc.Utf8)
}
const R = (encryptedKey, privateKey) => {
const decrypt = new JSEncrypt()
decrypt.setPrivateKey(privateKey)
const decryptedKey = decrypt.decrypt(encryptedKey)
return decryptedKey
}
const res = await this.$get(this.api.encrypt)
const RE = A(R(res.encryptedKey, res.privateKey), res.encryptedData).split('/')
localStorage.setItem('osc', JSON.stringify(RE))
},
//
chooseUser (user) {
user.isEnable && this.$post(`${this.api.getToken}?id=${user.id}`).then(({ data }) => {
sessionStorage.setItem('token', data.token)
this.token = data.token
this.setLogin()
}).catch(res => { })
},
//
async setLogin () {
try {
const res = await this.$get(`${this.api.getUserRolesPermissionMenu}?platformId=${Setting.platformId}`)
const list = res.permissionMenu
addRoutes(res.permissionMenu[0].children)
this.$store.commit('setDataPer', res.dataPermissionList)
this.$message.success('登录成功!')
this.$router.push({
path: list[0].children[0].path
});
localStorage.setItem('ms_username', this.param.username);
} catch (e) {
if (e.status === 500) {
sessionStorage.clear()
}
}
}, },
blur () { blur () {
this.param.random = Math.floor(Math.random() * 999999999) this.param.random = Math.floor(Math.random() * 999999999)
@ -305,24 +361,28 @@ export default {
.wrap { .wrap {
min-height: 100%; min-height: 100%;
} }
.logo { .logo {
z-index: 2; z-index: 2;
position: absolute; position: absolute;
top: 50px; top: 50px;
left: 50px; left: 50px;
} }
.login { .login {
position: relative; position: relative;
height: 100%; height: 100%;
background-image: url(../assets/img/devLogin.jpg); background-image: url(../assets/img/devLogin.jpg);
background-size: 100%; background-size: 100%;
} }
.box { .box {
width: 448px; width: 448px;
position: absolute; position: absolute;
right: 20%; right: 20%;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
h1 { h1 {
margin-bottom: 20px; margin-bottom: 20px;
font-size: 34px; font-size: 34px;
@ -330,21 +390,25 @@ export default {
text-align: center; text-align: center;
} }
} }
/deep/ .form { /deep/ .form {
padding: 20px 60px 0; padding: 20px 60px 0;
background-color: rgba(255, 255, 255, .3); background-color: rgba(255, 255, 255, .3);
border-radius: 4px; border-radius: 4px;
box-sizing: border-box; box-sizing: border-box;
border: 4px solid rgba(255, 255, 255, .2); border: 4px solid rgba(255, 255, 255, .2);
.el-input__inner { .el-input__inner {
height: 50px; height: 50px;
line-height: 50px; line-height: 50px;
border: 1px solid rgba(220, 220, 220, 1); border: 1px solid rgba(220, 220, 220, 1);
border-radius: 2px; border-radius: 2px;
} }
.el-form-item { .el-form-item {
margin-bottom: 25px; margin-bottom: 25px;
} }
.verification { .verification {
position: absolute; position: absolute;
top: 1px; top: 1px;
@ -354,11 +418,13 @@ export default {
cursor: pointer; cursor: pointer;
} }
} }
.tab { .tab {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
margin-bottom: 24px; margin-bottom: 24px;
li { li {
padding: 18px 5px; padding: 18px 5px;
margin: 0 20px; margin: 0 20px;
@ -367,23 +433,28 @@ export default {
color: #fff; color: #fff;
cursor: pointer; cursor: pointer;
border-bottom: 2px solid transparent; border-bottom: 2px solid transparent;
&:last-child { &:last-child {
margin-right: 0; margin-right: 0;
} }
&.active { &.active {
color: #fff; color: #fff;
border-bottom-color: #ccc; border-bottom-color: #ccc;
} }
} }
} }
.title { .title {
font-size: 16px; font-size: 16px;
text-align: center; text-align: center;
font-weight: bold; font-weight: bold;
} }
.login-btn { .login-btn {
text-align: center; text-align: center;
} }
.login-btn button { .login-btn button {
width: 100%; width: 100%;
height: 48px; height: 48px;
@ -393,13 +464,55 @@ export default {
border-radius: 4px; border-radius: 4px;
border: 0; border: 0;
} }
.forget { .forget {
margin-bottom: 28px; margin-bottom: 28px;
text-align: right; text-align: right;
color: #999; color: #999;
font-weight: bold; font-weight: bold;
&:hover { &:hover {
color: #0092FF; color: #0092FF;
} }
} }
/deep/.user-dia {
.tips {
margin-bottom: 20px;
text-align: center;
color: #666;
}
.users {
li {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 15px;
margin-bottom: 10px;
line-height: 40px;
font-size: 14px;
background-color: #ebeef5;
cursor: pointer;
&.isEnable {
color: #c0c4cc;
background-color: #f5f7fa;
cursor: not-allowed;
}
&:last-child {
margin-bottom: 0;
}
&:hover {
background-color: #d3e0ff;
}
i {
font-size: 16px;
}
}
}
}
</style> </style>

@ -9,8 +9,8 @@
<div class="p-title">大赛发布类型</div> <div class="p-title">大赛发布类型</div>
<el-form label-width="100px" label-suffix=":" size="small" :disabled="!editing && id != ''"> <el-form label-width="100px" label-suffix=":" size="small" :disabled="!editing && id != ''">
<el-form-item label="请选择类型"> <el-form-item label="请选择类型">
<el-radio v-model="releaseType" :label="0">仅发布信息</el-radio> <el-radio v-for="(item, i) in releaseTypes" :key="i" v-model="releaseType" :label="item.id">{{ item.name
<el-radio v-model="releaseType" :label="1">设置完整比赛</el-radio> }}</el-radio>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-button v-if="!editing && id" class="edit" type="primary" @click="editing = 1" <el-button v-if="!editing && id" class="edit" type="primary" @click="editing = 1"
@ -83,6 +83,20 @@ export default {
updateTime: 0, updateTime: 0,
setupId: '', setupId: '',
releaseType: 0, releaseType: 0,
releaseTypes: [
{
id: 0,
name: '仅发布信息'
},
{
id: 1,
name: '设置完整比赛'
},
// {
// id: 2,
// name: ''
// },
],
editing: this.$route.query.id ? 0 : 1, editing: this.$route.query.id ? 0 : 1,
showBtns: true, showBtns: true,
loadIns: null loadIns: null
@ -140,9 +154,10 @@ export default {
next (next, setupId, competitionId) { next (next, setupId, competitionId) {
if (!next) { if (!next) {
if (this.step === 3 && this.$refs['step' + this.step].form[0].contentId) { if (this.step === 3 && this.$refs['step' + this.step].form[0].contentId) {
// && // &&
this.editing = 0 this.editing = 0
this.step = 1 this.step = 1
this.$parent.initTabs && this.$parent.initTabs()
} else { } else {
// //
this.$router.push(`/match`) this.$router.push(`/match`)

@ -1,103 +1,137 @@
<template> <template>
<div> <div>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<div> <div>
<p class="m-b-20">比赛名称</p> <p class="m-b-20">比赛名称</p>
{{ form.stageName }} {{ form.stageName }}
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<div> <div>
<p class="m-b-20">比赛时间</p> <p class="m-b-20">比赛时间</p>
<div class="date-inputs"> <div class="date-inputs">
起止时间 起止时间
<div style="display: inline-flex;align-items: center;"> <div style="display: inline-flex;align-items: center;">
<el-date-picker v-model="form.time" <el-date-picker v-model="form.time" type="datetimerange" range-separator="~" start-placeholder="开始日期"
type="datetimerange" end-placeholder="结束日期" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
range-separator="~"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
@change="timeChange"> @change="timeChange">
</el-date-picker> </el-date-picker>
<el-alert style="width: auto;padding: 4px 16px;margin-left: 10px;" <el-alert style="width: auto;padding: 4px 16px;margin-left: 10px;"
:title="'(请设置在 ' + step1.playStartTime + ' ~ ' + step1.playEndTime + '间)'" :title="'(请设置在 ' + step1.playStartTime + ' ~ ' + step1.playEndTime + '间)'" type="error" :closable="false"
type="error"
:closable="false"
effect="dark"> effect="dark">
</el-alert> </el-alert>
</div> </div>
</div> </div>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover"
class="mgr20 m-b-20"> <!-- 理论系统 -->
<template v-if="isTheory">
<!-- 理论系统选择试卷库非理论则选择系统 -->
<el-card shadow="hover" class="mgr20 m-b-20">
<div>
<p class="m-b-20">试卷库</p>
<div class="inline-input">
<el-select v-model="libraryId" placeholder="请选择试卷库" @change="getProject">
<el-option v-for="(item, i) in paperLibraries" :key="i" :label="item.libraryName" :value="item.libraryId">
</el-option>
</el-select>
</div>
</div>
</el-card>
<el-card shadow="hover" class="m-b-20">
<div class="flex-between m-b-20">
<span>理论试卷</span>
<div style="display: inline-flex;">
<div>
<el-input placeholder="请输入试卷名称" prefix-icon="el-icon-search" v-model.trim="keyword" clearable></el-input>
</div>
</div>
</div>
<p v-if="form.paperName" style="margin-bottom: 20px">
已选试卷{{ form.paperName }}
<el-button type="primary" size="mini" @click="previewPaper(form)">预览</el-button>
</p>
<el-table :data="projects" class="table" stripe header-align="center">
<el-table-column width="60" label="选择" align="center">
<template slot-scope="scope">
<el-radio v-model="form.paperId" :label="scope.row.paperId" @change="paperChange">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="name" label="试卷名称" min-width="140" align="center"></el-table-column>
<el-table-column prop="questionCount" label="试题总数" align="center" min-width="70"></el-table-column>
<el-table-column prop="score" label="总分" align="center" min-width="70"></el-table-column>
<el-table-column prop="difficult" label="试卷难度" align="center" min-width="70" sortable="custom">
<template slot-scope="scope">{{ difficults.find(e => e.id === scope.row.difficult) ? difficults.find(e =>
e.id === scope.row.difficult).name : '' }}</template>
</el-table-column>
<el-table-column prop="suggestTime" label="建议用时" align="center" min-width="70">
<template slot-scope="scope">{{ scope.row.suggestTime }}min</template>
</el-table-column>
<el-table-column prop="classificationPath" label="试卷分类" align="center" min-width="70"
show-overflow-tooltip></el-table-column>
<el-table-column label="建议用途" align="center" min-width="70">
<template slot-scope="scope">{{ paperTypes.find(e => e.id === scope.row.paperType) ? paperTypes.find(e =>
e.id === scope.row.paperType).name : '' }}</template>
</el-table-column>
<el-table-column prop="updateTime" label="最近编辑时间" align="center" width="170"></el-table-column>
<el-table-column prop="createUser" label="最近编辑人" align="center" width="110"></el-table-column>
<el-table-column label="操作" align="center" width="80">
<template slot-scope="scope">
<el-button type="text" @click="previewPaper(scope.row)">预览</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background :page-size="pageSize" @current-change="handleCurrentChange"
layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
</el-card>
</template>
<template v-else>
<el-card shadow="hover" class="mgr20 m-b-20">
<div> <div>
<p class="m-b-20">课程</p> <p class="m-b-20">课程</p>
<div class="inline-input"> <div class="inline-input">
<el-cascader ref="cur" <el-cascader ref="cur" v-model="mallIds" :options="curs" :props="{ checkStrictly: true, value: 'id' }"
v-model="mallIds" popper-class="course-cas" @expand-change="curChange" @change="curChange"></el-cascader>
:options="curs"
:props="{ checkStrictly: true, value: 'id' }"
popper-class="course-cas"
@expand-change="curChange"
@change="curChange"></el-cascader>
</div> </div>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover"
class="m-b-20"> <el-card shadow="hover" class="m-b-20">
<div class="flex-between m-b-20"> <div class="flex-between m-b-20">
<span>实训项目</span> <span>实训项目</span>
<div style="display: inline-flex;"> <div style="display: inline-flex;">
<div> <div>
<el-input placeholder="请输入项目名称" <el-input placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model.trim="keyword" clearable></el-input>
prefix-icon="el-icon-search"
v-model.trim="keyword"
clearable></el-input>
</div> </div>
<el-button style="margin-left: 5px" <el-button style="margin-left: 5px" type="primary" round @click="toProject">自定义实验项目</el-button>
type="primary"
round
@click="toProject">自定义实验项目</el-button>
</div> </div>
</div> </div>
<!-- 实训项目表格 --> <!-- 实训项目表格 -->
<el-table :data="projects" <el-table :data="projects" class="table" stripe header-align="center">
class="table" <el-table-column width="60" label="选择" align="center">
stripe
header-align="center">
<el-table-column width="60"
label="选择"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-radio v-model="form.projectId" <el-radio v-model="form.projectId" :label="scope.row.projectId">&nbsp;</el-radio>
:label="scope.row.projectId">&nbsp;</el-radio>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="projectName" <el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
label="项目名称" <el-table-column prop="auth" label="项目权限" align="center">
align="center"></el-table-column>
<el-table-column prop="auth"
label="项目权限"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ permissionsKeys[scope.row.permissions] }} {{ permissionsKeys[scope.row.permissions] }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="founder" <el-table-column prop="founder" label="创建人" align="center">
label="创建人"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.founder ? '老师创建' : '系统内置' }} {{ scope.row.founder ? '老师创建' : '系统内置' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" <el-table-column prop="createTime" label="创建时间" align="center"></el-table-column>
label="创建时间"
align="center"></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="showProject(scope.row)">查看</el-button> <el-button type="text" @click="showProject(scope.row)">查看</el-button>
@ -105,42 +139,54 @@
</el-table-column> --> </el-table-column> -->
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background <el-pagination background :page-size="pageSize" @current-change="handleCurrentChange"
:page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
@current-change="handleCurrentChange"
layout="total,prev, pager, next"
:total="total"></el-pagination>
</div> </div>
</el-card> </el-card>
</template>
<div style="text-align: center"> <div style="text-align: center">
<el-button @click="back">返回</el-button> <el-button @click="back">返回</el-button>
<el-button type="primary" <el-button type="primary" @click="save">保存</el-button>
@click="save">保存</el-button>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import Setting from '@/setting'
import util from "@/libs/util"; import util from "@/libs/util";
import { Loading } from 'element-ui' import { Loading } from 'element-ui'
import TestPaperConst from '@/const/testPaper'
export default { export default {
props: ['form', 'step1'], props: ['form', 'step1'],
data () { data () {
return { return {
difficults: TestPaperConst.difficults,
paperTypes: TestPaperConst.paperTypes,
loadIns: null, loadIns: null,
mallIds: [], mallIds: [],
curs: [], curs: [],
paperLibraries: [],
testPapers: [],
keyword: '', keyword: '',
projects: [], projects: [],
page: 1, page: 1,
pageSize: 5, pageSize: 5,
total: 0, total: 0,
libraryId: '',
sysId: '', sysId: '',
paperId: '',
paperName: '',
permissionsKeys: ['练习', '考核', '竞赛'], permissionsKeys: ['练习', '考核', '竞赛'],
timeInvalid: false timeInvalid: false,
}; };
}, },
computed: {
//
isTheory () {
return this.form.method === 1
},
},
watch: { watch: {
// , // ,
form: { form: {
@ -157,7 +203,7 @@ export default {
} }
}, },
mounted () { mounted () {
this.getCourse() this.isTheory ? this.getLibrary() : this.getCourse()
}, },
methods: { methods: {
// //
@ -186,7 +232,7 @@ export default {
records.map(e => { records.map(e => {
e.id = +e.mallId e.id = +e.mallId
e.label = e.productName e.label = e.productName
e.children = serviceList.records.filter(n => e.systemId.split(',').includes(n.systemId)) // e.children = serviceList.records.filter(n => e.systemId && e.systemId.split(',').includes(n.systemId)) //
}) })
this.curs = records this.curs = records
@ -216,31 +262,65 @@ export default {
this.loadIns = Loading.service() this.loadIns = Loading.service()
this.getProject() this.getProject()
}, },
//
async getLibrary () {
try {
const res = await this.$post(this.api.libraryList, {
pageNum: 1,
pageSize: 10000,
type: 1,
isDisable: 0,
})
const { records } = res.pageList
if (records.length) {
this.paperLibraries = records
this.libraryId = records[0].libraryId
this.loadIns = Loading.service()
this.getProject()
}
} finally { }
},
// // /
getProject () { async getProject () {
this.$post(this.api.getProjectAssessmentByCompetition, { try {
//
if (this.isTheory) {
const res = await this.$post(this.api.examPaperList, {
pageNum: this.page,
pageSize: this.pageSize,
type: 1,
keyWord: this.keyword,
libraryId: this.libraryId,
isDisable: 0,
status: 1
})
this.projects = res.pageList.records
this.total = res.pageList.total
} else {
//
const { data } = await this.$post(this.api.getProjectAssessmentByCompetition, {
pageNum: this.page, pageNum: this.page,
pageSize: this.pageSize, pageSize: this.pageSize,
cid: this.form.cid, cid: this.form.cid,
projectName: this.keyword, projectName: this.keyword,
systemId: this.sysId, systemId: this.sysId,
permissions: 2 permissions: 2,
}).then(({ data }) => { })
this.projects = data.records this.projects = data.records
this.total = data.total this.total = data.total
}
} finally {
this.loadIns.close() this.loadIns.close()
}).catch(err => { }
this.loadIns.close()
});
}, },
initData () { initData () {
this.page = 1; this.page = 1
this.getProject(); this.getProject()
}, },
handleCurrentChange (val) { handleCurrentChange (val) {
this.page = val; this.page = val
this.getProject(); this.getProject()
}, },
// //
toProject () { toProject () {
@ -277,22 +357,58 @@ export default {
} }
} }
}, },
//
previewPaper (row) {
this.$parent.previewPaper(row)
},
//
paperChange (id) {
const item = this.projects.find(e => e.paperId === id)
if (item) this.form.paperName = item.name
},
// //
save () { save () {
const { form } = this const { form } = this
if (!form.time.length) return util.warningMsg('请选择比赛时间') if (!form.time.length) return util.warningMsg('请选择比赛时间')
const { playStartTime, playEndTime } = this.step1 const { playStartTime, playEndTime } = this.step1
if (new Date(form.time[0]) < new Date(playStartTime) || new Date(form.time[1]) > new Date(playEndTime)) return util.warningMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。') if (new Date(form.time[0]) < new Date(playStartTime) || new Date(form.time[1]) > new Date(playEndTime)) return util.warningMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。')
//
if (this.isTheory) {
if (!this.libraryId) return util.warningMsg('请选择试卷库')
if (!form.paperId) return util.warningMsg('请选择试卷')
form.libraryId = this.libraryId
const curPaper = this.projects.find(e => e.paperId === form.paperId)
if (curPaper) form.paperName = curPaper.name
} else {
if (!form.cid) return util.warningMsg('请选择课程') if (!form.cid) return util.warningMsg('请选择课程')
if (!form.projectId) return util.warningMsg('请选择项目') if (!form.projectId) return util.warningMsg('请选择项目')
const { systemId, systemName, projectName } = this.projects.find(e => e.projectId == form.projectId) const { systemId, systemName, projectName } = this.projects.find(e => e.projectId == form.projectId)
if (systemId) form.systemId = systemId if (systemId) form.systemId = systemId
if (projectName) form.projectName = projectName if (projectName) form.projectName = projectName
if (systemName) form.systemName = systemName if (systemName) form.systemName = systemName
}
form.startTime = form.time[0] form.startTime = form.time[0]
form.endTime = form.time[1] form.endTime = form.time[1]
this.handlePaper()
this.$emit('hideSet', this.form) this.$emit('hideSet', this.form)
}, },
//
async handlePaper () {
const { form } = this
// id
if (form.paperName !== form.originPaperName) {
const res = await this.$post(this.api.copyExamPaper, {
associatedID: form.stageId,
paperId: form.paperId,
typeId: 1
})
if (res.examPaper) {
form.paperId = res.examPaper.paperId
}
}
},
// //
back () { back () {
this.$emit('update:form', this.$parent.curOriginForm) this.$emit('update:form', this.$parent.curOriginForm)
@ -302,5 +418,4 @@ export default {
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss"></style>
</style>

@ -37,6 +37,8 @@
<el-input placeholder="请输入竞赛名称" v-model="form.name" clearable></el-input> <el-input placeholder="请输入竞赛名称" v-model="form.name" clearable></el-input>
</div> </div>
</el-form-item> </el-form-item>
<template v-if="!isPractice">
<el-form-item class="req" label="主办方"> <el-form-item class="req" label="主办方">
<div class="inline-input"> <div class="inline-input">
<div class="input-wrap" v-for="(item, index) in sponsorList" :key="index"> <div class="input-wrap" v-for="(item, index) in sponsorList" :key="index">
@ -72,6 +74,7 @@
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
:picker-options="pickerOptions"></el-date-picker> :picker-options="pickerOptions"></el-date-picker>
</el-form-item> </el-form-item>
</template>
<el-form-item class="req" label="竞赛时间"> <el-form-item class="req" label="竞赛时间">
<el-date-picker v-model="playTime" value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange" <el-date-picker v-model="playTime" value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
@ -92,6 +95,7 @@
</template> </template>
</div> </div>
</el-form-item> </el-form-item>
<template v-if="!isPractice">
<el-form-item class="req" label="竞赛类型"> <el-form-item class="req" label="竞赛类型">
<el-radio v-model="form.completeCompetitionSetup.competitionType" :label="0">个人赛</el-radio> <el-radio v-model="form.completeCompetitionSetup.competitionType" :label="0">个人赛</el-radio>
<el-radio v-model="form.completeCompetitionSetup.competitionType" :label="1">团队赛</el-radio> <el-radio v-model="form.completeCompetitionSetup.competitionType" :label="1">团队赛</el-radio>
@ -128,6 +132,7 @@
<el-button v-if="form.completeCompetitionSetup.isNeedCode === 1" @click="randomInv">随机</el-button> <el-button v-if="form.completeCompetitionSetup.isNeedCode === 1" @click="randomInv">随机</el-button>
</div> </div>
</el-form-item> </el-form-item>
</template>
<el-form-item class="req" label="竞赛详情"> <el-form-item class="req" label="竞赛详情">
<quill v-if="quillShow" :border="true" v-model="form.description" :height="400" <quill v-if="quillShow" :border="true" v-model="form.description" :height="400"
:readonly="!editing && form.id !== ''" /> :readonly="!editing && form.id !== ''" />
@ -136,6 +141,56 @@
<Upload :limit="5" :file-list.sync="fileList" :on-remove="handleAnnexRemove" <Upload :limit="5" :file-list.sync="fileList" :on-remove="handleAnnexRemove"
@onSuccess="uploadAnnexSuccess" /> @onSuccess="uploadAnnexSuccess" />
</el-form-item> </el-form-item>
<template v-if="isPractice">
<el-form-item label="比赛方式">
<el-radio-group v-model="form.type">
<el-radio :label="0">实训</el-radio>
<el-radio :label="1">理论</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="比赛内容">
<el-button style="margin-bottom: 10px;" size="small" type="primary">选择理论试卷</el-button>
<el-table :data="list" class="table" ref="table" stripe header-align="center" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="name" label="试卷名称" align="center" min-width="100"></el-table-column>
<el-table-column prop="questionCount" label="试题总数" align="center" width="70"></el-table-column>
<el-table-column prop="score" label="总分" align="center" width="60"></el-table-column>
<el-table-column prop="questionType" label="题型" align="center" min-width="90"
show-overflow-tooltip></el-table-column>
<el-table-column prop="difficult" label="试卷难度" align="center" width="100" sortable="custom">
<!-- <template slot-scope="scope">{{ difficults.find(e => e.id === scope.row.difficult) ? difficults.find(e
=>
e.id === scope.row.difficult).name : '' }}</template> -->
</el-table-column>
<el-table-column prop="suggestTime" label="建议用时" align="center" width="70">
<template slot-scope="scope">{{ scope.row.suggestTime }}min</template>
</el-table-column>
<el-table-column prop="classificationPath" label="试卷分类" align="center" width="90"
show-overflow-tooltip></el-table-column>
<el-table-column label="建议用途" align="center" width="70">
<!-- <template slot-scope="scope">{{ paperTypes.find(e => e.id === scope.row.paperType) ? paperTypes.find(e
=>
e.id === scope.row.paperType).name : '' }}</template> -->
</el-table-column>
<el-table-column prop="updateTime" label="最近编辑时间" align="center" width="160"
sortable="custom"></el-table-column>
<el-table-column prop="createUser" label="最近编辑人" align="center" width="90"></el-table-column>
<el-table-column label="操作" align="center" width="240">
<template slot-scope="scope">
<el-button type="text" @click="toDetail(scope.row, 1)">复制</el-button>
<!-- <el-button type="text" @click="edit(scope.row)">预览</el-button> -->
<el-button type="text" @click="toDetail(scope.row)">编辑</el-button>
<el-button type="text" @click="del(scope.row)">删除</el-button>
<el-switch v-if="!scope.row.status" v-model="scope.row.isDisable" :active-value="false"
:inactive-value="true" style="margin: 0 10px 0 5px" :active-text="scope.row.isDisable ? '关' : '开'"
@change="switchOff($event, scope.row, scope.$index)"></el-switch>
</template>
</el-table-column>
</el-table>
</el-form-item>
</template>
</el-form> </el-form>
</div> </div>
</div> </div>
@ -293,6 +348,11 @@ export default {
quill, quill,
Upload Upload
}, },
computed: {
isPractice () {
return this.$parent.releaseType === 2
},
},
watch: { watch: {
editing: function (val) { editing: function (val) {
this.quillShow = false this.quillShow = false

@ -104,7 +104,7 @@
阶段比赛结束后 阶段比赛结束后
<el-input v-model.number="item.resultAnnouncementTime" type="number" min="0" <el-input v-model.number="item.resultAnnouncementTime" type="number" min="0"
style="width: 120px"></el-input> style="width: 120px"></el-input>
小时公布阶段比赛成绩 小时公布阶段比赛成绩为空则不公布成绩为0则阶段比赛结束后立马公布成绩
</div> </div>
<div <div
v-if="item.resultAnnouncementTime !== '' && item.resultAnnouncementTime !== null && item.resultAnnouncementTime !== undefined" v-if="item.resultAnnouncementTime !== '' && item.resultAnnouncementTime !== null && item.resultAnnouncementTime !== undefined"
@ -136,13 +136,15 @@
</div> </div>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item prop="rule" label="成绩公布时间"> <el-form-item label="成绩公布时间">
阶段比赛结束后 阶段比赛结束后
<el-input v-model.number="form.competitionStageList[0].resultAnnouncementTime" type="number" min="0" <el-input v-model.number="form.competitionStageList[0].resultAnnouncementTime" type="number" min="0"
style="width: 120px"></el-input> style="width: 120px"></el-input>
小时公布阶段比赛成绩 小时公布阶段比赛成绩为空则不公布成绩为0则阶段比赛结束后立马公布成绩
</el-form-item> </el-form-item>
<el-form-item prop="resultsDetails" label="是否公布成绩详情"> <el-form-item
v-if="form.competitionStageList[0].resultAnnouncementTime !== '' && form.competitionStageList[0].resultAnnouncementTime !== null && form.competitionStageList[0].resultAnnouncementTime !== undefined"
prop="resultsDetails" label="是否公布成绩详情">
<el-radio v-model="form.competitionStageList[0].resultsDetails" :label="0"></el-radio> <el-radio v-model="form.competitionStageList[0].resultsDetails" :label="0"></el-radio>
<el-radio v-model="form.competitionStageList[0].resultsDetails" :label="1"></el-radio> <el-radio v-model="form.competitionStageList[0].resultsDetails" :label="1"></el-radio>
<p class="tips">若选择则公布成绩详情竞赛结束后参赛者可查看自己的比赛成绩得分详情</p> <p class="tips">若选择则公布成绩详情竞赛结束后参赛者可查看自己的比赛成绩得分详情</p>
@ -320,12 +322,12 @@ export default {
// //
if (this.step1.completeCompetitionSetup.competitionType) { if (this.step1.completeCompetitionSetup.competitionType) {
const { form, originForm } = this const { form, originForm } = this
// 34 // 34
let changeLimit = 0 let changeLimit = 0
for (const i in form.competitionStageList) { for (const i in form.competitionStageList) {
const e = form.competitionStageList[i] const e = form.competitionStageList[i]
if (e.teamNumLimit !== originForm.competitionStageList[i].teamNumLimit || e.customNumber !== originForm.competitionStageList[i].customNumber) { const originStage = originForm.competitionStageList[i]
if (!originStage || e.teamNumLimit !== originStage.teamNumLimit || e.customNumber !== originStage.customNumber) {
changeLimit = 1 changeLimit = 1
break break
} }

@ -22,6 +22,7 @@
</el-alert> </el-alert>
</div> </div>
</el-form-item> </el-form-item>
<!-- 其他赛事 -->
<template v-if="item.method === 2"> <template v-if="item.method === 2">
<el-form-item class="req" label="比赛地点"> <el-form-item class="req" label="比赛地点">
<el-input v-model="item.offlineAddress" style="width: 80%"></el-input> <el-input v-model="item.offlineAddress" style="width: 80%"></el-input>
@ -70,12 +71,25 @@
</el-form-item> </el-form-item>
</template> </template>
<template v-else> <template v-else>
<template v-if="item.method === 0">
<el-form-item class="req" prop="cid" label="课程系统"> <el-form-item class="req" prop="cid" label="课程系统">
{{ item.systemName }} {{ item.systemName }}
</el-form-item> </el-form-item>
<el-form-item class="req" prop="assessmentId" label="已选择考核"> <el-form-item class="req" prop="assessmentId" label="已选择考核">
{{ item.projectName }} {{ item.projectName }}
</el-form-item> </el-form-item>
</template>
<template v-else>
<el-form-item class="req" label="已选择试卷">
<div class="flex">
{{ item.paperName }}&emsp;
<el-form>
<el-button v-if="item.paperName" type="primary" size="mini" :disabled="false"
@click="previewPaper(item)">预览</el-button>
</el-form>
</div>
</el-form-item>
</template>
<el-form-item class="req" prop="resultAnnouncementTime" label="比赛地点"> <el-form-item class="req" prop="resultAnnouncementTime" label="比赛地点">
<div class="line"> <div class="line">
<el-checkbox v-model="item.onlineButton">线上</el-checkbox> <el-checkbox v-model="item.onlineButton">线上</el-checkbox>
@ -94,8 +108,7 @@
</div> </div>
</div> </div>
<set v-if="setVisible" :form.sync="form[curStep]" :step1.sync="step1" @hideSet="hideSet" /> <Set v-if="setVisible" :form.sync="form[curStep]" :step1.sync="step1" @hideSet="hideSet" />
<el-dialog title="提示" :visible.sync="tipsVisible" width="500px" :close-on-click-modal="false" <el-dialog title="提示" :visible.sync="tipsVisible" width="500px" :close-on-click-modal="false"
custom-class="tips-dia"> custom-class="tips-dia">
@ -113,11 +126,13 @@
</template> </template>
<script> <script>
import Set from './set'
import Oss from '@/components/upload/upload.js' import Oss from '@/components/upload/upload.js'
import Setting from '@/setting'
import Util from '@/libs/util' import Util from '@/libs/util'
import set from './set'
export default { export default {
props: ['setupId', 'competitionId', 'editing'], props: ['setupId', 'competitionId', 'editing'],
components: { Set },
data () { data () {
return { return {
headers: { headers: {
@ -151,6 +166,8 @@ export default {
stageId: '', stageId: '',
startTime: '', startTime: '',
systemId: '', systemId: '',
paperId: '',
paperName: '',
offlineAddress: '', offlineAddress: '',
offlineButton: 0, offlineButton: 0,
onlineAddress: '', onlineAddress: '',
@ -166,9 +183,6 @@ export default {
tipsVisible: false, tipsVisible: false,
}; };
}, },
components: {
set
},
watch: { watch: {
// , // ,
form: { form: {
@ -237,8 +251,10 @@ export default {
form.method = e.method form.method = e.method
form.stageId = e.stageId form.stageId = e.stageId
form.stageName = e.stageName form.stageName = e.stageName
if (form.paperName) form.originPaperName = form.paperName //
this.form.push(form) this.form.push(form)
}) })
this.resumeData() this.resumeData()
this.$nextTick(() => { this.$nextTick(() => {
this.updateTime = 0 this.updateTime = 0
@ -258,6 +274,19 @@ export default {
this.setVisible = false this.setVisible = false
this.$parent.showBtns = true this.$parent.showBtns = true
}, },
//
previewPaper (row) {
let url = `${location.origin}/examination`
if (Setting.isDev) {
url = `http://192.168.31.125:8098/`
} else if (Setting.isPro) {
const { host } = location
url = `https://${host === 'dev.huorantech.cn' ? host : 'www.huorantech.cn'}/examination/`
}
url += `#/testPaper/preview?id=${row.paperId}&token=${sessionStorage.getItem('token')}`
localStorage.setItem('exam_token', sessionStorage.getItem('token'))
window.open(url)
},
// //
timeChange (val) { timeChange (val) {
if (val.length) { if (val.length) {
@ -363,6 +392,7 @@ export default {
this.$confirm('团队赛发布成功,由于您设置的报名时间已结束,如需自动分配阶段参赛人员,请前往报名人员列表进行设置', '提示', { this.$confirm('团队赛发布成功,由于您设置的报名时间已结束,如需自动分配阶段参赛人员,请前往报名人员列表进行设置', '提示', {
confirmButtonText: '关闭', confirmButtonText: '关闭',
type: 'success', type: 'success',
showCancelButton: false,
closeOnClickModal: false, closeOnClickModal: false,
dangerouslyUseHTMLString: true, dangerouslyUseHTMLString: true,
showClose: false, showClose: false,
@ -377,6 +407,10 @@ export default {
this.$emit('next', next) this.$emit('next', next)
} }
}, },
// websocket
async sendSocket () {
await this.$post(`${this.api.refreshPageNotification}?content=1`)
},
// //
save (status, next = 0) { save (status, next = 0) {
const { form } = this const { form } = this
@ -401,11 +435,16 @@ export default {
Util.errorMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。') Util.errorMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。')
break break
} }
if (e.method !== 2 && !e.cid) { if (e.method === 0 && !e.cid) {
invalid = 1 invalid = 1
Util.errorMsg('请选择课程') Util.errorMsg('请选择课程')
break break
} }
if (e.method === 1 && !e.paperId) {
invalid = 1
Util.errorMsg('请选择试卷')
break
}
if (e.method === 2) { // 线 if (e.method === 2) { // 线
if (!e.offlineAddress) { if (!e.offlineAddress) {
invalid = 1 invalid = 1
@ -470,7 +509,10 @@ export default {
}).then(res => { }).then(res => {
this.$parent.hideLoad() this.$parent.hideLoad()
// //
status && this.publish(status) if (status) {
this.publish(status)
this.sendSocket()
}
Util.successMsg((status ? '发布' : '保存') + '成功') Util.successMsg((status ? '发布' : '保存') + '成功')
this.updateTime = 0 this.updateTime = 0
if (status && this.$parent.$refs.step1.form.completeCompetitionSetup.competitionType) { if (status && this.$parent.$refs.step1.form.completeCompetitionSetup.competitionType) {

@ -0,0 +1,211 @@
<template>
<!-- 理论考试选择试卷 -->
<div>
<el-dialog title="请选择试卷" :visible.sync="listVisible" width="1200px" :close-on-click-modal="false"
@closed="closeDia">
<div class="tool">
<ul class="filter">
<li>
<label>试卷库</label>
<el-select v-model="filter.libraryId" placeholder="请选择试卷库" @change="initData">
<el-option v-for="(item, i) in paperLibraries" :key="i" :label="item.libraryName" :value="item.libraryId">
</el-option>
</el-select>
</li>
<li>
<label>建议用途</label>
<el-select v-model="filter.paperType" clearable placeholder="请选择状态" @change="initData">
<el-option v-for="(item, i) in paperTypes" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
<li>
<label>试卷难度</label>
<el-select v-model="filter.difficult" clearable multiple placeholder="请选择试卷难度" @change="initData">
<el-option v-for="(item, i) in difficults" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
<li>
<label>题目类型</label>
<el-select v-model="questionType" clearable multiple placeholder="请选择题目类型" @change="initData">
<el-option v-for="(item, i) in questionTypes" :key="i" :label="item.name" :value="item.name"></el-option>
</el-select>
</li>
<li>
<label>搜索</label>
<el-input style="width: 250px;" placeholder="请输入试卷名称" prefix-icon="el-icon-search" v-model="filter.keyWord"
clearable />
</li>
</ul>
<div>
<!-- <el-button type="primary" @click="add">自定义理论试卷</el-button> -->
</div>
</div>
<el-table :data="papers" class="table" stripe header-align="center" @sort-change="sortChange">
<el-table-column width="60" label="选择" align="center">
<template slot-scope="scope">
<el-radio v-model="form.paperId" :label="scope.row.paperId">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="name" label="试卷名称" min-width="140" align="center"></el-table-column>
<el-table-column prop="questionCount" label="试题总数" align="center" min-width="70"></el-table-column>
<el-table-column prop="score" label="总分" align="center" min-width="70"></el-table-column>
<el-table-column prop="questionType" label="题型" align="center" min-width="90"
show-overflow-tooltip></el-table-column>
<el-table-column prop="difficult" label="试卷难度" align="center" min-width="70" sortable="custom">
<template slot-scope="scope">{{ difficults.find(e => e.id === scope.row.difficult) ? difficults.find(e =>
e.id === scope.row.difficult).name : '' }}</template>
</el-table-column>
<el-table-column prop="suggestTime" label="建议用时" align="center" min-width="70">
<template slot-scope="scope">{{ scope.row.suggestTime }}min</template>
</el-table-column>
<el-table-column prop="classificationPath" label="试卷分类" align="center" min-width="70"
show-overflow-tooltip></el-table-column>
<el-table-column label="建议用途" align="center" min-width="70">
<template slot-scope="scope">{{ paperTypes.find(e => e.id === scope.row.paperType) ? paperTypes.find(e =>
e.id === scope.row.paperType).name : '' }}</template>
</el-table-column>
<el-table-column prop="updateTime" label="最近编辑时间" align="center" width="170"
sortable="custom"></el-table-column>
<el-table-column prop="createUser" label="最近编辑人" align="center" width="110"></el-table-column>
<el-table-column label="操作" align="center" width="80">
<template slot-scope="scope">
<el-button type="text" @click="previewPaper(scope.row)">预览</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background :page-size="pageSize" @current-change="handleCurrentChange"
layout="total,prev, pager, next" :total="total"></el-pagination>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="listVisible = false">取消</el-button>
<el-button type="primary" :loading="submiting" @click="submit">确定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import Setting from '@/setting'
import Util from '@/libs/util'
import _ from 'lodash'
import QuesConst from '@/const/ques'
import TestPaperConst from '@/const/testPaper'
export default {
props: ['visible', 'form'],
data () {
return {
arabicToChinese: Util.arabicToChinese,
questionTypes: QuesConst.questionTypes,
difficults: TestPaperConst.difficults,
paperTypes: TestPaperConst.paperTypes,
listVisible: false,
searchTimer: null,
questionType: [],
paperLibraries: [],
filter: {
libraryId: '',
paperType: '',
difficult: [],
keyWord: '',
},
list: [],
page: 1,
pageSize: 10,
total: 0,
paperId: '',
submiting: false,
};
},
watch: {
'filter.keyWord': function (val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(this.initData, 500)
},
visible () {
this.listVisible = this.visible
this.visible && this.getList()
}
},
mounted () {
this.originForm = _.cloneDeep(this.form)
},
methods: {
//
async getList () {
try {
const res = await this.$post(this.api.examPaperList, {
...this.filter,
pageNum: this.page,
pageSize: this.pageSize,
type: 1,
keyWord: this.keyword,
libraryId: this.systemId
})
this.papers = res.pageList.records
this.total = res.pageList.total
} catch (e) { }
},
//
currentChange (val) {
this.page = val
this.getList()
},
handleCurrentChange (val) {
this.page = val
this.getList()
},
initData () {
this.page = 1
this.getList()
},
//
sortChange (column) {
if (column.prop === 'updateTime') this.filter.updateTimeOrder = column.order ? column.order === 'ascending' ? 1 : 2 : ''
this.getList()
},
//
add () {
this.form = _.cloneDeep(this.originForm)
this.detailVisible = true
},
//
previewPaper (row) {
this.$parent.previewPaper(row)
},
//
async submit () {
const { paperId } = this.form
if (!paperId) return Util.warningMsg('请选择试卷')
const curPaper = this.papers.find(e => e.paperId === paperId)
if (curPaper) this.form.paperName = curPaper.name
this.handlePaper()
},
//
async handlePaper () {
const { form } = this
// id
if (form.paperName !== form.originPaperName) {
const res = await this.$post(this.api.copyExamPaper, {
associatedID: form.stageId,
paperId: form.paperId,
typeId: 1
})
if (res.examPaper) {
form.paperId = res.examPaper.paperId
}
}
},
//
closeDia () {
this.$emit('update:visible', false)
}
}
};
</script>
<style lang="scss" scoped></style>

@ -29,17 +29,35 @@
<div class="tool mul"> <div class="tool mul">
<ul class="filter"> <ul class="filter">
<li> <li>
<label>赛来源</label> <label>赛来源</label>
<el-select v-model="form.platformSource" clearable @change="sourceChange"> <el-select v-model="form.platformSource" clearable @change="initData">
<el-option v-for="(item, i) in sourceList" :key="i" :label="item.name" :value="item.id"></el-option> <el-option v-for="(item, i) in sourceList" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select> </el-select>
</li> </li>
<li> <li>
<label>大赛范围</label> <label>发布类型</label>
<el-select v-model="form.competitionScope" clearable @change="initData"> <el-select v-model="form.releaseType" clearable @change="initData">
<el-option v-for="(item, i) in releaseTypes" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
<li>
<label>竞赛范围</label>
<el-select v-model="form.competitionScope" @change="initData">
<el-option v-for="(item, i) in rangeList" :key="i" :label="item.name" :value="item.id"></el-option> <el-option v-for="(item, i) in rangeList" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select> </el-select>
</li> </li>
<li>
<label>竞赛类型</label>
<el-select v-model="form.competitionType" clearable @change="initData">
<el-option v-for="(item, i) in competitionTypes" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
<li>
<label>状态</label>
<el-select v-model="form.publishStatus" clearable @change="initData">
<el-option v-for="(item, i) in publishStatus" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
</ul> </ul>
<div> <div>
<el-button type="primary" round @click="add" v-auth>创建竞赛</el-button> <el-button type="primary" round @click="add" v-auth>创建竞赛</el-button>
@ -56,34 +74,39 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="competitionName" label="竞赛名称" align="center"></el-table-column> <el-table-column prop="competitionName" label="竞赛名称" align="center"></el-table-column>
<el-table-column prop="name" label="竞赛类型" width="90" align="center"> <el-table-column prop="name" label="竞赛来源" width="90" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.competitionType ? '团队赛' : '个人赛' }} {{ sourceList.find(e => e.id === scope.row.platformSource).name }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="founderName" label="创建人" align="center"></el-table-column> <el-table-column prop="name" label="发布类型" width="110" align="center">
<el-table-column prop="name" label="大赛来源" width="110" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ sourceList.find(e => e.id === scope.row.platformSource).name }} {{ scope.row.releaseType ? '设置完整比赛' : '练习赛' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="name" label="大赛范围" align="center"> <el-table-column prop="name" label="竞赛范围" width="100" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ rangeList.find(e => e.id === scope.row.competitionScope).name }} {{ rangeList.find(e => e.id === scope.row.competitionScope).name }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="name" label="竞赛类型" width="90" align="center">
<template slot-scope="scope">
{{ scope.row.competitionType ? '团队赛' : '个人赛' }}
</template>
</el-table-column>
<el-table-column prop="applicantNum" label="报名人数" align="center" width="100"></el-table-column> <el-table-column prop="applicantNum" label="报名人数" align="center" width="100"></el-table-column>
<el-table-column prop="status" label="状态" align="center" width="80"> <el-table-column prop="status" label="状态" align="center" width="80">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.publishStatus ? '已发布' : '未发布' }} {{ scope.row.publishStatus ? '已发布' : '未发布' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="time" label="赛时间" align="center" width="290"> <el-table-column prop="time" label="赛时间" align="center" width="290">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.playStartTime }} ~ {{ scope.row.playEndTime }} {{ scope.row.playStartTime }} ~ {{ scope.row.playEndTime }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center" width="160"></el-table-column> <el-table-column prop="createTime" label="创建时间" align="center" width="160"></el-table-column>
<el-table-column prop="founderName" label="创建人" width="130" align="center"></el-table-column>
<el-table-column label="操作" align="center" width="280"> <el-table-column label="操作" align="center" width="280">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click="copy(scope.row)">复制</el-button> <el-button type="text" @click="copy(scope.row)">复制</el-button>
@ -128,7 +151,7 @@
</template> </template>
<script> <script>
import util from "@/libs/util"; import Util from '@/libs/util'
import Bus from '@/libs/bus' import Bus from '@/libs/bus'
import qs from 'qs' import qs from 'qs'
export default { export default {
@ -150,11 +173,25 @@ export default {
name: "院校创建" name: "院校创建"
} }
], ],
rangeList: [ releaseTypes: [
{ {
id: '', id: '',
name: "不限" name: "不限"
}, },
{
id: 0,
name: '发布信息'
},
{
id: 1,
name: '完整比赛'
}
],
rangeList: [
{
id: null,
name: "不限"
},
{ {
id: 1, id: 1,
name: "全平台" name: "全平台"
@ -168,14 +205,45 @@ export default {
name: "校内" name: "校内"
} }
], ],
competitionTypes: [
{
id: '',
name: '不限'
},
{
id: 0,
name: '个人赛'
},
{
id: 1,
name: '团队赛'
}
],
publishStatus: [
{
id: '',
name: '不限'
},
{
id: 0,
name: '未发布'
},
{
id: 1,
name: '已发布'
}
],
matchData: [], matchData: [],
form: { form: {
keyWord: this.$route.query.keyWord || null, keyWord: null,
month: +this.$route.query.month || '', month: '',
startTime: this.$route.query.startTime || '', startTime: null,
endTime: this.$route.query.endTime || '', endTime: null,
platformSource: this.$route.query.platformSource === 'null' ? null : (+this.$route.query.platformSource || 0), // (01) releaseType: '',
competitionScope: this.$route.query.competitionScope ? +this.$route.query.competitionScope : '', // (0: 1: 2.) publishStatus: '',
competitionType: '',
platformSource: 0, // (01)
competitionScope: null, // (0: 1: 2.)
}, },
multipleSelection: [], multipleSelection: [],
dateList: [ dateList: [
@ -215,13 +283,14 @@ export default {
}] }]
}, },
loading: false, loading: false,
now: '',
}; };
}, },
watch: { watch: {
"form.month": function (val) { "form.month": function (val) {
if (val) { if (val) {
let unit = 24 * 60 * 60 * 1000; let unit = 24 * 60 * 60 * 1000;
this.date = [util.formatDate("yyyy-MM-dd", new Date(new Date().getTime() - unit * 30 * val)), util.formatDate("yyyy-MM-dd", new Date(new Date().getTime() + unit))]; this.date = [Util.formatDate("yyyy-MM-dd", new Date(new Date().getTime() - unit * 30 * val)), Util.formatDate("yyyy-MM-dd", new Date(new Date().getTime() + unit))];
} else { } else {
this.date = []; this.date = [];
} }
@ -246,6 +315,18 @@ export default {
mounted () { mounted () {
const { query } = this.$route const { query } = this.$route
if (query.page) { if (query.page) {
const { keyWord, month, startTime, endTime, platformSource, competitionScope, competitionType, publishStatus, releaseType } = query
this.form = {
keyWord: keyWord || null,
month: +month || '',
startTime: startTime || null,
endTime: endTime || null,
competitionType: competitionType || '',
publishStatus: publishStatus || '',
releaseType: releaseType || '',
platformSource: platformSource === 'null' ? null : (+platformSource || 0), // (01)
competitionScope: competitionScope ? +competitionScope : null, // (0: 1: 2.)
}
this.$router.push('/match').catch(() => { }) this.$router.push('/match').catch(() => { })
} }
@ -260,53 +341,57 @@ export default {
}) })
}, },
methods: { methods: {
getData () { async getData () {
this.loading = true this.loading = true
try {
const { form } = this const { form } = this
this.$post(this.api.CompetitionPageConditionQueryByNakadai, { const { data } = await this.$post(this.api.CompetitionPageConditionQueryByNakadai, {
pageNum: this.page, pageNum: this.page,
pageSize: this.pageSize, pageSize: this.pageSize,
competitionScope: form.competitionScope === '' ? null : form.competitionScope, ...form
endTime: form.endTime || null, })
keyWord: form.keyWord, this.matchData = data.records
platformSource: form.platformSource,
startTime: form.startTime || null, this.now = await Util.getNow()
}).then(({ data }) => { clearInterval(this.timer)
const list = data.records this.handleBeganStage()
//
this.timer = setInterval(() => { this.timer = setInterval(() => {
const now = new Date() this.now = new Date(this.now.setSeconds(this.now.getSeconds() + 1))
list.map(e => { this.handleBeganStage()
}, 1000)
this.total = data.total
this.$refs.table.clearSelection()
this.loading = false
if (!this.matchData.length && this.total) {
this.page--
this.getData()
}
} catch (e) {
this.loading = false
}
},
//
async handleBeganStage () {
this.matchData.map(e => {
if (!e.playingStages) { if (!e.playingStages) {
this.$set(e, 'playingStages', []) this.$set(e, 'playingStages', [])
} else { } else {
e.playingStages = [] e.playingStages = []
} }
// //
if (now >= new Date(e.playStartTime) && now <= new Date(e.playEndTime)) { if (this.now >= new Date(e.playStartTime) && this.now <= new Date(e.playEndTime)) {
// //
if (e.competitionStageList) { if (e.competitionStageList) {
for (const n of e.competitionStageList) { for (const n of e.competitionStageList) {
// //
if (now >= new Date(n.startTime) && now <= new Date(n.endTime)) { if (this.now >= new Date(n.startTime) && this.now <= new Date(n.endTime)) {
e.playingStages.push(n) e.playingStages.push(n)
} }
} }
} }
} }
}) })
}, 1000)
this.matchData = list
this.total = data.total
this.$refs.table.clearSelection()
this.loading = false
if (!this.matchData.length && this.total) {
this.page--
this.getData()
}
}).catch(res => {
this.loading = false
})
}, },
initData () { initData () {
this.page = 1; this.page = 1;
@ -326,7 +411,7 @@ export default {
type: "warning" type: "warning"
}).then(async () => { }).then(async () => {
await this.$post(`${this.api.copyCompetition}?competitionId=${row.id}`) await this.$post(`${this.api.copyCompetition}?competitionId=${row.id}`)
util.successMsg('复制成功') Util.successMsg('复制成功')
this.initData() this.initData()
}).catch(() => { }) }).catch(() => { })
}, },
@ -349,7 +434,7 @@ export default {
competitionContents: data competitionContents: data
}).then(async res => { }).then(async res => {
await this.$post(`${this.api.refreshPageNotification}?content=1`) await this.$post(`${this.api.refreshPageNotification}?content=1`)
util.successMsg('修改成功') Util.successMsg('修改成功')
this.modifyVisible = false this.modifyVisible = false
this.getData() this.getData()
}).catch(err => { }) }).catch(err => { })
@ -374,7 +459,7 @@ export default {
}) })
.then(() => { .then(() => {
this.$post(`${this.api.batchDeleteCompetition}?competitionIds=${row.id}`).then(res => { this.$post(`${this.api.batchDeleteCompetition}?competitionIds=${row.id}`).then(res => {
util.successMsg("删除成功"); Util.successMsg("删除成功");
this.getData(); this.getData();
}).catch(res => { }).catch(res => {
}); });
@ -419,7 +504,7 @@ export default {
isOpen: val, isOpen: val,
type: 0 // (01) type: 0 // (01)
}).then(res => { }).then(res => {
util.successMsg(val == 1 ? '禁用成功' : '启用成功') Util.successMsg(val == 1 ? '禁用成功' : '启用成功')
}).catch(err => { }) }).catch(err => { })
await this.$post(`${this.api.refreshPageNotification}?content=1`) await this.$post(`${this.api.refreshPageNotification}?content=1`)

@ -42,7 +42,6 @@ export default {
tab3: "竞赛进展", tab3: "竞赛进展",
tab4: "公告通知", tab4: "公告通知",
tab5: "报名人员", tab5: "报名人员",
tab6: '查看异常团队'
} }
}; };
}, },
@ -55,7 +54,11 @@ export default {
AbnormalTeam AbnormalTeam
}, },
mounted () { mounted () {
Setting.dynamicRoute && this.initTabs() // if (Setting.dynamicRoute) {
this.initTabs()
// } else {
// this.active = this.$route.query.tab || 'tab1'
// }
}, },
methods: { methods: {
async initTabs () { async initTabs () {
@ -73,7 +76,12 @@ export default {
tab3 || this.$delete(this.tabs, 'tab3') tab3 || this.$delete(this.tabs, 'tab3')
tab4 || this.$delete(this.tabs, 'tab4') tab4 || this.$delete(this.tabs, 'tab4')
tab5 || this.$delete(this.tabs, 'tab5') tab5 || this.$delete(this.tabs, 'tab5')
res.competition.completeCompetitionSetup.competitionType || this.$delete(this.tabs, 'tab6')
if (res.competition.completeCompetitionSetup.competitionType) {
this.tabs.tab6 || this.$set(this.tabs, 'tab6', '查看异常团队')
} else {
this.tabs.tab6 && this.$delete(this.tabs, 'tab6')
}
const type = this.$route.query.tab const type = this.$route.query.tab
const keys = Object.keys(this.tabs) const keys = Object.keys(this.tabs)
@ -117,7 +125,7 @@ export default {
// tab // tab
tabSwitch (i) { tabSwitch (i) {
this.active = i this.active = i
this.$router.push(`/matchManage?id=${this.$route.query.id}&tab=${i}&name=${this.name}`) this.$router.push(`/matchManage?id=${this.$route.query.id}&tab=${i}&name=${this.name}`).catch(e => { })
}, },
// tab // tab
backOrTab (i) { backOrTab (i) {

@ -1,61 +1,57 @@
<template> <template>
<!-- 报名人员 --> <!-- 报名人员 -->
<div class="page-content" <div class="page-content" style="padding: 24px">
style="padding: 24px"> <el-table ref="table" :data="list" class="table" stripe header-align="center" row-key="stageId">
<el-table ref="table" <el-table-column type="index" width="60" label="序号" align="center">
:data="list"
class="table"
stripe
header-align="center"
row-key="stageId">
<el-table-column type="index"
width="60"
label="序号"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.$index + 1 }} {{ scope.$index + 1 }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="stageName" <el-table-column prop="stageName" label="阶段名称" align="center"></el-table-column>
label="阶段名称" <el-table-column prop="competitionContent" label="比赛内容" align="center"></el-table-column>
align="center"></el-table-column> <el-table-column prop="methodName" label="比赛方式" align="center"></el-table-column>
<el-table-column prop="methodName" <el-table-column label="竞赛类型" align="center">
label="比赛方式"
align="center"></el-table-column>
<el-table-column prop="founderName"
label="比赛形式"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.competitionType ? '团队赛' : '个人赛' }} {{ scope.row.competitionType ? '团队赛' : '个人赛' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="ruleName" <el-table-column prop="ruleName" label="赛制" align="center"></el-table-column>
label="赛制" <el-table-column prop="status" label="大赛状态" align="center"></el-table-column>
align="center"></el-table-column> <el-table-column prop="reviewStatus" label="评阅情况" align="center"></el-table-column>
<el-table-column prop="status" <el-table-column label="竞赛时间" width="290" align="center">
label="状态"
align="center"></el-table-column>
<el-table-column label="竞赛起止时间"
width="290"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.startTime + ' ~ ' + scope.row.endTime }} {{ scope.row.startTime + ' ~ ' + scope.row.endTime }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" align="center" width="280">
align="center"
width="260">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="primary" <el-button type="text" @click="toRank(scope.row, scope.$index)">排名</el-button>
@click="toRank(scope.row, scope.$index)">排名</el-button> <el-button type="text" @click="toArch(scope.row, scope.$index)">成绩统计</el-button>
<el-button @click="toArch(scope.row, scope.$index)">成绩管理</el-button> <!-- <el-button @click="toArch(scope.row, scope.$index)">编辑试卷</el-button> -->
<template v-if="scope.row.method === 1">
<el-button v-if="scope.row.showMyReviewTask" type="text"
@click="showReview(scope.row, '/myReview/records')">我的评阅任务</el-button>
<el-button v-auth="'/review:分配评阅任务'" type="text"
@click="showReview(scope.row, '/allocationReview')">分配评阅任务</el-button>
</template>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<el-drawer title="" :visible.sync="reviewVisible" size="100%" :close-on-click-modal="false" :withHeader="false"
custom-class="review-dia">
<div>
<button type="button" class="el-drawer__close-btn" @click="reviewVisible = false">
<i class="el-dialog__close el-icon el-icon-close"></i>
</button>
</div>
<iframe :src="reviewUrl" frameborder="0" width="100%"></iframe>
</el-drawer>
</div> </div>
</template> </template>
<script> <script>
import Setting from '@/setting'
import Const from '@/const/match' import Const from '@/const/match'
export default { export default {
name: "matchArch", name: "matchArch",
@ -66,6 +62,8 @@ export default {
form: {}, form: {},
timer: null, timer: null,
curStep: [], curStep: [],
reviewVisible: false,
reviewUrl: '',
}; };
}, },
mounted () { mounted () {
@ -125,7 +123,16 @@ export default {
this.$store.commit('setInnerReferrer', this.$route.fullPath) this.$store.commit('setInnerReferrer', this.$route.fullPath)
const cur = this.form.competitionStage[i] const cur = this.form.competitionStage[i]
const showFile = !!(cur.method === 2 && cur.competitionStageContentSetting && cur.competitionStageContentSetting.whetherToUploadFiles) const showFile = !!(cur.method === 2 && cur.competitionStageContentSetting && cur.competitionStageContentSetting.whetherToUploadFiles)
this.$router.push(`/matchArchList?id=${this.id}&stageId=${row.stageId}&method=${row.method}&competitionType=${row.competitionType}&showFile=${showFile}`) this.$router.push(`/${cur.method === 2 ? 'otherArchList' : 'matchArchList'}?id=${this.id}&stageId=${row.stageId}&method=${row.method}&competitionType=${row.competitionType}&showFile=${showFile}&showMyReviewTask=${row.showMyReviewTask}`)
},
//
showReview (row, path) {
let url = `${location.origin}/reviewCenter/`
if (Setting.isDev) url = `http://192.168.31.125:8099/`
url += `#${path}?token=${sessionStorage.getItem('token')}&v=${Date.now()}&competitionId=${this.id}&stageId=${row.stageId}`
localStorage.setItem('review_token', sessionStorage.getItem('token'))
this.reviewUrl = url
this.reviewVisible = true
} }
} }
}; };
@ -136,12 +143,26 @@ export default {
font-size: 16px; font-size: 16px;
color: #333; color: #333;
} }
.line { .line {
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
align-items: center; align-items: center;
span { span {
margin-right: 30px; margin-right: 30px;
} }
} }
/deep/.review-dia {
.el-drawer__close-btn {
position: absolute;
top: 20px;
right: 20px;
}
iframe {
height: 100%;
}
}
</style> </style>

@ -1,277 +1,191 @@
<template> <template>
<div> <div>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20 head-card">
class="m-b-20 head-card">
<div class="flex-between m-b-20"> <div class="flex-between m-b-20">
<el-page-header @back="back" <el-page-header @back="back" content="成绩管理"></el-page-header>
content="成绩管理"></el-page-header>
</div> </div>
</el-card> </el-card>
<div v-loading="loading"> <div v-loading="loading">
<el-card v-if="method != 2" <el-card v-if="method != 2" shadow="hover" class="m-b-20">
shadow="hover"
class="m-b-20">
<div class="stat"> <div class="stat">
<div class="nums"> <div class="nums">
<div class="item"> <div class="item">
<p class="name">已参加/应参加人数</p> <p class="name">已参加/应参加人数</p>
<p class="val">{{ isNaN(statData.totalNumber) ? '' : statData.attendance + '/' + statData.totalNumber }}</p> <p class="val">{{ isNaN(statData.totalNumber) ? '' : statData.attendance + '/' + statData.totalNumber }}
</p>
</div> </div>
<div class="item"> <div class="item">
<p class="name">实验平均分</p> <p class="name">平均分</p>
<p class="val">{{ avgScore }}</p> <p class="val">{{ (+statData.avgScore).toFixed(2) }}</p>
</div> </div>
<div class="item">
<p class="name">最高分</p>
<p class="val">{{ statData.maxScore }}
</p>
</div>
<div class="item">
<p class="name">最低分</p>
<p class="val">{{ statData.minScore }}</p>
</div> </div>
<div class="chart" </div>
id="chart"></div> <div class="chart" id="chart"></div>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20"> <div class="tabs m-b-20">
<div v-if="showFile" <a class="item" v-for="(item, i) in tabs" :key="i" :class="{ active: item.id === active }"
class="tabs m-b-20"> @click="tabChange(item.id)">{{ item.name }}</a>
<a class="item"
v-for="(item, i) in tabs"
:key="i"
:class="{active: i === active}"
@click="tabChange(i)">{{ item }}</a>
</div> </div>
<div class="flex-between m-b-20"> <div class="tool flex-between">
<ul class="filter">
<li>
<label>省份</label>
<el-select v-model="filter.provinceId" filterable clearable placeholder="请选择省份" @change="provinceChange"
@clear="clearProvince">
<el-option v-for="(item, i) in provinces" :key="i" :label="item.provinceName"
:value="item.provinceId"></el-option>
</el-select>
</li>
<li>
<label>城市</label>
<el-select v-model="filter.cityId" filterable clearable placeholder="请选择城市" :disabled="!filter.provinceId"
@change="initData">
<el-option v-for="(item, i) in cities" :key="i" :label="item.cityName" :value="item.cityId"></el-option>
</el-select>
</li>
<li>
<label>学校</label>
<el-select v-model="filter.realSchoolId" clearable filterable placeholder="请选择学校" @change="initData">
<el-option v-for="(item, i) in schools" :key="i" :label="item.schoolName"
:value="item.schoolId"></el-option>
</el-select>
</li>
<li v-if="active">
<label>评阅状态</label>
<el-select v-model="filter.reviewStatus" clearable placeholder="请选择评阅状态" @change="initData">
<el-option value="待评阅"></el-option>
<el-option value="已评阅"></el-option>
</el-select>
</li>
<li>
<el-input size="small" placeholder="请输入学生姓名、学生学号、团队名称" prefix-icon="el-icon-search" v-model="keyword"
clearable style="width: 300px"></el-input>
</li>
</ul>
<div> <div>
<el-input size="small" <template v-if="active && method === 1">
placeholder="请输入学校/学生姓名" <el-button v-auth="'/review:分配评阅任务'" type="primary" size="mini"
prefix-icon="el-icon-search" @click="showReview('/allocationReview')">分配评阅任务</el-button>
v-model="keyword" <el-button v-if="showMyReviewTask" type="primary" size="mini"
clearable @click="showReview('/myReview/records')">我的评阅任务</el-button>
style="width: 300px"></el-input> <el-button type="primary" size="mini" @click="exportFiles">导出答题文件</el-button>
</div> </template>
<div v-if="!active"> <el-button type="primary" size="mini" :loading="exportingList" @click="exportList">{{ exportingList ? '正在导出'
<el-button v-if="method == 2" :
type="primary" '导出成绩列表'
@click="batchImport">上传成绩</el-button> }}</el-button>
<el-button type="primary" <template v-if="active">
:disabled="!!multipleSelection.find(e => method != 2 && !e.reportId)" <el-button type="primary" size="mini" :loading="exportingReport" @click="exporReport">{{ exportingReport ?
@click="delAllData">批量删除</el-button> '正在导出' :
<el-button type="primary" '导出成绩报告'
:loading="exporting" }}</el-button>
@click="exportData">{{ exporting ? '正在导出' : '批量导出' }}</el-button> <el-button type="primary" size="mini" @click="delAllData">批量删除</el-button>
</div> </template>
<div v-else>
<el-button type="primary"
:loading="exporting1"
@click="exportData1">{{ exporting1 ? '正在导出' : '批量导出' }}</el-button>
</div> </div>
</div> </div>
<template v-if="!active"> <el-table :data="list" class="table" :key="1" ref="table" stripe header-align="center"
<el-table :data="list" @selection-change="handleSelectionChange" row-key="id" @sort-change="sortChange">
class="table" <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
:key="1" <el-table-column type="index" width="60" label="序号" align="center">
ref="table"
stripe
header-align="center"
@selection-change="handleSelectionChange"
row-key="id">
<el-table-column type="selection"
width="55"
align="center"
:reserve-selection="true"></el-table-column>
<el-table-column type="index"
width="60"
label="序号"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.$index + (page - 1) * pageSize + 1 }} {{ scope.$index + (page - 1) * pageSize + 1 }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="schoolName" <el-table-column prop="provinceName" label="省份" min-width="100" align="center"></el-table-column>
label="学生账号归属" <el-table-column prop="cityName" label="城市" min-width="100" align="center"></el-table-column>
min-width="100" <el-table-column prop="schoolName" label="学生账号归属" min-width="100" align="center"></el-table-column>
<el-table-column prop="realSchool" label="学生所在院校" min-width="100" align="center"></el-table-column>
<el-table-column v-if="competitionType" prop="teamName" label="团队名称" min-width="100"
align="center"></el-table-column> align="center"></el-table-column>
<el-table-column prop="realSchool" <el-table-column prop="userName" label="学生姓名" min-width="100" align="center"></el-table-column>
label="学生所在院校" <el-table-column prop="workNumber" label="学号" min-width="100" align="center"></el-table-column>
min-width="100" <el-table-column prop="score" label="成绩" width="90" align="center" sortable="custom">
align="center"></el-table-column>
<el-table-column v-if="competitionType"
prop="teamName"
label="团队名称"
min-width="100"
align="center"></el-table-column>
<el-table-column prop="userName"
label="学生姓名"
min-width="100"
align="center"></el-table-column>
<el-table-column prop="workNumber"
label="学号"
min-width="100"
align="center"></el-table-column>
<el-table-column prop="score"
label="分数"
width="90"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.submitTime ? scope.row.score : '--' }} {{ scope.row.submitTime ? scope.row.score : '--' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="timeSum" <el-table-column prop="timeSum" label="用时" width="90" align="center">
label="耗时"
width="90"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.timeSum ? scope.row.timeSum + 'min' : '--' }} {{ scope.row.timeSum ? scope.row.timeSum + 'min' : '--' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="submitTime" <el-table-column prop="submitTime" label="提交时间" min-width="150" align="center" sortable="custom">
label="提交时间"
min-width="150"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.submitTime || '--' }} {{ scope.row.submitTime || '--' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="状态" <el-table-column label="状态" width="100" align="center">
width="100"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.reportId || method == 2 ? '已参加' : '未参加' }} {{ scope.row.reportId || method == 2 ? '已参加' : '未参加' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column prop="evaluationStatus" label="评阅状态" align="center" width="90">
align="center"
width="160">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button v-if="method != 2 && scope.row.reportId" <span v-if="scope.row.reviewStatus === '-'">-</span>
type="text" <el-tag v-else :type="scope.row.reviewStatus === '待评阅' ? 'danger' : 'success'">{{ scope.row.reviewStatus
@click="show(scope.row)">查看成绩报告</el-button> }}</el-tag>
<el-button v-if="scope.row.reportId"
type="text"
@click="handleDelete(scope.row)">删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> <el-table-column v-if="active" label="操作" align="center" width="300">
<div class="pagination"> <template v-if="scope.row.reportId" slot-scope="scope">
<el-pagination background <template v-if="method === 1">
layout="total, prev, pager, next" <el-popover placement="top" trigger="click" popper-class="files-tip">
:total="total" <div>
@current-change="handleCurrentChange" <ul class="match-files">
:current-page="page"> <li v-for="(file, i) in scope.row.files" :key="i" @click="preview(file.attachmentUrl)">{{
</el-pagination> file.attachmentName }}</li>
</ul>
</div> </div>
<el-button slot="reference" :disabled="!scope.row.hasFile" type="text"
@click="showFiles(scope.row)">查看答题文件</el-button>
</el-popover>
<el-button style="margin-left: 10px;" :disabled="!scope.row.hasFile" type="text"
@click="downloadFile(scope.row)">下载答题文件</el-button>
</template> </template>
<template v-else> <el-button v-if="method != 2" type="text" @click="toReport(scope.row)">查看成绩报告</el-button>
<el-table :data="list1" <el-button type="text" @click="handleDelete(scope.row)">删除</el-button>
class="table"
:key="2"
stripe
header-align="center"
@selection-change="handleSelectionChange1"
row-key="id">
<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">
<template slot-scope="scope">
{{ scope.$index + (page1 - 1) * pageSize + 1 }}
</template>
</el-table-column>
<el-table-column prop="schoolName"
label="学生账号归属"
align="center"></el-table-column>
<el-table-column prop="realSchool"
label="学生所在院校"
align="center"></el-table-column>
<el-table-column v-if="competitionType"
prop="teamName"
label="团队名称"
align="center"></el-table-column>
<el-table-column prop="userName"
label="学生姓名"
align="center"></el-table-column>
<el-table-column prop="workNumber"
label="学号"
align="center"></el-table-column>
<el-table-column prop="fileName"
label="文件名"
align="center"></el-table-column>
<el-table-column prop="fileSize"
label="文件大小"
align="center"></el-table-column>
<el-table-column prop="fileType"
label="文件类型"
align="center"></el-table-column>
<el-table-column prop="fileFormat"
label="文件格式"
align="center"></el-table-column>
<el-table-column prop="createTime"
label="提交时间"
width="150"
align="center">
</el-table-column>
<el-table-column label="操作"
width="200">
<template slot-scope="scope">
<el-button v-if="!isCompress(scope.row.fileFormat)"
type="text"
@click="preview(scope.row)">预览文件</el-button>
<el-button type="primary"
size="mini"
:loading="scope.row.loading"
@click="exportFile(scope.row)">导出文件</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background <el-pagination background layout="total, prev, pager, next" :total="total"
layout="total, prev, pager, next" @current-change="handleCurrentChange" :current-page="page">
:total="total1"
@current-change="handleCurrentChange1"
:current-page="page1">
</el-pagination> </el-pagination>
</div> </div>
</template>
</el-card> </el-card>
</div> </div>
<el-dialog title="批量导入"
:visible.sync="importVisible" <el-dialog title="批量导入" :visible.sync="importVisible" width="24%" :close-on-click-modal="false"
width="24%"
:close-on-click-modal="false"
@close="cancelUpload"> @close="cancelUpload">
<div style="text-align: center"> <div style="text-align: center">
<template v-if="!uploadFaild"> <template v-if="!uploadFaild">
<div style="margin-bottom: 10px;"> <div style="margin-bottom: 10px;">
<el-button type="primary" <el-button type="primary" @click="download">模板下载<i class="el-icon-download el-icon--right"></i></el-button>
@click="download">模板下载<i class="el-icon-download el-icon--right"></i></el-button>
</div> </div>
<el-upload ref="upload" <el-upload ref="upload" name="file" accept=".xls,.xlsx" class="import-file" :before-upload="beforeUpload"
name="file" :on-remove="handleRemove" :on-error="uploadError" :on-success="uploadSuccess" :before-remove="beforeRemove"
accept=".xls,.xlsx" :limit="1" :on-exceed="handleExceed" :action="this.api.batchImportGrades" :file-list="uploadList"
class="import-file" :headers="headers" :disabled="uploading" :data="{
:before-upload="beforeUpload"
:on-remove="handleRemove"
:on-error="uploadError"
:on-success="uploadSuccess"
:before-remove="beforeRemove"
:limit="1"
:on-exceed="handleExceed"
:action="this.api.batchImportGrades"
:file-list="uploadList"
:headers="headers"
:disabled="uploading"
:data="{
competitionId: this.id, competitionId: this.id,
stageId: this.stageId, stageId: this.stageId,
systemId: 0 systemId: 0
}"> }">
<el-button type="primary" <el-button type="primary" :loading="uploading" class="ml20">上传文件<i
:loading="uploading" class="el-icon-upload2 el-icon--right"></i></el-button>
class="ml20">上传文件<i class="el-icon-upload2 el-icon--right"></i></el-button>
</el-upload> </el-upload>
</template> </template>
<template v-else> <template v-else>
@ -281,29 +195,58 @@
@click="showFaild">部分数据导入失败查看失败原因</p> @click="showFaild">部分数据导入失败查看失败原因</p>
</template> </template>
</div> </div>
<span v-if="uploading" <span v-if="uploading" slot="footer" class="dialog-footer">
slot="footer"
class="dialog-footer">
<el-button @click="cancelUpload">停止导入</el-button> <el-button @click="cancelUpload">停止导入</el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-drawer title="" :visible.sync="reviewVisible" size="100%" :close-on-click-modal="false" :withHeader="false"
custom-class="review-dia">
<div>
<button type="button" class="el-drawer__close-btn" @click="reviewVisible = false">
<i class="el-dialog__close el-icon el-icon-close"></i>
</button>
</div>
<iframe :src="reviewUrl" frameborder="0" width="100%"></iframe>
</el-drawer>
<el-dialog title="图片预览" :visible.sync="previewImgVisible" width="800px" :close-on-click-modal="false">
<el-image style="max-width: 100px; max-height: 100px" :src="previewImg" :preview-src-list="[previewImg]">
</el-image>
</el-dialog>
<PdfDia :key="pdfVisible" :visible.sync="pdfVisible" :src.sync="pdfSrc" />
</div> </div>
</template> </template>
<script> <script>
import util from "@/libs/util"; import Setting from '@/setting'
import PdfDia from '@/components/pdf'
import Util from '@/libs/util'
import * as echarts from "echarts"; import * as echarts from "echarts";
import axios from 'axios'; import axios from 'axios';
import Zip from '@/libs/zip'
export default { export default {
components: {
PdfDia
},
data () { data () {
return { return {
id: +this.$route.query.id, id: +this.$route.query.id,
stageId: +this.$route.query.stageId, stageId: +this.$route.query.stageId,
method: +this.$route.query.method, method: +this.$route.query.method,
competitionType: +this.$route.query.competitionType, competitionType: +this.$route.query.competitionType,
showFile: this.$route.query.showFile === 'true', showMyReviewTask: +this.$route.query.showMyReviewTask,
isCompress: util.isCompress, isCompress: Util.isCompress,
filter: {
provinceId: '',
cityId: '',
realSchoolId: '',
reviewStatus: '',
scoreSortOrder: '',
submitTimeSortOrder: '',
},
provinces: [],
cities: [],
schools: [],
keyword: this.$route.query.keyword || '', keyword: this.$route.query.keyword || '',
searchTimer: null, searchTimer: null,
list: [], list: [],
@ -326,12 +269,34 @@ export default {
headers: { headers: {
token: sessionStorage.getItem("token") token: sessionStorage.getItem("token")
}, },
statData: {}, statData: {
tabs: ['成绩列表', '文件列表'], avgScore: 0,
active: 0, maxScore: 0,
minScore: 0,
},
tabs: [
{
id: 1,
name: '已提交'
},
{
id: 0,
name: '未提交'
}
],
active: 1,
loading: false, loading: false,
exporting: false, exportingFiles: false,
exporting1: false, exportingList: false,
exportingReport: false,
previewImgVisible: false,
previewImg: '',
pdfVisible: false,
pdfSrc: '',
reviewVisible: false,
reviewUrl: '',
}; };
}, },
watch: { watch: {
@ -351,76 +316,141 @@ export default {
}, },
mounted () { mounted () {
this.getData() this.getData()
this.getProvince()
this.getSchool()
}, },
methods: { methods: {
async getData () { async getData () {
this.loading = true this.loading = true
//
if (this.active) {
const { data } = await this.$post(this.api.cCompetitionStageFileList, {
pageNum: this.page1,
pageSize: this.pageSize,
competitionId: this.id,
stageId: this.stageId,
keyWord: this.keyword,
})
data.records.forEach(e => {
e.loading = false
e.fileType = '其他'
if (util.isVideo(e.fileFormat)) {
e.fileType = '视频'
} else if (util.isAudio(e.fileFormat)) {
e.fileType = '音频'
} else if (util.isImg(e.fileFormat)) {
e.fileType = '图片'
} else if (util.isDoc(e.fileFormat)) {
e.fileType = '文档'
} else if (util.isCompress(e.fileFormat)) {
e.fileType = '压缩包'
} else if (e.fileType === 'pdf') {
e.fileType = 'pdf'
}
})
this.list1 = data.records
this.total1 = data.total
this.loading = false
} else { //
const { data, page } = await this.$post(this.api.stageGradeManagementList, { const { data, page } = await this.$post(this.api.stageGradeManagementList, {
pageNum: this.page, pageNum: this.page,
pageSize: this.pageSize, pageSize: this.pageSize,
competitionId: this.id, competitionId: this.id,
keyWord: this.keyword, keyWord: this.keyword,
stageId: this.stageId, stageId: this.stageId,
isNakadai: 1 isNakadai: 1,
participatingState: this.active,
...this.filter
}) })
this.loading = false this.loading = false
this.total = page.total this.total = page.total
this.list = page.records this.list = page.records
this.statData = data this.statData = data
this.avgScore = (+data.avgScore).toFixed(2) this.getChart()
this.method != 2 && this.getChart()
}
}, },
initData () { initData () {
this.page = 1 this.page = 1
this.getData() this.getData()
}, },
//
async getProvince () {
const { list } = await this.$get(this.api.queryProvince)
this.provinces = list
},
//
clearProvince () {
this.filter.cityId = ''
},
//
provinceChange () {
this.clearProvince()
this.getCity()
this.initData()
},
//
async getCity () {
const id = this.filter.provinceId
if (id) {
const { list } = await this.$get(this.api.queryCity, {
provinceId: id
})
this.cities = list
}
},
//
async getSchool () {
const { list } = await this.$get(this.api.querySchoolData)
this.schools = list
},
//
sortChange (column) {
if (column.prop === 'score') this.filter.scoreSortOrder = column.order ? column.order === 'ascending' ? 'ASC' : 'DESC' : ''
if (column.prop === 'submitTime') this.filter.scoreSortOrder = column.order ? column.order === 'ascending' ? 'ASC' : 'DESC' : ''
this.getData()
},
//
async showFiles (row) {
const { data } = await this.$get(this.api.getPaperUploadFile, {
reportId: row.reportId
})
this.$set(row, 'files', data)
},
//
async downloadFile (row) {
const res = await axios.post(this.api.getPaperUploadFileZip, {
reportIds: [row.reportId],
// reportIds: [3785],
stageId: this.stageId
}, {
headers: this.headers,
responseType: 'blob'
})
const name = res.headers['content-disposition']
Util.downloadFileDirect(name ? decodeURI(name) : '答题文件.zip', new Blob([res.data]))
},
// //
show (row) { toReport (row) {
this.$router.push(`/matchReport?reportId=${row.reportId}`) this.$router.push(`/${this.method === 1 ? 'theoryReport' : 'trialReport'}?reportId=${row.reportId}`)
},
//
showReview (path) {
let url = `${location.origin}/reviewCenter/`
if (Setting.isDev) url = `http://192.168.31.125:8099/`
url += `#${path}?token=${sessionStorage.getItem('token')}&v=${Date.now()}&competitionId=${this.id}&stageId=${this.stageId}`
localStorage.setItem('review_token', sessionStorage.getItem('token'))
this.reviewUrl = url
this.reviewVisible = true
}, },
// () //
async exportData () { async exportFiles () {
if (this.list.length) { if (this.list.length) {
this.exporting = true this.exportingFiles = true
const list = this.multipleSelection
const ids = []
if (list.length) {
list.forEach(e => {
e.reportId && ids.push(e.reportId)
})
}
const res = await axios.post(this.api.getPaperUploadFileZip, {
reportIds: ids,
// reportIds: [3785],
stageId: this.stageId
}, {
headers: this.headers,
responseType: 'blob'
})
const name = res.headers['content-disposition']
Util.downloadFileDirect(name ? decodeURI(name) : '答题文件.zip', new Blob([res.data]))
this.exportingFiles = false
}
},
// ()
async exportList () {
if (this.list.length) {
this.exportingList = true
// //
if (this.multipleSelection.length) { if (this.multipleSelection.length) {
const res = await axios.post(this.api.exportExperimentalResultsInBatch, this.multipleSelection, { const res = await axios.post(this.api.exportExperimentalResultsInBatch, this.multipleSelection, {
headers: this.headers, headers: this.headers,
responseType: 'blob' responseType: 'blob'
}) })
util.downloadFileDirect(`赛事成绩.xls`, new Blob([res.data])) Util.downloadFileDirect(`赛事成绩.xls`, new Blob([res.data]))
this.exporting = false this.exportingList = false
} else if (this.list.length) { } else if (this.list.length) {
const res = await axios.post(this.api.allExperimentalResultsAreDerived, { const res = await axios.post(this.api.allExperimentalResultsAreDerived, {
pageNum: 1, pageNum: 1,
@ -428,40 +458,70 @@ export default {
competitionId: this.id, competitionId: this.id,
isNakadai: 1, isNakadai: 1,
stageId: this.stageId, stageId: this.stageId,
participatingState: this.active,
}, { }, {
headers: this.headers, headers: this.headers,
responseType: 'blob' responseType: 'blob'
}) })
util.downloadFileDirect(`赛事成绩.xls`, new Blob([res.data])) Util.downloadFileDirect(`赛事成绩.xls`, new Blob([res.data]))
this.exporting = false this.exportingList = false
} }
} }
}, },
// () // ()
exportData1 () { async exporReport () {
this.exporting1 = true if (this.list.length) {
let list = this.list1 this.exportingReport = true
if (this.multipleSelection1.length) { const list = this.multipleSelection
list = this.multipleSelection1 const ids = []
if (list.length) {
list.forEach(e => {
e.reportId && ids.push(e.reportId)
})
} }
Zip('批量导出', list, () => { let res
this.exporting1 = false //
if (this.method) {
res = await axios.post(this.api.exportExamPaperReports, {
ids,
stageId: list.length ? '' : this.stageId
}, {
headers: this.headers,
responseType: 'blob'
})
Util.downloadFileDirect('成绩报告.zip', new Blob([res.data]))
this.exportingReport = false
} else {
//
res = await axios.post(this.api.batchExportReportsAsZip, {
reportIds: ids,
stageId: this.stageId,
competitionId: this.id,
}, {
headers: this.headers,
responseType: 'blob'
}) })
Util.downloadFileDirect('成绩报告.zip', new Blob([res.data]))
this.exportingReport = false
}
}
}, },
handleDelete (row) { // async handleDelete (row) { //
this.$confirm("确定要删除吗?", "提示", { await this.$confirm(`<p>确认要删除【${row.userName}】的成绩记录吗?</p><p style="color: #f56c6c;">删除后成绩数据不可恢复,自动变为未提交</p>`, '提示', {
type: "warning" confirmButtonText: '确定',
}).then(() => { cancelButtonText: '取消',
this.$post(this.api.batchDeleteContestGrade, { type: 'warning',
closeOnClickModal: false,
dangerouslyUseHTMLString: true,
})
await this.$post(this.api.batchDeleteContestGrade, {
ids: [this.method == 2 ? row.scoreId : row.reportId], ids: [this.method == 2 ? row.scoreId : row.reportId],
competitionId: this.id, competitionId: this.id,
stageId: this.stageId stageId: this.stageId
}).then(res => { })
util.successMsg("删除成功"); Util.successMsg("删除成功")
this.getData(); this.getData()
}).catch(res => {
});
}).catch(() => { });
}, },
delAllData () { // delAllData () { //
const list = this.multipleSelection const list = this.multipleSelection
@ -483,7 +543,7 @@ export default {
await this.$post(this.api.batchDeleteContestGrade, data) await this.$post(this.api.batchDeleteContestGrade, data)
this.multipleSelection = []; this.multipleSelection = [];
this.$refs.table.clearSelection(); this.$refs.table.clearSelection();
util.successMsg("删除成功"); Util.successMsg("删除成功");
this.getData(); this.getData();
}).catch(() => { }); }).catch(() => { });
}, },
@ -505,16 +565,8 @@ export default {
handleSelectionChange1 (val) { // handleSelectionChange1 (val) { //
this.multipleSelection1 = val; this.multipleSelection1 = val;
}, },
handleCurrentChange1 (val) { //
this.page1 = val;
this.getData();
},
getChart () { // 线 getChart () { // 线
const data = [] const { fractionalSegmentCounts: data } = this.statData
const { statData } = this
for (let i = 1; i <= 10; i++) {
data.push(statData['num' + i])
}
let myChart = echarts.init(document.getElementById("chart")); let myChart = echarts.init(document.getElementById("chart"));
myChart.setOption({ myChart.setOption({
title: { text: "实验分数分布图" }, title: { text: "实验分数分布图" },
@ -524,7 +576,7 @@ export default {
type: "category", type: "category",
boundaryGap: false, boundaryGap: false,
interval: 10, interval: 10,
data: ["0-10", "10-20", "20-30", "30-40", "40-50", "50-60", "60-70", "70-80", "80-90", "90-100"] data: data.map(e => e.range)
}, },
yAxis: { yAxis: {
name: "人数", name: "人数",
@ -532,9 +584,13 @@ export default {
minInterval: 10 minInterval: 10
}, },
series: [{ series: [{
data, data: data.map(e => e.count),
type: "line", type: "line",
areaStyle: {}, areaStyle: {},
label: {
show: true,
position: 'top'
},
color: ["#8191fd"] color: ["#8191fd"]
}] }]
}); });
@ -551,12 +607,12 @@ export default {
headers: this.headers, headers: this.headers,
responseType: 'blob' responseType: 'blob'
}).then((res) => { }).then((res) => {
util.downloadFileDirect('赛事成绩导入模板.xlsx', new Blob([res.data])) Util.downloadFileDirect('赛事成绩导入模板.xlsx', new Blob([res.data]))
}).catch(res => { }) }).catch(res => { })
}, },
// //
handleExceed (files, fileList) { handleExceed (files, fileList) {
util.warningMsg( Util.warningMsg(
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!` `当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
) )
}, },
@ -566,7 +622,7 @@ export default {
headers: this.headers, headers: this.headers,
responseType: 'blob' responseType: 'blob'
}).then((res) => { }).then((res) => {
util.downloadFileDirect(`批量导入成绩管理失败数据导出.xls`, new Blob([res.data])) Util.downloadFileDirect(`批量导入成绩管理失败数据导出.xls`, new Blob([res.data]))
}).catch(res => { }) }).catch(res => { })
}, },
uploadSuccess (res) { uploadSuccess (res) {
@ -579,11 +635,11 @@ export default {
this.faildData = data this.faildData = data
this.uploadFaild = true this.uploadFaild = true
} else { } else {
util.successMsg(data.tip, 3000) Util.successMsg(data.tip, 3000)
this.importVisible = false this.importVisible = false
} }
} else { } else {
util.errorMsg(res.message || '上传失败,请检查数据') Util.errorMsg(res.message || '上传失败,请检查数据')
} }
}, },
uploadError (err, file, fileList) { uploadError (err, file, fileList) {
@ -613,29 +669,23 @@ export default {
}, },
// tab // tab
tabChange (i) { tabChange (i) {
this.multipleSelection = []
this.$refs.table.clearSelection()
this.active = i this.active = i
this.getData() this.initData()
}, },
// //
preview (item) { preview (url) {
window.open((util.isDoc(item.fileFormat) ? 'https://view.officeapps.live.com/op/view.aspx?src=' : '') + item.filePath) const ext = url.split('.').pop()
}, if (Util.isDoc(ext)) {
// window.open('https://view.officeapps.live.com/op/view.aspx?src=' + url)
exportFile (item) { } else if (Util.isImg(ext)) {
item.loading = true this.previewImgVisible = true
const url = item.filePath this.previewImg = url
var x = new XMLHttpRequest() } else if (ext === 'pdf') {
x.open("GET", url, true) this.pdfVisible = true
x.responseType = "blob" this.pdfSrc = url
x.onload = function (e) { }
var url = window.URL.createObjectURL(x.response)
var a = document.createElement("a")
a.href = url
a.download = item.userName + '-' + item.fileName
a.click()
item.loading = false
}
x.send()
}, },
back () { back () {
this.$router.push(this.$store.state.innerReferrer) this.$router.push(this.$store.state.innerReferrer)
@ -663,12 +713,31 @@ export default {
} }
} }
.tool {
align-items: flex-start;
margin-bottom: 10px;
.filter {
flex-wrap: wrap;
}
li {
margin-bottom: 10px;
}
/deep/.el-select {
width: 140px;
}
}
.stat { .stat {
display: flex; display: flex;
.nums { .nums {
display: flex; display: flex;
flex-wrap: wrap;
align-items: center; align-items: center;
width: 640px;
margin-right: 20px; margin-right: 20px;
.item:nth-child(1) { .item:nth-child(1) {
@ -679,6 +748,14 @@ export default {
background-image: url('../../../assets/img/avg.png'); background-image: url('../../../assets/img/avg.png');
} }
.item:nth-child(3) {
background-image: url('../../../assets/img/ach1.png');
}
.item:nth-child(4) {
background-image: url('../../../assets/img/ach2.png');
}
.item { .item {
width: 300px; width: 300px;
min-height: 145px; min-height: 145px;
@ -703,10 +780,11 @@ export default {
} }
.chart { .chart {
flex: 1; width: calc(100% - 660px);
height: 300px; height: 300px;
} }
} }
/deep/.import-file { /deep/.import-file {
.el-progress__text, .el-progress__text,
.el-progress, .el-progress,
@ -714,4 +792,16 @@ export default {
display: none !important; display: none !important;
} }
} }
/deep/.review-dia {
.el-drawer__close-btn {
position: absolute;
top: 20px;
right: 20px;
}
iframe {
height: 100%;
}
}
</style> </style>

@ -36,15 +36,15 @@
</tr> </tr>
<tr> <tr>
<th>学校</th> <th>学校</th>
<td>{{ info.person.schoolName }}</td> <td>{{ info.person.realSchool }}</td>
</tr> </tr>
</template> </template>
<template v-if="form.completeCompetitionSetup.competitionType"> <template v-if="form.completeCompetitionSetup.competitionType">
<template> <template>
<tr> <tr>
<th>队长</th> <th>队长</th>
<td>{{ info.caption.userName }}{{ info.caption.schoolName && ',' + info.caption.schoolName }}{{ <td>{{ info.captain.userName }}{{ info.captain.realSchool && ',' + info.captain.realSchool }}{{
info.caption.workNumber && ',' + info.caption.workNumber }}</td> info.captain.workNumber && ',' + info.captain.workNumber }}</td>
</tr> </tr>
<tr> <tr>
<th>团队成员</th> <th>团队成员</th>
@ -129,7 +129,7 @@
<td colspan="6">暂无数据</td> <td colspan="6">暂无数据</td>
</tr> </tr>
</table> </table>
<el-alert v-if="form.completeCompetitionSetup.competitionType" style="margin-top: 10px;" <el-alert v-if="form.completeCompetitionSetup.competitionType && form.rule !== 2" style="margin-top: 10px;"
:title="'注:请团长(团队创建人)设置各阶段参赛成员,只有被选择的允许参赛成员可进入对应阶段比赛' + (info.teamLimit ? ',每个团队成员只能参加一个赛项阶段' : '') + '!'" :title="'注:请团长(团队创建人)设置各阶段参赛成员,只有被选择的允许参赛成员可进入对应阶段比赛' + (info.teamLimit ? ',每个团队成员只能参加一个赛项阶段' : '') + '!'"
type="warning" show-icon> type="warning" show-icon>
</el-alert> </el-alert>
@ -144,12 +144,13 @@
}}</el-tag> }}</el-tag>
</div> </div>
<div class="flex-center"> <div class="flex-center">
<p>队长{{ info.caption.userName }}</p> <p>队长{{ info.captain.userName }}</p>
<el-button type="primary" @click="transfer">转让队长</el-button> <el-button type="primary" @click="transfer">转让队长</el-button>
</div> </div>
<el-table :data="info.teamDetail" stripe header-align="center"> <el-table :data="info.teamDetail" stripe header-align="center">
<el-table-column prop="userName" label="成员姓名" min-width="100" align="center"></el-table-column> <el-table-column prop="userName" label="成员姓名" min-width="100" align="center"></el-table-column>
<el-table-column prop="schoolName" label="学校" min-width="100" align="center"></el-table-column> <el-table-column prop="realSchool" label="学校" min-width="100" align="center"></el-table-column>
<el-table-column prop="phone" label="手机号" min-width="100" align="center"></el-table-column>
<el-table-column prop="workNumber" label="学号" min-width="100" align="center"></el-table-column> <el-table-column prop="workNumber" label="学号" min-width="100" align="center"></el-table-column>
<el-table-column prop="createTime" label="加入时间" width="180" align="center"></el-table-column> <el-table-column prop="createTime" label="加入时间" width="180" align="center"></el-table-column>
<el-table-column label="操作" align="center" width="160"> <el-table-column label="操作" align="center" width="160">
@ -198,7 +199,7 @@
<tr v-for="(item, i) in members" :key="i"> <tr v-for="(item, i) in members" :key="i">
<td>{{ i + 1 }}</td> <td>{{ i + 1 }}</td>
<td>{{ item.userName }}</td> <td>{{ item.userName }}</td>
<td>{{ item.schoolName }}</td> <td>{{ item.realSchool }}</td>
<td>{{ item.timeSum }}min</td> <td>{{ item.timeSum }}min</td>
<td>{{ item.score }}</td> <td>{{ item.score }}</td>
<td> <td>
@ -239,7 +240,7 @@ export default {
info: { info: {
isCaption: 0, isCaption: 0,
person: {}, person: {},
caption: {}, captain: {},
team: { team: {
captain: 1, captain: 1,
invitationCode: '' invitationCode: ''
@ -314,10 +315,10 @@ export default {
info.team = {} info.team = {}
info.teamDetail = [] info.teamDetail = []
} else { } else {
info.isCaption = info.team.caption info.isCaption = info.team.captain
} }
const caption = info.teamDetail.find(e => !e.caption) const captain = info.teamDetail.find(e => !e.captain)
info.caption = caption ? caption : {} info.captain = captain ? captain : {}
info.person = info.personalDetail || info.teamDetail.find(e => e.accountId == info.team.accountId) info.person = info.personalDetail || info.teamDetail.find(e => e.accountId == info.team.accountId)
this.originInfo = JSON.parse(JSON.stringify(info)) this.originInfo = JSON.parse(JSON.stringify(info))
// accountId // accountId
@ -347,9 +348,10 @@ export default {
teamId: this.info.teamId teamId: this.info.teamId
}) })
this.teamErrors = res.teamTip.split(';').filter(e => e) this.teamErrors = res.teamTip.split(';').filter(e => e)
if (Object.keys(res.stageTip).length) { if (Object.keys(res.stageTip).length) {
this.stageTip = res.stageTip this.stageTip = res.stageTip
} else {
this.stageTip = null
} }
}, },
// //
@ -451,7 +453,7 @@ export default {
transferSubmit () { transferSubmit () {
if (!this.checkedPlayer) return Util.errorMsg('请选择成员') if (!this.checkedPlayer) return Util.errorMsg('请选择成员')
this.$post(this.api.captainOfTransfer, { this.$post(this.api.captainOfTransfer, {
captainId: this.info.caption.teamId, captainId: this.info.captain.teamId,
playerId: this.checkedPlayer playerId: this.checkedPlayer
}).then(res => { }).then(res => {
this.checkedPlayer = '' this.checkedPlayer = ''
@ -570,9 +572,9 @@ export default {
}, },
// //
show (row) { show (row) {
this.curRow = row
// //
if (this.form.completeCompetitionSetup.competitionType) { // if (this.form.completeCompetitionSetup.competitionType) { //
this.curRow = row
this.memberVisible = true this.memberVisible = true
if (this.info.teamId) { if (this.info.teamId) {
this.getMembers() this.getMembers()
@ -589,7 +591,7 @@ export default {
}, },
// //
toReport (row) { toReport (row) {
this.$router.push(`/matchReport?reportId=${row.reportId}`) this.$router.push(`/${this.curRow.method === 1 ? 'theoryReport' : 'trialReport'}?reportId=${row.reportId}`)
}, },
back () { back () {
this.$router.push(this.$store.state.innerReferrer) this.$router.push(this.$store.state.innerReferrer)

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<el-card shadow="hover" class="m-b-20 head-card"> <el-card shadow="hover" class="m-b-20 head-card">
<div class="flex-between m-b-20"> <div class="flex-between">
<el-page-header v-if="grades.length" @back="back" :content="grades[index].stageName + '/排名'"></el-page-header> <el-page-header v-if="grades.length" @back="back" :content="grades[index].stageName + '/排名'"></el-page-header>
</div> </div>
@ -14,15 +14,41 @@
@click="tabChange(item.stageId)">{{ item.stageName }}排名</a> @click="tabChange(item.stageId)">{{ item.stageName }}排名</a>
</template> </template>
</div> </div>
<div class="flex-between" style="margin: 20px 0">
<div class="tool flex-between" style="margin-top: 20px">
<div style="display: inline-flex;align-items: center"> <div style="display: inline-flex;align-items: center">
<el-radio v-model="type" :label="0" @change="typeChange">默认系统排序</el-radio> <el-radio v-model="type" :label="0" @change="typeChange">默认系统排序</el-radio>
<el-radio v-model="type" :label="1" @change="typeChange">手动上传</el-radio> <el-radio v-model="type" :label="1" @change="typeChange">手动上传</el-radio>
<el-button type="primary" :disabled="type === 0" class="ml20" @click="batchImport">上传文件</el-button> <el-button type="primary" :disabled="type === 0" class="ml20" @click="batchImport">上传文件</el-button>
</div> </div>
<div style="display: inline-flex;align-items: center"> <ul class="filter" style="flex: none;">
<li>
<label>省份</label>
<el-select v-model="filter.provinceId" clearable filterable placeholder="请选择省份" @change="provinceChange"
@clear="clearProvince">
<el-option v-for="(item, i) in provinces" :key="i" :label="item.provinceName"
:value="item.provinceId"></el-option>
</el-select>
</li>
<li>
<label>城市</label>
<el-select v-model="filter.cityId" clearable filterable placeholder="请选择城市" :disabled="!filter.provinceId"
@change="initData">
<el-option v-for="(item, i) in cities" :key="i" :label="item.cityName" :value="item.cityId"></el-option>
</el-select>
</li>
<li>
<label>学校</label>
<el-select v-model="filter.realSchoolId" clearable filterable placeholder="请选择学校" @change="initData">
<el-option v-for="(item, i) in schools" :key="i" :label="item.schoolName"
:value="item.schoolId"></el-option>
</el-select>
</li>
<li>
<el-input style="margin-right: 15px" :placeholder="'请输入' + (competitionType ? '团队名称/队长' : '学生姓名') + '/学校'" <el-input style="margin-right: 15px" :placeholder="'请输入' + (competitionType ? '团队名称/队长' : '学生姓名') + '/学校'"
prefix-icon="el-icon-search" v-model="keyword" clearable></el-input> prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</li>
<el-button v-if="!published" type="primary" @click="cancelPublish(1)">发布排名</el-button> <el-button v-if="!published" type="primary" @click="cancelPublish(1)">发布排名</el-button>
<template v-else> <template v-else>
<span style="margin-right: 10px;white-space: nowrap;">{{ publishTime }}发布排名</span> <span style="margin-right: 10px;white-space: nowrap;">{{ publishTime }}发布排名</span>
@ -31,8 +57,9 @@
<el-button v-if="list.length" type="primary" :loading="exporting" @click="exportData">{{ exporting ? '正在导出' : <el-button v-if="list.length" type="primary" :loading="exporting" @click="exportData">{{ exporting ? '正在导出' :
'批量导出' '批量导出'
}}</el-button> }}</el-button>
</ul>
</div> </div>
</div>
<el-table :data="list" class="table" ref="table" stripe row-key="scoreId" <el-table :data="list" class="table" ref="table" stripe row-key="scoreId"
@selection-change="handleSelectionChange" header-align="center"> @selection-change="handleSelectionChange" header-align="center">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
@ -46,6 +73,8 @@
<el-table-column prop="leaderName" label="队长" min-width="150" align="center"></el-table-column> <el-table-column prop="leaderName" label="队长" min-width="150" align="center"></el-table-column>
</template> </template>
<el-table-column v-else prop="userName" label="学生姓名" min-width="100" align="center"></el-table-column> <el-table-column v-else prop="userName" label="学生姓名" min-width="100" align="center"></el-table-column>
<el-table-column prop="provinceName" label="省份" min-width="100" align="center"></el-table-column>
<el-table-column prop="cityName" label="城市" min-width="100" align="center"></el-table-column>
<el-table-column prop="schoolName" label="学生账号归属" min-width="100" align="center"></el-table-column> <el-table-column prop="schoolName" label="学生账号归属" min-width="100" align="center"></el-table-column>
<el-table-column prop="realSchool" label="学生所在院校" min-width="100" align="center"></el-table-column> <el-table-column prop="realSchool" label="学生所在院校" min-width="100" align="center"></el-table-column>
<el-table-column prop="timeSum" label="用时" width="90" align="center"> <el-table-column prop="timeSum" label="用时" width="90" align="center">
@ -100,7 +129,7 @@
<template v-if="item.accountId"> <template v-if="item.accountId">
<td>{{ i + 1 }}</td> <td>{{ i + 1 }}</td>
<td>{{ item.userName }}</td> <td>{{ item.userName }}</td>
<td>{{ item.schoolName }}</td> <td>{{ item.realSchool }}</td>
<td>{{ item.timeSum }}min</td> <td>{{ item.timeSum }}min</td>
<td>{{ item.score }}</td> <td>{{ item.score }}</td>
<td> <td>
@ -178,10 +207,18 @@ export default {
id: +this.$route.query.id, id: +this.$route.query.id,
stageId: +this.$route.query.stageId, stageId: +this.$route.query.stageId,
index: +this.$route.query.index, index: +this.$route.query.index,
method: this.$route.query.method, method: +this.$route.query.method,
competitionType: +this.$route.query.competitionType, competitionType: +this.$route.query.competitionType,
rule: +this.$route.query.rule, rule: +this.$route.query.rule,
searchTimer: null, searchTimer: null,
filter: {
provinceId: '',
cityId: '',
realSchoolId: '',
},
provinces: [],
cities: [],
schools: [],
keyword: this.$route.query.keyword || '', keyword: this.$route.query.keyword || '',
teamCalculationMethods: [ teamCalculationMethods: [
{ {
@ -262,6 +299,8 @@ export default {
} }
}, },
mounted () { mounted () {
this.getProvince()
this.getSchool()
this.getStage() this.getStage()
}, },
methods: { methods: {
@ -275,6 +314,7 @@ export default {
}, },
// //
getRank () { getRank () {
const { filter } = this
this.loading = true this.loading = true
// //
if (this.type) { if (this.type) {
@ -284,7 +324,8 @@ export default {
competitionId: this.id, competitionId: this.id,
isOverallRanking: this.active ? 0 : 1, isOverallRanking: this.active ? 0 : 1,
stageId: this.active || this.stageId, stageId: this.active || this.stageId,
keyword: this.keyword keyword: this.keyword,
...filter
}).then(({ message, publishStatus }) => { }).then(({ message, publishStatus }) => {
// isRelease 01 // isRelease 01
this.published = publishStatus this.published = publishStatus
@ -307,7 +348,8 @@ export default {
publicationType: this.type, publicationType: this.type,
locationStageId: this.stageId, locationStageId: this.stageId,
stageIds: ids.splice(0, ids.length - 1), stageIds: ids.splice(0, ids.length - 1),
keyword: this.keyword keyword: this.keyword,
...filter
}).then(({ page, publishStatus, total }) => { }).then(({ page, publishStatus, total }) => {
this.published = publishStatus this.published = publishStatus
this.list = page || [] this.list = page || []
@ -319,7 +361,7 @@ export default {
}) })
} else { } else {
// //
this.$post(`${this.api.stageRaceRanking}?competitionId=${this.id}&stageId=${this.active}&pageNum=${this.page}&pageSize=${this.pageSize}&publicationType=${this.type}&keyword=${this.keyword}`).then(({ page, total, publishStatus }) => { this.$post(`${this.api.stageRaceRanking}?competitionId=${this.id}&stageId=${this.active}&pageNum=${this.page}&pageSize=${this.pageSize}&publicationType=${this.type}&keyword=${this.keyword}&provinceId=${filter.provinceId}&cityId=${filter.cityId}&realSchoolId=${filter.realSchoolId}`).then(({ page, total, publishStatus }) => {
this.published = publishStatus this.published = publishStatus
this.list = page this.list = page
this.total = total this.total = total
@ -367,6 +409,39 @@ export default {
this.active = i this.active = i
this.initData() this.initData()
}, },
//
async getProvince () {
const { list } = await this.$get(this.api.queryProvince)
this.provinces = list
},
//
clearProvince () {
this.filter.cityId = ''
},
//
provinceChange () {
this.clearProvince()
this.getCity()
this.initData()
},
//
async getCity () {
const id = this.filter.provinceId
if (id) {
const { list } = await this.$get(this.api.queryCity, {
provinceId: id
})
this.cities = list
}
},
//
async getSchool () {
const { list } = await this.$get(this.api.querySchoolData)
this.schools = list
},
// //
show (row, i) { show (row, i) {
this.teams = [] this.teams = []
@ -449,7 +524,7 @@ export default {
}, },
// //
toReport (row) { toReport (row) {
this.$router.push(`/matchReport?reportId=${row.reportId}`) this.$router.push(`/${this.method !== 1 ? 'trialReport' : 'theoryReport'}?reportId=${row.reportId}`)
}, },
handleSelectionChange (val) { // handleSelectionChange (val) { //
this.multipleSelection = val; this.multipleSelection = val;

@ -1,449 +0,0 @@
<template>
<div class="wrap">
<el-card shadow="hover"
class="m-b-20">
<el-page-header @back="$router.back()"
content="查看报告"></el-page-header>
</el-card>
<div class="content"
v-loading="loading">
<div class="text-right">
<el-button type="primary"
@click="exportPage">导出报告</el-button>
</div>
<h6 class="r-title">标准实验报告</h6>
<div class="info">
<h6 class="l-title">
<img src="@/assets/img/info1.png"
alt="">
基本信息
</h6>
<ul :class="['info-list', {edit: editing}]">
<li>
<label>学生姓名</label>
<el-input v-if="editing"
v-model="infoData.userName"
disabled></el-input>
<span v-else>{{ infoData.userName }}</span>
</li>
<li>
<label>学生学号</label>
<el-input v-if="editing"
v-model="infoData.workNumber"
disabled></el-input>
<span v-else>{{ infoData.workNumber }}</span>
</li>
<li>
<label>实验时间</label>
<el-input v-if="editing"
v-model="infoData.submitTime"
disabled></el-input>
<span v-else>{{ infoData.submitTime }}</span>
</li>
<li>
<label>实验成绩</label>
<el-input v-if="editing"
v-model="infoData.score"
disabled></el-input>
<div v-else
class="score-wrap">
<em>{{ infoData.score }}</em>
<img src="@/assets/img/point.png"
alt="">
</div>
</li>
<li>
<label>学生班级</label>
<el-input v-if="editing"
v-model="infoData.className"></el-input>
<span v-else>{{ infoData.className }}</span>
</li>
<li>
<label>指导老师</label>
<el-input v-if="editing"
v-model="infoData.instructor"></el-input>
<span v-else>{{ infoData.instructor }}</span>
</li>
<li>
<label>实验学时</label>
<el-input v-if="editing"
v-model="infoData.period"></el-input>
<span v-else>{{ infoData.period }}</span>
</li>
</ul>
<div class="m-b-20">
<h6 class="l-title">
<img src="@/assets/img/report2.png"
alt="">
实验项目名称
</h6>
<el-input v-if="editing"
v-model="form.projectName"
type="textarea"></el-input>
<div v-else
class="pre-wrap"
v-html="form.projectName"></div>
</div>
<div class="m-b-20">
<h6 class="l-title">
<img src="@/assets/img/report3.png"
alt="">
实验目的
</h6>
<div :class="['pre-wrap', {edit: editing}]"
v-html="form.purpose"></div>
</div>
<div class="m-b-20">
<h6 class="l-title">
<img src="@/assets/img/report4.png"
alt="">
实验数据
</h6>
<el-table :data="expData"
class="table"
border
stripe
header-align="center">
<el-table-column type="index"
label="序号"
align="center"
width="60">
<template slot-scope="scope">
{{ scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column prop="judgmentName"
label="判分点"
width="270"
align="center"></el-table-column>
<el-table-column v-if='project'
prop="judgmentName"
label="考核点"
align="center"
width="150">
<template slot-scope="scope">
<div v-for="(item, index) in scope.row.lcRuleRecords"
:key="index">
<span>
<span>{{index+1}}. </span>{{item.name}}
</span>
</div>
</template>
</el-table-column>
<el-table-column prop="ruleAnswer"
label="参考答案"
style='word-wrap: break-word'>
<template slot-scope="scope">
<div v-if='scope.row.lcRuleRecords'>
<div v-for="(item, index) in scope.row.lcRuleRecords"
:key="index">
<span>
<span>{{index+1}}. </span>{{item.ruleAnswer}}
</span>
</div>
</div>
<div v-else
v-html="scope.row.referenceAnswer"></div>
</template>
</el-table-column>
<el-table-column prop="userAnswer"
label="学生答案">
<template slot-scope="scope">
<div v-if='scope.row.lcRuleRecords'>
<div v-for="(item, index) in scope.row.lcRuleRecords"
:key="index">
<span v-if='item.userAnswer'>
<span>{{index+1}}. </span>{{item.userAnswer}}
</span>
<span v-else>
<span>{{index+1}}. </span>未填写
</span>
</div>
</div>
<div v-else
v-html='scope.row.answer'
style='white-space: pre-wrap'></div>
<template v-if="scope.row.runThePictureList">
<img v-for="(img, i) in scope.row.runThePictureList"
:key="i"
width="200"
class="result-pic"
:src="img"
alt="">
</template>
</template>
</el-table-column>
<el-table-column prop="quesScore"
label="分值"
:key="6"
width="80"
align="center"></el-table-column>
<el-table-column prop="score"
label="得分"
width="80"
align="center"></el-table-column>
</el-table>
</div>
<div class="m-b-20">
<h6 class="l-title">
<img src="@/assets/img/report5.png"
alt="">
实验总结与体会
</h6>
<quill v-if="editing"
:border="true"
v-model="form.summarize"
:minHeight="150"
:height="150" />
<div v-else
class="pre-wrap"
v-html="form.summarize"></div>
</div>
</div>
</div>
</div>
</template>
<script>
import util from "@/libs/util";
export default {
data () {
return {
reportId: this.$route.query.reportId,
title: "实验报告",
form: {
className: "",
instructor: "",
period: "",
projectName: "",
summarize: "",
},
infoData: {},
expData: [],
editing: false,
loadIns: null,
loading: false,
project: false,
userScores: []
};
},
mounted () {
this.getData()
},
methods: {
getData () { //
this.loading = true
this.$get(`${this.api.reportDetail}?reportId=${this.reportId}`).then(({ report, userScores }) => {
this.form = report
this.expData = userScores
this.project = this.expData.find(e => e.lcRuleRecords) // lcRuleRecords
let form = this.form;
this.infoData = {
workNumber: form.workNumber,
experimentalClassName: form.experimentalClassName,
instructor: form.instructor,
period: form.period,
laboratory: form.laboratory,
submitTime: form.submitTime,
score: form.score,
className: form.className,
userName: form.userName
}
const data = report.data
this.userScores = userScores
// data使
if (!data) {
this.handleList(userScores)
this.$post(this.api.editExperimentalData, {
reportId,
data: JSON.stringify(userScores)
}).then(res => { }).catch(err => { })
} else {
this.handleList(userScores.find(e => e.lcRuleRecords) ? userScores : JSON.parse(data))
}
}).catch(res => {
this.loading = false
})
},
//
handleList (list) {
this.project = list.find(e => e.lcRuleRecords) // lcRuleRecords
if (this.project) {
list.map(e => {
e.assessmentPoint = ''
e.referenceAnswer = ''
e.answer = ''
e.lcRuleRecords.map((n, i) => {
e.assessmentPoint += `${i + 1}.${n.name}`
e.referenceAnswer += `${i + 1}.${n.ruleAnswer}`
e.answer += `${i + 1}.${n.userAnswer}`
})
})
} else { // pythonuserScores
list.forEach(e => {
const item = this.userScores.find(n => n.judgmentId == e.judgmentId)
if (item && item.runThePictureList) e.runThePictureList = item.runThePictureList
})
}
this.expData = list
this.loading = false
},
exportPage () {
const form = Object.assign(this.form, this.infoData)
const list = JSON.parse(JSON.stringify(this.expData))
list.map((e, i) => {
const item = this.userScores.find(n => n.judgmentId == e.judgmentId)
if (item && item.runThePicture) e.runThePicture = item.runThePicture
if (item && item.runThePictureList) e.runThePictureList = item.runThePictureList
e.id = i + 1
// if (e.referenceAnswer && typeof e.referenceAnswer === 'string') e.referenceAnswer = e.referenceAnswer.replace(/<[^>]+>/g, '').replace(/(&nbsp;|&amp;|%s)/g, '').replace(/>/g, '&gt;').replace(/</g, '&lt;')
if (e.answer && typeof e.answer === 'string') e.answer = e.answer.replace(/<[^>]+>/g, '').replace(/(&nbsp;|&amp;|%s)/g, '').replace(/>/g, '&gt;').replace(/</g, '&lt;')
})
for (const i in form) {
if (form[i] && typeof form[i] === 'string') form[i] = form[i].replace(/<[^>]+>/g, '')
}
form.purpose = form.purpose.replace(/<[^>]+>/g, '')
this.$post(this.project ? this.api.exportBankExperimentReport : this.api.exportLabReport, {
...form,
experimentalData: list
}).then(res => {
console.log(res)
util.downloadFileDirect(`实验报告.docx`, new Blob([res]))
}).catch(res => { })
},
}
};
</script>
<style lang="scss" scoped>
.wrap {
padding: 12px 300px 20px;
}
.text-right {
text-align: right;
}
code,
kbd,
samp {
font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif;
word-wrap: break-word;
white-space: pre-wrap;
}
/deep/ pre {
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
word-break: break-all;
overflow: hidden;
font-size: 12px;
font-weight: 400;
font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif;
}
.content {
padding: 16px 40px;
background: #fff;
.r-title {
margin-bottom: 40px;
font-size: 24px;
text-align: center;
color: #333;
}
.info {
padding: 20px 16px;
border: 1px solid #e1e6f2;
}
.l-title {
display: flex;
align-items: center;
padding: 5px 8px;
margin-bottom: 12px;
font-size: 14px;
color: #333;
background-color: #f7f5ff;
}
.info-list {
display: flex;
flex-wrap: wrap;
padding: 10px 0 0 20px;
li {
display: inline-flex;
width: 23%;
padding: 0 10px;
margin-bottom: 34px;
}
&.edit {
li {
align-items: center;
}
}
label {
font-size: 14px;
color: #333;
white-space: nowrap;
}
span {
min-width: 150px;
padding: 0 10px 3px;
border-bottom: 1px solid #e1e6f2;
}
/deep/.el-input {
width: 174px;
}
}
.score-wrap {
position: relative;
min-width: 150px;
border-bottom: 1px solid #e1e6f2;
em {
position: absolute;
top: -12px;
left: 30px;
font-family: din;
font-size: 30px;
font-weight: 600;
color: #0b1d30;
}
img {
position: absolute;
bottom: -15px;
left: 0;
}
}
/deep/.el-textarea .el-textarea__inner,
.pre-wrap {
min-height: 72px;
padding: 10px 16px;
font-size: 14px;
color: #333;
&.edit {
color: #abb3c6;
border: 1px solid #cacfdb;
border-radius: 4px;
background-color: #f6f7f9;
}
}
/deep/ .table th {
background-color: #e5dfff !important;
.cell {
line-height: 35px;
color: #fff;
}
}
}
.result-pic {
margin: 10px 0;
}
@media (max-width: 1650px) {
.wrap {
padding: 12px 200px 20px;
}
}
@media (max-width: 1430px) {
.wrap {
padding: 12px 100px 20px;
}
}
</style>

@ -17,9 +17,22 @@
</li> </li>
</ul> </ul>
<div> <div>
<el-button v-show="loaded && info.completeCompetitionSetup.competitionType" type="primary" round <template v-if="loaded && info.completeCompetitionSetup.competitionType">
:disabled="hasReport" :loading="allocating" @click="autoAllocationConfirm">{{ !notBeginSign && allocated ? <el-button type="primary" round :disabled="hasReport" :loading="allocating" @click="autoAllocationConfirm">{{
!notBeginSign && allocated ?
'取消' : '' }}自动分配阶段成员</el-button> '取消' : '' }}自动分配阶段成员</el-button>
<el-tooltip placement="top">
<div slot="content">
<p>报名结束前设置的自动分配将在报名结束时触发一次系统自动分配取消则不触发</p>
<p style="margin: 5px 0;">报名结束后也可以手动点击自动分配按钮来立即触发系统自动分配并且点击一次就触发一次</p>
<p></p>
<p style="margin: 5px 0;">&emsp;&emsp;1. 自动分配仅对触发时已报名的人员进行对于分配后才报名的人员如需自动分配则需手动再次触发自动分配</p>
<p>&emsp;&emsp;2. 若已有学生提交了成绩报告则无法启用自动分配功能</p>
</div>
<i class="el-icon-question"
style="margin: 0 10px 0 5px;font-size: 16px;color: #8f8f8f;cursor: pointer;"></i>
</el-tooltip>
</template>
<el-button type="primary" round @click="batchImport">导入</el-button> <el-button type="primary" round @click="batchImport">导入</el-button>
<el-button type="primary" round @click="add" v-auth="'/match:管理:报名人员:新增'">新增</el-button> <el-button type="primary" round @click="add" v-auth="'/match:管理:报名人员:新增'">新增</el-button>
<el-button type="primary" round :loading="exporting" @click="exportAll" <el-button type="primary" round :loading="exporting" @click="exportAll"
@ -69,11 +82,13 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" width="270"> <el-table-column label="操作" align="center" width="270">
<template slot-scope="scope"> <template slot-scope="scope">
<template v-if="!scope.row.isDel">
<el-button v-auth="'/match:管理:报名人员:编辑'" type="text" @click="edit(scope.row)">编辑</el-button> <el-button v-auth="'/match:管理:报名人员:编辑'" type="text" @click="edit(scope.row)">编辑</el-button>
<el-button type="text" @click="del(scope.row)">删除</el-button> <el-button type="text" @click="del(scope.row)">删除</el-button>
</template>
<template v-if="info.releaseType"> <template v-if="info.releaseType">
<el-button v-auth="'/match:管理:报名人员:参赛信息与成绩'" type="text" @click="toInfo(scope.row)">参赛信息与成绩</el-button> <el-button v-auth="'/match:管理:报名人员:参赛信息与成绩'" type="text" @click="toInfo(scope.row)">参赛信息与成绩</el-button>
<el-switch v-auth="'/match:管理:报名人员:禁用'" v-model="scope.row.isDisable" <el-switch v-if="!scope.row.isDel" v-auth="'/match:管理:报名人员:禁用'" v-model="scope.row.isDisable"
:active-text="scope.row.isDisable ? '禁用' : '启用'" :active-value="0" :inactive-value="1" :active-text="scope.row.isDisable ? '禁用' : '启用'" :active-value="0" :inactive-value="1"
style="margin: 0 10px 0 5px" @change="switchOff($event, scope.row, scope.$index)"></el-switch> style="margin: 0 10px 0 5px" @change="switchOff($event, scope.row, scope.$index)"></el-switch>
</template> </template>

@ -0,0 +1,675 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20 head-card">
<div class="flex-between m-b-20">
<el-page-header @back="back" content="成绩管理"></el-page-header>
</div>
</el-card>
<div v-loading="loading">
<el-card v-if="method != 2" shadow="hover" class="m-b-20">
<div class="stat">
<div class="nums">
<div class="item">
<p class="name">已参加/应参加人数</p>
<p class="val">{{ isNaN(statData.totalNumber) ? '' : statData.attendance + '/' + statData.totalNumber }}
</p>
</div>
<div class="item">
<p class="name">实验平均分</p>
<p class="val">{{ avgScore }}</p>
</div>
</div>
<div class="chart" id="chart"></div>
</div>
</el-card>
<el-card shadow="hover" class="m-b-20">
<div v-if="showFile" class="tabs m-b-20">
<a class="item" v-for="(item, i) in tabs" :key="i" :class="{ active: i === active }" @click="tabChange(i)">{{
item }}</a>
</div>
<div class="tool flex-between">
<ul class="filter">
<li>
<label>省份</label>
<el-select v-model="filter.provinceId" filterable clearable placeholder="请选择省份" @change="provinceChange"
@clear="clearProvince">
<el-option v-for="(item, i) in provinces" :key="i" :label="item.provinceName"
:value="item.provinceId"></el-option>
</el-select>
</li>
<li>
<label>城市</label>
<el-select v-model="filter.cityId" filterable clearable placeholder="请选择城市" :disabled="!filter.provinceId"
@change="initData">
<el-option v-for="(item, i) in cities" :key="i" :label="item.cityName" :value="item.cityId"></el-option>
</el-select>
</li>
<li>
<label>学校</label>
<el-select v-model="filter.realSchoolId" clearable filterable placeholder="请选择学校" @change="initData">
<el-option v-for="(item, i) in schools" :key="i" :label="item.schoolName"
:value="item.schoolId"></el-option>
</el-select>
</li>
<li>
<el-input size="small" placeholder="请输入学生姓名" prefix-icon="el-icon-search" v-model="keyword" clearable
style="width: 300px"></el-input>
</li>
</ul>
<div v-if="!active">
<el-button v-if="method == 2" type="primary" @click="batchImport">上传成绩</el-button>
<el-button type="primary" :disabled="!!multipleSelection.find(e => method != 2 && !e.reportId)"
@click="delAllData">批量删除</el-button>
<el-button type="primary" :loading="exporting" @click="exportData">{{ exporting ? '正在导出' : '批量导出'
}}</el-button>
</div>
<div v-else>
<el-button type="primary" :loading="exporting1" @click="exportData1">{{ exporting1 ? '正在导出' : '批量导出'
}}</el-button>
</div>
</div>
<template v-if="!active">
<el-table :data="list" class="table" :key="1" ref="table" stripe header-align="center"
@selection-change="handleSelectionChange" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center">
<template slot-scope="scope">
{{ scope.$index + (page - 1) * pageSize + 1 }}
</template>
</el-table-column>
<el-table-column prop="provinceName" label="省份" min-width="100" align="center"></el-table-column>
<el-table-column prop="cityName" label="城市" min-width="100" align="center"></el-table-column>
<el-table-column prop="schoolName" label="学生账号归属" min-width="100" align="center"></el-table-column>
<el-table-column prop="realSchool" label="学生所在院校" min-width="100" align="center"></el-table-column>
<el-table-column v-if="competitionType" prop="teamName" label="团队名称" min-width="100"
align="center"></el-table-column>
<el-table-column prop="userName" label="学生姓名" min-width="100" align="center"></el-table-column>
<el-table-column prop="workNumber" label="学号" min-width="100" align="center"></el-table-column>
<el-table-column prop="score" label="分数" width="90" align="center">
<template slot-scope="scope">
{{ scope.row.submitTime ? scope.row.score : '--' }}
</template>
</el-table-column>
<el-table-column prop="timeSum" label="耗时" width="90" align="center">
<template slot-scope="scope">
{{ scope.row.timeSum ? scope.row.timeSum + 'min' : '--' }}
</template>
</el-table-column>
<el-table-column prop="submitTime" label="提交时间" min-width="150" align="center">
<template slot-scope="scope">
{{ scope.row.submitTime || '--' }}
</template>
</el-table-column>
<el-table-column label="状态" width="100" align="center">
<template slot-scope="scope">
{{ scope.row.reportId || method == 2 ? '已参加' : '未参加' }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="160">
<template slot-scope="scope">
<el-button v-if="method != 2 && scope.row.reportId" type="text"
@click="show(scope.row)">查看成绩报告</el-button>
<el-button v-if="scope.row.reportId" type="text" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total, prev, pager, next" :total="total"
@current-change="handleCurrentChange" :current-page="page">
</el-pagination>
</div>
</template>
<template v-else>
<el-table :data="list1" class="table" :key="2" stripe header-align="center"
@selection-change="handleSelectionChange1" row-key="id">
<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">
<template slot-scope="scope">
{{ scope.$index + (page1 - 1) * pageSize + 1 }}
</template>
</el-table-column>
<el-table-column prop="provinceName" label="省份" align="center"></el-table-column>
<el-table-column prop="cityName" label="城市" align="center"></el-table-column>
<el-table-column prop="schoolName" label="学生账号归属" align="center"></el-table-column>
<el-table-column prop="realSchool" label="学生所在院校" align="center"></el-table-column>
<el-table-column v-if="competitionType" prop="teamName" label="团队名称" align="center"></el-table-column>
<el-table-column prop="userName" label="学生姓名" align="center"></el-table-column>
<el-table-column prop="workNumber" label="学号" align="center"></el-table-column>
<el-table-column prop="fileName" label="文件名" align="center"></el-table-column>
<el-table-column prop="fileSize" label="文件大小" align="center"></el-table-column>
<el-table-column prop="fileType" label="文件类型" align="center"></el-table-column>
<el-table-column prop="fileFormat" label="文件格式" align="center"></el-table-column>
<el-table-column prop="createTime" label="提交时间" width="150" align="center">
</el-table-column>
<el-table-column label="操作" width="200">
<template slot-scope="scope">
<el-button v-if="!isCompress(scope.row.fileFormat)" type="text"
@click="preview(scope.row)">预览文件</el-button>
<el-button type="primary" size="mini" :loading="scope.row.loading"
@click="exportFile(scope.row)">导出文件</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total, prev, pager, next" :total="total1"
@current-change="handleCurrentChange1" :current-page="page1">
</el-pagination>
</div>
</template>
</el-card>
</div>
<el-dialog title="批量导入" :visible.sync="importVisible" width="24%" :close-on-click-modal="false"
@close="cancelUpload">
<div style="text-align: center">
<template v-if="!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-upload ref="upload" name="file" accept=".xls,.xlsx" class="import-file" :before-upload="beforeUpload"
:on-remove="handleRemove" :on-error="uploadError" :on-success="uploadSuccess" :before-remove="beforeRemove"
:limit="1" :on-exceed="handleExceed" :action="this.api.batchImportGrades" :file-list="uploadList"
:headers="headers" :disabled="uploading" :data="{
competitionId: this.id,
stageId: this.stageId,
systemId: 0
}">
<el-button type="primary" :loading="uploading" class="ml20">上传文件<i
class="el-icon-upload2 el-icon--right"></i></el-button>
</el-upload>
</template>
<template v-else>
<p style="margin: -10px 0 13px;font-size: 14px;color: #e90000;">{{ faildData.tip }}</p>
<p type="primary"
style="margin-bottom: 10px;font-size: 14px;color: #9076FF;text-decoration: underline;cursor: pointer;"
@click="showFaild">部分数据导入失败查看失败原因</p>
</template>
</div>
<span v-if="uploading" slot="footer" class="dialog-footer">
<el-button @click="cancelUpload">停止导入</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import util from "@/libs/util";
import * as echarts from "echarts";
import axios from 'axios';
import Zip from '@/libs/zip'
export default {
data () {
return {
id: +this.$route.query.id,
stageId: +this.$route.query.stageId,
method: +this.$route.query.method,
competitionType: +this.$route.query.competitionType,
showFile: this.$route.query.showFile === 'true',
isCompress: util.isCompress,
filter: {
provinceId: '',
cityId: '',
realSchoolId: '',
reviewStatus: '',
scoreSortOrder: '',
submitTimeSortOrder: '',
},
provinces: [],
cities: [],
schools: [],
keyword: this.$route.query.keyword || '',
searchTimer: null,
list: [],
multipleSelection: [],
page: +this.$route.query.page || 1,
pageSize: 10,
total: 0,
list1: [],
multipleSelection1: [],
page1: 1,
total1: 0,
avgScore: 0, //
importVisible: false,
uploadList: [],
uploadFaild: false,
uploading: false,
faildData: null,
headers: {
token: sessionStorage.getItem("token")
},
statData: {},
tabs: ['成绩列表', '文件列表'],
active: 0,
loading: false,
exporting: false,
exporting1: false,
};
},
watch: {
keyword: function (val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.$router.push({
path: '/otherArchList',
query: {
...this.$route.query,
keyword: val
}
})
this.initData();
}, 500);
}
},
mounted () {
this.getData()
this.getProvince()
this.getSchool()
},
methods: {
async getData () {
this.loading = true
//
if (this.active) {
const { data } = await this.$post(this.api.cCompetitionStageFileList, {
pageNum: this.page1,
pageSize: this.pageSize,
competitionId: this.id,
stageId: this.stageId,
keyWord: this.keyword,
...this.filter
})
data.records.forEach(e => {
e.loading = false
e.fileType = '其他'
if (util.isVideo(e.fileFormat)) {
e.fileType = '视频'
} else if (util.isAudio(e.fileFormat)) {
e.fileType = '音频'
} else if (util.isImg(e.fileFormat)) {
e.fileType = '图片'
} else if (util.isDoc(e.fileFormat)) {
e.fileType = '文档'
} else if (util.isCompress(e.fileFormat)) {
e.fileType = '压缩包'
} else if (e.fileType === 'pdf') {
e.fileType = 'pdf'
}
})
this.list1 = data.records
this.total1 = data.total
this.loading = false
} else { //
const { data, page } = await this.$post(this.api.stageGradeManagementList, {
pageNum: this.page,
pageSize: this.pageSize,
competitionId: this.id,
keyWord: this.keyword,
stageId: this.stageId,
isNakadai: 1,
...this.filter
})
this.loading = false
this.total = page.total
this.list = page.records
this.statData = data
this.avgScore = (+data.avgScore).toFixed(2)
this.method != 2 && this.getChart()
}
},
initData () {
this.page = 1
this.getData()
},
//
async getProvince () {
const { list } = await this.$get(this.api.queryProvince)
this.provinces = list
},
//
clearProvince () {
this.filter.cityId = ''
},
//
provinceChange () {
this.clearProvince()
this.getCity()
this.initData()
},
//
async getCity () {
const id = this.filter.provinceId
if (id) {
const { list } = await this.$get(this.api.queryCity, {
provinceId: id
})
this.cities = list
}
},
//
async getSchool () {
const { list } = await this.$get(this.api.querySchoolData)
this.schools = list
},
//
show (row) {
this.$router.push(`/trialReport?reportId=${row.reportId}`)
},
// ()
async exportData () {
if (this.list.length) {
this.exporting = true
//
if (this.multipleSelection.length) {
const res = await axios.post(this.api.exportExperimentalResultsInBatch, this.multipleSelection, {
headers: this.headers,
responseType: 'blob'
})
util.downloadFileDirect(`赛事成绩.xls`, new Blob([res.data]))
this.exporting = false
} else if (this.list.length) {
const res = await axios.post(this.api.allExperimentalResultsAreDerived, {
pageNum: 1,
pageSize: 10000,
competitionId: this.id,
isNakadai: 1,
stageId: this.stageId,
}, {
headers: this.headers,
responseType: 'blob'
})
util.downloadFileDirect(`赛事成绩.xls`, new Blob([res.data]))
this.exporting = false
}
}
},
// ()
exportData1 () {
this.exporting1 = true
let list = this.list1
if (this.multipleSelection1.length) {
list = this.multipleSelection1
}
Zip('批量导出', list, () => {
this.exporting1 = false
})
},
handleDelete (row) { //
this.$confirm("确定要删除吗?", "提示", {
type: "warning"
}).then(() => {
this.$post(this.api.batchDeleteContestGrade, {
ids: [this.method == 2 ? row.scoreId : row.reportId],
competitionId: this.id,
stageId: this.stageId
}).then(res => {
util.successMsg("删除成功");
this.getData();
}).catch(res => {
});
}).catch(() => { });
},
delAllData () { //
const list = this.multipleSelection
this.$confirm(list.length ? '该项目下的所有成绩报告将会删除,是否继续?' : '是否确定删除列表所有成绩数据?', "提示", {
type: "warning"
}).then(async () => {
let ids = []
if (list.length) {
ids = list.map(item => {
return this.method == 2 ? item.scoreId : item.reportId
});
ids = ids.filter(e => e)
}
const data = {
competitionId: this.id,
stageId: this.stageId
}
if (list.length) data.ids = ids
await this.$post(this.api.batchDeleteContestGrade, data)
this.multipleSelection = [];
this.$refs.table.clearSelection();
util.successMsg("删除成功");
this.getData();
}).catch(() => { });
},
handleSelectionChange (val) { //
this.multipleSelection = val;
},
handleCurrentChange (val) { //
this.$router.push({
path: '/otherArchList',
query: {
...this.$route.query,
page: val
}
})
this.page = val;
this.getData();
},
handleSelectionChange1 (val) { //
this.multipleSelection1 = val;
},
handleCurrentChange1 (val) { //
this.page1 = val;
this.getData();
},
getChart () { // 线
const data = []
const { statData } = this
for (let i = 1; i <= 10; i++) {
data.push(statData['num' + i])
}
let myChart = echarts.init(document.getElementById("chart"));
myChart.setOption({
title: { text: "实验分数分布图" },
tooltip: {},
xAxis: {
name: "分数",
type: "category",
boundaryGap: false,
interval: 10,
data: ["0-10", "10-20", "20-30", "30-40", "40-50", "50-60", "60-70", "70-80", "80-90", "90-100"]
},
yAxis: {
name: "人数",
type: "value",
minInterval: 10
},
series: [{
data,
type: "line",
areaStyle: {},
label: {
show: true,
position: 'top'
},
color: ["#8191fd"]
}]
});
},
//
batchImport () {
this.importVisible = true
this.uploadList = []
this.uploadFaild = false
},
//
download () {
axios.get(`${this.api.gradeDownloadExcel}?competitionId=${this.id}&stageId=${this.stageId}`, {
headers: this.headers,
responseType: 'blob'
}).then((res) => {
util.downloadFileDirect('赛事成绩导入模板.xlsx', new Blob([res.data]))
}).catch(res => { })
},
//
handleExceed (files, fileList) {
util.warningMsg(
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
)
},
//
showFaild () {
axios.get(`${this.api.performanceExportFailure}?exportCode=${this.faildData.exportCode}&competitionType=${this.faildData.competitionType}`, {
headers: this.headers,
responseType: 'blob'
}).then((res) => {
util.downloadFileDirect(`批量导入成绩管理失败数据导出.xls`, new Blob([res.data]))
}).catch(res => { })
},
uploadSuccess (res) {
this.uploading = false
this.uploadFaild = false
if (res.status === 200) {
this.initData()
const { data } = res
if (data.exportCode) {
this.faildData = data
this.uploadFaild = true
} else {
util.successMsg(data.tip, 3000)
this.importVisible = false
}
} else {
util.errorMsg(res.message || '上传失败,请检查数据')
}
},
uploadError (err, file, fileList) {
this.uploading = false
this.$message({
message: "上传出错,请重试!",
type: "error",
center: true
})
},
beforeUpload (file) {
this.uploading = true
},
beforeRemove (file, fileList) {
return this.$confirm(`确定移除 ${file.name}`)
},
handleRemove (file, fileList) {
this.uploadList = fileList
this.uploadFaild = false
},
cancelUpload () {
this.uploading = false
if (this.$refs.upload) this.$refs.upload.abort()
this.keyword = ''
this.initData()
this.importVisible = false
},
// tab
tabChange (i) {
this.active = i
this.getData()
},
//
preview (item) {
window.open((util.isDoc(item.fileFormat) ? 'https://view.officeapps.live.com/op/view.aspx?src=' : '') + item.filePath)
},
//
exportFile (item) {
item.loading = true
const url = item.filePath
var x = new XMLHttpRequest()
x.open("GET", url, true)
x.responseType = "blob"
x.onload = function (e) {
var url = window.URL.createObjectURL(x.response)
var a = document.createElement("a")
a.href = url
a.download = item.userName + '-' + item.fileName
a.click()
item.loading = false
}
x.send()
},
back () {
this.$router.push(this.$store.state.innerReferrer)
}
}
};
</script>
<style lang="scss" scoped>
/deep/ .head-card {
.el-card__body {
padding-bottom: 0px;
.el-tabs__header {
margin-bottom: 1px;
.el-tabs__nav-wrap::after {
display: none;
}
.el-tabs__item {
font-size: 18px;
}
}
}
}
.stat {
display: flex;
.nums {
display: flex;
align-items: center;
margin-right: 20px;
.item:nth-child(1) {
background-image: url('../../../assets/img/total.png');
}
.item:nth-child(2) {
background-image: url('../../../assets/img/avg.png');
}
.item {
width: 300px;
min-height: 145px;
padding: 30px 30px;
margin: 0 10px;
box-sizing: border-box;
border-radius: 8px;
background-size: 100% 100%;
background-repeat: no-repeat;
p {
font-size: 18px;
color: #ffffff;
}
.val {
margin-top: 10px;
color: #ffffff;
font-size: 36px;
}
}
}
.chart {
flex: 1;
height: 300px;
}
}
/deep/.import-file {
.el-progress__text,
.el-progress,
.el-upload-list__item-status-label {
display: none !important;
}
}
</style>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,413 @@
<template>
<div class="wrap">
<el-card shadow="hover" class="m-b-20">
<el-page-header @back="$router.back()" content="查看报告"></el-page-header>
</el-card>
<div class="content" v-loading="loading">
<div class="text-right">
<el-button type="primary" @click="exportPage">导出报告</el-button>
</div>
<h6 class="r-title">标准实验报告</h6>
<div class="info">
<h6 class="l-title">
<img src="@/assets/img/info1.png" alt="">
基本信息
</h6>
<ul :class="['info-list', { edit: editing }]">
<li>
<label>学生姓名</label>
<el-input v-if="editing" v-model="infoData.userName" disabled></el-input>
<span v-else>{{ infoData.userName }}</span>
</li>
<li>
<label>学生学号</label>
<el-input v-if="editing" v-model="infoData.workNumber" disabled></el-input>
<span v-else>{{ infoData.workNumber }}</span>
</li>
<li>
<label>实验时间</label>
<el-input v-if="editing" v-model="infoData.submitTime" disabled></el-input>
<span v-else>{{ infoData.submitTime }}</span>
</li>
<li>
<label>实验成绩</label>
<el-input v-if="editing" v-model="infoData.score" disabled></el-input>
<div v-else class="score-wrap">
<em>{{ infoData.score }}</em>
<img src="@/assets/img/point.png" alt="">
</div>
</li>
<li>
<label>学生班级</label>
<el-input v-if="editing" v-model="infoData.className"></el-input>
<span v-else>{{ infoData.className }}</span>
</li>
<li>
<label>指导老师</label>
<el-input v-if="editing" v-model="infoData.instructor"></el-input>
<span v-else>{{ infoData.instructor }}</span>
</li>
<li>
<label>实验学时</label>
<el-input v-if="editing" v-model="infoData.period"></el-input>
<span v-else>{{ infoData.period }}</span>
</li>
</ul>
<div class="m-b-20">
<h6 class="l-title">
<img src="@/assets/img/report2.png" alt="">
实验项目名称
</h6>
<el-input v-if="editing" v-model="form.projectName" type="textarea"></el-input>
<div v-else class="pre-wrap" v-html="form.projectName"></div>
</div>
<div class="m-b-20">
<h6 class="l-title">
<img src="@/assets/img/report3.png" alt="">
实验目的
</h6>
<div :class="['pre-wrap', { edit: editing }]" v-html="form.purpose"></div>
</div>
<div class="m-b-20">
<h6 class="l-title">
<img src="@/assets/img/report4.png" alt="">
实验数据
</h6>
<el-table :data="expData" class="table" border stripe header-align="center">
<el-table-column type="index" label="序号" align="center" width="60">
<template slot-scope="scope">
{{ scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column prop="judgmentName" label="判分点" width="270" align="center"></el-table-column>
<el-table-column v-if='project' prop="judgmentName" label="考核点" align="center" width="150">
<template slot-scope="scope">
<div v-for="(item, index) in scope.row.lcRuleRecords" :key="index">
<span>
<span>{{ index + 1 }}. </span>{{ item.name }}
</span>
</div>
</template>
</el-table-column>
<el-table-column prop="ruleAnswer" label="参考答案" style='word-wrap: break-word'>
<template slot-scope="scope">
<div v-if='scope.row.lcRuleRecords'>
<div v-for="(item, index) in scope.row.lcRuleRecords" :key="index">
<span>
<span>{{ index + 1 }}. </span>{{ item.ruleAnswer }}
</span>
</div>
</div>
<div v-else v-html="scope.row.referenceAnswer"></div>
</template>
</el-table-column>
<el-table-column prop="userAnswer" label="学生答案">
<template slot-scope="scope">
<div v-if='scope.row.lcRuleRecords'>
<div v-for="(item, index) in scope.row.lcRuleRecords" :key="index">
<span v-if='item.userAnswer'>
<span>{{ index + 1 }}. </span>{{ item.userAnswer }}
</span>
<span v-else>
<span>{{ index + 1 }}. </span>未填写
</span>
</div>
</div>
<div v-else class="pre-code">{{ scope.row.answer }}</div>
<template v-if="scope.row.runThePictureList">
<img v-for="(img, i) in scope.row.runThePictureList" :key="i" width="200" class="result-pic"
:src="img" alt="">
</template>
</template>
</el-table-column>
<el-table-column prop="quesScore" label="分值" :key="6" width="80" align="center"></el-table-column>
<el-table-column prop="score" label="得分" width="80" align="center"></el-table-column>
</el-table>
</div>
<div class="m-b-20">
<h6 class="l-title">
<img src="@/assets/img/report5.png" alt="">
实验总结与体会
</h6>
<quill v-if="editing" :border="true" v-model="form.summarize" :minHeight="150" :height="150" />
<div v-else class="pre-wrap" v-html="form.summarize"></div>
</div>
</div>
</div>
</div>
</template>
<script>
import util from "@/libs/util";
export default {
data () {
return {
reportId: this.$route.query.reportId,
title: "实验报告",
form: {
className: "",
instructor: "",
period: "",
projectName: "",
summarize: "",
},
infoData: {},
expData: [],
editing: false,
loadIns: null,
loading: false,
project: false,
userScores: []
};
},
mounted () {
this.getData()
},
methods: {
getData () { //
this.loading = true
this.$get(`${this.api.reportDetail}?reportId=${this.reportId}`).then(({ report, userScores }) => {
this.form = report
this.project = this.expData.find(e => e.lcRuleRecords) // lcRuleRecords
let form = this.form;
this.infoData = {
workNumber: form.workNumber,
experimentalClassName: form.experimentalClassName,
instructor: form.instructor,
period: form.period,
laboratory: form.laboratory,
submitTime: form.submitTime,
score: form.score,
className: form.className,
userName: form.userName
}
const { data } = report
// data使
if (!data) {
this.userScores = userScores
this.handleList(userScores)
this.$post(this.api.editExperimentalData, {
reportId,
data: JSON.stringify(userScores)
}).then(res => { }).catch(err => { })
} else {
this.handleList(JSON.parse(data))
}
}).catch(res => {
this.loading = false
})
},
//
handleList (list) {
this.project = list.find(e => e.lcRuleRecords) // lcRuleRecords
if (this.project) {
list.map(e => {
e.assessmentPoint = ''
e.referenceAnswer = ''
e.answer = ''
e.lcRuleRecords && e.lcRuleRecords.map((n, i) => {
e.assessmentPoint += `${i + 1}.${n.name}`
e.referenceAnswer += `${i + 1}.${n.ruleAnswer}`
e.answer += `${i + 1}.${n.userAnswer}`
})
})
} else { // pythonuserScores
list.forEach(e => {
const item = this.userScores.find(n => n.judgmentId == e.judgmentId)
if (item && item.runThePictureList) e.runThePictureList = item.runThePictureList
})
}
this.expData = list
this.loading = false
},
exportPage () {
const form = Object.assign(this.form, this.infoData)
const list = JSON.parse(JSON.stringify(this.expData))
list.map((e, i) => {
const item = this.userScores.find(n => n.judgmentId == e.judgmentId)
if (item && item.runThePicture) e.runThePicture = item.runThePicture
if (item && item.runThePictureList) e.runThePictureList = item.runThePictureList
e.id = i + 1
// if (e.referenceAnswer && typeof e.referenceAnswer === 'string') e.referenceAnswer = e.referenceAnswer.replace(/<[^>]+>/g, '').replace(/(&nbsp;|&amp;|%s)/g, '').replace(/>/g, '&gt;').replace(/</g, '&lt;')
if (e.answer && typeof e.answer === 'string') e.answer = e.answer.replace(/<[^>]+>/g, '').replace(/(&nbsp;|&amp;|%s)/g, '').replace(/>/g, '&gt;').replace(/</g, '&lt;')
})
for (const i in form) {
if (form[i] && typeof form[i] === 'string') form[i] = form[i].replace(/<[^>]+>/g, '')
}
form.purpose = form.purpose.replace(/<[^>]+>/g, '')
this.$post(this.project ? this.api.exportBankExperimentReport : this.api.exportLabReport, {
...form,
experimentalData: list
}).then(res => {
console.log(res)
util.downloadFileDirect(`实验报告.docx`, new Blob([res]))
}).catch(res => { })
},
}
};
</script>
<style lang="scss" scoped>
.wrap {
padding: 12px 300px 20px;
}
.pre-code {
white-space: pre-wrap;
}
.text-right {
text-align: right;
}
code,
kbd,
samp {
font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif;
word-wrap: break-word;
white-space: pre-wrap;
}
/deep/ pre {
white-space: pre-wrap;
/* css-3 */
white-space: -moz-pre-wrap;
/* Mozilla, since 1999 */
white-space: pre-wrap;
/* Opera 4-6 */
white-space: -o-pre-wrap;
/* Opera 7 */
word-wrap: break-word;
/* Internet Explorer 5.5+ */
word-break: break-all;
overflow: hidden;
font-size: 12px;
font-weight: 400;
font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif;
}
.content {
padding: 16px 40px;
background: #fff;
.r-title {
margin-bottom: 40px;
font-size: 24px;
text-align: center;
color: #333;
}
.info {
padding: 20px 16px;
border: 1px solid #e1e6f2;
}
.l-title {
display: flex;
align-items: center;
padding: 5px 8px;
margin-bottom: 12px;
font-size: 14px;
color: #333;
background-color: #f7f5ff;
}
.info-list {
display: flex;
flex-wrap: wrap;
padding: 10px 0 0 20px;
li {
display: inline-flex;
width: 23%;
padding: 0 10px;
margin-bottom: 34px;
}
&.edit {
li {
align-items: center;
}
}
label {
font-size: 14px;
color: #333;
white-space: nowrap;
}
span {
min-width: 150px;
padding: 0 10px 3px;
border-bottom: 1px solid #e1e6f2;
}
/deep/.el-input {
width: 174px;
}
}
.score-wrap {
position: relative;
min-width: 150px;
border-bottom: 1px solid #e1e6f2;
em {
position: absolute;
top: -12px;
left: 30px;
font-family: din;
font-size: 30px;
font-weight: 600;
color: #0b1d30;
}
img {
position: absolute;
bottom: -15px;
left: 0;
}
}
/deep/.el-textarea .el-textarea__inner,
.pre-wrap {
min-height: 72px;
padding: 10px 16px;
font-size: 14px;
color: #333;
&.edit {
color: #abb3c6;
border: 1px solid #cacfdb;
border-radius: 4px;
background-color: #f6f7f9;
}
}
/deep/ .table th {
background-color: #e5dfff !important;
.cell {
line-height: 35px;
color: #fff;
}
}
}
.result-pic {
margin: 10px 0;
}
@media (max-width: 1650px) {
.wrap {
padding: 12px 200px 20px;
}
}
@media (max-width: 1430px) {
.wrap {
padding: 12px 100px 20px;
}
}
</style>

@ -11,9 +11,13 @@
<span class="per_back">返回</span> <span class="per_back">返回</span>
<span class="per_school">{{ titlesw }}</span> <span class="per_school">{{ titlesw }}</span>
</div> </div>
<el-button v-if="!viewDisabled" type="primary" round class="mag" v-preventReClick @click="submitOrder">确定 <div>
<el-button v-if="dispose || isAdd" type="primary" round v-preventReClick @click="shipAll">一键发货
</el-button>
<el-button v-if="!viewDisabled" type="primary" round v-preventReClick @click="submitOrder">确定
</el-button> </el-button>
</div> </div>
</div>
</el-card> </el-card>
<el-card shadow="hover" class="mgb20"> <el-card shadow="hover" class="mgb20">
@ -66,7 +70,7 @@
</el-form-item> </el-form-item>
<el-form-item prop="orderType" label="订单类型"> <el-form-item prop="orderType" label="订单类型">
<el-select :disabled="viewDisabled" v-model="form.orderType" clearable placeholder="请选择订单类型" <el-select :disabled="viewDisabled" v-model="form.orderType" clearable placeholder="请选择订单类型"
@change="updateOrderType"> @change="orderTypeChange">
<el-option v-for="(item, index) in orderTypeList" :key="index" :label="item.name" <el-option v-for="(item, index) in orderTypeList" :key="index" :label="item.name"
:value="item.value"></el-option> :value="item.value"></el-option>
</el-select> </el-select>
@ -125,6 +129,20 @@
<el-table-column prop="productName" label="产品名称" align="center" min-width="150" show-overflow-tooltip> <el-table-column prop="productName" label="产品名称" align="center" min-width="150" show-overflow-tooltip>
</el-table-column> </el-table-column>
<el-table-column label="使用期限" align="center" min-width="190"> <el-table-column label="使用期限" align="center" min-width="190">
<template slot="header" slot-scope="scope">
<template v-if="viewDisabled || isEdit">使用期限</template>
<template v-else>
<el-input class="batch-time" :disabled="viewDisabled || isEdit" maxlength="4" size="small"
@change="batchDeadlineChange(0)"
@input="productProps[0].deadline = productProps[0].deadline.replace(/[^0-9.]/g, '')"
v-model="productProps[0].deadline" placeholder="批量输入时间" />
<el-select class="batch-unit" v-model="productProps[0].unit" :disabled="viewDisabled || isEdit"
size="small" placeholder="请选择" @change="batchUnitChange(0)">
<el-option v-for="(item, i) in units" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</template>
</template>
<template slot-scope="scope"> <template slot-scope="scope">
<div class="small"> <div class="small">
<el-input class="time-input" :class="!scope.row.periodOfUse && whetherSubmit ? 'red' : ''" <el-input class="time-input" :class="!scope.row.periodOfUse && whetherSubmit ? 'red' : ''"
@ -134,9 +152,7 @@
v-model="scope.row.periodOfUse" placeholder="输入时间"></el-input> v-model="scope.row.periodOfUse" placeholder="输入时间"></el-input>
<el-select class="time-select" v-model="scope.row.options" :disabled="viewDisabled || isEdit" <el-select class="time-select" v-model="scope.row.options" :disabled="viewDisabled || isEdit"
placeholder="请选择" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)"> placeholder="请选择" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)">
<el-option label="日" :value="0"></el-option> <el-option v-for="(item, i) in units" :key="i" :label="item.name" :value="item.id"></el-option>
<el-option label="月" :value="1"></el-option>
<el-option label="年" :value="2"></el-option>
</el-select> </el-select>
</div> </div>
</template> </template>
@ -144,15 +160,15 @@
<el-table-column label="起止日期" align="center" min-width="240"> <el-table-column label="起止日期" align="center" min-width="240">
<template slot-scope="scope"> <template slot-scope="scope">
<p v-if="!scope.row.startTime"> <p v-if="!scope.row.startTime">
<el-date-picker :class="orderRepeat.includes(scope.row.dataOrCourseId) ? 'red' : ''" <el-date-picker :class="orderRepeat.includes(scope.row.mallId) ? 'red' : ''" style="width:130px"
style="width:130px" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit"
@change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)"
placeholder="请选择使用日期"> placeholder="请选择使用日期">
</el-date-picker> </el-date-picker>
</p> </p>
<p v-else> <p v-else>
<el-date-picker :class="orderRepeat.includes(scope.row.dataOrCourseId) ? 'red' : ''" <el-date-picker :class="orderRepeat.includes(scope.row.mallId) ? 'red' : ''" style="width:130px"
style="width:130px" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit"
@change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)"
placeholder="请选择使用日期"> placeholder="请选择使用日期">
</el-date-picker> </el-date-picker>
@ -188,7 +204,7 @@
<el-input :class="['normal', scope.row.finalPrice === '' && whetherSubmit ? 'red' : '']" <el-input :class="['normal', scope.row.finalPrice === '' && whetherSubmit ? 'red' : '']"
:disabled="viewDisabled" :disabled="viewDisabled"
@input="scope.row.finalPrice = scope.row.finalPrice.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1')" @input="scope.row.finalPrice = scope.row.finalPrice.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1')"
@change="[allAmount($event, scope.row), calculateDiscountCourse($event, scope.row)]" @change="[allAmount(scope.row), calculateDiscountCourse(scope.row)]"
v-model="scope.row.finalPrice" type="text"></el-input> v-model="scope.row.finalPrice" type="text"></el-input>
</div> </div>
</template> </template>
@ -262,6 +278,20 @@
<el-table-column prop="productName" label="产品名称" align="center" min-width="150" show-overflow-tooltip> <el-table-column prop="productName" label="产品名称" align="center" min-width="150" show-overflow-tooltip>
</el-table-column> </el-table-column>
<el-table-column label="使用期限" align="center" min-width="190"> <el-table-column label="使用期限" align="center" min-width="190">
<template slot="header" slot-scope="scope">
<template v-if="viewDisabled || isEdit">使用期限</template>
<template v-else>
<el-input class="batch-time" :disabled="viewDisabled || isEdit" maxlength="4"
@change="batchDeadlineChange(1)"
@input="productProps[1].deadline = productProps[1].deadline.replace(/[^0-9.]/g, '')"
v-model="productProps[1].deadline" placeholder="批量输入时间" />
<el-select class="batch-unit" v-model="productProps[1].unit" :disabled="viewDisabled || isEdit"
placeholder="请选择" @change="batchUnitChange(1)">
<el-option v-for="(item, i) in units" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</template>
</template>
<template slot-scope="scope"> <template slot-scope="scope">
<div class="small"> <div class="small">
<el-input class="time-input" :class="!scope.row.periodOfUse && whetherSubmit ? 'red' : ''" <el-input class="time-input" :class="!scope.row.periodOfUse && whetherSubmit ? 'red' : ''"
@ -271,9 +301,7 @@
v-model="scope.row.periodOfUse" placeholder="输入时间"></el-input> v-model="scope.row.periodOfUse" placeholder="输入时间"></el-input>
<el-select class="time-select" v-model="scope.row.options" :disabled="viewDisabled || isEdit" <el-select class="time-select" v-model="scope.row.options" :disabled="viewDisabled || isEdit"
placeholder="请选择" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)"> placeholder="请选择" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)">
<el-option label="日" :value="0"></el-option> <el-option v-for="(item, i) in units" :key="i" :label="item.name" :value="item.id"></el-option>
<el-option label="月" :value="1"></el-option>
<el-option label="年" :value="2"></el-option>
</el-select> </el-select>
</div> </div>
</template> </template>
@ -281,19 +309,19 @@
<el-table-column label="起止日期" align="center" min-width="240"> <el-table-column label="起止日期" align="center" min-width="240">
<template slot-scope="scope"> <template slot-scope="scope">
<p v-if="!scope.row.startTime"> <p v-if="!scope.row.startTime">
<el-date-picker :class="orderRepeat.includes(scope.row.dataOrCourseId) ? 'red' : ''" <el-date-picker :class="orderRepeat.includes(scope.row.mallId) ? 'red' : ''" style="width:130px"
style="width:130px" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit"
@change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)"
placeholder="请选择使用日期"> placeholder="请选择使用日期">
</el-date-picker> </el-date-picker>
</p> </p>
<p v-else> <p v-else>
<el-date-picker :class="orderRepeat.includes(scope.row.dataOrCourseId) ? 'red' : ''" <el-date-picker :class="orderRepeat.includes(scope.row.mallId) ? 'red' : ''" style="width:130px"
style="width:130px" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit"
@change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)"
placeholder="请选择使用日期"> placeholder="请选择使用日期">
</el-date-picker> </el-date-picker>
<span v-if="scope.row.startTime"><span v-if='scope.row.endTime'> - </span>{{ scope.row.endTime <span v-if="scope.row.startTime"><span v-if="scope.row.endTime"> - </span>{{ scope.row.endTime
}}</span> }}</span>
</p> </p>
</template> </template>
@ -325,7 +353,7 @@
<el-input :class="['normal', scope.row.finalPrice === '' && whetherSubmit ? 'red' : '']" <el-input :class="['normal', scope.row.finalPrice === '' && whetherSubmit ? 'red' : '']"
:disabled="viewDisabled" :disabled="viewDisabled"
@input="scope.row.finalPrice = scope.row.finalPrice.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1')" @input="scope.row.finalPrice = scope.row.finalPrice.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1')"
@change="[allAmount($event, scope.row), calculateDiscountCourse($event, scope.row)]" @change="[allAmount(scope.row), calculateDiscountCourse(scope.row)]"
v-model="scope.row.finalPrice" type="text"></el-input> v-model="scope.row.finalPrice" type="text"></el-input>
</div> </div>
</template> </template>
@ -399,7 +427,21 @@
</el-table-column> </el-table-column>
<el-table-column prop="productName" label="产品名称" align="center" min-width="100"> <el-table-column prop="productName" label="产品名称" align="center" min-width="100">
</el-table-column> </el-table-column>
<el-table-column label="使用期限" align="center" min-width="190"> <el-table-column label="使用期限" align="center" min-width="210">
<template slot="header" slot-scope="scope">
<template v-if="viewDisabled || isEdit">使用期限</template>
<template v-else>
<el-input class="batch-time" :disabled="viewDisabled || isEdit" maxlength="4"
@change="batchDeadlineChange(4)"
@input="productProps[4].deadline = productProps[4].deadline.replace(/[^0-9.]/g, '')"
v-model="productProps[4].deadline" placeholder="批量输入时间" />
<el-select class="batch-unit" v-model="productProps[4].unit" :disabled="viewDisabled || isEdit"
placeholder="请选择" @change="batchUnitChange(4)">
<el-option v-for="(item, i) in units" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</template>
</template>
<template slot-scope="scope"> <template slot-scope="scope">
<div class="small"> <div class="small">
<el-input class="time-input" :class="!scope.row.periodOfUse && whetherSubmit ? 'red' : ''" <el-input class="time-input" :class="!scope.row.periodOfUse && whetherSubmit ? 'red' : ''"
@ -410,9 +452,8 @@
<span style="margin-left:5px"> <span style="margin-left:5px">
<el-select class="time-select" v-model="scope.row.options" :disabled="viewDisabled || isEdit" <el-select class="time-select" v-model="scope.row.options" :disabled="viewDisabled || isEdit"
placeholder="请选择" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options)"> placeholder="请选择" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options)">
<el-option label="日" :value="0"></el-option> <el-option v-for="(item, i) in units" :key="i" :label="item.name"
<el-option label="月" :value="1"></el-option> :value="item.id"></el-option>
<el-option label="年" :value="2"></el-option>
</el-select> </el-select>
</span> </span>
</div> </div>
@ -421,15 +462,15 @@
<el-table-column label="起止日期" align="center" min-width="240"> <el-table-column label="起止日期" align="center" min-width="240">
<template slot-scope="scope"> <template slot-scope="scope">
<p v-if="!scope.row.startTime"> <p v-if="!scope.row.startTime">
<el-date-picker :class="orderRepeat.includes(scope.row.dataOrCourseId) ? 'red' : ''" <el-date-picker :class="orderRepeat.includes(scope.row.mallId) ? 'red' : ''" style="width:130px"
style="width:130px" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit"
@change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)"
placeholder="请选择使用日期"> placeholder="请选择使用日期">
</el-date-picker> </el-date-picker>
</p> </p>
<p v-else> <p v-else>
<el-date-picker :class="orderRepeat.includes(scope.row.dataOrCourseId) ? 'red' : ''" <el-date-picker :class="orderRepeat.includes(scope.row.mallId) ? 'red' : ''" style="width:130px"
style="width:130px" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit"
@change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)"
placeholder="请选择使用日期"> placeholder="请选择使用日期">
</el-date-picker> </el-date-picker>
@ -474,7 +515,7 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="账号数" align="center" min-width="100"> <el-table-column label="账号数" align="center" min-width="90">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="small"> <div class="small">
<el-input :class="['normal', !scope.row.accountNum && whetherSubmit ? 'red' : '']" <el-input :class="['normal', !scope.row.accountNum && whetherSubmit ? 'red' : '']"
@ -486,19 +527,18 @@
</template> </template>
</el-table-column> </el-table-column>
<!-- 金额自动计算计算方式账号数*成交价且可以手动修改保留两位小数 --> <!-- 金额自动计算计算方式账号数*成交价且可以手动修改保留两位小数 -->
<el-table-column label="成交价" align="center" min-width="160"> <el-table-column label="成交价" align="center" min-width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="small"> <div class="small">
<el-input style="width: 80%" <el-input style="width: 80%"
:class="['normal', scope.row.finalPrice === '' && whetherSubmit ? 'red' : '']" :class="['normal', scope.row.finalPrice === '' && whetherSubmit ? 'red' : '']"
:disabled="viewDisabled" :disabled="viewDisabled" @blur="[allAmount(scope.row), dealFinalValue($event, scope.row)]"
@blur="[allAmount($event, scope.row), dealFinalValue($event, scope.row)]"
@input="scope.row.finalPrice = scope.row.finalPrice.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1')" @input="scope.row.finalPrice = scope.row.finalPrice.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1')"
v-model="scope.row.finalPrice" type="text"></el-input> v-model="scope.row.finalPrice" type="text"></el-input>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="结算价" align="center" min-width="140"> <el-table-column label="结算价" align="center" min-width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<div class="small"> <div class="small">
<el-input style="width: 80%" <el-input style="width: 80%"
@ -559,6 +599,20 @@
<el-table-column prop="productName" label="产品名称" align="center" min-width="100"> <el-table-column prop="productName" label="产品名称" align="center" min-width="100">
</el-table-column> </el-table-column>
<el-table-column label="使用期限" align="center" min-width="190"> <el-table-column label="使用期限" align="center" min-width="190">
<template slot="header" slot-scope="scope">
<template v-if="viewDisabled || isEdit">使用期限</template>
<template v-else>
<el-input class="batch-time" :disabled="viewDisabled || isEdit" maxlength="4"
@change="batchDeadlineChange(2)"
@input="productProps[2].deadline = productProps[2].deadline.replace(/[^0-9.]/g, '')"
v-model="productProps[2].deadline" placeholder="批量输入时间" />
<el-select class="batch-unit" v-model="productProps[2].unit" :disabled="viewDisabled || isEdit"
placeholder="请选择" @change="batchUnitChange(2)">
<el-option v-for="(item, i) in units" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</template>
</template>
<template slot-scope="scope"> <template slot-scope="scope">
<div class="small"> <div class="small">
<el-input class="time-input" :class="!scope.row.periodOfUse && whetherSubmit ? 'red' : ''" <el-input class="time-input" :class="!scope.row.periodOfUse && whetherSubmit ? 'red' : ''"
@ -569,9 +623,8 @@
<span style="margin-left:5px"> <span style="margin-left:5px">
<el-select class="time-select" v-model="scope.row.options" :disabled="viewDisabled || isEdit" <el-select class="time-select" v-model="scope.row.options" :disabled="viewDisabled || isEdit"
placeholder="请选择" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options)"> placeholder="请选择" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options)">
<el-option label="日" :value="0"></el-option> <el-option v-for="(item, i) in units" :key="i" :label="item.name"
<el-option label="月" :value="1"></el-option> :value="item.id"></el-option>
<el-option label="年" :value="2"></el-option>
</el-select> </el-select>
</span> </span>
</div> </div>
@ -580,14 +633,14 @@
<el-table-column label="起止日期" align="center" min-width="240"> <el-table-column label="起止日期" align="center" min-width="240">
<template slot-scope="scope"> <template slot-scope="scope">
<p v-if="!scope.row.startTime"> <p v-if="!scope.row.startTime">
<el-date-picker :class="orderRepeat.includes(scope.row.dataOrCourseId) ? 'red' : ''" <el-date-picker :class="orderRepeat.includes(scope.row.mallId) ? 'red' : ''" style="width:130px"
style="width:130px" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit"
placeholder="请选择使用日期"> placeholder="请选择使用日期">
</el-date-picker> </el-date-picker>
</p> </p>
<p v-else> <p v-else>
<el-date-picker :class="orderRepeat.includes(scope.row.dataOrCourseId) ? 'red' : ''" <el-date-picker :class="orderRepeat.includes(scope.row.mallId) ? 'red' : ''" style="width:130px"
style="width:130px" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit"
@change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)"
placeholder="请选择使用日期"> placeholder="请选择使用日期">
</el-date-picker> </el-date-picker>
@ -679,13 +732,26 @@
</div> </div>
</div> </div>
<!--:summary-method="getSummaries"-->
<el-table :data="practicalCourses" class="orderTable orderTables" stripe header-align="center"> <el-table :data="practicalCourses" class="orderTable orderTables" stripe header-align="center">
<el-table-column type="index" width="60" label="序号" align="center"> <el-table-column type="index" width="60" label="序号" align="center">
</el-table-column> </el-table-column>
<el-table-column prop="productName" label="产品名称" align="center" min-width="150" show-overflow-tooltip> <el-table-column prop="productName" label="产品名称" align="center" min-width="150" show-overflow-tooltip>
</el-table-column> </el-table-column>
<el-table-column label="使用期限" align="center" min-width="190"> <el-table-column label="使用期限" align="center" min-width="190">
<template slot="header" slot-scope="scope">
<template v-if="viewDisabled || isEdit">使用期限</template>
<template v-else>
<el-input class="batch-time" :disabled="viewDisabled || isEdit" maxlength="4"
@change="batchDeadlineChange(3)"
@input="productProps[3].deadline = productProps[3].deadline.replace(/[^0-9.]/g, '')"
v-model="productProps[3].deadline" placeholder="批量输入时间" />
<el-select class="batch-unit" v-model="productProps[3].unit" :disabled="viewDisabled || isEdit"
placeholder="请选择" @change="batchUnitChange(3)">
<el-option v-for="(item, i) in units" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</template>
</template>
<template slot-scope="scope"> <template slot-scope="scope">
<div class="small"> <div class="small">
<el-input class="time-input" :class="!scope.row.periodOfUse && whetherSubmit ? 'red' : ''" <el-input class="time-input" :class="!scope.row.periodOfUse && whetherSubmit ? 'red' : ''"
@ -695,9 +761,7 @@
v-model="scope.row.periodOfUse" placeholder="输入时间"></el-input> v-model="scope.row.periodOfUse" placeholder="输入时间"></el-input>
<el-select class="time-select" v-model="scope.row.options" :disabled="viewDisabled || isEdit" <el-select class="time-select" v-model="scope.row.options" :disabled="viewDisabled || isEdit"
placeholder="请选择" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)"> placeholder="请选择" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)">
<el-option label="日" :value="0"></el-option> <el-option v-for="(item, i) in units" :key="i" :label="item.name" :value="item.id"></el-option>
<el-option label="月" :value="1"></el-option>
<el-option label="年" :value="2"></el-option>
</el-select> </el-select>
</div> </div>
</template> </template>
@ -705,15 +769,15 @@
<el-table-column label="起止日期" align="center" min-width="240"> <el-table-column label="起止日期" align="center" min-width="240">
<template slot-scope="scope"> <template slot-scope="scope">
<p v-if="!scope.row.startTime"> <p v-if="!scope.row.startTime">
<el-date-picker :class="orderRepeat.includes(scope.row.dataOrCourseId) ? 'red' : ''" <el-date-picker :class="orderRepeat.includes(scope.row.mallId) ? 'red' : ''" style="width:130px"
style="width:130px" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit"
@change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)"
placeholder="请选择使用日期"> placeholder="请选择使用日期">
</el-date-picker> </el-date-picker>
</p> </p>
<p v-else> <p v-else>
<el-date-picker :class="orderRepeat.includes(scope.row.dataOrCourseId) ? 'red' : ''" <el-date-picker :class="orderRepeat.includes(scope.row.mallId) ? 'red' : ''" style="width:130px"
style="width:130px" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit"
@change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)"
placeholder="请选择使用日期"> placeholder="请选择使用日期">
</el-date-picker> </el-date-picker>
@ -749,7 +813,7 @@
<el-input :class="['normal', scope.row.finalPrice === '' && whetherSubmit ? 'red' : '']" <el-input :class="['normal', scope.row.finalPrice === '' && whetherSubmit ? 'red' : '']"
:disabled="viewDisabled" :disabled="viewDisabled"
@input="scope.row.finalPrice = scope.row.finalPrice.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1')" @input="scope.row.finalPrice = scope.row.finalPrice.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1')"
@change="[allAmount($event, scope.row), calculateDiscountCourse($event, scope.row)]" @change="[allAmount(scope.row), calculateDiscountCourse(scope.row)]"
v-model="scope.row.finalPrice" type="text"></el-input> v-model="scope.row.finalPrice" type="text"></el-input>
</div> </div>
</template> </template>
@ -821,6 +885,20 @@
<el-table-column prop="productName" label="产品名称" align="center" min-width="150" show-overflow-tooltip> <el-table-column prop="productName" label="产品名称" align="center" min-width="150" show-overflow-tooltip>
</el-table-column> </el-table-column>
<el-table-column label="使用期限" align="center" min-width="190"> <el-table-column label="使用期限" align="center" min-width="190">
<template slot="header" slot-scope="scope">
<template v-if="viewDisabled || isEdit">使用期限</template>
<template v-else>
<el-input class="batch-time" :disabled="viewDisabled || isEdit" maxlength="4"
@change="batchDeadlineChange(5)"
@input="productProps[5].deadline = productProps[5].deadline.replace(/[^0-9.]/g, '')"
v-model="productProps[5].deadline" placeholder="批量输入时间" />
<el-select class="batch-unit" v-model="productProps[5].unit" :disabled="viewDisabled || isEdit"
placeholder="请选择" @change="batchUnitChange(5)">
<el-option v-for="(item, i) in units" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</template>
</template>
<template slot-scope="scope"> <template slot-scope="scope">
<div class="small"> <div class="small">
<el-input class="time-input" :class="!scope.row.periodOfUse && whetherSubmit ? 'red' : ''" <el-input class="time-input" :class="!scope.row.periodOfUse && whetherSubmit ? 'red' : ''"
@ -830,9 +908,7 @@
v-model="scope.row.periodOfUse" placeholder="输入时间"></el-input> v-model="scope.row.periodOfUse" placeholder="输入时间"></el-input>
<el-select class="time-select" v-model="scope.row.options" :disabled="viewDisabled || isEdit" <el-select class="time-select" v-model="scope.row.options" :disabled="viewDisabled || isEdit"
placeholder="请选择" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)"> placeholder="请选择" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)">
<el-option label="日" :value="0"></el-option> <el-option v-for="(item, i) in units" :key="i" :label="item.name" :value="item.id"></el-option>
<el-option label="月" :value="1"></el-option>
<el-option label="年" :value="2"></el-option>
</el-select> </el-select>
</div> </div>
</template> </template>
@ -840,15 +916,15 @@
<el-table-column label="起止日期" align="center" min-width="240"> <el-table-column label="起止日期" align="center" min-width="240">
<template slot-scope="scope"> <template slot-scope="scope">
<p v-if="!scope.row.startTime"> <p v-if="!scope.row.startTime">
<el-date-picker :class="orderRepeat.includes(scope.row.dataOrCourseId) ? 'red' : ''" <el-date-picker :class="orderRepeat.includes(scope.row.mallId) ? 'red' : ''" style="width:130px"
style="width:130px" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit"
@change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)"
placeholder="请选择使用日期"> placeholder="请选择使用日期">
</el-date-picker> </el-date-picker>
</p> </p>
<p v-else> <p v-else>
<el-date-picker :class="orderRepeat.includes(scope.row.dataOrCourseId) ? 'red' : ''" <el-date-picker :class="orderRepeat.includes(scope.row.mallId) ? 'red' : ''" style="width:130px"
style="width:130px" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit" v-model="scope.row.startTime" type="date" :disabled="viewDisabled || isEdit"
@change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)" @change="deadLine(scope.row.periodOfUse, scope.row, scope.row.options, 1)"
placeholder="请选择使用日期"> placeholder="请选择使用日期">
</el-date-picker> </el-date-picker>
@ -884,7 +960,7 @@
<el-input :class="['normal', scope.row.finalPrice === '' && whetherSubmit ? 'red' : '']" <el-input :class="['normal', scope.row.finalPrice === '' && whetherSubmit ? 'red' : '']"
:disabled="viewDisabled" :disabled="viewDisabled"
@input="scope.row.finalPrice = scope.row.finalPrice.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1')" @input="scope.row.finalPrice = scope.row.finalPrice.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1')"
@change="[allAmount($event, scope.row), calculateDiscountCourse($event, scope.row)]" @change="[allAmount(scope.row), calculateDiscountCourse(scope.row)]"
v-model="scope.row.finalPrice" type="text"></el-input> v-model="scope.row.finalPrice" type="text"></el-input>
</div> </div>
</template> </template>
@ -1098,30 +1174,42 @@ export default {
return { return {
// authority: 01234 // authority: 01234
deliverShow: ['pageTypes', 'dataPageTypes', 'modelPageTypes', 'practiceCourseTypes', 'expToolTypes', 'theoryCourse'], deliverShow: ['pageTypes', 'dataPageTypes', 'modelPageTypes', 'practiceCourseTypes', 'expToolTypes', 'theoryCourse'],
listName: [ productProps: [
{ {
id: 1, id: 1,
name: 'coursePermissions' name: 'coursePermissions',
deadline: '',
unit: '',
}, },
{ {
id: 2, id: 2,
name: 'theoryCourseList' name: 'theoryCourseList',
deadline: '',
unit: '',
}, },
{ {
id: 3, id: 3,
name: 'valuePermissions' name: 'valuePermissions',
deadline: '',
unit: '',
}, },
{ {
id: 4, id: 4,
name: 'practicalCourses' name: 'practicalCourses',
deadline: '',
unit: '',
}, },
{ {
id: 5, id: 5,
name: 'dataPlatformPermissions' name: 'dataPlatformPermissions',
deadline: '',
unit: '',
}, },
{ {
id: 6, id: 6,
name: 'expTools' name: 'expTools',
deadline: '',
unit: '',
}, },
], ],
pageTypes: false, pageTypes: false,
@ -1310,7 +1398,23 @@ export default {
// 1 2 3 45 6 // 1 2 3 45 6
classificationId: 0, classificationId: 0,
// //
theoryCourseList: [] theoryCourseList: [],
units: [
{
id: 0,
name: '日'
},
{
id: 1,
name: '月'
},
{
id: 2,
name: '年'
},
],
batchDeadline1: '',
batchUnit1: 2,
}; };
}, },
watch: { watch: {
@ -1469,7 +1573,6 @@ export default {
promises.push(new Promise((resolve, reject) => { promises.push(new Promise((resolve, reject) => {
this.$post(this.api.renew, { this.$post(this.api.renew, {
authority: 4, authority: 4,
// authority: 3,
customerId, customerId,
productId: orderOther.filter(e => e.authority === 4).map(e => e.mallId), productId: orderOther.filter(e => e.authority === 4).map(e => e.mallId),
}).then(({ orderOthers }) => { }).then(({ orderOthers }) => {
@ -1488,21 +1591,31 @@ export default {
* type 正式为1 * type 正式为1
* 试用为2 * 试用为2
*/ */
updateOrderType (type) { orderTypeChange (type) {
console.log('options=>', type)
if (type == 1) { if (type == 1) {
this.coursePermissions.forEach(item => { this.coursePermissions.forEach(e => {
this.dealSettlePrice(item) this.dealSettlePrice(e)
this.calculateDiscountCourse(e)
}) })
} else { } else {
this.coursePermissions.forEach(item => { this.productProps.map(e => {
item.finalPrice = 0 this[e.name].map(n => {
item.settlementPrice = 0 n.finalPrice = 0
n.settlementPrice = 0
// 使1
if (!n.periodOfUse) {
n.periodOfUse = 1
n.options = 1
this.deadLine(n.periodOfUse, n, n.options, 1)
}
this.calculateDiscountCourse(n)
})
}) })
} }
}, },
async setStartDate (renewList, orderOther) { async setStartDate (renewList, orderOther) {
const now = await Util.getNow() const now = await Util.getNow()
const onTrial = this.form.orderType === 2
let list = orderOther.map(e => { let list = orderOther.map(e => {
e.settlementPriceUnit = e.settlementPrice e.settlementPriceUnit = e.settlementPrice
const item = renewList.find(n => n.dataOrCourseId == e.dataOrCourseId && n.authority == e.authority) // renew const item = renewList.find(n => n.dataOrCourseId == e.dataOrCourseId && n.authority == e.authority) // renew
@ -1520,11 +1633,17 @@ export default {
// //
e.startTime = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}` e.startTime = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`
} }
e.endTime = ""; e.endTime = ''
e.periodOfUse = ""; e.periodOfUse = ''
// 1
if (onTrial) {
e.periodOfUse = 1
e.options = 1
this.deadLine(e.periodOfUse, e, e.options, 1)
}
} else if (!this.viewDisabled) { // } else if (!this.viewDisabled) { //
e.startTime = cur.startTime.split(" ")[0]; e.startTime = cur.startTime.split(" ")[0];
e.endTime = cur.endTime.split(" ")[0]; if (cur.endTime) e.endTime = cur.endTime.split(" ")[0];
} }
// } // }
if (item && this.renewDisabled) { if (item && this.renewDisabled) {
@ -1577,6 +1696,29 @@ export default {
const curClient = this.clients.find(e => e.customerId == customerId) const curClient = this.clients.find(e => e.customerId == customerId)
this.$post(`${this.api.refreshCache}?schoolId=${curClient ? curClient.schoolId : ''}`).then(res => { }).catch(res => { }) this.$post(`${this.api.refreshCache}?schoolId=${curClient ? curClient.schoolId : ''}`).then(res => { }).catch(res => { })
}, },
//
shipAll () {
this.productProps.map(e => {
this[e.name].map(n => {
n.ship = 1
n.isEnable = 1
})
})
},
//
batchDeadlineChange (i) {
this[this.productProps[i].name].map(e => {
e.periodOfUse = this.productProps[i].deadline
this.deadLine(e.periodOfUse, e, e.options, 1)
})
},
//
batchUnitChange (i) {
this[this.productProps[i].name].map(e => {
e.options = this.productProps[i].unit
this.deadLine(e.periodOfUse, e, e.options, 1)
})
},
// //
submitOrder () { submitOrder () {
let purchase = 0 // let purchase = 0 //
@ -1764,7 +1906,8 @@ export default {
}, },
// orderRepeatid // orderRepeatid
handleOrderRepeat (id) { handleOrderRepeat (id) {
this.orderRepeat.includes(id) && this.orderRepeat.splice(this.orderRepeat.findIndex(e => e == id), 1) const i = this.orderRepeat.findIndex(e => e == id)
i !== -1 && this.orderRepeat.splice(i, 1)
}, },
/* 处理0开头的期限 */ /* 处理0开头的期限 */
zero (e, row) { zero (e, row) {
@ -1793,15 +1936,20 @@ export default {
this.getSettlemennt() this.getSettlemennt()
}); });
this.$forceUpdate(); this.$forceUpdate();
//
this.productProps.map(e => {
this[e.name].map(n => {
this.deadLine(n.periodOfUse, n, n.options, 1)
})
})
} }
}, },
// //
getSettlemennt () { getSettlemennt () {
const list = [] const list = []
this.listName.map(e => e.name).forEach(e => { this.productProps.map(e => e.name).forEach(e => {
list.push(...this[e]) list.push(...this[e])
}) })
console.log("🚀 ~ file: AddOrder.vue:1954 ~ getSettlemennt ~ list:", list)
list.map(e => { list.map(e => {
this.$post(`${this.api.queryCitySettlementPrice}?mallId=${e.mallId}&provinceId=${this.form.provinceId}&cityId=${this.form.cityId}`).then(res => { this.$post(`${this.api.queryCitySettlementPrice}?mallId=${e.mallId}&provinceId=${this.form.provinceId}&cityId=${this.form.cityId}`).then(res => {
@ -1824,7 +1972,7 @@ export default {
// if (this.renewDisabled && this.coursePermissions.length === 1) { // if (this.renewDisabled && this.coursePermissions.length === 1) {
// return this.$message.warning(""); // return this.$message.warning("");
// } else { // } else {
this.handleOrderRepeat(row.dataOrCourseId) this.handleOrderRepeat(row.mallId)
this.coursePermissions.splice(index, 1); this.coursePermissions.splice(index, 1);
// } // }
}); });
@ -1837,7 +1985,7 @@ export default {
// if (this.renewDisabled && this.theoryCourseList.length === 1) { // if (this.renewDisabled && this.theoryCourseList.length === 1) {
// return this.$message.warning(""); // return this.$message.warning("");
// } else { // } else {
this.handleOrderRepeat(row.dataOrCourseId) this.handleOrderRepeat(row.mallId)
this.theoryCourseList.splice(index, 1); this.theoryCourseList.splice(index, 1);
// } // }
}); });
@ -1851,7 +1999,7 @@ export default {
// if (this.renewDisabled && this.dataPlatformPermissions.length === 1) { // if (this.renewDisabled && this.dataPlatformPermissions.length === 1) {
// return this.$message.warning(""); // return this.$message.warning("");
// } else { // } else {
this.handleOrderRepeat(row.dataOrCourseId) this.handleOrderRepeat(row.mallId)
this.dataPlatformPermissions.splice(index, 1); this.dataPlatformPermissions.splice(index, 1);
// } // }
}); });
@ -1865,7 +2013,7 @@ export default {
// if (this.renewDisabled && this.valuePermissions.length === 1) { // if (this.renewDisabled && this.valuePermissions.length === 1) {
// return this.$message.warning(""); // return this.$message.warning("");
// } else { // } else {
this.handleOrderRepeat(row.dataOrCourseId) this.handleOrderRepeat(row.mallId)
this.valuePermissions.splice(index, 1); this.valuePermissions.splice(index, 1);
// } // }
}); });
@ -1898,7 +2046,7 @@ export default {
}, },
practicalCoursesSelectable (row, index) { // practicalCoursesSelectable (row, index) { //
let boolean = true; let boolean = true;
const { name } = this.listName.find(e => e.id == this.classificationId) const { name } = this.productProps.find(e => e.id == this.classificationId)
this[name].length && this[name].some(e => { this[name].length && this[name].some(e => {
if (e.mallId == row.mallId) { if (e.mallId == row.mallId) {
boolean = false; boolean = false;
@ -1938,13 +2086,13 @@ export default {
break; break;
} }
const { orderType } = this.form const { orderType } = this.form
const { name } = this.listName.find(e => e.id == that.classificationId) const { name } = this.productProps.find(e => e.id == that.classificationId)
let fn = function (e) { let createProduct = function (e) {
that[name].push({ const row = {
dataOrCourseId: e.associatedProduct,// id dataOrCourseId: e.associatedProduct,// id
mallId: e.mallId, mallId: e.mallId,
productName: e.productName,// productName: e.productName,//
periodOfUse: "",// 使 periodOfUse: orderType === 2 ? 1 : '',// 使
startTime: new Date(),// startTime: new Date(),//
endTime: "", // endTime: "", //
remainingPeriod: "",// remainingPeriod: "",//
@ -1958,11 +2106,12 @@ export default {
isEnable: 0, // 10 isEnable: 0, // 10
ship: 0,// 01 ship: 0,// 01
authority, // authority, //
options: 2, options: orderType === 2 ? 1 : 2,
settlementPrice: orderType === 2 ? 0 : '', // settlementPrice: orderType === 2 ? 0 : '', //
settlementPriceUnit: e.settlementPrice || 0, // settlementPriceUnit: e.settlementPrice || 0, //
mallNonAssociatedLinks: e.mallNonAssociatedLinks // mallNonAssociatedLinks: e.mallNonAssociatedLinks //
}) }
that[name].push(row)
}; };
const productId = [] const productId = []
this.practicalCoursesSelect.map(e => {// this.practicalCoursesSelect.map(e => {//
@ -1975,33 +2124,37 @@ export default {
if (mall) { if (mall) {
e.settlementPrice = mall.discountRate e.settlementPrice = mall.discountRate
} }
fn(e); createProduct(e)
}).catch((res) => { }) }).catch((res) => { })
} }
}); });
this.practicalCourseVisible = false; this.practicalCourseVisible = false
this.practicalCourseName = ""; this.practicalCourseName = ''
this.practicalCoursesSelect = []; this.practicalCoursesSelect = []
/* 调接口,判断是否为客户已有的产品功能 */ /* 调接口,判断是否为客户已有的产品功能 */
productId.length && await this.$post(this.api.renew, { if (productId.length) {
const res = await this.$post(this.api.renew, {
authority, authority,
customerId: this.form.customerId, customerId: this.form.customerId,
productId, productId,
}).then(res => { })
this[name].map(e => { this[name].map(e => {
res.orderOthers.map(el => { const cur = res.orderOthers.find(n => n.mallId === e.mallId && n.dataOrCourseId == e.dataOrCourseId && n.authority == authority)
if (el.dataOrCourseId == e.dataOrCourseId && el.authority == authority) { if (cur) {
let time = new Date(el.endTime) let time = new Date(cur.endTime)
time = new Date(time.setDate(time.getDate() + 1)) time = new Date(time.setDate(time.getDate() + 1))
e.startTime = `${time.getFullYear()}-${time.getMonth() + 1}-${time.getDate()}` e.startTime = `${time.getFullYear()}-${time.getMonth() + 1}-${time.getDate()}`
e.endTime = ""; e.endTime = ''
e.periodOfUse = ""; // e.periodOfUse = orderType === 2 ? 0 : ''
e.renew = true; e.renew = true
}
if (orderType === 2) {
this.deadLine(e.periodOfUse, e, e.options, 1)
this.calculateDiscountCourse(e)
}
})
} }
});
});
});
} else { } else {
return this.$message.warning("请选择数据"); return this.$message.warning("请选择数据");
} }
@ -2019,7 +2172,7 @@ export default {
// if (this.renewDisabled && this.practicalCourses.length === 1) { // if (this.renewDisabled && this.practicalCourses.length === 1) {
// return this.$message.warning(""); // return this.$message.warning("");
// } else { // } else {
this.handleOrderRepeat(row.dataOrCourseId) this.handleOrderRepeat(row.mallId)
this.practicalCourses.splice(index, 1); this.practicalCourses.splice(index, 1);
// } // }
}); });
@ -2033,7 +2186,7 @@ export default {
if (this.renewDisabled && this.expTools.length === 1) { if (this.renewDisabled && this.expTools.length === 1) {
return this.$message.warning("续费至少保留一条产品信息"); return this.$message.warning("续费至少保留一条产品信息");
} else { } else {
this.handleOrderRepeat(row.dataOrCourseId) this.handleOrderRepeat(row.mallId)
this.expTools.splice(index, 1); this.expTools.splice(index, 1);
} }
}); });
@ -2086,10 +2239,10 @@ export default {
return isNaN(val) ? 0 : val return isNaN(val) ? 0 : val
}, },
// //
calculateDiscountCourse (val, row) { calculateDiscountCourse (row) {
const { finalPrice, marketValue } = row const { finalPrice, marketValue } = row
// (-)÷ x100% // (-)÷ x100%
if (finalPrice) row.discountRate = marketValue == 0 ? '0%' : ((marketValue - finalPrice) / marketValue * 100).toFixed(2) + "%"; if (finalPrice !== '') row.discountRate = marketValue == 0 ? '0%' : ((marketValue - finalPrice) / marketValue * 100).toFixed(2) + "%";
}, },
// //
calculateDiscount (val, row) { calculateDiscount (val, row) {
@ -2105,7 +2258,7 @@ export default {
} }
}, },
// //
allAmount ($event, row) { allAmount (row) {
this.dealSettlePrice(row) this.dealSettlePrice(row)
let total = 0 let total = 0
const list = [...this.coursePermissions, ...this.dataPlatformPermissions, ...this.practicalCourses, ...this.expTools] const list = [...this.coursePermissions, ...this.dataPlatformPermissions, ...this.practicalCourses, ...this.expTools]
@ -2139,7 +2292,7 @@ export default {
} }
} }
this.dealSettlePrice(row) this.dealSettlePrice(row)
this.allAmount(e, row) this.allAmount(row)
}, },
// //
dealSettlePrice (row) { dealSettlePrice (row) {
@ -2177,7 +2330,6 @@ export default {
let time = new Date(row.startTime).getTime(); let time = new Date(row.startTime).getTime();
let endTime = time + optionsData let endTime = time + optionsData
row.endTime = time + optionsData
var timestamp = endTime; var timestamp = endTime;
var dt = new Date(timestamp); // var dt = new Date(timestamp); //
row.endTime = (dt.getFullYear()) + "-" + (dt.getMonth() + 1) + "-" + (dt.getDate()) row.endTime = (dt.getFullYear()) + "-" + (dt.getMonth() + 1) + "-" + (dt.getDate())
@ -2195,13 +2347,13 @@ export default {
price * useUnit)).toFixed(2) price * useUnit)).toFixed(2)
this.dealComputers(e, row) this.dealComputers(e, row)
row.authority ? this.calculateDiscountCourse(e, row) : this.calculateDiscount(e, row) row.authority ? this.calculateDiscountCourse(row) : this.calculateDiscount(e, row)
// +1 // +1
if (isDate) { if (isDate) {
const cId = row.dataOrCourseId const cId = row.mallId
const date = new Date(row.startTime) const date = new Date(row.startTime)
const orderRepeat = this.orderRepeat const { orderRepeat } = this
this.$post(this.api.getOrderOtherTime, { this.$post(this.api.getOrderOtherTime, {
customerId: this.form.customerId, customerId: this.form.customerId,
id: row.mallId, id: row.mallId,
@ -2442,6 +2594,27 @@ export default {
width: 100px; width: 100px;
} }
.batch-time {
width: 100px !important;
/deep/.el-input__inner {
padding: 0 10px;
}
}
.batch-unit {
width: 77px !important;
margin-left: 5px;
/deep/.el-input {
width: auto !important;
}
/deep/.el-input__inner {
padding: 0 10px;
}
}
.time-input { .time-input {
width: 90px !important; width: 90px !important;
} }

@ -1,7 +1,6 @@
<template> <template>
<div> <div>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div> <div>
<div class="flex-center mgb20"> <div class="flex-center mgb20">
<p class="hr_tag"></p> <p class="hr_tag"></p>
@ -11,63 +10,41 @@
<el-form label-width="80px"> <el-form label-width="80px">
<el-col :span="4"> <el-col :span="4">
<el-form-item label="省份"> <el-form-item label="省份">
<el-select v-model="form.provinceId" <el-select v-model="form.provinceId" clearable placeholder="请选择省份" @change="getCity()"
clearable
placeholder="请选择省份"
@change="getCity()"
@clear="clearprovince()"> @clear="clearprovince()">
<el-option v-for="(item,index) in provinceList" <el-option v-for="(item, index) in provinceList" :key="index" :label="item.provinceName"
:key="index"
:label="item.provinceName"
:value="item.provinceId"></el-option> :value="item.provinceId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="4"> <el-col :span="4">
<el-form-item label="城市"> <el-form-item label="城市">
<el-select v-model="form.cityId" <el-select v-model="form.cityId" clearable placeholder="请选择城市"
clearable :disabled="form.provinceId ? false : true" @change="getData()">
placeholder="请选择城市" <el-option v-for="(item, index) in cityList" :key="index" :label="item.cityName"
:disabled="form.provinceId ? false : true"
@change="getData()">
<el-option v-for="(item,index) in cityList"
:key="index"
:label="item.cityName"
:value="item.cityId"></el-option> :value="item.cityId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="4"> <el-col :span="4">
<el-form-item label="订单类型"> <el-form-item label="订单类型">
<el-select v-model="form.orderType" <el-select v-model="form.orderType" clearable placeholder="请选择订单类型" @change="getData()">
clearable <el-option v-for="(item, index) in orderTypeList" :key="index" :label="item.name"
placeholder="请选择订单类型"
@change="getData()">
<el-option v-for="(item,index) in orderTypeList"
:key="index"
:label="item.name"
:value="item.value"></el-option> :value="item.value"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="4"> <el-col :span="4">
<el-form-item label="订单状态"> <el-form-item label="订单状态">
<el-select v-model="form.orderStatus" <el-select v-model="form.orderStatus" clearable placeholder="请选择订单状态" @change="getData()">
clearable <el-option v-for="(item, index) in orderStatusList" :key="index" :label="item.name"
placeholder="请选择订单状态"
@change="getData()">
<el-option v-for="(item,index) in orderStatusList"
:key="index"
:label="item.name"
:value="item.value"></el-option> :value="item.value"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item> <el-form-item>
<el-input placeholder="请输入订单号/客户名称/订单名称" <el-input placeholder="请输入订单号/客户名称/订单名称" prefix-icon="el-icon-search" v-model="form.customerName"
prefix-icon="el-icon-search"
v-model="form.customerName"
clearable></el-input> clearable></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -76,104 +53,56 @@
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="card">
class="card">
<div class="flex-between mgb20"> <div class="flex-between mgb20">
<div class="flex-center"> <div class="flex-center">
<p class="hr_tag"></p> <p class="hr_tag"></p>
<span>订单列表</span> <span>订单列表</span>
</div> </div>
<div> <div>
<el-button type="primary" <el-button type="primary" round @click="addOrder" v-auth>新建订单</el-button>
round <el-button type="primary" round @click="delAllSelection" v-auth>批量删除</el-button>
@click="addOrder"
v-auth>新建订单</el-button>
<el-button type="primary"
round
@click="delAllSelection"
v-auth>批量删除</el-button>
</div> </div>
</div> </div>
<el-table :data="orderData" <el-table :data="orderData" class="table" ref="table" stripe header-align="center"
class="table" @selection-change="handleSelectionChange" row-key="orderId">
ref="table" <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
stripe <el-table-column type="index" width="100" label="序号" align="center">
header-align="center"
@selection-change="handleSelectionChange"
row-key="orderId">
<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>
<el-table-column prop="orderNumber" <el-table-column prop="orderNumber" label="订单编号" align="center">
label="订单编号"
align="center">
</el-table-column> </el-table-column>
<el-table-column prop="customerName" <el-table-column prop="customerName" label="客户名称" align="center">
label="客户名称"
align="center">
</el-table-column> </el-table-column>
<el-table-column prop="orderContent" <el-table-column prop="orderContent" label="订单内容" align="center" show-overflow-tooltip></el-table-column>
label="订单内容" <el-table-column prop="orderAmount" label="订单金额(元)" align="center">
align="center"
show-overflow-tooltip></el-table-column>
<el-table-column prop="orderAmount"
label="订单金额(元)"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.orderType === '试用' ? 0 : scope.row.orderAmount }} {{ scope.row.orderType === '试用' ? 0 : scope.row.orderAmount }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" <el-table-column prop="createTime" label="订单日期" align="center">
label="订单日期"
align="center">
</el-table-column> </el-table-column>
<el-table-column prop="orderType" <el-table-column prop="orderType" label="订单类型" align="center">
label="订单类型"
align="center">
</el-table-column> </el-table-column>
<el-table-column prop="orderStatus" <el-table-column prop="orderStatus" label="订单状态" align="center">
label="订单状态"
align="center">
</el-table-column> </el-table-column>
<el-table-column prop="orderNature" <el-table-column prop="orderNature" label="订单性质" align="center">
label="订单性质"
align="center">
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" align="center">
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" <el-button type="text" v-if="scope.row.isDel !== 1" @click="handle('edit', scope.row)" v-auth="'/order:修改'">
v-if="scope.row.isDel!==1"
@click="handle('edit',scope.row)"
v-auth="'/order:修改'">
{{ scope.row.orderStatus === "已完成" ? "修改" : "处理" }} {{ scope.row.orderStatus === "已完成" ? "修改" : "处理" }}
</el-button> </el-button>
<el-button type="text" <el-button type="text" @click="handle('watch', scope.row)" v-auth>查看</el-button>
@click="handle('watch',scope.row)" <el-button type="text" @click="handleDelete(scope.row)" v-auth>删除</el-button>
v-auth>查看</el-button> <el-button type="text" v-if="scope.row.orderStatus === '已完成' && scope.row.isDel !== 1"
<el-button type="text" @click="handle('renew', scope.row)" v-auth>续费
@click="handleDelete(scope.row)"
v-auth>删除</el-button>
<el-button type="text"
v-if="scope.row.orderStatus==='已完成'&&scope.row.isDel!==1"
@click="handle('renew',scope.row)"
v-auth>续费
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background <el-pagination background layout="total, prev, pager, next" @current-change="handleCurrentChange"
layout="total, prev, pager, next" :current-page="page" :total="totals">
@current-change="handleCurrentChange"
:current-page="page"
:total="totals">
</el-pagination> </el-pagination>
</div> </div>
</el-card> </el-card>
@ -404,9 +333,11 @@ export default {
.card { .card {
min-height: calc(100vh - 300px); min-height: calc(100vh - 300px);
} }
.mag { .mag {
margin-right: 20px; margin-right: 20px;
} }
.cell { .cell {
white-space: pre-wrap; white-space: pre-wrap;
width: 140px; width: 140px;
@ -417,6 +348,7 @@ export default {
line-clamp: 2; line-clamp: 2;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
} }
.tags { .tags {
border: none; border: none;
background: none; background: none;
@ -431,4 +363,3 @@ export default {
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
} }
</style> </style>

@ -21,37 +21,20 @@
</div> </div>
<div style="height: 504px; max-height: 504px; overflow: auto"> <div style="height: 504px; max-height: 504px; overflow: auto">
<el-tree <el-tree :data="orgList" default-expand-all ref="orgTree" node-key="id" highlight-current
:data="orgList" :expand-on-click-node="false" @node-click="handleNodeClick"
default-expand-all :props="{ children: 'children', label: 'partnerClassificationName', isLeaf: 'leaf' }">
ref="orgTree"
node-key="id"
highlight-current
:expand-on-click-node="false"
@node-click="handleNodeClick"
:props="{children: 'children', label: 'partnerClassificationName', isLeaf: 'leaf'}"
>
<span class="custom-tree-node" slot-scope="{ node, data }"> <span class="custom-tree-node" slot-scope="{ node, data }">
<span class="org-name">{{ node.label }}</span> <span class="org-name">{{ node.label }}</span>
<span> <span>
<!-- isTeam 0: 分类1: 团队 --> <!-- isTeam 0: 分类1: 团队 -->
<el-button <el-button v-auth="'/parner:账号管理:添加分类'" v-if="!data.isTeam" type="text"
v-auth="'/parner:账号管理:添加分类'" icon="el-icon-circle-plus-outline" @click="() => addOrg(node, data)">
v-if="!data.isTeam"
type="text"
icon="el-icon-circle-plus-outline"
@click="() => addOrg(node, data)">
</el-button> </el-button>
<el-button <el-button v-auth="'/parner:账号管理:编辑分类'" type="text" icon="el-icon-edit-outline"
v-auth="'/parner:账号管理:编辑分类'"
type="text"
icon="el-icon-edit-outline"
@click="() => editOrg(node, data)"> @click="() => editOrg(node, data)">
</el-button> </el-button>
<el-button <el-button v-auth="'/parner:账号管理:删除分类'" type="text" icon="el-icon-delete"
v-auth="'/parner:账号管理:删除分类'"
type="text"
icon="el-icon-delete"
@click="() => delOrg(node, data)"> @click="() => delOrg(node, data)">
</el-button> </el-button>
</span> </span>
@ -60,27 +43,16 @@
</div> </div>
</div> </div>
<el-dialog <el-dialog :title="typeForm.id ? '编辑' : '新增' + '分类'" :visible.sync="orgVisible" :close-on-click-modal="false"
:title="typeForm.id ? '编辑' : '新增' + '分类'" width="50%" @close="closeType">
:visible.sync="orgVisible"
:close-on-click-modal="false"
width="50%"
@close="closeType"
>
<el-form v-if="orgVisible" ref="typeForm" :model="typeForm" :rules="orgRules" label-width="100px"> <el-form v-if="orgVisible" ref="typeForm" :model="typeForm" :rules="orgRules" label-width="100px">
<el-form-item label="分类名称" prop="partnerClassificationName"> <el-form-item label="分类名称" prop="partnerClassificationName">
<el-input v-model.trim="typeForm.partnerClassificationName" placeholder="请输入"></el-input> <el-input v-model.trim="typeForm.partnerClassificationName" placeholder="请输入"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="上级部门"> <el-form-item label="上级部门">
<span v-if="typeForm.parentName">{{ typeForm.parentName }}</span> <span v-if="typeForm.parentName">{{ typeForm.parentName }}</span>
<el-cascader <el-cascader v-else :options="orgListDia" v-model="cascaderValue" :props="cascaderProps" clearable
v-else style="width: 100%">
:options="orgListDia"
v-model="cascaderValue"
:props="cascaderProps"
clearable
style="width: 100%"
>
</el-cascader> </el-cascader>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -96,7 +68,8 @@
<div class="tool"> <div class="tool">
<ul class="filter"> <ul class="filter">
<li> <li>
<el-input style="width: 250px;" placeholder="请输入员工姓名/手机号" prefix-icon="el-icon-search" v-model="keyWord" clearable></el-input> <el-input style="width: 250px;" placeholder="请输入员工姓名/手机号" prefix-icon="el-icon-search" v-model="keyWord"
clearable></el-input>
</li> </li>
</ul> </ul>
<div> <div>
@ -104,18 +77,21 @@
</div> </div>
</div> </div>
<el-table :data="listData" class="table" ref="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id"> <el-table :data="listData" class="table" ref="table" stripe header-align="center"
@selection-change="handleSelectionChange" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> <el-table-column type="selection" width="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 type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="userName" label="姓名" align="center" min-width="100"></el-table-column> <el-table-column prop="userName" label="姓名" align="center" min-width="100"></el-table-column>
<el-table-column prop="account" label="账号" align="center" min-width="100"></el-table-column> <el-table-column prop="account" label="账号" align="center" min-width="100"></el-table-column>
<el-table-column prop="phone" label="手机号" align="center" min-width="120"></el-table-column> <el-table-column prop="phone" label="手机号" align="center" min-width="120"></el-table-column>
<el-table-column prop="invitationAccount" label="邀请人" align="center" min-width="120"></el-table-column> <el-table-column prop="invitationAccount" label="邀请人" align="center" min-width="120"></el-table-column>
<el-table-column prop="partnerClassificationName" label="团队名称" align="center" min-width="120" show-overflow-tooltip></el-table-column> <el-table-column prop="partnerClassificationName" label="团队名称" align="center" min-width="120"
show-overflow-tooltip></el-table-column>
<template v-if="!type"> <template v-if="!type">
<el-table-column prop="provinceName" label="省份" align="center" min-width="80"></el-table-column> <el-table-column prop="provinceName" label="省份" align="center" min-width="80"></el-table-column>
<el-table-column prop="cityName" label="城市" align="center" min-width="80"></el-table-column> <el-table-column prop="cityName" label="城市" align="center" min-width="80"></el-table-column>
<el-table-column prop="roleName" label="授权角色" align="center" min-width="120" show-overflow-tooltip></el-table-column> <el-table-column prop="roleName" label="授权角色" align="center" min-width="120"
show-overflow-tooltip></el-table-column>
<el-table-column prop="phone" label="费率" align="center" min-width="120"> <el-table-column prop="phone" label="费率" align="center" min-width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<p v-if="scope.row.annualTeamFee">团队年费{{ scope.row.annualTeamFee }}w</p> <p v-if="scope.row.annualTeamFee">团队年费{{ scope.row.annualTeamFee }}w</p>
@ -130,16 +106,20 @@
<el-button v-if="!type" type="text" v-auth="'/parner:账号管理:重置密码'" @click="edit(scope.row)">编辑</el-button> <el-button v-if="!type" type="text" v-auth="'/parner:账号管理:重置密码'" @click="edit(scope.row)">编辑</el-button>
<el-button type="text" v-auth="'/parner:账号管理:重置密码'" @click="resetPassword(scope.row)">重置密码</el-button> <el-button type="text" v-auth="'/parner:账号管理:重置密码'" @click="resetPassword(scope.row)">重置密码</el-button>
<el-button v-if="type" type="text" v-auth="'/parner:账号管理:删除合伙人'" @click="del(scope.row)">删除</el-button> <el-button v-if="type" type="text" v-auth="'/parner:账号管理:删除合伙人'" @click="del(scope.row)">删除</el-button>
<el-button v-else-if="scope.row.isTeam == 1" type="text" v-auth="'/parner:账号管理:转让超管'" @click="transfer(scope.row)">转让超管</el-button> <el-button v-else-if="scope.row.isTeam == 1" type="text" v-auth="'/parner:账号管理:转让超管'"
<el-button v-if="scope.row.isTeam == 0" type="text" v-auth="'/parner:账号管理:移除'" @click="remove(scope.row)">移除</el-button> @click="transfer(scope.row)">转让超管</el-button>
<el-button v-if="scope.row.isTeam == 0" type="text" v-auth="'/parner:账号管理:移除'"
@click="remove(scope.row)">移除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next" :total="total"></el-pagination> <el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next"
:total="total"></el-pagination>
</div> </div>
<el-dialog title="添加城市合伙人" :visible.sync="parnerVisible" width="580px" custom-class="add-dia" :close-on-click-modal="false" @close="closeAdd"> <el-dialog title="添加城市合伙人" :visible.sync="parnerVisible" width="580px" custom-class="add-dia"
:close-on-click-modal="false" @close="closeAdd">
<p class="tips">链接/二维码失效时间{{ expireTime }}</p> <p class="tips">链接/二维码失效时间{{ expireTime }}</p>
<p class="title">城市合伙人 <em>邀请链接</em></p> <p class="title">城市合伙人 <em>邀请链接</em></p>
<p class="des">加盟商合作伙伴可以通过这个链接加入 <em>城市合伙人计划</em></p> <p class="des">加盟商合作伙伴可以通过这个链接加入 <em>城市合伙人计划</em></p>
@ -152,21 +132,24 @@
<img width="250" :src="qrcode" alt=""> <img width="250" :src="qrcode" alt="">
</el-dialog> </el-dialog>
<el-dialog title="转让管理员" :visible.sync="transferVisible" width="350px" custom-class="transfer-dia" :close-on-click-modal="false"> <el-dialog title="转让管理员" :visible.sync="transferVisible" width="350px" custom-class="transfer-dia"
:close-on-click-modal="false">
<div style="text-align: center"> <div style="text-align: center">
<el-button type="primary" @click="showChoose">转给团队成员</el-button> <el-button type="primary" @click="showChoose">转给团队成员</el-button>
<el-button @click="add(1)">邀请外部人员</el-button> <el-button @click="add(1)">邀请外部人员</el-button>
</div> </div>
</el-dialog> </el-dialog>
<el-dialog title="请选择要转让的团队成员" :visible.sync="chooseVisible" width="300px" custom-class="choose-dia" :close-on-click-modal="false"> <el-dialog title="请选择要转让的团队成员" :visible.sync="chooseVisible" width="300px" custom-class="choose-dia"
:close-on-click-modal="false">
<ul class="member-list"> <ul class="member-list">
<li v-for="(item, i) in members" :key="i"> <li v-for="(item, i) in members" :key="i">
<div class="info"> <div class="info">
<img src="@/assets/img/avatar.png" alt=""> <img src="@/assets/img/avatar.png" alt="">
<span class="name">{{ item.userName }}</span> <span class="name">{{ item.userName }}</span>
</div> </div>
<el-radio v-model="choosePartnerId" :label="item.partnerId" :disabled="curRow.accountId === item.accountId"></el-radio> <el-radio v-model="choosePartnerId" :label="item.partnerId"
:disabled="curRow.accountId === item.accountId"></el-radio>
</li> </li>
</ul> </ul>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
@ -184,22 +167,22 @@
<el-select class="w-100" v-model="form.roleList" multiple> <el-select class="w-100" v-model="form.roleList" multiple>
<template v-for="item in roleList"> <template v-for="item in roleList">
<!-- 不显示超管 --> <!-- 不显示超管 -->
<el-option <el-option :key="item.id" :label="item.roleName" :value="item.id">
:key="item.id"
:label="item.roleName"
:value="item.id">
</el-option> </el-option>
</template> </template>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="provinceId" label="省份"> <el-form-item prop="provinceId" label="省份">
<el-select style="width: 100%" v-model="form.provinceId" placeholder="请选择省份" @change="getCity"> <el-select style="width: 100%" v-model="form.provinceId" placeholder="请选择省份" @change="getCity">
<el-option v-for="(item,index) in provinces" :key="index" :label="item.provinceName" :value="item.provinceId"></el-option> <el-option v-for="(item, index) in provinces" :key="index" :label="item.provinceName"
:value="item.provinceId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="cityId" label="城市"> <el-form-item prop="cityId" label="城市">
<el-select style="width: 100%" v-model="form.cityId" placeholder="请选择城市" :disabled="form.provinceId ? false : true"> <el-select style="width: 100%" v-model="form.cityId" placeholder="请选择城市"
<el-option v-for="(item,index) in cities" :key="index" :label="item.cityName" :value="item.cityId"></el-option> :disabled="form.provinceId ? false : true">
<el-option v-for="(item, index) in cities" :key="index" :label="item.cityName"
:value="item.cityId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -665,47 +648,58 @@ export default {
.m-b-20 { .m-b-20 {
margin-bottom: 20px; margin-bottom: 20px;
} }
.org-name { .org-name {
margin-right: 20px; margin-right: 20px;
} }
.w-100 { .w-100 {
width: 100%; width: 100%;
} }
.wrap { .wrap {
display: flex; display: flex;
padding: 0 24px; padding: 0 24px;
.side { .side {
width: 300px; width: 300px;
padding: 24px 10px 24px 0; padding: 24px 10px 24px 0;
margin-right: 24px; margin-right: 24px;
border-right: 1px solid rgba(0, 0, 0, 0.06); border-right: 1px solid rgba(0, 0, 0, 0.06);
} }
.right { .right {
width: calc(100% - 324px); width: calc(100% - 324px);
padding: 24px 0; padding: 24px 0;
} }
} }
.add-dia { .add-dia {
.tips { .tips {
font-size: 12px; font-size: 12px;
color: #f00; color: #f00;
} }
.title { .title {
margin: 10px 0; margin: 10px 0;
font-size: 14px; font-size: 14px;
em { em {
font-style: normal; font-style: normal;
} }
} }
.des { .des {
font-size: 13px; font-size: 13px;
color: #7a7a7a; color: #7a7a7a;
} }
.link-wrap { .link-wrap {
display: flex; display: flex;
align-items: center; align-items: center;
margin: 10px 0 20px; margin: 10px 0 20px;
} }
.link { .link {
padding: 10px; padding: 10px;
margin-right: 15px; margin-right: 15px;
@ -713,6 +707,7 @@ export default {
border-radius: 4px; border-radius: 4px;
} }
} }
/deep/.choose-dia { /deep/.choose-dia {
.member-list { .member-list {
li { li {
@ -721,17 +716,21 @@ export default {
align-items: center; align-items: center;
margin-bottom: 10px; margin-bottom: 10px;
} }
.info { .info {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
} }
img { img {
width: 40px; width: 40px;
height: 40px; height: 40px;
} }
.name { .name {
margin-left: 10px; margin-left: 10px;
} }
.el-radio__label { .el-radio__label {
display: none; display: none;
} }

@ -0,0 +1,50 @@
<template>
<div>
<iframe :src="url" frameborder="0" width="100%"></iframe>
</div>
</template>
<script>
import Setting from '@/setting'
export default {
data () {
return {
url: ''
};
},
mounted () {
const token = sessionStorage.getItem('token')
const cache = localStorage.getItem('reviewPath') // localStorage
let url = `${location.origin}/reviewCenter/`
if (Setting.isDev) url = `http://192.168.31.125:8099/`
if (cache) {
url += '#' + this.replaceParam(cache, Date.now())
} else {
url += `#/myReview?nakadai=1${Setting.isDev ? `&token=${token}` : ''}&v=${Date.now()}`
}
console.log("🚀 ~ mounted ~ url:", url)
localStorage.setItem('review_token', token)
this.url = url
},
methods: {
replaceParam (url, newVValue) {
const vParamRegex = /v=[^&]+/g
let newUrl = url.replace(vParamRegex, `v=${newVValue}`)
const [baseUrl, hash] = newUrl.split('#');
if (hash) {
newUrl = `${baseUrl}#${hash.replace(vParamRegex, `v=${newVValue}`)}`
}
return newUrl
}
}
};
</script>
<style lang="scss" scoped>
iframe {
height: calc(100vh - 167px);
}
</style>

@ -1,7 +1,6 @@
<template> <template>
<div> <div>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div> <div>
<div class="flex-center mgb20"> <div class="flex-center mgb20">
<p class="hr_tag"></p> <p class="hr_tag"></p>
@ -12,36 +11,22 @@
<div> <div>
<el-col :span="4"> <el-col :span="4">
<el-form-item label="系统归属"> <el-form-item label="系统归属">
<el-select v-model="form.belong" <el-select v-model="form.belong" clearable placeholder="请选择系统归属" @change="initData">
clearable <el-option v-for="(item, i) in belongs" :key="i" :label="item" :value="i"></el-option>
placeholder="请选择系统归属"
@change="initData">
<el-option v-for="(item, i) in belongs"
:key="i"
:label="item"
:value="i"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="4"> <el-col :span="4">
<el-form-item label="系统类型"> <el-form-item label="系统类型">
<el-select v-model="form.type" <el-select v-model="form.type" clearable placeholder="请选择系统类型" @change="initData">
clearable <el-option v-for="(item, i) in types" :key="i" :label="item" :value="i"></el-option>
placeholder="请选择系统类型"
@change="initData">
<el-option v-for="(item, i) in types"
:key="i"
:label="item"
:value="i"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
</div> </div>
<el-col :span="6"> <el-col :span="6">
<el-form-item> <el-form-item>
<el-input placeholder="请输入系统名称" <el-input placeholder="请输入系统名称" prefix-icon="el-icon-search" v-model.trim="form.systemName"
prefix-icon="el-icon-search"
v-model.trim="form.systemName"
clearable></el-input> clearable></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -50,84 +35,53 @@
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="card">
class="card">
<div class="flex-center mgb20"> <div class="flex-center mgb20">
<p class="hr_tag"></p> <p class="hr_tag"></p>
<span>服务列表</span> <span>服务列表</span>
</div> </div>
<el-table :data="list" <el-table :data="list" class="table" stripe header-align="center">
class="table"
stripe
header-align="center">
<!-- <el-table-column type="selection" width="55" align="center"></el-table-column> --> <!-- <el-table-column type="selection" width="55" align="center"></el-table-column> -->
<el-table-column type="index" <el-table-column type="index" width="100" label="序号" align="center">
width="100"
label="序号"
align="center">
</el-table-column> </el-table-column>
<el-table-column prop="systemName" <el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
label="系统名称" <el-table-column prop="type" label="系统类型" align="center">
align="center"></el-table-column>
<el-table-column prop="type"
label="系统类型"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ types[scope.row.type] }} {{ types[scope.row.type] }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="supplierName" <el-table-column prop="supplierName" label="供应商" align="center"></el-table-column>
label="供应商" <el-table-column prop="belong" label="系统归属" align="center">
align="center"></el-table-column>
<el-table-column prop="belong"
label="系统归属"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ belongs[scope.row.belong] }} {{ belongs[scope.row.belong] }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="state" <el-table-column prop="state" label="系统状态" align="center">
label="系统状态"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ states[scope.row.state] }} {{ states[scope.row.state] }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="payamount" <el-table-column prop="payamount" label="系统后台" align="center">
label="系统后台"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" <el-button type="text" @click="toBackstage(scope.row)"
@click="toBackstage(scope.row)"
v-if="scope.row.systemId !== '11' && scope.row.systemId !== '12'" v-if="scope.row.systemId !== '11' && scope.row.systemId !== '12'"
v-auth="'/configure:系统后台进入'">进入</el-button> v-auth="'/configure:系统后台进入'">进入</el-button>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="payamount" <el-table-column prop="payamount" label="项目系统" align="center">
label="项目系统"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" <el-button type="text" @click="getIntoProject(scope.row)" v-auth="'/configure:项目系统进入'">进入</el-button>
@click="getIntoProject(scope.row)"
v-auth="'/configure:项目系统进入'">进入</el-button>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="payamount" <el-table-column prop="payamount" label="判分系统" align="center">
label="判分系统"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" <el-button type="text" @click="getIntoJudgement(scope.row)" v-auth="'/configure:判分系统进入'">进入</el-button>
@click="getIntoJudgement(scope.row)"
v-auth="'/configure:判分系统进入'">进入</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background <el-pagination background @current-change="handleCurrentChange" layout="total, prev, pager, next"
@current-change="handleCurrentChange" :current-page="page" :total="total">
layout="total, prev, pager, next"
:current-page="page"
:total="total">
</el-pagination> </el-pagination>
</div> </div>
</el-card> </el-card>
@ -154,7 +108,7 @@ export default {
1: '外部产品', 1: '外部产品',
0: '内部系统' 0: '内部系统'
}, },
types: ['编程类', '流程类'], types: ['编程类', '流程类', 'AI类'],
states: ['运行中', '默认'], states: ['运行中', '默认'],
page: +this.$route.query.page || 1, page: +this.$route.query.page || 1,
pageSize: 10 pageSize: 10
@ -207,7 +161,7 @@ export default {
// //
toBackstage (row) { toBackstage (row) {
this.setReferrer() this.setReferrer()
if (row.systemId == 19) { if (row.systemId == 19 || row.systemId == 30) {
location.href = `${Setting.sandPath}/#/config?token=${sessionStorage.getItem('token')}&admin=1&referrer=${encodeURIComponent(location.href)}` location.href = `${Setting.sandPath}/#/config?token=${sessionStorage.getItem('token')}&admin=1&referrer=${encodeURIComponent(location.href)}`
} else { } else {
this.$router.push(`/backstage?systemId=${row.systemId}&show=1&name=${row.systemName}`) this.$router.push(`/backstage?systemId=${row.systemId}&show=1&name=${row.systemName}`)
@ -229,8 +183,8 @@ export default {
.card { .card {
min-height: calc(100vh - 300px); min-height: calc(100vh - 300px);
} }
.mag { .mag {
margin-right: 20px; margin-right: 20px;
} }
</style> </style>

@ -1,28 +1,20 @@
<template> <template>
<div ref="main" <div ref="main" class="main" v-loading="loading">
class="main"
v-loading="loading">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="24"> <el-col :span="24">
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="flex-between"> <div class="flex-between">
<el-page-header @back="back" <el-page-header @back="back" content="项目配置"></el-page-header>
content="项目配置"></el-page-header>
<div v-if="!isDetail"> <div v-if="!isDetail">
<el-button type="success" <el-button type="success" :loading="submiting === 0"
:loading="submiting === 0"
@click="handleSubmit(0, projectManage.isOpen = 1, projectManage.ztOpen = 1)">保存为草稿 @click="handleSubmit(0, projectManage.isOpen = 1, projectManage.ztOpen = 1)">保存为草稿
</el-button> </el-button>
<el-button type="primary" <el-button type="primary" :loading="submiting === 1" @click="handleSubmit(1)">确定并发布</el-button>
:loading="submiting === 1"
@click="handleSubmit(1)">确定并发布</el-button>
</div> </div>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="flex-center mgb20"> <div class="flex-center mgb20">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>课程信息</span> <span>课程信息</span>
@ -33,26 +25,18 @@
<el-form label-width="80px"> <el-form label-width="80px">
<div style="display: flex"> <div style="display: flex">
<el-form-item label="项目名称"> <el-form-item label="项目名称">
<el-input :disabled="isDetail" <el-input :disabled="isDetail" v-model.trim="projectManage.projectName" placeholder="20个字符以内"
v-model.trim="projectManage.projectName"
placeholder="20个字符以内"
@blur="projectNameExistis"></el-input> @blur="projectNameExistis"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="备注"> <el-form-item label="备注">
<el-input v-model.trim="projectManage.remark" <el-input v-model.trim="projectManage.remark" placeholder="20个字符以内"></el-input>
placeholder="20个字符以内"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="项目用途"> <el-form-item label="项目用途">
<el-select :disabled="isDetail" <el-select :disabled="isDetail" v-model="projectManage.permissions" placeholder="请选择"
v-model="projectManage.permissions"
placeholder="请选择"
@change="permissionChange"> @change="permissionChange">
<el-option label="练习" <el-option label="练习" :value="0"></el-option>
:value="0"></el-option> <el-option label="考核" :value="1"></el-option>
<el-option label="考核" <el-option label="竞赛" :value="2"></el-option>
:value="1"></el-option>
<el-option label="竞赛"
:value="2"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</div> </div>
@ -60,8 +44,7 @@
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="flex-center mgb20"> <div class="flex-center mgb20">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>实验目标</span> <span>实验目标</span>
@ -70,20 +53,14 @@
<div> <div>
<el-form label-width="0"> <el-form label-width="0">
<el-form-item> <el-form-item>
<quill :border="true" <quill :border="true" :readonly="isDetail" v-model="projectManage.experimentTarget"
:readonly="isDetail" :type.sync="projectManage.experimentTargetType" radio :minHeight="150" :height="150" />
v-model="projectManage.experimentTarget"
:type.sync="projectManage.experimentTargetType"
radio
:minHeight="150"
:height="150" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="flex-center mgb20"> <div class="flex-center mgb20">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>项目背景</span> <span>项目背景</span>
@ -92,30 +69,22 @@
<div> <div>
<el-form label-width="0"> <el-form label-width="0">
<el-form-item> <el-form-item>
<quill :border="true" <quill :border="true" :readonly="isDetail" v-model="projectManage.experimentDescription"
:readonly="isDetail" :type.sync="projectManage.experimentDescriptionType" radio :minHeight="150" :height="150"
v-model="projectManage.experimentDescription"
:type.sync="projectManage.experimentDescriptionType"
radio
:minHeight="150"
:height="150"
:index="1" /> :index="1" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="flex-between mgb20"> <div class="flex-between mgb20">
<div class="flex-center"> <div class="flex-center">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>实验任务</span> <span>实验任务</span>
</div> </div>
<div> <div>
<el-button :disabled="isDetail" <el-button :disabled="isDetail" type="primary" @click="toJudgePoint('home')">进入判分点
type="primary"
@click="toJudgePoint('home')">进入判分点
</el-button> </el-button>
</div> </div>
</div> </div>
@ -123,120 +92,67 @@
<div class="mgb20 flex-between"> <div class="mgb20 flex-between">
<div class="flex-center"> <div class="flex-center">
<div class="m-r-20" <div class="m-r-20" style="color: #f00">项目总分值100</div>
style="color: #f00">项目总分值100</div>
<!-- <div>权重&emsp;<div class="dib"><el-input></el-input></div></div> --> <!-- <div>权重&emsp;<div class="dib"><el-input></el-input></div></div> -->
</div> </div>
<div> <div>
<el-button :disabled="isDetail" <el-button :disabled="isDetail" class="m-r-20" type="text" @click="avgDistributionScore">
class="m-r-20"
type="text"
@click="avgDistributionScore">
平均分配分值 平均分配分值
</el-button> </el-button>
<el-button :disabled="isDetail" <el-button :disabled="isDetail" class="m-r-20" type="text" @click="manualDistributionScore">
class="m-r-20"
type="text"
@click="manualDistributionScore">
手动分配分值 手动分配分值
</el-button> </el-button>
<span>(待分配分值: {{ handDistributionScore }}/100)</span> <span>(待分配分值: {{ handDistributionScore }}/100)</span>
</div> </div>
</div> </div>
<el-button :disabled="isDetail" <el-button :disabled="isDetail" type="primary" icon="el-icon-plus" round @click="handleAddJudgment"
type="primary"
icon="el-icon-plus"
round
@click="handleAddJudgment"
style="margin-bottom: 10px">判分点 style="margin-bottom: 10px">判分点
</el-button> </el-button>
<el-button :disabled="isDetail" <el-button :disabled="isDetail" type="primary" icon="el-icon-delete" round @click="batchDeleteProjectJudgment"
type="primary"
icon="el-icon-delete"
round
@click="batchDeleteProjectJudgment"
style="margin-bottom: 10px">批量删除 style="margin-bottom: 10px">批量删除
</el-button> </el-button>
<div class="draggable"> <div class="draggable">
<u-table ref="projectJudgementTable" <el-table ref="projectJudgementTable" :data="projectJudgmentData" class="table" stripe header-align="center"
:data="projectJudgmentData" :use-virtual="isLc" :max-height="600" :row-height="60" :border="false"
class="table" @selection-change="handleSelectionProjectJudgment" row-key="judgmentId" v-loading="listLoading">
stripe <el-table-column type="selection" width="55" align="center"></el-table-column>
header-align="center" <el-table-column prop="sort" label="序号" width="80" align="center">
:use-virtual="isLc"
:max-height="600"
:row-height="60"
:border="false"
@selection-change="handleSelectionProjectJudgment"
row-key="judgmentId"
v-loading="listLoading">
<u-table-column type="selection"
width="55"
align="center"></u-table-column>
<u-table-column prop="sort"
label="序号"
width="80"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.sort }} {{ scope.row.sort }}
</template> </template>
</u-table-column> </el-table-column>
<u-table-column prop="name" <el-table-column prop="name" label="判分指标" align="center" show-overflow-tooltip
label="判分指标" min-width="140"></el-table-column>
align="center" <el-table-column prop="name" label="判分点名称" align="center" show-overflow-tooltip
show-overflow-tooltip min-width="140"></el-table-column>
min-width="140"></u-table-column> <el-table-column label="实验要求" align="center" width="600">
<u-table-column prop="name"
label="判分点名称"
align="center"
show-overflow-tooltip
min-width="140"></u-table-column>
<u-table-column label="实验要求"
align="center"
width="600">
<template slot-scope="scope"> <template slot-scope="scope">
<quill :readonly="true" <quill :readonly="true" elseRead="true" v-model="scope.row.experimentalRequirements" :index="2" />
elseRead="true"
v-model="scope.row.experimentalRequirements"
:index="2" />
</template> </template>
</u-table-column> </el-table-column>
<u-table-column prop="score" <el-table-column prop="score" label="分数" align="center" width="120">
label="分数"
align="center"
width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input :disabled="isDetail" <el-input :disabled="isDetail" :key="scope.$index" type="number" step="0.1"
:key="scope.$index"
type="number"
step="0.1"
v-model.trim="scope.row.score"></el-input> v-model.trim="scope.row.score"></el-input>
<!-- <!--
@input="scoreChange(scope.row, scope.$index)" --> @input="scoreChange(scope.row, scope.$index)" -->
</template> </template>
</u-table-column> </el-table-column>
<u-table-column label="操作" <el-table-column label="操作" width="140" align="center">
width="140"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button :disabled="isDetail" <el-button :disabled="isDetail" type="text" style="margin-right: 10px"
type="text"
style="margin-right: 10px"
@click="toJudgePoint('edit', scope.row)">自定义</el-button> @click="toJudgePoint('edit', scope.row)">自定义</el-button>
<el-button :disabled="isDetail" <el-button :disabled="isDetail" type="text" @click="delJudgePoint(scope.$index)">
type="text"
@click="delJudgePoint(scope.$index)">
删除 删除
</el-button> </el-button>
</template> </template>
</u-table-column> </el-table-column>
</u-table> </el-table>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="flex-between mgb20"> <div class="flex-between mgb20">
<div class="flex-center"> <div class="flex-center">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
@ -244,25 +160,16 @@
</div> </div>
<div> <div>
启用 启用
<el-switch :disabled="isDetail" <el-switch :disabled="isDetail" :active-value="0" :inactive-value="1"
:active-value="0"
:inactive-value="1"
v-model="projectManage.hintOpen"></el-switch> v-model="projectManage.hintOpen"></el-switch>
</div> </div>
</div> </div>
<div class="border-b-dashed"></div> <div class="border-b-dashed"></div>
<div> <div>
<el-form label-width="0"> <el-form label-width="0">
<el-form-item prop="tips" <el-form-item prop="tips" label="">
label=""> <quill :border="true" :readonly="isDetail" v-model="projectManage.experimentHint"
<quill :border="true" :type.sync="projectManage.experimentHintType" radio :minHeight="150" :height="400" :index="3" />
:readonly="isDetail"
v-model="projectManage.experimentHint"
:type.sync="projectManage.experimentHintType"
radio
:minHeight="150"
:height="400"
:index="3" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@ -271,62 +178,34 @@
</el-row> </el-row>
<!--选择判分点对话框--> <!--选择判分点对话框-->
<el-dialog title="添加判分点" <el-dialog title="添加判分点" :visible.sync="dialogVisible" width="40%" :close-on-click-modal="false"
:visible.sync="dialogVisible"
width="40%"
:close-on-click-modal="false"
@close="closeJudgment"> @close="closeJudgment">
<div class="text-right mgb10"> <div class="text-right mgb10">
<div> <div>
<el-input placeholder="请输入需要查找的判分点" <el-input placeholder="请输入需要查找的判分点" prefix-icon="el-icon-search" v-model.trim="judgementpointsquery"
prefix-icon="el-icon-search"
v-model.trim="judgementpointsquery"
clearable></el-input> clearable></el-input>
</div> </div>
</div> </div>
<u-table v-loading="visibleLoading" <el-table v-loading="visibleLoading" :data="judgementData" ref="judgementTable" class="table" stripe
:data="judgementData" header-align="center" use-virtual :row-height="45" :max-height="400" :border="false"
ref="judgementTable" @selection-change="handleSelectionJudgment" :row-key="rowKey">
class="table" <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
stripe <el-table-column prop="id" label="序号" align="center" width="100">
header-align="center"
use-virtual
:row-height="45"
:max-height="400"
:border="false"
@selection-change="handleSelectionJudgment"
:row-key="rowKey">
<u-table-column type="selection"
width="55"
align="center"
:reserve-selection="true"></u-table-column>
<u-table-column prop="id"
label="序号"
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.$index + 1 }} {{ scope.$index + 1 }}
</template> </template>
</u-table-column> </el-table-column>
<u-table-column prop="name" <el-table-column prop="name" label="判分点名称" align="center"></el-table-column>
label="判分点名称" <el-table-column label="操作" align="center" width="100">
align="center"></u-table-column>
<u-table-column label="操作"
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="mini" <el-button size="mini" @click="toJudgePoint('view', scope.row)">查看</el-button>
@click="toJudgePoint('view', scope.row)">查看</el-button>
</template> </template>
</u-table-column> </el-table-column>
</u-table> </el-table>
<div slot="footer" <div slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="closeJudgment"> </el-button> <el-button @click="closeJudgment"> </el-button>
<el-button type="primary" <el-button type="primary" :loading="savingJud" @click="saveJudgment"> </el-button>
:loading="savingJud"
@click="saveJudgment"> </el-button>
</div> </div>
</el-dialog> </el-dialog>
</div> </div>
@ -440,6 +319,8 @@ export default {
if (this.$route.query.projectId) { if (this.$route.query.projectId) {
this.projectId = this.$route.query.projectId; this.projectId = this.$route.query.projectId;
this.getInfoData(); this.getInfoData();
} else {
this.rowDrop()
} }
// //
if (JSON.stringify(this.projectFields) != "{}") { if (JSON.stringify(this.projectFields) != "{}") {
@ -447,7 +328,6 @@ export default {
this.projectManage = projectManage; this.projectManage = projectManage;
this.projectJudgmentData = projectJudgmentData; this.projectJudgmentData = projectJudgmentData;
} }
this.rowDrop();
this.$refs.main.scrollTop = 0; this.$refs.main.scrollTop = 0;
}, },
beforeDestroy () { beforeDestroy () {
@ -482,6 +362,7 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateTime = 0 this.updateTime = 0
this.$refs.main.scrollTop = 0; this.$refs.main.scrollTop = 0;
this.rowDrop();
}); });
}).catch(err => { }).catch(err => {
this.loading = false this.loading = false
@ -785,24 +666,16 @@ export default {
// //
rowDrop () { rowDrop () {
// //
const tbody = document.querySelector(".draggable .el-table__body-wrapper tbody"); const tbody = document.querySelector(".el-table__body tbody");
const _this = this; const that = this;
Sortable.create(tbody, { this.$refs.projectJudgementTable && Sortable.create(tbody, {
// //
draggable: ".draggable .el-table__row", // draggable: ".draggable .el-table__row",
onEnd ({ newIndex, oldIndex }) { onUpdate ({ newIndex, oldIndex }) {
// : vue$nextTick console.log("🚀 ~ onEnd ~ newIndex, oldIndex:", newIndex, oldIndex)
_this.projectJudgmentData.splice(newIndex, 0, _this.projectJudgmentData.splice(oldIndex, 1)[0]); if (newIndex == oldIndex) return false
let newArray = _this.projectJudgmentData.slice(0); const currentRow = that.projectJudgmentData.splice(oldIndex, 1)[0]
_this.projectJudgmentData = []; that.projectJudgmentData.splice(newIndex, 0, currentRow)
_this.$nextTick(function () {
newArray.forEach((e, i) => {
_this.$set(e, "sort", i + 1);//
_this.$set(e, "name", e.name + "?");
_this.$set(e, "name", e.name.slice(0, e.name.length - 1)); //
});
_this.projectJudgmentData = newArray;
});
} }
}); });
}, },
@ -915,6 +788,7 @@ export default {
padding: 0; padding: 0;
border-bottom: 0; border-bottom: 0;
} }
.main { .main {
overflow: auto; overflow: auto;
overflow-x: hidden; overflow-x: hidden;

@ -13,7 +13,8 @@
<li> <li>
<label>所在国家</label> <label>所在国家</label>
<el-select size="small" v-model="form.countries"> <el-select size="small" v-model="form.countries">
<el-option v-for="item in countryList" :key="item.value" :label="item.label" :value="item.label"></el-option> <el-option v-for="item in countryList" :key="item.value" :label="item.label"
:value="item.label"></el-option>
</el-select> </el-select>
</li> </li>
</div> </div>
@ -21,7 +22,8 @@
<li> <li>
<label>性别</label> <label>性别</label>
<el-select size="small" v-model="form.sex"> <el-select size="small" v-model="form.sex">
<el-option v-for="item in sexList" :key="item.value" :label="item.name" :value="item.value"></el-option> <el-option v-for="item in sexList" :key="item.value" :label="item.name"
:value="item.value"></el-option>
</el-select> </el-select>
</li> </li>
<li class="selects"> <li class="selects">
@ -29,17 +31,21 @@
<div class="mul"> <div class="mul">
<div class="child"> <div class="child">
<el-select size="small" v-model="form.countries" placeholder> <el-select size="small" v-model="form.countries" placeholder>
<el-option v-for="item in countryList" :key="item.value" :label="item.label" :value="item.label"></el-option> <el-option v-for="item in countryList" :key="item.value" :label="item.label"
:value="item.label"></el-option>
</el-select> </el-select>
</div> </div>
<div class="child"> <div class="child">
<el-select size="small" v-model="form.provinceId" placeholder @change="id => getCity(id, 1)"> <el-select size="small" v-model="form.provinceId" placeholder @change="id => getCity(id, 1)">
<el-option v-for="item in provinceList" :key="item.provinceId" :label="item.provinceName" :value="item.provinceId"></el-option> <el-option v-for="item in provinceList" :key="item.provinceId" :label="item.provinceName"
:value="item.provinceId"></el-option>
</el-select> </el-select>
</div> </div>
<div class="child"> <div class="child">
<el-select size="small" v-model="form.cityId" placeholder :disabled="form.provinceId ? false : true"> <el-select size="small" v-model="form.cityId" placeholder
<el-option v-for="item in cityList" :key="item.cityId" :label="item.cityName" :value="item.cityId"></el-option> :disabled="form.provinceId ? false : true">
<el-option v-for="item in cityList" :key="item.cityId" :label="item.cityName"
:value="item.cityId"></el-option>
</el-select> </el-select>
</div> </div>
</div> </div>
@ -48,7 +54,8 @@
<div class="line info"> <div class="line info">
<li> <li>
<label>出生年月</label> <label>出生年月</label>
<el-date-picker size="small" placeholder="请选择时间" v-model="form.dateBirth" :clearable="false" type="date" format="yyyy-MM-dd" value-format="yyyy-MM-dd"></el-date-picker> <el-date-picker size="small" placeholder="请选择时间" v-model="form.dateBirth" :clearable="false" type="date"
format="yyyy-MM-dd" value-format="yyyy-MM-dd"></el-date-picker>
</li> </li>
<li> <li>
<label>身份证</label> <label>身份证</label>
@ -59,7 +66,8 @@
<li> <li>
<label>教育程度</label> <label>教育程度</label>
<el-select size="small" v-model="form.educationDegree" placeholder="请选择教育程度"> <el-select size="small" v-model="form.educationDegree" placeholder="请选择教育程度">
<el-option v-for="(item,index) in educationDegreeList" :key="index" :label="item.name" :value="item.value"></el-option> <el-option v-for="(item, index) in educationDegreeList" :key="index" :label="item.name"
:value="item.value"></el-option>
</el-select> </el-select>
</li> </li>
</div> </div>
@ -76,41 +84,52 @@
<li> <li>
<label>职业</label> <label>职业</label>
<el-select size="small" v-model="archive.personalCareerId" placeholder="选择职业"> <el-select size="small" v-model="archive.personalCareerId" placeholder="选择职业">
<el-option v-for="item in occupationList" :key="item.value" :label="item.label" :value="item.value"></el-option> <el-option v-for="item in occupationList" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select> </el-select>
</li> </li>
<li> <li>
<label>所在国家</label> <label>所在国家</label>
<el-select size="small" v-model="form.countries" placeholder> <el-select size="small" v-model="form.countries" placeholder>
<el-option v-for="item in countryList" :key="item.value" :label="item.label" :value="item.label" ></el-option> <el-option v-for="item in countryList" :key="item.value" :label="item.label"
:value="item.label"></el-option>
</el-select> </el-select>
</li> </li>
</div> </div>
<div class="line"> <div class="line">
<li> <li>
<label>学校名称</label> <label>学校名称</label>
<el-select size="small" v-model="archive.schoolId" filterable placeholder="选择学校" @change="id => getSchoolName(id,index)"> <el-select size="small" v-model="archive.schoolId" filterable placeholder="选择学校"
<el-option v-for="item in schoolList" :key="item.value" :label="item.schoolName" :value="item.schoolId"></el-option> @change="id => getSchoolName(id, index)">
<el-option v-for="item in schoolList" :key="item.value" :label="item.schoolName"
:value="item.schoolId"></el-option>
</el-select> </el-select>
</li> </li>
<li> <li>
<label>专业学科</label> <label>专业学科</label>
<el-select size="small" v-model="archive.disciplineId" placeholder="选择专业学科" @change="id => getItemProfessionalClass(id,index)" @clear="() => clearItemClass(index)"> <el-select size="small" v-model="archive.disciplineId" placeholder="选择专业学科"
<el-option v-for="item in subjectList" :key="item.value" :label="item.disciplineName" :value="item.disciplineId"></el-option> @change="id => getItemProfessionalClass(id, index)" @clear="() => clearItemClass(index)">
<el-option v-for="item in subjectList" :key="item.value" :label="item.disciplineName"
:value="item.disciplineId"></el-option>
</el-select> </el-select>
</li> </li>
</div> </div>
<div class="line" style="margin-bottom: 0"> <div class="line" style="margin-bottom: 0">
<li> <li>
<label>专业类</label> <label>专业类</label>
<el-select size="small" v-model="archive.professionalClassId" placeholder="选择专业类" :disabled="archive.disciplineId ? false : true" @change="id => getItemProfessional(id,index)" @clear="() => clearItemProfess(index)"> <el-select size="small" v-model="archive.professionalClassId" placeholder="选择专业类"
<el-option v-for="item in archive.ProfessionalClassList" :key="item.professionalClassId" :label="item.professionalClassName" :value="item.professionalClassId"></el-option> :disabled="archive.disciplineId ? false : true" @change="id => getItemProfessional(id, index)"
@clear="() => clearItemProfess(index)">
<el-option v-for="item in archive.ProfessionalClassList" :key="item.professionalClassId"
:label="item.professionalClassName" :value="item.professionalClassId"></el-option>
</el-select> </el-select>
</li> </li>
<li> <li>
<label>专业</label> <label>专业</label>
<el-select size="small" v-model="archive.professionalId" placeholder="选择专业" :disabled="archive.professionalClassId ? false : true" @change="getItemStuGrade"> <el-select size="small" v-model="archive.professionalId" placeholder="选择专业"
<el-option v-for="item in archive.ProfessionalList" :key="item.professionalId" :label="item.professionalName" :value="item.professionalId"></el-option> :disabled="archive.professionalClassId ? false : true" @change="getItemStuGrade">
<el-option v-for="item in archive.ProfessionalList" :key="item.professionalId"
:label="item.professionalName" :value="item.professionalId"></el-option>
</el-select> </el-select>
</li> </li>
</div> </div>
@ -163,7 +182,8 @@
<el-button type="primary" size="small" @click="save">更新</el-button> <el-button type="primary" size="small" @click="save">更新</el-button>
</div> </div>
<el-dialog :title="form.email ? '更换邮箱' : '绑定邮箱'" :visible.sync="emailVisible" :close-on-click-modal="false" @close="closeEmail" width="30%"> <el-dialog :title="form.email ? '更换邮箱' : '绑定邮箱'" :visible.sync="emailVisible" :close-on-click-modal="false"
@close="closeEmail" width="30%">
<el-form ref="form" :model="form" label-width="60px"> <el-form ref="form" :model="form" label-width="60px">
<el-form-item label="邮箱"> <el-form-item label="邮箱">
<el-input style="width: 394px;" placeholder="请输入邮箱" v-model="email"></el-input> <el-input style="width: 394px;" placeholder="请输入邮箱" v-model="email"></el-input>
@ -171,7 +191,8 @@
<el-form-item label="验证码"> <el-form-item label="验证码">
<div class="flex"> <div class="flex">
<el-input v-model="emailCode" placeholder="请输入验证码" maxlength="6"></el-input> <el-input v-model="emailCode" placeholder="请输入验证码" maxlength="6"></el-input>
<el-button style="margin-left: 10px" type="text" @click="sendEmailCode" :disabled="emailDisabled">{{emailBtnText}}</el-button> <el-button style="margin-left: 10px" type="text" @click="sendEmailCode" :disabled="emailDisabled">{{
emailBtnText }}</el-button>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -181,7 +202,8 @@
</span> </span>
</el-dialog> </el-dialog>
<el-dialog :title="form.phone ? '更换手机号' : '绑定手机号'" :visible.sync="phoneVisible" :close-on-click-modal="false" @close="closePhone" width="30%"> <el-dialog :title="form.phone ? '更换手机号' : '绑定手机号'" :visible.sync="phoneVisible" :close-on-click-modal="false"
@close="closePhone" width="30%">
<el-form ref="form" :model="form" label-width="60px"> <el-form ref="form" :model="form" label-width="60px">
<el-form-item label="手机号"> <el-form-item label="手机号">
<el-input style="width: 404px;" placeholder="请输入手机号" v-model="phone" maxlength="11"></el-input> <el-input style="width: 404px;" placeholder="请输入手机号" v-model="phone" maxlength="11"></el-input>
@ -189,7 +211,8 @@
<el-form-item label="验证码"> <el-form-item label="验证码">
<div class="flex"> <div class="flex">
<el-input v-model="phoneCode" placeholder="请输入验证码" maxlength="6"></el-input> <el-input v-model="phoneCode" placeholder="请输入验证码" maxlength="6"></el-input>
<el-button style="margin-left: 10px" type="text" @click="sendPhoneCode" :disabled="phoneDisabled">{{phoneBtnText}}</el-button> <el-button style="margin-left: 10px" type="text" @click="sendPhoneCode" :disabled="phoneDisabled">{{
phoneBtnText }}</el-button>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -199,16 +222,19 @@
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="更换密码" :visible.sync="passwordVisible" :close-on-click-modal="false" @close="closePassword" width="30%"> <el-dialog title="更换密码" :visible.sync="passwordVisible" :close-on-click-modal="false" @close="closePassword"
width="30%">
<el-form ref="passwordForm" :model="form" label-width="82px"> <el-form ref="passwordForm" :model="form" label-width="82px">
<el-form-item label="原密码"> <el-form-item label="原密码">
<el-input type="password" v-model="passwordForm.password" placeholder="请输入原密码"></el-input> <el-input type="password" v-model="passwordForm.password" placeholder="请输入原密码"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="新密码"> <el-form-item label="新密码">
<el-input type="password" v-model="passwordForm.newPassword" placeholder="请输入新密码" @keyup.enter.native="editPassword"></el-input> <el-input type="password" v-model="passwordForm.newPassword" placeholder="请输入新密码"
@keyup.enter.native="editPassword"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="确认新密码"> <el-form-item label="确认新密码">
<el-input type="password" v-model="passwordForm.reNewPassword" placeholder="请确认新密码" @keyup.enter.native="editPassword"></el-input> <el-input type="password" v-model="passwordForm.reNewPassword" placeholder="请确认新密码"
@keyup.enter.native="editPassword"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
@ -835,37 +861,46 @@ export default {
.flex { .flex {
display: flex; display: flex;
} }
.m-r-10 { .m-r-10 {
margin-right: 10px; margin-right: 10px;
} }
.l-title { .l-title {
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 12px; margin-bottom: 12px;
font-size: 14px; font-size: 14px;
color: #333; color: #333;
img { img {
margin-right: 5px; margin-right: 5px;
} }
} }
.scroll { .scroll {
max-height: calc(100vh - 218px); max-height: calc(100vh - 218px);
overflow: auto; overflow: auto;
} }
.page { .page {
margin-bottom: 12px; margin-bottom: 12px;
/deep/.el-input__inner { /deep/.el-input__inner {
border-color: #CACFDB; border-color: #CACFDB;
} }
.list { .list {
.line { .line {
display: flex; display: flex;
margin-bottom: 24px; margin-bottom: 24px;
&.info li:not(.selects) { &.info li:not(.selects) {
.el-input { .el-input {
flex: 1; flex: 1;
} }
} }
&.imp li { &.imp li {
&:nth-child(odd) { &:nth-child(odd) {
width: 360px; width: 360px;
@ -873,15 +908,20 @@ export default {
} }
} }
} }
.el-input, .el-select{
.el-input,
.el-select {
width: 220px; width: 220px;
.el-input__inner { .el-input__inner {
border-color: #CACFDB; border-color: #CACFDB;
} }
} }
li { li {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
&>label { &>label {
width: 100px; width: 100px;
margin-right: 5px; margin-right: 5px;
@ -889,23 +929,29 @@ export default {
font-size: 14px; font-size: 14px;
color: #4c4c4c; color: #4c4c4c;
} }
.el-select { .el-select {
flex: 1; flex: 1;
} }
.el-select .el-input.is-disabled .el-input__inner { .el-select .el-input.is-disabled .el-input__inner {
border-color: #ddd; border-color: #ddd;
} }
.val { .val {
margin-right: 15px; margin-right: 15px;
color: #606266; color: #606266;
font-size: 14px; font-size: 14px;
} }
.mul { .mul {
display: inline-flex; display: inline-flex;
.child { .child {
display: inline-flex; display: inline-flex;
width: 132px; width: 132px;
margin-right: 10px; margin-right: 10px;
&>span { &>span {
margin-bottom: 5px; margin-bottom: 5px;
font-size: 14px; font-size: 14px;
@ -913,12 +959,14 @@ export default {
} }
} }
} }
&:nth-child(odd) { &:nth-child(odd) {
width: 325px; width: 325px;
margin-right: 100px; margin-right: 100px;
} }
} }
} }
.archives { .archives {
position: relative; position: relative;
width: 862px; width: 862px;
@ -926,6 +974,7 @@ export default {
margin-bottom: 6px; margin-bottom: 6px;
border-radius: 4px; border-radius: 4px;
background-color: #FAFAFA; background-color: #FAFAFA;
.del { .del {
position: absolute; position: absolute;
top: 80px; top: 80px;
@ -933,28 +982,34 @@ export default {
cursor: pointer; cursor: pointer;
} }
} }
.fold { .fold {
margin-top: 20px; margin-top: 20px;
text-align: center; text-align: center;
font-size: 12px; font-size: 12px;
color: #006EFF; color: #006EFF;
span { span {
cursor: pointer; cursor: pointer;
i { i {
transition: .5s; transition: .5s;
} }
&.active i { &.active i {
transform: rotate(180deg); transform: rotate(180deg);
} }
} }
} }
} }
.btns { .btns {
width: 100%; width: 100%;
padding: 12px 0; padding: 12px 0;
text-align: center; text-align: center;
background-color: #fff; background-color: #fff;
box-shadow: 0px 0px 10px 0px rgba(188, 201, 218, 0.4); box-shadow: 0px 0px 10px 0px rgba(188, 201, 218, 0.4);
.el-button { .el-button {
width: 80px; width: 80px;
} }

File diff suppressed because it is too large Load Diff

@ -4,8 +4,7 @@
<div class="side"> <div class="side">
<div class="m-b-20"> <div class="m-b-20">
<h6 class="p-title">后台员工账号</h6> <h6 class="p-title">后台员工账号</h6>
<el-radio-group v-model="studentType" <el-radio-group v-model="studentType" @change="changeType">
@change="changeType">
<div class="m-b-20"> <div class="m-b-20">
<el-radio :label="1">所有员工</el-radio> <el-radio :label="1">所有员工</el-radio>
</div> </div>
@ -17,39 +16,24 @@
<el-divider></el-divider> <el-divider></el-divider>
<div> <div>
<div class="flex-between"> <div class="flex-between">
<h6 class="p-title" <h6 class="p-title" style="margin-bottom: 0">组织架构</h6>
style="margin-bottom: 0">组织架构</h6> <el-button type="text" @click="addOrg" v-auth="'/system:后台账号:新增部门'">添加</el-button>
<el-button type="text"
@click="addOrg"
v-auth="'/system:后台账号:新增部门'">添加</el-button>
</div> </div>
<div style="overflow: auto"> <div style="overflow: auto">
<el-tree :data="orgList" <el-tree :data="orgList" default-expand-all ref="orgTree" node-key="id" highlight-current
default-expand-all :expand-on-click-node="false" @node-click="handleNodeClick"
ref="orgTree"
node-key="id"
highlight-current
:expand-on-click-node="false"
@node-click="handleNodeClick"
:props="{ children: 'children', label: 'organizationName', isLeaf: 'leaf' }"> :props="{ children: 'children', label: 'organizationName', isLeaf: 'leaf' }">
<span class="custom-tree-node" <span class="custom-tree-node" slot-scope="{ node, data }">
slot-scope="{ node, data }">
<span class="org-name">{{ node.label }}</span> <span class="org-name">{{ node.label }}</span>
<span> <span>
<el-button v-auth="'/system:后台账号:新增部门'" <el-button v-auth="'/system:后台账号:新增部门'" type="text" icon="el-icon-circle-plus-outline"
type="text"
icon="el-icon-circle-plus-outline"
@click="() => addOrg(node, data)"> @click="() => addOrg(node, data)">
</el-button> </el-button>
<el-button v-auth="'/system:后台账号:编辑部门'" <el-button v-auth="'/system:后台账号:编辑部门'" type="text" icon="el-icon-edit-outline"
type="text"
icon="el-icon-edit-outline"
@click="() => editOrg(node, data)"> @click="() => editOrg(node, data)">
</el-button> </el-button>
<el-button v-auth="'/system:后台账号:删除部门'" <el-button v-auth="'/system:后台账号:删除部门'" type="text" icon="el-icon-delete"
type="text"
icon="el-icon-delete"
@click="() => delOrg(node, data)"> @click="() => delOrg(node, data)">
</el-button> </el-button>
</span> </span>
@ -58,36 +42,22 @@
</div> </div>
</div> </div>
<el-dialog :title="orgForm.id ? '编辑' : '新增' + '部门'" <el-dialog :title="orgForm.id ? '编辑' : '新增' + '部门'" :visible.sync="orgVisible" :close-on-click-modal="false"
:visible.sync="orgVisible"
:close-on-click-modal="false"
width="50%"> width="50%">
<el-form v-if="orgVisible" <el-form v-if="orgVisible" ref="orgForm" :model="orgForm" :rules="orgRules" label-width="100px">
ref="orgForm" <el-form-item label="部门名称" prop="organizationName">
:model="orgForm" <el-input v-model.trim="orgForm.organizationName" placeholder="请输入"></el-input>
:rules="orgRules"
label-width="100px">
<el-form-item label="部门名称"
prop="organizationName">
<el-input v-model.trim="orgForm.organizationName"
placeholder="请输入"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="上级部门"> <el-form-item label="上级部门">
<span v-if="orgForm.parentName">{{ orgForm.parentName }}</span> <span v-if="orgForm.parentName">{{ orgForm.parentName }}</span>
<el-cascader v-else <el-cascader v-else :options="orgListDia" v-model="cascaderValue" :props="cascaderProps" clearable
:options="orgListDia"
v-model="cascaderValue"
:props="cascaderProps"
clearable
style="width: 100%"> style="width: 100%">
</el-cascader> </el-cascader>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="closeOrg"> </el-button> <el-button @click="closeOrg"> </el-button>
<el-button type="primary" <el-button type="primary" @click="orgSubmit"> </el-button>
@click="orgSubmit"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
@ -97,195 +67,96 @@
<div class="tool"> <div class="tool">
<ul class="filter"> <ul class="filter">
<li> <li>
<el-input style="width: 250px;" <el-input style="width: 250px;" placeholder="请输入员工姓名/手机号" prefix-icon="el-icon-search" v-model="keyWord"
placeholder="请输入员工姓名/手机号"
prefix-icon="el-icon-search"
v-model="keyWord"
clearable></el-input> clearable></el-input>
</li> </li>
</ul> </ul>
<div> <div>
<el-button type="primary" <el-button type="primary" @click="addStaff" v-auth="'/system:后台账号:新增员工'">新增员工</el-button>
@click="addStaff" <el-button type="primary" @click="batchImport" v-auth="'/system:后台账号:批量导入'">批量导入</el-button>
v-auth="'/system:后台账号:新增员工'">新增员工</el-button>
<el-button type="primary"
@click="batchImport"
v-auth="'/system:后台账号:批量导入'">批量导入</el-button>
</div> </div>
</div> </div>
<el-table :data="listData" <el-table :data="listData" class="table" ref="table" stripe header-align="center"
class="table" @selection-change="handleSelectionChange" row-key="accountId">
ref="table" <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
stripe <el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
header-align="center" <el-table-column prop="userName" label="员工姓名" align="center" min-width="100"></el-table-column>
@selection-change="handleSelectionChange" <el-table-column prop="account" label="账号" align="center" min-width="100"></el-table-column>
row-key="accountId"> <el-table-column prop="phone" label="手机号" align="center" width="120"></el-table-column>
<el-table-column type="selection" <el-table-column prop="staffArchitectureName" label="所在部门" align="center" min-width="200"
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="userName"
label="员工姓名"
align="center"
min-width="100"></el-table-column>
<el-table-column prop="account"
label="账号"
align="center"
min-width="100"></el-table-column>
<el-table-column prop="phone"
label="手机号"
align="center"
width="120"></el-table-column>
<el-table-column prop="staffArchitectureName"
label="所在部门"
align="center"
min-width="200"
show-overflow-tooltip></el-table-column> show-overflow-tooltip></el-table-column>
<el-table-column prop="roleName" <el-table-column prop="roleName" label="授权角色" align="center" min-width="200"
label="授权角色"
align="center"
min-width="200"
show-overflow-tooltip></el-table-column> show-overflow-tooltip></el-table-column>
<el-table-column prop="lastLoginTime" <el-table-column prop="lastLoginTime" label="最后登录时间" align="center" width="130"></el-table-column>
label="最后登录时间" <el-table-column label="操作" align="center" width="300">
align="center"
width="130"></el-table-column>
<el-table-column label="操作"
align="center"
width="300">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" <el-button type="text" v-auth="'/system:后台账号:查看'" @click="queryStaff(scope.row, true)">查看</el-button>
v-auth="'/system:后台账号:查看'" <el-button type="text" v-auth="'/system:后台账号:编辑'" @click="queryStaff(scope.row, false)">编辑</el-button>
@click="queryStaff(scope.row,true)">查看</el-button> <el-button type="text" v-auth="'/system:后台账号:重置密码'" @click="resetPassword(scope.row)">重置密码</el-button>
<el-button type="text" <el-button type="text" v-auth="'/system:后台账号:删除'" @click="delStaff(scope.row)">删除</el-button>
v-auth="'/system:后台账号:编辑'"
@click="queryStaff(scope.row,false)">编辑</el-button>
<el-button type="text"
v-auth="'/system:后台账号:重置密码'"
@click="resetPassword(scope.row)">重置密码</el-button>
<el-button type="text"
v-auth="'/system:后台账号:删除'"
@click="delStaff(scope.row)">删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background <el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next"
@current-change="currentChange"
:current-page="page"
layout="total, prev, pager, next"
:total="total"></el-pagination> :total="total"></el-pagination>
</div> </div>
<el-dialog :title="isDetail ? '查看' : (form.accountId ? '编辑' : '新增') + '员工'" <el-dialog :title="isDetail ? '查看' : (form.accountId ? '编辑' : '新增') + '员工'" :visible.sync="staffVisible"
:visible.sync="staffVisible" width="580px" class="dialog" :close-on-click-modal="false" @close="closeStaff">
width="580px" <el-form ref="form" :model="form" :rules="rules" label-width="150px" :disabled="isDetail"
class="dialog"
:close-on-click-modal="false"
@close="closeStaff">
<el-form ref="form"
:model="form"
:rules="rules"
label-width="150px"
:disabled="isDetail"
style='margin-right: 80px;'> style='margin-right: 80px;'>
<el-form-item prop="workNumber" <el-form-item prop="workNumber" label="工号">
label="工号"> <el-input v-model.trim="form.workNumber" placeholder="请输入工号"></el-input>
<el-input v-model.trim="form.workNumber"
placeholder="请输入工号"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="userName" <el-form-item prop="userName" label="姓名">
label="姓名"> <el-input v-model.trim="form.userName" placeholder="请输入姓名"></el-input>
<el-input v-model.trim="form.userName"
placeholder="请输入姓名"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="account" <el-form-item prop="account" label="账号">
label="账号"> <el-input v-model.trim="form.account" placeholder="请输入账号"></el-input>
<el-input v-model.trim="form.account"
placeholder="请输入账号"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="roleList" <el-form-item prop="roleList" label="授权角色">
label="授权角色"> <el-select class="w-100" v-model="form.roleList" multiple>
<el-select class="w-100"
v-model="form.roleList"
multiple>
<template v-for="item in roleList"> <template v-for="item in roleList">
<!-- 不显示超管 --> <!-- 不显示超管 -->
<el-option v-if="item.roleName !== '超级管理员'" <el-option v-if="item.roleName !== '超级管理员'" :key="item.id" :label="item.roleName" :value="item.id">
:key="item.id"
:label="item.roleName"
:value="item.id">
</el-option> </el-option>
</template> </template>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="所在部门"> <el-form-item label="所在部门">
<el-cascader class="w-100" <el-cascader class="w-100" v-model="form.staffArchitectureId" :options="orgList"
v-model="form.staffArchitectureId"
:options="orgList"
:props="casProps"></el-cascader> :props="casProps"></el-cascader>
</el-form-item> </el-form-item>
<el-form-item prop="phone" <el-form-item prop="phone" label="手机号">
label="手机号"> <el-input v-model.trim="form.phone" placeholder="请输入手机号" maxlength="11"></el-input>
<el-input v-model.trim="form.phone"
placeholder="请输入手机号"
maxlength="11"></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="email" <el-form-item prop="email" label="邮箱">
label="邮箱"> <el-input v-model.trim="form.email" placeholder="请输入邮箱"></el-input>
<el-input v-model.trim="form.email"
placeholder="请输入邮箱"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
<span slot="footer" <span slot="footer" class="dialog-footer" v-if="!isDetail">
class="dialog-footer"
v-if="!isDetail">
<el-button @click="staffVisible = false">取消</el-button> <el-button @click="staffVisible = false">取消</el-button>
<el-button type="primary" <el-button type="primary" @click="submitStaff">确定</el-button>
@click="submitStaff">确定</el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="批量导入" <el-dialog title="批量导入" :visible.sync="importVisible" width="24%" :close-on-click-modal="false">
:visible.sync="importVisible"
width="24%"
:close-on-click-modal="false">
<div style="text-align: center"> <div style="text-align: center">
<div style="margin-bottom: 10px;"> <div style="margin-bottom: 10px;">
<el-button type="primary" <el-button type="primary" @click="download">模板下载<i class="el-icon-download el-icon--right"></i></el-button>
@click="download">模板下载<i class="el-icon-download el-icon--right"></i></el-button>
</div> </div>
<el-upload ref="importStaff" <el-upload ref="importStaff" name="file" accept=".xls,.xlsx" :on-remove="handleRemove" :on-error="uploadError"
name="file" :on-success="uploadSuccess" :before-remove="beforeRemove" :limit="1" :on-exceed="handleExceed"
accept=".xls,.xlsx" :action="this.api.importStaff" :file-list="uploadList" :headers="headers">
:on-remove="handleRemove" <el-button type="primary" class="ml20">上传文件<i class="el-icon-upload2 el-icon--right"></i></el-button>
:on-error="uploadError"
:on-success="uploadSuccess"
:before-remove="beforeRemove"
:limit="1"
:on-exceed="handleExceed"
:action="this.api.importStaff"
:file-list="uploadList"
:headers="headers">
<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" <el-link v-if="uploadFaild" type="primary" @click="showFaild">部分数据导入失败查看失败原因</el-link>
type="primary"
@click="showFaild">部分数据导入失败查看失败原因</el-link>
</div> </div>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer"> <el-button size="small" @click="importVisible = false"> </el-button>
<el-button size="small" <el-button size="small" type="primary" @click="uploadSure"> </el-button>
@click="importVisible = false"> </el-button>
<el-button size="small"
type="primary"
@click="uploadSure"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
@ -870,22 +741,27 @@ export default {
.m-b-20 { .m-b-20 {
margin-bottom: 20px; margin-bottom: 20px;
} }
.org-name { .org-name {
margin-right: 20px; margin-right: 20px;
} }
.w-100 { .w-100 {
width: 100%; width: 100%;
} }
.wrap { .wrap {
display: flex; display: flex;
min-height: 100%; min-height: 100%;
padding: 0 24px; padding: 0 24px;
.side { .side {
width: 300px; width: 300px;
padding: 24px 10px 24px 0; padding: 24px 10px 24px 0;
margin-right: 24px; margin-right: 24px;
border-right: 1px solid rgba(0, 0, 0, 0.06); border-right: 1px solid rgba(0, 0, 0, 0.06);
} }
.right { .right {
width: calc(100% - 374px); width: calc(100% - 374px);
padding: 24px 0; padding: 24px 0;

@ -705,7 +705,7 @@ export default {
// //
if (row.fileId) { if (row.fileId) {
this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => { this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => {
this.playAuth = res.data.playAuth; this.playAuth = res.playAuth;
if (this.player) { if (this.player) {
this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth); this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth);
} else { } else {

@ -2,161 +2,87 @@
<!-- 平台自建 --> <!-- 平台自建 -->
<div style="padding-top: 24px"> <div style="padding-top: 24px">
<div class="tool"> <div class="tool">
<ul class="filter" <ul class="filter" style="align-items: flex-start">
style="align-items: flex-start">
<li> <li>
<label>可见范围</label> <label>可见范围</label>
<el-select v-model="form.visibleRange" <el-select v-model="form.visibleRange" clearable placeholder="请选择可见范围" @change="getData">
clearable <el-option v-for="(item, index) in regions" :key="index" :label="item.name" :value="item.id"></el-option>
placeholder="请选择可见范围"
@change="getData">
<el-option v-for="(item,index) in regions"
:key="index"
:label="item.name"
:value="item.id"></el-option>
</el-select> </el-select>
</li> </li>
<li> <li>
<label>课程分类</label> <label>课程分类</label>
<el-select v-model="form.categoryId" <el-select v-model="form.categoryId" clearable placeholder="请选择课程分类" @change="getData">
clearable <el-option label="不限" value=""></el-option>
placeholder="请选择课程分类" <el-option label="暂无分类" value="0"></el-option>
@change="getData"> <el-option v-for="(item, index) in classificationList" :key="index" :label="item.classificationName"
<el-option label="不限"
value=""></el-option>
<el-option label="暂无分类"
value="0"></el-option>
<el-option v-for="(item,index) in classificationList"
:key="index"
:label="item.classificationName"
:value="item.id"></el-option> :value="item.id"></el-option>
</el-select> </el-select>
</li> </li>
<li> <li>
<label>课程类型</label> <label>课程类型</label>
<el-select v-model="form.courseType" <el-select v-model="form.courseType" clearable placeholder="请选择课程类型" @change="getData">
clearable <el-option v-for="(item, index) in types" :key="index" :label="item.name" :value="item.id"></el-option>
placeholder="请选择课程类型"
@change="getData">
<el-option v-for="(item,index) in types"
:key="index"
:label="item.name"
:value="item.id"></el-option>
</el-select> </el-select>
</li> </li>
<li> <li>
<label>搜索</label> <label>搜索</label>
<el-input placeholder="请输入理论课程名称/创建人" <el-input placeholder="请输入理论课程名称/创建人" suffix-icon="el-icon-search" v-model="form.keyWord" clearable
suffix-icon="el-icon-search"
v-model="form.keyWord"
clearable
size="small"></el-input> size="small"></el-input>
</li> </li>
</ul> </ul>
<div> <div>
<el-button v-auth="'平台自建:新增'" <el-button v-auth="'平台自建:新增'" type="primary" round @click="addCourse">新增</el-button>
type="primary" <el-button v-auth="'平台自建:批量删除'" type="primary" round @click="delAllData">批量删除</el-button>
round
@click="addCourse">新增</el-button>
<el-button v-auth="'平台自建:批量删除'"
type="primary"
round
@click="delAllData">批量删除</el-button>
</div> </div>
</div> </div>
<el-table :data="list" <el-table :data="list" class="table" ref="table" stripe header-align="center"
class="table" @selection-change="handleSelectionChange" row-key="id">
ref="table" <el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
stripe <el-table-column type="index" width="100" label="序号" align="center">
header-align="center"
@selection-change="handleSelectionChange"
row-key="id">
<el-table-column type="selection"
width="80"
align="center"
:reserve-selection="true"></el-table-column>
<el-table-column type="index"
width="100"
label="序号"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.$index + (page - 1) * pageSize + 1 }} {{ scope.$index + (page - 1) * pageSize + 1 }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="courseName" <el-table-column prop="courseName" label="课程名称" align="center">
label="课程名称"
align="center">
</el-table-column> </el-table-column>
<el-table-column label="可见范围" <el-table-column label="可见范围" align="center">
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ regionName[scope.row.visibleRange] }} {{ regionName[scope.row.visibleRange] }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" <el-table-column prop="createTime" label="创建时间" align="center">
label="创建时间"
align="center">
</el-table-column> </el-table-column>
<el-table-column prop="courseClassification" <el-table-column prop="courseClassification" label="课程类型" align="center">
label="课程类型"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.courseType == 1 ? '付费' : '免费' }} {{ scope.row.courseType == 1 ? '付费' : '免费' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="founder" <el-table-column prop="founder" label="创建人" align="center">
label="创建人"
align="center">
</el-table-column> </el-table-column>
<el-table-column prop="courseClassification" <el-table-column prop="courseClassification" label="课程分类" align="center" show-overflow-tooltip>
label="课程分类"
align="center"
show-overflow-tooltip>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" align="center" width="250">
align="center"
width="250">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button v-auth="'平台自建:编辑信息'" <el-button v-auth="'平台自建:编辑信息'" type="text" @click="editCourse(scope.row)">编辑信息</el-button>
type="text" <el-divider v-auth="'平台自建:编辑信息'" direction="vertical"></el-divider>
@click="editCourse(scope.row)">编辑信息</el-button> <el-button v-auth="'平台自建:内容设置'" type="text" @click="config(scope.row)">内容设置</el-button>
<el-divider v-auth="'平台自建:编辑信息'" <el-divider v-auth="'平台自建:内容设置'" direction="vertical"></el-divider>
direction="vertical"></el-divider> <el-button v-auth="'平台自建:预览'" type="text" @click="preview(scope.row)">预览</el-button>
<el-button v-auth="'平台自建:内容设置'" <el-divider v-auth="'平台自建:预览'" direction="vertical"></el-divider>
type="text" <el-button v-auth="'平台自建:删除'" type="text" @click="handleDelete(scope.row)">删除</el-button>
@click="config(scope.row)">内容设置</el-button>
<el-divider v-auth="'平台自建:内容设置'"
direction="vertical"></el-divider>
<el-button v-auth="'平台自建:预览'"
type="text"
@click="preview(scope.row)">预览</el-button>
<el-divider v-auth="'平台自建:预览'"
direction="vertical"></el-divider>
<el-button v-auth="'平台自建:删除'"
type="text"
@click="handleDelete(scope.row)">删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="可授权状态" <el-table-column label="可授权状态" align="center" width="120">
align="center"
width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch v-auth="'平台自建:禁用'" <el-switch v-auth="'平台自建:禁用'" v-model="scope.row.ztOpen" :active-value="0" :inactive-value="1"
v-model="scope.row.ztOpen" style="margin: 0 10px 0 5px" :active-text="scope.row.ztOpen ? '关' : '开'"
:active-value="0"
:inactive-value="1"
style="margin: 0 10px 0 5px"
:active-text="scope.row.ztOpen ? '关' : '开'"
@change="switchOff($event, scope.row, scope.$index)"></el-switch> @change="switchOff($event, scope.row, scope.$index)"></el-switch>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background <el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange"
layout="total, prev, pager, next"
:total="total"
@current-change="handleCurrentChange"
:current-page="page"> :current-page="page">
</el-pagination> </el-pagination>
</div> </div>

@ -2,11 +2,8 @@
<!-- 理论课程管理 --> <!-- 理论课程管理 -->
<div class="page"> <div class="page">
<div class="tabs"> <div class="tabs">
<a class="item" <a class="item" v-for="(item, i) in tabs" :key="i" :class="{ active: i == active }" @click="tabChange(i)">{{ item
v-for="(item, i) in tabs" }}</a>
:key="i"
:class="{active: i == active}"
@click="tabChange(i)">{{ item }}</a>
</div> </div>
<div class="page-content"> <div class="page-content">
<!-- 平台自建 --> <!-- 平台自建 -->
@ -61,5 +58,4 @@ export default {
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped></style>
</style>

@ -1,78 +1,46 @@
<template> <template>
<!-- 课程预览 --> <!-- 课程预览 -->
<div class="wrap"> <div class="wrap">
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<div class="flex-between"> <div class="flex-between">
<el-page-header @back="back" <el-page-header @back="back" :content="'课程预览'"></el-page-header>
:content="'课程预览'"></el-page-header>
</div> </div>
</el-card> </el-card>
<div class="flex"> <div class="flex">
<div class="cover" <div class="cover" :class="{ 'is-word': showMask1 }">
:class="{'is-word': showMask1}"> <img v-if="coverUrl" :src="coverUrl" alt="" width="100%" height="100%">
<img v-if="coverUrl"
:src="coverUrl"
alt=""
width="100%"
height="100%">
<template v-else-if="iframeSrc"> <template v-else-if="iframeSrc">
<iframe class="inner fileIframe" <iframe class="inner fileIframe" id="fileIframe" :src="iframeSrc" frameborder="0"></iframe>
id="fileIframe"
:src="iframeSrc"
frameborder="0"></iframe>
<template v-if="showMask"> <template v-if="showMask">
<div class="mask" <div class="mask" style="width: 500px;height: 30px;top: 53px;right: 320px"></div>
style="width: 500px;height: 30px;top: 53px;right: 320px"></div> <div class="mask" style="width: 175px;height: 30px;top: 53px;right: 5px"></div>
<div class="mask"
style="width: 175px;height: 30px;top: 53px;right: 5px"></div>
</template> </template>
<template v-if="showMask1"> <template v-if="showMask1">
<div class="word-mask" <div class="word-mask" style="height: 40px;"></div>
style="height: 40px;"></div> <div class="word-mask2" style="top: 55px;left: 28%;width: 44%;height: calc(100% - 80px);"></div>
<div class="word-mask2"
style="top: 55px;left: 28%;width: 44%;height: calc(100% - 80px);"></div>
</template> </template>
<template v-if="showMask2"> <template v-if="showMask2">
<div class="excel-mask1" <div class="excel-mask1" style="height: 48px;"></div>
style="height: 48px;"></div>
</template> </template>
</template> </template>
<div class="pdf inner" <div class="pdf inner" v-else-if="pdfSrc">
v-else-if="pdfSrc">
<p class="arrow"> <p class="arrow">
<span @click="changePdfPage(0)" <span @click="changePdfPage(0)" class="turn el-icon-arrow-left" :class="{ grey: currentPage == 1 }"></span>
class="turn el-icon-arrow-left"
:class="{grey: currentPage==1}"></span>
{{ currentPage }} / {{ pageCount }} {{ currentPage }} / {{ pageCount }}
<span @click="changePdfPage(1)" <span @click="changePdfPage(1)" class="turn el-icon-arrow-right"
class="turn el-icon-arrow-right"
:class="{ grey: currentPage == pageCount }"></span> :class="{ grey: currentPage == pageCount }"></span>
</p> </p>
<pdf class="pdf-wrap" <pdf class="pdf-wrap" :src="pdfSrc" :page="currentPage" @num-pages="pageCount = $event"
:src="pdfSrc" @page-loaded="currentPage = $event" @loaded="loadPdfHandler">
:page="currentPage"
@num-pages="pageCount=$event"
@page-loaded="currentPage=$event"
@loaded="loadPdfHandler">
</pdf> </pdf>
</div> </div>
<div class="inner" <div class="inner" v-else-if="playAuth">
v-else-if="playAuth"> <div class="video_wid" id="player"></div>
<div class="video_wid"
id="player"></div>
</div> </div>
<div class="inner" <div class="inner" v-else-if="videoSrc">
v-else-if="videoSrc"> <video class="video" :key="videoSrc" width="100%" height="100%" autoplay controls>
<video class="video" <source :src="videoSrc" type="video/mp4">
:key="videoSrc"
width="100%"
height="100%"
autoplay
controls>
<source :src="videoSrc"
type="video/mp4">
您的浏览器不支持 video 标签 您的浏览器不支持 video 标签
</video> </video>
</div> </div>
@ -81,49 +49,26 @@
<div class="list"> <div class="list">
<h4 class="title">{{ courseName }}</h4> <h4 class="title">{{ courseName }}</h4>
<div class="desc-wrap"> <div class="desc-wrap">
<div class="desc" <div class="desc" :class="{ active: desShrink }" v-html="description"></div>
:class="{active: desShrink}" <i class="arrow" :class="{ active: desShrink }" v-if="description.length > 40">
v-html="description"></div>
<i class="arrow"
:class="{active: desShrink}"
v-if="description.length > 40">
<span>...</span> <span>...</span>
<img src="@/assets/img/arrow-down.png" <img src="@/assets/img/arrow-down.png" alt="" @click="desShrink = !desShrink">
alt=""
@click="desShrink = !desShrink">
</i> </i>
</div> </div>
<div class="chapters"> <div class="chapters">
<template v-if="videoList.length"> <template v-if="videoList.length">
<div class="chapter" <div class="chapter" v-for="(item, index) in videoList" :key="index">
v-for="(item,index) in videoList"
:key="index">
<div class="chapterName">{{ item.name }}</div> <div class="chapterName">{{ item.name }}</div>
<div class="section" <div class="section" v-if="item.subsectionList.length">
v-if="item.subsectionList.length"> <div v-for="(section, i) in item.subsectionList" :key="i" @click="preview(section, item.name)">
<div v-for="(section,i) in item.subsectionList" <p class="sectionName ellipsis" :class="{ active: curLink === `${item.name}${section.name}` }">
:key="i" <img v-if="section.fileType === 'pptx'" src="@/assets/img/exts/ppt.png" alt="">
@click="preview(section, item.name)"> <img v-else-if="section.fileType === 'mp4'" src="@/assets/img/exts/video.png" alt="">
<p class="sectionName ellipsis"
:class="{active: curLink === `${item.name}${section.name}`}">
<img v-if="section.fileType === 'pptx'"
src="@/assets/img/exts/ppt.png"
alt="">
<img v-else-if="section.fileType === 'mp4'"
src="@/assets/img/exts/video.png"
alt="">
<img v-else-if="section.fileType === 'doc' || section.fileType === 'docx'" <img v-else-if="section.fileType === 'doc' || section.fileType === 'docx'"
src="@/assets/img/exts/word.png" src="@/assets/img/exts/word.png" alt="">
alt=""> <img v-else-if="section.fileType === 'txt'" src="@/assets/img/exts/txt.png" alt="">
<img v-else-if="section.fileType === 'txt'" <img v-else-if="section.fileType === 'pdf'" src="@/assets/img/exts/pdf.png" alt="">
src="@/assets/img/exts/txt.png" <img v-else src="@/assets/img/exts/pic.png" alt="">
alt="">
<img v-else-if="section.fileType === 'pdf'"
src="@/assets/img/exts/pdf.png"
alt="">
<img v-else
src="@/assets/img/exts/pic.png"
alt="">
{{ section.name }} {{ section.name }}
</p> </p>
</div> </div>
@ -222,7 +167,7 @@ export default {
// //
if (row.fileId) { if (row.fileId) {
this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => { this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => {
this.playAuth = res.data.playAuth; this.playAuth = res.playAuth;
this.$nextTick(() => { this.$nextTick(() => {
if (this.player) { if (this.player) {
this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth); this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth);
@ -322,7 +267,9 @@ export default {
.wrap { .wrap {
padding: 0 200px; padding: 0 200px;
} }
$height: 700px; $height: 700px;
.video_wid, .video_wid,
.cover { .cover {
position: relative; position: relative;
@ -330,9 +277,11 @@ $height: 700px;
height: $height !important; height: $height !important;
border: 0; border: 0;
} }
.page { .page {
/deep/.des { /deep/.des {
overflow: auto; overflow: auto;
div, div,
p, p,
span { span {
@ -340,21 +289,27 @@ $height: 700px;
} }
} }
} }
.l-title { .l-title {
font-size: 17px; font-size: 17px;
} }
.cover { .cover {
background-color: #252528; background-color: #252528;
img { img {
border-radius: 8px; border-radius: 8px;
} }
&.is-word { &.is-word {
overflow: hidden; overflow: hidden;
} }
} }
.fileIframe { .fileIframe {
height: $height !important; height: $height !important;
} }
.video_wid, .video_wid,
.inner { .inner {
width: 100%; width: 100%;
@ -362,42 +317,52 @@ $height: 700px;
border: 0; border: 0;
overflow: auto; overflow: auto;
} }
.cover.is-word { .cover.is-word {
.inner { .inner {
height: calc(100% + 38px) !important; height: calc(100% + 38px) !important;
margin-top: -38px; margin-top: -38px;
} }
} }
.video_wid:focus { .video_wid:focus {
outline: none; outline: none;
} }
.catalog { .catalog {
width: 296px; width: 296px;
padding: 16px; padding: 16px;
margin-left: 12px; margin-left: 12px;
background-color: #252528; background-color: #252528;
} }
.list { .list {
height: calc(700px - 82px); height: calc(700px - 82px);
overflow-y: auto; overflow-y: auto;
.title { .title {
margin-bottom: 11px; margin-bottom: 11px;
color: #fff; color: #fff;
font-size: 16px; font-size: 16px;
} }
.pro-title { .pro-title {
margin-bottom: 5px; margin-bottom: 5px;
color: #fff; color: #fff;
font-size: 12px; font-size: 12px;
} }
/deep/.el-progress-bar { /deep/.el-progress-bar {
width: 92%; width: 92%;
} }
/deep/.el-progress__text { /deep/.el-progress__text {
color: #fff; color: #fff;
} }
.desc-wrap { .desc-wrap {
position: relative; position: relative;
.desc { .desc {
font-size: 12px; font-size: 12px;
color: #fff; color: #fff;
@ -407,11 +372,13 @@ $height: 700px;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
&.active { &.active {
display: block; display: block;
overflow: visible; overflow: visible;
} }
} }
.arrow { .arrow {
position: absolute; position: absolute;
bottom: 2px; bottom: 2px;
@ -420,41 +387,50 @@ $height: 700px;
justify-content: space-between; justify-content: space-between;
width: 46px; width: 46px;
background-color: #fff; background-color: #fff;
span { span {
font-size: 14px; font-size: 14px;
color: rgba(0, 0, 0, 0.65); color: rgba(0, 0, 0, 0.65);
} }
img { img {
width: 16px; width: 16px;
cursor: pointer; cursor: pointer;
} }
&.active { &.active {
span { span {
opacity: 0; opacity: 0;
} }
img { img {
transform: rotate(180deg); transform: rotate(180deg);
} }
} }
} }
} }
.chapters { .chapters {
margin-top: 16px; margin-top: 16px;
max-height: calc(100% - 53px); max-height: calc(100% - 53px);
overflow: auto; overflow: auto;
} }
.chapter { .chapter {
margin-bottom: 20px; margin-bottom: 20px;
} }
.chapterName { .chapterName {
color: #fff; color: #fff;
font-size: 14px; font-size: 14px;
} }
.section { .section {
padding: 5px 15px; padding: 5px 15px;
margin-top: 12px; margin-top: 12px;
background-color: #121214; background-color: #121214;
} }
.sectionName { .sectionName {
position: relative; position: relative;
display: flex; display: flex;
@ -464,36 +440,44 @@ $height: 700px;
font-size: 12px; font-size: 12px;
color: #999; color: #999;
cursor: pointer; cursor: pointer;
img { img {
margin-right: 8px; margin-right: 8px;
} }
.icon { .icon {
position: absolute; position: absolute;
right: 0; right: 0;
font-size: 14px; font-size: 14px;
color: #00c935; color: #00c935;
} }
.circle { .circle {
width: 14px; width: 14px;
height: 14px; height: 14px;
border-radius: 50%; border-radius: 50%;
border: 1px solid #ccc; border: 1px solid #ccc;
} }
&.active { &.active {
color: #fff; color: #fff;
} }
} }
} }
.buy { .buy {
text-align: center; text-align: center;
.tips { .tips {
margin-bottom: 10px; margin-bottom: 10px;
font-size: 14px; font-size: 14px;
} }
img { img {
width: 85%; width: 85%;
} }
} }
.el-image-viewer__wrapper { .el-image-viewer__wrapper {
transform: translateY(-10px); transform: translateY(-10px);
transition: transform 0.5s; transition: transform 0.5s;
@ -502,19 +486,23 @@ $height: 700px;
transform: translateY(0); transform: translateY(0);
} }
} }
.el-image-viewer__close { .el-image-viewer__close {
z-index: 2000; z-index: 2000;
top: 15px; top: 15px;
right: 15px; right: 15px;
&.doc-close { &.doc-close {
i { i {
color: #000 !important; color: #000 !important;
} }
} }
} }
.list::-webkit-scrollbar { .list::-webkit-scrollbar {
width: 4px; width: 4px;
} }
.list::-webkit-scrollbar-thumb { .list::-webkit-scrollbar-thumb {
border-radius: 10px; border-radius: 10px;
background: rgba(0, 0, 0, 0.06); background: rgba(0, 0, 0, 0.06);
@ -525,6 +513,7 @@ $height: 700px;
position: absolute; position: absolute;
background-color: rgb(57, 58, 61); background-color: rgb(57, 58, 61);
} }
.word-mask { .word-mask {
z-index: 9; z-index: 9;
position: absolute; position: absolute;
@ -533,6 +522,7 @@ $height: 700px;
width: 100%; width: 100%;
background-color: rgb(243, 242, 241); background-color: rgb(243, 242, 241);
} }
.word-mask1 { .word-mask1 {
z-index: 9; z-index: 9;
position: absolute; position: absolute;
@ -541,11 +531,13 @@ $height: 700px;
width: 100%; width: 100%;
background-color: #185abd; background-color: #185abd;
} }
.word-mask2 { .word-mask2 {
z-index: 9; z-index: 9;
position: absolute; position: absolute;
background-color: transparent; background-color: transparent;
} }
.excel-mask1 { .excel-mask1 {
z-index: 9; z-index: 9;
position: absolute; position: absolute;
@ -554,14 +546,17 @@ $height: 700px;
width: 60%; width: 60%;
background-color: #107c41; background-color: #107c41;
} }
.pdf { .pdf {
position: relative; position: relative;
.full { .full {
position: absolute; position: absolute;
top: 7px; top: 7px;
right: 10px; right: 10px;
cursor: pointer; cursor: pointer;
} }
.arrow { .arrow {
padding: 10px 0; padding: 10px 0;
display: flex; display: flex;
@ -570,12 +565,14 @@ $height: 700px;
font-size: 16px; font-size: 16px;
color: #fff; color: #fff;
background-color: #333; background-color: #333;
.turn { .turn {
margin: 0 10px; margin: 0 10px;
font-size: 18px; font-size: 18px;
cursor: pointer; cursor: pointer;
} }
} }
.pdf-wrap { .pdf-wrap {
width: 80%; width: 80%;
margin: 0 auto; margin: 0 auto;

@ -0,0 +1,39 @@
<template>
<div>
<iframe :src="url" frameborder="0" width="100%"></iframe>
</div>
</template>
<script>
import Util from '@/libs/util'
import Setting from '@/setting'
export default {
data () {
return {
url: ''
};
},
mounted () {
const cache = localStorage.getItem('examPath') // localStorage
let url = `${location.origin}/examination/`
if (Setting.isDev) url = `http://192.168.31.125:8098/`
if (cache) {
url += `#${cache}${cache.includes('?') ? `&` : '?'}token=${sessionStorage.getItem('token')}`
} else {
url += `#/quesBankType?token=${sessionStorage.getItem('token')}`
}
url += `&v=${Date.now()}`
localStorage.setItem('exam_token', sessionStorage.getItem('token'))
this.url = url
},
methods: {
}
};
</script>
<style lang="scss" scoped>
iframe {
height: calc(100vh - 167px);
}
</style>

@ -0,0 +1,57 @@
<template>
<div>
<el-card shadow="hover" class="m-b-20">
<div class="flex-between">
<el-page-header @back="back" content="理论考试系统程序"></el-page-header>
</div>
</el-card>
<div class="page">
<div class="tabs m-b-20">
<a class="item" v-for="(item, i) in tabs" :key="i" :class="{ active: i == active }" @click="tabChange(i)">{{
item
}}</a>
</div>
<System v-if="active == 'tab1'" />
<Program v-if="active == 'tab2'" />
</div>
</div>
</template>
<script>
import System from './system'
import Program from './program'
export default {
components: {
System,
Program,
},
data () {
return {
active: 'tab1',
tabs: {
tab1: '系统列表',
tab2: '程序后台',
},
};
},
mounted () {
},
methods: {
tabChange (i) {
this.active = i
},
back () {
this.$router.back()
},
}
};
</script>
<style scoped>
.card {
min-height: calc(100vh - 300px);
}
</style>

@ -0,0 +1,139 @@
<template>
<div>
<el-table v-loading="loading" :data="list" class="table" ref="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="curriculumName" label="程序名称" align="center"></el-table-column>
<el-table-column prop="curriculumType" label="供应商" align="center"></el-table-column>
<el-table-column prop="userName" label="程序类型" align="center"></el-table-column>
<el-table-column prop="orderVolume" label="程序归属" align="center"></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>
</template>
<script>
import qs from 'qs'
export default {
data () {
return {
list: [],
form: {
curriculumName: this.$route.query.curriculumName || ''
},
page: +this.$route.query.page || 1,
pageSize: 10,
total: 0,
loading: false,
searchTimer: null
};
},
watch: {
"form.curriculumName": function (val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.initData();
}, 500);
}
},
mounted () {
this.getData()
},
methods: {
//
getData () {
const sid = this.$store.state.dataPer.find(e => e.permissionName === '课程管理')
let data = {
...this.form,
pageNum: this.page,
pageSize: this.pageSize,
supplierId: sid ? sid.supplierId : ''
};
this.$post(this.api.curriculumList, data).then(res => {
this.list = res.page.records
this.total = res.page.total
this.loading = false
}).catch(err => { })
},
initData () {
this.page = 1
this.getData()
},
// url
setReferrer () {
this.$store.commit('setReferrer', `${this.$route.path}?${qs.stringify(this.form)}&page=${this.page}`)
},
//
addcourse () {
this.setReferrer()
this.$router.push("/addcurriculum");
},
//
edit (row) {
this.setReferrer()
this.$router.push(`/addcurriculum?cid=${row.cid}`);
},
//
config (row) {
this.setReferrer()
this.$router.push(`/contentSettings?cid=${row.cid}&name=${row.curriculumName}`);
},
//
handleDelete (row) {
this.$post(`${this.api.deleteCoursePrompt}?cids=${row.cid}`).then(({ status }) => {
if (status === 200) {
this.$confirm("确定要删除吗?", "提示", {
type: "warning"
}).then(() => {
this.$post(`${this.api.delCourse}?cids=${row.cid}`).then(res => {
this.getData();
this.$message.success("删除成功");
}).catch(err => { })
}).catch(() => {
});
}
}).catch(err => { })
},
//
delAllSelection () {
if (this.multipleSelection.length) {
let cids = []
this.multipleSelection.forEach(i => {
cids.push('cids=' + i.cid)
});
this.$post(`${this.api.deleteCoursePrompt}?${cids.join('&')}`).then(({ status }) => {
if (status === 200) {
this.$confirm("确定要删除吗?", "提示", {
type: "warning"
}).then(() => {
let ids = this.multipleSelection.map(i => i.cid);
this.$post(`${this.api.delCourse}?cids=${ids.toString()}`).then(res => {
if (ids.length == this.list.length) {
if (this.page > 1) {
this.page = this.page - 1
}
}
this.getData();
this.$message.success("删除成功");
this.$refs.table.clearSelection()
}).catch(err => { })
}).catch(() => { })
}
}).catch(err => { })
} else {
this.$message.warning("请先选择课程 !");
}
},
//
handleCurrentChange (val) {
this.page = val;
this.$router.push(`/curriculum?page=${val}`)
this.getData();
},
}
};
</script>
<style scoped></style>

@ -0,0 +1,321 @@
<template>
<div>
<div class="tool">
<ul class="filter">
<li>
<label>搜索</label>
<el-input placeholder="请输入系统名称" suffix-icon="el-icon-search" v-model="curriculumName" clearable
size="small"></el-input>
</li>
</ul>
<div>
<el-button type="primary" round @click="add">新增系统</el-button>
</div>
</div>
<el-table v-loading="loading" :data="list" class="table" ref="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="curriculumName" label="系统名称" align="center"></el-table-column>
<el-table-column prop="curriculumType" label="系统分类" align="center"></el-table-column>
<el-table-column prop="userName" label="系统描述" align="center"></el-table-column>
<el-table-column label="创建时间" align="center"></el-table-column>
<el-table-column prop="orderVolume" label="创建人" align="center"></el-table-column>
<el-table-column prop="expectedCourse" label="系统后台" align="center">
<template slot-scope="scope">
<el-button type="text" @click="edit(scope.row)">进入</el-button>
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="text" @click="edit(scope.row)">编辑</el-button>
<el-button type="text" @click="handleDelete(scope.row)">删除</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-dialog :title="(form.accountId ? '编辑' : '新增') + '系统'" :visible.sync="systemVisible" width="400px"
:close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item prop="workNumber" label="关联程序">
<el-input value="理论考试系统程序" disabled class="m-r-10" style="width: 240px;" />
<el-button type="text" @click="showProgram">查看</el-button>
</el-form-item>
<el-form-item prop="userName" label="系统名称">
<el-input v-model.trim="form.userName" placeholder="请输入系统名称"></el-input>
</el-form-item>
<el-form-item prop="account" label="系统分类">
<el-select v-model="form.operator" class="m-r-10" style="width: 230px;">
<!-- <el-option v-for="i in operators" :key="i" :label="i" :value="i"></el-option> -->
</el-select>
<el-button type="text" @click="customType">自定义</el-button>
</el-form-item>
<el-form-item prop="email" label="系统描述">
<el-input v-model.trim="form.email" type="textarea" :rows="4" placeholder="请输入系统描述"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="systemVisible = false">取消</el-button>
<el-button type="primary" @click="submitSystem">确定</el-button>
</span>
</el-dialog>
<!-- 程序列表 -->
<el-dialog title="程序列表" :visible.sync="programVisible" width="600px" :close-on-click-modal="false">
<Program />
<span slot="footer" class="dialog-footer">
<el-button @click="programVisible = false">关闭</el-button>
</span>
</el-dialog>
<!-- 系统分类设置 -->
<el-dialog title="系统分类设置" :visible.sync="typeVisible" width="600px" :close-on-click-modal="false"
class="manage-dia">
<div class="plus">
<i class="el-icon-circle-plus-outline" @click="addClass"></i>
</div>
<el-table :data="types" ref="table" header-align="center" row-key="id">
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="classificationName" label="分类名称" align="center" min-width="130">
<template slot-scope="scope">
<el-input v-if="scope.row.edit" placeholder="请输入分类名称" v-model="scope.row.classificationName" clearable
maxlength="30"></el-input>
<span v-else>{{ scope.row.classificationName }}</span>
</template>
</el-table-column>
<el-table-column prop="updateTime1" label="已引用系统数量" align="center" min-width="60"></el-table-column>
<el-table-column label="操作" align="center" min-width="60">
<template slot-scope="scope">
<i v-if="scope.row.edit" class="el-icon-check action m-r-10" @click="submitClass(scope.row)"></i>
<i v-else class="el-icon-edit action m-r-10" @click="editClass(scope.row)"></i>
<i class="el-icon-delete action" @click="delClass(scope.row, scope.$index)"></i>
</template>
</el-table-column>
</el-table>
<span slot="footer">
<el-button @click="closeClass">返回</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import Program from './program'
export default {
components: {
Program,
},
data () {
return {
list: [],
curriculumName: this.$route.query.curriculumName || '',
page: +this.$route.query.page || 1,
pageSize: 10,
total: 0,
loading: false,
searchTimer: null,
systemVisible: false,
form: {},
rules: {
roleList: [
{ required: true, message: '请输入系统名称', trigger: 'blur' }
],
type: [
{ required: true, message: '请选择系统分类', trigger: 'change' }
],
},
programVisible: false,
types: [],
typeVisible: false,
};
},
watch: {
curriculumName: function (val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.initData();
}, 500);
}
},
mounted () {
// this.getData()
},
methods: {
//
getData () {
let data = {
curriculumName: this.curriculumName,
pageNum: this.page,
pageSize: this.pageSize,
};
this.$post(this.api.curriculumList, data).then(res => {
this.list = res.page.records
this.total = res.page.total
this.loading = false
}).catch(err => { })
},
initData () {
this.page = 1
this.getData()
},
//
add () {
this.systemVisible = true
},
//
edit (row) {
this.$router.push(`/addcurriculum?cid=${row.cid}`);
},
//
config (row) {
this.$router.push(`/contentSettings?cid=${row.cid}&name=${row.curriculumName}`);
},
//
handleDelete (row) {
this.$post(`${this.api.deleteCoursePrompt}?cids=${row.cid}`).then(({ status }) => {
if (status === 200) {
this.$confirm("确定要删除吗?", "提示", {
type: "warning"
}).then(() => {
this.$post(`${this.api.delCourse}?cids=${row.cid}`).then(res => {
this.getData();
this.$message.success("删除成功");
}).catch(err => { })
}).catch(() => {
});
}
}).catch(err => { })
},
//
delAllSelection () {
if (this.multipleSelection.length) {
let cids = []
this.multipleSelection.forEach(i => {
cids.push('cids=' + i.cid)
});
this.$post(`${this.api.deleteCoursePrompt}?${cids.join('&')}`).then(({ status }) => {
if (status === 200) {
this.$confirm("确定要删除吗?", "提示", {
type: "warning"
}).then(() => {
let ids = this.multipleSelection.map(i => i.cid);
this.$post(`${this.api.delCourse}?cids=${ids.toString()}`).then(res => {
if (ids.length == this.list.length) {
if (this.page > 1) {
this.page = this.page - 1
}
}
this.getData();
this.$message.success("删除成功");
this.$refs.table.clearSelection()
}).catch(err => { })
}).catch(() => { })
}
}).catch(err => { })
} else {
this.$message.warning("请先选择课程 !");
}
},
//
handleCurrentChange (val) {
this.page = val;
this.$router.push(`/curriculum?page=${val}`)
this.getData();
},
//
showProgram () {
this.programVisible = true
},
//
customType () {
this.typeVisible = true
},
//
getType (detail) {
this.$post(`${this.api.queryClassificationByType}?typeId=${this.typeId}`).then(({ data }) => {
this.types = data
// id
if (detail) {
const id = this.form.classificationId
if (!data.find(e => e.id == id)) this.form.classificationId = ''
setTimeout(() => {
this.updateTime = 0
}, 500)
}
}).catch(err => { })
},
//
addClass () {
this.types.find(e => e.edit) ?
Util.errorMsg('请先保存分类!') :
this.types.push({
edit: true,
id: '',
classificationName: ''
})
},
//
editClass (row) {
this.types.find(e => e.edit) ?
Util.errorMsg('请先保存分类!') :
this.$set(row, 'edit', 1)
},
//
delClass (row, i) {
if (row.id) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
this.$post(`${this.api.batchDeletionParnerClass}?ids=${row.id}`).then(res => {
Util.successMsg('删除成功')
this.getType()
}).catch(res => { })
}).catch(() => { })
} else {
this.types.splice(i, 1)
}
},
//
submitClass (row, showMsg = 1) {
if (!row.classificationName) return Util.errorMsg('请输入分类名称')
this.$post(`${this.api.checkForHeavyParnerClass}?classificationName=${row.classificationName}&typeId=${this.typeId}&classificationId=${row.id}`).then(res => {
this.$post(this.api[row.id ? 'updateParnerClass' : 'saveParnerClass'], {
classificationName: row.classificationName,
typeId: this.typeId, // (1.2.)
id: row.id,
}).then(res => {
showMsg && Util.successMsg((row.id ? '修改' : '新增') + '成功')
this.getType()
}).catch(res => { })
}).catch(res => { })
},
//
submitSystem () {
},
}
};
</script>
<style lang="scss" scoped>
.plus {
margin-bottom: 10px;
font-size: 18px;
color: #9278ff;
text-align: right;
cursor: pointer;
}
.action {
cursor: pointer;
}
</style>
Loading…
Cancel
Save