Personnel Attendance Management System with Java Spring Boot, SSM, and Vue.js

Technical Stack Overview

Backend Framework: Spring Boot

Spring Boot is a framework designed for creating independent, production-grade Spring-based applications. Its primary objective is to simplify the Spring application development process by offering out-of-the-box functionality while maintaining core power and flexibility.

Spring Boot provides a rapid application development approach through automatic configuration and convention-over-configuration principles, reducing the amount of boilerplate code developers need to write. Its design philosophy follows "convention over configuration," allowing developers to focus on business logic implementation rather than configuration file writing.

The framework includes embedded web servers like Tomcat, Undertow, or Jetty, enabling applications to be packaged as executable JAR files. This design simplifies deployment and execution, requiring only a java -jar command to run. Additionally, Spring Boot offers extensive Actuator support for runtime monitoring and management of applications.

Furthermore, Spring Boot provides rich plugin and extension mechanisms that can easily integrate various features such as security authentication, data access, message queues, and caching. By using Spring Boot Starter dependencies, developers can conveniently add required functional modules and configure them through simple settings.

Frontend Framework: Vue.js

Vue.js is a popular JavaScript framework for building user interfaces (UI) and single-page applications (SPA). Created by Evan You in 2014, it is a lightweight, easy-to-learn, and flexible framework.

Vue.js's core strength lies in its reactive data binding system, which allows developers to easily manage view and data changes. It also provides a set of concise, intuitive APIs that make the development process more efficient and flexible.

Vue's component-based development model enables developers to break applications into small, independent components and then combine these components into complete applications. This approach enhances code reusability and makes maintenance and testing easier.

Moreover, Vue.js has a very active community that offers many useful plugins and tools, along with extensive documentation and tutorials. This makes learning and using Vue.js more straightforward and enjoyable.

Core Code Implementation

package attendance.system;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
@MapperScan(basePackages = {"attendance.system.dao"})
public class AttendanceManagementApp extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(AttendanceManagementApp.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(AttendanceManagementApp.class);
    }
}

package attendance.system.controller;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;

import attendance.system.utils.ValidatorUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.annotation.IgnoreAuth;

import attendance.system.entity.EmployeeEntity;
import attendance.system.entity.view.EmployeeView;

import attendance.system.service.EmployeeService;
import attendance.system.service.TokenService;
import attendance.system.utils.PageUtils;
import attendance.system.utils.R;
import attendance.system.utils.MPUtil;
import attendance.system.utils.MapUtils;
import attendance.system.utils.CommonUtil;
import java.io.IOException;

/**
 * Employee Management
 * Backend Interface
 * @author 
 * @email 
 * @date 2024-04-24 17:59:31
 */
@RestController
@RequestMapping("/employee")
public class EmployeeController {
    @Autowired
    private EmployeeService employeeService;

	@Autowired
	private TokenService tokenService;
	
	/**
	 * Login
	 */
	@IgnoreAuth
	@RequestMapping(value = "/login")
	public R login(String username, String password, String captcha, HttpServletRequest request) {
		EmployeeEntity user = employeeService.selectOne(new EntityWrapper<EmployeeEntity>().eq("employeeId", username));
		if(user==null || !user.getPassword().equals(password)) {
			return R.error("Username or password is incorrect");
		}
		
		String token = tokenService.generateToken(user.getId(), username,"employee",  "User" );
		return R.ok().put("token", token);
	}

	/**
     * Registration
     */
	@IgnoreAuth
    @RequestMapping("/register")
    public R register(@RequestBody EmployeeEntity employee){
    	//ValidatorUtils.validateEntity(employee);
    	EmployeeEntity existingUser = employeeService.selectOne(new EntityWrapper<EmployeeEntity>().eq("employeeId", employee.getEmployeeId()));
		if(existingUser!=null) {
			return R.error("Employee already exists");
		}
		Long userId = new Date().getTime();
		employee.setId(userId);
        employeeService.insert(employee);
        return R.ok();
    }

	/**
	 * Logout
	 */
	@RequestMapping("/logout")
	public R logout(HttpServletRequest request) {
		request.getSession().invalidate();
		return R.ok("Logout successful");
	}
	
	/**
     * Get current user session information
     */
    @RequestMapping("/session")
    public R getCurrentUser(HttpServletRequest request){
    	Long id = (Long)request.getSession().getAttribute("userId");
        EmployeeEntity user = employeeService.selectById(id);
        return R.ok().put("data", user);
    }
    
    /**
     * Password reset
     */
    @IgnoreAuth
	@RequestMapping(value = "/resetPassword")
    public R resetPassword(String username, HttpServletRequest request){
    	EmployeeEntity user = employeeService.selectOne(new EntityWrapper<EmployeeEntity>().eq("employeeId", username));
    	if(user==null) {
    		return R.error("Account does not exist");
    	}
        user.setPassword("123456");
        employeeService.updateById(user);
        return R.ok("Password has been reset to: 123456");
    }

    /**
     * Backend list
     */
    @RequestMapping("/page")
    public R page(@RequestParam Map<String, Object> params,EmployeeEntity employee,
		HttpServletRequest request){
        EntityWrapper<EmployeeEntity> ew = new EntityWrapper<EmployeeEntity>();

		PageUtils page = employeeService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, employee), params), params));

        return R.ok().put("data", page);
    }
    
    /**
     * Frontend list
     */
	@IgnoreAuth
    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> params,EmployeeEntity employee, 
		HttpServletRequest request){
        EntityWrapper<EmployeeEntity> ew = new EntityWrapper<EmployeeEntity>();

		PageUtils page = employeeService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, employee), params), params));
        return R.ok().put("data", page);
    }

	/**
     * List
     */
    @RequestMapping("/lists")
    public R list( EmployeeEntity employee){
       	EntityWrapper<EmployeeEntity> ew = new EntityWrapper<EmployeeEntity>();
      	ew.allEq(MPUtil.allEQMapPre( employee, "employee")); 
        return R.ok().put("data", employeeService.selectListView(ew));
    }

	 /**
     * Query
     */
    @RequestMapping("/query")
    public R query(EmployeeEntity employee){
        EntityWrapper< EmployeeEntity> ew = new EntityWrapper< EmployeeEntity>();
 		ew.allEq(MPUtil.allEQMapPre( employee, "employee")); 
		EmployeeView employeeView =  employeeService.selectView(ew);
		return R.ok("Employee query successful").put("data", employeeView);
    }
	
    /**
     * Backend details
     */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Long id){
        EmployeeEntity employee = employeeService.selectById(id);
        return R.ok().put("data", employee);
    }

    /**
     * Frontend details
     */
	@IgnoreAuth
    @RequestMapping("/detail/{id}")
    public R detail(@PathVariable("id") Long id){
        EmployeeEntity employee = employeeService.selectById(id);
        return R.ok().put("data", employee);
    }
    
    /**
     * Backend save
     */
    @RequestMapping("/save")
    public R save(@RequestBody EmployeeEntity employee, HttpServletRequest request){
        if(employeeService.selectCount(new EntityWrapper<EmployeeEntity>().eq("employeeId", employee.getEmployeeId()))>0) {
            return R.error("Employee ID already exists");
        }
    	employee.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
    	//ValidatorUtils.validateEntity(employee);
    	EmployeeEntity existingUser = employeeService.selectOne(new EntityWrapper<EmployeeEntity>().eq("employeeId", employee.getEmployeeId()));
		if(existingUser!=null) {
			return R.error("Employee already exists");
		}
		employee.setId(new Date().getTime());
        employeeService.insert(employee);
        return R.ok();
    }
    
    /**
     * Frontend save
     */
    @RequestMapping("/add")
    public R add(@RequestBody EmployeeEntity employee, HttpServletRequest request){
        if(employeeService.selectCount(new EntityWrapper<EmployeeEntity>().eq("employeeId", employee.getEmployeeId()))>0) {
            return R.error("Employee ID already exists");
        }
    	employee.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
    	//ValidatorUtils.validateEntity(employee);
    	EmployeeEntity existingUser = employeeService.selectOne(new EntityWrapper<EmployeeEntity>().eq("employeeId", employee.getEmployeeId()));
		if(existingUser!=null) {
			return R.error("Employee already exists");
		}
		employee.setId(new Date().getTime());
        employeeService.insert(employee);
        return R.ok();
    }

    /**
     * Update
     */
    @RequestMapping("/update")
    @Transactional
    public R update(@RequestBody EmployeeEntity employee, HttpServletRequest request){
        //ValidatorUtils.validateEntity(employee);
        if(employeeService.selectCount(new EntityWrapper<EmployeeEntity>().ne("id", employee.getId()).eq("employeeId", employee.getEmployeeId()))>0) {
            return R.error("Employee ID already exists");
        }
        employeeService.updateById(employee);
        return R.ok();
    }

    /**
     * Delete
     */
    @RequestMapping("/delete")
    public R delete(@RequestBody Long[] ids){
        employeeService.deleteBatchIds(Arrays.asList(ids));
        return R.ok();
    }
    
}

System Testing

The primary objective of testing this system from multiple perspectives is to identify existing problems. Through functional testing, we aim to discover system defects and correct them, ensuring the system is free of issues. During testing, we verify that the system meets customer requirements, identify problems and shortcomings, and address them prompt. After completing testing, we draw test conclusions.

System Testing Objectives

In the development lifecycle of an attendance management system, system testing is an essential and patience-testing process. Its importance lies in being the final checkpoint for ensuring system quality and reliability, as well as the last inspection of the entire system development process.

System testing primarily aims to prevent problems when users are using the system and enhance user experience. To avoid impacting user experience, we need to consider potential system issues from multiple angles and perspectives, discovering defects and solving problems through different simulated scenarios. The testing process also helps us understand the system's quality, whether functions are complete, and if the system logic is smooth. A qualified system testing process will significantly improve system quality and usability. The goal of testing is to verify whether the system conforms to the requirements specification and identify any inconsistencies or conflicts with the requirements specification. During testing, we must consider issues from the user's perspective, avoiding unrealistic scenarios that waste testing time and may lead to discrepancies between expected and actual results.

System Functional Testing

Functional testing of system modules involves a series of black-box tests through methods such as clicking, inputting boundary values, and validating required versus non-required fields. By creating test cases and executing them, we can draw test conclusions.

Login function test plan: When accesssing the system, verify through account and password functionality. Users must enter content matching data stored in the database. When any input is incorrect, the system will prompt for incorrect input. This interface also has corresponding validation for role permissions. When a user with an employee role attempts to log in using an administrator account, an error will be reported. The login function test cases are as shown in the table.

System Testing Conclusion

This system primarily uses black-box testing, simulating user interactions with the system to implement various functions, create test cases, and conduct testing. This ensures the correctness of system workflows. System testing is essential as it makes the system more complete and improves its usability.

Testing this system mainly aims to verify whether the system's functional modules meet our initial design concepts and whether the logic of each functional module is correct. This system does not require overly complex logic processing to ensure ease of use for operators. The ultimate goal of testing revolves around user experience. All scenarios during testing should align with user requirements without deviating from the target. When encountering problems, we should think from the user's perspective. After a series of testing processes, we obtain the final test results. From these results, we can see that the implemented system meets design requirements in terms of functionality and performance.

Tags: java Spring Boot Vue.js attendance management employee management

Posted on Sat, 01 Aug 2026 16:05:19 +0000 by dicky96