Browse Source

项目初始化

seimin 3 years ago
commit
f7d189db48
54 changed files with 19790 additions and 0 deletions
  1. 3 0
      .browserslistrc
  2. 5 0
      .editorconfig
  3. 17 0
      .eslintrc.js
  4. 22 0
      .gitignore
  5. 24 0
      README.md
  6. 5 0
      babel.config.js
  7. 12200 0
      package-lock.json
  8. 35 0
      package.json
  9. BIN
      public/favicon.ico
  10. 17 0
      public/index.html
  11. 9 0
      src/App.vue
  12. 539 0
      src/assets/font/demo.css
  13. 2010 0
      src/assets/font/demo_index.html
  14. 335 0
      src/assets/font/iconfont.css
  15. BIN
      src/assets/font/iconfont.eot
  16. 569 0
      src/assets/font/iconfont.json
  17. 266 0
      src/assets/font/iconfont.svg
  18. BIN
      src/assets/font/iconfont.ttf
  19. BIN
      src/assets/font/iconfont.woff
  20. BIN
      src/assets/font/iconfont.woff2
  21. BIN
      src/assets/img/bg.jpg
  22. BIN
      src/assets/img/image_no1.png
  23. BIN
      src/assets/img/image_no2.png
  24. BIN
      src/assets/img/image_title01.png
  25. BIN
      src/assets/img/image_title02.png
  26. BIN
      src/assets/img/logo.png
  27. 147 0
      src/assets/js/flexible.js
  28. 1 0
      src/assets/less/_variables.less
  29. 75 0
      src/assets/less/style.less
  30. 203 0
      src/components/AppHeader.vue
  31. 58 0
      src/components/AppToday.vue
  32. 298 0
      src/components/BusinessTypeRatio.vue
  33. 104 0
      src/components/DeliveryRate.vue
  34. 140 0
      src/components/DeliveryRateLine.vue
  35. 204 0
      src/components/ErrorWorkOrder.vue
  36. 400 0
      src/components/GroupPerformance.vue
  37. 211 0
      src/components/GroupPraise.vue
  38. 121 0
      src/components/OnDutyToday.vue
  39. 355 0
      src/components/OnDutyTodayPie.vue
  40. 240 0
      src/components/OnTimeArrivalRate.vue
  41. 242 0
      src/components/PointsRanking.vue
  42. 185 0
      src/components/TimeUtilization.vue
  43. 185 0
      src/components/TodayWorkOrder.vue
  44. 34 0
      src/http/http.js
  45. 6 0
      src/lib/components/fullScreenContainer/index.js
  46. 8 0
      src/lib/components/fullScreenContainer/src/main.css
  47. 57 0
      src/lib/components/fullScreenContainer/src/main.vue
  48. 14 0
      src/lib/index.js
  49. 76 0
      src/lib/mixin/autoResize.js
  50. 47 0
      src/lib/util/index.js
  51. 21 0
      src/main.js
  52. 16 0
      src/router/index.js
  53. 264 0
      src/views/AppIndex.vue
  54. 22 0
      vue.config.js

+ 3 - 0
.browserslistrc

@@ -0,0 +1,3 @@
1
+> 1%
2
+last 2 versions
3
+not dead

+ 5 - 0
.editorconfig

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

+ 17 - 0
.eslintrc.js

@@ -0,0 +1,17 @@
1
+module.exports = {
2
+  root: true,
3
+  env: {
4
+    node: true
5
+  },
6
+  extends: [
7
+    'plugin:vue/essential',
8
+    '@vue/standard'
9
+  ],
10
+  parserOptions: {
11
+    parser: 'babel-eslint'
12
+  },
13
+  rules: {
14
+    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
15
+    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
16
+  }
17
+}

+ 22 - 0
.gitignore

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

+ 24 - 0
README.md

@@ -0,0 +1,24 @@
1
+# 大势科技大屏项目
2
+
3
+## Project setup
4
+```
5
+npm install
6
+```
7
+
8
+### Compiles and hot-reloads for development
9
+```
10
+npm run serve
11
+```
12
+
13
+### Compiles and minifies for production
14
+```
15
+npm run build
16
+```
17
+
18
+### Lints and fixes files
19
+```
20
+npm run lint
21
+```
22
+
23
+### Customize configuration
24
+See [Configuration Reference](https://cli.vuejs.org/config/).

+ 5 - 0
babel.config.js

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

File diff suppressed because it is too large
+ 12200 - 0
package-lock.json


+ 35 - 0
package.json

@@ -0,0 +1,35 @@
1
+{
2
+  "name": "largescreen",
3
+  "version": "0.1.0",
4
+  "private": true,
5
+  "scripts": {
6
+    "start": "vue-cli-service serve",
7
+    "build": "vue-cli-service build",
8
+    "lint": "vue-cli-service lint"
9
+  },
10
+  "dependencies": {
11
+    "axios": "^0.19.2",
12
+    "core-js": "^3.6.5",
13
+    "echarts": "^4.0.4",
14
+    "moment": "^2.27.0",
15
+    "vue": "^2.6.11",
16
+    "vue-router": "^3.2.0"
17
+  },
18
+  "devDependencies": {
19
+    "@vue/cli-plugin-babel": "~4.4.0",
20
+    "@vue/cli-plugin-eslint": "~4.4.0",
21
+    "@vue/cli-plugin-router": "~4.4.0",
22
+    "@vue/cli-service": "~4.4.0",
23
+    "@vue/eslint-config-standard": "^5.1.2",
24
+    "babel-eslint": "^10.1.0",
25
+    "eslint": "^6.7.2",
26
+    "eslint-plugin-import": "^2.20.2",
27
+    "eslint-plugin-node": "^11.1.0",
28
+    "eslint-plugin-promise": "^4.2.1",
29
+    "eslint-plugin-standard": "^4.0.0",
30
+    "eslint-plugin-vue": "^6.2.2",
31
+    "less": "^3.0.4",
32
+    "less-loader": "^5.0.0",
33
+    "vue-template-compiler": "^2.6.11"
34
+  }
35
+}

BIN
public/favicon.ico


+ 17 - 0
public/index.html

@@ -0,0 +1,17 @@
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
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
8
+    <title><%= htmlWebpackPlugin.options.title %></title>
9
+  </head>
10
+  <body>
11
+    <noscript>
12
+      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
13
+    </noscript>
14
+    <div id="app"></div>
15
+    <!-- built files will be auto injected -->
16
+  </body>
17
+</html>

+ 9 - 0
src/App.vue

@@ -0,0 +1,9 @@
1
+<template>
2
+  <div id="app">
3
+    <router-view/>
4
+  </div>
5
+</template>
6
+
7
+<style lang="less">
8
+
9
+</style>

+ 539 - 0
src/assets/font/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
+}

File diff suppressed because it is too large
+ 2010 - 0
src/assets/font/demo_index.html


+ 335 - 0
src/assets/font/iconfont.css

@@ -0,0 +1,335 @@
1
+@font-face {font-family: "icon_transport";
2
+  src: url('iconfont.eot?t=1592895040969'); /* IE9 */
3
+  src: url('iconfont.woff?t=1592895040969') format('woff'),
4
+  url('iconfont.ttf?t=1592895040969') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
5
+  url('iconfont.svg?t=1592895040969#icon_transport') format('svg'); /* iOS 4.1- */
6
+}
7
+
8
+.icon_transport {
9
+  font-family: "icon_transport" !important;
10
+  font-size: 16px;
11
+  font-style: normal;
12
+  -webkit-font-smoothing: antialiased;
13
+  -moz-osx-font-smoothing: grayscale;
14
+}
15
+
16
+.transport-laba1:before {
17
+  content: "\e681";
18
+}
19
+
20
+.transport-erweima:before {
21
+  content: "\e606";
22
+}
23
+
24
+.transport-chaoshi:before {
25
+  content: "\e63b";
26
+}
27
+
28
+.transport-guanbi1:before {
29
+  content: "\e658";
30
+}
31
+
32
+.transport-lingdang:before {
33
+  content: "\e60d";
34
+}
35
+
36
+.transport-peijianlunyitubiao:before {
37
+  content: "\e655";
38
+}
39
+
40
+.transport-ccgl-kuneizhuanyi-1:before {
41
+  content: "\e6e5";
42
+}
43
+
44
+.transport-qita1:before {
45
+  content: "\e663";
46
+}
47
+
48
+.transport--:before {
49
+  content: "\e60b";
50
+}
51
+
52
+.transport-yaopin:before {
53
+  content: "\e604";
54
+}
55
+
56
+.transport-biaobencaiji:before {
57
+  content: "\e6ea";
58
+}
59
+
60
+.transport-icon_liucheng:before {
61
+  content: "\e636";
62
+}
63
+
64
+.transport-zhengchang:before {
65
+  content: "\e63e";
66
+}
67
+
68
+.transport-yichang:before {
69
+  content: "\e63a";
70
+}
71
+
72
+.transport-qita:before {
73
+  content: "\e60f";
74
+}
75
+
76
+.transport-shuyeguanli:before {
77
+  content: "\e678";
78
+}
79
+
80
+.transport-yidonghuliicon_biaobenliuqu:before {
81
+  content: "\e61b";
82
+}
83
+
84
+.transport-saoma:before {
85
+  content: "\e660";
86
+}
87
+
88
+.transport-shezhi:before {
89
+  content: "\e62f";
90
+}
91
+
92
+.transport-required:before {
93
+  content: "\e603";
94
+}
95
+
96
+.transport-yunzhuanzhentongjiicon-:before {
97
+  content: "\e61a";
98
+}
99
+
100
+.transport-tag27fuben:before {
101
+  content: "\e614";
102
+}
103
+
104
+.transport-qidian:before {
105
+  content: "\e6e7";
106
+}
107
+
108
+.transport-search:before {
109
+  content: "\e651";
110
+}
111
+
112
+.transport-shouye10:before {
113
+  content: "\e63f";
114
+}
115
+
116
+.transport-shouye9:before {
117
+  content: "\e629";
118
+}
119
+
120
+.transport-luyin:before {
121
+  content: "\e6c5";
122
+}
123
+
124
+.transport-xiala2:before {
125
+  content: "\e669";
126
+}
127
+
128
+.transport-wenhao:before {
129
+  content: "\e7d2";
130
+}
131
+
132
+.transport-keshidaozhen:before {
133
+  content: "\ead2";
134
+}
135
+
136
+.transport-yi-peisong:before {
137
+  content: "\e647";
138
+}
139
+
140
+.transport-wei-peisong:before {
141
+  content: "\e662";
142
+}
143
+
144
+.transport-shujuyuanzongshu:before {
145
+  content: "\e650";
146
+}
147
+
148
+.transport-tongji:before {
149
+  content: "\e6db";
150
+}
151
+
152
+.transport-shouye8:before {
153
+  content: "\e621";
154
+}
155
+
156
+.transport-icon3:before {
157
+  content: "\e654";
158
+}
159
+
160
+.transport-tongjibaobiao:before {
161
+  content: "\e677";
162
+}
163
+
164
+.transport-chuangwei:before {
165
+  content: "\e64a";
166
+}
167
+
168
+.transport-paixu-shang:before {
169
+  content: "\eeeb";
170
+}
171
+
172
+.transport-paixu-xia:before {
173
+  content: "\eeec";
174
+}
175
+
176
+.transport-paixujiantoushang:before {
177
+  content: "\e7fe";
178
+}
179
+
180
+.transport-paixujiantouxia:before {
181
+  content: "\e7ff";
182
+}
183
+
184
+.transport-webicon19:before {
185
+  content: "\e67d";
186
+}
187
+
188
+.transport-webicon206:before {
189
+  content: "\e684";
190
+}
191
+
192
+.transport-xiangyou:before {
193
+  content: "\e637";
194
+}
195
+
196
+.transport-xiangzuo2:before {
197
+  content: "\e6b0";
198
+}
199
+
200
+.transport-shiwujiaoxing:before {
201
+  content: "\e635";
202
+}
203
+
204
+.transport-xialajiantou:before {
205
+  content: "\e638";
206
+}
207
+
208
+.transport-fuxuankuang:before {
209
+  content: "\e639";
210
+}
211
+
212
+.transport-fuxuankuang-:before {
213
+  content: "\e646";
214
+}
215
+
216
+.transport-xiangzuo1:before {
217
+  content: "\e673";
218
+}
219
+
220
+.transport-xiaoxi:before {
221
+  content: "\e617";
222
+}
223
+
224
+.transport-shangla-:before {
225
+  content: "\e628";
226
+}
227
+
228
+.transport-shuangjiantouxiangyou-:before {
229
+  content: "\e71e";
230
+}
231
+
232
+.transport-shibai:before {
233
+  content: "\e626";
234
+}
235
+
236
+.transport-duigou:before {
237
+  content: "\e602";
238
+}
239
+
240
+.transport-shouye7:before {
241
+  content: "\e619";
242
+}
243
+
244
+.transport-xiala2-01:before {
245
+  content: "\e62e";
246
+}
247
+
248
+.transport-xiala:before {
249
+  content: "\e68f";
250
+}
251
+
252
+.transport-shouye2:before {
253
+  content: "\e613";
254
+}
255
+
256
+.transport-shouye3:before {
257
+  content: "\e615";
258
+}
259
+
260
+.transport-shouye4:before {
261
+  content: "\e616";
262
+}
263
+
264
+.transport-shouye5:before {
265
+  content: "\e61c";
266
+}
267
+
268
+.transport-shouye6:before {
269
+  content: "\e642";
270
+}
271
+
272
+.transport-icon:before {
273
+  content: "\e65f";
274
+}
275
+
276
+.transport-icon1:before {
277
+  content: "\e68e";
278
+}
279
+
280
+.transport-icon2:before {
281
+  content: "\e69e";
282
+}
283
+
284
+.transport-daojishi:before {
285
+  content: "\e668";
286
+}
287
+
288
+.transport-xiangzuo:before {
289
+  content: "\e601";
290
+}
291
+
292
+.transport-haoping:before {
293
+  content: "\e612";
294
+}
295
+
296
+.transport-gengduoda:before {
297
+  content: "\e633";
298
+}
299
+
300
+.transport-shouye1:before {
301
+  content: "\e62d";
302
+}
303
+
304
+.transport-haoping1:before {
305
+  content: "\e640";
306
+}
307
+
308
+.transport-guanbi:before {
309
+  content: "\e60c";
310
+}
311
+
312
+.transport-sousuo:before {
313
+  content: "\e634";
314
+}
315
+
316
+.transport-xiala1:before {
317
+  content: "\e66b";
318
+}
319
+
320
+.transport-shouye:before {
321
+  content: "\e605";
322
+}
323
+
324
+.transport-liebiao:before {
325
+  content: "\e632";
326
+}
327
+
328
+.transport-tongjifenxi:before {
329
+  content: "\e712";
330
+}
331
+
332
+.transport-keshijieshao:before {
333
+  content: "\e600";
334
+}
335
+

BIN
src/assets/font/iconfont.eot


+ 569 - 0
src/assets/font/iconfont.json

@@ -0,0 +1,569 @@
1
+{
2
+  "id": "579983",
3
+  "name": "黄石转运系统",
4
+  "font_family": "icon_transport",
5
+  "css_prefix_text": "transport-",
6
+  "description": "黄石转运系统",
7
+  "glyphs": [
8
+    {
9
+      "icon_id": "15486827",
10
+      "name": "喇叭 (1)",
11
+      "font_class": "laba1",
12
+      "unicode": "e681",
13
+      "unicode_decimal": 59009
14
+    },
15
+    {
16
+      "icon_id": "3086025",
17
+      "name": "二维码",
18
+      "font_class": "erweima",
19
+      "unicode": "e606",
20
+      "unicode_decimal": 58886
21
+    },
22
+    {
23
+      "icon_id": "7489416",
24
+      "name": "超时",
25
+      "font_class": "chaoshi",
26
+      "unicode": "e63b",
27
+      "unicode_decimal": 58939
28
+    },
29
+    {
30
+      "icon_id": "9016785",
31
+      "name": "关 闭",
32
+      "font_class": "guanbi1",
33
+      "unicode": "e658",
34
+      "unicode_decimal": 58968
35
+    },
36
+    {
37
+      "icon_id": "10836451",
38
+      "name": "铃铛",
39
+      "font_class": "lingdang",
40
+      "unicode": "e60d",
41
+      "unicode_decimal": 58893
42
+    },
43
+    {
44
+      "icon_id": "1473516",
45
+      "name": "陪检(轮椅)图标",
46
+      "font_class": "peijianlunyitubiao",
47
+      "unicode": "e655",
48
+      "unicode_decimal": 58965
49
+    },
50
+    {
51
+      "icon_id": "1973826",
52
+      "name": "转移",
53
+      "font_class": "ccgl-kuneizhuanyi-1",
54
+      "unicode": "e6e5",
55
+      "unicode_decimal": 59109
56
+    },
57
+    {
58
+      "icon_id": "7503408",
59
+      "name": "其他",
60
+      "font_class": "qita1",
61
+      "unicode": "e663",
62
+      "unicode_decimal": 58979
63
+    },
64
+    {
65
+      "icon_id": "9385203",
66
+      "name": "注射器",
67
+      "font_class": "-",
68
+      "unicode": "e60b",
69
+      "unicode_decimal": 58891
70
+    },
71
+    {
72
+      "icon_id": "9714964",
73
+      "name": "药品",
74
+      "font_class": "yaopin",
75
+      "unicode": "e604",
76
+      "unicode_decimal": 58884
77
+    },
78
+    {
79
+      "icon_id": "11830234",
80
+      "name": "标本采集",
81
+      "font_class": "biaobencaiji",
82
+      "unicode": "e6ea",
83
+      "unicode_decimal": 59114
84
+    },
85
+    {
86
+      "icon_id": "4852580",
87
+      "name": "icon_liucheng",
88
+      "font_class": "icon_liucheng",
89
+      "unicode": "e636",
90
+      "unicode_decimal": 58934
91
+    },
92
+    {
93
+      "icon_id": "5762790",
94
+      "name": "正常",
95
+      "font_class": "zhengchang",
96
+      "unicode": "e63e",
97
+      "unicode_decimal": 58942
98
+    },
99
+    {
100
+      "icon_id": "6853490",
101
+      "name": "异常",
102
+      "font_class": "yichang",
103
+      "unicode": "e63a",
104
+      "unicode_decimal": 58938
105
+    },
106
+    {
107
+      "icon_id": "4082004",
108
+      "name": "其他",
109
+      "font_class": "qita",
110
+      "unicode": "e60f",
111
+      "unicode_decimal": 58895
112
+    },
113
+    {
114
+      "icon_id": "9923151",
115
+      "name": "输液管理",
116
+      "font_class": "shuyeguanli",
117
+      "unicode": "e678",
118
+      "unicode_decimal": 59000
119
+    },
120
+    {
121
+      "icon_id": "10059601",
122
+      "name": "标本留取",
123
+      "font_class": "yidonghuliicon_biaobenliuqu",
124
+      "unicode": "e61b",
125
+      "unicode_decimal": 58907
126
+    },
127
+    {
128
+      "icon_id": "6757421",
129
+      "name": "扫一扫",
130
+      "font_class": "saoma",
131
+      "unicode": "e660",
132
+      "unicode_decimal": 58976
133
+    },
134
+    {
135
+      "icon_id": "453042",
136
+      "name": "设置",
137
+      "font_class": "shezhi",
138
+      "unicode": "e62f",
139
+      "unicode_decimal": 58927
140
+    },
141
+    {
142
+      "icon_id": "2817690",
143
+      "name": "星号",
144
+      "font_class": "required",
145
+      "unicode": "e603",
146
+      "unicode_decimal": 58883
147
+    },
148
+    {
149
+      "icon_id": "5260595",
150
+      "name": "空白页-暂无漏接诊单",
151
+      "font_class": "yunzhuanzhentongjiicon-",
152
+      "unicode": "e61a",
153
+      "unicode_decimal": 58906
154
+    },
155
+    {
156
+      "icon_id": "7035784",
157
+      "name": "增加",
158
+      "font_class": "tag27fuben",
159
+      "unicode": "e614",
160
+      "unicode_decimal": 58900
161
+    },
162
+    {
163
+      "icon_id": "8092249",
164
+      "name": "轨迹起点",
165
+      "font_class": "qidian",
166
+      "unicode": "e6e7",
167
+      "unicode_decimal": 59111
168
+    },
169
+    {
170
+      "icon_id": "10193579",
171
+      "name": "搜索",
172
+      "font_class": "search",
173
+      "unicode": "e651",
174
+      "unicode_decimal": 58961
175
+    },
176
+    {
177
+      "icon_id": "768745",
178
+      "name": "进行中",
179
+      "font_class": "shouye10",
180
+      "unicode": "e63f",
181
+      "unicode_decimal": 58943
182
+    },
183
+    {
184
+      "icon_id": "765558",
185
+      "name": "提醒",
186
+      "font_class": "shouye9",
187
+      "unicode": "e629",
188
+      "unicode_decimal": 58921
189
+    },
190
+    {
191
+      "icon_id": "4024735",
192
+      "name": "录音",
193
+      "font_class": "luyin",
194
+      "unicode": "e6c5",
195
+      "unicode_decimal": 59077
196
+    },
197
+    {
198
+      "icon_id": "6678312",
199
+      "name": "下  拉 (1)",
200
+      "font_class": "xiala2",
201
+      "unicode": "e669",
202
+      "unicode_decimal": 58985
203
+    },
204
+    {
205
+      "icon_id": "6771223",
206
+      "name": "问好",
207
+      "font_class": "wenhao",
208
+      "unicode": "e7d2",
209
+      "unicode_decimal": 59346
210
+    },
211
+    {
212
+      "icon_id": "5082433",
213
+      "name": "科室导诊#bl",
214
+      "font_class": "keshidaozhen",
215
+      "unicode": "ead2",
216
+      "unicode_decimal": 60114
217
+    },
218
+    {
219
+      "icon_id": "3095282",
220
+      "name": "已-配送 ",
221
+      "font_class": "yi-peisong",
222
+      "unicode": "e647",
223
+      "unicode_decimal": 58951
224
+    },
225
+    {
226
+      "icon_id": "3264610",
227
+      "name": "未-配送",
228
+      "font_class": "wei-peisong",
229
+      "unicode": "e662",
230
+      "unicode_decimal": 58978
231
+    },
232
+    {
233
+      "icon_id": "5094525",
234
+      "name": "数据源总数",
235
+      "font_class": "shujuyuanzongshu",
236
+      "unicode": "e650",
237
+      "unicode_decimal": 58960
238
+    },
239
+    {
240
+      "icon_id": "4195869",
241
+      "name": "统计",
242
+      "font_class": "tongji",
243
+      "unicode": "e6db",
244
+      "unicode_decimal": 59099
245
+    },
246
+    {
247
+      "icon_id": "765433",
248
+      "name": "历史记录",
249
+      "font_class": "shouye8",
250
+      "unicode": "e621",
251
+      "unicode_decimal": 58913
252
+    },
253
+    {
254
+      "icon_id": "782321",
255
+      "name": "说明",
256
+      "font_class": "icon3",
257
+      "unicode": "e654",
258
+      "unicode_decimal": 58964
259
+    },
260
+    {
261
+      "icon_id": "2938506",
262
+      "name": "统计报表",
263
+      "font_class": "tongjibaobiao",
264
+      "unicode": "e677",
265
+      "unicode_decimal": 58999
266
+    },
267
+    {
268
+      "icon_id": "3164198",
269
+      "name": "床位",
270
+      "font_class": "chuangwei",
271
+      "unicode": "e64a",
272
+      "unicode_decimal": 58954
273
+    },
274
+    {
275
+      "icon_id": "4965634",
276
+      "name": "排序-上",
277
+      "font_class": "paixu-shang",
278
+      "unicode": "eeeb",
279
+      "unicode_decimal": 61163
280
+    },
281
+    {
282
+      "icon_id": "4965639",
283
+      "name": "排序-下",
284
+      "font_class": "paixu-xia",
285
+      "unicode": "eeec",
286
+      "unicode_decimal": 61164
287
+    },
288
+    {
289
+      "icon_id": "689267",
290
+      "name": "排序箭头上",
291
+      "font_class": "paixujiantoushang",
292
+      "unicode": "e7fe",
293
+      "unicode_decimal": 59390
294
+    },
295
+    {
296
+      "icon_id": "689268",
297
+      "name": "排序箭头下",
298
+      "font_class": "paixujiantouxia",
299
+      "unicode": "e7ff",
300
+      "unicode_decimal": 59391
301
+    },
302
+    {
303
+      "icon_id": "1053844",
304
+      "name": "单选框-选中",
305
+      "font_class": "webicon19",
306
+      "unicode": "e67d",
307
+      "unicode_decimal": 59005
308
+    },
309
+    {
310
+      "icon_id": "1053854",
311
+      "name": "单选框-未选中",
312
+      "font_class": "webicon206",
313
+      "unicode": "e684",
314
+      "unicode_decimal": 59012
315
+    },
316
+    {
317
+      "icon_id": "479506",
318
+      "name": "向右",
319
+      "font_class": "xiangyou",
320
+      "unicode": "e637",
321
+      "unicode_decimal": 58935
322
+    },
323
+    {
324
+      "icon_id": "814447",
325
+      "name": "向左",
326
+      "font_class": "xiangzuo2",
327
+      "unicode": "e6b0",
328
+      "unicode_decimal": 59056
329
+    },
330
+    {
331
+      "icon_id": "383685",
332
+      "name": "实五角星",
333
+      "font_class": "shiwujiaoxing",
334
+      "unicode": "e635",
335
+      "unicode_decimal": 58933
336
+    },
337
+    {
338
+      "icon_id": "287187",
339
+      "name": "下拉箭头",
340
+      "font_class": "xialajiantou",
341
+      "unicode": "e638",
342
+      "unicode_decimal": 58936
343
+    },
344
+    {
345
+      "icon_id": "3055031",
346
+      "name": "复选框。",
347
+      "font_class": "fuxuankuang",
348
+      "unicode": "e639",
349
+      "unicode_decimal": 58937
350
+    },
351
+    {
352
+      "icon_id": "3422864",
353
+      "name": "复选框 (1)-01",
354
+      "font_class": "fuxuankuang-",
355
+      "unicode": "e646",
356
+      "unicode_decimal": 58950
357
+    },
358
+    {
359
+      "icon_id": "3292558",
360
+      "name": "向左",
361
+      "font_class": "xiangzuo1",
362
+      "unicode": "e673",
363
+      "unicode_decimal": 58995
364
+    },
365
+    {
366
+      "icon_id": "3315133",
367
+      "name": "消息",
368
+      "font_class": "xiaoxi",
369
+      "unicode": "e617",
370
+      "unicode_decimal": 58903
371
+    },
372
+    {
373
+      "icon_id": "4242826",
374
+      "name": "上拉2-01 (2)",
375
+      "font_class": "shangla-",
376
+      "unicode": "e628",
377
+      "unicode_decimal": 58920
378
+    },
379
+    {
380
+      "icon_id": "2015246",
381
+      "name": "双箭头(向右)-01",
382
+      "font_class": "shuangjiantouxiangyou-",
383
+      "unicode": "e71e",
384
+      "unicode_decimal": 59166
385
+    },
386
+    {
387
+      "icon_id": "100733",
388
+      "name": "失败",
389
+      "font_class": "shibai",
390
+      "unicode": "e626",
391
+      "unicode_decimal": 58918
392
+    },
393
+    {
394
+      "icon_id": "3668000",
395
+      "name": "对勾",
396
+      "font_class": "duigou",
397
+      "unicode": "e602",
398
+      "unicode_decimal": 58882
399
+    },
400
+    {
401
+      "icon_id": "765340",
402
+      "name": "定位",
403
+      "font_class": "shouye7",
404
+      "unicode": "e619",
405
+      "unicode_decimal": 58905
406
+    },
407
+    {
408
+      "icon_id": "1312798",
409
+      "name": "下拉2-01",
410
+      "font_class": "xiala2-01",
411
+      "unicode": "e62e",
412
+      "unicode_decimal": 58926
413
+    },
414
+    {
415
+      "icon_id": "704337",
416
+      "name": "下拉",
417
+      "font_class": "xiala",
418
+      "unicode": "e68f",
419
+      "unicode_decimal": 59023
420
+    },
421
+    {
422
+      "icon_id": "765262",
423
+      "name": "首页",
424
+      "font_class": "shouye2",
425
+      "unicode": "e613",
426
+      "unicode_decimal": 58899
427
+    },
428
+    {
429
+      "icon_id": "765290",
430
+      "name": "我的",
431
+      "font_class": "shouye3",
432
+      "unicode": "e615",
433
+      "unicode_decimal": 58901
434
+    },
435
+    {
436
+      "icon_id": "765318",
437
+      "name": "药丸",
438
+      "font_class": "shouye4",
439
+      "unicode": "e616",
440
+      "unicode_decimal": 58902
441
+    },
442
+    {
443
+      "icon_id": "765360",
444
+      "name": "设置",
445
+      "font_class": "shouye5",
446
+      "unicode": "e61c",
447
+      "unicode_decimal": 58908
448
+    },
449
+    {
450
+      "icon_id": "769223",
451
+      "name": "待就诊",
452
+      "font_class": "shouye6",
453
+      "unicode": "e642",
454
+      "unicode_decimal": 58946
455
+    },
456
+    {
457
+      "icon_id": "784528",
458
+      "name": "日历",
459
+      "font_class": "icon",
460
+      "unicode": "e65f",
461
+      "unicode_decimal": 58975
462
+    },
463
+    {
464
+      "icon_id": "988620",
465
+      "name": "热度",
466
+      "font_class": "icon1",
467
+      "unicode": "e68e",
468
+      "unicode_decimal": 59022
469
+    },
470
+    {
471
+      "icon_id": "1167542",
472
+      "name": "化学",
473
+      "font_class": "icon2",
474
+      "unicode": "e69e",
475
+      "unicode_decimal": 59038
476
+    },
477
+    {
478
+      "icon_id": "3861282",
479
+      "name": "倒计时",
480
+      "font_class": "daojishi",
481
+      "unicode": "e668",
482
+      "unicode_decimal": 58984
483
+    },
484
+    {
485
+      "icon_id": "1353",
486
+      "name": "向左",
487
+      "font_class": "xiangzuo",
488
+      "unicode": "e601",
489
+      "unicode_decimal": 58881
490
+    },
491
+    {
492
+      "icon_id": "398877",
493
+      "name": "好评",
494
+      "font_class": "haoping",
495
+      "unicode": "e612",
496
+      "unicode_decimal": 58898
497
+    },
498
+    {
499
+      "icon_id": "695135",
500
+      "name": "更多 大",
501
+      "font_class": "gengduoda",
502
+      "unicode": "e633",
503
+      "unicode_decimal": 58931
504
+    },
505
+    {
506
+      "icon_id": "765588",
507
+      "name": "药箱",
508
+      "font_class": "shouye1",
509
+      "unicode": "e62d",
510
+      "unicode_decimal": 58925
511
+    },
512
+    {
513
+      "icon_id": "1351206",
514
+      "name": "好评",
515
+      "font_class": "haoping1",
516
+      "unicode": "e640",
517
+      "unicode_decimal": 58944
518
+    },
519
+    {
520
+      "icon_id": "2604472",
521
+      "name": "关闭",
522
+      "font_class": "guanbi",
523
+      "unicode": "e60c",
524
+      "unicode_decimal": 58892
525
+    },
526
+    {
527
+      "icon_id": "2675116",
528
+      "name": "搜索",
529
+      "font_class": "sousuo",
530
+      "unicode": "e634",
531
+      "unicode_decimal": 58932
532
+    },
533
+    {
534
+      "icon_id": "982411",
535
+      "name": "下拉1",
536
+      "font_class": "xiala1",
537
+      "unicode": "e66b",
538
+      "unicode_decimal": 58987
539
+    },
540
+    {
541
+      "icon_id": "1838258",
542
+      "name": "首页",
543
+      "font_class": "shouye",
544
+      "unicode": "e605",
545
+      "unicode_decimal": 58885
546
+    },
547
+    {
548
+      "icon_id": "3391239",
549
+      "name": "列表",
550
+      "font_class": "liebiao",
551
+      "unicode": "e632",
552
+      "unicode_decimal": 58930
553
+    },
554
+    {
555
+      "icon_id": "3721152",
556
+      "name": "统计分析",
557
+      "font_class": "tongjifenxi",
558
+      "unicode": "e712",
559
+      "unicode_decimal": 59154
560
+    },
561
+    {
562
+      "icon_id": "3022726",
563
+      "name": "科室介绍",
564
+      "font_class": "keshijieshao",
565
+      "unicode": "e600",
566
+      "unicode_decimal": 58880
567
+    }
568
+  ]
569
+}

File diff suppressed because it is too large
+ 266 - 0
src/assets/font/iconfont.svg


BIN
src/assets/font/iconfont.ttf


BIN
src/assets/font/iconfont.woff


BIN
src/assets/font/iconfont.woff2


BIN
src/assets/img/bg.jpg


BIN
src/assets/img/image_no1.png


BIN
src/assets/img/image_no2.png


BIN
src/assets/img/image_title01.png


BIN
src/assets/img/image_title02.png


BIN
src/assets/img/logo.png


+ 147 - 0
src/assets/js/flexible.js

@@ -0,0 +1,147 @@
1
+(function (win, lib) {
2
+  var doc = win.document
3
+  var docEl = doc.documentElement
4
+  var metaEl = doc.querySelector('meta[name="viewport"]')
5
+  var flexibleEl = doc.querySelector('meta[name="flexible"]')
6
+  var dpr = 0
7
+  var scale = 0
8
+  var tid
9
+  var flexible = lib.flexible || (lib.flexible = {})
10
+
11
+  if (metaEl) {
12
+    console.warn('将根据已有的meta标签来设置缩放比例')
13
+    var match = metaEl
14
+      .getAttribute('content')
15
+      // eslint-disable-next-line no-useless-escape
16
+      .match(/initial\-scale=([\d\.]+)/)
17
+    if (match) {
18
+      scale = parseFloat(match[1])
19
+      dpr = parseInt(1 / scale)
20
+    }
21
+  } else if (flexibleEl) {
22
+    var content = flexibleEl.getAttribute('content')
23
+    if (content) {
24
+      // eslint-disable-next-line no-useless-escape
25
+      var initialDpr = content.match(/initial\-dpr=([\d\.]+)/)
26
+      // eslint-disable-next-line no-useless-escape
27
+      var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/)
28
+      if (initialDpr) {
29
+        dpr = parseFloat(initialDpr[1])
30
+        scale = parseFloat((1 / dpr).toFixed(2))
31
+      }
32
+      if (maximumDpr) {
33
+        dpr = parseFloat(maximumDpr[1])
34
+        scale = parseFloat((1 / dpr).toFixed(2))
35
+      }
36
+    }
37
+  }
38
+
39
+  if (!dpr && !scale) {
40
+    // eslint-disable-next-line no-unused-vars
41
+    var isAndroid = win.navigator.appVersion.match(/android/gi)
42
+    var isIPhone = win.navigator.appVersion.match(/iphone/gi)
43
+    var devicePixelRatio = win.devicePixelRatio
44
+    if (isIPhone) {
45
+      // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
46
+      if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
47
+        dpr = 3
48
+      } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)) {
49
+        dpr = 2
50
+      } else {
51
+        dpr = 1
52
+      }
53
+    } else {
54
+      // 其他设备下,仍旧使用1倍的方案
55
+      dpr = 1
56
+    }
57
+    scale = 1 / dpr
58
+  }
59
+
60
+  docEl.setAttribute('data-dpr', dpr)
61
+  if (!metaEl) {
62
+    metaEl = doc.createElement('meta')
63
+    metaEl.setAttribute('name', 'viewport')
64
+    metaEl.setAttribute(
65
+      'content',
66
+      'initial-scale=' +
67
+        scale +
68
+        ', maximum-scale=' +
69
+        scale +
70
+        ', minimum-scale=' +
71
+        scale +
72
+        ', user-scalable=no'
73
+    )
74
+    if (docEl.firstElementChild) {
75
+      docEl.firstElementChild.appendChild(metaEl)
76
+    } else {
77
+      var wrap = doc.createElement('div')
78
+      wrap.appendChild(metaEl)
79
+      doc.write(wrap.innerHTML)
80
+    }
81
+  }
82
+
83
+  function refreshRem () {
84
+    var width = docEl.getBoundingClientRect().width
85
+    // 最小1366px,最大适配2560px
86
+    if (width / dpr < 1366) {
87
+      width = 1366 * dpr
88
+    } else if (width / dpr > 2560) {
89
+      width = 2560 * dpr
90
+    }
91
+    // 设置成24等份,设计稿时1920px的,这样1rem就是80px
92
+    var rem = width / 24
93
+    docEl.style.fontSize = rem + 'px'
94
+    flexible.rem = win.rem = rem
95
+  }
96
+
97
+  win.addEventListener(
98
+    'resize',
99
+    function () {
100
+      clearTimeout(tid)
101
+      tid = setTimeout(refreshRem, 300)
102
+    },
103
+    false
104
+  )
105
+  win.addEventListener(
106
+    'pageshow',
107
+    function (e) {
108
+      if (e.persisted) {
109
+        clearTimeout(tid)
110
+        tid = setTimeout(refreshRem, 300)
111
+      }
112
+    },
113
+    false
114
+  )
115
+
116
+  if (doc.readyState === 'complete') {
117
+    doc.body.style.fontSize = 12 * dpr + 'px'
118
+  } else {
119
+    doc.addEventListener(
120
+      'DOMContentLoaded',
121
+      // eslint-disable-next-line no-unused-vars
122
+      function (e) {
123
+        doc.body.style.fontSize = 12 * dpr + 'px'
124
+      },
125
+      false
126
+    )
127
+  }
128
+
129
+  refreshRem()
130
+
131
+  flexible.dpr = win.dpr = dpr
132
+  flexible.refreshRem = refreshRem
133
+  flexible.rem2px = function (d) {
134
+    var val = parseFloat(d) * this.rem
135
+    if (typeof d === 'string' && d.match(/rem$/)) {
136
+      val += 'px'
137
+    }
138
+    return val
139
+  }
140
+  flexible.px2rem = function (d) {
141
+    var val = parseFloat(d) / this.rem
142
+    if (typeof d === 'string' && d.match(/px$/)) {
143
+      val += 'rem'
144
+    }
145
+    return val
146
+  }
147
+})(window, window.lib || (window.lib = {}))

+ 1 - 0
src/assets/less/_variables.less

@@ -0,0 +1 @@
1
+// 颜色

+ 75 - 0
src/assets/less/style.less

@@ -0,0 +1,75 @@
1
+@import "./_variables.less";
2
+@import "./../font/iconfont.css";
3
+
4
+//  全局样式
5
+* {
6
+  margin: 0;
7
+  padding: 0;
8
+  list-style-type: none;
9
+  box-sizing: border-box;
10
+  outline: none;
11
+}
12
+
13
+html {
14
+  margin: 0;
15
+  padding: 0;
16
+}
17
+
18
+body {
19
+  font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
20
+  line-height: 1.2em;
21
+  margin: 0;
22
+  padding: 0;
23
+}
24
+h1,h2,h3,h4,h5,h6{
25
+  font-weight: normal;
26
+}
27
+i,em{
28
+  font-style: normal;
29
+}
30
+
31
+a {
32
+  color: #343440;
33
+  text-decoration: none;
34
+}
35
+
36
+.clearfix {
37
+  &::after {
38
+    content: "";
39
+    display: table;
40
+    height: 0;
41
+    line-height: 0;
42
+    visibility: hidden;
43
+    clear: both;
44
+  }
45
+}
46
+
47
+//浮动
48
+.float-r {
49
+  float: right;
50
+}
51
+
52
+//浮动
53
+.float-l {
54
+  float: left;
55
+}
56
+
57
+// 字体加粗
58
+.fw-b {
59
+  font-weight: bold;
60
+}
61
+
62
+//文章一行显示,多余省略号显示
63
+.title-item {
64
+  overflow: hidden;
65
+  text-overflow: ellipsis;
66
+  white-space: nowrap;
67
+}
68
+//文章二行显示,多余省略号显示
69
+.ellipsis {
70
+  display: -webkit-box !important;
71
+  text-overflow: ellipsis;
72
+  overflow: hidden;
73
+  -webkit-line-clamp: 2;
74
+  -webkit-box-orient: vertical;
75
+}

+ 203 - 0
src/components/AppHeader.vue

@@ -0,0 +1,203 @@
1
+<template>
2
+  <header class="app-header">
3
+    <!-- 头部线条及标题 -->
4
+    <div class="app-header__main">
5
+      <div class="app-header__main--left"></div>
6
+      <div class="app-header__main--right"></div>
7
+      <div class="app-header__main--leftBottom"></div>
8
+      <div class="app-header__main--rightBottom"></div>
9
+      <h1 class="app-header__title">
10
+        <img class="app-header__logo" src="./../assets/img/logo.png">
11
+        大势输送保障管理平台
12
+      </h1>
13
+    </div>
14
+    <!-- /头部线条及标题 -->
15
+    <div class="app-header__content">
16
+      <!-- 今日新冠送检,标本运输数,患者陪检 -->
17
+      <AppToday></AppToday>
18
+      <!-- /今日新冠送检,标本运输数,患者陪检 -->
19
+      <!-- 时间 -->
20
+      <div class="app-header__contentTime">{{time|weekFormat}}<time>{{time|timeFormat}}</time></div>
21
+      <!-- /时间 -->
22
+    </div>
23
+  </header>
24
+</template>
25
+
26
+<script>
27
+import AppToday from './AppToday'
28
+export default {
29
+  name: 'AppHeader',
30
+  components: {
31
+    AppToday
32
+  },
33
+  data () {
34
+    return {
35
+      time: new Date().getTime(), // 时间戳
36
+      timer: null, // 时间定时器
37
+      week: ''// 星期
38
+    }
39
+  },
40
+  filters: {
41
+    // 格式化时间
42
+    timeFormat (time) {
43
+      const newDate = new Date(time)
44
+      const hours = newDate.getHours().toString().padStart(2, '0')
45
+      const minutes = newDate.getMinutes().toString().padStart(2, '0')
46
+      const seconds = newDate.getSeconds().toString().padStart(2, '0')
47
+      return `${hours}:${minutes}:${seconds}`
48
+    },
49
+    // 获得当前的星期
50
+    weekFormat (time) {
51
+      const newDate = new Date(time)
52
+      const week = newDate.getDay()
53
+      const weeks = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
54
+      return `${weeks[week]}`
55
+    }
56
+  },
57
+  methods: {
58
+    // 时间日期
59
+    runTime () {
60
+      // const t1 = Date.now()
61
+      clearTimeout(this.timer)
62
+      this.timer = setTimeout(() => {
63
+        // const t2 = Date.now()
64
+        // console.log(t2 - t1)
65
+        // this.time += 1000
66
+        this.time = Date.now()
67
+        this.runTime()
68
+      }, 500)
69
+    }
70
+  },
71
+  mounted () {
72
+    this.runTime()
73
+  },
74
+  beforeDestroy () {
75
+    clearTimeout(this.timer)
76
+  }
77
+}
78
+</script>
79
+
80
+<style lang="less">
81
+.app-header {
82
+  position: relative;
83
+  height: 1.375rem;
84
+  padding-top: 0.2rem;
85
+  // 边框线
86
+  .app-header__main {
87
+    width: 5.15rem;
88
+    height: 0.675rem;
89
+    margin: 0 auto;
90
+    border-bottom: 1px solid #68ffff;
91
+    position: relative;
92
+    .app-header__title{
93
+      display: flex;
94
+      justify-content: center;
95
+      align-items: center;
96
+      .app-header__logo{
97
+        height: .6125rem;
98
+      }
99
+    }
100
+    .app-header__main--left {
101
+      position: absolute;
102
+      width: calc(50vw - 3.17rem);
103
+      height: 1px;
104
+      background-image: linear-gradient(#30c8ff, #68f8ff);
105
+      top: 1px;
106
+      left: calc(2.81rem - 50vw);
107
+    }
108
+    .app-header__main--right {
109
+      position: absolute;
110
+      width: calc(50vw - 3.17rem);
111
+      height: 1px;
112
+      background-image: linear-gradient(#68f8ff, #30c8ff);
113
+      top: 1px;
114
+      right: calc(2.81rem - 50vw);
115
+    }
116
+    .app-header__main--leftBottom {
117
+      position: absolute;
118
+      left: -5.7rem;
119
+      top: 0.15rem;
120
+      width: 5.2375rem;
121
+      height: 0.075rem;
122
+      background-color: rgba(253, 255, 250, 0.2);
123
+      transform: skewX(45deg);
124
+      border-top: 1px solid #489ec9;
125
+    }
126
+    .app-header__main--rightBottom {
127
+      position: absolute;
128
+      right: -5.7rem;
129
+      top: 0.15rem;
130
+      width: 5.2375rem;
131
+      height: 0.075rem;
132
+      background-color: rgba(253, 255, 250, 0.2);
133
+      transform: skewX(-45deg);
134
+      border-top: 1px solid #489ec9;
135
+    }
136
+    &::before {
137
+      content: "";
138
+      position: absolute;
139
+      left: -0.61rem;
140
+      bottom: 0.21rem;
141
+      width: 0.75rem;
142
+      height: 0.125rem;
143
+      border-top: 1px solid #5ceef9;
144
+      transform: rotate(60deg);
145
+    }
146
+    &::after {
147
+      content: "";
148
+      position: absolute;
149
+      right: -0.61rem;
150
+      bottom: 0.21rem;
151
+      width: 0.75rem;
152
+      height: 0.125rem;
153
+      border-top: 1px solid #5ceef9;
154
+      transform: rotate(-60deg);
155
+    }
156
+    .app-header__title {
157
+      position: relative;
158
+      bottom: 0.125rem;
159
+      font-size: 0.425rem;
160
+      color: #fff;
161
+      height: 0.75rem;
162
+      display: flex;
163
+      justify-content: center;
164
+      align-items: center;
165
+    }
166
+  }
167
+  // 头部内容
168
+  .app-header__content{
169
+    position: absolute;
170
+    left: 0;
171
+    top: 0.4rem;
172
+    display: flex;
173
+    justify-content: space-between;
174
+    align-items: center;
175
+    width: 100%;
176
+    height: 0.475rem;
177
+    .app-header__contentNews{
178
+      display: flex;
179
+      justify-content: space-between;
180
+      align-items: center;
181
+      .app-header__contentNewsItem{
182
+        font-size: .2rem;
183
+        color: #fff;
184
+        margin-right: .4rem;
185
+        em{
186
+          color: #70c2ab;
187
+          margin-left: .2rem;
188
+          i{
189
+            color: #c27073;
190
+          }
191
+        }
192
+      }
193
+    }
194
+    .app-header__contentTime{
195
+      color: #fff;
196
+      font-size: .3rem;
197
+      time{
198
+        margin-left: .2rem;
199
+      }
200
+    }
201
+  }
202
+}
203
+</style>

+ 58 - 0
src/components/AppToday.vue

@@ -0,0 +1,58 @@
1
+<template>
2
+  <div class="app-header__contentNews">
3
+    <div class="app-header__contentNewsItem">
4
+      今日新冠送检
5
+      <em>
6
+        <i>{{allData.todayNovelCoronavirus}}</i>/{{allData.todayNovelCoronavirusAll}}
7
+      </em>
8
+    </div>
9
+    <div class="app-header__contentNewsItem">
10
+      今日标本运输数
11
+      <em>
12
+        <i>{{allData.todaySample}}</i>/{{allData.todaySampleAll}}
13
+      </em>
14
+    </div>
15
+    <div class="app-header__contentNewsItem">
16
+      今日患者陪检
17
+      <em>{{allData.todayPaiJian}}/{{allData.todayPaiJianAll}}</em>
18
+    </div>
19
+  </div>
20
+</template>
21
+
22
+<script>
23
+import { post, timer1 } from './../http/http'
24
+export default {
25
+  name: 'AppToday',
26
+  inject: ['hospitalId'],
27
+  data () {
28
+    return {
29
+      allData: {}, // 数据对象
30
+      timer: null// 轮询定时器
31
+    }
32
+  },
33
+  methods: {
34
+    // 获取今日新冠送检,今日标本运输数,今日患者陪检
35
+    async getTodayData () {
36
+      const result = await post(`/largeScreen/getData/todayTitle/${this.hospitalId}`, {})
37
+      this.allData = result
38
+      this.polling()
39
+    },
40
+    // 轮询请求
41
+    polling () {
42
+      clearTimeout(this.timer)
43
+      this.timer = setTimeout(() => {
44
+        this.getTodayData()
45
+      }, timer1)
46
+    }
47
+  },
48
+  mounted () {
49
+    this.getTodayData()
50
+  },
51
+  beforeDestroy () {
52
+    clearTimeout(this.timer)
53
+  }
54
+}
55
+</script>
56
+
57
+<style lang="less">
58
+</style>

+ 298 - 0
src/components/BusinessTypeRatio.vue

@@ -0,0 +1,298 @@
1
+<template>
2
+  <div class="business-type-ratio" ref="BusinessTypeRatio"></div>
3
+</template>
4
+
5
+<script>
6
+import echarts from 'echarts'
7
+import { post, timer10 } from './../http/http'
8
+export default {
9
+  name: 'BusinessTypeRatio',
10
+  inject: ['hospitalId'],
11
+  data () {
12
+    return {
13
+      timer: null,
14
+      myChart: null,
15
+      associationTypeProportion: [],
16
+      associationTypeProportionNum: [],
17
+      associationTypeProportionName: [],
18
+      associationTypeProportionAll: []
19
+    }
20
+  },
21
+  methods: {
22
+    // 画图
23
+    draw () {
24
+      const that = this
25
+      this.myChart = echarts.init(this.$refs.BusinessTypeRatio)
26
+      const option = {
27
+        tooltip: {
28
+          trigger: 'item',
29
+          formatter: '{a} <br/>{b} : {c} ({d}%)'
30
+        },
31
+        grid: {
32
+          show: false,
33
+          top: '5%',
34
+          left: '5%',
35
+          right: '5%',
36
+          bottom: '0%'
37
+        },
38
+        // legend: {
39
+        //   left: '20%',
40
+        //   orient: 'horizontal',
41
+        //   itemWidth: 8,
42
+        //   itemHeight: 8,
43
+        //   icon: 'rect',
44
+        //   bottom: '0%',
45
+        //   data: this.associationTypeProportionName,
46
+        //   textStyle: {
47
+        //     color: '#fff'
48
+        //   },
49
+        //   formatter (name) {
50
+        //     const arr = that.associationTypeProportionAll.filter(item => item[0] === name)
51
+        //     return `${name} ${arr[0][1]}单 ${arr[0][2]}%`
52
+        //   }
53
+        // },
54
+        legend: [
55
+          {
56
+            right: '55%',
57
+            orient: 'horizontal',
58
+            itemWidth: 8,
59
+            itemHeight: 8,
60
+            icon: 'rect',
61
+            bottom: '20%',
62
+            data: this.associationTypeProportionName.slice(
63
+              0,
64
+              Math.ceil(this.associationTypeProportionName.length / 2)
65
+            ),
66
+            textStyle: {
67
+              color: '#fff'
68
+            },
69
+            formatter (name) {
70
+              const arr = that.associationTypeProportionAll.filter(
71
+                (item) => item[0] === name
72
+              )
73
+              return `${name} ${arr[0][1]}单 ${arr[0][2]}%`
74
+            }
75
+          },
76
+          {
77
+            left: '55%',
78
+            orient: 'horizontal',
79
+            itemWidth: 8,
80
+            itemHeight: 8,
81
+            icon: 'rect',
82
+            bottom: '24%',
83
+            data: this.associationTypeProportionName.slice(
84
+              Math.ceil(this.associationTypeProportionName.length / 2),
85
+              this.associationTypeProportionName.length
86
+            ),
87
+            textStyle: {
88
+              color: '#fff'
89
+            },
90
+            formatter (name) {
91
+              const arr = that.associationTypeProportionAll.filter(
92
+                (item) => item[0] === name
93
+              )
94
+              return `${name} ${arr[0][1]}单 ${arr[0][2]}%`
95
+            }
96
+          }
97
+        ],
98
+        color: [
99
+          {
100
+            type: 'linear',
101
+            x: 0,
102
+            y: 0,
103
+            x2: 0,
104
+            y2: 1,
105
+            colorStops: [
106
+              {
107
+                offset: 0,
108
+                color: '#c27073' // 0% 处的颜色
109
+              },
110
+              {
111
+                offset: 1,
112
+                color: 'rgba(194, 112, 115, 0.5)' // 100% 处的颜色
113
+              }
114
+            ],
115
+            global: false // 缺省为 false
116
+          },
117
+          {
118
+            type: 'linear',
119
+            x: 0,
120
+            y: 0,
121
+            x2: 0,
122
+            y2: 1,
123
+            colorStops: [
124
+              {
125
+                offset: 0,
126
+                color: '#c2ab70' // 0% 处的颜色
127
+              },
128
+              {
129
+                offset: 1,
130
+                color: 'rgba(194, 171, 112, 0.5)' // 100% 处的颜色
131
+              }
132
+            ],
133
+            global: false // 缺省为 false
134
+          },
135
+          {
136
+            type: 'linear',
137
+            x: 0,
138
+            y: 0,
139
+            x2: 0,
140
+            y2: 1,
141
+            colorStops: [
142
+              {
143
+                offset: 0,
144
+                color: '#70c2ab' // 0% 处的颜色
145
+              },
146
+              {
147
+                offset: 1,
148
+                color: 'rgba(112, 194, 171, 0.5)' // 100% 处的颜色
149
+              }
150
+            ],
151
+            global: false // 缺省为 false
152
+          },
153
+          {
154
+            type: 'linear',
155
+            x: 0,
156
+            y: 0,
157
+            x2: 0,
158
+            y2: 1,
159
+            colorStops: [
160
+              {
161
+                offset: 0,
162
+                color: '#70c282' // 0% 处的颜色
163
+              },
164
+              {
165
+                offset: 1,
166
+                color: 'rgba(112, 194, 130, 0.5)' // 100% 处的颜色
167
+              }
168
+            ],
169
+            global: false // 缺省为 false
170
+          },
171
+          {
172
+            type: 'linear',
173
+            x: 0,
174
+            y: 0,
175
+            x2: 0,
176
+            y2: 1,
177
+            colorStops: [
178
+              {
179
+                offset: 0,
180
+                color: '#9cc270' // 0% 处的颜色
181
+              },
182
+              {
183
+                offset: 1,
184
+                color: 'rgba(156, 194, 112, 0.5)' // 100% 处的颜色
185
+              }
186
+            ],
187
+            global: false // 缺省为 false
188
+          },
189
+          {
190
+            type: 'linear',
191
+            x: 0,
192
+            y: 0,
193
+            x2: 0,
194
+            y2: 1,
195
+            colorStops: [
196
+              {
197
+                offset: 0,
198
+                color: '#709cc2' // 0% 处的颜色
199
+              },
200
+              {
201
+                offset: 1,
202
+                color: 'rgba(112, 156, 194, 0.5)' // 100% 处的颜色
203
+              }
204
+            ],
205
+            global: false // 缺省为 false
206
+          },
207
+          {
208
+            type: 'linear',
209
+            x: 0,
210
+            y: 0,
211
+            x2: 0,
212
+            y2: 1,
213
+            colorStops: [
214
+              {
215
+                offset: 0,
216
+                color: '#c270b0' // 0% 处的颜色
217
+              },
218
+              {
219
+                offset: 1,
220
+                color: 'rgba(194, 112, 176, 0.5)' // 100% 处的颜色
221
+              }
222
+            ],
223
+            global: false // 缺省为 false
224
+          }
225
+        ],
226
+        series: [
227
+          {
228
+            name: '数据统计',
229
+            type: 'pie',
230
+            center: ['50%', '35%'],
231
+            roseType: 'radius',
232
+            label: {
233
+              normal: {
234
+                show: false
235
+              },
236
+              emphasis: {
237
+                show: false
238
+              }
239
+            },
240
+            lableLine: {
241
+              normal: {
242
+                show: false
243
+              },
244
+              emphasis: {
245
+                show: true
246
+              }
247
+            },
248
+            data: this.associationTypeProportion
249
+          }
250
+        ]
251
+      }
252
+      this.myChart.setOption(option)
253
+    },
254
+    // 获取数据
255
+    async getData () {
256
+      const srartTime = this.$moment()
257
+        .subtract(29, 'days')
258
+        .format('YYYY-MM-DD') // 近三十天
259
+      const endTime = this.$moment().format('YYYY-MM-DD') // 今天
260
+      const result = await post(
261
+        `/largeScreen/getData/associationTypeProportion/${this.hospitalId}`,
262
+        { srartTime, endTime }
263
+      )
264
+      this.associationTypeProportionNum = []
265
+      this.associationTypeProportionName = []
266
+      this.associationTypeProportion = []
267
+      this.associationTypeProportionAll = result.associationTypeProportion
268
+      result.associationTypeProportion.forEach((item) => {
269
+        this.associationTypeProportionNum.push(item[1]) // 获取到的数据
270
+        this.associationTypeProportionName.push(item[0]) // 获取到的名称
271
+        this.associationTypeProportion.push({ value: item[1], name: item[0] }) // 获取到的名称
272
+      })
273
+      this.draw()
274
+      this.polling()
275
+    },
276
+    // 轮询请求
277
+    polling () {
278
+      clearTimeout(this.timer)
279
+      this.timer = setTimeout(() => {
280
+        this.getData()
281
+      }, timer10)
282
+    }
283
+  },
284
+  mounted () {
285
+    this.getData()
286
+  },
287
+  beforeDestroy () {
288
+    clearTimeout(this.timer)
289
+  }
290
+}
291
+</script>
292
+
293
+<style lang="less">
294
+.business-type-ratio {
295
+  height: 7rem;
296
+  margin: 0 auto;
297
+}
298
+</style>

+ 104 - 0
src/components/DeliveryRate.vue

@@ -0,0 +1,104 @@
1
+<template>
2
+  <div class="delivery-rate">
3
+    <!-- <div class="delivery-rate__item" v-for="(workOrderOnTime,k) in workOrderOnTimes" :key="k" v-show="currentDictionary == k"> -->
4
+    <div class="delivery-rate__item">
5
+      <DeliveryRateLine :workOrderOnTime="workOrderOnTimes[currentDictionary]"></DeliveryRateLine>
6
+    </div>
7
+  </div>
8
+</template>
9
+
10
+<script>
11
+import DeliveryRateLine from './DeliveryRateLine.vue'
12
+import { post, timer11 } from './../http/http'
13
+export default {
14
+  name: 'DeliveryRate',
15
+  inject: ['hospitalId'],
16
+  props: {
17
+    // 当前tab索引
18
+    currentDictionary: {
19
+      type: Number,
20
+      default: 0
21
+    }
22
+  },
23
+  data () {
24
+    return {
25
+      timer: null,
26
+      timer1: null,
27
+      dictionary: [], // 字典数据
28
+      workOrderOnTimes: {}// 各类型数据汇总
29
+    }
30
+  },
31
+  methods: {
32
+    // tab轮询
33
+    autoNext () {
34
+      const ids = []
35
+      const len = this.dictionary.length
36
+      this.dictionary.forEach(item => {
37
+        ids.push(item[0])
38
+      })
39
+      let index = ids.indexOf(this.currentDictionary)
40
+      index++
41
+      if (index === len) {
42
+        index = 0
43
+      }
44
+      this.$emit('changeCurrentDictionary', this.dictionary[index][0])
45
+      clearTimeout(this.timer1)
46
+      this.timer1 = setTimeout(() => {
47
+        this.autoNext()
48
+      }, 10000)
49
+    },
50
+    // 获取字典数据
51
+    async getDictionary () {
52
+      const result = await post(
53
+        `/largeScreen/getData/getDictionary/${this.hospitalId}`,
54
+        { key: 'association_types' }
55
+      )
56
+      this.dictionary = result.dictionary
57
+      this.$emit('dictionaryHandle', JSON.stringify(this.dictionary))
58
+      this.dictionary.forEach(item => {
59
+        this.getData(item[0])
60
+      })
61
+      this.polling()
62
+    },
63
+    // 获取数据
64
+    async getData (id) {
65
+      const srartTime = this.$moment()
66
+        .subtract(29, 'days')
67
+        .format('YYYY-MM-DD') // 近三十天
68
+      const endTime = this.$moment().format('YYYY-MM-DD') // 今天
69
+      const result = await post(
70
+        `/largeScreen/getData/workOrderOnTime/${this.hospitalId}`,
71
+        { srartTime, endTime, associationId: id }
72
+      )
73
+      this.$set(this.workOrderOnTimes, id, result.workOrderOnTime)
74
+    },
75
+    // 轮询请求
76
+    polling () {
77
+      clearTimeout(this.timer)
78
+      clearTimeout(this.timer1)
79
+      this.timer = setTimeout(() => {
80
+        this.getDictionary()
81
+      }, timer11)
82
+      this.timer1 = setTimeout(() => {
83
+        this.autoNext()
84
+      }, 10000)
85
+    }
86
+  },
87
+  components: {
88
+    DeliveryRateLine
89
+  },
90
+  mounted () {
91
+    this.getDictionary()
92
+  },
93
+  beforeDestroy () {
94
+    clearTimeout(this.timer)
95
+  }
96
+}
97
+</script>
98
+
99
+<style lang="less">
100
+.delivery-rate {
101
+  height: 1.9375rem;
102
+  overflow: hidden;
103
+}
104
+</style>

+ 140 - 0
src/components/DeliveryRateLine.vue

@@ -0,0 +1,140 @@
1
+<template>
2
+    <div class="delivery-rate-line" ref="DeliveryRateLine" v-if="workOrderOnTime.length>0"></div>
3
+</template>
4
+
5
+<script>
6
+import echarts from 'echarts'
7
+export default {
8
+  name: 'DeliveryRateLine',
9
+  data () {
10
+    return {
11
+      myChart: null,
12
+      workOrderOnTimeNum: [],
13
+      workOrderOnTimeName: []
14
+    }
15
+  },
16
+  props: {
17
+    workOrderOnTime: {
18
+      type: Array,
19
+      default: () => []
20
+    }
21
+  },
22
+  methods: {
23
+    // 画图
24
+    draw () {
25
+      this.myChart = echarts.init(this.$refs.DeliveryRateLine)
26
+      const option = {
27
+        title: {
28
+          text: '按时送达率(%)',
29
+          left: 15,
30
+          textStyle: {
31
+            color: '#d4d6d7',
32
+            fontSize: 12
33
+          }
34
+        },
35
+        xAxis: {
36
+          type: 'category',
37
+          axisLabel: {
38
+            show: true,
39
+            textStyle: {
40
+              color: '#d4d6d7', // 更改坐标轴文字颜色
41
+              fontSize: 12 // 更改坐标轴文字大小
42
+            }
43
+          },
44
+          axisLine: {
45
+            lineStyle: {
46
+              color: '#709cc2' // 更改坐标轴颜色
47
+            }
48
+          },
49
+          axisTick: {
50
+            show: false
51
+          },
52
+          data: this.workOrderOnTimeName
53
+        },
54
+        yAxis: {
55
+          type: 'value',
56
+          max: 1,
57
+          min: 0,
58
+          interval: 0.25,
59
+          axisLabel: {
60
+            formatter (value) {
61
+              return value * 100
62
+            },
63
+            show: true,
64
+            textStyle: {
65
+              color: '#d4d6d7', // 更改坐标轴文字颜色
66
+              fontSize: 12 // 更改坐标轴文字大小
67
+            }
68
+          },
69
+          axisLine: {
70
+            lineStyle: {
71
+              color: '#709cc2' // 更改坐标轴颜色
72
+            }
73
+          },
74
+          axisTick: {
75
+            show: false
76
+          },
77
+          splitLine: {
78
+            // 网格线
79
+            lineStyle: {
80
+              color: ['rgba(255,255,255,0.1)'],
81
+              type: 'dashed' // 设置网格线类型 dotted:虚线   solid:实线
82
+            },
83
+            show: true // 隐藏或显示
84
+          }
85
+        },
86
+        grid: {
87
+          top: '20%',
88
+          bottom: '25%',
89
+          left: '5%',
90
+          right: '2%',
91
+          borderColor: 'rgba(255,255,255,0.1)'
92
+        },
93
+        series: [
94
+          {
95
+            data: this.workOrderOnTimeNum,
96
+            type: 'line',
97
+            symbol: 'circle',
98
+            symbolSize: 4,
99
+            label: {
100
+              show: true,
101
+              position: 'top',
102
+              textStyle: '#fff',
103
+              formatter (params) {
104
+                return (params.value * 100).toFixed(2) + '%'
105
+              }
106
+            },
107
+            itemStyle: {
108
+              normal: {
109
+                color: '#70c282', // 折点颜色
110
+                lineStyle: {
111
+                  color: '#70c282' // 折线颜色
112
+                }
113
+              }
114
+            }
115
+          }
116
+        ]
117
+      }
118
+      this.myChart.setOption(option)
119
+    }
120
+  },
121
+  updated () {
122
+    this.workOrderOnTimeNum = []
123
+    this.workOrderOnTimeName = []
124
+    if (this.workOrderOnTime.length > 0) {
125
+      this.workOrderOnTime.forEach(item => {
126
+        this.workOrderOnTimeNum.push(item[1] / 100)
127
+        this.workOrderOnTimeName.push(item[0])
128
+      })
129
+      this.draw()
130
+    }
131
+  }
132
+}
133
+</script>
134
+
135
+<style lang="less">
136
+.delivery-rate-line {
137
+  height: 1.9375rem;
138
+  margin: 0.2rem auto 0;
139
+}
140
+</style>

+ 204 - 0
src/components/ErrorWorkOrder.vue

@@ -0,0 +1,204 @@
1
+<template>
2
+  <div class="error-work-order__wrap">
3
+    <div class="error-work-order__inner">
4
+      <div class="error-work-order--bg">
5
+        <div class="error-work-order-item--bg" v-for="item in 5" :key="item"></div>
6
+      </div>
7
+      <div class="error-work-order" :class="{marquee_top:animate}">
8
+        <div
9
+          class="error-work-order__item"
10
+          v-for="item in todayAbnormityWorkOrderList"
11
+          :key="item.id"
12
+        >
13
+          <strong
14
+            class="error-work-order__status"
15
+            :class="[item[0] === 1?'error-work-order__status--error':'error-work-order__status--timeout']"
16
+          >
17
+            <i class="error-work-order__icon"></i>
18
+            {{item[0] === 1?'异常':'超时'}}
19
+          </strong>
20
+          <div class="error-work-order__id">{{item[1]}}</div>
21
+          <div class="error-work-order__name">{{item[2]}}</div>
22
+          <div class="error-work-order__group">{{item[3]}}</div>
23
+          <div class="error-work-order__type">{{item[4]}}</div>
24
+          <div class="error-work-order__level">{{item[5]}}</div>
25
+          <div class="error-work-order__date">{{item[6]|formatTime(that)}}</div>
26
+        </div>
27
+      </div>
28
+    </div>
29
+  </div>
30
+</template>
31
+
32
+<script>
33
+import { post, timer7 } from './../http/http'
34
+export default {
35
+  name: 'ErrorWorkOrder',
36
+  inject: ['hospitalId'],
37
+  data () {
38
+    return {
39
+      that: this,
40
+      animate: false,
41
+      timer: null,
42
+      timer1: null,
43
+      todayAbnormityWorkOrder: [], // 今日工单异常情况
44
+      todayAbnormityWorkOrderList: [] // 列表
45
+    }
46
+  },
47
+  filters: {
48
+    // 格式化日期
49
+    formatTime (value, that) {
50
+      return that.$moment(value).format('YYYYMMDD HH:mm')
51
+    }
52
+  },
53
+  methods: {
54
+    // 无限滚动
55
+    scrollInfinite () {
56
+      if (this.todayAbnormityWorkOrderList.length <= 5) {
57
+        return
58
+      }
59
+      clearTimeout(this.timer1)
60
+      this.timer1 = setTimeout(() => {
61
+        this.showMarquee()
62
+        this.scrollInfinite()
63
+      }, 2000)
64
+    },
65
+    // 处理数组方法
66
+    showMarquee () {
67
+      this.animate = true
68
+      this.todayAbnormityWorkOrderList.push(
69
+        this.todayAbnormityWorkOrderList[0]
70
+      )
71
+      setTimeout(() => {
72
+        this.todayAbnormityWorkOrderList.shift()
73
+        this.animate = false
74
+      }, 1000)
75
+    },
76
+    // 获取数据
77
+    async getData () {
78
+      const result = await post(
79
+        `/largeScreen/getData/todayAbnormityWorkOrder/${this.hospitalId}`
80
+      )
81
+      this.todayAbnormityWorkOrder = []
82
+      this.todayAbnormityWorkOrderList = []
83
+      this.todayAbnormityWorkOrder = result.todayAbnormityWorkOrder[0]
84
+      this.todayAbnormityWorkOrderList = result.todayAbnormityWorkOrderList
85
+      this.$emit(
86
+        'todayAbnormityWorkOrderHandle',
87
+        JSON.stringify(this.todayAbnormityWorkOrder)
88
+      )
89
+      this.polling()
90
+      this.scrollInfinite()
91
+    },
92
+    // 轮询请求
93
+    polling () {
94
+      clearTimeout(this.timer)
95
+      this.timer = setTimeout(() => {
96
+        this.getData()
97
+      }, timer7)
98
+    }
99
+  },
100
+  mounted () {
101
+    this.getData()
102
+  },
103
+  beforeDestroy () {
104
+    clearTimeout(this.timer)
105
+    clearTimeout(this.timer1)
106
+  }
107
+}
108
+</script>
109
+
110
+<style lang="less">
111
+.error-work-order__wrap {
112
+  height: 2.3125rem;
113
+  padding-bottom: 0.2rem;
114
+  background: linear-gradient(
115
+      96deg,
116
+      rgba(255, 255, 255, 0.05) 0%,
117
+      rgba(255, 255, 255, 0) 70%
118
+    )
119
+    left bottom no-repeat;
120
+  background-size: 100% 0.2rem;
121
+  margin-bottom: 0.4375rem;
122
+  .error-work-order__inner {
123
+    height: 100%;
124
+    overflow: hidden;
125
+    position: relative;
126
+    .error-work-order--bg {
127
+      position: absolute;
128
+      left: 0;
129
+      top: 0;
130
+      width: 100%;
131
+      height: 100%;
132
+      .error-work-order-item--bg {
133
+        height: 0.425rem;
134
+        &:nth-of-type(even) {
135
+          background: linear-gradient(
136
+            96deg,
137
+            rgba(255, 255, 255, 0.05) 0%,
138
+            rgba(255, 255, 255, 0) 70%
139
+          );
140
+        }
141
+      }
142
+    }
143
+    .error-work-order {
144
+      &.marquee_top {
145
+        transition: all 1s;
146
+        transform: translateY(-0.425rem);
147
+      }
148
+      .error-work-order__item {
149
+        height: 0.425rem;
150
+        display: flex;
151
+        align-items: center;
152
+        justify-content: space-between;
153
+        font-size: 0.175rem;
154
+        padding-left: 0.3rem;
155
+        padding-right: 0.3rem;
156
+        .error-work-order__id,
157
+        .error-work-order__group,
158
+        .error-work-order__type,
159
+        .error-work-order__date{
160
+          width: 1.6rem;
161
+          white-space: nowrap;
162
+          text-overflow: ellipsis;
163
+          overflow: hidden;
164
+        }
165
+        .error-work-order__name{
166
+          width: 2rem;
167
+          white-space: nowrap;
168
+          text-overflow: ellipsis;
169
+          overflow: hidden;
170
+        }
171
+        .error-work-order__level{
172
+          width: 0.5rem;
173
+          white-space: nowrap;
174
+          text-overflow: ellipsis;
175
+          overflow: hidden;
176
+        }
177
+        .error-work-order__status {
178
+          width: 0.55rem;
179
+          display: flex;
180
+          justify-content: space-between;
181
+          align-items: center;
182
+          &.error-work-order__status--error {
183
+            color: #c27073;
184
+            .error-work-order__icon {
185
+              background-color: #c27073;
186
+            }
187
+          }
188
+          &.error-work-order__status--timeout {
189
+            color: #c2ab70;
190
+            .error-work-order__icon {
191
+              background-color: #c2ab70;
192
+            }
193
+          }
194
+          .error-work-order__icon {
195
+            width: 0.1rem;
196
+            height: 0.1rem;
197
+            border-radius: 50%;
198
+          }
199
+        }
200
+      }
201
+    }
202
+  }
203
+}
204
+</style>

+ 400 - 0
src/components/GroupPerformance.vue

@@ -0,0 +1,400 @@
1
+<template>
2
+  <div class="group-performanceWrap">
3
+    <div id="group-performance"></div>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+import echarts from 'echarts'
9
+import { post, timer3 } from './../http/http'
10
+export default {
11
+  name: 'GroupPerformance',
12
+  inject: ['hospitalId'],
13
+  data () {
14
+    return {
15
+      timer: null,
16
+      groutWorkOrderListSuccessNum: [], // 获取到的正常单数
17
+      groutWorkOrderListErrorNum: [], // 获取到的异常单数
18
+      groutWorkOrderListName: [] // 获取到的小组名称
19
+    }
20
+  },
21
+  methods: {
22
+    // 画图
23
+    draw () {
24
+      const myChart = echarts.init(
25
+        document.getElementById('group-performance')
26
+      )
27
+      var xData = this.groutWorkOrderListName
28
+      var lastYearData = this.groutWorkOrderListSuccessNum // 正常
29
+      var thisYearData = this.groutWorkOrderListErrorNum // 异常
30
+      var timeLineData = [1]
31
+      const legend = ['已完成工单数(单)', '异常工单数(单)']
32
+      var background = 'rgba(255,255,255,0)' // 背景
33
+      const textColor = '#fff'
34
+      const lineColor = 'rgba(255,255,255,0.2)'
35
+      const colors = [
36
+        {
37
+          borderColor: 'rgba(112, 194, 130,1)',
38
+          start: 'rgba(112, 194, 130,0.8)',
39
+          end: 'rgba(112, 194, 130,0.1)'
40
+        },
41
+        {
42
+          borderColor: 'rgba(194, 112, 115,1)',
43
+          start: 'rgba(194, 112, 115,0.1)',
44
+          end: 'rgba(194, 112, 115,0.8)'
45
+        }
46
+      ]
47
+      let borderData = []
48
+      const scale = 2
49
+      borderData = xData.map((item) => {
50
+        return scale
51
+      })
52
+      var option = {
53
+        baseOption: {
54
+          backgroundColor: background,
55
+          timeline: {
56
+            show: false,
57
+            top: 0,
58
+            data: []
59
+          },
60
+          legend: {
61
+            top: '3%',
62
+            right: 'left',
63
+            itemWidth: 20,
64
+            itemHeight: 5,
65
+            icon: 'none',
66
+            width: '100%',
67
+            itemGap: 124,
68
+            textStyle: {
69
+              color: '#ffffff',
70
+              fontSize: 14
71
+            },
72
+            data: legend
73
+          },
74
+          grid: [
75
+            {
76
+              show: false,
77
+              left: '5%',
78
+              top: '10%',
79
+              bottom: '8%',
80
+              containLabel: true,
81
+              width: '37%'
82
+            },
83
+            {
84
+              show: false,
85
+              left: '51%',
86
+              top: '10%',
87
+              bottom: '8%',
88
+              width: '0%'
89
+            },
90
+            {
91
+              show: false,
92
+              right: '2%',
93
+              top: '10%',
94
+              bottom: '8%',
95
+              containLabel: true,
96
+              width: '37%'
97
+            }
98
+          ],
99
+          xAxis: [
100
+            {
101
+              type: 'value',
102
+              inverse: true,
103
+              axisLine: {
104
+                show: false
105
+              },
106
+              axisTick: {
107
+                show: false
108
+              },
109
+              position: 'top',
110
+              axisLabel: {
111
+                show: false,
112
+                color: textColor
113
+              },
114
+              max: function (value) {
115
+                return Math.ceil(value.max * 1.5)
116
+              },
117
+              splitLine: {
118
+                show: false,
119
+                lineStyle: {
120
+                  color: lineColor
121
+                }
122
+              }
123
+            },
124
+            {
125
+              gridIndex: 1,
126
+              show: false
127
+            },
128
+            {
129
+              gridIndex: 2,
130
+              axisLine: {
131
+                show: false
132
+              },
133
+              max: function (value) {
134
+                return Math.ceil(value.max * 1.5)
135
+              },
136
+              axisTick: {
137
+                show: false
138
+              },
139
+              position: 'top',
140
+              axisLabel: {
141
+                show: false,
142
+                color: textColor
143
+              },
144
+              splitLine: {
145
+                show: false,
146
+                lineStyle: {
147
+                  color: lineColor
148
+                }
149
+              }
150
+            }
151
+          ],
152
+          yAxis: [
153
+            {
154
+              type: 'category',
155
+              inverse: true,
156
+              position: 'right',
157
+              axisLine: {
158
+                show: true,
159
+                lineStyle: {
160
+                  color: lineColor
161
+                }
162
+              },
163
+              axisTick: {
164
+                show: false
165
+              },
166
+              axisLabel: {
167
+                show: false
168
+              },
169
+              data: xData
170
+            },
171
+            {
172
+              gridIndex: 1,
173
+              type: 'category',
174
+              inverse: true,
175
+              position: 'left',
176
+              axisLine: {
177
+                show: false
178
+              },
179
+              axisTick: {
180
+                show: false
181
+              },
182
+              axisLabel: {
183
+                show: true,
184
+                color: '#ffffff',
185
+                fontSize: 14,
186
+                align: 'center',
187
+                margin: -3
188
+              },
189
+              data: xData.map(function (params) {
190
+                var newParamsName = ''// 最终拼接成的字符串
191
+                var paramsNameNumber = params.length // 实际标签的个数
192
+                var provideNumber = 4 // 每行能显示的字的个数
193
+                var rowNumber = Math.ceil(paramsNameNumber / provideNumber) // 换行的话,需要显示几行,向上取整
194
+                /**
195
+                 * 判断标签的个数是否大于规定的个数, 如果大于,则进行换行处理 如果不大于,即等于或小于,就返回原标签
196
+                 */
197
+                // 条件等同于rowNumber>1
198
+                if (paramsNameNumber > provideNumber) {
199
+                  /** 循环每一行,p表示行 */
200
+                  for (var p = 0; p < rowNumber; p++) {
201
+                    var tempStr = '' // 表示每一次截取的字符串
202
+                    var start = p * provideNumber // 开始截取的位置
203
+                    var end = start + provideNumber // 结束截取的位置
204
+                    // 此处特殊处理最后一行的索引值
205
+                    if (p === rowNumber - 1) {
206
+                      // 最后一次不换行
207
+                      tempStr = params.substring(start, paramsNameNumber)
208
+                    } else {
209
+                      // 每一次拼接字符串并换行
210
+                      tempStr = params.substring(start, end) + '\n'
211
+                    }
212
+                    newParamsName += tempStr // 最终拼成的字符串
213
+                  }
214
+                } else {
215
+                  // 将旧标签的值赋给新标签
216
+                  newParamsName = params
217
+                }
218
+                return {
219
+                  value: newParamsName,
220
+                  textStyle: {
221
+                    align: 'center'
222
+                  }
223
+                }
224
+              })
225
+            },
226
+            {
227
+              gridIndex: 2,
228
+              type: 'category',
229
+              inverse: true,
230
+              position: 'left',
231
+              axisLine: {
232
+                show: true,
233
+                lineStyle: {
234
+                  color: lineColor
235
+                }
236
+              },
237
+              axisTick: {
238
+                show: false
239
+              },
240
+              axisLabel: {
241
+                show: false
242
+              },
243
+              data: xData
244
+            }
245
+          ],
246
+          series: []
247
+        },
248
+        options: []
249
+      }
250
+
251
+      option.baseOption.timeline.data.push(timeLineData[0])
252
+      option.options.push({
253
+        series: [
254
+          {
255
+            name: '已完成工单数(单)',
256
+            type: 'bar',
257
+            barWidth: 10,
258
+            stack: '1',
259
+            itemStyle: {
260
+              normal: {
261
+                color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
262
+                  {
263
+                    offset: 0,
264
+                    color: colors[0].start
265
+                  },
266
+                  {
267
+                    offset: 1,
268
+                    color: colors[0].end
269
+                  }
270
+                ])
271
+              }
272
+            },
273
+            label: {
274
+              normal: {
275
+                show: true,
276
+                position: 'right',
277
+                offset: [-170, 2],
278
+                textStyle: {
279
+                  color: '#fff',
280
+                  fontSize: 14
281
+                }
282
+              }
283
+            },
284
+            data: lastYearData,
285
+            animationEasing: 'elasticOut'
286
+          },
287
+          {
288
+            name: '已完成工单数(单)',
289
+            type: 'bar',
290
+            barWidth: 25,
291
+            stack: '1',
292
+            itemStyle: {
293
+              normal: {
294
+                color: colors[0].borderColor
295
+              }
296
+            },
297
+            data: borderData
298
+          },
299
+          {
300
+            name: '异常工单数(单)',
301
+            type: 'bar',
302
+            stack: '2',
303
+            barWidth: 10,
304
+            xAxisIndex: 2,
305
+            yAxisIndex: 2,
306
+            itemStyle: {
307
+              normal: {
308
+                color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
309
+                  {
310
+                    offset: 0,
311
+                    color: colors[1].start
312
+                  },
313
+                  {
314
+                    offset: 1,
315
+                    color: colors[1].end
316
+                  }
317
+                ])
318
+              }
319
+            },
320
+            label: {
321
+              show: true,
322
+              position: [140, 0],
323
+              textStyle: {
324
+                color: '#fff',
325
+                fontSize: 14
326
+              }
327
+            },
328
+            data: thisYearData,
329
+            animationEasing: 'elasticOut'
330
+          },
331
+          {
332
+            name: '异常工单数(单)',
333
+            type: 'bar',
334
+            xAxisIndex: 2,
335
+            yAxisIndex: 2,
336
+            barWidth: 25,
337
+            stack: '2',
338
+            itemStyle: {
339
+              normal: {
340
+                color: colors[1].borderColor
341
+              }
342
+            },
343
+            data: borderData
344
+          }
345
+        ]
346
+      })
347
+      myChart.setOption(option)
348
+    },
349
+    // 获取数据
350
+    async getData () {
351
+      const srartTime = this.$moment()
352
+        .subtract(29, 'days')
353
+        .format('YYYY-MM-DD') // 近三十天
354
+      const endTime = this.$moment().format('YYYY-MM-DD') // 今天
355
+      const result = await post(
356
+        `/largeScreen/getData/groupWorkOrder/${this.hospitalId}`,
357
+        { srartTime, endTime }
358
+      )
359
+      this.groutWorkOrderListSuccessNum = []
360
+      this.groutWorkOrderListErrorNum = []
361
+      this.groutWorkOrderListName = []
362
+      if (result.groutWorkOrderList.length > 5) {
363
+        result.groutWorkOrderList = result.groutWorkOrderList.slice(0, 5)
364
+      }
365
+      result.groutWorkOrderList.forEach((item) => {
366
+        this.groutWorkOrderListSuccessNum.push(item[1]) // 获取到的正常单数
367
+        this.groutWorkOrderListErrorNum.push(item[0]) // 获取到的异常单数
368
+        this.groutWorkOrderListName.push(item[3]) // 获取到的小组名称
369
+      })
370
+      this.draw()
371
+      this.polling()
372
+    },
373
+    // 轮询请求
374
+    polling () {
375
+      clearTimeout(this.timer)
376
+      this.timer = setTimeout(() => {
377
+        this.getData()
378
+      }, timer3)
379
+    }
380
+  },
381
+  mounted () {
382
+    this.getData()
383
+  },
384
+  beforeDestroy () {
385
+    clearTimeout(this.timer)
386
+  }
387
+}
388
+</script>
389
+
390
+<style lang="less">
391
+#group-performance {
392
+  width: 100%;
393
+  height: 100%;
394
+}
395
+.group-performanceWrap {
396
+  width: 5.15rem;
397
+  height: 5.0625rem;
398
+  margin: 0.2rem auto;
399
+}
400
+</style>

+ 211 - 0
src/components/GroupPraise.vue

@@ -0,0 +1,211 @@
1
+<template>
2
+  <div class="group-praise">
3
+    <!-- 广播 -->
4
+    <div class="group-praise__broadcast">
5
+      <i class="group-praise__broadcast--icon icon_transport transport-laba1"></i>
6
+      <div class="group-praise__broadcastListWrap">
7
+        <ul class="group-praise__broadcastList" :class="{marquee_top:animate}" :style="{transform:'translateY('+(0.375*n)+'rem)'}">
8
+          <li
9
+            v-for="(item,i) in evaluateUserList"
10
+            :key="i"
11
+          >【{{item[0]}}】支助人员「{{item[1]}}」 {{item[2]}}</li>
12
+        </ul>
13
+      </div>
14
+    </div>
15
+    <div class="group-praise__content">
16
+      <div class="group-praise__circle">
17
+        <header class="group-praise__title">NO.2</header>
18
+        <div class="group-praise__circleContent" v-if="evaluateGroutList[1]">
19
+          <p class="group-praise__circleName ellipsis">{{evaluateGroutList[1][1]}}</p>
20
+          <p class="group-praise__circlePercent">{{evaluateGroutList[1][4]}}%</p>
21
+        </div>
22
+      </div>
23
+      <div class="group-praise__circle--win">
24
+        <header class="group-praise__title">NO.1</header>
25
+        <div class="group-praise__circleContent" v-if="evaluateGroutList[0]">
26
+          <p class="group-praise__circleName ellipsis">{{evaluateGroutList[0][1]}}</p>
27
+          <p class="group-praise__circlePercent">{{evaluateGroutList[0][4]}}%</p>
28
+        </div>
29
+      </div>
30
+      <div class="group-praise__circle">
31
+        <header class="group-praise__title">NO.3</header>
32
+        <div class="group-praise__circleContent" v-if="evaluateGroutList[2]">
33
+          <p class="group-praise__circleName ellipsis">{{evaluateGroutList[2][1]}}</p>
34
+          <p class="group-praise__circlePercent">{{evaluateGroutList[2][4]}}%</p>
35
+        </div>
36
+      </div>
37
+    </div>
38
+  </div>
39
+</template>
40
+
41
+<script>
42
+import { post, timer2 } from './../http/http'
43
+export default {
44
+  name: 'GroupPraise',
45
+  inject: ['hospitalId'],
46
+  data () {
47
+    return {
48
+      allData: {},
49
+      fontSize: parseFloat(document.querySelector('html').style.fontSize),
50
+      timer: null,
51
+      animate: false,
52
+      timer1: null,
53
+      n: 0,
54
+      evaluateGroutList: [], // 小组排名(无序)
55
+      evaluateUserList: [], // 滚动数据
56
+      disY: 0.375, // 滚动数据偏移量
57
+      disHeight: 0, // 滚动数据高度
58
+      isShow: true // 滚动数据显示隐藏
59
+    }
60
+  },
61
+  methods: {
62
+    // 无限滚动
63
+    scrollInfinite () {
64
+      clearTimeout(this.timer1)
65
+      this.timer1 = setTimeout(() => {
66
+        this.showMarquee()
67
+        this.scrollInfinite()
68
+      }, 2000)
69
+    },
70
+    // 处理数组方法
71
+    showMarquee () {
72
+      this.animate = true
73
+      this.n--
74
+      if (this.n === -(this.evaluateUserList.length)) {
75
+        this.animate = false
76
+        this.n = 0
77
+      }
78
+    },
79
+    // 近30天小组好评排行
80
+    async getGroupPraise () {
81
+      const srartTime = this.$moment()
82
+        .subtract(29, 'days')
83
+        .format('YYYY-MM-DD') // 近三十天
84
+      const endTime = this.$moment().format('YYYY-MM-DD') // 今天
85
+      const result = await post(
86
+        `/largeScreen/getData/groupEvaluateRanking/${this.hospitalId}`,
87
+        { srartTime, endTime }
88
+      )
89
+      this.evaluateGroutList = result.evaluateGroutList
90
+      this.evaluateGroutList.sort((a, b) => b[4] - a[4]) // 排行从高往低排序
91
+      this.evaluateUserList = result.evaluateUserList
92
+      this.polling()
93
+      if (this.evaluateUserList.length > 0) {
94
+        this.evaluateUserList = [...this.evaluateUserList, this.evaluateUserList[0]]
95
+        this.scrollInfinite()
96
+      }
97
+    },
98
+    // 轮询请求
99
+    polling () {
100
+      clearTimeout(this.timer)
101
+      this.timer = setTimeout(() => {
102
+        this.getGroupPraise()
103
+      }, timer2)
104
+    }
105
+  },
106
+  mounted () {
107
+    this.getGroupPraise()
108
+  },
109
+  beforeDestroy () {
110
+    clearTimeout(this.timer)
111
+    clearTimeout(this.timer1)
112
+  }
113
+}
114
+</script>
115
+
116
+<style lang="less">
117
+.group-praise {
118
+  height: 2.7125rem;
119
+  padding-top: 0.2rem;
120
+  padding-bottom: 0.375rem;
121
+  .group-praise__broadcast {
122
+    height: 0.4rem;
123
+    background-color: rgba(255, 255, 255, 0.2);
124
+    border: solid 1px rgba(255, 255, 255, 0.2);
125
+    display: flex;
126
+    align-items: center;
127
+    .group-praise__broadcast--icon {
128
+      font-size: 0.275rem;
129
+      color: #2496d2;
130
+      margin-left: 0.1rem;
131
+    }
132
+    .group-praise__broadcastListWrap {
133
+      flex: 1;
134
+      height: 0.375rem;
135
+      line-height: 0.375rem;
136
+      padding-left: 0.2rem;
137
+      padding-right: 0.1rem;
138
+      overflow: hidden;
139
+      .group-praise__broadcastList {
140
+        &.marquee_top {
141
+          transition: all 1s;
142
+        }
143
+        li {
144
+          word-break: break-all;
145
+        }
146
+      }
147
+    }
148
+  }
149
+  .group-praise__content {
150
+    display: flex;
151
+    justify-content: center;
152
+    .group-praise__title {
153
+      color: #c2ab70;
154
+      font-size: 0.2rem;
155
+      font-weight: 700;
156
+      text-align: center;
157
+    }
158
+    .group-praise__circleContent {
159
+      color: #fff;
160
+      font-size: 0.175rem;
161
+      height: 0.875rem;
162
+      display: flex;
163
+      align-items: center;
164
+      justify-content: center;
165
+      flex-direction: column;
166
+      line-height: 1.3em;
167
+      text-align: center;
168
+      .group-praise__circleName {
169
+        width: 0.725rem;
170
+      }
171
+    }
172
+    .group-praise__circle {
173
+      width: 1.2rem;
174
+      height: 1.2rem;
175
+      margin-top: 0.4rem;
176
+      position: relative;
177
+      &::after {
178
+        content: "";
179
+        opacity: 0.5;
180
+        width: 100%;
181
+        height: 100%;
182
+        background: url("./../assets/img/image_no2.png") no-repeat;
183
+        background-size: 100%;
184
+        position: absolute;
185
+        left: 0;
186
+        top: 0;
187
+      }
188
+    }
189
+    .group-praise__circle--win {
190
+      width: 1.7625rem;
191
+      height: 1.6875rem;
192
+      margin: 0.05rem 0.1375rem 0;
193
+      position: relative;
194
+      &::after {
195
+        content: "";
196
+        position: absolute;
197
+        left: 0;
198
+        top: 0;
199
+        opacity: 0.5;
200
+        width: 100%;
201
+        height: 100%;
202
+        background: url("./../assets/img/image_no1.png") no-repeat;
203
+        background-size: 100%;
204
+      }
205
+      .group-praise__circleContent {
206
+        margin-top: 0.1rem;
207
+      }
208
+    }
209
+  }
210
+}
211
+</style>

+ 121 - 0
src/components/OnDutyToday.vue

@@ -0,0 +1,121 @@
1
+<template>
2
+  <div class="on-duty-today">
3
+    <div class="on-duty-today__inner" :class="{marquee_top:animate}" :style="{transform:'translateY('+(2.7125*n)+'rem)'}">
4
+      <div class="on-duty-today__list" v-for="(item1,i) in todayGroutList" :key="i">
5
+        <div class="on-duty-today__item" v-for="item2 in item1" :key="item2[2]">
6
+          <OnDutyTodayPie :todayGroutListItem="item2"></OnDutyTodayPie>
7
+        </div>
8
+      </div>
9
+    </div>
10
+  </div>
11
+</template>
12
+
13
+<script>
14
+import OnDutyTodayPie from './OnDutyTodayPie.vue'
15
+import { post, timer5 } from './../http/http'
16
+export default {
17
+  name: 'OnDutyToday',
18
+  inject: ['hospitalId'],
19
+  data () {
20
+    return {
21
+      timer: null,
22
+      timer1: null,
23
+      animate: false,
24
+      n: 0,
25
+      todayBeOnDuty: [], // 头部总当班人数
26
+      todayGroutList: [] // 当班人数(工作中,空闲中)
27
+    }
28
+  },
29
+  components: {
30
+    OnDutyTodayPie
31
+  },
32
+  methods: {
33
+    // 无限滚动
34
+    scrollInfinite () {
35
+      clearTimeout(this.timer1)
36
+      this.timer1 = setTimeout(() => {
37
+        this.showMarquee()
38
+        this.scrollInfinite()
39
+      }, 5000)
40
+    },
41
+    // 处理数组方法
42
+    showMarquee () {
43
+      this.animate = true
44
+      this.n--
45
+      if (this.n === -(this.todayGroutList.length)) {
46
+        this.animate = false
47
+        this.n = 0
48
+      }
49
+    },
50
+    // 获取数据
51
+    async getData () {
52
+      const result = await post(
53
+        `/largeScreen/getData/todayBeOnDuty/${this.hospitalId}`
54
+      )
55
+      this.todayBeOnDuty = []
56
+      this.todayGroutList = []
57
+      this.todayBeOnDuty = result.todayBeOnDuty[0]
58
+      const len = Math.ceil(result.todayGroutList.length / 3)
59
+      for (let i = 0; i < len; i++) {
60
+        let list = [
61
+          result.todayGroutList[0 + 3 * i],
62
+          result.todayGroutList[1 + 3 * i],
63
+          result.todayGroutList[2 + 3 * i]
64
+        ]
65
+        list = list.filter((item) => item !== undefined)
66
+        this.todayGroutList.push(list)
67
+      }
68
+      this.$emit('todayBeOnDutyHandle', JSON.stringify(this.todayBeOnDuty))
69
+      this.polling()
70
+      if (this.todayGroutList.length > 0) {
71
+        this.todayGroutList = [...this.todayGroutList, this.todayGroutList[0]]
72
+        this.scrollInfinite()
73
+      }
74
+    },
75
+    // 轮询请求
76
+    polling () {
77
+      clearTimeout(this.timer)
78
+      this.timer = setTimeout(() => {
79
+        this.getData()
80
+      }, timer5)
81
+    }
82
+  },
83
+  mounted () {
84
+    this.getData()
85
+  },
86
+  beforeDestroy () {
87
+    clearTimeout(this.timer)
88
+  }
89
+}
90
+</script>
91
+
92
+<style lang="less">
93
+.on-duty-today {
94
+  overflow: hidden;
95
+  height: 2.7125rem;
96
+  .on-duty-today__inner {
97
+    // display: flex;
98
+    // flex-wrap: wrap;
99
+    // width: 1000%;
100
+    &.marquee_top {
101
+      transition: all 1s;
102
+      // transform: translateY(-2.7125rem);
103
+    }
104
+    .on-duty-today__list {
105
+      width: 11.7rem;
106
+      display: flex;
107
+      justify-content: space-between;
108
+      height: 2.7125rem;
109
+      .on-duty-today__item {
110
+        margin-top: 0.2rem;
111
+        &:first-child {
112
+          margin-left: 0.3rem;
113
+        }
114
+        &:last-child {
115
+          margin-right: 0.3rem;
116
+        }
117
+      }
118
+    }
119
+  }
120
+}
121
+</style>

+ 355 - 0
src/components/OnDutyTodayPie.vue

@@ -0,0 +1,355 @@
1
+<template>
2
+  <div class="on-duty-today-pie__wrap">
3
+    <div class="on-duty-today-pie" ref="pie"></div>
4
+    <div class="on-duty-today-pie__tips">
5
+      <ul class="on-duty-today-pie__list">
6
+        <li class="on-duty-today-pie__item">
7
+          <i class="on-duty-today-pie__item--red"></i>空闲中
8
+          <em>{{ todayGroutListItem[1] }}</em>
9
+        </li>
10
+        <li class="on-duty-today-pie__item">
11
+          <i class="on-duty-today-pie__item--green"></i>工作中
12
+          <em>{{ todayGroutListItem[0] }}</em>
13
+        </li>
14
+      </ul>
15
+    </div>
16
+  </div>
17
+</template>
18
+
19
+<script>
20
+import echarts from 'echarts'
21
+export default {
22
+  name: 'OnDutyTodayPie',
23
+  data () {
24
+    return {
25
+      // timer: null,
26
+      myChart: null
27
+    }
28
+  },
29
+  props: {
30
+    todayGroutListItem: {
31
+      type: Array,
32
+      default: () => []
33
+    }
34
+  },
35
+  watch: {
36
+    todayGroutListItem () {
37
+      this.draw()
38
+    }
39
+  },
40
+  methods: {
41
+    // 画图
42
+    draw () {
43
+      this.myChart = echarts.init(this.$refs.pie)
44
+      const todayGroutListItem = this.todayGroutListItem
45
+      const option = {
46
+        title: {
47
+          text: todayGroutListItem[3],
48
+          textStyle: {
49
+            color: '#fff',
50
+            fontSize: 14,
51
+            fontWeight: 'normal'
52
+          },
53
+          left: 'center',
54
+          top: -5
55
+        },
56
+        color: ['#237189', '#1d3e5b'],
57
+        series: [
58
+          {
59
+            type: 'pie',
60
+            top: 15,
61
+            center: ['50%', '55%'],
62
+            zlevel: 1,
63
+            silent: true,
64
+            radius: ['83%', '84%'],
65
+            hoverAnimation: false,
66
+            label: {
67
+              normal: {
68
+                show: false
69
+              }
70
+            },
71
+            labelLine: {
72
+              normal: {
73
+                show: false
74
+              }
75
+            },
76
+            data: this._pie3()
77
+          },
78
+          {
79
+            type: 'pie',
80
+            top: 15,
81
+            center: ['50%', '55%'],
82
+            zlevel: 2,
83
+            silent: true,
84
+            radius: ['76%', '77%'],
85
+            startAngle: 90,
86
+            hoverAnimation: false,
87
+            label: {
88
+              normal: {
89
+                show: false
90
+              }
91
+            },
92
+            labelLine: {
93
+              normal: {
94
+                show: false
95
+              }
96
+            },
97
+            data: this._pie2()
98
+          },
99
+          {
100
+            type: 'pie',
101
+            top: 15,
102
+            center: ['50%', '55%'],
103
+            zlevel: 3,
104
+            silent: true,
105
+            radius: ['72%', '70%'],
106
+            label: {
107
+              normal: {
108
+                show: false
109
+              }
110
+            },
111
+            labelLine: {
112
+              normal: {
113
+                show: false
114
+              }
115
+            },
116
+            data: [1]
117
+          },
118
+          {
119
+            type: 'pie',
120
+            top: 15,
121
+            center: ['50%', '55%'],
122
+            zlevel: 4,
123
+            silent: true,
124
+            radius: ['46%', '66%'],
125
+            startAngle: 180,
126
+            hoverAnimation: false,
127
+            // label: {
128
+            //   show: true,
129
+            //   formatter () {
130
+            //     const num = [todayGroutListItem[1], todayGroutListItem[0]]
131
+            //     return `当班人数\n${num[0]}/${num[1]}`
132
+            //   },
133
+            //   fontSize: 14,
134
+            //   lineHeight: 30,
135
+            //   color: '#d4d6d7',
136
+            //   position: 'center'
137
+            // },
138
+            data: this._pie4()
139
+          }
140
+        ]
141
+      }
142
+      this.myChart.setOption(option)
143
+    },
144
+    _pie1 () {
145
+      const dataArr = []
146
+      for (var i = 0; i < 8; i++) {
147
+        dataArr.push({
148
+          name: (i + 1).toString(),
149
+          value: 20,
150
+          itemStyle: {
151
+            normal: {
152
+              color: 'rgba(88,142,197,0.4)',
153
+              borderWidth: 0,
154
+              borderColor: 'rgba(0,0,0,0)'
155
+            }
156
+          }
157
+        })
158
+      }
159
+      return dataArr
160
+    },
161
+    _pie2 () {
162
+      const dataArr = []
163
+      for (var i = 0; i < 16; i++) {
164
+        if (i % 4 === 0) {
165
+          dataArr.push({
166
+            name: (i + 1).toString(),
167
+            value: 50,
168
+            itemStyle: {
169
+              normal: {
170
+                borderWidth: 0,
171
+                borderColor: 'rgba(0,0,0,0)'
172
+              }
173
+            }
174
+          })
175
+        } else if (i % 4 === 1) {
176
+          dataArr.push({
177
+            name: (i + 1).toString(),
178
+            value: 2,
179
+            itemStyle: {
180
+              normal: {
181
+                color: 'rgba(88,142,197,0)',
182
+                borderWidth: 0,
183
+                borderColor: 'rgba(0,0,0,0)'
184
+              }
185
+            }
186
+          })
187
+        } else if (i % 4 === 2) {
188
+          dataArr.push({
189
+            name: (i + 1).toString(),
190
+            value: 20,
191
+            itemStyle: {
192
+              normal: {
193
+                borderWidth: 0,
194
+                borderColor: 'rgba(0,0,0,0)'
195
+              }
196
+            }
197
+          })
198
+        } else {
199
+          dataArr.push({
200
+            name: (i + 1).toString(),
201
+            value: 2,
202
+            itemStyle: {
203
+              normal: {
204
+                color: 'rgba(88,142,197,0)',
205
+                borderWidth: 0,
206
+                borderColor: 'rgba(0,0,0,0)'
207
+              }
208
+            }
209
+          })
210
+        }
211
+      }
212
+      return dataArr
213
+    },
214
+    _pie3 () {
215
+      const dataArr = []
216
+      for (var i = 0; i < 100; i++) {
217
+        if (i % 2 === 0) {
218
+          dataArr.push({
219
+            name: (i + 1).toString(),
220
+            value: 25,
221
+            itemStyle: {
222
+              normal: {
223
+                color: '#30586a',
224
+                borderWidth: 0,
225
+                borderColor: 'rgba(0,0,0,0)'
226
+              }
227
+            }
228
+          })
229
+        } else {
230
+          dataArr.push({
231
+            name: (i + 1).toString(),
232
+            value: 20,
233
+            itemStyle: {
234
+              normal: {
235
+                color: 'rgba(0,0,0,0)',
236
+                borderWidth: 0,
237
+                borderColor: 'rgba(0,0,0,0)'
238
+              }
239
+            }
240
+          })
241
+        }
242
+      }
243
+      return dataArr
244
+    },
245
+    _pie4 () {
246
+      const dataArr = []
247
+      const arr = ['空闲中', '工作中']
248
+      const color = ['#c27073', '#70c282']
249
+      const num = [this.todayGroutListItem[1], this.todayGroutListItem[0]]
250
+      for (var i = 0; i < arr.length; i++) {
251
+        dataArr.push({
252
+          name: arr[i],
253
+          value: num[i],
254
+          itemStyle: {
255
+            normal: {
256
+              color: color[i],
257
+              borderWidth: 0,
258
+              borderColor: 'rgba(0,0,0,0)'
259
+            }
260
+          }
261
+        })
262
+        if (i === 0) {
263
+          dataArr[0].label = {
264
+            show: true,
265
+            formatter () {
266
+              return `当班人数\n${num[0]}/${num[1]}`
267
+            },
268
+            fontSize: 14,
269
+            lineHeight: 30,
270
+            color: '#d4d6d7',
271
+            position: 'center',
272
+            padding: [35, 0, 0, 0]
273
+          }
274
+        }
275
+        if (i === 1) {
276
+          dataArr[1].label = {
277
+            show: false,
278
+            formatter () {
279
+              return ''
280
+            },
281
+            fontSize: 0,
282
+            lineHeight: 0,
283
+            color: '#d4d6d7',
284
+            position: 'center'
285
+          }
286
+        }
287
+      }
288
+      return dataArr
289
+    }
290
+    // 动画
291
+    // doing () {
292
+    //   clearTimeout(this.timer)
293
+    //   const option = this.myChart.getOption()
294
+    //   option.series[1].startAngle = option.series[1].startAngle - 1
295
+    //   this.myChart.setOption(option)
296
+    //   this.timer = setTimeout(() => {
297
+    //     this.doing()
298
+    //   }, 16)
299
+    // }
300
+  },
301
+  mounted () {
302
+    this.draw()
303
+    // this.doing()
304
+  }
305
+  // beforeDestroy () {
306
+  //   clearTimeout(this.timer)
307
+  // }
308
+}
309
+</script>
310
+
311
+<style lang="less">
312
+.on-duty-today-pie__wrap {
313
+  // width: 2.5rem;
314
+  width: 3rem;
315
+  .on-duty-today-pie {
316
+    // width: 1.8rem;
317
+    width: 2.6rem;
318
+    // height: 2.125rem;
319
+    height: 2rem;
320
+    margin: 0 auto;
321
+  }
322
+  .on-duty-today-pie__tips {
323
+    .on-duty-today-pie__list {
324
+      display: flex;
325
+      justify-content: space-around;
326
+      align-items: center;
327
+      .on-duty-today-pie__item {
328
+        display: flex;
329
+        justify-content: space-between;
330
+        align-items: center;
331
+        color: #d4d6d7;
332
+        font-size: 0.15rem;
333
+        em {
334
+          font-size: 0.2rem;
335
+          margin-left: 0.1rem;
336
+        }
337
+        .on-duty-today-pie__item--red {
338
+          width: 0.1rem;
339
+          height: 0.1rem;
340
+          background-color: #c27073;
341
+          border-radius: 0.025rem;
342
+          margin-right: 0.075rem;
343
+        }
344
+        .on-duty-today-pie__item--green {
345
+          width: 0.1rem;
346
+          height: 0.1rem;
347
+          background-color: #70c282;
348
+          border-radius: 0.025rem;
349
+          margin-right: 0.075rem;
350
+        }
351
+      }
352
+    }
353
+  }
354
+}
355
+</style>

+ 240 - 0
src/components/OnTimeArrivalRate.vue

@@ -0,0 +1,240 @@
1
+<template>
2
+  <div class="on-time-arrival-rate__wrap">
3
+    <div class="on-time-arrival-rate" ref="OnTimeArrivalRate"></div>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+import echarts from 'echarts'
9
+import { post, timer9 } from './../http/http'
10
+export default {
11
+  name: 'OnTimeArrivalRate',
12
+  inject: ['hospitalId'],
13
+  data () {
14
+    return {
15
+      timer: null,
16
+      myChart: null,
17
+      userOnTimeRankingListNum: [],
18
+      userOnTimeRankingListName: []
19
+    }
20
+  },
21
+  methods: {
22
+    // 画图
23
+    draw () {
24
+      this.myChart = echarts.init(this.$refs.OnTimeArrivalRate)
25
+      var colorArray = [
26
+        {
27
+          top: '#c2ab70', // 第一
28
+          bottom: 'rgba(194, 171, 112, 0.5)',
29
+          borderColor: '#c2ab70'
30
+        },
31
+        {
32
+          top: '#70c282', // 第二
33
+          bottom: 'rgba(112, 194, 130, 0.5)'
34
+        },
35
+        {
36
+          top: '#709cc2', // 第三
37
+          bottom: 'rgba(112, 156, 194, 0.5)'
38
+        },
39
+        {
40
+          top: '#709cc2', // 第四
41
+          bottom: 'rgba(112, 156, 194, 0.5)'
42
+        },
43
+        {
44
+          top: '#709cc2', // 第五
45
+          bottom: 'rgba(112, 156, 194, 0.5)'
46
+        }
47
+      ]
48
+      const option = {
49
+        tooltip: {
50
+          show: false,
51
+          formatter: '{b}:{c}'
52
+        },
53
+        grid: {
54
+          left: '5%',
55
+          top: '12%',
56
+          right: '1%',
57
+          bottom: '8%',
58
+          containLabel: true
59
+        },
60
+        xAxis: {
61
+          type: 'value',
62
+          show: false,
63
+          position: 'top',
64
+          axisTick: {
65
+            show: false
66
+          },
67
+          axisLine: {
68
+            show: false,
69
+            lineStyle: {
70
+              color: '#fff'
71
+            }
72
+          },
73
+          splitLine: {
74
+            show: false
75
+          }
76
+        },
77
+        yAxis: [
78
+          {
79
+            type: 'category',
80
+            axisTick: {
81
+              show: false,
82
+              alignWithLabel: false,
83
+              length: 5
84
+            },
85
+            splitLine: {
86
+              // 网格线
87
+              show: false
88
+            },
89
+            inverse: 'true', // 排序
90
+            axisLine: {
91
+              show: false,
92
+              lineStyle: {
93
+                color: '#fff'
94
+              }
95
+            },
96
+            data: this.userOnTimeRankingListName
97
+          }
98
+        ],
99
+        series: [
100
+          {
101
+            name: 'xxx',
102
+            type: 'bar',
103
+            label: {
104
+              normal: {
105
+                show: true,
106
+                position: [360, 0],
107
+                formatter (params) {
108
+                  return params.value + '%'
109
+                },
110
+                textStyle: {
111
+                  color: '#fff'
112
+                }
113
+              }
114
+            },
115
+            itemStyle: {
116
+              normal: {
117
+                show: true,
118
+                color: function (params) {
119
+                  const num = colorArray.length
120
+                  return {
121
+                    type: 'linear',
122
+                    colorStops: [
123
+                      {
124
+                        offset: 0,
125
+                        color: colorArray[params.dataIndex % num].bottom
126
+                      },
127
+                      {
128
+                        offset: 1,
129
+                        color: colorArray[params.dataIndex % num].top
130
+                      },
131
+                      {
132
+                        offset: 0,
133
+                        color: colorArray[params.dataIndex % num].bottom
134
+                      },
135
+                      {
136
+                        offset: 1,
137
+                        color: colorArray[params.dataIndex % num].top
138
+                      },
139
+                      {
140
+                        offset: 0,
141
+                        color: colorArray[params.dataIndex % num].bottom
142
+                      },
143
+                      {
144
+                        offset: 1,
145
+                        color: colorArray[params.dataIndex % num].top
146
+                      },
147
+                      {
148
+                        offset: 0,
149
+                        color: colorArray[params.dataIndex % num].bottom
150
+                      },
151
+                      {
152
+                        offset: 1,
153
+                        color: colorArray[params.dataIndex % num].top
154
+                      },
155
+                      {
156
+                        offset: 0,
157
+                        color: colorArray[params.dataIndex % num].bottom
158
+                      },
159
+                      {
160
+                        offset: 1,
161
+                        color: colorArray[params.dataIndex % num].top
162
+                      },
163
+                      {
164
+                        offset: 0,
165
+                        color: colorArray[params.dataIndex % num].bottom
166
+                      },
167
+                      {
168
+                        offset: 1,
169
+                        color: colorArray[params.dataIndex % num].top
170
+                      }
171
+                    ]
172
+                  }
173
+                },
174
+                barBorderRadius: 70,
175
+                borderWidth: 0,
176
+                borderColor: '#333'
177
+              }
178
+            },
179
+            barGap: '0%',
180
+            barCategoryGap: '70%',
181
+            barWidth: 8,
182
+            data: this.userOnTimeRankingListNum.sort((a, b) => b - a)
183
+          }
184
+        ]
185
+      }
186
+      this.myChart.setOption(option)
187
+    },
188
+    // 获取数据
189
+    async getData () {
190
+      const srartTime = this.$moment()
191
+        .subtract(29, 'days')
192
+        .format('YYYY-MM-DD') // 近三十天
193
+      const endTime = this.$moment().format('YYYY-MM-DD') // 今天
194
+      const result = await post(
195
+        `/largeScreen/getData/userOnTimeRankingList/${this.hospitalId}`,
196
+        { srartTime, endTime }
197
+      )
198
+      this.userOnTimeRankingListNum = []
199
+      this.userOnTimeRankingListName = []
200
+      if (result.userOnTimeRankingList.length > 5) {
201
+        result.userOnTimeRankingList = result.userOnTimeRankingList.slice(0, 5)
202
+      }
203
+      result.userOnTimeRankingList.forEach(item => {
204
+        this.userOnTimeRankingListNum.push(item[0]) // 获取到的数据
205
+        this.userOnTimeRankingListName.push(item[1]) // 获取到的名称
206
+      })
207
+      this.draw()
208
+      this.polling()
209
+    },
210
+    // 轮询请求
211
+    polling () {
212
+      clearTimeout(this.timer)
213
+      this.timer = setTimeout(() => {
214
+        this.getData()
215
+      }, timer9)
216
+    }
217
+  },
218
+  mounted () {
219
+    this.getData()
220
+  },
221
+  beforeDestroy () {
222
+    clearTimeout(this.timer)
223
+  }
224
+}
225
+</script>
226
+
227
+<style lang="less">
228
+.on-time-arrival-rate__wrap {
229
+  // height: 2.7125rem;
230
+  height: 2.3875rem;
231
+  overflow: hidden;
232
+  .on-time-arrival-rate {
233
+    width: 100%;
234
+    height: 100%;
235
+    position: absolute;
236
+    left: 0;
237
+    top: -0.175rem;
238
+  }
239
+}
240
+</style>

+ 242 - 0
src/components/PointsRanking.vue

@@ -0,0 +1,242 @@
1
+<template>
2
+  <div class="points-ranking__wrap">
3
+    <div class="points-ranking" ref="PointsRanking"></div>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+import echarts from 'echarts'
9
+import { post, timer8 } from './../http/http'
10
+export default {
11
+  name: 'PointsRanking',
12
+  inject: ['hospitalId'],
13
+  data () {
14
+    return {
15
+      timer: null,
16
+      myChart: null,
17
+      gradeRankingListNum: [],
18
+      gradeRankingListName: []
19
+    }
20
+  },
21
+  methods: {
22
+    // 画图
23
+    draw () {
24
+      this.myChart = echarts.init(this.$refs.PointsRanking)
25
+      var colorArray = [
26
+        {
27
+          top: '#c2ab70', // 第一
28
+          bottom: 'rgba(194, 171, 112, 0.5)',
29
+          borderColor: '#c2ab70'
30
+        },
31
+        {
32
+          top: '#70c282', // 第二
33
+          bottom: 'rgba(112, 194, 130, 0.5)'
34
+        },
35
+        {
36
+          top: '#709cc2', // 第三
37
+          bottom: 'rgba(112, 156, 194, 0.5)'
38
+        },
39
+        {
40
+          top: '#709cc2', // 第四
41
+          bottom: 'rgba(112, 156, 194, 0.5)'
42
+        },
43
+        {
44
+          top: '#709cc2', // 第五
45
+          bottom: 'rgba(112, 156, 194, 0.5)'
46
+        }
47
+      ]
48
+      const option = {
49
+        tooltip: {
50
+          show: false,
51
+          formatter: '{b}:{c}'
52
+        },
53
+        grid: {
54
+          left: '5%',
55
+          top: '12%',
56
+          right: '1%',
57
+          bottom: '8%',
58
+          containLabel: true
59
+        },
60
+        xAxis: {
61
+          type: 'value',
62
+          show: false,
63
+          position: 'top',
64
+          max: function (value) {
65
+            return value.max * 1.5
66
+          },
67
+          axisTick: {
68
+            show: false
69
+          },
70
+          axisLine: {
71
+            show: false,
72
+            lineStyle: {
73
+              color: '#fff'
74
+            }
75
+          },
76
+          splitLine: {
77
+            show: false
78
+          }
79
+        },
80
+        yAxis: [
81
+          {
82
+            type: 'category',
83
+            axisTick: {
84
+              show: false,
85
+              alignWithLabel: false,
86
+              length: 5
87
+            },
88
+            splitLine: {
89
+              // 网格线
90
+              show: false
91
+            },
92
+            inverse: 'true', // 排序
93
+            axisLine: {
94
+              show: false,
95
+              lineStyle: {
96
+                color: '#fff'
97
+              }
98
+            },
99
+            data: this.gradeRankingListName
100
+          }
101
+        ],
102
+        series: [
103
+          {
104
+            name: 'xxx',
105
+            type: 'bar',
106
+            label: {
107
+              normal: {
108
+                show: true,
109
+                position: [365, 0],
110
+                formatter: '{c}',
111
+                textStyle: {
112
+                  color: '#fff'
113
+                }
114
+              }
115
+            },
116
+            itemStyle: {
117
+              normal: {
118
+                show: true,
119
+                color: function (params) {
120
+                  const num = colorArray.length
121
+                  return {
122
+                    type: 'linear',
123
+                    colorStops: [
124
+                      {
125
+                        offset: 0,
126
+                        color: colorArray[params.dataIndex % num].bottom
127
+                      },
128
+                      {
129
+                        offset: 1,
130
+                        color: colorArray[params.dataIndex % num].top
131
+                      },
132
+                      {
133
+                        offset: 0,
134
+                        color: colorArray[params.dataIndex % num].bottom
135
+                      },
136
+                      {
137
+                        offset: 1,
138
+                        color: colorArray[params.dataIndex % num].top
139
+                      },
140
+                      {
141
+                        offset: 0,
142
+                        color: colorArray[params.dataIndex % num].bottom
143
+                      },
144
+                      {
145
+                        offset: 1,
146
+                        color: colorArray[params.dataIndex % num].top
147
+                      },
148
+                      {
149
+                        offset: 0,
150
+                        color: colorArray[params.dataIndex % num].bottom
151
+                      },
152
+                      {
153
+                        offset: 1,
154
+                        color: colorArray[params.dataIndex % num].top
155
+                      },
156
+                      {
157
+                        offset: 0,
158
+                        color: colorArray[params.dataIndex % num].bottom
159
+                      },
160
+                      {
161
+                        offset: 1,
162
+                        color: colorArray[params.dataIndex % num].top
163
+                      },
164
+                      {
165
+                        offset: 0,
166
+                        color: colorArray[params.dataIndex % num].bottom
167
+                      },
168
+                      {
169
+                        offset: 1,
170
+                        color: colorArray[params.dataIndex % num].top
171
+                      }
172
+                    ]
173
+                  }
174
+                },
175
+                barBorderRadius: 70,
176
+                borderWidth: 0,
177
+                borderColor: '#333'
178
+              }
179
+            },
180
+            barGap: '0%',
181
+            barCategoryGap: '70%',
182
+            barWidth: 8,
183
+            data: this.gradeRankingListNum
184
+          }
185
+        ]
186
+      }
187
+      this.myChart.setOption(option)
188
+    },
189
+    // 获取数据
190
+    async getData () {
191
+      const srartTime = this.$moment()
192
+        .subtract(29, 'days')
193
+        .format('YYYY-MM-DD') // 近三十天
194
+      const endTime = this.$moment().format('YYYY-MM-DD') // 今天
195
+      const result = await post(
196
+        `/largeScreen/getData/gradeRankingList/${this.hospitalId}`,
197
+        { srartTime, endTime }
198
+      )
199
+      this.gradeRankingListNum = []
200
+      this.gradeRankingListName = []
201
+      if (result.gradeRankingList.length > 5) {
202
+        result.gradeRankingList = result.gradeRankingList.slice(0, 5)
203
+      }
204
+      if (result.gradeRankingList.length > 0) {
205
+        result.gradeRankingList.forEach(item => {
206
+          this.gradeRankingListNum.push(item[2]) // 获取到的数据
207
+          this.gradeRankingListName.push(item[1]) // 获取到的名称
208
+        })
209
+      }
210
+      this.draw()
211
+      this.polling()
212
+    },
213
+    // 轮询请求
214
+    polling () {
215
+      clearTimeout(this.timer)
216
+      this.timer = setTimeout(() => {
217
+        this.getData()
218
+      }, timer8)
219
+    }
220
+  },
221
+  mounted () {
222
+    this.getData()
223
+  },
224
+  beforeDestroy () {
225
+    clearTimeout(this.timer)
226
+  }
227
+}
228
+</script>
229
+
230
+<style lang="less">
231
+.points-ranking__wrap {
232
+  height: 2.7125rem;
233
+  overflow: hidden;
234
+  .points-ranking {
235
+    width: 100%;
236
+    height: 3.25rem;
237
+    position: absolute;
238
+    left: 0;
239
+    top: -0.175rem;
240
+  }
241
+}
242
+</style>

+ 185 - 0
src/components/TimeUtilization.vue

@@ -0,0 +1,185 @@
1
+<template>
2
+  <div class="time-utilization" ref="TimeUtilization"></div>
3
+</template>
4
+
5
+<script>
6
+import echarts from 'echarts'
7
+import { post, timer4 } from './../http/http'
8
+export default {
9
+  name: 'TimeUtilization',
10
+  inject: ['hospitalId'],
11
+  data () {
12
+    return {
13
+      timer: null,
14
+      myChart: null,
15
+      groupWorkRatioName: [],
16
+      groupWorkRatioNum: []
17
+    }
18
+  },
19
+  methods: {
20
+    // 画图
21
+    draw () {
22
+      this.myChart = echarts.init(this.$refs.TimeUtilization)
23
+
24
+      const option = {
25
+        title: {
26
+          text: '时间利用率(%)',
27
+          top: 5,
28
+          left: 15,
29
+          textStyle: {
30
+            color: '#d4d6d7',
31
+            fontSize: 12
32
+          }
33
+        },
34
+        grid: {
35
+          left: '10%',
36
+          top: '20%',
37
+          bottom: '20%',
38
+          right: '5%'
39
+        },
40
+        xAxis: {
41
+          data: this.groupWorkRatioName,
42
+          axisTick: {
43
+            show: false
44
+          },
45
+          axisLine: {
46
+            lineStyle: {
47
+              color: '#709cc2'
48
+            }
49
+          },
50
+          axisLabel: {
51
+            textStyle: {
52
+              color: '#d4d6d7',
53
+              fontSize: 12
54
+            }
55
+          }
56
+        },
57
+        yAxis: [
58
+          {
59
+            max: 1,
60
+            min: 0,
61
+            interval: 0.25,
62
+            axisTick: {
63
+              show: false
64
+            },
65
+            axisLine: {
66
+              lineStyle: {
67
+                color: '#709cc2'
68
+              }
69
+            },
70
+            axisLabel: {
71
+              formatter (value) {
72
+                return value * 100
73
+              },
74
+              textStyle: {
75
+                color: '#d4d6d7',
76
+                fontSize: 12
77
+              }
78
+            },
79
+            splitArea: {
80
+              areaStyle: {
81
+                color: 'rgba(255,255,255,.5)'
82
+              }
83
+            },
84
+            splitLine: {
85
+              show: true,
86
+              lineStyle: {
87
+                color: 'rgba(255, 255, 255, 0.1)',
88
+                type: 'dashed'
89
+              }
90
+            }
91
+          }
92
+        ],
93
+        series: [
94
+          {
95
+            name: 'hill',
96
+            type: 'bar',
97
+            barCategoryGap: '0%',
98
+            barWidth: 24,
99
+            symbol:
100
+              'path://M0,10 L10,10 C5.5,10 5.5,5 5,0 C4.5,5 4.5,10 0,10 z',
101
+            label: {
102
+              show: false,
103
+              position: 'top',
104
+              distance: 0,
105
+              color: '#70c2ab',
106
+              fontWeight: 'bold',
107
+              fontSize: 12
108
+            },
109
+            itemStyle: {
110
+              normal: {
111
+                color: {
112
+                  type: 'linear',
113
+                  x: 0,
114
+                  y: 0,
115
+                  x2: 0,
116
+                  y2: 1,
117
+                  colorStops: [
118
+                    {
119
+                      offset: 0,
120
+                      color: 'rgba(112,194,130, .8)' //  0%  处的颜色
121
+                    },
122
+                    {
123
+                      offset: 1,
124
+                      color: 'rgba(112,194,130, .1)' //  100%  处的颜色
125
+                    }
126
+                  ],
127
+                  global: false //  缺省为  false
128
+                }
129
+              },
130
+              emphasis: {
131
+                opacity: 1
132
+              }
133
+            },
134
+            data: this.groupWorkRatioNum,
135
+            z: 10
136
+          }
137
+        ]
138
+      }
139
+      this.myChart.setOption(option)
140
+    },
141
+    // 获取数据
142
+    async getData () {
143
+      const srartTime = this.$moment()
144
+        .subtract(29, 'days')
145
+        .format('YYYY-MM-DD') // 近三十天
146
+      const endTime = this.$moment().format('YYYY-MM-DD') // 今天
147
+      const result = await post(
148
+        `/largeScreen/getData/groupWorkRatio/${this.hospitalId}`,
149
+        { srartTime, endTime }
150
+      )
151
+      this.groupWorkRatioNum = []
152
+      this.groupWorkRatioName = []
153
+      if (result.groutWorkRatio.length > 5) {
154
+        result.groutWorkRatio = result.groutWorkRatio.slice(0, 5)
155
+      }
156
+      result.groutWorkRatio.forEach(item => {
157
+        this.groupWorkRatioNum.push(item[1] / 100) // 获取到的数据
158
+        this.groupWorkRatioName.push(item[2]) // 获取到的名称
159
+      })
160
+      this.draw()
161
+      this.polling()
162
+    },
163
+    // 轮询请求
164
+    polling () {
165
+      clearTimeout(this.timer)
166
+      this.timer = setTimeout(() => {
167
+        this.getData()
168
+      }, timer4)
169
+    }
170
+  },
171
+  mounted () {
172
+    this.getData()
173
+  },
174
+  beforeDestroy () {
175
+    clearTimeout(this.timer)
176
+  }
177
+}
178
+</script>
179
+
180
+<style lang="less">
181
+.time-utilization{
182
+  height: 2.1375rem;
183
+  margin: 0 auto;
184
+}
185
+</style>

+ 185 - 0
src/components/TodayWorkOrder.vue

@@ -0,0 +1,185 @@
1
+<template>
2
+  <div class="today-work-order" ref="TodayWorkOrder"></div>
3
+</template>
4
+
5
+<script>
6
+import echarts from 'echarts'
7
+import { post, timer6 } from './../http/http'
8
+export default {
9
+  name: 'TodayWorkOrder',
10
+  inject: ['hospitalId'],
11
+  data () {
12
+    return {
13
+      timer: null,
14
+      myChart: null,
15
+      todayWorkOrder: [], // 今日工单情况
16
+      todayGroupWorkOrderNum: [], // 今日工单情况,图表数据,数量
17
+      todayGroupWorkOrderName: []// 今日工单情况,图表数据,名称
18
+    }
19
+  },
20
+  methods: {
21
+    // 画图
22
+    draw () {
23
+      this.myChart = echarts.init(this.$refs.TodayWorkOrder)
24
+
25
+      const option = {
26
+        title: {
27
+          text: '已完成工单数(单)',
28
+          top: 10,
29
+          left: 15,
30
+          textStyle: {
31
+            color: '#d4d6d7',
32
+            fontSize: 12
33
+          }
34
+        },
35
+        grid: {
36
+          left: '5%',
37
+          top: '25%',
38
+          bottom: '20%',
39
+          right: '5%'
40
+        },
41
+        xAxis: {
42
+          data: this.todayGroupWorkOrderName,
43
+          axisTick: {
44
+            show: false
45
+          },
46
+          axisLine: {
47
+            lineStyle: {
48
+              color: '#709cc2'
49
+            }
50
+          },
51
+          axisLabel: {
52
+            textStyle: {
53
+              color: '#d4d6d7',
54
+              fontSize: 12
55
+            }
56
+          }
57
+        },
58
+        yAxis: [
59
+          {
60
+            max: function (value) {
61
+              return value.max
62
+            },
63
+            splitNumber: 5,
64
+            minInterval: 1,
65
+            axisTick: {
66
+              show: false
67
+            },
68
+            axisLine: {
69
+              lineStyle: {
70
+                color: '#709cc2'
71
+              }
72
+            },
73
+            axisLabel: {
74
+              textStyle: {
75
+                color: '#d4d6d7',
76
+                fontSize: 12
77
+              }
78
+            },
79
+            splitArea: {
80
+              areaStyle: {
81
+                color: 'rgba(255,255,255,.5)'
82
+              }
83
+            },
84
+            splitLine: {
85
+              show: true,
86
+              lineStyle: {
87
+                color: 'rgba(255, 255, 255, 0.1)',
88
+                type: 'dashed'
89
+              }
90
+            }
91
+          }
92
+        ],
93
+        series: [
94
+          {
95
+            name: 'hill',
96
+            type: 'pictorialBar',
97
+            barCategoryGap: '0%',
98
+            barWidth: 122,
99
+            symbol:
100
+              'path://M0,10 L10,10 C5.5,10 5.5,5 5,0 C4.5,5 4.5,10 0,10 z',
101
+            label: {
102
+              show: true,
103
+              position: 'top',
104
+              distance: 0,
105
+              color: '#70c2ab',
106
+              fontWeight: 'bold',
107
+              fontSize: 12
108
+            },
109
+            itemStyle: {
110
+              normal: {
111
+                color: {
112
+                  type: 'linear',
113
+                  x: 0,
114
+                  y: 0,
115
+                  x2: 0,
116
+                  y2: 1,
117
+                  colorStops: [
118
+                    {
119
+                      offset: 0,
120
+                      color: 'rgba(112,194,130, .1)' //  0%  处的颜色
121
+                    },
122
+                    {
123
+                      offset: 1,
124
+                      color: 'rgba(112,194,130, .8)' //  100%  处的颜色
125
+                    }
126
+                  ],
127
+                  global: false //  缺省为  false
128
+                }
129
+              },
130
+              emphasis: {
131
+                opacity: 1
132
+              }
133
+            },
134
+            data: this.todayGroupWorkOrderNum,
135
+            z: 10
136
+          }
137
+        ]
138
+      }
139
+      this.myChart.setOption(option)
140
+    },
141
+    // 获取数据
142
+    async getData () {
143
+      const result = await post(
144
+        `/largeScreen/getData/todayWorkOrder/${this.hospitalId}`
145
+      )
146
+      this.todayWorkOrder = []
147
+      this.todayGroupWorkOrderNum = []
148
+      this.todayGroupWorkOrderName = []
149
+      this.todayWorkOrder = result.todayWorkOrder[0]
150
+      this.$emit('todayWorkOrderHandle', JSON.stringify(this.todayWorkOrder))
151
+      // if (result.todayGroupWorkOrder.length > 0) {
152
+      if (result.todayGroupWorkOrder.length > 5) {
153
+        result.todayGroupWorkOrder = result.todayGroupWorkOrder.slice(0, 5)
154
+      }
155
+      result.todayGroupWorkOrder.forEach(item => {
156
+        this.todayGroupWorkOrderNum.push(item[2]) // 获取到的数据
157
+        this.todayGroupWorkOrderName.push(item[1]) // 获取到的名称
158
+      })
159
+      this.draw()
160
+      // }
161
+      this.polling()
162
+    },
163
+    // 轮询请求
164
+    polling () {
165
+      clearTimeout(this.timer)
166
+      this.timer = setTimeout(() => {
167
+        this.getData()
168
+      }, timer6)
169
+    }
170
+  },
171
+  mounted () {
172
+    this.getData()
173
+  },
174
+  beforeDestroy () {
175
+    clearTimeout(this.timer)
176
+  }
177
+}
178
+</script>
179
+
180
+<style lang="less">
181
+.today-work-order{
182
+  height: 2.3875rem;
183
+  margin: 0 auto;
184
+}
185
+</style>

+ 34 - 0
src/http/http.js

@@ -0,0 +1,34 @@
1
+import axios from 'axios'
2
+const domainName = location.host// 域名+端口
3
+const protocolName = document.location.protocol// http协议
4
+const path = process.env.NODE_ENV === 'production' ? protocolName + '//' + domainName + '/service' : '/service'
5
+axios.defaults.baseURL = path
6
+axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'
7
+export const timer1 = 30000// AppToday
8
+export const timer2 = 300000// GroupPraise
9
+export const timer3 = 300000// GroupPerformance
10
+export const timer4 = 300000// TimeUtilization
11
+export const timer5 = 30000// OnDutyToday
12
+export const timer6 = 30000// TodayWorkOrder
13
+export const timer7 = 30000// ErrorWorkOrder
14
+export const timer8 = 300000// PointsRanking
15
+export const timer9 = 300000// OnTimeArrivalRate
16
+export const timer10 = 300000// BusinessTypeRatio
17
+export const timer11 = 300000// DeliveryRate
18
+// post请求
19
+export function post (url, data = {}) {
20
+  url = path + url
21
+  return new Promise((resolve, reject) => {
22
+    axios({
23
+      method: 'post',
24
+      url,
25
+      data
26
+    })
27
+      .then(res => {
28
+        resolve(res.data)
29
+      })
30
+      .catch(err => {
31
+        reject(err)
32
+      })
33
+  })
34
+}

+ 6 - 0
src/lib/components/fullScreenContainer/index.js

@@ -0,0 +1,6 @@
1
+import './src/main.css'
2
+import FullScreenContainer from './src/main.vue'
3
+
4
+export default function (Vue) {
5
+  Vue.component(FullScreenContainer.name, FullScreenContainer)
6
+}

+ 8 - 0
src/lib/components/fullScreenContainer/src/main.css

@@ -0,0 +1,8 @@
1
+#dv-full-screen-container {
2
+  position: fixed;
3
+  top: 0px;
4
+  left: 0px;
5
+  overflow: hidden;
6
+  transform-origin: left top;
7
+  z-index: 999;
8
+}

+ 57 - 0
src/lib/components/fullScreenContainer/src/main.vue

@@ -0,0 +1,57 @@
1
+<template>
2
+  <div id="dv-full-screen-container" :ref="ref">
3
+    <template v-if="ready">
4
+      <slot></slot>
5
+    </template>
6
+  </div>
7
+</template>
8
+
9
+<script>
10
+import autoResize from '../../../mixin/autoResize.js'
11
+
12
+export default {
13
+  name: 'DvFullScreenContainer',
14
+  mixins: [autoResize],
15
+  data () {
16
+    return {
17
+      ref: 'full-screen-container',
18
+      allWidth: 0,
19
+      scale: 0,
20
+      datavRoot: '',
21
+      ready: false
22
+    }
23
+  },
24
+  methods: {
25
+    afterAutoResizeMixinInit () {
26
+      const { initConfig, setAppScale } = this
27
+
28
+      initConfig()
29
+
30
+      setAppScale()
31
+
32
+      this.ready = true
33
+    },
34
+    initConfig () {
35
+      const { dom } = this
36
+      const { width, height } = screen
37
+
38
+      this.allWidth = width
39
+
40
+      dom.style.width = `${width}px`
41
+      dom.style.height = `${height}px`
42
+    },
43
+    setAppScale () {
44
+      const { allWidth, dom } = this
45
+
46
+      const currentWidth = document.body.clientWidth
47
+
48
+      dom.style.transform = `scale(${currentWidth / allWidth})`
49
+    },
50
+    onResize () {
51
+      const { setAppScale } = this
52
+
53
+      setAppScale()
54
+    }
55
+  }
56
+}
57
+</script>

+ 14 - 0
src/lib/index.js

@@ -0,0 +1,14 @@
1
+/**
2
+ * EXPORT COMPONENTS
3
+ */
4
+/**
5
+ * IMPORT COMPONENTS
6
+ */
7
+import fullScreenContainer from './components/fullScreenContainer/index'
8
+export { default as fullScreenContainer } from './components/fullScreenContainer/index'
9
+/**
10
+ * USE COMPONENTS
11
+ */
12
+export default function (Vue) {
13
+  Vue.use(fullScreenContainer)
14
+}

+ 76 - 0
src/lib/mixin/autoResize.js

@@ -0,0 +1,76 @@
1
+import { debounce, observerDomResize } from '../util/index'
2
+
3
+export default {
4
+  data () {
5
+    return {
6
+      dom: '',
7
+
8
+      width: 0,
9
+      height: 0,
10
+
11
+      debounceInitWHFun: '',
12
+
13
+      domObserver: ''
14
+    }
15
+  },
16
+  methods: {
17
+    async autoResizeMixinInit () {
18
+      const { initWH, getDebounceInitWHFun, bindDomResizeCallback, afterAutoResizeMixinInit } = this
19
+
20
+      await initWH(false)
21
+
22
+      getDebounceInitWHFun()
23
+
24
+      bindDomResizeCallback()
25
+
26
+      if (typeof afterAutoResizeMixinInit === 'function') afterAutoResizeMixinInit()
27
+    },
28
+    initWH (resize = true) {
29
+      const { $nextTick, $refs, ref, onResize } = this
30
+
31
+      return new Promise(resolve => {
32
+        $nextTick(e => {
33
+          const dom = this.dom = $refs[ref]
34
+
35
+          this.width = dom.clientWidth
36
+          this.height = dom.clientHeight
37
+
38
+          if (typeof onResize === 'function' && resize) onResize()
39
+
40
+          resolve()
41
+        })
42
+      })
43
+    },
44
+    getDebounceInitWHFun () {
45
+      const { initWH } = this
46
+
47
+      this.debounceInitWHFun = debounce(100, initWH)
48
+    },
49
+    bindDomResizeCallback () {
50
+      const { dom, debounceInitWHFun } = this
51
+
52
+      this.domObserver = observerDomResize(dom, debounceInitWHFun)
53
+
54
+      window.addEventListener('resize', debounceInitWHFun)
55
+    },
56
+    unbindDomResizeCallback () {
57
+      let { domObserver, debounceInitWHFun } = this
58
+
59
+      domObserver.disconnect()
60
+      domObserver.takeRecords()
61
+      domObserver = null
62
+
63
+      window.removeEventListener('resize', debounceInitWHFun)
64
+    }
65
+  },
66
+  mounted () {
67
+    const { autoResizeMixinInit } = this
68
+
69
+    autoResizeMixinInit()
70
+  },
71
+  beforeDestroy () {
72
+    const { unbindDomResizeCallback } = this
73
+
74
+    unbindDomResizeCallback()
75
+  }
76
+}

+ 47 - 0
src/lib/util/index.js

@@ -0,0 +1,47 @@
1
+export function randomExtend (minNum, maxNum) {
2
+  if (arguments.length === 1) {
3
+    return parseInt(Math.random() * minNum + 1, 10)
4
+  } else {
5
+    return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10)
6
+  }
7
+}
8
+
9
+export function debounce (delay, callback) {
10
+  let lastTime
11
+
12
+  return function () {
13
+    clearTimeout(lastTime)
14
+
15
+    const [that, args] = [this, arguments]
16
+
17
+    lastTime = setTimeout(() => {
18
+      callback.apply(that, args)
19
+    }, delay)
20
+  }
21
+}
22
+
23
+export function observerDomResize (dom, callback) {
24
+  const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
25
+
26
+  const observer = new MutationObserver(callback)
27
+
28
+  observer.observe(dom, { attributes: true, attributeFilter: ['style'], attributeOldValue: true })
29
+
30
+  return observer
31
+}
32
+
33
+export function getPointDistance (pointOne, pointTwo) {
34
+  const minusX = Math.abs(pointOne[0] - pointTwo[0])
35
+
36
+  const minusY = Math.abs(pointOne[1] - pointTwo[1])
37
+
38
+  return Math.sqrt(minusX * minusX + minusY * minusY)
39
+}
40
+
41
+export function uuid () {
42
+  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
43
+    const r = Math.random() * 16 | 0
44
+    const v = c === 'x' ? r : (r & 0x3 | 0x8)
45
+    return v.toString(16)
46
+  })
47
+}

+ 21 - 0
src/main.js

@@ -0,0 +1,21 @@
1
+import Vue from 'vue'
2
+import App from './App.vue'
3
+import router from './router'
4
+import { fullScreenContainer } from './lib'
5
+// import { fullScreenContainer } from '@jiaminghi/data-view'
6
+import moment from 'moment'
7
+// 适配flex
8
+import '@/assets/js/flexible.js'
9
+
10
+// 引入全局css
11
+import './assets/less/style.less'
12
+
13
+Vue.use(fullScreenContainer)
14
+Vue.prototype.$moment = moment
15
+
16
+Vue.config.productionTip = false
17
+
18
+new Vue({
19
+  router,
20
+  render: h => h(App)
21
+}).$mount('#app')

+ 16 - 0
src/router/index.js

@@ -0,0 +1,16 @@
1
+import Vue from 'vue'
2
+import VueRouter from 'vue-router'
3
+
4
+Vue.use(VueRouter)
5
+
6
+const routes = [{
7
+  path: '/:id',
8
+  name: 'index',
9
+  component: () => import('../views/AppIndex.vue')
10
+}]
11
+
12
+const router = new VueRouter({
13
+  routes
14
+})
15
+
16
+export default router

+ 264 - 0
src/views/AppIndex.vue

@@ -0,0 +1,264 @@
1
+<template>
2
+  <div class="app-index">
3
+    <dv-full-screen-container class="bg">
4
+      <div>
5
+        <!-- 头部 -->
6
+        <AppHeader></AppHeader>
7
+        <!-- 主体 -->
8
+        <main class="app-index__main">
9
+          <aside class="app-index__left">
10
+            <!-- 近三十天各小组好评率排行榜 -->
11
+            <div class="app-item">
12
+              <h2 class="app-item__header">近三十天各小组好评率排行榜</h2>
13
+              <GroupPraise></GroupPraise>
14
+            </div>
15
+            <!-- 近三十天各小组完成以及异常工单数 -->
16
+            <div class="app-item">
17
+              <h2 class="app-item__header">近三十天各小组完成以及异常工单数</h2>
18
+              <GroupPerformance></GroupPerformance>
19
+            </div>
20
+            <!-- 近三十天各小组人员工作时间利用率 -->
21
+            <div class="app-item">
22
+              <h2 class="app-item__header">近三十天各小组人员工作时间利用率</h2>
23
+              <TimeUtilization></TimeUtilization>
24
+            </div>
25
+          </aside>
26
+          <article class="app-index__center">
27
+            <!-- 今日当班情况 -->
28
+            <div class="app-item">
29
+              <h2 class="app-item__header app-item__header--big">
30
+                今日当班情况
31
+                <ul class="app-item__headerData">
32
+                  <li class="app-item__headerDataItem">总当班人数<em>{{todayBeOnDuty[0]}}/{{todayBeOnDuty[1]}}</em></li>
33
+                </ul>
34
+              </h2>
35
+              <OnDutyToday @todayBeOnDutyHandle="todayBeOnDutyHandle"></OnDutyToday>
36
+            </div>
37
+            <!-- 今日工单情况 -->
38
+            <div class="app-item">
39
+              <h2 class="app-item__header app-item__header--big">
40
+                今日工单情况
41
+                <ul class="app-item__headerData">
42
+                  <li class="app-item__headerDataItem">执行中<em>{{todayWorkOrder[0]}}</em></li>
43
+                  <li class="app-item__headerDataItem">已超时<em>{{todayWorkOrder[1]}}</em></li>
44
+                  <li class="app-item__headerDataItem">已完成<em>{{todayWorkOrder[2]}}</em></li>
45
+                </ul>
46
+              </h2>
47
+              <TodayWorkOrder @todayWorkOrderHandle = "todayWorkOrderHandle"></TodayWorkOrder>
48
+            </div>
49
+            <!-- 今日工单异常情况 -->
50
+            <div class="app-item">
51
+              <h2 class="app-item__header app-item__header--big">
52
+                今日工单异常情况
53
+                <ul class="app-item__headerData">
54
+                  <li class="app-item__headerDataItem app-item__headerDataItem--error">异常<em>{{todayAbnormityWorkOrder[0]}}</em></li>
55
+                  <li class="app-item__headerDataItem app-item__headerDataItem--timeout">超时<em>{{todayAbnormityWorkOrder[1]}}</em></li>
56
+                </ul>
57
+              </h2>
58
+              <ErrorWorkOrder @todayAbnormityWorkOrderHandle="todayAbnormityWorkOrderHandle"></ErrorWorkOrder>
59
+            </div>
60
+            <!-- 近三十天各类型工单按时送达率趋势 -->
61
+            <div class="app-item">
62
+              <h2 class="app-item__header app-item__header--big">
63
+                近三十天各类型工单按时送达率趋势
64
+                <ul class="app-item__headerData">
65
+                  <li @click="currentDictionary = item[0]" v-for="item in dictionary" :key="item[0]" class="app-item__headerDataItem app-item__headerDataItem--normal" :class="{'app-item__headerDataItem--active':currentDictionary === item[0]}"><span>{{item[1]}}</span></li>
66
+                </ul>
67
+              </h2>
68
+              <DeliveryRate @changeCurrentDictionary="changeCurrentDictionary" @dictionaryHandle="dictionaryHandle" :currentDictionary="currentDictionary"></DeliveryRate>
69
+            </div>
70
+          </article>
71
+          <aside class="app-index__right">
72
+            <!-- 近三十天人员积分排行榜 -->
73
+            <div class="app-item">
74
+              <h2 class="app-item__header">近三十天人员积分排行榜</h2>
75
+              <PointsRanking></PointsRanking>
76
+            </div>
77
+            <!-- 近三十天人员按时到达率排行榜 -->
78
+            <div class="app-item">
79
+              <h2 class="app-item__header">近三十天人员按时到达率排行榜</h2>
80
+              <OnTimeArrivalRate></OnTimeArrivalRate>
81
+            </div>
82
+            <!-- 近三十天各业务类型占比 -->
83
+            <div class="app-item">
84
+              <h2 class="app-item__header">近三十天各业务类型占比</h2>
85
+              <BusinessTypeRatio></BusinessTypeRatio>
86
+            </div>
87
+          </aside>
88
+        </main>
89
+      </div>
90
+    </dv-full-screen-container>
91
+  </div>
92
+</template>
93
+
94
+<script>
95
+import AppHeader from '../components/AppHeader.vue'
96
+import GroupPraise from '../components/GroupPraise.vue'
97
+import GroupPerformance from '../components/GroupPerformance.vue'
98
+import OnDutyToday from '../components/OnDutyToday.vue'
99
+import TodayWorkOrder from '../components/TodayWorkOrder.vue'
100
+import PointsRanking from '../components/PointsRanking.vue'
101
+import BusinessTypeRatio from '../components/BusinessTypeRatio.vue'
102
+import ErrorWorkOrder from '../components/ErrorWorkOrder.vue'
103
+import DeliveryRate from '../components/DeliveryRate.vue'
104
+import TimeUtilization from '../components/TimeUtilization.vue'
105
+import OnTimeArrivalRate from '../components/OnTimeArrivalRate.vue'
106
+export default {
107
+  name: 'AppIndex',
108
+  components: {
109
+    AppHeader, // 头部
110
+    GroupPraise, // 近三十天各小组好评率排行榜
111
+    GroupPerformance, // 近三十天各小组完成以及异常工单数
112
+    OnDutyToday, // 今日当班情况
113
+    TodayWorkOrder, // 今日工单情况
114
+    PointsRanking, // 近三十天人员积分排行榜
115
+    BusinessTypeRatio, // 近三十天各业务类型占比
116
+    ErrorWorkOrder, // 今日工单异常情况
117
+    DeliveryRate, // 近三十天各类型工单按时送达率趋势
118
+    TimeUtilization, // 近三十天各小组人员工作时间利用率
119
+    OnTimeArrivalRate// 近三十天人员按时到达率排行榜
120
+  },
121
+  data () {
122
+    return {
123
+      todayBeOnDuty: [], // 今日当班情况
124
+      todayWorkOrder: [], // 今日工单情况
125
+      todayAbnormityWorkOrder: [], // 今日工单异常情况
126
+      dictionary: [], // 近三十天各类型工单按时送达率趋势
127
+      currentDictionary: -1// 近三十天各类型工单按时送达率趋势(id)
128
+    }
129
+  },
130
+  methods: {
131
+    // 今日当班情况
132
+    todayBeOnDutyHandle (value) {
133
+      this.todayBeOnDuty = JSON.parse(value)
134
+    },
135
+    // 今日工单情况
136
+    todayWorkOrderHandle (value) {
137
+      this.todayWorkOrder = JSON.parse(value)
138
+    },
139
+    // 今日工单异常情况
140
+    todayAbnormityWorkOrderHandle (value) {
141
+      this.todayAbnormityWorkOrder = JSON.parse(value)
142
+    },
143
+    // 近三十天各类型工单按时送达率趋势
144
+    dictionaryHandle (value) {
145
+      this.dictionary = JSON.parse(value)
146
+      this.currentDictionary = this.dictionary[0][0]
147
+      this.dictionary.forEach(item => {
148
+        if (item[0] === 255) {
149
+          item[1] = '转运'
150
+        } else if (item[0] === 256) {
151
+          item[1] = '标本'
152
+        } else if (item[0] === 257) {
153
+          item[1] = '药品'
154
+        } else if (item[0] === 258) {
155
+          item[1] = '静配'
156
+        } else if (item[0] === 259) {
157
+          item[1] = '其他'
158
+        } else if (item[0] === 260) {
159
+          item[1] = '陪检'
160
+        } else if (item[0] === 380) {
161
+          item[1] = '轮巡'
162
+        }
163
+      })
164
+    },
165
+    // 近三十天各类型工单按时送达率趋势---修改索引
166
+    changeCurrentDictionary (value) {
167
+      this.currentDictionary = value
168
+    }
169
+  },
170
+  provide () {
171
+    return {
172
+      hospitalId: this.$route.params.id
173
+    }
174
+  },
175
+  mounted () {
176
+    // setTimeout(() => {
177
+    //   this.loading = false
178
+    // }, 1000)
179
+  }
180
+}
181
+</script>
182
+<style lang="less">
183
+.app-index {
184
+  color: #fff;
185
+  background-color: #000;
186
+  width: 100vw;
187
+  height: 100vh;
188
+  .bg {
189
+    padding: 0.2rem;
190
+    background-image: url("../assets/img/bg.jpg");
191
+    background-size: cover;
192
+    background-position: center center;
193
+  }
194
+  // 各模块公共头部
195
+  .app-item {
196
+    position: relative;
197
+    .app-item__header {
198
+      height: 0.3375rem;
199
+      font-size: 0.25rem;
200
+      color: #fff;
201
+      background: url("./../assets/img/image_title01.png") left bottom no-repeat;
202
+      background-size: 100%;
203
+      display: flex;
204
+      justify-content: space-between;
205
+      &.app-item__header--big{
206
+        background: url("./../assets/img/image_title02.png") left bottom no-repeat;
207
+        background-size: 100%;
208
+        .app-item__headerData{
209
+          display: flex;
210
+          justify-content: space-between;
211
+          align-content: center;
212
+          font-size: .2rem;
213
+          color: #fff;
214
+          margin-right: 1.6625rem;
215
+          margin-top: .05rem;
216
+          .app-item__headerDataItem{
217
+            margin-left: .3rem;
218
+            position: relative;
219
+            &.app-item__headerDataItem--normal span{
220
+              color: rgba(255, 255, 255, 0.6);
221
+              cursor: pointer;
222
+            }
223
+            &.app-item__headerDataItem--active span{
224
+              display: flex;
225
+              justify-content: center;
226
+              align-items: center;
227
+              width: .75rem;
228
+              background-color: #14334f;
229
+              border-radius: .15rem;
230
+              padding-top: .075rem;
231
+              padding-bottom: .075rem;
232
+              transform: translateY(-0.1rem);
233
+              color: #fff;
234
+            }
235
+            &.app-item__headerDataItem--error{
236
+              color: #c27073;
237
+            }
238
+            &.app-item__headerDataItem--timeout{
239
+              color: #c2ab70;
240
+            }
241
+          }
242
+          em{
243
+            margin-left: .1rem;
244
+          }
245
+        }
246
+      }
247
+    }
248
+  }
249
+  // 主体
250
+  .app-index__main {
251
+    display: flex;
252
+    justify-content: space-between;
253
+    .app-index__left {
254
+      width: 24.3%;
255
+    }
256
+    .app-index__center {
257
+      width: 49.5%;
258
+    }
259
+    .app-index__right {
260
+      width: 24.3%;
261
+    }
262
+  }
263
+}
264
+</style>

+ 22 - 0
vue.config.js

@@ -0,0 +1,22 @@
1
+module.exports = {
2
+  publicPath: process.env.NODE_ENV === 'production' ? '/largeScreen/' : '/',
3
+  outputDir: 'dist/largeScreen',
4
+  productionSourceMap: false,
5
+  devServer: {
6
+    open: false, // 是否自动弹出浏览器页面
7
+    host: 'localhost',
8
+    port: '8080',
9
+    https: false, // 是否使用https协议
10
+    hotOnly: false, // 是否开启热更新
11
+    proxy: {
12
+      '/service': {
13
+        target: 'http://192.168.3.108', // API服务器的地址
14
+        ws: true, // 代理websockets
15
+        changeOrigin: true, // 虚拟的站点需要更管origin
16
+        pathRewrite: {
17
+          '^/service': ''
18
+        }
19
+      }
20
+    }
21
+  }
22
+}