feat: 登录用户相关数据的读取接口
diff --git a/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/admin/AdminApplicationController.java b/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/admin/AdminApplicationController.java
index 41a23bb..1cdaaf6 100644
--- a/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/admin/AdminApplicationController.java
+++ b/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/admin/AdminApplicationController.java
@@ -35,7 +35,7 @@
 import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
 import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
 
-@Api(value = "BaseAdminApplication", tags = { "BaseAdminApplication" }, description = "路由信息的操作接口")
+@Api(value = "BaseAdminApplication", tags = { "BaseAdminApplication" }, description = "应用的操作接口")
 @Slf4j
 @RestController
 @RequestMapping("/v1/admin/applications")
diff --git a/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/admin/AdminMenuController.java b/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/admin/AdminMenuController.java
index 9526d94..67a2d3e 100644
--- a/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/admin/AdminMenuController.java
+++ b/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/admin/AdminMenuController.java
@@ -2,7 +2,6 @@
 
 import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import io.swagger.annotations.Api;
 import lombok.extern.slf4j.Slf4j;
@@ -18,6 +17,7 @@
 import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.ResponseStatus;
 import org.springframework.web.bind.annotation.RestController;
@@ -184,12 +184,10 @@
   @GetMapping(path = "/tree", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
   @ResponseStatus(value = HttpStatus.OK)
   @ResponseBody
-  public DefaultApiResponse<PermissionTreeResponseData> tree() {
+  public DefaultApiResponse<PermissionTreeResponseData> tree(
+      @RequestParam(name = "applicationId", required = false) String applicationId) {
     
-    Map<String, Object> mapBean = new HashMap<String, Object>();
-    mapBean.put("type", Permission.TYPE_MENU);
-
-    PermissionTreeNode tree = permissionService.selectPermissionTree(mapBean);
+    PermissionTreeNode tree = permissionService.selectPermissionTree(applicationId, Permission.TYPE_MENU);
 
     PermissionTreeResponseData data = PermissionTreeResponseData.of(tree);
 
diff --git a/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/admin/AdminPermissionController.java b/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/admin/AdminPermissionController.java
index f10244a..7fc4481 100644
--- a/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/admin/AdminPermissionController.java
+++ b/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/admin/AdminPermissionController.java
@@ -29,19 +29,19 @@
   @Autowired
   private PermissionService permissionService;
 
-  @GetMapping(path = "/tree", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
-  @ResponseStatus(value = HttpStatus.OK)
-  @ResponseBody
-  public DefaultApiResponse<PermissionTreeResponseData> tree() {
-    
-    Map<String, Object> mapBean = new HashMap<String, Object>();
-    //mapBean.put("type", Permission.TYPE_MENU);
-
-    PermissionTreeNode tree = permissionService.selectPermissionTree(mapBean);
-
-    PermissionTreeResponseData data = PermissionTreeResponseData.of(tree);
-
-    return new DefaultApiResponse<PermissionTreeResponseData>(data);
-  }
+//  @GetMapping(path = "/tree", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+//  @ResponseStatus(value = HttpStatus.OK)
+//  @ResponseBody
+//  public DefaultApiResponse<PermissionTreeResponseData> tree() {
+//    
+//    Map<String, Object> mapBean = new HashMap<String, Object>();
+//    //mapBean.put("type", Permission.TYPE_MENU);
+//
+//    PermissionTreeNode tree = permissionService.selectPermissionTree(mapBean);
+//
+//    PermissionTreeResponseData data = PermissionTreeResponseData.of(tree);
+//
+//    return new DefaultApiResponse<PermissionTreeResponseData>(data);
+//  }
   
 }
diff --git a/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/authn/AuthnAccountController.java b/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/authn/AuthnAccountController.java
new file mode 100644
index 0000000..76663d2
--- /dev/null
+++ b/base/api/src/main/java/com/supwisdom/institute/backend/base/api/v1/authn/AuthnAccountController.java
@@ -0,0 +1,192 @@
+package com.supwisdom.institute.backend.base.api.v1.authn;
+
+import java.util.List;
+
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.institute.backend.base.api.vo.response.AuthnAccountPermissionsResponseData;
+import com.supwisdom.institute.backend.base.api.vo.response.AuthnAccountResourcesResponseData;
+import com.supwisdom.institute.backend.base.api.vo.response.AuthnAccountResponseData;
+import com.supwisdom.institute.backend.base.api.vo.response.AuthnAccountRolesResponseData;
+import com.supwisdom.institute.backend.base.domain.entity.Account;
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.base.domain.entity.Resource;
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.base.domain.service.AccountService;
+import com.supwisdom.institute.backend.base.domain.service.PermissionService;
+import com.supwisdom.institute.backend.base.domain.service.ResourceService;
+import com.supwisdom.institute.backend.base.domain.service.RoleService;
+import com.supwisdom.institute.backend.common.framework.vo.response.DefaultApiResponse;
+
+@Api(value = "BaseAuthnAccount", tags = { "BaseAuthnAccount" }, description = "帐号接口(认证、授权用)")
+@Slf4j
+@RestController
+@RequestMapping("/v1/authn")
+public class AuthnAccountController {
+  
+  @Autowired
+  private AccountService accountService;
+  
+  @Autowired
+  private RoleService roleService;
+  
+  @Autowired
+  private PermissionService permissionService; 
+
+  @Autowired
+  private ResourceService resourceService; 
+
+  @GetMapping(path = "/{username}/account", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+  @ResponseStatus(value = HttpStatus.OK)
+  @ResponseBody
+  public DefaultApiResponse<AuthnAccountResponseData> account(
+      @PathVariable("username") String username) {
+
+    if (username == null || username.length() == 0) {
+      throw new RuntimeException("exception.get.username.must.not.empty");
+    }
+
+    Account account = accountService.selectByUsername(username);
+
+    if (account == null) {
+      throw new RuntimeException("exception.get.account.not.exist");
+    }
+    
+    AuthnAccountResponseData data = AuthnAccountResponseData.of(account);
+
+    return new DefaultApiResponse<AuthnAccountResponseData>(data);
+  }
+  
+  
+  @GetMapping(path = "/{username}/roles", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+  @ResponseStatus(value = HttpStatus.OK)
+  @ResponseBody
+  public DefaultApiResponse<AuthnAccountRolesResponseData> roles(
+      @PathVariable("username") String username) {
+
+    if (username == null || username.length() == 0) {
+      throw new RuntimeException("exception.get.username.must.not.empty");
+    }
+
+    Account account = accountService.selectByUsername(username);
+
+    if (account == null) {
+      throw new RuntimeException("exception.get.account.not.exist");
+    }
+    
+    List<Role> roles = roleService.selectByUsername(username);
+    
+    AuthnAccountRolesResponseData data = AuthnAccountRolesResponseData.of(roles);
+
+    return new DefaultApiResponse<AuthnAccountRolesResponseData>(data);
+  }
+
+  @GetMapping(path = "/{username}/applications", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+  @ResponseStatus(value = HttpStatus.OK)
+  @ResponseBody
+  public DefaultApiResponse<AuthnAccountPermissionsResponseData> applications(
+      @PathVariable("username") String username,
+      @RequestParam(name = "applicationId", required = false) String applicationId) {
+
+    if (username == null || username.length() == 0) {
+      throw new RuntimeException("exception.get.username.must.not.empty");
+    }
+
+    Account account = accountService.selectByUsername(username);
+
+    if (account == null) {
+      throw new RuntimeException("exception.get.account.not.exist");
+    }
+    
+    List<Permission> applications = permissionService.selectByUsername(username, null, Permission.TYPE_APPLICATION);
+    
+    AuthnAccountPermissionsResponseData data = AuthnAccountPermissionsResponseData.of(applications);
+
+    return new DefaultApiResponse<AuthnAccountPermissionsResponseData>(data);
+  }
+
+  @GetMapping(path = "/{username}/menus", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+  @ResponseStatus(value = HttpStatus.OK)
+  @ResponseBody
+  public DefaultApiResponse<AuthnAccountPermissionsResponseData> menus(
+      @PathVariable("username") String username, 
+      @RequestParam(name = "applicationId", required = false) String applicationId) {
+
+    if (username == null || username.length() == 0) {
+      throw new RuntimeException("exception.get.username.must.not.empty");
+    }
+
+    Account account = accountService.selectByUsername(username);
+
+    if (account == null) {
+      throw new RuntimeException("exception.get.account.not.exist");
+    }
+    
+    List<Permission> menus = permissionService.selectByUsername(username, applicationId, Permission.TYPE_MENU);
+    
+    AuthnAccountPermissionsResponseData data = AuthnAccountPermissionsResponseData.of(menus);
+
+    return new DefaultApiResponse<AuthnAccountPermissionsResponseData>(data);
+  }
+
+  @GetMapping(path = "/{username}/operations", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+  @ResponseStatus(value = HttpStatus.OK)
+  @ResponseBody
+  public DefaultApiResponse<AuthnAccountPermissionsResponseData> operations(
+      @PathVariable("username") String username, 
+      @RequestParam(name = "applicationId", required = false) String applicationId) {
+
+    if (username == null || username.length() == 0) {
+      throw new RuntimeException("exception.get.username.must.not.empty");
+    }
+
+    Account account = accountService.selectByUsername(username);
+
+    if (account == null) {
+      throw new RuntimeException("exception.get.account.not.exist");
+    }
+    
+    List<Permission> operations = permissionService.selectByUsername(username, applicationId, Permission.TYPE_OPERATION);
+    
+    AuthnAccountPermissionsResponseData data = AuthnAccountPermissionsResponseData.of(operations);
+
+    return new DefaultApiResponse<AuthnAccountPermissionsResponseData>(data);
+  }
+
+  @GetMapping(path = "/{username}/resources", produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+  @ResponseStatus(value = HttpStatus.OK)
+  @ResponseBody
+  public DefaultApiResponse<AuthnAccountResourcesResponseData> resources(
+      @PathVariable("username") String username, 
+      @RequestParam(name = "applicationId", required = false) String applicationId) {
+
+    if (username == null || username.length() == 0) {
+      throw new RuntimeException("exception.get.username.must.not.empty");
+    }
+
+    Account account = accountService.selectByUsername(username);
+
+    if (account == null) {
+      throw new RuntimeException("exception.get.account.not.exist");
+    }
+    
+    List<Resource> resources = null;// FIXME: resourceService.selectByUsername(username, applicationId);
+    
+    AuthnAccountResourcesResponseData data = AuthnAccountResourcesResponseData.of(resources);
+
+    return new DefaultApiResponse<AuthnAccountResourcesResponseData>(data);
+  }
+
+}
diff --git a/base/api/src/main/java/com/supwisdom/institute/backend/base/api/vo/response/AuthnAccountPermissionsResponseData.java b/base/api/src/main/java/com/supwisdom/institute/backend/base/api/vo/response/AuthnAccountPermissionsResponseData.java
new file mode 100644
index 0000000..e1666ed
--- /dev/null
+++ b/base/api/src/main/java/com/supwisdom/institute/backend/base/api/vo/response/AuthnAccountPermissionsResponseData.java
@@ -0,0 +1,31 @@
+package com.supwisdom.institute.backend.base.api.vo.response;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.Permission;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class AuthnAccountPermissionsResponseData implements IApiResponseData {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = 8276878427539012799L;
+
+  @Getter
+  @Setter
+  public List<Permission> permissions;
+  
+  
+  public static AuthnAccountPermissionsResponseData of(List<Permission> permissions) {
+    AuthnAccountPermissionsResponseData data = new AuthnAccountPermissionsResponseData();
+    
+    data.setPermissions(permissions);
+    
+    return data;
+  }
+  
+}
diff --git a/base/api/src/main/java/com/supwisdom/institute/backend/base/api/vo/response/AuthnAccountResourcesResponseData.java b/base/api/src/main/java/com/supwisdom/institute/backend/base/api/vo/response/AuthnAccountResourcesResponseData.java
new file mode 100644
index 0000000..b62dabf
--- /dev/null
+++ b/base/api/src/main/java/com/supwisdom/institute/backend/base/api/vo/response/AuthnAccountResourcesResponseData.java
@@ -0,0 +1,31 @@
+package com.supwisdom.institute.backend.base.api.vo.response;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.Resource;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class AuthnAccountResourcesResponseData implements IApiResponseData {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = 4924064418294890589L;
+
+  @Getter
+  @Setter
+  public List<Resource> resources;
+  
+  
+  public static AuthnAccountResourcesResponseData of(List<Resource> resources) {
+    AuthnAccountResourcesResponseData data = new AuthnAccountResourcesResponseData();
+    
+    data.setResources(resources);
+    
+    return data;
+  }
+
+}
diff --git a/base/api/src/main/java/com/supwisdom/institute/backend/base/api/vo/response/AuthnAccountResponseData.java b/base/api/src/main/java/com/supwisdom/institute/backend/base/api/vo/response/AuthnAccountResponseData.java
new file mode 100644
index 0000000..85cddde
--- /dev/null
+++ b/base/api/src/main/java/com/supwisdom/institute/backend/base/api/vo/response/AuthnAccountResponseData.java
@@ -0,0 +1,19 @@
+package com.supwisdom.institute.backend.base.api.vo.response;
+
+import com.supwisdom.institute.backend.base.domain.entity.Account;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class AuthnAccountResponseData extends Account implements IApiResponseData {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = -289285783805128927L;
+
+  public static AuthnAccountResponseData of(Account entity) {
+    AuthnAccountResponseData data = new AuthnAccountResponseData();
+    return EntityUtils.copy(entity, data);
+  }
+
+}
diff --git a/base/api/src/main/java/com/supwisdom/institute/backend/base/api/vo/response/AuthnAccountRolesResponseData.java b/base/api/src/main/java/com/supwisdom/institute/backend/base/api/vo/response/AuthnAccountRolesResponseData.java
new file mode 100644
index 0000000..9fc82ef
--- /dev/null
+++ b/base/api/src/main/java/com/supwisdom/institute/backend/base/api/vo/response/AuthnAccountRolesResponseData.java
@@ -0,0 +1,31 @@
+package com.supwisdom.institute.backend.base.api.vo.response;
+
+import java.util.List;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import com.supwisdom.institute.backend.base.domain.entity.Role;
+import com.supwisdom.institute.backend.common.framework.vo.response.data.IApiResponseData;
+
+public class AuthnAccountRolesResponseData implements IApiResponseData {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = -6588284546370817275L;
+  
+  @Getter
+  @Setter
+  public List<Role> roles;
+  
+  
+  public static AuthnAccountRolesResponseData of(List<Role> roles) {
+    AuthnAccountRolesResponseData data = new AuthnAccountRolesResponseData();
+    
+    data.setRoles(roles);
+    
+    return data;
+  }
+
+}
diff --git a/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Permission.java b/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Permission.java
index 1fedb61..7fdd8c0 100644
--- a/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Permission.java
+++ b/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/entity/Permission.java
@@ -15,11 +15,11 @@
    */
   private static final long serialVersionUID = -8834200833972243635L;
   
-  // public static final String ROOT_PARENT_ID = "0";
+  public static final String ROOT_PARENT_ID = "0";
   
   public static final String APPLICATION_ID = "1";
 
-  public static final String TYPE_SYSTEM = "1";
+  public static final String TYPE_APPLICATION = "1";
   public static final String TYPE_MENU = "2";
   public static final String TYPE_OPERATION = "3";
 
diff --git a/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/PermissionRepository.java b/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/PermissionRepository.java
index c48af15..623411d 100644
--- a/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/PermissionRepository.java
+++ b/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/PermissionRepository.java
@@ -3,7 +3,6 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 
 import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
@@ -321,28 +320,29 @@
     
     BaseJpaRepository.super.delete(id);
   }
+  
+  
 
-  public default Permission selectApplicationPermissionByCode(String code) {
-    Permission probe = new Permission();
-    probe.setCode(code);
-    probe.setType("1");
+
+  public default List<Permission> selectList(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
     
-    ExampleMatcher matcher = ExampleMatcher.matching()
-        .withMatcher("code", ExampleMatcher.GenericPropertyMatchers.exact())
-        .withMatcher("type", ExampleMatcher.GenericPropertyMatchers.exact());
+    Specification<Permission> spec = convertToSpec(mapBean);
     
-    Example<Permission> example = Example.of(probe, matcher);
-    
-    Optional<Permission> o = this.findOne(example);
-    
-    if (o.isPresent()) {
-      return o.get();
+    if (loadAll) {
+      pageIndex = 0;
+      pageSize = Integer.MAX_VALUE;
     }
     
-    return null;
+    Sort sort = convertToSort(orderBy);
+
+    if (sort == null) {
+      return this.findAll(spec);
+    } else {
+      return this.findAll(spec, sort);
+    }
   }
+
   
- 
 
   @Query(value = "select p from Permission p "
       + "inner join RolePermission rp on p.id=rp.permissionId "
@@ -368,46 +368,52 @@
       + "and p.status='1' and r.status='1' and g.status='1' and a.status='1' and a.enabled=1 ")
   public List<Permission> selectAccountGroupRolePermissionByUsername(@Param("username") String username, @Param("lft") int lft, @Param("rgt") int rgt, @Param("type") String type);
 
-  public default List<Permission> selectByUsername(String username, String applicationCode, String type) {
-    List<Permission> permissions = new ArrayList<Permission>();
-    
-    Permission applicationPermission = selectApplicationPermissionByCode(applicationCode);
-    if (applicationPermission == null) {
-      return permissions;
-    }
-    
-    int lft = applicationPermission.getLft();
-    int rgt = applicationPermission.getRgt();
-    
-    List<Permission> accountRolePermissions = selectAccountRolePermissionByUsername(username, lft, rgt, type);
-    permissions.addAll(accountRolePermissions);
-    
-    List<Permission> accountGroupRolePermissions = selectAccountGroupRolePermissionByUsername(username, lft, rgt, type);
-    permissions.addAll(accountGroupRolePermissions);
-    
-    return permissions;
-  }
+
+  @Query(value = "select p from Permission p "
+      + "inner join RolePermission rp on p.id=rp.permissionId "
+      + "inner join Role r on rp.roleId=r.id "
+      + "inner join AccountRole ar on r.id=ar.roleId "
+      + "inner join Account a on ar.accountId=a.id "
+      + "where a.username=:username "
+      + "and p.applicationId = :applicationId "
+      + "and (:type is null or p.type=:type) "
+      + "and p.status='1' and r.status='1' and a.status='1' and a.enabled=1 ")
+  public List<Permission> selectAccountRolePermissionByUsername(@Param("username") String username, @Param("applicationId") String applicationId, @Param("type") String type);
+  
+  @Query(value = "select p from Permission p "
+      + "inner join RolePermission rp on p.id=rp.permissionId "
+      + "inner join Role r on rp.roleId=r.id "
+      + "inner join GroupRole gr on r.id=gr.roleId "
+      + "inner join Group_ g on gr.groupId=g.id "
+      + "inner join AccountGroup ag on g.id=ag.groupId "
+      + "inner join Account a on ag.accountId=a.id "
+      + "where a.username=:username "
+      + "and p.applicationId = :applicationId "
+      + "and (:type is null or p.type=:type) "
+      + "and p.status='1' and r.status='1' and g.status='1' and a.status='1' and a.enabled=1 ")
+  public List<Permission> selectAccountGroupRolePermissionByUsername(@Param("username") String username, @Param("applicationId") String applicationId, @Param("type") String type);
 
 
-
-
-  public default List<Permission> selectList(boolean loadAll, int pageIndex, int pageSize, Map<String, Object> mapBean, Map<String, String> orderBy) {
-    
-    Specification<Permission> spec = convertToSpec(mapBean);
-    
-    if (loadAll) {
-      pageIndex = 0;
-      pageSize = Integer.MAX_VALUE;
-    }
-    
-    Sort sort = convertToSort(orderBy);
-
-    if (sort == null) {
-      return this.findAll(spec);
-    } else {
-      return this.findAll(spec, sort);
-    }
-  }
-
+  @Query(value = "select p from Permission p "
+      + "inner join RolePermission rp on p.id=rp.permissionId "
+      + "inner join Role r on rp.roleId=r.id "
+      + "inner join AccountRole ar on r.id=ar.roleId "
+      + "inner join Account a on ar.accountId=a.id "
+      + "where a.username=:username "
+      + "and (:type is null or p.type=:type) "
+      + "and p.status='1' and r.status='1' and a.status='1' and a.enabled=1 ")
+  public List<Permission> selectAccountRolePermissionByUsername(@Param("username") String username, @Param("type") String type);
+  
+  @Query(value = "select p from Permission p "
+      + "inner join RolePermission rp on p.id=rp.permissionId "
+      + "inner join Role r on rp.roleId=r.id "
+      + "inner join GroupRole gr on r.id=gr.roleId "
+      + "inner join Group_ g on gr.groupId=g.id "
+      + "inner join AccountGroup ag on g.id=ag.groupId "
+      + "inner join Account a on ag.accountId=a.id "
+      + "where a.username=:username "
+      + "and (:type is null or p.type=:type) "
+      + "and p.status='1' and r.status='1' and g.status='1' and a.status='1' and a.enabled=1 ")
+  public List<Permission> selectAccountGroupRolePermissionByUsername(@Param("username") String username, @Param("type") String type);
 
 }
diff --git a/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/RoleRepository.java b/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/RoleRepository.java
index f9ed2db..5853b26 100644
--- a/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/RoleRepository.java
+++ b/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/repo/RoleRepository.java
@@ -143,16 +143,4 @@
       + "and r.status='1' and g.status='1' and a.status='1' and a.enabled=1 ")
   public List<Role> selectAccountGroupRoleByUsername(@Param("username") String username);
 
-  public default List<Role> selectByUsername(String username) {
-    List<Role> roles = new ArrayList<Role>();
-    
-    List<Role> userRoles = selectAccountRoleByUsername(username);
-    roles.addAll(userRoles);
-    
-    List<Role> userGroupRoles = selectAccountGroupRoleByUsername(username);
-    roles.addAll(userGroupRoles);
-    
-    return roles;
-  }
-  
 }
diff --git a/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/AccountService.java b/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/AccountService.java
index ece1cda..b0cad6c 100644
--- a/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/AccountService.java
+++ b/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/AccountService.java
@@ -196,4 +196,8 @@
     return accountRoles;
   }
 
+  
+  public Account selectByUsername(String username) {
+    return accountRepository.selectByUsername(username);
+  }
 }
diff --git a/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/PermissionService.java b/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/PermissionService.java
index ead21b9..ff500bf 100644
--- a/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/PermissionService.java
+++ b/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/PermissionService.java
@@ -1,12 +1,14 @@
 package com.supwisdom.institute.backend.base.domain.service;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
 import lombok.extern.slf4j.Slf4j;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -50,19 +52,57 @@
     
     return permission;
   }
+  
+  private List<Permission> selectApplicationPermissionList() {
+    Map<String, Object> mapBean = new HashMap<String, Object>();
+    mapBean.put("type", Permission.TYPE_APPLICATION);
+    
+    return permissionRepository.selectList(true, -1, -1, mapBean, null);
+  }
 
-  public PermissionTreeNode selectPermissionTree(Map<String, Object> mapBean) {
+  public PermissionTreeNode selectPermissionTree(String applicationId, String type) {
+
+    Map<String, Object> mapBean = new HashMap<String, Object>();
+    mapBean.put("type", type);
     
-    Permission applicationPermission = this.selectApplicationPermission();
+    String rootTreeNodeId = "0";
     
+    List<Permission> permissions = new ArrayList<Permission>();
+    
+    if (StringUtils.isBlank(applicationId)) {
+      Permission rootPermission = new Permission();
+      rootPermission.setId(Permission.ROOT_PARENT_ID);
+      rootPermission.setCode("root");
+      rootPermission.setName("根");
+      
+      permissions.add(rootPermission);
+      rootTreeNodeId = rootPermission.getId();
+
+      List<Permission> applicationPermissions = this.selectApplicationPermissionList();
+      permissions.addAll(applicationPermissions);
+    } else {
+      Permission applicationPermission = permissionRepository.selectById(applicationId); // this.selectApplicationPermissionByCode(applicationCode);
+      if (applicationPermission == null) {
+        return null;
+      }
+      
+      permissions.add(applicationPermission);
+      rootTreeNodeId = applicationPermission.getId();
+    }
+    
+    List<Permission> menuPermissions = permissionRepository.selectList(true, -1, -1, mapBean, null);
+    permissions.addAll(menuPermissions);
+
+    return convertPermissionTree(permissions, rootTreeNodeId);
+  }
+  
+  private PermissionTreeNode convertPermissionTree(List<Permission> permissions, String rootTreeNodeId) {
+    if (permissions == null || permissions.size() == 0) {
+      return null;
+    }
+
     Map<String, PermissionTreeNode> parentTreeNode = new LinkedHashMap<String, PermissionTreeNode>();
-    
-    PermissionTreeNode rootTreeNode = EntityUtils.copy(applicationPermission, new PermissionTreeNode());
-    rootTreeNode.setChildren(new ArrayList<PermissionTreeNode>());
-    
-    parentTreeNode.put(rootTreeNode.getId(), rootTreeNode);
 
-    List<Permission> permissions = permissionRepository.selectList(true, -1, -1, mapBean, null);
     for (Permission permission : permissions) {
       PermissionTreeNode treeNode = EntityUtils.copy(permission, new PermissionTreeNode());
       treeNode.setChildren(new ArrayList<PermissionTreeNode>());
@@ -81,7 +121,91 @@
       parentTreeNode.get(treeNode.getParentId()).getChildren().add(treeNode);
     }
     
-    return rootTreeNode;
+    return parentTreeNode.get(rootTreeNodeId);
+  }
+
+  
+
+//  public Permission selectApplicationPermissionByCode(String code) {
+//    Permission probe = new Permission();
+//    probe.setCode(code);
+//    probe.setType("1");
+//    
+//    ExampleMatcher matcher = ExampleMatcher.matching()
+//        .withMatcher("code", ExampleMatcher.GenericPropertyMatchers.exact())
+//        .withMatcher("type", ExampleMatcher.GenericPropertyMatchers.exact());
+//    
+//    Example<Permission> example = Example.of(probe, matcher);
+//    
+//    Optional<Permission> o = permissionRepository.findOne(example);
+//    
+//    if (o.isPresent()) {
+//      return o.get();
+//    }
+//    
+//    return null;
+//  }
+  
+
+  public List<Permission> selectByUsername(String username, String applicationId, String type) {
+    List<Permission> permissions = new ArrayList<Permission>();
+    
+//    Permission applicationPermission = permissionRepository.selectById(applicationId);
+//    if (applicationPermission == null) {
+//      return permissions;
+//    }
+//    
+//    int lft = applicationPermission.getLft();
+//    int rgt = applicationPermission.getRgt();
+    
+    if (StringUtils.isBlank(applicationId)) {
+      List<Permission> accountRolePermissions = permissionRepository.selectAccountRolePermissionByUsername(username, type);
+      permissions.addAll(accountRolePermissions);
+      
+      List<Permission> accountGroupRolePermissions = permissionRepository.selectAccountGroupRolePermissionByUsername(username, type);
+      permissions.addAll(accountGroupRolePermissions);
+    } else {
+      List<Permission> accountRolePermissions = permissionRepository.selectAccountRolePermissionByUsername(username, applicationId, type);
+      permissions.addAll(accountRolePermissions);
+      
+      List<Permission> accountGroupRolePermissions = permissionRepository.selectAccountGroupRolePermissionByUsername(username, applicationId, type);
+      permissions.addAll(accountGroupRolePermissions);
+    }
+    
+    return EntityUtils.distinctList(permissions);
+  }
+  
+  @Deprecated
+  public PermissionTreeNode selectPermissionTreeByUsername(String username, String applicationId, String type) {
+    String rootTreeNodeId = "0";
+    
+    List<Permission> permissions = new ArrayList<Permission>();
+    
+    if (StringUtils.isBlank(applicationId)) {
+      Permission rootPermission = new Permission();
+      rootPermission.setId(Permission.ROOT_PARENT_ID);
+      rootPermission.setCode("root");
+      rootPermission.setName("根");
+      
+      permissions.add(rootPermission);
+      rootTreeNodeId = rootPermission.getId();
+
+      List<Permission> applicationPermissions = this.selectApplicationPermissionList();
+      permissions.addAll(applicationPermissions);
+    } else {
+      Permission applicationPermission = permissionRepository.selectById(applicationId); // this.selectApplicationPermissionByCode(applicationCode);
+      if (applicationPermission == null) {
+        return null;
+      }
+      
+      permissions.add(applicationPermission);
+      rootTreeNodeId = applicationPermission.getId();
+    }
+    
+    List<Permission> menuPermissions = this.selectByUsername(username, applicationId, type);
+    permissions.addAll(menuPermissions);
+
+    return convertPermissionTree(permissions, rootTreeNodeId);
   }
 
 }
diff --git a/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/RoleService.java b/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/RoleService.java
index 403927f..c66e3ff 100644
--- a/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/RoleService.java
+++ b/base/domain/src/main/java/com/supwisdom/institute/backend/base/domain/service/RoleService.java
@@ -1,5 +1,6 @@
 package com.supwisdom.institute.backend.base.domain.service;
 
+import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -19,6 +20,7 @@
 import com.supwisdom.institute.backend.base.domain.repo.GroupRoleRepository;
 import com.supwisdom.institute.backend.base.domain.repo.RolePermissionRepository;
 import com.supwisdom.institute.backend.base.domain.repo.RoleRepository;
+import com.supwisdom.institute.backend.common.framework.entity.EntityUtils;
 import com.supwisdom.institute.backend.common.framework.service.ABaseService;
 import com.supwisdom.institute.backend.common.util.MapBeanUtils;
 
@@ -246,4 +248,21 @@
     return rolePermissions;
   }
 
+  
+  
+
+  public List<Role> selectByUsername(String username) {
+    List<Role> roles = new ArrayList<Role>();
+    
+    List<Role> userRoles = roleRepository.selectAccountRoleByUsername(username);
+    roles.addAll(userRoles);
+    
+    List<Role> userGroupRoles = roleRepository.selectAccountGroupRoleByUsername(username);
+    roles.addAll(userGroupRoles);
+    
+    roles = EntityUtils.distinctList(roles);
+    
+    return roles;
+  }
+  
 }