Web项目之人力资源管理系统

项目Gitee

地址

博客地址

项目需求

人力资源管理系统定位

  • 实现的人力资源管理系统面向股东,员工以及实习生服务。
  • 通过实现各模块功能,通过系统的方法进行公司的人员的加入,内部调动及离职人员变动,并为这些人员流动提供辅助管理。
  • 以确保在适当的职位上又各种适当的人才能够既有效率又有效能地完成各项任务。

用户权限与认证

  • 本模块实现的功能是用户的注册以及权限的分配,连接数据库和shiro实现用户安全,结合thymeleaf-shiro实现用户权限分组。
  • JS设计登录的密码长度判断,用户名格式是否正确。
  • 登陆成功跳转到主页,或者选择注册,注册成功后,跳转到登录。
  • 不同权限用户可查看的页面不同,操作权限也不同。

部门管理

  • 前端方面,需要画树状图,在点击结点的时候,显示其对应部门下的所有员工。
  • 在这里,树状图的绘制通过模板的fuel ux库完成。
  • 在前端中得到从后端传来的json字符串作为画树状图的数据源,在js中用其parse函数转换为js对象,并定义渲染时的回调函数。
  • 在点击结点的时候,调用一个jumptoDepartment函数,根据点击的节点自动跳转到相应的部门人员显示页面。
  • 后端方面,建立一颗树用来表示部门之间的从属关系,每个结点中用一个List储存子部门的各个信息,同时给前端提供其相应的函数。

薪资管理

  • 员工信息统计:
    包括基础工资,所属部门,每月加班时长累计,每月考勤请假情况等;并且实现查询功能,员工信息添加功能,删除功能,分页功能,模糊查询功能,分页查询功能。
  • 薪资明细表:
    算出员工的奖金,处罚金,纳税金额,最后结算工资;并且实现查询功能,删除功能,分页功能,模糊查询功能,分页查询功能。

考勤管理

  • 本模块实现的功能是查看员工的考勤状况
  • 将员工的考勤状态分为:1:出勤,2:请假,3:出差,4:加班,5:补休,6:调班,7:停工。
  • 页面在显示状态的同时也显示出员工的ID,姓名,状态的开始和结束时间,并添加备注。
  • 在每个员工表格行的末尾添加修改功能,点击修改跳转到修改页面,可以修改该员工考勤状态、时间和备注。
  • 另外增加了筛选功能,可以通过选择考勤状况查看处于该状态的员工。

人事处理

  • 此模块实现调动管理管理模块,包括职员入职、转正、调岗、调薪、离职、复职等业务。

发布部署到服务器

  • 项目最终打包(jar)发布到服务器。

项目设计

登录注册

在这里插入图片描述

部门管理

在这里插入图片描述

薪资管理

在这里插入图片描述

考勤管理

在这里插入图片描述

人事处理

在这里插入图片描述

数据库设计

Userall(用户)

类型长度小数点不是null
uservarchar25501key
passwordvarchar25501
saltvarchar25500

UserPer(用户权限)

类型长度小数点不是null
uservarchar25501key
permsvarchar25500

department(部门)

类型长度小数点不是null
departmentvarchar25501
d_idint25501key
paridint25500

employees(职员【所有】)

类型长度小数点不是null
idint1101key
namevarchar25501
ageint1101
sexvarchar201
phonevarchar25500
emailvarchar25500
dNamevarchar25501
pNamevarchar25501
gNamevarchar25501
flagbit101

gangwei(岗位)

类型长度小数点不是null
namevarchar25500
g_idint25501key

kaoqin(考勤)

类型长度小数点不是null
idint1101key
namevarchar25500
typeint1101
startdate000
enddate001
remarkvarchar25500

position(职位)

类型长度小数点不是null
positionvarchar25501
p_idint25501key
levelint25500

salary(薪资)

类型长度小数点不是null
timevarchar25500
gidint1101key
pidint1101
usernamevarchar25500
basicSalaryint1101
dnamevarchar25500
workovertimeint1101
checkaccoutint1101

项目核心代码

详细设计

登录与注册

@RequestMapping(value = "/index", method = RequestMethod.GET)  
    public String indexPage(String username, String password, Map<String, Object> map, HttpSession session, HttpServletRequest request, Model model) {  
        /** 
         * 使用shiro编写认证的操作 
         */  
        //1.获取Subject  
        Subject subject = SecurityUtils.getSubject();  
        //2.封装用户数据  
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);  
        try {  
//3.执行登录方法  
            subject.login(token);  
            model.addAttribute("username", username);  
            session.setAttribute("username", username);  
            return "index";  
        } catch (UnknownAccountException e) {  
            //登录失败,用户名错误  
            model.addAttribute("msg", "用户名不存在!");  
            return "login";  
        } catch (IncorrectCredentialsException e) {  
            //登录失败,密码错误  
            model.addAttribute("msg", "用户名或密码错误!");  
            return "login";  
        }  
}
@RequestMapping(value = "/login")  
    public String regPageToLogin(String username, String password, Map<String, Object> map, HttpSession session, Model model) {  
  
        Userall userall = new Userall(username, password);  
        if (username == null || password == null) {  
            return "reg";  
        }  
        if (password.length() < 4 || password.length() > 10) {  
            return "reg";  
        }  
        Userall userall1 = userCheckServiceImpl.selectByKeyName(username);  
        if (userall1 != null) {  
            map.put("error", "用户名重复");  
            return "reg";  
        }  
        try {  
            Integer id = Integer.parseInt(username);  
            boolean flag = userCheckServiceImpl.insert(username, password);  
            if (flag) {  
                //设置用户权限  
  
                String role = employServiceImpl.getRole(Integer.parseInt(username));  
  
                userCheckServiceImpl.insertUserPer(username, role);  
                return "login";  
            } else {  
                Userall usercheck = userCheckServiceImpl.selectByNameAndPassword(username, password);  
                if (usercheck == null) {  
                    return "reg";  
                } else {  
                    return "login";  
                }  
            }  
        } catch (Exception e) {  
            map.put("error", "用户名不符合数字格式");  
            return "reg";  
        }  
}  
/** 
     * 执行认证逻辑 
     * 
     * @param authenticationToken 
     * @return 
     * @throws AuthenticationException 
     */  
    @Override  
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {  
        System.out.println("执行认证:Authentiction");  
  
        //假设数据库的用户名和密码  
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;  
  
        Userall user = userCheckService.selectByKeyName(token.getUsername());  
        String DBPassword = user.getPassword();  
        String Salt = user.getSalt();  
        System.out.println(Salt);  
        return new SimpleAuthenticationInfo(user,DBPassword, ByteSource.Util.bytes(Salt),"");  
}  
@Override  
   public boolean insert(String username, String password) {  
       String Salt = new SecureRandomNumberGenerator().nextBytes().toHex();  
       //加密  
       SimpleHash simpleHash = new SimpleHash("md5",password,Salt,1);  
       String NewPassword = simpleHash.toString();  
       //System.out.println(password);  
       userallMapper.insert(username,NewPassword,Salt);  
       return true;  
   }  	
<div class="container">  
  
    <form class="form-signin" action="/index" id = "signForm">  
        <div class="form-signin-heading text-center">  
            <h1 class="sign-title">登录</h1>  
            <img src="../static/images/login-top.png" alt=""/>  
        </div>  
        <div class="login-wrap">  
            <input type="text" class="form-control" placeholder="User ID" autofocus name="username" id = "username" required="required">  
            <input type="password" class="form-control" placeholder="Password" name="password" id = "password" required="required"><p class="message">请输入4~10位密码</p>  
            <script>  
                var password = document.querySelector('.form-control');  
                var message = document.querySelector('.message');  
  
               password.onblur = function() {  
                    if (this.value.length < 4 || this.value.length > 10) {  
                        message.innerHTML = '密码长度错误,应为4~10位';  
                        message.className = 'message wrong';  
  
                    } else {  
                        message.innerHTML = '密码长度正确';  
                        message.className = 'message right';  
                    }  
                }  
            </script>  
            <button class="btn btn-lg btn-login btn-block" type="submit" onclick="mycheck()" >  
                <i class="fa fa-check"></i>  
            </button>  
            <div class="registration">  
                <a class="" href="/reg">  
                    注册  
                </a>  
            </div>  
        </div>  
    </form>  
</div>  

<div class="login-wrap">  
  
            <input type="text" autofocus="" placeholder="输入编号,实习生请输入0" class="form-control" name="username" required="required" id="username">  
            <input type="password" autofocus="" placeholder="password" class="form-control" name="password" required="required" id="password"><p class="message">请输入4~10位密码</p>  
            <p th:text="${error}" color="red"></p>  
            <script>  
                var password = document.querySelector('.form-control');  
                var message = document.querySelector('.message');  
  
                password.onblur = function() {  
                    if (this.value.length < 4 || this.value.length > 10) {  
                        message.innerHTML = '密码长度错误,应为4~10位';  
                        message.className = 'message wrong';  
  
                    } else {  
                        message.innerHTML = '密码长度正确';  
                        message.className = 'message right';  
                    }  
                }  
            </script>  
            <button type="submit" class="btn btn-lg btn-login btn-block" onclick="mycheck()">  
                <i class="fa fa-check"></i>  
            </button>  
            <div class="registration">  
                Already Registered.  
                <a href="login.html" class="">  
                    Login  
                </a>  
          </div>  
</div>  

部门管理

Controller层

Service层

@Service
    public class departmentTree {
    private Department department;
    private List<departmentTree> children;
    departmentTree() {
    }
    departmentTree(DepartmentMapper departmentMapper, int id) {

        department = departmentMapper.getById(id);
        department.setdId(id);
        children = new ArrayList<departmentTree>();
        for (int childrenId : departmentMapper.geIdtByParId(id)) {
            children.add(new departmentTree(departmentMapper, childrenId));
        }
    }
    // 获取该节点下所有的员工
    ArrayList<Employees> getAllEmployee(EmployeesMapper employeesMapper) {
        ArrayList<Employees> ans = employeesMapper.getBydName(department.getDepartment());
        for (departmentTree tmp : children) {
            ans.addAll(tmp.getAllEmployee(employeesMapper));
        }
        return ans;
    }
    Department getDepartment() {
        return department;
    }
    public List<departmentTree> getChildren() {
        return children;
    }
}

@Service
public class departmentTool implements departmantToolService {
    @Autowired
    DepartmentMapper departmentMapper;
    @Autowired
    EmployeesMapper employeesMapper;
    private String getJSONByNode(departmentTree node) {
        JSONObject JSON = new JSONObject();
        // 获取该节点之下的所有值
        String ch = null;
        for (departmentTree son : node.getChildren()) {
            if (ch == null)
                ch = getJSONByNode(son);
            else
                ch = ch + "," + getJSONByNode(son);
        }
        return "{" + "\"name\": \"" + node.getDepartment().getDepartment()
                + "\" ,\"type\": \"" + (node.getChildren().size() != 0 ? "folder" : "item")
                + "\" ,\"id\": " + node.getDepartment().getdId()
                + " ,\"children\": " + "[" + (ch == null ? "" : ch) + "]"
                + "}";
    }
    // 获取根节点
    @Override
    public departmentTree getRoot() {
        return new departmentTree(departmentMapper, 0);
    }
    // 获取JSON
    @Override
    public String getJSON() {
        // JSONObject JSON = new JSONObject();
        return "[" + getJSONByNode(new departmentTree(departmentMapper, 0)) + "]";
    }
    // 根据id寻找某个部门下所有的员工
    @Override
    public ArrayList<Employees> getEmployeeById(int id) {
        return (new departmentTree(departmentMapper, id)).getAllEmployee(employeesMapper);
    }
}

Mapper层

@Mapper  
public interface DepartmentMapper {  
    int deleteByPrimaryKey(Integer dId);  
    int insert(Department record);  
    int insertSelective(Department record);  
    Department selectByPrimaryKey(Integer dId);  
    int updateByPrimaryKeySelective(Department record);  
    int updateByPrimaryKey(Department record);  
    @Select("select * from department where d_id = #{id} ")  
    Department getById(int id);  
    @Select("select d_id from department where parid = #{id} ")  
    List<Integer> geIdtByParId(int id); // 通过父节点找到所有子节点的id  
    @Select("select * from department")  
List<Department> getAll();  
}  
@Mapper  
public interface EmployeesMapper {  
    int deleteByPrimaryKey(Integer id);  
    int insert(Employees record);  
    int insertSelective(Employees record);  
    Employees selectByPrimaryKey(Integer id);  
    int updateByPrimaryKeySelective(Employees record);  
    int updateByPrimaryKey(Employees record);  
    @Select("select * from employees")  
    List<Employees> getAll();  
    @Select("select * from employees where dName = #{dName} ")  
    ArrayList<Employees> getBydName(String dName);  
} 

前端HTML&JS

var DMPTree = function () {
    return {
        //main function to initiate the module
        init: function () {
            var DataSourceTree = function (options) {
                this._data  = options.data;
                this._delay = options.delay;
            };
            DataSourceTree.prototype = {
                data: function (options, callback) {
                    var nodes;
                    if($.isEmptyObject(options)) {
                        nodes = this._data;
                    }
                    else {
                        if(options.children == null || options.children == undefined) {
                            nodes = {};
                        }
                        else {
                            nodes = options.children;
                        }
                    }
                    setTimeout(function () {
                        callback({ data: nodes });
                    }, this._delay)
                }
            };
            var treeDataSourceDynamicStr = $("#dataTreeSrc").val();
            var treeDataSourceDynamic = JSON.parse(treeDataSourceDynamicStr);
            var deparmentTreeSrc = new DataSourceTree({
                data: treeDataSourceDynamic,
                delay: 400
            });
            $('#DepartmentTree').tree({
                dataSource: deparmentTreeSrc,
                loadingHTML: '<img src="../static/images/input-spinner.gif"/>'
            });
        }
    };
}();
前端管理跳转函数:
<script>
    function jumpToDepartment() {
        var dmpid = ($('#DepartmentTree').tree('selectedItems')[0]).id;
        window.location.href = "/index/department/" + dmpid;
    }
</script>
HTML接收后端传入json字符串:
<input type="hidden" id="dataTreeSrc" th:value="${treeDataSrc}">

薪资管理

Controller层

@RequestMapping("/index/salary_search")
    public String salary_select(Model model,String username,
                                @RequestParam(required = false,defaultValue="1",value="pageNum")Integer pageNum,
                                @RequestParam(defaultValue="5",value="pageSize")Integer pageSize){

        if(pageNum==null || pageNum<=0){
            pageNum = 1;
        }
        if(pageSize == null){
            pageSize = 1;
        }
        PageHelper.startPage(pageNum,pageSize);
        try {
            List<Salary> users=salaryServiceImpl.findUserByName(username);
            PageInfo<Salary> pageInfo = new PageInfo<Salary>(users,pageSize);
            model.addAttribute("pageInfo",pageInfo);
            model.addAttribute("salary",users);
            model.addAttribute("username",username);
        }finally {
        }
        return "salary_search";
@GetMapping("/index/salary_delete/{id}")
    public String salary_delete(@PathVariable Integer id){
        salaryServiceImpl.salary_delete(id);
        return "redirect:/index/salary";
    }
@RequestMapping("/index/salary_insert")
    public String insertPage(){
        return "salary_insert";
    }

    @RequestMapping("/index/salaryBack")
    public String insert(Salary salary) {
        salaryServiceImpl.add(salary);
        return "redirect:/index/salary_control";
    }

Service层

List<Salary> getSalary();

int salary_delete(Integer id);

List<Salary> findUserByName(String username);

void add(Salary salary);

int update(Salary salary);

Mapper层

@Select("select * from salary")
 List<Salary> getSalary();

 @Select("select * from kaoqin")
 List<Salary> getKaqqinInformation();
 /*
     删除用户
*/
 @Delete("delete from salary\n" +
         "    where gid = #{gid,jdbcType=INTEGER}")
 int salary_delete(Integer gid);

 /*
     查询用户信息
  */
 @Select("select * from salary where username like CONCAT('%',#{name},'%')")
 List<Salary> findUserByName(String username);

 @Insert("insert into salary (`time`, pid, username, \n" +
         "      basicSalary, dname, workovertime, \n" +
         "      checkaccount)\n" +
         "    values (#{time,jdbcType=VARCHAR}, #{pid,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, \n" +
         "      #{basicsalary,jdbcType=INTEGER}, #{dname,jdbcType=VARCHAR}, #{workovertime,jdbcType=INTEGER}, \n" +
         "      #{checkaccount,jdbcType=INTEGER})")
 void add(Salary user);

考勤管理

Controller层

@RequestMapping("/index/employee_table2")  
public  String KaoqinList(Model model,  
@RequestParam(required = false,defaultValue="1",value="pageNum")Integer pageNum,  
@RequestParam(defaultValue="10",value="pageSize")Integer pageSize){  
        //为了程序的严谨性,判断非空:  
        //设置默认当前页  
        if(pageNum==null || pageNum<=0){  
        pageNum = 1;  
        }  
        //设置默认每页显示的数据数  
        if(pageSize == null){  
        pageSize = 1;  
        }  
        // System.out.println("当前页是:"+pageNum+"显示条数是:"+pageSize);  
  
        //1.引入分页插件,pageNum是第几页,pageSize是每页显示多少条,默认查询总数count  
        PageHelper.startPage(pageNum,pageSize);  
        //2.紧跟的查询就是一个分页查询-必须紧跟.后面的其他查询不会被分页,除非再次调用PageHelper.startPage  
        List<Kaoqin> kaoqins = kaoqinServiceImpl.kaoqinList();  
        //3.使用PageInfo包装查询后的结果,5是连续显示的条数,结果list类型是Page<E>  
        PageInfo<Kaoqin> pageInfo = new PageInfo<Kaoqin>(kaoqins,pageSize);  
        //4.使用model传参数回前端  
        model.addAttribute("pageInfo",pageInfo);  
        model.addAttribute("kaoqins",kaoqins);  
        return "kaoqin_table";  
        }  
//根据考勤类型查找  
@RequestMapping("/find")  
public String find(Integer type, Model model){  
        List<Kaoqin> kaoqins =  kaoqinServiceImpl.findKaoqin(type);  
        model.addAttribute("kaoqins",kaoqins);  
        System.out.println(type);  
        return "kaoqin_table";  
        }  
//根据id更新考勤内容  
@GetMapping("/update/{id}")  
public String update(Model model, @PathVariable int id){  
        Kaoqin kaoqin = kaoqinServiceImpl.findKaoqinById(id);  
        model.addAttribute("kaoqin",kaoqin);  
        return "updateKaoqin";  
        }  
//更新考勤  
@PostMapping("/update")  
public String updateKaoqin(Kaoqin kaoqin){  
        kaoqinServiceImpl.updateKaoqin(kaoqin);  
        return "redirect:/index/employee_table2";  
        }  

Service层

@Autowired  
KaoqinMapper kaoqinMapper;  
@Override  
public List<Kaoqin> kaoqinList(){  
    return kaoqinMapper.kaoqinList();  
}  
@Override  
public List<Kaoqin> findKaoqin(Integer type){  
    return kaoqinMapper.findKaoqin(type);  
}  
@Override  
public Kaoqin findKaoqinById(int id){  
    return kaoqinMapper.findKaoqinById(id);  
}  
@Override  
public int updateKaoqin(Kaoqin kaoqin){  
    return kaoqinMapper.updateKaoqin(kaoqin);  
}  
List<Kaoqin> kaoqinList();  
List<Kaoqin> findKaoqin(Integer type);  
Kaoqin findKaoqinById(int id);   
int updateKaoqin(Kaoqin kaoqin);  

Mapper层

@Select("select * from kaoqin")  
List<Kaoqin> kaoqinList();  
@Select("select * from kaoqin where type = #{type}")  
List<Kaoqin> findKaoqin(Integer type);  
@Select("select * from kaoqin where id = #{id}")  
Kaoqin findKaoqinById(int id);  
@Update("update kaoqin set type = #{type}, start = #{start}, end = #{end}, remark = #{remark} where id = #{id}")  
int updateKaoqin(Kaoqin kaoqin);  

人事处理

Controller层

public String employeeListPage(Model model, @RequestParam(defaultValue = "1") Integer pageNum) {
        PageHelper.startPage(pageNum, 5);
        List<Employees> list = employServiceImpl.getAll();
        PageInfo<Employees> pageInfo = new PageInfo<Employees>(list);
        model.addAttribute("pageInfo", pageInfo);
        model.addAttribute("employee", list);
        return "employee_table";
    }
    @RequestMapping(value = "/index/addEmployee")
    public String addStus(String name,int age,String sex,
                          String dname,String pname,String gname,boolean flag,int id,String email,String phone,
                          @RequestParam(defaultValue = "1") Integer pageNum,
                          Model model) {
        Employees employees = new Employees(name,age,sex,dname,pname,gname,email,phone,id,flag);
        try {
            employServiceImpl.addEmployees(employees);
        }catch (Exception e){
            return "addStu";
        }
        return "index";
    }
    @RequestMapping(value = "/index/delEmployee")
    public String delEmployee(String name,int age,String sex,
                             String dname,String pname,String gname,boolean flag,int id,String email,String phone) {

        Employees employees = new Employees(name,age,sex,dname,pname,gname,email,phone,id,flag);
        employServiceImpl.delEmployees(employees);
        return "delSuccess";
    }

Sevice层

EmployeesMapper employeesMapper;
    @Override
    public void addEmployees(Employees employees) {
         employeesMapper.save(employees);
    }
    @Override
    public void delEmployees(Employees employees) {
        employeesMapper.delete(employees);
    }
    @Override
    public List<Employees> getAll() {
        return employeesMapper.getAll();
    }

Mapper层

@Select("select * from employees")
List<Employees> getAll();
@Delete("DELETE from employees where name = #{name} and age = #{age} and sex = #{sex} and id = #{id} ")
void delete(Employees employee);
@Insert("INSERT INTO employees VALUES(#{id},#{name},#{age},#{sex},#{phone},#{email},#{dname},#{pname},#{gname},#{flag})")
void save(Employees employee);

用户权限分组

shiroConfiguration

@Configuration  
public class ShiroConfiguration {  
    /** 
     * LifecycleBeanPostProcessor,这是个DestructionAwareBeanPostProcessor的子类, 
     * 负责org.apache.shiro.util.Initializable类型bean的生命周期的,初始化和销毁。 
     * 主要是AuthorizingRealm类的子类,以及EhCacheManager类。 
     */  
    @Bean(name = "lifecycleBeanPostProcessor")  
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {  
        return new LifecycleBeanPostProcessor();  
    }  
  
    /** 
     * HashedCredentialsMatcher,这个类是为了对密码进行编码的, 
     * 防止密码在数据库里明码保存,当然在登陆认证的时候, 
     * 这个类也负责对form里输入的密码进行编码。 
     */  
    @Bean  
    public HashedCredentialsMatcher hashedCredentialsMatcher() {  
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();  
        hashedCredentialsMatcher.setHashAlgorithmName("md5");  
        return hashedCredentialsMatcher;  
    }  
    /** 
     * ShiroRealm,这是个自定义的认证类,继承自AuthorizingRealm, 
    * 负责用户的认证和权限的处理,可以参考JdbcRealm的实现。 
     */  
    @Bean(name = "shiroRealm")  
    @DependsOn("lifecycleBeanPostProcessor")  
    public ShiroRealm shiroRealm() {  
        ShiroRealm realm = new ShiroRealm();  
        realm.setCredentialsMatcher(hashedCredentialsMatcher());  
        return realm;  
    }  
    /** 
     * SecurityManager,权限管理,这个类组合了登陆,登出,权限,session的处理,是个比较重要的类。 
     * // 
     */  
    @Bean(name = "securityManager")  
    public DefaultWebSecurityManager securityManager() {  
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();  
        securityManager.setRealm(shiroRealm());  
        return securityManager;  
    }  
  
    /** 
     * ShiroFilterFactoryBean,是个factorybean,为了生成ShiroFilter。 
     * 它主要保持了三项数据,securityManager,filters,filterChainDefinitionManager。 
     */  
    @Bean(name = "shiroFilter")  
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {  
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();  
        shiroFilterFactoryBean.setSecurityManager(securityManager());  
  
        Map<String, Filter> filters = new LinkedHashMap<String, Filter>();  
        LogoutFilter logoutFilter = new LogoutFilter();  
        logoutFilter.setRedirectUrl("/login");  
        shiroFilterFactoryBean.setFilters(filters);  
  
        Map<String, String> filterChainDefinitionManager = new LinkedHashMap<String, String>();  
        //登录  
        // 添加shiro的内置过滤器  
        /** 
         * anon:无需认证就可以访问 
         * authc:必须认证了才能访问 
         * user:必须拥有记住我功能才能用 
         * perms:拥有对某个资源的权限才能访问 
         * role:拥有某个角色的权限才能访问 
         */  
        filterChainDefinitionManager.put("/login","anon");  
        filterChainDefinitionManager.put("/logout", "anon");  
        filterChainDefinitionManager.put("/index","anon");  
        filterChainDefinitionManager.put("/index/**", "authc");  
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionManager);  
  
        shiroFilterFactoryBean.setLoginUrl("/");  
        shiroFilterFactoryBean.setSuccessUrl("/index");  
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");  
        return shiroFilterFactoryBean;  
    }  
  
    /**  
     * DefaultAdvisorAutoProxyCreator,Spring的一个bean,由Advisor决定对哪些类的方法进行AOP代理。  
     */  
    @Bean  
    @ConditionalOnMissingBean  
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {  
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();  
        defaultAAP.setProxyTargetClass(true);  
        return defaultAAP;  
    }  
    /** 
     * AuthorizationAttributeSourceAdvisor,shiro里实现的Advisor类, 
     * 内部使用AopAllianceAnnotationsAuthorizingMethodInterceptor来拦截用以下注解的方法。 
     */  
    @Bean  
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {  
        AuthorizationAttributeSourceAdvisor aASA = new AuthorizationAttributeSourceAdvisor();  
        aASA.setSecurityManager(securityManager());  
        return aASA;  
    }  
    /** 
     * 配置 shiroDialect 用于thymeleaf和 
     * @return 
     */  
    @Bean  
    public ShiroDialect getShiroDialect() {  
        return new ShiroDialect();  
    }  
}  

shiroRealm

public class ShiroRealm extends AuthorizingRealm {  
    @Autowired  
    userCheckServiceImpl userCheckService;  
  
  
    @Override  
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {  
        System.out.println("执行授权:Authorization");  
  
  
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();  
  
  
        Subject subject = SecurityUtils.getSubject();  
        Userall userall = (Userall)subject.getPrincipal();  
        String role = userCheckService.getUserPer(userall.getUser());  
        System.out.println(role);  
        info.addStringPermission(role);  
  
        return info;  
    }  
  
    /** 
     * 执行认证逻辑 
     * 
     * @param authenticationToken 
     * @return 
     * @throws AuthenticationException 
     */  
    @Override  
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {  
        System.out.println("执行认证:Authentiction");  
  
        //假设数据库的用户名和密码  
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;  
  
        Userall user = userCheckService.selectByKeyName(token.getUsername());  
       String DBPassword = user.getPassword();  
        String Salt = user.getSalt();  
        System.out.println(Salt);  
        return new SimpleAuthenticationInfo(user,DBPassword, ByteSource.Util.bytes(Salt),"");  
    }  
}  

thymeleaf+shiro

<li class="menu-list nav-active" shiro:hasAnyPermissions="boss,deputy,fudeputy,staff">
      <a href="#"><i  class="fa fa-th-list"></i> <span>人事归档</span></a>  
      <ul class="sub-menu-list">  
      <li class="active"><a href="/index/employee_table">人事归档</a></li>  
      <li class="active" shiro:hasAnyPermissions="boss,deputy,fudeputy">
		<a  href="/index/addStu">员工入职</a>
      </li>  
      <li class="active" shiro:hasAnyPermissions="boss,deputy,fudeputy">
			<a  href="/index/delStu">员工离职</a>
      </li>  
    </ul>  
</li> 

项目部署

部署网址

  • 4
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高明爱圣子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值