springboot 整合 shiro、JPA 、sqlserver实现权限管理

1、添加maven依赖

        <!-- shiro -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>
        <!-- 兼容于thymeleaf的shiro -->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>

2、添加实体类 SysUSer、SysRole、SysPermission

@Entity
@Table(name = "sys_user")
public class SysUser {

    @Id
    private String userId;
    @Column(unique =true)
    private String username;//帐号
    private String nickName;//名称(昵称或者真实姓名,不同系统不同定义)
    private String password; //密码;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
    private Date createTime;
    
    //private byte state;//用户状态,0:创建未认证(比如没有激活,没有输入验证码等等)--等待验证的用户 , 1:正常状态,2:用户被锁定.

    private Boolean createUser;//操作人

    @ManyToMany(fetch= FetchType.EAGER)//立即从数据库中进行加载数据;
    @JoinTable(name = "sys_user_role", joinColumns = { @JoinColumn(name = "userId") }, inverseJoinColumns ={@JoinColumn(name = "roleId") })
    private List<SysRole> roleList;// 一个用户具有多个角色

    /**
     * 密码盐.
     * @return
     */
    public String getCredentialsSalt(){
        return this.username;
    }


    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public byte getState() {
        return state;
    }

    public void setState(byte state) {
        this.state = state;
    }

    public List<SysRole> getRoleList() {
        return roleList;
    }

    public void setRoleList(List<SysRole> roleList) {
        this.roleList = roleList;
    }

    public Boolean getCreateUser() {
        return createUser;
    }

    public void setCreateUser(Boolean createUser) {
        this.createUser = createUser;
    }
}
@Entity
@Table(name = "sys_role")
public class SysRole {

    @Id
    private String id; // 编号
    private String role; // 角色标识程序中判断使用,如"admin",这个是唯一的:
    private String description; // 角色描述,UI界面显示使用
    private Boolean available = Boolean.TRUE; // 是否可用,如果不可用将不会添加给用户
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
    private Date createTime;

    //角色 -- 权限关系:多对多关系;
    @ManyToMany(fetch= FetchType.EAGER)
    @JoinTable(name="sys_role_permission",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="permissionId")})
    private List<SysPermission> permissions;

    // 用户 - 角色关系定义;
    @ManyToMany
    @JoinTable(name="sys_user_role",joinColumns={@JoinColumn(name="roleId")},inverseJoinColumns={@JoinColumn(name="userId")})
    private List<SysUser> userInfos;// 一个角色对应多个用户

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Boolean getAvailable() {
        return available;
    }

    public void setAvailable(Boolean available) {
        this.available = available;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public List<SysPermission> getPermissions() {
        return permissions;
    }

    public void setPermissions(List<SysPermission> permissions) {
        this.permissions = permissions;
    }

    public List<SysUser> getUserInfos() {
        return userInfos;
    }

    public void setUserInfos(List<SysUser> userInfos) {
        this.userInfos = userInfos;
    }
}
@Entity
@Table(name = "sys_permission")
public class SysPermission {

    @Id
    private String id;//主键.
    private String name;//名称.
    @Column(columnDefinition="enum('menu','button')")
    private String resourceType;//资源类型,[menu|button]
    private String url;//资源路径.
    private String permission; //权限字符串,menu例子:role:*,button例子:role:create,role:update,role:delete,role:view
    private String parentId; //父编号
    private String parentIds; //父编号列表
    private Boolean available = Boolean.TRUE;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
    private Date createTime;

    private Integer orderNum;//排序

    @ManyToMany
    @JoinTable(name="sys_role_permission",joinColumns={@JoinColumn(name="permissionId")},inverseJoinColumns={@JoinColumn(name="roleId")})
    private List<SysRole> roles;


    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getResourceType() {
        return resourceType;
    }

    public void setResourceType(String resourceType) {
        this.resourceType = resourceType;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getPermission() {
        return permission;
    }

    public void setPermission(String permission) {
        this.permission = permission;
    }

    public String getParentId() {
        return parentId;
    }

    public void setParentId(String parentId) {
        this.parentId = parentId;
    }

    public String getParentIds() {
        return parentIds;
    }

    public void setParentIds(String parentIds) {
        this.parentIds = parentIds;
    }

    public Boolean getAvailable() {
        return available;
    }

    public void setAvailable(Boolean available) {
        this.available = available;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public List<SysRole> getRoles() {
        return roles;
    }

    public void setRoles(List<SysRole> roles) {
        this.roles = roles;
    }

    public Integer getOrderNum() {
        return orderNum;
    }

    public void setOrderNum(Integer orderNum) {
        this.orderNum = orderNum;
    }
}

实体类不能用@Data注解来配置get set 方法,实体类会重复加载关联表数据,导致报错

3、数据库应该有五张表

sys_permission

sys_role

sys_user

sys_role_permission

sys_user_role

/*
Navicat SQL Server Data Transfer

Source Server         : localhost
Source Server Version : 105000
Source Host           : localhost:1433
Source Database       : shiro_demo
Source Schema         : dbo

Target Server Type    : SQL Server
Target Server Version : 105000
File Encoding         : 65001

Date: 2019-04-28 11:39:25
*/


-- ----------------------------
-- 创建权限表 sys_permission
-- ----------------------------
DROP TABLE [dbo].[sys_permission]
GO
CREATE TABLE [dbo].[sys_permission] (
[id] varchar(225) NOT NULL ,
[name] varchar(225) NULL ,
[resource_type] varchar(225) NULL ,
[url] varchar(225) NULL ,
[permission] varchar(225) NULL ,
[available] varchar(225) NULL ,
[parent_id] varchar(225) NULL ,
[parent_ids] varchar(255) NULL ,
[create_time] datetime2(7) NOT NULL ,
[order_num] int NULL 
)


GO

-- ----------------------------
-- sys_permission 权限表插入数据
-- ----------------------------
INSERT INTO [dbo].[sys_permission] ([id], [name], [resource_type], [url], [permission], [available], [parent_id], [parent_ids], [create_time], [order_num]) VALUES (N'06f0c8b82d544f8085691913687df551', N'角色删除', N'button', N'/sysrole/deleteById', N'sysrole:delete', N'1', N'66185a14828b47828c4eaf40ae45e1d7', N'', N'2019-04-18 10:54:15.0000000', N'2')
GO
GO
INSERT INTO [dbo].[sys_permission] ([id], [name], [resource_type], [url], [permission], [available], [parent_id], [parent_ids], [create_time], [order_num]) VALUES (N'5739f65164444011bde4833c86354f93', N'权限编辑', N'button', N'/syspermission/edit', N'syspermission:edit', N'1', N'6880007dcce0491b8511753dd5ee1a5e', N'', N'2019-04-18 10:54:15.0000000', N'1')
GO
GO
INSERT INTO [dbo].[sys_permission] ([id], [name], [resource_type], [url], [permission], [available], [parent_id], [parent_ids], [create_time], [order_num]) VALUES (N'66185a14828b47828c4eaf40ae45e1d7', N'角色管理', N'menu', N'sysrole/list', N'sysrole:view', N'1', N'0', N'', N'2019-04-18 10:54:15.0000000', N'1')
GO
GO
INSERT INTO [dbo].[sys_permission] ([id], [name], [resource_type], [url], [permission], [available], [parent_id], [parent_ids], [create_time], [order_num]) VALUES (N'6880007dcce0491b8511753dd5ee1a5e', N'权限管理', N'menu', N'syspermission/list', N'syspermission:view', N'1', N'0', N'', N'2019-04-18 10:54:15.0000000', N'2')
GO
GO
INSERT INTO [dbo].[sys_permission] ([id], [name], [resource_type], [url], [permission], [available], [parent_id], [parent_ids], [create_time], [order_num]) VALUES (N'88aac459b3484a0296201d8d19b59210', N'用户管理', N'menu', N'sysuser/list', N'sysuser:view', N'1', N'0', N'', N'2019-04-18 10:54:15.0000000', N'3')
GO
GO
INSERT INTO [dbo].[sys_permission] ([id], [name], [resource_type], [url], [permission], [available], [parent_id], [parent_ids], [create_time], [order_num]) VALUES (N'a3080c70b61a4180ac5ab4dd16d42b61', N'权限删除', N'button', N'/syspermission/deleteById', N'syspermission:delete', N'1', N'6880007dcce0491b8511753dd5ee1a5e', N'', N'2019-04-18 10:54:15.0000000', N'2')
GO
GO
INSERT INTO [dbo].[sys_permission] ([id], [name], [resource_type], [url], [permission], [available], [parent_id], [parent_ids], [create_time], [order_num]) VALUES (N'aaedf1eee04d47f9819449749399603a', N'用户删除', N'button', N'sysuser/deleteById', N'sysuser:delete', N'1', N'88aac459b3484a0296201d8d19b59210', N'', N'2019-04-18 10:54:15.0000000', N'2')
GO
GO
INSERT INTO [dbo].[sys_permission] ([id], [name], [resource_type], [url], [permission], [available], [parent_id], [parent_ids], [create_time], [order_num]) VALUES (N'aaedf1eee04d47f9819449749399603c', N'用户编辑', N'button', N'sysuser/edit', N'sysuser:edit', N'1', N'88aac459b3484a0296201d8d19b59210', N'', N'2019-04-18 10:54:15.0000000', N'1')
GO
GO
INSERT INTO [dbo].[sys_permission] ([id], [name], [resource_type], [url], [permission], [available], [parent_id], [parent_ids], [create_time], [order_num]) VALUES (N'c2cf6721c69d47528663e238ee947bfe', N'角色编辑', N'button', N'/sysrole/edit', N'sysrole:edit', N'1', N'66185a14828b47828c4eaf40ae45e1d7', N'', N'2019-04-18 10:54:15.0000000', N'1')
GO
GO

-- ----------------------------
-- 创建角色表 for sys_role
-- ----------------------------
DROP TABLE [dbo].[sys_role]
GO
CREATE TABLE [dbo].[sys_role] (
[id] varchar(225) NOT NULL ,
[role] varchar(225) NULL ,
[description] varchar(225) NULL ,
[available] tinyint NULL ,
[create_time] datetime2(7) NOT NULL 
)


GO

-- ----------------------------
-- sys_role 角色表插入数据
-- ----------------------------
INSERT INTO [dbo].[sys_role] ([id], [role], [description], [available], [create_time]) VALUES (N'1', N'管理员', N'权限管理', N'1', N'2019-04-28 11:31:44.0000000')
GO
GO

-- ----------------------------
-- 创建角色权限表 sys_role_permission
-- ----------------------------
DROP TABLE [dbo].[sys_role_permission]
GO
CREATE TABLE [dbo].[sys_role_permission] (
[permission_id] varchar(225) NOT NULL ,
[role_id] varchar(225) NOT NULL 
)


GO

-- ----------------------------
-- sys_role_permission 插入数据
-- ----------------------------
INSERT INTO [dbo].[sys_role_permission] ([permission_id], [role_id]) VALUES (N'06f0c8b82d544f8085691913687df551', N'1')
GO
GO
INSERT INTO [dbo].[sys_role_permission] ([permission_id], [role_id]) VALUES (N'5739f65164444011bde4833c86354f93', N'1')
GO
GO
INSERT INTO [dbo].[sys_role_permission] ([permission_id], [role_id]) VALUES (N'66185a14828b47828c4eaf40ae45e1d7', N'1')
GO
GO
INSERT INTO [dbo].[sys_role_permission] ([permission_id], [role_id]) VALUES (N'6880007dcce0491b8511753dd5ee1a5e', N'1')
GO
GO
INSERT INTO [dbo].[sys_role_permission] ([permission_id], [role_id]) VALUES (N'88aac459b3484a0296201d8d19b59210', N'1')
GO
GO
INSERT INTO [dbo].[sys_role_permission] ([permission_id], [role_id]) VALUES (N'a3080c70b61a4180ac5ab4dd16d42b61', N'1')
GO
GO
INSERT INTO [dbo].[sys_role_permission] ([permission_id], [role_id]) VALUES (N'aaedf1eee04d47f9819449749399603a', N'1')
GO
GO
INSERT INTO [dbo].[sys_role_permission] ([permission_id], [role_id]) VALUES (N'aaedf1eee04d47f9819449749399603c', N'1')
GO
GO
INSERT INTO [dbo].[sys_role_permission] ([permission_id], [role_id]) VALUES (N'c2cf6721c69d47528663e238ee947bfe', N'1')
GO
GO

-- ----------------------------
-- 创建用户表 for sys_user
-- ----------------------------
DROP TABLE [dbo].[sys_user]
GO
CREATE TABLE [dbo].[sys_user] (
[user_id] varchar(100) NOT NULL ,
[username] varchar(255) NULL DEFAULT NULL ,
[password] varchar(255) NULL DEFAULT NULL ,
[nick_name] varchar(255) NULL DEFAULT NULL ,
[state] char(1) NULL ,
[create_time] datetime2(7) NULL ,
[create_user] varchar(225) NULL 
)


GO
IF ((SELECT COUNT(*) from fn_listextendedproperty('MS_Description', 
'SCHEMA', N'dbo', 
'TABLE', N'sys_user', 
'COLUMN', N'state')) > 0) 
EXEC sp_updateextendedproperty @name = N'MS_Description', @value = N'用户状态,0:创建未认证(比如没有激活,没有输入验证码等等)--等待验证的用户 , 1:正常状态,2:用户被锁定.'
, @level0type = 'SCHEMA', @level0name = N'dbo'
, @level1type = 'TABLE', @level1name = N'sys_user'
, @level2type = 'COLUMN', @level2name = N'state'
ELSE
EXEC sp_addextendedproperty @name = N'MS_Description', @value = N'用户状态,0:创建未认证(比如没有激活,没有输入验证码等等)--等待验证的用户 , 1:正常状态,2:用户被锁定.'
, @level0type = 'SCHEMA', @level0name = N'dbo'
, @level1type = 'TABLE', @level1name = N'sys_user'
, @level2type = 'COLUMN', @level2name = N'state'
GO

-- ----------------------------
-- sys_user 用户表插入数据
-- ----------------------------
INSERT INTO [dbo].[sys_user] ([user_id], [username], [password], [nick_name], [state], [create_time], [create_user]) VALUES (N'1', N'admin', N'be98207ac6d9de9ce8f53ada21922be3', N'管理员', N'0', N'2019-04-28 11:30:43.0000000', N'1')
GO
GO

-- ----------------------------
-- 创建用户角色表 sys_user_role
-- ----------------------------
DROP TABLE [dbo].[sys_user_role]
GO
CREATE TABLE [dbo].[sys_user_role] (
[role_id] varchar(225) NOT NULL ,
[user_id] varchar(225) NOT NULL 
)


GO

-- ----------------------------
-- sys_user_role 用户角色表插入数据
-- ----------------------------
INSERT INTO [dbo].[sys_user_role] ([role_id], [user_id]) VALUES (N'1', N'1')
GO
GO

-- ----------------------------
-- Indexes structure for table sys_permission
-- ----------------------------

-- ----------------------------
-- Primary Key structure for table sys_permission
-- ----------------------------
ALTER TABLE [dbo].[sys_permission] ADD PRIMARY KEY ([id])
GO

-- ----------------------------
-- Indexes structure for table sys_role
-- ----------------------------

-- ----------------------------
-- Primary Key structure for table sys_role
-- ----------------------------
ALTER TABLE [dbo].[sys_role] ADD PRIMARY KEY ([id])
GO

-- ----------------------------
-- Indexes structure for table sys_user
-- ----------------------------

-- ----------------------------
-- Primary Key structure for table sys_user
-- ----------------------------
ALTER TABLE [dbo].[sys_user] ADD PRIMARY KEY ([user_id])
GO

-- ----------------------------
-- Foreign Key structure for table [dbo].[sys_user_role]
-- ----------------------------
ALTER TABLE [dbo].[sys_user_role] ADD FOREIGN KEY ([role_id]) REFERENCES [dbo].[sys_role] ([id]) ON DELETE NO ACTION ON UPDATE NO ACTION
GO

4、添加DAO类

public interface SysPermissionRepository extends BaseRepository<SysPermission,Integer> {

    SysPermission findById(String id);

    SysPermission findByName(String name);

    List findAllByOrderByParentIdAscOrderNumAsc();

}
public interface SysRoleRepository extends BaseRepository<SysRole,Integer>{

    SysRole findById(String id);

    SysRole findByRole(String role);

    List findAllByOrderByCreateTimeDesc();
}
public interface SysUserRepository extends BaseRepository<SysUser,Integer> {

    SysUser findByUsernameAndPassword(String username,String password);

    SysUser findByUserId(String userId);

    SysUser findByUsername(String username);
}
@NoRepositoryBean
public interface BaseRepository <T,ID extends Serializable> extends JpaRepository<T,ID>, JpaSpecificationExecutor<T> {
}

5、Service 逻辑

@Service
public class SysPermissionService {

    @Autowired
    SysPermissionRepository sysPermissionRepository;

    public List findAll(){
        return sysPermissionRepository.findAllByOrderByParentIdAscOrderNumAsc();
    }

    public Page findList(String nameParam,
                         int pageNum, int pageSize){
        Pageable pageable = PageRequest.of(pageNum,pageSize, Sort.Direction.ASC,"parentId","orderNum");
        Page<SysPermission> bookPage = sysPermissionRepository.findAll(new Specification<SysPermission>(){
            @Override
            public Predicate toPredicate(Root<SysPermission> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList();
                if(!StringUtils.isEmpty(nameParam)){
                    list.add(criteriaBuilder.like(root.get("name").as(String.class), "%"+nameParam+"%"));
                }
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            }
        },pageable);
        return bookPage;
    }

    public SysPermission findById(String id){
        return sysPermissionRepository.findById(id);
    }

    @Transactional
    public Map edit(SysPermission bean){
        Map map = new HashMap();
        if (null==bean.getId() || "".equals(bean.getId())){//新增
            bean.setId(IdUtil.getId());
        }
        SysPermission idBean = sysPermissionRepository.findById(bean.getId());
        if (null==idBean){//新增
            idBean = sysPermissionRepository.findByName(bean.getName());
            if (null!=idBean){
                map.put("code",0);
                map.put("msg","权限名称不能重复");
                return map;
            }
        }else{//修改
            SysPermission nameBean = sysPermissionRepository.findByName(bean.getName());
            if (null!=nameBean && !nameBean.getId().equals(bean.getId())){
                map.put("code",0);
                map.put("msg","权限名称不能重复");
                return map;
            }
        }

        bean.setCreateTime(DateUtil.currentDateTime());
        bean = sysPermissionRepository.save(bean);
        map.put("bean",bean);
        map.put("code",1);
        map.put("msg","成功");
        return map;
    }

    @Transactional
    public void deleteById(String id){
        SysPermission bean = new SysPermission();
        bean.setId(id);
        sysPermissionRepository.delete(bean);
    }
    
}
@Service
public class SysRoleService {
    
    @Autowired
    SysRoleRepository sysRoleRepository;

    @Autowired
    SysPermissionRepository sysPermissionRepository;

    public List findAll(){
        return sysRoleRepository.findAllByOrderByCreateTimeDesc();
    }

    public Page findList(String nameParam,
                         int pageNum, int pageSize){
        Pageable pageable = PageRequest.of(pageNum,pageSize, Sort.Direction.DESC,"createTime");
        Page<SysRole> bookPage = sysRoleRepository.findAll(new Specification<SysRole>(){
            @Override
            public Predicate toPredicate(Root<SysRole> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList();
                if(!StringUtils.isEmpty(nameParam)){
                    list.add(criteriaBuilder.like(root.get("role").as(String.class), "%"+nameParam+"%"));
                }
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            }
        },pageable);
        return bookPage;
    }

    public SysRole findById(String id){
        return sysRoleRepository.findById(id);
    }

    @Transactional
    public Map edit(SysRole bean,String permissionString){
        Map map = new HashMap();
        if (null==bean.getId() || "".equals(bean.getId())){//新增
            bean.setId(IdUtil.getId());
        }
        SysRole idBean = sysRoleRepository.findById(bean.getId());
        if (null==idBean){//新增
            idBean = sysRoleRepository.findByRole(bean.getRole());
            if (null!=idBean){
                map.put("code",0);
                map.put("msg","角色不能重复");
                return map;
            }
        }else{//修改
            SysRole nameBean = sysRoleRepository.findByRole(bean.getRole());
            if (null!=nameBean && !nameBean.getId().equals(bean.getId())){
                map.put("code",0);
                map.put("msg","角色不能重复");
                return map;
            }
        }

        //设置权限
        JSONArray array = JSON.parseArray(permissionString);
        List<SysPermission> permissions = new ArrayList<>();
        for (int i=0;i<array.size();i++){
            String permissionId = array.get(i).toString();
            SysPermission sysPermission = sysPermissionRepository.findById(permissionId);
            permissions.add(sysPermission);
        }
        bean.setPermissions(permissions);
        bean.setCreateTime(DateUtil.currentDateTime());
        bean = sysRoleRepository.save(bean);
        map.put("bean",bean);
        map.put("code",1);
        map.put("msg","成功");
        return map;
    }

    public Boolean findRoleUserById(String id){
        SysRole sysRole = sysRoleRepository.findById(id);
        if (null!=sysRole.getUserInfos() && sysRole.getUserInfos().size()>0){
            return true;
        }else{
            return false;
        }
    }

    @Transactional
    public void deleteById(String id){
        SysRole bean = new SysRole();
        bean.setId(id);
        sysRoleRepository.delete(bean);
    }
}
@Service
public class SysUserService {

    @Autowired
    SysUserRepository sysUserRepository;
    @Autowired
    SysRoleRepository sysRoleRepository;

    public SysUser findByUsername(String username){
        return sysUserRepository.findByUsername(username);
    }

    public Page findList(String nameParam,
                         int pageNum, int pageSize){
        Pageable pageable = PageRequest.of(pageNum,pageSize, Sort.Direction.DESC,"createTime");
        Page<SysUser> bookPage = sysUserRepository.findAll(new Specification<SysUser>(){
            @Override
            public Predicate toPredicate(Root<SysUser> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList();
                if(!StringUtils.isEmpty(nameParam)){
                    list.add(criteriaBuilder.like(root.get("name").as(String.class), "%"+nameParam+"%"));
                }
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            }
        },pageable);
        return bookPage;
    }

    public SysUser findById(String id){
        return sysUserRepository.findByUserId(id);
    }

    @Transactional
    public Map edit(SysUser bean,String roleIdString){
        Map map = new HashMap();
        if (null==bean.getUserId() || "".equals(bean.getUserId())){//新增
            bean.setUserId(IdUtil.getId());
        }
        SysUser idBean = sysUserRepository.findByUserId(bean.getUserId());
        if (null==idBean){//新增
            idBean = sysUserRepository.findByUsername(bean.getUsername());
            if (null!=idBean){
                map.put("code",0);
                map.put("msg","名称不能重复");
                return map;
            }
            bean.setPassword(PasswordUtil.encryptPassword(bean.getPassword(),bean.getUsername()));
        }else{//修改
            SysUser nameBean = sysUserRepository.findByUsername(bean.getUsername());
            if (null!=nameBean && !nameBean.getUserId().equals(bean.getUserId())){
                map.put("code",0);
                map.put("msg","名称不能重复");
                return map;
            }
            if (null!=nameBean && !nameBean.getPassword().equals(bean.getPassword())){
                bean.setPassword(PasswordUtil.encryptPassword(bean.getPassword(),bean.getUsername()));
            }
        }
        //设置角色
        JSONArray array = JSON.parseArray(roleIdString);
        List<SysRole> roleList = new ArrayList<>();
        for (int i=0;i<array.size();i++){
            String roleId = array.get(i).toString();
            SysRole sysRole = sysRoleRepository.findById(roleId);
            roleList.add(sysRole);
        }
        bean.setRoleList(roleList);
        bean.setCreateTime(DateUtil.currentDateTime());
        bean = sysUserRepository.save(bean);
        map.put("bean",bean);
        map.put("code",1);
        map.put("msg","成功");
        return map;
    }

    @Transactional
    public void deleteById(String id){
        SysUser bean = new SysUser();
        bean.setUserId(id);
        sysUserRepository.delete(bean);
    }
}

6、Controller

package com.ym.bomaccounting.controller;

import com.ym.bomaccounting.entity.SysPermission;
import com.ym.bomaccounting.service.SysPermissionService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("syspermission")
public class SysPermissionController {

    @Autowired
    SysPermissionService sysPermissionService;

    @RequestMapping("list")
    @RequiresPermissions("syspermission:view")//权限管理;
    public String list(HashMap map,String nameParam,
                       @RequestParam(value = "page", defaultValue = "1") Integer page,
                       @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize){
        try {
            map.put("datas",sysPermissionService.findList(nameParam,page-1,pageSize));
            map.put("nameParam",nameParam);
            map.put("permissionList",sysPermissionService.findAll());
            map.put("code",1);
            map.put("msg","成功");
        }catch (Exception e){
            map.put("code",0);
            map.put("msg","失败");
            e.printStackTrace();
        }
        return "sys/permission_list";
    }

    @RequestMapping("toEdit")
    @ResponseBody
    public Map<String,Object> toEdit(String id){
        Map<String,Object> map = new HashMap();
        try {
            map.put("bean",sysPermissionService.findById(id));
            map.put("code",1);
            map.put("msg","成功");
        }catch (Exception e){
            map.put("code",0);
            map.put("msg","失败");
            e.printStackTrace();
        }
        return map;
    }

    @RequestMapping("edit")
    @ResponseBody
    @RequiresPermissions("syspermission:edit")//权限管理;
    public Map editMenu(SysPermission bean){
        Map map = new HashMap();
        try {
            return sysPermissionService.edit(bean);
        }catch (Exception e){
            map.put("code",0);
            map.put("msg","失败");
            e.printStackTrace();
            return map;
        }
    }

    @RequestMapping("deleteById")
    @ResponseBody
    @RequiresPermissions("syspermission:delete")//权限管理;
    public Map deleteById(String id){
        Map map = new HashMap();
        try {
            sysPermissionService.deleteById(id);
            map.put("code",1);
            map.put("msg","成功");
        }catch (Exception e){
            map.put("code",0);
            map.put("msg","失败");
            e.printStackTrace();
        }
        return map;
    }
}
package com.ym.bomaccounting.controller;

import com.ym.bomaccounting.entity.SysRole;
import com.ym.bomaccounting.service.SysPermissionService;
import com.ym.bomaccounting.service.SysRoleService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("sysrole")
public class SysRoleController {

    @Autowired
    SysRoleService sysRoleService;
    @Autowired
    SysPermissionService sysPermissionService;

    @RequestMapping("list")
    @RequiresPermissions("sysrole:view")//权限管理;
    public String list(HashMap map,String nameParam,
                       @RequestParam(value = "page", defaultValue = "1") Integer page,
                       @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize){
        try {
            map.put("datas",sysRoleService.findList(nameParam,page-1,pageSize));
            map.put("nameParam",nameParam);
            map.put("permissionList",sysPermissionService.findAll());
            map.put("code",1);
            map.put("msg","成功");
        }catch (Exception e){
            map.put("code",0);
            map.put("msg","失败");
            e.printStackTrace();
        }
        return "sys/role_list";
    }

    @RequestMapping("toEdit")
    @ResponseBody
    public Map toEdit(String id){
        Map map = new HashMap();
        try {
            SysRole role = sysRoleService.findById(id);
            map.put("bean",role);
            map.put("permissions",role.getPermissions());
            map.put("code",1);
            map.put("msg","成功");
        }catch (Exception e){
            map.put("code",0);
            map.put("msg","失败");
            e.printStackTrace();
        }
        return map;
    }

    @RequestMapping("edit")
    @ResponseBody
    @RequiresPermissions("sysrole:edit")//权限管理;
    public Map editMenu(SysRole bean,String permissionString){
        Map map = new HashMap();
        try {
            return sysRoleService.edit(bean,permissionString);
        }catch (Exception e){
            map.put("code",0);
            map.put("msg","失败");
            e.printStackTrace();
            return map;
        }
    }

    @RequestMapping("deleteById")
    @ResponseBody
    @RequiresPermissions("sysrole:delete")//权限管理;
    public Map deleteById(String id){
        Map map = new HashMap();
        try {
            //查询角色下是否存在用户
            if(sysRoleService.findRoleUserById(id)){
                map.put("code",0);
                map.put("msg","该角色下存在用户,不能删除");
                return map;
            }
            sysRoleService.deleteById(id);
            map.put("code",1);
            map.put("msg","成功");
        }catch (Exception e){
            map.put("code",0);
            map.put("msg","失败");
            e.printStackTrace();
        }
        return map;
    }
}
package com.ym.bomaccounting.controller;

import com.ym.bomaccounting.entity.SysUser;
import com.ym.bomaccounting.service.SysRoleService;
import com.ym.bomaccounting.service.SysUserService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("sysuser")
public class SysUserController {

    @Autowired
    SysUserService sysUserService;
    @Autowired
    SysRoleService sysRoleService;

    @RequestMapping("list")
    @RequiresPermissions("sysuser:view")//权限管理;
    public String list(HashMap map,String nameParam,
                       @RequestParam(value = "page", defaultValue = "1") Integer page,
                       @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize){
        try {
            map.put("datas",sysUserService.findList(nameParam,page-1,pageSize));
            map.put("nameParam",nameParam);
            map.put("roleList",sysRoleService.findAll());
            map.put("code",1);
            map.put("msg","成功");
        }catch (Exception e){
            map.put("code",0);
            map.put("msg","失败");
            e.printStackTrace();
        }
        return "sys/user_list";
    }

    @RequestMapping("toEdit")
    @ResponseBody
    public Map toEdit(String id){
        Map map = new HashMap();
        try {
            map.put("bean",sysUserService.findById(id));
            map.put("code",1);
            map.put("msg","成功");
        }catch (Exception e){
            map.put("code",0);
            map.put("msg","失败");
            e.printStackTrace();
        }
        return map;
    }

    @RequestMapping("edit")
    @ResponseBody
    @RequiresPermissions("sysuser:edit")//权限管理;
    public Map editMenu(SysUser bean,String roleIdString){
        Map map = new HashMap();
        try {
            return sysUserService.edit(bean,roleIdString);
        }catch (Exception e){
            map.put("code",0);
            map.put("msg","失败");
            e.printStackTrace();
            return map;
        }
    }

    @RequestMapping("deleteById")
    @ResponseBody
    @RequiresPermissions("sysuser:delete")//权限管理;
    public Map deleteById(String id){
        Map map = new HashMap();
        try {
            sysUserService.deleteById(id);
            map.put("code",1);
            map.put("msg","成功");
        }catch (Exception e){
            map.put("code",0);
            map.put("msg","失败");
            e.printStackTrace();
        }
        return map;
    }
}

7、shiro config设置

package com.ym.bomaccounting.config;

import com.ym.bomaccounting.entity.SysPermission;
import com.ym.bomaccounting.entity.SysRole;
import com.ym.bomaccounting.entity.SysUser;
import com.ym.bomaccounting.service.SysUserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Created by wmm on 2019/4/12.
 */
public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    SysUserService sysUserService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        SysUser userInfo  = (SysUser) principals.getPrimaryPrincipal();
        for(SysRole role:userInfo.getRoleList()){
            authorizationInfo.addRole(role.getRole());
            for(SysPermission p:role.getPermissions()){
                authorizationInfo.addStringPermission(p.getPermission());
            }
        }
        return authorizationInfo;
    }

    /*主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
            throws AuthenticationException {
        System.out.println("MyShiroRealm.doGetAuthenticationInfo()");
        //获取用户的输入的账号.
        String username = (String)token.getPrincipal();
        System.out.println(token.getCredentials());
        //通过username从数据库中查找 User对象,如果找到,没找到.
        //实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法
        SysUser userInfo = sysUserService.findByUsername(username);
//        System.out.println("----->>userInfo="+userInfo);
        if(userInfo == null){
            return null;
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                userInfo, //用户名
                userInfo.getPassword(), //密码
                ByteSource.Util.bytes(userInfo.getCredentialsSalt()),//salt=username+salt
                getName()  //realm name
        );
        return authenticationInfo;
    }

}
package com.ym.bomaccounting.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Created by wmm on 2019/4/12.
 */
@Configuration
public class ShiroConfig {
    private static final Logger log = LoggerFactory.getLogger(ShiroConfig.class);

    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        System.out.println("ShiroConfiguration.shirFilter()");
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //拦截器.
        Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
        // 配置不会被拦截的链接 顺序判断
        filterChainDefinitionMap.put("/static/**", "anon");
        //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
        filterChainDefinitionMap.put("/logout", "logout");
        //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
        //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
        filterChainDefinitionMap.put("/**", "authc");
        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.setSuccessUrl("/home");

        //未授权界面;
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    /**
     * 凭证匹配器
     * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
     * )
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
        hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5(""));
        return hashedCredentialsMatcher;
    }

    @Bean
    public MyShiroRealm myShiroRealm(){
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return myShiroRealm;
    }


    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

    /**
     *  开启shiro aop注解支持.
     *  使用代理方式;所以需要开启代码支持;
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    @Bean(name="simpleMappingExceptionResolver")
    public SimpleMappingExceptionResolver
    createSimpleMappingExceptionResolver() {
        SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
        Properties mappings = new Properties();
        mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理
        mappings.setProperty("UnauthorizedException","403");
        r.setExceptionMappings(mappings);  // None by default
        r.setDefaultErrorView("error");    // No default
        r.setExceptionAttribute("ex");     // Default is "exception"
        //r.setWarnLogCategory("example.MvcLogger");     // No default
        return r;
    }

    @Bean
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }

}

8、登录管理

package com.ym.bomaccounting.controller;

import com.ym.bomaccounting.entity.SysUser;
import com.ym.bomaccounting.service.SysMenuService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@Controller
public class IndexController {

    @Autowired
    SysMenuService sysMenuService;

    @RequestMapping("/login")
    public String login(HttpServletRequest request, Map<String, Object> map){
        // 登录失败从request中获取shiro处理的异常信息。
        // shiroLoginFailure:就是shiro异常类的全类名.
        String exception = (String) request.getAttribute("shiroLoginFailure");
        System.out.println("exception=" + exception);
        String msg = "";
        if (exception != null) {
            if (UnknownAccountException.class.getName().equals(exception)) {
                System.out.println("UnknownAccountException -- > 账号不存在:");
                msg = "账号不存在";
            } else if (IncorrectCredentialsException.class.getName().equals(exception)) {
                System.out.println("IncorrectCredentialsException -- > 密码不正确");
                msg = "密码不正确";
            } else if ("kaptchaValidateFailed".equals(exception)) {
                System.out.println("kaptchaValidateFailed -- > 验证码错误");
                msg = "验证码错误";
            } else {
                msg = "其他异常 >> ";
                System.out.println("else -- >" + exception);
            }
        }
        map.put("msg", msg);
        // 此方法不处理登录成功,由shiro进行处理
        return "login";
    }

    @RequestMapping({"/","/home"})
    public String index(HashMap map){
        //获取当前登录用户
        Subject subject = SecurityUtils.getSubject();
        SysUser sysUser = (SysUser) subject.getPrincipal();
        map.put("sysUser",sysUser);
        return "home";
    }

    @RequestMapping("/403")
    public String forbidden(HashMap map){
        return "403";
    }

    @RequestMapping("/logout")
    public String logout(){
        return "login";
    }

}

9、HTML页面

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <div th:replace="base/common :: commonHeader('菜单')"></div>
</head>
<body class="sticky-header">
<section>
    <!-- sidebar left start-->
    <div th:replace="base/common :: sidebarLeft"></div>
    <!-- sidebar left end-->

    <!-- body content start-->
    <div class="body-content" style="min-height: 1000px;">
        <!-- header section start-->
        <div th:replace="base/common :: headerSection"></div>
        <!-- header section end-->

        <!--body wrapper start-->
        <div class="wrapper">
            <div class="row">
                <div class="col-sm-12">
                    <section class="panel">
                        <!--<form  th:action="@{'/user/findUserByCondition'}">
                            <input name="username" class="form-control" id="H_user" type="text"
                                   placeholder="请输入用户名..." />
                            <input type="submit" value="查询" />
                        </form>-->
                        <header class="panel-heading ">
                            菜单列表
                            <span class="tools pull-right">
                                <a class="btn btn-success" data-toggle="modal" data-target="#myModal" href="#myModal">新增</a>
                            </span>
                        </header>
                        <table class="table data-table" style="margin-left: 10px;">
                        <!--<table class="table colvis-data-table data-table">-->
                            <thead>
                            <tr>
                                <!--<th>序号</th>-->
                                <th>名称</th>
                                <th>链接</th>
                                <th>类型</th>
                                <th>权限</th>
                                <th>排序</th>
                                <th>操作</th>
                            </tr>
                            </thead>
                            <tbody>
                            <tr id="tbodyDiv" th:each="var:${datas.content}">
                                <!--<td class="center-block" style="vertical-align: middle">
                                    <label><input type="checkbox" name="ids" th:value="${var.menuId}"/></label>
                                </td>-->
                                <td th:text="${var.name}"></td>
                                <td th:text="${var.url}"></td>
                                <td th:text="${var.resourceType}"></td>
                                <td th:text="${var.permission}"></td>
                                <td th:text="${var.orderNum}"></td>
                                <td>
                                    <a data-toggle="modal" href="#myModal" th:onclick="toEdit([[${var.id}]])" >编辑</a>
                                    <a href="#" th:onclick="del([[${var.id}]])" >删除</a>
                                </td>
                            </tr>
                            </tbody>
                        </table>

                        <div class="pagination pagination-sm pull-right">
                            <div id="page" url="/syspermission/list" ></div>
                            <div th:include="base/page :: pager" th:remove="tag"></div>
                        </div>
                    </section>
                </div>
            </div>
            <!-- Modal -->
            <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
                <div class="modal-dialog">
                    <div class="modal-content">
                        <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                            <h4 class="modal-title">权限编辑</h4>
                        </div>
                        <div class="modal-body">
                            <div class="row">
                                <input type="hidden" id="id">
                                <div class="form-group ">
                                    <label class="control-label col-md-4">上级:</label>
                                    <div class="col-md-8">
                                        <select class="form-control" id="parentId" name="parentId">
                                            <option value="0">顶级</option>
                                            <option th:each="permission,userStat:${permissionList}" th:value="${permission.id}" th:text="${permission.name}"></option>
                                        </select>
                                        <span class="help-block"></span>
                                    </div>
                                </div>
                                <div class="form-group ">
                                    <label class="control-label col-md-4">名称:</label>
                                    <div class="col-md-8">
                                        <input class=" form-control" id="name" name="name" minlength="2" type="text"/>
                                        <span class="help-block"></span>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label class="control-label col-md-4">链接:</label>
                                    <div class="col-md-8">
                                        <input class="form-control " id="url" type="url" name="url" />
                                        <span class="help-block"></span>
                                    </div>
                                </div>
                                <div class="form-group ">
                                    <label class="control-label col-md-4">类型:</label>
                                    <div class="col-md-8">
                                        <select class="form-control" id="resourceType" name="resourceType">
                                            <option value="menu">菜单</option>
                                            <option value="button">按钮</option>
                                        </select>
                                        <span class="help-block"></span>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label class="control-label col-md-4">权限:</label>
                                    <div class="col-md-8">
                                        <input class=" form-control" id="permission" name="permission" minlength="1" type="text" required />
                                        <span class="help-block"></span>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label class="control-label col-md-4">排序:</label>
                                    <div class="col-md-8">
                                        <input class=" form-control" id="orderNum" name="orderNum" minlength="1" type="number" min="0" step="1"/>
                                        <span class="help-block"></span>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="modal-footer">
                            <button class="btn btn-success" type="submit" id="saveBtn">保存</button>
                            <button data-dismiss="modal" class="btn btn-default" type="button" id="cancelBtn">取消</button>
                        </div>
                    </div>
                </div>
            </div>
            <!-- modal -->
        </div>
        <!--body wrapper end-->

        <!--footer section start-->
        <div th:replace="base/common :: commonFooter"></div>
        <!--footer section end-->
    </div>
    <!-- body content end-->
</section>

<script th:inline="javascript">

    $("#saveBtn").click(function () {

        if ($("#parentId").val()==null || $("#parentId").val()==""){
            alert("请选择上级菜单")
            return;
        }
        if ($("#name").val()==null || $("#name").val()==""){
            alert("名称不能为空")
            return;
        }

        $.ajax({
            type: 'POST',
            dataType: "json",
            url: "/syspermission/edit",
            data: {
                "id": $("#id").val(),
                "parentId": $("#parentId").val(),
                "name": $("#name").val(),
                "url": $("#url").val(),
                "resourceType": $("#resourceType").val(),
                "permission": $("#permission").val(),
                "orderNum": $("#orderNum").val()
            },
            success: function (res) {
                if (res.code==0){
                    alert(res.msg);
                } else{
                    $("#cancelBtn").click();
                    window.location.reload();
                }
            }, error: function (res) {
                console.log("error" + res.toString());
            }
        })
    })

    function toEdit(id) {
        console.log(id);
        $("#id").val(id);
        $.ajax({
            type:'POST',
            dataType:"json",
            url:"/syspermission/toEdit",
            data:{
                id:id
            },
            success:function (res) {
                $("#parentId").val(res.bean.parentId);
                $("#name").val(res.bean.name);
                $("#url").val(res.bean.url);
                $("#resourceType").val(res.bean.resourceType);
                $("#permission").val(res.bean.permission);
                $("#orderNum").val(res.bean.orderNum);
            },
            error:function (res) {
                console.log(res.toString());
            }
        })
    }

    function del(id) {

        if(confirm("确实要删除吗?")){
            $.ajax({
                type:'POST',
                dataType:"json",
                url:"/syspermission/deleteById",
                data:{
                    id:id
                },
                success:function (res) {
                    alert(res.msg)
                    window.location.reload();
                },
                error:function (res) {
                    console.log(res.toString());
                }
            })
        }


    }

</script>

</body>
</html>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <div th:replace="base/common :: commonHeader('角色')"></div>
</head>
<body class="sticky-header">
<section>
    <!-- sidebar left start-->
    <div th:replace="base/common :: sidebarLeft"></div>
    <!-- sidebar left end-->

    <!-- body content start-->
    <div class="body-content" style="min-height: 1000px;">
        <!-- header section start-->
        <div th:replace="base/common :: headerSection"></div>
        <!-- header section end-->

        <!--body wrapper start-->
        <div class="wrapper">
            <div class="row">
                <div class="col-sm-12">
                    <section class="panel">

                        <header class="panel-heading ">
                            角色列表
                            <span class="tools pull-right">
                                <a class="btn btn-success m-b-10" data-toggle="modal" href="#myModal" th:onclick="toAdd()">新增</a>
                            </span>
                        </header>
                        <form class="form-inline" style="margin-top: 10px;margin-left: 10px" th:action="@{'/sysrole/list'}">
                            <div class="form-group">
                                <label class="sr-only" for="inputName">Email address</label>
                                <input type="text" class="form-control" id="inputName" name="nameParam" th:value="${nameParam}" placeholder="请输入名称...">
                            </div>
                            <input type="submit" class="btn btn-round btn-success" value="查询" />
                        </form>
                        <table class="table data-table" style="margin-left: 10px;">
                        <!--<table class="table colvis-data-table data-table">-->
                            <thead>
                            <tr>
                                <!--<th>序号</th>-->
                                <th>名称</th>
                                <th>描述</th>
                                <th>创建时间</th>
                                <th>操作</th>
                            </tr>
                            </thead>
                            <tbody>
                            <tr id="tbodyDiv" th:each="var:${datas.content}">
                                <!--<td class="center-block" style="vertical-align: middle">
                                    <label><input type="checkbox" name="ids" th:value="${var.menuId}"/></label>
                                </td>-->
                                <td th:text="${var.role}"></td>
                                <td th:text="${var.description}"></td>
                                <td th:text="${#dates.format(var.createTime, 'yyyy-MM-dd HH:mm:ss')}"></td>
                                <td>
                                    <a data-toggle="modal" href="#myModal" th:onclick="toEdit([[${var.id}]])" >编辑</a>
                                    <a href="#" th:onclick="del([[${var.id}]])" >删除</a>
                                </td>
                            </tr>
                            </tbody>
                        </table>

                        <div class="pagination pagination-sm pull-right">
                            <div id="page" url="/sysrole/list" ></div>
                            <div th:include="base/page :: pager" th:remove="tag"></div>
                        </div>
                    </section>
                </div>
            </div>
            <!-- Modal -->
            <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
                <div class="modal-dialog">
                    <div class="modal-content">
                        <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                            <h4 class="modal-title">用户编辑</h4>
                        </div>
                        <div class="modal-body">
                            <div class="row">
                                <input type="hidden" id="id">
                                <div class="form-group ">
                                    <label class="control-label col-md-4">角色:</label>
                                    <div class="col-md-8">
                                        <input class=" form-control" id="role" name="role" minlength="2" type="text"/>
                                        <span class="help-block"></span>
                                    </div>
                                </div>
                                <div class="form-group ">
                                    <label class="control-label col-md-4">描述:</label>
                                    <div class="col-md-8">
                                        <input class=" form-control" id="description" name="description" minlength="2" type="text"/>
                                        <span class="help-block"></span>
                                    </div>
                                </div>
                                <div class="form-group ">
                                    <label class="control-label col-md-4">权限设置:</label>
                                    <div class="col-md-8">
                                        <div>
                                            <input type="checkbox" class="iCheck-flat-orange" id="checkAll" value="all">
                                            <label class="control-label">全选</label>
                                        </div>
                                        <div th:each="permission:${permissionList}">
                                            <input name="optionName" type="checkbox" class="iCheck-flat-orange" th:value="${permission.id}" th:id="${permission.id}">
                                            <label class="control-label" th:text="${permission.name}"></label>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="modal-footer">
                            <button class="btn btn-success" type="submit" id="saveBtn">保存</button>
                            <button data-dismiss="modal" class="btn btn-default" type="button" id="cancelBtn">取消</button>
                        </div>
                    </div>
                </div>
            </div>
            <!-- modal -->
        </div>
        <!--body wrapper end-->

        <!--footer section start-->
        <div th:replace="base/common :: commonFooter"></div>
        <!--footer section end-->
    </div>
    <!-- body content end-->
</section>

<script th:inline="javascript">

    $("#saveBtn").click(function () {
        if ($("#role").val()==null || $("#role").val()==""){
            alert("角色不能为空")
            return;
        }
        //获取选中权限
        var checkBoxArr = [];
        $('input[name="optionName"]:checked').each(function() {
            checkBoxArr.push($(this).val());
        });
        $.ajax({
            type: 'POST',
            dataType: "json",
            url: "/sysrole/edit",
            data: {
                "id": $("#id").val(),
                "role": $("#role").val(),
                "description": $("#description").val(),
                "permissionString":JSON.stringify(checkBoxArr)
            },
            success: function (res) {
                if (res.code==0){
                    alert(res.msg);
                } else{
                    $("#cancelBtn").click();
                    window.location.reload();
                }
            }, error: function (res) {
                console.log("error" + res.toString());
            }
        })
    })

    function toAdd() {
        $("#id").val("");
        $("#role").val("");
        $("#description").val("");
    }

    function toEdit(id) {
        console.log(id);
        $("#userId").val(id);
        $.ajax({
            type:'POST',
            dataType:"json",
            url:"/sysrole/toEdit",
            data:{
                id:id
            },
            success:function (res) {
                $("#id").val(res.bean.id);
                $("#role").val(res.bean.role);
                $("#description").val(res.bean.description);
                var permissions = res.permissions;
                var permissionList = [[${permissionList}]];

                //取消全选
                $("input[name='optionName']").iCheck("uncheck");
                //找选中的权限
                var newArray = [];
                for (var i=0;i<permissionList.length;i++){
                    for (var j=0;j<permissions.length;j++){
                        if (permissions[j].id==permissionList[i].id){
                            newArray.push(permissionList[i]);
                        }
                    }
                }
                //初始化选中
                for (var i=0;i<newArray.length;i++){
                    $("#"+newArray[i].id).iCheck("check");
                }
            },
            error:function (res) {
                console.log(res.toString());
            }
        })
    }

    function del(id) {

        if(confirm("确实要删除吗?")){
            $.ajax({
                type:'POST',
                dataType:"json",
                url:"/sysrole/deleteById",
                data:{
                    id:id
                },
                success:function (res) {
                    alert(res.msg)
                    window.location.reload();
                },
                error:function (res) {
                    console.log(res.toString());
                }
            })
        }
    }

    //实现全选反选
/*    $("#checkAll").on('click', function() {
        $("input[name='optionName']").prop("checked", $(this).prop('checked'));
    })
    $("input[name='optionName']").on('click', function() {
        //当选中的长度等于checkbox的长度的时候,就让控制全选反选的checkbox设置为选中,否则就为未选中
        if($("input[name='optionName']").length === $("input[name='optionName']").length) {
            $("#checkAll").prop("checked", true);
        } else {
            $("#checkAll").prop("checked", false);
        }
    })*/

    $('#checkAll').on('ifChecked', function(event){
        $("input[name='optionName']").iCheck("check");
    });
    $('#checkAll').on('ifUnchecked', function(event){
        $("input[name='optionName']").iCheck("uncheck");
    });
</script>

</body>
</html>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <div th:replace="base/common :: commonHeader('用户')"></div>
</head>
<body class="sticky-header">
<section>
    <!-- sidebar left start-->
    <div th:replace="base/common :: sidebarLeft"></div>
    <!-- sidebar left end-->

    <!-- body content start-->
    <div class="body-content" style="min-height: 1000px;">
        <!-- header section start-->
        <div th:replace="base/common :: headerSection"></div>
        <!-- header section end-->

        <!--body wrapper start-->
        <div class="wrapper">
            <div class="row">
                <div class="col-sm-12">
                    <section class="panel">

                        <header class="panel-heading ">
                            用户列表
                            <span class="tools pull-right">
                                <a class="btn btn-success m-b-10" data-toggle="modal" href="#myModal" th:onclick="toAdd()">新增</a>
                            </span>
                        </header>
                        <form class="form-inline" style="margin-top: 10px;margin-left: 10px" th:action="@{'/sysuser/list'}">
                            <div class="form-group">
                                <label class="sr-only" for="inputName">Email address</label>
                                <input type="text" class="form-control" id="inputName" name="nameParam" th:value="${nameParam}" placeholder="请输入名称...">
                            </div>
                            <input type="submit" class="btn btn-round btn-success" value="查询" />
                        </form>
                        <table class="table data-table" style="margin-left: 10px;">
                        <!--<table class="table colvis-data-table data-table">-->
                            <thead>
                            <tr>
                                <!--<th>序号</th>-->
                                <th>用户名</th>
                                <th>昵称</th>
                                <th>创建时间</th>
                                <th>操作</th>
                            </tr>
                            </thead>
                            <tbody>
                            <tr id="tbodyDiv" th:each="var:${datas.content}">
                                <!--<td class="center-block" style="vertical-align: middle">
                                    <label><input type="checkbox" name="ids" th:value="${var.menuId}"/></label>
                                </td>-->
                                <td th:text="${var.username}"></td>
                                <td th:text="${var.nickName}"></td>
                                <td th:text="${#dates.format(var.createTime, 'yyyy-MM-dd HH:mm:ss')}"></td>
                                <td>
                                    <a data-toggle="modal" href="#myModal" th:onclick="toEdit([[${var.userId}]])" >编辑</a>
                                    <a href="#" th:onclick="del([[${var.userId}]])" >删除</a>
                                </td>
                            </tr>
                            </tbody>
                        </table>

                        <div class="pagination pagination-sm pull-right">
                            <div id="page" url="/sysuser/list" ></div>
                            <div th:include="base/page :: pager" th:remove="tag"></div>
                        </div>
                    </section>
                </div>
            </div>
            <!-- Modal -->
            <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
                <div class="modal-dialog">
                    <div class="modal-content">
                        <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                            <h4 class="modal-title">用户编辑</h4>
                        </div>
                        <div class="modal-body">
                            <div class="row">
                                <input type="hidden" id="userId">
                                <div class="form-group ">
                                    <label class="control-label col-md-4">用户名:</label>
                                    <div class="col-md-8">
                                        <input class=" form-control" id="username" name="username" minlength="2" type="text"/>
                                        <span class="help-block"></span>
                                    </div>
                                </div>
                                <div class="form-group ">
                                    <label class="control-label col-md-4">昵称:</label>
                                    <div class="col-md-8">
                                        <input class=" form-control" id="nick" name="nickName" minlength="2" type="text"/>
                                        <span class="help-block"></span>
                                    </div>
                                </div>
                                <div class="form-group ">
                                    <label class="control-label col-md-4">密码:</label>
                                    <div class="col-md-8">
                                        <input class=" form-control" id="password" name="password" minlength="2" type="password"/>
                                        <span class="help-block"></span>
                                    </div>
                                </div>
                                <div class="form-group">
                                    <label class="col-md-4 control-label">角色:</label>
                                    <div class="col-md-8">
                                        <select id="multiple" class="form-control select2-multiple" multiple>
                                            <option th:each="role,roleStat:${roleList}" th:value="${role.id}" th:text="${role.role}"></option>
                                        </select>
                                    </div>
                                </div>
                                <!--<div class="form-group">
                                    <label class="col-md-4 control-label">是否工厂人员:</label>
                                    <div class="col-md-8">
                                            <input type="radio" id="iCheckTrue" name="iCheck" class="iCheck-flat-orange" th:value="true">
                                            <label class="control-label">是</label>

                                            <input type="radio" id="iCheckFalse" name="iCheck" class="iCheck-flat-orange" th:value="false" checked>
                                            <label class="control-label">否</label>

                                    </div>
                                </div>-->

                            </div>
                        </div>
                        <div class="modal-footer">
                            <button class="btn btn-success" type="submit" id="saveBtn">保存</button>
                            <button data-dismiss="modal" class="btn btn-default" type="button" id="cancelBtn">取消</button>
                        </div>
                    </div>
                </div>
            </div>
            <!-- modal -->
        </div>
        <!--body wrapper end-->

        <!--footer section start-->
        <div th:replace="base/common :: commonFooter"></div>
        <!--footer section end-->
    </div>
    <!-- body content end-->
</section>

<script th:inline="javascript">

    $("#saveBtn").click(function () {
        if ($("#username").val()==null || $("#username").val()==""){
            alert("用户名不能为空")
            return;
        }
        if ($("#nick").val()==null || $("#nick").val()==""){
            alert("昵称不能为空")
            return;
        }
        if ($("#password").val()==null || $("#password").val()==""){
            alert("密码不能为空")
            return;
        }

        //获取选中角色
        var roleList = $("#multiple").val();
        if (null==roleList || roleList.length==0){
            alert("请选择角色")
            return;
        }

        // var ifFactory = $('input[name="iCheck"]:checked').val();

        $.ajax({
            type: 'POST',
            dataType: "json",
            url: "/sysuser/edit",
            data: {
                "userId": $("#userId").val(),
                "username": $("#username").val(),
                "nickName": $("#nick").val(),
                "password": $("#password").val(),
                "roleIdString":JSON.stringify(roleList)
            },
            success: function (res) {
                if (res.code==0){
                    alert(res.msg);
                } else{
                    $("#cancelBtn").click();
                    window.location.reload();
                }
            }, error: function (res) {
                console.log("error" + res.toString());
            }
        })
    })

    function toAdd() {
        $("#userId").val("");
        $("#username").val("");
        $("#nick").val("");
        $("#password").val("");
    }

    function toEdit(id) {
        console.log(id);
        $("#userId").val(id);
        $.ajax({
            type:'POST',
            dataType:"json",
            url:"/sysuser/toEdit",
            data:{
                id:id
            },
            success:function (res) {
                $("#userId").val(res.bean.userId);
                $("#username").val(res.bean.username);
                $("#nick").val(res.bean.nickName);
                $("#password").val(res.bean.password);
                /*if (res.bean.ifFactory==true){
                    $("#iCheckTrue").iCheck("check");
                }
                if (res.bean.ifFactory==false){
                    $("#iCheckFalse").iCheck("check");
                }*/
                var roleList = res.bean.roleList;
                var array = new Array;
                for (var i=0;i<roleList.length;i++){
                    array.push(roleList[i].id);
                }
                $("#multiple").select2();
                $("#multiple").val(array).trigger("change")
            },
            error:function (res) {
                console.log(res.toString());
            }
        })
    }

    function del(id) {

        if(confirm("确实要删除吗?BOM可能在用!")){
            $.ajax({
                type:'POST',
                dataType:"json",
                url:"/sysuser/deleteById",
                data:{
                    id:id
                },
                success:function (res) {
                    alert(res.msg)
                    window.location.reload();
                },
                error:function (res) {
                    console.log(res.toString());
                }
            })
        }


    }

</script>

</body>
</html>

<div th:replace="base/common :: sidebarLeft"></div>

代表引入base路径下的common.html中  th:fragment="sidebarLeft" 的div

可以根据需求进行修改

html中有些参数表达式会报红,是因为IDEA自动检测语法默认不支持,不影响项目运行。

看着不舒服的解决办法:file--settings--Editor--Inspections--右侧找到Thymeleaf,第三个右面的√去掉就可以了。

有些表达式还是会报错,不用在意

项目github地址:shiro权限管理demo

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值