maotao 1 月之前
父節點
當前提交
7c67dc6abc

+ 11 - 2
src/app/services/main.service.ts

@@ -150,7 +150,7 @@ export class MainService {
150 150
       headers: this.headers,
151 151
     });
152 152
   }
153
-	
153
+
154 154
 	// 通用操作configuration信息 有操作类型(新增/更新/删除)//coop:操作类型addData:新增,updData更新,rmvData删除
155 155
 	apiPublicData(coop, type, data): any {
156 156
 	  return this.http.post(
@@ -159,7 +159,7 @@ export class MainService {
159 159
 	    { headers: this.headers }
160 160
 	  );
161 161
 	}
162
-	
162
+
163 163
   // 权限相关
164 164
   getPermission(type): any {
165 165
     return this.http.get(host.host + "/permission/roleMenu/" + type, {
@@ -180,6 +180,15 @@ export class MainService {
180 180
       headers: this.headers,
181 181
     });
182 182
   }
183
+
184
+  // 自定义请求 post-导出
185
+  postExportCustom(type, info, data): any {
186
+    return this.http.post(host.host + "/" + type + "/" + info, data, {
187
+      headers: this.exportHeader,
188
+      responseType: "arraybuffer",
189
+    });
190
+  }
191
+
183 192
   // 科室二维码打印flag=1
184 193
   postCustomCode(type, info, data): any {
185 194
     return this.http.post(host.host + "/" + type + "/" + info + "/1", data, {

+ 5 - 0
src/app/views/new-statistics/components/query-range/query-range.component.ts

@@ -103,6 +103,7 @@ export class QueryRangeComponent implements OnInit {
103 103
   // 选择院区
104 104
   changeHospital(hosId){
105 105
     if(this.validateForm.value.queryType == 3){
106
+      this.dutyList = [];
106 107
       this.getDutyList(hosId);
107 108
     }
108 109
   }
@@ -140,6 +141,10 @@ export class QueryRangeComponent implements OnInit {
140 141
   // 获取所有的责任部门
141 142
   dutyList:any[] = [];
142 143
   getDutyList(parentId){
144
+    if(!parentId){
145
+      this.dutyList = [];
146
+      return;
147
+    }
143 148
     let postData: any = {
144 149
       idx: 0,
145 150
       sum: 99999,

+ 97 - 0
src/app/views/new-statistics/components/search-more/search-more.component.html

@@ -0,0 +1,97 @@
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
+      <form nz-form [formGroup]="validateForm" class="addForm">
7
+        <nz-form-item [hidden]="!fieldConfig.config.groupAndUser">
8
+          <nz-form-label [nzSpan]="6" nzFor="groupId">维&nbsp;&nbsp;修&nbsp;&nbsp;组</nz-form-label>
9
+          <nz-form-control [nzSpan]="18" nzErrorTip="请选择维修组!">
10
+            <nz-select [nzDropdownMatchSelectWidth]="false" nzAllowClear nzServerSearch nzShowSearch (nzOnSearch)="changeGroupInp($event)" formControlName="groupId" nzPlaceHolder="请选择维修组" (nzOpenChange)="openChangeGroup($event)" (ngModelChange)="changeGroup($event)">
11
+              <ng-container *ngFor="let option of groupList">
12
+                <nz-option *ngIf="!isLoading" [nzLabel]="option.groupName" [nzValue]="option.id"></nz-option>
13
+              </ng-container>
14
+              <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
15
+                <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
16
+              </nz-option>
17
+            </nz-select>
18
+          </nz-form-control>
19
+        </nz-form-item>
20
+
21
+        <nz-form-item [hidden]="!fieldConfig.config.groupAndUser">
22
+          <nz-form-label [nzSpan]="6" nzFor="groupId">维修人员</nz-form-label>
23
+          <nz-form-control [nzSpan]="18" nzErrorTip="请选择维修人员!">
24
+            <nz-select [nzDropdownMatchSelectWidth]="false" nzAllowClear nzServerSearch nzShowSearch (nzOnSearch)="changeUserInp($event)" formControlName="userId" nzPlaceHolder="请选择维修人员" (nzOpenChange)="openChangeUser($event)">
25
+              <ng-container *ngFor="let option of userList">
26
+                <nz-option *ngIf="!isLoading" [nzLabel]="option.name" [nzValue]="option.id"></nz-option>
27
+              </ng-container>
28
+              <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
29
+                <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
30
+              </nz-option>
31
+            </nz-select>
32
+          </nz-form-control>
33
+        </nz-form-item>
34
+
35
+        <nz-form-item [hidden]="!fieldConfig.config.category123">
36
+          <nz-form-label [nzSpan]="6" nzFor="category1Id">一级分类</nz-form-label>
37
+          <nz-form-control [nzSpan]="18" nzErrorTip="请选择一级分类!">
38
+            <nz-select [nzDropdownMatchSelectWidth]="false" nzAllowClear nzServerSearch nzShowSearch (nzOnSearch)="changeCategory1Inp($event)" formControlName="category1Id" nzPlaceHolder="请选择一级分类" (nzOpenChange)="openChangeCategory1($event)" (ngModelChange)="changeCategory1($event)">
39
+              <ng-container *ngFor="let option of category1List">
40
+                <nz-option *ngIf="!isLoading" [nzLabel]="option.category" [nzValue]="option.id"></nz-option>
41
+              </ng-container>
42
+              <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
43
+                <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
44
+              </nz-option>
45
+            </nz-select>
46
+          </nz-form-control>
47
+        </nz-form-item>
48
+
49
+        <nz-form-item [hidden]="!fieldConfig.config.category123">
50
+          <nz-form-label [nzSpan]="6" nzFor="category2Id">二级分类</nz-form-label>
51
+          <nz-form-control [nzSpan]="18" nzErrorTip="请选择二级分类!">
52
+            <nz-select [nzDropdownMatchSelectWidth]="false" nzAllowClear nzServerSearch nzShowSearch (nzOnSearch)="changeCategory2Inp($event)" formControlName="category2Id" nzPlaceHolder="请选择二级分类" (nzOpenChange)="openChangeCategory2($event)" (ngModelChange)="changeCategory2($event)">
53
+              <ng-container *ngFor="let option of category2List">
54
+                <nz-option *ngIf="!isLoading" [nzLabel]="option.category" [nzValue]="option.id"></nz-option>
55
+              </ng-container>
56
+              <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
57
+                <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
58
+              </nz-option>
59
+            </nz-select>
60
+          </nz-form-control>
61
+        </nz-form-item>
62
+
63
+        <nz-form-item [hidden]="!fieldConfig.config.category123">
64
+          <nz-form-label [nzSpan]="6" nzFor="category3Id">三级分类</nz-form-label>
65
+          <nz-form-control [nzSpan]="18" nzErrorTip="请选择三级分类!">
66
+            <nz-select [nzDropdownMatchSelectWidth]="false" nzAllowClear nzServerSearch nzShowSearch (nzOnSearch)="changeCategory3Inp($event)" formControlName="category3Id" nzPlaceHolder="请选择三级分类" (nzOpenChange)="openChangeCategory3($event)">
67
+              <ng-container *ngFor="let option of category3List">
68
+                <nz-option *ngIf="!isLoading" [nzLabel]="option.category" [nzValue]="option.id"></nz-option>
69
+              </ng-container>
70
+              <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
71
+                <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
72
+              </nz-option>
73
+            </nz-select>
74
+          </nz-form-control>
75
+        </nz-form-item>
76
+
77
+        <nz-form-item [hidden]="!fieldConfig.config.source">
78
+          <nz-form-label [nzSpan]="6" nzFor="sourceId">故障来源</nz-form-label>
79
+          <nz-form-control [nzSpan]="18" nzErrorTip="请选择故障来源!">
80
+            <nz-select [nzDropdownMatchSelectWidth]="false" nzAllowClear formControlName="sourceId" nzPlaceHolder="请选择故障来源">
81
+              <ng-container *ngFor="let option of sourceList">
82
+                <nz-option *ngIf="!isLoading" [nzLabel]="option.name" [nzValue]="option.id"></nz-option>
83
+              </ng-container>
84
+              <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
85
+                <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
86
+              </nz-option>
87
+            </nz-select>
88
+          </nz-form-control>
89
+        </nz-form-item>
90
+      </form>
91
+    </div>
92
+    <div class="display_flex justify-content_flex-center">
93
+      <button nz-button nzType="default" (click)="hideModal()">取消</button>
94
+      <button nzType="primary" nz-button (click)="submitForm()">确认</button>
95
+    </div>
96
+  </div>
97
+</div>

+ 116 - 0
src/app/views/new-statistics/components/search-more/search-more.component.less

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

+ 318 - 0
src/app/views/new-statistics/components/search-more/search-more.component.ts

@@ -0,0 +1,318 @@
1
+import { Subject } from 'rxjs';
2
+import { debounceTime } from 'rxjs/operators';
3
+import { ToolService } from './../../../../services/tool.service';
4
+import { Component, OnInit, Output, Input } from '@angular/core';
5
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
6
+import { EventEmitter } from '@angular/core';
7
+import { MainService } from 'src/app/services/main.service';
8
+
9
+@Component({
10
+  selector: 'app-search-more',
11
+  templateUrl: './search-more.component.html',
12
+  styleUrls: ['./search-more.component.less']
13
+})
14
+export class SearchMoreComponent implements OnInit {
15
+  @Output() submitEvent = new EventEmitter();
16
+  @Output() cancelEvent = new EventEmitter();
17
+  @Input() fieldConfig: any = { fields: [], config: [] };
18
+  @Input() hosId: any;
19
+  @Input() parentDutyId: any;
20
+  @Input() dutyId: any;
21
+  @Input() queryType: any;
22
+  validateForm: FormGroup;//表单
23
+  searchTimerSubject = new Subject();
24
+  constructor(
25
+    private fb: FormBuilder,
26
+    private tool: ToolService,
27
+    private mainService: MainService,
28
+  ) { }
29
+
30
+  ngOnInit() {
31
+    this.searchTimerSubject.pipe(debounceTime(500)).subscribe((v) => {
32
+      let fun = v[0];
33
+      fun.call(this, v[1]);
34
+    });
35
+    this.initForm();
36
+    this.getSourceList();
37
+  }
38
+  // 隐藏模态框
39
+  hideModal() {
40
+    this.cancelEvent.emit()
41
+  }
42
+  // 初始化form表单
43
+  initForm() {
44
+    this.groupList = this.fieldConfig.fields.groupDTO ? [this.fieldConfig.fields.groupDTO] : [];
45
+    this.userList = this.fieldConfig.fields.userDTO ? [this.fieldConfig.fields.userDTO] : [];
46
+    this.category1List = this.fieldConfig.fields.category1DTO ? [this.fieldConfig.fields.category1DTO] : [];
47
+    this.category2List = this.fieldConfig.fields.category2DTO ? [this.fieldConfig.fields.category2DTO] : [];
48
+    this.category3List = this.fieldConfig.fields.category3DTO ? [this.fieldConfig.fields.category3DTO] : [];
49
+    this.sourceList = this.fieldConfig.fields.sourceDTO ? [this.fieldConfig.fields.sourceDTO] : [];
50
+
51
+    this.validateForm = this.fb.group({
52
+      groupId: [this.fieldConfig.fields.groupId || null],
53
+      userId: [this.fieldConfig.fields.userId === undefined ? null : this.fieldConfig.fields.userId],
54
+      category1Id: [this.fieldConfig.fields.category1DTO ? this.fieldConfig.fields.category1DTO.id  : null],
55
+      category2Id: [this.fieldConfig.fields.category2DTO ? this.fieldConfig.fields.category2DTO.id  : null],
56
+      category3Id: [this.fieldConfig.fields.category3DTO ? this.fieldConfig.fields.category3DTO.id  : null],
57
+      sourceId: [this.fieldConfig.fields.sourceId || null],
58
+    });
59
+  }
60
+  // 表单提交
61
+  submitForm(): void {
62
+    for (const i in this.validateForm.controls) {
63
+      this.validateForm.controls[i].markAsDirty({ onlySelf: true });
64
+      this.validateForm.controls[i].updateValueAndValidity();
65
+    }
66
+    if (this.validateForm.invalid) return;
67
+
68
+    let categoryId, hierarchy;
69
+    if(this.validateForm.value.category3Id){
70
+      categoryId = this.validateForm.value.category3Id;
71
+      hierarchy = 3;
72
+    }else if(this.validateForm.value.category2Id){
73
+      categoryId = this.validateForm.value.category2Id;
74
+      hierarchy = 2;
75
+    }else if(this.validateForm.value.category1Id){
76
+      categoryId = this.validateForm.value.category1Id;
77
+      hierarchy = 1;
78
+    }
79
+    let fields:any = {}
80
+    if(this.fieldConfig.config.groupAndUser){
81
+      fields.groupId = this.validateForm.value.groupId;
82
+      fields.groupDTO = this.groupList.find(item => item.id == this.validateForm.value.groupId);
83
+      fields.userId = this.validateForm.value.userId;
84
+      fields.userDTO = this.userList.find(item => item.id == this.validateForm.value.userId);
85
+    }
86
+    if(this.fieldConfig.config.category123){
87
+      fields.categoryId = categoryId;
88
+      fields.hierarchy = hierarchy;
89
+      fields.category1DTO = this.category1List.find(item => item.id == this.validateForm.value.category1Id);
90
+      fields.category2DTO = this.category2List.find(item => item.id == this.validateForm.value.category2Id);
91
+      fields.category3DTO = this.category3List.find(item => item.id == this.validateForm.value.category3Id);
92
+    }
93
+    if(this.fieldConfig.config.source){
94
+      fields.sourceId = this.validateForm.value.sourceId;
95
+      fields.sourceDTO = this.sourceList.find(item => item.id == this.validateForm.value.sourceId);
96
+    }
97
+    this.submitEvent.emit(fields);
98
+    this.hideModal();
99
+  }
100
+
101
+  get getHosId(){
102
+    return this.parentDutyId || this.dutyId || this.hosId;
103
+  }
104
+
105
+  // 防抖
106
+  isLoading = false;
107
+  searchTimer(fun, e) {
108
+    this.isLoading = true;
109
+    this.searchTimerSubject.next([fun, e]);
110
+  }
111
+
112
+  // =================维修组===================
113
+
114
+  // 维修组搜索
115
+  changeGroupInp(e) {
116
+    this.searchTimer(this.getGroupList, e);
117
+  }
118
+
119
+  // 获取维修组列表
120
+  groupList:any[] = [];
121
+  getGroupList(keyword?){
122
+    let postData: any = {
123
+      idx: 0,
124
+      sum: 20,
125
+      group2: {
126
+        hospitals: this.getHosId,
127
+        groupName: keyword,
128
+        type: 3,
129
+      },
130
+    };
131
+    this.isLoading = true;
132
+    this.mainService.getFetchDataList("simple/data", "group2", postData).subscribe(result => {
133
+      this.isLoading = false;
134
+      if(result.status == 200){
135
+        this.groupList = result.list || [];
136
+      }else{
137
+        this.groupList = [];
138
+      }
139
+    });
140
+  }
141
+  openChangeGroup(flag){
142
+    flag && this.getGroupList();
143
+  }
144
+
145
+  changeGroup(id){
146
+    this.userList = [];
147
+    this.validateForm.controls.userId.setValue(null);
148
+    this.getUserList('', id);
149
+  }
150
+
151
+  // =================维修人员===================
152
+
153
+  // 维修人员搜索
154
+  changeUserInp(e) {
155
+    this.searchTimer(this.getUserList, e);
156
+  }
157
+
158
+  // 获取维修人员列表
159
+  userList:any[] = [];
160
+  getUserList(keyword = '', groupId = ''){
161
+    if(!groupId){
162
+      this.isLoading = false;
163
+      this.userList = [];
164
+      return;
165
+    }
166
+    let postData: any = {
167
+      idx: 0,
168
+      sum: 20,
169
+      user: {
170
+        hospitals: this.getHosId,
171
+        groupName: keyword,
172
+        type: 3,
173
+      },
174
+    };
175
+    this.isLoading = true;
176
+    this.mainService.getFetchDataList("simple/data", "user", postData).subscribe(result => {
177
+      this.isLoading = false;
178
+      if(result.status == 200){
179
+        this.userList = result.list || [];
180
+      }else{
181
+        this.userList = [];
182
+      }
183
+    });
184
+  }
185
+  openChangeUser(flag){
186
+    flag && this.getUserList('', this.validateForm.value.groupId);
187
+  }
188
+
189
+  // =================一级分类===================
190
+
191
+  // 一级分类搜索
192
+  changeCategory1Inp(e) {
193
+    this.searchTimer(this.getCategory1List, e);
194
+  }
195
+
196
+  // 获取一级分类列表
197
+  category1List:any[] = [];
198
+  getCategory1List(keyword?){
199
+    let postData: any = {
200
+      category: {
201
+        category: keyword,
202
+        selectType: 'mutlQuery',
203
+        dutyIds: this.queryType == 3 ? this.dutyId : undefined,
204
+        parentDutyId: this.queryType == 3 ? this.parentDutyId : undefined,
205
+        hierarchy: 1,
206
+      },
207
+    };
208
+    this.isLoading = true;
209
+    this.mainService.incidentPost("listIncidentCategory", postData).subscribe(result => {
210
+      this.isLoading = false;
211
+      if(result.status == 200){
212
+        this.category1List = result.data || [];
213
+      }else{
214
+        this.category1List = [];
215
+      }
216
+    });
217
+  }
218
+  openChangeCategory1(flag){
219
+    flag && this.getCategory1List();
220
+  }
221
+
222
+  changeCategory1(id){
223
+    this.category2List = [];
224
+    this.validateForm.controls.category2Id.setValue(null);
225
+    this.getCategory2List('', id);
226
+
227
+    this.category3List = [];
228
+    this.validateForm.controls.category3Id.setValue(null);
229
+  }
230
+
231
+  // =================二级分类===================
232
+
233
+  // 二级分类搜索
234
+  changeCategory2Inp(e) {
235
+    this.searchTimer(this.getCategory2List, e);
236
+  }
237
+
238
+  // 获取二级分类列表
239
+  category2List:any[] = [];
240
+  getCategory2List(keyword = '', parentId = ''){
241
+    if(!parentId){
242
+      this.isLoading = false;
243
+      this.category2List = [];
244
+      return;
245
+    }
246
+    let postData: any = {
247
+      category: {
248
+        category: keyword,
249
+        selectType: 'mutlQuery',
250
+        parent: { id: parentId },
251
+      },
252
+    };
253
+    this.isLoading = true;
254
+    this.mainService.incidentPost("listIncidentCategory", postData).subscribe(result => {
255
+      this.isLoading = false;
256
+      if(result.status == 200){
257
+        this.category2List = result.data || [];
258
+      }else{
259
+        this.category2List = [];
260
+      }
261
+    });
262
+  }
263
+  openChangeCategory2(flag){
264
+    flag && this.getCategory2List('', this.validateForm.value.category1Id);
265
+  }
266
+
267
+  changeCategory2(id){
268
+    this.category3List = [];
269
+    this.validateForm.controls.category3Id.setValue(null);
270
+    this.getCategory3List('', id);
271
+  }
272
+
273
+  // =================三级分类===================
274
+
275
+  // 三级分类搜索
276
+  changeCategory3Inp(e) {
277
+    this.searchTimer(this.getCategory3List, e);
278
+  }
279
+
280
+  // 获取三级分类列表
281
+  category3List:any[] = [];
282
+  getCategory3List(keyword = '', parentId = ''){
283
+    if(!parentId){
284
+      this.isLoading = false;
285
+      this.category3List = [];
286
+      return;
287
+    }
288
+    let postData: any = {
289
+      category: {
290
+        category: keyword,
291
+        selectType: 'mutlQuery',
292
+        parent: { id: parentId },
293
+      },
294
+    };
295
+    this.isLoading = true;
296
+    this.mainService.incidentPost("listIncidentCategory", postData).subscribe(result => {
297
+      this.isLoading = false;
298
+      if(result.status == 200){
299
+        this.category3List = result.data || [];
300
+      }else{
301
+        this.category3List = [];
302
+      }
303
+    });
304
+  }
305
+  openChangeCategory3(flag){
306
+    flag && this.getCategory3List('', this.validateForm.value.category2Id);
307
+  }
308
+
309
+  // =================故障来源===================
310
+
311
+  // 获取故障来源列表
312
+  sourceList:any[] = [];
313
+  getSourceList(){
314
+    this.mainService.getDictionary("list", "incident_source").subscribe(result => {
315
+      this.sourceList = result;
316
+    });
317
+  }
318
+}

+ 20 - 0
src/app/views/new-statistics/components/search-more/search-more.module.ts

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

+ 46 - 6
src/app/views/new-statistics/maintenance-statistics/incident-statistics/incident-statistics.component.html

@@ -5,14 +5,34 @@
5 5
       <nz-range-picker [(ngModel)]="dateRange" [nzAllowClear]="false" (ngModelChange)="changeDate($event)" (nzOnCalendarChange)="onCalendarChangeDate($event)">
6 6
       </nz-range-picker>
7 7
     </div>
8
+    <div class="searchDataItem">
9
+      <span class="label">报修科室</span>:
10
+      <nz-select class="selectItem" [nzDropdownMatchSelectWidth]="false" nzServerSearch nzShowSearch (nzOnSearch)="changeRepairDeptInp($event)" nzAllowClear nzPlaceHolder="请选择报修科室" [(ngModel)]="repairDeptId" (nzOpenChange)="openChangeRepairDept($event)">
11
+      <ng-container *ngFor="let option of repairDeptList">
12
+        <nz-option *ngIf="!isLoading" [nzLabel]="option.dept" [nzValue]="option.id"></nz-option>
13
+      </ng-container>
14
+      <nz-option *ngIf="isLoading" nzDisabled nzCustomContent>
15
+        <i nz-icon nzType="loading" class="loading-icon"></i> 搜索中...
16
+      </nz-option>
17
+    </nz-select>
18
+    </div>
8 19
   </div>
9 20
   <div class="operation">
10
-    <button nz-button class="btn default" (click)="search(1)">搜索</button>
11
-    <button nz-button class="btn default ml8" (click)="excelExport()">导出</button>
21
+    <i class="icon_transport transport-gengduo" (click)="showMore()"></i>
22
+    <button nz-button class="btn default" (click)="search()">查询</button>
12 23
     <button nz-button class="btn default ml8" (click)="reset()">重置</button>
24
+    <button nz-button class="btn default ml8" (click)="excelExport()" [nzLoading]="excelExportLoading">导出</button>
13 25
   </div>
14 26
 </div>
15
-<nz-table [nzData]="listOfData" nzSize="middle" [nzShowPagination]="false" [nzLoading]="loading1">
27
+<div class="moreFilter" *ngIf="fieldConfig.fields.groupDTO || fieldConfig.fields.userDTO || fieldConfig.fields.category1DTO || fieldConfig.fields.category2DTO || fieldConfig.fields.category3DTO || fieldConfig.fields.sourceDTO">
28
+  <span>{{fieldConfig.fields.groupDTO?.groupName}}</span>
29
+  <span>{{fieldConfig.fields.userDTO?.name}}</span>
30
+  <span>{{fieldConfig.fields.category1DTO?.category}}</span>
31
+  <span>{{fieldConfig.fields.category2DTO?.category}}</span>
32
+  <span>{{fieldConfig.fields.category3DTO?.category}}</span>
33
+  <span>{{fieldConfig.fields.sourceDTO?.name}}</span>
34
+</div>
35
+<nz-table class="table" [nzData]="listOfData" nzSize="middle" [nzShowPagination]="false" [nzLoading]="loading1" [nzScroll]="{ y: tableHeight + 'px' }" [nzFooter]="footerTpl">
16 36
   <thead (nzSortChange)="sort($event)" nzSingleSort>
17 37
     <tr>
18 38
       <th nzWidth="10%" nzShowSort nzSortKey="startDate" [(nzSort)]="sortCurrent.startDate">时间</th>
@@ -29,7 +49,7 @@
29 49
     </tr>
30 50
   </thead>
31 51
   <tbody>
32
-    <tr *ngFor="let data of listOfData; let index = index">
52
+    <tr *ngFor="let data of listOfData">
33 53
       <td>{{ data.startDate }}</td>
34 54
       <td>{{ data.sum }}</td>
35 55
       <td>{{ data.avgResponseTime }}</td>
@@ -43,7 +63,27 @@
43 63
       <td>{{ data.favorableRate }}</td>
44 64
     </tr>
45 65
   </tbody>
66
+  <ng-template #footerTpl>
67
+    <table class="footTable">
68
+      <tr *ngFor="let data of listOfDataEnd">
69
+        <td style="width: 10%">{{ data.startDate }}</td>
70
+        <td style="width: 9%">{{ data.sum }}</td>
71
+        <td style="width: 9%">{{ data.avgResponseTime }}</td>
72
+        <td style="width: 9%">{{ data.avgResolvedTime }}</td>
73
+        <td style="width: 9%">{{ data.resolvedOverNum }}</td>
74
+        <td style="width: 9%">{{ data.overTimeNum }}</td>
75
+        <td style="width: 9%">{{ data.consumablePrice }}</td>
76
+        <td style="width: 9%">{{ data.workHourPrice }}</td>
77
+        <td style="width: 9%">{{ data.totalPrice }}</td>
78
+        <td style="width: 9%">{{ data.negativeNum }}</td>
79
+        <td style="width: 9%">{{ data.favorableRate }}</td>
80
+      </tr>
81
+    </table>
82
+  </ng-template>
46 83
 </nz-table>
47
-<div>
48
-  <nz-pagination [(nzPageIndex)]="pageIndex" [(nzTotal)]="listLength" nzShowSizeChanger [(nzPageSize)]="pageSize" (nzPageIndexChange)="getList(pageIndex, sortCurrentKey, sortCurrentValue)" (nzPageSizeChange)="getList(pageIndex, sortCurrentKey, sortCurrentValue)"></nz-pagination>
84
+<div class="pagination">
85
+  <nz-pagination [(nzPageIndex)]="pageIndex" [(nzTotal)]="listLength" [(nzPageSize)]="pageSize" (nzPageIndexChange)="getList(pageIndex, sortCurrentKey, sortCurrentValue)" (nzPageSizeChange)="getList(pageIndex, sortCurrentKey, sortCurrentValue)"></nz-pagination>
49 86
 </div>
87
+
88
+<!-- 详细搜索 -->
89
+<app-search-more [fieldConfig]="fieldConfig" *ngIf="showSearchMore" [hosId]="hosId" [queryType]="queryType"  [dutyId]="dutyId"  [parentDutyId]="parentDutyId" (cancelEvent)="cancelEvent()" (submitEvent)="submitEvent($event)"></app-search-more>

+ 50 - 0
src/app/views/new-statistics/maintenance-statistics/incident-statistics/incident-statistics.component.less

@@ -5,17 +5,67 @@
5 5
   right: 0;
6 6
   bottom: 0;
7 7
   left: 0;
8
+  ::ng-deep .ant-table-footer{
9
+    padding: 16px 0;
10
+    width: calc(100% - 16px);
11
+    font-weight: bold;
12
+  }
13
+  tr, th{
14
+    text-align: center;
15
+  }
8 16
   .searchDataWrap{
9 17
     display: flex;
10 18
     align-items: center;
11 19
     justify-content: space-between;
12 20
     .searchData{
13 21
       padding: 16px;
22
+      display: flex;
23
+      align-items: center;
14 24
       .searchDataItem{
25
+        margin-right: 24px;
15 26
         .label{
16 27
           font-size: 16px;
17 28
         }
29
+        .selectItem{
30
+          width: 224px;
31
+        }
32
+      }
33
+    }
34
+    .operation{
35
+      margin-right: 16px;
36
+      display: flex;
37
+      align-items: center;
38
+      cursor: pointer;
39
+      .icon_transport{
40
+        margin-right: 16px;
41
+        font-size: 24px;
42
+      }
43
+      .btn{
44
+        &.default{
45
+          height: 32px;
46
+          line-height: 32px;
47
+          min-width: 70px;
48
+        }
18 49
       }
19 50
     }
20 51
   }
52
+
53
+  .table{
54
+    margin: 0 8px;
55
+  }
56
+
57
+  .moreFilter{
58
+    margin-bottom: 16px;
59
+    span{
60
+      margin-left: 16px;
61
+      color: @primary-color;
62
+    }
63
+  }
64
+
65
+  .pagination{
66
+    padding: 16px;
67
+    display: flex;
68
+    justify-content: flex-end;
69
+    align-items: center;
70
+  }
21 71
 }

+ 171 - 26
src/app/views/new-statistics/maintenance-statistics/incident-statistics/incident-statistics.component.ts

@@ -1,26 +1,59 @@
1
-import { format, addMonths, startOfMonth, endOfMonth } from 'date-fns';
2
-import { Component, OnInit } from "@angular/core";
1
+import { debounceTime } from 'rxjs/operators';
2
+import { Subject } from 'rxjs';
3
+import { NzMessageService } from 'ng-zorro-antd/message';
4
+import { format, addMonths, startOfMonth, endOfMonth, startOfDay, endOfDay } from 'date-fns';
5
+import { Component, OnInit, HostListener, AfterViewInit } from "@angular/core";
3 6
 import { MainService } from 'src/app/services/main.service';
7
+import { ActivatedRoute } from '@angular/router';
4 8
 @Component({
5 9
   selector: "app-incident-statistics",
6 10
   templateUrl: "./incident-statistics.component.html",
7 11
   styleUrls: ["./incident-statistics.component.less"],
8 12
 })
9
-export class IncidentStatisticsComponent implements OnInit {
13
+export class IncidentStatisticsComponent implements OnInit, AfterViewInit {
10 14
   constructor(
11 15
     private mainService: MainService,
16
+    private message: NzMessageService,
17
+    private route: ActivatedRoute,
12 18
   ) {}
13 19
 
14 20
   listOfData: any[] = []; //表格数据
21
+  listOfDataEnd: any[] = []; //表格合计
15 22
   pageIndex: number = 1; //表格当前页码
16
-  pageSize: number = 10; //表格每页展示条数
17
-  listLength: number = 10; //表格总数据量
23
+  pageSize: number = 30; //表格每页展示条数
24
+  listLength: number = 0; //表格总数据量
25
+
26
+  repairDeptId;//报修科室id
27
+
28
+  searchTimerSubject = new Subject();
18 29
 
19 30
   ngOnInit() {
31
+    this.searchTimerSubject.pipe(debounceTime(500)).subscribe((v) => {
32
+      let fun = v[0];
33
+      fun.call(this, v[1]);
34
+    });
20 35
     this.initSessionData();
21 36
     this.search();
22 37
   }
23 38
 
39
+  ngAfterViewInit(){
40
+    this.onResize();
41
+  }
42
+
43
+  tableHeight:number = 0;
44
+  @HostListener('window:resize')
45
+  onResize(): void {
46
+    setTimeout(() => {
47
+      this.tableHeight = window.innerHeight - 64 - 64 - 36 - 48 - 8 - 45 - 54 - this.getMoreFilter;
48
+      console.log('this.tableHeight:', this.tableHeight)
49
+    }, 0)
50
+  }
51
+
52
+  get getMoreFilter(){
53
+    let flag = this.fieldConfig.fields.groupDTO || this.fieldConfig.fields.userDTO || this.fieldConfig.fields.category1DTO || this.fieldConfig.fields.category2DTO || this.fieldConfig.fields.category3DTO || this.fieldConfig.fields.sourceDTO;
54
+    return flag ? 21 : 0;
55
+  }
56
+
24 57
   // 初始化缓存数据
25 58
   queryType:any;
26 59
   hosId:any;
@@ -56,6 +89,10 @@ export class IncidentStatisticsComponent implements OnInit {
56 89
     }
57 90
   }
58 91
 
92
+  get getHosId(){
93
+    return this.parentDutyId || this.dutyId || this.hosId;
94
+  }
95
+
59 96
   // 表格数据
60 97
   loading1 = false;
61 98
   getList(num?: number, field?: string, sort?: string) {
@@ -70,6 +107,12 @@ export class IncidentStatisticsComponent implements OnInit {
70 107
       hosId: this.hosId,
71 108
       dutyId: this.dutyId,
72 109
       parentDutyId: this.parentDutyId,
110
+      repairDeptId: this.repairDeptId,
111
+      groupId: this.fieldConfig.fields.groupId,
112
+      userId: this.fieldConfig.fields.userId,
113
+      categoryId: this.fieldConfig.fields.categoryId,
114
+      sourceId: this.fieldConfig.fields.sourceId,
115
+      hierarchy: this.fieldConfig.fields.hierarchy,
73 116
     };
74 117
     if (field && sort) {
75 118
       postData.sort = `${field} ${sort === "ascend" ? `asc` : `desc`}`
@@ -79,7 +122,8 @@ export class IncidentStatisticsComponent implements OnInit {
79 122
       .postCustom("itsm/report", "incidentWorkOrder", postData)
80 123
       .subscribe((result) => {
81 124
         this.loading1 = false;
82
-        this.listOfData = result.dataList || [];
125
+        this.listOfData = result.dataList.filter((v, i) => { return i != result.dataList.length - 1 });
126
+        this.listOfDataEnd = result.dataList.filter((v, i) => { return i == result.dataList.length - 1 });
83 127
         this.listLength = result.totalCount;
84 128
       });
85 129
   }
@@ -96,36 +140,137 @@ export class IncidentStatisticsComponent implements OnInit {
96 140
   }
97 141
 
98 142
   // 搜索
99
-  search(num?: number) {
100
-    if (num !== undefined) {
101
-      this.getList(num, this.sortCurrentKey, this.sortCurrentValue);
102
-    } else {
103
-      this.getList(this.pageIndex, this.sortCurrentKey, this.sortCurrentValue);
104
-    }
143
+  search() {
144
+    this.getList(1, this.sortCurrentKey, this.sortCurrentValue);
105 145
   }
106 146
 
107
-  // 日期选择
108
-  dateRange: any = [format(startOfMonth(addMonths(new Date(), -2)), 'yyyy-MM-dd HH:mm:ss'), format(endOfMonth(addMonths(new Date(), -1)), 'yyyy-MM-dd HH:mm:ss')]; //发起时间区间 天
147
+  // 日期选择
148
+  dateRange: any = [format(startOfMonth(addMonths(new Date(), -1)), 'yyyy-MM-dd HH:mm:ss'), format(endOfMonth(addMonths(new Date(), -1)), 'yyyy-MM-dd HH:mm:ss')];
109 149
   changeDate(result?): void {
110
-    console.log(this.dateRange);
111
-    console.log(result);
112
-    result[0] = format(result[0], 'yyyy-MM-dd HH:mm:ss');
113
-    result[1] = format(result[1], 'yyyy-MM-dd HH:mm:ss');
150
+    result[0] = format(startOfDay(result[0]), 'yyyy-MM-dd HH:mm:ss');
151
+    result[1] = format(endOfDay(result[1]), 'yyyy-MM-dd HH:mm:ss');
114 152
     this.dateRange = result;
115
-    this.search();
116 153
   }
117 154
 
118 155
   onCalendarChangeDate(dateArr){
119 156
     console.log(dateArr)
120 157
     if(dateArr.length == 2){
121
-      let dateStart = new Date(dateArr[0]);
122
-      let dateEnd = new Date(dateArr[1]);
123
-      dateStart.setHours(0,0,0);
124
-      dateEnd.setHours(23,59,59);
125
-      this.dateRange = [dateStart,dateEnd];
158
+      this.dateRange = [format(startOfDay(dateArr[0]), 'yyyy-MM-dd HH:mm:ss'), format(endOfDay(dateArr[1]), 'yyyy-MM-dd HH:mm:ss')];
126 159
     }
127 160
   }
128 161
 
129
-  excelExport(){}
130
-  reset(){}
162
+  // 导出
163
+  excelExportLoading:any = false;
164
+  excelExport(){
165
+    this.excelExportLoading = this.message.loading("导出中..", {
166
+      nzDuration: 0,
167
+    }).messageId;
168
+    let postData:any = {
169
+      startDate: this.dateRange[0],
170
+      endDate: this.dateRange[1],
171
+      hosId: this.hosId,
172
+      dutyId: this.dutyId,
173
+      parentDutyId: this.parentDutyId,
174
+      repairDeptId: this.repairDeptId,
175
+      groupId: this.fieldConfig.fields.groupId,
176
+      userId: this.fieldConfig.fields.userId,
177
+      categoryId: this.fieldConfig.fields.categoryId,
178
+      sourceId: this.fieldConfig.fields.sourceId,
179
+      hierarchy: this.fieldConfig.fields.hierarchy,
180
+    };
181
+    if (this.sortCurrentKey && this.sortCurrentValue) {
182
+      postData.sort = `${this.sortCurrentKey} ${this.sortCurrentValue === "ascend" ? `asc` : `desc`}`
183
+    }
184
+    this.mainService
185
+      .postExportCustom("itsm/export", "incidentWorkOrder", postData)
186
+      .subscribe((data) => {
187
+        this.message.remove(this.excelExportLoading);
188
+        this.excelExportLoading = false;
189
+        this.message.success('导出成功');
190
+        var file = new Blob([data], {
191
+          type: "application/vnd.ms-excel",
192
+        });
193
+        //trick to download store a file having its URL
194
+        var fileURL = URL.createObjectURL(file);
195
+        var a = document.createElement("a");
196
+        a.href = fileURL;
197
+        a.target = "_blank";
198
+        a.download = `${this.route.parent.routeConfig.data.title}.xls`;
199
+        document.body.appendChild(a);
200
+        a.click();
201
+      },(err) => {
202
+        this.message.remove(this.excelExportLoading);
203
+        this.excelExportLoading = false;
204
+        this.message.error('导出失败');
205
+      });
206
+  }
207
+  // 重置
208
+  reset(){
209
+    this.sortCurrentKey = "";
210
+		this.sortCurrentValue = "";
211
+		this.sortCurrent = {};
212
+    this.dateRange = [format(startOfMonth(addMonths(new Date(), -1)), 'yyyy-MM-dd HH:mm:ss'), format(endOfMonth(addMonths(new Date(), -1)), 'yyyy-MM-dd HH:mm:ss')]
213
+    this.repairDeptId = undefined;
214
+    this.fieldConfig.fields = {groupId: undefined, userId: undefined, categoryId: undefined, sourceId: undefined, hierarchy: undefined};
215
+    this.search();
216
+  }
217
+
218
+  // 科室搜索
219
+  changeRepairDeptInp(e) {
220
+    this.searchTimer(this.getRepairDeptList, e);
221
+  }
222
+
223
+  // 防抖
224
+  isLoading = false;
225
+  searchTimer(fun, e) {
226
+    this.isLoading = true;
227
+    this.searchTimerSubject.next([fun, e]);
228
+  }
229
+
230
+  openChangeRepairDept(flag){
231
+    flag && this.getRepairDeptList();
232
+  }
233
+
234
+  // 获取报修科室列表
235
+  repairDeptList:any[] = [];
236
+  getRepairDeptList(keyword?) {
237
+    let data = {
238
+      department: {
239
+        cascadeHosId: this.getHosId,
240
+        dept: keyword,
241
+        searchType: 1,
242
+      },
243
+      idx: 0,
244
+      sum: 20,
245
+    };
246
+    this.isLoading = true;
247
+    this.mainService
248
+      .getFetchDataList("data", "department", data)
249
+      .subscribe((data) => {
250
+        this.isLoading = false;
251
+        this.repairDeptList = data.list;
252
+      });
253
+  }
254
+
255
+  // 详细搜索
256
+  fieldConfig:any = {
257
+    fields: {groupId: undefined, userId: undefined, categoryId: undefined, sourceId: undefined, hierarchy: undefined},
258
+    config: {groupAndUser: true, category123: true, source: true},
259
+  }
260
+  showSearchMore:boolean = false;
261
+  showMore(){
262
+    this.showSearchMore = true;
263
+  }
264
+
265
+  cancelEvent(){
266
+    this.showSearchMore = false;
267
+  }
268
+
269
+  submitEvent(fields){
270
+    this.showSearchMore = false;
271
+    this.fieldConfig.fields = fields;
272
+    console.log('this.fieldConfig.fields:', this.fieldConfig.fields)
273
+    this.search();
274
+    this.onResize();
275
+  }
131 276
 }

+ 2 - 0
src/app/views/new-statistics/maintenance-statistics/incident-statistics/incident-statistics.module.ts

@@ -5,6 +5,7 @@ import { CommonModule } from '@angular/common';
5 5
 import { IncidentStatisticsRoutingModule } from './incident-statistics-routing.module';
6 6
 import { ShareModule } from 'src/app/share/share.module';
7 7
 import { VirtualScrollerModule } from 'ngx-virtual-scroller';
8
+import { SearchMoreModule } from '../../components/search-more/search-more.module';
8 9
 
9 10
 
10 11
 @NgModule({
@@ -16,6 +17,7 @@ import { VirtualScrollerModule } from 'ngx-virtual-scroller';
16 17
     IncidentStatisticsRoutingModule,
17 18
     ShareModule,
18 19
     VirtualScrollerModule,
20
+    SearchMoreModule,
19 21
   ]
20 22
 })
21 23
 export class IncidentStatisticsModule { }

+ 1 - 0
src/app/views/new-statistics/maintenance-statistics/maintenance-statistics.component.less

@@ -61,6 +61,7 @@
61 61
     flex: 1;
62 62
     min-height: 0;
63 63
 		overflow-x: hidden;
64
+    height: 100%;
64 65
     .secondMenu{
65 66
       width: 175px;
66 67
       height: 100%;