Compare commits

..

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

  1. 2
      .prettierrc
  2. 3549
      package-lock.json
  3. 18
      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. 129
      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/mini.jpg
  27. BIN
      src/assets/img/project.png
  28. 1
      src/assets/img/right.svg
  29. 1
      src/assets/img/shrink.svg
  30. 1
      src/assets/img/tag-active.svg
  31. 1
      src/assets/img/tag.svg
  32. BIN
      src/assets/img/wechat-code.jpeg
  33. BIN
      src/assets/img/workbench/1.png
  34. BIN
      src/assets/img/workbench/10.png
  35. BIN
      src/assets/img/workbench/11.png
  36. BIN
      src/assets/img/workbench/12.png
  37. BIN
      src/assets/img/workbench/13.png
  38. BIN
      src/assets/img/workbench/14.png
  39. BIN
      src/assets/img/workbench/15.png
  40. BIN
      src/assets/img/workbench/16.png
  41. BIN
      src/assets/img/workbench/2.png
  42. BIN
      src/assets/img/workbench/3.png
  43. BIN
      src/assets/img/workbench/4.png
  44. BIN
      src/assets/img/workbench/5.png
  45. BIN
      src/assets/img/workbench/6.png
  46. BIN
      src/assets/img/workbench/7.png
  47. BIN
      src/assets/img/workbench/8.png
  48. BIN
      src/assets/img/workbench/9.png
  49. 1
      src/assets/img/wrong.svg
  50. 96
      src/components/Header.vue
  51. 149
      src/components/Navbar.vue
  52. 260
      src/components/Sidebar.vue
  53. 54
      src/components/codemirror.vue
  54. 47
      src/components/img-upload/Cropper.vue
  55. 139
      src/components/quill/index.vue
  56. 32
      src/components/upload/config.js
  57. 140
      src/components/upload/index.vue
  58. 40
      src/components/upload/upload.js
  59. 2
      src/const/match.js
  60. 50
      src/const/ques.js
  61. 28
      src/const/source.js
  62. 34
      src/const/testPaper.js
  63. 4
      src/libs/aliyun/aliyun-oss-sdk-6.17.1.min.js
  64. 7
      src/libs/aliyun/aliyun-upload-sdk-1.5.6.min.js
  65. 59
      src/libs/util.js
  66. 56
      src/libs/zip.js
  67. 9
      src/main.js
  68. 100
      src/router/index.js
  69. 16
      src/setting.js
  70. 32
      src/store/index.js
  71. 157
      src/utils/api.js
  72. 4
      src/utils/core.js
  73. 276
      src/utils/editor.js
  74. 24
      src/utils/http.js
  75. 79
      src/views/Home.vue
  76. 234
      src/views/Login.vue
  77. 413
      src/views/course/AddCurriculum.vue
  78. 204
      src/views/course/AddLink.vue
  79. 317
      src/views/course/Curriculum.vue
  80. 1080
      src/views/course/content/index.vue
  81. 610
      src/views/course/content/source.vue
  82. 290
      src/views/course/contentSettings.vue
  83. 1209
      src/views/course/detail.vue
  84. 332
      src/views/course/list.vue
  85. 502
      src/views/customer/AddCustomer.vue
  86. 33
      src/views/customer/Order.vue
  87. 16
      src/views/customer/Permission.vue
  88. 115
      src/views/customer/customer.vue
  89. 63
      src/views/data/Framework.vue
  90. 52
      src/views/data/Introduce.vue
  91. 130
      src/views/data/Product.vue
  92. 195
      src/views/devLogin.vue
  93. 99
      src/views/information/addArticle/index.vue
  94. 79
      src/views/information/columnManage/index.vue
  95. 21
      src/views/information/contentManage/contentList.vue
  96. 13
      src/views/information/contentManage/index.vue
  97. 13
      src/views/information/list/index.vue
  98. 251
      src/views/market/index.vue
  99. 88
      src/views/match/add/index.vue
  100. 379
      src/views/match/add/set.vue
  101. Some files were not shown because too many files have changed in this diff Show More

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

3549
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -8,41 +8,29 @@
"build": "vue-cli-service build"
},
"dependencies": {
"@tinymce/tinymce-vue": "^3.2.8",
"ali-oss": "^6.18.1",
"axios": "^0.18.0",
"@tinymce/tinymce-vue": "^3.2.8",
"babel-polyfill": "^6.26.0",
"blueimp-md5": "^2.19.0",
"clipboard": "^2.0.11",
"crypto-js": "^4.2.0",
"decimal.js": "^10.4.3",
"echarts": "^5.4.1",
"element-theme": "^2.0.1",
"element-ui": "^2.13.0",
"file-saver": "^2.0.5",
"image-conversion": "^2.1.1",
"image-webpack-loader": "^8.1.0",
"js-cookie": "^3.0.1",
"jsencrypt": "^3.3.2",
"jszip": "^3.10.1",
"lodash": "^4.17.21",
"mavon-editor": "^2.10.4",
"mavon-editor": "^2.6.17",
"postcss-px2rem": "^0.3.0",
"px2rem-loader": "^0.1.9",
"qs": "^6.11.2",
"sortablejs": "^1.14.0",
"stompjs": "^2.3.3",
"tinymce-plugin": "0.0.3-beta.22",
"umy-ui": "^1.1.6",
"vue": "^2.6.10",
"vue-codemirror": "^4.0.6",
"vue-cropper": "^0.5.8",
"vue-cropper": "^0.5.10",
"vue-cropperjs": "^3.0.0",
"vue-pdf": "^4.3.0",
"vue-quill-editor": "^3.0.6",
"vue-router": "^3.5.1",
"vue-schart": "^2.0.0",
"vue-ueditor-wrap": "^2.5.6",
"vue-uuid": "^2.0.2",
"vuedraggable": "^2.17.0",
"vuex": "^3.1.2"

@ -1,11 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<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, user-scalable=yes, shrink-to-fit=no" />
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="keywords" content="深圳或然科技中台">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
<link rel="stylesheet" href="//at.alicdn.com/t/font_830376_qzecyukz0s.css">
<title>深圳或然科技中台</title>
</head>
<body>
@ -14,6 +14,5 @@
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<script src="/dev/styles/tinymce/tinymce.min.js"></script>
</body>
</html>

@ -1,29 +1,13 @@
<template>
<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>
</div>
</template>
<script>
import Setting from '@/setting'
export default {
name: 'App',
data () {
return {
Setting,
ip: localStorage.getItem('ip') ? +localStorage.getItem('ip') : 0,
};
},
created () {
window.exitSystem = () => {
sessionStorage.removeItem('token')
location.reload()
}
//sessionStorage
if (sessionStorage.getItem("store") ) {
this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(sessionStorage.getItem("store"))))
@ -33,16 +17,14 @@ export default {
window.addEventListener("beforeunload",()=>{
sessionStorage.getItem("token") && sessionStorage.setItem("store",JSON.stringify(this.$store.state))
})
},
methods: {
ipChange (val) {
localStorage.setItem('ip', val)
location.reload()
},
}
}
</script>
<style>
@import "./assets/css/main.css";
/* @import "./assets/css/color-dark.css"; */
/*深色主题*/
@import "./assets/css/theme-green/color-green.css";
/* 浅绿色主题 */
</style>

@ -0,0 +1,28 @@
.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);
}

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

@ -8,25 +8,18 @@ body,
#app,
.wrapper {
width: 100%;
min-height: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
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;
}
.ip {
z-index: 1;
position: fixed;
top: 0;
left: 0;
}
a {
text-decoration: none;
text-decoration: none
}
i{
font-style: normal;
@ -35,6 +28,7 @@ li {
list-style-type:none;
}
::-webkit-scrollbar {
width: 8px;
height: 8px;
@ -60,14 +54,37 @@ li {
.el-table th>.cell {
font-size: 14px;
}
.content-box {
-webkit-transition: left .3s ease-in-out;
transition: left .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 {
padding-left: 5px;
margin-bottom: 24px;
line-height: 1;
font-size: 14px;
color: #585858;
border-left: 3px solid #062c87;
border-left: 3px solid #9278ff;
}
.el-upload-list{
width: 100%;
@ -98,7 +115,7 @@ li {
margin-right: 6px;
font-size: 14px;
line-height: 14px;
color: rgba(0, 0, 0, 0.65);
color: rgba(0, 0, 0, .65);
white-space: nowrap;
}
@ -106,7 +123,7 @@ li {
display: flex;
align-items: center;
padding: 0 24px;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
border-bottom: 1px solid rgba(0, 0, 0, .06);
}
.tabs .item {
position: relative;
@ -131,7 +148,7 @@ li {
border-radius: 2px;
}
.tabs .item.active:after {
border-bottom-color: #062c87;
border-bottom-color: #9278ff;
}
.crumbs {
@ -181,7 +198,7 @@ li {
.move-enter-active,
.move-leave-active {
transition: opacity 0.5s;
transition: opacity .5s;
}
.move-enter,
@ -253,6 +270,16 @@ li {
font-style: normal;
}
/* .link_upload .el-upload-list{
width: 30%;
} */
/*VueEditor*/
.ql-container {
min-height: 400px;
}
.ql-snow .ql-tooltip {
transform: translateX(117.5px) translateY(10px) !important;
}
@ -306,13 +333,12 @@ li {
color: #fff;
}
#app .el-table th{
background-color: #fafafc !important;
background-color: #9278FF!important;
font-size: 16px;
font-weight: normal;
color: #000;
}
.el-input__inner[type='number'] {
.el-input__inner[type=number] {
padding-right: 0;
}
/*flex*/
@ -356,7 +382,7 @@ li {
}
.hr_tag{
background-color: #062c87;
background-color: #9278FF;
width: 3px;
height: 15px;
margin-right: 5px;
@ -373,18 +399,20 @@ li {
margin-bottom: 20px;
}
.shadow{
border: 0.0625rem solid #ebeef5;
background-color: #fff;
border: 0.0625rem solid #EBEEF5;
background-color: #FFF;
color: #303133;
-webkit-transition: 0.3s;
transition: 0.3s;
-webkit-transition: .3s;
transition: .3s;
}
.shadow :hover{
box-shadow: 0 0.125rem 0.75rem 0 rgb(0 0 0 / 10%);
}
.flex-col{
display: flex;
flex-direction: column;
}
.addhr_tag{
background-color: #666;
@ -426,15 +454,12 @@ li {
.el-switch__label span {
font-size: 12px;
}
.m-r-5 {
margin-right: 5px;
.m-b-20 {
margin-bottom: 20px;
}
.m-r-10 {
margin-right: 10px;
}
.m-b-20 {
margin-bottom: 20px;
}
@media (max-width: 720px) {
.el-message {
min-width: auto !important;
@ -442,7 +467,7 @@ li {
}
}
.el-tooltip__popper {
max-width: 100% !important;
max-width: 500px !important;
}
.no-atTheMoment > .el-picker-panel__footer > .el-button--text:first-child{
display: none;
@ -450,7 +475,7 @@ li {
.tox-notifications-container {
display: none;
}
.mce-content-body:not([dir='rtl']) blockquote {
.mce-content-body:not([dir=rtl]) blockquote {
border-left: 0;
background-color: #ccc;
}
@ -466,47 +491,3 @@ li {
.search-wrap .el-input__inner {
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;
}

@ -1,189 +0,0 @@
.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;
}
}
}
}
}

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

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="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>

Before

Width:  |  Height:  |  Size: 946 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 343 B

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

Before

Width:  |  Height:  |  Size: 593 B

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

Before

Width:  |  Height:  |  Size: 766 B

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

Before

Width:  |  Height:  |  Size: 545 B

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

Before

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

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

Before

Width:  |  Height:  |  Size: 768 B

@ -10,84 +10,22 @@
<span class="user-avator">{{userName}}</span>
</div>
<el-divider class="ml20" 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>
</template>
<script>
import Bus from '@/libs/bus'
import Setting from '@/setting'
export default {
data() {
return {
timer: null,
Setting,
userName: '',
userName: ''
};
},
mounted(){
this.getUserInfo()
this.userName || this.getUserInfo()
},
methods: {
toPerson () {
if (this.$route.path.split('/').pop() !== 'person') {
this.$router.push('/person')
}
},
async logout () {
await this.$post(this.api.logout)
localStorage.removeItem('ms_username')
localStorage.removeItem('token')
sessionStorage.clear()
location.reload()
},
goHome () {
this.$router.push('/customer')
},
// socket
open () {
console.log("socket连接成功");
},
// socket
error () {
console.log("连接错误");
},
//
getMessage (msg) {
console.log("==websocket接收数据==");
console.log(JSON.parse(msg.data));
const { content } = JSON.parse(msg.data)
// 1234-id
content == 1 && Bus.$emit('matchSocket')
content == 4 && Bus.$emit('modelSocket')
},
// socket
close () {
console.log("socket已经关闭");
},
initSocket ({ id, account }) {
// socket
this.socket = new WebSocket(`wss://${Setting.isDev ? '192.168.31.51' : location.host}/nakadai/websocket/${id}/${account}`)
// this.socket = new WebSocket(`ws://121.37.12.51:9100/nakadai/websocket/${id}/${account}`)
// socket
this.socket.onopen = this.open;
// socket
this.socket.onerror = this.error;
// socket
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(){
this.$get(this.api.queryUserInfoDetails).then(({ result }) => {
let userInfo = result.hrUserInfo
@ -96,10 +34,22 @@ export default {
const { id } = result.userAccount
id && this.$store.commit('SET_ACCOUNTID', id)
this.$store.commit('SET_USERNAME', this.userName)
this.initSocket(result.userAccount)
Setting.isPro && this.heartbeatDetection()
}).catch(err => {})
},
toPerson(){
if(this.$route.path.split('/').pop()!=='person'){
this.$router.push('/person')
}
},
loginout() {
localStorage.removeItem('ms_username');
localStorage.removeItem('token');
sessionStorage.clear()
location.reload()
},
goHome(){
this.$router.push('/customer')
}
},
};
</script>
@ -112,66 +62,54 @@ export default {
font-size: 16px;
color: #333;
}
.header .logo {
float: left;
width: 170px;
height: 40px;
margin-left: 20px;
}
.header .logo img{
width: 100%;
height: 100%;
}
.header-right {
float: right;
padding-right: 50px;
}
.header-user-con {
display: flex;
height: 70px;
align-items: center;
}
.header-user-con .user{
display: inline-flex;
align-items: center;
cursor: pointer;
}
.user-avator {
cursor: pointer;
margin-left: 10px;
font-size: 12px;
}
.ml20{
margin-left: 20px;
}
.user-avator img {
display: block;
width: 40px;
height: 40px;
border-radius: 50%;
}
/deep/.header-right .el-button--text{
color: #333;
span {
font-size: 12px;
}
}
.header-right .el-divider--vertical{
width: 2px;
height: 15px;
}
.header-right .el-divider{
background-color: #333;
}

@ -1,149 +0,0 @@
<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,26 +1,47 @@
<template>
<div class="sidebar">
<el-menu :default-active="active" :default-openeds="['1', '2', '3', '4']" background-color="#fff" text-color="#333"
active-text-color="#062c87" router>
<div>
<el-menu
class="sidebar-el-menu"
:default-active="onRoutes"
background-color="#324157"
text-color="#bfcbd9"
active-text-color="#9278FF"
unique-opened
mode="horizontal"
router
@select="handleSelect"
>
<template v-for="item in menus">
<template v-if="item.children">
<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.children">
<el-submenu v-if="subItem.children" :index="subItem.index" :key="subItem.index">
<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.children" :key="i" :index="threeItem.index">{{
threeItem.title
}}</el-menu-item>
<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>
<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>
@ -31,203 +52,136 @@
<script>
import Setting from '@/setting'
import addRoutes from '@/libs/route/addRoutes'
export default {
props: ['path'],
data() {
return {
active: '',
defaultMenus: [
menuList: [
{
index: '1',
title: '系统后台',
children: [
{
index: '/configure?id=1',
title: 'Python系统'
icon: 'el-icon-school',
index: '/customer',
title: '客户管理'
},
{
index: '/theoryExam',
title: '理论考试系统'
icon: 'el-icon-user',
index: '/user',
title: '用户管理'
},
{
index: '/configure?id=3',
title: '金融产品设计及数字化营销沙盘系统'
icon: 'el-icon-shopping-bag-2',
index: '/order',
title: '订单管理'
},
{
index: '/configure?id=4',
title: '银行综合系统'
icon: 'el-icon-document-checked',
index: '/curriculum',
title: '课程管理'
},
{
index: '/configure?id=5',
title: '众筹系统'
},
]
icon: 'el-icon-notebook-2',
index: '/data',
title: '数据管理'
},
{
index: '2',
title: '职站教学后台',
children: [
{
index: '/curriculum',
title: '教学课程管理'
icon: 'el-icon-tickets',
index: '/match',
title: '大赛管理'
},
{
icon: 'el-icon-takeaway-box',
index: '/theoreticalCourse',
title: '精品课程管理'
title: '理论课程'
},
{
icon: 'el-icon-box',
index: '/information',
title: '资讯管理'
},
{
index: '/resourse',
title: '资源库'
},
]
},
{
index: '3',
title: '职站商城后台',
children: [
{
index: '/shop',
title: '产品管理'
},
{
index: '/market',
title: '营销管理'
icon: 'el-icon-receiving',
index: '/configure',
title: '服务配置'
},
{
index: '/parnerOperation',
title: '小程序内容管理'
icon: 'el-icon-office-building',
index: '/system',
title: '系统配置'
},
{
icon: 'el-icon-s-check',
index: '/parner',
title: '销售代理人管理'
},
]
},
{
index: '4',
title: '运营后台',
children: [
{
index: '/match',
title: '大赛管理'
title: '合伙管理'
},
{
index: '/data',
title: '数据管理'
},
{
index: '/review',
title: '评阅管理'
},
]
icon: 'el-icon-data-line',
index: '/parnerOperation',
title: '合伙运营'
},
],
menus: [],
onRoutes: this.$route.path
};
},
watch:{
path: {
handler (val) {
this.active = val === '/configure' ? `/configure?id=${this.$route.query.id}` : val
},
immediate: true
"$route.path":function(val){
this.menuList.map(e=>{
if(val.replace('/', '')===e.index){
this.handleSelect(val.replace('/', ''))
this.$forceUpdate();
}
})
}
},
mounted() {
Setting.dynamicRoute && this.initTabs()
sessionStorage.getItem('sideBar') && this.handleSelect(sessionStorage.getItem('sideBar'))
sessionStorage.getItem('token') && this.getPer() //
},
methods:{
initTabs () {
const { btns } = this.$store.state
const tabs = this.defaultMenus
btns.includes('/configure') && this.menus.push(tabs[0])
const children1 = []
btns.includes('/curriculum') && children1.push(tabs[1].children[0])
btns.includes('/theoreticalCourse') && children1.push(tabs[1].children[1])
btns.includes('/information') && children1.push(tabs[1].children[2])
btns.includes('/resourse') && children1.push(tabs[1].children[3])
this.menus.push({
index: '2',
title: '职站教学后台',
children: children1
})
const children2 = []
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])
this.menus.push({
index: '3',
title: '职站商城后台',
children: children2
})
const children3 = []
btns.includes('/match') && children3.push(tabs[3].children[0])
btns.includes('/data') && children3.push(tabs[3].children[1])
btns.includes('/review') && children3.push(tabs[3].children[2])
this.menus.push({
index: '4',
title: '运营后台',
children: children3
handleSelect(index){
this.onRoutes = index
this.$store.commit('setOrderParam', null)
this.$store.commit('setInfoTab', '1')
this.$store.commit('setColumnId', '')
sessionStorage.setItem('sideBar',index)
},
initMenu() {
if (Setting.dynamicRoute) {
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
}
},
handleSelect (index) {
//
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>
.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;
}
}
}
<style scoped>
.sidebar::-webkit-scrollbar {
width: 0;
}
.sidebar-el-menu:not(.el-menu--collapse) {
width: 100%;
}
.sidebar > ul {
height: 100%;
}

@ -1,45 +1,37 @@
<template>
<div class="wrap">
<div class="left">
<codemirror v-model="codeVal"
<codemirror
v-model="codeVal"
:options="cmOption"
class="code-mirror"
@ready="ready"
ref="codemirror"></codemirror>
<el-button class="run btn"
ref="codemirror"
></codemirror>
<el-button
class="run btn"
type="primary"
@click="runCode">运行</el-button>
@click="runCode"
>运行</el-button>
</div>
<div class="code-right answer">
<p class="text-wrapper">{{ runResult }}</p>
<div class="pic-wrap"
v-if="picSrcList.length">
<div class="pic-item"
v-for="(img, i) in picSrcList"
:key="i">
<el-image class="pic"
<div class="pic-wrap" v-if="picSrcList.length">
<div class="pic-item" v-for="(img, i) in picSrcList" :key="i">
<el-image
class="pic"
:src="img"
:preview-src-list="picSrcList">
</el-image>
<el-button class="download-btn btn"
type="primary"
size="mini"
@click="downloadPic(i)">下载图片</el-button>
<a :ref="'picLink' + i"
style="display: none;"
download="运行结果.png"
:href="img">下载图片</a>
<el-button class="download-btn btn" type="primary" size="mini" @click="downloadPic(i)">下载图片</el-button>
<a :ref="'picLink' + i" style="display: none;" download="运行结果.png" :href="img">下载图片</a>
</div>
</div>
<div class="result-right t-color"
v-show="isError">
<img src="@/assets/img/yes.png"
alt />运行成功
<div class="result-right t-color" v-show="isError">
<img src="@/assets/img/yes.png" alt />运行成功
</div>
<div class="result-wrong"
v-show="isError === 0">
<img src="@/assets/img/error.png"
alt />
<div class="result-wrong" v-show="isError === 0">
<img src="@/assets/img/error.png" alt />
{{errLine}}行出现错误
</div>
</div>
@ -225,7 +217,7 @@ export default {
::-webkit-scrollbar-thumb {
width: 5px;
border-radius: 6px;
background: rgba(173, 173, 173, 0.7);
background: rgba(173,173,173,.7);
}
.wrap {
display: flex;
@ -234,9 +226,6 @@ export default {
position: relative;
width: calc(100% - 400px);
}
.code-mirror {
line-height: 30px;
}
.text-wrapper {
white-space: pre-wrap;
}
@ -297,6 +286,11 @@ export default {
}
}
}
/deep/.CodeMirror-wrap pre.CodeMirror-line,
.CodeMirror-wrap pre.CodeMirror-line-like {
height: 30px;
line-height: 30px;
}
.result-right {
background-color: rgba(43, 40, 22, 1);
}

@ -3,7 +3,8 @@
<div class="cropper-content">
<!-- 剪裁框 -->
<div class="cropper">
<vueCropper ref="cropper"
<vueCropper
ref="cropper"
:img="option.img"
:output-size="option.size"
:output-type="option.outputType"
@ -13,21 +14,20 @@
:can-move-box="option.canMoveBox"
:original="option.original"
:auto-crop="option.autoCrop"
:auto-crop-width="autoCropWidth"
:auto-crop-height="autoCropHeight"
:auto-crop-width="option.autoCropWidth"
:auto-crop-height="option.autoCropHeight"
:fixed-box="option.fixedBox"
:fixed="fixed"
:fixed-number="fixedNumber"
@real-time="realTime"></vueCropper>
@realTime="realTime" />
<!-- <vueCropper ref="cropper" :img="option.img" :outputSize="option.size" :outputType="option.outputType"></vueCropper> -->
</div>
<!-- 预览框 -->
<div class="show-preview"
<div
class="show-preview"
:style="{'width': '500px', 'height': '400px', 'overflow': 'hidden', 'margin': '0 25px', 'display':'flex', 'align-items' : 'center'}">
<div :style="previews.div"
class="preview">
<img :src="previews.url"
:style="previews.img" />
<div :style="previews.div" class="preview">
<img :src="previews.url" :style="previews.img" />
</div>
</div>
</div>
@ -41,7 +41,8 @@
</div>-->
<!-- 确认上传按钮 -->
<div class="upload-btn">
<el-button type="primary"
<el-button
type="primary"
:loading="isUpload"
:disabled="isDisabled"
@click.prevent="uploadImg('blob')">
@ -85,16 +86,6 @@ export default {
fixed: {
type: Boolean,
default: true
},
// (:80%)
autoCropWidth: {
type: Number,
default: 480
},
// (:80%)
autoCropHeight: {
type: Number,
default: 124
}
},
data() {
@ -102,13 +93,15 @@ export default {
previews: {}, //
option: {
img: '', // ()
size: 1, // (:1)
size: 0.8, // (:1)
full: true, // true (:false)
outputType: 'png', // (:jpg)
outputType: 'jpg', // (:jpg)
canMove: true, // (:true)
original: false, // (:false)
canMoveBox: true, // (:true)
autoCrop: true, // (:false)
autoCropWidth: 480, // (:80%)
autoCropHeight: 124, // (:80%)
fixedBox: false, // (:false)
fixed: true, // (:true)
fixedNumber: [1, 0.26], // (:[1:1])
@ -133,7 +126,7 @@ export default {
},
updateImg(file) {
this.option.img = file.url
// this.option.size = file.size / 1024 > 200 ? 0.9 : 0.95
this.option.size = file.size / 1024 > 200 ? 0.9 : 0.95
},
realTime(data) {
//
@ -147,9 +140,9 @@ export default {
const that = this
if (type === 'blob') {
this.$refs.cropper.getCropBlob(data => {
// compress(data, 1).then(res => {
that.$emit('upload', data)
// })
compress(data, 0.8).then(res => {
that.$emit('upload', res)
})
})
} else {
this.$refs.cropper.getCropData(data => {

@ -1,21 +1,14 @@
<template>
<div>
<el-radio-group v-if="!readonly && radio" class="type-radio" v-model="editorType" @change="typeChange">
<el-radio label="0">富文本</el-radio>
<el-radio label="1">markdown</el-radio>
</el-radio-group>
<div v-show="editorType == 0" class="quill" ref="quill" :class="classes">
<div class="quill" ref="quill" :class="classes">
<div ref="editor" :style="styles" v-loading="loading"></div>
<Upload :max-size="1000" :limit="100" @beforeUpload="beforeUpload" @onSuccess="editorUploadSuccess"
<el-upload
:headers="headers"
:action="this.api.fileupload"
:before-upload="beforeUpload"
:on-success="editorUploadSuccess"
style="display: none">
<div slot="trigger">
<el-button :id="'editorUpload' + index" type="primary">点击上传</el-button>
</div>
</Upload>
</div>
<mavon-editor class="md" v-model="mdVal" v-show="editorType == 1" ref="md" :ishljs="true" :subfield="false"
@change="mdChange" @imgAdd="imgAdd" />
<el-button class="editorUpload" type="primary">点击上传</el-button>
</el-upload>
</div>
</template>
@ -25,17 +18,9 @@ import 'quill/dist/quill.core.css';
import 'quill/dist/quill.snow.css';
import 'quill/dist/quill.bubble.css';
import toolbarOptions from './options'
import { mavonEditor } from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'
import Upload from '@/components/upload';
import Oss from '@/components/upload/upload.js'
export default {
name: 'quill',
components: {
Upload,
mavonEditor
},
props: {
value: {
type: String,
@ -65,31 +50,13 @@ export default {
*/
elseRead:{
type:String,default:'false'
},
//
index: {
type: Number,
default: 0
},
//
radio: {
type: Boolean,
default: false
},
//
type: {
type: String,
default: '0'
},
}
},
data () {
const that = this
return {
headers: {
token: sessionStorage.getItem('token')
},
editorType: '0',
mdVal: '',
Quill: null,
currentValue: '',
options: {
@ -103,7 +70,7 @@ export default {
'image': function (value) {
if (value) {
// iview
document.querySelector("#editorUpload" + that.index).click();
document.querySelector('.editorUpload').click()
} else {
this.Quill.format('image', false);
}
@ -138,27 +105,20 @@ export default {
},
watch: {
type: {
handler (val) {
this.editorType = val
},
immediate: true
},
value: {
handler (val) {
if (this.type == 0) {
if (val !== this.currentValue) {
this.currentValue = val;
if (this.Quill) {
this.Quill.pasteHTML(this.value);
}
}
}
if (!this.mdVal) this.mdVal = val
},
immediate: true
}
},
created(){
},
mounted () {
this.init();
//
@ -167,7 +127,7 @@ export default {
children.padding = '0'
children.overflow = 'hidden'
children.height = '0'
children.border = '0'
children.borderTop = '0'
}
},
beforeDestroy () {
@ -175,12 +135,6 @@ export default {
this.Quill = null;
},
methods: {
//
typeChange (val) {
this.$emit('update:type', val)
if (!this.mdVal) this.mdVal = this.value
},
init () {
const editor = this.$refs.editor;
//
@ -224,16 +178,20 @@ export default {
if (!file.type.match(/^image\/(gif|jpe?g|a?png|bmp)/i)) {
return
}
// ossbase64
Oss.upload(file).then(res => {
const param = new FormData()
param.append('file', file)
// base64
this.$post(this.api.fileupload, param, {
headers: { "Content-Type": "multipart/form-data" }
}).then(res => {
var range = ins.getSelection()
if (range) {
//
ins.insertEmbed(range.index, 'image', res.url)
ins.insertEmbed(range.index, 'image', res.data.filesResult.fileUrl)
//
ins.setSelection(range.index + 1)
}
})
}).catch(res => {})
});
}
}, false)
@ -241,12 +199,11 @@ export default {
beforeUpload(file){
this.loading = true
},
// quill
editorUploadSuccess (file) {
editorUploadSuccess (res) {
//
let quill = this.Quill
//
if (file.url) {
if (res.data.filesResult.fileUrl) {
//
let lengths;
if ( quill.getSelection() == null){
@ -255,7 +212,7 @@ export default {
lengths = quill.getSelection().index;
}
// res
quill.insertEmbed(lengths, 'image', file.url)
quill.insertEmbed(lengths, 'image', res.data.filesResult.fileUrl)
//
quill.setSelection(lengths + 1)
} else {
@ -263,39 +220,19 @@ export default {
}
this.loading = false
},
//
mdChange (val) {
this.$emit('input', val)
},
// markdown
imgAdd (pos, $file) {
let $vm = this.$refs.md
// oss
Oss.upload($file).then(res => {
$vm.$img2Url(pos, res.url);
})
},
}
}
</script>
<style lang="scss" scoped>
.type-radio {
margin-bottom: 20px;
}
.quill-no-border{
.ql-toolbar.ql-snow{
border: none;
border-bottom: 1px solid #e8eaec;
}
.ql-container.ql-snow{
border: none;
}
}
.else{
.ql-toolbar.ql-snow{
height: 0;
@ -304,10 +241,8 @@ export default {
border-top: 0;
}
}
/deep/.ql-snow {
position: relative;
.ql-tooltip {
position: absolute !important;
top: 0 !important;
@ -315,30 +250,4 @@ export default {
transform: translateY(10px);
}
}
.md {
max-height: 300px;
}
/deep/.v-note-wrapper .v-note-panel {
min-height: 200px;
}
/deep/.markdown-body {
ul {
list-style: disc;
li {
list-style: inherit;
}
}
ol {
list-style: decimal;
li {
list-style: inherit;
}
}
}
</style>

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

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

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

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

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

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

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,17 +1,13 @@
import cookies from './util.cookies'
import {_local,_session} from './util.db'
import { Message } from 'element-ui'
import Setting from '@/setting'
import axios from 'axios'
import api from '@/utils/api'
// 文件后缀集合
const exts = {
video: 'mp4,3gp,mov,m4v,avi,dat,mkv,flv,vob,rmvb,rm,qlv',
audio: 'mp3,aac,ape,flac,wav,wma,amr,mid',
img: 'jpg,jpeg,png,gif,svg,psd',
doc: 'doc,docx,txt,xls,xlsx,csv,xml,ppt,pptx',
compress: 'zip,rar,7z,tar,gz,bz2',
doc: 'doc,docx,txt,xls,xlsx,csv,xml,ppt,pptx'
}
const util = {
cookies,
@ -90,11 +86,6 @@ const util = {
if (exts.doc.includes(ext)) return true;
return false;
},
// 传入文件后缀判断是否是压缩包
isCompress (ext) {
if (exts.compress.includes(ext)) return true;
return false;
},
// 判断是否能够预览
canPreview(ext) {
if (!util.isVideo(ext) && !util.isAudio(ext) && !util.isImg(ext) && !util.isDoc(ext)) return false
@ -161,54 +152,6 @@ const util = {
preZero(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

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

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

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

@ -5,20 +5,16 @@ const url = location.host;
const isDev = process.env.NODE_ENV === 'development' // 开发环境
const isPro = url.includes('huorantech.cn') //正式服
let jumpPath = `${location.origin}/panfen/`
let sandPath = `https://www.occupationlab.com/sandbox` // 沙盘地址
let jumpPath = `${location.origin}/judgmentPoint`
let host = `${location.origin}/`
if (isDev) {
jumpPath = 'http://192.168.31.125:8087/' // 本地调试-需要启动本地判分点系统
// jumpPath = 'https://judgment.huorantech.cn/'
sandPath = `http://${location.hostname}:9520`
host = 'http://121.37.12.51/'
// host = 'https://huorantech.cn/'
const ips = ['http://192.168.31.217:9000/', 'http://192.168.31.51:9000/', 'https://occupationlab.com/']
host = ips[+localStorage.getItem('ip')]
host = 'http://192.168.31.151:9000/'// 榕
// host = 'http://192.168.31.117:9000/'// 赓
} else if (isPro) {
sandPath = `https://izhixinyun.com/sandbox`
// jumpPath = 'https://judgment.huorantech.cn/'
jumpPath = 'https://www.huorantech.cn/judgmentPoint/'
}
@ -28,9 +24,7 @@ const Setting = {
* */
platformId: 3, // 平台标识,1职站,2数据平台,3中台,4合伙人
platformSource: 0, // 平台来源(0中台,1职站)
autoLogoutTime: 1000 * 60 * 60 * 3, // 长时间未操作,自动退出登录时间
jumpPath, // 判分点系统跳转路径前缀
sandPath, // 沙盘地址
apiBaseURL: host, // 请求路径前缀
uploadURL: isDev ? 'http://121.37.12.51/' : location.origin + '/', // 阿里云oss域名
// 平台列表
@ -51,7 +45,7 @@ const Setting = {
isDev,
isPro,
// 是否使用动态路由
dynamicRoute: true,
dynamicRoute: false,
/**
* @description 默认密码
*/

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

@ -1,6 +1,8 @@
import Setting from "@/setting";
const { apiBaseURL: host } = Setting
const host = Setting.apiBaseURL
const uploadURL = Setting.uploadURL
export default {
logins: `users/users/user/login`, //登录
@ -9,19 +11,8 @@ export default {
sendPhoneOrEmailCode: `users/users/userAccount/sendPhoneOrEmailCode`,// 手机验证码
getUserRolesPermissionMenu: `users/users/user-role/getUserRolesPermissionMenu`,
deleteProfile : `users/users/userInfo/deleteProfile`,
refreshPageNotification: `nakadai/message/refreshPageNotification`,
heartbeatDetection: `nakadai/message/heartbeatDetection`,
getCurrentTime: `competition/competition/management/getCurrentTime`,
getToken: `users/users/user/getToken`,
logout: `users/users/user/logout`,
// 阿里云文件/视频管理
getPlayAuth: `nakadai/nakadai/oss/getPlayAuth`, // 获取播放凭证
encrypt: `nakadai/data/encrypt`,
staffTemplate: `https://occupationlab.com/template/%E6%89%B9%E9%87%8F%E5%AF%BC%E5%85%A5%E5%91%98%E5%B7%A5%E6%A8%A1%E6%9D%BF.xlsx`, // 后台账号模板
competionPersonTemplate: `https://www.occupationlab.com/template/中台个人赛报名人员导入模板.xlsx`, // 中台个人报名人员模板
competionTeamTemplate: `https://www.occupationlab.com/template/中台团队赛报名人员导入模板.xlsx`, // 中台团队报名人员模板
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`, // 后台账号模板
checkEmailOrPhone: `occupationlab/occupationlab/architecture/checkEmailOrPhone`, // 新增学生前:校验手机号或者邮箱
checkWorkNumOrAccount: `occupationlab/occupationlab/architecture/checkWorkNumOrAccount`, // 新增/编辑学生前:校验学号或者学生账号
@ -38,7 +29,6 @@ export default {
getOrderOtherTime: `nakadai/nakadai/orderOther/getOrderOtherTime`,
refreshCache: `data/data/myDate/refreshCache`,
getPartnerTeamRates: `nakadai/nakadai/partner-team/getPartnerTeamRates`,
getCustomerOrderRecord: `nakadai/nakadai/order/getCustomerOrderRecord`,
// 客户管理
delCustomers: `nakadai/nakadai/customer/delCustomers`,
@ -53,13 +43,6 @@ export default {
getProductsSubscribedByCustomers: `nakadai/nakadai/customer/getProductsSubscribedByCustomers`,
orderBulkDisableEnable: `nakadai/nakadai/orderOther/orderBulkDisableEnable`,
exportSubscribedRecords: `nakadai/nakadai/order/exportSubscribedRecords`,
addNewCustomersByOneself: `nakadai/nakadai/school/addNewCustomersByOneself`,
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`,
queryCustomerIsExists: `nakadai/nakadai/customer/queryCustomerIsExists`,
@ -71,7 +54,7 @@ export default {
getBusinessManagerOrder: `nakadai/nakadai/customer/getBusinessManagerOrder`,
// 用户管理
delUserAccountsByNakadai: `users/users/userAccount/delUserAccountsByNakadai`,
delUserAccounts: `users/users/userAccount/delUserAccounts`,
queryUserInfoDetails: `users/users/userAccount/queryUserInfoDetails`,
personalFile: `users/users/userAccount/personalFile`,
@ -90,8 +73,7 @@ export default {
oneClickEnableVerification: `users/users/userAccount/oneClickEnableVerification`,
getValueModule: `nakadai/nakadai/valueModuleManagement/getValueModule`,
queryServiceConfig: `nakadai/nakadai/serviceConfiguration/getAllService`,
workbenchSystemDemonstration: `nakadai/nakadai/serviceConfiguration/workbenchSystemDemonstration`,
queryServiceConfig: `nakadai/nakadai/serviceConfiguration/getAllService`, //查询服务配置
// 项目管理
avgValues: `occupationlab/occupationlab/projectManage/avgValues`, // 平均分分配值
deleteProjectManage: `occupationlab/occupationlab/projectManage/deleteProjectManage`, // 新增项目管理
@ -106,8 +88,8 @@ export default {
editProjectDraft: `occupationlab/occupationlab/projectManage/editProjectDraft`, // 修改项目管理
copyProjectManage: `occupationlab/occupationlab/projectManage/copyProjectManage`, // 复制项目管理
// 判分点
getBcJudgmentPoint: `${host}judgment/judgment/bcJudgmentPoint/getBcJudgmentPoint`, // 获取编程类判分点列表(分页)
getLcJudgmentPoint: `${host}judgment/judgment/lcJudgmentPoint/queryAllJudgmentPoint`, // 获取流程类判分点列表(分页)
getBcJudgmentPoint: `judgment/judgment/bcJudgmentPoint/getBcJudgmentPoint`, // 获取编程类判分点列表(分页)
getLcJudgmentPoint: `judgment/judgment/lcJudgmentPoint/queryAllJudgmentPoint`, // 获取流程类判分点列表(分页)
addProjectJudgment: `occupationlab/occupationlab/projectJudgment/addProjectJudgment`, // 添加项目管理、判分点中间表
updateProjectJudgment: `occupationlab/occupationlab/projectJudgment/updateProjectJudgment`, // 判分点中间表批量更新
deleteProjectJudgment: `occupationlab/occupationlab/projectJudgment/deleteProjectJudgment`, // 判分点中间表批量删除
@ -143,12 +125,6 @@ export default {
updateSysModelDemo: `nakadai/nakadai/model/demo/updateSysModelDemo`,
runPythonCode: `nakadai/nakadai/model/demo/runPythonCode`,
getAllModelListBySys: `nakadai/nakadai/model/demo/getAllModelListBySys`,
InstitutionSourceModel: `nakadai/nakadai/model/demo/InstitutionSourceModel`,
disableModelDemo: `nakadai/nakadai/model/demo/disabledEvents`,
copyTheModelToTheNakadai: `nakadai/nakadai/model/demo/copyTheModelToTheNakadai`,
builtInModelButtonDisplayByNakadai: `nakadai/nakadai/model/demo/builtInModelButtonDisplayByNakadai`,
builtInModelState: `nakadai/nakadai/model/demo/builtInModelState`,
modelRedis: `nakadai/nakadai/model/demo/getRedisCache`,
// 课程管理三级联查
courseDiscipline: `nakadai/nakadai/subject/courseDiscipline`, //课程学科类别
@ -156,37 +132,13 @@ export default {
courseProfessional: `nakadai/nakadai/subject/courseProfessional`, //课程专业
//课程管理
curriculumList: `nakadai/nakadai/curriculum/curriculumList`, //课程列表
curriculumTree: `nakadai/nakadai/curriculum/curriculumTree`,
createCurriculum: `nakadai/nakadai/curriculum/createCurriculum`, //创建课程
configureCourseProject: `nakadai/nakadai/curriculum/configureCourseProject`,
curriculumDetail: `nakadai/nakadai/curriculum/curriculumDetail`, //课程详情
modifyCourse: `nakadai/nakadai/curriculum/modifyCourse`, //编辑课程
delCourse: `nakadai/nakadai/curriculum/delCourse`, //单个、批量删除课程
isShelves: `nakadai/nakadai/curriculum/isShelves`, //上下架课程
getInternalProjectBySystemId: `occupationlab/occupationlab/projectManage/getInternalProjectBySystemId`, //根据系统id、项目权限获取系统内置项目
checkConfig: `nakadai/nakadai/curriculum/checkConfig`,
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`, //添加章节
editChapter: `nakadai/nakadai/curriculum/chapter/editChapter`, //修改章节
@ -203,7 +155,6 @@ export default {
delTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/batchDeletion`,
findTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/findById`,
listTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/pageConditionalQueryCourse`,
boutiqueCurriculumTree: `occupationlab/occupationlab/theoreticalCourse/boutiqueCurriculumTree`,
saveTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/save`,
updateTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/update`,
disabledTheoreticalCourse: `occupationlab/occupationlab/theoreticalCourse/disabledEvents`,
@ -230,8 +181,6 @@ export default {
deleteSubsectionTheoretical: `occupationlab/occupationlab/theoreticalCourseSubsection/deleteSubsection`, // 根据id删除小节
editSubsectionTheoretical: `occupationlab/occupationlab/theoreticalCourseSubsection/editSubsection`, // 修改小节
getSubsectionTheoretical: `occupationlab/occupationlab/theoreticalCourseSubsection/getSubsection`, // 根据小节id获取预览文件地址
batchDeletionTheoretical: `occupationlab/occupationlab/theoreticalCourseSubsection/batchDeletion`,
deleteSubsectionBatch: `nakadai/nakadai/curriculum/subsection/deleteSubsectionBatch`,
// 栏目管理
addColumn: `occupationlab/occupationlab/information/column/addColumn`,
@ -249,6 +198,14 @@ export default {
queryArticleByCondition: `occupationlab/occupationlab/information/article/queryArticleByCondition`,
articleSort: `occupationlab/occupationlab/information/article/articleSort`,
// 阿里云文件/视频管理
fileDeletion: `${uploadURL}oss/manage/fileDeletion`, // 删除OSS文件
fileupload: `${uploadURL}oss/manage/fileupload`, // 文件上传
getPlayAuth: `${uploadURL}oss/manage/getPlayAuth`, // 获取播放凭证
removeMoreVideo: `${uploadURL}oss/manage/removeMoreVideo`, // 批量删除视频文件
removeVideo: `${uploadURL}oss/manage/removeVideo`, // 删除视频文件
fileUploadNakadai: `${host}nakadai/nakadai/oss/fileUpload`,
queryProvince: `nakadai/nakadai/province/queryProvince`, //查询省份
queryCity: `nakadai/nakadai/city/queryCity`, //查询城市
@ -282,7 +239,6 @@ export default {
updateProduct: `data/data/product/update`,
saveRecord: `data/data/dataRecord/saveRecord`,
getAllTableIdBycategoryId: `data/data/product/getAllTableIdBycategoryId`,
deleteDataPrompt: `data/data/product/deleteDataPrompt`,
// 关键词
addKeyword: `data/data/keyword/addKeyword`,
@ -323,8 +279,6 @@ export default {
checkRepeat: `nakadai/nakadai/log/checkRepeat`,
logWithdrawal: `nakadai/nakadai/log/logWithdrawal`,
sysLogs: `occupationlab/sys/logs`,
// 合伙人
deleteParner: `nakadai/nakadai/partnerClassification/delete`,
saveParner: `nakadai/nakadai/partnerClassification/save`,
@ -359,23 +313,6 @@ export default {
detailsOfCompetitionStage: `competition/competition/management/detailsOfCompetitionStage`,
entryInformation: `competition/competition/team/entryInformation`,
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`,
@ -423,14 +360,6 @@ export default {
enquireAboutSchoolStudents: `users/users/userAccount/enquireAboutSchoolStudents`,
cancelParticipant: `competition/competition/teamParticipant/cancelParticipant`,
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`,
amendmentAnnouncement: `competition/competition/announcement/amendmentAnnouncement`,
@ -443,12 +372,9 @@ export default {
batchDeleteContestGrade: `competition/competition/performance/batchDeleteContestGrade`,
batchImportGrades: `${host}competition/competition/performance/batchImportGrades`,
exportExperimentalResultsInBatch: `${host}competition/competition/performance/exportExperimentalResultsInBatch`,
exportExamPaperReports: `${host}exam/exam/paper/exportExamPaperReports`,
batchExportReportsAsZip: `${host}occupationlab/occupationlab/achievement/batchExportReportsAsZip`,
performanceExportFailure: `${host}competition/competition/performance/exportFailure`,
rankExportFailure: `${host}competition/competition/rank/exportFailure`,
batchImportRanking: `${host}competition/competition/rank/batchImportRanking`,
getPaperUploadFileZip: `${host}exam/exam/paper/question/userAnswer/getPaperUploadFileZip`,
stageGradeManagementList: `competition/competition/performance/stageGradeManagementList`,
stageRaceRanking: `competition/competition/rank/stageRaceRanking`,
overallStandingsInThePointsRace: `competition/competition/rank/overallStandingsInThePointsRace`,
@ -469,17 +395,6 @@ export default {
toggleTheSortingMode: `competition/competition/rank/toggleTheSortingMode`,
selectTheLastSortStatus: `competition/competition/rank/selectTheLastSortStatus`,
cancelImport: `competition/competition/rank/cancelImport`,
addCompetitionStageRankingTime: `competition/competitionReleaseTime/addCompetitionStageRankingTime`,
cancelCompetitionStageRankingTime: `competition/competitionReleaseTime/cancelCompetitionStageRankingTime`,
getCompetitionStageRankingTime: `competition/competitionReleaseTime/getCompetitionStageRankingTime`,
frontOfficeCompetitionRanking: `competition/competition/rank/frontOfficeCompetitionRanking`,
cCompetitionStageFileList: `competition/cCompetitionStageFile/listByEntity`,
getPaperUploadFile: `exam/exam/paper/question/userAnswer/getPaperUploadFile`,
derive: `${host}competition/cCompetitionStageFile/deriveAll`,
allExperimentalResultsAreDerived: `${host}competition/competition/performance/allExperimentalResultsAreDerived`,
derivedRanking: `${host}competition/competition/rank/derivedRanking`,
individualDerivedRanking: `${host}competition/competition/rank/individualDerivedRanking`,
gradeDownloadExcel: `${host}competition/competition/performance/downloadExcel`,
gradeImport: `https://www.occupationlab.com/template/赛事成绩导入模板.xlsx`,
rankImportTeam: `https://www.occupationlab.com/template/赛事排名导入模板(团队赛).xlsx`,
rankImportPerson: `https://www.occupationlab.com/template/赛事排名导入模板(个人赛).xlsx`,
@ -517,44 +432,4 @@ export default {
saveScheme: `nakadai/nakadai/partner/schemeManagement/save`,
schemeList: `nakadai/nakadai/partner/schemeManagement/schemeList`,
updateScheme: `nakadai/nakadai/partner/schemeManagement/update`,
// 商城管理
addProductCategory: `nakadai/productClassification/addProductCategory`,
deleteProductCategory: `nakadai/productClassification/deleteProductCategory`,
productCategoryList: `nakadai/productClassification/productCategoryList`,
addProductType: `nakadai/productType/addProductType`,
deleteProductType: `nakadai/productType/deleteProductType`,
productTypeList: `nakadai/productType/productTypeList`,
updateProductType: `nakadai/productType/updateProductType`,
addSupplier: `nakadai/supplier/addSupplier`,
deleteSupplier: `nakadai/supplier/deleteSupplier`,
supplierList: `nakadai/supplier/supplierList`,
addTags: `nakadai/tags/addTags`,
deleteTags: `nakadai/tags/deleteTags`,
tagsList: `nakadai/tags/tagsList`,
updateTags: `nakadai/tags/updateTags`,
updateTagsSort: `nakadai/tags/updateTagsSort`,
addGoods: `nakadai/mall/addGoods`,
listOfGoods: `nakadai/mall/listOfGoods`,
deletionOfGoods: `nakadai/mall/deletionOfGoods`,
detailsOfGoods: `nakadai/mall/detailsOfGoods`,
renewalOfGoods: `nakadai/mall/renewalOfGoods`,
goodsOffTheShelf: `nakadai/mall/goodsOffTheShelf`,
goodsSelection: `nakadai/mall/goodsSelection`,
queryCitySettlementPrice: `nakadai/mallPrice/queryCitySettlementPrice`,
allSubjects: `nakadai/productTheme/allSubjects`,
// 营销推广
delMarketing: `nakadai/nakadai/mall/marketing/promotion/batchDeletion`,
findByIdMarketing: `nakadai/nakadai/mall/marketing/promotion/findById`,
listMarketing: `nakadai/nakadai/mall/marketing/promotion/pagingQueryList`,
saveMarketing: `nakadai/nakadai/mall/marketing/promotion/save`,
updateMarketing: `nakadai/nakadai/mall/marketing/promotion/update`,
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`,
};

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

@ -1,276 +0,0 @@
import Oss from '@/components/upload/upload.js'
import { Loading } from 'element-ui'
export default {
//skin:'oxide-dark',
language: 'zh_CN',
language_url: './styles/tinymce/langs/zh_CN.js',
plugins: 'print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help emoticons autoresize',
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 | \
table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | indent2em',
style_formats: [
//新增 首行缩进与行高 配置
{
title: '首行缩进',
block: 'p',
styles: {
'text-indent': '2em'
}
},
{
title: '行高',
items: [{
title: '1',
styles: {
'line-height': '1'
},
inline: 'span'
},
{
title: '1.5',
styles: {
'line-height': '1.5'
},
inline: 'span'
},
{
title: '2',
styles: {
'line-height': '2'
},
inline: 'span'
},
{
title: '2.5',
styles: {
'line-height': '2.5'
},
inline: 'span'
},
{
title: '3',
styles: {
'line-height': '3'
},
inline: 'span'
}
]
},
//默认的配置
{
title: 'headings',
items: [
{
title: 'Heading 1',
format: 'h1'
},
{
title: 'Heading 2',
format: 'h2'
},
{
title: 'Heading 3',
format: 'h3'
},
{
title: 'Heading 4',
format: 'h4'
},
{
title: 'Heading 5',
format: 'h5'
},
{
title: 'Heading 6',
format: 'h6'
}
]
},
{
title: 'Inline',
items: [
{
title: 'Bold',
icon: 'bold',
format: 'bold'
},
{
title: 'Italic',
icon: 'italic',
format: 'italic'
},
{
title: 'Underline',
icon: 'underline',
format: 'underline'
},
{
title: 'Strikethrough',
icon: 'strikethrough',
format: 'strikethrough'
},
{
title: 'Superscript',
icon: 'superscript',
format: 'superscript'
},
{
title: 'Subscript',
icon: 'subscript',
format: 'subscript'
},
{
title: 'Code',
icon: 'code',
format: 'code'
}
]
},
{
title: 'Blocks',
items: [
{
title: 'Paragraph',
format: 'p'
},
{
title: 'Blockquote',
format: 'blockquote'
},
{
title: 'Div',
format: 'div'
},
{
title: 'Pre',
format: 'pre'
}
]
},
{
title: 'Alignment',
items: [
{
title: 'Left',
icon: 'alignleft',
format: 'alignleft'
},
{
title: 'Center',
icon: 'aligncenter',
format: 'aligncenter'
},
{
title: 'Right',
icon: 'alignright',
format: 'alignright'
},
{
title: 'Justify',
icon: 'alignjustify',
format: 'alignjustify'
}
]
}
],
promotion: false,
branding: false,
width: 940,
height: 600, //编辑器高度
min_height: 400,
max_height: 600,
content_css: [ //可设置编辑区内容展示的css,谨慎使用
'./styles/css/editor.css',
],
// content_style: Style,
fontsize_formats: '12px 14px 16px 19px 24px 36px 48px 56px 72px',
font_formats: '苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats;知乎配置=BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei, sans-serif;小米配置=Helvetica Neue,Helvetica,Arial,Microsoft Yahei,Hiragino Sans GB,Heiti SC,WenQuanYi Micro Hei,sans-serif',
link_list: [
{ title: '预置链接1', value: 'http://www.tinymce.com' },
{ title: '预置链接2', value: 'http://tinymce.ax-z.cn' }
],
image_list: [
{ title: '预置图片1', value: 'https://www.tiny.cloud/images/glyph-tinymce@2x.png' },
{ title: '预置图片2', value: 'https://www.baidu.com/img/bd_logo1.png' }
],
image_class_list: [
{ title: 'None', value: '' },
{ title: 'Some class', value: 'class-name' }
],
//为内容模板插件提供预置模板
templates: [],
// content_security_policy: "https://cdn.tiny.cloud/1/rnk6zw9v267xqz7pf98twt1vmrvltmd436je7a642pckltda/tinymce/6/tinymce.min.js",
// extended_valid_elements:'script[src]',
//
// template_cdate_format: '[CDATE: %m/%d/%Y : %H:%M:%S]',
// template_mdate_format: '[MDATE: %m/%d/%Y : %H:%M:%S]',
// autosave_ask_before_unload: false,
toolbar_mode: 'wrap',
// automatic_uploads: true,
// images_upload_base_path: '/demo',
// images_upload_url: 'http://10.10.11.7:10000/iasf/sysFiles/upload',
paste_data_images: true,
powerpaste_allow_local_images: true,
powerpaste_word_import: 'clean',
powerpaste_html_import: 'clean',
urlconverter_callback: (url, node, onSave, name) => {
if (node === 'img' && url.startsWith('blob:')) {
// Do some custom URL conversion
tinymce.activeEditor && tinymce.activeEditor.uploadImages()
}
// Return new URL
return url
},
// 自定义上传
images_upload_handler: function (blobInfo, succFun, failFun) {
const blob = blobInfo.blob()
// blob转换为file
const file = new File([blob], blobInfo.filename(), {
type: 'application/json',
lastModified: Date.now()
});
Oss.upload(file).then(res => {
succFun(res.url)
})
},
//自定义文件选择器的回调内容 此方法只有在点击上方图片按钮才会触发
file_picker_callback: function (callback, value, meta) {
if (meta.filetype === 'file') {
callback('https://www.baidu.com/img/bd_logo1.png', { text: 'My text' });
}
if (meta.filetype === 'image') {
callback('https://www.baidu.com/img/bd_logo1.png', { alt: 'My alt text' });
}
// 主要判断 media
if (meta.filetype === 'media') {
// 动态创建上传input,并进行模拟点击上传操作,达到本地上传视频效果。
let input = document.createElement('input');//创建一个隐藏的input
input.setAttribute('type', 'file');
input.setAttribute("accept", ".mp4");
input.onchange = function () {
let file = this.files[0];
const load = Loading.service()
Oss.upload(file).then(res => {
load.close()
callback(res.url)
}).catch(e => {
load.close()
})
}
//触发点击
input.click();
}
},
// 初始化事件
setup: function (editor) {
editor.on('init', function (ed) {
// 设置默认字体
ed.target.editorCommands.execCommand("fontName", false, "PingFang SC")
ed.target.editorCommands.execCommand("fontSize", false, "16px")
ed.target.editorCommands.execCommand("lineHeight", false, "1.5")
const el = top.document.querySelector('#focus-el')
el && el.focus() // 第一个字段聚焦
})
},
}

@ -6,7 +6,7 @@ import Setting from '@/setting'
axios.defaults.baseURL = Setting.apiBaseURL
// 请求超时时间
axios.defaults.timeout = 3000000000;
axios.defaults.timeout = 30000;
// post请求头
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
@ -30,12 +30,11 @@ axios.interceptors.request.use(config => {
return Promise.reject(err);
})
let logouted = 0;
// 响应拦截器
axios.interceptors.response.use(
response => {
if (response.status === 200) {
const { status, code, msg } = response.data
const { status } = response.data
if (status) {
// 接口定义的非正常返回的时候,应当处于报错状态
if (status === 10020) {
@ -47,22 +46,6 @@ axios.interceptors.response.use(
} else {
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 {
return Promise.resolve(response)
}
@ -79,7 +62,6 @@ axios.interceptors.response.use(
// 未登录则跳转登录页面,并携带当前页面的路径
// 在登录成功后返回当前页面,这一步需要在登录页操作。
case 401:
if (!logouted) {
Message.error('登录过期,请重新登录!');
setTimeout(() => {
router.replace({
@ -89,8 +71,6 @@ axios.interceptors.response.use(
}
});
}, 1000);
logouted = 1
}
break;
// 403 token过期
// 登录过期对用户进行提示

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

@ -13,17 +13,24 @@
<el-menu-item index="1">账号登录</el-menu-item>
<el-menu-item index="2">手机号/邮箱登录</el-menu-item>
</el-menu>
<el-form v-show="activeIndex === '1'" :model="param" :rules="rules" ref="login" label-width="0px"
style="margin-top: 20px">
<el-form v-show="activeIndex==='1'" :model="param" :rules="rules" ref="login" label-width="0px" style="margin-top: 40px">
<el-form-item prop="account">
<el-input @blur="blur" v-model="param.account" placeholder="请输入账号"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password" placeholder="请输入密码" v-model="param.password">
<el-input
type="password"
placeholder="请输入密码"
v-model="param.password"
>
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="showVerify">
<el-input placeholder="请输入验证码" v-model="param.code" @keyup.enter.native="submitForm()">
<el-input
placeholder="请输入验证码"
v-model="param.code"
@keyup.enter.native="submitForm()"
>
</el-input>
<img @click="blur" :src="verificationIMG" class="verification" alt="">
</el-form-item>
@ -36,17 +43,24 @@
</div>
</el-form>
<el-form v-show="activeIndex === '2'" :model="phoneOrEmail" :rules="phoneOrEmailrules" ref="phoneOrEmail"
label-width="0px" style="margin-top: 20px">
<el-form v-show="activeIndex==='2'" :model="phoneOrEmail" :rules="phoneOrEmailrules" ref="phoneOrEmail" label-width="0px" style="margin-top: 40px">
<el-form-item prop="account">
<el-input @blur="phoneBlur" v-model="phoneOrEmail.workNumber" placeholder="请输入电话/邮箱"></el-input>
<el-input @blur="phoneBlur" v-model="phoneOrEmail.account" placeholder="请输入电话/邮箱"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password" placeholder="请输入密码" v-model="phoneOrEmail.password">
<el-input
type="password"
placeholder="请输入密码"
v-model="phoneOrEmail.password"
>
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="showPhoneVerify">
<el-input placeholder="请输入验证码" v-model="phoneOrEmail.code" @keyup.enter.native="submitForm('phone')">
<el-input
placeholder="请输入验证码"
v-model="phoneOrEmail.code"
@keyup.enter.native="submitForm('phone')"
>
</el-input>
<img @click="phoneBlur" :src="PhoneVerificationIMG" class="verification" alt="">
</el-form-item>
@ -70,8 +84,7 @@
<el-form-item label="验证码">
<div style="display:flex;">
<el-input v-model="phoneCode" placeholder="请输入验证码" maxlength="6"></el-input>
<el-button style="margin-left:10px" @click="sendPhoneCode" :disabled="phoneDisabled">{{ phoneBtnText
}}</el-button>
<el-button style="margin-left:10px" @click="sendPhoneCode" :disabled="phoneDisabled">{{phoneBtnText}}</el-button>
</div>
</el-form-item>
</el-form>
@ -80,21 +93,6 @@
<el-button type="primary" @click="phoneSubmit"> </el-button>
</span>
</el-dialog>
<el-dialog title="请选择您要登录的用户" :visible.sync="userVisible" :close-on-click-modal="false" custom-class="user-dia"
width="500px">
<p class="tips">该手机号已绑定以下用户信息</p>
<ul class="users">
<li :class="{ isEnable: !user.isEnable }" v-for="(user, i) in users" :key="i" @click="chooseUser(user)">
<span>{{ user.schoolName }}{{ user.userName }}{{ user.workNumber }}{{
user.isEnable
? ''
: '(已禁用)' }}</span>
<i class="el-icon-right"></i>
</li>
</ul>
</el-dialog>
<v-footer class="footer" ref="footer"></v-footer>
</div>
</template>
@ -103,8 +101,6 @@
import vFooter from '../components/Footer'
import Setting from '@/setting'
import addRoutes from '@/libs/route/addRoutes'
import CryptoJS from 'crypto-js'
import JSEncrypt from 'jsencrypt'
export default {
data: function() {
var regPhoneOrEmail = (rule, value, callback) => {//
@ -132,6 +128,7 @@ export default {
platform:3,
random:'',
distinguish:1,
type: 2
},
rules: {
account: [{ required: true, message: '请输入账号', trigger: 'blur' }],
@ -143,15 +140,16 @@ export default {
showPhoneVerify:true,// -
PhoneVerificationIMG:'',//
phoneOrEmail: {
workNumber: '',
account: '',
password: '',
code:'',
platform:3,
random:'',
distinguish: 1,
distinguish:2,
type: 2
},
phoneOrEmailrules:{
workNumber: [{ validator: regPhoneOrEmail, trigger: 'blur' }],
account: [{ validator: regPhoneOrEmail, trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
code: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
},
@ -162,11 +160,8 @@ export default {
phoneDisabled:false,
phoneBtnText: '发送验证码',
phoneTimer:'',
phoneOpener: '',
phoneOpener:''
userVisible: false,
users: [],
};
},
components: {
@ -200,29 +195,27 @@ export default {
let param = val==='phone'?this.phoneOrEmail:this.param
this.$refs[ref].validate(valid => {
if (valid) {
this.$post(this.api.logins, param).then(({ status, data, message }) => {
localStorage.removeItem('examPath')
localStorage.removeItem('reviewPath')
this.getOss()
if (status == 200) {
const accounts = data.userAccounts
//
if (accounts instanceof Array) {
this.users = accounts
this.userVisible = true
} else {
sessionStorage.setItem('token', data.token)
this.setLogin()
}
} else {
param.code = ''
this.$message.error(message)
this.$post(this.api.logins,param).then(res => {
const { message } = res
sessionStorage.setItem('token',res.data.token)
this.$get(`${this.api.getUserRolesPermissionMenu}?platformId=${Setting.platformId}`).then(res => {
const list = res.permissionMenu
addRoutes(res.permissionMenu[0].children)
this.$store.commit('setDataPer', res.dataPermissionList)
this.$message.success(message);
this.$router.push({
path: list[0].children[0].path
});
localStorage.setItem('ms_username', this.param.username);
}).catch(err => {
if (err.status === 500) {
sessionStorage.clear()
}
})
}).catch(err => {
if(err.status===30001){
this.phoneVisible = true
} else if (err.status == 10004 || err.status == 10005) {
param.code = ''
}else if(err.status == 10004){
this.blur()
}
});
@ -231,55 +224,7 @@ export default {
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(){
this.param.random = Math.floor(Math.random()*999999999)
@ -369,15 +314,13 @@ export default {
background-image: url(../assets/img/login-bg.png);
background-size: 100%;
}
.ms-title {
width: 548px;
position: absolute;
left: 50%;
top: 30px;
top: 50px;
transform: translate(-50%,0);
}
/deep/ .ms-login {
position: relative;
width: 1200px;
@ -387,14 +330,12 @@ export default {
box-shadow:0px 0px 79px 0px rgba(11,15,65,0.36);
background-repeat: no-repeat;
overflow: hidden;
.el-input__inner {
height: 80px;
line-height: 80px;
border: 1px solid rgba(220, 220, 220, 1);
border-radius: 2px;
}
.verification{
position: absolute;
top: 1px;
@ -404,17 +345,14 @@ export default {
cursor: pointer;
}
}
.title{
font-size: 16px;
text-align: center;
font-weight: bold;
}
.login-btn {
text-align: center;
}
.login-btn button {
width: 100%;
height: 88px;
@ -424,24 +362,20 @@ export default {
box-shadow:0px 7px 27px 0px rgba(50,129,255,0.51);
border-radius:10px;
}
.login-tips {
text-align: center;
color: #999;
font-weight:bold;
}
.forget{
margin-bottom: 28px;
text-align: right;
color: #999;
font-weight:bold;
&:hover{
color: #0092ff;
color: #0092FF;
}
}
.thirdParty{
width: 100%;
display: flex;
@ -458,33 +392,27 @@ export default {
align-items: center;
font-size: 18px;
}
.logo{
width: 171px;
height: 40px;
margin-left: 20px;
}
img{
width: 100%;
height: 100%;
}
.header_title{
width: 33%;
display: flex;
justify-content: space-between;
align-items: center;
}
.header_title a{
cursor: pointer;
}
.header_title a:hover{
color: blueviolet;
}
.nul{
width:80px;
margin-right: 30px;
@ -496,74 +424,10 @@ img {
border-bottom: 0;
background-color: transparent;
}
.tips {
margin: -20px 0 20px 5px;
font-size: 14px;
text-align: center;
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) {
/deep/.ms-login {
width: 1000px;
.el-input__inner {
height: 50px;
line-height: 50px;
}
.verification {
height: 48px;
}
}
.ms-title {
width: 480px;
}
.login-btn button {
height: 60px;
}
}
</style>

@ -4,12 +4,13 @@
<el-col :span="24">
<el-card shadow="hover" class="mgb20">
<div class="flex-between">
<div class="per_title" v-preventReClick @click="back">
<div class="per_title" v-preventReClick @click="goback()">
<i class="el-icon-arrow-left"></i>
<span class="per_back">返回</span>
<span class="per_school" v-text="form.cid ? '编辑课程' : '新建课程'"></span>
</div>
<el-button type="primary" round class="mag" v-preventReClick @click="saveAdd">确定
<el-button type="primary" round class="mag" v-preventReClick
@click="saveAdd">确定
</el-button>
</div>
</el-card>
@ -29,30 +30,51 @@
</el-form-item>
<el-form-item label="学科类别" prop="categoryId">
<el-select v-model="form.categoryId" clearable placeholder="请选择学科类别" @change="getProfessionalClass()"
@clear="clearsubjectType()">
<el-option v-for="(item, index) in subjectList" :key="index" :label="item.disciplineName"
:value="item.disciplineId"></el-option>
<el-select v-model="form.categoryId" clearable placeholder="请选择学科类别"
@change="getProfessionalClass()" @clear="clearsubjectType()">
<el-option v-for="(item,index) in subjectList" :key="index"
:label="item.disciplineName" :value="item.disciplineId"></el-option>
</el-select>
</el-form-item>
<el-form-item label="专业" prop="professionalId">
<el-select v-model="form.professionalId" clearable placeholder="请选择专业"
:disabled="form.professionalCategoryId ? false : true">
<el-option v-for="(item, index) in ProfessionalList" :key="index" :label="item.professionalName"
<el-option v-for="(item,index) in ProfessionalList" :key="index"
:label="item.professionalName"
:value="item.professionalId"></el-option>
</el-select>
</el-form-item>
<el-form-item label="供应厂商" prop="supplier">
<el-select v-model="form.supplier" clearable placeholder="请选择供应厂商" multiple>
<el-option v-for="(item, i) in suppliers" :key="i" :label="item.supplierName"
:value="item.supplierId"></el-option>
</el-select>
<el-form-item label="市场单价格" prop="marketPrice">
<el-input placeholder="请输入市场单价格" v-model.trim="form.marketPrice">
<template slot="append">/</template>
</el-input>
</el-form-item>
<el-form-item label="结算方式" prop="settlementMethod" style="width: 800px">
<div class="settlement">
<el-radio v-model="form.settlementMethod" label="0">结算单价</el-radio>
<el-input v-model.trim="form.settlementPrice">
<template slot="append">/</template>
</el-input>
</div>
<div class="settlement">
<el-radio v-model="form.settlementMethod" label="1">比例分成</el-radio>
<span class="label">商务经理占比</span>
<el-input v-model.trim="form.businessProportion" @change="calcProp">
<template slot="append">%</template>
</el-input>
<span class="label">产品厂商占比</span>
<el-input v-model.trim="form.manufacturerProportion" @change="calcProp">
<template slot="append">%</template>
</el-input>
</div>
</el-form-item>
</el-col>
<el-col :span="6" :offset="2">
<el-form-item label="课程类别" prop="curriculumType">
<el-form-item label="课程类别">
<el-select v-model="form.curriculumType" clearable placeholder="请选择课程类型">
<el-option label="理论课程" :value="0"></el-option>
<el-option label="实训课程" :value="1"></el-option>
@ -63,7 +85,8 @@
:disabled="form.categoryId ? false : true" @change="getProfessional()"
@clear="clearProfessionalClass()">
<el-option v-for="(item,index) in ProfessionalClassList" :key="index"
:label="item.professionalClassName" :value="item.professionalClassId"></el-option>
:label="item.professionalClassName"
:value="item.professionalClassId"></el-option>
</el-select>
</el-form-item>
<el-form-item label="预计课时" prop="expectedCourse">
@ -72,9 +95,66 @@
<el-option label="64课时" value="64课时"></el-option>
</el-select>
</el-form-item>
<el-form-item label="供应厂商" prop="supplier">
<el-select v-model="form.supplier" clearable placeholder="请选择供应厂商" multiple>
<el-option v-for="(item, i) in suppliers" :key="i" :label="item.supplierName" :value="item.supplierId"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="14" :offset="5">
<el-form-item label="课程封面" prop="coverUrl">
<el-upload
class="avatar-uploader"
accept=".jpg,.png,.jpeg"
:on-remove="handleRemove"
:on-error="uploadError"
:on-success="uploadSuccess"
:before-remove="beforeRemove"
:limit="1"
:on-exceed="handleExceed"
:action="this.api.fileupload"
:headers="headers"
name="file"
>
<img v-if="form.coverUrl" :src="form.coverUrl" class="avatar">
<div class="uploader-default" v-else>
<i class="el-icon-plus"></i>
<p>上传封面</p>
</div>
<div slot="tip" class="el-upload__tip">
<p>只能上传jpg/png文件</p>
<p>课程封面图将按1:1显示最佳分辨率80*80</p>
</div>
</el-upload>
</el-form-item>
<el-form-item label="小程序图标" prop="miniProgramPictureAddress">
<el-upload
class="avatar-uploader"
accept=".jpg,.png,.jpeg"
:on-remove="handleRemoveMini"
:on-error="uploadError"
:on-success="uploadSuccessMini"
:before-remove="beforeRemove"
:limit="1"
:on-exceed="handleExceed"
:action="this.api.fileupload"
:headers="headers"
name="file"
>
<img v-if="form.miniProgramPictureAddress" :src="form.miniProgramPictureAddress" class="avatar">
<div class="uploader-default" v-else>
<i class="el-icon-plus"></i>
<p>上传封面</p>
</div>
<div slot="tip" class="el-upload__tip">
<p>只能上传jpg/png文件</p>
<p>课程封面图将按1:1显示最佳分辨率80*80</p>
</div>
</el-upload>
</el-form-item>
<el-form-item label="课程简介" prop="briefIntroduction">
<el-input type="textarea" :autosize="{ minRows: 4 }" placeholder="请输入课程简介"
v-model.trim="form.briefIntroduction"></el-input>
@ -88,12 +168,12 @@
</div>
</el-card>
<!-- 练习项目配置 -->
<!-- 练习配置 -->
<el-card shadow="hover" class="mgb20">
<div class="mgb20 flex-between">
<div class="flex-center ">
<p class="addhr_tag"></p>
<span>练习项目配置</span>
<span>练习配置</span>
</div>
<div>
<el-button @click="handleBatchDelete(0)">批量移除</el-button>
@ -102,17 +182,17 @@
</div>
<div class="border-b-dashed"></div>
<div>
<el-table :data="practiceData" class="table" header-align="center" max-height="400"
<el-table :data="practiceData" class="table" stripe header-align="center" max-height="400"
@selection-change="handleSelectionPractice">
<el-table-column type="selection" width="55" align="center"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="projectName" label="项目名称" align="center">
<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">
{{ scope.row.projectName || scope.row.paperName }}
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }}
</template>
</el-table-column>
<el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
<el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
<el-table-column label="排序" align="center" width="100">
<template slot-scope="scope">
<el-input v-model.trim="scope.row.sort"
@ -121,15 +201,17 @@
</el-table-column>
<el-table-column label="展示控制" align="center" width="100">
<template slot-scope="scope">
<el-switch v-model="scope.row.isShow" :active-value="0" :inactive-value="1"
<el-switch
v-model="scope.row.isShow"
:active-value="0"
:inactive-value="1"
:disabled="scope.row.disabled">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="100">
<template slot-scope="scope">
<el-button :disabled="scope.row.disabled"
@click.native.prevent="handleDelete(scope.$index, practiceData)">移除
<el-button :disabled="scope.row.disabled" @click.native.prevent="handleDelete(scope.$index, practiceData)">移除
</el-button>
</template>
</el-table-column>
@ -137,12 +219,12 @@
</div>
</el-card>
<!-- 考核项目配置 -->
<!-- 考核配置 -->
<el-card shadow="hover" class="mgb20">
<div class="mgb20 flex-between">
<div class="flex-center ">
<p class="addhr_tag"></p>
<span>考核项目配置</span>
<span>考核配置</span>
</div>
<div>
<el-button @click="handleBatchDelete(1)">批量移除</el-button>
@ -152,17 +234,17 @@
<div class="border-b-dashed"></div>
<!-- 实训配置 -->
<div>
<el-table :data="assessmentData" class="table" header-align="center" max-height="400"
<el-table :data="assessmentData" class="table" stripe header-align="center" max-height="400"
@selection-change="handleSelectionAssessment">
<el-table-column type="selection" width="55" align="center"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="projectName" label="项目名称" align="center">
<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">
{{ scope.row.projectName || scope.row.paperName }}
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }}
</template>
</el-table-column>
<el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
<el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
<el-table-column label="排序" align="center" width="100">
<template slot-scope="scope">
<el-input v-model.trim="scope.row.sort"
@ -171,27 +253,29 @@
</el-table-column>
<el-table-column label="展示控制" align="center" width="100">
<template slot-scope="scope">
<el-switch v-model="scope.row.isShow" :active-value="0" :inactive-value="1"
<el-switch
v-model="scope.row.isShow"
:active-value="0"
:inactive-value="1"
:disabled="scope.row.disabled">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="100">
<template slot-scope="scope">
<el-button :disabled="scope.row.disabled"
@click.native.prevent="handleDelete(scope.$index, assessmentData)">移除</el-button>
<el-button :disabled="scope.row.disabled" @click.native.prevent="handleDelete(scope.$index, assessmentData)">移除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<!-- 大赛项目配置 -->
<!-- 竞赛配置 -->
<el-card shadow="hover" class="mgb20">
<div class="mgb20 flex-between">
<div class="flex-center ">
<p class="addhr_tag"></p>
<span>大赛项目配置</span>
<span>竞赛配置</span>
</div>
<div>
<el-button @click="handleBatchDelete(2)">批量移除</el-button>
@ -201,16 +285,16 @@
<div class="border-b-dashed"></div>
<!-- 实训配置 -->
<div>
<el-table :data="matches" class="table" header-align="center" max-height="400"
<el-table :data="matches" class="table" stripe header-align="center" max-height="400"
@selection-change="handleSelectionMatch">
<el-table-column type="selection" width="55" align="center"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="projectName" label="项目名称" align="center">
<el-table-column prop="projectName" label="项目名称" align="center"></el-table-column>
<el-table-column prop="applicationName" label="系统名称" align="center">
<template slot-scope="scope">
{{ scope.row.projectName || scope.row.paperName }}
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }}
</template>
</el-table-column>
<el-table-column prop="systemName" label="系统名称" align="center"></el-table-column>
<el-table-column label="排序" align="center" width="100">
<template slot-scope="scope">
<el-input v-model.trim="scope.row.sort"
@ -219,15 +303,17 @@
</el-table-column>
<el-table-column label="展示控制" align="center" width="100">
<template slot-scope="scope">
<el-switch v-model="scope.row.isShow" :active-value="0" :inactive-value="1"
<el-switch
v-model="scope.row.isShow"
:active-value="0"
:inactive-value="1"
:disabled="scope.row.disabled">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="100">
<template slot-scope="scope">
<el-button :disabled="scope.row.disabled"
@click.native.prevent="handleDelete(scope.$index, matches)">移除</el-button>
<el-button :disabled="scope.row.disabled" @click.native.prevent="handleDelete(scope.$index, matches)">移除</el-button>
</template>
</el-table-column>
</el-table>
@ -245,8 +331,7 @@
<p class="addhr_tag"></p>
<span>系统列表</span>
</div>
<el-input placeholder="请输入系统名称" prefix-icon="el-icon-search" v-model.trim="systemKeyword"
clearable></el-input>
<el-input placeholder="请输入系统名称" prefix-icon="el-icon-search" v-model.trim="systemKeyword" clearable></el-input>
<ul class="systems">
<li v-for="(item, i) in systems" :key="i" :title="item.systemName">
@ -264,16 +349,12 @@
<p class="addhr_tag"></p>
<span>项目列表</span>
</div>
<el-input placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model.trim="projectKeyword"
clearable></el-input>
<el-input placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model.trim="projectKeyword" clearable></el-input>
<ul class="systems">
<el-checkbox v-if="projects.length" v-model="checkAll" label="全选"
@change="val => checkAllChange(val, projects[0].systemId)"></el-checkbox>
<el-checkbox v-if="projects.length" v-model="checkAll" label="全选" @change="val => checkAllChange(val, projects[0].systemId)"></el-checkbox>
<li v-for="(item, i) in projects" :key="i" :title="item.projectName">
<el-checkbox v-model="item.check"
:label="item.remark ? item.remark + '(' + item.projectName + ')' : (item.projectName || item.paperName)"
@change="val => projectChange(val, item)"></el-checkbox>
<el-checkbox v-model="item.check" :label="item.remark ? item.remark + '(' + item.projectName + ')' : item.projectName" @change="val => projectChange(val, item)"></el-checkbox>
</li>
</ul>
</div>
@ -283,26 +364,24 @@
<p class="addhr_tag"></p>
<span>已选择项目{{ checkeds.length }}</span>
</div>
<el-input style="width: 200px;margin-bottom: 20px;" placeholder="请输入项目名称" prefix-icon="el-icon-search"
v-model.trim="checkedKeyword" clearable></el-input>
<el-table :data="checkeds" class="table" header-align="center" max-height="470">
<el-input style="width: 200px;margin-bottom: 20px;" placeholder="请输入项目名称" prefix-icon="el-icon-search" v-model.trim="checkedKeyword" clearable></el-input>
<el-table :data="checkeds" 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="systemName" label="系统名称" align="center"></el-table-column>
<el-table-column prop="projectName" width="80" label="系统类型" align="center">
<el-table-column prop="applicationName" label="系统名称" align="center">
<template slot-scope="scope">
{{ scope.row.type === 1 ? '流程类' : scope.row.type === 3 ? '理论' : '编程类' }}
{{ scope.row.applicationName || systemAll.find(e => e.systemId == scope.row.systemId).systemName }}
</template>
</el-table-column>
<el-table-column prop="remark" label="备注名称" align="center"></el-table-column>
<el-table-column prop="projectName" label="项目名称" align="center">
<el-table-column prop="projectName" width="80" label="系统类型" align="center">
<template slot-scope="scope">
{{ scope.row.projectName || scope.row.paperName }}
{{ scope.row.type ? '流程类' : '编程类' }}
</template>
</el-table-column>
<el-table-column prop="remark" 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">
<i :class="['el-icon-delete rm', { disabled: scope.row.disabled }]"
@click="delProject(scope.$index, scope.row)"></i>
<i :class="['el-icon-delete rm', {disabled: scope.row.disabled}]" @click="delProject(scope.$index, scope.row)"></i>
</template>
</el-table-column>
</el-table>
@ -328,17 +407,23 @@ export default {
form: {
cid: this.$route.query.cid,
curriculumName: "",
curriculumType: '',
courseType: "",
categoryId: 1,
professionalCategoryId: 1,
professionalId: 1,
categoryId: "",
professionalCategoryId: "",
professionalId: "",
coverUrl: "",
miniProgramPictureAddress: '',
expectedCourse: "",
marketPrice: "",
briefIntroduction: "",
teachingObjectives: "",
systemIdByAssessment: [],
systemIdByPractice: [],
supplier: []
supplier: '',
businessProportion: '',
manufacturerProportion: '',
settlementPrice: '',
settlementMethod: '0'
},
rules: {
curriculumName: [
@ -350,21 +435,28 @@ export default {
professionalId: [
{ required: true, message: "请选择专业", trigger: "change" }
],
marketPrice: [
{ required: true, message: "请输入市场单价格", trigger: "blur" },
{ pattern: /^(([1-9][0-9]*)|(([0]\.\d{1,2}|[1-9][0-9]*\.\d{1,2})))$/, message: "请输入正确金额格式,可保留两位小数" }
],
supplier: [
{ required: true, message: "请选择供应厂商", trigger: "change" }
{ required: true, message: "请输入供应厂商", trigger: "blur" }
],
settlementMethod: [
{ required: true, message: "请选择结算方式", trigger: "change" }
],
expectedCourse: [
{ required: true, message: "请选择预计课时", trigger: "change" }
],
curriculumType: [
{ required: true, message: "请选择课程类别", trigger: "change" }
],
professionalCategoryId: [
{ required: true, message: "请选择专业类", trigger: "change" }
],
courseType: [
{ required: true, message: "请选择课程类别", trigger: "change" }
],
coverUrl: [
{ required: true, message: "请选择课程封面", trigger: "change" }
],
briefIntroduction: [
{ required: true, message: "请输入课程简介", trigger: "blur" }
],
@ -415,6 +507,7 @@ export default {
systemChecked: [],
curSystem: '',
projects: [],
projectAll: [],
projectKeyword: '',
checkedKeyword: '',
checkeds: [],
@ -441,7 +534,7 @@ export default {
projectKeyword: function(val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.getProject();
this.filterProject();
}, 500);
},
checkedKeyword: function(val) {
@ -477,6 +570,7 @@ export default {
}
this.$nextTick(() => {
this.form = data;
data.miniProgramPictureAddress || this.$set(this.form, 'miniProgramPictureAddress', '')
const pList = data.practiceConfig
const { systemsAll } = this
pList.map(e => {
@ -527,14 +621,13 @@ export default {
},
getSubject() { //
this.$get(this.api.courseDiscipline).then(res => {
this.subjectList = res.list
this.form.categoryId === 1 && this.getProfessionalClass()
this.subjectList = res.list;
}).catch(err => {
});
},
clearsubjectType() { //
this.form.professionalCategoryId = this.form.categoryId === 1 ? 1 : ''
this.form.professionalId = this.form.categoryId === 1 ? 1 : ''
this.form.professionalCategoryId = "",
this.form.professionalId = "";
},
getProfessionalClass() { //
this.clearsubjectType();
@ -546,12 +639,11 @@ export default {
};
this.$get(this.api.courseProfessionalClass, data).then(res => {
this.ProfessionalClassList = res.list;
this.form.professionalCategoryId === 1 && this.getProfessional()
}).catch(err => {
});
},
clearProfessionalClass() { //
this.form.professionalId = this.form.professionalCategoryId === 1 ? 1 : ''
this.form.professionalId = "";
},
getProfessional() { //
this.clearProfessionalClass();
@ -566,6 +658,49 @@ export default {
}).catch(err => {
});
},
//
calcProp() {
const p1 = this.form.businessProportion
const p2 = this.form.manufacturerProportion
if (p1 && p2) {
if(isNaN(p1)) return this.$message.warning('商务经理占比请输入数字')
if(isNaN(p2)) return this.$message.warning('产品厂商占比请输入数字')
if(+p1 + +p2 !== 100) return this.$message.warning('比例分成总和须为100%,请重新修改')
}
},
handleExceed(files, fileList) { //
this.$message.warning("当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!");
},
uploadSuccess(res, file, fileList) { //
this.form.coverUrl = res.data.filesResult.fileUrl;
},
uploadError(err, file, fileList) { //
this.$message({
message: "上传出错,请重试!",
type: "error",
center: true
});
},
beforeRemove(file, fileList) { //
return this.$confirm(`确定移除 ${file.name}`);
},
handleRemove(file, fileList) { //
this.$del(`${this.api.fileDeletion}?keys=${this.form.coverUrl}`).then(res => {
this.form.coverUrl = "";
}).catch(err => {
});
},
uploadSuccessMini(res, file, fileList) { //
this.form.miniProgramPictureAddress = res.data.filesResult.fileUrl;
},
handleRemoveMini(file, fileList) { //
this.$del(`${this.api.fileDeletion}?keys=${this.form.miniProgramPictureAddress}`).then(res => {
this.form.miniProgramPictureAddress = "";
}).catch(err => {
});
},
//
handleConfig(type) {
this.systemKeyword = ''
@ -576,7 +711,6 @@ export default {
this.pageNo = 1;
this.getConfig();
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() {
@ -609,23 +743,26 @@ export default {
}).catch(err => {})
},
//
async getProject (item, fromSystemChange) {
getProject(item) {
const checked = this.checkeds
if (item) this.curSystem = item.systemId
let res
if (!fromSystemChange) {
res = await this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${this.curSystem}&keyword=${this.projectKeyword}`)
}
this.curSystem = item.systemId
this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${item.systemId}`).then(res => {
this.projectAll = JSON.parse(JSON.stringify(res)) //
const result = []
const projects = fromSystemChange ? this.projects : res
projects.map(e => {
res.map(e => {
//
const include = checked.some(n => (e.projectId && n.projectId == e.projectId && n.systemId == e.systemId) || (e.paperId && n.paperId == e.paperId))
const include = checked.some(n => n.projectId == e.projectId && n.systemId == e.systemId)
e.check = include
result.push(e)
})
this.checkAll = !result.filter(e => !e.check).length
this.projects = result
}).catch(err => {})
},
//
filterProject() {
const val = this.projectKeyword
this.projects = this.projectAll.filter(e => e.projectName.includes(val))
},
//
systemChange(val, item) {
@ -637,7 +774,7 @@ export default {
})
}
this.projectKeyword = ''
this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${item.systemId}&keyword=${this.projectKeyword}`).then(res => {
this.$get(`${this.api.getInternalProjectBySystemId}?permissions=${this.permissions}&systemId=${item.systemId}`).then(res => {
if (val) {
//
if (!this.mulSystem) {
@ -645,18 +782,18 @@ export default {
item.check = true
}
res.map(e => {
if (!checkeds.find(n => (e.projectId && n.projectId == e.projectId && n.systemId == e.systemId) || (e.paperId && e.paperId == n.paperId))) {
if (!checkeds.find(n => n.projectId == e.projectId && n.systemId == e.systemId)) {
checkeds.push(e)
}
})
} else {
res.map(e => {
const i = checkeds.findIndex(n => (e.projectId && n.projectId == e.projectId && n.systemId == e.systemId) || (e.paperId && e.paperId == n.paperId))
const i = checkeds.findIndex(n => n.projectId == e.projectId && n.systemId == e.systemId)
i === -1 || checkeds.splice(i, 1)
})
}
this.checkedAll = JSON.parse(JSON.stringify(checkeds)) //
this.getProject(item, 1)
this.getProject(item)
}).catch(err => {})
},
//
@ -668,8 +805,8 @@ export default {
},
//
projectChange(val, item) {
const { systemId, paperId } = item
const i = this.checkeds.findIndex(e => (item.projectId && e.projectId == item.projectId && e.systemId == systemId) || (paperId && paperId == e.paperId))
const { systemId } = item
const i = this.checkeds.findIndex(e => e.projectId == item.projectId && e.systemId == systemId)
// push
if (val) {
this.checkeds.push(item)
@ -682,11 +819,12 @@ export default {
})
this.checkAll = !this.projects.find(e => !e.check) //
this.checkedAll = JSON.parse(JSON.stringify(this.checkeds)) //
console.log("🚀 ~ file: AddCurriculum.vue ~ line 728 ~ projectChange ~ checkedAll", this.checkeds, item)
},
//
filterChecked() {
const val = this.checkedKeyword
this.checkeds = this.checkedAll.filter(e => (e.projectName && e.projectName.includes(val)) || (e.paperName && e.paperName.includes(val)))
this.checkeds = this.checkedAll.filter(e => e.projectName.includes(val))
},
//
delProject(i, e) {
@ -697,9 +835,9 @@ export default {
this.checkeds.splice(i, 1)
// checkdisabled
if (e.systemId == this.curSystem) {
const { projectId, paperId } = e
const { projectId } = e
this.projects.map(n => {
if ((projectId && n.projectId == projectId) || (paperId && n.paperId == paperId)) {
if (n.projectId == projectId) {
n.check = false
}
})
@ -805,21 +943,35 @@ export default {
this.$message.info("已取消移除");
});
},
saveAdd () {
saveAdd(fromBack) {
this.$refs.form.validate((valid) => {
if (valid) {
if (this.submiting) return false
const form = JSON.parse(JSON.stringify(this.form))
const { businessProportion, manufacturerProportion, settlementMethod, settlementPrice } = form
if (settlementMethod == 0) {
if(!settlementPrice) return this.$message.warning('请输入结算单价')
if(isNaN(settlementPrice)) return this.$message.warning('结算单价请输入数字')
} else {
if(!businessProportion) return this.$message.warning('请输入商务经理占比')
if(isNaN(businessProportion)) return this.$message.warning('商务经理占比请输入数字')
if(!manufacturerProportion) return this.$message.warning('请输入产品厂商占比')
if(isNaN(manufacturerProportion)) return this.$message.warning('产品厂商占比请输入数字')
if(+businessProportion + +manufacturerProportion !== 100) return this.$message.warning('比例分成总和须为100%,请重新修改')
}
form.supplier = form.supplier.join()
if (!form.coverUrl) {
this.$message.warning("请上传课程封面");
return;
}
if (!this.practiceData.length) {
this.$message.warning("请添加练习项目配置");
this.$message.warning("请添加练习配置");
return;
} else {
form.systemIdByPractice = this.practiceData.map(i => {
let obj = {
isShow: i.isShow,
projectId: i.projectId || '',
paperId: i.paperId || '',
projectId: i.projectId,
sort: Number(i.sort),
systemId: i.systemId
};
@ -828,14 +980,13 @@ export default {
form.systemIdByPractice.sort((a, b) => a.sort - b.sort)
}
if (!this.assessmentData.length) {
this.$message.warning("请添加考核项目配置");
this.$message.warning("请添加考核配置");
return;
} else {
form.systemIdByAssessment = this.assessmentData.map(i => {
let obj = {
isShow: i.isShow,
projectId: i.projectId,
paperId: i.paperId || '',
sort: Number(i.sort),
systemId: i.systemId
};
@ -843,12 +994,11 @@ export default {
});
form.systemIdByAssessment.sort((a, b) => a.sort - b.sort)
}
//
//
form.systemIdByCompetition = this.matches.map(i => {
let obj = {
isShow: i.isShow,
projectId: i.projectId,
paperId: i.paperId || '',
sort: Number(i.sort),
systemId: i.systemId
};
@ -863,7 +1013,6 @@ export default {
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
})
debugger
if (form.cid) {
this.$post(this.api.modifyCourse, form).then((res) => {
this.$message.success("编辑成功");
@ -874,17 +1023,15 @@ export default {
});
} else {
this.$post(this.api.createCurriculum, form).then((res) => {
this.loadIns.close()
this.$confirm("课程创建成功,是否马上进行课程内容设置?", "提示", {
!fromBack ? this.$confirm("课程创建成功,是否马上进行课程内容设置?", "提示", {
type: "success",
confirmButtonText: "马上设置",
cancelButtonText: "稍后操作",
closeOnClickModal: false
cancelButtonText: "稍后操作"
}).then(() => {
this.$router.push(`/contentSettings?cid=${res.cid}&name=${form.curriculumName}`);
this.$router.push(`/contentSettings?cid=${res.cid}`);
}).catch(() => {
this.$router.push('/curriculum')
})
this.backPage()
}) : this.backPage()
}).catch((res) => {
this.submiting = false
this.loadIns.close()
@ -895,16 +1042,15 @@ export default {
}
});
},
back () {
goback() {
const id = this.form.cid
const updateTime = this.updateTime
//
if ((id && updateTime > 2) || (!id && updateTime)) {
this.$confirm(`编辑的内容未保存,是否保存?`, '提示', {
type: 'warning',
closeOnClickModal: false
type: 'warning'
}).then(() => {
this.saveAdd()
this.saveAdd(1)
}).catch(() => {
this.backPage()
})
@ -914,8 +1060,8 @@ export default {
},
//
backPage() {
this.loadIns && this.loadIns.close()
this.$router.push(this.$store.state.referrer || '/curriculum')
this.$router.back()
this.loadIns.close()
}
}
};
@ -923,7 +1069,6 @@ export default {
<style lang="scss" scoped>
$avatar-width: 104px;
/deep/ .avatar-uploader {
.el-upload {
position: relative;
@ -935,7 +1080,7 @@ $avatar-width: 104px;
overflow: hidden;
&:hover {
border-color: #409eff;
border-color: #409EFF;
}
.uploader-default {
@ -982,34 +1127,28 @@ $avatar-width: 104px;
}
}
}
.settlement {
display: flex;
align-items: center;
margin-bottom: 10px;
.label {
margin-right: 10px;
white-space: nowrap;
color: #606266;
font-size: 14px;
}
.el-input {
width: 150px;
margin-right: 30px;
}
}
/deep/.config-dia {
.config-wrap {
display: flex;
}
.title-wrap {
margin-bottom: 15px;
}
.item {
width: 250px;
max-height: 600px;
@ -1017,22 +1156,18 @@ $avatar-width: 104px;
margin-right: 20px;
overflow: hidden;
}
.system {
background-color: #f9f9f9;
}
.systems {
margin-top: 10px;
max-height: 520px;
max-height: 550px;
overflow: auto;
li {
display: flex;
align-items: center;
margin: 10px 0;
}
.name {
display: inline-flex;
flex: 1;
@ -1040,12 +1175,9 @@ $avatar-width: 104px;
align-items: center;
margin-left: 5px;
cursor: pointer;
&.active,
&:hover {
color: #062c87;
&.active, &:hover {
color: #9076FF;
}
span {
max-width: 200px;
text-overflow: ellipsis;
@ -1054,25 +1186,20 @@ $avatar-width: 104px;
}
}
}
.checked {
flex: 1;
width: auto;
.el-table .cell {
font-size: 12px;
}
}
.rm {
font-size: 14px;
cursor: pointer;
&.disabled {
color: #ccc;
cursor: not-allowed;
}
&:hover {
color: #17161f;
}

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

@ -0,0 +1,317 @@
<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 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.$confirm("确定要删除吗?", "提示", {
type: "warning"
}).then(() => {
this.$post(`${this.api.delCourse}?cids=${row.cid}`).then(res => {
this.getData();
this.$message.success("删除成功");
}).catch(err => {
});
}).catch(() => {
});
},
//
handleSelectionChange(val) {
this.multipleSelection = val;
},
//
delAllSelection() {
if (this.multipleSelection.length) {
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(() => {
});
} 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

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

@ -2,11 +2,12 @@
<div>
<el-card shadow="hover" class="mgb20">
<div class="flex-between">
<el-page-header @back="back" :content="name + '/' + (sorting ? '编辑排序' : '内容设置')"></el-page-header>
<el-page-header @back="goBack" :content="name + '/' + (sorting? '编辑排序' : '内容设置')"></el-page-header>
</div>
</el-card>
<!--内容设置-->
<div class="page mgb20">
<el-card shadow="hover" class="mgb20">
<div class="page">
<div class="relative">
<div class="p-title">内容设置</div>
<div class="btns">
@ -28,23 +29,18 @@
<div>{{ chapter.name }}</div>
<div>
<template v-if="!sorting">
<el-button class="action-btn" plain @click="editChapter(chapter)"
v-auth="'/curriculum:内容设置:修改章节名称'">修改章节名称</el-button>
<el-button class="action-btn" plain @click="addSection(chapter.id)"
v-auth="'/curriculum:内容设置:添加小节'">添加小节</el-button>
<el-button class="action-btn" plain @click="delChapter(chapter.id)"
v-auth="'/curriculum:内容设置:删除章节'">删除</el-button>
<el-button class="action-btn" plain @click="editChapter(chapter)" v-auth="'/curriculum:内容设置:修改章节名称'">修改章节名称</el-button>
<el-button class="action-btn" plain @click="addSection(chapter.id)" v-auth="'/curriculum:内容设置:添加小节'">添加小节</el-button>
<el-button class="action-btn" plain @click="delChapter(chapter.id)" v-auth="'/curriculum:内容设置:删除章节'">删除</el-button>
</template>
<template v-else>
<i class="el-icon-top sort-icon" :class="{ disabled: index == 0 }" style="margin-right: 5px"
@click="sortChapter(chapter, 'up', index == 0, index)"></i>
<i class="el-icon-bottom sort-icon" :class="{ disabled: index == chapters.length - 1 }"
@click="sortChapter(chapter, 'down', index == chapter.length - 1, index)"></i>
<i class="el-icon-top sort-icon" :class="{disabled: index == 0}" style="margin-right: 5px" @click="sortChapter(chapter,'up',index == 0,index)"></i>
<i class="el-icon-bottom sort-icon" :class="{disabled: index == chapters.length-1}" @click="sortChapter(chapter,'down',index == chapter.length-1,index)"></i>
</template>
</div>
</div>
<el-table :data="chapter.subsectionList" class="table" header-align="center" row-key="id">
<el-table :data="chapter.subsectionList" class="table" stripe header-align="center" row-key="id">
<el-table-column v-if="sorting" width="55" align="center">
<template slot-scope="scope">
<el-checkbox v-model="scope.row.check"></el-checkbox>
@ -63,27 +59,20 @@
<template v-if="!sorting">
<el-button type="text" @click="download(scope.row)" v-auth="'/curriculum:内容设置:下载'">下载</el-button>
<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>
<el-button type="text" @click="editSectionName(scope.row, chapter.id)"
v-auth="'/curriculum:内容设置:修改小节名称'">修改小节名称</el-button>
<el-button type="text" @click="switchFile(scope.row, chapter.id)"
v-auth="'/curriculum:内容设置:更换文件'">更换文件</el-button>
<el-button type="text" @click="delSection(scope.row)" v-auth="'/curriculum:内容设置:删除小节'">删除</el-button>
<el-button type="text" @click="editSectionName(scope.row,chapter.id)" v-auth="'/curriculum:内容设置:修改小节名称'">修改小节名称</el-button>
<el-button type="text" @click="switchFile(scope.row,chapter.id)" v-auth="'/curriculum:内容设置:更换文件'">更换文件</el-button>
</template>
<template v-else>
<i class="el-icon-top sort-icon" :class="{ disabled: scope.$index == 0 }" style="margin-right: 5px"
@click="sortSection(index, 'up', scope.$index == 0, scope.$index)"></i>
<i class="el-icon-bottom sort-icon"
:class="{ disabled: scope.$index == chapter.subsectionList.length - 1 }"
@click="sortSection(index, 'down', scope.$index == chapter.subsectionList.length - 1, scope.$index)"></i>
<i class="el-icon-top sort-icon" :class="{disabled: scope.$index == 0}" style="margin-right: 5px" @click="sortSection(index,'up',scope.$index == 0,scope.$index)"></i>
<i class="el-icon-bottom sort-icon" :class="{disabled: scope.$index == chapter.subsectionList.length-1}" @click="sortSection(index,'down',scope.$index == chapter.subsectionList.length-1,scope.$index)"></i>
</template>
</template>
</el-table-column>
</el-table>
</div>
<el-dialog :title="chapterId ? '编辑章节' : '新增章节'" :visible.sync="chapterVisible" width="540px"
:close-on-click-modal="false">
<el-dialog :title="chapterId ? '编辑章节' : '新增章节'" :visible.sync="chapterVisible" width="540px" :close-on-click-modal="false">
<el-form>
<el-form-item>
<el-input placeholder="请输入章节名称,便于对小节归类" v-model="chapterName" maxlength="50"></el-input>
@ -95,20 +84,29 @@
</span>
</el-dialog>
<el-dialog title="添加小节" :visible.sync="sectionVisible" width="540px" @close="closeSection"
:close-on-click-modal="false">
<el-form ref="form" :model="sectionForm" label-width="80px" @submit.native.prevent>
<el-dialog title="添加小节" :visible.sync="sectionVisible" width="540px" @close="closeSection" :close-on-click-modal="false">
<el-form label-width="80px">
<el-form-item label="资源添加">
<Upload :max-size="100000" :file-list="uploadList" :on-remove="handleRemove"
@beforeUpload="beforeUpload" @onSuccess="uploadSuccess">
<template slot="tip">
<p>视频请上传MP4格式大小不超过150Moffice文件大小不要超过10M</p>
</template>
</Upload>
<el-upload
:before-upload="beforeUpload"
:on-remove="handleRemove"
:on-error="uploadError"
:before-remove="beforeRemove"
:limit="1"
:on-exceed="handleExceed"
:action="this.api.fileupload"
:file-list="uploadList"
:headers="headers"
:http-request="handleRequest"
name="file"
>
<el-button size="small"><img src="@/assets/img/upload.png" alt=""> 上传资源</el-button>
<div slot="tip" class="el-upload__tip">视频请上传MP4格式大小不超过30Moffice文件大小不要超过10M</div>
</el-upload>
<el-progress v-if="showProgress" :stroke-width="3" :percentage="progressPercent"></el-progress>
</el-form-item>
<el-form-item label="小节名称">
<el-input placeholder="请输入小节名称" v-model.trim="sectionForm.sectionName" maxlength="50"
@keyup.enter.native="sectionSubmit()"></el-input>
<el-input placeholder="请输入小节名称" v-model="sectionName" maxlength="50"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
@ -117,13 +115,24 @@
</span>
</el-dialog>
<el-dialog title="更换文件" :visible.sync="switchVisible" width="540px" :close-on-click-modal="false"
@close="closeSwitch">
<el-dialog title="更换文件" :visible.sync="switchVisible" width="540px" :close-on-click-modal="false" @close="closeSwitch">
<div style="text-align: center">
<Upload :max-size="100000" :file-list="uploadList" :on-remove="handleRemove" @beforeUpload="beforeUpload"
@onSuccess="uploadSuccess">
<div slot="tip"></div>
</Upload>
<el-upload
:before-upload="beforeUpload"
:on-remove="handleRemove"
:on-error="uploadError"
:before-remove="beforeRemove"
:limit="1"
:on-exceed="handleExceed"
:action="this.api.fileupload"
:file-list="uploadList"
:headers="headers"
:http-request="handleRequest"
name="file"
>
<el-button size="small"><img src="@/assets/img/upload.png" alt=""> 上传资源</el-button>
</el-upload>
<el-progress v-if="showProgress" :stroke-width="3" :percentage="progressPercent"></el-progress>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="switchVisible = false">取消</el-button>
@ -132,10 +141,9 @@
</el-dialog>
<el-dialog title="修改小节名称" :visible.sync="sectionNameVisible" width="540px" :close-on-click-modal="false">
<el-form @submit.native.prevent>
<el-form>
<el-form-item>
<el-input placeholder="请输入小节名称" v-model="sectionForm.sectionName" maxlength="50"
@keyup.enter.native="sectionNameSubmit()"></el-input>
<el-input placeholder="请输入小节名称" v-model="sectionName" maxlength="50"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
@ -144,28 +152,18 @@
</span>
</el-dialog>
<div v-show="previewImg" class="el-image-viewer__wrapper" :class="{ active: previewImg }"
style="z-index: 2000">
<div v-show="previewImg" class="el-image-viewer__wrapper" :class="{active: previewImg}" style="z-index: 2000">
<div class="el-image-viewer__mask"></div>
<span class="el-image-viewer__btn el-image-viewer__close" @click="previewImg = ''"><i
class="el-icon-circle-close" style="color: #fff"></i></span>
<span class="el-image-viewer__btn el-image-viewer__close" @click="previewImg = ''"><i class="el-icon-circle-close" style="color: #fff"></i></span>
<div class="el-image-viewer__canvas">
<img :src="previewImg" class="el-image-viewer__img"
style="transform: scale(1) rotate(0deg);margin-top: -1px; max-height: 100%; max-width: 100%;">
<img :src="previewImg" class="el-image-viewer__img" style="transform: scale(1) rotate(0deg);margin-top: -1px; max-height: 100%; max-width: 100%;">
</div>
</div>
<div v-show="iframeSrc || videoSrc" class="el-image-viewer__wrapper" :class="{ active: iframeSrc }"
style="z-index: 2000">
<div v-show="iframeSrc" class="el-image-viewer__wrapper" :class="{active: iframeSrc}" style="z-index: 2000">
<div class="el-image-viewer__mask"></div>
<span class="el-image-viewer__btn el-image-viewer__close" :class="{ 'doc-close': isWord }"
:style="{ top: isWord ? '50px' : '5px' }" @click="closeIframe"><i class="el-icon-circle-close"
style="color: #fff"></i></span>
<span class="el-image-viewer__btn el-image-viewer__close" :class="{'doc-close': isWord}" :style="{top: isWord ? '50px' : '5px'}" @click="closeIframe"><i class="el-icon-circle-close" style="color: #fff"></i></span>
<div class="el-image-viewer__canvas">
<iframe v-if="iframeSrc" class="fileIframe" id="fileIframe" :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>
<template v-if="showMask">
<div class="mask" style="width: 200px;height: 30px;top: 53px;right: 320px"></div>
<div class="mask" style="width: 175px;height: 30px;top: 53px;right: 5px"></div>
@ -182,14 +180,14 @@
</div>
<div v-show="playAuth" class="el-image-viewer__wrapper" :class="{active: playAuth}" style="z-index: 2000">
<div class="el-image-viewer__mask"></div>
<span class="el-image-viewer__btn el-image-viewer__close" @click="closePlayer"><i
class="el-icon-circle-close" style="color: #fff"></i></span>
<span class="el-image-viewer__btn el-image-viewer__close" @click="closePlayer"><i class="el-icon-circle-close" style="color: #fff"></i></span>
<div class="player" id="player"></div>
</div>
<Pdf :visible.sync="pdfVisible" :src.sync="pdfSrc" />
<pdf :visible.sync="pdfVisible" :src.sync="pdfSrc"></pdf>
</div>
</div>
</el-card>
<div class="player-download" id="playerDownload"></div>
<el-dialog title="资源移动" :visible.sync="moveVisible" :close-on-click-modal="false" width="330px">
@ -215,11 +213,8 @@
<script>
import { Loading } from "element-ui";
import Pdf from "@/components/pdf";
import Upload from '@/components/upload';
import Oss from '@/components/upload/upload.js'
import Util from '@/libs/util'
import pdf from "@/components/pdf";
import axios from 'axios'
export default {
name: "contentSettings",
data() {
@ -243,21 +238,11 @@ export default {
sectionId: "",
switchVisible: false,
sectionNameVisible: false,
rules: {
sectionName: [
{ required: true, message: "请输入小节名称", trigger: "blur" }
],
},
sectionForm: {
sectionName: ''
},
fileId: "",
fileName: "",
fileUrl: "",
originalFileName: "",
fileType: "",
videoSrc: '',
playAuth: "",
player: null,
previewImg: "",
@ -295,18 +280,18 @@ export default {
moved: false //
};
},
components: { Pdf, Upload },
components: { pdf },
mounted() {
this.insertScript();
this.id && this.getData();
//
if (window.history && window.history.pushState) {
history.pushState(null, null, document.URL);
window.addEventListener("popstate", this.back, false);
window.addEventListener("popstate", this.goBack, false);
}
},
destroyed() {
window.removeEventListener("popstate", this.back, false);
window.removeEventListener("popstate", this.goBack, false);
},
methods: {
getData() {
@ -322,7 +307,7 @@ export default {
handleSelectionChange(val) {
this.multipleSelection = val
},
back () {
goBack() {
//
if (this.previewing) {
this.closeIframe();
@ -332,8 +317,7 @@ export default {
//
if (this.moved) {
this.$confirm(`编辑的内容未保存,是否保存?`, '提示', {
type: 'warning',
closeOnClickModal: false
type: 'warning'
}).then(() => {
this.saveSort()
this.moved = false
@ -345,7 +329,7 @@ export default {
this.sorting = false
}
} else {
this.$router.push(this.$store.state.referrer || '/curriculum')
this.$router.back()
}
}
},
@ -382,10 +366,19 @@ export default {
},
//
beforeUpload(file) {
let type = this.transferType(file.name.substring(file.name.lastIndexOf(".") + 1));
// if (type != "" && type != "" && type != "pdf" && (file.size / 1024 / 1024) > 10) {
// this.$message.error("10M");
// return false;
// }
// if (type == "" && (file.size / 1024 / 1024) > 30) {
// this.$message.warning('30M')
// return false;
// }
this.uploading = true;
this.originalFileName = file.name;
if (this.isAddSection) this.sectionForm.sectionName = file.name.substring(0, file.name.lastIndexOf("."));
this.fileType = Util.getFileExt(file.name)
if (this.isAddSection) this.sectionName = file.name.substring(0, file.name.lastIndexOf("."));
this.fileType = file.name.substring(file.name.lastIndexOf(".") + 1);
this.showProgress = true
},
handleExceed(files, fileList) {
@ -393,12 +386,33 @@ export default {
`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`
);
},
uploadSuccess (file) {
//
handleRequest(data) {
const param = new FormData()
param.append('file', data.file)
const config = {
timeout: 10000000000,
headers: {
'Accept': '*/*',
'Content-Type': 'multipart/form-data'
},
//
onUploadProgress: progressEvent => {
const per = Number((progressEvent.loaded / progressEvent.total * 100).toFixed(2))
console.log("🚀 ~ file: contentSettings.vue ~ line 329 ~ handleRequest ~ per", per, this.progressPercent)
if (this.progressPercent <= 80) this.progressPercent = (per > 80) ? (Math.random() * 10 + 80).toFixed(2) : per
}
}
axios.post(this.api.fileupload, param, config).then(res => {
this.progressPercent = 100
this.showProgress = false
const { fileId, fileType, fileUrl, ossFileName } = res.data.data.filesResult
this.uploading = false
this.fileId = ''
this.fileType = file.format
this.fileUrl = file.url
this.fileName = file.name
this.fileId = fileId
this.fileType = fileType
this.fileUrl = fileUrl
this.fileName = ossFileName
})
},
uploadError(err, file, fileList) {
this.$message({
@ -412,9 +426,8 @@ export default {
return this.$confirm(`确定移除 ${file.name}`);
}
},
handleRemove () {
Oss.del(this.fileUrl)
this.fileUrl = ''
handleRemove(file, fileList) {
this.uploadList = fileList;
},
uploadSure() {
this.importVisible = false;
@ -546,8 +559,11 @@ export default {
this.$del(`${this.api.deleteChapter}/${id}`).then(res => {
this.$message.success("删除成功");
this.getData();
}).catch(res => { });
}).catch(() => { });
}).catch(res => {
});
})
.catch(() => {
});
},
closeSection() {
this.isAddSection = false;
@ -555,7 +571,7 @@ export default {
},
addSection(id) {
this.chapterId = id;
this.sectionForm.sectionName = "";
this.sectionName = "";
this.fileUrl = "";
this.uploadList = [];
this.sectionId = "";
@ -587,15 +603,15 @@ export default {
});
}
},
sectionSubmit (e) {
if (!this.sectionForm.sectionName) return this.$message.warning("请填写小节名称");
sectionSubmit() {
if (!this.sectionName) return this.$message.warning("请填写小节名称");
if (this.uploading) return this.$message.warning("资源正在上传中,请稍候");
if (!this.fileUrl && !this.fileId) return this.$message.warning("请上传资源");
let data = {
id: this.sectionId,
cid: this.id,
chapterId: this.chapterId,
name: this.sectionForm.sectionName,
name: this.sectionName,
fileId: this.fileId,
fileUrl: this.fileUrl,
fileName: this.fileName,
@ -608,7 +624,7 @@ export default {
this.getData();
})
.catch(err => {
})
});
},
closeSwitch() {
this.fileId = "";
@ -620,19 +636,19 @@ export default {
},
//
download(row) {
const { fileType, fileId } = row
const { fileType } = row
// ppt
if (fileType === 'pptx') {
this.downloadFile(row.originalFileName || row.name, row.fileUrl)
} else if (fileId) {
//
this.$get(`${this.api.getPlayAuth}/${fileId}`).then(res => {
new Aliplayer({
this.downloadFile(row.name, row.fileUrl)
} else if (fileType === 'mp4') {
//
this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => {
const player = new Aliplayer({
id: "playerDownload",
width: "100%",
autoplay: false,
vid: fileId,
playauth: res.playAuth,
vid: row.fileId,
playauth: res.data.playAuth,
encryptType: 1 //
}, player => {
this.downloadFile(row.name, player._urls[0].Url)
@ -644,10 +660,8 @@ export default {
},
preview(row) {
if (this.transferType(row.fileType) == "视频") {
//
if (row.fileId) {
this.$get(`${this.api.getPlayAuth}/${row.fileId}`).then(res => {
this.playAuth = res.playAuth;
this.playAuth = res.data.playAuth;
if (this.player) {
this.player.replayByVidAndPlayAuth(row.fileId, this.playAuth);
} else {
@ -660,10 +674,8 @@ export default {
encryptType: 1 //
});
}
}).catch(res => { });
} else {
this.videoSrc = row.fileUrl
}
}).catch(res => {
});
} else if (this.transferType(row.fileType) == "图片") {
this.previewImg = row.fileUrl;
} else if (row.fileType == "pdf") {
@ -703,7 +715,7 @@ export default {
editSectionName(row, chapterId) {
this.chapterId = chapterId;
this.sectionId = row.id;
this.sectionForm.sectionName = row.name;
this.sectionName = row.name;
this.sectionNameVisible = true;
},
switchFile(row, chapterId, sectionId) {
@ -716,7 +728,7 @@ export default {
};
this.chapterId = chapterId;
this.sectionId = row.id;
this.sectionForm.sectionName = row.sectionName;
this.sectionName = row.sectionName;
this.switchVisible = true;
},
@ -725,7 +737,7 @@ export default {
id: this.sectionId,
cid: this.id,
chapterId: this.chapterId,
name: this.sectionForm.sectionName,
name: this.sectionName,
fileId: this.fileId,
fileName: this.fileName,
fileType: this.fileType,
@ -743,7 +755,20 @@ export default {
switchSubmit() {
if (this.uploading) return this.$message.warning("资源正在上传中,请稍候");
if (!this.fileUrl && !this.fileId) return this.$message.warning("请上传资源");
if (this.transferType(this.curFile.fileType) == "视频") {
let data = {
videoIdList: [this.sectionId]
};
this.$del(`${this.api.removeVideo}/${this.curFile.fileId}`).then(res => {
this.switchSubmitFile();
}).catch(res => {
});
} else {
this.$del(`${this.api.fileDeletion}?keys=${this.curFile.fileName}`).then(res => {
this.switchSubmitFile();
}).catch(res => {
});
}
},
delSection(row) {
this.$confirm("此删除操作不可逆,是否确认删除选中项?", "提示", {
@ -751,7 +776,6 @@ export default {
})
.then(() => {
this.$del(`${this.api.deleteSubsection}/${row.id}`).then(res => {
row.fileUrl && Oss.del(row.fileUrl)
this.$message.success("删除成功");
this.getData();
}).catch(res => {
@ -786,12 +810,12 @@ export default {
}
},
sectionNameSubmit() {
if (!this.sectionForm.sectionName) return this.$message.warning("请填写小节名称");
if (!this.sectionName) return this.$message.warning("请填写小节名称");
let data = {
id: this.sectionId,
cid: this.id,
chapterId: this.chapterId,
name: this.sectionForm.sectionName
name: this.sectionName
};
this.$put(this.api.editSubsection, data).then(res => {
this.$message.success("修改成功");
@ -807,7 +831,6 @@ export default {
},
closeIframe() {
this.iframeSrc = "";
this.videoSrc = ''
this.showMask = false;
this.showMask1 = false;
this.showMask2 = false;
@ -822,11 +845,10 @@ export default {
max-height: calc(100vh - 420px);
overflow: auto;
}
.action-btn{
color: #062c87;
color: #9076FF;
font-size: 14px;
border: #062c87 1px solid;
border: #9076FF 1px solid;
background-color: #fff;
border-radius: 4px;
}
@ -847,15 +869,13 @@ export default {
&.disabled {
color: #ccc;
cursor: not-allowed;
cursor: not-allowed
}
}
/deep/.el-progress-bar {
padding-right: 70px;
margin-right: -70px;
}
.el-upload__tip {
position: absolute;
top: -4px;
@ -863,13 +883,12 @@ export default {
width: 300px;
line-height: 1.4;
}
.el-image-viewer__wrapper {
transform: translateY(-10px);
transition: transform 0.5s;
transition: transform .5s;
&.active {
transform: translateY(0);
transform: translateY(0)
}
}
@ -893,7 +912,6 @@ export default {
width: 1200px !important;
height: 600px !important;
}
.player-download {
position: absolute;
top: -9999px;
@ -973,7 +991,7 @@ export default {
margin-right: 6px;
font-size: 14px;
line-height: 14px;
color: rgba(0, 0, 0, 0.65);
color: rgba(0, 0, 0, .65);
white-space: nowrap;
}
}

File diff suppressed because it is too large Load Diff

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

@ -5,96 +5,74 @@
<div class="per_title" v-preventReClick @click="goback(0)">
<i class="el-icon-arrow-left"></i>
<span class="per_back">返回</span>
<span v-if="form.customerName || !customerId" class="per_school"
v-text="isDetail ? form.customerName + '/查看' : (customerId ? form.customerName + '/编辑' : '新增')"></span>
<span v-if="form.customerName || !customerId" class="per_school" v-text="isDetail ? form.customerName + '/查看' : (customerId ? form.customerName + '/编辑' : '新增')"></span>
</div>
</div>
</el-card>
<el-card shadow="hover" class="card">
<div class="tabs" v-if="customerId">
<a class="item" v-for="(item, i) in tabs" :key="i" :class="{ active: i == curTab }" @click="tabChange(i)">{{
item
}}</a>
<a class="item" v-for="(item, i) in tabs" :key="i" :class="{active: i == curTab}" @click="tabChange(i)">{{ item }}</a>
</div>
<div v-show="curTab === 'tab1'">
<el-form :model="form" :rules="rules" ref="form" label-width="120px" class="flex-start-around info"
:disabled="isDetail">
<el-form :model="form" :rules="rules" ref="form" label-width="120px" class="flex-start-around info" :disabled="isDetail">
<el-col :span="6" style="margin-right: 60px;">
<el-form-item prop="countries" label="国家">
<el-select v-model="form.countries" clearable placeholder="请选择国家">
<el-option v-for="(item, index) in countryList" :key="index" :label="item.name"
:value="item.name"></el-option>
<el-option v-for="(item,index) in countryList" :key="index" :label="item.name" :value="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="schoolId" label="客户名称">
<div class="flex a-center">
<el-select v-model="form.schoolId" filterable clearable placeholder="请选择学校" :disabled="!!customerId"
@change="SchoolChange" @clear="clearSchool">
<el-option v-for="(item, index) in schoolList" :key="index" :label="item.schoolName"
:value="item.schoolId"></el-option>
<el-select v-model="form.schoolId" filterable clearable placeholder="请选择学校" :disabled="customerId" @change="SchoolChange" @clear="clearSchool">
<el-option v-for="(item,index) in schoolList" :key="index" :label="item.schoolName" :value="item.schoolId"></el-option>
</el-select>
<!-- <i v-if="!isDetail"
class="el-icon-circle-plus-outline plus-cus"
@click="addCustomer"></i> -->
<el-button v-if="!isDetail" style="margin-left: 5px" type="primary" size="mini"
@click="setCustomer">设置</el-button>
</div>
</el-form-item>
<el-form-item prop="cityId" label="城市">
<el-select v-model="form.cityId" placeholder="" disabled>
<el-option v-for="(item, index) in cityList" :key="index" :label="item.cityName"
:value="item.cityId"></el-option>
<el-option v-for="(item,index) in cityList" :key="index" :label="item.cityName" :value="item.cityId"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="industryId" label="行业">
<el-select v-model="form.industryId" clearable placeholder="请选择行业"
:disabled="form.industryClassId ? false : true">
<el-option v-for="(item, index) in industryList" :key="index" :label="item.industryName"
:value="item.industryId"></el-option>
<el-select v-model="form.industryId" clearable placeholder="请选择行业" :disabled="form.industryClassId ? false : true">
<el-option v-for="(item,index) in industryList" :key="index" :label="item.industryName" :value="item.industryId"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="account" label="账号">
<el-input placeholder="请输入账号" v-model.trim="form.account"></el-input>
<el-input placeholder="请输入账号" v-model="form.account"></el-input>
</el-form-item>
<el-form-item label="职务">
<el-input placeholder="请输入职务名称" v-model.trim="form.position" maxlength="11"></el-input>
<el-input placeholder="请输入职务名称" v-model="form.position" maxlength="11"></el-input>
</el-form-item>
<el-form-item label="产品到期时间">
<el-date-picker type="date" disabled v-model="form.expireDate" style="width: 100%;"
value-format="yyyy-MM-dd"></el-date-picker>
<el-date-picker type="date" disabled v-model="form.expireDate" style="width: 100%;" value-format="yyyy-MM-dd"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="6" style="margin-left: 60px;">
<el-form-item label="客户类型">
<el-select v-model="form.customerType" placeholder="下单后客户类型自动补充" disabled>
<el-option v-for="(item, index) in customerTypeList" :key="index" :label="item.name"
:value="item.value"></el-option>
<el-option v-for="(item,index) in customerTypeList" :key="index" :label="item.name" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="provinceId" label="省份">
<el-select v-model="form.provinceId" placeholder="" disabled>
<el-option v-for="(item, index) in provinceList" :key="index" :label="item.provinceName"
:value="item.provinceId"></el-option>
<el-option v-for="(item,index) in provinceList" :key="index" :label="item.provinceName" :value="item.provinceId"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="industryClassId" label="行业类型">
<el-select v-model="form.industryClassId" clearable placeholder="请选择行业类型" @change="changIndustry"
@clear="clearIndustry()">
<el-option v-for="(item, index) in IndustryClassList" :key="index" :label="item.industryClassName"
:value="item.industryClassId"></el-option>
<el-select v-model="form.industryClassId" clearable placeholder="请选择行业类型" @change="changIndustry" @clear="clearIndustry()">
<el-option v-for="(item,index) in IndustryClassList" :key="index" :label="item.industryClassName" :value="item.industryClassId"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="name" label="联系人姓名">
<el-input placeholder="请输入联系人姓名" v-model.trim="form.name"></el-input>
<el-input placeholder="请输入联系人姓名" v-model="form.name"></el-input>
</el-form-item>
<el-form-item prop="phone" label="手机号">
<el-input placeholder="请输入联系人手机号" v-model.trim="form.phone" maxlength="11"></el-input>
<el-input placeholder="请输入联系人手机号" v-model="form.phone" maxlength="11"></el-input>
</el-form-item>
<el-form-item prop="email" label="邮箱">
<el-input placeholder="请输入邮箱" v-model.trim="form.email"></el-input>
<el-input placeholder="请输入邮箱" v-model="form.email"></el-input>
</el-form-item>
</el-col>
</el-form>
@ -108,38 +86,34 @@
<div class="tool">
<ul class="filter">
<li>
<label>产品分类</label>
<el-select v-model="form2.productType" placeholder="请选择产品类型" clearable @change="filterForm2">
<el-option v-for="(item, index) in productTypeList" :key="index" :label="item.classificationName"
:value="item.classificationId"></el-option>
<label>产品类型</label>
<el-select v-model="form2.productType" placeholder="请选择产品类型" @change="filterForm2">
<el-option v-for="(item,index) in productTypeList" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
<li>
<label>订阅状态</label>
<el-select v-model="form2.status" placeholder="请选择订阅状态" @change="filterForm2">
<el-option v-for="(item, index) in subStatusList" :key="index" :label="item.name"
:value="item.name"></el-option>
<el-option v-for="(item,index) in subStatusList" :key="index" :label="item.name" :value="item.name"></el-option>
</el-select>
</li>
<li>
<el-input style="width: 250px;" placeholder="请输入产品名称" prefix-icon="el-icon-search" clearable
v-model="form2.keyword"></el-input>
<el-input style="width: 250px;" placeholder="请输入产品名称" prefix-icon="el-icon-search" clearable v-model="form2.keyword"></el-input>
</li>
</ul>
<div>
<el-button type="primary" @click="exportList">导出列表</el-button>
</div>
</div>
<el-table :data="products" class="orderTable" header-align="center" @selection-change="handleSelectionChange"
row-key="id">
<el-table :data="products" class="orderTable" stripe header-align="center" @selection-change="handleSelectionChange" row-key="dataOrCourseId">
<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="goodsName" label="产品名称" align="center"></el-table-column>
<el-table-column prop="productTypeName" label="产品类" align="center"></el-table-column>
<el-table-column prop="productName" label="产品名称" align="center"></el-table-column>
<el-table-column prop="productTypeName" label="产品类" align="center"></el-table-column>
<el-table-column label="起止日期" align="center">
<template slot-scope="scope">
{{ scope.row.status === '已过期' ? '-' : scope.row.startAndEndTime }}
{{ scope.row.status === '已过期' ? '' : scope.row.startAndEndTime }}
<el-tooltip v-if="scope.row.other" class="item" effect="dark" placement="top">
<div slot="content">
还有<span v-html="scope.row.other"></span><br>的订单还未生效
@ -156,15 +130,12 @@
<el-table-column prop="status" label="订阅状态" align="center"></el-table-column>
<el-table-column label="产品状态" align="center">
<template slot-scope="scope">
<el-switch v-model="scope.row.isEnable" :active-value="1" :inactive-value="0"
:active-text="scope.row.isEnable ? '启用' : '禁用'" :disabled="scope.row.status === '已过期'"
@change="switchOff($event, scope.row, scope.$index)"></el-switch>
<el-switch v-model="scope.row.isEnable" :active-value="1" :inactive-value="0" :active-text="scope.row.isEnable ? '启用' : '禁用'" :disabled="scope.row.status === '已过期'" @change="switchOff($event,scope.row,scope.$index)"></el-switch>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total, prev, pager, next" @current-change="handleCurrentChangeProduct"
:current-page="pageProduct" :page-size="pageSizeProduct" :total="totalProduct"></el-pagination>
<el-pagination background layout="total, prev, pager, next" @current-change="handleCurrentChangeProduct" :current-page="pageProduct" :page-size="pageSizeProduct" :total="totalProduct"></el-pagination>
</div>
</div>
@ -173,34 +144,29 @@
<ul class="filter">
<li>
<label>订单类型</label>
<el-select v-model="form3.orderType" clearable placeholder="请选择订单类型" @change="initOrder">
<el-option v-for="(item, index) in orderTypeList" :key="index" :label="item.name"
:value="item.value"></el-option>
<el-select v-model="form3.orderType" clearable placeholder="请选择订单类型" @change="getOrder">
<el-option v-for="(item,index) in orderTypeList" :key="index" :label="item.name" :value="item.value"></el-option>
</el-select>
</li>
<li>
<label>订单状态</label>
<el-select v-model="form3.orderStatus" clearable placeholder="请选择订单状态" @change="initOrder">
<el-option v-for="(item, index) in orderStatusList" :key="index" :label="item.name"
:value="item.id"></el-option>
<el-select v-model="form3.orderStatus" clearable placeholder="请选择订单状态" @change="getOrder">
<el-option v-for="(item,index) in orderStatusList" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</li>
</ul>
<div>
<el-input style="width: 250px;" placeholder="请输入订单编号、内容" prefix-icon="el-icon-search" clearable
v-model="form3.keyword"></el-input>
<el-input style="width: 250px;" placeholder="请输入订单编号、内容" prefix-icon="el-icon-search" clearable v-model="form3.keyword"></el-input>
</div>
</div>
<el-table :data="orders" class="orderTable" header-align="center" @selection-change="handleSelectionChange"
row-key="orderId">
<el-table :data="orders" class="orderTable" stripe header-align="center" @selection-change="handleSelectionChange" row-key="orderId">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center">
</el-table-column>
<el-table-column prop="orderNumber" label="订单编号" align="center"></el-table-column>
<el-table-column prop="orderContent" label="订单内容" align="center">
<template slot-scope="scope">
<el-popover trigger="hover" placement="top" style='width: 500px'
v-if='scope.row.orderContent && scope.row.orderContent.length > 14'>
<el-popover trigger="hover" placement="top" style='width: 500px' v-if='scope.row.orderContent.length >14'>
<p> {{ scope.row.orderContent }}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium" class='tags'>{{ scope.row.orderContent }}</el-tag>
@ -222,19 +188,17 @@
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total, prev, pager, next" @current-change="handleCurrentChangeOrder"
:current-page="pageOrder" :page-size="pageSizeOrder" :total="totalOrder"></el-pagination>
<el-pagination background layout="total, prev, pager, next" @current-change="handleCurrentChangeOrder" :current-page="pageOrder" :page-size="pageSizeOrder" :total="totalOrder"></el-pagination>
</div>
</div>
<div v-show="curTab === 'tab4'">
<div class="tool">
<div>
<el-input style="width: 350px;" placeholder="请输入订单编号、合同名称、合同编号、产品内容" prefix-icon="el-icon-search"
clearable></el-input>
<el-input style="width: 350px;" placeholder="请输入订单编号、合同名称、合同编号、产品内容" prefix-icon="el-icon-search" clearable></el-input>
</div>
</div>
<el-table :data="contractInformations" class="table" header-align="center">
<el-table :data="contractInformations" class="table" stripe header-align="center">
<el-table-column type="index" width="100" label="序号" align="center">
</el-table-column>
<el-table-column prop="contractNumber" label="订单号" align="center"></el-table-column>
@ -243,8 +207,7 @@
</el-table-column>
<el-table-column prop="endTime" label="合同期限" align="center">
<template slot-scope="scope">
{{ scope.row.startTime ? scope.row.startTime.split('').shift() : ''
}}&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;{{ scope.row.endTime ? scope.row.endTime.split('').shift() : '' }}
{{scope.row.startTime?scope.row.startTime.split(' ').shift():''}}&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;{{scope.row.endTime?scope.row.endTime.split(' ').shift():''}}
</template>
</el-table-column>
<el-table-column prop="dataOrCourseName" label="产品内容" align="center">
@ -266,11 +229,10 @@
<div v-show="curTab === 'tab5'">
<div class="tool">
<div>
<el-input style="width: 300px;" placeholder="请输入商务经理、手机号" prefix-icon="el-icon-search" clearable
v-model="bmsKeyword"></el-input>
<el-input style="width: 300px;" placeholder="请输入商务经理、手机号" prefix-icon="el-icon-search" clearable v-model="bmsKeyword"></el-input>
</div>
</div>
<el-table :data="bms" class="table" header-align="center">
<el-table :data="bms" class="table" stripe header-align="center">
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="userName" label="姓名" width="200" align="center">
<template slot-scope="scope">
@ -293,8 +255,7 @@
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total, prev, pager, next" @current-change="handleCurrentChangeBm"
:current-page="pageBm" :page-size="pageSizeBm" :total="totalBm"></el-pagination>
<el-pagination background layout="total, prev, pager, next" @current-change="handleCurrentChangeBm" :current-page="pageBm" :page-size="pageSizeBm" :total="totalBm"></el-pagination>
</div>
</div>
</el-card>
@ -302,82 +263,14 @@
<el-dialog :visible.sync="showImg" width="70%" center>
<img :src="fileSrc" width="100%" alt="">
</el-dialog>
<el-dialog :title="curRow ? '编辑客户' : '添加客户'" :visible.sync="customerVisible" width="300px" class="dialog"
:close-on-click-modal="false">
<el-form label-width="70px">
<el-form-item label="客户名称">
<el-input v-model="customerForm.schoolName" placeholder="请输入客户名称"></el-input>
</el-form-item>
<el-form-item prop="userName" label="省份">
<el-select v-model="customerForm.provinceId" placeholder="请选择省份" @change="provinceChange">
<el-option v-for="(item, index) in provinceList" :key="index" :label="item.provinceName"
:value="item.provinceId"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="userName" label="城市">
<el-select v-model="customerForm.cityId" placeholder="请选择城市"
:disabled="customerForm.provinceId ? false : true">
<el-option v-for="(item, index) in cities" :key="index" :label="item.cityName"
:value="item.cityId"></el-option>
</el-select>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="customerVisible = false">取消</el-button>
<el-button type="primary" @click="submitCustomer">确定</el-button>
</span>
</el-dialog>
<el-dialog title="客户字典设置" :visible.sync="customerListVisible" width="800px" class="dialog"
:close-on-click-modal="false" custom-class="customer-dia">
<div style="display: flex;justify-content: space-between;align-items: center;margin-bottom: 10px">
<el-input style="width: 200px;" placeholder="请输入客户名称" prefix-icon="el-icon-search" v-model="customerKeyword"
clearable></el-input>
<i class="el-icon-circle-plus plus-cus" @click="addCustomer"></i>
</div>
<el-table :data="customers" class="table" ref="table" header-align="center" row-key="customerId">
<el-table-column type="index" width="100" label="序号" align="center">
<template slot-scope="scope">
{{ scope.$index + (pageCustomer - 1) * pageSizeCustomer + 1 }}
</template>
</el-table-column>
<el-table-column prop="customerName" label="客户名称" align="center">
<template slot-scope="scope">
{{ scope.row.customerName || scope.row.schoolName }}
</template>
</el-table-column>
<el-table-column prop="provinceName" label="省份" align="center">
</el-table-column>
<el-table-column prop="cityName" label="城市" align="center">
</el-table-column>
<el-table-column prop="countries" label="是否为客户" align="center">
<template slot-scope="scope">
{{ scope.row.bindOrNot ? '是' : '否' }}
</template>
</el-table-column>
<el-table-column label="操作" width="100" align="center">
<template slot-scope="scope">
<i class="el-icon-edit icon" @click="editCustomer(scope.row)"></i>
<i v-if="!scope.row.bindOrNot" class="el-icon-delete icon" @click="delCustomer(scope.row, i)"></i>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total, prev, pager, next" :total="totalCustomer"
@current-change="handleCurrentChangeCustomer" :current-page="pageCustomer" :page-size="pageSizeCustomer">
</el-pagination>
</div>
</el-dialog>
<pdf :visible.sync="pdfVisible" :src.sync="fileSrc"></pdf>
</div>
</template>
<script>
import pdf from '../../components/pdf.vue'
import Util from '@/libs/util'
import util from '@/utils/util'
import axios from 'axios'
import qs from 'qs'
export default {
components:{pdf},
data() {
@ -401,8 +294,8 @@ export default {
customerId: "",
customerName: '',
countries: '中国',
industryClassId: 16,
industryId: 83,
industryClassId: '',
industryId: '',
provinceId: '',
account: '',
name: '',
@ -499,10 +392,6 @@ export default {
{
id: 3,
name: '数据产品'
},
{
id: 4,
name: '职站增值模块'
}
],
//
@ -526,15 +415,14 @@ export default {
],
products: [],
productAll: [],
productAllOrigin: [],
pageProduct: this.$route.query.type === 'tab2' ? (+this.$route.query.page || 1) : 1,
pageSizeProduct: 10,
totalProduct: 0,
form3: {
orderType: +this.$route.query.orderType || '',
orderStatus: +this.$route.query.orderStatus || '',
keyword: this.$route.query.keyword || ''
orderType: '',
orderStatus: '',
keyword: ''
},
//
orderTypeList: [{
@ -566,6 +454,7 @@ export default {
pageSizeOrder: 10,
totalOrder: 0,
orders: [],
orderAll: [],
bmsKeyword: '',
bms: [],
@ -589,22 +478,7 @@ export default {
phoneRepeat: false,
emailRepeat: false,
submiting: false, //
updateTime: 0,
customerVisible: false,
cities: [],
customerForm: {
schoolName: '',
provinceId: '',
cityId: '',
},
customerListVisible: false,
customers: [],
pageCustomer: 1,
pageSizeCustomer: 10,
totalCustomer: 0,
customerKeyword: '',
curRow: null
updateTime: 0
};
},
watch: {
@ -625,7 +499,7 @@ export default {
this.pageOrder = 1
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initOrder()
this.handlePageOrder()
},500)
},
bmsKeyword: function(val) {
@ -634,17 +508,10 @@ export default {
this.getBm()
},500)
},
customerKeyword: function (val) {
clearTimeout(this.searchTimer)
this.searchTimer = setTimeout(() => {
this.initCustomer()
}, 500)
},
},
mounted() {
this.getIndustryClass()
this.getBm()
this.getCategory()
if(this.customerId){
this.getProduct()
this.$get(this.api.queryCustomerDetails,{
@ -674,11 +541,10 @@ export default {
this.dataPermissionss = res.result.dataPermissionss
this.getCityData()
this.changIndustryData()
this.getSchool()
this.getSchoolData()
}).catch((res) => {})
}else{
this.changIndustryData()
this.getSchool()
this.getSchoolData()
}
},
methods: {
@ -686,14 +552,12 @@ export default {
getProduct() {
this.$get(this.api.getProductsSubscribedByCustomers, {
customeId: this.customerId
}).then(async ({ data }) => {
}).then(({ data }) => {
data = data.filter(e => !e.productDel) // productDel=1
const { productTypeList } = this
const now = await Util.getNow()
data.map((e, i) => {
e.id = i
data.map(e => {
const list = e.startAndEndTimeList
if (list && list.length) {
if (list) {
let connect = true //
list.map((n, i) => {
//
@ -702,8 +566,8 @@ export default {
}
})
//
// if (list[0].startTime && list[0].endTime) {
if (list[0].startTime && now < new Date(list[0].startTime)) {
const now = Date.now()
if (now < new Date(list[0].startTime).getTime()) {
e.startTime = list[0].startTime
e.endTime = connect ? list[list.length - 1].endTime : list[0].endTime
e.status = '未生效'
@ -717,7 +581,7 @@ export default {
e.other += `<br>${j.startTime} ~ ${j.endTime}`
})
}
} else if (list[list.length - 1].endTime && now > new Date(list[list.length - 1].endTime)) {
} else if (now > new Date(list[list.length - 1].endTime).getTime()) {
e.status = '已过期'
} else {
//
@ -730,7 +594,7 @@ export default {
for (const j in list) {
const i = +j
const n = list[i]
if (n.startTime && n.endTime && now >= new Date(n.startTime) && now <= new Date(n.endTime)) {
if (now >= new Date(n.startTime).getTime() && now <= new Date(n.endTime).getTime()) {
//
e.startTime = n.startTime
e.endTime = n.endTime
@ -745,7 +609,7 @@ export default {
})
}
break
} else if (i != 0 && list[i - 1].endTime && n.startTime && n.endTime && now > new Date(list[i - 1].endTime) && now < new Date(n.startTime)) {
} else if (i != 0 && now > new Date(list[i - 1].endTime).getTime() && now < new Date(n.startTime).getTime()) {
//
e.startTime = n.startTime
e.endTime = n.endTime
@ -756,19 +620,13 @@ export default {
}
}
}
// }
const date = new Date()
date.setHours(0)
date.setMinutes(0)
date.setSeconds(0)
e.remain = e.status === '已过期' ? 0 : this.getRemain(date.getTime(), e.endTime) //
e.startAndEndTime = e.status === '已过期' ? '' : e.startTime + ' ~ ' + e.endTime
const isHave = productTypeList.find(n => n.classificationId === e.productType)
if (isHave) {
e.productTypeName = isHave.classificationName
} else {
e.productTypeName = ''
}
e.productTypeName = productTypeList.find(n => n.id === e.productType).name
// 1 0
e.isEnable = (e.status === '未生效' || e.status === '已过期' || !e.orderEnable) ?
0 :
@ -776,14 +634,13 @@ export default {
}
})
this.productAll = data
this.productAllOrigin = data
this.totalProduct = data.length
this.handlePage()
}).catch(res => {})
},
//
getRemain(startTime, endTime) {
return parseInt(((new Date(endTime) - new Date(startTime)) / 86400000))
return parseInt(((new Date(endTime).getTime() - new Date(startTime).getTime()) / 86400000))
},
//
handlePage() {
@ -796,122 +653,9 @@ export default {
},
//
filterForm2() {
const list = this.productAllOrigin
const list = this.productAll
const { productType, status, keyword } = this.form2
this.productAll = list.filter(e => (productType === '' || productType === e.productType) && (e.status === status || status === '全部') && (!e.goodsName || (e.goodsName && e.goodsName.includes(keyword))))
this.pageProduct = 1
this.totalProduct = this.productAll.length
this.handlePage()
},
//
setCustomer () {
this.initCustomer()
this.customerListVisible = true
},
handleCurrentChangeCustomer (val) {
this.pageCustomer = val
this.getCustomer()
},
//
getCustomer () {
this.$post(this.api.customerSettingsList, {
pageNum: this.pageCustomer,
pageSize: this.pageSizeCustomer,
keyword: this.customerKeyword,
}).then(({ page }) => {
this.customers = page.records
this.totalCustomer = page.total
}).catch(res => { });
},
initCustomer () {
this.pageCustomer = 1
this.getCustomer()
},
//
addCustomer () {
this.curRow = null
this.customerForm = {
schoolName: '',
provinceId: '',
cityId: '',
customerId: '',
schoolId: '',
}
this.customerVisible = true
},
//
editCustomer (row) {
this.curRow = row
this.customerVisible = true
this.customerForm = {
schoolName: row.customerName || row.schoolName,
provinceId: row.provinceId,
cityId: row.cityId,
customerId: row.customerId || '',
schoolId: row.schoolId || '',
}
row.provinceId && this.provinceChange()
},
//
delCustomer (row, i) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(async () => {
await this.$post(`${this.api.delClientsOrSchools}?schoolId=${row.schoolId}`).then(res => {
this.$message.success('删除成功')
this.getSchool(row.schoolId)
this.getCustomer()
})
}).catch(() => { })
},
//
provinceChange (e) {
this.$get(this.api.queryCity, {
provinceId: this.customerForm.provinceId
}).then(({ list }) => {
this.cities = list
if (e) this.customerForm.cityId = ''
}).catch(res => { });
},
//
async submitCustomer () {
if (this.submiting) return false
const form = this.customerForm
if (!form.schoolName) return this.$message.warning('请输入客户名称')
if (!form.provinceId) return this.$message.warning('请选择省份')
if (!form.cityId) return this.$message.warning('请选择城市')
this.submiting = true
const row = this.curRow
form.customerName = form.schoolName
let res
try {
if (this.curRow) {
if (row.bindOrNot) {
//
res = await this.$post(this.api.clientSettingsEditClient, form)
} else {
//
res = await this.$post(this.api.editClientsOrSchools, form)
}
} else {
//
res = await this.$get(this.api.addNewCustomersByOneself, form)
}
} finally {
this.submiting = false
}
this.customerVisible = false
this.$message.success('添加成功')
this.getCustomer()
this.getSchool(!this.customerId ? res.schoolId || '' : '') //
},
//
getCategory () {
this.$get(this.api.productCategoryList).then(res => {
this.productTypeList = res.classificationList
}).catch(err => { })
this.products = list.filter(e => (productType === '' || productType === e.productType) && (e.status === status || status === '全部') && e.productName.includes(keyword))
},
//
exportList() {
@ -922,7 +666,7 @@ export default {
data.push({
productName: e.productName,
productStatus: e.status,
productType: e.productTypeName,
productType: e.productName,
remainingPeriod: e.remain,
startAndEndTime: e.startAndEndTime,
subscriptionStatus: e.isEnable ? '启用' : '禁用',
@ -934,43 +678,50 @@ export default {
},
responseType: 'blob'
}).then((res) => {
Util.downloadFileDirect(`已订阅产品.xls`, new Blob([res.data]))
util.downloadFileDirect(`已订阅产品.xls`, new Blob([res.data]))
}).catch(res => {})
},
//
getOrder() {
const { orderStatus, orderType, keyword } = this.form3
this.$post(this.api.getCustomerOrderRecord, {
customerId: this.customerId,
const { orderStatus, orderType } = this.form3
this.$post(this.api.orderList, {
cityId: '',
orderContent: keyword,
customerName: this.form.customerName,
orderStatus,
orderType,
pageNo: this.pageOrder,
pageSize: this.pageSizeOrder,
pageNo: 1,
pageSize: 10000,
provinceId: ''
}).then(({ orders }) => {
orders.records.forEach(e => {
}).then(({ orderPage }) => {
orderPage.orders.forEach(e => {
e.orderType = this.orderTypeFn(e.orderType)
e.orderStatus = this.orderStatusFn(e.orderStatus)
e.orderNature = this.orderNatureFn(e.orderNature)
});
this.orders = orders.records
this.totalOrder = orders.total
this.orderAll = orderPage.orders
this.totalOrder = orderPage.total
this.handlePageOrder()
}).catch(res => {})
},
initOrder () {
this.pageOrder = 1
this.getOrder()
//
filterOrder() {
const { keyword } = this.form3
const { orders } = this
this.orders = keyword ? this.orderAll.filter(e => e.orderNumber.includes(keyword) || e.orderContent.includes(keyword)) : orders
},
//
handlePageOrder() {
this.orders = this.orderAll.slice((this.pageOrder - 1) * this.pageSizeOrder, this.pageOrder * this.pageSizeOrder)
this.filterOrder()
},
handleCurrentChangeOrder(val) {
this.pageOrder = val
this.getOrder()
this.handlePageOrder()
this.$router.push(`addcustomer?id=${this.customerId}&type=tab3&page=${val}`)
},
//
toOrderDetail(row) {
this.$router.push(`/addcustomer?id=${this.customerId}&type=tab3&${qs.stringify(this.form3)}&page=${this.pageOrder}`)
this.$router.push(`/AddOrder?val=watch&orderId=${row.orderId}&orderStatus=${row.orderStatus === '已完成' ? 1 : 0}`)
},
@ -999,7 +750,6 @@ export default {
},
//
toOrder(row) {
this.$router.push(`/addcustomer?id=${this.customerId}&type=tab5&keyword=${this.bmsKeyword}&page=${this.pageOrder}`)
this.$router.push(`/bmOrder?businessManagerId=${row.businessManagerId}&customerId=${this.customerId}&customerName=${this.form.customerName}&userName=${row.userName}&teamId=${row.teamId}`)
},
@ -1014,15 +764,16 @@ export default {
this.pageProduct = 1
this.pageOrder = 1
this.pageBm = 1
index === 'tab3' && this.initOrder()
index === 'tab3' && this.handlePageOrder()
this.updateTime = this.form.customerId ? 1 : 0
}
},
//
getCityData(){
this.$get(this.api.queryCity, {
let data = {
provinceId: this.form.provinceId
}).then(res => {
}
this.$get(this.api.queryCity,data).then(res => {
this.cityList = res.list
}).catch(res => {});
},
@ -1033,21 +784,14 @@ export default {
this.form.customerName = ''
},
// /
getSchool (schoolId) {
this.$get(this.api.querySchoolData).then(({ list }) => {
this.schoolList = list
// schoolId
if (schoolId && !this.customerId) {
const item = list.find(e => e.schoolId == schoolId)
if (item) {
this.form.schoolId = schoolId
this.form.provinceId = item.provinceId
this.getCityData()
this.form.cityId = item.cityId
} else {
this.form.schoolId = ''
}
getSchoolData(){
let data = {
schoolName: '',
provinceId: '',
cityId: ''
}
this.$get(this.api.querySchoolData).then(res => {
this.schoolList = res.list
}).catch(res => {});
},
//
@ -1192,13 +936,12 @@ export default {
}, 1500)
this.$store.commit('schoolIdData',{schoolId: this.form.schoolId})
this.$message.success('添加成功')
tab ? this.tabChange(tab, 1) : this.$router.push('/customer')
tab ? this.tabChange(tab, 1) : this.backPage()
}).catch((res) => {
this.submiting = false
})
}
}else{
this.submiting = false
this.$message.warning('该客户已存在')
}
}
@ -1227,8 +970,7 @@ export default {
//
if ((id && updateTime > 1) || (!id && updateTime)) {
this.$confirm(`编辑的内容未保存,是否保存?`, '提示', {
type: 'warning',
closeOnClickModal: false
type: 'warning'
}).then(() => {
this.saveAdd(i)
}).catch(() => {
@ -1239,7 +981,7 @@ export default {
}
},
backPage(){
this.$router.push(this.$store.state.referrer || '/customer')
this.$router.push(`customer?page=${this.$store.state.customerPage}`)
}
}
};
@ -1249,33 +991,27 @@ export default {
.tabs {
margin-bottom: 30px;
}
.card {
min-height: calc(100vh - 260px);
margin-bottom: 20px;
}
.addhr_tag{
background-color: #666;
width: 6px;
height: 17px;
margin-right: 5px;
}
.radio_icon{
font-size: 26px;
color: #062c87;
color: #9278FF;
}
/deep/.warning {
margin-left: 5px;
color: #062c87;
color: #9278FF;
}
.tags{
border: none;
background: none;
color: #000;
background: none;color: #000;
white-space:pre-wrap;
overflow: hidden;
text-overflow: ellipsis;
@ -1284,32 +1020,10 @@ export default {
line-clamp: 2;
-webkit-box-orient: vertical;
}
.info {
margin-top: 20px;
.el-select {
width: 100%;
}
}
.plus-cus {
margin-left: 10px;
font-size: 18px;
color: #062c87;
cursor: pointer;
}
/deep/.customer-dia {
.icon {
margin-right: 10px;
font-size: 16px;
color: #7a7a7a;
cursor: pointer;
&:hover {
color: #062c87;
}
}
}
</style>

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

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

@ -1,5 +1,5 @@
<template>
<div v-loading="loading">
<div>
<el-card shadow="hover" class="mgb20">
<div>
<div class="flex-center mgb20">
@ -9,35 +9,29 @@
<div>
<el-form label-width="80px">
<el-col :span="4">
<el-form-item label="省份">
<el-select v-model="form.provinces" clearable placeholder="请选择省份" @change="getCity"
@clear="clearprovince">
<el-option v-for="(item, index) in provinceList" :key="index" :label="item.provinceName"
:value="item.provinceId"></el-option>
<el-form-item label="国家">
<el-select v-model="form.countries" placeholder="请选择国家">
<el-option v-for="(item,index) in countryList" :key="index" :label="item.name" :value="item.name"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="城市">
<el-select v-model="form.city" clearable placeholder="请选择城市" :disabled="form.provinces ? false : true"
@change="initData">
<el-option v-for="(item, index) in cityList" :key="index" :label="item.cityName"
:value="item.cityId"></el-option>
<el-form-item label="省份">
<el-select v-model="form.provinces" clearable placeholder="请选择省份" @change="getCity" @clear="clearprovince">
<el-option v-for="(item,index) in provinceList" :key="index" :label="item.provinceName" :value="item.provinceId"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="客户类型">
<el-select v-model="form.customerType" placeholder="请选择客户类型" @change="initData">
<el-option v-for="(item, index) in customerTypeList" :key="index" :label="item.name"
:value="item.value"></el-option>
<el-form-item label="城市">
<el-select v-model="form.city" clearable placeholder="请选择城市" :disabled="form.provinces ? false : true" @change="initData">
<el-option v-for="(item,index) in cityList" :key="index" :label="item.cityName" :value="item.cityId"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item>
<el-input placeholder="支持客户,联系人,账号搜索" prefix-icon="el-icon-search" v-model="form.keyword"
clearable></el-input>
<el-input placeholder="支持客户,联系人,账号搜索" prefix-icon="el-icon-search" v-model="form.keyword" clearable></el-input>
</el-form-item>
</el-col>
</el-form>
@ -52,13 +46,11 @@
<span>客户列表</span>
</div>
<div>
<el-button type="primary" round class="mag" @click="exportData">导出客户列表</el-button>
<el-button type="primary" round class="mag" @click="addcustomer" v-auth>新增</el-button>
<el-button type="primary" round @click="delAllSelection" v-auth>批量删除</el-button>
</div>
</div>
<el-table :data="listData" class="table" ref="table" header-align="center"
@selection-change="handleSelectionChange" row-key="customerId">
<el-table v-loading="loading" :data="listData" class="table" ref="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="customerId">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center">
<template slot-scope="scope">
@ -72,11 +64,7 @@
<span class="ellipsis">{{scope.row.industryName}}</span>
</template>
</el-table-column>
<el-table-column prop="countries" label="客户类型" align="center">
<template slot-scope="scope">
<span v-if="scope.row.customerType">{{ customerTypeList.find(e => e.value == scope.row.customerType).name
}}</span>
</template>
<el-table-column prop="countries" label="国家" align="center">
</el-table-column>
<el-table-column prop="provinceName" label="省份" align="center">
</el-table-column>
@ -92,14 +80,13 @@
<template slot-scope="scope">
<el-button type="text" @click="resetPassword(scope.row)" v-auth>重置密码</el-button>
<el-button type="text" @click="show(scope.row)" v-auth>查看</el-button>
<el-button type="text" @click="edit(scope.row)" v-auth>管理</el-button>
<el-button type="text" @click="edit(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 layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange"
:current-page="page">
<el-pagination background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" :current-page="page">
</el-pagination>
</div>
</el-card>
@ -108,9 +95,6 @@
<script>
import Setting from '@/setting'
import axios from 'axios';
import util from "@/libs/util";
import qs from 'qs'
export default {
name: 'customer',
data() {
@ -120,29 +104,12 @@ export default {
countryList: [{
name:'中国'
}],
customerTypeList: [
{
value: '',
name: '不限'
},
{
name: '正式',
value: 1
},
{
name: '试用',
value: 2
},
{
name: '到期',
value: 3
}],
listData: [],
form: {
customerType: +this.$route.query.customerType || '',
provinces: +this.$route.query.provinces || '',
city: +this.$route.query.city || '',
keyword: this.$route.query.keyword || ''
countries:'中国',
provinces: '',
city: '',
keyword: ''
},
multipleSelection: [],
provinceList: [],
@ -162,11 +129,6 @@ export default {
},
},
mounted() {
const { query } = this.$route
if (query.page) {
this.$router.push('/customer').catch(() => { })
}
this.getData()
this.getProvince()
},
@ -175,9 +137,9 @@ export default {
const sid = this.$store.state.dataPer.find(e => e.permissionName === '客户管理')
this.loading = true
this.$post(this.api.queryCustomer,{
countries: this.form.countries,
provinceId: this.form.provinces,
cityId: this.form.city,
customerType: this.form.customerType,
searchContent: this.form.keyword,
page: this.page,
size: this.pageSize,
@ -198,7 +160,6 @@ export default {
this.$get(this.api.queryProvince).then(res => {
this.provinceList = res.list
this.$store.commit("provinceData", { provinceList : this.provinceList})
this.form.city && this.getCityData()
}).catch(res => {})
},
clearprovince(){
@ -221,47 +182,13 @@ export default {
permission(row){
this.$router.push(`/permission?name=${row.customerName}`)
},
//
async exportData () {
let sid = this.$store.state.dataPer.find(e => e.permissionName === '客户管理')
sid = (sid && !sid.all) ? sid.supplierId : ''
let list = this.multipleSelection
//
if (!list.length) {
const res = await this.$post(this.api.queryCustomer, {
page: 1,
size: 1000,
supplierId: sid
})
list = res.message.list
}
const ids = list.map(e => e.customerId)
axios.post(this.api.exportClient, {
exportCustomerIds: ids,
supplierId: sid
}, {
headers: {
token: this.token
},
responseType: 'blob'
}).then((res) => {
util.downloadFileDirect(`客户列表.xlsx`, new Blob([res.data]))
}).catch(res => { })
},
// url
setReferrer () {
this.$store.commit('setReferrer', `${this.$route.path}?${qs.stringify(this.form)}&page=${this.page}`)
},
addcustomer(){
this.setReferrer()
this.$router.push('addcustomer')
},
edit(row){
this.setReferrer()
this.$router.push(`addcustomer?id=${row.customerId}`)
},
show(row){
this.setReferrer()
this.$router.push(`addcustomer?id=${row.customerId}&show=true`)
},
handleDelete(row) {
@ -311,6 +238,7 @@ export default {
},
handleCurrentChange(val) {
this.page = val
this.$store.commit('SET_C_PAGE', val)
this.$router.push(`customer?page=${val}`)
this.getData()
},
@ -338,3 +266,4 @@ export default {
min-height: calc(100vh - 300px);
}
</style>

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

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

@ -5,14 +5,12 @@
<ul class="filter">
<li>
<label>创建日期</label>
<el-date-picker v-model="date" align="right" unlink-panels type="daterange" start-placeholder="开始日期"
end-placeholder="结束日期" format="yyyy-MM-dd" value-format="yyyy-MM-dd" clearable></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>
<label>状态</label>
<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>
</li>
</ul>
@ -27,8 +25,7 @@
<el-button type="primary" round @click="delAllSelection" v-auth="'/data:产品管理:批量删除'">批量删除</el-button>
</div>
</div>
<el-table :data="listData" class="table" ref="table" header-align="center" @selection-change="handleSelectionChange"
row-key="id">
<el-table :data="listData" class="table" ref="table" stripe header-align="center" @selection-change="handleSelectionChange" row-key="id">
<el-table-column type="selection" width="55" align="center" :reserve-selection="true"></el-table-column>
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column prop="productName" label="产品名称" align="center"></el-table-column>
@ -39,8 +36,7 @@
<el-table-column prop="createTime" label="创建时间" align="center"></el-table-column>
<el-table-column prop="orderNature" label="状态" align="center">
<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>
</el-table-column>
<el-table-column label="操作">
@ -52,28 +48,54 @@
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination background layout="total, prev, pager, next" @current-change="handleCurrentChange"
:current-page="page" :total="totals"></el-pagination>
<el-pagination background layout="total, prev, pager, next" @current-change="handleCurrentChange" :current-page="page" :total="totals"></el-pagination>
</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-item label="数据产品名称">
<el-input v-model="productName" placeholder="请输入数据产品名称"></el-input>
</el-form-item>
<el-form-item label="市场单价格">
<el-input v-model="market" placeholder="请输入市场价格" :min="0">
<span slot="suffix">/账号/</span>
</el-input>
</el-form-item>
<el-form-item label="供应厂商" prop="supplier">
<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-form-item>
<el-form-item label="结算方式" prop="settlementMethod" style="width: 800px">
<div class="settlement" style="align-items: center">
<el-radio v-model="settlementMethod" label="0">结算单价</el-radio>
<el-input style="width: 244px" v-model.trim="settlementPrice">
<template slot="append">/账号/</template>
</el-input>
</div>
<div class="settlement">
<el-radio style="margin-top: 10px" v-model="settlementMethod" label="1">比例分成</el-radio>
<div class="settle-item">
<div style="margin-bottom: 10px">
<span class="label">商务经理占比</span>
<el-input v-model.trim="businessProportion" @change="calcProp">
<template slot="append">%</template>
</el-input>
</div>
<div>
<span class="label">产品厂商占比</span>
<el-input v-model.trim="manufacturerProportion" @change="calcProp">
<template slot="append">%</template>
</el-input>
</div>
</div>
</div>
</el-form-item>
<el-form-item label="配置数据">
<el-button type="primary" @click="configData">配置数据权限</el-button>
</el-form-item>
<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 :title="node.label">{{ node.label }}</span>
</span>
@ -86,13 +108,10 @@
</span>
</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-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 :title="node.label">{{ node.label }}</span>
</span>
@ -104,14 +123,12 @@
<el-form label-width="80px" class="flex-between mgb20">
<div class="flex-center">
<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-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>
</el-form>
<el-table :data="listConfigData" class="table" ref="table" header-align="center">
<el-table :data="listConfigData" class="table" ref="table" stripe header-align="center">
<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="dataTotal" label="数据总量" align="center"></el-table-column>
@ -124,8 +141,7 @@
</el-table-column>
</el-table>
<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>
</el-card>
</el-main>
@ -137,10 +153,9 @@
</el-dialog>
<el-dialog title="预览" :visible.sync="previewVisible" width="60%" center :close-on-click-modal="false">
<el-table :data="previewData" class="table" header-align="center" row-key="id">
<el-table :data="previewData" class="table" stripe header-align="center" row-key="id">
<el-table-column type="index" width="100" label="序号" align="center"></el-table-column>
<el-table-column 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-dialog>
</div>
@ -178,7 +193,12 @@ export default {
id: '',
userId: '',
productName: '',
market: '',
supplier: '',
businessProportion: '',
manufacturerProportion: '',
settlementPrice: '',
settlementMethod: '0',
typeList: [],
loading: false,
defaultProps: {
@ -401,6 +421,11 @@ export default {
this.$post(`${this.api.findById}?id=${this.id}`).then(res => {
const data = res.product
this.productName = data.productName
this.market = data.market
this.businessProportion = data.businessProportion
this.manufacturerProportion = data.manufacturerProportion
this.settlementMethod = data.settlementMethod
this.settlementPrice = data.settlementPrice
this.supplier = data.supplier
this.checkedIds = data.tableId.split(',')
this.$refs.type.setCheckedKeys(this.checkedIds) //
@ -426,6 +451,7 @@ export default {
this.$post(this.api.updateProduct,{
id: row.id,
productName: row.productName,
market: row.market,
tableId: row.tableId,
userId: row.userId,
userName: row.userName,
@ -446,8 +472,6 @@ export default {
},
//
handleDelete(row) {
this.$post(`${this.api.deleteDataPrompt}?ids=${row.id}`).then(({ status }) => {
if (status === 200) {
this.$confirm('确定要删除吗?', '提示', {
type: 'warning'
}).then(() => {
@ -456,20 +480,12 @@ export default {
this.getData()
}).catch(res => {})
}).catch(() => {})
}
}).catch(err => { })
},
handleSelectionChange(val) {
this.multipleSelection = val
},
delAllSelection() {
if (this.multipleSelection.length) {
let ids = []
this.multipleSelection.forEach(i => {
ids.push('ids=' + i.id)
});
this.$post(`${this.api.deleteDataPrompt}?${ids.join('&')}`).then(({ status }) => {
if (status === 200) {
if(this.multipleSelection.length != ''){
let arr = this.multipleSelection
let result = arr.map(e => e.id)
this.$confirm('确定要删除吗?', '提示', {
@ -486,8 +502,6 @@ export default {
this.getData()
}).catch(res => {})
}).catch(() => {})
}
}).catch(err => { })
}else{
this.$message.error('请先选择数据')
}
@ -509,6 +523,11 @@ export default {
//
closeProduct(){
this.productName = ''
this.market = ''
this.businessProportion = ''
this.manufacturerProportion = ''
this.settlementMethod = '0'
this.settlementPrice = ''
this.supplier = ''
this.isDetail = false
this.typeList = []
@ -542,9 +561,21 @@ export default {
//
confirm(){
if(this.submited) return false
const { productName, supplier } = this
const { productName, market, businessProportion, manufacturerProportion, settlementMethod, settlementPrice, supplier } = this
if(!productName) return this.$message.warning('请输入数据产品名称')
if(!market) return this.$message.warning('请输入市场单价格')
if(isNaN(market)) return this.$message.warning('市场单价格请输入数字')
if(!supplier) return this.$message.warning('请选择供应厂商')
if (settlementMethod == 0) {
if(!settlementPrice) return this.$message.warning('请输入结算单价')
if(isNaN(settlementPrice)) return this.$message.warning('结算单价请输入数字')
} else {
if(!businessProportion) return this.$message.warning('请输入商务经理占比')
if(isNaN(businessProportion)) return this.$message.warning('商务经理占比请输入数字')
if(!manufacturerProportion) return this.$message.warning('请输入产品厂商占比')
if(isNaN(manufacturerProportion)) return this.$message.warning('产品厂商占比请输入数字')
if(+businessProportion + +manufacturerProportion !== 100) return this.$message.warning('比例分成总和须为100%,请重新修改')
}
if(!this.checkedIds.length) return this.$message.warning('请选择数据')
this.submited = true //
let tableId = this.checkedIds
@ -552,6 +583,11 @@ export default {
let data = {
id: this.id,
productName,
market,
businessProportion,
manufacturerProportion,
settlementMethod,
settlementPrice,
supplier,
tableId: tableId.join(),
userId: this.userId,
@ -683,24 +719,20 @@ export default {
/deep/.el-input--suffix .el-input__inner{
padding-right: 56px;
}
.type-wrap{
height: 450px;
margin-left: 25px;
overflow:auto;
}
.settlement {
display: flex;
margin-bottom: 10px;
.label {
margin-right: 10px;
white-space: nowrap;
color: #606266;
font-size: 14px;
}
.el-input {
width: 150px;
margin-right: 30px;

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

@ -1,74 +1,51 @@
<template>
<div>
<el-card shadow="hover"
class="m-b-20">
<el-card shadow="hover" class="m-b-20">
<div class="flex-between">
<el-page-header @back="goBack"
:content="'新增文章'"></el-page-header>
<el-page-header @back="goBack" :content="'新增文章'"></el-page-header>
</div>
</el-card>
<el-card shadow="hover"
class="m-b-20">
<el-form :model="form"
:rules="rules"
ref="form"
label-width="90px"
label-suffix=":"
size="small">
<el-form-item prop="coverUrl"
label="封面图">
<el-upload class="avatar-uploader"
<el-card shadow="hover" class="m-b-20">
<el-form :model="form" :rules="rules" ref="form" label-width="90px" label-suffix=":" size="small">
<el-form-item prop="coverUrl" label="封面图">
<el-upload
class="avatar-uploader"
accept=".jpg,.png,.jpeg"
:on-remove="handleRemove"
:on-error="uploadError"
:on-success="uploadSuccess"
:before-remove="beforeRemove"
:limit="1"
:on-exceed="handleExceed"
action=""
:http-request="handleRequest">
<img v-if="form.coverUrl"
:src="form.coverUrl"
class="avatar">
<div class="uploader-default"
v-else>
:action="this.api.fileupload"
:headers="headers"
name="file"
>
<img v-if="form.coverUrl" :src="form.coverUrl" class="avatar">
<div class="uploader-default" v-else>
<i class="el-icon-plus"></i>
<p>上传封面</p>
</div>
</el-upload>
</el-form-item>
<el-form-item prop="author"
label="作者">
<el-form-item prop="author" label="作者">
<div class="d-inline-block">
<el-input placeholder="请输入作者"
v-model="form.author"
clearable></el-input>
<el-input placeholder="请输入作者" v-model="form.author" clearable></el-input>
</div>
</el-form-item>
<el-form-item prop="date"
label="日期">
<el-form-item prop="date" label="日期">
<div class="d-inline-block">
<el-date-picker v-model="form.date"
type="date"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择日期"></el-date-picker>
<el-date-picker v-model="form.date" type="date" value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期"></el-date-picker>
</div>
</el-form-item>
<el-form-item prop="title"
label="文章标题">
<el-input placeholder="请输入文章标题"
v-model="form.title"
clearable></el-input>
<el-form-item prop="title" label="文章标题">
<el-input placeholder="请输入文章标题" v-model="form.title" clearable></el-input>
</el-form-item>
<el-form-item prop="content"
label="文章内容">
<quill :border="true"
v-model="form.content"
:uploading.sync="uploading"
:height="400" />
<el-form-item prop="content" label="文章内容">
<quill :border="true" v-model="form.content" :uploading.sync="uploading" :height="400" />
</el-form-item>
<el-form-item>
<el-button type="primary"
@click="saveData">确定</el-button>
<el-button type="primary" @click="saveData">确定</el-button>
</el-form-item>
</el-form>
</el-card>
@ -76,7 +53,6 @@
</template>
<script>
import Oss from '@/components/upload/upload.js'
import quill from "@/components/quill";
import util from "@/libs/util";
export default {
@ -172,12 +148,14 @@ export default {
handleExceed(files, fileList) {
util.warningMsg(`当前限制选择 1 个文件,如需更换,请删除上一个文件再重新选择!`);
},
//
async handleRequest ({ file }) {
this.form.coverUrl && Oss.del(this.form.coverUrl)
Oss.upload(file).then(res => {
this.form.coverUrl = res.url
})
uploadSuccess(res, file, fileList) {
if (this.form.coverUrl) {
let fileName = this.coverUrl.replace("https://liuwanr.oss-cn-shenzhen.aliyuncs.com/", "");
this.$del(`${this.api.fileDeletion}?keys=${fileName}`).then(res => {
}).catch(res => {
});
}
this.form.coverUrl = res.data.filesResult.fileUrl;
},
uploadError(err, file, fileList) {
this.$message({
@ -190,8 +168,11 @@ export default {
return this.$confirm(`确定移除 ${file.name}`);
},
handleRemove(file, fileList) {
Oss.del(this.form.coverUrl)
this.form.coverUrl = ''
let fileName = this.form.coverUrl.replace("https://liuwanr.oss-cn-shenzhen.aliyuncs.com/", "");
this.$del(`${this.api.fileDeletion}?keys=${fileName}`).then(res => {
this.form.coverUrl = "";
}).catch(res => {
});
},
uploadSure() {
this.BatchUpload = false;
@ -204,8 +185,7 @@ export default {
},
goback() {
this.$confirm("确定返回?未更新的信息将不会保存。", "提示", {
type: "warning",
closeOnClickModal: false
type: "warning"
})
.then(() => {
this.back();
@ -241,7 +221,7 @@ $avatar-width: 104px;
overflow: hidden;
&:hover {
border-color: #409eff;
border-color: #409EFF;
}
.uploader-default {
@ -292,8 +272,7 @@ $avatar-width: 104px;
/deep/ .d-inline-block {
width: 216px;
.el-select,
.el-input {
.el-select, .el-input {
width: 100%;
}
}

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

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

@ -2,8 +2,7 @@
<!-- 内容管理 -->
<div class="flex">
<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 class="right">
<ContentList ref="content" v-show="menuList.length" :columnId="columnId" />
@ -72,8 +71,7 @@ export default {
//
if (JSON.stringify(list) !== JSON.stringify(originList)) {
this.$confirm(`您已更改了文章排序,是否保存更改?`, '提示', {
type: 'warning',
closeOnClickModal: false
type: 'warning'
}).then(() => {
content.sortSubmit()
this.setColumnId(key.id)
@ -93,19 +91,16 @@ export default {
width: 210px;
height: calc(100vh - 250px);
border-right: solid 1px #e6e6e6;
background-color: #f2f6fc;
background-color: #F2F6FC;
/deep/.el-tree-node__content {
height: 50px;
}
}
.right {
flex: 1;
}
/deep/.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
color: #fff;
background-color: #062c87;
background-color: #9278ff;
}
</style>

@ -42,8 +42,7 @@ export default {
//
if (JSON.stringify(list) !== JSON.stringify(originList)) {
this.$confirm(`您已更改了${tab == 1 ? '栏目' : '文章'}排序,是否保存更改?`, '提示', {
type: 'warning',
closeOnClickModal: false
type: 'warning'
}).then(() => {
content.sortSubmit()
fn(param)
@ -69,28 +68,22 @@ export default {
.flex-1 {
flex: 1;
}
.page {
display: flex;
}
.column-tab {
width: 120px;
border-right: solid 1px #e6e6e6;
li {
display: flex;
align-items: center;
height: 60px;
cursor: pointer;
i {
margin-right: 5px;
}
&:hover,
&.active {
color: #062c87;
&:hover, &.active {
color: #9278FF;
}
}
}

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

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

@ -12,102 +12,43 @@
<div class="date-inputs">
起止时间
<div style="display: inline-flex;align-items: center;">
<el-date-picker v-model="form.time" type="datetimerange" range-separator="~" start-placeholder="开始日期"
end-placeholder="结束日期" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
<el-date-picker
v-model="form.time"
type="datetimerange"
range-separator="~"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
@change="timeChange">
</el-date-picker>
<el-alert style="width: auto;padding: 4px 16px;margin-left: 10px;"
:title="'(请设置在 ' + step1.playStartTime + ' ~ ' + step1.playEndTime + '间)'" type="error" :closable="false"
<el-alert
style="width: auto;padding: 4px 16px;margin-left: 10px;"
:title="'(请设置在 ' + step1.playStartTime + ' ~ ' + step1.playEndTime + '间)'"
type="error"
:closable="false"
effect="dark">
</el-alert>
</div>
</div>
</div>
</el-card>
<!-- 理论系统选择试卷库非理论则选择系统 -->
<el-card shadow="hover" class="m-b-20">
<el-card shadow="hover" class="mgr20 m-b-20">
<div>
<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>
<p class="m-b-20">课程</p>
<div class="inline-input">
<!-- 选择系统 -->
<el-select v-if="courseSystem" v-model="systemId" placeholder="请选择系统" @change="getProject">
<el-option v-for="(item, i) in services" :key="i" :label="item.systemName" :value="item.systemId">
</el-option>
</el-select>
<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-select v-model="form.cid" @change="courseChange">
<el-option
v-for="item in curriculumList"
:key="item.cid"
:label="item.curriculumName"
:value="item.cid">
</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>
</template>
</div>
</div>
</el-card>
<!-- 理论系统 -->
<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">
<el-card shadow="hover" class="m-b-20">
<div class="flex-between m-b-20">
<span>实训项目</span>
<div style="display: inline-flex;">
@ -118,7 +59,7 @@
</div>
</div>
<!-- 实训项目表格 -->
<el-table :data="projects" class="table" header-align="center">
<el-table :data="projects" class="table" stripe header-align="center">
<el-table-column width="60" label="选择" align="center">
<template slot-scope="scope">
<el-radio v-model="form.projectId" :label="scope.row.projectId">&nbsp;</el-radio>
@ -143,8 +84,13 @@
</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>
<el-pagination
background
:page-size="pageSize"
@current-change="handleCurrentChange"
layout="total,prev, pager, next"
:total="total"
></el-pagination>
</div>
</el-card>
@ -156,41 +102,24 @@
</template>
<script>
import Util from '@/libs/util'
import util from "@/libs/util";
import { Loading } from 'element-ui'
import TestPaperConst from '@/const/testPaper'
export default {
props: ['form', 'step1'],
data() {
return {
difficults: TestPaperConst.difficults,
paperTypes: TestPaperConst.paperTypes,
loadIns: null,
mallIds: [],
systemId: '',
curs: [],
paperLibraries: [],
services: [],
curriculumList: [],
keyword: '',
projects: [],
page: 1,
pageSize: 5,
total: 0,
libraryId: '',
sysId: '',
paperId: '',
paperName: '',
permissionsKeys: ['练习', '考核', '竞赛'],
timeInvalid: false,
courseSystem: 1,
timeInvalid: false
};
},
computed: {
//
isTheory () {
return this.form.method === 1
},
},
watch: {
// ,
form: {
@ -202,167 +131,63 @@ export default {
keyword: function(val) {
clearTimeout(this.searchTimer);
this.searchTimer = setTimeout(() => {
this.initData()
}, 500)
this.initData();
}, 500);
}
},
mounted() {
// this.isTheory ? this.getLibrary() : this.getCourse()
this.getSystem()
this.getCourse()
},
methods: {
//
async getCourse () {
const sid = this.$store.state.dataPer.find(e => e.permissionName === '服务配置')
//
const res = await this.$post(this.api.queryServiceConfig, {
pageNum: 1,
pageSize: 1000,
supplierId: sid ? sid.supplierId : ''
})
const services = res.serviceList.records
//
const { page } = await this.$post(this.api.listOfGoods, {
getCourse() {
this.loadIns = Loading.service()
const sid = this.$store.state.dataPer.find(e => e.permissionName === '课程管理')
this.$post(this.api.curriculumList, {
isShelves: 1,
pageNum: 1,
pageSize: 10000,
hotTag: 1,
sort: 0,
isAssociatedProduct: 1,
isShelves: 0,
})
const { records } = page
const { mallId, cid, systemId } = this.form
if (records.length) {
services.map(e => {
e.id = +e.systemId
e.label = e.systemName
})
records.map(e => {
e.id = +e.mallId
e.label = e.productName
e.children = services.filter(n => e.systemId && e.systemId.split(',').includes(n.systemId)) //
})
this.curs = records
//
const first = records[0]
this.mallIds = [mallId || first.mallId, systemId || first.children[0].id]
this.form.mallId = mallId || first.mallId
this.form.cid = cid || +first.associatedProduct
this.form.systemId = systemId || first.systemId
this.sysId = systemId || first.systemId
this.loadIns = Loading.service()
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()
}
supplierId: sid ? sid.supplierId : ''
}).then(({ page }) => {
const list = page.records
this.curriculumList = page.records
if (!this.form.cid && list.length) this.form.cid = list[0].cid
this.courseChange()
}).catch(err => {
this.loadIns.close()
});
},
//
curChange (val) {
const id = val[0]
const item = this.curs.find(e => e.id == id)
if (val.length === 1) {
//
this.mallIds = [id, item.children[0].id]
}
this.form.mallId = id
this.form.cid = +item.associatedProduct
this.form.systemId = this.mallIds[1]
this.sysId = this.mallIds[1]
this.loadIns = Loading.service()
courseChange(val) {
const { systemId } = this.curriculumList.find(e => e.cid == this.form.cid)
this.sysId = systemId
if (val) this.loadIns = Loading.service()
this.getProject()
},
//
async getLibrary () {
try {
const res = await this.$post(this.api.libraryList, {
pageNum: 1,
pageSize: 10000,
type: 1,
isDisable: 0,
})
const { records } = res.pageList
if (records.length) {
this.paperLibraries = records
this.libraryId = records[0].libraryId
this.loadIns = Loading.service()
this.getProject()
}
} finally { }
},
// /
async getProject () {
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, {
//
getProject() {
this.$post(this.api.getProjectAssessmentByCompetition, {
pageNum: this.page,
pageSize: this.pageSize,
cid: this.form.cid,
projectName: this.keyword,
systemId: this.sysId,
permissions: 2,
})
permissions: 2
}).then(({ data }) => {
this.projects = data.records
this.total = data.total
}
}
} finally {
this.loadIns.close()
}
}).catch(err => {
this.loadIns.close()
});
},
initData() {
this.page = 1
this.getProject()
this.page = 1;
this.getProject();
},
handleCurrentChange(val) {
this.page = val
this.getProject()
this.page = val;
this.getProject();
},
//
toProject() {
@ -372,17 +197,10 @@ export default {
form,
curStep
})
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}`)
const item = this.curriculumList.find(e => e.cid == this.form.cid) || {} // id
let systemId = item.sysId || '1'
systemId = systemId.split(',')[0] // id
this.$router.push(`/projectList?systemId=${systemId}&show=1&name=${item.sysName.split(',')[0]}`)
},
//
timeChange(val) {
@ -392,7 +210,7 @@ export default {
const { playStartTime, playEndTime } = this.step1
if (startTime < new Date(playStartTime) || endTime > new Date(playEndTime)) {
this.timeInvalid = true
return Util.warningMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。')
return util.warningMsg('设置的阶段比赛时间必须要在第一步设置的竞赛时间范围内,请重新设置。')
}
this.timeInvalid = false
const { form, curStep } = this.$parent
@ -402,74 +220,37 @@ export default {
const time1 = new Date(form[i].startTime)
const time2 = new Date(form[i].endTime)
if ((startTime >= time1 && startTime <= time2) || (endTime >= time1 && endTime <= time2)) {
Util.warningMsg('请注意,所设置的时间与已设置的阶段时间重合。')
util.warningMsg('请注意,所设置的时间与已设置的阶段时间重合。')
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() {
const { form, courseSystem } = this
if (!form.time.length) return Util.warningMsg('请选择比赛时间')
const { form } = this
if (!form.time.length) return util.warningMsg('请选择比赛时间')
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 (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('请选择项目')
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('请选择项目')
const { systemId, systemName, projectName } = this.projects.find(e => e.projectId == form.projectId)
if (systemId) form.systemId = systemId
if (projectName) form.projectName = projectName
if (systemName) form.systemName = systemName
}
if (courseSystem) {
form.mallId = ''
form.cid = ''
}
form.startTime = form.time[0]
form.endTime = form.time[1]
this.handlePaper()
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() {
this.$emit('update:form', this.$parent.curOriginForm)
this.$emit('hideSet')
}
}
};
</script>
<style scoped lang="scss"></style>
<style scoped lang="scss">
</style>

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

Loading…
Cancel
Save