Architectural Design and Implementation of an Alumni Forest Mini Program System

Technology Stack Architecture

Backend Framework: Spring Boot

Spring Boot serves as the core backend framework, leveraging its embedded servlet containers (Tomcat, Jetty) to eliminate the need for external server deployment. Its convention-over-configuration paradigm significantly accelerates development velocity. Through auto-configuration, the framework manages dependency injection and bean lifecycle, allowing developers to focus on business logic rather than infrastructure boilerplate. Furthermore, it integrates seamlessly with Spring Data, Security, and Cloud ecosystems, providing a robust foundation for scalable application development.

Frontend Framework: Vue.js

Vue.js is utilized for building interactive user interfaces. The framework employs a reactive data binding system and a component-based architecture. By implementing a Virtual DOM, Vue ensures efficient rendering and state management. When the underlying data model changes, the view updates automatically, minimizing manual DOM manipulation. This approach enhances code maintainability and facilitates the development of Single Page Applications (SPAs) with a clear separation of concerns.

Persistence Layer: MyBatis-Plus

MyBatis-Plus acts as an enhancement to the standard MyBatis framework. It simplifies database interactions by providing a generic CRUD interface, significantly reducing the volume of SQL boilerplate code. Features such as code generation, pagination plugins, and dynamic SQL construction streamline data access layer development. Supporting multiple database dialects, it allows for efficient object-relational mapping and complex query execution without sacrificing performance.

System Testing Strategy

System testing is integral to ensuring software quality and reliability. The testing phase employs Black-Box testing techniques to validate functional requirements against actual system behavior. The primary objective is to identify logical defects, verify input constraints, and ensure the system meets user specifications under various operational scenarios.

Authentication Module Testing

The authentication module is tested to verify login security, including credential validation and role-based access control. Test cases cover valid inputs, incorrect passwords, and empty field handling.

Test InputExpected ResultActual ResultStatus
User: admin, Pass: valid_pwd, Captcha: correctLogin successful, redirect to dashboardRedirected successfullyPass
User: admin, Pass: wrong_pwd, Captcha: correctSystem prompts 'Invalid credentials'Error message displayedPass
User: admin, Pass: valid_pwd, Captcha: wrongSystem prompts 'Captcha mismatch'Error message displayedPass
User: [Empty], Pass: valid_pwdSystem prompts 'Username required'Validation error shownPass

User Management Module Testing

User management functions, including creation, modification, and deletion, are verified to ensure data integrity and UI responsiveness.

OperationTest ScenarioExpected ResultStatus
Add UserSubmit valid user dataUser appears in listPass
Edit UserModify existing detailsUpdates reflected immediatelyPass
Delete UserConfirm deletion promptUser removed from databasePass
Duplicate UserRegister existing usernameSystem rejects submissionPass

Core Implementation Details

The following code snippets illustrate the implementation of the login logic, token generation, and request interception for authorization.

Login Controller

@RestController
@RequestMapping("/api/auth")
public class AuthController {

    @Autowired
    private SysUserService userService;

    @Autowired
    private TokenService tokenService;

    @PostMapping("/login")
    public Result<Map<String, Object>> login(@RequestBody LoginDTO dto) {
        SysUser user = userService.getOne(
            new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, dto.getUsername())
        );

        if (user == null || !user.getPassword().equals(dto.getPassword())) {
            return Result.error("Invalid username or password");
        }

        String accessToken = tokenService.generateToken(user.getId(), user.getUsername(), "sys_user", user.getRole());
        Map<String, Object> data = new HashMap<>();
        data.put("token", accessToken);
        return Result.ok(data);
    }
}

Token Generation Service

@Service
public class TokenServiceImpl implements TokenService {

    @Autowired
    private UserTokenMapper tokenMapper;

    @Override
    public String generateToken(Long userId, String username, String table, String role) {
        UserToken existingToken = tokenMapper.selectOne(
            new LambdaQueryWrapper<UserToken>().eq(UserToken::getUserId, userId)
        );

        String newToken = UUID.randomUUID().toString().replace("-", "");
        Date expiryTime = DateUtil.offsetHour(new Date(), 1);

        if (existingToken != null) {
            existingToken.setToken(newToken);
            existingToken.setExpiryTime(expiryTime);
            tokenMapper.updateById(existingToken);
        } else {
            UserToken tokenEntity = new UserToken();
            tokenEntity.setUserId(userId);
            tokenEntity.setUsername(username);
            tokenEntity.setToken(newToken);
            tokenEntity.setExpiryTime(expiryTime);
            tokenMapper.insert(tokenEntity);
        }
        return newToken;
    }
}

Authorization Interceptor

@Component
public class AuthInterceptor implements HandlerInterceptor {

    public static final String AUTH_HEADER = "Authorization";

    @Autowired
    private TokenService tokenService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // Handle CORS preflight requests
        if (HttpMethod.OPTIONS.name().equals(request.getMethod())) {
            response.setStatus(HttpStatus.OK.value());
            return true;
        }

        // Check for @IgnoreAuth annotation
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            if (handlerMethod.getMethodAnnotation(IgnoreAuth.class) != null) {
                return true;
            }
        }

        String tokenStr = request.getHeader(AUTH_HEADER);
        if (StrUtil.isBlank(tokenStr)) {
            throw new AuthException("Missing authentication token");
        }

        UserToken tokenEntity = tokenService.getTokenEntity(tokenStr);
        if (tokenEntity == null) {
            throw new AuthException("Invalid or expired token");
        }

        // Store user info in session context
        request.getSession().setAttribute("userId", tokenEntity.getUserId());
        request.getSession().setAttribute("role", tokenEntity.getRole());
        return true;
    }
}

Database Schema Design

The authentication system relies on a token table to manage user sessions. The schema definition is as follows:

CREATE TABLE `sys_user_token` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
  `user_id` bigint(20) NOT NULL COMMENT 'Associated User ID',
  `username` varchar(100) NOT NULL COMMENT 'Username',
  `table_name` varchar(100) DEFAULT NULL COMMENT 'Associated Table',
  `role` varchar(100) DEFAULT NULL COMMENT 'User Role',
  `token` varchar(200) NOT NULL COMMENT 'Access Token',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Creation Time',
  `expiry_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Expiration Time',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_token` (`token`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Session Token Management';

Tags: Spring Boot Vue.js UniApp WeChat Mini Program System Implementation

Posted on Tue, 19 May 2026 10:21:30 +0000 by PRSWeb