Design and Implementation of a News Information System Using SpringBoot, Vue, and Uniapp-Based Mini Programs

Architecture and Technical Choices

The news information system adopts a separated frontend and backend architecture. The server side relies on SpringBoot for API development, session management, and business logic processing. The web admin panel is built with Vue, while the client side uses a Uniapp framework to deliver a cross-platform WeChat mini program experience.

Backend SpringBoot provides an embedded web container and auto-configuration capabilities that eliminate complex deployment steps. It handles request routing, JWT-based token authentication, database transactions, and role-based access checks.

Admin Frontend Vue manages the administrator interface through a component tree and reactive state. All dashboard views, form interactions, and data tables are driven by Vue’s virtual DOM and binding mechanisms, ensuring smooth updates when server data changes.

Mini Program Client Uniapp compiles a single codebase into a WeChat mini program, enabling article browsing, category filtering, and user interaction features directly on mobile devices.

Data Layer MyBatis-Plus wraps MyBatis with enhanced CRUD interfaces, pagination plugins, and a code generator. Entities, mappers, and XML files are automatically scaffolded, and runtime features such as optimistic locking and dynamic queries reduce hand-written SQL.


Core Module Implementations

User Authentication and Token Management

Login verification compares submitted credentials against the database. On success, a random 32-character token is generated and persisted with an expiration timestamp. The token associates the current user ID, role, and table name. Subsequent requests must include the token in the HTTP header; an interceptor validates it and injects session attributes.

@PostMapping("/auth/signin")
@IgnoreAuth
public R performSignIn(String username, String password, String captcha) {
    UsersEntity account = userService.getOne(
        new LambdaQueryWrapper<UsersEntity>().eq(UsersEntity::getUsername, username));
    if (account == null || !account.getPassword().equals(password)) {
        return R.fail("Invalid username or password");
    }
    String jwt = tokenService.createToken(account.getId(), username,
                                          "users", account.getRole());
    return R.ok().put("accessToken", jwt);
}
@Override
public String createToken(Long userId, String username, String table, String role) {
    TokenEntity existing = this.getOne(new LambdaQueryWrapper<TokenEntity>()
            .eq(TokenEntity::getUserid, userId)
            .eq(TokenEntity::getRole, role));
    String rawToken = CommonUtil.generateRandomString(32);
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.HOUR_OF_DAY, 2);
    if (existing != null) {
        existing.setToken(rawToken);
        existing.setExpiratedtime(calendar.getTime());
        this.updateById(existing);
    } else {
        this.save(new TokenEntity(userId, username, table, role,
                                  rawToken, calendar.getTime()));
    }
    return rawToken;
}

The request interceptor checks every incoming call, skipping annotated public endpoints. It reads the token header, looks up the token entity, and rejects the request with a 401 status if the token is absent or invalid.

@Component
public class AccessInterceptor implements HandlerInterceptor {

    private static final String HEADER_TOKEN = "Auth-Token";

    @Autowired
    private TokenService tokenService;

    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res,
                             Object handler) throws Exception {
        configureCorsHeaders(res, req);
        if (RequestMethod.OPTIONS.name().equals(req.getMethod())) {
            res.setStatus(HttpStatus.OK.value());
            return false;
        }

        IgnoreAuth skipAuth = null;
        if (handler instanceof HandlerMethod) {
            skipAuth = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
        } else {
            return true;
        }

        if (skipAuth != null) {
            return true;
        }

        String token = req.getHeader(HEADER_TOKEN);
        TokenEntity tokenEntity = StringUtils.isNotBlank(token) ?
                tokenService.findByToken(token) : null;

        if (tokenEntity != null) {
            req.getSession().setAttribute("userId", tokenEntity.getUserid());
            req.getSession().setAttribute("role", tokenEntity.getRole());
            req.getSession().setAttribute("tableName", tokenEntity.getTablename());
            req.getSession().setAttribute("username", tokenEntity.getUsername());
            return true;
        }

        res.setCharacterEncoding("UTF-8");
        res.setContentType("application/json; charset=utf-8");
        try (PrintWriter out = res.getWriter()) {
            out.print(JSONObject.toJSONString(R.fail(401, "Authentication required")));
        }
        return false;
    }

    private void configureCorsHeaders(HttpServletResponse res, HttpServletRequest req) {
        res.setHeader("Access-Control-Allow-Methods",
                      "POST, GET, OPTIONS, DELETE");
        res.setHeader("Access-Control-Max-Age", "3600");
        res.setHeader("Access-Control-Allow-Credentials", "true");
        res.setHeader("Access-Control-Allow-Headers",
                      "x-requested-with, Auth-Token, Origin, Content-Type, Accept");
        res.setHeader("Access-Control-Allow-Origin",
                      req.getHeader("Origin"));
    }
}

Article & Category Management

Administrators create and publish articles with titles, summaries, rich text content, and cover images. Each article belongs to a category, and the Uniapp client fetches paginated lists filtered by category. MyBatis-Plus pagination interceptors automatically append LIMIT clauses to queries.

User and Role Administration

The user management module enforces unique usernames and mandatory fields. Admin users can create, update, or soft-delete accounts. The system differentiates roles (admin, editor, regular user) and applies distinct permissions during menu rendering and API access.


Database Design

Key tables include users, articles, categories, and token. The token table stores sessions independently to allow quick validation without repeatedly querying the user table.

DROP TABLE IF EXISTS `token`;
CREATE TABLE `token` (
  `id`          BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'primary key',
  `userid`      BIGINT(20) NOT NULL COMMENT 'user identifier',
  `username`    VARCHAR(100) NOT NULL COMMENT 'login name',
  `tablename`   VARCHAR(100) DEFAULT NULL COMMENT 'associated table',
  `role`        VARCHAR(100) DEFAULT NULL COMMENT 'role label',
  `token`       VARCHAR(200) NOT NULL COMMENT 'access token',
  `addtime`     TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'created at',
  `expiratedtime` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'expiration',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='token storage';

Sample seed data:

INSERT INTO `token` VALUES
  ('9','23','cd01','xuesheng','student','al6svx5qkei1wljry5o1npswhdpqcpcg','2023-02-23 21:46:45','2023-03-15 14:01:36'),
  ('12','1','admin','users','administrator','h1pqzsb9bldh93m92j9m2sljy9bt1wdh','2023-02-27 19:37:01','2023-03-17 18:23:02');

Testing Approach

Functional testing covers login, user management, and article publishing workflows. Black-box test cases validate required fields, duplicate detection, and role-based access constraints.

  • Login checks verify responses for missing credentials, wrong passwords, and expired tokens.
  • User management tests confirm that adding a duplicate username triggers an error, and that deleting an account removes it from list views after confirmation.
  • All deviation between expected and actual outcomes are documented and resolved before release.

Testing confirms that the system meets the original requirements, with all module behaving consistently under both normal and edge-case scenarios.

Tags: SpringBoot vue UniApp WeChat Mini Program News System

Posted on Thu, 10 Sep 2026 16:45:40 +0000 by drisate