Compare commits

..

No commits in common. 'master' and 'V2.4.9' have entirely different histories.

  1. 10
      .prettierrc
  2. 3009
      package-lock.json
  3. 12
      package.json
  4. 31
      public/index.html
  5. 62
      src/App.vue
  6. 65
      src/assets/css/main.css
  7. BIN
      src/assets/img/ach1.png
  8. BIN
      src/assets/img/ach2.png
  9. BIN
      src/assets/img/exts/pdf.png
  10. BIN
      src/assets/img/exts/pic.png
  11. BIN
      src/assets/img/exts/ppt.png
  12. BIN
      src/assets/img/exts/txt.png
  13. BIN
      src/assets/img/exts/video.png
  14. BIN
      src/assets/img/exts/word.png
  15. BIN
      src/assets/img/mini.jpg
  16. 1
      src/assets/img/right.svg
  17. 1
      src/assets/img/shrink.svg
  18. 1
      src/assets/img/tag-active.svg
  19. 1
      src/assets/img/tag.svg
  20. 1
      src/assets/img/wrong.svg
  21. 120
      src/components/Header.vue
  22. 56
      src/components/Sidebar.vue
  23. 6
      src/components/img-upload/Cropper.vue
  24. 565
      src/components/quill/index.vue
  25. 32
      src/components/upload/config.js
  26. 140
      src/components/upload/index.vue
  27. 40
      src/components/upload/upload.js
  28. 2
      src/const/match.js
  29. 50
      src/const/ques.js
  30. 34
      src/const/testPaper.js
  31. 4
      src/libs/aliyun/aliyun-oss-sdk-6.17.1.min.js
  32. 7
      src/libs/aliyun/aliyun-upload-sdk-1.5.6.min.js
  33. 38
      src/libs/route/addRoutes.js
  34. 195
      src/libs/util.js
  35. 56
      src/libs/zip.js
  36. 552
      src/router/index.js
  37. 76
      src/setting.js
  38. 34
      src/store/index.js
  39. 1000
      src/utils/api.js
  40. 4
      src/utils/core.js
  41. 281
      src/utils/editor.js
  42. 296
      src/utils/http.js
  43. 82
      src/utils/util.js
  44. 71
      src/views/Home.vue
  45. 897
      src/views/Login.vue
  46. 756
      src/views/course/AddCurriculum.vue
  47. 662
      src/views/course/Curriculum.vue
  48. 1818
      src/views/course/contentSettings.vue
  49. 919
      src/views/customer/AddCustomer.vue
  50. 288
      src/views/customer/Order.vue
  51. 177
      src/views/customer/customer.vue
  52. 433
      src/views/data/Introduce.vue
  53. 779
      src/views/devLogin.vue
  54. 415
      src/views/information/addArticle/index.vue
  55. 447
      src/views/information/columnManage/index.vue
  56. 431
      src/views/information/contentManage/contentList.vue
  57. 162
      src/views/information/contentManage/index.vue
  58. 144
      src/views/information/list/index.vue
  59. 284
      src/views/match/add/index.vue
  60. 356
      src/views/match/add/set.vue
  61. 1518
      src/views/match/add/step1.vue
  62. 874
      src/views/match/add/step2.vue
  63. 465
      src/views/match/add/step3.vue
  64. 75
      src/views/match/add/step4.vue
  65. 211
      src/views/match/add/template.vue
  66. 456
      src/views/match/list/index.vue
  67. 630
      src/views/match/manage/abnormalTeam.vue
  68. 227
      src/views/match/manage/index.vue
  69. 115
      src/views/match/manage/matchArch.vue
  70. 1104
      src/views/match/manage/matchArchList.vue
  71. 1116
      src/views/match/manage/matchInfo.vue
  72. 447
      src/views/match/manage/matchProgress.vue
  73. 646
      src/views/match/manage/matchRank.vue
  74. 442
      src/views/match/manage/matchReport.vue
  75. 1227
      src/views/match/manage/matchSignup.vue
  76. 266
      src/views/match/manage/notice.vue
  77. 315
      src/views/match/manage/noticeDetail.vue
  78. 675
      src/views/match/manage/otherArchList.vue
  79. 1059
      src/views/match/manage/theoryReport.vue
  80. 413
      src/views/match/manage/trialReport.vue
  81. 7
      src/views/match/preview/index.vue
  82. 2123
      src/views/order/AddOrder.vue
  83. 680
      src/views/order/Order.vue
  84. 1249
      src/views/parner/staff.vue
  85. 101
      src/views/parnerOperation/index.vue
  86. 339
      src/views/parnerOperation/info.vue
  87. 339
      src/views/parnerOperation/learn.vue
  88. 165
      src/views/parnerOperation/learnMg.vue
  89. 221
      src/views/parnerOperation/mobileRole.vue
  90. 269
      src/views/parnerOperation/pcRole.vue
  91. 279
      src/views/parnerOperation/plan.vue
  92. 65
      src/views/parnerOperation/schemeSet.vue
  93. 268
      src/views/parnerOperation/staff.vue
  94. 50
      src/views/review/index.vue
  95. 363
      src/views/serve/Configure.vue
  96. 3
      src/views/serve/addModel.vue
  97. 2
      src/views/serve/backstage/index.vue
  98. 10
      src/views/serve/backstage/model.vue
  99. 9
      src/views/serve/backstage/sourceModel.vue
  100. 342
      src/views/serve/projectAdd.vue
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,6 +1,6 @@
{ {
"tabWidth": 2, "tabWidth": 4,
"singleQuote": true, "singleQuote": true,
"trailingComma": "none", "trailingComma": "none",
"printWidth": 140 "printWidth": 140
} }

3009
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -9,31 +9,21 @@
}, },
"dependencies": { "dependencies": {
"@tinymce/tinymce-vue": "^3.2.8", "@tinymce/tinymce-vue": "^3.2.8",
"ali-oss": "^6.18.1",
"axios": "^0.18.0", "axios": "^0.18.0",
"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",
"echarts": "^5.4.1", "echarts": "^5.4.1",
"element-theme": "^2.0.1", "element-theme": "^2.0.1",
"element-ui": "^2.13.0", "element-ui": "^2.13.0",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"image-conversion": "^2.1.1", "image-conversion": "^2.1.1",
"image-webpack-loader": "^8.1.0",
"js-cookie": "^3.0.1", "js-cookie": "^3.0.1",
"jsencrypt": "^3.3.2", "mavon-editor": "^2.6.17",
"jszip": "^3.10.1",
"lodash": "^4.17.21",
"mavon-editor": "^2.10.4",
"postcss-px2rem": "^0.3.0", "postcss-px2rem": "^0.3.0",
"px2rem-loader": "^0.1.9", "px2rem-loader": "^0.1.9",
"qs": "^6.11.2", "qs": "^6.11.2",
"sortablejs": "^1.14.0", "sortablejs": "^1.14.0",
"stompjs": "^2.3.3",
"tinymce-plugin": "0.0.3-beta.22",
"umy-ui": "^1.1.6",
"vue": "^2.6.10", "vue": "^2.6.10",
"vue-codemirror": "^4.0.6", "vue-codemirror": "^4.0.6",
"vue-cropper": "^0.5.8", "vue-cropper": "^0.5.8",

@ -1,19 +1,18 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="keywords" content="深圳或然科技中台" /> <meta name="keywords" content="深圳或然科技中台">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
<meta name="viewport" content="width=device-width, user-scalable=yes, shrink-to-fit=no" /> <script src="/styles/tinymce/tinymce.min.js"></script>
<title>深圳或然科技中台</title> <title>深圳或然科技中台</title>
</head> </head>
<body> <body>
<noscript> <noscript>
<strong>We're sorry but vms doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> <strong>We're sorry but vms doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript> </noscript>
<div id="app"></div> <div id="app"></div>
<!-- built files will be auto injected --> <!-- built files will be auto injected -->
<script src="/dev/styles/tinymce/tinymce.min.js"></script> </body>
</body>
</html> </html>

@ -1,52 +1,30 @@
<template> <template>
<div id="app"> <div id="app">
<el-radio-group v-if="Setting.isDev" class="ip" v-model="ip" @change="ipChange"> <router-view></router-view>
<el-radio :label="0">刘榕ip</el-radio> </div>
<el-radio :label="1">陈赓ip</el-radio>
<el-radio :label="2">测试服ip</el-radio>
</el-radio-group>
<router-view></router-view>
</div>
</template> </template>
<script> <script>
import Setting from '@/setting' export default {
export default { name: 'App',
name: 'App', created () {
data () { //sessionStorage
return { if (sessionStorage.getItem("store") ) {
Setting, this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(sessionStorage.getItem("store"))))
ip: localStorage.getItem('ip') ? +localStorage.getItem('ip') : 0, }
};
}, //vuexsessionStorage
created () { window.addEventListener("beforeunload",()=>{
window.exitSystem = () => { sessionStorage.getItem("token") && sessionStorage.setItem("store",JSON.stringify(this.$store.state))
sessionStorage.removeItem('token') })
location.reload()
} }
//sessionStorage
if (sessionStorage.getItem("store")) {
this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem("store"))))
} }
//vuexsessionStorage
window.addEventListener("beforeunload", () => {
sessionStorage.getItem("token") && sessionStorage.setItem("store", JSON.stringify(this.$store.state))
})
},
methods: {
ipChange (val) {
localStorage.setItem('ip', val)
location.reload()
},
}
}
</script> </script>
<style> <style>
@import "./assets/css/main.css"; @import "./assets/css/main.css";
/* @import "./assets/css/color-dark.css"; */ /* @import "./assets/css/color-dark.css"; */
/*深色主题*/ /*深色主题*/
@import "./assets/css/theme-green/color-green.css"; @import "./assets/css/theme-green/color-green.css";
/* 浅绿色主题 */ /* 浅绿色主题 */
</style> </style>

@ -14,17 +14,10 @@ body,
} }
body { body {
min-width: 1200px;
font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif; font-family: 'PingFang SC', 'Helvetica Neue', Helvetica, 'microsoft yahei', arial, STHeiTi, sans-serif;
font-size: 14px; font-size: 14px;
} }
.ip {
z-index: 1;
position: fixed;
top: 0;
left: 0;
}
a { a {
text-decoration: none; text-decoration: none;
} }
@ -276,6 +269,16 @@ li {
font-style: normal; font-style: normal;
} }
/* .link_upload .el-upload-list{
width: 30%;
} */
/*VueEditor*/
.ql-container {
min-height: 400px;
}
.ql-snow .ql-tooltip { .ql-snow .ql-tooltip {
transform: translateX(117.5px) translateY(10px) !important; transform: translateX(117.5px) translateY(10px) !important;
} }
@ -448,15 +451,12 @@ li {
.el-switch__label span { .el-switch__label span {
font-size: 12px; font-size: 12px;
} }
.m-r-5 { .m-b-20 {
margin-right: 5px; margin-bottom: 20px;
} }
.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;
@ -464,7 +464,7 @@ li {
} }
} }
.el-tooltip__popper { .el-tooltip__popper {
max-width: 100% !important; max-width: 500px !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;
@ -488,42 +488,3 @@ 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.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 88 KiB

@ -1 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 593 B

@ -1 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 766 B

@ -1 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 545 B

@ -1 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 545 B

@ -1 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 768 B

@ -1,29 +1,33 @@
<template> <template>
<div class="header flex-between"> <div class="header flex-between">
<div class="logo"> <div class="logo">
<img class="cursor" @click="goHome" src="../assets/img/logo.png"> <img class="cursor"
@click="goHome"
src="../assets/img/logo.png">
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="header-user-con"> <div class="header-user-con">
<div class="user" @click="toPerson"> <div class="user"
<el-avatar :size="40" :src="$store.state.avatar"></el-avatar> @click="toPerson">
<span class="user-avator">{{ userName }}</span> <el-avatar :size="40"
:src="$store.state.avatar"></el-avatar>
<span class="user-avator">{{userName}}</span>
</div> </div>
<el-divider class="ml20" direction="vertical"></el-divider> <el-divider class="ml20"
<el-button type="text" class="ml20" @click="logout">退出</el-button> direction="vertical"></el-divider>
<el-button type="text"
class="ml20"
@click="loginout">退出</el-button>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import Bus from '@/libs/bus' import Bus from '@/libs/bus'
import Setting from '@/setting'
export default { export default {
data () { data () {
return { return {
timer: null, userName: ''
Setting,
userName: '',
}; };
}, },
mounted () { mounted () {
@ -35,10 +39,9 @@ export default {
this.$router.push('/person') this.$router.push('/person')
} }
}, },
async logout () { loginout () {
await this.$post(this.api.logout) localStorage.removeItem('ms_username');
localStorage.removeItem('ms_username') localStorage.removeItem('token');
localStorage.removeItem('token')
sessionStorage.clear() sessionStorage.clear()
location.reload() location.reload()
}, },
@ -80,12 +83,6 @@ export default {
// socket // socket
this.socket.onmessage = this.getMessage; this.socket.onmessage = this.getMessage;
}, },
//
heartbeatDetection () {
this.timer = setInterval(async () => {
sessionStorage.getItem('token') ? await this.$get(this.api.heartbeatDetection) : clearInterval(this.timer)
}, 58 * 1000)
},
getUserInfo () { getUserInfo () {
@ -97,7 +94,6 @@ export default {
id && this.$store.commit('SET_ACCOUNTID', id) id && this.$store.commit('SET_ACCOUNTID', id)
this.$store.commit('SET_USERNAME', this.userName) this.$store.commit('SET_USERNAME', this.userName)
this.initSocket(result.userAccount) this.initSocket(result.userAccount)
Setting.isPro && this.heartbeatDetection()
}).catch(err => { }) }).catch(err => { })
}, },
}, },
@ -105,74 +101,62 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.header { .header {
position: relative; position: relative;
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;
height: 60px; height: 60px;
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;
} }
</style> </style>

@ -1,27 +1,40 @@
<template> <template>
<div> <div>
<el-menu class="sidebar-el-menu" :default-active="onRoutes" background-color="#324157" text-color="#bfcbd9" <el-menu class="sidebar-el-menu"
active-text-color="#9278FF" unique-opened mode="horizontal" router @select="handleSelect"> :default-active="onRoutes"
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" :key="item.index"> <el-submenu :index="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" :index="subItem.index" :key="subItem.index"> <el-submenu v-if="subItem.subs"
: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" :key="i" :index="threeItem.index">{{ <el-menu-item v-for="(threeItem,i) in subItem.subs"
threeItem.title :key="i"
}}</el-menu-item> :index="threeItem.index">{{ threeItem.title }}</el-menu-item>
</el-submenu> </el-submenu>
<el-menu-item v-else :index="subItem.index" :key="subItem.index">{{ subItem.title }}</el-menu-item> <el-menu-item v-else
: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" :key="item.index"> <el-menu-item :index="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>
@ -89,7 +102,7 @@ export default {
title: '系统配置' title: '系统配置'
}, },
{ {
icon: 'el-icon-box', icon: 'el-icon-s-check',
index: '/parner', index: '/parner',
title: '合伙管理' title: '合伙管理'
}, },
@ -99,20 +112,10 @@ export default {
title: '合伙运营' title: '合伙运营'
}, },
{ {
icon: 'el-icon-shopping-cart-2', icon: 'el-icon-s-shop',
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
@ -135,6 +138,7 @@ export default {
methods: { methods: {
handleSelect (index) { handleSelect (index) {
this.onRoutes = index this.onRoutes = index
this.$store.commit('setOrderParam', null)
this.$store.commit('setInfoTab', '1') this.$store.commit('setInfoTab', '1')
this.$store.commit('setColumnId', '') this.$store.commit('setColumnId', '')
this.$store.commit('setCompetitionCache', null) this.$store.commit('setCompetitionCache', null)
@ -173,14 +177,12 @@ export default {
<style scoped> <style scoped>
.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%;
} }
</style> </style>

@ -147,9 +147,9 @@ export default {
const that = this const that = this
if (type === 'blob') { if (type === 'blob') {
this.$refs.cropper.getCropBlob(data => { this.$refs.cropper.getCropBlob(data => {
// compress(data, 1).then(res => { compress(data, 1).then(res => {
that.$emit('upload', data) that.$emit('upload', res)
// }) })
}) })
} else { } else {
this.$refs.cropper.getCropData(data => { this.$refs.cropper.getCropData(data => {

@ -1,344 +1,253 @@
<template> <template>
<div> <div class="quill" ref="quill" :class="classes">
<el-radio-group v-if="!readonly && radio" class="type-radio" v-model="editorType" @change="typeChange"> <div ref="editor" :style="styles" v-loading="loading"></div>
<el-radio label="0">富文本</el-radio> <el-upload
<el-radio label="1">markdown</el-radio> :headers="headers"
</el-radio-group> :action="this.api.fileupload"
:before-upload="beforeUpload"
<div v-show="editorType == 0" class="quill" ref="quill" :class="classes"> :on-success="editorUploadSuccess"
<div ref="editor" :style="styles" v-loading="loading"></div> style="display: none">
<Upload :max-size="1000" :limit="100" @beforeUpload="beforeUpload" @onSuccess="editorUploadSuccess" <el-button class="editorUpload" type="primary">点击上传</el-button>
style="display: none"> </el-upload>
<div slot="trigger">
<el-button :id="'editorUpload' + index" type="primary">点击上传</el-button>
</div>
</Upload>
</div> </div>
<mavon-editor class="md" v-model="mdVal" v-show="editorType == 1" ref="md" :ishljs="true" :subfield="false"
@change="mdChange" @imgAdd="imgAdd" />
</div>
</template> </template>
<script> <script>
import Quill from 'quill'; import Quill from 'quill';
import 'quill/dist/quill.core.css'; import 'quill/dist/quill.core.css';
import 'quill/dist/quill.snow.css'; import 'quill/dist/quill.snow.css';
import 'quill/dist/quill.bubble.css'; import 'quill/dist/quill.bubble.css';
import toolbarOptions from './options' import toolbarOptions from './options'
import { mavonEditor } from 'mavon-editor'
import 'mavon-editor/dist/css/index.css' export default {
import Upload from '@/components/upload'; name: 'quill',
import Oss from '@/components/upload/upload.js' props: {
value: {
export default { type: String,
name: 'quill', default: ''
components: { },
Upload, readonly: {
mavonEditor type: Boolean,
}, default:false
props: { },
value: { toTop: {
type: String, type: Boolean,
default: '' default:true
}, },
readonly: { border: {
type: Boolean, type: Boolean,
default: false default:false
}, },
toTop: { height: {
type: Boolean, type: Number
default: true },
}, minHeight: {
border: { type: Number
type: Boolean, },
default: false /*
}, * 原本的readOnly失效,对比其他项目发现是quill版本不同导致
height: { * 使用props传入elseRead = 'true'手动隐藏工具栏
type: Number */
}, elseRead:{
minHeight: { type:String,default:'false'
type: Number }
}, },
/* data () {
* 原本的readOnly失效,对比其他项目发现是quill版本不同导致 return {
* 使用props传入elseRead = 'true'手动隐藏工具栏 headers: {
*/ token: sessionStorage.getItem('token')
elseRead: { },
type: String, default: 'false' Quill: null,
}, currentValue: '',
// options: {
index: { theme: 'snow',
type: Number, bounds: document.body,
default: 0 debug: 'warn',
}, modules: {
// toolbar: {
radio: { container: toolbarOptions,
type: Boolean, handlers: {
default: false 'image': function (value) {
}, if (value) {
// // iview
type: { document.querySelector('.editorUpload').click()
type: String, } else {
default: '0' this.Quill.format('image', false);
}, }
}, }
data () { }
const that = this }
return { },
headers: { placeholder: '',
token: sessionStorage.getItem('token') readOnly: this.readonly
}, },
editorType: '0', loading: false
mdVal: '', }
Quill: null, },
currentValue: '', computed: {
options: { classes () {
theme: 'snow', return [
bounds: document.body, {
debug: 'warn', 'quill-no-border': !this.border
modules: { }
toolbar: { ];
container: toolbarOptions, },
handlers: { styles () {
'image': function (value) { let style = {};
if (value) { if (this.minHeight) {
// iview style.minHeight = `${this.minHeight}px`;
document.querySelector("#editorUpload" + that.index).click(); }
} else { if (this.height) {
this.Quill.format('image', false); style.height = `${this.height}px`;
} }
} return style;
},
},
watch: {
value: {
handler (val) {
if (val !== this.currentValue) {
this.currentValue = val;
if (this.Quill) {
this.Quill.pasteHTML(this.value);
}
}
},
immediate: true
} }
}
}, },
placeholder: '', created(){
readOnly: this.readonly },
}, mounted () {
loading: false this.init();
} //
}, if(this.elseRead==='true'){
computed: { let children = this.$refs.quill.children[0].style
classes () { children.padding = '0'
return [ children.overflow = 'hidden'
{ children.height = '0'
'quill-no-border': !this.border children.borderTop = '0'
}
];
},
styles () {
let style = {};
if (this.minHeight) {
style.minHeight = `${this.minHeight}px`;
}
if (this.height) {
style.height = `${this.height}px`;
}
return style;
},
},
watch: {
type: {
handler (val) {
this.editorType = val
},
immediate: true
},
value: {
handler (val) {
if (this.type == 0) {
if (val !== this.currentValue) {
this.currentValue = val;
if (this.Quill) {
this.Quill.pasteHTML(this.value);
} }
} },
beforeDestroy () {
//
this.Quill = null;
},
methods: {
init () {
const editor = this.$refs.editor;
//
this.Quill = new Quill(editor, this.options);
const ins = this.Quill
//
ins.pasteHTML(this.currentValue);
if(this.toTop){
this.$nextTick(() => {
window.scrollTo(0,0)
})
}
//
ins.on('text-change', (delta, oldDelta, source) => {
const html = this.$refs.editor.children[0].innerHTML;
const text = ins.getText();
const quill = this.Quill;
//
this.currentValue = html;
// v-model
this.$emit('input', html);
//
this.$emit('on-change', { html, text, quill });
});
// quill
ins.on('text-change', (delta, oldDelta, source) => {
this.$emit('on-text-change', delta, oldDelta, source);
});
ins.on('selection-change', (range, oldRange, source) => {
this.$emit('on-selection-change', range, oldRange, source);
});
ins.on('editor-change', (eventName, ...args) => {
this.$emit('on-editor-change', eventName, ...args);
});
//
ins.root.addEventListener('paste', evt => {
if (evt.clipboardData && evt.clipboardData.files && evt.clipboardData.files.length) {
evt.preventDefault();
//
[].forEach.call(evt.clipboardData.files, file => {
if (!file.type.match(/^image\/(gif|jpe?g|a?png|bmp)/i)) {
return
}
const param = new FormData()
param.append('file', file)
// base64
this.$post(this.api.fileupload, param, {
headers: { "Content-Type": "multipart/form-data" }
}).then(res => {
var range = ins.getSelection()
if (range) {
//
ins.insertEmbed(range.index, 'image', res.data.filesResult.fileUrl)
//
ins.setSelection(range.index + 1)
}
}).catch(res => {})
});
}
}, false)
},
beforeUpload(file){
this.loading = true
},
editorUploadSuccess (res) {
//
let quill = this.Quill
//
if (res.data.filesResult.fileUrl) {
//
let lengths;
if ( quill.getSelection() == null){
lengths = 1
}else{
lengths = quill.getSelection().index;
}
// res
quill.insertEmbed(lengths, 'image', res.data.filesResult.fileUrl)
//
quill.setSelection(lengths + 1)
} else {
this.$message.success('图片插入失败')
}
this.loading = false
},
} }
if (!this.mdVal) this.mdVal = val
},
immediate: true
}
},
mounted () {
this.init();
//
if (this.elseRead === 'true') {
let children = this.$refs.quill.children[0].style
children.padding = '0'
children.overflow = 'hidden'
children.height = '0'
children.border = '0'
} }
},
beforeDestroy () {
//
this.Quill = null;
},
methods: {
//
typeChange (val) {
this.$emit('update:type', val)
if (!this.mdVal) this.mdVal = this.value
},
init () {
const editor = this.$refs.editor;
//
this.Quill = new Quill(editor, this.options);
const ins = this.Quill
//
ins.pasteHTML(this.currentValue);
if (this.toTop) {
this.$nextTick(() => {
window.scrollTo(0, 0)
})
}
//
ins.on('text-change', (delta, oldDelta, source) => {
const html = this.$refs.editor.children[0].innerHTML;
const text = ins.getText();
const quill = this.Quill;
//
this.currentValue = html;
// v-model
this.$emit('input', html);
//
this.$emit('on-change', { html, text, quill });
});
// quill
ins.on('text-change', (delta, oldDelta, source) => {
this.$emit('on-text-change', delta, oldDelta, source);
});
ins.on('selection-change', (range, oldRange, source) => {
this.$emit('on-selection-change', range, oldRange, source);
});
ins.on('editor-change', (eventName, ...args) => {
this.$emit('on-editor-change', eventName, ...args);
});
//
ins.root.addEventListener('paste', evt => {
if (evt.clipboardData && evt.clipboardData.files && evt.clipboardData.files.length) {
evt.preventDefault();
//
[].forEach.call(evt.clipboardData.files, file => {
if (!file.type.match(/^image\/(gif|jpe?g|a?png|bmp)/i)) {
return
}
// ossbase64
Oss.upload(file).then(res => {
var range = ins.getSelection()
if (range) {
//
ins.insertEmbed(range.index, 'image', res.url)
//
ins.setSelection(range.index + 1)
}
})
});
}
}, false)
},
beforeUpload (file) {
this.loading = true
},
// quill
editorUploadSuccess (file) {
//
let quill = this.Quill
//
if (file.url) {
//
let lengths;
if (quill.getSelection() == null) {
lengths = 1
} else {
lengths = quill.getSelection().index;
}
// res
quill.insertEmbed(lengths, 'image', file.url)
//
quill.setSelection(lengths + 1)
} else {
this.$message.success('图片插入失败')
}
this.loading = false
},
//
mdChange (val) {
this.$emit('input', val)
},
// markdown
imgAdd (pos, $file) {
let $vm = this.$refs.md
// oss
Oss.upload($file).then(res => {
$vm.$img2Url(pos, res.url);
})
},
}
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.type-radio { .quill-no-border{
margin-bottom: 20px; .ql-toolbar.ql-snow{
} border: none;
border-bottom: 1px solid #e8eaec;
.quill-no-border { }
.ql-toolbar.ql-snow { .ql-container.ql-snow{
border: none; border: none;
border-bottom: 1px solid #e8eaec; }
}
.ql-container.ql-snow {
border: none;
}
}
.else {
.ql-toolbar.ql-snow {
height: 0;
overflow: hidden;
padding: 0;
border-top: 0;
}
}
/deep/.ql-snow {
position: relative;
.ql-tooltip {
position: absolute !important;
top: 0 !important;
left: -100px !important;
transform: translateY(10px);
}
}
.md {
max-height: 300px;
}
/deep/.v-note-wrapper .v-note-panel {
min-height: 200px;
}
/deep/.markdown-body {
ul {
list-style: disc;
li {
list-style: inherit;
} }
} .else{
.ql-toolbar.ql-snow{
ol { height: 0;
list-style: decimal; overflow: hidden;
padding: 0;
li { border-top: 0;
list-style: inherit; }
}
/deep/.ql-snow {
position: relative;
.ql-tooltip {
position: absolute !important;
top: 0 !important;
left: -100px !important;
transform: translateY(10px);
}
} }
}
}
</style> </style>

@ -1,32 +0,0 @@
/**
* 阿里云oss配置
* */
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账号信息
config: {
region: 'oss-cn-shenzhen',
accessKeyId: RE[0],
accessKeySecret: RE[1],
bucket: 'huoran'
},
// 上传成功url前置部分(成功回调没有返回url)
preUrl: 'https://huoran.oss-cn-shenzhen.aliyuncs.com/'
}
} catch (e) { }
}

@ -1,140 +0,0 @@
<template>
<el-upload :disabled="uploading" :before-upload="beforeUpload" :on-remove="onRemove" :on-error="uploadError"
:limit="limit" action="" :on-exceed="handleExceed" :show-file-list="showFiles" :file-list="fileList"
:http-request="handleRequest" name="file">
<slot name="trigger">
<el-button size="small" :loading="uploading">{{ uploading ? '正在上传' : '上传文件' }}</el-button>
</slot>
<div slot="tip" class="el-upload__tip">
<el-progress v-if="uploading" class="upload-progress" :stroke-width="3"
:percentage="uploadProgress"></el-progress>
<slot name="tip">
<p>支持扩展名.rar .zip .doc .docx .pdf .jpg...</p>
</slot>
</div>
</el-upload>
</template>
<script>
import OSS from 'ali-oss'
import OssConfig from './config.js'
import Util from '@/libs/util'
export default {
props: {
//
limit: {
type: Number,
default: 1
},
// (: Mb)
maxSize: {
type: Number,
default: 10
},
//
showFileList: {
type: Boolean,
default: true
},
//
fileList: {
type: Array,
default: () => []
},
// fileList使fileListfalse
changeFileList: {
type: Boolean,
default: true
},
//
onRemove: {
type: Function,
default: new Function()
},
},
data () {
return {
client: null,
uploading: false,
uploadProgress: 0,
showFiles: this.showFileList,
Oss: {},
};
},
mounted () {
this.initOss()
},
methods: {
// oss
async initOss () {
this.Oss = await OssConfig()
this.client = new OSS(this.Oss.config)
},
//
beforeUpload (file) {
const oversize = file.size / 1024 / 1024 < this.maxSize
if (!oversize) Util.warningMsg(`请上传小于${this.maxSize}MB的附件!`)
if (oversize) {
this.$emit('beforeUpload', file)
return true
} else {
return false
}
},
//
handleProgress (progress) {
this.uploadProgress = Number((progress * 100).toFixed(2))
},
//
async handleRequest ({ file }) {
try {
this.uploadProgress = 0
this.uploading = true
this.showFiles = false
// oss
const { name } = await this.client.multipartUpload(Date.now() + '.' + Util.getFileExt(file.name), file, {
progress: this.handleProgress
});
this.uploading = false
const url = this.Oss.preUrl + name
this.changeFileList && this.$emit('update:fileList', [
...this.fileList,
{
name: name,
url
}
])
this.showFiles = true
this.$emit('onSuccess', {
format: Util.getFileExt(file.name),
name: file.name,
url,
size: file.size,
})
} catch (error) { }
},
uploadError (err, file, fileList) {
this.$message({
message: "上传出错,请重试!",
type: "error",
center: true
})
},
beforeRemove (file, fileList) {
return this.$confirm(`确定移除 ${file.name}`);
},
handleExceed (files, fileList) {
Util.warningMsg(`当前限制选择 ${this.limit} 个文件,如需更换,请删除上一个文件再重新选择!`);
},
}
};
</script>
<style lang="scss" scoped>
/deep/.upload-progress {
max-width: 300px;
margin: 10px 0;
white-space: nowrap;
}
</style>

@ -1,40 +0,0 @@
// 阿里云oss上传
import OSS from 'ali-oss'
import OssConfig from './config'
import Util from '@/libs/util'
let client = null
let Oss
// 初始化oss
const initOss = async () => {
Oss = await OssConfig()
if (!client) client = new OSS(Oss.config)
}
initOss()
export default {
// 上传文件
upload (file) {
initOss()
return new Promise(async (resolve, reject) => {
try {
// 上传到阿里云oss
const res = await client.multipartUpload(Date.now() + '.' + Util.getFileExt(file.name), file);
resolve({
format: Util.getFileExt(file.name),
name: file.name,
url: Oss.preUrl + res.name,
size: file.size,
})
} catch (error) {
reject()
}
})
},
// 删除文件(传完整url,不是没有https的name,因为很多接口没有存name,只存url,所以统一使用url)
async del (url) {
initOss()
await client.delete(url.replace(Oss.preUrl, ''));
}
}

@ -28,7 +28,7 @@
}, },
{ {
id: 2, id: 2,
name: '其它' name: '线下'
} }
], ],
teamCalculationMethods: [ teamCalculationMethods: [

@ -1,50 +0,0 @@
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: '问答题'
},
],
}

@ -1,34 +0,0 @@
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: '竞赛'
},
],
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -3,27 +3,27 @@ import generateBtnPermission from '../auth/generateBtnPermission';
const newRoutes = [] const newRoutes = []
function createMeta (item) { function createMeta(item){
let meta = { title: item.name } let meta = { title: item.name }
return meta return meta
} }
function createRoute (data) { function createRoute(data){
data.map(e => { data.map(e => {
if (e.path) { if(e.path){
let meta = createMeta(e) let meta = createMeta(e)
newRoutes.push({ newRoutes.push({
path: e.path, path: e.path,
meta meta
}) })
} }
// 递归生成路由集合 // 递归生成路由集合
e.children && e.children.length && createRoute(e.children) e.children && e.children.length && createRoute(e.children)
}) })
} }
export default function (data, path) { export default function(data,path){
generateBtnPermission(data) generateBtnPermission(data)
createRoute(data) createRoute(data)
store.commit('addRoutes', newRoutes) store.commit('addRoutes',newRoutes)
} }

@ -1,132 +1,123 @@
import cookies from './util.cookies' import cookies from './util.cookies'
import { _local, _session } from './util.db' import {_local,_session} from './util.db'
import { Message } from 'element-ui' import { Message } from 'element-ui'
import Setting from '@/setting'
import axios from 'axios'
import api from '@/utils/api'
// 文件后缀集合 // 文件后缀集合
const exts = { const exts = {
video: 'mp4,3gp,mov,m4v,avi,dat,mkv,flv,vob,rmvb,rm,qlv', video: 'mp4,3gp,mov,m4v,avi,dat,mkv,flv,vob,rmvb,rm,qlv',
audio: 'mp3,aac,ape,flac,wav,wma,amr,mid', audio: 'mp3,aac,ape,flac,wav,wma,amr,mid',
img: 'jpg,jpeg,png,gif,svg,psd', img: 'jpg,jpeg,png,gif,svg,psd',
doc: 'doc,docx,txt,xls,xlsx,csv,xml,ppt,pptx', doc: 'doc,docx,txt,xls,xlsx,csv,xml,ppt,pptx'
compress: 'zip,rar,7z,tar,gz,bz2',
} }
const util = { const util = {
cookies, cookies,
local: _local, local: _local,
session: _session, session: _session,
// 传入身份证获取生日 // 传入身份证获取生日
getBirth (idCard) { getBirth(idCard) {
var birthday = ""; var birthday = "";
if (idCard != null && idCard != "") { if(idCard != null && idCard != ""){
if (idCard.length == 15) { if(idCard.length == 15){
birthday = "19" + idCard.slice(6, 12); birthday = "19"+idCard.slice(6,12);
} else if (idCard.length == 18) { } else if(idCard.length == 18){
birthday = idCard.slice(6, 14); birthday = idCard.slice(6,14);
} }
birthday = birthday.replace(/(.{4})(.{2})/, "$1-$2-"); birthday = birthday.replace(/(.{4})(.{2})/,"$1-$2-");
//通过正则表达式来指定输出格式为:1990-01-01 //通过正则表达式来指定输出格式为:1990-01-01
} }
return birthday; return birthday;
}, },
// new Date('2020-11-12 00:00:00') 在IE下失效,因此把-替换成/ // new Date('2020-11-12 00:00:00') 在IE下失效,因此把-替换成/
dateCompatible (date) { dateCompatible(date) {
return date.replace(/\-/g, '/') return date.replace(/\-/g, '/')
}, },
// 日期时间前面补零 // 日期时间前面补零
formateTime (num) { formateTime(num) {
return num < 10 ? `0${num}` : num return num < 10 ? `0${num}` : num
}, },
//返回格式化时间,传参例如:"yyyy-MM-dd hh:mm:ss" //返回格式化时间,传参例如:"yyyy-MM-dd hh:mm:ss"
formatDate (fmt, date) { formatDate(fmt,date) {
var date = date ? date : new Date() var date = date ? date : new Date()
var o = { var o = {
"M+": date.getMonth() + 1, //月份 "M+" : date.getMonth()+1, //月份
"d+": date.getDate(), //日 "d+" : date.getDate(), //日
"h+": date.getHours(), //小时 "h+" : date.getHours(), //小时
"m+": date.getMinutes(), //分 "m+" : date.getMinutes(), //分
"s+": date.getSeconds(), //秒 "s+" : date.getSeconds(), //秒
"q+": Math.floor((date.getMonth() + 3) / 3), //季度 "q+" : Math.floor((date.getMonth()+3)/3), //季度
"S": date.getMilliseconds() //毫秒 "S" : date.getMilliseconds() //毫秒
}; };
if (/(y+)/.test(fmt)) { if(/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length)); fmt=fmt.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length));
} }
for (var k in o) { for(var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) { if(new RegExp("("+ k +")").test(fmt)){
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
} }
} }
return fmt; return fmt;
}, },
// 移除数组中指定值 // 移除数组中指定值
removeByValue (arr, val) { removeByValue(arr, val) {
for (var i = 0; i < arr.length; i++) { for(var i=0; i<arr.length; i++) {
if (arr[i] == val) { if(arr[i] == val) {
arr.splice(i, 1); arr.splice(i, 1);
break; break;
} }
} }
}, },
// 传入文件后缀判断是否是视频 // 传入文件后缀判断是否是视频
isVideo (ext) { isVideo(ext) {
if (exts.video.includes(ext)) return true; if (exts.video.includes(ext)) return true;
return false; return false;
}, },
// 传入文件后缀判断是否是音频 // 传入文件后缀判断是否是音频
isAudio (ext) { isAudio(ext) {
if (exts.audio.includes(ext)) return true; if (exts.audio.includes(ext)) return true;
return false; return false;
}, },
// 传入文件后缀判断是否是图片 // 传入文件后缀判断是否是图片
isImg (ext) { isImg(ext) {
if (exts.img.includes(ext)) return true; if (exts.img.includes(ext)) return true;
return false; return false;
}, },
// 传入文件后缀判断是否是pdf以外的文档 // 传入文件后缀判断是否是pdf以外的文档
isDoc (ext) { isDoc(ext) {
if (exts.doc.includes(ext)) return true; if (exts.doc.includes(ext)) return true;
return false; return false;
},
// 传入文件后缀判断是否是压缩包
isCompress (ext) {
if (exts.compress.includes(ext)) return true;
return false;
}, },
// 判断是否能够预览 // 判断是否能够预览
canPreview (ext) { canPreview(ext) {
if (!util.isVideo(ext) && !util.isAudio(ext) && !util.isImg(ext) && !util.isDoc(ext)) return false if (!util.isVideo(ext) && !util.isAudio(ext) && !util.isImg(ext) && !util.isDoc(ext)) return false
return true return true
}, },
// 循环去除html标签 // 循环去除html标签
removeHtmlTag (list, attr) { removeHtmlTag(list,attr) {
list.map(n => { list.map(n => {
n[attr] = n[attr].replace(/<\/?.+?>/gi, '') n[attr] = n[attr].replace(/<\/?.+?>/gi,'')
}) })
return list return list
}, },
// 传入文件名获取文件后缀 // 传入文件名获取文件后缀
getFileExt (fileName) { getFileExt(fileName) {
return fileName.substring(fileName.lastIndexOf('.') + 1) return fileName.substring(fileName.lastIndexOf('.') + 1)
}, },
// 传入文件名和路径,下载图片视频,支持跨域,a标签加download不支持跨域 // 传入文件名和路径,下载图片视频,支持跨域,a标签加download不支持跨域
downloadFile (fileName, url) { downloadFile(fileName,url) {
var x = new XMLHttpRequest() var x = new XMLHttpRequest()
x.open("GET", url, true) x.open("GET", url, true)
x.responseType = 'blob' x.responseType = 'blob'
x.onload = function (e) { x.onload=function(e) {
var url = window.URL.createObjectURL(x.response) var url = window.URL.createObjectURL(x.response)
var a = document.createElement('a') var a = document.createElement('a')
a.href = url a.href = url
a.download = fileName a.download = fileName
a.click() a.click()
} }
x.send() x.send()
}, },
// 传入文件名和数据,下载文件 // 传入文件名和数据,下载文件
downloadFileDirect (fileName, data) { downloadFileDirect(fileName,data) {
if ('download' in document.createElement('a')) { // 非IE下载 if ('download' in document.createElement('a')) { // 非IE下载
const elink = document.createElement('a') const elink = document.createElement('a')
elink.download = fileName elink.download = fileName
@ -141,74 +132,26 @@ const util = {
} }
}, },
// 成功提示 // 成功提示
successMsg (message, duration = 1500) { successMsg(message,duration = 1500) {
return Message.success({ message, showClose: true, offset: (document.documentElement.clientHeight - 40) / 2, duration }) return Message.success({message,showClose: true,offset: (document.documentElement.clientHeight - 40) / 2,duration})
}, },
// 警告提示 // 警告提示
warningMsg (message, duration = 1500) { warningMsg(message,duration = 1500) {
return Message.warning({ message, showClose: true, offset: (document.documentElement.clientHeight - 40) / 2, duration }) return Message.warning({message,showClose: true,offset: (document.documentElement.clientHeight - 40) / 2,duration})
}, },
// 错误提示 // 错误提示
errorMsg (message, duration = 1500) { errorMsg(message,duration = 1500) {
return Message.error({ message, showClose: true, offset: (document.documentElement.clientHeight - 40) / 2, duration }) return Message.error({message,showClose: true,offset: (document.documentElement.clientHeight - 40) / 2,duration})
}, },
// 判断是否是移动端 // 判断是否是移动端
isMobile () { isMobile() {
if (window.navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)) return true if(window.navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)) return true
return false return false
}, },
// 前置加0 // 前置加0
preZero (num) { preZero(num) {
return num > 9 ? num : `0${num}` return num > 9 ? num : `0${num}`
}, },
// 获取当前时间
getNow () {
return new Promise(async (resolve, reject) => {
const { data } = await axios.get(Setting.apiBaseURL + api.getCurrentTime, {
headers: {
token: sessionStorage.getItem('token')
}
})
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

@ -1,56 +0,0 @@
// 导出压缩包
import JSZip from 'jszip'
import FileSaver from 'file-saver'
//文件以流的形式获取(参数url为文件链接地址)
const getImgArrayBuffer = url => {
return new Promise((resolve, reject) => {
//通过请求获取文件blob格式
let xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', url, true);
xmlhttp.responseType = 'blob'
xmlhttp.onload = function () {
if (xmlhttp.status == 200) {
resolve(xmlhttp.response);
} else {
reject(xmlhttp.response);
}
};
xmlhttp.send();
});
}
/**
* @param {String} zipName 压缩包名字
* @param {Array} files 需要压缩的文件数组
* @param {Function | undefined} callback 回调
*/
export default function (zipName, files, callback) {
var zip = new JSZip();
var promises = [];
let cache = {};
for (let item of files) {
// item.filePath为文件链接地址
// item.fileName为文件名称
if(item.filePath) {
const promise = getImgArrayBuffer(item.filePath).then((data) => {
// 下载文件, 并存成ArrayBuffer对象(blob)
zip.file(item.fileName, data, { binary: true }); // 逐个添加文件
cache[item.fileName] = data;
});
promises.push(promise);
} else {
// 地址不存在时提示
console.log(`附件${item.fileName}地址错误,下载失败`);
}
}
Promise.all(promises).then(() => {
zip.generateAsync({ type: "blob" }).then((content) => {
// 生成二进制流
FileSaver.saveAs(content, zipName); // 利用file-saver保存文件 zipName: 自定义文件名
callback && callback()
});
}).catch((res) => {
console.log("文件压缩失败");
});
}

@ -4,279 +4,293 @@ import Router from 'vue-router';
Vue.use(Router); Vue.use(Router);
let router = new Router({ let router = new Router({
mode: 'hash', mode: 'hash',
base: process.env.BASE_URL, base: process.env.BASE_URL,
routes: [ routes: [
{ {
path: '/', path: '/',
redirect: '/login' redirect: '/login'
}, },
{ {
path: '/', path: '/',
component: () => import('../views/Home.vue'), component: () => import('../views/Home.vue'),
meta: { title: '自述文件' }, meta: { title: '自述文件' },
children: [ children: [
{ {
path: '/customer', path: '/customer',
component: () => import('../views/customer/customer.vue'), component: () => import( '../views/customer/customer.vue'),
}, // meta: { title: '客户管理' }
{ },
path: '/addcustomer', {
component: () => import('../views/customer/AddCustomer.vue'), path: '/addcustomer',
}, component: () => import( '../views/customer/AddCustomer.vue'),
{ // meta: { title: '新增客户' }
path: '/bmOrder', },
component: () => import('../views/customer/Order.vue'), {
}, path: '/bmOrder',
{ component: () => import( '../views/customer/Order.vue'),
path: '/user', // meta: { title: '新增客户' }
component: () => import('../views/user/User.vue'), },
}, {
{ path: '/user',
path: '/adduser', component: () => import( '../views/user/User.vue'),
component: () => import('../views/user/AddUser.vue'), // meta: { title: '用户管理' }
}, },
{ {
path: '/info', path: '/adduser',
component: () => import('../views/user/Info.vue'), component: () => import( '../views/user/AddUser.vue'),
}, // meta: { title: '新增用户' }
{ },
path: '/order', {
component: () => import('../views/order/Order.vue'), path: '/info',
}, component: () => import( '../views/user/Info.vue'),
{ // meta: { title: '新增用户' }
path: '/addorder', },
component: () => import('../views/order/AddOrder.vue'), {
}, path: '/order',
{ component: () => import( '../views/order/Order.vue'),
path: '/selectClient', // meta: { title: '订单管理' }
component: () => import('../views/order/selectClient.vue'), },
}, {
path: '/addorder',
component: () => import( '../views/order/AddOrder.vue'),
// meta: { title: '新增订单' }
},
{
path: '/selectClient',
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', {
component: () => import('../views/serve/backstage'), path: '/backstage',
}, component: () => import( '../views/serve/backstage'),
{ // meta: { title: '服务配置' }
path: '/addModel', },
component: () => import('../views/serve/addModel'), {
}, path: '/addModel',
{ component: () => import( '../views/serve/addModel'),
path: '/addconfigure', // meta: { title: '服务配置' }
component: () => import('../views/serve/AddConfigure.vue'), },
}, {
{ path: '/addconfigure',
path: '/projectList', component: () => import( '../views/serve/AddConfigure.vue'),
component: () => import('../views/serve/projectList.vue'), // meta: { title: '新增配置' }
}, },
{ {
path: '/projectAdd', path: '/projectList',
component: () => import('../views/serve/projectAdd.vue'), component: () => import( '../views/serve/projectList.vue'),
}, // meta: { title: '项目管理' }
{ },
path: '/curriculum', {
component: () => import('../views/course/Curriculum.vue'), path: '/projectAdd',
}, component: () => import( '../views/serve/projectAdd.vue'),
{ // meta: { title: '项目配置' }
path: '/addcurriculum', },
component: () => import('../views/course/AddCurriculum.vue'), {
}, path: '/curriculum',
{ component: () => import( '../views/course/Curriculum.vue'),
path: '/contentSettings', // meta: { title: '课程管理' }
component: () => import('../views/course/contentSettings.vue'), },
}, {
{ path: '/addcurriculum',
path: '/addlink', component: () => import( '../views/course/AddCurriculum.vue'),
component: () => import('../views/course/AddLink.vue'), // meta: { title: '新建课程' }
}, },
{ {
path: '/data', path: '/contentSettings',
component: () => import('../views/data/Data.vue'), component: () => import( '../views/course/contentSettings.vue'),
}, // meta: { title: '内容设置' }
{ },
path: '/match', {
component: () => import('../views/match/list'), path: '/addlink',
}, component: () => import( '../views/course/AddLink.vue'),
{ // meta: { title: '添加环节' }
path: '/addMatch', },
component: () => import('../views/match/add'), {
}, path: '/data',
{ component: () => import( '../views/data/Data.vue'),
path: '/matchManage', // meta: { title: '数据管理' }
component: () => import('../views/match/manage'), },
}, {
{ path: '/match',
path: '/noticeDetail', component: () => import( '../views/match/list'),
component: () => import('../views/match/manage/noticeDetail'), // meta: { title: '数据管理' }
}, },
{ {
path: '/otherArchList', path: '/addMatch',
component: () => import('../views/match/manage/otherArchList'), component: () => import( '../views/match/add'),
}, // meta: { title: '数据管理' }
{ },
path: '/matchRank', {
component: () => import('../views/match/manage/matchRank'), path: '/matchManage',
}, component: () => import( '../views/match/manage'),
{ // meta: { title: '数据管理' }
path: '/trialReport', },
component: () => import('../views/match/manage/trialReport'), {
}, path: '/noticeDetail',
{ component: () => import( '../views/match/manage/noticeDetail'),
path: '/matchArchList', // meta: { title: '数据管理' }
component: () => import('../views/match/manage/matchArchList'), },
}, {
{ path: '/matchArchList',
path: '/theoryReport', component: () => import( '../views/match/manage/matchArchList'),
component: () => import('../views/match/manage/theoryReport'), // meta: { title: '数据管理' }
}, },
{ {
path: '/matchInfo', path: '/matchRank',
component: () => import('../views/match/manage/matchInfo'), component: () => import( '../views/match/manage/matchRank'),
}, // meta: { title: '数据管理' }
{ },
path: `/theoreticalCourse`, {
component: () => import("../views//theoreticalCourse/list"), path: '/matchReport',
meta: { title: "理论课程" } component: () => import( '../views/match/manage/matchReport'),
}, // meta: { title: '数据管理' }
{ },
path: `/addTheoreticalCourse`, {
component: () => import("../views//theoreticalCourse/add"), path: '/matchInfo',
meta: { title: "理论课程详情" } component: () => import( '../views/match/manage/matchInfo'),
}, // meta: { title: '数据管理' }
{ },
path: `/previewTheoreticalCourse`, {
component: () => import("../views//theoreticalCourse/preview"), path: `/theoreticalCourse`,
meta: { title: "理论课程预览" } component: () => import("../views//theoreticalCourse/list"),
}, meta: { title: "理论课程" }
{ },
path: `/setTheoreticalCourse`, {
component: () => import("../views//theoreticalCourse/contentSettings"), path: `/addTheoreticalCourse`,
meta: { title: "理论课程内容设置" } component: () => import("../views//theoreticalCourse/add"),
}, meta: { title: "理论课程详情" }
{ },
path: `/information`, {
component: () => import("../views//information/list"), path: `/previewTheoreticalCourse`,
meta: { title: "资讯管理" } component: () => import("../views//theoreticalCourse/preview"),
}, meta: { title: "理论课程预览" }
{ },
path: `/addArticle`, {
component: () => import("../views//information/addArticle"), path: `/setTheoreticalCourse`,
meta: { title: "新增文章" } component: () => import("../views//theoreticalCourse/contentSettings"),
}, meta: { title: "理论课程内容设置" }
{ },
path: '/system', {
component: () => import('../views/system'), path: `/information`,
}, component: () => import("../views//information/list"),
{ meta: { title: "资讯管理" }
path: '/manageLog', },
component: () => import('../views/system/manageLog'), {
}, path: `/addArticle`,
{ component: () => import("../views//information/addArticle"),
path: '/addLog', meta: { title: "新增文章" }
component: () => import('../views/system/addLog'), },
}, {
{ path: '/system',
path: '/permission', component: () => import( '../views/system'),
component: () => import('../views/customer/Permission.vue'), // meta: { title: '数据管理' }
}, },
{ {
path: '/person', path: '/manageLog',
component: () => import('../views/setting'), component: () => import( '../views/system/manageLog'),
}, // meta: { title: '数据管理' }
{ },
path: '/parner', {
component: () => import('../views/parner'), path: '/addLog',
}, component: () => import( '../views/system/addLog'),
{ // meta: { title: '数据管理' }
path: '/parnerOperation', },
component: () => import('../views/parnerOperation'), {
}, path: '/permission',
{ component: () => import('../views/customer/Permission.vue'),
path: '/learnMg', // meta: { title: '应用权限', permission: true }
component: () => import('../views/parnerOperation/learnMg'), },
}, {
{ path: '/person',
path: '/schemeSet', component: () => import('../views/setting'),
component: () => import('../views/parnerOperation/schemeSet'), // meta: { title: '个人中心' }
}, },
{ {
path: '/shop', path: '/parner',
component: () => import('../views/shop/list'), component: () => import('../views/parner'),
}, // meta: { title: '个人中心' }
{ },
path: '/shop/addProduct', {
component: () => import('../views/shop/addProduct'), path: '/parnerOperation',
}, component: () => import('../views/parnerOperation'),
{ },
path: '/theoryExam/list', {
component: () => import('../views/theoryExam/list/index'), path: '/learnMg',
}, component: () => import('../views/parnerOperation/learnMg'),
{ },
path: '/theoryExam', {
component: () => import('../views/theoryExam'), path: '/schemeSet',
}, component: () => import('../views/parnerOperation/schemeSet'),
{ },
path: '/review', {
component: () => import('../views/review'), path: '/shop',
}, component: () => import('../views/shop/list'),
{ },
path: '/404', {
component: () => import('../views/404.vue'), path: '/shop/addProduct',
// meta: { title: '404' } component: () => import('../views/shop/addProduct'),
}, },
{ {
path: '/403', path: '/404',
component: () => import('../views/403.vue'), component: () => import('../views/404.vue'),
// meta: { title: '403' } // meta: { title: '404' }
},
{
path: '/403',
component: () => import('../views/403.vue'),
// meta: { title: '403' }
}
]
},
{
path: '/login',
component: () => import('../views/Login.vue'),
meta: { title: '登录' }
},
{
path: '/devLogin',
component: () => import('../views/devLogin.vue'),
meta: { title: '开发者登录' }
},
{
path: '/join',
component: () => import('../views/join'),
meta: { title: '城市合伙人运营管理平台' }
},
{
path: '/matchPreview',
component: () => import( '../views/match/preview'),
// meta: { title: '数据管理' }
},
{
path: '/success',
component: () => import('../views/join/success'),
meta: { title: '城市合伙人运营管理平台' }
},
{
path: '*',
redirect: '/404'
} }
] ]
},
{
path: '/login',
component: () => import('../views/Login.vue'),
meta: { title: '登录' }
},
{
path: '/devLogin',
component: () => import('../views/devLogin.vue'),
meta: { title: '开发者登录' }
},
{
path: '/join',
component: () => import('../views/join'),
meta: { title: '城市合伙人运营管理平台' }
},
{
path: '/matchPreview',
component: () => import('../views/match/preview'),
// meta: { title: '数据管理' }
},
{
path: '/success',
component: () => import('../views/join/success'),
meta: { title: '城市合伙人运营管理平台' }
},
{
path: '*',
redirect: '/404'
}
]
}); });
router.beforeEach(function (to, from, next) { router.beforeEach(function(to, from, next) {
// 根据路由元信息设置文档标题 // 根据路由元信息设置文档标题
window.document.title = to.meta.title || '中台'; window.document.title = to.meta.title || '中台';
//使用钩子函数对路由进行权限跳转 //使用钩子函数对路由进行权限跳转
const login = location.href.includes('dev.huorantech.cn') ? '/devLogin' : '/login' const login = location.href.includes('dev.huorantech.cn') ? '/devLogin' : '/login'
if (!sessionStorage.getItem('token') && to.path !== login && to.path !== '/join' && to.path !== '/success') { if (!sessionStorage.getItem('token') && to.path !== login && to.path !== '/join' && to.path !== '/success') {
next(login); next(login);
} else { } else {
next(); next();
} }
}); });
export default router; export default router;

@ -5,57 +5,51 @@ 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}/panfen/` let jumpPath = `${location.origin}/judgmentPoint`
let sandPath = `http://121.37.12.51/sandbox` // 沙盘地址
let host = `${location.origin}/` let host = `${location.origin}/`
if (isDev) { if (isDev) {
jumpPath = 'http://192.168.31.125:8087/' // 本地调试-需要启动本地判分点系统 jumpPath = 'http://192.168.31.125:8087/' // 本地调试-需要启动本地判分点系统
// jumpPath = 'https://judgment.huorantech.cn/'
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/'
const ips = ['http://192.168.31.217:9000/', 'http://192.168.31.51:9000/', 'http://121.37.12.51/'] // host = 'http://192.168.31.217:9000/'// 榕
host = ips[+localStorage.getItem('ip')] // host = 'http://192.168.31.51:9000/'// 赓
} else if (isPro) { } else if (isPro) {
sandPath = `https://izhixinyun.com/sandbox` jumpPath = 'https://www.huorantech.cn/judgmentPoint/'
// jumpPath = 'https://judgment.huorantech.cn/'
} }
const Setting = { const Setting = {
/** /**
* 基础配置 * 基础配置
* */ * */
platformId: 3, // 平台标识,1职站,2数据平台,3中台,4合伙人 platformId: 3, // 平台标识,1职站,2数据平台,3中台,4合伙人
platformSource: 0, // 平台来源(0中台,1职站) platformSource: 0, // 平台来源(0中台,1职站)
autoLogoutTime: 1000 * 60 * 60 * 3, // 长时间未操作,自动退出登录时间 jumpPath, // 判分点系统跳转路径前缀
jumpPath, // 判分点系统跳转路径前缀 apiBaseURL: host, // 请求路径前缀
sandPath, // 沙盘地址 uploadURL: isDev ? 'http://121.37.12.51/' : location.origin + '/', // 阿里云oss域名
apiBaseURL: host, // 请求路径前缀 // 平台列表
uploadURL: isDev ? 'http://121.37.12.51/' : location.origin + '/', // 阿里云oss域名 platformList: [
// 平台列表 {
platformList: [ id: 1,
{ name: '职站'
id: 1, },
name: '职站' {
}, id: 2,
{ name: '数据平台'
id: 2, },
name: '数据平台' {
}, id: 3,
{ name: '中台'
id: 3, }
name: '中台' ],
} isDev,
], isPro,
isDev, // 是否使用动态路由
isPro, dynamicRoute: true,
// 是否使用动态路由 /**
dynamicRoute: true, * @description 默认密码
/** */
* @description 默认密码 initialPassword: '1122aa',
*/
initialPassword: '1122aa',
}; };
export default Setting; export default Setting;

@ -21,13 +21,14 @@ const store = new Vuex.Store({
projectFields: {}, projectFields: {},
btns: [], btns: [],
routes: [], routes: [],
customerPage: 1,
matchPage: 1,
platformSource: 0,
columnId: '', columnId: '',
tabId: '1', tabId: '1',
dataPer: [], dataPer: [],
competitionCache: null, orderParam: null,
referrer: '', competitionCache: null
innerReferrer: '',
orderParam: null,
}, },
actions: { actions: {
setSystemId({ state,commit },systemId) { setSystemId({ state,commit },systemId) {
@ -53,6 +54,15 @@ const store = new Vuex.Store({
SET_USERNAME (state, userName) { SET_USERNAME (state, userName) {
state.userName = userName state.userName = userName
}, },
SET_C_PAGE: (state, page) => {
state.customerPage = page
},
SET_M_PAGE: (state, page) => {
state.matchPage = page
},
SET_M_SOURCE: (state, platformSource) => {
state.platformSource = platformSource
},
courseData (state, payload) { courseData (state, payload) {
state.courseId = payload.course_id state.courseId = payload.course_id
}, },
@ -65,6 +75,10 @@ const store = new Vuex.Store({
configData (state, payload) { configData (state, payload) {
state.configId = payload.config_id state.configId = payload.config_id
}, },
systemData (state, payload) {
state.systemId = payload.system_id
state.orderId = payload.order_id
},
userLoginData (state, payload) { userLoginData (state, payload) {
state.userLoginId = payload.userLogin_id state.userLoginId = payload.userLogin_id
state.userName = payload.userName state.userName = payload.userName
@ -91,18 +105,12 @@ const store = new Vuex.Store({
setInfoTab: (state, tabId) => { setInfoTab: (state, tabId) => {
state.tabId = tabId state.tabId = tabId
}, },
setOrderParam: (state, orderParam) => {
state.orderParam = orderParam
},
setCompetitionCache: (state, param) => { setCompetitionCache: (state, param) => {
state.competitionCache = param state.competitionCache = param
}, },
setReferrer: (state, val) => {
state.referrer = val
},
setInnerReferrer: (state, val) => {
state.innerReferrer = val
},
setOrderParam: (state, val) => {
state.orderParam = val
},
} }
}); });

File diff suppressed because it is too large Load Diff

@ -1,3 +1,5 @@
import { Loading } from 'element-ui'
const pad2 = str => ('0' + str).substr(-2) const pad2 = str => ('0' + str).substr(-2)
function fMoney (s, n) { function fMoney (s, n) {
@ -203,6 +205,7 @@ function formatDate(fmt,date) {
// 传入文件名和路径,下载图片视频,支持跨域,a标签加download不支持跨域 // 传入文件名和路径,下载图片视频,支持跨域,a标签加download不支持跨域
function downloadFile(fileName, url) { function downloadFile(fileName, url) {
const loadIns = Loading.service()
var x = new XMLHttpRequest() var x = new XMLHttpRequest()
x.open("GET", url, true) x.open("GET", url, true)
x.responseType = "blob" x.responseType = "blob"
@ -212,6 +215,7 @@ function downloadFile(fileName, url) {
a.href = url a.href = url
a.download = fileName a.download = fileName
a.click() a.click()
loadIns.close()
} }
x.send() x.send()
} }

@ -1,14 +1,16 @@
import Oss from '@/components/upload/upload.js' import Axios from 'axios'
import Api from '@/utils/api'
import Setting from '@/setting'
import Util from '@/libs/util'
import { Loading } from 'element-ui' import { Loading } from 'element-ui'
export default { 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 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', 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',
toolbar: 'code undo redo restoredraft | cut copy pastetext | forecolor backcolor headings fontsize lineHeight bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify | \ toolbar: 'code undo redo restoredraft | cut copy powerpaste 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', table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | indent2em formatpainter',
style_formats: [ style_formats: [
//新增 首行缩进与行高 配置 //新增 首行缩进与行高 配置
{ {
@ -21,40 +23,40 @@ export default {
{ {
title: '行高', title: '行高',
items: [{ items: [{
title: '1', title: '1',
styles: { styles: {
'line-height': '1' 'line-height': '1'
},
inline: 'span'
}, },
inline: 'span' {
}, title: '1.5',
{ styles: {
title: '1.5', 'line-height': '1.5'
styles: { },
'line-height': '1.5' inline: 'span'
},
inline: 'span'
},
{
title: '2',
styles: {
'line-height': '2'
}, },
inline: 'span' {
}, title: '2',
{ styles: {
title: '2.5', 'line-height': '2'
styles: { },
'line-height': '2.5' inline: 'span'
}, },
inline: 'span' {
}, title: '2.5',
{ styles: {
title: '3', 'line-height': '2.5'
styles: { },
'line-height': '3' inline: 'span'
}, },
inline: 'span' {
} title: '3',
styles: {
'line-height': '3'
},
inline: 'span'
}
] ]
}, },
//默认的配置 //默认的配置
@ -187,26 +189,125 @@ export default {
fontsize_formats: '12px 14px 16px 19px 24px 36px 48px 56px 72px', fontsize_formats: '12px 14px 16px 19px 24px 36px 48px 56px 72px',
font_formats: '苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats;知乎配置=BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei, sans-serif;小米配置=Helvetica Neue,Helvetica,Arial,Microsoft Yahei,Hiragino Sans GB,Heiti SC,WenQuanYi Micro Hei,sans-serif', font_formats: '苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats;知乎配置=BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei, sans-serif;小米配置=Helvetica Neue,Helvetica,Arial,Microsoft Yahei,Hiragino Sans GB,Heiti SC,WenQuanYi Micro Hei,sans-serif',
link_list: [ link_list: [
{ title: '预置链接1', value: 'http://www.tinymce.com' }, { title: '预置链接1', value: 'http://www.tinymce.com' },
{ title: '预置链接2', value: 'http://tinymce.ax-z.cn' } { title: '预置链接2', value: 'http://tinymce.ax-z.cn' }
], ],
image_list: [ image_list: [
{ title: '预置图片1', value: 'https://www.tiny.cloud/images/glyph-tinymce@2x.png' }, { title: '预置图片1', value: 'https://www.tiny.cloud/images/glyph-tinymce@2x.png' },
{ title: '预置图片2', value: 'https://www.baidu.com/img/bd_logo1.png' } { title: '预置图片2', value: 'https://www.baidu.com/img/bd_logo1.png' }
], ],
image_class_list: [ image_class_list: [
{ title: 'None', value: '' }, { title: 'None', value: '' },
{ title: 'Some class', value: 'class-name' } { title: 'Some class', value: 'class-name' }
], ],
//importcss_append: true,
//自定义文件选择器的回调内容
file_picker_callback: function (callback, value, meta) {
if (meta.filetype === 'file') {
callback('https://www.baidu.com/img/bd_logo1.png', { text: 'My text' });
}
if (meta.filetype === 'image') {
callback('https://www.baidu.com/img/bd_logo1.png', { alt: 'My alt text' });
}
if (meta.filetype === 'media') {
callback('movie.mp4', { source2: 'alt.ogg', poster: 'https://www.baidu.com/img/bd_logo1.png' });
}
},
//为内容模板插件提供预置模板 //为内容模板插件提供预置模板
templates: [], templates: [
{ title: '中文文章模板1', description: '图片文字流', content: `
<div class="tiny-wrap">
<div class="block">
<div class="fl">
<img class="pic" src="images/default.png"/>
<p class="img-des">图片描述</p>
</div>
<div class="texts">
<p>S³FEL主要由一台超导直线加速器波荡器光束线和实验站组成可产生重复频率达1MHz电子束能量达2.5 GeV的软X 射线自由电子激光可在百飞秒内级实现原子分子及外壳层电子结构的无损动态监测是科学家认识和了解物质微观结构及动态变化的高速摄像机S³FEL为科学家和企业用户提供了一种具有超高时间分辨空间分辨和能量分辨的新方法新技术 S³FEL在量子材料能源催化生物医药大气与星际科学原子分子科学等领域的应用研究将为促进我国战略性新兴产业创新发展和关键S³FEL主要由一台超导直线加速器波荡器光束线和实验站组成可产生重复频率达1MHz电子束能量达2.5 GeV的软X 射线自由电子激光可在百飞秒内级实现原子分子及外壳层电子结构的无损动态监测是科学家认识和了解物质微观结构及动态变化的高速摄像机S³FEL为科学家和企业用户提供了一种具有超高时间分辨空间分辨和能量分辨的新方法新技术 S³FEL在量子材料能源催化生物医药大气与星际科学原子分子科学等领域的应用研究将为促进我国战略性新兴产业创新发展和关键S³FEL主要由一台超导直线加速器波荡器光束线和实验站组成可产生重复频率达1MHz电子束能量达2.5 GeV的软X 射线自由电子激光可在百飞秒内级实现原子分子及外壳层电子结构的无损动态监测是科学家认识和了解物质微观结构及动态变化的高速摄像机S³FEL为科学家和企业用户提供了一种具有超高时间分辨空间分辨和能量分辨的新方法新技术 S³FEL在量子材料能源催化生物医药大气与星际科学原子分子科学等领域的应用研究将为促进我国战略性新兴产业创新发展和关键S³FEL主要由一台超导直线加速器波荡器光束线和实验站组成可产生重复频率达1MHz电子束能量达2.5 GeV的软X 射线自由电子激光可在百飞秒内级实现原子分子及外壳层电子结构的无损动态监测是科学家认识和了解物质微观结构及动态变化的高速摄像机S³FEL在量子材料能源催化生物医药大气与星际科学原子分子科学等领域的应用研究将为促进我国战略性新兴产业创新发展和关键S³FEL主要由一台超导直线加速器波荡器光束线和实验站组成可产生重复频率达1MHz电子束能量达2.5 GeV的软X 射线自由电子激光可在百飞秒内级实现原子分子及外壳层电子结构的无损动态监测是科学家认识和了解物质微观结构及动态变化的高速摄像机
</p>
</div>
</div>
<div class="block">
<div class="fr">
<img class="pic" src="images/default.png"/>
<p class="img-des">图片描述</p>
</div>
<div>
<p>集聚世界前沿和原创性科学技术及产业研发将推动一批高水平大学和科研机构的科技人才队伍建设及相关学科的高质量发展营造粤港澳大湾区人才高地并助力粤港澳大湾区国际科技创新中心的建设此外 S³FEL作为重要的科普教育基地</p>
<p>S³FEL汇聚并培养信息生命材料能源等学科领域的国际水平科技领军人才集聚世界前沿和原创性科学技术及产业研发将推动一批高水平大学和科研机构的科技人才队伍建设及相关学科的高质量发展营造粤港澳大湾区人才高地并助力粤港澳大湾区国际科技创新中心的建设此外 S³FEL作为重要的科普教育基地是展示我国科技实力提高全民族科学素质和民族自信的重要宣传窗口 S³FEL主体建筑将成为深圳市地标式建筑促进提升深圳市的城市形象和国际化知名度S³FEL汇聚并培养信息生命材料能源等学科领域的国际水平科技领军人才集聚世界前沿和原创性科学技术及产业研发将推动一批高水平大学和科研机构的科技人才队伍建设及相关学科的高质量发展营造粤港澳大湾区人才高地并助力粤港澳大湾区国际科技创新中心的建设此外 S³FEL作为重要的科普教育基地是展示我国科技实力提高全民族科学素质和民族自信的重要宣传窗口 S³FEL主体建筑将成为深圳市地标式建筑促进提升深圳市的城市形象和国际化知名度S³FEL汇聚并培养信息生命材料能源等学科领域的国际水平科技领军人才集聚世界前沿和原创性科学技术及产业研发将推动一批高水平大学和科研机构的科技人才队伍建设及相关学科的高质量发展营造粤港澳大湾区人才高地并助力粤港澳大湾区国际科技创新中心的建设此外 S³FEL作为重要的科普教育基地是展示我国科技实力提高全民族科学素质和民族自信的重要宣传窗口 S³FEL主体建筑将成为深圳市地标式建筑促进提升深圳市的城市形象和国际化知名度</p>
</div>
</div>
</div>
`
},
{ title: '英文文章模板1', description: '图片文字流', content: `
<div class="tiny-wrap">
<div class="block en-block">
<div class="fr">
<img class="pic" src="images/default.png"/>
<p class="img-des">Picture description</p>
</div>
<div>
<p>One of the major barriers to treating pain effectively is rooted in providers fear of killing their patients. This includes caregivers who may be family or friends. In a 2014 study I led of nonprofessional hospice caregivers, we found that the majority of pain medication errors caregivers made involved administering less than the prescribed dose, which makes it difficult for patients to achieve optimal pain relief.</p>
<p>Meanwhile, more than 11 million Americans  often family members or friends provide unpaid care for people with Alzheimer's or other dementias, according to calculations by the Alzheimers Association. In 2021, caregivers for people with Alzheimers or other dementias provided an estimated 16 billion hours of unpaid care valued at nearly $272 billion.My father took her to the emergency room. A doctor found a severe knee infection and took her into surgery. She was hospitalized for two weeks, followed by two months of rehabilitation at a skilled nursing facility.</p>
<p>If you heated the salt on your kitchen table up to 801 C (1,474 F), it would melt, and youd have molten salt. However, for making and storing energy, not just any salt will do. Scientists are exploring different combinations of salts to get the exact properties needed to cool and fuel a nuclear power reactor efficiently for decades. These properties include lower melting temperatures, the right consistency, and the ability to absorb high amounts of heat, among others.</p>
<div class="quote">We used experimental results to validate our simulation. At the same time, the simulation results provided us more details about which salts to study further. They work with each other. Jicheng Guo, chemical engineer at Argonne National Laboratory</div>
<p>Which molten salt blueprints will deliver the desired traits for a nuclear reactor? The potential variations are nearly endless. The study set out to determine whether computer simulations driven by machine learning could guide and refine real-world experiments at the Advanced Photon Source (APS), a DOE Office of Science user facility at Argonne. The results were recently published in the journal Physical Review B.</p>
<p>We used experimental results from the APS to validate our simulation. At the same time, the simulation results provided us more details about which salts to study further. They work with each other, said Jicheng Guo, a chemical engineer at Argonne and the papers lead author. This allows us to study multiple compositions at the same time.</p>
</div>
</div>
</div>
`
},
{ title: '新闻模板', description: '', content: `
<div class="tiny-wrap">
<div class="block" style="margin-bottom: 70px;">
<div class="fr">
<img class="pic" src="images/default.png"/>
<p class="img-des">图片描述</p>
</div>
<div>
<p style="text-indent: 2em">S³FEL汇聚并培养信息生命材料能源等学科领域的国际水平科技领军人才集聚世界前沿和原创性科学技术及产业研发将推动一批高水平大学和科研机构的科技人才队伍建设及相关学科的高质量发展营造粤港澳大湾区人才高地并助力粤港澳大湾区国际科技创新中心的建设此外 S³FEL作为重要的科普教育基地是展示我国科技实力提高全民族科学素质和民族自信的重要宣传窗口 S³FEL主体建筑将成为深圳市地标式建筑促进提升深圳市的城市形象和国际化知名度S³FEL汇聚并培养信息生命材料能源等学科领域的国际水平科技领军人才集聚世界前沿和原创性科学技术及产业研发将推动一批高水平大学和科研机构的科技人才队伍建设及相关学科的高质量发展营造粤港澳大湾区人才高地并助力粤港澳大湾区国际科技创新中心的建设此外 S³FEL作为重要的科普教育基地是展示我国科技实力提高全民族科学素质和民族自信的重要宣传窗口 S³FEL主体建筑将成为深圳市地标式建筑促进提升深圳市的城市形象和国际化知名度S³FEL汇聚并培养信息生命材料能源等学科领域的国际水平科技领军人才集聚世界前沿和原创性科学技术及产业研发将推动一批高水平大学和科研机构的科技人才队伍建设及相关学科的高质量发展营造粤港澳大湾区人才高地并助力粤港澳大湾区国际科技创新中心的建设此外 S³FEL作为重要的科普教育基地是展示我国科技实力提高全民族科学素质和民族自信的重要宣传窗口 S³FEL主体建筑将成为深圳市地标式建筑促进提升深圳市的城市形象和国际化知名度</p>
<div class="quote">
Here is a long quotation here is a long quotation here is a long quotation
here is a long quotation here is a long quotation here is a long quotation
here is a long quotation here is a long quotation here is a long quotation.
</div>
</div>
</div>
<div class="block">
<div class="img-wrap">
<img class="pic" src="images/default.png"/>
<p class="img-des">图片描述</p>
</div>
<div class="texts">
<h6 class="tiny-title">小标题</h6>
<p style="text-indent: 2em">S³FEL主要由一台超导直线加速器波荡器光束线和实验站组成可产生重复频率达1MHz电子束能量达2.5 GeV的软X 射线自由电子激光可在百飞秒内级实现原子分子及外壳层电子结构的无损动态监测是科学家认识和了解物质微观结构及动态变化的高速摄像机S³FEL为科学家和企业用户提供了一种具有超高时间分辨空间分辨和能量分辨的新方法新技术 S³FEL在量子材料能源催化生物医药大气与星际科学原子分子科学等领域的应用研究将为促进我国战略性新兴产业创新发展和关键S³FEL主要由一台超导直线加速器波荡器光束线和实验站组成可产生重复频率达1MHz电子束能量达2.5 GeV的软X 射线自由电子激光可在百飞秒内级实现原子分子及外壳层电子结构的无损动态监测是科学家认识和了解物质微观结构及动态变化的高速摄像机S³FEL为科学家和企业用户提供了一种具有超高时间分辨空间分辨和能量分辨的新方法新技术 S³FEL在量子材料能源催化生物医药大气与星际科学原子分子科学等领域的应用研究将为促进我国战略性新兴产业创新发展和关键
</p>
</div>
</div>
</div>
`
},
{ title: '图片描述', description: '', content: `
<div class="tiny-wrap">
<div class="block">
<div class="img-wrap">
<img class="pic" src="images/default.png"/>
<p class="img-des">图片描述</p>
</div>
</div>
</div>
`
}
],
// content_security_policy: "https://cdn.tiny.cloud/1/rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda/tinymce/6/tinymce.min.js", // content_security_policy: "https://cdn.tiny.cloud/1/rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda/tinymce/6/tinymce.min.js",
// extended_valid_elements:'script[src]', // extended_valid_elements:'script[src]',
// //
// template_cdate_format: '[CDATE: %m/%d/%Y : %H:%M:%S]', // template_cdate_format: '[CDATE: %m/%d/%Y : %H:%M:%S]',
// template_mdate_format: '[MDATE: %m/%d/%Y : %H:%M:%S]', // template_mdate_format: '[MDATE: %m/%d/%Y : %H:%M:%S]',
// autosave_ask_before_unload: false, // autosave_ask_before_unload: false,
toolbar_mode: 'wrap', toolbar_mode : 'wrap',
// automatic_uploads: true, // automatic_uploads: true,
// images_upload_base_path: '/demo', // images_upload_base_path: '/demo',
// images_upload_url: 'http://10.10.11.7:10000/iasf/sysFiles/upload', // images_upload_url: 'http://10.10.11.7:10000/iasf/sysFiles/upload',
@ -214,25 +315,57 @@ export default {
powerpaste_allow_local_images: true, powerpaste_allow_local_images: true,
powerpaste_word_import: 'clean', powerpaste_word_import: 'clean',
powerpaste_html_import: 'clean', powerpaste_html_import: 'clean',
urlconverter_callback: (url, node, onSave, name) => { extraPlugins: 'uploadimage',
if (node === 'img' && url.startsWith('blob:')) { imageUploadUrl: Api.fileUploadNakadai,
// Do some custom URL conversion init_instance_callback: function (editor) {
tinymce.activeEditor && tinymce.activeEditor.uploadImages() editor.on('paste', (evt) => {
} // 监听粘贴事件
// Return new URL // 实现图片粘贴上传
return url const items = (evt.clipboardData || window.clipboardData).items
}, if (items[0].type.indexOf('image') !== -1) {
const file = items[0].getAsFile()
const form = new FormData()
form.append('file', file)
// 自定义上传图片的方法
Axios({
method: 'post',
url: Api.fileUploadNakadai,
data: form,
headers: {
'Content-Type': 'multipart/form-data',
token: Util.local.get(Setting.tokenKey)
},
}).then(({ data }) => {
// 使用指令,在当前鼠标标光的位置插入元素
// img元素的src就是远程图片的链接地址
editor.execCommand(
"mceReplaceContent",
true,
`<img style="max-width:500px;" src="${data.filesResult.fileUrl}" >`
);
}).catch(res => {})
// 阻止默认事件,防止粘贴的图片进入富文本编辑器中
evt.preventDefault();
} else {
console.log('粘贴的不是图片,不能上传')
}
})
},
// 自定义上传 // 自定义上传
images_upload_handler: function (blobInfo, succFun, failFun) { images_upload_handler: function (blobInfo, succFun, failFun) {
const blob = blobInfo.blob() const form = new FormData()
// blob转换为file form.append('file', blobInfo.blob())
const file = new File([blob], blobInfo.filename(), { Axios({
type: 'application/json', method: 'post',
lastModified: Date.now() url: Api.fileUploadNakadai,
}); data: form,
Oss.upload(file).then(res => { headers: {
succFun(res.url) 'Content-Type': 'multipart/form-data',
}) token: Util.local.get(Setting.tokenKey)
},
}).then(({ data }) => {
succFun(data.filesResult.fileUrl)
}).catch(res => {})
}, },
//自定义文件选择器的回调内容 此方法只有在点击上方图片按钮才会触发 //自定义文件选择器的回调内容 此方法只有在点击上方图片按钮才会触发
file_picker_callback: function (callback, value, meta) { file_picker_callback: function (callback, value, meta) {
@ -248,13 +381,23 @@ export default {
let input = document.createElement('input');//创建一个隐藏的input let input = document.createElement('input');//创建一个隐藏的input
input.setAttribute('type', 'file'); input.setAttribute('type', 'file');
input.setAttribute("accept", ".mp4"); input.setAttribute("accept", ".mp4");
input.onchange = function () { input.onchange = function(){
let file = this.files[0]; let file = this.files[0];
let fd = new FormData();
fd.append("file", file);
const load = Loading.service() const load = Loading.service()
Oss.upload(file).then(res => { Axios({
method: 'post',
url: Api.fileUploadNakadai,
data: fd,
headers: {
'Content-Type': 'multipart/form-data',
token: Util.local.get(Setting.tokenKey)
},
}).then(({ data }) => {
load.close() load.close()
callback(res.url) callback(data.filesResult.fileUrl)
}).catch(e => { }).catch(res => {
load.close() load.close()
}) })
} }
@ -263,11 +406,11 @@ export default {
} }
}, },
// 初始化事件 // 初始化事件
setup: function (editor) { setup: function(editor) {
editor.on('init', function (ed) { editor.on('init', function(ed) {
// 设置默认字体 // 设置默认字体
ed.target.editorCommands.execCommand("fontName", false, "PingFang SC") ed.target.editorCommands.execCommand("fontName", false, "Microsoft Yahei")
ed.target.editorCommands.execCommand("fontSize", false, "16px") ed.target.editorCommands.execCommand("fontSize", false, "19px")
ed.target.editorCommands.execCommand("lineHeight", false, "1.5") ed.target.editorCommands.execCommand("lineHeight", false, "1.5")
const el = top.document.querySelector('#focus-el') const el = top.document.querySelector('#focus-el')
el && el.focus() // 第一个字段聚焦 el && el.focus() // 第一个字段聚焦

@ -13,182 +13,162 @@ axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
// 请求拦截器 // 请求拦截器
axios.interceptors.request.use(config => { axios.interceptors.request.use(config => {
let token = sessionStorage.getItem('token') let token = sessionStorage.getItem('token')
if (token) { if(token){
config.headers.token = token config.headers.token = token
}
let schoolId = store.state.schoolId
if (schoolId) config.headers.schoolId = store.state.schoolId
return config;
}, err => {
Message.error({
message: '退出登陆',
onClose: function () {
router.push({ name: 'login' });
} }
}) let schoolId = store.state.schoolId
return Promise.reject(err); if(schoolId) config.headers.schoolId = store.state.schoolId
return config;
}, err => {
Message.error({
message: '退出登陆',
onClose: function () {
router.push({name: 'login'});
}
})
return Promise.reject(err);
}) })
let logouted = 0;
// 响应拦截器 // 响应拦截器
axios.interceptors.response.use( axios.interceptors.response.use(
response => { response => {
if (response.status === 200) { if (response.status === 200) {
const { status, code, msg } = response.data const { status } = response.data
if (status) { if (status) {
// 接口定义的非正常返回的时候,应当处于报错状态 // 接口定义的非正常返回的时候,应当处于报错状态
if (status === 10020) { if (status === 10020) {
// 该状态为用户列表启用用户的接口返回的状态,特殊处理 // 该状态为用户列表启用用户的接口返回的状态,特殊处理
return Promise.reject(response) return Promise.reject(response)
} else if (status !== 200) { } else if (status !== 200) {
Message.error(response.data.message) Message.error(response.data.message)
return Promise.reject(response) return Promise.reject(response)
} else {
return Promise.resolve(response)
}
} else {
return Promise.resolve(response)
}
} else { } else {
return Promise.resolve(response) Message.error(response.message,'res');
return Promise.reject(response);
} }
} else if (code === 401) { },
// 账号互踢 // 服务器状态码不是200的情况
if (!logouted) { error => {
sessionStorage.removeItem('token') if (error.response.status) {
Message.error(msg.includes('顶') ? '您的账号已在其他设备登录,您已被迫下线!' : '登录过期,请重新登录!') switch (error.response.status) {
setTimeout(() => { // 401: 未登录
router.replace({ // 未登录则跳转登录页面,并携带当前页面的路径
path: '/login', // 在登录成功后返回当前页面,这一步需要在登录页操作。
query: { case 401:
redirect: router.currentRoute.fullPath Message.error('登录过期,请重新登录!');
} setTimeout(() => {
}) router.replace({
logouted = 0 path: '/login',
}, 1500) query: {
logouted = 1 redirect: router.currentRoute.fullPath
}
});
}, 1000);
break;
// 403 token过期
// 登录过期对用户进行提示
// 清除本地token和清空vuex中token对象
// 跳转登录页面
case 403:
// 清除token
sessionStorage.removeItem('token');
store.commit('loginSuccess', null);
// 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
setTimeout(() => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
}, 1000);
break;
// 404请求不存在
case 404:
Message.error('404网络请求不存在!');
break;
case 500:// 网络错误
Message.error('网络错误!');
// router.replace({
// path: '/login',
// query: { redirect: router.currentRoute.fullPath }
// });
break;
// 其他错误,直接抛出错误提示
default:
Message.error(error.response.data.message);
break;
}
return Promise.reject(error.response);
} }
} else {
return Promise.resolve(response)
}
} else {
Message.error(response.message, 'res');
return Promise.reject(response);
}
},
// 服务器状态码不是200的情况
error => {
if (error.response.status) {
switch (error.response.status) {
// 401: 未登录
// 未登录则跳转登录页面,并携带当前页面的路径
// 在登录成功后返回当前页面,这一步需要在登录页操作。
case 401:
if (!logouted) {
Message.error('登录过期,请重新登录!');
setTimeout(() => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
}, 1000);
logouted = 1
}
break;
// 403 token过期
// 登录过期对用户进行提示
// 清除本地token和清空vuex中token对象
// 跳转登录页面
case 403:
// 清除token
sessionStorage.removeItem('token');
store.commit('loginSuccess', null);
// 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
setTimeout(() => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
}, 1000);
break;
// 404请求不存在
case 404:
Message.error('404网络请求不存在!');
break;
case 500:// 网络错误
Message.error('网络错误!');
// router.replace({
// path: '/login',
// query: { redirect: router.currentRoute.fullPath }
// });
break;
// 其他错误,直接抛出错误提示
default:
Message.error(error.response.data.message);
break;
}
return Promise.reject(error.response);
} }
}
); );
function logouts () { function logouts(){
store.replaceState({}) store.replaceState({})
localStorage.clear() localStorage.clear()
sessionStorage.clear() sessionStorage.clear()
location.reload() location.reload()
} }
let tokenStatus = { let tokenStatus = {
0: '用户未登录,请登录后操作!', 0: '用户未登录,请登录后操作!',
1: 'token错误,请重新登录!' 1: 'token错误,请重新登录!'
} }
/** /**
* get方法对应get请求 * get方法对应get请求
*/ */
export function get (url, params) { export function get(url, params){
return new Promise((resolve, reject) => { return new Promise((resolve, reject) =>{
axios.get(url, { axios.get(url, {
params: params params: params
}) })
.then(res => { .then(res => {
resolve(res.data) resolve(res.data)
}) })
.catch(err => { .catch(err => {
reject(err.data) reject(err.data)
}) })
}); });
} }
/** /**
* post方法对应post请求 * post方法对应post请求
*/ */
export function post (url, params, config) { export function post(url, params, config) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
axios.post(url, params, config) axios.post(url,params, config)
.then(res => { .then(res => {
return resolve(res.data); return resolve(res.data);
}) })
.catch(err => { .catch(err => {
return reject(err.data) return reject(err.data)
}) })
}); });
} }
/** /**
* delete方法对应delete请求 * delete方法对应delete请求
*/ */
export function del (url, params) { export function del(url, params){
return new Promise((resolve, reject) => { return new Promise((resolve, reject) =>{
axios.delete(url, { axios.delete(url, {
params: params params: params
}) })
.then(res => { .then(res => {
resolve(res.data); resolve(res.data);
}) })
.catch(err => { .catch(err => {
reject(err.data) reject(err.data)
}) })
}); });
} }
/** /**
@ -196,14 +176,14 @@ export function del (url, params) {
* @param {} url * @param {} url
* @param {*} params * @param {*} params
*/ */
export function put (url, params) { export function put(url, params){
return new Promise((resolve, reject) => { return new Promise((resolve, reject) =>{
axios.put(url, params) axios.put(url, params)
.then(res => { .then(res => {
resolve(res.data); resolve(res.data);
}) })
.catch(err => { .catch(err => {
reject(err.data) reject(err.data)
}) })
}); });
} }

@ -1,45 +1,45 @@
const util = { const util = {
deepCopy (obj) { // 深拷贝 deepCopy(obj) { // 深拷贝
if (obj == null) { if (obj == null) {
return null; return null;
} }
if (typeof obj !== "object") return obj; if (typeof obj !== "object") return obj;
let result; let result;
if (Array.isArray(obj)) { if (Array.isArray(obj)) {
result = []; result = [];
obj.forEach(item => { obj.forEach(item => {
result.push( result.push(
typeof item === "object" && !(item instanceof Date) typeof item === "object" && !(item instanceof Date)
? util.deepCopy(item) ? util.deepCopy(item)
: item : item
); );
}); });
} else { } else {
result = {}; result = {};
Object.keys(obj).forEach(key => { Object.keys(obj).forEach(key => {
result[key] = result[key] =
typeof obj[key] === "object" && !(obj[key] instanceof Date) typeof obj[key] === "object" && !(obj[key] instanceof Date)
? util.deepCopy(obj[key]) ? util.deepCopy(obj[key])
: obj[key]; : obj[key];
}); });
} }
return result; return result;
}, },
// 传入文件名和数据,下载文件 // 传入文件名和数据,下载文件
downloadFileDirect (fileName, data) { downloadFileDirect(fileName,data) {
if ('download' in document.createElement('a')) { // 非IE下载 if ('download' in document.createElement('a')) { // 非IE下载
const elink = document.createElement('a') const elink = document.createElement('a')
elink.download = fileName elink.download = fileName
elink.style.display = 'none' elink.style.display = 'none'
elink.href = URL.createObjectURL(data) elink.href = URL.createObjectURL(data)
document.body.appendChild(elink) document.body.appendChild(elink)
elink.click() elink.click()
URL.revokeObjectURL(elink.href) // 释放URL 对象 URL.revokeObjectURL(elink.href) // 释放URL 对象
document.body.removeChild(elink) document.body.removeChild(elink)
} else { // IE10+下载 } else { // IE10+下载
navigator.msSaveBlob(data, fileName) navigator.msSaveBlob(data, fileName)
} }
}, },
}; };
export default util; export default util;

@ -1,59 +1,34 @@
<template> <template>
<div class="wrapper"> <div class="wrapper">
<v-head></v-head> <v-head></v-head>
<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" mode="out-in"> <transition name="move" mode="out-in">
<!-- <keep-alive> --> <!-- <keep-alive> -->
<router-view></router-view> <router-view></router-view>
<!-- </keep-alive> --> <!-- </keep-alive> -->
</transition> </transition>
<el-backtop target=".content"></el-backtop> <el-backtop target=".content"></el-backtop>
</div> </div>
</div>
</div> </div>
</div>
</template> </template>
<script> <script>
import vHead from '../components/Header.vue'; import vHead from '../components/Header.vue';
import vSidebar from '../components/Sidebar.vue'; import vSidebar from '../components/Sidebar.vue';
import Setting from "@/setting";
import util from "@/libs/util";
export default { export default {
data () { data() {
return { return {
tagsList: [], tagsList: [],
}; };
}, },
components: { components: {
vHead, vHead,
vSidebar, vSidebar,
}, },
created () { created() {
// this.autoLogout()
},
methods: {
// ,退
autoLogout () {
let lastTime = new Date().getTime();
document.onmousedown = () => {
lastTime = new Date().getTime();
};
const timer = setInterval(() => {
if (sessionStorage.getItem('token') && (new Date().getTime() - lastTime) > Setting.autoLogoutTime) {
clearInterval(timer)
util.errorMsg("由于您已经有三个小时没有操作,系统自动登出,请重新登录。页面刷新到登录页。");
setTimeout(() => {
localStorage.removeItem('ms_username');
localStorage.removeItem('token');
sessionStorage.clear()
location.reload()
}, 1500);
}
}, 1000);
} }
}
}; };
</script> </script>

@ -1,568 +1,433 @@
<template> <template>
<div class="login-wrap"> <div class="login-wrap">
<div class="header"> <div class="header">
<div class="logo"> <div class="logo">
<img src="../assets/img/logo.png"> <img src="../assets/img/logo.png">
</div> </div>
</div>
<div class="ms-login">
<div class="ms-title">
<!-- <p class="title">账号登录</p> -->
<el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
<el-menu-item index="1">账号登录</el-menu-item>
<el-menu-item index="2">手机号/邮箱登录</el-menu-item>
</el-menu>
<el-form v-show="activeIndex==='1'" :model="param" :rules="rules" ref="login" label-width="0px" style="margin-top: 40px">
<el-form-item prop="account">
<el-input @blur="blur" v-model="param.account" placeholder="请输入账号"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
type="password"
placeholder="请输入密码"
v-model="param.password"
>
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="showVerify">
<el-input
placeholder="请输入验证码"
v-model="param.code"
@keyup.enter.native="submitForm()"
>
</el-input>
<img @click="blur" :src="verificationIMG" class="verification" alt="">
</el-form-item>
<div style="width:100%;display:flex;justify-content: flex-end;">
<el-button type="text" class="forget">忘记密码?</el-button>
</div>
<div class="login-btn">
<el-button type="primary" @click="submitForm()">马上登录</el-button>
</div>
</el-form>
<el-form v-show="activeIndex==='2'" :model="phoneOrEmail" :rules="phoneOrEmailrules" ref="phoneOrEmail" label-width="0px" style="margin-top: 40px">
<el-form-item prop="account">
<el-input @blur="phoneBlur" v-model="phoneOrEmail.account" placeholder="请输入电话/邮箱"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
type="password"
placeholder="请输入密码"
v-model="phoneOrEmail.password"
>
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="showPhoneVerify">
<el-input
placeholder="请输入验证码"
v-model="phoneOrEmail.code"
@keyup.enter.native="submitForm('phone')"
>
</el-input>
<img @click="phoneBlur" :src="PhoneVerificationIMG" class="verification" alt="">
</el-form-item>
<div style="width:100%;display:flex;justify-content: flex-end;">
<el-button type="text" class="forget">忘记密码?</el-button>
</div>
<div class="login-btn">
<el-button type="primary" @click="submitForm('phone')">马上登录</el-button>
</div>
</el-form>
</div>
</div>
<el-dialog title="绑定手机号" :visible.sync="phoneVisible" :close-on-click-modal="false" width="576px">
<p class="tips">依据国家政策法规需绑定手机号进行网络实名才可登录使用本平台</p>
<el-form ref="form" label-width="60px">
<el-form-item label="手机号">
<el-input placeholder="请输入手机号" v-model="phone" maxlength="11"></el-input>
</el-form-item>
<el-form-item label="验证码">
<div style="display:flex;">
<el-input v-model="phoneCode" placeholder="请输入验证码" maxlength="6"></el-input>
<el-button style="margin-left:10px" @click="sendPhoneCode" :disabled="phoneDisabled">{{phoneBtnText}}</el-button>
</div>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="phoneVisible = false"> </el-button>
<el-button type="primary" @click="phoneSubmit"> </el-button>
</span>
</el-dialog>
<v-footer class="footer" ref="footer"></v-footer>
</div> </div>
<div class="ms-login">
<div class="ms-title">
<!-- <p class="title">账号登录</p> -->
<el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect">
<el-menu-item index="1">账号登录</el-menu-item>
<el-menu-item index="2">手机号/邮箱登录</el-menu-item>
</el-menu>
<el-form v-show="activeIndex === '1'" :model="param" :rules="rules" ref="login" label-width="0px"
style="margin-top: 20px">
<el-form-item prop="account">
<el-input @blur="blur" v-model="param.account" placeholder="请输入账号"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password" placeholder="请输入密码" v-model="param.password">
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="showVerify">
<el-input placeholder="请输入验证码" v-model="param.code" @keyup.enter.native="submitForm()">
</el-input>
<img @click="blur" :src="verificationIMG" class="verification" alt="">
</el-form-item>
<div style="width:100%;display:flex;justify-content: flex-end;">
<el-button type="text" class="forget">忘记密码?</el-button>
</div>
<div class="login-btn">
<el-button type="primary" @click="submitForm()">马上登录</el-button>
</div>
</el-form>
<el-form v-show="activeIndex === '2'" :model="phoneOrEmail" :rules="phoneOrEmailrules" ref="phoneOrEmail"
label-width="0px" style="margin-top: 20px">
<el-form-item prop="account">
<el-input @blur="phoneBlur" v-model="phoneOrEmail.workNumber" placeholder="请输入电话/邮箱"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password" placeholder="请输入密码" v-model="phoneOrEmail.password">
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="showPhoneVerify">
<el-input placeholder="请输入验证码" v-model="phoneOrEmail.code" @keyup.enter.native="submitForm('phone')">
</el-input>
<img @click="phoneBlur" :src="PhoneVerificationIMG" class="verification" alt="">
</el-form-item>
<div style="width:100%;display:flex;justify-content: flex-end;">
<el-button type="text" class="forget">忘记密码?</el-button>
</div>
<div class="login-btn">
<el-button type="primary" @click="submitForm('phone')">马上登录</el-button>
</div>
</el-form>
</div>
</div>
<el-dialog title="绑定手机号" :visible.sync="phoneVisible" :close-on-click-modal="false" width="576px">
<p class="tips">依据国家政策法规需绑定手机号进行网络实名才可登录使用本平台</p>
<el-form ref="form" label-width="60px">
<el-form-item label="手机号">
<el-input placeholder="请输入手机号" v-model="phone" maxlength="11"></el-input>
</el-form-item>
<el-form-item label="验证码">
<div style="display:flex;">
<el-input v-model="phoneCode" placeholder="请输入验证码" maxlength="6"></el-input>
<el-button style="margin-left:10px" @click="sendPhoneCode" :disabled="phoneDisabled">{{ phoneBtnText
}}</el-button>
</div>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="phoneVisible = false"> </el-button>
<el-button type="primary" @click="phoneSubmit"> </el-button>
</span>
</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>
</div>
</template> </template>
<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 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) => {//
let emailReg = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ let emailReg = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
let phoneReg = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/ let phoneReg = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/
if (value === '') { if (value === '') {
callback(new Error('请输入手机或邮箱!')); callback(new Error('请输入手机或邮箱!'));
} else if (!emailReg.test(value) && !phoneReg.test(value)) { } else if (!emailReg.test(value)&&!phoneReg.test(value)) {
callback(new Error('输入的手机/邮箱格式不正确!')); callback(new Error('输入的手机/邮箱格式不正确!'));
} else {
callback();
}
};
return {
activeIndex: "1",
showVerify: true,// -
verificationIMG: '',//
//
param: {
account: '',
password: '',
code: '',
platform: 3,
random: '',
distinguish: 1,
},
rules: {
account: [{ required: true, message: '请输入账号', trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
code: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
},
// +
showPhoneVerify: true,// -
PhoneVerificationIMG: '',//
phoneOrEmail: {
workNumber: '',
password: '',
code: '',
platform: 3,
random: '',
distinguish: 1,
},
phoneOrEmailrules: {
workNumber: [{ validator: regPhoneOrEmail, trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
code: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
},
phoneVisible: false,
phone: '',
phoneCode: '',
phoneDisabled: false,
phoneBtnText: '发送验证码',
phoneTimer: '',
phoneOpener: '',
userVisible: false,
users: [],
};
},
components: {
vFooter
},
watch: {
verificationIMG: function (val) {// --
if (val) {
this.showVerify = true
} else {
this.showVerify = false
}
},
PhoneVerificationIMG: function (val) {// --
if (val) {
this.showPhoneVerify = true
} else {
this.showPhoneVerify = false
}
},
},
created () {
if (this.param.account) {
this.showVerify = true
}
this.blur()
},
methods: {
submitForm (val) {
let ref = val === 'phone' ? 'phoneOrEmail' : 'login'
let param = val === 'phone' ? this.phoneOrEmail : this.param
this.$refs[ref].validate(valid => {
if (valid) {
this.$post(this.api.logins, param).then(({ status, data, message }) => {
localStorage.removeItem('examPath')
localStorage.removeItem('reviewPath')
this.getOss()
if (status == 200) {
const accounts = data.userAccounts
//
if (accounts instanceof Array) {
this.users = accounts
this.userVisible = true
} else {
sessionStorage.setItem('token', data.token)
this.setLogin()
}
} else { } else {
param.code = '' callback();
this.$message.error(message)
}
}).catch(err => {
if (err.status === 30001) {
this.phoneVisible = true
} else if (err.status == 10004 || err.status == 10005) {
param.code = ''
this.blur()
} }
}); };
} else { return {
this.$message.error('请输入账号/密码/验证码'); activeIndex:"1",
return false;
} showVerify: true,// -
}); verificationIMG:'',//
//
param: {
account: '',
password: '',
code:'',
platform:3,
random:'',
distinguish:1,
type: 2
},
rules: {
account: [{ required: true, message: '请输入账号', trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
code: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
},
// +
showPhoneVerify:true,// -
PhoneVerificationIMG:'',//
phoneOrEmail: {
account: '',
password: '',
code:'',
platform:3,
random:'',
distinguish:2,
type: 2
},
phoneOrEmailrules:{
account: [{ validator: regPhoneOrEmail, trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
code: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
},
phoneVisible:false,
phone:'',
phoneCode:'',
phoneDisabled:false,
phoneBtnText: '发送验证码',
phoneTimer:'',
phoneOpener:''
};
}, },
// oss components: {
async getOss () { vFooter
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))
}, },
// watch:{
chooseUser (user) { verificationIMG:function(val){// --
user.isEnable && this.$post(`${this.api.getToken}?id=${user.id}`).then(({ data }) => { if(val){
sessionStorage.setItem('token', data.token) this.showVerify = true
this.token = data.token }else{
this.setLogin() this.showVerify = false
}).catch(res => { }) }
}, },
// PhoneVerificationIMG:function(val){// --
async setLogin () { if(val){
try { this.showPhoneVerify = true
const res = await this.$get(`${this.api.getUserRolesPermissionMenu}?platformId=${Setting.platformId}`) }else{
const list = res.permissionMenu this.showPhoneVerify = false
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 () {
this.param.random = Math.floor(Math.random() * 999999999)
this.verificationIMG = this.api.verification + '?random=' + `${this.param.random}`
},
phoneBlur () {
this.phoneOrEmail.random = Math.floor(Math.random() * 999999999)
this.PhoneVerificationIMG = this.api.verification + '?random=' + `${this.phoneOrEmail.random}`
},
handleSelect (val) {
this.activeIndex = val
this.param.account = "";
this.param.password = "";
this.param.code = "";
this.phoneOrEmail.account = "";
this.phoneOrEmail.password = "";
this.phoneOrEmail.code = "";
this.$refs.phoneOrEmail.clearValidate()
// this.blur()
this.phoneBlur()
}, },
sendPhoneCode () { created(){
if (!this.phone) return this.$message.warning('请输入手机号') if(this.param.account){
if (!/^1[3456789]\d{9}$/.test(this.phone)) return this.$message.warning('请输入正确的手机号') this.showVerify = true
let data = {
phone: this.phone,
types: 2
}
this.$post(this.api.sendPhoneOrEmailCode, data).then(res => {
this.phoneCountdown()//
if (res.message.opener) {
this.phoneOpener = res.message.opener
} else {
this.$message(res.message)
} }
this.blur()
}).catch(res => { })
}, },
phoneSubmit () { methods: {
if (!this.phone) return this.$message.warning('请输入手机号') submitForm(val) {
if (!/^1[3456789]\d{9}$/.test(this.phone)) return this.$message.warning('请输入正确的手机号') let ref = val==='phone'?'phoneOrEmail':'login'
if (!this.phoneCode) return this.$message.warning('请输入验证码') let param = val==='phone'?this.phoneOrEmail:this.param
let data = { this.$refs[ref].validate(valid => {
phone: this.phone, if (valid) {
types: 2, this.$post(this.api.logins,param).then(res => {
code: this.phoneCode, const { message } = res
opener: this.phoneOpener, sessionStorage.setItem('token',res.data.token)
platform: 3, this.$get(`${this.api.getUserRolesPermissionMenu}?platformId=${Setting.platformId}`).then(res => {
account: this.param.account const list = res.permissionMenu
} addRoutes(res.permissionMenu[0].children)
this.$post(this.api.bindPhoneOrEmail, data).then(res => { this.$store.commit('setDataPer', res.dataPermissionList)
sessionStorage.setItem('token', res.token) this.$message.success(message);
this.$router.push({ this.$router.push({
path: '/customer' path: list[0].children[0].path
}); });
localStorage.setItem('ms_username', this.param.username); localStorage.setItem('ms_username', this.param.username);
this.$message.success('绑定成功') }).catch(err => {
// this.form.phone = this.phone if (err.status === 500) {
// this.phoneVisible = false sessionStorage.clear()
}).catch(res => { }) }
}, })
phoneCountdown () { }).catch(err => {
let count = 60 if(err.status===30001){
if (!this.phoneTimer) { this.phoneVisible = true
this.phoneDisabled = true }else if(err.status == 10004){
this.phoneTimer = setInterval(() => { this.blur()
if (count > 0) { }
count-- });
this.phoneBtnText = `${count}秒后重试` } else {
} else { this.$message.error('请输入账号/密码/验证码');
this.phoneDisabled = false return false;
clearInterval(this.phoneTimer) }
this.phoneTimer = null });
this.phoneBtnText = `发送验证码`
} },
}, 1000) blur(){
} this.param.random = Math.floor(Math.random()*999999999)
this.verificationIMG = this.api.verification+'?random='+`${this.param.random}`
},
phoneBlur(){
this.phoneOrEmail.random = Math.floor(Math.random()*999999999)
this.PhoneVerificationIMG = this.api.verification+'?random='+`${this.phoneOrEmail.random}`
},
handleSelect(val){
this.activeIndex = val
this.param.account = "";
this.param.password = "";
this.param.code = "";
this.phoneOrEmail.account = "";
this.phoneOrEmail.password = "";
this.phoneOrEmail.code = "";
this.$refs.phoneOrEmail.clearValidate()
// this.blur()
this.phoneBlur()
},
sendPhoneCode(){
if(!this.phone) return this.$message.warning('请输入手机号')
if(!/^1[3456789]\d{9}$/.test(this.phone)) return this.$message.warning('请输入正确的手机号')
let data = {
phone: this.phone,
types: 2
}
this.$post(this.api.sendPhoneOrEmailCode,data).then(res => {
this.phoneCountdown()//
if(res.message.opener){
this.phoneOpener = res.message.opener
}else{
this.$message(res.message)
}
}).catch(res => {})
},
phoneSubmit(){
if(!this.phone) return this.$message.warning('请输入手机号')
if(!/^1[3456789]\d{9}$/.test(this.phone)) return this.$message.warning('请输入正确的手机号')
if(!this.phoneCode) return this.$message.warning('请输入验证码')
let data = {
phone: this.phone,
types: 2,
code: this.phoneCode,
opener: this.phoneOpener,
platform: 3,
account: this.param.account
}
this.$post(this.api.bindPhoneOrEmail,data).then(res => {
sessionStorage.setItem('token',res.token)
this.$router.push({
path:'/customer'
});
localStorage.setItem('ms_username', this.param.username);
this.$message.success('绑定成功')
// this.form.phone = this.phone
// this.phoneVisible = false
}).catch(res => {})
},
phoneCountdown(){
let count = 60
if(!this.phoneTimer){
this.phoneDisabled = true
this.phoneTimer = setInterval(() => {
if(count > 0){
count--
this.phoneBtnText = `${count}秒后重试`
}else{
this.phoneDisabled = false
clearInterval(this.phoneTimer)
this.phoneTimer = null
this.phoneBtnText = `发送验证码`
}
},1000)
}
},
}, },
},
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.login-wrap { .login-wrap {
position: relative; position: relative;
width: 100%; width: 100%;
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;
left: 50%; left: 50%;
top: 30px; top: 50px;
transform: translate(-50%, 0); transform: translate(-50%,0);
} }
/deep/ .ms-login { /deep/ .ms-login {
position: relative; position: relative;
width: 1200px; width: 1200px;
height: calc(92vh - 40px); height: calc(92vh - 40px);
margin: 60px auto 0; margin: 60px auto 0;
background-image: url(../assets/img/login-input.png); background-image: url(../assets/img/login-input.png);
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{
position: absolute;
.verification { top: 1px;
position: absolute; right: 1px;
top: 1px; width: 160px;
right: 1px; height: 78px;
width: 160px; cursor: pointer;
height: 78px; }
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;
margin-bottom: 50px; margin-bottom: 50px;
font-weight: bold; font-weight: bold;
background: linear-gradient(90deg, rgba(94, 206, 253, 1), rgba(91, 67, 231, 1)); background:linear-gradient(90deg,rgba(94,206,253,1),rgba(91,67,231,1));
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{
color: #0092FF;
&:hover { }
color: #0092ff;
}
} }
.thirdParty{
.thirdParty { width: 100%;
width: 100%; display: flex;
display: flex; justify-content: center;
justify-content: center; margin-top: 33px;
margin-top: 33px;
} }
/* 头部 */ /* 头部 */
.header { .header{
height: 60px; height: 60px;
background-color: #fff; background-color: #fff;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
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;
} }
.el-menu-demo { .el-menu-demo{
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
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;
color: #666;
}
/deep/.user-dia {
.tips {
margin-bottom: 20px;
text-align: center; text-align: center;
color: #666; 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) {
/deep/.ms-login {
width: 1000px;
.el-input__inner {
height: 50px;
line-height: 50px;
}
.verification {
height: 48px;
}
}
.ms-title {
width: 480px;
}
.login-btn button {
height: 60px;
}
} }
</style> </style>

File diff suppressed because it is too large Load Diff

@ -1,371 +1,318 @@
<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> <span>筛选</span>
<span>筛选</span> </div>
</div> <div>
<div> <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.categoryId" clearable
<el-select v-model="form.categoryId" @change="getProfessionalClass()" @clear="clearClass()">
clearable <el-option v-for="(item,index) in subjectList" :key="index"
@change="getProfessionalClass()" :label="item.disciplineName"
@clear="clearClass()"> :value="item.disciplineId"></el-option>
<el-option v-for="(item,index) in subjectList" </el-select>
:key="index" </el-form-item>
:label="item.disciplineName" </el-col>
:value="item.disciplineId"></el-option> <el-col :span="4">
</el-select> <el-form-item label="专业类">
</el-form-item> <el-select v-model="form.professionalCategoryId" clearable
</el-col> :disabled="form.categoryId ? false : true"
<el-col :span="4"> @change="getProfessional()" @clear="clearProfess()">
<el-form-item label="专业类"> <el-option v-for="(item,index) in ProfessionalClassList" :key="index"
<el-select v-model="form.professionalCategoryId" :label="item.professionalClassName"
clearable :value="item.professionalClassId"></el-option>
:disabled="form.categoryId ? false : true" </el-select>
@change="getProfessional()" </el-form-item>
@clear="clearProfess()"> </el-col>
<el-option v-for="(item,index) in ProfessionalClassList" <el-col :span="4">
:key="index" <el-form-item label="专业">
:label="item.professionalClassName" <el-select v-model="form.professionalId" clearable
:value="item.professionalClassId"></el-option> :disabled="form.professionalCategoryId ? false : true"
</el-select> @change="getData()">
</el-form-item> <el-option v-for="(item,index) in ProfessionalList" :key="index"
</el-col> :label="item.professionalName"
<el-col :span="4"> :value="item.professionalId"></el-option>
<el-form-item label="专业"> </el-select>
<el-select v-model="form.professionalId" </el-form-item>
clearable </el-col>
:disabled="form.professionalCategoryId ? false : true" <el-col :span="4">
@change="getData()"> <el-form-item label="课程类别">
<el-option v-for="(item,index) in ProfessionalList" <el-select v-model="form.curriculumType" clearable
:key="index" @change="getData()">
:label="item.professionalName" <el-option label="理论课程" :value="0"></el-option>
:value="item.professionalId"></el-option> <el-option label="实训课程" :value="1"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="4"> <el-col :span="6">
<el-form-item label="课程类别"> <el-form-item>
<el-select v-model="form.curriculumType" <el-input placeholder="请输入课程名称" prefix-icon="el-icon-search"
clearable v-model="form.curriculumName" clearable
@change="getData()"> @keyup.enter.native="onSearch"></el-input>
<el-option label="理论课程" </el-form-item>
:value="0"></el-option> </el-col>
<el-option label="实训课程" </el-form>
:value="1"></el-option> </div>
</el-select> </div>
</el-form-item> </el-card>
</el-col>
<el-col :span="6">
<el-form-item>
<el-input placeholder="请输入课程名称"
prefix-icon="el-icon-search"
v-model="form.curriculumName"
clearable
@keyup.enter.native="onSearch"></el-input>
</el-form-item>
</el-col>
</el-form>
</div>
</div>
</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" round @click="addcourse" v-auth>新增课程</el-button>
<el-button type="primary" <el-button type="primary" round @click="delAllSelection" v-auth>批量删除</el-button>
round </div>
@click="addcourse" </div>
v-auth>新增课程</el-button> <el-table v-loading="loading" :data="courseData" class="table" ref="table" stripe header-align="center"
<el-button type="primary" @selection-change="handleSelectionChange" :row-key="getRowKeys">
round <el-table-column type="selection" width="55" align="center"
@click="delAllSelection" :reserve-selection="true"></el-table-column>
v-auth>批量删除</el-button> <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
</div> <el-table-column prop="curriculumName" label="课程名称" align="center"></el-table-column>
</div> <el-table-column prop="curriculumType" label="课程类型" align="center">
<el-table v-loading="loading" <template slot-scope="scope">
:data="courseData" <span class="ellipsis">{{ courseTypeStatus[scope.row.curriculumType] }}</span>
class="table" </template>
ref="table" </el-table-column>
stripe <el-table-column prop="userName" label="创建人" align="center"></el-table-column>
header-align="center" <el-table-column label="配置的实训应用" align="center">
@selection-change="handleSelectionChange" <template slot-scope="scope">
:row-key="getRowKeys"> <span class="ellipsis">{{ scope.row.sysName }}</span>
<el-table-column type="selection" </template>
width="55" </el-table-column>
align="center" <el-table-column prop="orderVolume" label="订单量" align="center"></el-table-column>
:reserve-selection="true"></el-table-column> <el-table-column prop="expectedCourse" label="预计课时" align="center"></el-table-column>
<el-table-column type="index" <el-table-column label="上架/下架" align="center">
width="100" <template slot-scope="scope">
label="序号" <el-switch
align="center"></el-table-column> v-model="scope.row.isShelves"
<el-table-column prop="curriculumName" :active-value="1"
label="课程名称" :inactive-value="0"
align="center"></el-table-column> @change="changeSwitch($event, scope.row)"
<el-table-column prop="curriculumType" v-auth="'/curriculum:上下架'">
label="课程类型" </el-switch>
align="center"> </template>
<template slot-scope="scope"> </el-table-column>
<span class="ellipsis">{{ courseTypeStatus[scope.row.curriculumType] }}</span> <el-table-column label="操作" align="center">
</template> <template slot-scope="scope">
</el-table-column> <el-button type="text" @click="edit(scope.row)" v-auth>编辑</el-button>
<el-table-column prop="userName" <el-button type="text" @click="config(scope.row)" v-auth>内容设置</el-button>
label="创建人" <el-button type="text" @click="handleDelete(scope.row)" v-auth>删除</el-button>
align="center"></el-table-column> </template>
<el-table-column label="配置的实训应用" </el-table-column>
align="center"> </el-table>
<template slot-scope="scope"> <div class="pagination">
<span class="ellipsis">{{ scope.row.sysName }}</span> <el-pagination background @current-change="handleCurrentChange" :current-page="pageNo"
</template> layout="total, prev, pager, next" :total="totals"></el-pagination>
</el-table-column> </div>
<el-table-column prop="orderVolume" </el-card>
label="订单量" </div>
align="center"></el-table-column>
<el-table-column prop="expectedCourse"
label="预计课时"
align="center"></el-table-column>
<el-table-column label="上架/下架"
align="center">
<template slot-scope="scope">
<el-switch v-model="scope.row.isShelves"
:active-value="1"
:inactive-value="0"
@change="changeSwitch($event, scope.row)"
v-auth="'/curriculum:上下架'">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作"
align="center">
<template slot-scope="scope">
<el-button type="text"
@click="edit(scope.row)"
v-auth>编辑</el-button>
<el-button type="text"
@click="config(scope.row)"
v-auth>内容设置</el-button>
<el-button type="text"
@click="handleDelete(scope.row)"
v-auth>删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background
@current-change="handleCurrentChange"
:current-page="page"
layout="total, prev, pager, next"
:total="totals"></el-pagination>
</div>
</el-card>
</div>
</template> </template>
<script> <script>
import qs from 'qs'
export default { export default {
data () { name: "customer",
return { data() {
courseTypeStatus: { return {
0: "理论课程", courseTypeStatus: {
1: "实训课程" 0: "理论课程",
}, 1: "实训课程"
name: localStorage.getItem("ms_username"), },
courseData: [], name: localStorage.getItem("ms_username"),
form: { courseData: [],
categoryId: +this.$route.query.categoryId || '', form: {
professionalCategoryId: +this.$route.query.professionalCategoryId || '', categoryId: "",
professionalId: +this.$route.query.professionalId || '', professionalCategoryId: "",
curriculumType: this.$route.query.curriculumType ? +this.$route.query.curriculumType : '', professionalId: "",
curriculumName: this.$route.query.curriculumName || '' curriculumType: "",
}, curriculumName: ""
page: +this.$route.query.page || 1, },
pageSize: 10, pageNo: +this.$route.query.page || 1,
totals: 0, pageSize: 10,
subjectList: [], // totals: 0,
ProfessionalClassList: [], // subjectList: [], //
ProfessionalList: [], // ProfessionalClassList: [], //
multipleSelection: [], ProfessionalList: [], //
loading: false, multipleSelection: [],
searchTimer: null loading: false,
}; searchTimer: null
}, };
watch: {
"form.curriculumName": function (val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.initData();
}, 500);
}
},
mounted () {
this.getSubject();
this.getData();
},
methods: {
getRowKeys (row) {
return row.cid;
},
//
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.courseData = res.page.records;
this.totals = res.page.total;
this.loading = false;
}).catch(err => { });
},
initData () {
this.page = 1;
this.getData();
},
//
async getSubject () {
const { list } = await this.$get(this.api.courseDiscipline)
this.subjectList = list
this.form.professionalCategoryId && this.getProfessionalClassData()
},
//
clearClass () {
this.form.professionalCategoryId = ''
this.form.professionalId = ''
},
//
getProfessionalClass () {
this.clearClass();
this.getProfessionalClassData();
this.page = 1;
this.getData();
},
async getProfessionalClassData () {
const { list } = await this.$get(this.api.courseProfessionalClass, {
disciplineId: this.form.categoryId
})
this.ProfessionalClassList = list
this.form.professionalId && this.getProfessionalData()
},
//
clearProfess () {
this.form.professionalId = ''
},
//
getProfessional () {
this.clearProfess();
this.getProfessionalData();
this.page = 1;
this.getData();
},
async getProfessionalData () {
const { list } = await this.$get(this.api.courseProfessional, {
professionalClassId: this.form.professionalCategoryId
})
this.ProfessionalList = list
},
// url
setReferrer () {
this.$store.commit('setReferrer', `${this.$route.path}?${qs.stringify(this.form)}&page=${this.page}`)
},
//
addcourse () {
this.setReferrer()
this.$router.push("/addcurriculum");
}, },
// watch: {
edit (row) { "form.curriculumName": function(val) {
this.setReferrer() clearTimeout(this.searchTimer);
this.$router.push(`/addcurriculum?cid=${row.cid}`); this.searchTimer = setTimeout(() => {
}, this.initData();
// }, 500);
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 => { })
}, },
// mounted() {
handleSelectionChange (val) { this.getSubject();
this.multipleSelection = val; this.getData();
}, },
// methods: {
delAllSelection () { getRowKeys(row) {
if (this.multipleSelection.length) { return row.cid;
let cids = [] },
this.multipleSelection.forEach(i => { //
cids.push('cids=' + i.cid) getData() {
}); const sid = this.$store.state.dataPer.find(e => e.permissionName === '课程管理')
this.$post(`${this.api.deleteCoursePrompt}?${cids.join('&')}`).then(({ status }) => { let data = {
if (status === 200) { ...this.form,
this.$confirm("确定要删除吗?", "提示", { pageNum: this.pageNo,
type: "warning" pageSize: this.pageSize,
}).then(() => { supplierId: sid ? sid.supplierId : ''
let ids = this.multipleSelection.map(i => i.cid); };
this.$post(`${this.api.delCourse}?cids=${ids.toString()}`).then(res => { this.$post(this.api.curriculumList, data).then(res => {
if (ids.length == this.courseData.length) { this.courseData = res.page.records;
if (this.page > 1) { this.totals = res.page.total;
this.page = this.page - 1 this.loading = false;
} }).catch(err => {
} });
this.getData(); },
this.$message.success("删除成功"); initData() {
this.$refs.table.clearSelection() this.pageNo = 1;
}).catch(err => { }) this.getData();
}).catch(() => { }) },
//
getSubject() {
this.$get(this.api.courseDiscipline).then(res => {
this.subjectList = res.list;
}).catch(err => {
});
},
//
clearClass() {
this.form.professionalCategoryId = "";
this.form.professionalId = "";
},
//
getProfessionalClass() {
this.clearClass();
this.getProfessionalClassData();
this.pageNo = 1;
this.getData();
},
getProfessionalClassData() {
let data = {
disciplineId: this.form.categoryId
};
this.$get(this.api.courseProfessionalClass, data).then(res => {
this.ProfessionalClassList = res.list;
}).catch(err => {
});
},
//
clearProfess() {
this.form.professionalId = "";
},
//
getProfessional() {
this.clearProfess();
this.getProfessionalData();
this.pageNo = 1;
this.getData();
},
getProfessionalData() {
let data = {
professionalClassId: this.form.professionalCategoryId
};
this.$get(this.api.courseProfessional, data).then(res => {
this.ProfessionalList = res.list;
}).catch(err => {
});
},
//
addcourse() {
this.$router.push("/addcurriculum");
},
//
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 => {})
},
//
handleSelectionChange(val) {
this.multipleSelection = val;
},
//
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.courseData.length){
if(this.pageNo > 1){
this.pageNo = this.pageNo-1
}
}
this.getData();
this.$message.success("删除成功");
this.$refs.table.clearSelection()
}).catch(err => {})
}).catch(() => {})
}
}).catch(err => {})
} else {
this.$message.warning("请先选择课程 !");
} }
}).catch(err => { }) },
} else { //
this.$message.warning("请先选择课程 !"); handleCurrentChange(val) {
} this.pageNo = val;
}, this.$router.push(`curriculum?page=${val}`)
// this.getData();
handleCurrentChange (val) { },
this.page = val; //
this.$router.push(`/curriculum?page=${val}`) onSearch() {
this.getData(); this.pageNo = 1;
}, this.getData();
// },
onSearch () { //
this.page = 1; changeSwitch(value, row) {
this.getData(); this.$post(`${this.api.isShelves}?cid=${row.cid}&isShelves=${value}`).then((res) => {
}, this.getData();
// this.$message.success("修改上下架状态成功!");
changeSwitch (value, row) { }).catch((res) => {
this.$post(`${this.api.isShelves}?cid=${row.cid}&isShelves=${value}`).then((res) => { });
this.getData(); }
this.$message.success("修改上下架状态成功!");
}).catch((res) => {
});
} }
}
}; };
</script> </script>
@ -373,5 +320,8 @@ export default {
.card { .card {
min-height: calc(100vh - 300px); min-height: calc(100vh - 300px);
} }
.mag {
margin-right: 20px;
}
</style> </style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,179 +1,126 @@
<template> <template>
<div> <div>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20"> <div class="flex-between">
<div class="flex-between"> <div class="per_title" v-preventReClick @click="back">
<div class="per_title" <i class="el-icon-arrow-left"></i>
v-preventReClick <span class="per_back">返回</span>
@click="back"> <span class="per_school">{{ $route.query.userName }}的订单</span>
<i class="el-icon-arrow-left"></i> </div>
<span class="per_back">返回</span> </div>
<span class="per_school">{{ $route.query.userName }}的订单</span> </el-card>
</div>
</div>
</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> <el-input style="width: 300px" placeholder="请输入订单编号/产品名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
<el-input style="width: 300px" </div>
placeholder="请输入订单编号/产品名称" <el-table :data="orderData" class="table" ref="table" stripe header-align="center"
prefix-icon="el-icon-search" @selection-change="handleSelectionChange" :row-key="getRowKeys">
v-model="keyword" <el-table-column type="index" width="100" label="序号" align="center">
clearable></el-input> </el-table-column>
</div> <el-table-column prop="orderNumber" label="订单编号" align="center">
<el-table :data="orderData" </el-table-column>
class="table" <el-table-column prop="customerName" label="客户名称" align="center">
ref="table" <template slot-scope="scope">
stripe {{ customerName }}
header-align="center" </template>
@selection-change="handleSelectionChange" </el-table-column>
:row-key="getRowKeys"> <el-table-column prop="productName" label="产品内容" align="center" show-overflow-tooltip></el-table-column>
<el-table-column type="index" <el-table-column prop="orderAmount" label="订单金额(元)" align="center">
width="100" </el-table-column>
label="序号" <el-table-column prop="createTime" label="订单日期" align="center">
align="center"> </el-table-column>
</el-table-column> <el-table-column prop="orderType" label="订单类型" align="center">
<el-table-column prop="orderNumber" </el-table-column>
label="订单编号" <el-table-column prop="orderStatus" label="订单状态" align="center">
align="center"> </el-table-column>
</el-table-column> <el-table-column prop="orderNature" label="订单性质" align="center">
<el-table-column prop="customerName" </el-table-column>
label="客户名称" <el-table-column label="操作" align="center">
align="center"> <template slot-scope="scope">
<template slot-scope="scope"> <el-button type="text" @click="toDetail(scope.row)">查看</el-button>
{{ customerName }} </template>
</template> </el-table-column>
</el-table-column> </el-table>
<el-table-column prop="productName" <div class="pagination">
label="产品内容" <el-pagination background layout="total, prev, pager, next"
align="center" @current-change="handleCurrentChange" :current-page="page" :total="totals">
show-overflow-tooltip></el-table-column> </el-pagination>
<el-table-column prop="orderAmount" </div>
label="订单金额(元)" </el-card>
align="center"> </div>
</el-table-column>
<el-table-column prop="createTime"
label="订单日期"
align="center">
</el-table-column>
<el-table-column prop="orderType"
label="订单类型"
align="center">
</el-table-column>
<el-table-column prop="orderStatus"
label="订单状态"
align="center">
</el-table-column>
<el-table-column prop="orderNature"
label="订单性质"
align="center">
</el-table-column>
<el-table-column label="操作"
align="center">
<template slot-scope="scope">
<el-button type="text"
@click="toDetail(scope.row)">查看</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background
layout="total, prev, pager, next"
@current-change="handleCurrentChange"
:current-page="page"
:total="totals">
</el-pagination>
</div>
</el-card>
</div>
</template> </template>
<script> <script>
export default { export default {
data () { data() {
return { return {
businessManagerId: this.$route.query.businessManagerId, businessManagerId: this.$route.query.businessManagerId,
teamId: this.$route.query.teamId, teamId: this.$route.query.teamId,
customerId: this.$route.query.customerId, customerId: this.$route.query.customerId,
customerName: this.$route.query.customerName, customerName: this.$route.query.customerName,
keyword: "", keyword: "",
orderData: [], orderData: [],
page: 1, page: 1,
pageSize: 10, pageSize: 10,
totals: 0, totals: 0,
searchTimer: null searchTimer: null
}; };
},
watch: {
keyword: function (val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.initData();
}, 500);
}
},
created () {
const { orderParam } = this.$store.state
if (orderParam) {
this.keyword = orderParam.keyword
this.page = orderParam.page
this.$store.commit('setOrderParam', null)
}
this.getData();
},
methods: {
getData () {
let data = {
businessManagerId: this.businessManagerId,
teamId: this.teamId,
keywords: this.keyword,
customerId: this.customerId,
pageNum: this.page,
pageSize: this.pageSize,
};
this.$post(this.api.getBusinessManagerOrder, data).then(({ data }) => {
const { records } = data
records.forEach(e => {
e.orderType = this.orderTypeFn(e.orderType);
e.orderStatus = this.orderStatusFn(e.orderStatus);
e.orderNature = this.orderNatureFn(e.orderNature);
});
this.orderData = records
this.totals = data.total
}).catch(res => { })
}, },
initData () { watch: {
this.page = 1 keyword: function(val) {
this.getData() clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.initData();
}, 500);
}
}, },
handleCurrentChange (val) { created() {
this.page = val this.getData();
this.getData()
}, },
toDetail (row) { methods: {
this.$store.commit('setOrderParam', { getData() {
keyword: this.keyword, let data = {
page: this.page, businessManagerId: this.businessManagerId,
}) teamId: this.teamId,
this.$router.push({ keywords: this.keyword,
path: '/AddOrder', customerId: this.customerId,
query: { pageNum: this.page,
val: 'watch', pageSize: this.pageSize,
orderId: row.orderId, };
orderStatus: row.orderStatus === '已完成' ? 1 : 0, this.$post(this.api.getBusinessManagerOrder, data).then(({ data }) => {
const { records } = data
records.forEach(e => {
e.orderType = this.orderTypeFn(e.orderType);
e.orderStatus = this.orderStatusFn(e.orderStatus);
e.orderNature = this.orderNatureFn(e.orderNature);
});
this.orderData = records
this.totals = data.total
}).catch(res => {})
},
initData() {
this.page = 1
this.getData()
},
toDetail(row) {
this.$router.push({
path:'/AddOrder',
query:{
val: 'watch',
orderId: row.orderId,
orderStatus: row.orderStatus === '已完成' ? 1 : 0
}
})
},
back() {
this.$router.back()
} }
})
},
back () {
this.$router.back()
} }
}
}; };
</script> </script>
@ -184,8 +131,8 @@ export default {
.mag { .mag {
margin-right: 20px; margin-right: 20px;
} }
.cell { .cell{
white-space: pre-wrap; white-space:pre-wrap;
width: 140px; width: 140px;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
@ -194,11 +141,10 @@ 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;color: #000;
color: #000; white-space:pre-wrap;
white-space: pre-wrap;
width: 140px; width: 140px;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;

@ -1,6 +1,7 @@
<template> <template>
<div v-loading="loading"> <div>
<el-card shadow="hover" class="mgb20"> <el-card shadow="hover"
class="mgb20">
<div> <div>
<div class="flex-center mgb20"> <div class="flex-center mgb20">
<p class="hr_tag"></p> <p class="hr_tag"></p>
@ -10,34 +11,50 @@
<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.provinces" clearable placeholder="请选择省份" @change="getCity" <el-select v-model="form.provinces"
@clear="clearprovince"> clearable
<el-option v-for="(item, index) in provinceList" :key="index" :label="item.provinceName" placeholder="请选择省份"
:value="item.provinceId"></el-option> @change="getCity"
@clear="clearprovince">
<el-option v-for="(item,index) in provinceList"
:key="index"
:label="item.provinceName"
: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.city" clearable placeholder="请选择城市" :disabled="form.provinces ? false : true" <el-select v-model="form.city"
@change="initData"> clearable
<el-option v-for="(item, index) in cityList" :key="index" :label="item.cityName" placeholder="请选择城市"
:value="item.cityId"></el-option> :disabled="form.provinces ? false : true"
@change="initData">
<el-option v-for="(item,index) in cityList"
:key="index"
:label="item.cityName"
: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.customerType" placeholder="请选择客户类型" @change="initData"> <el-select v-model="form.customerType"
<el-option v-for="(item, index) in customerTypeList" :key="index" :label="item.name" placeholder="请选择客户类型"
:value="item.value"></el-option> @change="initData">
<el-option v-for="(item,index) in customerTypeList"
:key="index"
:label="item.name"
: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="支持客户,联系人,账号搜索" prefix-icon="el-icon-search" v-model="form.keyword" <el-input placeholder="支持客户,联系人,账号搜索"
clearable></el-input> prefix-icon="el-icon-search"
v-model="form.keyword"
clearable></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-form> </el-form>
@ -45,61 +62,111 @@
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" class="card"> <el-card shadow="hover"
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" round class="mag" @click="exportData">导出客户列表</el-button> <el-button type="primary"
<el-button type="primary" round class="mag" @click="addcustomer" v-auth>新增</el-button> round
<el-button type="primary" round @click="delAllSelection" v-auth>批量删除</el-button> class="mag"
@click="exportData">导出客户列表</el-button>
<el-button type="primary"
round
class="mag"
@click="addcustomer"
v-auth>新增</el-button>
<el-button type="primary"
round
@click="delAllSelection"
v-auth>批量删除</el-button>
</div> </div>
</div> </div>
<el-table :data="listData" class="table" ref="table" stripe header-align="center" <el-table v-loading="loading"
@selection-change="handleSelectionChange" row-key="customerId"> :data="listData"
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> class="table"
<el-table-column type="index" width="100" label="序号" align="center"> ref="table"
stripe
header-align="center"
@selection-change="handleSelectionChange"
row-key="customerId">
<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">
<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="customerName" label="客户名称" align="center"> <el-table-column prop="customerName"
label="客户名称"
align="center">
</el-table-column> </el-table-column>
<el-table-column label="行业" align="center"> <el-table-column label="行业"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<span class="ellipsis">{{ scope.row.industryName }}</span> <span class="ellipsis">{{scope.row.industryName}}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="countries" label="客户类型" align="center"> <el-table-column prop="countries"
label="客户类型"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<span v-if="scope.row.customerType">{{ customerTypeList.find(e => e.value == scope.row.customerType).name <span v-if="scope.row.customerType">{{ customerTypeList.find(e => e.value == scope.row.customerType).name }}</span>
}}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="provinceName" label="省份" align="center"> <el-table-column prop="provinceName"
label="省份"
align="center">
</el-table-column> </el-table-column>
<el-table-column prop="cityName" label="城市" align="center"> <el-table-column prop="cityName"
label="城市"
align="center">
</el-table-column> </el-table-column>
<el-table-column prop="name" label="联系人" align="center"> <el-table-column prop="name"
label="联系人"
align="center">
</el-table-column> </el-table-column>
<el-table-column prop="account" label="账号" align="center"> <el-table-column prop="account"
label="账号"
align="center">
</el-table-column> </el-table-column>
<el-table-column prop="loginNumber" label="登录次数" align="center"> <el-table-column prop="loginNumber"
label="登录次数"
align="center">
</el-table-column> </el-table-column>
<el-table-column label="操作" width="270" align="center"> <el-table-column label="操作"
width="270"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click="resetPassword(scope.row)" v-auth>重置密码</el-button> <el-button type="text"
<el-button type="text" @click="show(scope.row)" v-auth>查看</el-button> @click="resetPassword(scope.row)"
<el-button type="text" @click="edit(scope.row)" v-auth>管理</el-button> v-auth>重置密码</el-button>
<el-button type="text" @click="handleDelete(scope.row)" v-auth>删除</el-button> <el-button type="text"
@click="show(scope.row)"
v-auth>查看</el-button>
<el-button type="text"
@click="edit(scope.row)"
v-auth>编辑</el-button>
<el-button type="text"
@click="handleDelete(scope.row)"
v-auth>删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" <el-pagination background
:current-page="page"> layout="total, prev, pager, next"
:total="total"
@current-change="handleCurrentChange"
:current-page="page">
</el-pagination> </el-pagination>
</div> </div>
</el-card> </el-card>
@ -110,7 +177,6 @@
import Setting from '@/setting' import Setting from '@/setting'
import axios from 'axios'; import axios from 'axios';
import util from "@/libs/util"; import util from "@/libs/util";
import qs from 'qs'
export default { export default {
name: 'customer', name: 'customer',
data () { data () {
@ -139,10 +205,10 @@ export default {
}], }],
listData: [], listData: [],
form: { form: {
customerType: +this.$route.query.customerType || '', customerType: '',
provinces: +this.$route.query.provinces || '', provinces: '',
city: +this.$route.query.city || '', city: '',
keyword: this.$route.query.keyword || '' keyword: ''
}, },
multipleSelection: [], multipleSelection: [],
provinceList: [], provinceList: [],
@ -162,11 +228,6 @@ export default {
}, },
}, },
mounted () { mounted () {
const { query } = this.$route
if (query.page) {
this.$router.push('/customer').catch(() => { })
}
this.getData() this.getData()
this.getProvince() this.getProvince()
}, },
@ -198,7 +259,6 @@ export default {
this.$get(this.api.queryProvince).then(res => { this.$get(this.api.queryProvince).then(res => {
this.provinceList = res.list this.provinceList = res.list
this.$store.commit("provinceData", { provinceList: this.provinceList }) this.$store.commit("provinceData", { provinceList: this.provinceList })
this.form.city && this.getCityData()
}).catch(res => { }) }).catch(res => { })
}, },
clearprovince () { clearprovince () {
@ -248,20 +308,13 @@ export default {
util.downloadFileDirect(`客户列表.xlsx`, new Blob([res.data])) util.downloadFileDirect(`客户列表.xlsx`, new Blob([res.data]))
}).catch(res => { }) }).catch(res => { })
}, },
// url
setReferrer () {
this.$store.commit('setReferrer', `${this.$route.path}?${qs.stringify(this.form)}&page=${this.page}`)
},
addcustomer () { addcustomer () {
this.setReferrer()
this.$router.push('addcustomer') this.$router.push('addcustomer')
}, },
edit (row) { edit (row) {
this.setReferrer()
this.$router.push(`addcustomer?id=${row.customerId}`) this.$router.push(`addcustomer?id=${row.customerId}`)
}, },
show (row) { show (row) {
this.setReferrer()
this.$router.push(`addcustomer?id=${row.customerId}&show=true`) this.$router.push(`addcustomer?id=${row.customerId}&show=true`)
}, },
handleDelete (row) { handleDelete (row) {
@ -311,6 +364,7 @@ export default {
}, },
handleCurrentChange (val) { handleCurrentChange (val) {
this.page = val this.page = val
this.$store.commit('SET_C_PAGE', val)
this.$router.push(`customer?page=${val}`) this.$router.push(`customer?page=${val}`)
this.getData() this.getData()
}, },
@ -335,6 +389,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.card { .card {
min-height: calc(100vh - 300px); min-height: calc(100vh - 300px);
} }
</style> </style>

@ -1,243 +1,212 @@
<template> <template>
<div class="wrap"> <div class="wrap">
<div class="side"> <div class="side">
<el-tree ref="type" <el-tree ref="type" :data="typeList" node-key="id" accordion :default-expanded-keys="defaultActive" :current-node-key="categoryId" :props="defaultProps" :highlight-current="true" @current-change="typeClick"></el-tree>
:data="typeList"
node-key="id"
accordion
:default-expanded-keys="defaultActive"
:current-node-key="categoryId"
:props="defaultProps"
:highlight-current="true"
@current-change="typeClick"></el-tree>
</div>
<div class="right">
<div class="flex-between"
style="margin-bottom: 10px;">
<p>数据简介</p>
<el-button v-if="introduceText && !editing"
type="primary"
@click="editing = !editing"
v-auth="'/data:数据简介:编辑'">编辑</el-button>
</div>
<div class="intro"
v-if="!introduceText && !editing">
<p class="text">请添加简介</p>
<div class="btn">
<el-button type="primary"
@click="edit">添加</el-button>
</div>
</div>
<template v-if="introduceText || editing">
<el-input placeholder="请输入简介"
v-model="introduce"
type="textarea"
rows="5"
:disabled="!editing"></el-input>
<div class="field">
<p class="label">数据源</p>
<el-input style="width: 250px"
placeholder="请输入数据源"
v-model="dataSource"
type="text"
:disabled="!editing"></el-input>
</div> </div>
</template>
<div class="field"> <div class="right">
<p class="label">关键字</p> <div class="flex-between" style="margin-bottom: 10px;">
<div class="tag-add" <p>数据简介</p>
v-if="editing"> <el-button v-if="introduceText && !editing" type="primary" @click="editing = !editing" v-auth="'/data:数据简介:编辑'">编辑</el-button>
<el-input placeholder="请输入关键字" </div>
size="small" <div class="intro" v-if="!introduceText && !editing">
v-model="newKeyword"></el-input> <p class="text">请添加简介</p>
<span v-if="editing"> <div class="btn">
<el-button @click="save" <el-button type="primary" @click="edit">添加</el-button>
style="color: #9076FF;border: 1px solid #9076FF;border-radius:5px;height: 25px;line-height: 0px"> </el-button> </div>
</span> </div>
</div> <template v-if="introduceText || editing">
<div class="tag-wrap"> <el-input placeholder="请输入简介" v-model="introduce" type="textarea" rows="5" :disabled="!editing"></el-input>
<el-tag :key="tag.id" <div class="field">
:type="editing ? '' : 'info'" <p class="label">数据源</p>
v-for="tag in keywordList" <el-input style="width: 250px" placeholder="请输入数据源" v-model="dataSource" type="text" :disabled="!editing"></el-input>
:closable="editing" </div>
:disable-transitions="false" </template>
@close="delKeyword(tag)"> <div class="field">
{{tag.keyword}} <p class="label">关键字</p>
</el-tag> <div class="tag-add" v-if="editing">
<el-input placeholder="请输入关键字" size="small" v-model="newKeyword"></el-input>
<span v-if="editing">
<el-button @click="save" style="color: #9076FF;border: 1px solid #9076FF;border-radius:5px;height: 25px;line-height: 0px"> </el-button>
</span>
</div>
<div class="tag-wrap">
<el-tag
:key="tag.id"
:type="editing ? '' : 'info'"
v-for="tag in keywordList"
:closable="editing"
:disable-transitions="false"
@close="delKeyword(tag)">
{{tag.keyword}}
</el-tag>
</div>
</div>
<div class="btns" v-if="editing">
<el-button @click="editing = false"> </el-button>
<el-button type="primary" @click="confirmData"> </el-button>
</div>
</div> </div>
</div>
<div class="btns"
v-if="editing">
<el-button @click="editing = false"> </el-button>
<el-button type="primary"
@click="confirmData"> </el-button>
</div>
</div> </div>
</div>
</template> </template>
<script> <script>
export default { export default {
data () { data() {
return { return {
id: this.$route.query.id || '', typeList: [],
typeList: [], defaultProps: {
defaultProps: { children: 'children',
children: 'children', label: 'label'
label: 'label' },
}, defaultActive: [],
defaultActive: [], editing: false,
editing: false, edited: false,
edited: false, introduce: '',
introduce: '', dataSource: '',
dataSource: '', introduceText: '',
introduceText: '', categoryId: '',
categoryId: '', keywordList: [],
keywordList: [], newKeyword: ''
newKeyword: '' };
};
},
watch: {
keyword: function (val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.getData()
}, 500)
}
},
mounted () {
this.getData()
},
methods: {
getData () {
//
this.$post(this.api.getTableByClassification).then(res => {
// idlabel
function handleId (data) {
data.map(n => {
n.id = String(n.id)
n.label = n.categoryName
if (n.children.length) {
handleId(n.children)
}
})
}
handleId(res)
this.typeList = res
if (!this.edited) {
// id
if (res[0].children.length) {
let item = res[0].children[0]
this.categoryId = item.id
this.dataSource = res[0].children[0].dataSource
this.defaultActive = [res[0].children[0].id]
// this.defaultActive = [item.id]
this.introduceText = item.introduce
this.introduce = item.introduce
} else {
this.categoryId = res[0].id
this.dataSource = res[0].dataSource
this.defaultActive = [res[0].children[0].id]
// this.defaultActive = [res[0].id]
this.introduceText = res[0].introduce
this.introduce = res[0].introduce
}
this.$nextTick(() => {
this.$refs.type.setCurrentKey(this.categoryId)
})
} else if (this.id) {
this.$nextTick(() => {
this.defaultActive = [+this.id]
this.$refs.type.setCurrentKey(+this.id)
})
}
this.getKeyword()
}).catch(res => { })
}, },
// watch: {
typeClick (data, node) { keyword: function(val) {
this.$router.push(`/data?tab=third&id=${data.id}`).catch(e => { }) clearTimeout(this.searchTimer)
this.editing = false this.searchTimer = setTimeout(() => {
this.categoryId = data.id this.getData()
this.defaultActive = [data.id] },500)
this.introduceText = data.introduce }
this.introduce = data.introduce
this.dataSource = data.dataSource
this.getKeyword()
},
//
getKeyword () {
this.$get(this.api.getKeywordByCategoryId, {
categoryId: this.categoryId
}).then(res => {
this.keywordList = res.keywords
}).catch(res => { })
},
//
edit () {
this.editing = true
this.introduce = this.introduceText
}, },
// mounted(){
saveType () {
const id = this.categoryId // id
this.$post(this.api.updateCategory, {
id,
introduce: this.introduce,
dataSource: this.dataSource
}).then(res => {
this.$message.success(this.introduceText ? '编辑成功' : '新增成功')
this.introduceText = this.introduce
this.editing = false
this.edited = true
this.getData() this.getData()
}).catch(res => { })
},
//
delKeyword (item) {
this.$post(`${this.api.deleteKeyword}?categoryId=${this.categoryId}&keyword=${item.keyword}`).then(res => {
this.$message.success('删除成功')
this.getKeyword()
}).catch(res => { })
},
save () {
const keyword = this.newKeyword
if (keyword) {
if (this.keywordList.find(e => e.keyword === keyword)) return this.$message.error('请不要输入重复关键字!')
// this.confirmEdit()
this.$post(this.api.addKeyword, {
categoryId: this.categoryId,
keyword
}).then(res => {
this.newKeyword = ''
this.getKeyword()
}).catch(res => { })
} else {
this.confirmEdit()
}
}, },
// methods: {
confirmData () { getData(){
const keyword = this.newKeyword // //
// this.$post(this.api.getTableByClassification).then(res => {
if (keyword) { // idlabel
// function handleId(data){
if (this.keywordList.find(e => e.keyword === keyword)) return this.$message.error('请不要输入重复关键字!') data.map(n => {
this.saveType() n.id = String(n.id)
// n.label = n.categoryName
this.$post(this.api.addKeyword, { if(n.children.length){
categoryId: this.categoryId, handleId(n.children)
keyword }
}).then(res => { })
this.newKeyword = '' // }
this.getKeyword() handleId(res)
}).catch(res => { }) console.log(res)
} else {
this.saveType() this.typeList = res
} // id
if (!this.edited) {
if(res[0].children.length){
let item = res[0].children[0]
this.categoryId = item.id
this.dataSource = res[0].children[0].dataSource
this.defaultActive = [res[0].children[0].id]
// this.defaultActive = [item.id]
this.introduceText = item.introduce
this.introduce = item.introduce
}else{
this.categoryId = res[0].id
this.dataSource = res[0].dataSource
this.defaultActive = [res[0].children[0].id]
// this.defaultActive = [res[0].id]
this.introduceText = res[0].introduce
this.introduce = res[0].introduce
}
this.$nextTick(() => {
this.$refs.type.setCurrentKey(this.categoryId)
})
}
this.getKeyword()
}).catch(res => {})
},
//
typeClick(data,node){
console.log(data)
this.editing = false
this.categoryId = data.id
this.defaultActive = [data.id]
this.introduceText = data.introduce
this.introduce = data.introduce
this.dataSource = data.dataSource
this.getKeyword()
},
//
getKeyword(){
this.$get(this.api.getKeywordByCategoryId,{
categoryId: this.categoryId
}).then(res => {
this.keywordList = res.keywords
}).catch(res => {})
},
//
edit(){
this.editing = true
this.introduce = this.introduceText
},
//
saveType(){
const id = this.categoryId // id
this.$post(this.api.updateCategory,{
id,
introduce: this.introduce,
dataSource: this.dataSource
}).then(res => {
this.$message.success(this.introduceText ? '编辑成功' : '新增成功')
this.introduceText = this.introduce
this.editing = false
this.edited = true
// this.getData()
}).catch(res => {})
},
//
delKeyword(item) {
this.$post(`${this.api.deleteKeyword}?categoryId=${this.categoryId}&keyword=${item.keyword}`).then(res => {
this.$message.success('删除成功')
this.getKeyword()
}).catch(res => {})
},
save(){
const keyword = this.newKeyword
if (keyword) {
if (this.keywordList.find(e => e.keyword === keyword)) return this.$message.error('请不要输入重复关键字!')
// this.confirmEdit()
this.$post(this.api.addKeyword,{
categoryId: this.categoryId,
keyword
}).then(res => {
this.newKeyword = ''
this.getKeyword()
}).catch(res => {})
} else {
this.confirmEdit()
}
},
//
confirmData() {
const keyword = this.newKeyword //
//
if (keyword) {
//
if (this.keywordList.find(e => e.keyword === keyword)) return this.$message.error('请不要输入重复关键字!')
this.saveType()
//
this.$post(this.api.addKeyword,{
categoryId: this.categoryId,
keyword
}).then(res => {
this.newKeyword = '' //
this.getKeyword()
}).catch(res => {})
} else {
this.saveType()
}
}
} }
}
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -255,12 +224,12 @@ export default {
width: calc(100% - 374px); width: calc(100% - 374px);
padding: 24px 0; padding: 24px 0;
} }
.intro { .intro{
padding: 20px; padding: 20px;
margin: 20px 0; margin: 20px 0;
border: 1px solid #dcdcdc; border: 1px solid #dcdcdc;
border-radius: 4px; border-radius: 4px;
.text { .text{
margin-bottom: 20px; margin-bottom: 20px;
} }
} }
@ -275,7 +244,7 @@ export default {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.btns { .btns{
margin-top: 20px; margin-top: 20px;
} }
} }
@ -290,7 +259,7 @@ export default {
margin-left: 5px; margin-left: 5px;
} }
} }
.mag { .mag{
margin-right: 20px; margin-right: 20px;
margin-left: 20px; margin-left: 20px;
} }

@ -5,81 +5,80 @@
<div class="box"> <div class="box">
<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 }" <li v-for="(item, i) in tabList" :key="i" :class="{active: activeIndex == item.id}" @click="handleSelect(item.id)">{{item.label}}</li>
@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"
</el-input> placeholder="请输入密码"
</el-form-item> v-model="param.password"
<el-form-item prop="code" v-if="showVerify"> >
<el-input placeholder="请输入验证码" v-model="param.code" @keyup.enter.native="submitForm()"> </el-input>
</el-input> </el-form-item>
<img @click="blur" :src="verificationIMG" class="verification" alt=""> <el-form-item prop="code" v-if="showVerify">
</el-form-item> <el-input
<div class="login-btn"> placeholder="请输入验证码"
<el-button type="primary" @click="submitForm()">马上登录</el-button> v-model="param.code"
</div> @keyup.enter.native="submitForm()"
</el-form> >
</el-input>
<el-form v-show="activeIndex === '2'" :model="phoneOrEmail" :rules="phoneOrEmailrules" ref="phoneOrEmail" <img @click="blur" :src="verificationIMG" class="verification" alt="">
label-width="0px"> </el-form-item>
<el-form-item prop="account"> <div class="login-btn">
<el-input @blur="phoneBlur" v-model="phoneOrEmail.account" placeholder="请输入电话/邮箱"></el-input> <el-button type="primary" @click="submitForm()">马上登录</el-button>
</el-form-item> </div>
<el-form-item prop="password"> </el-form>
<el-input type="password" placeholder="请输入密码" v-model="phoneOrEmail.password">
</el-input> <el-form v-show="activeIndex==='2'" :model="phoneOrEmail" :rules="phoneOrEmailrules" ref="phoneOrEmail" label-width="0px">
</el-form-item> <el-form-item prop="account">
<el-form-item prop="code" v-if="showPhoneVerify"> <el-input @blur="phoneBlur" v-model="phoneOrEmail.account" placeholder="请输入电话/邮箱"></el-input>
<el-input placeholder="请输入验证码" v-model="phoneOrEmail.code" @keyup.enter.native="submitForm('phone')"> </el-form-item>
</el-input> <el-form-item prop="password">
<img @click="phoneBlur" :src="PhoneVerificationIMG" class="verification" alt=""> <el-input
</el-form-item> type="password"
<div class="login-btn"> placeholder="请输入密码"
<el-button type="primary" @click="submitForm('phone')">马上登录</el-button> v-model="phoneOrEmail.password"
</div> >
</el-form> </el-input>
</el-form-item>
<el-form-item prop="code" v-if="showPhoneVerify">
<el-input
placeholder="请输入验证码"
v-model="phoneOrEmail.code"
@keyup.enter.native="submitForm('phone')"
>
</el-input>
<img @click="phoneBlur" :src="PhoneVerificationIMG" class="verification" alt="">
</el-form-item>
<div class="login-btn">
<el-button type="primary" @click="submitForm('phone')">马上登录</el-button>
</div>
</el-form>
</div> </div>
</div> </div>
</div> </div>
<el-dialog title="绑定手机号" :visible.sync="phoneVisible" :close-on-click-modal="false" width="576px"> <el-dialog title="绑定手机号" :visible.sync="phoneVisible" :close-on-click-modal="false" width="576px">
<p class="tips">依据国家政策法规需绑定手机号进行网络实名才可登录使用本平台</p> <p class="tips">依据国家政策法规需绑定手机号进行网络实名才可登录使用本平台</p>
<el-form ref="form" label-width="60px"> <el-form ref="form" label-width="60px">
<el-form-item label="手机号"> <el-form-item label="手机号">
<el-input placeholder="请输入手机号" v-model="phone" maxlength="11"></el-input> <el-input placeholder="请输入手机号" 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" 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 style="margin-left:10px" @click="sendPhoneCode" :disabled="phoneDisabled">{{phoneBtnText}}</el-button>
}}</el-button> </div>
</div> </el-form-item>
</el-form-item> </el-form>
</el-form> <span slot="footer" class="dialog-footer">
<span slot="footer" class="dialog-footer"> <el-button @click="phoneVisible = false"> </el-button>
<el-button @click="phoneVisible = false"> </el-button> <el-button type="primary" @click="phoneSubmit"> </el-button>
<el-button type="primary" @click="phoneSubmit"> </el-button> </span>
</span>
</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> </el-dialog>
<v-footer class="footer" ref="footer"></v-footer> <v-footer class="footer" ref="footer"></v-footer>
</div> </div>
@ -88,272 +87,217 @@
<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) => {//
let emailReg = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ let emailReg = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
let phoneReg = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/ let phoneReg = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/
if (value === '') { if (value === '') {
callback(new Error('请输入手机或邮箱!')); callback(new Error('请输入手机或邮箱!'));
} else if (!emailReg.test(value) && !phoneReg.test(value)) { } else if (!emailReg.test(value)&&!phoneReg.test(value)) {
callback(new Error('输入的手机/邮箱格式不正确!')); callback(new Error('输入的手机/邮箱格式不正确!'));
} else {
callback();
}
};
return {
tabList: [
{
id: '1',
label: '账号登录'
}, {
id: '2',
label: '手机号/邮箱登录'
}
],
activeIndex: "1",
showVerify: true,// -
verificationIMG: '',//
//
param: {
account: '',
password: '',
code: '',
platform: 3,
random: '',
distinguish: 1,
type: 2
},
rules: {
account: [{ required: true, message: '请输入账号', trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
code: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
},
// +
showPhoneVerify: true,// -
PhoneVerificationIMG: '',//
phoneOrEmail: {
account: '',
password: '',
code: '',
platform: 3,
random: '',
distinguish: 2,
type: 2
},
phoneOrEmailrules: {
account: [{ validator: regPhoneOrEmail, trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
code: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
},
phoneVisible: false,
phone: '',
phoneCode: '',
phoneDisabled: false,
phoneBtnText: '发送验证码',
phoneTimer: '',
phoneOpener: '',
userVisible: false,
users: [],
};
},
components: {
vFooter
},
watch: {
verificationIMG: function (val) {// --
if (val) {
this.showVerify = true
} else {
this.showVerify = false
}
},
PhoneVerificationIMG: function (val) {// --
if (val) {
this.showPhoneVerify = true
} else {
this.showPhoneVerify = false
}
},
},
created () {
if (this.param.account) {
this.showVerify = true
}
this.blur()
},
methods: {
submitForm (val) {
let ref = val === 'phone' ? 'phoneOrEmail' : 'login'
let param = val === 'phone' ? this.phoneOrEmail : this.param
this.$refs[ref].validate(valid => {
if (valid) {
this.$post(this.api.logins, param).then(({ status, data, message }) => {
localStorage.removeItem('examPath')
localStorage.removeItem('reviewPath')
this.getOss()
if (status == 200) {
const accounts = data.userAccounts
//
if (accounts instanceof Array) {
this.users = accounts
this.userVisible = true
} else {
sessionStorage.setItem('token', data.token)
this.setLogin()
}
} else { } else {
param.code = '' callback();
this.$message.error(message)
} }
}).catch(err => { };
if (err.status === 30001) { return {
this.phoneVisible = true tabList: [
} else if (err.status == 10004 || err.status == 10005) { {
param.code = '' id: '1',
this.blur() label: '账号登录'
} }, {
}); id: '2',
} else { label: '手机号/邮箱登录'
this.$message.error('请输入账号/密码/验证码'); }
return false; ],
} activeIndex:"1",
});
}, showVerify: true,// -
// oss verificationIMG:'',//
async getOss () {
const A = (key, encryptedData) => { //
const keyHex = CryptoJS.enc.Base64.parse(key) param: {
const decrypted = CryptoJS.AES.decrypt(encryptedData, keyHex, { account: '',
mode: CryptoJS.mode.ECB, password: '',
padding: CryptoJS.pad.Pkcs7 code:'',
}) platform:3,
return decrypted.toString(CryptoJS.enc.Utf8) random:'',
} distinguish:1,
type: 2
const R = (encryptedKey, privateKey) => { },
const decrypt = new JSEncrypt() rules: {
decrypt.setPrivateKey(privateKey) account: [{ required: true, message: '请输入账号', trigger: 'blur' }],
const decryptedKey = decrypt.decrypt(encryptedKey) password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
return decryptedKey code: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
} },
const res = await this.$get(this.api.encrypt) // +
const RE = A(R(res.encryptedKey, res.privateKey), res.encryptedData).split('/') showPhoneVerify:true,// -
localStorage.setItem('osc', JSON.stringify(RE)) PhoneVerificationIMG:'',//
}, phoneOrEmail: {
// account: '',
chooseUser (user) { password: '',
user.isEnable && this.$post(`${this.api.getToken}?id=${user.id}`).then(({ data }) => { code:'',
sessionStorage.setItem('token', data.token) platform:3,
this.token = data.token random:'',
this.setLogin() distinguish:2,
}).catch(res => { }) type: 2
}, },
// phoneOrEmailrules:{
async setLogin () { account: [{ validator: regPhoneOrEmail, trigger: 'blur' }],
try { password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
const res = await this.$get(`${this.api.getUserRolesPermissionMenu}?platformId=${Setting.platformId}`) code: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
const list = res.permissionMenu },
addRoutes(res.permissionMenu[0].children)
this.$store.commit('setDataPer', res.dataPermissionList) phoneVisible:false,
this.$message.success('登录成功!') phone:'',
this.$router.push({ phoneCode:'',
path: list[0].children[0].path phoneDisabled:false,
}); phoneBtnText: '发送验证码',
localStorage.setItem('ms_username', this.param.username); phoneTimer:'',
} catch (e) { phoneOpener:''
if (e.status === 500) {
sessionStorage.clear() };
}
}
},
blur () {
this.param.random = Math.floor(Math.random() * 999999999)
this.verificationIMG = this.api.verification + '?random=' + `${this.param.random}`
}, },
phoneBlur () { components: {
this.phoneOrEmail.random = Math.floor(Math.random() * 999999999) vFooter
this.PhoneVerificationIMG = this.api.verification + '?random=' + `${this.phoneOrEmail.random}`
}, },
handleSelect (val) { watch:{
this.activeIndex = val verificationIMG:function(val){// --
this.param.account = ""; if(val){
this.param.password = ""; this.showVerify = true
this.param.code = ""; }else{
this.phoneOrEmail.account = ""; this.showVerify = false
this.phoneOrEmail.password = ""; }
this.phoneOrEmail.code = ""; },
this.$refs.phoneOrEmail.clearValidate() PhoneVerificationIMG:function(val){// --
// this.blur() if(val){
this.phoneBlur() this.showPhoneVerify = true
}else{
this.showPhoneVerify = false
}
},
}, },
sendPhoneCode () { created(){
if (!this.phone) return this.$message.warning('请输入手机号') if(this.param.account){
if (!/^1[3456789]\d{9}$/.test(this.phone)) return this.$message.warning('请输入正确的手机号') this.showVerify = true
let data = {
phone: this.phone,
types: 2
}
this.$post(this.api.sendPhoneOrEmailCode, data).then(res => {
this.phoneCountdown()//
if (res.message.opener) {
this.phoneOpener = res.message.opener
} else {
this.$message(res.message)
} }
this.blur()
}).catch(res => { })
},
phoneSubmit () {
if (!this.phone) return this.$message.warning('请输入手机号')
if (!/^1[3456789]\d{9}$/.test(this.phone)) return this.$message.warning('请输入正确的手机号')
if (!this.phoneCode) return this.$message.warning('请输入验证码')
let data = {
phone: this.phone,
types: 2,
code: this.phoneCode,
opener: this.phoneOpener,
platform: 3,
account: this.param.account
}
this.$post(this.api.bindPhoneOrEmail, data).then(res => {
sessionStorage.setItem('token', res.token)
this.$router.push({
path: '/customer'
});
localStorage.setItem('ms_username', this.param.username);
this.$message.success('绑定成功')
// this.form.phone = this.phone
// this.phoneVisible = false
}).catch(res => { })
}, },
phoneCountdown () { methods: {
let count = 60 submitForm(val) {
if (!this.phoneTimer) { let ref = val==='phone'?'phoneOrEmail':'login'
this.phoneDisabled = true let param = val==='phone'?this.phoneOrEmail:this.param
this.phoneTimer = setInterval(() => { this.$refs[ref].validate(valid => {
if (count > 0) { if (valid) {
count-- this.$post(this.api.logins,param).then(res => {
this.phoneBtnText = `${count}秒后重试` const { message } = res
} else { sessionStorage.setItem('token',res.data.token)
this.phoneDisabled = false this.$get(`${this.api.getUserRolesPermissionMenu}?platformId=${Setting.platformId}`).then(res => {
clearInterval(this.phoneTimer) const list = res.permissionMenu
this.phoneTimer = null this.$store.commit('setDataPer', res.dataPermissionList)
this.phoneBtnText = `发送验证码` this.$message.success(message);
} this.$router.push({
}, 1000) path: list[0].children[0].path
} });
localStorage.setItem('ms_username', this.param.username);
}).catch(err => {
if (err.status === 500) {
sessionStorage.clear()
}
})
}).catch(err => {
if(err.status===30001){
this.phoneVisible = true
}else if(err.status == 10004){
this.blur()
}
});
} else {
this.$message.error('请输入账号/密码/验证码');
return false;
}
});
},
blur(){
this.param.random = Math.floor(Math.random()*999999999)
this.verificationIMG = this.api.verification+'?random='+`${this.param.random}`
},
phoneBlur(){
this.phoneOrEmail.random = Math.floor(Math.random()*999999999)
this.PhoneVerificationIMG = this.api.verification+'?random='+`${this.phoneOrEmail.random}`
},
handleSelect(val){
this.activeIndex = val
this.param.account = "";
this.param.password = "";
this.param.code = "";
this.phoneOrEmail.account = "";
this.phoneOrEmail.password = "";
this.phoneOrEmail.code = "";
this.$refs.phoneOrEmail.clearValidate()
// this.blur()
this.phoneBlur()
},
sendPhoneCode(){
if(!this.phone) return this.$message.warning('请输入手机号')
if(!/^1[3456789]\d{9}$/.test(this.phone)) return this.$message.warning('请输入正确的手机号')
let data = {
phone: this.phone,
types: 2
}
this.$post(this.api.sendPhoneOrEmailCode,data).then(res => {
this.phoneCountdown()//
if(res.message.opener){
this.phoneOpener = res.message.opener
}else{
this.$message(res.message)
}
}).catch(res => {})
},
phoneSubmit(){
if(!this.phone) return this.$message.warning('请输入手机号')
if(!/^1[3456789]\d{9}$/.test(this.phone)) return this.$message.warning('请输入正确的手机号')
if(!this.phoneCode) return this.$message.warning('请输入验证码')
let data = {
phone: this.phone,
types: 2,
code: this.phoneCode,
opener: this.phoneOpener,
platform: 3,
account: this.param.account
}
this.$post(this.api.bindPhoneOrEmail,data).then(res => {
sessionStorage.setItem('token',res.token)
this.$router.push({
path:'/customer'
});
localStorage.setItem('ms_username', this.param.username);
this.$message.success('绑定成功')
// this.form.phone = this.phone
// this.phoneVisible = false
}).catch(res => {})
},
phoneCountdown(){
let count = 60
if(!this.phoneTimer){
this.phoneDisabled = true
this.phoneTimer = setInterval(() => {
if(count > 0){
count--
this.phoneBtnText = `${count}秒后重试`
}else{
this.phoneDisabled = false
clearInterval(this.phoneTimer)
this.phoneTimer = null
this.phoneBtnText = `发送验证码`
}
},1000)
}
},
}, },
},
}; };
</script> </script>
@ -361,28 +305,24 @@ 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;
@ -390,129 +330,76 @@ 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 {
margin-bottom: 25px;
}
.verification {
position: absolute;
top: 1px;
right: 1px;
width: 160px;
height: 47px;
cursor: pointer;
}
}
.tab {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 24px;
li {
padding: 18px 5px;
margin: 0 20px;
font-size: 16px;
font-weight: 600;
color: #fff;
cursor: pointer;
border-bottom: 2px solid transparent;
&:last-child {
margin-right: 0;
} }
.el-form-item {
&.active { margin-bottom: 25px;
color: #fff; }
border-bottom-color: #ccc; .verification{
position: absolute;
top: 1px;
right: 1px;
width: 160px;
height: 47px;
cursor: pointer;
} }
}
} }
.tab{
.title { display: flex;
font-size: 16px; justify-content: center;
text-align: center; align-items: center;
font-weight: bold; margin-bottom: 24px;
li{
padding: 18px 5px;
margin: 0 20px;
font-size: 16px;
font-weight: 600;
color: #fff;
cursor: pointer;
border-bottom: 2px solid transparent;
&:last-child{
margin-right: 0;
}
&.active{
color: #fff;
border-bottom-color: #ccc;
}
}
}
.title{
font-size: 16px;
text-align: center;
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;
margin-bottom: 50px; margin-bottom: 50px;
font-weight: bold; font-weight: bold;
background: #1dabff; background: #1dabff;
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{
color: #0092FF;
&:hover {
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>

@ -1,231 +1,211 @@
<template> <template>
<div> <div>
<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="goBack" :content="'新增文章'"></el-page-header>
<el-page-header @back="goBack"
:content="'新增文章'"></el-page-header>
</div>
</el-card>
<el-card shadow="hover"
class="m-b-20">
<el-form :model="form"
:rules="rules"
ref="form"
label-width="90px"
label-suffix=":"
size="small">
<el-form-item prop="coverUrl"
label="封面图">
<el-upload class="avatar-uploader"
accept=".jpg,.png,.jpeg"
:on-remove="handleRemove"
:on-error="uploadError"
:before-remove="beforeRemove"
:limit="1"
:on-exceed="handleExceed"
action=""
:http-request="handleRequest">
<img v-if="form.coverUrl"
:src="form.coverUrl"
class="avatar">
<div class="uploader-default"
v-else>
<i class="el-icon-plus"></i>
<p>上传封面</p>
</div> </div>
</el-upload> </el-card>
</el-form-item> <el-card shadow="hover" class="m-b-20">
<el-form-item prop="author" <el-form :model="form" :rules="rules" ref="form" label-width="90px" label-suffix=":" size="small">
label="作者"> <el-form-item prop="coverUrl" label="封面图">
<div class="d-inline-block"> <el-upload
<el-input placeholder="请输入作者" class="avatar-uploader"
v-model="form.author" accept=".jpg,.png,.jpeg"
clearable></el-input> :on-remove="handleRemove"
</div> :on-error="uploadError"
</el-form-item> :on-success="uploadSuccess"
<el-form-item prop="date" :before-remove="beforeRemove"
label="日期"> :limit="1"
<div class="d-inline-block"> :on-exceed="handleExceed"
<el-date-picker v-model="form.date" :action="this.api.fileupload"
type="date" :headers="headers"
value-format="yyyy-MM-dd HH:mm:ss" name="file"
placeholder="选择日期"></el-date-picker> >
</div> <img v-if="form.coverUrl" :src="form.coverUrl" class="avatar">
</el-form-item> <div class="uploader-default" v-else>
<el-form-item prop="title" <i class="el-icon-plus"></i>
label="文章标题"> <p>上传封面</p>
<el-input placeholder="请输入文章标题" </div>
v-model="form.title" </el-upload>
clearable></el-input> </el-form-item>
</el-form-item> <el-form-item prop="author" label="作者">
<el-form-item prop="content" <div class="d-inline-block">
label="文章内容"> <el-input placeholder="请输入作者" v-model="form.author" clearable></el-input>
<quill :border="true" </div>
v-model="form.content" </el-form-item>
:uploading.sync="uploading" <el-form-item prop="date" label="日期">
:height="400" /> <div class="d-inline-block">
</el-form-item> <el-date-picker v-model="form.date" type="date" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期"></el-date-picker>
<el-form-item> </div>
<el-button type="primary" </el-form-item>
@click="saveData">确定</el-button> <el-form-item prop="title" label="文章标题">
</el-form-item> <el-input placeholder="请输入文章标题" v-model="form.title" clearable></el-input>
</el-form> </el-form-item>
</el-card> <el-form-item prop="content" label="文章内容">
</div> <quill :border="true" v-model="form.content" :uploading.sync="uploading" :height="400" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="saveData">确定</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template> </template>
<script> <script>
import Oss from '@/components/upload/upload.js'
import quill from "@/components/quill"; import quill from "@/components/quill";
import util from "@/libs/util"; import util from "@/libs/util";
export default { export default {
name: "addarticle", name: "addarticle",
data () { data() {
return { return {
headers: { headers: {
token: sessionStorage.getItem('token') token: sessionStorage.getItem('token')
}, },
form: { form: {
columnId: +this.$route.query.columnId, columnId: +this.$route.query.columnId,
sort: +this.$route.query.sort, sort: +this.$route.query.sort,
id: '', id: '',
coverUrl: '', coverUrl: '',
author: '', author: '',
date: '', date: '',
title: '', title: '',
content: '', content: '',
createUser: this.$store.state.userName createUser: this.$store.state.userName
}, },
rules: { rules: {
coverUrl: [ coverUrl: [
{ required: true, message: '请上传封面', trigger: 'change' } { required: true, message: '请上传封面', trigger: 'change' }
], ],
author: [ author: [
{ required: true, message: '请输入作者', trigger: 'blur' } { required: true, message: '请输入作者', trigger: 'blur' }
], ],
date: [ date: [
{ required: true, message: '请选择日期', trigger: 'change' } { required: true, message: '请选择日期', trigger: 'change' }
], ],
title: [ title: [
{ required: true, message: '请输入文章标题', trigger: 'blur' } { required: true, message: '请输入文章标题', trigger: 'blur' }
], ],
content: [ content: [
{ required: true, message: '请输入文章内容', trigger: 'blur' } { required: true, message: '请输入文章内容', trigger: 'blur' }
], ],
}, },
uploadList: [], uploadList: [],
uploadDataList: [], uploadDataList: [],
submiting: false, submiting: false,
uploading: false uploading: false
}; };
},
components: {
quill
},
mounted () {
this.id = this.$route.query.id;
this.id && this.getData();
},
methods: {
//
goBack () {
this.$router.back();
}, },
getData () { components: {
this.$get(`${this.api.getArticle}?articleId=${this.id}`).then(({ article }) => { quill
this.form = article
}).catch(err => { })
}, },
saveData () { mounted() {
this.$refs.form.validate((valid) => { this.id = this.$route.query.id;
if (valid) { this.id && this.getData();
if (this.submiting) return false },
const { form } = this methods: {
if (this.uploading) return util.warningMsg("图片正在上传中,请稍等"); //
this.submiting = true goBack() {
if (form.id) { this.$router.back();
this.$put(this.api.editArticle, form).then(res => { },
this.submiting = false; getData() {
util.successMsg("修改成功"); this.$get(`${this.api.getArticle}?articleId=${this.id}`).then(({ article }) => {
this.back(); this.form = article
}) }).catch(err => {})
.catch(err => { },
this.submiting = false; saveData() {
}); this.$refs.form.validate((valid) => {
} else { if (valid) {
this.$post(this.api.addArticle, form).then(res => { if (this.submiting) return false
this.submiting = false; const { form } = this
util.successMsg("创建成功"); if (this.uploading) return util.warningMsg("图片正在上传中,请稍等");
this.back(); this.submiting = true
if (form.id) {
this.$put(this.api.editArticle, form).then(res => {
this.submiting = false;
util.successMsg("修改成功");
this.back();
})
.catch(err => {
this.submiting = false;
});
} else {
this.$post(this.api.addArticle, form).then(res => {
this.submiting = false;
util.successMsg("创建成功");
this.back();
})
.catch(err => {
this.submiting = false;
});
}
}
})
},
handleCurrentChange(val) {
this.currPage = val;
},
handleExceed(files, fileList) {
util.warningMsg(`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`);
},
uploadSuccess(res, file, fileList) {
if (this.form.coverUrl) {
let fileName = this.coverUrl.replace("https://liuwanr.oss-cn-shenzhen.aliyuncs.com/", "");
this.$del(`${this.api.fileDeletion}?keys=${fileName}`).then(res => {
}).catch(res => {
});
}
this.form.coverUrl = res.data.filesResult.fileUrl;
},
uploadError(err, file, fileList) {
this.$message({
message: "上传出错,请重试!",
type: "error",
center: true
});
},
beforeRemove(file, fileList) {
return this.$confirm(`确定移除 ${file.name}`);
},
handleRemove(file, fileList) {
let fileName = this.form.coverUrl.replace("https://liuwanr.oss-cn-shenzhen.aliyuncs.com/", "");
this.$del(`${this.api.fileDeletion}?keys=${fileName}`).then(res => {
this.form.coverUrl = "";
}).catch(res => {
});
},
uploadSure() {
this.BatchUpload = false;
this.pageNo = 1;
this.keyword = "";
this.getData();
},
back() {
this.$router.back();
},
goback() {
this.$confirm("确定返回?未更新的信息将不会保存。", "提示", {
type: "warning"
}) })
.catch(err => { .then(() => {
this.submiting = false; this.back();
}); })
} .catch(() => {
});
},
addSponsor() {
this.sponsorList.push("");
},
delSponsor(index) {
this.sponsorList.splice(index, 1);
},
addOrganizer() {
this.organzinerList.push("");
},
delOrganizer(index) {
this.organzinerList.splice(index, 1);
} }
})
},
handleCurrentChange (val) {
this.currPage = val;
},
handleExceed (files, fileList) {
util.warningMsg(`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`);
},
//
async handleRequest ({ file }) {
this.form.coverUrl && Oss.del(this.form.coverUrl)
Oss.upload(file).then(res => {
this.form.coverUrl = res.url
})
},
uploadError (err, file, fileList) {
this.$message({
message: "上传出错,请重试!",
type: "error",
center: true
});
},
beforeRemove (file, fileList) {
return this.$confirm(`确定移除 ${file.name}`);
},
handleRemove (file, fileList) {
Oss.del(this.form.coverUrl)
this.form.coverUrl = ''
},
uploadSure () {
this.BatchUpload = false;
this.pageNo = 1;
this.keyword = "";
this.getData();
},
back () {
this.$router.back();
},
goback () {
this.$confirm("确定返回?未更新的信息将不会保存。", "提示", {
type: "warning",
closeOnClickModal: false
})
.then(() => {
this.back();
})
.catch(() => {
});
},
addSponsor () {
this.sponsorList.push("");
},
delSponsor (index) {
this.sponsorList.splice(index, 1);
},
addOrganizer () {
this.organzinerList.push("");
},
delOrganizer (index) {
this.organzinerList.splice(index, 1);
} }
}
}; };
</script> </script>
@ -241,7 +221,7 @@ $avatar-width: 104px;
overflow: hidden; overflow: hidden;
&:hover { &:hover {
border-color: #409eff; border-color: #409EFF;
} }
.uploader-default { .uploader-default {
@ -292,8 +272,7 @@ $avatar-width: 104px;
/deep/ .d-inline-block { /deep/ .d-inline-block {
width: 216px; width: 216px;
.el-select, .el-select, .el-input {
.el-input {
width: 100%; width: 100%;
} }
} }

@ -1,257 +1,220 @@
<template> <template>
<div> <div>
<div class="page"> <div class="page">
<div class="btn-wrap"> <div class="btn-wrap">
<template v-if="sorting"> <template v-if="sorting">
<el-button class="action-btn" <el-button class="action-btn" type="primary" round @click="cancelSort">取消</el-button>
type="primary" <el-button class="action-btn" type="primary" round @click="sortSubmit">保存</el-button>
round
@click="cancelSort">取消</el-button>
<el-button class="action-btn"
type="primary"
round
@click="sortSubmit">保存</el-button>
</template>
<template v-if="!sorting">
<el-button v-auth="'栏目管理:更改排序'"
class="action-btn"
type="primary"
round
@click="openSort">更改排序
</el-button>
<el-button v-auth="'栏目管理:添加栏目'"
class="action-btn"
type="primary"
round
@click="handleColumn(false, 0, 0)">添加栏目
</el-button>
</template>
</div>
<div class="page-content"
style="padding-top: 24px; margin-top: 24px">
<div class="el-table">
<div class="list">
<div class="thead">
<span>栏目名称</span>
<span><em :class="{hide: sorting}"
style="font-style: normal">操作</em></span>
</div>
</div>
<el-tree :data="list"
node-key="id"
default-expand-all
:draggable="sorting"
:allow-drop="allowDrop">
<span class="custom-tree-node"
slot-scope="{ node, data }">
<span class="name">{{ data.name }}</span>
<span class="action"
v-show="!sorting">
<el-button v-auth="'栏目管理:编辑'"
type="text"
@click.stop="handleColumn(data)">编辑</el-button>
<el-divider v-auth="'栏目管理:编辑'"
direction="vertical"></el-divider>
<template v-if="node.level < 4">
<el-button v-auth="'栏目管理:新增'"
type="text"
@click.stop="handleColumn(data, data.id, data.level + 1)">新增</el-button>
<el-divider v-auth="'栏目管理:新增'"
direction="vertical"></el-divider>
</template> </template>
<el-button v-auth="'栏目管理:删除'" <template v-if="!sorting">
type="text" <el-button v-auth="'栏目管理:更改排序'" class="action-btn" type="primary" round @click="openSort">更改排序
@click.stop="delData(data)">删除</el-button> </el-button>
</span> <el-button v-auth="'栏目管理:添加栏目'" class="action-btn" type="primary" round @click="handleColumn(false, 0, 0)">添加栏目
</span> </el-button>
</el-tree> </template>
</div>
<div class="page-content" style="padding-top: 24px; margin-top: 24px">
<div class="el-table">
<div class="list">
<div class="thead">
<span>栏目名称</span>
<span><em :class="{hide: sorting}" style="font-style: normal">操作</em></span>
</div>
</div>
<el-tree :data="list" node-key="id" default-expand-all :draggable="sorting" :allow-drop="allowDrop">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span class="name">{{ data.name }}</span>
<span class="action" v-show="!sorting">
<el-button v-auth="'栏目管理:编辑'" type="text" @click.stop="handleColumn(data)">编辑</el-button>
<el-divider v-auth="'栏目管理:编辑'" direction="vertical"></el-divider>
<template v-if="node.level < 4">
<el-button v-auth="'栏目管理:新增'" type="text" @click.stop="handleColumn(data, data.id, data.level + 1)">新增</el-button>
<el-divider v-auth="'栏目管理:新增'" direction="vertical"></el-divider>
</template>
<el-button v-auth="'栏目管理:删除'" type="text" @click.stop="delData(data)">删除</el-button>
</span>
</span>
</el-tree>
</div>
</div>
</div> </div>
</div>
</div>
<el-dialog :title="!curRow.id ? '添加栏目' : '编辑栏目'" <el-dialog :title="!curRow.id ? '添加栏目' : '编辑栏目'" :visible.sync="columnVisible" width="400px"
:visible.sync="columnVisible" :close-on-click-modal="false" @close="closeColumn">
width="400px" <el-form>
:close-on-click-modal="false" <el-form-item>
@close="closeColumn"> <el-input placeholder="栏目名称" v-model="curRow.name"></el-input>
<el-form> </el-form-item>
<el-form-item> </el-form>
<el-input placeholder="栏目名称" <span slot="footer" class="dialog-footer">
v-model="curRow.name"></el-input> <el-button @click="columnVisible = false"> </el-button>
</el-form-item> <el-button type="primary" @click="columnSubmit"> </el-button>
</el-form> </span>
<span slot="footer" </el-dialog>
class="dialog-footer"> </div>
<el-button @click="columnVisible = false"> </el-button>
<el-button type="primary"
@click="columnSubmit"> </el-button>
</span>
</el-dialog>
</div>
</template> </template>
<script> <script>
import util from "@/libs/util"; import util from "@/libs/util";
import Setting from '@/setting' import Setting from '@/setting'
export default { export default {
name: "columnManage", name: "columnManage",
data () { data() {
return { return {
activeName: "first", activeName: "first",
tabs: { tabs: {
first: "栏目管理" first: "栏目管理"
}, },
name: this.$store.state.name, name: this.$store.state.name,
originList: [], originList: [],
list: [], list: [],
multipleSelection: [], multipleSelection: [],
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
total: 0, total: 0,
columnVisible: false, columnVisible: false,
curRow: {}, curRow: {},
sortObj: null, sortObj: null,
sorting: false, sorting: false,
parentId: '', parentId: '',
isAddType: false, isAddType: false,
defaultProps: { defaultProps: {
label: "name" label: "name"
}, },
level: 0 level: 0
}; };
},
mounted () {
this.getData();
},
beforeRouteLeave (to, from, next) {
if (JSON.stringify(this.originList) !== JSON.stringify(this.list)) {
this.$confirm("确定返回?排序尚未保存。", "提示", {
type: "warning",
closeOnClickModal: false
})
.then(() => {
next();
})
.catch(() => {
});
} else {
next();
}
},
methods: {
getData () {
this.$get(this.api.queryAllColumns, {
school: 0
}).then(({ columnTree }) => {
this.list = columnTree
this.originList = JSON.parse(JSON.stringify(this.list));
this.total = columnTree.length
}).catch(res => {
});
},
delData (row) {
this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", {
type: "warning"
})
.then(() => {
this.$del(`${this.api.deleteColumn}/${row.id}`).then(res => {
util.successMsg("删除成功");
this.getData();
}).catch(res => {
});
})
.catch(() => {
});
}, },
handleColumn (row, parentId, level) { mounted() {
this.columnVisible = true this.getData();
if (row) {
this.curRow = JSON.parse(JSON.stringify(row))
}
if (typeof parentId === 'number') {
this.curRow = {
parentId,
level,
name: '',
platformId: Setting.platformId
}
}
}, },
// list beforeRouteLeave(to, from, next) {
handleList (data, parent = {}) { if (JSON.stringify(this.originList) !== JSON.stringify(this.list)) {
data.map((n, i) => { this.$confirm("确定返回?排序尚未保存。", "提示", {
n.parentId = parent.id || 0 type: "warning"
n.level = this.level })
n.sort = i .then(() => {
if (n.children.length) { next();
this.level++ })
this.handleList(n.children, n) .catch(() => {
});
} else { } else {
this.level = 0 next();
} }
})
}, },
sortSubmit () { methods: {
this.level = 0 getData() {
let list = JSON.parse(JSON.stringify(this.list)) this.$get(this.api.queryAllColumns, {
this.handleList(list) school: 0
this.$post(this.api.columnReorder, { }).then(({ columnTree }) => {
columnTree: list this.list = columnTree
}).then(res => { this.originList = JSON.parse(JSON.stringify(this.list));
util.successMsg("保存成功"); this.total = columnTree.length
this.sorting = false; }).catch(res => {
this.getData(); });
}).catch(res => { },
}); delData(row) {
}, this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", {
columnSubmit () { type: "warning"
const row = this.curRow })
if (!row.name) return util.warningMsg("请填写栏目名称"); .then(() => {
if (this.curRow.id) { this.$del(`${this.api.deleteColumn}/${row.id}`).then(res => {
this.$put(this.api.editColumn, row).then(res => { util.successMsg("删除成功");
util.successMsg("修改成功"); this.getData();
this.columnVisible = false; }).catch(res => {
this.getData(); });
}).catch(res => { })
}); .catch(() => {
} else { });
this.$post(this.api.addColumn, row).then(res => { },
util.successMsg("添加成功"); handleColumn(row, parentId, level) {
this.columnVisible = false; this.columnVisible = true
this.getData(); if (row) {
}).catch(res => { this.curRow = JSON.parse(JSON.stringify(row))
}); }
} if (typeof parentId === 'number') {
}, this.curRow = {
cancelSort () { parentId,
this.sorting = false; level,
this.list = JSON.parse(JSON.stringify(this.originList)); name: '',
this.sortObj.destroy(); platformId: Setting.platformId
}, }
openSort () { }
this.sorting = true; },
}, // list
handleSelectionChange (val) { handleList(data, parent = {}) {
this.multipleSelection = val; data.map((n, i) => {
}, n.parentId = parent.id || 0
handleCurrentChange (val) { n.level = this.level
this.pageNo = val; n.sort = i
this.getData(); if (n.children.length) {
}, this.level++
closeColumn () { this.handleList(n.children, n)
this.curRow = {} } else {
}, this.level = 0
allowDrop (draggingNode, dropNode, type) { }
console.log("🚀 ~ file: index.vue ~ line 207 ~ allowDrop ~ draggingNode, dropNode, type", draggingNode, dropNode.level, type) })
if (dropNode.level == 4 && draggingNode.childNodes.length == 0) { },
return type !== "inner"; sortSubmit() {
} else if ((draggingNode.childNodes.length > 0 && dropNode.level == 4) || (draggingNode.childNodes.length > 0 && type == "inner")) { this.level = 0
return false; let list = JSON.parse(JSON.stringify(this.list))
} else { this.handleList(list)
return true; this.$post(this.api.columnReorder, {
} columnTree: list
}).then(res => {
util.successMsg("保存成功");
this.sorting = false;
this.getData();
}).catch(res => {
});
},
columnSubmit() {
const row = this.curRow
if (!row.name) return util.warningMsg("请填写栏目名称");
if (this.curRow.id) {
this.$put(this.api.editColumn, row).then(res => {
util.successMsg("修改成功");
this.columnVisible = false;
this.getData();
}).catch(res => {
});
} else {
this.$post(this.api.addColumn, row).then(res => {
util.successMsg("添加成功");
this.columnVisible = false;
this.getData();
}).catch(res => {
});
}
},
cancelSort() {
this.sorting = false;
this.list = JSON.parse(JSON.stringify(this.originList));
this.sortObj.destroy();
},
openSort() {
this.sorting = true;
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
handleCurrentChange(val) {
this.pageNo = val;
this.getData();
},
closeColumn() {
this.curRow = {}
},
allowDrop(draggingNode, dropNode, type) {
console.log("🚀 ~ file: index.vue ~ line 207 ~ allowDrop ~ draggingNode, dropNode, type", draggingNode, dropNode.level, type)
if (dropNode.level == 4 && draggingNode.childNodes.length == 0) {
return type !== "inner";
} else if ((draggingNode.childNodes.length > 0 && dropNode.level == 4) || (draggingNode.childNodes.length > 0 && type == "inner")) {
return false;
} else {
return true;
}
}
} }
}
}; };
</script> </script>
@ -279,7 +242,7 @@ export default {
&:first-child { &:first-child {
padding-left: 23.5vw; padding-left: 23.5vw;
@media (max-width: 1270px) { @media(max-width: 1270px) {
padding-left: 25.5%; padding-left: 25.5%;
} }
} }
@ -294,14 +257,14 @@ export default {
/deep/ .el-tree { /deep/ .el-tree {
.el-tree-node__expand-icon { .el-tree-node__expand-icon {
margin-left: 22.5vw; margin-left: 22.5vw;
@media (max-width: 1270px) { @media(max-width: 1270px) {
margin-left: 23.5%; margin-left: 23.5%;
} }
} }
.el-tree-node__content { .el-tree-node__content {
padding: 5px; padding: 5px;
border-bottom: 0.0625rem solid #ebeef5; border-bottom: 0.0625rem solid #EBEEF5;
} }
} }
@ -320,7 +283,7 @@ export default {
.action { .action {
width: 8.5vw; width: 8.5vw;
text-align: left; text-align: left;
@media (max-width: 1270px) { @media(max-width: 1270px) {
width: 16%; width: 16%;
} }
} }

@ -1,261 +1,212 @@
<template> <template>
<div class="page"> <div class="page">
<!-- <div class="tabs">--> <!-- <div class="tabs">-->
<!-- <a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == activeName}" @click="tabChange(index)">{{item}}</a>--> <!-- <a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == activeName}" @click="tabChange(index)">{{item}}</a>-->
<!-- </div>--> <!-- </div>-->
<div class="btn-wrap"> <div class="btn-wrap">
<el-button v-auth="'内容管理:保存排序'" <el-button v-auth="'内容管理:保存排序'" class="action-btn" type="primary" @click="sortSubmit">保存排序</el-button>
class="action-btn" <el-button v-auth="'内容管理:批量删除'" class="action-btn" type="primary" @click="delAllData">批量删除</el-button>
type="primary" <el-button v-auth="'内容管理:新增文章'" class="action-btn" type="primary" @click="addArticle">新增文章</el-button>
@click="sortSubmit">保存排序</el-button> </div>
<el-button v-auth="'内容管理:批量删除'" <div class="page-content" style="padding-top: 24px">
class="action-btn" <el-table ref="table" :data="list" class="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id">
type="primary" <el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
@click="delAllData">批量删除</el-button> <el-table-column type="index" width="60" label="序号" align="center">
<el-button v-auth="'内容管理:新增文章'" <template slot-scope="scope">
class="action-btn" {{ scope.$index + (pageNo - 1) * pageSize + 1 }}
type="primary" </template>
@click="addArticle">新增文章</el-button> </el-table-column>
<el-table-column prop="title" label="标题" show-overflow-tooltip align="center">
</el-table-column>
<el-table-column prop="title" label="栏目" show-overflow-tooltip align="center">
{{ columnName }}
</el-table-column>
<el-table-column prop="name" label="排序值" width="80" align="center">
<template slot-scope="scope">
<el-input class="sort-input" width="120" min="1" v-model.number="scope.row.sort" type="number"></el-input>
<span>{{ scope.row.sort }}</span>
</template>
</el-table-column>
<el-table-column prop="date" label="添加日期" align="center">
<template slot-scope="scope">
{{ transferDate(scope.row.date) }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="170">
<template slot-scope="scope">
<el-button v-auth="'内容管理:编辑'" type="text" @click="editArticle(scope)">编辑</el-button>
<el-divider v-auth="'内容管理:编辑'" direction="vertical"></el-divider>
<el-button v-auth="'内容管理:删除'" type="text" @click="delData(scope.row)">删除</el-button>
</template>
</el-table-column>
<el-table-column prop="name" label="文章发布状态" width="120" align="center">
<template slot-scope="scope">
<el-switch
v-auth="'内容管理:禁用'"
class="off"
v-model="scope.row.status"
:active-value="0"
:inactive-value="1"
style="margin: 0 5px"
:active-text="scope.row.status ? '关' : '开'"
@change="switchOff($event,scope.row,scope.$index)"
></el-switch>
<span>{{ scope.row.status ? "禁用" : "启用" }}</span>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total, prev, pager, next" :total="totals" @current-change="handleCurrentChange" :current-page="pageNo">
</el-pagination>
</div>
</div>
</div> </div>
<div class="page-content"
style="padding-top: 24px">
<el-table ref="table"
:data="list"
class="table"
stripe
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="60"
label="序号"
align="center">
<template slot-scope="scope">
{{ scope.$index + (pageNo - 1) * pageSize + 1 }}
</template>
</el-table-column>
<el-table-column prop="title"
label="标题"
show-overflow-tooltip
align="center">
</el-table-column>
<el-table-column prop="title"
label="栏目"
show-overflow-tooltip
align="center">
{{ columnName }}
</el-table-column>
<el-table-column prop="name"
label="排序值"
width="80"
align="center">
<template slot-scope="scope">
<el-input class="sort-input"
width="120"
min="1"
v-model.number="scope.row.sort"
type="number"></el-input>
<span>{{ scope.row.sort }}</span>
</template>
</el-table-column>
<el-table-column prop="date"
label="添加日期"
align="center">
<template slot-scope="scope">
{{ transferDate(scope.row.date) }}
</template>
</el-table-column>
<el-table-column label="操作"
align="center"
width="170">
<template slot-scope="scope">
<el-button v-auth="'内容管理:编辑'"
type="text"
@click="editArticle(scope)">编辑</el-button>
<el-divider v-auth="'内容管理:编辑'"
direction="vertical"></el-divider>
<el-button v-auth="'内容管理:删除'"
type="text"
@click="delData(scope.row)">删除</el-button>
</template>
</el-table-column>
<el-table-column prop="name"
label="文章发布状态"
width="120"
align="center">
<template slot-scope="scope">
<el-switch v-auth="'内容管理:禁用'"
class="off"
v-model="scope.row.status"
:active-value="0"
:inactive-value="1"
style="margin: 0 5px"
:active-text="scope.row.status ? '关' : '开'"
@change="switchOff($event,scope.row,scope.$index)"></el-switch>
<span>{{ scope.row.status ? "禁用" : "启用" }}</span>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background
layout="total, prev, pager, next"
:total="totals"
@current-change="handleCurrentChange"
:current-page="pageNo">
</el-pagination>
</div>
</div>
</div>
</template> </template>
<script> <script>
import util from "@/libs/util"; import util from "@/libs/util";
export default { export default {
data () { data() {
return { return {
activeName: "first", activeName: "first",
tabs: { tabs: {
first: "栏目内容管理" first: "栏目内容管理"
}, },
columns: this.$parent.menuList, columns: this.$parent.menuList,
columnName: '', columnName: '',
list: [], list: [],
multipleSelection: [], multipleSelection: [],
pageNo: +this.$route.query.page || 1, pageNo: +this.$route.query.page || 1,
pageSize: 10, pageSize: 10,
totals: 0, totals: 0,
originList: [] originList: []
}; };
},
props: {
columnId: ""
},
watch: {
columnId () {
this.getColumnName(this.$parent.menuList)
this.getData();
}
},
mounted () {
this.getColumnName(this.$parent.menuList)
this.getData();
},
methods: {
getData (id) {
let data = {
columnId: this.columnId
};
this.$get(`${this.api.queryArticleByCondition}/${this.pageNo}/${this.pageSize}`, data).then(({ articleList, total }) => {
this.list = articleList;
this.totals = total;
if (JSON.stringify(this.originList) !== '{}') this.originList = JSON.parse(JSON.stringify(articleList))
if (!this.list.length && this.totals) {
this.pageNo--;
this.getData();
}
}).catch(res => {
});
},
handleSelectionChange (val) {
this.multipleSelection = val;
}, },
handleCurrentChange (val) { props: {
this.pageNo = val; columnId: ""
this.$router.push(`/information?page=${val}`)
this.getData();
},
//
getColumnName (data) {
data.map(e => {
if (e.id == this.columnId) {
this.columnName = e.name
} else {
this.getColumnName(e.children)
}
})
}, },
addArticle () { watch: {
this.$router.push(`/addArticle?columnId=${this.columnId}&sort=${this.list.length + 1}`); columnId() {
}, this.getColumnName(this.$parent.menuList)
editArticle (scope) {
this.$router.push(`/addArticle?columnId=${this.columnId}&id=${scope.row.id}&sort=${scope.$index + 1}`);
},
delData (row) {
this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", {
type: "warning"
})
.then(() => {
this.$del(`${this.api.deleteArticles}?articleIds=${row.id}`).then(res => {
util.successMsg("删除成功");
this.getData(); this.getData();
}).catch(res => { }
});
})
.catch(() => {
});
}, },
transferDate (date) { mounted() {
return date.replace(" 00:00:00", ""); this.getColumnName(this.$parent.menuList)
this.getData();
}, },
delAllData () { methods: {
if (this.multipleSelection.length != "") { getData(id) {
let newArr = this.multipleSelection; let data = {
let delList = newArr.map(item => { columnId: this.columnId
return item.id; };
}); this.$get(`${this.api.queryArticleByCondition}/${this.pageNo}/${this.pageSize}`, data).then(({ articleList, total }) => {
this.list = articleList;
let title = newArr[0].title; this.totals = total;
if (title.length > 14) { if (JSON.stringify(this.originList) !== '{}') this.originList = JSON.parse(JSON.stringify(articleList))
title = title.substr(0, 14) + "……"; if (!this.list.length && this.totals) {
} this.pageNo--;
this.$confirm(`此批量删除操作不可逆,是否确认删除${title}${newArr.length}个选中项?`, "提示", { this.getData();
type: "warning" }
})
.then(() => {
this.$del(`${this.api.deleteArticles}?articleIds=${delList.join(",")}`).then(res => {
this.$refs.table.clearSelection();
util.successMsg("删除成功");
this.getData();
}).catch(res => { }).catch(res => {
}); });
if (this.multipleSelection.length === this.list.length && this.pageNo > 1) { },
this.handleCurrentChange(this.pageNo - 1) handleSelectionChange(val) {
this.multipleSelection = val;
},
handleCurrentChange(val) {
this.pageNo = val;
this.$router.push(`list?page=${val}`)
this.getData();
},
//
getColumnName(data) {
data.map(e => {
if (e.id == this.columnId) {
this.columnName = e.name
} else {
this.getColumnName(e.children)
} }
}) })
.catch(() => { },
}); addArticle() {
} else { this.$router.push(`/addArticle?columnId=${this.columnId}&sort=${this.list.length + 1}`);
util.errorMsg("请先选择数据 !"); },
} editArticle(scope) {
}, this.$router.push(`/addArticle?columnId=${this.columnId}&id=${scope.row.id}&sort=${scope.$index + 1}`);
switchOff (val, row, index) { },
this.$put(`${this.api.enableArticle}/${row.id}/${val}`) delData(row) {
.then(res => { this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", {
val == 1 ? util.errorMsg("该文章已隐藏,对学生端用户不可见") : util.successMsg("该文章已发布,对学生端用户可见"); type: "warning"
}) })
.catch(err => { .then(() => {
}); this.$del(`${this.api.deleteArticles}?articleIds=${row.id}`).then(res => {
}, util.successMsg("删除成功");
sortSubmit () { this.getData();
if (this.list.length) { }).catch(res => {
if (this.list.find(n => n.sort < 1)) return util.errorMsg("排序值最小为1"); });
let data = { articleList: this.list }; })
this.$post(this.api.articleSort, data).then(res => { .catch(() => {
util.successMsg("保存成功"); });
this.getData() },
}) transferDate(date) {
.catch(err => { return date.replace(" 00:00:00", "");
}); },
} else { delAllData() {
util.errorMsg("数据为空"); if (this.multipleSelection.length != "") {
} let newArr = this.multipleSelection;
let delList = newArr.map(item => {
return item.id;
});
let title = newArr[0].title;
if (title.length > 14) {
title = title.substr(0, 14) + "……";
}
this.$confirm(`此批量删除操作不可逆,是否确认删除${title}${newArr.length}个选中项?`, "提示", {
type: "warning"
})
.then(() => {
this.$del(`${this.api.deleteArticles}?articleIds=${delList.join(",")}`).then(res => {
this.$refs.table.clearSelection();
util.successMsg("删除成功");
this.getData();
}).catch(res => {
});
if(this.multipleSelection.length === this.list.length && this.pageNo>1) {
this.handleCurrentChange(this.pageNo - 1)
}
})
.catch(() => {
});
} else {
util.errorMsg("请先选择数据 !");
}
},
switchOff(val, row, index) {
this.$put(`${this.api.enableArticle}/${row.id}/${val}`)
.then(res => {
val == 1 ? util.errorMsg("该文章已隐藏,对学生端用户不可见") : util.successMsg("该文章已发布,对学生端用户可见");
})
.catch(err => {
});
},
sortSubmit() {
if (this.list.length) {
if (this.list.find(n => n.sort < 1)) return util.errorMsg("排序值最小为1");
let data = { articleList: this.list };
this.$post(this.api.articleSort, data).then(res => {
util.successMsg("保存成功");
this.getData()
})
.catch(err => {
});
} else {
util.errorMsg("数据为空");
}
}
} }
}
}; };
</script> </script>

@ -2,19 +2,10 @@
<!-- 内容管理 --> <!-- 内容管理 -->
<div class="flex"> <div class="flex">
<div class="menu-con"> <div class="menu-con">
<el-tree ref="column" <el-tree ref="column" :data="menuList" :props="{ label: 'name' }" highlight-current :expand-on-click-node="false" default-expand-all node-key="id" @node-click="handleSelect"></el-tree>
:data="menuList"
:props="{ label: 'name' }"
highlight-current
:expand-on-click-node="false"
default-expand-all
node-key="id"
@node-click="handleSelect"></el-tree>
</div> </div>
<div class="right"> <div class="right">
<ContentList ref="content" <ContentList ref="content" v-show="menuList.length" :columnId="columnId" />
v-show="menuList.length"
:columnId="columnId" />
</div> </div>
</div> </div>
</template> </template>
@ -24,93 +15,92 @@ import menuTree from '@/components/menuTree'
import ContentList from "./contentList"; import ContentList from "./contentList";
import Setting from '@/setting' import Setting from '@/setting'
export default { export default {
name: "contentManage", name: "contentManage",
components: { components: {
menuTree, menuTree,
ContentList ContentList
},
data () {
return {
menuList: [],
activeName: this.$store.state.columnId,
columnId: "",
ids: [],
curId: ''
};
},
mounted () {
this.getMenuData();
},
methods: {
getMenuData () {
this.$get(this.api.queryAllColumns, {
school: 0
}).then(res => {
this.menuList = res.columnTree
const storeId = this.$store.state.columnId
if (this.menuList.length) {
this.getId(this.menuList)
this.columnId = this.menuList[0].id
if (!storeId) {
this.$store.commit('setColumnId', this.columnId)
} else {
this.columnId = storeId
}
}
this.$nextTick(() => {
this.$refs.column.setCurrentKey(this.columnId)
})
}).catch(err => {
});
}, },
// id便 data() {
getId (data) { return {
data.map(e => { menuList: [],
this.ids.push(e.id) activeName: this.$store.state.columnId,
e.children.length && this.getId(e.children) columnId: "",
}) ids: [],
curId: ''
};
}, },
setColumnId (id) { mounted() {
this.columnId = id this.getMenuData();
this.$store.commit('setColumnId', id)
}, },
handleSelect (key) { methods: {
const { content } = this.$refs getMenuData() {
const { list, originList } = content this.$get(this.api.queryAllColumns, {
// school: 0
if (JSON.stringify(list) !== JSON.stringify(originList)) { }).then(res => {
this.$confirm(`您已更改了文章排序,是否保存更改?`, '提示', { this.menuList = res.columnTree
type: 'warning', const storeId = this.$store.state.columnId
closeOnClickModal: false if (this.menuList.length) {
}).then(() => { this.getId(this.menuList)
content.sortSubmit() this.columnId = this.menuList[0].id
this.setColumnId(key.id) if (!storeId) {
}).catch(() => { this.$store.commit('setColumnId', this.columnId)
this.setColumnId(key.id) } else {
}) this.columnId = storeId
} else { }
this.setColumnId(key.id) }
} this.$nextTick(() => {
this.$refs.column.setCurrentKey(this.columnId)
})
}).catch(err => {
});
},
// id便
getId(data) {
data.map(e => {
this.ids.push(e.id)
e.children.length && this.getId(e.children)
})
},
setColumnId(id) {
this.columnId = id
this.$store.commit('setColumnId', id)
},
handleSelect(key) {
const { content } = this.$refs
const { list, originList } = content
//
if (JSON.stringify(list) !== JSON.stringify(originList)) {
this.$confirm(`您已更改了文章排序,是否保存更改?`, '提示', {
type: 'warning'
}).then(() => {
content.sortSubmit()
this.setColumnId(key.id)
}).catch(() => {
this.setColumnId(key.id)
})
} else {
this.setColumnId(key.id)
}
}
} }
}
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.menu-con { .menu-con {
width: 210px; width: 210px;
height: calc(100vh - 250px); height: calc(100vh - 250px);
border-right: solid 1px #e6e6e6; border-right: solid 1px #e6e6e6;
background-color: #f2f6fc; background-color: #F2F6FC;
/deep/.el-tree-node__content { /deep/.el-tree-node__content {
height: 50px; height: 50px;
} }
} }
.right { .right {
flex: 1; flex: 1;
} }
/deep/.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content { /deep/.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
color: #fff; color: #fff;
background-color: #9278ff; background-color: #9278ff;
} }
</style> </style>

@ -1,98 +1,90 @@
<template> <template>
<!-- 资讯管理 --> <!-- 资讯管理 -->
<div class="page"> <div class="page">
<ul class="column-tab"> <ul class="column-tab">
<li :class="{active: tabsName == 1}" <li :class="{active: tabsName == 1}" @click="handleClick(1)"><i class="el-icon-collection-tag"></i> 栏目管理</li>
@click="handleClick(1)"><i class="el-icon-collection-tag"></i> 栏目管理</li> <li :class="{active: tabsName == 2}" @click="handleClick(2)"><i class="el-icon-document"></i> 内容管理</li>
<li :class="{active: tabsName == 2}" </ul>
@click="handleClick(2)"><i class="el-icon-document"></i> 内容管理</li> <columnManage class="flex-1" ref="content1" v-if="tabsName == 1" />
</ul> <ContentManage class="flex-1" ref="content2" v-if="tabsName == 2" />
<columnManage class="flex-1" </div>
ref="content1"
v-if="tabsName == 1" />
<ContentManage class="flex-1"
ref="content2"
v-if="tabsName == 2" />
</div>
</template> </template>
<script> <script>
import ColumnManage from "../columnManage"; import ColumnManage from "../columnManage";
import ContentManage from "../contentManage"; import ContentManage from "../contentManage";
export default { export default {
components: { components: {
ColumnManage, ColumnManage,
ContentManage ContentManage
},
data () {
return {
tabsName: this.$store.state.tabId
};
},
//
beforeRouteLeave (to, from, next) {
this.routeLeave(next, true)
},
methods: {
switchTab (id) {
this.tabsName = id
this.$store.commit('setInfoTab', id)
this.$store.commit('setColumnId', '')
}, },
// data() {
routeLeave (fn, param) { return {
const tab = this.tabsName tabsName: this.$store.state.tabId
let content = this.$refs['content' + tab] };
if (tab == 2) content = content.$refs.content
const { list, originList } = content
//
if (JSON.stringify(list) !== JSON.stringify(originList)) {
this.$confirm(`您已更改了${tab == 1 ? '栏目' : '文章'}排序,是否保存更改?`, '提示', {
type: 'warning',
closeOnClickModal: false
}).then(() => {
content.sortSubmit()
fn(param)
}).catch(() => {
fn(param)
})
} else {
fn(param)
}
}, },
// tab //
handleClick (id) { beforeRouteLeave(to, from, next) {
this.routeLeave(this.switchTab, id) this.routeLeave(next, true)
} },
}, methods: {
mounted () { switchTab(id) {
this.tabsName = id
this.$store.commit('setInfoTab', id)
this.$store.commit('setColumnId', '')
},
//
routeLeave(fn, param) {
const tab = this.tabsName
let content = this.$refs['content' + tab]
if (tab == 2) content = content.$refs.content
const { list, originList } = content
//
if (JSON.stringify(list) !== JSON.stringify(originList)) {
this.$confirm(`您已更改了${tab == 1 ? '栏目' : '文章'}排序,是否保存更改?`, '提示', {
type: 'warning'
}).then(() => {
content.sortSubmit()
fn(param)
}).catch(() => {
fn(param)
})
} else {
fn(param)
}
},
// tab
handleClick(id) {
this.routeLeave(this.switchTab, id)
}
},
mounted() {
} }
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.flex-1 { .flex-1 {
flex: 1; flex: 1;
} }
.page { .page {
display: flex; display: flex;
} }
.column-tab { .column-tab {
width: 120px; width: 120px;
border-right: solid 1px #e6e6e6; border-right: solid 1px #e6e6e6;
li { li {
display: flex; display: flex;
align-items: center; align-items: center;
height: 60px; height: 60px;
cursor: pointer; cursor: pointer;
i { i {
margin-right: 5px; margin-right: 5px;
} }
&:hover, &:hover, &.active {
&.active { color: #9278FF;
color: #9278ff;
}
} }
}
} }
</style> </style>

@ -1,38 +1,56 @@
<template> <template>
<div> <div>
<el-card v-if="!id" shadow="hover" class="m-b-20"> <el-card v-if="!id"
shadow="hover"
class="m-b-20">
<div class="flex-between"> <div class="flex-between">
<el-page-header @back="back" :content="'创建赛事'"></el-page-header> <el-page-header @back="back"
:content="'创建赛事'"></el-page-header>
</div> </div>
</el-card> </el-card>
<div v-if="step === 1 || (id && !editing)" :class="['type-wrap', { pd: !id }]"> <div v-if="step === 1 || (id && !editing)"
:class="['type-wrap', {pd: !id}]">
<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-for="(item, i) in releaseTypes" :key="i" v-model="releaseType" :label="item.id">{{ item.name <el-radio v-model="releaseType"
}}</el-radio> :label="0">仅发布信息</el-radio>
<el-radio v-model="releaseType"
:label="1">设置完整比赛</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"
v-auth="'/match:管理:大赛详情:编辑'">编辑</el-button> class="edit"
type="primary"
@click="editing = 1"
v-auth="'/match:管理:大赛详情:编辑'">编辑</el-button>
</div> </div>
<el-card v-if="step !== 4" shadow="hover" class="m-b-20" style="position: relative;margin-top: 20px"> <el-card v-if="step !== 4"
<ul :class="['steps', { pointer: !editing && id && publishStatus }]"> shadow="hover"
<li :class="{ active: step === 1, done: step > 1 }" @click="toStep(1)"> class="m-b-20"
style="position: relative;margin-top: 20px">
<ul :class="['steps', {pointer: !editing && id && publishStatus}]">
<li :class="{active: step === 1,done: step > 1}"
@click="toStep(1)">
<span class="circle">1</span> <span class="circle">1</span>
<p class="text">大赛信息填写</p> <p class="text">大赛信息填写</p>
</li> </li>
<template v-if="releaseType"> <template v-if="releaseType">
<li :class="{ active: step === 2, done: step > 2 }" @click="toStep(2)"> <li :class="{active: step === 2,done: step > 2}"
@click="toStep(2)">
<span class="circle circle2">2</span> <span class="circle circle2">2</span>
<p class="text">赛程与规则设置</p> <p class="text">赛程与规则设置</p>
</li> </li>
<li :class="{ active: step === 3, done: step > 3 }" @click="toStep(3)"> <li :class="{active: step === 3,done: step > 3}"
@click="toStep(3)">
<span class="circle circle3">3</span> <span class="circle circle3">3</span>
<p class="text">比赛内容设置</p> <p class="text">比赛内容设置</p>
</li> </li>
</template> </template>
<li :class="{ done: step > 3 }"> <li :class="{done: step > 3}">
<span class="circle circle4">{{ releaseType ? 4 : 2 }}</span> <span class="circle circle4">{{ releaseType ? 4 : 2 }}</span>
<p class="text">发布{{ !editing && id ? '成功' : '' }}</p> <p class="text">发布{{ !editing && id ? '成功' : '' }}</p>
</li> </li>
@ -40,21 +58,43 @@
</el-card> </el-card>
<div class="page"> <div class="page">
<div class="page-content"> <div class="page-content">
<step1 v-show="step === 1" ref="step1" :editing.sync="editing" @next="next" /> <step1 v-show="step === 1"
<step2 v-if="step === 2" ref="step2" :editing.sync="editing" :setupId.sync="setupId" @next="next" /> ref="step1"
<step3 v-if="step === 3" ref="step3" :editing.sync="editing" :setupId.sync="setupId" :editing.sync="editing"
:competitionId.sync="competitionId" @next="next" /> @next="next" />
<step4 v-if="step === 4" ref="step4" /> <step2 v-if="step === 2"
ref="step2"
:editing.sync="editing"
:setupId.sync="setupId"
@next="next" />
<step3 v-if="step === 3"
ref="step3"
:editing.sync="editing"
:setupId.sync="setupId"
:competitionId.sync="competitionId"
@next="next" />
<step4 v-if="step === 4"
ref="step4" />
<div v-if="step !== 4 && showBtns" class="btns"> <div v-if="step !== 4 && showBtns"
class="btns">
<!-- 处于编辑状态(列表点编辑按钮进来默认是查看状态不可编辑点了编辑按钮才可编辑)或者新增才显示这几个按钮 --> <!-- 处于编辑状态(列表点编辑按钮进来默认是查看状态不可编辑点了编辑按钮才可编辑)或者新增才显示这几个按钮 -->
<template v-if="editing || !id"> <template v-if="editing || !id">
<el-button v-if="!publishStatus" @click="save(0)">保存{{ releaseType ? '草稿' : '' }}</el-button> <el-button v-if="!publishStatus"
<el-button v-if="step === 2 || step === 3" type="primary" @click="prev">上一步</el-button> @click="save(0)">保存{{ releaseType ? '草稿' : '' }}</el-button>
<el-button v-if="!releaseType || (releaseType && step === 3)" type="primary" @click="save(1)">发布</el-button> <el-button v-if="step === 2 || step === 3"
<el-button v-else type="primary" @click="save(0, 2)">保存并下一步</el-button> type="primary"
@click="prev">上一步</el-button>
<el-button v-if="!releaseType || (releaseType && step === 3)"
type="primary"
@click="save(1)">发布</el-button>
<el-button v-else
type="primary"
@click="save(id ? 1 : 0, 2)">保存并下一步</el-button>
</template> </template>
<el-button type="danger" @click="preview" v-auth="'/match:管理:大赛详情:预览'">预览</el-button> <el-button type="danger"
@click="preview"
v-auth="'/match:管理:大赛详情:预览'">预览</el-button>
<el-button @click="cancel">{{ editing ? '取消' : '返回' }}</el-button> <el-button @click="cancel">{{ editing ? '取消' : '返回' }}</el-button>
</div> </div>
</div> </div>
@ -83,20 +123,6 @@ 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
@ -139,8 +165,7 @@ export default {
const { updateTime } = this.$refs['step' + this.step] const { updateTime } = this.$refs['step' + this.step]
if (updateTime) { if (updateTime) {
this.$confirm(`编辑的内容未保存,是否保存?`, '提示', { this.$confirm(`编辑的内容未保存,是否保存?`, '提示', {
type: 'warning', type: 'warning'
closeOnClickModal: false
}).then(() => { }).then(() => {
this.save(0, 1) this.save(0, 1)
}).catch(() => { }).catch(() => {
@ -153,15 +178,7 @@ 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) { this.$router.push(`/match?page=${this.$store.state.matchPage}`)
// &&
this.editing = 0
this.step = 1
this.$parent.initTabs && this.$parent.initTabs()
} else {
//
this.$router.push(`/match`)
}
} else if (next === 2) { } else if (next === 2) {
if (setupId) this.setupId = setupId if (setupId) this.setupId = setupId
if (competitionId) { if (competitionId) {
@ -172,12 +189,6 @@ export default {
this.step++ this.step++
} else if (next === 1) { } else if (next === 1) {
this.step-- this.step--
} else {
if (typeof setupId === 'function') {
setupId()
} else if (typeof type === 'function') {
type()
}
} }
}, },
// //
@ -197,8 +208,7 @@ export default {
const { updateTime } = this.$refs['step' + this.step] const { updateTime } = this.$refs['step' + this.step]
if (this.step < 4 && updateTime) { if (this.step < 4 && updateTime) {
this.$confirm(`编辑的内容未保存,是否保存?`, '提示', { this.$confirm(`编辑的内容未保存,是否保存?`, '提示', {
type: 'warning', type: 'warning'
closeOnClickModal: false
}).then(() => { }).then(() => {
this.save(0, 3) this.save(0, 3)
}).catch(() => { }).catch(() => {
@ -208,7 +218,7 @@ export default {
this.editing = false this.editing = false
} }
} else { } else {
this.backPage() this.$router.push(`/match?page=${this.$store.state.matchPage}&platformSource=${this.$store.state.platformSource}`)
} }
}, },
back () { back () {
@ -216,8 +226,7 @@ export default {
const { updateTime } = this.$refs['step' + this.step] const { updateTime } = this.$refs['step' + this.step]
if (this.step < 4 && updateTime) { if (this.step < 4 && updateTime) {
this.$confirm(`编辑的内容未保存,是否保存?`, '提示', { this.$confirm(`编辑的内容未保存,是否保存?`, '提示', {
type: 'warning', type: 'warning'
closeOnClickModal: false
}).then(() => { }).then(() => {
this.save(0) this.save(0)
}).catch(() => { }).catch(() => {
@ -228,7 +237,7 @@ export default {
} }
}, },
backPage () { backPage () {
this.$router.push(this.$store.state.referrer || '/match') this.$router.push(`/match?page=${this.$store.state.matchPage}&platformSource=${this.$store.state.platformSource}`)
} }
} }
}; };
@ -236,104 +245,87 @@ export default {
<style scoped lang="scss"> <style scoped lang="scss">
.type-wrap { .type-wrap {
position: relative; position: relative;
padding: 10px; margin-top: 20px;
margin-top: 20px; background: #fff;
background: #fff; &.pd {
padding: 15px;
&.pd { }
padding: 15px;
}
} }
.edit { .edit {
position: absolute; position: absolute;
top: 30px; top: 30px;
right: 30px; right: 30px;
} }
.el-steps { .el-steps {
justify-content: center; justify-content: center;
} }
.steps { .steps {
display: flex; display: flex;
justify-content: center;
&.pointer {
li {
cursor: pointer;
}
}
li {
position: relative;
margin-right: 100px;
text-align: center;
}
.circle {
display: inline-flex;
justify-content: center; justify-content: center;
align-items: center; &.pointer {
width: 35px; li {
margin: 0 auto 10px; cursor: pointer;
line-height: 35px; }
font-size: 18px; }
color: #333; li {
background: #f9f9f9; position: relative;
border: 5px solid #e1e1e1; margin-right: 100px;
border-radius: 50%; text-align: center;
&:after {
content: '';
position: absolute;
left: 64px;
width: 146px;
height: 3px;
background: #e1e1e1;
} }
}
.active {
.circle { .circle {
color: #fff; display: inline-flex;
border-color: #459ffb; justify-content: center;
background: #007eff; align-items: center;
width: 35px;
margin: 0 auto 10px;
line-height: 35px;
font-size: 18px;
color: #333;
background: #f9f9f9;
border: 5px solid #e1e1e1;
border-radius: 50%;
&:after {
content: '';
position: absolute;
left: 64px;
width: 146px;
height: 3px;
background: #e1e1e1;
}
} }
.active {
.text { .circle {
color: #007eff; color: #fff;
border-color: #459ffb;
background: #007eff;
}
.text {
color: #007eff;
}
} }
} .done {
.circle {
.done { color: #fff;
.circle { background: #9c86ff;
color: #fff; border-color: #bbacff;
background: #9c86ff; &:after {
border-color: #bbacff; background: #bbacff;
}
&:after { }
background: #bbacff; .text {
} color: #9178ff;
}
} }
.circle2:after {
.text { left: 71px;
color: #9178ff; width: 147px;
}
.circle4:after {
display: none;
} }
}
.circle2:after {
left: 71px;
width: 147px;
}
.circle4:after {
display: none;
}
} }
.btns { .btns {
text-align: center; text-align: center;
} }
</style> </style>

@ -1,192 +1,146 @@
<template> <template>
<div> <div>
<el-card shadow="hover" class="m-b-20"> <el-card shadow="hover"
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" class="m-b-20"> <el-card shadow="hover"
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" type="datetimerange" range-separator="~" start-placeholder="开始日期" <el-date-picker v-model="form.time"
end-placeholder="结束日期" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange"
@change="timeChange"> range-separator="~"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
@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 + '间)'" type="error" :closable="false" :title="'(请设置在 ' + step1.playStartTime + ' ~ ' + step1.playEndTime + '间)'"
effect="dark"> type="error"
:closable="false"
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"> <div>
<!-- 理论系统选择试卷库非理论则选择系统 --> <p class="m-b-20">课程</p>
<el-card shadow="hover" class="mgr20 m-b-20"> <div class="inline-input">
<div> <el-cascader ref="cur"
<p class="m-b-20">试卷库</p> v-model="mallIds"
<div class="inline-input"> :options="curs"
<el-select v-model="libraryId" placeholder="请选择试卷库" @change="getProject"> :props="{ checkStrictly: true, value: 'id' }"
<el-option v-for="(item, i) in paperLibraries" :key="i" :label="item.libraryName" :value="item.libraryId"> popper-class="course-cas"
</el-option> @expand-change="curChange"
</el-select> @change="curChange"></el-cascader>
</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>
<p class="m-b-20">课程</p>
<div class="inline-input">
<el-cascader ref="cur" v-model="mallIds" :options="curs" :props="{ checkStrictly: true, value: 'id' }"
popper-class="course-cas" @expand-change="curChange" @change="curChange"></el-cascader>
</div>
</div> </div>
</el-card> </div>
</el-card>
<el-card shadow="hover" class="m-b-20"> <el-card shadow="hover"
<div class="flex-between m-b-20"> class="m-b-20">
<span>实训项目</span> <div class="flex-between m-b-20">
<div style="display: inline-flex;"> <span>实训项目</span>
<div> <div style="display: inline-flex;">
<el-input placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model.trim="keyword" clearable></el-input> <div>
</div> <el-input placeholder="请输入项目名称"
<el-button style="margin-left: 5px" type="primary" round @click="toProject">自定义实验项目</el-button> prefix-icon="el-icon-search"
v-model.trim="keyword"
clearable></el-input>
</div> </div>
<el-button style="margin-left: 5px"
type="primary"
round
@click="toProject">自定义实验项目</el-button>
</div> </div>
<!-- 实训项目表格 --> </div>
<el-table :data="projects" class="table" stripe header-align="center"> <!-- 实训项目表格 -->
<el-table-column width="60" label="选择" align="center"> <el-table :data="projects"
<template slot-scope="scope"> class="table"
<el-radio v-model="form.projectId" :label="scope.row.projectId">&nbsp;</el-radio> stripe
</template> header-align="center">
</el-table-column> <el-table-column width="60"
<el-table-column prop="projectName" label="项目名称" align="center"></el-table-column> label="选择"
<el-table-column prop="auth" label="项目权限" align="center"> align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ permissionsKeys[scope.row.permissions] }} <el-radio v-model="form.projectId"
</template> :label="scope.row.projectId">&nbsp;</el-radio>
</el-table-column> </template>
<el-table-column prop="founder" label="创建人" align="center"> </el-table-column>
<template slot-scope="scope"> <el-table-column prop="projectName"
{{ scope.row.founder ? '老师创建' : '系统内置' }} label="项目名称"
</template> align="center"></el-table-column>
</el-table-column> <el-table-column prop="auth"
<el-table-column prop="createTime" label="创建时间" align="center"></el-table-column> label="项目权限"
<!-- <el-table-column label="操作" align="center"> align="center">
<template slot-scope="scope">
{{ permissionsKeys[scope.row.permissions] }}
</template>
</el-table-column>
<el-table-column prop="founder"
label="创建人"
align="center">
<template slot-scope="scope">
{{ scope.row.founder ? '老师创建' : '系统内置' }}
</template>
</el-table-column>
<el-table-column prop="createTime"
label="创建时间"
align="center"></el-table-column>
<!-- <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>
</template> </template>
</el-table-column> --> </el-table-column> -->
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background :page-size="pageSize" @current-change="handleCurrentChange" <el-pagination background
layout="total,prev, pager, next" :total="total"></el-pagination> :page-size="pageSize"
</div> @current-change="handleCurrentChange"
</el-card> layout="total,prev, pager, next"
</template> :total="total"></el-pagination>
</div>
</el-card>
<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" @click="save">保存</el-button> <el-button type="primary"
@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: {
@ -203,7 +157,7 @@ export default {
} }
}, },
mounted () { mounted () {
this.isTheory ? this.getLibrary() : this.getCourse() this.getCourse()
}, },
methods: { methods: {
// //
@ -232,7 +186,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 && e.systemId.split(',').includes(n.systemId)) // e.children = serviceList.records.filter(n => e.systemId.split(',').includes(n.systemId)) //
}) })
this.curs = records this.curs = records
@ -262,65 +216,31 @@ 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 { }
},
// / //
async getProject () { getProject () {
try { this.$post(this.api.getProjectAssessmentByCompetition, {
// pageNum: this.page,
if (this.isTheory) { pageSize: this.pageSize,
const res = await this.$post(this.api.examPaperList, { cid: this.form.cid,
pageNum: this.page, projectName: this.keyword,
pageSize: this.pageSize, systemId: this.sysId,
type: 1, permissions: 2
keyWord: this.keyword, }).then(({ data }) => {
libraryId: this.libraryId, this.projects = data.records
isDisable: 0, this.total = data.total
status: 1
})
this.projects = res.pageList.records
this.total = res.pageList.total
} else {
//
const { data } = await this.$post(this.api.getProjectAssessmentByCompetition, {
pageNum: this.page,
pageSize: this.pageSize,
cid: this.form.cid,
projectName: this.keyword,
systemId: this.sysId,
permissions: 2,
})
this.projects = data.records
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 () {
@ -357,65 +277,29 @@ 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 (!form.cid) return util.warningMsg('请选择课程')
if (this.isTheory) { if (!form.projectId) return util.warningMsg('请选择项目')
if (!this.libraryId) return util.warningMsg('请选择试卷库') const { systemId, systemName, projectName } = this.projects.find(e => e.projectId == form.projectId)
if (!form.paperId) return util.warningMsg('请选择试卷') if (systemId) form.systemId = systemId
if (projectName) form.projectName = projectName
form.libraryId = this.libraryId if (systemName) form.systemName = systemName
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.projectId) return util.warningMsg('请选择项目')
const { systemId, systemName, projectName } = this.projects.find(e => e.projectId == form.projectId)
if (systemId) form.systemId = systemId
if (projectName) form.projectName = projectName
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('hideSet') this.$emit('hideSet')
} }
} }
}; };
</script> </script>
<style scoped lang="scss"></style> <style scoped lang="scss">
</style>

File diff suppressed because it is too large Load Diff

@ -1,528 +1,476 @@
<template> <template>
<div> <div>
<div class="page"> <div class="page">
<div class="page-content"> <div class="page-content">
<div class="p-title">赛程与规则设置</div> <div class="p-title">赛程与规则设置</div>
<el-form :model="form" :rules="validRules" label-width="170px" label-suffix=":" size="small" <el-form :model="form" :rules="validRules" label-width="170px" label-suffix=":" size="small" :disabled="!editing && id">
:disabled="!!(!editing && id)"> <el-form-item label="竞赛类型">
<el-form-item label="竞赛类型"> {{ step1.completeCompetitionSetup.competitionType ? '团队赛(' + step1.completeCompetitionSetup.minTeamSize + '-' + step1.completeCompetitionSetup.maxTeamSize + '人/队)' : '个人赛' }} <span class="tips">如需修改请返回上一步</span>
{{ step1.completeCompetitionSetup.competitionType ? '团队赛(' + step1.completeCompetitionSetup.minTeamSize + </el-form-item>
'-' + step1.completeCompetitionSetup.maxTeamSize + '人/队)' : '个人赛' }} <span <el-form-item prop="rule" label="赛制">
class="tips">如需修改请返回上一步</span> <el-radio v-for="(rule, i) in rules" :key="i" v-model="form.rule" :label="rule.id">{{ rule.name }}</el-radio>
</el-form-item> <p class="tips">积分赛包含多个竞赛阶段每个阶段的成绩都包含在最终总成绩里最后一轮结束后总成绩排名靠前的参赛者得到获奖资格</p>
<el-form-item prop="rule" label="赛制"> <p class="tips">淘汰赛包含多个竞赛阶段每个阶段结束后之后只有部分参赛者能晋级下一阶段晋级最后一轮且在最后一轮排名靠前的参赛者得到获奖资格</p>
<el-radio v-for="(rule, i) in rules" :key="i" v-model="form.rule" :label="rule.id">{{ rule.name <p class="tips">单项赛仅包含一个竞赛阶段单项的成绩排名即为最终排名排名靠前的参赛者得到获奖资格</p>
}}</el-radio> <p class="tips">系统默认排名规则优先按分数排名分数高则排名靠前分数相同则按用时排名用时短则排名靠前</p>
<p class="tips">积分赛包含多个竞赛阶段每个阶段的成绩都包含在最终总成绩里最后一轮结束后总成绩排名靠前的参赛者得到获奖资格</p> </el-form-item>
<p class="tips">淘汰赛包含多个竞赛阶段每个阶段结束后之后只有部分参赛者能晋级下一阶段晋级最后一轮且在最后一轮排名靠前的参赛者得到获奖资格</p> <template v-if="form.rule !== 2">
<p class="tips">单项赛仅包含一个竞赛阶段单项的成绩排名即为最终排名排名靠前的参赛者得到获奖资格</p> <el-form-item prop="stageNum" label="阶段数量">
<p class="tips">系统默认排名规则优先按分数排名分数高则排名靠前分数相同则按用时排名用时短则排名靠前</p> <div class="input-center">
</el-form-item> <el-select v-model="form.stageNum" @change="stageChange">
<template v-if="form.rule !== 2"> <el-option v-for="i in 10" :key="i" :label="i" :value="i"></el-option>
<el-form-item prop="stageNum" label="阶段数量"> </el-select>
<div class="input-center"> </div>
<el-select v-model="form.stageNum" @change="stageChange"> <div v-if="step1.completeCompetitionSetup.competitionType" class="tips">
<el-option v-for="i in 10" :key="i" :label="i" :value="i"></el-option> (团队赛是否限制队内每个成员只能参加一个阶段赛项
</el-select> <el-radio v-model="form.teamLimit" :label="1"></el-radio>
</div> <el-radio v-model="form.teamLimit" :label="0"></el-radio>
<div v-if="step1.completeCompetitionSetup.competitionType" class="tips"> )
(团队赛是否限制队内每个成员只能参加一个阶段赛项 </div>
<el-radio v-model="form.teamLimit" :label="1"></el-radio> </el-form-item>
<el-radio v-model="form.teamLimit" :label="0"></el-radio> <el-form-item v-if="!form.rule" prop="resultCalculationMethod" label="总成绩计算方式">
) <el-radio v-model="form.resultCalculationMethod" :label="0">各阶段成绩加权求和</el-radio>
</div> <el-radio v-model="form.resultCalculationMethod" :label="1">各阶段成绩直接求和</el-radio>
</el-form-item> <el-radio v-model="form.resultCalculationMethod" :label="2">各阶段成绩取平均值</el-radio>
<el-form-item v-if="!form.rule" prop="resultCalculationMethod" label="总成绩计算方式"> <p class="tips">若选择加权求和则需要设置每个阶段成绩所占权重且权重总和须为100%</p>
<el-radio v-model="form.resultCalculationMethod" :label="0">各阶段成绩加权求和</el-radio> </el-form-item>
<el-radio v-model="form.resultCalculationMethod" :label="1">各阶段成绩直接求和</el-radio> <el-form-item prop="stageNum" label="阶段设置">
<el-radio v-model="form.resultCalculationMethod" :label="2">各阶段成绩取平均值</el-radio> <div v-for="(item, i) in form.competitionStageList" :key="i" class="step-set">
<p class="tips">若选择加权求和则需要设置每个阶段成绩所占权重且权重总和须为100%</p> <div class="line">
</el-form-item> {{ serials[i] }}阶段 <el-input v-model="item.stageName" clearable placeholder="请输入阶段名称,如“初赛”" style="width: 200px"></el-input>
<el-form-item prop="stageNum" label="阶段设置"> </div>
<div v-for="(item, i) in form.competitionStageList" :key="i" class="step-set"> <div class="line">
<div class="line"> <span class="req">*</span>
{{ serials[i] }}阶段 <el-input v-model="item.stageName" clearable placeholder="请输入阶段名称,如“初赛”" 比赛方式
style="width: 200px"></el-input> <el-radio v-for="(method, i) in methods" :key="i" v-model="item.method" :label="method.id">{{ method.name }}</el-radio>
</div> </div>
<div class="line"> <div v-if="step1.completeCompetitionSetup.competitionType" class="line">
<span class="req">*</span> <span class="req">*</span>
比赛方式 团队参赛人数限制
<el-radio v-for="(method, i) in methods" :key="i" v-model="item.method" :label="method.id">{{ <el-radio v-model="item.teamNumLimitOpt" :label="0">不限制</el-radio>
method.name }}</el-radio> <el-radio v-model="item.teamNumLimitOpt" :label="1">自定义</el-radio>
</div> <el-input v-model.number="item.teamNumLimit" type="number" style="width: 150px;" :disabled="item.teamNumLimitOpt === 0"></el-input>
<div v-if="step1.completeCompetitionSetup.competitionType" class="line"> <span class="tips">可限制本阶段单个团队的出战人数</span>
<span class="req">*</span> </div>
团队参赛人数限制 <div v-if="step1.completeCompetitionSetup.competitionType" class="line">
<el-radio v-model="item.teamNumLimit" :label="0">不限制</el-radio> <span class="req">*</span>
<el-radio v-model="item.teamNumLimit" :label="1">自定义</el-radio> 团队成绩计算方式
<el-input v-model.number="item.customNumber" type="number" min="0" style="width: 150px;" <el-radio v-for="(j, i) in teamCalculationMethods" :key="i" v-model="item.teamCalculationMethod" :label="j.id">{{ j.name }}</el-radio>
:disabled="item.teamNumLimit === 0"></el-input> <span class="tips">可设置本阶段的团队取分规则</span>
<span class="tips">可限制本阶段单个团队的出战人数</span> </div>
</div> <div v-if="form.rule === 1 && i !== form.competitionStageList.length - 1" class="line" style="display: flex;">
<div v-if="step1.completeCompetitionSetup.competitionType" class="line"> <p>
<span class="req">*</span> <span class="req">*</span>晋级规则
团队成绩计算方式 </p>
<el-radio v-for="(j, i) in teamCalculationMethods" :key="i" v-model="item.teamCalculationMethod" <div>
:label="j.id">{{ j.name }}</el-radio> <div class="line">
<span class="tips">可设置本阶段的团队取分规则</span> 本阶段成绩排名前
</div> <el-input v-model.number="item.peopleLimit" type="number" style="width: 100px"></el-input>
<div v-if="form.rule === 1 && i !== form.competitionStageList.length - 1" class="line" 可晋级下一阶段比赛
style="display: flex;"> </div>
<p> <div class="line">
<span class="req">*</span>晋级规则 本阶段成绩排名前
</p> <el-input v-model.number="item.percentageLimit" type="number" style="width: 100px"></el-input>
<div> %可晋级下一阶段比赛
<div class="line"> </div>
本阶段成绩排名前 <div>
<el-input v-model.number="item.peopleLimit" type="number" min="0" style="width: 100px"></el-input> 本阶段成绩
可晋级下一阶段比赛 <el-select v-model="item.operator" style="width: 80px;margin-right: 10px">
<el-option v-for="i in operators" :key="i" :label="i" :value="i"></el-option>
</el-select>
<el-input v-model="item.score" type="number" style="width: 100px"></el-input>
可晋级下一阶段比赛
</div>
</div>
</div>
<div v-if="!form.rule" class="line">
<span class="req">*</span>
占总成绩权重
<el-input v-model.number="item.pointWeight" type="number" :disabled="form.resultCalculationMethod != 0" style="width: 150px;"></el-input> %
</div>
<div class="line">
<span class="req">*</span>
成绩公布时间
阶段比赛结束后
<el-input v-model.number="item.resultAnnouncementTime" type="number" style="width: 120px"></el-input>
小时公布阶段比赛成绩
</div>
<div class="line">
<span class="req">*</span>
是否公布成绩详情
<el-radio v-model="item.resultsDetails" :label="0"></el-radio>
<el-radio v-model="item.resultsDetails" :label="1"></el-radio>
<p class="tips">若选择则公布成绩详情竞赛结束后参赛者可查看自己的比赛成绩得分详情</p>
<p class="tips">若选择则不公布成绩详情参赛者只能知晓自己的分数及排名不能查看得分详情</p>
</div>
</div> </div>
<div class="line"> </el-form-item>
本阶段成绩排名前 </template>
<el-input v-model.number="item.percentageLimit" type="number" min="0" <template v-else>
style="width: 100px"></el-input> <el-form-item prop="stageNum" label="规则设置">
%可晋级下一阶段比赛 <div class="step-set">
<div class="line">
<span class="req">*</span>
比赛方式
<el-radio v-for="(method, i) in methods" :key="i" v-model="form.competitionStageList[0].method" :label="method.id">{{ method.name }}</el-radio>
</div>
<div v-if="step1.completeCompetitionSetup.competitionType" class="line">
<span class="req">*</span>
团队成绩计算方式
<el-radio v-for="(j, i) in teamCalculationMethods" :key="i" v-model="form.competitionStageList[0].teamCalculationMethod" :label="j.id">{{ j.name }}</el-radio>
<span class="tips">可设置本阶段的团队取分规则</span>
</div>
</div> </div>
<div> </el-form-item>
本阶段成绩 <el-form-item prop="rule" label="成绩公布时间">
<el-select v-model="item.operator" style="width: 80px;margin-right: 10px"> 阶段比赛结束后
<el-option v-for="i in operators" :key="i" :label="i" :value="i"></el-option> <el-input v-model.number="form.competitionStageList[0].resultAnnouncementTime" type="number" style="width: 120px"></el-input>
</el-select> 小时公布阶段比赛成绩
<el-input v-model="item.score" type="number" min="0" style="width: 100px"></el-input> </el-form-item>
可晋级下一阶段比赛 <el-form-item prop="resultsDetails" label="是否公布成绩详情">
</div> <el-radio v-model="form.competitionStageList[0].resultsDetails" :label="0"></el-radio>
</div> <el-radio v-model="form.competitionStageList[0].resultsDetails" :label="1"></el-radio>
</div> <p class="tips">若选择则公布成绩详情竞赛结束后参赛者可查看自己的比赛成绩得分详情</p>
<div v-if="!form.rule" class="line"> <p class="tips">若选择则不公布成绩详情参赛者只能知晓自己的分数及排名不能查看得分详情</p>
<span class="req">*</span> </el-form-item>
占总成绩权重 </template>
<el-input v-model.number="item.pointWeight" type="number" min="0" </el-form>
:disabled="form.resultCalculationMethod != 0" style="width: 150px;"></el-input> % </div>
</div> </div>
<div class="line">
成绩公布时间
阶段比赛结束后
<el-input v-model.number="item.resultAnnouncementTime" type="number" min="0"
style="width: 120px"></el-input>
小时公布阶段比赛成绩为空则不公布成绩为0则阶段比赛结束后立马公布成绩
</div>
<div
v-if="item.resultAnnouncementTime !== '' && item.resultAnnouncementTime !== null && item.resultAnnouncementTime !== undefined"
class="line">
是否公布成绩详情
<el-radio v-model="item.resultsDetails" :label="0"></el-radio>
<el-radio v-model="item.resultsDetails" :label="1"></el-radio>
<p class="tips">若选择则公布成绩详情竞赛结束后参赛者可查看自己的比赛成绩得分详情</p>
<p class="tips">若选择则不公布成绩详情参赛者只能知晓自己的分数及排名不能查看得分详情</p>
</div>
</div>
</el-form-item>
</template>
<template v-else>
<el-form-item prop="stageNum" label="规则设置">
<div class="step-set">
<div class="line">
<span class="req">*</span>
比赛方式
<el-radio v-for="(method, i) in methods" :key="i" v-model="form.competitionStageList[0].method"
:label="method.id">{{ method.name }}</el-radio>
</div>
<div v-if="step1.completeCompetitionSetup.competitionType" class="line">
<span class="req">*</span>
团队成绩计算方式
<el-radio v-for="(j, i) in teamCalculationMethods" :key="i"
v-model="form.competitionStageList[0].teamCalculationMethod" :label="j.id">{{ j.name }}</el-radio>
<span class="tips">可设置本阶段的团队取分规则</span>
</div>
</div>
</el-form-item>
<el-form-item label="成绩公布时间">
阶段比赛结束后
<el-input v-model.number="form.competitionStageList[0].resultAnnouncementTime" type="number" min="0"
style="width: 120px"></el-input>
小时公布阶段比赛成绩为空则不公布成绩为0则阶段比赛结束后立马公布成绩
</el-form-item>
<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="1"></el-radio>
<p class="tips">若选择则公布成绩详情竞赛结束后参赛者可查看自己的比赛成绩得分详情</p>
<p class="tips">若选择则不公布成绩详情参赛者只能知晓自己的分数及排名不能查看得分详情</p>
</el-form-item>
</template>
</el-form>
</div>
</div> </div>
</div>
</template> </template>
<script> <script>
import util from "@/libs/util"; import util from "@/libs/util";
import quill from "@/components/quill";
import Const from '@/const/match' import Const from '@/const/match'
import _ from 'lodash'
export default { export default {
props: ['setupId', 'editing'], props: ['setupId', 'editing'],
data () { data() {
return { return {
id: this.$route.query.id, id: this.$route.query.id,
updateTime: 0, updateTime: 0,
step1: this.$parent.$refs.step1.form, step1: this.$parent.$refs.step1.form,
serials: ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'], serials: ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'],
form: { form: {
resultCalculationMethod: 0, resultCalculationMethod: 0,
rule: 0, rule: 0,
stageNum: 3, stageNum: 3,
teamLimit: 1, teamLimit: 1,
competitionStageList: [ competitionStageList: [
{ {
method: 0, method: 0,
number: 1, number: 1,
pointWeight: '', pointWeight: '',
stageName: '', stageName: '',
teamCalculationMethod: 0, teamCalculationMethod: 0,
peopleLimit: '', peopleLimit: '',
percentageLimit: '', percentageLimit: '',
scoreLimit: '', scoreLimit: '',
operator: '>', operator: '>',
score: '', score: '',
customNumber: '', teamNumLimit: '',
teamNumLimit: 0, teamNumLimitOpt: 0,
resultAnnouncementTime: '', resultAnnouncementTime: '',
resultsDetails: '', resultsDetails: 0,
},
{
method: 0,
number: 2,
pointWeight: '',
stageName: '',
teamCalculationMethod: 0,
peopleLimit: '',
percentageLimit: '',
scoreLimit: '',
operator: '>',
score: '',
teamNumLimit: '',
teamNumLimitOpt: 0,
resultAnnouncementTime: '',
resultsDetails: 0,
},
{
method: 0,
number: 3,
pointWeight: '',
stageName: '',
teamCalculationMethod: 0,
peopleLimit: '',
percentageLimit: '',
scoreLimit: '',
operator: '>',
score: '',
teamNumLimit: '',
teamNumLimitOpt: 0,
resultAnnouncementTime: '',
resultsDetails: 0,
}
]
}, },
{ validRules: {
method: 0, rule: [
number: 2, { required: true, trigger: 'change' }
pointWeight: '', ],
stageName: '', stageNum: [
teamCalculationMethod: 0, { required: true, trigger: 'change' }
peopleLimit: '', ],
percentageLimit: '', resultCalculationMethod: [
scoreLimit: '', { required: true, trigger: 'change' }
operator: '>', ],
score: '', resultAnnouncementTime: [
customNumber: '', { required: true, message: '请输入成绩公布时间', trigger: 'change' }
teamNumLimit: 0, ],
resultAnnouncementTime: '', resultsDetails: [
resultsDetails: '', { required: true, trigger: 'change' }
],
}, },
{ ruleForm: {},
method: 0, rules: Const.rules,
number: 3, methods: Const.methods,
pointWeight: '', teamCalculationMethods: Const.teamCalculationMethods,
stageName: '', operators: ['>', '>=', '=', '<', '<=']
teamCalculationMethod: 0, };
peopleLimit: '',
percentageLimit: '',
scoreLimit: '',
operator: '>',
score: '',
customNumber: '',
teamNumLimit: 0,
resultAnnouncementTime: '',
resultsDetails: '',
}
]
},
validRules: {
rule: [
{ required: true, trigger: 'change' }
],
stageNum: [
{ required: true, trigger: 'change' }
],
resultCalculationMethod: [
{ required: true, trigger: 'change' }
],
resultAnnouncementTime: [
{ required: true, message: '请输入成绩公布时间', trigger: 'change' }
],
resultsDetails: [
{ required: true, trigger: 'change' }
],
},
originForm: null,
ruleForm: {},
rules: Const.rules,
methods: Const.methods,
teamCalculationMethods: Const.teamCalculationMethods,
operators: ['>', '>=', '=', '<', '<=']
};
},
watch: {
// ,
form: {
handler () {
this.updateTime++
},
deep: true
},
},
mounted () {
this.ruleForm = JSON.parse(JSON.stringify(this.form.competitionStageList[0]))
this.id && this.getData()
this.step1 || this.getStep1() //
},
methods: {
getData () {
this.$get(this.api.getCompetitionRule, {
competitionId: this.id
}).then(res => {
const rule = res.competitionRule
if (rule) {
rule.competitionStageList.map(e => {
const limit = e.scoreLimit
if (limit) {
e.operator = limit.replace(/\d+/, '')
const num = limit.replace(/\D+/, '')
if (num) e.score = num
} else {
e.operator = '>'
e.score = ''
}
if (!e.peopleLimit) e.peopleLimit = ''
if (!e.percentageLimit) e.percentageLimit = ''
e.teamCalculationMethod = +e.teamCalculationMethod
})
this.originForm = _.cloneDeep(rule)
this.form = rule
}
this.$nextTick(() => {
this.updateTime = 0
})
}).catch(res => { })
}, },
// watch: {
getStep1 () { // ,
this.$post(`${this.api.getCompetition}?competitionId=${this.id}`).then(({ competition }) => { form: {
this.step1 = competition handler(){
const { minTeamSize, maxTeamSize, competitionType } = this.step1.completeCompetitionSetup this.updateTime++
competitionType && minTeamSize !== '' && maxTeamSize !== '' && minTeamSize == maxTeamSize && this.teamCalculationMethods.pop() // },
}).catch(err => { }) deep:true
},
}, },
// mounted() {
stageChange (val) { this.ruleForm = JSON.parse(JSON.stringify(this.form.competitionStageList[0]))
const stages = this.form.competitionStageList this.id && this.getData()
const { ruleId } = this.form this.step1 || this.getStep1() //
if (stages.length < val) {
const len = stages.length
for (let i = 1; i <= val - len; i++) {
const form = JSON.parse(JSON.stringify(this.ruleForm))
form.number = len + i
if (ruleId) form.ruleId = ruleId
this.form.competitionStageList.push(form)
}
} else {
this.form.competitionStageList = stages.slice(0, val)
}
}, },
// methods: {
async automaticAllocation (next) { getData() {
// this.$get(this.api.getCompetitionRule, {
if (this.step1.completeCompetitionSetup.competitionType) { competitionId: this.id
const { form, originForm } = this }).then(res => {
// 34 const rule = res.competitionRule
let changeLimit = 0 if (rule) {
for (const i in form.competitionStageList) { rule.competitionStageList.map(e => {
const e = form.competitionStageList[i] const limit = e.scoreLimit
const originStage = originForm.competitionStageList[i] if (limit) {
if (!originStage || e.teamNumLimit !== originStage.teamNumLimit || e.customNumber !== originStage.customNumber) { e.operator = limit.replace(/\d+/, '')
changeLimit = 1 const num = limit.replace(/\D+/, '')
break if (num) e.score = num
} else {
e.operator = '>'
e.score = ''
}
if (!e.peopleLimit) e.peopleLimit = ''
if (!e.percentageLimit) e.percentageLimit = ''
e.teamNumLimitOpt = e.teamNumLimit ? 1 : 0
e.teamCalculationMethod = +e.teamCalculationMethod
})
this.form = rule
} }
} this.$nextTick(() => {
// new Date(this.$parent.$refs.step1.form.signUpEndTime) this.updateTime = 0
if (form.rule !== originForm.rule || form.stageNum !== originForm.stageNum || form.teamLimit !== originForm.teamLimit || changeLimit) {
await this.$post(this.api.updateEventAllocationRecord, {
competitionId: +this.id,
whetherToModifyTheRule: 1,
}) })
this.$emit('next', next) }).catch(res => {})
},
//
getStep1() {
this.$post(`${this.api.getCompetition}?competitionId=${this.id}`).then(({ competition }) => {
this.step1 = competition
const { minTeamSize, maxTeamSize, competitionType } = this.step1.completeCompetitionSetup
competitionType && minTeamSize !== '' && maxTeamSize !== '' && minTeamSize == maxTeamSize && this.teamCalculationMethods.pop() //
}).catch(err => {})
},
//
stageChange(val) {
const stages = this.form.competitionStageList
const { ruleId } = this.form
if (stages.length < val) {
const list = []
for (let i = 1; i <= val - stages.length; i++) {
const form = JSON.parse(JSON.stringify(this.ruleForm))
form.number = stages.length + i
if (ruleId) form.ruleId = ruleId
this.form.competitionStageList.push(form)
}
} else { } else {
this.$emit('next', next) this.form.competitionStageList = stages.slice(0, val)
} }
} else { },
this.$emit('next', next) //
} save(status, next = 0) {
}, let { form } = this
// const { rule } = form
save (status, next = 0) { let invalid = 0
const form = _.cloneDeep(this.form) let pointWeight = 0
const { rule } = form const { step1 } = this
let invalid = 0 //
let pointWeight = 0 if (next === 2) {
const { step1 } = this let stages = form.competitionStageList
// if (form.rule === 2) { //
if (next === 2) { const e = stages[0]
let stages = form.competitionStageList e.stageName = step1.name
if (form.rule === 2) { // if (!e.resultsDetails) {
const e = stages[0] if (e.resultAnnouncementTime === '') {
e.stageName = step1.name return util.errorMsg('请填写成绩公布时间')
if (e.resultsDetails === 0 && e.resultAnnouncementTime !== '') {
if (e.resultAnnouncementTime < 0) {
return util.errorMsg('成绩公布时间不得小于0')
}
if (e.resultAnnouncementTime % 1) {
return util.errorMsg('成绩公布时间须为整数')
}
e.resultAnnouncementTime = +e.resultAnnouncementTime
}
form.competitionStageList = stages.slice(0, 1) //
} else { //
let customNumber = 0
const { competitionType, minTeamSize, maxTeamSize } = step1.completeCompetitionSetup // 01
for (const i in stages) {
const e = stages[i]
if (rule !== 2 && !e.stageName) {
invalid = 1
util.errorMsg('请输入阶段名称')
break
}
// rule: 012
//
if (!rule) {
//
if (form.resultCalculationMethod == 0 && (e.pointWeight === '' || e.pointWeight === undefined)) {
invalid = 1
util.errorMsg('请输入权重')
break
} }
pointWeight += e.pointWeight // if (e.resultAnnouncementTime < 0) {
} else if (rule === 1) { // return util.errorMsg('成绩公布时间不得小于0')
// ()
if (i != stages.length - 1 && e.peopleLimit === '' && e.percentageLimit === '' && e.score === '') {
invalid = 1
util.errorMsg('请至少填写一条晋级规则')
break
} }
if (e.score !== '') e.scoreLimit = e.operator + e.score if (e.resultAnnouncementTime % 1) {
} return util.errorMsg('成绩公布时间须为整数')
if (rule !== 2 && competitionType && e.teamNumLimit) {
if (e.customNumber === '' || e.customNumber === undefined) {
invalid = 1
util.errorMsg('请输入团队参数人数限制')
break
} else if (e.customNumber < 0) {
invalid = 1
util.errorMsg('团队参数人数不得小于0')
break
} else if (maxTeamSize !== '' && e.customNumber > maxTeamSize) {
invalid = 1
util.errorMsg('团队参数人数不得大于团队人数上限')
break
} }
e.resultAnnouncementTime = +e.resultAnnouncementTime
} }
if (e.resultsDetails === 0 && (e.resultAnnouncementTime !== '' && e.resultAnnouncementTime !== undefined)) { form.competitionStageList = stages.slice(0, 1) //
if (e.resultAnnouncementTime < 0) { } else { //
for (const i in stages) {
const e = stages[i]
if (rule !== 2 && !e.stageName) {
invalid = 1 invalid = 1
util.errorMsg('成绩公布时间不得小于0') util.errorMsg('请输入阶段名称')
break break
} }
if (e.resultAnnouncementTime % 1) { const { competitionType, maxTeamSize } = step1.completeCompetitionSetup // 01
invalid = 1 // rule: 012
util.errorMsg('成绩公布时间须为整数') //
break if (!rule) {
//
if (form.resultCalculationMethod == 0 && e.pointWeight === '') {
invalid = 1
util.errorMsg('请输入权重')
break
}
pointWeight += e.pointWeight //
} else if (rule === 1) { //
// ()
if (i != stages.length - 1 && e.peopleLimit === '' && e.percentageLimit === '' && e.score === '') {
invalid = 1
util.errorMsg('请至少填写一条晋级规则')
break
}
if (e.score !== '') e.scoreLimit = e.operator + e.score
}
if (rule !== 2 && competitionType && e.teamNumLimitOpt) {
if (e.teamNumLimit === '') {
invalid = 1
util.errorMsg('请输入团队参数人数限制')
break
} else if (e.teamNumLimit < 0) {
invalid = 1
util.errorMsg('团队参数人数不得小于0')
break
} else if (maxTeamSize !== '' && e.teamNumLimit > maxTeamSize) {
invalid = 1
util.errorMsg('团队参数人数不得大于团队人数上限')
break
}
}
if (!e.resultsDetails) {
if (e.resultAnnouncementTime === '') {
invalid = 1
util.errorMsg('请填写成绩公布时间')
break
}
if (e.resultAnnouncementTime < 0) {
invalid = 1
util.errorMsg('成绩公布时间不得小于0')
break
}
if (e.resultAnnouncementTime % 1) {
invalid = 1
util.errorMsg('成绩公布时间须为整数')
break
}
e.resultAnnouncementTime = +e.resultAnnouncementTime
} }
e.resultAnnouncementTime = +e.resultAnnouncementTime
} }
if (e.teamNumLimit && e.customNumber) customNumber += e.customNumber // if (invalid) return
if (!e.teamNumLimit) e.customNumber = '' if (form.resultCalculationMethod == 0 && !rule && pointWeight > 0 && pointWeight !== 100) return util.errorMsg('权重须等于100,请重新输入')
} }
if (invalid) return } else { // 稿
if (form.teamLimit && competitionType) { form.competitionStageList = form.competitionStageList.filter(e => e.stageName)
if (stages.length > minTeamSize) return util.errorMsg('阶段数不得大于团队人数下限')
if (customNumber > minTeamSize) return util.errorMsg('各阶段自定义的参赛人数之和不得大于团队人数下限')
}
if (form.resultCalculationMethod == 0 && !rule && pointWeight > 0 && pointWeight !== 100) return util.errorMsg('权重须等于100,请重新输入')
} }
} else { // 稿 for (const e of form.competitionStageList) {
form.competitionStageList = form.competitionStageList.filter(e => e.stageName) if (!e.teamNumLimitOpt) e.teamNumLimit = 0
} }
this.$parent.showLoad() this.$parent.showLoad()
if (form.ruleId) { if (form.ruleId) {
this.$post(this.api.editCompetitionRule, form).then(res => { this.$post(this.api.editCompetitionRule, form).then(res => {
this.$parent.hideLoad() this.$parent.hideLoad()
this.updateTime && util.successMsg("修改成功"); util.successMsg("修改成功");
this.automaticAllocation(next) this.$emit('next', next)
}).catch(err => { }).catch(err => {
this.$parent.hideLoad() this.$parent.hideLoad()
}) })
} else { } else {
form.setupId = this.setupId form.setupId = this.setupId
this.$post(this.api.addCompetitionRule, form).then(res => { this.$post(this.api.addCompetitionRule, form).then(res => {
this.$parent.hideLoad() this.$parent.hideLoad()
util.successMsg("创建成功"); util.successMsg("创建成功");
this.$emit('next', next) this.$emit('next', next)
}).catch(err => { }).catch(err => {
this.$parent.hideLoad() this.$parent.hideLoad()
}) })
} }
}, },
} }
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
/deep/ .d-inline-block { /deep/ .d-inline-block {
width: 216px; width: 216px;
.el-select, .el-input {
.el-select, width: 100%;
.el-input { }
width: 100%;
}
} }
.inline-input { .inline-input {
.input-wrap { .input-wrap {
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 10px; margin-bottom: 10px;
.el-input { .el-input {
display: inline-block; display: inline-block;
width: 216px; width: 216px;
margin-right: 8px; margin-right: 8px;
} }
.remove { .remove {
width: 16px; width: 16px;
height: 16px; height: 16px;
background: url('../../../assets/img/close.png') 0 0 / cover no-repeat; background: url("../../../assets/img/close.png") 0 0/cover no-repeat;
cursor: pointer; cursor: pointer;
}
} }
}
.add-btn { .add-btn {
margin-left: 32px; margin-left: 32px;
} }
} }
.input-center { .input-center {
display: flex; display: flex;
align-items: center; align-items: center;
width: 216px; width: 216px;
white-space: nowrap; white-space: nowrap;
.el-input { .el-input {
margin-right: 5px; margin-right: 5px;
} }
} }
.step-set { .step-set {
padding: 15px; padding: 15px;
background-color: #fbfbfb; background-color: #fbfbfb;
} }
.tips { .tips {
font-size: 13px; font-size: 13px;
color: #959595; color: #959595;
} }
.req { .req {
color: #f00; color: #f00;
} }
.line { .line {
margin-bottom: 10px; margin-bottom: 10px;
} }

@ -1,105 +1,93 @@
<template> <template>
<div> <div>
<div v-show="!setVisible" class="page"> <div v-show="!setVisible"
class="page">
<div class="page-content"> <div class="page-content">
<div class="p-title">比赛内容设置</div> <div class="p-title">比赛内容设置</div>
<el-form label-width="170px" label-suffix=":" size="small" :disabled="!!(!editing && id)"> <el-form label-width="170px"
<div v-for="(item, i) in form" :key="i" class="step"> label-suffix=":"
size="small"
:disabled="!editing && id">
<div v-for="(item, i) in form"
:key="i"
class="step">
<div class="title"> <div class="title">
<span>{{ item.stageName }}{{ nums[i] }}阶段 | {{ methods.find(e => e.id === item.method).name }} </span> <span>{{ item.stageName }}{{ nums[i] }}阶段 | {{ methods.find(e => e.id === item.method).name }} </span>
<el-button v-if="item.method !== 2" type="primary" @click="toSet(i)">设置</el-button> <el-button v-if="item.method !== 2"
type="primary"
@click="toSet(i)">设置</el-button>
</div> </div>
<el-form-item class="req" prop="time" label="比赛时间"> <el-form-item class="req"
prop="time"
label="比赛时间">
<span v-if="item.method !== 2 && item.startTime">{{ item.startTime + ' ' + item.endTime }}</span> <span v-if="item.method !== 2 && item.startTime">{{ item.startTime + ' ' + item.endTime }}</span>
<div style="display: flex;align-items: center;" v-if="item.method === 2"> <div style="display: flex;align-items: center;"
<el-date-picker v-model="item.time" type="datetimerange" range-separator="~" start-placeholder="开始日期" v-if="item.method === 2">
end-placeholder="结束日期" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" <el-date-picker v-model="item.time"
@change="timeChange"> type="datetimerange"
range-separator="~"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
@change="timeChange">
</el-date-picker> </el-date-picker>
<el-alert style="width: auto;padding: 0px 16px;margin-left: 10px;" <el-alert style="width: auto;padding: 0px 16px;margin-left: 10px;"
:title="'(请设置在 ' + step1.playStartTime + ' ~ ' + step1.playEndTime + '间)'" type="error" :title="'(请设置在 ' + step1.playStartTime + ' ~ ' + step1.playEndTime + '间)'"
:closable="false" effect="dark"> type="error"
:closable="false"
effect="dark">
</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"
<el-input v-model="item.offlineAddress" style="width: 80%"></el-input> label="比赛地点">
<el-input v-model="item.offlineAddress"
style="width: 80%"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="系统链接"> <el-form-item class="req"
<el-input v-model="item.competitionStageContentSetting.systemLink" style="width: 80%"></el-input> label="比赛内容">
<el-input v-model="item.contentDescription"
type="textarea"
style="width: 80%"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="是否支持上传文件"> <el-form-item class="req"
<div> label="评分规则">
<el-radio v-model="item.competitionStageContentSetting.whetherToUploadFiles" :label="0"></el-radio> <el-input v-model="item.scoreRule"
</div> type="textarea"
<div class="flex a-center"> style="width: 80%"></el-input>
<el-radio v-model="item.competitionStageContentSetting.whetherToUploadFiles" :label="1"></el-radio>
<template v-if="item.competitionStageContentSetting.whetherToUploadFiles">
<el-upload class="file-upload" :on-remove="(file, fileList) => handleRemove(file, fileList, item)"
:on-error="uploadError" :before-remove="beforeRemove" :on-preview="handlePreview" action=""
:file-list="item.competitionStageContentSetting.fileList"
:http-request="res => handleRequest(res, item)">
<el-button size="small" type="primary">上传文件</el-button>
<!-- <div slot="tip"
class="el-upload__tip"
style="position: relative">
<div v-if="item.competitionStageContentSetting.fileList.length"
class="download"
@click="downloadFile(item.competitionStageContentSetting.fileList)">
<p v-for="(file, i) in item.competitionStageContentSetting.fileList"
:key="i">下载</p>
</div>
</div> -->
</el-upload>
</template>
</div>
<div style="display: flex;align-items: flex-start;margin-top: 10px">
<span style="margin: 0 10px 0 30px;">说明</span>
<el-input maxlength="1000" placeholder="请输入内容" type="textarea"
v-model="item.competitionStageContentSetting.stageExplain"
style="width: calc(80% - 216px);"></el-input>
</div>
</el-form-item>
<el-form-item class="req" label="比赛内容">
<el-input v-model="item.contentDescription" type="textarea" style="width: 80%"></el-input>
</el-form-item>
<el-form-item class="req" label="评分规则">
<el-input v-model="item.scoreRule" type="textarea" style="width: 80%"></el-input>
</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"
<el-form-item class="req" prop="cid" label="课程系统"> prop="cid"
{{ item.systemName }} label="课程系统">
</el-form-item> {{ item.systemName }}
<el-form-item class="req" prop="assessmentId" label="已选择考核"> </el-form-item>
{{ item.projectName }} <el-form-item class="req"
</el-form-item> prop="assessmentId"
</template> label="已选择考核">
<template v-else> {{ item.projectName }}
<el-form-item class="req" label="已选择试卷"> </el-form-item>
<div class="flex"> <el-form-item class="req"
{{ item.paperName }}&emsp; prop="resultAnnouncementTime"
<el-form> label="比赛地点">
<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="比赛地点">
<div class="line"> <div class="line">
<el-checkbox v-model="item.onlineButton">线上</el-checkbox> <el-checkbox v-model="item.onlineButton">线上</el-checkbox>
<el-input v-model="item.onlineAddress" clearable placeholder="请输入比赛网址" :disabled="!item.onlineButton" <el-input v-model="item.onlineAddress"
style="width: 400px;margin-left: 10px"></el-input> clearable
placeholder="请输入比赛网址"
:disabled="!item.onlineButton"
style="width: 400px;margin-left: 10px"></el-input>
</div> </div>
<div class="line"> <div class="line">
<el-checkbox v-model="item.offlineButton">线下</el-checkbox> <el-checkbox v-model="item.offlineButton">线下</el-checkbox>
<el-input v-model="item.offlineAddress" clearable placeholder="请输入地址" :disabled="!item.offlineButton" <el-input v-model="item.offlineAddress"
style="width: 400px;margin-left: 10px"></el-input> clearable
placeholder="请输入地址"
:disabled="!item.offlineButton"
style="width: 400px;margin-left: 10px"></el-input>
</div> </div>
</el-form-item> </el-form-item>
</template> </template>
@ -108,41 +96,25 @@
</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]"
<el-dialog title="提示" :visible.sync="tipsVisible" width="500px" :close-on-click-modal="false" :step1.sync="step1"
custom-class="tips-dia"> @hideSet="hideSet" />
<p style="font-size: 17px;text-align: center;color: #9076ff;">编辑发布成功</p>
<p style="margin: 5px 0px 10px;line-height: 1.6">
温馨提示报名结束后更改报名时间或赛程规则不影响已分配的阶段参赛人员且后续添加的人员不会自动分配如需重新自动分配所有团队请到报名列表执行全员重新分配操作
</p>
<el-checkbox v-model="closeStatus">不再提示</el-checkbox>
<span slot="footer" class="dialog-footer">
<el-button size="small" type="primary" @click="closePopup">关闭</el-button>
</span>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import Set from './set' import util from "@/libs/util";
import Oss from '@/components/upload/upload.js' import set from './set'
import Setting from '@/setting'
import Util from '@/libs/util'
export default { export default {
props: ['setupId', 'competitionId', 'editing'], props: ['setupId', 'competitionId', 'editing'],
components: { Set },
data () { data () {
return { return {
headers: {
token: sessionStorage.getItem('token')
},
id: this.$route.query.id, id: this.$route.query.id,
updateTime: 0, updateTime: 0,
step1: this.$parent.$refs.step1.form, step1: this.$parent.$refs.step1.form,
cache: this.$store.state.competitionCache, cache: this.$store.state.competitionCache,
nums: ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'], nums: ['一', '二', '三'],
methods: [ methods: [
{ {
id: 0, id: 0,
@ -166,23 +138,20 @@ export default {
stageId: '', stageId: '',
startTime: '', startTime: '',
systemId: '', systemId: '',
paperId: '',
paperName: '',
offlineAddress: '', offlineAddress: '',
offlineButton: 0, offlineButton: 0,
onlineAddress: '', onlineAddress: '',
onlineButton: 0, onlineButton: 0,
time: [], time: []
}, },
form: [], form: [],
setVisible: false, setVisible: false,
curStep: 0, curStep: 0,
curOriginForm: {},
closeStatus: false,
tipsVisible: false,
}; };
}, },
components: {
set
},
watch: { watch: {
// , // ,
form: { form: {
@ -216,45 +185,14 @@ export default {
} else { } else {
form.time = [] form.time = []
} }
// 线
if (e.method === 2) {
if (!form.competitionStageContentSetting) {
form.competitionStageContentSetting = {
whetherToUploadFiles: 0,
stageExplain: '',
fileUrl: '',
systemLink: '',
fileList: []
}
}
form.competitionStageContentSetting.fileList = []
//
if (form.competitionStageContentSetting.fileUrl) {
const urls = form.competitionStageContentSetting.fileUrl.split('|')
const names = form.competitionStageContentSetting.fileName.split('|')
urls.map((n, i) => {
form.competitionStageContentSetting.fileList.push({
name: names[i],
url: n
})
})
} else {
form.competitionStageContentSetting.fileList = []
}
form.competitionStageContentSetting.competitionId = this.id
form.competitionStageContentSetting.stageId = e.stageId
}
if (!form.mallId) form.mallId = '' if (!form.mallId) form.mallId = ''
form.offlineButton = !!form.offlineButton form.offlineButton = !!form.offlineButton
form.onlineButton = !!form.onlineButton form.onlineButton = !!form.onlineButton
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
@ -263,7 +201,6 @@ export default {
}, },
// //
toSet (i) { toSet (i) {
this.curOriginForm = JSON.parse(JSON.stringify(this.form[i]))
this.curStep = i this.curStep = i
this.$parent.showBtns = false this.$parent.showBtns = false
this.setVisible = true this.setVisible = true
@ -274,26 +211,13 @@ 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) {
const startTime = new Date(val[0]) const startTime = new Date(val[0])
const endTime = new Date(val[1]) const endTime = new Date(val[1])
const { playStartTime, playEndTime } = this.step1 const { playStartTime, playEndTime } = this.step1
if (startTime < new Date(playStartTime) || endTime > new Date(playEndTime)) return Util.warningMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。') if (startTime < new Date(playStartTime) || endTime > new Date(playEndTime)) return util.warningMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。')
const { form, curStep } = this const { form, curStep } = this
for (const i in form) { for (const i in form) {
// //
@ -301,207 +225,88 @@ export default {
const time1 = new Date(form[i].startTime) const time1 = new Date(form[i].startTime)
const time2 = new Date(form[i].endTime) const time2 = new Date(form[i].endTime)
if ((startTime >= time1 && startTime <= time2) || (endTime >= time1 && endTime <= time2)) { if ((startTime >= time1 && startTime <= time2) || (endTime >= time1 && endTime <= time2)) {
Util.warningMsg('请注意,所设置的时间与已设置的阶段时间重合。') util.warningMsg('请注意,所设置的时间与已设置的阶段时间重合。')
break break
} }
} }
} }
} }
}, },
//
beforeUpload (file) {
const isLt2M = file.size / 1024 / 1024 < 10
if (!isLt2M) Util.warningMsg('请上传小于10MB的附件!')
if (isLt2M) {
this.fileName = file.name
return true
} else {
return false
}
},
uploadError (err, file, fileList) {
this.$message({
message: "上传出错,请重试!",
type: "error",
center: true
})
},
downloadFile () {
// const { name, url } = this.fileList[0]
// Util.downloadFile(name, url)
},
handlePreview (file) {
window.open((Util.isDoc(Util.getFileExt(file.name)) ? 'https://view.officeapps.live.com/op/view.aspx?src=' : '') + file.url)
},
beforeRemove (file, fileList) {
return this.$confirm(`确定移除 ${file.name}`);
},
handleRemove (file, fileList, item) {
Oss.del(file.url)
item.competitionStageContentSetting.fileList = fileList
},
//
async handleRequest ({ file }, item) {
Oss.upload(file).then(res => {
item.competitionStageContentSetting.fileList.push({
name: res.name,
url: res.url
})
})
},
// //
publish () { publish () {
this.competitionId && this.$post(`${this.api.publishCompetition}?competitionId=${this.competitionId}&publishStatus=1`).then(res => { }).catch(err => { }) this.competitionId && this.$post(`${this.api.publishCompetition}?competitionId=${this.competitionId}&publishStatus=1`).then(res => { }).catch(err => { })
}, },
//
async closePopup () {
if (this.closeStatus) await this.$post(`${this.api.closePopup}?competitionId=${this.competitionId}`)
this.$emit('next', 0)
},
//
async automaticAllocation (assignOrNot, next) {
await this.$post(this.api.updateEventAllocationRecord, {
assignOrNot,
competitionId: this.competitionId,
})
this.$emit('next', next)
},
//
async autoAllocationConfirm (next) {
//
const { data } = await this.$post(`${this.api.viewEventAllocationInformation}?competitionId=${this.competitionId}`)
if (!data || data.assignOrNot === undefined || !this.form[0].contentId) {
// or
const now = await Util.getNow()
//
if (new Date(this.$parent.$refs.step1.form.signUpEndTime) > now) {
this.$confirm('<p>团队赛发布成功,您是否要启用自动分配阶段参赛人员功能?</p><p style="margin-top: 10px;color: #a9a9a9;">(点击“是”将会在报名截止时清空已有分配,并为所有团队重新自动分配。)</p>', '提示', {
confirmButtonText: '是',
cancelButtonText: '否',
type: 'success',
closeOnClickModal: false,
dangerouslyUseHTMLString: true,
}).then(() => {
this.automaticAllocation(1, next)
}).catch(() => {
this.automaticAllocation(0, next)
})
} else {
this.$confirm('团队赛发布成功,由于您设置的报名时间已结束,如需自动分配阶段参赛人员,请前往报名人员列表进行设置', '提示', {
confirmButtonText: '关闭',
type: 'success',
showCancelButton: false,
closeOnClickModal: false,
dangerouslyUseHTMLString: true,
showClose: false,
}).then(() => {
this.$emit('next', next)
}).catch(() => { })
}
} else if (data.whetherToHidePopUps) {
//
this.tipsVisible = true
} else {
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
if (!form.length) { if (!form.length) {
this.$parent.hideLoad() this.$parent.hideLoad()
Util.successMsg('保存成功') util.successMsg('保存成功')
this.$emit('next', next) this.$emit('next', next)
return return
} }
let invalid = 0 //
const { playStartTime, playEndTime } = this.step1 if (status) {
for (const e of form) { let invalid = 0
// const { playStartTime, playEndTime } = this.step1
if (status) { for (const e of form) {
if (!e.time.length) { if (!e.time.length) {
invalid = 1 invalid = 1
Util.errorMsg('请选择比赛时间') util.errorMsg('请选择比赛时间')
break break
} }
if (new Date(e.time[0]) < new Date(playStartTime) || new Date(e.time[1]) > new Date(playEndTime)) { if (new Date(e.time[0]) < new Date(playStartTime) || new Date(e.time[1]) > new Date(playEndTime)) {
invalid = 1 invalid = 1
Util.errorMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。') util.errorMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。')
break break
} }
if (e.method === 0 && !e.cid) { e.startTime = e.time[0]
e.endTime = e.time[1]
if (e.method !== 2 && !e.cid) {
invalid = 1 invalid = 1
Util.errorMsg('请选择课程') util.errorMsg('请选择课程')
break
}
if (e.method === 1 && !e.paperId) {
invalid = 1
Util.errorMsg('请选择试卷')
break break
} }
if (e.method === 2) { // 线 if (e.method === 2) { // 线
if (!e.offlineAddress) { if (!e.offlineAddress) {
invalid = 1 invalid = 1
Util.errorMsg('请输入比赛地点') util.errorMsg('请输入比赛地点')
break break
} }
if (!e.contentDescription) { if (!e.contentDescription) {
invalid = 1 invalid = 1
Util.errorMsg('请输入比赛内容') util.errorMsg('请输入比赛内容')
break break
} }
if (!e.scoreRule) { if (!e.scoreRule) {
invalid = 1 invalid = 1
Util.errorMsg('请输入评分规则') util.errorMsg('请输入评分规则')
break break
} }
// if (e.competitionStageContentSetting.whetherToUploadFiles && !e.competitionStageContentSetting.stageExplain) {
// invalid = 1
// Util.errorMsg('')
// break
// }
} else { } else {
if (e.onlineButton && !e.onlineAddress) { if (e.onlineButton && !e.onlineAddress) {
invalid = 1 invalid = 1
Util.errorMsg('请输入线上地点') util.errorMsg('请输入线上地点')
break break
} }
if (e.offlineButton && !e.offlineAddress) { if (e.offlineButton && !e.offlineAddress) {
invalid = 1 invalid = 1
Util.errorMsg('请输入线下地点') util.errorMsg('请输入线下地点')
break break
} }
if (!e.onlineAddress && !e.offlineAddress) { if (!e.onlineAddress && !e.offlineAddress) {
invalid = 1 invalid = 1
Util.errorMsg('请输入比赛地点') util.errorMsg('请输入比赛地点')
break break
} }
} }
} }
if (invalid) return
e.startTime = e.time[0]
e.endTime = e.time[1]
} }
if (invalid) return
// //
for (const e of form) { for (const e of form) {
e.offlineButton = e.offlineButton ? 1 : 0 e.offlineButton = e.offlineButton ? 1 : 0
e.onlineButton = e.onlineButton ? 1 : 0 e.onlineButton = e.onlineButton ? 1 : 0
if (e.competitionStageContentSetting) {
if (e.competitionStageContentSetting.fileList && e.competitionStageContentSetting.fileList.length) {
e.competitionStageContentSetting.fileName = e.competitionStageContentSetting.fileList.map(n => n.name).join('|')
e.competitionStageContentSetting.fileUrl = e.competitionStageContentSetting.fileList.map(n => n.url).join('|')
} else {
e.competitionStageContentSetting.fileName = ''
e.competitionStageContentSetting.fileUrl = ''
}
}
} }
this.$parent.showLoad() this.$parent.showLoad()
this.$post(this.api[form[0].contentId ? 'editCompetitionContent' : 'addCompetitionContent'], { this.$post(this.api[form[0].contentId ? 'editCompetitionContent' : 'addCompetitionContent'], {
@ -509,17 +314,9 @@ export default {
}).then(res => { }).then(res => {
this.$parent.hideLoad() this.$parent.hideLoad()
// //
if (status) { status && this.publish(status)
this.publish(status) util.successMsg((status ? '发布' : '保存') + '成功')
this.sendSocket() this.$emit('next', next)
}
Util.successMsg((status ? '发布' : '保存') + '成功')
this.updateTime = 0
if (status && this.$parent.$refs.step1.form.completeCompetitionSetup.competitionType) {
this.autoAllocationConfirm() //
} else {
this.$emit('next', next)
}
}).catch(err => { }).catch(err => {
this.$parent.hideLoad() this.$parent.hideLoad()
}) })
@ -530,51 +327,29 @@ export default {
<style scoped lang="scss"> <style scoped lang="scss">
.step { .step {
padding-bottom: 10px; padding-bottom: 10px;
background-color: #f9f9f9; background-color: #f9f9f9;
.title {
.title { display: flex;
display: flex; justify-content: space-between;
justify-content: space-between; align-items: center;
align-items: center; padding: 10px 15px;
padding: 10px 15px; margin-bottom: 10px;
margin-bottom: 10px; background-color: #ededed;
background-color: #ededed; }
}
} }
.line { .line {
margin-bottom: 10px; margin-bottom: 10px;
} }
/deep/.req { /deep/.req {
.el-form-item__label { .el-form-item__label {
&:before { &:before {
content: '*'; content: '*';
margin-right: 5px; margin-right: 5px;
font-size: 18px; font-size: 18px;
vertical-align: middle; vertical-align: middle;
color: #f00; color: #f00;
}
} }
}
}
/deep/.file-upload {
width: 500px;
.download {
position: absolute;
bottom: -63px;
right: 0;
font-size: 12px;
color: #007eff;
cursor: pointer;
}
}
/deep/.tips-dia {
.el-dialog__body {
padding: 10px 20px;
}
} }
</style> </style>

@ -1,56 +1,53 @@
<template> <template>
<div class="wrap"> <div class="wrap">
<div class="modal"> <div class="modal">
<el-steps :space="200" <el-steps :space="200" :active="4" finish-status="success">
:active="4" <el-step title="大赛信息填写"></el-step>
finish-status="success"> <el-step title="赛程与规则设置"></el-step>
<el-step title="大赛信息填写"></el-step> <el-step title="比赛内容设置"></el-step>
<el-step title="赛程与规则设置"></el-step> <el-step title="发布"></el-step>
<el-step title="比赛内容设置"></el-step> </el-steps>
<el-step title="发布"></el-step> <h1>大赛已发布</h1>
</el-steps> <div class="btns">
<h1>大赛已发布</h1> <el-button type="primary" @click="back">确定</el-button>
<div class="btns"> </div>
<el-button type="primary"
@click="back">确定</el-button>
</div> </div>
</div> </div>
</div>
</template> </template>
<script> <script>
export default { export default {
data () { data() {
return { return {
}; };
}, },
mounted () { mounted() {
}, },
methods: { methods: {
back () { back() {
this.$router.push(this.$store.state.referrer || '/match') this.$router.push(`/match?page=${this.$store.state.matchPage}`)
}
} }
}
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.wrap { .wrap {
height: calc(100vh - 300px); height: calc(100vh - 300px);
background-color: #fefefe; background-color: #fefefe;
} }
.modal { .modal {
width: 500px; width: 500px;
padding-top: 150px; padding-top: 150px;
margin: 0 auto; margin: 0 auto ;
h1 { h1 {
margin: 20px; margin: 20px;
text-align: center; text-align: center;
} }
.btns { .btns {
text-align: center; text-align: center;
} }
} }
</style> </style>

@ -1,211 +0,0 @@
<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>

@ -1,5 +1,5 @@
<template> <template>
<div class="page" v-loading="loading"> <div class="page">
<h6 class="p-title">筛选</h6> <h6 class="p-title">筛选</h6>
<div class="tool mul"> <div class="tool mul">
<ul class="filter"> <ul class="filter">
@ -8,9 +8,12 @@
<div class="single-choice"> <div class="single-choice">
<dl> <dl>
<dd> <dd>
<el-radio-group v-model="form.month" @change="changeType"> <el-radio-group v-model="form.month"
<el-radio v-for="(item, index) in dateList" :key="index" :label="item.id" border>{{ item.name @change="changeType">
}}</el-radio> <el-radio v-for="(item,index) in dateList"
:key="index"
:label="item.id"
border>{{ item.name }}</el-radio>
</el-radio-group> </el-radio-group>
</dd> </dd>
</dl> </dl>
@ -18,150 +21,218 @@
</li> </li>
<li> <li>
<label>创建区间</label> <label>创建区间</label>
<el-date-picker v-model="date" align="right" unlink-panels type="daterange" start-placeholder="开始日期" <el-date-picker v-model="date"
end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" clearable></el-date-picker> align="right"
unlink-panels
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
clearable></el-date-picker>
</li> </li>
<li> <li>
<el-input placeholder="请输入竞赛名称/创建人" suffix-icon="el-icon-search" v-model="form.keyWord" clearable></el-input> <el-input placeholder="请输入竞赛名称/创建人"
suffix-icon="el-icon-search"
v-model="keyword"
clearable></el-input>
</li> </li>
</ul> </ul>
</div> </div>
<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="initData"> <el-select v-model="form.platformSource"
<el-option v-for="(item, i) in sourceList" :key="i" :label="item.name" :value="item.id"></el-option> clearable
@change="sourceChange">
<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.releaseType" clearable @change="initData"> <el-select v-model="form.competitionScope"
<el-option v-for="(item, i) in releaseTypes" :key="i" :label="item.name" :value="item.id"></el-option> clearable
</el-select> @change="initData">
</li> <el-option v-for="(item, i) in rangeList"
<li> :key="i"
<label>竞赛范围</label> :label="item.name"
<el-select v-model="form.competitionScope" @change="initData"> :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>
</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> </el-select>
</li> </li>
</ul> </ul>
<div> <div>
<el-button type="primary" round @click="add" v-auth>创建竞赛</el-button> <el-button type="primary"
<el-button type="primary" round @click="delAllSelection" v-auth>批量删除</el-button> round
@click="add"
v-auth>创建竞赛</el-button>
<el-button type="primary"
round
@click="delAllSelection"
v-auth>批量删除</el-button>
</div> </div>
</div> </div>
<el-table ref="table" :data="matchData" class="table" stripe header-align="center" <el-table ref="table"
@selection-change="handleSelectionChange" row-key="id"> :data="matchData"
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> class="table"
<el-table-column type="index" width="60" label="序号" align="center"> 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="competitionName" label="竞赛名称" align="center"></el-table-column> <el-table-column prop="competitionName"
<el-table-column prop="name" label="竞赛来源" width="90" align="center"> label="竞赛名称"
align="center"></el-table-column>
<el-table-column prop="founderName"
label="创建人"
align="center"></el-table-column>
<el-table-column prop="name"
label="大赛来源"
width="120"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ sourceList.find(e => e.id === scope.row.platformSource).name }} {{ sourceList.find(e => e.id === scope.row.platformSource).name }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="name" label="发布类型" width="110" align="center"> <el-table-column prop="name"
<template slot-scope="scope"> label="大赛范围"
{{ scope.row.releaseType ? '设置完整比赛' : '练习赛' }} align="center">
</template>
</el-table-column>
<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"> <el-table-column prop="applicantNum"
<template slot-scope="scope"> label="报名人数"
{{ scope.row.competitionType ? '团队赛' : '个人赛' }} align="center"
</template> width="100"></el-table-column>
</el-table-column> <el-table-column prop="status"
<el-table-column prop="applicantNum" label="报名人数" align="center" width="100"></el-table-column> label="状态"
<el-table-column prop="status" label="状态" align="center" width="80"> 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"
<el-table-column prop="founderName" label="创建人" width="130" align="center"></el-table-column> label="创建时间"
<el-table-column label="操作" align="center" width="280"> align="center"
width="160"></el-table-column>
<el-table-column label="操作"
align="center"
width="260">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click="copy(scope.row)">复制</el-button> <el-button v-if="scope.row.playingStages && scope.row.playingStages.length"
<el-button v-if="scope.row.publishStatus && scope.row.playingStages && scope.row.playingStages.length" type="text"
type="text" @click="editEndTime(scope.row)" v-auth>修改结束时间</el-button> @click="editEndTime(scope.row)"
<el-button type="text" @click="manage(scope.row)" v-auth>管理</el-button> v-auth>修改结束时间</el-button>
<el-button type="text" @click="delData(scope.row)" v-auth>删除</el-button> <el-button type="text"
<el-switch v-if="scope.row.publishStatus" v-auth="'/match:启用'" v-model="scope.row.ztOpen" :active-value="0" @click="manage(scope.row)"
:inactive-value="1" style="margin: 0 10px 0 5px" :active-text="scope.row.ztOpen ? '关' : '开'" v-auth>管理</el-button>
@change="switchOff($event, scope.row, scope.$index)"></el-switch> <el-button type="text"
@click="delData(scope.row)"
v-auth>删除</el-button>
<el-switch v-if="scope.row.publishStatus"
v-auth="'/match:启用'"
v-model="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>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" <el-pagination background
:current-page="page"> layout="total, prev, pager, next"
:total="total"
@current-change="handleCurrentChange"
:current-page="page">
</el-pagination> </el-pagination>
</div> </div>
<el-dialog title="修改当前阶段结束时间" :visible.sync="modifyVisible" width="900px" :close-on-click-modal="false"> <el-dialog title="修改当前阶段结束时间"
<el-table :data="curRow.playingStages" class="table" ref="table" stripe header-align="center"> :visible.sync="modifyVisible"
<el-table-column prop="stageName" label="阶段名称" min-width="100" align="center"></el-table-column> width="900px"
<el-table-column label="竞赛起止时间" width="300" align="center"> :close-on-click-modal="false">
<el-table :data="curRow.playingStages"
class="table"
ref="table"
stripe
header-align="center">
<el-table-column prop="stageName"
label="阶段名称"
min-width="100"
align="center"></el-table-column>
<el-table-column label="竞赛起止时间"
width="300"
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="结束时间调整为" align="center" width="280"> <el-table-column label="结束时间调整为"
align="center"
width="280">
<template slot-scope="scope"> <template slot-scope="scope">
<el-date-picker popper-class="no-atTheMoment" v-model="scope.row.newEndTime" placeholder="请选择结束时间" <el-date-picker popper-class="no-atTheMoment"
type="datetime" :picker-options="pickerOptions"> v-model="scope.row.newEndTime"
placeholder="请选择结束时间"
type="datetime"
:picker-options="pickerOptions">
</el-date-picker> </el-date-picker>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<span slot="footer" class="dialog-footer"> <span slot="footer"
<el-button size="small" @click="modifyVisible = false"> </el-button> class="dialog-footer">
<el-button size="small" type="primary" @click="modifySubmit"> </el-button> <el-button size="small"
@click="modifyVisible = false"> </el-button>
<el-button size="small"
type="primary"
@click="modifySubmit"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script> <script>
import Util from '@/libs/util' import util from "@/libs/util";
import Setting from "@/setting";
import { Loading } from 'element-ui'
import Bus from '@/libs/bus' import Bus from '@/libs/bus'
import qs from 'qs'
export default { export default {
name: "match", name: "match",
data () { data () {
return { return {
timer: null, timer: null,
keyword: "",
sourceList: [ sourceList: [
{ {
id: null, id: "",
name: "不限" name: "不限"
}, },
{ {
@ -173,23 +244,9 @@ export default {
name: "院校创建" name: "院校创建"
} }
], ],
releaseTypes: [
{
id: '',
name: "不限"
},
{
id: 0,
name: '发布信息'
},
{
id: 1,
name: '完整比赛'
}
],
rangeList: [ rangeList: [
{ {
id: null, id: "",
name: "不限" name: "不限"
}, },
{ {
@ -205,45 +262,14 @@ 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: null, month: "",
month: '', publishStatus: "",
startTime: null, startTime: "",
endTime: null, endTime: "",
releaseType: '', platformSource: +this.$route.query.platformSource || 0, // (01)
publishStatus: '', competitionScope: '', // (0: 1: 2.)
competitionType: '',
platformSource: 0, // (01)
competitionScope: null, // (0: 1: 2.)
}, },
multipleSelection: [], multipleSelection: [],
dateList: [ dateList: [
@ -281,16 +307,14 @@ export default {
picker.$emit('pick', new Date(Date.now() + 5000)) picker.$emit('pick', new Date(Date.now() + 5000))
} }
}] }]
}, }
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 = [];
} }
@ -300,12 +324,12 @@ export default {
this.form.startTime = val[0]; this.form.startTime = val[0];
this.form.endTime = val[1]; this.form.endTime = val[1];
} else { } else {
this.form.startTime = '' this.form.startTime = "";
this.form.endTime = '' this.form.endTime = "";
} }
this.initData(); this.initData();
}, },
'form.keyWord': function (val) { keyword: function (val) {
clearTimeout(this.searchTimer); clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => { this.searchTimer = setTimeout(() => {
this.initData(); this.initData();
@ -313,23 +337,6 @@ export default {
} }
}, },
mounted () { mounted () {
const { query } = this.$route
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(() => { })
}
// websocket // websocket
Bus.$on('matchSocket', () => { Bus.$on('matchSocket', () => {
this.getData() this.getData()
@ -341,80 +348,64 @@ export default {
}) })
}, },
methods: { methods: {
async getData () { getData () {
this.loading = true const { form } = this
try { this.$post(this.api.CompetitionPageConditionQueryByNakadai, {
const { form } = this pageNum: this.page,
const { data } = await this.$post(this.api.CompetitionPageConditionQueryByNakadai, { pageSize: this.pageSize,
pageNum: this.page, competitionScope: form.competitionScope === '' ? null : form.competitionScope,
pageSize: this.pageSize, endTime: form.endTime || null,
...form keyWord: this.keyword || null,
}) platformSource: form.platformSource === '' ? null : form.platformSource,
this.matchData = data.records startTime: form.startTime || null,
}).then(({ data }) => {
this.now = await Util.getNow() // load.close()
clearInterval(this.timer) const list = data.records
this.handleBeganStage() //
this.timer = setInterval(() => { this.timer = setInterval(() => {
this.now = new Date(this.now.setSeconds(this.now.getSeconds() + 1)) const now = new Date()
this.handleBeganStage() list.map(e => {
if (!e.playingStages) {
this.$set(e, 'playingStages', [])
} else {
e.playingStages = []
}
//
if (now >= new Date(e.playStartTime) && now <= new Date(e.playEndTime)) {
//
if (e.competitionStageList) {
for (const n of e.competitionStageList) {
//
if (now >= new Date(n.startTime) && now <= new Date(n.endTime)) {
e.playingStages.push(n)
}
}
}
}
})
}, 1000) }, 1000)
this.matchData = list
this.total = data.total this.total = data.total
this.$refs.table.clearSelection() this.$refs.table.clearSelection()
this.loading = false
if (!this.matchData.length && this.total) { if (!this.matchData.length && this.total) {
this.page-- this.page--
this.getData() this.getData()
} }
} catch (e) { }).catch(res => { })
this.loading = false
}
},
//
async handleBeganStage () {
this.matchData.map(e => {
if (!e.playingStages) {
this.$set(e, 'playingStages', [])
} else {
e.playingStages = []
}
//
if (this.now >= new Date(e.playStartTime) && this.now <= new Date(e.playEndTime)) {
//
if (e.competitionStageList) {
for (const n of e.competitionStageList) {
//
if (this.now >= new Date(n.startTime) && this.now <= new Date(n.endTime)) {
e.playingStages.push(n)
}
}
}
}
})
}, },
initData () { initData () {
this.page = 1; this.page = 1;
this.getData(); this.getData();
}, },
// url // redis
setReferrer () { getRedis () {
this.$store.commit('setReferrer', `${this.$route.path}?${qs.stringify(this.form)}&page=${this.page}`) this.$post(this.api.getRedisCacheCompetition).then(({ data }) => {
data && this.getList()
}).catch(res => { })
}, },
add () { add () {
this.setReferrer()
this.$router.push("/addMatch"); this.$router.push("/addMatch");
}, },
//
copy (row) {
this.$confirm('确定要复制吗', "提示", {
type: "warning"
}).then(async () => {
await this.$post(`${this.api.copyCompetition}?competitionId=${row.id}`)
Util.successMsg('复制成功')
this.initData()
}).catch(() => { })
},
// //
editEndTime (row) { editEndTime (row) {
this.modifyVisible = true this.modifyVisible = true
@ -432,16 +423,14 @@ export default {
}) })
this.$post(this.api.editCompetitionContent, { this.$post(this.api.editCompetitionContent, {
competitionContents: data competitionContents: data
}).then(async res => { }).then(res => {
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 => { })
}, },
// //
manage (row) { manage (row) {
this.setReferrer()
this.$router.push(`/matchManage?id=${row.id}&name=${row.competitionName}`) this.$router.push(`/matchManage?id=${row.id}&name=${row.competitionName}`)
}, },
@ -451,6 +440,14 @@ export default {
}, },
// //
sourceChange (val) { sourceChange (val) {
this.$router.push({
path: '/match',
query: {
...this.$route.query,
platformSource: val
}
})
this.$store.commit('SET_M_SOURCE', val)
this.initData() this.initData()
}, },
delData (row) { delData (row) {
@ -459,7 +456,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 => {
}); });
@ -493,6 +490,7 @@ export default {
this.page = val; this.page = val;
this.$router.push(`match?page=${val}`) this.$router.push(`match?page=${val}`)
this.getData(); this.getData();
this.$store.commit('SET_M_PAGE', val)
}, },
transferTime (date, type) { transferTime (date, type) {
if (date == "0000-00-00 00:00:00") return "---"; if (date == "0000-00-00 00:00:00") return "---";
@ -504,7 +502,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`)
@ -515,22 +513,22 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
/deep/ .tool { /deep/ .tool {
.filter { .filter {
.el-input { .el-input {
min-width: 190px; min-width: 190px;
}
} }
}
} }
@media (max-width: 1640px) { @media (max-width: 1640px) {
.page .page-content .tool .filter { .page .page-content .tool .filter {
flex-wrap: wrap; flex-wrap: wrap;
margin-bottom: -15px; margin-bottom: -15px;
li { li {
min-width: 34%; min-width: 34%;
margin-bottom: 15px; margin-bottom: 15px;
}
} }
}
} }
</style> </style>

@ -1,630 +0,0 @@
<template>
<!-- 报名人员 -->
<div class="page-content" style="padding: 24px">
<div class="tool">
<ul class="filter">
<li>
<label>搜索</label>
<el-input
:placeholder="'请输入姓名、手机号、' + (info.completeCompetitionSetup.competitionType ? '团队名称、' : '') + '学号、学校'"
prefix-icon="el-icon-search" v-model="keyword" clearable size="mini" style="width: 350px"></el-input>
</li>
<li v-if="info.releaseType">
<label>参赛人员状态</label>
<el-select v-model="isDisable" @change="initData">
<el-option v-for="(item, i) in statusList" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
</ul>
<div>
<el-button type="primary" round :loading="exporting" @click="exportAll"
v-auth="'/match:管理:报名人员:导出'">批量导出</el-button>
<el-button type="primary" @click="batchDel" round v-auth="'/match:管理:报名人员:导出'">批量删除</el-button>
</div>
</div>
<el-table ref="table" :data="listData" class="table" stripe header-align="center"
@selection-change="handleSelectionChange" row-key="id" v-loading="loading" @sort-change="sortChange">
<el-table-column type="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center">
<template slot-scope="scope">
{{ scope.$index + (page - 1) * pageSize + 1 }}
</template>
</el-table-column>
<el-table-column prop="school" label="学生账号归属" sortable="custom" min-width="180" align="center"></el-table-column>
<el-table-column prop="realSchool" label="学生所在院校" min-width="180" align="center"></el-table-column>
<el-table-column v-if="info.completeCompetitionSetup.competitionType" prop="teamName" label="团队名称"
sortable="custom" min-width="140" align="center">
</el-table-column>
<el-table-column prop="username" label="队长" min-width="140" align="center">
</el-table-column>
<el-table-column prop="workNumber" label="队长学号" min-width="140" align="center">
</el-table-column>
<el-table-column prop="phone" label="队长手机号" min-width="140" align="center">
</el-table-column>
<el-table-column prop="captain" label="是否为队长" min-width="90" align="center"></el-table-column>
<el-table-column prop="teachers" label="指导老师" min-width="200" align="center" show-overflow-tooltip>
<template slot-scope="scope">
<template v-if="scope.row.teachers">
<el-tooltip placement="top">
<div slot="content" style="line-height: 1.8">
<div v-for="(item, i) in scope.row.teachers" :key="i">
{{ item.name }}{{ item.phone ? ',' + item.phone : '' }}{{ item.position ? ',' + item.position : '' }}
</div>
</div>
<p>{{ scope.row.teachers[0].name }}{{ scope.row.teachers[0].phone ? ',' + scope.row.teachers[0].phone : ''
}}{{ scope.row.teachers[0].position ? ',' + scope.row.teachers[0].position : '' }}</p>
</el-tooltip>
</template>
</template>
</el-table-column>
<el-table-column prop="captain" label="团队状态" min-width="80" align="center">
<template slot-scope="scope">
<el-link type="danger" style="font-size: 16px" @click="toInfo(scope.row)">异常</el-link>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="270">
<template slot-scope="scope">
<el-button v-auth="'/match:管理:报名人员:编辑'" type="text" @click="edit(scope.row)">编辑</el-button>
<el-button type="text" @click="del(scope.row)">删除</el-button>
<template v-if="info.releaseType">
<el-button v-auth="'/match:管理:报名人员:参赛信息与成绩'" type="text" @click="toInfo(scope.row)">参赛信息与成绩</el-button>
<el-switch v-auth="'/match:管理:报名人员:禁用'" v-model="scope.row.isDisable"
: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>
</template>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange"
:current-page="page">
</el-pagination>
</div>
<el-dialog :title="(!isAdd ? '编辑' : '新增') + '参赛人员'" :visible.sync="addVisible" width="440px" class="dialog"
:close-on-click-modal="false" @close="closeAdd">
<el-form ref="form" :model="form" :rules="rules" label-width="110px" style='margin-right: 10px;'>
<el-form-item v-if="!schoolDisable" prop="schoolId" label="学生账号归属">
<el-select v-model="form.schoolId" filterable :disabled="!isAdd" @change="schoolChange" style="width: 100%">
<el-option v-for="(item, i) in clients" :key="i" :label="item.schoolName"
:value="item.schoolId"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="studentAffiliatedInstitutionId" label="学生所在院校">
<el-select v-model="form.studentAffiliatedInstitutionId" filterable style="width: 100%">
<el-option v-for="(item, i) in schools" :key="i" :label="item.schoolName"
:value="item.schoolId"></el-option>
</el-select>
<p style="margin-top: 10px;line-height: 1.4;font-size: 12px;">学生所属院校为学生实际院校</p>
</el-form-item>
<el-form-item prop="workNumber" label="学生学号">
<el-input v-model="form.workNumber" placeholder="请输入学生学号" @change="workNumberChange"></el-input>
</el-form-item>
<el-form-item prop="userName" label="学生姓名">
<el-input v-model="form.userName" placeholder="请输入学生姓名" :disabled="isAdd"></el-input>
</el-form-item>
<el-form-item label="账号角色">
学生
</el-form-item>
<el-form-item v-if="info.completeCompetitionSetup.competitionType" prop="teamId" label="所属团队">
<div style="display: flex;align-items: center">
<el-select v-model="form.teamId" :disabled="formEnable && isAdd" filterable
style="width: 240px;margin-right: 10px">
<el-option v-for="(item, i) in teams" :key="i" :label="item.teamName" :value="item.teamId"></el-option>
</el-select>
<el-button v-if="isAdd && !formEnable" type="text" @click="createTeam">创建团队</el-button>
</div>
</el-form-item>
<el-form-item prop="phone" label="手机号">
<el-input v-model="form.phone" maxlength="11" placeholder="请输入手机号" :disabled="isAdd"></el-input>
</el-form-item>
<el-form-item prop="email" label="邮箱">
<el-input v-model="form.email" placeholder="请输入邮箱" :disabled="isAdd"></el-input>
</el-form-item>
</el-form>
<p v-if="!isAdd" class="tips" style="margin-left: 13px">当前页面信息修改会同步修改掉学生账号信息</p>
<span slot="footer" class="dialog-footer">
<el-button @click="addVisible = false">取消</el-button>
<el-button type="primary" @click="submit">确定</el-button>
</span>
</el-dialog>
<el-dialog title="创建团队" :visible.sync="teamVisible" :close-on-click-modal="false" width="300px">
<el-form class="dia-form">
<el-form-item>
<el-input placeholder="请输入团队名称" maxlength="10" v-model="teamForm.teamName"></el-input>
</el-form-item>
<el-form-item>
<el-input placeholder="请设置团队邀请码" maxlength="6" v-model="teamForm.invitationCode"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button size="small" type="primary" @click="teamSubmit">确定并使用</el-button>
<el-button size="small" @click="teamVisible = false">取消</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import util from "@/libs/util";
import axios from 'axios'
import Setting from "@/setting";
export default {
data () {
return {
token: sessionStorage.getItem('token'),
id: +this.$route.query.id,
info: {
completeCompetitionSetup: {
competitionType: 1,
}
},
isDisable: this.$route.query.isDisable ? +this.$route.query.isDisable : '',
statusList: [
{
id: '',
name: '不限'
},
{
id: 1,
name: '已禁用'
},
{
id: 0,
name: '未禁用'
}
],
keyword: this.$route.query.keyword || '',
listData: [],
multipleSelection: [],
page: +this.$route.query.page || 1,
pageSize: 10,
total: 0,
schoolOrder: '',
teamOrder: '',
clients: [],
schools: [],
addVisible: false,
formEnable: true,
isAdd: false,
form: {
captain: 0,
competitionId: this.$route.query.id,
userName: '',
workNumber: '',
schoolId: '',
studentAffiliatedInstitutionId: '',
teamId: '',
whetherSignUp: 0,
phone: '',
email: '',
identification: 1,
uniqueIdentification: Date.now(),
password: Setting.initialPassword
},
rules: {
schoolId: [
{ required: true, message: "请选择所属院校", trigger: "change" }
],
workNumber: [
{ required: true, message: "请输入学号", trigger: "blur" }
],
teamId: [
{ required: true, message: "请选择所属团队", trigger: "change" }
]
},
submiting: false,
teamVisible: false,
teams: [],
teamNameRepeat: false,
teamForm: {
competitionId: this.$route.query.id,
registrationInvitationCode: '',
teamName: '',
invitationCode: '',
whetherSignUp: 1,
identification: 1
},
originForm: {},
exitMember: 0,
notExit: 0,
schoolDisable: false,
importVisible: false,
uploadList: [],
uploadFaild: false,
uploadTips: '',
exportCode: '',
headers: {
token: sessionStorage.getItem("token")
},
uploading: false,
isBackstage: 0,
exporting: false,
loading: false,
};
},
watch: {
keyword: function (val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.initData();
}, 500);
}
},
mounted () {
this.getData()
this.getInfo()
this.getTeam()
},
methods: {
init () {
this.initData()
this.getTeam()
this.getClient()
},
async getData () {
this.loading = true
const { data } = await this.$post(this.api.queryAbnormalTeam, {
pageNum: this.page,
pageSize: this.pageSize,
competitionId: this.id,
keyWord: this.keyword,
isDisable: this.isDisable,
schoolOrder: this.schoolOrder,
teamOrder: this.teamOrder,
})
const list = data.records;
list.map(e => {
if (e.teacherDetails) {
e.teachers = JSON.parse(e.teacherDetails)
}
})
this.listData = list
this.total = data.total;
this.$refs.table.clearSelection();
this.loading = false
},
//
getInfo () {
this.$post(`${this.api.getCompetition}?competitionId=${this.id}`).then(({ competition }) => {
this.info = competition
this.getSchool()
//
if (competition.competitionScope) {
this.getClient()
} else {
this.schoolDisable = true
this.form.schoolId = competition.schoolId
}
}).catch(err => { })
},
initData () {
this.page = 1
this.getData()
},
handleSelectionChange (val) {
this.multipleSelection = val;
},
handleCurrentChange (val) {
this.page = val;
this.getData();
},
switchOff (val, row, index) {
this.$put(`${this.api.disableRegistration}?competitionRegistrationId=${row.id}&isDisable=${val}`).then(res => { }).catch(err => { });
},
//
sortChange (column) {
// 12
if (column.prop === 'school') this.schoolOrder = column.order ? column.order === 'ascending' ? 2 : 1 : ''
if (column.prop === 'teamName') this.teamOrder = column.order ? column.order === 'ascending' ? 2 : 1 : ''
this.getData()
},
//
edit (row) {
this.notExit = 0
this.isAdd = false
this.addVisible = true
row.userName = row.username
this.exitMember = 0
row.id = row.accountId
this.originForm = JSON.parse(JSON.stringify(row))
this.form = JSON.parse(JSON.stringify(row))
},
del (row) {
this.$confirm(!this.info.completeCompetitionSetup.competitionType || row.captain === '否' ? '删除后该参赛人员已有的成绩会一并删除,成绩排名将会受影响,是否确定要删除?' : '删除队长后,该团队下所有成员都会同步移除报名,已有的成绩也会一并删除,成绩排名将会受影响,是否确认删除?', "提示", {
type: "warning"
}).then(() => {
this.$post(this.api.batchDeleteApplicants, { registrationVOS: [row] }).then(res => {
util.successMsg("删除成功");
this.init()
}).catch(res => { });
}).catch(() => { });
},
//
schoolChange () {
if (!this.form.studentAffiliatedInstitutionId) this.form.studentAffiliatedInstitutionId = this.form.schoolId
},
//
workNumberChange () {
const { form } = this
if (this.originForm.workNumber !== form.workNumber) {
form.schoolId && form.workNumber && this.$get(`${this.api.enquireAboutSchoolStudents}?schoolId=${form.schoolId}&workNumber=${form.workNumber}${this.isAdd ? '' : '&applyFor=1'}`).then(({ account }) => {
this.notExit = 0
this.exitMember = 0
if (account) {
const { studentAffiliatedInstitutionId } = form
account.studentAffiliatedInstitutionId = studentAffiliatedInstitutionId
this.form = account
}
this.formEnable = !account
}).catch(res => {
if (res.message === '学生不存在') this.notExit = 1
if (!this.isAdd) this.exitMember = 1
})
} else {
this.exitMember = 0
}
},
//
submitForm () {
const { form } = this
if (!this.isAdd) { //
this.$post(this.api.updateUser, {
hrUserAccount: {
...form,
id: form.id,
lastTimeInstitutionId: this.originForm.studentAffiliatedInstitutionId
},
hrUserInfo: {
userId: form.userId,
schoolId: form.schoolId,
email: form.email,
userName: form.userName
}
}).then(res => {
//
if (this.originForm.teamId !== form.teamId) {
this.$post(this.api.joinCompetitionTeam, {
schoolId: form.schoolId,
studentAffiliatedInstitutionId: form.studentAffiliatedInstitutionId,
accountId: form.id,
competitionId: this.id,
teamId: form.teamId,
identification: 1,
whetherSignUp: 1
}).then(res => {
this.addVisible = false
this.init()
this.submiting = false
util.successMsg('编辑成功!')
}).catch(res => {
this.submiting = false
})
} else {
this.addVisible = false
this.init()
this.submiting = false
util.successMsg('编辑成功!')
}
}).catch(res => {
this.submiting = false
})
} else {
//
this.$post(this.api[this.info.completeCompetitionSetup.competitionType ? 'joinCompetitionTeam' : 'addCompetitionRegistration'], {
schoolId: form.schoolId,
studentAffiliatedInstitutionId: form.studentAffiliatedInstitutionId,
accountId: form.id,
competitionId: this.id,
teamId: this.form.teamId,
identification: 1,
whetherSignUp: 1
}).then(res => {
this.addVisible = false
this.init()
this.submiting = false
util.successMsg('报名成功!')
}).catch(res => {
this.submiting = false
})
}
},
//
submit () {
this.$refs.form.validate((valid) => {
if (valid) {
if (this.submiting) return false
const { form } = this
const team = this.teams.find(e => e.teamId == form.teamId)
if (team && team.invitationCode) form.invitationCode = team.invitationCode
// id-id-schoolId-workNumber
form.account = `${Setting.platformId}-3-${form.schoolId}-${form.workNumber}`
const { phone, email } = form
if (phone && !/^1[3456789]\d{9}$/.test(phone)) {
return util.errorMsg("请输入正确的手机号")
} else if (email && !/^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/.test(email)) {
return util.errorMsg("请输入正确的邮箱")
} else if (this.notExit) {
return util.errorMsg('学生不存在,无法添加!')
} else if (this.exitMember) {
return util.errorMsg('学生已存在')
} else {
this.submiting = true
this.submitForm()
}
}
})
},
//
closeAdd () {
this.form = {
captain: 0,
competitionId: this.id,
userName: '',
workNumber: '',
schoolId: '',
teamId: '',
whetherSignUp: 0,
phone: '',
email: '',
identification: 1,
uniqueIdentification: Date.now(),
password: Setting.initialPassword
}
},
//
createTeam () {
this.teamForm = {
competitionId: this.id,
registrationInvitationCode: '',
teamName: '',
invitationCode: '',
whetherSignUp: 1,
identification: 1
}
this.teamVisible = true
},
//
async getSchool () {
const { list } = await this.$get(this.api.querySchoolData)
this.schools = list
},
//
async getClient () {
if (this.info.competitionScope === 2) {
//
this.$get(`${this.api.schoolsInCompetitionArea}?competitionId=${this.id}`).then(({ schools }) => {
this.clients = schools
}).catch(res => { })
} else {
//
const sid = this.$store.state.dataPer.find(e => e.permissionName === '客户管理')
this.$post(this.api.queryCustomer, {
customerType: '',
page: 1,
size: 10000,
supplierId: (sid && !sid.all) ? sid.supplierId : ''
}).then(res => {
const { list } = res.message
list.map(e => {
e.schoolName = e.customerName
})
this.clients = list
}).catch(res => { })
}
},
//
getTeam () {
this.$get(this.api.searchTeam, {
teamName: '',
competitionId: this.id
}).then(({ teamList }) => {
this.teams = teamList
}).catch(res => { })
},
//
teamSubmit () {
const form = this.teamForm
if (!form.teamName) return util.errorMsg('请输入团队名称')
if (form.invitationCode.length !== 6) return util.errorMsg('请输入6位数团队邀请码')
form.accountId = this.form.id
form.schoolId = this.form.schoolId
form.studentAffiliatedInstitutionId = this.form.studentAffiliatedInstitutionId
this.$post(this.api.addCompetitionTeam, form).then(res => {
this.teamVisible = false
this.addVisible = false
this.init()
util.successMsg('报名成功!')
}).catch(res => { })
},
//
toInfo (row) {
this.$store.commit('setInnerReferrer', `${this.$route.path}?id=${this.id}&tab=tab6&name=${this.$route.query.name}&keyword=${this.keyword}&page=${this.page}&isDisable=${this.isDisable}`)
this.$router.push(`/matchInfo?id=${this.id}&accountId=${row.accountId}`)
},
exportAll () {
if (this.listData.length) {
this.exporting = true
const data = this.multipleSelection
if (data.length) {
data.map((e, i) => e.id = i + 1)
axios.post(this.api.exportDataInBatches, data, {
headers: {
token: this.token
},
responseType: 'blob'
}).then((res) => {
const name = res.headers['content-disposition']
util.downloadFileDirect(name ? decodeURI(name) : '报名人员.xlsx', new Blob([res.data]))
this.exporting = false
}).catch(res => {
this.exporting = false
})
} else {
axios.get(`${this.api.exportAbnormalData}?competitionId=${this.id}`, {
headers: {
token: this.token
},
responseType: 'blob'
}).then((res) => {
const name = res.headers['content-disposition']
util.downloadFileDirect(name ? decodeURI(name) : '报名人员.xlsx', new Blob([res.data]))
this.exporting = false
}).catch(res => {
this.exporting = false
})
}
}
},
//
async batchDel () {
const list = this.multipleSelection
const tips = list.length ? (this.info.completeCompetitionSetup.competitionType && list.find(e => e.captain === '是') ? '删除队长后,该团队下所有成员都会同步移除报名,已有的成绩也会一并删除,成绩排名将会受影响,是否确认删除?' : '删除后该参赛人员已有的成绩会一并删除,成绩排名将会受影响,是否确定要删除?') : '删除后参赛人员已有的成绩会一并删除,成绩排名将会受影响,<span style="font-size: 15px;color: #f00">是否确定删除全部报名人员?</span>'
this.$confirm(tips, "提示", {
type: "warning",
dangerouslyUseHTMLString: true
}).then(async () => {
if (list.length) {
await this.$post(this.api.batchDeleteApplicants, { registrationVOS: list })
} else {
await this.$post(`${this.api.deleteAllData}?competitionId=${this.id}`)
}
this.init()
this.$message.success("删除成功");
this.$refs.table.clearSelection()
}).catch(() => { });
},
}
};
</script>
<style lang="scss" scoped>
/deep/.dia-form {
.w-100 {
width: 100%;
}
.tips {
display: flex;
justify-content: center;
align-items: center;
}
}
.tips {
font-size: 12px;
color: #e90000;
}
/deep/.import-file {
.el-progress__text,
.el-progress,
.el-upload-list__item-status-label {
display: none !important;
}
}
</style>

@ -1,24 +1,22 @@
<template> <template>
<!-- 赛事管理 --> <!-- 赛事管理 -->
<div> <div>
<el-card shadow="hover" class="m-b-20"> <el-card shadow="hover" class="m-b-20">
<div class="flex-between"> <div class="flex-between">
<el-page-header @back="back" :content="name + '/管理'"></el-page-header> <el-page-header @back="back" :content="name + '/管理'"></el-page-header>
</div> </div>
</el-card> </el-card>
<div class="page" style="margin-bottom: 24px"> <div class="page" style="margin-bottom: 24px">
<div class="tabs"> <div class="tabs">
<a class="item" v-for="(item, index) in tabs" :key="index" :class="{ active: index == active }" <a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{ item }}</a>
@click="tabChange(index)">{{ item }}</a> </div>
</div> <MatchDetail v-if="active == 'tab1'" ref="detail" />
<MatchDetail v-if="active == 'tab1'" ref="detail" /> <MatchArch v-if="active == 'tab2'" />
<MatchArch v-if="active == 'tab2'" /> <MatchProgress v-else-if="active == 'tab3'" />
<MatchProgress v-else-if="active == 'tab3'" /> <notice v-else-if="active == 'tab4'" />
<Notice v-else-if="active == 'tab4'" /> <MatchSignup v-else-if="active == 'tab5'" />
<MatchSignup v-else-if="active == 'tab5'" /> </div>
<AbnormalTeam v-else-if="active == 'tab6'" />
</div> </div>
</div>
</template> </template>
@ -27,116 +25,103 @@ import Setting from "@/setting";
import MatchDetail from "../add"; import MatchDetail from "../add";
import MatchArch from "./matchArch"; import MatchArch from "./matchArch";
import MatchProgress from "./matchProgress"; import MatchProgress from "./matchProgress";
import Notice from "./notice"; import notice from "./notice";
import MatchSignup from './matchSignup' import MatchSignup from "./matchSignup";
import AbnormalTeam from './abnormalTeam'
export default { export default {
name: "matchManage", name: "matchManage",
data () { data() {
return { return {
name: this.$route.query.name, name: this.$route.query.name,
active: this.$route.query.tab || '', active: this.$route.query.tab || "tab1",
tabs: { tabs: {
tab1: "大赛详情", tab1: "大赛详情",
tab2: "大赛成绩管理", tab2: "大赛成绩管理",
tab3: "竞赛进展", tab3: "竞赛进展",
tab4: "公告通知", tab4: "公告通知",
tab5: "报名人员", tab5: "报名人员"
} }
}; };
},
components: {
MatchDetail,
MatchArch,
MatchProgress,
Notice,
MatchSignup,
AbnormalTeam
},
mounted () {
// if (Setting.dynamicRoute) {
this.initTabs()
// } else {
// this.active = this.$route.query.tab || 'tab1'
// }
},
methods: {
async initTabs () {
const btns = this.$store.state.btns
const tab1 = btns.includes('/match:管理:大赛详情')
const tab2 = btns.includes('/match:管理:大赛成绩管理')
const tab3 = btns.includes('/match:管理:竞赛进展')
const tab4 = btns.includes('/match:管理:公告通知')
const tab5 = btns.includes('/match:管理:报名人员')
const res = await this.$post(`${this.api.getCompetition}?competitionId=${this.$route.query.id}`)
tab1 || this.$delete(this.tabs, 'tab1')
if (!tab2 || !res.competition.releaseType) this.$delete(this.tabs, 'tab2')
tab3 || this.$delete(this.tabs, 'tab3')
tab4 || this.$delete(this.tabs, 'tab4')
tab5 || this.$delete(this.tabs, 'tab5')
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 keys = Object.keys(this.tabs)
if (keys.length) this.active = keys.includes(type) ? type : keys[0]
}, },
back () { components: {
this.handleSave(0) && this.backPage() MatchDetail,
MatchArch,
MatchProgress,
notice,
MatchSignup
}, },
// confirm mounted() {
handleSave (i) { Setting.dynamicRoute && this.initTabs()
// },
if (this.active === 'tab1') { methods: {
const { detail } = this.$refs initTabs() {
if (detail) { const btns = this.$store.state.btns
const step = detail.$refs['step' + detail.step] const tab1 = btns.includes('/match:管理:大赛详情')
if (detail.step < 4 && step && step.updateTime) { const tab2 = btns.includes('/match:管理:大赛成绩管理')
this.$confirm(`编辑的内容未保存,是否保存并且发布?`, '提示', { const tab3 = btns.includes('/match:管理:竞赛进展')
type: 'warning', const tab4 = btns.includes('/match:管理:公告通知')
closeOnClickModal: false const tab5 = btns.includes('/match:管理:报名人员')
}).then(() => {
detail.save(1, 1) tab1 || this.$delete(this.tabs, 'tab1')
this.backOrTab(i) tab2 || this.$delete(this.tabs, 'tab2')
}).catch(() => { tab3 || this.$delete(this.tabs, 'tab3')
tab4 || this.$delete(this.tabs, 'tab4')
tab5 || this.$delete(this.tabs, 'tab5')
const type = this.$route.query.tab
const keys = Object.keys(this.tabs)
this.active = keys.includes(type) ? type : keys[0]
},
back() {
this.handleSave(0) && this.backPage()
},
// confirm
handleSave(i) {
//
if (this.active === 'tab1') {
const { detail } = this.$refs
if (detail) {
const step = detail.$refs['step' + detail.step]
if (detail.step < 4 && step && step.updateTime) {
this.$confirm(`编辑的内容未保存,是否保存并且发布?`, '提示', {
type: 'warning'
}).then(() => {
detail.save(1, 1)
this.backOrTab(i)
}).catch(() => {
this.backOrTab(i)
})
} else {
this.backOrTab(i)
}
} else {
this.backOrTab(i) this.backOrTab(i)
}) }
return false
} else { } else {
this.backOrTab(i) return true
} }
} else { },
this.backOrTab(i) //
backPage(){
this.$router.push(`/match?page=${this.$store.state.matchPage}&platformSource=${this.$store.state.platformSource}`)
},
// tab
tabSwitch(i) {
this.active = i
this.$router.push(`/matchManage?id=${this.$route.query.id}&tab=${i}&name=${this.name}`)
},
// tab
backOrTab(i) {
i ? this.tabSwitch(i) : this.backPage()
},
// tab
tabChange(i) {
this.handleSave(i) && this.tabSwitch(i)
} }
return false
} else {
return true
}
},
//
backPage () {
this.$router.push(this.$store.state.referrer || '/match')
},
// tab
tabSwitch (i) {
this.active = i
this.$router.push(`/matchManage?id=${this.$route.query.id}&tab=${i}&name=${this.name}`).catch(e => { })
},
// tab
backOrTab (i) {
i ? this.tabSwitch(i) : this.backPage()
},
// tab
tabChange (i) {
this.handleSave(i) && this.tabSwitch(i)
} }
}
}; };
</script> </script>
<style scoped></style> <style scoped>
</style>

@ -1,57 +1,58 @@
<template> <template>
<!-- 报名人员 --> <!-- 报名人员 -->
<div class="page-content" style="padding: 24px"> <div class="page-content"
<el-table ref="table" :data="list" class="table" stripe header-align="center" row-key="stageId"> style="padding: 24px">
<el-table-column type="index" width="60" label="序号" align="center"> <el-table ref="table"
: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" label="阶段名称" align="center"></el-table-column> <el-table-column prop="methodName"
<el-table-column prop="competitionContent" label="比赛内容" align="center"></el-table-column> label="比赛方式"
<el-table-column prop="methodName" label="比赛方式" align="center"></el-table-column> align="center"></el-table-column>
<el-table-column label="竞赛类型" align="center"> <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" label="赛制" align="center"></el-table-column> <el-table-column prop="ruleName"
<el-table-column prop="status" label="大赛状态" align="center"></el-table-column> label="赛制"
<el-table-column prop="reviewStatus" label="评阅情况" align="center"></el-table-column> align="center"></el-table-column>
<el-table-column label="竞赛时间" width="290" align="center"> <el-table-column prop="status"
label="状态"
align="center"></el-table-column>
<el-table-column label="竞赛起止时间"
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="操作" align="center" width="280"> <el-table-column label="操作"
align="center"
width="260">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click="toRank(scope.row, scope.$index)">排名</el-button> <el-button type="primary"
<el-button type="text" @click="toArch(scope.row, scope.$index)">成绩统计</el-button> @click="toRank(scope.row, scope.$index)">排名</el-button>
<!-- <el-button @click="toArch(scope.row, scope.$index)">编辑试卷</el-button> --> <el-button @click="toArch(scope.row)">成绩管理</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 util from "@/libs/util";
import Const from '@/const/match' import Const from '@/const/match'
export default { export default {
name: "matchArch", name: "matchArch",
@ -62,8 +63,6 @@ export default {
form: {}, form: {},
timer: null, timer: null,
curStep: [], curStep: [],
reviewVisible: false,
reviewUrl: '',
}; };
}, },
mounted () { mounted () {
@ -112,27 +111,15 @@ export default {
} }
} }
}) })
console.log("🚀 ~ file: matchArch.vue:87 ~ handleStatus ~ this.status", this.list)
}, },
// //
toRank (row, i) { toRank (row, i) {
this.$store.commit('setInnerReferrer', this.$route.fullPath)
this.$router.push(`/matchRank?id=${this.id}&stageId=${row.stageId}&index=${i}&method=${row.method}&competitionType=${row.competitionType}&rule=${row.rule}`) this.$router.push(`/matchRank?id=${this.id}&stageId=${row.stageId}&index=${i}&method=${row.method}&competitionType=${row.competitionType}&rule=${row.rule}`)
}, },
// //
toArch (row, i) { toArch (row) {
this.$store.commit('setInnerReferrer', this.$route.fullPath) this.$router.push(`/matchArchList?id=${this.id}&stageId=${row.stageId}&method=${row.method}&competitionType=${row.competitionType}`)
const cur = this.form.competitionStage[i]
const showFile = !!(cur.method === 2 && cur.competitionStageContentSetting && cur.competitionStageContentSetting.whetherToUploadFiles)
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
} }
} }
}; };
@ -140,29 +127,15 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
/deep/.el-collapse-item__header { /deep/.el-collapse-item__header {
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>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,260 +1,223 @@
<template> <template>
<!-- 竞赛进展 --> <!-- 竞赛进展 -->
<div class="page-content" <div class="page-content" style="padding: 24px">
style="padding: 24px"> <el-table ref="table" :data="listData" class="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id">
<el-table ref="table" <el-table-column type="index" width="60" label="序号" align="center">
:data="listData" <template slot-scope="scope">
class="table" {{ scope.$index + (pageNo - 1) * pageSize + 1 }}
stripe </template>
header-align="center" </el-table-column>
@selection-change="handleSelectionChange" <el-table-column prop="name" label="标题">
row-key="id"> <template slot-scope="scope">
<el-table-column type="index" <el-input placeholder="请输入标题" :disabled="!scope.row.operate" v-model="scope.row.title"></el-input>
width="60" </template>
label="序号" </el-table-column>
align="center"> <el-table-column prop="name" label="详情描述">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.$index + (pageNo - 1) * pageSize + 1 }} <el-input placeholder="请输入详情描述" :disabled="!scope.row.operate" type="textarea" v-model="scope.row.description"></el-input>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="name" <el-table-column prop="name" label="状态" width="150">
label="标题"> <template slot-scope="scope">
<template slot-scope="scope"> <el-select v-model="scope.row.status" :disabled="!scope.row.operate" clearable placeholder="请选择状态">
<el-input placeholder="请输入标题" <el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.value"></el-option>
:disabled="!scope.row.operate" </el-select>
v-model="scope.row.title"></el-input> </template>
</template> </el-table-column>
</el-table-column> <el-table-column label="操作" align="center" width="170">
<el-table-column prop="name" <template slot-scope="scope">
label="详情描述"> <el-button v-if="!scope.row.operate" type="text" @click="operateIt(scope.row)" v-auth="'/match:管理:竞赛进展:编辑'">编辑</el-button>
<template slot-scope="scope"> <el-button v-else type="text" @click="saveData(scope.row)">保存</el-button>
<el-input placeholder="请输入详情描述" <el-button type="text" @click="handleDelete(scope.row, scope.$index)" v-auth="'/match:管理:竞赛进展:删除'">删除</el-button>
:disabled="!scope.row.operate" </template>
type="textarea" </el-table-column>
v-model="scope.row.description"></el-input> </el-table>
</template> <div class="plus" @click="addData" v-auth="'/match:管理:竞赛进展:新增'">
</el-table-column> <i class="el-icon-circle-plus-outline"></i>
<el-table-column prop="name" </div>
label="状态"
width="150">
<template slot-scope="scope">
<el-select v-model="scope.row.status"
:disabled="!scope.row.operate"
clearable
placeholder="请选择状态">
<el-option v-for="(item,index) in statusList"
:key="index"
:label="item.name"
:value="item.value"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="操作"
align="center"
width="170">
<template slot-scope="scope">
<el-button v-if="!scope.row.operate"
type="text"
@click="operateIt(scope.row)"
v-auth="'/match:管理:竞赛进展:编辑'">编辑</el-button>
<el-button v-else
type="text"
@click="saveData(scope.row)">保存</el-button>
<el-button type="text"
@click="handleDelete(scope.row, scope.$index)"
v-auth="'/match:管理:竞赛进展:删除'">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="plus"
@click="addData"
v-auth="'/match:管理:竞赛进展:新增'">
<i class="el-icon-circle-plus-outline"></i>
</div> </div>
</div>
</template> </template>
<script> <script>
import util from "@/libs/util"; import util from "@/libs/util";
export default { export default {
name: "matchProgress", name: "matchProgress",
data () { data() {
return { return {
save: false, save: false,
id: this.$route.query.id, id: this.$route.query.id,
statusList: [ statusList: [
{ {
value: 0, value: 0,
name: "未完成" name: "未完成"
}, },
{ {
value: 1, value: 1,
name: "进行中" name: "进行中"
}, },
{ {
value: 2, value: 2,
name: "已完成" name: "已完成"
} }
], ],
listData: [], listData: [],
multipleSelection: [], multipleSelection: [],
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
totals: 0, totals: 0,
touchTime: 0, touchTime:0,
timeOut: {} timeOut: {}
}; };
},
mounted () {
this.getData();
},
methods: {
operateIt (row) {
row.operate = true
}, },
getData () { mounted() {
this.$get(this.api.getCompetitionProgress, { this.getData();
competitionId: this.id
}).then(res => {
this.listData = res.competitionProgressList;
for (let index = 0; index < this.listData.length; index++) {
//
this.$set(this.listData, index, { operate: false, ...this.listData[index] })
}
}).catch(res => {
});
}, },
saveData (row) { methods: {
// operateIt(row) {
let data = row; row.operate = true
if (data.title.length) { },
if (row.id) { getData() {
this.$put(this.api.editCompetitionProgress, data).then(res => { this.$get(this.api.getCompetitionProgress, {
this.touchTime = this.touchTime - 1 competitionId: this.id
util.successMsg("修改成功"); }).then(res => {
this.getData(); this.listData = res.competitionProgressList;
}).catch(res => { for(let index=0; index<this.listData.length; index++) {
}); //
} else { this.$set(this.listData, index, { operate: false, ...this.listData[index]})
this.$post(this.api.addCompetitionProgress, data).then(res => { }
this.touchTime = this.touchTime - 1 }).catch(res => {
util.successMsg("创建成功"); });
},
saveData(row) {
//
let data = row;
if (data.title.length) {
if (row.id) {
this.$put(this.api.editCompetitionProgress, data).then(res => {
this.touchTime = this.touchTime-1
util.successMsg("修改成功");
this.getData();
}).catch(res => {
});
} else {
this.$post(this.api.addCompetitionProgress, data).then(res => {
this.touchTime = this.touchTime-1
util.successMsg("创建成功");
this.getData();
}).catch(res => {
});
}
} else {
util.warningMsg("请填写标题");
}
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
onSearch() {
this.pageNo = 1;
this.getData(); this.getData();
}).catch(res => { },
}); handleCurrentChange(val) {
} this.pageNo = val;
} else {
util.warningMsg("请填写标题");
}
},
handleSelectionChange (val) {
this.multipleSelection = val;
},
onSearch () {
this.pageNo = 1;
this.getData();
},
handleCurrentChange (val) {
this.pageNo = val;
this.getData();
},
handleDelete (row, index) {
this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", {
type: "warning"
}).then(() => {
if (row.id === "") {
this.listData.splice(index, 1)
util.successMsg("删除成功");
} else {
this.touchTime = this.touchTime + 1
this.$del(`${this.api.deleteCompetitionProgress}?competitionProgressId=${row.id}`).then(res => {
util.successMsg("删除成功");
this.getData(); this.getData();
}).catch(res => { },
}); handleDelete(row, index) {
} this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", {
type: "warning"
}).catch(() => { }).then(() => {
}); if(row.id === "") {
}, this.listData.splice(index, 1)
addData () { util.successMsg("删除成功");
// this.$store.commit("match/setWait", 1); }else {
this.touchTime = this.touchTime + 1 this.touchTime = this.touchTime+1
if (this.listData.length) { this.$del(`${this.api.deleteCompetitionProgress}?competitionProgressId=${row.id}`).then(res => {
if (this.listData[this.listData.length - 1].id) { util.successMsg("删除成功");
this.listData.push({ this.getData();
competitionId: this.id, }).catch(res => {
id: "", });
title: "", }
description: "",
status: 0, }).catch(() => {
operate: true });
}); },
this.operateIt(this.listData[this.listData.length - 1]) addData() {
} else { // this.$store.commit("match/setWait", 1);
util.warningMsg("请先保存新数据"); this.touchTime = this.touchTime+1
} if (this.listData.length) {
} else { if (this.listData[this.listData.length - 1].id) {
this.listData.push({ this.listData.push({
competitionId: this.id, competitionId: this.id,
id: "", id: "",
title: "", title: "",
description: "", description: "",
status: 1, // status1 status: 0,
operate: true operate: true
}); });
} this.operateIt(this.listData[this.listData.length - 1])
}, } else {
waitSave () { util.warningMsg("请先保存新数据");
if (this.hasEdit) { }
this.$confirm('暂未保存,是否保存本次编辑?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
closeOnClickModal: false
}).then(() => {
let num = 0;
for (var i = 0; i < this.listData.length; i++) {
let data = this.listData[i];
if (data.title) {
if (this.listData[i].id) {
this.$put(this.api.editContestProgress, data).then(res => {
}).catch(res => {
});
} else {
num = num + 1
}
} else { } else {
num = num + 1 this.listData.push({
competitionId: this.id,
id: "",
title: "",
description: "",
status: 1, // status1
operate: true
});
} }
} },
if (num > 0) { waitSave() {
this.$message({ if(this.hasEdit) {
type: 'error', this.$confirm('暂未保存,是否保存本次编辑?', '提示', {
message: '保存失败,有未填项目' confirmButtonText: '确定',
}); cancelButtonText: '取消',
} else { type: 'warning'
this.$message({ }).then(() => {
type: 'success', let num = 0;
message: '保存成功!' for(var i=0;i<this.listData.length;i++){
}); let data = this.listData[i];
} if (data.title) {
}).catch(() => { if (this.listData[i].id) {
this.$message({ this.$put(this.api.editContestProgress, data).then(res => {
type: 'info',
message: '已取消保存'
});
});
}
}).catch(res => {
});
}else{
num = num+1
}
}else{
num = num+1
}
}
if (num >0){
this.$message({
type: 'error',
message: '保存失败,有未填项目'
});
}else{
this.$message({
type: 'success',
message: '保存成功!'
});
}
}).catch(() => {
this.$message({
type: 'info',
message: '已取消保存'
});
});
}
}
},
computed: {
hasEdit() {
return this.listData.some(item => item.operate)
}
} }
},
computed: {
hasEdit () {
return this.listData.some(item => item.operate)
}
}
}; };
</script> </script>

@ -1,105 +1,121 @@
<template> <template>
<div> <div>
<el-card shadow="hover" class="m-b-20 head-card"> <el-card shadow="hover"
<div class="flex-between"> class="m-b-20 head-card">
<el-page-header v-if="grades.length" @back="back" :content="grades[index].stageName + '/排名'"></el-page-header> <div class="flex-between m-b-20">
<el-page-header v-if="grades.length"
@back="$router.back()"
:content="grades[index].stageName + '/排名'"></el-page-header>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" v-loading="loading" class="m-b-20"> <el-card shadow="hover"
class="m-b-20">
<div class="tabs"> <div class="tabs">
<template v-for="(item, i) in grades"> <template v-for="(item, i) in grades">
<a v-if="i === index || !item.stageId" :key="i" class="item" :class="{ active: item.stageId == active }" <a v-if="i === index || !item.stageId"
@click="tabChange(item.stageId)">{{ item.stageName }}排名</a> :key="i"
class="item"
:class="{active: item.stageId == active}"
@click="tabChange(item.stageId)">{{ item.stageName }}排名</a>
</template> </template>
</div> </div>
<div class="flex-between"
<div class="tool flex-between" style="margin-top: 20px"> style="margin: 20px 0">
<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"
<el-radio v-model="type" :label="1" @change="typeChange">手动上传</el-radio> :label="0"
<el-button type="primary" :disabled="type === 0" class="ml20" @click="batchImport">上传文件</el-button> @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>
</div>
<div>
<el-button v-if="!published"
type="primary"
@click="cancelPublish(1)">发布排名</el-button>
<div v-else>
<span style="margin-right: 10px">{{ publishTime }}发布排名</span>
<el-button type="primary"
@click="cancelPublish(0)">取消发布</el-button>
</div>
</div> </div>
<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 ? '团队名称/队长' : '学生姓名') + '/学校'"
prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</li>
<el-button v-if="!published" type="primary" @click="cancelPublish(1)">发布排名</el-button>
<template v-else>
<span style="margin-right: 10px;white-space: nowrap;">{{ publishTime }}发布排名</span>
<el-button type="primary" @click="cancelPublish(0)">取消发布</el-button>
</template>
<el-button v-if="list.length" type="primary" :loading="exporting" @click="exportData">{{ exporting ? '正在导出' :
'批量导出'
}}</el-button>
</ul>
</div> </div>
<el-table :data="list"
<el-table :data="list" class="table" ref="table" stripe row-key="scoreId" class="table"
@selection-change="handleSelectionChange" header-align="center"> 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"> header-align="center">
<el-table-column type="index"
width="60"
label="排名"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.$index + (page - 1) * pageSize + 1 }} {{ scope.$index + (page - 1) * pageSize + 1 }}
</template> </template>
</el-table-column> </el-table-column>
<template v-if="competitionType == 1"> <template v-if="competitionType == 1">
<el-table-column prop="teamName" label="团队名称" min-width="150" align="center"></el-table-column> <el-table-column prop="teamName"
<el-table-column prop="leaderName" label="队长" min-width="150" align="center"></el-table-column> 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
<el-table-column prop="provinceName" label="省份" min-width="100" align="center"></el-table-column> prop="userName"
<el-table-column prop="cityName" label="城市" min-width="100" align="center"></el-table-column> label="学生姓名"
<el-table-column prop="schoolName" label="学生账号归属" min-width="100" align="center"></el-table-column> min-width="100"
<el-table-column prop="realSchool" label="学生所在院校" min-width="100" align="center"></el-table-column> align="center"></el-table-column>
<el-table-column prop="timeSum" label="用时" width="90" align="center"> <el-table-column prop="schoolName"
label="学校"
min-width="100"
align="center"></el-table-column>
<el-table-column prop="timeSum"
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="score" label="分数" width="90" align="center"></el-table-column> <el-table-column prop="score"
<el-table-column label="得分详情" align="center" width="160"> label="分数"
width="90"
align="center"></el-table-column>
<el-table-column label="得分详情"
align="center"
width="160">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button v-if="(!competitionType && scope.row.reportId) || competitionType" type="text" <el-button v-if="(!competitionType && scope.row.reportId) || competitionType"
@click="show(scope.row, scope.$index)">查看</el-button> type="text"
@click="show(scope.row, scope.$index)">查看</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" <el-pagination background
:current-page="page"> layout="total, prev, pager, next"
:total="total"
@current-change="handleCurrentChange"
:current-page="page">
</el-pagination> </el-pagination>
</div> </div>
</el-card> </el-card>
<el-dialog title="团队得分详情" :visible.sync="teamVisible" width="900px" :close-on-click-modal="false"> <el-dialog title="团队得分详情"
<h6 v-if="active" style="margin-bottom: 10px;font-size: 16px;">团队名称{{ curRow.teamName }} 阶段名称{{ stageName }} :visible.sync="teamVisible"
</h6> width="900px"
:close-on-click-modal="false">
<h6 v-if="active"
style="margin-bottom: 10px;font-size: 16px;">团队名称{{ curRow.teamName }} 阶段名称{{ stageName }}</h6>
<table class="table tc"> <table class="table tc">
<tr> <tr>
<template v-if="!active"> <template v-if="!active">
@ -114,29 +130,32 @@
<th width="100">得分详情</th> <th width="100">得分详情</th>
</tr> </tr>
<template v-if="teams.length"> <template v-if="teams.length">
<tr v-for="(item, i) in teams" :key="i"> <tr v-for="(item, i) in teams"
:key="i">
<template v-if="!active && item.rowspan"> <template v-if="!active && item.rowspan">
<td :rowspan="item.rowspan">{{ item.stageName }}</td> <td :rowspan="item.rowspan">{{ item.stageName }}</td>
<td class="scores" :rowspan="item.rowspan"> <td class="scores"
:rowspan="item.rowspan">
<p class="score">{{ item.teamScore }}</p> <p class="score">{{ item.teamScore }}</p>
<p>{{ item.teamCalculationMethodName }}</p> <p>{{ item.teamCalculationMethodName }}</p>
<template v-if="isPointWeight"> <p>权重</p>
<p>权重</p> <p>{{ item.pointWeight }}%</p>
<p>{{ item.pointWeight }}%</p>
</template>
</td> </td>
</template> </template>
<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.realSchool }}</td> <td>{{ item.schoolName }}</td>
<td>{{ item.timeSum }}min</td> <td>{{ item.timeSum }}min</td>
<td>{{ item.score }}</td> <td>{{ item.score }}</td>
<td> <td>
<el-button v-if="item.reportId" type="text" @click="toReport(item)">查看</el-button> <el-button v-if="item.reportId"
type="text"
@click="toReport(item)">查看</el-button>
</td> </td>
</template> </template>
<td v-else colspan="6"></td> <td v-else
colspan="6"></td>
</tr> </tr>
</template> </template>
<tr v-else> <tr v-else>
@ -148,78 +167,96 @@
<td colspan="6">总排名{{ curRow.index }}</td> <td colspan="6">总排名{{ curRow.index }}</td>
</tr> </tr>
</table> </table>
<span slot="footer" class="dialog-footer"> <span slot="footer"
<el-button size="small" type="primary" @click="teamVisible = false">确定</el-button> class="dialog-footer">
<el-button size="small"
type="primary"
@click="teamVisible = false">确定</el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="批量导入" :visible.sync="importVisible" width="24%" :close-on-click-modal="false" <el-dialog title="批量导入"
@close="cancelUpload"> :visible.sync="importVisible"
width="24%"
:close-on-click-modal="false">
<div style="text-align: center"> <div style="text-align: center">
<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" name="file" accept=".xls,.xlsx" class="import-file" :before-upload="beforeUpload" <el-upload ref="upload"
:on-remove="handleRemove" :on-error="uploadError" :on-success="uploadSuccess" :before-remove="beforeRemove" name="file"
:limit="1" :on-exceed="handleExceed" :action="this.api.batchImportRanking" :file-list="uploadList" accept=".xls,.xlsx"
:headers="headers" :disabled="uploading" :data="{ :on-remove="handleRemove"
competitionId: this.id, :on-error="uploadError"
stageId: this.stageId, :on-success="uploadSuccess"
isOverallRanking: active ? 0 : 1, :before-remove="beforeRemove"
schoolId: '' :limit="1"
}"> :on-exceed="handleExceed"
<el-button type="primary" :loading="uploading" class="ml20">上传文件<i :action="this.api.batchImportRanking"
class="el-icon-upload2 el-icon--right"></i></el-button> :file-list="uploadList"
</el-upload> :headers="headers"
</template> :data="{
<template v-else> competitionId: this.id,
<p style="margin: -10px 0 13px;font-size: 14px;color: #e90000;">{{ faildData.tip }}</p> stageId: this.stageId,
<p type="primary" isOverallRanking: active ? 0 : 1,
style="margin-bottom: 10px;font-size: 14px;color: #9076FF;text-decoration: underline;cursor: pointer;" schoolId: ''
@click="showFaild">部分数据导入失败查看失败原因</p> }"
</template> :auto-upload="false">
<el-button type="primary"
class="ml20">上传文件<i class="el-icon-upload2 el-icon--right"></i></el-button>
</el-upload>
<el-link v-if="uploadFaild"
type="primary"
@click="showFaild">部分数据导入失败查看失败原因</el-link>
</div> </div>
<span v-if="uploading" slot="footer" class="dialog-footer"> <span slot="footer"
<el-button @click="cancelUpload">停止导入</el-button> class="dialog-footer">
<el-button size="small"
@click="importVisible = false"> </el-button>
<el-button size="small"
type="primary"
@click="uploadSure"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="请选择发布排名时间" :visible.sync="publishVisible" width="260px" :close-on-click-modal="false" <el-dialog title="请选择发布排名时间"
custom-class="publish-dia"> :visible.sync="publishVisible"
<el-date-picker popper-class="no-atTheMoment" v-model="publishTime" placeholder="请选择结束时间" type="datetime" width="260px"
:picker-options="pickerOptions"> :close-on-click-modal="false"
custom-class="publish-dia">
<el-date-picker popper-class="no-atTheMoment"
v-model="publishTime"
placeholder="请选择结束时间"
type="datetime"
:picker-options="pickerOptions">
</el-date-picker> </el-date-picker>
<span slot="footer" class="dialog-footer"> <span slot="footer"
<el-button size="small" @click="publishVisible = false"> </el-button> class="dialog-footer">
<el-button size="small" type="primary" @click="publishTimeSubmit"> </el-button> <el-button size="small"
@click="publishVisible = false"> </el-button>
<el-button size="small"
type="primary"
@click="publishTimeSubmit"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script> <script>
import Util from '@/libs/util' import Setting from '@/setting'
import axios from 'axios' import util from "@/libs/util";
import echarts from "echarts";
import axios from 'axios';
export default { export default {
data () { data () {
return { return {
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,
filter: {
provinceId: '',
cityId: '',
realSchoolId: '',
},
provinces: [],
cities: [],
schools: [],
keyword: this.$route.query.keyword || '',
teamCalculationMethods: [ teamCalculationMethods: [
{ {
id: 0, id: 0,
@ -240,7 +277,7 @@ export default {
active: '', active: '',
grades: [], grades: [],
list: [], list: [],
page: +this.$route.query.page || 1, page: 1,
pageSize: 10, pageSize: 10,
total: 0, total: 0,
type: 0, type: 0,
@ -251,8 +288,7 @@ export default {
importVisible: false, importVisible: false,
uploadList: [], uploadList: [],
uploadFaild: false, uploadFaild: false,
uploading: false, exportCode: '',
faildData: null,
curRow: {}, curRow: {},
stageName: '', stageName: '',
totalScore: 0, totalScore: 0,
@ -276,31 +312,10 @@ export default {
return [`${hour}:${minute}:${second} - 23:59:59`] return [`${hour}:${minute}:${second} - 23:59:59`]
})(), })(),
}, },
uploaded: 0, uploaded: 0
multipleSelection: [],
loading: false,
exporting: false,
isPointWeight: false
}; };
}, },
watch: {
keyword: function (val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.$router.push({
path: '/matchRank',
query: {
...this.$route.query,
keyword: val
}
})
this.getRank();
}, 500);
}
},
mounted () { mounted () {
this.getProvince()
this.getSchool()
this.getStage() this.getStage()
}, },
methods: { methods: {
@ -314,8 +329,6 @@ export default {
}, },
// //
getRank () { getRank () {
const { filter } = this
this.loading = true
// //
if (this.type) { if (this.type) {
this.$post(this.api.manuallyUploadedRankings, { this.$post(this.api.manuallyUploadedRankings, {
@ -323,9 +336,7 @@ export default {
pageSize: this.pageSize, pageSize: this.pageSize,
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,
...filter
}).then(({ message, publishStatus }) => { }).then(({ message, publishStatus }) => {
// isRelease 01 // isRelease 01
this.published = publishStatus this.published = publishStatus
@ -333,10 +344,7 @@ export default {
this.list = message.records this.list = message.records
this.total = message.total this.total = message.total
this.getPublishTime() this.getPublishTime()
this.loading = false }).catch(res => { })
}).catch(res => {
this.loading = false
})
} else { // } else { //
if (!this.active) { if (!this.active) {
// //
@ -347,41 +355,30 @@ export default {
competitionId: this.id, competitionId: this.id,
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,
...filter
}).then(({ page, publishStatus, total }) => { }).then(({ page, publishStatus, total }) => {
this.published = publishStatus this.published = publishStatus
this.list = page || [] this.list = page
this.total = total this.total = total
this.getPublishTime() this.getPublishTime()
this.loading = false }).catch(res => { })
}).catch(res => { } else { //
this.loading = false this.$post(`${this.api.stageRaceRanking}?competitionId=${this.id}&stageId=${this.active}&pageNum=${this.page}&pageSize=${this.pageSize}&publicationType=${this.type}`).then(({ page, total, publishStatus }) => {
})
} else {
//
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
this.getPublishTime() this.getPublishTime()
this.loading = false }).catch(res => { })
}).catch(res => {
this.loading = false
})
} }
} }
}, },
// //
async getStage () { getStage () {
this.loading = true this.$post(this.api.detailsOfCompetitionStage, {
try { pageNum: 1,
const { page } = await this.$post(this.api.detailsOfCompetitionStage, { pageSize: 100,
pageNum: 1, contestId: this.id,
pageSize: 100, }).then(({ page }) => {
contestId: this.id,
})
this.grades = page.records.slice(0, this.index + 1) this.grades = page.records.slice(0, this.index + 1)
this.active = this.grades[this.index].stageId this.active = this.grades[this.index].stageId
// //
@ -390,13 +387,11 @@ export default {
stageName: '总分' stageName: '总分'
}) })
this.getData() this.getData()
} catch (e) { }).catch(res => { });
this.loading = false
}
}, },
// //
async typeChange (val) { typeChange (val) {
await this.$post(`${this.api.toggleTheSortingMode}?competitionId=${this.id}&stageId=${this.active || this.stageId}&isOverallRanking=${this.active ? 0 : 1}&whetherToManuallyPublish=${this.type}`) this.$post(`${this.api.toggleTheSortingMode}?competitionId=${this.id}&stageId=${this.active || this.stageId}&isOverallRanking=${this.active ? 0 : 1}&whetherToManuallyPublish=${this.type}`).then(res => { }).catch(res => { })
this.getRank() this.getRank()
}, },
initData () { initData () {
@ -409,39 +404,6 @@ 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 = []
@ -469,12 +431,11 @@ export default {
data.stageIds = ids.splice(0, this.index + 1) data.stageIds = ids.splice(0, this.index + 1)
// //
// if (this.published) { // if (this.published) {
this.$post(this.api.totalRankingScoreDetails, data).then(res => { this.$post(this.api.totalRankingScoreDetails, data).then(({ data }) => {
this.isPointWeight = res.isPointWeight if (data.length) {
if (res.data.length) {
const result = [] const result = []
// //
res.data.map(e => { data.map(e => {
const team = e.stageTeamInformation const team = e.stageTeamInformation
if (team.length) { if (team.length) {
const teamCItem = this.teamCalculationMethods.find(n => n.id == e.teamCalculationMethod) const teamCItem = this.teamCalculationMethods.find(n => n.id == e.teamCalculationMethod)
@ -524,90 +485,58 @@ export default {
}, },
// //
toReport (row) { toReport (row) {
this.$router.push(`/${this.method !== 1 ? 'trialReport' : 'theoryReport'}?reportId=${row.reportId}`) this.$router.push(`/matchReport?reportId=${row.reportId}`)
},
handleSelectionChange (val) { //
this.multipleSelection = val;
}, },
handleCurrentChange (val) { // handleCurrentChange (val) { //
this.$router.push({
path: '/matchRank',
query: {
...this.$route.query,
page: val
}
})
this.page = val; this.page = val;
this.getData(); this.getData();
}, },
// () //
async exportData () { publishSubmit () {
this.exporting = true if (this.type) { //
let { list } = this this.$post(this.api.batchRelease, this.list.map(e => e.id)).then(res => {
if (this.multipleSelection.length) { // this.getData()
list = this.multipleSelection // util.successMsg('')
}).catch(res => { })
} else { } else {
// pageSize10000 let data = [] // data
if (!this.type) { //
// //
if (this.type) { const { list, id } = this
const res = await this.$post(this.api.manuallyUploadedRankings, { const isOverall = this.active ? 0 : 1
pageNum: 1, if (list.length) {
pageSize: 10000, const isPerson = this.competitionType == 0
competitionId: this.id, list.map(e => {
isOverallRanking: this.active ? 0 : 1, e.competitionId = id
stageId: this.active || this.stageId e.isOverallRanking = isOverall
}) e.stageId = this.stageId
list = res.message.records // if (isOverall) delete e.stageId
} else { // if (isPerson) e.teamId = null // teamIdnull
if (!this.active) {
//
const ids = this.grades.map(e => e.stageId)
const res = await this.$post(this.api.overallStandingsInThePointsRace, {
pageNum: 1,
pageSize: 10000,
competitionId: this.id,
publicationType: this.type,
locationStageId: this.stageId,
stageIds: ids.splice(0, ids.length - 1)
}) })
list = res.page data = list
} else { //
const res = await this.$post(`${this.api.stageRaceRanking}?competitionId=${this.id}&stageId=${this.active}&pageNum=1&pageSize=10000&publicationType=${this.type}`)
list = res.page
} }
} }
data.forEach(e => {
e.publicationType = this.type
})
const ids = this.grades.map(e => e.stageId)
ids.pop()
//
// this.$post(`${this.api.releaseVerification}?competitionId=${this.id}&stageId=${this.active || this.stageId}&isOverallRanking=${this.active ? 0 : 1}&whetherToManuallyPublish=${this.type}`).then(res => {
this.$post(this.api.publishRanking, data).then(res => {
this.uploadData = []
// this.getData()
// util.successMsg('')
}).catch(res => { })
// }).catch(res => {})
} }
list.forEach((e, i) => {
e.serialNumber = i + 1
if (e.leaderName) e.userName = e.leaderName
})
axios.post(this.api[this.competitionType ? 'derivedRanking' : 'individualDerivedRanking'], list, {
headers: this.headers,
responseType: 'blob'
}).then((res) => {
Util.downloadFileDirect(`${this.grades.find(e => e.stageId == this.active).stageName}排名.xls`, new Blob([res.data]))
this.exporting = false
}).catch(res => { })
},
//
async publishSubmit () {
await this.$post(this.api.publishRanking, {
competitionId: this.id,
isOverallRanking: this.active ? 0 : 1,
publicationType: this.type,
releaseTime: Util.formatDate("yyyy-MM-dd hh:mm:ss", this.publishTime),
stageId: this.active || this.stageId,
})
this.uploadData = []
}, },
// //
publish () { publish () {
this.$post(`${this.api.whetherToPublish}?competitionId=${this.id}&stageId=${this.active || this.stageId}&isOverallRanking=${this.active ? 0 : 1}&publicationType=${this.type}`).then(({ whetherToPublish }) => { this.$post(`${this.api.whetherToPublish}?competitionId=${this.id}&stageId=${this.active || this.stageId}&isOverallRanking=${this.active ? 0 : 1}&publicationType=${this.type}`).then(({ whetherToPublish }) => {
whetherToPublish ? whetherToPublish ?
this.$confirm('排名已经发布,是否直接覆盖?', '提示', { this.$confirm('排名已经发布,是否直接覆盖?', '提示', {
type: 'success', type: 'success'
closeOnClickModal: false
}).then(() => { }).then(() => {
this.publishSubmit() this.publishSubmit()
}).catch(() => { }) : }).catch(() => { }) :
@ -635,19 +564,18 @@ export default {
// //
async publishTimeSubmit () { async publishTimeSubmit () {
const { startTime, endTime } = this.grades[this.index] const { startTime, endTime } = this.grades[this.index]
const now = await Util.getNow() if (Date.now() <= new Date(endTime)) return util.errorMsg('当前阶段还在进行中,请在本阶段结束后再发布!')
if (now <= new Date(endTime)) return Util.errorMsg('当前阶段还在进行中,请在本阶段结束后再发布!')
this.publishSubmit() this.publishSubmit()
// await this.$post(this.api.addCompetitionStageRankingTime, { await this.$post(this.api.addCompetitionStageRankingTime, {
// competitionId: this.id, competitionId: this.id,
// isOverallRanking: this.active ? 0 : 1, isOverallRanking: this.active ? 0 : 1,
// publicationType: this.type, publicationType: this.type,
// stageId: this.active || this.stageId, stageId: this.active || this.stageId,
// releaseTime: Util.formatDate("yyyy-MM-dd hh:mm:ss", this.publishTime) releaseTime: util.formatDate("yyyy-MM-dd hh:mm:ss", this.publishTime)
// }) })
Util.successMsg('发布成功') util.successMsg('发布成功')
this.getData() this.getData()
this.uploaded = 0 this.uploaded = 0
this.publishVisible = false this.publishVisible = false
@ -665,7 +593,7 @@ export default {
if (publish) { if (publish) {
// //
if (this.type && !this.uploaded && !this.list.length) { if (this.type && !this.uploaded && !this.list.length) {
return Util.errorMsg('请先上传数据!') return util.errorMsg('请先上传数据!')
} else { } else {
this.publishTime = new Date() this.publishTime = new Date()
this.publishVisible = true this.publishVisible = true
@ -676,12 +604,12 @@ export default {
// if (this.timeId) { // if (this.timeId) {
// await this.$post(`${this.api.cancelCompetitionStageRankingTime}?competitionId=${this.id}&releaseId=${this.timeId}&isOverallRanking=${this.active ? 0 : 1}&stageId=${this.active || this.stageId}`) // await this.$post(`${this.api.cancelCompetitionStageRankingTime}?competitionId=${this.id}&releaseId=${this.timeId}&isOverallRanking=${this.active ? 0 : 1}&stageId=${this.active || this.stageId}`)
// } else { // } else {
await this.$post(`${this.api.cancelRanking}?competitionId=${this.id}&isOverallRanking=${this.active ? 0 : 1}&${this.active ? 'stageIds=' + this.active : query.join('&')}&releaseId=${this.timeId}&publicationType=${this.type}`) await this.$post(`${this.api.cancelRanking}?competitionId=${this.id}&isOverallRanking=${this.active ? 0 : 1}&${this.active ? 'stageIds=' + this.active : query.join('&')}&releaseId=${this.timeId}`)
// } // }
this.sourceType = '' this.sourceType = ''
this.type = 0 this.type = 0
this.getData() this.getData()
Util.successMsg('取消发布成功!') util.successMsg('取消发布成功!')
} catch (error) { } } catch (error) { }
} }
}, },
@ -697,53 +625,45 @@ export default {
}, },
// //
handleExceed (files, fileList) { handleExceed (files, fileList) {
Util.warningMsg( util.warningMsg(
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!` `当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
) )
}, },
// //
showFaild () { showFaild () {
axios.get(`${this.api.rankExportFailure}?exportCode=${this.faildData.exportCode}&competitionId=${this.id}`, { axios.get(`${this.api.rankExportFailure}?exportCode=${this.exportCode}&competitionId=${this.id}`, {
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, file, fileList) {
this.uploading = false
this.uploadFaild = false this.uploadFaild = false
this.uploaded = 0 this.uploaded = 0
if (res.status === 200) { if (res.status === 200) {
this.getRank() const { exportCode } = res.data
const { data } = res if (exportCode) {
if (data.exportCode) { this.exportCode = exportCode
this.faildData = data
this.uploadFaild = true this.uploadFaild = true
util.errorMsg(`本次上传有${res.data.failureNum}个错误信息录入`)
} else { } else {
this.uploaded = 1 this.uploaded = 1
this.importVisible = false this.importVisible = false
Util.successMsg(data.tip, 3000) this.getRank()
// Util.successMsg('') util.successMsg('请检查数据后,点击发布排名以发布数据!')
} }
} else { } else {
Util.errorMsg(res.message || "上传失败,请检查数据") util.errorMsg(res.message || "上传失败,请检查数据")
} }
}, },
uploadError (err, file, fileList) { uploadError (err, file, fileList) {
this.uploading = false
this.$message({ this.$message({
message: "上传出错,请重试!", message: "上传出错,请重试!",
type: "error", type: "error",
center: true center: true
}) })
}, },
async beforeUpload (file) {
this.uploading = true
if (this.list.length) {
await this.$post(`${this.api.cancelRanking}?competitionId=${this.id}&isOverallRanking=${this.active ? 0 : 1}&${this.active ? 'stageIds=' + this.active : query.join('&')}&releaseId=${this.timeId}&publicationType=${this.type}`)
}
},
beforeRemove (file, fileList) { beforeRemove (file, fileList) {
return this.$confirm(`确定移除 ${file.name}`) return this.$confirm(`确定移除 ${file.name}`)
}, },
@ -751,15 +671,12 @@ export default {
this.uploadList = fileList this.uploadList = fileList
this.uploadFaild = false this.uploadFaild = false
}, },
cancelUpload () { uploadSure () {
this.uploading = false this.list.length ?
if (this.$refs.upload) this.$refs.upload.abort() this.$post(this.api.cancelImport, this.list.map(e => e.id)).then(res => {
this.keyword = '' this.$refs.upload.submit()
this.getRank() }).catch(res => { }) :
this.importVisible = false this.$refs.upload.submit()
},
back () {
this.$router.push(this.$store.state.innerReferrer)
} }
} }
}; };
@ -767,40 +684,27 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.table { .table {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
th,
th, td {
td { padding: 12px;
padding: 12px; border: 1px solid #ebeef5;
border: 1px solid #ebeef5; }
} &.tc {
text-align: center;
&.tc { }
text-align: center; th {
} text-align: center;
background-color: #f8faff;
th { }
text-align: center; .scores {
background-color: #f8faff; line-height: 1.6;
} }
.score {
.scores { font-size: 16px;
line-height: 1.6; font-weight: 600;
} color: #9076ff;
}
.score {
font-size: 16px;
font-weight: 600;
color: #9076ff;
}
}
/deep/.import-file {
.el-progress__text,
.el-progress,
.el-upload-list__item-status-label {
display: none !important;
}
} }
</style> </style>

@ -0,0 +1,442 @@
<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">
<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="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.$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 => { })
},
//
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
},
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;
&.loading {
padding-top: 30px;
}
.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>

File diff suppressed because it is too large Load Diff

@ -1,74 +1,48 @@
<template> <template>
<!-- 报名人员 --> <!-- 报名人员 -->
<div class="page-content" <div class="page-content" style="padding: 24px">
style="padding: 24px"> <div class="tool" style="justify-content: flex-end">
<div class="tool" <el-button type="primary" round @click="add" v-auth="'/match:管理:公告通知:新增'">新增</el-button>
style="justify-content: flex-end"> </div>
<el-button type="primary"
round
@click="add"
v-auth="'/match:管理:公告通知:新增'">新增</el-button>
</div>
<el-table ref="table" <el-table ref="table" :data="listData" class="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id">
:data="listData" <el-table-column type="index" width="60" label="序号" align="center">
class="table" <template slot-scope="scope">
stripe {{ scope.$index + (pageNo - 1) * pageSize + 1 }}
header-align="center" </template>
@selection-change="handleSelectionChange" </el-table-column>
row-key="id"> <el-table-column prop="announcementTitle" label="标题名称">
<el-table-column type="index" </el-table-column>
width="60" <el-table-column prop="createTime" label="创建时间">
label="序号" </el-table-column>
align="center"> <el-table-column prop="updateTime" label="发布时间">
<template slot-scope="scope"> </el-table-column>
{{ scope.$index + (pageNo - 1) * pageSize + 1 }} <el-table-column prop="phone" label="状态">
</template> <template slot-scope="scope">
</el-table-column> {{ scope.row.status ? '已发布' : '草稿' }}
<el-table-column prop="announcementTitle" </template>
label="标题名称"> </el-table-column>
</el-table-column> <el-table-column label="操作" align="center" width="250">
<el-table-column prop="createTime" <template slot-scope="scope">
label="创建时间"> <el-button type="text" @click="edit(scope.row)" v-auth="'/match:管理:公告通知:编辑'">编辑</el-button>
</el-table-column> <el-button type="text" @click="del(scope.row)" v-auth="'/match:管理:公告通知:删除'">删除</el-button>
<el-table-column prop="updateTime" <el-switch
label="发布时间"> v-auth="'/match:管理:公告通知:启用'"
</el-table-column> v-model="scope.row.isOpen"
<el-table-column prop="phone" :active-text="scope.row.isOpen ? '关' : '开'"
label="状态"> :active-value="0"
<template slot-scope="scope"> :inactive-value="1"
{{ scope.row.status ? '已发布' : '草稿' }} style="margin: 0 10px 0 5px"
</template> @change="switchOff($event,scope.row,scope.$index)"
</el-table-column> ></el-switch>
<el-table-column label="操作" </template>
align="center" </el-table-column>
width="250"> </el-table>
<template slot-scope="scope"> <div class="pagination">
<el-button type="text" <el-pagination background layout="total, prev, pager, next" :total="totals" @current-change="handleCurrentChange" :current-page="pageNo">
@click="edit(scope.row)" </el-pagination>
v-auth="'/match:管理:公告通知:编辑'">编辑</el-button> </div>
<el-button type="text"
@click="del(scope.row)"
v-auth="'/match:管理:公告通知:删除'">删除</el-button>
<el-switch v-auth="'/match:管理:公告通知:启用'"
v-model="scope.row.isOpen"
:active-text="scope.row.isOpen ? '关' : '开'"
:active-value="0"
:inactive-value="1"
style="margin: 0 10px 0 5px"
@change="switchOff($event,scope.row,scope.$index)"></el-switch>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background
layout="total, prev, pager, next"
:total="totals"
@current-change="handleCurrentChange"
:current-page="pageNo">
</el-pagination>
</div> </div>
</div>
</template> </template>
<script> <script>
@ -76,91 +50,91 @@ import util from "@/libs/util";
import Setting from "@/setting"; import Setting from "@/setting";
export default { export default {
name: "matchSignup", name: "matchSignup",
data () { data() {
return { return {
token: util.local.get(Setting.tokenKey), token: util.local.get(Setting.tokenKey),
id: this.$route.query.id, id: this.$route.query.id,
keyword: "", keyword: "",
listData: [], listData: [],
multipleSelection: [], multipleSelection: [],
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
totals: 0 totals: 0
}; };
},
watch: {
keyword: function (val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.getData();
}, 500);
}
},
mounted () {
this.getData()
},
methods: {
getData () {
this.$post(`${this.api.queryAnnouncementByCompetitionId}?pageNum=${this.pageNo}&pageSize=${this.pageSize}&competitionId=${this.id}`).then(({ data }) => {
this.listData = data.records
this.totals = data.total
this.$refs.table.clearSelection()
}).catch(res => { })
}, },
handleSelectionChange (val) { watch: {
this.multipleSelection = val; keyword: function(val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.getData();
}, 500);
}
}, },
handleCurrentChange (val) { mounted() {
this.pageNo = val; this.getData()
this.getData();
}, },
del (row) { methods: {
this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", { getData() {
type: "warning" this.$post(`${this.api.queryAnnouncementByCompetitionId}?pageNum=${this.pageNo}&pageSize=${this.pageSize}&competitionId=${this.id}`).then(({ data }) => {
}) this.listData = data.records
.then(() => { this.totals = data.total
this.$post(`${this.api.deleteAnnouncement}?id=${row.id}`).then(res => { this.$refs.table.clearSelection()
util.successMsg("删除成功"); }).catch(res => {})
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
handleCurrentChange(val) {
this.pageNo = val;
this.getData(); this.getData();
}).catch(res => { },
}); del(row) {
}) this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", {
.catch(() => { type: "warning"
}); })
}, .then(() => {
switchOff (val, row, index) { this.$post(`${this.api.deleteAnnouncement}?id=${row.id}`).then(res => {
if (val) { util.successMsg("删除成功");
this.$put(`${this.api.disableAnnouncement}?id=${row.id}&isDisable=${val}`).then(res => { }).catch(err => { }) this.getData();
} else if (!row.status) { }).catch(res => {
this.$confirm('是否发布该公告?', '提示', { });
type: 'success', })
closeOnClickModal: false .catch(() => {
}).then(() => { });
this.$put(`${this.api.disableAnnouncement}?id=${row.id}&isDisable=${val}`).then(res => { },
this.$post(this.api.amendmentAnnouncement, { switchOff(val, row, index) {
id: row.id, if (val) {
status: 1 this.$put(`${this.api.disableAnnouncement}?id=${row.id}&isDisable=${val}`).then(res => {}).catch(err => {})
}).then(res => { } else if (!row.status) {
this.getData() this.$confirm('是否发布该公告?', '提示', {
}).catch(err => { }) type: 'success'
}).catch(err => { }) }).then(() => {
}).catch(() => { this.$put(`${this.api.disableAnnouncement}?id=${row.id}&isDisable=${val}`).then(res => {
row.isOpen = 1 this.$post(this.api.amendmentAnnouncement, {
}) id: row.id,
} else { status: 1
this.$put(`${this.api.disableAnnouncement}?id=${row.id}&isDisable=${val}`).then(res => { }).catch(err => { }) }).then(res => {
} this.getData()
}, }).catch(err => {})
add () { }).catch(err => {})
this.$router.push(`/noticeDetail?competitionId=${this.id}`) }).catch(() => {
}, row.isOpen = 1
edit (row) { })
this.$router.push(`/noticeDetail?id=${row.id}&competitionId=${this.id}`) } else {
this.$put(`${this.api.disableAnnouncement}?id=${row.id}&isDisable=${val}`).then(res => {}).catch(err => {})
}
},
add() {
this.$router.push(`/noticeDetail?competitionId=${this.id}`)
},
edit(row) {
this.$router.push(`/noticeDetail?id=${row.id}&competitionId=${this.id}`)
}
} }
}
}; };
</script> </script>
<style scoped> <style scoped>
</style> </style>

@ -1,170 +1,174 @@
<template> <template>
<!-- 大赛详情 --> <!-- 大赛详情 -->
<div> <div>
<el-card shadow="hover" <el-card shadow="hover" style="margin-bottom: 20px">
style="margin-bottom: 20px"> <div class="flex-between">
<div class="flex-between"> <el-page-header @back="back" :content="(form.id ? '编辑' : '创建') + '公告'"></el-page-header>
<el-page-header @back="back" </div>
:content="(form.id ? '编辑' : '创建') + '公告'"></el-page-header> </el-card>
</div> <div class="page">
</el-card> <div class="page-content">
<div class="page"> <el-form label-width="170px" label-suffix=":" size="small">
<div class="page-content"> <el-form-item label="公告标题">
<el-form label-width="170px" <div class="d-inline-block">
label-suffix=":" <el-input placeholder="请输入公告名称" v-model="form.announcementTitle" clearable></el-input>
size="small"> </div>
<el-form-item label="公告标题"> </el-form-item>
<div class="d-inline-block"> <el-form-item label="正文">
<el-input placeholder="请输入公告名称" <quill :border="true" v-model="form.announcementText" :height="400" />
v-model="form.announcementTitle" </el-form-item>
clearable></el-input> <el-form-item label="附件">
</div> <el-upload
</el-form-item> :on-remove="handleRemove"
<el-form-item label="正文"> :on-error="uploadError"
<quill :border="true" :on-success="uploadSuccess"
v-model="form.announcementText" :before-upload="beforeUpload"
:height="400" /> :before-remove="beforeRemove"
</el-form-item> :limit="5"
<el-form-item label="附件"> :on-exceed="handleExceed"
<Upload :limit="5" :action="this.api.fileupload"
:file-list="fileList" :headers="headers"
:on-remove="handleRemove" :file-list="fileList"
@onSuccess="uploadSuccess" /> name="file"
</el-form-item> >
<el-form-item> <el-button size="small" type="primary">点击上传</el-button>
<el-button v-if="!form.id" <div slot="tip" class="el-upload__tip">
@click="save(0)" <p>支持扩展名.rar .zip .doc .docx .pdf .jpg...</p>
v-auth="'/match:管理:公告通知:草稿'">草稿</el-button> </div>
<el-button type="primary" </el-upload>
@click="save(1)" </el-form-item>
v-auth="'/match:管理:公告通知:发布'">发布</el-button> <el-form-item>
<el-button @click="back">取消</el-button> <el-button v-if="!form.id" @click="save(0)" v-auth="'/match:管理:公告通知:草稿'">草稿</el-button>
</el-form-item> <el-button type="primary" @click="save(1)" v-auth="'/match:管理:公告通知:发布'">发布</el-button>
</el-form> <el-button @click="back">取消</el-button>
</el-form-item>
</el-form>
</div>
</div> </div>
</div> </div>
</div>
</template> </template>
<script> <script>
import quill from "@/components/quill"; import quill from "@/components/quill";
import util from "@/libs/util"; import util from "@/libs/util";
import Upload from '@/components/upload';
import Oss from '@/components/upload/upload.js'
export default { export default {
name: "matchDetail", name: "matchDetail",
data () { data() {
return { return {
headers: { headers: {
token: sessionStorage.getItem('token') token: sessionStorage.getItem('token')
}, },
form: { form: {
id: this.$route.query.id, id: this.$route.query.id,
competitionId: this.$route.query.competitionId, competitionId: this.$route.query.competitionId,
announcementText: '', announcementText: '',
announcementTitle: '', announcementTitle: '',
announcementAnnexList: [], announcementAnnexList: [],
isOpen: 1 isOpen: 1
}, },
updateTime: 0, updateTime: 0,
fileName: '', fileName: '',
fileList: [], fileList: [],
}; };
},
components: {
quill,
Upload
},
watch: {
// ,
form: {
handler () {
this.updateTime++
if (this.updateTime > 1) this.$store.commit('match/setWait', 0)
},
deep: true
},
},
mounted () {
this.form.id && this.getData()
},
methods: {
getData () {
this.$post(`${this.api.queryAnnouncementDetails}?id=${this.form.id}`).then(({ data }) => {
this.form = data
//
const fileList = data.announcementAnnexList
if (fileList) {
const files = []
fileList.map(e => {
files.push({
name: e.fileName,
url: e.filePath
})
})
this.fileList = files
} else {
data.announcementAnnexList = []
}
}).catch(err => { })
},
//
save (status) {
const form = this.form
if (!form.announcementTitle) return util.warningMsg('请填写公告标题')
if (!form.announcementText) return util.warningMsg('请填写正文')
form.status = status
if (form.id) {
form.isOpen = 0
delete form.announcementAnnexList
this.$post(this.api.amendmentAnnouncement, form).then(res => {
util.successMsg("修改成功")
this.$router.back()
}).catch(err => { })
} else {
form.isOpen = status ? 0 : 1
this.$post(this.api.addAnnouncement, form).then(res => {
util.successMsg("创建成功")
this.$router.back()
}).catch(err => { })
}
}, },
handleExceed (files, fileList) { components: {
util.warningMsg(`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`); quill
}, },
// watch: {
uploadSuccess (file) { // ,
const { id } = this.form form: {
const data = { handler(){
announcementId: id || '', this.updateTime++
fileName: file.name, if(this.updateTime > 1) this.$store.commit('match/setWait', 0)
filePath: file.url },
} deep:true
this.form.announcementAnnexList.push(data) },
//
id && this.$post(this.api.saveAnnouncementAnnex, data).then(res => { }).catch(res => { })
}, },
uploadError (err, file, fileList) { mounted() {
this.$message({ this.form.id && this.getData()
message: "上传出错,请重试!",
type: "error",
center: true
});
}, },
beforeRemove (file, fileList) { methods: {
return this.$confirm(`确定移除 ${file.name}`); getData() {
}, this.$post(`${this.api.queryAnnouncementDetails}?id=${this.form.id}`).then(({ data }) => {
handleRemove (file, fileList) { this.form = data
if (file.url) { //
Oss.del(file.url) const fileList = data.announcementAnnexList
const id = this.form.announcementAnnexList.find(e => e.fileName === file.name).id if (fileList) {
this.$post(`${this.api.delAnnex}?id=${id}`).then(res => { }).catch(res => { }) const files = []
} fileList.map(e => {
}, files.push({
back () { name: e.fileName,
this.$router.back() url: e.filePath
})
})
this.fileList = files
} else {
data.announcementAnnexList = []
}
}).catch(err => {})
},
//
save(status) {
const form = this.form
if (!form.announcementTitle) return util.warningMsg('请填写公告标题')
if (!form.announcementText) return util.warningMsg('请填写正文')
form.status = status
if (form.id) {
form.isOpen = 0
delete form.announcementAnnexList
this.$post(this.api.amendmentAnnouncement, form).then(res => {
util.successMsg("修改成功")
this.$router.back()
}).catch(err => {})
} else {
form.isOpen = status ? 0 : 1
this.$post(this.api.addAnnouncement, form).then(res => {
util.successMsg("创建成功")
this.$router.back()
}).catch(err => {})
}
},
handleExceed(files, fileList) {
util.warningMsg(`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`);
},
//
uploadSuccess(res) {
const file = res.data.filesResult
const { id } = this.form
const data = {
announcementId: id || '',
fileName: this.fileName,
filePath: file.fileUrl || file.fileId
}
this.form.announcementAnnexList.push(data)
//
id && this.$post(this.api.saveAnnouncementAnnex, data).then(res => {}).catch(res => {})
},
//
beforeUpload(file) {
this.fileName = file.name
},
uploadError(err, file, fileList) {
this.$message({
message: "上传出错,请重试!",
type: "error",
center: true
});
},
beforeRemove(file, fileList) {
return this.$confirm(`确定移除 ${file.name}`);
},
handleRemove(file, fileList) {
if (file.url) {
this.$del(`${this.api.fileDeletion}?keys=${file.url}`).then(res => {}).catch(res => {})
const id = this.form.announcementAnnexList.find(e => e.fileName === file.name).id
this.$post(`${this.api.delAnnex}?id=${id}`).then(res => {}).catch(res => {})
}
},
back() {
this.$router.back()
}
} }
}
}; };
</script> </script>
@ -251,8 +255,7 @@ $upload-lg-height: 150px;
/deep/ .d-inline-block { /deep/ .d-inline-block {
width: 216px; width: 216px;
.el-select, .el-select, .el-input {
.el-input {
width: 100%; width: 100%;
} }
} }
@ -272,7 +275,7 @@ $upload-lg-height: 150px;
.remove { .remove {
width: 16px; width: 16px;
height: 16px; height: 16px;
background: url('../../../assets/img/close.png') 0 0 / cover no-repeat; background: url("../../../assets/img/close.png") 0 0/cover no-repeat;
cursor: pointer; cursor: pointer;
} }
} }

@ -1,675 +0,0 @@
<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

@ -1,413 +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 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>

@ -69,16 +69,16 @@
<p v-if="rule.onlineButton">线上地点{{ rule.onlineAddress }}</p> <p v-if="rule.onlineButton">线上地点{{ rule.onlineAddress }}</p>
<p v-if="rule.offlineButton">线下地点{{ rule.offlineAddress }}</p> <p v-if="rule.offlineButton">线下地点{{ rule.offlineAddress }}</p>
<template v-if="rule.method === 2"> <template v-if="rule.method === 2">
<p>比赛地点{{ rule.offlineAddress }}</p> <p>线下地点{{ rule.offlineAddress }}</p>
<p>比赛内容{{ rule.contentDescription }}</p> <p>比赛内容{{ rule.contentDescription }}</p>
<p>评分规则{{ rule.scoreRule }}</p> <p>评分规则{{ rule.scoreRule }}</p>
</template> </template>
<template v-if="form.completeCompetitionSetup.competitionType"> <template v-if="form.completeCompetitionSetup.competitionType">
<p>每个团队参赛人数限制{{ rule.teamNumLimit || '不限制' }}</p> <p>团队参赛人数限制{{ rule.teamNumLimit || '不限制' }}</p>
<p>团队成绩计算方式{{ teamCalculationMethods.find(e => e.id == rule.teamCalculationMethod) && teamCalculationMethods.find(e => e.id == rule.teamCalculationMethod).name }}</p> <p>团队成绩计算方式{{ teamCalculationMethods.find(e => e.id == rule.teamCalculationMethod) && teamCalculationMethods.find(e => e.id == rule.teamCalculationMethod).name }}</p>
</template> </template>
<!-- <p v-if="rule.resultAnnouncementTime != 0">阶段比赛结束后{{ rule.resultAnnouncementTime }}小时公布阶段比赛成绩</p> --> <p>阶段比赛结束后{{ rule.resultAnnouncementTime }}小时公布阶段比赛成绩</p>
<div v-if="form.rule === 1" <div v-if="form.rule === 1"
class="flex"> class="flex">
<p>晋级规则</p> <p>晋级规则</p>
@ -183,7 +183,6 @@ export default {
}, },
mounted () { mounted () {
this.handleAnnex() this.handleAnnex()
console.log("🚀 ~ file: index.vue:187 ~ mounted ~ this.form:", this.form)
if (this.form.id) { if (this.form.id) {
this.getProgress() this.getProgress()
this.getNotice() this.getNotice()

File diff suppressed because it is too large Load Diff

@ -1,365 +1,363 @@
<template> <template>
<div> <div>
<el-card shadow="hover" class="mgb20"> <el-card shadow="hover" class="mgb20">
<div> <div>
<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>
<div> <div>
<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" clearable placeholder="请选择省份" @change="getCity()" <el-select v-model="form.provinces" clearable placeholder="请选择省份"
@clear="clearprovince()"> @change="getCity()" @clear="clearprovince()">
<el-option v-for="(item, index) in provinceList" :key="index" :label="item.provinceName" <el-option v-for="(item,index) in provinceList" :key="index"
:value="item.provinceId"></el-option> :label="item.provinceName" :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" clearable placeholder="请选择城市" <el-select v-model="form.city" clearable placeholder="请选择城市"
:disabled="form.provinceId ? false : true" @change="getData()"> :disabled="form.provinces ? false : true" @change="getData()">
<el-option v-for="(item, index) in cityList" :key="index" :label="item.cityName" <el-option v-for="(item,index) in cityList" :key="index"
:value="item.cityId"></el-option> :label="item.cityName" :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" clearable placeholder="请选择订单类型" @change="getData()"> <el-select v-model="form.orderType" clearable placeholder="请选择订单类型"
<el-option v-for="(item, index) in orderTypeList" :key="index" :label="item.name" @change="getData()">
:value="item.value"></el-option> <el-option v-for="(item,index) in orderTypeList" :key="index"
</el-select> :label="item.name" :value="item.value"></el-option>
</el-form-item> </el-select>
</el-col> </el-form-item>
<el-col :span="4"> </el-col>
<el-form-item label="订单状态"> <el-col :span="4">
<el-select v-model="form.orderStatus" clearable placeholder="请选择订单状态" @change="getData()"> <el-form-item label="订单状态">
<el-option v-for="(item, index) in orderStatusList" :key="index" :label="item.name" <el-select v-model="form.orderStatus" clearable placeholder="请选择订单状态"
:value="item.value"></el-option> @change="getData()">
</el-select> <el-option v-for="(item,index) in orderStatusList" :key="index"
</el-form-item> :label="item.name" :value="item.value"></el-option>
</el-col> </el-select>
<el-col :span="6"> </el-form-item>
<el-form-item> </el-col>
<el-input placeholder="请输入订单号/客户名称/订单名称" prefix-icon="el-icon-search" v-model="form.customerName" <el-col :span="6">
clearable></el-input> <el-form-item>
</el-form-item> <el-input placeholder="请输入订单号/客户名称/订单名称" prefix-icon="el-icon-search" v-model="keyword" clearable></el-input>
</el-col> </el-form-item>
</el-form> </el-col>
</div> </el-form>
</div> </div>
</el-card> </div>
</el-card>
<el-card shadow="hover" class="card"> <el-card shadow="hover" 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" round @click="addOrder" v-auth>新建订单</el-button> <el-button type="primary" round @click="addOrder()" v-auth>新建订单</el-button>
<el-button type="primary" round @click="delAllSelection" v-auth>批量删除</el-button> <el-button type="primary" round @click="delAllSelection" v-auth>批量删除</el-button>
</div> </div>
</div> </div>
<el-table :data="orderData" class="table" ref="table" stripe header-align="center" <el-table :data="orderData" class="table" ref="table" stripe header-align="center"
@selection-change="handleSelectionChange" row-key="orderId"> @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="selection" width="55" align="center"
<el-table-column type="index" width="100" label="序号" align="center"> :reserve-selection="true"></el-table-column>
</el-table-column> <el-table-column type="index" width="100" label="序号" align="center">
<el-table-column prop="orderNumber" label="订单编号" align="center"> </el-table-column>
</el-table-column> <el-table-column prop="orderNumber" label="订单编号" align="center">
<el-table-column prop="customerName" label="客户名称" align="center"> </el-table-column>
</el-table-column> <el-table-column prop="customerName" label="客户名称" align="center">
<el-table-column prop="orderContent" label="订单内容" align="center" show-overflow-tooltip></el-table-column> </el-table-column>
<el-table-column prop="orderAmount" label="订单金额(元)" align="center"> <el-table-column prop="orderContent" label="订单内容" align="center" show-overflow-tooltip></el-table-column>
<template slot-scope="scope"> <el-table-column prop="orderAmount" label="订单金额(元)" align="center">
{{ scope.row.orderType === '试用' ? 0 : scope.row.orderAmount }} <template slot-scope="scope">
</template> {{ scope.row.orderType === '试用' ? 0 : scope.row.orderAmount }}
</el-table-column> </template>
<el-table-column prop="createTime" label="订单日期" align="center"> </el-table-column>
</el-table-column> <el-table-column prop="createTime" label="订单日期" align="center">
<el-table-column prop="orderType" label="订单类型" align="center"> </el-table-column>
</el-table-column> <el-table-column prop="orderType" label="订单类型" align="center">
<el-table-column prop="orderStatus" label="订单状态" align="center"> </el-table-column>
</el-table-column> <el-table-column prop="orderStatus" label="订单状态" align="center">
<el-table-column prop="orderNature" label="订单性质" align="center"> </el-table-column>
</el-table-column> <el-table-column prop="orderNature" label="订单性质" align="center">
<el-table-column label="操作" align="center"> </el-table-column>
<template slot-scope="scope"> <el-table-column label="操作" align="center">
<el-button type="text" v-if="scope.row.isDel !== 1" @click="handle('edit', scope.row)" v-auth="'/order:修改'"> <template slot-scope="scope">
{{ scope.row.orderStatus === "已完成" ? "修改" : "处理" }} <el-button type="text" v-if="scope.row.isDel!==1" @click="handle('edit',scope.row)" v-auth="'/order:修改'">
</el-button> {{ scope.row.orderStatus === "已完成" ? "修改" : "处理" }}
<el-button type="text" @click="handle('watch', scope.row)" v-auth>查看</el-button> </el-button>
<el-button type="text" @click="handleDelete(scope.row)" v-auth>删除</el-button> <el-button type="text" @click="handle('watch',scope.row)" v-auth>查看</el-button>
<el-button type="text" v-if="scope.row.orderStatus === '已完成' && scope.row.isDel !== 1" <el-button type="text" @click="handleDelete(scope.row)" v-auth>删除</el-button>
@click="handle('renew', scope.row)" v-auth>续费 <el-button type="text" v-if="scope.row.orderStatus==='已完成'&&scope.row.isDel!==1"
</el-button> @click="handle('renew',scope.row)" v-auth>续费
</template> </el-button>
</el-table-column> </template>
</el-table> </el-table-column>
<div class="pagination"> </el-table>
<el-pagination background layout="total, prev, pager, next" @current-change="handleCurrentChange" <div class="pagination">
:current-page="page" :total="totals"> <el-pagination background layout="total, prev, pager, next"
</el-pagination> @current-change="handleCurrentChange" :current-page="pageNo" :total="totals">
</div> </el-pagination>
</el-card> </div>
</div> </el-card>
</div>
</template> </template>
<script> <script>
import qs from 'qs'
export default { export default {
data () { data() {
return { return {
form: { orderParam: this.$store.state.orderParam,
provinceId: +this.$route.query.provinceId || '', form: {
cityId: +this.$route.query.cityId || '', provinces: "",
orderType: +this.$route.query.orderType || '', city: "",
orderStatus: this.$route.query.orderStatus ? +this.$route.query.orderStatus : '', orderType: "",
customerName: this.$route.query.customerName || '' orderStatus: ""
}, },
orderData: [], keyword: "",
multipleSelection: [], orderData: [],
provinceList: this.$store.state.provinceList, multipleSelection: [],
cityList: [], provinceList: this.$store.state.provinceList,
orderTypeList: [{ cityList: [],
name: "正式", orderTypeList: [{
value: 1 name: "正式",
}, value: 1
{ },
name: "试用", {
value: 2 name: "试用",
}], value: 2
orderStatusList: [{ }],
name: "待发货", orderStatusList: [{
value: 0 name: "待发货",
}, value: 0
{ },
name: "已完成", {
value: 1 name: "已完成",
}, value: 1
{ },
name: "已取消", {
value: 2 name: "已取消",
}], value: 2
page: +this.$route.query.page || 1, }],
pageSize: 10, pageNo: +this.$route.query.page || 1,
totals: 0, pageSize: 10,
searchTimer: null, totals: 0,
schools: [] searchTimer: null,
}; schools: []
}, };
watch: {
'form.customerName': function (val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.initData();
}, 500);
}
},
mounted () {
const { query } = this.$route
if (query.page) {
this.$router.push('/order').catch(() => { })
}
this.form.provinceId && this.getCityData()
this.getData()
this.getSchool()
},
methods: {
test (val) {
if (val.length > 5) {
val = 5;
}
},
getData () {
const sid = this.$store.state.dataPer.find(e => e.permissionName === '订单管理')
let data = {
...this.form,
pageNo: this.page,
pageSize: this.pageSize,
supplierId: sid ? sid.supplierId : ''
};
this.$post(this.api.orderList, data).then(res => {
res.orderPage.orders.forEach(e => {
e.orderType = this.orderTypeFn(e.orderType);
e.orderStatus = this.orderStatusFn(e.orderStatus);
e.orderNature = this.orderNatureFn(e.orderNature);
});
this.orderData = res.orderPage.orders;
this.totals = res.orderPage.total;
}).catch(res => { });
},
//
clearprovince () {
this.form.cityId = ''
},
//
getCity () {
this.clearprovince();
this.getCityData();
this.page = 1;
this.getData();
}, },
async getCityData () { watch: {
const { list } = await this.$get(this.api.queryCity, { keyword: function(val) {
provinceId: this.form.provinceId clearTimeout(this.searchTimer);
}) this.searchTimer = setTimeout(() => {
this.cityList = list this.initData();
}, }, 500);
// url
setReferrer () {
this.$router.push(`${this.$route.path}?${qs.stringify(this.form)}&page=${this.page}`)
// this.$store.commit('setReferrer', `${this.$route.path}?${qs.stringify(this.form)}&page=${this.page}`)
},
addOrder () {
this.setReferrer()
this.$router.push({
path: '/AddOrder',
query: {
val: 'isAdd',
}
})
},
handle (val, row) {
this.setReferrer()
let orderStatus
if (row.orderStatus == '已完成') {
orderStatus = 1
} else {
orderStatus = 0
}
this.$router.push({
path: '/AddOrder',
query: {
val: val,
orderId: row.orderId,
orderStatus
} }
})
},
//
getSchool () {
let sid = this.$store.state.dataPer.find(e => e.permissionName === '客户管理')
//
if (!sid) sid = this.$store.state.dataPer.find(e => e.permissionName === '订单管理')
this.$post(this.api.queryCustomer, {
countries: '中国',
provinceId: '',
cityId: '',
searchContent: '',
page: 1,
size: 10000,
// supplierId: sid ? sid.supplierId : ''
}).then(res => {
this.schools = res.message.list
}).catch(res => { })
},
//
refreshCache (customerId) {
this.$post(`${this.api.refreshCache}?schoolId=${this.schools.find(e => e.customerId == customerId).schoolId}`).then(res => { }).catch(res => { })
}, },
// created() {
handleDelete (row) { if (this.orderParam) this.form = this.orderParam
this.$confirm("确定要删除吗?", "提示", { this.getData()
type: "warning" this.getSchool()
}).then(() => {
var arr = [];
arr.push(row.orderId);
this.$post(this.api.orderDelete, { ids: arr }).then(res => {
this.$message.success("删除成功");
this.refreshCache(row.customerId)
this.getData();
}).catch(res => {
});
}).catch(() => {
});
}, },
// methods: {
handleRenew (row) { test(val) {
if (val.length > 5) {
val = 5;
}
},
getData() {
const sid = this.$store.state.dataPer.find(e => e.permissionName === '订单管理')
let data = {
cityId: this.form.city,
customerName: this.keyword,
orderStatus: this.form.orderStatus,
orderType: this.form.orderType,
pageNo: this.pageNo,
pageSize: this.pageSize,
provinceId: this.form.provinces,
supplierId: sid ? sid.supplierId : ''
};
this.$post(this.api.orderList, data).then(res => {
res.orderPage.orders.forEach(e => {
e.orderType = this.orderTypeFn(e.orderType);
e.orderStatus = this.orderStatusFn(e.orderStatus);
e.orderNature = this.orderNatureFn(e.orderNature);
});
this.orderData = res.orderPage.orders;
this.totals = res.orderPage.total;
}).catch(res => {
});
},
//
clearprovince() {
this.form.city = "";
},
//
getCity() {
this.clearprovince();
this.getCityData();
this.pageNo = 1;
this.getData();
},
getCityData() {
let data = {
provinceId: this.form.provinces
};
this.$get(this.api.queryCity, data).then(res => {
this.cityList = res.list;
}).catch(res => {
});
},
addOrder() {
this.$store.commit("systemData", { order_id: "" });
this.$router.push({
path:'/AddOrder',
query:{
val:'isAdd',
}
})
},
handle(val, row) {
let orderStatus
if(row.orderStatus == '已完成'){
orderStatus = 1
}else{
orderStatus = 0
}
this.$store.commit('setOrderParam', this.form)
this.$router.push({
path:'/AddOrder',
query:{
val:val,
orderId:row.orderId,
orderStatus
}
})
// this.$router.push("/addorder?" + val + "=" + row.orderId+"&orderStatus="+orderStatus);
},
//
getSchool() {
let sid = this.$store.state.dataPer.find(e => e.permissionName === '客户管理')
//
if (!sid) sid = this.$store.state.dataPer.find(e => e.permissionName === '订单管理')
this.$post(this.api.queryCustomer, {
countries: '中国',
provinceId: '',
cityId: '',
searchContent: '',
page: 1,
size: 10000,
// supplierId: sid ? sid.supplierId : ''
}).then(res => {
this.schools = res.message.list
}).catch(res => {})
},
//
refreshCache(customerId) {
this.$post(`${this.api.refreshCache}?schoolId=${this.schools.find(e => e.customerId == customerId).schoolId}`).then(res => {}).catch(res => {})
},
//
handleDelete(row) {
this.$confirm("确定要删除吗?", "提示", {
type: "warning"
}).then(() => {
var arr = [];
arr.push(row.orderId);
this.$post(this.api.orderDelete, { ids: arr }).then(res => {
this.$message.success("删除成功");
this.refreshCache(row.customerId)
this.getData();
}).catch(res => {
});
}).catch(() => {
});
},
//
handleRenew(row) {
}, },
handleSelectionChange (val) { handleSelectionChange(val) {
if (val.length > 0) { if (val.length > 0) {
this.multipleSelection = val.map(e => e.orderId); this.multipleSelection = val.map(e => e.orderId);
} else { } else {
this.multipleSelection = []; this.multipleSelection = [];
} }
}, },
delAllSelection () { delAllSelection() {
const list = this.multipleSelection const list = this.multipleSelection
if (list.length != "") { if (list.length != "") {
// //
this.$confirm("确定要删除吗?", "提示", { this.$confirm("确定要删除吗?", "提示", {
type: "warning" type: "warning"
}).then(() => { }).then(() => {
this.$post(this.api.orderDelete, { ids: list }).then(res => { this.$post(this.api.orderDelete, { ids: list }).then(res => {
const { orderData } = this const { orderData } = this
console.log("🚀 ~ file: Order.vue ~ line 299 ~ this.$post ~ message", list, orderData) console.log("🚀 ~ file: Order.vue ~ line 299 ~ this.$post ~ message", list, orderData)
this.$message.success("删除成功"); this.$message.success("删除成功");
this.$refs.table.clearSelection() this.$refs.table.clearSelection()
this.getData();
list.map(e => this.refreshCache(orderData.find(n => n.orderId == e).customerId))
}).catch(err => {
});
}).catch(err => {
});
} else {
this.$message.error("请先选择订单 !");
}
},
initData() {
this.pageNo = 1;
this.getData(); this.getData();
list.map(e => this.refreshCache(orderData.find(n => n.orderId == e).customerId)) },
}).catch(err => { handleCurrentChange(val) {
}); this.pageNo = val;
}).catch(err => { this.$router.push(`order?page=${val}`)
}); this.getData();
} else { },
this.$message.error("请先选择订单 !"); //
} gotoClient() {
}, this.$router.push("");
initData () { }
this.page = 1;
this.getData();
},
handleCurrentChange (val) {
this.page = val;
this.$router.push(`order?page=${val}`)
this.getData();
},
//
gotoClient () {
this.$router.push("");
} }
}
}; };
</script> </script>
<style scoped> <style scoped>
.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; overflow: hidden;
overflow: hidden; text-overflow: ellipsis;
text-overflow: ellipsis; display: -webkit-box;
display: -webkit-box; -webkit-line-clamp: 2;
-webkit-line-clamp: 2; line-clamp: 2;
line-clamp: 2; -webkit-box-orient: vertical;
-webkit-box-orient: vertical;
} }
.tags{
.tags { border: none;
border: none; background: none;color: #000;
background: none; white-space:pre-wrap;
color: #000; width: 140px;
white-space: pre-wrap; overflow: hidden;
width: 140px; text-overflow: ellipsis;
overflow: hidden; display: -webkit-box;
text-overflow: ellipsis; -webkit-line-clamp: 2;
display: -webkit-box; line-clamp: 2;
-webkit-line-clamp: 2; -webkit-box-orient: vertical;
line-clamp: 2;
-webkit-box-orient: vertical;
} }
</style> </style>

File diff suppressed because it is too large Load Diff

@ -1,63 +1,64 @@
<template> <template>
<div class="page system" <div class="page system" style="padding: 0">
style="padding: 0"> <div class="tabs">
<div class="tabs"> <a class="item" v-for="(item,index) in tabs" :key="index" :class="{active: index == active}" @click="tabChange(index)">{{ item }}</a>
<a class="item" </div>
v-for="(item,index) in tabs"
:key="index"
:class="{active: index == active}"
@click="tabChange(index)">{{ item }}</a>
</div>
<learn v-if="active == 'learn'" /> <staff v-if="active == 'staff'"></staff>
<info v-if="active == 'info'" /> <pc-role v-if="active == 'pcRole'"></pc-role>
<plan v-if="active == 'plan'" /> <mobile-role v-if="active == 'mobileRole'"></mobile-role>
</div> </div>
</template> </template>
<script> <script>
import Setting from "@/setting"; import Setting from "@/setting";
import learn from "./learn"; import staff from "./staff";
import info from "./info"; import pcRole from "./pcRole";
import plan from "./plan"; import mobileRole from "./mobileRole";
export default { export default {
data () { data() {
return { return {
active: this.$route.query.type || 'learn', active: this.$route.query.type || 'staff',
tabs: { tabs: {
learn: "合伙人学习管理", staff: "合伙人学习管理",
info: "合伙人资讯管理", pcRole: "合伙人资讯管理",
plan: "方案管理" mobileRole: "方案管理"
} }
}; };
}, },
components: { components: {
learn, staff,
info, pcRole,
plan mobileRole
}, },
created () { created() {
Setting.dynamicRoute && this.initTabs(); Setting.dynamicRoute && this.initTabs();
},
methods: {
tabChange (index) {
this.active = index
this.$router.push(`/parnerOperation?type=${index}`)
}, },
initTabs () { methods: {
const btns = this.$store.state.btns tabChange(index) {
const tab1 = btns.includes('/parnerOperation:合伙人学习管理') this.active = index
const tab2 = btns.includes('/parnerOperation:合伙人资讯管理') this.$router.push({
const tab3 = btns.includes('/parnerOperation:方案管理') path: 'parnerOperation',
query: {
...this.$route.query,
type: index
}
})
},
initTabs() {
const btns = this.$store.state.btns
const tab1 = btns.includes('/parnerOperation:合伙人学习管理')
const tab2 = btns.includes('/parnerOperation:合伙人资讯管理')
const tab3 = btns.includes('/parnerOperation:方案管理')
tab1 || delete this.tabs.learn tab1 || delete this.tabs.staff
tab2 || delete this.tabs.info tab2 || delete this.tabs.pcRole
tab3 || delete this.tabs.plan tab3 || delete this.tabs.mobileRole
const type = this.$route.query.type const type = this.$route.query.type
const keys = Object.keys(this.tabs) const keys = Object.keys(this.tabs)
this.active = keys.includes(type) ? type : keys[0] this.active = keys.includes(type) ? type : keys[0]
}
} }
}
}; };
</script> </script>

@ -1,339 +0,0 @@
<template>
<div class="page">
<div class="tool">
<div class="search-wrap">
<el-select v-model="field"
@change="initData">
<el-option v-for="(item, i) in keywords"
:key="i"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-input class="keyword"
:placeholder="'请输入' + keywords.find(e => e.id === field).name"
v-model.trim="keyword"
clearable></el-input>
</div>
<div class="actions">
<el-button v-auth="'/parnerOperation:合伙人资讯管理:批量删除'"
@click="batchDel">批量删除</el-button>
<el-button v-auth="'/parnerOperation:合伙人资讯管理:新增文章'"
type="primary"
@click="add">新增文章</el-button>
</div>
</div>
<el-table :data="list"
class="table"
ref="table"
header-align="center"
@selection-change="handleSelectionChange"
row-key="id"
@sort-change="sortChange">
<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 show-overflow-tooltip
prop="title"
label="标题"
align="center"
min-width="150"></el-table-column>
<el-table-column prop="classificationName"
label="所属分类"
align="center"
min-width="120"
sortable="custom"></el-table-column>
<el-table-column prop="founderName"
label="录入人"
align="center"
min-width="80"></el-table-column>
<el-table-column prop="editorName"
label="修改人"
align="center"
min-width="80"></el-table-column>
<el-table-column prop="updateTime"
label="修改日期"
align="center"
min-width="150"
sortable="custom"></el-table-column>
<el-table-column prop="releaseTime"
label="发布日期"
align="center"
min-width="100"
sortable="custom"></el-table-column>
<el-table-column prop="learnerNumber"
label="总浏览"
align="center"
min-width="70"></el-table-column>
<el-table-column prop="workNumber"
label="状态"
align="center"
min-width="80">
<template slot-scope="scope">
{{ scope.row.isRelease ? '已发布' : '草稿' }}
</template>
</el-table-column>
<el-table-column prop="sequence"
label="置顶"
align="center"
min-width="80"
sortable="custom">
<template slot-scope="scope">
<i v-if="scope.row.isRelease"
:class="['squ-icon', scope.row.isTop ? 'el-icon-check' : 'el-icon-close']"
@click="sticky(scope.row)"></i>
</template>
</el-table-column>
<el-table-column label="操作"
align="center"
width="210">
<template slot-scope="scope">
<el-button v-auth="'/parnerOperation:合伙人资讯管理:编辑'"
type="text"
@click="edit(scope.row)">编辑</el-button>
<el-button v-auth="'/parnerOperation:合伙人资讯管理:删除'"
type="text"
@click="handleDelete(scope.row)">删除</el-button>
<el-switch v-auth="'/parnerOperation:合伙人资讯管理:禁用'"
v-if="scope.row.isRelease"
class="m-l-10"
v-model="scope.row.isDisable"
:active-value="0"
:inactive-value="1"
@change="switchOff($event, scope.row, scope.$index)">
</el-switch>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background
@current-change="currentChange"
:current-page="page"
layout="total, prev, pager, next"
:total="total"></el-pagination>
</div>
</div>
</template>
<script>
import util from '@/libs/util'
export default {
data () {
return {
field: this.$route.query.field || 'title',
keywords: [
{
id: 'title',
name: '标题'
},
{
id: 'founder',
name: '录入人'
},
{
id: 'editor',
name: '修改人'
}
],
keyword: this.$route.query.keyword || '',
list: [],
page: +this.$route.query.page || 1,
pageSize: 10,
total: 0,
topSort: '',
classificationNameSort: '',
releaseDateSort: '',
editTimeSort: '',
multipleSelection: [],
};
},
watch: {
keyword: function (val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initData()
}, 500)
}
},
mounted () {
const { query } = this.$route
if (query.page) {
this.$router.push('/parnerOperation?type=info').catch(() => { })
}
this.getData()
},
methods: {
//
getData () {
const { keyword } = this
this.$post(this.api.partnerOperatingList, {
pageNum: this.page,
pageSize: this.pageSize,
querySource: 3, //(3. 4.)
topSort: this.topSort,
classificationNameSort: this.classificationNameSort,
editTimeSort: this.editTimeSort,
releaseDateSort: this.releaseDateSort,
typeId: 2, // (1.2.)
title: this.field === 'title' ? keyword : '',
founderName: this.field === 'founder' ? keyword : '',
editorName: this.field === 'editor' ? keyword : ''
}).then(({ page, total }) => {
page.forEach(e => {
e.editing = false
})
this.list = page
this.total = total
}).catch(err => { })
},
currentChange (val) {
this.page = val
this.getData()
},
handleSelectionChange (val) {
this.multipleSelection = val
},
initData () {
this.$refs.table.clearSelection()
this.page = 1
this.getData()
},
//
batchDel () {
const list = this.multipleSelection
if (list.length) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
const data = []
list.map(e => {
data.push('ids=' + e.id)
})
this.$post(`${this.api.batchDeletionParnerArticle}?${data.join('&')}`).then(res => {
this.$refs.table.clearSelection()
util.successMsg("删除成功")
this.getData()
}).catch(res => { })
}).catch(() => { })
} else {
util.errorMsg('请先选择数据 !')
}
},
//
handleDelete (row) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
this.$post(`${this.api.batchDeletionParnerArticle}?ids=${row.id}`).then(res => {
util.successMsg('删除成功')
this.getData()
}).catch(res => { })
}).catch(() => { })
},
//
switchOff (val, row) {
this.$post(`${this.api.articleEnableOrDisable}?id=${row.id}&isDisable=${val}`).then(res => { }).catch((res) => { })
},
//
sortChange (column) {
const { order } = column
// 1
if (column.prop === 'classificationName') {
this.classificationNameSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.releaseDateSort = ''
this.topSort = ''
}
}
if (column.prop === 'updateTime') {
this.editTimeSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.classificationNameSort = ''
this.releaseDateSort = ''
this.topSort = ''
}
}
if (column.prop === 'releaseTime') {
this.releaseDateSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.classificationNameSort = ''
this.topSort = ''
}
}
if (column.prop === 'sequence') {
this.topSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.releaseDateSort = ''
this.classificationNameSort = ''
}
}
this.getData()
},
//
submitSequence (row) {
if (!row.sequence) return Util.errorMsg('请输入排序')
this.$post(`${this.api.modifiedSort}?articleId=${row.id}&sequenceNumber=${row.sequence}`).then(res => {
this.initData()
}).catch(res => { })
},
//
editSequence (row) {
this.list.forEach(e => {
e.editing = false
})
row.editing = true
},
//
sticky (row) {
this.$post(`${this.api.articleTopOperation}?articleId=${row.id}&isTop=${row.isTop ? 0 : 1}`).then(res => {
this.initData()
}).catch(res => { })
},
// url
setReferrer () {
this.$store.commit('setReferrer', `${this.$route.fullPath}&keyword=${this.keyword}&field=${this.field}&page=${this.page}`)
},
//
add () {
this.setReferrer()
this.$router.push(`/learnMg?type=2`)
},
//
edit (row) {
this.setReferrer()
this.$router.push(`/learnMg?id=${row.id}&type=2`)
},
}
};
</script>
<style lang="scss" scoped>
.m-l-10 {
margin-left: 10px;
}
.squ-icon {
font-size: 16px;
font-weight: 600;
cursor: pointer;
color: #f70000;
&.el-icon-check {
color: #05991e;
}
}
/deep/.squ-input {
width: auto;
.el-input__inner {
width: 60px;
padding: 0 10px;
}
}
</style>

@ -1,339 +0,0 @@
<template>
<div class="page">
<div class="tool">
<div class="search-wrap">
<el-select v-model="field"
@change="initData">
<el-option v-for="(item, i) in keywords"
:key="i"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-input class="keyword"
:placeholder="'请输入' + keywords.find(e => e.id === field).name"
v-model.trim="keyword"
clearable></el-input>
</div>
<div class="actions">
<el-button v-auth="'/parnerOperation:合伙人学习管理:批量删除'"
@click="batchDel">批量删除</el-button>
<el-button v-auth="'/parnerOperation:合伙人学习管理:新增文章'"
type="primary"
@click="add">新增文章</el-button>
</div>
</div>
<el-table :data="list"
class="table"
ref="table"
header-align="center"
@selection-change="handleSelectionChange"
row-key="id"
@sort-change="sortChange">
<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 show-overflow-tooltip
prop="title"
label="标题"
align="center"
min-width="150"></el-table-column>
<el-table-column prop="classificationName"
label="所属分类"
align="center"
min-width="120"
sortable="custom"></el-table-column>
<el-table-column prop="founderName"
label="录入人"
align="center"
min-width="80"></el-table-column>
<el-table-column prop="editorName"
label="修改人"
align="center"
min-width="80"></el-table-column>
<el-table-column prop="updateTime"
label="修改日期"
align="center"
min-width="150"
sortable="custom"></el-table-column>
<el-table-column prop="releaseTime"
label="发布日期"
align="center"
min-width="100"
sortable="custom"></el-table-column>
<el-table-column prop="learnerNumber"
label="已学习人数"
align="center"
min-width="70"></el-table-column>
<el-table-column prop="workNumber"
label="状态"
align="center"
min-width="80">
<template slot-scope="scope">
{{ scope.row.isRelease ? '已发布' : '草稿' }}
</template>
</el-table-column>
<el-table-column prop="sequence"
label="置顶"
align="center"
min-width="80"
sortable="custom">
<template slot-scope="scope">
<i v-if="scope.row.isRelease"
:class="['squ-icon', scope.row.isTop ? 'el-icon-check' : 'el-icon-close']"
@click="sticky(scope.row)"></i>
</template>
</el-table-column>
<el-table-column label="操作"
align="center"
width="210">
<template slot-scope="scope">
<el-button v-auth="'/parnerOperation:合伙人学习管理:编辑'"
type="text"
@click="edit(scope.row)">编辑</el-button>
<el-button v-auth="'/parnerOperation:合伙人学习管理:删除'"
type="text"
@click="handleDelete(scope.row)">删除</el-button>
<el-switch v-auth="'/parnerOperation:合伙人学习管理:禁用'"
v-if="scope.row.isRelease"
class="m-l-10"
v-model="scope.row.isDisable"
:active-value="0"
:inactive-value="1"
@change="switchOff($event, scope.row, scope.$index)">
</el-switch>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background
@current-change="currentChange"
:current-page="page"
layout="total, prev, pager, next"
:total="total"></el-pagination>
</div>
</div>
</template>
<script>
import util from '@/libs/util'
export default {
data () {
return {
field: this.$route.query.field || 'title',
keywords: [
{
id: 'title',
name: '标题'
},
{
id: 'founder',
name: '录入人'
},
{
id: 'editor',
name: '修改人'
}
],
keyword: this.$route.query.keyword || '',
list: [],
page: +this.$route.query.page || 1,
pageSize: 10,
total: 0,
topSort: '',
classificationNameSort: '',
releaseDateSort: '',
editTimeSort: '',
multipleSelection: [],
};
},
watch: {
keyword: function (val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initData()
}, 500)
}
},
mounted () {
const { query } = this.$route
if (query.page) {
this.$router.push('/parnerOperation?type=learn').catch(() => { })
}
this.getData()
},
methods: {
//
getData () {
const { keyword } = this
this.$post(this.api.partnerOperatingList, {
pageNum: this.page,
pageSize: this.pageSize,
querySource: 3, //(3. 4.)
topSort: this.topSort,
classificationNameSort: this.classificationNameSort,
editTimeSort: this.editTimeSort,
releaseDateSort: this.releaseDateSort,
typeId: 1, // (1.2.)
title: this.field === 'title' ? keyword : '',
founderName: this.field === 'founder' ? keyword : '',
editorName: this.field === 'editor' ? keyword : ''
}).then(({ page, total }) => {
page.forEach(e => {
e.editing = false
})
this.list = page
this.total = total
}).catch(err => { })
},
currentChange (val) {
this.page = val
this.getData()
},
handleSelectionChange (val) {
this.multipleSelection = val
},
initData () {
this.$refs.table.clearSelection()
this.page = 1
this.getData()
},
//
batchDel () {
const list = this.multipleSelection
if (list.length) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
const data = []
list.map(e => {
data.push('ids=' + e.id)
})
this.$post(`${this.api.batchDeletionParnerArticle}?${data.join('&')}`).then(res => {
this.$refs.table.clearSelection()
util.successMsg("删除成功")
this.getData()
}).catch(res => { })
}).catch(() => { })
} else {
util.errorMsg('请先选择数据 !')
}
},
//
handleDelete (row) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
this.$post(`${this.api.batchDeletionParnerArticle}?ids=${row.id}`).then(res => {
util.successMsg('删除成功')
this.getData()
}).catch(res => { })
}).catch(() => { })
},
//
switchOff (val, row) {
this.$post(`${this.api.articleEnableOrDisable}?id=${row.id}&isDisable=${val}`).then(res => { }).catch((res) => { })
},
//
sortChange (column) {
const { order } = column
// 1
if (column.prop === 'classificationName') {
this.classificationNameSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.releaseDateSort = ''
this.topSort = ''
}
}
if (column.prop === 'updateTime') {
this.editTimeSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.classificationNameSort = ''
this.releaseDateSort = ''
this.topSort = ''
}
}
if (column.prop === 'releaseTime') {
this.releaseDateSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.classificationNameSort = ''
this.topSort = ''
}
}
if (column.prop === 'sequence') {
this.topSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.releaseDateSort = ''
this.classificationNameSort = ''
}
}
this.getData()
},
//
submitSequence (row) {
if (!row.sequence) return Util.errorMsg('请输入排序')
this.$post(`${this.api.modifiedSort}?articleId=${row.id}&sequenceNumber=${row.sequence}`).then(res => {
this.initData()
}).catch(res => { })
},
//
editSequence (row) {
this.list.forEach(e => {
e.editing = false
})
row.editing = true
},
//
sticky (row) {
this.$post(`${this.api.articleTopOperation}?articleId=${row.id}&isTop=${row.isTop ? 0 : 1}`).then(res => {
this.initData()
}).catch(res => { })
},
// url
setReferrer () {
this.$store.commit('setReferrer', `${this.$route.fullPath}&keyword=${this.keyword}&field=${this.field}&page=${this.page}`)
},
//
add () {
this.setReferrer()
this.$router.push(`/learnMg?type=1`)
},
//
edit (row) {
this.setReferrer()
this.$router.push(`/learnMg?id=${row.id}&type=1`)
},
}
};
</script>
<style lang="scss" scoped>
.m-l-10 {
margin-left: 10px;
}
.squ-icon {
font-size: 16px;
font-weight: 600;
cursor: pointer;
color: #f70000;
&.el-icon-check {
color: #05991e;
}
}
/deep/.squ-input {
width: auto;
.el-input__inner {
width: 60px;
padding: 0 10px;
}
}
</style>

@ -125,7 +125,7 @@
accept=".jpg,.png,.jpeg,.gif" accept=".jpg,.png,.jpeg,.gif"
:on-change="changeFile" :on-change="changeFile"
:show-file-list="false" :show-file-list="false"
action="" :action="this.api.fileupload"
:auto-upload="false"> :auto-upload="false">
<img v-if="form.bannerImg" <img v-if="form.bannerImg"
:src="form.bannerImg" :src="form.bannerImg"
@ -147,11 +147,14 @@
</el-form-item> </el-form-item>
<el-form-item prop="file" <el-form-item prop="file"
label="文件上传"> label="文件上传">
<Upload :limit="20" <el-upload :before-upload="fileBeforeUpload"
:changeFileList="false" :on-remove="handleRemove"
:file-list.sync="form.fileList" :on-success="uploadSuccessFile"
:on-remove="handleRemove" :action="this.api.fileUploadNakadai"
@onSuccess="uploadSuccessFile" /> :file-list="form.fileList"
:headers="headers">
<el-button>上传</el-button>
</el-upload>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div class="btns"> <div class="btns">
@ -294,9 +297,6 @@ import Editor from '@tinymce/tinymce-vue'
import editorConfig from '@/utils/editor' import editorConfig from '@/utils/editor'
import Cropper from '@/components/img-upload/Cropper' import Cropper from '@/components/img-upload/Cropper'
import Axios from 'axios' import Axios from 'axios'
import Upload from '@/components/upload';
import Oss from '@/components/upload/upload.js'
export default { export default {
data () { data () {
return { return {
@ -356,8 +356,7 @@ export default {
}, },
components: { components: {
Editor, Editor,
Cropper, Cropper
Upload
}, },
watch: { watch: {
// , // ,
@ -376,11 +375,11 @@ export default {
// //
if (this.updateTime) { if (this.updateTime) {
this.$confirm(`所填写内容暂未保存,是否保存?`, '提示', { this.$confirm(`所填写内容暂未保存,是否保存?`, '提示', {
type: 'warning', type: 'warning'
closeOnClickModal: false
}).then(() => { }).then(() => {
this.submit(this.form.isRelease, next) this.submit(this.form.isRelease, next)
}).catch(() => { }).catch(() => {
console.log(55)
next() next()
}) })
} else { } else {
@ -425,19 +424,15 @@ export default {
}, },
// //
addClass () { addClass () {
this.classifications.find(e => e.edit) ? this.classifications.push({
Util.errorMsg('请先保存分类!') : edit: true,
this.classifications.push({ id: '',
edit: true, classificationName: ''
id: '', })
classificationName: ''
})
}, },
// //
editClass (row) { editClass (row) {
this.classifications.find(e => e.edit) ? this.$set(row, 'edit', 1)
Util.errorMsg('请先保存分类!') :
this.$set(row, 'edit', 1)
}, },
// //
delClass (row, i) { delClass (row, i) {
@ -473,8 +468,7 @@ export default {
const list = this.classifications const list = this.classifications
if (list.find(e => e.edit && e.classificationName)) { if (list.find(e => e.edit && e.classificationName)) {
this.$confirm('所填写内容暂未保存,是否保存?', '提示', { this.$confirm('所填写内容暂未保存,是否保存?', '提示', {
type: 'warning', type: 'warning'
closeOnClickModal: false
}).then(() => { }).then(() => {
list.map(e => { list.map(e => {
e.edit && e.classificationName && this.submitClass(e, 0) e.edit && e.classificationName && this.submitClass(e, 0)
@ -502,19 +496,15 @@ export default {
}, },
// //
addLabel () { addLabel () {
this.labels.find(e => e.edit) ? this.labels.push({
Util.errorMsg('请先保存主题!') : edit: true,
this.labels.push({ id: '',
edit: true, labelName: ''
id: '', })
labelName: ''
})
}, },
// //
editLabel (row) { editLabel (row) {
this.labels.find(e => e.edit) ? this.$set(row, 'edit', 1)
Util.errorMsg('请先保存主题!') :
this.$set(row, 'edit', 1)
}, },
// //
delLabel (row, i) { delLabel (row, i) {
@ -549,8 +539,7 @@ export default {
const list = this.labels const list = this.labels
if (list.find(e => e.edit && e.labelName)) { if (list.find(e => e.edit && e.labelName)) {
this.$confirm('所填写内容暂未保存,是否保存?', '提示', { this.$confirm('所填写内容暂未保存,是否保存?', '提示', {
type: 'warning', type: 'warning'
closeOnClickModal: false
}).then(() => { }).then(() => {
list.map(e => { list.map(e => {
e.edit && e.labelName && this.submitLabel(e, 0) e.edit && e.labelName && this.submitLabel(e, 0)
@ -583,17 +572,61 @@ export default {
}, },
// //
customUpload (data) { customUpload (data) {
data.name = this.file.name const formData = new FormData()
this.imgUpload(data) formData.append('file', data, this.file.name)
this.imgUpload(formData)
},
//
compress (img) {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
// let initSize = img.src.length;
const width = img.width
const height = img.height
canvas.width = width
canvas.height = height
//
ctx.fillStyle = '#fff'
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(img, 0, 0, width, height)
//
const ndata = canvas.toDataURL('image/jpeg', 0.8)
return ndata
},
// base64bolb
dataURItoBlob (base64Data) {
let byteString
if (base64Data.split(',')[0].indexOf('base64') >= 0) {
byteString = atob(base64Data.split(',')[1])
} else {
byteString = unescape(base64Data.split(',')[1])
}
const mimeString = base64Data
.split(',')[0]
.split(':')[1]
.split(';')[0]
const ia = new Uint8Array(byteString.length)
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i)
}
return new Blob([ia], {
type: mimeString
})
}, },
// //
imgUpload (formData) { imgUpload (formData) {
this.isUpload = true this.isUpload = true
Oss.upload(formData).then(res => { Axios({
this.form.bannerImg && Oss.del(this.form.bannerImg) method: 'post',
this.form.bannerImg = res.url url: this.api.fileUploadNakadai,
}) data: formData,
headers: {
'Content-Type': 'multipart/form-data',
...this.headers
},
}).then(({ data }) => {
this.form.bannerImg = data.filesResult.fileUrl
}).catch(res => { })
this.$refs.cropper.isDisabled = false this.$refs.cropper.isDisabled = false
this.isUpload = false this.isUpload = false
this.cropperModel = false this.cropperModel = false
@ -621,69 +654,71 @@ export default {
}, },
// //
handleRemove (e, fileList) { handleRemove (e, fileList) {
Oss.del(e.filePath)
e.id ? this.$post(`${this.api.batchDeletionParnerFile}?ids=${e.id}`).then(res => { e.id ? this.$post(`${this.api.batchDeletionParnerFile}?ids=${e.id}`).then(res => {
this.form.fileList = fileList this.form.fileList = fileList
}).catch(res => { }) : (this.form.fileList = fileList) }).catch(res => { }) : (this.form.fileList = fileList)
}, },
// banner
uploadSuccessBanner (res) {
let url = this.form.bannerImg
url && this.$del(this.api.delFile, [url.split('/').pop()]).then(res => { }).catch(e => { })
this.form.bannerImg = res.url
},
// //
fileBeforeUpload (file) { fileBeforeUpload (file) {
this.uploading++ this.uploading++
}, },
// //
uploadSuccessFile (file) { uploadSuccessFile (res) {
const { name, url } = file const { originalFileName, fileUrl } = res.filesResult
this.uploading-- this.uploading--
this.form.id ? this.form.id ?
this.$post(this.api.saveParnerFile, { this.$post(this.api.saveParnerFile, {
contentId: this.form.id, contentId: this.form.id,
id: '', id: '',
fileName: name, fileName: originalFileName,
filePath: url filePath: fileUrl
}).then(({ data }) => { }).then(({ data }) => {
this.form.fileList.push({ this.form.fileList.push({
fileName: name, fileName: originalFileName,
filePath: url, filePath: fileUrl,
name: name, name: originalFileName,
url, url: fileUrl,
id: data id: data
}) })
}).catch(res => { }) : }).catch(res => { }) :
this.form.fileList.push({ this.form.fileList.push({
fileName: name, fileName: originalFileName,
filePath: url, filePath: fileUrl,
name: name, name: originalFileName,
url url: fileUrl
}) })
}, },
// //
preview () { preview () {
window.open((Setting.isDev ? `http://${location.hostname}:8095` : this.$store.state.content.site.domainName) + `#/article?articleId=${this.form.id}&siteId=${this.form.siteId}&id=${this.form.columnId}`) window.open((Setting.isDev ? `http://${location.hostname}:8095` : this.$store.state.content.site.domainName) + `#/article?articleId=${this.form.id}&siteId=${this.form.siteId}&id=${this.form.columnId}`)
}, },
backPage () {
this.$router.push(this.$store.state.referrer || '/parnerOperation')
},
// //
back () { back () {
this.pass = true this.pass = true
// //
if (this.updateTime) { if (this.updateTime) {
this.$confirm(`所填写内容暂未保存,是否保存?`, '提示', { this.$confirm(`所填写内容暂未保存,是否保存?`, '提示', {
type: 'warning', type: 'warning'
closeOnClickModal: false
}).then(() => { }).then(() => {
this.submit(this.form.isRelease) this.submit(this.form.isRelease)
}).catch(() => { }).catch(() => {
this.backPage() this.$router.back()
}) })
} else { } else {
this.backPage() this.$router.back()
} }
}, },
// //
submit (isRelease, next) { submit (isRelease, next) {
if (this.submiting) return false if (this.submiting) return false
const form = JSON.parse(JSON.stringify(this.form)) const form = JSON.parse(JSON.stringify(this.form))
console.log('form=>', form)
if (!form.title) return Util.errorMsg('请填写标题') if (!form.title) return Util.errorMsg('请填写标题')
if (this.nameRepeat) return Util.errorMsg('该标题已重复!') if (this.nameRepeat) return Util.errorMsg('该标题已重复!')
// //
@ -704,7 +739,7 @@ export default {
delete form.children delete form.children
this.$post(this.api.updateParnerArticle, form).then(res => { this.$post(this.api.updateParnerArticle, form).then(res => {
Util.successMsg('修改成功') Util.successMsg('修改成功')
next ? next() : this.backPage() next ? next() : this.$router.back()
}).catch(err => { }).catch(err => {
this.submiting = false this.submiting = false
}) })

@ -0,0 +1,221 @@
<template>
<div class="page">
<div class="tool">
<div class="search-wrap">
<el-select v-model="field" @change="initData">
<el-option
v-for="(item, i) in keywords"
:key="i"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-input class="keyword" :placeholder="'请输入' + keywords.find(e => e.id === field).name" v-model.trim="keyword" clearable></el-input>
</div>
<div class="actions">
<el-button v-auth="'/parnerOperation:方案管理:批量删除'" @click="batchDel">批量删除</el-button>
<el-button v-auth="'/parnerOperation:方案管理:新增文章'" type="primary" @click="add" >新增文章</el-button>
</div>
</div>
<el-table :data="list" class="table" ref="table" header-align="center" @selection-change="handleSelectionChange" row-key="id" @sort-change="sortChange">
<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 show-overflow-tooltip prop="title" label="标题" align="center" min-width="150"></el-table-column>
<el-table-column prop="classificationName" label="所属分类" align="center" min-width="120" sortable="custom"></el-table-column>
<el-table-column prop="founderName" label="录入人" align="center" min-width="80"></el-table-column>
<el-table-column prop="editorName" label="修改人" align="center" min-width="80"></el-table-column>
<el-table-column prop="updateTime" label="修改日期" align="center" min-width="150" sortable="custom"></el-table-column>
<el-table-column prop="createTime" label="发布日期" align="center" min-width="100" sortable="custom"></el-table-column>
<el-table-column prop="workNumber" label="状态" align="center" min-width="80">
<template slot-scope="scope">
{{ scope.row.isRelease ? '已发布' : '草稿' }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="170">
<template slot-scope="scope">
<el-button v-auth="'/parnerOperation:方案管理:编辑'" type="text" @click="edit(scope.row)">编辑</el-button>
<el-button v-auth="'/parnerOperation:方案管理:删除'" type="text" @click="handleDelete(scope.row)">删除</el-button>
<el-switch
v-auth="'/parnerOperation:方案管理:禁用'"
v-if="scope.row.isRelease"
class="m-l-10"
v-model="scope.row.isDisable"
:active-value="0"
:inactive-value="1"
@change="switchOff($event, scope.row, scope.$index)">
</el-switch>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next" :total="total"></el-pagination>
</div>
</div>
</template>
<script>
import util from '@/libs/util'
export default {
data() {
return {
field: 'title',
keywords: [
{
id: 'title',
name: '标题'
},
{
id: 'founder',
name: '录入人'
},
{
id: 'editor',
name: '修改人'
}
],
keyword: '',
list: [],
page: 1,
pageSize: 10,
total: 0,
modifiedTimeSort: '',
releaseDateSort: 'desc',
classificationNameSort: '',
editTimeSort: '',
multipleSelection: [],
};
},
watch: {
keyword: function(val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initData()
}, 500)
}
},
mounted() {
this.getData()
},
methods: {
//
getData() {
const { keyword } = this
const data = {
pageNum: this.page,
pageSize: this.pageSize,
querySource: 3, //(3. 4.)
classificationNameSort: this.classificationNameSort,
editTimeSort: this.editTimeSort,
createTimeSort: this.releaseDateSort,
title: this.field === 'title' ? keyword : '',
founderName: this.field === 'founder' ? keyword : '',
editorName: this.field === 'editor' ? keyword : ''
}
this.$post(this.api.schemeList, data).then(({ data }) => {
this.list = data.records
this.total = +data.total
}).catch(err => {})
},
currentChange(val) {
this.page = val
this.getData()
},
handleSelectionChange(val) {
this.multipleSelection = val
},
initData() {
this.$refs.table.clearSelection()
this.page = 1
this.getData()
},
//
batchDel() {
const list = this.multipleSelection
if (list.length) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
const data = []
list.map(e => {
data.push('ids=' + e.id)
})
this.$post(`${this.api.batchDeletionScheme}?${data.join('&')}`).then(res => {
this.$refs.table.clearSelection()
util.successMsg("删除成功")
this.getData()
}).catch(res => {})
}).catch(() => {})
} else {
util.errorMsg('请先选择数据 !')
}
},
//
handleDelete(row) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
this.$post(`${this.api.batchDeletionScheme}?ids=${row.id}`).then(res => {
util.successMsg('删除成功')
this.getData()
}).catch(res => {})
}).catch(() => {})
},
//
switchOff(val, row) {
this.$post(`${this.api.enableOrDisableScheme}?id=${row.id}&isDisable=${val}`).then(res => {}).catch((res) => {})
},
//
add() {
this.$router.push(`/schemeSet`)
},
//
sortChange(column) {
const { order } = column
// 1
if (column.prop === 'classificationName') {
this.classificationNameSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.releaseDateSort = ''
this.sequenceSort = ''
}
}
if (column.prop === 'updateTime') {
this.editTimeSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.classificationNameSort = ''
this.releaseDateSort = ''
this.sequenceSort = ''
}
}
if (column.prop === 'createTime') {
this.releaseDateSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.classificationNameSort = ''
this.sequenceSort = ''
}
}
if (column.prop === 'sequence') {
this.sequenceSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.releaseDateSort = ''
this.classificationNameSort = ''
}
}
this.getData()
},
//
edit(row) {
this.$router.push(`/schemeSet?id=${row.id}`)
},
}
};
</script>
<style lang="scss" scoped>
.m-l-10 {
margin-left: 10px;
}
</style>

@ -0,0 +1,269 @@
<template>
<div class="page">
<div class="tool">
<div class="search-wrap">
<el-select v-model="field" @change="initData">
<el-option
v-for="(item, i) in keywords"
:key="i"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-input class="keyword" :placeholder="'请输入' + keywords.find(e => e.id === field).name" v-model.trim="keyword" clearable></el-input>
</div>
<div class="actions">
<el-button v-auth="'/parnerOperation:合伙人资讯管理:批量删除'" @click="batchDel">批量删除</el-button>
<el-button v-auth="'/parnerOperation:合伙人资讯管理:新增文章'" type="primary" @click="add" >新增文章</el-button>
</div>
</div>
<el-table :data="list" class="table" ref="table" header-align="center" @selection-change="handleSelectionChange" row-key="id" @sort-change="sortChange">
<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 show-overflow-tooltip prop="title" label="标题" align="center" min-width="150"></el-table-column>
<el-table-column prop="classificationName" label="所属分类" align="center" min-width="120" sortable="custom"></el-table-column>
<el-table-column prop="founderName" label="录入人" align="center" min-width="80"></el-table-column>
<el-table-column prop="editorName" label="修改人" align="center" min-width="80"></el-table-column>
<el-table-column prop="updateTime" label="修改日期" align="center" min-width="150" sortable="custom"></el-table-column>
<el-table-column prop="releaseTime" label="发布日期" align="center" min-width="100" sortable="custom"></el-table-column>
<el-table-column prop="learnerNumber" label="总浏览" align="center" min-width="70"></el-table-column>
<el-table-column prop="workNumber" label="状态" align="center" min-width="80">
<template slot-scope="scope">
{{ scope.row.isRelease ? '已发布' : '草稿' }}
</template>
</el-table-column>
<el-table-column prop="sequence" label="置顶" align="center" min-width="80" sortable="custom">
<template slot-scope="scope">
<i v-if="scope.row.isRelease" :class="['squ-icon', scope.row.isTop ? 'el-icon-check' : 'el-icon-close']" @click="sticky(scope.row)"></i>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="210">
<template slot-scope="scope">
<el-button v-auth="'/parnerOperation:合伙人资讯管理:编辑'" type="text" @click="edit(scope.row)">编辑</el-button>
<el-button v-auth="'/parnerOperation:合伙人资讯管理:删除'" type="text" @click="handleDelete(scope.row)">删除</el-button>
<el-switch
v-auth="'/parnerOperation:合伙人资讯管理:禁用'"
v-if="scope.row.isRelease"
class="m-l-10"
v-model="scope.row.isDisable"
:active-value="0"
:inactive-value="1"
@change="switchOff($event, scope.row, scope.$index)">
</el-switch>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next" :total="total"></el-pagination>
</div>
</div>
</template>
<script>
import Setting from '@/setting'
import util from '@/libs/util'
import { mapMutations } from 'vuex'
export default {
data() {
return {
field: 'title',
keywords: [
{
id: 'title',
name: '标题'
},
{
id: 'founder',
name: '录入人'
},
{
id: 'editor',
name: '修改人'
}
],
keyword: '',
list: [],
page: 1,
pageSize: 10,
total: 0,
topSort: '',
classificationNameSort: '',
releaseDateSort: '',
editTimeSort: '',
multipleSelection: [],
};
},
watch: {
keyword: function(val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initData()
}, 500)
}
},
mounted() {
this.getData()
},
methods: {
//
getData() {
const { keyword } = this
this.$post(this.api.partnerOperatingList, {
pageNum: this.page,
pageSize: this.pageSize,
querySource: 3, //(3. 4.)
topSort: this.topSort,
classificationNameSort: this.classificationNameSort,
editTimeSort: this.editTimeSort,
releaseDateSort: this.releaseDateSort,
typeId: 2, // (1.2.)
title: this.field === 'title' ? keyword : '',
founderName: this.field === 'founder' ? keyword : '',
editorName: this.field === 'editor' ? keyword : ''
}).then(({ page, total }) => {
page.forEach(e => {
e.editing = false
})
this.list = page
this.total = total
}).catch(err => {})
},
currentChange(val) {
this.page = val
this.getData()
},
handleSelectionChange(val) {
this.multipleSelection = val
},
initData() {
this.$refs.table.clearSelection()
this.page = 1
this.getData()
},
//
batchDel() {
const list = this.multipleSelection
if (list.length) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
const data = []
list.map(e => {
data.push('ids=' + e.id)
})
this.$post(`${this.api.batchDeletionParnerArticle}?${data.join('&')}`).then(res => {
this.$refs.table.clearSelection()
util.successMsg("删除成功")
this.getData()
}).catch(res => {})
}).catch(() => {})
} else {
util.errorMsg('请先选择数据 !')
}
},
//
handleDelete(row) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
this.$post(`${this.api.batchDeletionParnerArticle}?ids=${row.id}`).then(res => {
util.successMsg('删除成功')
this.getData()
}).catch(res => {})
}).catch(() => {})
},
//
switchOff(val, row) {
this.$post(`${this.api.articleEnableOrDisable}?id=${row.id}&isDisable=${val}`).then(res => {}).catch((res) => {})
},
//
add() {
this.$router.push(`/learnMg?type=2`)
},
//
sortChange(column) {
const { order } = column
// 1
if (column.prop === 'classificationName') {
this.classificationNameSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.releaseDateSort = ''
this.topSort = ''
}
}
if (column.prop === 'updateTime') {
this.editTimeSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.classificationNameSort = ''
this.releaseDateSort = ''
this.topSort = ''
}
}
if (column.prop === 'releaseTime') {
this.releaseDateSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.classificationNameSort = ''
this.topSort = ''
}
}
if (column.prop === 'sequence') {
this.topSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.releaseDateSort = ''
this.classificationNameSort = ''
}
}
this.getData()
},
//
submitSequence(row) {
if (!row.sequence) return Util.errorMsg('请输入排序')
this.$post(`${this.api.modifiedSort}?articleId=${row.id}&sequenceNumber=${row.sequence}`).then(res => {
this.initData()
}).catch(res => {})
},
//
editSequence(row) {
this.list.forEach(e => {
e.editing = false
})
row.editing = true
},
//
sticky(row) {
this.$post(`${this.api.articleTopOperation}?articleId=${row.id}&isTop=${row.isTop ? 0 : 1}`).then(res => {
this.initData()
}).catch(res => {})
},
//
edit(row) {
this.$router.push(`/learnMg?id=${row.id}&type=2`)
},
}
};
</script>
<style lang="scss" scoped>
.m-l-10 {
margin-left: 10px;
}
.squ-icon {
font-size: 16px;
font-weight: 600;
cursor: pointer;
color: #f70000;
&.el-icon-check {
color: #05991e;
}
}
/deep/.squ-input {
width: auto;
.el-input__inner {
width: 60px;
padding: 0 10px;
}
}
</style>

@ -1,279 +0,0 @@
<template>
<div class="page">
<div class="tool">
<div class="search-wrap">
<el-select v-model="field"
@change="initData">
<el-option v-for="(item, i) in keywords"
:key="i"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-input class="keyword"
:placeholder="'请输入' + keywords.find(e => e.id === field).name"
v-model.trim="keyword"
clearable></el-input>
</div>
<div class="actions">
<el-button v-auth="'/parnerOperation:方案管理:批量删除'"
@click="batchDel">批量删除</el-button>
<el-button v-auth="'/parnerOperation:方案管理:新增文章'"
type="primary"
@click="add">新增文章</el-button>
</div>
</div>
<el-table :data="list"
class="table"
ref="table"
header-align="center"
@selection-change="handleSelectionChange"
row-key="id"
@sort-change="sortChange">
<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 show-overflow-tooltip
prop="title"
label="标题"
align="center"
min-width="150"></el-table-column>
<el-table-column prop="classificationName"
label="所属分类"
align="center"
min-width="120"
sortable="custom"></el-table-column>
<el-table-column prop="founderName"
label="录入人"
align="center"
min-width="80"></el-table-column>
<el-table-column prop="editorName"
label="修改人"
align="center"
min-width="80"></el-table-column>
<el-table-column prop="updateTime"
label="修改日期"
align="center"
min-width="150"
sortable="custom"></el-table-column>
<el-table-column prop="createTime"
label="发布日期"
align="center"
min-width="100"
sortable="custom"></el-table-column>
<el-table-column prop="workNumber"
label="状态"
align="center"
min-width="80">
<template slot-scope="scope">
{{ scope.row.isRelease ? '已发布' : '草稿' }}
</template>
</el-table-column>
<el-table-column label="操作"
align="center"
width="170">
<template slot-scope="scope">
<el-button v-auth="'/parnerOperation:方案管理:编辑'"
type="text"
@click="edit(scope.row)">编辑</el-button>
<el-button v-auth="'/parnerOperation:方案管理:删除'"
type="text"
@click="handleDelete(scope.row)">删除</el-button>
<el-switch v-auth="'/parnerOperation:方案管理:禁用'"
v-if="scope.row.isRelease"
class="m-l-10"
v-model="scope.row.isDisable"
:active-value="0"
:inactive-value="1"
@change="switchOff($event, scope.row, scope.$index)">
</el-switch>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background
@current-change="currentChange"
:current-page="page"
layout="total, prev, pager, next"
:total="total"></el-pagination>
</div>
</div>
</template>
<script>
import util from '@/libs/util'
export default {
data () {
return {
field: this.$route.query.field || 'title',
keywords: [
{
id: 'title',
name: '标题'
},
{
id: 'founder',
name: '录入人'
},
{
id: 'editor',
name: '修改人'
}
],
keyword: this.$route.query.keyword || '',
list: [],
page: +this.$route.query.page || 1,
pageSize: 10,
total: 0,
modifiedTimeSort: '',
releaseDateSort: 'desc',
classificationNameSort: '',
editTimeSort: '',
multipleSelection: [],
};
},
watch: {
keyword: function (val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initData()
}, 500)
}
},
mounted () {
this.getData()
},
methods: {
//
getData () {
const { keyword } = this
const data = {
pageNum: this.page,
pageSize: this.pageSize,
querySource: 3, //(3. 4.)
classificationNameSort: this.classificationNameSort,
editTimeSort: this.editTimeSort,
createTimeSort: this.releaseDateSort,
title: this.field === 'title' ? keyword : '',
founderName: this.field === 'founder' ? keyword : '',
editorName: this.field === 'editor' ? keyword : ''
}
this.$post(this.api.schemeList, data).then(({ data }) => {
this.list = data.records
this.total = +data.total
}).catch(err => { })
},
currentChange (val) {
this.page = val
this.getData()
},
handleSelectionChange (val) {
this.multipleSelection = val
},
initData () {
this.$refs.table.clearSelection()
this.page = 1
this.getData()
},
//
batchDel () {
const list = this.multipleSelection
if (list.length) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
const data = []
list.map(e => {
data.push('ids=' + e.id)
})
this.$post(`${this.api.batchDeletionScheme}?${data.join('&')}`).then(res => {
this.$refs.table.clearSelection()
util.successMsg("删除成功")
this.getData()
}).catch(res => { })
}).catch(() => { })
} else {
util.errorMsg('请先选择数据 !')
}
},
//
handleDelete (row) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
this.$post(`${this.api.batchDeletionScheme}?ids=${row.id}`).then(res => {
util.successMsg('删除成功')
this.getData()
}).catch(res => { })
}).catch(() => { })
},
//
switchOff (val, row) {
this.$post(`${this.api.enableOrDisableScheme}?id=${row.id}&isDisable=${val}`).then(res => { }).catch((res) => { })
},
//
sortChange (column) {
const { order } = column
// 1
if (column.prop === 'classificationName') {
this.classificationNameSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.releaseDateSort = ''
this.sequenceSort = ''
}
}
if (column.prop === 'updateTime') {
this.editTimeSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.classificationNameSort = ''
this.releaseDateSort = ''
this.sequenceSort = ''
}
}
if (column.prop === 'createTime') {
this.releaseDateSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.classificationNameSort = ''
this.sequenceSort = ''
}
}
if (column.prop === 'sequence') {
this.sequenceSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.releaseDateSort = ''
this.classificationNameSort = ''
}
}
this.getData()
},
// url
setReferrer () {
this.$store.commit('setReferrer', `${this.$route.fullPath}&keyword=${this.keyword}&field=${this.field}&page=${this.page}`)
},
//
add () {
this.setReferrer()
this.$router.push(`/schemeSet`)
},
//
edit (row) {
this.setReferrer()
this.$router.push(`/schemeSet?id=${row.id}`)
},
}
};
</script>
<style lang="scss" scoped>
.m-l-10 {
margin-left: 10px;
}
</style>

@ -77,10 +77,15 @@
</el-form-item> </el-form-item>
<el-form-item prop="schemeFile" <el-form-item prop="schemeFile"
label="方案文件"> label="方案文件">
<Upload :max-size="100000" <el-upload :before-upload="fileBeforeUpload"
:file-list.sync="fileList" :on-success="uploadSuccessFile"
:on-remove="handleRemove" :action="this.api.fileUploadNakadai"
@onSuccess="uploadSuccessFile" /> :file-list="fileList"
:limit="1"
:on-exceed="handleExceed"
:headers="headers">
<el-button>上传</el-button>
</el-upload>
</el-form-item> </el-form-item>
</el-form> </el-form>
<div class="btns"> <div class="btns">
@ -259,8 +264,6 @@ import Util from '@/libs/util'
import Editor from '@tinymce/tinymce-vue' import Editor from '@tinymce/tinymce-vue'
import editorConfig from '@/utils/editor' import editorConfig from '@/utils/editor'
import Cropper from '@/components/img-upload/Cropper' import Cropper from '@/components/img-upload/Cropper'
import Upload from '@/components/upload';
import Oss from '@/components/upload/upload.js'
import Axios from 'axios' import Axios from 'axios'
export default { export default {
data () { data () {
@ -329,8 +332,7 @@ export default {
}, },
components: { components: {
Editor, Editor,
Cropper, Cropper
Upload
}, },
watch: { watch: {
// , // ,
@ -355,8 +357,7 @@ export default {
// //
if (this.updateTime) { if (this.updateTime) {
this.$confirm(`所填写内容暂未保存,是否保存?`, '提示', { this.$confirm(`所填写内容暂未保存,是否保存?`, '提示', {
type: 'warning', type: 'warning'
closeOnClickModal: false
}).then(() => { }).then(() => {
this.submit(this.form.isRelease, next) this.submit(this.form.isRelease, next)
}).catch(() => { }).catch(() => {
@ -403,19 +404,15 @@ export default {
}, },
// //
addClass () { addClass () {
this.classifications.find(e => e.edit) ? this.classifications.push({
Util.errorMsg('请先保存分类!') : edit: true,
this.classifications.push({ id: '',
edit: true, classificationName: ''
id: '', })
classificationName: ''
})
}, },
// //
editClass (row) { editClass (row) {
this.classifications.find(e => e.edit) ? this.$set(row, 'edit', 1)
Util.errorMsg('请先保存分类!') :
this.$set(row, 'edit', 1)
}, },
// //
delClass (row, i) { delClass (row, i) {
@ -451,8 +448,7 @@ export default {
const list = this.classifications const list = this.classifications
if (list.find(e => e.edit && e.classificationName)) { if (list.find(e => e.edit && e.classificationName)) {
this.$confirm('所填写内容暂未保存,是否保存?', '提示', { this.$confirm('所填写内容暂未保存,是否保存?', '提示', {
type: 'warning', type: 'warning'
closeOnClickModal: false
}).then(() => { }).then(() => {
list.map(e => { list.map(e => {
e.edit && e.classificationName && this.submitClass(e, 0) e.edit && e.classificationName && this.submitClass(e, 0)
@ -556,17 +552,10 @@ export default {
fileBeforeUpload (file) { fileBeforeUpload (file) {
this.uploading++ this.uploading++
}, },
//
handleRemove () {
Oss.del(this.form.schemeFile)
this.fileList = []
this.form.fileName = ''
this.form.schemeFile = ''
},
// //
uploadSuccessFile (file) { uploadSuccessFile ({ filesResult }) {
this.form.fileName = file.name this.form.fileName = filesResult.originalFileName
this.form.schemeFile = file.url this.form.schemeFile = filesResult.fileUrl
}, },
// //
handleExceed (files, fileList) { handleExceed (files, fileList) {
@ -574,24 +563,20 @@ export default {
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!` `当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
) )
}, },
backPage () {
this.$router.push(this.$store.state.referrer || '/parnerOperation?type=plan')
},
// //
back () { back () {
this.pass = true this.pass = true
// //
if (this.updateTime) { if (this.updateTime) {
this.$confirm(`所填写内容暂未保存,是否保存?`, '提示', { this.$confirm(`所填写内容暂未保存,是否保存?`, '提示', {
type: 'warning', type: 'warning'
closeOnClickModal: false
}).then(() => { }).then(() => {
this.submit(this.form.isRelease) this.submit(this.form.isRelease)
}).catch(() => { }).catch(() => {
this.backPage() this.$router.back()
}) })
} else { } else {
this.backPage() this.$router.back()
} }
}, },
// //
@ -625,7 +610,7 @@ export default {
if (form.id) { if (form.id) {
this.$post(this.api.updateScheme, form).then(res => { this.$post(this.api.updateScheme, form).then(res => {
Util.successMsg('修改成功') Util.successMsg('修改成功')
next ? next() : this.backPage() next ? next() : this.$router.back()
}).catch(err => { }).catch(err => {
this.submiting = false this.submiting = false
}) })

@ -0,0 +1,268 @@
<template>
<div class="page">
<div class="tool">
<div class="search-wrap">
<el-select v-model="field" @change="initData">
<el-option
v-for="(item, i) in keywords"
:key="i"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
<el-input class="keyword" :placeholder="'请输入' + keywords.find(e => e.id === field).name" v-model.trim="keyword" clearable></el-input>
</div>
<div class="actions">
<el-button v-auth="'/parnerOperation:合伙人学习管理:批量删除'" @click="batchDel">批量删除</el-button>
<el-button v-auth="'/parnerOperation:合伙人学习管理:新增文章'" type="primary" @click="add" >新增文章</el-button>
</div>
</div>
<el-table :data="list" class="table" ref="table" header-align="center" @selection-change="handleSelectionChange" row-key="id" @sort-change="sortChange">
<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 show-overflow-tooltip prop="title" label="标题" align="center" min-width="150"></el-table-column>
<el-table-column prop="classificationName" label="所属分类" align="center" min-width="120" sortable="custom"></el-table-column>
<el-table-column prop="founderName" label="录入人" align="center" min-width="80"></el-table-column>
<el-table-column prop="editorName" label="修改人" align="center" min-width="80"></el-table-column>
<el-table-column prop="updateTime" label="修改日期" align="center" min-width="150" sortable="custom"></el-table-column>
<el-table-column prop="releaseTime" label="发布日期" align="center" min-width="100" sortable="custom"></el-table-column>
<el-table-column prop="learnerNumber" label="已学习人数" align="center" min-width="70"></el-table-column>
<el-table-column prop="workNumber" label="状态" align="center" min-width="80">
<template slot-scope="scope">
{{ scope.row.isRelease ? '已发布' : '草稿' }}
</template>
</el-table-column>
<el-table-column prop="sequence" label="置顶" align="center" min-width="80" sortable="custom">
<template slot-scope="scope">
<i v-if="scope.row.isRelease" :class="['squ-icon', scope.row.isTop ? 'el-icon-check' : 'el-icon-close']" @click="sticky(scope.row)"></i>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="210">
<template slot-scope="scope">
<el-button v-auth="'/parnerOperation:合伙人学习管理:编辑'" type="text" @click="edit(scope.row)">编辑</el-button>
<el-button v-auth="'/parnerOperation:合伙人学习管理:删除'" type="text" @click="handleDelete(scope.row)">删除</el-button>
<el-switch
v-auth="'/parnerOperation:合伙人学习管理:禁用'"
v-if="scope.row.isRelease"
class="m-l-10"
v-model="scope.row.isDisable"
:active-value="0"
:inactive-value="1"
@change="switchOff($event, scope.row, scope.$index)">
</el-switch>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background @current-change="currentChange" :current-page="page" layout="total, prev, pager, next" :total="total"></el-pagination>
</div>
</div>
</template>
<script>
import Setting from '@/setting'
import util from '@/libs/util'
export default {
data() {
return {
field: 'title',
keywords: [
{
id: 'title',
name: '标题'
},
{
id: 'founder',
name: '录入人'
},
{
id: 'editor',
name: '修改人'
}
],
keyword: '',
list: [],
page: 1,
pageSize: 10,
total: 0,
topSort: '',
classificationNameSort: '',
releaseDateSort: '',
editTimeSort: '',
multipleSelection: [],
};
},
watch: {
keyword: function(val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initData()
}, 500)
}
},
mounted() {
this.getData()
},
methods: {
//
getData() {
const { keyword } = this
this.$post(this.api.partnerOperatingList, {
pageNum: this.page,
pageSize: this.pageSize,
querySource: 3, //(3. 4.)
topSort: this.topSort,
classificationNameSort: this.classificationNameSort,
editTimeSort: this.editTimeSort,
releaseDateSort: this.releaseDateSort,
typeId: 1, // (1.2.)
title: this.field === 'title' ? keyword : '',
founderName: this.field === 'founder' ? keyword : '',
editorName: this.field === 'editor' ? keyword : ''
}).then(({ page, total }) => {
page.forEach(e => {
e.editing = false
})
this.list = page
this.total = total
}).catch(err => {})
},
currentChange(val) {
this.page = val
this.getData()
},
handleSelectionChange(val) {
this.multipleSelection = val
},
initData() {
this.$refs.table.clearSelection()
this.page = 1
this.getData()
},
//
batchDel() {
const list = this.multipleSelection
if (list.length) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
const data = []
list.map(e => {
data.push('ids=' + e.id)
})
this.$post(`${this.api.batchDeletionParnerArticle}?${data.join('&')}`).then(res => {
this.$refs.table.clearSelection()
util.successMsg("删除成功")
this.getData()
}).catch(res => {})
}).catch(() => {})
} else {
util.errorMsg('请先选择数据 !')
}
},
//
handleDelete(row) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
this.$post(`${this.api.batchDeletionParnerArticle}?ids=${row.id}`).then(res => {
util.successMsg('删除成功')
this.getData()
}).catch(res => {})
}).catch(() => {})
},
//
switchOff(val, row) {
this.$post(`${this.api.articleEnableOrDisable}?id=${row.id}&isDisable=${val}`).then(res => {}).catch((res) => {})
},
//
add() {
this.$router.push(`/learnMg?type=1`)
},
//
sortChange(column) {
const { order } = column
// 1
if (column.prop === 'classificationName') {
this.classificationNameSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.releaseDateSort = ''
this.topSort = ''
}
}
if (column.prop === 'updateTime') {
this.editTimeSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.classificationNameSort = ''
this.releaseDateSort = ''
this.topSort = ''
}
}
if (column.prop === 'releaseTime') {
this.releaseDateSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.classificationNameSort = ''
this.topSort = ''
}
}
if (column.prop === 'sequence') {
this.topSort = order ? order === 'ascending' ? 'asc' : 'desc' : ''
if (order) {
this.editTimeSort = ''
this.releaseDateSort = ''
this.classificationNameSort = ''
}
}
this.getData()
},
//
submitSequence(row) {
if (!row.sequence) return Util.errorMsg('请输入排序')
this.$post(`${this.api.modifiedSort}?articleId=${row.id}&sequenceNumber=${row.sequence}`).then(res => {
this.initData()
}).catch(res => {})
},
//
editSequence(row) {
this.list.forEach(e => {
e.editing = false
})
row.editing = true
},
//
sticky(row) {
this.$post(`${this.api.articleTopOperation}?articleId=${row.id}&isTop=${row.isTop ? 0 : 1}`).then(res => {
this.initData()
}).catch(res => {})
},
//
edit(row) {
this.$router.push(`/learnMg?id=${row.id}&type=1`)
},
}
};
</script>
<style lang="scss" scoped>
.m-l-10 {
margin-left: 10px;
}
.squ-icon {
font-size: 16px;
font-weight: 600;
cursor: pointer;
color: #f70000;
&.el-icon-check {
color: #05991e;
}
}
/deep/.squ-input {
width: auto;
.el-input__inner {
width: 60px;
padding: 0 10px;
}
}
</style>

@ -1,50 +0,0 @@
<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,190 +1,215 @@
<template> <template>
<div> <div>
<el-card shadow="hover" class="mgb20"> <el-card shadow="hover" class="mgb20">
<div>
<div class="flex-center mgb20">
<p class="hr_tag"></p>
<span>筛选</span>
</div>
<div>
<el-form label-width="80px">
<div> <div>
<el-col :span="4"> <div class="flex-center mgb20">
<el-form-item label="系统归属"> <p class="hr_tag"></p>
<el-select v-model="form.belong" clearable placeholder="请选择系统归属" @change="initData"> <span>筛选</span>
<el-option v-for="(item, i) in belongs" :key="i" :label="item" :value="i"></el-option> </div>
</el-select> <div>
</el-form-item> <el-form label-width="80px">
</el-col> <div>
<el-col :span="4"> <el-col :span="4">
<el-form-item label="系统类型"> <el-form-item label="系统归属">
<el-select v-model="form.type" clearable placeholder="请选择系统类型" @change="initData"> <el-select v-model="systemAttribution" clearable placeholder="请选择系统归属"
<el-option v-for="(item, i) in types" :key="i" :label="item" :value="i"></el-option> @change="initData">
</el-select> <el-option v-for="(item,index) in systemBelongList" :key="index"
</el-form-item> :label="item.label" :value="item.value"></el-option>
</el-col> </el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="系统类型">
<el-select v-model="systemType" clearable placeholder="请选择系统类型"
@change="initData">
<el-option v-for="(item,index) in systemTypeList" :key="index"
:label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
</div>
<el-col :span="6">
<el-form-item>
<el-input placeholder="请输入系统名称" prefix-icon="el-icon-search"
v-model.trim="systemSearch" clearable></el-input>
</el-form-item>
</el-col>
</el-form>
</div>
</div> </div>
<el-col :span="6"> </el-card>
<el-form-item>
<el-input placeholder="请输入系统名称" prefix-icon="el-icon-search" v-model.trim="form.systemName"
clearable></el-input>
</el-form-item>
</el-col>
</el-form>
</div>
</div>
</el-card>
<el-card shadow="hover" class="card"> <el-card shadow="hover" 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" class="table" stripe header-align="center"> <el-table :data="systemData" 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" width="100" label="序号" align="center"> <el-table-column type="index" width="100" label="序号" align="center">
</el-table-column> </el-table-column>
<el-table-column prop="systemName" label="系统名称" align="center"></el-table-column> <el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
<el-table-column prop="type" label="系统类型" align="center"> <el-table-column prop="type" label="系统类型" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ types[scope.row.type] }} {{ systemTypeKeys[scope.row.type] }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="supplierName" label="供应商" align="center"></el-table-column> <el-table-column prop="supplierName" label="供应商" align="center"></el-table-column>
<el-table-column prop="belong" label="系统归属" align="center"> <el-table-column prop="belong" label="系统归属" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ belongs[scope.row.belong] }} {{ systemBelongKeys[scope.row.belong] }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="state" label="系统状态" align="center"> <el-table-column prop="state" label="系统状态" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ states[scope.row.state] }} {{ systemStatusKeys[scope.row.state] }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="payamount" label="系统后台" align="center"> <el-table-column prop="payamount" label="系统后台" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click="toBackstage(scope.row)" <el-button type="text" @click="toBackstage(scope.row)" v-if="scope.row.systemId !== '11'" v-auth="'/configure:系统后台进入'">进入</el-button>
v-if="scope.row.systemId !== '11' && scope.row.systemId !== '12'" </template>
v-auth="'/configure:系统后台进入'">进入</el-button> </el-table-column>
</template> <el-table-column prop="payamount" label="项目系统" align="center">
</el-table-column> <template slot-scope="scope">
<el-table-column prop="payamount" label="项目系统" align="center"> <el-button type="text" @click="getIntoProject(scope.row)" v-auth="'/configure:项目系统进入'">进入</el-button>
<template slot-scope="scope"> </template>
<el-button type="text" @click="getIntoProject(scope.row)" v-auth="'/configure:项目系统进入'">进入</el-button> </el-table-column>
</template> <el-table-column prop="payamount" label="判分系统" align="center">
</el-table-column> <template slot-scope="scope">
<el-table-column prop="payamount" label="判分系统" align="center"> <el-button type="text" @click="getIntoJudgement(scope.row)" v-auth="'/configure:判分系统进入'">进入</el-button>
<template slot-scope="scope"> </template>
<el-button type="text" @click="getIntoJudgement(scope.row)" v-auth="'/configure:判分系统进入'">进入</el-button> </el-table-column>
</template> </el-table>
</el-table-column> <div class="pagination">
</el-table> <el-pagination background @current-change="handleCurrentChange"
<div class="pagination"> layout="total, prev, pager, next" :total="totals">
<el-pagination background @current-change="handleCurrentChange" layout="total, prev, pager, next" </el-pagination>
:current-page="page" :total="total"> </div>
</el-pagination> </el-card>
</div> </div>
</el-card>
</div>
</template> </template>
<script> <script>
import Setting from "@/setting"; import Setting from "@/setting";
import qs from 'qs'
export default { export default {
data () { data() {
return { return {
userId: this.$store.state.userLoginId, userId: this.$store.state.userLoginId,
token: btoa(sessionStorage.getItem('token')), token: btoa(sessionStorage.getItem('token')),
form: { systemAttribution: "",
belong: this.$route.query.belong || '', systemType: "",
type: this.$route.query.type ? +this.$route.query.type : '', systemSearch: "",
systemName: this.$route.query.systemName || '' searchTimer: null,
}, systemData: [],
searchTimer: null, totals: 0,
list: [], systemBelongList: [
total: 0, {
belongs: { label: "外部产品",
1: '外部产品', value: 1
0: '内部系统' },
}, {
types: ['编程类', '流程类', 'AI类'], label: "内部系统",
states: ['运行中', '默认'], value: 0
page: +this.$route.query.page || 1, }
pageSize: 10 ],
}; systemBelongKeys: {
}, 1: '外部产品',
watch: { 0: '内部系统'
'form.systemName': function (val) { },
clearTimeout(this.searchTimer); systemTypeList: [
this.searchTimer = setTimeout(() => { {
this.initData(); label: "编程类",
}, 500); value: 0
} },
}, {
mounted () { label: "流程类",
const { query } = this.$route value: 1
if (query.page) { }
this.$router.push('/configure').catch(() => { }) ],
} systemTypeKeys: {
0: '编程类',
this.getData(); 1: '流程类'
}, },
methods: { systemStatusKeys: {
initData () { 0: '运行中',
this.page = 1; 1: '默认'
this.getData(); },
}, pageNo: +this.$route.query.page || 1,
getData () { pageSize: 10
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.queryServiceConfig, data).then(res => {
this.list = res.serviceList.records;
this.total = res.serviceList.total;
}).catch(res => {
});
}, },
handleCurrentChange (val) { watch: {
this.page = val; systemSearch: function(val) {
this.$router.push(`configure?page=${val}`) clearTimeout(this.searchTimer);
this.getData(); this.searchTimer = setTimeout(() => {
this.initData();
}, 500);
}
}, },
// url mounted() {
setReferrer () { this.getData();
this.$store.commit('setReferrer', `${this.$route.path}?${qs.stringify(this.form)}&page=${this.page}`)
}, },
// methods: {
toBackstage (row) { initData() {
this.setReferrer() this.pageNum = 1;
if (row.systemId == 19 || row.systemId == 30) { this.getData();
location.href = `${Setting.sandPath}/#/config?token=${sessionStorage.getItem('token')}&admin=1&referrer=${encodeURIComponent(location.href)}` },
} else { getData() {
this.$router.push(`/backstage?systemId=${row.systemId}&show=1&name=${row.systemName}`) const sid = this.$store.state.dataPer.find(e => e.permissionName === '服务配置')
} let data = {
}, belong: this.systemAttribution,
getIntoProject (row) { type: this.systemType,
this.setReferrer() systemName: this.systemSearch,
this.$router.push(`/projectList?systemId=${row.systemId}&show=1&name=${row.systemName}`) pageNum: this.pageNo,
}, pageSize: this.pageSize,
getIntoJudgement (row) { supplierId: sid ? sid.supplierId : ''
this.setReferrer() };
location.href = `${Setting.jumpPath}#/?systemId=${row.systemId}&token=${this.token}&referrer=${btoa(location.href)}`; this.$post(this.api.queryServiceConfig, data).then(res => {
}, this.systemData = res.serviceList.records;
} this.totals = res.serviceList.total;
}).catch(res => {
});
},
handleCurrentChange(val) {
this.pageNo = val;
this.$router.push(`configure?page=${val}`)
this.getData();
},
edit(row) {
this.$store.commit("configData", { config_id: row.systemId });
this.$router.push("/addconfigure");
},
//
toBackstage(row) {
this.$router.push(`/backstage?systemId=${row.systemId}&show=1&name=${row.systemName}`)
},
getIntoProject(row) {
this.$router.push(`/projectList?systemId=${row.systemId}&show=1&name=${row.systemName}`)
},
getIntoJudgement(row) {
// console.log(`${Setting.jumpPath}#/?systemId=${row.systemId}&token=${this.token}&referrer=${btoa(location.href)}`);
location.href = `${Setting.jumpPath}#/?systemId=${row.systemId}&token=${this.token}&referrer=${btoa(location.href)}`;
},
setCookie(name, value) {
if (value) {
var days = 1;//
var exp = new Date();
exp.setTime(exp.getTime() + days * 24 * 60 * 60 * 1000);
//Cookie,toGMTString
document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString + ";path=/;";
}
}
}
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.card { .card {
min-height: calc(100vh - 300px); min-height: calc(100vh - 300px);
} }
.mag { .mag {
margin-right: 20px; margin-right: 20px;
} }
</style> </style>

@ -194,8 +194,7 @@ export default {
// //
if ((id && updateTime > 1) || (!id && updateTime)) { if ((id && updateTime > 1) || (!id && updateTime)) {
this.$confirm(`编辑的内容未保存,是否保存?`, '提示', { this.$confirm(`编辑的内容未保存,是否保存?`, '提示', {
type: 'warning', type: 'warning'
closeOnClickModal: false
}).then(() => { }).then(() => {
this.submit(this.postStatus ? 1 : 0, 1) this.submit(this.postStatus ? 1 : 0, 1)
this.backPage() this.backPage()

@ -57,7 +57,7 @@ export default {
}) })
}, },
back () { back () {
this.$router.push(this.$store.state.referrer || '/configure') this.$router.push('/configure')
} }
} }
}; };

@ -106,6 +106,7 @@
</template> </template>
<script> <script>
import org from "./modelType" import org from "./modelType"
import Setting from '@/setting'
import Bus from '@/libs/bus' import Bus from '@/libs/bus'
export default { export default {
data () { data () {
@ -113,7 +114,7 @@ export default {
systemId: this.$route.query.systemId, systemId: this.$route.query.systemId,
isTopLevel: true, // isTopLevel: true, //
listData: [], listData: [],
keyword: this.$route.query.keyword || '', keyword: '',
page: +this.$route.query.page || 1, page: +this.$route.query.page || 1,
pageSize: 10, pageSize: 10,
total: 0, total: 0,
@ -131,13 +132,6 @@ export default {
keyword: function (val) { keyword: function (val) {
clearTimeout(this.searchTimer); clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => { this.searchTimer = setTimeout(() => {
this.$router.push({
path: 'backstage',
query: {
...this.$route.query,
keyword: val
}
})
this.initData() this.initData()
}, 500) }, 500)
} }

@ -144,7 +144,7 @@ export default {
systemId: this.$route.query.systemId, systemId: this.$route.query.systemId,
isTopLevel: true, // isTopLevel: true, //
listData: [], listData: [],
keyword: this.$route.query.keyword || '', keyword: "",
page: +this.$route.query.page || 1, page: +this.$route.query.page || 1,
pageSize: 10, pageSize: 10,
total: 0, total: 0,
@ -169,13 +169,6 @@ export default {
keyword: function (val) { keyword: function (val) {
clearTimeout(this.searchTimer); clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => { this.searchTimer = setTimeout(() => {
this.$router.push({
path: 'backstage',
query: {
...this.$route.query,
keyword: val
}
})
this.initData() this.initData()
}, 500) }, 500)
} }

@ -1,20 +1,25 @@
<template> <template>
<div ref="main" class="main" v-loading="loading"> <div ref="main"
class="main">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="24"> <el-col :span="24">
<el-card shadow="hover" class="mgb20"> <el-card shadow="hover"
class="mgb20">
<div class="flex-between"> <div class="flex-between">
<el-page-header @back="back" content="项目配置"></el-page-header> <el-page-header @back="back"
content="项目配置"></el-page-header>
<div v-if="!isDetail"> <div v-if="!isDetail">
<el-button type="success" :loading="submiting === 0" <el-button type="success"
@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" :loading="submiting === 1" @click="handleSubmit(1)">确定并发布</el-button> <el-button type="primary"
@click="handleSubmit(1)">确定并发布</el-button>
</div> </div>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" class="mgb20"> <el-card shadow="hover"
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>
@ -25,18 +30,26 @@
<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" v-model.trim="projectManage.projectName" placeholder="20个字符以内" <el-input :disabled="isDetail"
@blur="projectNameExistis"></el-input> v-model.trim="projectManage.projectName"
placeholder="20个字符以内"
@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" placeholder="20个字符以内"></el-input> <el-input v-model.trim="projectManage.remark"
placeholder="20个字符以内"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="项目用途"> <el-form-item label="项目用途">
<el-select :disabled="isDetail" v-model="projectManage.permissions" placeholder="请选择" <el-select :disabled="isDetail"
@change="permissionChange"> v-model="projectManage.permissions"
<el-option label="练习" :value="0"></el-option> placeholder="请选择"
<el-option label="考核" :value="1"></el-option> @change="permissionChange">
<el-option label="竞赛" :value="2"></el-option> <el-option label="练习"
:value="0"></el-option>
<el-option label="考核"
:value="1"></el-option>
<el-option label="竞赛"
:value="2"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</div> </div>
@ -44,7 +57,8 @@
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" class="mgb20"> <el-card shadow="hover"
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>
@ -53,14 +67,18 @@
<div> <div>
<el-form label-width="0"> <el-form label-width="0">
<el-form-item> <el-form-item>
<quill :border="true" :readonly="isDetail" v-model="projectManage.experimentTarget" <quill :border="true"
:type.sync="projectManage.experimentTargetType" radio :minHeight="150" :height="150" /> :readonly="isDetail"
v-model="projectManage.experimentTarget"
:minHeight="150"
:height="150" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" class="mgb20"> <el-card shadow="hover"
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>
@ -69,22 +87,27 @@
<div> <div>
<el-form label-width="0"> <el-form label-width="0">
<el-form-item> <el-form-item>
<quill :border="true" :readonly="isDetail" v-model="projectManage.experimentDescription" <quill :border="true"
:type.sync="projectManage.experimentDescriptionType" radio :minHeight="150" :height="150" :readonly="isDetail"
:index="1" /> v-model="projectManage.experimentDescription"
:minHeight="150"
:height="150" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" class="mgb20"> <el-card shadow="hover"
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" type="primary" @click="toJudgePoint('home')">进入判分点 <el-button :disabled="isDetail"
type="primary"
@click="toJudgePoint('home')">进入判分点
</el-button> </el-button>
</div> </div>
</div> </div>
@ -92,58 +115,101 @@
<div class="mgb20 flex-between"> <div class="mgb20 flex-between">
<div class="flex-center"> <div class="flex-center">
<div class="m-r-20" style="color: #f00">项目总分值100</div> <div class="m-r-20"
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" class="m-r-20" type="text" @click="avgDistributionScore"> <el-button :disabled="isDetail"
class="m-r-20"
type="text"
@click="avgDistributionScore">
平均分配分值 平均分配分值
</el-button> </el-button>
<el-button :disabled="isDetail" class="m-r-20" type="text" @click="manualDistributionScore"> <el-button :disabled="isDetail"
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" type="primary" icon="el-icon-plus" round @click="handleAddJudgment" <el-button :disabled="isDetail"
style="margin-bottom: 10px">判分点 type="primary"
icon="el-icon-plus"
round
@click="handleAddJudgment"
style="margin-bottom: 10px">判分点
</el-button> </el-button>
<el-button :disabled="isDetail" type="primary" icon="el-icon-delete" round @click="batchDeleteProjectJudgment" <el-button :disabled="isDetail"
style="margin-bottom: 10px">批量删除 type="primary"
icon="el-icon-delete"
round
@click="batchDeleteProjectJudgment"
style="margin-bottom: 10px">批量删除
</el-button> </el-button>
<div class="draggable"> <div class="draggable">
<el-table ref="projectJudgementTable" :data="projectJudgmentData" class="table" stripe header-align="center" <el-table ref="projectJudgementTable"
:use-virtual="isLc" :max-height="600" :row-height="60" :border="false" :data="projectJudgmentData"
@selection-change="handleSelectionProjectJudgment" row-key="judgmentId" v-loading="listLoading"> class="table"
<el-table-column type="selection" width="55" align="center"></el-table-column> stripe
<el-table-column prop="sort" label="序号" width="80" align="center"> header-align="center"
@selection-change="handleSelectionProjectJudgment"
row-key="judgmentId"
v-loading="listLoading">
<el-table-column type="selection"
width="55"
align="center"></el-table-column>
<el-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>
</el-table-column> </el-table-column>
<el-table-column prop="name" label="判分指标" align="center" show-overflow-tooltip <el-table-column prop="name"
min-width="140"></el-table-column> label="判分指标"
<el-table-column prop="name" label="判分点名称" align="center" show-overflow-tooltip align="center"></el-table-column>
min-width="140"></el-table-column> <el-table-column prop="name"
<el-table-column label="实验要求" align="center" width="600"> label="判分点名称"
align="center"></el-table-column>
<el-table-column label="实验要求"
align="center"
width="600">
<template slot-scope="scope"> <template slot-scope="scope">
<quill :readonly="true" elseRead="true" v-model="scope.row.experimentalRequirements" :index="2" /> <quill :border="true"
:readonly="true"
elseRead="true"
v-model="scope.row.experimentalRequirements"
:minHeight="100"
:height="100" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="score" label="分数" align="center" width="120"> <el-table-column prop="score"
label="分数"
align="center"
width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input :disabled="isDetail" :key="scope.$index" type="number" step="0.1" <!--type="number" @blur="updateProjectJudgment"-->
v-model.trim="scope.row.score"></el-input> <el-input :disabled="isDetail"
<!-- v-model.trim="scope.row.score"
@input="scoreChange(scope.row, scope.$index)" --> @input="scoreChange(scope.row, scope.$index,$event)"></el-input>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="140" align="center"> <el-table-column label="操作"
width="140"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button :disabled="isDetail" type="text" style="margin-right: 10px" <el-button :disabled="isDetail"
@click="toJudgePoint('edit', scope.row)">自定义</el-button> type="text"
<el-button :disabled="isDetail" type="text" @click="delJudgePoint(scope.$index)"> style="margin-right: 10px"
@click="toJudgePoint('edit', scope.row)">自定义</el-button>
<el-button :disabled="isDetail"
type="text"
@click="delJudgePoint(scope.$index)">
删除 删除
</el-button> </el-button>
</template> </template>
@ -152,7 +218,8 @@
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" class="mgb20"> <el-card shadow="hover"
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>
@ -160,16 +227,22 @@
</div> </div>
<div> <div>
启用 启用
<el-switch :disabled="isDetail" :active-value="0" :inactive-value="1" <el-switch :disabled="isDetail"
v-model="projectManage.hintOpen"></el-switch> :active-value="0"
:inactive-value="1"
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" label=""> <el-form-item prop="tips"
<quill :border="true" :readonly="isDetail" v-model="projectManage.experimentHint" label="">
:type.sync="projectManage.experimentHintType" radio :minHeight="150" :height="400" :index="3" /> <quill :border="true"
:readonly="isDetail"
v-model="projectManage.experimentHint"
:minHeight="150"
:height="150" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@ -178,34 +251,58 @@
</el-row> </el-row>
<!--选择判分点对话框--> <!--选择判分点对话框-->
<el-dialog title="添加判分点" :visible.sync="dialogVisible" width="40%" :close-on-click-modal="false" <el-dialog title="添加判分点"
@close="closeJudgment"> :visible.sync="dialogVisible"
width="40%"
:close-on-click-modal="false"
@close="closeJudgment">
<div class="text-right mgb10"> <div class="text-right mgb10">
<div> <div>
<el-input placeholder="请输入需要查找的判分点" prefix-icon="el-icon-search" v-model.trim="judgementpointsquery" <el-input placeholder="请输入需要查找的判分点"
clearable></el-input> prefix-icon="el-icon-search"
v-model.trim="judgementpointsquery"
clearable></el-input>
</div> </div>
</div> </div>
<el-table v-loading="visibleLoading" :data="judgementData" ref="judgementTable" class="table" stripe <el-table v-loading="visibleLoading"
header-align="center" use-virtual :row-height="45" :max-height="400" :border="false" :data="judgementData"
@selection-change="handleSelectionJudgment" :row-key="rowKey"> ref="judgementTable"
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> class="table"
<el-table-column prop="id" label="序号" align="center" width="100"> stripe
header-align="center"
max-height="400"
@selection-change="handleSelectionJudgment"
:row-key="rowKey">
<el-table-column type="selection"
width="55"
align="center"
:reserve-selection="true"></el-table-column>
<el-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>
</el-table-column> </el-table-column>
<el-table-column prop="name" label="判分点名称" align="center"></el-table-column> <el-table-column prop="name"
<el-table-column label="操作" align="center" width="100"> label="判分点名称"
align="center"></el-table-column>
<el-table-column label="操作"
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="mini" @click="toJudgePoint('view', scope.row)">查看</el-button> <el-button size="mini"
@click="toJudgePoint('view', scope.row)">查看</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div slot="footer" class="dialog-footer"> <div slot="footer"
class="dialog-footer">
<el-button @click="closeJudgment"> </el-button> <el-button @click="closeJudgment"> </el-button>
<el-button type="primary" :loading="savingJud" @click="saveJudgment"> </el-button> <el-button type="primary"
@click="saveJudgment"> </el-button>
</div> </div>
</el-dialog> </el-dialog>
</div> </div>
@ -215,13 +312,10 @@
import Setting from "@/setting"; import Setting from "@/setting";
import quill from "@/components/quill"; import quill from "@/components/quill";
import Sortable from "sortablejs"; import Sortable from "sortablejs";
import { UTable, UTableColumn } from 'umy-ui'
import Decimal from 'decimal.js'
export default { export default {
components: { components: {
quill, quill
UTable,
UTableColumn
}, },
data () { data () {
return { return {
@ -243,10 +337,7 @@ export default {
state: 0, // (0稿 1) state: 0, // (0稿 1)
isOpen: 0, // (0 1 0) isOpen: 0, // (0 1 0)
ztOpen: 0, // (0 1 0) ztOpen: 0, // (0 1 0)
isDel: 0, // (0 1 0) isDel: 0 // (0 1 0)
experimentTargetType: '0',
experimentDescriptionType: '0',
experimentHintType: '0',
}, },
projectJudgmentData: [], //() projectJudgmentData: [], //()
oriPer: '', // oriPer: '', //
@ -268,9 +359,7 @@ export default {
visibleLoading: false, // visibleLoading: false, //
listLoading: false,// listLoading: false,//
submiting: false, // submiting: false, //
updateTime: 0, updateTime: 0
savingJud: false,
loading: false,
}; };
}, },
computed: { computed: {
@ -280,11 +369,11 @@ export default {
projectFields () { projectFields () {
return this.$store.state.projectFields; return this.$store.state.projectFields;
}, },
handDistributionScore () { handDistributionScore: function () {
//100 //100
let score = 0; let score = 0;
this.projectJudgmentData.forEach(e => { this.projectJudgmentData.forEach(e => {
if (e.score && !isNaN(e.score)) score = Decimal(e.score).add(Decimal(score)) score += parseInt(e.score);
}); });
if (isNaN(score)) { if (isNaN(score)) {
return 0; return 0;
@ -293,12 +382,7 @@ export default {
this.$message.error("分配的数值已超过100"); this.$message.error("分配的数值已超过100");
} }
return score; return score;
}, }
//
isLc () {
const systemId = +this.$route.query.systemId
return systemId === 11 || systemId === 12 || systemId === 19
},
}, },
watch: { watch: {
// , // ,
@ -319,8 +403,6 @@ 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) != "{}") {
@ -328,6 +410,7 @@ 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 () {
@ -345,27 +428,21 @@ export default {
}, },
getInfoData () { // getInfoData () { //
if (!this.isToPoint) { if (!this.isToPoint) {
this.loading = true
this.$get(`${this.api.getProjectDetail}?projectId=${this.projectId}`).then(res => { this.$get(`${this.api.getProjectDetail}?projectId=${this.projectId}`).then(res => {
let { projectManage, projectJudgmentVos } = res; let { projectManage, projectJudgmentVos } = res;
if (!projectManage.remark) projectManage.remark = projectManage.projectName // if (!projectManage.remark) projectManage.remark = projectManage.projectName //
if (!projectManage.experimentDescriptionType) projectManage.experimentDescriptionType = '0'
if (!projectManage.experimentHintType) projectManage.experimentHintType = '0'
if (!projectManage.experimentTargetType) projectManage.experimentTargetType = '0'
this.projectManage = projectManage; this.projectManage = projectManage;
this.projectJudgmentData = projectJudgmentVos; this.projectJudgmentData = projectJudgmentVos;
this.oriPer = projectManage.permissions this.oriPer = projectManage.permissions
this.projectJudgmentData.forEach((e, i) => { this.projectJudgmentData.forEach((e, i) => {
e.sort = i + 1; e.sort = i + 1;
}); });
this.loading = false
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 console.log(err);
}); });
} }
}, },
@ -445,11 +522,11 @@ export default {
return true; return true;
}, },
handleSubmit (state) { // handleSubmit (state) { //
if (this.submiting === 0 || this.submiting === 1) return false if (this.submiting) return false
if (!this.judgmentRelease(state)) { // if (!this.judgmentRelease(state)) { //
return; return;
} }
this.submiting = state this.submiting = true
this.$store.dispatch("setSystemId", this.projectManage.systemId); this.$store.dispatch("setSystemId", this.projectManage.systemId);
this.projectManage.state = state; this.projectManage.state = state;
this.projectManage.ztOpen = state ? 0 : 1 this.projectManage.ztOpen = state ? 0 : 1
@ -495,7 +572,7 @@ export default {
} else { } else {
this.$message.success('更新实验项目成功') this.$message.success('更新实验项目成功')
} }
this.toList(); this.$router.back();
} }
}).catch(err => { }).catch(err => {
this.submiting = false this.submiting = false
@ -540,9 +617,8 @@ export default {
let y = index + 2; let y = index + 2;
this.projectJudgmentData.splice(x - 1, 1, ...this.projectJudgmentData.splice(y - 1, 1, this.projectJudgmentData[x - 1])); this.projectJudgmentData.splice(x - 1, 1, ...this.projectJudgmentData.splice(y - 1, 1, this.projectJudgmentData[x - 1]));
}, },
scoreChange (row, i) { scoreChange (row, index) { //
row.score = row.score.replace(/[^\d\.]/g, '') this.projectJudgmentData.splice(index, 1, row);
this.projectJudgmentData.splice(i, 1, row);
}, },
delJudgePoint (index) { // delJudgePoint (index) { //
this.$confirm("确定要删除吗?", "提示", { this.$confirm("确定要删除吗?", "提示", {
@ -591,7 +667,7 @@ export default {
}; };
if (systemId == 2 || systemId == 3) { if (systemId == 2 || systemId == 3) {
console.log("系统id:", systemId); console.log("系统id:", systemId);
} else if (this.isLc) { } else if (systemId == 11 || systemId == 12) {
// () // ()
this.rowKey = "lcId"; this.rowKey = "lcId";
this.getProcessClassData(params); this.getProcessClassData(params);
@ -644,11 +720,10 @@ export default {
}, },
saveJudgment () { // saveJudgment () { //
if (this.selectedJudgment.length) { if (this.selectedJudgment.length) {
this.savingJud = true
this.judgementpointsquery = ""; this.judgementpointsquery = "";
this.dialogVisible = false; this.dialogVisible = false;
let tempArr = this.selectedJudgment.map(i => { let tempArr = this.selectedJudgment.map(i => {
this.$set(i, 'score', 0) i.score = 0;
return i; return i;
}); });
this.projectJudgmentData = this.projectJudgmentData.concat(tempArr); this.projectJudgmentData = this.projectJudgmentData.concat(tempArr);
@ -656,7 +731,6 @@ export default {
e.sort = i + 1; e.sort = i + 1;
}); });
this.$nextTick(() => { this.$nextTick(() => {
this.savingJud = false
this.$refs.projectJudgementTable.clearSelection(); this.$refs.projectJudgementTable.clearSelection();
}); });
} else { } else {
@ -666,16 +740,24 @@ export default {
// //
rowDrop () { rowDrop () {
// //
const tbody = document.querySelector(".el-table__body tbody"); const tbody = document.querySelector(".draggable .el-table__body-wrapper tbody");
const that = this; const _this = this;
this.$refs.projectJudgementTable && Sortable.create(tbody, { Sortable.create(tbody, {
// //
// draggable: ".draggable .el-table__row", draggable: ".draggable .el-table__row",
onUpdate ({ newIndex, oldIndex }) { onEnd ({ newIndex, oldIndex }) {
console.log("🚀 ~ onEnd ~ newIndex, oldIndex:", newIndex, oldIndex) // : vue$nextTick
if (newIndex == oldIndex) return false _this.projectJudgmentData.splice(newIndex, 0, _this.projectJudgmentData.splice(oldIndex, 1)[0]);
const currentRow = that.projectJudgmentData.splice(oldIndex, 1)[0] let newArray = _this.projectJudgmentData.slice(0);
that.projectJudgmentData.splice(newIndex, 0, currentRow) _this.projectJudgmentData = [];
_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;
});
} }
}); });
}, },
@ -728,7 +810,7 @@ export default {
console.log(systemId); console.log(systemId);
} else if (systemId == 3) { } else if (systemId == 3) {
console.log(systemId); console.log(systemId);
} else if (this.isLc) { } else if (systemId == 11 || systemId == 12) {
// //
href = `${jumpPath}/#/Transaction?isView=true&systemId=${systemId}&lcId=${row.judgmentId}&token=${this.token}&referrer=${btoa(location.href)}`; href = `${jumpPath}/#/Transaction?isView=true&systemId=${systemId}&lcId=${row.judgmentId}&token=${this.token}&referrer=${btoa(location.href)}`;
} else { } else {
@ -741,7 +823,7 @@ export default {
console.log(systemId); console.log(systemId);
} else if (systemId == 3) { } else if (systemId == 3) {
console.log(systemId); console.log(systemId);
} else if (this.isLc) { } else if (systemId == 11 || systemId == 12) {
// //
href = `${jumpPath}/#/Transaction?isEdit=true&systemId=${systemId}&lcId=${row.judgmentId}&token=${this.token}&referrer=${btoa(location.href)}`; href = `${jumpPath}/#/Transaction?isEdit=true&systemId=${systemId}&lcId=${row.judgmentId}&token=${this.token}&referrer=${btoa(location.href)}`;
} else { } else {
@ -760,15 +842,14 @@ export default {
}, },
// //
toList () { toList () {
this.$router.push(this.$store.state.innerReferrer) this.$router.back()
}, },
// //
back () { back () {
// //
if (this.updateTime) { if (this.updateTime) {
this.$confirm('编辑的内容未保存,是否保存?', "提示", { this.$confirm('编辑的内容未保存,是否保存?', "提示", {
type: "warning", type: "warning"
closeOnClickModal: false
}).then(() => { }).then(() => {
this.handleSubmit(this.projectManage.state) this.handleSubmit(this.projectManage.state)
}).catch(() => { }).catch(() => {
@ -784,14 +865,13 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
/deep/ .readonly .ql-toolbar { /deep/ .readonly .ql-toolbar {
height: 0; height: 0;
padding: 0; padding: 0;
border-bottom: 0; border-bottom: 0;
} }
.main { .main {
overflow: auto; overflow: auto;
overflow-x: hidden; overflow-x: hidden;
height: calc(100vh - 161px); height: calc(100vh - 152px);
} }
</style> </style>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save