소스 검색

标本打包

seimin 1 개월 전
부모
커밋
70f6c166c0
41개의 변경된 파일2947개의 추가작업 그리고 45개의 파일을 삭제
  1. 5 0
      src/app/app-routing.module.ts
  2. 166 5
      src/app/components/configurationCenter/configuration-specimen/configuration-specimen.component.html
  3. 220 24
      src/app/components/configurationCenter/configuration-specimen/configuration-specimen.component.ts
  4. 49 0
      src/app/services/main.service.ts
  5. 18 0
      src/app/share/detail-ordinary/detail-ordinary.component.html
  6. 63 0
      src/app/share/detail-ordinary/detail-ordinary.component.less
  7. 19 0
      src/app/share/order-detail/order-detail.component.html
  8. 35 0
      src/app/share/package-specimen-rule/package-specimen-rule.component.html
  9. 154 0
      src/app/share/package-specimen-rule/package-specimen-rule.component.less
  10. 70 0
      src/app/share/package-specimen-rule/package-specimen-rule.component.ts
  11. 11 0
      src/app/share/share.module.ts
  12. 93 0
      src/app/share/specimen-package-list-modal/specimen-package-list-modal.component.html
  13. 261 0
      src/app/share/specimen-package-list-modal/specimen-package-list-modal.component.less
  14. 151 0
      src/app/share/specimen-package-list-modal/specimen-package-list-modal.component.ts
  15. 56 0
      src/app/share/specimen-package-log-prompt-modal/specimen-package-log-prompt-modal.component.html
  16. 165 0
      src/app/share/specimen-package-log-prompt-modal/specimen-package-log-prompt-modal.component.less
  17. 54 0
      src/app/share/specimen-package-log-prompt-modal/specimen-package-log-prompt-modal.component.ts
  18. 17 0
      src/app/views/batch-specimen/batch-specimen-routing.module.ts
  19. 97 0
      src/app/views/batch-specimen/batch-specimen.component.html
  20. 193 0
      src/app/views/batch-specimen/batch-specimen.component.less
  21. 361 0
      src/app/views/batch-specimen/batch-specimen.component.ts
  22. 19 0
      src/app/views/batch-specimen/batch-specimen.module.ts
  23. 7 0
      src/app/views/hushijiandan/hushijiandan.component.html
  24. 6 0
      src/app/views/hushijiandan/hushijiandan.component.less
  25. 43 0
      src/app/views/hushijiandan/hushijiandan.component.ts
  26. 5 0
      src/app/views/main/main-routing.module.ts
  27. 2 1
      src/app/views/pathology-check/pathology-check.component.ts
  28. 9 7
      src/app/views/pathology/pathology.component.ts
  29. 2 1
      src/app/views/pathologyScan/pathologyScan.component.ts
  30. 17 0
      src/app/views/specimen-package/specimen-package-routing.module.ts
  31. 103 0
      src/app/views/specimen-package/specimen-package.component.html
  32. 176 0
      src/app/views/specimen-package/specimen-package.component.less
  33. 240 0
      src/app/views/specimen-package/specimen-package.component.ts
  34. 19 0
      src/app/views/specimen-package/specimen-package.module.ts
  35. 26 3
      src/assets/iconfont/demo_index.html
  36. 7 3
      src/assets/iconfont/iconfont.css
  37. 1 1
      src/assets/iconfont/iconfont.js
  38. 7 0
      src/assets/iconfont/iconfont.json
  39. BIN
      src/assets/iconfont/iconfont.ttf
  40. BIN
      src/assets/iconfont/iconfont.woff
  41. BIN
      src/assets/iconfont/iconfont.woff2

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

@@ -206,6 +206,11 @@ const routes: Routes = [
206 206
     loadChildren: () => import('./views/inspect-closed-loop-view/inspect-closed-loop-view.module').then(m => m.InspectClosedLoopViewModule),
207 207
     canActivate: [InspectClosedLoopViewGuard]
208 208
   },
209
+  // 标本打包
210
+  {
211
+    path: 'batchSpecimen',
212
+    loadChildren: () => import('./views/batch-specimen/batch-specimen.module').then(m => m.BatchSpecimenModule),
213
+  },
209 214
   // 临时路由
210 215
   {
211 216
     path: "redirect",

+ 166 - 5
src/app/components/configurationCenter/configuration-specimen/configuration-specimen.component.html

@@ -49,13 +49,13 @@
49 49
                   <nz-form-label class="label">必须扫描动态二维码</nz-form-label>
50 50
                   <nz-checkbox-group [(ngModel)]="arriveScanDynamicCode"></nz-checkbox-group>
51 51
                 </div>
52
-								
52
+
53 53
 								<!-- 输入动态数字密钥 -->
54 54
 								<div class="display_flex align-items_center mb8" *ngIf="arriveScanCode[0].checked">
55 55
 								  <nz-form-label class="label">输入动态数字密钥</nz-form-label>
56 56
 								  <nz-checkbox-group [(ngModel)]="enterDynamicDigitalKey"></nz-checkbox-group>
57 57
 								</div>
58
-								
58
+
59 59
                 <!-- 退回标本是否填写交接人 -->
60 60
                 <div class="display_flex align-items_center mb8">
61 61
                   <nz-form-label class="label">退回标本是否填写交接人</nz-form-label>
@@ -140,7 +140,7 @@
140 140
 										</ng-container>
141 141
 									</nz-select>
142 142
 								</div>
143
-								
143
+
144 144
 								<!-- 手术病理标签样式 -->
145 145
 								<div class="display_flex align-items_center mb8">
146 146
 									<nz-form-label class="label">手术病理标签样式</nz-form-label>
@@ -150,7 +150,7 @@
150 150
 										</ng-container>
151 151
 									</nz-select>
152 152
 								</div>
153
-								
153
+
154 154
 								<!-- 速冻标本数量控制 -->
155 155
 								<div class="display_flex align-items_center mb8">
156 156
 									<nz-form-label class="label">速冻标本数量控制</nz-form-label>
@@ -159,7 +159,7 @@
159 159
 										<label nz-radio [nzValue]="0">多只</label>
160 160
 									</nz-radio-group>
161 161
 								</div>
162
-								
162
+
163 163
 								<!-- 提示语 -->
164 164
 								<div class="display_flex align-items_center mb8" *ngIf="pathologyFrozenSpecimenNum==1">
165 165
 									<nz-form-label class="label">提示语</nz-form-label>
@@ -182,6 +182,167 @@
182 182
 						</div>
183 183
 					</div>
184 184
 				</div>
185
+        <div class="TaskTypeManagement" *ngIf="activeDictionaryKey=='specimenPackage'">
186
+					<div class="taskTypeInfo">
187
+            <div class="top">
188
+              <div class="item" (click)="tabModal('characteristics')" [ngClass]="{'items':tabModalName=='characteristics'}">
189
+                特性配置
190
+              </div>
191
+              <div class="item" (click)="tabModal('nursePackage')" [ngClass]="{'items':tabModalName=='nursePackage'}">
192
+                护士打包配置
193
+              </div>
194
+              <div class="item" (click)="tabModal('automaticOrderCreation')" [ngClass]="{'items':tabModalName=='automaticOrderCreation'}">
195
+                自动建单配置
196
+              </div>
197
+            </div>
198
+            <div class="list" *ngIf="!loading">
199
+              <!-- 特性配置 -->
200
+              <div *ngIf="tabModalName=='characteristics'">
201
+                <!-- 是否联合标本收取 -->
202
+                <div class="display_flex align-items_center mb8">
203
+                  <nz-form-label class="label">是否联合标本收取</nz-form-label>
204
+                  <nz-radio-group [(ngModel)]="spePackageUnionReceive">
205
+                    <label nz-radio [nzValue]="1">是</label>
206
+                    <label nz-radio [nzValue]="0">否</label>
207
+                  </nz-radio-group>
208
+                </div>
209
+                <!-- 关联任务类型 -->
210
+                <div class="display_flex align-items_center mb8">
211
+                  <nz-form-label class="label">关联任务类型</nz-form-label>
212
+                  {{tasktype.taskName}}
213
+                </div>
214
+                <!-- 工单模式 -->
215
+                <div class="display_flex align-items_center mb8">
216
+                  <nz-form-label class="label" nzRequired>工单模式</nz-form-label>
217
+                  <nz-radio-group [(ngModel)]="spePackageModel">
218
+                    <label nz-radio [nzValue]="item.value" *ngFor="let item of spePackageModelList">{{ item.label }}</label>
219
+                  </nz-radio-group>
220
+                </div>
221
+                <!-- 支持建单并签到 -->
222
+                <div class="display_flex align-items_center mb8">
223
+                  <nz-form-label class="label">支持建单并签到</nz-form-label>
224
+                  <nz-checkbox-group [(ngModel)]="drugsCreateSign"></nz-checkbox-group>
225
+                </div>
226
+                <!-- 支持接单并签到 -->
227
+                <div class="display_flex align-items_center mb8">
228
+                  <nz-form-label class="label">支持接单并签到</nz-form-label>
229
+                  <nz-checkbox-group [(ngModel)]="drugsReceiveSign"></nz-checkbox-group>
230
+                </div>
231
+
232
+                <!-- 起点科室支持核对 -->
233
+                <div class="display_flex align-items_center mb8">
234
+                  <nz-form-label class="label">起点科室支持核对</nz-form-label>
235
+                  <nz-checkbox-group [(ngModel)]="drugsStartCheck" (ngModelChange)="changeDrugsStartCheck($event)"></nz-checkbox-group>
236
+                </div>
237
+                <ng-container *ngIf="drugsStartCheck[0].checked">
238
+                  <!-- 核对方式 -->
239
+                  <div class="display_flex align-items_center mb8">
240
+                    <nz-form-label class="label" nzRequired>核对方式</nz-form-label>
241
+                    <nz-checkbox-group [(ngModel)]="drugsStartCheckScanIds"></nz-checkbox-group>
242
+                  </div>
243
+                  <!-- 手动填写 -->
244
+                  <div class="display_flex align-items_center mb8">
245
+                    <nz-form-label class="label">手动填写</nz-form-label>
246
+                    <nz-select class="w320px" nzPlaceHolder="请选择手动填写" [(ngModel)]="drugsStartManual" nzAllowClear>
247
+                      <nz-option *ngFor="let item of drugsManualList" [nzLabel]="item.label" [nzValue]="item.value"></nz-option>
248
+                    </nz-select>
249
+                  </div>
250
+                </ng-container>
251
+
252
+                <!-- 终点科室支持核对 -->
253
+                <div class="display_flex align-items_center mb8">
254
+                  <nz-form-label class="label">终点科室支持核对</nz-form-label>
255
+                  <nz-checkbox-group [nzDisabled]="true" [(ngModel)]="drugsEndCheck" (ngModelChange)="changeDrugsEndCheck($event)"></nz-checkbox-group>
256
+                </div>
257
+                <ng-container *ngIf="drugsEndCheck[0].checked">
258
+                  <!-- 核对方式 -->
259
+                  <div class="display_flex align-items_center mb8">
260
+                    <nz-form-label class="label" nzRequired>核对方式</nz-form-label>
261
+                    <nz-checkbox-group [(ngModel)]="drugsEndCheckScanIds"></nz-checkbox-group>
262
+                  </div>
263
+                  <!-- 手动填写 -->
264
+                  <div class="display_flex align-items_center mb8">
265
+                    <nz-form-label class="label">手动填写</nz-form-label>
266
+                    <nz-select class="w320px" nzPlaceHolder="请选择手动填写" [(ngModel)]="drugsEndManual" nzAllowClear>
267
+                      <nz-option *ngFor="let item of drugsManualList" [nzLabel]="item.label" [nzValue]="item.value"></nz-option>
268
+                    </nz-select>
269
+                  </div>
270
+                </ng-container>
271
+              </div>
272
+              <!-- 护士打包配置 -->
273
+              <div *ngIf="tabModalName=='nursePackage'">
274
+                <!-- 是否自动打包 -->
275
+                <div class="display_flex align-items_center mb8">
276
+                  <nz-form-label class="label">自动打包</nz-form-label>
277
+                  <nz-checkbox-group [(ngModel)]="spePackageAutoPack" (ngModelChange)="changeSpePackageAutoPack($event)"></nz-checkbox-group>
278
+                </div>
279
+
280
+                <ng-container *ngIf="spePackageAutoPack[0].checked">
281
+                  <!-- 自动关联普标急标 -->
282
+                  <div class="display_flex align-items_center mb8">
283
+                    <nz-form-label class="label">自动关联普标急标</nz-form-label>
284
+                    <nz-checkbox-group [(ngModel)]="spePackageUrgents"></nz-checkbox-group>
285
+                  </div>
286
+                  <!-- 自动关联科室 -->
287
+                  <div class="display_flex align-items_center mb8">
288
+                    <nz-form-label class="label">自动关联科室</nz-form-label>
289
+                    <nz-select nzMode="multiple" style="width: 500px;" [nzDropdownMatchSelectWidth]="false" nzServerSearch nzShowSearch nzAllowClear
290
+                    (nzOnSearch)="changeDept($event)" nzPlaceHolder="请选择自动关联科室" [(ngModel)]="spePackageDeptIds" (nzOpenChange)="openDeptList($event)">
291
+                      <ng-container *ngFor="let option of deptList">
292
+                        <nz-option *ngIf="!isLoading" [nzLabel]="option.dept" [nzValue]="option.id"></nz-option>
293
+                      </ng-container>
294
+                      <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
295
+                        <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
296
+                      </nz-option>
297
+                    </nz-select>
298
+                  </div>
299
+                  <!-- 自动关联试管类型 -->
300
+                  <div class="display_flex align-items_center mb8">
301
+                    <nz-form-label class="label">自动关联试管类型</nz-form-label>
302
+                    <nz-select nzMode="multiple" style="width: 500px;" nzPlaceHolder="请选择自动关联试管类型" [(ngModel)]="spePackageTubeIds" nzAllowClear>
303
+                      <nz-option *ngFor="let item of spePackageTubeList" [nzLabel]="item.label" [nzValue]="item.value"></nz-option>
304
+                    </nz-select>
305
+                  </div>
306
+                </ng-container>
307
+
308
+                <!-- 清点方式 -->
309
+                <div class="display_flex align-items_center mb8">
310
+                  <nz-form-label class="label">清点方式</nz-form-label>
311
+                  <nz-checkbox-group [(ngModel)]="spePackageInventoryTypes"></nz-checkbox-group>
312
+                </div>
313
+
314
+                <!-- 是否生成配送工单 -->
315
+                <div class="display_flex align-items_center mb8">
316
+                  <nz-form-label class="label">生成配送工单</nz-form-label>
317
+                  <nz-checkbox-group [(ngModel)]="spePackageCreateOrder"></nz-checkbox-group>
318
+                </div>
319
+
320
+                <!-- 条码打印尺寸 -->
321
+                <div class="display_flex align-items_center mb8">
322
+                  <nz-form-label class="label">条码打印尺寸</nz-form-label>
323
+                  <nz-select class="w320px" nzPlaceHolder="请选择条码打印尺寸" [(ngModel)]="spePackageCodeSize" nzAllowClear>
324
+                    <nz-option nzLabel="80*80" [nzValue]="1"></nz-option>
325
+                  </nz-select>
326
+                </div>
327
+              </div>
328
+              <!-- 自动建单配置 -->
329
+              <div *ngIf="tabModalName=='automaticOrderCreation'">
330
+                <!-- 自动建单 -->
331
+              </div>
332
+              <div class="bottom">
333
+                <button class="login-form-button" nzType="primary" [nzLoading]="btnLoading" nz-button (click)="submitSpecimenPackageForm()">保存</button>
334
+              </div>
335
+            </div>
336
+            <div class="list" *ngIf="loading">
337
+              <div class="loadingFull display_flex justify-content_flex-center align-items_center">
338
+                <div class="loadingFullInner">
339
+                  <img src="../../../assets/images/loading.gif" alt="">
340
+                  <div>加载中...</div>
341
+                </div>
342
+              </div>
343
+            </div>
344
+          </div>
345
+				</div>
185 346
       </div>
186 347
     </div>
187 348
   </div>

+ 220 - 24
src/app/components/configurationCenter/configuration-specimen/configuration-specimen.component.ts

@@ -2,7 +2,7 @@ import { Component, OnInit } from "@angular/core";
2 2
 import { MainService } from "../../../services/main.service";
3 3
 import { ToolService } from 'src/app/services/tool.service';
4 4
 import { NzMessageService } from 'ng-zorro-antd';
5
-import { Subject } from 'rxjs';
5
+import { Subject, forkJoin } from 'rxjs';
6 6
 import { debounceTime } from 'rxjs/operators';
7 7
 
8 8
 @Component({
@@ -15,7 +15,7 @@ export class ConfigurationSpecimenComponent implements OnInit {
15 15
   btnLoading:boolean = false; //提交按钮的loading
16 16
   tabModalName:string = 'characteristics'; //当前选中的tab
17 17
   hosId = this.tool.getCurrentHospital().id; //当前院区
18
-	
18
+
19 19
 	// tab类型
20 20
 	dictionaryKeyList:any[] = [
21 21
 		{
@@ -23,14 +23,43 @@ export class ConfigurationSpecimenComponent implements OnInit {
23 23
 		},
24 24
 		{
25 25
 			name:'病理标本',key:'pathology'
26
-		}
26
+		},
27
+    {
28
+      name:'标本打包',key:'specimenPackage'
29
+    }
27 30
 	];
28
-	
31
+
32
+  spePackageUnionReceive:any = undefined;//是否联合标本收取
33
+  spePackageModel:any = undefined;//工单模式
34
+  drugsCreateSign:any = [{ label:'是否开启', value: 0 }];//支持建单并签到
35
+  drugsReceiveSign:any = [{ label:'是否开启', value: 0 }];//支持接单并签到
36
+  drugsStartCheck:any = [{ label:'是否开启', value: 0 }];//起点科室支持核对
37
+  drugsStartCheckScanIds:any = [];//起点核对方式
38
+  drugsStartManual:any = undefined;//起点科室手动填写
39
+  drugsEndCheck:any = [{ label:'是否开启', value: 1 }];//终点科室支持核对
40
+  drugsEndCheckScanIds:any = [];//终点核对方式
41
+  drugsEndManual:any = undefined;//终点科室手动填写
42
+  spePackageAutoPack:any = [{ label:'是否开启', value: 0 }];//自动打包
43
+  spePackageUrgents:any[] = [{label: '急标', value: 1}, {label: '普标', value: 0}];//自动关联急标普标急标
44
+  spePackageTubeIds:any[] = [];// 自动关联试管类型
45
+  spePackageTubeList:any[] = [];// 自动关联试管类型列表
46
+  spePackageInventoryTypes:any[] = [{label: '患者', value: 1, disabled: true, checked: true}, {label: '试管', value: 2}];//清点方式
47
+  spePackageCreateOrder:any = [{ label:'是否开启', value: 0 }];//生成配送工单
48
+  spePackageCodeSize:any = undefined;//条码打印尺寸
49
+
50
+  // 工单模式
51
+  spePackageModelList:any[] = [
52
+    { label: '一单一包', value: 1 },
53
+  ];
54
+
55
+  // 手动填写
56
+  drugsManualList:any[] = [];
57
+
29 58
 	// 是否支持根据手术新建申请单
30 59
 	autoCreate:any[] = [
31 60
 	  {label:'是否开启',value: 0}
32 61
 	];
33
-	
62
+
34 63
 	// 是否是否支持门诊新增申请单
35 64
 	outpatientCreatePathologyForm:any[] = [
36 65
 	  {label:'是否开启',value: 0}
@@ -41,7 +70,7 @@ export class ConfigurationSpecimenComponent implements OnInit {
41 70
 	outpatientInVitroFixation:any[] = [
42 71
 	  {label:'是否开启',value: 0}
43 72
 	];
44
-	
73
+
45 74
   // 扫描时指定科室不提醒勾选项
46 75
   deptNotAlert:any[] = [
47 76
     {label:'是否开启',value: 0}
@@ -56,12 +85,12 @@ export class ConfigurationSpecimenComponent implements OnInit {
56 85
   arriveScanDynamicCode:any[] = [
57 86
     {label:'是否开启',value: 0}
58 87
   ];
59
-	
88
+
60 89
 	// 必须扫描动态二维码
61 90
 	enterDynamicDigitalKey:any[] = [
62 91
 	  {label:'是否开启',value: 0}
63 92
 	];
64
-	
93
+
65 94
   // 退回标本是否填写交接人
66 95
   returnSpecimenWhetherHandover:any[] = [
67 96
     {label:'是否开启',value: 0}
@@ -86,16 +115,16 @@ export class ConfigurationSpecimenComponent implements OnInit {
86 115
   defaultScanSpe:any[] = [
87 116
     {label:'是否开启',value: 0}
88 117
   ];
89
-	
118
+
90 119
 	// 速冻标本数量控制
91 120
 	pathologyFrozenSpecimenNum:any = '0';
92
-	
121
+
93 122
 	// 提示语
94 123
 	prompt:any;
95
-	
124
+
96 125
 	//申请单条码设置
97 126
 	pathologyBarCode:any;
98
-	
127
+
99 128
   // 配置
100 129
   configs:any = {};
101 130
   // 任务类型
@@ -112,20 +141,40 @@ export class ConfigurationSpecimenComponent implements OnInit {
112 141
     this.getDeptList();
113 142
     this.getTaskType();
114 143
   }
115
-	
144
+
116 145
 	// 点击数据字典key
117 146
 	activeDictionaryKey:any = 'examine';
118 147
 	clickDictionaryKey(item){
119 148
 	  this.activeDictionaryKey = item.key;
149
+    this.tabModal('characteristics');
120 150
 		if(item.key=='examine'){
121 151
 			this.getDeptList();
122 152
 			this.getTaskType();
123
-		}else{
153
+		}else if(item.key=='pathology'){
124 154
 			this.getLabelDic()
125 155
 			this.getTaskTypesId()
156
+		}else if(item.key=='specimenPackage'){
157
+      this.getDeptList();
158
+      this.loading = true;
159
+      let drugs_bag_check_scan_type$ = this.mainService.getDictionary('list', 'drugs_bag_check_scan_type', true);
160
+      let drugs_bag_manual_type$ = this.mainService.getDictionary('list', 'drugs_bag_manual_type', true);
161
+      let specimen_tube_type$ = this.mainService.getDictionary('list', 'specimen_tube_type', true);
162
+      forkJoin(drugs_bag_check_scan_type$, drugs_bag_manual_type$, specimen_tube_type$).subscribe((data:any[]) => {
163
+        let drugs_bag_check_scan_type = data[0] || [];
164
+        let drugs_bag_manual_type = data[1] || [];
165
+        let specimen_tube_type = data[2] || [];
166
+
167
+        this.drugsStartCheckScanIds = drugs_bag_check_scan_type.map(v => ({ label:v.name, value: v.id }));
168
+        this.drugsEndCheckScanIds = drugs_bag_check_scan_type.map(v => ({ label:v.name, value: v.id }));
169
+        this.drugsManualList = drugs_bag_manual_type.map(v => ({ label:v.name, value: v.id }));
170
+
171
+        this.spePackageTubeList = specimen_tube_type.map(v => ({ label:v.name, value: v.id }));
172
+
173
+        this.getTaskTypeByOrdinary('specimenPackage')
174
+      })
126 175
 		}
127 176
 	}
128
-	
177
+
129 178
   // 扫描时指定科室不提醒勾选项
130 179
   changeDeptNotAlert(e){
131 180
     console.log(e);
@@ -144,6 +193,7 @@ export class ConfigurationSpecimenComponent implements OnInit {
144 193
   // 用户输入搜索
145 194
   isLoading: boolean = false;
146 195
   deptNotAlertIds:any[] = [];
196
+  spePackageDeptIds:any[] = [];
147 197
   deptList:any[] = [];
148 198
   changeDept(e) {
149 199
     this.searchTimer(this.getDeptList, e);
@@ -183,7 +233,7 @@ export class ConfigurationSpecimenComponent implements OnInit {
183 233
   tabModal(tabModalName:string){
184 234
     this.tabModalName = tabModalName;
185 235
   }
186
-	
236
+
187 237
 	//病理标本保存
188 238
 	submitPathologyForm(){
189 239
 		let postData:any = {
@@ -201,7 +251,7 @@ export class ConfigurationSpecimenComponent implements OnInit {
201 251
 			},
202 252
 			surgeryPathologyLabelSize:{
203 253
 				id:this.surgeryPathologyLabelSize
204
-			}, 
254
+			},
205 255
 		};
206 256
 		this.btnLoading = true;
207 257
 		this.mainService
@@ -213,7 +263,7 @@ export class ConfigurationSpecimenComponent implements OnInit {
213 263
 		    }
214 264
 		  });
215 265
 	}
216
-	
266
+
217 267
   // 检查标本保存
218 268
   submitForm() {
219 269
     if(!this.tasktype.id){
@@ -249,7 +299,61 @@ export class ConfigurationSpecimenComponent implements OnInit {
249 299
         }
250 300
       });
251 301
   }
252
-	
302
+
303
+  // 标本打包保存
304
+  submitSpecimenPackageForm() {
305
+    if(!this.tasktype.id){
306
+      this.msg.create("warning", "请先配置关联任务类型!");
307
+      return;
308
+    }
309
+    if(!this.spePackageModel){
310
+      this.msg.create("warning", "请选择工单模式!");
311
+      return;
312
+    }
313
+
314
+    if(this.drugsStartCheck[0].checked && !this.drugsStartCheckScanIds.filter(v => v.checked).length){
315
+      this.msg.create("warning", "请选择起点科室的核对方式!");
316
+      return;
317
+    }
318
+
319
+    if(this.drugsEndCheck[0].checked && !this.drugsEndCheckScanIds.filter(v => v.checked).length){
320
+      this.msg.create("warning", "请选择终点科室的核对方式!");
321
+      return;
322
+    }
323
+
324
+    let postData:any = {
325
+      id: this.configs.id,
326
+      taskType: this.tasktype.id,
327
+      hosId: this.hosId,
328
+      spePackageUnionReceive: this.spePackageUnionReceive,
329
+      spePackageModel: this.spePackageModel || undefined,
330
+      drugsCreateSign: this.drugsCreateSign[0].checked ? 1 : 0,
331
+      drugsReceiveSign: this.drugsReceiveSign[0].checked ? 1 : 0,
332
+      drugsStartCheck: this.drugsStartCheck[0].checked ? 1 : 0,
333
+      drugsStartCheckScanIds: this.drugsStartCheckScanIds.filter(v => v.checked).map(v => v.value).toString() || undefined,
334
+      drugsStartManual: this.drugsStartManual ? { id: this.drugsStartManual } : undefined,
335
+      drugsEndCheck: this.drugsEndCheck[0].checked ? 1 : 0,
336
+      drugsEndCheckScanIds: this.drugsEndCheckScanIds.filter(v => v.checked).map(v => v.value).toString() || undefined,
337
+      drugsEndManual: this.drugsEndManual ? { id: this.drugsEndManual } : undefined,
338
+      spePackageAutoPack: this.spePackageAutoPack[0].checked ? 1 : 0,
339
+      spePackageUrgents: this.spePackageUrgents.filter(v => v.checked).map(v => v.value).toString() || undefined,
340
+      spePackageDeptIds: this.spePackageDeptIds.length ? this.spePackageDeptIds.toString() : undefined,
341
+      spePackageTubeIds: this.spePackageTubeIds.length ? this.spePackageTubeIds.toString() : undefined,
342
+      spePackageInventoryTypes: this.spePackageInventoryTypes.filter(v => v.checked).map(v => v.value).toString() || undefined,
343
+      spePackageCreateOrder: this.spePackageCreateOrder[0].checked ? 1 : 0,
344
+      spePackageCodeSize: this.spePackageCodeSize || undefined,
345
+    };
346
+    this.btnLoading = true;
347
+    this.mainService
348
+      .simplePost("addData", "taskTypeConfig", postData)
349
+      .subscribe((result) => {
350
+        this.btnLoading = false;
351
+        if (result.status == 200) {
352
+          this.getConfig();
353
+        }
354
+      });
355
+  }
356
+
253 357
 	// 获取标本字典
254 358
 	labelData:any = [];
255 359
 	getLabelDic(){
@@ -257,7 +361,7 @@ export class ConfigurationSpecimenComponent implements OnInit {
257 361
 			this.labelData = data
258 362
 		});
259 363
 	}
260
-	
364
+
261 365
 	// 获取任务类型(病理标本)
262 366
 	taskTypeData:any;
263 367
 	getTaskTypesId() {
@@ -266,7 +370,7 @@ export class ConfigurationSpecimenComponent implements OnInit {
266 370
 			this.getConfig();
267 371
 		});
268 372
 	}
269
-	
373
+
270 374
   //获取任务类型
271 375
   getTaskType() {
272 376
     this.loading = true;
@@ -295,6 +399,34 @@ export class ConfigurationSpecimenComponent implements OnInit {
295 399
       });
296 400
   }
297 401
 
402
+  //获取任务类型
403
+  getTaskTypeByOrdinary(key) {
404
+    this.loading = true;
405
+    let postData = {
406
+      idx: 0,
407
+      sum: 10,
408
+      taskType: {
409
+        simpleQuery: true,
410
+        hosId: {
411
+          id: this.hosId
412
+        },
413
+        ordinaryField: {
414
+          key:"ordinary_field",
415
+          value: key
416
+        }
417
+      }
418
+    };
419
+    this.mainService
420
+      .getFetchDataList("simple/data", "taskType", postData)
421
+      .subscribe((result) => {
422
+        this.loading = false;
423
+        if (result.status == 200) {
424
+          this.tasktype = result.list[0] || {};
425
+          this.getConfig();
426
+        }
427
+      });
428
+  }
429
+
298 430
   // 获取配置
299 431
   getConfig() {
300 432
     this.loading = true;
@@ -312,7 +444,7 @@ export class ConfigurationSpecimenComponent implements OnInit {
312 444
 			    }
313 445
 			  }
314 446
 			};
315
-		}else{
447
+		}else if(this.activeDictionaryKey=='pathology'){
316 448
 			postData = {
317 449
 			  idx: 0,
318 450
 			  sum: 10,
@@ -321,8 +453,21 @@ export class ConfigurationSpecimenComponent implements OnInit {
321 453
 					taskType:this.taskTypeData.id
322 454
 			  }
323 455
 			};
456
+		}else if(this.activeDictionaryKey=='specimenPackage'){
457
+			postData = {
458
+			  idx: 0,
459
+			  sum: 10,
460
+			  taskTypeConfig: {
461
+			    taskTypeDTO: {
462
+			      hosId: {
463
+			        id: this.hosId
464
+			      },
465
+			      ordinaryField: this.tasktype.ordinaryField
466
+			    }
467
+			  }
468
+			};
324 469
 		}
325
-    
470
+
326 471
     this.mainService
327 472
       .getFetchDataList("simple/data", "taskTypeConfig", postData)
328 473
       .subscribe((result) => {
@@ -342,7 +487,7 @@ export class ConfigurationSpecimenComponent implements OnInit {
342 487
 						this.defaultScanSpe[0].checked = this.configs.defaultScanSpe == 1;
343 488
 						this.deptNotAlertIds = this.configs.deptNotAlertIds ? this.configs.deptNotAlertIds.split(',').map(v => +v) : [];
344 489
 						this.deptList = this.configs.deptNotAlertList || [];
345
-					}else{
490
+					}else if(this.activeDictionaryKey=='pathology'){
346 491
 						// 病理标本
347 492
 						this.autoCreate[0].checked = this.configs.autoCreate == 1;
348 493
 						this.outpatientCreatePathologyForm[0].checked = this.configs.outpatientCreatePathologyForm == 1;
@@ -352,8 +497,59 @@ export class ConfigurationSpecimenComponent implements OnInit {
352 497
 						this.prompt = this.configs.prompt || '';
353 498
 						this.outpatientPathologyLabelSize = this.configs.outpatientPathologyLabelSize.id; //门诊病理标签样式
354 499
 						this.surgeryPathologyLabelSize = this.configs.surgeryPathologyLabelSize.id //手术病理标签样式
500
+					}else if(this.activeDictionaryKey=='specimenPackage'){
501
+						// 标本打包
502
+						this.spePackageUnionReceive = this.configs.spePackageUnionReceive || 0;
503
+						this.spePackageModel = this.configs.spePackageModel || undefined;
504
+            this.drugsCreateSign[0].checked = this.configs.drugsCreateSign == 1;
505
+            this.drugsReceiveSign[0].checked = this.configs.drugsReceiveSign == 1;
506
+
507
+            this.drugsStartCheck[0].checked = this.configs.drugsStartCheck == 1;
508
+            this.drugsStartCheckScanIds = this.drugsStartCheckScanIds.map(v => ({...v, checked: (this.configs.drugsStartCheckScanIds || '').split(',').includes(v.value.toString())}));
509
+            this.drugsStartManual = this.configs.drugsStartManual ? this.configs.drugsStartManual.id : undefined;
510
+
511
+            this.drugsEndCheck[0].checked = true;
512
+            this.drugsEndCheckScanIds = this.drugsEndCheckScanIds.map(v => ({...v, checked: (this.configs.drugsEndCheckScanIds || '').split(',').includes(v.value.toString())}));
513
+            this.drugsEndManual = this.configs.drugsEndManual ? this.configs.drugsEndManual.id : undefined;
514
+
515
+            this.spePackageAutoPack[0].checked = true;
516
+            this.spePackageUrgents = this.spePackageUrgents.map(v => ({...v, checked: (this.configs.spePackageUrgents || '').split(',').includes(v.value.toString())}));
517
+            this.spePackageDeptIds = this.configs.spePackageDeptIds ? this.configs.spePackageDeptIds.split(',').map(v => +v) : [];
518
+            this.deptList = this.configs.spePackageDeptList || [];
519
+            this.spePackageTubeIds = this.configs.spePackageTubeIds ? this.configs.spePackageTubeIds.split(',').map(v => +v) : [];
520
+            this.spePackageInventoryTypes = this.spePackageInventoryTypes.map(v => ({...v, checked: (this.configs.spePackageInventoryTypes || '').split(',').includes(v.value.toString())}));
521
+            this.spePackageCreateOrder[0].checked = true;
522
+            this.spePackageCodeSize = this.configs.spePackageCodeSize || undefined;
355 523
 					}
356 524
         }
357 525
       });
358 526
   }
527
+
528
+  // 修改起点科室支持核对
529
+  changeDrugsStartCheck(e){
530
+    console.log(e);
531
+    if(!e[0].checked){
532
+      this.drugsStartCheckScanIds = this.drugsStartCheckScanIds.map(v => ({...v, checked: false}));
533
+      this.drugsStartManual = undefined;
534
+    }
535
+  }
536
+
537
+  // 修改终点科室支持核对
538
+  changeDrugsEndCheck(e){
539
+    console.log(e);
540
+    if(!e[0].checked){
541
+      this.drugsEndCheckScanIds = this.drugsEndCheckScanIds.map(v => ({...v, checked: false}));
542
+      this.drugsEndManual = undefined;
543
+    }
544
+  }
545
+
546
+  // 修改自动打包
547
+  changeSpePackageAutoPack(e){
548
+    console.log(e);
549
+    if(!e[0].checked){
550
+      this.spePackageUrgents = this.spePackageUrgents.map(v => ({...v, checked: false}));
551
+      this.spePackageDeptIds = [];
552
+      this.spePackageTubeIds = [];
553
+    }
554
+  }
359 555
 }

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

@@ -1162,4 +1162,53 @@ export class MainService {
1162 1162
 		});
1163 1163
 	}
1164 1164
 
1165
+  // 标本打包-获取患者、试管类型列表、标本总数
1166
+	querySaveSpePackage(data = {}){
1167
+		return this.http.post(host.host + `/nurse/specimen/querySaveSpePackage`, data, {
1168
+		  headers: this.headers,
1169
+		});
1170
+	}
1171
+
1172
+  // 标本打包-新增标本
1173
+	addPackageSpe(data = {}){
1174
+		return this.http.post(host.host + `/nurse/specimen/addPackageSpe`, data, {
1175
+		  headers: this.headers,
1176
+		});
1177
+	}
1178
+
1179
+  // 标本打包-移除标本
1180
+	removePackageSpe(data = {}){
1181
+		return this.http.post(host.host + `/nurse/specimen/removePackageSpe`, data, {
1182
+		  headers: this.headers,
1183
+		});
1184
+	}
1185
+
1186
+  // 标本打包-重置
1187
+	resetPackageSpe(data = {}){
1188
+		return this.http.post(host.host + `/nurse/specimen/resetPackageSpe`, data, {
1189
+		  headers: this.headers,
1190
+		});
1191
+	}
1192
+
1193
+  // 标本打包-建单
1194
+	createOrTakeOrderSpecimen(data = {}){
1195
+		return this.http.post(host.host + `/transflow/createOrTakeOrder`, data, {
1196
+		  headers: this.headers,
1197
+		});
1198
+	}
1199
+
1200
+  // 标本打包-打印
1201
+	makeQrCode(data = {}, code){
1202
+		return this.http.post(host.host + `/workerOrder/makeQrCode/specimenPackage/${code}`, data, {
1203
+		  headers: this.headers,
1204
+		});
1205
+	}
1206
+
1207
+  // 护士端-标本打包图标下两个数字
1208
+	getSpePackageCount(data = {}){
1209
+		return this.http.post(host.host + `/nurse/specimen/getSpePackageCount`, data, {
1210
+		  headers: this.headers,
1211
+		});
1212
+	}
1213
+
1165 1214
 }

+ 18 - 0
src/app/share/detail-ordinary/detail-ordinary.component.html

@@ -71,6 +71,24 @@
71 71
           </div> -->
72 72
         </div>
73 73
 
74
+        <!-- 标本打包 -->
75
+        <div class="info" *ngIf="orderInfo.taskType.ordinaryField.value == 'specimenPackage'">
76
+          <div nz-row class="top">
77
+            <div class="left" nz-col nzSpan="12">
78
+              <p>
79
+                <span class="label">打包码</span>
80
+                <span>{{orderInfo.pathologyPackInfoDTO?.packCode}}</span>
81
+              </p>
82
+            </div>
83
+            <div class="right" nz-col nzSpan="12">
84
+              <p>
85
+                <span class="label">标本数量</span>
86
+                <span>{{orderInfo.pathologyPackInfoDTO?.specimenNum}}</span>
87
+              </p>
88
+            </div>
89
+          </div>
90
+        </div>
91
+
74 92
         <!-- <div class="table">
75 93
           <nz-table class="detailSampleTable" [nzData]="orderInfo.specimenSet" nzSize="small" [nzShowPagination]="null">
76 94
             <thead>

+ 63 - 0
src/app/share/detail-ordinary/detail-ordinary.component.less

@@ -174,6 +174,69 @@
174 174
           }
175 175
         }
176 176
       }
177
+
178
+      .info {
179
+        width: 100%;
180
+        height: 100%;
181
+        background: #fff;
182
+        border-radius: 5px;
183
+        border: 1px solid #e5e9ed;
184
+        padding: 24px 28px 14px 28px;
185
+        margin-bottom: 8px;
186
+
187
+        .top {
188
+          .left {
189
+            border-right: 1px dashed #e5e9ed;
190
+
191
+            p {
192
+              padding: 0 70px 0 102px;
193
+              overflow: hidden;
194
+
195
+              & > span:nth-child(1) {
196
+                float: left;
197
+              }
198
+
199
+              & > span:nth-child(2) {
200
+                float: right;
201
+                color: #666;
202
+                text-align: right;
203
+                max-width: 175px;
204
+              }
205
+            }
206
+          }
207
+
208
+          .right {
209
+            p {
210
+              padding: 0 102px 0 70px;
211
+              overflow: hidden;
212
+
213
+              span:nth-child(1) {
214
+                float: left;
215
+              }
216
+
217
+              span:nth-child(2) {
218
+                float: right;
219
+                color: #666;
220
+                text-align: right;
221
+              }
222
+            }
223
+          }
224
+        }
225
+
226
+        .wait {
227
+          text-align: center;
228
+          margin-top: 7px;
229
+
230
+          i {
231
+            font-size: 24px;
232
+            color: #62c26d;
233
+          }
234
+
235
+          span {
236
+            color: #62c26d;
237
+          }
238
+        }
239
+      }
177 240
     }
178 241
   }
179 242
 

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

@@ -981,6 +981,25 @@
981 981
           </div>
982 982
         </div>
983 983
       </div>
984
+      <!-- 标本打包 -->
985
+      <div class="bottom">
986
+        <div class="info" *ngIf="orderInfo.taskType.ordinaryField.value == 'specimenPackage'">
987
+            <div nz-row class="top">
988
+              <div class="left" nz-col nzSpan="12">
989
+                <p>
990
+                  <span class="label">打包码</span>
991
+                  <span>{{orderInfo.pathologyPackInfoDTO?.packCode}}</span>
992
+                </p>
993
+              </div>
994
+              <div class="right" nz-col nzSpan="12">
995
+                <p>
996
+                  <span class="label">标本数量</span>
997
+                  <span>{{orderInfo.pathologyPackInfoDTO?.specimenNum}}</span>
998
+                </p>
999
+              </div>
1000
+            </div>
1001
+          </div>
1002
+      </div>
984 1003
     </div>
985 1004
     </overlay-scrollbars>
986 1005
     <!-- 评价内容 -->

+ 35 - 0
src/app/share/package-specimen-rule/package-specimen-rule.component.html

@@ -0,0 +1,35 @@
1
+<div class="save add display_flex align-items_center justify-content_flex-center">
2
+  <div class="modalBody">
3
+    <div class="title">自动清点规则<i class="icon_transport transport-guanbi" (click)="hideModal()"></i>
4
+    </div>
5
+    <div class="content">
6
+      <div class="block">
7
+        <div class="name">标本紧急度:</div>
8
+        <div class="value">
9
+          <ng-container *ngFor="let item of configs.spePackageUrgentsList;let last = last">
10
+            {{item.name}}<ng-container *ngIf="!last">、</ng-container>
11
+          </ng-container>
12
+        </div>
13
+      </div>
14
+      <div class="block">
15
+        <div class="name">关联检验科室:</div>
16
+        <div class="value">
17
+          <ng-container *ngFor="let item of configs.spePackageDeptList;let last = last">
18
+            {{item.dept}}<br *ngIf="!last">
19
+          </ng-container>
20
+        </div>
21
+      </div>
22
+      <div class="block">
23
+        <div class="name">关联试管类型:</div>
24
+        <div class="value">
25
+          <ng-container *ngFor="let item of configs.spePackageTubeList;let last = last">
26
+            {{item.name}}<ng-container *ngIf="!last">、</ng-container>
27
+          </ng-container>
28
+        </div>
29
+      </div>
30
+    </div>
31
+    <div class="display_flex justify-content_flex-center">
32
+      <button class="btn cancel" nz-button nzType="default" (click)="hideModal()">取消</button>
33
+    </div>
34
+  </div>
35
+</div>

+ 154 - 0
src/app/share/package-specimen-rule/package-specimen-rule.component.less

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

+ 70 - 0
src/app/share/package-specimen-rule/package-specimen-rule.component.ts

@@ -0,0 +1,70 @@
1
+import { Component, OnInit, Output, Input } from '@angular/core';
2
+import { EventEmitter } from '@angular/core';
3
+import { ToolService } from 'src/app/services/tool.service';
4
+import { MainService } from 'src/app/services/main.service';
5
+
6
+@Component({
7
+  selector: 'app-package-specimen-rule',
8
+  templateUrl: './package-specimen-rule.component.html',
9
+  styleUrls: ['./package-specimen-rule.component.less']
10
+})
11
+export class PackageSpecimenRuleComponent implements OnInit {
12
+  @Output() cancelFlagHand = new EventEmitter();
13
+  constructor(
14
+    private mainService: MainService,
15
+    private tool: ToolService,
16
+  ) { }
17
+
18
+  hosId:any = this.tool.getCurrentHospital().id; //当前院区
19
+
20
+  ngOnInit() {
21
+    this.getConfig();
22
+  }
23
+  // 隐藏模态框
24
+  hideModal() {
25
+    this.cancelFlagHand.emit(false)
26
+  }
27
+
28
+  // 获取配置
29
+  configs:any = {};
30
+  spePackageUrgents = {
31
+    '0': '普标',
32
+    '1': '急标',
33
+  }
34
+  getConfig() {
35
+		let postData = {
36
+      idx: 0,
37
+      sum: 10,
38
+      taskTypeConfig: {
39
+        taskTypeDTO: {
40
+          hosId: {
41
+            id: this.hosId
42
+          },
43
+          ordinaryField: {
44
+            key:"ordinary_field",
45
+            value: 'specimenPackage'
46
+          }
47
+        }
48
+      }
49
+    };
50
+
51
+    this.mainService
52
+      .getFetchDataList("simple/data", "taskTypeConfig", postData)
53
+      .subscribe((result) => {
54
+        if (result.status == 200) {
55
+          let configs = result.list[0] || {};
56
+
57
+          configs.spePackageDeptList = configs.spePackageDeptList || [];
58
+          configs.spePackageTubeList = configs.spePackageTubeList || [];
59
+          if(configs.spePackageUrgents){
60
+            configs.spePackageUrgentsList = configs.spePackageUrgents.split(',').map(v => ({ name: this.spePackageUrgents[v] }));
61
+          }else{
62
+            configs.spePackageUrgentsList = [];
63
+          }
64
+
65
+          this.configs = configs;
66
+        }
67
+      });
68
+  }
69
+}
70
+

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

@@ -62,6 +62,10 @@ import { BusinessDataDetailInfoModalComponent } from './businessData-detail-info
62 62
 import { SelectDateComponent } from './select-date/select-date.component';
63 63
 import { AddInspectModalComponent } from './add-inspect-modal/add-inspect-modal.component';
64 64
 import { SelectDateYytimeComponent } from './select-date-yytime/select-date-yytime.component';
65
+import { PackageSpecimenRuleComponent } from './package-specimen-rule/package-specimen-rule.component';
66
+import { SpecimenPackageListModalComponent } from './specimen-package-list-modal/specimen-package-list-modal.component';
67
+import { NgxPrintModule } from 'ngx-print';
68
+import { SpecimenPackageLogPromptModalComponent } from './specimen-package-log-prompt-modal/specimen-package-log-prompt-modal.component';
65 69
 
66 70
 @NgModule({
67 71
   declarations: [
@@ -127,6 +131,9 @@ import { SelectDateYytimeComponent } from './select-date-yytime/select-date-yyti
127 131
     SelectDateComponent,
128 132
     AddInspectModalComponent,
129 133
     SelectDateYytimeComponent,
134
+    PackageSpecimenRuleComponent,
135
+    SpecimenPackageListModalComponent,
136
+    SpecimenPackageLogPromptModalComponent,
130 137
   ],
131 138
   imports: [
132 139
     CommonModule,
@@ -135,6 +142,7 @@ import { SelectDateYytimeComponent } from './select-date-yytime/select-date-yyti
135 142
     ReactiveFormsModule,
136 143
     OverlayscrollbarsModule,
137 144
     NzIconModule,
145
+    NgxPrintModule,
138 146
   ],
139 147
   exports: [
140 148
     DetailSampleComponent,
@@ -200,6 +208,9 @@ import { SelectDateYytimeComponent } from './select-date-yytime/select-date-yyti
200 208
     SelectDateComponent,
201 209
     AddInspectModalComponent,
202 210
     SelectDateYytimeComponent,
211
+    PackageSpecimenRuleComponent,
212
+    SpecimenPackageListModalComponent,
213
+    SpecimenPackageLogPromptModalComponent,
203 214
   ]
204 215
 })
205 216
 export class ShareModule { }

+ 93 - 0
src/app/share/specimen-package-list-modal/specimen-package-list-modal.component.html

@@ -0,0 +1,93 @@
1
+<div class="modal display_flex justify-content_flex-center align-items_center">
2
+  <div class="modalBody" style="width: 1200px;">
3
+    <div class="title">科室内打包信息<i class="icon_transport transport-guanbi" (click)="hideModal()"></i></div>
4
+    <div class="list-template w100">
5
+      <div class="list-template__content">
6
+        <div class="list-template__top" nz-row>
7
+          <div nz-col nzXl='24' class="list-template__searchBox">
8
+            <div class="list-template__searchItem">
9
+              <span class="label">状态</span>:
10
+              <nz-select class="formItem" nzAllowClear [nzDropdownMatchSelectWidth]="false" nzShowSearch nzPlaceHolder="请选择状态" [(ngModel)]="searchCriteria.status" (ngModelChange)="selectStatus($event)">
11
+                <nz-option *ngFor="let option of specimentPackageTypeList" [nzLabel]="option.name" [nzValue]="option.id"></nz-option>
12
+              </nz-select>
13
+            </div>
14
+          </div>
15
+        </div>
16
+      </div>
17
+    </div>
18
+    <div class="content">
19
+      <nz-table class="hospitalTable" [nzData]="packageList" nzSize="middle" [nzShowPagination]="false"
20
+        [nzLoading]="hsLoading" [nzScroll]="{ y: '500px' }">
21
+        <thead>
22
+          <tr class="thead">
23
+            <th nzWidth="13%">包号</th>
24
+            <th nzWidth="6%">打包人</th>
25
+            <th nzWidth="12%">打包时间</th>
26
+            <th nzWidth="9%">申请单数</th>
27
+            <th nzWidth="6%">标本数</th>
28
+            <th nzWidth="6%">配送人</th>
29
+            <th nzWidth="12%">配送时间</th>
30
+            <th nzWidth="6%">接收人</th>
31
+            <th nzWidth="12%">接收时间</th>
32
+            <th nzWidth="8%">状态</th>
33
+            <th nzWidth="10%">操作</th>
34
+          </tr>
35
+        </thead>
36
+        <tbody>
37
+          <tr *ngFor="let data of packageList;let i = index;">
38
+            <td>{{ data.packCode }}</td>
39
+            <td>{{ data.packUserDTO?.name }}</td>
40
+            <td>{{ data.packTime | date: 'yyyy-MM-dd HH:mm'}}</td>
41
+            <td>{{ data.pathologyFormNum }}</td>
42
+            <td>{{ data.specimenNum }}</td>
43
+            <td>{{ data.deliveryUserDTO?.name }}</td>
44
+            <td>{{ data.deliveryTime | date: 'yyyy-MM-dd HH:mm'}}</td>
45
+            <td>{{ data.receiveUserDTO?.name }}</td>
46
+            <td>{{ data.receiveTime | date: 'yyyy-MM-dd HH:mm'}}</td>
47
+            <td>{{ data.status?.name }}</td>
48
+            <td>
49
+              <div class="coop">
50
+                <span (click)="printPackageByConfig(data)">补打</span>
51
+                <span (click)="toSpecimenPackage(data)" *ngIf="data.status.value === '0' || data.status.value === '1'">修改</span>
52
+              </div>
53
+            </td>
54
+          </tr>
55
+        </tbody>
56
+      </nz-table>
57
+
58
+      <div class="pagination">
59
+        <ng-template #totalTemplate let-total> 共 {{ total }} 条 </ng-template>
60
+        <nz-pagination [(nzPageIndex)]="pageIndex" [(nzTotal)]="total"
61
+          [(nzPageSize)]="pageSize" (nzPageIndexChange)="getList()"
62
+          (nzPageSizeChange)="getList()" [nzShowTotal]="totalTemplate">
63
+        </nz-pagination>
64
+      </div>
65
+    </div>
66
+    <div class="display_flex justify-content_flex-center bottom-btn">
67
+      <button class="btn cancel know" nz-button nzType="default" (click)="hideModal()">取消</button>
68
+    </div>
69
+  </div>
70
+</div>
71
+
72
+<!-- 打印的内容 -->
73
+<div id="print-section-package" hidden>
74
+  <!-- 80mm*80mm -->
75
+  <ng-container *ngIf="configs.spePackageCodeSize == 1">
76
+    <div style="overflow: hidden;padding: 4mm;font-size: 4mm;width: 80mm;height: 80mm;">
77
+      <div style="display: flex;">
78
+        <img [src]="base64" style="width: 23mm;height: 23mm;margin-right: 3mm;">
79
+        <div style="flex: 1;">
80
+          <div>包号:{{package.packCode}}</div>
81
+          <div style="margin-top: 3mm;">打包人:{{package.packUserDTO?.name}}</div>
82
+          <div style="margin-top: 3mm;">标本总数:{{package.specimenNum}}</div>
83
+        </div>
84
+      </div>
85
+      <div style="margin-top: 3mm;">打包时间:{{package.packTime | date: 'yyyy-MM-dd HH:mm'}}</div>
86
+      <div style="margin-top: 3mm;">检验科室:{{package.packDeptDTO?.dept}}</div>
87
+      <div style="display: flex;flex-wrap: wrap;">
88
+        <div style="width: 33.33%;margin-top: 3mm;" *ngFor="let item of typeSpecimentList | slice:0:9">{{item.name}}:{{item.size}}</div>
89
+      </div>
90
+    </div>
91
+  </ng-container>
92
+</div>
93
+<button ngxPrint printSectionId="print-section-package" #printBtnPackage hidden [printStyle]="{ '@page': { margin: '0 !important' }, 'body': { margin: '0 !important' } }">打印</button>

+ 261 - 0
src/app/share/specimen-package-list-modal/specimen-package-list-modal.component.less

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

+ 151 - 0
src/app/share/specimen-package-list-modal/specimen-package-list-modal.component.ts

@@ -0,0 +1,151 @@
1
+import { Component, OnInit, Input, Output, EventEmitter, ViewChild, ElementRef } from '@angular/core';
2
+import { MainService } from '../../services/main.service';
3
+import { ToolService } from 'src/app/services/tool.service';
4
+import { format, startOfDay, endOfDay } from 'date-fns';
5
+import { NzMessageService } from 'ng-zorro-antd';
6
+import { Router } from '@angular/router';
7
+@Component({
8
+  selector: 'app-specimen-package-list-modal',
9
+  templateUrl: './specimen-package-list-modal.component.html',
10
+  styleUrls: ['./specimen-package-list-modal.component.less']
11
+})
12
+export class SpecimenPackageListModalComponent implements OnInit {
13
+  @ViewChild('printBtnPackage', { static: false }) printBtnPackage: ElementRef<HTMLElement>;
14
+  // 切换科室,切换弹窗
15
+  hosId;
16
+  hsLoading = false;
17
+  packageList: any = [];// 标本列表
18
+  pageIndex: number = 1;//表格当前页码
19
+  pageSize: number = 10;//表格每页展示条数
20
+  total: number = 0;//表格总数据量
21
+  searchCriteria:any = {}
22
+
23
+  deptId = this.tool.getCurrentUserDept().id;
24
+  @Input() specimenPackageStateValue = '';
25
+  @Output() closeModelHs = new EventEmitter<any>();//1.组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件
26
+
27
+  constructor(
28
+    private mainService: MainService,
29
+    private tool: ToolService,
30
+    private message: NzMessageService,
31
+    public router: Router,
32
+  ) { }
33
+
34
+  ngOnInit() {
35
+    this.hosId = this.tool.getCurrentHospital().id;
36
+
37
+    this.getStatusList();
38
+  }
39
+  // 关闭弹窗
40
+  hideModal() {
41
+    this.closeModelHs.emit(JSON.stringify({ show: false }));//emits(向上弹射)事件
42
+  }
43
+
44
+  // 切换状态下拉框
45
+  selectStatus(e){
46
+    this.getSpecimenPackageList(1);
47
+  }
48
+
49
+  // 分页获取数据
50
+  getList(){
51
+    this.getSpecimenPackageList();
52
+  }
53
+
54
+  // 获取状态
55
+  specimentPackageTypeList: any[] = [];
56
+  getStatusList() {
57
+    this.mainService.getDictionary("list", "pathology_pack_status").subscribe((data:any) => {
58
+      this.specimentPackageTypeList = data || [];
59
+
60
+      let obj = this.specimentPackageTypeList.find(v => v.value == this.specimenPackageStateValue);
61
+      if(obj){
62
+        this.searchCriteria.status = obj.id;
63
+      }
64
+      this.getSpecimenPackageList(1);
65
+    })
66
+  }
67
+
68
+  // 获取标本列表
69
+  getSpecimenPackageList(idx?) {
70
+    if (idx) {
71
+      this.pageIndex = 1;
72
+    }
73
+    let postData = {
74
+      idx: this.pageIndex - 1,
75
+      sum: this.pageSize,
76
+      pathologyPackInfo: {
77
+        deptId: this.deptId,
78
+        busiType: 'specimen',//标本打包
79
+        status: this.searchCriteria.status ? { id: this.searchCriteria.status } : undefined,
80
+      }
81
+    }
82
+    this.hsLoading = true;
83
+    this.mainService.getFetchDataList('simple/data','pathologyPackInfo',postData).subscribe(data => {
84
+      this.hsLoading = false;
85
+      this.packageList = data.list || [];
86
+      this.total = data.totalNum || 0;
87
+    })
88
+  }
89
+
90
+  // 修改
91
+  toSpecimenPackage(data){
92
+    this.router.navigateByUrl(`/batchSpecimen?id=${data.id}`);
93
+  }
94
+
95
+  // 补打
96
+  base64:string = '';
97
+  typeSpecimentList:any[] = [];
98
+  patientSpecimentList:any[] = [];
99
+  package:any = {};
100
+  printPackage(item){
101
+    this.mainService
102
+      .makeQrCode({}, item.packCode)
103
+      .subscribe((data:any) => {
104
+        if (data.state == 200) {
105
+          this.typeSpecimentList = data.tube || [];
106
+          this.patientSpecimentList = data.patient || [];
107
+          this.package = data.package || {};
108
+          this.base64 = data.base64 || '';
109
+
110
+          this.message.success("操作成功");
111
+          setTimeout(()=>{
112
+            this.printBtnPackage.nativeElement.click();
113
+          },0)
114
+        } else {
115
+          this.message.error(data.msg || "操作失败");
116
+        }
117
+      });
118
+  }
119
+
120
+  // 获取配置
121
+  configs:any = {};
122
+  printPackageByConfig(data) {
123
+		let postData = {
124
+      idx: 0,
125
+      sum: 10,
126
+      taskTypeConfig: {
127
+        taskTypeDTO: {
128
+          hosId: {
129
+            id: this.hosId
130
+          },
131
+          ordinaryField: {
132
+            key:"ordinary_field",
133
+            value: 'specimenPackage'
134
+          }
135
+        }
136
+      }
137
+    };
138
+
139
+    this.mainService
140
+      .getFetchDataList("simple/data", "taskTypeConfig", postData)
141
+      .subscribe((result) => {
142
+        if (result.status == 200) {
143
+          this.configs = result.list[0] || {};
144
+          this.printPackage(data);
145
+        }
146
+      });
147
+  }
148
+}
149
+
150
+
151
+

+ 56 - 0
src/app/share/specimen-package-log-prompt-modal/specimen-package-log-prompt-modal.component.html

@@ -0,0 +1,56 @@
1
+<div
2
+  class="modal display_flex justify-content_flex-center align-items_center"
3
+  *ngIf="show"
4
+>
5
+  <div class="modalBody">
6
+    <div class="title">
7
+      流程信息查看<i
8
+        class="icon_transport transport-guanbi"
9
+        (click)="hideModal()"
10
+      ></i>
11
+    </div>
12
+    <div class="content">
13
+      <nz-table
14
+        class="hospitalTable"
15
+        [nzData]="historySpecimenList"
16
+        nzSize="middle"
17
+        [nzShowPagination]="false"
18
+        [nzLoading]="hsLoading"
19
+      >
20
+        <thead>
21
+          <tr class="thead">
22
+            <th nzWidth="8%">序号</th>
23
+            <th nzWidth="23%">动作</th>
24
+            <th nzWidth="23%">时间</th>
25
+            <th nzWidth="23%">备注</th>
26
+            <th nzWidth="23%">操作人</th>
27
+          </tr>
28
+        </thead>
29
+        <tbody>
30
+          <tr *ngFor="let data of historySpecimenList; let i = index">
31
+            <td>{{ i+(historySpecimenPageIndex-1) * historySpecimenPageSize + 1 }}</td>
32
+            <td>{{ data.operationType?.name }}</td>
33
+            <td>{{ data.createTime | date: "MM-dd HH:mm:ss" }}</td>
34
+            <td>{{ data.logRemarks }}</td>
35
+            <td>{{ data.operationUserDTO?.name }}</td>
36
+          </tr>
37
+        </tbody>
38
+      </nz-table>
39
+      <div class="pagination">
40
+        <nz-pagination
41
+          [(nzPageIndex)]="historySpecimenPageIndex"
42
+          [(nzTotal)]="historySpecimenListLength"
43
+          [(nzPageSize)]="historySpecimenPageSize"
44
+          (nzPageIndexChange)="getHistorySpecimen()"
45
+          (nzPageSizeChange)="getHistorySpecimen()"
46
+        >
47
+        </nz-pagination>
48
+      </div>
49
+    </div>
50
+    <div class="display_flex justify-content_flex-center">
51
+      <button class="btn cancel" nz-button (click)="hideModal()">
52
+        关闭
53
+      </button>
54
+    </div>
55
+  </div>
56
+</div>

+ 165 - 0
src/app/share/specimen-package-log-prompt-modal/specimen-package-log-prompt-modal.component.less

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

+ 54 - 0
src/app/share/specimen-package-log-prompt-modal/specimen-package-log-prompt-modal.component.ts

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

+ 17 - 0
src/app/views/batch-specimen/batch-specimen-routing.module.ts

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

+ 97 - 0
src/app/views/batch-specimen/batch-specimen.component.html

@@ -0,0 +1,97 @@
1
+<div class="header">
2
+  <div class="display_flex align-items_center">
3
+    <div class="dept">标本打包-{{deptDisplay == 2 ? deptDTO.deptalias : deptDTO.dept}}</div>
4
+  </div>
5
+  <input class="specimenCode" #specimenCodeElement nz-input placeholder="可扫描标本条码快速添加" [(ngModel)]="specimenCode" (input)="inputChange($event)" />
6
+  <div class="display_flex align-items_center">
7
+    <button nz-button class="btn default" (click)="showDelModal({}, '您确认要重置标本吗,重置会先清空标本在根据规则自动清点?','重置标本','reset')">重置标本</button>
8
+    <button nz-button nzType="default" class="ml8" *ngIf="configs.spePackageAutoPack == 1" (click)='showPackageSpecimenRule()'>自动清点规则</button>
9
+  </div>
10
+</div>
11
+<div class="table display_flex">
12
+  <div class="filter display_flex flex-direction_column">
13
+    <div class="total">总标本数:{{total}}</div>
14
+    <div class="block display_flex flex-direction_column" *ngIf="typeSpecimentList.length">
15
+      <div class="block_title">试管类型</div>
16
+      <div class="block_content">
17
+        <div class="block_item" *ngFor="let item of typeSpecimentList" (click)="clickType(item)" [ngClass]="{'active': item.id == activeTypeId}">{{item.name}}:{{item.size}}</div>
18
+      </div>
19
+    </div>
20
+    <div class="block display_flex flex-direction_column patient" *ngIf="patientSpecimentList.length">
21
+      <div class="block_title">患者</div>
22
+      <div class="block_content">
23
+        <div class="block_item" *ngFor="let item of patientSpecimentList" (click)="clickPatient(item)" [ngClass]="{'active': item.no == activePatientNo}">{{item.name}}:{{item.size}}</div>
24
+      </div>
25
+    </div>
26
+  </div>
27
+  <nz-table class="list-template__nzTable filter_table" [nzData]="listOfData" nzSize="middle" [nzShowPagination]="false" [nzLoading]="loading1">
28
+    <thead>
29
+      <tr class="thead">
30
+        <th nzWidth="11%">患者姓名</th>
31
+        <th nzWidth="11%">住院号</th>
32
+        <th nzWidth="11%">标本条码</th>
33
+        <th nzWidth="11%">检验项目</th>
34
+        <th nzWidth="11%">类型</th>
35
+        <th nzWidth="11%">采集人</th>
36
+        <th nzWidth="11%">采集时间</th>
37
+        <th nzWidth="11%">检验科室</th>
38
+        <th nzWidth="12%">操作</th>
39
+      </tr>
40
+    </thead>
41
+    <tbody>
42
+      <tr *ngFor="let data of listOfData">
43
+        <td>{{ data.patientName }}<span *ngIf="data.bedNum">({{ data.bedNum }})</span></td>
44
+        <td>{{ data.residenceNo }}</td>
45
+        <td>{{ data.scode }}</td>
46
+        <td>{{ data.specimenDesc }}</td>
47
+        <td>{{ data.stype?.name }}<span *ngIf="data.tubeType">({{ data.tubeType?.name }})</span></td>
48
+        <td>{{ data.collectNurseName }}</td>
49
+        <td>{{ data.printDate }}</td>
50
+        <td>{{ data.checkDept?.dept }}</td>
51
+        <td>
52
+          <div class="coop">
53
+            <span (click)="showDelModal(data, '您确认要移除吗?','移除','del')">移除</span>
54
+          </div>
55
+        </td>
56
+      </tr>
57
+    </tbody>
58
+  </nz-table>
59
+</div>
60
+<div class="footer display_flex align-items_center justify-content_flex-center">
61
+  <button nzType="primary" class="btn" nz-button (click)='packageHandler()' *ngIf="this.total > 0">打包</button>
62
+  <button nzType="default" nz-button class="btn cancel ml8" (click)='goBack()'>取消</button>
63
+</div>
64
+
65
+<!-- 操作成功/失败提示框 -->
66
+<app-prompt-modal *ngIf="promptModalShow" [content]="promptContent" [success]="ifSuccess" [show]="promptModalShow"
67
+  [info]="promptInfo">
68
+</app-prompt-modal>
69
+
70
+<!-- 删除模态框 -->
71
+<app-dialog-delete [delModal]="delModal" (hideDelModalEvent)="hideDelModal()" [btnLoading]="btnLoading"
72
+(confirmDelEvent)="confirmDel()" [content]="tipsMsg1"></app-dialog-delete>
73
+
74
+<app-package-specimen-rule *ngIf="isShowPackageSpecimenRule" (cancelFlagHand)="closePackageSpecimenRule($event)"></app-package-specimen-rule>
75
+
76
+<!-- 打印的内容 -->
77
+<div id="print-section" hidden>
78
+  <!-- 80mm*80mm -->
79
+  <ng-container *ngIf="configs.spePackageCodeSize == 1">
80
+    <div style="overflow: hidden;padding: 4mm;font-size: 4mm;width: 80mm;height: 80mm;">
81
+      <div style="display: flex;">
82
+        <img [src]="base64" style="width: 23mm;height: 23mm;margin-right: 3mm;">
83
+        <div style="flex: 1;">
84
+          <div>包号:{{package.packCode}}</div>
85
+          <div style="margin-top: 3mm;">打包人:{{package.packUserDTO?.name}}</div>
86
+          <div style="margin-top: 3mm;">标本总数:{{package.specimenNum}}</div>
87
+        </div>
88
+      </div>
89
+      <div style="margin-top: 3mm;">打包时间:{{package.packTime | date: 'yyyy-MM-dd HH:mm'}}</div>
90
+      <div style="margin-top: 3mm;">检验科室:{{package.packDeptDTO?.dept}}</div>
91
+      <div style="display: flex;flex-wrap: wrap;">
92
+        <div style="width: 33.33%;margin-top: 3mm;" *ngFor="let item of typeSpecimentList | slice:0:9">{{item.name}}:{{item.size}}</div>
93
+      </div>
94
+    </div>
95
+  </ng-container>
96
+</div>
97
+<button ngxPrint printSectionId="print-section" #printBtn hidden [printStyle]="{ '@page': { margin: '0 !important' }, 'body': { margin: '0 !important' } }">打印</button>

+ 193 - 0
src/app/views/batch-specimen/batch-specimen.component.less

@@ -0,0 +1,193 @@
1
+@import "../../../../src/theme.less";
2
+
3
+:host {
4
+  width: 100vw;
5
+  height: 100vh;
6
+  overflow: hidden;
7
+  background-color: #D9D9D9;
8
+  display: flex;
9
+  flex-direction: column;
10
+  .header{
11
+    height: 73px;
12
+    background-color: #fff;
13
+    display: flex;
14
+    align-items: center;
15
+    justify-content: space-between;
16
+    padding: 0 24px;
17
+    font-size: 20px;
18
+    .specimenCode{
19
+      width: 365px;
20
+      height: 40px;
21
+    }
22
+    .dept{
23
+      margin-right: 48px;
24
+      color: @primary-color;
25
+    }
26
+    .patient{
27
+      margin-left: 24px;
28
+    }
29
+    .label{
30
+      padding-right: 16px;
31
+      font-size: 14px;
32
+    }
33
+    .formItem{
34
+      width: 173px;
35
+    }
36
+    .info{
37
+      margin-left: 48px;
38
+    }
39
+  }
40
+  .table{
41
+    flex: 1;
42
+    min-height: 0;
43
+    margin-top: 1px;
44
+    background-color: #fff;
45
+    padding: 8px 16px;
46
+    .filter{
47
+      width: 176px;
48
+      margin-right: 10px;
49
+      .total{
50
+        height: 30px;
51
+        display: flex;
52
+        align-items: center;
53
+        font-size: 16px;
54
+        background: rgba(0,0,0,0.06);
55
+        font-weight: bold;
56
+        padding: 0 16px;
57
+      }
58
+      .block{
59
+        margin-top: 10px;
60
+        font-size: 14px;
61
+        &.patient{
62
+          flex: 1;
63
+          min-height: 0;
64
+          .block_content{
65
+            height: auto;
66
+            flex: 1;
67
+          }
68
+        }
69
+        .block_title{
70
+          border: 1px solid #D9D9D9;
71
+          font-weight: bold;
72
+          height: 40px;
73
+          display: flex;
74
+          align-items: center;
75
+          padding: 0 16px;
76
+        }
77
+        .block_content{
78
+          border: 1px solid #D9D9D9;
79
+          border-top: none;
80
+          overflow-y: auto;
81
+          height: 113px;
82
+          .block_item{
83
+            padding: 0 16px;
84
+            height: 28px;
85
+            display: flex;
86
+            align-items: center;
87
+            cursor: pointer;
88
+            &.active,
89
+            &:hover{
90
+              background: #F0F6ED;
91
+              color: @primary-color;
92
+            }
93
+          }
94
+        }
95
+      }
96
+    }
97
+    .filter_table{
98
+      flex: 1;
99
+      overflow-y: auto;
100
+    }
101
+    .patient{
102
+      position: relative;
103
+      .circle{
104
+        width: 8px;
105
+        height: 8px;
106
+        border-radius: 50%;
107
+        background-color: @primary-color;
108
+        position: absolute;
109
+        top: 50%;
110
+        left: -8px;
111
+        transform: translate(-50%,-50%);
112
+        &.red{
113
+          background-color: red;
114
+        }
115
+      }
116
+    }
117
+    .transport-weibiaoti2010104{
118
+      font-size: 15px;
119
+      color: #999;
120
+      margin-left: 10px;
121
+      margin-top: 3px;
122
+      cursor: pointer;
123
+    }
124
+    .transport-shanchu1{
125
+      font-size: 15px;
126
+      color: #999;
127
+      margin-left: 5px;
128
+      margin-top: 3px;
129
+      cursor: pointer;
130
+    }
131
+    .thead{
132
+      background-image: linear-gradient(to right, @bg-start, @bg-end);
133
+      th {
134
+        background: transparent;
135
+        color: #fff;
136
+        text-align: center;
137
+      }
138
+    }
139
+    .ant-table-body {
140
+      border-bottom: 1px solid #e5e9ed;
141
+    }
142
+
143
+    .ant-table-tbody {
144
+      tr {
145
+        text-align: center;
146
+        color: #333;
147
+
148
+        td {
149
+          border: none;
150
+
151
+          &.tab_hover:hover{
152
+            text-decoration: underline;
153
+            cursor: pointer;
154
+          }
155
+
156
+          .coop {
157
+            button{
158
+              color: #333;
159
+            }
160
+            span,button {
161
+              display: inline-block;
162
+              padding: 0 8px;
163
+              cursor: pointer;
164
+              position: relative;
165
+
166
+              &::after {
167
+                content: "|";
168
+                position: absolute;
169
+                top: 0;
170
+                right: 0;
171
+              }
172
+
173
+              &:hover,
174
+              &:active {
175
+                color: @primary-color;
176
+              }
177
+
178
+              &:nth-last-child(1) {
179
+                &::after {
180
+                  content: "";
181
+                }
182
+              }
183
+            }
184
+          }
185
+        }
186
+      }
187
+    }
188
+  }
189
+  .footer{
190
+    height: 60px;
191
+    background-color: #fff;
192
+  }
193
+}

+ 361 - 0
src/app/views/batch-specimen/batch-specimen.component.ts

@@ -0,0 +1,361 @@
1
+import { Component, OnInit, AfterViewInit, ElementRef, ViewChild } from '@angular/core';
2
+import { ToolService } from 'src/app/services/tool.service';
3
+import { MainService } from 'src/app/services/main.service';
4
+import { NzMessageService } from 'ng-zorro-antd';
5
+import { Location } from '@angular/common';
6
+import { Subject } from 'rxjs';
7
+import { debounceTime } from 'rxjs/operators';
8
+import { Router, ActivatedRoute } from '@angular/router';
9
+@Component({
10
+  selector: 'app-batch-specimen',
11
+  templateUrl: './batch-specimen.component.html',
12
+  styleUrls: ['./batch-specimen.component.less']
13
+})
14
+export class BatchSpecimenComponent implements OnInit, AfterViewInit {
15
+  @ViewChild('printBtn', { static: false }) printBtn: ElementRef<HTMLElement>;
16
+  @ViewChild('specimenCodeElement', { static: false}) specimenCodeElementRef: ElementRef;
17
+
18
+  constructor(
19
+    private mainService: MainService,
20
+    private tool: ToolService,
21
+    private message: NzMessageService,
22
+    private _location: Location,
23
+    public router: Router,
24
+    private route: ActivatedRoute,
25
+  ) { }
26
+
27
+  hosId:any = this.tool.getCurrentHospital().id; //当前院区
28
+  deptDTO:any = this.tool.getCurrentUserDept(); //当前科室
29
+  deptDisplay; //护士端是否显示可以别名,1是显示科室名称,2是显示科室别名
30
+  listOfData: any[] = []; //表格数据
31
+
32
+  searchTimerSubject = new Subject(); //防抖
33
+
34
+  ngOnInit() {
35
+    //防抖
36
+    this.searchTimerSubject.pipe(debounceTime(500)).subscribe((v) => {
37
+      let fun = v[0];
38
+      fun.call(this, v[1]);
39
+    });
40
+
41
+    this.tool.getDeptDisplay().subscribe((result) => {
42
+      if (result.status == 200) {
43
+        this.deptDisplay = result.list[0].valueconfig;
44
+      }
45
+    });
46
+
47
+    this.init();
48
+  }
49
+
50
+  ngAfterViewInit() {
51
+    this.specimenCodeElementRef.nativeElement.focus();
52
+  }
53
+
54
+  init(){
55
+    this.getConfig();
56
+  }
57
+
58
+  // 获取配置
59
+  configs:any = {};
60
+  getConfig() {
61
+		let postData = {
62
+      idx: 0,
63
+      sum: 10,
64
+      taskTypeConfig: {
65
+        taskTypeDTO: {
66
+          hosId: {
67
+            id: this.hosId
68
+          },
69
+          ordinaryField: {
70
+            key:"ordinary_field",
71
+            value: 'specimenPackage'
72
+          }
73
+        }
74
+      }
75
+    };
76
+
77
+    this.mainService
78
+      .getFetchDataList("simple/data", "taskTypeConfig", postData)
79
+      .subscribe((result) => {
80
+        if (result.status == 200) {
81
+          this.configs = result.list[0] || {};
82
+          this.querySaveSpePackage();
83
+        }
84
+      });
85
+  }
86
+
87
+  // 获取患者、试管类型列表、标本总数
88
+  total:any;
89
+  typeSpecimentList:any[] = [];
90
+  patientSpecimentList:any[] = [];
91
+  package:any = {};
92
+  querySaveSpePackage(){
93
+    let postData:any = {
94
+      deptId: this.deptDTO.id,
95
+    };
96
+
97
+    if(this.route.snapshot.paramMap.get("id")){
98
+      postData.packageId = +this.route.snapshot.paramMap.get("id");
99
+    }
100
+
101
+    this.mainService
102
+      .querySaveSpePackage(postData)
103
+      .subscribe((result:any) => {
104
+        if (result.state == 200) {
105
+          this.total = result.totalCount;
106
+          this.typeSpecimentList = result.tube || [];
107
+          this.patientSpecimentList = result.patient || [];
108
+          this.package = result.package || {};
109
+
110
+          this.getList();
111
+        }
112
+      })
113
+  }
114
+
115
+  inspectActiveList: any = [];//选中检查列表
116
+  patientActiveList: any = [];//选中患者列表
117
+
118
+  coopData: any = {}; //当前操作列
119
+  btnLoading: boolean = false; //提交按钮loading状态
120
+
121
+  delModal: boolean = false; //删除模态框
122
+  tipsMsg1: string; //提示框信息
123
+  tipsMsg2: string; //操作后信息
124
+  confirmDelType: string; //确认的类型(启用/停用,删除)
125
+  showDelModal(
126
+    data,
127
+    tipsMsg1: string,
128
+    tipsMsg2: string,
129
+    type: string,
130
+  ) {
131
+    this.confirmDelType = type;
132
+    this.delModal = true;
133
+    this.coopData = data;
134
+    this.tipsMsg1 = tipsMsg1;
135
+    this.tipsMsg2 = tipsMsg2;
136
+  }
137
+  // 隐藏删除框
138
+  hideDelModal() {
139
+    this.delModal = false;
140
+  }
141
+  // 确认删除
142
+  confirmDel() {
143
+    this.btnLoading = true;
144
+    if (this.confirmDelType === "del") {
145
+      //删除-移除标本
146
+      let postData = {
147
+        speIds: this.coopData.id.toString(),
148
+        packageId: this.package.id,
149
+      }
150
+
151
+      this.mainService
152
+        .removePackageSpe(postData)
153
+        .subscribe((data:any) => {
154
+          this.btnLoading = false;
155
+          this.delModal = false;
156
+          if (data.state == 200) {
157
+            this.showPromptModal(this.tipsMsg2, true, "");
158
+          } else {
159
+            this.showPromptModal(this.tipsMsg2, false, data.msg);
160
+          }
161
+        });
162
+    }else if (this.confirmDelType === "reset") {
163
+      //先重置再自动清点
164
+      let postData = {
165
+        packageId: this.package.id,
166
+      }
167
+
168
+      this.mainService
169
+        .resetPackageSpe(postData)
170
+        .subscribe((data:any) => {
171
+          this.btnLoading = false;
172
+          this.delModal = false;
173
+          if (data.state == 200) {
174
+            this.showPromptModal(this.tipsMsg2, true, "");
175
+          } else {
176
+            this.showPromptModal(this.tipsMsg2, false, data.msg);
177
+          }
178
+        });
179
+    }else if (this.confirmDelType === "package") {
180
+      //打包
181
+      if(this.configs.spePackageCreateOrder == 1){
182
+        // 生成配送工单
183
+        let postData = {
184
+          type: 'specimenPackage',
185
+          id: this.package.id,
186
+        }
187
+
188
+        this.mainService
189
+          .createOrTakeOrderSpecimen(postData)
190
+          .subscribe((data:any) => {
191
+            this.btnLoading = false;
192
+            this.delModal = false;
193
+            if (data.state == 200) {
194
+              this.printPackage();
195
+            } else {
196
+              this.message.error(data.msg || "操作失败");
197
+            }
198
+          });
199
+      }else{
200
+        this.btnLoading = false;
201
+        this.delModal = false;
202
+        this.printPackage();
203
+      }
204
+    }
205
+  }
206
+
207
+  // 打印
208
+  base64:string = '';
209
+  printPackage(){
210
+    this.mainService
211
+      .makeQrCode({}, this.package.packCode)
212
+      .subscribe((data:any) => {
213
+        if (data.state == 200) {
214
+          this.total = data.totalCount;
215
+          this.typeSpecimentList = data.tube || [];
216
+          this.patientSpecimentList = data.patient || [];
217
+          this.package = data.package || {};
218
+          this.base64 = data.base64 || '';
219
+
220
+          this.message.success("操作成功");
221
+          setTimeout(()=>{
222
+            this.printBtn.nativeElement.click();
223
+            this.router.navigateByUrl("/main/orderManagement");
224
+          },0)
225
+        } else {
226
+          this.message.error(data.msg || "操作失败");
227
+        }
228
+      });
229
+  }
230
+
231
+  // 打包
232
+  packageHandler(){
233
+    this.showDelModal({}, `你确认要打包${this.total}只标本吗?`,'打包','package')
234
+  }
235
+
236
+  // 展示信息提示框(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)
237
+  promptContent: string; //操作提示框提示信息
238
+  ifSuccess: boolean; //操作成功/失败
239
+  promptInfo: string; //操作结果提示信息
240
+  promptModalShow: boolean; //操作提示框是否展示
241
+  showPromptModal(con, success, promptInfo?) {
242
+    this.promptModalShow = false;
243
+    this.promptContent = con;
244
+    this.ifSuccess = success;
245
+    this.promptInfo = promptInfo;
246
+    setTimeout(() => {
247
+      this.promptModalShow = true;
248
+    }, 100);
249
+    this.querySaveSpePackage();
250
+  }
251
+
252
+  loading1:boolean = false;
253
+
254
+  getList(){
255
+    let data = {
256
+      idx: 0,
257
+      sum: 99999,
258
+      specimen: {
259
+        packageId: this.package ? this.package.id : undefined,
260
+        patientNo: this.activePatientNo || undefined,
261
+        tubeType: this.activeTypeId ? { id: this.activeTypeId } : undefined,
262
+      },
263
+    };
264
+    this.loading1 = true;
265
+    this.mainService
266
+      .getFetchDataList("simple/data", "specimen", data)
267
+      .subscribe((data) => {
268
+        this.loading1 = false;
269
+        if (data.status == 200) {
270
+          this.listOfData = data.list;
271
+        }else{
272
+          this.message.error(data.msg || "请求数据失败");
273
+        }
274
+      });
275
+  }
276
+
277
+  // 返回
278
+  goBack(){
279
+    this._location.back();
280
+  }
281
+
282
+  // 选择试管类型
283
+  activeTypeId:any;
284
+  clickType(item){
285
+    if(this.activeTypeId == item.id){
286
+      this.activeTypeId = undefined;
287
+    }else{
288
+      this.activeTypeId = item.id;
289
+    }
290
+
291
+    this.querySaveSpePackage();
292
+  }
293
+
294
+  // 选择患者
295
+  activePatientNo:any;
296
+  clickPatient(item){
297
+    if(this.activePatientNo == item.no){
298
+      this.activePatientNo = undefined;
299
+    }else{
300
+      this.activePatientNo = item.no;
301
+    }
302
+
303
+    this.querySaveSpePackage();
304
+  }
305
+
306
+  /**
307
+   * @description: PDA扫码复制到文本输入框
308
+   * @return {*}
309
+   * @author: seimin
310
+   */
311
+  specimenCode:string = '';
312
+  inputChange(e){
313
+    if(this.specimenCode.length >= 8){
314
+      this.searchTimer(this.addSpeciment, this.specimenCode);
315
+    }
316
+  }
317
+
318
+  // 添加标本
319
+  maskFlag: any = false;
320
+  addSpeciment(speCode){
321
+    this.maskFlag = this.message.loading("正在加载中..", {
322
+      nzDuration: 0,
323
+    }).messageId;
324
+
325
+    let postData = {
326
+      speCode,
327
+      packageId: this.package.id,
328
+    };
329
+
330
+    this.mainService
331
+      .addPackageSpe(postData)
332
+      .subscribe((result:any) => {
333
+        this.message.remove(this.maskFlag);
334
+        this.maskFlag = false;
335
+
336
+        if(result.state == 200){
337
+          this.message.success('操作成功!');
338
+          this.specimenCode = '';//清空
339
+          this.querySaveSpePackage();
340
+        }else{
341
+          this.message.error(result.msg || '操作失败!');
342
+        }
343
+      });
344
+  }
345
+
346
+  // 防抖
347
+  searchTimer(fun, e) {
348
+    this.searchTimerSubject.next([fun, e]);
349
+  }
350
+
351
+  // 自动清点规则
352
+  isShowPackageSpecimenRule:boolean = false;
353
+  showPackageSpecimenRule(){
354
+    this.isShowPackageSpecimenRule = true;
355
+  }
356
+
357
+  // 关闭自动清点规则
358
+  closePackageSpecimenRule(e){
359
+    this.isShowPackageSpecimenRule = e;
360
+  }
361
+}

+ 19 - 0
src/app/views/batch-specimen/batch-specimen.module.ts

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

+ 7 - 0
src/app/views/hushijiandan/hushijiandan.component.html

@@ -361,6 +361,10 @@
361 361
                           <span (click)="changeInspectClosedLoopView($event, '2')">预:{{patientInspectCountMsg.data ? patientInspectCountMsg.data[0].yyCount : 0}}</span>
362 362
                           <span (click)="changeInspectClosedLoopView($event, '3,4')">检:{{patientInspectCountMsg.data ? patientInspectCountMsg.data[0].workingCount : 0}}</span>
363 363
                         </div>
364
+                        <div class="navSpecimen" *ngIf="item.icon.value === 'specimenPackage'">
365
+                          <span (click)="toSpecimenPackage($event, '1')">未:{{specimenPackageCountMsg.data ? specimenPackageCountMsg.data[0].waitCount : 0}}</span>
366
+                          <span (click)="toSpecimenPackage($event, '2')">送:{{specimenPackageCountMsg.data ? specimenPackageCountMsg.data[0].workingCount : 0}}</span>
367
+                        </div>
364 368
                       </div>
365 369
                     </div>
366 370
                   </div>
@@ -2753,3 +2757,6 @@
2753 2757
 
2754 2758
 <!-- 智能客服 -->
2755 2759
 <app-smart-dialogue *ngIf="smartShow" (cancelModal)="smartClose($event)"></app-smart-dialogue>
2760
+
2761
+<!-- 标本打包-数字点击 -->
2762
+<app-specimen-package-list-modal *ngIf="isShowSpecimenPackageList" (closeModelHs)="closeSpecimenPackageList($event)" [specimenPackageStateValue]="specimenPackageStateValue"></app-specimen-package-list-modal>

+ 6 - 0
src/app/views/hushijiandan/hushijiandan.component.less

@@ -1467,6 +1467,12 @@
1467 1467
                           font-size: 24px;
1468 1468
                         }
1469 1469
                       }
1470
+                      &.specimenPackage{
1471
+                        background: linear-gradient( 41deg, rgba(40,60,237,0.73) 0%, #0FBBE2 100%);
1472
+                        .icon_transport{
1473
+                          font-size: 24px;
1474
+                        }
1475
+                      }
1470 1476
                     }
1471 1477
                     h2{
1472 1478
                       font-size: 12px;

+ 43 - 0
src/app/views/hushijiandan/hushijiandan.component.ts

@@ -791,6 +791,8 @@ export class HushijiandanComponent implements OnInit {
791 791
       return 'incident';
792 792
     }else if(icon === 'transport-peihuguanli'){
793 793
       return 'inspect';
794
+    }else if(icon === 'transport-dabao'){
795
+      return 'specimenPackage';
794 796
     }else{
795 797
       return '';
796 798
     }
@@ -1248,6 +1250,7 @@ export class HushijiandanComponent implements OnInit {
1248 1250
     this.msgTimerId = setInterval(() => {
1249 1251
       this.getSpecimenWorkOrderMsg();
1250 1252
       this.getPatientInspectCountMsg();
1253
+      this.getSpePackageCountMsg();
1251 1254
     }, 60000);
1252 1255
   }
1253 1256
 
@@ -1294,6 +1297,23 @@ export class HushijiandanComponent implements OnInit {
1294 1297
       });
1295 1298
   }
1296 1299
 
1300
+  // 护士端-标本打包图标下两个数字
1301
+  specimenPackageCountMsg: any = {};
1302
+  getSpePackageCountMsg() {
1303
+    if(this.currentDept.typeValue == 'surgery' && !this.tabSearchCont){
1304
+      return;
1305
+    }
1306
+    let that = this;
1307
+
1308
+    that.mainService
1309
+      .getSpePackageCount({
1310
+        deptId: JSON.parse(localStorage.getItem("user")).user.dept.id,
1311
+      })
1312
+      .subscribe((data) => {
1313
+        that.specimenPackageCountMsg = data;
1314
+      });
1315
+  }
1316
+
1297 1317
   // 手术提示信息
1298 1318
   surgeryLoading = false;
1299 1319
 	now:any = new Date();
@@ -1806,6 +1826,8 @@ export class HushijiandanComponent implements OnInit {
1806 1826
             // 药品静配权限
1807 1827
             that.getJpDrugsWKOMsg();
1808 1828
           }
1829
+
1830
+          that.getSpePackageCountMsg();
1809 1831
         }
1810 1832
 
1811 1833
         if(data.data.tabPermission && Array.isArray(data.data.tabPermission.data)){
@@ -4553,6 +4575,12 @@ export class HushijiandanComponent implements OnInit {
4553 4575
     }
4554 4576
     this.router.navigateByUrl(`/inspectClosedLoopView?queryParams=${JSON.stringify(queryParams)}`);
4555 4577
   }
4578
+
4579
+  // 标本打包弹窗
4580
+  toSpecimenPackage(e, stateValue){
4581
+    e.stopPropagation();
4582
+    this.viewSpecimenPackageList(stateValue);
4583
+  }
4556 4584
   // 隐藏查看标本详情弹层
4557 4585
   hideSpeDetailModel() {
4558 4586
     this.detailModel = false;
@@ -5284,6 +5312,9 @@ export class HushijiandanComponent implements OnInit {
5284 5312
     if(data.bussType.value === 'service'){
5285 5313
       // 运维报修
5286 5314
       this.showBxModal();
5315
+    }else if(data.icon.value === 'specimenPackage'){
5316
+      // 标本打包
5317
+      this.router.navigateByUrl("/batchSpecimen");
5287 5318
     }else if(data.bussType.value === 'goods'){
5288 5319
       // 物品配送
5289 5320
       this.buildQuickConfirmData = data || {};
@@ -5442,4 +5473,16 @@ export class HushijiandanComponent implements OnInit {
5442 5473
         }
5443 5474
       });
5444 5475
   }
5476
+
5477
+  // 查看标本打包
5478
+  specimenPackageStateValue;
5479
+  isShowSpecimenPackageList = false; //业务数据弹窗开关
5480
+  viewSpecimenPackageList(stateValue) {
5481
+    this.specimenPackageStateValue = stateValue;
5482
+    this.isShowSpecimenPackageList = true;
5483
+  }
5484
+  // 关闭标本打包弹窗
5485
+  closeSpecimenPackageList(e) {
5486
+    this.isShowSpecimenPackageList = JSON.parse(e).show;
5487
+  }
5445 5488
 }

+ 5 - 0
src/app/views/main/main-routing.module.ts

@@ -627,6 +627,11 @@ const routes: Routes = [
627 627
 			{
628 628
 			  path: "patientInspectLog",
629 629
 			  loadChildren: () => import("../patient-inspect-log/patient-inspect-log.module").then((m) => m.PatientInspectLogModule),
630
+			},
631
+      // 标本打包
632
+			{
633
+			  path: "specimenPackage",
634
+			  loadChildren: () => import("../specimen-package/specimen-package.module").then((m) => m.SpecimenPackageModule),
630 635
 			}
631 636
     ],
632 637
   },

+ 2 - 1
src/app/views/pathology-check/pathology-check.component.ts

@@ -342,7 +342,8 @@ export class PathologyCheckComponent implements OnInit, OnDestroy {
342 342
 			receiveUser:this.connectUserId,
343 343
 			deliveryUser:this.dispatchingUserId,
344 344
 			operationType:this.operationType,
345
-			id:this.scanCodeData.id
345
+			id:this.scanCodeData.id,
346
+      busiType: 'pathology',//病理打包
346 347
 		};
347 348
 		this.btnConnectLoading = true
348 349
 		this.mainService

+ 9 - 7
src/app/views/pathology/pathology.component.ts

@@ -219,7 +219,7 @@ export class PathologyComponent implements OnInit, OnDestroy {
219 219
 			this.getToday()
220 220
 		},60000)
221 221
   }
222
-	
222
+
223 223
 	isShowNurseCode = false; //是否展开科室二维码
224 224
 	nurseCodeImg = ""; //图片
225 225
 	refreshQRCodeTime = 0; //刷新时间间隔
@@ -248,7 +248,7 @@ export class PathologyComponent implements OnInit, OnDestroy {
248 248
 	    }
249 249
 	  });
250 250
 	}
251
-	
251
+
252 252
   // 当前时间日期
253 253
   runTime() {
254 254
     clearTimeout(this.timer);
@@ -372,7 +372,8 @@ export class PathologyComponent implements OnInit, OnDestroy {
372 372
 	    idx: that.pageThreeIndex - 1,
373 373
 	    sum: that.pageSize,
374 374
 	    pathologyPackInfo: {
375
-	  		deptId: this.deptId
375
+	  		deptId: this.deptId,
376
+        busiType: 'pathology',//病理打包
376 377
 	    },
377 378
 	  };
378 379
 	  this.loading3 = true;
@@ -478,7 +479,8 @@ export class PathologyComponent implements OnInit, OnDestroy {
478 479
 			deliveryUser:this.handoverUserId,
479 480
 			receiveHos:this.validateForm.value.gurop,
480 481
 			targetDept:this.validateForm.value.department,
481
-			operationType:'bagDelivery'
482
+			operationType:'bagDelivery',
483
+      busiType: 'pathology',//病理打包
482 484
 		};
483 485
 		this.btnLoading = true
484 486
 		this.mainService
@@ -512,12 +514,12 @@ export class PathologyComponent implements OnInit, OnDestroy {
512 514
 		this.isDeptLoading = true
513 515
 		this.changeInpSubjectDepartment.next([e]);
514 516
 	}
515
-	
517
+
516 518
 	// 关闭查看标本
517 519
 	closeSpecimenModal(){
518 520
 		this.specimenViewDialog = false
519 521
 	}
520
-	
522
+
521 523
 	// 查看标本
522 524
 	specimenViewDialog:any = false;
523 525
 	viewData:any = [];
@@ -528,7 +530,7 @@ export class PathologyComponent implements OnInit, OnDestroy {
528 530
 		this.specimenItem = item;
529 531
 		this.viewData.push(item)
530 532
 	}
531
-	
533
+
532 534
 	// 获取院区
533 535
 	getHospitalData(){
534 536
 		let arr = this.tool.getHospitalList().filter(i=>i.parent==undefined)

+ 2 - 1
src/app/views/pathologyScan/pathologyScan.component.ts

@@ -431,7 +431,8 @@ export class PathologyScanComponent implements OnInit, OnDestroy {
431 431
 			receiveUser:this.connectUserId,
432 432
 			deliveryUser:this.dispatchingUserId,
433 433
 			operationType:'bagReceive',
434
-			id:this.scanCodeData.id
434
+			id:this.scanCodeData.id,
435
+      busiType: 'pathology',//病理打包
435 436
 		};
436 437
 		this.btnConnectLoading = true
437 438
 		this.mainService

+ 17 - 0
src/app/views/specimen-package/specimen-package-routing.module.ts

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

+ 103 - 0
src/app/views/specimen-package/specimen-package.component.html

@@ -0,0 +1,103 @@
1
+<div class="list-template">
2
+  <div class="list-template__content">
3
+    <div class="list-template__top" nz-row>
4
+      <div nz-col nzXl='19' class="list-template__searchBox">
5
+        <div class="list-template__searchItem">
6
+          <span class="label">时间区间</span>:
7
+          <nz-range-picker nzShowTime [(ngModel)]="dateRange" (nzOnCalendarChange)="onCalendarChangeDate($event)"></nz-range-picker>
8
+        </div>
9
+        <div class="list-template__searchItem">
10
+          <span class="label">打包科室</span>:
11
+          <nz-select class="formItem" [nzDropdownMatchSelectWidth]="false" nzPlaceHolder="请选择打包科室" [(ngModel)]="searchDto.packDept" nzAllowClear nzServerSearch nzShowSearch (nzOnSearch)="changeInp('department', $event)" (nzOpenChange)="openChangeDept($event)" (ngModelChange)="setIsSelecting(true)">
12
+            <ng-container *ngFor="let option of deptList">
13
+              <nz-option *ngIf="!isLoading" [nzLabel]="option.dept" [nzValue]="option.id"></nz-option>
14
+            </ng-container>
15
+            <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
16
+              <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
17
+            </nz-option>
18
+          </nz-select>
19
+        </div>
20
+        <div class="list-template__searchItem">
21
+          <span class="label">收取人</span>:
22
+          <nz-select class="formItem" [nzDropdownMatchSelectWidth]="false" nzPlaceHolder="请选择收取人" [(ngModel)]="searchDto.receiveUser" nzAllowClear nzServerSearch nzShowSearch (nzOnSearch)="changeInp('patient', $event)" (nzOpenChange)="openChangePatient($event)" (ngModelChange)="setIsSelecting(true)">
23
+            <ng-container *ngFor="let option of receiveUserList">
24
+              <nz-option *ngIf="!isLoading" [nzLabel]="option.name" [nzValue]="option.id"></nz-option>
25
+            </ng-container>
26
+            <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
27
+              <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
28
+            </nz-option>
29
+          </nz-select>
30
+        </div>
31
+        <div class="list-template__searchItem">
32
+          <span class="label">状态</span>:
33
+          <nz-select class="formItem" [nzDropdownMatchSelectWidth]="false" nzShowSearch nzAllowClear nzPlaceHolder="请选择状态" [(ngModel)]="searchDto.status">
34
+            <ng-container *ngFor="let option of stateList">
35
+              <nz-option *ngIf="!isLoading" [nzLabel]="option.name" [nzValue]="option.id"></nz-option>
36
+            </ng-container>
37
+            <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
38
+              <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
39
+            </nz-option>
40
+          </nz-select>
41
+        </div>
42
+      </div>
43
+      <div nz-col nzLg="5" class="list-template__btns">
44
+        <button nz-button class="btn default ml8" (click)='search()'>搜索</button>
45
+        <button nz-button class="btn default ml8" (click)='reset()'>重置</button>
46
+      </div>
47
+    </div>
48
+    <div class="list-template__bottom">
49
+      <nz-table class="list-template__nzTable" [nzData]="listOfData" nzSize="middle" [nzShowPagination]="false"
50
+        [nzLoading]="loading1">
51
+        <thead>
52
+          <tr class="thead">
53
+            <th nzWidth="10%">包号</th>
54
+            <th nzWidth="10%">打包人</th>
55
+            <th nzWidth="10%">打包科室</th>
56
+            <th nzWidth="10%">终点科室</th>
57
+            <th nzWidth="10%">标本数</th>
58
+            <th nzWidth="10%">配送人|配送时间</th>
59
+            <th nzWidth="10%">接收人|接收时间</th>
60
+            <th nzWidth="10%">状态</th>
61
+            <th nzWidth="10%">工单号</th>
62
+            <th nzWidth="10%">操作</th>
63
+          </tr>
64
+        </thead>
65
+        <tbody>
66
+          <tr *ngFor="let data of listOfData;let i = index">
67
+            <td>{{data.packCode}}</td>
68
+            <td>{{ data.packUserDTO?.name }}<br>{{ data.packTime | date: 'yyyy-MM-dd HH:mm'}}</td>
69
+            <td>{{data.packDeptDTO?.dept}}</td>
70
+            <td>{{ data.endDeptNames }}</td>
71
+            <td>{{data.specimenNum}}</td>
72
+            <td>{{ data.deliveryUserDTO?.name }}<br>{{ data.deliveryTime | date: 'yyyy-MM-dd HH:mm'}}</td>
73
+            <td>{{ data.receiveUserDTO?.name }}<br>{{ data.receiveTime | date: 'yyyy-MM-dd HH:mm'}}</td>
74
+            <td>{{ data.status?.name }}</td>
75
+            <td>{{ data.gdDTO?.gdcode }}</td>
76
+            <td>
77
+              <div class="coop">
78
+                <span (click)="showLogs(data)">查看日志</span>
79
+              </div>
80
+            </td>
81
+          </tr>
82
+        </tbody>
83
+      </nz-table>
84
+      <div class="list-template__pagination">
85
+        <nz-pagination [(nzPageIndex)]="pageIndex" [(nzTotal)]="listLength" [(nzPageSize)]="pageSize" nzShowSizeChanger
86
+          (nzPageIndexChange)="getList(0)" (nzPageSizeChange)="getList(0)">
87
+        </nz-pagination>
88
+      </div>
89
+    </div>
90
+  </div>
91
+</div>
92
+<!-- 操作成功/失败提示框 -->
93
+<app-prompt-modal *ngIf="promptModalShow" [content]="promptContent" [success]="ifSuccess" [show]="promptModalShow"
94
+  [info]="promptInfo">
95
+</app-prompt-modal>
96
+
97
+<!-- 查看日志 -->
98
+<app-specimen-package-log-prompt-modal
99
+  *ngIf="logPromptModalShow"
100
+  [show]="logPromptModalShow"
101
+  [id]="packId"
102
+  (closeModelHs)="closeModelLog($event)"
103
+></app-specimen-package-log-prompt-modal>

+ 176 - 0
src/app/views/specimen-package/specimen-package.component.less

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

+ 240 - 0
src/app/views/specimen-package/specimen-package.component.ts

@@ -0,0 +1,240 @@
1
+import { Component, OnInit } from "@angular/core";
2
+import { ActivatedRoute, Router } from "@angular/router";
3
+import { FormBuilder, Validators, FormGroup } from "@angular/forms";
4
+
5
+import { MainService } from "../../services/main.service";
6
+import { ToolService } from "../../services/tool.service";
7
+import { NzMessageService } from 'ng-zorro-antd';
8
+import { Subject } from 'rxjs';
9
+import { debounceTime } from 'rxjs/operators';
10
+import { startOfDay, endOfDay, format } from 'date-fns';
11
+@Component({
12
+  selector: "app-specimen-package",
13
+  templateUrl: "./specimen-package.component.html",
14
+  styleUrls: ["./specimen-package.component.less"],
15
+})
16
+export class SpecimenPackageComponent implements OnInit {
17
+  constructor(
18
+    private fb: FormBuilder,
19
+    private mainService: MainService,
20
+    private route: ActivatedRoute,
21
+    private router: Router,
22
+    private tool: ToolService,
23
+    private message: NzMessageService,
24
+  ) {}
25
+
26
+  listOfData: any[] = []; //表格数据
27
+  pageIndex: number = 1; //表格当前页码
28
+  pageSize: number = 10; //表格每页展示条数
29
+  listLength: number = 10; //表格总数据量
30
+  modal: boolean = false; //新增/编辑模态框
31
+  add: boolean; //true:新增;false:编辑
32
+  validateForm: FormGroup; //新增/编辑表单
33
+  coopData: any; //当前操作列
34
+  currentHospital; //当前院区
35
+
36
+  btnLoading: boolean = false; //提交按钮loading状态
37
+
38
+  promptContent: string; //操作提示框提示信息
39
+  ifSuccess: boolean; //操作成功/失败
40
+  promptInfo: string; //操作结果提示信息
41
+  promptModalShow: boolean; //操作提示框是否展示
42
+  modelName = ""; //模态框名称
43
+
44
+  searchTimerSubject = new Subject(); //防抖
45
+  showDropdown:boolean = false;
46
+
47
+  dateRange: any = []; //发起时间
48
+
49
+  ngOnInit() {
50
+    //防抖
51
+    this.searchTimerSubject.pipe(debounceTime(500)).subscribe((v) => {
52
+      let fun = v[0];
53
+      fun.call(this, v[1]);
54
+    });
55
+    this.currentHospital = this.tool.getCurrentHospital();
56
+    this.coopBtns = this.tool.initCoopBtns(this.route);
57
+    this.getList(1);
58
+    this.getStatus();
59
+  }
60
+
61
+  // 初始化增删改按钮
62
+  coopBtns: any = {};
63
+
64
+  // 查看
65
+  detail(e, id) {
66
+    e.stopPropagation();
67
+    this.router.navigateByUrl("/main/patientInspectLog/patientInspectLogDetail/" + id);
68
+  }
69
+
70
+  // 日期选择
71
+  onCalendarChangeDate(dateArr){
72
+    if(dateArr.length == 2){
73
+      this.dateRange = [startOfDay(dateArr[0]), endOfDay(dateArr[1])];
74
+    }
75
+  }
76
+
77
+  // 搜索
78
+  search() {
79
+    this.getList(1);
80
+  }
81
+  // 重置
82
+  reset() {
83
+    this.searchDto = {};
84
+    this.dateRange = [];
85
+    this.getList(1);
86
+  }
87
+
88
+  // 表格数据
89
+  searchDto: any = {};
90
+  loading1 = false;
91
+  getList(type) {
92
+    if (type == 1) {
93
+      this.pageIndex = 1;
94
+    }
95
+    let data = {
96
+      idx: this.pageIndex - 1,
97
+      sum: this.pageSize,
98
+      pathologyPackInfo: {
99
+        hosId: this.currentHospital.id,
100
+        busiType: 'specimen',//标本打包
101
+        status: this.searchDto.status ? { id: this.searchDto.status } : undefined,
102
+        receiveUser: this.searchDto.receiveUser || undefined,
103
+        packDept: this.searchDto.packDept || undefined,
104
+        startTime: this.dateRange.length ? format(this.dateRange[0], 'yyyy-MM-dd HH:mm:ss') : undefined,
105
+        endTime: this.dateRange.length ? format(this.dateRange[1], 'yyyy-MM-dd HH:mm:ss') : undefined,
106
+      },
107
+    };
108
+    this.loading1 = true;
109
+    this.mainService
110
+      .getFetchDataList("simple/data", "pathologyPackInfo", data)
111
+      .subscribe((data) => {
112
+        this.loading1 = false;
113
+        if (data.status == 200) {
114
+          let listOfData = data.list || [];
115
+          listOfData.forEach((v) => {
116
+            if(v.endDeptList){
117
+              v.endDeptNames = v.endDeptList.map(v => v.dept).toString();
118
+            }else{
119
+              v.endDeptNames = "";
120
+            }
121
+          })
122
+          this.listOfData = listOfData;
123
+          this.listLength = data.totalNum;
124
+        }else{
125
+          this.message.error(data.msg || "请求数据失败");
126
+        }
127
+      });
128
+  }
129
+
130
+  // 防抖
131
+  isLoading = false;
132
+  isSelecting:boolean = false; // 是否在选中状态
133
+  searchTimer(fun, e) {
134
+    if (this.isSelecting) {
135
+      this.isSelecting = false; // 重置标志
136
+      return; // 跳过处理
137
+    }
138
+    this.isLoading = true;
139
+    this.searchTimerSubject.next([fun, e]);
140
+  }
141
+
142
+  // 搜索
143
+  changeInp(type, e) {
144
+    if(type === 'department'){
145
+      this.searchTimer(this.getDeptList, e);
146
+    }else if(type === 'patient'){
147
+      this.searchTimer(this.getReceiveUserList, e);
148
+    }
149
+  }
150
+
151
+  // 设置标志
152
+  setIsSelecting(flag){
153
+    this.isSelecting = flag; // 设置标志
154
+  }
155
+
156
+  openChangeDept(flag){
157
+    flag && this.setIsSelecting(false);
158
+    flag && this.getDeptList();
159
+  }
160
+
161
+  // 获取科室
162
+  deptList: any = [];
163
+  getDeptList(e = undefined) {
164
+    let postData = {
165
+      idx: 0,
166
+      sum: 20,
167
+      department: {
168
+        searchType: 1,// 简单查询
169
+        cascadeHosId: this.currentHospital.id,
170
+        dept: e,
171
+      }
172
+    };
173
+    this.isLoading = true;
174
+    this.mainService
175
+      .getFetchDataList("simple/data", "department", postData)
176
+      .subscribe((data) => {
177
+        this.isLoading = false;
178
+        this.deptList = data.list || [];
179
+      });
180
+  }
181
+
182
+  openChangePatient(flag){
183
+    flag && this.setIsSelecting(false);
184
+    flag && this.getReceiveUserList();
185
+  }
186
+
187
+  // 获取收取人
188
+  receiveUserList: any = [];
189
+  getReceiveUserList(e = undefined) {
190
+    let postData = {
191
+      idx: 0,
192
+      sum: 20,
193
+      user: {
194
+        hospital: { id: this.currentHospital.id },
195
+        name: e,
196
+      }
197
+    };
198
+    this.isLoading = true;
199
+    this.mainService
200
+      .getFetchDataList("simple/data", "user", postData)
201
+      .subscribe((data) => {
202
+        this.isLoading = false;
203
+        this.receiveUserList = data.list || [];
204
+      });
205
+  }
206
+
207
+  //获取状态
208
+  stateList:any[] = [];
209
+  getStatus() {
210
+    this.mainService
211
+    .getDictionary('list', 'pathology_pack_status')
212
+    .subscribe((data) => {
213
+      this.stateList = data || [];
214
+    });
215
+  }
216
+
217
+  // 展示信息提示框(con:提示信息,success:操作是否成功,promptInfo:操作结果提示信息)
218
+  showPromptModal(con, success, promptInfo?) {
219
+    this.promptModalShow = false;
220
+    this.promptContent = con;
221
+    this.ifSuccess = success;
222
+    this.promptInfo = promptInfo;
223
+    setTimeout(() => {
224
+      this.promptModalShow = true;
225
+    }, 100);
226
+    this.getList(0);
227
+  }
228
+
229
+  // 查看日志弹窗
230
+  logPromptModalShow = false; //弹窗开关
231
+  packId = ""; //查看记录携带id
232
+  showLogs(data) {
233
+    this.packId = data.id;
234
+    this.logPromptModalShow = true;
235
+  }
236
+  // 关闭日志弹窗
237
+  closeModelLog(e) {
238
+    this.logPromptModalShow = JSON.parse(e).show;
239
+  }
240
+}

+ 19 - 0
src/app/views/specimen-package/specimen-package.module.ts

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

+ 26 - 3
src/assets/iconfont/demo_index.html

@@ -55,6 +55,12 @@
55 55
           <ul class="icon_lists dib-box">
56 56
           
57 57
             <li class="dib">
58
+              <span class="icon icon_transport">&#xe674;</span>
59
+                <div class="name">打包</div>
60
+                <div class="code-name">&amp;#xe674;</div>
61
+              </li>
62
+          
63
+            <li class="dib">
58 64
               <span class="icon icon_transport">&#xe670;</span>
59 65
                 <div class="name">陪护管理</div>
60 66
                 <div class="code-name">&amp;#xe670;</div>
@@ -1074,9 +1080,9 @@
1074 1080
 <pre><code class="language-css"
1075 1081
 >@font-face {
1076 1082
   font-family: 'icon_transport';
1077
-  src: url('iconfont.woff2?t=1743992402666') format('woff2'),
1078
-       url('iconfont.woff?t=1743992402666') format('woff'),
1079
-       url('iconfont.ttf?t=1743992402666') format('truetype');
1083
+  src: url('iconfont.woff2?t=1746761473702') format('woff2'),
1084
+       url('iconfont.woff?t=1746761473702') format('woff'),
1085
+       url('iconfont.ttf?t=1746761473702') format('truetype');
1080 1086
 }
1081 1087
 </code></pre>
1082 1088
           <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@@ -1103,6 +1109,15 @@
1103 1109
         <ul class="icon_lists dib-box">
1104 1110
           
1105 1111
           <li class="dib">
1112
+            <span class="icon icon_transport transport-dabao"></span>
1113
+            <div class="name">
1114
+              打包
1115
+            </div>
1116
+            <div class="code-name">.transport-dabao
1117
+            </div>
1118
+          </li>
1119
+          
1120
+          <li class="dib">
1106 1121
             <span class="icon icon_transport transport-peihuguanli"></span>
1107 1122
             <div class="name">
1108 1123
               陪护管理
@@ -2634,6 +2649,14 @@
2634 2649
           
2635 2650
             <li class="dib">
2636 2651
                 <svg class="icon svg-icon" aria-hidden="true">
2652
+                  <use xlink:href="#transport-dabao"></use>
2653
+                </svg>
2654
+                <div class="name">打包</div>
2655
+                <div class="code-name">#transport-dabao</div>
2656
+            </li>
2657
+          
2658
+            <li class="dib">
2659
+                <svg class="icon svg-icon" aria-hidden="true">
2637 2660
                   <use xlink:href="#transport-peihuguanli"></use>
2638 2661
                 </svg>
2639 2662
                 <div class="name">陪护管理</div>

+ 7 - 3
src/assets/iconfont/iconfont.css

@@ -1,8 +1,8 @@
1 1
 @font-face {
2 2
   font-family: "icon_transport"; /* Project id 4543613 */
3
-  src: url('iconfont.woff2?t=1743992402666') format('woff2'),
4
-       url('iconfont.woff?t=1743992402666') format('woff'),
5
-       url('iconfont.ttf?t=1743992402666') format('truetype');
3
+  src: url('iconfont.woff2?t=1746761473702') format('woff2'),
4
+       url('iconfont.woff?t=1746761473702') format('woff'),
5
+       url('iconfont.ttf?t=1746761473702') format('truetype');
6 6
 }
7 7
 
8 8
 .icon_transport {
@@ -13,6 +13,10 @@
13 13
   -moz-osx-font-smoothing: grayscale;
14 14
 }
15 15
 
16
+.transport-dabao:before {
17
+  content: "\e674";
18
+}
19
+
16 20
 .transport-peihuguanli:before {
17 21
   content: "\e670";
18 22
 }

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 1
src/assets/iconfont/iconfont.js


+ 7 - 0
src/assets/iconfont/iconfont.json

@@ -6,6 +6,13 @@
6 6
   "description": "",
7 7
   "glyphs": [
8 8
     {
9
+      "icon_id": "9807812",
10
+      "name": "打包",
11
+      "font_class": "dabao",
12
+      "unicode": "e674",
13
+      "unicode_decimal": 58996
14
+    },
15
+    {
9 16
       "icon_id": "24101601",
10 17
       "name": "陪护管理",
11 18
       "font_class": "peihuguanli",

BIN
src/assets/iconfont/iconfont.ttf


BIN
src/assets/iconfont/iconfont.woff


BIN
src/assets/iconfont/iconfont.woff2