ソースを参照

管控第一次提交

gzb
wangzhonglu 9ヶ月前
コミット
0e2a4f1d9d
72個のファイルの変更50214行の追加0行の削除
  1. 20
    0
      .eslintrc.js
  2. 23
    0
      .gitignore
  3. 4
    0
      .prettierrc
  4. 19
    0
      README.md
  5. 3
    0
      babel.config.js
  6. 20
    0
      jsconfig.json
  7. 8921
    0
      package-lock.json
  8. 31
    0
      package.json
  9. 34
    0
      public/config.js
  10. バイナリ
      public/favicon.ico
  11. 539
    0
      public/iconfont/demo.css
  12. 9687
    0
      public/iconfont/demo_index.html
  13. 1667
    0
      public/iconfont/iconfont.css
  14. 1
    0
      public/iconfont/iconfont.js
  15. 2900
    0
      public/iconfont/iconfont.json
  16. バイナリ
      public/iconfont/iconfont.ttf
  17. バイナリ
      public/iconfont/iconfont.woff
  18. バイナリ
      public/iconfont/iconfont.woff2
  19. 39
    0
      public/index.html
  20. 3
    0
      public/librarys/axios@0.21.1/axios.min.js
  21. 4
    0
      public/librarys/babel-polyfill@6.26.0/polyfill.min.js
  22. 890
    0
      public/librarys/clipboard@2.0.11/clipboard.js
  23. 7
    0
      public/librarys/clipboard@2.0.11/clipboard.min.js
  24. 6059
    0
      public/librarys/crypto-js.js
  25. 1688
    0
      public/librarys/echarts-liquidfill@3.1.0/echarts-liquidfill.js
  26. 2
    0
      public/librarys/echarts-liquidfill@3.1.0/echarts-liquidfill.min.js
  27. 1786
    0
      public/librarys/echarts-wordcloud@2.1.0/echarts-wordcloud.js
  28. 3
    0
      public/librarys/echarts-wordcloud@2.1.0/echarts-wordcloud.min.js
  29. 45
    0
      public/librarys/echarts@5.4.3/echarts.min.js
  30. 34
    0
      public/librarys/secret.js
  31. 870
    0
      public/librarys/view-design@4.7.0/fonts/ionicons.svg
  32. バイナリ
      public/librarys/view-design@4.7.0/fonts/ionicons.ttf
  33. バイナリ
      public/librarys/view-design@4.7.0/fonts/ionicons.woff
  34. バイナリ
      public/librarys/view-design@4.7.0/fonts/ionicons.woff2
  35. 1
    0
      public/librarys/view-design@4.7.0/iview.css
  36. 27
    0
      public/librarys/view-design@4.7.0/iview.min.js
  37. 6
    0
      public/librarys/vue-router@3.2.0/vue-router.min.js
  38. 11965
    0
      public/librarys/vue@2.6.11/vue.js
  39. 6
    0
      public/librarys/vue@2.6.11/vue.min.js
  40. 6
    0
      public/librarys/vuex@3.2.0/vuex.min.js
  41. 78
    0
      src/App.vue
  42. 279
    0
      src/api/system.js
  43. 333
    0
      src/assets/less/common.less
  44. 71
    0
      src/assets/less/customModal.less
  45. 174
    0
      src/assets/less/reset.less
  46. 70
    0
      src/assets/less/rootPage.less
  47. 467
    0
      src/components/ImgPreview/ImgPreview.vue
  48. 69
    0
      src/components/ImgPreview/index.js
  49. 29
    0
      src/main.js
  50. 113
    0
      src/router/index.js
  51. 9
    0
      src/store/index.js
  52. 164
    0
      src/utils/httpRequest.js
  53. 722
    0
      src/utils/index.js
  54. 30
    0
      src/utils/resetMessage.js
  55. 15
    0
      src/views/layout.vue
  56. 14
    0
      src/views/login/login.vue
  57. 14
    0
      src/views/personal/personal.vue
  58. 14
    0
      src/views/platform/admin/index.vue
  59. 14
    0
      src/views/platform/home/index.vue
  60. 14
    0
      src/views/platform/log/index.vue
  61. 14
    0
      src/views/platform/networkManage/index.vue
  62. 14
    0
      src/views/platform/notice/index.vue
  63. 14
    0
      src/views/platform/regionManage/index.vue
  64. 14
    0
      src/views/region/admin/index.vue
  65. 14
    0
      src/views/region/home/index.vue
  66. 14
    0
      src/views/region/regionManage/index.vue
  67. 14
    0
      src/views/region/schoolManage/index.vue
  68. 14
    0
      src/views/school/admin/index.vue
  69. 14
    0
      src/views/school/home/index.vue
  70. 14
    0
      src/views/school/index.vue
  71. 14
    0
      src/views/school/regionManage/index.vue
  72. 57
    0
      vue.config.js

+ 20
- 0
.eslintrc.js ファイルの表示

@@ -0,0 +1,20 @@
1
+module.exports = {
2
+  root: true,
3
+  env: {
4
+    node: true
5
+  },
6
+  extends: [
7
+    "plugin:vue/essential",
8
+    "eslint:recommended",
9
+    "plugin:prettier/recommended"
10
+  ],
11
+  parserOptions: {
12
+    parser: "@babel/eslint-parser"
13
+  },
14
+  rules: {
15
+    "vue/multi-word-component-names": "off",
16
+    // 不使用script-setup
17
+    "vue/script-setup-uses-vars": "off"
18
+  },
19
+  ignorePatterns: ["public/*"] // 忽略 public 文件夹下的所有文件
20
+};

+ 23
- 0
.gitignore ファイルの表示

@@ -0,0 +1,23 @@
1
+.DS_Store
2
+node_modules
3
+/dist
4
+
5
+# local env files
6
+.env.local
7
+.env.*.local
8
+
9
+# Log files
10
+npm-debug.log*
11
+yarn-debug.log*
12
+yarn-error.log*
13
+pnpm-debug.log*
14
+
15
+# Editor directories and files
16
+.idea
17
+.vscode
18
+*.suo
19
+*.ntvs*
20
+*.njsproj
21
+*.sln
22
+*.sw?
23
+*.zip

+ 4
- 0
.prettierrc ファイルの表示

@@ -0,0 +1,4 @@
1
+{
2
+  "endOfLine": "auto",
3
+  "trailingComma": "none"
4
+}

+ 19
- 0
README.md ファイルの表示

@@ -0,0 +1,19 @@
1
+## 下载依赖
2
+```
3
+npm install
4
+```
5
+
6
+### 本地运行
7
+```
8
+npm run serve
9
+```
10
+
11
+### 打包
12
+```
13
+npm run build
14
+```
15
+
16
+### 打包分析
17
+```
18
+npm run report
19
+```

+ 3
- 0
babel.config.js ファイルの表示

@@ -0,0 +1,3 @@
1
+module.exports = {
2
+  presets: ["@vue/cli-plugin-babel/preset"]
3
+};

+ 20
- 0
jsconfig.json ファイルの表示

@@ -0,0 +1,20 @@
1
+{
2
+  "compilerOptions": {
3
+    "target": "es5",
4
+    "module": "esnext",
5
+    "baseUrl": "./",
6
+    "moduleResolution": "node",
7
+    "paths": {
8
+      "@/*": [
9
+        "src/*"
10
+      ]
11
+    },
12
+    "lib": [
13
+      "esnext",
14
+      "dom",
15
+      "dom.iterable",
16
+      "scripthost"
17
+    ]
18
+  },
19
+  "exclude": ["node_modules", "dist"]
20
+}

+ 8921
- 0
package-lock.json
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 31
- 0
package.json ファイルの表示

@@ -0,0 +1,31 @@
1
+{
2
+  "name": "xhkj_bi",
3
+  "version": "1.0.0",
4
+  "private": true,
5
+  "scripts": {
6
+    "serve": "vue-cli-service serve",
7
+    "build": "vue-cli-service build",
8
+    "report": "vue-cli-service build --report"
9
+  },
10
+  "dependencies": {
11
+    "vue-simple-uploader": "^0.7.6"
12
+  },
13
+  "devDependencies": {
14
+    "@babel/core": "~7.12.16",
15
+    "@babel/eslint-parser": "~7.12.16",
16
+    "@vue/cli-plugin-babel": "~5.0.0",
17
+    "@vue/cli-plugin-eslint": "~5.0.0",
18
+    "@vue/cli-plugin-router": "~5.0.0",
19
+    "@vue/cli-plugin-vuex": "~5.0.0",
20
+    "@vue/cli-service": "~5.0.0",
21
+    "eslint": "~7.32.0",
22
+    "eslint-config-prettier": "~8.3.0",
23
+    "eslint-plugin-prettier": "~4.0.0",
24
+    "eslint-plugin-vue": "~8.0.3",
25
+    "less": "~4.0.0",
26
+    "less-loader": "~8.0.0",
27
+    "prettier": "~2.4.1",
28
+    "quill-image-extend-module": "^1.1.2",
29
+    "vue-template-compiler": "~2.6.11"
30
+  }
31
+}

+ 34
- 0
public/config.js ファイルの表示

@@ -0,0 +1,34 @@
1
+window.isTest = true; //测试环境true 正式环境false
2
+window._config = window.isTest
3
+  ? {
4
+      // 测试环境
5
+      webUrl: "https://xhbitest.xhkjedu.com/",
6
+      baseUrl: "https://xhbiapitest.xhkjedu.com/",
7
+      baseImageUrl: "https://xhbifiletest.xhkjedu.com/",
8
+      showImageUrl: "https://xhbistatictest.xhkjedu.com/",
9
+      useMicroservice: true, // 是否使用微服务
10
+      axiosApiTimeout: 60, // 接口超时时间 单位秒
11
+      axiosFileTimeout: 120, // 上传文件超时时间 单位秒
12
+      // 开发者
13
+      developer: "河南星火燎原软件科技有限公司",
14
+      // 联系我们
15
+      contactUs: "https://www.xhkjedu.com/",
16
+      versionname: "测试 v1.0.0",
17
+      secret: false
18
+    }
19
+  : {
20
+      // 正式环境
21
+      webUrl: "https://xhbi.xhkjedu.com/",
22
+      baseUrl: "https://xhbiapi.xhkjedu.com/",
23
+      baseImageUrl: "https://xhbifile.xhkjedu.com/",
24
+      showImageUrl: "https://xhbistatic.xhkjedu.com/",
25
+      useMicroservice: true, // 是否使用微服务
26
+      axiosApiTimeout: 20, // 接口超时时间 单位秒
27
+      axiosFileTimeout: 30, // 上传文件超时时间 单位秒
28
+      // 开发者
29
+      developer: "河南星火燎原软件科技有限公司",
30
+      // 联系我们
31
+      contactUs: "https://www.xhkjedu.com/",
32
+      versionname: "正式 v1.0.0",
33
+      secret: true
34
+    };

バイナリ
public/favicon.ico ファイルの表示


+ 539
- 0
public/iconfont/demo.css ファイルの表示

@@ -0,0 +1,539 @@
1
+/* Logo 字体 */
2
+@font-face {
3
+  font-family: "iconfont logo";
4
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
5
+  src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
6
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
7
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
8
+    url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
9
+}
10
+
11
+.logo {
12
+  font-family: "iconfont logo";
13
+  font-size: 160px;
14
+  font-style: normal;
15
+  -webkit-font-smoothing: antialiased;
16
+  -moz-osx-font-smoothing: grayscale;
17
+}
18
+
19
+/* tabs */
20
+.nav-tabs {
21
+  position: relative;
22
+}
23
+
24
+.nav-tabs .nav-more {
25
+  position: absolute;
26
+  right: 0;
27
+  bottom: 0;
28
+  height: 42px;
29
+  line-height: 42px;
30
+  color: #666;
31
+}
32
+
33
+#tabs {
34
+  border-bottom: 1px solid #eee;
35
+}
36
+
37
+#tabs li {
38
+  cursor: pointer;
39
+  width: 100px;
40
+  height: 40px;
41
+  line-height: 40px;
42
+  text-align: center;
43
+  font-size: 16px;
44
+  border-bottom: 2px solid transparent;
45
+  position: relative;
46
+  z-index: 1;
47
+  margin-bottom: -1px;
48
+  color: #666;
49
+}
50
+
51
+
52
+#tabs .active {
53
+  border-bottom-color: #f00;
54
+  color: #222;
55
+}
56
+
57
+.tab-container .content {
58
+  display: none;
59
+}
60
+
61
+/* 页面布局 */
62
+.main {
63
+  padding: 30px 100px;
64
+  width: 960px;
65
+  margin: 0 auto;
66
+}
67
+
68
+.main .logo {
69
+  color: #333;
70
+  text-align: left;
71
+  margin-bottom: 30px;
72
+  line-height: 1;
73
+  height: 110px;
74
+  margin-top: -50px;
75
+  overflow: hidden;
76
+  *zoom: 1;
77
+}
78
+
79
+.main .logo a {
80
+  font-size: 160px;
81
+  color: #333;
82
+}
83
+
84
+.helps {
85
+  margin-top: 40px;
86
+}
87
+
88
+.helps pre {
89
+  padding: 20px;
90
+  margin: 10px 0;
91
+  border: solid 1px #e7e1cd;
92
+  background-color: #fffdef;
93
+  overflow: auto;
94
+}
95
+
96
+.icon_lists {
97
+  width: 100% !important;
98
+  overflow: hidden;
99
+  *zoom: 1;
100
+}
101
+
102
+.icon_lists li {
103
+  width: 100px;
104
+  margin-bottom: 10px;
105
+  margin-right: 20px;
106
+  text-align: center;
107
+  list-style: none !important;
108
+  cursor: default;
109
+}
110
+
111
+.icon_lists li .code-name {
112
+  line-height: 1.2;
113
+}
114
+
115
+.icon_lists .icon {
116
+  display: block;
117
+  height: 100px;
118
+  line-height: 100px;
119
+  font-size: 42px;
120
+  margin: 10px auto;
121
+  color: #333;
122
+  -webkit-transition: font-size 0.25s linear, width 0.25s linear;
123
+  -moz-transition: font-size 0.25s linear, width 0.25s linear;
124
+  transition: font-size 0.25s linear, width 0.25s linear;
125
+}
126
+
127
+.icon_lists .icon:hover {
128
+  font-size: 100px;
129
+}
130
+
131
+.icon_lists .svg-icon {
132
+  /* 通过设置 font-size 来改变图标大小 */
133
+  width: 1em;
134
+  /* 图标和文字相邻时,垂直对齐 */
135
+  vertical-align: -0.15em;
136
+  /* 通过设置 color 来改变 SVG 的颜色/fill */
137
+  fill: currentColor;
138
+  /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
139
+      normalize.css 中也包含这行 */
140
+  overflow: hidden;
141
+}
142
+
143
+.icon_lists li .name,
144
+.icon_lists li .code-name {
145
+  color: #666;
146
+}
147
+
148
+/* markdown 样式 */
149
+.markdown {
150
+  color: #666;
151
+  font-size: 14px;
152
+  line-height: 1.8;
153
+}
154
+
155
+.highlight {
156
+  line-height: 1.5;
157
+}
158
+
159
+.markdown img {
160
+  vertical-align: middle;
161
+  max-width: 100%;
162
+}
163
+
164
+.markdown h1 {
165
+  color: #404040;
166
+  font-weight: 500;
167
+  line-height: 40px;
168
+  margin-bottom: 24px;
169
+}
170
+
171
+.markdown h2,
172
+.markdown h3,
173
+.markdown h4,
174
+.markdown h5,
175
+.markdown h6 {
176
+  color: #404040;
177
+  margin: 1.6em 0 0.6em 0;
178
+  font-weight: 500;
179
+  clear: both;
180
+}
181
+
182
+.markdown h1 {
183
+  font-size: 28px;
184
+}
185
+
186
+.markdown h2 {
187
+  font-size: 22px;
188
+}
189
+
190
+.markdown h3 {
191
+  font-size: 16px;
192
+}
193
+
194
+.markdown h4 {
195
+  font-size: 14px;
196
+}
197
+
198
+.markdown h5 {
199
+  font-size: 12px;
200
+}
201
+
202
+.markdown h6 {
203
+  font-size: 12px;
204
+}
205
+
206
+.markdown hr {
207
+  height: 1px;
208
+  border: 0;
209
+  background: #e9e9e9;
210
+  margin: 16px 0;
211
+  clear: both;
212
+}
213
+
214
+.markdown p {
215
+  margin: 1em 0;
216
+}
217
+
218
+.markdown>p,
219
+.markdown>blockquote,
220
+.markdown>.highlight,
221
+.markdown>ol,
222
+.markdown>ul {
223
+  width: 80%;
224
+}
225
+
226
+.markdown ul>li {
227
+  list-style: circle;
228
+}
229
+
230
+.markdown>ul li,
231
+.markdown blockquote ul>li {
232
+  margin-left: 20px;
233
+  padding-left: 4px;
234
+}
235
+
236
+.markdown>ul li p,
237
+.markdown>ol li p {
238
+  margin: 0.6em 0;
239
+}
240
+
241
+.markdown ol>li {
242
+  list-style: decimal;
243
+}
244
+
245
+.markdown>ol li,
246
+.markdown blockquote ol>li {
247
+  margin-left: 20px;
248
+  padding-left: 4px;
249
+}
250
+
251
+.markdown code {
252
+  margin: 0 3px;
253
+  padding: 0 5px;
254
+  background: #eee;
255
+  border-radius: 3px;
256
+}
257
+
258
+.markdown strong,
259
+.markdown b {
260
+  font-weight: 600;
261
+}
262
+
263
+.markdown>table {
264
+  border-collapse: collapse;
265
+  border-spacing: 0px;
266
+  empty-cells: show;
267
+  border: 1px solid #e9e9e9;
268
+  width: 95%;
269
+  margin-bottom: 24px;
270
+}
271
+
272
+.markdown>table th {
273
+  white-space: nowrap;
274
+  color: #333;
275
+  font-weight: 600;
276
+}
277
+
278
+.markdown>table th,
279
+.markdown>table td {
280
+  border: 1px solid #e9e9e9;
281
+  padding: 8px 16px;
282
+  text-align: left;
283
+}
284
+
285
+.markdown>table th {
286
+  background: #F7F7F7;
287
+}
288
+
289
+.markdown blockquote {
290
+  font-size: 90%;
291
+  color: #999;
292
+  border-left: 4px solid #e9e9e9;
293
+  padding-left: 0.8em;
294
+  margin: 1em 0;
295
+}
296
+
297
+.markdown blockquote p {
298
+  margin: 0;
299
+}
300
+
301
+.markdown .anchor {
302
+  opacity: 0;
303
+  transition: opacity 0.3s ease;
304
+  margin-left: 8px;
305
+}
306
+
307
+.markdown .waiting {
308
+  color: #ccc;
309
+}
310
+
311
+.markdown h1:hover .anchor,
312
+.markdown h2:hover .anchor,
313
+.markdown h3:hover .anchor,
314
+.markdown h4:hover .anchor,
315
+.markdown h5:hover .anchor,
316
+.markdown h6:hover .anchor {
317
+  opacity: 1;
318
+  display: inline-block;
319
+}
320
+
321
+.markdown>br,
322
+.markdown>p>br {
323
+  clear: both;
324
+}
325
+
326
+
327
+.hljs {
328
+  display: block;
329
+  background: white;
330
+  padding: 0.5em;
331
+  color: #333333;
332
+  overflow-x: auto;
333
+}
334
+
335
+.hljs-comment,
336
+.hljs-meta {
337
+  color: #969896;
338
+}
339
+
340
+.hljs-string,
341
+.hljs-variable,
342
+.hljs-template-variable,
343
+.hljs-strong,
344
+.hljs-emphasis,
345
+.hljs-quote {
346
+  color: #df5000;
347
+}
348
+
349
+.hljs-keyword,
350
+.hljs-selector-tag,
351
+.hljs-type {
352
+  color: #a71d5d;
353
+}
354
+
355
+.hljs-literal,
356
+.hljs-symbol,
357
+.hljs-bullet,
358
+.hljs-attribute {
359
+  color: #0086b3;
360
+}
361
+
362
+.hljs-section,
363
+.hljs-name {
364
+  color: #63a35c;
365
+}
366
+
367
+.hljs-tag {
368
+  color: #333333;
369
+}
370
+
371
+.hljs-title,
372
+.hljs-attr,
373
+.hljs-selector-id,
374
+.hljs-selector-class,
375
+.hljs-selector-attr,
376
+.hljs-selector-pseudo {
377
+  color: #795da3;
378
+}
379
+
380
+.hljs-addition {
381
+  color: #55a532;
382
+  background-color: #eaffea;
383
+}
384
+
385
+.hljs-deletion {
386
+  color: #bd2c00;
387
+  background-color: #ffecec;
388
+}
389
+
390
+.hljs-link {
391
+  text-decoration: underline;
392
+}
393
+
394
+/* 代码高亮 */
395
+/* PrismJS 1.15.0
396
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
397
+/**
398
+ * prism.js default theme for JavaScript, CSS and HTML
399
+ * Based on dabblet (http://dabblet.com)
400
+ * @author Lea Verou
401
+ */
402
+code[class*="language-"],
403
+pre[class*="language-"] {
404
+  color: black;
405
+  background: none;
406
+  text-shadow: 0 1px white;
407
+  font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
408
+  text-align: left;
409
+  white-space: pre;
410
+  word-spacing: normal;
411
+  word-break: normal;
412
+  word-wrap: normal;
413
+  line-height: 1.5;
414
+
415
+  -moz-tab-size: 4;
416
+  -o-tab-size: 4;
417
+  tab-size: 4;
418
+
419
+  -webkit-hyphens: none;
420
+  -moz-hyphens: none;
421
+  -ms-hyphens: none;
422
+  hyphens: none;
423
+}
424
+
425
+pre[class*="language-"]::-moz-selection,
426
+pre[class*="language-"] ::-moz-selection,
427
+code[class*="language-"]::-moz-selection,
428
+code[class*="language-"] ::-moz-selection {
429
+  text-shadow: none;
430
+  background: #b3d4fc;
431
+}
432
+
433
+pre[class*="language-"]::selection,
434
+pre[class*="language-"] ::selection,
435
+code[class*="language-"]::selection,
436
+code[class*="language-"] ::selection {
437
+  text-shadow: none;
438
+  background: #b3d4fc;
439
+}
440
+
441
+@media print {
442
+
443
+  code[class*="language-"],
444
+  pre[class*="language-"] {
445
+    text-shadow: none;
446
+  }
447
+}
448
+
449
+/* Code blocks */
450
+pre[class*="language-"] {
451
+  padding: 1em;
452
+  margin: .5em 0;
453
+  overflow: auto;
454
+}
455
+
456
+:not(pre)>code[class*="language-"],
457
+pre[class*="language-"] {
458
+  background: #f5f2f0;
459
+}
460
+
461
+/* Inline code */
462
+:not(pre)>code[class*="language-"] {
463
+  padding: .1em;
464
+  border-radius: .3em;
465
+  white-space: normal;
466
+}
467
+
468
+.token.comment,
469
+.token.prolog,
470
+.token.doctype,
471
+.token.cdata {
472
+  color: slategray;
473
+}
474
+
475
+.token.punctuation {
476
+  color: #999;
477
+}
478
+
479
+.namespace {
480
+  opacity: .7;
481
+}
482
+
483
+.token.property,
484
+.token.tag,
485
+.token.boolean,
486
+.token.number,
487
+.token.constant,
488
+.token.symbol,
489
+.token.deleted {
490
+  color: #905;
491
+}
492
+
493
+.token.selector,
494
+.token.attr-name,
495
+.token.string,
496
+.token.char,
497
+.token.builtin,
498
+.token.inserted {
499
+  color: #690;
500
+}
501
+
502
+.token.operator,
503
+.token.entity,
504
+.token.url,
505
+.language-css .token.string,
506
+.style .token.string {
507
+  color: #9a6e3a;
508
+  background: hsla(0, 0%, 100%, .5);
509
+}
510
+
511
+.token.atrule,
512
+.token.attr-value,
513
+.token.keyword {
514
+  color: #07a;
515
+}
516
+
517
+.token.function,
518
+.token.class-name {
519
+  color: #DD4A68;
520
+}
521
+
522
+.token.regex,
523
+.token.important,
524
+.token.variable {
525
+  color: #e90;
526
+}
527
+
528
+.token.important,
529
+.token.bold {
530
+  font-weight: bold;
531
+}
532
+
533
+.token.italic {
534
+  font-style: italic;
535
+}
536
+
537
+.token.entity {
538
+  cursor: help;
539
+}

+ 9687
- 0
public/iconfont/demo_index.html
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 1667
- 0
public/iconfont/iconfont.css
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 1
- 0
public/iconfont/iconfont.js
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 2900
- 0
public/iconfont/iconfont.json
ファイル差分が大きすぎるため省略します
ファイルの表示


バイナリ
public/iconfont/iconfont.ttf ファイルの表示


バイナリ
public/iconfont/iconfont.woff ファイルの表示


バイナリ
public/iconfont/iconfont.woff2 ファイルの表示


+ 39
- 0
public/index.html ファイルの表示

@@ -0,0 +1,39 @@
1
+<!DOCTYPE html>
2
+<html lang="zh-cn">
3
+  <head>
4
+    <meta charset="utf-8" />
5
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
+    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
7
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
8
+    <meta http-equiv="cache-control" content="no-cache">
9
+    <meta name="viewport" content="width=device-width, user-scalable=no" />
10
+    <link rel="stylesheet" href="/librarys/view-design@4.7.0/iview.css">
11
+    <link rel="stylesheet" href="/iconfont/iconfont.css">
12
+    <link rel="icon" href="favicon.ico" />
13
+    <title>星火云鸽BI</title>
14
+    <script src="/config.js"></script>
15
+  </head>
16
+  <body>
17
+    <noscript>
18
+      <strong>欢迎使用星火云鸽BI</strong>
19
+    </noscript>
20
+    <div id="app"></div>
21
+    <script src="/librarys/babel-polyfill@6.26.0/polyfill.min.js"></script>
22
+    <% for (var i in
23
+     htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
24
+     <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
25
+    <% } %>
26
+    <script src="/librarys/axios@0.21.1/axios.min.js"></script>
27
+    <script src="/librarys/vue-router@3.2.0/vue-router.min.js"></script>
28
+    <script src="/librarys/vuex@3.2.0/vuex.min.js"></script>
29
+    <script src="/librarys/crypto-js.js"></script>
30
+    <script src="/librarys/secret.js"></script>
31
+    <script src="/librarys/view-design@4.7.0/iview.min.js"></script>
32
+    <script src="/librarys/echarts@5.4.3/echarts.min.js"></script>
33
+    <script src="/librarys/echarts-liquidfill@3.1.0/echarts-liquidfill.min.js"></script>
34
+    <script src="/librarys/echarts-wordcloud@2.1.0/echarts-wordcloud.min.js"></script>
35
+    <script src="/librarys/xlsx/xlsx-style.full.min.js"></script>
36
+    <script src="/librarys/xlsx/xlsx.extendscript.js"></script>
37
+    <script src="./librarys/clipboard@2.0.11/clipboard.js"></script>
38
+  </body>
39
+</html>

+ 3
- 0
public/librarys/axios@0.21.1/axios.min.js
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 4
- 0
public/librarys/babel-polyfill@6.26.0/polyfill.min.js
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 890
- 0
public/librarys/clipboard@2.0.11/clipboard.js ファイルの表示

@@ -0,0 +1,890 @@
1
+/*!
2
+ * clipboard.js v2.0.11
3
+ * https://clipboardjs.com/
4
+ *
5
+ * Licensed MIT © Zeno Rocha
6
+ */
7
+(function webpackUniversalModuleDefinition(root, factory) {
8
+	if(typeof exports === 'object' && typeof module === 'object')
9
+		module.exports = factory();
10
+	else if(typeof define === 'function' && define.amd)
11
+		define([], factory);
12
+	else if(typeof exports === 'object')
13
+		exports["ClipboardJS"] = factory();
14
+	else
15
+		root["ClipboardJS"] = factory();
16
+})(this, function() {
17
+return /******/ (function() { // webpackBootstrap
18
+/******/ 	var __webpack_modules__ = ({
19
+
20
+/***/ 686:
21
+/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
22
+
23
+"use strict";
24
+
25
+// EXPORTS
26
+__webpack_require__.d(__webpack_exports__, {
27
+  "default": function() { return /* binding */ clipboard; }
28
+});
29
+
30
+// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js
31
+var tiny_emitter = __webpack_require__(279);
32
+var tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);
33
+// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js
34
+var listen = __webpack_require__(370);
35
+var listen_default = /*#__PURE__*/__webpack_require__.n(listen);
36
+// EXTERNAL MODULE: ./node_modules/select/src/select.js
37
+var src_select = __webpack_require__(817);
38
+var select_default = /*#__PURE__*/__webpack_require__.n(src_select);
39
+;// CONCATENATED MODULE: ./src/common/command.js
40
+/**
41
+ * Executes a given operation type.
42
+ * @param {String} type
43
+ * @return {Boolean}
44
+ */
45
+function command(type) {
46
+  try {
47
+    return document.execCommand(type);
48
+  } catch (err) {
49
+    return false;
50
+  }
51
+}
52
+;// CONCATENATED MODULE: ./src/actions/cut.js
53
+
54
+
55
+/**
56
+ * Cut action wrapper.
57
+ * @param {String|HTMLElement} target
58
+ * @return {String}
59
+ */
60
+
61
+var ClipboardActionCut = function ClipboardActionCut(target) {
62
+  var selectedText = select_default()(target);
63
+  command('cut');
64
+  return selectedText;
65
+};
66
+
67
+/* harmony default export */ var actions_cut = (ClipboardActionCut);
68
+;// CONCATENATED MODULE: ./src/common/create-fake-element.js
69
+/**
70
+ * Creates a fake textarea element with a value.
71
+ * @param {String} value
72
+ * @return {HTMLElement}
73
+ */
74
+function createFakeElement(value) {
75
+  var isRTL = document.documentElement.getAttribute('dir') === 'rtl';
76
+  var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS
77
+
78
+  fakeElement.style.fontSize = '12pt'; // Reset box model
79
+
80
+  fakeElement.style.border = '0';
81
+  fakeElement.style.padding = '0';
82
+  fakeElement.style.margin = '0'; // Move element out of screen horizontally
83
+
84
+  fakeElement.style.position = 'absolute';
85
+  fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically
86
+
87
+  var yPosition = window.pageYOffset || document.documentElement.scrollTop;
88
+  fakeElement.style.top = "".concat(yPosition, "px");
89
+  fakeElement.setAttribute('readonly', '');
90
+  fakeElement.value = value;
91
+  return fakeElement;
92
+}
93
+;// CONCATENATED MODULE: ./src/actions/copy.js
94
+
95
+
96
+
97
+/**
98
+ * Create fake copy action wrapper using a fake element.
99
+ * @param {String} target
100
+ * @param {Object} options
101
+ * @return {String}
102
+ */
103
+
104
+var fakeCopyAction = function fakeCopyAction(value, options) {
105
+  var fakeElement = createFakeElement(value);
106
+  options.container.appendChild(fakeElement);
107
+  var selectedText = select_default()(fakeElement);
108
+  command('copy');
109
+  fakeElement.remove();
110
+  return selectedText;
111
+};
112
+/**
113
+ * Copy action wrapper.
114
+ * @param {String|HTMLElement} target
115
+ * @param {Object} options
116
+ * @return {String}
117
+ */
118
+
119
+
120
+var ClipboardActionCopy = function ClipboardActionCopy(target) {
121
+  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
122
+    container: document.body
123
+  };
124
+  var selectedText = '';
125
+
126
+  if (typeof target === 'string') {
127
+    selectedText = fakeCopyAction(target, options);
128
+  } else if (target instanceof HTMLInputElement && !['text', 'search', 'url', 'tel', 'password'].includes(target === null || target === void 0 ? void 0 : target.type)) {
129
+    // If input type doesn't support `setSelectionRange`. Simulate it. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange
130
+    selectedText = fakeCopyAction(target.value, options);
131
+  } else {
132
+    selectedText = select_default()(target);
133
+    command('copy');
134
+  }
135
+
136
+  return selectedText;
137
+};
138
+
139
+/* harmony default export */ var actions_copy = (ClipboardActionCopy);
140
+;// CONCATENATED MODULE: ./src/actions/default.js
141
+function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
142
+
143
+
144
+
145
+/**
146
+ * Inner function which performs selection from either `text` or `target`
147
+ * properties and then executes copy or cut operations.
148
+ * @param {Object} options
149
+ */
150
+
151
+var ClipboardActionDefault = function ClipboardActionDefault() {
152
+  var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
153
+  // Defines base properties passed from constructor.
154
+  var _options$action = options.action,
155
+      action = _options$action === void 0 ? 'copy' : _options$action,
156
+      container = options.container,
157
+      target = options.target,
158
+      text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.
159
+
160
+  if (action !== 'copy' && action !== 'cut') {
161
+    throw new Error('Invalid "action" value, use either "copy" or "cut"');
162
+  } // Sets the `target` property using an element that will be have its content copied.
163
+
164
+
165
+  if (target !== undefined) {
166
+    if (target && _typeof(target) === 'object' && target.nodeType === 1) {
167
+      if (action === 'copy' && target.hasAttribute('disabled')) {
168
+        throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');
169
+      }
170
+
171
+      if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {
172
+        throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');
173
+      }
174
+    } else {
175
+      throw new Error('Invalid "target" value, use a valid Element');
176
+    }
177
+  } // Define selection strategy based on `text` property.
178
+
179
+
180
+  if (text) {
181
+    return actions_copy(text, {
182
+      container: container
183
+    });
184
+  } // Defines which selection strategy based on `target` property.
185
+
186
+
187
+  if (target) {
188
+    return action === 'cut' ? actions_cut(target) : actions_copy(target, {
189
+      container: container
190
+    });
191
+  }
192
+};
193
+
194
+/* harmony default export */ var actions_default = (ClipboardActionDefault);
195
+;// CONCATENATED MODULE: ./src/clipboard.js
196
+function clipboard_typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return clipboard_typeof(obj); }
197
+
198
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
199
+
200
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
201
+
202
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
203
+
204
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
205
+
206
+function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
207
+
208
+function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
209
+
210
+function _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
211
+
212
+function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
213
+
214
+function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
215
+
216
+function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
217
+
218
+
219
+
220
+
221
+
222
+
223
+/**
224
+ * Helper function to retrieve attribute value.
225
+ * @param {String} suffix
226
+ * @param {Element} element
227
+ */
228
+
229
+function getAttributeValue(suffix, element) {
230
+  var attribute = "data-clipboard-".concat(suffix);
231
+
232
+  if (!element.hasAttribute(attribute)) {
233
+    return;
234
+  }
235
+
236
+  return element.getAttribute(attribute);
237
+}
238
+/**
239
+ * Base class which takes one or more elements, adds event listeners to them,
240
+ * and instantiates a new `ClipboardAction` on each click.
241
+ */
242
+
243
+
244
+var Clipboard = /*#__PURE__*/function (_Emitter) {
245
+  _inherits(Clipboard, _Emitter);
246
+
247
+  var _super = _createSuper(Clipboard);
248
+
249
+  /**
250
+   * @param {String|HTMLElement|HTMLCollection|NodeList} trigger
251
+   * @param {Object} options
252
+   */
253
+  function Clipboard(trigger, options) {
254
+    var _this;
255
+
256
+    _classCallCheck(this, Clipboard);
257
+
258
+    _this = _super.call(this);
259
+
260
+    _this.resolveOptions(options);
261
+
262
+    _this.listenClick(trigger);
263
+
264
+    return _this;
265
+  }
266
+  /**
267
+   * Defines if attributes would be resolved using internal setter functions
268
+   * or custom functions that were passed in the constructor.
269
+   * @param {Object} options
270
+   */
271
+
272
+
273
+  _createClass(Clipboard, [{
274
+    key: "resolveOptions",
275
+    value: function resolveOptions() {
276
+      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
277
+      this.action = typeof options.action === 'function' ? options.action : this.defaultAction;
278
+      this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;
279
+      this.text = typeof options.text === 'function' ? options.text : this.defaultText;
280
+      this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;
281
+    }
282
+    /**
283
+     * Adds a click event listener to the passed trigger.
284
+     * @param {String|HTMLElement|HTMLCollection|NodeList} trigger
285
+     */
286
+
287
+  }, {
288
+    key: "listenClick",
289
+    value: function listenClick(trigger) {
290
+      var _this2 = this;
291
+
292
+      this.listener = listen_default()(trigger, 'click', function (e) {
293
+        return _this2.onClick(e);
294
+      });
295
+    }
296
+    /**
297
+     * Defines a new `ClipboardAction` on each click event.
298
+     * @param {Event} e
299
+     */
300
+
301
+  }, {
302
+    key: "onClick",
303
+    value: function onClick(e) {
304
+      var trigger = e.delegateTarget || e.currentTarget;
305
+      var action = this.action(trigger) || 'copy';
306
+      var text = actions_default({
307
+        action: action,
308
+        container: this.container,
309
+        target: this.target(trigger),
310
+        text: this.text(trigger)
311
+      }); // Fires an event based on the copy operation result.
312
+
313
+      this.emit(text ? 'success' : 'error', {
314
+        action: action,
315
+        text: text,
316
+        trigger: trigger,
317
+        clearSelection: function clearSelection() {
318
+          if (trigger) {
319
+            trigger.focus();
320
+          }
321
+
322
+          window.getSelection().removeAllRanges();
323
+        }
324
+      });
325
+    }
326
+    /**
327
+     * Default `action` lookup function.
328
+     * @param {Element} trigger
329
+     */
330
+
331
+  }, {
332
+    key: "defaultAction",
333
+    value: function defaultAction(trigger) {
334
+      return getAttributeValue('action', trigger);
335
+    }
336
+    /**
337
+     * Default `target` lookup function.
338
+     * @param {Element} trigger
339
+     */
340
+
341
+  }, {
342
+    key: "defaultTarget",
343
+    value: function defaultTarget(trigger) {
344
+      var selector = getAttributeValue('target', trigger);
345
+
346
+      if (selector) {
347
+        return document.querySelector(selector);
348
+      }
349
+    }
350
+    /**
351
+     * Allow fire programmatically a copy action
352
+     * @param {String|HTMLElement} target
353
+     * @param {Object} options
354
+     * @returns Text copied.
355
+     */
356
+
357
+  }, {
358
+    key: "defaultText",
359
+
360
+    /**
361
+     * Default `text` lookup function.
362
+     * @param {Element} trigger
363
+     */
364
+    value: function defaultText(trigger) {
365
+      return getAttributeValue('text', trigger);
366
+    }
367
+    /**
368
+     * Destroy lifecycle.
369
+     */
370
+
371
+  }, {
372
+    key: "destroy",
373
+    value: function destroy() {
374
+      this.listener.destroy();
375
+    }
376
+  }], [{
377
+    key: "copy",
378
+    value: function copy(target) {
379
+      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
380
+        container: document.body
381
+      };
382
+      return actions_copy(target, options);
383
+    }
384
+    /**
385
+     * Allow fire programmatically a cut action
386
+     * @param {String|HTMLElement} target
387
+     * @returns Text cutted.
388
+     */
389
+
390
+  }, {
391
+    key: "cut",
392
+    value: function cut(target) {
393
+      return actions_cut(target);
394
+    }
395
+    /**
396
+     * Returns the support of the given action, or all actions if no action is
397
+     * given.
398
+     * @param {String} [action]
399
+     */
400
+
401
+  }, {
402
+    key: "isSupported",
403
+    value: function isSupported() {
404
+      var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];
405
+      var actions = typeof action === 'string' ? [action] : action;
406
+      var support = !!document.queryCommandSupported;
407
+      actions.forEach(function (action) {
408
+        support = support && !!document.queryCommandSupported(action);
409
+      });
410
+      return support;
411
+    }
412
+  }]);
413
+
414
+  return Clipboard;
415
+}((tiny_emitter_default()));
416
+
417
+/* harmony default export */ var clipboard = (Clipboard);
418
+
419
+/***/ }),
420
+
421
+/***/ 828:
422
+/***/ (function(module) {
423
+
424
+var DOCUMENT_NODE_TYPE = 9;
425
+
426
+/**
427
+ * A polyfill for Element.matches()
428
+ */
429
+if (typeof Element !== 'undefined' && !Element.prototype.matches) {
430
+    var proto = Element.prototype;
431
+
432
+    proto.matches = proto.matchesSelector ||
433
+                    proto.mozMatchesSelector ||
434
+                    proto.msMatchesSelector ||
435
+                    proto.oMatchesSelector ||
436
+                    proto.webkitMatchesSelector;
437
+}
438
+
439
+/**
440
+ * Finds the closest parent that matches a selector.
441
+ *
442
+ * @param {Element} element
443
+ * @param {String} selector
444
+ * @return {Function}
445
+ */
446
+function closest (element, selector) {
447
+    while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {
448
+        if (typeof element.matches === 'function' &&
449
+            element.matches(selector)) {
450
+          return element;
451
+        }
452
+        element = element.parentNode;
453
+    }
454
+}
455
+
456
+module.exports = closest;
457
+
458
+
459
+/***/ }),
460
+
461
+/***/ 438:
462
+/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
463
+
464
+var closest = __webpack_require__(828);
465
+
466
+/**
467
+ * Delegates event to a selector.
468
+ *
469
+ * @param {Element} element
470
+ * @param {String} selector
471
+ * @param {String} type
472
+ * @param {Function} callback
473
+ * @param {Boolean} useCapture
474
+ * @return {Object}
475
+ */
476
+function _delegate(element, selector, type, callback, useCapture) {
477
+    var listenerFn = listener.apply(this, arguments);
478
+
479
+    element.addEventListener(type, listenerFn, useCapture);
480
+
481
+    return {
482
+        destroy: function() {
483
+            element.removeEventListener(type, listenerFn, useCapture);
484
+        }
485
+    }
486
+}
487
+
488
+/**
489
+ * Delegates event to a selector.
490
+ *
491
+ * @param {Element|String|Array} [elements]
492
+ * @param {String} selector
493
+ * @param {String} type
494
+ * @param {Function} callback
495
+ * @param {Boolean} useCapture
496
+ * @return {Object}
497
+ */
498
+function delegate(elements, selector, type, callback, useCapture) {
499
+    // Handle the regular Element usage
500
+    if (typeof elements.addEventListener === 'function') {
501
+        return _delegate.apply(null, arguments);
502
+    }
503
+
504
+    // Handle Element-less usage, it defaults to global delegation
505
+    if (typeof type === 'function') {
506
+        // Use `document` as the first parameter, then apply arguments
507
+        // This is a short way to .unshift `arguments` without running into deoptimizations
508
+        return _delegate.bind(null, document).apply(null, arguments);
509
+    }
510
+
511
+    // Handle Selector-based usage
512
+    if (typeof elements === 'string') {
513
+        elements = document.querySelectorAll(elements);
514
+    }
515
+
516
+    // Handle Array-like based usage
517
+    return Array.prototype.map.call(elements, function (element) {
518
+        return _delegate(element, selector, type, callback, useCapture);
519
+    });
520
+}
521
+
522
+/**
523
+ * Finds closest match and invokes callback.
524
+ *
525
+ * @param {Element} element
526
+ * @param {String} selector
527
+ * @param {String} type
528
+ * @param {Function} callback
529
+ * @return {Function}
530
+ */
531
+function listener(element, selector, type, callback) {
532
+    return function(e) {
533
+        e.delegateTarget = closest(e.target, selector);
534
+
535
+        if (e.delegateTarget) {
536
+            callback.call(element, e);
537
+        }
538
+    }
539
+}
540
+
541
+module.exports = delegate;
542
+
543
+
544
+/***/ }),
545
+
546
+/***/ 879:
547
+/***/ (function(__unused_webpack_module, exports) {
548
+
549
+/**
550
+ * Check if argument is a HTML element.
551
+ *
552
+ * @param {Object} value
553
+ * @return {Boolean}
554
+ */
555
+exports.node = function(value) {
556
+    return value !== undefined
557
+        && value instanceof HTMLElement
558
+        && value.nodeType === 1;
559
+};
560
+
561
+/**
562
+ * Check if argument is a list of HTML elements.
563
+ *
564
+ * @param {Object} value
565
+ * @return {Boolean}
566
+ */
567
+exports.nodeList = function(value) {
568
+    var type = Object.prototype.toString.call(value);
569
+
570
+    return value !== undefined
571
+        && (type === '[object NodeList]' || type === '[object HTMLCollection]')
572
+        && ('length' in value)
573
+        && (value.length === 0 || exports.node(value[0]));
574
+};
575
+
576
+/**
577
+ * Check if argument is a string.
578
+ *
579
+ * @param {Object} value
580
+ * @return {Boolean}
581
+ */
582
+exports.string = function(value) {
583
+    return typeof value === 'string'
584
+        || value instanceof String;
585
+};
586
+
587
+/**
588
+ * Check if argument is a function.
589
+ *
590
+ * @param {Object} value
591
+ * @return {Boolean}
592
+ */
593
+exports.fn = function(value) {
594
+    var type = Object.prototype.toString.call(value);
595
+
596
+    return type === '[object Function]';
597
+};
598
+
599
+
600
+/***/ }),
601
+
602
+/***/ 370:
603
+/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
604
+
605
+var is = __webpack_require__(879);
606
+var delegate = __webpack_require__(438);
607
+
608
+/**
609
+ * Validates all params and calls the right
610
+ * listener function based on its target type.
611
+ *
612
+ * @param {String|HTMLElement|HTMLCollection|NodeList} target
613
+ * @param {String} type
614
+ * @param {Function} callback
615
+ * @return {Object}
616
+ */
617
+function listen(target, type, callback) {
618
+    if (!target && !type && !callback) {
619
+        throw new Error('Missing required arguments');
620
+    }
621
+
622
+    if (!is.string(type)) {
623
+        throw new TypeError('Second argument must be a String');
624
+    }
625
+
626
+    if (!is.fn(callback)) {
627
+        throw new TypeError('Third argument must be a Function');
628
+    }
629
+
630
+    if (is.node(target)) {
631
+        return listenNode(target, type, callback);
632
+    }
633
+    else if (is.nodeList(target)) {
634
+        return listenNodeList(target, type, callback);
635
+    }
636
+    else if (is.string(target)) {
637
+        return listenSelector(target, type, callback);
638
+    }
639
+    else {
640
+        throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');
641
+    }
642
+}
643
+
644
+/**
645
+ * Adds an event listener to a HTML element
646
+ * and returns a remove listener function.
647
+ *
648
+ * @param {HTMLElement} node
649
+ * @param {String} type
650
+ * @param {Function} callback
651
+ * @return {Object}
652
+ */
653
+function listenNode(node, type, callback) {
654
+    node.addEventListener(type, callback);
655
+
656
+    return {
657
+        destroy: function() {
658
+            node.removeEventListener(type, callback);
659
+        }
660
+    }
661
+}
662
+
663
+/**
664
+ * Add an event listener to a list of HTML elements
665
+ * and returns a remove listener function.
666
+ *
667
+ * @param {NodeList|HTMLCollection} nodeList
668
+ * @param {String} type
669
+ * @param {Function} callback
670
+ * @return {Object}
671
+ */
672
+function listenNodeList(nodeList, type, callback) {
673
+    Array.prototype.forEach.call(nodeList, function(node) {
674
+        node.addEventListener(type, callback);
675
+    });
676
+
677
+    return {
678
+        destroy: function() {
679
+            Array.prototype.forEach.call(nodeList, function(node) {
680
+                node.removeEventListener(type, callback);
681
+            });
682
+        }
683
+    }
684
+}
685
+
686
+/**
687
+ * Add an event listener to a selector
688
+ * and returns a remove listener function.
689
+ *
690
+ * @param {String} selector
691
+ * @param {String} type
692
+ * @param {Function} callback
693
+ * @return {Object}
694
+ */
695
+function listenSelector(selector, type, callback) {
696
+    return delegate(document.body, selector, type, callback);
697
+}
698
+
699
+module.exports = listen;
700
+
701
+
702
+/***/ }),
703
+
704
+/***/ 817:
705
+/***/ (function(module) {
706
+
707
+function select(element) {
708
+    var selectedText;
709
+
710
+    if (element.nodeName === 'SELECT') {
711
+        element.focus();
712
+
713
+        selectedText = element.value;
714
+    }
715
+    else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {
716
+        var isReadOnly = element.hasAttribute('readonly');
717
+
718
+        if (!isReadOnly) {
719
+            element.setAttribute('readonly', '');
720
+        }
721
+
722
+        element.select();
723
+        element.setSelectionRange(0, element.value.length);
724
+
725
+        if (!isReadOnly) {
726
+            element.removeAttribute('readonly');
727
+        }
728
+
729
+        selectedText = element.value;
730
+    }
731
+    else {
732
+        if (element.hasAttribute('contenteditable')) {
733
+            element.focus();
734
+        }
735
+
736
+        var selection = window.getSelection();
737
+        var range = document.createRange();
738
+
739
+        range.selectNodeContents(element);
740
+        selection.removeAllRanges();
741
+        selection.addRange(range);
742
+
743
+        selectedText = selection.toString();
744
+    }
745
+
746
+    return selectedText;
747
+}
748
+
749
+module.exports = select;
750
+
751
+
752
+/***/ }),
753
+
754
+/***/ 279:
755
+/***/ (function(module) {
756
+
757
+function E () {
758
+  // Keep this empty so it's easier to inherit from
759
+  // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
760
+}
761
+
762
+E.prototype = {
763
+  on: function (name, callback, ctx) {
764
+    var e = this.e || (this.e = {});
765
+
766
+    (e[name] || (e[name] = [])).push({
767
+      fn: callback,
768
+      ctx: ctx
769
+    });
770
+
771
+    return this;
772
+  },
773
+
774
+  once: function (name, callback, ctx) {
775
+    var self = this;
776
+    function listener () {
777
+      self.off(name, listener);
778
+      callback.apply(ctx, arguments);
779
+    };
780
+
781
+    listener._ = callback
782
+    return this.on(name, listener, ctx);
783
+  },
784
+
785
+  emit: function (name) {
786
+    var data = [].slice.call(arguments, 1);
787
+    var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
788
+    var i = 0;
789
+    var len = evtArr.length;
790
+
791
+    for (i; i < len; i++) {
792
+      evtArr[i].fn.apply(evtArr[i].ctx, data);
793
+    }
794
+
795
+    return this;
796
+  },
797
+
798
+  off: function (name, callback) {
799
+    var e = this.e || (this.e = {});
800
+    var evts = e[name];
801
+    var liveEvents = [];
802
+
803
+    if (evts && callback) {
804
+      for (var i = 0, len = evts.length; i < len; i++) {
805
+        if (evts[i].fn !== callback && evts[i].fn._ !== callback)
806
+          liveEvents.push(evts[i]);
807
+      }
808
+    }
809
+
810
+    // Remove event from queue to prevent memory leak
811
+    // Suggested by https://github.com/lazd
812
+    // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910
813
+
814
+    (liveEvents.length)
815
+      ? e[name] = liveEvents
816
+      : delete e[name];
817
+
818
+    return this;
819
+  }
820
+};
821
+
822
+module.exports = E;
823
+module.exports.TinyEmitter = E;
824
+
825
+
826
+/***/ })
827
+
828
+/******/ 	});
829
+/************************************************************************/
830
+/******/ 	// The module cache
831
+/******/ 	var __webpack_module_cache__ = {};
832
+/******/ 	
833
+/******/ 	// The require function
834
+/******/ 	function __webpack_require__(moduleId) {
835
+/******/ 		// Check if module is in cache
836
+/******/ 		if(__webpack_module_cache__[moduleId]) {
837
+/******/ 			return __webpack_module_cache__[moduleId].exports;
838
+/******/ 		}
839
+/******/ 		// Create a new module (and put it into the cache)
840
+/******/ 		var module = __webpack_module_cache__[moduleId] = {
841
+/******/ 			// no module.id needed
842
+/******/ 			// no module.loaded needed
843
+/******/ 			exports: {}
844
+/******/ 		};
845
+/******/ 	
846
+/******/ 		// Execute the module function
847
+/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
848
+/******/ 	
849
+/******/ 		// Return the exports of the module
850
+/******/ 		return module.exports;
851
+/******/ 	}
852
+/******/ 	
853
+/************************************************************************/
854
+/******/ 	/* webpack/runtime/compat get default export */
855
+/******/ 	!function() {
856
+/******/ 		// getDefaultExport function for compatibility with non-harmony modules
857
+/******/ 		__webpack_require__.n = function(module) {
858
+/******/ 			var getter = module && module.__esModule ?
859
+/******/ 				function() { return module['default']; } :
860
+/******/ 				function() { return module; };
861
+/******/ 			__webpack_require__.d(getter, { a: getter });
862
+/******/ 			return getter;
863
+/******/ 		};
864
+/******/ 	}();
865
+/******/ 	
866
+/******/ 	/* webpack/runtime/define property getters */
867
+/******/ 	!function() {
868
+/******/ 		// define getter functions for harmony exports
869
+/******/ 		__webpack_require__.d = function(exports, definition) {
870
+/******/ 			for(var key in definition) {
871
+/******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
872
+/******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
873
+/******/ 				}
874
+/******/ 			}
875
+/******/ 		};
876
+/******/ 	}();
877
+/******/ 	
878
+/******/ 	/* webpack/runtime/hasOwnProperty shorthand */
879
+/******/ 	!function() {
880
+/******/ 		__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
881
+/******/ 	}();
882
+/******/ 	
883
+/************************************************************************/
884
+/******/ 	// module exports must be returned from runtime so entry inlining is disabled
885
+/******/ 	// startup
886
+/******/ 	// Load entry module and return exports
887
+/******/ 	return __webpack_require__(686);
888
+/******/ })()
889
+.default;
890
+});

+ 7
- 0
public/librarys/clipboard@2.0.11/clipboard.min.js
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 6059
- 0
public/librarys/crypto-js.js
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 1688
- 0
public/librarys/echarts-liquidfill@3.1.0/echarts-liquidfill.js
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 2
- 0
public/librarys/echarts-liquidfill@3.1.0/echarts-liquidfill.min.js
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 1786
- 0
public/librarys/echarts-wordcloud@2.1.0/echarts-wordcloud.js
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 3
- 0
public/librarys/echarts-wordcloud@2.1.0/echarts-wordcloud.min.js
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 45
- 0
public/librarys/echarts@5.4.3/echarts.min.js
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 34
- 0
public/librarys/secret.js ファイルの表示

@@ -0,0 +1,34 @@
1
+let keystr = "XINGHUOLIAOYUAN7"; //密钥
2
+
3
+// 字符串转hex
4
+let string_to_hex = function (str) {
5
+  let tempstr = "";
6
+  for (let i = 0; i < str.length; i++) {
7
+    if (tempstr === "") tempstr = str.charCodeAt(i).toString(16);
8
+    else tempstr += str.charCodeAt(i).toString(16);
9
+  }
10
+  return tempstr;
11
+};
12
+let key = string_to_hex(keystr);
13
+key = CryptoJS.enc.Hex.parse(key);
14
+
15
+// 加密
16
+const getEncryptedString = (src) => {
17
+  const enc = CryptoJS.AES.encrypt(src, key, {
18
+    mode: CryptoJS.mode.ECB,
19
+    padding: CryptoJS.pad.Pkcs7
20
+  });
21
+  const enced = enc.ciphertext.toString();
22
+  return enced;
23
+};
24
+// 解密
25
+const getDecryptString = (enced) => {
26
+  const dec = CryptoJS.AES.decrypt(CryptoJS.format.Hex.parse(enced), key, {
27
+    mode: CryptoJS.mode.ECB,
28
+    padding: CryptoJS.pad.Pkcs7
29
+  });
30
+  let decstr = CryptoJS.enc.Utf8.stringify(dec);
31
+  return decstr;
32
+};
33
+window.getEncryptedString = getEncryptedString;
34
+window.getDecryptString = getDecryptString;

+ 870
- 0
public/librarys/view-design@4.7.0/fonts/ionicons.svg
ファイル差分が大きすぎるため省略します
ファイルの表示


バイナリ
public/librarys/view-design@4.7.0/fonts/ionicons.ttf ファイルの表示


バイナリ
public/librarys/view-design@4.7.0/fonts/ionicons.woff ファイルの表示


バイナリ
public/librarys/view-design@4.7.0/fonts/ionicons.woff2 ファイルの表示


+ 1
- 0
public/librarys/view-design@4.7.0/iview.css
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 27
- 0
public/librarys/view-design@4.7.0/iview.min.js
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 6
- 0
public/librarys/vue-router@3.2.0/vue-router.min.js
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 11965
- 0
public/librarys/vue@2.6.11/vue.js
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 6
- 0
public/librarys/vue@2.6.11/vue.min.js
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 6
- 0
public/librarys/vuex@3.2.0/vuex.min.js
ファイル差分が大きすぎるため省略します
ファイルの表示


+ 78
- 0
src/App.vue ファイルの表示

@@ -0,0 +1,78 @@
1
+<template>
2
+  <div id="app">
3
+    <div class="btn">新建</div>
4
+    <Button type="primary" class="my_btn">Primary</Button>
5
+
6
+    1212
7
+    <router-view></router-view>
8
+  </div>
9
+</template>
10
+
11
+<script>
12
+export default {
13
+  data() {
14
+    return {};
15
+  },
16
+  created() {},
17
+  methods: {}
18
+};
19
+</script>
20
+<style lang="less">
21
+@import "@/assets/less/reset.less";
22
+@import "@/assets/less/common.less";
23
+@import "@/assets/less/customModal.less";
24
+
25
+// 加载动画
26
+.ivu-spin {
27
+  z-index: 1000;
28
+}
29
+.demo-spin-icon-load {
30
+  animation: ani-demo-spin 1s linear infinite;
31
+}
32
+@keyframes ani-demo-spin {
33
+  from {
34
+    transform: rotate(0deg);
35
+  }
36
+  50% {
37
+    transform: rotate(180deg);
38
+  }
39
+  to {
40
+    transform: rotate(360deg);
41
+  }
42
+}
43
+.require {
44
+  .ivu-form-item-label {
45
+    &::before {
46
+      content: "*" !important;
47
+      display: inline-block;
48
+      margin-right: 4px;
49
+      line-height: 1;
50
+      font-family: SimSun;
51
+      font-size: 14px;
52
+      color: #ed4014;
53
+    }
54
+  }
55
+}
56
+.btn {
57
+  margin: 20px;
58
+  width: 80px;
59
+  height: 32px;
60
+  text-align: center;
61
+  line-height: 32px;
62
+  color: #fff;
63
+  border-radius: 8px;
64
+  opacity: 1;
65
+  background: linear-gradient(180deg, #30e5fc 0%, #34a4ff 100%);
66
+  box-shadow: inset 0 1px 2px 0 #ffffffb3, inset 0 -2px 3px 0 #ffffff4d,
67
+    0 3px 5px 0 #339dff80, inset 0 -2px 0 0 #2b89e0;
68
+}
69
+.primary_btn.ivu-btn.ivu-btn-primary {
70
+  margin: 20px;
71
+  border: none;
72
+  border-radius: 8px;
73
+  opacity: 1;
74
+  background: linear-gradient(180deg, #30e5fc 0%, #34a4ff 100%);
75
+  box-shadow: inset 0 1px 2px 0 #ffffffb3, inset 0 -2px 3px 0 #ffffff4d,
76
+    0 3px 5px 0 #339dff80, inset 0 -2px 0 0 #2b89e0;
77
+}
78
+</style>

+ 279
- 0
src/api/system.js ファイルの表示

@@ -0,0 +1,279 @@
1
+import { ssystem_url } from "@/utils/httpRequest";
2
+
3
+/**
4
+ * 用户登录
5
+ */
6
+export const login_login = (data) => ssystem_url("login/login", data);
7
+/**
8
+ * 用户退出/断开连接
9
+ */
10
+export const login_out = (data) => ssystem_url("login/out", data);
11
+/**
12
+ *1.2.6分组--用户列表(分享用)
13
+ */
14
+export const group_list_gu = (data) => ssystem_url("group/list_gu", data);
15
+/**
16
+ * 1.3.1角色--选择列表(分享用)
17
+ */
18
+export const role_list_sel = (data) => ssystem_url("role/list_sel", data);
19
+/**
20
+ * 4.1.2参数--保存
21
+ */
22
+export const dict_add_dict = (data) => ssystem_url("dict/add_dict", data);
23
+/**
24
+ * 4.1.3参数--详情
25
+ */
26
+export const dict_detail = (data) => ssystem_url("dict/detail", data);
27
+/**
28
+ * 4.1.3.2参数--属性
29
+ */
30
+export const dict_property = (data) => ssystem_url("dict/property", data);
31
+/**
32
+ * 4.1.3.3参数--更新
33
+ */
34
+export const dict_edit = (data) => ssystem_url("dict/edit", data);
35
+/**
36
+ * 4.1.2.2参数--保存参数详情
37
+ */
38
+export const dict_add_detail = (data) => ssystem_url("dict/add_detail", data);
39
+/**
40
+ * 4.1.1参数--列表
41
+ */
42
+export const dict_list_sel = (data) => ssystem_url("dict/list_sel", data);
43
+/**
44
+ * 4.1.4参数--数据列表
45
+ */
46
+export const dict_list_data = (data) => ssystem_url("dict/list_data", data);
47
+/**
48
+ * 4.1.6参数--分页列表
49
+ */
50
+export const dict_list = (data) => ssystem_url("dict/list", data);
51
+/**
52
+ * 4.1.7参数--删除
53
+ */
54
+export const dict_delete = (data) => ssystem_url("dict/delete", data);
55
+/**
56
+ * 4.1.8参数--移动
57
+ */
58
+export const dict_move = (data) => ssystem_url("dict/move", data);
59
+/**
60
+ * 4.2.3地区--根据名称获取编码
61
+ */
62
+export const areazone_get_code = (data) =>
63
+  ssystem_url("areazone/get_code", data);
64
+/**
65
+ * 1.1.1用户--列表
66
+ */
67
+export const user_list = (data) => ssystem_url("user/list", data);
68
+/**
69
+ * 1.1.2用户--添加
70
+ */
71
+export const user_add = (data) => ssystem_url("user/add", data);
72
+/**
73
+ * 1.1.3用户--更新
74
+ */
75
+export const user_edit = (data) => ssystem_url("user/edit", data);
76
+/**
77
+ * 1.1.3.2用户--改头像
78
+ */
79
+export const user_edit_userpic = (data) =>
80
+  ssystem_url("user/edit_userpic", data);
81
+/**
82
+ * 1.1.4用户--删除
83
+ */
84
+export const user_delete = (data) => ssystem_url("user/delete", data);
85
+/**
86
+ * 1.1.5用户--移除分组
87
+ */
88
+export const user_remove_group = (data) =>
89
+  ssystem_url("user/remove_group", data);
90
+/**
91
+ * 1.1.5.2用户--分组列表
92
+ */
93
+export const user_list_group = (data) => ssystem_url("user/list_group", data);
94
+/**
95
+ * 1.1.6.2用户--角色列表
96
+ */
97
+export const user_list_role = (data) => ssystem_url("user/list_role", data);
98
+/**
99
+ * 1.1.7用户--修改手机号
100
+ */
101
+export const user_edit_phone = (data) => ssystem_url("user/edit_phone", data);
102
+/**
103
+ * 1.1.8用户--修改密码
104
+ */
105
+export const user_edit_pwd = (data) => ssystem_url("user/edit_pwd", data);
106
+/**
107
+ * 1.1.9用户--获取验证码
108
+ */
109
+export const user_get_code = (data) => ssystem_url("user/get_code", data);
110
+/**
111
+ * 1.1.10用户--功能菜单
112
+ */
113
+export const power_list_user = (data) => ssystem_url("power/list_user", data);
114
+/**
115
+ * 1.2.1分组--列表
116
+ */
117
+export const group_list = (data) => ssystem_url("group/list", data);
118
+/**
119
+ * 1.2.2分组--添加
120
+ */
121
+export const group_add = (data) => ssystem_url("group/add", data);
122
+/**
123
+ * 1.2.3分组--更新
124
+ */
125
+export const group_edit = (data) => ssystem_url("group/edit", data);
126
+/**
127
+ * 1.2.4分组--删除
128
+ */
129
+export const group_delete = (data) => ssystem_url("group/delete", data);
130
+/**
131
+ * 1.3.1角色--列表
132
+ */
133
+export const role_list = (data) => ssystem_url("role/list", data);
134
+/**
135
+ * 1.3.2角色--添加
136
+ */
137
+export const role_add = (data) => ssystem_url("role/add", data);
138
+/**
139
+ * 1.3.2.2角色--添加角色分组用户
140
+ */
141
+export const role_add_group_user = (data) =>
142
+  ssystem_url("role/add_group_user", data);
143
+/**
144
+ * 1.3.2.3角色--获取角色分组用户
145
+ */
146
+export const role_list_gu = (data) => ssystem_url("role/list_gu", data);
147
+/**
148
+ * 1.3.2.4角色--角色分组用户选择列表
149
+ */
150
+export const role_list_gu_sel = (data) => ssystem_url("role/list_gu_sel", data);
151
+/**
152
+ * 1.3.2.5角色--权限选择列表
153
+ */
154
+export const power_list_sel = (data) => ssystem_url("power/list_sel", data);
155
+/**
156
+ * 1.3.2.6角色--角色权限列表
157
+ */
158
+export const role_list_power = (data) => ssystem_url("role/list_power", data);
159
+/**
160
+ * 1.3.2.7角色--保存角色权限
161
+ */
162
+export const role_add_power = (data) => ssystem_url("role/add_power", data);
163
+/**
164
+ * 1.3.2.9 角色--角色资源保存
165
+ */
166
+export const roletree_add = (data) => ssystem_url("roletree/add", data);
167
+/**
168
+ * 1.3.2.10 角色--角色资源
169
+ */
170
+export const roletree_list_role = (data) =>
171
+  ssystem_url("roletree/list_role", data);
172
+/**
173
+ * 1.3.3角色--更新
174
+ */
175
+export const role_edit = (data) => ssystem_url("role/edit", data);
176
+/**
177
+ * 1.3.4角色--删除
178
+ */
179
+export const role_delete = (data) => ssystem_url("role/delete", data);
180
+/**
181
+ * 1.3.5角色--添加分组
182
+ */
183
+export const role_add_group = (data) => ssystem_url("role/add_group", data);
184
+/**
185
+ * 1.3.6角色--添加用户
186
+ */
187
+export const role_add_user = (data) => ssystem_url("role/add_user", data);
188
+/**
189
+ * 1.4.0会话--列表
190
+ */
191
+export const user_session_list = (data) =>
192
+  ssystem_url("user_session/list", data);
193
+/**
194
+ * 1.4.1会话--单独断开
195
+ */
196
+export const user_login_out = (data) => ssystem_url("login/out", data);
197
+/**
198
+ * 1.4.2会话--批量断开
199
+ */
200
+export const user_session_batch_out = (data) =>
201
+  ssystem_url("user_session/batch_out", data);
202
+/**
203
+ * 1.4.3用户--校验用户登录状态
204
+ */
205
+export const user_check_login = (data) => ssystem_url("user/check_login", data);
206
+/**
207
+ * 1.4.4消息推送--列表
208
+ */
209
+export const notice_list = (data) => ssystem_url("notice/list", data);
210
+/**
211
+ * 1.4.5消息推送--发送
212
+ */
213
+export const notice_send = (data) => ssystem_url("notice/send", data);
214
+/**
215
+ * 1.4.6消息推送--删除
216
+ */
217
+export const notice_delete = (data) => ssystem_url("notice/delete", data);
218
+/**
219
+ * 1.4.7消息推送--置顶
220
+ */
221
+export const notice_toped = (data) => ssystem_url("notice/toped", data);
222
+/**
223
+ * 1.4.8消息推送--取消置顶
224
+ */
225
+export const notice_untoped = (data) => ssystem_url("notice/untoped", data);
226
+/**
227
+ * 1.4.9消息推送--批量删除
228
+ */
229
+export const notice_deletebatch = (data) =>
230
+  ssystem_url("notice/deletebatch", data);
231
+/**
232
+ * 1.4.9消息推送--新增
233
+ */
234
+export const notice_add = (data) => ssystem_url("notice/add", data);
235
+/**
236
+ * 1.4.10消息推送--编辑
237
+ */
238
+export const notice_edit = (data) => ssystem_url("notice/edit", data);
239
+/**
240
+ * 1.4.11消息推送--详情
241
+ */
242
+export const notice_detail = (data) => ssystem_url("notice/detail", data);
243
+/**
244
+ * 1.4.12消息推送--用户列表
245
+ */
246
+export const notice_list_user = (data) => ssystem_url("notice/list_user", data);
247
+/**
248
+ * 1.4.13消息推送--用户详情
249
+ */
250
+export const notice_detail_user = (data) =>
251
+  ssystem_url("notice/detail_user", data);
252
+/**
253
+ * 9.1.1 脱敏规则--列表
254
+ */
255
+export const tm_list = (data) => ssystem_url("tm/list", data);
256
+/**
257
+ * 9.1.2 脱敏规则--添加
258
+ */
259
+export const tm_add = (data) => ssystem_url("tm/add", data);
260
+/**
261
+ * 9.1.3 脱敏规则--修改
262
+ */
263
+export const tm_edit = (data) => ssystem_url("tm/edit", data);
264
+/**
265
+ * 9.1.4 脱敏规则--删除
266
+ */
267
+export const tm_delete = (data) => ssystem_url("tm/delete", data);
268
+/**
269
+ * 9.1.5 脱敏规则--详情
270
+ */
271
+export const tm_detail = (data) => ssystem_url("tm/detail", data);
272
+/**
273
+ * 9.1.6 脱敏规则--移动
274
+ */
275
+export const tm_move = (data) => ssystem_url("tm/move", data);
276
+/**
277
+ * 9.1.7 脱敏规则--属性
278
+ */
279
+export const tm_attr = (data) => ssystem_url("tm/attr", data);

+ 333
- 0
src/assets/less/common.less ファイルの表示

@@ -0,0 +1,333 @@
1
+:root {
2
+  --blue: #007bff;
3
+}
4
+html,
5
+body,
6
+#app,
7
+.dashboard_wrap {
8
+  position: relative;
9
+  width: 100vw;
10
+  height: 100vh;
11
+  font-family: "Microsoft YaHei", "微软雅黑" !important;
12
+  color: #253a70;
13
+  font-size: 14px;
14
+  user-select: none;
15
+  background: #ffff;
16
+  box-sizing: border-box;
17
+  overflow: hidden;
18
+  // 设置弥散渐变
19
+  background-image: url("~@/assets/img/dispersion_gradient.png");
20
+  background-size: cover;
21
+  background-repeat: no-repeat;
22
+  background-position: center;
23
+  /* 第一个方块颜色,第二个轨道颜色(用于更改火狐浏览器样式) */
24
+  // scrollbar-color: #7c8db5 #f3f4fc;
25
+  /* 火狐滚动条无法自定义宽度,只能通过此属性使滚动条宽度变细 */
26
+  // scrollbar-width: thin;
27
+  // -ms-overflow-style: none;
28
+}
29
+
30
+// 自定义滚动条样式
31
+::-webkit-scrollbar {
32
+  width: 10px !important;
33
+  height: 10px !important;
34
+  background: #fff;
35
+}
36
+::-webkit-scrollbar-track,
37
+::-webkit-scrollbar-track:hover {
38
+  background: #f3f4fc;
39
+}
40
+::-webkit-scrollbar-thumb {
41
+  border-radius: 5px;
42
+  border-style: dashed;
43
+  background: #7c8db5;
44
+  border-color: transparent;
45
+  border-width: 2px;
46
+  background-clip: padding-box;
47
+}
48
+::-webkit-scrollbar-thumb:hover {
49
+  border-radius: 4px;
50
+  background: #7c8db5;
51
+  background-clip: border-box;
52
+}
53
+.theme_color_h:hover {
54
+  cursor: pointer;
55
+  color: #339dff;
56
+}
57
+// iview表格全局自定义样式
58
+.ivu-table {
59
+  background-color: #ffffff66;
60
+  .ivu-table-header,
61
+  .ivu-table-fixed-header {
62
+    thead tr {
63
+      background-color: #e9f0ff;
64
+      th {
65
+        padding: 12px 0;
66
+        line-height: 1;
67
+        background-color: #e9f0ff;
68
+      }
69
+    }
70
+  }
71
+  .ivu-table-fixed .ivu-table-tbody tr,
72
+  .ivu-table-fixed-right .ivu-table-tbody tr,
73
+  .ivu-table-body .ivu-table-tbody tr {
74
+    &.ivu-table-row-hover {
75
+      background-color: #ffffff;
76
+      box-shadow: 6px 1px 9px 0 #0879cd24;
77
+      td {
78
+        background-color: #ffffff;
79
+      }
80
+    }
81
+    td {
82
+      position: relative;
83
+      background-color: #ffffff66;
84
+      .tree_open_column {
85
+        display: flex;
86
+        justify-content: flex-start;
87
+        align-items: center;
88
+        .tree_column_arrow {
89
+          display: flex;
90
+          justify-content: center;
91
+          align-items: center;
92
+          padding: 6px;
93
+          cursor: pointer;
94
+          .tree_arrow {
95
+            transition: all 0.2s ease-in-out;
96
+            &.tree_arrow_down {
97
+              transform: rotate(90deg);
98
+            }
99
+          }
100
+        }
101
+        .tree_column_content {
102
+          display: flex;
103
+          justify-content: center;
104
+          align-items: center;
105
+          .column_icon {
106
+            padding: 6px;
107
+          }
108
+        }
109
+      }
110
+    }
111
+  }
112
+  .ivu-table-fixed .ivu-table-tbody tr,
113
+  .ivu-table-body .ivu-table-tbody tr {
114
+    &.ivu-table-row-hover {
115
+      td:first-child::before {
116
+        content: "";
117
+        position: absolute;
118
+        top: 0;
119
+        bottom: 0;
120
+        left: 0;
121
+        display: inline-block;
122
+        width: 4px;
123
+        height: auto;
124
+        background-color: #339dff;
125
+        z-index: 1;
126
+      }
127
+    }
128
+  }
129
+  .ivu-table-cell {
130
+    line-height: 1.6;
131
+  }
132
+  .ivu-table-overflowX{
133
+    overflow: visible;
134
+  }
135
+  .ivu-table-tip {
136
+    overflow: hidden;
137
+  }
138
+}
139
+// iview表单全局自定义样式
140
+.ivu-form {
141
+  .ivu-form-item-label {
142
+    color: #253a70;
143
+  }
144
+}
145
+// iview分页全局自定义样式
146
+.ivu-page {
147
+  .ivu-page-total {
148
+    color: #253a70;
149
+    font-weight: bold;
150
+  }
151
+  .ivu-page-item,
152
+  .ivu-page-next,
153
+  .ivu-page-prev {
154
+    border-radius: 8px;
155
+    border-color: #b8c2d9;
156
+  }
157
+  .ivu-page-item-active {
158
+    border-color: #339cff;
159
+    a {
160
+      color: #339cff;
161
+    }
162
+  }
163
+}
164
+//按钮圆角
165
+.ivu-btn,
166
+.ivu-input {
167
+  border-radius: 6px;
168
+}
169
+// 模拟输入框样式
170
+.imitate_input {
171
+  font-size: 14px;
172
+  line-height: 30px;
173
+  padding: 0 7px;
174
+  color: #515a6e;
175
+  border: 1px solid #dcdee2;
176
+  border-radius: 6px;
177
+  background-color: #fff;
178
+  text-overflow: ellipsis;
179
+  white-space: nowrap;
180
+  overflow: hidden;
181
+  &.disabled {
182
+    color: #253a70;
183
+    border-color: #d8dce9;
184
+    background-color: #f3f4fc;
185
+    cursor: not-allowed;
186
+  }
187
+}
188
+// 禁用输入框背景色
189
+.ivu-input[disabled],
190
+fieldset[disabled] .ivu-input,
191
+.ivu-select-disabled .ivu-select-selection {
192
+  color: #253a70;
193
+  border-color: #d8dce9;
194
+  background-color: #f3f4fc;
195
+  user-select: none;
196
+}
197
+// 二级路由页面全局样式
198
+.page_root {
199
+  width: 100%;
200
+  height: 100%;
201
+  .page_root_main {
202
+    margin-right: 16px;
203
+    margin-bottom: 16px;
204
+    padding: 16px;
205
+    width: calc(100% - 16px);
206
+    height: calc(100% - 16px);
207
+    border-radius: 10px;
208
+    background: #ffffff66;
209
+    border: 2px solid #fff;
210
+    box-shadow: 0 12px 16px 0 #0000000a;
211
+    overflow: auto;
212
+  }
213
+}
214
+// iview颜色拾取器
215
+.color_picker_transfer {
216
+  width: 260px;
217
+}
218
+// 更多菜单弹窗
219
+.more_menu {
220
+  position: fixed;
221
+  left: -999999999999px;
222
+  top: -999999999999px;
223
+  display: none;
224
+  padding: 10px 0;
225
+  width: 152px;
226
+  font-size: 12px;
227
+  border-radius: 6px;
228
+  background: #fff;
229
+  box-shadow: 0 12px 16px 0 #798cb524;
230
+  border: 1px solid #ced9f2;
231
+  z-index: 9999999;
232
+  .menu_group {
233
+    .group_separator {
234
+      margin: 2px 0;
235
+      width: 100%;
236
+      height: 1px;
237
+      background: #ced9f2;
238
+    }
239
+    &:last-child {
240
+      .group_separator {
241
+        display: none;
242
+      }
243
+    }
244
+    .menu_group_item {
245
+      position: relative;
246
+      line-height: 35px;
247
+      text-align: left;
248
+      cursor: pointer;
249
+      .menu_group_item_pop {
250
+        display: none;
251
+      }
252
+      &:hover {
253
+        background-color: #dbeeffcc;
254
+        .menu_group_item_pop {
255
+          display: block;
256
+          position: absolute;
257
+          top: -10px;
258
+          left: 150px;
259
+          padding: 10px 0;
260
+          width: 152px;
261
+          border-radius: 6px;
262
+          background: #fff;
263
+          box-shadow: 0 12px 16px 0 #798cb524;
264
+          border: 1px solid #ced9f2;
265
+          cursor: pointer;
266
+          .menu_pop_group {
267
+            .menu_pop_group_item {
268
+              position: relative;
269
+              padding: 0 14px;
270
+              line-height: 35px;
271
+              text-align: left;
272
+              cursor: pointer;
273
+              overflow: hidden;
274
+              text-overflow: ellipsis;
275
+              white-space: nowrap;
276
+              &:hover {
277
+                background-color: #dbeeffcc;
278
+              }
279
+            }
280
+            .pop_group_separator {
281
+              margin: 2px 0;
282
+              width: 100%;
283
+              height: 1px;
284
+              background: #ced9f2;
285
+            }
286
+            &:last-child {
287
+              .pop_group_separator {
288
+                display: none;
289
+              }
290
+            }
291
+          }
292
+        }
293
+      }
294
+      .menu_group_item_main {
295
+        display: flex;
296
+        justify-content: space-between;
297
+        align-items: center;
298
+        .menu_title {
299
+          margin-left: 14px;
300
+          width: calc(100% - 28px);
301
+          overflow: hidden;
302
+          text-overflow: ellipsis;
303
+          white-space: nowrap;
304
+        }
305
+        .menu_dropright {
306
+          display: flex;
307
+          justify-content: center;
308
+          align-items: center;
309
+          width: 14px;
310
+        }
311
+      }
312
+    }
313
+  }
314
+}
315
+// 多选框禁用时选中颜色修改
316
+.ivu-checkbox-disabled {
317
+  &.ivu-checkbox-checked .ivu-checkbox-inner,
318
+  .ivu-checkbox-inner {
319
+    background-color: #D2DBF3;
320
+    border-color: #98AAE1;
321
+    &:after {
322
+      border-color: #253A70;
323
+    }
324
+  }
325
+}
326
+// 没有权限禁止操作
327
+.no_auth {
328
+  cursor: not-allowed !important;
329
+}
330
+// 可关闭的错误消息可复制消息
331
+.ivu-message-custom-content.ivu-message-error {
332
+  user-select: text;
333
+}

+ 71
- 0
src/assets/less/customModal.less ファイルの表示

@@ -0,0 +1,71 @@
1
+.modal1 {
2
+  .ivu-modal {
3
+    width: 50% !important;
4
+    min-width: 1000px;
5
+  }
6
+}
7
+.modal2 {
8
+  .ivu-modal {
9
+    width: 70% !important;
10
+  }
11
+}
12
+.modal3 {
13
+  .ivu-modal {
14
+    width: 300px !important;
15
+  }
16
+}
17
+.modal4 {
18
+  .ivu-modal {
19
+    width: 30% !important;
20
+    min-width: 500px;
21
+  }
22
+}
23
+
24
+.modal5 {
25
+  .ivu-modal {
26
+    width: 90% !important;
27
+    min-width: 500px;
28
+  }
29
+}
30
+.modal_tip {
31
+  .ivu-modal {
32
+    width: 450px !important;
33
+  }
34
+}
35
+.ivu-modal-content {
36
+  border-radius: 16px;
37
+  overflow: hidden;
38
+  .ivu-modal-header {
39
+    padding: 13px 16px !important;
40
+    border-bottom: none;
41
+    // 设置弥散渐变
42
+    background-image: url("~@/assets/img/dispersion_gradient1.png");
43
+    background-size: cover;
44
+    background-repeat: no-repeat;
45
+    background-position: center;
46
+    .ivu-modal-header-inner {
47
+      font-size: 16px !important;
48
+      color: #253A70;
49
+    }
50
+  }
51
+  .ivu-modal-close {
52
+    top: 4px;
53
+    .ivu-icon-ios-close:before {
54
+      color: #253A70;
55
+      font-size: 36px;
56
+      font-weight: 600;
57
+    }
58
+  }
59
+  .ivu-modal-footer {
60
+    border-top: none;
61
+
62
+  }
63
+}
64
+
65
+.ivu-modal-body {
66
+  max-height: calc(100vh - 260px);
67
+  overflow: auto;
68
+}
69
+.ivu-modal-fullscreen .ivu-modal-body {
70
+  max-height: none !important;
71
+}

+ 174
- 0
src/assets/less/reset.less ファイルの表示

@@ -0,0 +1,174 @@
1
+div,
2
+span,
3
+object,
4
+iframe,
5
+h1,
6
+h2,
7
+h3,
8
+h4,
9
+h5,
10
+h6,
11
+p,
12
+blockquote,
13
+pre,
14
+abbr,
15
+address,
16
+cite,
17
+code,
18
+del,
19
+dfn,
20
+em,
21
+img,
22
+ins,
23
+kbd,
24
+q,
25
+samp,
26
+small,
27
+strong,
28
+sub,
29
+sup,
30
+var,
31
+b,
32
+i,
33
+dl,
34
+dt,
35
+dd,
36
+ol,
37
+ul,
38
+li,
39
+fieldset,
40
+form,
41
+label,
42
+legend,
43
+table,
44
+caption,
45
+tbody,
46
+tfoot,
47
+thead,
48
+tr,
49
+th,
50
+td,
51
+article,
52
+aside,
53
+canvas,
54
+details,
55
+figcaption,
56
+figure,
57
+footer,
58
+header,
59
+hgroup,
60
+menu,
61
+nav,
62
+section,
63
+summary,
64
+time,
65
+mark,
66
+audio,
67
+video {
68
+  margin: 0;
69
+  padding: 0;
70
+  border: 0;
71
+  outline: 0;
72
+  font-size: 100%;
73
+  vertical-align: baseline;
74
+  background: transparent;
75
+  box-sizing: border-box;
76
+}
77
+
78
+body {
79
+  line-height: 1;
80
+}
81
+
82
+:focus {
83
+  outline: 1;
84
+}
85
+
86
+article,
87
+aside,
88
+canvas,
89
+details,
90
+figcaption,
91
+figure,
92
+footer,
93
+header,
94
+hgroup,
95
+menu,
96
+nav,
97
+section,
98
+summary {
99
+  display: block;
100
+}
101
+
102
+ul {
103
+  list-style: none;
104
+}
105
+
106
+blockquote,
107
+q {
108
+  quotes: none;
109
+}
110
+
111
+blockquote:before,
112
+blockquote:after,
113
+q:before,
114
+q:after {
115
+  content: "";
116
+  content: none;
117
+}
118
+
119
+a {
120
+  margin: 0;
121
+  padding: 0;
122
+  border: 0;
123
+  font-size: 100%;
124
+  vertical-align: baseline;
125
+  background: transparent;
126
+}
127
+
128
+ins {
129
+  background-color: #ff9;
130
+  color: #000;
131
+  text-decoration: none;
132
+}
133
+
134
+mark {
135
+  background-color: #ff9;
136
+  color: #000;
137
+  font-style: italic;
138
+  font-weight: bold;
139
+}
140
+
141
+del {
142
+  text-decoration: line-through;
143
+}
144
+
145
+abbr[title],
146
+dfn[title] {
147
+  border-bottom: 1px dotted #000;
148
+  cursor: help;
149
+}
150
+
151
+table {
152
+  border-collapse: collapse;
153
+  border-spacing: 0;
154
+}
155
+
156
+hr {
157
+  display: block;
158
+  height: 1px;
159
+  border: 0;
160
+  border-top: 1px solid #cccccc;
161
+  margin: 1em 0;
162
+  padding: 0;
163
+}
164
+
165
+// 清除浮动
166
+.clearfix:before,
167
+.clearfix:after {
168
+  content: " ";
169
+  display: table;
170
+}
171
+
172
+.clearfix:after {
173
+  clear: both;
174
+}

+ 70
- 0
src/assets/less/rootPage.less ファイルの表示

@@ -0,0 +1,70 @@
1
+.root_main_box {
2
+  display: flex;
3
+  justify-content: space-between;
4
+  height: calc(100% - 50px);
5
+  overflow: hidden;
6
+  > .root_main_tree {
7
+    width: 266px;
8
+    height: 100%;
9
+    overflow: hidden;
10
+    box-shadow: 0 0 30px 0 #95abdf33;
11
+    &.hide_left {
12
+      display: none;
13
+    }
14
+    > .main_tree_top {
15
+      display: flex;
16
+      justify-content: center;
17
+      align-items: center;
18
+      margin: 10px;
19
+      .search_input {
20
+        // width: calc(100% - 38px);
21
+        width: 100%;
22
+        /deep/.ivu-input {
23
+          border: none;
24
+          &:focus {
25
+            box-shadow: none;
26
+          }
27
+        }
28
+      }
29
+    }
30
+    > .tree_list_box {
31
+      margin-top: 10px;
32
+      height: calc(100% - 52px);
33
+      box-shadow: 0 0 30px 0 #95abdf33;
34
+      border-radius: 4px;
35
+      background-color: #ffffff66;
36
+      overflow: hidden;
37
+      &:hover {
38
+        overflow: auto;
39
+      }
40
+    }
41
+  }
42
+  .root_main_content {
43
+    width: calc(100% - 282px);
44
+    height: 100%;
45
+    overflow: hidden;
46
+    &.full_right {
47
+      width: 100% !important;
48
+      /deep/ .page_root,
49
+      /deep/ .nav_page_root,
50
+      /deep/ .navigation_list {
51
+        padding-left: 16px;
52
+      }
53
+    }
54
+    > .navigation_list {
55
+      display: flex;
56
+      justify-content: flex-start;
57
+      align-items: center;
58
+      height: 52px;
59
+      .move_btn {
60
+        transform: rotate(90deg);
61
+        cursor: e-resize;
62
+      }
63
+    }
64
+    > .navigation_content {
65
+      width: 100%;
66
+      height: calc(100% - 52px);
67
+      overflow: auto;
68
+    }
69
+  }
70
+}

+ 467
- 0
src/components/ImgPreview/ImgPreview.vue ファイルの表示

@@ -0,0 +1,467 @@
1
+<template>
2
+  <div>
3
+    <div id="imgPreviewContainer" ref="imgPreviewContainer"><slot></slot></div>
4
+    <div ref="imgPreviewMask">
5
+      <Transition name="fade">
6
+        <div v-if="showPreview" class="image_preview_mask"></div>
7
+      </Transition>
8
+      <Transition name="fade">
9
+        <div class="image_preview_wrap" v-if="showPreview">
10
+          <div
11
+            class="image_preview"
12
+            ref="imagePreview"
13
+            @click.stop="handleOperation('close')"
14
+          >
15
+            <img
16
+              :class="imgClasses"
17
+              :style="imageStyle"
18
+              :src="currentSrc"
19
+              @click.stop
20
+              @load="setImgScale"
21
+              @error="imgLoadError"
22
+              @mousedown.stop.prevent="handleMousedown"
23
+            />
24
+            <div class="image_preview_operations">
25
+              <div class="img_name">
26
+                {{ currentImgName }}
27
+                <span v-if="originalSize.width && originalSize.height"
28
+                  >({{ originalSize.width }} *
29
+                  {{ originalSize.height }})</span
30
+                >
31
+              </div>
32
+              <div class="operations_btn_box">
33
+                <div class="operations_btn_main">
34
+                  <div title="放大" @click.stop="handleOperation('zoomIn')">
35
+                    <svg
36
+                      class="operations_btn_item"
37
+                      viewBox="0 0 1024 1024"
38
+                      version="1.1"
39
+                      xmlns="http://www.w3.org/2000/svg"
40
+                      p-id="7197"
41
+                      width="200"
42
+                      height="200"
43
+                    >
44
+                      <path
45
+                        d="M637 443H519V309c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v134H325c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h118v134c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V519h118c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"
46
+                        p-id="7198"
47
+                        fill="#ffffff"
48
+                      ></path>
49
+                      <path
50
+                        d="M921 867L775 721c122.1-148.9 113.6-369.5-26-509-148-148.1-388.4-148.1-537 0-148.1 148.6-148.1 389 0 537 139.5 139.6 360.1 148.1 509 26l146 146c3.2 2.8 8.3 2.8 11 0l43-43c2.8-2.7 2.8-7.8 0-11zM696 696c-118.8 118.7-311.2 118.7-430 0-118.7-118.8-118.7-311.2 0-430 118.8-118.7 311.2-118.7 430 0 118.7 118.8 118.7 311.2 0 430z"
51
+                        p-id="7199"
52
+                        fill="#ffffff"
53
+                      ></path>
54
+                    </svg>
55
+                  </div>
56
+                  <div title="缩小" @click.stop="handleOperation('zoomOut')">
57
+                    <svg
58
+                      class="operations_btn_item"
59
+                      viewBox="0 0 1024 1024"
60
+                      version="1.1"
61
+                      xmlns="http://www.w3.org/2000/svg"
62
+                      p-id="7412"
63
+                      width="200"
64
+                      height="200"
65
+                    >
66
+                      <path
67
+                        d="M637 443H325c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h312c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8z"
68
+                        p-id="7413"
69
+                        fill="#ffffff"
70
+                      ></path>
71
+                      <path
72
+                        d="M921 867L775 721c122.1-148.9 113.6-369.5-26-509-148-148.1-388.4-148.1-537 0-148.1 148.6-148.1 389 0 537 139.5 139.6 360.1 148.1 509 26l146 146c3.2 2.8 8.3 2.8 11 0l43-43c2.8-2.7 2.8-7.8 0-11zM696 696c-118.8 118.7-311.2 118.7-430 0-118.7-118.8-118.7-311.2 0-430 118.8-118.7 311.2-118.7 430 0 118.7 118.8 118.7 311.2 0 430z"
73
+                        p-id="7414"
74
+                        fill="#ffffff"
75
+                      ></path>
76
+                    </svg>
77
+                  </div>
78
+                  <div
79
+                    title="向左旋转"
80
+                    @click.stop="handleOperation('rotateLeft')"
81
+                  >
82
+                    <svg
83
+                      class="operations_btn_item"
84
+                      viewBox="0 0 1024 1024"
85
+                      version="1.1"
86
+                      xmlns="http://www.w3.org/2000/svg"
87
+                      p-id="13308"
88
+                      width="200"
89
+                      height="200"
90
+                    >
91
+                      <path
92
+                        d="M672 418H144c-17.7 0-32 14.3-32 32v414c0 17.7 14.3 32 32 32h528c17.7 0 32-14.3 32-32V450c0-17.7-14.3-32-32-32z m-44 402H188V494h440v326z m191.3-491.5c-78.8-100.7-196-153.6-314.6-154.2l-0.2-64c0-6.5-7.6-10.1-12.6-6.1l-128 101c-4 3.1-3.9 9.1 0 12.3L492 318.6c5.1 4 12.7 0.4 12.6-6.1v-63.9c12.9 0.1 25.9 0.9 38.8 2.5 42.1 5.2 82.1 18.2 119 38.7 38.1 21.2 71.2 49.7 98.4 84.3 27.1 34.7 46.7 73.7 58.1 115.8 11 40.7 14 82.7 8.9 124.8-0.7 5.4-1.4 10.8-2.4 16.1h74.9c14.8-103.6-11.3-213-81-302.3z"
93
+                        p-id="13309"
94
+                        fill="#ffffff"
95
+                      ></path>
96
+                    </svg>
97
+                  </div>
98
+                  <div
99
+                    title="向右旋转"
100
+                    @click.stop="handleOperation('rotateRight')"
101
+                  >
102
+                    <svg
103
+                      class="operations_btn_item"
104
+                      viewBox="0 0 1024 1024"
105
+                      version="1.1"
106
+                      xmlns="http://www.w3.org/2000/svg"
107
+                      p-id="13521"
108
+                      width="200"
109
+                      height="200"
110
+                    >
111
+                      <path
112
+                        d="M480.5 251.2c13-1.6 25.9-2.4 38.8-2.5v63.9c0 6.5 7.5 10.1 12.6 6.1L660 217.6c4-3.2 4-9.2 0-12.3l-128-101c-5.1-4-12.6-0.4-12.6 6.1l-0.2 64c-118.6 0.5-235.8 53.4-314.6 154.2-69.6 89.2-95.7 198.6-81.1 302.4h74.9c-0.9-5.3-1.7-10.7-2.4-16.1-5.1-42.1-2.1-84.1 8.9-124.8 11.4-42.2 31-81.1 58.1-115.8 27.2-34.7 60.3-63.2 98.4-84.3 37-20.6 76.9-33.6 119.1-38.8zM880 418H352c-17.7 0-32 14.3-32 32v414c0 17.7 14.3 32 32 32h528c17.7 0 32-14.3 32-32V450c0-17.7-14.3-32-32-32z m-44 402H396V494h440v326z"
113
+                        p-id="13522"
114
+                        fill="#ffffff"
115
+                      ></path>
116
+                    </svg>
117
+                  </div>
118
+                  <div
119
+                    v-if="images && images.length > 1"
120
+                    title="上一张"
121
+                    @click.stop="handleOperation('previous')"
122
+                  >
123
+                    <Icon class="operations_btn_item" type="ios-arrow-back" />
124
+                  </div>
125
+                  <div
126
+                    v-if="images && images.length > 1"
127
+                    title="下一张"
128
+                    @click.stop="handleOperation('next')"
129
+                  >
130
+                    <Icon
131
+                      class="operations_btn_item"
132
+                      type="ios-arrow-forward"
133
+                    />
134
+                  </div>
135
+                  <div title="关闭" @click.stop="handleOperation('close')">
136
+                    <Icon class="operations_btn_item" type="md-close" />
137
+                  </div>
138
+                </div>
139
+              </div>
140
+            </div>
141
+          </div>
142
+        </div>
143
+      </Transition>
144
+    </div>
145
+  </div>
146
+</template>
147
+
148
+<script>
149
+import KeyCode from "@/utils/keyCode";
150
+import { on, off } from "@/utils/dom";
151
+export default {
152
+  props: {
153
+    images: {
154
+      type: Array,
155
+      default: function () {
156
+        return [];
157
+      }
158
+    }
159
+  },
160
+  data() {
161
+    return {
162
+      // 图片原始尺寸
163
+      originalSize: {
164
+        width: 0,
165
+        height: 0
166
+      },
167
+      isAddScale: false,
168
+      scale: 1,
169
+      degree: 0,
170
+      translate: { x: 0, y: 0 },
171
+      startX: 0,
172
+      startY: 0,
173
+      transition: true,
174
+      showPreview: false,
175
+      currentSrc: "",
176
+      previewIndex: 0,
177
+      changeTimer: null
178
+    };
179
+  },
180
+  computed: {
181
+    currentImgName() {
182
+      let _url = this.currentSrc;
183
+      if (!_url || _url.startsWith("data:image/")) {
184
+        return "";
185
+      }
186
+      return _url.slice(_url.lastIndexOf("/") + 1);
187
+    },
188
+    imgClasses() {
189
+      return [
190
+        "image_preview_image",
191
+        {
192
+          ["image_preview_transition"]: this.transition
193
+        }
194
+      ];
195
+    },
196
+    imageStyle() {
197
+      let translateX = this.translate.x / this.scale;
198
+      let translateY = this.translate.y / this.scale;
199
+      const mod = this.degree % 360;
200
+      if ([90, -270].includes(mod)) {
201
+        [translateX, translateY] = [translateY, -translateX];
202
+      }
203
+      if ([180, -180].includes(mod)) {
204
+        [translateX, translateY] = [-translateX, -translateY];
205
+      }
206
+      if ([270, -90].includes(mod)) {
207
+        [translateX, translateY] = [-translateY, translateX];
208
+      }
209
+      return {
210
+        transform: `scale(${this.scale}) rotate(${this.degree}deg) translate(${translateX}px, ${translateY}px)`
211
+      };
212
+    }
213
+  },
214
+  mounted() {
215
+    on(document, "keydown", this.handleKeydown);
216
+    on(document, "keyup", this.handleKeyup);
217
+    on(document, "wheel", this.handleWheel);
218
+    on(this.$refs.imgPreviewContainer, "click", this.containerImgsClick);
219
+    this.$nextTick(() => {
220
+      const body = document.querySelector("body");
221
+      if (body.append) {
222
+        body.append(this.$refs.imgPreviewMask);
223
+      } else {
224
+        body.appendChild(this.$refs.imgPreviewMask);
225
+      }
226
+    });
227
+  },
228
+  beforeDestroy() {
229
+    off(document, "keydown", this.handleKeydown);
230
+    off(document, "keyup", this.handleKeyup);
231
+    off(document, "wheel", this.handleWheel);
232
+    off(this.$refs.imgPreviewContainer, "click", this.containerImgsClick);
233
+    if (this.changeTimer) {
234
+      clearTimeout(this.changeTimer);
235
+      this.changeTimer = null;
236
+    }
237
+  },
238
+  methods: {
239
+    // 图片加载失败
240
+    imgLoadError() {
241
+      this.originalSize.width = 0;
242
+      this.originalSize.height = 0;
243
+    },
244
+    // 图片加载完成
245
+    setImgScale(event) {
246
+      let imgEl = event.target;
247
+      let imgWith = imgEl.offsetWidth;
248
+      this.originalSize.width = imgWith;
249
+      let imgHeight = imgEl.offsetHeight;
250
+      this.originalSize.height = imgHeight;
251
+      let _maskW = this.$refs.imagePreview.offsetWidth;
252
+      let _maskH = this.$refs.imagePreview.offsetHeight;
253
+      let _wScale = 1;
254
+      let _hScale = 1;
255
+      if (imgWith > _maskW) {
256
+        _wScale = _maskW / imgWith;
257
+      }
258
+      if (imgHeight > _maskH) {
259
+        _hScale = _maskH / imgHeight;
260
+      }
261
+      let scale = _wScale > _hScale ? _hScale : _wScale;
262
+      if (this.changeTimer) {
263
+        clearTimeout(this.changeTimer);
264
+        this.changeTimer = null;
265
+      }
266
+      this.changeTimer = setTimeout(() => {
267
+        this.resetStyle(scale);
268
+      }, 100);
269
+    },
270
+    containerImgsClick(event) {
271
+      this.$refs.imgPreviewContainer
272
+        .getElementsByTagName("img")
273
+        .forEach((imgDom, imgIndex) => {
274
+          imgDom.setAttribute("preview_index", imgIndex);
275
+        });
276
+      let previewIndex = event.target.getAttribute("preview_index");
277
+      let selectUrl = event.target.src;
278
+      if (selectUrl) {
279
+        selectUrl = decodeURI(selectUrl);
280
+        if (this.images.includes(selectUrl)) {
281
+          this.currentSrc = selectUrl;
282
+          this.previewIndex = Number(previewIndex);
283
+          this.showPreview = true;
284
+        }
285
+      }
286
+      event.stopPropagation();
287
+    },
288
+    resetStyle(scale = 1) {
289
+      this.scale = scale;
290
+      // 就近纠正,防止切换图片后旋转多圈
291
+      let _degree = this.degree % 360;
292
+      if (_degree > 0) {
293
+        if (_degree >= 180) {
294
+          this.degree = this.degree + 360 - _degree;
295
+        } else {
296
+          this.degree = this.degree - _degree;
297
+        }
298
+      } else if (_degree < 0) {
299
+        if (_degree >= -180) {
300
+          this.degree = this.degree - (360 + _degree);
301
+        } else {
302
+          this.degree = this.degree - _degree;
303
+        }
304
+      }
305
+      this.translate.x = 0;
306
+      this.translate.y = 0;
307
+    },
308
+    handleOperation(operationType) {
309
+      if (operationType === "zoomIn" && this.scale < 6) this.scale += 0.25;
310
+      if (operationType === "zoomOut" && this.scale > 0.25) this.scale -= 0.25;
311
+      if (operationType === "rotateLeft") this.degree -= 90;
312
+      if (operationType === "rotateRight") this.degree += 90;
313
+      if (operationType === "previous") {
314
+        if (this.previewIndex === 0) {
315
+          this.previewIndex = this.images.length - 1;
316
+        } else {
317
+          this.previewIndex -= 1;
318
+        }
319
+        this.currentSrc = this.images[this.previewIndex];
320
+        if (this.isAddScale) {
321
+          this.scale += 0.02;
322
+        } else {
323
+          this.scale -= 0.02;
324
+        }
325
+        this.isAddScale = !this.isAddScale;
326
+      }
327
+      if (operationType === "next") {
328
+        if (this.previewIndex + 1 === this.images.length) {
329
+          this.previewIndex = 0;
330
+        } else {
331
+          this.previewIndex += 1;
332
+        }
333
+        this.currentSrc = this.images[this.previewIndex];
334
+        if (this.isAddScale) {
335
+          this.scale += 0.02;
336
+        } else {
337
+          this.scale -= 0.02;
338
+        }
339
+        this.isAddScale = !this.isAddScale;
340
+      }
341
+      if (operationType === "close") {
342
+        this.showPreview = false;
343
+        this.resetStyle();
344
+      }
345
+    },
346
+    handleMousedown(event) {
347
+      const { pageX, pageY, which } = event;
348
+      if (which !== 1) return;
349
+      this.startX = pageX;
350
+      this.startY = pageY;
351
+      this.transition = false;
352
+      on(document, "mousemove", this.handleMousemove);
353
+      on(document, "mouseup", this.handleMouseup);
354
+    },
355
+    handleMousemove(event) {
356
+      event.stopPropagation();
357
+      const { pageX, pageY } = event;
358
+      this.translate.x += pageX - this.startX;
359
+      this.translate.y += pageY - this.startY;
360
+      this.startX = pageX;
361
+      this.startY = pageY;
362
+    },
363
+    handleMouseup() {
364
+      this.transition = true;
365
+      off(document, "mousemove", this.handleMousemove);
366
+      off(document, "mouseup", this.handleMouseup);
367
+    },
368
+    handleKeydown(event) {
369
+      if (!this.showPreview) return;
370
+      const { keyCode } = event;
371
+      if (keyCode === KeyCode.LEFT) this.handleOperation("previous");
372
+      if (keyCode === KeyCode.RIGHT) this.handleOperation("next");
373
+      if (keyCode === KeyCode.UP) this.handleOperation("zoomIn");
374
+      if (keyCode === KeyCode.DOWN) this.handleOperation("zoomOut");
375
+    },
376
+    handleKeyup(event) {
377
+      if (!this.showPreview) return;
378
+      const { keyCode } = event;
379
+      if (keyCode === KeyCode.ESC) this.handleOperation("close");
380
+    },
381
+    handleWheel(event) {
382
+      if (!this.showPreview) return;
383
+      const { deltaY } = event;
384
+      this.handleOperation(deltaY < 0 ? "zoomIn" : "zoomOut");
385
+    }
386
+  }
387
+};
388
+</script>
389
+
390
+<style scoped lang="less">
391
+#imgPreviewContainer img {
392
+  cursor: pointer;
393
+}
394
+.image_preview_mask {
395
+  position: fixed;
396
+  top: 0;
397
+  bottom: 0;
398
+  left: 0;
399
+  right: 0;
400
+  background-color: rgba(55, 55, 55, 0.6);
401
+  height: 100%;
402
+  z-index: 9999;
403
+}
404
+.image_preview_wrap {
405
+  position: fixed;
406
+  top: 0;
407
+  right: 0;
408
+  bottom: 0;
409
+  left: 0;
410
+  z-index: 9999;
411
+  user-select: none;
412
+  overflow: hidden;
413
+  .image_preview {
414
+    position: relative;
415
+    display: flex;
416
+    justify-content: center;
417
+    align-items: center;
418
+    height: 100%;
419
+    .image_preview_image {
420
+      cursor: grab;
421
+    }
422
+    .image_preview_transition {
423
+      transition: transform 0.3s ease;
424
+    }
425
+    .image_preview_operations {
426
+      position: absolute;
427
+      left: 0;
428
+      right: 0;
429
+      bottom: 30px;
430
+      margin: 0 auto;
431
+      text-align: center;
432
+      .img_name {
433
+        margin-bottom: 10px;
434
+        font-size: 12px;
435
+        color: #ccc;
436
+        line-height: 20px;
437
+        white-space: nowrap;
438
+      }
439
+      .operations_btn_box {
440
+        display: flex;
441
+        justify-content: center;
442
+        align-items: center;
443
+        .operations_btn_main {
444
+          display: flex;
445
+          justify-content: center;
446
+          align-items: center;
447
+          background: rgba(55, 55, 55, 0.4);
448
+          border-radius: 4px;
449
+          overflow: hidden;
450
+          .operations_btn_item {
451
+            margin: 0 6px;
452
+            padding: 4px 8px;
453
+            width: 36px;
454
+            height: 40px;
455
+            line-height: 32px;
456
+            font-size: 18px;
457
+            color: #fff;
458
+            text-align: center;
459
+            cursor: pointer;
460
+            transition: opacity 0.1s ease-in-out;
461
+          }
462
+        }
463
+      }
464
+    }
465
+  }
466
+}
467
+</style>

+ 69
- 0
src/components/ImgPreview/index.js ファイルの表示

@@ -0,0 +1,69 @@
1
+import ImgPreview from "./ImgPreview.vue";
2
+function setPreview(Vue, el) {
3
+  if (el.nodeName.toLowerCase() === "img") {
4
+    let imgUrl = el.src;
5
+    if (imgUrl) {
6
+      el.style.cursor = "pointer";
7
+      el.onclick = () => {
8
+        let _ImgPreview = Vue.extend(ImgPreview);
9
+        const instance = new _ImgPreview({
10
+          propsData: {
11
+            images: [imgUrl]
12
+          }
13
+        });
14
+        instance.$mount();
15
+        document.body.appendChild(instance.$el);
16
+        instance.previewIndex = 0;
17
+        instance.currentSrc = imgUrl;
18
+        instance.showPreview = true;
19
+      };
20
+    }
21
+  } else {
22
+    let imgEls = el.getElementsByTagName("img");
23
+    let imgUrls = [];
24
+    for (let imgIndex = 0; imgIndex < imgEls.length; imgIndex++) {
25
+      let imgEl = imgEls[imgIndex];
26
+      imgEl.setAttribute("preview_index", imgIndex);
27
+      let imgUrl = imgEl.src;
28
+      if (imgUrl) {
29
+        imgUrls.push(imgUrl);
30
+      }
31
+    }
32
+    for (const imgEl of imgEls) {
33
+      let imgIndex = imgEl.getAttribute("preview_index");
34
+      let imgUrl = imgEl.src;
35
+      if (imgUrl) {
36
+        imgEl.style.cursor = "pointer";
37
+        imgEl.onclick = () => {
38
+          let _ImgPreview = Vue.extend(ImgPreview);
39
+          const instance = new _ImgPreview({
40
+            propsData: {
41
+              images: imgUrls
42
+            }
43
+          });
44
+          instance.$mount();
45
+          document.body.appendChild(instance.$el);
46
+          instance.$nextTick(() => {
47
+            instance.currentSrc = imgUrl;
48
+            instance.previewIndex = Number(imgIndex);
49
+            instance.showPreview = true;
50
+          });
51
+        };
52
+      }
53
+    }
54
+  }
55
+}
56
+const installObj = {
57
+  install: function (Vue) {
58
+    Vue.component("ImgPreview", ImgPreview);
59
+    Vue.directive("preview", {
60
+      inserted: function (el) {
61
+        setPreview(Vue, el);
62
+      },
63
+      componentUpdated: function (el) {
64
+        setPreview(Vue, el);
65
+      }
66
+    });
67
+  }
68
+};
69
+export default installObj;

+ 29
- 0
src/main.js ファイルの表示

@@ -0,0 +1,29 @@
1
+import Vue from "vue";
2
+import ViewUI from "view-design";
3
+import axios from "axios";
4
+import uploader from "vue-simple-uploader";
5
+import App from "./App.vue";
6
+import router from "./router";
7
+import store from "./store";
8
+import { message } from "@/utils/resetMessage.js";
9
+import ImgPreview from "./components/ImgPreview";
10
+
11
+Vue.use(uploader);
12
+Vue.use(ViewUI);
13
+Vue.use(ImgPreview);
14
+Vue.prototype.$Message = message;
15
+Vue.prototype.$api = window._config;
16
+// 全局事件总线
17
+Vue.prototype.$EventBus = new Vue();
18
+
19
+axios.defaults.baseURL = window._config.baseUrl;
20
+Vue.prototype.axios = axios;
21
+window.axios = axios;
22
+
23
+Vue.config.productionTip = false;
24
+
25
+window.vue = new Vue({
26
+  router,
27
+  store,
28
+  render: (h) => h(App)
29
+}).$mount("#app");

+ 113
- 0
src/router/index.js ファイルの表示

@@ -0,0 +1,113 @@
1
+import Vue from "vue";
2
+import VueRouter from "vue-router";
3
+Vue.use(VueRouter);
4
+function queryStorage(location) {
5
+  if (location instanceof Object && location.path) {
6
+    let _location = {};
7
+    _location.path = location.path;
8
+    let _queryStorage = sessionStorage.getItem("_queryStorage");
9
+    _queryStorage = _queryStorage ? JSON.parse(_queryStorage) : {};
10
+    if (location.query) {
11
+      _queryStorage[location.path] = location.query;
12
+      _location.query = location.query;
13
+    } else {
14
+      if (
15
+        _queryStorage[location.path] &&
16
+        window.location.href.includes(location.path)
17
+      ) {
18
+        _location.query = _queryStorage[location.path];
19
+      }
20
+    }
21
+    sessionStorage.setItem("_queryStorage", JSON.stringify(_queryStorage));
22
+    return _location;
23
+  }
24
+  return location;
25
+}
26
+const routerPush = VueRouter.prototype.push;
27
+VueRouter.prototype.push = function push(location) {
28
+  let newLocation = queryStorage(location);
29
+  return routerPush.call(this, newLocation).catch((error) => error);
30
+};
31
+const originalReplace = VueRouter.prototype.replace;
32
+VueRouter.prototype.replace = function replace(location) {
33
+  let newLocation = queryStorage(location);
34
+  return originalReplace.call(this, newLocation).catch((err) => err);
35
+};
36
+const createRouter = () =>
37
+  new VueRouter({
38
+    scrollBehavior: () => ({
39
+      y: 0
40
+    }),
41
+    routes: [
42
+      /* {
43
+        path: "/login",
44
+        name: "login",
45
+        component: () => import("@/views/login/login.vue"),
46
+        meta: {
47
+          // 缓存
48
+          keepAlive: true,
49
+          // 需要登录权限
50
+          isAuth: false,
51
+          // 路由名称
52
+          title: "登录"
53
+        }
54
+      }, */
55
+      {
56
+        path: "/",
57
+        component: () => import("@/views/layout.vue"),
58
+        name: "layout"
59
+        // redirect: {
60
+        //   path: "/"
61
+        // },
62
+        // children: []
63
+      }
64
+    ]
65
+  });
66
+const router = createRouter();
67
+/**
68
+ * 路由守卫(拦截)
69
+ */
70
+router.beforeEach((to, from, next) => {
71
+  if (!to.meta.isAuth) {
72
+    next();
73
+  } else {
74
+    /**
75
+     * bi_userInfo 登录用户信息
76
+     * {content, datetime}
77
+     */
78
+    let _userInfo = localStorage.getItem("bi_userInfo");
79
+    if (_userInfo) {
80
+      _userInfo = JSON.parse(_userInfo) || {};
81
+      if (_userInfo.content) {
82
+        const bi_userInfo = _userInfo.content;
83
+        const datetime = _userInfo.datetime;
84
+        const nowtime = new Date().getTime();
85
+        let diff = nowtime - datetime;
86
+        if (bi_userInfo && diff < 1000 * 60 * 60 * 24) {
87
+          _userInfo.datetime = nowtime;
88
+          localStorage.setItem("bi_userInfo", JSON.stringify(_userInfo));
89
+          next();
90
+        } else {
91
+          console.log("文件名:router index.vue,退出原因:超过24小时未登录");
92
+          next({
93
+            path: "/login",
94
+            query: to.query
95
+          });
96
+        }
97
+      } else {
98
+        console.log("文件名:router index.vue,退出原因:userInfo不存在1");
99
+        next({
100
+          path: "/login",
101
+          query: to.query
102
+        });
103
+      }
104
+    } else {
105
+      console.log("文件名:router index.vue,退出原因:userInfo不存在2");
106
+      next({
107
+        path: "/login",
108
+        query: to.query
109
+      });
110
+    }
111
+  }
112
+});
113
+export default router;

+ 9
- 0
src/store/index.js ファイルの表示

@@ -0,0 +1,9 @@
1
+import Vue from "vue";
2
+import Vuex from "vuex";
3
+Vue.use(Vuex);
4
+
5
+export default new Vuex.Store({
6
+  state: {},
7
+  mutations: {},
8
+  actions: {}
9
+});

+ 164
- 0
src/utils/httpRequest.js ファイルの表示

@@ -0,0 +1,164 @@
1
+import axios from "axios";
2
+import { message } from "@/utils/resetMessage.js";
3
+
4
+let errTimer = null;
5
+let setErrorMsg = function (err) {
6
+  let err_msg = "请求失败";
7
+  if (err.message.includes("timeout")) {
8
+    err_msg = "请求超时,请刷新后重试!";
9
+  } else if (err.message.includes("Network Error")) {
10
+    err_msg = "网络连接错误,请刷新后重试!";
11
+  }
12
+  if (errTimer) {
13
+    clearTimeout(errTimer);
14
+    errTimer = null;
15
+  }
16
+  errTimer = setTimeout(() => {
17
+    message.error(err_msg);
18
+  }, 1500);
19
+  err.message = err_msg;
20
+  return err;
21
+};
22
+const http = axios.create({
23
+  retry: 2,
24
+  retryDelay: 1000,
25
+  timeout: 1000 * window._config.axiosApiTimeout,
26
+  validateStatus: function (status) {
27
+    return status >= 200 && status <= 500; // 默认的
28
+  },
29
+  headers: {
30
+    "Content-Type": "application/json"
31
+  }
32
+});
33
+
34
+/**
35
+ * HTTP request拦截
36
+ */
37
+http.interceptors.request.use(
38
+  (config) => {
39
+    // 登录后校验账号
40
+    let bi_userInfo = localStorage.getItem("bi_userInfo");
41
+    if (bi_userInfo) {
42
+      bi_userInfo = JSON.parse(bi_userInfo).content;
43
+      if (bi_userInfo) {
44
+        config.headers["Token-Key"] = bi_userInfo.token_key;
45
+        config.headers["Token-Value"] = bi_userInfo.token_value;
46
+        // 验证登陆人
47
+        config.headers["XH-UserId"] = bi_userInfo.userid;
48
+      }
49
+    }
50
+    config.headers.st = window._config.secret;
51
+    if (window._config.secret) {
52
+      let config_data_str = JSON.stringify(config.data);
53
+      config.data = window.getEncryptedString(config_data_str);
54
+    }
55
+    return config;
56
+  },
57
+  (err) => {
58
+    err.message = "请求失败";
59
+    return Promise.reject(err);
60
+  }
61
+);
62
+
63
+/**
64
+ * HTTP response拦截
65
+ */
66
+http.interceptors.response.use(
67
+  (response) => {
68
+    let resData = response.data;
69
+    if (resData.code === 2) {
70
+      console.log(
71
+        "文件名:httpRequest.js,退出原因:" +
72
+          response.config.url +
73
+          "返回code等于2"
74
+      );
75
+      window.vue.$router.push("/login");
76
+    }
77
+    return resData;
78
+  },
79
+  function axiosRetryInterceptor(err) {
80
+    let config = (err && err.config) || {};
81
+    if (!config.retry) {
82
+      return Promise.reject(setErrorMsg(err));
83
+    }
84
+    config.__retryCount = config.__retryCount || 0;
85
+    if (config.__retryCount >= config.retry) {
86
+      return Promise.reject(setErrorMsg(err));
87
+    }
88
+    config.__retryCount += 1;
89
+    let backoff = new Promise(function (resolve) {
90
+      setTimeout(function () {
91
+        resolve();
92
+      }, config.retryDelay || 1);
93
+    });
94
+    return backoff.then(function () {
95
+      if (window._config.secret) {
96
+        let config_data_str = window.getDecryptString(config.data);
97
+        config.data = JSON.parse(config_data_str);
98
+      }
99
+      return http(config);
100
+    });
101
+  }
102
+);
103
+/**
104
+ * @param {*} prefix 微服务前缀
105
+ * @param {*} url 不带前缀的url
106
+ * @param {*} data 传参
107
+ * @returns Promise
108
+ */
109
+const setRequest = ({ prefix, url, data }) =>
110
+  http({
111
+    url: `${window._config.baseUrl}${
112
+      window._config.useMicroservice ? prefix : ""
113
+    }${url}`,
114
+    method: "post",
115
+    data: data || {}
116
+  });
117
+/**
118
+ * 微服务前缀 sdatasource/
119
+ * @param {*} url 不带前缀的url
120
+ * @param {*} data 传参
121
+ * @returns Promise
122
+ */
123
+export const sdatasource_url = (url, data) =>
124
+  setRequest({
125
+    prefix: "sdatasource/",
126
+    url,
127
+    data
128
+  });
129
+/**
130
+ * 微服务前缀 ssystem/
131
+ * @param {*} url 不带前缀的url
132
+ * @param {*} data 传参
133
+ * @returns Promise
134
+ */
135
+export const ssystem_url = (url, data) =>
136
+  setRequest({
137
+    prefix: "ssystem/",
138
+    url,
139
+    data
140
+  });
141
+/**
142
+ * 微服务前缀 sdataintegration/
143
+ * @param {*} url 不带前缀的url
144
+ * @param {*} data 传参
145
+ * @returns Promise
146
+ */
147
+export const sdataintegration_url = (url, data) =>
148
+  setRequest({
149
+    prefix: "sdataintegration/",
150
+    url,
151
+    data
152
+  });
153
+/**
154
+ * 微服务前缀 sanalysis/
155
+ * @param {*} url 不带前缀的url
156
+ * @param {*} data 传参
157
+ * @returns Promise
158
+ */
159
+export const sanalysis_url = (url, data) =>
160
+  setRequest({
161
+    prefix: "sanalysis/",
162
+    url,
163
+    data
164
+  });

+ 722
- 0
src/utils/index.js ファイルの表示

@@ -0,0 +1,722 @@
1
+// 东八区时间差
2
+let _timezone = 8; //目标时区时间,东八区   东时区正数 西时区负数
3
+let _offset_GMT = new Date().getTimezoneOffset(); // 本地时间和格林威治的时间差,单位为分钟
4
+let diffTime = _offset_GMT * 60 * 1000 + _timezone * 60 * 60 * 1000; //0
5
+export const weekDay = [
6
+  {
7
+    label: "周一",
8
+    alias: "星期一",
9
+    value: 1
10
+  },
11
+  {
12
+    label: "周二",
13
+    alias: "星期二",
14
+    value: 2
15
+  },
16
+  {
17
+    label: "周三",
18
+    alias: "星期三",
19
+    value: 3
20
+  },
21
+  {
22
+    label: "周四",
23
+    alias: "星期四",
24
+    value: 4
25
+  },
26
+  {
27
+    label: "周五",
28
+    alias: "星期五",
29
+    value: 5
30
+  },
31
+  {
32
+    label: "周六",
33
+    alias: "星期六",
34
+    value: 6
35
+  },
36
+  {
37
+    label: "周日",
38
+    alias: "星期日",
39
+    value: 0
40
+  }
41
+];
42
+export const getWeekNameFromVal = (index) => {
43
+  const week = weekDay.map((v) => v.label);
44
+  return week[index - 1 < 0 ? 6 : index - 1];
45
+};
46
+export const getWeekDateName = (date, useAlias = false) => {
47
+  const week = weekDay.map((v) => {
48
+    return useAlias ? v.alias : v.label;
49
+  });
50
+  const index = new Date(date).getDay();
51
+  return week[index - 1 < 0 ? 6 : index - 1];
52
+};
53
+export const toChinesNum = (num) => {
54
+  let changeNum = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
55
+  let unit = ["", "十", "百", "千", "万"];
56
+  num = parseInt(num);
57
+  let getWan = (temp) => {
58
+    let strArr = temp.toString().split("").reverse();
59
+    let newNum = "";
60
+    for (var i = 0; i < strArr.length; i++) {
61
+      newNum =
62
+        (i == 0 && strArr[i] == 0
63
+          ? ""
64
+          : i > 0 && strArr[i] == 0 && strArr[i - 1] == 0
65
+          ? ""
66
+          : changeNum[strArr[i]] + (strArr[i] == 0 ? unit[0] : unit[i])) +
67
+        newNum;
68
+    }
69
+    return newNum;
70
+  };
71
+  let overWan = Math.floor(num / 10000);
72
+  let noWan = num % 10000;
73
+  if (noWan.toString().length < 4) {
74
+    noWan = "0" + noWan;
75
+  }
76
+  return overWan ? getWan(overWan) + "万" + getWan(noWan) : getWan(num);
77
+};
78
+// 保留小数(四舍五入)
79
+export const fomatFloat = (src, pos) => {
80
+  return Math.round(src * Math.pow(10, pos)) / Math.pow(10, pos);
81
+};
82
+export const setStringToDate = (timeStr) => {
83
+  // IE不能识别字符串日期
84
+  let splitArray = timeStr.split(" ");
85
+  let dateArray = splitArray[0].split("-");
86
+  let d = new Date();
87
+  d.setFullYear(dateArray[0], dateArray[1] - 1, dateArray[2]);
88
+  d.setHours(0);
89
+  d.setMinutes(0);
90
+  d.setSeconds(0);
91
+  return d;
92
+};
93
+//  获取当前时间
94
+export const getNow = () => {
95
+  var date = new Date();
96
+  var year = date.getFullYear();
97
+  var month = date.getMonth() + 1;
98
+  var day = date.getDate();
99
+  if (month < 10) {
100
+    month = "0" + month;
101
+  }
102
+  if (day < 10) {
103
+    day = "0" + day;
104
+  }
105
+  return year + month + day;
106
+};
107
+/**
108
+ * 格式化秒
109
+ * @param int  value 总秒数
110
+ * @return string result 格式化后的字符串
111
+ */
112
+export const formatSeconds = (value) => {
113
+  var theTime = parseInt(value); // 需要转换的时间秒
114
+  var theTime1 = 0; // 分
115
+  var theTime2 = 0; // 小时
116
+  if (theTime > 60) {
117
+    theTime1 = parseInt(theTime / 60);
118
+    theTime = parseInt(theTime % 60);
119
+    if (theTime1 > 60) {
120
+      theTime2 = parseInt(theTime1 / 60);
121
+      theTime1 = parseInt(theTime1 % 60);
122
+    }
123
+  }
124
+  var result = "";
125
+  if (theTime === 0 && theTime1 === 0 && theTime2 === 0) {
126
+    result = "0秒";
127
+  }
128
+  if (theTime > 0) {
129
+    result = "" + parseInt(theTime) + "秒";
130
+  }
131
+  if (theTime1 > 0) {
132
+    result = "" + parseInt(theTime1) + "分" + result;
133
+  }
134
+  if (theTime2 > 0) {
135
+    result = "" + parseInt(theTime2) + "小时" + result;
136
+  }
137
+  return result;
138
+};
139
+/**
140
+ * 格式化秒
141
+ * @param int  value 总秒数
142
+ * @return string result 格式化后的字符串 HH:mm:ss
143
+ */
144
+export const format_seconds = (value) => {
145
+  let theTime = parseInt(value); // 需要转换的时间秒
146
+  let theTime1 = 0; // 分
147
+  let theTime2 = 0; // 小时
148
+  if (theTime > 60) {
149
+    theTime1 = parseInt(theTime / 60);
150
+    theTime = parseInt(theTime % 60);
151
+    if (theTime1 > 60) {
152
+      theTime2 = parseInt(theTime1 / 60);
153
+      theTime1 = parseInt(theTime1 % 60);
154
+    }
155
+  }
156
+  let t_hour = 0;
157
+  let t_min = 0;
158
+  let t_sec = 0;
159
+  if (theTime > 0) {
160
+    t_sec = parseInt(theTime);
161
+  }
162
+  if (theTime1 > 0) {
163
+    t_min = parseInt(theTime1);
164
+  }
165
+  if (theTime2 > 0) {
166
+    t_hour = parseInt(theTime2);
167
+  }
168
+  return t_hour > 0
169
+    ? `${t_hour > 9 ? "" : 0}${t_hour}:${t_min > 9 ? "" : 0}${t_min}:${
170
+        t_sec > 9 ? "" : 0
171
+      }${t_sec}`
172
+    : `${t_min > 9 ? "" : 0}${t_min}:${t_sec > 9 ? "" : 0}${t_sec}`;
173
+};
174
+/**
175
+ * 获取对象类型
176
+ */
177
+export const getObjType = (obj) => {
178
+  var toString = Object.prototype.toString;
179
+  var map = {
180
+    "[object Boolean]": "boolean",
181
+    "[object Number]": "number",
182
+    "[object String]": "string",
183
+    "[object Function]": "function",
184
+    "[object Array]": "array",
185
+    "[object Date]": "date",
186
+    "[object RegExp]": "regExp",
187
+    "[object Undefined]": "undefined",
188
+    "[object Null]": "null",
189
+    "[object Object]": "object"
190
+  };
191
+  if (obj instanceof Element) {
192
+    return "element";
193
+  }
194
+  return map[toString.call(obj)];
195
+};
196
+//时间戳转时间
197
+export const date_format = (unixtimestamp, type) => {
198
+  if (!unixtimestamp) {
199
+    return "";
200
+  }
201
+  unixtimestamp = new Date(unixtimestamp * 1000 + diffTime);
202
+  var year = 1900 + unixtimestamp.getYear();
203
+  var month = "0" + (unixtimestamp.getMonth() + 1);
204
+  var date = "0" + unixtimestamp.getDate();
205
+  var hour = "0" + unixtimestamp.getHours();
206
+  var minute = "0" + unixtimestamp.getMinutes();
207
+  var second = "0" + unixtimestamp.getSeconds();
208
+  return (
209
+    year +
210
+    "-" +
211
+    month.substring(month.length - 2, month.length) +
212
+    "-" +
213
+    date.substring(date.length - 2, date.length) +
214
+    " " +
215
+    hour.substring(hour.length - 2, hour.length) +
216
+    ":" +
217
+    minute.substring(minute.length - 2, minute.length) +
218
+    (type ? "" : ":" + second.substring(second.length - 2, second.length))
219
+  );
220
+};
221
+//时间转化为时间戳
222
+export const date_time = (datestring) => {
223
+  let time = new Date(datestring).getTime() / 1000;
224
+  if (!time && datestring) {
225
+    //兼容火狐浏览器
226
+    datestring = datestring.replace(new RegExp(/-/gm), "/");
227
+    time = new Date(datestring).getTime() / 1000;
228
+  }
229
+  return parseInt(time);
230
+};
231
+/**
232
+ * 对象深拷贝
233
+ */
234
+export const deepClone = (data) => {
235
+  var type = getObjType(data);
236
+  var obj;
237
+  if (type === "array") {
238
+    obj = [];
239
+  } else if (type === "object") {
240
+    obj = {};
241
+  } else {
242
+    // 不再具有下一层次
243
+    return data;
244
+  }
245
+  if (type === "array") {
246
+    for (var i = 0, len = data.length; i < len; i++) {
247
+      obj.push(deepClone(data[i]));
248
+    }
249
+  } else if (type === "object") {
250
+    for (var key in data) {
251
+      obj[key] = deepClone(data[key]);
252
+    }
253
+  }
254
+  return obj;
255
+};
256
+
257
+/**
258
+ * 日期格式化,时间戳
259
+ */
260
+export function format_date(time, format = "yyyy-MM-dd hh:mm:ss") {
261
+  let date = new Date(time * 1000 + diffTime);
262
+  if (date !== "Invalid Date") {
263
+    let o = {
264
+      "M+": date.getMonth() + 1, // month
265
+      "d+": date.getDate(), // day
266
+      "h+": date.getHours(), // hour
267
+      "m+": date.getMinutes(), // minute
268
+      "s+": date.getSeconds(), // second
269
+      "q+": Math.floor((date.getMonth() + 3) / 3), // quarter
270
+      S: date.getMilliseconds() // millisecond
271
+    };
272
+    if (/(y+)/.test(format)) {
273
+      format = format.replace(
274
+        RegExp.$1,
275
+        (date.getFullYear() + "").substr(4 - RegExp.$1.length)
276
+      );
277
+    }
278
+    for (let k in o) {
279
+      if (new RegExp("(" + k + ")").test(format)) {
280
+        format = format.replace(
281
+          RegExp.$1,
282
+          RegExp.$1.length === 1
283
+            ? o[k]
284
+            : ("00" + o[k]).substr(("" + o[k]).length)
285
+        );
286
+      }
287
+    }
288
+    return format;
289
+  }
290
+  return "";
291
+}
292
+/**
293
+ * 日期格式化
294
+ */
295
+export function dateFormat(dateDemo, format = "yyyy-MM-dd hh:mm:ss") {
296
+  let date = new Date(dateDemo);
297
+  if (date !== "Invalid Date") {
298
+    var o = {
299
+      "M+": date.getMonth() + 1, // month
300
+      "d+": date.getDate(), // day
301
+      "h+": date.getHours(), // hour
302
+      "m+": date.getMinutes(), // minute
303
+      "s+": date.getSeconds(), // second
304
+      "q+": Math.floor((date.getMonth() + 3) / 3), // quarter
305
+      S: date.getMilliseconds() // millisecond
306
+    };
307
+    if (/(y+)/.test(format)) {
308
+      format = format.replace(
309
+        RegExp.$1,
310
+        (date.getFullYear() + "").substr(4 - RegExp.$1.length)
311
+      );
312
+    }
313
+    for (var k in o) {
314
+      if (new RegExp("(" + k + ")").test(format)) {
315
+        format = format.replace(
316
+          RegExp.$1,
317
+          RegExp.$1.length === 1
318
+            ? o[k]
319
+            : ("00" + o[k]).substr(("" + o[k]).length)
320
+        );
321
+      }
322
+    }
323
+    return format;
324
+  }
325
+  return "";
326
+}
327
+
328
+// 颜色渐变函数
329
+export function hexToRgba(hex, opacity) {
330
+  let rgbaColor = "";
331
+  let reg = /^#[\da-f]{6}$/i;
332
+  if (reg.test(hex)) {
333
+    rgbaColor = `rgba(${parseInt("0x" + hex.slice(1, 3))},${parseInt(
334
+      "0x" + hex.slice(3, 5)
335
+    )},${parseInt("0x" + hex.slice(5, 7))},${opacity})`;
336
+  }
337
+  return rgbaColor;
338
+}
339
+export const unitsDigit = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
340
+export const upperCaseLetters = [
341
+  "A",
342
+  "B",
343
+  "C",
344
+  "D",
345
+  "E",
346
+  "F",
347
+  "G",
348
+  "H",
349
+  "I",
350
+  "J",
351
+  "K",
352
+  "L",
353
+  "M",
354
+  "N",
355
+  "O",
356
+  "P",
357
+  "Q",
358
+  "R",
359
+  "S",
360
+  "T",
361
+  "U",
362
+  "V",
363
+  "W",
364
+  "X",
365
+  "Y",
366
+  "Z"
367
+];
368
+export const lowerCaseLetters = [
369
+  "a",
370
+  "b",
371
+  "c",
372
+  "d",
373
+  "e",
374
+  "f",
375
+  "g",
376
+  "h",
377
+  "i",
378
+  "j",
379
+  "k",
380
+  "l",
381
+  "m",
382
+  "n",
383
+  "o",
384
+  "p",
385
+  "q",
386
+  "r",
387
+  "s",
388
+  "t",
389
+  "u",
390
+  "v",
391
+  "w",
392
+  "x",
393
+  "y",
394
+  "z"
395
+];
396
+// 随机字母和数字组合
397
+export const getRandomPassword = (num = 6) => {
398
+  if (num <= 0) {
399
+    return "";
400
+  }
401
+  let passwordArr = [unitsDigit, upperCaseLetters, lowerCaseLetters];
402
+  let psw = "";
403
+  let numDigit = 0;
404
+  for (let i = 0; i < num; i++) {
405
+    let selectIndex = Math.floor(Math.random() * passwordArr.length);
406
+    if (selectIndex === 0) {
407
+      numDigit++;
408
+    }
409
+    if (numDigit === num && i === num - 1) {
410
+      let selectArr = [upperCaseLetters, lowerCaseLetters][
411
+        Math.floor(Math.random() * 2)
412
+      ];
413
+      psw += selectArr[Math.floor(Math.random() * selectArr.length)];
414
+    } else if (numDigit === 0 && i === num - 1) {
415
+      psw += unitsDigit[Math.floor(Math.random() * unitsDigit.length)];
416
+    } else {
417
+      let selectArr = passwordArr[selectIndex];
418
+      psw += selectArr[Math.floor(Math.random() * selectArr.length)];
419
+    }
420
+  }
421
+  return psw;
422
+};
423
+/**
424
+ * 提取html字符串中的文字
425
+ */
426
+export const getHtmlPlainText = (html_str = "") => {
427
+  let text = html_str.replace(/<[^<>]+>/g, "").trim();
428
+  return text;
429
+};
430
+//判断html中是否有文字或图片
431
+export const htmlHasContent = (html_str = "") => {
432
+  let text = html_str.replace(/<[^<>]+>/g, "").trim();
433
+  let imgReg = /<img [^>]*src=['"]([^'"]+)[^>]*>/gi;
434
+  let imgUrls = html_str.match(imgReg) || [];
435
+  imgUrls.filter((url) => {
436
+    return url && url.match(/src=['"]?([^'"]*)['"]?/i);
437
+  });
438
+  return Boolean(text) || imgUrls.length > 0;
439
+};
440
+/**
441
+ * 压缩图片方法
442
+ * @param {file} file 文件或文件数组
443
+ * @param {Number} quality 图片质量(取值0-1之间默认0.92)
444
+ */
445
+export const compressImg = (file, quality) => {
446
+  if (Array.isArray(file)) {
447
+    return Promise.all(Array.from(file).map((e) => compressImg(e, quality))); // 如果是 file 数组返回 Promise 数组
448
+  } else {
449
+    let qualitys = 1;
450
+    //单位:MB
451
+    let fileSize = parseInt((file.size / 1024 / 1024).toFixed(2));
452
+    if (1 < fileSize && fileSize < 5) {
453
+      qualitys = 0.92;
454
+    }
455
+    if (5 < fileSize && fileSize < 10) {
456
+      qualitys = 0.85;
457
+    }
458
+    if (10 < fileSize) {
459
+      qualitys = 0.52;
460
+    }
461
+    if (quality) {
462
+      qualitys = quality;
463
+    }
464
+    return new Promise((resolve) => {
465
+      if (qualitys >= 1) {
466
+        resolve(file);
467
+      } else {
468
+        let fileType = file.type;
469
+        if (!fileType || !fileType.includes("image/")) {
470
+          resolve(file);
471
+          return;
472
+        }
473
+        const fileReader = new FileReader(); // 创建 FileReader
474
+        fileReader.onload = ({ target: { result: src } }) => {
475
+          const image = new Image(); // 创建 img 元素
476
+          image.onload = () => {
477
+            const mCanvas = document.createElement("canvas"); // 创建 canvas 元素
478
+            const mCtx = mCanvas.getContext("2d");
479
+            let targetWidth = image.width;
480
+            let targetHeight = image.height;
481
+            let originWidth = image.width;
482
+            let originHeight = image.height;
483
+            if (1 <= fileSize) {
484
+              let maxWidth = 1400;
485
+              let maxHeight = 1400;
486
+              if (5 < fileSize) {
487
+                maxWidth = 1920;
488
+                maxHeight = 1920;
489
+              }
490
+              targetWidth = originWidth;
491
+              targetHeight = originHeight;
492
+              // 图片尺寸超过的限制
493
+              if (originWidth > maxWidth || originHeight > maxHeight) {
494
+                if (originWidth / originHeight > maxWidth / maxHeight) {
495
+                  // 更宽,按照宽度限定尺寸
496
+                  targetWidth = maxWidth;
497
+                  targetHeight = Math.round(
498
+                    maxWidth * (originHeight / originWidth)
499
+                  );
500
+                } else {
501
+                  targetHeight = maxHeight;
502
+                  targetWidth = Math.round(
503
+                    maxHeight * (originWidth / originHeight)
504
+                  );
505
+                }
506
+              }
507
+            }
508
+            mCanvas.width = targetWidth;
509
+            mCanvas.height = targetHeight;
510
+            mCtx.clearRect(0, 0, targetWidth, targetHeight);
511
+            mCtx.drawImage(image, 0, 0, targetWidth, targetHeight); // 绘制 canvas
512
+            const canvasURL = mCanvas.toDataURL(fileType, qualitys);
513
+            const buffer = atob(canvasURL.split(",")[1]);
514
+            let length = buffer.length;
515
+            const bufferArray = new Uint8Array(new ArrayBuffer(length));
516
+            while (length--) {
517
+              bufferArray[length] = buffer.charCodeAt(length);
518
+            }
519
+            const miniFile = new File([bufferArray], file.name, {
520
+              type: fileType
521
+            });
522
+            resolve(miniFile);
523
+          };
524
+          image.src = src;
525
+        };
526
+        fileReader.readAsDataURL(file);
527
+      }
528
+    });
529
+  }
530
+};
531
+/**
532
+ * 连接类型列表
533
+ */
534
+export const relationTypeList = [
535
+  {
536
+    label: "左连接",
537
+    value: "left join"
538
+  },
539
+  {
540
+    label: "右连接",
541
+    value: "right join"
542
+  },
543
+  {
544
+    label: "内连接",
545
+    value: "inner join"
546
+  }
547
+];
548
+/**
549
+ * 根据value获取连接的label
550
+ */
551
+export const getRelationTypeName = (relationType) => {
552
+  let relationTypeItem = relationTypeList.filter(
553
+    (v) => v.value === relationType
554
+  )[0];
555
+  return relationTypeItem ? relationTypeItem.label : null;
556
+};
557
+/**
558
+ * 支持字段
559
+ */
560
+export const behaviorList = [
561
+  { id: "long", name: "整型" },
562
+  { id: "double", name: "浮点型" },
563
+  { id: "string", name: "文本" },
564
+  { id: "text", name: "长文本" },
565
+  { id: "date", name: "日期" },
566
+  { id: "datetime", name: "日期时间" },
567
+  { id: "time", name: "时间" }
568
+];
569
+export function uuid() {
570
+  const s = [];
571
+  const hexDigits = "0123456789abcdef";
572
+  for (let i = 0; i < 36; i++) {
573
+    let start = Math.floor(Math.random() * 0x10);
574
+    s[i] = hexDigits.substring(start, start + 1);
575
+  }
576
+  s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
577
+  let start = (s[19] & 0x3) | 0x8;
578
+  s[19] = hexDigits.substring(start, start + 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
579
+  s[8] = s[13] = s[18] = s[23] = "-";
580
+
581
+  return s.join("");
582
+}
583
+
584
+export function getPosInDom(outerDom, innerDom) {
585
+  // 元素的坐标和大小
586
+  const rect = outerDom.getBoundingClientRect();
587
+  const rect2 = innerDom.getBoundingClientRect();
588
+  const x = rect2.left - rect.left;
589
+  const y = rect2.top - rect.top;
590
+
591
+  return {
592
+    x: x,
593
+    y: y,
594
+    width: rect2.width,
595
+    height: rect2.height
596
+  };
597
+}
598
+
599
+export function getPosInDomByEvent(outerDom, event) {
600
+  // 元素的坐标和大小
601
+  const rect = outerDom.getBoundingClientRect();
602
+
603
+  // 鼠标坐标
604
+  const x = event.clientX;
605
+  const y = event.clientY;
606
+
607
+  // 计算鼠标在元素中的坐标
608
+  const elementX = x - rect.left;
609
+  const elementY = y - rect.top;
610
+
611
+  return {
612
+    x: elementX,
613
+    y: elementY
614
+  };
615
+}
616
+//表单正则验证
617
+export function testVerify(eleProps) {
618
+  //添加编辑状态不执行
619
+  if (!eleProps.infoFilling) {
620
+    return;
621
+  }
622
+  if (eleProps.isrequired) {
623
+    eleProps.iserr = false;
624
+    //必填校验
625
+    if (
626
+      eleProps.compType === "tpl_comp_select_muti" ||
627
+      eleProps.compType === "tpl_comp_cascade" ||
628
+      eleProps.compType === "tpl_comp_pic" ||
629
+      eleProps.compType === "tpl_comp_annex" ||
630
+      eleProps.compType === "tpl_comp_sign"
631
+    ) {
632
+      //多选 级联
633
+      if (eleProps.fieldvalue.length === 0) {
634
+        this.$Message.error(`${eleProps.requiredmsg}`);
635
+        eleProps.iserr = true;
636
+        return;
637
+      }
638
+    } else if (eleProps.compType === "tpl_comp_stepper") {
639
+      //步进器
640
+      if (eleProps.fieldvalue === 0) {
641
+        this.$Message.error(`${eleProps.requiredmsg}`);
642
+        eleProps.iserr = true;
643
+        return;
644
+      }
645
+    } else if (eleProps.compType === "tpl_comp_table") {
646
+      eleProps.tbodyObj.forEach((arr) => {
647
+        arr.forEach((item) => {
648
+          if (item.state && !item.title) {
649
+            this.$Message.error(`${eleProps.requiredmsg}`);
650
+            eleProps.iserr = true;
651
+            return;
652
+          }
653
+        });
654
+      });
655
+    } else {
656
+      if (eleProps.fieldvalue === "") {
657
+        this.$Message.error(`${eleProps.requiredmsg}`);
658
+        eleProps.iserr = true;
659
+        return;
660
+      }
661
+    }
662
+    if (eleProps.isverification) {
663
+      //正则校验
664
+      if (eleProps.showrule) {
665
+        //自定义正则 customrules
666
+        let reg = new RegExp(eleProps.customrules);
667
+        if (!reg.test(eleProps.fieldvalue)) {
668
+          this.$Message.error(`${eleProps.errmsg}`);
669
+          eleProps.iserr = true;
670
+        }
671
+      } else {
672
+        //选定正则 selectrule
673
+        if (eleProps.selectrule === "^1\\d{10}$") {
674
+          eleProps.fieldvalue = parseInt(eleProps.fieldvalue); //手机号 需要转数字
675
+        }
676
+        let reg = new RegExp(eleProps.selectrule);
677
+        if (!reg.test(eleProps.fieldvalue)) {
678
+          this.$Message.error(`${eleProps.errmsg}`);
679
+          eleProps.iserr = true;
680
+        }
681
+      }
682
+    }
683
+  }
684
+  this.$forceUpdate();
685
+}
686
+/**
687
+ * 返回开始日期(以0点开始)和结束日期(以24点结束)的秒数
688
+ * @param beginDate 开始日期
689
+ * @param endDate 结束日期
690
+ */
691
+export const dateRangeToSecond = ([beginDate, endDate]) => {
692
+  let _begintime = null;
693
+  let _endtime = null;
694
+  if (beginDate) {
695
+    let _beginDate = new Date(beginDate);
696
+    _begintime = new Date(
697
+      _beginDate.getFullYear(),
698
+      _beginDate.getMonth(),
699
+      _beginDate.getDate(),
700
+      0,
701
+      0,
702
+      0
703
+    ).getTime();
704
+    _begintime = parseInt(_begintime / 1000);
705
+  }
706
+  if (endDate) {
707
+    let _endDate = new Date(endDate);
708
+    _endtime = new Date(
709
+      _endDate.getFullYear(),
710
+      _endDate.getMonth(),
711
+      _endDate.getDate(),
712
+      23,
713
+      59,
714
+      59
715
+    ).getTime();
716
+    _endtime = parseInt(_endtime / 1000);
717
+  }
718
+  return {
719
+    begintime: _begintime,
720
+    endtime: _endtime
721
+  };
722
+};

+ 30
- 0
src/utils/resetMessage.js ファイルの表示

@@ -0,0 +1,30 @@
1
+import ViewUI from "view-design";
2
+let errorTipMinTime = 3;
3
+let msgInstance = null;
4
+let resetMessage = {
5
+  destroy: ViewUI.Message.destroy
6
+};
7
+["error", "success", "info", "warning", "loading", "config"].forEach((type) => {
8
+  resetMessage[type] = (options) => {
9
+    if (msgInstance) {
10
+      ViewUI.Message.destroy();
11
+    }
12
+    if (type === "error" || type === "warning") {
13
+      if (typeof options === "string") {
14
+        options = {
15
+          content: options,
16
+          duration: errorTipMinTime
17
+        };
18
+      } else {
19
+        if (options.duration !== 0) {
20
+          options.duration =
21
+            options.duration > errorTipMinTime
22
+              ? options.duration
23
+              : errorTipMinTime;
24
+        }
25
+      }
26
+    }
27
+    msgInstance = ViewUI.Message[type](options);
28
+  };
29
+});
30
+export const message = resetMessage;

+ 15
- 0
src/views/layout.vue ファイルの表示

@@ -0,0 +1,15 @@
1
+<template>
2
+  <div class="layout_box"></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  created() {},
11
+  methods: {}
12
+};
13
+</script>
14
+
15
+<style lang="less" scoped></style>

+ 14
- 0
src/views/login/login.vue ファイルの表示

@@ -0,0 +1,14 @@
1
+<template>
2
+  <div></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  methods: {}
11
+};
12
+</script>
13
+
14
+<style lang="less" scoped></style>

+ 14
- 0
src/views/personal/personal.vue ファイルの表示

@@ -0,0 +1,14 @@
1
+<template>
2
+  <div></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  methods: {}
11
+};
12
+</script>
13
+
14
+<style lang="less" scoped></style>

+ 14
- 0
src/views/platform/admin/index.vue ファイルの表示

@@ -0,0 +1,14 @@
1
+<template>
2
+  <div></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  methods: {}
11
+};
12
+</script>
13
+
14
+<style lang="less" scoped></style>

+ 14
- 0
src/views/platform/home/index.vue ファイルの表示

@@ -0,0 +1,14 @@
1
+<template>
2
+  <div></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  methods: {}
11
+};
12
+</script>
13
+
14
+<style lang="less" scoped></style>

+ 14
- 0
src/views/platform/log/index.vue ファイルの表示

@@ -0,0 +1,14 @@
1
+<template>
2
+  <div></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  methods: {}
11
+};
12
+</script>
13
+
14
+<style lang="less" scoped></style>

+ 14
- 0
src/views/platform/networkManage/index.vue ファイルの表示

@@ -0,0 +1,14 @@
1
+<template>
2
+  <div></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  methods: {}
11
+};
12
+</script>
13
+
14
+<style lang="less" scoped></style>

+ 14
- 0
src/views/platform/notice/index.vue ファイルの表示

@@ -0,0 +1,14 @@
1
+<template>
2
+  <div></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  methods: {}
11
+};
12
+</script>
13
+
14
+<style lang="less" scoped></style>

+ 14
- 0
src/views/platform/regionManage/index.vue ファイルの表示

@@ -0,0 +1,14 @@
1
+<template>
2
+  <div></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  methods: {}
11
+};
12
+</script>
13
+
14
+<style lang="less" scoped></style>

+ 14
- 0
src/views/region/admin/index.vue ファイルの表示

@@ -0,0 +1,14 @@
1
+<template>
2
+  <div></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  methods: {}
11
+};
12
+</script>
13
+
14
+<style lang="less" scoped></style>

+ 14
- 0
src/views/region/home/index.vue ファイルの表示

@@ -0,0 +1,14 @@
1
+<template>
2
+  <div></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  methods: {}
11
+};
12
+</script>
13
+
14
+<style lang="less" scoped></style>

+ 14
- 0
src/views/region/regionManage/index.vue ファイルの表示

@@ -0,0 +1,14 @@
1
+<template>
2
+  <div></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  methods: {}
11
+};
12
+</script>
13
+
14
+<style lang="less" scoped></style>

+ 14
- 0
src/views/region/schoolManage/index.vue ファイルの表示

@@ -0,0 +1,14 @@
1
+<template>
2
+  <div></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  methods: {}
11
+};
12
+</script>
13
+
14
+<style lang="less" scoped></style>

+ 14
- 0
src/views/school/admin/index.vue ファイルの表示

@@ -0,0 +1,14 @@
1
+<template>
2
+  <div></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  methods: {}
11
+};
12
+</script>
13
+
14
+<style lang="less" scoped></style>

+ 14
- 0
src/views/school/home/index.vue ファイルの表示

@@ -0,0 +1,14 @@
1
+<template>
2
+  <div></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  methods: {}
11
+};
12
+</script>
13
+
14
+<style lang="less" scoped></style>

+ 14
- 0
src/views/school/index.vue ファイルの表示

@@ -0,0 +1,14 @@
1
+<template>
2
+  <div></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  methods: {}
11
+};
12
+</script>
13
+
14
+<style lang="less" scoped></style>

+ 14
- 0
src/views/school/regionManage/index.vue ファイルの表示

@@ -0,0 +1,14 @@
1
+<template>
2
+  <div></div>
3
+</template>
4
+
5
+<script>
6
+export default {
7
+  data() {
8
+    return {};
9
+  },
10
+  methods: {}
11
+};
12
+</script>
13
+
14
+<style lang="less" scoped></style>

+ 57
- 0
vue.config.js ファイルの表示

@@ -0,0 +1,57 @@
1
+const { defineConfig } = require("@vue/cli-service");
2
+const timestamp = new Date().getTime();
3
+//生产环境标记
4
+const IS_PRODUCTION = process.env.NODE_ENV === "production";
5
+
6
+// 生产配置
7
+const cdn_production = {
8
+  js: ["/librarys/vue@2.6.11/vue.min.js"]
9
+};
10
+// 开发配置
11
+const cdn_development = {
12
+  js: ["/librarys/vue@2.6.11/vue.js"]
13
+};
14
+module.exports = defineConfig({
15
+  lintOnSave: false,
16
+  productionSourceMap: !IS_PRODUCTION, //打包不生成map文件
17
+  devServer: {
18
+    open: false
19
+  },
20
+  css: {
21
+    extract: IS_PRODUCTION
22
+      ? {
23
+          filename: `css/[name].${timestamp}.css`,
24
+          chunkFilename: `css/[name].${timestamp}.css`
25
+        }
26
+      : false,
27
+    loaderOptions: {
28
+      less: {
29
+        lessOptions: {
30
+          javascriptEnabled: true
31
+        }
32
+      }
33
+    }
34
+  },
35
+  configureWebpack: {
36
+    output: {
37
+      filename: `js/[name].${timestamp}.js`,
38
+      chunkFilename: `js/[name].${timestamp}.js`
39
+    },
40
+    // 排除不引用
41
+    externals: {
42
+      vue: "Vue",
43
+      "vue-router": "VueRouter",
44
+      vuex: "Vuex",
45
+      echarts: "echarts",
46
+      axios: "axios",
47
+      "view-design": "iview",
48
+      "crypto-js": "CryptoJS"
49
+    }
50
+  },
51
+  chainWebpack: (config) => {
52
+    config.plugin("html").tap((args) => {
53
+      args[0].cdn = IS_PRODUCTION ? cdn_production : cdn_development;
54
+      return args;
55
+    });
56
+  }
57
+});

読み込み中…
キャンセル
保存