增加Permission 权限相关接口
diff --git a/samples/user/src/main/java/com/supwisdom/leaveschool/user/controller/api/admin/Api1AdminPermissionController.java b/samples/user/src/main/java/com/supwisdom/leaveschool/user/controller/api/admin/Api1AdminPermissionController.java
new file mode 100644
index 0000000..6ebc5fe
--- /dev/null
+++ b/samples/user/src/main/java/com/supwisdom/leaveschool/user/controller/api/admin/Api1AdminPermissionController.java
@@ -0,0 +1,119 @@
+package com.supwisdom.leaveschool.user.controller.api.admin;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections.IteratorUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.supwisdom.leaveschool.common.controller.api.CrudApiController;
+import com.supwisdom.leaveschool.common.model.PagerRequestModel;
+import com.supwisdom.leaveschool.common.model.PagerResponseModel;
+import com.supwisdom.leaveschool.user.domain.Permission;
+import com.supwisdom.leaveschool.user.domain.RolePermission;
+import com.supwisdom.leaveschool.user.model.RolePermissions;
+import com.supwisdom.leaveschool.user.repository.PermissionRepository;
+import com.supwisdom.leaveschool.user.repository.RolePermissionRepository;
+
+@RestController
+@RequestMapping("/api/v1/admin/permissions")
+public class Api1AdminPermissionController extends CrudApiController<Permission, PermissionRepository> {
+
+  @Autowired
+  private PermissionRepository permissionRepository;
+
+  @Autowired
+  private RolePermissionRepository permissionRoleRepository;
+
+  @Override
+  protected PermissionRepository getRepository() {
+    return permissionRepository;
+  }
+
+  /**
+   * 
+   * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:10010/api/v1/admin/permissions/1/roles'
+   * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:10010/api/v1/admin/permissions/1/roles?pageIndex=2&pageSize=50'
+   * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:10010/api/v1/admin/permissions/1/roles?pageIndex=0&pageSize=20&mapBean[rolecode]=code&mapBean[rolename]=name'
+   * 
+   * 
+   * 
+   * @param id
+   * @param pagerRequestModel
+   * @return
+   */
+  @RequestMapping(value = "/{id}/roles", method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+  @ResponseBody
+  public PagerResponseModel<RolePermission> permissionRoles(@PathVariable("id") String id, PagerRequestModel pagerRequestModel) {
+
+    if (id == null || id.length() == 0) {
+      throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+    }
+
+    Permission permission = permissionRepository.selectById(id);
+
+    if (permission == null) {
+      throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+    }
+
+    if (pagerRequestModel.getMapBean() == null) {
+      pagerRequestModel.setMapBean(new HashMap<String, Object>());
+    }
+    pagerRequestModel.getMapBean().put("permissionId", permission.getId());
+
+    Page<RolePermission> page = permissionRoleRepository.selectRolePermissions(pagerRequestModel.getPageIndex(),
+        pagerRequestModel.getPageSize(), pagerRequestModel.getMapBean());
+
+    @SuppressWarnings("unchecked")
+    List<RolePermission> list = IteratorUtils.toList(page.iterator());
+
+    PagerResponseModel<RolePermission> pagerResponseModel = PagerResponseModel.of(pagerRequestModel);
+    pagerResponseModel.setPageCount(page.getTotalPages());
+    pagerResponseModel.setRecordCount(page.getTotalElements());
+    pagerResponseModel.setItems(list);
+
+    return pagerResponseModel;
+  }
+
+  /**
+   * 
+   * curl -i -s -X POST -H 'Content-Type:application/json' -H 'Accept:application/json' 'http://localhost:10010/api/v1/admin/permissions/1/roles' \
+   * -d '{"rolePermissions":[{"rolecode":"role001"},{"rolecode":"role002"}]}'
+   * 
+   * 
+   * @param id
+   * @param permissionUsers
+   * @return
+   */
+  @RequestMapping(value = "/{id}/roles", method = RequestMethod.POST, consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+  @ResponseBody
+  public Map<String, Object> relateRoles(@PathVariable("id") String id, @RequestBody RolePermissions rolePermissions) {
+
+    if (id == null || id.length() == 0) {
+      throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+    }
+
+    Permission permission = permissionRepository.selectById(id);
+
+    if (permission == null) {
+      throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+    }
+
+    permissionRoleRepository.relatePermissionRoles(permission, rolePermissions.getRolePermissions());
+
+    Map<String, Object> res = new HashMap<String, Object>();
+    res.put("success", "info.set.success");
+
+    return res;
+  }
+
+}
diff --git a/samples/user/src/main/java/com/supwisdom/leaveschool/user/controller/api/admin/Api1AdminRoleController.java b/samples/user/src/main/java/com/supwisdom/leaveschool/user/controller/api/admin/Api1AdminRoleController.java
index 3765112..60a94ab 100644
--- a/samples/user/src/main/java/com/supwisdom/leaveschool/user/controller/api/admin/Api1AdminRoleController.java
+++ b/samples/user/src/main/java/com/supwisdom/leaveschool/user/controller/api/admin/Api1AdminRoleController.java
@@ -20,10 +20,13 @@
 import com.supwisdom.leaveschool.common.model.PagerResponseModel;
 import com.supwisdom.leaveschool.user.domain.GroupRole;
 import com.supwisdom.leaveschool.user.domain.Role;
+import com.supwisdom.leaveschool.user.domain.RolePermission;
 import com.supwisdom.leaveschool.user.domain.UserRole;
 import com.supwisdom.leaveschool.user.model.GroupRoles;
+import com.supwisdom.leaveschool.user.model.RolePermissions;
 import com.supwisdom.leaveschool.user.model.UserRoles;
 import com.supwisdom.leaveschool.user.repository.GroupRoleRepository;
+import com.supwisdom.leaveschool.user.repository.RolePermissionRepository;
 import com.supwisdom.leaveschool.user.repository.RoleRepository;
 import com.supwisdom.leaveschool.user.repository.UserRoleRepository;
 
@@ -202,4 +205,86 @@
     return res;
   }
 
+
+
+  @Autowired
+  private RolePermissionRepository rolePermissionRepository;
+
+  /**
+   * 
+   * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:10010/api/v1/admin/roles/1/permissions'
+   * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:10010/api/v1/admin/roles/1/permissions?pageIndex=2&pageSize=50'
+   * curl -i -s -X GET -H 'Accept:application/json' 'http://localhost:10010/api/v1/admin/roles/1/permissions?pageIndex=0&pageSize=20&mapBean[permissionCode]=permissionCode'
+   * 
+   * 
+   * 
+   * @param id
+   * @param pagerRequestModel
+   * @return
+   */
+  @RequestMapping(value = "/{id}/permissions", method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+  @ResponseBody
+  public PagerResponseModel<RolePermission> rolePermissions(@PathVariable("id") String id, PagerRequestModel pagerRequestModel) {
+
+    if (id == null || id.length() == 0) {
+      throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+    }
+
+    Role role = roleRepository.selectById(id);
+
+    if (role == null) {
+      throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+    }
+
+    if (pagerRequestModel.getMapBean() == null) {
+      pagerRequestModel.setMapBean(new HashMap<String, Object>());
+    }
+    pagerRequestModel.getMapBean().put("rolecode", role.getCode());
+
+    Page<RolePermission> page = rolePermissionRepository.selectRolePermissions(pagerRequestModel.getPageIndex(),
+        pagerRequestModel.getPageSize(), pagerRequestModel.getMapBean());
+
+    @SuppressWarnings("unchecked")
+    List<RolePermission> list = IteratorUtils.toList(page.iterator());
+
+    PagerResponseModel<RolePermission> pagerResponseModel = PagerResponseModel.of(pagerRequestModel);
+    pagerResponseModel.setPageCount(page.getTotalPages());
+    pagerResponseModel.setRecordCount(page.getTotalElements());
+    pagerResponseModel.setItems(list);
+
+    return pagerResponseModel;
+  }
+
+  /**
+   * 
+   * curl -i -s -X POST -H 'Content-Type:application/json' -H 'Accept:application/json' 'http://localhost:10010/api/v1/admin/roles/1/permissons' \
+   * -d '{"userRoles":[{"groupId":"1"},{"groupId":"2"}]}'
+   * 
+   * 
+   * @param id
+   * @param groupRoles
+   * @return
+   */
+  @RequestMapping(value = "/{id}/permissons", method = RequestMethod.POST, consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
+  @ResponseBody
+  public Map<String, Object> relatePermissions(@PathVariable("id") String id, @RequestBody RolePermissions rolePermissions) {
+
+    if (id == null || id.length() == 0) {
+      throw new RuntimeException("exception.get.id.must.not.empty"); // FIXME: RestException
+    }
+
+    Role role = roleRepository.selectById(id);
+
+    if (role == null) {
+      throw new RuntimeException("exception.get.domain.not.exist"); // FIXME: RestException
+    }
+
+    rolePermissionRepository.relateRolePermissions(role, rolePermissions.getRolePermissions());
+
+    Map<String, Object> res = new HashMap<String, Object>();
+    res.put("success", "info.set.success");
+
+    return res;
+  }
+
 }
diff --git a/samples/user/src/main/java/com/supwisdom/leaveschool/user/domain/Permission.java b/samples/user/src/main/java/com/supwisdom/leaveschool/user/domain/Permission.java
index 1473f80..b5954ff 100644
--- a/samples/user/src/main/java/com/supwisdom/leaveschool/user/domain/Permission.java
+++ b/samples/user/src/main/java/com/supwisdom/leaveschool/user/domain/Permission.java
@@ -39,6 +39,42 @@
   @Column(name = "STATUS")
   private String status;
 
+  /**
+   * 类型(1 应用,2 页面,3 操作)
+   */
+  @Column(name = "TYPE")
+  private String type;
+
+  /**
+   * URL地址
+   */
+  @Column(name = "URL")
+  private String url;
+
+  /**
+   * 父级ID
+   */
+  @Column(name = "PARENT_ID")
+  private String parentId;
+
+  /**
+   * 层次
+   */
+  @Column(name = "LEVEL")
+  private String level;
+
+  /**
+   * 左序
+   */
+  @Column(name = "LFT")
+  private int lft;
+
+  /**
+   * 右序
+   */
+  @Column(name = "RGT")
+  private int rgt;
+
   public String getCode() {
     return code;
   }
@@ -71,4 +107,52 @@
     this.status = status;
   }
 
+  public String getType() {
+    return type;
+  }
+
+  public void setType(String type) {
+    this.type = type;
+  }
+
+  public String getUrl() {
+    return url;
+  }
+
+  public void setUrl(String url) {
+    this.url = url;
+  }
+
+  public String getParentId() {
+    return parentId;
+  }
+
+  public void setParentId(String parentId) {
+    this.parentId = parentId;
+  }
+
+  public String getLevel() {
+    return level;
+  }
+
+  public void setLevel(String level) {
+    this.level = level;
+  }
+
+  public int getLft() {
+    return lft;
+  }
+
+  public void setLft(int lft) {
+    this.lft = lft;
+  }
+
+  public int getRgt() {
+    return rgt;
+  }
+
+  public void setRgt(int rgt) {
+    this.rgt = rgt;
+  }
+
 }
diff --git a/samples/user/src/main/java/com/supwisdom/leaveschool/user/domain/RolePermission.java b/samples/user/src/main/java/com/supwisdom/leaveschool/user/domain/RolePermission.java
new file mode 100644
index 0000000..4edfb92
--- /dev/null
+++ b/samples/user/src/main/java/com/supwisdom/leaveschool/user/domain/RolePermission.java
@@ -0,0 +1,46 @@
+package com.supwisdom.leaveschool.user.domain;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import com.supwisdom.leaveschool.common.domain.ABaseDomain;
+
+@Entity
+@Table(name = "TB_U_ROLE_PERMISSION")
+public class RolePermission extends ABaseDomain {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = 5293251541687343949L;
+
+  /**
+   * 角色代码
+   */
+  @Column(name = "ROLECODE")
+  private String rolecode;
+
+  /**
+   * 权限ID
+   */
+  @Column(name = "PERMISSION_ID")
+  private String permissionId;
+
+  public String getRolecode() {
+    return rolecode;
+  }
+
+  public void setRolecode(String rolecode) {
+    this.rolecode = rolecode;
+  }
+
+  public String getPermissionId() {
+    return permissionId;
+  }
+
+  public void setPermissionId(String permissionId) {
+    this.permissionId = permissionId;
+  }
+
+}
diff --git a/samples/user/src/main/java/com/supwisdom/leaveschool/user/model/RolePermissions.java b/samples/user/src/main/java/com/supwisdom/leaveschool/user/model/RolePermissions.java
new file mode 100644
index 0000000..72cfb4d
--- /dev/null
+++ b/samples/user/src/main/java/com/supwisdom/leaveschool/user/model/RolePermissions.java
@@ -0,0 +1,25 @@
+package com.supwisdom.leaveschool.user.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+import com.supwisdom.leaveschool.user.domain.RolePermission;
+
+public class RolePermissions implements Serializable {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = -2452925034310554167L;
+  
+  private List<RolePermission> rolePermissions;
+
+  public List<RolePermission> getRolePermissions() {
+    return rolePermissions;
+  }
+
+  public void setRolePermissions(List<RolePermission> rolePermissions) {
+    this.rolePermissions = rolePermissions;
+  }
+
+}
diff --git a/samples/user/src/main/java/com/supwisdom/leaveschool/user/repository/PermissionRepository.java b/samples/user/src/main/java/com/supwisdom/leaveschool/user/repository/PermissionRepository.java
new file mode 100644
index 0000000..fc1a5c3
--- /dev/null
+++ b/samples/user/src/main/java/com/supwisdom/leaveschool/user/repository/PermissionRepository.java
@@ -0,0 +1,41 @@
+package com.supwisdom.leaveschool.user.repository;
+
+import java.util.Map;
+
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Repository;
+
+import com.supwisdom.leaveschool.common.repository.BaseJpaRepository;
+import com.supwisdom.leaveschool.common.util.MapBeanUtils;
+import com.supwisdom.leaveschool.user.domain.Permission;
+
+@Repository
+public interface PermissionRepository extends BaseJpaRepository<Permission> {
+
+  public default Page<Permission> selectPageList(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+    Permission probe = new Permission();
+    if (mapBean != null) {
+      probe.setCode(MapBeanUtils.getString(mapBean, "code"));
+      probe.setName(MapBeanUtils.getString(mapBean, "name"));
+      probe.setMemo(MapBeanUtils.getString(mapBean, "memo"));
+      probe.setStatus(MapBeanUtils.getString(mapBean, "status"));
+    }
+    
+    ExampleMatcher matcher = ExampleMatcher.matching()
+        .withMatcher("code", ExampleMatcher.GenericPropertyMatchers.contains())
+        .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains())
+        .withMatcher("memo", ExampleMatcher.GenericPropertyMatchers.contains())
+        .withMatcher("status", ExampleMatcher.GenericPropertyMatchers.exact());
+    
+    PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+    Example<Permission> example = Example.of(probe, matcher);
+    
+    Page<Permission> page = this.findAll(example, pageRequest);
+    
+    return page;
+  }
+  
+}
diff --git a/samples/user/src/main/java/com/supwisdom/leaveschool/user/repository/RolePermissionRepository.java b/samples/user/src/main/java/com/supwisdom/leaveschool/user/repository/RolePermissionRepository.java
new file mode 100644
index 0000000..b967598
--- /dev/null
+++ b/samples/user/src/main/java/com/supwisdom/leaveschool/user/repository/RolePermissionRepository.java
@@ -0,0 +1,151 @@
+package com.supwisdom.leaveschool.user.repository;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.data.domain.Example;
+import org.springframework.data.domain.ExampleMatcher;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.stereotype.Repository;
+
+import com.supwisdom.leaveschool.common.repository.BaseJpaRepository;
+import com.supwisdom.leaveschool.common.util.MapBeanUtils;
+import com.supwisdom.leaveschool.user.domain.Permission;
+import com.supwisdom.leaveschool.user.domain.RolePermission;
+import com.supwisdom.leaveschool.user.domain.Role;
+
+@Repository
+public interface RolePermissionRepository extends BaseJpaRepository<RolePermission> {
+
+  public default Page<RolePermission> selectPageList(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+    RolePermission probe = new RolePermission();
+    if (mapBean != null) {
+      probe.setRolecode(MapBeanUtils.getString(mapBean, "rolecode"));
+      probe.setPermissionId(MapBeanUtils.getString(mapBean, "permissionId"));
+    }
+
+    ExampleMatcher matcher = ExampleMatcher.matching()
+        .withMatcher("rolecode", ExampleMatcher.GenericPropertyMatchers.exact())
+        .withMatcher("permissionId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+    PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+    Example<RolePermission> example = Example.of(probe, matcher);
+
+    Page<RolePermission> page = this.findAll(example, pageRequest);
+
+    return page;
+  }
+
+  public default Page<RolePermission> selectRolePermissions(int pageIndex, int pageSize, Map<String, Object> mapBean) {
+
+    RolePermission probe = new RolePermission();
+    if (mapBean != null) {
+      probe.setRolecode(MapBeanUtils.getString(mapBean, "rolecode"));
+      probe.setPermissionId(MapBeanUtils.getString(mapBean, "permissionId"));
+    }
+
+    ExampleMatcher matcher = ExampleMatcher.matching()
+        .withMatcher("rolecode", ExampleMatcher.GenericPropertyMatchers.exact())
+        .withMatcher("permissionId", ExampleMatcher.GenericPropertyMatchers.exact());
+
+    Example<RolePermission> example = Example.of(probe, matcher);
+
+    PageRequest pageRequest = PageRequest.of(pageIndex, pageSize);
+
+    Page<RolePermission> page = this.findAll(example, pageRequest); // FIXME: 多表关联查询
+
+    return page;
+  }
+
+  public default void relateRolePermissions(Role role, List<RolePermission> rolePermissions) {
+
+    List<RolePermission> existRolePermissions = this.selectListByRolecode(role.getCode());
+
+    Map<String, RolePermission> existMapRolePermissions = new LinkedHashMap<String, RolePermission>();
+    for (RolePermission rolePermission : existRolePermissions) {
+      String k = String.format("%s", rolePermission.getPermissionId());
+      existMapRolePermissions.put(k, rolePermission);
+    }
+
+    for (RolePermission rolePermission : rolePermissions) {
+      String k = String.format("%s", rolePermission.getPermissionId());
+
+      if (existMapRolePermissions.containsKey(k)) {
+        existMapRolePermissions.remove(k);
+      } else {
+        rolePermission.setCompanyId(role.getCompanyId());
+        rolePermission.setRolecode(role.getCode());
+
+        this.insert(rolePermission);
+      }
+    }
+
+    for (RolePermission rolePermission : existMapRolePermissions.values()) {
+      this.deleteById(rolePermission.getId());
+    }
+  }
+
+  public default List<RolePermission> selectListByRolecode(String rolecode) {
+
+    RolePermission probe = new RolePermission();
+    probe.setRolecode(rolecode);
+
+    ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("rolecode",
+        ExampleMatcher.GenericPropertyMatchers.exact());
+
+    Example<RolePermission> example = Example.of(probe, matcher);
+
+    List<RolePermission> rolePermissions = this.findAll(example);
+
+    return rolePermissions;
+  }
+
+  public default void relatePermissionRoles(Permission permission, List<RolePermission> rolePermissions) {
+
+    // 获取权限已关联的角色
+    List<RolePermission> existPermissionRoles = this.selectListByPermissionId(permission.getId());
+
+    Map<String, RolePermission> existMapPermissionRoles = new LinkedHashMap<String, RolePermission>();
+    for (RolePermission rolePermission : existPermissionRoles) {
+      String k = String.format("%s", rolePermission.getRolecode());
+      existMapPermissionRoles.put(k, rolePermission);
+    }
+
+    // 保存未关联的角色
+    for (RolePermission rolePermission : rolePermissions) {
+      String k = String.format("%s", rolePermission.getRolecode());
+
+      if (existMapPermissionRoles.containsKey(k)) {
+        existMapPermissionRoles.remove(k);
+      } else {
+        rolePermission.setCompanyId(permission.getCompanyId());
+        rolePermission.setPermissionId(permission.getId());
+
+        this.insert(rolePermission);
+      }
+    }
+
+    // 删除移除关联的角色
+    for (RolePermission rolePermission : existMapPermissionRoles.values()) {
+      this.deleteById(rolePermission.getId());
+    }
+  }
+
+  public default List<RolePermission> selectListByPermissionId(String permissionId) {
+
+    RolePermission probe = new RolePermission();
+    probe.setPermissionId(permissionId);
+
+    ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("permissionId",
+        ExampleMatcher.GenericPropertyMatchers.exact());
+
+    Example<RolePermission> example = Example.of(probe, matcher);
+
+    List<RolePermission> rolePermissions = this.findAll(example);
+
+    return rolePermissions;
+  }
+
+}
diff --git a/samples/user/src/main/java/com/supwisdom/leaveschool/user/repository/RoleRepository.java b/samples/user/src/main/java/com/supwisdom/leaveschool/user/repository/RoleRepository.java
index 5cecfe5..18bda86 100644
--- a/samples/user/src/main/java/com/supwisdom/leaveschool/user/repository/RoleRepository.java
+++ b/samples/user/src/main/java/com/supwisdom/leaveschool/user/repository/RoleRepository.java
@@ -1,6 +1,7 @@
 package com.supwisdom.leaveschool.user.repository;
 
 import java.util.Map;
+import java.util.Optional;
 
 import org.springframework.data.domain.Example;
 import org.springframework.data.domain.ExampleMatcher;
@@ -38,4 +39,23 @@
     return page;
   }
   
+  
+  public default Role selectByCode(String code) {
+    Role probe = new Role();
+    probe.setCode(code);
+    
+    ExampleMatcher matcher = ExampleMatcher.matching()
+        .withMatcher("code", ExampleMatcher.GenericPropertyMatchers.exact());
+    
+    Example<Role> example = Example.of(probe, matcher);
+    
+    Optional<Role> o = this.findOne(example);
+    
+    if (o.isPresent()) {
+      return o.get();
+    }
+    
+    return null;
+  }
+  
 }
diff --git a/sql/sample-user.sql b/sql/sample-user.sql
index 3304062..1350738 100644
--- a/sql/sample-user.sql
+++ b/sql/sample-user.sql
@@ -137,3 +137,52 @@
 
 
 
+CREATE TABLE `TB_U_PERMISSION` (
+  `ID` VARCHAR(100) NOT NULL COMMENT '',
+  `COMPANY_ID` VARCHAR(100) COMMENT 'CompanyID',
+  `DELETED` INT(1) COMMENT '是否删除',
+  `ADD_ACCOUNT` VARCHAR(100) COMMENT '创建人',
+  `ADD_TIME` DATETIME COMMENT '创建时间',
+  `EDIT_ACCOUNT` VARCHAR(100) COMMENT '修改人',
+  `EDIT_TIME` DATETIME COMMENT '修改时间',
+  `DELETE_ACCOUNT` VARCHAR(100) COMMENT '删除人',
+  `DELETE_TIME` DATETIME COMMENT '删除时间',
+
+  `CODE` VARCHAR(200) NOT NULL COMMENT '代码',
+  `NAME` VARCHAR(200) NOT NULL COMMENT '名称',
+  `MEMO` VARCHAR(500) COMMENT '备注',
+  `STATUS` VARCHAR(10) NOT NULL COMMENT '状态(1 启用,0 停用)',
+
+  `TYPE` VARCHAR(10) NOT NULL COMMENT '类型(1 应用,2 页面,3 操作)',
+  `URL` VARCHAR(500) COMMENT 'URL地址',
+
+  `PARENT_ID` VARCHAR(10) NOT NULL COMMENT '父级ID', 
+  `LEVEL` VARCHAR(10) NOT NULL COMMENT '层次',
+  `LFT` INT(11) COMMENT '左序',
+  `RGT` INT(11) COMMENT '右序',
+
+  PRIMARY KEY (`ID`),
+  UNIQUE KEY `UQ_CODE` (`COMPANY_ID`,`CODE`)
+)
+COMMENT = '权限表';
+
+
+
+CREATE TABLE `TB_U_ROLE_PERMISSION` (
+  `ID` VARCHAR(100) NOT NULL COMMENT '',
+  `COMPANY_ID` VARCHAR(100) COMMENT 'CompanyID',
+  `DELETED` INT(1) COMMENT '是否删除',
+  `ADD_ACCOUNT` VARCHAR(100) COMMENT '创建人',
+  `ADD_TIME` DATETIME COMMENT '创建时间',
+  `EDIT_ACCOUNT` VARCHAR(100) COMMENT '修改人',
+  `EDIT_TIME` DATETIME COMMENT '修改时间',
+  `DELETE_ACCOUNT` VARCHAR(100) COMMENT '删除人',
+  `DELETE_TIME` DATETIME COMMENT '删除时间',
+
+  `ROLECODE` VARCHAR(200) NOT NULL COMMENT '角色代码',
+  `PERMISSION_ID` VARCHAR(200) NOT NULL COMMENT '权限ID',
+
+  PRIMARY KEY (`ID`)
+)
+COMMENT = '角色 - 权限表';
+