网站首页/ 信息中心/ 行业信息/

档案预约系统实战指南:从零搭建可扩展的预约服务

发布时间:2026年06月28日 02:30:26 浏览量:0

一、系统核心架构设计

我们采用前后端分离的架构,前端使用Vue 3,后端使用Spring Boot,数据库使用MySQL。这种组合能确保系统易于维护和扩展。

1.1 数据库设计

创建以下核心表结构:

```sql -- 用户表 CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) UNIQUE NOT NULL, password VARCHAR(100) NOT NULL, real_name VARCHAR(50) NOT NULL, phone VARCHAR(20) NOT NULL, email VARCHAR(100), role ENUM('user', 'admin') DEFAULT 'user', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 档案类型表 CREATE TABLE archive_types ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100) NOT NULL, description TEXT, max_daily_slots INT DEFAULT 20, appointment_duration INT DEFAULT 30, -- 分钟 is_active BOOLEAN DEFAULT true ); -- 预约时间段表 CREATE TABLE time_slots ( id INT PRIMARY KEY AUTO_INCREMENT, archive_type_id INT NOT NULL, slot_date DATE NOT NULL, start_time TIME NOT NULL, end_time TIME NOT NULL, max_capacity INT DEFAULT 1, current_bookings INT DEFAULT 0, is_available BOOLEAN DEFAULT true, FOREIGN KEY (archive_type_id) REFERENCES archive_types(id), UNIQUE KEY unique_slot (archive_type_id, slot_date, start_time) ); -- 预约记录表 CREATE TABLE appointments ( id VARCHAR(20) PRIMARY KEY, -- AP202401010001格式 user_id INT NOT NULL, time_slot_id INT NOT NULL, archive_type_id INT NOT NULL, status ENUM('pending', 'confirmed', 'completed', 'cancelled') DEFAULT 'pending', purpose TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id), FOREIGN KEY (time_slot_id) REFERENCES time_slots(id), FOREIGN KEY (archive_type_id) REFERENCES archive_types(id) ); ```

二、后端服务搭建

2.1 项目初始化

使用Spring Initializr创建项目,选择以下依赖:

```xml org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-data-jpa mysql mysql-connector-java 8.0.33 org.springframework.boot spring-boot-starter-security io.jsonwebtoken jjwt 0.9.1 ```

2.2 应用配置文件

在application.yml中配置:

```yaml server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/archive_booking?useSSL=false&serverTimezone=UTC username: root password: your_password driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true properties: hibernate: dialect: org.hibernate.dialect.MySQL8Dialect app: jwt: secret: your_jwt_secret_key_here_minimum_32_chars expiration: 86400000 24小时 ```

2.3 核心业务逻辑实现

创建预约服务类:

档案预约系统实战指南:从零搭建可扩展的预约服务

```java @Service public class AppointmentService { @Autowired private TimeSlotRepository timeSlotRepository; @Autowired private AppointmentRepository appointmentRepository; @Transactional public Appointment createAppointment(Integer userId, Integer timeSlotId, Integer archiveTypeId, String purpose) { // 检查时间段是否可用 TimeSlot timeSlot = timeSlotRepository.findById(timeSlotId) .orElseThrow(() -> new RuntimeException("时间段不存在")); if (!timeSlot.isAvailable() || timeSlot.getCurrentBookings() >= timeSlot.getMaxCapacity()) { throw new RuntimeException("该时间段已满"); } // 生成预约编号 String appointmentNo = "AP" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + String.format("%04d", getDailySequence()); // 创建预约记录 Appointment appointment = new Appointment(); appointment.setId(appointmentNo); appointment.setUserId(userId); appointment.setTimeSlotId(timeSlotId); appointment.setArchiveTypeId(archiveTypeId); appointment.setPurpose(purpose); appointment.setStatus("pending"); // 更新时间段预约数量 timeSlot.setCurrentBookings(timeSlot.getCurrentBookings() + 1); if (timeSlot.getCurrentBookings() >= timeSlot.getMaxCapacity()) { timeSlot.setAvailable(false); } timeSlotRepository.save(timeSlot); return appointmentRepository.save(appointment); } private synchronized int getDailySequence() { // 实现每日序列号生成逻辑 return sequenceService.getNextDailySequence(); } } ```

2.4 时间段自动生成

创建定时任务,每天自动生成未来7天的时间段:

```java @Component public class TimeSlotGenerator { @Autowired private ArchiveTypeRepository archiveTypeRepository; @Autowired private TimeSlotRepository timeSlotRepository; @Scheduled(cron = "0 0 2 ?") // 每天凌晨2点执行 public void generateTimeSlots() { LocalDate startDate = LocalDate.now().plusDays(1); LocalDate endDate = LocalDate.now().plusDays(7); List activeTypes = archiveTypeRepository.findByIsActiveTrue(); for (ArchiveType type : activeTypes) { for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) { // 跳过周末 if (date.getDayOfWeek() == DayOfWeek.SATURDAY || date.getDayOfWeek() == DayOfWeek.SUNDAY) { continue; } generateDailySlots(type, date); } } } private void generateDailySlots(ArchiveType type, LocalDate date) { int slotDuration = type.getAppointmentDuration(); int maxSlots = type.getMaxDailySlots(); LocalTime startTime = LocalTime.of(9, 0); // 上午9点开始 LocalTime endTime = LocalTime.of(17, 0); // 下午5点结束 int slotCount = 0; LocalTime current = startTime; while (current.isBefore(endTime) && slotCount < maxSlots) { LocalTime slotEnd = current.plusMinutes(slotDuration); TimeSlot slot = new TimeSlot(); slot.setArchiveTypeId(type.getId()); slot.setSlotDate(date); slot.setStartTime(current); slot.setEndTime(slotEnd); slot.setMaxCapacity(1); slot.setCurrentBookings(0); slot.setAvailable(true); timeSlotRepository.save(slot); current = slotEnd; slotCount++; } } } ```

三、前端界面开发

3.1 Vue项目初始化

创建Vue项目并安装必要依赖:

```bash npm create vue@latest archive-booking-system cd archive-booking-system npm install npm install axios vue-router@4 pinia element-plus ```

3.2 预约日历组件

创建预约日历组件:

```vue ```

3.3 预约表单组件

创建预约确认表单:

```vue