瀏覽代碼

初始化项目

seimin 4 年之前
當前提交
8d7b61336f
共有 100 個文件被更改,包括 25522 次插入0 次删除
  1. 13 0
      .editorconfig
  2. 47 0
      .gitignore
  3. 7 0
      README.md
  4. 142 0
      angular.json
  5. 10 0
      browserslist
  6. 32 0
      e2e/protractor.conf.js
  7. 23 0
      e2e/src/app.e2e-spec.ts
  8. 11 0
      e2e/src/app.po.ts
  9. 13 0
      e2e/tsconfig.json
  10. 32 0
      karma.conf.js
  11. 13732 0
      package-lock.json
  12. 71 0
      package.json
  13. 10 0
      proxy.conf.json
  14. 50 0
      src/app/app-routing.module.ts
  15. 1 0
      src/app/app.component.html
  16. 87 0
      src/app/app.component.less
  17. 7 0
      src/app/app.component.ts
  18. 38 0
      src/app/app.module.ts
  19. 80 0
      src/app/directives/drag.directive.ts
  20. 28 0
      src/app/guard/fuwutai.guard.ts
  21. 28 0
      src/app/guard/main.guard.ts
  22. 29 0
      src/app/guard/nurse.guard.ts
  23. 27 0
      src/app/guard/pharmacy.guard.ts
  24. 31 0
      src/app/pipes/date-transform.pipe.ts
  25. 136 0
      src/app/services/date.service.ts
  26. 86 0
      src/app/services/httpInterceptor.service.ts
  27. 316 0
      src/app/services/main.service.ts
  28. 20 0
      src/app/services/my-service.service.ts
  29. 21 0
      src/app/services/tool.service.ts
  30. 61 0
      src/app/services/websocket-phone.service.ts
  31. 56 0
      src/app/services/websocket.service.ts
  32. 59 0
      src/app/share/allocation-worker/allocation-worker.component.html
  33. 110 0
      src/app/share/allocation-worker/allocation-worker.component.less
  34. 172 0
      src/app/share/allocation-worker/allocation-worker.component.ts
  35. 433 0
      src/app/share/appraise-detail/appraise-detail.component.html
  36. 487 0
      src/app/share/appraise-detail/appraise-detail.component.less
  37. 205 0
      src/app/share/appraise-detail/appraise-detail.component.ts
  38. 111 0
      src/app/share/batch-orders/batch-orders.component.html
  39. 649 0
      src/app/share/batch-orders/batch-orders.component.less
  40. 373 0
      src/app/share/batch-orders/batch-orders.component.ts
  41. 145 0
      src/app/share/detail-drug/detail-drug.component.html
  42. 299 0
      src/app/share/detail-drug/detail-drug.component.less
  43. 218 0
      src/app/share/detail-drug/detail-drug.component.ts
  44. 95 0
      src/app/share/detail-others/detail-others.component.html
  45. 297 0
      src/app/share/detail-others/detail-others.component.less
  46. 213 0
      src/app/share/detail-others/detail-others.component.ts
  47. 182 0
      src/app/share/detail-patients/detail-patients.component.html
  48. 320 0
      src/app/share/detail-patients/detail-patients.component.less
  49. 230 0
      src/app/share/detail-patients/detail-patients.component.ts
  50. 133 0
      src/app/share/detail-sample/detail-sample.component.html
  51. 303 0
      src/app/share/detail-sample/detail-sample.component.less
  52. 212 0
      src/app/share/detail-sample/detail-sample.component.ts
  53. 15 0
      src/app/share/dialog-delete/dialog-delete.component.html
  54. 174 0
      src/app/share/dialog-delete/dialog-delete.component.less
  55. 28 0
      src/app/share/dialog-delete/dialog-delete.component.ts
  56. 29 0
      src/app/share/generate-floor/generate-floor.component.html
  57. 156 0
      src/app/share/generate-floor/generate-floor.component.less
  58. 80 0
      src/app/share/generate-floor/generate-floor.component.ts
  59. 35 0
      src/app/share/history-prompt-modal/history-prompt-modal.component.html
  60. 163 0
      src/app/share/history-prompt-modal/history-prompt-modal.component.less
  61. 51 0
      src/app/share/history-prompt-modal/history-prompt-modal.component.ts
  62. 48 0
      src/app/share/hs-prompt-modal/hs-prompt-modal.component.html
  63. 154 0
      src/app/share/hs-prompt-modal/hs-prompt-modal.component.less
  64. 133 0
      src/app/share/hs-prompt-modal/hs-prompt-modal.component.ts
  65. 1 0
      src/app/share/mask/mask.component.html
  66. 9 0
      src/app/share/mask/mask.component.less
  67. 15 0
      src/app/share/mask/mask.component.ts
  68. 595 0
      src/app/share/order-detail/order-detail.component.html
  69. 520 0
      src/app/share/order-detail/order-detail.component.less
  70. 215 0
      src/app/share/order-detail/order-detail.component.ts
  71. 24 0
      src/app/share/prompt-modal/prompt-modal.component.html
  72. 135 0
      src/app/share/prompt-modal/prompt-modal.component.less
  73. 42 0
      src/app/share/prompt-modal/prompt-modal.component.ts
  74. 71 0
      src/app/share/replication-scheme/replication-scheme.component.html
  75. 226 0
      src/app/share/replication-scheme/replication-scheme.component.less
  76. 228 0
      src/app/share/replication-scheme/replication-scheme.component.ts
  77. 28 0
      src/app/share/select-dept/select-dept.component.html
  78. 125 0
      src/app/share/select-dept/select-dept.component.less
  79. 72 0
      src/app/share/select-dept/select-dept.component.ts
  80. 24 0
      src/app/share/select-hospital/select-hospital.component.html
  81. 125 0
      src/app/share/select-hospital/select-hospital.component.less
  82. 25 0
      src/app/share/select-hospital/select-hospital.component.spec.ts
  83. 47 0
      src/app/share/select-hospital/select-hospital.component.ts
  84. 88 0
      src/app/share/share.module.ts
  85. 14 0
      src/app/views/advice-detail/advice-detail-routing.module.ts
  86. 22 0
      src/app/views/advice-detail/advice-detail.component.html
  87. 119 0
      src/app/views/advice-detail/advice-detail.component.less
  88. 39 0
      src/app/views/advice-detail/advice-detail.component.ts
  89. 19 0
      src/app/views/advice-detail/advice-detail.module.ts
  90. 24 0
      src/app/views/advice-management/advice-management-routing.module.ts
  91. 103 0
      src/app/views/advice-management/advice-management.component.html
  92. 91 0
      src/app/views/advice-management/advice-management.component.less
  93. 250 0
      src/app/views/advice-management/advice-management.component.ts
  94. 19 0
      src/app/views/advice-management/advice-management.module.ts
  95. 25 0
      src/app/views/appraise-management/appraise-management-routing.module.ts
  96. 138 0
      src/app/views/appraise-management/appraise-management.component.html
  97. 128 0
      src/app/views/appraise-management/appraise-management.component.less
  98. 340 0
      src/app/views/appraise-management/appraise-management.component.ts
  99. 19 0
      src/app/views/appraise-management/appraise-management.module.ts
  100. 0 0
      src/app/views/building-distance/building-distance-routing.module.ts

+ 13 - 0
.editorconfig

@@ -0,0 +1,13 @@
1
+# Editor configuration, see https://editorconfig.org
2
+root = true
3
+
4
+[*]
5
+charset = utf-8
6
+indent_style = space
7
+indent_size = 2
8
+insert_final_newline = true
9
+trim_trailing_whitespace = true
10
+
11
+[*.md]
12
+max_line_length = off
13
+trim_trailing_whitespace = false

+ 47 - 0
.gitignore

@@ -0,0 +1,47 @@
1
+# See http://help.github.com/ignore-files/ for more about ignoring files.
2
+
3
+# compiled output
4
+/dist
5
+/tmp
6
+/out-tsc
7
+# Only exists if Bazel was run
8
+/bazel-out
9
+
10
+# dependencies
11
+/node_modules
12
+
13
+# profiling files
14
+chrome-profiler-events.json
15
+speed-measure-plugin.json
16
+
17
+# IDEs and editors
18
+/.idea
19
+/.vscode
20
+.project
21
+.classpath
22
+.c9/
23
+*.launch
24
+.settings/
25
+*.sublime-workspace
26
+
27
+# IDE - VSCode
28
+.vscode/*
29
+!.vscode/settings.json
30
+!.vscode/tasks.json
31
+!.vscode/launch.json
32
+!.vscode/extensions.json
33
+.history/*
34
+
35
+# misc
36
+/.sass-cache
37
+/connect.lock
38
+/coverage
39
+/libpeerconnection.log
40
+npm-debug.log
41
+yarn-error.log
42
+testem.log
43
+/typings
44
+
45
+# System Files
46
+.DS_Store
47
+Thumbs.db

+ 7 - 0
README.md

@@ -0,0 +1,7 @@
1
+# 目录说明-seimin(2021-03-08)
2
+- directives存放指令
3
+- guard存放守卫
4
+- pipes存放管道
5
+- services存放服务
6
+- views存放视图
7
+- share存放共享组件

+ 142 - 0
angular.json

@@ -0,0 +1,142 @@
1
+{
2
+  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3
+  "version": 1,
4
+  "newProjectRoot": "projects",
5
+  "projects": {
6
+    "itsm-zy": {
7
+      "projectType": "application",
8
+      "schematics": {
9
+        "@schematics/angular:component": {
10
+          "style": "less"
11
+        }
12
+      },
13
+      "root": "",
14
+      "sourceRoot": "src",
15
+      "prefix": "app",
16
+      "architect": {
17
+        "build": {
18
+          "builder": "@angular-devkit/build-angular:browser",
19
+          "options": {
20
+            "outputPath": "dist/itsm-pc",
21
+            "index": "src/index.html",
22
+            "main": "src/main.ts",
23
+            "polyfills": "src/polyfills.ts",
24
+            "tsConfig": "tsconfig.app.json",
25
+            "aot": false,
26
+            "assets": [
27
+              "src/favicon.ico",
28
+              "src/assets",
29
+              {
30
+                "glob": "**/*",
31
+                "input": "./node_modules/@ant-design/icons-angular/src/inline-svg/",
32
+                "output": "/assets/"
33
+              }
34
+            ],
35
+            "styles": [
36
+              "src/styles.less",
37
+              "src/assets/iconfont/iconfont.css"
38
+            ],
39
+            "scripts": [
40
+              "node_modules/echarts/dist/echarts.min.js"
41
+            ]
42
+          },
43
+          "configurations": {
44
+            "production": {
45
+              "fileReplacements": [
46
+                {
47
+                  "replace": "src/environments/environment.ts",
48
+                  "with": "src/environments/environment.prod.ts"
49
+                }
50
+              ],
51
+              "optimization": true,
52
+              "outputHashing": "all",
53
+              "sourceMap": false,
54
+              "extractCss": true,
55
+              "namedChunks": false,
56
+              "aot": true,
57
+              "extractLicenses": true,
58
+              "vendorChunk": false,
59
+              "buildOptimizer": true,
60
+              "budgets": [
61
+                {
62
+                  "type": "initial",
63
+                  "maximumWarning": "30mb",
64
+                  "maximumError": "30mb"
65
+                }
66
+              ]
67
+            },
68
+            "es5":{
69
+              "tsConfig": "./tsconfig.app.es5.json"
70
+            }
71
+          }
72
+        },
73
+        "serve": {
74
+          "builder": "@angular-devkit/build-angular:dev-server",
75
+          "options": {
76
+            "browserTarget": "itsm-zy:build"
77
+          },
78
+          "configurations": {
79
+            "production": {
80
+              "browserTarget": "itsm-zy:build:production"
81
+            },
82
+            "es5":{
83
+              "browserTarget": "itsm-zy:build:es5"
84
+            }
85
+          }
86
+        },
87
+        "extract-i18n": {
88
+          "builder": "@angular-devkit/build-angular:extract-i18n",
89
+          "options": {
90
+            "browserTarget": "itsm-zy:build"
91
+          }
92
+        },
93
+        "test": {
94
+          "builder": "@angular-devkit/build-angular:karma",
95
+          "options": {
96
+            "main": "src/test.ts",
97
+            "polyfills": "src/polyfills.ts",
98
+            "tsConfig": "tsconfig.spec.json",
99
+            "karmaConfig": "karma.conf.js",
100
+            "assets": [
101
+              "src/favicon.ico",
102
+              "src/assets"
103
+            ],
104
+            "styles": [
105
+              "src/styles.less",
106
+              "src/assets/iconfont/iconfont.css"
107
+            ],
108
+            "scripts": [
109
+              "node_modules/echarts/dist/echarts.min.js"
110
+            ]
111
+          }
112
+        },
113
+        "lint": {
114
+          "builder": "@angular-devkit/build-angular:tslint",
115
+          "options": {
116
+            "tsConfig": [
117
+              "tsconfig.app.json",
118
+              "tsconfig.spec.json",
119
+              "e2e/tsconfig.json"
120
+            ],
121
+            "exclude": [
122
+              "**/node_modules/**"
123
+            ]
124
+          }
125
+        },
126
+        "e2e": {
127
+          "builder": "@angular-devkit/build-angular:protractor",
128
+          "options": {
129
+            "protractorConfig": "e2e/protractor.conf.js",
130
+            "devServerTarget": "itsm-zy:serve"
131
+          },
132
+          "configurations": {
133
+            "production": {
134
+              "devServerTarget": "itsm-zy:serve:production"
135
+            }
136
+          }
137
+        }
138
+      }
139
+    }
140
+  },
141
+  "defaultProject": "itsm-zy"
142
+}

+ 10 - 0
browserslist

@@ -0,0 +1,10 @@
1
+# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
2
+# For additional information regarding the format and rule options, please see:
3
+# https://github.com/browserslist/browserslist#queries
4
+
5
+# You can see what browsers were selected by your queries by running:
6
+#   npx browserslist
7
+> 1%,
8
+last 2 versions,
9
+chrome 39,
10
+not ie <= 9,

+ 32 - 0
e2e/protractor.conf.js

@@ -0,0 +1,32 @@
1
+// @ts-check
2
+// Protractor configuration file, see link for more information
3
+// https://github.com/angular/protractor/blob/master/lib/config.ts
4
+
5
+const { SpecReporter } = require('jasmine-spec-reporter');
6
+
7
+/**
8
+ * @type { import("protractor").Config }
9
+ */
10
+exports.config = {
11
+  allScriptsTimeout: 11000,
12
+  specs: [
13
+    './src/**/*.e2e-spec.ts'
14
+  ],
15
+  capabilities: {
16
+    'browserName': 'chrome'
17
+  },
18
+  directConnect: true,
19
+  baseUrl: 'http://localhost:4200/',
20
+  framework: 'jasmine',
21
+  jasmineNodeOpts: {
22
+    showColors: true,
23
+    defaultTimeoutInterval: 30000,
24
+    print: function() {}
25
+  },
26
+  onPrepare() {
27
+    require('ts-node').register({
28
+      project: require('path').join(__dirname, './tsconfig.json')
29
+    });
30
+    jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
31
+  }
32
+};

+ 23 - 0
e2e/src/app.e2e-spec.ts

@@ -0,0 +1,23 @@
1
+import { AppPage } from './app.po';
2
+import { browser, logging } from 'protractor';
3
+
4
+describe('workspace-project App', () => {
5
+  let page: AppPage;
6
+
7
+  beforeEach(() => {
8
+    page = new AppPage();
9
+  });
10
+
11
+  it('should display welcome message', () => {
12
+    page.navigateTo();
13
+    expect(page.getTitleText()).toEqual('Welcome to itsm-zy!');
14
+  });
15
+
16
+  afterEach(async () => {
17
+    // Assert that there are no errors emitted from the browser
18
+    const logs = await browser.manage().logs().get(logging.Type.BROWSER);
19
+    expect(logs).not.toContain(jasmine.objectContaining({
20
+      level: logging.Level.SEVERE,
21
+    } as logging.Entry));
22
+  });
23
+});

+ 11 - 0
e2e/src/app.po.ts

@@ -0,0 +1,11 @@
1
+import { browser, by, element } from 'protractor';
2
+
3
+export class AppPage {
4
+  navigateTo() {
5
+    return browser.get(browser.baseUrl) as Promise<any>;
6
+  }
7
+
8
+  getTitleText() {
9
+    return element(by.css('app-root h1')).getText() as Promise<string>;
10
+  }
11
+}

+ 13 - 0
e2e/tsconfig.json

@@ -0,0 +1,13 @@
1
+{
2
+  "extends": "../tsconfig.json",
3
+  "compilerOptions": {
4
+    "outDir": "../out-tsc/e2e",
5
+    "module": "commonjs",
6
+    "target": "es5",
7
+    "types": [
8
+      "jasmine",
9
+      "jasminewd2",
10
+      "node"
11
+    ]
12
+  }
13
+}

+ 32 - 0
karma.conf.js

@@ -0,0 +1,32 @@
1
+// Karma configuration file, see link for more information
2
+// https://karma-runner.github.io/1.0/config/configuration-file.html
3
+
4
+module.exports = function (config) {
5
+  config.set({
6
+    basePath: '',
7
+    frameworks: ['jasmine', '@angular-devkit/build-angular'],
8
+    plugins: [
9
+      require('karma-jasmine'),
10
+      require('karma-chrome-launcher'),
11
+      require('karma-jasmine-html-reporter'),
12
+      require('karma-coverage-istanbul-reporter'),
13
+      require('@angular-devkit/build-angular/plugins/karma')
14
+    ],
15
+    client: {
16
+      clearContext: false // leave Jasmine Spec Runner output visible in browser
17
+    },
18
+    coverageIstanbulReporter: {
19
+      dir: require('path').join(__dirname, './coverage/itsm-zy'),
20
+      reports: ['html', 'lcovonly', 'text-summary'],
21
+      fixWebpackSourcePaths: true
22
+    },
23
+    reporters: ['progress', 'kjhtml'],
24
+    port: 9876,
25
+    colors: true,
26
+    logLevel: config.LOG_INFO,
27
+    autoWatch: true,
28
+    browsers: ['Chrome'],
29
+    singleRun: false,
30
+    restartOnFileChange: true
31
+  });
32
+};

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


+ 71 - 0
package.json

@@ -0,0 +1,71 @@
1
+{
2
+  "name": "itsm-zy",
3
+  "version": "0.0.0",
4
+  "scripts": {
5
+    "210": "ng serve --proxy-config proxy.conf.json --port 4210 --disable-host-check --public-host=dashitech.com",
6
+    "ng": "ng",
7
+    "start": "ng serve",
8
+    "build": "ng build --prod",
9
+    "upload": "node ./upload/index.js",
10
+    "test": "ng test",
11
+    "lint": "ng lint",
12
+    "e2e": "ng e2e",
13
+    "bundle-report": "ng build --prod --stats-json && webpack-bundle-analyzer dist/itsm-zy/stats.json"
14
+  },
15
+  "private": true,
16
+  "dependencies": {
17
+    "@angular/animations": "~8.1.1",
18
+    "@angular/common": "~8.1.1",
19
+    "@angular/compiler": "~8.1.1",
20
+    "@angular/core": "~8.1.1",
21
+    "@angular/forms": "~8.1.1",
22
+    "@angular/platform-browser": "~8.1.1",
23
+    "@angular/platform-browser-dynamic": "~8.1.1",
24
+    "@angular/router": "~8.1.1",
25
+    "@types/crypto-js": "^3.1.47",
26
+    "@types/overlayscrollbars": "^1.9.0",
27
+    "core-js": "^3.5.0",
28
+    "crypto-js": "^4.0.0",
29
+    "datatables.net": "^1.10.20",
30
+    "date-fns": "^2.9.0",
31
+    "echarts": "^4.6.0",
32
+    "ng-zorro-antd": "^8.5.2",
33
+    "ngx-echarts": "^4.2.2",
34
+    "ngx-sortablejs": "^3.1.3",
35
+    "npm": "^6.9.0",
36
+    "overlayscrollbars": "^1.11.0",
37
+    "overlayscrollbars-ngx": "^0.1.1",
38
+    "rxjs": "~6.4.0",
39
+    "sortablejs": "^1.12.0",
40
+    "tslib": "^1.9.0",
41
+    "zone.js": "^0.9.1"
42
+  },
43
+  "devDependencies": {
44
+    "@angular-devkit/build-angular": "~0.801.1",
45
+    "@angular/cli": "~8.1.1",
46
+    "@angular/compiler-cli": "~8.1.1",
47
+    "@angular/language-service": "~8.1.1",
48
+    "@types/datatables.net": "^1.10.18",
49
+    "@types/echarts": "^4.4.2",
50
+    "@types/jasmine": "~3.3.8",
51
+    "@types/jasminewd2": "~2.0.3",
52
+    "@types/node": "~8.9.4",
53
+    "babel-polyfill": "^6.26.0",
54
+    "codelyzer": "^5.0.0",
55
+    "jasmine-core": "~3.4.0",
56
+    "jasmine-spec-reporter": "~4.2.1",
57
+    "karma": "~4.1.0",
58
+    "karma-chrome-launcher": "~2.2.0",
59
+    "karma-coverage-istanbul-reporter": "~2.0.1",
60
+    "karma-jasmine": "~2.0.1",
61
+    "karma-jasmine-html-reporter": "^1.4.0",
62
+    "protractor": "~5.4.0",
63
+    "shelljs": "^0.8.4",
64
+    "ssh2-sftp-client": "^6.0.1",
65
+    "ts-node": "~7.0.0",
66
+    "tslint": "~5.15.0",
67
+    "typescript": "~3.4.3",
68
+    "webpack-bundle-analyzer": "^3.7.0",
69
+    "zone.js": "^0.9.1"
70
+  }
71
+}

+ 10 - 0
proxy.conf.json

@@ -0,0 +1,10 @@
1
+{
2
+  "/service": {
3
+    "target": "http://192.168.3.87",
4
+    "logLevel": "debug",
5
+    "changeOrigin": true,
6
+    "pathRewrite": {
7
+      "^/service": "/service"
8
+    }
9
+  }
10
+}

+ 50 - 0
src/app/app-routing.module.ts

@@ -0,0 +1,50 @@
1
+import { NgModule } from '@angular/core';
2
+import { Routes, RouterModule } from '@angular/router';
3
+
4
+import { NurseGuard } from './guard/nurse.guard';//护士端权限
5
+import { FuwutaiGuard } from './guard/fuwutai.guard';//服务台权限
6
+import { MainGuard } from './guard/main.guard';//管理端权限
7
+import { PharmacyGuard } from './guard/pharmacy.guard';//药房端权限
8
+const routes: Routes = [
9
+  {
10
+    path: '',
11
+    redirectTo: 'login',
12
+    pathMatch: 'full'
13
+  },
14
+  {
15
+    // 登录
16
+    path: 'login',
17
+    loadChildren: () => import('./views/login/login.module').then(m => m.LoginModule)
18
+  },
19
+  {
20
+    //管理端
21
+    path: 'main',
22
+    loadChildren: () => import('./views/main/main.module').then(m => m.MainModule),
23
+    canActivate: [MainGuard],
24
+  },
25
+  {
26
+    //调度台
27
+    path: 'dispatchingDesk',
28
+    loadChildren: () => import('./views/fuwutai/fuwutai.module').then(m => m.FuwutaiModule),
29
+    canActivate: [FuwutaiGuard],
30
+  },
31
+  {
32
+    // 护士端
33
+    path: 'nurse',
34
+    loadChildren: () => import('./views/hushijiandan/hushijiandan.module').then(m => m.HushijiandanModule),
35
+    canActivate: [NurseGuard],
36
+  },
37
+  {
38
+    path: 'pharmacy',//药房端
39
+    loadChildren: () => import('./views/pharmacy/pharmacy.module').then(m => m.PharmacyModule),
40
+    canActivate: [PharmacyGuard]
41
+  },
42
+  { path: '**', redirectTo: 'main/home' }
43
+
44
+];
45
+
46
+@NgModule({
47
+  imports: [RouterModule.forRoot(routes)],
48
+  exports: [RouterModule]
49
+})
50
+export class AppRoutingModule { }

+ 1 - 0
src/app/app.component.html

@@ -0,0 +1 @@
1
+<router-outlet></router-outlet>

+ 87 - 0
src/app/app.component.less

@@ -0,0 +1,87 @@
1
+:host {
2
+  width: 100%;
3
+  height: 100%;
4
+  display: flex;
5
+  text-rendering: optimizeLegibility;
6
+  -webkit-font-smoothing: antialiased;
7
+  -moz-osx-font-smoothing: grayscale;
8
+}
9
+
10
+app-main {
11
+  width: 100%;
12
+}
13
+
14
+.app-layout {
15
+  width: 100%;
16
+  height: 100vh;
17
+}
18
+
19
+.menu-sidebar {
20
+  position: relative;
21
+  z-index: 8;
22
+  min-height: 100vh;
23
+  box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
24
+}
25
+
26
+.header-trigger {
27
+  height: 64px;
28
+  padding: 20px 24px;
29
+  font-size: 20px;
30
+  cursor: pointer;
31
+  transition: all 0.3s, padding 0s;
32
+}
33
+
34
+.trigger:hover {
35
+  color: #1890ff;
36
+}
37
+
38
+.sidebar-logo {
39
+  position: relative;
40
+  height: 64px;
41
+  padding-left: 24px;
42
+  overflow: hidden;
43
+  line-height: 64px;
44
+  background: #001529;
45
+  transition: all 0.3s;
46
+}
47
+
48
+.sidebar-logo img {
49
+  display: inline-block;
50
+  height: 32px;
51
+  width: 32px;
52
+  vertical-align: middle;
53
+}
54
+
55
+.sidebar-logo h1 {
56
+  display: inline-block;
57
+  margin: 0 0 0 20px;
58
+  color: #fff;
59
+  font-weight: 600;
60
+  font-size: 14px;
61
+  font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
62
+  vertical-align: middle;
63
+}
64
+
65
+nz-header {
66
+  padding: 0;
67
+  width: 100%;
68
+  z-index: 2;
69
+}
70
+
71
+.app-header {
72
+  position: relative;
73
+  height: 64px;
74
+  padding: 0;
75
+  background: #fff;
76
+  box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
77
+}
78
+
79
+nz-content {
80
+  margin: 24px;
81
+}
82
+
83
+.inner-content {
84
+  padding: 24px;
85
+  background: #fff;
86
+  /* height: 100%; */
87
+}

+ 7 - 0
src/app/app.component.ts

@@ -0,0 +1,7 @@
1
+import { Component } from '@angular/core';
2
+@Component({
3
+  selector: 'app-root',
4
+  templateUrl: './app.component.html',
5
+  styleUrls: ['./app.component.less']
6
+})
7
+export class AppComponent {}

+ 38 - 0
src/app/app.module.ts

@@ -0,0 +1,38 @@
1
+import { BrowserModule } from '@angular/platform-browser';
2
+import { NgModule } from '@angular/core';
3
+import { CommonModule } from '@angular/common';
4
+import { AppRoutingModule } from './app-routing.module';
5
+import { AppComponent } from './app.component';
6
+import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
7
+import { registerLocaleData, HashLocationStrategy, LocationStrategy } from '@angular/common';
8
+import zh from '@angular/common/locales/zh';
9
+import { HttpInterceptorService } from './services/httpInterceptor.service';//请求拦截器
10
+import { ShareModule } from './share/share.module';
11
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
12
+import { NZ_I18N, zh_CN, NzConfig, NZ_CONFIG } from 'ng-zorro-antd';
13
+const ngZorroConfig: NzConfig = {
14
+  // 注意组件名称没有 nz 前缀
15
+  notification: { nzTop: 100 }
16
+};
17
+registerLocaleData(zh);
18
+@NgModule({
19
+  declarations: [
20
+    AppComponent,
21
+  ],
22
+  imports: [
23
+    BrowserModule,
24
+    CommonModule,
25
+    BrowserAnimationsModule,
26
+    AppRoutingModule,
27
+    HttpClientModule,
28
+    ShareModule,
29
+  ],
30
+  providers: [
31
+    { provide: NZ_I18N, useValue: zh_CN },
32
+    { provide: NZ_CONFIG, useValue: ngZorroConfig },
33
+    { provide: LocationStrategy, useClass: HashLocationStrategy },
34
+    { provide: HTTP_INTERCEPTORS, useClass: HttpInterceptorService, multi: true },
35
+  ],
36
+  bootstrap: [AppComponent]
37
+})
38
+export class AppModule { }

+ 80 - 0
src/app/directives/drag.directive.ts

@@ -0,0 +1,80 @@
1
+import { Directive, ElementRef, HostListener, OnInit } from '@angular/core';
2
+import { fromEvent } from 'rxjs';
3
+
4
+@Directive({
5
+  selector: '[appDrag]'
6
+})
7
+export class DragDirective implements OnInit {
8
+
9
+  private isDown = false;
10
+  private disX = 0;
11
+  private disY = 0;
12
+
13
+  constructor(private el: ElementRef) { }
14
+
15
+  /*  ElementRef是一个服务,它赋予我们通过它的nativeElement属性直接访问 "DOM 元素"的能力  */
16
+
17
+  ngOnInit() {
18
+    this.el.nativeElement.style.left = (document.documentElement.clientWidth - this.el.nativeElement.offsetWidth) / 2 + 'px';
19
+    this.el.nativeElement.style.top = (document.documentElement.clientHeight - this.el.nativeElement.offsetHeight) / 2 + 'px';
20
+
21
+    /* 模态框距左边的距离是document的宽度减去模态框的宽度除以二,同理得出距上面的距离 */
22
+
23
+    fromEvent(window, 'resize').subscribe(() => {
24
+      this.el.nativeElement.style.left = (document.documentElement.clientWidth - this.el.nativeElement.offsetWidth) / 2 + 'px';
25
+      this.el.nativeElement.style.top = (document.documentElement.clientHeight - this.el.nativeElement.offsetHeight) / 2 + 'px';
26
+    });
27
+
28
+    /* 监控浏览区大小变化,将其设置在浏览器中间位置 */
29
+
30
+  }
31
+
32
+  // 点击事件
33
+  @HostListener('mousedown', ['$event']) onMousedown(event) {
34
+    // 点击关闭
35
+    if (!event.target.className.includes('icon-close')&&!event.target.className.includes('dialog-refresh')){
36
+      // if (event.target.className.indexOf('drag-title') !== -1) {
37
+      // 移动区域
38
+      this.isDown = true;
39
+      this.disX = event.clientX - this.el.nativeElement.offsetLeft;
40
+      this.disY = event.clientY - this.el.nativeElement.offsetTop;
41
+      // }
42
+    }
43
+    return false;
44
+  }
45
+  // 监听document移动事件事件
46
+  @HostListener('document:mousemove', ['$event']) onMousemove(event) {
47
+    // 判断该元素是否被点击了。
48
+    if (this.isDown) {
49
+      // 移动中;
50
+      const newdisX = event.clientX;
51
+      const newdisY = event.clientY;
52
+      let oLeft = newdisX - this.disX;
53
+      let oTop = newdisY - this.disY;
54
+      if (oLeft < 0) {
55
+        oLeft = 0;
56
+      } else if (oLeft > document.documentElement.clientWidth - this.el.nativeElement.offsetWidth) {
57
+        oLeft = document.documentElement.clientWidth - this.el.nativeElement.offsetWidth;
58
+      }
59
+      if (oTop < 0) {
60
+        oTop = 0;
61
+      } else if (oTop > document.documentElement.clientHeight - this.el.nativeElement.offsetHeight) {
62
+        oTop = document.documentElement.clientHeight - this.el.nativeElement.offsetHeight;
63
+      }
64
+      this.el.nativeElement.style.left = oLeft + 'px';
65
+      this.el.nativeElement.style.top = oTop + 'px';
66
+    }
67
+    return false;
68
+  }
69
+  // 监听document离开事件
70
+
71
+  @HostListener('document:mouseup', ['$event']) onMouseup() {
72
+    // 只用当元素移动过了,离开函数体才会触发。
73
+    if (this.isDown) {
74
+      document.onmousemove = null;
75
+      document.onmouseup = null;
76
+      this.isDown = false;
77
+    }
78
+    return false;
79
+  }
80
+}

+ 28 - 0
src/app/guard/fuwutai.guard.ts

@@ -0,0 +1,28 @@
1
+import { Injectable } from '@angular/core';
2
+import { Router, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, CanActivate } from '@angular/router';
3
+import { Observable } from 'rxjs';
4
+
5
+@Injectable({
6
+  providedIn: 'root'
7
+})
8
+export class FuwutaiGuard implements CanActivate {
9
+
10
+  constructor(public router: Router) { }
11
+
12
+  canActivate(): boolean {
13
+    let menus = JSON.parse(localStorage.getItem('menu'));
14
+    let can = false;
15
+    if (menus) {
16
+      menus.forEach((e) => {
17
+        if (e.link == 'dispatchingDesk') {
18
+          can = true;
19
+        }
20
+      });
21
+    }
22
+    if (!can) {
23
+      this.router.navigate(['login']);
24
+      return false
25
+    }
26
+    return true;
27
+  }
28
+}

+ 28 - 0
src/app/guard/main.guard.ts

@@ -0,0 +1,28 @@
1
+import { Injectable } from '@angular/core';
2
+import { ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, CanActivate, Router } from '@angular/router';
3
+import { Observable } from 'rxjs';
4
+
5
+@Injectable({
6
+  providedIn: 'root'
7
+})
8
+export class MainGuard implements CanActivate {
9
+  constructor(public router: Router) { }
10
+
11
+  canActivate(): boolean {
12
+    let menus = JSON.parse(localStorage.getItem('menu'));
13
+    let can = false;
14
+    if (menus) {
15
+      console.log(menus,'守卫');
16
+      menus.forEach((e) => {
17
+        if (!e.parentid && !e.link && e.event == 1) {
18
+          can = true;
19
+        }
20
+      });
21
+    }
22
+    if (!can) {
23
+      this.router.navigate(['login']);
24
+      return false
25
+    }
26
+    return true;
27
+  }
28
+}

+ 29 - 0
src/app/guard/nurse.guard.ts

@@ -0,0 +1,29 @@
1
+import { Injectable } from '@angular/core';
2
+import { Router, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, CanActivate } from '@angular/router';
3
+import { Observable } from 'rxjs';
4
+
5
+@Injectable({
6
+  providedIn: 'root'
7
+})
8
+export class NurseGuard implements CanActivate {
9
+
10
+  constructor(public router: Router) { }
11
+
12
+  canActivate(): boolean {
13
+    let menus = JSON.parse(localStorage.getItem('menu'));
14
+    let can = false;
15
+    if(menus){
16
+      menus.forEach((e) => {
17
+        if (e.link == 'nurse') {
18
+          can = true;
19
+        }
20
+      });
21
+    }
22
+    if (!can) {
23
+      this.router.navigate(['login']);
24
+      return false
25
+    }
26
+    return true;
27
+  }
28
+
29
+}

+ 27 - 0
src/app/guard/pharmacy.guard.ts

@@ -0,0 +1,27 @@
1
+import { Injectable } from '@angular/core';
2
+import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from '@angular/router';
3
+import { Observable } from 'rxjs';
4
+
5
+@Injectable({
6
+  providedIn: 'root'
7
+})
8
+export class PharmacyGuard implements CanActivate {
9
+  constructor(public router: Router) { }
10
+
11
+  canActivate(): boolean {
12
+    let menus = JSON.parse(localStorage.getItem('menu'));
13
+    let can = false;
14
+    if (menus) {
15
+      menus.forEach((e) => {
16
+        if (e.link == 'pharmacy') {
17
+          can = true;
18
+        }
19
+      });
20
+    }
21
+    if (!can) {
22
+      this.router.navigate(['login']);
23
+      return false
24
+    }
25
+    return true;
26
+  }
27
+}

+ 31 - 0
src/app/pipes/date-transform.pipe.ts

@@ -0,0 +1,31 @@
1
+import { Pipe, PipeTransform } from '@angular/core';
2
+
3
+@Pipe({
4
+  name: 'dateTransform'
5
+})
6
+export class DateTransformPipe implements PipeTransform {
7
+
8
+  transform(value: any, ...args: any[]): any {
9
+    let fullDate = new Date(value);//传入的日期
10
+    let year = fullDate.getFullYear();
11
+    let month = (fullDate.getMonth() + 1).toString().padStart(2, '0');
12
+    let date = fullDate.getDate().toString().padStart(2, '0');
13
+    let hour = fullDate.getHours().toString().padStart(2, '0');
14
+    let minute = fullDate.getMinutes().toString().padStart(2, '0');
15
+    let nowFullDate = new Date();//当前的日期
16
+    let nowYear = nowFullDate.getFullYear();//当前的年份
17
+    let nowDate = nowFullDate.getDate().toString().padStart(2, '0');//当前是几号
18
+    let day1 = new Date(nowFullDate.getTime() - 24 * 60 * 60);//昨天
19
+    let day1Date = day1.getDate().toString().padStart(2, '0');//昨天是几号
20
+    if (year !== nowYear) {//跨年
21
+      return `${year}-${month}-${date} ${hour}:${minute}`;
22
+    } else if (day1Date === date) {//昨日
23
+      return `昨日 ${month}-${date} ${hour}:${minute}`;
24
+    } else if (nowDate === date) {//今日
25
+      return `今日 ${month}-${date} ${hour}:${minute}`;
26
+    } else {
27
+      return `${month}-${date} ${hour}:${minute}`;
28
+    }
29
+  }
30
+
31
+}

+ 136 - 0
src/app/services/date.service.ts

@@ -0,0 +1,136 @@
1
+import { Injectable } from '@angular/core';
2
+
3
+@Injectable({
4
+  providedIn: 'root'
5
+})
6
+export class DateService {
7
+
8
+  constructor() { }
9
+  date() {
10
+    /**
11
+     * 获取本周、本季度、本月、上月的开始日期、结束日期
12
+     */
13
+    var now = new Date(); //当前日期
14
+    var nowDayOfWeek = now.getDay(); //今天本周的第几天
15
+    var nowDay = now.getDate(); //当前日
16
+    var nowMonth = now.getMonth(); //当前月
17
+    var nowYear = now.getFullYear(); //当前年
18
+    nowYear += (nowYear < 2000) ? 1900 : 0; //
19
+    var lastMonthDate = new Date(); //上月日期
20
+    lastMonthDate.setDate(1);
21
+    lastMonthDate.setMonth(lastMonthDate.getMonth() - 1);
22
+    var lastYear = lastMonthDate.getFullYear();
23
+    var lastMonth = lastMonthDate.getMonth();
24
+    var lastMonthYear = lastMonthDate.getFullYear();//上月的年份
25
+    //格式化日期:yyyy-MM-dd
26
+    function formatDate(date) {
27
+      var myyear = date.getFullYear();
28
+      var mymonth = date.getMonth() + 1;
29
+      var myweekday = date.getDate();
30
+      if (mymonth < 10) {
31
+        mymonth = "0" + mymonth;
32
+      }
33
+      if (myweekday < 10) {
34
+        myweekday = "0" + myweekday;
35
+      }
36
+      return (myyear + "-" + mymonth + "-" + myweekday);
37
+    }
38
+    //获得某月的天数
39
+    function getMonthDays(myMonth) {
40
+      var monthStartDate = new Date(nowYear, myMonth, 1);
41
+      var monthEndDate = new Date(nowYear, myMonth + 1, 1);
42
+      var days = (Number(monthEndDate) - Number(monthStartDate)) / (1000 * 60 * 60 * 24);
43
+      return days;
44
+    }
45
+    //获得本季度的开始月份
46
+    function getQuarterStartMonth() {
47
+      var quarterStartMonth = 0;
48
+      if (nowMonth < 3) {
49
+        quarterStartMonth = 0;
50
+      }
51
+      if (2 < nowMonth && nowMonth < 6) {
52
+        quarterStartMonth = 3;
53
+      }
54
+      if (5 < nowMonth && nowMonth < 9) {
55
+        quarterStartMonth = 6;
56
+      }
57
+      if (nowMonth > 8) {
58
+        quarterStartMonth = 9;
59
+      }
60
+      return quarterStartMonth;
61
+    }
62
+    //获得本周的开始日期
63
+    function getWeekStartDate() {
64
+      var weekStartDate = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek);
65
+      return weekStartDate;
66
+    }
67
+    //获得本周的结束日期
68
+    function getWeekEndDate() {
69
+      var weekEndDate = new Date(nowYear, nowMonth, nowDay + (6 - nowDayOfWeek));
70
+      return weekEndDate;
71
+    }
72
+    //获得上周的开始日期
73
+    function getLastWeekStartDate() {
74
+      var weekStartDate = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek - 6);
75
+      // var weekStartDate = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek - 7);//周日为一周的第一天
76
+      return weekStartDate;
77
+    }
78
+    //获得上周的结束日期
79
+    function getLastWeekEndDate() {
80
+      var weekEndDate = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek);
81
+      // var weekEndDate = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek-1);//周六为一周的最后一天
82
+      return weekEndDate;
83
+    }
84
+    //获得本月的开始日期
85
+    function getMonthStartDate() {
86
+      var monthStartDate = new Date(nowYear, nowMonth, 1);
87
+      return monthStartDate;
88
+    }
89
+    //获得本月的结束日期
90
+    function getMonthEndDate() {
91
+      var monthEndDate = new Date(nowYear, nowMonth, getMonthDays(nowMonth));
92
+      return monthEndDate;
93
+    }
94
+    //获得上月开始时间
95
+    function getLastMonthStartDate() {
96
+      var lastMonthStartDate = new Date(lastMonthYear, lastMonth, 1);
97
+      return lastMonthStartDate;
98
+    }
99
+    //获得上月结束时间
100
+    function getLastMonthEndDate() {
101
+      var lastMonthEndDate = new Date(lastMonthYear, lastMonth, getMonthDays(lastMonth));
102
+      return lastMonthEndDate;
103
+    }
104
+    //获得本季度的开始日期
105
+    function getQuarterStartDate() {
106
+      var quarterStartDate = new Date(nowYear, getQuarterStartMonth(), 1);
107
+      return quarterStartDate;
108
+    }
109
+    //获得本季度的结束日期
110
+    function getQuarterEndDate() {
111
+      var quarterEndMonth = getQuarterStartMonth() + 2;
112
+      var quarterStartDate = new Date(nowYear, quarterEndMonth,
113
+        getMonthDays(quarterEndMonth));
114
+      return quarterStartDate;
115
+    }
116
+    //获得上年的开始日期
117
+    function getLastYearStartDate() {
118
+      var yearStartDate = new Date(nowYear - 1, 0, 1);
119
+      return yearStartDate;
120
+    }
121
+    //获得上年的结束日期
122
+    function getLastYearEndDate() {
123
+      var yearEndDate = new Date(nowYear - 1, 11, 31);
124
+      return yearEndDate;
125
+    }
126
+    return {
127
+      lastWeekStartDate: getLastWeekStartDate(),
128
+      lastWeekEndDate: getLastWeekEndDate(),
129
+      lastMonthStartDate: getLastMonthStartDate(),
130
+      lastMonthEndDate: getLastMonthEndDate(),
131
+      lastYearStartDate: getLastYearStartDate(),
132
+      lastYearEndDate: getLastYearEndDate(),
133
+      formatDate: formatDate,
134
+    }
135
+  }
136
+}

+ 86 - 0
src/app/services/httpInterceptor.service.ts

@@ -0,0 +1,86 @@
1
+import { Injectable } from '@angular/core';
2
+import { HttpInterceptor, HttpEvent, HttpHandler, HttpRequest, HttpResponse } from '@angular/common/http';
3
+import { Observable } from 'rxjs';
4
+import { tap } from 'rxjs/operators';
5
+import { Router } from '@angular/router'
6
+import { NzMessageService } from 'ng-zorro-antd/message';
7
+const ignoreToken = ['login', 'logout', 'table'];
8
+// @Injectable()
9
+export class HttpInterceptorService implements HttpInterceptor {
10
+  constructor(private router: Router, private msg: NzMessageService) { }
11
+  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
12
+    // alert(6)
13
+    // 先补全请求协议
14
+    let url = req.url;
15
+    const needToken = ignoreToken.filter(u => url.match(u));
16
+    // if (url.indexOf('http://') < 0 || url.indexOf('https://') < 0) {
17
+    //   url = 'http://' + url;
18
+    // }
19
+    // 过滤掉不需要token的请求
20
+    if (!needToken.length) {
21
+      req = req.clone({
22
+        url
23
+      });
24
+    } else {
25
+      req = req.clone({
26
+        url,
27
+        headers: req.headers.set('token', 'asdqwe')
28
+      });
29
+    }
30
+    return next.handle(req).pipe(
31
+      tap(
32
+        event => {
33
+          if (event instanceof HttpResponse) {
34
+            let that = this;
35
+            if (event.body == 520) {
36
+              // 登录失效
37
+              // console.log('event登录失效')
38
+              // that.msg.error('您的登录已失效,请重新登录!', {
39
+              //   nzDuration: 3000
40
+              // });
41
+              setTimeout(() => {
42
+                that.router.navigateByUrl('login');
43
+              }, 2000);
44
+              localStorage.removeItem('user')
45
+              localStorage.removeItem('menu')
46
+              localStorage.removeItem('phones')
47
+              localStorage.removeItem('index')
48
+              return;
49
+            }
50
+            else if (event.status == 500) {
51
+              // 系统异常
52
+              console.log('event系统异常')
53
+              // that.msg.error(event.body.remarks, {
54
+              //   nzDuration: 2000
55
+              // });
56
+              return
57
+            }
58
+          }
59
+        },
60
+        error => {
61
+          // console.log(error)
62
+          let that = this;
63
+          if (error.error && error.error.text == 520) {
64
+            // 登录失效
65
+            setTimeout(() => {
66
+              that.router.navigateByUrl('login');
67
+              localStorage.removeItem('user')
68
+              localStorage.removeItem('menu')
69
+              localStorage.removeItem('phones')
70
+              localStorage.removeItem('index')
71
+            }, 2000);
72
+            return
73
+          }
74
+          else if (error.status == 500) {
75
+            // 系统异常
76
+            console.log('error系统异常,请重试!')
77
+            // that.msg.error('error系统异常,请重试!', {
78
+            //   nzDuration: 3000
79
+            // });
80
+            return
81
+          }
82
+
83
+        })
84
+    );
85
+  }
86
+}

+ 316 - 0
src/app/services/main.service.ts

@@ -0,0 +1,316 @@
1
+import { Injectable } from '@angular/core';
2
+import { HttpClient, HttpHeaders } from '@angular/common/http';
3
+
4
+import host from "../../assets/js/http";
5
+
6
+@Injectable({
7
+  providedIn: 'root'
8
+})
9
+export class MainService {
10
+  constructor(private http: HttpClient) { }
11
+
12
+  headers = new HttpHeaders({
13
+    'Content-Type': 'application/json',
14
+    'Cache-Control': 'no-cache'
15
+  });
16
+  exportHeader = new HttpHeaders().set('Accept', '*/*');//导出excel表使用
17
+  // 单点登录
18
+  singleSignOnLogin(data): any {
19
+    return this.http.post(host.host + '/auth/portalLogin', data, { headers: this.headers });
20
+  }
21
+  // 登录
22
+  login(name: string, pwd: string): any {
23
+    const data = {
24
+      username: name,
25
+      password: pwd,
26
+      type: 'PC'
27
+    }
28
+    return this.http.post(host.host + '/auth/login', data, { headers: this.headers });
29
+  }
30
+  // 登出
31
+  logOut(): any {
32
+    return this.http.delete(host.host + '/auth/logout2', { headers: this.headers });
33
+  }
34
+
35
+  // 修改密码
36
+  upPwd(data): any {
37
+    return this.http.post(host.host + '/auth/uppwd', data, { headers: this.headers });
38
+  }
39
+  // 字典表
40
+  getDictionary(type, key): any {
41
+    const data = {
42
+      type: type,
43
+      key: key
44
+    }
45
+    return this.http.post(host.host + '/common/common/getDictionary', data, { headers: this.headers });
46
+  }
47
+  // 列表搜索(get data)
48
+  getDataFetchData(type, id): any {
49
+    return this.http.get(host.host + '/data/fetchData/' + type + '/' + id, { headers: this.headers });
50
+  }
51
+  // api 详情 -工单详情
52
+  getApiFetchData(type, id): any {
53
+    return this.http.get(host.host + '/api/fetchData/' + type + '/' + id, { headers: this.headers });
54
+  }
55
+  // 列表搜索(通用)
56
+  getFetchDataList(type, target, data): any {
57
+    return this.http.post(host.host + '/' + type + '/fetchDataList/' + target, data, { headers: this.headers });
58
+  }
59
+
60
+  // 调度台 获取支助人员信息
61
+  getSerInfo(type, data): any {
62
+    return this.http.post(host.host + '/ser/' + type, data, { headers: this.headers });
63
+  }
64
+
65
+  // 通用操作data信息(新增/更新/删除)//coop:操作类型addData:新增,updData更新,rmvData删除
66
+  coopData(coop, type, data): any {
67
+    return this.http.post(host.host + '/data/' + coop + '/' + type, data, { headers: this.headers });
68
+  }
69
+
70
+  // 通用操作user data信息(新增/更新/删除)//coop:操作类型addData:新增,updData更新,rmvData删除
71
+  coopUserData(coop, type, data): any {
72
+    return this.http.post(host.host + '/user/data/' + coop + '/' + type, data, { headers: this.headers });
73
+  }
74
+  // 获取院区user信息
75
+  getHosUser(type, id): any {
76
+    return this.http.get(host.host + '/user/data/' + type + '/' + id, {});
77
+  }
78
+
79
+  // 通用操作configuration信息 有操作类型(新增/更新/删除)//coop:操作类型addData:新增,updData更新,rmvData删除
80
+  coopTypeConfig(coop, type, data): any {
81
+    return this.http.post(host.host + '/configuration/' + coop + '/' + type, data, { headers: this.headers });
82
+  }
83
+  // 通用操作configuration信息(新增/更新/删除)
84
+  coopConfig(type, data): any {
85
+    return this.http.post(host.host + '/configuration/' + type, data, { headers: this.headers });
86
+  }
87
+
88
+  // 查询所有数据
89
+  findAllDataList(type): any {
90
+    return this.http.post(host.host + '/data/findAll/' + type, {}, { headers: this.headers });
91
+  }
92
+
93
+  // 权限相关
94
+  getPermission(type): any {
95
+    return this.http.get(host.host + '/permission/roleMenu/' + type, { headers: this.headers });
96
+  }
97
+
98
+  //科室详情
99
+  getOfficeDetail(id): any {
100
+    return this.http.get(host.host + '/data/fetchData/department/' + id, { headers: this.headers });
101
+  }
102
+
103
+  // fetchData查看详情
104
+  getFetchData(type, info, id?): any {
105
+    let url = id ? host.host + '/' + type + '/fetchData/' + info + '/' + id : host.host + '/' + type + '/fetchData/' + info
106
+    return this.http.get(url, { headers: this.headers });
107
+  }
108
+
109
+  // 获取楼栋信息/楼层信息
110
+  getBuildingOrFloor(type, data): any {
111
+    return this.http.post(host.host + '/data/getBuildingOrFloor/' + type, data, { headers: this.headers });
112
+  }
113
+
114
+  // 自定义请求 post
115
+  postCustom(type, info, data): any {
116
+    return this.http.post(host.host + '/' + type + '/' + info, data, { headers: this.headers });
117
+  }
118
+  // 科室二维码打印flag=1
119
+  postCustomCode(type, info, data): any {
120
+    return this.http.post(host.host + '/' + type + '/' + info + '/1', data, { headers: this.headers });
121
+  }
122
+
123
+  // 自定义请求 get
124
+  getCustom(type, info): any {
125
+    return this.http.get(host.host + '/' + type + '/' + info, { headers: this.headers });
126
+  }
127
+  // 调度台-分派工单
128
+  assignWorker(data, type): any {
129
+    return this.http.post(host.host + '/workerOrder/' + type, data, { headers: this.headers });
130
+  }
131
+
132
+  // 调度台-删除工单
133
+  delOrder(id): any {
134
+    return this.http.get(host.host + '/workerOrder/delWorkOrder/' + id, { headers: this.headers });
135
+  }
136
+  // 工单列表-删除工单
137
+  delOrders(ids): any {
138
+    return this.http.post(host.host + '/workerOrder/delWorkOrders', { ids }, { headers: this.headers });
139
+  }
140
+
141
+  // 调度台工单相关
142
+  coopWorkerOrder(type, data): any {
143
+    return this.http.post(host.host + '/workerOrder/' + type, data, { headers: this.headers });
144
+  }
145
+
146
+  // 调度台-工单历史记录
147
+  getWorkOrderLog(id): any {
148
+    return this.http.get(host.host + '/ser/fetchWorkOrderLog/' + id, { headers: this.headers });
149
+  }
150
+
151
+  // 综合报表
152
+  postReportCount(type, data): any {
153
+    return this.http.post(host.host + '/report/orderCount/' + type, data, { headers: this.headers });
154
+  }
155
+
156
+  // 报表导出
157
+  exportReport(type, data): any {
158
+    return this.http.post(host.host + '/report/export/' + type, data, { headers: this.exportHeader, responseType: 'arraybuffer' });
159
+  }
160
+
161
+  dataExport(type, data): any {
162
+    return this.http.post(host.host + '/data/export/' + type, data, { headers: this.exportHeader, responseType: 'arraybuffer' });
163
+  }
164
+  //新增/编辑轮巡计划
165
+  addRoundRobin(type: string, data: any): any {
166
+    return this.http.post(host.host + '/orderPlan/' + type, data, { headers: this.headers });
167
+  }
168
+  //删除轮巡计划
169
+  delRoundRobin(id): any {
170
+    return this.http.get(host.host + '/orderPlan/deletePlan/' + id, { headers: this.headers });
171
+  }
172
+  //启用/停用轮巡计划
173
+  switchRoundRobin(isSwitch, id): any {
174
+    return this.http.get(`${host.host}/orderPlan/activePlan/${isSwitch}/${id}`, { headers: this.headers });
175
+  }
176
+  //新增/编辑快捷建单
177
+  addShortcutBuildOrders(type: string, data: any): any {
178
+    return this.http.post(host.host + '/api/' + type + '/quickOrder', data, { headers: this.headers });
179
+  }
180
+  //删除快捷建单
181
+  delShortcutBuildOrders(id): any {
182
+    return this.http.post(host.host + '/api/rmvData/quickOrder', [id], { headers: this.headers });
183
+  }
184
+  // 快捷建单二维码批量打印
185
+  printShortcutBuildOrders(idArr): any {
186
+    return this.http.post(host.host + '/api/orderCodes', idArr, { headers: this.headers });
187
+  }
188
+  //护士端返回二维码信息,flag=0,动态二维码
189
+  getDeptCode(idArr) {
190
+    return this.http.post(host.host + '/dept/deptCodes/0', idArr, { headers: this.headers });
191
+  }
192
+  //药房端药房列表查询、搜索接口
193
+  getPharmacyList(idx, type, searchKey, launch) {
194
+    return this.http.post(host.host + '/api/fetchDataList/drugsBag', { "idx": idx, "sum": 10, "drugsBag": { "searchType": type, "searchKey": searchKey, "launch": launch } }, { headers: this.headers });
195
+  }
196
+  //药房端打印二维码的接口
197
+  printRequisition(idArr) {
198
+    return this.http.post(host.host + '/drugsBag/printRequisition', idArr, { headers: this.headers });
199
+  }
200
+  //药房端待打印变为待配药接口
201
+  changeToDispensing(idArr, name) {
202
+    return this.http.post(host.host + '/drugsBag/changeToDispensing/' + name, idArr, { headers: this.headers });
203
+  }
204
+  //新建工单->获取新建类型
205
+  getAutoWorkTypes(hosId) {
206
+    return this.http.get(host.host + '/ser/getAutoWorkTypes/' + hosId, { headers: this.headers });
207
+  }
208
+  //服务台新建工单—调度台建单获取起点科室或者终点科室列表
209
+  getdeptList(taskTypeId) {
210
+    return this.http.post(host.host + '/ser/getdeptList', { taskTypeId }, { headers: this.headers });
211
+  }
212
+  //服务台新建工单—调度台建单获取患者
213
+  getPatientList(data) {
214
+    return this.http.post(host.host + '/ser/getPatientInfo', data, { headers: this.headers });
215
+  }
216
+  //服务台新建工单—调度台建单获取起点科室或者终点科室列表
217
+  buildOrder(data) {
218
+    return this.http.post(host.host + '/ser/buildOrder', data, { headers: this.headers });
219
+  }
220
+  //获取当前用户信息
221
+  getCurrentUser1() {
222
+    return this.http.get(host.host + '/user/data/getCurrentUser', { headers: this.headers });
223
+  }
224
+  //获取通话记录音频地址
225
+  getCallLogPath(data) {
226
+    return this.http.post(host.host + '/callLog/getRecordByPath', data, { headers: this.headers });
227
+  }
228
+  //根据工作分配和人员id获取科室信息
229
+  getDeptByUser(data) {
230
+    return this.http.post(host.host + '/api/getDeptByUser', data, { headers: this.headers });
231
+  }
232
+  //根据工作分配和分组id获取科室信息
233
+  getDeptByGroup(data) {
234
+    return this.http.post(host.host + '/api/getDeptByGroup', data, { headers: this.headers });
235
+  }
236
+  //微信配置修改
237
+  changeWechatConfig(data) {
238
+    return this.http.post(host.host + '/simple/data/addData/wechatConfig', data, { headers: this.headers });
239
+  }
240
+  //系统配置修改
241
+  changeSysConfig(data) {
242
+    return this.http.post(host.host + '/simple/data/addListData/systemConfiguration', data, { headers: this.headers });
243
+  }
244
+  //护士端关注接口
245
+  changeFollow(data) {
246
+    return this.http.post(host.host + '/nurse/updData/patient', data, { headers: this.headers });
247
+  }
248
+  //数据字典楼栋保存接口
249
+  saveBuildingList(data) {
250
+    return this.http.post(host.host + '/simple/data/addListData/building', data, { headers: this.headers });
251
+  }
252
+  //数据字典楼栋删除接口
253
+  delBuildingList(data) {
254
+    return this.http.post(host.host + '/simple/data/rmvData/building', data, { headers: this.headers });
255
+  }
256
+  //数据字典楼层保存接口
257
+  saveFloorList(data) {
258
+    return this.http.post(host.host + '/simple/data/addListData/floor', data, { headers: this.headers });
259
+  }
260
+  //数据字典楼层保存接口
261
+  delFloorList(data) {
262
+    return this.http.post(host.host + '/simple/data/rmvData/floor', data, { headers: this.headers });
263
+  }
264
+  //获取患者最近一条检查信息
265
+  getRecentInfo(data) {
266
+    return this.http.post(host.host + '/nurse/workOrder/findInspectRecently', data, { headers: this.headers });
267
+  }
268
+  //simple增删改查,addData新增
269
+  simplePost(coop, type, data): any {
270
+    return this.http.post(host.host + '/simple/data/' + coop + '/' + type, data, { headers: this.headers });
271
+  }
272
+  //任务类型列表排序
273
+  sortTaskType(data): any {
274
+    return this.http.post(host.host + '/configuration/setOrders', data, { headers: this.headers });
275
+  }
276
+  //获取工单详情里的历史记录
277
+  getWorkOrderRecord(data): any {
278
+    return this.http.post(host.host + '/workerOrder/getWorkOrderRecord', data, { headers: this.headers });
279
+  }
280
+  //刷新字典缓存
281
+  refreshDic(): any {
282
+    return this.http.post(host.host + '/common/common/refreshCache', {}, { headers: this.headers });
283
+  }
284
+  //调度台建单获取可搜索的任务类型列表
285
+  getTaskTypeBySearchKey(data): any {
286
+    return this.http.post(host.host + '/ser/getTaskTypeBySearchKey', data, { headers: this.headers });
287
+  }
288
+  //切换院区
289
+  changeHospital(data): any {
290
+    return this.http.post(host.host + '/auth/changeHospital', data, { headers: this.headers });
291
+  }
292
+  //刷新缓存
293
+  refreshTaskType(): any {
294
+    return this.http.get(host.host + '/ser/refreshTaskType', { headers: this.headers });
295
+  }
296
+  //楼栋配置保存接口
297
+  saveBuildings(data) {
298
+    return this.http.post(host.host + '/simple/data/addListData/workOrderGradeBuilding', data, { headers: this.headers });
299
+  }
300
+  //删除接口
301
+  delBuildings(data) {
302
+    return this.http.post(host.host + '/simple/data/rmvData/workOrderGradeBuilding', data, { headers: this.headers });
303
+  }
304
+  //获取配置文件的接口
305
+  systemConfiguration(data) {
306
+    return this.http.post(host.host + '/simple/data/fetchDataList/systemConfiguration', data, { headers: this.headers });
307
+  }
308
+  //检查信息,患者信息
309
+  listMsgByMain(type,data) {
310
+    return this.http.post(host.host + '/nurse/'+type, data, { headers: this.headers });
311
+  }
312
+  //院区系统配置修改
313
+  changeHospitalSysConfig(data) {
314
+    return this.http.post(host.host + '/simple/data/addListData/hospitalConfig', data, { headers: this.headers });
315
+  }
316
+}

+ 20 - 0
src/app/services/my-service.service.ts

@@ -0,0 +1,20 @@
1
+import { Injectable } from '@angular/core';
2
+import { Subject, Observable } from 'rxjs';
3
+
4
+@Injectable({
5
+  providedIn: 'root'
6
+})
7
+export class MyServiceService {
8
+  public constructor() { }
9
+
10
+  private subject = new Subject<any>();
11
+  sendMsg(data) {
12
+    let that = this;
13
+    setTimeout(() => {
14
+      that.subject.next(data);
15
+    }, 1);
16
+  }
17
+  getMsg(): Observable<any> {
18
+    return this.subject.asObservable();
19
+  }
20
+}

+ 21 - 0
src/app/services/tool.service.ts

@@ -0,0 +1,21 @@
1
+import { Injectable } from '@angular/core';
2
+
3
+@Injectable({
4
+  providedIn: 'root'
5
+})
6
+export class ToolService {
7
+
8
+  constructor() { }
9
+  // 获取权限中的院区
10
+  getHospitalList() {
11
+    return JSON.parse(localStorage.getItem('user')).infoPermission.hospitals || [];
12
+  }
13
+  // 获取权限中的分组
14
+  getGroupList() {
15
+    return JSON.parse(localStorage.getItem('user')).infoPermission.groups || [];
16
+  }
17
+  // 获取当前院区
18
+  getCurrentHospital() {
19
+    return JSON.parse(localStorage.getItem('user')).user.currentHospital ? JSON.parse(localStorage.getItem('user')).user.currentHospital : JSON.parse(localStorage.getItem('user')).infoPermission.hospitals[0];
20
+  }
21
+}

+ 61 - 0
src/app/services/websocket-phone.service.ts

@@ -0,0 +1,61 @@
1
+import { Injectable } from '@angular/core';
2
+import { Subject, Observable, from } from 'rxjs';
3
+
4
+@Injectable({
5
+  providedIn: 'root'
6
+})
7
+export class WebsocketPhoneService {
8
+
9
+  constructor() { }
10
+
11
+
12
+  ws: WebSocket;//定义websocket
13
+  private subject;
14
+  flag = 1;//是否自动重连,1,正常,2,关闭,3,重连
15
+  // 连接websocket
16
+  connectWs(url, data): Observable<any> {
17
+    var postData = data;
18
+    if (this.ws != null) { this.ws.close() };
19
+    if (this.subject) { this.subject = null };
20
+    this.ws = new WebSocket(url);
21
+    this.subject = new Subject<any>();
22
+    let that = this;
23
+    this.ws.onopen = function (event) {
24
+      //socket 开启后执行,可以向后端传递信息
25
+      var sendData = JSON.stringify(postData)
26
+      that.ws.send(sendData);
27
+      console.log('open')
28
+    }
29
+    this.ws.onmessage = function (event) {
30
+      //socket 获取后端传递到前端的信息
31
+      console.log('onmessage')
32
+      if (event.data && event.data.length > 1) {
33
+        that.subject.next(JSON.parse(event.data));
34
+      }
35
+    }
36
+
37
+    this.ws.onerror = function (event) {
38
+      //socket error信息
39
+      console.log('error')
40
+
41
+    }
42
+    this.ws.onclose = function (event) {
43
+      //socket 关闭后执行
44
+      console.log('close')
45
+      console.log('websocket 断开: ' + event.code + ' ' + event.reason + ' ' + event.wasClean)
46
+      if(event.wasClean){
47
+        that.flag = 2;
48
+      }else{
49
+        that.flag = 3;
50
+      }
51
+    }
52
+
53
+    return that.subject.asObservable();
54
+  }
55
+
56
+  // 断开websocket,true关闭,false,断线重连
57
+  closeWs() {
58
+    this.ws.close()
59
+  }
60
+}
61
+

+ 56 - 0
src/app/services/websocket.service.ts

@@ -0,0 +1,56 @@
1
+import { Injectable } from '@angular/core';
2
+import { Subject, Observable } from 'rxjs';
3
+
4
+@Injectable({
5
+  providedIn: 'root'
6
+})
7
+export class WebsocketService {
8
+
9
+  constructor() { }
10
+  ws: WebSocket;//定义websocket
11
+  private subject;
12
+  // 连接websocket
13
+  connectWs(url, data): Observable<any> {
14
+    var postData = data;
15
+    if (this.ws != null) { this.ws.close() };
16
+    if (this.subject) { this.subject = null };
17
+    this.ws = new WebSocket(url);
18
+    this.subject = new Subject<any>();
19
+    let that = this;
20
+    this.ws.onopen = function (event) {
21
+      //socket 开启后执行,可以向后端传递信息
22
+      var sendData = JSON.stringify(postData)
23
+      that.ws.send(sendData);
24
+      console.log('open')
25
+    }
26
+    this.ws.onmessage = function (event) {
27
+      //socket 获取后端传递到前端的信息
28
+      console.log('onmessage')
29
+      if (event.data && event.data.length > 1) {
30
+        that.subject.next(JSON.parse(event.data));
31
+      }
32
+    }
33
+
34
+    this.ws.onerror = function (event) {
35
+      //socket error信息
36
+      console.log('error')
37
+
38
+    }
39
+    this.ws.onclose = function (event) {
40
+      //socket 关闭后执行
41
+      console.log('close')
42
+    }
43
+
44
+    return that.subject.asObservable();
45
+  }
46
+
47
+  // 断开websocket
48
+  closeWs() {
49
+    this.ws.close()
50
+  }
51
+
52
+
53
+
54
+
55
+
56
+}

+ 59 - 0
src/app/share/allocation-worker/allocation-worker.component.html

@@ -0,0 +1,59 @@
1
+<div class="detail">
2
+  <div class="title">分配支助人员<i class="icon_transport transport-guanbi" (click)="close()"></i></div>
3
+  <div class="content">
4
+    <div nz-row class="select">
5
+      <div nz-col nzSpan="6">
6
+        <div class="label">人员姓名:</div>
7
+        <input nz-input placeholder="请输入人员姓名" [(ngModel)]="searchName" nzSize="default" (ngModelChange)="searchInp()" />
8
+      </div>
9
+      <div nz-col nzSpan="6" class="ml8">
10
+        <div class="label">人员分组:</div>
11
+        <nz-select style="width: 220px;" [nzDropdownMatchSelectWidth]="false" [(ngModel)]="checkedGroup"
12
+          (ngModelChange)="searchInp()" nzPlaceHolder="请选择人员分组">
13
+          <nz-option *ngFor="let optionData of groupList" [nzLabel]="optionData.groupName" [nzValue]="optionData.id">
14
+          </nz-option>
15
+        </nz-select>
16
+      </div>
17
+    </div>
18
+    <div class="table">
19
+      <div class="box">
20
+        <nz-table class="allotWorkerTable" [nzShowPagination]="false" #rowSelectionTable [nzData]="workerList"
21
+          nzSize="small" [nzScroll]="{ y: '270px' }" [nzLoading]="loading1">
22
+          <thead>
23
+            <tr class="thead">
24
+              <th nzWidth="30px" style="text-align: center"></th>
25
+              <th nzWidth="60px" style="text-align: center">姓名</th>
26
+              <th nzWidth="140px" style="text-align: center">工作情况</th>
27
+              <th nzWidth="200px" style="text-align: center">最后地址以及目标地址</th>
28
+            </tr>
29
+          </thead>
30
+          <tbody>
31
+            <tr *ngFor="let data of rowSelectionTable.data" (click)="checkAllotWorker(data.id,true)">
32
+              <td nzShowCheckbox [(nzChecked)]="mapOfCheckedId[data.id]" (nzCheckedChange)="checkAllotWorker(data.id)">
33
+              </td>
34
+              <td nzAlign="center">{{ data.name }}</td>
35
+              <td nzAlign="center">{{ data.freetime }}</td>
36
+              <td nzAlign="center">{{ data.palce||'-' }}</td>
37
+            </tr>
38
+          </tbody>
39
+        </nz-table>
40
+        <div class="pagination">
41
+          <nz-pagination [(nzPageIndex)]="pageIndex" [(nzTotal)]="listLength" nzShowSizeChanger
42
+            [(nzPageSize)]="pageSize" (nzPageIndexChange)="getWorkerList()" (nzPageSizeChange)="getWorkerList()">
43
+          </nz-pagination>
44
+        </div>
45
+      </div>
46
+    </div>
47
+  </div>
48
+  <div class="btns display_flex justify-content_flex-center">
49
+    <button nz-button nzType="primary" [nzLoading]="btnLoading" (click)="submit()" *ngIf="mapOfCheckedId[worderId]">确认</button>
50
+    <button class=" btn cancel" nz-button nzType="default" (click)="close()">取消</button>
51
+  </div>
52
+</div>
53
+
54
+
55
+<!-- 操作成功/失败提示框 -->
56
+<app-prompt-modal *ngIf="promptModalShow" [content]="promptContent" [success]="ifSuccess" [show]="promptModalShow"
57
+  [info]="promptInfo" (closeModel)="close()">
58
+  <!-- 2.父组件调用子组件时绑定到这个事件属性,并在事件发生时作出回应。(closeModel)="close()" -->
59
+</app-prompt-modal>

+ 110 - 0
src/app/share/allocation-worker/allocation-worker.component.less

@@ -0,0 +1,110 @@
1
+@import "../../../../src/theme.less";
2
+:host {
3
+  width: 100%;
4
+  height: 100%;
5
+  position: fixed;
6
+  left: 0;
7
+  top: 0;
8
+  background: rgba(0, 0, 0, 0.4);
9
+  z-index: 999;
10
+
11
+  display: flex;
12
+  justify-content: center;
13
+  align-items: center;
14
+}
15
+
16
+.detail {
17
+  width: 1000px;
18
+  min-height: 580px;
19
+  border-radius: 5px;
20
+  background: #fff;
21
+  color: #333;
22
+  font-size: 14px;
23
+  padding: 12px 20px;
24
+  padding-bottom: 70px;
25
+  position: relative;
26
+
27
+  .title {
28
+    font-size: 18px;
29
+    text-align: center;
30
+    line-height: 24px;
31
+    margin: 0;
32
+    margin-bottom: 12px;
33
+    position: relative;
34
+
35
+    i {
36
+      position: absolute;
37
+      right: 0;
38
+      top: 0;
39
+      font-size: 20px;
40
+      color: #666;
41
+      cursor: pointer;
42
+      padding: 0 5px;
43
+    }
44
+  }
45
+
46
+  .content {
47
+    width: 960px;
48
+    overflow: hidden;
49
+
50
+    .select {
51
+      width: 100%;
52
+      background: #f9fafb;
53
+      border: 1px solid #e5e9ed;
54
+      border-radius: 5px;
55
+      padding: 13px 20px;
56
+
57
+      .label {
58
+        margin-bottom: 8px;
59
+      }
60
+    }
61
+
62
+    .table {
63
+      width: 100%;
64
+      margin-top: 15px;
65
+
66
+      .thead {
67
+        background-image: repeating-linear-gradient(
68
+          to right,
69
+          @bg-start,
70
+          @bg-end 100%
71
+        ) !important;
72
+
73
+        th {
74
+          color: #fff !important;
75
+          text-align: center;
76
+          font-size: 12px;
77
+          border: none;
78
+        }
79
+      }
80
+
81
+      .box {
82
+        min-height: 380px;
83
+        border-radius: 5px;
84
+        background: #f9fafb;
85
+        border: 1px solid #e5e9ed;
86
+        padding-bottom: 60px;
87
+        position: relative;
88
+
89
+        .pagination {
90
+          margin-top: 14px;
91
+          position: absolute;
92
+          bottom: 12px;
93
+          right: 5px;
94
+        }
95
+      }
96
+    }
97
+  }
98
+
99
+  .btns {
100
+    width: 100%;
101
+    position: absolute;
102
+    left: 0;
103
+    bottom: 20px;
104
+
105
+    button {
106
+      margin: 9px;
107
+      margin-bottom: 0;
108
+    }
109
+  }
110
+}

+ 172 - 0
src/app/share/allocation-worker/allocation-worker.component.ts

@@ -0,0 +1,172 @@
1
+import { Component, OnInit, Output, EventEmitter } from "@angular/core";
2
+import { ActivatedRoute, Router } from "@angular/router";
3
+import { Location } from "@angular/common";
4
+import { MainService } from "../../services/main.service";
5
+
6
+@Component({
7
+  selector: "app-allocation-worker",
8
+  templateUrl: "./allocation-worker.component.html",
9
+  styleUrls: ["./allocation-worker.component.less"],
10
+})
11
+export class AllocationWorkerComponent implements OnInit {
12
+  constructor(
13
+    private route: ActivatedRoute,
14
+    private router: Router,
15
+    private location: Location,
16
+    private mainService: MainService
17
+  ) {}
18
+
19
+  ngOnInit() {
20
+    this.getWorkerList();
21
+    // this.getGroupList();
22
+  }
23
+  // 支助人员数据
24
+  workerList = [];
25
+
26
+  id; //工单id
27
+  stateId; //工单状态id
28
+  listOfDisplayData: any[] = [];
29
+  mapOfCheckedId: { [key: string]: boolean } = {};
30
+  searchName: string = ""; //搜索框内容
31
+  checkedGroup; //选中人员分组
32
+  pageIndex: number = 1; //表格当前页码
33
+  pageSize: number = 10; //表格每页展示条数
34
+  listLength: number = 10; //表格总数据量
35
+
36
+  promptContent: string; //操作提示框提示信息
37
+  ifSuccess: boolean; //操作成功/失败
38
+  promptInfo: string; //操作结果提示信息
39
+  promptModalShow: boolean; //是否展示提示框
40
+
41
+  btnLoading: boolean = false; //提交按钮loading状态
42
+
43
+  // 支助人员数据
44
+  groupList: Array<{ groupName: string; id: string }> = []; //分组下拉框
45
+  groupIds;
46
+  snum = 0;
47
+  loading1 = false;
48
+  getWorkerList(pageIndex?) {
49
+    let that = this;
50
+    that.id = that.route.snapshot.paramMap.get("id");
51
+    that.stateId = that.route.snapshot.paramMap.get("stateId");
52
+    this.pageIndex = pageIndex ? pageIndex : this.pageIndex;
53
+
54
+    let groupsId = [];
55
+    JSON.parse(localStorage.getItem("user")).infoPermission.groups.forEach(
56
+      (e) => {
57
+        groupsId.push(e.id);
58
+      }
59
+    );
60
+
61
+    let postData = {
62
+      idx: this.pageIndex - 1,
63
+      sum: that.pageSize,
64
+      // workOrderId: that.id,
65
+      groupId: that.checkedGroup ? that.checkedGroup : "",
66
+      groupIds: that.groupIds ? that.groupIds : "",
67
+      name: that.searchName,
68
+      hosId: this.route.snapshot.paramMap.get("hosId"),
69
+    };
70
+    this.snum++;
71
+    this.loading1 = true;
72
+    that.mainService
73
+      .getSerInfo("getOnlineWorker", postData)
74
+      .subscribe((data) => {
75
+        this.snum--;
76
+        if (this.snum == 0) {
77
+          this.loading1 = false;
78
+        }
79
+        console.log(data);
80
+        that.workerList = data.data;
81
+        that.listLength = data.totalNum;
82
+        if (data.groupIds) {
83
+          // 获取分组
84
+          that.groupIds = data.groupIds;
85
+          that.mainService
86
+            .coopData("group", "findGroup", { groupIds: data.groupIds })
87
+            .subscribe((res) => {
88
+              that.groupList = res.data;
89
+            });
90
+        } else {
91
+          that.groupList = [];
92
+        }
93
+      });
94
+  }
95
+
96
+  // 输入用户信息搜索节流阀
97
+  time: any;
98
+  searchInp() {
99
+    let that = this;
100
+    // clearTimeout(that.time);
101
+    // that.time = setTimeout(() => {
102
+    that.getWorkerList(1);
103
+    // }, 2000);
104
+  }
105
+
106
+  // 选择分配支助人员
107
+  worderId = 0; //支助人员id
108
+  checkAllotWorker(id, flag?): void {
109
+    this.mapOfCheckedId = { [id]: flag?!this.mapOfCheckedId[id]:this.mapOfCheckedId[id] };
110
+    this.worderId = id;
111
+  }
112
+
113
+  // 分配
114
+  submit() {
115
+    let that = this;
116
+    that.btnLoading = true;
117
+    let flag: any = that.route.snapshot.paramMap.get("flag");
118
+
119
+    let postData: any = {};
120
+    let flags = "";
121
+    if (that.id.includes("_")) {
122
+      flags = "batchExcuteWorkOrder";
123
+      let ids_types = that.id.split("-");
124
+      let stateIds = that.stateId.split("-");
125
+      postData.workOrders = [];
126
+      stateIds.forEach((item, i) => {
127
+        postData.workOrders.push({
128
+          id: ids_types[i].split("_")[0],
129
+          type: ids_types[i].split("_")[1],
130
+          worker: { id: that.worderId },
131
+          gdState: { id: item },
132
+        });
133
+      });
134
+    } else {
135
+      flags = flag == 1 ? "excuteWorkOrder/reassign" : "excuteWorkOrder/assign";
136
+      postData = {
137
+        workOrder: {
138
+          id: that.id,
139
+          worker: { id: that.worderId },
140
+          gdState: { id: that.stateId },
141
+        },
142
+      };
143
+    }
144
+    that.mainService.assignWorker(postData, flags).subscribe((data) => {
145
+      console.log(data);
146
+      // that.close();
147
+      that.btnLoading = false;
148
+      if (data.status == 200) {
149
+        that.showPromptModal("分配", true, "");
150
+      } else {
151
+        that.showPromptModal("分配", false, data.msg);
152
+      }
153
+    });
154
+  }
155
+
156
+  // 关闭弹框
157
+  close() {
158
+    // this.router.navigateByUrl('dispatchingDesk');
159
+    history.go(-1);
160
+  }
161
+
162
+  // 展示信息提示框(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)
163
+  showPromptModal(con, success, promptInfo?) {
164
+    this.promptModalShow = false;
165
+    this.promptContent = con;
166
+    this.ifSuccess = success;
167
+    this.promptInfo = promptInfo;
168
+    setTimeout(() => {
169
+      this.promptModalShow = true;
170
+    }, 100);
171
+  }
172
+}

+ 433 - 0
src/app/share/appraise-detail/appraise-detail.component.html

@@ -0,0 +1,433 @@
1
+<!-- 药品/静配 -->
2
+<div class="detail" *ngIf="!maskFlag">
3
+  <div class="title">差评查看<i class="icon_transport transport-guanbi" (click)="close()"></i></div>
4
+  <div class="box">
5
+    <div class="tab display_flex">
6
+      <div [ngClass]="{'item':true, 'flex_1':true, checked:tabType==1}" (click)="checkTab(1)">工单信息</div>
7
+      <div [ngClass]="{'item':true, 'flex_1':true, checked:tabType==2}" (click)="checkTab(2)">评价内容</div>
8
+      <div [ngClass]="{'item':true, 'flex_1':true, checked:tabType==3}" (click)="checkTab(3)">调解</div>
9
+    </div>
10
+    <!-- 其他类型工单信息 -->
11
+    <div *ngIf="(tabType==1)&&(orderInfo.workOrderObj.taskType.associationType.id==259)" class="content orders">
12
+      <div class="top">
13
+        <div class="num">
14
+          <span class="left">单号:{{orderInfo.workOrderObj.gdcode}}</span>
15
+          <span class="right">{{orderInfo.workOrderObj.gdState?orderInfo.workOrderObj.gdState.name:''}}</span>
16
+        </div>
17
+        <div class="info" nz-row>
18
+          <div nz-col nzSpan="6">工单日期:{{orderInfo.workOrderObj.startTime|date:'yyyy-MM-dd HH:mm'}}</div>
19
+          <div nz-col nzSpan="6">总耗时:{{orderInfo.workOrderObj.showTimeNum}}</div>
20
+          <div nz-col nzSpan="8">申请类型:{{orderInfo.workOrderObj.taskType?orderInfo.workOrderObj.taskType.taskName:''}}
21
+          </div>
22
+          <div nz-col nzSpan="4">支助人员信息:{{orderInfo.workOrderObj.worker?orderInfo.workOrderObj.worker.name:''}}</div>
23
+        </div>
24
+        <div class="info" nz-row>
25
+          <div nz-col nzSpan="6">
26
+            申请科室:{{orderInfo.workOrderObj.createDeptDTO?orderInfo.workOrderObj.createDeptDTO.dept:''}}
27
+          </div>
28
+          <div nz-col nzSpan="6">
29
+            目标科室:{{(orderInfo.workOrderObj.endDepts&&orderInfo.workOrderObj.endDepts[0])?orderInfo.workOrderObj.endDepts[0].dept:''}}
30
+          </div>
31
+          <div nz-col nzSpan="8" *ngIf="orderInfo.workOrderObj.urgentDetails">
32
+            加急状态:{{orderInfo.workOrderObj.urgentDetails.checkStatus.name}}</div>
33
+        </div>
34
+        <div class="info" nz-row *ngIf="orderInfo.workOrderObj.urgentDetails">
35
+          <div nz-col nzSpan="24" class="jiaji">加急原因:{{orderInfo.workOrderObj.urgentDetails.urgentReason}}</div>
36
+        </div>
37
+      </div>
38
+      <div class="center">
39
+        <div class="box">
40
+          <div class="steps" *ngFor="let step of logList">
41
+            <div class="step">
42
+              <div class="info">
43
+                <i
44
+                  [ngClass]="{'icon_transport':true, 'transport-icon_liucheng':true,'green':(step.record&&step.record[0]&&step.record[0].operationTime)}"></i>
45
+                <p>{{step.operationName}}</p>
46
+                <p>{{step.record?step.record.operationtime:''}}</p>
47
+                <p *ngIf="step.record&&step.record.length&&step.record[0].dept"><span
48
+                    *ngFor="let dept of step.record">{{dept.dept}},</span></p>
49
+                <p *ngIf="step.record&&step.record.length&&step.operationName!='申请'">耗时{{filterTime(step.record)}}</p>
50
+              </div>
51
+              <div class="line"></div>
52
+            </div>
53
+          </div>
54
+        </div>
55
+      </div>
56
+    </div>
57
+    <!-- 标本类型工单信息 -->
58
+    <div
59
+      *ngIf="tabType==1&&(orderInfo.workOrderObj.taskType.associationType.id==256||orderInfo.workOrderObj.taskType.associationType.id==380)"
60
+      class="content orders">
61
+      <div class="top">
62
+        <div class="num">
63
+          <span class="left">单号:{{orderInfo.workOrderObj.gdcode}}</span>
64
+          <span class="right">{{orderInfo.workOrderObj.gdState?orderInfo.workOrderObj.gdState.name:''}}</span>
65
+        </div>
66
+        <div class="info" nz-row>
67
+          <div nz-col nzSpan="6">工单日期:{{orderInfo.workOrderObj.startTime|date:'yyyy-MM-dd HH:mm'}}</div>
68
+          <div nz-col nzSpan="6">总耗时:{{orderInfo.workOrderObj.showTimeNum}}</div>
69
+          <div nz-col nzSpan="8">申请类型:{{orderInfo.workOrderObj.taskType?orderInfo.workOrderObj.taskType.taskName:''}}
70
+          </div>
71
+          <div nz-col nzSpan="4">支助人员信息:{{orderInfo.workOrderObj.worker?orderInfo.workOrderObj.worker.name:''}}</div>
72
+        </div>
73
+        <div class="info" nz-row>
74
+          <div nz-col nzSpan="6">
75
+            申请科室:{{orderInfo.workOrderObj.createDeptDTO?orderInfo.workOrderObj.createDeptDTO.dept:''}}
76
+          </div>
77
+          <div nz-col nzSpan="6">
78
+            目标科室:{{(orderInfo.workOrderObj.endDepts&&orderInfo.workOrderObj.endDepts[0])?orderInfo.workOrderObj.endDepts[0].dept:''}}
79
+          </div>
80
+          <div nz-col nzSpan="4">预计接收:{{orderInfo.workOrderObj.expectReceiveNum}}</div>
81
+          <div nz-col nzSpan="4">送达:{{orderInfo.workOrderObj.deliveryNum}}</div>
82
+          <div nz-col nzSpan="4">实际接收:{{orderInfo.workOrderObj.actualReceiveNum}}</div>
83
+        </div>
84
+        <div class="info" nz-row *ngIf="orderInfo.workOrderObj.urgentDetails">
85
+          <div nz-col nzSpan="8">
86
+            加急状态:{{orderInfo.workOrderObj.urgentDetails.checkStatus.name}}</div>
87
+          <div nz-col nzSpan="24" class="jiaji">加急原因:{{orderInfo.workOrderObj.urgentDetails.urgentReason}}</div>
88
+        </div>
89
+      </div>
90
+      <div class="center">
91
+        <div class="box">
92
+          <div class="steps" *ngFor="let step of logList">
93
+            <div class="step">
94
+              <div class="info">
95
+                <i
96
+                  [ngClass]="{'icon_transport':true, 'transport-icon_liucheng':true,'green':(step.record&&step.record[0]&&step.record[0].operationTime)}"></i>
97
+                <p>{{step.operationName}}</p>
98
+                <p>{{step.record?step.record.operationtime:''}}</p>
99
+                <p *ngIf="step.record&&step.record.length&&step.record[0].dept"><span
100
+                    *ngFor="let dept of step.record">{{dept.dept}},</span></p>
101
+                <p *ngIf="step.record&&step.record.length&&step.operationName!='申请'">耗时{{filterTime(step.record)}}</p>
102
+              </div>
103
+              <div class="line"></div>
104
+            </div>
105
+          </div>
106
+        </div>
107
+      </div>
108
+      <div class="bottom">
109
+        <div class="table">
110
+          <nz-table class="" [nzData]="orderInfo.workOrderObj.specimenSet" nzSize="small"
111
+            [nzScroll]="{ y: (orderInfo.workOrderObj.urgentDetails?'124px':'153px') }" [nzShowPagination]="null">
112
+            <thead>
113
+              <tr class="thead">
114
+                <th nzWidth="50px">序号</th>
115
+                <th nzWidth="95px">标本类型</th>
116
+                <th nzWidth="110px">标本编码</th>
117
+                <th nzWidth="88px">患者姓名</th>
118
+                <th nzWidth="50px">床号</th>
119
+                <th nzWidth="88px">目标科室</th>
120
+                <th nzWidth="75px">是否接收</th>
121
+                <th nzWidth="75px">是否送达</th>
122
+                <th nzWidth="123px">接收扫描时间</th>
123
+                <th nzWidth="123px">送达扫描时间</th>
124
+              </tr>
125
+            </thead>
126
+            <tbody *ngIf="orderInfo.workOrderObj.specimenSet">
127
+              <tr *ngFor="let data of orderInfo.workOrderObj.specimenSet;let i =index;">
128
+                <td>{{i+1}}</td>
129
+                <td>{{data.stype.name}}</td>
130
+                <td>{{data.scode}}</td>
131
+                <td>{{data.patientName}}</td>
132
+                <td>{{data.bedNum}}</td>
133
+                <td>{{data.checkDept.dept}}</td>
134
+                <td>{{data.received?"是":"否"}}</td>
135
+                <td>{{data.arrived?"是":"否"}}</td>
136
+                <td>{{data.arriveTime|date:'yyyy-MM-dd HH:mm'}}</td>
137
+                <td>{{data.sendTime|date:'yyyy-MM-dd HH:mm'}}</td>
138
+              </tr>
139
+            </tbody>
140
+          </nz-table>
141
+        </div>
142
+      </div>
143
+    </div>
144
+    <!-- 药品/静配配送类型工单信息 -->
145
+    <div
146
+      *ngIf="tabType==1&&(orderInfo.workOrderObj.taskType.associationType.id==257||orderInfo.workOrderObj.taskType.associationType.id==258)"
147
+      class="content orders">
148
+      <div class="top">
149
+        <div class="num">
150
+          <span class="left">单号:{{orderInfo.workOrderObj.gdcode}}</span>
151
+          <span class="right">{{orderInfo.workOrderObj.gdState?orderInfo.workOrderObj.gdState.name:''}}</span>
152
+        </div>
153
+        <div class="info" nz-row>
154
+          <div nz-col nzSpan="6">工单日期:{{orderInfo.workOrderObj.startTime|date:'yyyy-MM-dd HH:mm'}}</div>
155
+          <div nz-col nzSpan="6">总耗时:{{orderInfo.workOrderObj.showTimeNum}}</div>
156
+          <div nz-col nzSpan="8">申请类型:{{orderInfo.workOrderObj.taskType?orderInfo.workOrderObj.taskType.taskName:''}}
157
+          </div>
158
+          <div nz-col nzSpan="4">支助人员信息:{{orderInfo.workOrderObj.worker?orderInfo.workOrderObj.worker.name:''}}</div>
159
+        </div>
160
+        <div class="info" nz-row>
161
+          <div nz-col nzSpan="6">
162
+            申请科室:{{orderInfo.workOrderObj.createDeptDTO?orderInfo.workOrderObj.createDeptDTO.dept:''}}
163
+          </div>
164
+          <div nz-col nzSpan="6">
165
+            目标科室:{{(orderInfo.workOrderObj.endDepts&&orderInfo.workOrderObj.endDepts[0])?orderInfo.workOrderObj.endDepts[0].dept:''}}
166
+          </div>
167
+          <div nz-col nzSpan="8" *ngIf="orderInfo.workOrderObj.urgentDetails">
168
+            加急状态:{{orderInfo.workOrderObj.urgentDetails.checkStatus.name}}</div>
169
+        </div>
170
+        <div class="info" nz-row *ngIf="orderInfo.workOrderObj.urgentDetails">
171
+          <div nz-col nzSpan="24" class="jiaji">加急原因:{{orderInfo.workOrderObj.urgentDetails.urgentReason}}</div>
172
+        </div>
173
+      </div>
174
+      <div class="center">
175
+        <div class="box">
176
+          <div class="steps" *ngFor="let step of logList">
177
+            <div class="step">
178
+              <div class="info">
179
+                <i
180
+                  [ngClass]="{'icon_transport':true, 'transport-icon_liucheng':true,'green':(step.record&&step.record[0]&&step.record[0].operationTime)}"></i>
181
+                <p>{{step.operationName}}</p>
182
+                <p>{{step.record?step.record.operationtime:''}}</p>
183
+                <p *ngIf="step.record&&step.record.length&&step.record[0].dept"><span
184
+                    *ngFor="let dept of step.record">{{dept.dept}},</span></p>
185
+                <p *ngIf="step.record&&step.record.length&&step.operationName!='申请'">耗时{{filterTime(step.record)}}</p>
186
+              </div>
187
+              <div class="line"></div>
188
+            </div>
189
+          </div>
190
+        </div>
191
+      </div>
192
+      <div class="bottom">
193
+        <div class="table">
194
+          <!-- 静配 -->
195
+          <nz-table *ngIf="orderInfo.workOrderObj.staticDistri" class="detailDrugTable"
196
+            [nzData]="orderInfo.workOrderObj.staticDistri.jpdetailsFormat" nzSize="small" [nzScroll]="{ y: '125px' }"
197
+            [nzShowPagination]="null">
198
+            <thead>
199
+              <tr class="thead">
200
+                <th nzWidth="15%">患者信息</th>
201
+                <th nzWidth="30%">药品</th>
202
+                <th nzWidth="5%">数量</th>
203
+                <th nzWidth="15%">患者信息</th>
204
+                <th nzWidth="30%">药品</th>
205
+                <th nzWidth="5%">数量</th>
206
+              </tr>
207
+            </thead>
208
+            <tbody *ngIf="orderInfo.workOrderObj.staticDistri">
209
+              <tr *ngFor="let data of orderInfo.workOrderObj.staticDistri.jpdetailsFormat">
210
+                <td>{{data[0].bedNum}}床:{{data[0].patientInfo}}</td>
211
+                <td>{{data[0].jpInfo}}</td>
212
+                <td>{{data[0].jpNum}}</td>
213
+                <td>{{data[1]?data[1].bedNum+"床:"+data[1].patientInfo:''}}</td>
214
+                <td>{{data[1]?data[1].jpInfo:''}}</td>
215
+                <td>{{data[1]?data[1].jpNum:''}}</td>
216
+              </tr>
217
+            </tbody>
218
+          </nz-table>
219
+          <!-- 药品 -->
220
+          <nz-table *ngIf="orderInfo.workOrderObj.drugs" class="detailDrugTable"
221
+            [nzData]="orderInfo.workOrderObj.drugs.drugsFormat" nzSize="small" [nzScroll]="{ y: '125px' }"
222
+            [nzShowPagination]="null">
223
+            <thead>
224
+              <tr class="thead">
225
+                <th nzWidth="15%">患者信息</th>
226
+                <th nzWidth="30%">药品</th>
227
+                <th nzWidth="5%">数量</th>
228
+                <th nzWidth="15%">患者信息</th>
229
+                <th nzWidth="30%">药品</th>
230
+                <th nzWidth="5%">数量</th>
231
+              </tr>
232
+            </thead>
233
+            <tbody *ngIf="orderInfo.workOrderObj.drugs">
234
+              <tr *ngFor="let data of orderInfo.workOrderObj.drugs.drugsFormat">
235
+                <td>{{data[0].bedNum}}床:{{data[0].patientInfo}}</td>
236
+                <td>{{data[0].drugsInfo}}</td>
237
+                <td>{{data[0].drugsNum}}</td>
238
+                <td>{{data[1]?data[1].bedNum+"床:"+data[1].patientInfo:''}}</td>
239
+                <td>{{data[1]?data[1].drugsInfo:''}}</td>
240
+                <td>{{data[1]?data[1].drugsNum:''}}</td>
241
+              </tr>
242
+            </tbody>
243
+          </nz-table>
244
+        </div>
245
+      </div>
246
+    </div>
247
+    <!-- 患者陪检/患者转运类型工单信息 -->
248
+    <div
249
+      *ngIf="tabType==1&&(orderInfo.workOrderObj.taskType.associationType.id==260||orderInfo.workOrderObj.taskType.associationType.id==255)"
250
+      class="content orders">
251
+      <div class="top">
252
+        <div class="num">
253
+          <span class="left">单号:{{orderInfo.workOrderObj.gdcode}}</span>
254
+          <span class="right">{{orderInfo.workOrderObj.gdState?orderInfo.workOrderObj.gdState.name:''}}</span>
255
+        </div>
256
+        <div class="info" nz-row>
257
+          <div nz-col nzSpan="6">工单日期:{{orderInfo.workOrderObj.startTime|date:'yyyy-MM-dd HH:mm'}}</div>
258
+          <div nz-col nzSpan="6">总耗时:{{orderInfo.workOrderObj.showTimeNum}}</div>
259
+          <div nz-col nzSpan="8">申请类型:{{orderInfo.workOrderObj.taskType?orderInfo.workOrderObj.taskType.taskName:''}}
260
+          </div>
261
+          <div nz-col nzSpan="4">支助人员信息:{{orderInfo.workOrderObj.worker?orderInfo.workOrderObj.worker.name:''}}</div>
262
+        </div>
263
+        <div class="info" nz-row>
264
+          <div nz-col nzSpan="6">
265
+            申请科室:{{orderInfo.workOrderObj.createDeptDTO?orderInfo.workOrderObj.createDeptDTO.dept:''}}
266
+          </div>
267
+          <div nz-col nzSpan="6">
268
+            目标科室:{{(orderInfo.workOrderObj.endDepts&&orderInfo.workOrderObj.endDepts[0])?orderInfo.workOrderObj.endDepts[0].dept:''}}
269
+          </div>
270
+          <div nz-col nzSpan="8" *ngIf="orderInfo.workOrderObj.urgentDetails">
271
+            加急状态:{{orderInfo.workOrderObj.urgentDetails.checkStatus.name}}</div>
272
+        </div>
273
+        <div class="info" nz-row *ngIf="orderInfo.workOrderObj.urgentDetails">
274
+          <div nz-col nzSpan="24" class="jiaji">加急原因:{{orderInfo.workOrderObj.urgentDetails.urgentReason}}</div>
275
+        </div>
276
+      </div>
277
+      <div class="center">
278
+        <div class="box">
279
+          <div class="steps" *ngFor="let step of logList">
280
+            <div class="step">
281
+              <div class="info">
282
+                <i
283
+                  [ngClass]="{'icon_transport':true, 'transport-icon_liucheng':true,'green':(step.record&&step.record[0]&&step.record[0].operationTime)}"></i>
284
+                <p>{{step.operationName}}</p>
285
+                <p>{{step.record?step.record.operationtime:''}}</p>
286
+                <p *ngIf="step.record&&step.record.length&&step.record[0].dept"><span
287
+                    *ngFor="let dept of step.record">{{dept.dept}},</span></p>
288
+                <p *ngIf="step.record&&step.record.length&&step.operationName!='申请'">耗时{{filterTime(step.record)}}</p>
289
+              </div>
290
+              <div class="line"></div>
291
+            </div>
292
+          </div>
293
+        </div>
294
+      </div>
295
+      <div class="bottom">
296
+        <div class="info">
297
+          <div nz-row class="top">
298
+            <div class="left" nz-col nzSpan="12">
299
+              <p>
300
+                <span class="label">患者姓名</span>
301
+                <span>{{orderInfo.workOrderObj.patient.patientName}}</span>
302
+              </p>
303
+              <p>
304
+                <span class="label">床位</span>
305
+                <span>{{orderInfo.workOrderObj.patient.bedNum}}</span>
306
+              </p>
307
+              <p *ngIf="orderInfo.workOrderObj.taskType.associationType.id==260">
308
+                <span class="label">检查项目</span>
309
+                <span>
310
+                  <span *ngFor="let item of orderInfo.workOrderObj.checkList;let i = index;">
311
+                    <span *ngIf="i!=orderInfo.workOrderObj.checkList.length-1">{{item.inspectName}},</span>
312
+                    <span *ngIf="i==orderInfo.workOrderObj.checkList.length-1">{{item.inspectName}}</span>
313
+                  </span>
314
+                </span>
315
+              </p>
316
+            </div>
317
+            <div class="right" nz-col nzSpan="12">
318
+              <p>
319
+                <span class="label">患者编码</span>
320
+                <span>{{orderInfo.workOrderObj.patient.patientCode}}</span>
321
+              </p>
322
+              <p>
323
+                <span class="label">携带物品</span>
324
+                <span>{{orderInfo.workOrderObj.goods}}</span>
325
+              </p>
326
+              <p *ngIf="orderInfo.workOrderObj.taskType.associationType.id==260">
327
+                <span class="label">预约时间</span>
328
+                <span>{{orderInfo.workOrderObj.yyTime?orderInfo.workOrderObj.yyTime:''}}</span>
329
+              </p>
330
+            </div>
331
+          </div>
332
+        </div>
333
+      </div>
334
+    </div>
335
+    <!-- 评价内容 -->
336
+    <div *ngIf="tabType==2" class="content pingjia">
337
+      <div class="msg">
338
+        <div>评价等级:{{orderInfo.evaluationDetails.serviceEvaluation.name}}</div>
339
+        <div>评价人:{{orderInfo.evaluationDetails.evalutationUser.name}}</div>
340
+      </div>
341
+      <div class="con">
342
+        意见内容:{{orderInfo.evaluationDetails.remark}}
343
+      </div>
344
+    </div>
345
+    <!-- 调解(未调解) -->
346
+    <div *ngIf="tabType==3&&orderInfo.handleStatus.id==286" class="content">
347
+      <div class="form">
348
+        <form nz-form [formGroup]="validateForm" class="addForm" (ngSubmit)="submitForm()">
349
+          <nz-form-item>
350
+            <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="reason">原因及事件过程</nz-form-label>
351
+            <nz-form-control nzErrorTip="请输入原因及事件过程!">
352
+              <nz-input-group>
353
+                <textarea rows="3" maxlength="500" nz-input type="reason" formControlName="reason"
354
+                  placeholder="请输入原因及事件过程"></textarea>
355
+              </nz-input-group>
356
+            </nz-form-control>
357
+          </nz-form-item>
358
+          <nz-form-item>
359
+            <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="process">调解过程</nz-form-label>
360
+            <nz-form-control nzErrorTip="请输入调解过程!">
361
+              <nz-input-group>
362
+                <textarea rows="3" maxlength="500" nz-input type="process" formControlName="process"
363
+                  placeholder="请输入调解过程"></textarea>
364
+              </nz-input-group>
365
+            </nz-form-control>
366
+          </nz-form-item>
367
+          <nz-form-item>
368
+            <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="handleType">解决方式</nz-form-label>
369
+            <nz-form-control nzErrorTip="请选择解决方式!">
370
+              <nz-select [nzDropdownMatchSelectWidth]="false" type="handleType" nzShowSearch nzAllowClear
371
+                formControlName="handleType" nzPlaceHolder="请选择解决方式">
372
+                <nz-option nzLabel="{{data.name}}" nzValue="{{data.id}}" *ngFor="let data of allHandleType">
373
+                </nz-option>
374
+              </nz-select>
375
+            </nz-form-control>
376
+          </nz-form-item>
377
+          <nz-form-item>
378
+            <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="improve">改进意见</nz-form-label>
379
+            <nz-form-control nzErrorTip="请输入改进意见!">
380
+              <nz-input-group>
381
+                <textarea rows="3" maxlength="500" nz-input type="improve" formControlName="improve"
382
+                  placeholder="请输入改进意见"></textarea>
383
+              </nz-input-group>
384
+            </nz-form-control>
385
+          </nz-form-item>
386
+        </form>
387
+      </div>
388
+    </div>
389
+    <!-- 调解(已调解) -->
390
+    <div *ngIf="tabType==3&&orderInfo.handleStatus.id==287" class="content">
391
+      <div class="mediation">
392
+        <div class="item">
393
+          <div class="label">原因及事件过程:</div>
394
+          <div class="info">{{orderInfo.reasonAndEventProcess}}</div>
395
+        </div>
396
+        <div class="item">
397
+          <div class="label">调解过程:</div>
398
+          <div class="info">{{orderInfo.mediationProcess}}</div>
399
+        </div>
400
+        <div class="item display_flex align-items_center justify-content_space-between">
401
+          <div class="block">
402
+            <div class="label">解决方式:</div>
403
+            <div class="info">{{orderInfo.handleType.name}}</div>
404
+          </div>
405
+          <div class="block">
406
+            <div class="label">调解人:</div>
407
+            <div class="info">{{orderInfo.mediationUser?orderInfo.mediationUser.name:''}}</div>
408
+          </div>
409
+          <div class="block">
410
+            <div class="label">调解时间:</div>
411
+            <div class="info">{{orderInfo.mediationTime?date(orderInfo.mediationTime):''}}</div>
412
+          </div>
413
+        </div>
414
+        <div class="item">
415
+          <div class="label">改进意见:</div>
416
+          <div class="info">{{orderInfo.advice}}</div>
417
+        </div>
418
+      </div>
419
+    </div>
420
+  </div>
421
+  <div class="btns">
422
+    <button *ngIf="tabType==3&&orderInfo.handleStatus.id==286" class="candelBtn btn" nz-button nzType="primary"
423
+      [nzLoading]="btnLoading" (click)="submitForm()">调解记录保存</button>
424
+    <button class="candelBtn btn cancel" nz-button nzType="default" (click)="close()">关闭</button>
425
+  </div>
426
+</div>
427
+<!-- 操作成功/失败提示框 -->
428
+<app-prompt-modal *ngIf="promptModalShow" [content]="promptContent" [success]="ifSuccess" [show]="promptModalShow"
429
+  [info]="promptInfo" (closeModel)="close()">
430
+  <!-- 2.父组件调用子组件时绑定到这个事件属性,并在事件发生时作出回应。(closeModel)="close()" -->
431
+</app-prompt-modal>
432
+<!-- 遮罩 -->
433
+<app-mask *ngIf="maskFlag"></app-mask>

+ 487 - 0
src/app/share/appraise-detail/appraise-detail.component.less

@@ -0,0 +1,487 @@
1
+@import "../../../../src/theme.less";
2
+
3
+:host {
4
+  width: 100%;
5
+  height: 100%;
6
+  position: fixed;
7
+  left: 0;
8
+  top: 0;
9
+  background: rgba(0, 0, 0, 0.4);
10
+  z-index: 99;
11
+
12
+  display: flex;
13
+  justify-content: center;
14
+  align-items: center;
15
+}
16
+
17
+.detail {
18
+  width: 1000px;
19
+  min-height: 580px;
20
+  border-radius: 5px;
21
+  background: #fff;
22
+  color: #333;
23
+  font-size: 14px;
24
+  padding: 12px 20px;
25
+  position: relative;
26
+  padding-bottom: 70px;
27
+
28
+  .title {
29
+    font-size: 18px;
30
+    text-align: center;
31
+    line-height: 24px;
32
+    margin: 0;
33
+    margin-bottom: 12px;
34
+    position: relative;
35
+
36
+    i {
37
+      position: absolute;
38
+      right: 0;
39
+      top: 0;
40
+      font-size: 20px;
41
+      color: #666;
42
+      cursor: pointer;
43
+      padding: 0 5px;
44
+    }
45
+  }
46
+
47
+  & > .box {
48
+    width: 960px;
49
+    border: 1px solid #e5e9ed;
50
+    border-radius: 5px;
51
+    overflow: hidden;
52
+
53
+    .tab {
54
+      width: 100%;
55
+      height: 60px;
56
+      border-bottom: 1px solid #e5e9ed;
57
+
58
+      .item {
59
+        text-align: center;
60
+        line-height: 60px;
61
+        height: 100%;
62
+        border-right: 1px solid #e5e9ed;
63
+
64
+        &:nth-last-child(1) {
65
+          border: none;
66
+        }
67
+
68
+        &.checked {
69
+          background: #f9fafb;
70
+        }
71
+      }
72
+    }
73
+
74
+    .content {
75
+      width: 100%;
76
+      min-height: 453px;
77
+      max-height: 500px;
78
+      overflow: hidden;
79
+      overflow-y: auto;
80
+
81
+      &.orders {
82
+        background: #f9fafb;
83
+      }
84
+
85
+      & > .top {
86
+        padding: 10px 32px;
87
+        border-bottom: 1px solid #e5e9ed;
88
+        overflow: hidden;
89
+        background: #fff;
90
+
91
+        .num {
92
+          font-size: 16px;
93
+          overflow: hidden;
94
+          margin-bottom: 6px;
95
+
96
+          .left {
97
+            float: left;
98
+            font-weight: 600;
99
+          }
100
+
101
+          .right {
102
+            float: right;
103
+          }
104
+        }
105
+
106
+        .info {
107
+          color: #666;
108
+
109
+          & > div {
110
+            margin: 4px 0;
111
+          }
112
+
113
+          .jiaji {
114
+            margin: 0;
115
+            margin-top: 8px;
116
+          }
117
+        }
118
+      }
119
+
120
+      & > .center {
121
+        padding: 27px 0 17px 0;
122
+        border-bottom: 1px solid #e5e9ed;
123
+        font-size: 12px;
124
+        background: #fff;
125
+
126
+        .box {
127
+          display: flex;
128
+          justify-content: center;
129
+
130
+          .steps {
131
+            &:nth-last-child(1) {
132
+              .line {
133
+                display: none !important;
134
+              }
135
+            }
136
+
137
+            .step {
138
+              .info {
139
+                width: 90px;
140
+                text-align: center;
141
+                display: inline-block;
142
+                vertical-align: top;
143
+
144
+                i {
145
+                  color: #e5e9ed;
146
+
147
+                  &.green {
148
+                    color: #bee1a7;
149
+                  }
150
+                }
151
+              }
152
+
153
+              p {
154
+                margin: 0;
155
+              }
156
+
157
+              .line {
158
+                display: inline-block;
159
+                width: 60px;
160
+                height: 2px;
161
+                background: #e5e9ed;
162
+              }
163
+            }
164
+          }
165
+        }
166
+      }
167
+
168
+      & > .bottom {
169
+        padding: 25px 32px;
170
+        background: #f9fafb;
171
+
172
+        .urgent {
173
+          input {
174
+            width: 600px;
175
+          }
176
+
177
+          .candelBtn {
178
+            margin-left: 20px;
179
+          }
180
+        }
181
+
182
+        .table {
183
+          width: 100%;
184
+          height: 100%;
185
+          min-height: 160px;
186
+          background: #fff;
187
+          border-radius: 5px;
188
+
189
+          .thead {
190
+            background-image: repeating-linear-gradient(
191
+              to right,
192
+              @bg-start,
193
+              @bg-end 100%
194
+            ) !important;
195
+            background-image: -ms-linear-gradient(
196
+              top,
197
+              @bg-start,
198
+              @bg-end
199
+            ) !important;
200
+
201
+            th {
202
+              color: #fff !important;
203
+              text-align: center;
204
+              font-size: 12px;
205
+              border: none;
206
+            }
207
+          }
208
+
209
+          .detailDrugTable {
210
+            .thead {
211
+              background-image: repeating-linear-gradient(
212
+                to right,
213
+                @bg-start,
214
+                @bg-end 50%
215
+              ) !important;
216
+            }
217
+          }
218
+
219
+          .ant-table-tbody {
220
+            tr {
221
+              text-align: center;
222
+              font-size: 12px;
223
+              border: none;
224
+
225
+              td {
226
+                border: none;
227
+              }
228
+            }
229
+
230
+            tr:nth-child(2n) {
231
+              background: #f9fafb;
232
+            }
233
+          }
234
+        }
235
+
236
+        .info {
237
+          width: 100%;
238
+          height: 100%;
239
+          background: #fff;
240
+          border-radius: 5px;
241
+          border: 1px solid #e5e9ed;
242
+          padding: 24px 28px 14px 28px;
243
+
244
+          .top {
245
+            // border-bottom: 1px solid #e5e9ed;
246
+            padding-bottom: 12px;
247
+
248
+            .left {
249
+              border-right: 1px dashed #e5e9ed;
250
+
251
+              p {
252
+                padding: 0 70px 0 102px;
253
+                overflow: hidden;
254
+
255
+                & > span:nth-child(1) {
256
+                  float: left;
257
+                }
258
+
259
+                & > span:nth-child(2) {
260
+                  float: right;
261
+                  color: #666;
262
+                  text-align: right;
263
+                  max-width: 175px;
264
+                }
265
+              }
266
+            }
267
+
268
+            .right {
269
+              p {
270
+                padding: 0 102px 0 70px;
271
+                overflow: hidden;
272
+
273
+                span:nth-child(1) {
274
+                  float: left;
275
+                }
276
+
277
+                span:nth-child(2) {
278
+                  float: right;
279
+                  color: #666;
280
+                  text-align: right;
281
+                }
282
+              }
283
+            }
284
+          }
285
+
286
+          .wait {
287
+            text-align: center;
288
+            margin-top: 7px;
289
+
290
+            i {
291
+              font-size: 24px;
292
+              color: #62c26d;
293
+            }
294
+
295
+            span {
296
+              color: #62c26d;
297
+            }
298
+          }
299
+        }
300
+      }
301
+
302
+      &.pingjia {
303
+        .msg {
304
+          width: 100%;
305
+          height: 50px;
306
+          line-height: 50px;
307
+          padding-left: 32px;
308
+          border-bottom: 1px solid #e5e9ed;
309
+
310
+          div {
311
+            display: inline-block;
312
+            margin-right: 100px;
313
+          }
314
+        }
315
+
316
+        .con {
317
+          padding: 16px 32px;
318
+          min-height: 360px;
319
+        }
320
+      }
321
+
322
+      & > .form {
323
+        .ant-form-item {
324
+          padding: 0 32px 13px 32px;
325
+          margin-bottom: 0;
326
+          border-bottom: 1px solid #e5e9ed;
327
+
328
+          &:nth-last-child(1) {
329
+            border: none;
330
+          }
331
+        }
332
+
333
+        .ant-form-item-label {
334
+          line-height: 34px;
335
+          text-align: left;
336
+        }
337
+      }
338
+
339
+      & > .mediation {
340
+        padding: 16px 32px;
341
+
342
+        .item {
343
+          border-bottom: 1px solid #e5e9ed;
344
+          padding-top: 10px;
345
+
346
+          .label {
347
+            line-height: 28px;
348
+            margin-top: 10px;
349
+          }
350
+
351
+          .info {
352
+            line-height: 28px;
353
+            color: #999;
354
+            padding-bottom: 20px;
355
+          }
356
+        }
357
+      }
358
+    }
359
+  }
360
+
361
+  .btns {
362
+    display: flex;
363
+    justify-content: center;
364
+    align-items: center;
365
+    width: 100%;
366
+    position: absolute;
367
+    left: 0;
368
+    bottom: 20px;
369
+
370
+    .btn {
371
+      margin: 9px;
372
+      margin-bottom: 0;
373
+    }
374
+  }
375
+
376
+  .ant-table {
377
+    border: none !important;
378
+  }
379
+}
380
+
381
+// 撤回工单
382
+.recallOrder {
383
+  position: fixed;
384
+  left: 0;
385
+  top: 0;
386
+  width: 100%;
387
+  height: 100%;
388
+
389
+  display: flex;
390
+  justify-content: center;
391
+  align-items: center;
392
+  background: rgba(0, 0, 0, 0.4);
393
+  z-index: 99;
394
+
395
+  .modalBody {
396
+    width: 350px;
397
+    height: 220px;
398
+    background: #fff;
399
+    border-radius: 5px;
400
+    padding: 10px 20px;
401
+    color: #333;
402
+
403
+    .title {
404
+      width: 100%;
405
+      text-align: center;
406
+      font-size: 18px;
407
+      position: relative;
408
+
409
+      i {
410
+        position: absolute;
411
+        right: 0;
412
+        top: 0;
413
+        font-size: 20px;
414
+        color: #666;
415
+        cursor: pointer;
416
+        padding: 0 5px;
417
+      }
418
+    }
419
+
420
+    .content {
421
+      width: 310px;
422
+      height: 117px;
423
+      background: #f9fafb;
424
+      border: 1px solid #e5e9ed;
425
+      border-radius: 5px;
426
+      overflow: hidden;
427
+      margin-top: 12px;
428
+
429
+      div {
430
+        text-align: center;
431
+        margin: 0;
432
+
433
+        &.icon {
434
+          margin-top: 17px;
435
+
436
+          i {
437
+            color: #ff3b53;
438
+            font-size: 30px !important;
439
+
440
+            &.transport-wenhao {
441
+              color: #f5a523;
442
+            }
443
+          }
444
+        }
445
+
446
+        &.defeat {
447
+          color: #333;
448
+          font-size: 18px;
449
+        }
450
+
451
+        &:nth-child(3) {
452
+          font-size: 14px;
453
+          color: #666;
454
+        }
455
+      }
456
+
457
+      .conditions {
458
+        padding: 16px 20px;
459
+
460
+        div {
461
+          text-align: left;
462
+        }
463
+      }
464
+    }
465
+
466
+    .btn {
467
+      display: flex;
468
+      justify-content: center;
469
+
470
+      button {
471
+        width: 120px;
472
+        height: 34px;
473
+        line-height: 34px;
474
+        margin-top: 10px;
475
+
476
+        &.btn {
477
+          width: 80px;
478
+          margin-left: 8px;
479
+        }
480
+      }
481
+    }
482
+  }
483
+}
484
+
485
+.txtC {
486
+  text-align: center;
487
+}

+ 205 - 0
src/app/share/appraise-detail/appraise-detail.component.ts

@@ -0,0 +1,205 @@
1
+import { Component, OnInit } from "@angular/core";
2
+import { ActivatedRoute } from "@angular/router";
3
+import { FormBuilder, Validators, FormGroup } from "@angular/forms";
4
+import { MainService } from "../../services/main.service";
5
+import { NzMessageService } from "ng-zorro-antd";
6
+import { forkJoin } from "rxjs";
7
+
8
+@Component({
9
+  selector: "app-appraise-detail",
10
+  templateUrl: "./appraise-detail.component.html",
11
+  styleUrls: ["./appraise-detail.component.less"],
12
+})
13
+export class AppraiseDetailComponent implements OnInit {
14
+  constructor(
15
+    private message: NzMessageService,
16
+    private fb: FormBuilder,
17
+    private route: ActivatedRoute,
18
+    private mainService: MainService
19
+  ) {}
20
+
21
+  id: number; //工单id
22
+  orderInfo; //工单详情信息
23
+  showCoop: boolean = true; //是否展示详情页操作按钮
24
+  loginUser: any = localStorage.getItem("user")
25
+    ? JSON.parse(localStorage.getItem("user")).user
26
+    : null; //登录人信息
27
+
28
+  promptContent: string; //操作提示框提示信息
29
+  ifSuccess: boolean; //操作成功/失败
30
+  promptInfo: string; //操作结果提示信息
31
+  promptModalShow: boolean; //是否展示提示框
32
+
33
+  urgentLoading: boolean = false; //确认加急按钮loading状态
34
+  recLoading: boolean = false; //撤回并删除按钮loading状态
35
+  btnLoading: boolean = false; //确认按钮loading状态
36
+
37
+  ngOnInit() {
38
+    this.getInfo();
39
+    this.initForm();
40
+  }
41
+
42
+  // 获取工单详情
43
+  maskFlag: any = false;
44
+  getInfo() {
45
+    this.id = +this.route.snapshot.paramMap.get("id");
46
+    if (this.route.snapshot.fragment == "tj") {
47
+      this.checkTab(3);
48
+    }
49
+    this.maskFlag = this.message.loading("正在加载中..", {
50
+      nzDuration: 0,
51
+    }).messageId;
52
+    this.mainService
53
+      .getFetchData("adviceCollection", "badEvaluationHandle", this.id)
54
+      .subscribe((data) => {
55
+        this.orderInfo = data.data;
56
+        let log$ = this.getLog();
57
+        let allHandleType$ = this.getAllHandleType();
58
+        forkJoin(log$, allHandleType$).subscribe((res) => {
59
+          this.message.remove(this.maskFlag);
60
+          this.maskFlag = false;
61
+          // getLog
62
+          this.logList = res[0]["data"];
63
+          // getAllHandleType
64
+          this.allHandleType = res[1];
65
+        });
66
+      });
67
+  }
68
+  // 切换tab栏
69
+  tabType: number = 1; //tab栏
70
+  checkTab(type) {
71
+    this.tabType = type;
72
+  }
73
+
74
+  // 关闭弹框
75
+  close() {
76
+    // this.router.navigateByUrl('dispatchingDesk');
77
+    history.go(-1);
78
+  }
79
+
80
+  // 获取工单历史记录
81
+  logList = []; //工单历史记录
82
+  getLog() {
83
+    return this.mainService.getWorkOrderLog(this.orderInfo["workOrderObj"].id);
84
+  }
85
+
86
+  // 获取所有院区
87
+  allHandleType: any = [];
88
+  getAllHandleType() {
89
+    return this.mainService.getDictionary("list", "bad_evaluation_handle_type");
90
+  }
91
+
92
+  // 初始化新增form表单
93
+  validateForm: FormGroup; //新增/编辑表单
94
+  initForm() {
95
+    this.validateForm = this.fb.group({
96
+      reason: [null, [Validators.required]],
97
+      process: [null, [Validators.required]],
98
+      handleType: [null, [Validators.required]],
99
+      improve: [null, [Validators.required]],
100
+    });
101
+  }
102
+
103
+  // 新增表单提交
104
+  submitForm(): void {
105
+    var that = this;
106
+    for (const i in that.validateForm.controls) {
107
+      that.validateForm.controls[i].markAsDirty();
108
+      that.validateForm.controls[i].updateValueAndValidity();
109
+    }
110
+    if (that.validateForm.invalid) return;
111
+    that.btnLoading = true;
112
+    let date = new Date();
113
+    // let time = date.getFullYear() + '-' + ((((date.getMonth() + 1) < 10) ? ('0' + (date.getMonth() + 1)) : (date.getMonth() + 1))) + '-' + ((((date.getDate()) < 10) ? ('0' + (date.getDate())) : (date.getDate())));
114
+    // time = time + ' ' + (date.getHours() < 10 ? ('0' + date.getHours()) : date.getHours()) + ':' + (date.getMinutes() < 10 ? ('0' + date.getMinutes()) : date.getMinutes()) + ':' + (date.getSeconds() < 10 ? ('0' + date.getSeconds()) : date.getSeconds());
115
+    let postData = {
116
+      badEvaluationHandle: {
117
+        id: that.id,
118
+        reasonAndEventProcess: that.validateForm.value.reason,
119
+        mediationProcess: that.validateForm.value.process,
120
+        handleType: { id: that.validateForm.value.handleType },
121
+        advice: that.validateForm.value.improve,
122
+        handleStatus: { key: "bad_evaluation_handle_status", value: "2" },
123
+        mediationUser: { id: that.loginUser.id },
124
+        mediationTime: date,
125
+      },
126
+    };
127
+
128
+    that.mainService
129
+      .postCustom("adviceCollection", "updData/badEvaluationHandle", postData)
130
+      .subscribe((data) => {
131
+        that.btnLoading = false;
132
+        if (data.status == 200) {
133
+          that.showPromptModal("调解", true, "");
134
+          that.getInfo();
135
+          // that.initForm();
136
+        } else {
137
+          that.showPromptModal("调解", false, data.msg);
138
+        }
139
+      });
140
+  }
141
+
142
+  // 展示信息提示框(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)
143
+  showPromptModal(con, success, promptInfo?) {
144
+    this.promptModalShow = false;
145
+    this.promptContent = con;
146
+    this.ifSuccess = success;
147
+    this.promptInfo = promptInfo;
148
+    setTimeout(() => {
149
+      this.promptModalShow = true;
150
+    }, 100);
151
+  }
152
+
153
+  // 格式化时分秒
154
+  // (时间小于一分钟则显示秒,时间大于一分钟则显示分钟数,如超出一小时则显示小时和分钟。)time单位:秒
155
+  formatTime(time) {
156
+    let timeStr = "";
157
+    if (time >= 0 && time < 60) {
158
+      // 秒
159
+      timeStr = time + "秒";
160
+    } else if (time >= 60 && time < 3600) {
161
+      // 分钟
162
+      timeStr = Math.floor(time / 60) + "分钟";
163
+    } else if (time >= 3600) {
164
+      // 时 + 分
165
+      let h = "";
166
+      let m = "";
167
+      h = Math.floor(time / 3600) + "小时";
168
+      m = time % 3600 >= 60 ? Math.floor((time % 3600) / 60) + "分钟" : "";
169
+      timeStr = h + m;
170
+    }
171
+    return timeStr;
172
+  }
173
+
174
+  // 计算历史记录耗时
175
+  filterTime(step) {
176
+    // step = [{ difTime: 2 }, { difTime: 6 }]
177
+    let num = 0;
178
+    step.forEach((e) => {
179
+      num += e.difTime;
180
+    });
181
+    return this.formatTime(num / 1000);
182
+  }
183
+
184
+  // 格式化时间戳
185
+  date(time) {
186
+    let date = new Date(time);
187
+    let timeStr =
188
+      date.getFullYear() +
189
+      "-" +
190
+      (date.getMonth() + 1 < 10
191
+        ? "0" + (date.getMonth() + 1)
192
+        : date.getMonth() + 1) +
193
+      "-" +
194
+      (date.getDate() < 10 ? "0" + date.getDate() : date.getDate());
195
+    timeStr =
196
+      timeStr +
197
+      " " +
198
+      (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) +
199
+      ":" +
200
+      (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) +
201
+      ":" +
202
+      (date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds());
203
+    return timeStr;
204
+  }
205
+}

+ 111 - 0
src/app/share/batch-orders/batch-orders.component.html

@@ -0,0 +1,111 @@
1
+<!-- 批量建单设置 -->
2
+<div class="detail">
3
+  <div class="title">
4
+    <div class="detail_btn">
5
+      <button nz-button nzType="primary" [disabled]="!checkedDepIds.length" (click)='showDelModals($event)'>批量删除</button>
6
+      <button class="ml8" nz-button nzType="primary" (click)="addModal()">新增</button>
7
+    </div>
8
+    <span>{{selectedBatchOrder.title}} - 批量建单设置</span>
9
+    <i class="icon_transport transport-guanbi" (click)="closeHandler()"></i>
10
+  </div>
11
+  <div class="box">
12
+    <nz-table class="hospitalTable" [nzData]="listOfData" nzSize="middle" [nzShowPagination]="false"
13
+      [nzLoading]="loading1">
14
+      <thead>
15
+        <tr class="thead">
16
+          <th nzWidth="5%" nzShowCheckbox [(nzChecked)]="isAllDisplayDataChecked" (nzCheckedChange)="checkAll($event)"></th>
17
+          <th nzWidth="5%">序号</th>
18
+          <th nzWidth="30%">发起科室</th>
19
+          <th nzWidth="30%">起点科室</th>
20
+          <th nzWidth="30%">终点科室</th>
21
+        </tr>
22
+      </thead>
23
+      <tbody>
24
+        <tr *ngFor="let data of listOfData;let index=index;">
25
+          <td nzShowCheckbox [(nzChecked)]="mapOfCheckedId[data.id]" (nzCheckedChange)="refreshStatus()"></td>
26
+          <td>{{index+(pageIndex-1)*10+1}}</td>
27
+          <td>{{data.createDept.dept}}</td>
28
+          <td>{{data.startDept.dept}}</td>
29
+          <td>{{data.endDept.dept}}</td>
30
+        </tr>
31
+      </tbody>
32
+    </nz-table>
33
+    <div class="pagination">
34
+      <nz-pagination [(nzPageIndex)]="pageIndex" [(nzTotal)]="listLength" nzShowSizeChanger [(nzPageSize)]="pageSize"
35
+        (nzPageIndexChange)="getList(pageIndex)"
36
+        (nzPageSizeChange)="getList(pageIndex)">
37
+      </nz-pagination>
38
+    </div>
39
+  </div>
40
+  <div class="btns">
41
+    <button class=" btn cancel" nz-button nzType="default" (click)="closeHandler()">关闭</button>
42
+  </div>
43
+</div>
44
+<!-- 批量建单设置 - 新增模态框 -->
45
+<div class="save display_flex justify-content_flex-center align-items_center add" *ngIf="modal">
46
+  <div class="modalBody">
47
+    <div class="title">新增批量建单设置<i class="icon_transport transport-guanbi" (click)="hideModal()"></i>
48
+    </div>
49
+    <div class="content">
50
+      <form nz-form [formGroup]="validateForm" class="addForm">
51
+        <nz-form-item>
52
+          <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="initiatingDepartment">发起科室</nz-form-label>
53
+          <nz-form-control nzErrorTip="请选择发起科室!">
54
+            <nz-select [nzDropdownMatchSelectWidth]="false" formControlName="initiatingDepartment" nzShowSearch
55
+              nzPlaceHolder="请选择发起科室" nzServerSearch (nzOnSearch)="changeInp($event,'initiating')"
56
+              (nzOpenChange)="changeFormDept($event)" (ngModelChange)="selectedDeptHandler($event,'initiating')">
57
+              <ng-container *ngFor="let data of initiatingDepartments">
58
+                <nz-option *ngIf="!isLoading" [nzLabel]="data.dept" [nzValue]="data._uid">
59
+                </nz-option>
60
+              </ng-container>
61
+              <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
62
+                <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
63
+              </nz-option>
64
+            </nz-select>
65
+          </nz-form-control>
66
+        </nz-form-item>
67
+        <nz-form-item>
68
+          <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="startDepartment">起点科室</nz-form-label>
69
+          <nz-form-control nzErrorTip="请选择起点科室!">
70
+            <nz-select [nzDropdownMatchSelectWidth]="false" formControlName="startDepartment" nzShowSearch
71
+              nzPlaceHolder="请选择起点科室" nzServerSearch (nzOnSearch)="changeInp($event,'start')"
72
+              (nzOpenChange)="changeFormDept($event)" (ngModelChange)="selectedDeptHandler($event,'start')"
73
+              [nzDisabled]="startDepartmentsDisabled">
74
+              <ng-container *ngFor="let data of startDepartments">
75
+                <nz-option *ngIf="!isLoading" [nzLabel]="data.dept" [nzValue]="data._uid">
76
+                </nz-option>
77
+              </ng-container>
78
+              <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
79
+                <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
80
+              </nz-option>
81
+            </nz-select>
82
+          </nz-form-control>
83
+        </nz-form-item>
84
+        <nz-form-item>
85
+          <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="endDepartment">终点科室</nz-form-label>
86
+          <nz-form-control nzErrorTip="请选择终点科室!">
87
+            <nz-select [nzDropdownMatchSelectWidth]="false" formControlName="endDepartment" nzShowSearch
88
+              nzPlaceHolder="请选择终点科室" nzServerSearch (nzOnSearch)="changeInp($event,'end')"
89
+              (nzOpenChange)="changeFormDept($event)" (ngModelChange)="selectedDeptHandler($event,'end')"
90
+              [nzDisabled]="endDepartmentsDisabled">
91
+              <ng-container *ngFor="let data of endDepartments">
92
+                <nz-option *ngIf="!isLoading" [nzLabel]="data.dept" [nzValue]="data._uid">
93
+                </nz-option>
94
+              </ng-container>
95
+              <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
96
+                <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
97
+              </nz-option>
98
+            </nz-select>
99
+          </nz-form-control>
100
+        </nz-form-item>
101
+      </form>
102
+    </div>
103
+    <div class="display_flex justify-content_flex-center">
104
+      <button nzType="primary" nz-button (click)="submitForm()" [nzLoading]="saveLoading">保存</button>
105
+      <button class="btn cancel" nz-button nzType="default" (click)="hideModal()">取消</button>
106
+    </div>
107
+  </div>
108
+</div>
109
+<!-- 删除模态框 -->
110
+<app-dialog-delete [delModal]="delModal" (hideDelModalEvent)="hideDelModal()" [btnLoading]="loading3"
111
+(confirmDelEvent)="confirmDel()" content="您确认要删除吗?"></app-dialog-delete>

+ 649 - 0
src/app/share/batch-orders/batch-orders.component.less

@@ -0,0 +1,649 @@
1
+@import "../../../../src/theme.less";
2
+:host {
3
+  width: 100%;
4
+  height: 100%;
5
+  position: fixed;
6
+  left: 0;
7
+  top: 0;
8
+  background: rgba(0, 0, 0, 0.4);
9
+  z-index: 99;
10
+  display: flex;
11
+  justify-content: center;
12
+  align-items: center;
13
+  .hospitalTable {
14
+    padding: 21px 12px;
15
+    padding-bottom: 0;
16
+
17
+    .thead {
18
+      background-image: linear-gradient(to right, @bg-start, @bg-end);
19
+
20
+      th {
21
+        background: transparent;
22
+        color: #fff;
23
+        text-align: center;
24
+        font-size: 14px;
25
+      }
26
+    }
27
+
28
+    .ant-table-body {
29
+      border-bottom: 1px solid #e5e9ed;
30
+    }
31
+
32
+    .ant-table-tbody {
33
+      tr {
34
+        text-align: center;
35
+        font-size: 14px;
36
+        border: none;
37
+        color: #333;
38
+
39
+        td {
40
+          border: none;
41
+
42
+          .coop {
43
+            span {
44
+              display: inline-block;
45
+              width: 60px;
46
+              cursor: pointer;
47
+
48
+              &::after {
49
+                content: "|";
50
+                float: right;
51
+              }
52
+
53
+              &:hover {
54
+                color: @primary-color;
55
+              }
56
+
57
+              &:active {
58
+                color: @primary-color;
59
+              }
60
+
61
+              &:nth-last-child(1) {
62
+                &::after {
63
+                  content: "";
64
+                }
65
+              }
66
+            }
67
+          }
68
+        }
69
+      }
70
+
71
+      tr:nth-child(2n-1) {
72
+        background: #f9fafb;
73
+      }
74
+    }
75
+  }
76
+  .pagination {
77
+    margin-top: 14px;
78
+    position: absolute;
79
+    right: 5px;
80
+  }
81
+  .detail {
82
+    width: 1000px;
83
+    max-height: 580px;
84
+    border-radius: 5px;
85
+    background: #fff;
86
+    color: #333;
87
+    font-size: 14px;
88
+    padding: 12px 20px;
89
+    position: relative;
90
+    padding-bottom: 70px;
91
+
92
+    .title {
93
+      font-size: 18px;
94
+      text-align: center;
95
+      line-height: 24px;
96
+      margin: 0;
97
+      margin-bottom: 12px;
98
+      position: relative;
99
+      .detail_btn {
100
+        position: absolute;
101
+        left: 8px;
102
+      }
103
+
104
+      i {
105
+        position: absolute;
106
+        right: 0;
107
+        top: 0;
108
+        font-size: 20px;
109
+        color: #666;
110
+        cursor: pointer;
111
+        padding: 0 5px;
112
+      }
113
+    }
114
+
115
+    & > .box {
116
+      width: 960px;
117
+      border: 1px solid #e5e9ed;
118
+      border-radius: 5px;
119
+      overflow: hidden;
120
+
121
+      .tab {
122
+        width: 100%;
123
+        height: 60px;
124
+        border-bottom: 1px solid #e5e9ed;
125
+
126
+        .item {
127
+          text-align: center;
128
+          line-height: 60px;
129
+          height: 100%;
130
+          border-right: 1px solid #e5e9ed;
131
+
132
+          &:nth-last-child(1) {
133
+            border: none;
134
+          }
135
+
136
+          &.checked {
137
+            background: #f9fafb;
138
+          }
139
+        }
140
+      }
141
+
142
+      .content {
143
+        width: 100%;
144
+        min-height: 453px;
145
+        max-height: 500px;
146
+
147
+        &.orders {
148
+          background: #f9fafb;
149
+        }
150
+
151
+        & > .top {
152
+          padding: 10px 32px;
153
+          border-bottom: 1px solid #e5e9ed;
154
+          overflow: hidden;
155
+          background: #fff;
156
+
157
+          .num {
158
+            font-size: 16px;
159
+            overflow: hidden;
160
+            margin-bottom: 6px;
161
+
162
+            .left {
163
+              float: left;
164
+              font-weight: 600;
165
+            }
166
+
167
+            .right {
168
+              float: right;
169
+            }
170
+          }
171
+
172
+          .info {
173
+            color: #666;
174
+
175
+            & > div {
176
+              margin: 4px 0;
177
+            }
178
+
179
+            .jiaji {
180
+              margin: 0;
181
+              margin-top: 8px;
182
+            }
183
+          }
184
+        }
185
+
186
+        & > .center {
187
+          padding: 27px 0 17px 0;
188
+          border-bottom: 1px solid #e5e9ed;
189
+          font-size: 12px;
190
+          background: #fff;
191
+
192
+          .box {
193
+            display: flex;
194
+            justify-content: center;
195
+
196
+            .steps {
197
+              &:nth-last-child(1) {
198
+                .line {
199
+                  display: none !important;
200
+                }
201
+              }
202
+
203
+              .step {
204
+                .info {
205
+                  width: 90px;
206
+                  text-align: center;
207
+                  display: inline-block;
208
+                  vertical-align: top;
209
+
210
+                  i {
211
+                    color: #e5e9ed;
212
+
213
+                    &.green {
214
+                      color: #bee1a7;
215
+                    }
216
+                  }
217
+                }
218
+
219
+                p {
220
+                  margin: 0;
221
+                }
222
+
223
+                .line {
224
+                  display: inline-block;
225
+                  width: 60px;
226
+                  height: 2px;
227
+                  background: #e5e9ed;
228
+                }
229
+              }
230
+            }
231
+          }
232
+        }
233
+
234
+        & > .bottom {
235
+          padding: 25px 32px;
236
+          background: #f9fafb;
237
+
238
+          .urgent {
239
+            input {
240
+              width: 600px;
241
+            }
242
+
243
+            .candelBtn {
244
+              margin-left: 20px;
245
+            }
246
+          }
247
+
248
+          .table {
249
+            width: 100%;
250
+            height: 100%;
251
+            min-height: 160px;
252
+            background: #fff;
253
+            border-radius: 5px;
254
+
255
+            .thead {
256
+              background-image: repeating-linear-gradient(
257
+                to right,
258
+                @bg-start,
259
+                @bg-end 100%
260
+              ) !important;
261
+
262
+              th {
263
+                color: #fff !important;
264
+                text-align: center;
265
+                font-size: 12px;
266
+                border: none;
267
+              }
268
+            }
269
+
270
+            .detailDrugTable {
271
+              .thead {
272
+                background-image: repeating-linear-gradient(
273
+                  to right,
274
+                  @bg-start,
275
+                  @bg-end 50%
276
+                ) !important;
277
+              }
278
+            }
279
+
280
+            .ant-table-tbody {
281
+              tr {
282
+                text-align: center;
283
+                font-size: 12px;
284
+                border: none;
285
+
286
+                td {
287
+                  border: none;
288
+                }
289
+              }
290
+
291
+              tr:nth-child(2n) {
292
+                background: #f9fafb;
293
+              }
294
+            }
295
+          }
296
+
297
+          .info {
298
+            width: 100%;
299
+            height: 100%;
300
+            background: #fff;
301
+            border-radius: 5px;
302
+            border: 1px solid #e5e9ed;
303
+            padding: 24px 28px 14px 28px;
304
+            margin-bottom: 8px;
305
+
306
+            .top {
307
+              .left {
308
+                border-right: 1px dashed #e5e9ed;
309
+
310
+                p {
311
+                  padding: 0 70px 0 102px;
312
+                  overflow: hidden;
313
+
314
+                  & > span:nth-child(1) {
315
+                    float: left;
316
+                  }
317
+
318
+                  & > span:nth-child(2) {
319
+                    float: right;
320
+                    color: #666;
321
+                    text-align: right;
322
+                    max-width: 175px;
323
+                  }
324
+                }
325
+              }
326
+
327
+              .right {
328
+                p {
329
+                  padding: 0 102px 0 70px;
330
+                  overflow: hidden;
331
+
332
+                  span:nth-child(1) {
333
+                    float: left;
334
+                  }
335
+
336
+                  span:nth-child(2) {
337
+                    float: right;
338
+                    color: #666;
339
+                    text-align: right;
340
+                  }
341
+                }
342
+              }
343
+            }
344
+
345
+            .wait {
346
+              text-align: center;
347
+              margin-top: 7px;
348
+
349
+              i {
350
+                font-size: 24px;
351
+                color: #62c26d;
352
+              }
353
+
354
+              span {
355
+                color: #62c26d;
356
+              }
357
+            }
358
+          }
359
+        }
360
+
361
+        &.pingjia {
362
+          .msg {
363
+            width: 100%;
364
+            height: 50px;
365
+            line-height: 50px;
366
+            padding-left: 32px;
367
+            border-bottom: 1px solid #e5e9ed;
368
+
369
+            div {
370
+              display: inline-block;
371
+              margin-right: 100px;
372
+            }
373
+          }
374
+
375
+          .con {
376
+            padding: 16px 32px;
377
+            min-height: 360px;
378
+          }
379
+        }
380
+
381
+        & > .form {
382
+          .ant-form-item {
383
+            padding: 0 32px 13px 32px;
384
+            margin-bottom: 0;
385
+            border-bottom: 1px solid #e5e9ed;
386
+
387
+            &:nth-last-child(1) {
388
+              border: none;
389
+            }
390
+          }
391
+
392
+          .ant-form-item-label {
393
+            line-height: 34px;
394
+            text-align: left;
395
+          }
396
+        }
397
+
398
+        & > .mediation {
399
+          padding: 16px 32px;
400
+
401
+          .item {
402
+            border-bottom: 1px solid #e5e9ed;
403
+            padding-top: 10px;
404
+
405
+            .label {
406
+              line-height: 28px;
407
+              margin-top: 10px;
408
+            }
409
+
410
+            .info {
411
+              line-height: 28px;
412
+              color: #999;
413
+              padding-bottom: 20px;
414
+            }
415
+          }
416
+        }
417
+
418
+        &.jifen {
419
+          padding: 32px;
420
+
421
+          & > .table {
422
+            width: 100%;
423
+            height: 100%;
424
+            min-height: 160px;
425
+            padding: 6px;
426
+            background: #fff;
427
+            border: 1px solid #e5e9ed;
428
+            border-radius: 5px;
429
+            overflow: hidden;
430
+
431
+            .thead {
432
+              background-image: repeating-linear-gradient(
433
+                to right,
434
+                @bg-start,
435
+                @bg-end 100%
436
+              ) !important;
437
+
438
+              th {
439
+                color: #fff !important;
440
+                text-align: center;
441
+                font-size: 12px;
442
+                border: none;
443
+                background: transparent;
444
+              }
445
+            }
446
+
447
+            .ant-table-tbody {
448
+              tr {
449
+                text-align: center;
450
+                font-size: 12px;
451
+                border: none;
452
+
453
+                td {
454
+                  border: none;
455
+                }
456
+              }
457
+
458
+              tr:nth-child(2n) {
459
+                background: #f9fafb;
460
+              }
461
+            }
462
+          }
463
+        }
464
+      }
465
+    }
466
+
467
+    .btns {
468
+      display: flex;
469
+      justify-content: center;
470
+      align-items: center;
471
+      width: 60%;
472
+      margin: 48px auto 0;
473
+
474
+      .btn {
475
+        margin: 9px;
476
+        margin-bottom: 0;
477
+      }
478
+    }
479
+
480
+    .ant-table {
481
+      border: none !important;
482
+    }
483
+  }
484
+}
485
+.save {
486
+  position: fixed;
487
+  left: 0;
488
+  top: 0;
489
+  width: 100%;
490
+  height: 100%;
491
+  background: rgba(0, 0, 0, 0.4);
492
+  z-index: 99;
493
+
494
+  .modalBody {
495
+    width: 350px;
496
+    height: 220px;
497
+    background: #fff;
498
+    border-radius: 5px;
499
+    padding: 10px 20px;
500
+    color: #333;
501
+
502
+    .title {
503
+      width: 100%;
504
+      text-align: center;
505
+      font-size: 18px;
506
+      position: relative;
507
+
508
+      i {
509
+        position: absolute;
510
+        right: 0;
511
+        top: 0;
512
+        font-size: 20px;
513
+        color: #666;
514
+        cursor: pointer;
515
+        padding: 0 5px;
516
+      }
517
+    }
518
+
519
+    .content {
520
+      width: 310px;
521
+      height: 117px;
522
+      background: #f9fafb;
523
+      border: 1px solid #e5e9ed;
524
+      border-radius: 5px;
525
+      overflow: hidden;
526
+      margin-top: 12px;
527
+
528
+      & > div {
529
+        text-align: center;
530
+        margin: 0;
531
+
532
+        &.icon {
533
+          margin-top: 17px;
534
+
535
+          i {
536
+            color: #34b349;
537
+            font-size: 30px !important;
538
+
539
+            &.transport-wenhao {
540
+              color: #f5a523;
541
+            }
542
+
543
+            &.transport-shibai {
544
+              color: #ff3a52;
545
+            }
546
+          }
547
+        }
548
+
549
+        &.defeat {
550
+          color: #333;
551
+          font-size: 18px;
552
+        }
553
+
554
+        &:nth-child(3) {
555
+          font-size: 14px;
556
+          color: #666;
557
+        }
558
+      }
559
+      .roundRobinTips {
560
+        font-size: 12px;
561
+      }
562
+    }
563
+
564
+    button {
565
+      margin-top: 10px;
566
+
567
+      &.btn {
568
+        margin-left: 8px;
569
+      }
570
+    }
571
+  }
572
+
573
+  // 新增
574
+  &.add {
575
+    .modalBody {
576
+      width: 480px;
577
+      height: auto;
578
+
579
+      .content {
580
+        width: 100%;
581
+        height: auto;
582
+        padding: 18px 14px 0 14px;
583
+        max-height: 497px;
584
+        overflow-y: auto;
585
+
586
+        .addForm {
587
+          .ant-form-item {
588
+            margin-bottom: 15px;
589
+
590
+            .ant-form-item-label {
591
+              line-height: 14px;
592
+              text-align: left;
593
+            }
594
+
595
+            .desc {
596
+              margin-top: 5px;
597
+            }
598
+          }
599
+
600
+          .datesControl {
601
+            margin-top: -16px;
602
+
603
+            .ant-form-item-label {
604
+              line-height: 40px;
605
+            }
606
+          }
607
+
608
+          .timer {
609
+            .ant-form-item-label {
610
+              width: 100%;
611
+              text-align: left;
612
+            }
613
+
614
+            .numInp {
615
+              margin-right: 5px;
616
+            }
617
+
618
+            .line {
619
+              margin-right: 5px;
620
+            }
621
+          }
622
+
623
+          .timer2 {
624
+            .ant-form-item-label {
625
+              line-height: 20px;
626
+            }
627
+          }
628
+        }
629
+
630
+        .editForm {
631
+          .ant-form-item {
632
+            margin-bottom: 15px;
633
+
634
+            .ant-form-item-label {
635
+              line-height: 14px;
636
+              text-align: left;
637
+            }
638
+          }
639
+        }
640
+      }
641
+
642
+      button {
643
+        &:nth-child(1) {
644
+          margin-right: 20px;
645
+        }
646
+      }
647
+    }
648
+  }
649
+}

+ 373 - 0
src/app/share/batch-orders/batch-orders.component.ts

@@ -0,0 +1,373 @@
1
+import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core";
2
+import { FormBuilder, FormGroup, Validators } from "@angular/forms";
3
+import { NzMessageService } from "ng-zorro-antd";
4
+import { MainService } from "src/app/services/main.service";
5
+import { ToolService } from "src/app/services/tool.service";
6
+
7
+@Component({
8
+  selector: "app-batch-orders",
9
+  templateUrl: "./batch-orders.component.html",
10
+  styleUrls: ["./batch-orders.component.less"],
11
+})
12
+export class BatchOrdersComponent implements OnInit {
13
+  @Input() selectedBatchOrder = null;
14
+  @Output() close = new EventEmitter();
15
+  hosId; //当前院区id
16
+  // 起点科室是默认发起科室,终点科室是固定科室
17
+  // 起点科室是固定科室,终点科室是默认发起科室
18
+  // 起点科室是默认发起科室,终点科室是默认发起科室
19
+  // 其他
20
+  type = 0;
21
+  modal = false; //新增的弹窗
22
+  validateForm: FormGroup; //新增
23
+  initiatingDepartments = []; //发起科室列表
24
+  startDepartments = []; //起点科室列表
25
+  startDepartmentsDisabled = false; //是否禁用起点科室
26
+  endDepartments = []; //终点科室列表
27
+  endDepartmentsDisabled = false; //是否禁用终点科室
28
+  isLoading = false; //科室下拉框搜索
29
+  keyword = ""; //当前输入的关键词
30
+  taskType = null; //当前任务类型
31
+  startCarryingCourses = null; //当前起点科室运输过程
32
+  endCarryingCourses = null; //当前终点科室运输过程
33
+  saveLoading = false; //保存的loading
34
+  constructor(
35
+    private fb: FormBuilder,
36
+    private mainService: MainService,
37
+    private tool: ToolService,
38
+    private message: NzMessageService,
39
+  ) {}
40
+  // 初始化表单
41
+  initForm() {
42
+    this.validateForm = this.fb.group({
43
+      initiatingDepartment: [null, [Validators.required]],
44
+      startDepartment: [null, [Validators.required]],
45
+      endDepartment: [null, [Validators.required]],
46
+    });
47
+  }
48
+  // 关闭批量建单设置弹窗
49
+  closeHandler() {
50
+    this.close.emit("false");
51
+  }
52
+  //新增-打开
53
+  addModal() {
54
+    this.modal = true;
55
+    this.initForm();
56
+  }
57
+  // 新增-关闭
58
+  hideModal() {
59
+    this.modal = false;
60
+  }
61
+  //获取科室列表
62
+  /**
63
+   *
64
+   * @param type 科室类型id
65
+   * @returns
66
+   */
67
+  getDeptList(obj: { e?: string; typeId?: string } = {}) {
68
+    let postData: any = {
69
+      department: { hospital: { id: this.hosId } },
70
+      idx: 0,
71
+      sum: 10,
72
+    };
73
+    if (obj.e) {
74
+      postData.department.dept = obj.e;
75
+    }
76
+    if (obj.typeId) {
77
+      postData.department.type = { id: obj.typeId };
78
+    }
79
+    this.isLoading = true;
80
+    return this.mainService.getFetchDataList("data", "department", postData);
81
+  }
82
+  //打开发起科室下拉框
83
+  changeFormDept(flag) {
84
+    if (flag) {
85
+      // 发起科室列表
86
+      this.getDeptList().subscribe((result) => {
87
+        this.isLoading = false;
88
+        if (result.status == 200) {
89
+          result.list.forEach((item) => {
90
+            item._uid = item.id + "__" + item.dept;
91
+          });
92
+          this.initiatingDepartments = result.list;
93
+        }
94
+      });
95
+    }
96
+  }
97
+  /**
98
+   * 选择科室
99
+   * @param e 选中的科室uid
100
+   * @param type 科室类型(initiating,start,end)
101
+   */
102
+  selectedDeptHandler(e, type) {
103
+    let arr = e.split("__");
104
+    let o = { id: arr[0], dept: arr[1], _uid: arr[0] + "__" + arr[1] };
105
+    if (this.type === 1 && type === "initiating") {
106
+      this.startDepartments = [o];
107
+      this.validateForm.controls.startDepartment.setValue(e);
108
+      this.endDepartments = this.endCarryingCourses.departmentDTOS;
109
+      this.validateForm.controls.endDepartment.setValue(
110
+        this.endDepartments[0]._uid
111
+      );
112
+    } else if (this.type === 2 && type === "initiating") {
113
+      this.endDepartments = [o];
114
+      this.validateForm.controls.endDepartment.setValue(e);
115
+      this.startDepartments = this.startCarryingCourses.departmentDTOS;
116
+      this.validateForm.controls.startDepartment.setValue(
117
+        this.startDepartments[0]._uid
118
+      );
119
+    } else if (this.type === 3 && type === "initiating") {
120
+      this.endDepartments = [o];
121
+      this.validateForm.controls.endDepartment.setValue(e);
122
+      this.startDepartments = [o];
123
+      this.validateForm.controls.startDepartment.setValue(e);
124
+    }
125
+  }
126
+  //搜索科室
127
+  changeInp(e, type) {
128
+    this.keyword = e;
129
+    if (
130
+      (this.type === 1 ||
131
+        this.type === 2 ||
132
+        this.type === 3 ||
133
+        this.type === 4) &&
134
+      type === "initiating"
135
+    ) {
136
+      // 发起科室列表
137
+      this.getDeptList({ e }).subscribe((result) => {
138
+        if (result.status == 200 && this.keyword == e) {
139
+          this.isLoading = false;
140
+          result.list.forEach((item) => {
141
+            item._uid = item.id + "__" + item.dept;
142
+          });
143
+          this.initiatingDepartments = result.list;
144
+        } else if (result.status != 200) {
145
+          this.isLoading = false;
146
+        }
147
+      });
148
+    }
149
+    if (this.type === 4 && type === "start") {
150
+      // 起点科室列表
151
+      this.getDeptList({ e }).subscribe((result) => {
152
+        if (result.status == 200 && this.keyword == e) {
153
+          this.isLoading = false;
154
+          result.list.forEach((item) => {
155
+            item._uid = item.id + "__" + item.dept;
156
+          });
157
+          this.startDepartments = result.list;
158
+        } else if (result.status != 200) {
159
+          this.isLoading = false;
160
+        }
161
+      });
162
+    }
163
+    if (this.type === 4 && type === "end") {
164
+      // 终点科室列表
165
+      this.getDeptList({ e }).subscribe((result) => {
166
+        if (result.status == 200 && this.keyword == e) {
167
+          this.isLoading = false;
168
+          result.list.forEach((item) => {
169
+            item._uid = item.id + "__" + item.dept;
170
+          });
171
+          this.endDepartments = result.list;
172
+        } else if (result.status != 200) {
173
+          this.isLoading = false;
174
+        }
175
+      });
176
+    }
177
+  }
178
+  //保存
179
+  submitForm() {
180
+    console.log(this.validateForm.get("initiatingDepartment").value);
181
+    console.log(this.validateForm.get("startDepartment").value);
182
+    console.log(this.validateForm.get("endDepartment").value);
183
+    for (const i in this.validateForm.controls) {
184
+      this.validateForm.controls[i].markAsDirty();
185
+      this.validateForm.controls[i].updateValueAndValidity();
186
+    }
187
+    if (this.validateForm.invalid) {
188
+      return;
189
+    }
190
+    let postData = {
191
+      hosId: this.hosId,
192
+      orderPlanId: this.selectedBatchOrder.id,
193
+      createDept: {
194
+        id: this.validateForm.get("initiatingDepartment").value.split("__")[0],
195
+      },
196
+      startDept: {
197
+        id: this.validateForm.get("startDepartment").value.split("__")[0],
198
+      },
199
+      endDept: {
200
+        id: this.validateForm.get("endDepartment").value.split("__")[0],
201
+      },
202
+    };
203
+    this.saveLoading = true;
204
+    this.mainService
205
+      .simplePost("addData", "orderPlanRule", postData)
206
+      .subscribe((result) => {
207
+        this.hideModal();
208
+        this.saveLoading = false;
209
+        if (result.status == 200) {
210
+          this.getList(1);
211
+        }
212
+      });
213
+  }
214
+  //获取列表数据
215
+  loading1 = false;
216
+  listOfData: any[] = []; //表格数据
217
+  pageIndex: number = 1; //表格当前页码
218
+  pageSize: number = 10; //表格每页展示条数
219
+  listLength: number = 10; //表格总数据量
220
+  getList(type) {
221
+    if (type == 1) {
222
+      this.pageIndex = 1;
223
+    }
224
+    let data = {
225
+      idx: this.pageIndex - 1,
226
+      sum: this.pageSize,
227
+      orderPlanRule: {
228
+        hosId: this.hosId,
229
+      },
230
+    };
231
+    this.mapOfCheckedId = {};
232
+    this.checkedDepIds = [];
233
+    this.isAllDisplayDataChecked = false;
234
+    this.loading1 = true;
235
+    this.mainService
236
+      .getFetchDataList("simple/data", "orderPlanRule", data)
237
+      .subscribe((data) => {
238
+        this.loading1 = false;
239
+        if (data.status == 200) {
240
+          this.listOfData = data.list;
241
+          this.listLength = data.totalNum;
242
+        }
243
+      });
244
+  }
245
+  // 选中表格单列
246
+  mapOfCheckedId: { [key: string]: boolean } = {};
247
+  checkedDepIds = []; //已选中单列id
248
+  refreshStatus(): void {
249
+    this.isAllDisplayDataChecked = this.listOfData.every(
250
+      (item) => this.mapOfCheckedId[item.id]
251
+    );
252
+    let arr = [];
253
+    for (var k in this.mapOfCheckedId) {
254
+      if (this.mapOfCheckedId[k]) {
255
+        arr.push(Number(k));
256
+      }
257
+    }
258
+    this.checkedDepIds = arr;
259
+  }
260
+  // 全选
261
+  isAllDisplayDataChecked = false; //当前页是否全选
262
+  checkAll(value: boolean): void {
263
+    this.listOfData.forEach((item) => {
264
+      this.mapOfCheckedId[item.id] = value;
265
+    });
266
+    this.refreshStatus();
267
+  }
268
+  // 批量删除
269
+  showDelModals(e) {
270
+    let ids = this.checkedDepIds.join(",");
271
+    this.showDelModal(e, ids);
272
+  }
273
+  //删除
274
+  delModal: boolean = false; //删除模态框
275
+  loading3 = false;
276
+  coopId: string; //表格中执行操作的id
277
+  showDelModal(e, id) {
278
+    e.stopPropagation();
279
+    this.delModal = true;
280
+    this.coopId = id + "";
281
+  }
282
+  hideDelModal() {
283
+    this.delModal = false;
284
+  }
285
+  confirmDel() {
286
+    this.loading3 = true;
287
+    this.mainService.simplePost("rmvData", "orderPlanRule",this.coopId.split(',')).subscribe((data) => {
288
+      this.loading3 = false;
289
+      this.delModal = false;
290
+      if (data.status == 200) {
291
+        if (
292
+          this.listOfData.length == 1 &&
293
+          this.pageIndex == Math.ceil(this.listLength / this.pageSize)
294
+        ) {
295
+          this.listLength--;
296
+          this.pageIndex = Math.ceil(this.listLength / this.pageSize);
297
+        }
298
+        this.message.success('删除成功');
299
+        this.getList(1);
300
+      } else {
301
+        this.message.error('删除失败');
302
+      }
303
+    });
304
+  }
305
+  ngOnInit() {
306
+    console.log(this.selectedBatchOrder);
307
+    this.hosId = this.tool.getCurrentHospital().id;
308
+    this.getList(1);
309
+    // 发起科室列表
310
+    this.getDeptList().subscribe((result) => {
311
+      if (result.status == 200) {
312
+        result.list.forEach((item) => {
313
+          item._uid = item.id + "__" + item.dept;
314
+        });
315
+        this.initiatingDepartments = result.list;
316
+      }
317
+    });
318
+    this.taskType = JSON.parse(
319
+      JSON.stringify(this.selectedBatchOrder.taskType)
320
+    );
321
+    this.startCarryingCourses = this.taskType.carryingCourses[0];
322
+    this.endCarryingCourses = this.taskType.carryingCourses[1];
323
+    if (this.startCarryingCourses.departmentDTOS) {
324
+      this.startCarryingCourses.departmentDTOS.forEach((item) => {
325
+        item._uid = item.id + "__" + item.dept;
326
+      });
327
+    }
328
+    if (this.endCarryingCourses.departmentDTOS) {
329
+      this.endCarryingCourses.departmentDTOS.forEach((item) => {
330
+        item._uid = item.id + "__" + item.dept;
331
+      });
332
+    }
333
+    if (
334
+      // 起点科室是默认发起科室,终点科室是固定科室
335
+      this.startCarryingCourses.departmentStrategy.value === "1" &&
336
+      this.endCarryingCourses.departmentStrategy.value === "2"
337
+    ) {
338
+      this.type = 1;
339
+      this.startDepartmentsDisabled = true;
340
+      this.endDepartmentsDisabled = true;
341
+    } else if (
342
+      // 起点科室是固定科室,终点科室是默认发起科室
343
+      this.startCarryingCourses.departmentStrategy.value === "2" &&
344
+      this.endCarryingCourses.departmentStrategy.value === "1"
345
+    ) {
346
+      this.type = 2;
347
+      this.startDepartmentsDisabled = true;
348
+      this.endDepartmentsDisabled = true;
349
+    } else if (
350
+      // 起点科室是默认发起科室,终点科室是默认发起科室
351
+      this.startCarryingCourses.departmentStrategy.value === "1" &&
352
+      this.endCarryingCourses.departmentStrategy.value === "1"
353
+    ) {
354
+      this.type = 3;
355
+      this.startDepartmentsDisabled = true;
356
+      this.endDepartmentsDisabled = true;
357
+    } else {
358
+      //其他情况
359
+      this.type = 4;
360
+      // 发起科室列表,起点科室列表,终点科室列表
361
+      this.getDeptList().subscribe((result) => {
362
+        if (result.status == 200) {
363
+          result.list.forEach((item) => {
364
+            item._uid = item.id + "__" + item.dept;
365
+          });
366
+          this.initiatingDepartments = JSON.parse(JSON.stringify(result.list));
367
+          this.startDepartments = JSON.parse(JSON.stringify(result.list));
368
+          this.endDepartments = JSON.parse(JSON.stringify(result.list));
369
+        }
370
+      });
371
+    }
372
+  }
373
+}

+ 145 - 0
src/app/share/detail-drug/detail-drug.component.html

@@ -0,0 +1,145 @@
1
+<!-- 药品/静配 -->
2
+<div class="detail" *ngIf="!maskFlag">
3
+  <div class="title">工单信息<i class="icon_transport transport-guanbi" (click)="close()"></i></div>
4
+  <div class="content">
5
+    <div class="top">
6
+      <div class="num">
7
+        <span class="left">单号:{{orderInfo.gdcode}}</span>
8
+        <span class="right">{{orderInfo.gdState?orderInfo.gdState.name:''}}</span>
9
+      </div>
10
+      <div class="info" nz-row>
11
+        <div nz-col nzSpan="8">工单日期:{{orderInfo.startTime}}</div>
12
+        <div nz-col nzSpan="8">总耗时:{{orderInfo.showTimeNum}}</div>
13
+        <div nz-col nzSpan="8">申请类型:{{orderInfo.taskType?orderInfo.taskType.taskName:''}}</div>
14
+        <div nz-col nzSpan="8">申请科室:{{orderInfo.createDeptDTO?orderInfo.createDeptDTO.dept:''}}</div>
15
+        <div nz-col nzSpan="8">目标科室:{{(orderInfo.endDepts&&orderInfo.endDepts[0])?orderInfo.endDepts[0].dept:''}}</div>
16
+        <div nz-col nzSpan="8" *ngIf="orderInfo.worker">支助人员信息:{{orderInfo.worker.name}}</div>
17
+        <div nz-col nzSpan="24" *ngIf="orderInfo.specialCloseReason">
18
+          特殊情况关闭原因:{{orderInfo.specialCloseReason}}
19
+        </div>
20
+      </div>
21
+    </div>
22
+    <div class="center">
23
+      <div class="box">
24
+        <div class="steps" *ngFor="let step of logList">
25
+          <div class="step">
26
+            <div class="info">
27
+              <i
28
+                [ngClass]="{'icon_transport':true, 'transport-icon_liucheng':true,'green':(step.record&&step.record[0]&&step.record[0].operationTime)}"></i>
29
+              <p>{{step.operationName}}</p>
30
+              <p>{{step.record.length>=1?(step.record[0].operationTime|date:'MM-dd HH:mm'):''}}</p>
31
+              <p *ngIf="step.record&&step.record.length&&step.record[0].dept"><span
32
+                  *ngFor="let dept of step.record">{{dept.dept}},</span></p>
33
+              <p *ngIf="step.record&&step.record.length">{{filterTime(step.record)?'耗时'+filterTime(step.record):''}}</p>
34
+            </div>
35
+            <div class="line"></div>
36
+          </div>
37
+        </div>
38
+      </div>
39
+    </div>
40
+    <div class="bottom">
41
+
42
+      <div class="urgent" *ngIf="orderInfo.urgentDetails&&showCoop">
43
+        加急原因:{{orderInfo.urgentDetails.urgentReason}}
44
+        <button *ngIf="orderInfo.urgentDetails.checkStatus.id==329" nz-button nzType="primary"
45
+          [nzLoading]="urgentLoading" nzGhost (click)="urgent()">确认加急</button>
46
+      </div>
47
+      <div class="table">
48
+        <nz-table *ngIf="orderInfo.staticDistri" class="detailDrugTable"
49
+          [nzData]="orderInfo.staticDistri.jpdetailsFormat" nzSize="small" [nzScroll]="{ y: '110px' }"
50
+          [nzShowPagination]="null">
51
+          <thead>
52
+            <tr class="thead">
53
+              <th nzWidth="100px">患者信息</th>
54
+              <th nzWidth="200px">药品</th>
55
+              <th nzWidth="50px">数量</th>
56
+              <th nzWidth="100px">患者信息</th>
57
+              <th nzWidth="200px">药品</th>
58
+              <th nzWidth="50px">数量</th>
59
+            </tr>
60
+          </thead>
61
+          <tbody *ngIf="orderInfo.staticDistri">
62
+            <tr *ngFor="let data of orderInfo.staticDistri.jpdetailsFormat">
63
+              <td>{{data[0].bedNum}}床:{{data[0].patientInfo}}</td>
64
+              <td>{{data[0].jpInfo}}</td>
65
+              <td>{{data[0].jpNum}}</td>
66
+              <td>{{data[1]?data[1].bedNum+"床:"+data[1].patientInfo:''}}</td>
67
+              <td>{{data[1]?data[1].jpInfo:''}}</td>
68
+              <td>{{data[1]?data[1].jpNum:''}}</td>
69
+            </tr>
70
+          </tbody>
71
+        </nz-table>
72
+        <nz-table *ngIf="orderInfo.drugs" class="detailDrugTable" [nzData]="orderInfo.drugs.drugsFormat" nzSize="small"
73
+          [nzScroll]="{ y: '110px' }" [nzShowPagination]="null">
74
+          <thead>
75
+            <tr class="thead">
76
+              <th nzWidth="100px">患者信息</th>
77
+              <th nzWidth="200px">药品</th>
78
+              <th nzWidth="50px">数量</th>
79
+              <th nzWidth="100px">患者信息</th>
80
+              <th nzWidth="200px">药品</th>
81
+              <th nzWidth="50px">数量</th>
82
+            </tr>
83
+          </thead>
84
+          <tbody *ngIf="orderInfo.drugs">
85
+            <tr *ngFor="let data of orderInfo.drugs.drugsFormat">
86
+              <td>{{data[0].bedNum}}床:{{data[0].patientInfo}}</td>
87
+              <td>{{data[0].drugsInfo}}</td>
88
+              <td>{{data[0].drugsNum}}</td>
89
+              <td>{{data[1]?data[1].bedNum+"床:"+data[1].patientInfo:''}}</td>
90
+              <td>{{data[1]?data[1].drugsInfo:''}}</td>
91
+              <td>{{data[1]?data[1].drugsNum:''}}</td>
92
+            </tr>
93
+          </tbody>
94
+        </nz-table>
95
+      </div>
96
+    </div>
97
+  </div>
98
+  <div class="btns display_flex justify-content_flex-center">
99
+    <!-- <button *ngIf="showCoop&&orderInfo.gdState.id==69" nz-button nzType="primary" (click)='allotWorker()'>派单</button>
100
+    <button *ngIf="showCoop&&(orderInfo.gdState.id==70||orderInfo.gdState.id==71)" nz-button nzType="primary" nzGhost
101
+      (click)="openRecallModal()">撤回</button>
102
+    <button *ngIf="showCoop&&(orderInfo.gdState.id==69||orderInfo.gdState.id==70||orderInfo.gdState.id==71)" nz-button
103
+      nzType="danger" (click)="openDelModal()">删除</button> -->
104
+    <button class=" btn cancel" nz-button nzType="default" (click)="close()">取消</button>
105
+  </div>
106
+</div>
107
+<!-- 撤回工单 -->
108
+<div class="recallOrder" *ngIf="recallOrderShow">
109
+  <div class="modalBody">
110
+    <div class="title">提示<i class="icon_transport transport-guanbi" (click)="closeRecallOrderModal()"></i></div>
111
+    <div class="content">
112
+      <div class="icon"><i class="icon_transport transport-wenhao"></i></div>
113
+      <div class="defeat">您确认要撤回此工单吗?</div>
114
+    </div>
115
+    <div class="btns display_flex justify-content_flex-center">
116
+      <button nz-button nzType="primary" [nzLoading]="btnLoading" (click)="confirmRec()">确认</button>
117
+      <button nz-button nzType="primary" [nzLoading]="recLoading" nzGhost (click)="recAndDel()">撤回并删除</button>
118
+      <button class=" btn cancel" nz-button nzType="default" (click)="closeRecallOrderModal()">取消</button>
119
+    </div>
120
+  </div>
121
+</div>
122
+
123
+<!-- 删除工单 -->
124
+<div class="recallOrder delModel" *ngIf="delOrderShow">
125
+  <div class="modalBody">
126
+    <div class="title">提示<i class="icon_transport transport-guanbi" (click)="closeDelOrderModal()"></i></div>
127
+    <div class="content">
128
+      <div class="icon"><i class="icon_transport transport-wenhao"></i></div>
129
+      <div class="defeat">您确认要删除此工单吗?</div>
130
+    </div>
131
+    <div class="btns display_flex justify-content_flex-center">
132
+      <button nz-button nzType="primary" [nzLoading]='btnLoading' (click)="confirmDel()">确认</button>
133
+      <!-- <button class="candelBtn btn" nz-button nzType="primary" nzGhost>撤回并删除</button> -->
134
+      <button class=" btn cancel" nz-button nzType="default" (click)="closeDelOrderModal()">取消</button>
135
+    </div>
136
+  </div>
137
+</div>
138
+
139
+<!-- 操作成功/失败提示框 -->
140
+<app-prompt-modal *ngIf="promptModalShow" [content]="promptContent" [success]="ifSuccess" [show]="promptModalShow"
141
+  [info]="promptInfo" (closeModel)="close()">
142
+  <!-- 2.父组件调用子组件时绑定到这个事件属性,并在事件发生时作出回应。(closeModel)="close()" -->
143
+</app-prompt-modal>
144
+<!-- 遮罩 -->
145
+<app-mask *ngIf="maskFlag"></app-mask>

+ 299 - 0
src/app/share/detail-drug/detail-drug.component.less

@@ -0,0 +1,299 @@
1
+@import "../../../../src/theme.less";
2
+:host {
3
+  width: 100%;
4
+  height: 100%;
5
+  position: fixed;
6
+  left: 0;
7
+  top: 0;
8
+  background: rgba(0, 0, 0, 0.4);
9
+  z-index: 9;
10
+
11
+  display: flex;
12
+  justify-content: center;
13
+  align-items: center;
14
+}
15
+
16
+.detail {
17
+  width: 1000px;
18
+  min-height: 580px;
19
+  border-radius: 5px;
20
+  background: #fff;
21
+  color: #333;
22
+  font-size: 14px;
23
+  padding: 12px 20px;
24
+  position: relative;
25
+  padding-bottom: 70px;
26
+
27
+  .title {
28
+    font-size: 18px;
29
+    text-align: center;
30
+    line-height: 24px;
31
+    margin: 0;
32
+    margin-bottom: 12px;
33
+    position: relative;
34
+
35
+    i {
36
+      position: absolute;
37
+      right: 0;
38
+      top: 0;
39
+      font-size: 20px;
40
+      color: #666;
41
+      cursor: pointer;
42
+      padding: 0 5px;
43
+    }
44
+  }
45
+
46
+  .content {
47
+    width: 960px;
48
+    // height: 474px;
49
+    border: 1px solid #e5e9ed;
50
+    border-radius: 5px;
51
+    overflow: hidden;
52
+
53
+    & > .top {
54
+      padding: 10px 32px;
55
+      border-bottom: 1px solid #e5e9ed;
56
+
57
+      .num {
58
+        font-size: 16px;
59
+        overflow: hidden;
60
+        margin-bottom: 6px;
61
+
62
+        .left {
63
+          float: left;
64
+          font-weight: 600;
65
+        }
66
+
67
+        .right {
68
+          float: right;
69
+        }
70
+      }
71
+
72
+      .info {
73
+        color: #666;
74
+
75
+        & > div {
76
+          margin: 4px 0;
77
+        }
78
+      }
79
+    }
80
+
81
+    & > .center {
82
+      padding: 27px 0 17px 0;
83
+      border-bottom: 1px solid #e5e9ed;
84
+      font-size: 12px;
85
+
86
+      .box {
87
+        display: flex;
88
+        justify-content: center;
89
+
90
+        .steps {
91
+          &:nth-last-child(1) {
92
+            .line {
93
+              display: none !important;
94
+            }
95
+          }
96
+
97
+          .step {
98
+            .info {
99
+              width: 90px;
100
+              text-align: center;
101
+              display: inline-block;
102
+              vertical-align: top;
103
+
104
+              i {
105
+                color: #e5e9ed;
106
+
107
+                &.green {
108
+                  color: @primary-color;
109
+                }
110
+              }
111
+            }
112
+
113
+            p {
114
+              margin: 0;
115
+            }
116
+
117
+            .line {
118
+              display: inline-block;
119
+              width: 60px;
120
+              height: 2px;
121
+              background: #e5e9ed;
122
+            }
123
+          }
124
+        }
125
+      }
126
+    }
127
+
128
+    & > .bottom {
129
+      padding: 28px 32px;
130
+      background: #f9fafb;
131
+
132
+      .urgent {
133
+        input {
134
+          width: 600px;
135
+        }
136
+
137
+        .candelBtn {
138
+          margin-left: 20px;
139
+        }
140
+      }
141
+
142
+      .table {
143
+        width: 100%;
144
+        height: 160px;
145
+        background: #fff;
146
+        border-radius: 5px;
147
+        margin-top: 16px;
148
+
149
+        .thead {
150
+          background-image: repeating-linear-gradient(
151
+            to right,
152
+            @bg-start,
153
+            @bg-end 50%
154
+          ) !important;
155
+
156
+          th {
157
+            color: #fff !important;
158
+            text-align: center;
159
+            font-size: 12px;
160
+            border: none;
161
+          }
162
+        }
163
+
164
+        .ant-table-tbody {
165
+          tr {
166
+            text-align: center;
167
+            font-size: 12px;
168
+            border: none;
169
+
170
+            td {
171
+              border: none;
172
+            }
173
+          }
174
+
175
+          tr:nth-child(2n) {
176
+            background: #f9fafb;
177
+          }
178
+        }
179
+      }
180
+    }
181
+  }
182
+
183
+  .btns {
184
+    width: 100%;
185
+    position: absolute;
186
+    left: 0;
187
+    bottom: 20px;
188
+
189
+    button {
190
+      margin: 9px;
191
+      margin-bottom: 0;
192
+    }
193
+  }
194
+
195
+  .ant-table {
196
+    border: none !important;
197
+  }
198
+}
199
+
200
+// 撤回工单
201
+.recallOrder {
202
+  position: fixed;
203
+  left: 0;
204
+  top: 0;
205
+  width: 100%;
206
+  height: 100%;
207
+
208
+  display: flex;
209
+  justify-content: center;
210
+  align-items: center;
211
+  background: rgba(0, 0, 0, 0.4);
212
+  z-index: 99;
213
+
214
+  .modalBody {
215
+    width: 350px;
216
+    height: 220px;
217
+    background: #fff;
218
+    border-radius: 5px;
219
+    padding: 10px 20px;
220
+    color: #333;
221
+
222
+    .title {
223
+      width: 100%;
224
+      text-align: center;
225
+      font-size: 18px;
226
+      position: relative;
227
+
228
+      i {
229
+        position: absolute;
230
+        right: 0;
231
+        top: 0;
232
+        font-size: 20px;
233
+        color: #666;
234
+        cursor: pointer;
235
+        padding: 0 5px;
236
+      }
237
+    }
238
+
239
+    .content {
240
+      width: 310px;
241
+      height: 117px;
242
+      background: #f9fafb;
243
+      border: 1px solid #e5e9ed;
244
+      border-radius: 5px;
245
+      overflow: hidden;
246
+      margin-top: 12px;
247
+
248
+      div {
249
+        text-align: center;
250
+        margin: 0;
251
+
252
+        &.icon {
253
+          margin-top: 17px;
254
+
255
+          i {
256
+            color: #ff3b53;
257
+            font-size: 30px !important;
258
+
259
+            &.transport-wenhao {
260
+              color: #f5a523;
261
+            }
262
+          }
263
+        }
264
+
265
+        &.defeat {
266
+          color: #333;
267
+          font-size: 18px;
268
+        }
269
+
270
+        &:nth-child(3) {
271
+          font-size: 14px;
272
+          color: #666;
273
+        }
274
+      }
275
+
276
+      .conditions {
277
+        padding: 16px 20px;
278
+
279
+        div {
280
+          text-align: left;
281
+        }
282
+      }
283
+    }
284
+
285
+    .btns {
286
+      button {
287
+        margin-top: 10px;
288
+
289
+        &.btn {
290
+          margin-left: 8px;
291
+        }
292
+      }
293
+    }
294
+  }
295
+}
296
+
297
+.txtC {
298
+  text-align: center;
299
+}

+ 218 - 0
src/app/share/detail-drug/detail-drug.component.ts

@@ -0,0 +1,218 @@
1
+import { Component, OnInit } from '@angular/core';
2
+import { ActivatedRoute, Router } from '@angular/router';
3
+import { MainService } from '../../services/main.service';
4
+import { forkJoin } from 'rxjs';
5
+import { NzMessageService } from 'ng-zorro-antd';
6
+
7
+@Component({
8
+  selector: 'app-detail-drug',
9
+  templateUrl: './detail-drug.component.html',
10
+  styleUrls: ['./detail-drug.component.less']
11
+})
12
+export class DetailDrugComponent implements OnInit {
13
+
14
+  constructor(
15
+    private message: NzMessageService,
16
+    private route: ActivatedRoute,
17
+    private router: Router,
18
+    private mainService: MainService
19
+  ) { }
20
+
21
+  id: number;//工单id
22
+  orderInfo: any;//工单详情信息
23
+  showCoop: boolean = true;//是否展示详情页操作按钮
24
+
25
+  promptContent: string;//操作提示框提示信息
26
+  ifSuccess: boolean;//操作成功/失败
27
+  promptInfo: string;//操作结果提示信息
28
+  promptModalShow: boolean;//是否展示提示框
29
+
30
+  urgentLoading: boolean = false;//确认加急按钮loading状态
31
+  recLoading: boolean = false;//撤回并删除按钮loading状态
32
+  btnLoading: boolean = false;//确认按钮loading状态
33
+  maskFlag: any = false;
34
+
35
+  ngOnInit() {
36
+    if (this.route.snapshot.parent.parent.routeConfig.path == 'nurse') {
37
+      this.showCoop = false;
38
+    }
39
+    this.id = +this.route.snapshot.paramMap.get('id');
40
+    let log$ = this.getLog();
41
+    let detail$ = this.getDetail();
42
+    this.maskFlag = this.message.loading('正在加载中..', { nzDuration: 0 }).messageId;
43
+    forkJoin(log$, detail$).subscribe(res => {
44
+      this.message.remove(this.maskFlag);
45
+      this.maskFlag = false;
46
+      // getLog
47
+      this.logList = res[0]['data'];
48
+      // getDetail
49
+      this.orderInfo = res[1]['data'];
50
+    })
51
+  }
52
+
53
+  // 获取工单详情
54
+  getDetail() {
55
+    return this.mainService.getApiFetchData('workOrder', this.id);
56
+  }
57
+
58
+  // 关闭弹框
59
+  close() {
60
+    // this.router.navigateByUrl('dispatchingDesk');
61
+    history.go(-1)
62
+  }
63
+
64
+
65
+  // 加急
66
+  urgent() {
67
+    let that = this;
68
+    that.urgentLoading = true;
69
+    let postData = {
70
+      urgentDetails: {
71
+        workerOrder: that.id,
72
+        checkStatus: { id: 330 },
73
+        urgentReason: that.orderInfo['urgentDetails']['urgentReason'],
74
+        id: that.orderInfo['urgentDetails']['id']
75
+      }
76
+    }
77
+    that.mainService.postCustom('workerOrder', 'urge', postData).subscribe(data => {
78
+      console.log(data);
79
+      that.urgentLoading = false;
80
+      if (data.status == 200) {
81
+        that.showPromptModal('加急', true, '');
82
+      } else {
83
+        that.showPromptModal('加急', false, data.msg);
84
+      }
85
+    })
86
+  }
87
+
88
+  // 派单
89
+  allotWorker() {
90
+    this.router.navigateByUrl('dispatchingDesk/allotWorker/' + this.id + '/' + this.orderInfo['gdState']['id']);
91
+  }
92
+
93
+  // 获取工单历史记录
94
+  logList = [];//工单历史记录
95
+  getLog() {
96
+    return this.mainService.getWorkOrderLog(this.id);
97
+  }
98
+
99
+  // 撤回
100
+  recallOrderShow: boolean = false;
101
+  openRecallModal(): void {
102
+    this.recallOrderShow = true;
103
+  }
104
+  // 确认撤回
105
+  confirmRec() {
106
+    let that = this;
107
+    that.btnLoading = true;
108
+    let postData = {
109
+      workOrder: {
110
+        id: that.id
111
+      }
112
+    }
113
+    that.mainService.coopWorkerOrder('excuteWorkOrder/recall', postData).subscribe(data => {
114
+      that.btnLoading = false;
115
+      that.closeRecallOrderModal()
116
+      if (data.status == 200) {
117
+        that.showPromptModal('撤回', true, '');
118
+      } else {
119
+        that.showPromptModal('撤回', false, data.msg);
120
+      }
121
+    })
122
+  }
123
+  // 撤回并删除
124
+  recAndDel() {
125
+    let that = this;
126
+    that.recLoading = true;
127
+    that.mainService.delOrder(that.id).subscribe(data => {
128
+      console.log(data);
129
+      that.recLoading = false;
130
+      that.closeDelOrderModal()
131
+      if (data.status == 200) {
132
+        that.showPromptModal('删除', true, '');
133
+      } else {
134
+        that.showPromptModal('删除', false, data.msg);
135
+      }
136
+    })
137
+  }
138
+  // 关闭撤回弹框
139
+  closeRecallOrderModal() {
140
+    this.recallOrderShow = false;
141
+  }
142
+
143
+  // 删除
144
+  // 打开模态框
145
+  delOrderShow: boolean = false;
146
+  openDelModal() {
147
+    this.delOrderShow = true;
148
+  }
149
+  // 确认删除
150
+  confirmDel() {
151
+    let that = this;
152
+    that.btnLoading = true;
153
+    that.mainService.delOrder(that.id).subscribe(data => {
154
+      that.btnLoading = false;
155
+      that.closeDelOrderModal()
156
+      if (data.status == 200) {
157
+        that.showPromptModal('删除', true, '');
158
+      } else {
159
+        that.showPromptModal('删除', false, data.msg);
160
+      }
161
+    })
162
+  }
163
+
164
+  // 关闭模态框
165
+  closeDelOrderModal() {
166
+    this.delOrderShow = false;
167
+  }
168
+
169
+
170
+
171
+
172
+  // 展示信息提示框(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)
173
+  showPromptModal(con, success, promptInfo?) {
174
+    this.promptModalShow = false;
175
+    this.promptContent = con;
176
+    this.ifSuccess = success;
177
+    this.promptInfo = promptInfo;
178
+    setTimeout(() => {
179
+      this.promptModalShow = true;
180
+    }, 100);
181
+  }
182
+
183
+
184
+
185
+
186
+
187
+
188
+  // 格式化时分秒
189
+  // (时间小于一分钟则显示秒,时间大于一分钟则显示分钟数,如超出一小时则显示小时和分钟。)time单位:秒
190
+  formatTime(time) {
191
+    let timeStr = '';
192
+    if (time >= 0 && time < 60) {
193
+      // 秒
194
+      timeStr = time + '秒';
195
+    } else if (time >= 60 && time < 3600) {
196
+      // 分钟
197
+      timeStr = Math.floor(time / 60) + '分钟'
198
+    } else if (time >= 3600) {
199
+      // 时 + 分
200
+      let h = '';
201
+      let m = '';
202
+      h = Math.floor(time / 3600) + '小时';
203
+      m = (time % 3600) >= 60 ? Math.floor((time % 3600) / 60) + '分钟' : '';
204
+      timeStr = h + m;
205
+    }
206
+    return timeStr;
207
+  }
208
+
209
+  // 计算历史记录耗时
210
+  filterTime(step) {
211
+    // step = [{ difTime: 2 }, { difTime: 6 }]
212
+    let num = 0;
213
+    step.forEach(e => {
214
+      num += e.difTime;
215
+    });
216
+    return this.formatTime(num / 1000);
217
+  }
218
+}

+ 95 - 0
src/app/share/detail-others/detail-others.component.html

@@ -0,0 +1,95 @@
1
+<!-- 患者转运/其他 -->
2
+<div class="detail" *ngIf="!maskFlag">
3
+  <div class="title">工单信息<i class="icon_transport transport-guanbi" (click)="close()"></i></div>
4
+  <div class="content">
5
+    <div class="top">
6
+      <div class="num">
7
+        <span class="left">单号:{{orderInfo.gdcode}}</span>
8
+        <span class="right">{{orderInfo.gdState.name}}</span>
9
+      </div>
10
+      <div class="info" nz-row>
11
+        <div nz-col nzSpan="8">工单日期:{{orderInfo.startTime}}</div>
12
+        <div nz-col nzSpan="8">总耗时:{{orderInfo.showTimeNum}}</div>
13
+        <div nz-col nzSpan="8">申请类型:{{orderInfo.taskType.taskName}}</div>
14
+        <div nz-col nzSpan="8">申请科室:{{orderInfo.createDeptDTO?orderInfo.createDeptDTO.dept:'-'}}</div>
15
+        <div nz-col nzSpan="8">目标科室:{{endDepts}}</div>
16
+        <div nz-col nzSpan="8" *ngIf="orderInfo.worker">支助人员信息:{{orderInfo.worker.name}}</div>
17
+        <div nz-col nzSpan="24" *ngIf="orderInfo.workOrderRemark">备注信息:{{orderInfo.workOrderRemark}}
18
+        </div>
19
+        <div nz-col nzSpan="24" *ngIf="orderInfo.specialCloseReason">特殊情况关闭原因:{{orderInfo.specialCloseReason}}
20
+        </div>
21
+      </div>
22
+    </div>
23
+    <div class="center">
24
+      <div class="box">
25
+        <div class="steps" *ngFor="let step of logList;let i = index;">
26
+          <div class="step">
27
+            <div class="info">
28
+              <i
29
+                [ngClass]="{'icon_transport':true, 'transport-icon_liucheng':true,'green':(step.record&&step.record[0]&&step.record[0].operationTime)}"></i>
30
+              <p>{{step.operationName}}</p>
31
+              <p>{{step.record.length>=1?(step.record[0].operationTime|date:'MM-dd HH:mm'):''}}</p>
32
+              <p *ngIf="i!=0&&step.record&&step.record.length">耗时{{filterTime(step.record)}}</p>
33
+            </div>
34
+            <div class="line"></div>
35
+          </div>
36
+        </div>
37
+      </div>
38
+    </div>
39
+    <div class="bottom" *ngIf="orderInfo.urgentDetails&&showCoop">
40
+      <div class="urgent">
41
+        加急原因:{{orderInfo.urgentDetails.urgentReason}}
42
+        <button *ngIf="orderInfo.urgentDetails.checkStatus.id==329" nz-button nzType="primary"
43
+          [nzLoading]="urgentLoading" nzGhost (click)="urgent()">确认加急</button>
44
+      </div>
45
+    </div>
46
+  </div>
47
+  <div class="btns display_flex justify-content_flex-center">
48
+    <!-- <button *ngIf="showCoop&&orderInfo.gdState.id==69" nz-button nzType="primary" [nzLoading]="isOkLoading"
49
+      (click)='allotWorker()'>派单</button>
50
+    <button *ngIf="showCoop&&(orderInfo.gdState.id==70||orderInfo.gdState.id==71)" nz-button nzType="primary" nzGhost
51
+      (click)="openRecallModal()">撤回</button>
52
+    <button *ngIf="showCoop&&(orderInfo.gdState.id==69||orderInfo.gdState.id==70||orderInfo.gdState.id==71)" nz-button
53
+      nzType="danger" (click)="openDelModal()">删除</button> -->
54
+    <button class=" btn cancel" nz-button nzType="default" (click)="close()">取消</button>
55
+  </div>
56
+</div>
57
+
58
+<!-- 撤回工单 -->
59
+<div class="recallOrder" *ngIf="recallOrderShow">
60
+  <div class="modalBody">
61
+    <div class="title">提示<i class="icon_transport transport-guanbi" (click)="closeRecallOrderModal()"></i></div>
62
+    <div class="content">
63
+      <div class="icon"><i class="icon_transport transport-wenhao"></i></div>
64
+      <div class="defeat">您确认要撤回此工单吗?</div>
65
+    </div>
66
+    <div class="btns display_flex justify-content_flex-center">
67
+      <button nz-button nzType="primary" [nzLoading]='btnLoading' (click)="confirmRec()">确认</button>
68
+      <button nz-button nzType="primary" [nzLoading]='recLoading' nzGhost (click)="recAndDel()">撤回并删除</button>
69
+      <button class=" btn cancel" nz-button nzType="default" (click)="closeRecallOrderModal()">取消</button>
70
+    </div>
71
+  </div>
72
+</div>
73
+
74
+<!-- 删除工单 -->
75
+<div class="recallOrder delModel" *ngIf="delOrderShow">
76
+  <div class="modalBody">
77
+    <div class="title">提示<i class="icon_transport transport-guanbi" (click)="closeDelOrderModal()"></i></div>
78
+    <div class="content">
79
+      <div class="icon"><i class="icon_transport transport-wenhao"></i></div>
80
+      <div class="defeat">您确认要删除此工单吗?</div>
81
+    </div>
82
+    <div class="btns display_flex justify-content_flex-center">
83
+      <button nz-button nzType="primary" [nzLoading]='btnLoading' (click)="confirmDel()">确认</button>
84
+      <button class="btn cancel" nz-button nzType="default" (click)="closeDelOrderModal()">关闭</button>
85
+    </div>
86
+  </div>
87
+</div>
88
+
89
+<!-- 操作成功/失败提示框 -->
90
+<app-prompt-modal *ngIf="promptModalShow" [content]="promptContent" [success]="ifSuccess" [show]="promptModalShow"
91
+  [info]="promptInfo" (closeModel)="close()">
92
+  <!-- 2.父组件调用子组件时绑定到这个事件属性,并在事件发生时作出回应。(closeModel)="close()" -->
93
+</app-prompt-modal>
94
+<!-- 遮罩 -->
95
+<app-mask *ngIf="maskFlag"></app-mask>

+ 297 - 0
src/app/share/detail-others/detail-others.component.less

@@ -0,0 +1,297 @@
1
+@import "../../../../src/theme.less";
2
+:host {
3
+  width: 100%;
4
+  height: 100%;
5
+  position: fixed;
6
+  left: 0;
7
+  top: 0;
8
+  background: rgba(0, 0, 0, 0.4);
9
+  z-index: 9;
10
+
11
+  display: flex;
12
+  justify-content: center;
13
+  align-items: center;
14
+}
15
+
16
+.detail {
17
+  width: 1000px;
18
+  min-height: 530px;
19
+  border-radius: 5px;
20
+  background: #fff;
21
+  color: #333;
22
+  font-size: 14px;
23
+  padding: 12px 20px;
24
+  position: relative;
25
+  padding-bottom: 70px;
26
+
27
+  .title {
28
+    font-size: 18px;
29
+    text-align: center;
30
+    line-height: 24px;
31
+    margin: 0;
32
+    margin-bottom: 12px;
33
+    position: relative;
34
+
35
+    i {
36
+      position: absolute;
37
+      right: 0;
38
+      top: 0;
39
+      font-size: 20px;
40
+      color: #666;
41
+      cursor: pointer;
42
+      padding: 0 5px;
43
+    }
44
+  }
45
+
46
+  .content {
47
+    width: 960px;
48
+    min-height: 400px;
49
+    border: 1px solid #e5e9ed;
50
+    border-radius: 5px;
51
+    overflow: hidden;
52
+
53
+    & > .top {
54
+      padding: 10px 32px;
55
+      border-bottom: 1px solid #e5e9ed;
56
+
57
+      .num {
58
+        font-size: 16px;
59
+        overflow: hidden;
60
+        margin-bottom: 6px;
61
+
62
+        .left {
63
+          float: left;
64
+          font-weight: 600;
65
+        }
66
+
67
+        .right {
68
+          float: right;
69
+        }
70
+      }
71
+
72
+      .info {
73
+        color: #666;
74
+
75
+        & > div {
76
+          margin: 4px 0;
77
+        }
78
+      }
79
+    }
80
+
81
+    & > .center {
82
+      padding: 27px 0 17px 0;
83
+      border-bottom: 1px solid #e5e9ed;
84
+      font-size: 12px;
85
+
86
+      .box {
87
+        display: flex;
88
+        justify-content: center;
89
+
90
+        .steps {
91
+          &:nth-last-child(1) {
92
+            .line {
93
+              display: none !important;
94
+            }
95
+          }
96
+
97
+          .step {
98
+            .info {
99
+              width: 90px;
100
+              text-align: center;
101
+              display: inline-block;
102
+              vertical-align: top;
103
+
104
+              i {
105
+                color: #e5e9ed;
106
+
107
+                &.green {
108
+                  color: @primary-color;
109
+                }
110
+              }
111
+            }
112
+
113
+            p {
114
+              margin: 0;
115
+            }
116
+
117
+            .line {
118
+              display: inline-block;
119
+              width: 60px;
120
+              height: 2px;
121
+              background: #e5e9ed;
122
+            }
123
+          }
124
+        }
125
+      }
126
+    }
127
+
128
+    & > .bottom {
129
+      padding: 28px 32px;
130
+      background: #f9fafb;
131
+
132
+      .urgent {
133
+        input {
134
+          width: 600px;
135
+        }
136
+
137
+        .candelBtn {
138
+          margin-left: 20px;
139
+        }
140
+      }
141
+
142
+      .table {
143
+        width: 100%;
144
+        height: 160px;
145
+        // padding: 6px;
146
+        background: #fff;
147
+        // border: 1px solid #e5e9ed;
148
+        border-radius: 5px;
149
+        margin-top: 16px;
150
+
151
+        .thead {
152
+          background: linear-gradient(to right, @bg-start, @bg-end) !important;
153
+
154
+          th {
155
+            color: #fff !important;
156
+            text-align: center;
157
+            font-size: 12px;
158
+            border: none;
159
+          }
160
+        }
161
+
162
+        .ant-table-tbody {
163
+          tr {
164
+            text-align: center;
165
+            font-size: 12px;
166
+            border: none;
167
+
168
+            td {
169
+              border: none;
170
+            }
171
+          }
172
+
173
+          tr:nth-child(2n) {
174
+            background: #f9fafb;
175
+          }
176
+        }
177
+      }
178
+    }
179
+  }
180
+
181
+  .btns {
182
+    width: 100%;
183
+    position: absolute;
184
+    left: 0;
185
+    bottom: 20px;
186
+
187
+    button {
188
+      margin: 9px;
189
+      margin-bottom: 0;
190
+    }
191
+  }
192
+
193
+  .ant-table {
194
+    border: none !important;
195
+  }
196
+}
197
+
198
+// 撤回工单
199
+.recallOrder {
200
+  position: fixed;
201
+  left: 0;
202
+  top: 0;
203
+  width: 100%;
204
+  height: 100%;
205
+
206
+  display: flex;
207
+  justify-content: center;
208
+  align-items: center;
209
+  background: rgba(0, 0, 0, 0.4);
210
+  z-index: 99;
211
+
212
+  .modalBody {
213
+    width: 350px;
214
+    height: 220px;
215
+    background: #fff;
216
+    border-radius: 5px;
217
+    padding: 10px 20px;
218
+    color: #333;
219
+
220
+    .title {
221
+      width: 100%;
222
+      text-align: center;
223
+      font-size: 18px;
224
+      position: relative;
225
+
226
+      i {
227
+        position: absolute;
228
+        right: 0;
229
+        top: 0;
230
+        font-size: 20px;
231
+        color: #666;
232
+        cursor: pointer;
233
+        padding: 0 5px;
234
+      }
235
+    }
236
+
237
+    .content {
238
+      width: 310px;
239
+      height: 117px;
240
+      background: #f9fafb;
241
+      border: 1px solid #e5e9ed;
242
+      border-radius: 5px;
243
+      overflow: hidden;
244
+      margin-top: 12px;
245
+
246
+      div {
247
+        text-align: center;
248
+        margin: 0;
249
+
250
+        &.icon {
251
+          margin-top: 17px;
252
+
253
+          i {
254
+            color: #ff3b53;
255
+            font-size: 30px !important;
256
+
257
+            &.transport-wenhao {
258
+              color: #f5a523;
259
+            }
260
+          }
261
+        }
262
+
263
+        &.defeat {
264
+          color: #333;
265
+          font-size: 18px;
266
+        }
267
+
268
+        &:nth-child(3) {
269
+          font-size: 14px;
270
+          color: #666;
271
+        }
272
+      }
273
+
274
+      .conditions {
275
+        padding: 16px 20px;
276
+
277
+        div {
278
+          text-align: left;
279
+        }
280
+      }
281
+    }
282
+
283
+    .btns {
284
+      button {
285
+        margin-top: 10px;
286
+
287
+        &.btn {
288
+          margin-left: 8px;
289
+        }
290
+      }
291
+    }
292
+  }
293
+}
294
+
295
+.txtC {
296
+  text-align: center;
297
+}

+ 213 - 0
src/app/share/detail-others/detail-others.component.ts

@@ -0,0 +1,213 @@
1
+import { Component, OnInit } from '@angular/core';
2
+import { ActivatedRoute, Router } from '@angular/router';
3
+import { MainService } from '../../services/main.service';
4
+import { forkJoin } from 'rxjs';
5
+import { NzMessageService } from 'ng-zorro-antd';
6
+
7
+@Component({
8
+  selector: 'app-detail-others',
9
+  templateUrl: './detail-others.component.html',
10
+  styleUrls: ['./detail-others.component.less']
11
+})
12
+export class DetailOthersComponent implements OnInit {
13
+
14
+  constructor(
15
+    private message: NzMessageService,
16
+    private route: ActivatedRoute,
17
+    private router: Router,
18
+    private mainService: MainService) { }
19
+
20
+  id: number;//工单id
21
+  orderInfo: any;//工单详情信息
22
+  endDepts = '';//工单详情目标科室
23
+  showCoop: boolean = true;//是否展示详情页操作按钮
24
+
25
+  promptContent: string;//操作提示框提示信息
26
+  ifSuccess: boolean;//操作成功/失败
27
+  promptInfo: string;//操作结果提示信息
28
+  promptModalShow: boolean;//是否展示提示框
29
+
30
+  urgentLoading: boolean = false;//确认加急按钮loading状态
31
+  recLoading: boolean = false;//撤回并删除按钮loading状态
32
+  btnLoading: boolean = false;//确认按钮loading状态
33
+  maskFlag: any = false;
34
+
35
+  ngOnInit() {
36
+    if (this.route.snapshot.parent.parent.routeConfig.path == 'nurse') {
37
+      this.showCoop = false;
38
+    }
39
+    this.id = +this.route.snapshot.paramMap.get('id');
40
+    let log$ = this.getLog();
41
+    let detail$ = this.getDetail();
42
+    this.maskFlag = this.message.loading('正在加载中..', { nzDuration: 0 }).messageId;
43
+    forkJoin(log$, detail$).subscribe(res => {
44
+      this.message.remove(this.maskFlag);
45
+      this.maskFlag = false;
46
+      // getLog
47
+      this.logList = res[0]['data'];
48
+      // getDetail
49
+      this.orderInfo = res[1]['data'];
50
+      this.endDepts = res[1]['data'].endDepts.map(item => item.dept).join();
51
+    })
52
+  }
53
+
54
+  // 获取工单详情
55
+  getDetail() {
56
+    return this.mainService.getApiFetchData('workOrder', this.id);
57
+  }
58
+
59
+  // 确认加急
60
+  urgent() {
61
+    let that = this;
62
+    that.urgentLoading = true;
63
+    let postData = {
64
+      "urgentDetails": {
65
+        "workerOrder": this.orderInfo['id'],
66
+        "checkStatus": {
67
+          "id": 330
68
+        },
69
+        "urgentReason": this.orderInfo['urgentDetails'].urgentReason,
70
+        "id": this.orderInfo['urgentDetails'].id
71
+      }
72
+    }
73
+    that.mainService.coopWorkerOrder('urge', postData).subscribe(data => {
74
+      that.urgentLoading = false;
75
+      if (data.status == 200) {
76
+        that.showPromptModal('加急', true, '');
77
+      } else {
78
+        that.showPromptModal('加急', false, data.msg);
79
+      }
80
+    })
81
+  }
82
+
83
+  // 关闭弹框
84
+  close() {
85
+    // this.router.navigateByUrl('dispatchingDesk');
86
+    history.go(-1)
87
+  }
88
+  // 展示信息提示框(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)
89
+  showPromptModal(con, success, promptInfo?) {
90
+    this.promptModalShow = false;
91
+    this.promptContent = con;
92
+    this.ifSuccess = success;
93
+    this.promptInfo = promptInfo;
94
+    setTimeout(() => {
95
+      this.promptModalShow = true;
96
+    }, 100);
97
+  }
98
+  // 获取工单历史记录
99
+  logList = [];//工单历史记录
100
+  getLog() {
101
+    return this.mainService.getWorkOrderLog(this.id);
102
+  }
103
+
104
+  // 派单
105
+  allotWorker() {
106
+    this.router.navigateByUrl('dispatchingDesk/allotWorker/' + this.id + '/' + this.orderInfo['gdState']['id']);
107
+  }
108
+
109
+  // 撤回
110
+  recallOrderShow: boolean = false;
111
+  openRecallModal(): void {
112
+    this.recallOrderShow = true;
113
+  }
114
+  // 撤回并删除
115
+  recAndDel() {
116
+    let that = this;
117
+    that.recLoading = true;
118
+    that.mainService.delOrder(that.id).subscribe(data => {
119
+      console.log(data);
120
+      that.recLoading = false;
121
+      that.closeDelOrderModal()
122
+      if (data.status == 200) {
123
+        that.showPromptModal('删除', true, '');
124
+      } else {
125
+        that.showPromptModal('删除', false, data.msg);
126
+      }
127
+    })
128
+  }
129
+  // 确认撤回
130
+  confirmRec() {
131
+    let that = this;
132
+    that.btnLoading = true;
133
+    let postData = {
134
+      workOrder: {
135
+        id: that.id
136
+      }
137
+    }
138
+    that.mainService.coopWorkerOrder('excuteWorkOrder/recall', postData).subscribe(data => {
139
+      that.btnLoading = false;
140
+      that.closeRecallOrderModal()
141
+      if (data.status == 200) {
142
+        that.showPromptModal('撤回', true, '');
143
+      } else {
144
+        that.showPromptModal('撤回', false, data.msg);
145
+      }
146
+    })
147
+  }
148
+  // 关闭撤回弹框
149
+  closeRecallOrderModal() {
150
+    this.recallOrderShow = false;
151
+  }
152
+
153
+
154
+  // 删除
155
+  // 打开模态框
156
+  delOrderShow: boolean = false;
157
+  openDelModal() {
158
+    this.delOrderShow = true;
159
+  }
160
+  // 确认删除
161
+  confirmDel() {
162
+    let that = this;
163
+    that.btnLoading = true;
164
+    that.mainService.delOrder(that.id).subscribe(data => {
165
+      that.btnLoading = false;
166
+      that.closeDelOrderModal()
167
+      if (data.status == 200) {
168
+        that.showPromptModal('删除', true, '');
169
+      } else {
170
+        that.showPromptModal('删除', false, data.msg);
171
+      }
172
+    })
173
+  }
174
+
175
+  // 关闭模态框
176
+  closeDelOrderModal() {
177
+    this.delOrderShow = false;
178
+  }
179
+
180
+  // 格式化时分秒
181
+  // (时间小于一分钟则显示秒,时间大于一分钟则显示分钟数,如超出一小时则显示小时和分钟。)time单位:秒
182
+  formatTime(time) {
183
+    let timeStr = '';
184
+    if (time >= 0 && time < 60) {
185
+      // 秒
186
+      timeStr = time + '秒';
187
+    } else if (time >= 60 && time < 3600) {
188
+      // 分钟
189
+      timeStr = Math.floor(time / 60) + '分钟'
190
+    } else if (time >= 3600) {
191
+      // 时 + 分
192
+      let h = '';
193
+      let m = '';
194
+      h = Math.floor(time / 3600) + '小时';
195
+      m = (time % 3600) >= 60 ? Math.floor((time % 3600) / 60) + '分钟' : '';
196
+      timeStr = h + m;
197
+    }
198
+    return timeStr;
199
+  }
200
+
201
+  // 计算历史记录耗时
202
+  filterTime(step) {
203
+    // step = [{ difTime: 2 }, { difTime: 6 }]
204
+    let num = 0;
205
+    step.forEach(e => {
206
+      num += e.difTime;
207
+    });
208
+    return this.formatTime(num / 1000);
209
+
210
+  }
211
+
212
+
213
+}

+ 182 - 0
src/app/share/detail-patients/detail-patients.component.html

@@ -0,0 +1,182 @@
1
+<!-- 患者陪检/患者转运 -->
2
+<div class="detail" *ngIf="!maskFlag">
3
+  <div class="title">工单信息<i class="icon_transport transport-guanbi" (click)="close()"></i></div>
4
+  <overlay-scrollbars #osComponentRef1 style="height: 462px;">
5
+    <div class="content">
6
+      <div class="top">
7
+        <div class="num">
8
+          <span class="left">单号:{{orderInfo.gdcode}}</span>
9
+          <span class="right">{{orderInfo.gdState.name}}</span>
10
+        </div>
11
+        <div class="info" nz-row>
12
+          <div nz-col nzSpan="8">工单日期:{{orderInfo.startTime}}</div>
13
+          <div nz-col nzSpan="8">总耗时:{{orderInfo.showTimeNum}}</div>
14
+          <div nz-col nzSpan="8">申请类型:{{orderInfo.taskType.taskName}}</div>
15
+          <div nz-col nzSpan="8">申请科室:{{orderInfo.createDeptDTO.dept}}</div>
16
+          <div nz-col nzSpan="8" *ngIf="middleDept.length>0">中间科室:{{middleDept.join(',')}}</div>
17
+          <div nz-col nzSpan="8">目标科室:
18
+            <span *ngFor="let dep of orderInfo.endDepts;let i=index;">
19
+              <span *ngIf="i!=orderInfo.endDepts.length-1">{{dep.dept}},</span>
20
+              <span *ngIf="i==orderInfo.endDepts.length-1">{{dep.dept}}</span>
21
+            </span>
22
+          </div>
23
+          <div nz-col nzSpan="8" *ngIf="orderInfo.worker">支助人员信息:{{orderInfo.worker.name}}</div>
24
+          <div nz-col nzSpan="24" *ngIf="orderInfo.specialCloseReason">
25
+            特殊情况关闭原因:{{orderInfo.specialCloseReason}}
26
+          </div>
27
+        </div>
28
+      </div>
29
+      <div class="center">
30
+        <div class="box display_flex justify-content_flex-center">
31
+          <div class="steps" *ngFor="let step of logList;let i = index;">
32
+            <div class="step">
33
+              <div class="info">
34
+                <i
35
+                  [ngClass]="{'icon_transport':true, 'transport-icon_liucheng':true,'green':(step.record&&step.record[0]&&step.record[0].operationTime)}"></i>
36
+                <p>{{step.operationName}}</p>
37
+                <p>{{step.record.length>=1?(step.record[0].operationTime|date:'MM-dd HH:mm'):''}}</p>
38
+                <p *ngIf="step.record[0]&&step.record[0].dept">
39
+                  <span *ngFor="let dept of step.record">{{dept.dept}},</span>
40
+                </p>
41
+                <p *ngIf="i!=0&&step.record&&step.record.length">耗时{{filterTime(step.record)}}</p>
42
+              </div>
43
+              <div class="line"></div>
44
+            </div>
45
+          </div>
46
+        </div>
47
+      </div>
48
+      <div class="bottom">
49
+        <div class="urgent" *ngIf="orderInfo.urgentDetails&&showCoop">
50
+          加急原因:{{orderInfo.urgentDetails.urgentReason}}
51
+          <button *ngIf="orderInfo.urgentDetails.checkStatus.id==329" nz-button nzType="primary"
52
+            [nzLoading]="urgentLoading" nzGhost (click)="urgent()">确认加急</button>
53
+        </div>
54
+        <div class="info">
55
+          <div nz-row class="top">
56
+            <div class="left" nz-col nzSpan="12">
57
+              <p>
58
+                <span class="label">患者姓名</span>
59
+                <span>{{orderInfo.patient.patientName}}</span>
60
+              </p>
61
+              <p>
62
+                <span class="label">床位</span>
63
+                <span>{{orderInfo.patient.bedNum}}</span>
64
+              </p>
65
+              <p *ngIf="orderInfo.patient.careLevel">
66
+                <span class="label">{{orderInfo.patient.careLevel.desc}}</span>
67
+                <span>{{orderInfo.patient.careLevel.name}}</span>
68
+              </p>
69
+            </div>
70
+            <div class="right" nz-col nzSpan="12">
71
+              <p>
72
+                <span class="label">患者编码</span>
73
+                <span>{{orderInfo.patient.patientCode}}</span>
74
+              </p>
75
+              <p>
76
+                <span class="label">携带物品</span>
77
+                <span>{{orderInfo.goods||'暂无'}}</span>
78
+              </p>
79
+              <p *ngIf="orderInfo.patient.illnessState">
80
+                <span class="label">{{orderInfo.patient.illnessState.desc}}</span>
81
+                <span>{{orderInfo.patient.illnessState.name}}</span>
82
+              </p>
83
+            </div>
84
+          </div>
85
+        </div>
86
+        <ng-container *ngIf="orderInfo.taskType.associationType.id==260">
87
+          <div class="info" *ngFor="let item of orderInfo.checkList">
88
+            <div nz-row class="top">
89
+              <div nz-col nzSpan="8">
90
+                <p>
91
+                  <span class="label">检查项目:</span>
92
+                  <span>
93
+                    <span>
94
+                      <span>{{item.inspectName||'-'}}</span>
95
+                    </span>
96
+                  </span>
97
+                </p>
98
+              </div>
99
+              <div nz-col nzSpan="8">
100
+                <p>
101
+                  <span class="label">预约时间:</span>
102
+                  <span>{{item.yyTime||'-'}}</span>
103
+                </p>
104
+              </div>
105
+              <div nz-col nzSpan="8">
106
+                <p>
107
+                  <span class="label">叫号信息:</span>
108
+                  <span>{{item.reservationNumber||'-'}}</span>
109
+                </p>
110
+              </div>
111
+              <div nz-col nzSpan="8">
112
+                <p>
113
+                  <span class="label">到达时间:</span>
114
+                  <span>{{item.arriveTime||'-'}}</span>
115
+                </p>
116
+              </div>
117
+              <div nz-col nzSpan="8">
118
+                <p>
119
+                  <span class="label">检查科室:</span>
120
+                  <span>{{item.execDept?item.execDept.dept:'-'}}</span>
121
+                </p>
122
+              </div>
123
+              <div nz-col nzSpan="8">
124
+                <p>
125
+                  <span class="label">是否送达:</span>
126
+                  <span>{{item.arriveTime?'是':'否'}}</span>
127
+                </p>
128
+              </div>
129
+            </div>
130
+          </div>
131
+        </ng-container>
132
+      </div>
133
+    </div>
134
+  </overlay-scrollbars>
135
+  <div class="btns display_flex justify-content_flex-center align-items_center">
136
+    <!-- <button *ngIf="showCoop&&orderInfo.gdState.id==69" nz-button nzType="primary" (click)='allotWorker()'>派单</button>
137
+    <button *ngIf="showCoop&&(orderInfo.gdState.id==70||orderInfo.gdState.id==71)" nz-button nzType="primary" nzGhost
138
+      (click)="openRecallModal()">撤回</button>
139
+    <button *ngIf="showCoop&&(orderInfo.gdState.id==69||orderInfo.gdState.id==70||orderInfo.gdState.id==71)" nz-button
140
+      nzType="danger" (click)="openDelModal()">删除</button> -->
141
+    <button class=" btn cancel" nz-button nzType="default" (click)="close()">取消</button>
142
+  </div>
143
+</div>
144
+
145
+<!-- 撤回工单 -->
146
+<div class="recallOrder display_flex justify-content_flex-center align-items_center" *ngIf="recallOrderShow">
147
+  <div class="modalBody">
148
+    <div class="title">提示<i class="icon_transport transport-guanbi" (click)="closeRecallOrderModal()"></i></div>
149
+    <div class="content">
150
+      <div class="icon"><i class="icon_transport transport-wenhao"></i></div>
151
+      <div class="defeat">您确认要撤回此工单吗?</div>
152
+    </div>
153
+    <div class="btns display_flex justify-content_flex-center">
154
+      <button nz-button nzType="primary" [nzLoading]='btnLoading' (click)="confirmRec()">确认</button>
155
+      <button nz-button nzType="primary" [nzLoading]='recLoading' nzGhost (click)="recAndDel()">撤回并删除</button>
156
+      <button class=" btn cancel" nz-button nzType="default" (click)="closeRecallOrderModal()">取消</button>
157
+    </div>
158
+  </div>
159
+</div>
160
+
161
+<!-- 删除工单 -->
162
+<div class="recallOrder delModel display_flex justify-content_flex-center align-items_center" *ngIf="delOrderShow">
163
+  <div class="modalBody">
164
+    <div class="title">提示<i class="icon_transport transport-guanbi" (click)="closeDelOrderModal()"></i></div>
165
+    <div class="content">
166
+      <div class="icon"><i class="icon_transport transport-wenhao"></i></div>
167
+      <div class="defeat">您确认要删除此工单吗?</div>
168
+    </div>
169
+    <div class="btns display_flex justify-content_flex-center">
170
+      <button nz-button nzType="primary" [nzLoading]='btnLoading' (click)="confirmDel()">确认</button>
171
+      <button class=" btn cancel" nz-button nzType="default" (click)="closeDelOrderModal()">取消</button>
172
+    </div>
173
+  </div>
174
+</div>
175
+
176
+<!-- 操作成功/失败提示框 -->
177
+<app-prompt-modal *ngIf="promptModalShow" [content]="promptContent" [success]="ifSuccess" [show]="promptModalShow"
178
+  [info]="promptInfo" (closeModel)="close()">
179
+  <!-- 2.父组件调用子组件时绑定到这个事件属性,并在事件发生时作出回应。(closeModel)="close()" -->
180
+</app-prompt-modal>
181
+<!-- 遮罩 -->
182
+<app-mask *ngIf="maskFlag"></app-mask>

+ 320 - 0
src/app/share/detail-patients/detail-patients.component.less

@@ -0,0 +1,320 @@
1
+@import "../../../../src/theme.less";
2
+:host {
3
+  width: 100%;
4
+  height: 100%;
5
+  position: fixed;
6
+  left: 0;
7
+  top: 0;
8
+  background: rgba(0, 0, 0, 0.4);
9
+  z-index: 9;
10
+  display: flex;
11
+  justify-content: center;
12
+  align-items: center;
13
+}
14
+
15
+.detail {
16
+  width: 1000px;
17
+  max-height: 580px;
18
+  border-radius: 5px;
19
+  background: #fff;
20
+  color: #333;
21
+  font-size: 14px;
22
+  padding: 12px 20px;
23
+  position: relative;
24
+  padding-bottom: 70px;
25
+
26
+  .title {
27
+    font-size: 18px;
28
+    text-align: center;
29
+    line-height: 24px;
30
+    margin: 0;
31
+    margin-bottom: 12px;
32
+    position: relative;
33
+
34
+    i {
35
+      position: absolute;
36
+      right: 0;
37
+      top: 0;
38
+      font-size: 20px;
39
+      color: #666;
40
+      cursor: pointer;
41
+      padding: 0 5px;
42
+    }
43
+  }
44
+
45
+  .content {
46
+    width: 960px;
47
+    // height: 474px;
48
+    border: 1px solid #e5e9ed;
49
+    border-radius: 5px;
50
+    overflow: hidden;
51
+
52
+    & > .top {
53
+      padding: 10px 32px;
54
+      border-bottom: 1px solid #e5e9ed;
55
+
56
+      .num {
57
+        font-size: 16px;
58
+        overflow: hidden;
59
+        margin-bottom: 6px;
60
+
61
+        .left {
62
+          float: left;
63
+          font-weight: 600;
64
+        }
65
+
66
+        .right {
67
+          float: right;
68
+        }
69
+      }
70
+
71
+      .info {
72
+        color: #666;
73
+
74
+        & > div {
75
+          margin: 4px 0;
76
+        }
77
+      }
78
+    }
79
+
80
+    & > .center {
81
+      padding: 27px 0 17px 0;
82
+      border-bottom: 1px solid #e5e9ed;
83
+      font-size: 12px;
84
+
85
+      .box {
86
+        // display: flex;
87
+        // justify-content: center;
88
+
89
+        .steps {
90
+          &:nth-last-child(1) {
91
+            .line {
92
+              display: none !important;
93
+            }
94
+          }
95
+
96
+          .step {
97
+            .info {
98
+              width: 120px;
99
+              text-align: center;
100
+              display: inline-block;
101
+              vertical-align: top;
102
+
103
+              i {
104
+                color: #e5e9ed;
105
+
106
+                &.green {
107
+                  color: @primary-color;
108
+                }
109
+              }
110
+            }
111
+
112
+            p {
113
+              margin: 0;
114
+            }
115
+
116
+            .line {
117
+              display: inline-block;
118
+              width: 60px;
119
+              height: 2px;
120
+              background: #e5e9ed;
121
+            }
122
+          }
123
+        }
124
+      }
125
+    }
126
+
127
+    & > .bottom {
128
+      padding: 28px 32px;
129
+      background: #f9fafb;
130
+
131
+      .urgent {
132
+        input {
133
+          width: 600px;
134
+        }
135
+
136
+        .candelBtn {
137
+          margin-left: 20px;
138
+        }
139
+      }
140
+
141
+      .info {
142
+        width: 100%;
143
+        height: 100%;
144
+        background: #fff;
145
+        border-radius: 5px;
146
+        border: 1px solid #e5e9ed;
147
+        padding: 24px 28px 14px 28px;
148
+        margin-bottom: 8px;
149
+
150
+        .top {
151
+          .left {
152
+            border-right: 1px dashed #e5e9ed;
153
+
154
+            p {
155
+              padding: 0 70px 0 102px;
156
+              overflow: hidden;
157
+
158
+              & > span:nth-child(1) {
159
+                float: left;
160
+              }
161
+
162
+              & > span:nth-child(2) {
163
+                float: right;
164
+                color: #666;
165
+                text-align: right;
166
+                max-width: 175px;
167
+              }
168
+            }
169
+          }
170
+
171
+          .right {
172
+            p {
173
+              padding: 0 102px 0 70px;
174
+              overflow: hidden;
175
+
176
+              span:nth-child(1) {
177
+                float: left;
178
+              }
179
+
180
+              span:nth-child(2) {
181
+                float: right;
182
+                color: #666;
183
+                text-align: right;
184
+              }
185
+            }
186
+          }
187
+        }
188
+
189
+        .wait {
190
+          text-align: center;
191
+          margin-top: 7px;
192
+
193
+          i {
194
+            font-size: 24px;
195
+            color: #62c26d;
196
+          }
197
+
198
+          span {
199
+            color: #62c26d;
200
+          }
201
+        }
202
+      }
203
+    }
204
+  }
205
+
206
+  .btns {
207
+    width: 100%;
208
+    position: absolute;
209
+    left: 0;
210
+    bottom: 20px;
211
+
212
+    button {
213
+      margin: 9px;
214
+      margin-bottom: 0;
215
+    }
216
+  }
217
+}
218
+
219
+// 撤回工单
220
+.recallOrder {
221
+  position: fixed;
222
+  left: 0;
223
+  top: 0;
224
+  width: 100%;
225
+  height: 100%;
226
+  // display: flex;
227
+  // justify-content: center;
228
+  // align-items: center;
229
+  background: rgba(0, 0, 0, 0.4);
230
+  z-index: 99;
231
+
232
+  .modalBody {
233
+    width: 350px;
234
+    height: 220px;
235
+    background: #fff;
236
+    border-radius: 5px;
237
+    padding: 10px 20px;
238
+    color: #333;
239
+
240
+    .title {
241
+      width: 100%;
242
+      text-align: center;
243
+      font-size: 18px;
244
+      position: relative;
245
+
246
+      i {
247
+        position: absolute;
248
+        right: 0;
249
+        top: 0;
250
+        font-size: 20px;
251
+        color: #666;
252
+        cursor: pointer;
253
+        padding: 0 5px;
254
+      }
255
+    }
256
+
257
+    .content {
258
+      width: 310px;
259
+      height: 117px;
260
+      background: #f9fafb;
261
+      border: 1px solid #e5e9ed;
262
+      border-radius: 5px;
263
+      overflow: hidden;
264
+      margin-top: 12px;
265
+
266
+      div {
267
+        text-align: center;
268
+        margin: 0;
269
+
270
+        &.icon {
271
+          margin-top: 17px;
272
+
273
+          i {
274
+            color: #ff3b53;
275
+            font-size: 30px !important;
276
+
277
+            &.transport-wenhao {
278
+              color: #f5a523;
279
+            }
280
+          }
281
+        }
282
+
283
+        &.defeat {
284
+          color: #333;
285
+          font-size: 18px;
286
+        }
287
+
288
+        &:nth-child(3) {
289
+          font-size: 14px;
290
+          color: #666;
291
+        }
292
+      }
293
+
294
+      .conditions {
295
+        padding: 16px 20px;
296
+
297
+        div {
298
+          text-align: left;
299
+        }
300
+      }
301
+    }
302
+
303
+    .btns {
304
+      // display: flex;
305
+      // justify-content: center;
306
+
307
+      button {
308
+        margin-top: 10px;
309
+
310
+        &.btn {
311
+          margin-left: 8px;
312
+        }
313
+      }
314
+    }
315
+  }
316
+}
317
+
318
+.txtC {
319
+  text-align: center;
320
+}

+ 230 - 0
src/app/share/detail-patients/detail-patients.component.ts

@@ -0,0 +1,230 @@
1
+import { Component, OnInit, ViewChild } from '@angular/core';
2
+import { ActivatedRoute, Router } from '@angular/router';
3
+import { MainService } from '../../services/main.service';
4
+import { OverlayScrollbarsComponent } from 'overlayscrollbars-ngx';
5
+import { NzMessageService } from 'ng-zorro-antd';
6
+import { forkJoin } from 'rxjs';
7
+
8
+@Component({
9
+  selector: 'app-detail-patients',
10
+  templateUrl: './detail-patients.component.html',
11
+  styleUrls: ['./detail-patients.component.less']
12
+})
13
+export class DetailPatientsComponent implements OnInit {
14
+  @ViewChild('osComponentRef1', { read: OverlayScrollbarsComponent, static: false })
15
+  osComponentRef1: OverlayScrollbarsComponent;
16
+  constructor(
17
+    private message: NzMessageService,
18
+    private route: ActivatedRoute,
19
+    private router: Router,
20
+    private mainService: MainService) { }
21
+
22
+  id: number;//工单id
23
+  orderInfo: any;//工单详情信息
24
+  showCoop: boolean = true;//是否展示详情页操作按钮
25
+
26
+  promptContent: string;//操作提示框提示信息
27
+  ifSuccess: boolean;//操作成功/失败
28
+  promptInfo: string;//操作结果提示信息
29
+  promptModalShow: boolean;//是否展示提示框
30
+
31
+  urgentLoading: boolean = false;//确认加急按钮loading状态
32
+  recLoading: boolean = false;//撤回并删除按钮loading状态
33
+  btnLoading: boolean = false;//确认按钮loading状态
34
+  maskFlag: any = false;
35
+  ngOnInit() {
36
+    if (this.route.snapshot.parent.parent.routeConfig.path == 'nurse') {
37
+      this.showCoop = false;
38
+    }
39
+    this.id = +this.route.snapshot.paramMap.get('id');
40
+    let log$ = this.getLog();
41
+    let detail$ = this.getDetail();
42
+    this.maskFlag = this.message.loading('正在加载中..', { nzDuration: 0 }).messageId;
43
+    forkJoin(log$, detail$).subscribe(res => {
44
+      this.message.remove(this.maskFlag);
45
+      this.maskFlag = false;
46
+      // getLog
47
+      this.logList = res[0]['data'];
48
+      // getDetail
49
+      this.orderInfo = res[1]['data'];
50
+      if (this.orderInfo['checkList'] && this.orderInfo['checkList'].length) {
51
+        let arr = [];
52
+        let orderInfo = this.orderInfo['checkList'].filter(item => item.yyTime);
53
+        if (orderInfo.length) {
54
+          arr = orderInfo.map(item => [(new Date(item.yyTime)).getTime() - (new Date()).getTime(), item.yyTime]);
55
+          arr.sort((a, b) => (a - b));
56
+          this.orderInfo['yyTime'] = arr[0][1];
57
+        } else {
58
+          this.orderInfo['yyTime'] = '';
59
+        }
60
+      } else {
61
+        this.orderInfo['yyTime'] = '';
62
+      }
63
+      if (res[1]['data'].middleDept) {
64
+        this.middleDept = res[1]['data'].middleDept.map(item => item.dept);
65
+      } else {
66
+        this.middleDept = [];
67
+      }
68
+    })
69
+  }
70
+  // 获取工单详情
71
+  middleDept = [];//中间科室数组
72
+  getDetail() {
73
+    return this.mainService.getApiFetchData('workOrder', this.id);
74
+  }
75
+  // 获取工单历史记录
76
+  logList = [];//工单历史记录
77
+  getLog() {
78
+    return this.mainService.getWorkOrderLog(this.id);
79
+  }
80
+
81
+  // 加急
82
+  urgent() {
83
+    let that = this;
84
+    that.urgentLoading = true;
85
+    let postData = {
86
+      urgentDetails: {
87
+        workerOrder: that.id,
88
+        checkStatus: { id: 330 },
89
+        urgentReason: that.orderInfo['urgentDetails']['urgentReason'],
90
+        id: that.orderInfo['urgentDetails']['id']
91
+      }
92
+    }
93
+    that.mainService.postCustom('workerOrder', 'urge', postData).subscribe(data => {
94
+      console.log(data);
95
+      that.urgentLoading = false;
96
+      if (data.status == 200) {
97
+        that.showPromptModal('加急', true, '');
98
+      } else {
99
+        that.showPromptModal('加急', false, data.msg);
100
+      }
101
+    })
102
+  }
103
+
104
+  // 派单
105
+  allotWorker() {
106
+    this.router.navigateByUrl('dispatchingDesk/allotWorker/' + this.id + '/' + this.orderInfo['gdState']['id']);
107
+  }
108
+
109
+  // 撤回
110
+  recallOrderShow: boolean = false;
111
+  openRecallModal(): void {
112
+    this.recallOrderShow = true;
113
+  }
114
+  // 确认撤回
115
+  confirmRec() {
116
+    let that = this;
117
+    that.btnLoading = true;
118
+    let postData = {
119
+      workOrder: {
120
+        id: that.id
121
+      }
122
+    }
123
+    that.mainService.coopWorkerOrder('excuteWorkOrder/recall', postData).subscribe(data => {
124
+      that.btnLoading = false;
125
+      that.closeRecallOrderModal()
126
+      if (data.status == 200) {
127
+        that.showPromptModal('撤回', true, '');
128
+      } else {
129
+        that.showPromptModal('撤回', false, data.msg);
130
+      }
131
+    })
132
+  }
133
+  // 撤回并删除
134
+  recAndDel() {
135
+    let that = this;
136
+    that.recLoading = true;
137
+    that.mainService.delOrder(that.id).subscribe(data => {
138
+      console.log(data);
139
+      that.recLoading = false;
140
+      that.closeDelOrderModal()
141
+      if (data.status == 200) {
142
+        that.showPromptModal('删除', true, '');
143
+      } else {
144
+        that.showPromptModal('删除', false, data.msg);
145
+      }
146
+    })
147
+  }
148
+  // 关闭撤回弹框
149
+  closeRecallOrderModal() {
150
+    this.recallOrderShow = false;
151
+  }
152
+
153
+  // 关闭弹框
154
+  close() {
155
+    // this.router.navigateByUrl('dispatchingDesk');
156
+    history.go(-1)
157
+  }
158
+
159
+  // 删除
160
+  // 打开模态框
161
+  delOrderShow: boolean = false;
162
+  openDelModal() {
163
+    this.delOrderShow = true;
164
+  }
165
+  // 确认删除
166
+  confirmDel() {
167
+    let that = this;
168
+    that.btnLoading = true;
169
+    that.mainService.delOrder(that.id).subscribe(data => {
170
+      that.closeDelOrderModal()
171
+      that.btnLoading = false;
172
+      if (data.status == 200) {
173
+        that.showPromptModal('删除', true, '');
174
+      } else {
175
+        that.showPromptModal('删除', false, data.msg);
176
+      }
177
+    })
178
+  }
179
+
180
+  // 关闭模态框
181
+  closeDelOrderModal() {
182
+    this.delOrderShow = false;
183
+  }
184
+
185
+
186
+
187
+
188
+  // 展示信息提示框(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)
189
+  showPromptModal(con, success, promptInfo?) {
190
+    this.promptModalShow = false;
191
+    this.promptContent = con;
192
+    this.ifSuccess = success;
193
+    this.promptInfo = promptInfo;
194
+    setTimeout(() => {
195
+      this.promptModalShow = true;
196
+    }, 100);
197
+  }
198
+
199
+  // 格式化时分秒
200
+  // (时间小于一分钟则显示秒,时间大于一分钟则显示分钟数,如超出一小时则显示小时和分钟。)time单位:秒
201
+  formatTime(time) {
202
+    let timeStr = '';
203
+    if (time >= 0 && time < 60) {
204
+      // 秒
205
+      timeStr = time + '秒';
206
+    } else if (time >= 60 && time < 3600) {
207
+      // 分钟
208
+      timeStr = Math.floor(time / 60) + '分钟'
209
+    } else if (time >= 3600) {
210
+      // 时 + 分
211
+      let h = '';
212
+      let m = '';
213
+      h = Math.floor(time / 3600) + '小时';
214
+      m = (time % 3600) >= 60 ? Math.floor((time % 3600) / 60) + '分钟' : '';
215
+      timeStr = h + m;
216
+    }
217
+    return timeStr;
218
+  }
219
+
220
+  // 计算历史记录耗时
221
+  filterTime(step) {
222
+    // step = [{ difTime: 2 }, { difTime: 6 }]
223
+    let num = 0;
224
+    step.forEach(e => {
225
+      num += e.difTime;
226
+    });
227
+    return this.formatTime(num / 1000);
228
+  }
229
+}
230
+

+ 133 - 0
src/app/share/detail-sample/detail-sample.component.html

@@ -0,0 +1,133 @@
1
+<!-- 标本 -->
2
+<div class="detail" *ngIf="!maskFlag">
3
+  <div class="title">工单信息<i class="icon_transport transport-guanbi" (click)="close()"></i></div>
4
+  <div class="content">
5
+    <div class="top">
6
+      <div class="num">
7
+        <span class="left">单号:{{orderInfo.gdcode}}</span>
8
+        <span class="right">{{orderInfo.gdState.name}}</span>
9
+      </div>
10
+      <div class="info" nz-row>
11
+        <div nz-col nzSpan="8">工单日期:{{orderInfo.startTime}}</div>
12
+        <div nz-col nzSpan="8">总耗时:{{orderInfo.showTimeNum}}</div>
13
+        <div nz-col nzSpan="8">申请类型:{{orderInfo.taskType.taskName}}</div>
14
+        <div nz-col nzSpan="8">预计接收:{{orderInfo.expectReceiveNum?orderInfo.expectReceiveNum:''}}</div>
15
+
16
+        <div nz-col nzSpan="8">申请科室:{{orderInfo.createDeptDTO.dept}}</div>
17
+        <div nz-col nzSpan="8">目标科室:{{endDepts}}</div>
18
+        <div nz-col nzSpan="8" *ngIf="orderInfo.worker">支助人员信息:{{orderInfo.worker.name}}</div>
19
+        <div nz-col nzSpan="8">实际接收:{{orderInfo.actualReceiveNum?orderInfo.actualReceiveNum:''}}</div>
20
+        <div nz-col nzSpan="24" *ngIf="orderInfo.specialCloseReason">
21
+          特殊情况关闭原因:{{orderInfo.specialCloseReason}}
22
+        </div>
23
+      </div>
24
+    </div>
25
+    <div class="center">
26
+      <div class="box display_flex justify-content_flex-center">
27
+        <div class="steps" *ngFor="let step of logList;let i=index;">
28
+          <div class="step">
29
+            <div class="info">
30
+              <i
31
+                [ngClass]="{'icon_transport':true, 'transport-icon_liucheng':true,'green':(step.record&&step.record[0]&&step.record[0].operationTime)}"></i>
32
+              <p>{{step.operationName}}</p>
33
+              <p>{{step.record.length>=1?(step.record[0].operationTime|date:'MM-dd HH:mm'):''}}</p>
34
+              <p *ngIf="step.record[0]&&step.record[0].dept">
35
+                <span *ngFor="let dept of step.record">{{dept.dept}},</span>
36
+              </p>
37
+              <p *ngIf="i!=0&&step.record&&step.record.length">耗时{{filterTime(step.record)}}</p>
38
+            </div>
39
+            <div class="line"></div>
40
+          </div>
41
+        </div>
42
+      </div>
43
+    </div>
44
+    <div class="bottom">
45
+      <div class="urgent" *ngIf="orderInfo.urgentDetails&&showCoop">
46
+        加急原因:{{orderInfo.urgentDetails.urgentReason}}
47
+        <button *ngIf="orderInfo.urgentDetails.checkStatus.id==329" class=" btn default" nz-button nzType="primary"
48
+          [nzLoading]="urgentLoading" nzGhost (click)="urgent()">确认加急</button>
49
+      </div>
50
+      <div class="table">
51
+        <nz-table class="detailSampleTable" [nzData]="orderInfo.specimenSet" nzSize="small" [nzScroll]="{ y: '105px' }"
52
+          [nzShowPagination]="null">
53
+          <thead>
54
+            <tr class="thead">
55
+              <th nzWidth="50px">序号</th>
56
+              <th nzWidth="95px">标本类型</th>
57
+              <th nzWidth="110px">标本编码</th>
58
+              <th nzWidth="88px">患者姓名</th>
59
+              <th nzWidth="50px">床号</th>
60
+              <th nzWidth="88px">目标科室</th>
61
+              <th nzWidth="75px">是否接收</th>
62
+              <th nzWidth="75px">是否送达</th>
63
+              <th nzWidth="123px">接收扫描时间</th>
64
+              <th nzWidth="123px">送达扫描时间</th>
65
+            </tr>
66
+          </thead>
67
+          <tbody *ngIf="orderInfo.specimenSet">
68
+            <tr *ngFor="let data of orderInfo.specimenSet;let i =index;">
69
+              <td>{{i+1}}</td>
70
+              <td>{{data.stype.name}}</td>
71
+              <td>{{data.scode}}</td>
72
+              <td>{{data.patientName}}</td>
73
+              <td>{{data.bedNum}}</td>
74
+              <td>{{data.checkDept.dept}}</td>
75
+              <td>{{data.received?"是":"否"}}</td>
76
+              <td>{{data.arrived?"是":"否"}}</td>
77
+              <td>{{data.arriveTime?data.arriveTime:'-'}}</td>
78
+              <td style="position: relative;">{{data.sendTime?data.sendTime:'-'}}<img *ngIf="data.urgent == 1"
79
+                  src="../../assets/images/icon_ji.png" alt="" class="ji"></td>
80
+            </tr>
81
+          </tbody>
82
+        </nz-table>
83
+      </div>
84
+    </div>
85
+  </div>
86
+  <div class="btns display_flex justify-content_flex-center align-items_center">
87
+    <!-- <button *ngIf="showCoop&&orderInfo.gdState.value==2" nz-button nzType="primary" (click)='allotWorker()'>派单</button>
88
+    <button *ngIf="showCoop&&(orderInfo.gdState.value==3||orderInfo.gdState.value==4)" nz-button nzType="primary" nzGhost
89
+      (click)="openRecallModal()">撤回</button>
90
+    <button *ngIf="showCoop&&(orderInfo.gdState.value==2||orderInfo.gdState.value==3||orderInfo.gdState.value==4)" nz-button
91
+      nzType="danger" (click)="openDelModal()">删除</button> -->
92
+    <button class=" btn cancel" nz-button nzType="default" (click)="close()">取消</button>
93
+  </div>
94
+</div>
95
+<!-- 撤回工单 -->
96
+<div class="recallOrder display_flex justify-content_flex-center align-items_center" *ngIf="recallOrderShow">
97
+  <div class="modalBody">
98
+    <div class="title">提示<i class="icon_transport transport-guanbi" (click)="closeRecallOrderModal()"></i></div>
99
+    <div class="content">
100
+      <div class="icon"><i class="icon_transport transport-wenhao"></i></div>
101
+      <div class="defeat">您确认要撤回此工单吗?</div>
102
+    </div>
103
+    <div class="btns display_flex justify-content_flex-center align-items_center">
104
+      <button nz-button nzType="primary" [nzLoading]='btnLoading' (click)="confirmRec()">确认</button>
105
+      <button nz-button nzType="primary" [nzLoading]='recLoading' nzGhost (click)="recAndDel()">撤回并删除</button>
106
+      <button class=" btn cancel" nz-button nzType="default" (click)="closeRecallOrderModal()">关闭</button>
107
+    </div>
108
+  </div>
109
+</div>
110
+
111
+<!-- 删除工单 -->
112
+<div class="recallOrder display_flex justify-content_flex-center align-items_center delModel" *ngIf="delOrderShow">
113
+  <div class="modalBody">
114
+    <div class="title">提示<i class="icon_transport transport-guanbi" (click)="closeDelOrderModal()"></i></div>
115
+    <div class="content">
116
+      <div class="icon"><i class="icon_transport transport-wenhao"></i></div>
117
+      <div class="defeat">您确认要删除此工单吗?</div>
118
+    </div>
119
+    <div class="btns display_flex justify-content_flex-center">
120
+      <button nz-button nzType="primary" [nzLoading]='btnLoading' (click)="confirmDel()">确认</button>
121
+      <!-- <button class="candelBtn btn display_flex justify-content_flex-center" nz-button nzType="primary" nzGhost>撤回并删除</button> -->
122
+      <button class=" btn cancel" nz-button nzType="default" (click)="closeDelOrderModal()">取消</button>
123
+    </div>
124
+  </div>
125
+</div>
126
+
127
+<!-- 操作成功/失败提示框 -->
128
+<app-prompt-modal *ngIf="promptModalShow" [content]="promptContent" [success]="ifSuccess" [show]="promptModalShow"
129
+  [info]="promptInfo" (closeModel)="close()">
130
+  <!-- 2.父组件调用子组件时绑定到这个事件属性,并在事件发生时作出回应。(closeModel)="close()" -->
131
+</app-prompt-modal>
132
+<!-- 遮罩 -->
133
+<app-mask *ngIf="maskFlag"></app-mask>

+ 303 - 0
src/app/share/detail-sample/detail-sample.component.less

@@ -0,0 +1,303 @@
1
+@import "../../../../src/theme.less";
2
+:host {
3
+  width: 100%;
4
+  height: 100%;
5
+  position: fixed;
6
+  left: 0;
7
+  top: 0;
8
+  background: rgba(0, 0, 0, 0.4);
9
+  z-index: 9;
10
+  display: flex;
11
+  justify-content: center;
12
+  align-items: center;
13
+}
14
+
15
+.detail {
16
+  width: 1000px;
17
+  min-height: 580px;
18
+  border-radius: 5px;
19
+  background: #fff;
20
+  color: #333;
21
+  font-size: 14px;
22
+  padding: 12px 20px;
23
+  position: relative;
24
+  padding-bottom: 70px;
25
+
26
+  .title {
27
+    font-size: 18px;
28
+    text-align: center;
29
+    line-height: 24px;
30
+    margin: 0;
31
+    margin-bottom: 12px;
32
+    position: relative;
33
+
34
+    i {
35
+      position: absolute;
36
+      right: 0;
37
+      top: 0;
38
+      font-size: 20px;
39
+      color: #666;
40
+      cursor: pointer;
41
+      padding: 0 5px;
42
+    }
43
+  }
44
+
45
+  .content {
46
+    width: 960px;
47
+    // height: 474px;
48
+    border: 1px solid #e5e9ed;
49
+    border-radius: 5px;
50
+    overflow: hidden;
51
+
52
+    & > .top {
53
+      padding: 10px 32px;
54
+      border-bottom: 1px solid #e5e9ed;
55
+
56
+      .num {
57
+        font-size: 16px;
58
+        overflow: hidden;
59
+        margin-bottom: 6px;
60
+
61
+        .left {
62
+          float: left;
63
+          font-weight: 600;
64
+        }
65
+
66
+        .right {
67
+          float: right;
68
+        }
69
+      }
70
+
71
+      .info {
72
+        color: #666;
73
+
74
+        & > div {
75
+          margin: 4px 0;
76
+        }
77
+      }
78
+    }
79
+
80
+    & > .center {
81
+      padding: 27px 0 17px 0;
82
+      border-bottom: 1px solid #e5e9ed;
83
+      font-size: 12px;
84
+
85
+      .box {
86
+        // display: flex;
87
+        // justify-content: center;
88
+
89
+        .steps {
90
+          &:nth-last-child(1) {
91
+            .line {
92
+              display: none !important;
93
+            }
94
+          }
95
+
96
+          .step {
97
+            .info {
98
+              width: 90px;
99
+              text-align: center;
100
+              display: inline-block;
101
+              vertical-align: top;
102
+
103
+              i {
104
+                color: #e5e9ed;
105
+
106
+                &.green {
107
+                  color: @primary-color;
108
+                }
109
+              }
110
+            }
111
+
112
+            p {
113
+              margin: 0;
114
+            }
115
+
116
+            .line {
117
+              display: inline-block;
118
+              width: 60px;
119
+              height: 2px;
120
+              background: #e5e9ed;
121
+            }
122
+          }
123
+        }
124
+      }
125
+    }
126
+
127
+    & > .bottom {
128
+      padding: 28px 32px;
129
+      background: #f9fafb;
130
+
131
+      .urgent {
132
+        input {
133
+          width: 600px;
134
+        }
135
+
136
+        .candelBtn {
137
+          margin-left: 20px;
138
+        }
139
+      }
140
+
141
+      .table {
142
+        width: 100%;
143
+        background: #fff;
144
+        border-radius: 5px;
145
+
146
+        .thead {
147
+          background: linear-gradient(to right, @bg-start, @bg-end) !important;
148
+          th {
149
+            color: #fff !important;
150
+            text-align: center;
151
+            font-size: 12px;
152
+            border: none;
153
+          }
154
+        }
155
+
156
+        .ant-table-tbody {
157
+          tr {
158
+            text-align: center;
159
+            font-size: 12px;
160
+            border: none;
161
+
162
+            td {
163
+              border: none;
164
+            }
165
+          }
166
+
167
+          tr:nth-child(2n) {
168
+            background: #f9fafb;
169
+          }
170
+        }
171
+      }
172
+    }
173
+  }
174
+
175
+  .btns {
176
+    // display: flex;
177
+    // justify-content: center;
178
+    // align-items: center;
179
+    width: 100%;
180
+    position: absolute;
181
+    left: 0;
182
+    bottom: 20px;
183
+
184
+    button {
185
+      margin: 9px;
186
+      margin-bottom: 0;
187
+    }
188
+  }
189
+
190
+  .ant-table {
191
+    border: none !important;
192
+  }
193
+}
194
+
195
+// 撤回工单
196
+.recallOrder {
197
+  position: fixed;
198
+  left: 0;
199
+  top: 0;
200
+  width: 100%;
201
+  height: 100%;
202
+  // display: flex;
203
+  // justify-content: center;
204
+  // align-items: center;
205
+  background: rgba(0, 0, 0, 0.4);
206
+  z-index: 99;
207
+
208
+  .modalBody {
209
+    width: 350px;
210
+    height: 220px;
211
+    background: #fff;
212
+    border-radius: 5px;
213
+    padding: 10px 20px;
214
+    color: #333;
215
+
216
+    .title {
217
+      width: 100%;
218
+      text-align: center;
219
+      font-size: 18px;
220
+      position: relative;
221
+
222
+      i {
223
+        position: absolute;
224
+        right: 0;
225
+        top: 0;
226
+        font-size: 20px;
227
+        color: #666;
228
+        cursor: pointer;
229
+        padding: 0 5px;
230
+      }
231
+    }
232
+
233
+    .content {
234
+      width: 310px;
235
+      height: 117px;
236
+      background: #f9fafb;
237
+      border: 1px solid #e5e9ed;
238
+      border-radius: 5px;
239
+      overflow: hidden;
240
+      margin-top: 12px;
241
+
242
+      div {
243
+        text-align: center;
244
+        margin: 0;
245
+
246
+        &.icon {
247
+          margin-top: 17px;
248
+
249
+          i {
250
+            color: #ff3b53;
251
+            font-size: 30px !important;
252
+
253
+            &.transport-wenhao {
254
+              color: #f5a523;
255
+            }
256
+          }
257
+        }
258
+
259
+        &.defeat {
260
+          color: #333;
261
+          font-size: 18px;
262
+        }
263
+
264
+        &:nth-child(3) {
265
+          font-size: 14px;
266
+          color: #666;
267
+        }
268
+      }
269
+
270
+      .conditions {
271
+        padding: 16px 20px;
272
+
273
+        div {
274
+          text-align: left;
275
+        }
276
+      }
277
+    }
278
+
279
+    .btns {
280
+      // display: flex;
281
+      // justify-content: center;
282
+
283
+      button {
284
+        margin-top: 10px;
285
+
286
+        &.btn {
287
+          width: 80px;
288
+          margin-left: 8px;
289
+        }
290
+      }
291
+    }
292
+  }
293
+}
294
+
295
+.txtC {
296
+  text-align: center;
297
+}
298
+.ji {
299
+  position: absolute;
300
+  right: 0px;
301
+  top: -3px;
302
+  width: 30px;
303
+}

+ 212 - 0
src/app/share/detail-sample/detail-sample.component.ts

@@ -0,0 +1,212 @@
1
+import { Component, OnInit } from '@angular/core';
2
+import { ActivatedRoute, Router } from '@angular/router';
3
+import { MainService } from '../../services/main.service';
4
+import { forkJoin } from 'rxjs';
5
+import { NzMessageService } from 'ng-zorro-antd';
6
+
7
+
8
+@Component({
9
+  selector: 'app-detail-sample',
10
+  templateUrl: './detail-sample.component.html',
11
+  styleUrls: ['./detail-sample.component.less']
12
+})
13
+export class DetailSampleComponent implements OnInit {
14
+
15
+  constructor(
16
+    private message: NzMessageService,
17
+    private route: ActivatedRoute,
18
+    private router: Router,
19
+    private mainService: MainService) { }
20
+
21
+  id: number;//工单id
22
+  orderInfo: any;//工单详情信息
23
+  endDepts = '';//工单详情目标科室
24
+  showCoop: boolean = true;//是否展示详情页操作按钮
25
+
26
+  promptContent: string;//操作提示框提示信息
27
+  ifSuccess: boolean;//操作成功/失败
28
+  promptInfo: string;//操作结果提示信息
29
+  promptModalShow: boolean;//是否展示提示框
30
+
31
+  urgentLoading: boolean = false;//确认加急按钮loading状态
32
+  recLoading: boolean = false;//撤回并删除按钮loading状态
33
+  btnLoading: boolean = false;//确认按钮loading状态
34
+  maskFlag: any = false;
35
+  ngOnInit() {
36
+    if (this.route.snapshot.parent.parent.routeConfig.path == 'nurse') {
37
+      this.showCoop = false;
38
+    }
39
+    this.id = +this.route.snapshot.paramMap.get('id');
40
+    let log$ = this.getLog();
41
+    let detail$ = this.getDetail();
42
+    this.maskFlag = this.message.loading('正在加载中..', { nzDuration: 0 }).messageId;
43
+    forkJoin(log$, detail$).subscribe(res => {
44
+      this.message.remove(this.maskFlag);
45
+      this.maskFlag = false;
46
+      // getLog
47
+      this.logList = res[0]['data'];
48
+      // getDetail
49
+      this.orderInfo = res[1]['data'];
50
+      this.endDepts = res[1]['data'].endDepts.map(item => item.dept).join();
51
+    })
52
+  }
53
+
54
+  // 获取工单详情
55
+  getDetail() {
56
+    return this.mainService.getApiFetchData('workOrder', this.id);
57
+  }
58
+
59
+  // 确认加急
60
+  urgent() {
61
+    let that = this;
62
+    that.urgentLoading = true;
63
+    let postData = {
64
+      "urgentDetails": {
65
+        "workerOrder": this.orderInfo['id'],
66
+        "checkStatus": {
67
+          "id": 330
68
+        },
69
+        "urgentReason": this.orderInfo['urgentDetails'].urgentReason,
70
+        "id": this.orderInfo['urgentDetails'].id
71
+      }
72
+    }
73
+    that.mainService.coopWorkerOrder('urge', postData).subscribe(data => {
74
+      that.urgentLoading = false;
75
+      if (data.status == 200) {
76
+        that.showPromptModal('加急', true, '');
77
+      } else {
78
+        that.showPromptModal('加急', false, data.msg);
79
+      }
80
+    })
81
+  }
82
+  // 获取工单历史记录
83
+  logList = [];//工单历史记录
84
+  getLog() {
85
+    return this.mainService.getWorkOrderLog(this.id);
86
+  }
87
+
88
+  // 派单
89
+  allotWorker() {
90
+    this.router.navigateByUrl('dispatchingDesk/allotWorker/' + this.id + '/' + this.orderInfo['gdState']['id']);
91
+  }
92
+
93
+  // 撤回
94
+  recallOrderShow: boolean = false;
95
+  openRecallModal(): void {
96
+    this.recallOrderShow = true;
97
+  }
98
+  // 确认撤回
99
+  confirmRec() {
100
+    let that = this;
101
+    that.btnLoading = true;
102
+    let postData = {
103
+      workOrder: {
104
+        id: that.id
105
+      }
106
+    }
107
+    that.mainService.coopWorkerOrder('excuteWorkOrder/recall', postData).subscribe(data => {
108
+      that.btnLoading = false;
109
+      that.closeRecallOrderModal()
110
+      if (data.status == 200) {
111
+        that.showPromptModal('撤回', true, '');
112
+      } else {
113
+        that.showPromptModal('撤回', false, data.msg);
114
+      }
115
+    })
116
+  }
117
+  // 撤回并删除
118
+  recAndDel() {
119
+    let that = this;
120
+    that.recLoading = true;
121
+    that.mainService.delOrder(that.id).subscribe(data => {
122
+      console.log(data);
123
+      that.recLoading = false;
124
+      that.closeDelOrderModal()
125
+      if (data.status == 200) {
126
+        that.showPromptModal('删除', true, '');
127
+      } else {
128
+        that.showPromptModal('删除', false, data.msg);
129
+      }
130
+    })
131
+  }
132
+  // 关闭撤回弹框
133
+  closeRecallOrderModal() {
134
+    this.recallOrderShow = false;
135
+  }
136
+
137
+  // 关闭弹框
138
+  close() {
139
+    // this.router.navigateByUrl('dispatchingDesk');
140
+    history.go(-1)
141
+  }
142
+
143
+  // 删除
144
+  // 打开模态框
145
+  delOrderShow: boolean = false;
146
+  openDelModal() {
147
+    this.delOrderShow = true;
148
+  }
149
+  // 确认删除
150
+  confirmDel() {
151
+    let that = this;
152
+    that.btnLoading = true;
153
+    that.mainService.delOrder(that.id).subscribe(data => {
154
+      that.btnLoading = false;
155
+      that.closeDelOrderModal()
156
+      if (data.status == 200) {
157
+        that.showPromptModal('删除', true, '');
158
+      } else {
159
+        that.showPromptModal('删除', false, data.msg);
160
+      }
161
+    })
162
+  }
163
+
164
+  // 关闭模态框
165
+  closeDelOrderModal() {
166
+    this.delOrderShow = false;
167
+  }
168
+
169
+  // 展示信息提示框(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)
170
+  showPromptModal(con, success, promptInfo?) {
171
+    this.promptModalShow = false;
172
+    this.promptContent = con;
173
+    this.ifSuccess = success;
174
+    this.promptInfo = promptInfo;
175
+    setTimeout(() => {
176
+      this.promptModalShow = true;
177
+    }, 100);
178
+  }
179
+
180
+
181
+  // 格式化时分秒
182
+  // (时间小于一分钟则显示秒,时间大于一分钟则显示分钟数,如超出一小时则显示小时和分钟。)time单位:秒
183
+  formatTime(time) {
184
+    let timeStr = '';
185
+    if (time >= 0 && time < 60) {
186
+      // 秒
187
+      timeStr = time + '秒';
188
+    } else if (time >= 60 && time < 3600) {
189
+      // 分钟
190
+      timeStr = Math.floor(time / 60) + '分钟'
191
+    } else if (time >= 3600) {
192
+      // 时 + 分
193
+      let h = '';
194
+      let m = '';
195
+      h = Math.floor(time / 3600) + '小时';
196
+      m = (time % 3600) >= 60 ? Math.floor((time % 3600) / 60) + '分钟' : '';
197
+      timeStr = h + m;
198
+    }
199
+    return timeStr;
200
+  }
201
+
202
+
203
+  // 计算历史记录耗时
204
+  filterTime(step) {
205
+    // step = [{ difTime: 2 }, { difTime: 6 }]
206
+    let num = 0;
207
+    step.forEach(e => {
208
+      num += e.difTime;
209
+    });
210
+    return this.formatTime(num / 1000);
211
+  }
212
+}

+ 15 - 0
src/app/share/dialog-delete/dialog-delete.component.html

@@ -0,0 +1,15 @@
1
+<!-- 删除模态框 -->
2
+<div class="dialog-delete" *ngIf="delModal">
3
+  <div class="modalBody">
4
+    <div class="title">提示<i class="icon_transport transport-guanbi" (click)="hideDelModal()"></i></div>
5
+    <div class="content">
6
+      <div class="icon"><i class="icon_transport transport-wenhao"></i></div>
7
+      <div class="defeat">{{content}}</div>
8
+      <div class="tips red" *ngIf="tips">({{tips}})</div>
9
+    </div>
10
+    <div class="operate">
11
+      <button nz-button nzType="primary" (click)="confirmDel()" [nzLoading]="btnLoading">确认</button>
12
+      <button class="btn cancel ml8" nz-button nzType="default" (click)="hideDelModal()">取消</button>
13
+    </div>
14
+  </div>
15
+</div>

+ 174 - 0
src/app/share/dialog-delete/dialog-delete.component.less

@@ -0,0 +1,174 @@
1
+.dialog-delete {
2
+  display: flex;
3
+  justify-content: center;
4
+  align-items: center;
5
+  position: fixed;
6
+  left: 0;
7
+  top: 0;
8
+  width: 100%;
9
+  height: 100%;
10
+  background: rgba(0, 0, 0, 0.4);
11
+  z-index: 99;
12
+
13
+  .modalBody {
14
+    width: 350px;
15
+    height: 220px;
16
+    background: #fff;
17
+    border-radius: 8px;
18
+    padding: 8px 16px;
19
+    color: #333;
20
+    display: flex;
21
+    flex-direction: column;
22
+
23
+    .title {
24
+      text-align: center;
25
+      font-size: 18px;
26
+      position: relative;
27
+
28
+      i {
29
+        position: absolute;
30
+        right: 0;
31
+        top: 0;
32
+        font-size: 20px;
33
+        color: #666;
34
+        cursor: pointer;
35
+        padding: 0 5px;
36
+      }
37
+    }
38
+
39
+    .content {
40
+      flex: 1;
41
+      background: #f9fafb;
42
+      border: 1px solid #e5e9ed;
43
+      border-radius: 8px;
44
+      margin-top: 8px;
45
+      display: flex;
46
+      flex-direction: column;
47
+      align-items: center;
48
+      justify-content: center;
49
+
50
+      & > div {
51
+        text-align: center;
52
+        margin: 0;
53
+
54
+        &.icon {
55
+          i {
56
+            color: #34b349;
57
+            font-size: 30px !important;
58
+
59
+            &.transport-wenhao {
60
+              color: #f5a523;
61
+            }
62
+
63
+            &.transport-shibai {
64
+              color: #ff3a52;
65
+            }
66
+          }
67
+        }
68
+
69
+        &.defeat {
70
+          color: #333;
71
+          font-size: 16px;
72
+        }
73
+        &.tips {
74
+          font-size: 14px;
75
+        }
76
+
77
+        &:nth-child(3) {
78
+          font-size: 14px;
79
+          color: #666;
80
+        }
81
+      }
82
+    }
83
+    .operate {
84
+      display: flex;
85
+      justify-content: center;
86
+      align-items: center;
87
+      margin-top: 8px;
88
+    }
89
+  }
90
+
91
+  // 新增
92
+  &.add {
93
+    .modalBody {
94
+      width: 480px;
95
+      height: auto;
96
+
97
+      .content {
98
+        width: 100%;
99
+        height: auto;
100
+        padding: 18px 14px 0 14px;
101
+        max-height: 497px;
102
+        overflow-y: auto;
103
+
104
+        .addForm {
105
+          .ant-form-item {
106
+            margin-bottom: 15px;
107
+
108
+            .ant-form-item-label {
109
+              line-height: 14px;
110
+              text-align: left;
111
+            }
112
+
113
+            .desc {
114
+              margin-top: 5px;
115
+            }
116
+          }
117
+
118
+          .datesControl {
119
+            margin-top: -16px;
120
+
121
+            .ant-form-item-label {
122
+              line-height: 40px;
123
+            }
124
+
125
+            .datesGroup {
126
+              margin-left: 125px;
127
+            }
128
+          }
129
+
130
+          .timer {
131
+            // display: inline-block;
132
+            // width: 50%;
133
+
134
+            .ant-form-item-label {
135
+              width: 100%;
136
+              text-align: left;
137
+            }
138
+
139
+            .numInp {
140
+              margin-right: 5px;
141
+            }
142
+
143
+            .line {
144
+              margin-right: 5px;
145
+            }
146
+          }
147
+
148
+          .timer2 {
149
+            .ant-form-item-label {
150
+              line-height: 20px;
151
+            }
152
+          }
153
+        }
154
+
155
+        .editForm {
156
+          .ant-form-item {
157
+            margin-bottom: 15px;
158
+
159
+            .ant-form-item-label {
160
+              line-height: 14px;
161
+              text-align: left;
162
+            }
163
+          }
164
+        }
165
+      }
166
+
167
+      button {
168
+        &:nth-child(1) {
169
+          margin-right: 20px;
170
+        }
171
+      }
172
+    }
173
+  }
174
+}

+ 28 - 0
src/app/share/dialog-delete/dialog-delete.component.ts

@@ -0,0 +1,28 @@
1
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
2
+
3
+@Component({
4
+  selector: 'app-dialog-delete',
5
+  templateUrl: './dialog-delete.component.html',
6
+  styleUrls: ['./dialog-delete.component.less']
7
+})
8
+export class DialogDeleteComponent implements OnInit {
9
+  @Output() hideDelModalEvent = new EventEmitter<any>();
10
+  @Output() confirmDelEvent = new EventEmitter<any>();
11
+  @Input() btnLoading: boolean = false;
12
+  @Input() delModal: boolean = false;
13
+  @Input() content: string = '您确定要删除吗?';
14
+  @Input() tips: string = '';
15
+  constructor() { }
16
+
17
+  ngOnInit() {
18
+  }
19
+  // 隐藏
20
+  hideDelModal() {
21
+    this.hideDelModalEvent.emit();
22
+  }
23
+  // 确认删除
24
+  confirmDel() {
25
+    this.confirmDelEvent.emit();
26
+  }
27
+
28
+}

+ 29 - 0
src/app/share/generate-floor/generate-floor.component.html

@@ -0,0 +1,29 @@
1
+<!-- 生成楼层 -->
2
+<div class="generate-floor" *ngIf="generateModal">
3
+  <div class="modalBody">
4
+    <div class="title">生成楼层<i class="icon_transport transport-guanbi" (click)="hideGenerateModal()"></i></div>
5
+    <div class="content">
6
+      <div class="formItem">
7
+        <nz-select class="w120" [ngClass]="{errorMsg:!building}" [(ngModel)]="building" [nzLoading]="loading1"
8
+          nzPlaceHolder="请选择楼栋">
9
+          <nz-option [nzValue]="building" [nzLabel]="building.buildingName" *ngFor="let building of buildingList">
10
+          </nz-option>
11
+        </nz-select>
12
+        <nz-input-number [ngClass]="{errorMsg:!startFloor}" [ngModel]="startFloor" [nzMin]="startFloorMin"
13
+          [nzMax]="startFloorMax" [nzStep]="1" nzPlaceHolder='起始楼层' (ngModelChange)="startFloorChange($event)">
14
+        </nz-input-number>
15
+        <nz-input-number [ngClass]="{errorMsg:!endFloor}" [ngModel]="endFloor" [nzMin]="endFloorMin"
16
+          [nzMax]="endFloorMax" [nzStep]="1" nzPlaceHolder='结束楼层' (ngModelChange)="endFloorChange($event)">
17
+        </nz-input-number>
18
+      </div>
19
+      <div class="mt8 red" *ngIf="(!building || !startFloor || !endFloor)">请填写楼栋,起始楼层和结束楼层!</div>
20
+    </div>
21
+    <div class="operate">
22
+      <button nz-button nzType="primary" (click)="confirmGenerate()">确认</button>
23
+      <button class="btn cancel ml8" nz-button nzType="default" (click)="hideGenerateModal()">取消</button>
24
+    </div>
25
+  </div>
26
+</div>
27
+<!-- 模态框 -->
28
+<app-dialog-delete [delModal]="delModal" (hideDelModalEvent)="hideDelModal()" [btnLoading]="btnLoading"
29
+  (confirmDelEvent)="confirmDel()" [content]="tipsMsg1"></app-dialog-delete>

+ 156 - 0
src/app/share/generate-floor/generate-floor.component.less

@@ -0,0 +1,156 @@
1
+.generate-floor {
2
+  display: flex;
3
+  justify-content: center;
4
+  align-items: center;
5
+  position: fixed;
6
+  left: 0;
7
+  top: 0;
8
+  width: 100%;
9
+  height: 100%;
10
+  background: rgba(0, 0, 0, 0.4);
11
+  z-index: 99;
12
+
13
+  .modalBody {
14
+    width: 350px;
15
+    height: 220px;
16
+    background: #fff;
17
+    border-radius: 8px;
18
+    padding: 8px 16px;
19
+    color: #333;
20
+    display: flex;
21
+    flex-direction: column;
22
+
23
+    .title {
24
+      text-align: center;
25
+      font-size: 18px;
26
+      position: relative;
27
+
28
+      i {
29
+        position: absolute;
30
+        right: 0;
31
+        top: 0;
32
+        font-size: 20px;
33
+        color: #666;
34
+        cursor: pointer;
35
+        padding: 0 5px;
36
+      }
37
+    }
38
+
39
+    .content {
40
+      flex: 1;
41
+      background: #f9fafb;
42
+      border: 1px solid #e5e9ed;
43
+      border-radius: 8px;
44
+      margin-top: 8px;
45
+      display: flex;
46
+      flex-direction: column;
47
+      align-items: center;
48
+      justify-content: center;
49
+      .formItem {
50
+        width: 100%;
51
+        display: flex;
52
+        align-items: center;
53
+        justify-content: space-evenly;
54
+        .w120 {
55
+          width: 120px;
56
+        }
57
+        .errorMsg ::ng-deep {
58
+          .ant-select-selection,
59
+          input {
60
+            border: 1px solid red !important;
61
+          }
62
+        }
63
+      }
64
+    }
65
+    .operate {
66
+      display: flex;
67
+      justify-content: center;
68
+      align-items: center;
69
+      margin-top: 8px;
70
+    }
71
+  }
72
+
73
+  // 新增
74
+  &.add {
75
+    .modalBody {
76
+      width: 480px;
77
+      height: auto;
78
+
79
+      .content {
80
+        width: 100%;
81
+        height: auto;
82
+        padding: 18px 14px 0 14px;
83
+        max-height: 497px;
84
+        overflow-y: auto;
85
+
86
+        .addForm {
87
+          .ant-form-item {
88
+            margin-bottom: 15px;
89
+
90
+            .ant-form-item-label {
91
+              line-height: 14px;
92
+              text-align: left;
93
+            }
94
+
95
+            .desc {
96
+              margin-top: 5px;
97
+            }
98
+          }
99
+
100
+          .datesControl {
101
+            margin-top: -16px;
102
+
103
+            .ant-form-item-label {
104
+              line-height: 40px;
105
+            }
106
+
107
+            .datesGroup {
108
+              margin-left: 125px;
109
+            }
110
+          }
111
+
112
+          .timer {
113
+            // display: inline-block;
114
+            // width: 50%;
115
+
116
+            .ant-form-item-label {
117
+              width: 100%;
118
+              text-align: left;
119
+            }
120
+
121
+            .numInp {
122
+              margin-right: 5px;
123
+            }
124
+
125
+            .line {
126
+              margin-right: 5px;
127
+            }
128
+          }
129
+
130
+          .timer2 {
131
+            .ant-form-item-label {
132
+              line-height: 20px;
133
+            }
134
+          }
135
+        }
136
+
137
+        .editForm {
138
+          .ant-form-item {
139
+            margin-bottom: 15px;
140
+
141
+            .ant-form-item-label {
142
+              line-height: 14px;
143
+              text-align: left;
144
+            }
145
+          }
146
+        }
147
+      }
148
+
149
+      button {
150
+        &:nth-child(1) {
151
+          margin-right: 20px;
152
+        }
153
+      }
154
+    }
155
+  }
156
+}

+ 80 - 0
src/app/share/generate-floor/generate-floor.component.ts

@@ -0,0 +1,80 @@
1
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
2
+import { MainService } from 'src/app/services/main.service';
3
+import { ToolService } from 'src/app/services/tool.service';
4
+
5
+@Component({
6
+  selector: 'app-generate-floor',
7
+  templateUrl: './generate-floor.component.html',
8
+  styleUrls: ['./generate-floor.component.less']
9
+})
10
+export class GenerateFloorComponent implements OnInit {
11
+  @Output() hideGenerateModalEvent = new EventEmitter<any>();
12
+  @Output() confirmGenerateEvent = new EventEmitter<any>();
13
+  @Input() btnLoading: boolean = false;
14
+  @Input() generateModal: boolean = false;
15
+  constructor(
16
+    private mainService: MainService,
17
+    private tool: ToolService,
18
+  ) { }
19
+  hosId;//院区
20
+  building = null;//选择的楼栋
21
+  startFloor = null;//起始楼层
22
+  startFloorMin = 1;//起始楼层最小
23
+  startFloorMax = Infinity;//起始楼层最大
24
+  endFloor = null;//结束楼层
25
+  endFloorMin = 1;//结束楼层最小
26
+  endFloorMax = Infinity;//结束楼层最大
27
+  delModal = false;
28
+  tipsMsg1 = '';
29
+  ngOnInit() {
30
+    this.building = null;
31
+    this.startFloor = null;
32
+    this.endFloor = null;
33
+    this.hosId = this.tool.getCurrentHospital().id;
34
+    this.getBuildings(this.hosId);
35
+  }
36
+  // 获取楼栋
37
+  loading1: boolean = false;
38
+  buildingList = [];
39
+  getBuildings(hosId) {
40
+    this.loading1 = true;
41
+    this.mainService.getFetchDataList('simple/data', 'building', { idx: 0, sum: 9999, building: { hosId } }).subscribe(result => {
42
+      this.loading1 = false;
43
+      if (result['status'] == 200) {
44
+        this.buildingList = result['list'];
45
+      }
46
+    })
47
+  }
48
+  //修改起始楼层
49
+  startFloorChange(e) {
50
+    this.startFloor = e;
51
+    this.endFloorMin = e;
52
+    this.endFloorMax = Infinity;
53
+  }
54
+  //修改结束楼层
55
+  endFloorChange(e) {
56
+    this.endFloor = e;
57
+    this.startFloorMin = 1;
58
+    this.startFloorMax = e;
59
+  }
60
+  // 隐藏生成楼层弹窗
61
+  hideGenerateModal() {
62
+    this.hideGenerateModalEvent.emit();
63
+  }
64
+  // 确认生成楼层->弹窗提示信息
65
+  confirmGenerate() {
66
+    if (!this.building || !this.startFloor || !this.endFloor) {
67
+    } else {
68
+      this.tipsMsg1 = `是否在${this.building.buildingName}生成楼层${this.startFloor}层到${this.endFloor}层?`;
69
+      this.delModal = true;
70
+    }
71
+  }
72
+  //隐藏提示弹窗
73
+  hideDelModal() {
74
+    this.delModal = false;
75
+  }
76
+  //确认生成楼层
77
+  confirmDel() {
78
+    this.confirmGenerateEvent.emit([this.building, this.startFloor, this.endFloor]);
79
+  }
80
+}

+ 35 - 0
src/app/share/history-prompt-modal/history-prompt-modal.component.html

@@ -0,0 +1,35 @@
1
+<div class="modal display_flex justify-content_flex-center align-items_center" *ngIf="show">
2
+  <div class="modalBody">
3
+    <div class="title">标本完整记录查看<i class="icon_transport transport-guanbi" (click)="hideModal()"></i></div>
4
+    <div class="content">
5
+      <nz-table class="hospitalTable" [nzData]="historySpecimenList" nzSize="middle" [nzShowPagination]="false"
6
+        [nzLoading]="hsLoading">
7
+        <thead>
8
+          <tr class="thead">
9
+            <th nzWidth="10%">序号</th>
10
+            <th nzWidth="30%">动作</th>
11
+            <th nzWidth="30%">时间</th>
12
+            <th nzWidth="30%">操作人</th>
13
+          </tr>
14
+        </thead>
15
+        <tbody>
16
+          <tr *ngFor="let data of historySpecimenList;let i = index;">
17
+            <td>{{i+1}}</td>
18
+            <td>{{ data.operationType?data.operationType.name:'-' }}</td>
19
+            <td>{{ data.creatTime||'-' }}</td>
20
+            <td>{{ data.operationUserName||'-' }}</td>
21
+          </tr>
22
+        </tbody>
23
+      </nz-table>
24
+      <div class="pagination">
25
+        <nz-pagination [(nzPageIndex)]="historySpecimenPageIndex" [(nzTotal)]="historySpecimenListLength"
26
+          [(nzPageSize)]="historySpecimenPageSize" (nzPageIndexChange)="getHistorySpecimen()"
27
+          (nzPageSizeChange)="getHistorySpecimen()">
28
+        </nz-pagination>
29
+      </div>
30
+    </div>
31
+    <div class="display_flex justify-content_flex-center">
32
+      <button class="btn know" nz-button nzType="primary" (click)="hideModal()">知道了</button>
33
+    </div>
34
+  </div>
35
+</div>

+ 163 - 0
src/app/share/history-prompt-modal/history-prompt-modal.component.less

@@ -0,0 +1,163 @@
1
+@import "../../../../src/theme.less";
2
+.modal {
3
+  position: fixed;
4
+  left: 0;
5
+  top: 0;
6
+  width: 100%;
7
+  height: 100%;
8
+  background: rgba(0, 0, 0, 0.4);
9
+  z-index: 999;
10
+  .hospitalTable {
11
+    width: 100%;
12
+    td {
13
+      text-align: center !important;
14
+    }
15
+    .thead {
16
+      background-image: linear-gradient(to right, @bg-start, @bg-end);
17
+      th {
18
+        text-align: center !important;
19
+        color: #fff;
20
+        background: transparent;
21
+      }
22
+    }
23
+  }
24
+
25
+  .modalBody {
26
+    width: 700px;
27
+    min-height: 220px;
28
+    background: #fff;
29
+    border-radius: 5px;
30
+    padding: 10px 20px;
31
+    color: #333;
32
+    &.modalBody-search {
33
+      width: 480px;
34
+      min-height: 250px;
35
+    }
36
+
37
+    .title {
38
+      width: 100%;
39
+      text-align: center;
40
+      font-size: 18px;
41
+      position: relative;
42
+
43
+      i {
44
+        position: absolute;
45
+        right: 0;
46
+        top: 0;
47
+        font-size: 20px;
48
+        color: #666;
49
+        cursor: pointer;
50
+        padding: 0 5px;
51
+      }
52
+    }
53
+
54
+    .content {
55
+      min-height: 117px;
56
+      background: #f9fafb;
57
+      border: 1px solid #e5e9ed;
58
+      border-radius: 5px;
59
+      overflow: hidden;
60
+      margin-top: 12px;
61
+      display: flex;
62
+      flex-direction: column;
63
+      justify-content: center;
64
+      align-items: center;
65
+      &.content-search {
66
+        min-height: 147px;
67
+        justify-content: start;
68
+        .defeat-search {
69
+          width: 100%;
70
+          height: 52px;
71
+          display: flex;
72
+          justify-content: center;
73
+          align-items: center;
74
+          border-bottom: solid 1px #e5e9ed;
75
+          em {
76
+            color: #666;
77
+            font-style: normal;
78
+          }
79
+        }
80
+        .form {
81
+          width: 100%;
82
+          padding: 0 16px;
83
+          .ant-form-item-label,
84
+          .ant-form-explain {
85
+            text-align: left !important;
86
+          }
87
+        }
88
+      }
89
+
90
+      div {
91
+        text-align: center;
92
+        margin: 0;
93
+
94
+        &.defeat {
95
+          color: #333;
96
+          font-size: 28px;
97
+        }
98
+        &.countDown {
99
+          font-size: 14px;
100
+          color: 666;
101
+          em {
102
+            font-style: normal;
103
+            color: @primary-color;
104
+          }
105
+        }
106
+
107
+        &:nth-child(3) {
108
+          font-size: 14px;
109
+          color: #666;
110
+          padding-bottom: 10px;
111
+        }
112
+      }
113
+    }
114
+
115
+    button {
116
+      margin-top: 10px;
117
+
118
+      &.btn {
119
+        margin-left: 8px;
120
+      }
121
+    }
122
+  }
123
+
124
+  // 新增
125
+  &.add {
126
+    .modalBody {
127
+      width: 480px;
128
+      height: auto;
129
+
130
+      .content {
131
+        width: 100%;
132
+        height: auto;
133
+        padding: 18px 14px 0 14px;
134
+
135
+        .addForm {
136
+          .ant-form-item {
137
+            margin-bottom: 15px;
138
+
139
+            .ant-form-item-label {
140
+              line-height: 0;
141
+            }
142
+          }
143
+        }
144
+
145
+        .editForm {
146
+          .ant-form-item {
147
+            margin-bottom: 15px;
148
+
149
+            .ant-form-item-label {
150
+              line-height: 0;
151
+            }
152
+          }
153
+        }
154
+      }
155
+
156
+      button {
157
+        &:nth-child(1) {
158
+          margin-right: 20px;
159
+        }
160
+      }
161
+    }
162
+  }
163
+}

+ 51 - 0
src/app/share/history-prompt-modal/history-prompt-modal.component.ts

@@ -0,0 +1,51 @@
1
+import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
2
+import { MainService } from '../../services/main.service';
3
+
4
+@Component({
5
+  selector: 'app-history-prompt-modal',
6
+  templateUrl: './history-prompt-modal.component.html',
7
+  styleUrls: ['./history-prompt-modal.component.less']
8
+})
9
+export class HistoryPromptModalComponent implements OnInit {
10
+  // 切换科室,切换弹窗
11
+  hsLoading = false;
12
+  historySpecimenList: any = [];
13
+  historySpecimenPageIndex: number = 1;//表格当前页码
14
+  historySpecimenPageSize: number = 5;//表格每页展示条数
15
+  historySpecimenListLength: number = 10;//表格总数据量
16
+  @Input() show: Boolean;
17
+  @Input() scode: String;
18
+
19
+  @Output() closeModelHs = new EventEmitter<any>();//1.组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件
20
+
21
+  constructor(private mainService: MainService) { }
22
+
23
+  ngOnInit() {
24
+    this.getHistorySpecimen();
25
+  }
26
+  // 关闭弹窗
27
+  hideModal() {
28
+    this.closeModelHs.emit(JSON.stringify({ show: false }));//emits(向上弹射)事件
29
+  }
30
+  // 获取列表数据
31
+  getHistorySpecimen(idx?) {
32
+    if (idx) {
33
+      this.historySpecimenPageIndex = 1;
34
+    }
35
+    let postData = {
36
+      idx: this.historySpecimenPageIndex - 1,
37
+      sum: this.historySpecimenPageSize,
38
+      specimenHistory: {
39
+        scode: this.scode
40
+      }
41
+    }
42
+    this.hsLoading = true;
43
+    this.mainService.getFetchDataList('api','specimenHistory',postData).subscribe(data => {
44
+      this.hsLoading = false;
45
+      this.historySpecimenList = data.list || [];
46
+      this.historySpecimenListLength = data.totalNum || 0;
47
+    })
48
+  }
49
+}
50
+
51
+

+ 48 - 0
src/app/share/hs-prompt-modal/hs-prompt-modal.component.html

@@ -0,0 +1,48 @@
1
+<div class="modal display_flex justify-content_flex-center align-items_center" *ngIf="show">
2
+  <div class="modalBody" *ngIf="changeShow">
3
+    <div class="title">当前科室<i class="icon_transport transport-guanbi" (click)="hideModal()"></i></div>
4
+    <div class="content">
5
+      <div class="defeat">{{currentDept}}</div>
6
+      <div class="countDown">关闭倒计时<em>{{closeTime}}s</em></div>
7
+    </div>
8
+    <div class="display_flex justify-content_flex-center">
9
+      <button class="btn know" nz-button nzType="primary" (click)="hideModal()">知道了</button>
10
+      <button class="btn know" nz-button nzType="primary" nzGhost (click)="changeModal()">切换科室</button>
11
+    </div>
12
+  </div>
13
+  <div class="modalBody modalBody-search" *ngIf="!changeShow">
14
+    <div class="title">搜索当前科室<i class="icon_transport transport-guanbi" (click)="hideModal()"></i></div>
15
+    <div class="content content-search">
16
+      <div class="defeat-search display_flex justify-content_flex-center flex-direction_column">
17
+        <span>当前院区:<em>{{currentHospital.hosName}}</em></span>
18
+        <span>当前科室:<em>{{currentDept}}</em></span>
19
+      </div>
20
+      <div class="form">
21
+        <form nz-form [formGroup]="validateForm">
22
+          <nz-form-item>
23
+            <nz-form-label class="label" [nzSm]="24" [nzXs]="24" nzRequired nzFor="dutyDeptFc">搜索当值科室
24
+            </nz-form-label>
25
+            <nz-form-control class="control" [nzSm]="24" [nzXs]="24" nzErrorTip="请选择当值科室!">
26
+              <nz-select formControlName="dutyDeptFc" [nzDropdownMatchSelectWidth]="false" nzServerSearch nzShowSearch
27
+                (nzOnSearch)="searchDept($event)" nzAllowClear nzPlaceHolder="请选择当值科室" [(ngModel)]="dutyDept">
28
+                <ng-container *ngFor="let option of dutyDepts">
29
+                  <nz-option *ngIf="!isLoading" [nzLabel]="option.dept" [nzValue]="option.id"></nz-option>
30
+                </ng-container>
31
+                <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
32
+                  <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
33
+                </nz-option>
34
+              </nz-select>
35
+            </nz-form-control>
36
+          </nz-form-item>
37
+        </form>
38
+      </div>
39
+    </div>
40
+    <div class="display_flex justify-content_flex-center">
41
+      <button class="btn know" nz-button nzType="primary" (click)="ok()">确定</button>
42
+      <button class="btn know" nz-button nzType="primary" nzGhost (click)="hideModal()">取消</button>
43
+    </div>
44
+  </div>
45
+</div>
46
+<!-- 操作成功/失败提示框 -->
47
+<app-prompt-modal *ngIf="promptModalShow" [content]="promptContent" [success]="ifSuccess" [show]="promptModalShow"
48
+  [info]="promptInfo" [isReLoad]="true"></app-prompt-modal>

+ 154 - 0
src/app/share/hs-prompt-modal/hs-prompt-modal.component.less

@@ -0,0 +1,154 @@
1
+
2
+@import "../../../../src/theme.less";
3
+.modal {
4
+  position: fixed;
5
+  left: 0;
6
+  top: 0;
7
+  width: 100%;
8
+  height: 100%;
9
+  background: rgba(0, 0, 0, .4);
10
+  z-index: 999;
11
+
12
+  .modalBody {
13
+    width: 350px;
14
+    min-height: 220px;
15
+    background: #fff;
16
+    border-radius: 5px;
17
+    padding: 10px 20px;
18
+    color: #333;
19
+    &.modalBody-search{
20
+      width: 480px;
21
+      min-height: 250px;
22
+    }
23
+
24
+    .title {
25
+      width: 100%;
26
+      text-align: center;
27
+      font-size: 18px;
28
+      position: relative;
29
+
30
+      i {
31
+        position: absolute;
32
+        right: 0;
33
+        top: 0;
34
+        font-size: 20px;
35
+        color: #666;
36
+        cursor: pointer;
37
+        padding: 0 5px;
38
+      }
39
+    }
40
+
41
+    .content {
42
+      min-height: 117px;
43
+      background: #f9fafb;
44
+      border: 1px solid #e5e9ed;
45
+      border-radius: 5px;
46
+      overflow: hidden;
47
+      margin-top: 12px;
48
+      display: flex;
49
+      flex-direction: column;
50
+      justify-content: center;
51
+      align-items: center;
52
+      &.content-search{
53
+        min-height: 147px;
54
+        justify-content: start;
55
+        .defeat-search{
56
+          width: 100%;
57
+          height: 52px;
58
+          display: flex;
59
+          justify-content: center;
60
+          align-items: center;
61
+          border-bottom: solid 1px #e5e9ed;
62
+          em{
63
+            color: #666;
64
+            font-style: normal;
65
+          }
66
+        }
67
+        .form{
68
+          width: 100%;
69
+          padding: 0 16px;
70
+          .ant-form-item-label,.ant-form-explain{
71
+            text-align: left!important;
72
+          }
73
+        }
74
+      }
75
+
76
+      div {
77
+        text-align: center;
78
+        margin: 0;
79
+
80
+        &.defeat {
81
+          color: #333;
82
+          font-size: 28px;
83
+        }
84
+        &.countDown{
85
+          font-size: 14px;
86
+          color: 666;
87
+          em{
88
+            font-style: normal;
89
+            color: @primary-color;
90
+          }
91
+        }
92
+
93
+        &:nth-child(3) {
94
+          font-size: 14px;
95
+          color: #666;
96
+          padding-bottom: 10px;
97
+        }
98
+      }
99
+    }
100
+
101
+    button {
102
+      margin-top: 10px;
103
+
104
+      &.btn {
105
+        margin-left: 8px;
106
+      }
107
+    }
108
+
109
+  }
110
+
111
+  // 新增
112
+  &.add {
113
+    .modalBody {
114
+      width: 480px;
115
+      height: auto;
116
+
117
+      .content {
118
+        width: 100%;
119
+        height: auto;
120
+        padding: 18px 14px 0 14px;
121
+
122
+        .addForm {
123
+          .ant-form-item {
124
+            margin-bottom: 15px;
125
+
126
+            .ant-form-item-label {
127
+              line-height: 0;
128
+            }
129
+          }
130
+        }
131
+
132
+        .editForm {
133
+          .ant-form-item {
134
+            margin-bottom: 15px;
135
+
136
+            .ant-form-item-label {
137
+              line-height: 0;
138
+            }
139
+          }
140
+        }
141
+
142
+      }
143
+
144
+      button {
145
+        &:nth-child(1) {
146
+          margin-right: 20px;
147
+
148
+        }
149
+      }
150
+
151
+    }
152
+  }
153
+
154
+}

+ 133 - 0
src/app/share/hs-prompt-modal/hs-prompt-modal.component.ts

@@ -0,0 +1,133 @@
1
+import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
2
+import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
3
+import { MainService } from '../../services/main.service';
4
+import { ToolService } from '../../services/tool.service';
5
+import { Subject } from 'rxjs';
6
+import { debounceTime } from 'rxjs/operators';
7
+
8
+@Component({
9
+  selector: 'app-hs-prompt-modal',
10
+  templateUrl: './hs-prompt-modal.component.html',
11
+  styleUrls: ['./hs-prompt-modal.component.less']
12
+})
13
+export class HsPromptModalComponent implements OnInit {
14
+  // 切换科室,切换弹窗
15
+  // changeShow = true //true显示第一个弹窗,false显示选择科室的弹窗
16
+  validateForm!: FormGroup;
17
+  dutyDept;//当值科室
18
+  dutyDepts = [];//当值科室列表
19
+  isLoading = false;
20
+  currentHospital;//当前院区
21
+  currentDept = JSON.parse(localStorage.getItem('user')).user.dept.dept;//当前科室
22
+  @Input() show: Boolean;
23
+  @Input() changeShow: Boolean;
24
+  @Input() closeTime: Number;
25
+
26
+  @Output() closeModelHs = new EventEmitter<any>();//1.组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件
27
+  @Output() clearModelHs = new EventEmitter<any>();//1.组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件
28
+
29
+  constructor(private fb: FormBuilder, private mainService: MainService, private tool: ToolService) { }
30
+  searchDeptSubject = new Subject();
31
+  ngOnInit() {
32
+    this.searchDeptSubject.pipe(debounceTime(500)).subscribe(v => {
33
+      this.search(v);
34
+    })
35
+    this.currentHospital = this.tool.getCurrentHospital();
36
+    this.validateForm = this.fb.group({
37
+      dutyDeptFc: [null, [Validators.required]],//当班科室
38
+    });
39
+    this.search(false)
40
+  }
41
+  // 关闭弹窗
42
+  hideModal() {
43
+    this.closeModelHs.emit(JSON.stringify({ show: false, changeShow: true }));//emits(向上弹射)事件
44
+    // this.changeShow = true
45
+  }
46
+  // 切换科室
47
+  changeModal() {
48
+    // this.changeShow = false
49
+    this.clearModelHs.emit(JSON.stringify({ clear: true, changeShow: false }));//emits(向上弹射)事件
50
+  }
51
+  // 获取当前用户信息
52
+  getCurrentUserNow() {
53
+    this.mainService.getCurrentUser1().subscribe(data => {
54
+      if (data['status'] == 200) {
55
+        let user = JSON.parse(localStorage.getItem('user'))
56
+        user.user.dept = data['data'].dept
57
+        localStorage.setItem('user', JSON.stringify(user))
58
+        this.showPromptModal('切换科室', true, '')
59
+        this.hideModal()
60
+      }
61
+    })
62
+  }
63
+  // 确定
64
+  ok() {
65
+    let flag = true
66
+    for (const i in this.validateForm.controls) {
67
+      this.validateForm.controls[i].markAsDirty();
68
+      this.validateForm.controls[i].updateValueAndValidity();
69
+      if (this.validateForm.controls[i].valid === false) {//携带物品非必填
70
+        flag = false
71
+      }
72
+    }
73
+    if (!flag) {
74
+      return;
75
+    }
76
+    let dataObj = {
77
+      "user": {
78
+        "dept": {
79
+          "id": this.validateForm.controls.dutyDeptFc.value
80
+        },
81
+        "id": JSON.parse(localStorage.getItem('user')).user.id
82
+      }
83
+    }
84
+
85
+    this.mainService.coopData('updData', 'user', dataObj).subscribe(data => {
86
+      if (data.status == 200) {
87
+        this.getCurrentUserNow()
88
+      } else {
89
+        this.showPromptModal('切换科室', false, '')
90
+      }
91
+    })
92
+  }
93
+
94
+  // 展示信息提示框(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)
95
+  promptModalShow = false;
96
+  promptContent = '';
97
+  ifSuccess = false;
98
+  promptInfo = '';
99
+  showPromptModal(con, success, promptInfo?) {
100
+    this.promptModalShow = false;
101
+    this.promptContent = con;
102
+    this.ifSuccess = success;
103
+    this.promptInfo = promptInfo;
104
+    setTimeout(() => {
105
+      this.promptModalShow = true;
106
+    }, 100);
107
+  }
108
+  //当值科室搜索
109
+  searchDept(e) {
110
+    this.searchDeptSubject.next(e);
111
+  }
112
+  // 当值科室搜索
113
+  search(e) {
114
+    let keywords = ''
115
+    if (e) {
116
+      keywords = e
117
+    }
118
+    let dataObj = {
119
+      "idx": 0,
120
+      "sum": 20,
121
+      "department": {
122
+        "hospital": { id: this.currentHospital.id },
123
+        "keyWord": keywords
124
+      }
125
+    }
126
+    this.mainService.getFetchDataList('data', 'department', dataObj).subscribe(data => {
127
+      if (data.status == 200) {
128
+        this.dutyDepts = data.list
129
+      }
130
+    })
131
+  }
132
+}
133
+

+ 1 - 0
src/app/share/mask/mask.component.html

@@ -0,0 +1 @@
1
+<div class="app-mask"></div>

+ 9 - 0
src/app/share/mask/mask.component.less

@@ -0,0 +1,9 @@
1
+.app-mask {
2
+  position: fixed;
3
+  left: 0;
4
+  top: 0;
5
+  width: 100vw;
6
+  height: 100vh;
7
+  background-color: rgba(0, 0, 0, 0.4);
8
+  z-index: 99;
9
+}

+ 15 - 0
src/app/share/mask/mask.component.ts

@@ -0,0 +1,15 @@
1
+import { Component, OnInit } from '@angular/core';
2
+
3
+@Component({
4
+  selector: 'app-mask',
5
+  templateUrl: './mask.component.html',
6
+  styleUrls: ['./mask.component.less']
7
+})
8
+export class MaskComponent implements OnInit {
9
+
10
+  constructor() { }
11
+
12
+  ngOnInit() {
13
+  }
14
+
15
+}

+ 595 - 0
src/app/share/order-detail/order-detail.component.html

@@ -0,0 +1,595 @@
1
+<div class="detail" *ngIf="!maskFlag">
2
+  <div class="title">工单查看<i class="icon_transport transport-guanbi" (click)="close()"></i></div>
3
+  <div class="box">
4
+    <div class="tab display_flex">
5
+      <div [ngClass]="{'item':true, 'flex_1':true, checked:tabType==1}" (click)="checkTab(1)">工单信息</div>
6
+      <div [ngClass]="{'item':true, 'flex_1':true, checked:tabType==2}" (click)="checkTab(2)">评价内容</div>
7
+      <div [ngClass]="{'item':true, 'flex_1':true, checked:tabType==3}" (click)="checkTab(3)">积分</div>
8
+      <div [ngClass]="{'item':true, 'flex_1':true, checked:tabType==4}" (click)="checkTab(4)">历史记录</div>
9
+    </div>
10
+    <!-- 其他类型工单信息 -->
11
+    <overlay-scrollbars #osComponentRef3 style="max-height: 400px;">
12
+      <div *ngIf="(tabType==1)&&(orderInfo.taskType.associationType.id==259)" class="content orders">
13
+        <div class="top">
14
+          <div class="num">
15
+            <span class="left">单号:{{orderInfo.gdcode}}</span>
16
+            <span class="right">{{orderInfo.gdState?orderInfo.gdState.name:''}}</span>
17
+          </div>
18
+          <div class="info" nz-row>
19
+            <div nz-col nzSpan="6">工单日期:{{orderInfo.startTime|date:'yyyy-MM-dd HH:mm'}}</div>
20
+            <div nz-col nzSpan="6">总耗时:{{orderInfo.showTimeNum}}</div>
21
+            <div nz-col nzSpan="8">申请类型:{{orderInfo.taskType?orderInfo.taskType.taskName:''}}</div>
22
+            <div nz-col nzSpan="4">支助人员信息:{{orderInfo.worker?orderInfo.worker.name:''}}</div>
23
+          </div>
24
+          <div class="info" nz-row>
25
+            <div nz-col nzSpan="6">申请科室:{{orderInfo.createDeptDTO?orderInfo.createDeptDTO.dept:''}}
26
+            </div>
27
+            <div nz-col nzSpan="6">
28
+              目标科室:{{endDepts}}
29
+            </div>
30
+            <div nz-col nzSpan="8" *ngIf="orderInfo.urgentDetails">
31
+              加急状态:{{orderInfo.urgentDetails.checkStatus.name}}</div>
32
+          </div>
33
+          <div class="info" nz-row *ngIf="orderInfo.urgentDetails">
34
+            <div nz-col nzSpan="24" class="jiaji">加急原因:{{orderInfo.urgentDetails.urgentReason}}</div>
35
+          </div>
36
+          <div class="info" nz-row *ngIf="orderInfo.workOrderRemark!==undefined">
37
+            <div nz-col nzSpan="24">备注信息:{{orderInfo.workOrderRemark||'-'}}
38
+            </div>
39
+          </div>
40
+          <div class="info" nz-row *ngIf="orderInfo.specialCloseReason!==undefined">
41
+            <div nz-col nzSpan="24">特殊情况关闭原因:{{orderInfo.specialCloseReason||'-'}}
42
+            </div>
43
+          </div>
44
+        </div>
45
+        <div class="center">
46
+          <div class="box">
47
+            <div class="steps" *ngFor="let step of logList">
48
+              <div class="step">
49
+                <div class="info">
50
+                  <i
51
+                    [ngClass]="{'icon_transport':true, 'transport-icon_liucheng':true,'green':(step.record&&step.record[0]&&step.record[0].operationTime)}"></i>
52
+                  <p>{{step.operationName}}</p>
53
+                  <p>{{step.record?step.record.operationtime:''}}</p>
54
+                  <p *ngIf="step.record&&step.record.length&&step.record[0].dept"><span
55
+                      *ngFor="let dept of step.record">{{dept.dept}},</span></p>
56
+                  <p *ngIf="step.record&&step.record.length&&step.operationName!='申请'">耗时{{filterTime(step.record)}}</p>
57
+                </div>
58
+                <div class="line"></div>
59
+              </div>
60
+            </div>
61
+          </div>
62
+        </div>
63
+      </div>
64
+    </overlay-scrollbars>
65
+    <!-- 标本类型工单信息 -->
66
+    <overlay-scrollbars #osComponentRef4 style="max-height: 400px;">
67
+      <div *ngIf="tabType==1&&orderInfo.taskType.associationType.id==256" class="content orders">
68
+        <div class="top">
69
+          <div class="num">
70
+            <span class="left">单号:{{orderInfo.gdcode}}</span>
71
+            <span class="right">{{orderInfo.gdState?orderInfo.gdState.name:''}}</span>
72
+          </div>
73
+          <div class="info" nz-row>
74
+            <div nz-col nzSpan="6">工单日期:{{orderInfo.startTime|date:'yyyy-MM-dd HH:mm'}}</div>
75
+            <div nz-col nzSpan="6">总耗时:{{orderInfo.showTimeNum}}</div>
76
+            <div nz-col nzSpan="8">申请类型:{{orderInfo.taskType?orderInfo.taskType.taskName:''}}</div>
77
+            <div nz-col nzSpan="4">支助人员信息:{{orderInfo.worker?orderInfo.worker.name:''}}</div>
78
+          </div>
79
+          <div class="info" nz-row>
80
+            <div nz-col nzSpan="4">申请科室:{{orderInfo.createDeptDTO?orderInfo.createDeptDTO.dept:''}}
81
+            </div>
82
+            <div nz-col nzSpan="9">
83
+              目标科室:{{endDepts}}
84
+            </div>
85
+            <div nz-col nzSpan="4">预计接收:{{orderInfo.expectReceiveNum}}</div>
86
+            <div nz-col nzSpan="3">送达:{{orderInfo.deliveryNum}}</div>
87
+            <div nz-col nzSpan="4">实际接收:{{orderInfo.actualReceiveNum}}</div>
88
+          </div>
89
+          <div class="info" nz-row *ngIf="orderInfo.urgentDetails">
90
+            <div nz-col nzSpan="8">
91
+              加急状态:{{orderInfo.urgentDetails.checkStatus.name}}</div>
92
+            <div nz-col nzSpan="24" class="jiaji">加急原因:{{orderInfo.urgentDetails.urgentReason}}</div>
93
+          </div>
94
+          <div class="info" nz-row *ngIf="orderInfo.specialCloseReason!==undefined">
95
+            <div nz-col nzSpan="24">特殊情况关闭原因:{{orderInfo.specialCloseReason||'-'}}
96
+            </div>
97
+          </div>
98
+        </div>
99
+        <div class="center">
100
+          <div class="box">
101
+            <div class="steps" *ngFor="let step of logList">
102
+              <div class="step">
103
+                <div class="info">
104
+                  <i
105
+                    [ngClass]="{'icon_transport':true, 'transport-icon_liucheng':true,'green':(step.record&&step.record[0]&&step.record[0].operationTime)}"></i>
106
+                  <p>{{step.operationName}}</p>
107
+                  <p>{{step.record?step.record.operationtime:''}}</p>
108
+                  <p *ngIf="step.record&&step.record.length&&step.record[0].dept"><span
109
+                      *ngFor="let dept of step.record">{{dept.dept}},</span></p>
110
+                  <p *ngIf="step.record&&step.record.length&&step.operationName!='申请'">耗时{{filterTime(step.record)}}</p>
111
+                </div>
112
+                <div class="line"></div>
113
+              </div>
114
+            </div>
115
+          </div>
116
+        </div>
117
+        <div class="bottom">
118
+          <div class="table">
119
+            <nz-table class="" [nzData]="orderInfo.specimenSet" nzSize="small"
120
+              [nzScroll]="{ y: (orderInfo.urgentDetails?'124px':'153px') }" [nzShowPagination]="null">
121
+              <thead>
122
+                <tr class="thead">
123
+                  <th nzWidth="50px">序号</th>
124
+                  <th nzWidth="95px">标本类型</th>
125
+                  <th nzWidth="110px">标本编码</th>
126
+                  <th nzWidth="88px">患者姓名</th>
127
+                  <th nzWidth="50px">床号</th>
128
+                  <th nzWidth="88px">目标科室</th>
129
+                  <th nzWidth="75px">是否接收</th>
130
+                  <th nzWidth="75px">是否送达</th>
131
+                  <th nzWidth="123px">接收扫描时间</th>
132
+                  <th nzWidth="123px">送达扫描时间</th>
133
+                </tr>
134
+              </thead>
135
+              <tbody *ngIf="orderInfo.specimenSet">
136
+                <tr *ngFor="let data of orderInfo.specimenSet;let i =index;">
137
+                  <td>{{i+1}}</td>
138
+                  <td>{{data.stype.name}}</td>
139
+                  <td>{{data.scode}}</td>
140
+                  <td>{{data.patientName}}</td>
141
+                  <td>{{data.bedNum}}</td>
142
+                  <td>{{data.checkDept.dept}}</td>
143
+                  <td>{{data.received?"是":"否"}}</td>
144
+                  <td>{{data.arrived?"是":"否"}}</td>
145
+                  <td>{{data.arriveTime|date:'yyyy-MM-dd HH:mm'}}</td>
146
+                  <td style="position: relative;">{{data.sendTime|date:'yyyy-MM-dd HH:mm'}}<img *ngIf="data.urgent == 1"
147
+                      src="../../assets/images/icon_ji.png" alt="" class="ji"></td>
148
+                </tr>
149
+              </tbody>
150
+            </nz-table>
151
+          </div>
152
+        </div>
153
+      </div>
154
+    </overlay-scrollbars>
155
+    <!-- 标本轮巡工单信息 -->
156
+    <overlay-scrollbars #osComponentRef5 style="max-height: 400px;">
157
+      <div *ngIf="tabType==1&&orderInfo.taskType.associationType.id==380" class="content orders">
158
+        <div class="top">
159
+          <div class="num">
160
+            <span class="left">单号:{{orderInfo.gdcode}}</span>
161
+            <span class="right">{{orderInfo.gdState?orderInfo.gdState.name:''}}</span>
162
+          </div>
163
+          <div class="info" nz-row>
164
+            <div nz-col nzSpan="6">工单日期:{{orderInfo.startTime|date:'yyyy-MM-dd HH:mm'}}</div>
165
+            <div nz-col nzSpan="6">总耗时:{{orderInfo.showTimeNum}}</div>
166
+            <div nz-col nzSpan="8">申请类型:{{orderInfo.taskType?orderInfo.taskType.taskName:''}}</div>
167
+            <div nz-col nzSpan="4">支助人员信息:{{orderInfo.worker?orderInfo.worker.name:''}}</div>
168
+          </div>
169
+          <div class="info" nz-row>
170
+            <div nz-col nzSpan="4">申请科室:{{orderInfo.createDeptDTO?orderInfo.createDeptDTO.dept:''}}
171
+            </div>
172
+            <div nz-col nzSpan="10">
173
+              目标科室:{{endDepts}}
174
+            </div>
175
+            <div nz-col nzSpan="4">预计接收:{{orderInfo.expectReceiveNum}}</div>
176
+            <div nz-col nzSpan="3">送达:{{orderInfo.deliveryNum}}</div>
177
+            <div nz-col nzSpan="3">实际接收:{{orderInfo.actualReceiveNum}}</div>
178
+          </div>
179
+          <div class="info" nz-row *ngIf="orderInfo.urgentDetails">
180
+            <div nz-col nzSpan="8">
181
+              加急状态:{{orderInfo.urgentDetails.checkStatus.name}}</div>
182
+            <div nz-col nzSpan="24" class="jiaji">加急原因:{{orderInfo.urgentDetails.urgentReason}}</div>
183
+          </div>
184
+          <div class="info" nz-row *ngIf="orderInfo.specialCloseReason!==undefined">
185
+            <div nz-col nzSpan="24">特殊情况关闭原因:{{orderInfo.specialCloseReason||'-'}}
186
+            </div>
187
+          </div>
188
+        </div>
189
+        <div class="center">
190
+          <div class="box">
191
+            <div class="steps" *ngFor="let step of logList">
192
+              <div class="step">
193
+                <div class="info">
194
+                  <i
195
+                    [ngClass]="{'icon_transport':true, 'transport-icon_liucheng':true,'green':(step.record&&step.record[0]&&step.record[0].operationTime)}"></i>
196
+                  <p>{{step.operationName}}</p>
197
+                  <p>{{step.record?step.record.operationtime:''}}</p>
198
+                  <p *ngIf="step.record&&step.record.length&&step.record[0].dept"><span
199
+                      *ngFor="let dept of step.record">{{dept.dept}},</span></p>
200
+                  <p *ngIf="step.record&&step.record.length&&step.operationName!='申请'">耗时{{filterTime(step.record)}}</p>
201
+                </div>
202
+                <div class="line"></div>
203
+              </div>
204
+            </div>
205
+          </div>
206
+        </div>
207
+        <div class="bottom">
208
+          <div class="table">
209
+            <nz-table class="" [nzData]="orderInfo.specimenSet" nzSize="small"
210
+              [nzScroll]="{ y: (orderInfo.urgentDetails?'124px':'153px') }" [nzShowPagination]="null">
211
+              <thead>
212
+                <tr class="thead">
213
+                  <th nzWidth="50px">序号</th>
214
+                  <th nzWidth="95px">标本类型</th>
215
+                  <th nzWidth="110px">标本编码</th>
216
+                  <th nzWidth="88px">患者姓名</th>
217
+                  <th nzWidth="50px">床号</th>
218
+                  <th nzWidth="88px">目标科室</th>
219
+                  <th nzWidth="75px">是否接收</th>
220
+                  <th nzWidth="75px">是否送达</th>
221
+                  <th nzWidth="123px">接收扫描时间</th>
222
+                  <th nzWidth="123px">送达扫描时间</th>
223
+                </tr>
224
+              </thead>
225
+              <tbody *ngIf="orderInfo.specimenSet">
226
+                <tr *ngFor="let data of orderInfo.specimenSet;let i =index;">
227
+                  <td>{{i+1}}</td>
228
+                  <td>{{data.stype.name}}</td>
229
+                  <td>{{data.scode}}</td>
230
+                  <td>{{data.patientName}}</td>
231
+                  <td>{{data.bedNum}}</td>
232
+                  <td>{{data.checkDept.dept}}</td>
233
+                  <td>{{data.received?"是":"否"}}</td>
234
+                  <td>{{data.arrived?"是":"否"}}</td>
235
+                  <td>{{data.arriveTime|date:'yyyy-MM-dd HH:mm'}}</td>
236
+                  <td style="position: relative;">{{data.sendTime|date:'yyyy-MM-dd HH:mm'}}<img *ngIf="data.urgent == 1"
237
+                      src="../../assets/images/icon_ji.png" alt="" class="ji"></td>
238
+                </tr>
239
+              </tbody>
240
+            </nz-table>
241
+          </div>
242
+        </div>
243
+      </div>
244
+    </overlay-scrollbars>
245
+    <!-- 药品/静配配送类型工单信息 -->
246
+    <overlay-scrollbars #osComponentRef6 style="max-height: 400px;">
247
+      <div *ngIf="tabType==1&&(orderInfo.taskType.associationType.id==257||orderInfo.taskType.associationType.id==258)"
248
+        class="content orders">
249
+        <div class="top">
250
+          <div class="num">
251
+            <span class="left">单号:{{orderInfo.gdcode}}</span>
252
+            <span class="right">{{orderInfo.gdState?orderInfo.gdState.name:''}}</span>
253
+          </div>
254
+          <div class="info" nz-row>
255
+            <div nz-col nzSpan="6">工单日期:{{orderInfo.startTime|date:'yyyy-MM-dd HH:mm'}}</div>
256
+            <div nz-col nzSpan="6">总耗时:{{orderInfo.showTimeNum}}</div>
257
+            <div nz-col nzSpan="8">申请类型:{{orderInfo.taskType?orderInfo.taskType.taskName:''}}</div>
258
+            <div nz-col nzSpan="4">支助人员信息:{{orderInfo.worker?orderInfo.worker.name:''}}</div>
259
+          </div>
260
+          <div class="info" nz-row>
261
+            <div nz-col nzSpan="6">申请科室:{{orderInfo.createDeptDTO?orderInfo.createDeptDTO.dept:''}}
262
+            </div>
263
+            <div nz-col nzSpan="6">
264
+              目标科室:{{endDepts}}
265
+            </div>
266
+            <div nz-col nzSpan="8" *ngIf="orderInfo.urgentDetails">加急状态:{{orderInfo.urgentDetails.checkStatus.name}}
267
+            </div>
268
+          </div>
269
+          <div class="info" nz-row *ngIf="orderInfo.urgentDetails">
270
+            <div nz-col nzSpan="24" class="jiaji">加急原因:{{orderInfo.urgentDetails.urgentReason}}</div>
271
+          </div>
272
+          <div class="info" nz-row *ngIf="orderInfo.specialCloseReason!==undefined">
273
+            <div nz-col nzSpan="24">特殊情况关闭原因:{{orderInfo.specialCloseReason||'-'}}
274
+            </div>
275
+          </div>
276
+        </div>
277
+        <div class="center">
278
+          <div class="box">
279
+            <div class="steps" *ngFor="let step of logList">
280
+              <div class="step">
281
+                <div class="info">
282
+                  <i
283
+                    [ngClass]="{'icon_transport':true, 'transport-icon_liucheng':true,'green':(step.record&&step.record[0]&&step.record[0].operationTime)}"></i>
284
+                  <p>{{step.operationName}}</p>
285
+                  <p>{{step.record?step.record.operationtime:''}}</p>
286
+                  <p *ngIf="step.record&&step.record.length&&step.record[0].dept"><span
287
+                      *ngFor="let dept of step.record">{{dept.dept}},</span></p>
288
+                  <p *ngIf="step.record&&step.record.length&&step.operationName!='申请'">耗时{{filterTime(step.record)}}</p>
289
+                </div>
290
+                <div class="line"></div>
291
+              </div>
292
+            </div>
293
+          </div>
294
+        </div>
295
+        <div class="bottom">
296
+          <div class="table">
297
+            <!-- 静配 -->
298
+            <nz-table *ngIf="orderInfo.staticDistri" class="detailDrugTable"
299
+              [nzData]="orderInfo.staticDistri.jpdetailsFormat" nzSize="small" [nzScroll]="{ y: '125px' }"
300
+              [nzShowPagination]="null">
301
+              <thead>
302
+                <tr class="thead">
303
+                  <th nzWidth="15%">患者信息</th>
304
+                  <th nzWidth="30%">药品</th>
305
+                  <th nzWidth="5%">数量</th>
306
+                  <th nzWidth="15%">患者信息</th>
307
+                  <th nzWidth="30%">药品</th>
308
+                  <th nzWidth="5%">数量</th>
309
+                </tr>
310
+              </thead>
311
+              <tbody *ngIf="orderInfo.staticDistri">
312
+                <tr *ngFor="let data of orderInfo.staticDistri.jpdetailsFormat">
313
+                  <td>{{data[0].bedNum}}床:{{data[0].patientInfo}}</td>
314
+                  <td>{{data[0].jpInfo}}</td>
315
+                  <td>{{data[0].jpNum}}</td>
316
+                  <td>{{data[1]?data[1].bedNum+"床:"+data[1].patientInfo:''}}</td>
317
+                  <td>{{data[1]?data[1].jpInfo:''}}</td>
318
+                  <td>{{data[1]?data[1].jpNum:''}}</td>
319
+                </tr>
320
+              </tbody>
321
+            </nz-table>
322
+            <!-- 药品 -->
323
+            <nz-table *ngIf="orderInfo.drugs" class="detailDrugTable" [nzData]="orderInfo.drugs.drugsFormat"
324
+              nzSize="small" [nzScroll]="{ y: '125px' }" [nzShowPagination]="null">
325
+              <thead>
326
+                <tr class="thead">
327
+                  <th nzWidth="15%">患者信息</th>
328
+                  <th nzWidth="30%">药品</th>
329
+                  <th nzWidth="5%">数量</th>
330
+                  <th nzWidth="15%">患者信息</th>
331
+                  <th nzWidth="30%">药品</th>
332
+                  <th nzWidth="5%">数量</th>
333
+                </tr>
334
+              </thead>
335
+              <tbody *ngIf="orderInfo.drugs">
336
+                <tr *ngFor="let data of orderInfo.drugs.drugsFormat">
337
+                  <td>{{data[0].bedNum}}床:{{data[0].patientInfo}}</td>
338
+                  <td>{{data[0].drugsInfo}}</td>
339
+                  <td>{{data[0].drugsNum}}</td>
340
+                  <td>{{data[1]?data[1].bedNum+"床:"+data[1].patientInfo:''}}</td>
341
+                  <td>{{data[1]?data[1].drugsInfo:''}}</td>
342
+                  <td>{{data[1]?data[1].drugsNum:''}}</td>
343
+                </tr>
344
+              </tbody>
345
+            </nz-table>
346
+          </div>
347
+        </div>
348
+      </div>
349
+    </overlay-scrollbars>
350
+    <!-- 患者陪检/患者转运类型工单信息 -->
351
+    <overlay-scrollbars #osComponentRef1 style="max-height: 400px;">
352
+      <div *ngIf="tabType==1&&(orderInfo.taskType.associationType.id==260||orderInfo.taskType.associationType.id==255)"
353
+        class="content orders">
354
+        <div class="top">
355
+          <div class="num">
356
+            <span class="left">单号:{{orderInfo.gdcode}}</span>
357
+            <span class="right">{{orderInfo.gdState?orderInfo.gdState.name:''}}</span>
358
+          </div>
359
+          <div class="info" nz-row>
360
+            <div nz-col nzSpan="6">工单日期:{{orderInfo.startTime|date:'yyyy-MM-dd HH:mm'}}</div>
361
+            <div nz-col nzSpan="6">总耗时:{{orderInfo.showTimeNum}}</div>
362
+            <div nz-col nzSpan="8">申请类型:{{orderInfo.taskType?orderInfo.taskType.taskName:''}}</div>
363
+            <div nz-col nzSpan="4">支助人员信息:{{orderInfo.worker?orderInfo.worker.name:''}}</div>
364
+          </div>
365
+          <div class="info" nz-row>
366
+            <div nz-col nzSpan="6">申请科室:{{orderInfo.createDeptDTO?orderInfo.createDeptDTO.dept:''}}
367
+            </div>
368
+            <div nz-col nzSpan="6" *ngIf="middleDept.length>0">中间科室:{{middleDept.join(',')}}
369
+            </div>
370
+            <div nz-col nzSpan="6">
371
+              目标科室:{{endDepts}}
372
+            </div>
373
+            <div nz-col nzSpan="8" *ngIf="orderInfo.urgentDetails">加急状态:{{orderInfo.urgentDetails.checkStatus.name}}
374
+            </div>
375
+          </div>
376
+          <div class="info" nz-row *ngIf="orderInfo.urgentDetails">
377
+            <div nz-col nzSpan="24" class="jiaji">加急原因:{{orderInfo.urgentDetails.urgentReason}}</div>
378
+          </div>
379
+          <div class="info" nz-row *ngIf="orderInfo.specialCloseReason!==undefined">
380
+            <div nz-col nzSpan="24">特殊情况关闭原因:{{orderInfo.specialCloseReason||'-'}}
381
+            </div>
382
+          </div>
383
+        </div>
384
+        <div class="center">
385
+          <div class="box">
386
+            <div class="steps" *ngFor="let step of logList">
387
+              <div class="step">
388
+                <div class="info">
389
+                  <i
390
+                    [ngClass]="{'icon_transport':true, 'transport-icon_liucheng':true,'green':(step.record&&step.record[0]&&step.record[0].operationTime)}"></i>
391
+                  <p>{{step.operationName}}</p>
392
+                  <p>{{step.record?step.record.operationtime:''}}</p>
393
+                  <p *ngIf="step.record&&step.record.length&&step.record[0].dept"><span
394
+                      *ngFor="let dept of step.record">{{dept.dept}},</span></p>
395
+                  <p *ngIf="step.record&&step.record.length&&step.operationName!='申请'">耗时{{filterTime(step.record)}}</p>
396
+                </div>
397
+                <div class="line"></div>
398
+              </div>
399
+            </div>
400
+          </div>
401
+        </div>
402
+        <div class="bottom">
403
+          <div class="info">
404
+            <div nz-row class="top">
405
+              <div class="left" nz-col nzSpan="12">
406
+                <p>
407
+                  <span class="label">患者姓名</span>
408
+                  <span>{{orderInfo.patient?orderInfo.patient.patientName:'-'}}</span>
409
+                </p>
410
+                <p>
411
+                  <span class="label">床位</span>
412
+                  <span>{{orderInfo.patient?orderInfo.patient.bedNum:'-'}}</span>
413
+                </p>
414
+              </div>
415
+              <div class="right" nz-col nzSpan="12">
416
+                <p>
417
+                  <span class="label">患者编码</span>
418
+                  <span>{{orderInfo.patient?orderInfo.patient.patientCode:'-'}}</span>
419
+                </p>
420
+                <p>
421
+                  <span class="label">携带物品</span>
422
+                  <span>{{orderInfo.goods||'暂无'}}</span>
423
+                </p>
424
+              </div>
425
+            </div>
426
+          </div>
427
+          <ng-container *ngIf="orderInfo.taskType.associationType.id==260">
428
+            <div class="info" *ngFor="let item of orderInfo.checkList">
429
+              <div nz-row class="top">
430
+                <div nz-col nzSpan="8">
431
+                  <p>
432
+                    <span class="label">检查项目:</span>
433
+                    <span>
434
+                      <span>
435
+                        <span>{{item.inspectName||'-'}}</span>
436
+                      </span>
437
+                    </span>
438
+                  </p>
439
+                </div>
440
+                <div nz-col nzSpan="8">
441
+                  <p>
442
+                    <span class="label">预约时间:</span>
443
+                    <span>{{item.yyTime||'-'}}</span>
444
+                  </p>
445
+                </div>
446
+                <div nz-col nzSpan="8">
447
+                  <p>
448
+                    <span class="label">叫号信息:</span>
449
+                    <span>{{item.reservationNumber||'-'}}</span>
450
+                  </p>
451
+                </div>
452
+                <div nz-col nzSpan="8">
453
+                  <p>
454
+                    <span class="label">到达时间:</span>
455
+                    <span>{{item.arriveTime||'-'}}</span>
456
+                  </p>
457
+                </div>
458
+                <div nz-col nzSpan="8">
459
+                  <p>
460
+                    <span class="label">检查科室:</span>
461
+                    <span>{{item.execDept?item.execDept.dept:'-'}}</span>
462
+                  </p>
463
+                </div>
464
+                <div nz-col nzSpan="8">
465
+                  <p>
466
+                    <span class="label">是否送达:</span>
467
+                    <span>{{item.arriveTime?'是':'否'}}</span>
468
+                  </p>
469
+                </div>
470
+              </div>
471
+            </div>
472
+          </ng-container>
473
+        </div>
474
+      </div>
475
+    </overlay-scrollbars>
476
+    <!-- 评价内容 -->
477
+    <overlay-scrollbars #osComponentRef7 style="max-height: 400px;">
478
+      <div *ngIf="tabType==2" class="content pingjia">
479
+        <div class="msg">
480
+          <div>评价等级:{{orderInfo.evaluationDetails?orderInfo.evaluationDetails.serviceEvaluation.name:''}}</div>
481
+          <div>评价人:{{orderInfo.evaluationDetails?orderInfo.evaluationDetails.evalutationUser.name:''}}</div>
482
+        </div>
483
+        <div class="con">
484
+          意见内容:{{orderInfo.evaluationDetails?orderInfo.evaluationDetails.remark:''}}
485
+        </div>
486
+      </div>
487
+    </overlay-scrollbars>
488
+    <!-- 积分 -->
489
+    <overlay-scrollbars #osComponentRef8 style="max-height: 400px;">
490
+      <div *ngIf="tabType==3" class="content jifen">
491
+        <div class="table">
492
+          <nz-table class="integralTable" [nzData]="[1,2]" nzSize="middle" [nzShowPagination]="null">
493
+            <thead>
494
+              <tr class="thead">
495
+                <th nzWidth="15%">考核项</th>
496
+                <th nzWidth="10%">分值</th>
497
+                <th nzWidth="60%">计算</th>
498
+                <th nzWidth="15%">实际得分</th>
499
+              </tr>
500
+            </thead>
501
+            <tbody>
502
+              <tr>
503
+                <td>响应时间</td>
504
+                <td>{{orderInfo.grade?orderInfo.grade.estimateResponseGrade:'-'}}</td>
505
+                <td>{{orderInfo.grade?orderInfo.grade.responseDetails:'-'}}</td>
506
+                <td>{{orderInfo.grade?orderInfo.grade.responseGrade:'-'}}</td>
507
+              </tr>
508
+              <tr>
509
+                <td>到达时间</td>
510
+                <td>{{orderInfo.grade?orderInfo.grade.estimateArriveGrade:'-'}}</td>
511
+                <td>{{orderInfo.grade?orderInfo.grade.arriveDetails:'-'}}</td>
512
+                <td>{{orderInfo.grade?orderInfo.grade.arriveGrade:'-'}}</td>
513
+              </tr>
514
+              <tr>
515
+                <td>执行时间</td>
516
+                <td>{{orderInfo.grade?orderInfo.grade.estimateExecutionGrade:'-'}}</td>
517
+                <td>{{orderInfo.grade?orderInfo.grade.executionDetails:'-'}}</td>
518
+                <td>{{orderInfo.grade?orderInfo.grade.executionGrade:'-'}}</td>
519
+              </tr>
520
+              <tr>
521
+                <td>基础分</td>
522
+                <td>{{orderInfo.grade?orderInfo.grade.estimateBaseGrade:'-'}}</td>
523
+                <td>{{orderInfo.grade?orderInfo.grade.baseDetails:'-'}}</td>
524
+                <td>{{orderInfo.grade?orderInfo.grade.baseGrade:'-'}}</td>
525
+              </tr>
526
+              <tr>
527
+                <td>评价分</td>
528
+                <td>{{orderInfo.grade?orderInfo.grade.estimateEvaluationGrade:'-'}}</td>
529
+                <td>{{orderInfo.grade?orderInfo.grade.evaluationDetails:'-'}}</td>
530
+                <td>{{orderInfo.grade?orderInfo.grade.evaluationGrade:'-'}}</td>
531
+              </tr>
532
+              <tr>
533
+                <td>楼栋分</td>
534
+                <td>{{orderInfo.grade?orderInfo.grade.estimateBuildingGrade:'-'}}</td>
535
+                <td>{{orderInfo.grade?orderInfo.grade.buildingDetails:'-'}}</td>
536
+                <td>{{orderInfo.grade?orderInfo.grade.buildingGrade:'-'}}</td>
537
+              </tr>
538
+              <tr>
539
+                <td>最终得分</td>
540
+                <td>{{orderInfo.grade?orderInfo.grade.estimateGradeTotal:'-'}}</td>
541
+                <td>{{orderInfo.grade?orderInfo.grade.totalDetails:'-'}}</td>
542
+                <td>{{orderInfo.grade?orderInfo.grade.gradeTotal:'-'}}</td>
543
+              </tr>
544
+            </tbody>
545
+          </nz-table>
546
+        </div>
547
+      </div>
548
+    </overlay-scrollbars>
549
+    <!-- 历史记录 -->
550
+    <overlay-scrollbars #osComponentRef2 style="max-height: 400px;">
551
+      <div *ngIf="tabType==4" class="content jifen">
552
+        <div class="table">
553
+          <nz-table class="integralTable" [nzData]="[1,2]" nzSize="middle" [nzShowPagination]="null">
554
+            <thead>
555
+              <tr class="thead">
556
+                <th nzWidth="5%">序号</th>
557
+                <th nzWidth="30%">操作动作</th>
558
+                <th nzWidth="15%">操作时间</th>
559
+                <th nzWidth="10%">操作人</th>
560
+                <th nzWidth="10%">图片查看</th>
561
+                <th nzWidth="30%">异常关闭原因</th>
562
+              </tr>
563
+            </thead>
564
+            <tbody>
565
+              <tr *ngFor="let item of workOrderRecord;let i = index;">
566
+                <td>{{i+1}}</td>
567
+                <td>{{item.operation?item.operation.name:'-'}}</td>
568
+                <td>{{item.operationTime||'-'}}</td>
569
+                <td>{{item.username||'-'}}</td>
570
+                <td><button *ngIf="item.attachments"
571
+                    (click)="previewImageHandler(item.attachments[0].token)">查看图片</button><span
572
+                    *ngIf="!item.attachments">无</span></td>
573
+                <td>{{item.specialCloseReason === 'true'?orderInfo.specialCloseReason:'-'}}</td>
574
+              </tr>
575
+            </tbody>
576
+          </nz-table>
577
+        </div>
578
+      </div>
579
+    </overlay-scrollbars>
580
+  </div>
581
+  <div class="btns">
582
+    <button class=" btn cancel" nz-button nzType="default" (click)="close()">关闭</button>
583
+  </div>
584
+</div>
585
+<!-- 操作成功/失败提示框 -->
586
+<app-prompt-modal *ngIf="promptModalShow" [content]="promptContent" [success]="ifSuccess" [show]="promptModalShow"
587
+  [info]="promptInfo" (closeModel)="close()">
588
+  <!-- 2.父组件调用子组件时绑定到这个事件属性,并在事件发生时作出回应。(closeModel)="close()" -->
589
+</app-prompt-modal>
590
+<!-- 图片提示框 -->
591
+<app-prompt-modal *ngIf="promptModalShowImg" [show]="promptModalShowImg" (closeModel)="closeImg()"
592
+  [previewImage]="previewImage">
593
+</app-prompt-modal>
594
+<!-- 遮罩 -->
595
+<app-mask *ngIf="maskFlag"></app-mask>

+ 520 - 0
src/app/share/order-detail/order-detail.component.less

@@ -0,0 +1,520 @@
1
+@import "../../../../src/theme.less";
2
+:host {
3
+  width: 100%;
4
+  height: 100%;
5
+  position: fixed;
6
+  left: 0;
7
+  top: 0;
8
+  background: rgba(0, 0, 0, 0.4);
9
+  z-index: 99;
10
+
11
+  display: flex;
12
+  justify-content: center;
13
+  align-items: center;
14
+}
15
+
16
+.detail {
17
+  width: 1000px;
18
+  max-height: 580px;
19
+  border-radius: 5px;
20
+  background: #fff;
21
+  color: #333;
22
+  font-size: 14px;
23
+  padding: 12px 20px;
24
+  position: relative;
25
+  padding-bottom: 70px;
26
+
27
+  .title {
28
+    font-size: 18px;
29
+    text-align: center;
30
+    line-height: 24px;
31
+    margin: 0;
32
+    margin-bottom: 12px;
33
+    position: relative;
34
+
35
+    i {
36
+      position: absolute;
37
+      right: 0;
38
+      top: 0;
39
+      font-size: 20px;
40
+      color: #666;
41
+      cursor: pointer;
42
+      padding: 0 5px;
43
+    }
44
+  }
45
+
46
+  & > .box {
47
+    width: 960px;
48
+    border: 1px solid #e5e9ed;
49
+    border-radius: 5px;
50
+    overflow: hidden;
51
+
52
+    .tab {
53
+      width: 100%;
54
+      height: 60px;
55
+      border-bottom: 1px solid #e5e9ed;
56
+
57
+      .item {
58
+        text-align: center;
59
+        line-height: 60px;
60
+        height: 100%;
61
+        border-right: 1px solid #e5e9ed;
62
+
63
+        &:nth-last-child(1) {
64
+          border: none;
65
+        }
66
+
67
+        &.checked {
68
+          background: #f9fafb;
69
+        }
70
+      }
71
+    }
72
+
73
+    .content {
74
+      width: 100%;
75
+      min-height: 453px;
76
+      max-height: 500px;
77
+
78
+      &.orders {
79
+        background: #f9fafb;
80
+      }
81
+
82
+      & > .top {
83
+        padding: 10px 32px;
84
+        border-bottom: 1px solid #e5e9ed;
85
+        overflow: hidden;
86
+        background: #fff;
87
+
88
+        .num {
89
+          font-size: 16px;
90
+          overflow: hidden;
91
+          margin-bottom: 6px;
92
+
93
+          .left {
94
+            float: left;
95
+            font-weight: 600;
96
+          }
97
+
98
+          .right {
99
+            float: right;
100
+          }
101
+        }
102
+
103
+        .info {
104
+          color: #666;
105
+
106
+          & > div {
107
+            margin: 4px 0;
108
+          }
109
+
110
+          .jiaji {
111
+            margin: 0;
112
+            margin-top: 8px;
113
+          }
114
+        }
115
+      }
116
+
117
+      & > .center {
118
+        padding: 27px 0 17px 0;
119
+        border-bottom: 1px solid #e5e9ed;
120
+        font-size: 12px;
121
+        background: #fff;
122
+
123
+        .box {
124
+          display: flex;
125
+          justify-content: center;
126
+
127
+          .steps {
128
+            &:nth-last-child(1) {
129
+              .line {
130
+                display: none !important;
131
+              }
132
+            }
133
+
134
+            .step {
135
+              .info {
136
+                width: 90px;
137
+                text-align: center;
138
+                display: inline-block;
139
+                vertical-align: top;
140
+
141
+                i {
142
+                  color: #e5e9ed;
143
+
144
+                  &.green {
145
+                    color: #bee1a7;
146
+                  }
147
+                }
148
+              }
149
+
150
+              p {
151
+                margin: 0;
152
+              }
153
+
154
+              .line {
155
+                display: inline-block;
156
+                width: 60px;
157
+                height: 2px;
158
+                background: #e5e9ed;
159
+              }
160
+            }
161
+          }
162
+        }
163
+      }
164
+
165
+      & > .bottom {
166
+        padding: 25px 32px;
167
+        background: #f9fafb;
168
+
169
+        .urgent {
170
+          input {
171
+            width: 600px;
172
+          }
173
+
174
+          .candelBtn {
175
+            margin-left: 20px;
176
+          }
177
+        }
178
+
179
+        .table {
180
+          width: 100%;
181
+          height: 100%;
182
+          min-height: 160px;
183
+          background: #fff;
184
+          border-radius: 5px;
185
+
186
+          .thead {
187
+            background-image: repeating-linear-gradient(
188
+              to right,
189
+              @bg-start,
190
+              @bg-end 100%
191
+            ) !important;
192
+
193
+            th {
194
+              color: #fff !important;
195
+              text-align: center;
196
+              font-size: 12px;
197
+              border: none;
198
+            }
199
+          }
200
+
201
+          .detailDrugTable {
202
+            .thead {
203
+              background-image: repeating-linear-gradient(
204
+                to right,
205
+                @bg-start, @bg-end 50%
206
+              ) !important;
207
+            }
208
+          }
209
+
210
+          .ant-table-tbody {
211
+            tr {
212
+              text-align: center;
213
+              font-size: 12px;
214
+              border: none;
215
+
216
+              td {
217
+                border: none;
218
+              }
219
+            }
220
+
221
+            tr:nth-child(2n) {
222
+              background: #f9fafb;
223
+            }
224
+          }
225
+        }
226
+
227
+        .info {
228
+          width: 100%;
229
+          height: 100%;
230
+          background: #fff;
231
+          border-radius: 5px;
232
+          border: 1px solid #e5e9ed;
233
+          padding: 24px 28px 14px 28px;
234
+          margin-bottom: 8px;
235
+
236
+          .top {
237
+            .left {
238
+              border-right: 1px dashed #e5e9ed;
239
+
240
+              p {
241
+                padding: 0 70px 0 102px;
242
+                overflow: hidden;
243
+
244
+                & > span:nth-child(1) {
245
+                  float: left;
246
+                }
247
+
248
+                & > span:nth-child(2) {
249
+                  float: right;
250
+                  color: #666;
251
+                  text-align: right;
252
+                  max-width: 175px;
253
+                }
254
+              }
255
+            }
256
+
257
+            .right {
258
+              p {
259
+                padding: 0 102px 0 70px;
260
+                overflow: hidden;
261
+
262
+                span:nth-child(1) {
263
+                  float: left;
264
+                }
265
+
266
+                span:nth-child(2) {
267
+                  float: right;
268
+                  color: #666;
269
+                  text-align: right;
270
+                }
271
+              }
272
+            }
273
+          }
274
+
275
+          .wait {
276
+            text-align: center;
277
+            margin-top: 7px;
278
+
279
+            i {
280
+              font-size: 24px;
281
+              color: #62c26d;
282
+            }
283
+
284
+            span {
285
+              color: #62c26d;
286
+            }
287
+          }
288
+        }
289
+      }
290
+
291
+      &.pingjia {
292
+        .msg {
293
+          width: 100%;
294
+          height: 50px;
295
+          line-height: 50px;
296
+          padding-left: 32px;
297
+          border-bottom: 1px solid #e5e9ed;
298
+
299
+          div {
300
+            display: inline-block;
301
+            margin-right: 100px;
302
+          }
303
+        }
304
+
305
+        .con {
306
+          padding: 16px 32px;
307
+          min-height: 360px;
308
+        }
309
+      }
310
+
311
+      & > .form {
312
+        .ant-form-item {
313
+          padding: 0 32px 13px 32px;
314
+          margin-bottom: 0;
315
+          border-bottom: 1px solid #e5e9ed;
316
+
317
+          &:nth-last-child(1) {
318
+            border: none;
319
+          }
320
+        }
321
+
322
+        .ant-form-item-label {
323
+          line-height: 34px;
324
+          text-align: left;
325
+        }
326
+      }
327
+
328
+      & > .mediation {
329
+        padding: 16px 32px;
330
+
331
+        .item {
332
+          border-bottom: 1px solid #e5e9ed;
333
+          padding-top: 10px;
334
+
335
+          .label {
336
+            line-height: 28px;
337
+            margin-top: 10px;
338
+          }
339
+
340
+          .info {
341
+            line-height: 28px;
342
+            color: #999;
343
+            padding-bottom: 20px;
344
+          }
345
+        }
346
+      }
347
+
348
+      &.jifen {
349
+        padding: 32px;
350
+
351
+        & > .table {
352
+          width: 100%;
353
+          height: 100%;
354
+          min-height: 160px;
355
+          padding: 6px;
356
+          background: #fff;
357
+          border: 1px solid #e5e9ed;
358
+          border-radius: 5px;
359
+          overflow: hidden;
360
+
361
+          .thead {
362
+            background-image: repeating-linear-gradient(
363
+              to right,
364
+              @bg-start,
365
+              @bg-end 100%
366
+            ) !important;
367
+
368
+            th {
369
+              color: #fff !important;
370
+              text-align: center;
371
+              font-size: 12px;
372
+              border: none;
373
+              background: transparent;
374
+            }
375
+          }
376
+
377
+          .ant-table-tbody {
378
+            tr {
379
+              text-align: center;
380
+              font-size: 12px;
381
+              border: none;
382
+
383
+              td {
384
+                border: none;
385
+              }
386
+            }
387
+
388
+            tr:nth-child(2n) {
389
+              background: #f9fafb;
390
+            }
391
+          }
392
+        }
393
+      }
394
+    }
395
+  }
396
+
397
+  .btns {
398
+    display: flex;
399
+    justify-content: center;
400
+    align-items: center;
401
+    width: 100%;
402
+    position: absolute;
403
+    left: 0;
404
+    bottom: 20px;
405
+
406
+    .btn {
407
+      margin: 9px;
408
+      margin-bottom: 0;
409
+    }
410
+  }
411
+
412
+  .ant-table {
413
+    border: none !important;
414
+  }
415
+}
416
+
417
+// 撤回工单
418
+.recallOrder {
419
+  position: fixed;
420
+  left: 0;
421
+  top: 0;
422
+  width: 100%;
423
+  height: 100%;
424
+
425
+  display: flex;
426
+  justify-content: center;
427
+  align-items: center;
428
+  background: rgba(0, 0, 0, 0.4);
429
+  z-index: 99;
430
+
431
+  .modalBody {
432
+    width: 350px;
433
+    height: 220px;
434
+    background: #fff;
435
+    border-radius: 5px;
436
+    padding: 10px 20px;
437
+    color: #333;
438
+
439
+    .title {
440
+      width: 100%;
441
+      text-align: center;
442
+      font-size: 18px;
443
+      position: relative;
444
+
445
+      i {
446
+        position: absolute;
447
+        right: 0;
448
+        top: 0;
449
+        font-size: 20px;
450
+        color: #666;
451
+        cursor: pointer;
452
+        padding: 0 5px;
453
+      }
454
+    }
455
+
456
+    .content {
457
+      width: 310px;
458
+      height: 117px;
459
+      background: #f9fafb;
460
+      border: 1px solid #e5e9ed;
461
+      border-radius: 5px;
462
+      overflow: hidden;
463
+      margin-top: 12px;
464
+
465
+      div {
466
+        text-align: center;
467
+        margin: 0;
468
+
469
+        &.icon {
470
+          margin-top: 17px;
471
+
472
+          i {
473
+            color: #ff3b53;
474
+            font-size: 30px !important;
475
+
476
+            &.transport-wenhao {
477
+              color: #f5a523;
478
+            }
479
+          }
480
+        }
481
+
482
+        &.defeat {
483
+          color: #333;
484
+          font-size: 18px;
485
+        }
486
+
487
+        &:nth-child(3) {
488
+          font-size: 14px;
489
+          color: #666;
490
+        }
491
+      }
492
+
493
+      .conditions {
494
+        padding: 16px 20px;
495
+
496
+        div {
497
+          text-align: left;
498
+        }
499
+      }
500
+    }
501
+
502
+    button {
503
+      margin-top: 10px;
504
+
505
+      &.btn {
506
+        margin-left: 8px;
507
+      }
508
+    }
509
+  }
510
+}
511
+
512
+.txtC {
513
+  text-align: center;
514
+}
515
+.ji {
516
+  position: absolute;
517
+  right: 0px;
518
+  top: -3px;
519
+  width: 30px;
520
+}

+ 215 - 0
src/app/share/order-detail/order-detail.component.ts

@@ -0,0 +1,215 @@
1
+import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
2
+import { ActivatedRoute } from '@angular/router';
3
+import { FormBuilder, Validators, FormGroup, FormControl } from '@angular/forms';
4
+import { MainService } from '../../services/main.service';
5
+import { OverlayScrollbarsComponent } from 'overlayscrollbars-ngx';
6
+import { NzMessageService } from 'ng-zorro-antd';
7
+import { forkJoin } from 'rxjs';
8
+@Component({
9
+  selector: 'app-order-detail',
10
+  templateUrl: './order-detail.component.html',
11
+  styleUrls: ['./order-detail.component.less']
12
+})
13
+export class OrderDetailComponent implements OnInit {
14
+  @ViewChild('osComponentRef1', { read: OverlayScrollbarsComponent, static: false })
15
+  osComponentRef1: OverlayScrollbarsComponent;
16
+  @ViewChild('osComponentRef2', { read: OverlayScrollbarsComponent, static: false })
17
+  osComponentRef2: OverlayScrollbarsComponent;
18
+  @ViewChild('osComponentRef3', { read: OverlayScrollbarsComponent, static: false })
19
+  osComponentRef3: OverlayScrollbarsComponent;
20
+  @ViewChild('osComponentRef4', { read: OverlayScrollbarsComponent, static: false })
21
+  osComponentRef4: OverlayScrollbarsComponent;
22
+  @ViewChild('osComponentRef5', { read: OverlayScrollbarsComponent, static: false })
23
+  osComponentRef5: OverlayScrollbarsComponent;
24
+  @ViewChild('osComponentRef6', { read: OverlayScrollbarsComponent, static: false })
25
+  osComponentRef6: OverlayScrollbarsComponent;
26
+  @ViewChild('osComponentRef7', { read: OverlayScrollbarsComponent, static: false })
27
+  osComponentRef7: OverlayScrollbarsComponent;
28
+  @ViewChild('osComponentRef8', { read: OverlayScrollbarsComponent, static: false })
29
+  osComponentRef8: OverlayScrollbarsComponent;
30
+  constructor(
31
+    private message: NzMessageService,
32
+    private fb: FormBuilder,
33
+    private route: ActivatedRoute,
34
+    private mainService: MainService,
35
+  ) { }
36
+  maskFlag: any = false;
37
+  id: number;//工单id
38
+  orderInfo: any;//工单详情信息
39
+  endDepts = '';//工单详情目标科室
40
+  showCoop: boolean = true;//是否展示详情页操作按钮
41
+
42
+  promptContent: string;//操作提示框提示信息
43
+  ifSuccess: boolean;//操作成功/失败
44
+  promptInfo: string;//操作结果提示信息
45
+  previewImage: string;//操作结果图片预览
46
+  promptModalShow: boolean;//是否展示提示框
47
+  promptModalShowImg: boolean;//是否展示提示框-图片
48
+
49
+  urgentLoading: boolean = false;//确认加急按钮loading状态
50
+  recLoading: boolean = false;//撤回并删除按钮loading状态
51
+  btnLoading: boolean = false;//确认按钮loading状态
52
+
53
+
54
+  ngOnInit() {
55
+    this.tabType = this.route.snapshot.params.type || 1;
56
+    this.getInfo()
57
+    this.initForm()
58
+  }
59
+  ngOnDestroy() {
60
+  }
61
+
62
+  // 获取工单详情
63
+  middleDept = [];//中间科室数组
64
+  getInfo() {
65
+    this.id = +this.route.snapshot.paramMap.get('id');
66
+    this.maskFlag = this.message.loading('正在加载中..', { nzDuration: 0 }).messageId;
67
+    this.mainService.getApiFetchData('workOrder', this.id).subscribe(data => {
68
+      this.orderInfo = data.data;
69
+      if (data.data.middleDept) {
70
+        this.middleDept = data.data.middleDept.map(item => item.dept);
71
+      } else {
72
+        this.middleDept = [];
73
+      }
74
+      this.endDepts = data.data.endDepts.map(item => item.dept).join();
75
+      let log$ = this.getLog();
76
+      let record$ = this.getWorkOrderRecord();
77
+      forkJoin(log$, record$).subscribe(res => {
78
+        this.message.remove(this.maskFlag);
79
+        this.maskFlag = false;
80
+        // getLog
81
+        this.logList = res[0]['data'];
82
+        // getWorkOrderRecord
83
+        if (res[1]['status'] == 200) {
84
+          this.workOrderRecord = res[1]['data'];
85
+        }
86
+      })
87
+    })
88
+  }
89
+  // 预览图片
90
+  previewImageHandler(token) {
91
+    this.showPromptModalImg(token);
92
+  }
93
+  // 获取历史记录
94
+  workOrderRecord: any = [];
95
+  getWorkOrderRecord() {
96
+    return this.mainService.getWorkOrderRecord({ "gdid": this.id });
97
+  }
98
+  // 切换tab栏
99
+  tabType: number = 1;//tab栏
100
+  checkTab(type) {
101
+    this.tabType = type;
102
+  }
103
+
104
+  // 关闭弹框
105
+  close() {
106
+    history.go(-1);
107
+  }
108
+  closeImg() {
109
+    this.promptModalShowImg = false;
110
+  }
111
+
112
+  // 获取工单历史记录
113
+  logList = [];//工单历史记录
114
+  getLog() {
115
+    return this.mainService.getWorkOrderLog(this.id);
116
+  }
117
+
118
+  // 初始化新增form表单
119
+  validateForm: FormGroup;//新增/编辑表单
120
+  initForm() {
121
+    this.validateForm = this.fb.group({
122
+      reason: [null, [Validators.required]],
123
+      process: [null, [Validators.required]],
124
+      handleType: [null, [Validators.required]],
125
+      improve: [null, [Validators.required]]
126
+    });
127
+  }
128
+
129
+  // 新增表单提交
130
+  submitForm(): void {
131
+    var that = this;
132
+    for (const i in that.validateForm.controls) {
133
+      that.validateForm.controls[i].markAsDirty();
134
+      that.validateForm.controls[i].updateValueAndValidity();
135
+    }
136
+    if (that.validateForm.invalid) return;
137
+    that.btnLoading = true;
138
+    let postData = {
139
+      badEvaluationHandle: {
140
+        id: that.id,
141
+        reasonAndEventProcess: that.validateForm.value.reason,
142
+        mediationProcess: that.validateForm.value.process,
143
+        handleType: { id: that.validateForm.value.handleType },
144
+        advice: that.validateForm.value.improve,
145
+        handleStatus: { key: "bad_evaluation_handle_status", value: "2" }
146
+      }
147
+    }
148
+
149
+    that.mainService.postCustom('adviceCollection', 'updData/badEvaluationHandle', postData).subscribe(data => {
150
+      that.btnLoading = false;
151
+      if (data.status == 200) {
152
+        that.showPromptModal('调解', true, '');
153
+        that.getInfo()
154
+        // that.initForm();
155
+      } else {
156
+        that.showPromptModal('调解', false, data.msg);
157
+      }
158
+    })
159
+
160
+
161
+  }
162
+
163
+
164
+
165
+
166
+  // 展示信息提示框(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)
167
+  showPromptModal(con, success, promptInfo?, previewImage?) {
168
+    this.promptModalShow = false;
169
+    this.promptContent = con;
170
+    this.ifSuccess = success;
171
+    this.promptInfo = promptInfo;
172
+    this.previewImage = previewImage ? previewImage : '';
173
+    setTimeout(() => {
174
+      this.promptModalShow = true;
175
+    }, 100);
176
+  }
177
+  showPromptModalImg(previewImage) {
178
+    this.promptModalShowImg = false;
179
+    this.previewImage = previewImage ? previewImage : '';
180
+    setTimeout(() => {
181
+      this.promptModalShowImg = true;
182
+    }, 100);
183
+  }
184
+
185
+  // 格式化时分秒
186
+  // (时间小于一分钟则显示秒,时间大于一分钟则显示分钟数,如超出一小时则显示小时和分钟。)time单位:秒
187
+  formatTime(time) {
188
+    let timeStr = '';
189
+    if (time >= 0 && time < 60) {
190
+      // 秒
191
+      timeStr = time + '秒';
192
+    } else if (time >= 60 && time < 3600) {
193
+      // 分钟
194
+      timeStr = Math.floor(time / 60) + '分钟'
195
+    } else if (time >= 3600) {
196
+      // 时 + 分
197
+      let h = '';
198
+      let m = '';
199
+      h = Math.floor(time / 3600) + '小时';
200
+      m = (time % 3600) >= 60 ? Math.floor((time % 3600) / 60) + '分钟' : '';
201
+      timeStr = h + m;
202
+    }
203
+    return timeStr;
204
+  }
205
+
206
+  // 计算历史记录耗时
207
+  filterTime(step) {
208
+    // step = [{ difTime: 2 }, { difTime: 6 }]
209
+    let num = 0;
210
+    step.forEach(e => {
211
+      num += e.difTime;
212
+    });
213
+    return this.formatTime(num / 1000);
214
+  }
215
+}

+ 24 - 0
src/app/share/prompt-modal/prompt-modal.component.html

@@ -0,0 +1,24 @@
1
+<div class="modal display_flex justify-content_flex-center align-items_center" *ngIf="show&&!loading">
2
+  <div class="modalBody">
3
+    <div class="title">{{previewImage?'查看图片':'提示'}}<i class="icon_transport transport-guanbi" (click)="hideModal()"></i></div>
4
+    <div class="content" *ngIf="!previewImage">
5
+      <div class="icon"><i
6
+          [ngClass]="{'icon_transport':true, 'transport-duigou':success,'transport-shibai':!success}"></i></div>
7
+      <div class="defeat">{{content}}{{(success?"成功":"失败")}}</div>
8
+      <div *ngIf="info" [innerHTML]="info"></div>
9
+    </div>
10
+    <div class="content" *ngIf="previewImage">
11
+      <img [src]="host+'/common/common/previewAttachmentImage/'+previewImage" class="w100">
12
+    </div>
13
+    <div class="display_flex justify-content_flex-center">
14
+      <button class="btn know" nz-button nzType="primary" nzGhost (click)="hideModal()">知道了</button>
15
+    </div>
16
+  </div>
17
+</div>
18
+<div class="modal display_flex justify-content_flex-center align-items_center" *ngIf="loading">
19
+  <!-- loading -->
20
+  <div class="txtC" style="text-align: center;">
21
+    <img src="../../../assets/images/loading.gif" alt="">
22
+    <!-- <div>加载中...</div> -->
23
+  </div>
24
+</div>

+ 135 - 0
src/app/share/prompt-modal/prompt-modal.component.less

@@ -0,0 +1,135 @@
1
+
2
+.modal {
3
+  position: fixed;
4
+  left: 0;
5
+  top: 0;
6
+  width: 100%;
7
+  height: 100%;
8
+  background: rgba(0, 0, 0, .4);
9
+  z-index: 999999;
10
+
11
+  .modalBody {
12
+    width: 350px;
13
+    min-height: 220px;
14
+    background: #fff;
15
+    border-radius: 5px;
16
+    padding: 10px 20px;
17
+    color: #333;
18
+
19
+
20
+    .title {
21
+      width: 100%;
22
+      text-align: center;
23
+      font-size: 18px;
24
+      position: relative;
25
+
26
+      i {
27
+        position: absolute;
28
+        right: 0;
29
+        top: 0;
30
+        font-size: 20px;
31
+        color: #666;
32
+        cursor: pointer;
33
+        padding: 0 5px;
34
+      }
35
+    }
36
+
37
+    .content {
38
+      width: 310px;
39
+      min-height: 117px;
40
+      max-height: 50vh;
41
+      background: #f9fafb;
42
+      border: 1px solid #e5e9ed;
43
+      border-radius: 5px;
44
+      overflow: auto;
45
+      margin-top: 12px;
46
+
47
+      div {
48
+        text-align: center;
49
+        margin: 0;
50
+
51
+        &.icon {
52
+
53
+          margin-top: 17px;
54
+
55
+          i {
56
+            color: #34b349;
57
+            font-size: 30px !important;
58
+
59
+            &.transport-wenhao {
60
+              color: #f5a523;
61
+            }
62
+
63
+            &.transport-shibai {
64
+              color: #ff3a52;
65
+            }
66
+          }
67
+        }
68
+
69
+        &.defeat {
70
+          color: #333;
71
+          font-size: 14px;
72
+        }
73
+
74
+        &:nth-child(3) {
75
+          font-size: 14px;
76
+          color: #666;
77
+          padding-bottom: 10px;
78
+        }
79
+      }
80
+    }
81
+
82
+    button {
83
+      margin-top: 10px;
84
+
85
+      &.btn {
86
+        margin-left: 8px;
87
+      }
88
+    }
89
+
90
+  }
91
+
92
+  // 新增
93
+  &.add {
94
+    .modalBody {
95
+      width: 480px;
96
+      height: auto;
97
+
98
+      .content {
99
+        width: 100%;
100
+        height: auto;
101
+        padding: 18px 14px 0 14px;
102
+
103
+        .addForm {
104
+          .ant-form-item {
105
+            margin-bottom: 15px;
106
+
107
+            .ant-form-item-label {
108
+              line-height: 0;
109
+            }
110
+          }
111
+        }
112
+
113
+        .editForm {
114
+          .ant-form-item {
115
+            margin-bottom: 15px;
116
+
117
+            .ant-form-item-label {
118
+              line-height: 0;
119
+            }
120
+          }
121
+        }
122
+
123
+      }
124
+
125
+      button {
126
+        &:nth-child(1) {
127
+          margin-right: 20px;
128
+
129
+        }
130
+      }
131
+
132
+    }
133
+  }
134
+
135
+}

+ 42 - 0
src/app/share/prompt-modal/prompt-modal.component.ts

@@ -0,0 +1,42 @@
1
+import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
2
+import host from "../../../assets/js/http.js";
3
+// import { ActivatedRoute, Router } from '@angular/router';
4
+
5
+@Component({
6
+  selector: 'app-prompt-modal',
7
+  templateUrl: './prompt-modal.component.html',
8
+  styleUrls: ['./prompt-modal.component.less']
9
+})
10
+export class PromptModalComponent implements OnInit {
11
+  host=host.host;
12
+  @Input() content: string;
13
+  @Input() success: boolean;
14
+  @Input() show: boolean;
15
+  @Input() info: string;
16
+  @Input() back: string = '';
17
+  @Input() isReLoad: Boolean = false;
18
+  @Input() loading: Boolean = false;
19
+  @Input() previewImage: string = '';
20
+  // @Input() nUrl: string;
21
+
22
+  @Output() closeModel = new EventEmitter<any>();//1.组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件
23
+
24
+  constructor() {}
25
+  // constructor(private router: Router) {}
26
+
27
+  ngOnInit() {
28
+    console.log(this.show);
29
+    console.log(this.previewImage)
30
+  }
31
+  hideModal() {
32
+    this.show = false;
33
+    this.closeModel.emit(this.back);//emits(向上弹射)事件
34
+    // if(this.nUrl){
35
+    //   this.router.navigateByUrl(this.nUrl);
36
+    // }
37
+    if(this.isReLoad){
38
+      location.reload(true)
39
+    }
40
+  }
41
+
42
+}

+ 71 - 0
src/app/share/replication-scheme/replication-scheme.component.html

@@ -0,0 +1,71 @@
1
+<div class="modal display_flex justify-content_flex-center align-items_center" *ngIf="show">
2
+  <div class="modalBody">
3
+    <div class="title">复制方案<i class="icon_transport transport-guanbi" (click)="hideModal()"></i></div>
4
+    <div class="content content-search">
5
+      <div class="defeat-search-wrap">
6
+        <div class="defeat-search">
7
+          将<em>【{{currentTaskType['queryParamsName']}}-{{currentTaskType['taskTypeName']}}-{{currentTaskType['classesName']}}-{{currentTaskType['bindId']==3?'科室绑定人员':'科室绑定分组'}}】</em>
8
+        </div>
9
+      </div>
10
+      <div class="form">
11
+        <!-- 方案名称 -->
12
+        <overlay-scrollbars #osComponentRef1 class="schemeName">
13
+          <ul *ngIf="!loading1&&schemeNameList.length>0">
14
+            <li *ngFor="let item of schemeNameList" (click)="schemeNameClick(item)"
15
+              [ngClass]="{active:schemeNameId==item.id}">{{item.name}}</li>
16
+          </ul>
17
+          <div class="noData" *ngIf="!loading1&&schemeNameList.length===0">
18
+            <div>暂无数据</div>
19
+          </div>
20
+          <div class="loading" *ngIf="loading1">
21
+            <img src="../../../assets/images/loading.gif" alt="">
22
+            <div>加载中...</div>
23
+          </div>
24
+        </overlay-scrollbars>
25
+        <!-- 任务类型名称 -->
26
+        <overlay-scrollbars #osComponentRef2 class="taskTypeName">
27
+          <ul *ngIf="!loading2&&typeList.length>0">
28
+            <li *ngFor="let item of typeList" (click)="typeNameClick(item)" [ngClass]="{active:typeNameId==item.id}">
29
+              {{item.taskName}}</li>
30
+          </ul>
31
+          <div class="noData" *ngIf="!loading2&&typeList.length===0">
32
+            <div>暂无数据</div>
33
+          </div>
34
+          <div class="loading" *ngIf="loading2">
35
+            <img src="../../../assets/images/loading.gif" alt="">
36
+            <div>加载中...</div>
37
+          </div>
38
+        </overlay-scrollbars>
39
+        <!-- 班次 -->
40
+        <overlay-scrollbars #osComponentRef3 class="frequencyName">
41
+          <ul *ngIf="classesList.length>0">
42
+            <li *ngFor="let item of classesList" (click)="classesNameClick(item)" [ngClass]="{active:item.flag}">
43
+              {{item.name}}-{{currentTaskType['bindId']==3?'科室绑定人员':'科室绑定分组'}}
44
+              <i *ngIf="item.flag">√</i>
45
+            </li>
46
+          </ul>
47
+          <div class="noData" *ngIf="classesList.length===0">
48
+            <div>暂无数据</div>
49
+          </div>
50
+        </overlay-scrollbars>
51
+      </div>
52
+    </div>
53
+    <overlay-scrollbars #osComponentRef4 [ngStyle]="{height:'120px'}" class="defeat-search-wrap--foot">
54
+      <div class="defeat-search-wrap">
55
+        <div class="defeat-search defeat-search--foot">复制到</div>
56
+        <div *ngIf="targetResultFlag" class="defeat-search defeat-search--foot" style="color:#f5222d;margin-left: 8px;font-weight: bold;">请选择您要复制到的方案!</div>
57
+        <div class="defeat-search defeat-search--foot xx" *ngFor="let item of targetResult">
58
+          <em>【{{item.schemeName}}-{{item.typeName}}-{{item.classesName}}-{{currentTaskType.bindId==3?'科室绑定人员':'科室绑定分组'}}】</em>
59
+          <i class="icon icon_transport transport-guanbi1" (click)="deleteThis(item)"></i>
60
+        </div>
61
+      </div>
62
+    </overlay-scrollbars>
63
+    <div class="display_flex justify-content_flex-center">
64
+      <button class="btn know" nz-button nzType="primary" [nzLoading]="isLoading" (click)="ok()">确定</button>
65
+      <button class="btn know" nz-button nzType="primary" nzGhost (click)="hideModal()">取消</button>
66
+    </div>
67
+  </div>
68
+</div>
69
+<!-- 操作成功/失败提示框 -->
70
+<app-prompt-modal *ngIf="promptModalShow" [content]="promptContent" [success]="ifSuccess" [show]="promptModalShow"
71
+  [info]="promptInfo"></app-prompt-modal>

+ 226 - 0
src/app/share/replication-scheme/replication-scheme.component.less

@@ -0,0 +1,226 @@
1
+@import "../../../../src/theme.less";
2
+.modal {
3
+  position: fixed;
4
+  left: 0;
5
+  top: 0;
6
+  width: 100%;
7
+  height: 100%;
8
+  background: rgba(0, 0, 0, .4);
9
+  z-index: 999;
10
+  .loading,.noData{
11
+    height: 100%;
12
+    display: flex;
13
+    flex-direction: column;
14
+    justify-content: center;
15
+    align-items: center;
16
+  }
17
+  .noData{
18
+    color: @primary-color;
19
+    font-size: 20px;
20
+    font-weight: bold;
21
+  }
22
+  .modalBody {
23
+    width: 1000px;
24
+    height: 580px;
25
+    background: #fff;
26
+    border-radius: 5px;
27
+    padding: 10px 20px;
28
+    color: #333;
29
+
30
+    .title {
31
+      width: 100%;
32
+      text-align: center;
33
+      font-size: 18px;
34
+      position: relative;
35
+
36
+      i {
37
+        position: absolute;
38
+        right: 0;
39
+        top: 0;
40
+        font-size: 20px;
41
+        color: #666;
42
+        cursor: pointer;
43
+        padding: 0 5px;
44
+      }
45
+    }
46
+    .defeat-search-wrap--foot{
47
+      height: 120px;
48
+      border-bottom: solid 1px #e5e9ed;
49
+      border-left: solid 1px #e5e9ed;
50
+      border-right: solid 1px #e5e9ed;
51
+      border-bottom-left-radius: 5px;
52
+      border-bottom-right-radius: 5px;
53
+    }
54
+    .defeat-search-wrap{
55
+      width: 100%;
56
+      display: flex;
57
+      flex-wrap: wrap;
58
+      align-items: center;
59
+      align-content: center;
60
+      padding: 0 16px;
61
+    }
62
+    .defeat-search{
63
+      height: 40px;
64
+      display: flex;
65
+      align-items: center;
66
+      &.defeat-search--foot{
67
+        height: 26px;
68
+        margin-top: 3px;
69
+        &.xx{
70
+          border: 1px solid #dde1e5;
71
+          background-color: #f9fafb;
72
+          margin-left: 8px;
73
+          padding-right: 4px;
74
+          i{
75
+            color: #e5e9ed;
76
+            cursor: pointer;
77
+            &:hover{
78
+              color: #ff3b53;
79
+            }
80
+          }
81
+        }
82
+      }
83
+      em{
84
+        color: #333;
85
+        font-style: normal;
86
+        font-weight: bold;
87
+      }
88
+    }
89
+    .content {
90
+      min-height: 117px;
91
+      background: #f9fafb;
92
+      border: 1px solid #e5e9ed;
93
+      border-top-left-radius: 5px;
94
+      border-top-right-radius: 5px;
95
+      overflow: hidden;
96
+      margin-top: 12px;
97
+      display: flex;
98
+      flex-direction: column;
99
+      justify-content: center;
100
+      align-items: center;
101
+
102
+      &.content-search{
103
+        min-height: 147px;
104
+        justify-content: start;
105
+        .form{
106
+          width: 100%;
107
+          height: 320px;
108
+          display: flex;
109
+          ul{
110
+            list-style: none;
111
+            margin: 0;
112
+            text-align: left;
113
+            padding: 8px;
114
+            li{
115
+              height: 26px;
116
+              padding: 0 8px;
117
+              overflow: hidden;
118
+              text-overflow: ellipsis;
119
+              white-space: nowrap;
120
+              cursor: pointer;
121
+              display: flex;
122
+              justify-content: space-between;
123
+              align-items: center;
124
+              &.active{
125
+                background-color: #f0f6ed;
126
+                color: @primary-color;
127
+                cursor: not-allowed;
128
+              }
129
+            }
130
+          }
131
+          .schemeName{
132
+            width: 25%;
133
+            border-right: 1px solid #e5e9ed;
134
+          }
135
+          .taskTypeName{
136
+            width: 25%;
137
+            border-right: 1px solid #e5e9ed;
138
+          }
139
+          .frequencyName{
140
+            width: 50%;
141
+          }
142
+          ::ng-deep .os-content{
143
+            height: 100%!important;
144
+          }
145
+        }
146
+      }
147
+
148
+      div {
149
+        text-align: center;
150
+        margin: 0;
151
+
152
+        &.defeat {
153
+          color: #333;
154
+          font-size: 28px;
155
+        }
156
+        &.countDown{
157
+          font-size: 14px;
158
+          color: 666;
159
+          em{
160
+            font-style: normal;
161
+            color: @primary-color;
162
+          }
163
+        }
164
+
165
+        &:nth-child(3) {
166
+          font-size: 14px;
167
+          color: #666;
168
+          padding-bottom: 10px;
169
+        }
170
+      }
171
+    }
172
+
173
+    button {
174
+      margin-top: 10px;
175
+
176
+      &.btn {
177
+        margin-left: 8px;
178
+      }
179
+    }
180
+
181
+  }
182
+
183
+  // 新增
184
+  &.add {
185
+    .modalBody {
186
+      width: 480px;
187
+      height: auto;
188
+
189
+      .content {
190
+        width: 100%;
191
+        height: auto;
192
+        padding: 18px 14px 0 14px;
193
+
194
+        .addForm {
195
+          .ant-form-item {
196
+            margin-bottom: 15px;
197
+
198
+            .ant-form-item-label {
199
+              line-height: 0;
200
+            }
201
+          }
202
+        }
203
+
204
+        .editForm {
205
+          .ant-form-item {
206
+            margin-bottom: 15px;
207
+
208
+            .ant-form-item-label {
209
+              line-height: 0;
210
+            }
211
+          }
212
+        }
213
+
214
+      }
215
+
216
+      button {
217
+        &:nth-child(1) {
218
+          margin-right: 20px;
219
+
220
+        }
221
+      }
222
+
223
+    }
224
+  }
225
+
226
+}

+ 228 - 0
src/app/share/replication-scheme/replication-scheme.component.ts

@@ -0,0 +1,228 @@
1
+import { Component, OnInit, Input, Output, EventEmitter, ViewChild } from '@angular/core';
2
+import { MainService } from '../../services/main.service';
3
+import { OverlayScrollbarsComponent } from 'overlayscrollbars-ngx';
4
+import { ToolService } from '../../services/tool.service';
5
+
6
+@Component({
7
+  selector: 'app-replication-scheme',
8
+  templateUrl: './replication-scheme.component.html',
9
+  styleUrls: ['./replication-scheme.component.less']
10
+})
11
+export class ReplicationSchemeComponent implements OnInit {
12
+  @ViewChild('osComponentRef1', { read: OverlayScrollbarsComponent, static: false })
13
+  osComponentRef1: OverlayScrollbarsComponent;
14
+  @ViewChild('osComponentRef2', { read: OverlayScrollbarsComponent, static: false })
15
+  osComponentRef2: OverlayScrollbarsComponent;
16
+  @ViewChild('osComponentRef3', { read: OverlayScrollbarsComponent, static: false })
17
+  osComponentRef3: OverlayScrollbarsComponent;
18
+  @ViewChild('osComponentRef4', { read: OverlayScrollbarsComponent, static: false })
19
+  osComponentRef4: OverlayScrollbarsComponent;
20
+  @Input() show: Boolean;
21
+  @Input() currentTaskType: any;//当前任务类型,班次,绑定方式的数据
22
+
23
+  @Output() closeModelHs = new EventEmitter<any>();//1.组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件
24
+  @Output() reloadModelHs = new EventEmitter<any>();//1.组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件
25
+  loading1 = false;//工作分配方案列表loading
26
+  schemeNameList = [];//工作分配方案列表
27
+  schemeNameId;//工作分配方案id(选中的)
28
+  schemeName;//工作分配方案名称(选中的)
29
+  loading2 = false;//任务类型列表loading
30
+  typeList = [];//任务类型列表
31
+  typeNameId;//任务类型id(选中的)
32
+  typeName;//任务类型名称(选中的)
33
+  classesList = [];//任务类型列表
34
+  classesNameId;//任务类型id(选中的)
35
+  classesName;//任务类型名称(选中的)
36
+  currentHospital;//当前院区
37
+
38
+  targetResult = [];//复制到的方案集合
39
+  targetResultFlag = false;//必选
40
+  isLoading = false;
41
+  constructor(private tool: ToolService, private mainService: MainService) { }
42
+
43
+  ngOnInit() {
44
+    this.currentHospital = this.tool.getCurrentHospital();
45
+    this.getSchemeNameList();
46
+  }
47
+  // 获取工作分配方案列表
48
+  getSchemeNameList() {
49
+    this.loading1 = true;
50
+    let data = {
51
+      idx: 0,
52
+      sum: 999,
53
+      workScheme: {
54
+        "hosId": this.currentHospital.id
55
+      }
56
+    }
57
+    this.mainService.getFetchDataList('configuration', 'workScheme', data).subscribe(data => {
58
+      this.loading1 = false;
59
+      if (data.status == 200) {
60
+        this.schemeNameList = data.list;
61
+      }
62
+    })
63
+  }
64
+  // 分配方案选中
65
+  schemeNameClick(o) {
66
+    console.log(o)
67
+    this.classesList = [];
68
+    this.typeNameId = null;
69
+    this.schemeNameId = o.id;
70
+    this.schemeName = o.name;
71
+    this.getTypeList(o.id);
72
+  }
73
+  // 获取任务类型
74
+  getTypeList(id) {
75
+    this.loading2 = true;
76
+    let data = {
77
+      idx: 0,
78
+      sum: 999,
79
+      taskType: {
80
+        schemeId: id,
81
+        hosIds: this.currentHospital.id + ''
82
+      }
83
+    }
84
+    this.mainService.getFetchDataList('configuration', 'taskType', data).subscribe(data => {
85
+      this.loading2 = false;
86
+      this.typeList = data.list;
87
+      if (this.currentTaskType['bindId'] == 4) {//科室绑定分组,需要过滤,只能选择相同班次
88
+        this.typeList = this.typeList.filter(item => {//筛选有该班次的任务类型
89
+          let arr = [];
90
+          item.classesIds.forEach(item1 => {
91
+            arr.push(item1.id);
92
+          })
93
+          return arr.includes(this.currentTaskType['classesId']);
94
+        });
95
+        this.typeList.forEach(item => {//筛选有该班次的任务类型
96
+          item.classesIds = item.classesIds.filter(item1 => item1.id == this.currentTaskType['classesId']);
97
+        });
98
+        //过滤当前任务类型
99
+        if (this.schemeNameId == this.currentTaskType['queryParamsId']) {
100
+          this.typeList = this.typeList.filter(item => item.id != this.currentTaskType['taskTypeId']);
101
+        }
102
+      } else if (this.currentTaskType['bindId'] == 3 && this.schemeNameId == this.currentTaskType['queryParamsId']) {//科室绑定人员,去除当前班次
103
+        this.typeList.forEach(item => {
104
+          if (item.id == this.currentTaskType['taskTypeId']) {
105
+            let index = item.classesIds.findIndex(item1 => item1.id == this.currentTaskType['classesId']);
106
+            item.classesIds.splice(index, 1);
107
+          }
108
+        })
109
+      }
110
+    })
111
+  }
112
+  // 任务类型选中
113
+  typeNameClick(o) {
114
+    console.log(o)
115
+    this.classesNameId = null;
116
+    this.typeNameId = o.id;
117
+    this.typeName = o.taskName;
118
+    this.getClassesList(o.id);
119
+  }
120
+  // 获取班次
121
+  getClassesList(id) {
122
+    let obj = this.typeList.find(item => item.id == id);
123
+    this.classesList = obj.classesIds;
124
+    this.classesList.forEach(item => {
125
+      item.flag = false;
126
+    });
127
+    this.classesList.forEach(item => {
128
+      this.targetResult.forEach(item1 => {
129
+        if (this.schemeNameId == item1.schemeId && item.id == item1.classId && item1.schemeId == this.schemeNameId && item1.taskTypeId == this.typeNameId) {
130
+          item.flag = true;
131
+        }
132
+      });
133
+    });
134
+  }
135
+  // 班次选中
136
+  classesNameClick(o) {
137
+    console.log(o);
138
+    let obj = this.targetResult.find(item => item.schemeId == this.schemeNameId && item.classId == o.id && item.schemeId == this.schemeNameId && item.taskTypeId == this.typeNameId);
139
+    if (obj) {
140
+      return;
141
+    }
142
+    this.classesList.find(item => item.id == o.id).flag = true;//选中项高亮
143
+    this.classesNameId = o.id;
144
+    this.classesName = o.name;
145
+    this.targetResult.push({
146
+      "schemeId": this.schemeNameId,
147
+      "taskTypeId": this.typeNameId,
148
+      "classId": this.classesNameId,
149
+      "schemeName": this.schemeName,//x
150
+      "typeName": this.typeName,//x
151
+      "classesName": this.classesName,//x
152
+      "bindingType": this.currentTaskType['bindId'] == 3 ? 1 : 2
153
+    });
154
+    this.targetResultFlag = false;
155
+    console.log(this.targetResult);
156
+  }
157
+  // 删除复制到的方案
158
+  deleteThis(o) {
159
+    console.log(o);
160
+    let objs = this.targetResult.filter(item => !(item.schemeId == o.schemeId && item.classId == o.classId && item.schemeId == o.schemeId && item.taskTypeId == o.taskTypeId));
161
+    this.targetResult = objs;
162
+    this.getClassesList(this.typeNameId);
163
+  }
164
+  // 关闭弹窗
165
+  hideModal() {
166
+    this.targetResultFlag = false;
167
+    this.targetResult = [];
168
+    this.schemeNameId = null;//工作分配方案id(选中的)
169
+    this.typeList = [];//任务类型列表
170
+    this.typeNameId = null;//任务类型id(选中的)
171
+    this.classesList = [];//任务类型列表
172
+    this.classesNameId = null;//任务类型id(选中的)
173
+    this.closeModelHs.emit(JSON.stringify({ show: false }));//emits(向上弹射)事件
174
+  }
175
+  // 确定
176
+  ok() {
177
+    if (this.targetResult.length === 0) {
178
+      this.targetResultFlag = true;
179
+      return;
180
+    }
181
+    let target = this.targetResult.map(item => {
182
+      return {
183
+        "schemeId": item.schemeId,
184
+        "taskTypeId": item.taskTypeId,
185
+        "classId": item.classId,
186
+        "bindingType": item.bindingType
187
+      }
188
+    });
189
+    let dataObj = {
190
+      "source": {
191
+        "schemeId": this.currentTaskType['queryParamsId'],
192
+        "taskTypeId": this.currentTaskType['taskTypeId'],
193
+        "classId": this.currentTaskType['classesId'],
194
+        "bindingType": this.currentTaskType['bindId'] == 3 ? 1 : 2
195
+      },
196
+      "target": target
197
+    }
198
+    console.log(dataObj);
199
+    this.isLoading = true;
200
+    this.mainService.coopConfig('allocatePropertyCopy', dataObj).subscribe(data => {
201
+      this.isLoading = false;
202
+      this.hideModal();
203
+      if (data.status == 200) {
204
+        this.showPromptModal('复制', true, '')
205
+        this.reloadModelHs.emit(JSON.stringify({ show: true }));//emits(向上弹射)事件
206
+      } else {
207
+        this.showPromptModal('复制', false, data.msg)
208
+      }
209
+    })
210
+  }
211
+
212
+  // 展示信息提示框(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)
213
+  promptModalShow = false;
214
+  promptContent = '';
215
+  ifSuccess = false;
216
+  promptInfo = '';
217
+  showPromptModal(con, success, promptInfo?) {
218
+    this.promptModalShow = false;
219
+    this.promptContent = con;
220
+    this.ifSuccess = success;
221
+    this.promptInfo = promptInfo;
222
+    setTimeout(() => {
223
+      this.promptModalShow = true;
224
+    }, 100);
225
+  }
226
+}
227
+
228
+

+ 28 - 0
src/app/share/select-dept/select-dept.component.html

@@ -0,0 +1,28 @@
1
+<div class="save add display_flex align-items_center justify-content_flex-center" *ngIf="deptFlag">
2
+  <div class="modalBody">
3
+    <div class="title">选择转入科室<i class="icon_transport transport-guanbi" (click)="hideModal()"></i>
4
+    </div>
5
+    <div class="content">
6
+      <form nz-form [formGroup]="validateForm" class="addForm">
7
+        <nz-form-item>
8
+          <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="zrDept">转入科室</nz-form-label>
9
+          <nz-form-control nzErrorTip="请选择转入科室!">
10
+            <nz-select [nzDropdownMatchSelectWidth]="false" type="zrDept" nzShowSearch nzServerSearch (nzOnSearch)="getDept(hosId,$event)"
11
+              formControlName="zrDept" nzPlaceHolder="请选择转入科室">
12
+              <ng-container *ngFor="let data of deptList">
13
+                <nz-option *ngIf="!loading" [nzValue]="data['id']" [nzLabel]="data['dept']"></nz-option>
14
+              </ng-container>
15
+              <nz-option *ngIf="loading" nzDisabled nzCustomContent>
16
+                <i nz-icon nzType="loading" class="loading-icon"></i> 加载中...
17
+              </nz-option>
18
+            </nz-select>
19
+          </nz-form-control>
20
+        </nz-form-item>
21
+      </form>
22
+    </div>
23
+    <div class="display_flex justify-content_flex-center">
24
+      <button nzType="primary" nz-button (click)="submitForm()" [nzLoading]="createLoading">确认</button>
25
+      <button class="btn cancel" nz-button nzType="default" (click)="hideModal()">取消</button>
26
+    </div>
27
+  </div>
28
+</div>

+ 125 - 0
src/app/share/select-dept/select-dept.component.less

@@ -0,0 +1,125 @@
1
+.save {
2
+  position: fixed;
3
+  left: 0;
4
+  top: 0;
5
+  width: 100%;
6
+  height: 100%;
7
+  background: rgba(0, 0, 0, 0.4);
8
+  z-index: 999;
9
+
10
+  .modalBody {
11
+    width: 350px;
12
+    background: #fff;
13
+    border-radius: 5px;
14
+    padding: 10px 20px;
15
+    color: #333;
16
+
17
+    .title {
18
+      width: 100%;
19
+      text-align: center;
20
+      font-size: 18px;
21
+      position: relative;
22
+
23
+      i {
24
+        position: absolute;
25
+        right: 0;
26
+        top: 0;
27
+        font-size: 20px;
28
+        color: #666;
29
+        cursor: pointer;
30
+        padding: 0 5px;
31
+      }
32
+    }
33
+
34
+    .content {
35
+      width: 100%;
36
+      height: 117px;
37
+      background: #f9fafb;
38
+      border: 1px solid #e5e9ed;
39
+      border-radius: 5px;
40
+      overflow: hidden;
41
+      margin-top: 12px;
42
+
43
+      div {
44
+        text-align: center;
45
+        margin: 0;
46
+
47
+        &.icon {
48
+          margin-top: 17px;
49
+
50
+          i {
51
+            color: #34b349;
52
+            font-size: 30px !important;
53
+
54
+            &.transport-wenhao {
55
+              color: #f5a523;
56
+            }
57
+
58
+            &.transport-shibai {
59
+              color: #ff3a52;
60
+            }
61
+          }
62
+        }
63
+
64
+        &.defeat {
65
+          color: #333;
66
+          font-size: 16px;
67
+        }
68
+
69
+        &:nth-child(3) {
70
+          font-size: 14px;
71
+          color: #666;
72
+        }
73
+      }
74
+    }
75
+
76
+    button {
77
+      margin-top: 10px;
78
+
79
+      &.btn {
80
+        margin-left: 8px;
81
+      }
82
+    }
83
+  }
84
+
85
+  // 新增
86
+  &.add {
87
+    .modalBody {
88
+      width: 480px;
89
+      height: auto;
90
+
91
+      .content {
92
+        width: 100%;
93
+        height: auto;
94
+        padding: 19px 14px 0 14px;
95
+        max-height: 500px;
96
+        overflow-y: auto;
97
+
98
+        .addForm {
99
+          .ant-form-item {
100
+            margin-bottom: 14px;
101
+
102
+            .ant-form-item-label {
103
+              line-height: 14px;
104
+              text-align: left;
105
+            }
106
+          }
107
+        }
108
+
109
+        .editForm {
110
+          .ant-form-item {
111
+            margin-bottom: 14px;
112
+
113
+            .ant-form-item-label {
114
+              line-height: 0;
115
+            }
116
+          }
117
+        }
118
+      }
119
+
120
+      button:nth-child(1) {
121
+        margin-right: 20px;
122
+      }
123
+    }
124
+  }
125
+}

+ 72 - 0
src/app/share/select-dept/select-dept.component.ts

@@ -0,0 +1,72 @@
1
+import { Component, OnInit, Output, Input } from '@angular/core';
2
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
3
+import { EventEmitter } from '@angular/core';
4
+import { MainService } from '../../services/main.service';
5
+
6
+@Component({
7
+  selector: 'app-select-dept',
8
+  templateUrl: './select-dept.component.html',
9
+  styleUrls: ['./select-dept.component.less']
10
+})
11
+export class SelectDeptComponent implements OnInit {
12
+  @Output() submitFormHand = new EventEmitter();
13
+  @Output() deptFlagHand = new EventEmitter();
14
+  @Input() deptFlag: boolean = false;//模态框
15
+  @Input() createLoading: boolean = false;//确定按钮的loading
16
+  @Input() hosId: any;//院区id
17
+  loading = false;//获取科室的loading
18
+  validateForm: FormGroup;//表单
19
+  deptList = [];//护理单元科室列表
20
+  constructor(private fb: FormBuilder, private mainService: MainService) { }
21
+
22
+  ngOnInit() {
23
+    this.getDept(this.hosId);
24
+    this.initForm()
25
+  }
26
+  // 隐藏模态框
27
+  hideModal() {
28
+    this.deptFlagHand.emit(false)
29
+    this.initForm()
30
+  }
31
+  // 初始化新增form表单
32
+  initForm() {
33
+    this.validateForm = this.fb.group({
34
+      zrDept: [null, [Validators.required]]
35
+    });
36
+  }
37
+  //获取护理单元类型的科室
38
+  getDept(id, keyword = "") {
39
+    this.loading = true;
40
+    let postData = {
41
+      "idx": 0,
42
+      "sum": 10,
43
+      "department": {
44
+        "hospital": {
45
+          "id": id
46
+        },
47
+        "dept": keyword,
48
+        "type": {
49
+          "id": "281"
50
+        }
51
+      }
52
+    };
53
+    this.mainService.getFetchDataList('data','department', postData).subscribe(result => {
54
+      this.loading = false;
55
+      if (result.status == 200) {
56
+        this.deptList = result.list;
57
+      }
58
+    })
59
+  }
60
+  // 表单提交
61
+  submitForm(): void {
62
+    for (const i in this.validateForm.controls) {
63
+      this.validateForm.controls[i].markAsDirty({ onlySelf: true });
64
+      this.validateForm.controls[i].updateValueAndValidity();
65
+    }
66
+    if (this.validateForm.invalid) return;
67
+    let id = this.validateForm.value.zrDept;
68
+    this.submitFormHand.emit(id);
69
+    this.hideModal();
70
+  }
71
+}
72
+

+ 24 - 0
src/app/share/select-hospital/select-hospital.component.html

@@ -0,0 +1,24 @@
1
+<div class="save add display_flex align-items_center justify-content_flex-center" *ngIf="hosFlag">
2
+  <div class="modalBody">
3
+    <div class="title">选择院区<i class="icon_transport transport-guanbi" (click)="hideModal()"></i>
4
+    </div>
5
+    <div class="content">
6
+      <form nz-form [formGroup]="validateForm" class="addForm">
7
+        <nz-form-item>
8
+          <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="affiliatedHospital">所属院区</nz-form-label>
9
+          <nz-form-control nzErrorTip="请选择所属院区!">
10
+            <nz-select [nzDropdownMatchSelectWidth]="false" type="affiliatedHospital" nzShowSearch
11
+              formControlName="affiliatedHospital" nzPlaceHolder="请选择所属院区">
12
+              <nz-option nzLabel="{{data['hosName']}}" nzValue="{{data['id']}}" *ngFor="let data of allHospital">
13
+              </nz-option>
14
+            </nz-select>
15
+          </nz-form-control>
16
+        </nz-form-item>
17
+      </form>
18
+    </div>
19
+    <div class="display_flex justify-content_flex-center">
20
+      <button nzType="primary" nz-button (click)="submitForm()">确认</button>
21
+      <button class="btn cancel" nz-button nzType="default" (click)="hideModal()">取消</button>
22
+    </div>
23
+  </div>
24
+</div>

+ 125 - 0
src/app/share/select-hospital/select-hospital.component.less

@@ -0,0 +1,125 @@
1
+.save {
2
+  position: fixed;
3
+  left: 0;
4
+  top: 0;
5
+  width: 100%;
6
+  height: 100%;
7
+  background: rgba(0, 0, 0, 0.4);
8
+  z-index: 99;
9
+
10
+  .modalBody {
11
+    width: 350px;
12
+    background: #fff;
13
+    border-radius: 5px;
14
+    padding: 10px 20px;
15
+    color: #333;
16
+
17
+    .title {
18
+      width: 100%;
19
+      text-align: center;
20
+      font-size: 18px;
21
+      position: relative;
22
+
23
+      i {
24
+        position: absolute;
25
+        right: 0;
26
+        top: 0;
27
+        font-size: 20px;
28
+        color: #666;
29
+        cursor: pointer;
30
+        padding: 0 5px;
31
+      }
32
+    }
33
+
34
+    .content {
35
+      width: 100%;
36
+      height: 117px;
37
+      background: #f9fafb;
38
+      border: 1px solid #e5e9ed;
39
+      border-radius: 5px;
40
+      overflow: hidden;
41
+      margin-top: 12px;
42
+
43
+      div {
44
+        text-align: center;
45
+        margin: 0;
46
+
47
+        &.icon {
48
+          margin-top: 17px;
49
+
50
+          i {
51
+            color: #34b349;
52
+            font-size: 30px !important;
53
+
54
+            &.transport-wenhao {
55
+              color: #f5a523;
56
+            }
57
+
58
+            &.transport-shibai {
59
+              color: #ff3a52;
60
+            }
61
+          }
62
+        }
63
+
64
+        &.defeat {
65
+          color: #333;
66
+          font-size: 16px;
67
+        }
68
+
69
+        &:nth-child(3) {
70
+          font-size: 14px;
71
+          color: #666;
72
+        }
73
+      }
74
+    }
75
+
76
+    button {
77
+      margin-top: 10px;
78
+
79
+      &.btn {
80
+        margin-left: 8px;
81
+      }
82
+    }
83
+  }
84
+
85
+  // 新增
86
+  &.add {
87
+    .modalBody {
88
+      width: 480px;
89
+      height: auto;
90
+
91
+      .content {
92
+        width: 100%;
93
+        height: auto;
94
+        padding: 19px 14px 0 14px;
95
+        max-height: 500px;
96
+        overflow-y: auto;
97
+
98
+        .addForm {
99
+          .ant-form-item {
100
+            margin-bottom: 14px;
101
+
102
+            .ant-form-item-label {
103
+              line-height: 14px;
104
+              text-align: left;
105
+            }
106
+          }
107
+        }
108
+
109
+        .editForm {
110
+          .ant-form-item {
111
+            margin-bottom: 14px;
112
+
113
+            .ant-form-item-label {
114
+              line-height: 0;
115
+            }
116
+          }
117
+        }
118
+      }
119
+
120
+      button:nth-child(1) {
121
+        margin-right: 20px;
122
+      }
123
+    }
124
+  }
125
+}

+ 25 - 0
src/app/share/select-hospital/select-hospital.component.spec.ts

@@ -0,0 +1,25 @@
1
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+import { SelectHospitalComponent } from './select-hospital.component';
4
+
5
+describe('SelectHospitalComponent', () => {
6
+  let component: SelectHospitalComponent;
7
+  let fixture: ComponentFixture<SelectHospitalComponent>;
8
+
9
+  beforeEach(async(() => {
10
+    TestBed.configureTestingModule({
11
+      declarations: [ SelectHospitalComponent ]
12
+    })
13
+    .compileComponents();
14
+  }));
15
+
16
+  beforeEach(() => {
17
+    fixture = TestBed.createComponent(SelectHospitalComponent);
18
+    component = fixture.componentInstance;
19
+    fixture.detectChanges();
20
+  });
21
+
22
+  it('should create', () => {
23
+    expect(component).toBeTruthy();
24
+  });
25
+});

+ 47 - 0
src/app/share/select-hospital/select-hospital.component.ts

@@ -0,0 +1,47 @@
1
+import { Component, OnInit, Output, Input } from '@angular/core';
2
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
3
+import { EventEmitter } from '@angular/core';
4
+import { ToolService } from '../../services/tool.service';
5
+
6
+@Component({
7
+  selector: 'app-select-hospital',
8
+  templateUrl: './select-hospital.component.html',
9
+  styleUrls: ['./select-hospital.component.less']
10
+})
11
+export class SelectHospitalComponent implements OnInit {
12
+  @Output() submitFormHand = new EventEmitter();
13
+  @Output() hosFlagHand = new EventEmitter();
14
+  @Input() hosFlag: boolean = false;//模态框
15
+  validateForm: FormGroup;//表单
16
+  allHospital: any;//所有院区
17
+  hosLoading: boolean = false;//确定按钮的loading
18
+  constructor(private fb: FormBuilder, private tool: ToolService) { }
19
+
20
+  ngOnInit() {
21
+    this.allHospital = this.tool.getHospitalList();
22
+    this.initForm()
23
+  }
24
+  // 隐藏模态框
25
+  hideModal() {
26
+    this.hosFlagHand.emit(false)
27
+    this.initForm()
28
+  }
29
+  // 初始化新增form表单
30
+  initForm() {
31
+    this.validateForm = this.fb.group({
32
+      affiliatedHospital: [this.tool.getCurrentHospital().id + '', [Validators.required]]
33
+    });
34
+  }
35
+  // 表单提交
36
+  submitForm(): void {
37
+    for (const i in this.validateForm.controls) {
38
+      this.validateForm.controls[i].markAsDirty({ onlySelf: true });
39
+      this.validateForm.controls[i].updateValueAndValidity();
40
+    }
41
+    if (this.validateForm.invalid) return;
42
+    let id = this.validateForm.value.affiliatedHospital;
43
+    this.hosLoading = true;
44
+    this.submitFormHand.emit(id);
45
+    this.hideModal();
46
+  }
47
+}

+ 88 - 0
src/app/share/share.module.ts

@@ -0,0 +1,88 @@
1
+import { NgModule } from '@angular/core';
2
+import { CommonModule } from '@angular/common';
3
+import { NgZorroAntdModule } from 'ng-zorro-antd';
4
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
5
+import { NgxEchartsModule } from 'ngx-echarts';
6
+import { OverlayscrollbarsModule } from 'overlayscrollbars-ngx';
7
+import { SelectHospitalComponent } from './select-hospital/select-hospital.component';
8
+import { SelectDeptComponent } from './select-dept/select-dept.component';
9
+import { PromptModalComponent } from './prompt-modal/prompt-modal.component';
10
+import { SortablejsModule } from 'ngx-sortablejs';
11
+import { ReplicationSchemeComponent } from './replication-scheme/replication-scheme.component';
12
+import { HsPromptModalComponent } from './hs-prompt-modal/hs-prompt-modal.component';
13
+import { HistoryPromptModalComponent } from './history-prompt-modal/history-prompt-modal.component';
14
+import { DetailSampleComponent } from './detail-sample/detail-sample.component';
15
+import { DetailPatientsComponent } from './detail-patients/detail-patients.component';
16
+import { DetailDrugComponent } from './detail-drug/detail-drug.component';
17
+import { DetailOthersComponent } from './detail-others/detail-others.component';
18
+import { AllocationWorkerComponent } from './allocation-worker/allocation-worker.component';
19
+import { DateTransformPipe } from '../pipes/date-transform.pipe';
20
+import { DragDirective } from '../directives/drag.directive';
21
+import { AppraiseDetailComponent } from './appraise-detail/appraise-detail.component';
22
+import { OrderDetailComponent } from './order-detail/order-detail.component';
23
+import { DialogDeleteComponent } from './dialog-delete/dialog-delete.component';
24
+import { MaskComponent } from './mask/mask.component';
25
+import { GenerateFloorComponent } from './generate-floor/generate-floor.component';
26
+import { BatchOrdersComponent } from './batch-orders/batch-orders.component';
27
+
28
+@NgModule({
29
+  declarations: [
30
+    DetailSampleComponent,
31
+    DetailPatientsComponent,
32
+    DetailDrugComponent,
33
+    DetailOthersComponent,
34
+    AllocationWorkerComponent,
35
+    SelectHospitalComponent,
36
+    SelectDeptComponent,
37
+    PromptModalComponent,
38
+    ReplicationSchemeComponent,
39
+    HsPromptModalComponent,
40
+    HistoryPromptModalComponent,
41
+    AppraiseDetailComponent,
42
+    OrderDetailComponent,
43
+    DateTransformPipe,
44
+    DragDirective,
45
+    DialogDeleteComponent,
46
+    MaskComponent,
47
+    GenerateFloorComponent,
48
+    BatchOrdersComponent,
49
+  ],
50
+  imports: [
51
+    CommonModule,
52
+    NgZorroAntdModule,
53
+    FormsModule,
54
+    ReactiveFormsModule,
55
+    NgxEchartsModule,
56
+    OverlayscrollbarsModule,
57
+    SortablejsModule
58
+  ],
59
+  exports: [
60
+    DetailSampleComponent,
61
+    DetailPatientsComponent,
62
+    DetailDrugComponent,
63
+    DetailOthersComponent,
64
+    AllocationWorkerComponent,
65
+    SelectHospitalComponent,
66
+    SelectDeptComponent,
67
+    PromptModalComponent,
68
+    ReplicationSchemeComponent,
69
+    HsPromptModalComponent,
70
+    HistoryPromptModalComponent,
71
+    AppraiseDetailComponent,
72
+    OrderDetailComponent,
73
+    CommonModule,
74
+    NgZorroAntdModule,
75
+    FormsModule,
76
+    ReactiveFormsModule,
77
+    NgxEchartsModule,
78
+    OverlayscrollbarsModule,
79
+    SortablejsModule,
80
+    DateTransformPipe,
81
+    DragDirective,
82
+    DialogDeleteComponent,
83
+    MaskComponent,
84
+    GenerateFloorComponent,
85
+    BatchOrdersComponent,
86
+  ]
87
+})
88
+export class ShareModule { }

+ 14 - 0
src/app/views/advice-detail/advice-detail-routing.module.ts

@@ -0,0 +1,14 @@
1
+import { NgModule } from '@angular/core';
2
+import { Routes, RouterModule } from '@angular/router';
3
+import { AdviceDetailComponent } from './advice-detail.component';
4
+
5
+
6
+const routes: Routes = [
7
+  { path: '', component: AdviceDetailComponent }
8
+];
9
+
10
+@NgModule({
11
+  imports: [RouterModule.forChild(routes)],
12
+  exports: [RouterModule]
13
+})
14
+export class AdviceDetailRoutingModule { }

+ 22 - 0
src/app/views/advice-detail/advice-detail.component.html

@@ -0,0 +1,22 @@
1
+<div class="detail display_flex justify-content_flex-center align-items_center" *ngIf="!maskFlag">
2
+  <div class="modalBody">
3
+    <div class="title">意见箱 - 查看<i class="icon_transport transport-guanbi" (click)="hideModal()"></i></div>
4
+    <div class="content">
5
+      <div class="top display_flex justify-content_space-between align-items_center">
6
+        <span>填写科室:{{adviceInfo.creatDepartment?adviceInfo.creatDepartment.dept:''}}</span>
7
+        <span>填写时间:{{adviceInfo.createTime}}</span>
8
+      </div>
9
+      <div class="info">
10
+        意见内容:{{adviceInfo.content}}
11
+      </div>
12
+      <div *ngIf="adviceInfo.replyContent" class="info reply">
13
+        回复内容:{{adviceInfo.replyContent}}
14
+      </div>
15
+    </div>
16
+    <div class="display_flex justify-content_flex-center">
17
+      <button class="btn know" nz-button nzType="primary" nzGhost (click)="hideModal()">知道了</button>
18
+    </div>
19
+  </div>
20
+</div>
21
+<!-- 遮罩 -->
22
+<app-mask *ngIf="maskFlag"></app-mask>

+ 119 - 0
src/app/views/advice-detail/advice-detail.component.less

@@ -0,0 +1,119 @@
1
+.detail {
2
+  position: fixed;
3
+  left: 0;
4
+  top: 0;
5
+  width: 100%;
6
+  height: 100%;
7
+  // display: flex;
8
+  // justify-content: center;
9
+  // align-items: center;
10
+  background: rgba(0, 0, 0, .4);
11
+  z-index: 99;
12
+
13
+  .modalBody {
14
+    width: 600px;
15
+    background: #fff;
16
+    border-radius: 5px;
17
+    padding: 10px 20px;
18
+    color: #333;
19
+
20
+    .title {
21
+      width: 100%;
22
+      text-align: center;
23
+      font-size: 18px;
24
+      position: relative;
25
+
26
+      i {
27
+        position: absolute;
28
+        right: 0;
29
+        top: 0;
30
+        font-size: 20px;
31
+        color: #666;
32
+        cursor: pointer;
33
+        padding: 0 5px;
34
+      }
35
+    }
36
+
37
+    .content {
38
+      width: 100%;
39
+      background: #f9fafb;
40
+      border: 1px solid #e5e9ed;
41
+      border-radius: 5px;
42
+      overflow: hidden;
43
+      margin-top: 12px;
44
+      padding: 9px 24px;
45
+
46
+      .top {
47
+        height: 35px;
48
+        border-bottom: 2px solid #eff2f4;
49
+      }
50
+
51
+      .info {
52
+        margin-top: 15px;
53
+        margin-bottom: 4px;
54
+        min-height: 150px;
55
+
56
+        &.reply {
57
+          padding-top: 10px;
58
+          border-top: 2px solid #eff2f4;
59
+        }
60
+      }
61
+
62
+    }
63
+
64
+    button {
65
+      margin-top: 10px;
66
+
67
+      &.btn {
68
+        margin-left: 8px;
69
+      }
70
+    }
71
+
72
+  }
73
+
74
+  // 新增
75
+  &.add {
76
+    .modalBody {
77
+      width: 480px;
78
+      height: auto;
79
+
80
+      .content {
81
+        width: 100%;
82
+        height: auto;
83
+        padding: 18px 14px 0 14px;
84
+
85
+        .addForm {
86
+          .ant-form-item {
87
+            margin-bottom: 14px;
88
+
89
+            .ant-form-item-label {
90
+              line-height: 0;
91
+            }
92
+          }
93
+        }
94
+
95
+        .editForm {
96
+          .ant-form-item {
97
+            margin-bottom: 14px;
98
+
99
+            .ant-form-item-label {
100
+              line-height: 0;
101
+            }
102
+          }
103
+        }
104
+
105
+      }
106
+
107
+      button {
108
+        &:nth-child(1) {
109
+          margin-right: 20px;
110
+        }
111
+      }
112
+    }
113
+  }
114
+
115
+}
116
+
117
+.txtC {
118
+  text-align: center;
119
+}

+ 39 - 0
src/app/views/advice-detail/advice-detail.component.ts

@@ -0,0 +1,39 @@
1
+import { Component, OnInit } from '@angular/core';
2
+import { Router, ActivatedRoute } from "@angular/router";
3
+import { NzMessageService } from 'ng-zorro-antd';
4
+
5
+import { MainService } from "../../services/main.service";
6
+
7
+
8
+@Component({
9
+  selector: 'app-advice-detail',
10
+  templateUrl: './advice-detail.component.html',
11
+  styleUrls: ['./advice-detail.component.less']
12
+})
13
+export class AdviceDetailComponent implements OnInit {
14
+
15
+  constructor(private message: NzMessageService, private router: Router, private mainService: MainService, private routerInfo: ActivatedRoute) { }
16
+
17
+  ngOnInit() {
18
+    this.getDetail()
19
+  }
20
+
21
+  id: number;
22
+  adviceInfo: any = {};
23
+  hideModal() {
24
+    this.router.navigateByUrl('/main/adviceManagement')
25
+  }
26
+
27
+  // 获取详情
28
+  maskFlag: any = false;
29
+  getDetail() {
30
+    this.id = this.routerInfo.snapshot.params['id'];
31
+    this.maskFlag = this.message.loading('正在加载中..', { nzDuration: 0 }).messageId;
32
+    this.mainService.getFetchData('adviceCollection', 'advice', this.id).subscribe(data => {
33
+      this.message.remove(this.maskFlag);
34
+      this.maskFlag = false;
35
+      this.adviceInfo = data.data;
36
+    })
37
+  }
38
+
39
+}

+ 19 - 0
src/app/views/advice-detail/advice-detail.module.ts

@@ -0,0 +1,19 @@
1
+import { NgModule } from '@angular/core';
2
+import { CommonModule } from '@angular/common';
3
+
4
+import { AdviceDetailRoutingModule } from './advice-detail-routing.module';
5
+import { AdviceDetailComponent } from './advice-detail.component';
6
+import { ShareModule } from 'src/app/share/share.module';
7
+
8
+
9
+@NgModule({
10
+  declarations: [
11
+    AdviceDetailComponent
12
+  ],
13
+  imports: [
14
+    CommonModule,
15
+    AdviceDetailRoutingModule,
16
+    ShareModule
17
+  ]
18
+})
19
+export class AdviceDetailModule { }

+ 24 - 0
src/app/views/advice-management/advice-management-routing.module.ts

@@ -0,0 +1,24 @@
1
+import { NgModule } from '@angular/core';
2
+import { Routes, RouterModule } from '@angular/router';
3
+import { AdviceManagementComponent } from './advice-management.component';
4
+
5
+
6
+const routes: Routes = [
7
+  {
8
+    path: '',
9
+    component: AdviceManagementComponent,
10
+    children: [
11
+      {
12
+        // 查看详情
13
+        path: 'adviceDetail/:id',
14
+        loadChildren: () => import('../advice-detail/advice-detail.module').then(m => m.AdviceDetailModule),
15
+      }
16
+    ]
17
+  }
18
+];
19
+
20
+@NgModule({
21
+  imports: [RouterModule.forChild(routes)],
22
+  exports: [RouterModule]
23
+})
24
+export class AdviceManagementRoutingModule { }

+ 103 - 0
src/app/views/advice-management/advice-management.component.html

@@ -0,0 +1,103 @@
1
+<div class="list-template">
2
+  <div class="list-template__content">
3
+    <div class="list-template__top" nz-row>
4
+      <div nz-col nzXl='20' class="list-template__searchBox">
5
+        <div class="list-template__searchItem">
6
+          <span class="label">所属科室</span>:
7
+          <nz-select class="formItem" [nzDropdownMatchSelectWidth]="false" nzServerSearch nzShowSearch
8
+            (nzOnSearch)="changeInp($event)" nzAllowClear nzPlaceHolder="请选择所属科室" [(ngModel)]="department">
9
+            <ng-container *ngFor="let option of alldepart">
10
+              <nz-option *ngIf="!isLoading" [nzLabel]="option.dept" [nzValue]="option.id"></nz-option>
11
+            </ng-container>
12
+            <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
13
+              <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
14
+            </nz-option>
15
+          </nz-select>
16
+        </div>
17
+        <div class="list-template__searchItem">
18
+          <span class="label">状态</span>:
19
+          <nz-select class="formItem" [nzDropdownMatchSelectWidth]="false" [nzShowSearch]="false" nzAllowClear
20
+            nzPlaceHolder="请选择状态" [(ngModel)]="replyType">
21
+            <nz-option nzLabel="{{data.label}}" nzValue="{{data.value}}" *ngFor="let data of replyTypes"></nz-option>
22
+          </nz-select>
23
+        </div>
24
+      </div>
25
+      <div nz-col nzXl='4' class="list-template__btns">
26
+        <button nz-button class="btn default" (click)='search()'>搜索</button>
27
+        <button nz-button class="btn default ml8" (click)='reset()'>重置</button>
28
+      </div>
29
+    </div>
30
+    <div class="list-template__bottom">
31
+      <nz-table class="list-template__nzTable" [nzData]="listOfData" nzSize="middle" [nzShowPagination]="false"
32
+        [nzLoading]="loading1">
33
+        <thead>
34
+          <tr class="thead">
35
+            <th nzWidth="5%">序号</th>
36
+            <th nzWidth="15%">填写科室</th>
37
+            <th nzWidth="18%">填写时间</th>
38
+            <th nzWidth="35%">意见内容</th>
39
+            <th nzWidth="10%">状态</th>
40
+            <th nzWidth="18%">操作</th>
41
+          </tr>
42
+        </thead>
43
+        <tbody>
44
+          <tr *ngFor="let data of listOfData;let index=index;">
45
+            <td>{{index+(pageIndex-1)*10+1}}</td>
46
+            <td>{{ data.creatDepartment.dept }}</td>
47
+            <td>{{ data.createTime|date:'yyyy-MM-dd HH:mm'}}</td>
48
+            <td>
49
+              <span style="overflow: hidden;text-overflow: ellipsis;">
50
+                {{ spliceContent(data.content) }}
51
+              </span>
52
+            </td>
53
+            <td>{{data.replaceFlag==0?'未回复':'已回复'}}</td>
54
+            <td>
55
+              <div class="coop">
56
+                <span *ngIf="coopBtns.look" (click)="detail(data.id)">查看</span>
57
+                <span *ngIf="coopBtns.reply&&data.replaceFlag==0" (click)="reply(data)">回复</span>
58
+              </div>
59
+            </td>
60
+          </tr>
61
+        </tbody>
62
+      </nz-table>
63
+      <div class="list-template__pagination">
64
+        <nz-pagination [(nzPageIndex)]="pageIndex" [(nzTotal)]="listLength" nzShowSizeChanger [(nzPageSize)]="pageSize"
65
+          (nzPageIndexChange)="getList()" (nzPageSizeChange)="getList()">
66
+        </nz-pagination>
67
+      </div>
68
+    </div>
69
+  </div>
70
+  <!-- 意见箱查看 -->
71
+  <div class="save display_flex align-items_center justify-content_flex-center advice" *ngIf="modal">
72
+    <div class="modalBody">
73
+      <div class="title">意见箱 - 回复<i class="icon_transport transport-guanbi" (click)="hideModal()"></i></div>
74
+      <div class="content">
75
+        <div class="conItem">
76
+          <div class="jiTit borderB color3" nz-row>
77
+            <div nz-col nzSpan="8" class="txtL">填写科室:{{replyCon.creatDepartment.dept}}
78
+            </div>
79
+            <div nz-col nzSpan="6" class="txtL">填写人:{{replyCon.createUser.name}}
80
+            </div>
81
+            <div nz-col nzSpan="10" class="txtR">填写时间:{{replyCon.createTime}}</div>
82
+          </div>
83
+          <div class="defeat">意见内容:{{replyCon.content}}</div>
84
+        </div>
85
+        <div class="conItem noCon">
86
+          <div class="title">回复内容:</div>
87
+          <textarea rows="4" maxlength="255" nz-input [(ngModel)]="adviceSubContent" placeholder="请填写回复内容"></textarea>
88
+        </div>
89
+      </div>
90
+      <div class=" display_flex justify-content_flex-center">
91
+        <button nzType="primary" nz-button (click)="submitForm()" [nzLoading]="btnLoading">回复</button>
92
+        <button class="btn cancel" nz-button nzType="default" (click)="hideModal()">取消</button>
93
+      </div>
94
+    </div>
95
+  </div>
96
+
97
+</div>
98
+<!-- 操作成功/失败提示框 -->
99
+<app-prompt-modal *ngIf="promptModalShow" [content]="promptContent" [success]="ifSuccess" [show]="promptModalShow"
100
+  [info]="promptInfo"></app-prompt-modal>
101
+
102
+<!-- 查看详情 -->
103
+<router-outlet></router-outlet>

+ 91 - 0
src/app/views/advice-management/advice-management.component.less

@@ -0,0 +1,91 @@
1
+@import "../../../../src/theme.less";
2
+.save {
3
+  position: fixed;
4
+  left: 0;
5
+  top: 0;
6
+  width: 100%;
7
+  height: 100%;
8
+  background: rgba(0, 0, 0, 0.4);
9
+  z-index: 99;
10
+
11
+  .modalBody {
12
+    width: 1000px;
13
+    background: #fff;
14
+    border-radius: 5px;
15
+    padding: 10px 20px;
16
+    color: #333;
17
+
18
+    .title {
19
+      width: 100%;
20
+      text-align: center;
21
+      font-size: 18px;
22
+      position: relative;
23
+
24
+      i {
25
+        position: absolute;
26
+        right: 0;
27
+        top: 0;
28
+        font-size: 20px;
29
+        color: #666;
30
+        cursor: pointer;
31
+        padding: 0 5px;
32
+      }
33
+    }
34
+
35
+    .content {
36
+      width: 100%;
37
+      border: 1px solid #e5e9ed;
38
+      border-radius: 5px;
39
+      overflow: hidden;
40
+      margin-top: 12px;
41
+
42
+      // 意见箱查看
43
+      .conItem {
44
+        color: #333;
45
+
46
+        .jiTit {
47
+          height: 50px;
48
+          line-height: 50px;
49
+          border-bottom: 1px solid #e5e9ed;
50
+          padding: 0 32px;
51
+        }
52
+
53
+        .defeat {
54
+          font-size: 14px;
55
+          color: #333;
56
+          padding: 15px 32px;
57
+          min-height: 125px;
58
+        }
59
+
60
+        &.noCon {
61
+          background: #f9fafb;
62
+          padding: 16px 32px 24px 32px;
63
+          border-top: 1px solid #e5e9ed;
64
+
65
+          .title {
66
+            text-align: left;
67
+            font-size: 14px;
68
+            margin-bottom: 8px;
69
+          }
70
+
71
+          textarea {
72
+            min-height: 210px;
73
+          }
74
+        }
75
+      }
76
+    }
77
+
78
+    button {
79
+      margin-top: 10px;
80
+      margin-left: 10px;
81
+    }
82
+  }
83
+
84
+  .txtL {
85
+    text-align: left !important;
86
+  }
87
+
88
+  .txtR {
89
+    text-align: right !important;
90
+  }
91
+}

+ 250 - 0
src/app/views/advice-management/advice-management.component.ts

@@ -0,0 +1,250 @@
1
+import { ActivatedRoute, Router } from "@angular/router"
2
+import { Component, OnInit } from '@angular/core';
3
+
4
+import { MainService } from "../../services/main.service";
5
+import { ToolService } from '../../services/tool.service';
6
+import { Subject } from 'rxjs';
7
+import { debounceTime } from 'rxjs/operators';
8
+
9
+@Component({
10
+  selector: 'app-advice-management',
11
+  templateUrl: './advice-management.component.html',
12
+  styleUrls: ['./advice-management.component.less']
13
+})
14
+export class AdviceManagementComponent implements OnInit {
15
+
16
+  constructor(private route: ActivatedRoute, private router: Router, private mainService: MainService, private tool: ToolService) { }
17
+  changeInpSubject = new Subject();
18
+  ngOnInit() {
19
+    this.changeInpSubject.pipe(debounceTime(500)).subscribe(v => {
20
+      this.getDeparts(v);
21
+    })
22
+    this.initCoopBtns();
23
+    this.getAllHos()
24
+    this.getReplyTypes();
25
+  }
26
+
27
+  menu: any = JSON.parse(localStorage.getItem('menu')) || [];//菜单
28
+  listOfData: any[] = [];//表格数据
29
+
30
+  modal: boolean = false;//回复模态框
31
+  coopId: number;//表格中执行操作的id
32
+  department: any;//所属科室
33
+  num;//工号
34
+  name;//姓名
35
+  replyType: any;//选择状态
36
+  alldepart: any = [];//所有所属科室
37
+  replyTypes: any;//所有状态
38
+  pageIndex: number = 1;//页码
39
+  listLength: number = 10;//总条数
40
+  pageSize: number = 10;//每页条数
41
+
42
+  promptContent: string;//操作提示框提示信息
43
+  ifSuccess: boolean;//操作成功/失败
44
+  promptInfo: string;//操作结果提示信息
45
+  promptModalShow: boolean;//操作提示框是否展示
46
+
47
+  btnLoading: boolean = false;//提交按钮loading状态
48
+
49
+
50
+
51
+  // 初始化增删改按钮
52
+  coopBtns: any = {
53
+    look: false,
54
+    reply: false
55
+  };
56
+
57
+  initCoopBtns() {
58
+    // 二级菜单
59
+    let secondMenus = []
60
+    this.menu.forEach(e => {
61
+      e.childrens.forEach(el => {
62
+        secondMenus.push(el)
63
+      });
64
+    });
65
+    console.log(secondMenus)
66
+    let link = this.route.parent.snapshot.routeConfig.path;
67
+    let btns = []
68
+    secondMenus.forEach(e => {
69
+      if (e.link == link) {
70
+        btns = e.childrens || [];
71
+      }
72
+    });
73
+    btns.forEach(e => {
74
+      switch (e.link) {
75
+        case 'look':
76
+          this.coopBtns.look = true;
77
+          break;
78
+        case 'reply':
79
+          this.coopBtns.reply = true;
80
+          break;
81
+      }
82
+    })
83
+    console.log(this.coopBtns);
84
+  }
85
+
86
+  // 获取院区
87
+  hospital: string;//选中院区
88
+  getAllHos() {
89
+    this.hospital = this.tool.getCurrentHospital().id + '';
90
+    this.changeHos();
91
+    this.getList();
92
+  }
93
+  // 修改院区获取对应科室
94
+  changeHos() {
95
+    this.department = null;
96
+    this.getDeparts()
97
+  }
98
+  // 搜索
99
+  search() {
100
+    this.pageIndex = 1;
101
+    this.getList();
102
+  }
103
+  // 重置
104
+  reset() {
105
+    this.pageIndex = 1;
106
+    this.replyType = null;
107
+    this.department = null;
108
+    this.getList()
109
+
110
+  }
111
+  // 表格数据
112
+  loading1 = false;
113
+  getList() {
114
+    var that = this;
115
+    let data = {
116
+      idx: that.pageIndex - 1,
117
+      sum: that.pageSize,
118
+      advice: {
119
+        replaceFlag: that.replyType || '',
120
+        hosId: that.hospital,
121
+        creatDepartment: {
122
+          id: that.department || '',
123
+        }
124
+      },
125
+    }
126
+    if (!data.advice.replaceFlag) {
127
+      delete data.advice.replaceFlag
128
+    }
129
+    if (!data.advice.creatDepartment || !data.advice.creatDepartment.id) {
130
+      delete data.advice.creatDepartment
131
+    }
132
+    this.loading1 = true;
133
+    that.mainService.getFetchDataList('adviceCollection', 'advice', data).subscribe(data => {
134
+      this.loading1 = false;
135
+      that.listOfData = data.list;
136
+      that.listLength = data.totalNum;
137
+    })
138
+
139
+  }
140
+
141
+
142
+  // 获取所有科室
143
+  timerNum = 0;//边输入边搜索的定时器
144
+  getDeparts(dept?) {
145
+    var that = this;
146
+    let data = {
147
+      department: {
148
+        hospital: { id: that.hospital },
149
+        dept: dept || ''
150
+      },
151
+      idx: 0,
152
+      sum: 20
153
+    }
154
+    this.timerNum++;
155
+    that.mainService.getFetchDataList('data', 'department', data).subscribe(data => {
156
+      console.log(data);
157
+      that.alldepart = data.list;
158
+      this.timerNum--;
159
+      if (this.timerNum === 0) {
160
+        that.isLoading = false;
161
+      }
162
+    })
163
+  }
164
+
165
+  // 获取所属组
166
+  getReplyTypes() {
167
+    var that = this;
168
+    that.replyTypes = [
169
+      {
170
+        value: 0,
171
+        label: '未回复'
172
+      }, {
173
+        value: 1,
174
+        label: '已回复'
175
+      }
176
+    ]
177
+  }
178
+
179
+
180
+  // 新增弹框
181
+  replyCon: any;//意见内容
182
+  reply(data) {
183
+    this.modal = true;
184
+    this.replyCon = data;
185
+  }
186
+  hideModal() {
187
+    this.modal = false;
188
+  }
189
+  // 回复
190
+  adviceSubContent: string;//回复内容
191
+  submitForm() {
192
+    console.log(this.adviceSubContent)
193
+    let that = this;
194
+    if (!that.adviceSubContent) return;
195
+    that.btnLoading = true;
196
+    let postData = {
197
+      advice: {
198
+        id: that.replyCon.id,
199
+        replyUser: { id: that.replyCon.createUser.id },
200
+        replyContent: that.adviceSubContent
201
+      }
202
+    }
203
+    that.mainService.postCustom('adviceCollection', 'updData/advice', postData).subscribe(data => {
204
+      that.btnLoading = false;
205
+      that.adviceSubContent = '';
206
+      if (data.status == 200) {
207
+        that.showPromptModal('回复', true, '');
208
+        that.getList()
209
+        that.hideModal()
210
+      } else {
211
+        that.showPromptModal('回复', false, data.msg);
212
+      }
213
+    })
214
+
215
+  }
216
+
217
+  // 展示信息提示框(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)
218
+  showPromptModal(con, success, promptInfo?) {
219
+    this.promptModalShow = false;
220
+    this.promptContent = con;
221
+    this.ifSuccess = success;
222
+    this.promptInfo = promptInfo;
223
+    setTimeout(() => {
224
+      this.promptModalShow = true;
225
+    }, 100);
226
+    this.getList();
227
+  }
228
+
229
+  // 查看
230
+  detail(id) {
231
+    this.router.navigateByUrl('/main/adviceManagement/adviceDetail/' + id);
232
+  }
233
+
234
+  // 边输边搜节流阀
235
+  isLoading = false;
236
+  changeInp(e) {
237
+    this.isLoading = true;
238
+    this.changeInpSubject.next(e);
239
+  }
240
+
241
+  // 截取意见内容(ie内核截取)
242
+  spliceContent(con) {
243
+    if (con.length >= 41 && navigator.userAgent.indexOf('Trident') > -1) {
244
+      return con.slice(0, 20) + '...'
245
+    } else {
246
+      return con;
247
+    }
248
+  }
249
+
250
+}

+ 19 - 0
src/app/views/advice-management/advice-management.module.ts

@@ -0,0 +1,19 @@
1
+import { NgModule } from '@angular/core';
2
+import { CommonModule } from '@angular/common';
3
+
4
+import { AdviceManagementRoutingModule } from './advice-management-routing.module';
5
+import { AdviceManagementComponent } from './advice-management.component';
6
+import { ShareModule } from 'src/app/share/share.module';
7
+
8
+
9
+@NgModule({
10
+  declarations: [
11
+    AdviceManagementComponent,
12
+  ],
13
+  imports: [
14
+    CommonModule,
15
+    AdviceManagementRoutingModule,
16
+    ShareModule
17
+  ]
18
+})
19
+export class AdviceManagementModule { }

+ 25 - 0
src/app/views/appraise-management/appraise-management-routing.module.ts

@@ -0,0 +1,25 @@
1
+import { NgModule } from '@angular/core';
2
+import { Routes, RouterModule } from '@angular/router';
3
+import { AppraiseManagementComponent } from './appraise-management.component';
4
+import { AppraiseDetailComponent } from '../../share/appraise-detail/appraise-detail.component';
5
+
6
+
7
+const routes: Routes = [
8
+  {
9
+    path: '',
10
+    component: AppraiseManagementComponent,
11
+    children: [
12
+      {
13
+        // 查看详情
14
+        path: 'appraiseDetail/:id',
15
+        component: AppraiseDetailComponent,
16
+      }
17
+    ]
18
+  }
19
+];
20
+
21
+@NgModule({
22
+  imports: [RouterModule.forChild(routes)],
23
+  exports: [RouterModule]
24
+})
25
+export class AppraiseManagementRoutingModule { }

+ 138 - 0
src/app/views/appraise-management/appraise-management.component.html

@@ -0,0 +1,138 @@
1
+<div class="list-template">
2
+  <div class="list-template__content">
3
+    <div class="list-template__top" nz-row>
4
+      <div nz-col nzXl='18' class="list-template__searchBox">
5
+        <div class="list-template__searchItem">
6
+          <span class="label">工单类型</span>:
7
+          <nz-select class="formItem" [nzDropdownMatchSelectWidth]="false" [nzShowSearch]="false" nzAllowClear
8
+            nzPlaceHolder="请选择工单类型" [(ngModel)]="taskType">
9
+            <ng-container *ngFor="let data of allTaskType">
10
+              <nz-option nzLabel="{{data.taskName}}" nzValue="{{data.id}}"></nz-option>
11
+            </ng-container>
12
+          </nz-select>
13
+        </div>
14
+        <div class="list-template__searchItem">
15
+          <span class="label label--big">执行支助人员</span>:
16
+          <nz-select class="formItem" [nzDropdownMatchSelectWidth]="false" nzServerSearch nzShowSearch
17
+            (nzOnSearch)="changeUser($event)" nzAllowClear nzPlaceHolder="请选择执行支助人员" [(ngModel)]="worker">
18
+            <ng-container *ngFor="let option of allWorker">
19
+              <nz-option *ngIf="!isLoading" [nzLabel]="option.name" [nzValue]="option.id"></nz-option>
20
+            </ng-container>
21
+            <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
22
+              <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
23
+            </nz-option>
24
+          </nz-select>
25
+        </div>
26
+        <div class="list-template__searchItem">
27
+          <span class="label">调解人</span>:
28
+          <nz-select class="formItem" [nzDropdownMatchSelectWidth]="false" nzServerSearch nzShowSearch
29
+            (nzOnSearch)="changeMediUser($event)" nzAllowClear nzPlaceHolder="请选择调解人" [(ngModel)]="mediUser">
30
+            <ng-container *ngFor="let option of allMediUser">
31
+              <nz-option *ngIf="!isLoading" [nzLabel]="option.name" [nzValue]="option.id"></nz-option>
32
+            </ng-container>
33
+            <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
34
+              <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
35
+            </nz-option>
36
+          </nz-select>
37
+        </div>
38
+        <div class="list-template__searchItem">
39
+          <span class="label">处理状态</span>:
40
+          <nz-select class="formItem" [nzDropdownMatchSelectWidth]="false" [nzShowSearch]="false" nzAllowClear
41
+            nzPlaceHolder="请选择处理状态" [(ngModel)]="status">
42
+            <nz-option nzLabel="{{data.name}}" nzValue="{{data.id}}" *ngFor="let data of handleStatus"></nz-option>
43
+          </nz-select>
44
+        </div>
45
+      </div>
46
+      <div nz-col nzXl='6' class="list-template__btns">
47
+        <button nz-button class="btn default" (click)='search()'>搜索</button>
48
+        <button nz-button class="btn default ml8" (click)='reset()'>重置</button>
49
+      </div>
50
+    </div>
51
+    <div class="list-template__bottom">
52
+      <nz-table class="list-template__nzTable" [nzData]="listOfData" nzSize="middle" [nzShowPagination]="false"
53
+        [nzLoading]="loading1">
54
+        <thead>
55
+          <tr class="thead">
56
+            <th nzWidth="5%">序号</th>
57
+            <th nzWidth="10%">工单单号</th>
58
+            <th nzWidth="10%">申请科室</th>
59
+            <th nzWidth="7%">工单类型</th>
60
+            <th nzWidth="10%">发起时间</th>
61
+            <th nzWidth="10%">评价描述</th>
62
+            <th nzWidth="7%">评价等级</th>
63
+            <th nzWidth="10%">执行支助人员</th>
64
+            <th nzWidth="7%">处理状态</th>
65
+            <th nzWidth="7%">调解人</th>
66
+            <th nzWidth="17%">操作</th>
67
+          </tr>
68
+        </thead>
69
+        <tbody>
70
+          <tr *ngFor="let data of listOfData;let index=index;">
71
+            <td>{{index+(pageIndex-1)*10+1}}</td>
72
+            <td>{{data.workOrderObj?data.workOrderObj.gdcode:''}}</td>
73
+            <td>{{ data.startDept.dept }}</td>
74
+            <td>{{data.workOrderObj.taskType.taskName}}</td>
75
+            <td>{{timestampToTime(data.startTime)}}</td>
76
+            <td>
77
+              <span style="overflow: hidden;text-overflow: ellipsis;">{{ data.evaluationDetails.remark }}</span>
78
+            </td>
79
+            <td>{{ data.evaluationDetails.serviceEvaluation.name }}</td>
80
+            <td>{{data.worker?data.worker.name:''}}</td>
81
+            <td>{{data.handleStatus.name}}</td>
82
+            <td>{{data.mediationUser?data.mediationUser.name:''}}</td>
83
+            <td>
84
+              <div class="coop">
85
+                <span *ngIf="coopBtns.look" (click)="detail(data.id)">查看</span>
86
+                <span *ngIf="coopBtns.mediate&&data.handleStatus.id==286" (click)="detail(data.id,true)">调解</span>
87
+                <span *ngIf="coopBtns.designate&&data.handleStatus.id==286"
88
+                  (click)="designate(data.id,data.hosId)">指派</span>
89
+              </div>
90
+            </td>
91
+          </tr>
92
+        </tbody>
93
+      </nz-table>
94
+      <div class="list-template__pagination">
95
+        <nz-pagination [(nzPageIndex)]="pageIndex" [(nzTotal)]="listLength" nzShowSizeChanger [(nzPageSize)]="pageSize"
96
+          (nzPageIndexChange)="getList()" (nzPageSizeChange)="getList()">
97
+        </nz-pagination>
98
+      </div>
99
+    </div>
100
+  </div>
101
+
102
+  <!-- 指派模态框 -->
103
+  <div class="save add display_flex align-items_center justify-content_flex-center" *ngIf="modal">
104
+    <div class="modalBody">
105
+      <div class="title">产品处理指派调解人员<i class="icon_transport transport-guanbi" (click)="hideModal()"></i>
106
+      </div>
107
+      <div class="content">
108
+        <form nz-form [formGroup]="validateForm" class="addForm" (ngSubmit)="submitForm()">
109
+          <nz-form-item>
110
+            <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="user">指派调解人员</nz-form-label>
111
+            <nz-form-control nzErrorTip="请选择指派调解人员!">
112
+              <nz-select [nzDropdownMatchSelectWidth]="false" type="user" nzShowSearch nzAllowClear
113
+                formControlName="user" nzPlaceHolder="请选择指派调解人员">
114
+                <ng-container *ngFor="let data of allDesUser">
115
+                  <nz-option *ngIf="!isLoading" [nzLabel]="data.name" [nzValue]="data.id"></nz-option>
116
+                </ng-container>
117
+                <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
118
+                  <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
119
+                </nz-option>
120
+              </nz-select>
121
+            </nz-form-control>
122
+          </nz-form-item>
123
+        </form>
124
+      </div>
125
+      <div class="display_flex justify-content_flex-center">
126
+        <button nzType="primary" nz-button (click)="submitForm()" [nzLoading]="btnLoading">确认</button>
127
+        <button class="btn cancel" nz-button nzType="default" (click)="hideModal()">取消</button>
128
+      </div>
129
+    </div>
130
+  </div>
131
+
132
+</div>
133
+<!-- 操作成功/失败提示框 -->
134
+<app-prompt-modal *ngIf="promptModalShow" [content]="promptContent" [success]="ifSuccess" [show]="promptModalShow"
135
+  [info]="promptInfo"></app-prompt-modal>
136
+
137
+<!-- 查看详情 -->
138
+<router-outlet (deactivate)="getList()"></router-outlet>

+ 128 - 0
src/app/views/appraise-management/appraise-management.component.less

@@ -0,0 +1,128 @@
1
+@import "../../../../src/theme.less";
2
+.save {
3
+  position: fixed;
4
+  left: 0;
5
+  top: 0;
6
+  width: 100%;
7
+  height: 100%;
8
+  background: rgba(0, 0, 0, 0.4);
9
+  z-index: 99;
10
+
11
+  .modalBody {
12
+    width: 350px;
13
+    background: #fff;
14
+    border-radius: 5px;
15
+    padding: 10px 20px;
16
+    color: #333;
17
+
18
+    .title {
19
+      width: 100%;
20
+      text-align: center;
21
+      font-size: 18px;
22
+      position: relative;
23
+
24
+      i {
25
+        position: absolute;
26
+        right: 0;
27
+        top: 0;
28
+        font-size: 20px;
29
+        color: #666;
30
+        cursor: pointer;
31
+        padding: 0 5px;
32
+      }
33
+    }
34
+
35
+    .content {
36
+      width: 100%;
37
+      height: 117px;
38
+      background: #f9fafb;
39
+      border: 1px solid #e5e9ed;
40
+      border-radius: 5px;
41
+      overflow: hidden;
42
+      margin-top: 12px;
43
+
44
+      div {
45
+        text-align: center;
46
+        margin: 0;
47
+
48
+        &.icon {
49
+          margin-top: 17px;
50
+
51
+          i {
52
+            color: #34b349;
53
+            font-size: 30px !important;
54
+
55
+            &.transport-wenhao {
56
+              color: #f5a523;
57
+            }
58
+
59
+            &.transport-shibai {
60
+              color: #ff3a52;
61
+            }
62
+          }
63
+        }
64
+
65
+        &.defeat {
66
+          color: #333;
67
+          font-size: 18px;
68
+        }
69
+
70
+        &:nth-child(3) {
71
+          font-size: 14px;
72
+          color: #666;
73
+        }
74
+      }
75
+    }
76
+
77
+    button {
78
+      margin-top: 10px;
79
+
80
+      &.btn {
81
+        margin-left: 8px;
82
+      }
83
+    }
84
+  }
85
+
86
+  // 新增
87
+  &.add {
88
+    .modalBody {
89
+      width: 480px;
90
+      height: auto;
91
+
92
+      .content {
93
+        width: 100%;
94
+        height: auto;
95
+        padding: 19px 14px 0 14px;
96
+        max-height: 500px;
97
+        overflow-y: auto;
98
+
99
+        .addForm {
100
+          .ant-form-item {
101
+            margin-bottom: 14px;
102
+
103
+            .ant-form-item-label {
104
+              line-height: 14px;
105
+              text-align: left;
106
+            }
107
+          }
108
+        }
109
+
110
+        .editForm {
111
+          .ant-form-item {
112
+            margin-bottom: 14px;
113
+
114
+            .ant-form-item-label {
115
+              line-height: 0;
116
+            }
117
+          }
118
+        }
119
+      }
120
+
121
+      button {
122
+        &:nth-child(1) {
123
+          margin-right: 20px;
124
+        }
125
+      }
126
+    }
127
+  }
128
+}

+ 340 - 0
src/app/views/appraise-management/appraise-management.component.ts

@@ -0,0 +1,340 @@
1
+import { Component, OnInit } from '@angular/core';
2
+import { ActivatedRoute, Router } from "@angular/router"
3
+import { FormBuilder, Validators, FormGroup } from '@angular/forms';
4
+
5
+import { MainService } from "../../services/main.service";
6
+import { ToolService } from '../../services/tool.service';
7
+import { Subject } from 'rxjs';
8
+import { debounceTime } from 'rxjs/operators';
9
+
10
+@Component({
11
+  selector: 'app-appraise-management',
12
+  templateUrl: './appraise-management.component.html',
13
+  styleUrls: ['./appraise-management.component.less']
14
+})
15
+export class AppraiseManagementComponent implements OnInit {
16
+
17
+  constructor(private fb: FormBuilder, private route: ActivatedRoute, private router: Router, private mainService: MainService, private tool: ToolService) { }
18
+
19
+  menu: any = JSON.parse(localStorage.getItem('menu')) || [];//菜单
20
+  listOfData: any[] = [];//表格数据
21
+
22
+  modal: boolean = false;//新增/编辑模态框
23
+  validateForm: FormGroup;//新增/编辑表单
24
+  coopId: number;//表格中执行操作的id
25
+  department: any;//所属科室
26
+  mediUser: number;//调解人
27
+  taskType: number;//工单类型
28
+  allTaskType: any;//所有工单类型
29
+  allHospital: any;//所有院区
30
+  pageIndex: number = 1;//页码
31
+  listLength: number = 10;//总条数
32
+  pageSize: number = 10;//每页条数
33
+
34
+  promptContent: string;//操作提示框提示信息
35
+  ifSuccess: boolean;//操作成功/失败
36
+  promptInfo: string;//操作结果提示信息
37
+  promptModalShow: boolean;//操作提示框是否展示
38
+
39
+  btnLoading: boolean = false;//提交按钮loading状态
40
+  searchTimerSubject = new Subject();
41
+
42
+  ngOnInit() {
43
+    this.searchTimerSubject.pipe(debounceTime(500)).subscribe(v => {
44
+      let fun = v[0];
45
+      fun(v[1], v[2]);
46
+    })
47
+    this.initCoopBtns();
48
+    this.getAllHos()
49
+    this.getStatus()
50
+    this.initForm()
51
+  }
52
+
53
+  // 初始化增删改按钮
54
+  coopBtns: any = {
55
+    look: false,
56
+    mediate: false,//调解
57
+    designate: false,//指派
58
+  };
59
+
60
+  initCoopBtns() {
61
+    // 二级菜单
62
+    let secondMenus = []
63
+    this.menu.forEach(e => {
64
+      e.childrens.forEach(el => {
65
+        secondMenus.push(el)
66
+      });
67
+    });
68
+    console.log(secondMenus)
69
+    let link = this.route.parent.snapshot.routeConfig.path;
70
+    let btns = []
71
+    secondMenus.forEach(e => {
72
+      if (e.link == link) {
73
+        btns = e.childrens || [];
74
+      }
75
+    });
76
+    btns.forEach(e => {
77
+      switch (e.link) {
78
+        case 'look':
79
+          this.coopBtns.look = true;
80
+          break;
81
+        case 'mediate':
82
+          this.coopBtns.mediate = true;
83
+          break;
84
+        case 'designate':
85
+          this.coopBtns.designate = true;
86
+          break;
87
+      }
88
+    })
89
+    console.log(this.coopBtns);
90
+  }
91
+
92
+  // 获取院区
93
+  hospital: string;//选中院区
94
+  getAllHos() {
95
+    this.hospital = this.tool.getCurrentHospital().id + '';
96
+    this.changeHos();
97
+    this.getList();
98
+  }
99
+  // 修改院区获取对应科室
100
+  changeHos() {
101
+    this.taskType = null;
102
+    this.worker = null;
103
+    this.mediUser = null;
104
+    this.status = null;
105
+    this.getAllTaskType()
106
+    this.getAllWorker()
107
+    this.getAllMediUser()
108
+  }
109
+
110
+  // 获取支助人员
111
+  worker: number;//支助人员
112
+  allWorker: any = [];//所有支助人员
113
+  snum1 = 0;
114
+  getAllWorker(e?, those?) {
115
+    let that = those || this;
116
+    let postData = {
117
+      user: {
118
+        name: e || '',
119
+        hospital: { id: that.hospital },
120
+        usertype: { id: 106 }//支助人员
121
+      },
122
+      idx: 0,
123
+      sum: 20
124
+    }
125
+    that.snum1++;
126
+    that.mainService.getFetchDataList('data', 'user', postData).subscribe(data => {
127
+      that.allWorker = data.list;
128
+      that.snum1--;
129
+      if (that.snum1 === 0) {
130
+        that.isLoading = false;
131
+      }
132
+    })
133
+  }
134
+
135
+  // 指派人员
136
+  allDesUser: any = [];//所有支助人员
137
+  getAllDesUser(id) {
138
+    this.isLoading = true;
139
+    this.mainService.getHosUser('getUsersByPermission', id).subscribe(data => {
140
+      this.isLoading = false;
141
+      this.allDesUser = data.data || []
142
+    })
143
+  }
144
+
145
+  // 获取所有调解人
146
+  allMediUser: any = [];//所有调解人
147
+  snum2 = 0;
148
+  getAllMediUser(e?, those?) {
149
+    let that = those || this;
150
+    let postData = {
151
+      user: {
152
+        name: e || '',
153
+        hospital: { id: that.hospital },
154
+        usertype: { id: 107 }//服务台
155
+      },
156
+      idx: 0,
157
+      sum: 20
158
+    }
159
+    that.snum2++;
160
+    that.mainService.getFetchDataList('data', 'user', postData).subscribe(data => {
161
+      that.allMediUser = data.list;
162
+      that.snum2--;
163
+      if (that.snum2 === 0) {
164
+        that.isLoading = false;
165
+      }
166
+    })
167
+  }
168
+
169
+  // 用户输入搜索
170
+  changeUser(e) {
171
+    this.searchTimer(this.getAllWorker, e, this);
172
+  }
173
+
174
+  // 调解人搜索
175
+  changeMediUser(e) {
176
+    this.searchTimer(this.getAllMediUser, e, this);
177
+  }
178
+
179
+  // 边输入边搜索节流阀
180
+  isLoading: boolean = false;
181
+  searchTimer(fun, e, those) {
182
+    this.isLoading = true;
183
+    this.searchTimerSubject.next([fun, e, those]);
184
+  }
185
+
186
+  // 获取处理状态
187
+  status: number;//处理状态
188
+  handleStatus: any = [];//所有处理状态
189
+  getStatus() {
190
+    var that = this;
191
+    that.mainService.getDictionary('list', 'bad_evaluation_handle_status').subscribe(data => {
192
+      that.handleStatus = data
193
+    })
194
+  }
195
+
196
+  // 搜索
197
+  search() {
198
+    this.pageIndex = 1;
199
+    this.getList();
200
+  }
201
+  // 重置
202
+  reset() {
203
+    this.pageIndex = 1;
204
+    this.taskType = null;
205
+    this.worker = null;
206
+    this.mediUser = null;
207
+    this.status = null;
208
+    this.getList()
209
+
210
+  }
211
+  // 表格数据
212
+  loading1 = false;
213
+  getList() {
214
+    var that = this;
215
+    let data = {
216
+      idx: that.pageIndex - 1,
217
+      sum: that.pageSize,
218
+      badEvaluationHandle: {
219
+        taskType: that.taskType || '',
220
+        worker: { id: that.worker || '' },
221
+        handleStatus: { id: that.status || '' },
222
+        hosId: that.hospital,
223
+        mediationUser: { id: that.mediUser }
224
+      },
225
+    }
226
+    if (!data.badEvaluationHandle.taskType) {
227
+      delete data.badEvaluationHandle.taskType
228
+    }
229
+    if (!data.badEvaluationHandle.worker.id) {
230
+      delete data.badEvaluationHandle.worker
231
+    }
232
+    if (!data.badEvaluationHandle.handleStatus.id) {
233
+      delete data.badEvaluationHandle.handleStatus
234
+    }
235
+    if (!data.badEvaluationHandle.mediationUser.id) {
236
+      delete data.badEvaluationHandle.mediationUser
237
+    }
238
+    this.loading1 = true;
239
+    that.mainService.getFetchDataList('adviceCollection', 'badEvaluationHandle', data).subscribe(data => {
240
+      this.loading1 = false;
241
+      that.listOfData = data.list;
242
+      that.listLength = data.totalNum;
243
+    })
244
+
245
+  }
246
+
247
+
248
+  // 获取工单类型
249
+  getAllTaskType() {
250
+    let that = this;
251
+    let postData = {
252
+      taskType: {
253
+        hosId: { id: that.hospital },
254
+      },
255
+      idx: 0,
256
+      sum: 30
257
+    }
258
+    that.mainService.getFetchDataList('configuration', 'taskType', postData).subscribe(data => {
259
+      that.allTaskType = data.list;
260
+    })
261
+  }
262
+
263
+  // 初始化新增form表单
264
+  initForm() {
265
+    this.validateForm = this.fb.group({
266
+      user: [null, [Validators.required]],
267
+    });
268
+  }
269
+  submitForm() {
270
+    var that = this;
271
+    for (const i in that.validateForm.controls) {
272
+      that.validateForm.controls[i].markAsDirty();
273
+      that.validateForm.controls[i].updateValueAndValidity();
274
+    }
275
+    if (that.validateForm.invalid) return;
276
+    that.btnLoading = true;
277
+    let postData = {
278
+      badEvaluationHandle: {
279
+        id: that.coopId,
280
+        mediationUser: { id: that.validateForm.value.user },
281
+      }
282
+    }
283
+    that.mainService.postCustom('adviceCollection', 'updData/badEvaluationHandle', postData).subscribe(data => {
284
+      that.hideModal()
285
+      that.btnLoading = false;
286
+      if (data.status == 200) {
287
+        that.showPromptModal('指派', true, '');
288
+        that.initForm()
289
+        that.getList()
290
+      } else {
291
+        that.showPromptModal('指派', false, data.msg);
292
+      }
293
+    })
294
+  }
295
+
296
+  // 指派
297
+  designate(id, hosId) {
298
+    this.modal = true;
299
+    this.coopId = id;
300
+    this.getAllDesUser(hosId)
301
+  }
302
+  hideModal() {
303
+    this.modal = false;
304
+  }
305
+
306
+
307
+  // 展示信息提示框(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)
308
+  showPromptModal(con, success, promptInfo?) {
309
+    this.promptModalShow = false;
310
+    this.promptContent = con;
311
+    this.ifSuccess = success;
312
+    this.promptInfo = promptInfo;
313
+    setTimeout(() => {
314
+      this.promptModalShow = true;
315
+    }, 100);
316
+    this.getList();
317
+  }
318
+
319
+  // 查看
320
+  detail(id, tj?) {
321
+    if (tj) {
322
+      this.router.navigate(['/main/appraiseManagement/appraiseDetail/' + id], { fragment: 'tj' });
323
+    } else {
324
+      this.router.navigate(['/main/appraiseManagement/appraiseDetail/' + id]);
325
+    }
326
+  }
327
+
328
+  // 格式化时间戳
329
+  timestampToTime(timestamp) {
330
+    var date = new Date(timestamp);//时间戳为10位需*1000,时间戳为13位的话不需乘1000
331
+    let Y = date.getFullYear() + '-';
332
+    let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
333
+    let D = date.getDate() < 10 ? '0' + date.getDate() + ' ' : date.getDate() + ' ';
334
+    let h = date.getHours() < 10 ? '0' + date.getHours() + ':' : date.getHours() + ':';
335
+    let m = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes();
336
+    return Y + M + D + h + m;
337
+  }
338
+
339
+}
340
+

+ 19 - 0
src/app/views/appraise-management/appraise-management.module.ts

@@ -0,0 +1,19 @@
1
+import { NgModule } from '@angular/core';
2
+import { CommonModule } from '@angular/common';
3
+
4
+import { AppraiseManagementRoutingModule } from './appraise-management-routing.module';
5
+import { AppraiseManagementComponent } from './appraise-management.component';
6
+import { ShareModule } from 'src/app/share/share.module';
7
+
8
+
9
+@NgModule({
10
+  declarations: [
11
+    AppraiseManagementComponent,
12
+  ],
13
+  imports: [
14
+    CommonModule,
15
+    AppraiseManagementRoutingModule,
16
+    ShareModule
17
+  ]
18
+})
19
+export class AppraiseManagementModule { }

+ 0 - 0
src/app/views/building-distance/building-distance-routing.module.ts


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