Compare commits

...

113 Commits

Author SHA1 Message Date
yujialong 87e0c2c1c8 fix 2 months ago
yujialong b7425ca1df fix 2 months ago
yujialong c9d67373d3 fix 2 months ago
yujialong 0c9e5562a1 权限 2 months ago
yujialong 429f9d672c 赛事导入人员模板更换 2 months ago
yujialong b5aa906326 fix 2 months ago
yujialong 6df319cf51 fix 2 months ago
yujialong be1ee97189 fix 2 months ago
yujialong db23e62753 fix 2 months ago
yujialong 04c306898f fix 2 months ago
yujialong 878645d672 fix 2 months ago
yujialong 2de12c8ec0 fix 3 months ago
yujialong 79a92a3410 fix 3 months ago
yujialong 08adddc010 fix 3 months ago
yujialong 3bf85a18bb 订单修复,资源库联调 3 months ago
yujialong 69fc4e49b2 fix 3 months ago
yujialong 07b36913d2 订单添加理实课程 3 months ago
yujialong 89abb11569 赛事相关 3 months ago
yujialong e467d90550 fix 3 months ago
yujialong 1d800d91b2 fix 3 months ago
yujialong b4b748d3ca fix 3 months ago
yujialong 6beec3d7e7 fix 3 months ago
yujialong 59f018f18c fix 3 months ago
yujialong 0e6e54bd81 fix 3 months ago
yujialong 28cce9dc63 课程相关 3 months ago
yujialong 38565b6669 fix 3 months ago
yujialong 9ea6496254 课程相关 3 months ago
yujialong 9356e4debe 课程 3 months ago
yujialong 0d1cbd6ed0 资源库等 3 months ago
yujialong 9dd6f20a62 新增课程修改 3 months ago
yujialong f2b6fb204f fix 3 months ago
yujialong 8f99871ad7 左侧导航 3 months ago
yujialong f508148177 整体风格调整 3 months ago
yujialong 36c1a45fe2 工作台及头部导航、主题色更改 3 months ago
yujialong 801c4683a9 工号同步职站 3 months ago
yujialong 26ec77f7de 订单修复 3 months ago
yujialong d5425d48bb fix 3 months ago
yujialong 2a1ffda11c fix 3 months ago
yujialong 24b60d7468 fix 4 months ago
yujialong 796f802fc5 fix 4 months ago
yujialong 2af18aa23c fix 4 months ago
yujialong fe4a1b7900 fix 4 months ago
yujialong 66b4c21343 fix 4 months ago
yujialong 40327a423f fix 5 months ago
yujialong a089ad2943 fix 5 months ago
yujialong 734524aab2 赛事修复 5 months ago
yujialong 4779595867 fix 5 months ago
yujialong df33b0b5eb fix 5 months ago
yujialong b692519c5d fix 5 months ago
yujialong 996a611e03 fix 5 months ago
yujialong 37eb678280 fix 5 months ago
yujialong 46eaca3745 fix 5 months ago
yujialong 56361bdd11 fix 6 months ago
yujialong f3e795125d 竞赛修复 6 months ago
yujialong d0764a64a0 赛事成绩列表实训跟理论合并,线下单独一个页面 6 months ago
yujialong a033ef3565 fix 6 months ago
yujialong f07e4ccdb2 fix 6 months ago
yujialong bf8f4093f6 评阅中心 6 months ago
yujialong dabd2f9871 fix 6 months ago
yujialong 02b22578a4 赛事修复 6 months ago
yujialong e44b2ad9b9 fix 6 months ago
yujialong 0d952de033 fix 6 months ago
yujialong 45ff98f698 fix 6 months ago
yujialong 6747314cc9 fix 7 months ago
yujialong 645e52a679 fix 7 months ago
yujialong 5a21e78cac 赛事成绩相关 7 months ago
yujialong 5c7bb7eba0 fix 7 months ago
yujialong 8eb83be7c7 赛事列表、赛事理论成绩列表 7 months ago
yujialong 89a1a63f71 理论考试实验报告联调完成 7 months ago
yujialong 3668825847 赛事选择试卷相关 7 months ago
yujialong b8a41a5e23 登录调整 7 months ago
yujialong a2b4e242b4 fix 7 months ago
yujialong 58f007cfc9 oss上传秘钥加密 7 months ago
yujialong 812f1c916a 考试平台iframe,订单、客户修复 8 months ago
yujialong b831b14302 知识点、题库分类 8 months ago
yujialong 2669f15962 理论考试系统列表、题库管理 8 months ago
yujialong 300e917d1e 订单修复 8 months ago
yujialong 6fe4a41fa1 订单:一键发货、批量修改期限、试用默认1月 8 months ago
yujialong d611d682a2 fix 8 months ago
yujialong 6c2437e6f3 fix 9 months ago
yujialong c11eb9ca6b 赛事修复 9 months ago
yujialong 23986d7b7e 赛事修复 9 months ago
yujialong d3c9cc9876 赛事修复 10 months ago
yujialong 6599d982a4 赛事分配等 10 months ago
yujialong 0ba3475f1f fix 10 months ago
yujialong 56565ded13 大赛自动分配 10 months ago
yujialong 64d15ceab0 赛事分配等 10 months ago
yujialong 5fdb75fec9 fix 10 months ago
yujialong 267dd86ac0 fix 10 months ago
yujialong d5d594b967 编辑客户学校 10 months ago
yujialong ebf4e9ffbc 全站添加筛选功能缓存 11 months ago
yujialong 34d84486ea fix 11 months ago
yujialong 45ec91acba fix 11 months ago
yujialong ba7c09ecf8 fix 11 months ago
yujialong c7772e54ad fix 11 months ago
yujialong d820cb0e8b 赛事相关 11 months ago
yujialong effa4606b7 添加loading 11 months ago
yujialong 09d3eaa5d8 fix 11 months ago
yujialong 43b59996f3 赛事相关 11 months ago
yujialong 2419a97063 赛事相关 11 months ago
yujialong 6ba5f44a33 赛事修复 11 months ago
yujialong 88a040c68a 赛事相关修复 11 months ago
yujialong e13f523d73 赛事人员相关 12 months ago
yujialong e615d0399b 赛事导入人员等 12 months ago
yujialong a140f773c8 赛事人员导入等 12 months ago
yujialong 8aacf50ab4 赛事复制等 12 months ago
yujialong 27789601f6 fix 12 months ago
yujialong 06dcc3b2d1 fix 12 months ago
yujialong 1449f2073d fix 1 year ago
yujialong 539f1f95cc confirm确认弹框禁止点击遮盖层关闭 1 year ago
yujialong f7a27f7e30 fix 1 year ago
yujialong 8ca2239f95 fix 1 year ago
yujialong 717b8a08dd fix 1 year ago
  1. 2
      .prettierrc
  2. 2670
      package-lock.json
  3. 7
      package.json
  4. 11
      public/index.html
  5. 26
      src/App.vue
  6. 28
      src/assets/css/color-dark.css
  7. 7
      src/assets/css/default/index.scss
  8. 104
      src/assets/css/main.css
  9. 189
      src/assets/css/station.scss
  10. 29
      src/assets/css/theme-green/color-green.css
  11. BIN
      src/assets/css/theme-green/fonts/element-icons.ttf
  12. BIN
      src/assets/css/theme-green/fonts/element-icons.woff
  13. 1
      src/assets/css/theme-green/index.css
  14. BIN
      src/assets/img/ach1.png
  15. BIN
      src/assets/img/ach2.png
  16. 1
      src/assets/img/drag.svg
  17. 1
      src/assets/img/empty.svg
  18. BIN
      src/assets/img/exts/excel.png
  19. BIN
      src/assets/img/exts/pdf.png
  20. BIN
      src/assets/img/exts/pic.png
  21. BIN
      src/assets/img/exts/ppt.png
  22. BIN
      src/assets/img/exts/txt.png
  23. BIN
      src/assets/img/exts/video.png
  24. BIN
      src/assets/img/exts/word.png
  25. BIN
      src/assets/img/full.png
  26. BIN
      src/assets/img/project.png
  27. 1
      src/assets/img/right.svg
  28. 1
      src/assets/img/shrink.svg
  29. 1
      src/assets/img/tag-active.svg
  30. 1
      src/assets/img/tag.svg
  31. BIN
      src/assets/img/wechat-code.jpeg
  32. BIN
      src/assets/img/workbench/1.png
  33. BIN
      src/assets/img/workbench/10.png
  34. BIN
      src/assets/img/workbench/11.png
  35. BIN
      src/assets/img/workbench/12.png
  36. BIN
      src/assets/img/workbench/13.png
  37. BIN
      src/assets/img/workbench/14.png
  38. BIN
      src/assets/img/workbench/15.png
  39. BIN
      src/assets/img/workbench/16.png
  40. BIN
      src/assets/img/workbench/2.png
  41. BIN
      src/assets/img/workbench/3.png
  42. BIN
      src/assets/img/workbench/4.png
  43. BIN
      src/assets/img/workbench/5.png
  44. BIN
      src/assets/img/workbench/6.png
  45. BIN
      src/assets/img/workbench/7.png
  46. BIN
      src/assets/img/workbench/8.png
  47. BIN
      src/assets/img/workbench/9.png
  48. 1
      src/assets/img/wrong.svg
  49. 48
      src/components/Header.vue
  50. 149
      src/components/Navbar.vue
  51. 260
      src/components/Sidebar.vue
  52. 6
      src/components/img-upload/Cropper.vue
  53. 59
      src/components/quill/index.vue
  54. 23
      src/components/upload/config.js
  55. 34
      src/components/upload/index.vue
  56. 11
      src/components/upload/upload.js
  57. 50
      src/const/ques.js
  58. 28
      src/const/source.js
  59. 34
      src/const/testPaper.js
  60. 51
      src/libs/util.js
  61. 9
      src/main.js
  62. 96
      src/router/index.js
  63. 12
      src/setting.js
  64. 32
      src/store/index.js
  65. 92
      src/utils/api.js
  66. 98
      src/utils/editor.js
  67. 22
      src/utils/http.js
  68. 63
      src/views/Home.vue
  69. 278
      src/views/Login.vue
  70. 464
      src/views/course/AddCurriculum.vue
  71. 204
      src/views/course/AddLink.vue
  72. 327
      src/views/course/Curriculum.vue
  73. 1080
      src/views/course/content/index.vue
  74. 610
      src/views/course/content/source.vue
  75. 304
      src/views/course/contentSettings.vue
  76. 1209
      src/views/course/detail.vue
  77. 332
      src/views/course/list.vue
  78. 802
      src/views/customer/AddCustomer.vue
  79. 33
      src/views/customer/Order.vue
  80. 16
      src/views/customer/Permission.vue
  81. 157
      src/views/customer/customer.vue
  82. 63
      src/views/data/Framework.vue
  83. 52
      src/views/data/Introduce.vue
  84. 51
      src/views/data/Product.vue
  85. 195
      src/views/devLogin.vue
  86. 3
      src/views/information/addArticle/index.vue
  87. 79
      src/views/information/columnManage/index.vue
  88. 21
      src/views/information/contentManage/contentList.vue
  89. 13
      src/views/information/contentManage/index.vue
  90. 13
      src/views/information/list/index.vue
  91. 251
      src/views/market/index.vue
  92. 158
      src/views/match/add/index.vue
  93. 352
      src/views/match/add/set.vue
  94. 398
      src/views/match/add/step1.vue
  95. 255
      src/views/match/add/step2.vue
  96. 285
      src/views/match/add/step3.vue
  97. 9
      src/views/match/add/step4.vue
  98. 211
      src/views/match/add/template.vue
  99. 408
      src/views/match/list/index.vue
  100. 630
      src/views/match/manage/abnormalTeam.vue
  101. Some files were not shown because too many files have changed in this diff Show More

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

2670
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -14,19 +14,26 @@
"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",
"jszip": "^3.10.1", "jszip": "^3.10.1",
"lodash": "^4.17.21",
"mavon-editor": "^2.10.4", "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", "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,11 +1,11 @@
<!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" />
<script src="/styles/tinymce/tinymce.min.js"></script> <meta name="viewport" content="width=device-width, user-scalable=yes, shrink-to-fit=no" />
<title>深圳或然科技中台</title> <title>深圳或然科技中台</title>
</head> </head>
<body> <body>
@ -14,5 +14,6 @@
</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,13 +1,29 @@
<template> <template>
<div id="app"> <div id="app">
<el-radio-group v-if="Setting.isDev" class="ip" v-model="ip" @change="ipChange">
<el-radio :label="0">刘榕ip</el-radio>
<el-radio :label="1">陈赓ip</el-radio>
<el-radio :label="2">测试服ip</el-radio>
</el-radio-group>
<router-view></router-view> <router-view></router-view>
</div> </div>
</template> </template>
<script> <script>
import Setting from '@/setting'
export default { export default {
name: 'App', name: 'App',
data () {
return {
Setting,
ip: localStorage.getItem('ip') ? +localStorage.getItem('ip') : 0,
};
},
created () { created () {
window.exitSystem = () => {
sessionStorage.removeItem('token')
location.reload()
}
//sessionStorage //sessionStorage
if (sessionStorage.getItem("store")) { if (sessionStorage.getItem("store")) {
this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem("store")))) this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem("store"))))
@ -17,14 +33,16 @@
window.addEventListener("beforeunload", () => { window.addEventListener("beforeunload", () => {
sessionStorage.getItem("token") && sessionStorage.setItem("store", JSON.stringify(this.$store.state)) sessionStorage.getItem("token") && sessionStorage.setItem("store", JSON.stringify(this.$store.state))
}) })
},
methods: {
ipChange (val) {
localStorage.setItem('ip', val)
location.reload()
},
} }
} }
</script> </script>
<style> <style>
@import "./assets/css/main.css"; @import "./assets/css/main.css";
/* @import "./assets/css/color-dark.css"; */
/*深色主题*/
@import "./assets/css/theme-green/color-green.css";
/* 浅绿色主题 */
</style> </style>

@ -1,28 +0,0 @@
.header{
background-color: #242f42;
}
.login-wrap{
background: #324157;
}
.plugins-tips{
background: #eef1f6;
}
.plugins-tips a{
color: #20a0ff;
}
.el-upload--text em {
color: #20a0ff;
}
.pure-button{
background: #20a0ff;
}
.tags-li.active {
border: 1px solid #409EFF;
background-color: #409EFF;
}
.message-title{
color: #20a0ff;
}
.collapse-btn:hover{
background: rgb(40,52,70);
}

@ -0,0 +1,7 @@
/* 改变主题色变量 */
$--color-primary: #062c87;
/* 改变 icon 字体路径变量,必需 */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index";

@ -8,16 +8,23 @@ body,
#app, #app,
.wrapper { .wrapper {
width: 100%; width: 100%;
height: 100%; min-height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
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;
} }
@ -53,37 +60,14 @@ li {
.el-table th > .cell { .el-table th > .cell {
font-size: 14px; font-size: 14px;
} }
.content-box {
-webkit-transition: left 0.3s ease-in-out;
transition: left 0.3s ease-in-out;
background: #f0f0f0;
flex: 1;
}
.content {
width: auto;
min-height: 100%;
padding: 20px;
box-sizing: border-box;
}
.content-collapse {
left: 65px;
}
.container {
padding: 30px;
background: #fff;
border: 1px solid #ddd;
border-radius: 5px;
}
.p-title { .p-title {
padding-left: 5px; padding-left: 5px;
margin-bottom: 24px; margin-bottom: 24px;
line-height: 1; line-height: 1;
font-size: 14px; font-size: 14px;
color: #585858; color: #585858;
border-left: 3px solid #9278ff; border-left: 3px solid #062c87;
} }
.el-upload-list { .el-upload-list {
width: 100%; width: 100%;
@ -147,7 +131,7 @@ li {
border-radius: 2px; border-radius: 2px;
} }
.tabs .item.active:after { .tabs .item.active:after {
border-bottom-color: #9278ff; border-bottom-color: #062c87;
} }
.crumbs { .crumbs {
@ -269,16 +253,6 @@ 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;
} }
@ -332,9 +306,10 @@ li {
color: #fff; color: #fff;
} }
#app .el-table th { #app .el-table th {
background-color: #9278ff !important; background-color: #fafafc !important;
font-size: 16px; font-size: 16px;
font-weight: normal; font-weight: normal;
color: #000;
} }
.el-input__inner[type='number'] { .el-input__inner[type='number'] {
@ -381,7 +356,7 @@ li {
} }
.hr_tag { .hr_tag {
background-color: #9278ff; background-color: #062c87;
width: 3px; width: 3px;
height: 15px; height: 15px;
margin-right: 5px; margin-right: 5px;
@ -451,12 +426,15 @@ li {
.el-switch__label span { .el-switch__label span {
font-size: 12px; font-size: 12px;
} }
.m-b-20 { .m-r-5 {
margin-bottom: 20px; margin-right: 5px;
} }
.m-r-10 { .m-r-10 {
margin-right: 10px; margin-right: 10px;
} }
.m-b-20 {
margin-bottom: 20px;
}
@media (max-width: 720px) { @media (max-width: 720px) {
.el-message { .el-message {
min-width: auto !important; min-width: auto !important;
@ -464,7 +442,7 @@ li {
} }
} }
.el-tooltip__popper { .el-tooltip__popper {
max-width: 500px !important; max-width: 100% !important;
} }
.no-atTheMoment > .el-picker-panel__footer > .el-button--text:first-child { .no-atTheMoment > .el-picker-panel__footer > .el-button--text:first-child {
display: none; display: none;
@ -488,3 +466,47 @@ 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;
}
}
.el-drawer__header > :first-child {
font-size: 16px;
font-weight: 600;
color: #333;
}

@ -0,0 +1,189 @@
.msg {
li {
margin-bottom: 10px;
border-top: 1px solid #f1f1f1;
&:first-child {
border-top: 0;
}
.li-wrap {
position: relative;
display: flex;
justify-content: space-between;
padding: 16px 0;
.avatar {
width: 48px;
height: 48px;
border-radius: 50%;
}
.texts {
flex: 1;
margin-left: 24px;
.name {
color: rgba(0, 0, 0, 0.85);
font-size: 16px;
}
.date {
color: rgba(0, 0, 0, 0.45);
font-size: 14px;
}
/deep/img {
max-width: 95%;
}
}
.reply-name {
color: #062c87;
}
.action {
display: inline-flex;
align-items: center;
margin: 15px 10px 0 0;
.icon {
margin: 0 5px;
color: #062c87;
font-size: 18px;
cursor: pointer;
&:hover {
opacity: 0.8;
}
&:first-child {
margin-right: 5px;
}
&.del {
color: rgba(0, 0, 0, 0.65);
border: 1px solid rgba(0, 0, 0, 0.15);
}
}
}
.like-wrap {
display: inline-flex;
align-items: center;
cursor: pointer;
}
}
.reply {
margin-top: 20px;
}
}
&.children {
margin-left: 72px;
padding-left: 24px;
background-color: rgba(0, 0, 0, 0.02);
border-radius: 8px;
li {
border-top-color: rgba(0, 0, 0, 0.06);
}
}
}
.toggle {
margin: 16px 0;
text-align: center;
color: #062c87;
font-size: 14px;
span {
cursor: pointer;
}
}
/deep/.quill {
background-color: #fff;
}
/deep/.timeline {
padding-left: 9%;
overflow: hidden;
.el-timeline-item {
padding-bottom: 40px;
}
.el-timeline-item__node--normal {
top: 30px;
}
.el-timeline-item__wrapper {
top: 15px;
padding-left: 40px;
}
.el-timeline-item__tail {
height: 250%;
border-left-width: 1px;
}
.sign {
position: relative;
display: inline-block;
margin-left: -12.5%;
font-size: 14px;
color: #062c87;
}
.draft {
.ver,
.sign {
color: #b1b1b1;
}
}
.ver {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 10px;
margin: -22px 0 20px;
font-size: 15px;
color: #062c87;
border-bottom: 1px dashed #bfbfbf;
}
.des {
p,
span,
em {
font-size: 14px !important;
}
}
.withdraw {
margin-right: 10px;
font-size: 13px;
color: #979797;
}
.action {
margin-left: 15px;
i {
margin-left: 8px;
font-size: 14px;
color: #062c87;
cursor: pointer;
&:hover {
opacity: 0.9;
}
}
}
.detail {
li {
margin-bottom: 20px;
}
.name {
display: flex;
align-items: center;
margin-bottom: 5px;
font-size: 15px;
font-weight: 600;
img {
width: 20px;
margin-right: 5px;
}
}
.val {
font-size: 14px;
line-height: 1.8;
white-space: pre-wrap;
p {
position: relative;
color: #6a6a6a;
&:before {
content: '';
display: inline-block;
width: 5px;
height: 5px;
margin: 0 10px 0 5px;
vertical-align: middle;
border-radius: 20px;
background-color: #c5b8ff;
}
}
}
}
}

@ -1,29 +0,0 @@
.header{
background-color: #fff;
}
.login-wrap{
background: rgba(56, 157, 170, 0.82);;
}
.plugins-tips{
background: #f2f2f2;
}
.plugins-tips a{
color: #00d1b2;
}
.el-upload--text em {
color: #00d1b2;
}
.pure-button{
background: #00d1b2;
}
.pagination > .active > a, .pagination > .active > a:hover, .pagination > .active > a:focus, .pagination > .active > span, .pagination > .active > span:hover, .pagination > .active > span:focus {
background-color: #00d1b2 !important;
border-color: #00d1b2 !important;
}
.tags-li.active {
border: 1px solid #9278FF;
background-color: #9278FF;
}
.collapse-btn:hover{
background: #00d1b2;
}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1734423793915" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7651" width="16" height="16" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M362.666667 192m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#666666" p-id="7652"></path><path d="M661.333333 192m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#666666" p-id="7653"></path><path d="M362.666667 512m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#666666" p-id="7654"></path><path d="M661.333333 512m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#666666" p-id="7655"></path><path d="M362.666667 832m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#666666" p-id="7656"></path><path d="M661.333333 832m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#666666" p-id="7657"></path></svg>

After

Width:  |  Height:  |  Size: 946 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

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

After

Width:  |  Height:  |  Size: 593 B

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

After

Width:  |  Height:  |  Size: 766 B

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

After

Width:  |  Height:  |  Size: 545 B

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

After

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

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

After

Width:  |  Height:  |  Size: 768 B

@ -1,33 +1,29 @@
<template> <template>
<div class="header flex-between"> <div class="header flex-between">
<div class="logo"> <div class="logo">
<img class="cursor" <img class="cursor" @click="goHome" src="../assets/img/logo.png">
@click="goHome"
src="../assets/img/logo.png">
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="header-user-con"> <div class="header-user-con">
<div class="user" <div class="user" @click="toPerson">
@click="toPerson"> <el-avatar :size="40" :src="$store.state.avatar"></el-avatar>
<el-avatar :size="40"
:src="$store.state.avatar"></el-avatar>
<span class="user-avator">{{ userName }}</span> <span class="user-avator">{{ userName }}</span>
</div> </div>
<el-divider class="ml20" <el-divider class="ml20" direction="vertical"></el-divider>
direction="vertical"></el-divider> <el-button type="text" class="ml20" @click="logout">退出</el-button>
<el-button type="text"
class="ml20"
@click="loginout">退出</el-button>
</div> </div>
</div> </div>
</div> </div>
</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 {
userName: '' timer: null,
Setting,
userName: '',
}; };
}, },
mounted () { mounted () {
@ -39,9 +35,10 @@ export default {
this.$router.push('/person') this.$router.push('/person')
} }
}, },
loginout () { async logout () {
localStorage.removeItem('ms_username'); await this.$post(this.api.logout)
localStorage.removeItem('token'); localStorage.removeItem('ms_username')
localStorage.removeItem('token')
sessionStorage.clear() sessionStorage.clear()
location.reload() location.reload()
}, },
@ -83,6 +80,12 @@ 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 () {
@ -94,6 +97,7 @@ 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 => { })
}, },
}, },
@ -108,54 +112,66 @@ export default {
font-size: 16px; font-size: 16px;
color: #333; color: #333;
} }
.header .logo { .header .logo {
float: left; float: left;
width: 170px; width: 170px;
height: 40px; height: 40px;
margin-left: 20px; margin-left: 20px;
} }
.header .logo img { .header .logo img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.header-right { .header-right {
float: right; float: right;
padding-right: 50px; padding-right: 50px;
} }
.header-user-con { .header-user-con {
display: flex; display: flex;
height: 70px; height: 70px;
align-items: center; align-items: center;
} }
.header-user-con .user { .header-user-con .user {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
cursor: pointer; cursor: pointer;
} }
.user-avator { .user-avator {
cursor: pointer; cursor: pointer;
margin-left: 10px; margin-left: 10px;
font-size: 12px; font-size: 12px;
} }
.ml20 { .ml20 {
margin-left: 20px; margin-left: 20px;
} }
.user-avator img { .user-avator img {
display: block; display: block;
width: 40px; width: 40px;
height: 40px; height: 40px;
border-radius: 50%; border-radius: 50%;
} }
/deep/.header-right .el-button--text { /deep/.header-right .el-button--text {
color: #333; color: #333;
span { span {
font-size: 12px; font-size: 12px;
} }
} }
.header-right .el-divider--vertical { .header-right .el-divider--vertical {
width: 2px; width: 2px;
height: 15px; height: 15px;
} }
.header-right .el-divider { .header-right .el-divider {
background-color: #333; background-color: #333;
} }

@ -0,0 +1,149 @@
<template>
<div class="menus">
<el-menu class="nav" :default-active="onRoutes" background-color="#062c87" text-color="#fff"
active-text-color="#333" unique-opened mode="horizontal" router @select="handleSelect">
<template v-for="item in menus">
<template v-if="item.subs">
<el-submenu :index="item.index" :key="item.index">
<template slot="title">
<!-- <i :class="item.icon"></i> -->
<span slot="title">{{ item.title }}</span>
</template>
<template v-for="subItem in item.subs">
<el-submenu v-if="subItem.subs" :index="subItem.index" :key="subItem.index">
<template slot="title">{{ subItem.title }}</template>
<el-menu-item v-for="(threeItem, i) in subItem.subs" :key="i" :index="threeItem.index">{{
threeItem.title
}}</el-menu-item>
</el-submenu>
<el-menu-item v-else :index="subItem.index" :key="subItem.index">{{ subItem.title }}</el-menu-item>
</template>
</el-submenu>
</template>
<template v-else>
<el-menu-item :index="item.index" :key="item.index">
<!-- <i :class="item.icon"></i> -->
<span slot="title">{{ item.title }}</span>
</el-menu-item>
</template>
</template>
</el-menu>
</div>
</template>
<script>
import Setting from '@/setting'
import addRoutes from '@/libs/route/addRoutes'
export default {
data () {
return {
menuList: [
{
icon: 'el-icon-school',
index: '/workbench',
title: '工作台'
},
{
icon: 'el-icon-user',
index: '/customer',
title: '客户管理'
},
{
icon: 'el-icon-shopping-bag-2',
index: '/user',
title: '用户管理'
},
{
icon: 'el-icon-document-checked',
index: '/order',
title: '订单管理'
},
{
icon: 'el-icon-office-building',
index: '/system',
title: '系统配置'
},
],
menus: [],
onRoutes: this.$route.path
};
},
watch: {
"$route.path": function (val) {
this.menuList.map(e => {
if (val.replace('/', '') === e.index) {
this.handleSelect(val.replace('/', ''))
this.$forceUpdate();
}
})
}
},
mounted () {
sessionStorage.getItem('token') && this.getPer() //
},
methods: {
handleSelect (index) {
this.onRoutes = index
this.$store.commit('setInfoTab', '1')
this.$store.commit('setColumnId', '')
this.$store.commit('setCompetitionCache', null)
},
initMenu () {
if (Setting.dynamicRoute) {
this.menus = this.menuList
return false
const routes = this.$store.state.routes
const menus = []
this.menuList.map(e => {
routes.find(n => n.path === e.index) && menus.push(e)
})
this.menus = menus
} else {
this.menus = this.menuList
}
},
//
getPer () {
this.$get(`${this.api.getUserRolesPermissionMenu}?platformId=${Setting.platformId}`).then(res => {
const routes = res.permissionMenu[0].children
addRoutes(routes)
this.initMenu()
this.$store.commit('setDataPer', res.dataPermissionList)
}).catch(err => {
if (err.status === 500) {
localStorage.removeItem('ms_username');
sessionStorage.clear()
location.reload()
}
})
},
}
};
</script>
<style lang="scss" scoped>
.menus {
z-index: 2000;
position: sticky;
top: 0;
display: flex;
justify-content: center;
background-color: #062c87;
/deep/.nav {
border-bottom: 0;
&>.el-menu-item {
height: 56px;
padding: 0 30px;
line-height: 56px;
}
&>.el-menu-item.is-active {
background-color: #fff !important;
border-bottom: 0;
}
}
}
</style>

@ -1,41 +1,26 @@
<template> <template>
<div> <div class="sidebar">
<el-menu class="sidebar-el-menu" <el-menu :default-active="active" :default-openeds="['1', '2', '3', '4']" background-color="#fff" text-color="#333"
:default-active="onRoutes" active-text-color="#062c87" router>
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.children">
<el-submenu :index="item.index" <el-submenu :index="item.index" :key="item.index">
:key="item.index">
<template slot="title"> <template slot="title">
<i :class="item.icon"></i>
<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.children">
<el-submenu v-if="subItem.subs" <el-submenu v-if="subItem.children" :index="subItem.index" :key="subItem.index">
:index="subItem.index"
:key="subItem.index">
<template slot="title">{{ subItem.title }}</template> <template slot="title">{{ subItem.title }}</template>
<el-menu-item v-for="(threeItem,i) in subItem.subs" <el-menu-item v-for="(threeItem, i) in subItem.children" :key="i" :index="threeItem.index">{{
:key="i" threeItem.title
:index="threeItem.index">{{ threeItem.title }}</el-menu-item> }}</el-menu-item>
</el-submenu> </el-submenu>
<el-menu-item v-else <el-menu-item v-else :index="subItem.index" :key="subItem.index">{{ subItem.title }}</el-menu-item>
:index="subItem.index"
:key="subItem.index">{{ subItem.title }}</el-menu-item>
</template> </template>
</el-submenu> </el-submenu>
</template> </template>
<template v-else> <template v-else>
<el-menu-item :index="item.index" <el-menu-item :index="item.index" :key="item.index">
:key="item.index">
<i :class="item.icon"></i>
<span slot="title">{{ item.title }}</span> <span slot="title">{{ item.title }}</span>
</el-menu-item> </el-menu-item>
</template> </template>
@ -46,142 +31,203 @@
<script> <script>
import Setting from '@/setting' import Setting from '@/setting'
import addRoutes from '@/libs/route/addRoutes'
export default { export default {
props: ['path'],
data () { data () {
return { return {
menuList: [ active: '',
defaultMenus: [
{ {
icon: 'el-icon-school', index: '1',
index: '/customer', title: '系统后台',
title: '客户管理' children: [
{
index: '/configure?id=1',
title: 'Python系统'
}, },
{ {
icon: 'el-icon-user', index: '/theoryExam',
index: '/user', title: '理论考试系统'
title: '用户管理'
}, },
{ {
icon: 'el-icon-shopping-bag-2', index: '/configure?id=3',
index: '/order', title: '金融产品设计及数字化营销沙盘系统'
title: '订单管理'
}, },
{ {
icon: 'el-icon-document-checked', index: '/configure?id=4',
index: '/curriculum', title: '银行综合系统'
title: '课程管理'
}, },
{ {
icon: 'el-icon-notebook-2', index: '/configure?id=5',
index: '/data', title: '众筹系统'
title: '数据管理' },
]
}, },
{ {
icon: 'el-icon-tickets', index: '2',
index: '/match', title: '职站教学后台',
title: '大赛管理' children: [
{
index: '/curriculum',
title: '教学课程管理'
}, },
{ {
icon: 'el-icon-takeaway-box',
index: '/theoreticalCourse', index: '/theoreticalCourse',
title: '理论课程' title: '精品课程管理'
}, },
{ {
icon: 'el-icon-box',
index: '/information', index: '/information',
title: '资讯管理' title: '资讯管理'
}, },
{ {
icon: 'el-icon-receiving', index: '/resourse',
index: '/configure', title: '资源库'
title: '服务配置'
}, },
]
},
{
index: '3',
title: '职站商城后台',
children: [
{ {
icon: 'el-icon-office-building', index: '/shop',
index: '/system', title: '产品管理'
title: '系统配置'
}, },
{ {
icon: 'el-icon-s-check', index: '/market',
index: '/parner', title: '营销管理'
title: '合伙管理'
}, },
{ {
icon: 'el-icon-data-line',
index: '/parnerOperation', index: '/parnerOperation',
title: '合伙运营' title: '小程序内容管理'
}, },
{ {
icon: 'el-icon-s-shop', index: '/parner',
index: '/shop', title: '销售代理人管理'
title: '商城管理' },
]
},
{
index: '4',
title: '运营后台',
children: [
{
index: '/match',
title: '大赛管理'
},
{
index: '/data',
title: '数据管理'
},
{
index: '/review',
title: '评阅管理'
},
]
}, },
], ],
menus: [], menus: [],
onRoutes: this.$route.path
}; };
}, },
watch: { watch: {
"$route.path": function (val) { path: {
this.menuList.map(e => { handler (val) {
if (val.replace('/', '') === e.index) { this.active = val === '/configure' ? `/configure?id=${this.$route.query.id}` : val
this.handleSelect(val.replace('/', '')) },
this.$forceUpdate(); immediate: true
}
})
} }
}, },
mounted () { mounted () {
// sessionStorage.getItem('sideBar') && this.handleSelect(sessionStorage.getItem('sideBar')) Setting.dynamicRoute && this.initTabs()
sessionStorage.getItem('token') && this.getPer() //
}, },
methods: { methods: {
handleSelect (index) { initTabs () {
this.onRoutes = index const { btns } = this.$store.state
this.$store.commit('setOrderParam', null) const tabs = this.defaultMenus
this.$store.commit('setInfoTab', '1') btns.includes('/configure') && this.menus.push(tabs[0])
this.$store.commit('setColumnId', '')
this.$store.commit('setCompetitionCache', null) const children1 = []
sessionStorage.setItem('sideBar', index) btns.includes('/curriculum') && children1.push(tabs[1].children[0])
}, btns.includes('/theoreticalCourse') && children1.push(tabs[1].children[1])
initMenu () { btns.includes('/information') && children1.push(tabs[1].children[2])
if (Setting.dynamicRoute) { btns.includes('/resourse') && children1.push(tabs[1].children[3])
const routes = this.$store.state.routes this.menus.push({
const menus = [] index: '2',
this.menuList.map(e => { title: '职站教学后台',
routes.find(n => n.path === e.index) && menus.push(e) children: children1
}) })
this.menus = menus
} else { const children2 = []
this.menus = this.menuList btns.includes('/shop:产品管理') && children2.push(tabs[2].children[0])
} btns.includes('/shop:营销推广管理') && children2.push(tabs[2].children[1])
}, btns.includes('/parnerOperation') && children2.push(tabs[2].children[2])
// btns.includes('/parner') && children2.push(tabs[2].children[3])
getPer () { this.menus.push({
this.$get(`${this.api.getUserRolesPermissionMenu}?platformId=${Setting.platformId}`).then(res => { index: '3',
const routes = res.permissionMenu[0].children title: '职站商城后台',
addRoutes(routes) children: children2
this.initMenu() })
this.$store.commit('setDataPer', res.dataPermissionList)
}).catch(err => { const children3 = []
if (err.status === 500) { btns.includes('/match') && children3.push(tabs[3].children[0])
localStorage.removeItem('ms_username'); btns.includes('/data') && children3.push(tabs[3].children[1])
sessionStorage.clear() btns.includes('/review') && children3.push(tabs[3].children[2])
location.reload() this.menus.push({
} index: '4',
title: '运营后台',
children: children3
}) })
}, },
handleSelect (index) {
},
} }
}; };
</script> </script>
<style scoped> <style lang="scss" scoped>
.sidebar {
min-width: 200px;
max-width: 200px;
height: calc(100vh - 116px);
overflow: auto;
// transition: .5s;
transform: translateX(-200px);
&.show {
transform: translateX(0);
}
/deep/.el-menu {
border-right: 0 !important;
.el-menu-item,
.el-submenu__title {
height: 40px;
line-height: 40px;
&.is-active {
font-weight: 600;
}
}
.el-menu .el-menu-item {
padding: 0 20px 0 40px !important;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
.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%;
} }

@ -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', res) that.$emit('upload', data)
}) // })
}) })
} else { } else {
this.$refs.cropper.getCropData(data => { this.$refs.cropper.getCropData(data => {

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

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

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

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

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

@ -0,0 +1,28 @@
export default {
types: [
{
id: 1,
name: '演示文稿类'
},
{
id: 2,
name: '视频类'
},
{
id: 3,
name: '图形类'
},
{
id: 4,
name: '文本类'
},
{
id: 5,
name: '音频类'
},
{
id: 6,
name: '其他'
},
],
}

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

@ -1,6 +1,9 @@
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 = {
@ -158,6 +161,54 @@ const util = {
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

@ -2,8 +2,7 @@ import Vue from 'vue';
import App from './App.vue'; import App from './App.vue';
import router from './router'; import router from './router';
import ElementUI from 'element-ui'; import ElementUI from 'element-ui';
// import 'element-ui/lib/theme-chalk/index.css'; // 默认主题 import "@/assets/css/default/index.scss";
import './assets/css/theme-green/index.css'; // 浅绿色主题
import './assets/css/icon.css'; import './assets/css/icon.css';
import './assets/icon/iconfont.css'; import './assets/icon/iconfont.css';
import 'babel-polyfill'; import 'babel-polyfill';
@ -11,8 +10,10 @@ import './utils/rem';
import { post, get, del, put } from './utils/http'; import { post, get, del, put } from './utils/http';
import api from './utils/api'; import api from './utils/api';
import store from './store' import store from './store'
import { systemStatus, systemTypeStatus, systemAttributionStatus, courseTypeStatus, import {
hoursStatus, roleStatus, orderTypeFn, orderStatusFn, orderNatureFn, Percentage, removeByValue, isIE, encodeString, formatDate, downloadFile, dateCompatible } from './utils/core'; systemStatus, systemTypeStatus, systemAttributionStatus, courseTypeStatus,
hoursStatus, roleStatus, orderTypeFn, orderStatusFn, orderNatureFn, Percentage, removeByValue, isIE, encodeString, formatDate, downloadFile, dateCompatible
} from './utils/core';
import preventReClick from './utils/preventReClick' //防多次点击,重复提交 import preventReClick from './utils/preventReClick' //防多次点击,重复提交
import plugins from '@/directive'; import plugins from '@/directive';

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

@ -5,18 +5,20 @@ const url = location.host;
const isDev = process.env.NODE_ENV === 'development' // 开发环境 const isDev = process.env.NODE_ENV === 'development' // 开发环境
const isPro = url.includes('huorantech.cn') //正式服 const isPro = url.includes('huorantech.cn') //正式服
let jumpPath = `${location.origin}/judgmentPoint` let jumpPath = `${location.origin}/panfen/`
let sandPath = `${location.origin}/sandbox` // 沙盘地址 let sandPath = `https://www.occupationlab.com/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` sandPath = `http://${location.hostname}:9520`
host = 'http://121.37.12.51/' host = 'http://121.37.12.51/'
// host = 'https://huorantech.cn/' // host = 'https://huorantech.cn/'
host = 'http://192.168.31.217:9000/'// 榕 const ips = ['http://192.168.31.217:9000/', 'http://192.168.31.51:9000/', 'https://occupationlab.com/']
// host = 'http://192.168.31.51:9000/'// 赓 host = ips[+localStorage.getItem('ip')]
} else if (isPro) { } else if (isPro) {
jumpPath = 'https://www.huorantech.cn/judgmentPoint/' sandPath = `https://izhixinyun.com/sandbox`
// jumpPath = 'https://judgment.huorantech.cn/'
} }

@ -21,14 +21,13 @@ 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,
referrer: '',
innerReferrer: '',
orderParam: null, orderParam: null,
competitionCache: null
}, },
actions: { actions: {
setSystemId({ state,commit },systemId) { setSystemId({ state,commit },systemId) {
@ -54,15 +53,6 @@ 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
}, },
@ -75,10 +65,6 @@ 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
@ -105,12 +91,18 @@ 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
},
} }
}); });

@ -1,8 +1,6 @@
import Setting from "@/setting"; import Setting from "@/setting";
const host = Setting.apiBaseURL const { apiBaseURL: host } = Setting
const uploadURL = Setting.uploadURL
export default { export default {
logins: `users/users/user/login`, //登录 logins: `users/users/user/login`, //登录
@ -12,11 +10,18 @@ export default {
getUserRolesPermissionMenu: `users/users/user-role/getUserRolesPermissionMenu`, getUserRolesPermissionMenu: `users/users/user-role/getUserRolesPermissionMenu`,
deleteProfile: `users/users/userInfo/deleteProfile`, deleteProfile: `users/users/userInfo/deleteProfile`,
refreshPageNotification: `nakadai/message/refreshPageNotification`, refreshPageNotification: `nakadai/message/refreshPageNotification`,
heartbeatDetection: `nakadai/message/heartbeatDetection`,
getCurrentTime: `competition/competition/management/getCurrentTime`,
getToken: `users/users/user/getToken`,
logout: `users/users/user/logout`,
// 阿里云文件/视频管理 // 阿里云文件/视频管理
getPlayAuth: `${uploadURL}oss/manage/getPlayAuth`, // 获取播放凭证 getPlayAuth: `nakadai/nakadai/oss/getPlayAuth`, // 获取播放凭证
encrypt: `nakadai/data/encrypt`,
staffTemplate: `http://www.huorantech.cn/template/%E6%89%B9%E9%87%8F%E5%AF%BC%E5%85%A5%E5%91%98%E5%B7%A5%E6%A8%A1%E6%9D%BF.xlsx`, // 后台账号模板 staffTemplate: `https://occupationlab.com/template/%E6%89%B9%E9%87%8F%E5%AF%BC%E5%85%A5%E5%91%98%E5%B7%A5%E6%A8%A1%E6%9D%BF.xlsx`, // 后台账号模板
competionPersonTemplate: `https://www.occupationlab.com/template/中台个人赛报名人员导入模板.xlsx`, // 中台个人报名人员模板
competionTeamTemplate: `https://www.occupationlab.com/template/中台团队赛报名人员导入模板.xlsx`, // 中台团队报名人员模板
checkEmailOrPhone: `occupationlab/occupationlab/architecture/checkEmailOrPhone`, // 新增学生前:校验手机号或者邮箱 checkEmailOrPhone: `occupationlab/occupationlab/architecture/checkEmailOrPhone`, // 新增学生前:校验手机号或者邮箱
checkWorkNumOrAccount: `occupationlab/occupationlab/architecture/checkWorkNumOrAccount`, // 新增/编辑学生前:校验学号或者学生账号 checkWorkNumOrAccount: `occupationlab/occupationlab/architecture/checkWorkNumOrAccount`, // 新增/编辑学生前:校验学号或者学生账号
@ -33,6 +38,7 @@ export default {
getOrderOtherTime: `nakadai/nakadai/orderOther/getOrderOtherTime`, getOrderOtherTime: `nakadai/nakadai/orderOther/getOrderOtherTime`,
refreshCache: `data/data/myDate/refreshCache`, refreshCache: `data/data/myDate/refreshCache`,
getPartnerTeamRates: `nakadai/nakadai/partner-team/getPartnerTeamRates`, getPartnerTeamRates: `nakadai/nakadai/partner-team/getPartnerTeamRates`,
getCustomerOrderRecord: `nakadai/nakadai/order/getCustomerOrderRecord`,
// 客户管理 // 客户管理
delCustomers: `nakadai/nakadai/customer/delCustomers`, delCustomers: `nakadai/nakadai/customer/delCustomers`,
@ -49,6 +55,11 @@ export default {
exportSubscribedRecords: `nakadai/nakadai/order/exportSubscribedRecords`, exportSubscribedRecords: `nakadai/nakadai/order/exportSubscribedRecords`,
addNewCustomersByOneself: `nakadai/nakadai/school/addNewCustomersByOneself`, addNewCustomersByOneself: `nakadai/nakadai/school/addNewCustomersByOneself`,
exportClient: `${host}nakadai/nakadai/customer/exportClient`, exportClient: `${host}nakadai/nakadai/customer/exportClient`,
customerSettingsList: `nakadai/nakadai/customer/customerSettingsList`,
clientSettingsEditClient: `nakadai/nakadai/customer/clientSettingsEditClient`,
delClientsOrSchools: `nakadai/nakadai/school/delClientsOrSchools`,
editClientsOrSchools: `nakadai/nakadai/school/editClientsOrSchools`,
userManagementList: `users/users/userAccount/userManagementList`,
resetPwdCustomer: `nakadai/nakadai/customer/resetPwd`, resetPwdCustomer: `nakadai/nakadai/customer/resetPwd`,
queryCustomerIsExists: `nakadai/nakadai/customer/queryCustomerIsExists`, queryCustomerIsExists: `nakadai/nakadai/customer/queryCustomerIsExists`,
@ -60,7 +71,7 @@ export default {
getBusinessManagerOrder: `nakadai/nakadai/customer/getBusinessManagerOrder`, getBusinessManagerOrder: `nakadai/nakadai/customer/getBusinessManagerOrder`,
// 用户管理 // 用户管理
delUserAccounts: `users/users/userAccount/delUserAccounts`, delUserAccountsByNakadai: `users/users/userAccount/delUserAccountsByNakadai`,
queryUserInfoDetails: `users/users/userAccount/queryUserInfoDetails`, queryUserInfoDetails: `users/users/userAccount/queryUserInfoDetails`,
personalFile: `users/users/userAccount/personalFile`, personalFile: `users/users/userAccount/personalFile`,
@ -79,7 +90,8 @@ export default {
oneClickEnableVerification: `users/users/userAccount/oneClickEnableVerification`, oneClickEnableVerification: `users/users/userAccount/oneClickEnableVerification`,
getValueModule: `nakadai/nakadai/valueModuleManagement/getValueModule`, getValueModule: `nakadai/nakadai/valueModuleManagement/getValueModule`,
queryServiceConfig: `nakadai/nakadai/serviceConfiguration/getAllService`, //查询服务配置 queryServiceConfig: `nakadai/nakadai/serviceConfiguration/getAllService`,
workbenchSystemDemonstration: `nakadai/nakadai/serviceConfiguration/workbenchSystemDemonstration`,
// 项目管理 // 项目管理
avgValues: `occupationlab/occupationlab/projectManage/avgValues`, // 平均分分配值 avgValues: `occupationlab/occupationlab/projectManage/avgValues`, // 平均分分配值
deleteProjectManage: `occupationlab/occupationlab/projectManage/deleteProjectManage`, // 新增项目管理 deleteProjectManage: `occupationlab/occupationlab/projectManage/deleteProjectManage`, // 新增项目管理
@ -94,8 +106,8 @@ export default {
editProjectDraft: `occupationlab/occupationlab/projectManage/editProjectDraft`, // 修改项目管理 editProjectDraft: `occupationlab/occupationlab/projectManage/editProjectDraft`, // 修改项目管理
copyProjectManage: `occupationlab/occupationlab/projectManage/copyProjectManage`, // 复制项目管理 copyProjectManage: `occupationlab/occupationlab/projectManage/copyProjectManage`, // 复制项目管理
// 判分点 // 判分点
getBcJudgmentPoint: `judgment/judgment/bcJudgmentPoint/getBcJudgmentPoint`, // 获取编程类判分点列表(分页) getBcJudgmentPoint: `${host}judgment/judgment/bcJudgmentPoint/getBcJudgmentPoint`, // 获取编程类判分点列表(分页)
getLcJudgmentPoint: `judgment/judgment/lcJudgmentPoint/queryAllJudgmentPoint`, // 获取流程类判分点列表(分页) getLcJudgmentPoint: `${host}judgment/judgment/lcJudgmentPoint/queryAllJudgmentPoint`, // 获取流程类判分点列表(分页)
addProjectJudgment: `occupationlab/occupationlab/projectJudgment/addProjectJudgment`, // 添加项目管理、判分点中间表 addProjectJudgment: `occupationlab/occupationlab/projectJudgment/addProjectJudgment`, // 添加项目管理、判分点中间表
updateProjectJudgment: `occupationlab/occupationlab/projectJudgment/updateProjectJudgment`, // 判分点中间表批量更新 updateProjectJudgment: `occupationlab/occupationlab/projectJudgment/updateProjectJudgment`, // 判分点中间表批量更新
deleteProjectJudgment: `occupationlab/occupationlab/projectJudgment/deleteProjectJudgment`, // 判分点中间表批量删除 deleteProjectJudgment: `occupationlab/occupationlab/projectJudgment/deleteProjectJudgment`, // 判分点中间表批量删除
@ -144,7 +156,9 @@ export default {
courseProfessional: `nakadai/nakadai/subject/courseProfessional`, //课程专业 courseProfessional: `nakadai/nakadai/subject/courseProfessional`, //课程专业
//课程管理 //课程管理
curriculumList: `nakadai/nakadai/curriculum/curriculumList`, //课程列表 curriculumList: `nakadai/nakadai/curriculum/curriculumList`, //课程列表
curriculumTree: `nakadai/nakadai/curriculum/curriculumTree`,
createCurriculum: `nakadai/nakadai/curriculum/createCurriculum`, //创建课程 createCurriculum: `nakadai/nakadai/curriculum/createCurriculum`, //创建课程
configureCourseProject: `nakadai/nakadai/curriculum/configureCourseProject`,
curriculumDetail: `nakadai/nakadai/curriculum/curriculumDetail`, //课程详情 curriculumDetail: `nakadai/nakadai/curriculum/curriculumDetail`, //课程详情
modifyCourse: `nakadai/nakadai/curriculum/modifyCourse`, //编辑课程 modifyCourse: `nakadai/nakadai/curriculum/modifyCourse`, //编辑课程
delCourse: `nakadai/nakadai/curriculum/delCourse`, //单个、批量删除课程 delCourse: `nakadai/nakadai/curriculum/delCourse`, //单个、批量删除课程
@ -152,6 +166,27 @@ export default {
getInternalProjectBySystemId: `occupationlab/occupationlab/projectManage/getInternalProjectBySystemId`, //根据系统id、项目权限获取系统内置项目 getInternalProjectBySystemId: `occupationlab/occupationlab/projectManage/getInternalProjectBySystemId`, //根据系统id、项目权限获取系统内置项目
checkConfig: `nakadai/nakadai/curriculum/checkConfig`, checkConfig: `nakadai/nakadai/curriculum/checkConfig`,
deleteCoursePrompt: `nakadai/nakadai/curriculum/deleteCoursePrompt`, deleteCoursePrompt: `nakadai/nakadai/curriculum/deleteCoursePrompt`,
combinationResource: `nakadai/nakadai/curriculum/combinationResource`,
replaceResource: `nakadai/nakadai/curriculum/subsection/replaceResource`,
curriculumChapter: `nakadai/nakadai/curriculum/chapter/queryChaptersAndSubsections`,
courseLearningProgress: 'nakadai/nakadai/curriculum/learning/progressprogress/courseLearningProgress',
deleteLearningProgress: 'nakadai/nakadai/curriculum/learning/progressprogress/delete',
curriculumGetSubsection: `nakadai/nakadai/curriculum/subsection/getSubsection`,
copySelfBuildCourse: `nakadai/nakadai/curriculum/copySelfBuildCourse`,
// 课程笔记
addNote: `nakadai/curriculumNotes/addNote`,
curriculumNoteList: `nakadai/curriculumNotes/curriculumNoteList`,
deleteNotes: `nakadai/curriculumNotes/deleteNotes`,
updateNote: `nakadai/curriculumNotes/updateNote`,
// 教学互动
addCommentStation: `nakadai/comment/addComment`,
commentTreeList: `nakadai/comment/commentTreeList`,
deleteAComment: `nakadai/comment/deleteAComment`,
commentAndLike: `nakadai/commentLike/commentAndLike`,
unlike: `nakadai/commentLike/unlike`,
messageNotificationList: `nakadai/notify/messageNotificationList`,
noticeRead: `nakadai/notify/noticeRead`,
// 课程章节管理 // 课程章节管理
addChapter: `nakadai/nakadai/curriculum/chapter/addChapter`, //添加章节 addChapter: `nakadai/nakadai/curriculum/chapter/addChapter`, //添加章节
editChapter: `nakadai/nakadai/curriculum/chapter/editChapter`, //修改章节 editChapter: `nakadai/nakadai/curriculum/chapter/editChapter`, //修改章节
@ -168,6 +203,7 @@ export default {
delTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/batchDeletion`, delTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/batchDeletion`,
findTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/findById`, findTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/findById`,
listTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/pageConditionalQueryCourse`, listTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/pageConditionalQueryCourse`,
boutiqueCurriculumTree: `occupationlab/occupationlab/theoreticalCourse/boutiqueCurriculumTree`,
saveTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/save`, saveTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/save`,
updateTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/update`, updateTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/update`,
disabledTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/disabledEvents`, disabledTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/disabledEvents`,
@ -194,6 +230,8 @@ export default {
deleteSubsectionTheoretical: `occupationlab/occupationlab/theoreticalCourseSubsection/deleteSubsection`, // 根据id删除小节 deleteSubsectionTheoretical: `occupationlab/occupationlab/theoreticalCourseSubsection/deleteSubsection`, // 根据id删除小节
editSubsectionTheoretical: `occupationlab/occupationlab/theoreticalCourseSubsection/editSubsection`, // 修改小节 editSubsectionTheoretical: `occupationlab/occupationlab/theoreticalCourseSubsection/editSubsection`, // 修改小节
getSubsectionTheoretical: `occupationlab/occupationlab/theoreticalCourseSubsection/getSubsection`, // 根据小节id获取预览文件地址 getSubsectionTheoretical: `occupationlab/occupationlab/theoreticalCourseSubsection/getSubsection`, // 根据小节id获取预览文件地址
batchDeletionTheoretical: `occupationlab/occupationlab/theoreticalCourseSubsection/batchDeletion`,
deleteSubsectionBatch: `nakadai/nakadai/curriculum/subsection/deleteSubsectionBatch`,
// 栏目管理 // 栏目管理
addColumn: `occupationlab/occupationlab/information/column/addColumn`, addColumn: `occupationlab/occupationlab/information/column/addColumn`,
@ -321,6 +359,23 @@ export default {
detailsOfCompetitionStage: `competition/competition/management/detailsOfCompetitionStage`, detailsOfCompetitionStage: `competition/competition/management/detailsOfCompetitionStage`,
entryInformation: `competition/competition/team/entryInformation`, entryInformation: `competition/competition/team/entryInformation`,
getRedisCacheCompetition: `competition/competition/management/getRedisCache`, getRedisCacheCompetition: `competition/competition/management/getRedisCache`,
copyCompetition: `competition/competition/management/copyCompetition`,
checkCustomerBySchool: `competition/competition/team/checkCustomerBySchool`,
updateEventAllocationRecord: `competition/competitionAutomaticAllocationRecord/updateEventAllocationRecord`,
editWhetherPopUpsAppear: `competition/competitionAutomaticAllocationRecord/editWhetherPopUpsAppear`,
automaticAllocation: `competition/competition/automaticAllocation/automaticAllocation`,
checkTeamStatus: `competition/teamAbnormalInformation/checkTeamStatus`,
queryAbnormalTeam: `competition/teamAbnormalInformation/queryAbnormalTeam`,
viewEventAllocationInformation: `competition/competitionAutomaticAllocationRecord/viewEventAllocationInformation`,
getCompetitionProjectByMiddleGround: `occupationlab/occupationlab/projectManage/getCompetitionProjectByMiddleGround`,
libraryList: `exam/exam/paperLibrary/libraryList`,
examPaperList: `exam/exam/paper/examPaperList`,
copyExamPaper: `exam/exam/paper/copyExamPaper`,
getDetailedExamScores: `exam/exam/paper/getDetailedExamScores`,
exportExamPaperReport: `exam/exam/paper/exportExamPaperReport`,
exportLabReport: `${host}occupationlab/occupationlab/achievement/exportLabReport`,
exportBankExperimentReport: `${host}occupationlab/occupationlab/achievement/exportBankExperimentReport`,
getServiceOfType: `nakadai/nakadai/serviceConfiguration/getServiceOfType`,
// 赛事内容 // 赛事内容
addCompetitionContent: `competition/competition/content/addCompetitionContent`, addCompetitionContent: `competition/competition/content/addCompetitionContent`,
@ -368,6 +423,14 @@ export default {
enquireAboutSchoolStudents: `users/users/userAccount/enquireAboutSchoolStudents`, enquireAboutSchoolStudents: `users/users/userAccount/enquireAboutSchoolStudents`,
cancelParticipant: `competition/competition/teamParticipant/cancelParticipant`, cancelParticipant: `competition/competition/teamParticipant/cancelParticipant`,
schoolsInCompetitionArea: `competition/competition/range/schoolsInCompetitionArea`, schoolsInCompetitionArea: `competition/competition/range/schoolsInCompetitionArea`,
batchDeleteApplicants: `competition/competition/registration/batchDeleteApplicants`,
deleteAllData: `competition/competition/registration/deleteAllData`,
whetherThereIsReport: `competition/competitionAutomaticAllocationRecord/whetherThereIsReport`,
closePopup: `competition/competitionAutomaticAllocationRecord/closePopup`,
batchImportPersonalData: `${host}competition/competition/registration/batchImportPersonalData`,
batchImportTeamData: `${host}competition/competition/registration/batchImportTeamData`,
TeamDataExportFailure: `${host}competition/competition/registration/exportFailure`,
exportAbnormalData: `${host}competition/teamAbnormalInformation/exportAbnormalData`,
// 赛事公告 // 赛事公告
addAnnouncement: `competition/competition/announcement/addAnnouncement`, addAnnouncement: `competition/competition/announcement/addAnnouncement`,
amendmentAnnouncement: `competition/competition/announcement/amendmentAnnouncement`, amendmentAnnouncement: `competition/competition/announcement/amendmentAnnouncement`,
@ -380,9 +443,12 @@ export default {
batchDeleteContestGrade: `competition/competition/performance/batchDeleteContestGrade`, batchDeleteContestGrade: `competition/competition/performance/batchDeleteContestGrade`,
batchImportGrades: `${host}competition/competition/performance/batchImportGrades`, batchImportGrades: `${host}competition/competition/performance/batchImportGrades`,
exportExperimentalResultsInBatch: `${host}competition/competition/performance/exportExperimentalResultsInBatch`, exportExperimentalResultsInBatch: `${host}competition/competition/performance/exportExperimentalResultsInBatch`,
exportExamPaperReports: `${host}exam/exam/paper/exportExamPaperReports`,
batchExportReportsAsZip: `${host}occupationlab/occupationlab/achievement/batchExportReportsAsZip`,
performanceExportFailure: `${host}competition/competition/performance/exportFailure`, performanceExportFailure: `${host}competition/competition/performance/exportFailure`,
rankExportFailure: `${host}competition/competition/rank/exportFailure`, rankExportFailure: `${host}competition/competition/rank/exportFailure`,
batchImportRanking: `${host}competition/competition/rank/batchImportRanking`, batchImportRanking: `${host}competition/competition/rank/batchImportRanking`,
getPaperUploadFileZip: `${host}exam/exam/paper/question/userAnswer/getPaperUploadFileZip`,
stageGradeManagementList: `competition/competition/performance/stageGradeManagementList`, stageGradeManagementList: `competition/competition/performance/stageGradeManagementList`,
stageRaceRanking: `competition/competition/rank/stageRaceRanking`, stageRaceRanking: `competition/competition/rank/stageRaceRanking`,
overallStandingsInThePointsRace: `competition/competition/rank/overallStandingsInThePointsRace`, overallStandingsInThePointsRace: `competition/competition/rank/overallStandingsInThePointsRace`,
@ -408,10 +474,12 @@ export default {
getCompetitionStageRankingTime: `competition/competitionReleaseTime/getCompetitionStageRankingTime`, getCompetitionStageRankingTime: `competition/competitionReleaseTime/getCompetitionStageRankingTime`,
frontOfficeCompetitionRanking: `competition/competition/rank/frontOfficeCompetitionRanking`, frontOfficeCompetitionRanking: `competition/competition/rank/frontOfficeCompetitionRanking`,
cCompetitionStageFileList: `competition/cCompetitionStageFile/listByEntity`, cCompetitionStageFileList: `competition/cCompetitionStageFile/listByEntity`,
getPaperUploadFile: `exam/exam/paper/question/userAnswer/getPaperUploadFile`,
derive: `${host}competition/cCompetitionStageFile/deriveAll`, derive: `${host}competition/cCompetitionStageFile/deriveAll`,
allExperimentalResultsAreDerived: `${host}competition/competition/performance/allExperimentalResultsAreDerived`, allExperimentalResultsAreDerived: `${host}competition/competition/performance/allExperimentalResultsAreDerived`,
derivedRanking: `${host}competition/competition/rank/derivedRanking`, derivedRanking: `${host}competition/competition/rank/derivedRanking`,
individualDerivedRanking: `${host}competition/competition/rank/individualDerivedRanking`, individualDerivedRanking: `${host}competition/competition/rank/individualDerivedRanking`,
gradeDownloadExcel: `${host}competition/competition/performance/downloadExcel`,
gradeImport: `https://www.occupationlab.com/template/赛事成绩导入模板.xlsx`, gradeImport: `https://www.occupationlab.com/template/赛事成绩导入模板.xlsx`,
rankImportTeam: `https://www.occupationlab.com/template/赛事排名导入模板(团队赛).xlsx`, rankImportTeam: `https://www.occupationlab.com/template/赛事排名导入模板(团队赛).xlsx`,
rankImportPerson: `https://www.occupationlab.com/template/赛事排名导入模板(个人赛).xlsx`, rankImportPerson: `https://www.occupationlab.com/template/赛事排名导入模板(个人赛).xlsx`,
@ -483,4 +551,10 @@ export default {
saveMarketing: `nakadai/nakadai/mall/marketing/promotion/save`, saveMarketing: `nakadai/nakadai/mall/marketing/promotion/save`,
updateMarketing: `nakadai/nakadai/mall/marketing/promotion/update`, updateMarketing: `nakadai/nakadai/mall/marketing/promotion/update`,
bannerEnableOrDisable: `nakadai/nakadai/mall/marketing/promotion/bannerEnableOrDisable`, bannerEnableOrDisable: `nakadai/nakadai/mall/marketing/promotion/bannerEnableOrDisable`,
resourceLibrary: `nakadai/resourceLibrary/resourceLibrary`,
resourceDel: `nakadai/resourceLibrary/batchDeletion`,
resourceFind: `nakadai/resourceLibrary/findById`,
resourceSave: `nakadai/resourceLibrary/saveOrUpdate`,
getFileType: `nakadai/resourceLibrary/getFileType`,
}; };

@ -5,10 +5,10 @@ export default {
//skin:'oxide-dark', //skin:'oxide-dark',
language: 'zh_CN', language: 'zh_CN',
language_url: './styles/tinymce/langs/zh_CN.js', language_url: './styles/tinymce/langs/zh_CN.js',
plugins: 'print powerpaste preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template advcode codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help emoticons autosave autoresize formatpainter', plugins: 'print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help emoticons autoresize',
toolbar: 'code undo redo restoredraft | cut copy powerpaste pastetext | forecolor backcolor headings fontsize lineHeight bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify | \ toolbar: 'code undo redo restoredraft | cut copy pastetext | forecolor backcolor headings fontsize lineHeight bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify | \
styleselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \ styleselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \
table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | indent2em formatpainter', table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | indent2em',
style_formats: [ style_formats: [
//新增 首行缩进与行高 配置 //新增 首行缩进与行高 配置
{ {
@ -199,93 +199,7 @@ export default {
{ title: 'Some class', value: 'class-name' } { title: 'Some class', value: 'class-name' }
], ],
//为内容模板插件提供预置模板 //为内容模板插件提供预置模板
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]',
// //
@ -352,8 +266,8 @@ export default {
setup: function (editor) { setup: function (editor) {
editor.on('init', function (ed) { editor.on('init', function (ed) {
// 设置默认字体 // 设置默认字体
ed.target.editorCommands.execCommand("fontName", false, "Microsoft Yahei") ed.target.editorCommands.execCommand("fontName", false, "PingFang SC")
ed.target.editorCommands.execCommand("fontSize", false, "19px") ed.target.editorCommands.execCommand("fontSize", false, "16px")
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() // 第一个字段聚焦

@ -30,11 +30,12 @@ axios.interceptors.request.use(config => {
return Promise.reject(err); 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 } = response.data const { status, code, msg } = response.data
if (status) { if (status) {
// 接口定义的非正常返回的时候,应当处于报错状态 // 接口定义的非正常返回的时候,应当处于报错状态
if (status === 10020) { if (status === 10020) {
@ -46,6 +47,22 @@ axios.interceptors.response.use(
} else { } else {
return Promise.resolve(response) return Promise.resolve(response)
} }
} else if (code === 401) {
// 账号互踢
if (!logouted) {
sessionStorage.removeItem('token')
Message.error(msg.includes('顶') ? '您的账号已在其他设备登录,您已被迫下线!' : '登录过期,请重新登录!')
setTimeout(() => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
})
logouted = 0
}, 1500)
logouted = 1
}
} else { } else {
return Promise.resolve(response) return Promise.resolve(response)
} }
@ -62,6 +79,7 @@ axios.interceptors.response.use(
// 未登录则跳转登录页面,并携带当前页面的路径 // 未登录则跳转登录页面,并携带当前页面的路径
// 在登录成功后返回当前页面,这一步需要在登录页操作。 // 在登录成功后返回当前页面,这一步需要在登录页操作。
case 401: case 401:
if (!logouted) {
Message.error('登录过期,请重新登录!'); Message.error('登录过期,请重新登录!');
setTimeout(() => { setTimeout(() => {
router.replace({ router.replace({
@ -71,6 +89,8 @@ axios.interceptors.response.use(
} }
}); });
}, 1000); }, 1000);
logouted = 1
}
break; break;
// 403 token过期 // 403 token过期
// 登录过期对用户进行提示 // 登录过期对用户进行提示

@ -1,38 +1,49 @@
<template> <template>
<div class="wrapper"> <div class="wrapper">
<v-head></v-head> <v-head></v-head>
<v-sidebar></v-sidebar> <Navbar></Navbar>
<div class="layout">
<Sidebar :class="{ show: showSidebar }" :path.sync="path" />
<div class="content-box"> <div class="content-box">
<div class="content"> <transition name="move" mode="out-in">
<transition name="move"
mode="out-in">
<!-- <keep-alive> -->
<router-view></router-view> <router-view></router-view>
<!-- </keep-alive> -->
</transition> </transition>
<el-backtop target=".content"></el-backtop> <el-backtop target=".content-box"></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 Navbar from '../components/Navbar.vue'
import Setting from "@/setting"; import Sidebar from '../components/Sidebar.vue'
import util from "@/libs/util"; import Setting from "@/setting"
import util from "@/libs/util"
export default { export default {
data () { data () {
return { return {
tagsList: [], showSidebar: false,
path: '',
}; };
}, },
components: { components: {
vHead, vHead,
vSidebar, Navbar,
Sidebar,
},
watch: {
'$route.path': {
handler (val) {
this.path = val
//
this.showSidebar = ['/configure', '/curriculum', '/information', '/shop', '/market', '/parnerOperation', '/parner', '/match', '/data', '/review', '/theoreticalCourse', '/resourse'].includes(val)
},
immediate: true
}
}, },
created () { created () {
this.autoLogout()
}, },
methods: { methods: {
// ,退 // ,退
@ -58,3 +69,27 @@ export default {
} }
}; };
</script> </script>
<style lang="scss" scoped>
.layout {
display: flex;
background: #f5f7fa;
.content-box {
width: calc(100vw - 208px);
padding: 20px;
box-sizing: border-box;
// -webkit-transition: left 0.3s ease-in-out;
// transition: left 0.3s ease-in-out;
}
.sidebar:not(.show) {
margin-left: -200px;
&+.content-box {
width: 100%;
}
}
}
</style>

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

@ -2,28 +2,19 @@
<div> <div>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="24"> <el-col :span="24">
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="flex-between"> <div class="flex-between">
<div class="per_title" <div class="per_title" v-preventReClick @click="back">
v-preventReClick
@click="goback()">
<i class="el-icon-arrow-left"></i> <i class="el-icon-arrow-left"></i>
<span class="per_back">返回</span> <span class="per_back">返回</span>
<span class="per_school" <span class="per_school" v-text="form.cid ? '编辑课程' : '新建课程'"></span>
v-text="form.cid ? '编辑课程' : '新建课程'"></span>
</div> </div>
<el-button type="primary" <el-button type="primary" round class="mag" v-preventReClick @click="saveAdd">确定
round
class="mag"
v-preventReClick
@click="saveAdd">确定
</el-button> </el-button>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="mgb20 ">
class="mgb20 ">
<div class="flex-center mgb20"> <div class="flex-center mgb20">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>课程信息</span> <span>课程信息</span>
@ -31,111 +22,65 @@
<div class="border-b-dashed"></div> <div class="border-b-dashed"></div>
<div> <div>
<el-form :model="form" <el-form :model="form" :rules="rules" ref="form" label-width="100px">
:rules="rules" <el-col :span="6" :offset="5">
ref="form" <el-form-item label="课程名称" prop="curriculumName">
label-width="100px"> <el-input placeholder="请输入课程名称" v-model.trim="form.curriculumName"></el-input>
<el-col :span="6"
:offset="5">
<el-form-item label="课程名称"
prop="curriculumName">
<el-input placeholder="请输入课程名称"
v-model.trim="form.curriculumName"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="学科类别" <el-form-item label="学科类别" prop="categoryId">
prop="categoryId"> <el-select v-model="form.categoryId" clearable placeholder="请选择学科类别" @change="getProfessionalClass()"
<el-select v-model="form.categoryId"
clearable
placeholder="请选择学科类别"
@change="getProfessionalClass()"
@clear="clearsubjectType()"> @clear="clearsubjectType()">
<el-option v-for="(item,index) in subjectList" <el-option v-for="(item, index) in subjectList" :key="index" :label="item.disciplineName"
:key="index"
:label="item.disciplineName"
:value="item.disciplineId"></el-option> :value="item.disciplineId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="专业" <el-form-item label="专业" prop="professionalId">
prop="professionalId"> <el-select v-model="form.professionalId" clearable placeholder="请选择专业"
<el-select v-model="form.professionalId"
clearable
placeholder="请选择专业"
:disabled="form.professionalCategoryId ? false : true"> :disabled="form.professionalCategoryId ? false : true">
<el-option v-for="(item,index) in ProfessionalList" <el-option v-for="(item, index) in ProfessionalList" :key="index" :label="item.professionalName"
:key="index"
:label="item.professionalName"
:value="item.professionalId"></el-option> :value="item.professionalId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="供应厂商" <el-form-item label="供应厂商" prop="supplier">
prop="supplier"> <el-select v-model="form.supplier" clearable placeholder="请选择供应厂商" multiple>
<el-select v-model="form.supplier" <el-option v-for="(item, i) in suppliers" :key="i" :label="item.supplierName"
clearable
placeholder="请选择供应厂商"
multiple>
<el-option v-for="(item, i) in suppliers"
:key="i"
:label="item.supplierName"
:value="item.supplierId"></el-option> :value="item.supplierId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6" <el-col :span="6" :offset="2">
:offset="2"> <el-form-item label="课程类别" prop="curriculumType">
<el-form-item label="课程类别"> <el-select v-model="form.curriculumType" clearable placeholder="请选择课程类型">
<el-select v-model="form.curriculumType" <el-option label="理论课程" :value="0"></el-option>
clearable <el-option label="实训课程" :value="1"></el-option>
placeholder="请选择课程类型">
<el-option label="理论课程"
:value="0"></el-option>
<el-option label="实训课程"
:value="1"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="专业类" <el-form-item label="专业类" prop="professionalCategoryId">
prop="professionalCategoryId"> <el-select v-model="form.professionalCategoryId" clearable placeholder="请选择专业类"
<el-select v-model="form.professionalCategoryId" :disabled="form.categoryId ? false : true" @change="getProfessional()"
clearable
placeholder="请选择专业类"
:disabled="form.categoryId ? false : true"
@change="getProfessional()"
@clear="clearProfessionalClass()"> @clear="clearProfessionalClass()">
<el-option v-for="(item,index) in ProfessionalClassList" <el-option v-for="(item, index) in ProfessionalClassList" :key="index"
:key="index" :label="item.professionalClassName" :value="item.professionalClassId"></el-option>
:label="item.professionalClassName"
:value="item.professionalClassId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="预计课时" <el-form-item label="预计课时" prop="expectedCourse">
prop="expectedCourse"> <el-select v-model="form.expectedCourse" clearable placeholder="请选择预计课时">
<el-select v-model="form.expectedCourse" <el-option label="32课时" value="32课时"></el-option>
clearable <el-option label="64课时" value="64课时"></el-option>
placeholder="请选择预计课时">
<el-option label="32课时"
value="32课时"></el-option>
<el-option label="64课时"
value="64课时"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="14" <el-col :span="14" :offset="5">
:offset="5"> <el-form-item label="课程简介" prop="briefIntroduction">
<el-form-item label="课程简介" <el-input type="textarea" :autosize="{ minRows: 4 }" placeholder="请输入课程简介"
prop="briefIntroduction">
<el-input type="textarea"
:autosize="{ minRows: 4 }"
placeholder="请输入课程简介"
v-model.trim="form.briefIntroduction"></el-input> v-model.trim="form.briefIntroduction"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="教学目标" <el-form-item label="教学目标" prop="teachingObjectives">
prop="teachingObjectives"> <el-input type="textarea" :autosize="{ minRows: 4 }" placeholder="请输入教学目标"
<el-input type="textarea"
:autosize="{ minRows: 4 }"
placeholder="请输入教学目标"
v-model.trim="form.teachingObjectives"></el-input> v-model.trim="form.teachingObjectives"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -144,8 +89,7 @@
</el-card> </el-card>
<!-- 练习项目配置 --> <!-- 练习项目配置 -->
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="mgb20 flex-between"> <div class="mgb20 flex-between">
<div class="flex-center "> <div class="flex-center ">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
@ -153,61 +97,36 @@
</div> </div>
<div> <div>
<el-button @click="handleBatchDelete(0)">批量移除</el-button> <el-button @click="handleBatchDelete(0)">批量移除</el-button>
<el-button @click="handleConfig(0)" <el-button @click="handleConfig(0)" icon="el-icon-plus" circle></el-button>
icon="el-icon-plus"
circle></el-button>
</div> </div>
</div> </div>
<div class="border-b-dashed"></div> <div class="border-b-dashed"></div>
<div> <div>
<el-table :data="practiceData" <el-table :data="practiceData" class="table" header-align="center" max-height="400"
class="table"
stripe
header-align="center"
max-height="400"
@selection-change="handleSelectionPractice"> @selection-change="handleSelectionPractice">
<el-table-column type="selection" <el-table-column type="selection" width="55" align="center"></el-table-column>
width="55" <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
align="center"></el-table-column> <el-table-column prop="projectName" label="项目名称" align="center">
<el-table-column type="index"
width="100"
label="序号"
align="center"></el-table-column>
<el-table-column prop="projectName"
label="项目名称"
align="center"></el-table-column>
<el-table-column prop="remark"
label="备注名称"
align="center"></el-table-column>
<el-table-column prop="applicationName"
label="系统名称"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }} {{ scope.row.projectName || scope.row.paperName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="排序" <el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
align="center" <el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
width="100"> <el-table-column label="排序" align="center" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-model.trim="scope.row.sort" <el-input v-model.trim="scope.row.sort"
@input="practiceSortChange(scope.row, scope.$index)"></el-input> @input="practiceSortChange(scope.row, scope.$index)"></el-input>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="展示控制" <el-table-column label="展示控制" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch v-model="scope.row.isShow" <el-switch v-model="scope.row.isShow" :active-value="0" :inactive-value="1"
:active-value="0"
:inactive-value="1"
:disabled="scope.row.disabled"> :disabled="scope.row.disabled">
</el-switch> </el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button :disabled="scope.row.disabled" <el-button :disabled="scope.row.disabled"
@click.native.prevent="handleDelete(scope.$index, practiceData)">移除 @click.native.prevent="handleDelete(scope.$index, practiceData)">移除
@ -219,8 +138,7 @@
</el-card> </el-card>
<!-- 考核项目配置 --> <!-- 考核项目配置 -->
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="mgb20 flex-between"> <div class="mgb20 flex-between">
<div class="flex-center "> <div class="flex-center ">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
@ -228,62 +146,37 @@
</div> </div>
<div> <div>
<el-button @click="handleBatchDelete(1)">批量移除</el-button> <el-button @click="handleBatchDelete(1)">批量移除</el-button>
<el-button @click="handleConfig(1)" <el-button @click="handleConfig(1)" icon="el-icon-plus" circle></el-button>
icon="el-icon-plus"
circle></el-button>
</div> </div>
</div> </div>
<div class="border-b-dashed"></div> <div class="border-b-dashed"></div>
<!-- 实训配置 --> <!-- 实训配置 -->
<div> <div>
<el-table :data="assessmentData" <el-table :data="assessmentData" class="table" header-align="center" max-height="400"
class="table"
stripe
header-align="center"
max-height="400"
@selection-change="handleSelectionAssessment"> @selection-change="handleSelectionAssessment">
<el-table-column type="selection" <el-table-column type="selection" width="55" align="center"></el-table-column>
width="55" <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
align="center"></el-table-column> <el-table-column prop="projectName" label="项目名称" align="center">
<el-table-column type="index"
width="100"
label="序号"
align="center"></el-table-column>
<el-table-column prop="projectName"
label="项目名称"
align="center"></el-table-column>
<el-table-column prop="remark"
label="备注名称"
align="center"></el-table-column>
<el-table-column prop="applicationName"
label="系统名称"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }} {{ scope.row.projectName || scope.row.paperName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="排序" <el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
align="center" <el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
width="100"> <el-table-column label="排序" align="center" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-model.trim="scope.row.sort" <el-input v-model.trim="scope.row.sort"
@input="assessmentSortChange(scope.row, scope.$index)"></el-input> @input="assessmentSortChange(scope.row, scope.$index)"></el-input>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="展示控制" <el-table-column label="展示控制" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch v-model="scope.row.isShow" <el-switch v-model="scope.row.isShow" :active-value="0" :inactive-value="1"
:active-value="0"
:inactive-value="1"
:disabled="scope.row.disabled"> :disabled="scope.row.disabled">
</el-switch> </el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button :disabled="scope.row.disabled" <el-button :disabled="scope.row.disabled"
@click.native.prevent="handleDelete(scope.$index, assessmentData)">移除</el-button> @click.native.prevent="handleDelete(scope.$index, assessmentData)">移除</el-button>
@ -294,8 +187,7 @@
</el-card> </el-card>
<!-- 大赛项目配置 --> <!-- 大赛项目配置 -->
<el-card shadow="hover" <el-card shadow="hover" class="mgb20">
class="mgb20">
<div class="mgb20 flex-between"> <div class="mgb20 flex-between">
<div class="flex-center "> <div class="flex-center ">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
@ -303,59 +195,36 @@
</div> </div>
<div> <div>
<el-button @click="handleBatchDelete(2)">批量移除</el-button> <el-button @click="handleBatchDelete(2)">批量移除</el-button>
<el-button @click="handleConfig(2)" <el-button @click="handleConfig(2)" icon="el-icon-plus" circle></el-button>
icon="el-icon-plus"
circle></el-button>
</div> </div>
</div> </div>
<div class="border-b-dashed"></div> <div class="border-b-dashed"></div>
<!-- 实训配置 --> <!-- 实训配置 -->
<div> <div>
<el-table :data="matches" <el-table :data="matches" class="table" header-align="center" max-height="400"
class="table"
stripe
header-align="center"
max-height="400"
@selection-change="handleSelectionMatch"> @selection-change="handleSelectionMatch">
<el-table-column type="selection" <el-table-column type="selection" width="55" align="center"></el-table-column>
width="55" <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
align="center"></el-table-column> <el-table-column prop="projectName" label="项目名称" align="center">
<el-table-column type="index"
width="100"
label="序号"
align="center"></el-table-column>
<el-table-column prop="projectName"
label="项目名称"
align="center"></el-table-column>
<el-table-column prop="applicationName"
label="系统名称"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }} {{ scope.row.projectName || scope.row.paperName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="排序" <el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
align="center" <el-table-column label="排序" align="center" width="100">
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-input v-model.trim="scope.row.sort" <el-input v-model.trim="scope.row.sort"
@input="assessmentSortChange(scope.row, scope.$index)"></el-input> @input="assessmentSortChange(scope.row, scope.$index)"></el-input>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="展示控制" <el-table-column label="展示控制" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch v-model="scope.row.isShow" <el-switch v-model="scope.row.isShow" :active-value="0" :inactive-value="1"
:active-value="0"
:inactive-value="1"
:disabled="scope.row.disabled"> :disabled="scope.row.disabled">
</el-switch> </el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" <el-table-column label="操作" align="center" width="100">
align="center"
width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button :disabled="scope.row.disabled" <el-button :disabled="scope.row.disabled"
@click.native.prevent="handleDelete(scope.$index, matches)">移除</el-button> @click.native.prevent="handleDelete(scope.$index, matches)">移除</el-button>
@ -369,29 +238,20 @@
</el-row> </el-row>
<!-- 配置弹窗 --> <!-- 配置弹窗 -->
<el-dialog :visible.sync="configVisible" <el-dialog :visible.sync="configVisible" width="1200px" center custom-class="config-dia">
width="1200px"
center
custom-class="config-dia">
<div class="config-wrap"> <div class="config-wrap">
<div class="item system"> <div class="item system">
<div class="title-wrap flex-center"> <div class="title-wrap flex-center">
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>系统列表</span> <span>系统列表</span>
</div> </div>
<el-input placeholder="请输入系统名称" <el-input placeholder="请输入系统名称" prefix-icon="el-icon-search" v-model.trim="systemKeyword"
prefix-icon="el-icon-search"
v-model.trim="systemKeyword"
clearable></el-input> clearable></el-input>
<ul class="systems"> <ul class="systems">
<li v-for="(item, i) in systems" <li v-for="(item, i) in systems" :key="i" :title="item.systemName">
:key="i" <el-checkbox v-model="item.check" @change="val => systemChange(val, item)"></el-checkbox>
:title="item.systemName"> <div :class="['name', { active: curSystem == item.systemId }]" @click="getProject(item)">
<el-checkbox v-model="item.check"
@change="val => systemChange(val, item)"></el-checkbox>
<div :class="['name', {active: curSystem == item.systemId}]"
@click="getProject(item)">
<span>{{ item.systemName }}</span> <span>{{ item.systemName }}</span>
<i class="el-icon-arrow-right"></i> <i class="el-icon-arrow-right"></i>
</div> </div>
@ -404,21 +264,15 @@
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>项目列表</span> <span>项目列表</span>
</div> </div>
<el-input placeholder="请输入项目名称" <el-input placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model.trim="projectKeyword"
prefix-icon="el-icon-search"
v-model.trim="projectKeyword"
clearable></el-input> clearable></el-input>
<ul class="systems"> <ul class="systems">
<el-checkbox v-if="projects.length" <el-checkbox v-if="projects.length" v-model="checkAll" label="全选"
v-model="checkAll"
label="全选"
@change="val => checkAllChange(val, projects[0].systemId)"></el-checkbox> @change="val => checkAllChange(val, projects[0].systemId)"></el-checkbox>
<li v-for="(item, i) in projects" <li v-for="(item, i) in projects" :key="i" :title="item.projectName">
:key="i"
:title="item.projectName">
<el-checkbox v-model="item.check" <el-checkbox v-model="item.check"
:label="item.remark ? item.remark + '(' + item.projectName + ')' : item.projectName" :label="item.remark ? item.remark + '(' + item.projectName + ')' : (item.projectName || item.paperName)"
@change="val => projectChange(val, item)"></el-checkbox> @change="val => projectChange(val, item)"></el-checkbox>
</li> </li>
</ul> </ul>
@ -429,44 +283,23 @@
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>已选择项目{{ checkeds.length }}</span> <span>已选择项目{{ checkeds.length }}</span>
</div> </div>
<el-input style="width: 200px;margin-bottom: 20px;" <el-input style="width: 200px;margin-bottom: 20px;" placeholder="请输入项目名称" prefix-icon="el-icon-search"
placeholder="请输入项目名称" v-model.trim="checkedKeyword" clearable></el-input>
prefix-icon="el-icon-search" <el-table :data="checkeds" class="table" header-align="center" max-height="470">
v-model.trim="checkedKeyword" <el-table-column type="index" width="55" label="序号" align="center"></el-table-column>
clearable></el-input> <el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
<el-table :data="checkeds" <el-table-column prop="projectName" width="80" label="系统类型" align="center">
class="table"
stripe
header-align="center"
max-height="470">
<el-table-column type="index"
width="55"
label="序号"
align="center"></el-table-column>
<el-table-column prop="applicationName"
label="系统名称"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }} {{ scope.row.type === 1 ? '流程类' : scope.row.type === 3 ? '理论' : '编程类' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="projectName" <el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
width="80" <el-table-column prop="projectName" label="项目名称" align="center">
label="系统类型"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.type ? '流程类' : '编程类' }} {{ scope.row.projectName || scope.row.paperName }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="remark" <el-table-column label="操作" align="center" width="55">
label="备注名称"
align="center"></el-table-column>
<el-table-column prop="projectName"
label="项目名称"
align="center"></el-table-column>
<el-table-column label="操作"
align="center"
width="55">
<template slot-scope="scope"> <template slot-scope="scope">
<i :class="['el-icon-delete rm', { disabled: scope.row.disabled }]" <i :class="['el-icon-delete rm', { disabled: scope.row.disabled }]"
@click="delProject(scope.$index, scope.row)"></i> @click="delProject(scope.$index, scope.row)"></i>
@ -476,11 +309,9 @@
</div> </div>
</div> </div>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer">
<el-button @click="configVisible = false"> </el-button> <el-button @click="configVisible = false"> </el-button>
<el-button type="primary" <el-button type="primary" @click="handleConfirm"> </el-button>
@click="handleConfirm"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
@ -497,6 +328,7 @@ export default {
form: { form: {
cid: this.$route.query.cid, cid: this.$route.query.cid,
curriculumName: "", curriculumName: "",
curriculumType: '',
courseType: "", courseType: "",
categoryId: 1, categoryId: 1,
professionalCategoryId: 1, professionalCategoryId: 1,
@ -524,6 +356,9 @@ export default {
expectedCourse: [ expectedCourse: [
{ required: true, message: "请选择预计课时", trigger: "change" } { required: true, message: "请选择预计课时", trigger: "change" }
], ],
curriculumType: [
{ required: true, message: "请选择课程类别", trigger: "change" }
],
professionalCategoryId: [ professionalCategoryId: [
{ required: true, message: "请选择专业类", trigger: "change" } { required: true, message: "请选择专业类", trigger: "change" }
], ],
@ -580,7 +415,6 @@ export default {
systemChecked: [], systemChecked: [],
curSystem: '', curSystem: '',
projects: [], projects: [],
projectAll: [],
projectKeyword: '', projectKeyword: '',
checkedKeyword: '', checkedKeyword: '',
checkeds: [], checkeds: [],
@ -607,7 +441,7 @@ export default {
projectKeyword: function (val) { projectKeyword: function (val) {
clearTimeout(this.searchTimer); clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => { this.searchTimer = setTimeout(() => {
this.filterProject(); this.getProject();
}, 500); }, 500);
}, },
checkedKeyword: function (val) { checkedKeyword: function (val) {
@ -742,6 +576,7 @@ export default {
this.pageNo = 1; this.pageNo = 1;
this.getConfig(); this.getConfig();
this.checkeds = JSON.parse(JSON.stringify(type == 1 ? this.assessmentData : type == 2 ? this.matches : this.practiceData)) this.checkeds = JSON.parse(JSON.stringify(type == 1 ? this.assessmentData : type == 2 ? this.matches : this.practiceData))
this.checkedAll = JSON.parse(JSON.stringify(this.checkeds))
}, },
// //
getConfig () { getConfig () {
@ -774,26 +609,23 @@ export default {
}).catch(err => { }) }).catch(err => { })
}, },
// //
getProject (item) { async getProject (item, fromSystemChange) {
const checked = this.checkeds const checked = this.checkeds
this.curSystem = item.systemId if (item) this.curSystem = item.systemId
this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${item.systemId}`).then(res => { let res
this.projectAll = JSON.parse(JSON.stringify(res)) // if (!fromSystemChange) {
res = await this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${this.curSystem}&keyword=${this.projectKeyword}`)
}
const result = [] const result = []
res.map(e => { const projects = fromSystemChange ? this.projects : res
projects.map(e => {
// //
const include = checked.some(n => n.projectId == e.projectId && n.systemId == e.systemId) const include = checked.some(n => (e.projectId && n.projectId == e.projectId && n.systemId == e.systemId) || (e.paperId && n.paperId == e.paperId))
e.check = include e.check = include
result.push(e) result.push(e)
}) })
this.checkAll = !result.filter(e => !e.check).length this.checkAll = !result.filter(e => !e.check).length
this.projects = result this.projects = result
}).catch(err => { })
},
//
filterProject () {
const val = this.projectKeyword
this.projects = this.projectAll.filter(e => e.projectName.includes(val))
}, },
// //
systemChange (val, item) { systemChange (val, item) {
@ -805,7 +637,7 @@ export default {
}) })
} }
this.projectKeyword = '' this.projectKeyword = ''
this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${item.systemId}`).then(res => { this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${item.systemId}&keyword=${this.projectKeyword}`).then(res => {
if (val) { if (val) {
// //
if (!this.mulSystem) { if (!this.mulSystem) {
@ -813,18 +645,18 @@ export default {
item.check = true item.check = true
} }
res.map(e => { res.map(e => {
if (!checkeds.find(n => n.projectId == e.projectId && n.systemId == e.systemId)) { if (!checkeds.find(n => (e.projectId && n.projectId == e.projectId && n.systemId == e.systemId) || (e.paperId && e.paperId == n.paperId))) {
checkeds.push(e) checkeds.push(e)
} }
}) })
} else { } else {
res.map(e => { res.map(e => {
const i = checkeds.findIndex(n => n.projectId == e.projectId && n.systemId == e.systemId) const i = checkeds.findIndex(n => (e.projectId && n.projectId == e.projectId && n.systemId == e.systemId) || (e.paperId && e.paperId == n.paperId))
i === -1 || checkeds.splice(i, 1) i === -1 || checkeds.splice(i, 1)
}) })
} }
this.checkedAll = JSON.parse(JSON.stringify(checkeds)) // this.checkedAll = JSON.parse(JSON.stringify(checkeds)) //
this.getProject(item) this.getProject(item, 1)
}).catch(err => { }) }).catch(err => { })
}, },
// //
@ -836,8 +668,8 @@ export default {
}, },
// //
projectChange (val, item) { projectChange (val, item) {
const { systemId } = item const { systemId, paperId } = item
const i = this.checkeds.findIndex(e => e.projectId == item.projectId && e.systemId == systemId) const i = this.checkeds.findIndex(e => (item.projectId && e.projectId == item.projectId && e.systemId == systemId) || (paperId && paperId == e.paperId))
// push // push
if (val) { if (val) {
this.checkeds.push(item) this.checkeds.push(item)
@ -850,12 +682,11 @@ export default {
}) })
this.checkAll = !this.projects.find(e => !e.check) // this.checkAll = !this.projects.find(e => !e.check) //
this.checkedAll = JSON.parse(JSON.stringify(this.checkeds)) // this.checkedAll = JSON.parse(JSON.stringify(this.checkeds)) //
console.log("🚀 ~ file: AddCurriculum.vue ~ line 728 ~ projectChange ~ checkedAll", this.checkeds, item)
}, },
// //
filterChecked () { filterChecked () {
const val = this.checkedKeyword const val = this.checkedKeyword
this.checkeds = this.checkedAll.filter(e => e.projectName.includes(val)) this.checkeds = this.checkedAll.filter(e => (e.projectName && e.projectName.includes(val)) || (e.paperName && e.paperName.includes(val)))
}, },
// //
delProject (i, e) { delProject (i, e) {
@ -866,9 +697,9 @@ export default {
this.checkeds.splice(i, 1) this.checkeds.splice(i, 1)
// checkdisabled // checkdisabled
if (e.systemId == this.curSystem) { if (e.systemId == this.curSystem) {
const { projectId } = e const { projectId, paperId } = e
this.projects.map(n => { this.projects.map(n => {
if (n.projectId == projectId) { if ((projectId && n.projectId == projectId) || (paperId && n.paperId == paperId)) {
n.check = false n.check = false
} }
}) })
@ -974,7 +805,7 @@ export default {
this.$message.info("已取消移除"); this.$message.info("已取消移除");
}); });
}, },
saveAdd (fromBack) { saveAdd () {
this.$refs.form.validate((valid) => { this.$refs.form.validate((valid) => {
if (valid) { if (valid) {
if (this.submiting) return false if (this.submiting) return false
@ -987,7 +818,8 @@ export default {
form.systemIdByPractice = this.practiceData.map(i => { form.systemIdByPractice = this.practiceData.map(i => {
let obj = { let obj = {
isShow: i.isShow, isShow: i.isShow,
projectId: i.projectId, projectId: i.projectId || '',
paperId: i.paperId || '',
sort: Number(i.sort), sort: Number(i.sort),
systemId: i.systemId systemId: i.systemId
}; };
@ -1003,6 +835,7 @@ export default {
let obj = { let obj = {
isShow: i.isShow, isShow: i.isShow,
projectId: i.projectId, projectId: i.projectId,
paperId: i.paperId || '',
sort: Number(i.sort), sort: Number(i.sort),
systemId: i.systemId systemId: i.systemId
}; };
@ -1015,6 +848,7 @@ export default {
let obj = { let obj = {
isShow: i.isShow, isShow: i.isShow,
projectId: i.projectId, projectId: i.projectId,
paperId: i.paperId || '',
sort: Number(i.sort), sort: Number(i.sort),
systemId: i.systemId systemId: i.systemId
}; };
@ -1029,6 +863,7 @@ export default {
spinner: 'el-icon-loading', spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)' background: 'rgba(0, 0, 0, 0.7)'
}) })
debugger
if (form.cid) { if (form.cid) {
this.$post(this.api.modifyCourse, form).then((res) => { this.$post(this.api.modifyCourse, form).then((res) => {
this.$message.success("编辑成功"); this.$message.success("编辑成功");
@ -1039,15 +874,17 @@ export default {
}); });
} else { } else {
this.$post(this.api.createCurriculum, form).then((res) => { this.$post(this.api.createCurriculum, form).then((res) => {
!fromBack ? this.$confirm("课程创建成功,是否马上进行课程内容设置?", "提示", { this.loadIns.close()
this.$confirm("课程创建成功,是否马上进行课程内容设置?", "提示", {
type: "success", type: "success",
confirmButtonText: "马上设置", confirmButtonText: "马上设置",
cancelButtonText: "稍后操作" cancelButtonText: "稍后操作",
closeOnClickModal: false
}).then(() => { }).then(() => {
this.$router.push(`/contentSettings?cid=${res.cid}`); this.$router.push(`/contentSettings?cid=${res.cid}&name=${form.curriculumName}`);
}).catch(() => { }).catch(() => {
this.backPage() this.$router.push('/curriculum')
}) : this.backPage() })
}).catch((res) => { }).catch((res) => {
this.submiting = false this.submiting = false
this.loadIns.close() this.loadIns.close()
@ -1058,15 +895,16 @@ export default {
} }
}); });
}, },
goback () { back () {
const id = this.form.cid const id = this.form.cid
const updateTime = this.updateTime const updateTime = this.updateTime
// //
if ((id && updateTime > 2) || (!id && updateTime)) { if ((id && updateTime > 2) || (!id && updateTime)) {
this.$confirm(`编辑的内容未保存,是否保存?`, '提示', { this.$confirm(`编辑的内容未保存,是否保存?`, '提示', {
type: 'warning' type: 'warning',
closeOnClickModal: false
}).then(() => { }).then(() => {
this.saveAdd(1) this.saveAdd()
}).catch(() => { }).catch(() => {
this.backPage() this.backPage()
}) })
@ -1076,8 +914,8 @@ export default {
}, },
// //
backPage () { backPage () {
this.$router.back() this.loadIns && this.loadIns.close()
this.loadIns.close() this.$router.push(this.$store.state.referrer || '/curriculum')
} }
} }
}; };
@ -1085,6 +923,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
$avatar-width: 104px; $avatar-width: 104px;
/deep/ .avatar-uploader { /deep/ .avatar-uploader {
.el-upload { .el-upload {
position: relative; position: relative;
@ -1143,28 +982,34 @@ $avatar-width: 104px;
} }
} }
} }
.settlement { .settlement {
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 10px; margin-bottom: 10px;
.label { .label {
margin-right: 10px; margin-right: 10px;
white-space: nowrap; white-space: nowrap;
color: #606266; color: #606266;
font-size: 14px; font-size: 14px;
} }
.el-input { .el-input {
width: 150px; width: 150px;
margin-right: 30px; margin-right: 30px;
} }
} }
/deep/.config-dia { /deep/.config-dia {
.config-wrap { .config-wrap {
display: flex; display: flex;
} }
.title-wrap { .title-wrap {
margin-bottom: 15px; margin-bottom: 15px;
} }
.item { .item {
width: 250px; width: 250px;
max-height: 600px; max-height: 600px;
@ -1172,18 +1017,22 @@ $avatar-width: 104px;
margin-right: 20px; margin-right: 20px;
overflow: hidden; overflow: hidden;
} }
.system { .system {
background-color: #f9f9f9; background-color: #f9f9f9;
} }
.systems { .systems {
margin-top: 10px; margin-top: 10px;
max-height: 550px; max-height: 520px;
overflow: auto; overflow: auto;
li { li {
display: flex; display: flex;
align-items: center; align-items: center;
margin: 10px 0; margin: 10px 0;
} }
.name { .name {
display: inline-flex; display: inline-flex;
flex: 1; flex: 1;
@ -1191,10 +1040,12 @@ $avatar-width: 104px;
align-items: center; align-items: center;
margin-left: 5px; margin-left: 5px;
cursor: pointer; cursor: pointer;
&.active, &.active,
&:hover { &:hover {
color: #9076ff; color: #062c87;
} }
span { span {
max-width: 200px; max-width: 200px;
text-overflow: ellipsis; text-overflow: ellipsis;
@ -1203,20 +1054,25 @@ $avatar-width: 104px;
} }
} }
} }
.checked { .checked {
flex: 1; flex: 1;
width: auto; width: auto;
.el-table .cell { .el-table .cell {
font-size: 12px; font-size: 12px;
} }
} }
.rm { .rm {
font-size: 14px; font-size: 14px;
cursor: pointer; cursor: pointer;
&.disabled { &.disabled {
color: #ccc; color: #ccc;
cursor: not-allowed; cursor: not-allowed;
} }
&:hover { &:hover {
color: #17161f; color: #17161f;
} }

@ -1,204 +0,0 @@
<template>
<div>
<el-row :gutter="20">
<el-col :span="24">
<el-card shadow="hover" class="mgb20">
<div class="flex-between">
<div class="per_title" @click="goback()">
<i class="el-icon-arrow-left"></i>
<span class="per_back">返回</span>
<span class="per_school">添加环节</span>
</div>
<div>
<el-button type="primary" round class="mag" @click="saveAdd('form')">确定
</el-button>
</div>
</div>
</el-card>
<el-card shadow="hover" class="mgb20">
<div class="flex-between mgb20 user_header">
<div class="flex-center">
<p class="addhr_tag"></p>
<span>环节1.1</span>
</div>
<el-button type="primary" round class="mag" @click="addcourse()">添加环节</el-button>
</div>
<div>
<el-form :model="form" ref="form" label-width="120px" class="courseware">
<ul class="mgb20">
<li v-for="(item,index) in form.courseList" :key="index" class="flex-between">
<div style="width: 50%;">
<el-form-item label="环节名称" :prop="'courseList.' + index + '.linkName'"
:rules="{required: true, message: '请输入项目课件', trigger: 'blur'}">
<el-input placeholder="请输入项目课件" v-model="item.linkName"></el-input>
</el-form-item>
<el-form-item label="资源添加" :prop="'courseList.' + index + '.fileLink'"
:rules="{required: true, message: '请添加文件', trigger: 'blur'}">
<el-upload
class="link_upload"
:headers="{token}"
:action="api.uploadFiles"
:on-remove="(file, fileList)=>{return handleRemove(file, fileList, index)}"
:on-error="uploadError"
:on-success="(response, file, fileList)=>{return uploadSuccess(response, file, fileList, index)}"
:before-remove="beforeRemove"
:limit="1"
:on-exceed="handleExceed"
:file-list="item.uploadList">
<el-button size="medium" type="primary" icon="el-icon-upload"
class="uploadTitle">点击上传
</el-button>
</el-upload>
</el-form-item>
</div>
<div>
<el-button size="medium" type="primary" @click="delCourse(index)">删除课件
</el-button>
</div>
</li>
</ul>
</el-form>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
data() {
return {
token: this.$store.state.loginToken,
form: {
courseList: [{
projectId: this.$store.state.systemId,
courseId: this.$store.state.courseId,
linkName: "",
fileLink: "",
uploadList: []
}]
}
};
},
mounted() {
this.getData();
},
methods: {
getData() {
let data = {
projectId: this.form.courseList[0].projectId,
courseId: this.form.courseList[0].courseId
};
this.$get(this.api.queryLinkDetails, data).then((res) => {
res.message.map(e => {
var arr = [];
arr.push({ name: e.linkName, url: e.fileLink });
this.$set(e, "uploadList", arr);
});
this.form.courseList = res.message;
}).catch((res) => {
});
},
saveAdd(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
var arr = this.form.courseList.map(v => {
var obj = {
...v
};
delete obj.uploadList;
return obj;
});
let data = {
courseLink: arr
};
this.$post(this.api.addCourseLink, data).then((res) => {
this.$message.success("添加成功!");
this.goback();
}).catch((res) => {
});
}
});
},
addcourse() {
this.form.courseList = this.form.courseList.concat({
projectId: this.$store.state.systemId,
courseId: this.$store.state.courseId,
linkName: "",
fileLink: "",
uploadList: []
});
},
//
handleExceed(files, fileList) {
this.$message.warning(
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
);
},
uploadSuccess(response, file, fileList, idx) {
this.form.courseList[idx].uploadList.push({ name: file.name, url: response.message.fileUrl });
this.form.courseList[idx].fileLink = response.message.fileUrl;
},
uploadError(err, file, fileList) {
this.$message({
message: "上传出错,请重试!",
type: "error",
center: true
});
},
beforeRemove(file, fileList) {
return this.$confirm(`确定移除 ${file.name}`);
},
handleRemove(file, fileList, idx) {
let uploadList = this.form.courseList[idx].uploadList;
uploadList.forEach((item, index) => {
if (file.name == item.name) {
uploadList.splice(index, 1);
}
});
},
delCourse(index) {
this.$confirm("确定要删除该课件吗?", "提示", {
type: "warning"
})
.then(() => {
this.form.courseList.splice(index, 1);
this.$message.success("删除成功");
})
.catch(() => {
});
},
goback() {
this.$router.go(-1);
}
}
};
</script>
<style scoped>
/* .courseware ul .el-input{
width: 30%;
} */
.courseware ul li {
margin-top: 20px;
padding: 0 0 10px 0;
border-bottom: 1px dashed #eee;
}
.courseware ul li:first-child {
margin-top: 0;
}
.courseware ul li:last-child {
border-bottom: none;
}
.uploadTitle {
height: 40px !important;
font-size: 16px;
}
</style>

@ -1,327 +0,0 @@
<template>
<div>
<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">
<el-col :span="4">
<el-form-item label="学科类别">
<el-select v-model="form.categoryId" clearable
@change="getProfessionalClass()" @clear="clearClass()">
<el-option v-for="(item,index) in subjectList" :key="index"
:label="item.disciplineName"
:value="item.disciplineId"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="专业类">
<el-select v-model="form.professionalCategoryId" clearable
:disabled="form.categoryId ? false : true"
@change="getProfessional()" @clear="clearProfess()">
<el-option v-for="(item,index) in ProfessionalClassList" :key="index"
:label="item.professionalClassName"
:value="item.professionalClassId"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="专业">
<el-select v-model="form.professionalId" clearable
:disabled="form.professionalCategoryId ? false : true"
@change="getData()">
<el-option v-for="(item,index) in ProfessionalList" :key="index"
:label="item.professionalName"
:value="item.professionalId"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="课程类别">
<el-select v-model="form.curriculumType" clearable
@change="getData()">
<el-option label="理论课程" :value="0"></el-option>
<el-option label="实训课程" :value="1"></el-option>
</el-select>
</el-form-item>
</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" class="card">
<div class="flex-between mgb20">
<div class="flex-center">
<p class="hr_tag"></p>
<span>课程列表</span>
</div>
<div>
<el-button type="primary" round @click="addcourse" v-auth>新增课程</el-button>
<el-button type="primary" round @click="delAllSelection" v-auth>批量删除</el-button>
</div>
</div>
<el-table v-loading="loading" :data="courseData" class="table" ref="table" stripe header-align="center"
@selection-change="handleSelectionChange" :row-key="getRowKeys">
<el-table-column type="selection" width="55" align="center"
:reserve-selection="true"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="curriculumName" label="课程名称" align="center"></el-table-column>
<el-table-column prop="curriculumType" label="课程类型" align="center">
<template slot-scope="scope">
<span class="ellipsis">{{ courseTypeStatus[scope.row.curriculumType] }}</span>
</template>
</el-table-column>
<el-table-column prop="userName" label="创建人" align="center"></el-table-column>
<el-table-column label="配置的实训应用" align="center">
<template slot-scope="scope">
<span class="ellipsis">{{ scope.row.sysName }}</span>
</template>
</el-table-column>
<el-table-column prop="orderVolume" label="订单量" 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="pageNo"
layout="total, prev, pager, next" :total="totals"></el-pagination>
</div>
</el-card>
</div>
</template>
<script>
export default {
name: "customer",
data() {
return {
courseTypeStatus: {
0: "理论课程",
1: "实训课程"
},
name: localStorage.getItem("ms_username"),
courseData: [],
form: {
categoryId: "",
professionalCategoryId: "",
professionalId: "",
curriculumType: "",
curriculumName: ""
},
pageNo: +this.$route.query.page || 1,
pageSize: 10,
totals: 0,
subjectList: [], //
ProfessionalClassList: [], //
ProfessionalList: [], //
multipleSelection: [],
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.pageNo,
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.pageNo = 1;
this.getData();
},
//
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("请先选择课程 !");
}
},
//
handleCurrentChange(val) {
this.pageNo = val;
this.$router.push(`curriculum?page=${val}`)
this.getData();
},
//
onSearch() {
this.pageNo = 1;
this.getData();
},
//
changeSwitch(value, row) {
this.$post(`${this.api.isShelves}?cid=${row.cid}&isShelves=${value}`).then((res) => {
this.getData();
this.$message.success("修改上下架状态成功!");
}).catch((res) => {
});
}
}
};
</script>
<style scoped>
.card {
min-height: calc(100vh - 300px);
}
.mag {
margin-right: 20px;
}
</style>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,610 @@
<template>
<el-drawer title="添加系统资源" :visible.sync="sourceVisible" size="1200px" :close-on-click-modal="false"
custom-class="source-dia" @closed="closeDia">
<div class="overflow" v-loading="loading">
<div class="left">
<div class="tabs mgb20">
<a class="item" v-for="(item, i) in tabs" :key="i" :class="{ active: i == active }" @click="tabChange(i)">{{
item
}}</a>
</div>
<template v-if="active !== 'tab3'">
<el-input class="mgb10" style="width: 300px" placeholder="请输入资源名称" prefix-icon="el-icon-search"
v-model="keyword" clearable></el-input>
<div class="course">
<div v-for="(course, i) in course" :key="i" class="item">
<div class="line">
<i :class="`el-icon-caret-right arrow ${course.shrink ? 'active' : ''}`"
@click="course.shrink = !course.shrink"></i>
<el-checkbox class="check" v-model="course.check" @change="checkCourse(course)"></el-checkbox>
<img v-if="course.coverUrl" class="cover" :src="course.coverUrl" alt="">
<span class="course-name">{{ course.curriculumName || course.courseName }}</span>
</div>
<div v-if="course.shrink" class="chapters">
<!-- 章节 -->
<div v-for="(chapter, j) in course.chapters" :key="j" class="">
<div class="line">
<i :class="`el-icon-caret-right arrow ${chapter.shrink ? 'active' : ''}`"
@click="chapter.shrink = !chapter.shrink"></i>
<el-checkbox class="check" v-model="chapter.check" @change="checkChapter(chapter, course)">{{
chapter.name
}}</el-checkbox>
</div>
<!-- 小节 -->
<div v-if="chapter.shrink" class="sections">
<div v-for="(section, k) in chapter.subsections" :key="k" class="line">
<el-checkbox class="check" v-model="section.check" @change="checkSection(section, chapter)">
<img v-if="section.fileType === 'pptx'" src="@/assets/img/exts/ppt.png" alt="">
<img v-else-if="section.fileType === 'mp4'" src="@/assets/img/exts/video.png" alt="">
<img v-else-if="section.fileType === 'doc' || section.fileType === 'docx'"
src="@/assets/img/exts/word.png" alt="">
<img v-else-if="section.fileType === 'xlsx' || section.fileType === 'xls'"
src="@/assets/img/exts/excel.png" alt="">
<img v-else-if="section.fileType === 'txt'" src="@/assets/img/exts/txt.png" alt="">
<img v-else-if="section.fileType === 'pdf'" src="@/assets/img/exts/pdf.png" alt="">
<img v-else src="@/assets/img/exts/pic.png" alt="">
{{ section.name }}</el-checkbox>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<!-- 文件素材 -->
<div v-else class="materials">
<div class="types">
<div class="flex-center m-b-10">
<p class="addhr_tag"></p>
<span>资源类型</span>
</div>
<ul class="lines">
<li v-for="(item, i) in sourceType" :key="i" :class="['line', { active: curType === item.name }]"
@click="checkType(item)">{{ item.name }}</li>
</ul>
</div>
<div class="sources">
<div class="flex-center m-b-10">
<p class="addhr_tag"></p>
<span>资源列表</span>
</div>
<el-input class="m-b-10" placeholder="请输入资源名称" prefix-icon="el-icon-search" v-model="keyword"
clearable></el-input>
<ul class="lines">
<el-checkbox v-if="sources.length" v-model="checkAll" label="全选" @change="checkAllChange"></el-checkbox>
<li v-for="(item, i) in sources" :key="i" class="line">
<el-checkbox v-model="item.check" :label="item.resourceName" @change="sourceChange(item)"></el-checkbox>
</li>
</ul>
</div>
</div>
</div>
<div class="right">
<div v-if="$parent.curSection.id" class="m-b-20">
<p class="total m-b-10">原资源共1个</p>
<div v-html="$parent.curSection.name"></div>
</div>
<template v-if="checked.length">
<div class="flex-between m-b-10">
<p class="total">已选资源{{ checked.length }}</p>
<el-button type="text" @click="batchDelChecked">批量移除</el-button>
</div>
<el-input placeholder="请输入资源名称" prefix-icon="el-icon-search" v-model="checkedKeyword" clearable></el-input>
<div class="lines">
<template v-for="(item, i) in checked">
<div v-if="!item.name || item.name.includes(checkedKeyword)" :key="i" class="line">
<div class="check-left">
<el-checkbox v-model="item.check"></el-checkbox>
<span class="serial">{{ i + 1 }}</span>
<el-tooltip effect="dark" :content="item.name" placement="top-start">
<p class="checked-name ellipsis">{{ item.name }}</p>
</el-tooltip>
</div>
<i class="el-icon-delete action-icon" @click="delChecked(item)"></i>
</div>
</template>
</div>
</template>
<div v-else class="empty">
<img class="icon" src="@/assets/img/empty.svg" alt="">
<p>暂无数据</p>
</div>
</div>
</div>
<div class="btns">
<el-button @click="sourceVisible = false">取消</el-button>
<el-button type="primary" :loading="submiting" @click="submit">确定</el-button>
</div>
</el-drawer>
</template>
<script>
import Setting from '@/setting'
import Util from '@/libs/util'
import _ from 'lodash'
import SourceConst from '@/const/source'
export default {
props: ['visible'],
data () {
return {
sourceVisible: false,
active: 'tab1',
tabs: {
tab1: '教学课程',
tab2: '精品课程',
tab3: '文件素材',
},
sourceType: [],
curType: '全部',
sources: [],
checkAll: false,
keyword: '',
searchTimer: null,
checkedKeyword: '',
allSections: [],
course: [],
checked: [],
submiting: false,
loading: false,
};
},
watch: {
'keyword': function (val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(this.getCourse, 500)
},
visible () {
this.sourceVisible = this.visible
this.visible && this.init()
}
},
mounted () {
},
methods: {
//
init () {
this.checked = []
this.curType = '全部'
this.sourceType = [
{
id: '',
name: '全部'
},
...SourceConst.types
]
this.sourceType.forEach(e => {
e.check = false
})
this.getCourse()
},
//
async getCourse () {
try {
this.loading = true
this.checkAll = false
const { checked } = this
if (this.active === 'tab3') {
const { page } = await this.$post(this.api.resourceLibrary, {
pageNum: 1,
pageSize: 10000,
platformId: Setting.platformId,
type: 2,
keyword: this.keyword,
displayFileType: this.curType === '全部' ? [] : [this.curType],
})
const list = page.records
list.forEach(e => {
const cur = checked.find(m => m.resourceName && m.id === e.id)
e.name = e.resourceName
e.check = !!cur
})
this.sources = list
} else {
const { list } = await this.$post(`${this.api[this.active === 'tab1' ? 'curriculumTree' : 'boutiqueCurriculumTree']}?name=${this.keyword}`)
if (list.length) {
const all = []
list.forEach(e => {
e.shrink = false
e.check = false
e.chapters.forEach(n => {
n.shrink = false
n.check = false
all.push(...n.subsections)
n.subsections.forEach(m => {
const cur = checked.find(j => m.cid === j.cid && m.id === j.id)
m.check = !!cur
})
})
})
list.forEach(e => {
e.shrink = false
e.check = false
e.chapters.forEach(n => {
n.shrink = false
n.check = n.subsections.every(m => m.check)
})
})
list.forEach(e => {
e.shrink = false
e.check = e.chapters.every(m => m.check)
})
list[0].shrink = true
list[0].chapters[0].shrink = true
this.allSections = all
}
this.course = list
}
} finally {
this.loading = false
}
},
initData () {
this.page = 1;
this.getData();
},
tabChange (index) {
this.keyword = ''
this.active = index
this.getCourse()
},
//
checkCourse (row) {
const { check } = row
const { checked } = this
row.chapters.forEach(e => {
e.check = check
e.subsections.forEach(n => {
n.check = check
const cur = checked.findIndex(m => m.id === n.id)
if (check) {
if (cur === -1) {
const section = _.cloneDeep(n)
section.check = false
checked.push(section)
}
} else {
cur !== -1 && checked.splice(cur, 1)
}
})
})
},
//
checkChapter (row, course) {
const { check } = row
const { checked } = this
row.subsections.forEach(n => {
n.check = check
const cur = checked.findIndex(m => m.id === n.id)
if (check) {
if (cur === -1) {
const section = _.cloneDeep(n)
section.check = false
checked.push(section)
}
} else {
cur !== -1 && checked.splice(cur, 1)
}
})
course.check = course.chapters.every(e => e.check)
},
//
async checkSection (row, chapter) {
const { check } = row
const { checked } = this
const cur = checked.findIndex(m => m.id === row.id)
if (check) {
if (cur === -1) {
const section = _.cloneDeep(row)
section.check = false
this.checked.push(section)
}
} else {
cur !== -1 && this.checked.splice(cur, 1)
}
chapter.check = chapter.subsections.every(e => e.check)
},
//
checkAllChange (val) {
this.sources.map(e => {
e.check = val
this.sourceChange(e)
})
},
//
checkType ({ name }) {
this.curType = name
this.getCourse()
},
//
sourceChange (row) {
const { check } = row
const { checked } = this
const cur = checked.findIndex(m => m.id === row.id)
if (check) {
if (cur === -1) {
const section = _.cloneDeep(row)
section.check = false
this.checked.push(section)
}
} else {
cur !== -1 && this.checked.splice(cur, 1)
}
},
//
async batchDelChecked (val) {
try {
const checked = this.checked.filter(e => e.check)
if (checked.length) {
checked.map(e => {
const cur = this.allSections.find(n => n.id === e.id)
if (cur) {
cur.check = false
}
})
this.checked = this.checked.filter(e => !e.check)
} else {
Util.warningMsg('请选择数据')
}
} catch (e) { }
},
//
async delChecked (item) {
try {
const cur = this.allSections.find(e => e.id === item.id)
if (cur) cur.check = false
this.checked.splice(this.checked.findIndex(e => e.id === item.id), 1)
} catch (e) { }
},
//
async submit () {
try {
if (this.submiting) return false
const { checked } = this
if (checked.length) {
this.submiting = true
const { chapterId, id } = this.$parent
const result = checked.map(e => {
return {
chapterId,
cid: id,
resourceId: e.id,
type: e.cid ? 0 : e.resourceName ? 2 : 1,
}
})
const old = this.$parent.curSection //
if (old.id) {
//
await this.$post(this.api.replaceResource, {
chapterId: old.chapterId,
cid: +id,
subsectionId: old.id,
newResource: result
})
} else {
//
await this.$post(this.api.combinationResource, result)
}
this.sourceVisible = false
this.$parent.switchTypeVisible = false
this.$parent.getData()
this.submiting = false
} else {
Util.warningMsg('请选择资源')
}
} catch (e) {
this.submiting = false
}
},
//
closeDia () {
this.$emit('update:visible', false)
}
}
};
</script>
<style lang="scss" scoped>
/deep/.source-dia {
.el-drawer__header {
padding-bottom: 20px;
margin-bottom: 0;
border-bottom: 1px solid #eee;
}
.overflow {
display: flex;
}
.btns {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding: 14px 0;
text-align: center;
background-color: #fff;
box-shadow: 4px -2px 6px 0px rgba(198, 198, 198, 0.3500);
}
.empty {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
font-size: 14px;
text-align: center;
color: #a3a3a3;
}
.left {
width: 700px;
padding: 0 15px;
border-right: 1px solid #eee;
box-sizing: border-box;
.course {
height: calc(100vh - 263px);
overflow: auto;
.item {
padding: 10px;
margin-bottom: 10px;
background-color: #f9f9f9;
}
}
.line {
display: flex;
align-items: center;
}
.arrow {
font-size: 16px;
color: #9f9f9f;
cursor: pointer;
transition: .3s;
&.active {
transform: rotate(90deg);
}
}
.check {
margin: 0 10px;
img {
vertical-align: middle;
}
}
.cover {
width: 100px;
max-height: 80px;
margin-right: 15px;
border-radius: 6px;
}
.course-name {
font-size: 14px;
color: #333;
}
.chapters {
padding-left: 26px;
margin-top: 10px;
.line {
margin-bottom: 10px;
}
}
.chapter-name {
font-size: 13px;
color: #ccc;
}
.sections {
padding-left: 43px;
}
}
.right {
flex: 1;
padding: 15px;
.total {
font-size: 15px;
color: #333;
font-weight: 600;
}
.lines {
height: calc(100vh - 228px);
padding-right: 10px;
margin-top: 10px;
overflow: auto;
}
.line {
display: flex;
padding: 5px 0;
color: #333;
}
.serial {
width: 32px;
margin: 0 12px;
text-align: center;
white-space: nowrap;
}
.check-left {
display: inline-flex;
align-items: center;
}
.checked-name {
width: 360px;
margin-right: 20px;
}
.action-icon {
font-size: 14px;
cursor: pointer;
}
}
.materials {
display: flex;
gap: 20px;
}
.types {
width: 250px;
height: calc(100vh - 223px);
padding: 15px;
background-color: #f9f9f9;
box-sizing: border-box;
overflow: auto;
.line {
margin-bottom: 10px;
cursor: pointer;
&.active {
font-weight: 600;
color: #062c87;
}
}
}
.sources {
flex: 1;
padding: 10px;
.line {
margin-top: 8px;
}
}
}
</style>

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

File diff suppressed because it is too large Load Diff

@ -0,0 +1,332 @@
<template>
<div>
<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">
<el-col :span="4">
<el-form-item label="学科类别">
<el-select v-model="form.categoryId" clearable @change="getProfessionalClass()" @clear="clearClass()">
<el-option v-for="(item, index) in subjectList" :key="index" :label="item.disciplineName"
:value="item.disciplineId"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="专业类">
<el-select v-model="form.professionalCategoryId" clearable :disabled="form.categoryId ? false : true"
@change="getProfessional()" @clear="clearProfess()">
<el-option v-for="(item, index) in ProfessionalClassList" :key="index"
:label="item.professionalClassName" :value="item.professionalClassId"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="专业">
<el-select v-model="form.professionalId" clearable
:disabled="form.professionalCategoryId ? false : true" @change="getData()">
<el-option v-for="(item, index) in ProfessionalList" :key="index" :label="item.professionalName"
:value="item.professionalId"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="课程类别">
<el-select v-model="form.curriculumType" clearable @change="getData()">
<el-option v-for="(item, i) in courseTypeStatus" :key="i" :label="item" :value="i"></el-option>
</el-select>
</el-form-item>
</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" class="card">
<div class="flex-between mgb20">
<div class="flex-center">
<p class="hr_tag"></p>
<span>课程列表</span>
</div>
<div>
<el-button type="primary" round @click="addcourse" v-auth="'/curriculum:新增课程'">新增课程</el-button>
<el-button type="primary" round @click="delAllSelection" v-auth="'/curriculum:批量删除'">批量删除</el-button>
</div>
</div>
<el-table v-loading="loading" :data="courseData" class="table" ref="table" header-align="center"
@selection-change="handleSelectionChange" row-key="cid">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="70" label="序号" align="center"></el-table-column>
<el-table-column prop="curriculumName" label="课程名称" align="center"></el-table-column>
<el-table-column prop="curriculumType" label="课程类别" width="90" align="center">
<template slot-scope="scope">
<span class="ellipsis">{{ courseTypeStatus[scope.row.curriculumType] }}</span>
</template>
</el-table-column>
<el-table-column label="配置的系统" align="center">
<template slot-scope="scope">
<span class="ellipsis">{{ scope.row.sysName }}</span>
</template>
</el-table-column>
<el-table-column prop="expectedCourse" label="预计课时" width="90" align="center"></el-table-column>
<el-table-column prop="orderVolume" label="订单量" width="90" align="center"></el-table-column>
<el-table-column prop="userName" label="创建人" width="120" align="center"></el-table-column>
<el-table-column label="上架/下架" width="90" 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="操作" width="240" align="center">
<template slot-scope="scope">
<el-button type="text" @click="preview(scope.row)">预览课程</el-button>
<el-button type="text" @click="edit(scope.row)" v-auth="'/curriculum:编辑'">编辑</el-button>
<el-button type="text" @click="config(scope.row)" v-auth="'/curriculum:内容设置'">内容设置</el-button>
<el-button type="text" @click="copy(scope.row)">复制</el-button>
<el-button type="text" @click="handleDelete(scope.row)" v-auth="'/curriculum:删除'">删除</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>
<script>
import Setting from '@/setting'
import qs from 'qs'
import Util from '@/libs/util'
export default {
data () {
return {
courseTypeStatus: {
0: '理论课程',
1: '实训课程',
2: '理实课程',
},
name: localStorage.getItem("ms_username"),
courseData: [],
form: {
categoryId: +this.$route.query.categoryId || '',
professionalCategoryId: +this.$route.query.professionalCategoryId || '',
professionalId: +this.$route.query.professionalId || '',
curriculumType: this.$route.query.curriculumType || '',
curriculumName: this.$route.query.curriculumName || ''
},
page: +this.$route.query.page || 1,
pageSize: 10,
totals: 0,
subjectList: [], //
ProfessionalClassList: [], //
ProfessionalList: [], //
multipleSelection: [],
loading: false,
searchTimer: null
};
},
watch: {
"form.curriculumName": function (val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.initData();
}, 500);
}
},
mounted () {
this.getSubject();
this.getData();
},
methods: {
async getData () {
try {
const sid = this.$store.state.dataPer.find(e => e.permissionName === '课程管理')
this.loading = true
const { page } = await this.$post(this.api.curriculumList, {
...this.form,
pageNum: this.page,
pageSize: this.pageSize,
supplierId: sid ? sid.supplierId : '',
platformId: Setting.platformId
})
this.courseData = page.records
this.totals = page.total
this.loading = false
} finally {
this.loading = false
}
},
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("/curriculum/detail");
},
//
edit (row) {
this.setReferrer()
this.$router.push(`/curriculum/detail?cid=${row.cid}`);
},
//
preview (row) {
this.setReferrer()
this.$router.push(`/station?courseId=${row.cid || ''}&curriculumName=${encodeURIComponent(row.curriculumName)}&mallId=${row.mallId || ''}`)
},
//
config (row) {
this.setReferrer()
this.$router.push(`/curriculum/content?cid=${row.cid}&name=${row.curriculumName}`);
},
//
async copy (row) {
this.$confirm('确定要复制吗', "提示", {
type: "warning"
}).then(async () => {
await this.$post(`${this.api.copySelfBuildCourse}?cid=${row.cid}`)
Util.successMsg('复制成功')
this.initData()
}).catch(() => { })
return
this.$router.push(`/curriculum/detail?cid=${row.cid}&copy=1`)
},
//
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.page > 1) {
this.page = this.page - 1
}
}
this.getData();
this.$message.success("删除成功");
this.$refs.table.clearSelection()
}).catch(err => { })
}).catch(() => { })
}
}).catch(err => { })
} else {
this.$message.warning("请先选择课程 !");
}
},
//
handleCurrentChange (val) {
this.page = val;
this.$router.push(`/curriculum?page=${val}`)
this.getData();
},
//
onSearch () {
this.page = 1;
this.getData();
},
//
changeSwitch (value, row) {
this.$post(`${this.api.isShelves}?cid=${row.cid}&isShelves=${value}`).then((res) => {
this.getData();
this.$message.success("修改上下架状态成功!");
}).catch((res) => {
});
}
}
};
</script>
<style scoped>
.card {
min-height: calc(100vh - 300px);
}
</style>

File diff suppressed because it is too large Load Diff

@ -16,9 +16,10 @@
<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" placeholder="请输入订单编号/产品名称" prefix-icon="el-icon-search" v-model="keyword"
clearable></el-input>
</div> </div>
<el-table :data="orderData" class="table" ref="table" stripe header-align="center" <el-table :data="orderData" class="table" ref="table" header-align="center"
@selection-change="handleSelectionChange" :row-key="getRowKeys"> @selection-change="handleSelectionChange" :row-key="getRowKeys">
<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>
@ -47,8 +48,8 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background layout="total, prev, pager, next" <el-pagination background layout="total, prev, pager, next" @current-change="handleCurrentChange"
@current-change="handleCurrentChange" :current-page="page" :total="totals"> :current-page="page" :total="totals">
</el-pagination> </el-pagination>
</div> </div>
</el-card> </el-card>
@ -80,6 +81,13 @@ export default {
} }
}, },
created () { created () {
const { orderParam } = this.$store.state
if (orderParam) {
this.keyword = orderParam.keyword
this.page = orderParam.page
this.$store.commit('setOrderParam', null)
}
this.getData(); this.getData();
}, },
methods: { methods: {
@ -107,13 +115,21 @@ export default {
this.page = 1 this.page = 1
this.getData() this.getData()
}, },
handleCurrentChange (val) {
this.page = val
this.getData()
},
toDetail (row) { toDetail (row) {
this.$store.commit('setOrderParam', {
keyword: this.keyword,
page: this.page,
})
this.$router.push({ this.$router.push({
path: '/AddOrder', path: '/AddOrder',
query: { query: {
val: 'watch', val: 'watch',
orderId: row.orderId, orderId: row.orderId,
orderStatus: row.orderStatus === '已完成' ? 1 : 0 orderStatus: row.orderStatus === '已完成' ? 1 : 0,
} }
}) })
}, },
@ -128,9 +144,11 @@ export default {
.card { .card {
min-height: calc(100vh - 300px); min-height: calc(100vh - 300px);
} }
.mag { .mag {
margin-right: 20px; margin-right: 20px;
} }
.cell { .cell {
white-space: pre-wrap; white-space: pre-wrap;
width: 140px; width: 140px;
@ -141,9 +159,11 @@ export default {
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;
color: #000;
white-space: pre-wrap; white-space: pre-wrap;
width: 140px; width: 140px;
overflow: hidden; overflow: hidden;
@ -154,4 +174,3 @@ export default {
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
} }
</style> </style>

@ -44,7 +44,7 @@
<p class="addhr_tag"></p> <p class="addhr_tag"></p>
<span>应用列表</span> <span>应用列表</span>
</div> </div>
<el-table :data="permissionData" class="table" stripe :span-method="SpanMethod" header-align="center"> <el-table :data="permissionData" class="table" :span-method="SpanMethod" header-align="center">
<el-table-column prop="id" label="序号" align="center"> <el-table-column prop="id" label="序号" align="center">
</el-table-column> </el-table-column>
<el-table-column prop="age" label="应用名称" align="center"> <el-table-column prop="age" label="应用名称" align="center">
@ -90,10 +90,7 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center"> <el-table-column label="操作" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch <el-switch v-model="scope.row.swtich" active-text="开启" inactive-text="关闭"
v-model="scope.row.swtich"
active-text="开启"
inactive-text="关闭"
@change="changeSwitch(scope.row)"> @change="changeSwitch(scope.row)">
</el-switch> </el-switch>
</template> </template>
@ -113,7 +110,7 @@
<p class="hr_tag"></p> <p class="hr_tag"></p>
<span>客户列表</span> <span>客户列表</span>
</div> </div>
<el-table :data="permissionData" class="table" stripe header-align="center"> <el-table :data="permissionData" class="table" header-align="center">
<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="age" label="服务器名称" align="center"> <el-table-column prop="age" label="服务器名称" align="center">
@ -219,24 +216,31 @@
border-left: 1px dashed #eee; border-left: 1px dashed #eee;
padding: 0 60px; padding: 0 60px;
} }
.border_lf label { .border_lf label {
width: 120px; width: 120px;
} }
.pad_none { .pad_none {
padding: 0 0 0 60px; padding: 0 0 0 60px;
} }
.mar_input { .mar_input {
margin-right: 80px; margin-right: 80px;
} }
.marb30 { .marb30 {
margin-bottom: 30px; margin-bottom: 30px;
} }
.tab_temp label { .tab_temp label {
width: 60px; width: 60px;
} }
.mar10 { .mar10 {
margin-top: 10px; margin-top: 10px;
} }
.radio_icon { .radio_icon {
font-size: 26px; font-size: 26px;
color: #9278FF; color: #9278FF;

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

@ -5,11 +5,14 @@
<div class="plus"> <div class="plus">
<i class="el-icon-circle-plus-outline" @click.stop="addType(0)"></i> <i class="el-icon-circle-plus-outline" @click.stop="addType(0)"></i>
</div> </div>
<el-tree ref="type" :data="typeList" node-key="id" accordion :default-expanded-keys="defaultActive" :current-node-key="categoryId" :props="defaultProps" :highlight-current="true" v-loading="loadingType" @current-change="typeClick"> <el-tree ref="type" :data="typeList" node-key="id" accordion :default-expanded-keys="defaultActive"
:current-node-key="categoryId" :props="defaultProps" :highlight-current="true" v-loading="loadingType"
@current-change="typeClick">
<span class="custom-tree-node" slot-scope="{ node, data }"> <span class="custom-tree-node" slot-scope="{ node, data }">
<span :title="node.label">{{ node.label }}</span> <span :title="node.label">{{ node.label }}</span>
<span class="actions"> <span class="actions">
<i class="el-icon-circle-plus-outline" @click.stop="addType(node)" v-if="data.level != 6" v-auth="'/data:数据架构:新增分类'"></i> <i class="el-icon-circle-plus-outline" @click.stop="addType(node)" v-if="data.level != 6"
v-auth="'/data:数据架构:新增分类'"></i>
<i class="el-icon-edit" @click.stop="editType(node)" v-auth="'/data:数据架构:编辑分类'"></i> <i class="el-icon-edit" @click.stop="editType(node)" v-auth="'/data:数据架构:编辑分类'"></i>
<i class="el-icon-delete" @click.stop="delType(node)" v-auth="'/data:数据架构:删除分类'"></i> <i class="el-icon-delete" @click.stop="delType(node)" v-auth="'/data:数据架构:删除分类'"></i>
</span> </span>
@ -21,7 +24,8 @@
<el-form label-width="80px" class="flex-between mgb20"> <el-form label-width="80px" class="flex-between mgb20">
<div class="flex-center"> <div class="flex-center">
<el-form-item label="更新时间" style="margin: 0 20px 0 0"> <el-form-item label="更新时间" style="margin: 0 20px 0 0">
<el-date-picker v-model="updateTime" type="date" placeholder="选择日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" @change="initData"></el-date-picker> <el-date-picker v-model="updateTime" type="date" placeholder="选择日期" format="yyyy-MM-dd"
value-format="yyyy-MM-dd" @change="initData"></el-date-picker>
</el-form-item> </el-form-item>
<el-input placeholder="请输入数据表名称" v-model="keyword" prefix-icon="el-icon-search" clearable></el-input> <el-input placeholder="请输入数据表名称" v-model="keyword" prefix-icon="el-icon-search" clearable></el-input>
</div> </div>
@ -30,7 +34,8 @@
<el-button type="primary" round @click="delAllSelection" v-auth="'/data:数据架构:批量删除'">批量删除</el-button> <el-button type="primary" round @click="delAllSelection" v-auth="'/data:数据架构:批量删除'">批量删除</el-button>
</div> </div>
</el-form> </el-form>
<el-table :data="listData" class="table" ref="table" stripe header-align="center" @selection-change="handleSelectionChange"> <el-table :data="listData" class="table" ref="table" header-align="center"
@selection-change="handleSelectionChange">
<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="70" label="序号" align="center"></el-table-column> <el-table-column type="index" width="70" label="序号" align="center"></el-table-column>
<el-table-column prop="tableComment" label="数据表名称" align="center"> <el-table-column prop="tableComment" label="数据表名称" align="center">
@ -57,28 +62,21 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background layout="total, prev, pager, next" :current-page="page" @current-change="handleCurrentChange" :total="total"> <el-pagination background layout="total, prev, pager, next" :current-page="page"
@current-change="handleCurrentChange" :total="total">
</el-pagination> </el-pagination>
</div> </div>
</div> </div>
<!-- 导入数据 --> <!-- 导入数据 -->
<el-dialog title="导入" :visible.sync="importVisible" width="80%" center @close="closeImport" class="dialog" :close-on-click-modal="false"> <el-dialog title="导入" :visible.sync="importVisible" width="80%" center @close="closeImport" class="dialog"
:close-on-click-modal="false">
<el-container style="padding: 20px 0 20px 20px;background-color: #f0f0f0;"> <el-container style="padding: 20px 0 20px 20px;background-color: #f0f0f0;">
<div style="overflow:auto;height: 558px;width:330px;padding:15px;background:#fff" ref="typeTreeWrap" @scroll="loadType"> <div style="overflow:auto;height: 558px;width:330px;padding:15px;background:#fff" ref="typeTreeWrap"
<el-tree v-loading="importLoading" @scroll="loadType">
ref="typeTree" <el-tree v-loading="importLoading" ref="typeTree" :data="importTypeList" node-key="id" accordion
:data="importTypeList" :default-expanded-keys="defaultTypeActive" :default-checked-keys="defaultTypeChecked"
node-key="id" :current-node-key="curId" show-checkbox :props="defaultProps" highlight-current
accordion @node-click="importTypeClick" @node-expand="importTypeExpand">
:default-expanded-keys="defaultTypeActive"
:default-checked-keys="defaultTypeChecked"
:current-node-key="curId"
show-checkbox
:props="defaultProps"
highlight-current
@node-click="importTypeClick"
@node-expand="importTypeExpand"
>
</el-tree> </el-tree>
</div> </div>
@ -88,9 +86,10 @@
<p class="hr_tag"></p> <p class="hr_tag"></p>
<span>预览</span> <span>预览</span>
</div> </div>
<el-table :data="fieldData" stripe header-align="center" v-if="fieldHead.length"> <el-table :data="fieldData" header-align="center" v-if="fieldHead.length">
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column> <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column v-for="(item,index) in fieldHead" :prop="item.field" :key="index" :label="item.comment" align="center"></el-table-column> <el-table-column v-for="(item, index) in fieldHead" :prop="item.field" :key="index" :label="item.comment"
align="center"></el-table-column>
</el-table> </el-table>
</el-card> </el-card>
</el-main> </el-main>
@ -102,7 +101,8 @@
</span> </span>
</el-dialog> </el-dialog>
<!-- 新增编辑分类 --> <!-- 新增编辑分类 -->
<el-dialog :title="id ? '编辑分类' : '新增分类'" :visible.sync="typeVisible" width="24%" center @close="closeType" :close-on-click-modal="false"> <el-dialog :title="id ? '编辑分类' : '新增分类'" :visible.sync="typeVisible" width="24%" center @close="closeType"
:close-on-click-modal="false">
<el-input placeholder="请输入分类名称" v-model="categoryName"></el-input> <el-input placeholder="请输入分类名称" v-model="categoryName"></el-input>
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button @click="typeVisible = false"> </el-button> <el-button @click="typeVisible = false"> </el-button>
@ -111,9 +111,10 @@
</el-dialog> </el-dialog>
<!-- 预览 --> <!-- 预览 -->
<el-dialog title="预览" :visible.sync="previewVisible" width="60%" center :close-on-click-modal="false"> <el-dialog title="预览" :visible.sync="previewVisible" width="60%" center :close-on-click-modal="false">
<el-table :data="previewData" class="table" stripe header-align="center" row-key="id"> <el-table :data="previewData" class="table" header-align="center" row-key="id">
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column> <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column v-for="(item,index) in previewHead" :prop="item.field" :key="index" :label="item.comment" align="center"></el-table-column> <el-table-column v-for="(item, index) in previewHead" :prop="item.field" :key="index" :label="item.comment"
align="center"></el-table-column>
</el-table> </el-table>
</el-dialog> </el-dialog>
<!-- 编辑产品数据表名称 --> <!-- 编辑产品数据表名称 -->
@ -126,14 +127,15 @@
</el-dialog> </el-dialog>
<!-- 自定义表头 --> <!-- 自定义表头 -->
<el-dialog title="自定义表头" :visible.sync="headVisible" width="60%" center :close-on-click-modal="false"> <el-dialog title="自定义表头" :visible.sync="headVisible" width="60%" center :close-on-click-modal="false">
<el-table :data="previewData" class="table" stripe header-align="center" row-key="id" :key="editIndex"> <el-table :data="previewData" class="table" header-align="center" row-key="id" :key="editIndex">
<el-table-column type="index" width="100" label="序号" align="center"> <el-table-column type="index" width="100" label="序号" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<template v-if="scope.row.custom">序号</template> <template v-if="scope.row.custom">序号</template>
<template v-else>{{ scope.$index }}</template> <template v-else>{{ scope.$index }}</template>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column v-for="(item,index) in previewHead" :prop="item.field" :key="index" :label="item.oldComment" align="center"> <el-table-column v-for="(item, index) in previewHead" :prop="item.field" :key="index" :label="item.oldComment"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<template v-if="scope.row.custom"> <template v-if="scope.row.custom">
<el-input placeholder="请输入" size="medium" v-model="item.comment"></el-input> <el-input placeholder="请输入" size="medium" v-model="item.comment"></el-input>
@ -742,26 +744,31 @@ export default {
display: flex; display: flex;
height: calc(100vh - 223px); height: calc(100vh - 223px);
padding: 0 24px; padding: 0 24px;
.side { .side {
width: 300px; width: 300px;
padding: 24px 10px 24px 0; padding: 24px 10px 24px 0;
margin-right: 24px; margin-right: 24px;
border-right: 1px solid rgba(0, 0, 0, 0.06); border-right: 1px solid rgba(0, 0, 0, 0.06);
} }
.right { .right {
width: calc(100% - 374px); width: calc(100% - 374px);
padding: 24px 0; padding: 24px 0;
} }
.plus { .plus {
text-align: right; text-align: right;
color: #9278FF; color: #9278FF;
cursor: pointer; cursor: pointer;
} }
.custom-tree-node { .custom-tree-node {
flex: 1; flex: 1;
display: inline-flex; display: inline-flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
.actions { .actions {
i { i {
margin-left: 5px; margin-left: 5px;

@ -1,13 +1,16 @@
<template> <template>
<div class="wrap"> <div class="wrap">
<div class="side"> <div class="side">
<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> <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>
</div> </div>
<div class="right"> <div class="right">
<div class="flex-between" style="margin-bottom: 10px;"> <div class="flex-between" style="margin-bottom: 10px;">
<p>数据简介</p> <p>数据简介</p>
<el-button v-if="introduceText && !editing" type="primary" @click="editing = !editing" v-auth="'/data:数据简介:编辑'">编辑</el-button> <el-button v-if="introduceText && !editing" type="primary" @click="editing = !editing"
v-auth="'/data:数据简介:编辑'">编辑</el-button>
</div> </div>
<div class="intro" v-if="!introduceText && !editing"> <div class="intro" v-if="!introduceText && !editing">
<p class="text">请添加简介</p> <p class="text">请添加简介</p>
@ -19,7 +22,8 @@
<el-input placeholder="请输入简介" v-model="introduce" type="textarea" rows="5" :disabled="!editing"></el-input> <el-input placeholder="请输入简介" v-model="introduce" type="textarea" rows="5" :disabled="!editing"></el-input>
<div class="field"> <div class="field">
<p class="label">数据源</p> <p class="label">数据源</p>
<el-input style="width: 250px" placeholder="请输入数据源" v-model="dataSource" type="text" :disabled="!editing"></el-input> <el-input style="width: 250px" placeholder="请输入数据源" v-model="dataSource" type="text"
:disabled="!editing"></el-input>
</div> </div>
</template> </template>
<div class="field"> <div class="field">
@ -27,17 +31,14 @@
<div class="tag-add" v-if="editing"> <div class="tag-add" v-if="editing">
<el-input placeholder="请输入关键字" size="small" v-model="newKeyword"></el-input> <el-input placeholder="请输入关键字" size="small" v-model="newKeyword"></el-input>
<span v-if="editing"> <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> <el-button @click="save"
style="color: #062c87;border: 1px solid #062c87;border-radius:5px;height: 25px;line-height: 0px">
</el-button>
</span> </span>
</div> </div>
<div class="tag-wrap"> <div class="tag-wrap">
<el-tag <el-tag :key="tag.id" :type="editing ? '' : 'info'" v-for="tag in keywordList" :closable="editing"
:key="tag.id" :disable-transitions="false" @close="delKeyword(tag)">
:type="editing ? '' : 'info'"
v-for="tag in keywordList"
:closable="editing"
:disable-transitions="false"
@close="delKeyword(tag)">
{{ tag.keyword }} {{ tag.keyword }}
</el-tag> </el-tag>
</div> </div>
@ -53,6 +54,7 @@
export default { export default {
data () { data () {
return { return {
id: this.$route.query.id || '',
typeList: [], typeList: [],
defaultProps: { defaultProps: {
children: 'children', children: 'children',
@ -95,11 +97,10 @@ export default {
}) })
} }
handleId(res) handleId(res)
console.log(res)
this.typeList = res this.typeList = res
// id
if (!this.edited) { if (!this.edited) {
// id
if (res[0].children.length) { if (res[0].children.length) {
let item = res[0].children[0] let item = res[0].children[0]
this.categoryId = item.id this.categoryId = item.id
@ -119,13 +120,18 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.$refs.type.setCurrentKey(this.categoryId) this.$refs.type.setCurrentKey(this.categoryId)
}) })
} else if (this.id) {
this.$nextTick(() => {
this.defaultActive = [+this.id]
this.$refs.type.setCurrentKey(+this.id)
})
} }
this.getKeyword() this.getKeyword()
}).catch(res => { }) }).catch(res => { })
}, },
// //
typeClick (data, node) { typeClick (data, node) {
console.log(data) this.$router.push(`/data?tab=third&id=${data.id}`).catch(e => { })
this.editing = false this.editing = false
this.categoryId = data.id this.categoryId = data.id
this.defaultActive = [data.id] this.defaultActive = [data.id]
@ -149,7 +155,6 @@ export default {
}, },
// //
saveType () { saveType () {
const id = this.categoryId // id const id = this.categoryId // id
this.$post(this.api.updateCategory, { this.$post(this.api.updateCategory, {
id, id,
@ -160,7 +165,7 @@ export default {
this.introduceText = this.introduce this.introduceText = this.introduce
this.editing = false this.editing = false
this.edited = true this.edited = true
// this.getData() this.getData()
}).catch(res => { }) }).catch(res => { })
}, },
// //
@ -214,58 +219,72 @@ export default {
display: flex; display: flex;
height: calc(100vh - 223px); height: calc(100vh - 223px);
padding: 0 24px; padding: 0 24px;
.side { .side {
width: 300px; width: 300px;
padding: 24px 10px 24px 0; padding: 24px 10px 24px 0;
margin-right: 24px; margin-right: 24px;
border-right: 1px solid rgba(0, 0, 0, 0.06); border-right: 1px solid rgba(0, 0, 0, 0.06);
} }
.right { .right {
width: calc(100% - 374px); width: calc(100% - 374px);
padding: 24px 0; padding: 24px 0;
} }
.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;
} }
} }
.field { .field {
margin-top: 20px; margin-top: 20px;
text-align: left; text-align: left;
.label { .label {
margin-bottom: 10px; margin-bottom: 10px;
} }
} }
.tag-wrap { .tag-wrap {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.btns { .btns {
margin-top: 20px; margin-top: 20px;
} }
} }
.tag-add { .tag-add {
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: 10px; margin-bottom: 10px;
.el-input { .el-input {
width: 200px; width: 200px;
} }
.el-button { .el-button {
margin-left: 5px; margin-left: 5px;
} }
} }
.mag { .mag {
margin-right: 20px; margin-right: 20px;
margin-left: 20px; margin-left: 20px;
} }
.el-tag+.el-tag { .el-tag+.el-tag {
margin-left: 10px; margin-left: 10px;
} }
.button-new-tag { .button-new-tag {
margin-left: 10px; margin-left: 10px;
height: 32px; height: 32px;
@ -273,6 +292,7 @@ export default {
padding-top: 0; padding-top: 0;
padding-bottom: 0; padding-bottom: 0;
} }
.input-new-tag { .input-new-tag {
width: 90px; width: 90px;
margin-left: 10px; margin-left: 10px;

@ -5,12 +5,14 @@
<ul class="filter"> <ul class="filter">
<li> <li>
<label>创建日期</label> <label>创建日期</label>
<el-date-picker v-model="date" align="right" unlink-panels type="daterange" start-placeholder="开始日期" end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" clearable></el-date-picker> <el-date-picker v-model="date" align="right" unlink-panels type="daterange" start-placeholder="开始日期"
end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" clearable></el-date-picker>
</li> </li>
<li> <li>
<label>状态</label> <label>状态</label>
<el-select v-model="status" clearable placeholder="请选择状态" @change="initData"> <el-select v-model="status" clearable placeholder="请选择状态" @change="initData">
<el-option v-for="(item,index) in statusList" :key="index" :label="item.name" :value="item.value"></el-option> <el-option v-for="(item, index) in statusList" :key="index" :label="item.name"
:value="item.value"></el-option>
</el-select> </el-select>
</li> </li>
</ul> </ul>
@ -25,7 +27,8 @@
<el-button type="primary" round @click="delAllSelection" v-auth="'/data:产品管理:批量删除'">批量删除</el-button> <el-button type="primary" round @click="delAllSelection" v-auth="'/data:产品管理:批量删除'">批量删除</el-button>
</div> </div>
</div> </div>
<el-table :data="listData" class="table" ref="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id"> <el-table :data="listData" class="table" ref="table" header-align="center" @selection-change="handleSelectionChange"
row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column> <el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column> <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="productName" label="产品名称" align="center"></el-table-column> <el-table-column prop="productName" label="产品名称" align="center"></el-table-column>
@ -36,7 +39,8 @@
<el-table-column prop="createTime" label="创建时间" align="center"></el-table-column> <el-table-column prop="createTime" label="创建时间" align="center"></el-table-column>
<el-table-column prop="orderNature" label="状态" align="center"> <el-table-column prop="orderNature" label="状态" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch v-model="scope.row.status" :active-text="scope.row.status ? '上架' : '下架'" :active-value="1" :inactive-value="0" @change="switchOff($event,scope.row,scope.$index)" v-auth="'/data:产品管理:上架'"></el-switch> <el-switch v-model="scope.row.status" :active-text="scope.row.status ? '上架' : '下架'" :active-value="1"
:inactive-value="0" @change="switchOff($event, scope.row, scope.$index)" v-auth="'/data:产品管理:上架'"></el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作"> <el-table-column label="操作">
@ -48,24 +52,28 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background layout="total, prev, pager, next" @current-change="handleCurrentChange" :current-page="page" :total="totals"></el-pagination> <el-pagination background layout="total, prev, pager, next" @current-change="handleCurrentChange"
:current-page="page" :total="totals"></el-pagination>
</div> </div>
<el-dialog :title="isDetail ? '查看产品' : (id ? '编辑产品' : '新增产品')" :visible.sync="productVisible" width="600px" center @close="closeProduct" class="dialog" :close-on-click-modal="false"> <el-dialog :title="isDetail ? '查看产品' : (id ? '编辑产品' : '新增产品')" :visible.sync="productVisible" width="600px" center
@close="closeProduct" class="dialog" :close-on-click-modal="false">
<el-form ref="form" label-width="98px" :disabled="isDetail" v-loading="loading"> <el-form ref="form" label-width="98px" :disabled="isDetail" v-loading="loading">
<el-form-item label="数据产品名称"> <el-form-item label="数据产品名称">
<el-input v-model="productName" placeholder="请输入数据产品名称"></el-input> <el-input v-model="productName" placeholder="请输入数据产品名称"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="供应厂商" prop="supplier"> <el-form-item label="供应厂商" prop="supplier">
<el-select v-model="supplier" clearable placeholder="请选择供应厂商"> <el-select v-model="supplier" clearable placeholder="请选择供应厂商">
<el-option v-for="(item, i) in suppliers" :key="i" :label="item.supplierName" :value="item.supplierId"></el-option> <el-option v-for="(item, i) in suppliers" :key="i" :label="item.supplierName"
:value="item.supplierId"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="配置数据"> <el-form-item label="配置数据">
<el-button type="primary" @click="configData">配置数据权限</el-button> <el-button type="primary" @click="configData">配置数据权限</el-button>
</el-form-item> </el-form-item>
<div class="type-wrap" ref="typeWrap" @scroll="loadType" v-show="checkedIds.length"> <div class="type-wrap" ref="typeWrap" @scroll="loadType" v-show="checkedIds.length">
<el-tree ref="type" :data="typeList" show-checkbox accordion node-key="id" :default-expanded-keys="checkedIds" :default-checked-keys="checkedIds" :props="defaultProps" @node-expand="typeExpand"> <el-tree ref="type" :data="typeList" show-checkbox accordion node-key="id" :default-expanded-keys="checkedIds"
:default-checked-keys="checkedIds" :props="defaultProps" @node-expand="typeExpand">
<span class="custom-tree-node" slot-scope="{ node, data }"> <span class="custom-tree-node" slot-scope="{ node, data }">
<span :title="node.label">{{ node.label }}</span> <span :title="node.label">{{ node.label }}</span>
</span> </span>
@ -78,10 +86,13 @@
</span> </span>
</el-dialog> </el-dialog>
<el-dialog title="数据配置" :visible.sync="configVisible" width="70%" center @close="closeConfig" :close-on-click-modal="false"> <el-dialog title="数据配置" :visible.sync="configVisible" width="70%" center @close="closeConfig"
:close-on-click-modal="false">
<el-container style="padding: 20px 0 20px 20px;background-color: #f0f0f0;"> <el-container style="padding: 20px 0 20px 20px;background-color: #f0f0f0;">
<el-aside width="300px"> <el-aside width="300px">
<el-tree style="margin: 10px;" ref="typeConfig" :data="typeConfigList" show-checkbox node-key="id" accordion :default-expanded-keys="configIds" :default-checked-keys="configIds" :current-node-key="categoryId" :props="defaultProps" highlight-current @current-change="typeConfigClick"> <el-tree style="margin: 10px;" ref="typeConfig" :data="typeConfigList" show-checkbox node-key="id" accordion
:default-expanded-keys="configIds" :default-checked-keys="configIds" :current-node-key="categoryId"
:props="defaultProps" highlight-current @current-change="typeConfigClick">
<span class="custom-tree-node" slot-scope="{ node, data }"> <span class="custom-tree-node" slot-scope="{ node, data }">
<span :title="node.label">{{ node.label }}</span> <span :title="node.label">{{ node.label }}</span>
</span> </span>
@ -93,12 +104,14 @@
<el-form label-width="80px" class="flex-between mgb20"> <el-form label-width="80px" class="flex-between mgb20">
<div class="flex-center"> <div class="flex-center">
<el-form-item label="创建日期" style="margin: 0 20px 0 0"> <el-form-item label="创建日期" style="margin: 0 20px 0 0">
<el-date-picker v-model="updateTime" type="date" placeholder="选择日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" @change="initConfigData"></el-date-picker> <el-date-picker v-model="updateTime" type="date" placeholder="选择日期" format="yyyy-MM-dd"
value-format="yyyy-MM-dd" @change="initConfigData"></el-date-picker>
</el-form-item> </el-form-item>
<el-input placeholder="请输入数据表名称" v-model="keywordConfig" prefix-icon="el-icon-search" clearable></el-input> <el-input placeholder="请输入数据表名称" v-model="keywordConfig" prefix-icon="el-icon-search"
clearable></el-input>
</div> </div>
</el-form> </el-form>
<el-table :data="listConfigData" class="table" ref="table" stripe header-align="center"> <el-table :data="listConfigData" class="table" ref="table" header-align="center">
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column> <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="showName" label="数据表名称" align="center"></el-table-column> <el-table-column prop="showName" label="数据表名称" align="center"></el-table-column>
<el-table-column prop="dataTotal" label="数据总量" align="center"></el-table-column> <el-table-column prop="dataTotal" label="数据总量" align="center"></el-table-column>
@ -111,7 +124,8 @@
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background layout="total, prev, pager, next" :current-page="pageConfig" @current-change="handleCurrentConfigChange" :total="totalConfig"></el-pagination> <el-pagination background layout="total, prev, pager, next" :current-page="pageConfig"
@current-change="handleCurrentConfigChange" :total="totalConfig"></el-pagination>
</div> </div>
</el-card> </el-card>
</el-main> </el-main>
@ -123,9 +137,10 @@
</el-dialog> </el-dialog>
<el-dialog title="预览" :visible.sync="previewVisible" width="60%" center :close-on-click-modal="false"> <el-dialog title="预览" :visible.sync="previewVisible" width="60%" center :close-on-click-modal="false">
<el-table :data="previewData" class="table" stripe header-align="center" row-key="id"> <el-table :data="previewData" class="table" header-align="center" row-key="id">
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column> <el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column v-for="(item,index) in previewHead" :prop="item.field" :key="index" :label="item.comment" align="center"></el-table-column> <el-table-column v-for="(item, index) in previewHead" :prop="item.field" :key="index" :label="item.comment"
align="center"></el-table-column>
</el-table> </el-table>
</el-dialog> </el-dialog>
</div> </div>
@ -668,20 +683,24 @@ export default {
/deep/.el-input--suffix .el-input__inner { /deep/.el-input--suffix .el-input__inner {
padding-right: 56px; padding-right: 56px;
} }
.type-wrap { .type-wrap {
height: 450px; height: 450px;
margin-left: 25px; margin-left: 25px;
overflow: auto; overflow: auto;
} }
.settlement { .settlement {
display: flex; display: flex;
margin-bottom: 10px; margin-bottom: 10px;
.label { .label {
margin-right: 10px; margin-right: 10px;
white-space: nowrap; white-space: nowrap;
color: #606266; color: #606266;
font-size: 14px; font-size: 14px;
} }
.el-input { .el-input {
width: 150px; width: 150px;
margin-right: 30px; margin-right: 30px;

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

@ -204,7 +204,8 @@ export default {
}, },
goback () { goback () {
this.$confirm("确定返回?未更新的信息将不会保存。", "提示", { this.$confirm("确定返回?未更新的信息将不会保存。", "提示", {
type: "warning" type: "warning",
closeOnClickModal: false
}) })
.then(() => { .then(() => {
this.back(); this.back();

@ -3,35 +3,65 @@
<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" type="primary" round @click="cancelSort">取消</el-button> <el-button class="action-btn"
<el-button class="action-btn" type="primary" round @click="sortSubmit">保存</el-button> type="primary"
round
@click="cancelSort">取消</el-button>
<el-button class="action-btn"
type="primary"
round
@click="sortSubmit">保存</el-button>
</template> </template>
<template v-if="!sorting"> <template v-if="!sorting">
<el-button v-auth="'栏目管理:更改排序'" class="action-btn" type="primary" round @click="openSort">更改排序 <el-button v-auth="'栏目管理:更改排序'"
class="action-btn"
type="primary"
round
@click="openSort">更改排序
</el-button> </el-button>
<el-button v-auth="'栏目管理:添加栏目'" class="action-btn" type="primary" round @click="handleColumn(false, 0, 0)">添加栏目 <el-button v-auth="'栏目管理:添加栏目'"
class="action-btn"
type="primary"
round
@click="handleColumn(false, 0, 0)">添加栏目
</el-button> </el-button>
</template> </template>
</div> </div>
<div class="page-content" style="padding-top: 24px; margin-top: 24px"> <div class="page-content"
style="padding-top: 24px; margin-top: 24px">
<div class="el-table"> <div class="el-table">
<div class="list"> <div class="list">
<div class="thead"> <div class="thead">
<span>栏目名称</span> <span>栏目名称</span>
<span><em :class="{hide: sorting}" style="font-style: normal">操作</em></span> <span><em :class="{hide: sorting}"
style="font-style: normal">操作</em></span>
</div> </div>
</div> </div>
<el-tree :data="list" node-key="id" default-expand-all :draggable="sorting" :allow-drop="allowDrop"> <el-tree :data="list"
<span class="custom-tree-node" slot-scope="{ node, data }"> 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="name">{{ data.name }}</span>
<span class="action" v-show="!sorting"> <span class="action"
<el-button v-auth="'栏目管理:编辑'" type="text" @click.stop="handleColumn(data)">编辑</el-button> v-show="!sorting">
<el-divider v-auth="'栏目管理:编辑'" direction="vertical"></el-divider> <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"> <template v-if="node.level < 4">
<el-button v-auth="'栏目管理:新增'" type="text" @click.stop="handleColumn(data, data.id, data.level + 1)">新增</el-button> <el-button v-auth="'栏目管理:新增'"
<el-divider v-auth="'栏目管理:新增'" direction="vertical"></el-divider> 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="'栏目管理:删除'" type="text" @click.stop="delData(data)">删除</el-button> <el-button v-auth="'栏目管理:删除'"
type="text"
@click.stop="delData(data)">删除</el-button>
</span> </span>
</span> </span>
</el-tree> </el-tree>
@ -39,16 +69,22 @@
</div> </div>
</div> </div>
<el-dialog :title="!curRow.id ? '添加栏目' : '编辑栏目'" :visible.sync="columnVisible" width="400px" <el-dialog :title="!curRow.id ? '添加栏目' : '编辑栏目'"
:close-on-click-modal="false" @close="closeColumn"> :visible.sync="columnVisible"
width="400px"
:close-on-click-modal="false"
@close="closeColumn">
<el-form> <el-form>
<el-form-item> <el-form-item>
<el-input placeholder="栏目名称" v-model="curRow.name"></el-input> <el-input placeholder="栏目名称"
v-model="curRow.name"></el-input>
</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="columnVisible = false"> </el-button> <el-button @click="columnVisible = false"> </el-button>
<el-button type="primary" @click="columnSubmit"> </el-button> <el-button type="primary"
@click="columnSubmit"> </el-button>
</span> </span>
</el-dialog> </el-dialog>
</div> </div>
@ -90,7 +126,8 @@ export default {
beforeRouteLeave (to, from, next) { beforeRouteLeave (to, from, next) {
if (JSON.stringify(this.originList) !== JSON.stringify(this.list)) { if (JSON.stringify(this.originList) !== JSON.stringify(this.list)) {
this.$confirm("确定返回?排序尚未保存。", "提示", { this.$confirm("确定返回?排序尚未保存。", "提示", {
type: "warning" type: "warning",
closeOnClickModal: false
}) })
.then(() => { .then(() => {
next(); next();
@ -264,7 +301,7 @@ export default {
.el-tree-node__content { .el-tree-node__content {
padding: 5px; padding: 5px;
border-bottom: 0.0625rem solid #EBEEF5; border-bottom: 0.0625rem solid #ebeef5;
} }
} }

@ -9,7 +9,8 @@
<el-button v-auth="'内容管理:新增文章'" class="action-btn" type="primary" @click="addArticle">新增文章</el-button> <el-button v-auth="'内容管理:新增文章'" class="action-btn" type="primary" @click="addArticle">新增文章</el-button>
</div> </div>
<div class="page-content" style="padding-top: 24px"> <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 ref="table" :data="list" class="table" 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="selection" width="80" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center"> <el-table-column type="index" width="60" label="序号" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
@ -41,22 +42,16 @@
</el-table-column> </el-table-column>
<el-table-column prop="name" label="文章发布状态" width="120" align="center"> <el-table-column prop="name" label="文章发布状态" width="120" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch <el-switch v-auth="'内容管理:禁用'" class="off" v-model="scope.row.status" :active-value="0" :inactive-value="1"
v-auth="'内容管理:禁用'" style="margin: 0 5px" :active-text="scope.row.status ? '关' : '开'"
class="off" @change="switchOff($event, scope.row, scope.$index)"></el-switch>
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> <span>{{ scope.row.status ? "禁用" : "启用" }}</span>
</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="totals" @current-change="handleCurrentChange" :current-page="pageNo"> <el-pagination background layout="total, prev, pager, next" :total="totals"
@current-change="handleCurrentChange" :current-page="pageNo">
</el-pagination> </el-pagination>
</div> </div>
</div> </div>
@ -117,7 +112,7 @@ export default {
}, },
handleCurrentChange (val) { handleCurrentChange (val) {
this.pageNo = val; this.pageNo = val;
this.$router.push(`list?page=${val}`) this.$router.push(`/information?page=${val}`)
this.getData(); this.getData();
}, },
// //

@ -2,7 +2,8 @@
<!-- 内容管理 --> <!-- 内容管理 -->
<div class="flex"> <div class="flex">
<div class="menu-con"> <div class="menu-con">
<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> <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>
</div> </div>
<div class="right"> <div class="right">
<ContentList ref="content" v-show="menuList.length" :columnId="columnId" /> <ContentList ref="content" v-show="menuList.length" :columnId="columnId" />
@ -71,7 +72,8 @@ export default {
// //
if (JSON.stringify(list) !== JSON.stringify(originList)) { if (JSON.stringify(list) !== JSON.stringify(originList)) {
this.$confirm(`您已更改了文章排序,是否保存更改?`, '提示', { this.$confirm(`您已更改了文章排序,是否保存更改?`, '提示', {
type: 'warning' type: 'warning',
closeOnClickModal: false
}).then(() => { }).then(() => {
content.sortSubmit() content.sortSubmit()
this.setColumnId(key.id) this.setColumnId(key.id)
@ -91,16 +93,19 @@ export default {
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: #062c87;
} }
</style> </style>

@ -42,7 +42,8 @@ export default {
// //
if (JSON.stringify(list) !== JSON.stringify(originList)) { if (JSON.stringify(list) !== JSON.stringify(originList)) {
this.$confirm(`您已更改了${tab == 1 ? '栏目' : '文章'}排序,是否保存更改?`, '提示', { this.$confirm(`您已更改了${tab == 1 ? '栏目' : '文章'}排序,是否保存更改?`, '提示', {
type: 'warning' type: 'warning',
closeOnClickModal: false
}).then(() => { }).then(() => {
content.sortSubmit() content.sortSubmit()
fn(param) fn(param)
@ -68,22 +69,28 @@ export default {
.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, &.active {
color: #9278FF; &:hover,
&.active {
color: #062c87;
} }
} }
} }

@ -0,0 +1,251 @@
<template>
<div class="page">
<div style="margin-bottom: 10px;text-align: right;">
<el-button v-auth="'/shop:营销推广管理:新增'" type="primary" round @click="add">新增</el-button>
</div>
<el-table :data="list" class="table" ref="table" header-align="center" row-key="id">
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="courseName" label="图片" min-width="150" align="center">
<template slot-scope="scope">
<img width="100" :src="scope.row.banner" alt="">
</template>
</el-table-column>
<el-table-column prop="title" label="标题" min-width="150" align="center"></el-table-column>
<el-table-column prop="subheading" label="副标题" min-width="150" align="center"></el-table-column>
<el-table-column prop="url" label="链接" min-width="150" align="center"></el-table-column>
<el-table-column label="操作" align="center" width="250">
<template slot-scope="scope">
<el-switch v-model="scope.row.isOpen" :active-value="0" :inactive-value="1"
@change="switchOff($event, scope.row)" v-auth="'/shop:营销推广管理:禁用'">
</el-switch>
<el-button style="margin-left: 10px;" v-auth="'/shop:营销推广管理:编辑'" type="text"
@click="edit(scope.row)">编辑</el-button>
<el-button v-auth="'/shop:营销推广管理:删除'" type="text" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog :title="(form.id ? '编辑' : '新增') + 'banner'" :visible.sync="bannerVisible" width="500px" class="dialog"
:close-on-click-modal="false">
<el-form ref="form" label-width="60px">
<el-form-item label="图片">
<el-upload class="avatar-uploader" accept=".jpg,.png,.jpeg,.gif" :on-change="changeFile"
:show-file-list="false" action="" :auto-upload="false">
<img v-if="form.banner" :src="form.banner" class="avatar">
<div class="uploader-default" v-else>
<i class="el-icon-plus"></i>
<p>上传图片</p>
</div>
</el-upload>
</el-form-item>
<el-form-item label="标题">
<el-input v-model="form.title" placeholder="请输入标题" maxlength="100"></el-input>
</el-form-item>
<el-form-item label="副标题">
<el-input v-model="form.subheading" placeholder="请输入副标题" maxlength="100"></el-input>
</el-form-item>
<el-form-item label="链接">
<el-input v-model="form.url" placeholder="请输入链接" maxlength="100"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="bannerVisible = false">取消</el-button>
<el-button type="primary" @click="submitBanner">确定</el-button>
</span>
</el-dialog>
<!-- 剪裁组件弹窗 -->
<el-dialog title="图片裁剪" append-to-body :visible.sync="cropperModel" width="1100px" :close-on-click-modal="false">
<Cropper ref="cropper" :img-file.sync="file" :is-upload="isUpload" :fixed="true" :fixedNumber.sync="fixedNumber"
:autoCropWidth="500" :autoCropHeight="138.8" @upload="customUpload" />
</el-dialog>
</div>
</template>
<script>
import Util from "@/libs/util";
import Setting from '@/setting'
import Cropper from '@/components/img-upload/Cropper'
import Axios from 'axios'
import Oss from '@/components/upload/upload.js'
export default {
data () {
return {
headers: {
token: sessionStorage.getItem("token")
},
list: [],
bannerVisible: false,
form: {
id: '',
banner: '',
title: '',
subheading: '',
url: '',
},
cropperModel: false,
isUpload: false,
fixedNumber: [5.4, 1],
file: ''
};
},
components: {
Cropper
},
mounted () {
this.getList()
},
methods: {
getList () {
this.$post(this.api.listMarketing, {
pageNum: 1,
pageSize: 1000
}).then(({ page }) => {
this.list = page.records;
this.total = page.total;
}).catch(res => {
});
},
//
customUpload (data) {
data.name = this.file.name
this.imgUpload(data)
},
//
imgUpload (formData) {
this.isUpload = true
Oss.upload(formData).then(res => {
this.form.banner && Oss.del(this.form.banner)
this.form.banner = res.url
})
this.$refs.cropper.isDisabled = false
this.isUpload = false
this.cropperModel = false
},
//
changeFile (file) {
const { size, name } = file
const ext = name.substring(name.lastIndexOf('.') + 1)
if (!Util.isImg(ext)) {
this.$message.error('请上传图片!')
return false
}
this.file = file
this.cropperModel = true
this.$nextTick(() => {
this.$refs.cropper.updateImg({
url: window.URL.createObjectURL(file.raw),
size: file.size
})
})
},
add () {
this.form = {
id: '',
banner: '',
title: '',
subheading: '',
url: '',
}
this.bannerVisible = true
},
edit (row) {
this.form = JSON.parse(JSON.stringify(row))
this.bannerVisible = true
},
// banner
submitBanner () {
const { form } = this
if (!form.banner) return Util.errorMsg('请上传图片')
this.$post(this.api[form.id ? 'updateMarketing' : 'saveMarketing'], form).then(res => {
this.getList()
this.bannerVisible = false
}).catch(res => { })
},
handleDelete (row) {
this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", {
type: "warning"
})
.then(() => {
this.$post(`${this.api.delMarketing}?ids=${row.id}`).then(res => {
Util.successMsg("删除成功");
this.getList();
}).catch(res => {
});
})
.catch(() => {
});
},
switchOff (val, row) {
this.$post(`${this.api.bannerEnableOrDisable}?id=${row.id}&isDisable=${row.isOpen}`).then(res => { }).catch(err => { })
}
}
};
</script>
<style lang="scss" scoped>
.m-l-10 {
margin-left: 10px;
}
$avatar-width: 104px;
/deep/ .avatar-uploader {
.el-upload {
position: relative;
width: $avatar-width;
height: $avatar-width;
border: 1px dashed #d9d9d9;
border-radius: 2px;
cursor: pointer;
overflow: hidden;
&:hover {
border-color: #409eff;
}
.uploader-default {
display: flex;
flex-direction: column;
justify-content: center;
width: $avatar-width !important;
height: $avatar-width;
text-align: center;
background: rgba(0, 0, 0, 0.04);
i {
font-size: 20px;
font-weight: bold;
color: #8c939d;
}
p {
margin-top: 10px;
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
line-height: 1;
}
}
.avatar {
width: $avatar-width;
height: $avatar-width;
display: block;
}
}
.el-upload__tip {
margin-top: 0;
p {
font-size: 14px;
color: rgba(0, 0, 0, 0.45);
line-height: 1;
&:first-child {
margin-bottom: 5px;
}
}
}
}
</style>

@ -1,51 +1,33 @@
<template> <template>
<div> <div>
<el-card v-if="!id" <el-card v-if="!id" shadow="hover" class="m-b-20">
shadow="hover"
class="m-b-20">
<div class="flex-between"> <div class="flex-between">
<el-page-header @back="back" <el-page-header @back="back" :content="'创建赛事'"></el-page-header>
:content="'创建赛事'"></el-page-header>
</div> </div>
</el-card> </el-card>
<div v-if="step === 1 || (id && !editing)" <div v-if="step === 1 || (id && !editing)" :class="['type-wrap', { pd: !id }]">
:class="['type-wrap', {pd: !id}]">
<div class="p-title">大赛发布类型</div> <div class="p-title">大赛发布类型</div>
<el-form label-width="100px" <el-form label-width="100px" label-suffix=":" size="small" :disabled="!editing && id != ''">
label-suffix=":"
size="small"
:disabled="!editing && id != ''">
<el-form-item label="请选择类型"> <el-form-item label="请选择类型">
<el-radio v-model="releaseType" <el-radio v-for="(item, i) in releaseTypes" :key="i" v-model="releaseType" :label="item.id">{{ item.name
:label="0">仅发布信息</el-radio> }}</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" <el-button v-if="!editing && id" class="edit" type="primary" @click="editing = 1"
class="edit"
type="primary"
@click="editing = 1"
v-auth="'/match:管理:大赛详情:编辑'">编辑</el-button> v-auth="'/match:管理:大赛详情:编辑'">编辑</el-button>
</div> </div>
<el-card v-if="step !== 4" <el-card v-if="step !== 4" shadow="hover" class="m-b-20" style="position: relative;margin-top: 20px">
shadow="hover"
class="m-b-20"
style="position: relative;margin-top: 20px">
<ul :class="['steps', { pointer: !editing && id && publishStatus }]"> <ul :class="['steps', { pointer: !editing && id && publishStatus }]">
<li :class="{active: step === 1,done: step > 1}" <li :class="{ active: step === 1, done: step > 1 }" @click="toStep(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}" <li :class="{ active: step === 2, done: step > 2 }" @click="toStep(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}" <li :class="{ active: step === 3, done: step > 3 }" @click="toStep(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>
@ -58,43 +40,21 @@
</el-card> </el-card>
<div class="page"> <div class="page">
<div class="page-content"> <div class="page-content">
<step1 v-show="step === 1" <step1 v-show="step === 1" ref="step1" :editing.sync="editing" @next="next" />
ref="step1" <step2 v-if="step === 2" ref="step2" :editing.sync="editing" :setupId.sync="setupId" @next="next" />
:editing.sync="editing" <step3 v-if="step === 3" ref="step3" :editing.sync="editing" :setupId.sync="setupId"
@next="next" /> :competitionId.sync="competitionId" @next="next" />
<step2 v-if="step === 2" <step4 v-if="step === 4" ref="step4" />
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" <div v-if="step !== 4 && showBtns" class="btns">
class="btns">
<!-- 处于编辑状态(列表点编辑按钮进来默认是查看状态不可编辑点了编辑按钮才可编辑)或者新增才显示这几个按钮 --> <!-- 处于编辑状态(列表点编辑按钮进来默认是查看状态不可编辑点了编辑按钮才可编辑)或者新增才显示这几个按钮 -->
<template v-if="editing || !id"> <template v-if="editing || !id">
<el-button v-if="!publishStatus" <el-button v-if="!publishStatus" @click="save(0)">保存{{ releaseType ? '草稿' : '' }}</el-button>
@click="save(0)">保存{{ releaseType ? '草稿' : '' }}</el-button> <el-button v-if="step === 2 || step === 3" type="primary" @click="prev">上一步</el-button>
<el-button v-if="step === 2 || step === 3" <el-button v-if="!releaseType || (releaseType && step === 3)" type="primary" @click="save(1)">发布</el-button>
type="primary" <el-button v-else type="primary" @click="save(0, 2)">保存并下一步</el-button>
@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(0, 2)">保存并下一步</el-button>
</template> </template>
<el-button type="danger" <el-button type="danger" @click="preview" v-auth="'/match:管理:大赛详情:预览'">预览</el-button>
@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>
@ -123,6 +83,20 @@ export default {
updateTime: 0, updateTime: 0,
setupId: '', setupId: '',
releaseType: 0, releaseType: 0,
releaseTypes: [
{
id: 0,
name: '仅发布信息'
},
{
id: 1,
name: '设置完整比赛'
},
// {
// id: 2,
// name: ''
// },
],
editing: this.$route.query.id ? 0 : 1, editing: this.$route.query.id ? 0 : 1,
showBtns: true, showBtns: true,
loadIns: null loadIns: null
@ -165,7 +139,8 @@ 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(() => {
@ -178,7 +153,15 @@ export default {
// //
next (next, setupId, competitionId) { next (next, setupId, competitionId) {
if (!next) { if (!next) {
this.$router.push(`/match?page=${this.$store.state.matchPage}`) if (this.step === 3 && this.$refs['step' + this.step].form[0].contentId) {
// &&
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) {
@ -189,6 +172,12 @@ 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()
}
} }
}, },
// //
@ -208,7 +197,8 @@ 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(() => {
@ -218,7 +208,7 @@ export default {
this.editing = false this.editing = false
} }
} else { } else {
this.$router.push(`/match?page=${this.$store.state.matchPage}&platformSource=${this.$store.state.platformSource}`) this.backPage()
} }
}, },
back () { back () {
@ -226,7 +216,8 @@ 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(() => {
@ -237,7 +228,7 @@ export default {
} }
}, },
backPage () { backPage () {
this.$router.push(`/match?page=${this.$store.state.matchPage}&platformSource=${this.$store.state.platformSource}`) this.$router.push(this.$store.state.referrer || '/match')
} }
} }
}; };
@ -246,33 +237,41 @@ 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 { &.pd {
padding: 15px; 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; justify-content: center;
&.pointer { &.pointer {
li { li {
cursor: pointer; cursor: pointer;
} }
} }
li { li {
position: relative; position: relative;
margin-right: 100px; margin-right: 100px;
text-align: center; text-align: center;
} }
.circle { .circle {
display: inline-flex; display: inline-flex;
justify-content: center; justify-content: center;
@ -285,6 +284,7 @@ export default {
background: #f9f9f9; background: #f9f9f9;
border: 5px solid #e1e1e1; border: 5px solid #e1e1e1;
border-radius: 50%; border-radius: 50%;
&:after { &:after {
content: ''; content: '';
position: absolute; position: absolute;
@ -294,37 +294,45 @@ export default {
background: #e1e1e1; background: #e1e1e1;
} }
} }
.active { .active {
.circle { .circle {
color: #fff; color: #fff;
border-color: #459ffb; border-color: #26499f;
background: #007eff; background: #062c87;
} }
.text { .text {
color: #007eff; color: #062c87;
} }
} }
.done { .done {
.circle { .circle {
color: #fff; color: #fff;
background: #9c86ff; background: #062c87;
border-color: #bbacff; border-color: #26499f;
&:after { &:after {
background: #bbacff; background: #062c87;
} }
} }
.text { .text {
color: #9178ff; color: #062c87;
} }
} }
.circle2:after { .circle2:after {
left: 71px; left: 71px;
width: 147px; width: 147px;
} }
.circle4:after { .circle4:after {
display: none; display: none;
} }
} }
.btns { .btns {
text-align: center; text-align: center;
} }

@ -1,103 +1,141 @@
<template> <template>
<div> <div>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<div> <div>
<p class="m-b-20">比赛名称</p> <p class="m-b-20">比赛名称</p>
{{ form.stageName }} {{ form.stageName }}
</div> </div>
</el-card> </el-card>
<el-card shadow="hover" <el-card shadow="hover" class="m-b-20">
class="m-b-20">
<div> <div>
<p class="m-b-20">比赛时间</p> <p class="m-b-20">比赛时间</p>
<div class="date-inputs"> <div class="date-inputs">
起止时间 起止时间
<div style="display: inline-flex;align-items: center;"> <div style="display: inline-flex;align-items: center;">
<el-date-picker v-model="form.time" <el-date-picker v-model="form.time" type="datetimerange" range-separator="~" start-placeholder="开始日期"
type="datetimerange" end-placeholder="结束日期" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
range-separator="~"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
@change="timeChange"> @change="timeChange">
</el-date-picker> </el-date-picker>
<el-alert style="width: auto;padding: 4px 16px;margin-left: 10px;" <el-alert style="width: auto;padding: 4px 16px;margin-left: 10px;"
:title="'(请设置在 ' + step1.playStartTime + ' ~ ' + step1.playEndTime + '间)'" :title="'(请设置在 ' + step1.playStartTime + ' ~ ' + step1.playEndTime + '间)'" type="error" :closable="false"
type="error"
:closable="false"
effect="dark"> effect="dark">
</el-alert> </el-alert>
</div> </div>
</div> </div>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover"
class="mgr20 m-b-20"> <!-- 理论系统选择试卷库非理论则选择系统 -->
<el-card shadow="hover" class="m-b-20">
<div> <div>
<p class="m-b-20">课程</p> <el-radio-group class="m-b-20" v-model="courseSystem" @change="courseSystemChange">
<el-radio :label="0">从课程中选择</el-radio>
<el-radio :label="1">从系统中选择</el-radio>
</el-radio-group>
<div class="inline-input"> <div class="inline-input">
<el-cascader ref="cur" <!-- 选择系统 -->
v-model="mallIds" <el-select v-if="courseSystem" v-model="systemId" placeholder="请选择系统" @change="getProject">
:options="curs" <el-option v-for="(item, i) in services" :key="i" :label="item.systemName" :value="item.systemId">
:props="{ checkStrictly: true, value: 'id' }" </el-option>
popper-class="course-cas" </el-select>
@expand-change="curChange"
<template v-else>
<!-- 理论 && 选择课程 -->
<el-select v-if="isTheory && !courseSystem" v-model="libraryId" placeholder="请选择试卷库" @change="getProject">
<el-option v-for="(item, i) in paperLibraries" :key="i" :label="item.libraryName" :value="item.libraryId">
</el-option>
</el-select>
<!-- 实训 && 选择课程 -->
<el-cascader v-else-if="!isTheory && !courseSystem" ref="cur" v-model="mallIds" :options="curs"
:props="{ checkStrictly: true, value: 'id' }" popper-class="course-cas" @expand-change="curChange"
@change="curChange"></el-cascader> @change="curChange"></el-cascader>
</template>
</div> </div>
</div> </div>
</el-card> </el-card>
<el-card shadow="hover"
class="m-b-20"> <!-- 理论系统 -->
<el-card v-if="isTheory" 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" 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>
<el-card v-else shadow="hover" class="m-b-20">
<div class="flex-between m-b-20"> <div class="flex-between m-b-20">
<span>实训项目</span> <span>实训项目</span>
<div style="display: inline-flex;"> <div style="display: inline-flex;">
<div> <div>
<el-input placeholder="请输入项目名称" <el-input placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model.trim="keyword" clearable></el-input>
prefix-icon="el-icon-search"
v-model.trim="keyword"
clearable></el-input>
</div> </div>
<el-button style="margin-left: 5px" <el-button style="margin-left: 5px" type="primary" round @click="toProject">自定义实验项目</el-button>
type="primary"
round
@click="toProject">自定义实验项目</el-button>
</div> </div>
</div> </div>
<!-- 实训项目表格 --> <!-- 实训项目表格 -->
<el-table :data="projects" <el-table :data="projects" class="table" header-align="center">
class="table" <el-table-column width="60" label="选择" align="center">
stripe
header-align="center">
<el-table-column width="60"
label="选择"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-radio v-model="form.projectId" <el-radio v-model="form.projectId" :label="scope.row.projectId">&nbsp;</el-radio>
:label="scope.row.projectId">&nbsp;</el-radio>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="projectName" <el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
label="项目名称" <el-table-column prop="auth" label="项目权限" align="center">
align="center"></el-table-column>
<el-table-column prop="auth"
label="项目权限"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ permissionsKeys[scope.row.permissions] }} {{ permissionsKeys[scope.row.permissions] }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="founder" <el-table-column prop="founder" label="创建人" align="center">
label="创建人"
align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.founder ? '老师创建' : '系统内置' }} {{ scope.row.founder ? '老师创建' : '系统内置' }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" <el-table-column prop="createTime" label="创建时间" align="center"></el-table-column>
label="创建时间"
align="center"></el-table-column>
<!-- <el-table-column label="操作" align="center"> <!-- <el-table-column label="操作" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click="showProject(scope.row)">查看</el-button> <el-button type="text" @click="showProject(scope.row)">查看</el-button>
@ -105,42 +143,54 @@
</el-table-column> --> </el-table-column> -->
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background <el-pagination background :page-size="pageSize" @current-change="handleCurrentChange"
:page-size="pageSize" layout="total,prev, pager, next" :total="total"></el-pagination>
@current-change="handleCurrentChange"
layout="total,prev, pager, next"
:total="total"></el-pagination>
</div> </div>
</el-card> </el-card>
<div style="text-align: center"> <div style="text-align: center">
<el-button @click="back">返回</el-button> <el-button @click="back">返回</el-button>
<el-button type="primary" <el-button type="primary" @click="save">保存</el-button>
@click="save">保存</el-button>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import 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: [],
systemId: '',
curs: [], curs: [],
paperLibraries: [],
services: [],
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,
courseSystem: 1,
}; };
}, },
computed: {
//
isTheory () {
return this.form.method === 1
},
},
watch: { watch: {
// , // ,
form: { form: {
@ -152,22 +202,27 @@ export default {
keyword: function (val) { keyword: function (val) {
clearTimeout(this.searchTimer); clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => { this.searchTimer = setTimeout(() => {
this.initData(); this.initData()
}, 500); }, 500)
} }
}, },
mounted () { mounted () {
this.getCourse() // this.isTheory ? this.getLibrary() : this.getCourse()
this.getSystem()
}, },
methods: { methods: {
// //
async getCourse () { async getCourse () {
const sid = this.$store.state.dataPer.find(e => e.permissionName === '服务配置') const sid = this.$store.state.dataPer.find(e => e.permissionName === '服务配置')
const { serviceList } = await this.$post(this.api.queryServiceConfig, { //
const res = await this.$post(this.api.queryServiceConfig, {
pageNum: 1, pageNum: 1,
pageSize: 1000, pageSize: 1000,
supplierId: sid ? sid.supplierId : '' supplierId: sid ? sid.supplierId : ''
}) })
const services = res.serviceList.records
//
const { page } = await this.$post(this.api.listOfGoods, { const { page } = await this.$post(this.api.listOfGoods, {
pageNum: 1, pageNum: 1,
pageSize: 10000, pageSize: 10000,
@ -179,14 +234,14 @@ export default {
const { records } = page const { records } = page
const { mallId, cid, systemId } = this.form const { mallId, cid, systemId } = this.form
if (records.length) { if (records.length) {
serviceList.records.map(e => { services.map(e => {
e.id = +e.systemId e.id = +e.systemId
e.label = e.systemName e.label = e.systemName
}) })
records.map(e => { records.map(e => {
e.id = +e.mallId e.id = +e.mallId
e.label = e.productName e.label = e.productName
e.children = serviceList.records.filter(n => e.systemId.split(',').includes(n.systemId)) // e.children = services.filter(n => e.systemId && e.systemId.split(',').includes(n.systemId)) //
}) })
this.curs = records this.curs = records
@ -201,6 +256,27 @@ export default {
this.getProject() this.getProject()
} }
}, },
//
async getSystem () {
const res = await this.$get(this.api.getServiceOfType, {
type: this.isTheory ? 3 : 1
})
res.serviceList.forEach(e => e.systemId = +e.systemId)
this.services = res.serviceList
if (this.services.length) {
this.systemId = this.form.systemId || this.services[0].systemId
this.getProject()
this.loadIns = Loading.service()
}
},
//
courseSystemChange (val) {
if (val) {
this.getSystem()
} else {
this.isTheory ? this.getLibrary() : this.getCourse()
}
},
// //
curChange (val) { curChange (val) {
const id = val[0] const id = val[0]
@ -216,31 +292,77 @@ export default {
this.loadIns = Loading.service() this.loadIns = Loading.service()
this.getProject() this.getProject()
}, },
//
async getLibrary () {
try {
const res = await this.$post(this.api.libraryList, {
pageNum: 1,
pageSize: 10000,
type: 1,
isDisable: 0,
})
const { records } = res.pageList
if (records.length) {
this.paperLibraries = records
this.libraryId = records[0].libraryId
this.loadIns = Loading.service()
this.getProject()
}
} finally { }
},
// // /
getProject () { async getProject () {
this.$post(this.api.getProjectAssessmentByCompetition, { try {
//
if (this.courseSystem) {
const res = await this.$get(`${this.api.getInternalProjectBySystemId}?permissions=2&systemId=${this.systemId}&keyword=${this.keyword}`)
if (this.isTheory) {
res.forEach(e => {
e.name = e.paperName
})
}
this.projects = res
}
else {
if (this.isTheory) {
//
const res = await this.$post(this.api.examPaperList, {
pageNum: this.page,
pageSize: this.pageSize,
type: 1,
keyWord: this.keyword,
libraryId: this.libraryId,
isDisable: 0,
status: 1
})
this.projects = res.pageList.records
this.total = res.pageList.total
} else { //
//
const { data } = await this.$post(this.api.getProjectAssessmentByCompetition, {
pageNum: this.page, pageNum: this.page,
pageSize: this.pageSize, pageSize: this.pageSize,
cid: this.form.cid, cid: this.form.cid,
projectName: this.keyword, projectName: this.keyword,
systemId: this.sysId, systemId: this.sysId,
permissions: 2 permissions: 2,
}).then(({ data }) => { })
this.projects = data.records this.projects = data.records
this.total = data.total this.total = data.total
}
}
} finally {
this.loadIns.close() this.loadIns.close()
}).catch(err => { }
this.loadIns.close()
});
}, },
initData () { initData () {
this.page = 1; this.page = 1
this.getProject(); this.getProject()
}, },
handleCurrentChange (val) { handleCurrentChange (val) {
this.page = val; this.page = val
this.getProject(); this.getProject()
}, },
// //
toProject () { toProject () {
@ -250,7 +372,17 @@ export default {
form, form,
curStep curStep
}) })
this.$router.push(`/projectList?systemId=${this.mallIds[1]}&show=1&name=${this.$refs.cur.getCheckedNodes()[0].label}`) let { systemId } = this
let name
if (systemId) {
const cur = this.services.find(e => e.systemId === systemId)
if (cur) name = cur.systemName
}
if (!this.courseSystem && this.mallIds.length > 1) {
systemId = this.mallIds[1]
name = this.$refs.cur.getCheckedNodes()[0].label
}
this.$router.push(`/projectList?systemId=${systemId}&custom=1&name=${name}`)
}, },
// //
timeChange (val) { timeChange (val) {
@ -260,7 +392,7 @@ export default {
const { playStartTime, playEndTime } = this.step1 const { playStartTime, playEndTime } = this.step1
if (startTime < new Date(playStartTime) || endTime > new Date(playEndTime)) { if (startTime < new Date(playStartTime) || endTime > new Date(playEndTime)) {
this.timeInvalid = true this.timeInvalid = true
return util.warningMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。') return Util.warningMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。')
} }
this.timeInvalid = false this.timeInvalid = false
const { form, curStep } = this.$parent const { form, curStep } = this.$parent
@ -270,36 +402,74 @@ 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
} }
} }
} }
} }
}, },
//
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, courseSystem } = 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 (!form.projectId) return util.warningMsg('请选择项目') if (this.isTheory) {
// if (!this.libraryId) return Util.warningMsg('')
if (!form.paperId) return Util.warningMsg('请选择试卷')
form.libraryId = courseSystem ? '' : this.libraryId
form.systemId = courseSystem ? this.systemId : ''
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) const { systemId, systemName, projectName } = this.projects.find(e => e.projectId == form.projectId)
if (systemId) form.systemId = systemId if (systemId) form.systemId = systemId
if (projectName) form.projectName = projectName if (projectName) form.projectName = projectName
if (systemName) form.systemName = systemName if (systemName) form.systemName = systemName
}
if (courseSystem) {
form.mallId = ''
form.cid = ''
}
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 (this.isTheory && 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 scoped lang="scss"></style>
</style>

@ -3,81 +3,48 @@
<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 label-width="170px" <el-form label-width="170px" label-suffix=":" size="small" :disabled="!editing && form.id !== ''">
label-suffix=":"
size="small"
:disabled="!editing && form.id !== ''">
<el-form-item label="竞赛封面(选填)"> <el-form-item label="竞赛封面(选填)">
<el-upload class="avatar-uploader" <el-upload class="avatar-uploader" accept=".jpg,.png,.jpeg,.gif" :on-remove="handleRemove"
accept=".jpg,.png,.jpeg,.gif" :on-error="uploadError" :before-remove="beforeRemove" :limit="1" :on-exceed="handleExceed" action=""
:on-remove="handleRemove"
:on-error="uploadError"
:before-remove="beforeRemove"
:limit="1"
:on-exceed="handleExceed"
action=""
:http-request="handleRequest"> :http-request="handleRequest">
<img v-if="form.coverUrl" <img v-if="form.coverUrl" :src="form.coverUrl" class="avatar">
:src="form.coverUrl" <div class="uploader-default" v-else>
class="avatar">
<div class="uploader-default"
v-else>
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
<p>上传封面</p> <p>上传封面</p>
</div> </div>
<div slot="tip" <div slot="tip" class="el-upload__tip">
class="el-upload__tip">
<p>展示宽度为220高度140JPG/PNG/GIF3MB以内</p> <p>展示宽度为220高度140JPG/PNG/GIF3MB以内</p>
</div> </div>
</el-upload> </el-upload>
</el-form-item> </el-form-item>
<el-form-item label="竞赛封面长图(选填)"> <el-form-item label="竞赛封面长图(选填)">
<el-upload class="avatar-uploader avatar-uploader-lg" <el-upload class="avatar-uploader avatar-uploader-lg" accept=".jpg,.png,.jpeg,.gif"
accept=".jpg,.png,.jpeg,.gif" :on-remove="handleLgRemove" :on-error="uploadError" :before-remove="beforeRemove" :limit="1"
:on-remove="handleLgRemove" :on-exceed="handleExceed" action="" :http-request="handleRequestLg">
:on-error="uploadError" <img v-if="form.carouselUrl" :src="form.carouselUrl" class="avatar-lg">
:before-remove="beforeRemove" <div class="uploader-default" v-else>
:limit="1"
:on-exceed="handleExceed"
action=""
:http-request="handleRequestLg">
<img v-if="form.carouselUrl"
:src="form.carouselUrl"
class="avatar-lg">
<div class="uploader-default"
v-else>
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
<p>上传封面</p> <p>上传封面</p>
</div> </div>
<div slot="tip" <div slot="tip" class="el-upload__tip">
class="el-upload__tip">
<p>展示宽度为1920高度300JPG/PNG/GIF3MB以内</p> <p>展示宽度为1920高度300JPG/PNG/GIF3MB以内</p>
</div> </div>
</el-upload> </el-upload>
</el-form-item> </el-form-item>
<el-form-item class="req" <el-form-item class="req" label="竞赛名称">
label="竞赛名称">
<div class="d-inline-block"> <div class="d-inline-block">
<el-input placeholder="请输入竞赛名称" <el-input placeholder="请输入竞赛名称" v-model="form.name" clearable></el-input>
v-model="form.name"
clearable></el-input>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item class="req"
label="主办方"> <template v-if="!isPractice">
<el-form-item class="req" label="主办方">
<div class="inline-input"> <div class="inline-input">
<div class="input-wrap" <div class="input-wrap" v-for="(item, index) in sponsorList" :key="index">
v-for="(item,index) in sponsorList" <el-input placeholder="主办方名称" v-model="sponsorList[index]"></el-input>
:key="index"> <i v-if="sponsorList.length > 1" class="remove" @click="delSponsor(index)"></i>
<el-input placeholder="主办方名称" <button v-if="index == 0" class="add-btn" type="button" :disabled="!editing && form.id !== ''"
v-model="sponsorList[index]"></el-input>
<i v-if="sponsorList.length > 1"
class="remove"
@click="delSponsor(index)"></i>
<button v-if="index == 0"
class="add-btn"
type="button"
:disabled="!editing && form.id !== ''"
@click="addSponsor"> @click="addSponsor">
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
<span>添加</span> <span>添加</span>
@ -87,187 +54,169 @@
</el-form-item> </el-form-item>
<el-form-item label="承办方(选填)"> <el-form-item label="承办方(选填)">
<div class="inline-input"> <div class="inline-input">
<div class="input-wrap" <div class="input-wrap" v-for="(item, index) in undertakerList" :key="index">
v-for="(item,index) in undertakerList" <el-input placeholder="承办方名称" v-model="undertakerList[index]"></el-input>
:key="index"> <i v-if="undertakerList.length > 1" class="remove" @click="delOrganizer(index)"></i>
<el-input placeholder="承办方名称" <button v-if="index == 0" class="add-btn" type="button" :disabled="!editing && form.id !== ''"
v-model="undertakerList[index]"></el-input>
<i v-if="undertakerList.length > 1"
class="remove"
@click="delOrganizer(index)"></i>
<button v-if="index == 0"
class="add-btn"
type="button"
:disabled="!editing && form.id !== ''"
@click="addOrganizer"> @click="addOrganizer">
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
<span>添加</span> <span>添加</span>
</button> </button>
</div> </div>
</div> </div>
<button v-if="!undertakerList.length" <button v-if="!undertakerList.length" class="add-btn" type="button" @click="addOrganizer">
class="add-btn"
type="button"
@click="addOrganizer">
<i class="el-icon-plus"></i> <i class="el-icon-plus"></i>
<span>添加</span> <span>添加</span>
</button> </button>
</el-form-item> </el-form-item>
<el-form-item class="req" <el-form-item class="req" label="报名时间">
label="报名时间"> <el-date-picker v-model="signupTime" value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange"
<el-date-picker v-model="signupTime" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
value-format="yyyy-MM-dd HH:mm:ss"
type="datetimerange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:picker-options="pickerOptions"></el-date-picker> :picker-options="pickerOptions"></el-date-picker>
</el-form-item> </el-form-item>
<el-form-item class="req" </template>
label="竞赛时间"> <el-form-item class="req" label="竞赛时间">
<el-date-picker v-model="playTime" <el-date-picker v-model="playTime" value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange"
value-format="yyyy-MM-dd HH:mm:ss" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
type="datetimerange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
:picker-options="pickerOptions"></el-date-picker> :picker-options="pickerOptions"></el-date-picker>
</el-form-item> </el-form-item>
<el-form-item class="req" <el-form-item class="req" label="比赛范围">
label="比赛范围">
<div v-if="form.id"> <div v-if="form.id">
<el-radio v-model="form.competitionScope" <el-radio v-model="form.competitionScope" :label="0" disabled>本校内</el-radio>
:label="0"
disabled>本校内</el-radio>
</div> </div>
<div> <div>
<el-radio v-model="form.competitionScope" <el-radio v-model="form.competitionScope" :label="1">全平台</el-radio>
:label="1">全平台</el-radio>
</div> </div>
<div> <div>
<el-radio v-model="form.competitionScope" <el-radio v-model="form.competitionScope" :label="2">指定区域院校</el-radio>
:label="2">指定区域院校</el-radio> <template v-if="form.competitionScope === 2">
<el-button v-if="form.competitionScope === 2" <el-button type="primary" size="mini" @click="showRange">选择院校</el-button>
type="primary"
size="mini"
@click="showRange">选择院校</el-button>
<span style="margin-left: 20px">{{ rangeName }}</span> <span style="margin-left: 20px">{{ rangeName }}</span>
</template>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item class="req" <template v-if="!isPractice">
label="竞赛类型"> <el-form-item class="req" label="竞赛类型">
<el-radio v-model="form.completeCompetitionSetup.competitionType" <el-radio v-model="form.completeCompetitionSetup.competitionType" :label="0">个人赛</el-radio>
:label="0">个人赛</el-radio> <el-radio v-model="form.completeCompetitionSetup.competitionType" :label="1">团队赛</el-radio>
<el-radio v-model="form.completeCompetitionSetup.competitionType"
:label="1">团队赛</el-radio>
</el-form-item> </el-form-item>
<el-form-item class="req" <el-form-item class="req" v-if="!form.completeCompetitionSetup.competitionType" label="报名人数上限">
v-if="!form.completeCompetitionSetup.competitionType"
label="报名人数上限">
<div class="input-center"> <div class="input-center">
<el-input placeholder="请输入人数" <el-input placeholder="请输入人数" v-model.number="form.completeCompetitionSetup.quantityLimit"
v-model.number="form.completeCompetitionSetup.quantityLimit" type="number"></el-input>
type="number"></el-input>
</div> </div>
</el-form-item> </el-form-item>
<template v-if="form.completeCompetitionSetup.competitionType"> <template v-if="form.completeCompetitionSetup.competitionType">
<el-form-item class="req" <el-form-item class="req" label="报名团队数上限">
label="报名团队数上限">
<div class="input-center"> <div class="input-center">
<el-input placeholder="请输入团队数" <el-input placeholder="请输入团队数" v-model.number="form.completeCompetitionSetup.quantityLimit"
v-model.number="form.completeCompetitionSetup.quantityLimit"
type="number"></el-input> type="number"></el-input>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item class="req" <el-form-item class="req" label="团队人数">
label="团队人数"> <div class="input-center" style="width: 250px;">
<div class="input-center" <el-input v-model.number="form.completeCompetitionSetup.minTeamSize" type="number"></el-input>
style="width: 250px;"> <el-input style="margin-left: 5px;" v-model.number="form.completeCompetitionSetup.maxTeamSize"
<el-input v-model.number="form.completeCompetitionSetup.minTeamSize"
type="number"></el-input>
<el-input style="margin-left: 5px;"
v-model.number="form.completeCompetitionSetup.maxTeamSize"
type="number"></el-input> / type="number"></el-input> /
</div> </div>
</el-form-item> </el-form-item>
</template> </template>
<el-form-item class="req" <el-form-item class="req" label="报名邀请码">
label="报名邀请码"> <div class="input-center" style="width: 550px;">
<div class="input-center" <el-radio v-model="form.completeCompetitionSetup.isNeedCode" :label="0">不需要</el-radio>
style="width: 550px;"> <el-radio v-model="form.completeCompetitionSetup.isNeedCode" :label="1">需要</el-radio>
<el-radio v-model="form.completeCompetitionSetup.isNeedCode" <el-input style="width: 250px" placeholder="请输入4位邀请码或点击随机生成"
:label="0">不需要</el-radio>
<el-radio v-model="form.completeCompetitionSetup.isNeedCode"
:label="1">需要</el-radio>
<el-input style="width: 250px"
placeholder="请输入4位邀请码或点击随机生成"
v-model="form.completeCompetitionSetup.invitationCode" v-model="form.completeCompetitionSetup.invitationCode"
:disabled="form.completeCompetitionSetup.isNeedCode === 0"></el-input> :disabled="form.completeCompetitionSetup.isNeedCode === 0"></el-input>
<el-button v-if="form.completeCompetitionSetup.isNeedCode === 1" <el-button v-if="form.completeCompetitionSetup.isNeedCode === 1" @click="randomInv">随机</el-button>
@click="randomInv">随机</el-button>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item class="req" </template>
label="竞赛详情"> <el-form-item class="req" label="竞赛详情">
<quill v-if="quillShow" <quill v-if="quillShow" :border="true" v-model="form.description" :height="400"
:border="true"
v-model="form.description"
:height="400"
:readonly="!editing && form.id !== ''" /> :readonly="!editing && form.id !== ''" />
</el-form-item> </el-form-item>
<el-form-item label="附件"> <el-form-item label="附件">
<Upload :limit="5" <Upload :limit="5" :file-list.sync="fileList" :on-remove="handleAnnexRemove"
:file-list.sync="fileList"
:on-remove="handleAnnexRemove"
@onSuccess="uploadAnnexSuccess" /> @onSuccess="uploadAnnexSuccess" />
</el-form-item> </el-form-item>
<template v-if="isPractice">
<el-form-item label="比赛方式">
<el-radio-group v-model="form.type">
<el-radio :label="0">实训</el-radio>
<el-radio :label="1">理论</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="比赛内容">
<el-button style="margin-bottom: 10px;" size="small" type="primary">选择理论试卷</el-button>
<el-table :data="list" class="table" ref="table" header-align="center" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
<el-table-column prop="name" label="试卷名称" align="center" min-width="100"></el-table-column>
<el-table-column prop="questionCount" label="试题总数" align="center" width="70"></el-table-column>
<el-table-column prop="score" label="总分" align="center" width="60"></el-table-column>
<el-table-column prop="questionType" label="题型" align="center" min-width="90"
show-overflow-tooltip></el-table-column>
<el-table-column prop="difficult" label="试卷难度" align="center" width="100" sortable="custom">
<!-- <template slot-scope="scope">{{ difficults.find(e => e.id === scope.row.difficult) ? difficults.find(e
=>
e.id === scope.row.difficult).name : '' }}</template> -->
</el-table-column>
<el-table-column prop="suggestTime" label="建议用时" align="center" width="70">
<template slot-scope="scope">{{ scope.row.suggestTime }}min</template>
</el-table-column>
<el-table-column prop="classificationPath" label="试卷分类" align="center" width="90"
show-overflow-tooltip></el-table-column>
<el-table-column label="建议用途" align="center" width="70">
<!-- <template slot-scope="scope">{{ paperTypes.find(e => e.id === scope.row.paperType) ? paperTypes.find(e
=>
e.id === scope.row.paperType).name : '' }}</template> -->
</el-table-column>
<el-table-column prop="updateTime" label="最近编辑时间" align="center" width="160"
sortable="custom"></el-table-column>
<el-table-column prop="createUser" label="最近编辑人" align="center" width="90"></el-table-column>
<el-table-column label="操作" align="center" width="240">
<template slot-scope="scope">
<el-button type="text" @click="toDetail(scope.row, 1)">复制</el-button>
<!-- <el-button type="text" @click="edit(scope.row)">预览</el-button> -->
<el-button type="text" @click="toDetail(scope.row)">编辑</el-button>
<el-button type="text" @click="del(scope.row)">删除</el-button>
<el-switch v-if="!scope.row.status" v-model="scope.row.isDisable" :active-value="false"
:inactive-value="true" style="margin: 0 10px 0 5px" :active-text="scope.row.isDisable ? '关' : '开'"
@change="switchOff($event, scope.row, scope.$index)"></el-switch>
</template>
</el-table-column>
</el-table>
</el-form-item>
</template>
</el-form> </el-form>
</div> </div>
</div> </div>
<el-dialog title="请勾选院校" <el-dialog title="请勾选院校" :visible.sync="rangeVisible" width="580px" custom-class="range-dia"
:visible.sync="rangeVisible"
width="580px"
custom-class="range-dia"
:close-on-click-modal="false"> :close-on-click-modal="false">
<div class="range-wrap"> <div class="range-wrap">
<el-cascader ref="range" <el-cascader ref="range" class="range-cas" key="range" v-model="range" :props="props" :show-all-levels="false"
class="range-cas" clearable filterable :before-filter="beforeFilter" :options="rangeList" @change="rangeChange"
key="range" @visible-change="rangeViChange" @input.native="rangeSearch"></el-cascader>
v-model="range" <el-tag v-for="(tag, i) in rangeChecked" :key="tag.value" class="range-check" closable
:props="props" :disable-transitions="false" @close="val => closeRange(i)">
:show-all-levels="false"
clearable
filterable
:before-filter="beforeFilter"
:options="rangeList"
@change="rangeChange"
@visible-change="rangeViChange"
@input.native="rangeSearch"></el-cascader>
<el-tag v-for="(tag, i) in rangeChecked"
:key="tag.value"
class="range-check"
closable
:disable-transitions="false"
@close="val => closeRange(i)">
{{ tag.label }} {{ tag.label }}
</el-tag> </el-tag>
</div> </div>
<span slot="footer" <span slot="footer" class="dialog-footer">
class="dialog-footer"> <el-button size="small" @click="rangeVisible = false"> </el-button>
<el-button size="small" <el-button size="small" type="primary" @click="rangeSubmit"> </el-button>
@click="rangeVisible = false"> </el-button>
<el-button size="small"
type="primary"
@click="rangeSubmit"> </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 quill from "@/components/quill"; import quill from "@/components/quill";
import Upload from '@/components/upload'; import Upload from '@/components/upload';
import Oss from '@/components/upload/upload.js' import Oss from '@/components/upload/upload.js'
@ -391,13 +340,19 @@ export default {
}, },
submiting: false, submiting: false,
updateTime: 0, updateTime: 0,
quillShow: true quillShow: true,
originSignUpEndTime: '',
}; };
}, },
components: { components: {
quill, quill,
Upload Upload
}, },
computed: {
isPractice () {
return this.$parent.releaseType === 2
},
},
watch: { watch: {
editing: function (val) { editing: function (val) {
this.quillShow = false this.quillShow = false
@ -439,7 +394,7 @@ export default {
}, },
methods: { methods: {
getData () { getData () {
const { id } = this.form const { id } = this.$route.query
id && this.$post(`${this.api.getCompetition}?competitionId=${id}`).then(({ competition }) => { id && this.$post(`${this.api.getCompetition}?competitionId=${id}`).then(({ competition }) => {
this.$parent.publishStatus = competition.publishStatus this.$parent.publishStatus = competition.publishStatus
this.$parent.releaseType = competition.releaseType this.$parent.releaseType = competition.releaseType
@ -487,6 +442,7 @@ export default {
}) })
this.rangeName = range.join(',') this.rangeName = range.join(',')
} }
this.originSignUpEndTime = competition.signUpEndTime
this.form = competition this.form = competition
this.$parent.resumeData() this.$parent.resumeData()
this.$nextTick(() => { this.$nextTick(() => {
@ -564,7 +520,7 @@ export default {
provinceId: e.provinceId || '', provinceId: e.provinceId || '',
cityId: e.cityId || '', cityId: e.cityId || '',
schoolId: e.schoolId || '', schoolId: e.schoolId || '',
type: e.schoolId ? 0 : 1 type: e.schoolId ? 0 : (e.cityId ? 1 : 2)
}) })
}) })
this.form.competitionRangeList = data this.form.competitionRangeList = data
@ -579,7 +535,7 @@ export default {
this.rangeVisible = false this.rangeVisible = false
}, },
handleExceed (files, fileList) { handleExceed (files, fileList) {
util.warningMsg(`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`); Util.warningMsg(`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`);
}, },
// //
async handleRequest ({ file }) { async handleRequest ({ file }) {
@ -646,47 +602,49 @@ export default {
const form = JSON.parse(JSON.stringify(this.form)) const form = JSON.parse(JSON.stringify(this.form))
form.sponsor = this.sponsorList.filter(d => d).join(); form.sponsor = this.sponsorList.filter(d => d).join();
form.undertaker = this.undertakerList.filter(d => d).join(); form.undertaker = this.undertakerList.filter(d => d).join();
if (!form.name) return util.warningMsg("请填写竞赛名称"); if (!form.name) return Util.warningMsg("请填写竞赛名称");
// //
if (next === 2) { if (next === 2) {
if (form.competitionScope == 2 && (!form.competitionRangeList || !form.competitionRangeList.length)) return util.warningMsg('请选择区域、院校') if (form.competitionScope == 2 && (!form.competitionRangeList || !form.competitionRangeList.length)) return Util.warningMsg('请选择区域、院校')
if (!form.sponsor) return util.warningMsg("请填写主办方"); if (!form.sponsor) return Util.warningMsg("请填写主办方");
if (!form.signUpStartTime) return util.warningMsg("请选择报名时间"); if (!form.signUpStartTime) return Util.warningMsg("请选择报名时间");
let now = new Date().getTime(); let now = new Date().getTime();
let signUpStartTime = new Date(form.signUpStartTime).getTime(); let signUpStartTime = new Date(form.signUpStartTime).getTime();
let signUpEndTime = new Date(form.signUpEndTime).getTime(); let signUpEndTime = new Date(form.signUpEndTime).getTime();
let playStartTime = new Date(form.playStartTime).getTime(); let playStartTime = new Date(form.playStartTime).getTime();
if (!form.playStartTime) return util.warningMsg("请选择竞赛时间"); if (!form.playStartTime) return Util.warningMsg("请选择竞赛时间");
if (playStartTime && signUpEndTime && playStartTime < signUpEndTime) return util.warningMsg("竞赛时间不能早于报名结束时间"); if (playStartTime && signUpEndTime && playStartTime < signUpEndTime) return Util.warningMsg("竞赛时间不能早于报名结束时间");
const { competitionType, quantityLimit, minTeamSize, maxTeamSize, isNeedCode, invitationCode } = form.completeCompetitionSetup const { competitionType, quantityLimit, minTeamSize, maxTeamSize, isNeedCode, invitationCode } = form.completeCompetitionSetup
// //
if (competitionType) { if (competitionType) {
if (quantityLimit === '') return util.warningMsg('请填写报名团队数上限') if (quantityLimit === '') return Util.warningMsg('请填写报名团队数上限')
if (quantityLimit < 0) return util.warningMsg('报名团队数上限不得小于0') if (quantityLimit < 0) return Util.warningMsg('报名团队数上限不得小于0')
if (minTeamSize === '') return util.warningMsg('请填写团队人数下限') if (minTeamSize === '') return Util.warningMsg('请填写团队人数下限')
if (minTeamSize < 2) return util.warningMsg('团队人数下限不得小于2') if (minTeamSize < 2) return Util.warningMsg('团队人数下限不得小于2')
if (maxTeamSize === '') return util.warningMsg('请填写团队人数上限') if (maxTeamSize === '') return Util.warningMsg('请填写团队人数上限')
if (minTeamSize > maxTeamSize) return util.warningMsg('团队人数上限不得小于下限') if (minTeamSize > maxTeamSize) return Util.warningMsg('团队人数上限不得小于下限')
} else { // } else { //
if (quantityLimit === '') return util.warningMsg('请填写报名人数上限') if (quantityLimit === '') return Util.warningMsg('请填写报名人数上限')
if (quantityLimit < 0) return util.warningMsg('报名人数上限不得小于0') if (quantityLimit < 0) return Util.warningMsg('报名人数上限不得小于0')
} }
if (isNeedCode && (!invitationCode || invitationCode.length !== 4)) return util.warningMsg('请填写四位数邀请码') if (isNeedCode && (!invitationCode || invitationCode.length !== 4)) return Util.warningMsg('请填写四位数邀请码')
if (!form.description) return util.warningMsg("请填写竞赛详情"); if (!form.description) return Util.warningMsg("请填写竞赛详情");
} else { } else {
if (form.competitionScope == 2 && (!form.competitionRangeList || !form.competitionRangeList.length)) form.competitionScope = 1 if (form.competitionScope == 2 && (!form.competitionRangeList || !form.competitionRangeList.length)) form.competitionScope = 1
} }
this.$parent.showLoad() this.$parent.showLoad()
delete form.publishStatus // delete form.publishStatus
if (status === 1) form.publishStatus = 1 // if (status === 1) form.publishStatus = 1
form.ztOpen = status ? 0 : 1 // form.publishStatus = status
form.releaseType = releaseType
form.id = this.$route.query.id form.id = this.$route.query.id
form.ztOpen = form.id ? form.ztOpen : (status ? 0 : 1) //
form.releaseType = releaseType
if (form.id) { if (form.id) {
this.$post(this.api.editCompetition, form).then(res => { this.$post(this.api.editCompetition, form).then(async () => {
this.$parent.hideLoad() this.$parent.hideLoad()
this.updateTime && util.successMsg("修改成功"); this.updateTime && Util.successMsg("修改成功")
this.updateTime = 0 this.updateTime = 0
await this.automaticAllocation(status)
this.$emit('next', next) this.$emit('next', next)
}).catch(err => { }).catch(err => {
this.$parent.hideLoad() this.$parent.hideLoad()
@ -695,29 +653,47 @@ export default {
this.$post(this.api.addCompetition, form).then(({ competitionId, setupId }) => { this.$post(this.api.addCompetition, form).then(({ competitionId, setupId }) => {
this.updateTime = 0 this.updateTime = 0
this.$parent.hideLoad() this.$parent.hideLoad()
util.successMsg("创建成功"); Util.successMsg("创建成功")
this.$emit('next', next, setupId, competitionId) this.$emit('next', next, setupId, competitionId)
}).catch(err => { }).catch(err => {
this.$parent.hideLoad() this.$parent.hideLoad()
}); });
} }
}, },
//
async automaticAllocation (status) {
//
if (this.form.completeCompetitionSetup.competitionType) {
const { signUpEndTime } = this.form
const { id } = this.$route.query
const now = await Util.getNow()
//
if (this.originSignUpEndTime && signUpEndTime !== this.originSignUpEndTime && (new Date(signUpEndTime) < now || (new Date(this.originSignUpEndTime) < now && new Date(signUpEndTime) > now))) {
await this.$post(this.api.updateEventAllocationRecord, {
competitionId: id,
whetherToModifyTheRule: 1,
})
this.originSignUpEndTime = signUpEndTime
}
}
},
// //
preview () { preview () {
util.local.set('match', this.form) Util.local.set('match', this.form)
window.open(this.$router.resolve('/matchPreview').href) window.open(this.$router.resolve('/matchPreview').href)
}, },
addSponsor () { addSponsor () {
this.sponsorList.push(""); this.sponsorList.push('')
}, },
delSponsor (index) { delSponsor (index) {
this.sponsorList.splice(index, 1); this.sponsorList.splice(index, 1)
}, },
addOrganizer () { addOrganizer () {
this.undertakerList.push(""); this.undertakerList.push('')
}, },
delOrganizer (index) { delOrganizer (index) {
this.undertakerList.splice(index, 1); this.undertakerList.splice(index, 1)
} }
} }
}; };
@ -727,6 +703,7 @@ export default {
$upload-width: 220px; $upload-width: 220px;
$upload-height: 140px; $upload-height: 140px;
$upload-lg-height: 150px; $upload-lg-height: 150px;
/deep/ .avatar-uploader { /deep/ .avatar-uploader {
.el-upload { .el-upload {
position: relative; position: relative;
@ -811,6 +788,7 @@ $upload-lg-height: 150px;
width: 100%; width: 100%;
} }
} }
.inline-input { .inline-input {
.input-wrap { .input-wrap {
display: flex; display: flex;
@ -855,27 +833,33 @@ $upload-lg-height: 150px;
font-weight: bold; font-weight: bold;
} }
} }
.range-check { .range-check {
display: inline-block; display: inline-block;
margin: 0 0 10px 10px; margin: 0 0 10px 10px;
} }
/deep/.range-cas { /deep/.range-cas {
.el-tag { .el-tag {
display: none; display: none;
} }
} }
.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;
} }
} }
.el-steps { .el-steps {
justify-content: center; justify-content: center;
} }
/deep/.req { /deep/.req {
.el-form-item__label { .el-form-item__label {
&:before { &:before {

@ -3,104 +3,70 @@
<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" <el-form :model="form" :rules="validRules" label-width="170px" label-suffix=":" size="small"
:rules="validRules" :disabled="!!(!editing && id)">
label-width="170px"
label-suffix=":"
size="small"
: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 +
'-' + step1.completeCompetitionSetup.maxTeamSize + '人/队)' : '个人赛' }} <span
class="tips">如需修改请返回上一步</span>
</el-form-item> </el-form-item>
<el-form-item prop="rule" <el-form-item prop="rule" label="赛制">
label="赛制"> <el-radio v-for="(rule, i) in rules" :key="i" v-model="form.rule" :label="rule.id">{{ rule.name
<el-radio v-for="(rule, i) in rules" }}</el-radio>
:key="i"
v-model="form.rule"
:label="rule.id">{{ rule.name }}</el-radio>
<p class="tips">积分赛包含多个竞赛阶段每个阶段的成绩都包含在最终总成绩里最后一轮结束后总成绩排名靠前的参赛者得到获奖资格</p> <p class="tips">积分赛包含多个竞赛阶段每个阶段的成绩都包含在最终总成绩里最后一轮结束后总成绩排名靠前的参赛者得到获奖资格</p>
<p class="tips">淘汰赛包含多个竞赛阶段每个阶段结束后之后只有部分参赛者能晋级下一阶段晋级最后一轮且在最后一轮排名靠前的参赛者得到获奖资格</p> <p class="tips">淘汰赛包含多个竞赛阶段每个阶段结束后之后只有部分参赛者能晋级下一阶段晋级最后一轮且在最后一轮排名靠前的参赛者得到获奖资格</p>
<p class="tips">单项赛仅包含一个竞赛阶段单项的成绩排名即为最终排名排名靠前的参赛者得到获奖资格</p> <p class="tips">单项赛仅包含一个竞赛阶段单项的成绩排名即为最终排名排名靠前的参赛者得到获奖资格</p>
<p class="tips">系统默认排名规则优先按分数排名分数高则排名靠前分数相同则按用时排名用时短则排名靠前</p> <p class="tips">系统默认排名规则优先按分数排名分数高则排名靠前分数相同则按用时排名用时短则排名靠前</p>
</el-form-item> </el-form-item>
<template v-if="form.rule !== 2"> <template v-if="form.rule !== 2">
<el-form-item prop="stageNum" <el-form-item prop="stageNum" label="阶段数量">
label="阶段数量">
<div class="input-center"> <div class="input-center">
<el-select v-model="form.stageNum" <el-select v-model="form.stageNum" @change="stageChange">
@change="stageChange"> <el-option v-for="i in 10" :key="i" :label="i" :value="i"></el-option>
<el-option v-for="i in 10"
:key="i"
:label="i"
:value="i"></el-option>
</el-select> </el-select>
</div> </div>
<div v-if="step1.completeCompetitionSetup.competitionType" <div v-if="step1.completeCompetitionSetup.competitionType" class="tips">
class="tips">
(团队赛是否限制队内每个成员只能参加一个阶段赛项 (团队赛是否限制队内每个成员只能参加一个阶段赛项
<el-radio v-model="form.teamLimit" <el-radio v-model="form.teamLimit" :label="1"></el-radio>
:label="1"></el-radio> <el-radio v-model="form.teamLimit" :label="0"></el-radio>
<el-radio v-model="form.teamLimit"
:label="0"></el-radio>
) )
</div> </div>
</el-form-item> </el-form-item>
<el-form-item v-if="!form.rule" <el-form-item v-if="!form.rule" prop="resultCalculationMethod" label="总成绩计算方式">
prop="resultCalculationMethod" <el-radio v-model="form.resultCalculationMethod" :label="0">各阶段成绩加权求和</el-radio>
label="总成绩计算方式"> <el-radio v-model="form.resultCalculationMethod" :label="1">各阶段成绩直接求和</el-radio>
<el-radio v-model="form.resultCalculationMethod" <el-radio v-model="form.resultCalculationMethod" :label="2">各阶段成绩取平均值</el-radio>
:label="0">各阶段成绩加权求和</el-radio>
<el-radio v-model="form.resultCalculationMethod"
:label="1">各阶段成绩直接求和</el-radio>
<el-radio v-model="form.resultCalculationMethod"
:label="2">各阶段成绩取平均值</el-radio>
<p class="tips">若选择加权求和则需要设置每个阶段成绩所占权重且权重总和须为100%</p> <p class="tips">若选择加权求和则需要设置每个阶段成绩所占权重且权重总和须为100%</p>
</el-form-item> </el-form-item>
<el-form-item prop="stageNum" <el-form-item prop="stageNum" label="阶段设置">
label="阶段设置"> <div v-for="(item, i) in form.competitionStageList" :key="i" class="step-set">
<div v-for="(item, i) in form.competitionStageList"
:key="i"
class="step-set">
<div class="line"> <div class="line">
{{ serials[i] }}阶段 <el-input v-model="item.stageName" {{ serials[i] }}阶段 <el-input v-model="item.stageName" clearable placeholder="请输入阶段名称,如“初赛”"
clearable
placeholder="请输入阶段名称,如“初赛”"
style="width: 200px"></el-input> style="width: 200px"></el-input>
</div> </div>
<div class="line"> <div class="line">
<span class="req">*</span> <span class="req">*</span>
比赛方式 比赛方式
<el-radio v-for="(method, i) in methods" <el-radio v-for="(method, i) in methods" :key="i" v-model="item.method" :label="method.id">{{
:key="i" method.name }}</el-radio>
v-model="item.method"
:label="method.id">{{ method.name }}</el-radio>
</div> </div>
<div v-if="step1.completeCompetitionSetup.competitionType" <div v-if="step1.completeCompetitionSetup.competitionType" class="line">
class="line">
<span class="req">*</span> <span class="req">*</span>
团队参赛人数限制 团队参赛人数限制
<el-radio v-model="item.teamNumLimitOpt" <el-radio v-model="item.teamNumLimit" :label="0">不限制</el-radio>
:label="0">不限制</el-radio> <el-radio v-model="item.teamNumLimit" :label="1">自定义</el-radio>
<el-radio v-model="item.teamNumLimitOpt" <el-input v-model.number="item.customNumber" type="number" min="0" style="width: 150px;"
:label="1">自定义</el-radio> :disabled="item.teamNumLimit === 0"></el-input>
<el-input v-model.number="item.teamNumLimit"
type="number"
style="width: 150px;"
:disabled="item.teamNumLimitOpt === 0"></el-input>
<span class="tips">可限制本阶段单个团队的出战人数</span> <span class="tips">可限制本阶段单个团队的出战人数</span>
</div> </div>
<div v-if="step1.completeCompetitionSetup.competitionType" <div v-if="step1.completeCompetitionSetup.competitionType" class="line">
class="line">
<span class="req">*</span> <span class="req">*</span>
团队成绩计算方式 团队成绩计算方式
<el-radio v-for="(j, i) in teamCalculationMethods" <el-radio v-for="(j, i) in teamCalculationMethods" :key="i" v-model="item.teamCalculationMethod"
:key="i"
v-model="item.teamCalculationMethod"
:label="j.id">{{ j.name }}</el-radio> :label="j.id">{{ j.name }}</el-radio>
<span class="tips">可设置本阶段的团队取分规则</span> <span class="tips">可设置本阶段的团队取分规则</span>
</div> </div>
<div v-if="form.rule === 1 && i !== form.competitionStageList.length - 1" <div v-if="form.rule === 1 && i !== form.competitionStageList.length - 1" class="line"
class="line"
style="display: flex;"> style="display: flex;">
<p> <p>
<span class="req">*</span>晋级规则 <span class="req">*</span>晋级规则
@ -108,58 +74,44 @@
<div> <div>
<div class="line"> <div class="line">
本阶段成绩排名前 本阶段成绩排名前
<el-input v-model.number="item.peopleLimit" <el-input v-model.number="item.peopleLimit" type="number" min="0" style="width: 100px"></el-input>
type="number"
style="width: 100px"></el-input>
可晋级下一阶段比赛 可晋级下一阶段比赛
</div> </div>
<div class="line"> <div class="line">
本阶段成绩排名前 本阶段成绩排名前
<el-input v-model.number="item.percentageLimit" <el-input v-model.number="item.percentageLimit" type="number" min="0"
type="number"
style="width: 100px"></el-input> style="width: 100px"></el-input>
%可晋级下一阶段比赛 %可晋级下一阶段比赛
</div> </div>
<div> <div>
本阶段成绩 本阶段成绩
<el-select v-model="item.operator" <el-select v-model="item.operator" style="width: 80px;margin-right: 10px">
style="width: 80px;margin-right: 10px"> <el-option v-for="i in operators" :key="i" :label="i" :value="i"></el-option>
<el-option v-for="i in operators"
:key="i"
:label="i"
:value="i"></el-option>
</el-select> </el-select>
<el-input v-model="item.score" <el-input v-model="item.score" type="number" min="0" style="width: 100px"></el-input>
type="number"
style="width: 100px"></el-input>
可晋级下一阶段比赛 可晋级下一阶段比赛
</div> </div>
</div> </div>
</div> </div>
<div v-if="!form.rule" <div v-if="!form.rule" class="line">
class="line">
<span class="req">*</span> <span class="req">*</span>
占总成绩权重 占总成绩权重
<el-input v-model.number="item.pointWeight" <el-input v-model.number="item.pointWeight" type="number" min="0"
type="number" :disabled="form.resultCalculationMethod != 0" style="width: 150px;"></el-input> %
:disabled="form.resultCalculationMethod != 0"
style="width: 150px;"></el-input> %
</div> </div>
<div class="line"> <div class="line">
成绩公布时间 成绩公布时间
阶段比赛结束后 阶段比赛结束后
<el-input v-model.number="item.resultAnnouncementTime" <el-input v-model.number="item.resultAnnouncementTime" type="number" min="0"
type="number"
style="width: 120px"></el-input> style="width: 120px"></el-input>
小时公布阶段比赛成绩 小时公布阶段比赛成绩为空则不公布成绩为0则阶段比赛结束后立马公布成绩
</div> </div>
<div v-if="item.resultAnnouncementTime !== '' && item.resultAnnouncementTime !== null && item.resultAnnouncementTime !== undefined" <div
v-if="item.resultAnnouncementTime !== '' && item.resultAnnouncementTime !== null && item.resultAnnouncementTime !== undefined"
class="line"> class="line">
是否公布成绩详情 是否公布成绩详情
<el-radio v-model="item.resultsDetails" <el-radio v-model="item.resultsDetails" :label="0"></el-radio>
:label="0"></el-radio> <el-radio v-model="item.resultsDetails" :label="1"></el-radio>
<el-radio v-model="item.resultsDetails"
:label="1"></el-radio>
<p class="tips">若选择则公布成绩详情竞赛结束后参赛者可查看自己的比赛成绩得分详情</p> <p class="tips">若选择则公布成绩详情竞赛结束后参赛者可查看自己的比赛成绩得分详情</p>
<p class="tips">若选择则不公布成绩详情参赛者只能知晓自己的分数及排名不能查看得分详情</p> <p class="tips">若选择则不公布成绩详情参赛者只能知晓自己的分数及排名不能查看得分详情</p>
</div> </div>
@ -167,43 +119,34 @@
</el-form-item> </el-form-item>
</template> </template>
<template v-else> <template v-else>
<el-form-item prop="stageNum" <el-form-item prop="stageNum" label="规则设置">
label="规则设置">
<div class="step-set"> <div class="step-set">
<div class="line"> <div class="line">
<span class="req">*</span> <span class="req">*</span>
比赛方式 比赛方式
<el-radio v-for="(method, i) in methods" <el-radio v-for="(method, i) in methods" :key="i" v-model="form.competitionStageList[0].method"
:key="i"
v-model="form.competitionStageList[0].method"
:label="method.id">{{ method.name }}</el-radio> :label="method.id">{{ method.name }}</el-radio>
</div> </div>
<div v-if="step1.completeCompetitionSetup.competitionType" <div v-if="step1.completeCompetitionSetup.competitionType" class="line">
class="line">
<span class="req">*</span> <span class="req">*</span>
团队成绩计算方式 团队成绩计算方式
<el-radio v-for="(j, i) in teamCalculationMethods" <el-radio v-for="(j, i) in teamCalculationMethods" :key="i"
:key="i" v-model="form.competitionStageList[0].teamCalculationMethod" :label="j.id">{{ j.name }}</el-radio>
v-model="form.competitionStageList[0].teamCalculationMethod"
:label="j.id">{{ j.name }}</el-radio>
<span class="tips">可设置本阶段的团队取分规则</span> <span class="tips">可设置本阶段的团队取分规则</span>
</div> </div>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item prop="rule" <el-form-item label="成绩公布时间">
label="成绩公布时间">
阶段比赛结束后 阶段比赛结束后
<el-input v-model.number="form.competitionStageList[0].resultAnnouncementTime" <el-input v-model.number="form.competitionStageList[0].resultAnnouncementTime" type="number" min="0"
type="number"
style="width: 120px"></el-input> style="width: 120px"></el-input>
小时公布阶段比赛成绩 小时公布阶段比赛成绩为空则不公布成绩为0则阶段比赛结束后立马公布成绩
</el-form-item> </el-form-item>
<el-form-item prop="resultsDetails" <el-form-item
label="是否公布成绩详情"> v-if="form.competitionStageList[0].resultAnnouncementTime !== '' && form.competitionStageList[0].resultAnnouncementTime !== null && form.competitionStageList[0].resultAnnouncementTime !== undefined"
<el-radio v-model="form.competitionStageList[0].resultsDetails" prop="resultsDetails" label="是否公布成绩详情">
:label="0"></el-radio> <el-radio v-model="form.competitionStageList[0].resultsDetails" :label="0"></el-radio>
<el-radio v-model="form.competitionStageList[0].resultsDetails" <el-radio v-model="form.competitionStageList[0].resultsDetails" :label="1"></el-radio>
:label="1"></el-radio>
<p class="tips">若选择则公布成绩详情竞赛结束后参赛者可查看自己的比赛成绩得分详情</p> <p class="tips">若选择则公布成绩详情竞赛结束后参赛者可查看自己的比赛成绩得分详情</p>
<p class="tips">若选择则不公布成绩详情参赛者只能知晓自己的分数及排名不能查看得分详情</p> <p class="tips">若选择则不公布成绩详情参赛者只能知晓自己的分数及排名不能查看得分详情</p>
</el-form-item> </el-form-item>
@ -216,8 +159,8 @@
<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 () {
@ -243,8 +186,8 @@ export default {
scoreLimit: '', scoreLimit: '',
operator: '>', operator: '>',
score: '', score: '',
teamNumLimit: '', customNumber: '',
teamNumLimitOpt: 0, teamNumLimit: 0,
resultAnnouncementTime: '', resultAnnouncementTime: '',
resultsDetails: '', resultsDetails: '',
}, },
@ -259,8 +202,8 @@ export default {
scoreLimit: '', scoreLimit: '',
operator: '>', operator: '>',
score: '', score: '',
teamNumLimit: '', customNumber: '',
teamNumLimitOpt: 0, teamNumLimit: 0,
resultAnnouncementTime: '', resultAnnouncementTime: '',
resultsDetails: '', resultsDetails: '',
}, },
@ -275,8 +218,8 @@ export default {
scoreLimit: '', scoreLimit: '',
operator: '>', operator: '>',
score: '', score: '',
teamNumLimit: '', customNumber: '',
teamNumLimitOpt: 0, teamNumLimit: 0,
resultAnnouncementTime: '', resultAnnouncementTime: '',
resultsDetails: '', resultsDetails: '',
} }
@ -299,6 +242,7 @@ export default {
{ required: true, trigger: 'change' } { required: true, trigger: 'change' }
], ],
}, },
originForm: null,
ruleForm: {}, ruleForm: {},
rules: Const.rules, rules: Const.rules,
methods: Const.methods, methods: Const.methods,
@ -339,9 +283,9 @@ export default {
} }
if (!e.peopleLimit) e.peopleLimit = '' if (!e.peopleLimit) e.peopleLimit = ''
if (!e.percentageLimit) e.percentageLimit = '' if (!e.percentageLimit) e.percentageLimit = ''
e.teamNumLimitOpt = e.teamNumLimit ? 1 : 0
e.teamCalculationMethod = +e.teamCalculationMethod e.teamCalculationMethod = +e.teamCalculationMethod
}) })
this.originForm = _.cloneDeep(rule)
this.form = rule this.form = rule
} }
this.$nextTick(() => { this.$nextTick(() => {
@ -373,9 +317,38 @@ export default {
this.form.competitionStageList = stages.slice(0, val) this.form.competitionStageList = stages.slice(0, val)
} }
}, },
//
async automaticAllocation (next) {
//
if (this.step1.completeCompetitionSetup.competitionType) {
const { form, originForm } = this
// 34
let changeLimit = 0
for (const i in form.competitionStageList) {
const e = form.competitionStageList[i]
const originStage = originForm.competitionStageList[i]
if (!originStage || e.teamNumLimit !== originStage.teamNumLimit || e.customNumber !== originStage.customNumber) {
changeLimit = 1
break
}
}
// new Date(this.$parent.$refs.step1.form.signUpEndTime)
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)
} else {
this.$emit('next', next)
}
} else {
this.$emit('next', next)
}
},
// //
save (status, next = 0) { save (status, next = 0) {
let { form } = this const form = _.cloneDeep(this.form)
const { rule } = form const { rule } = form
let invalid = 0 let invalid = 0
let pointWeight = 0 let pointWeight = 0
@ -397,6 +370,8 @@ export default {
} }
form.competitionStageList = stages.slice(0, 1) // form.competitionStageList = stages.slice(0, 1) //
} else { // } else { //
let customNumber = 0
const { competitionType, minTeamSize, maxTeamSize } = step1.completeCompetitionSetup // 01
for (const i in stages) { for (const i in stages) {
const e = stages[i] const e = stages[i]
if (rule !== 2 && !e.stageName) { if (rule !== 2 && !e.stageName) {
@ -404,12 +379,11 @@ export default {
util.errorMsg('请输入阶段名称') util.errorMsg('请输入阶段名称')
break break
} }
const { competitionType, maxTeamSize } = step1.completeCompetitionSetup // 01
// rule: 012 // rule: 012
// //
if (!rule) { if (!rule) {
// //
if (form.resultCalculationMethod == 0 && e.pointWeight === '') { if (form.resultCalculationMethod == 0 && (e.pointWeight === '' || e.pointWeight === undefined)) {
invalid = 1 invalid = 1
util.errorMsg('请输入权重') util.errorMsg('请输入权重')
break break
@ -424,22 +398,22 @@ export default {
} }
if (e.score !== '') e.scoreLimit = e.operator + e.score if (e.score !== '') e.scoreLimit = e.operator + e.score
} }
if (rule !== 2 && competitionType && e.teamNumLimitOpt) { if (rule !== 2 && competitionType && e.teamNumLimit) {
if (e.teamNumLimit === '') { if (e.customNumber === '' || e.customNumber === undefined) {
invalid = 1 invalid = 1
util.errorMsg('请输入团队参数人数限制') util.errorMsg('请输入团队参数人数限制')
break break
} else if (e.teamNumLimit < 0) { } else if (e.customNumber < 0) {
invalid = 1 invalid = 1
util.errorMsg('团队参数人数不得小于0') util.errorMsg('团队参数人数不得小于0')
break break
} else if (maxTeamSize !== '' && e.teamNumLimit > maxTeamSize) { } else if (maxTeamSize !== '' && e.customNumber > maxTeamSize) {
invalid = 1 invalid = 1
util.errorMsg('团队参数人数不得大于团队人数上限') util.errorMsg('团队参数人数不得大于团队人数上限')
break break
} }
} }
if (e.resultsDetails === 0 && e.resultAnnouncementTime !== '') { if (e.resultsDetails === 0 && (e.resultAnnouncementTime !== '' && e.resultAnnouncementTime !== undefined)) {
if (e.resultAnnouncementTime < 0) { if (e.resultAnnouncementTime < 0) {
invalid = 1 invalid = 1
util.errorMsg('成绩公布时间不得小于0') util.errorMsg('成绩公布时间不得小于0')
@ -452,22 +426,25 @@ export default {
} }
e.resultAnnouncementTime = +e.resultAnnouncementTime e.resultAnnouncementTime = +e.resultAnnouncementTime
} }
if (e.teamNumLimit && e.customNumber) customNumber += e.customNumber //
if (!e.teamNumLimit) e.customNumber = ''
} }
if (invalid) return if (invalid) return
if (form.teamLimit && competitionType) {
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,请重新输入') if (form.resultCalculationMethod == 0 && !rule && pointWeight > 0 && pointWeight !== 100) return util.errorMsg('权重须等于100,请重新输入')
} }
} else { // 稿 } else { // 稿
form.competitionStageList = form.competitionStageList.filter(e => e.stageName) form.competitionStageList = form.competitionStageList.filter(e => e.stageName)
} }
for (const e of form.competitionStageList) {
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("修改成功"); this.updateTime && util.successMsg("修改成功");
this.$emit('next', next) this.automaticAllocation(next)
}).catch(err => { }).catch(err => {
this.$parent.hideLoad() this.$parent.hideLoad()
}) })
@ -489,11 +466,13 @@ export default {
<style scoped lang="scss"> <style scoped lang="scss">
/deep/ .d-inline-block { /deep/ .d-inline-block {
width: 216px; width: 216px;
.el-select, .el-select,
.el-input { .el-input {
width: 100%; width: 100%;
} }
} }
.inline-input { .inline-input {
.input-wrap { .input-wrap {
display: flex; display: flex;
@ -518,26 +497,32 @@ export default {
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,75 +1,48 @@
<template> <template>
<div> <div>
<div v-show="!setVisible" <div v-show="!setVisible" class="page">
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" <el-form label-width="170px" label-suffix=":" size="small" :disabled="!!(!editing && id)">
label-suffix=":" <div v-for="(item, i) in form" :key="i" class="step">
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" <el-button v-if="item.method !== 2" type="primary" @click="toSet(i)">设置</el-button>
type="primary"
@click="toSet(i)">设置</el-button>
</div> </div>
<el-form-item class="req" <el-form-item class="req" prop="time" label="比赛时间">
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;" <div style="display: flex;align-items: center;" v-if="item.method === 2">
v-if="item.method === 2"> <el-date-picker v-model="item.time" type="datetimerange" range-separator="~" start-placeholder="开始日期"
<el-date-picker v-model="item.time" end-placeholder="结束日期" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
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"> @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 + '间)'" :title="'(请设置在 ' + step1.playStartTime + ' ~ ' + step1.playEndTime + '间)'" type="error"
type="error" :closable="false" effect="dark">
: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" <el-form-item class="req" label="比赛地点">
label="比赛地点"> <el-input v-model="item.offlineAddress" style="width: 80%"></el-input>
<el-input v-model="item.offlineAddress"
style="width: 80%"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="系统链接"> <el-form-item label="系统链接">
<el-input v-model="item.competitionStageContentSetting.systemLink" <el-input v-model="item.competitionStageContentSetting.systemLink" style="width: 80%"></el-input>
style="width: 80%"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="是否支持上传文件"> <el-form-item label="是否支持上传文件">
<div> <div>
<el-radio v-model="item.competitionStageContentSetting.whetherToUploadFiles" <el-radio v-model="item.competitionStageContentSetting.whetherToUploadFiles" :label="0"></el-radio>
:label="0"></el-radio>
</div> </div>
<div class="flex a-center"> <div class="flex a-center">
<el-radio v-model="item.competitionStageContentSetting.whetherToUploadFiles" <el-radio v-model="item.competitionStageContentSetting.whetherToUploadFiles" :label="1"></el-radio>
:label="1"></el-radio>
<template v-if="item.competitionStageContentSetting.whetherToUploadFiles"> <template v-if="item.competitionStageContentSetting.whetherToUploadFiles">
<el-upload class="file-upload" <el-upload class="file-upload" :on-remove="(file, fileList) => handleRemove(file, fileList, item)"
:on-remove="(file, fileList) => handleRemove(file, fileList, item)" :on-error="uploadError" :before-remove="beforeRemove" :on-preview="handlePreview" action=""
:on-error="uploadError"
:before-remove="beforeRemove"
:on-preview="handlePreview"
action=""
:file-list="item.competitionStageContentSetting.fileList" :file-list="item.competitionStageContentSetting.fileList"
:http-request="res => handleRequest(res, item)"> :http-request="res => handleRequest(res, item)">
<el-button size="small" <el-button size="small" type="primary">上传文件</el-button>
type="primary">上传文件</el-button>
<!-- <div slot="tip" <!-- <div slot="tip"
class="el-upload__tip" class="el-upload__tip"
style="position: relative"> style="position: relative">
@ -85,54 +58,45 @@
</div> </div>
<div style="display: flex;align-items: flex-start;margin-top: 10px"> <div style="display: flex;align-items: flex-start;margin-top: 10px">
<span style="margin: 0 10px 0 30px;">说明</span> <span style="margin: 0 10px 0 30px;">说明</span>
<el-input maxlength="1000" <el-input maxlength="1000" placeholder="请输入内容" type="textarea"
placeholder="请输入内容"
type="textarea"
v-model="item.competitionStageContentSetting.stageExplain" v-model="item.competitionStageContentSetting.stageExplain"
style="width: calc(80% - 216px);"></el-input> style="width: calc(80% - 216px);"></el-input>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item class="req" <el-form-item class="req" label="比赛内容">
label="比赛内容"> <el-input v-model="item.contentDescription" type="textarea" style="width: 80%"></el-input>
<el-input v-model="item.contentDescription"
type="textarea"
style="width: 80%"></el-input>
</el-form-item> </el-form-item>
<el-form-item class="req" <el-form-item class="req" label="评分规则">
label="评分规则"> <el-input v-model="item.scoreRule" type="textarea" style="width: 80%"></el-input>
<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>
<el-form-item class="req" <template v-if="item.method === 0">
prop="cid" <el-form-item class="req" prop="cid" label="课程系统">
label="课程系统">
{{ item.systemName }} {{ item.systemName }}
</el-form-item> </el-form-item>
<el-form-item class="req" <el-form-item class="req" prop="assessmentId" label="已选择考核">
prop="assessmentId"
label="已选择考核">
{{ item.projectName }} {{ item.projectName }}
</el-form-item> </el-form-item>
<el-form-item class="req" </template>
prop="resultAnnouncementTime" <el-form-item v-else class="req" label="已选择试卷">
label="比赛地点"> <div class="flex">
{{ item.paperName }}&emsp;
<el-form>
<el-button v-if="item.paperName" type="primary" size="mini" :disabled="false"
@click="previewPaper(item)">预览</el-button>
</el-form>
</div>
</el-form-item>
<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" <el-input v-model="item.onlineAddress" clearable placeholder="请输入比赛网址" :disabled="!item.onlineButton"
clearable
placeholder="请输入比赛网址"
:disabled="!item.onlineButton"
style="width: 400px;margin-left: 10px"></el-input> 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" <el-input v-model="item.offlineAddress" clearable placeholder="请输入地址" :disabled="!item.offlineButton"
clearable
placeholder="请输入地址"
:disabled="!item.offlineButton"
style="width: 400px;margin-left: 10px"></el-input> style="width: 400px;margin-left: 10px"></el-input>
</div> </div>
</el-form-item> </el-form-item>
@ -142,19 +106,31 @@
</div> </div>
</div> </div>
<set v-if="setVisible" <Set v-if="setVisible" :form.sync="form[curStep]" :step1.sync="step1" @hideSet="hideSet" />
:form.sync="form[curStep]"
:step1.sync="step1" <el-dialog title="提示" :visible.sync="tipsVisible" width="500px" :close-on-click-modal="false"
@hideSet="hideSet" /> custom-class="tips-dia">
<p style="font-size: 17px;text-align: center;color: #062c87;">编辑发布成功</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 Oss from '@/components/upload/upload.js' import Oss from '@/components/upload/upload.js'
import util from "@/libs/util"; import Setting from '@/setting'
import set from './set' import Util from '@/libs/util'
export default { export default {
props: ['setupId', 'competitionId', 'editing'], props: ['setupId', 'competitionId', 'editing'],
components: { Set },
data () { data () {
return { return {
headers: { headers: {
@ -188,6 +164,8 @@ export default {
stageId: '', stageId: '',
startTime: '', startTime: '',
systemId: '', systemId: '',
paperId: '',
paperName: '',
offlineAddress: '', offlineAddress: '',
offlineButton: 0, offlineButton: 0,
onlineAddress: '', onlineAddress: '',
@ -197,11 +175,12 @@ export default {
form: [], form: [],
setVisible: false, setVisible: false,
curStep: 0, curStep: 0,
curOriginForm: {},
closeStatus: false,
tipsVisible: false,
}; };
}, },
components: {
set
},
watch: { watch: {
// , // ,
form: { form: {
@ -258,6 +237,8 @@ export default {
url: n url: n
}) })
}) })
} else {
form.competitionStageContentSetting.fileList = []
} }
form.competitionStageContentSetting.competitionId = this.id form.competitionStageContentSetting.competitionId = this.id
form.competitionStageContentSetting.stageId = e.stageId form.competitionStageContentSetting.stageId = e.stageId
@ -268,8 +249,10 @@ export default {
form.method = e.method form.method = e.method
form.stageId = e.stageId form.stageId = e.stageId
form.stageName = e.stageName form.stageName = e.stageName
if (form.paperName) form.originPaperName = form.paperName //
this.form.push(form) this.form.push(form)
}) })
this.resumeData() this.resumeData()
this.$nextTick(() => { this.$nextTick(() => {
this.updateTime = 0 this.updateTime = 0
@ -278,6 +261,7 @@ 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
@ -288,13 +272,26 @@ 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) {
// //
@ -302,7 +299,7 @@ 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
} }
} }
@ -313,7 +310,7 @@ export default {
// //
beforeUpload (file) { beforeUpload (file) {
const isLt2M = file.size / 1024 / 1024 < 10 const isLt2M = file.size / 1024 / 1024 < 10
if (!isLt2M) util.warningMsg('请上传小于10MB的附件!') if (!isLt2M) Util.warningMsg('请上传小于10MB的附件!')
if (isLt2M) { if (isLt2M) {
this.fileName = file.name this.fileName = file.name
return true return true
@ -330,10 +327,10 @@ export default {
}, },
downloadFile () { downloadFile () {
// const { name, url } = this.fileList[0] // const { name, url } = this.fileList[0]
// util.downloadFile(name, url) // Util.downloadFile(name, url)
}, },
handlePreview (file) { handlePreview (file) {
window.open((util.isDoc(util.getFileExt(file.name)) ? 'https://view.officeapps.live.com/op/view.aspx?src=' : '') + file.url) window.open((Util.isDoc(Util.getFileExt(file.name)) ? 'https://view.officeapps.live.com/op/view.aspx?src=' : '') + file.url)
}, },
beforeRemove (file, fileList) { beforeRemove (file, fileList) {
return this.$confirm(`确定移除 ${file.name}`); return this.$confirm(`确定移除 ${file.name}`);
@ -355,12 +352,69 @@ export default {
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
} }
@ -371,54 +425,59 @@ export default {
if (status) { if (status) {
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 !== 2 && !e.cid) { if (e.method === 0 && !e.projectId) {
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) { // if (e.competitionStageContentSetting.whetherToUploadFiles && !e.competitionStageContentSetting.stageExplain) {
// invalid = 1 // invalid = 1
// util.errorMsg('') // Util.errorMsg('')
// break // 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
} }
} }
@ -448,9 +507,17 @@ export default {
}).then(res => { }).then(res => {
this.$parent.hideLoad() this.$parent.hideLoad()
// //
status && this.publish(status) if (status) {
util.successMsg((status ? '发布' : '保存') + '成功') this.publish(status)
this.sendSocket()
}
Util.successMsg((status ? '发布' : '保存') + '成功')
this.updateTime = 0
if (status && this.$parent.$refs.step1.form.completeCompetitionSetup.competitionType) {
this.autoAllocationConfirm() //
} else {
this.$emit('next', next) this.$emit('next', next)
}
}).catch(err => { }).catch(err => {
this.$parent.hideLoad() this.$parent.hideLoad()
}) })
@ -463,6 +530,7 @@ export default {
.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;
@ -472,9 +540,11 @@ export default {
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 {
@ -489,6 +559,7 @@ export default {
/deep/.file-upload { /deep/.file-upload {
width: 500px; width: 500px;
.download { .download {
position: absolute; position: absolute;
bottom: -63px; bottom: -63px;
@ -498,4 +569,10 @@ export default {
cursor: pointer; cursor: pointer;
} }
} }
/deep/.tips-dia {
.el-dialog__body {
padding: 10px 20px;
}
}
</style> </style>

@ -1,7 +1,9 @@
<template> <template>
<div class="wrap"> <div class="wrap">
<div class="modal"> <div class="modal">
<el-steps :space="200" :active="4" finish-status="success"> <el-steps :space="200"
:active="4"
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>
@ -9,7 +11,8 @@
</el-steps> </el-steps>
<h1>大赛已发布</h1> <h1>大赛已发布</h1>
<div class="btns"> <div class="btns">
<el-button type="primary" @click="back">确定</el-button> <el-button type="primary"
@click="back">确定</el-button>
</div> </div>
</div> </div>
</div> </div>
@ -27,7 +30,7 @@ export default {
}, },
methods: { methods: {
back () { back () {
this.$router.push(`/match?page=${this.$store.state.matchPage}`) this.$router.push(this.$store.state.referrer || '/match')
} }
} }
}; };

@ -0,0 +1,211 @@
<template>
<!-- 理论考试选择试卷 -->
<div>
<el-dialog title="请选择试卷" :visible.sync="listVisible" width="1200px" :close-on-click-modal="false"
@closed="closeDia">
<div class="tool">
<ul class="filter">
<li>
<label>试卷库</label>
<el-select v-model="filter.libraryId" placeholder="请选择试卷库" @change="initData">
<el-option v-for="(item, i) in paperLibraries" :key="i" :label="item.libraryName" :value="item.libraryId">
</el-option>
</el-select>
</li>
<li>
<label>建议用途</label>
<el-select v-model="filter.paperType" clearable placeholder="请选择状态" @change="initData">
<el-option v-for="(item, i) in paperTypes" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
<li>
<label>试卷难度</label>
<el-select v-model="filter.difficult" clearable multiple placeholder="请选择试卷难度" @change="initData">
<el-option v-for="(item, i) in difficults" :key="i" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
<li>
<label>题目类型</label>
<el-select v-model="questionType" clearable multiple placeholder="请选择题目类型" @change="initData">
<el-option v-for="(item, i) in questionTypes" :key="i" :label="item.name" :value="item.name"></el-option>
</el-select>
</li>
<li>
<label>搜索</label>
<el-input style="width: 250px;" placeholder="请输入试卷名称" prefix-icon="el-icon-search" v-model="filter.keyWord"
clearable />
</li>
</ul>
<div>
<!-- <el-button type="primary" @click="add">自定义理论试卷</el-button> -->
</div>
</div>
<el-table :data="papers" class="table" 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"> <div class="page" v-loading="loading">
<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,12 +8,9 @@
<div class="single-choice"> <div class="single-choice">
<dl> <dl>
<dd> <dd>
<el-radio-group v-model="form.month" <el-radio-group v-model="form.month" @change="changeType">
@change="changeType"> <el-radio v-for="(item, index) in dateList" :key="index" :label="item.id" border>{{ item.name
<el-radio v-for="(item,index) in dateList" }}</el-radio>
:key="index"
:label="item.id"
border>{{ item.name }}</el-radio>
</el-radio-group> </el-radio-group>
</dd> </dd>
</dl> </dl>
@ -21,218 +18,150 @@
</li> </li>
<li> <li>
<label>创建区间</label> <label>创建区间</label>
<el-date-picker v-model="date" <el-date-picker v-model="date" align="right" unlink-panels type="daterange" start-placeholder="开始日期"
align="right" end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" clearable></el-date-picker>
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="请输入竞赛名称/创建人" <el-input placeholder="请输入竞赛名称/创建人" suffix-icon="el-icon-search" v-model="form.keyWord" clearable></el-input>
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" <el-select v-model="form.platformSource" clearable @change="initData">
clearable <el-option v-for="(item, i) in sourceList" :key="i" :label="item.name" :value="item.id"></el-option>
@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.competitionScope" <el-select v-model="form.releaseType" clearable @change="initData">
clearable <el-option v-for="(item, i) in releaseTypes" :key="i" :label="item.name" :value="item.id"></el-option>
@change="initData"> </el-select>
<el-option v-for="(item, i) in rangeList" </li>
:key="i" <li>
:label="item.name" <label>竞赛范围</label>
:value="item.id"></el-option> <el-select v-model="form.competitionScope" @change="initData">
<el-option v-for="(item, i) in rangeList" :key="i" :label="item.name" :value="item.id"></el-option>
</el-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" <el-button type="primary" round @click="add" v-auth>创建竞赛</el-button>
round <el-button type="primary" round @click="delAllSelection" v-auth>批量删除</el-button>
@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" <el-table ref="table" :data="matchData" class="table" header-align="center"
:data="matchData" @selection-change="handleSelectionChange" row-key="id">
class="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"
@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" <el-table-column prop="competitionName" min-width="160" label="竞赛名称" align="center"></el-table-column>
label="竞赛名称" <el-table-column prop="name" label="竞赛来源" width="90" align="center">
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" <el-table-column prop="name" label="发布类型" width="110" align="center">
label="大赛范围" <template slot-scope="scope">
align="center"> {{ scope.row.releaseType ? '设置完整比赛' : '练习赛' }}
</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="applicantNum" <el-table-column prop="name" label="竞赛类型" width="90" align="center">
label="报名人数" <template slot-scope="scope">
align="center" {{ scope.row.competitionType ? '团队赛' : '个人赛' }}
width="100"></el-table-column> </template>
<el-table-column prop="status" </el-table-column>
label="状态" <el-table-column prop="applicantNum" label="报名人数" align="center" width="90"></el-table-column>
align="center" <el-table-column prop="status" label="状态" align="center" width="60">
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" <el-table-column prop="time" label="比赛时间" align="center" width="290">
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" <el-table-column prop="createTime" label="创建时间" align="center" width="160"></el-table-column>
label="创建时间" <el-table-column prop="founderName" label="创建人" width="130" align="center"></el-table-column>
align="center" <el-table-column label="操作" align="center" width="280">
width="160"></el-table-column>
<el-table-column label="操作"
align="center"
width="260">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button v-if="scope.row.playingStages && scope.row.playingStages.length" <el-button type="text" @click="copy(scope.row)">复制</el-button>
type="text" <el-button v-if="scope.row.publishStatus && scope.row.playingStages && scope.row.playingStages.length"
@click="editEndTime(scope.row)" type="text" @click="editEndTime(scope.row)" v-auth>修改结束时间</el-button>
v-auth>修改结束时间</el-button> <el-button type="text" @click="manage(scope.row)" v-auth>管理</el-button>
<el-button type="text" <el-button type="text" @click="delData(scope.row)" v-auth>删除</el-button>
@click="manage(scope.row)" <el-switch v-if="scope.row.publishStatus" v-auth="'/match:启用'" v-model="scope.row.ztOpen" :active-value="0"
v-auth>管理</el-button> :inactive-value="1" style="margin: 0 10px 0 5px" :active-text="scope.row.ztOpen ? '关' : '开'"
<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> @change="switchOff($event, scope.row, scope.$index)"></el-switch>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<div class="pagination"> <div class="pagination">
<el-pagination background <el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange"
layout="total, prev, pager, next"
:total="total"
@current-change="handleCurrentChange"
:current-page="page"> :current-page="page">
</el-pagination> </el-pagination>
</div> </div>
<el-dialog title="修改当前阶段结束时间" <el-dialog title="修改当前阶段结束时间" :visible.sync="modifyVisible" width="900px" :close-on-click-modal="false">
:visible.sync="modifyVisible" <el-table :data="curRow.playingStages" class="table" ref="table" header-align="center">
width="900px" <el-table-column prop="stageName" label="阶段名称" min-width="100" align="center"></el-table-column>
:close-on-click-modal="false"> <el-table-column label="竞赛起止时间" width="300" align="center">
<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="结束时间调整为" <el-table-column label="结束时间调整为" align="center" width="280">
align="center"
width="280">
<template slot-scope="scope"> <template slot-scope="scope">
<el-date-picker popper-class="no-atTheMoment" <el-date-picker popper-class="no-atTheMoment" v-model="scope.row.newEndTime" placeholder="请选择结束时间"
v-model="scope.row.newEndTime" type="datetime" :picker-options="pickerOptions">
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" <span slot="footer" class="dialog-footer">
class="dialog-footer"> <el-button size="small" @click="modifyVisible = false"> </el-button>
<el-button size="small" <el-button size="small" type="primary" @click="modifySubmit"> </el-button>
@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: "", id: null,
name: "不限" name: "不限"
}, },
{ {
@ -244,9 +173,23 @@ export default {
name: "院校创建" name: "院校创建"
} }
], ],
releaseTypes: [
{
id: '',
name: "不限"
},
{
id: 0,
name: '发布信息'
},
{
id: 1,
name: '完整比赛'
}
],
rangeList: [ rangeList: [
{ {
id: "", id: null,
name: "不限" name: "不限"
}, },
{ {
@ -262,14 +205,45 @@ export default {
name: "校内" name: "校内"
} }
], ],
competitionTypes: [
{
id: '',
name: '不限'
},
{
id: 0,
name: '个人赛'
},
{
id: 1,
name: '团队赛'
}
],
publishStatus: [
{
id: '',
name: '不限'
},
{
id: 0,
name: '未发布'
},
{
id: 1,
name: '已发布'
}
],
matchData: [], matchData: [],
form: { form: {
month: "", keyWord: null,
publishStatus: "", month: '',
startTime: "", startTime: null,
endTime: "", endTime: null,
platformSource: +this.$route.query.platformSource || 0, // (01) releaseType: '',
competitionScope: '', // (0: 1: 2.) publishStatus: '',
competitionType: '',
platformSource: 0, // (01)
competitionScope: null, // (0: 1: 2.)
}, },
multipleSelection: [], multipleSelection: [],
dateList: [ dateList: [
@ -307,14 +281,16 @@ 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 = [];
} }
@ -324,12 +300,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();
}, },
keyword: function (val) { 'form.keyWord': function (val) {
clearTimeout(this.searchTimer); clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => { this.searchTimer = setTimeout(() => {
this.initData(); this.initData();
@ -337,6 +313,23 @@ 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()
@ -348,64 +341,80 @@ export default {
}) })
}, },
methods: { methods: {
getData () { async getData () {
this.loading = true
try {
const { form } = this const { form } = this
this.$post(this.api.CompetitionPageConditionQueryByNakadai, { const { data } = await this.$post(this.api.CompetitionPageConditionQueryByNakadai, {
pageNum: this.page, pageNum: this.page,
pageSize: this.pageSize, pageSize: this.pageSize,
competitionScope: form.competitionScope === '' ? null : form.competitionScope, ...form
endTime: form.endTime || null, })
keyWord: this.keyword || null, this.matchData = data.records
platformSource: form.platformSource === '' ? null : form.platformSource,
startTime: form.startTime || null, this.now = await Util.getNow()
}).then(({ data }) => { clearInterval(this.timer)
// load.close() this.handleBeganStage()
const list = data.records
//
this.timer = setInterval(() => { this.timer = setInterval(() => {
const now = new Date() this.now = new Date(this.now.setSeconds(this.now.getSeconds() + 1))
list.map(e => { this.handleBeganStage()
}, 1000)
this.total = data.total
this.$refs.table.clearSelection()
this.loading = false
if (!this.matchData.length && this.total) {
this.page--
this.getData()
}
} catch (e) {
this.loading = false
}
},
//
async handleBeganStage () {
this.matchData.map(e => {
if (!e.playingStages) { if (!e.playingStages) {
this.$set(e, 'playingStages', []) this.$set(e, 'playingStages', [])
} else { } else {
e.playingStages = [] e.playingStages = []
} }
// //
if (now >= new Date(e.playStartTime) && now <= new Date(e.playEndTime)) { if (this.now >= new Date(e.playStartTime) && this.now <= new Date(e.playEndTime)) {
// //
if (e.competitionStageList) { if (e.competitionStageList) {
for (const n of e.competitionStageList) { for (const n of e.competitionStageList) {
// //
if (now >= new Date(n.startTime) && now <= new Date(n.endTime)) { if (this.now >= new Date(n.startTime) && this.now <= new Date(n.endTime)) {
e.playingStages.push(n) e.playingStages.push(n)
} }
} }
} }
} }
}) })
}, 1000)
this.matchData = list
this.total = data.total
this.$refs.table.clearSelection()
if (!this.matchData.length && this.total) {
this.page--
this.getData()
}
}).catch(res => { })
}, },
initData () { initData () {
this.page = 1; this.page = 1;
this.getData(); this.getData();
}, },
// redis // url
getRedis () { setReferrer () {
this.$post(this.api.getRedisCacheCompetition).then(({ data }) => { this.$store.commit('setReferrer', `${this.$route.path}?${qs.stringify(this.form)}&page=${this.page}`)
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
@ -425,13 +434,14 @@ export default {
competitionContents: data competitionContents: data
}).then(async res => { }).then(async res => {
await this.$post(`${this.api.refreshPageNotification}?content=1`) await this.$post(`${this.api.refreshPageNotification}?content=1`)
util.successMsg('修改成功') Util.successMsg('修改成功')
this.modifyVisible = false this.modifyVisible = false
this.getData() this.getData()
}).catch(err => { }) }).catch(err => { })
}, },
// //
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}`)
}, },
@ -441,14 +451,6 @@ 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) {
@ -457,7 +459,7 @@ export default {
}) })
.then(() => { .then(() => {
this.$post(`${this.api.batchDeleteCompetition}?competitionIds=${row.id}`).then(res => { this.$post(`${this.api.batchDeleteCompetition}?competitionIds=${row.id}`).then(res => {
util.successMsg("删除成功"); Util.successMsg("删除成功");
this.getData(); this.getData();
}).catch(res => { }).catch(res => {
}); });
@ -491,7 +493,6 @@ 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 "---";
@ -503,7 +504,7 @@ export default {
isOpen: val, isOpen: val,
type: 0 // (01) type: 0 // (01)
}).then(res => { }).then(res => {
util.successMsg(val == 1 ? '禁用成功' : '启用成功') Util.successMsg(val == 1 ? '禁用成功' : '启用成功')
}).catch(err => { }) }).catch(err => { })
await this.$post(`${this.api.refreshPageNotification}?content=1`) await this.$post(`${this.api.refreshPageNotification}?content=1`)
@ -514,7 +515,12 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
/deep/ .tool { /deep/ .tool {
margin-bottom: 0;
.filter { .filter {
flex-wrap: wrap;
li {
margin-bottom: 15px;
}
.el-input { .el-input {
min-width: 190px; min-width: 190px;
} }

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

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

Loading…
Cancel
Save