MaxKey 2 лет назад
Родитель
Сommit
200ce2cb0d
24 измененных файлов с 329 добавлено и 270 удалено
  1. 0 1
      maxkey-core/src/main/java/org/maxkey/entity/Groups.java
  2. 13 2
      maxkey-core/src/main/java/org/maxkey/entity/Institutions.java
  3. 11 1
      maxkey-core/src/main/java/org/maxkey/entity/Resources.java
  4. 21 1
      maxkey-core/src/main/java/org/maxkey/entity/Roles.java
  5. 4 2
      maxkey-core/src/main/java/org/maxkey/persistence/repository/InstitutionsRepository.java
  6. 4 4
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/entity/Institutions.ts
  7. 4 4
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/entity/Resources.ts
  8. 19 42
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/groups/group-editer/group-editer.component.html
  9. 23 0
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/groups/group-editer/group-editer.component.ts
  10. 35 46
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/config/accounts-strategy/accounts-strategy-editer/accounts-strategy-editer.component.html
  11. 22 0
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/config/accounts-strategy/accounts-strategy-editer/accounts-strategy-editer.component.ts
  12. 17 28
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/config/adapters/adapter-editer/adapter-editer.component.html
  13. 2 0
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/config/adapters/adapters.component.ts
  14. 43 29
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/config/institutions/institutions.component.html
  15. 2 2
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/config/ldap-context/ldap-context.component.html
  16. 5 3
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/config/synchronizers/synchronizer-editer/synchronizer-editer.component.html
  17. 46 51
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/permissions/resources/resource-editer/resource-editer.component.html
  18. 20 43
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/permissions/roles/role-editer/role-editer.component.html
  19. 22 0
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/permissions/roles/role-editer/role-editer.component.ts
  20. 6 4
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/shared/shared.module.ts
  21. 3 1
      maxkey-web-frontend/maxkey-web-mgt-app/src/assets/i18n/en-US.json
  22. 4 2
      maxkey-web-frontend/maxkey-web-mgt-app/src/assets/i18n/zh-CN.json
  23. 3 1
      maxkey-web-frontend/maxkey-web-mgt-app/src/assets/i18n/zh-TW.json
  24. 0 3
      sql/MaxKey单点登录认证系统v2.9.0GA.chnr.json

+ 0 - 1
maxkey-core/src/main/java/org/maxkey/entity/Groups.java

@@ -50,7 +50,6 @@ public class Groups extends JpaBaseEntity implements Serializable {
     String orgIdsList;
     @Column
     String resumeTime; 
-    
     @Column
     String suspendTime;
     

+ 13 - 2
maxkey-core/src/main/java/org/maxkey/entity/Institutions.java

@@ -69,11 +69,14 @@ public class Institutions extends JpaBaseEntity implements Serializable {
 	@Column
 	private String logo;
 	@Column
+	private String domain;
+	@Column
 	private String frontTitle;
 	@Column
-	private String consoleTitle;
+	private String consoleDomain;
 	@Column
-	private String domain;
+	private String consoleTitle;
+	
 	@Column
 	private String captchaType;
 	@Column
@@ -135,6 +138,14 @@ public class Institutions extends JpaBaseEntity implements Serializable {
 		this.captchaType = captchaType;
 	}
 
+	public String getConsoleDomain() {
+		return consoleDomain;
+	}
+
+	public void setConsoleDomain(String consoleDomain) {
+		this.consoleDomain = consoleDomain;
+	}
+
 	public String getConsoleTitle() {
 		return consoleTitle;
 	}

+ 11 - 1
maxkey-core/src/main/java/org/maxkey/entity/Resources.java

@@ -37,6 +37,8 @@ public class Resources  extends JpaBaseEntity implements Serializable {
     @Column
     String name;
     @Column
+    String permission;
+    @Column
     int sortIndex;
     @Column
     String appId;
@@ -108,7 +110,15 @@ public class Resources  extends JpaBaseEntity implements Serializable {
         this.appName = appName;
     }
 
-    public String getParentId() {
+    public String getPermission() {
+		return permission;
+	}
+
+	public void setPermission(String permission) {
+		this.permission = permission;
+	}
+
+	public String getParentId() {
         return parentId;
     }
 

+ 21 - 1
maxkey-core/src/main/java/org/maxkey/entity/Roles.java

@@ -46,6 +46,10 @@ public class Roles extends JpaBaseEntity implements Serializable {
     @Column
     String orgIdsList;
     @Column
+    String resumeTime; 
+    @Column
+    String suspendTime;
+    @Column
     String status;
     @Column
     String description;
@@ -154,7 +158,23 @@ public class Roles extends JpaBaseEntity implements Serializable {
         this.orgIdsList = orgIdsList;
     }
 
-    public String getInstId() {
+    public String getResumeTime() {
+		return resumeTime;
+	}
+
+	public void setResumeTime(String resumeTime) {
+		this.resumeTime = resumeTime;
+	}
+
+	public String getSuspendTime() {
+		return suspendTime;
+	}
+
+	public void setSuspendTime(String suspendTime) {
+		this.suspendTime = suspendTime;
+	}
+
+	public String getInstId() {
 		return instId;
 	}
 

+ 4 - 2
maxkey-core/src/main/java/org/maxkey/persistence/repository/InstitutionsRepository.java

@@ -36,7 +36,7 @@ public class InstitutionsRepository {
     private static Logger _logger = LoggerFactory.getLogger(InstitutionsRepository.class);
     
     private static final String SELECT_STATEMENT = 
-    						"select * from  mxk_institutions where id = ? or domain = ? " ;
+    						"select * from  mxk_institutions where id = ? or domain = ? or consoledomain = ?" ;
     
     private static final String DEFAULT_INSTID = "1";
 
@@ -69,13 +69,14 @@ public class InstitutionsRepository {
         Institutions inst = institutionsStore.getIfPresent(mapper.get(instIdOrDomain)==null ? DEFAULT_INSTID : mapper.get(instIdOrDomain) );
         if(inst == null) {
 	        List<Institutions> institutions = 
-	        		jdbcTemplate.query(SELECT_STATEMENT,new InstitutionsRowMapper(),instIdOrDomain,instIdOrDomain);
+	        		jdbcTemplate.query(SELECT_STATEMENT,new InstitutionsRowMapper(),instIdOrDomain,instIdOrDomain,instIdOrDomain);
 	        
 	        if (institutions != null && institutions.size() > 0) {
 	        	inst = institutions.get(0);
 	        }
 	        if(inst != null ) {
 		        institutionsStore.put(inst.getDomain(), inst);
+		        institutionsStore.put(inst.getConsoleDomain(), inst);
 		        mapper.put(inst.getId(), inst.getDomain());
 	        }
         }
@@ -93,6 +94,7 @@ public class InstitutionsRepository {
         	institution.setLogo(rs.getString("logo"));
         	institution.setDomain(rs.getString("domain"));
         	institution.setFrontTitle(rs.getString("fronttitle"));
+        	institution.setConsoleDomain(rs.getString("consoledomain"));
         	institution.setConsoleTitle(rs.getString("consoletitle"));
         	institution.setCaptchaType(rs.getString("captchatype"));
         	institution.setCaptchaSupport(rs.getString("captchasupport"));

+ 4 - 4
maxkey-web-frontend/maxkey-web-mgt-app/src/app/entity/Institutions.ts

@@ -1,19 +1,18 @@
 /*
  * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- 
 
 import { BaseEntity } from './BaseEntity';
 
@@ -27,6 +26,7 @@ export class Institutions extends BaseEntity {
     logo!: String;
     frontTitle!: String;
     consoleTitle!: String;
+    consoleDomain!: String;
     domain!: String;
     captchaType!: String;
     captchaSupport!: String;

+ 4 - 4
maxkey-web-frontend/maxkey-web-mgt-app/src/app/entity/Resources.ts

@@ -1,24 +1,24 @@
 /*
  * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- 
 
 import { BaseEntity } from './BaseEntity';
 
 export class Resources extends BaseEntity {
     name!: String;
+    permission!: String;
     appId!: String;
     appName!: String;
     parentId!: String;

+ 19 - 42
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/groups/group-editer/group-editer.component.html

@@ -4,7 +4,8 @@
     <nz-form-item>
       <nz-form-label [nzMd]="6" nzRequired nzFor="id">{{ 'mxk.text.id' | i18n }}</nz-form-label>
       <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid id!">
-        <input [(ngModel)]="form.model.id" disabled="{{ isEdit }}" [ngModelOptions]="{ standalone: true }" nz-input name="id" id="id" />
+        <input [(ngModel)]="form.model.id" disabled="{{ isEdit }}" [ngModelOptions]="{ standalone: true }" nz-input
+          name="id" id="id" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
@@ -16,13 +17,8 @@
     <nz-form-item>
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="dynamic">{{ 'mxk.groups.dynamic' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid status!">
-        <nz-switch
-          [(ngModel)]="form.model.switch_dynamic"
-          [ngModelOptions]="{ standalone: true }"
-          name="dynamic"
-          [nzCheckedChildren]="checkedTemplate"
-          [nzUnCheckedChildren]="unCheckedTemplate"
-        ></nz-switch>
+        <nz-switch [(ngModel)]="form.model.switch_dynamic" [ngModelOptions]="{ standalone: true }" name="dynamic"
+          [nzCheckedChildren]="checkedTemplate" [nzUnCheckedChildren]="unCheckedTemplate"></nz-switch>
         <ng-template #checkedTemplate><i nz-icon nzType="check"></i></ng-template>
         <ng-template #unCheckedTemplate><i nz-icon nzType="close"></i></ng-template>
       </nz-form-control>
@@ -30,59 +26,40 @@
     <nz-form-item *ngIf="form.model.switch_dynamic">
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="resumeTime">{{ 'mxk.groups.resumeTime' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid port!">
-        <nz-time-picker
-          [(ngModel)]="form.model.picker_resumeTime"
-          [ngModelOptions]="{ standalone: true }"
-          nzFormat="HH:mm"
-          name="picker_resumeTime"
-          id="picker_resumeTime"
-        ></nz-time-picker>
+        <nz-time-picker [(ngModel)]="form.model.picker_resumeTime" [ngModelOptions]="{ standalone: true }"
+          nzFormat="HH:mm" name="picker_resumeTime" id="picker_resumeTime"></nz-time-picker>
       </nz-form-control>
     </nz-form-item>
     <nz-form-item *ngIf="form.model.switch_dynamic">
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="suspendTime">{{ 'mxk.groups.suspendTime' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid suspendTime!">
-        <nz-time-picker
-          [(ngModel)]="form.model.picker_suspendTime"
-          [ngModelOptions]="{ standalone: true }"
-          nzFormat="HH:mm"
-          name="picker_suspendTime"
-          id="picker_suspendTime"
-        ></nz-time-picker>
+        <nz-time-picker [(ngModel)]="form.model.picker_suspendTime" [ngModelOptions]="{ standalone: true }"
+          nzFormat="HH:mm" name="picker_suspendTime" id="picker_suspendTime"></nz-time-picker>
       </nz-form-control>
     </nz-form-item>
     <nz-form-item *ngIf="form.model.switch_dynamic">
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="orgIdsList">{{ 'mxk.groups.orgIdsList' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid upperCase!">
-        <input [(ngModel)]="form.model.orgIdsList" [ngModelOptions]="{ standalone: true }" nz-input name="orgIdsList" id="orgIdsList" />
+        <input type="hidden" [(ngModel)]="form.model.orgIdsList" [ngModelOptions]="{ standalone: true }" nz-input
+          name="orgIdsList" id="orgIdsList" />
+        <nz-tree-select nzVirtualHeight="300px" [nzMaxTagCount]="3" [(ngModel)]="selectValues"
+          [ngModelOptions]="{ standalone: true }" [nzNodes]="treeNodes.nodes" nzCheckable nzPlaceHolder="Please select"
+          [nzCheckStrictly]="true">
+        </nz-tree-select>
       </nz-form-control>
     </nz-form-item>
     <nz-form-item *ngIf="form.model.switch_dynamic">
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="filters">{{ 'mxk.groups.filters' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid filters!">
-        <textarea
-          rows="4"
-          nz-input
-          [(ngModel)]="form.model.filters"
-          [ngModelOptions]="{ standalone: true }"
-          nz-input
-          name="filters"
-          id="filters"
-        ></textarea>
+        <textarea rows="4" nz-input [(ngModel)]="form.model.filters" [ngModelOptions]="{ standalone: true }" nz-input
+          name="filters" id="filters"></textarea>
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="description">{{ 'mxk.text.description' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid encoding!">
-        <textarea
-          rows="4"
-          nz-input
-          [(ngModel)]="form.model.description"
-          [ngModelOptions]="{ standalone: true }"
-          nz-input
-          name="description"
-          id="description"
-        ></textarea>
+        <textarea rows="4" nz-input [(ngModel)]="form.model.description" [ngModelOptions]="{ standalone: true }"
+          nz-input name="description" id="description"></textarea>
       </nz-form-control>
     </nz-form-item>
   </form>
@@ -91,4 +68,4 @@
 <div *nzModalFooter>
   <button nz-button nzType="default" (click)="onClose($event)">{{ 'mxk.text.close' | i18n }}</button>
   <button nz-button nzType="primary" (click)="onSubmit($event)">{{ 'mxk.text.submit' | i18n }}</button>
-</div>
+</div>

+ 23 - 0
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/groups/group-editer/group-editer.component.ts

@@ -23,7 +23,9 @@ import { NzMessageService } from 'ng-zorro-antd/message';
 import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal';
 
 import { Groups } from '../../../../entity/Groups';
+import { TreeNodes } from '../../../../entity/TreeNodes';
 import { GroupsService } from '../../../../service/groups.service';
+import { OrganizationsService } from '../../../../service/organizations.service';
 
 @Component({
   selector: 'app-group-editer',
@@ -49,11 +51,17 @@ export class GroupEditerComponent implements OnInit {
       model: new Groups()
     };
 
+  // TreeNodes
+  treeNodes = new TreeNodes(false);
+
+  selectValues: string[] = [];
+
   formGroup: FormGroup = new FormGroup({});
 
   constructor(
     private modalRef: NzModalRef,
     private groupsService: GroupsService,
+    private orgsService: OrganizationsService,
     private fb: FormBuilder,
     private msg: NzMessageService,
     @Inject(ALAIN_I18N_TOKEN) private i18n: I18NService,
@@ -61,14 +69,24 @@ export class GroupEditerComponent implements OnInit {
   ) { }
 
   ngOnInit(): void {
+    this.tree();
     if (this.isEdit) {
       this.groupsService.get(`${this.id}`).subscribe(res => {
         this.form.model.init(res.data);
+        this.selectValues = this.form.model.orgIdsList.split(',');
         this.cdr.detectChanges();
       });
     }
   }
 
+  tree(): void {
+    this.orgsService.tree({}).subscribe(res => {
+      this.treeNodes.init(res.data);
+      this.treeNodes.nodes = this.treeNodes.build();
+      this.cdr.detectChanges();
+    });
+  }
+
   onClose(e: MouseEvent): void {
     e.preventDefault();
     this.modalRef.destroy({ refresh: false });
@@ -78,6 +96,11 @@ export class GroupEditerComponent implements OnInit {
     e.preventDefault();
     this.form.submitting = true;
     this.form.model.trans();
+    this.form.model.orgIdsList = '';
+    this.selectValues.forEach(value => {
+      this.form.model.orgIdsList = `${this.form.model.orgIdsList + value},`;
+    });
+
     (this.isEdit ? this.groupsService.update(this.form.model) : this.groupsService.add(this.form.model)).subscribe(res => {
       if (res.code == 0) {
         this.msg.success(this.i18n.fanyi(this.isEdit ? 'mxk.alert.update.success' : 'mxk.alert.add.success'));

+ 35 - 46
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/config/accounts-strategy/accounts-strategy-editer/accounts-strategy-editer.component.html

@@ -4,37 +4,35 @@
     <nz-form-item>
       <nz-form-label [nzMd]="6" nzFor="id">{{ 'mxk.text.id' | i18n }}</nz-form-label>
       <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid id!">
-        <input [(ngModel)]="form.model.id" disabled="{{ isEdit }}" [ngModelOptions]="{ standalone: true }" nz-input name="id" id="id" />
+        <input [(ngModel)]="form.model.id" disabled="{{ isEdit }}" [ngModelOptions]="{ standalone: true }" nz-input
+          name="id" id="id" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
-      <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="name">{{ 'mxk.accountsstrategy.name' | i18n }}</nz-form-label>
+      <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="name">{{ 'mxk.accountsstrategy.name' | i18n }}
+      </nz-form-label>
       <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not validminLength!">
         <input [(ngModel)]="form.model.name" [ngModelOptions]="{ standalone: true }" nz-input name="name" id="name" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
-      <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="appName">{{ 'mxk.accountsstrategy.appName' | i18n }}</nz-form-label>
+      <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="appName">{{ 'mxk.accountsstrategy.appName' | i18n }}
+      </nz-form-label>
       <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid appName!">
         <nz-input-group nzSearch [nzAddOnAfter]="suffixButton">
-          <input
-            [(ngModel)]="form.model.appName"
-            [ngModelOptions]="{ standalone: true }"
-            readonly
-            type="text"
-            nz-input
-            name="appName"
-            id="appName"
-          />
+          <input [(ngModel)]="form.model.appName" [ngModelOptions]="{ standalone: true }" readonly type="text" nz-input
+            name="appName" id="appName" />
         </nz-input-group>
         <ng-template #suffixButton>
           <button nz-button nzType="primary" nzSearch (click)="onSelect($event)">{{ 'mxk.text.select' | i18n }}</button>
         </ng-template>
-        <input type="hidden" [(ngModel)]="form.model.appId" [ngModelOptions]="{ standalone: true }" nz-input name="appId" id="appId" />
+        <input type="hidden" [(ngModel)]="form.model.appId" [ngModelOptions]="{ standalone: true }" nz-input
+          name="appId" id="appId" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
-      <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="mapping">{{ 'mxk.accountsstrategy.mapping' | i18n }}</nz-form-label>
+      <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="mapping">{{ 'mxk.accountsstrategy.mapping' | i18n }}
+      </nz-form-label>
       <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid mapping!">
         <nz-select [(ngModel)]="form.model.mapping" [ngModelOptions]="{ standalone: true }">
           <nz-option nzValue="username" nzLabel="username"></nz-option>
@@ -47,36 +45,39 @@
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
-      <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="suffixes">{{ 'mxk.accountsstrategy.suffixes' | i18n }}</nz-form-label>
+      <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="suffixes">{{ 'mxk.accountsstrategy.suffixes' | i18n }}
+      </nz-form-label>
       <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid suffixes!">
-        <input [(ngModel)]="form.model.suffixes" [ngModelOptions]="{ standalone: true }" nz-input name="suffixes" id="suffixes" />
+        <input [(ngModel)]="form.model.suffixes" [ngModelOptions]="{ standalone: true }" nz-input name="suffixes"
+          id="suffixes" />
       </nz-form-control>
     </nz-form-item>
 
     <nz-form-item>
-      <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="orgIdsList">{{ 'mxk.accountsstrategy.orgIdsList' | i18n }}</nz-form-label>
+      <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="orgIdsList">{{ 'mxk.accountsstrategy.orgIdsList' | i18n }}
+      </nz-form-label>
       <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid upperCase!">
-        <input [(ngModel)]="form.model.orgIdsList" [ngModelOptions]="{ standalone: true }" nz-input name="orgIdsList" id="orgIdsList" />
+        <input type="hidden" [(ngModel)]="form.model.orgIdsList" [ngModelOptions]="{ standalone: true }" nz-input
+          name="orgIdsList" id="orgIdsList" />
+        <nz-tree-select nzVirtualHeight="300px" [nzMaxTagCount]="3" [(ngModel)]="selectValues"
+          [ngModelOptions]="{ standalone: true }" [nzNodes]="treeNodes.nodes" nzCheckable nzPlaceHolder="Please select"
+          [nzCheckStrictly]="true">
+        </nz-tree-select>
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="filters">{{ 'mxk.accountsstrategy.filters' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid filters!">
-        <textarea
-          rows="4"
-          nz-input
-          [(ngModel)]="form.model.filters"
-          [ngModelOptions]="{ standalone: true }"
-          nz-input
-          name="filters"
-          id="filters"
-        ></textarea>
+        <textarea rows="4" nz-input [(ngModel)]="form.model.filters" [ngModelOptions]="{ standalone: true }" nz-input
+          name="filters" id="filters"></textarea>
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
-      <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="createType">{{ 'mxk.accountsstrategy.createType' | i18n }}</nz-form-label>
+      <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="createType">{{ 'mxk.accountsstrategy.createType' | i18n }}
+      </nz-form-label>
       <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid createType!">
-        <nz-radio-group [(ngModel)]="form.model.createType" [ngModelOptions]="{ standalone: true }" nzButtonStyle="solid">
+        <nz-radio-group [(ngModel)]="form.model.createType" [ngModelOptions]="{ standalone: true }"
+          nzButtonStyle="solid">
           <label nz-radio-button nzValue="manual">{{ 'mxk.text.manual' | i18n }}</label>
           <label nz-radio-button nzValue="automatic">{{ 'mxk.text.automatic' | i18n }}</label>
         </nz-radio-group>
@@ -85,27 +86,15 @@
     <nz-form-item style="display: none">
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="description">{{ 'mxk.text.description' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid encoding!">
-        <textarea
-          rows="4"
-          nz-input
-          [(ngModel)]="form.model.description"
-          [ngModelOptions]="{ standalone: true }"
-          nz-input
-          name="description"
-          id="description"
-        ></textarea>
+        <textarea rows="4" nz-input [(ngModel)]="form.model.description" [ngModelOptions]="{ standalone: true }"
+          nz-input name="description" id="description"></textarea>
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
       <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="status">{{ 'mxk.text.status' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid status!">
-        <nz-switch
-          [(ngModel)]="form.model.switch_status"
-          [ngModelOptions]="{ standalone: true }"
-          name="status"
-          [nzCheckedChildren]="checkedTemplate"
-          [nzUnCheckedChildren]="unCheckedTemplate"
-        ></nz-switch>
+        <nz-switch [(ngModel)]="form.model.switch_status" [ngModelOptions]="{ standalone: true }" name="status"
+          [nzCheckedChildren]="checkedTemplate" [nzUnCheckedChildren]="unCheckedTemplate"></nz-switch>
         <ng-template #checkedTemplate><i nz-icon nzType="check"></i></ng-template>
         <ng-template #unCheckedTemplate><i nz-icon nzType="close"></i></ng-template>
       </nz-form-control>
@@ -116,4 +105,4 @@
 <div *nzModalFooter>
   <button nz-button nzType="default" (click)="onClose($event)">{{ 'mxk.text.close' | i18n }}</button>
   <button nz-button nzType="primary" (click)="onSubmit($event)">{{ 'mxk.text.submit' | i18n }}</button>
-</div>
+</div>

+ 22 - 0
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/config/accounts-strategy/accounts-strategy-editer/accounts-strategy-editer.component.ts

@@ -23,7 +23,9 @@ import { NzMessageService } from 'ng-zorro-antd/message';
 import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal';
 
 import { AccountsStrategy } from '../../../../entity/AccountsStrategy';
+import { TreeNodes } from '../../../../entity/TreeNodes';
 import { AccountsStrategyService } from '../../../../service/accounts-strategy.service';
+import { OrganizationsService } from '../../../../service/organizations.service';
 import { SelectAppsComponent } from '../../../apps/select-apps/select-apps.component';
 
 @Component({
@@ -51,10 +53,15 @@ export class AccountsStrategyEditerComponent implements OnInit {
     };
 
   formGroup: FormGroup = new FormGroup({});
+  // TreeNodes
+  treeNodes = new TreeNodes(false);
+
+  selectValues: string[] = [];
 
   constructor(
     private modal: NzModalRef,
     private accountsStrategyService: AccountsStrategyService,
+    private orgsService: OrganizationsService,
     private fb: FormBuilder,
     private modalService: NzModalService,
     private viewContainerRef: ViewContainerRef,
@@ -64,14 +71,24 @@ export class AccountsStrategyEditerComponent implements OnInit {
   ) { }
 
   ngOnInit(): void {
+    this.tree();
     if (this.isEdit) {
       this.accountsStrategyService.get(`${this.id}`).subscribe(res => {
         this.form.model.init(res.data);
+        this.selectValues = this.form.model.orgIdsList.split(',');
         this.cdr.detectChanges();
       });
     }
   }
 
+  tree(): void {
+    this.orgsService.tree({}).subscribe(res => {
+      this.treeNodes.init(res.data);
+      this.treeNodes.nodes = this.treeNodes.build();
+      this.cdr.detectChanges();
+    });
+  }
+
   onSelect(e: MouseEvent): void {
     e.preventDefault();
     const modal = this.modalService.create({
@@ -100,6 +117,11 @@ export class AccountsStrategyEditerComponent implements OnInit {
     e.preventDefault();
     this.form.submitting = true;
     this.form.model.trans();
+    this.form.model.orgIdsList = '';
+    this.selectValues.forEach(value => {
+      this.form.model.orgIdsList = `${this.form.model.orgIdsList + value},`;
+    });
+
     (this.isEdit ? this.accountsStrategyService.update(this.form.model) : this.accountsStrategyService.add(this.form.model)).subscribe(
       res => {
         if (res.code == 0) {

+ 17 - 28
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/config/adapters/adapter-editer/adapter-editer.component.html

@@ -2,43 +2,32 @@
 <div>
   <form nz-form [formGroup]="formGroup" (ngSubmit)="onSubmit($event)" se-container="1">
     <nz-form-item>
-      <nz-form-label [nzMd]="6" nzFor="id">{{ 'mxk.text.id' | i18n }}</nz-form-label>
-      <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid id!">
-        <input [(ngModel)]="form.model.id" disabled="{{ isEdit }}" [ngModelOptions]="{ standalone: true }" nz-input name="id" id="id" />
+      <nz-form-label [nzMd]="4" nzFor="id">{{ 'mxk.text.id' | i18n }}</nz-form-label>
+      <nz-form-control [nzMd]="20" nzErrorTip="The input is not valid id!">
+        <input [(ngModel)]="form.model.id" disabled="{{ isEdit }}" [ngModelOptions]="{ standalone: true }" nz-input
+          name="id" id="id" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
-      <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="name">{{ 'mxk.adapters.name' | i18n }}</nz-form-label>
-      <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not validminLength!">
+      <nz-form-label [nzSm]="4" [nzMd]="4" [nzXs]="24" nzRequired nzFor="name">{{ 'mxk.adapters.name' | i18n }}
+      </nz-form-label>
+      <nz-form-control [nzSm]="20" [nzMd]="20" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not validminLength!">
         <input [(ngModel)]="form.model.name" [ngModelOptions]="{ standalone: true }" nz-input name="name" id="name" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
-      <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="adapter">{{ 'mxk.adapters.adapter' | i18n }}</nz-form-label>
-      <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid adapter!">
-        <textarea
-          rows="4"
-          nz-input
-          [(ngModel)]="form.model.adapter"
-          [ngModelOptions]="{ standalone: true }"
-          nz-input
-          name="adapter"
-          id="adapter"
-        ></textarea>
+      <nz-form-label nzRequired [nzSm]="4" [nzXs]="24" nzFor="adapter">{{ 'mxk.adapters.adapter' | i18n }}
+      </nz-form-label>
+      <nz-form-control [nzSm]="20" [nzXs]="24" nzErrorTip="The input is not valid adapter!">
+        <textarea rows="4" nz-input [(ngModel)]="form.model.adapter" [ngModelOptions]="{ standalone: true }" nz-input
+          name="adapter" id="adapter"></textarea>
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
-      <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="description">{{ 'mxk.text.description' | i18n }}</nz-form-label>
-      <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid encoding!">
-        <textarea
-          rows="4"
-          nz-input
-          [(ngModel)]="form.model.description"
-          [ngModelOptions]="{ standalone: true }"
-          nz-input
-          name="description"
-          id="description"
-        ></textarea>
+      <nz-form-label [nzSm]="4" [nzXs]="24" nzFor="description">{{ 'mxk.text.description' | i18n }}</nz-form-label>
+      <nz-form-control [nzSm]="20" [nzXs]="24" nzErrorTip="The input is not valid encoding!">
+        <textarea rows="4" nz-input [(ngModel)]="form.model.description" [ngModelOptions]="{ standalone: true }"
+          nz-input name="description" id="description"></textarea>
       </nz-form-control>
     </nz-form-item>
   </form>
@@ -47,4 +36,4 @@
 <div *nzModalFooter>
   <button nz-button nzType="default" (click)="onClose($event)">{{ 'mxk.text.close' | i18n }}</button>
   <button nz-button nzType="primary" (click)="onSubmit($event)">{{ 'mxk.text.submit' | i18n }}</button>
-</div>
+</div>

+ 2 - 0
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/config/adapters/adapters.component.ts

@@ -130,6 +130,7 @@ export class AdaptersComponent implements OnInit {
         isEdit: false,
         id: ''
       },
+      nzWidth: 600,
       nzOnOk: () => new Promise(resolve => setTimeout(resolve, 1000))
     });
     // Return a result when closed
@@ -150,6 +151,7 @@ export class AdaptersComponent implements OnInit {
         isEdit: true,
         id: editiId
       },
+      nzWidth: 600,
       nzOnOk: () => new Promise(resolve => setTimeout(resolve, 1000))
     });
     // Return a result when closed

+ 43 - 29
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/config/institutions/institutions.component.html

@@ -4,7 +4,8 @@
     <nz-form-item style="display: none">
       <nz-form-label [nzMd]="6" nzRequired nzFor="id">{{ 'mxk.institutions.id' | i18n }}</nz-form-label>
       <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid id!">
-        <input [(ngModel)]="form.model.id" [disabled]="true" [ngModelOptions]="{ standalone: true }" nz-input name="id" id="id" />
+        <input [(ngModel)]="form.model.id" [disabled]="true" [ngModelOptions]="{ standalone: true }" nz-input name="id"
+          id="id" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
@@ -16,13 +17,8 @@
     <nz-form-item>
       <nz-form-label [nzMd]="6" nzRequired nzFor="fullName">{{ 'mxk.institutions.fullName' | i18n }}</nz-form-label>
       <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid fullName!">
-        <input [(ngModel)]="form.model.fullName" [ngModelOptions]="{ standalone: true }" nz-input name="fullName" id="fullName" />
-      </nz-form-control>
-    </nz-form-item>
-    <nz-form-item>
-      <nz-form-label [nzMd]="6" nzRequired nzFor="domain">{{ 'mxk.institutions.domain' | i18n }}</nz-form-label>
-      <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid domain!">
-        <input [(ngModel)]="form.model.domain" [ngModelOptions]="{ standalone: true }" nz-input name="domain" id="domain" />
+        <input [(ngModel)]="form.model.fullName" [ngModelOptions]="{ standalone: true }" nz-input name="fullName"
+          id="fullName" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
@@ -32,27 +28,47 @@
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
+      <nz-form-label [nzMd]="6" nzFor="defaultUri">{{ 'mxk.institutions.defaultUri' | i18n }}</nz-form-label>
+      <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid defaultUri!">
+        <input [(ngModel)]="form.model.defaultUri" [ngModelOptions]="{ standalone: true }" nz-input name="defaultUri"
+          id="defaultUri" />
+      </nz-form-control>
+    </nz-form-item>
+    <nz-form-item>
+      <nz-form-label [nzMd]="6" nzRequired nzFor="domain">{{ 'mxk.institutions.domain' | i18n }}</nz-form-label>
+      <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid domain!">
+        <input [(ngModel)]="form.model.domain" [ngModelOptions]="{ standalone: true }" nz-input name="domain"
+          id="domain" />
+      </nz-form-control>
+    </nz-form-item>
+    <nz-form-item>
       <nz-form-label [nzMd]="6" nzRequired nzFor="frontTitle">{{ 'mxk.institutions.frontTitle' | i18n }}</nz-form-label>
       <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid frontTitle!">
-        <input [(ngModel)]="form.model.frontTitle" [ngModelOptions]="{ standalone: true }" nz-input name="frontTitle" id="frontTitle" />
+        <input [(ngModel)]="form.model.frontTitle" [ngModelOptions]="{ standalone: true }" nz-input name="frontTitle"
+          id="frontTitle" />
+      </nz-form-control>
+    </nz-form-item>
+    <nz-form-item>
+      <nz-form-label [nzMd]="6" nzRequired nzFor="consoleDomain">{{ 'mxk.institutions.consoleDomain' | i18n }}
+      </nz-form-label>
+      <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid consoleDomain!">
+        <input [(ngModel)]="form.model.consoleDomain" [ngModelOptions]="{ standalone: true }" nz-input
+          name="consoleDomain" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
-      <nz-form-label [nzMd]="6" nzRequired nzFor="consoleTitle">{{ 'mxk.institutions.consoleTitle' | i18n }}</nz-form-label>
+      <nz-form-label [nzMd]="6" nzRequired nzFor="consoleTitle">{{ 'mxk.institutions.consoleTitle' | i18n }}
+      </nz-form-label>
       <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid consoleTitle!">
-        <input
-          [(ngModel)]="form.model.consoleTitle"
-          [ngModelOptions]="{ standalone: true }"
-          nz-input
-          name="consoleTitle"
-          id="consoleTitle"
-        />
+        <input [(ngModel)]="form.model.consoleTitle" [ngModelOptions]="{ standalone: true }" nz-input
+          name="consoleTitle" id="consoleTitle" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
       <nz-form-label [nzMd]="6" nzFor="captchaSupport">{{ 'mxk.institutions.captchaSupport' | i18n }}</nz-form-label>
       <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid captchaSupport!">
-        <nz-radio-group [(ngModel)]="form.model.captchaSupport" [ngModelOptions]="{ standalone: true }" nzButtonStyle="solid">
+        <nz-radio-group [(ngModel)]="form.model.captchaSupport" [ngModelOptions]="{ standalone: true }"
+          nzButtonStyle="solid">
           <label nz-radio-button nzValue="YES">{{ 'mxk.text.yes' | i18n }}</label>
           <label nz-radio-button nzValue="NO">{{ 'mxk.text.no' | i18n }}</label>
         </nz-radio-group>
@@ -69,33 +85,31 @@
     </nz-form-item>
 
     <nz-form-item>
-      <nz-form-label [nzMd]="6" nzFor="defaultUri">{{ 'mxk.institutions.defaultUri' | i18n }}</nz-form-label>
-      <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid defaultUri!">
-        <input [(ngModel)]="form.model.defaultUri" [ngModelOptions]="{ standalone: true }" nz-input name="defaultUri" id="defaultUri" />
-      </nz-form-control>
-    </nz-form-item>
-    <nz-form-item>
       <nz-form-label [nzMd]="6" nzFor="contact">{{ 'mxk.institutions.contact' | i18n }}</nz-form-label>
       <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid contact!">
-        <input [(ngModel)]="form.model.contact" [ngModelOptions]="{ standalone: true }" nz-input name="contact" id="contact" />
+        <input [(ngModel)]="form.model.contact" [ngModelOptions]="{ standalone: true }" nz-input name="contact"
+          id="contact" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
       <nz-form-label [nzMd]="6" nzFor="phone">{{ 'mxk.institutions.phone' | i18n }}</nz-form-label>
       <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid phone!">
-        <input [(ngModel)]="form.model.phone" [ngModelOptions]="{ standalone: true }" nz-input name="phone" id="phone" />
+        <input [(ngModel)]="form.model.phone" [ngModelOptions]="{ standalone: true }" nz-input name="phone"
+          id="phone" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
       <nz-form-label [nzMd]="6" nzFor="email">{{ 'mxk.institutions.email' | i18n }}</nz-form-label>
       <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid email!">
-        <input [(ngModel)]="form.model.email" [ngModelOptions]="{ standalone: true }" nz-input name="email" id="email" />
+        <input [(ngModel)]="form.model.email" [ngModelOptions]="{ standalone: true }" nz-input name="email"
+          id="email" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
       <nz-form-label [nzMd]="6" nzFor="address">{{ 'mxk.institutions.address' | i18n }}</nz-form-label>
       <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid address!">
-        <input [(ngModel)]="form.model.address" [ngModelOptions]="{ standalone: true }" nz-input name="address" id="address" />
+        <input [(ngModel)]="form.model.address" [ngModelOptions]="{ standalone: true }" nz-input name="address"
+          id="address" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item style="width: 100%">
@@ -104,4 +118,4 @@
       </nz-form-control>
     </nz-form-item>
   </form>
-</nz-card>
+</nz-card>

+ 2 - 2
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/config/ldap-context/ldap-context.component.html

@@ -101,14 +101,14 @@
         <ng-template #unCheckedTemplate><i nz-icon nzType="close"></i></ng-template>
       </nz-form-control>
     </nz-form-item>
-    <nz-form-item>
+    <nz-form-item *ngIf="form.model.switch_sslSwitch">
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="trustStore">{{ 'mxk.ldapcontext.trustStore' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid trustStore!">
         <input [(ngModel)]="form.model.trustStore" [ngModelOptions]="{ standalone: true }" nz-input name="trustStore"
           id="trustStore" />
       </nz-form-control>
     </nz-form-item>
-    <nz-form-item>
+    <nz-form-item *ngIf="form.model.switch_sslSwitch">
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="trustStorePassword">{{ 'mxk.ldapcontext.trustStorePassword' | i18n }}
       </nz-form-label>
       <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid trustStorePassword!">

+ 5 - 3
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/config/synchronizers/synchronizer-editer/synchronizer-editer.component.html

@@ -33,7 +33,7 @@
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="scheduler">{{ 'mxk.synchronizers.scheduler' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid icon!">
         <input [(ngModel)]="form.model.scheduler" [ngModelOptions]="{ standalone: true }" nz-input name="scheduler"
-          id="scheduler" />
+          placeholder="0 0 12 * * ?" id="scheduler" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item *ngIf="
@@ -99,7 +99,8 @@
         <ng-template #unCheckedTemplate><i nz-icon nzType="close"></i></ng-template>
       </nz-form-control>
     </nz-form-item>
-    <nz-form-item *ngIf="form.model.sourceType == 'LDAP' || form.model.sourceType == 'MSAD'">
+    <nz-form-item
+      *ngIf="(form.model.sourceType == 'LDAP' || form.model.sourceType == 'MSAD') && form.model.switch_sslSwitch">
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="trustStore">{{ 'mxk.synchronizers.trustStore' | i18n }}
       </nz-form-label>
       <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid trustStore!">
@@ -107,7 +108,8 @@
           id="trustStore" />
       </nz-form-control>
     </nz-form-item>
-    <nz-form-item *ngIf="form.model.sourceType == 'LDAP' || form.model.sourceType == 'MSAD'">
+    <nz-form-item
+      *ngIf="(form.model.sourceType == 'LDAP' || form.model.sourceType == 'MSAD') && form.model.switch_sslSwitch">
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="trustStorePassword">{{ 'mxk.synchronizers.trustStorePassword' | i18n
         }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid sortIndex!">

+ 46 - 51
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/permissions/resources/resource-editer/resource-editer.component.html

@@ -4,7 +4,8 @@
     <nz-form-item>
       <nz-form-label [nzMd]="6" nzFor="id">{{ 'mxk.resources.id' | i18n }}</nz-form-label>
       <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid id!">
-        <input [(ngModel)]="form.model.id" disabled="{{ isEdit }}" [ngModelOptions]="{ standalone: true }" nz-input name="id" id="id" />
+        <input [(ngModel)]="form.model.id" disabled="{{ isEdit }}" [ngModelOptions]="{ standalone: true }" nz-input
+          name="id" id="id" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
@@ -14,9 +15,12 @@
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
-      <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="resourceType">{{ 'mxk.resources.resourceType' | i18n }}</nz-form-label>
-      <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid resourceType!">
-        <nz-select [(ngModel)]="form.model.resourceType" [ngModelOptions]="{ standalone: true }" name="resourceType" id="resourceType">
+      <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="resourceType">{{ 'mxk.resources.resourceType' | i18n }}
+      </nz-form-label>
+      <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48"
+        nzErrorTip="The input is not valid resourceType!">
+        <nz-select [(ngModel)]="form.model.resourceType" [ngModelOptions]="{ standalone: true }" name="resourceType"
+          id="resourceType">
           <nz-option nzValue="MENU" nzLabel="{{ 'mxk.resources.resourceType.MENU' | i18n }}"></nz-option>
           <nz-option nzValue="PAGE" nzLabel="{{ 'mxk.resources.resourceType.PAGE' | i18n }}"></nz-option>
           <nz-option nzValue="MODULE" nzLabel="{{ 'mxk.resources.resourceType.MODULE' | i18n }}"></nz-option>
@@ -29,83 +33,74 @@
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
-      <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="parentId">{{ 'mxk.resources.parentId' | i18n }}</nz-form-label>
+      <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="parentId">{{ 'mxk.resources.parentId' | i18n }}
+      </nz-form-label>
       <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid parentId!">
-        <input [(ngModel)]="form.model.parentId" [ngModelOptions]="{ standalone: true }" nz-input name="parentId" id="parentId" />
+        <input [(ngModel)]="form.model.parentId" [ngModelOptions]="{ standalone: true }" nz-input name="parentId"
+          id="parentId" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="parentName">{{ 'mxk.resources.parentName' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid parentName!">
-        <input
-          [(ngModel)]="form.model.parentName"
-          readonly
-          [ngModelOptions]="{ standalone: true }"
-          nz-input
-          name="parentName"
-          id="parentName"
-        />
+        <input [(ngModel)]="form.model.parentName" readonly [ngModelOptions]="{ standalone: true }" nz-input
+          name="parentName" id="parentName" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="resourceUrl">{{ 'mxk.resources.resourceUrl' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid resourceUrl!">
-        <input [(ngModel)]="form.model.resourceUrl" [ngModelOptions]="{ standalone: true }" nz-input name="resourceUrl" id="resourceUrl" />
+        <input [(ngModel)]="form.model.resourceUrl" [ngModelOptions]="{ standalone: true }" nz-input name="resourceUrl"
+          id="resourceUrl" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
-      <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="resourceAction">{{ 'mxk.resources.resourceAction' | i18n }}</nz-form-label>
-      <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid resourceAction!">
-        <input
-          [(ngModel)]="form.model.resourceAction"
-          [ngModelOptions]="{ standalone: true }"
-          nz-input
-          name="resourceAction"
-          id="resourceAction"
-        />
+      <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="permission">{{ 'mxk.resources.permission' | i18n }}</nz-form-label>
+      <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid permission!">
+        <input [(ngModel)]="form.model.permission" [ngModelOptions]="{ standalone: true }" nz-input name="permission"
+          id="permission" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
-      <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="resourceStyle">{{ 'mxk.resources.resourceStyle' | i18n }}</nz-form-label>
-      <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid resourceStyle!">
-        <input
-          [(ngModel)]="form.model.resourceStyle"
-          [ngModelOptions]="{ standalone: true }"
-          nz-input
-          name="resourceStyle"
-          id="resourceStyle"
-        />
+      <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="resourceAction">{{ 'mxk.resources.resourceAction' | i18n }}
+      </nz-form-label>
+      <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48"
+        nzErrorTip="The input is not valid resourceAction!">
+        <input [(ngModel)]="form.model.resourceAction" [ngModelOptions]="{ standalone: true }" nz-input
+          name="resourceAction" id="resourceAction" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
-      <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="resourceIcon">{{ 'mxk.resources.resourceIcon' | i18n }}</nz-form-label>
-      <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid resourceIcon!">
-        <input
-          [(ngModel)]="form.model.resourceIcon"
-          [ngModelOptions]="{ standalone: true }"
-          nz-input
-          name="resourceIcon"
-          id="resourceIcon"
-        />
+      <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="resourceStyle">{{ 'mxk.resources.resourceStyle' | i18n }}
+      </nz-form-label>
+      <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48"
+        nzErrorTip="The input is not valid resourceStyle!">
+        <input [(ngModel)]="form.model.resourceStyle" [ngModelOptions]="{ standalone: true }" nz-input
+          name="resourceStyle" id="resourceStyle" />
+      </nz-form-control>
+    </nz-form-item>
+    <nz-form-item>
+      <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="resourceIcon">{{ 'mxk.resources.resourceIcon' | i18n }}
+      </nz-form-label>
+      <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48"
+        nzErrorTip="The input is not valid resourceIcon!">
+        <input [(ngModel)]="form.model.resourceIcon" [ngModelOptions]="{ standalone: true }" nz-input
+          name="resourceIcon" id="resourceIcon" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="sortIndex">{{ 'mxk.text.sortIndex' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzMd]="18" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not valid sortIndex!">
-        <input [(ngModel)]="form.model.sortIndex" [ngModelOptions]="{ standalone: true }" nz-input name="sortIndex" id="sortIndex" />
+        <input [(ngModel)]="form.model.sortIndex" [ngModelOptions]="{ standalone: true }" nz-input name="sortIndex"
+          id="sortIndex" />
       </nz-form-control>
     </nz-form-item>
 
     <nz-form-item>
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="status">{{ 'mxk.text.status' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid status!">
-        <nz-switch
-          [(ngModel)]="form.model.switch_status"
-          [ngModelOptions]="{ standalone: true }"
-          name="status"
-          [nzCheckedChildren]="checkedTemplate"
-          [nzUnCheckedChildren]="unCheckedTemplate"
-        ></nz-switch>
+        <nz-switch [(ngModel)]="form.model.switch_status" [ngModelOptions]="{ standalone: true }" name="status"
+          [nzCheckedChildren]="checkedTemplate" [nzUnCheckedChildren]="unCheckedTemplate"></nz-switch>
         <ng-template #checkedTemplate><i nz-icon nzType="check"></i></ng-template>
         <ng-template #unCheckedTemplate><i nz-icon nzType="close"></i></ng-template>
       </nz-form-control>
@@ -116,4 +111,4 @@
 <div *nzModalFooter>
   <button nz-button nzType="default" (click)="onClose($event)">{{ 'mxk.text.close' | i18n }}</button>
   <button nz-button nzType="primary" (click)="onSubmit($event)">{{ 'mxk.text.submit' | i18n }}</button>
-</div>
+</div>

+ 20 - 43
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/permissions/roles/role-editer/role-editer.component.html

@@ -4,7 +4,8 @@
     <nz-form-item>
       <nz-form-label [nzMd]="6" nzRequired nzFor="id">{{ 'mxk.text.id' | i18n }}</nz-form-label>
       <nz-form-control [nzMd]="18" nzErrorTip="The input is not valid id!">
-        <input [(ngModel)]="form.model.id" disabled="{{ isEdit }}" [ngModelOptions]="{ standalone: true }" nz-input name="id" id="id" />
+        <input [(ngModel)]="form.model.id" disabled="{{ isEdit }}" [ngModelOptions]="{ standalone: true }" nz-input
+          name="id" id="id" />
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
@@ -16,13 +17,8 @@
     <nz-form-item>
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="dynamic">{{ 'mxk.roles.dynamic' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid status!">
-        <nz-switch
-          [(ngModel)]="form.model.switch_dynamic"
-          [ngModelOptions]="{ standalone: true }"
-          name="dynamic"
-          [nzCheckedChildren]="checkedTemplate"
-          [nzUnCheckedChildren]="unCheckedTemplate"
-        ></nz-switch>
+        <nz-switch [(ngModel)]="form.model.switch_dynamic" [ngModelOptions]="{ standalone: true }" name="dynamic"
+          [nzCheckedChildren]="checkedTemplate" [nzUnCheckedChildren]="unCheckedTemplate"></nz-switch>
         <ng-template #checkedTemplate><i nz-icon nzType="check"></i></ng-template>
         <ng-template #unCheckedTemplate><i nz-icon nzType="close"></i></ng-template>
       </nz-form-control>
@@ -30,59 +26,40 @@
     <nz-form-item *ngIf="form.model.switch_dynamic">
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="resumeTime">{{ 'mxk.roles.resumeTime' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid port!">
-        <nz-time-picker
-          [(ngModel)]="form.model.picker_resumeTime"
-          [ngModelOptions]="{ standalone: true }"
-          nzFormat="HH:mm"
-          name="picker_resumeTime"
-          id="picker_resumeTime"
-        ></nz-time-picker>
+        <nz-time-picker [(ngModel)]="form.model.picker_resumeTime" [ngModelOptions]="{ standalone: true }"
+          nzFormat="HH:mm" name="picker_resumeTime" id="picker_resumeTime"></nz-time-picker>
       </nz-form-control>
     </nz-form-item>
     <nz-form-item *ngIf="form.model.switch_dynamic">
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="suspendTime">{{ 'mxk.roles.suspendTime' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid suspendTime!">
-        <nz-time-picker
-          [(ngModel)]="form.model.picker_suspendTime"
-          [ngModelOptions]="{ standalone: true }"
-          nzFormat="HH:mm"
-          name="picker_suspendTime"
-          id="picker_suspendTime"
-        ></nz-time-picker>
+        <nz-time-picker [(ngModel)]="form.model.picker_suspendTime" [ngModelOptions]="{ standalone: true }"
+          nzFormat="HH:mm" name="picker_suspendTime" id="picker_suspendTime"></nz-time-picker>
       </nz-form-control>
     </nz-form-item>
     <nz-form-item *ngIf="form.model.switch_dynamic">
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="orgIdsList">{{ 'mxk.roles.orgIdsList' | i18n }}</nz-form-label>
-      <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid upperCase!">
-        <input [(ngModel)]="form.model.orgIdsList" [ngModelOptions]="{ standalone: true }" nz-input name="orgIdsList" id="orgIdsList" />
+      <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid orgIdsList!">
+        <input type="hidden" [(ngModel)]="form.model.orgIdsList" [ngModelOptions]="{ standalone: true }" nz-input
+          name="orgIdsList" id="orgIdsList" />
+        <nz-tree-select nzVirtualHeight="300px" [nzMaxTagCount]="3" [(ngModel)]="selectValues"
+          [ngModelOptions]="{ standalone: true }" [nzNodes]="treeNodes.nodes" nzCheckable nzPlaceHolder="Please select"
+          [nzCheckStrictly]="true">
+        </nz-tree-select>
       </nz-form-control>
     </nz-form-item>
     <nz-form-item *ngIf="form.model.switch_dynamic">
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="filters">{{ 'mxk.roles.filters' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid filters!">
-        <textarea
-          rows="4"
-          nz-input
-          [(ngModel)]="form.model.filters"
-          [ngModelOptions]="{ standalone: true }"
-          nz-input
-          name="filters"
-          id="filters"
-        ></textarea>
+        <textarea rows="4" nz-input [(ngModel)]="form.model.filters" [ngModelOptions]="{ standalone: true }" nz-input
+          name="filters" id="filters"></textarea>
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
       <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="description">{{ 'mxk.text.description' | i18n }}</nz-form-label>
       <nz-form-control [nzSm]="18" [nzXs]="24" nzErrorTip="The input is not valid encoding!">
-        <textarea
-          rows="4"
-          nz-input
-          [(ngModel)]="form.model.description"
-          [ngModelOptions]="{ standalone: true }"
-          nz-input
-          name="description"
-          id="description"
-        ></textarea>
+        <textarea rows="4" nz-input [(ngModel)]="form.model.description" [ngModelOptions]="{ standalone: true }"
+          nz-input name="description" id="description"></textarea>
       </nz-form-control>
     </nz-form-item>
   </form>
@@ -91,4 +68,4 @@
 <div *nzModalFooter>
   <button nz-button nzType="default" (click)="onClose($event)">{{ 'mxk.text.close' | i18n }}</button>
   <button nz-button nzType="primary" (click)="onSubmit($event)">{{ 'mxk.text.submit' | i18n }}</button>
-</div>
+</div>

+ 22 - 0
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/permissions/roles/role-editer/role-editer.component.ts

@@ -23,7 +23,10 @@ import { NzMessageService } from 'ng-zorro-antd/message';
 import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal';
 import { Roles } from 'src/app/entity/Roles';
 
+import { TreeNodes } from '../../../../entity/TreeNodes';
+import { OrganizationsService } from '../../../../service/organizations.service';
 import { RolesService } from '../../../../service/roles.service';
+
 @Component({
   selector: 'app-role-editer',
   templateUrl: './role-editer.component.html',
@@ -47,12 +50,17 @@ export class RoleEditerComponent implements OnInit {
       submitting: false,
       model: new Roles()
     };
+  // TreeNodes
+  treeNodes = new TreeNodes(false);
+
+  selectValues: string[] = [];
 
   formGroup: FormGroup = new FormGroup({});
 
   constructor(
     private modalRef: NzModalRef,
     private rolesService: RolesService,
+    private orgsService: OrganizationsService,
     private fb: FormBuilder,
     private msg: NzMessageService,
     @Inject(ALAIN_I18N_TOKEN) private i18n: I18NService,
@@ -60,14 +68,24 @@ export class RoleEditerComponent implements OnInit {
   ) { }
 
   ngOnInit(): void {
+    this.tree();
     if (this.isEdit) {
       this.rolesService.get(`${this.id}`).subscribe(res => {
         this.form.model.init(res.data);
+        this.selectValues = this.form.model.orgIdsList.split(',');
         this.cdr.detectChanges();
       });
     }
   }
 
+  tree(): void {
+    this.orgsService.tree({}).subscribe(res => {
+      this.treeNodes.init(res.data);
+      this.treeNodes.nodes = this.treeNodes.build();
+      this.cdr.detectChanges();
+    });
+  }
+
   onClose(e: MouseEvent): void {
     e.preventDefault();
     this.modalRef.destroy({ refresh: false });
@@ -77,6 +95,10 @@ export class RoleEditerComponent implements OnInit {
     e.preventDefault();
     this.form.submitting = true;
     this.form.model.trans();
+    this.form.model.orgIdsList = '';
+    this.selectValues.forEach(value => {
+      this.form.model.orgIdsList = `${this.form.model.orgIdsList + value},`;
+    });
     (this.isEdit ? this.rolesService.update(this.form.model) : this.rolesService.add(this.form.model)).subscribe(res => {
       if (res.code == 0) {
         this.msg.success(this.i18n.fanyi(this.isEdit ? 'mxk.alert.update.success' : 'mxk.alert.add.success'));

+ 6 - 4
maxkey-web-frontend/maxkey-web-mgt-app/src/app/shared/shared.module.ts

@@ -1,19 +1,18 @@
 /*
  * Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *     http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- 
 
 import { CommonModule } from '@angular/common';
 import { NgModule, Type } from '@angular/core';
@@ -24,6 +23,7 @@ import { DelonFormModule } from '@delon/form';
 import { AlainThemeModule } from '@delon/theme';
 import { NzIconModule } from 'ng-zorro-antd/icon';
 import { NzTreeModule } from 'ng-zorro-antd/tree';
+import { NzTreeSelectModule } from 'ng-zorro-antd/tree-select';
 
 import { SHARED_DELON_MODULES } from './shared-delon.module';
 import { SHARED_ZORRO_MODULES } from './shared-zorro.module';
@@ -46,6 +46,7 @@ const DIRECTIVES: Array<Type<any>> = [];
     FormsModule,
     NzIconModule,
     NzTreeModule,
+    NzTreeSelectModule,
     RouterModule,
     ReactiveFormsModule,
     AlainThemeModule.forChild(),
@@ -65,6 +66,7 @@ const DIRECTIVES: Array<Type<any>> = [];
     CommonModule,
     FormsModule,
     NzTreeModule,
+    NzTreeSelectModule,
     ReactiveFormsModule,
     RouterModule,
     AlainThemeModule,

+ 3 - 1
maxkey-web-frontend/maxkey-web-mgt-app/src/assets/i18n/en-US.json

@@ -479,6 +479,7 @@
 		"resources": {
 			"id": "ID",
 			"name": "Resource",
+			"permission": "Permission",
 			"appId": "App Id",
 			"appName": "App Name",
 			"parentId": "Parent Id",
@@ -512,9 +513,10 @@
 			"email": "email",
 			"address": "address",
 			"logo": "LOGO",
+			"domain": "Domain",
 			"frontTitle": "Front Title",
 			"consoleTitle": "Console Title",
-			"domain": "Domain",
+			"consoleDomain": "Console Domain",
 			"captchaType": "Captcha Type",
 			"captchaType.text": "Text",
 			"captchaType.arithmetic": "Arithmetic",

+ 4 - 2
maxkey-web-frontend/maxkey-web-mgt-app/src/assets/i18n/zh-CN.json

@@ -478,6 +478,7 @@
 		"resources": {
 			"id": "资源编码",
 			"name": "资源名称",
+			"permission": "权限标识",
 			"appId": "应用编码",
 			"appName": "应用名称",
 			"parentId": "父级编码",
@@ -511,9 +512,10 @@
 			"email": "邮箱",
 			"address": "地址",
 			"logo": "LOGO",
-			"frontTitle": "系统名称",
-			"consoleTitle": "控制台名称",
 			"domain": "域名",
+			"frontTitle": "系統名称",
+			"consoleDomain": "控制台域名",
+			"consoleTitle": "控制台名称",
 			"captchaType": "验证码",
 			"captchaType.text": "字符",
 			"captchaType.arithmetic": "算术",

+ 3 - 1
maxkey-web-frontend/maxkey-web-mgt-app/src/assets/i18n/zh-TW.json

@@ -479,6 +479,7 @@
 		"resources": {
 			"id": "資源編碼",
 			"name": "資源名稱",
+			"permission": "許可權標識",
 			"appId": "應用編碼",
 			"appName": "應用名稱",
 			"parentId": "父級編碼",
@@ -512,9 +513,10 @@
 			"email": "郵箱",
 			"address": "地址",
 			"logo": "LOGO",
+			"domain": "域名",
 			"frontTitle": "系統名稱",
+			"consoleDomain": "控制台域名",
 			"consoleTitle": "控制台名稱",
-			"domain": "域名",
 			"captchaType": "驗證碼",
 			"captchaType.text": "字符",
 			"captchaType.arithmetic": "算術",

Разница между файлами не показана из-за своего большого размера
+ 0 - 3
sql/MaxKey单点登录认证系统v2.9.0GA.chnr.json


Некоторые файлы не были показаны из-за большого количества измененных файлов