Browse Source

Roles dynamic - >category

MaxKey 2 years ago
parent
commit
582fbe1463
15 changed files with 117 additions and 84 deletions
  1. 10 7
      maxkey-core/src/main/java/org/maxkey/entity/RoleMember.java
  2. 23 13
      maxkey-core/src/main/java/org/maxkey/entity/Roles.java
  3. 2 2
      maxkey-persistence/src/main/java/org/maxkey/persistence/service/RolesService.java
  4. 1 1
      maxkey-persistence/src/main/resources/org/maxkey/persistence/mapper/xml/mysql/RoleMemberMapper.xml
  5. 2 10
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/entity/Roles.ts
  6. 6 0
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/permissions/permissions.component.ts
  7. 1 3
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/role-members/role-members.component.html
  8. 4 0
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/role-members/role-members.component.ts
  9. 9 9
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/roles/role-editer/role-editer.component.html
  10. 10 3
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/roles/roles.component.html
  11. 10 0
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/roles/roles.component.ts
  12. 3 3
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/roles/select-roles/select-roles.component.html
  13. 5 2
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/config/ldap-context/ldap-context.component.html
  14. 30 30
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/permissions/privileges/privileges.component.html
  15. 1 1
      maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/permissions/privileges/privileges.component.ts

+ 10 - 7
maxkey-core/src/main/java/org/maxkey/entity/RoleMember.java

@@ -48,7 +48,7 @@ public class RoleMember extends UserInfo implements Serializable{
 	@Column
 	private String roleId;
 	private String roleName;
-	private String dynamic;
+	private String category;
 	@Column
 	private String memberId;
 	private String memberName;
@@ -160,14 +160,17 @@ public class RoleMember extends UserInfo implements Serializable{
 		this.memberName = memberName;
 	}
 
-	public String getDynamic() {
-		return dynamic;
+
+	public String getCategory() {
+		return category;
 	}
 
-	public void setDynamic(String dynamic) {
-		this.dynamic = dynamic;
+
+	public void setCategory(String category) {
+		this.category = category;
 	}
 
+
 	public String getInstId() {
 		return instId;
 	}
@@ -197,8 +200,8 @@ public class RoleMember extends UserInfo implements Serializable{
 		builder.append(roleId);
 		builder.append(", roleName=");
 		builder.append(roleName);
-		builder.append(", dynamic=");
-		builder.append(dynamic);
+		builder.append(", category=");
+		builder.append(category);
 		builder.append(", memberId=");
 		builder.append(memberId);
 		builder.append(", memberName=");

+ 23 - 13
maxkey-core/src/main/java/org/maxkey/entity/Roles.java

@@ -1,5 +1,5 @@
 /*
- * Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
+ * 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.
@@ -31,6 +31,16 @@ import org.hibernate.validator.constraints.Length;
 public class Roles extends JpaBaseEntity implements Serializable {
 
     private static final long serialVersionUID = 4660258495864814777L;
+    
+    public class Category{
+    	public static final String DYNAMIC = "dynamic";
+    	
+    	public static final String STATIC  = "static";
+    	
+    	public static final String APP     = "app";
+    }
+    
+    
     @Id
     @Column
     @GeneratedValue(strategy = GenerationType.AUTO, generator = "snowflakeid")
@@ -45,7 +55,7 @@ public class Roles extends JpaBaseEntity implements Serializable {
     String roleName;
     
     @Column
-    String dynamic;
+    String category;
 
     @Column
     String filters ;
@@ -185,20 +195,20 @@ public class Roles extends JpaBaseEntity implements Serializable {
 	 *		3, not filters
      */
     public void setDefaultAllUser() {
-    	this.dynamic = "1";
+    	this.category = "dynamic";
     	this.orgIdsList ="";
 		this.filters ="";
     }
-    
-    public String getDynamic() {
-        return dynamic;
-    }
 
-    public void setDynamic(String dynamic) {
-        this.dynamic = dynamic;
-    }
+    public String getCategory() {
+		return category;
+	}
+
+	public void setCategory(String category) {
+		this.category = category;
+	}
 
-    public String getFilters() {
+	public String getFilters() {
         return filters;
     }
 
@@ -255,8 +265,8 @@ public class Roles extends JpaBaseEntity implements Serializable {
 		builder.append(roleCode);
 		builder.append(", roleName=");
 		builder.append(roleName);
-		builder.append(", dynamic=");
-		builder.append(dynamic);
+		builder.append(", category=");
+		builder.append(category);
 		builder.append(", filters=");
 		builder.append(filters);
 		builder.append(", orgIdsList=");

+ 2 - 2
maxkey-persistence/src/main/java/org/maxkey/persistence/service/RolesService.java

@@ -1,5 +1,5 @@
 /*
- * Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
+ * 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.
@@ -79,7 +79,7 @@ public class RolesService  extends JpaBaseService<Roles> implements Serializable
 	}
 	
 	public void refreshDynamicRoles(Roles dynamicRole){
-	    if(dynamicRole.getDynamic().equals(ConstsStatus.ACTIVE+"")) {
+	    if(dynamicRole.getCategory().equals(Roles.Category.DYNAMIC)) {
 	        boolean isDynamicTimeSupport = false;
 	        boolean isBetweenEffectiveTime = false;
 	        if(StringUtils.isNotBlank(dynamicRole.getResumeTime())

+ 1 - 1
maxkey-persistence/src/main/resources/org/maxkey/persistence/mapper/xml/mysql/RoleMemberMapper.xml

@@ -16,7 +16,7 @@
 				rm.id as id,
 				r.id as roleid,
 				r.rolename,
-				r.dynamic dynamic,
+				r.category category,
 				u.username,
 				u.usertype,
 				u.windowsaccount,

+ 2 - 10
maxkey-web-frontend/maxkey-web-mgt-app/src/app/entity/Roles.ts

@@ -21,14 +21,13 @@ import { BaseEntity } from './BaseEntity';
 export class Roles extends BaseEntity {
     roleCode!: String;
     roleName!: String;
-    dynamic!: String;
+    category!: String;
     filters!: String;
     orgIdsList!: String;
     resumeTime!: String;
     suspendTime!: String;
     isdefault!: String;
 
-    switch_dynamic: boolean = false;
     picker_resumeTime: Date = new Date(format(new Date(), 'yyyy-MM-dd 00:00:00'));
     picker_suspendTime: Date = new Date(format(new Date(), 'yyyy-MM-dd 00:00:00'));
 
@@ -41,9 +40,7 @@ export class Roles extends BaseEntity {
         if (this.status == 1) {
             this.switch_status = true;
         }
-        if (this.dynamic == '1') {
-            this.switch_dynamic = true;
-        }
+
         if (this.resumeTime != '') {
             this.picker_resumeTime = new Date(format(new Date(), `yyyy-MM-dd ${this.resumeTime}:00`));
         }
@@ -57,11 +54,6 @@ export class Roles extends BaseEntity {
         } else {
             this.status = 0;
         }
-        if (this.switch_dynamic) {
-            this.dynamic = '1';
-        } else {
-            this.dynamic = '0';
-        }
 
         if (this.picker_resumeTime) {
             this.resumeTime = format(this.picker_resumeTime, 'HH:mm');

+ 6 - 0
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/permissions/permissions.component.ts

@@ -16,6 +16,7 @@
 
 import { ChangeDetectionStrategy, ViewContainerRef, ChangeDetectorRef, Component, OnInit, Inject } from '@angular/core';
 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
 import { I18NService } from '@core';
 import { _HttpClient, ALAIN_I18N_TOKEN, SettingsService } from '@delon/theme';
 import { format, addDays } from 'date-fns';
@@ -100,11 +101,16 @@ export class PermissionsComponent implements OnInit {
     private fb: FormBuilder,
     private msg: NzMessageService,
     @Inject(ALAIN_I18N_TOKEN) private i18n: I18NService,
+    private route: ActivatedRoute,
     private cdr: ChangeDetectorRef,
     private http: _HttpClient
   ) { }
 
   ngOnInit(): void {
+    if (this.route.snapshot.queryParams['roleId']) {
+      this.query.params.roleId = this.route.snapshot.queryParams['roleId'];
+      this.query.params.roleName = this.route.snapshot.queryParams['roleName'];
+    }
     this.query.tableInitialize = false;
   }
 

+ 1 - 3
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/role-members/role-members.component.html

@@ -57,7 +57,6 @@
               (nzCheckedChange)="onTableAllChecked($event)"></th>
             <th nzAlign="center">{{ 'mxk.roles.name' | i18n }}</th>
             <th nzAlign="center">{{ 'mxk.users.username' | i18n }}</th>
-            <th nzAlign="center">{{ 'mxk.users.employeeNumber' | i18n }}</th>
             <th nzAlign="center">{{ 'mxk.users.displayName' | i18n }}</th>
             <th nzAlign="center">{{ 'mxk.users.department' | i18n }}</th>
             <th nzAlign="center">{{ 'mxk.users.jobTitle' | i18n }}</th>
@@ -71,7 +70,6 @@
               (nzCheckedChange)="onTableItemChecked(data.id, $event)"></td>
             <td nzAlign="left"> {{ data.roleName }}</td>
             <td nzAlign="left"> {{ data.username }}</td>
-            <td nzAlign="left"> {{ data.employeeNumber }}</td>
             <td nzAlign="left"> {{ data.displayName }}</td>
             <td nzAlign="left"> {{ data.department }}</td>
             <td nzAlign="left"> {{ data.jobTitle }}</td>
@@ -79,7 +77,7 @@
               i18n) }}</td>
             <td nzAlign="left" nzBreakWord="false">
               <div nz-col>
-                <button *ngIf="data.dynamic == '0'" nz-button type="button" (click)="onDelete($event, data.id)"
+                <button *ngIf="data.category == 'static'" nz-button type="button" (click)="onDelete($event, data.id)"
                   nzDanger>{{
                   'mxk.text.delete' | i18n
                   }}</button>

+ 4 - 0
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/role-members/role-members.component.ts

@@ -110,6 +110,10 @@ export class RoleMembersComponent implements OnInit {
     if (this.route.snapshot.queryParams['username']) {
       this.query.params.username = this.route.snapshot.queryParams['username'];
     }
+    if (this.route.snapshot.queryParams['roleId']) {
+      this.query.params.roleId = this.route.snapshot.queryParams['roleId'];
+      this.query.params.roleName = this.route.snapshot.queryParams['roleName'];
+    }
     this.query.tableInitialize = false;
   }
 

+ 9 - 9
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/roles/role-editer/role-editer.component.html

@@ -22,29 +22,29 @@
       </nz-form-control>
     </nz-form-item>
     <nz-form-item>
-      <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="dynamic">{{ 'mxk.roles.dynamic' | i18n }}</nz-form-label>
+      <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="dynamic">{{ 'mxk.roles.category' | 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>
-        <ng-template #checkedTemplate><i nz-icon nzType="check"></i></ng-template>
-        <ng-template #unCheckedTemplate><i nz-icon nzType="close"></i></ng-template>
+        <nz-radio-group [(ngModel)]="form.model.category" [ngModelOptions]="{ standalone: true }" nzButtonStyle="solid">
+          <label nz-radio-button nzValue="static">{{ 'mxk.roles.category.static' | i18n }}</label>
+          <label nz-radio-button nzValue="dynamic">{{ 'mxk.roles.category.dynamic' | i18n }}</label>
+        </nz-radio-group>
       </nz-form-control>
     </nz-form-item>
-    <nz-form-item *ngIf="form.model.switch_dynamic">
+    <nz-form-item *ngIf="form.model.category == '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-form-control>
     </nz-form-item>
-    <nz-form-item *ngIf="form.model.switch_dynamic">
+    <nz-form-item *ngIf="form.model.category == '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-form-control>
     </nz-form-item>
-    <nz-form-item *ngIf="form.model.switch_dynamic">
+    <nz-form-item *ngIf="form.model.category == '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 type="hidden" [(ngModel)]="form.model.orgIdsList" [ngModelOptions]="{ standalone: true }" nz-input
@@ -55,7 +55,7 @@
         </nz-tree-select>
       </nz-form-control>
     </nz-form-item>
-    <nz-form-item *ngIf="form.model.switch_dynamic">
+    <nz-form-item *ngIf="form.model.category == '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

+ 10 - 3
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/roles/roles.component.html

@@ -41,7 +41,7 @@
           (nzCheckedChange)="onTableAllChecked($event)"></th>
         <th nzAlign="center" style="display: none">Id</th>
         <th nzAlign="center">{{ 'mxk.roles.name' | i18n }}</th>
-        <th nzAlign="center">{{ 'mxk.roles.dynamic' | i18n }}</th>
+        <th nzAlign="center">{{ 'mxk.roles.category' | i18n }}</th>
         <th nzAlign="center">{{ 'mxk.text.description' | i18n }}</th>
         <th nzAlign="center"><a>{{ 'mxk.text.action' | i18n }}</a></th>
       </tr>
@@ -54,11 +54,18 @@
           <span>{{ data.id }}</span>
         </td>
         <td nzAlign="left" nzBreakWord="false">{{ data.roleName }}</td>
-        <td nzAlign="center"> <i *ngIf="data.dynamic == 1" nz-icon nzType="check-circle" nzTheme="fill"
-            style="color: green"></i></td>
+        <td nzAlign="center" *ngIf="data.category == 'dynamic'"> {{ 'mxk.roles.category.dynamic' | i18n }}</td>
+        <td nzAlign="center" *ngIf="data.category == 'static'"> {{ 'mxk.roles.category.static' | i18n }}</td>
         <td nzAlign="left">{{ data.description }}</td>
         <td nzAlign="left" nzBreakWord="false">
           <div nz-col>
+            <button nz-button type="button" (click)="onMembers($event, data.id, data.roleName)" style="float: left">{{
+              'mxk.roles.member' | i18n
+              }}</button>
+            <button nz-button type="button" (click)="onPermissions($event, data.id, data.roleName)"
+              style="float: left">{{
+              'mxk.roles.permissions' | i18n
+              }}</button>
             <button nz-button type="button" (click)="onEdit($event, data.id)" style="float: left">{{ 'mxk.text.edit' |
               i18n }}</button>
             <button

+ 10 - 0
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/roles/roles.component.ts

@@ -16,6 +16,7 @@
 
 import { ChangeDetectionStrategy, ViewContainerRef, ChangeDetectorRef, Component, OnInit, Inject } from '@angular/core';
 import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { Router } from '@angular/router';
 import { I18NService } from '@core';
 import { _HttpClient, ALAIN_I18N_TOKEN, SettingsService } from '@delon/theme';
 import { format, addDays } from 'date-fns';
@@ -88,6 +89,7 @@ export class RolesComponent implements OnInit {
     private rolesService: RolesService,
     private fb: FormBuilder,
     private msg: NzMessageService,
+    private router: Router,
     @Inject(ALAIN_I18N_TOKEN) private i18n: I18NService,
     private cdr: ChangeDetectorRef
   ) { }
@@ -173,6 +175,14 @@ export class RolesComponent implements OnInit {
     });
   }
 
+  onMembers(e: MouseEvent, roleId: String, roleName: String): void {
+    this.router.navigateByUrl(`/access/rolemembers?roleId=${roleId}&roleName=${roleName}`);
+  }
+
+  onPermissions(e: MouseEvent, roleId: String, roleName: String): void {
+    this.router.navigateByUrl(`/access/permissions?roleId=${roleId}&roleName=${roleName}`);
+  }
+
   fetch(): void {
     this.query.submitLoading = true;
     this.query.tableLoading = true;

+ 3 - 3
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/access/roles/select-roles/select-roles.component.html

@@ -33,7 +33,7 @@
         <th></th>
         <th nzAlign="center" style="display: none">Id</th>
         <th nzAlign="center">{{ 'mxk.roles.name' | i18n }}</th>
-        <th nzAlign="center">{{ 'mxk.roles.dynamic' | i18n }}</th>
+        <th nzAlign="center">{{ 'mxk.roles.category' | i18n }}</th>
       </tr>
     </thead>
     <tbody>
@@ -44,8 +44,8 @@
           <span>{{ data.id }}</span>
         </td>
         <td nzAlign="left"> {{ data.roleName }}</td>
-        <td nzAlign="center"> <i *ngIf="data.dynamic == 1" nz-icon nzType="check-circle" nzTheme="fill"
-            style="color: green"></i></td>
+        <td nzAlign="center" *ngIf="data.category == 'dynamic'"> {{ 'mxk.roles.category.dynamic' | i18n }}</td>
+        <td nzAlign="center" *ngIf="data.category == 'static'"> {{ 'mxk.roles.category.static' | i18n }}</td>
       </tr>
     </tbody>
   </nz-table>

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

@@ -118,8 +118,11 @@
       </nz-form-control>
     </nz-form-item>
     <nz-form-item style="width: 100%">
-      <nz-form-control [nzOffset]="7" [nzSpan]="12">
-        <button nz-button nzType="primary" type="submit" [nzLoading]="form.submitting">提交</button>
+      <nz-form-control [nzOffset]="10" [nzSpan]="8">
+        <button nz-button nzType="primary" type="submit" [nzLoading]="form.submitting"> {{ 'mxk.text.submit' | i18n
+          }}</button>
+        <button nz-button nzType="default" (click)="onTest($event)" [nzLoading]="form.submitting"> {{ 'mxk.text.test' |
+          i18n }}</button>
       </nz-form-control>
     </nz-form-item>
   </form>

+ 30 - 30
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/permissions/privileges/privileges.component.html

@@ -5,6 +5,15 @@
     <div nz-row [nzGutter]="{ xs: 8, sm: 8, md: 8, lg: 24, xl: 48, xxl: 48 }">
       <div nz-col nzMd="10" nzSm="24">
         <nz-form-item>
+          <nz-form-label nzFor="roleName">{{ 'mxk.roles.name' | i18n }}</nz-form-label>
+          <nz-form-control>
+            <input nz-input [(ngModel)]="query.params.roleName" [ngModelOptions]="{ standalone: true }" name="roleName"
+              placeholder="" id="roleName" />
+          </nz-form-control>
+        </nz-form-item>
+      </div>
+      <div nz-col nzMd="10" nzSm="24">
+        <nz-form-item>
           <nz-form-label nzFor="name">{{ 'mxk.resources.appName' | i18n }}</nz-form-label>
           <nz-form-control>
             <nz-input-group nzSearch [nzAddOnAfter]="suffixButton">
@@ -18,16 +27,7 @@
           </nz-form-control>
         </nz-form-item>
       </div>
-      <div nz-col nzMd="8" nzSm="24">
-        <nz-form-item>
-          <nz-form-label nzFor="roleName">{{ 'mxk.roles.name' | i18n }}</nz-form-label>
-          <nz-form-control>
-            <input nz-input [(ngModel)]="query.params.roleName" [ngModelOptions]="{ standalone: true }" name="roleName"
-              placeholder="" id="roleName" />
-          </nz-form-control>
-        </nz-form-item>
-      </div>
-      <div nz-col [nzSpan]="query.expandForm ? 24 : 6" [class.text-right]="query.expandForm">
+      <div nz-col [nzSpan]="query.expandForm ? 24 : 4" [class.text-right]="query.expandForm">
         <button nz-button type="submit" [nzType]="'primary'" [nzLoading]="query.submitLoading">{{ 'mxk.text.query' |
           i18n }}</button>
         <button nz-button type="reset" (click)="onReset()" class="mx-sm" style="display: none">{{ 'mxk.text.reset' |
@@ -44,23 +44,6 @@
   </div>
   <div nz-row [nzGutter]="{ xs: 8, sm: 8, md: 8, lg: 24, xl: 48, xxl: 48 }">
     <div nz-col [nzSpan]="10" class="grid-border">
-      <nz-tree #nzTreeComponent nzShowLine="false" [nzCheckable]="treeNodes.checkable"
-        [nzCheckedKeys]="treeNodes.checkedKeys" nzBlockNode [nzData]="treeNodes.nodes" (nzDblClick)="openFolder($event)"
-        [nzTreeTemplate]="nzTreeTemplate"></nz-tree>
-      <ng-template #nzTreeTemplate let-node let-origin="origin">
-        <span class="custom-node">
-          <span *ngIf="!node.isLeaf">
-            <i nz-icon [nzType]="node.isExpanded ? 'folder-open' : 'folder'" (click)="openFolder(node)"></i>
-            <span class="folder-name">{{ node.title }}</span>
-          </span>
-          <span *ngIf="node.isLeaf">
-            <i nz-icon nzType="file"></i>
-            <span class="file-name">{{ node.title }}</span>
-          </span>
-        </span>
-      </ng-template>
-    </div>
-    <div nz-col [nzSpan]="14" class="grid-border">
       <nz-table #dynamicTable nzTableLayout="auto" nzSize="small" nzBordered nzShowSizeChanger
         [nzData]="query.results.rows" [nzFrontPagination]="false" [nzTotal]="query.results.records"
         [nzPageSizeOptions]="query.params.pageSizeOptions" [nzPageSize]="query.params.pageSize"
@@ -73,7 +56,7 @@
             <th nzAlign="center"></th>
             <th nzAlign="center" style="display: none">Id</th>
             <th nzAlign="center">{{ 'mxk.roles.name' | i18n }}</th>
-            <th nzAlign="center">{{ 'mxk.roles.dynamic' | i18n }}</th>
+            <th nzAlign="center">{{ 'mxk.roles.category' | i18n }}</th>
           </tr>
         </thead>
         <tbody>
@@ -84,11 +67,28 @@
               <span>{{ data.id }}</span>
             </td>
             <td nzAlign="left" nzBreakWord="false">{{ data.roleName }}</td>
-            <td nzAlign="center"> <i *ngIf="data.dynamic == 1" nz-icon nzType="check-circle" nzTheme="fill"
-                style="color: green"></i></td>
+            <td nzAlign="center" *ngIf="data.category == 'dynamic'"> {{ 'mxk.roles.category.dynamic' | i18n }}</td>
+            <td nzAlign="center" *ngIf="data.category == 'static'"> {{ 'mxk.roles.category.static' | i18n }}</td>
           </tr>
         </tbody>
       </nz-table>
     </div>
+    <div nz-col [nzSpan]="14" class="grid-border">
+      <nz-tree #nzTreeComponent nzShowLine="false" [nzCheckable]="treeNodes.checkable"
+        [nzCheckedKeys]="treeNodes.checkedKeys" nzBlockNode [nzData]="treeNodes.nodes" (nzDblClick)="openFolder($event)"
+        [nzTreeTemplate]="nzTreeTemplate"></nz-tree>
+      <ng-template #nzTreeTemplate let-node let-origin="origin">
+        <span class="custom-node">
+          <span *ngIf="!node.isLeaf">
+            <i nz-icon [nzType]="node.isExpanded ? 'folder-open' : 'folder'" (click)="openFolder(node)"></i>
+            <span class="folder-name">{{ node.title }}</span>
+          </span>
+          <span *ngIf="node.isLeaf">
+            <i nz-icon nzType="file"></i>
+            <span class="file-name">{{ node.title }}</span>
+          </span>
+        </span>
+      </ng-template>
+    </div>
   </div>
 </nz-card>

+ 1 - 1
maxkey-web-frontend/maxkey-web-mgt-app/src/app/routes/permissions/privileges/privileges.component.ts

@@ -160,7 +160,7 @@ export class PrivilegesComponent implements OnInit {
       this.query.tableLoading = false;
       if (res.code == 0) {
         this.msg.success(this.i18n.fanyi('mxk.alert.operate.success'));
-        this.fetch();
+        //this.fetch();
       } else {
         this.msg.error(this.i18n.fanyi('mxk.alert.operate.error'));
       }