Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Building a Smart Study Space: Developing a Seat Reservation and Access Control System with Spring Boot and WeChat Mini-Programs

Tech 1

Backend Architecture with Spring Boot

Spring Boot serves as the backbone for the study room management system, providing a robust environment for micro-services and RESTful API development. Its primary advantage lies in its opinionated configuration, which eliminates the need for manual boilerplate setup. By utilizing embedded containers like Tomcat or Undertow, the application can be deployed as a standalone JAR, significantly simplifying the CI/CD pipeline.

The following example demonstrates a centralized controller managing study room availability. This approach uses the @RestController annotation to handle asynchronous requests from the WeChat Mini-Program client.

package com.studyroom.api;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
@RequestMapping("/api/v1/spaces")
public class StudySpaceApplication {

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

    @GetMapping("/availability")
    public Map<String, Object> checkSeatStatus() {
        Map<String, Object> status = new HashMap<>();
        status.put("totalSeats", 50);
        status.put("available", 12);
        status.put("timestamp", System.currentTimeMillis());
        return status;
    }
}

Frontend Componentization with Vue.js

In the management dashboard, Vue.js is employed to create a reactive user interface. The framework's core strength is its virtual DOM and component-based architecture, which ensures that UI updates are localized and efficient. When a user reserves a seat, Vue's data-binding mechanism reflects the state change across the dashboard without a full page reload.

Below is a simplified Vue component illustrating seat selection logic:

<div id="seat-manager">
  <h3>Study Zone A - Layout</h3>
  <div v-for="seat in seatList" :key="seat.id">
    <button 
      :class="{ 'occupied': seat.isTaken }" 
      @click="toggleSeat(seat)">
      Seat #{{ seat.code }}
    </button>
  </div>
</div>

<script>
  new Vue({
    el: '#seat-manager',
    data: {
      seatList: [
        { id: 1, code: 'A01', isTaken: false },
        { id: 2, code: 'A02', isTaken: true }
      ]
    },
    methods: {
      toggleSeat(item) {
        if (!item.isTaken) {
          item.isTaken = true;
          console.log("Seat " + item.code + " reserved.");
        }
      }
    }
  });
</script>

Data Persistence via MyBatis

To bridge the gap between the Java domain model and the relational database, MyBatis is utilized as the persistence layer. Unlike traditional ORMs that generate complex SQL, MyBatis provides full control over query execution through XML or annotation-based mapping. This is particularly useful for optimizing complex queries involved in seat scheduling and access log analysis.

Key features include:

  1. SQL Decoupling: Business logic remains separate from database queries.
  2. Dynamic SQL: Queries can be modified at runtime based on parameters like user roles or time slots.
  3. Caching: Internal caching mechanisms reduce database load during high-traffic booking windows.

Authentication and Access Control Logic

Security is enforced using a token-based authentication system. When a user logs in via the WeChat interface, the backend validates credentials and issues a unique access key. An interceptor then validates this key for every subsequent request to ensure the user has the necessary permissions to access specific study rooms.

@Component
public class SecurityGateInterceptor implements HandlerInterceptor {

    @Autowired
    private SessionManager sessionManager;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // Handle pre-flight requests for CORS
        if (RequestMethod.OPTIONS.name().equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        }

        String accessKey = request.getHeader("X-Auth-Token");
        
        // Skip validation for methods annotated with @PublicAccess
        if (handler instanceof HandlerMethod) {
            if (((HandlerMethod) handler).hasMethodAnnotation(PublicAccess.class)) {
                return true;
            }
        }

        if (accessKey != null && sessionManager.validate(accessKey)) {
            UserSession session = sessionManager.getSessionData(accessKey);
            request.setAttribute("currentUser", session.getUserId());
            return true;
        }

        response.sendError(401, "Unauthorized: Please log in.");
        return false;
    }
}

System Verification and Testing

Comprehensive testing ensures the reliability of the booking flow and the access control hardware integration. Functional testing involves verifying boundary conditions, such as concurrent booking atempts for the same seat or invalid access attempts outside of reserved hours.

Sample Test Case: User Authentication

Input Scenarios Expected Outcome Actual Result Verification
Valid credentials Token issued; redirect to map Success Match
Incorrect password Error message: "Invalid ID/Pass" Error displayed Match
Empty username Validation prompt Prompt shown Match
Expired token access 401 Unauthorized status Redirect to login Match

Database Schema Design

A structured database is required to track seat status, user reservations, and door logs. Below is a schema for the seat management table:

CREATE TABLE `study_room_seats` (
  `seat_id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `room_label` VARCHAR(50) NOT NULL COMMENT 'Room Identifier',
  `seat_number` INT(11) NOT NULL,
  `current_status` TINYINT(1) DEFAULT 0 COMMENT '0: Free, 1: Occupied',
  `last_update` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`seat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- Example Seed Data
INSERT INTO `study_room_seats` (`room_label`, `seat_number`, `current_status`) 
VALUES ('Quiet Zone', 101, 0), ('Collaboration Hub', 205, 1);

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

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.