瀏覽代碼

拉取代码

maotao 1 月之前
父節點
當前提交
3985b7ac54

+ 90 - 0
src/app/components/configurationCenter/configuration-system-security/configuration-system-security.component.html

@@ -0,0 +1,90 @@
1
+<div class="content specimen" id="dictionary">
2
+  <div class="contentInner">
3
+		<div class="address">
4
+		  <overlay-scrollbars #osComponentRef1 class="contentBody">
5
+		    <div class="contentItem" [title]="item.name" [ngClass]="{ active: item.key == activeDictionaryKey }" (click)="clickDictionaryKey(item)" *ngFor="let item of dictionaryKeyList">{{ item.name }}</div>
6
+		  </overlay-scrollbars>
7
+		</div>
8
+    <div class="addressAssign">
9
+      <div class="contentBody2">
10
+        <div class="TaskTypeManagement" *ngIf="activeDictionaryKey=='login'">
11
+          <div class="taskTypeInfo">
12
+    <!--        <div class="top">
13
+              <div class="item" (click)="tabModal('characteristics')" [ngClass]="{'items':tabModalName=='characteristics'}">
14
+                特性配置
15
+              </div>
16
+              <div class="item" (click)="tabModal('automaticOrderCreation')" [ngClass]="{'items':tabModalName=='automaticOrderCreation'}">
17
+                自动建单配置
18
+              </div>
19
+            </div> -->
20
+            <div class="list" *ngIf="!loading">
21
+              <div>
22
+                <!-- 是否需要验证码登录 -->
23
+                <div class="display_flex align-items_center mb8">
24
+                  <nz-form-label class="label">是否需要验证码登录</nz-form-label>
25
+                  <nz-checkbox-group [(ngModel)]="verificationCode"></nz-checkbox-group>
26
+                </div>
27
+								
28
+								<!-- 验证码位数 -->
29
+								<div class="display_flex align-items_center mb8" *ngIf="verificationCode[0].checked">
30
+									<nz-form-label class="label">验证码位数</nz-form-label>
31
+									<nz-select class="formItem" [nzDropdownMatchSelectWidth]="false" nzShowSearch nzAllowClear nzPlaceHolder="请选择验证码位数" [(ngModel)]="digit">
32
+										<ng-container *ngFor="let option of digitData">
33
+											<nz-option [nzLabel]="option.name" [nzValue]="option.id"></nz-option>
34
+										</ng-container>
35
+									</nz-select>
36
+								</div>
37
+								
38
+								<!-- 验证码有效期 -->
39
+								<div class="display_flex align-items_center mb8" *ngIf="verificationCode[0].checked">
40
+									<nz-form-label class="label">验证码有效期</nz-form-label>
41
+									<nz-input-number [(ngModel)]="validity" [nzMin]="0" [nzMax]="99999" [nzStep]="1"></nz-input-number>&nbsp;&nbsp;分钟 
42
+								</div>
43
+								
44
+                <!-- 是否限制账户错误登录次数 -->
45
+                <div class="display_flex align-items_center mb8">
46
+                  <nz-form-label class="label">是否限制账户错误登录次数</nz-form-label>
47
+                  <nz-checkbox-group [(ngModel)]="isErrorTime"></nz-checkbox-group>
48
+                </div>
49
+								
50
+								
51
+                <!-- 支持错误次数 -->
52
+                <div class="display_flex align-items_center mb8" *ngIf="isErrorTime[0].checked">
53
+                  <nz-form-label class="label">支持错误次数</nz-form-label>
54
+									<nz-input-number [(ngModel)]="errorTime" [nzMin]="2" [nzMax]="99999" [nzStep]="1"></nz-input-number>&nbsp;&nbsp;次 
55
+								</div>
56
+
57
+								<!-- 是否限制单点登录ip -->
58
+								<div class="display_flex align-items_center mb8">
59
+								  <nz-form-label class="label">是否限制单点登录ip</nz-form-label>
60
+								  <nz-checkbox-group [(ngModel)]="astrictIp"></nz-checkbox-group>
61
+								</div>
62
+
63
+                <!-- 单点登录范围内IP -->
64
+                <div class="display_flex flex-wrap_wrap align-items_baseline mb8" *ngIf="astrictIp[0].checked">
65
+                  <nz-form-label class="label">单点登录范围内IP</nz-form-label>
66
+									<div *ngFor="let i of ipData let index = index;" class="ip-list" [ngClass]="{'margin-list':index!=0}">
67
+										<input class="width-300" type="text" nz-input [(ngModel)]="i.rangeIp"/> 
68
+										<i class="add-class" (click)="addIp()" nz-icon nzType="plus" nzTheme="outline"></i>
69
+										<i class="add-class" (click)="delIp(i, index)" nz-icon nzType="minus" nzTheme="outline"></i>
70
+									</div>
71
+								</div>
72
+              </div>
73
+              <div class="bottom">
74
+                <button class="login-form-button" nzType="primary" [nzLoading]="btnLoading" nz-button (click)="submitForm()">保存</button>
75
+              </div>
76
+            </div>
77
+            <div class="list" *ngIf="loading">
78
+              <div class="loadingFull display_flex justify-content_flex-center align-items_center">
79
+                <div class="loadingFullInner">
80
+                  <img src="../../../assets/images/loading.gif" alt="">
81
+                  <div>加载中...</div>
82
+                </div>
83
+              </div>
84
+            </div>
85
+          </div>
86
+        </div>
87
+      </div>
88
+    </div>
89
+  </div>
90
+</div>

+ 895 - 0
src/app/components/configurationCenter/configuration-system-security/configuration-system-security.component.less

@@ -0,0 +1,895 @@
1
+@import "../../../../../src/theme.less";
2
+:host {
3
+  height: 100%;
4
+  display: flex;
5
+  flex-direction: column;
6
+  justify-content: space-between;
7
+  background-color: #F0F2F5;
8
+  .list-template__nzTable,
9
+  .list-template__bottom{
10
+    padding: 0!important;
11
+    border: none!important;
12
+    background: #fff!important;
13
+  }
14
+  .list-template{
15
+    width: 100%!important;
16
+    height: 100%!important;
17
+  }
18
+	.width-100{
19
+		width: 100px;
20
+	}
21
+	.width-300{
22
+		width: 300px;
23
+	}
24
+	.align-items_baseline{
25
+		align-items: baseline;
26
+	}
27
+	
28
+	.ip-list{
29
+		display: flex;
30
+		align-items: center;
31
+		margin-bottom: 20px;
32
+		.add-class{
33
+			cursor: pointer;
34
+			font-size: 22px;
35
+			margin-left: 20px;
36
+		}
37
+	}
38
+	
39
+	.margin-list{
40
+		margin-left: 123px;
41
+	}
42
+	
43
+	.flex-wrap_wrap{
44
+		flex-wrap: wrap;
45
+	}
46
+	
47
+  #dictionary{
48
+    margin: 24px 16px;
49
+    .addressAssign{
50
+      flex: 7;
51
+    }
52
+    .contentItem{
53
+      margin: 0 16px;
54
+      padding: 8px;
55
+      text-align: center;
56
+      &.active{
57
+        background-color: @primary-color;
58
+        color: #fff;
59
+        border-radius: 4px;
60
+      }
61
+    }
62
+    .contentBody{
63
+      padding: 16px;
64
+      min-height: 0;
65
+      display: flex;
66
+      flex-direction: column;
67
+    }
68
+    .contentBody2{
69
+      flex: 1;
70
+    }
71
+    ::ng-deep .ant-form-item{
72
+      margin-bottom: 0;
73
+    }
74
+    .dictionaryRow{
75
+      display: flex;
76
+      align-items: center;
77
+      justify-content: center;
78
+      gap: 16px;
79
+      .orders{
80
+        flex: 1;
81
+        display: flex;
82
+        justify-content: flex-end;
83
+        align-items: center;
84
+      }
85
+      .name{
86
+        width: 100px;
87
+        display: flex;
88
+        justify-content: flex-end;
89
+        align-items: center;
90
+      }
91
+      .value{
92
+        flex: 3;
93
+        display: flex;
94
+        align-items: center;
95
+        .valueInput{
96
+          width: 600px;
97
+        }
98
+        .icon_transport{
99
+          font-size: 20px;
100
+          color: #8a8a8a;
101
+          cursor: pointer;
102
+        }
103
+      }
104
+
105
+    }
106
+  }
107
+  .content{
108
+    flex: 1;
109
+    min-height: 0;
110
+    display: flex;
111
+    flex-direction: column;
112
+    justify-content: space-between;
113
+    border: 1px solid #EEF3F9;
114
+    &.priority{
115
+      margin: 24px 118px 0;
116
+      background-color: #fff;
117
+      .contentInner{
118
+        padding: 48px 206px;
119
+        border: 1px solid #E8EBEF;
120
+      }
121
+    }
122
+    .contentItem{
123
+      padding: 4px 16px;
124
+      cursor: pointer;
125
+      overflow: hidden;
126
+      text-overflow: ellipsis;
127
+      white-space: nowrap;
128
+      &.active{
129
+        color: @primary-color;
130
+        background-color: #F0F6ED;
131
+        border-radius: 4px;
132
+      }
133
+    }
134
+    .contentInner{
135
+      flex: 1;
136
+      display: flex;
137
+      justify-content: space-between;
138
+      align-items: center;
139
+      padding: 0 16px;
140
+      gap: 16px;
141
+      .contentHead{
142
+        height: 45px;
143
+        display: flex;
144
+        justify-content: space-between;
145
+        align-items: center;
146
+        gap: 16px;
147
+        padding: 0 16px;
148
+        font-size: 16px;
149
+        font-weight: bold;
150
+        border-bottom: 1px solid #D9D9D9;
151
+        .title{
152
+          overflow: hidden;
153
+          text-overflow: ellipsis;
154
+          white-space: nowrap;
155
+        }
156
+        .btns{
157
+          flex-shrink: 0;
158
+        }
159
+      }
160
+      .contentBody{
161
+        padding: 0 8px;
162
+        margin: 4px 0;
163
+        flex: 1;
164
+      }
165
+      .address{
166
+        flex: 1;
167
+        height: 100%;
168
+        background: #FFFFFF;
169
+        border: 1px solid #E8EBEF;
170
+        display: flex;
171
+        flex-direction: column;
172
+        width: 0;
173
+      }
174
+      .addressAssign{
175
+        flex: 3;
176
+        height: 100%;
177
+        background: #FFFFFF;
178
+        border: 1px solid #E8EBEF;
179
+        display: flex;
180
+        flex-direction: column;
181
+        width: 0;
182
+      }
183
+      .list-template__searchItem {
184
+        margin-bottom: 16px;
185
+        .label {
186
+          color: #333;
187
+          display: inline-block;
188
+          width: 70px;
189
+          text-align-last: justify;
190
+          text-align: justify;
191
+          &.label--big {
192
+            width: 100px;
193
+          }
194
+        }
195
+        .formItem {
196
+          width: 135px;
197
+        }
198
+      }
199
+    }
200
+    .contentBtns{
201
+      margin-bottom: 16px;
202
+      display: flex;
203
+      justify-content: center;
204
+      align-items: center;
205
+    }
206
+  }
207
+  .TaskTypeManagement {
208
+    height: calc(100vh - 136px);
209
+    background: #f9fafb;
210
+    overflow: hidden;
211
+    padding: 16px 20px;
212
+
213
+    .pagination {
214
+      margin-top: 14px;
215
+      margin-bottom: 14px;
216
+      bottom: 12px;
217
+      right: 5px;
218
+    }
219
+
220
+    .taskType {
221
+      float: left;
222
+      width: 24%;
223
+      height: 100%;
224
+      border: 1px solid #e5e9ed;
225
+      background: #fff;
226
+      color: #333;
227
+      font-size: 14px;
228
+      position: relative;
229
+      overflow: hidden;
230
+
231
+      .title {
232
+        width: 100%;
233
+        height: 40px;
234
+        line-height: 40px;
235
+        padding-left: 16px;
236
+        border-bottom: 1px solid #e5e9ed;
237
+        position: relative;
238
+        background: #fff;
239
+        z-index: 2;
240
+      }
241
+
242
+      .operate {
243
+        width: 100%;
244
+        border-bottom: 1px solid #e5e9ed;
245
+        position: relative;
246
+        background: #fff;
247
+        z-index: 2;
248
+        display: flex;
249
+
250
+        .item {
251
+          flex: 1;
252
+          height: 34px;
253
+          line-height: 34px;
254
+          border-right: 1px solid #e5e9ed;
255
+          text-align: center;
256
+          color: #666; // cursor: default;
257
+          cursor: pointer;
258
+
259
+          &:hover {
260
+            color: @primary-color;
261
+            background: #f0f6ed;
262
+          }
263
+
264
+          &:nth-last-child(1) {
265
+            border: none;
266
+          }
267
+        }
268
+      }
269
+
270
+      .taskTypes {
271
+        // width: 110%;
272
+        width: 100%;
273
+        height: 92%;
274
+        // padding-right: 10%;
275
+        overflow-y: auto;
276
+        z-index: 1;
277
+        padding-bottom: 30px;
278
+
279
+        .itemChoice {
280
+          color: @primary-color;
281
+          background: #f0f6ed;
282
+        }
283
+
284
+        .item {
285
+          width: 100%;
286
+          height: 34px;
287
+          line-height: 34px;
288
+          text-align: center;
289
+          cursor: pointer;
290
+          overflow: hidden;
291
+          text-overflow: ellipsis;
292
+          white-space: nowrap;
293
+
294
+          &:hover {
295
+            color: @primary-color;
296
+            background: #f0f6ed;
297
+          }
298
+
299
+          &.checked {
300
+            color: @primary-color;
301
+            background: #f0f6ed;
302
+          }
303
+        }
304
+      }
305
+    }
306
+
307
+    //任务类型管理-主体
308
+    .taskTypeInfo {
309
+      height: 100%;
310
+      border: 1px solid #e5e9ed;
311
+      background: #fff;
312
+      color: #333;
313
+      position: relative;
314
+
315
+      .top {
316
+        height: 61px;
317
+        line-height: 60px;
318
+        display: flex;
319
+        align-items: center;
320
+        border-bottom: 1px solid #e5e9ed;
321
+        position: relative;
322
+        z-index: 2;
323
+
324
+        .items {
325
+          background: #f0f6ed;
326
+        }
327
+
328
+        & > div {
329
+          border-right: 1px solid #e5e9ed;
330
+          width: 30%;
331
+          text-align: center; // display: flex;
332
+          // align-items: center;
333
+          cursor: pointer;
334
+
335
+          &:hover {
336
+            background: #f0f6ed;
337
+          }
338
+        }
339
+
340
+        &:nth-last-child(4) {
341
+          border: none;
342
+        }
343
+      }
344
+
345
+      .list {
346
+        width: 100%; // height: 100%;
347
+        padding: 16px; // position: absolute;
348
+        // top: 0;
349
+        // padding-top: 90px;
350
+        background: #fff;
351
+        height: 89%;
352
+        overflow: auto;
353
+
354
+        nz-form-label {
355
+          margin-left: 0px !important;
356
+        }
357
+				
358
+				.ant-select{
359
+					width: 200px;
360
+				}
361
+				
362
+				.width-200{
363
+					width: 275px;
364
+				}
365
+				
366
+        & > div {
367
+          background: #f9fafb;
368
+          border: 1px solid #e5e9ed;
369
+          border-radius: 10px 10px 0px 0px;
370
+          padding: 24px 120px;
371
+
372
+          .label {
373
+            margin-left: 16px;
374
+            font-size: 14px;
375
+            color: #333;
376
+          }
377
+        }
378
+
379
+        // 规则信息
380
+        .ruleList {
381
+          padding: 15px 15px 0px 15px;
382
+          background: #fff;
383
+
384
+          .table {
385
+            width: 100%;
386
+            height: 100%;
387
+
388
+            .box {
389
+              // background: #f9fafb;
390
+              // border: 1px solid #e5e9ed;
391
+              border-radius: 5px;
392
+              position: relative;
393
+
394
+              .table_title {
395
+                font-size: 18px;
396
+                margin: 14px 0px;
397
+                text-align: center;
398
+              }
399
+
400
+              .thead {
401
+                background-image: linear-gradient(to right, @bg-start, @bg-end);
402
+
403
+                th {
404
+                  background: transparent;
405
+                  color: #fff;
406
+                  text-align: center;
407
+                  font-size: 14px;
408
+                }
409
+              }
410
+
411
+              .ant-table-body {
412
+                border-bottom: 1px solid #e5e9ed;
413
+                background: #f9fafb;
414
+              }
415
+
416
+              .ant-table-tbody {
417
+                background: #f9fafb;
418
+                border: 1px solid #e5e9ed;
419
+
420
+                .zzBontton {
421
+                  & > td {
422
+                    border-bottom: 1px solid #e5e9ed;
423
+                  }
424
+                }
425
+
426
+                tr {
427
+                  text-align: center;
428
+                  font-size: 14px;
429
+                  border: none;
430
+                  color: #333;
431
+                  overflow: hidden;
432
+
433
+                  .lin {
434
+                    width: 68.2%;
435
+                    height: 2rem;
436
+                    border-bottom: 0.1rem solid #e5e9ed;
437
+                    position: absolute;
438
+                    text-align: center;
439
+                    margin-left: 0%;
440
+                    margin-top: -0.8%;
441
+                    transform: rotate(6.5deg);
442
+                  }
443
+
444
+                  td {
445
+                    border: none;
446
+
447
+                    nz-input-number {
448
+                      width: 50px;
449
+                    }
450
+
451
+                    .coop {
452
+                      .line {
453
+                        margin: 10px;
454
+                      }
455
+
456
+                      span:nth-child(2n-1) {
457
+                        cursor: pointer;
458
+
459
+                        &:hover {
460
+                          color: @primary-color;
461
+                        }
462
+
463
+                        &:active {
464
+                          color: @primary-color;
465
+                        }
466
+                      }
467
+                    }
468
+                  }
469
+                }
470
+
471
+                tr:nth-child(even) {
472
+                  background: #fff;
473
+                }
474
+              }
475
+            }
476
+          }
477
+        }
478
+
479
+        //运送过程
480
+        .ysgcItem {
481
+          padding: 0px 0px 0px 0px; // background: #fff;
482
+
483
+          .ysgc_top {
484
+            height: 88px;
485
+            background: #fff;
486
+            border-radius: 10px 10px 0px 0px;
487
+            padding: 15px 22px 0px 22px;
488
+
489
+            .title {
490
+              span {
491
+                font-size: 18px;
492
+              }
493
+            }
494
+
495
+            .carrItems {
496
+              color: @primary-color;
497
+              border-color: @primary-color !important;
498
+            }
499
+
500
+            .process {
501
+              width: 80%;
502
+              display: flex;
503
+              justify-content: center;
504
+              align-items: center;
505
+              margin: 5px auto;
506
+              font-size: 14px;
507
+
508
+              .carrItem {
509
+                height: 40px;
510
+                line-height: 28px;
511
+                cursor: pointer;
512
+                display: flex;
513
+                justify-content: center;
514
+                align-items: center;
515
+
516
+                .carrItem_icon {
517
+                  width: 35px;
518
+                  height: 35px;
519
+                  border: 1px solid #e5e9ed;
520
+                  border-radius: 50%;
521
+                  text-align: center;
522
+                  line-height: 35px;
523
+                  margin-right: 10px;
524
+
525
+                  i {
526
+                    font-size: 18px;
527
+                  }
528
+                }
529
+              }
530
+
531
+              .carrItem1 {
532
+                float: left;
533
+                width: 45%;
534
+                height: 40px;
535
+                line-height: 28px;
536
+                padding-left: 10%;
537
+                cursor: pointer;
538
+
539
+                .carrItem_icon {
540
+                  width: 35px;
541
+                  height: 35px;
542
+                  border: 1px solid #e5e9ed;
543
+                  border-radius: 50%;
544
+                  text-align: center;
545
+                  line-height: 35px;
546
+                  float: left;
547
+                  margin-right: 10px;
548
+
549
+                  i {
550
+                    font-size: 18px;
551
+                  }
552
+                }
553
+              }
554
+            }
555
+          }
556
+
557
+          .ysgc_cont {
558
+            padding: 0px 240px 24px 240px;
559
+
560
+            textarea {
561
+              padding-right: 10%;
562
+            }
563
+
564
+            .icon_btn {
565
+              cursor: pointer;
566
+              font-size: 18px;
567
+            }
568
+
569
+            .icon_text {
570
+              display: block;
571
+              cursor: pointer;
572
+              position: relative;
573
+              right: 5px;
574
+            }
575
+
576
+            .item_type_cont {
577
+              height: 70px;
578
+              padding-top: 4px;
579
+
580
+              & > div {
581
+                height: 65px;
582
+                border: 1px solid #e5e9ed;
583
+                border-radius: 5px;
584
+                background: #fff;
585
+
586
+                .item_type_cont_L {
587
+                  height: 100%;
588
+                  width: 90%;
589
+                  float: left;
590
+                  padding: 2px 12px;
591
+                  overflow: auto;
592
+
593
+                  .item_yq {
594
+                    width: 24%;
595
+                    height: 28px;
596
+                    display: inline-block;
597
+                    border: 1px solid #e5e9ed;
598
+                    border-radius: 20px;
599
+                    text-align: center;
600
+                    line-height: 26px;
601
+                    background: #f9fafb;
602
+                    margin-right: 1%;
603
+                    margin-bottom: 2px;
604
+                    font-size: 12px;
605
+                    padding-left: 8px;
606
+
607
+                    span {
608
+                      width: 75%;
609
+                      float: left;
610
+                      overflow: hidden;
611
+                      text-overflow: ellipsis;
612
+                      white-space: nowrap;
613
+                    }
614
+
615
+                    i {
616
+                      font-size: 14px;
617
+                      color: #999;
618
+                      cursor: pointer;
619
+                    }
620
+                  }
621
+                }
622
+
623
+                .item_type_cont_R {
624
+                  height: 100%;
625
+                  width: 10%;
626
+                  float: right;
627
+                  text-align: center;
628
+                  padding-top: 15px;
629
+                  border-left: 1px solid #e5e9ed;
630
+                  cursor: pointer;
631
+
632
+                  i {
633
+                    display: block;
634
+                    font-size: 16px;
635
+                  }
636
+
637
+                  i:hover {
638
+                    color: @primary-color;
639
+                  }
640
+
641
+                  .icon_text {
642
+                    right: 1px;
643
+                  }
644
+                }
645
+              }
646
+            }
647
+          }
648
+        }
649
+
650
+        //关联信息
651
+        .glxxItem {
652
+          padding: 10px 15px 0px 15px;
653
+          background: #fff;
654
+
655
+          .tab_btn {
656
+            cursor: pointer;
657
+          }
658
+
659
+          .tab_btn:hover {
660
+            color: @primary-color;
661
+          }
662
+
663
+          .table_title {
664
+            font-size: 18px;
665
+            margin: 14px 0px;
666
+            text-align: center;
667
+          }
668
+
669
+          .thead {
670
+            background-image: linear-gradient(to right, @bg-start, @bg-end);
671
+
672
+            th {
673
+              background: transparent;
674
+              color: #fff;
675
+              text-align: center;
676
+              font-size: 14px;
677
+            }
678
+          }
679
+
680
+          .ant-table-body {
681
+            // border-bottom: 1px solid #e5e9ed;
682
+            background: #f9fafb;
683
+          }
684
+
685
+          .ant-table-tbody {
686
+            background: #f9fafb;
687
+            border: 1px solid #e5e9ed;
688
+
689
+            tr {
690
+              text-align: center;
691
+              font-size: 14px;
692
+              border: none;
693
+              color: #333;
694
+
695
+              td {
696
+                border: none; // font-size: 14px;
697
+
698
+                nz-input-number {
699
+                  width: 40px;
700
+                }
701
+
702
+                .coop {
703
+                  .line {
704
+                    margin: 10px;
705
+                  }
706
+
707
+                  span:nth-child(2n-1) {
708
+                    cursor: pointer;
709
+
710
+                    &:hover {
711
+                      color: @primary-color;
712
+                    }
713
+
714
+                    &:active {
715
+                      color: @primary-color;
716
+                    }
717
+                  }
718
+                }
719
+              }
720
+            }
721
+
722
+            tr:nth-child(even) {
723
+              background: #fff;
724
+            }
725
+          }
726
+        }
727
+
728
+        // 开通科室
729
+        .ktksItem {
730
+          padding: 0px 0px 0px 0px;
731
+          background: #fff;
732
+
733
+          .top {
734
+            width: 100%; // padding-bottom: 7px;
735
+            // border-bottom: 1px solid #e5e9ed;
736
+            position: relative;
737
+            overflow: hidden;
738
+            z-index: 2;
739
+            display: flex;
740
+            align-items: center;
741
+            justify-content: space-between;
742
+
743
+            .top_L {
744
+              width: 70%;
745
+              text-align: left;
746
+              display: flex;
747
+              flex-wrap: wrap;
748
+              align-items: center;
749
+              padding: 0 4px;
750
+              .top_L_item {
751
+                margin-left: 4px;
752
+              }
753
+
754
+              .label {
755
+                font-size: 14px;
756
+                color: #333;
757
+                margin-left: 0;
758
+              }
759
+
760
+              nz-select {
761
+                font-size: 12px;
762
+                width: 100px;
763
+              }
764
+
765
+              input {
766
+                font-size: 12px;
767
+                width: 100px;
768
+              }
769
+            }
770
+
771
+            .top_R {
772
+              border: 0px;
773
+
774
+              .btn {
775
+                margin-left: 10px;
776
+              }
777
+            }
778
+          }
779
+
780
+          .ktksItemList {
781
+            padding: 10px 15px 0px 15px;
782
+            .table {
783
+              min-height: 528px;
784
+            }
785
+
786
+            .operate {
787
+              float: right;
788
+              margin-bottom: 5px;
789
+
790
+              span {
791
+                font-size: 14px;
792
+              }
793
+
794
+              .num {
795
+                font-size: 18px;
796
+                color: @primary-color;
797
+              }
798
+            }
799
+
800
+            .thead {
801
+              background-image: linear-gradient(to right, @bg-start, @bg-end);
802
+
803
+              th {
804
+                background: transparent;
805
+                color: #fff;
806
+                text-align: center;
807
+                font-size: 14px;
808
+              }
809
+            }
810
+
811
+            .ant-table-body {
812
+              border-bottom: 1px solid #e5e9ed;
813
+              background: #f9fafb;
814
+            }
815
+
816
+            .ant-table-tbody {
817
+              background: #f9fafb;
818
+              border: 1px solid #e5e9ed;
819
+
820
+              .zzBontton {
821
+                & > td {
822
+                  border-bottom: 1px solid #e5e9ed;
823
+                }
824
+              }
825
+
826
+              tr {
827
+                text-align: center;
828
+                font-size: 14px;
829
+                border: none;
830
+                color: #333;
831
+
832
+                td {
833
+                  border: none; // font-size: 14px;
834
+
835
+                  nz-input-number {
836
+                    width: 40px;
837
+                  }
838
+
839
+                  .coop {
840
+                    .line {
841
+                      margin: 10px;
842
+                    }
843
+
844
+                    span:nth-child(2n-1) {
845
+                      cursor: pointer;
846
+
847
+                      &:hover {
848
+                        color: @primary-color;
849
+                      }
850
+
851
+                      &:active {
852
+                        color: @primary-color;
853
+                      }
854
+                    }
855
+                  }
856
+                }
857
+              }
858
+
859
+              tr:nth-child(even) {
860
+                background: #fff;
861
+              }
862
+            }
863
+          }
864
+
865
+          .pagination {
866
+            margin-top: 25px;
867
+            margin-bottom: 14px;
868
+            bottom: 12px;
869
+            right: 5px;
870
+            position: relative;
871
+            height: 30px;
872
+            .page {
873
+              position: absolute;
874
+              right: 5px;
875
+            }
876
+          }
877
+        }
878
+
879
+        .bottom {
880
+          height: 60px;
881
+          border-radius: 0px 0px 10px 10px;
882
+          padding: 10px 240px 0px 240px;
883
+          border-top: 0px;
884
+
885
+          button {
886
+            width: 80px;
887
+            height: 34px;
888
+            display: block;
889
+            margin: 0 auto;
890
+          }
891
+        }
892
+      }
893
+    }
894
+  }
895
+}

+ 247 - 0
src/app/components/configurationCenter/configuration-system-security/configuration-system-security.component.ts

@@ -0,0 +1,247 @@
1
+import { Component, OnInit } from "@angular/core";
2
+import { MainService } from "../../../services/main.service";
3
+import { ToolService } from 'src/app/services/tool.service';
4
+import { NzMessageService } from 'ng-zorro-antd';
5
+import { Subject, forkJoin } from 'rxjs';
6
+import { debounceTime } from 'rxjs/operators';
7
+
8
+@Component({
9
+  selector: "app-configuration-system-security",
10
+  templateUrl: "./configuration-system-security.component.html",
11
+  styleUrls: ["./configuration-system-security.component.less"],
12
+})
13
+export class ConfigurationSystemSecurityComponent implements OnInit {
14
+  loading:boolean = false; //页面加载的loading
15
+  btnLoading:boolean = false; //提交按钮的loading
16
+  tabModalName:string = 'characteristics'; //当前选中的tab
17
+  hosId = this.tool.getCurrentHospital().id; //当前院区
18
+
19
+	// tab类型
20
+	dictionaryKeyList:any[] = [
21
+		{
22
+			name:'登录安全',key:'login'
23
+		}
24
+	];
25
+
26
+  verificationCode:any = [{ label:'是否开启', value: 0 }];//是否需要验证码登录
27
+  digitData:any = [
28
+		{ name:'4位验证码', id: 4 },
29
+		{ name:'6位验证码', id: 6 },
30
+	];//验证码位数
31
+	digit:any; //验证码位数
32
+	validity:any; //验证码有效期
33
+  isErrorTime:any = [{ label:'是否开启', value: 0 }];//是否限制账户错误登录次数
34
+  errorTime:any;//支持错误次数
35
+  astrictIp:any = [{ label:'是否开启', value: 1 }];//终点科室支持核对
36
+  drugsEndCheckScanIds:any = [];//是否限制单点登录ip
37
+  rangeIp:any;//单点登录范围内IP
38
+  // 配置
39
+  configs:any = {};
40
+  // 任务类型
41
+  tasktype:any = {};
42
+  searchTimerSubject = new Subject();
43
+  constructor(private mainService: MainService,private tool: ToolService,private msg: NzMessageService) {}
44
+
45
+  ngOnInit():void {
46
+    // todo
47
+    this.searchTimerSubject.pipe(debounceTime(500)).subscribe((v) => {
48
+      let fun = v[0];
49
+      fun.call(this, v[1]);
50
+    });
51
+		this.getConfig();
52
+  }
53
+
54
+	// 点击数据字典key
55
+	activeDictionaryKey:any = 'login';
56
+	clickDictionaryKey(item){
57
+	  this.activeDictionaryKey = item.key;
58
+		if(item.key=='login'){
59
+			this.getConfig();
60
+		}
61
+	}
62
+
63
+  isLoading: boolean = false;
64
+  // 边输入边搜索节流阀
65
+  searchTimer(fun, e) {
66
+    this.isLoading = true;
67
+    this.searchTimerSubject.next([fun, e]);
68
+  }
69
+	// 添加ip
70
+	ipData:any= [{
71
+		rangeIp:''
72
+	}];
73
+	addIp(){
74
+		this.ipData.push({
75
+			rangeIp:'',
76
+		})
77
+	}
78
+	
79
+	// 删除ip
80
+	delIp(item, index){
81
+		if(this.ipData.length==1){
82
+			return
83
+		}
84
+		this.ipData.splice(index, 1)
85
+	}
86
+	
87
+	// 验证是否有特殊字符
88
+	containsSymbol(str) {
89
+	    return /[^a-zA-Z0-9]/.test(str);
90
+	}
91
+	
92
+  // 保存
93
+  submitForm() {
94
+		if(this.verificationCode[0].checked){
95
+			if(!this.digit){
96
+				this.msg.error('验证码位数不能为空')
97
+				return 
98
+			}
99
+			if(!this.validity){
100
+				this.msg.error('验证码有效期不能为空')
101
+				return 
102
+			}
103
+		}
104
+		
105
+		if(this.isErrorTime[0].checked){
106
+			if(!this.errorTime){
107
+				this.msg.error('支持错误次数不能为空')
108
+				return 
109
+			}
110
+		}
111
+	
112
+		if(this.astrictIp[0].checked){
113
+			let isEmpty = this.ipData.filter(i=>i.rangeIp=='')
114
+			if(isEmpty.length>0){
115
+				this.msg.error('ip不能为空')
116
+				return 
117
+			}
118
+		}
119
+		
120
+		let filterData = this.initConfig;
121
+		filterData.forEach((item) => {
122
+		 if (item.configKey === "verificationCode") {
123
+				let value = null
124
+				if(this.verificationCode[0].checked){
125
+					value = '1'
126
+				}else{
127
+					value = '0'
128
+				}
129
+		    item.configValue = value;
130
+		  } else if (item.configKey === "verificationCodeLength") {
131
+			  item.configValue = this.digit;
132
+			}else if (item.configKey === "verificationCodeDuration") {
133
+		    item.configValue = this.validity;
134
+		  }else if (item.configKey === "limitIncorrectLogin") {
135
+		    let value = null
136
+		    if(this.isErrorTime[0].checked){
137
+		    	value = '1'
138
+		    }else{
139
+		    	value = '0'
140
+		    }
141
+		    item.configValue = value;
142
+		  }else if (item.configKey === "incorrectNum") {
143
+				item.configValue = this.errorTime;
144
+		  }else if (item.configKey === "limitSingleLoginIp") {
145
+				let value = null
146
+				if(this.astrictIp[0].checked){
147
+					value = '1'
148
+				}else{
149
+					value = '0'
150
+				}
151
+				item.configValue = value;
152
+		  }else if (item.configKey === "ipWhiteList") {
153
+				let str = JSON.parse(JSON.stringify(this.ipData))
154
+				let data = str.map(i=>{
155
+					return i.rangeIp
156
+				})
157
+				console.log(4444, data)
158
+				item.configValue = data.join(';');
159
+		  }
160
+		});
161
+		const postData = filterData;
162
+    this.btnLoading = true;
163
+    this.mainService
164
+      .simplePost("addListData", "systemSafeConfig", postData)
165
+      .subscribe((result) => {
166
+        this.btnLoading = false;
167
+        if (result.status == 200) {
168
+          this.getConfig();
169
+        }
170
+      });
171
+  }
172
+
173
+  // 获取配置
174
+	initConfig:any;
175
+	config:any;
176
+  getConfig() {
177
+    this.loading = true;
178
+		let postData = null;
179
+		if(this.activeDictionaryKey=='login'){
180
+			postData = {
181
+			  idx: 0,
182
+			  sum: 999,
183
+			  type: 'login'
184
+			};
185
+		}
186
+
187
+    this.mainService
188
+      .getFetchDataList("simple/data", "systemSafeConfig", postData)
189
+      .subscribe((result) => {
190
+        this.loading = false;
191
+        if (result.status == 200) {
192
+					if (result.list && Array.isArray(result.list)) {
193
+						this.initConfig = JSON.parse(JSON.stringify(result.list));
194
+						this.config = result.list.map((item) => {
195
+							return [item.configKey, item.configValue, item.id, item.label];
196
+						});
197
+						this.config.forEach((c) => {
198
+							switch (c[0]) {
199
+								case "verificationCode":
200
+									if(c[1]=='1'){
201
+										this.verificationCode[0].checked = true
202
+									}else{
203
+										this.verificationCode[0].checked = false
204
+									}
205
+									break;
206
+								case "verificationCodeLength":
207
+									this.digit = Number(c[1])
208
+									break;	
209
+								case "verificationCodeDuration":
210
+									this.validity = c[1]
211
+									break;
212
+								case "limitIncorrectLogin":
213
+									if(c[1]=='1'){
214
+										this.isErrorTime[0].checked = true
215
+									}else{
216
+										this.isErrorTime[0].checked = false
217
+									}
218
+									break;
219
+								case "incorrectNum":
220
+									this.errorTime = c[1]
221
+									break;	
222
+								case "limitSingleLoginIp":
223
+									if(c[1]=='1'){
224
+										this.astrictIp[0].checked = true
225
+									}else{
226
+										this.astrictIp[0].checked = false
227
+									}
228
+									break;
229
+								case "ipWhiteList":
230
+									let data = c[1].split(';')
231
+									this.ipData = []
232
+									for(let i=0; i<data.length; i++){
233
+										this.ipData.push({
234
+											rangeIp: data[i]
235
+										}) 
236
+									}
237
+									break;
238
+							}
239
+						});
240
+					} else {
241
+						this.initConfig = [];
242
+						this.config = [];
243
+					}
244
+        }
245
+      });
246
+  }
247
+}

+ 7 - 1
src/app/services/main.service.ts

@@ -34,10 +34,12 @@ export class MainService {
34
     return tmpAES.toString();
34
     return tmpAES.toString();
35
   }
35
   }
36
   // 登录
36
   // 登录
37
-  login(name: string, pwd: string): any {
37
+  login(name: string, pwd: string, captcha: string, captchaId: string): any {
38
     let data:any = {
38
     let data:any = {
39
       username: name,
39
       username: name,
40
       password: pwd,
40
       password: pwd,
41
+			captcha: captcha, 
42
+			captchaId: captchaId,
41
       type: "PC",
43
       type: "PC",
42
     };
44
     };
43
     data = {
45
     data = {
@@ -1278,4 +1280,8 @@ export class MainService {
1278
 		});
1280
 		});
1279
 	}
1281
 	}
1280
 	
1282
 	
1283
+	// 获取登录验证码
1284
+	getLoginCode(data){
1285
+		return this.http.get(host.host + "/auth/captcha", {});
1286
+	}
1281
 }
1287
 }

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

@@ -375,6 +375,12 @@ export class ToolService {
375
 				case "batchProcessing":
375
 				case "batchProcessing":
376
 				  coopBtns.batchProcessing = true; //批量不处理
376
 				  coopBtns.batchProcessing = true; //批量不处理
377
 				  break;
377
 				  break;
378
+				case "unlock":
379
+				  coopBtns.unlock = true; //解锁
380
+				  break;
381
+					case "lock":
382
+					  coopBtns.lock = true; //锁定
383
+					  break;
378
       }
384
       }
379
     });
385
     });
380
     console.log(coopBtns);
386
     console.log(coopBtns);

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

@@ -567,6 +567,9 @@ export class FuwutaiComponent implements OnInit {
567
           if (go === "&go&") {
567
           if (go === "&go&") {
568
             this.applyDept = data["createDept"].id;
568
             this.applyDept = data["createDept"].id;
569
             this.applyStartDept = data["createDept"];
569
             this.applyStartDept = data["createDept"];
570
+						this.patientObj = data["patient"] ? data["patient"] : null;
571
+						this.patientCode = data["patient"] ? data["patient"].patientCode : null;
572
+						this.taskTypeId = data["taskTypeId"];
570
             this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
573
             this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
571
             this.showPromptModal("建单", true, "", "closeGo");
574
             this.showPromptModal("建单", true, "", "closeGo");
572
           } else {
575
           } else {
@@ -580,6 +583,9 @@ export class FuwutaiComponent implements OnInit {
580
 					if (go === "&go&") {
583
 					if (go === "&go&") {
581
 						this.applyDept = data["createDept"].id;
584
 						this.applyDept = data["createDept"].id;
582
 						this.applyStartDept = data["createDept"];
585
 						this.applyStartDept = data["createDept"];
586
+						this.patientObj = data["patient"] ? data["patient"] : null;
587
+						this.patientCode = data["patient"] ? data["patient"].patientCode : null;
588
+						this.taskTypeId = data["taskTypeId"];
583
 						this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
589
 						this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
584
 						this.showPromptModal("建单", false, data["msg"], "closeGo");
590
 						this.showPromptModal("建单", false, data["msg"], "closeGo");
585
 					}else{
591
 					}else{
@@ -591,6 +597,9 @@ export class FuwutaiComponent implements OnInit {
591
 					if (go === "&go&") {
597
 					if (go === "&go&") {
592
 						this.applyDept = data["createDept"].id;
598
 						this.applyDept = data["createDept"].id;
593
 						this.applyStartDept = data["createDept"];
599
 						this.applyStartDept = data["createDept"];
600
+						this.patientObj = data["patient"] ? data["patient"] : null;
601
+						this.patientCode = data["patient"] ? data["patient"].patientCode : null;
602
+						this.taskTypeId = data["taskTypeId"];
594
 						this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
603
 						this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
595
 					}
604
 					}
596
 					//重复建单那策略
605
 					//重复建单那策略
@@ -632,6 +641,9 @@ export class FuwutaiComponent implements OnInit {
632
         if (go === "&go&") {
641
         if (go === "&go&") {
633
           this.applyDept = data["createDept"].id;
642
           this.applyDept = data["createDept"].id;
634
           this.applyStartDept = data["createDept"];
643
           this.applyStartDept = data["createDept"];
644
+					this.patientObj = data["patient"] ? data["patient"] : null;
645
+					this.patientCode = data["patient"] ? data["patient"].patientCode : null;
646
+					this.taskTypeId = data["taskTypeId"];
635
           this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
647
           this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
636
           this.showPromptModal("建单", true, "", "closeGo");
648
           this.showPromptModal("建单", true, "", "closeGo");
637
         } else {
649
         } else {
@@ -645,6 +657,9 @@ export class FuwutaiComponent implements OnInit {
645
 				 if (go === "&go&") {
657
 				 if (go === "&go&") {
646
 				 	this.applyDept = data["createDept"].id;
658
 				 	this.applyDept = data["createDept"].id;
647
 				 	this.applyStartDept = data["createDept"];
659
 				 	this.applyStartDept = data["createDept"];
660
+					this.patientObj = data["patient"] ? data["patient"] : null;
661
+					this.patientCode = data["patient"] ? data["patient"].patientCode : null;
662
+					this.taskTypeId = data["taskTypeId"];
648
 				 	this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
663
 				 	this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
649
 				 }
664
 				 }
650
 				 //重复建单那策略
665
 				 //重复建单那策略
@@ -707,6 +722,9 @@ export class FuwutaiComponent implements OnInit {
707
         if (go === "&go&") {
722
         if (go === "&go&") {
708
           this.applyDept = data["createDept"].id;
723
           this.applyDept = data["createDept"].id;
709
           this.applyStartDept = data["createDept"];
724
           this.applyStartDept = data["createDept"];
725
+					this.patientObj = data["patient"] ? data["patient"] : null;
726
+					this.patientCode = data["patient"] ? data["patient"].patientCode : null;
727
+					this.taskTypeId = data["taskTypeId"];
710
           this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
728
           this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
711
           this.showPromptModal("建单", true, "", "closeGo");
729
           this.showPromptModal("建单", true, "", "closeGo");
712
         } else {
730
         } else {
@@ -721,6 +739,9 @@ export class FuwutaiComponent implements OnInit {
721
 				if (go === "&go&") {
739
 				if (go === "&go&") {
722
 					this.applyDept = data["createDept"].id;
740
 					this.applyDept = data["createDept"].id;
723
 					this.applyStartDept = data["createDept"];
741
 					this.applyStartDept = data["createDept"];
742
+					this.patientObj = data["patient"] ? data["patient"] : null;
743
+					this.patientCode = data["patient"] ? data["patient"].patientCode : null;
744
+					this.taskTypeId = data["taskTypeId"];
724
 					this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
745
 					this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
725
 				}
746
 				}
726
 				//重复建单那策略
747
 				//重复建单那策略
@@ -777,6 +798,9 @@ export class FuwutaiComponent implements OnInit {
777
         if (go === "&go&") {
798
         if (go === "&go&") {
778
           this.applyDept = data["createDept"].id;
799
           this.applyDept = data["createDept"].id;
779
           this.applyStartDept = data["createDept"];
800
           this.applyStartDept = data["createDept"];
801
+					this.patientObj = data["patient"] ? data["patient"] : null;
802
+					this.patientCode = data["patient"] ? data["patient"].patientCode : null;
803
+					this.taskTypeId = data["taskTypeId"];
780
           this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
804
           this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
781
           this.showPromptModal("建单", true, "", "closeGo");
805
           this.showPromptModal("建单", true, "", "closeGo");
782
         } else {
806
         } else {
@@ -791,6 +815,9 @@ export class FuwutaiComponent implements OnInit {
791
 				if (go === "&go&") {
815
 				if (go === "&go&") {
792
 					this.applyDept = data["createDept"].id;
816
 					this.applyDept = data["createDept"].id;
793
 					this.applyStartDept = data["createDept"];
817
 					this.applyStartDept = data["createDept"];
818
+					this.patientObj = data["patient"] ? data["patient"] : null;
819
+					this.patientCode = data["patient"] ? data["patient"].patientCode : null;
820
+					this.taskTypeId = data["taskTypeId"];
794
 					this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
821
 					this.incidentModel.incomingPhone = this.callNumber = this.incidentModel.contactsInformation = data["phone"];
795
 				}
822
 				}
796
 				//重复建单那策略
823
 				//重复建单那策略
@@ -3264,6 +3291,7 @@ export class FuwutaiComponent implements OnInit {
3264
           patient.department && (this.applicationDepartmentList = [patient.department]);
3291
           patient.department && (this.applicationDepartmentList = [patient.department]);
3265
           patient.department && (this.applyDept = patient.department.id);
3292
           patient.department && (this.applyDept = patient.department.id);
3266
           patient.department && this.tabClick('患者转运', false, patient);
3293
           patient.department && this.tabClick('患者转运', false, patient);
3294
+					this.crossHospital==1 && patient.hospitalDTO && (this.inHosId = patient.hospitalDTO.id);
3267
           // patient.department && (this.patientList = [patient]);
3295
           // patient.department && (this.patientList = [patient]);
3268
           patient.department && (this.patientZy = patient.patientCode);
3296
           patient.department && (this.patientZy = patient.patientCode);
3269
           console.log(this.patientList)
3297
           console.log(this.patientList)

+ 12 - 0
src/app/views/login/login.component.html

@@ -27,6 +27,18 @@
27
                 </nz-input-group>
27
                 </nz-input-group>
28
               </nz-form-control>
28
               </nz-form-control>
29
             </nz-form-item>
29
             </nz-form-item>
30
+						<nz-form-item *ngIf="!isSingleSignOn && verificationCode==1">
31
+						  <nz-form-control nzErrorTip="请输入验证码!">
32
+						    <nz-input-group>
33
+									<div class="login-code">
34
+										<input class="inp" nz-input formControlName="code" (keyup)="enterUp($event)"
35
+										  placeholder="请输入验证码" autocomplete="new-password" />
36
+										<img (click)="resetCode()" class="code-img" [src]="loginImg" alt="">	
37
+									</div>
38
+								</nz-input-group>
39
+						  </nz-form-control>
40
+						</nz-form-item>
41
+						<div class="error-tip" *ngIf="errorTip">{{errorTip}}</div>
30
             <label nz-checkbox formControlName="remember" class="mb8">
42
             <label nz-checkbox formControlName="remember" class="mb8">
31
               <span>记住密码</span>
43
               <span>记住密码</span>
32
             </label>
44
             </label>

+ 17 - 2
src/app/views/login/login.component.less

@@ -44,7 +44,7 @@
44
 
44
 
45
       .form_wrap {
45
       .form_wrap {
46
         width: 480px;
46
         width: 480px;
47
-        height: 400px;
47
+        // height: 400px;
48
         padding: 32px 40px;
48
         padding: 32px 40px;
49
         background-color: #ffffff;
49
         background-color: #ffffff;
50
         border-radius: 8px;
50
         border-radius: 8px;
@@ -61,7 +61,22 @@
61
             height: 52px;
61
             height: 52px;
62
             font-size: 16px;
62
             font-size: 16px;
63
           }
63
           }
64
-
64
+					
65
+					.login-code{
66
+						display: flex;
67
+						justify-content: space-between;
68
+						.code-img{
69
+							width: 150px;
70
+							margin-left: 20px;
71
+							cursor: pointer;
72
+						}
73
+					}
74
+					
75
+					.error-tip{
76
+						color: red;
77
+						margin-bottom: 10px;
78
+					}
79
+					
65
           .loginBtn {
80
           .loginBtn {
66
             button {
81
             button {
67
               width: 100%;
82
               width: 100%;

+ 83 - 13
src/app/views/login/login.component.ts

@@ -1,6 +1,6 @@
1
 import { Component, OnInit } from "@angular/core";
1
 import { Component, OnInit } from "@angular/core";
2
 import { Router, NavigationStart } from "@angular/router";
2
 import { Router, NavigationStart } from "@angular/router";
3
-import { FormBuilder, Validators, FormGroup } from "@angular/forms";
3
+import { FormBuilder, Validators, FormGroup, FormControl } from "@angular/forms";
4
 import { NzMessageService } from "ng-zorro-antd/message";
4
 import { NzMessageService } from "ng-zorro-antd/message";
5
 import { MainService } from "../../services/main.service";
5
 import { MainService } from "../../services/main.service";
6
 import http from "../../../assets/js/http";
6
 import http from "../../../assets/js/http";
@@ -38,6 +38,7 @@ export class LoginComponent implements OnInit {
38
   }
38
   }
39
   ngOnInit() {
39
   ngOnInit() {
40
     this.http = http;
40
     this.http = http;
41
+		this.getSysConfig();
41
     this.isSingleSignOn = location.href.includes("?");
42
     this.isSingleSignOn = location.href.includes("?");
42
 		localStorage.removeItem("scanCodeData");
43
 		localStorage.removeItem("scanCodeData");
43
 		localStorage.removeItem("pathologyActiveIndex");
44
 		localStorage.removeItem("pathologyActiveIndex");
@@ -81,7 +82,13 @@ export class LoginComponent implements OnInit {
81
       (data) => {
82
       (data) => {
82
         this.loading = false;
83
         this.loading = false;
83
         this.msg.remove(loadingId);
84
         this.msg.remove(loadingId);
84
-        this.apiLogin(data.userId, data.pwd, true);
85
+				if(data.status==200){
86
+					this.apiLogin(data.userId, data.pwd, "", "", true);
87
+				}else{
88
+					this.msg.error(data.remarks, {
89
+					  nzDuration: 1000,
90
+					});
91
+				}
85
       },
92
       },
86
       (err) => {
93
       (err) => {
87
         this.loading = false;
94
         this.loading = false;
@@ -143,8 +150,43 @@ export class LoginComponent implements OnInit {
143
       userName: [username || null, [Validators.required]],
150
       userName: [username || null, [Validators.required]],
144
       password: [passsword || null, [Validators.required]],
151
       password: [passsword || null, [Validators.required]],
145
       remember: [Boolean(localStorage.getItem("remember"))],
152
       remember: [Boolean(localStorage.getItem("remember"))],
153
+			code: [null, [Validators.required]]
146
     });
154
     });
155
+		
156
+		if(this.isSingleSignOn){
157
+			this.validateForm.removeControl('code');
158
+		}else{
159
+			this.validateForm.addControl('code', new FormControl(null, Validators.required));
160
+		}
147
   }
161
   }
162
+	// 重新请求验证码
163
+	resetCode(){
164
+		this.getCode()
165
+	}
166
+	
167
+	// 获取系统安全配置
168
+	verificationCode:any;
169
+	getSysConfig(){
170
+		this.tool.getSysNameAndLogoAsync().subscribe(result => {
171
+			this.verificationCode = result.verificationCode;
172
+			if(this.verificationCode==1){
173
+				this.getCode();
174
+			}
175
+		})
176
+	}
177
+	
178
+	// 获取验证码
179
+	loginImg:any;
180
+	captchaId:any;
181
+	getCode(){
182
+		this.mainService.getLoginCode({}).subscribe((data:any)=> {
183
+			if(data.status==200){
184
+				this.captchaId = data.data.captchaId
185
+				this.loginImg = data.data.image
186
+			}
187
+		})
188
+	}
189
+	
148
   // enter触发
190
   // enter触发
149
   enterUp(e): void {
191
   enterUp(e): void {
150
     let keyCode = e.which || e.keyCode || 0;
192
     let keyCode = e.which || e.keyCode || 0;
@@ -166,16 +208,32 @@ export class LoginComponent implements OnInit {
166
       this.msg.info("用户名或密码不能为空!");
208
       this.msg.info("用户名或密码不能为空!");
167
       return;
209
       return;
168
     }
210
     }
169
-    this.apiLogin(
170
-      this.validateForm.value.userName,
171
-      this.validateForm.value.password
172
-    );
211
+		if(!this.isSingleSignOn && this.verificationCode==1){
212
+			if (
213
+			  !this.validateForm.value.code) {
214
+			  this.msg.info("验证码不能为空!");
215
+			  return;
216
+			}
217
+			this.apiLogin(
218
+			  this.validateForm.value.userName,
219
+			  this.validateForm.value.password,
220
+				this.validateForm.value.code,
221
+				this.captchaId
222
+			);
223
+		}else{
224
+			this.apiLogin(
225
+			  this.validateForm.value.userName,
226
+			  this.validateForm.value.password
227
+			);
228
+		}
229
+
173
   }
230
   }
174
   // 登录接口,true是单点登录
231
   // 登录接口,true是单点登录
175
-  apiLogin(user, pwd, flag = false) {
232
+	errorTip:any;
233
+  apiLogin(user, pwd, captcha="", captchaId="", flag = false) {
176
     const loadingId = this.msg.loading("登录中..", { nzDuration: 0 }).messageId;
234
     const loadingId = this.msg.loading("登录中..", { nzDuration: 0 }).messageId;
177
     this.loading = true;
235
     this.loading = true;
178
-    this.mainService.login(user, pwd).subscribe((data) => {
236
+    this.mainService.login(user, pwd, captcha, captchaId).subscribe((data) => {
179
       this.loading = false;
237
       this.loading = false;
180
       this.msg.remove(loadingId);
238
       this.msg.remove(loadingId);
181
       if (data.status == 200) {
239
       if (data.status == 200) {
@@ -196,6 +254,7 @@ export class LoginComponent implements OnInit {
196
         console.log(data.user);
254
         console.log(data.user);
197
         let hosId = data.user.user.currentHospital ? data.user.user.currentHospital.id : ''
255
         let hosId = data.user.user.currentHospital ? data.user.user.currentHospital.id : ''
198
         this.tool.getSysNameAndLogoAsync(hosId).subscribe(result => {
256
         this.tool.getSysNameAndLogoAsync(hosId).subscribe(result => {
257
+					// this.verificationCode = result.verificationCode;
199
           let marking = result.project || '';
258
           let marking = result.project || '';
200
           let logoTitle = result.sysName || '';
259
           let logoTitle = result.sysName || '';
201
           let logoUrl = location.origin + '/file' + result.logo || '';
260
           let logoUrl = location.origin + '/file' + result.logo || '';
@@ -209,11 +268,22 @@ export class LoginComponent implements OnInit {
209
 					this.toRoute2(data);
268
 					this.toRoute2(data);
210
           this.initMenu(data.user.menu);
269
           this.initMenu(data.user.menu);
211
         })
270
         })
212
-      } else {
213
-        this.msg.error(data.remarks, {
214
-          nzDuration: 1000,
215
-        });
216
-      }
271
+				this.errorTip = null;
272
+      } else if(data.status == 501){
273
+				this.msg.error('验证码错误', {
274
+				  nzDuration: 1000,
275
+				});
276
+				this.errorTip = null;
277
+      } else if(data.status == 506){
278
+				this.errorTip = data.tips
279
+				this.resetCode()
280
+      }else {
281
+				this.errorTip = null;
282
+				this.resetCode()
283
+				this.msg.error(data.remarks, {
284
+				  nzDuration: 1000,
285
+				});
286
+			}
217
     });
287
     });
218
   }
288
   }
219
   // 页面跳转
289
   // 页面跳转

+ 5 - 0
src/app/views/system-config/system-config.component.html

@@ -17,6 +17,11 @@
17
 	<ng-container *ngIf="activeTagLink === 'nurseConfigQuick'">
17
 	<ng-container *ngIf="activeTagLink === 'nurseConfigQuick'">
18
 	  <app-configuration-quick></app-configuration-quick>
18
 	  <app-configuration-quick></app-configuration-quick>
19
 	</ng-container>
19
 	</ng-container>
20
+	
21
+	<!-- 系统安全 -->
22
+	<ng-container *ngIf="activeTagLink === 'systemSecurity'">
23
+	  <app-configuration-system-security></app-configuration-system-security>
24
+	</ng-container>
20
 </div>
25
 </div>
21
 
26
 
22
 
27
 

+ 3 - 1
src/app/views/system-config/system-config.module.ts

@@ -6,12 +6,14 @@ import { SystemConfigComponent } from './system-config.component';
6
 import { ShareModule } from 'src/app/share/share.module';
6
 import { ShareModule } from 'src/app/share/share.module';
7
 import { ConfigurationKeyComponent } from 'src/app/components/configurationCenter/configuration-key/configuration-key.component';
7
 import { ConfigurationKeyComponent } from 'src/app/components/configurationCenter/configuration-key/configuration-key.component';
8
 import { ConfigurationQuickComponent } from 'src/app/components/configurationCenter/configuration-quick/configuration-quick.component';
8
 import { ConfigurationQuickComponent } from 'src/app/components/configurationCenter/configuration-quick/configuration-quick.component';
9
+import { ConfigurationSystemSecurityComponent } from 'src/app/components/configurationCenter/configuration-system-security/configuration-system-security.component';
9
 
10
 
10
 @NgModule({
11
 @NgModule({
11
   declarations: [
12
   declarations: [
12
     SystemConfigComponent,
13
     SystemConfigComponent,
13
     ConfigurationKeyComponent,
14
     ConfigurationKeyComponent,
14
-		ConfigurationQuickComponent
15
+		ConfigurationQuickComponent,
16
+		ConfigurationSystemSecurityComponent
15
   ],
17
   ],
16
   imports: [
18
   imports: [
17
     CommonModule,
19
     CommonModule,

+ 12 - 3
src/app/views/users-management/users-management.component.html

@@ -61,9 +61,10 @@
61
             <th nzWidth="10%">绩效ID</th>
61
             <th nzWidth="10%">绩效ID</th>
62
             <th nzWidth="5%">性别</th>
62
             <th nzWidth="5%">性别</th>
63
             <th nzWidth="10%">手机号码</th>
63
             <th nzWidth="10%">手机号码</th>
64
-            <th nzWidth="15%">所属科室</th>
65
-            <th nzWidth="15%">所属组</th>
64
+            <th nzWidth="10%">所属科室</th>
65
+            <th nzWidth="10%">所属组</th>
66
             <th nzWidth="10%">用户类型</th>
66
             <th nzWidth="10%">用户类型</th>
67
+						<th nzWidth="10%">用户状态</th>
67
             <th nzWidth="15%">操作</th>
68
             <th nzWidth="15%">操作</th>
68
           </tr>
69
           </tr>
69
         </thead>
70
         </thead>
@@ -89,12 +90,15 @@
89
               </div>
90
               </div>
90
             </td>
91
             </td>
91
             <td>{{ data.usertype ? data.usertype.name : '' }}</td>
92
             <td>{{ data.usertype ? data.usertype.name : '' }}</td>
93
+						<td>{{ data.accountStatus?.name }}</td>
92
             <td>
94
             <td>
93
               <div class="coop">
95
               <div class="coop">
94
                 <span *ngIf="coopBtns.look && !checkOptionsOne[0].checked" (click)="detail(data.id)">查看</span>
96
                 <span *ngIf="coopBtns.look && !checkOptionsOne[0].checked" (click)="detail(data.id)">查看</span>
95
                 <span *ngIf="coopBtns.edit || checkOptionsOne[0].checked" (click)="edit(data)">编辑</span>
97
                 <span *ngIf="coopBtns.edit || checkOptionsOne[0].checked" (click)="edit(data)">编辑</span>
96
 								<span *ngIf="checkOptionsOne[0].checked" (click)="recover(data)">恢复</span>
98
 								<span *ngIf="checkOptionsOne[0].checked" (click)="recover(data)">恢复</span>
97
-                <span *ngIf="coopBtns.del && !checkOptionsOne[0].checked" (click)="del(data)">删除</span>
99
+                <span *ngIf="coopBtns.unlock && data.accountStatus.value==2" (click)="unlock(data,1)">解锁</span>
100
+								<span *ngIf="coopBtns.lock && data.accountStatus.value==1" (click)="unlock(data,2)">锁定</span>
101
+								<span *ngIf="coopBtns.del && !checkOptionsOne[0].checked" (click)="del(data)">删除</span>
98
                 <span *ngIf="coopBtns.resetPwd && !checkOptionsOne[0].checked" (click)="resetPwd(data)">重置密码</span>
102
                 <span *ngIf="coopBtns.resetPwd && !checkOptionsOne[0].checked" (click)="resetPwd(data)">重置密码</span>
99
               </div>
103
               </div>
100
             </td>
104
             </td>
@@ -268,6 +272,11 @@
268
   (confirmDelEvent)="confirmRecover()" (cancelDelEvent)="hideRecoverModal()" content="您确认恢复此用户吗?" confirmTxt="是" cancelTxt="否">
272
   (confirmDelEvent)="confirmRecover()" (cancelDelEvent)="hideRecoverModal()" content="您确认恢复此用户吗?" confirmTxt="是" cancelTxt="否">
269
 </app-dialog-delete>
273
 </app-dialog-delete>
270
 
274
 
275
+<!-- 解锁/锁定 -->
276
+<app-dialog-delete [delModal]="lockModal" [btnLoading]="lockLoading" (hideDelModalEvent)="hideLockModal()"
277
+  (confirmDelEvent)="confirmLock()" (cancelDelEvent)="hideLockModal()" [content]="lockContent" confirmTxt="是" cancelTxt="否">
278
+</app-dialog-delete>
279
+
271
 <!-- 重置密码模态框 -->
280
 <!-- 重置密码模态框 -->
272
 <app-dialog-delete [delModal]="resetModal" (hideDelModalEvent)="hideResetModal()" [btnLoading]="btnLoading" [cancenlLoading]="cancenlLoading"
281
 <app-dialog-delete [delModal]="resetModal" (hideDelModalEvent)="hideResetModal()" [btnLoading]="btnLoading" [cancenlLoading]="cancenlLoading"
273
   (confirmDelEvent)="confirmReset()" (cancelDelEvent)="cancelReset()" content="是否重置密码?">
282
   (confirmDelEvent)="confirmReset()" (cancelDelEvent)="cancelReset()" content="是否重置密码?">

+ 45 - 2
src/app/views/users-management/users-management.component.ts

@@ -676,7 +676,49 @@ export class UsersManagementComponent implements OnInit {
676
         }
676
         }
677
       });
677
       });
678
   }
678
   }
679
-
679
+	
680
+	// 解锁/锁定
681
+	lockModal:boolean = false;
682
+	lockLoading:boolean = false;
683
+	lockContent:any;
684
+	lockType:any;
685
+	unlock(data, type){
686
+		this.coopId = data.id;
687
+		this.lockType = type
688
+		if(type ==1){
689
+			this.lockContent = '您确定要解锁账号吗?'
690
+		}else{
691
+			this.lockContent = '您确定要锁定账号吗?锁定后用户将不能登录系统,包括PC登录、微信、单点登录!'
692
+		}
693
+		this.lockModal = true
694
+	}
695
+	
696
+	// 确定解锁/锁定
697
+	confirmLock(){
698
+		let that = this;
699
+		let query = {
700
+			user:{
701
+				id: this.coopId,
702
+				upType: this.lockType == 1 ? 'unlock' : 'lock'
703
+			}
704
+		}
705
+		that.lockLoading = true;
706
+		that.mainService.coopData("updData", "user", query).subscribe((data) => {
707
+		    that.lockLoading = false;
708
+		    that.hideLockModal();
709
+		    if (data["status"] == 200) {
710
+		      that.showPromptModal(this.lockType == 1?"解锁":"锁定", true, "");
711
+		    } else {
712
+		      that.showPromptModal(this.lockType == 1?"解锁":"锁定", false, data["msg"]);
713
+		    }
714
+		  });
715
+	}
716
+	
717
+	// 关闭锁定modal
718
+	hideLockModal(){
719
+		this.lockModal = false;
720
+	}
721
+	
680
 	// 确认恢复
722
 	// 确认恢复
681
 	confirmRecover() {
723
 	confirmRecover() {
682
 	  let that = this;
724
 	  let that = this;
@@ -712,7 +754,8 @@ export class UsersManagementComponent implements OnInit {
712
   // 重置密码
754
   // 重置密码
713
   resetModal: boolean = false; //删除模态框
755
   resetModal: boolean = false; //删除模态框
714
   resetPwd(data) {
756
   resetPwd(data) {
715
-    this.coopId = data.id;
757
+    
758
+		this.coopId = data.id;
716
     this.resetModal = true;
759
     this.resetModal = true;
717
   }
760
   }
718
   // 确认重置密码
761
   // 确认重置密码