Human resource management system of Web project

Posted by stuartbaggs on Fri, 21 Jan 2022 20:43:25 +0100

Project Gitee

address

Blog address

Project requirements

Human resource management system positioning

  • The realized human resource management system serves shareholders, employees and interns.
  • By realizing the functions of each module, the company's personnel joining, internal transfer and resignation personnel change are carried out through a systematic method, and auxiliary management is provided for these personnel movements.
  • To ensure that the right people in the right positions can complete all tasks efficiently and effectively.

User rights and authentication

  • The function of this module is to register users and assign permissions, connect the database and shiro to realize user security, and realize user permission grouping combined with thymeleaf shiro.
  • JS designs the password length of login to judge whether the user name format is correct.
  • After successful login, jump to the home page, or select registration. After successful registration, jump to login.
  • Users with different permissions can view different pages and have different operation permissions.

Department management

  • In the front end, you need to draw a tree view. When you click a node, all employees under its corresponding department will be displayed.
  • Here, the tree view is drawn through the fuel ux Library of the template.
  • Get the json string from the back end in the front end as the data source for drawing the tree view, convert it into js object with its parse function in js, and define the callback function during rendering.
  • When clicking a node, call a jumptoDepartment function to automatically jump to the corresponding department personnel display page according to the clicked node.
  • In the back end, a tree is established to represent the subordinate relationship between departments. A List is used in each node to store the information of sub departments, and its corresponding functions are provided to the front end.

Salary management

  • Employee information statistics:
    Including basic salary, Department, cumulative overtime hours per month, monthly attendance and leave, etc; And realize the query function, employee information addition function, deletion function, paging function, fuzzy query function and paging query function.
  • Salary details:
    Calculate the employee's bonus, impose a fine and tax amount, and finally settle the salary; And realize the query function, delete function, paging function, fuzzy query function and paging query function.

Attendance management

  • The function of this module is to view the attendance status of employees
  • The attendance status of employees is divided into: 1: attendance, 2: leave, 3: business trip, 4: overtime, 5: compensatory leave, 6: shift adjustment, 7: shutdown.
  • While displaying the status, the page also displays the employee's ID, name, start and end time of the status, and adds comments.
  • Add the modification function at the end of each employee table row. Click Modify to jump to the modification page to modify the employee's attendance status, time and comments.
  • In addition, the filtering function is added to view employees in this status by selecting attendance status.

Personnel handling

  • This module implements the transfer management module, including employee enrollment, employment confirmation, job transfer, salary adjustment, resignation, reinstatement and other businesses.

Publish deploy to server

  • The project is finally packaged (jar) and published to the server.

Project design

Login registration

Department management

Salary management

Attendance management

Personnel handling

Database design

Userall

nametypelengthdecimal pointNot null
uservarchar25501key
passwordvarchar25501
saltvarchar25500

UserPer (user rights)

nametypelengthdecimal pointNot null
uservarchar25501key
permsvarchar25500

department

nametypelengthdecimal pointNot null
departmentvarchar25501
d_idint25501key
paridint25500

Employees (all employees)

nametypelengthdecimal pointNot null
idint1101key
namevarchar25501
ageint1101
sexvarchar201
phonevarchar25500
emailvarchar25500
dNamevarchar25501
pNamevarchar25501
gNamevarchar25501
flagbit101

gangwei (post)

nametypelengthdecimal pointNot null
namevarchar25500
g_idint25501key

kaoqin (attendance)

nametypelengthdecimal pointNot null
idint1101key
namevarchar25500
typeint1101
startdate000
enddate001
remarkvarchar25500

position

nametypelengthdecimal pointNot null
positionvarchar25501
p_idint25501key
levelint25500

Salary (salary)

nametypelengthdecimal pointNot null
timevarchar25500
gidint1101key
pidint1101
usernamevarchar25500
basicSalaryint1101
dnamevarchar25500
workovertimeint1101
checkaccoutint1101

Project core code

detailed design

Login and registration

@RequestMapping(value = "/index", method = RequestMethod.GET)  
    public String indexPage(String username, String password, Map<String, Object> map, HttpSession session, HttpServletRequest request, Model model) {  
        /** 
         * Write the operation of authentication using shiro 
         */  
        //1. Get Subject  
        Subject subject = SecurityUtils.getSubject();  
        //2. Encapsulate user data  
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);  
        try {  
//3. Execute login method  
            subject.login(token);  
            model.addAttribute("username", username);  
            session.setAttribute("username", username);  
            return "index";  
        } catch (UnknownAccountException e) {  
            //Login failed, wrong user name  
            model.addAttribute("msg", "User name does not exist!");  
            return "login";  
        } catch (IncorrectCredentialsException e) {  
            //Login failed, password error  
            model.addAttribute("msg", "Wrong user name or password!");  
            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", "repeat of user name");  
            return "reg";  
        }  
        try {  
            Integer id = Integer.parseInt(username);  
            boolean flag = userCheckServiceImpl.insert(username, password);  
            if (flag) {  
                //Set user permissions  
  
                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", "The user name does not conform to the number format");  
            return "reg";  
        }  
}  
/** 
     * Execute authentication logic 
     * 
     * @param authenticationToken 
     * @return 
     * @throws AuthenticationException 
     */  
    @Override  
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {  
        System.out.println("Perform certification: Authentiction");  
  
        //Assume the user name and password of the database  
        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();  
       //encryption  
       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">Sign in</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">Please enter 4~10 Bit cipher</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 = 'Password length error, expected 4~10 position';  
                        message.className = 'message wrong';  
  
                    } else {  
                        message.innerHTML = 'The password length is correct';  
                        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">  
                    register  
                </a>  
            </div>  
        </div>  
    </form>  
</div>  

<div class="login-wrap">  
  
            <input type="text" autofocus="" placeholder="Enter number, intern please enter 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">Please enter 4~10 Bit cipher</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 = 'Password length error, expected 4~10 position';  
                        message.className = 'message wrong';  
  
                    } else {  
                        message.innerHTML = 'The password length is correct';  
                        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>  

Department management

Controller layer

Service layer

@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));
        }
    }
    // Get all employees under this node
    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();
        // Gets all values under the node
        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) + "]"
                + "}";
    }
    // Get root node
    @Override
    public departmentTree getRoot() {
        return new departmentTree(departmentMapper, 0);
    }
    // Get JSON
    @Override
    public String getJSON() {
        // JSONObject JSON = new JSONObject();
        return "[" + getJSONByNode(new departmentTree(departmentMapper, 0)) + "]";
    }
    // Find all employees in a department according to their id
    @Override
    public ArrayList<Employees> getEmployeeById(int id) {
        return (new departmentTree(departmentMapper, id)).getAllEmployee(employeesMapper);
    }
}

Mapper layer

@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); // Find the IDs of all child nodes through the parent node  
    @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);  
} 

Front end 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"/>'
            });
        }
    };
}();
Front end management jump function:
<script>
    function jumpToDepartment() {
        var dmpid = ($('#DepartmentTree').tree('selectedItems')[0]).id;
        window.location.href = "/index/department/" + dmpid;
    }
</script>
HTML Receive backend incoming json character string:
<input type="hidden" id="dataTreeSrc" th:value="${treeDataSrc}">

Salary management

Controller layer

@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 layer

List<Salary> getSalary();

int salary_delete(Integer id);

List<Salary> findUserByName(String username);

void add(Salary salary);

int update(Salary salary);

Mapper layer

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

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

 /*
     Query user information
  */
 @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);

Attendance management

Controller layer

@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){  
        //For the sake of the preciseness of the procedure, judge whether it is not empty:  
        //Set default current page  
        if(pageNum==null || pageNum<=0){  
        pageNum = 1;  
        }  
        //Sets the default number of data displayed per page  
        if(pageSize == null){  
        pageSize = 1;  
        }  
        // System.out.println("current page is:" + pageNum + "display number is:" + PageSize ");  
  
        //1. Introduce the paging plug-in. pageNum is the page number, pageSize is the number of items displayed on each page, and the default total number of queries is count  
        PageHelper.startPage(pageNum,pageSize);  
        //2. The following query is a paging query - it must be followed Other subsequent queries will not be paged unless PageHelper is called again startPage  
        List<Kaoqin> kaoqins = kaoqinServiceImpl.kaoqinList();  
        //3. Use PageInfo to wrap the query results. 5 is the number of continuously displayed items, and the result list type is page < E >  
        PageInfo<Kaoqin> pageInfo = new PageInfo<Kaoqin>(kaoqins,pageSize);  
        //4. Use model to send parameters back to the front end  
        model.addAttribute("pageInfo",pageInfo);  
        model.addAttribute("kaoqins",kaoqins);  
        return "kaoqin_table";  
        }  
//Find by attendance type  
@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";  
        }  
//Update attendance content according to id  
@GetMapping("/update/{id}")  
public String update(Model model, @PathVariable int id){  
        Kaoqin kaoqin = kaoqinServiceImpl.findKaoqinById(id);  
        model.addAttribute("kaoqin",kaoqin);  
        return "updateKaoqin";  
        }  
//Update attendance  
@PostMapping("/update")  
public String updateKaoqin(Kaoqin kaoqin){  
        kaoqinServiceImpl.updateKaoqin(kaoqin);  
        return "redirect:/index/employee_table2";  
        }  

Service layer

@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 layer

@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);  

Personnel handling

Controller layer

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 layer

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 layer

@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);

User rights grouping

shiroConfiguration

@Configuration  
public class ShiroConfiguration {  
    /** 
     * LifecycleBeanPostProcessor,This is a subclass of DestructionAwareBeanPostProcessor, 
     * Responsible for org apache. shiro. util. Initializable type bean's life cycle, initialization and destruction. 
     * It is mainly a subclass of the AuthorizingRealm class and the EhCacheManager class. 
     */  
    @Bean(name = "lifecycleBeanPostProcessor")  
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {  
        return new LifecycleBeanPostProcessor();  
    }  
  
    /** 
     * HashedCredentialsMatcher,This class is used to encode passwords, 
     * Prevent the password from being saved in the database. Of course, when logging in for authentication, 
     * This class is also responsible for encoding the password entered in the form. 
     */  
    @Bean  
    public HashedCredentialsMatcher hashedCredentialsMatcher() {  
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();  
        hashedCredentialsMatcher.setHashAlgorithmName("md5");  
        return hashedCredentialsMatcher;  
    }  
    /** 
     * ShiroRealm,This is a user-defined authentication class, which inherits from authoringrealm, 
    * Responsible for user authentication and authority processing, you can refer to the implementation of JdbcRealm. 
     */  
    @Bean(name = "shiroRealm")  
    @DependsOn("lifecycleBeanPostProcessor")  
    public ShiroRealm shiroRealm() {  
        ShiroRealm realm = new ShiroRealm();  
        realm.setCredentialsMatcher(hashedCredentialsMatcher());  
        return realm;  
    }  
    /** 
     * SecurityManager,Permission management, which combines login, logout, permission and session processing, is an important class. 
     * // 
     */  
    @Bean(name = "securityManager")  
    public DefaultWebSecurityManager securityManager() {  
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();  
        securityManager.setRealm(shiroRealm());  
        return securityManager;  
    }  
  
    /** 
     * ShiroFilterFactoryBean,It is a factorybean to generate ShiroFilter. 
     * It mainly maintains three data items: securityManager, filters and 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>();  
        //Sign in  
        // Add shiro's built-in filter  
        /** 
         * anon: Access without authentication 
         * authc: Must be authenticated to access 
         * user: You must have the remember me function to use 
         * perms: You must have permission on a resource to access it 
         * role: Only with the permission of a role can you access 
         */  
        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 The Advisor decides which class methods to AOP proxy.  
     */  
    @Bean  
    @ConditionalOnMissingBean  
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {  
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();  
        defaultAAP.setProxyTargetClass(true);  
        return defaultAAP;  
    }  
    /** 
     * AuthorizationAttributeSourceAdvisor,shiro Advisor class implemented in, 
     * AOP alliance annotations authoring method interceptor is used internally to intercept methods annotated below. 
     */  
    @Bean  
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {  
        AuthorizationAttributeSourceAdvisor aASA = new AuthorizationAttributeSourceAdvisor();  
        aASA.setSecurityManager(securityManager());  
        return aASA;  
    }  
    /** 
     * Configure shiroDialect for thymeleaf and 
     * @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("Execution authorization: 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;  
    }  
  
    /** 
     * Execute authentication logic 
     * 
     * @param authenticationToken 
     * @return 
     * @throws AuthenticationException 
     */  
    @Override  
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {  
        System.out.println("Perform certification: Authentiction");  
  
        //Assume the user name and password of the database  
        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 > personnel archiving < / span ></a>  
      <ul class="sub-menu-list">  
      <li class="active"><a href="/index/employee_table">Personnel filing</a></li>  
      <li class="active" shiro:hasAnyPermissions="boss,deputy,fudeputy">
		<a  href="/index/addStu">Employee induction</a>
      </li>  
      <li class="active" shiro:hasAnyPermissions="boss,deputy,fudeputy">
			<a  href="/index/delStu">Employee turnover</a>
      </li>  
    </ul>  
</li> 

Project deployment

Deployment URL

Topics: Javascript Front-end Spring Boot