Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Building a WeChat Mini Program Ordering System with Spring Boot and Vue.js

Tech 1

Spring Boot is a development framework built on top of the Spring Framework. It simplifies configuration by embedding servers like Tomcat and provides powerful auto-configuration based on project dependencies. This framework offers out-of-the-box features and plugins such as Spring Data and Spring Security, enabling rapid application development and easy integration with other technologies. Its flexible configuration management, quick deployment, strong community support, and robust testing tools make it a popular choice for building scalable and maintainable applications.

A basic Spring Boot application structure is illustrated below:

package com.example.demo;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication

@RestController

public class DemoApplication {

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

    @GetMapping("/greet")
    public String sendGreeting() {
        return "Welcome to the application!";
    }
}

The @SpringBootApplication annotation marks this class as the application's entry point. The @RestController annotation designates it as a controller for handling RESTful requests. The sendGreeting method, mapped to the /greet endpoint via @GetMapping, returns a simple string response. Running the application starts an embedded server, allowing access to the endpoint.

Vue.js is a progressive JavaScript framework for building user interfaces. Its core advantages include reactive data binding and a virtual DOM, which enable efficient UI updates. The component-based architecture promotes reusability and maintainability.

The following example demonstrates basic Vue.js functionality:

<!DOCTYPE html>
<html>
<head>
    <title>Vue Example</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
    <div id="app">
        <h3>{{ greetingText }}</h3>
        <button @click="updateGreeting">Update Text</button>
    </div>
    <script>
        const { createApp } = Vue;
        createApp({
            data() {
                return {
                    greetingText: 'Hello from Vue!'
                }
            },
            methods: {
                updateGreeting() {
                    this.greetingText = 'Vue.js is reactive!';
                }
            }
        }).mount('#app');
    </script>
</body>
</html>

This code creates a Vue application instance bound to the #app element. The greetingText data property is displayed in the template. Clicking the button triggers the updateGreeting method, which changes the greetingText value, and Vue automatically updates the DOM to reflect the change.

MyBatis is a persistance framework that simplifies database interactions by separating SQL statements from Java code. It uses XML or annotations to map Java objects to database tables. Key features include dynamic SQL support, caching mechanisms to improve performance, and a plugin system for extensibility.

Comprehensive testing is essential to ensure system quality and reliability. The primary goal is to identify defects from multiple perspectives, simulate various user scenarios, and verify that the system meets specified requirements. Testing helps improve the final product's stability and user experience.

Functional testing involves validating system modules using techniques like boundary value analysis and equivalence partitioning. Test cases are designed and executed to verify expected behavior.

For example, login functionality can be tested with the following cases:

Input Data (Username, Password, Captcha) Expected Result Actual Result Analysis
admin, correct_pwd, valid_captcha Successful login Successful login Pass
admin, wrong_pwd, valid_captcha Password error Password error Pass
admin, correct_pwd, invalid_captcha Captcha error Captcha error Pass
(empty), correct_pwd, valid_captcha Username required Username required Pass
admin, (empty), valid_captcha Password error Password error Pass

User management functions, including addition, modification, and deletion, should also be rigorously tested.

Function Input Data Expected Result Actual Result Analysis
Add User new_user, pwd123, User User added to list User added to list Pass
Add User existing_user, pwd123, User Username exists error Username exists error Pass
Edit User Select user, change password Password updated Password updated Pass
Delete User Select user, confirm User removed User removed Pass

Black-box testing, which simulates end-user interactions, is a primary method for validating system workflows. The testing process aims to confirm that all functional modules operate correctly according to design specifications and user requirements. The final test results demonstrate that the system meets functional and performance objectives.

The following Java code illustrates a login endpoint and token-based authentication interceptor:

// Login endpoint ignoring auth check
@IgnoreAuth
@PostMapping("/signin")
public Result loginUser(@RequestParam String uid,
                        @RequestParam String pwd,
                        HttpServletRequest req) {
    // Fetch user by username
    UserAccount account = accountService.query()
            .eq("username", uid).one();
    if (account == null || !account.getPassword().equals(pwd)) {
        return Result.error("Invalid credentials");
    }
    // Generate authentication token
    String authToken = tokenUtil.createToken(account.getId(),
                                             uid,
                                             account.getRole());
    return Result.ok().put("token", authToken);
}

// Token generation logic
public String createToken(Long userId,
                          String username,
                          String role) {
    // Check for existing token
    AuthToken existing = tokenDao.selectOne(new QueryWrapper<AuthToken>()
            .eq("user_id", userId).eq("role", role));
    String newToken = RandomStringUtils.randomAlphanumeric(32);
    Calendar expiry = Calendar.getInstance();
    expiry.add(Calendar.HOUR, 1);
    if (existing != null) {
        existing.setTokenValue(newToken);
        existing.setExpiryTime(expiry.getTime());
        tokenDao.updateById(existing);
    } else {
        AuthToken newRecord = new AuthToken();
        newRecord.setUserId(userId);
        newRecord.setUsername(username);
        newRecord.setRole(role);
        newRecord.setTokenValue(newToken);
        newRecord.setExpiryTime(expiry.getTime());
        tokenDao.insert(newRecord);
    }
    return newToken;
}

// Authentication interceptor
@Component
public class AuthInterceptor implements HandlerInterceptor {
    public static final String AUTH_HEADER = "X-Auth-Token";
    @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 false;
        }
        IgnoreAuth ignoreAuth = null;
        if (handler instanceof HandlerMethod) {
            ignoreAuth = ((HandlerMethod) handler)
                    .getMethodAnnotation(IgnoreAuth.class);
        }
        // Bypass auth for methods annotated with @IgnoreAuth
        if (ignoreAuth != null) {
            return true;
        }
        String token = request.getHeader(AUTH_HEADER);
        AuthToken tokenEntity = tokenService.getByToken(token);
        if (tokenEntity != null) {
            // Store user context in request session
            request.getSession().setAttribute("userId",
                    tokenEntity.getUserId());
            request.getSession().setAttribute("role",
                    tokenEntity.getRole());
            return true;
        }
        // Authentication failed
        response.setContentType("application/json;charset=UTF-8");
        try (PrintWriter out = response.getWriter()) {
            out.write(JSON.toJSONString(
                Result.error(401, "Authentication required")));
        }
        return false;
    }
}

The @IgnoreAuth annotation marks endpoints that do not require authentication, such as login. The login endpoint validates user credentials and issues a token. The AuthInterceptor checks for a valid token in the request header for protected endpoints, returning a 401 error if authentication fails.

A sample database table for storing product information is defined as follows:

CREATE TABLE `product` (
    `id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'Primary Key',
    `product_name` VARCHAR(200) NOT NULL COMMENT 'Product Name',
    `unit_price` DECIMAL(12,2) NOT NULL COMMENT 'Price',
    `details` TEXT COMMENT 'Description',
    `inventory` INT NOT NULL DEFAULT 0 COMMENT 'Stock Quantity',
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Product Catalog';

This table includes fields for product ID, name, price, description, stock level, and timestamps for creation and updates.

Sample data insertion:

INSERT INTO `product` (`product_name`, `unit_price`, `details`, `inventory`)
VALUES ('Wireless Headphones', 89.99, 'Noise-cancelling over-ear headphones', 200);

INSERT INTO `product` (`product_name`, `unit_price`, `details`, `inventory`)
VALUES ('Laptop Stand', 34.50, 'Adjustable aluminum stand', 150);

Related Articles

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

SBUS Signal Analysis and Communication Implementation Using STM32 with Fus Remote Controller

Overview In a recent project, I utilized the SBUS protocol with the Fus remote controller to control a vehicle's basic operations, including movement, lights, and mode switching. This article is aimed...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.