0.8

0.8

Practical Training Defense (2)

Student Information Management System#

System Function Description#

Student Information Management System is a system developed based on the B/S model. The system includes three roles: students, teachers, and administrators, and also allows for custom user addition. Under the administrator's authority, the permission allocation feature enables precise management of user permissions, ensuring the security of the Student Information Management System to a certain extent.

Students#

  • Students can view relevant information about classmates (passwords and other privacy factors are encrypted, non-administrator users do not have the right to view), can modify their own information, delete their records, and add a new personal information record about themselves.

    image-20230607144747923

  • Students can view the teacher team and relevant classes, understanding which classes are being taught and which teachers are teaching them.

    image-20230607144804949

Teachers#

  • Teachers can view relevant information about class students and can perform CRUD operations (including modifying login passwords, etc.) on class student information, which can optimize students' login experience to a certain extent.

    image-20230607145207165

  • Teachers can view the teaching situation of their colleagues and their corresponding teaching classes, and gain some understanding of their colleagues' relevant information.

    image-20230607145514877

  • Teachers can query historical operation records, which can trace back to a certain extent, improving the stability and security of the system.

    image-20230607145634278

Super Administrator#

  • The super administrator has all the functions of teachers and students, and on this basis, the super administrator also has the menu management function, supporting vertical browsing of the entire management system in the form of a Tree, facilitating system maintenance.

image-20230607145812395

  • The super administrator can manage the dictionary, and through the backend management system, the administrator can understand dictionary identifiers, dictionary types, dictionary values, creation time, update time, etc., supporting CRUD operations.

image-20230607150051720

  • This project supports secondary development. If the administrator has certain needs, they can perform secondary development on this system through the Development Center module.

    image-20230607150159203

System Function Module Diagram#

img

System Database Design#

sys_action_log.sql#

Records the operation logs of the management system.

image-20230607150621161

sys_dept.sql#

Used to store department management related data.

image-20230607150722949

sys_dict.sql#

Used to store menu management related data.

image-20230607150840705

sys_file.sql#

Used to store uploaded avatar related data.

image-20230607150919947

sys_menu.sql#

Used to store system menu related data.

image-20230607150954229

sys_role.sql#

Used to store system role related data.

image-20230607151042959

sys_role_menu.sql#

Used to store system role id related data.

image-20230607151135548

sys_user.sql#

Used to store system user related data.

image-20230607151209710

sys_user_role.sql#

Used to store system user id related data.

image-20230607151245779

Specific Implementation of the System#

Overall Function Module Diagram#

image-20230607151523622

Login Module#

H5 Page Diagram#

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
    <title>TIMO Login</title>
    <link rel="stylesheet" type="text/css" th:href="@{/css/login.css}">
</head>
<body class="layui-layout-login">
<div class="login-bg">
    <div class="cover"></div>
</div>
<div class="login-content" th:th:classappend="${isCaptcha} ? 'captcha'">
    <h1 class="login-box-title"><i class="fa fa-fw fa-user"></i>Login</h1>
    <form class="layui-form" th:action="@{/login}" method="post">
        <div class="layui-form-item">
            <label class="layui-icon layui-icon-username" for="username"></label>
            <input class="layui-input" type="text" name="username" id="username" placeholder="Username">
        </div>
        <div class="layui-form-item">
            <label class="layui-icon layui-icon-password" for="password"></label>
            <input class="layui-input" type="password" name="password" id="password" placeholder="Password">
        </div>
        <div th:if="${isCaptcha}" class="layui-form-item captcha-item">
            <label class="layui-icon layui-icon-vercode"></label>
            <input class="layui-input" type="text" name="captcha" autocomplete="off" placeholder="Captcha">
            <img class="captcha-img" th:src="@{/captcha}" />
        </div>
        <div class="layui-form-item">
            <input type="checkbox" name="rememberMe" title="Remember Me" lay-skin="primary">
            <a class="layui-layout-right forget-password" href="javascript:alert('Please contact the super administrator!')">Forgot Password?</a>
        </div>
        <button type="submit" class="layui-btn layui-btn-fluid ajax-login"><i class="fa fa-sign-in fa-lg fa-fw"></i> Login</button>
    </form>
    <div class="layui-layer-loading login-page-loading"><div class="layui-layer-content"></div></div>
</div>
<script th:replace="/common/template :: script"></script>
<script th:src="@{/js/login.js}" charset="utf-8"></script>
</body>
</html>

JS Core Code#

if(window.top!==window.self){window.top.location=window.location};
layui.use(['element'], function () {
    var $ = layui.jquery;
    $(document).on('click', '.captcha-img', function () {
        var src = this.src.split("?")[0];
        this.src = src + "?" + Math.random();
    });
    $(document).on('click', '.ajax-login', function (e) {
        e.preventDefault();
        var form = $(this).parents("form");
        var url = form.attr("action");
        var serializeArray = form.serializeArray();
        $.post(url, serializeArray, function (result) {
            if(result.code !== 200){
                $('.captcha-img').click();
            }
            $.fn.Messager(result);
        });
    });
    $('.layui-layer-loading').hide();
});

CSS Stylesheet#

@charset "UTF-8";
.layui-layout-login .login-bg{
    background-color: #e7e7e7;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: -1;
}
.layui-layout-login .login-bg .cover{
    background-color: #009688;
    height: 50%;
}
.layui-layout-login .login-content{
    width:250px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform:translate(-50%,-50%);
    background-color: #ffffff;
    padding: 40px;
    padding-top: 32px;
    -webkit-box-shadow: 0px 3px 20px 3px rgba(0, 0, 0, 0.15);
    box-shadow: 0px 3px 20px 3px rgba(0, 0, 0, 0.15);
}
.layui-layout-login .login-content.captcha{
    width:300px;
    padding-bottom: 38px;
}
.layui-layout-login .login-content.captcha .captcha-item .layui-icon{
    font-size: 16px;
}
.layui-layout-login .login-content.captcha .captcha-item .layui-input{
    float: left;
    width: 180px;
}
.layui-layout-login .login-content.captcha .captcha-item .captcha-img{
    float: right;
    height: 38px;
    cursor: pointer;
}
.layui-layout-login .login-box-title{
    font-size: 26px;
    margin-bottom: 20px;
    text-align: center;
    color: #444444;
}
.layui-layout-login .layui-form-item{
    position: relative;
    margin-bottom: 20px;
    min-height: 18px;
}
.layui-layout-login .layui-form-item label{
    position: absolute;
    top:0;
    left: 0;
    font-size: 18px;
    width: 38px;
    line-height: 38px;
    text-align: center;
    color: #999999;
}
.layui-layout-login .layui-form-item input[type=text],
.layui-layout-login .layui-form-item input[type=password]{
    padding-left: 36px;
    border: 1px solid #ddd;
    transition: all 0s;
    -webkit-transition: all 0s;
}
.layui-layout-login .layui-form-item .layui-form-checkbox{
    margin-top: 0;
}
.layui-layout-login .layui-form-item .layui-form-checkbox .layui-icon{
    width: 14px;
    height: 14px;
    top: 1px;
    line-height: 14px;
}
.layui-layout-login .layui-form-item .layui-form-checkbox[lay-skin=primary]:hover i {
    border-color: #009688;
}
.layui-layout-login .layui-form-item .layui-form-checked[lay-skin=primary] i{
    border-color: #009688;
    background-color: #009688;
}
.layui-layout-login .layui-form-item .forget-password{
    color: #009688;
}
.layui-layout-login .login-page-loading {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 0!important;
    background-color: rgba(255, 255, 255, 0.3)!important;
}

Business Code#

package com.linln.admin.system.controller;

import com.linln.common.config.properties.ProjectProperties;
import com.linln.common.data.URL;
import com.linln.common.enums.ResultEnum;
import com.linln.common.exception.ResultException;
import com.linln.common.utils.CaptchaUtil;
import com.linln.common.utils.ResultVoUtil;
import com.linln.common.utils.SpringContextUtil;
import com.linln.common.vo.ResultVo;
import com.linln.component.actionLog.action.UserAction;
import com.linln.component.actionLog.annotation.ActionLog;
import com.linln.component.shiro.ShiroUtil;
import com.linln.modules.system.domain.User;
import com.linln.modules.system.service.RoleService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Lazy Worm
 * @date 2018/8/14
 */
@Controller
public class LoginController implements ErrorController {

    @Autowired
    private RoleService roleService;

    /**
     * Redirect to login page
     */
    @GetMapping("/login")
    public String toLogin(Model model) {
        ProjectProperties properties = SpringContextUtil.getBean(ProjectProperties.class);
        model.addAttribute("isCaptcha", properties.isCaptchaOpen());
        return "/login";
    }

    /**
     * Implement login
     */
    @PostMapping("/login")
    @ResponseBody
    @ActionLog(key = UserAction.USER_LOGIN, action = UserAction.class)
    public ResultVo login(String username, String password, String captcha, String rememberMe) {
        // Check if username and password are empty
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            throw new ResultException(ResultEnum.USER_NAME_PWD_NULL);
        }

        // Check if captcha is correct
        ProjectProperties properties = SpringContextUtil.getBean(ProjectProperties.class);
        if (properties.isCaptchaOpen()) {
            Session session = SecurityUtils.getSubject().getSession();
            String sessionCaptcha = (String) session.getAttribute("captcha");
            if (StringUtils.isEmpty(captcha) || StringUtils.isEmpty(sessionCaptcha)
                    || !captcha.toUpperCase().equals(sessionCaptcha.toUpperCase())) {
                throw new ResultException(ResultEnum.USER_CAPTCHA_ERROR);
            }
            session.removeAttribute("captcha");
        }

        // 1. Get Subject object
        Subject subject = SecurityUtils.getSubject();

        // 2. Encapsulate user data
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);

        // 3. Execute login, enter custom Realm class
        try {
            // Check if auto-login is enabled
            if (rememberMe != null) {
                token.setRememberMe(true);
            } else {
                token.setRememberMe(false);
            }
            subject.login(token);

            // Check if the user has backend role
            User user = ShiroUtil.getSubject();
            if (roleService.existsUserOk(user.getId())) {
                return ResultVoUtil.success("Login successful", new URL("/"));
            } else {
                SecurityUtils.getSubject().logout();
                return ResultVoUtil.error("You are not a backend administrator!");
            }
        } catch (LockedAccountException e) {
            return ResultVoUtil.error("This account has been frozen");
        } catch (AuthenticationException e) {
            return ResultVoUtil.error("Username or password is incorrect");
        }
    }

    /**
     * Captcha image
     */
    @GetMapping("/captcha")
    public void captcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // Set response headers to notify the browser not to cache
        response.setHeader("Expires", "-1");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "-1");
        response.setContentType("image/jpeg");

        // Get captcha
        String code = CaptchaUtil.getRandomCode();
        // Store captcha in session for verification
        request.getSession().setAttribute("captcha", code);
        // Output to web page
        ImageIO.write(CaptchaUtil.genCaptcha(code), "jpg", response.getOutputStream());
    }

    /**
     * Logout
     */
    @GetMapping("/logout")
    public String logout() {
        SecurityUtils.getSubject().logout();
        return "redirect:/login";
    }

    /**
     * Insufficient permissions page
     */
    @GetMapping("/noAuth")
    public String noAuth() {
        return "/system/main/noAuth";
    }

    /**
     * Handle error page
     */
    @RequestMapping("${server.error.path:${error.path:/error}}")
    public String handleError(Model model, HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        String errorMsg = "It seems something went wrong!";
        if (statusCode == 404) {
            errorMsg = "The page cannot be found! It seems to have gone to Mars~";
        }

        model.addAttribute("statusCode", statusCode);
        model.addAttribute("msg", errorMsg);
        return "/system/main/error";
    }
}

Running Screenshots#

image-20230607151835654

image-20230607151851037

User Module#

Definition#

The user module includes administrator login, student login, and teacher login functions. Different users select different identities to log into the system and enjoy different permissions. At the same time, passwords and other information are encrypted, and non-administrators cannot view other users' information. The permission allocation feature enables precise management of user permissions, ensuring the security of the student information management system to a certain extent. Students can view relevant information about classmates (passwords and other privacy factors are encrypted, non-administrator users do not have the right to view), can modify their own information, delete their records, and add a new personal information record about themselves.

Function Introduction#

The user module of the student management system refers to the module used to manage user accounts and permissions in the system, mainly including the following functions:

  1. User Registration: New users can create accounts in the system through the registration function, filling in required information such as username, password, etc. At the same time, they can fill in other personal information such as name, contact information, etc. as needed.
  2. User Login: Registered users can enter the system through the login function, using their account and password for identity verification. After successful login, users can use other functions in the system.
  3. User Information Management: Logged-in users can view and modify their personal information, such as modifying contact information, etc.
  4. Permission Management: System administrators can set permissions for different users, including operation permissions and data access permissions, etc. Administrators can set different permission levels as needed to ensure the security and confidentiality of the system.
  5. User Query: Logged-in users can use the query function provided by the system to query their personal information and related records, such as grade queries, course selection records, etc.
  6. User Logout: Logged-in users can exit the system through the logout function to protect their account security.

Core Code (Implementation Class)#

package com.linln.modules.system.domain;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.linln.common.enums.StatusEnum;
import com.linln.common.utils.StatusUtil;
import com.linln.component.excel.annotation.Excel;
import com.linln.component.excel.enums.ExcelType;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

@Data
@Entity
@Table(name = "sys_user")
@ToString(exclude = {"dept", "roles"})
@EqualsAndHashCode(exclude = {"dept", "roles"})
@EntityListeners(AuditingEntityListener.class)
@SQLDelete(sql = "update sys_user" + StatusUtil.SLICE_DELETE)
@Where(clause = StatusUtil.NOT_DELETE)
@Excel("User Data")
public class User implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Excel(value = "User ID", type = ExcelType.EXPORT)
    private Long id;
    @Excel("Username")
    private String username;
    @JsonIgnore
    private String password;
    @JsonIgnore
    private String salt;
    @Excel("Nickname")
    private String nickname;
    private String picture;
    @Excel(value = "Gender", dict = "USER_SEX")
    private Byte sex;
    @Excel("Phone Number")
    private String phone;
    @Excel("Email")
    private String email;
    @CreatedDate
    @Excel("Creation Time")
    private Date createDate;
    @LastModifiedDate
    @Excel("Update Time")
    private Date updateDate;
    @Excel("Remarks")
    private String remark;
    @Excel(value = "Status", dict = "DATA_STATUS")
    private Byte status = StatusEnum.OK.getCode();

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "dept_id")
    @JsonIgnore
    private Dept dept;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "sys_user_role",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id"))
    @JsonIgnore
    private Set<Role> roles = new HashSet<>(0);
}

Core Code (Interface)#

package com.linln.modules.system.repository;

import com.linln.modules.system.domain.Dept;
import com.linln.modules.system.domain.User;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

import java.util.List;

public interface UserRepository extends BaseRepository<User, Long>, JpaSpecificationExecutor<User> {

    /**
     * Query user data by username
     * @param username Username
     * @return User data
     */
    public User findByUsername(String username);

    /**
     * Query user data by username, excluding specified ID
     * @param username Username
     * @param id Excluded user ID
     * @return User data
     */
    public User findByUsernameAndIdNot(String username, Long id);

    /**
     * Find user list for multiple corresponding departments
     * @param dept Department object
     * @return User list
     */
    public List<User> findByDept(Dept dept);

    /**
     * Delete multiple records
     * @param ids ID list
     * @return Affected rows
     */
    public Integer deleteByIdIn(List<Long> ids);
}

Running Screenshots#

image-20230608085049154

Menu Module#

Definition#

The menu module of the student management system refers to the menu bar provided in the system, which facilitates users to browse and use various functional modules in the system.

Functions#

  1. Menu Item Classification: Various functional modules in the system can be classified according to different categories, such as student information management, teacher information management, course management, grade management, etc., making it easier for users to find and use.
  2. Menu Item Sorting: Menu items in the system can be sorted according to user usage frequency or importance, allowing users to find the functions they need more easily.
  3. Menu Item Expansion: The system can provide menu item expansion and collapse functions. When there are too many menu items under a certain category, some menu items can be collapsed to reduce the user's visual burden.
  4. Menu Item Icons: Menu items in the system can have icons added to facilitate users to identify functions based on icons, improving user experience.
  5. Menu Item Permission Control: For different users, the display and availability of menu items in the system may vary, and need to be controlled according to user permissions to ensure the security and confidentiality of the system.
  6. Menu Item Search: When there are too many menu items in the system, users can use the menu item search function to search for the required functional modules by entering keywords or names, improving user efficiency.
  7. Menu Item Shortcuts: For frequently used functional modules, the system can set shortcuts for them, allowing users to quickly enter the corresponding functional modules through keyboard operations, improving user efficiency.
  8. Menu Item Customization: Menu items in the system can be customized according to user needs, allowing users to add frequently used menu items to a shortcut menu for quick access.
  9. Menu Item Internationalization: For some internationalized student management systems, menu items can automatically switch according to the user's language environment, improving convenience and user experience for cross-national use.
  10. Menu Item Grouping: For some large student management systems, menu items can be classified according to different groups, such as student management, teacher management, course management, etc., to facilitate user management and use.
  11. Menu Item Expansion: When the student management system needs to add new functional modules, the menu module can provide expansion functions, allowing administrators to easily add new menu items and functional modules.

Core Code (Implementation Class)#

package com.linln.modules.system.domain;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.linln.common.enums.StatusEnum;
import com.linln.common.utils.StatusUtil;
import lombok.*;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import org.hibernate.annotations.Where;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;
import java.io.Serializable;
import java.util.*;

@Data
@Entity
@Table(name = "sys_menu")
@ToString(exclude = {"roles", "createBy", "updateBy"})
@EqualsAndHashCode(exclude = {"roles", "createBy", "updateBy"})
@EntityListeners(AuditingEntityListener.class)
@Where(clause = StatusUtil.NOT_DELETE)
public class Menu implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private Long pid;
    private String pids;
    private String title;
    private String url;
    private String perms;
    private String icon;
    private Byte type;
    private Integer sort;
    private String remark;
    @CreatedDate
    private Date createDate;
    @LastModifiedDate
    private Date updateDate;
    @CreatedBy
    @ManyToOne(fetch = FetchType.LAZY)
    @NotFound(action = NotFoundAction.IGNORE)
    @JoinColumn(name = "create_by")
    @JsonIgnore
    private User createBy;
    @LastModifiedBy
    @ManyToOne(fetch = FetchType.LAZY)
    @NotFound(action = NotFoundAction.IGNORE)
    @JoinColumn(name = "update_by")
    @JsonIgnore
    private User updateBy;
    private Byte status = StatusEnum.OK.getCode();

    @ManyToMany(mappedBy = "menus")
    @JsonIgnore
    private Set<Role> roles = new HashSet<>(0);

    @Transient
    @JsonIgnore
    private Map<Long, Menu> children = new HashMap<>();

    public Menu(){

    }

    public Menu(Long id, String title, String pids) {
        this.id = id;
        this.title = title;
        this.pids = pids;
    }

    public void setPids(String pids) {
        if (pids.startsWith(",")){
            pids = pids.substring(1);
        }
        this.pids = pids;
    }
}

Core Code (Interface)#

package com.linln.modules.system.repository;

import com.linln.common.constant.StatusConst;
import com.linln.modules.system.domain.Menu;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

public interface MenuRepository extends BaseRepository<Menu, Long> {

    /**
     * Find multiple menus
     * @param ids ID list
     * @return Menu list
     */
    public List<Menu> findByIdIn(List<Long> ids);

    /**
     * Find menus with corresponding status
     * @param sort Sort object
     * @param status Data status
     * @return Menu list
     */
    public List<Menu> findAllByStatus(Sort sort, Byte status);

    /**
     * Query menu URL
     * @param url ID list
     * @return Menu information
     */
    public Menu findByUrl(String url);

    /**
     * Find child menus by parent ID
     * @param pids PID list
     * @param status Data status
     * @return Menu list
     */
    public List<Menu> findByPidsLikeAndStatus(String pids, Byte status);

    /**
     * Get maximum sort value
     * @param pid Parent menu ID
     * @return Maximum value
     */
    @Query("select max(sort) from Menu m where m.pid = ?1 and m.status <> " + StatusConst.DELETE)
    public Integer findSortMax(long pid);

    /**
     * Get all menus at this level by parent menu ID
     * @param sort Sort object
     * @param pid Parent menu ID
     * @param notId Menu ID to exclude
     * @return Menu list
     */
    public List<Menu> findByPidAndIdNot(Sort sort, long pid, long notId);

    /**
     * Cancel the relationship between menu and role
     * @param id Menu ID
     * @return Affected rows
     */
    @Modifying
    @Transactional
    @Query(value = "DELETE FROM sys_role_menu WHERE menu_id = ?1", nativeQuery = true)
    public Integer cancelRoleJoin(Long id);
}

Running Screenshots#

image-20230608085516770

Department Module#

Definition#

The department module of the student management system refers to the module used to manage department information in the system.

Functions#

  1. Department Information Maintenance: System administrators can add, edit, and delete department information through the department module, including department name, description, person in charge, etc.
  2. Department Personnel Management: Administrators can add, edit, and delete department personnel information in the department module, including name, position, contact information, etc. At the same time, administrators can assign one or more personnel to one or more departments.
  3. Department Permission Management: Administrators can set corresponding permissions for each department through the department module, including access permissions and operation permissions, etc. This ensures data security and isolation between departments.
  4. Department Data Query: Logged-in users can use the query function provided by the department module to query information and related records of their own department, such as department personnel information, project progress, etc.
  5. Department Report Generation: Through the department module, administrators can generate reports related to the department, such as personnel structure reports, project progress reports, etc. These reports can help administrators better understand and manage the department's situation.
  6. Department Collaboration: Through the department module, different departments can collaborate, such as sharing files, exchanging information, and cooperating on projects, to improve work efficiency and collaborative capabilities.
  7. Department Log Recording: Through the department module, the system can record operation logs related to the department, including adding, editing, and deleting department information, to help administrators understand the operation history of the department and trace issues.

Core Code (Implementation Class)#

package com.linln.modules.system.domain;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.linln.common.enums.StatusEnum;
import com.linln.common.utils.StatusUtil;
import lombok.Data;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import org.hibernate.annotations.Where;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

@Data
@Entity
@Table(name = "sys_dept")
@EntityListeners(AuditingEntityListener.class)
@Where(clause = StatusUtil.NOT_DELETE)
public class Dept implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /** Department Name */
    private String title;

    /** Parent ID */
    private Long pid;

    /** All Parent IDs */
    private String pids;

    /** Sort Order */
    private Integer sort;

    /** Remarks */
    private String remark;

    /** Creation Time */
    @CreatedDate
    private Date createDate;

    /** Update Time */
    @LastModifiedDate
    private Date updateDate;

    /** Creator */
    @CreatedBy
    @ManyToOne(fetch = FetchType.LAZY)
    @NotFound(action = NotFoundAction.IGNORE)
    @JoinColumn(name = "create_by")
    @JsonIgnore
    private User createBy;

    /** Updater */
    @LastModifiedBy
    @ManyToOne(fetch = FetchType.LAZY)
    @NotFound(action = NotFoundAction.IGNORE)
    @JoinColumn(name = "update_by")
    @JsonIgnore
    private User updateBy;

    /** Data Status */
    private Byte status = StatusEnum.OK.getCode();
}

Core Code (Interface)#

package com.linln.modules.system.repository;

import com.linln.common.constant.StatusConst;
import com.linln.modules.system.domain.Dept;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

public interface DeptRepository extends BaseRepository<Dept, Long> {

    /**
     * Find multiple departments
     * @param ids ID list
     * @return Department list
     */
    public List<Dept> findByIdIn(List<Long> ids);

    /**
     * Get maximum sort value
     * @param pid Parent department ID
     * @return Maximum value
     */
    @Query("select max(sort) from Menu m where m.pid = ?1 and m.status <> " + StatusConst.DELETE)
    public Integer findSortMax(long pid);

    /**
     * Find descendants by parent ID
     * @param pids PID list
     * @param status Data status
     * @return Department list
     */
    public List<Dept> findByPidsLikeAndStatus(String pids, Byte status);

    /**
     * Get all departments at this level by parent department ID
     * @param sort Sort object
     * @param pid Parent department ID
     * @param notId Department ID to exclude
     * @return Department list
     */
    public List<Dept> findByPidAndIdNot(Sort sort, long pid, long notId);
}

Running Screenshots#

image-20230608085533710

Log Module#

Definition#

The log module of the student management system is used to record various operation log information in the system.

Functions#

  1. Log Recording: System administrators can record various operations in the system through the log module, such as user login, data modification, system settings, etc., to help administrators understand the operation status and issues of the system.
  2. Log Query: Logged-in users can use the query function provided by the log module to query their own or other users' operation records, to understand their own or other users' operation history and behavior.
  3. Log Analysis: Through the log module, administrators can analyze the operation logs in the system to understand the usage status and issues of the system. For example, they can perform statistical analysis on user login times, data modification times, etc., to evaluate the security and stability of the system.
  4. Log Backup: To ensure the security of system data, the log module can provide backup functions, regularly backing up operation logs in the system for data recovery and tracing operation history when issues arise.
  5. Log Report Generation: Through the log module, administrators can generate reports of system operation logs for management and analysis of operation records. Reports can be classified and statistically analyzed according to different time periods, users, operation types, etc.
  6. Log Audit: Through the log module, administrators can audit the operation logs in the system to discover and resolve potential security issues and vulnerabilities.
  7. Log Filtering: Through the log module, administrators can filter based on different keywords to screen specific operation records. For example, filtering can be done based on user names, operation types, time ranges, etc.
  8. Log Security: To ensure the security and privacy of log records, the log module can provide security measures such as encryption and permission control to prevent unauthorized users from performing illegal operations and tampering with operation records.

Core Code (Implementation Class)#

package com.linln.modules.system.domain;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

@Data
@Entity
@Table(name="sys_action_log")
@EntityListeners(AuditingEntityListener.class)
public class ActionLog implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private Byte type;
    private String ipaddr;
    private String clazz;
    private String method;
    private String model;
    private Long recordId;
    @Lob @Column(columnDefinition="TEXT")
    private String message;
    @CreatedDate
    private Date createDate;
    @ManyToOne(fetch=FetchType.LAZY)
    @NotFound(action=NotFoundAction.IGNORE)
    @JoinColumn(name="oper_by")
    @JsonIgnore
    private User operBy;
    private String operName;

    public ActionLog(){}
    /**
     * Encapsulate log object
     * @param name Log name
     * @param message Log message
     */
    public ActionLog(String name, String message){
        this.name = name;
        this.message = message;
    }
}

Core Code (Interface)#

package com.linln.modules.system.repository;

import com.linln.modules.system.domain.ActionLog;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface ActionLogRepository extends JpaRepository<ActionLog, Long> {

    /**
     * Query log list by model and data ID
     * @param model Model (table name)
     * @param recordId Data ID
     * @return Log list
     */
    public List<ActionLog> findByModelAndRecordId(String model, Long recordId);
}

Running Screenshots#

image-20230608085724889

Training Summary#

Spring Boot is an open-source framework aimed at simplifying the creation, deployment, and operation of Java applications. Its main purpose is to quickly build production-level applications, reducing the number of configuration files and simplifying the configuration process. By using Spring Boot, developers can quickly build web applications, using its built-in Tomcat server without needing to manually configure anything, allowing for immediate startup.

During the training, we learned how to use Spring Boot to build Web applications, including how to use Spring MVC to build RESTful Web services, how to use Spring Data JPA for data persistence, how to use Thymeleaf to render HTML templates, and how to use Spring Security to provide security.

Overall, Spring Boot is a very powerful framework, and its simplified configuration and rapid development features are widely used in the field of Web development. For developers, using Spring Boot can reduce development time, improve productivity, and also enhance code quality.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.