Parcourir la source

Merge branch 'master' of http://git.dashitech.com/seimin/zy-pc

maotao il y a 3 mois
Parent
commit
9c34c72150
27 fichiers modifiés avec 2130 ajouts et 276 suppressions
  1. 8 0
      src/app/app-routing.module.ts
  2. 0 1
      src/app/components/configurationCenter/configuration-category/configuration-category.component.ts
  3. 0 1
      src/app/components/configurationCenter/configuration-deptUser/configuration-deptUser.component.ts
  4. 0 1
      src/app/components/incidentManagement/incident-create/incident-create.component.ts
  5. 115 22
      src/app/components/incidentManagement/incident-ser-visit/incident-ser-visit.component.html
  6. 163 75
      src/app/components/incidentManagement/incident-ser-visit/incident-ser-visit.component.less
  7. 346 84
      src/app/components/incidentManagement/incident-ser-visit/incident-ser-visit.component.ts
  8. 0 1
      src/app/components/incidentManagement/incident-substitutio-assign/incident-substitution-assign.component.ts
  9. 0 1
      src/app/components/incidentManagement/incident-substitutio-redeploy/incident-substitution-redeploy.component.ts
  10. 14 0
      src/app/components/incidentManagement/incident-substitution/incident-substitution.component.ts
  11. 22 0
      src/app/guard/realtimeBroadcast.guard.ts
  12. 4 1
      src/app/services/tool.service.ts
  13. 1 1
      src/app/views/fuwutai/fuwutai.component.html
  14. 0 1
      src/app/views/fuwutai/fuwutai.component.ts
  15. 27 28
      src/app/views/hospital-management/hospital-management.component.html
  16. 77 27
      src/app/views/hospital-management/hospital-management.component.ts
  17. 35 15
      src/app/views/incident-management/incident-management.component.ts
  18. 1 0
      src/app/views/main/main.component.html
  19. 9 0
      src/app/views/main/main.component.ts
  20. 18 0
      src/app/views/realtime-broadcast/realtime-broadcast-routing.module.ts
  21. 157 0
      src/app/views/realtime-broadcast/realtime-broadcast.component.html
  22. 601 0
      src/app/views/realtime-broadcast/realtime-broadcast.component.less
  23. 437 0
      src/app/views/realtime-broadcast/realtime-broadcast.component.ts
  24. 21 0
      src/app/views/realtime-broadcast/realtime-broadcast.module.ts
  25. 24 12
      src/app/views/repository-manage/repository-manage.component.html
  26. 44 2
      src/app/views/repository-manage/repository-manage.component.ts
  27. 6 3
      src/app/views/users-management/users-management.component.ts

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

@@ -26,6 +26,8 @@ import { PageConfigGuard } from './guard/PageConfig.guard';
26 26
 import { NurseConfigGuard } from './guard/nurseConfig.guard';
27 27
 //系统配置查看权限
28 28
 import { SystemConfigGuard } from './guard/SystemConfig.guard';
29
+// 故障实时播报权限
30
+import { RealtimeBroadcastGuard } from './guard/realtimeBroadcast.guard';
29 31
 const routes: Routes = [
30 32
   // 默认
31 33
   {
@@ -172,6 +174,12 @@ const routes: Routes = [
172 174
 	  path: 'repositoryManageAdd/:id',
173 175
 	  loadChildren: () => import('./views/repository-manage-add/repository-manage-add.module').then(m => m.RepositoryManageAddModule),
174 176
 	},
177
+  // 故障实时播报
178
+  {
179
+    path: 'realtimeBroadcast',
180
+    loadChildren: () => import('./views/realtime-broadcast/realtime-broadcast.module').then(m => m.RealtimeBroadcastModule),
181
+    canActivate: [RealtimeBroadcastGuard]
182
+  },
175 183
   // 管理端首页
176 184
   {
177 185
     path: '**',

+ 0 - 1
src/app/components/configurationCenter/configuration-category/configuration-category.component.ts

@@ -136,7 +136,6 @@ export class ConfigurationCategoryComponent implements OnInit {
136 136
     }
137 137
     let postData = {
138 138
       user: {
139
-        hospital: { id: this.validateConfigForm.value.dutyId },
140 139
         name: keyword,
141 140
         simpleQuery: true,
142 141
         groupdata: { id: this.validateConfigForm.value.groupId },

+ 0 - 1
src/app/components/configurationCenter/configuration-deptUser/configuration-deptUser.component.ts

@@ -165,7 +165,6 @@ export class ConfigurationDeptUserComponent implements OnInit {
165 165
 			sum: 9999,
166 166
 			user: {
167 167
 				// name:name,
168
-				hospital: { id: this.hosId || "" },
169 168
 				groupdata:{id:groupId || ""},
170 169
         roleCodes: 'first-line support',
171 170
         engineer: 1,

+ 0 - 1
src/app/components/incidentManagement/incident-create/incident-create.component.ts

@@ -558,7 +558,6 @@ export class IncidentCreateComponent implements OnInit {
558 558
       sum: 20,
559 559
       user: {
560 560
         name:keyWord,
561
-				hospital: this.incidentModel.duty ? { id: this.incidentModel.duty.id } : undefined,
562 561
 				groupdata: this.incidentModel.group ? { id: this.incidentModel.group } : undefined,
563 562
         roleCodes: 'first-line support',
564 563
         engineer: 1,

+ 115 - 22
src/app/components/incidentManagement/incident-ser-visit/incident-ser-visit.component.html

@@ -1,33 +1,126 @@
1 1
 <div class="modal display_flex align-items_center">
2 2
   <div class="modalBody">
3 3
     <div class="title">待回访<i class="icon_transport transport-guanbi" (click)="hideModal()"></i></div>
4
-    <overlay-scrollbars #osComponentRef1 class="content">
5
-      <nz-spin nzSimple [nzSpinning]="loading" class="mt8 text_align_center"></nz-spin>
6
-      <ng-container *ngIf="!loading">
7
-        <div class="items" *ngFor="let item of visitList">
8
-          <div class="row">
9
-            <div class="col"><span [ngClass]="priorityColor(item.priorityId)">{{item.priorityDTO?.name}}</span> {{item.incidentsign}}</div>
10
-            <div class="col">{{item.hosName}} <ng-container *ngIf="item.repairIncidentType.value === 'public'">{{ item.repairIncidentType.name }}</ng-container><ng-container *ngIf="item.repairIncidentType.value === 'dept'">{{ item.department?.dept }}</ng-container></div>
11
-          </div>
12
-          <div class="row">
13
-            <div class="col">故障描述:{{item.description}}</div>
14
-          </div>
15
-          <div class="row">
16
-            <div class="col">详细地址:{{ item.place ? item.place.building.buildingName : '' }}{{ item.place ? item.place.floorName + '层' : '' }}{{ item.houseNumber }} <span [innerHTML]="item.overtimeRemark"></span></div>
17
-          </div>
18
-          <div class="row">
19
-            <div class="col">申请时间:{{ item.startDate | date: 'yyyy-MM-dd HH:mm'}}</div>
20
-            <div class="col">处理人:{{computedHandlerUser(item)}}</div>
21
-            <div class="col btns">
22
-              <input type="button" class="mid_bot mr8" value="回访" (click)="visit(item)" />
23
-              <input type="button" class="btm_bot" value="查看" (click)="openItsmDetails(item)" />
4
+    <div class="content">
5
+      <div class="tabs">
6
+        <div class="tab" [ngClass]="{'active': queryTask == item.key}" (click)="changeTab(item.key)" *ngFor="let item of tabs">{{item.value}}<span [ngClass]="{ red: item.isRed && item.num > 0}">({{item.num}})</span></div>
7
+      </div>
8
+      <div class="list-template w100" style="padding: 16px;">
9
+        <div class="list-template__content">
10
+          <div class="list-template__top" nz-row style="padding: 0;">
11
+            <div nz-col nzXl='20' class="list-template__searchBox">
12
+              <div class="list-template__searchItem" *ngIf="coopBtns.strideLook && queryTask!='todo' && queryTask!='doing' && queryTask!='storage'">
13
+                <span class="label">维修科室</span>:
14
+                <nz-select class="formItem" [nzDropdownMatchSelectWidth]="false" nzShowSearch
15
+                   (ngModelChange)="deptChange($event)" nzAllowClear nzPlaceHolder="请选择维修科室" [(ngModel)]="searchDTO.maintainDepartment">
16
+                  <ng-container *ngFor="let option of maintainDept">
17
+                    <nz-option [nzLabel]="option.hosName" [nzValue]="option.id"></nz-option>
18
+                  </ng-container>
19
+                </nz-select>
20
+              </div>
21
+              <div class="list-template__searchItem">
22
+                <span class="label">登记时间</span>:
23
+                <nz-range-picker style="width: 373px;" nzShowTime [(ngModel)]="searchDTO.dateRange" (nzOnCalendarChange)="onCalendarChangeDate($event)"></nz-range-picker>
24
+              </div>
25
+              <div class="list-template__searchItem">
26
+                <span class="label">事件单号</span>:
27
+                <input nz-input class="formItem" placeholder="请输入事件单号" [(ngModel)]="searchDTO.incidentsign" />
28
+              </div>
29
+              <div class="list-template__searchItem">
30
+                <span class="label">报修科室</span>:
31
+                <nz-select class="formItem" [nzDropdownMatchSelectWidth]="false" nzServerSearch nzShowSearch
32
+                  (nzOnSearch)="changeInp($event)" nzAllowClear nzPlaceHolder="请选择报修科室" [(ngModel)]="searchDTO.department">
33
+                  <ng-container *ngFor="let option of alldepart">
34
+                    <nz-option *ngIf="!isLoading" [nzLabel]="option.dept" [nzValue]="option.id"></nz-option>
35
+                  </ng-container>
36
+                  <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
37
+                    <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
38
+                  </nz-option>
39
+                </nz-select>
40
+              </div>
41
+              <div class="list-template__searchItem">
42
+                <span class="label">状态</span>:
43
+                <nz-select class="formItem" [nzDropdownMatchSelectWidth]="false" [nzShowSearch]="false" nzAllowClear
44
+                  nzPlaceHolder="请选择状态" [(ngModel)]="searchDTO.statusId">
45
+                  <nz-option [nzLabel]="data.name" [nzValue]="data.id" *ngFor="let data of gdStates"></nz-option>
46
+                </nz-select>
47
+              </div>
48
+            </div>
49
+            <div nz-col nzXl='4' class="list-template__btns">
50
+              <button nz-button class="btn default ml8 mt0" (click)='search()'>搜索</button>
51
+              <button nz-button class="btn default ml8 mt0" (click)='reset()'>重置</button>
24 52
             </div>
25 53
           </div>
26 54
         </div>
27
-      </ng-container>
28
-    </overlay-scrollbars>
55
+      </div>
56
+      <div class="tableWrap">
57
+        <nz-table class="hospitalTable" [nzData]="listOfData" nzSize="small" [nzShowPagination]="false" [nzLoading]="loading1">
58
+          <thead>
59
+            <tr class="thead">
60
+              <th nzWidth="5%">序号</th>
61
+              <th nzWidth="27%">故障信息</th>
62
+              <th nzWidth="14%">详细地址</th>
63
+              <th nzWidth="12%">联系信息</th>
64
+              <th nzWidth="12%">受理人|处理人/组</th>
65
+              <th nzWidth="10%">延期记录</th>
66
+              <th nzWidth="8%">状态</th>
67
+              <th nzWidth="12%">操作</th>
68
+            </tr>
69
+          </thead>
70
+          <tbody>
71
+            <tr *ngFor="let data of listOfData;let index=index;" (click)="detail($event,data)">
72
+              <td>{{index+(pageIndex-1) * pageSize + 1}}</td>
73
+              <td class="text_align_left">
74
+                <span [ngClass]="priorityColor(data.priorityId)">{{ data.priorityDTO?.name }}</span>
75
+                {{ data.incidentsign }} {{ data.acceptDate | date: 'yyyy-MM-dd HH:mm' }}<br>{{ data.description }}
76
+                <i class="icon_transport transport-a-11111 ml8" *ngIf="data.reqAttachment"></i>
77
+                <i class="icon_transport transport-luyin ml8" *ngIf="data.reqRecord"></i>
78
+              </td>
79
+              <td class="text_align_left">
80
+                {{ data.hosName || '无' }}<br>
81
+                <ng-container *ngIf="data.repairIncidentType.value === 'public'">
82
+                  {{ data.repairIncidentType.name }}<br>
83
+                </ng-container>
84
+                <ng-container *ngIf="data.repairIncidentType.value === 'dept'">
85
+                  {{ data.department?.dept || '无' }}<br>
86
+                </ng-container>
87
+                {{ data.place ? data.place.building.buildingName : '' }}{{ data.place ? data.place.floorName + '层' : '' }}{{ data.houseNumber }}
88
+              </td>
89
+              <td class="text_align_left">
90
+                {{ data.requester?.name || '无' }}<br>
91
+                联电:{{ data.contactsInformation || '无' }}<br>
92
+                来电:{{ data.incomingPhone || '无' }}
93
+                <i class="icon_transport transport-luyin ml8" *ngIf="data.callID"></i>
94
+              </td>
95
+              <td>
96
+                {{ data.acceptUser?.name || '无' }}<br>
97
+                {{ transferSynergetic(data) }}<br>
98
+                <ng-container *ngIf="(data.state.value === 'pending' || data.state.value === 'reassign') && data.overdueResponseDate"><span [ngStyle]="{ color: data.acceptColourInfo ? data.acceptColourInfo.value : '' }">{{ data.overdueResponseDate | date: 'MM-dd HH:mm' }}</span>前接单</ng-container>
99
+                <ng-container *ngIf="data.state.value === 'handler' && data.overdueTime"><span [ngStyle]="{ color: data.handleColourInfo ? data.handleColourInfo.value : '' }">{{ data.overdueTime | date: 'MM-dd HH:mm' }}</span>前处理</ng-container>
100
+              </td>
101
+              <td [innerHTML]="data.overtimeRemark"></td>
102
+              <td>{{ data.state?.name }}</td>
103
+              <td>
104
+                <div class="coop">
105
+                  <span *ngIf="data.computedVisitFlag" (click)="visit($event,data)">回访</span>
106
+                </div>
107
+              </td>
108
+            </tr>
109
+          </tbody>
110
+        </nz-table>
111
+        <div class="pagination">
112
+          <ng-template #totalTemplate let-total> 共 {{ total }} 条 </ng-template>
113
+          <nz-pagination [(nzPageIndex)]="pageIndex" [(nzTotal)]="listLength"
114
+            [(nzPageSize)]="pageSize" (nzPageIndexChange)="getList()"
115
+            (nzPageSizeChange)="getList()" [nzShowTotal]="totalTemplate">
116
+          </nz-pagination>
117
+        </div>
118
+      </div>
119
+    </div>
29 120
   </div>
30 121
 </div>
122
+<!-- 操作成功/失败提示框 -->
123
+<app-prompt-modal *ngIf="promptModalShow" [content]="promptContent" [success]="ifSuccess" [show]="promptModalShow" [info]="promptInfo"></app-prompt-modal>
31 124
 
32 125
 <!-- 详情 -->
33 126
 <app-incident-detail [id]="coopData.id" *ngIf="detailModalShow" (closeModelHs)="closeDetailModelOrder($event)" (confirmModelHs)="confirmDetailModelOrder($event)"></app-incident-detail>

+ 163 - 75
src/app/components/incidentManagement/incident-ser-visit/incident-ser-visit.component.less

@@ -1,4 +1,56 @@
1 1
 @import "../../../../theme.less";
2
+.icon_transport{
3
+  color: @primary-color;;
4
+}
5
+.coop {
6
+  button{
7
+    color: #333;
8
+  }
9
+  span,button {
10
+    display: inline-block;
11
+    padding: 0 8px;
12
+    cursor: pointer;
13
+    position: relative;
14
+
15
+    &::after {
16
+      content: "|";
17
+      position: absolute;
18
+      top: 0;
19
+      right: 0;
20
+    }
21
+
22
+    &:hover,
23
+    &:active {
24
+      color: @primary-color;
25
+    }
26
+
27
+    &:nth-last-child(1) {
28
+      &::after {
29
+        content: "";
30
+      }
31
+    }
32
+  }
33
+}
34
+.tabs{
35
+  width: 100%;
36
+  height: 56px;
37
+  border-bottom: 1px solid #D9D9D9;
38
+  display: flex;
39
+  align-items: center;
40
+  .tab{
41
+    width: 148px;
42
+    display: flex;
43
+    height: 100%;
44
+    justify-content: center;
45
+    align-items: center;
46
+    font-size: #333;
47
+    cursor: pointer;
48
+    &.active{
49
+      color: @primary-color;
50
+      border-bottom: 2px solid @primary-color;
51
+    }
52
+  }
53
+}
2 54
 .modal {
3 55
   position: fixed;
4 56
   left: 0;
@@ -7,17 +59,29 @@
7 59
   height: 100%;
8 60
   background: rgba(0, 0, 0, 0.4);
9 61
   z-index: 999;
62
+  .tableWrap{
63
+    margin: 0 16px 16px!important;
64
+    background: #F9FAFB;
65
+    border-radius: 8px;
66
+    border: 1px solid #D9D9D9;
67
+    width: calc(100% - 32px);
68
+    min-height: 501px;
69
+    padding: 16px 16px 0;
70
+    ::ng-deep .ant-table-body{
71
+      margin: 0!important;
72
+    }
73
+  }
10 74
   .hospitalTable {
11 75
     width: 100%;
12 76
     td {
13
-      text-align: center !important;
77
+      text-align: center;
14 78
       position: relative;
15 79
       word-break: break-all;
16 80
     }
17 81
     .thead {
18 82
       background-image: linear-gradient(to right, @bg-start, @bg-end);
19 83
       th {
20
-        text-align: center !important;
84
+        text-align: center;
21 85
         color: #fff;
22 86
         background: transparent;
23 87
       }
@@ -37,34 +101,11 @@
37 101
     }
38 102
   }
39 103
 
40
-  .tab {
41
-    width: 100%;
42
-    height: 60px;
43
-    border-bottom: 1px solid #e5e9ed;
44
-    background-color: #fff;
45
-
46
-    .item {
47
-      text-align: center;
48
-      line-height: 60px;
49
-      height: 100%;
50
-      border-right: 1px solid #e5e9ed;
51
-
52
-      &:nth-last-child(1) {
53
-        border: none;
54
-      }
55
-
56
-      &.checked {
57
-        background: #f0f6ed;
58
-      }
59
-    }
60
-  }
61
-
62 104
   .modalBody {
63
-    width: 742px;
64
-    height: 707px;
105
+    width: 1315px;
65 106
     background: #fff;
66 107
     border-radius: 5px;
67
-    padding-bottom: 30px;
108
+    padding: 10px 20px;
68 109
     color: #333;
69 110
     &.modalBody-search {
70 111
       width: 480px;
@@ -73,73 +114,80 @@
73 114
 
74 115
     .title {
75 116
       width: 100%;
76
-      height: 40px;
77
-      line-height: 40px;
78 117
       text-align: center;
79
-      font-size: 16px;
118
+      font-size: 18px;
80 119
       position: relative;
81 120
 
82 121
       i {
83 122
         position: absolute;
84 123
         right: 0;
85 124
         top: 0;
86
-        font-size: 16px;
125
+        font-size: 20px;
87 126
         color: #666;
88 127
         cursor: pointer;
89
-        padding: 0 16px;
128
+        padding: 0 5px;
90 129
       }
91 130
     }
92 131
 
93 132
     .content {
94
-      height: calc(100% - 40px);
95
-      border-top: 1px solid #D9D9D9;
96
-      border-bottom: 1px solid #D9D9D9;
97
-      .items{
98
-        border-bottom: 1px solid #D9D9D9;
99
-        padding: 16px 48px;
100
-        font-size: 14px;
101
-        &:last-of-type{
102
-          border-bottom: none;
103
-        }
104
-        .row{
105
-          position: relative;
133
+      min-height: 117px;
134
+      // background: #f9fafb;
135
+      border: 1px solid #e5e9ed;
136
+      border-radius: 5px;
137
+      overflow: hidden;
138
+      margin-top: 12px;
139
+      display: flex;
140
+      flex-direction: column;
141
+      justify-content: center;
142
+      align-items: center;
143
+      &.content-search {
144
+        min-height: 147px;
145
+        justify-content: start;
146
+        .defeat-search {
147
+          width: 100%;
148
+          height: 52px;
106 149
           display: flex;
107
-          margin-top: 12px;
108
-          &:first-of-type{
109
-            margin-top: 0;
150
+          justify-content: center;
151
+          align-items: center;
152
+          border-bottom: solid 1px #e5e9ed;
153
+          em {
154
+            color: #666;
155
+            font-style: normal;
110 156
           }
111
-          .col{
112
-            margin-right: 48px;
113
-            &:last-of-type{
114
-              margin-right: 0;
115
-            }
116
-            &.btns{
117
-              position: absolute;
118
-              bottom: 0;
119
-              right: 0;
120
-            }
157
+        }
158
+        .form {
159
+          width: 100%;
160
+          padding: 0 16px;
161
+          .ant-form-item-label,
162
+          .ant-form-explain {
163
+            text-align: left !important;
121 164
           }
122 165
         }
123
-        /* 中按钮 */
124
-        .mid_bot {
125
-          width: 65px;
126
-          border-radius: 4px;
127
-          color: white;
128
-          background-color: @primary-color;
129
-          border: 1px @primary-color solid;
130
-          cursor: pointer;
131
-          height: 27px;
166
+      }
167
+
168
+      div {
169
+        text-align: center;
170
+        margin: 0;
171
+
172
+        &.defeat {
173
+          color: #333;
174
+          font-size: 28px;
175
+        }
176
+        &.countDown {
177
+          font-size: 14px;
178
+          color: 666;
179
+          em {
180
+            font-style: normal;
181
+            color: @primary-color;
182
+          }
132 183
         }
133 184
 
134
-        /* 下按钮 */
135
-        .btm_bot {
136
-          width: 65px;
137
-          border-radius: 4px;
138
-          color: #78797a;
139
-          background-color: #FFF;
140
-          border: 1px #e5e9ed solid;
141
-          cursor: pointer;
142
-          height: 27px;
185
+        &.pagination {
186
+          font-size: 14px;
187
+          color: #666;
188
+          padding-top: 16px;
189
+          padding-bottom: 16px;
190
+          text-align: right;
143 191
         }
144 192
       }
145 193
     }
@@ -152,4 +200,44 @@
152 200
       }
153 201
     }
154 202
   }
203
+
204
+  // 新增
205
+  &.add {
206
+    .modalBody {
207
+      width: 480px;
208
+      height: auto;
209
+
210
+      .content {
211
+        width: 100%;
212
+        height: auto;
213
+        padding: 18px 14px 0 14px;
214
+
215
+        .addForm {
216
+          .ant-form-item {
217
+            margin-bottom: 15px;
218
+
219
+            .ant-form-item-label {
220
+              line-height: 0;
221
+            }
222
+          }
223
+        }
224
+
225
+        .editForm {
226
+          .ant-form-item {
227
+            margin-bottom: 15px;
228
+
229
+            .ant-form-item-label {
230
+              line-height: 0;
231
+            }
232
+          }
233
+        }
234
+      }
235
+
236
+      button {
237
+        &:nth-child(1) {
238
+          margin-right: 20px;
239
+        }
240
+      }
241
+    }
242
+  }
155 243
 }

+ 346 - 84
src/app/components/incidentManagement/incident-ser-visit/incident-ser-visit.component.ts

@@ -1,38 +1,165 @@
1
-import { Component, OnInit, Input, Output, EventEmitter, ViewChild } from '@angular/core';
2
-import { ToolService } from 'src/app/services/tool.service';
3
-import { MainService } from 'src/app/services/main.service';
4
-import { OverlayScrollbarsComponent } from 'overlayscrollbars-ngx';
1
+import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core";
2
+import { ActivatedRoute } from "@angular/router";
3
+
4
+import { Subject } from "rxjs";
5
+import { debounceTime } from "rxjs/operators";
6
+import { format, addDays, addHours } from 'date-fns';
7
+import { FormGroup, FormBuilder } from '@angular/forms';
5 8
 import cloneDeep from 'lodash-es/cloneDeep'
6
-import { format, addHours, addDays } from 'date-fns';
9
+import { MainService } from 'src/app/services/main.service';
10
+import { ToolService } from 'src/app/services/tool.service';
7 11
 @Component({
8 12
   selector: 'app-incident-ser-visit',
9 13
   templateUrl: './incident-ser-visit.component.html',
10 14
   styleUrls: ['./incident-ser-visit.component.less']
11 15
 })
12 16
 export class IncidentSerVisitComponent implements OnInit {
13
-  @ViewChild("osComponentRef1", {
14
-    read: OverlayScrollbarsComponent,
15
-    static: false,
16
-  })
17
-  osComponentRef1: OverlayScrollbarsComponent;
18
-  // 切换科室,切换弹窗
19
-  loading = false;
20
-  visitList: any = [];// 列表
21
-  pageIndex: number = 1;//表格当前页码
22
-  pageSize: number = 10;//表格每页展示条数
23
-  total: number = 0;//表格总数据量
24
-
25 17
   @Input() itsmData:any;
26 18
   @Output() closeModelHs = new EventEmitter<any>();//1.组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件
27 19
 
28
-  constructor(private mainService: MainService, private tool: ToolService) { }
20
+  constructor(
21
+    public route: ActivatedRoute,
22
+    private mainService: MainService,
23
+    private tool: ToolService,
24
+    private fb: FormBuilder,
25
+  ) {}
26
+
27
+  listOfData: any[] = []; //表格数据
28
+  coopId: string; //表格中执行操作的id
29
+  hospital: string; //选中院区
30
+  alldepart: any = []; //当前院区所属科室
31
+  worker: number; //选择执行配送人员
32
+  gdState: number; //选择工单状态
33
+  gdStates: any; //工单状态列表
34
+  overdueStates: any; //逾期查询列表
35
+  pageIndex: number = 1; //页码
36
+  listLength: number = 0; //总条数
37
+  pageSize: number = 5; //每页条数
38
+
39
+  promptContent: string; //操作提示框提示信息
40
+  ifSuccess: boolean; //操作成功/失败
41
+  promptInfo: string; //操作结果提示信息
42
+  promptModalShow: boolean; //操作提示框是否展示
43
+
44
+  btnLoading: boolean = false; //提交按钮loading状态
45
+
46
+  tabs:any[] = [
47
+    {key: 'all', value: '全部故障', num: 0, isRed: false},
48
+    {key: 'callback', value: '待我回访', num: 0, isRed: false},
49
+    {key: 'owns', value: '与我关联', num: 0, isRed: false},
50
+  ]
51
+
52
+  searchDTO: any = {};
53
+
54
+  searchTimerSubject = new Subject();
55
+  debounceSubject = new Subject(); //防抖
56
+	maintainDept:any = []; //维修科室
57
+	hosIds:any; //当前院区
58
+  // 初始化增删改按钮
59
+  coopBtns: any = {};
60
+  // 选择tab
61
+  queryTask:string = 'callback';//默认待我回访
62
+  changeTab(key){
63
+    this.queryTask = key;
64
+		this.getDeparts();
65
+    this.loading1 = true;
66
+    this.debounceSubject.next(true);
67
+  }
29 68
 
30 69
   ngOnInit() {
31
-    this.getVisitList();
70
+		this.hosIds = this.tool.getCurrentHospital().id
71
+    console.log(this.itsmData)
72
+    this.searchTimerSubject.pipe(debounceTime(500)).subscribe((v) => {
73
+      let fun = v[0];
74
+      fun.call(this, v[1], v[2]);
75
+    });
76
+    this.debounceSubject.pipe(debounceTime(500)).subscribe((v:boolean) => {
77
+      this.getList(v);
78
+    });
79
+    this.coopBtns = this.tool.initCoopBtns(this.route);
80
+    if(this.itsmData.allDuty == 1){
81
+      this.maintainDept = this.tool.getUserInfoPermission().dutyList || [];
82
+    }else{
83
+      this.maintainDept = this.itsmData.checkedHos || [];
84
+      // if(this.coopBtns.strideLook){
85
+      //   this.defaDept()
86
+      // }
87
+    }
88
+    this.getGdStates();
89
+    this.getHospitalType();
90
+    this.getOverdueStates();
91
+    this.loading1 = true;
92
+    this.debounceSubject.next(true);
32 93
   }
33
-  // 关闭弹窗
34
-  hideModal() {
35
-    this.closeModelHs.emit(JSON.stringify({ show: false }));//emits(向上弹射)事件
94
+
95
+  // 获取院区类型
96
+  hospitalTypes:any[] = [];
97
+  getHospitalType() {
98
+    this.mainService.getDictionary("list", "hospital_type").subscribe((result) => {
99
+      this.hospitalTypes = result || [];
100
+    });
101
+  }
102
+
103
+  // 获取所有的责任部门
104
+  getMaintainDeptList(){
105
+    let type = this.hospitalTypes.find(v => v.value == 6);
106
+    let postData: any = {
107
+      idx: 0,
108
+      sum: 99999,
109
+      hospital: {
110
+        type: type || undefined,
111
+      },
112
+    };
113
+    this.mainService.getFetchDataList("data", "hospital", postData).subscribe(result => {
114
+      if(result.status == 200){
115
+        this.maintainDept = result.list || [];
116
+        // if(this.coopBtns.strideLook){
117
+        //   this.defaDept()
118
+        // }
119
+      }else{
120
+        this.maintainDept = [];
121
+      }
122
+    });
123
+  }
124
+
125
+	defaDept(){
126
+		let itemDept = this.maintainDept.find(i=>i.id == this.hosIds)
127
+		if(itemDept){
128
+			this.searchDTO.maintainDepartment = itemDept.id
129
+		}
130
+		this.getDeparts();
131
+	}
132
+
133
+	// 选择维修科室
134
+	deptChange(e){
135
+		this.searchDTO.department = null;
136
+		this.getDeparts();
137
+	}
138
+
139
+  // 搜索
140
+  search() {
141
+    this.loading1 = true;
142
+    this.debounceSubject.next(true);
143
+  }
144
+  // 重置
145
+  reset() {
146
+    this.searchDTO = {};
147
+		if(this.coopBtns.strideLook){
148
+			this.defaDept()
149
+		}
150
+    this.loading1 = true;
151
+    this.debounceSubject.next(true);
152
+  }
153
+
154
+  onCalendarChangeDate(dateArr){
155
+    console.log(dateArr)
156
+    if(dateArr.length == 2){
157
+      let dateStart = new Date(dateArr[0]);
158
+      let dateEnd = new Date(dateArr[1]);
159
+      dateStart.setHours(0,0,0);
160
+      dateEnd.setHours(23,59,59);
161
+      this.searchDTO.dateRange = [dateStart,dateEnd];
162
+    }
36 163
   }
37 164
 
38 165
   // 优先级颜色
@@ -46,98 +173,233 @@ export class IncidentSerVisitComponent implements OnInit {
46 173
       return 'red';
47 174
     }
48 175
   }
49
-
50
-  // 处理人
51
-  computedHandlerUser(item){
52
-    if(item.state.value == 'pending' && item.currentLog){
53
-      return item.currentLog.workerName;
176
+  // 处理人+协同人
177
+  transferSynergetic(incidentData){
178
+    let str = incidentData.groupORHandlerUser || "";
179
+    if(incidentData.synergetic && incidentData.synergetic.length){
180
+        str += ',' + incidentData.synergetic.map(v => v.name).join(',');
54 181
     }
55
-    if(item.state.value != 'pending' && item.handlingPersonnelUser){
56
-      return item.handlingPersonnelUser.name;
57
-    }
58
-  }
59
-
60
-  // 查看ITSM工单详情
61
-  detailModalShow = false; //弹窗开关
62
-  coopData:any = {};
63
-  openItsmDetails(data) {
64
-    this.coopData = data;
65
-    this.detailModalShow = true;
66
-  }
67
-  // 关闭弹窗
68
-  closeDetailModelOrder(e) {
69
-    this.detailModalShow = JSON.parse(e).show;
70
-  }
71
-  // 弹窗确定
72
-  confirmDetailModelOrder(e){
73
-    console.log(e);
74
-    this.detailModalShow = false;
75
-  }
76
-
77
-  // 回访-弹窗
78
-  visitModalShow = false; //弹窗开关
79
-  visit(data) {
80
-    this.coopData = data;
81
-    this.visitModalShow = true;
82
-  }
83
-  // 关闭弹窗
84
-  closeVisitModelOrder(e) {
85
-    this.visitModalShow = JSON.parse(e).show;
86
-  }
87
-  // 弹窗确定
88
-  confirmVisitModelOrder(e){
89
-    console.log(e);
90
-    this.visitModalShow = false;
91
-    this.getList();
92
-  }
93
-
94
-  // 分页获取数据
95
-  getList(){
96
-    this.getVisitList();
182
+    return str;
97 183
   }
98 184
 
99 185
   // 延期记录
100 186
   transferHandlerLog = function (currentLog) {
101 187
     if(!currentLog){
102
-        return '';
188
+        return '无';
103 189
     }
104 190
     currentLog = cloneDeep(currentLog);
105 191
     if(currentLog.extra1DTO && currentLog.extra2 && currentLog.startTime){
106 192
         if(currentLog.extra2==0.5){
107 193
           currentLog.extra2 = 4;
108
-          return currentLog.extra1DTO.name+" "+ format(addHours(currentLog.startTime, +currentLog.extra2), "MM月dd日") + format(addHours(currentLog.startTime, +currentLog.extra2), "HH时mm分前完成");
194
+          return currentLog.extra1DTO.name+"<br>"+ format(addHours(currentLog.startTime, +currentLog.extra2), "MM月dd日")+"<br>"+ format(addHours(currentLog.startTime, +currentLog.extra2), "HH时mm分前完成");
109 195
         }else{
110
-          return currentLog.extra1DTO.name+" "+ format(addDays(currentLog.startTime, +currentLog.extra2), "MM月dd日前完成");
196
+          return currentLog.extra1DTO.name+"<br>"+ format(addDays(currentLog.startTime, +currentLog.extra2), "MM月dd日前完成");
111 197
         }
112 198
     }else{
113
-        return '';
199
+        return '无';
114 200
     }
115 201
   }
116 202
 
117
-  // 获取回访列表
118
-  getVisitList(){
119
-    this.loading = true;
203
+  // 是否显示回访按钮
204
+  computedVisit(data){
205
+    return this.coopBtns.visit && data.state.value == 'close' && data.deleteFlag !== 1;
206
+  }
207
+
208
+  // 表格数据
209
+  loading1 = false;
210
+  getList(isInit = false) {
120 211
     let postData: any = {
121
-      idx: 0,
122
-      sum: 9999,
212
+      idx: isInit ? 0 : (this.pageIndex - 1),
213
+      sum: this.pageSize,
123 214
       incident: {
124
-        // "groupIds": this.itsmData.allDuty == 1 ? undefined : (this.itsmData.scopeGroups.map(v => v.id).toString() || undefined),
215
+        assignee: this.tool.getCurrentUserId(),
216
+        acceptDate: (this.searchDTO.dateRange && this.searchDTO.dateRange[0]) ? format(this.searchDTO.dateRange[0], 'yyyy-MM-dd HH:mm:ss') : undefined,
217
+        acceptDateEnd: (this.searchDTO.dateRange && this.searchDTO.dateRange[1]) ? format(this.searchDTO.dateRange[1], 'yyyy-MM-dd HH:mm:ss') : undefined,
218
+        incidentsign: this.searchDTO.incidentsign,
219
+        department: this.searchDTO.department ? { id: this.searchDTO.department } : undefined,
220
+        statusId: this.searchDTO.statusId || undefined,
221
+        todoingUser: this.searchDTO.todoingUser ? { id: this.searchDTO.todoingUser } : undefined,
222
+        deleteFlag: 0,
125 223
         "dutyIds": this.itsmData.allDuty == 1 ? undefined : (this.itsmData.checkedHos.map(v => v.id).toString() || undefined),
126 224
         "urgentType": +this.itsmData.orderScopeRadio + 1,
127
-        "queryTask": "callback",
128
-        "assignee": this.tool.getCurrentUserId(),
129
-        "deleteFlag": 0,
130 225
       },
131 226
     };
132 227
 
228
+		if(this.queryTask!='todo' && this.queryTask!='doing' && this.queryTask!='storage'){
229
+			if(this.searchDTO.maintainDepartment){
230
+				let itemDept = this.maintainDept.find(i=>i.id == this.searchDTO.maintainDepartment)
231
+				postData.incident.duty = itemDept;
232
+				delete postData.incident.dutyIds;
233
+			}
234
+		}
235
+
236
+    postData.incident.queryTask = this.queryTask;
237
+
238
+    if(this.queryTask === 'todo' || this.queryTask === 'owns'){
239
+      postData.incident.candidateGroups = this.tool.getCurrentGroupList().map(v => v.id).toString();
240
+    }else{
241
+      delete postData.incident.candidateGroups;
242
+    }
243
+
244
+    this.loading1 = true;
133 245
     this.mainService
134 246
       .getFetchDataList("simple/data", "incident", postData)
135 247
       .subscribe((result) => {
136
-        this.loading = false;
137
-        this.visitList = result.list.map(v => ({...v, endDeptsName: v.endDepts ? v.endDepts.map(v => v.dept).toString() : ''}));
248
+        this.loading1 = false;
249
+        let list = result.list || [];
250
+        list.forEach((item) => {
251
+          item.endDeptsName = item.endDepts ? item.endDepts.map(v => v.dept).toString() : '';
252
+          item.computedVisitFlag = this.computedVisit(item);
253
+        });
254
+        this.listOfData = list;
255
+        this.listLength = result.totalNum;
138 256
       });
257
+
258
+    // 获取数量
259
+    this.getCount(postData.incident);
139 260
   }
261
+
262
+  // 调用接口-查数量
263
+  getCount = function (incident = {}){
264
+    let postData = {
265
+        incidentList: [],
266
+    }
267
+    this.tabs.forEach(v => {
268
+        postData.incidentList.push({...incident, ...{queryTask: v.key}});
269
+    })
270
+    postData.incidentList.forEach(incident => {
271
+        // 请求参数调整
272
+        if(!incident){
273
+            incident = {
274
+              "dutyIds": this.itsmData.allDuty == 1 ? undefined : (this.itsmData.checkedHos.map(v => v.id).toString() || undefined),
275
+              "urgentType": +this.itsmData.orderScopeRadio + 1,
276
+            };
277
+        }
278
+
279
+				if(incident.queryTask!='todo' && incident.queryTask!='doing' && incident.queryTask!='storage'){
280
+					if(this.searchDTO.maintainDepartment){
281
+						let itemDept = this.maintainDept.find(i=>i.id == this.searchDTO.maintainDepartment)
282
+						incident.duty = itemDept;
283
+						delete incident.dutyIds;
284
+					}
285
+				}
286
+
287
+        incident.assignee = this.tool.getCurrentUserId();
288
+
289
+        if(incident.queryTask === 'todo' || incident.queryTask === 'owns'){
290
+          incident.candidateGroups = this.tool.getCurrentGroupList().map(v => v.id).toString();
291
+        }else{
292
+          delete incident.candidateGroups;
293
+        }
294
+    })
295
+    this.mainService
296
+      .getCount(postData)
297
+      .subscribe((result) => {
298
+        let myData = result.data || {};
299
+        this.tabs.forEach(v => {
300
+            v.num = myData[v.key];
301
+        })
302
+      });
140 303
 }
141 304
 
305
+  // 获取所有科室
306
+  getDeparts(dept?) {
307
+    let data = {
308
+      department: {
309
+        searchType: 1,// 简单查询
310
+        cascadeHosId: this.searchDTO.maintainDepartment?this.searchDTO.maintainDepartment:this.tool.getCurrentHospital().id,
311
+        dept: dept,
312
+      },
313
+      idx: 0,
314
+      sum: 20,
315
+    };
316
+    this.isLoading = true;
317
+    this.mainService
318
+      .getFetchDataList("data", "department", data)
319
+      .subscribe((data) => {
320
+        this.alldepart = data.list;
321
+        this.isLoading = false;
322
+      });
323
+  }
142 324
 
325
+  // 获取工单状态
326
+  getGdStates() {
327
+    this.mainService.getDictionary("list", "incident_status").subscribe((data) => {
328
+      this.gdStates = data || [];
329
+    });
330
+  }
143 331
 
332
+  // 获取逾期查询
333
+  getOverdueStates() {
334
+    this.mainService.getDictionary("list", "overdue_state").subscribe((data) => {
335
+      this.overdueStates = data || [];
336
+    });
337
+  }
338
+
339
+  // 展示信息提示框(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)
340
+  showPromptModal(con, success, promptInfo?) {
341
+    this.promptModalShow = false;
342
+    this.promptContent = con;
343
+    this.ifSuccess = success;
344
+    this.promptInfo = promptInfo;
345
+    setTimeout(() => {
346
+      this.promptModalShow = true;
347
+    }, 100);
348
+    this.loading1 = true;
349
+    this.debounceSubject.next(false);
350
+  }
351
+
352
+  // 回访-弹窗
353
+  coopData: any = {}; //当前操作列
354
+  visitModalShow = false; //弹窗开关
355
+  visit(e, data) {
356
+    e.stopPropagation();
357
+    this.coopData = data;
358
+    this.visitModalShow = true;
359
+  }
360
+  // 关闭弹窗
361
+  closeVisitModelOrder(e) {
362
+    this.visitModalShow = JSON.parse(e).show;
363
+  }
364
+  // 弹窗确定
365
+  confirmVisitModelOrder(e){
366
+    console.log(e);
367
+    this.visitModalShow = false;
368
+    this.getList(true);
369
+  }
370
+
371
+  // 详情-弹窗
372
+  detailModalShow = false; //弹窗开关
373
+  detail(e, data) {
374
+    e.stopPropagation();
375
+    this.coopData = data;
376
+    this.detailModalShow = true;
377
+  }
378
+  // 关闭弹窗
379
+  closeDetailModelOrder(e) {
380
+    this.detailModalShow = JSON.parse(e).show;
381
+  }
382
+  // 弹窗确定
383
+  confirmDetailModelOrder(e){
384
+    console.log(e);
385
+    this.detailModalShow = false;
386
+    this.getList(true);
387
+  }
388
+
389
+  // 科室边输边搜节流阀
390
+  isLoading = false;
391
+  changeInp(e) {
392
+    this.searchTimer(this.getDeparts, e);
393
+  }
394
+
395
+  // 边输入边搜索节流阀
396
+  searchTimer(fun, e, type?) {
397
+    this.isLoading = true;
398
+    this.searchTimerSubject.next([fun, e, type]);
399
+  }
400
+
401
+  // 关闭弹窗
402
+  hideModal() {
403
+    this.closeModelHs.emit(JSON.stringify({ show: false }));//emits(向上弹射)事件
404
+  }
405
+}

+ 0 - 1
src/app/components/incidentManagement/incident-substitutio-assign/incident-substitution-assign.component.ts

@@ -156,7 +156,6 @@ export class IncidentSubstitutionAssignComponent implements OnInit {
156 156
     }
157 157
     let postData = {
158 158
       user: {
159
-        hospital: { id: this.validateForm.value.dutyId },
160 159
         name: keyword,
161 160
         simpleQuery: true,
162 161
         groupdata: { id: this.validateForm.value.groupId },

+ 0 - 1
src/app/components/incidentManagement/incident-substitutio-redeploy/incident-substitution-redeploy.component.ts

@@ -91,7 +91,6 @@ export class IncidentSubstitutionRedeployComponent implements OnInit {
91 91
     }
92 92
     let postData = {
93 93
       user: {
94
-        hospital: { id: this.duty.id },
95 94
         name: keyword,
96 95
         simpleQuery: true,
97 96
         groupdata: { id: this.validateForm.value.groupId },

+ 14 - 0
src/app/components/incidentManagement/incident-substitution/incident-substitution.component.ts

@@ -88,6 +88,20 @@ export class IncidentSubstitutionComponent implements OnInit {
88 88
         // 转派
89 89
         if(this.incidentData.state.value == 'handler' && this.incidentData.handlingPersonnelUser && this.incidentData.handlingPersonnelUser.id == this.tool.getCurrentUserId() && !this.coopBtns.assign && this.coopBtns.transfer){
90 90
           this.tabs.splice(0, 0, {id: 1, name: '转派', value: 'redeploy', num: ''});
91
+        }else if(this.incidentData.state.value == 'pending'){
92
+          let inUser = this.incidentData.currentLog && this.incidentData.currentLog.workerId == this.tool.getCurrentUserId();
93
+          let inGroup = false;
94
+          let groupList = this.tool.getCurrentGroupList();
95
+          groupList.forEach(item => {
96
+              if(this.incidentData.currentLog){
97
+                  if (item.id == this.incidentData.currentLog.groupId) {
98
+                      inGroup = true;
99
+                  }
100
+              }
101
+          })
102
+          if((inUser || inGroup)){
103
+            this.tabs.splice(0, 0, {id: 1, name: '转派', value: 'redeploy', num: ''});
104
+          }
91 105
         }
92 106
 
93 107
         // 指派

+ 22 - 0
src/app/guard/realtimeBroadcast.guard.ts

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

+ 4 - 1
src/app/services/tool.service.ts

@@ -43,7 +43,7 @@ export class ToolService {
43 43
   }
44 44
 	// 获取权限中的信息
45 45
 	getUserInfoPermission() {
46
-	  return JSON.parse(localStorage.getItem("user")).infoPermission || [];
46
+	  return JSON.parse(localStorage.getItem("user")).infoPermission || {};
47 47
 	}
48 48
   // 获取权限中的分组
49 49
   getGroupList() {
@@ -289,6 +289,9 @@ export class ToolService {
289 289
 				case "strideLook":
290 290
 				  coopBtns.strideLook = true; //跨科查看
291 291
 				  break;
292
+				case "crossHospital":
293
+				  coopBtns.crossHospital = true; //跨部门选组
294
+				  break;
292 295
       }
293 296
     });
294 297
     console.log(coopBtns);

+ 1 - 1
src/app/views/fuwutai/fuwutai.component.html

@@ -1136,7 +1136,7 @@
1136 1136
                           <nz-form-item>
1137 1137
                             <nz-form-label class="label" [nzSm]="24" [nzXs]="24" nzRequired nzFor="endDepts">终点科室</nz-form-label>
1138 1138
                             <nz-form-control class="control" [nzSm]="24" [nzXs]="24" nzErrorTip="请选择终点科室!">
1139
-                              <nz-select formControlName="endDepts" [nzDisabled]="deptZyList.endStatus == 201 || deptZyList.endStatus == 203 || deptZyList.endStatus == 206" [nzDropdownMatchSelectWidth]="false" nzServerSearch nzShowSearch (nzOnSearch)="searchHosDepartment(checkedHos, 'end', $event)" nzAllowClear nzPlaceHolder="请选择终点科室" [(ngModel)]="endDeptZy" (ngModelChange)="endDeptZyChange(e)">
1139
+                              <nz-select formControlName="endDepts" [nzDisabled]="deptZyList.endStatus == 201 || deptZyList.endStatus == 203 || deptZyList.endStatus == 206" [nzDropdownMatchSelectWidth]="false" nzServerSearch nzShowSearch (nzOnSearch)="searchHosDepartment(checkedHos, 'end', $event)" nzAllowClear nzPlaceHolder="请选择终点科室" [(ngModel)]="endDeptZy" (ngModelChange)="endDeptZyChange()">
1140 1140
                                 <ng-container *ngFor="let option of deptZyList.endDept">
1141 1141
                                   <nz-option *ngIf="!isLoading" [nzLabel]="option.dept" [nzValue]="option.id"></nz-option>
1142 1142
                                 </ng-container>

+ 0 - 1
src/app/views/fuwutai/fuwutai.component.ts

@@ -3235,7 +3235,6 @@ export class FuwutaiComponent implements OnInit {
3235 3235
       sum: 20,
3236 3236
       user: {
3237 3237
         name:keyWord,
3238
-				hospital: this.incidentModel.duty ? { id: this.incidentModel.duty.id } : undefined,
3239 3238
 				groupdata: this.incidentModel.group ? { id: this.incidentModel.group } : undefined,
3240 3239
         roleCodes: 'first-line support',
3241 3240
         engineer: 1,

+ 27 - 28
src/app/views/hospital-management/hospital-management.component.html

@@ -17,10 +17,11 @@
17 17
       >
18 18
         <thead>
19 19
           <tr class="thead">
20
-            <th nzWidth="20%">院区/部门名称</th>
21
-            <th nzWidth="20%">部门类型</th>
22
-            <th nzWidth="20%">父院区</th>
23
-            <th nzWidth="20%">院区编码</th>
20
+            <th nzWidth="16%">院区/部门名称</th>
21
+            <th nzWidth="16%">部门类型</th>
22
+            <th nzWidth="16%">父院区</th>
23
+            <th nzWidth="16%">父级部门</th>
24
+            <th nzWidth="16%">院区编码</th>
24 25
             <th nzWidth="20%">操作</th>
25 26
           </tr>
26 27
         </thead>
@@ -29,18 +30,13 @@
29 30
             <td>{{ data.hosName || '无' }}</td>
30 31
             <td>{{ data.type ? data.type.name : '无' }}</td>
31 32
             <td>{{ data.parent ? data.parent.hosName : '无' }}</td>
33
+            <td>{{ data.parentDeptDTO ? data.parentDeptDTO.hosName : '无' }}</td>
32 34
             <td>{{ data.hosNo || '无' }}</td>
33 35
             <td>
34 36
               <div class="coop">
35
-                <span
36
-                  *ngIf="currentUserAccount == 'dsadmin'"
37
-                  (click)="copy(data)"
38
-                  >复制</span
39
-                >
37
+                <span *ngIf="currentUserAccount == 'dsadmin'" (click)="copy(data)">复制</span>
40 38
                 <span *ngIf="coopBtns.edit" (click)="edit(data)">编辑</span>
41
-                <span *ngIf="coopBtns.del" (click)="showDelModal(data.id)"
42
-                  >删除</span
43
-                >
39
+                <span *ngIf="coopBtns.del" (click)="showDelModal(data.id)">删除</span>
44 40
               </div>
45 41
             </td>
46 42
           </tr>
@@ -61,16 +57,9 @@
61 57
   </div>
62 58
 
63 59
   <!-- 新增/编辑模态框 -->
64
-  <div
65
-    class="save align-items_center display_flex justify-content_flex-center add"
66
-    *ngIf="modal"
67
-  >
60
+  <div class="save align-items_center display_flex justify-content_flex-center add" *ngIf="modal">
68 61
     <div class="modalBody">
69
-      <div class="title">
70
-        {{ add ? "新增" : "编辑" }}<i
71
-          class="icon_transport transport-guanbi"
72
-          (click)="hideAddModal()"
73
-        ></i>
62
+      <div class="title">{{ add ? "新增" : "编辑" }}<i class="icon_transport transport-guanbi" (click)="hideAddModal()"></i>
74 63
       </div>
75 64
       <div class="content">
76 65
         <form
@@ -80,14 +69,9 @@
80 69
           (ngSubmit)="submitForm()"
81 70
         >
82 71
           <nz-form-item>
83
-            <nz-form-label
84
-              [nzSm]="6"
85
-              [nzXs]="24"
86
-              nzFor="parentHospital"
87
-              >父院区</nz-form-label
88
-            >
72
+            <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="parentHospital">父院区</nz-form-label>
89 73
             <nz-form-control nzErrorTip="请选择父院区!">
90
-              <nz-select formControlName="parentHospital" [nzDropdownMatchSelectWidth]="false" nzPlaceHolder="请选择父院区" nzShowSearch nzAllowClear nzServerSearch (nzOnSearch)="changeInp($event)"
74
+              <nz-select formControlName="parentHospital" [nzDropdownMatchSelectWidth]="false" nzPlaceHolder="请选择父院区" nzShowSearch nzAllowClear nzServerSearch (nzOnSearch)="changeInp($event, 'parent')"
91 75
               (nzOpenChange)="openHospitalSelect($event)" (ngModelChange)="changeHospitalSelect($event)">
92 76
                 <ng-container *ngFor="let option of parentHospitals">
93 77
                   <nz-option *ngIf="!isLoading" [nzLabel]="option.hosName" [nzValue]="option.id"></nz-option>
@@ -100,6 +84,21 @@
100 84
             </nz-form-control>
101 85
           </nz-form-item>
102 86
           <nz-form-item>
87
+            <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="parentDeptId">父级部门</nz-form-label>
88
+            <nz-form-control nzErrorTip="请选择父级部门!">
89
+              <nz-select formControlName="parentDeptId" [nzDropdownMatchSelectWidth]="false" nzPlaceHolder="请选择父级部门" nzShowSearch nzAllowClear nzServerSearch (nzOnSearch)="changeInp($event, 'parentDept')"
90
+              (nzOpenChange)="openParentDeptSelect($event)">
91
+                <ng-container *ngFor="let option of parentDepts">
92
+                  <nz-option *ngIf="!isLoading" [nzLabel]="option.hosName" [nzValue]="option.id"></nz-option>
93
+                </ng-container>
94
+                <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
95
+                  <i nz-icon nzType="loading" class="loading-icon"></i>
96
+                  搜索中...
97
+                </nz-option>
98
+              </nz-select>
99
+            </nz-form-control>
100
+          </nz-form-item>
101
+          <nz-form-item>
103 102
             <nz-form-label
104 103
               [nzSm]="6"
105 104
               [nzXs]="24"

+ 77 - 27
src/app/views/hospital-management/hospital-management.component.ts

@@ -26,18 +26,29 @@ export class HospitalManagementComponent implements OnInit {
26 26
   ) {}
27 27
 
28 28
   ngOnInit() {
29
-    this.searchParentHospitalSubject.pipe(debounceTime(500)).subscribe((v: any) => {
30
-      this.getAllParentHospital(v).subscribe((result) => {
31
-        this.isLoading = false;
32
-        if (result.status == 200) {
33
-          this.parentHospitals = result.list;
34
-        }
35
-      });
29
+    this.searchParentHospitalSubject.pipe(debounceTime(500)).subscribe(({e, type}) => {
30
+      if(type === 'parentDept'){
31
+        this.getAllParentHospital(e, type === 'parentDept').subscribe((result) => {
32
+          this.isLoading = false;
33
+          if (result.status == 200) {
34
+            this.parentDepts = result.list;
35
+          }
36
+        });
37
+      }else if(type === 'parent'){
38
+        this.getAllParentHospital(e, type === 'parentDept').subscribe((result) => {
39
+          this.isLoading = false;
40
+          if (result.status == 200) {
41
+            this.parentHospitals = result.list;
42
+          }
43
+        });
44
+      }
45
+
36 46
     });
37 47
     this.coopBtns = this.tool.initCoopBtns(this.route);
38 48
     this.getList();
39 49
     this.initForm();
40 50
     this.initFormCopy();
51
+    this.getHospitalType();
41 52
   }
42 53
 
43 54
   currentUserAccount: any = JSON.parse(localStorage.getItem("user")).user.account; //当前登录人账号
@@ -63,11 +74,12 @@ export class HospitalManagementComponent implements OnInit {
63 74
   coopBtns: any = {};
64 75
   //所有院区
65 76
   parentHospitals: any = [];
77
+  parentDepts: any = [];
66 78
   searchParentHospitalSubject = new Subject();
67 79
   //搜索父级院区
68
-  changeInp(e) {
80
+  changeInp(e, type) {
69 81
     this.isLoading = true;
70
-    this.searchParentHospitalSubject.next(e);
82
+    this.searchParentHospitalSubject.next({e, type});
71 83
   }
72 84
   // 打开父级科室下拉框
73 85
   isLoading = false;
@@ -82,6 +94,18 @@ export class HospitalManagementComponent implements OnInit {
82 94
       });
83 95
     }
84 96
   }
97
+  // 打开父级部门下拉框
98
+  openParentDeptSelect(flag) {
99
+    if (flag) {
100
+      this.isLoading = true;
101
+      this.getAllParentHospital('', true).subscribe((result) => {
102
+        this.isLoading = false;
103
+        if (result.status == 200) {
104
+          this.parentDepts = result.list;
105
+        }
106
+      });
107
+    }
108
+  }
85 109
   // 选择父级科室下拉框
86 110
   changeHospitalSelect(e) {
87 111
     if(!e){
@@ -101,20 +125,42 @@ export class HospitalManagementComponent implements OnInit {
101 125
       });
102 126
     }
103 127
   }
128
+  // 获取院区类型
129
+  getHospitalType() {
130
+    this.mainService.getDictionary("list", "hospital_type").subscribe((result) => {
131
+      this.hospitalTypes = result || [];
132
+    });
133
+  }
104 134
   //获取所有的父级院区列表
105
-  getAllParentHospital(keyWord = "") {
106
-    let postData: any = {
107
-      idx: 0,
108
-      sum: 10,
109
-      hospital: {
110
-        keyWord: keyWord,
111
-      },
112
-    };
113
-    if (this.coopId) {
114
-      // 过滤这个院区及其子院区
115
-      postData.hospital.filterByHosId = this.coopId;
135
+  getAllParentHospital(keyWord = "", isParentDept = false) {
136
+    if(isParentDept){
137
+      let postData: any = {
138
+        idx: 0,
139
+        sum: 10,
140
+        hospital: {
141
+          keyWord: keyWord,
142
+          type: isParentDept ? this.hospitalTypes.find(v => v.value == 6) : undefined
143
+        },
144
+      };
145
+      if (this.coopId) {
146
+        // 过滤这个院区及其子院区
147
+        postData.hospital.filterByHosId = this.coopId;
148
+      }
149
+      return this.mainService.getFetchDataList("data", "hospital", postData);
150
+    }else{
151
+      let postData: any = {
152
+        idx: 0,
153
+        sum: 10,
154
+        hospital: {
155
+          keyWord: keyWord,
156
+        },
157
+      };
158
+      if (this.coopId) {
159
+        // 过滤这个院区及其子院区
160
+        postData.hospital.filterByHosId = this.coopId;
161
+      }
162
+      return this.mainService.getFetchDataList("data", "hospital", postData);
116 163
     }
117
-    return this.mainService.getFetchDataList("data", "hospital", postData);
118 164
   }
119 165
 
120 166
   // 表格数据
@@ -204,6 +250,7 @@ export class HospitalManagementComponent implements OnInit {
204 250
     this.validateForm = this.fb.group({
205 251
       hospitalType: [null],
206 252
       parentHospital: [null],
253
+      parentDeptId: [null],
207 254
       hospitalName: [null, [Validators.required]],
208 255
       hospitalNum: [null, [Validators.required]],
209 256
     });
@@ -227,6 +274,9 @@ export class HospitalManagementComponent implements OnInit {
227 274
     if (this.validateForm.value.parentHospital) {
228 275
       data.hospital.parent = { id: this.validateForm.value.parentHospital };
229 276
     }
277
+    if (this.validateForm.value.parentDeptId) {
278
+      data.hospital.parentDeptId =  this.validateForm.value.parentDeptId;
279
+    }
230 280
     if (this.validateForm.value.hospitalType) {
231 281
       data.hospital.type = { id: this.validateForm.value.hospitalType };
232 282
     }
@@ -253,12 +303,12 @@ export class HospitalManagementComponent implements OnInit {
253 303
     this.modal = true;
254 304
     this.coopId = data.id;
255 305
     if (data.parent) {
256
-      this.getAllParentHospital(data.parent.dept).subscribe((res) => {
257
-        if (res.status == 200) {
258
-          this.parentHospitals = res.list;
259
-          this.validateForm.controls.parentHospital.setValue(data.parent.id);
260
-        }
261
-      });
306
+      this.parentHospitals = [data.parent];
307
+      this.validateForm.controls.parentHospital.setValue(data.parent.id);
308
+    }
309
+    if (data.parentDeptId && data.parentDeptDTO) {
310
+      this.parentDepts = [data.parentDeptDTO];
311
+      this.validateForm.controls.parentDeptId.setValue(data.parentDeptId);
262 312
     }
263 313
     if(data.type){
264 314
       this.mainService.getDictionary("list", "hospital_type").subscribe((result) => {

+ 35 - 15
src/app/views/incident-management/incident-management.component.ts

@@ -1,4 +1,4 @@
1
-import { Component, OnInit } from "@angular/core";
1
+import { Component, OnInit, OnDestroy } from "@angular/core";
2 2
 import { ActivatedRoute, Router } from "@angular/router";
3 3
 
4 4
 import { MainService } from "../../services/main.service";
@@ -14,7 +14,7 @@ import cloneDeep from 'lodash-es/cloneDeep'
14 14
   templateUrl: "./incident-management.component.html",
15 15
   styleUrls: ["./incident-management.component.less"],
16 16
 })
17
-export class IncidentManagementComponent implements OnInit {
17
+export class IncidentManagementComponent implements OnInit, OnDestroy {
18 18
   constructor(
19 19
     public route: ActivatedRoute,
20 20
     private router: Router,
@@ -85,7 +85,7 @@ export class IncidentManagementComponent implements OnInit {
85 85
 			}else{
86 86
 				this.maintainGroup = this.tool.getUserInfoPermission().dutyGroupList
87 87
 			}
88
-			
88
+
89 89
 		}
90 90
 		this.getDeparts();
91 91
 		this.getUsers('', 'handle');
@@ -114,6 +114,25 @@ export class IncidentManagementComponent implements OnInit {
114 114
     this.getIncidentCategoryList();
115 115
     this.loading1 = true;
116 116
     this.debounceSubject.next(true);
117
+    this.autoRefresh();
118
+  }
119
+
120
+  ngOnDestroy(){
121
+    this.cancelRefresh();
122
+  }
123
+
124
+  // 定时器自动刷新页面
125
+  timer = null;
126
+  autoRefresh(){
127
+    this.cancelRefresh();
128
+    this.timer = setInterval(() => {
129
+      this.getList();
130
+    }, 60000)
131
+  }
132
+
133
+  // 清除定时器
134
+  cancelRefresh(){
135
+    clearInterval(this.timer);
117 136
   }
118 137
 
119 138
   // 初始化tab
@@ -133,7 +152,7 @@ export class IncidentManagementComponent implements OnInit {
133 152
     //     this.tabs.push({key: 'badEvaluate', value: '异常评价', num: 0, isRed: false});
134 153
     // }
135 154
   }
136
-	
155
+
137 156
 	defaDept(){
138 157
 		let itemDept = this.maintainDept.find(i=>i.id == this.hosIds)
139 158
 		if(itemDept){
@@ -143,7 +162,7 @@ export class IncidentManagementComponent implements OnInit {
143 162
 		this.getUsers('', 'handle');
144 163
 		this.getUsers('', 'acceptUser');
145 164
 	}
146
-	
165
+
147 166
 	// 选择维修科室
148 167
 	deptChange(e){
149 168
 		this.searchDTO.maintainGroup = null
@@ -153,11 +172,12 @@ export class IncidentManagementComponent implements OnInit {
153 172
 		}else{
154 173
 			this.maintainGroup = this.tool.getUserInfoPermission().dutyGroupList
155 174
 		}
156
-		this.searchDTO.maintainDepartment = e
175
+		this.searchDTO.department = null
176
+		this.searchDTO.todoingUser = null
157 177
 		this.getDeparts();
158 178
 		this.getUsers('', 'handle');
159 179
 	}
160
-	
180
+
161 181
   // 搜索
162 182
   search() {
163 183
     this.loading1 = true;
@@ -356,7 +376,7 @@ export class IncidentManagementComponent implements OnInit {
356 376
         delete postData.incident.duty;
357 377
         delete postData.incident.hosId;
358 378
     }
359
-		
379
+
360 380
 		if(this.queryTask!='todo' && this.queryTask!='doing' && this.queryTask!='storage'){
361 381
 			if(this.searchDTO.maintainDepartment){
362 382
 				let itemDept = this.maintainDept.find(i=>i.id == this.searchDTO.maintainDepartment)
@@ -369,7 +389,7 @@ export class IncidentManagementComponent implements OnInit {
369 389
 		}else{
370 390
 			delete postData.incident.candidateGroupId;
371 391
 		}
372
-		
392
+
373 393
     postData.incident.queryTask = this.queryTask;
374 394
 
375 395
     if(this.queryTask === 'todo' || this.queryTask === 'owns'){
@@ -428,7 +448,7 @@ export class IncidentManagementComponent implements OnInit {
428 448
             delete incident.duty;
429 449
             delete incident.hosId;
430 450
         }
431
-				
451
+
432 452
 				if(incident.queryTask!='todo' && incident.queryTask!='doing' && incident.queryTask!='storage'){
433 453
 					if(this.searchDTO.maintainDepartment){
434 454
 						let itemDept = this.maintainDept.find(i=>i.id == this.searchDTO.maintainDepartment)
@@ -436,7 +456,7 @@ export class IncidentManagementComponent implements OnInit {
436 456
 						delete incident.hosId;
437 457
 					}
438 458
 				}
439
-				
459
+
440 460
         incident.assignee = this.tool.getCurrentUserId();
441 461
 
442 462
         if(incident.queryTask === 'todo' || incident.queryTask === 'owns'){
@@ -669,7 +689,7 @@ export class IncidentManagementComponent implements OnInit {
669 689
         acceptUser: this.validateSearchForm.value.acceptUser ? { id: this.validateSearchForm.value.acceptUser } : undefined,
670 690
         selectType: this.validateSearchForm.value.selectType || undefined,
671 691
         deleteFlag: this.validateSearchForm.value.deleteFlag,
672
-				candidateGroupId: null
692
+				candidateGroupId: undefined
673 693
       },
674 694
     };
675 695
 
@@ -686,7 +706,7 @@ export class IncidentManagementComponent implements OnInit {
686 706
         delete postData.incident.duty;
687 707
         delete postData.incident.hosId;
688 708
     }
689
-		
709
+
690 710
 		if(this.queryTask!='todo' && this.queryTask!='doing' && this.queryTask!='storage'){
691 711
 			if(this.searchDTO.maintainDepartment){
692 712
 				let itemDept = this.maintainDept.find(i=>i.id == this.searchDTO.maintainDepartment)
@@ -694,13 +714,13 @@ export class IncidentManagementComponent implements OnInit {
694 714
 				delete postData.incident.hosId;
695 715
 			}
696 716
 		}
697
-		
717
+
698 718
 		if(this.queryTask!='todo' && this.queryTask!='owns' && this.queryTask!='storage'){
699 719
 			postData.incident.candidateGroupId = this.searchDTO.maintainGroup
700 720
 		}else{
701 721
 			delete postData.incident.candidateGroupId;
702 722
 		}
703
-		
723
+
704 724
     postData.incident.queryTask = this.queryTask;
705 725
 
706 726
     if(this.queryTask === 'todo' || this.queryTask === 'owns'){

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

@@ -49,6 +49,7 @@
49 49
 							<div class="dropdownItem" *ngIf="sampling" (click)="toSampling()">门诊病理采样端</div>
50 50
 							<div class="dropdownItem" *ngIf="communicationBook" (click)="toCommunicationBook()">病理交接本</div>
51 51
 							<div class="dropdownItem" *ngIf="disinfectionSupplyRole" (click)="toDisinfectionSupply()">全局业务查看</div>
52
+							<div class="dropdownItem" *ngIf="realtimeBroadcastRole" (click)="toRealtimeBroadcast()">故障实时播报</div>
52 53
             </div>
53 54
           </div>
54 55
         </div>

+ 9 - 0
src/app/views/main/main.component.ts

@@ -34,6 +34,7 @@ export class MainComponent implements OnInit {
34 34
 	sampling: boolean = false; //门诊病理采样端权限
35 35
 	communicationBook: boolean = false; //病理交接本权限
36 36
   disinfectionSupplyRole: boolean = false; //全局业务查看权限
37
+  realtimeBroadcastRole: boolean = false; //全局业务查看权限
37 38
   incidentConfigRole: boolean = false; //事件配置权限
38 39
   otherConfigRole: boolean = false; //三方配置权限
39 40
   pageConfigRole: boolean = false; //业务页面控制权限
@@ -316,6 +317,10 @@ export class MainComponent implements OnInit {
316 317
         this.disinfectionSupplyRole = true;
317 318
         console.log("全局业务查看权限");
318 319
       }
320
+      if (e.link == "realtimeBroadcast") {
321
+        this.realtimeBroadcastRole = true;
322
+        console.log("故障实时播报权限");
323
+      }
319 324
       if (e.link == "incidentConfig") {
320 325
         this.incidentConfigRole = true;
321 326
         console.log("事件配置权限");
@@ -463,6 +468,10 @@ export class MainComponent implements OnInit {
463 468
   toDisinfectionSupply(): void {
464 469
     this.router.navigateByUrl("disinfectionSupply");
465 470
   }
471
+  // 故障实时播报
472
+  toRealtimeBroadcast(): void {
473
+    this.router.navigateByUrl("realtimeBroadcast");
474
+  }
466 475
   // 配置中心
467 476
   toConfigurationCenter(): void {
468 477
     this.iShowMenuModal = true;

+ 18 - 0
src/app/views/realtime-broadcast/realtime-broadcast-routing.module.ts

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

Fichier diff supprimé car celui-ci est trop grand
+ 157 - 0
src/app/views/realtime-broadcast/realtime-broadcast.component.html


+ 601 - 0
src/app/views/realtime-broadcast/realtime-broadcast.component.less

@@ -0,0 +1,601 @@
1
+@import "../../../../src/theme.less";
2
+.icon_transport{
3
+  color: @primary-color;
4
+}
5
+.blue{
6
+  color: #57D8FF;
7
+}
8
+:host {
9
+  width: 100vw;
10
+  height: 100vh;
11
+  background-color: #00253F;
12
+  .save {
13
+    position: fixed;
14
+    left: 0;
15
+    top: 0;
16
+    width: 100%;
17
+    height: 100%;
18
+    background: rgba(0, 0, 0, 0.4);
19
+    z-index: 99;
20
+
21
+    .modalBody {
22
+      width: 350px;
23
+      background: #fff;
24
+      border-radius: 5px;
25
+      padding: 10px 20px;
26
+      color: #333;
27
+
28
+      .title {
29
+        width: 100%;
30
+        text-align: center;
31
+        font-size: 18px;
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: 100%;
47
+        height: 145px;
48
+        background: #f9fafb;
49
+        border: 1px solid #e5e9ed;
50
+        border-radius: 5px;
51
+        overflow: hidden;
52
+        margin-top: 12px;
53
+
54
+        div {
55
+          text-align: center;
56
+          margin: 0;
57
+
58
+          &.icon {
59
+            margin-top: 17px;
60
+
61
+            i {
62
+              color: #34b349;
63
+              font-size: 30px !important;
64
+
65
+              &.transport-wenhao {
66
+                color: #f5a523;
67
+              }
68
+
69
+              &.transport-shibai {
70
+                color: #ff3a52;
71
+              }
72
+            }
73
+          }
74
+
75
+          &.defeat {
76
+            color: #333;
77
+            font-size: 18px;
78
+          }
79
+
80
+          &:nth-child(3) {
81
+            font-size: 14px;
82
+            color: #666;
83
+          }
84
+        }
85
+      }
86
+
87
+      button {
88
+        margin-top: 10px;
89
+
90
+        &.btn {
91
+          margin-left: 8px;
92
+        }
93
+      }
94
+    }
95
+
96
+    // 新增
97
+    &.add {
98
+      .modalBody {
99
+        width: 480px;
100
+        height: auto;
101
+
102
+        .content {
103
+          width: 100%;
104
+          height: auto;
105
+          padding: 19px 14px 0 14px;
106
+          max-height: 500px;
107
+          overflow-y: auto;
108
+
109
+          .addForm {
110
+            .ant-form-item {
111
+              margin-bottom: 8px;
112
+
113
+              .ant-form-item-label {
114
+                text-align: left;
115
+              }
116
+            }
117
+          }
118
+
119
+          .editForm {
120
+            .ant-form-item {
121
+              margin-bottom: 14px;
122
+            }
123
+          }
124
+        }
125
+
126
+        button:nth-child(1) {
127
+          margin-right: 20px;
128
+        }
129
+      }
130
+    }
131
+  }
132
+  .realtimeBroadcast{
133
+    height: 100%;
134
+    display: flex;
135
+    flex-direction: column;
136
+    justify-content: space-between;
137
+    color: #fff;
138
+    .header{
139
+      height: 48px;
140
+      padding: 0 16px;
141
+      display: flex;
142
+      justify-content: space-between;
143
+      align-items: center;
144
+      background-color: #012F48;
145
+      .title{
146
+        display: flex;
147
+        align-items: center;
148
+        h1{
149
+          margin: 0;
150
+          font-size: 16px;
151
+          font-weight: normal;
152
+          color: #FFFFFF;
153
+        }
154
+        h2{
155
+          margin: 0;
156
+          font-size: 20px;
157
+          font-weight: bold;
158
+          color: #FFFFFF;
159
+          margin-left: 50px;
160
+        }
161
+      }
162
+      .userInfo {
163
+        height: 100%;
164
+        float: right;
165
+        padding: 0 24px;
166
+        box-sizing: border-box;
167
+        font-size: 14px;
168
+
169
+        // 下拉列表
170
+        &.dropdown{
171
+          position: relative;
172
+          height: 48px;
173
+          line-height: 48px;
174
+          .dropdown-content {
175
+            position: absolute;
176
+            top: 48px;
177
+            background-color: #fff;
178
+            width: 156px;
179
+            box-shadow: 0px 2px 4px 1px #D9D9D9;
180
+            z-index: 999999;
181
+            border-radius: 4px;
182
+            border: 1px solid rgba(0,0,0,0.15);
183
+            color: rgba(0,0,0,0.65);
184
+            &.ct{
185
+              left: 50%;
186
+              transform: translateX(-50%);
187
+            }
188
+            &.r8{
189
+              right: 8px;
190
+            }
191
+          }
192
+
193
+          .dropdown-content .dropdownItem {
194
+            height: 40px;
195
+            cursor: pointer;
196
+            display: flex;
197
+            align-items: center;
198
+            padding: 0 24px;
199
+          }
200
+
201
+          .dropdown-content .dropdownItem:hover {
202
+            background-color: #e9f7e9;
203
+          }
204
+        }
205
+
206
+        .wel {
207
+          line-height: 15px;
208
+          white-space: nowrap;
209
+          overflow: hidden;//文本超出隐藏
210
+          text-overflow: ellipsis;//文本超出省略号替代
211
+        }
212
+
213
+        .user {
214
+          overflow: hidden;
215
+          height: 48px;
216
+          display: flex;
217
+          justify-content: center;
218
+          align-items: center;
219
+          font-size: 16px;
220
+          cursor: pointer;
221
+
222
+          img {
223
+            width: 32px;
224
+            height: 32px;
225
+            margin-right: 8px;
226
+          }
227
+
228
+          span, .transport-xiala1 {
229
+            height: 48px;
230
+            line-height: 48px;
231
+          }
232
+        }
233
+
234
+        .logOut {
235
+          text-align: right;
236
+          color: @primary-color;
237
+          line-height: 20px;
238
+
239
+          span {
240
+            cursor: pointer;
241
+            padding: 10px;
242
+          }
243
+        }
244
+      }
245
+    }
246
+  }
247
+
248
+  // 调度台copy过来的
249
+  /* 工单总数 */
250
+  .lists_box {
251
+    width: 100%;
252
+    height: calc(100vh - 56px);
253
+    display: flex;
254
+    margin-bottom: 8px;
255
+  }
256
+
257
+  .lists {
258
+    flex: 1;
259
+    margin-right: 16px;
260
+    overflow: hidden;
261
+    position: relative;
262
+  }
263
+
264
+  .lists:nth-child(1) {
265
+    margin-left: 16px;
266
+  }
267
+
268
+  /* 头部 */
269
+  .lists .head {
270
+    height: 52px;
271
+    display: flex;
272
+    align-items: center;
273
+    justify-content: space-between;
274
+    font-size: 16px;
275
+    position: relative;
276
+    z-index: 8;
277
+    background-color: #164967;
278
+    box-shadow: 0px 3px 6px 1px #092543;
279
+    margin: 8px 0;
280
+    padding: 0 8px;
281
+    .title_bold{
282
+      font-weight: bold;
283
+    }
284
+    .refreshSeconds{
285
+      font-size: 14px;
286
+    }
287
+  }
288
+
289
+  .lists .head .shuaxin {
290
+    float: right;
291
+    color: @primary-color;
292
+    cursor: pointer;
293
+  }
294
+
295
+  .lists .head .shuaxin i {
296
+    font-size: 12px;
297
+  }
298
+
299
+  .lists .head .shuaxin span {
300
+    font-size: 12px;
301
+  }
302
+
303
+  /* 搜索 */
304
+  .lists .searchBox {
305
+    width: 100%;
306
+    padding: 10px 2%;
307
+    background: #f9fafb;
308
+    position: relative;
309
+    z-index: 8;
310
+    display: flex;
311
+    justify-content: space-between;
312
+    align-items: center;
313
+
314
+    .search {
315
+      height: 34px;
316
+      width: 90%;
317
+      background-color: white;
318
+      border: 1px rgb(225, 229, 232) solid;
319
+      border-radius: 20px;
320
+      overflow: hidden;
321
+    }
322
+  }
323
+
324
+  .lists input {
325
+    padding-left: 3%;
326
+    color: black;
327
+    height: 32px;
328
+    width: 80%;
329
+    float: left;
330
+    border: none;
331
+
332
+    &:focus {
333
+      outline: none;
334
+    }
335
+  }
336
+
337
+  .lists input::-webkit-input-placeholder {
338
+    color: #999999;
339
+  }
340
+
341
+  .lists .magnifier {
342
+    width: 14%;
343
+    height: 32px;
344
+    line-height: 32px;
345
+    float: left;
346
+    border-left: 1px rgb(225, 229, 232) solid;
347
+    cursor: pointer;
348
+    text-align: right;
349
+  }
350
+
351
+  .lists .magnifier i {
352
+    color: #999999;
353
+  }
354
+
355
+  .lists .magnifier span {
356
+    color: @primary-color;
357
+  }
358
+
359
+  /* 单子内容盒子 */
360
+  .lists .cots_body {
361
+    width: 100%;
362
+    height: calc(100% - 68px);
363
+    background: #0f384e;
364
+    border: 1px solid #7D7D7D;
365
+    color: #fff;
366
+  }
367
+
368
+  /* loading */
369
+  .cots_body .loading {
370
+    width: 100%;
371
+    height: 100%;
372
+    position: absolute;
373
+    left: 0;
374
+    top: 0;
375
+  }
376
+
377
+  /* 暂无数据 */
378
+  .cots_body .no_data {
379
+    width: 100%;
380
+    height: 100%;
381
+    position: absolute;
382
+    left: 0;
383
+    top: 0;
384
+    font-size: 24px;
385
+    font-weight: bold;
386
+    display: flex;
387
+    justify-content: center;
388
+    align-items: center;
389
+  }
390
+
391
+  /* 未分派 */
392
+  .weifenpai .list {
393
+    height: 145px;
394
+    border-bottom: 1px solid #7D7D7D;
395
+    position: relative;
396
+    overflow: hidden;
397
+    display: flex;
398
+  }
399
+  // 转出院记录
400
+  .patientLog .list {
401
+    height: auto !important;
402
+    th,
403
+    td {
404
+      text-align: center !important;
405
+    }
406
+  }
407
+
408
+  /* 左边 */
409
+  .left_cots {
410
+    width: 100%;
411
+    float: left;
412
+    padding: 0 8px;
413
+    cursor: pointer;
414
+    position: relative;
415
+  }
416
+
417
+  /* 急标 */
418
+  .left_cots .ji {
419
+    position: absolute;
420
+    right: -3px;
421
+    top: -3px;
422
+    width: 30px;
423
+  }
424
+
425
+  /* 右边 */
426
+  .right_bots {
427
+    width: 20%;
428
+    border-left: 1px #e1e5e8 solid;
429
+    padding: 8px 0;
430
+  }
431
+
432
+  /* 上按钮 */
433
+  .right_bots .top_bot {
434
+    width: 70%;
435
+    border-radius: 4px;
436
+    color: white;
437
+    background-color: @primary-color;
438
+    border: 1px @primary-color solid;
439
+    cursor: pointer;
440
+    height: 27px;
441
+    margin-bottom: 8px;
442
+  }
443
+
444
+  .slider {
445
+    position: absolute;
446
+    // top: 98px;
447
+    bottom: 0;
448
+    right: 0;
449
+    width: 100%;
450
+    height: 2px;
451
+
452
+    &.sgreen {
453
+      background: rgb(86, 186, 182);
454
+    }
455
+
456
+    &.syellow {
457
+      background: rgb(245, 166, 35);
458
+    }
459
+    &.sred {
460
+      background: #d81e06;
461
+    }
462
+  }
463
+
464
+  /* 中按钮 */
465
+  .right_bots .mid_bot {
466
+    width: 70%;
467
+    border-radius: 4px;
468
+    color: white;
469
+    background-color: @primary-color;
470
+    border: 1px @primary-color solid;
471
+    cursor: pointer;
472
+    height: 27px;
473
+  }
474
+
475
+  /* 下按钮 */
476
+  .right_bots .btm_bot {
477
+    width: 70%;
478
+    border-radius: 4px;
479
+    color: #78797a;
480
+    background-color: #FFF;
481
+    border: 1px #e5e9ed solid;
482
+    cursor: pointer;
483
+    height: 27px;
484
+  }
485
+
486
+  /* 工单 */
487
+  .weifenpai .left_cots .gongdan {
488
+    height: 24px;
489
+    margin: 4px 0;
490
+    line-height: 24px;
491
+    text-align: center;
492
+  }
493
+
494
+  .weifenpai .left_cots .gongdan .left {
495
+    float: left;
496
+    font-size: 14px;
497
+  }
498
+  .gongdan_name {
499
+    max-width: 80% !important;
500
+    overflow: hidden !important;
501
+    text-overflow: ellipsis !important;
502
+    white-space: nowrap !important;
503
+  }
504
+
505
+  .weifenpai .left_cots .gongdan .right {
506
+    float: right;
507
+
508
+    &.colorRed {
509
+      color: red;
510
+    }
511
+  }
512
+
513
+  .weifenpai .left_cots .gongdan .right span:nth-child(1) {
514
+    float: right;
515
+    font-size: 12px;
516
+
517
+    &.colorRed {
518
+      color: red;
519
+    }
520
+  }
521
+
522
+  .weifenpai .left_cots .gongdan .right span:nth-child(2) {
523
+    float: right;
524
+    border-radius: 50%;
525
+    width: 10px;
526
+    height: 10px;
527
+    background-color: red;
528
+    margin-top: 7px;
529
+    margin-right: 8px;
530
+  }
531
+
532
+  /* 地点 */
533
+  .weifenpai .didian {
534
+    height: 24px;
535
+    line-height: 24px;
536
+    margin: 4px 0;
537
+    display: flex;
538
+  }
539
+
540
+  .weifenpai .didian .left {
541
+    float: left;
542
+    font-size: 14px;
543
+    flex: 1;
544
+    white-space: nowrap;
545
+    overflow: hidden;//文本超出隐藏
546
+    text-overflow: ellipsis;//文本超出省略号替代
547
+    &.noEllipsis{
548
+      white-space: normal;
549
+      overflow: visible;
550
+      text-overflow: inherit;
551
+      word-break: break-all;
552
+    }
553
+  }
554
+
555
+  .weifenpai .didian .right {
556
+    float: right;
557
+    flex: 1;
558
+    white-space: nowrap;
559
+    overflow: hidden;//文本超出隐藏
560
+    text-overflow: ellipsis;//文本超出省略号替代
561
+    text-align: right;
562
+  }
563
+
564
+  .weifenpai .didian .right i {
565
+    font-size: 12px;
566
+    color: @primary-color;
567
+  }
568
+
569
+  .weifenpai .didian .right span {
570
+    font-size: 12px;
571
+  }
572
+
573
+  /* 时间 */
574
+  .weifenpai .shijian {
575
+    height: 24px;
576
+    line-height: 24px;
577
+    margin: 4px 0;
578
+  }
579
+
580
+  .weifenpai .shijian .left {
581
+    float: left;
582
+  }
583
+
584
+  .weifenpai .shijian .right {
585
+    float: right;
586
+    font-size: 12px;
587
+  }
588
+
589
+  .weifenpai .shijian .left i {
590
+    color: @primary-color;
591
+    font-size: 14px;
592
+
593
+    &.colorRed {
594
+      color: red;
595
+    }
596
+  }
597
+
598
+  .weifenpai .shijian .left span {
599
+    font-size: 12px;
600
+  }
601
+}

+ 437 - 0
src/app/views/realtime-broadcast/realtime-broadcast.component.ts

@@ -0,0 +1,437 @@
1
+import { Component, OnInit, AfterViewInit } from "@angular/core";
2
+import { Validators, FormGroup, FormBuilder } from '@angular/forms';
3
+import { Subject } from 'rxjs';
4
+import { debounceTime } from 'rxjs/operators';
5
+import { MainService } from 'src/app/services/main.service';
6
+import { ToolService } from 'src/app/services/tool.service';
7
+import { NzMessageService } from 'ng-zorro-antd';
8
+import { Router } from '@angular/router';
9
+import { Swiper, Autoplay } from 'swiper';
10
+Swiper.use([Autoplay]);
11
+import chunk from 'lodash-es/chunk';
12
+
13
+@Component({
14
+  selector: "app-realtime-broadcast",
15
+  templateUrl: "./realtime-broadcast.component.html",
16
+  styleUrls: ["./realtime-broadcast.component.less"],
17
+})
18
+export class RealtimeBroadcastComponent implements OnInit,AfterViewInit {
19
+  constructor(
20
+    private fb: FormBuilder,
21
+    private mainService: MainService,
22
+    public tool: ToolService,
23
+    private message: NzMessageService,
24
+    public router: Router,
25
+  ){}
26
+  validateForm: FormGroup; //表单
27
+  isMask:boolean = false; //遮罩
28
+  changeInpSubject = new Subject(); //防抖
29
+  showDropdown:boolean = false; //下拉
30
+  loginUser: any = this.tool.getCurrentUserInfo(); //登录人信息
31
+
32
+  ngOnInit(): void {
33
+    //防抖
34
+    this.changeInpSubject.pipe(debounceTime(500)).subscribe(({type, searchText}) => {
35
+      // this.getHospitalList(type, searchText);
36
+    });
37
+    this.initForm();
38
+  }
39
+
40
+  ngAfterViewInit(){
41
+    this.computedNum();
42
+    this.getIncidentStatusList();
43
+  }
44
+
45
+  ngOnDestroy(){
46
+    clearInterval(this.timer);
47
+    this.mySwiper1pending && this.mySwiper1pending.destroy();
48
+    this.mySwiper2handler && this.mySwiper2handler.destroy();
49
+    this.mySwiper3overtime && this.mySwiper3overtime.destroy();
50
+  }
51
+
52
+  mySwiper1pending:Swiper;
53
+  mySwiper2handler:Swiper;
54
+  mySwiper3overtime:Swiper;
55
+  swiperEnter(key){
56
+    this['mySwiper' + key] && this['mySwiper' + key].autoplay.stop();
57
+  }
58
+
59
+  swiperLeave(key){
60
+    this['mySwiper' + key] && this['mySwiper' + key].autoplay.start();
61
+  }
62
+
63
+  // 轮播
64
+  startSwiper(type){
65
+    let _this = this;
66
+    this['mySwiper' + type] && this['mySwiper' + type].destroy();
67
+    setTimeout(() => {
68
+      this['mySwiper' + type] = new Swiper('#mySwiper' + type, {
69
+        autoplay: {
70
+          delay: this.config.rollingSeconds * 1000,
71
+          // stopOnLastSlide: false,
72
+          // disableOnInteraction: false,
73
+        },
74
+        observer: true, //修改swiper自己或子元素时,自动初始化swiper
75
+        observeParents: true, //修改swiper的父元素时,自动初始化swiper
76
+        allowTouchMove: false, //禁止触摸滑动
77
+        // loop: true,
78
+        // pagination: {
79
+        //   el: '.swiper-pagination',
80
+        //   clickable: true, //轮播按钮支持点击
81
+        // },
82
+        on: {
83
+          // slideChangeTransitionEnd: function(swiper) {
84
+          //   _this.activeIndex = swiper.realIndex;
85
+          // },
86
+          click: function(swiper, event){
87
+            let parentNode = (event as any).target.closest('.list');
88
+            let hasClass = parentNode !== null;
89
+            if(hasClass){
90
+              const id = parentNode.getAttribute('data-id');
91
+              if(id !== null){
92
+                _this.openItsmDetails({id});
93
+              }
94
+            }
95
+          }
96
+        },
97
+      });
98
+    }, 0)
99
+  }
100
+
101
+  // 定时器
102
+  timer = null;
103
+  num:number = 0;
104
+  startGetList(){
105
+    clearInterval(this.timer);
106
+    this.timer = setInterval(() => {
107
+      this.num--;
108
+      if(this.num < 0){
109
+        this.num = this.config.refreshSeconds;
110
+        this.refreshIncidentList();
111
+      }
112
+    }, 1000)
113
+  }
114
+
115
+  // 初始化form表单
116
+  initForm() {
117
+    this.validateForm = this.fb.group({
118
+      deptIds: [[], [Validators.required]],
119
+      groupIds: [[]],
120
+      showOvertime: [undefined, [Validators.required]],
121
+      refreshSeconds: [30, [Validators.required]],
122
+      rollingSeconds: [3, [Validators.required]],
123
+    });
124
+  }
125
+
126
+  // 展示弹窗
127
+  showConfig(isEdit = false){
128
+    this.isMask = true;
129
+    this.getHospitalType();
130
+    if(isEdit && this.config.id){
131
+      this.validateForm.controls.deptIds.setValue(this.config.deptIds.split(',').map(v => +v));
132
+      this.validateForm.controls.groupIds.setValue(this.config.groupIds ? this.config.groupIds.split(',').map(v => +v) : []);
133
+      this.config.groupList && (this.groupList = this.config.groupList);
134
+      this.validateForm.controls.showOvertime.setValue(this.config.showOvertime);
135
+      this.validateForm.controls.refreshSeconds.setValue(this.config.refreshSeconds);
136
+      this.validateForm.controls.rollingSeconds.setValue(this.config.rollingSeconds);
137
+    }
138
+  }
139
+
140
+  // 关闭遮罩
141
+  hideModal(){
142
+    this.isMask = false;
143
+  }
144
+
145
+  // 边输边搜节流阀
146
+  isLoading = false;
147
+  changeInp(type, searchText) {
148
+    this.isLoading = true;
149
+    this.changeInpSubject.next({type, searchText});
150
+  }
151
+
152
+  // 获取院区类型
153
+  hospitalTypes:any[] = [];
154
+  getHospitalType() {
155
+    this.mainService.getDictionary("list", "hospital_type").subscribe((result) => {
156
+      this.hospitalTypes = result || [];
157
+      this.getHospitalList();
158
+    });
159
+  }
160
+
161
+  // 获取维修科室
162
+  hospitalList:any[] = [];
163
+  getHospitalList() {
164
+    let type = this.hospitalTypes.find(v => v.value == 6);
165
+    let postData = {
166
+      hospital: {
167
+        type: type || undefined,
168
+      },
169
+      idx: 0,
170
+      sum: 99999,
171
+    };
172
+    this.mainService
173
+      .getFetchDataList("data", "hospital", postData)
174
+      .subscribe((result) => {
175
+        this.hospitalList = result.list || [];
176
+      });
177
+  }
178
+
179
+  // 修改维修科室
180
+  changeHospital(arr){
181
+    this.getGroupList();
182
+    this.validateForm.controls.groupIds.setValue([]);
183
+  }
184
+
185
+  // 打开运维分组
186
+  openChangeGroup(flag){
187
+    flag && this.getGroupList();
188
+  }
189
+
190
+  // 获取运维分组
191
+  groupList:any[] = [];
192
+  getGroupList() {
193
+    if(!this.validateForm.value.deptIds.length){
194
+      this.isLoading = false;
195
+      this.groupList = [];
196
+      return;
197
+    }
198
+    let postData = {
199
+      group2: {
200
+        hospitalIds: this.validateForm.value.deptIds.toString(),
201
+        typeIds: 3,
202
+      },
203
+      idx: 0,
204
+      sum: 20,
205
+    };
206
+    this.mainService
207
+      .getFetchDataList("data", "group2", postData)
208
+      .subscribe((result) => {
209
+        this.isLoading = false;
210
+        this.groupList = result.list || [];
211
+      });
212
+  }
213
+
214
+  // 根据用户查询配置
215
+  config:any = {};
216
+  getConfig() {
217
+    let postData = {
218
+      incidentViewConfig: {
219
+        userId: this.tool.getCurrentUserInfo().id,
220
+      },
221
+      idx: 0,
222
+      sum: 1,
223
+    };
224
+    this.mainService
225
+      .getFetchDataList("simple/data", "incidentViewConfig", postData)
226
+      .subscribe((res:any) => {
227
+        let result = res.list || [];
228
+        if(result.length){
229
+          this.config = result[0];
230
+          this.num = this.config.refreshSeconds;
231
+
232
+          // 初始化故障工单列表
233
+          if(this.config.showOvertime == 1){
234
+            this.incidentList['2handler'].name = '待处理(不含延期处理)';
235
+            this.incidentList['3overtime'] = {
236
+              name: '延期处理',
237
+              list: [],
238
+            }
239
+            this.getIncidentList('1pending');
240
+            this.getIncidentList('2handler');
241
+            this.getIncidentList('3overtime');
242
+          }else{
243
+            this.incidentList['2handler'].name = '待处理';
244
+            delete this.incidentList['3overtime'];
245
+            this.getIncidentList('1pending');
246
+            this.getIncidentList('2handler');
247
+          }
248
+        }else{
249
+          this.config = {};
250
+          this.showConfig();
251
+        }
252
+      });
253
+  }
254
+  // 计算可视区范围展示信息的条数
255
+  pageSize = 0;
256
+  computedNum(){
257
+    let h = (document.querySelector('.lists_box') as HTMLElement).offsetHeight;
258
+    this.pageSize = Math.floor((h / 145));
259
+  }
260
+
261
+  // 刷新故障工单列表
262
+  refreshIncidentList() {
263
+    if(this.config.showOvertime == 1){
264
+      this.getIncidentList('1pending');
265
+      this.getIncidentList('2handler');
266
+      this.getIncidentList('3overtime');
267
+    }else{
268
+      this.getIncidentList('1pending');
269
+      this.getIncidentList('2handler');
270
+    }
271
+  }
272
+
273
+  // 获取故障工单状态
274
+  incidentStatusList:any[] = [];
275
+  getIncidentStatusList() {
276
+    this.mainService.getDictionary("list", "incident_status").subscribe((result) => {
277
+      this.incidentStatusList = result || [];
278
+      this.getConfig();
279
+    });
280
+  }
281
+
282
+  // 获取故障工单列表
283
+  loading:boolean = false;
284
+  incidentList:any = {
285
+    '1pending': {
286
+      name: '待接单',
287
+      list: [],
288
+    },
289
+    '2handler': {
290
+      name: '待处理',
291
+      list: [],
292
+    },
293
+    // '3overtime': {
294
+    //   name: '延期处理',
295
+    //   list: [],
296
+    // }
297
+  }
298
+  getIncidentList(type: string) {
299
+    this.loading = true;
300
+    let postData: any = {
301
+      idx: 0,
302
+      sum: 99999,
303
+      incident: {
304
+        deleteFlag: 0,
305
+				candidateGroups: this.config.groupIds ? this.config.groupIds.toString() : undefined,
306
+				dutyIds: this.config.deptIds.toString(),
307
+        queryTask: 'queryAll',
308
+      },
309
+    };
310
+    if(type == '1pending'){
311
+      postData.incident.statusId = this.incidentStatusList.find(v => v.value === 'pending').id;
312
+    }else if(type == '2handler'){
313
+      postData.incident.statusId = this.incidentStatusList.find(v => v.value === 'handler').id;
314
+      postData.incident.overtime = this.config.showOvertime == 1 ? 0 : undefined;
315
+    }else if(type == '3overtime'){
316
+      postData.incident.statusId = this.incidentStatusList.find(v => v.value === 'handler').id;
317
+      postData.incident.overtime = 1;
318
+    }
319
+    this.mainService
320
+      .getFetchDataList("simple/data", "incident", postData)
321
+      .subscribe((res:any) => {
322
+        this.loading = false;
323
+
324
+        let list = res.list || [];
325
+        this.incidentList[type].list = chunk(list, this.pageSize);
326
+        // console.log(this.incidentList)
327
+
328
+        this.startSwiper(type);
329
+        this.startGetList();
330
+      });
331
+  }
332
+
333
+  // 优先级颜色
334
+  priorityColor(priorityId) {
335
+    // 极低|低
336
+    if(priorityId == 1 || priorityId == 2){
337
+      return '';
338
+    } else if(priorityId == 3){
339
+      return 'yellow';
340
+    } else if(priorityId == 4 || priorityId == 5){
341
+      return 'red';
342
+    }
343
+  }
344
+
345
+  // 保存
346
+  btnLoading:boolean = false;
347
+  submitForm(){
348
+    for (const i in this.validateForm.controls) {
349
+      this.validateForm.controls[i].markAsDirty({ onlySelf: true });
350
+      this.validateForm.controls[i].updateValueAndValidity();
351
+    }
352
+    if (this.validateForm.invalid) return;
353
+    this.btnLoading = true;
354
+    let postData = {
355
+      id: this.config.id || undefined,
356
+      hosId: this.tool.getCurrentHospital().id,
357
+      userId: this.tool.getCurrentUserInfo().id,
358
+      deptIds: this.validateForm.value.deptIds.toString(),
359
+      groupIds: this.validateForm.value.groupIds.toString() || undefined,
360
+      showOvertime: this.validateForm.value.showOvertime,
361
+      refreshSeconds: this.validateForm.value.refreshSeconds,
362
+      rollingSeconds: this.validateForm.value.rollingSeconds,
363
+    }
364
+    this.mainService
365
+      .simplePost("addData", "incidentViewConfig", postData)
366
+      .subscribe((data) => {
367
+        this.btnLoading = false;
368
+        this.hideModal();
369
+        if (data.status == 200) {
370
+          this.showDropdown = false;
371
+          this.message.success("保存成功");
372
+          this.getConfig();
373
+        } else {
374
+          this.message.error(data.msg || '保存失败');
375
+        }
376
+      });
377
+  }
378
+
379
+  // 详情-弹窗
380
+  detailModalShow = false; //弹窗开关
381
+  coopData:any = {};
382
+  openItsmDetails(data) {
383
+    this.coopData = data;
384
+    this.detailModalShow = true;
385
+  }
386
+  // 关闭弹窗
387
+  closeDetailModelOrder(e) {
388
+    this.detailModalShow = JSON.parse(e).show;
389
+  }
390
+  // 弹窗确定
391
+  confirmDetailModelOrder(e){
392
+    console.log(e);
393
+    this.detailModalShow = false;
394
+  }
395
+
396
+  // 回到系统管理
397
+  toMain() {
398
+    this.router.navigateByUrl("main");
399
+  }
400
+
401
+  // 退出
402
+  logOut(): void {
403
+    // 假退出
404
+    let hospital = this.tool.getCurrentHospital();
405
+    if(hospital){
406
+      this.router.navigate(["login", hospital.id]);
407
+    }else{
408
+      this.router.navigateByUrl("login");
409
+    }
410
+    localStorage.removeItem("user");
411
+    localStorage.removeItem("menu");
412
+    localStorage.removeItem("index");
413
+
414
+    // 假退出
415
+    this.mainService.logOut().subscribe((data) => {
416
+      if (data.status == 200) {
417
+        if(hospital){
418
+          this.router.navigate(["login", hospital.id]);
419
+        }else{
420
+          this.router.navigateByUrl("login");
421
+        }
422
+        localStorage.removeItem("user");
423
+        localStorage.removeItem("menu");
424
+        localStorage.removeItem("index");
425
+      }
426
+    });
427
+  }
428
+
429
+  // 处理人+协同人
430
+  transferSynergetic(incidentData){
431
+    let str = incidentData.groupORHandlerUser || "";
432
+    if(incidentData.synergetic && incidentData.synergetic.length){
433
+        str += ',' + incidentData.synergetic.map(v => v.name).join(',');
434
+    }
435
+    return str;
436
+  }
437
+}

+ 21 - 0
src/app/views/realtime-broadcast/realtime-broadcast.module.ts

@@ -0,0 +1,21 @@
1
+import { NgModule } from '@angular/core';
2
+import { CommonModule } from '@angular/common';
3
+
4
+import { RealtimeBroadcastRoutingModule } from './realtime-broadcast-routing.module';
5
+import { RealtimeBroadcastComponent } from './realtime-broadcast.component';
6
+import { ShareModule } from 'src/app/share/share.module';
7
+import { IncidentDetailModule } from 'src/app/components/incidentManagement/incident-detail/incident-detail.module';
8
+
9
+
10
+@NgModule({
11
+  declarations: [
12
+    RealtimeBroadcastComponent,
13
+  ],
14
+  imports: [
15
+    CommonModule,
16
+    RealtimeBroadcastRoutingModule,
17
+    ShareModule,
18
+    IncidentDetailModule,
19
+  ]
20
+})
21
+export class RealtimeBroadcastModule { }

+ 24 - 12
src/app/views/repository-manage/repository-manage.component.html

@@ -11,7 +11,7 @@
11 11
 				    </ng-container>
12 12
 				  </nz-select>
13 13
 				</div>
14
-				
14
+
15 15
         <div class="list-template__searchItem">
16 16
           <span class="label">标题:</span>
17 17
           <input nz-input class="formItem" [(ngModel)]="title" placeholder="请输入标题" nzSize="default" />
@@ -20,6 +20,18 @@
20 20
           <span class="label">编号:</span>
21 21
           <input nz-input class="formItem" [(ngModel)]="solutionNumber" placeholder="请输入编号" nzSize="default" />
22 22
         </div>
23
+        <div class="list-template__searchItem">
24
+          <span class="label">创建人</span>:
25
+          <nz-select class="formItem" [nzDropdownMatchSelectWidth]="false" nzServerSearch nzShowSearch
26
+            (nzOnSearch)="changeUser($event)" nzAllowClear nzPlaceHolder="请选择创建人" [(ngModel)]="createUserId">
27
+            <ng-container *ngFor="let option of createUserList">
28
+              <nz-option *ngIf="!isLoading" [nzLabel]="option.name" [nzValue]="option.id"></nz-option>
29
+            </ng-container>
30
+            <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
31
+              <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
32
+            </nz-option>
33
+          </nz-select>
34
+        </div>
23 35
       </div>
24 36
       <div nz-col nzLg="6" class="list-template__btns">
25 37
         <button class="btn default" (click)='search()'>搜索</button>
@@ -49,11 +61,11 @@
49 61
 						<td>
50 62
 							<div>V{{ data.versionNumber }}</div>
51 63
 							<div>{{ data.type ? data.type.name : '-' }}</div>
52
-						</td>	
64
+						</td>
53 65
 						<td>
54 66
 							<div>{{ data.createUser.name }}</div>
55 67
 							<div>{{ data.createTime|date:'yyyy-MM-dd HH:mm' }}</div>
56
-						</td>	
68
+						</td>
57 69
 						<td>{{ data.status ? data.status.name : '-' }}</td>
58 70
             <td>
59 71
               <div class="coop">
@@ -84,7 +96,7 @@
84 96
       <!-- <overlay-scrollbars #osComponentRef1 class="content"> -->
85 97
        <div class="view-box">
86 98
 				 <div class="view-item left-box">
87
-					 <div class="item-left-list" 
99
+					 <div class="item-left-list"
88 100
 					 [ngClass]="{'activeClass': index == vIndex}"
89 101
 					 *ngFor="let item of detailData let index=index;" (click)="versionsClick(item, index)">V{{item.versionNumber}}</div>
90 102
 				 </div>
@@ -111,7 +123,7 @@
111 123
 						 </div>
112 124
 					 </div>
113 125
 				 </div>
114
-				 <div class="view-item right-box" *ngIf="solutionLogs"> 
126
+				 <div class="view-item right-box" *ngIf="solutionLogs">
115 127
 					 <nz-steps [nzCurrent]="stepLength" nzDirection="vertical" nzSize="small">
116 128
 						<ng-container *ngFor="let item of solutionLogs; let index = index">
117 129
 						    <nz-step
@@ -148,7 +160,7 @@
148 160
 				<button class="btn" *ngIf="optType=='audit' && vIndex==0" nz-button nzType="primary" (click)="submitForm(2)" [nzLoading]="btnLoading2">驳回</button>
149 161
 				<button class="btn cancel" *ngIf="optType=='audit'" nz-button nzType="default" (click)="hideModal()">取消</button>
150 162
 				<button class="btn" *ngIf="optType=='look'" nz-button nzType="primary" (click)="hideModal()">知道了</button>
151
-				
163
+
152 164
 			</div>
153 165
 			<div class="mask-style" *ngIf="isSpinning">
154 166
 				<nz-spin nzSimple class="spin-style"></nz-spin>
@@ -158,19 +170,19 @@
158 170
   <!-- 删除模态框 -->
159 171
   <app-dialog-delete [delModal]="delModal" (hideDelModalEvent)="hideDelModal()" [btnLoading]="btnLoading"
160 172
     (confirmDelEvent)="confirmDel()" content="您确认要删除此知识库吗?"></app-dialog-delete>
161
-	
173
+
162 174
 	<!-- 停用模态框 -->
163 175
 	<app-dialog-delete [delModal]="pauseModal" (hideDelModalEvent)="hideDelModal2()" [btnLoading]="btnLoading"
164 176
 	  (confirmDelEvent)="confirmDel2()" content="您确认要停用此知识库吗?"></app-dialog-delete>
165
-		
177
+
166 178
 	<!-- 恢复模态框 -->
167 179
 	<app-dialog-delete [delModal]="renewModal" (hideDelModalEvent)="hideDelModal3()" [btnLoading]="btnLoading"
168 180
 		(confirmDelEvent)="confirmDel3()" content="您确认要恢复此知识库吗?"></app-dialog-delete>
169
-		
181
+
170 182
 	<!-- 审核通过模态框 -->
171 183
 	<app-dialog-delete [delModal]="auditModal" (hideDelModalEvent)="hideDelModal4()" [btnLoading]="btnLoading"
172 184
 		(confirmDelEvent)="confirmDel4()" content="您确认通过此知识库的审核吗?"></app-dialog-delete>
173
-	
185
+
174 186
 	<!-- 审核驳回模态框 -->
175 187
 	<nz-modal [(nzVisible)]="rejectModal" nzTitle="您确认驳回此知识库吗?" (nzOnCancel)="rejectCancel()" (nzOnOk)="rejectOk()">
176 188
 		<textarea
@@ -178,10 +190,10 @@
178 190
 			[(ngModel)]="rejectData"
179 191
 			placeholder="请输入整改意见"
180 192
 			[nzAutosize]="{ minRows: 2, maxRows: 6 }"
181
-			
193
+
182 194
 		></textarea>
183 195
 	</nz-modal>
184
-			
196
+
185 197
   <!-- 编辑模态框 -->
186 198
   <app-dialog-delete [delModal]="editModal" (hideDelModalEvent)="hideDelModal1()" [btnLoading]="saveLoading"
187 199
     (confirmDelEvent)="confirmDel1()" [content]="'保存后会重置您的发药科室的药品信息,您确认吗?'"></app-dialog-delete>

+ 44 - 2
src/app/views/repository-manage/repository-manage.component.ts

@@ -39,10 +39,15 @@ export class RepositoryManageComponent implements OnInit {
39 39
     private http: HttpClient,
40 40
 		private sanitizer: DomSanitizer
41 41
   ) {}
42
+  searchTimerSubject = new Subject();
42 43
   ngOnInit() {
43 44
     this.searchParentDeptSubject.pipe(debounceTime(500)).subscribe((e) => {
44 45
 
45 46
     });
47
+    this.searchTimerSubject.pipe(debounceTime(500)).subscribe((v) => {
48
+      let fun = v[0];
49
+      fun.call(this, v[1], v[2]);
50
+    });
46 51
 		this.hosId = this.tool.getCurrentHospital().id;
47 52
     this.coopBtns = this.tool.initCoopBtns(this.route);
48 53
 		this.maintainDept = this.tool.getUserInfoPermission().dutyList
@@ -50,7 +55,9 @@ export class RepositoryManageComponent implements OnInit {
50 55
 			this.defaDept()
51 56
 		}
52 57
 		this.getList();
58
+    this.getUsers();
53 59
   }
60
+  createUserList: any = []; //创建人列表
54 61
 	maintainDept:any = []; //维修科室
55 62
 	maintainDepartment:any;
56 63
 	hosIds:any; //当前院区
@@ -68,6 +75,7 @@ export class RepositoryManageComponent implements OnInit {
68 75
 	hosId: number;
69 76
 	loadAllConsumeDept: boolean = true;//是否加载所有消耗科室
70 77
   solutionNumber; //编号
78
+  createUserId; //创建人
71 79
 	title; //标题
72 80
   num; //编码
73 81
   deptalias; //别名
@@ -115,7 +123,7 @@ export class RepositoryManageComponent implements OnInit {
115 123
     this.coopData = data;
116 124
     this.showDelModal1();
117 125
   }
118
-	
126
+
119 127
 	// 默认科室
120 128
 	defaDept(){
121 129
 		let itemDept = this.maintainDept.find(i=>i.id == this.hosId)
@@ -123,7 +131,7 @@ export class RepositoryManageComponent implements OnInit {
123 131
 			this.maintainDepartment = itemDept.id
124 132
 		}
125 133
 	}
126
-	
134
+
127 135
   showDelModal1() {
128 136
     this.editModal = true;
129 137
   }
@@ -170,6 +178,7 @@ export class RepositoryManageComponent implements OnInit {
170 178
     this.pageIndex = 1;
171 179
 		this.solutionNumber = null;
172 180
 		this.title = null;
181
+    this.createUserId = undefined;
173 182
 		if(this.coopBtns.strideLook){
174 183
 			this.defaDept()
175 184
 		}
@@ -185,6 +194,7 @@ export class RepositoryManageComponent implements OnInit {
185 194
       solution: {
186 195
     		title:this.title,
187 196
 				solutionNumber:this.solutionNumber,
197
+        createUserId: this.createUserId || undefined,
188 198
     		hosId: this.hosId,
189 199
       },
190 200
     };
@@ -533,4 +543,36 @@ export class RepositoryManageComponent implements OnInit {
533 543
 		this.router.navigateByUrl(`/dispensingDetail/${data.id}`);
534 544
   }
535 545
 
546
+  // 人员边输边搜节流阀
547
+  changeUser(e) {
548
+    this.searchTimer(this.getUsers, e);
549
+  }
550
+
551
+  // 边输入边搜索节流阀
552
+  searchTimer(fun, e) {
553
+    this.isLoading = true;
554
+    this.searchTimerSubject.next([fun, e]);
555
+  }
556
+
557
+  // 获取创建人
558
+  isLoading:boolean = false;
559
+  getUsers(e?) {
560
+    let postData = {
561
+      user: {
562
+        name: e,
563
+        hospital: { id: this.hosId },
564
+        simpleQuery: true,
565
+      },
566
+      idx: 0,
567
+      sum: 20,
568
+    };
569
+    this.isLoading = true;
570
+    this.mainService
571
+      .getFetchDataList("data", "user", postData)
572
+      .subscribe((data) => {
573
+        this.isLoading = false;
574
+        this.createUserList = data.list;
575
+      });
576
+  }
577
+
536 578
 }

+ 6 - 3
src/app/views/users-management/users-management.component.ts

@@ -257,8 +257,9 @@ export class UsersManagementComponent implements OnInit {
257 257
     };
258 258
     let groupData = {
259 259
       group2: {
260
-        hospitals: hid,
260
+        hospitals: this.coopBtns.crossHospital ? undefined : hid,
261 261
         typeIds: '1,3',
262
+        crossHospital: this.coopBtns.crossHospital ? hid : undefined,
262 263
       },
263 264
       idx: 0,
264 265
       sum: 9999,
@@ -304,8 +305,9 @@ export class UsersManagementComponent implements OnInit {
304 305
     };
305 306
     let groupData = {
306 307
       group2: {
307
-        hospitals: id,
308
+        hospitals: this.coopBtns.crossHospital ? undefined : id,
308 309
         typeIds: '1,3',
310
+        crossHospital: this.coopBtns.crossHospital ? id : undefined,
309 311
       },
310 312
       idx: 0,
311 313
       sum: 9999,
@@ -474,8 +476,9 @@ export class UsersManagementComponent implements OnInit {
474 476
     };
475 477
     let groupData = {
476 478
       group2: {
477
-        hospitals: hid,
479
+        hospitals: this.coopBtns.crossHospital ? undefined : hid,
478 480
         typeIds: '1,3',
481
+        crossHospital: this.coopBtns.crossHospital ? hid : undefined,
479 482
       },
480 483
       idx: 0,
481 484
       sum: 9999,