Design and Implementation of an Alumni Association WeChat Mini Program Based on SpringBoot, Vue and uni-app
Tech Stack
Backend: Spring Boot
Spring Boot comes with embedded application servers including Tomcat, Jetty and Undertow out of the box, eliminating the need for manual server installation and configuration. Its core advantage is auto-configuration, which automatically sets up the application based on included project dependencies, drastically simplifying manual configuration work. Spring Boot also provides a wide range of production-ready features and integrations such as Spring Data, Spring Security and Spring Cloud, enabling developers to build applications faster while making it easier to extend the system and integrate third-party technologies. It is one of the most popular Java backend frameworks today, with auto-configuration, embedded servers and rich extensions that help developers build high-quality applications faster and easier.
Frontend Management System: Vue.js
Vue.js centers on virtual DOM technology, an in-memory data structure that enables highly efficient DOM update operations. It leverages modern development paradigms including reactive data binding, virtual DOM and component-based architecture to provide developers with a flexible, efficient, and easy-to-maintain development workflow. When underlying application data changes, the UI updates automatically, allowing developers to focus on business logic processing instead of manual DOM manipulation, which embodies Vue's core characteristics of simplicity, flexibility and efficiency.
Data Access Layer: MyBatis-Plus
MyBatis-Plus is an enhancement tool built on top of the MyBatis framework, designed to simplify MyBatis-based development. This open-source Java framework supports all major relational databases including MySQL, Oracle, SQL Server and PostgreSQL. It provides rich APIs and annotations that enable ORM operations through simple configuration, greatly reducing the amount of handwritten SQL required for development. It also includes a built-in code generator that can automatically generate entity classes, Mapper interfaces and XML mapping files, drastical streamlining the development workflow. MyBatis-Plus also supports practical features like paged queries, dynamic queries, optimistic locking and performance analysis, enabling developers to build efficient data access layers faster, improving overall development efficiency while maintaining code quality.
System Testing
The primary goal of testing is to uncover defects across all aspects of the system, correct identified issues through functional testing, and confirm that the system meets all user requirements.
Testing Objectives
System testing is an essential, patience-intensive phase of the entire development lifecycle. It acts as the final quality gate and the last full check before delivering the completed system. The main purpose of testing is to prevent end-user issues and improve the overall user experience. To achieve this, we test the system from multiple perspectives with simulated real-world usage scenarios to catch and resolve defects before release. Testing also allows us to verify overall system quality, confirm all required functions are implemented correctly, and check that core logic flows work as expected. A complete testing process directly improves system quality and usability. Testing also validates that the implementation aligns with the original requirements specification, catching any inconsistencies or conflicts between the implementation and requirements. All testing is designed from a end-user perspective to avoid unrealistic test cases that waste time and lead to inaccurate test results.
Functional Testing
Black-box testing was performed on all system functional modules through interaction testing, boundary value input, and required field validation. Test cases were prepared in advance, and all tests were executed per the test plan to get final test results.
Login Function Test
The login flow validates input credentials against stored user data, returns corresponding error messages for invalid input, and enforces role-based access restrictions. Test cases are shown below:
| Input Data | Expected Outcome | Actual Outcome | Result |
|---|---|---|---|
Username: guanliyuan, Password: 123456, Correct captcha |
Login successful | Successfully logged into system | Matches expectation |
Username: guanliyuan, Password: 111111, Correct captcha |
Incorrect password error | "Incorrect password, please re-enter" displayed | Matches expectation |
Username: guanliyuan, Password: 123456, Incorrect captcha |
Incorrect captcha error | "Incorrect verification code" displayed | Matches expectation |
Username: Empty, Password: 123456, Correct captcha |
Username required error | "Please enter a username" displayed | Matches expectation |
Username: guanliyuan, Password: Empty, Correct captcha |
Incorrect password error | "Incorrect password, please re-enter" displayed | Matches expectation |
User Management Function Test
The user management module supports adding, editing, deleting and searching user accounts. We tested non-null validation for required fields, duplicate username checking, deletion confirmation, and updated data display. Test cases are shown below:
| Input Data | Expected Outcome | Actual Outcome | Result |
|---|---|---|---|
| Complete valid user basic information | Add successful, new user appears in user list | New user displayed in user list | Matches expectation |
| Modify existing user information | Edit successful, changes saved | User information updated correctly | Matches expectation |
| Select user for deletion | System prompts for confirmation, user removed after confirmation | Confirmation prompt displayed, user no longer found after confirmation | Matches expectation |
| Create user without entering username | Error: username is required | "Username cannot be empty" displayed | Matches expectation |
| Create user with an existing username | Add failed, duplicate username error | "Username already exists" error displayed | Matches expectation |
Testing Conclusion
This system primarily uses black-box testing, with test cases designed to simulate real user behavior to verify the correctness of end-to-end workflows. System testing is essential to refine the system and improve its overall usability, and the testing process confirmed that all functional modules meet the original design requirements, with all core logic working correctly. The system is designed to be simple and intuitive for end users, and all tested scenarios align with user requirements. All defects found during testing were resolved, and the final system meets all functional and performance design requirements.
Core Code Implemantation
@IgnoreAuth
@PostMapping(value = "/login")
public R authenticate(String username, String password, String verificationCode, HttpServletRequest request) {
UserAccount user = userService.getOne(new QueryWrapper<UserAccount>().eq("username", username));
if(user == null || !user.getPassword().equals(password)) {
return R.error("Invalid username or password");
}
String accessToken = tokenService.createToken(user.getId(), username, "users", user.getRole());
return R.ok().put("token", accessToken);
}
@Override
public String createToken(Long userId, String username, String tableName, String role) {
TokenEntity existingToken = this.getOne(new QueryWrapper<TokenEntity>().eq("userid", userId).eq("role", role));
String newToken = CommonUtil.generateRandomString(32);
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
calendar.add(Calendar.HOUR_OF_DAY, 1);
if(existingToken != null) {
existingToken.setToken(newToken);
existingToken.setExpireTime(calendar.getTime());
this.updateById(existingToken);
} else {
this.save(new TokenEntity(userId, username, tableName, role, newToken, calendar.getTime()));
}
return newToken;
}
/**
* Token-based Authentication Validation
*/
@Component
public class AuthInterceptor implements HandlerInterceptor {
public static final String AUTH_TOKEN_KEY = "Token";
@Autowired
private TokenService tokenService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// Enable cross-origin requests
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with,request-source,Token, Origin,imgType, Content-Type, cache-control,postman-token,Cookie, Accept,authorization");
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
// Preflight OPTIONS requests return OK directly
if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
response.setStatus(HttpStatus.OK.value());
return false;
}
IgnoreAuth openEndpoint;
if (handler instanceof HandlerMethod) {
openEndpoint = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
} else {
return true;
}
// Get token from request header
String token = request.getHeader(AUTH_TOKEN_KEY);
/**
* Skip authentication for open endpoints
*/
if(openEndpoint != null) {
return true;
}
TokenEntity validToken = null;
if(StringUtils.isNotBlank(token)) {
validToken = tokenService.getTokenEntity(token);
}
if(validToken != null) {
request.getSession().setAttribute("userId", validToken.getUserid());
request.getSession().setAttribute("role", validToken.getRole());
request.getSession().setAttribute("tableName", validToken.getTablename());
request.getSession().setAttribute("username", validToken.getUsername());
return true;
}
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
try (PrintWriter writer = response.getWriter()) {
writer.print(JSONObject.toJSONString(R.error(401, "Please log in first")));
}
return false;
}
}
Database Schema Reference
-- ----------------------------
-- Table structure for authentication tokens
-- ----------------------------
DROP TABLE IF EXISTS `auth_token`;
CREATE TABLE `auth_token` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'primary key',
`userid` bigint(20) NOT NULL COMMENT 'user ID',
`username` varchar(100) NOT NULL COMMENT 'username',
`tablename` varchar(100) DEFAULT NULL COMMENT 'user table name',
`role` varchar(100) DEFAULT NULL COMMENT 'user role',
`token` varchar(200) NOT NULL COMMENT 'authentication token',
`addtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'creation time',
`expire_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'expiration time',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='authentication token table';