commit:修改微服务工程目录名称

This commit is contained in:
Jerry
2020-09-26 20:14:58 +08:00
parent d05ad53a17
commit 322b3bc19d
463 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
> 1%
last 2 versions

View File

@@ -0,0 +1,5 @@
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true

View File

@@ -0,0 +1,40 @@
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/essential',
'@vue/standard'
],
parserOptions: {
parser: 'babel-eslint'
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'semi': ['off', 'always'],
'prefer-promise-reject-errors': ['error', { 'allowEmptyReject': true }],
'no-trailing-spaces': ['error', { 'skipBlankLines': true }],
'prefer-const': ['off'],
'quote-props': ['off'],
'object-curly-spacing': ['off'],
'dot-notation': ['off'],
'lines-between-class-members': ['off'],
// 'no-undef': ['off', 'always'],
// 'no-unused-vars': ['off', 'always'],
'no-new-func': ['off', 'always'],
'no-console': ['off']
},
overrides: [
{
files: [
'**/__tests__/*.{j,t}s?(x)',
'**/tests/unit/**/*.spec.{j,t}s?(x)'
],
env: {
jest: true
}
}
]
}

21
orange-demo-multi-web/.gitignore vendored Normal file
View File

@@ -0,0 +1,21 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@@ -0,0 +1,15 @@
## 橙单代码生成器
### 构建命令
``` bash
# install dependencies
npm install
# serve with hot reload at localhost:8080
npm run dev
# build for production with minification
npm run build
# run all tests
npm test
```

View File

@@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

View File

@@ -0,0 +1,3 @@
module.exports = {
preset: '@vue/cli-plugin-unit-jest'
}

View File

@@ -0,0 +1,61 @@
{
"name": "orange-single-page-project",
"version": "1.0.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"dev": "vue-cli-service serve",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^0.18.0",
"echarts": "^4.2.1",
"element-ui": "^2.13.0",
"jquery": "^3.3.1",
"jsencrypt": "^3.0.0-rc.1",
"json-bigint": "^0.3.0",
"layui-layer": "^1.0.9",
"lodash": "^4.17.5",
"core-js": "^3.6.4",
"register-service-worker": "^1.6.2",
"sortablejs": "^1.7.0",
"v-charts": "^1.19.0",
"vue": "^2.6.11",
"vue-router": "^3.1.5",
"vuex": "^3.1.2",
"wangeditor": "^3.1.1"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.2.0",
"@vue/cli-plugin-eslint": "~4.2.0",
"@vue/cli-plugin-pwa": "~4.2.0",
"@vue/cli-plugin-router": "~4.2.0",
"@vue/cli-plugin-unit-jest": "~4.2.0",
"@vue/cli-plugin-vuex": "~4.2.0",
"@vue/cli-service": "~4.2.0",
"@vue/eslint-config-standard": "^5.1.0",
"@vue/test-utils": "1.0.0-beta.31",
"babel-eslint": "^10.0.3",
"eslint": "^6.7.2",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^6.1.2",
"lint-staged": "^9.5.0",
"node-sass": "^4.13.1",
"sass-loader": "^7.3.1",
"vue-template-compiler": "^2.6.11"
},
"gitHooks": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*.{js,jsx,vue}": [
"vue-cli-service lint",
"git add"
]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,149 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="16.000000pt" height="16.000000pt" viewBox="0 0 16.000000 16.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.11, written by Peter Selinger 2001-2013
</metadata>
<g transform="translate(0.000000,16.000000) scale(0.000320,-0.000320)"
fill="#000000" stroke="none">
<path d="M18 46618 c45 -75 122 -207 122 -211 0 -2 25 -45 55 -95 30 -50 55
-96 55 -102 0 -5 5 -10 10 -10 6 0 10 -4 10 -9 0 -5 73 -135 161 -288 89 -153
173 -298 187 -323 14 -25 32 -57 41 -72 88 -149 187 -324 189 -335 2 -7 8 -13
13 -13 5 0 9 -4 9 -10 0 -5 46 -89 103 -187 175 -302 490 -846 507 -876 8 -16
20 -36 25 -45 28 -46 290 -498 339 -585 13 -23 74 -129 136 -236 61 -107 123
-215 137 -240 14 -25 29 -50 33 -56 5 -5 23 -37 40 -70 18 -33 38 -67 44 -75
11 -16 21 -33 63 -109 14 -25 29 -50 33 -56 4 -5 21 -35 38 -65 55 -100 261
-455 269 -465 4 -5 14 -21 20 -35 15 -29 41 -75 103 -180 24 -41 52 -88 60
-105 9 -16 57 -100 107 -185 112 -193 362 -626 380 -660 8 -14 23 -38 33 -55
11 -16 23 -37 27 -45 4 -8 26 -46 48 -85 23 -38 53 -90 67 -115 46 -81 64
-113 178 -310 62 -107 121 -210 132 -227 37 -67 56 -99 85 -148 16 -27 32 -57
36 -65 4 -8 15 -27 25 -42 9 -15 53 -89 96 -165 44 -76 177 -307 296 -513 120
-206 268 -463 330 -570 131 -227 117 -203 200 -348 36 -62 73 -125 82 -140 10
-15 21 -34 25 -42 4 -8 20 -37 36 -65 17 -27 38 -65 48 -82 49 -85 64 -111 87
-153 13 -25 28 -49 32 -55 4 -5 78 -134 165 -285 87 -151 166 -288 176 -305
10 -16 26 -43 35 -59 9 -17 125 -217 257 -445 132 -229 253 -441 270 -471 17
-30 45 -79 64 -108 18 -29 33 -54 33 -57 0 -2 20 -37 44 -77 24 -40 123 -212
221 -383 97 -170 190 -330 205 -355 16 -25 39 -65 53 -90 13 -25 81 -144 152
-265 70 -121 137 -238 150 -260 12 -22 37 -65 55 -95 18 -30 43 -73 55 -95 12
-22 48 -85 80 -140 77 -132 163 -280 190 -330 13 -22 71 -123 130 -225 59
-102 116 -199 126 -217 10 -17 29 -50 43 -72 15 -22 26 -43 26 -45 0 -2 27
-50 60 -106 33 -56 60 -103 60 -105 0 -2 55 -98 90 -155 8 -14 182 -316 239
-414 13 -22 45 -79 72 -124 27 -46 49 -86 49 -89 0 -2 14 -24 30 -48 16 -24
30 -46 30 -49 0 -5 74 -135 100 -176 5 -8 24 -42 43 -75 50 -88 58 -101 262
-455 104 -179 199 -345 213 -370 14 -25 28 -49 32 -55 4 -5 17 -26 28 -45 10
-19 62 -109 114 -200 114 -197 133 -230 170 -295 16 -27 33 -57 38 -65 17 -28
96 -165 103 -180 4 -8 16 -28 26 -45 10 -16 77 -131 148 -255 72 -124 181
-313 243 -420 62 -107 121 -209 131 -227 35 -62 323 -560 392 -678 38 -66 83
-145 100 -175 16 -30 33 -59 37 -65 4 -5 17 -27 29 -47 34 -61 56 -100 90
-156 17 -29 31 -55 31 -57 0 -2 17 -32 39 -67 21 -35 134 -229 251 -433 117
-203 235 -407 261 -451 27 -45 49 -85 49 -88 0 -4 8 -19 19 -34 15 -21 200
-341 309 -533 10 -19 33 -58 51 -87 17 -29 31 -54 31 -56 0 -2 25 -44 55 -94
30 -50 55 -95 55 -98 0 -4 6 -15 14 -23 7 -9 27 -41 43 -71 17 -30 170 -297
342 -594 171 -296 311 -542 311 -547 0 -5 5 -9 10 -9 6 0 10 -4 10 -10 0 -5
22 -47 49 -92 27 -46 58 -99 68 -118 24 -43 81 -140 93 -160 5 -8 66 -114 135
-235 69 -121 130 -227 135 -235 12 -21 259 -447 283 -490 10 -19 28 -47 38
-62 11 -14 19 -29 19 -32 0 -3 37 -69 83 -148 99 -170 305 -526 337 -583 13
-22 31 -53 41 -70 11 -16 22 -37 26 -45 7 -14 82 -146 103 -180 14 -24 181
-311 205 -355 13 -22 46 -80 75 -130 29 -49 64 -110 78 -135 14 -25 51 -88 82
-140 31 -52 59 -102 63 -110 4 -8 18 -33 31 -55 205 -353 284 -489 309 -535
17 -30 45 -78 62 -106 18 -28 36 -60 39 -72 4 -12 12 -22 17 -22 5 0 9 -4 9
-10 0 -5 109 -197 241 -427 133 -230 250 -431 259 -448 51 -90 222 -385 280
-485 37 -63 78 -135 92 -160 14 -25 67 -117 118 -205 51 -88 101 -175 111
-193 34 -58 55 -95 149 -257 51 -88 101 -173 110 -190 9 -16 76 -131 147 -255
72 -124 140 -241 151 -260 61 -108 281 -489 355 -615 38 -66 77 -133 87 -150
35 -63 91 -161 100 -175 14 -23 99 -169 128 -220 54 -97 135 -235 142 -245 4
-5 20 -32 35 -60 26 -48 238 -416 276 -480 10 -16 26 -46 37 -65 30 -53 382
-661 403 -695 10 -16 22 -37 26 -45 4 -8 26 -48 50 -88 24 -41 43 -75 43 -77
0 -2 22 -40 50 -85 27 -45 50 -84 50 -86 0 -3 38 -69 83 -147 84 -142 302
-520 340 -587 10 -19 34 -60 52 -90 18 -30 44 -75 57 -100 14 -25 45 -79 70
-120 25 -41 56 -96 70 -121 14 -25 77 -133 138 -240 62 -107 122 -210 132
-229 25 -43 310 -535 337 -581 11 -19 26 -45 34 -59 17 -32 238 -414 266 -460
11 -19 24 -41 28 -49 3 -7 75 -133 160 -278 84 -146 153 -269 153 -274 0 -5 5
-9 10 -9 6 0 10 -4 10 -10 0 -5 82 -150 181 -322 182 -314 201 -346 240 -415
12 -21 80 -139 152 -263 71 -124 141 -245 155 -270 14 -25 28 -49 32 -55 6 -8
145 -248 220 -380 37 -66 209 -362 229 -395 11 -19 24 -42 28 -49 4 -8 67
-118 140 -243 73 -125 133 -230 133 -233 0 -2 15 -28 33 -57 19 -29 47 -78 64
-108 17 -30 53 -93 79 -139 53 -90 82 -141 157 -272 82 -142 115 -199 381
-659 142 -245 268 -463 281 -485 12 -22 71 -125 132 -230 60 -104 172 -298
248 -430 76 -132 146 -253 156 -270 11 -16 22 -36 26 -44 3 -8 30 -54 60 -103
29 -49 53 -91 53 -93 0 -3 18 -34 40 -70 22 -36 40 -67 40 -69 0 -2 37 -66 81
-142 45 -77 98 -168 119 -204 20 -36 47 -81 58 -100 12 -19 27 -47 33 -62 6
-16 15 -28 20 -28 5 0 9 -4 9 -9 0 -6 63 -118 140 -251 77 -133 140 -243 140
-245 0 -2 18 -33 41 -70 22 -37 49 -83 60 -101 10 -19 29 -51 40 -71 25 -45
109 -189 126 -218 7 -11 17 -29 22 -40 6 -11 22 -38 35 -60 14 -22 37 -62 52
-90 14 -27 35 -62 45 -77 11 -14 19 -29 19 -32 0 -3 18 -35 40 -71 22 -36 40
-67 40 -69 0 -2 19 -35 42 -72 23 -38 55 -94 72 -124 26 -47 139 -244 171
-298 6 -9 21 -36 34 -60 28 -48 37 -51 51 -19 6 12 19 36 29 52 10 17 27 46
38 65 11 19 104 181 208 360 103 179 199 345 213 370 14 25 42 74 64 109 21
34 38 65 38 67 0 2 18 33 40 69 22 36 40 67 40 69 0 3 177 310 199 346 16 26
136 234 140 244 2 5 25 44 52 88 27 44 49 81 49 84 0 2 18 34 40 70 22 36 40
67 40 69 0 2 20 36 43 77 35 58 169 289 297 513 9 17 50 86 90 155 40 69 86
150 103 180 16 30 35 62 41 70 6 8 16 24 22 35 35 64 72 129 167 293 59 100
116 199 127 220 11 20 30 53 41 72 43 72 1070 1850 1121 1940 14 25 65 113
113 195 48 83 96 166 107 185 10 19 28 50 38 68 11 18 73 124 137 235 64 111
175 303 246 427 71 124 173 299 225 390 52 91 116 202 143 248 27 45 49 85 49
89 0 4 6 14 14 22 7 9 28 43 46 76 26 47 251 436 378 655 11 19 29 51 40 70
11 19 101 176 201 348 99 172 181 317 181 323 0 5 5 9 10 9 6 0 10 5 10 11 0
6 8 23 18 37 11 15 32 52 49 82 16 30 130 228 253 440 122 212 234 405 248
430 13 25 39 70 57 100 39 65 69 117 130 225 25 44 50 87 55 95 12 19 78 134
220 380 61 107 129 224 150 260 161 277 222 382 246 425 15 28 47 83 71 123
24 41 43 78 43 83 0 5 4 9 8 9 4 0 13 12 19 28 7 15 23 45 36 67 66 110 277
478 277 483 0 3 6 13 14 21 7 9 27 41 43 71 17 30 45 80 63 110 34 57 375 649
394 685 6 11 16 27 22 35 6 8 26 42 44 75 18 33 41 74 51 90 10 17 24 41 32
55 54 97 72 128 88 152 11 14 19 28 19 30 0 3 79 141 175 308 96 167 175 305
175 308 0 3 6 13 14 21 7 9 26 39 41 66 33 60 276 483 338 587 24 40 46 80 50
88 4 8 13 24 20 35 14 23 95 163 125 215 11 19 52 91 92 160 40 69 80 139 90
155 9 17 103 179 207 360 105 182 200 346 211 365 103 181 463 802 489 845 7
11 15 27 19 35 4 8 29 51 55 95 64 110 828 1433 848 1470 9 17 24 41 33 55 9
14 29 48 45 77 15 28 52 93 82 145 30 51 62 107 71 123 17 30 231 398 400 690
51 88 103 179 115 202 12 23 26 48 32 55 6 7 24 38 40 68 17 30 61 107 98 170
37 63 84 144 103 180 19 36 41 72 48 81 8 8 14 18 14 21 0 4 27 51 59 106 32
55 72 124 89 154 16 29 71 125 122 213 51 88 104 180 118 205 13 25 28 50 32
55 4 6 17 26 28 45 11 19 45 80 77 135 31 55 66 116 77 135 11 19 88 152 171
295 401 694 620 1072 650 1125 11 19 87 152 170 295 83 143 158 273 166 288 9
16 21 36 26 45 6 9 31 52 55 96 25 43 54 94 66 115 11 20 95 164 186 321 91
157 173 299 182 315 9 17 26 46 37 65 12 19 66 114 121 210 56 96 108 186 117
200 8 14 24 40 34 59 24 45 383 664 412 713 5 9 17 29 26 45 15 28 120 210
241 419 36 61 68 117 72 125 4 8 12 23 19 34 35 57 245 420 262 453 11 20 35
61 53 90 17 29 32 54 32 56 0 3 28 51 62 108 33 57 70 119 80 138 10 19 23 42
28 50 5 8 32 53 59 100 27 47 149 258 271 470 122 212 234 405 248 430 30 53
62 108 80 135 6 11 15 27 19 35 4 8 85 150 181 315 96 165 187 323 202 350 31
56 116 202 130 225 5 8 25 42 43 75 19 33 92 159 162 280 149 257 157 271 202
350 19 33 38 67 43 75 9 14 228 392 275 475 12 22 55 96 95 165 40 69 80 139
90 155 24 42 202 350 221 383 9 15 27 47 41 72 14 25 75 131 136 236 61 106
121 210 134 232 99 172 271 470 279 482 5 8 23 40 40 70 18 30 81 141 142 245
60 105 121 210 135 235 14 25 71 124 127 220 56 96 143 247 194 335 51 88 96
167 102 175 14 24 180 311 204 355 23 43 340 590 356 615 5 8 50 87 101 175
171 301 517 898 582 1008 25 43 46 81 46 83 0 2 12 23 27 47 14 23 40 67 56
97 16 30 35 62 42 70 7 8 15 22 18 30 4 8 20 38 37 65 16 28 33 57 37 65 6 12
111 196 143 250 5 8 55 95 112 193 57 98 113 195 126 215 12 20 27 46 32 57 6
11 14 27 20 35 5 8 76 130 156 270 80 140 165 287 187 325 23 39 52 90 66 115
13 25 30 52 37 61 8 8 14 18 14 21 0 4 41 77 92 165 50 87 175 302 276 478
101 176 208 360 236 408 28 49 67 117 86 152 19 35 41 70 48 77 6 6 12 15 12
19 0 7 124 224 167 291 12 21 23 40 23 42 0 2 21 40 46 83 26 43 55 92 64 109
54 95 327 568 354 614 19 30 45 75 59 100 71 128 82 145 89 148 4 2 8 8 8 13
0 5 42 82 94 172 311 538 496 858 518 897 14 25 40 70 58 100 18 30 42 71 53
90 10 19 79 139 152 265 73 127 142 246 153 265 10 19 43 76 72 125 29 50 63
108 75 130 65 116 80 140 87 143 4 2 8 8 8 12 0 8 114 212 140 250 6 8 14 24
20 35 5 11 54 97 108 190 l100 170 -9611 3 c-5286 1 -9614 -1 -9618 -5 -5 -6
-419 -719 -619 -1068 -89 -155 -267 -463 -323 -560 -38 -66 -81 -140 -95 -165
-31 -56 -263 -457 -526 -910 -110 -190 -224 -388 -254 -440 -29 -52 -61 -109
-71 -125 -23 -39 -243 -420 -268 -465 -11 -19 -204 -352 -428 -740 -224 -388
-477 -826 -563 -975 -85 -148 -185 -322 -222 -385 -37 -63 -120 -207 -185
-320 -65 -113 -177 -306 -248 -430 -72 -124 -172 -297 -222 -385 -51 -88 -142
-245 -202 -350 -131 -226 -247 -427 -408 -705 -65 -113 -249 -432 -410 -710
-160 -278 -388 -673 -506 -877 -118 -205 -216 -373 -219 -373 -3 0 -52 82
-109 183 -58 100 -144 250 -192 332 -95 164 -402 696 -647 1120 -85 149 -228
396 -317 550 -212 365 -982 1700 -1008 1745 -10 19 -43 76 -72 125 -29 50 -64
110 -77 135 -14 25 -63 110 -110 190 -47 80 -96 165 -110 190 -14 25 -99 171
-188 325 -89 154 -174 300 -188 325 -13 25 -64 113 -112 195 -48 83 -140 242
-205 355 -65 113 -183 317 -263 454 -79 137 -152 264 -163 282 -50 89 -335
583 -354 614 -12 19 -34 58 -50 85 -15 28 -129 226 -253 440 -124 215 -235
408 -247 430 -12 22 -69 121 -127 220 -58 99 -226 389 -373 645 -148 256 -324
561 -392 678 -67 117 -134 232 -147 255 -13 23 -33 59 -46 80 l-22 37 -9615 0
-9615 0 20 -32z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>橙单示例工程</title>
</head>
<body class="demo-project">
<noscript>
<strong>We're sorry but 橙单示例工程 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@@ -0,0 +1,2 @@
User-agent: *
Disallow:

View File

@@ -0,0 +1,19 @@
<template>
<div>
<router-view></router-view>
</div>
</template>
<script>
export default {
watch: {
$route: {
handler (newValue) {
document.title = '橙单工程';
if (newValue.meta && newValue.meta.title) document.title += ' - ' + newValue.meta.title;
},
immediate: true
}
}
}
</script>

View File

@@ -0,0 +1,65 @@
export default class ClassController {
static list (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/class/list', 'post', params, axiosOption, httpOption);
}
static view (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/class/view', 'get', params, axiosOption, httpOption);
}
static export (sender, params, fileName) {
return sender.download('/admin/CourseClass/class/export', params, fileName);
}
static add (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/class/add', 'post', params, axiosOption, httpOption);
}
static update (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/class/update', 'post', params, axiosOption, httpOption);
}
static delete (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/class/delete', 'post', params, axiosOption, httpOption);
}
static listClassCourse (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/class/listClassCourse', 'post', params, axiosOption, httpOption);
}
static listNotInClassCourse (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/class/listNotInClassCourse', 'post', params, axiosOption, httpOption);
}
static addClassCourse (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/class/addClassCourse', 'post', params, axiosOption, httpOption);
}
static updateClassCourse (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/class/updateClassCourse', 'post', params, axiosOption, httpOption);
}
static deleteClassCourse (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/class/deleteClassCourse', 'post', params, axiosOption, httpOption);
}
static listClassStudent (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/class/listClassStudent', 'post', params, axiosOption, httpOption);
}
static listNotInClassStudent (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/class/listNotInClassStudent', 'post', params, axiosOption, httpOption);
}
static addClassStudent (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/class/addClassStudent', 'post', params, axiosOption, httpOption);
}
static updateClassStudent (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/class/updateClassStudent', 'post', params, axiosOption, httpOption);
}
static deleteClassStudent (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/class/deleteClassStudent', 'post', params, axiosOption, httpOption);
}
}

View File

@@ -0,0 +1,25 @@
export default class CourseController {
static list (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/course/list', 'post', params, axiosOption, httpOption);
}
static view (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/course/view', 'get', params, axiosOption, httpOption);
}
static export (sender, params, fileName) {
return sender.download('/admin/CourseClass/course/export', params, fileName);
}
static add (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/course/add', 'post', params, axiosOption, httpOption);
}
static update (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/course/update', 'post', params, axiosOption, httpOption);
}
static delete (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/course/delete', 'post', params, axiosOption, httpOption);
}
}

View File

@@ -0,0 +1,17 @@
export default class CourseTransStatsController {
static list (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/stats/courseTransStats/list', 'post', params, axiosOption, httpOption);
}
static view (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/stats/courseTransStats/view', 'get', params, axiosOption, httpOption);
}
static export (sender, params, fileName) {
return sender.download('/admin/stats/courseTransStats/export', params, fileName);
}
static listWithGroup (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/stats/courseTransStats/listWithGroup', 'post', params, axiosOption, httpOption);
}
}

View File

@@ -0,0 +1,155 @@
import * as staticDict from '@/staticDict'
export default class DictionaryController {
static dictSysUserStatus () {
return new Promise((resolve) => {
resolve(staticDict.SysUserStatus);
});
}
static dictSysUserType () {
return new Promise((resolve) => {
resolve(staticDict.SysUserType);
});
}
static dictClassStatus () {
return new Promise((resolve) => {
resolve(staticDict.ClassStatus);
});
}
static dictClassLevel () {
return new Promise((resolve) => {
resolve(staticDict.ClassLevel);
});
}
static dictCourseDifficult () {
return new Promise((resolve) => {
resolve(staticDict.CourseDifficult);
});
}
static dictSubject () {
return new Promise((resolve) => {
resolve(staticDict.Subject);
});
}
static dictStudentActionType () {
return new Promise((resolve) => {
resolve(staticDict.StudentActionType);
});
}
static dictDeviceType () {
return new Promise((resolve) => {
resolve(staticDict.DeviceType);
});
}
static dictGender () {
return new Promise((resolve) => {
resolve(staticDict.Gender);
});
}
static dictExpLevel () {
return new Promise((resolve) => {
resolve(staticDict.ExpLevel);
});
}
static dictStudentStatus () {
return new Promise((resolve) => {
resolve(staticDict.StudentStatus);
});
}
static dictAreaCode (sender, params, axiosOption, httpOption) {
return new Promise((resolve, reject) => {
sender.doUrl('/admin/CourseClass/areaCode/listDictAreaCode', 'get', params, axiosOption, httpOption).then(res => {
let dictData = new staticDict.DictionaryBase();
dictData.setList(res.data);
resolve(dictData);
}).catch(err => {
reject(err);
});
});
}
static dictAreaCodeByParentId (sender, params, axiosOption, httpOption) {
return new Promise((resolve, reject) => {
sender.doUrl('/admin/CourseClass/areaCode/listDictAreaCodeByParentId', 'get', params, axiosOption, httpOption).then(res => {
let dictData = new staticDict.DictionaryBase();
dictData.setList(res.data);
resolve(dictData);
}).catch(err => {
reject(err);
});
});
}
static dictAddAreaCode (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/areaCode/add', 'post', params, axiosOption, httpOption);
}
static dictDeleteAreaCode (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/areaCode/delete', 'post', params, axiosOption, httpOption);
}
static dictBatchDeleteAreaCode (sender, params, axiosOption, httpOption) {
return sender.doUrl('', 'post', params, axiosOption, httpOption);
}
static dictUpdateAreaCode (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/areaCode/update', 'post', params, axiosOption, httpOption);
}
static dictReloadAreaCodeCachedData (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/areaCode/reloadCachedData', 'get', params, axiosOption, httpOption);
}
static dictCourse (sender, params, axiosOption, httpOption) {
return new Promise((resolve, reject) => {
sender.doUrl('/admin/CourseClass/course/listDictCourse', 'get', params, axiosOption, httpOption).then(res => {
let dictData = new staticDict.DictionaryBase();
dictData.setList(res.data);
resolve(dictData);
}).catch(err => {
reject(err);
});
});
}
static dictGrade (sender, params, axiosOption, httpOption) {
return new Promise((resolve, reject) => {
sender.doUrl('/admin/CourseClass/grade/listDictGrade', 'get', params, axiosOption, httpOption).then(res => {
let dictData = new staticDict.DictionaryBase();
dictData.setList(res.data);
resolve(dictData);
}).catch(err => {
reject(err);
});
});
}
static dictAddGrade (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/grade/add', 'post', params, axiosOption, httpOption);
}
static dictDeleteGrade (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/grade/delete', 'post', params, axiosOption, httpOption);
}
static dictBatchDeleteGrade (sender, params, axiosOption, httpOption) {
return sender.doUrl('', 'post', params, axiosOption, httpOption);
}
static dictUpdateGrade (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/grade/update', 'post', params, axiosOption, httpOption);
}
static dictReloadGradeCachedData (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/grade/reloadCachedData', 'get', params, axiosOption, httpOption);
}
static dictSchoolInfo (sender, params, axiosOption, httpOption) {
return new Promise((resolve, reject) => {
sender.doUrl('/admin/CourseClass/schoolInfo/listDictSchoolInfo', 'get', params, axiosOption, httpOption).then(res => {
let dictData = new staticDict.DictionaryBase();
dictData.setList(res.data);
resolve(dictData);
}).catch(err => {
reject(err);
});
});
}
static dictStudent (sender, params, axiosOption, httpOption) {
return new Promise((resolve, reject) => {
sender.doUrl('/admin/CourseClass/student/listDictStudent', 'get', params, axiosOption, httpOption).then(res => {
let dictData = new staticDict.DictionaryBase();
dictData.setList(res.data);
resolve(dictData);
}).catch(err => {
reject(err);
});
});
}
}

View File

@@ -0,0 +1,25 @@
export default class SchoolInfoController {
static list (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/schoolInfo/list', 'post', params, axiosOption, httpOption);
}
static view (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/schoolInfo/view', 'get', params, axiosOption, httpOption);
}
static export (sender, params, fileName) {
return sender.download('/admin/CourseClass/schoolInfo/export', params, fileName);
}
static add (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/schoolInfo/add', 'post', params, axiosOption, httpOption);
}
static update (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/schoolInfo/update', 'post', params, axiosOption, httpOption);
}
static delete (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/schoolInfo/delete', 'post', params, axiosOption, httpOption);
}
}

View File

@@ -0,0 +1,17 @@
export default class StudentActionStatsController {
static list (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/stats/studentActionStats/list', 'post', params, axiosOption, httpOption);
}
static view (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/stats/studentActionStats/view', 'get', params, axiosOption, httpOption);
}
static export (sender, params, fileName) {
return sender.download('/admin/stats/studentActionStats/export', params, fileName);
}
static listWithGroup (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/stats/studentActionStats/listWithGroup', 'post', params, axiosOption, httpOption);
}
}

View File

@@ -0,0 +1,25 @@
export default class StudentActionTransController {
static list (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/stats/studentActionTrans/list', 'post', params, axiosOption, httpOption);
}
static view (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/stats/studentActionTrans/view', 'get', params, axiosOption, httpOption);
}
static export (sender, params, fileName) {
return sender.download('/admin/stats/studentActionTrans/export', params, fileName);
}
static add (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/stats/studentActionTrans/add', 'post', params, axiosOption, httpOption);
}
static update (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/stats/studentActionTrans/update', 'post', params, axiosOption, httpOption);
}
static delete (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/stats/studentActionTrans/delete', 'post', params, axiosOption, httpOption);
}
}

View File

@@ -0,0 +1,65 @@
export default class StudentClassController {
static list (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/studentClass/list', 'post', params, axiosOption, httpOption);
}
static view (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/studentClass/view', 'get', params, axiosOption, httpOption);
}
static export (sender, params, fileName) {
return sender.download('/admin/CourseClass/studentClass/export', params, fileName);
}
static add (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/studentClass/add', 'post', params, axiosOption, httpOption);
}
static update (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/studentClass/update', 'post', params, axiosOption, httpOption);
}
static delete (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/studentClass/delete', 'post', params, axiosOption, httpOption);
}
static listClassCourse (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/studentClass/listClassCourse', 'post', params, axiosOption, httpOption);
}
static listNotInClassCourse (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/studentClass/listNotInClassCourse', 'post', params, axiosOption, httpOption);
}
static addClassCourse (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/studentClass/addClassCourse', 'post', params, axiosOption, httpOption);
}
static updateClassCourse (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/studentClass/updateClassCourse', 'post', params, axiosOption, httpOption);
}
static deleteClassCourse (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/studentClass/deleteClassCourse', 'post', params, axiosOption, httpOption);
}
static listClassStudent (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/studentClass/listClassStudent', 'post', params, axiosOption, httpOption);
}
static listNotInClassStudent (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/studentClass/listNotInClassStudent', 'post', params, axiosOption, httpOption);
}
static addClassStudent (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/studentClass/addClassStudent', 'post', params, axiosOption, httpOption);
}
static updateClassStudent (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/studentClass/updateClassStudent', 'post', params, axiosOption, httpOption);
}
static deleteClassStudent (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/studentClass/deleteClassStudent', 'post', params, axiosOption, httpOption);
}
}

View File

@@ -0,0 +1,25 @@
export default class StudentController {
static list (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/student/list', 'post', params, axiosOption, httpOption);
}
static view (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/student/view', 'get', params, axiosOption, httpOption);
}
static export (sender, params, fileName) {
return sender.download('/admin/CourseClass/student/export', params, fileName);
}
static add (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/student/add', 'post', params, axiosOption, httpOption);
}
static update (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/student/update', 'post', params, axiosOption, httpOption);
}
static delete (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/CourseClass/student/delete', 'post', params, axiosOption, httpOption);
}
}

View File

@@ -0,0 +1,61 @@
export default class SysDataPermController {
/**
* @param params {dataPermId, dataPermName, deptIdListString}
*/
static add (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysDataPerm/add', 'post', params, axiosOption, httpOption);
}
/**
* @param params {dataPermId, dataPermName, deptIdListString}
*/
static update (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysDataPerm/update', 'post', params, axiosOption, httpOption);
}
/**
* @param params {dataPermId}
*/
static delete (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysDataPerm/delete', 'post', params, axiosOption, httpOption);
}
/**
* @param params {dataPermName}
*/
static list (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysDataPerm/list', 'post', params, axiosOption, httpOption);
}
/**
* @param params {dataPermId}
*/
static view (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysDataPerm/view', 'get', params, axiosOption, httpOption);
}
/**
* @param params {dataPermId, searchString}
*/
static listDataPermUser (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysDataPerm/listDataPermUser', 'post', params, axiosOption, httpOption);
}
/**
* @param params {dataPermId, userIdListString}
*/
static addDataPermUser (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysDataPerm/addDataPermUser', 'post', params, axiosOption, httpOption);
}
/**
* @param params {dataPermId, userId}
*/
static deleteDataPermUser (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysDataPerm/deleteDataPermUser', 'post', params, axiosOption, httpOption);
}
static listNotInDataPermUser (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysDataPerm/listNotInDataPermUser', 'post', params, axiosOption, httpOption);
}
}

View File

@@ -0,0 +1,25 @@
export default class SysDeptController {
static list (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/upms/sysDept/list', 'post', params, axiosOption, httpOption);
}
static view (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/upms/sysDept/view', 'get', params, axiosOption, httpOption);
}
static export (sender, params, fileName) {
return sender.download('/admin/upms/sysDept/export', params, fileName);
}
static add (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/upms/sysDept/add', 'post', params, axiosOption, httpOption);
}
static update (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/upms/sysDept/update', 'post', params, axiosOption, httpOption);
}
static delete (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/upms/sysDept/delete', 'post', params, axiosOption, httpOption);
}
}

View File

@@ -0,0 +1,25 @@
export default class SysUserController {
static list (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/upms/sysUser/list', 'post', params, axiosOption, httpOption);
}
static view (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/upms/sysUser/view', 'get', params, axiosOption, httpOption);
}
static export (sender, params, fileName) {
return sender.download('/admin/upms/sysUser/export', params, fileName);
}
static add (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/upms/sysUser/add', 'post', params, axiosOption, httpOption);
}
static update (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/upms/sysUser/update', 'post', params, axiosOption, httpOption);
}
static delete (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/upms/sysUser/delete', 'post', params, axiosOption, httpOption);
}
}

View File

@@ -0,0 +1,201 @@
export default class SystemController {
static login (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/login/doLogin', 'get', params, axiosOption, httpOption);
}
static logout (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/login/doLogout', 'post', params, axiosOption, httpOption);
}
static changePassword (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/login/changePassword', 'post', params, axiosOption, httpOption);
}
static getDictList (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysDict/list', 'post', params, axiosOption, httpOption);
}
static getRoleList (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysRole/list', 'post', params, axiosOption, httpOption);
}
static getRole (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysRole/view', 'get', params, axiosOption, httpOption);
}
static deleteRole (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysRole/delete', 'post', params, axiosOption, httpOption);
}
static addRole (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysRole/add', 'post', params, axiosOption, httpOption);
}
static updateRole (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysRole/update', 'post', params, axiosOption, httpOption);
}
static getUserList (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysUser/list', 'post', params, axiosOption, httpOption);
}
static getUser (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysUser/view', 'get', params, axiosOption, httpOption);
}
static resetUserPassword (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysUser/resetPassword', 'post', params, axiosOption, httpOption);
}
static deleteUser (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysUser/delete', 'post', params, axiosOption, httpOption);
}
static addUser (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysUser/add', 'post', params, axiosOption, httpOption);
}
static updateUser (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysUser/update', 'post', params, axiosOption, httpOption);
}
// 菜单接口
static getMenuPermList (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysMenu/list', 'get', params, axiosOption, httpOption);
}
static addMenu (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysMenu/add', 'post', params, axiosOption, httpOption);
}
static updateMenu (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysMenu/update', 'post', params, axiosOption, httpOption);
}
static deleteMenu (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysMenu/delete', 'post', params, axiosOption, httpOption);
}
static viewMenu (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysMenu/view', 'get', params, axiosOption, httpOption);
}
static listMenuPerm (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysMenu/listMenuPerm', 'get', params, axiosOption, httpOption);
}
// 权限字接口
static getPermCodeList (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysPermCode/list', 'post', params, axiosOption, httpOption);
}
static addPermCode (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysPermCode/add', 'post', params, axiosOption, httpOption);
}
static updatePermCode (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysPermCode/update', 'post', params, axiosOption, httpOption);
}
static deletePermCode (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysPermCode/delete', 'post', params, axiosOption, httpOption);
}
static viewPermCode (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysPermCode/view', 'get', params, axiosOption, httpOption);
}
// 权限资源接口
static getAllPermList (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysPermModule/listAll', 'get', params, axiosOption, httpOption);
}
static getPermGroupList (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysPermModule/list', 'get', params, axiosOption, httpOption);
}
static addPermGroup (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysPermModule/add', 'post', params, axiosOption, httpOption);
}
static updatePermGroup (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysPermModule/update', 'post', params, axiosOption, httpOption);
}
static deletePermGroup (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysPermModule/delete', 'post', params, axiosOption, httpOption);
}
static getPermList (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysPerm/list', 'post', params, axiosOption, httpOption);
}
static viewPerm (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysPerm/view', 'get', params, axiosOption, httpOption);
}
static addPerm (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysPerm/add', 'post', params, axiosOption, httpOption);
}
static updatePerm (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysPerm/update', 'post', params, axiosOption, httpOption);
}
static deletePerm (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysPerm/delete', 'post', params, axiosOption, httpOption);
}
/**
* @param params {roleId, searchString}
*/
static listRoleUser (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysRole/listUserRole', 'post', params, axiosOption, httpOption);
}
static listNotInUserRole (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysRole/listNotInUserRole', 'post', params, axiosOption, httpOption);
}
/**
* @param params {roleId, userIdListString}
*/
static addRoleUser (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysRole/addUserRole', 'post', params, axiosOption, httpOption);
}
/**
* @param params {roleId, userId}
*/
static deleteRoleUser (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysRole/deleteUserRole', 'post', params, axiosOption, httpOption);
}
/**
* @param params {}
*/
static queryRoleByPermCode (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysRole/listAllRolesByPermCode', 'post', params, axiosOption, httpOption);
}
/**
* @param params {}
*/
static queryRoleByURL (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysRole/listAllRolesByPerm', 'post', params, axiosOption, httpOption);
}
/**
* @param params {}
*/
static queryPerm (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysUser/listAllPerms', 'post', params, axiosOption, httpOption);
}
/**
* @param params {}
*/
static queryPermCode (sender, params, axiosOption, httpOption) {
return sender.doUrl('admin/upms/sysRole/deleteUserRole', 'post', params, axiosOption, httpOption);
}
}

View File

@@ -0,0 +1,25 @@
import SystemController from './Controller/SystemController'
import SysDataPermController from './Controller/SysDataPermController'
import DictionaryController from './Controller/DictionaryController'
import CourseController from './Controller/CourseController.js'
import SchoolInfoController from './Controller/SchoolInfoController.js'
import StudentController from './Controller/StudentController.js'
import SysUserController from './Controller/SysUserController.js'
import StudentClassController from './Controller/StudentClassController.js'
import CourseTransStatsController from './Controller/CourseTransStatsController.js'
import StudentActionStatsController from './Controller/StudentActionStatsController.js'
import StudentActionTransController from './Controller/StudentActionTransController.js'
export {
SystemController,
SysDataPermController,
DictionaryController,
CourseController,
SchoolInfoController,
StudentController,
SysUserController,
StudentClassController,
CourseTransStatsController,
StudentActionStatsController,
StudentActionTransController
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 899 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,593 @@
@import "element-color.scss";
@import "transition.scss";
html, body {
padding: 0;
margin: 0;
font-size: 14px;
font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;
background-color: rgb(228,240,255);
}
*,
*:before,
*:after {
box-sizing: border-box;
}
$header-height: 60px;
// 过滤组件长度
$filter-item-width: 250px;
// 范围选择过滤组件长度
$filter-item-range-width: 400px;
// 左侧过滤树组件每一项高度
$tree-node-height: 40px;
// 高级管理表单标题高度
$advanced-title-height: 50px;
$border-color: rgb(216, 220, 229);
$menuHover: rgba(255,255,255,0.3);
$menu-background-color: transparent;
$tabs-header-margin-bottom: 25px;
$tab-header-background-color: #EBEEF5;
$image-item-width: 65px;
$box-padding-size: 25px;
/**
* 弹窗样式封装的layer的弹窗
**/
body .layer-dialog .layui-layer-title{
border-radius: 4px 4px 0px 0px;
border:1px solid #01000000;
}
body .layer-dialog .layui-layer-setwin {color: #ffffff}
body .layer-dialog {
border-radius: 4px;
border:1px solid #01000000;
}
body .layer-dialog .layui-layer-content {
padding: $box-padding-size;
}
.demo-project {
.el-main {
padding: 0px;
}
.flex-box {
flex-wrap: wrap;
}
.scrollbar_dropdown__wrap {
overflow-x: hidden;
}
.icon-btn.el-button {
font-size: 18px;
padding: 5px 0px;
}
.default-padding-box {
padding: $box-padding-size;
}
.padding-no-top {
padding: 0px $box-padding-size $box-padding-size $box-padding-size;
}
.default-border {
border: 1px solid $border-color1;
}
.default-border-left {
border-left: 1px solid $border-color1;
}
.default-border-right {
border-right: 1px solid $border-color1;
}
.default-border-top {
border-top: 1px solid $border-color1;
}
.default-border-bottom {
border-bottom: 1px solid $border-color1;
}
.page-close-box {
position: absolute;
background: #13ce66;
transform: rotate(45deg);
height: 60px;
width: 60px;
right: -30px;
top:-30px;
text-align: center;
.el-button {
transform: rotate(-45deg);
color: white;
margin-top: 30px;
}
}
/**
* 过滤组件样式
**/
.mask-box {
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.5);
top: 0;
z-index: 10;
}
.filter-box {
position: relative;
background-color: white;
padding: $box-padding-size $box-padding-size 0px $box-padding-size;
z-index: 20;
}
.advance-filter-box {
padding-bottom: 25px;
}
.filter-item {
width: $filter-item-width;
}
.cascader-item {
width: 160px!important;
}
.is-range, .is-search {
width: $filter-item-range-width;
}
.table-operation-box {
align-self: flex-end;
margin-bottom: 10px;
overflow: hidden;
}
/**
* 左侧树状组件的样式,用户高级管理表单以及用户管理表单
**/
.advanced-left-box {
border-right: 1px solid $border-color;
.el-tree-node__content {
height: $tree-node-height;
}
.tree-node-item {
height: $tree-node-height;
line-height: $tree-node-height;
width: 100%;
.tree-node-menu {
display: none;
float: right;
padding-right: 10px;
color: red!important;
}
&:hover .tree-node-menu {
display: block;
}
}
.el-tree-node .el-button+.el-button {
margin-left: 5px;
}
}
/**
* form表单输入组件宽度
**/
.full-width-input {
.el-select {
width: 100%;
}
.el-input {
width: 100%;
}
.el-cascader {
width: 100%;
}
.el-date-editor {
width: 100%;
}
.el-input-number {
width: 100%;
}
}
/**
* 左侧菜单样式
**/
.sidebar-bg {
background: linear-gradient(#FC8051, #EB6265);
}
.sidebar-title {
height: 160px;
overflow: hidden;
}
.sidebar-title-text {
width: 100%;
font-size: 18px;
color: #fff;
text-align: center;
margin: 0px;
}
.el-menu {
background-color: $menu-background-color;
border-right-width: 0px;
}
.menu-wrapper {
.el-menu {
background: linear-gradient(#FC8051, #EB6265);
}
.el-menu-item {
color: white;
i {
color: white;
}
&:hover {
background-color: rgba(255,255,255,0.3)!important;
}
}
.el-submenu {
.el-menu {
background: none;
}
}
}
.el-submenu__title i {
color: white;
}
.el-menu--collapse {
.el-submenu__icon-arrow {
display: none;
}
}
.nest-menu .el-submenu>.el-submenu__title, .el-submenu .el-menu-item {
min-width: 180px!important;
background: $menu-background-color;
}
.el-menu-item.is-active {
border-left: 3px solid #47ba5a;
background-color: rgba(255,255,255,0.3)!important;
}
.el-submenu__title {
background-color: $menu-background-color!important;
}
.el-menu {
border-right-width: 0px;
}
.menu-collapse-btn {
padding: 0px;
width: 15px;
border-radius: 2px;
border: none;
height: 100px;
background-color: $--color-primary-light-5;
position: fixed;
top: 20%;
z-index: -1;
color: white;
&:hover {
background-color: $--color-primary-light-7;
}
.chart-border {
border: 1px solid #EBEEF5;
}
}
/**
* 多tab页表单tab样式
**/
.el-tabs__header {
margin: 0 0 20px;
}
/**
* 表格表头背景色
**/
.table-header-gray, .has-gutter .gutter {
background-color: $tab-header-background-color;
}
/**
* 图片上传以及显示样式
**/
.upload-image-item {
font-size: 28px;
color: #8c939d;
width: $image-item-width;
height: $image-item-width;
text-align: center;
display: block;
.el-upload i {
line-height: $image-item-width;
}
}
.upload-image-multi {
display: inline;
}
.upload-image-item .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.upload-image-item .el-upload:hover {
border-color: #409eff;
}
.upload-image-show {
width: $image-item-width;
height: $image-item-width;
display: inline;
}
.table-cell-image {
width: $image-item-width;
height: $image-item-width;
line-height: $image-item-width;
text-align: center;
font-size: $image-item-width;
color: #606266;
margin: 0px 5px;
}
.upload-image-list .el-upload-list__item {
width: $image-item-width;
height: $image-item-width;
line-height: $image-item-width;
}
.upload-image-item .el-upload-list--picture-card .el-upload-list__item {
width: $image-item-width;
height: $image-item-width;
}
.upload-image-item .el-upload.el-upload--text {
width: $image-item-width;
height: $image-item-width;
}
.upload-image-item .el-upload--picture-card {
width: $image-item-width;
height: $image-item-width;
line-height: $image-item-width;
}
/**
*
**/
$header-menu-height: 32px;
.sidebar {
height: 100%;
background-color: #304156;
overflow: hidden;
}
.header {
display: flex;
height: $header-height;
background-color: white;
}
.header .menu-column {
margin-right: 20px;
.el-menu-item.is-active {
border-left: 0px solid #47ba5a;
}
}
.header-menu {
float: right;
height: $header-menu-height;
line-height: $header-menu-height;
margin-top: ($header-height - $header-menu-height) / 2;
}
.header-img {
width: $header-menu-height;
height: $header-menu-height;
border-radius: 50%;
margin-left: 10px;
float: right;
}
.user-dropdown {
color: $sub-text-color;
cursor: pointer;
font-size: 12px;
}
.user-dropdown-item {
font-size: 12px;
color: $main-text-color;
}
.hamburger-container {
line-height: 70px;
height: $header-height;
float: left;
padding: 0 10px;
}
.el-submenu__title {
background: #00000000;
}
::-webkit-scrollbar {
width: 7px;
height: 7px;
background: none;
}
::-webkit-scrollbar-thumb {
background: #DDDEE0;
border-radius: 7px;
}
::-webkit-scrollbar-thumb:hover {
background: #A8A8A8;
}
.tree-select {
.el-tree-node__content {
height: 34px;
line-height: 34px;
padding-right: 10px;
}
}
.tree-select.single-select-tree {
.el-tree-node.is-current > .el-tree-node__content > .el-tree-node__label {
color: $--color-primary;
font-weight: 700;
}
}
.cell {
.operation-cell {
color: #006CDC;
cursor: pointer;
text-decoration: underline;
}
}
.single-select-tree {
min-width: 200px!important;
}
.base-card-header {
display: flex;
align-items: center;
height: 50px;
line-height: 50px;
}
.base-card-operation {
flex-grow: 1;
display: flex;
justify-content: flex-end;
}
.el-card__header {
padding: 0px 15px;
}
.el-card__body {
padding: 15px;
}
.custom-cascader {
width: 200px!important;
}
.no-scroll {
overflow: hidden;
}
.custom-scroll .el-scrollbar__view {
overflow-x: hidden!important;
}
.upload-img-del {
position: absolute;
height: 20px;
width: 20px;
line-height: 20px;
font-size: 16px;
top: 2px;
right: 2px;
color: #C0C4CC;
}
.upload-img-del:hover {
color: #EF5E1C;
}
.input-label {
display: inline-block;
height: 29px;
line-height: 28px;
}
.input-progress {
height: 29px;
display: flex;
align-items: center;
}
.input-item {
width: 100%!important;
}
.table-header-gray {
background: rgba(237,237,237,1);
}
.card-header {
display: flex;
justify-content: space-between;
padding: 10px 0px;
line-height: 28px;
}
}
.ml20 {
margin-left: 20px;
}
.mr20 {
margin-right: 20px;
}
.mt20 {
margin-top: 20px;
}
.mb20 {
margin-bottom: 20px;
}
.pl20 {
padding-left: 20px;
}
.pr20 {
padding-right: 20px;
}
.pt20 {
padding-top: 20px;
}
.pb20 {
padding-bottom: 20px;
}

View File

@@ -0,0 +1,25 @@
$main-text-color: #303133;
$normal-text-color: #606266;
$sub-text-color: #909399;
$placeholder-text-color: #C0C4CC;
$border-color1: #DCDFE6;
$border-color2: #E4E7ED;
$border-color3: #EBEEF5;
$border-color4: #F2F6FC;
$success-color: #67C23A;
$warning-color: #E6A23C;
$danger-color: #F56C6C;
$info-color: #909399;
$--color-white: white;
$--color-primary: #EF5E1C !default;
$--color-primary-light-1: mix($--color-white, $--color-primary, 10%) !default; /* 53a8ff */
$--color-primary-light-2: mix($--color-white, $--color-primary, 20%) !default; /* 66b1ff */
$--color-primary-light-3: mix($--color-white, $--color-primary, 30%) !default; /* 79bbff */
$--color-primary-light-4: mix($--color-white, $--color-primary, 40%) !default; /* 8cc5ff */
$--color-primary-light-5: mix($--color-white, $--color-primary, 50%) !default; /* a0cfff */
$--color-primary-light-6: mix($--color-white, $--color-primary, 60%) !default; /* b3d8ff */
$--color-primary-light-7: mix($--color-white, $--color-primary, 70%) !default; /* c6e2ff */
$--color-primary-light-8: mix($--color-white, $--color-primary, 80%) !default; /* d9ecff */
$--color-primary-light-9: mix($--color-white, $--color-primary, 90%) !default; /* ecf5ff */

View File

@@ -0,0 +1,112 @@
.form-advanced-manager {
.advance-filter-box {
position: absolute;
top: 100%;
left: 0px;
background-color: white;
width: 100%;
padding: 10px $box-padding-size 15px $box-padding-size;
}
.title-box {
border-bottom: 1px solid $border-color;
padding: 0px 20px;
z-index: 20;
background-color: white;
height: $advanced-title-height;
.title {
line-height: $advanced-title-height;
color: #606266;
}
.menu-box {
position: absolute;
top: 0px;
right: 10px;
height: $advanced-title-height;
.el-row {
margin: 10px 0px;
height: $advanced-title-height - 20;
}
}
}
.advanced-right-box {
padding: 0px;
.gutter-box {
margin: (($advanced-title-height - 16)/2) 0px;
height: 16px;
width: 3px;
background-color: $--color-primary;
float: left
}
}
}
.form-dict-manager {
.dict-title {
height: 50px;
line-height: 50px;
color: $main-text-color;
border-bottom: 1px solid $border-color1;
font-size: 14px;
span {
margin-left: 20px;
}
}
.dict-item {
width: 100%;
height: 40px;
line-height: 40px;
color: #606266;
cursor: pointer;
padding-left: 20px;
&:hover {
background-color: $--color-primary-light-9;
}
}
.active-dict-item {
border-left: 3px solid $--color-primary;
color: $--color-primary;
background-color: $--color-primary-light-9 !important;
}
.el-scrollbar__bar.is-horizontal {
display: none!important;
}
}
.form-table-manager {
.advance-filter-box {
position: absolute;
padding: 20px;
top: 100%;
left: 0px;
background-color: white;
width: 100%;
padding: 10px $box-padding-size 15px $box-padding-size;
}
}
.form-table-multi-select {
//
}
.form-config {
padding: $box-padding-size;
}
.form-multi-fragment {
//
}
.form-single-fragment {
//
}

View File

@@ -0,0 +1,3 @@
@import "../theme/index.css";
@import "base.scss";
@import "form-style.scss";

View File

@@ -0,0 +1,31 @@
/*fade*/
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.28s;
}
.fade-enter,
.fade-leave-active {
opacity: 0;
}
/*fade*/
.breadcrumb-enter-active,
.breadcrumb-leave-active {
transition: all .5s;
}
.breadcrumb-enter,
.breadcrumb-leave-active {
opacity: 0;
transform: translateX(20px);
}
.breadcrumb-move {
transition: all .5s;
}
.breadcrumb-leave-active {
position: absolute;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,305 @@
<template>
<div class="date-range">
<!--<year-range-panel />-->
<el-select v-model="dateType" :size="size"
style="max-width: 100px; min-width: 100px; margin-right: 10px;"
v-if="!hideTypeOnlyOne || validTypeList.length > 1">
<el-option v-for="type in validTypeList" :key="type.value" :value="type.value" :label="type.label" />
</el-select>
<el-date-picker style="flex-grow: 1;" v-model="currentDates"
:size="size" :placeholder="placeholder" :type="innerDateType"
:disabled="disabled" :format="innerDateFormat" :readonly="readonly" :editable="editable"
:clearable="clearable" :start-placeholder="startPlaceholder" :end-placeholder="endPlaceholder"
:align="align" :range-separator="rangeSeparator" :value-format="valueFormat"
:prefix-icon="prefixIcon" :clear-icon="clearIcon" @change="onValueChange" />
</div>
</template>
<script>
import { formatDate, parseDate } from 'element-ui/src/utils/date-util';
const allTypeList = [{
value: 'day',
label: '自然日'
}, {
value: 'month',
label: '自然月'
}, {
value: 'year',
label: '自然年'
}];
export default {
name: 'DateRange',
props: {
/**
* 绑定的数据
*/
value: {
type: [Array],
default: () => {
return []
}
},
/**
* 默认显示的数据选择方式如果不存在与allowTypes中则显示allowTypes中的第一个
*/
defaultDateType: {
type: String,
default: 'day'
},
/**
* 组件大小medium / small / mini
*/
size: {
type: String
},
/**
* 数据选择方式只有一个的时候是否隐藏数据选择方式下拉
*/
hideTypeOnlyOne: {
type: Boolean,
default: true
},
/**
* 允许的数据选择方式day, month, year
* 默认值['day', 'month', 'year']
*/
allowTypes: {
type: Array,
default: () => {
return allTypeList.map((item) => {
return item.value;
});
}
},
/**
* 是否范围选择
*/
isRange: {
type: Boolean,
default: true
},
/**
* 输出字符串的format
*/
outputFormat: {
type: String,
default: 'yyyy-MM-dd HH:mm:ss'
},
/**
* 非范围选择时的占位内容
*/
placeholder: String,
/**
* 范围选择时开始日期的占位内容
*/
startPlaceholder: String,
/**
* 范围选择时结束日期的占位内容
*/
endPlaceholder: String,
/**
* 完全只读
*/
readonly: Boolean,
/**
* 禁用
*/
disabled: Boolean,
/**
* 文本框可输入
*/
editable: {
type: Boolean,
default: true
},
/**
* 是否显示清除按钮
*/
clearable: {
type: Boolean,
default: true
},
/**
* 对齐方式left, center, right
*/
align: {
type: String,
default: 'left'
},
/**
* 选择范围时的分隔符
*/
rangeSeparator: {
type: String,
default: '-'
},
/**
* 可选,绑定值的格式。不指定则绑定值为 Date 对象
*/
valueFormat: {
type: String,
default: 'yyyy-MM-dd'
},
/**
* 自定义头部图标的类名
*/
prefixIcon: {
type: String,
default: 'el-icon-date'
},
/**
* 自定义清空图标的类名
*/
clearIcon: {
type: String,
default: 'el-icon-circle-close'
}
},
data () {
return {
dateType: this.defaultDateType,
currentDates: undefined
}
},
methods: {
onValueChange (values) {
this.$nextTick(() => {
this.emitChange();
});
},
emitChange () {
let outputDate = [];
if (this.currentDates != null) {
if (!this.isRange) {
outputDate[0] = new Date(this.currentDates);
outputDate[1] = new Date(this.currentDates);
} else {
if (Array.isArray(this.currentDates) && this.currentDates.length === 2) {
outputDate[0] = new Date(this.currentDates[0]);
outputDate[1] = new Date(this.currentDates[1]);
}
}
if (outputDate[0] != null && outputDate[1] != null) {
outputDate[0].setHours(0, 0, 0, 0);
outputDate[1].setHours(0, 0, 0, 0);
switch (this.dateType) {
case 'day':
outputDate[1].setDate(outputDate[1].getDate() + 1);
break;
case 'month':
outputDate[1].setDate(1);
outputDate[0].setDate(1);
outputDate[1].setMonth(outputDate[1].getMonth() + 1);
break;
case 'year':
outputDate[1].setMonth(0);
outputDate[1].setDate(1);
outputDate[0].setMonth(0);
outputDate[0].setDate(1);
outputDate[1].setFullYear(outputDate[1].getFullYear() + 1);
break;
}
outputDate[1] = new Date(outputDate[1].getTime() - 1);
outputDate[0] = formatDate(outputDate[0], this.outputFormat);
outputDate[1] = formatDate(outputDate[1], this.outputFormat);
}
}
this.$emit('input', outputDate);
this.$emit('change', outputDate);
},
getCurrentStatsDateType () {
return this.dateType;
}
},
computed: {
validTypeList () {
return allTypeList.filter((item) => {
return this.allowTypes.indexOf(item.value) !== -1;
});
},
/**
* el-date-picker使用的type
*/
innerDateType () {
switch (this.dateType) {
case 'day': return this.isRange ? 'daterange' : 'date';
case 'month': return this.isRange ? 'monthrange' : 'month';
case 'year': return this.isRange ? 'monthrange' : 'year';
default: return this.isRange ? 'daterange' : 'date';
}
},
/**
* el-date-picker使用的format
*/
innerDateFormat () {
switch (this.dateType) {
case 'day': return 'yyyy-MM-dd';
case 'month': return 'yyyy-MM';
case 'year': return 'yyyy';
default: return 'yyyy-MM-dd';
}
}
},
watch: {
value: {
handler: function (newValue, oldValue) {
if (newValue == null || newValue.length < 2) {
this.currentDates = this.isRange ? [] : undefined;
} else {
if (this.currentDates == null) this.currentDates = [];
if (this.isRange) {
this.currentDates = [
parseDate(newValue[0], this.valueFormat),
parseDate(newValue[1], this.valueFormat)
];
} else {
this.currentDates = parseDate(newValue[0], this.valueFormat);
}
}
},
immediate: true,
deep: true
},
dateType: {
handler: function (newValue, oldValue) {
if (this.allowTypes.indexOf(this.dateType) === -1) {
this.dateType = this.allowTypes[0] || 'day';
}
this.emitChange();
},
immediate: true
},
defaultDateType: {
handler: function (newValue, oldValue) {
if (this.allowTypes.indexOf(newValue) !== -1) {
this.dateType = newValue;
} else {
this.dateType = this.allowTypes[0];
}
}
},
isRange: {
handler: function (newValue, oldValue) {
let temp;
if (newValue) {
temp = [this.currentDates, this.currentDates];
} else {
temp = this.currentDates[0];
}
this.currentDates = temp;
}
}
}
}
</script>
<style scoped>
.date-range {
display: flex;
}
</style>

View File

@@ -0,0 +1,77 @@
import $ from 'jquery';
import Vue from 'vue';
import router from '@/router';
import store from '@/store';
window.jQuery = $;
const layer = require('layui-layer');
class Dialog {
/**
* 关闭弹窗
* @param {*} index 要关闭的弹窗的index
*/
static close (index) {
layer.close(index);
}
/**
* 关闭所有弹窗
*/
static closeAll () {
layer.closeAll();
}
/**
* 打开弹窗
* @param {*} title 弹窗标题
* @param {*} component 弹窗内容的组件
* @param {*} options 弹窗设置详情请见layui官网
* @param {*} params 弹窗组件参数
*/
static show (title, component, options, params) {
return new Promise((resolve, reject) => {
let layerOptions = {
title: title,
type: 1,
skin: 'layer-dialog',
resize: false,
offset: 'auto',
zIndex: 1000,
index: 0,
contentDom: null
};
layerOptions = {...layerOptions, ...options};
layerOptions.end = () => {
if (layerOptions.contentDom) document.body.removeChild(layerOptions.contentDom);
}
let observer = {
cancel: function (isSuccess = false) {
layer.close(this.index);
if (isSuccess) {
resolve();
} else {
reject();
}
},
index: -1
}
layerOptions.cancel = () => {
reject();
}
let dom = document.createElement('div');
document.body.appendChild(dom);
let Content = Vue.extend(component);
let vueObj = new Content({router: router, store: store, propsData: params});
vueObj.observer = observer;
vueObj.$mount(dom);
layerOptions.contentDom = vueObj.$el;
layerOptions.content = $(layerOptions.contentDom);
observer.index = layer.open(layerOptions);
});
}
}
Vue.prototype.$dialog = Dialog;
export default Dialog;

View File

@@ -0,0 +1,134 @@
<template>
<el-row class="flex-box" type="flex" :justify="rowJustify">
<slot />
<div v-for="item in tempDomCount" :key="item" :style="{width: tempDomWidth}" />
<el-row type="flex" :justify="operatorPosition" :style="getMenuBoxStyle">
<slot name="operator" />
</el-row>
</el-row>
</template>
<script>
import $ from 'jquery';
export default {
name: 'FilterBox',
props: {
/**
* 每一个过滤项宽度(包含标题和输入框宽度总和)
*/
itemWidth: {
type: Number,
required: true
},
/**
* 每一项下间距
*/
marginBottom: {
type: String,
default: '18px'
},
/**
* 按钮块最小宽度默认350当每一行剩余空间大于此值按钮块将不会折行
*/
minMenuWidth: {
type: Number,
default: 350
},
/**
* 按钮位置默认为end可选值为start/end/center/space-around/space-between
*/
operatorPosition: {
type: String,
default: 'end'
}
},
data () {
return {
tempDomCount: 0,
tempDomWidth: undefined,
operatorWidth: undefined,
oldFilterItemCount: 0,
oldHasOperator: false,
oldWidth: 0,
rowJustify: 'space-between'
}
},
computed: {
getMenuBoxStyle () {
return {
'width': this.operatorWidth,
'margin-bottom': this.marginBottom,
'flex-grow': this.operatorWidth ? undefined : '1'
}
}
},
methods: {
onUpdate () {
setTimeout(() => {
let filterItemCount = Array.isArray(this.$slots.default) ? this.$slots.default.filter(item => item.context).length : 0;
let hasOperator = Array.isArray(this.$slots.operator) && this.$slots.operator.length > 0;
let width = $(this.$el).width();
if (filterItemCount === this.oldFilterItemCount && hasOperator === this.oldHasOperator && width === this.oldWidth) {
return;
}
let lineCount = this.itemWidth > 0 ? parseInt(width / this.itemWidth) : 1;
lineCount = Math.max(1, lineCount);
let residueCount = filterItemCount % lineCount;
this.tempDomCount = 0;
this.tempDomWidth = undefined;
this.rowJustify = 'space-between';
let tempCount = residueCount === 0 ? 0 : (lineCount - residueCount);
if (hasOperator) {
let residueWidth = width - ((Math.min(lineCount, filterItemCount) - residueCount) * this.itemWidth) - ((tempCount >= 1) ? 20 : 0);
// 判断剩余的空间是否够放下操作按钮
if (residueWidth >= this.minMenuWidth && residueCount === 0) {
this.rowJustify = 'start';
this.operatorWidth = undefined;
} else {
// 剩余空位数大于1需要占位dom
if (tempCount >= 1) {
if (residueWidth >= this.minMenuWidth) {
this.tempDomCount = tempCount - 1;
this.tempDomWidth = this.tempDomCount > 0 ? (20 / this.tempDomCount) + 'px' : undefined;
this.operatorWidth = this.tempDomCount > 0 ? (((tempCount * this.itemWidth) - 20) + 'px') : (this.itemWidth + 'px');
} else {
this.tempDomCount = tempCount;
this.tempDomWidth = (residueWidth / this.tempDomCount) + 'px';
this.operatorWidth = '100%';
}
} else {
this.operatorWidth = '100%';
}
}
} else {
this.tempDomCount = tempCount;
this.tempDomWidth = this.itemWidth + 'px';
}
this.oldFilterItemCount = filterItemCount;
this.oldHasOperator = hasOperator;
this.oldWidth = width;
});
}
},
beforeUpdate () {
this.onUpdate();
},
mounted () {
setTimeout(() => {
this.onUpdate();
});
},
created () {
window.addEventListener('resize', this.onUpdate);
},
beforeDestroy () {
window.removeEventListener('resize', this.onUpdate);
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,44 @@
<template>
<div>
<svg t="1492500959545" @click="toggleClick" class="hamburger" :class="{'is-active':isActive}" style="" viewBox="0 0 1024 1024"
version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1691" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64">
<path d="M966.8023 568.849776 57.196677 568.849776c-31.397081 0-56.850799-25.452695-56.850799-56.850799l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 543.397081 998.200404 568.849776 966.8023 568.849776z"
p-id="1692"></path>
<path d="M966.8023 881.527125 57.196677 881.527125c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 856.07443 998.200404 881.527125 966.8023 881.527125z"
p-id="1693"></path>
<path d="M966.8023 256.17345 57.196677 256.17345c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.850799 56.850799-56.850799l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.850799l0 0C1023.653099 230.720755 998.200404 256.17345 966.8023 256.17345z"
p-id="1694"></path>
</svg>
</div>
</template>
<script>
export default {
name: 'hamburger',
props: {
isActive: {
type: Boolean,
default: false
},
toggleClick: {
type: Function,
default: null
}
}
}
</script>
<style scoped>
.hamburger {
display: inline-block;
cursor: pointer;
width: 20px;
height: 20px;
transform: rotate(90deg);
transform-origin: 50% 50%;
}
.hamburger.is-active {
transform: rotate(0deg);
}
</style>

View File

@@ -0,0 +1,280 @@
[
"el-icon-delete-solid",
"el-icon-delete",
"el-icon-s-tools",
"el-icon-setting",
"el-icon-user-solid",
"el-icon-user",
"el-icon-phone",
"el-icon-phone-outline",
"el-icon-more",
"el-icon-more-outline",
"el-icon-star-on",
"el-icon-star-off",
"el-icon-s-goods",
"el-icon-goods",
"el-icon-warning",
"el-icon-warning-outline",
"el-icon-question",
"el-icon-info",
"el-icon-remove",
"el-icon-circle-plus",
"el-icon-success",
"el-icon-error",
"el-icon-zoom-in",
"el-icon-zoom-out",
"el-icon-remove-outline",
"el-icon-circle-plus-outline",
"el-icon-circle-check",
"el-icon-circle-close",
"el-icon-s-help",
"el-icon-help",
"el-icon-minus",
"el-icon-plus",
"el-icon-check",
"el-icon-close",
"el-icon-picture",
"el-icon-picture-outline",
"el-icon-picture-outline-round",
"el-icon-upload",
"el-icon-upload2",
"el-icon-download",
"el-icon-camera-solid",
"el-icon-camera",
"el-icon-video-camera-solid",
"el-icon-video-camera",
"el-icon-message-solid",
"el-icon-bell",
"el-icon-s-cooperation",
"el-icon-s-order",
"el-icon-s-platform",
"el-icon-s-fold",
"el-icon-s-unfold",
"el-icon-s-operation",
"el-icon-s-promotion",
"el-icon-s-home",
"el-icon-s-release",
"el-icon-s-ticket",
"el-icon-s-management",
"el-icon-s-open",
"el-icon-s-shop",
"el-icon-s-marketing",
"el-icon-s-flag",
"el-icon-s-comment",
"el-icon-s-finance",
"el-icon-s-claim",
"el-icon-s-custom",
"el-icon-s-opportunity",
"el-icon-s-data",
"el-icon-s-check",
"el-icon-s-grid",
"el-icon-menu",
"el-icon-share",
"el-icon-d-caret",
"el-icon-caret-left",
"el-icon-caret-right",
"el-icon-caret-bottom",
"el-icon-caret-top",
"el-icon-bottom-left",
"el-icon-bottom-right",
"el-icon-back",
"el-icon-right",
"el-icon-bottom",
"el-icon-top",
"el-icon-top-left",
"el-icon-top-right",
"el-icon-arrow-left",
"el-icon-arrow-right",
"el-icon-arrow-down",
"el-icon-arrow-up",
"el-icon-d-arrow-left",
"el-icon-d-arrow-right",
"el-icon-video-pause",
"el-icon-video-play",
"el-icon-refresh",
"el-icon-refresh-right",
"el-icon-refresh-left",
"el-icon-finished",
"el-icon-sort",
"el-icon-sort-up",
"el-icon-sort-down",
"el-icon-rank",
"el-icon-loading",
"el-icon-view",
"el-icon-c-scale-to-original",
"el-icon-date",
"el-icon-edit",
"el-icon-edit-outline",
"el-icon-folder",
"el-icon-folder-opened",
"el-icon-folder-add",
"el-icon-folder-remove",
"el-icon-folder-delete",
"el-icon-folder-checked",
"el-icon-tickets",
"el-icon-document-remove",
"el-icon-document-delete",
"el-icon-document-copy",
"el-icon-document-checked",
"el-icon-document",
"el-icon-document-add",
"el-icon-printer",
"el-icon-paperclip",
"el-icon-takeaway-box",
"el-icon-search",
"el-icon-monitor",
"el-icon-attract",
"el-icon-mobile",
"el-icon-scissors",
"el-icon-umbrella",
"el-icon-headset",
"el-icon-brush",
"el-icon-mouse",
"el-icon-coordinate",
"el-icon-magic-stick",
"el-icon-reading",
"el-icon-data-line",
"el-icon-data-board",
"el-icon-pie-chart",
"el-icon-data-analysis",
"el-icon-collection-tag",
"el-icon-film",
"el-icon-suitcase",
"el-icon-suitcase-1",
"el-icon-receiving",
"el-icon-collection",
"el-icon-files",
"el-icon-notebook-1",
"el-icon-notebook-2",
"el-icon-toilet-paper",
"el-icon-office-building",
"el-icon-school",
"el-icon-table-lamp",
"el-icon-house",
"el-icon-no-smoking",
"el-icon-smoking",
"el-icon-shopping-cart-full",
"el-icon-shopping-cart-1",
"el-icon-shopping-cart-2",
"el-icon-shopping-bag-1",
"el-icon-shopping-bag-2",
"el-icon-sold-out",
"el-icon-sell",
"el-icon-present",
"el-icon-box",
"el-icon-bank-card",
"el-icon-money",
"el-icon-coin",
"el-icon-wallet",
"el-icon-discount",
"el-icon-price-tag",
"el-icon-news",
"el-icon-guide",
"el-icon-male",
"el-icon-female",
"el-icon-thumb",
"el-icon-cpu",
"el-icon-link",
"el-icon-connection",
"el-icon-open",
"el-icon-turn-off",
"el-icon-set-up",
"el-icon-chat-round",
"el-icon-chat-line-round",
"el-icon-chat-square",
"el-icon-chat-dot-round",
"el-icon-chat-dot-square",
"el-icon-chat-line-square",
"el-icon-message",
"el-icon-postcard",
"el-icon-position",
"el-icon-turn-off-microphone",
"el-icon-microphone",
"el-icon-close-notification",
"el-icon-bangzhu",
"el-icon-time",
"el-icon-odometer",
"el-icon-crop",
"el-icon-aim",
"el-icon-switch-button",
"el-icon-full-screen",
"el-icon-copy-document",
"el-icon-mic",
"el-icon-stopwatch",
"el-icon-medal-1",
"el-icon-medal",
"el-icon-trophy",
"el-icon-trophy-1",
"el-icon-first-aid-kit",
"el-icon-discover",
"el-icon-place",
"el-icon-location",
"el-icon-location-outline",
"el-icon-location-information",
"el-icon-add-location",
"el-icon-delete-location",
"el-icon-map-location",
"el-icon-alarm-clock",
"el-icon-timer",
"el-icon-watch-1",
"el-icon-watch",
"el-icon-lock",
"el-icon-unlock",
"el-icon-key",
"el-icon-service",
"el-icon-mobile-phone",
"el-icon-bicycle",
"el-icon-truck",
"el-icon-ship",
"el-icon-basketball",
"el-icon-football",
"el-icon-soccer",
"el-icon-baseball",
"el-icon-wind-power",
"el-icon-light-rain",
"el-icon-lightning",
"el-icon-heavy-rain",
"el-icon-sunrise",
"el-icon-sunrise-1",
"el-icon-sunset",
"el-icon-sunny",
"el-icon-cloudy",
"el-icon-partly-cloudy",
"el-icon-cloudy-and-sunny",
"el-icon-moon",
"el-icon-moon-night",
"el-icon-dish",
"el-icon-dish-1",
"el-icon-food",
"el-icon-chicken",
"el-icon-fork-spoon",
"el-icon-knife-fork",
"el-icon-burger",
"el-icon-tableware",
"el-icon-sugar",
"el-icon-dessert",
"el-icon-ice-cream",
"el-icon-hot-water",
"el-icon-water-cup",
"el-icon-coffee-cup",
"el-icon-cold-drink",
"el-icon-goblet",
"el-icon-goblet-full",
"el-icon-goblet-square",
"el-icon-goblet-square-full",
"el-icon-refrigerator",
"el-icon-grape",
"el-icon-watermelon",
"el-icon-cherry",
"el-icon-apple",
"el-icon-pear",
"el-icon-orange",
"el-icon-coffee",
"el-icon-ice-tea",
"el-icon-ice-drink",
"el-icon-milk-tea",
"el-icon-potato-strips",
"el-icon-lollipop",
"el-icon-ice-cream-square",
"el-icon-ice-cream-round"
]

View File

@@ -0,0 +1,104 @@
<template>
<el-popover width="510" v-model="showDropdown" @show="onDropdownShow">
<div class="icon-select-dropdown">
<el-row type="flex" style="flex-wrap: wrap">
<el-col :span="3" v-for="icon in getIconList" :key="icon" class="icon-item"
:class="{active: (value === icon)}" @click.native="onIconClick(icon)">
<i :class="icon" />
</el-col>
</el-row>
<el-row type="flex" justify="space-between">
<el-button type="text" @click="onClearClick" style="margin-left: 10px;">清空</el-button>
<el-pagination
:current-page.sync="currentPage"
:page-size="pageSize"
layout="prev, pager, next"
:total="getIconCount">
</el-pagination>
</el-row>
</div>
<div slot="reference" class="icon-select"
:style="{width: height + 'px', height: height + 'px', 'line-height': height + 'px', 'font-size': height * 0.5 + 'px'}">
<i :class="value" />
</div>
</el-popover>
</template>
<script>
import iconList from './icon.json';
export default {
props: {
/**
* 绑定字段
*/
value: String,
/**
* 组件高度单位px
*/
height: {
type: Number,
default: 45
}
},
data () {
return {
showDropdown: false,
currentPage: 1,
pageSize: 32
}
},
methods: {
onIconClick (icon) {
this.$emit('input', icon);
this.showDropdown = false;
},
onClearClick () {
this.$emit('input');
this.showDropdown = false;
},
onDropdownShow () {
this.currentPage = 1
let pos = iconList.indexOf(this.value);
if (pos >= 0) {
this.currentPage += Math.floor(pos / this.pageSize);
}
}
},
computed: {
getIconCount () {
return iconList.length;
},
getIconList () {
let beginPos = (this.currentPage - 1) * this.pageSize;
let endPos = beginPos + this.pageSize;
return iconList.slice(beginPos, endPos);
}
}
}
</script>
<style scoped>
.icon-select {
text-align: center;
color: #5F6266;
border: 1px solid #DCDFE6;
border-radius: 4px;
cursor: pointer;
}
.icon-item {
width: 40px;
height: 40px;
line-height: 40px;
text-align: center;
font-size: 20px;
color: #5F6266;
border-radius: 3px;
border: 1px solid #DCDFE6;
margin: 10px;
cursor: pointer;
}
.active {
color: #EF5E1C;
}
</style>

View File

@@ -0,0 +1,226 @@
<template>
<div class="el-input el-date-editor el-range-editor el-input__inner el-input-number-range"
:class="
[
inputSize ? 'el-range-editor--' + inputSize : '',
focused ? 'is-active' : '',
{
'is-disabled': inputDisabled,
'el-input--prefix': prefixIcon
}
]"
@mouseenter="showClose = true"
@mouseleave="showClose = false">
<div class="el-input__icon el-range__icon" :class="prefixIcon">
<slot name="prepend"></slot>
</div>
<input
autocomplete="off"
:placeholder="startPlaceholder"
:value="userInput && userInput[0]"
:disabled="inputDisabled"
:readonly="readonly"
:name="name && name[0]"
@input="handleStartInput"
@change="handleStartChange"
@focus="focused = true"
@blur="focused = false"
class="el-range-input">
<slot name="range-separator">
<span class="el-range-separator">{{ rangeSeparator }}</span>
</slot>
<input
autocomplete="off"
:placeholder="endPlaceholder"
:value="userInput && userInput[1]"
:disabled="inputDisabled"
:readonly="readonly"
:name="name && name[1]"
@input="handleEndInput"
@change="handleEndChange"
@focus="focused = true"
@blur="focused = false"
class="el-range-input">
<i class="el-input__icon el-range__close-icon"
:class="[showClear ? 'el-icon-circle-close' : '']"
@click="handleClickClear">
</i>
</div>
</template>
<script>
import emitter from 'element-ui/src/mixins/emitter';
function isNumber (val) {
var regPos = /^\d+(\.\d+)?$/; // 非负浮点数
var regNeg = /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/; // 负浮点数
if (regPos.test(val) || regNeg.test(val)) {
return true;
} else {
return false;
}
}
export default {
name: 'InputNumberRange',
componentName: 'InputNumberRange',
mixins: [emitter],
props: {
/**
* 绑定字段
*/
value: {
type: Array,
default: function () {
return [];
}
},
/**
* 组件大小medium / small / mini
*/
size: String,
/**
* 禁用
*/
disabled: Boolean,
/**
* 完全只读
*/
readonly: Boolean,
/**
* 是否显示清除按钮
*/
clearable: {
type: Boolean,
default: false
},
/**
* 自定义头部图标的类名
*/
prefixIcon: String,
/**
* 范围选择时最小值的占位内容
*/
startPlaceholder: String,
/**
* 范围选择时最大值的占位内容
*/
endPlaceholder: String,
/**
* 原生属性
*/
name: {
default: ''
},
/**
* 选择范围时的分隔符
*/
rangeSeparator: {
type: String,
default: '-'
},
validateEvent: {
type: Boolean,
default: true
}
},
data () {
return {
hovering: false,
focused: false,
userInput: this.value,
showClose: false
};
},
inject: {
elForm: {
default: ''
},
elFormItem: {
default: ''
}
},
computed: {
_elFormItemSize () {
return (this.elFormItem || {}).elFormItemSize;
},
inputSize () {
let temp = this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
return temp;
},
inputDisabled () {
return this.disabled || (this.elForm || {}).disabled;
},
showClear () {
let temp = this.clearable && !this.inputDisabled && !this.readonly && this.showClose &&
this.userInput != null && Array.isArray(this.userInput) && this.userInput.length > 0 &&
(this.userInput[0] != null || this.userInput[1] != null);
return temp;
}
},
methods: {
handleStartInput (event) {
if (this.userInput) {
this.userInput = [event.target.value, this.userInput[1]];
} else {
this.userInput = [event.target.value, null];
}
},
handleEndInput (event) {
if (this.userInput) {
this.userInput = [this.userInput[0], event.target.value];
} else {
this.userInput = [null, event.target.value];
}
},
handleStartChange (event) {
let value = this.userInput && this.userInput[0];
value = isNumber(value) ? value : null;
value = value ? Number.parseFloat(value) : null;
if (this.userInput) {
this.userInput[0] = value;
} else {
this.userInput = [value, null];
}
event.srcElement.value = value;
this.emitInput(this.userInput);
},
handleEndChange (event) {
let value = this.userInput && this.userInput[1];
value = isNumber(value) ? value : null;
value = value ? Number.parseFloat(value) : null;
if (this.userInput) {
this.userInput[1] = value;
} else {
this.userInput = [null, value];
}
event.srcElement.value = value;
this.emitInput(this.userInput);
},
handleClickClear () {
this.userInput = undefined;
this.emitInput(this.userInput);
},
valueEquals (val, oldVal) {
return JSON.stringify(val) === JSON.stringify(oldVal);
},
emitInput (values) {
this.$emit('input', values);
this.$emit('change', values);
}
},
watch: {
value: {
handler: function (val, oldVal) {
if (!this.valueEquals(val, oldVal) && this.validateEvent) {
this.dispatch('ElFormItem', 'el.form.change', val);
}
},
deep: true
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,44 @@
<template>
<el-progress v-bind="$attrs" :percentage="getPercentage" />
</template>
<script>
export default {
name: 'Progress',
props: {
/**
* 组件最小值
*/
min: {
type: Number,
default: 0
},
/**
* 组件最大值
*/
max: {
type: Number,
default: 100
},
/**
* 组件当前值
*/
value: {
type: Number,
default: 0
}
},
computed: {
getPercentage () {
let value = Math.min(this.max, Math.max(this.min, this.value));
value = value - this.min;
if ((this.max - this.min) === 0) {
value = 0;
} else {
value = ((value * 100) / (this.max - this.min));
}
return Number.isInteger(value) ? value : parseInt(value);
}
}
}
</script>

View File

@@ -0,0 +1,129 @@
<template>
<div class="uditor-class" ref="editor"></div>
</template>
<script>
import WEditor from 'wangeditor';
const defaultConfigs = {
uploadImgServer: undefined,
uploadFileName: 'imageFile',
uploadImgMaxSize: 1 * 1024 * 1024,
uploadImgShowBase64: true,
uploadImgMaxLength: 5,
uploadImgParams: undefined,
uploadImgParamsWithUrl: true,
withCredentials: true,
uploadImgTimeout: 5000,
uploadImgHeaders: undefined,
uploadImgHooks: undefined,
zIndex: 0,
lang: undefined,
pasteFilterStyle: true,
pasteIgnoreImg: false,
onchangeTimeout: 10,
menus: [
// 标题
'head',
// 粗体
'bold',
// 字号
'fontSize',
// 字体
'fontName',
// 斜体
'italic',
// 下划线
'underline',
// 删除线
'strikeThrough',
// 文字颜色
'foreColor',
// 背景颜色
'backColor',
// 插入链接
'link',
// 列表
'list',
// 对齐方式
'justify',
// 引用
'quote',
// 插入图片
'image',
// 撤销
'undo',
// 重复
'redo'
]
}
export default {
props: {
/**
* 绑定字段
*/
value: {
type: String
},
/**
* 配置项详情请参考wangEditor文档
*/
config: {
type: Object,
default: () => {
return defaultConfigs;
}
}
},
data () {
return {
editor: null
}
},
computed: {
getConfigs () {
return {...this.config, ...defaultConfigs};
}
},
mounted () {
this.editor = new WEditor(this.$refs.editor);
this.editor.customConfig = {...this.getConfigs};
this.editor.customConfig.pasteTextHandle = (content) => {
// content 即粘贴过来的内容html 或 纯文本),可进行自定义处理然后返回
return content;
}
this.editor.customConfig.linkImgCallback = (url) => {
console.log(url) // url 即插入图片的地址
}
this.editor.customConfig.linkCheck = (text, link) => {
return true // 返回 true 表示校验成功
// return '验证失败' // 返回字符串,即校验失败的提示信息
}
this.editor.customConfig.linkImgCheck = (src) => {
return true // 返回 true 表示校验成功
// return '验证失败' // 返回字符串,即校验失败的提示信息
}
// 失去焦点后更新数据
this.editor.customConfig.onblur = (html) => {
console.log(html)
this.$emit('input', html);
}
this.editor.create();
this.editor.txt.html(this.value);
},
watch: {
value: {
handler (newValue) {
if (this.editor) this.editor.txt.html(this.value);
},
immediate: true
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,119 @@
<template>
<el-table-column v-bind="$attrs">
<template slot-scope="scope">
<orange-progress :stroke-width="strokeWidth" :type="type" :text-inside="textInside" :status="status" :color="color"
:width="width" :show-text="showText" :min="getMinValue(scope.row)" :max="getMaxValue(scope.row)"
:value="getValue(scope.row)" />
</template>
</el-table-column>
</template>
<script>
import Progress from '@/components/Progress/index.vue';
export default {
name: 'TableProgressColumn',
components: {
'orange-progress': Progress
},
props: {
/**
* 固定值最小值
*/
min: {
type: Number,
default: 0
},
/**
* 固定值最大值
*/
max: {
type: Number,
default: 100
},
/**
* 固定值当前值
*/
value: {
type: Number,
default: 0
},
/**
* 表格最小值字段名
*/
minColumn: {
type: String
},
/**
* 表格最大值字段名
*/
maxColumn: {
type: String
},
/**
* 表格当前值字段名
*/
valueColumn: {
type: String
},
/**
* 进度条的宽度,单位 px
*/
strokeWidth: {
type: Number,
default: 16
},
/**
* 进度条类型line/circle/dashboard
*/
type: {
type: String,
default: 'line'
},
/**
* 进度条显示文字内置在进度条内(只在 type=line 时可用)
*/
textInside: {
type: Boolean,
default: true
},
/**
* 进度条当前状态(success/exception/warning)
*/
status: {
type: String
},
/**
* 进度条背景色(会覆盖 status 状态颜色)
*/
color: {
type: [String, Function, Array]
},
/**
* 环形进度条画布宽度(只在 type 为 circle 或 dashboard 时可用)
*/
width: {
type: Number,
default: 126
},
/**
* 是否显示进度条文字内容
*/
showText: {
type: Boolean,
default: true
}
},
methods: {
getValue (row) {
return this.valueColumn ? row[this.valueColumn] : this.value;
},
getMinValue (row) {
return this.minColumn ? row[this.minColumn] : this.min;
},
getMaxValue (row) {
return this.maxColumn ? row[this.maxColumn] : this.max;
}
}
}
</script>

View File

@@ -0,0 +1,300 @@
<template>
<el-popover ref="popover" placement="bottom-start" trigger="click" popper-class="tree-select-popover"
:width="width" @show="onShowPopover">
<el-scrollbar :style="{'height': this.height, 'min-width': this.width}" ref="scrollbar">
<el-tree ref="dropdownTree" :props="getTreeProps" :highlightCurrent="highlightCurrent" :nodeKey="getDataProps.value"
:defaultExpandAll="defaultExpandAll" :expandOnClickNode="expandOnClickNode" :checkOnClickNode="checkOnClickNode"
:autoExpandParent="autoExpandParent" :defaultExpandedKeys="defaultExpandedKeys" :showCheckbox="showCheckbox"
:checkStrictly="checkStrictly" :defaultCheckedKeys="defaultCheckedKeys" :currentNodeKey="getCurrentNodeKey"
:accordion="accordion" :indent="indent" :iconClass="iconClass" :load="loadChildrenNodes" lazy :show-checkbox="multiple"
@node-click="onTreeNodeClick" @check="onTreeNodeCheck">
<span :style="getNodeStyle(data)" slot-scope="{ node, data }">{{data[getDataProps.label]}}</span>
</el-tree>
</el-scrollbar>
<el-select slot="reference" v-model="selectKeys" :multiple="multiple" :disabled="false" :size="size"
:clearable="clearable" :collapseTags="collapseTags" :placeholder="placeholder" popper-class="select-tree-popper"
@clear="onClear" @remove-tag="onClear">
<el-option v-for="item in selectNodes" :key="item[getDataProps.value]"
:value="item[getDataProps.value]" :label="item[getDataProps.label]" />
</el-select>
</el-popover>
</template>
<script>
import { findTreeNode } from '@/utils';
export default {
name: 'TreeSelect',
props: {
value: {
type: [String, Number]
},
multiple: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
size: {
type: String
},
height: {
type: String,
default: '200px'
},
width: {
type: String,
default: '300px'
},
activeColor: {
type: String,
default: '#EF5E1C'
},
clearable: {
type: Boolean,
default: false
},
collapseTags: {
type: Boolean,
default: true
},
placeholder: {
type: String
},
loading: {
type: Boolean,
default: false
},
loadingText: {
type: String,
default: '加载中'
},
// 树属性
data: {
type: Array
},
props: {
type: Object,
default: () => {
return {
label: 'label',
value: 'value',
parentKey: 'parentId',
children: 'children',
disabled: 'disabled'
}
}
},
defaultExpandAll: {
type: Boolean,
default: false
},
expandOnClickNode: {
type: Boolean,
default: true
},
checkOnClickNode: {
type: Boolean,
default: false
},
autoExpandParent: {
type: Boolean,
default: true
},
defaultExpandedKeys: {
type: Array
},
checkStrictly: {
type: Boolean,
default: true
},
currentNodeKey: {
type: [String, Number]
},
accordion: {
type: Boolean,
default: false
},
indent: {
type: Number,
default: 16
},
iconClass: {
type: String
}
},
data () {
return {
rootNode: undefined,
rootResolve: undefined,
allTreeNode: [],
selectNodes: [],
scrollTop: 0,
selectKeys: undefined
}
},
methods: {
onShowPopover () {
setTimeout(() => {
this.$refs.scrollbar.wrap.scrollTop = this.scrollTop;
// this.$refs.scrollbar.update();
}, 20);
if (!this.multiple) {
this.$refs.dropdownTree.setCurrentKey(this.value);
}
},
onClear () {
this.$nextTick(() => {
this.$emit('input', this.selectKeys);
});
},
onTreeNodeClick (data, node) {
this.$refs.popover.showPopper = false;
if (!this.multiple) {
this.scrollTop = this.$refs.scrollbar.wrap.scrollTop;
this.$emit('input', data[this.getDataProps.value]);
this.$emit('change', data[this.getDataProps.value]);
}
},
onTreeNodeCheck (data, {checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys}) {
this.scrollTop = this.$refs.scrollbar.wrap.scrollTop
this.$emit('input', checkedKeys);
this.$emit('change', checkedKeys);
},
parseNode (node) {
if (Array.isArray(node) && node.length > 0) {
node.forEach((item) => {
item['__node_is_leaf__'] = !(Array.isArray(item[this.getDataProps.children]) && item[this.getDataProps.children].length > 0);
});
return node;
} else {
return [];
}
},
loadChildrenNodes (node, resolve) {
if (node.level === 0) {
this.rootNode = node;
this.rootResolve = resolve;
return resolve(this.parseNode(this.allTreeNode));
} else {
return resolve(this.parseNode(node.data[this.getDataProps.children]));
}
},
getNodeStyle (data) {
if (!this.multiple && (this.selectNodes[0] || {})[this.getDataProps.value] === data[this.getDataProps.value]) {
return {
color: this.activeColor,
'font-weight': 700
}
}
}
},
computed: {
showCheckbox () {
return this.multiple;
},
getCurrentNodeKey () {
if (!this.multiple && Array.isArray(this.selectNodes) && this.selectNodes.length > 0) {
return this.selectNodes[0][this.getDataProps.value];
} else {
return null;
}
},
highlightCurrent () {
return this.multiple;
},
defaultCheckedKeys () {
return this.multiple ? this.selectNodes : undefined
},
getDataProps () {
return {
label: this.props.label || 'label',
value: this.props.value || 'value',
parentKey: this.props.parentKey || 'parentId',
children: this.props.children || 'children',
disabled: this.props.disabled || 'disabled'
}
},
getTreeProps () {
return {
label: this.getDataProps.label,
children: '__children_list__',
disabled: this.getDataProps.disabled,
isLeaf: '__node_is_leaf__'
};
}
},
watch: {
data: {
handler (newValue, oldValue) {
this.allTreeNode = newValue;
if (this.rootNode != null && this.rootResolve != null) {
this.rootNode.childNodes = [];
this.loadChildrenNodes(this.rootNode, this.rootResolve);
}
this.selectNodes = [];
if (this.multiple) {
if (Array.isArray(this.value)) {
this.value.forEach((item) => {
let data = findTreeNode(this.allTreeNode, item, this.getDataProps.value, this.getDataProps.children);
if (data) this.selectNodes.push(data);
});
}
} else {
let data = findTreeNode(this.allTreeNode, this.value, this.getDataProps.value, this.getDataProps.children);
if (data) this.selectNodes.push(data);
}
},
immediate: true
},
value: {
handler (newValue) {
this.selectNodes = [];
if (Array.isArray(newValue)) {
newValue.forEach((item) => {
let data = findTreeNode(this.allTreeNode, item, this.getDataProps.value, this.getDataProps.children);
if (data) this.selectNodes.push(data);
});
this.selectKeys = newValue;
} else {
let data = findTreeNode(this.allTreeNode, newValue, this.getDataProps.value, this.getDataProps.children);
if (data) this.selectNodes.push(data);
this.selectKeys = newValue;
}
if (this.$refs.dropdownTree) {
this.multiple ? this.$refs.dropdownTree.setCheckedKeys(newValue) : this.$refs.dropdownTree.setCurrentKey(newValue);
}
},
immediate: true
}
}
}
</script>
<style>
.select-tree-popper {
display: none;
}
.tree-select-popover {
padding: 6px 0px;
}
.tree-select-popover .popper__arrow {
left: 35px!important;
}
.tree-select-popover .el-tree .el-tree-node__content {
height: 34px;
line-height: 34px;
}
/*
.tree-select-popover .el-tree .el-tree-node.is-current .el-tree-node__content {
color: #fdb95c;
font-weight: 700;
}
*/
.current-node {
color: #EF5E1C;
font-weight: 700;
}
</style>

View File

@@ -0,0 +1,4 @@
module.exports = {
baseUrl: 'http://localhost:8082/',
projectName: '橙单生成器项目'
}

View File

@@ -0,0 +1,12 @@
const projectConfig = require('../config/' + process.env.NODE_ENV);
export const globalConfig = {
httpOption: {
showMask: true,
showError: true
},
axiosOption: {
}
};
export default projectConfig;

View File

@@ -0,0 +1,4 @@
module.exports = {
baseUrl: 'http://localhost:8082/',
projectName: '橙单生成器项目'
}

View File

@@ -0,0 +1,14 @@
import Vue from 'vue'
import { SortableData } from './sortableData';
/**
* 拖拽排序指令
*/
Vue.directive('sortable', {
inserted: function (el, binding, vnode) {
let sortableData = binding.value;
if (sortableData == null || !(sortableData instanceof SortableData)) return;
sortableData.init(vnode.elm);
}
});

View File

@@ -0,0 +1,60 @@
import sortable from 'sortablejs'
/**
* 拖拽排序对象
* expample
* <ul v-sortable="new SortableData(data)">
* <li>A</li>
* <li>B</li>
* <li>C</li>
* <li>D</li>
* </ul>
*/
export class SortableData {
constructor (data, group) {
this.list = data;
this.group = group;
this.ghostClass = 'sortable-ghost';
this.sortable = null;
this.disabled = false;
};
setData (list) {
this.list = list;
}
getElement (el) {
return el;
};
onEnd (oldIndex, newIndex) {
if (oldIndex === newIndex || this.list == null) return;
let targetRow = this.list.splice(oldIndex, 1)[0]
this.list.splice(newIndex, 0, targetRow);
};
init (el) {
var _this = this;
var _option = {};
if (this.ghostClass != null) _option.ghostClass = this.ghostClass;
if (this.group != null) _option.group = this.group;
if (this.disabled != null) _option.disabled = this.disabled;
// 列表中能拖动的dom的选择器例如.drag-item
if (this.draggable != null) _option.draggable = this.draggable;
// 列表中拖动项拖动把柄的选择器只有点击这个选择出来的dom才可以开始拖动例如.drag-handle
if (this.handle != null) _option.handle = this.handle;
_option.setData = function (dataTransfer) {
dataTransfer.setData('Text', '');
};
_option.onEnd = function (evt) {
_this.onEnd(evt.oldIndex, evt.newIndex);
};
this.sortable = sortable.create(_this.getElement(el), _option);
};
release () {
if (this.sortable != null) this.sortable.destroy();
this.sortable = null;
}
};

View File

@@ -0,0 +1,185 @@
import Vue from 'vue';
import { Loading, Message } from 'element-ui';
import request from './request';
import requestUrl from './requestUrl';
import merge from 'lodash/merge';
import { globalConfig } from '@/core/config';
/**
* 遮罩管理,多次调用支持引用计数
*/
class LoadingManager {
constructor (options) {
this.options = options;
this.refCount = 0;
this.loading = undefined;
}
showMask () {
this.loading = Loading.service(this.options);
this.refCount++;
}
hideMask () {
if (this.refCount <= 1 && this.loading != null) {
this.loading.close();
this.loading = null;
}
this.refCount--;
this.refCount = Math.max(0, this.refCount);
}
}
const loadingManager = new LoadingManager({
fullscreen: true,
background: 'rgba(0, 0, 0, 0.1)'
});
/**
* post请求
* @param {String} url 请求的url
* @param {Object} params 请求参数
* @param {Object} options axios设置项
* @returns {Promise}
*/
const fetchPost = function (url, params, options) {
if (options == null) return {};
let tempOptions = {
...options,
method: 'post',
url: requestUrl(url),
data: params
};
return request(tempOptions);
};
/**
* get请求
* @param {String} url 请求的url
* @param {Object} params 请求参数
* @param {Object} options axios设置项
* @returns {Promise}
*/
const fetchGet = function (url, params, options) {
if (options == null) return {};
let tempOptions = {
...options,
method: 'get',
url: requestUrl(url),
params
};
return request(tempOptions);
};
/**
* 下载请求
* @param {String} url 请求的url
* @param {Object} params 请求参数
* @param {String} fileName 下载后保存的文件名
* @returns {Promise}
*/
const fetchDownload = function (url, params, fileName) {
return new Promise((resolve, reject) => {
request({
url: requestUrl(url),
method: 'post',
data: params,
responseType: 'blob',
transformResponse: function (data) {
return (data instanceof Blob && data.size > 0) ? data : undefined;
}
}).then(res => {
if (res.data == null) {
reject(new Error('下载文件失败'));
} else {
let blobData = new Blob([res.data], { type: 'application/octet-stream' });
let blobUrl = window.URL.createObjectURL(blobData);
let linkDom = document.createElement('a');
linkDom.style.display = 'none';
linkDom.href = blobUrl;
linkDom.setAttribute('download', fileName);
if (typeof linkDom.download === 'undefined') {
linkDom.setAttribute('target', '_blank');
}
document.body.appendChild(linkDom);
linkDom.click();
document.body.removeChild(linkDom);
window.URL.revokeObjectURL(blobData);
resolve();
}
}).catch(e => {
if (e instanceof Blob) {
let reader = new FileReader();
reader.onload = function () {
let jsonObj = JSON.parse(reader.result);
reject((jsonObj || {}).errorMessage || '下载文件失败');
}
reader.readAsText(e);
} else {
reject(e);
}
});
});
}
/**
* 数据请求
* @param {String} url 请求的url
* @param {String} type 请求类型getpost
* @param {Object} params 请求参数
* @param {Object} axiosOption axios设置
* @param {Object} options 显示设置
*/
const doUrl = function (url, type, params, axiosOption, options) {
options = merge(globalConfig.httpOption, options);
axiosOption = merge(globalConfig.axiosOption, axiosOption);
if (type == null || type === '') type = 'post';
return new Promise((resolve, reject) => {
if (options.showMask) loadingManager.showMask();
let ajaxCall = null;
if (type.toLowerCase() === 'get') {
ajaxCall = fetchGet(url, params, axiosOption);
} else if (type.toLowerCase() === 'post') {
ajaxCall = fetchPost(url, params, axiosOption);
}
if (ajaxCall != null) {
ajaxCall.then(res => {
if (options.showMask) loadingManager.hideMask();
if (res.data && res.data.success) {
resolve(res.data);
} else {
if (options.showError) {
Message.error({
showClose: true,
message: res.data.errorMessage ? res.data.errorMessage : '数据请求失败'
});
}
reject(res.data);
}
}).catch(e => {
if (options.showMask) loadingManager.hideMask();
if (options.showError) {
Message.error({
showClose: true,
message: e.errorMessage ? e.errorMessage : '网络请求错误'
});
}
reject(e);
});
} else {
if (options.showMask) loadingManager.hideMask();
reject(new Error('错误的请求类型 - ' + type));
}
});
};
Vue.prototype.download = fetchDownload;
Vue.prototype.doUrl = doUrl;
Vue.prototype.loadingManager = loadingManager;
export default {
doUrl,
fetchPost,
fetchGet,
fetchDownload
}

View File

@@ -0,0 +1,73 @@
import axios from 'axios';
import router from '@/router';
import dialog from '@/components/Dialog';
import JSONbig from 'json-bigint';
// 创建axios实例
const service = axios.create({
timeout: 1000 * 30,
withCredentials: true,
headers: {
// 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
'Content-Type': 'application/json; charset=utf-8'
},
transformResponse: [
function (data) {
if (typeof data === 'string') {
const JSONbigString = new JSONbig({storeAsString: true});
return JSONbigString.parse(data);
} else {
return data;
}
}
]
})
// request拦截器
service.interceptors.request.use(
config => {
let token = window.sessionStorage.getItem('token');
let menuIdJsonStr = window.sessionStorage.getItem('currentMenuId');
let currentMenuId;
if (menuIdJsonStr != null) {
currentMenuId = (JSON.parse(menuIdJsonStr) || {}).data;
}
if (token != null) config.headers['Authorization'] = token;
if (currentMenuId != null) config.headers['MenuId'] = currentMenuId;
return config
}, error => {
return Promise.reject(error)
}
);
// response拦截器
service.interceptors.response.use(
response => {
if (response.data && response.data.errorCode === 'UNAUTHORIZED_LOGIN') { // 401, token失效
dialog.closeAll();
router.push({ name: 'login' })
} else {
if (response.headers['refreshedtoken'] != null) {
window.sessionStorage.setItem('token', response.headers['refreshedtoken']);
}
}
return response
}, error => {
let response = error.response;
if (response && response.data) {
if (response.data.errorCode === 'UNAUTHORIZED_LOGIN') {
dialog.closeAll();
router.push({ name: 'login' });
}
return Promise.reject(response.data);
} else {
return Promise.reject(new Error({
errorMessage: '数据获取失败,请稍后再试'
}));
}
}
);
export default service

View File

@@ -0,0 +1,27 @@
import projectConfig from '@/core/config';
import { objectToQueryString } from '@/utils';
console.log(process.env.NODE_ENV, projectConfig);
/**
* 请求地址统一处理/组装
* @param actionName action方法名称
*/
export default function (actionName) {
if (actionName != null && actionName !== '') {
if (actionName.substr(0, 1) === '/') actionName = actionName.substr(1);
}
return projectConfig.baseUrl + actionName;
}
export function buildGetUrl (actionName, params) {
let queryString = objectToQueryString(params);
if (actionName != null && actionName !== '') {
if (actionName.substr(0, 1) === '/') actionName = actionName.substr(1);
}
return projectConfig.baseUrl + actionName + (queryString == null ? '' : ('?' + queryString));
}
export {
projectConfig
}

View File

@@ -0,0 +1,117 @@
import Vue from 'vue';
import Request from '@/core/http/request.js';
import { mapMutations, mapGetters } from 'vuex';
// 全局mixin对象
const globalMixin = {
data () {
return {
isHttpLoading: false
}
},
methods: {
/**
* 是否显示遮罩
* @param {Boolean} isShow 是否显示
*/
showMask (isShow) {
isShow ? this.loadingManager.showMask() : this.loadingManager.hideMask();
},
/**
* 判读用户是否有权限
* @param {String} permCode 权限字
*/
checkPermCodeExist (permCode) {
if (this.getUserInfo.permCodeSet != null) {
return this.getUserInfo.permCodeSet.has(permCode);
} else {
return this.getUserInfo.isAdmin;
}
},
/**
* 将输入的值转换成指定的类型
* @param {Any} value
* @param {String} type 要转换的类型integer、float、boolean、string
*/
parseParams (value, type = 'string') {
if (value == null) return value;
switch (type) {
case 'integer': return Number.parseInt(value);
case 'float': return Number.parseFloat(value);
case 'boolean': return (value === 'true' || value);
default: return String(value);
}
},
/**
* 将输入值转换为执行的类型数组
* @param {Array} value 输入数组
* @param {String} type 要转换的类型integer、float、boolean、string
*/
parseArrayParams (value, type = 'string') {
if (Array.isArray(value)) {
return value.map((item) => {
switch (type) {
case 'integer': return Number.parseInt(item);
case 'float': return Number.parseFloat(item);
case 'boolean': return (item === 'true' || item);
default: return String(item);
}
});
} else {
return [];
}
},
/**
* 下载上传的文件
* @param {*} url 下载文件的url
* @param {*} fileName 下载文件名
*/
downloadFile (url, fileName) {
console.log(fileName);
Request({
url: url,
method: 'get',
responseType: 'blob',
transformResponse: function (data) {
console.log(data);
return data;
}
}).then(res => {
console.log(res);
let data = res.data;
if (res.status === 200 && data instanceof Blob) {
let url = window.URL.createObjectURL(data);
let link = document.createElement('a');
link.style.display = 'none';
link.href = url;
link.setAttribute('download', fileName);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} else {
this.$message.error('下载文件失败');
}
}).catch(e => {
let reader = new FileReader();
reader.onload = () => {
let jsonObj = JSON.parse(reader.result);
this.$message.error((jsonObj || {}).errorMessage || '下载文件失败');
}
reader.readAsText(e);
});
},
...mapMutations(['setLoadingStatus'])
},
computed: {
...mapGetters(['getUserInfo'])
},
watch: {
'loadingManager.loading': {
handler: function (newValue) {
this.isHttpLoading = (newValue != null);
}
}
}
}
Vue.mixin(globalMixin);

View File

@@ -0,0 +1,293 @@
import projectConfig from '@/core/config';
import { buildGetUrl } from '@/core/http/requestUrl.js';
import { formatDate, parseDate } from 'element-ui/src/utils/date-util';
import { mapMutations } from 'vuex';
/**
* 上传文件组件相关方法
*/
const uploadMixin = {
methods: {
/**
* 解析返回的上传文件数据
* @param {String} jsonData 上传文件数据,[{name, downloadUri, filename}]
* @param {Object} params 上传文件的参数
* @returns {Array} 上传文件信息,[{name, downloadUri, filename, url}]
*/
parseUploadData (jsonData, params) {
let pathList = [];
if (jsonData != null) {
try {
pathList = JSON.parse(jsonData);
} catch (e) {
console.error(e);
}
}
return pathList.map((item) => {
let downloadParams = {...params};
downloadParams.filename = item.filename;
return {
...item,
url: this.getUploadFileUrl(item, downloadParams)
}
});
},
/**
* 获得上传文件url列表
* @param {*} jsonData 上传文件数据,[{name, downloadUri, filename}]
* @param {*} params 上传文件的参数
* @returns {Array} 文件url列表
*/
getPictureList (jsonData, params) {
let tempList = this.parseUploadData(jsonData, params);
if (Array.isArray(tempList)) {
return tempList.map(item => item.url);
} else {
return [];
}
},
/**
* 将选中文件信息格式化成json信息
* @param {Array} fileList 上传文件列表,[{name, fileUrl, data}]
*/
fileListToJson (fileList) {
if (Array.isArray(fileList)) {
return JSON.stringify(fileList.map((item) => {
return {
name: item.name,
downloadUri: item.downloadUri || item.response.data.downloadUri,
filename: item.filename || item.response.data.filename
}
}));
} else {
return undefined;
}
},
/**
* 获得上传文件url
* @param {*} item 上传文件
* @param {*} params 上传文件的参数
*/
getUploadFileUrl (item, params) {
if (item == null || item.downloadUri == null) {
return null;
} else {
let menuIdJsonStr = window.sessionStorage.getItem('currentMenuId');
let currentMenuId;
if (menuIdJsonStr != null) {
currentMenuId = (JSON.parse(menuIdJsonStr) || {}).data;
}
params.Authorization = window.sessionStorage.getItem('token');
params.MenuId = currentMenuId;
return buildGetUrl(item.downloadUri, params);
}
},
/**
* 获得上传接口
* @param {*} url 上传路径
*/
getUploadActionUrl (url) {
if (url != null && url[0] === '/') {
url = url.substr(1);
}
return projectConfig.baseUrl + url;
},
/**
* 上传文件是否图片文件
* @param {*} file 上传文件
*/
pictureFile (file) {
if (['image/jpeg', 'image/jpg', 'image/png'].indexOf(file.type) !== -1) {
return true;
} else {
this.$message.error('图片文件格式不正确,请重新选择');
return false;
}
}
},
computed: {
getUploadHeaders () {
let token = window.sessionStorage.getItem('token');
return {
Authorization: token
}
}
}
};
const allowStatsType = [
'time',
'datetime',
'day',
'month',
'year'
];
/**
* 日期相关方法
*/
const statsDateRangeMixin = {
methods: {
/**
* 根据输入的日期获得日期范围例如输入2019-12-12输出['2019-12-12 00:00:00', '2019-12-12 23:59:59']
* @param {Date|String} date 要转换的日期
* @param {String} statsType 转换类型day, month, year
* @param {String} format 输出格式
*/
getDateRangeFilter (date, statsType = 'day', format = 'yyyy-MM-dd HH:mm:ss') {
if (date == null) return [];
statsType = allowStatsType.indexOf(statsType) === -1 ? 'day' : statsType;
date = date.substr(0, date.indexOf(' '));
let tempList = date.split('-');
let year = Number.parseInt(tempList[0]);
let month = Number.parseInt(tempList[1]);
let day = Number.parseInt(tempList[2]);
if (isNaN(year) || isNaN(month) || isNaN(day)) {
return [];
}
let tempDate = new Date(year, month - 1, day);
// 判断是否正确的日期
if (isNaN(tempDate.getTime())) return [];
tempDate.setHours(0, 0, 0, 0);
let retDate;
switch (statsType) {
case 'day':
retDate = [
new Date(tempDate),
new Date(tempDate.setDate(tempDate.getDate() + 1))
];
break;
case 'month':
tempDate.setDate(1);
retDate = [
new Date(tempDate),
new Date(tempDate.setMonth(tempDate.getMonth() + 1))
];
break;
case 'year':
tempDate.setDate(1);
tempDate.setMonth(0);
retDate = [
new Date(tempDate),
new Date(tempDate.setFullYear(tempDate.getFullYear() + 1))
]
}
retDate[1] = new Date(retDate[1].getTime() - 1);
return [
formatDate(retDate[0], format),
formatDate(retDate[1], format)
];
},
/**
* 格式化日期
* @param {Date|String} date 要格式化的日期
* @param {String} statsType 输出日期类型
* @param {String} format 输入日期的格式
*/
formatDateByStatsType (date, statsType = 'day', format = 'yyyy-MM-dd') {
if (date == null) return undefined;
statsType = allowStatsType.indexOf(statsType) === -1 ? 'day' : statsType;
if (statsType === 'datetime') format = 'yyyy-MM-dd HH:mm:ss';
let tempDate = ((date instanceof Date) ? date : parseDate(date, format));
if (!tempDate) return undefined;
switch (statsType) {
case 'time':
return formatDate(tempDate, 'HH:mm:ss');
case 'datetime':
return formatDate(tempDate, 'yyyy-MM-dd HH:mm:ss');
case 'day':
return formatDate(tempDate, 'yyyy-MM-dd');
case 'month':
return formatDate(tempDate, 'yyyy-MM');
case 'year':
return formatDate(tempDate, 'yyyy');
default:
return formatDate(tempDate, 'yyyy-MM-dd');
}
},
/**
* 获得统计类型中文名称
* @param {String} statsType 统计类型day, month, year
*/
getStatsTypeShowName (statsType) {
statsType = allowStatsType.indexOf(statsType) === -1 ? 'day' : statsType;
switch (statsType) {
case 'day': return '日统计';
case 'month': return '月统计';
case 'year': return '年统计';
}
},
/**
* 获取统计类型字典列表
* @param {Array} statsTypeList 统计类型列表
*/
getAllowStatsTypeList (statsTypeList) {
if (Array.isArray(statsTypeList) && statsTypeList.length > 0) {
return statsTypeList.map((item) => {
return {
id: item,
name: this.getStatsTypeShowName(item)
}
});
} else {
return [];
}
}
}
}
/**
* 页面缓存相关方法
*/
const cachePageMixin = {
methods: {
/**
* 移除缓存页面
* @param {*} name 缓存组件的名称
*/
removeCachePage (name) {
this.removeCachePage(name);
},
/**
* 从跳转页面返回并且刷新当前页面时调用
*/
onResume () {
},
...mapMutations(['addCachePage', 'removeCachePage'])
},
created () {
this.addCachePage(this.$options.name);
},
activated () {
if (this.$route && this.$route.meta && this.$route.meta.refresh) {
this.onResume();
this.$route.meta.refresh = false;
}
}
}
/**
* 缓存页面跳转页面相关方法
*/
const cachedPageChildMixin = {
data () {
return {
// 是否刷新父页面
refreshParentCachedPage: false
}
},
beforeRouteLeave (to, from, next) {
if (to.meta == null) to.meta = {};
to.meta.refresh = this.refreshParentCachedPage;
next();
}
}
export {
uploadMixin,
statsDateRangeMixin,
cachePageMixin,
cachedPageChildMixin
}

View File

@@ -0,0 +1,36 @@
import '@/core/http';
import '@/components/Dialog';
import Vue from 'vue';
import ElementUI from 'element-ui';
// import 'element-ui/lib/theme-chalk/index.css'
import '@/assets/style/index.scss';
import '@/core/mixins/global.js';
import App from './App';
import router from './router';
import store from './store';
import TreeSelect from '@/components/TreeSelect';
import RichEditor from '@/components/RichEditor';
import InputNumberRange from '@/components/InputNumberRange';
import DateRange from '@/components/DateRange';
import FilterBox from '@/components/FilterBox';
import TableProgressColumn from '@/components/TableProgressColumn';
import VCharts from 'v-charts';
Vue.component('tree-select', TreeSelect);
Vue.component('rich-editor', RichEditor);
Vue.component('input-number-range', InputNumberRange);
Vue.component('date-range', DateRange);
Vue.component('filter-box', FilterBox);
Vue.component('table-progress-column', TableProgressColumn);
Vue.use(ElementUI);
Vue.use(VCharts);
Vue.config.productionTip = false;
/* eslint-disable no-new */
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app');

View File

@@ -0,0 +1,32 @@
/* eslint-disable no-console */
import { register } from 'register-service-worker'
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
ready () {
console.log(
'App is being served from cache by a service worker.\n' +
'For more details, visit https://goo.gl/AFskqB'
)
},
registered () {
console.log('Service worker has been registered.')
},
cached () {
console.log('Content has been cached for offline use.')
},
updatefound () {
console.log('New content is downloading.')
},
updated () {
console.log('New content is available; please refresh.')
},
offline () {
console.log('No internet connection found. App is running in offline mode.')
},
error (error) {
console.error('Error during service worker registration:', error)
}
})
}

View File

@@ -0,0 +1 @@
module.exports = file => require('../views/' + file + '.vue').default

View File

@@ -0,0 +1 @@
module.exports = file => () => import('../views/' + file + '.vue')

View File

@@ -0,0 +1,30 @@
import Vue from 'vue';
import Router from 'vue-router';
import routers from './systemRouters.js';
import dialog from '@/components/Dialog';
Vue.use(Router)
const router = new Router({
mode: 'hash',
routes: routers
});
/**
* 路由跳转的时候判断token是否存在
*/
router.beforeResolve((to, from, next) => {
if (to.name === 'login') {
next();
} else {
let token = sessionStorage.getItem('token');
if (!token || !/\S/.test(token)) {
dialog.closeAll();
next({ name: 'login' })
} else {
next();
}
}
});
export default router;

View File

@@ -0,0 +1,52 @@
import state from '../store/state.js';
// 开发环境不使用懒加载, 因为懒加载页面太多的话会造成webpack热更新太慢, 所以只有开发环境使用懒加载
const _import = require('./import-' + process.env.NODE_ENV)
function getProps (route) {
return route.query;
}
// 系统生成路由
const routers = [
{ path: '/login', component: _import('login/index'), name: 'login', props: getProps, desc: '登录' },
{
path: '/',
component: _import('login/index'),
name: 'root'
},
{
path: '/main',
component: _import('layout/index'),
name: 'main',
props: getProps,
redirect: {
name: 'welcome'
},
meta: {
title: '主页',
showOnly: true
},
children: [
{path: 'welcome', component: _import('welcome/index'), name: 'welcome', meta: {title: '欢迎'}},
{path: 'formSysUser', component: _import('upms/formSysUser/index'), name: 'formSysUser', meta: {title: '用户管理'}},
{path: 'formSysRole', component: _import('upms/formSysRole/index'), name: 'formSysRole', meta: {title: '角色管理'}},
{path: 'formSysMenu', component: _import(state.supportColumn ? 'upms/formSysMenu/formSysColumnMenu' : 'upms/formSysMenu/index'), name: 'formSysMenu', meta: {title: '菜单列表'}},
{path: 'formSysDict', component: _import('upms/formDictManagement/index'), name: 'formSysDict', meta: {title: '字典管理'}},
{path: 'formSysPermCode', component: _import('upms/formSysPermCode/index'), name: 'formSysPermCode', meta: {title: '权限字管理'}},
{path: 'formSysPerm', component: _import('upms/formSysPerm/index'), name: 'formSysPerm', meta: {title: '权限资源管理'}},
{path: 'formSchool', component: _import('generated/formSchool/index'), name: 'formSchool', props: getProps, meta: {title: '校区管理'}},
{path: 'formStudent', component: _import('generated/formStudent/index'), name: 'formStudent', props: getProps, meta: {title: '学生管理'}},
{path: 'formCourse', component: _import('generated/formCourse/index'), name: 'formCourse', props: getProps, meta: {title: '课程管理'}},
{path: 'formClass', component: _import('generated/formClass/index'), name: 'formClass', props: getProps, meta: {title: '班级管理'}},
{path: 'formClassStudent', component: _import('generated/formClassStudent/index'), name: 'formClassStudent', props: getProps, meta: {title: '班级学生'}},
{path: 'formClassCourse', component: _import('generated/formClassCourse/index'), name: 'formClassCourse', props: getProps, meta: {title: '班级课程'}},
{path: 'formSetClassStudent', component: _import('generated/formSetClassStudent/index'), name: 'formSetClassStudent', props: getProps, meta: {title: '设置班级学生'}},
{path: 'formSetClassCourse', component: _import('generated/formSetClassCourse/index'), name: 'formSetClassCourse', props: getProps, meta: {title: '设置班级课程'}},
{path: 'formCourseStats', component: _import('generated/formCourseStats/index'), name: 'formCourseStats', props: getProps, meta: {title: '课程统计'}},
{path: 'formStudentActionStats', component: _import('generated/formStudentActionStats/index'), name: 'formStudentActionStats', props: getProps, meta: {title: '学生行为统计'}},
{path: 'formStudentActionDetail', component: _import('generated/formStudentActionDetail/index'), name: 'formStudentActionDetail', props: getProps, meta: {title: '学生行为详情'}}
]
}
];
export default routers;

View File

@@ -0,0 +1,351 @@
/**
* 常量字典数据
*/
import Vue from 'vue';
class DictionaryBase extends Map {
constructor (dataList, keyId = 'id', symbolId = 'symbol') {
super();
this.setList(dataList, keyId, symbolId);
}
setList (dataList, keyId = 'id', symbolId = 'symbol') {
this.clear();
if (Array.isArray(dataList)) {
dataList.forEach((item) => {
this.set(item[keyId], item);
if (item[symbolId] != null) {
Object.defineProperty(this, item[symbolId], {
get: function () {
return item[keyId];
}
});
}
});
}
}
getList (valueId = 'name', parentIdKey = 'parentId', filter) {
let temp = [];
this.forEach((value, key) => {
let obj = {
id: key,
name: (typeof value === 'string') ? value : value[valueId],
parentId: value[parentIdKey]
};
if (typeof filter !== 'function' || filter(obj)) {
temp.push(obj);
}
});
return temp;
}
getValue (id, valueId = 'name') {
return (this.get(id) || {})[valueId];
}
}
const SysUserStatus = new DictionaryBase([
{
id: 0,
name: '正常状态',
symbol: 'NORMAL'
},
{
id: 1,
name: '锁定状态',
symbol: 'LOCKED'
}
]);
Vue.prototype.SysUserStatus = SysUserStatus;
const SysUserType = new DictionaryBase([
{
id: 0,
name: '管理员',
symbol: 'ADMIN'
},
{
id: 1,
name: '系统操作员',
symbol: 'SYSTEM'
},
{
id: 2,
name: '普通操作员',
symbol: 'OPERATOR'
}
]);
Vue.prototype.SysUserType = SysUserType;
const ClassStatus = new DictionaryBase([
{
id: 1,
name: '正常',
symbol: 'NORAML'
},
{
id: -1,
name: '解散',
symbol: 'DELETED'
}
]);
Vue.prototype.ClassStatus = ClassStatus;
const ClassLevel = new DictionaryBase([
{
id: 0,
name: '初级班',
symbol: 'NORMAL'
},
{
id: 1,
name: '中级班',
symbol: 'MIDDLE'
},
{
id: 2,
name: '高级班',
symbol: 'HIGH'
}
]);
Vue.prototype.ClassLevel = ClassLevel;
const CourseDifficult = new DictionaryBase([
{
id: 0,
name: '容易',
symbol: 'NORMAL'
},
{
id: 1,
name: '普通',
symbol: 'MIDDLE'
},
{
id: 2,
name: '困难',
symbol: 'HIGH'
}
]);
Vue.prototype.CourseDifficult = CourseDifficult;
const Subject = new DictionaryBase([
{
id: 0,
name: '语文',
symbol: 'CHINESE'
},
{
id: 1,
name: '数学',
symbol: 'MATCH'
},
{
id: 2,
name: '英语',
symbol: 'ENGLISH'
}
]);
Vue.prototype.Subject = Subject;
const StudentActionType = new DictionaryBase([
{
id: 0,
name: '充值',
symbol: 'RECHARGE'
},
{
id: 1,
name: '购课',
symbol: 'BUY_COURSE'
},
{
id: 2,
name: '上课签到',
symbol: 'SIGNIN_COURSE'
},
{
id: 3,
name: '上课签退',
symbol: 'SIGNOUT_COURSE'
},
{
id: 4,
name: '看视频课',
symbol: 'WATCH_VIDEO'
},
{
id: 5,
name: '做作业',
symbol: 'DO_PAPER'
},
{
id: 6,
name: '刷题',
symbol: 'REFRESH_EXERCISE'
},
{
id: 7,
name: '献花',
symbol: 'PRESENT_FLOWER'
},
{
id: 8,
name: '购买视频课',
symbol: 'BUY_VIDEO_COURSE'
},
{
id: 9,
name: '购买鲜花',
symbol: 'BUY_FLOWER'
},
{
id: 10,
name: '购买作业',
symbol: 'BUY_PAPER'
}
]);
Vue.prototype.StudentActionType = StudentActionType;
const DeviceType = new DictionaryBase([
{
id: 0,
name: 'iOS',
symbol: 'IOS'
},
{
id: 1,
name: 'Android',
symbol: 'ANDROID'
},
{
id: 2,
name: 'PC',
symbol: 'PC'
}
]);
Vue.prototype.DeviceType = DeviceType;
const Gender = new DictionaryBase([
{
id: 1,
name: '男',
symbol: 'MALE'
},
{
id: 0,
name: '女',
symbol: 'FEMALE'
}
]);
Vue.prototype.Gender = Gender;
const ExpLevel = new DictionaryBase([
{
id: 0,
name: '初级学员',
symbol: 'LOWER'
},
{
id: 1,
name: '中级学员',
symbol: 'MIDDLE'
},
{
id: 2,
name: '高级学员',
symbol: 'HIGH'
}
]);
Vue.prototype.ExpLevel = ExpLevel;
const StudentStatus = new DictionaryBase([
{
id: 0,
name: '正常',
symbol: 'NORMAL'
},
{
id: 1,
name: '锁定',
symbol: 'LOCKED'
},
{
id: 2,
name: '注销',
symbol: 'DELETED'
}
]);
Vue.prototype.StudentStatus = StudentStatus;
const SysPermModuleType = new DictionaryBase([
{
id: 0,
name: '分组模块',
symbol: 'GROUP'
}, {
id: 1,
name: '接口模块',
symbol: 'CONTROLLER'
}
]);
Vue.prototype.SysPermModuleType = SysPermModuleType;
const SysPermCodeType = new DictionaryBase([{
id: 0,
name: '表单',
symbol: 'FORM'
}, {
id: 1,
name: '片段',
symbol: 'FRAGMENT'
}, {
id: 2,
name: '操作',
symbol: 'OPERATION'
}]);
Vue.prototype.SysPermCodeType = SysPermCodeType;
const SysMenuType = new DictionaryBase([
{
id: 0,
name: '目录',
symbol: 'DIRECTORY'
},
{
id: 1,
name: '表单',
symbol: 'MENU'
},
{
id: 2,
name: '片段',
symbol: 'FRAGMENT'
},
{
id: 3,
name: '按钮',
symbol: 'BUTTON'
}
]);
Vue.prototype.SysMenuType = SysMenuType;
export {
DictionaryBase,
SysUserStatus,
SysUserType,
ClassStatus,
ClassLevel,
CourseDifficult,
Subject,
StudentActionType,
DeviceType,
Gender,
ExpLevel,
StudentStatus,
SysPermModuleType,
SysPermCodeType,
SysMenuType
}

View File

@@ -0,0 +1 @@
export default {}

View File

@@ -0,0 +1,80 @@
import { findMenuItem } from './utils';
import * as StaticDict from '@/staticDict';
export default {
getMultiTags: (state) => {
return state.supportTags;
},
getCollapse: (state) => {
return state.isCollapse;
},
getClientHeight: (state) => {
return state.documentClientHeight;
},
getMainContextHeight: (state) => {
return state.documentClientHeight - (state.supportTags ? 130 : 90);
},
getUserInfo: (state) => {
return state.userInfo;
},
getCachePages: (state) => {
return state.cachePages;
},
getTagList: (state) => {
return state.tagList;
},
getMenuList: (state) => {
if (state.supportColumn) {
if (state.currentColumnId == null || state.currentColumnId === '') return [];
for (let i = 0; i < state.menuList.length; i++) {
if (state.menuList[i].menuId === state.currentColumnId) {
return state.menuList[i].children || [];
}
}
return [];
} else {
return state.menuList;
}
},
getColumnList: (state) => {
if (!state.supportColumn) return [];
return state.menuList.map(menu => {
if (menu.menuType === StaticDict.SysMenuType.DIRECTORY) {
return {
columnId: menu.menuId,
columnName: menu.menuName
}
}
}).filter(item => item != null);
},
getCurrentMenuId: (state) => {
return state.currentMenuId;
},
getMenuItem: (state) => {
if (Array.isArray(state.menuList)) {
for (let i = 0; i < state.menuList.length; i++) {
let temp = findMenuItem(state.menuList[i], state.currentMenuId);
if (temp != null) return temp;
}
}
return null;
},
getCurrentMenuPath: (state) => {
let menuPath = [];
if (Array.isArray(state.menuList)) {
for (let i = 0; i < state.menuList.length; i++) {
let temp = findMenuItem(state.menuList[i], state.currentMenuId, menuPath);
if (temp != null) break;
}
}
return menuPath;
},
getMultiColumn: (state) => {
return state.supportColumn;
},
getCurrentColumnId: (state) => {
return state.currentColumnId;
}
}

View File

@@ -0,0 +1,15 @@
import Vue from 'vue';
import Vuex from 'vuex';
import state from './state.js';
import getters from './getters.js';
import mutations from './mutations.js';
import actions from './actions.js';
Vue.use(Vuex);
export default new Vuex.Store({
state,
getters,
mutations,
actions,
strict: process.env.NODE_ENV !== 'production'
});

View File

@@ -0,0 +1,145 @@
import { initUserInfo, findMenuItem } from './utils';
import { setObjectToSessionStorage, findItemFromList, treeDataTranslate } from '@/utils';
export default {
setCollapse: (state, isCollapse) => {
state.isCollapse = isCollapse;
},
setClientHeight: (state, height) => {
state.documentClientHeight = height;
},
setUserInfo: (state, info) => {
setObjectToSessionStorage('userInfo', info);
state.userInfo = initUserInfo(info);
},
addCachePage (state, name) {
if (state.cachePages.indexOf(name) === -1) {
let temp = [...state.cachePages];
temp.push(name);
setObjectToSessionStorage('cachePages', temp);
state.cachePages = temp;
}
},
removeCachePage (state, name) {
let pos = state.cachePages.indexOf(name);
if (pos !== -1) {
let temp = [...state.cachePages];
temp.splice(pos, 1);
setObjectToSessionStorage('cachePages', temp);
state.cachePages = temp;
}
},
clearCachePage (state) {
setObjectToSessionStorage('cachePages', []);
state.cachePages = [];
},
addTag (state, id) {
if (id == null || id === '') return;
// 新增的标签是否存在
let tagList = state.tagList;
let tagItem = null;
if (Array.isArray(tagList)) {
tagItem = findItemFromList(tagList, id, 'menuId');
}
if (tagItem != null) return;
// 添加新增标签以及更新页面缓存
let menuList = state.menuList;
let menuObject = null;
if (Array.isArray(menuList)) {
for (let i = 0; i < menuList.length; i++) {
menuObject = findMenuItem(menuList[i], id);
if (menuObject != null) break;
}
}
if (menuObject != null) {
state.tagList = [...state.tagList, menuObject];
if (Array.isArray(state.cachePages) && state.cachePages.indexOf(menuObject.formRouterName) === -1) {
state.cachePages = [...state.cachePages, menuObject.formRouterName];
}
}
setObjectToSessionStorage('cachePages', state.cachePages);
setObjectToSessionStorage('tagList', state.tagList);
},
removeTag (state, id) {
if (id == null || id === '') return;
// 移除标签
let nextPos = -1;
let tagItem = null;
for (let i = 0; i < state.tagList.length; i++) {
if (state.tagList[i].menuId === id) {
tagItem = state.tagList[i];
state.tagList.splice(i, 1);
nextPos = Math.min(i, state.tagList.length - 1);
}
}
// let tagItem = findItemFromList(state.tagList, id, 'menuId', true);
if (tagItem == null) return;
// 移除页面缓存
findItemFromList(state.cachePages, tagItem.formRouterName, undefined, true);
setObjectToSessionStorage('cachePages', state.cachePages);
setObjectToSessionStorage('tagList', state.tagList);
// 如果移除的是当前显示页面,重新选择显示页面
let showTag = null;
if (state.currentMenuId === id) {
showTag = state.tagList[nextPos];
let tempId = (showTag || {}).menuId;
if (setObjectToSessionStorage('currentMenuId', tempId)) state.currentMenuId = tempId;
}
},
closeOtherTags (state, id) {
if (id == null || id === '') return;
// 移除其他所有标签
if (Array.isArray(state.tagList)) {
state.tagList = state.tagList.filter((item) => {
return item.menuId === id;
});
}
let menuObject = state.tagList[0];
if (menuObject && menuObject.formRouterName && menuObject.formRouterName !== '') {
state.cachePages = [menuObject.formRouterName];
if (setObjectToSessionStorage('currentMenuId', menuObject.menuId)) state.currentMenuId = menuObject.menuId;
}
setObjectToSessionStorage('cachePages', state.cachePages);
setObjectToSessionStorage('tagList', state.tagList);
},
clearAllTags (state) {
if (setObjectToSessionStorage('currentMenuId', undefined)) state.currentMenuId = undefined;
if (setObjectToSessionStorage('cachePages', [])) state.cachePages = [];
if (setObjectToSessionStorage('tagList', [])) state.tagList = [];
},
setMenuList: (state, list) => {
if (Array.isArray(list)) {
if (setObjectToSessionStorage('menuList', list)) state.menuList = treeDataTranslate(list, 'menuId', 'parentId');
let columnId = (state.menuList[0] || {}).menuId;
if (setObjectToSessionStorage('currentColumnId', columnId)) state.currentColumnId = columnId;
}
},
setCurrentMenuId: (state, menuId) => {
let menuItem = null;
if (setObjectToSessionStorage('currentMenuId', menuId)) state.currentMenuId = menuId;
if (Array.isArray(state.tagList) && Array.isArray(state.menuList)) {
for (let i = 0; i < state.menuList.length; i++) {
menuItem = findMenuItem(state.menuList[i], menuId, 'menuId');
if (menuItem != null) {
// 添加新的tag
let tagItem = findItemFromList(state.tagList, menuId, 'menuId');
if (tagItem == null) {
state.tagList = [...state.tagList, menuItem];
setObjectToSessionStorage('tagList', state.tagList);
}
// 添加新缓存
if (Array.isArray(state.cachePages) && state.cachePages.indexOf(menuItem.formRouterName) === -1) {
state.cachePages = [...state.cachePages, menuItem.formRouterName];
setObjectToSessionStorage('cachePages', state.cachePages);
}
break;
}
}
}
},
setCurrentColumnId: (state, columnId) => {
if (setObjectToSessionStorage('currentColumnId', columnId)) state.currentColumnId = columnId;
if (setObjectToSessionStorage('currentMenuId', null)) state.currentMenuId = null;
}
}

View File

@@ -0,0 +1,25 @@
import { initUserInfo } from './utils';
import { getObjectFromSessionStorage, treeDataTranslate } from '@/utils';
export default {
// 是否左侧菜单折叠
isCollapse: false,
// 是否多栏目
supportColumn: false,
// 是否多标签
supportTags: false,
// 浏览器客户区高度
documentClientHeight: 100,
// 用户登录信息
userInfo: initUserInfo(),
// 缓存页面
cachePages: getObjectFromSessionStorage('cachePages', []),
// 当前标签
tagList: getObjectFromSessionStorage('tagList', []),
// 菜单列表
menuList: treeDataTranslate(getObjectFromSessionStorage('menuList', []), 'menuId', 'parentId'),
// 当前菜单
currentMenuId: getObjectFromSessionStorage('currentMenuId', undefined),
// 当前栏目
currentColumnId: getObjectFromSessionStorage('currentColumnId', undefined)
}

View File

@@ -0,0 +1,36 @@
import { getObjectFromSessionStorage } from '@/utils';
function findMenuItem (menuItem, menuId, path) {
if (Array.isArray(path)) path.push(menuItem);
if ((menuItem.menuId + '') === (menuId + '')) return menuItem;
let bFind = false;
let findItem = null;
if (Array.isArray(menuItem.children)) {
for (let i = 0; i < menuItem.children.length; i++) {
findItem = findMenuItem(menuItem.children[i], menuId, path);
if (findItem != null) {
bFind = true;
break;
}
}
}
if (!bFind && Array.isArray(path)) path.pop();
return bFind ? findItem : null;
}
function initUserInfo (userInfo) {
if (userInfo == null) userInfo = getObjectFromSessionStorage('userInfo');
if (userInfo != null && userInfo.permCodeList != null && Array.isArray(userInfo.permCodeList)) {
userInfo.permCodeSet = new Set(userInfo.permCodeList);
}
return userInfo;
}
export {
findMenuItem,
initUserInfo
}

View File

@@ -0,0 +1,56 @@
const defaultLineChartOption = {
grid: {
left: '3%',
right: '4%',
bottom: '20px',
containLabel: true
},
xAxis: {
axisLabel: {
interval: 0,
showMaxLabel: true
}
},
legend: {
top: '3%'
}
}
const defaultBarChartOption = {
grid: {
left: '3%',
right: '4%',
bottom: '20px',
containLabel: true
},
xAxis: {
axisLabel: {
interval: 0,
showMaxLabel: true
}
},
legend: {
top: '3%'
}
}
const defaultPieChartOption = {
grid: {
left: '3%',
right: '4%',
bottom: '20px',
containLabel: true
},
legend: {
top: '3%'
},
series: {
center: ['50%', '60%']
}
}
export {
defaultLineChartOption,
defaultBarChartOption,
defaultPieChartOption
}

View File

@@ -0,0 +1,222 @@
import JSEncrypt from 'jsencrypt';
/**
* 列表数据转换树形数据
* @param {Array} data 要转换的列表
* @param {String} id 主键字段字段名
* @param {String} pid 父字段字段名
* @returns {Array} 转换后的树数据
*/
export function treeDataTranslate (data, id = 'id', pid = 'parentId') {
var res = []
var temp = {}
for (var i = 0; i < data.length; i++) {
temp[data[i][id]] = data[i]
}
for (var k = 0; k < data.length; k++) {
if (temp[data[k][pid]] && data[k][id] !== data[k][pid]) {
if (!temp[data[k][pid]]['children']) {
temp[data[k][pid]]['children'] = []
}
if (!temp[data[k][pid]]['_level']) {
temp[data[k][pid]]['_level'] = 1
}
data[k]['_level'] = temp[data[k][pid]]._level + 1
data[k]['_parent'] = data[k][pid]
temp[data[k][pid]]['children'].push(data[k])
} else {
res.push(data[k])
}
}
return res
}
/**
* 获取字符串字节长度中文算2个字符
* @param {String} str 要获取长度的字符串
*/
export function getStringLength (str) {
return str.replace(/[\u4e00-\u9fa5\uff00-\uffff]/g, '**').length
}
/**
* 获取uuid
*/
export function getUUID () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
return (c === 'x' ? (Math.random() * 16 | 0) : ('r&0x3' | '0x8')).toString(16)
});
}
/**
* 大小驼峰变换函数
* @param name 要转换的字符串
* @param type 转换的类型0转换成小驼峰1转换成大驼峰
*/
export function nameTranslate (name, type) {
name = name.toLowerCase();
let nameArray = name.split('_');
nameArray.forEach((item, index) => {
if (index === 0) {
name = type === 1 ? item.slice(0, 1).toUpperCase() + item.slice(1) : item;
} else {
name = name + item.slice(0, 1).toUpperCase() + item.slice(1);
}
});
nameArray = name.split('-');
nameArray.forEach((item, index) => {
if (index === 0) {
name = type === 1 ? item.slice(0, 1).toUpperCase() + item.slice(1) : item;
} else {
name = name + item.slice(0, 1).toUpperCase() + item.slice(1);
}
});
return name;
}
/**
* 通过id从树中获取指定的节点
* @param {Object} node 根节点
* @param {String|Nubmer} id 键值
* @param {Array} list 保存查询路径
* @param {String} idKey 主键字段名
* @param {String} childKey 子节点字段名
*/
function findNode (node, id, list, idKey = 'id', childKey = 'children') {
if (Array.isArray(list)) list.push(node[idKey]);
if (node[idKey] === id) {
return node;
}
if (node[childKey] != null && Array.isArray(node[childKey])) {
for (let i = 0; i < node[childKey].length; i++) {
let tempNode = findNode(node[childKey][i], id, list, idKey, childKey);
if (tempNode) return tempNode;
}
}
if (Array.isArray(list)) list.pop();
}
/**
* 通过id返回从根节点到指定节点的路径
* @param {Array} treeRoot 树根节点数组
* @param {*} id 要查询的节点的id
* @param {*} idKey 主键字段名
* @param {*} childKey 子节点字段名
*/
export function findTreeNodePath (treeRoot, id, idKey = 'id', childKey = 'children') {
let tempList = [];
for (let i = 0; i < treeRoot.length; i++) {
if (findNode(treeRoot[i], id, tempList, idKey, childKey)) {
return tempList;
}
}
return [];
}
/**
* 通过id从树中查找节点
* @param {Array} treeRoot 根节点数组
* @param {*} id 要查找的节点的id
* @param {*} idKey 主键字段名
* @param {*} childKey 子节点字段名
*/
export function findTreeNode (treeRoot, id, idKey = 'id', childKey = 'children') {
for (let i = 0; i < treeRoot.length; i++) {
let tempNode = findNode(treeRoot[i], id, undefined, idKey, childKey);
if (tempNode) return tempNode;
}
}
/**
* 把Object转换成query字符串
* @param {Object} params 要转换的Object
*/
export function objectToQueryString (params) {
if (params == null) {
return null;
} else {
return Object.keys(params).map((key) => {
return `${key}=${params[key]}`;
}).join('&');
}
}
/**
* 从数组中查找某一项
* @param {Array} list 要查找的数组
* @param {String} id 要查找的节点id
* @param {String} idKey 主键字段名如果为null则直接比较
* @param {Boolean} removeItem 是否从数组中移除查找到的节点
* @returns {Object} 找到返回节点没找到返回undefined
*/
export function findItemFromList (list, id, idKey, removeItem = false) {
if (Array.isArray(list) && list.length > 0 && id != null) {
for (let i = 0; i < list.length; i++) {
let item = list[i];
if (((idKey == null || idKey === '') && item === id) || (idKey != null && item[idKey] === id)) {
if (removeItem) list.splice(i, 1);
return item;
}
}
}
return null;
}
/**
* 将数据保存到sessionStorage
* @param {*} key sessionStorage的键值
* @param {*} value 要保存的数据
*/
export function setObjectToSessionStorage (key, value) {
if (key == null || key === '') return false;
if (value == null) {
window.sessionStorage.removeItem(key);
return true;
} else {
let jsonObj = {
data: value
}
window.sessionStorage.setItem(key, JSON.stringify(jsonObj));
return true;
}
}
/**
* 从sessionStorage里面获取数据
* @param {String} key 键值
* @param {*} defaultValue 默认值
*/
export function getObjectFromSessionStorage (key, defaultValue) {
let jsonObj = null;
try {
jsonObj = JSON.parse(window.sessionStorage.getItem(key));
jsonObj = (jsonObj || {}).data;
} catch (e) {
jsonObj = defaultValue;
};
return (jsonObj != null) ? jsonObj : defaultValue;
}
/**
* 判读字符串是否一个数字
* @param {String} str 要判断的字符串
*/
export function isNumber (str) {
let num = Number.parseFloat(str);
if (Number.isNaN(num)) return false;
return num.toString() === str;
}
/**
* 生成随机数
* @param {Integer} min 随机数最小值
* @param {Integer} max 随机数最大值
*/
export function random (min, max) {
let base = Math.random();
return min + base * (max - min);
}
/**
* 加密
* @param {*} value 要加密的字符串
*/
const publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpC4QMnbTrQOFriJJCCFFWhlruBJThAEBfRk7pRx1jsAhyNVL3CqJb0tRvpnbCnJhrRAEPdgFHXv5A0RrvFp+5Cw7QoFH6O9rKB8+0H7+aVQeKITMUHf/XMXioymw6Iq4QfWd8RhdtM1KM6eGTy8aU7SO2s69Mc1LXefg/x3yw6wIDAQAB';
export function encrypt (value) {
if (value == null || value === '') return null;
let encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);
return encodeURIComponent(encrypt.encrypt(value));
}

View File

@@ -0,0 +1,33 @@
const pattern = {
mobie: /^((\+?86)|(\(\+86\)))?(13[012356789][0-9]{8}|15[012356789][0-9]{8}|18[02356789][0-9]{8}|147[0-9]{8}|1349[0-9]{7})$/,
english: /^[a-zA-Z]+$/,
englishAndNumber: /^[a-zA-Z0-9]+$/
}
/**
* 邮箱
* @param str
*/
export function isEmail (str) {
return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(str)
}
/**
* 手机号码
* @param str
*/
export function isMobile (str) {
return pattern.mobie.test(str)
}
/**
* 电话号码
* @param str
*/
export function isPhone (str) {
return /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(str)
}
export default {
pattern
}

View File

@@ -0,0 +1,297 @@
import { Message } from 'element-ui';
import { treeDataTranslate } from '@/utils';
const DEFAULT_PAGE_SIZE = 10;
export class DropdownWidget {
/**
* 下拉组件Select、Cascade、TreeSelect等
* @param {function () : Promise} loadDropdownData 下拉数据获取函数
* @param {Boolean} isTree 是否是树数据
* @param {String} idKey 键字段字段名
* @param {String} parentIdKey 父字段字段名
*/
constructor (loadDropdownData, isTree = false, idKey = 'id', parentIdKey = 'parentId') {
this.loading = false;
this.dirty = true;
this.dropdownList = [];
this.isTree = isTree;
this.idKey = idKey;
this.parentIdKey = parentIdKey;
this.loadDropdownData = loadDropdownData;
this.setDropdownList = this.setDropdownList.bind(this);
this.onVisibleChange = this.onVisibleChange.bind(this);
}
/**
* 重新获取下拉数据
*/
reloadDropdownData () {
return new Promise((resolve, reject) => {
if (!this.loading) {
if (typeof this.loadDropdownData === 'function') {
this.loading = true;
this.loadDropdownData().then(dataList => {
this.setDropdownList(dataList);
this.loading = false;
this.dirty = false;
resolve(this.dropdownList);
}).catch(e => {
this.setDropdownList([]);
this.loading = false;
reject(this.dropdownList);
});
} else {
reject(new Error('获取下拉数据失败'));
}
} else {
resolve(this.dropdownList);
}
});
}
/**
* 下拉框显示或隐藏时调用
* @param {Boolean} isShow 正在显示或者隐藏
*/
onVisibleChange (isShow) {
return new Promise((resolve, reject) => {
if (isShow && this.dirty && !this.loading) {
this.reloadDropdownData().then(res => {
resolve(res);
}).catch(e => {
reject(e);
});
} else {
resolve(this.dropdownList);
}
});
}
/**
* 设置下拉数据
* @param {Array} dataList 要显示的下拉数据
*/
setDropdownList (dataList) {
if (Array.isArray(dataList)) {
this.dropdownList = this.isTree ? treeDataTranslate(dataList, this.idKey, this.parentIdKey) : dataList;
}
}
}
export class TableWidget {
/**
* 表格组件
* @param {function (params: Object) : Promise} loadTableData 表数据获取函数
* @param {function () : Boolean} verifyTableParameter 表数据获取检验函数
* @param {Boolean} paged 是否支持分页
* @param {String} orderFieldName 默认排序字段
* @param {Boolean} ascending 默认排序方式true为正序false为倒序
* @param {String} dateAggregateBy 默认排序字段的日期统计类型
*/
constructor (loadTableData, verifyTableParameter, paged, orderFieldName, ascending, dateAggregateBy) {
this.oldPage = 0;
this.currentPage = 1;
this.oldPageSize = DEFAULT_PAGE_SIZE;
this.pageSize = DEFAULT_PAGE_SIZE;
this.totalCount = 0;
this.dataList = [];
this.orderInfo = {
fieldName: orderFieldName,
asc: ascending,
dateAggregateBy: dateAggregateBy
};
this.paged = paged;
this.searchVerify = verifyTableParameter || function () { return true; };
this.loadTableData = loadTableData || function () { return Promise.resolve(); };
this.onCurrentPageChange = this.onCurrentPageChange.bind(this);
this.onPageSizeChange = this.onPageSizeChange.bind(this);
this.onSortChange = this.onSortChange.bind(this);
this.getTableIndex = this.getTableIndex.bind(this);
}
/**
* 表格分页变化
* @param {Integer} newCurrentPage 变化后的显示页面
*/
onCurrentPageChange (newCurrentPage) {
this.loadTableDataImpl(newCurrentPage, this.pageSize).then(() => {
this.oldPage = this.currentPage = newCurrentPage;
}).catch(() => {
this.currentPage = this.oldPage;
});
}
/**
* 表格分页每页显示数量变化
* @param {Integer} newPageSize 变化后的每页显示数量
*/
onPageSizeChange (newPageSize) {
this.loadTableDataImpl(1, newPageSize).then(() => {
this.oldPage = this.currentPage = 1;
this.oldPageSize = this.pageSize = newPageSize;
}).catch(e => {
this.currentPage = this.oldPage;
this.pageSize = this.oldPageSize;
});
}
/**
* 表格排序字段变化
* @param {String} prop 排序字段的字段名
* @param {String} order 正序还是倒序
*/
onSortChange ({ prop, order }) {
this.orderInfo.fieldName = prop;
this.orderInfo.asc = (order === 'ascending');
this.refreshTable();
}
/**
* 获取每一行的index信息
* @param {Integer} index 表格在本页位置
*/
getTableIndex (index) {
return this.paged ? ((this.currentPage - 1) * this.pageSize + (index + 1)) : (index + 1);
}
/**
* 获取表格数据
* @param {Integer} pageNum 当前分页
* @param {Integer} pageSize 每页数量
* @param {Boolean} reload 是否重新获取数据
*/
loadTableDataImpl (pageNum, pageSize, reload = false) {
return new Promise((resolve, reject) => {
if (typeof this.loadTableData !== 'function') {
reject();
} else {
// 如果pageSize和pageNum没有变化并且不强制刷新
if (this.paged && !reload && this.oldPage === pageNum && this.oldPageSize === pageSize) {
resolve();
} else {
let params = {};
if (this.orderInfo.fieldName != null) params.orderParam = [this.orderInfo];
if (this.paged) {
params.pageParam = {
pageNum,
pageSize
}
}
this.loadTableData(params).then(tableData => {
this.dataList = tableData.dataList;
this.totalCount = tableData.totalCount;
resolve();
}).catch(e => {
reject(e);
});
}
}
});
}
/**
* 刷新表格数据
* @param {Boolean} research 是否按照新的查询条件重新查询调用verify函数
* @param {Integer} pageNum 当前页面
*/
refreshTable (research = false, pageNum = undefined, showMsg = false) {
let reload = false;
if (research) {
if (typeof this.searchVerify === 'function' && !this.searchVerify()) return;
reload = true;
}
if (Number.isInteger(pageNum) && pageNum !== this.currentPage) {
this.loadTableDataImpl(pageNum, this.pageSize, reload).then(res => {
this.oldPage = this.currentPage = pageNum;
if (research && showMsg) Message.success('查询成功');
}).catch(e => {
this.currentPage = this.oldPage;
});
} else {
this.loadTableDataImpl(this.currentPage, this.pageSize, true).catch(e => {});
}
}
}
export class UploadWidget {
/**
* 上传组件
* @param {Integer} maxCount 最大上传数量
*/
constructor (maxCount = 1) {
this.maxCount = maxCount;
this.fileList = [];
this.onFileChange = this.onFileChange.bind(this);
}
/**
* 上传文件列表改变
* @param {Object} file 改变的文件
* @param {Array} fileList 改变后的文件列表
*/
onFileChange (file, fileList) {
if (Array.isArray(fileList) && fileList.length > 0) {
if (this.maxCount === 1) {
this.fileList = [fileList[fileList.length - 1]];
} else {
this.fileList = fileList;
}
} else {
this.fileList = [];
}
return this.fileList;
}
}
export class ChartWidget {
/**
* 图表组件
* @param {function (params) : Promise} loadTableData chart数据获取函数
* @param {function () : Boolean} verifyTableParameter 数据参数检验函数
* @param {Array} columns 数据列
*/
constructor (loadTableData, verifyTableParameter, columns) {
this.columns = columns;
this.loading = false;
this.dataEmpty = false;
this.chartData = undefined;
this.chartObject = undefined;
this.dimensionMaps = new Map();
this.chartSetting = undefined;
this.searchVerify = verifyTableParameter || function () { return true; };
this.loadTableData = loadTableData || function () { return Promise.resolve(); };
}
/**
* 获取图表数据
* @param {Boolean} reload 是否重新获取数据
*/
loadChartDataImpl (reload = false) {
return new Promise((resolve, reject) => {
if (typeof this.loadTableData !== 'function') {
reject();
} else {
if (!reload) {
resolve();
} else {
this.loading = true;
this.loadTableData().then(tableData => {
this.chartData = {
columns: this.columns,
rows: tableData.dataList
}
this.loading = false;
if (this.chartObject) this.chartObject.resize();
resolve();
}).catch(e => {
console.error(e);
this.loading = false;
reject(e);
});
}
}
});
}
/**
* 刷新图表数据
* @param {Boolean} research 是否按照新的查询条件重新查询调用verify函数
*/
refreshChart (research = false) {
if (research) {
if (typeof this.searchVerify === 'function' && !this.searchVerify()) return;
}
this.loadChartDataImpl(true).catch(e => {});
}
}

View File

@@ -0,0 +1,288 @@
<template>
<div style="position: relative;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="所属校区">
<el-select class="filter-item" v-model="formClass.formFilter.schoolId" :clearable="true" filterable
placeholder="所属校区" :loading="formClass.schoolId.impl.loading"
@visible-change="formClass.schoolId.impl.onVisibleChange"
@change="onSchoolIdValueChange">
<el-option v-for="item in formClass.schoolId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item label="班级级别">
<el-select class="filter-item" v-model="formClass.formFilter.classLevel" :clearable="true" filterable
placeholder="班级级别" :loading="formClass.classLevel.impl.loading"
@visible-change="formClass.classLevel.impl.onVisibleChange"
@change="onClassLevelValueChange">
<el-option v-for="item in formClass.classLevel.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item label="班级名称">
<el-input class="filter-item" v-model="formClass.formFilter.className"
:clearable="true" placeholder="班级名称" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormClass(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formClass:formClass:formCreateClass')"
@click="onFormCreateClassClick()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="formClass.Class.impl.dataList" size="mini" @sort-change="formClass.Class.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" :index="formClass.Class.impl.getTableIndex" />
<el-table-column label="班级名称" prop="className">
</el-table-column>
<el-table-column label="所属校区" prop="schoolIdDictMap.name">
</el-table-column>
<el-table-column label="班级级别" prop="classLevelDictMap.name">
</el-table-column>
<el-table-column label="已完成课时" prop="finishClassHour">
</el-table-column>
<el-table-column label="班级创建时间" prop="createTime">
<template slot-scope="scope">
<span>{{formatDateByStatsType(scope.row.createTime, 'day')}}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" min-width="150px">
<template slot-scope="scope">
<el-button @click="onFormEditClassClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formClass:formClass:formEditClass')">
编辑
</el-button>
<el-button @click="onFormClassStudentClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formClass:formClass:formClassStudent')">
学生
</el-button>
<el-button @click="onFormClassCourseClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formClass:formClass:formClassCourse')">
课程
</el-button>
<el-button @click="onDeleteClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formClass:formClass:delete')">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formClass.Class.impl.totalCount"
:current-page="formClass.Class.impl.currentPage"
:page-size="formClass.Class.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formClass.Class.impl.onCurrentPageChange"
@size-change="formClass.Class.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-row>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { StudentClassController, DictionaryController } from '@/api';
import formEditClass from '@/views/generated/formEditClass';
import formCreateClass from '@/views/generated/formCreateClass';
export default {
name: 'formClass',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formClass: {
formFilter: {
schoolId: undefined,
classLevel: undefined,
className: undefined
},
formFilterCopy: {
schoolId: undefined,
classLevel: undefined,
className: undefined
},
schoolId: {
impl: new DropdownWidget(this.loadSchoolIdDropdownList)
},
classLevel: {
impl: new DropdownWidget(this.loadClassLevelDropdownList)
},
Class: {
impl: new TableWidget(this.loadClassData, this.loadClassVerify, true, 'createTime', 1)
},
isInit: false
}
}
},
methods: {
/**
* 班级数据数据获取函数返回Primise
*/
loadClassData (params) {
if (params == null) params = {};
params = {
...params,
studentClassFilter: {
className: this.formClass.formFilterCopy.className,
schoolId: this.formClass.formFilterCopy.schoolId,
classLevel: this.formClass.formFilterCopy.classLevel
}
}
return new Promise((resolve, reject) => {
StudentClassController.list(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 班级数据数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadClassVerify () {
this.formClass.formFilterCopy.className = this.formClass.formFilter.className;
this.formClass.formFilterCopy.schoolId = this.formClass.formFilter.schoolId;
this.formClass.formFilterCopy.classLevel = this.formClass.formFilter.classLevel;
return true;
},
/**
* 所属校区下拉数据获取函数
*/
loadSchoolIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSchoolInfo(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所属校区选中值改变
*/
onSchoolIdValueChange (value) {
},
/**
* 班级级别下拉数据获取函数
*/
loadClassLevelDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictClassLevel(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 班级级别选中值改变
*/
onClassLevelValueChange (value) {
},
/**
* 更新班级管理
*/
refreshFormClass (reloadData = false) {
if (reloadData) {
this.formClass.Class.impl.refreshTable(true, 1);
} else {
this.formClass.Class.impl.refreshTable();
}
if (!this.formClass.isInit) {
// 初始化下拉数据
}
this.formClass.isInit = true;
},
/**
* 新建
*/
onFormCreateClassClick () {
let params = {};
this.$dialog.show('新建', formCreateClass, {
area: ['800px']
}, params).then(res => {
this.refreshFormClass();
}).catch(e => {});
},
/**
* 编辑
*/
onFormEditClassClick (row) {
let params = {
classId: row.classId
};
this.$dialog.show('编辑', formEditClass, {
area: ['800px']
}, params).then(res => {
this.formClass.Class.impl.refreshTable();
}).catch(e => {});
},
/**
* 学生
*/
onFormClassStudentClick (row) {
let params = {
classId: row.classId
};
params.closeVisible = 1;
this.$router.push({name: 'formClassStudent', query: params});
},
/**
* 课程
*/
onFormClassCourseClick (row) {
let params = {
classId: row.classId
};
params.closeVisible = 1;
this.$router.push({name: 'formClassCourse', query: params});
},
/**
* 删除
*/
onDeleteClick (row) {
let params = {
classId: row.classId
};
this.$confirm('是否删除此班级?').then(res => {
StudentClassController.delete(this, params).then(res => {
this.$message.success('删除成功');
this.formClass.Class.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
onResume () {
this.refreshFormClass();
},
initFormData () {
},
formInit () {
this.refreshFormClass();
}
},
created () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,185 @@
<template>
<div style="position: relative;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formClassCourse:formClassCourse:formSetClassCourse')"
@click="onFormSetClassCourseClick()">
设置班级课程
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="formClassCourse.Course.impl.dataList" size="mini" @sort-change="formClassCourse.Course.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" :index="formClassCourse.Course.impl.getTableIndex" />
<el-table-column label="课程名称" prop="courseName">
</el-table-column>
<el-table-column label="课程难度" prop="difficultyDictMap.name">
</el-table-column>
<el-table-column label="所属年级" prop="gradeIdDictMap.name">
</el-table-column>
<el-table-column label="所属学科" prop="subjectIdDictMap.name">
</el-table-column>
<el-table-column label="课时数量" prop="classHour">
</el-table-column>
<el-table-column label="课程图片" min-width="180px">
<template slot-scope="scope">
<el-image v-for="item in parseUploadData(scope.row.pictureUrl, {courseId: scope.row.courseId, fieldName: 'pictureUrl', asImage: true})"
:preview-src-list="getPictureList(scope.row.pictureUrl, {courseId: scope.row.courseId, fieldName: 'pictureUrl', asImage: true})"
class="table-cell-image" :key="item.url" :src="item.url" fit="fill">
<div slot="error" class="table-cell-image">
<i class="el-icon-picture-outline"></i>
</div>
</el-image>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right">
<template slot-scope="scope">
<el-button @click="onDeleteClassCourseClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formClassCourse:formClassCourse:deleteClassCourse')">
移除
</el-button>
</template>
</el-table-column>
</el-table>
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formClassCourse.Course.impl.totalCount"
:current-page="formClassCourse.Course.impl.currentPage"
:page-size="formClassCourse.Course.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formClassCourse.Course.impl.onCurrentPageChange"
@size-change="formClassCourse.Course.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-row>
<label v-if="closeVisible == '1'" class="page-close-box">
<el-button type="text" @click="onCancel(true)" icon="el-icon-close" />
</label>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { StudentClassController, DictionaryController } from '@/api';
export default {
name: 'formClassCourse',
props: {
classId: {
default: undefined
},
closeVisible: {
type: [Number, String],
default: 0
}
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin],
data () {
return {
formClassCourse: {
formFilter: {
},
formFilterCopy: {
},
Course: {
impl: new TableWidget(this.loadCourseData, this.loadCourseVerify, true)
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
this.removeCachePage(this.$options.name);
this.refreshParentCachedPage = isSuccess;
this.$router.go(-1);
},
/**
* 班级课程数据获取函数返回Primise
*/
loadCourseData (params) {
if (params == null) params = {};
params = {
...params,
classId: this.classId
}
return new Promise((resolve, reject) => {
StudentClassController.listClassCourse(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 班级课程数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadCourseVerify () {
return true;
},
/**
* 更新班级课程
*/
refreshFormClassCourse (reloadData = false) {
if (reloadData) {
this.formClassCourse.Course.impl.refreshTable(true, 1);
} else {
this.formClassCourse.Course.impl.refreshTable();
}
if (!this.formClassCourse.isInit) {
// 初始化下拉数据
}
this.formClassCourse.isInit = true;
},
/**
* 设置班级课程
*/
onFormSetClassCourseClick () {
let params = {
classId: this.classId
};
params.closeVisible = 1;
this.$router.push({name: 'formSetClassCourse', query: params});
},
/**
* 移除
*/
onDeleteClassCourseClick (row) {
let params = {
classId: this.classId,
courseId: row.courseId
};
this.$confirm('是否从班级中移除此课程?').then(res => {
StudentClassController.deleteClassCourse(this, params).then(res => {
this.$message.success('移除成功');
this.formClassCourse.Course.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
onResume () {
this.refreshFormClassCourse();
},
initFormData () {
},
formInit () {
this.refreshFormClassCourse();
}
},
created () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,179 @@
<template>
<div style="position: relative;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formClassStudent:formClassStudent:formSetClassStudent')"
@click="onFormSetClassStudentClick()">
设置班级学生
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="formClassStudent.Student.impl.dataList" size="mini" @sort-change="formClassStudent.Student.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" :index="formClassStudent.Student.impl.getTableIndex" />
<el-table-column label="姓名" prop="studentName">
</el-table-column>
<el-table-column label="手机号码" prop="loginMobile">
</el-table-column>
<el-table-column label="所属校区" prop="schoolIdDictMap.name">
</el-table-column>
<el-table-column label="年级" prop="gradeIdDictMap.name">
</el-table-column>
<el-table-column label="经验等级" prop="experienceLevelDictMap.name">
</el-table-column>
<el-table-column label="注册时间" prop="registerTime">
<template slot-scope="scope">
<span>{{formatDateByStatsType(scope.row.registerTime, 'day')}}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right">
<template slot-scope="scope">
<el-button @click="onDeleteClassStudentClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formClassStudent:formClassStudent:deleteClassStudent')">
移除
</el-button>
</template>
</el-table-column>
</el-table>
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formClassStudent.Student.impl.totalCount"
:current-page="formClassStudent.Student.impl.currentPage"
:page-size="formClassStudent.Student.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formClassStudent.Student.impl.onCurrentPageChange"
@size-change="formClassStudent.Student.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-row>
<label v-if="closeVisible == '1'" class="page-close-box">
<el-button type="text" @click="onCancel(true)" icon="el-icon-close" />
</label>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { StudentClassController, DictionaryController } from '@/api';
export default {
name: 'formClassStudent',
props: {
classId: {
default: undefined
},
closeVisible: {
type: [Number, String],
default: 0
}
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin, cachedPageChildMixin],
data () {
return {
formClassStudent: {
formFilter: {
},
formFilterCopy: {
},
Student: {
impl: new TableWidget(this.loadStudentData, this.loadStudentVerify, true)
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
this.removeCachePage(this.$options.name);
this.refreshParentCachedPage = isSuccess;
this.$router.go(-1);
},
/**
* 班级学生数据获取函数返回Primise
*/
loadStudentData (params) {
if (params == null) params = {};
params = {
...params,
classId: this.classId
}
return new Promise((resolve, reject) => {
StudentClassController.listClassStudent(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 班级学生数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadStudentVerify () {
return true;
},
/**
* 更新班级学生
*/
refreshFormClassStudent (reloadData = false) {
if (reloadData) {
this.formClassStudent.Student.impl.refreshTable(true, 1);
} else {
this.formClassStudent.Student.impl.refreshTable();
}
if (!this.formClassStudent.isInit) {
// 初始化下拉数据
}
this.formClassStudent.isInit = true;
},
/**
* 设置班级学生
*/
onFormSetClassStudentClick () {
let params = {
classId: this.classId
};
params.closeVisible = 1;
this.$router.push({name: 'formSetClassStudent', query: params});
},
/**
* 移除
*/
onDeleteClassStudentClick (row) {
let params = {
classId: this.classId,
studentId: row.studentId
};
this.$confirm('是否从班级中移除此学生?').then(res => {
StudentClassController.deleteClassStudent(this, params).then(res => {
this.$message.success('移除成功');
this.formClassStudent.Student.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
onResume () {
this.refreshFormClassStudent();
},
initFormData () {
},
formInit () {
this.refreshFormClassStudent();
}
},
created () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,306 @@
<template>
<div style="position: relative;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="所属年级">
<el-select class="filter-item" v-model="formCourse.formFilter.gradeId" :clearable="true" filterable
placeholder="所属年级" :loading="formCourse.gradeId.impl.loading"
@visible-change="formCourse.gradeId.impl.onVisibleChange"
@change="onGradeIdValueChange">
<el-option v-for="item in formCourse.gradeId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item label="所属学科">
<el-select class="filter-item" v-model="formCourse.formFilter.subjectId" :clearable="true" filterable
placeholder="所属学科" :loading="formCourse.subjectId.impl.loading"
@visible-change="formCourse.subjectId.impl.onVisibleChange"
@change="onSubjectIdValueChange">
<el-option v-for="item in formCourse.subjectId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item label="课程难度">
<el-select class="filter-item" v-model="formCourse.formFilter.difficulty" :clearable="true" filterable
placeholder="课程难度" :loading="formCourse.difficulty.impl.loading"
@visible-change="formCourse.difficulty.impl.onVisibleChange"
@change="onDifficultyValueChange">
<el-option v-for="item in formCourse.difficulty.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
<el-form-item label="课程名称">
<el-input class="filter-item" v-model="formCourse.formFilter.courseName"
:clearable="true" placeholder="课程名称" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormCourse(true)">查询</el-button>
<el-button slot="operator" type="primary" size="mini" :disabled="!checkPermCodeExist('formCourse:formCourse:formCreateCourse')"
@click="onFormCreateCourseClick()">
新建
</el-button>
</filter-box>
</el-form>
<el-row>
<el-col :span="24">
<el-table :data="formCourse.Course.impl.dataList" size="mini" @sort-change="formCourse.Course.impl.onSortChange"
header-cell-class-name="table-header-gray">
<el-table-column label="序号" header-align="center" align="center" type="index" width="55px" :index="formCourse.Course.impl.getTableIndex" />
<el-table-column label="课程名称" prop="courseName">
</el-table-column>
<el-table-column label="课程难度" prop="difficultyDictMap.name">
</el-table-column>
<el-table-column label="所属年级" prop="gradeIdDictMap.name">
</el-table-column>
<el-table-column label="所属学科" prop="subjectIdDictMap.name">
</el-table-column>
<el-table-column label="课时数量" prop="classHour">
</el-table-column>
<el-table-column label="课程价格" prop="price" sortable="custom">
</el-table-column>
<el-table-column label="课程图片" min-width="180px">
<template slot-scope="scope">
<el-image v-for="item in parseUploadData(scope.row.pictureUrl, {courseId: scope.row.courseId, fieldName: 'pictureUrl', asImage: true})"
:preview-src-list="getPictureList(scope.row.pictureUrl, {courseId: scope.row.courseId, fieldName: 'pictureUrl', asImage: true})"
class="table-cell-image" :key="item.url" :src="item.url" fit="fill">
<div slot="error" class="table-cell-image">
<i class="el-icon-picture-outline"></i>
</div>
</el-image>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="createTime">
<template slot-scope="scope">
<span>{{formatDateByStatsType(scope.row.createTime, 'day')}}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right">
<template slot-scope="scope">
<el-button @click="onFormEditCourseClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formCourse:formCourse:formEditCourse')">
编辑
</el-button>
<el-button @click="onDeleteClick(scope.row)" type="text" size="mini"
:disabled="!checkPermCodeExist('formCourse:formCourse:delete')">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-row type="flex" justify="end" style="margin-top: 10px;">
<el-pagination
:total="formCourse.Course.impl.totalCount"
:current-page="formCourse.Course.impl.currentPage"
:page-size="formCourse.Course.impl.pageSize"
:page-sizes="[10, 20, 50, 100]"
layout="total, prev, pager, next, sizes"
@current-change="formCourse.Course.impl.onCurrentPageChange"
@size-change="formCourse.Course.impl.onPageSizeChange">
</el-pagination>
</el-row>
</el-col>
</el-row>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { CourseController, DictionaryController } from '@/api';
import formCreateCourse from '@/views/generated/formCreateCourse';
import formEditCourse from '@/views/generated/formEditCourse';
export default {
name: 'formCourse',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formCourse: {
formFilter: {
gradeId: undefined,
subjectId: undefined,
difficulty: undefined,
courseName: undefined
},
formFilterCopy: {
gradeId: undefined,
subjectId: undefined,
difficulty: undefined,
courseName: undefined
},
gradeId: {
impl: new DropdownWidget(this.loadGradeIdDropdownList)
},
subjectId: {
impl: new DropdownWidget(this.loadSubjectIdDropdownList)
},
difficulty: {
impl: new DropdownWidget(this.loadDifficultyDropdownList)
},
Course: {
impl: new TableWidget(this.loadCourseData, this.loadCourseVerify, true, 'createTime', 1)
},
isInit: false
}
}
},
methods: {
/**
* 课程数据数据获取函数返回Primise
*/
loadCourseData (params) {
if (params == null) params = {};
params = {
...params,
courseFilter: {
courseName: this.formCourse.formFilterCopy.courseName,
difficulty: this.formCourse.formFilterCopy.difficulty,
gradeId: this.formCourse.formFilterCopy.gradeId,
subjectId: this.formCourse.formFilterCopy.subjectId
}
}
return new Promise((resolve, reject) => {
CourseController.list(this, params).then(res => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 课程数据数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadCourseVerify () {
this.formCourse.formFilterCopy.courseName = this.formCourse.formFilter.courseName;
this.formCourse.formFilterCopy.difficulty = this.formCourse.formFilter.difficulty;
this.formCourse.formFilterCopy.gradeId = this.formCourse.formFilter.gradeId;
this.formCourse.formFilterCopy.subjectId = this.formCourse.formFilter.subjectId;
return true;
},
/**
* 所属年级下拉数据获取函数
*/
loadGradeIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictGrade(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所属年级选中值改变
*/
onGradeIdValueChange (value) {
},
/**
* 所属学科下拉数据获取函数
*/
loadSubjectIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSubject(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所属学科选中值改变
*/
onSubjectIdValueChange (value) {
},
/**
* 课程难度下拉数据获取函数
*/
loadDifficultyDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictCourseDifficult(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 课程难度选中值改变
*/
onDifficultyValueChange (value) {
},
/**
* 更新课程管理
*/
refreshFormCourse (reloadData = false) {
if (reloadData) {
this.formCourse.Course.impl.refreshTable(true, 1);
} else {
this.formCourse.Course.impl.refreshTable();
}
if (!this.formCourse.isInit) {
// 初始化下拉数据
}
this.formCourse.isInit = true;
},
/**
* 新建
*/
onFormCreateCourseClick () {
let params = {};
this.$dialog.show('新建', formCreateCourse, {
area: ['800px']
}, params).then(res => {
this.refreshFormCourse();
}).catch(e => {});
},
/**
* 编辑
*/
onFormEditCourseClick (row) {
let params = {
courseId: row.courseId
};
this.$dialog.show('编辑', formEditCourse, {
area: ['800px']
}, params).then(res => {
this.formCourse.Course.impl.refreshTable();
}).catch(e => {});
},
/**
* 删除
*/
onDeleteClick (row) {
let params = {
courseId: row.courseId
};
this.$confirm('是否删除此课程?').then(res => {
CourseController.delete(this, params).then(res => {
this.$message.success('删除成功');
this.formCourse.Course.impl.refreshTable();
}).catch(e => {});
}).catch(e => {});
},
onResume () {
this.refreshFormCourse();
},
initFormData () {
},
formInit () {
this.refreshFormCourse();
}
},
created () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,312 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<filter-box :item-width="350">
<el-form-item label="统计日期">
<date-range class="filter-item" v-model="formCourseStats.formFilter.statsDate" :clearable="true" :allowTypes="['day']" align="left"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
format="yyyy-MM-dd" value-format="yyyy-MM-dd hh:mm:ss" />
</el-form-item>
<el-button slot="operator" type="primary" :plain="true" size="mini" @click="refreshFormCourseStats(true)">查询</el-button>
</filter-box>
</el-form>
<el-form ref="formCourseStats" :model="formData" class="full-width-input" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col class="table-box" :span="12">
<el-card class="base-card mb20" style="height: 350px" shadow="never" :body-style="{padding: '0px'}">
<div slot="header" class="base-card-header">
<span>课程统计年级</span>
<div class="base-card-operation">
</div>
</div>
<div class="card-chart" style="height: calc(350px - 50px);">
<ve-pie class="chart-border" height="100%"
:extend="formCourseStats.courseStatsByGradeId.chartOption"
:data="formCourseStats.courseStatsByGradeId.impl.chartData"
:settings="formCourseStats.courseStatsByGradeId.chartSetting"
:loading="formCourseStats.courseStatsByGradeId.impl.loading"
:data-empty="formCourseStats.courseStatsByGradeId.impl.dataEmpty"
:after-set-option-once="onCourseStatsByGradeIdOptionSet" />
</div>
</el-card>
</el-col>
<el-col class="table-box" :span="12">
<el-card class="base-card mb20" style="height: 350px" shadow="never" :body-style="{padding: '0px'}">
<div slot="header" class="base-card-header">
<span>课程统计学科</span>
<div class="base-card-operation">
</div>
</div>
<div class="card-chart" style="height: calc(350px - 50px);">
<ve-pie class="chart-border" height="100%"
:extend="formCourseStats.courseStatsBySubject.chartOption"
:data="formCourseStats.courseStatsBySubject.impl.chartData"
:settings="formCourseStats.courseStatsBySubject.chartSetting"
:loading="formCourseStats.courseStatsBySubject.impl.loading"
:data-empty="formCourseStats.courseStatsBySubject.impl.dataEmpty"
:after-set-option-once="onCourseStatsBySubjectOptionSet" />
</div>
</el-card>
</el-col>
<el-col class="table-box" :span="24">
<el-card class="base-card" style="height: 350px" shadow="never" :body-style="{padding: '0px'}">
<div slot="header" class="base-card-header">
<span>课程流水统计</span>
<div class="base-card-operation">
</div>
</div>
<div class="card-chart" style="height: calc(350px - 50px);">
<ve-histogram class="chart-border" height="100%"
:extend="formCourseStats.CourseTransStats.chartOption"
:data="formCourseStats.CourseTransStats.impl.chartData"
:settings="formCourseStats.CourseTransStats.chartSetting"
:loading="formCourseStats.CourseTransStats.impl.loading"
:data-empty="formCourseStats.CourseTransStats.impl.dataEmpty"
:after-set-option-once="onCourseTransStatsOptionSet"/>
</div>
</el-card>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { defaultLineChartOption, defaultBarChartOption, defaultPieChartOption } from '@/utils/chartOption.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin, cachePageMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { CourseTransStatsController, DictionaryController } from '@/api';
export default {
name: 'formCourseStats',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin, cachePageMixin],
data () {
return {
formData: {
CourseTransStats: {
statsId: undefined,
statsDate: undefined,
subjectId: undefined,
gradeId: undefined,
gradeName: undefined,
courseId: undefined,
courseName: undefined,
studentAttendCount: undefined,
studentFlowerAmount: undefined,
studentFlowerCount: undefined,
isDatasourceInit: false
}
},
formCourseStats: {
formFilter: {
statsDate: []
},
formFilterCopy: {
statsDate: []
},
courseStatsByGradeId: {
impl: new ChartWidget(this.loadCourseStatsByGradeIdData, this.loadCourseStatsByGradeIdVerify,
['gradeIdShowName', 'studentFlowerAmount']),
chartOption: defaultPieChartOption,
chartSetting: {
radius: 80,
dimension: 'gradeIdShowName',
metrics: 'studentFlowerAmount',
labelMap: {
'studentFlowerAmount': '献花数量'
}
}
},
courseStatsBySubject: {
impl: new ChartWidget(this.loadCourseStatsBySubjectData, this.loadCourseStatsBySubjectVerify,
['subjectIdShowName', 'studentFlowerAmount']),
chartOption: defaultPieChartOption,
chartSetting: {
radius: 80,
dimension: 'subjectIdShowName',
metrics: 'studentFlowerAmount',
labelMap: {
'studentFlowerAmount': '献花数量'
}
}
},
CourseTransStats: {
impl: new ChartWidget(this.loadCourseTransStatsData, this.loadCourseTransStatsVerify,
['statsDateShowName', 'studentAttendCount', 'studentFlowerAmount', 'studentFlowerCount']),
chartOption: defaultBarChartOption,
chartSetting: {
dimension: ['statsDateShowName'],
metrics: ['studentAttendCount', 'studentFlowerAmount', 'studentFlowerCount'],
labelMap: {
'studentAttendCount': '上课次数',
'studentFlowerAmount': '献花数量',
'studentFlowerCount': '献花次数'
}
}
},
isInit: false
}
}
},
methods: {
/**
* 课程统计年级数据获取函数返回Primise
*/
loadCourseStatsByGradeIdData () {
let params = {
groupParam: [
{
fieldName: 'gradeId'
}
],
courseTransStatsFilter: {
statsDateStart: Array.isArray(this.formCourseStats.formFilterCopy.statsDate) ? this.formCourseStats.formFilterCopy.statsDate[0] : undefined,
statsDateEnd: Array.isArray(this.formCourseStats.formFilterCopy.statsDate) ? this.formCourseStats.formFilterCopy.statsDate[1] : undefined
}
}
return new Promise((resolve, reject) => {
CourseTransStatsController.listWithGroup(this, params).then(res => {
resolve({
dataList: res.data.dataList.map((item) => {
return {...item, gradeIdShowName: item.gradeIdDictMap.name};
}),
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 课程统计年级数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadCourseStatsByGradeIdVerify () {
this.formCourseStats.formFilterCopy.statsDate = this.formCourseStats.formFilter.statsDate;
return true;
},
/**
* 获取课程统计年级的echarts实例
*/
onCourseStatsByGradeIdOptionSet (echarts) {
echarts.resize();
this.formCourseStats.courseStatsByGradeId.impl.chartObject = echarts;
},
/**
* 课程统计学科数据获取函数返回Primise
*/
loadCourseStatsBySubjectData () {
let params = {
groupParam: [
{
fieldName: 'subjectId'
}
],
courseTransStatsFilter: {
statsDateStart: Array.isArray(this.formCourseStats.formFilterCopy.statsDate) ? this.formCourseStats.formFilterCopy.statsDate[0] : undefined,
statsDateEnd: Array.isArray(this.formCourseStats.formFilterCopy.statsDate) ? this.formCourseStats.formFilterCopy.statsDate[1] : undefined
}
}
return new Promise((resolve, reject) => {
CourseTransStatsController.listWithGroup(this, params).then(res => {
resolve({
dataList: res.data.dataList.map((item) => {
return {...item, subjectIdShowName: item.subjectIdDictMap.name};
}),
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 课程统计学科数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadCourseStatsBySubjectVerify () {
this.formCourseStats.formFilterCopy.statsDate = this.formCourseStats.formFilter.statsDate;
return true;
},
/**
* 获取课程统计学科的echarts实例
*/
onCourseStatsBySubjectOptionSet (echarts) {
echarts.resize();
this.formCourseStats.courseStatsBySubject.impl.chartObject = echarts;
},
/**
* 课程流水统计数据获取函数返回Primise
*/
loadCourseTransStatsData () {
let params = {
groupParam: [
{
fieldName: 'statsDate'
}
],
courseTransStatsFilter: {
statsDateStart: Array.isArray(this.formCourseStats.formFilterCopy.statsDate) ? this.formCourseStats.formFilterCopy.statsDate[0] : undefined,
statsDateEnd: Array.isArray(this.formCourseStats.formFilterCopy.statsDate) ? this.formCourseStats.formFilterCopy.statsDate[1] : undefined
}
}
return new Promise((resolve, reject) => {
CourseTransStatsController.listWithGroup(this, params).then(res => {
resolve({
dataList: res.data.dataList.map((item) => {
return {...item, statsDateShowName: this.formatDateByStatsType(item.statsDate, this.formCourseStats.CourseTransStats.statsType)};
}),
totalCount: res.data.totalCount
});
}).catch(e => {
reject(e);
});
});
},
/**
* 课程流水统计数据获取检测函数返回true正常获取数据返回false停止获取数据
*/
loadCourseTransStatsVerify () {
this.formCourseStats.formFilterCopy.statsDate = this.formCourseStats.formFilter.statsDate;
return true;
},
/**
* 获取课程流水统计的echarts实例
*/
onCourseTransStatsOptionSet (echarts) {
echarts.resize();
this.formCourseStats.CourseTransStats.impl.chartObject = echarts;
},
/**
* 更新课程统计
*/
refreshFormCourseStats (reloadData = false) {
this.formCourseStats.courseStatsByGradeId.impl.refreshChart(reloadData);
this.formCourseStats.courseStatsBySubject.impl.refreshChart(reloadData);
this.formCourseStats.CourseTransStats.impl.refreshChart(reloadData);
if (!this.formCourseStats.isInit) {
// 初始化下拉数据
}
this.formCourseStats.isInit = true;
},
onResume () {
this.refreshFormCourseStats(true);
},
initFormData () {
},
formInit () {
this.refreshFormCourseStats();
}
},
computed: {
},
created () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,274 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formCreateClass" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="班级名称" prop="StudentClass.className">
<el-input class="input-item" v-model="formData.StudentClass.className"
:clearable="true" placeholder="班级名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="班级级别" prop="StudentClass.classLevel">
<el-select class="input-item" v-model="formData.StudentClass.classLevel" :clearable="true" filterable
placeholder="班级级别" :loading="formCreateClass.classLevel.impl.loading"
@visible-change="formCreateClass.classLevel.impl.onVisibleChange"
@change="onClassLevelValueChange">
<el-option v-for="item in formCreateClass.classLevel.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属校区" prop="StudentClass.schoolId">
<el-select class="input-item" v-model="formData.StudentClass.schoolId" :clearable="true" filterable
placeholder="所属校区" :loading="formCreateClass.schoolId.impl.loading"
@visible-change="formCreateClass.schoolId.impl.onVisibleChange"
@change="onSchoolIdValueChange">
<el-option v-for="item in formCreateClass.schoolId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="班长" prop="StudentClass.leaderId">
<el-select class="input-item" v-model="formData.StudentClass.leaderId" :clearable="true" filterable
placeholder="班长" :loading="formCreateClass.leaderId.impl.loading"
@visible-change="formCreateClass.leaderId.impl.onVisibleChange"
@change="onLeaderIdValueChange">
<el-option v-for="item in formCreateClass.leaderId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="已完成课时" prop="StudentClass.finishClassHour">
<el-input-number class="input-item" v-model="formData.StudentClass.finishClassHour"
:clearable="true" controls-position="right" placeholder="已完成课时" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini" :disabled="!checkPermCodeExist('formCreateClass:formCreateClass:add')"
@click="onAddClick()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { StudentClassController, DictionaryController } from '@/api';
export default {
name: 'formCreateClass',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin],
data () {
return {
formData: {
StudentClass: {
classId: undefined,
className: undefined,
schoolId: undefined,
leaderId: undefined,
finishClassHour: undefined,
classLevel: undefined,
createUserId: undefined,
createTime: undefined,
status: undefined,
course: {
courseId: undefined,
courseName: undefined,
price: undefined,
description: undefined,
difficulty: undefined,
gradeId: undefined,
subjectId: undefined,
classHour: undefined,
pictureUrl: undefined,
createUserId: undefined,
createTime: undefined,
updateTime: undefined
},
student: {
studentId: undefined,
loginMobile: undefined,
studentName: undefined,
provinceId: undefined,
cityId: undefined,
districtId: undefined,
gender: undefined,
birthday: undefined,
experienceLevel: undefined,
totalCoin: undefined,
leftCoin: undefined,
gradeId: undefined,
schoolId: undefined,
registerTime: undefined,
status: undefined
},
isDatasourceInit: false
}
},
rules: {
'StudentClass.className': [
{required: true, message: '请输入班级名称', trigger: 'blur'}
],
'StudentClass.classLevel': [
{required: true, message: '请输入班级级别', trigger: 'blur'}
],
'StudentClass.schoolId': [
{required: true, message: '请输入所属校区', trigger: 'blur'}
],
'StudentClass.leaderId': [
{required: true, message: '请输入班长', trigger: 'blur'}
],
'StudentClass.finishClassHour': [
{required: true, message: '请输入已完成课时', trigger: 'blur'},
{type: 'integer', message: '已完成课时只允许输入整数', trigger: 'blur', transform: (value) => Number(value)},
{type: 'number', min: 0, max: 9999, message: '已完成课时必须在0 - 9999之间', trigger: 'blur', transform: (value) => Number(value)}
]
},
formCreateClass: {
formFilter: {
},
formFilterCopy: {
},
classLevel: {
impl: new DropdownWidget(this.loadClassLevelDropdownList)
},
schoolId: {
impl: new DropdownWidget(this.loadSchoolIdDropdownList)
},
leaderId: {
impl: new DropdownWidget(this.loadLeaderIdDropdownList)
},
menuBlock: {
isInit: false
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
/**
* 班级级别下拉数据获取函数
*/
loadClassLevelDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictClassLevel(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 班级级别选中值改变
*/
onClassLevelValueChange (value) {
},
/**
* 所属校区下拉数据获取函数
*/
loadSchoolIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSchoolInfo(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所属校区选中值改变
*/
onSchoolIdValueChange (value) {
// 清除被过滤组件选中值并且将被过滤组件的状态设置为dirty
this.formData.StudentClass.leaderId = undefined;
this.formCreateClass.leaderId.impl.dirty = true;
this.onLeaderIdValueChange(this.formData.StudentClass.leaderId);
},
/**
* 班长下拉数据获取函数
*/
loadLeaderIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {
schoolId: this.formData.StudentClass.schoolId
};
DictionaryController.dictStudent(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 班长选中值改变
*/
onLeaderIdValueChange (value) {
},
/**
* 更新新建班级
*/
refreshFormCreateClass (reloadData = false) {
if (!this.formCreateClass.isInit) {
// 初始化下拉数据
}
this.formCreateClass.isInit = true;
},
/**
* 保存
*/
onAddClick () {
this.$refs.formCreateClass.validate((valid) => {
if (!valid) return;
let params = {
studentClass: {
className: this.formData.StudentClass.className,
schoolId: this.formData.StudentClass.schoolId,
leaderId: this.formData.StudentClass.leaderId,
finishClassHour: this.formData.StudentClass.finishClassHour,
classLevel: this.formData.StudentClass.classLevel
}
};
StudentClassController.add(this, params).then(res => {
this.$message.success('保存成功');
this.onCancel(true);
}).catch(e => {});
});
},
initFormData () {
},
formInit () {
this.refreshFormCreateClass();
}
},
computed: {
},
created () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,308 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formCreateCourse" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="课程名称" prop="Course.courseName">
<el-input class="input-item" v-model="formData.Course.courseName"
:clearable="true" placeholder="课程名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="课程价格" prop="Course.price">
<el-input-number class="input-item" v-model="formData.Course.price"
:clearable="true" controls-position="right" placeholder="课程价格" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="课程难度" prop="Course.difficulty">
<el-select class="input-item" v-model="formData.Course.difficulty" :clearable="true" filterable
placeholder="课程难度" :loading="formCreateCourse.difficulty.impl.loading"
@visible-change="formCreateCourse.difficulty.impl.onVisibleChange"
@change="onDifficultyValueChange">
<el-option v-for="item in formCreateCourse.difficulty.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属年级" prop="Course.gradeId">
<el-select class="input-item" v-model="formData.Course.gradeId" :clearable="true" filterable
placeholder="所属年级" :loading="formCreateCourse.gradeId.impl.loading"
@visible-change="formCreateCourse.gradeId.impl.onVisibleChange"
@change="onGradeIdValueChange">
<el-option v-for="item in formCreateCourse.gradeId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属学科" prop="Course.subjectId">
<el-select class="input-item" v-model="formData.Course.subjectId" :clearable="true" filterable
placeholder="所属学科" :loading="formCreateCourse.subjectId.impl.loading"
@visible-change="formCreateCourse.subjectId.impl.onVisibleChange"
@change="onSubjectIdValueChange">
<el-option v-for="item in formCreateCourse.subjectId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="课时数量" prop="Course.classHour">
<el-input-number class="input-item" v-model="formData.Course.classHour"
:clearable="true" controls-position="right" placeholder="课时数量" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="课程描述" prop="Course.description">
<el-input class="input-item" v-model="formData.Course.description"
:clearable="true" placeholder="课程描述" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="课程图片" prop="Course.pictureUrl">
<el-upload class="upload-image-item upload-image-multi" name="uploadFile" :headers="getUploadHeaders"
:action="getUploadActionUrl('/admin/CourseClass/course/upload')"
:data="{fieldName: 'pictureUrl', asImage: true}"
:on-success="onPictureUrlUploadSuccess"
:on-remove="onPictureUrlRemoveFile"
:before-upload="pictureFile"
:on-error="onUploadError" :on-exceed="onUploadLimit"
list-type="picture-card" :file-list="formCreateCourse.pictureUrl.impl.fileList" :limit="formCreateCourse.pictureUrl.impl.maxCount"
:show-file-list="true">
<i class="el-icon-plus upload-image-item"></i>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini" :disabled="!checkPermCodeExist('formCreateCourse:formCreateCourse:add')"
@click="onAddClick()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { CourseController, DictionaryController } from '@/api';
export default {
name: 'formCreateCourse',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin],
data () {
return {
formData: {
Course: {
courseId: undefined,
courseName: undefined,
price: undefined,
description: undefined,
difficulty: undefined,
gradeId: undefined,
subjectId: undefined,
classHour: undefined,
pictureUrl: undefined,
createUserId: undefined,
createTime: undefined,
updateTime: undefined,
isDatasourceInit: false
}
},
rules: {
'Course.courseName': [
{required: true, message: '请输入课程名称', trigger: 'blur'}
],
'Course.price': [
{required: true, message: '请输入课程价格', trigger: 'blur'},
{type: 'number', message: '课程价格只允许输入数字', trigger: 'blur', transform: (value) => Number(value)},
{type: 'number', min: 0, message: '课程价格必须大于0', trigger: 'blur', transform: (value) => Number(value)}
],
'Course.difficulty': [
{required: true, message: '请输入课程难度', trigger: 'blur'}
],
'Course.gradeId': [
{required: true, message: '请输入所属年级', trigger: 'blur'}
],
'Course.subjectId': [
{required: true, message: '请输入所属学科', trigger: 'blur'}
],
'Course.classHour': [
{required: true, message: '请输入课时数量', trigger: 'blur'},
{type: 'integer', message: '课时数量只允许输入整数', trigger: 'blur', transform: (value) => Number(value)},
{type: 'number', min: 1, message: '课时数量必须大于1', trigger: 'blur', transform: (value) => Number(value)}
],
'Course.pictureUrl': [
{required: true, message: '请输入课程图片', trigger: 'blur'}
]
},
formCreateCourse: {
formFilter: {
},
formFilterCopy: {
},
difficulty: {
impl: new DropdownWidget(this.loadDifficultyDropdownList)
},
gradeId: {
impl: new DropdownWidget(this.loadGradeIdDropdownList)
},
subjectId: {
impl: new DropdownWidget(this.loadSubjectIdDropdownList)
},
pictureUrl: {
impl: new UploadWidget(4)
},
menuBlock: {
isInit: false
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
/**
* 课程难度下拉数据获取函数
*/
loadDifficultyDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictCourseDifficult(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 课程难度选中值改变
*/
onDifficultyValueChange (value) {
},
/**
* 所属年级下拉数据获取函数
*/
loadGradeIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictGrade(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所属年级选中值改变
*/
onGradeIdValueChange (value) {
},
/**
* 所属学科下拉数据获取函数
*/
loadSubjectIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictSubject(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所属学科选中值改变
*/
onSubjectIdValueChange (value) {
},
/**
* 更新新建课程
*/
refreshFormCreateCourse (reloadData = false) {
if (!this.formCreateCourse.isInit) {
// 初始化下拉数据
}
this.formCreateCourse.isInit = true;
},
/**
* 保存
*/
onAddClick () {
this.$refs.formCreateCourse.validate((valid) => {
if (!valid) return;
let params = {
course: {
courseName: this.formData.Course.courseName,
price: this.formData.Course.price,
description: this.formData.Course.description,
difficulty: this.formData.Course.difficulty,
gradeId: this.formData.Course.gradeId,
subjectId: this.formData.Course.subjectId,
classHour: this.formData.Course.classHour,
pictureUrl: this.formData.Course.pictureUrl
}
};
CourseController.add(this, params).then(res => {
this.$message.success('保存成功');
this.onCancel(true);
}).catch(e => {});
});
},
initFormData () {
},
/**
* 课程图片上传成功
*/
onPictureUrlUploadSuccess (response, file, fileList) {
if (response.success) {
file.downloadUri = response.data.downloadUri;
file.filename = response.data.filename;
file.url = URL.createObjectURL(file.raw);
this.formCreateCourse.pictureUrl.impl.onFileChange(file, fileList);
this.formData.Course.pictureUrl = this.fileListToJson(this.formCreateCourse.pictureUrl.impl.fileList);
} else {
this.$message.error(response.message);
}
},
/**
* 移除课程图片
*/
onPictureUrlRemoveFile (file, fileList) {
this.formCreateCourse.pictureUrl.impl.onFileChange(file, fileList);
this.formData.Course.pictureUrl = this.fileListToJson(this.formCreateCourse.pictureUrl.impl.fileList);
},
onUploadError (e, file, fileList) {
this.$message.error('文件上传失败');
},
onUploadLimit (files, fileList) {
this.$message.error('已经超出最大上传个数限制');
},
formInit () {
this.refreshFormCreateCourse();
}
},
computed: {
},
created () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,195 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formCreateClass" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="学校名称" prop="SchoolInfo.schoolName">
<el-input class="input-item" v-model="formData.SchoolInfo.schoolName"
:clearable="true" placeholder="学校名称" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="所在省份" prop="SchoolInfo.provinceId">
<el-select class="input-item" v-model="formData.SchoolInfo.provinceId" :clearable="true" filterable
placeholder="所在省份" :loading="formCreateClass.provinceId.impl.loading"
@visible-change="formCreateClass.provinceId.impl.onVisibleChange"
@change="onProvinceIdValueChange">
<el-option v-for="item in formCreateClass.provinceId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="所在城市" prop="SchoolInfo.cityId">
<el-select class="input-item" v-model="formData.SchoolInfo.cityId" :clearable="true" filterable
placeholder="所在城市" :loading="formCreateClass.cityId.impl.loading"
@visible-change="formCreateClass.cityId.impl.onVisibleChange"
@change="onCityIdValueChange">
<el-option v-for="item in formCreateClass.cityId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini" :disabled="!checkPermCodeExist('formCreateSchool:formCreateClass:add')"
@click="onAddClick()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { SchoolInfoController, DictionaryController } from '@/api';
export default {
name: 'formCreateSchool',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin],
data () {
return {
formData: {
SchoolInfo: {
schoolId: undefined,
schoolName: undefined,
provinceId: undefined,
cityId: undefined,
isDatasourceInit: false
}
},
rules: {
'SchoolInfo.schoolName': [
{required: true, message: '请输入学校名称', trigger: 'blur'}
],
'SchoolInfo.provinceId': [
{required: true, message: '请输入所在省份', trigger: 'blur'}
],
'SchoolInfo.cityId': [
{required: true, message: '请输入所在城市', trigger: 'blur'}
]
},
formCreateClass: {
formFilter: {
},
formFilterCopy: {
},
provinceId: {
impl: new DropdownWidget(this.loadProvinceIdDropdownList)
},
cityId: {
impl: new DropdownWidget(this.loadCityIdDropdownList)
},
menuBlock: {
isInit: false
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
/**
* 所在省份下拉数据获取函数
*/
loadProvinceIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictAreaCodeByParentId(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所在省份选中值改变
*/
onProvinceIdValueChange (value) {
// 清除被过滤组件选中值并且将被过滤组件的状态设置为dirty
this.formData.SchoolInfo.cityId = undefined;
this.formCreateClass.cityId.impl.dirty = true;
this.onCityIdValueChange(this.formData.SchoolInfo.cityId);
},
/**
* 所在城市下拉数据获取函数
*/
loadCityIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {
parentId: this.formData.SchoolInfo.provinceId
};
if (params.parentId == null || params.parentId === '') {
resolve([]);
return;
}
DictionaryController.dictAreaCodeByParentId(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所在城市选中值改变
*/
onCityIdValueChange (value) {
},
/**
* 更新新建校区
*/
refreshFormCreateClass (reloadData = false) {
if (!this.formCreateClass.isInit) {
// 初始化下拉数据
}
this.formCreateClass.isInit = true;
},
/**
* 保存
*/
onAddClick () {
this.$refs.formCreateClass.validate((valid) => {
if (!valid) return;
let params = {
schoolInfo: {
schoolName: this.formData.SchoolInfo.schoolName,
provinceId: this.formData.SchoolInfo.provinceId,
cityId: this.formData.SchoolInfo.cityId
}
};
SchoolInfoController.add(this, params).then(res => {
this.$message.success('保存成功');
this.onCancel(true);
}).catch(e => {});
});
},
initFormData () {
},
formInit () {
this.refreshFormCreateClass();
}
},
computed: {
},
created () {
this.formInit();
}
}
</script>

View File

@@ -0,0 +1,429 @@
<template>
<div class="form-single-fragment" style="position: relative;">
<el-form ref="formCreateStudent" :model="formData" class="full-width-input" :rules="rules" style="width: 100%;"
label-width="100px" size="mini" label-position="right" @submit.native.prevent>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="姓名" prop="Student.studentName">
<el-input class="input-item" v-model="formData.Student.studentName"
:clearable="true" placeholder="姓名" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="性别" prop="Student.gender">
<el-select class="input-item" v-model="formData.Student.gender" :clearable="true" filterable
placeholder="性别" :loading="formCreateStudent.gender.impl.loading"
@visible-change="formCreateStudent.gender.impl.onVisibleChange"
@change="onGenderValueChange">
<el-option v-for="item in formCreateStudent.gender.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出生日期" prop="Student.birthday">
<el-date-picker class="input-item" v-model="formData.Student.birthday" :clearable="true"
placeholder="出生日期" type="date" align="left"
format="yyyy-MM-dd" value-format="yyyy-MM-dd hh:mm:ss" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="手机号码" prop="Student.loginMobile">
<el-input class="input-item" v-model="formData.Student.loginMobile"
:clearable="true" placeholder="手机号码" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所在年级" prop="Student.gradeId">
<el-select class="input-item" v-model="formData.Student.gradeId" :clearable="true" filterable
placeholder="所在年级" :loading="formCreateStudent.gradeId.impl.loading"
@visible-change="formCreateStudent.gradeId.impl.onVisibleChange"
@change="onGradeIdValueChange">
<el-option v-for="item in formCreateStudent.gradeId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="经验等级" prop="Student.experienceLevel">
<el-select class="input-item" v-model="formData.Student.experienceLevel" :clearable="true" filterable
placeholder="经验等级" :loading="formCreateStudent.experienceLevel.impl.loading"
@visible-change="formCreateStudent.experienceLevel.impl.onVisibleChange"
@change="onExperienceLevelValueChange">
<el-option v-for="item in formCreateStudent.experienceLevel.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所在省份" prop="Student.provinceId">
<el-select class="input-item" v-model="formData.Student.provinceId" :clearable="true" filterable
placeholder="所在省份" :loading="formCreateStudent.provinceId.impl.loading"
@visible-change="formCreateStudent.provinceId.impl.onVisibleChange"
@change="onProvinceIdValueChange">
<el-option v-for="item in formCreateStudent.provinceId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所在城市" prop="Student.cityId">
<el-select class="input-item" v-model="formData.Student.cityId" :clearable="true" filterable
placeholder="所在城市" :loading="formCreateStudent.cityId.impl.loading"
@visible-change="formCreateStudent.cityId.impl.onVisibleChange"
@change="onCityIdValueChange">
<el-option v-for="item in formCreateStudent.cityId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所在区县" prop="Student.districtId">
<el-select class="input-item" v-model="formData.Student.districtId" :clearable="true" filterable
placeholder="所在区县" :loading="formCreateStudent.districtId.impl.loading"
@visible-change="formCreateStudent.districtId.impl.onVisibleChange"
@change="onDistrictIdValueChange">
<el-option v-for="item in formCreateStudent.districtId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属校区" prop="Student.schoolId">
<el-select class="input-item" v-model="formData.Student.schoolId" :clearable="true" filterable
placeholder="所属校区" :loading="formCreateStudent.schoolId.impl.loading"
@visible-change="formCreateStudent.schoolId.impl.onVisibleChange"
@change="onSchoolIdValueChange">
<el-option v-for="item in formCreateStudent.schoolId.impl.dropdownList" :key="item.id" :value="item.id" :label="item.name" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-row class="no-scroll flex-box" type="flex" justify="end">
<el-button type="primary" size="mini" :plain="true"
@click="onCancel(false)">
取消
</el-button>
<el-button type="primary" size="mini" :disabled="!checkPermCodeExist('formCreateStudent:formCreateStudent:update')"
@click="onUpdateClick()">
保存
</el-button>
</el-row>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
/* eslint-disable-next-line */
import rules from '@/utils/validate.js';
/* eslint-disable-next-line */
import { DropdownWidget, TableWidget, UploadWidget, ChartWidget } from '@/utils/widget.js';
/* eslint-disable-next-line */
import { uploadMixin, statsDateRangeMixin } from '@/core/mixins';
/* eslint-disable-next-line */
import { StudentController, DictionaryController } from '@/api';
export default {
name: 'formCreateStudent',
props: {
},
mixins: [uploadMixin, statsDateRangeMixin],
data () {
return {
formData: {
Student: {
studentId: undefined,
loginMobile: undefined,
studentName: undefined,
provinceId: undefined,
cityId: undefined,
districtId: undefined,
gender: undefined,
birthday: undefined,
experienceLevel: undefined,
totalCoin: 0,
leftCoin: 0,
gradeId: undefined,
schoolId: undefined,
registerTime: undefined,
status: undefined,
isDatasourceInit: false
}
},
rules: {
'Student.studentName': [
{required: true, message: '请输入姓名', trigger: 'blur'}
],
'Student.gender': [
{required: true, message: '请输入性别', trigger: 'blur'}
],
'Student.birthday': [
{required: true, message: '请输入出生日期', trigger: 'blur'}
],
'Student.loginMobile': [
{required: true, message: '请输入手机号码', trigger: 'blur'},
{type: 'string', pattern: rules.pattern.mobie, message: '请输入正确的手机号码', trigger: 'blur'}
],
'Student.gradeId': [
{required: true, message: '请输入所在年级', trigger: 'blur'}
],
'Student.experienceLevel': [
{required: true, message: '请输入经验等级', trigger: 'blur'}
],
'Student.provinceId': [
{required: true, message: '请输入所在省份', trigger: 'blur'}
],
'Student.cityId': [
{required: true, message: '请输入所在城市', trigger: 'blur'}
],
'Student.districtId': [
{required: true, message: '请输入所在区县', trigger: 'blur'}
],
'Student.schoolId': [
{required: true, message: '请输入所属校区', trigger: 'blur'}
]
},
formCreateStudent: {
formFilter: {
},
formFilterCopy: {
},
gender: {
impl: new DropdownWidget(this.loadGenderDropdownList)
},
gradeId: {
impl: new DropdownWidget(this.loadGradeIdDropdownList)
},
experienceLevel: {
impl: new DropdownWidget(this.loadExperienceLevelDropdownList)
},
provinceId: {
impl: new DropdownWidget(this.loadProvinceIdDropdownList)
},
cityId: {
impl: new DropdownWidget(this.loadCityIdDropdownList)
},
districtId: {
impl: new DropdownWidget(this.loadDistrictIdDropdownList)
},
schoolId: {
impl: new DropdownWidget(this.loadSchoolIdDropdownList)
},
menuBlock: {
isInit: false
},
isInit: false
}
}
},
methods: {
onCancel (isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess);
}
},
/**
* 性别下拉数据获取函数
*/
loadGenderDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictGender(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 性别选中值改变
*/
onGenderValueChange (value) {
},
/**
* 所在年级下拉数据获取函数
*/
loadGradeIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictGrade(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所在年级选中值改变
*/
onGradeIdValueChange (value) {
},
/**
* 经验等级下拉数据获取函数
*/
loadExperienceLevelDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictExpLevel(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 经验等级选中值改变
*/
onExperienceLevelValueChange (value) {
},
/**
* 所在省份下拉数据获取函数
*/
loadProvinceIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {};
DictionaryController.dictAreaCodeByParentId(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所在省份选中值改变
*/
onProvinceIdValueChange (value) {
// 清除被过滤组件选中值并且将被过滤组件的状态设置为dirty
this.formData.Student.cityId = undefined;
this.formCreateStudent.cityId.impl.dirty = true;
this.onCityIdValueChange(this.formData.Student.cityId);
// 清除被过滤组件选中值并且将被过滤组件的状态设置为dirty
this.formData.Student.schoolId = undefined;
this.formCreateStudent.schoolId.impl.dirty = true;
this.onSchoolIdValueChange(this.formData.Student.schoolId);
},
/**
* 所在城市下拉数据获取函数
*/
loadCityIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {
parentId: this.formData.Student.provinceId
};
if (params.parentId == null || params.parentId === '') {
resolve([]);
return;
}
DictionaryController.dictAreaCodeByParentId(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所在城市选中值改变
*/
onCityIdValueChange (value) {
// 清除被过滤组件选中值并且将被过滤组件的状态设置为dirty
this.formData.Student.districtId = undefined;
this.formCreateStudent.districtId.impl.dirty = true;
this.onDistrictIdValueChange(this.formData.Student.districtId);
// 清除被过滤组件选中值并且将被过滤组件的状态设置为dirty
this.formData.Student.schoolId = undefined;
this.formCreateStudent.schoolId.impl.dirty = true;
this.onSchoolIdValueChange(this.formData.Student.schoolId);
},
/**
* 所在区县下拉数据获取函数
*/
loadDistrictIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {
parentId: this.formData.Student.cityId
};
if (params.parentId == null || params.parentId === '') {
resolve([]);
return;
}
DictionaryController.dictAreaCodeByParentId(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所在区县选中值改变
*/
onDistrictIdValueChange (value) {
},
/**
* 所属校区下拉数据获取函数
*/
loadSchoolIdDropdownList () {
return new Promise((resolve, reject) => {
let params = {
provinceId: this.formData.Student.provinceId,
cityId: this.formData.Student.cityId
};
DictionaryController.dictSchoolInfo(this, params).then(res => {
resolve(res.getList());
}).catch(e => {
reject(e);
});
});
},
/**
* 所属校区选中值改变
*/
onSchoolIdValueChange (value) {
},
/**
* 更新新建学生
*/
refreshFormCreateStudent (reloadData = false) {
if (!this.formCreateStudent.isInit) {
// 初始化下拉数据
}
this.formCreateStudent.isInit = true;
},
/**
* 保存
*/
onUpdateClick () {
this.$refs.formCreateStudent.validate((valid) => {
if (!valid) return;
let params = {
student: {
loginMobile: this.formData.Student.loginMobile,
studentName: this.formData.Student.studentName,
provinceId: this.formData.Student.provinceId,
cityId: this.formData.Student.cityId,
districtId: this.formData.Student.districtId,
gender: this.formData.Student.gender,
birthday: this.formData.Student.birthday,
experienceLevel: this.formData.Student.experienceLevel,
totalCoin: this.formData.Student.totalCoin,
leftCoin: this.formData.Student.leftCoin,
gradeId: this.formData.Student.gradeId,
schoolId: this.formData.Student.schoolId,
status: this.StudentStatus.NORMAL
}
};
StudentController.add(this, params).then(res => {
this.$message.success('保存成功');
this.onCancel(true);
}).catch(e => {});
});
},
initFormData () {
},
formInit () {
this.refreshFormCreateStudent();
}
},
computed: {
},
created () {
this.formInit();
}
}
</script>

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