Employee Management System Built with Spring Boot, Vue, and UniApp
The system employs a modern full-stack architecture combining Spring Boot for the backend, Vue.js for the web frontend, and UniApp for cross-platform mobile deployment.
Backend: Spring Boot
Spring Boot simplifies server-side development by embedding application servers like Tomcat and offering auto-configuration based on classpath dependencies. Integrated modules such as Spring Data JPA and Spring Security accelerate development while ensuring robustness and scalability.
Frontend: Vue.js
Vue.js leverages a reactive data-binding model and virtual DOM to deliver responsive user interfaces. Its component-based structure promotes reusability and maintainability, enabling rapid UI development that automatically reflects data changes without manual DOM manipulation.
Persistence Layer: MyBatis-Plus
MyBatis-Plus extends MyBatis with enhanced features including built-in CRUD operations, pagination support, and code generation tools. It reduces boilerplate SQL and mapper code, supports multiple databases (e.g., MySQL, PostgreSQL), and offers utilities like optimistic locking and perforrmance analysis interceptors.
Authentication Flow
User authentication is handled via token-based sessions. Upon successful login, a 32-character random token is generated and stored with an expiration time (typical one hour). The AuthorizationInterceptor validates this token on protected endpoints:
@PostMapping("/login")
public R authenticate(String username, String password, String captcha, HttpServletRequest req) {
UserEntity user = userService.getOne(Wrappers.<UserEntity>lambdaQuery()
.eq(UserEntity::getUsername, username));
if (user == null || !user.getPassword().equals(password)) {
return R.error("Invalid credentials");
}
String token = tokenService.createToken(user.getId(), user.getUsername(), "users", user.getRole());
return R.ok().put("token", token);
}
public String createToken(Long userId, String username, String table, String role) {
TokenEntity existing = tokenMapper.selectOne(Wrappers.<TokenEntity>lambdaQuery()
.eq(TokenEntity::getUserId, userId)
.eq(TokenEntity::getRole, role));
String newToken = RandomUtil.randomString(32);
Date expiry = DateUtil.offsetHour(new Date(), 1);
if (existing != null) {
existing.setToken(newToken);
existing.setExpiratedtime(expiry);
tokenMapper.updateById(existing);
} else {
tokenMapper.insert(new TokenEntity(userId, username, table, role, newToken, expiry));
}
return newToken;
}
The interceptor checks for the Token header on each request (except those annotated with @IgnoreAuth). Valid tokens populate session attributes (userId, role, etc.), while invalid or missing tokens return a 401 error.
Database Schema
A dedicated token table manages active sessions:
CREATE TABLE `token` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY,
`userid` BIGINT NOT NULL,
`username` VARCHAR(100) NOT NULL,
`tablename` VARCHAR(100),
`role` VARCHAR(100),
`token` VARCHAR(200) NOT NULL,
`addtime` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`expiratedtime` TIMESTAMP NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Sample records track user sessions with expiration timestamps, enabling automatic logout after inactivity.
Testing Strategy
Functional validation uses black-box testing with test cases covering:
- Login: Verifies correct/incorrect credentials, empty fields, and CAPTCHA validation
- User Management: Tests creation (with duplicate/empty checks), editing, and deletion workflows
All test scenarios align with user expectations and requirement specifications, confirming both correctness and usability.