1. 项目背景与意义
高校和科研院所的实验室设备普遍存在「利用率不均衡、管理分散、预约靠人工、使用记录难追溯」等问题。部分高价值设备长期闲置,而其他团队急需使用却找不到设备入口;设备借用、归还、维护状态依赖线下登记,信息不透明,容易产生冲突和损耗。
实验室设备共享平台旨在通过信息化手段解决上述痛点,实现设备资源的统一登记、在线检索、预约审批、使用记录与统计管理。其意义主要体现在三个方面:
- 提升设备利用率:让闲置设备被更多团队发现和使用,减少重复采购,节约经费。
- 规范管理流程:预约、审批、使用、归还全流程线上化,责任清晰、记录可追溯。
- 支撑数据决策:基于使用频次、设备状态等统计数据,为设备采购和维护提供依据。
2. 技术栈选型
本平台采用前后端分离架构,后端基于 Spring Boot 构建 RESTful API,前端使用 Vue 3 + Element Plus 实现管理界面,数据存储选用 MySQL,缓存与分布式会话使用 Redis。
| 层次 | 技术选型 | 说明 |
|---|---|---|
| 后端框架 | Spring Boot 2.7 / 3.x | 快速构建独立运行的微服务应用 |
| 持久层 | Spring Data JPA / MyBatis-Plus | 对象关系映射与通用 CRUD 封装 |
| 数据库 | MySQL 8.0 | 存储用户、设备、预约、使用记录等业务数据 |
| 缓存 | Redis | 设备状态缓存、验证码、热点数据 |
| 安全认证 | Spring Security + JWT | 登录鉴权与接口访问控制 |
| 前端 | Vue 3 + Element Plus + Axios | 管理后台与用户端界面 |
| 接口文档 | Knife4j / Swagger | 在线调试与接口说明 |
| 构建工具 | Maven | 依赖管理与项目构建 |
3. 系统功能模块设计
平台按角色划分为管理员、设备管理员和普通用户三类,核心功能模块如下:
- 用户管理:注册登录、个人信息维护、角色权限分配。
- 设备管理:设备信息录入、分类维护、状态管理(可用、预约中、维护中、已报废)。
- 预约管理:用户提交预约申请,设备管理员审批,支持时间段冲突校验。
- 使用记录:设备借用、归还登记,自动生成使用流水。
- 公告与消息:平台公告发布,预约审批结果通知。
- 数据统计:设备使用率、预约频次、故障率等统计图表。
4. 数据库设计
核心数据表包括用户表、设备表、设备分类表、预约单表和使用记录表。下面给出主要表结构说明。
| 表名 | 主要字段 | 说明 |
|---|---|---|
| sys_user | id, username, password, real_name, role, phone, email | 用户与角色信息 |
| device | id, name, category_id, location, status, price, purchase_date, description | 设备基础信息与状态 |
| device_category | id, name, remark | 设备分类 |
| reservation | id, device_id, user_id, start_time, end_time, purpose, status, approver_id | 预约申请与审批状态 |
| usage_record | id, reservation_id, device_id, user_id, borrow_time, return_time, remark | 设备使用流水 |
5. 核心代码实现
5.1 项目依赖配置
在 pom.xml 中引入 Web、JPA、Security、Redis 等核心依赖。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency>5.2 设备实体类
设备实体映射 device 表,使用 JPA 注解定义字段与枚举状态。
@Entity @Table(name = "device") public class Device { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false, length = 100) private String name; @Column(name = "category_id") private Long categoryId; @Column(length = 200) private String location; @Enumerated(EnumType.STRING) @Column(length = 20) private DeviceStatus status; private BigDecimal price; @Column(name = "purchase_date") private LocalDate purchaseDate; @Column(length = 500) private String description; // getter 和 setter 省略 }5.3 预约冲突校验
提交预约时,需要校验同一设备在目标时间段内是否已被占用。这里通过查询重叠区间实现。
@Service public class ReservationService { @Autowired private ReservationRepository reservationRepository; public boolean isTimeSlotAvailable(Long deviceId, LocalDateTime start, LocalDateTime end) { List<Reservation> conflicts = reservationRepository.findConflicting( deviceId, start, end, ReservationStatus.APPROVED); return conflicts.isEmpty(); } @Transactional public Reservation createReservation(Reservation reservation) { if (!isTimeSlotAvailable(reservation.getDeviceId(), reservation.getStartTime(), reservation.getEndTime())) { throw new BusinessException("该设备在所选时间段已被预约"); } reservation.setStatus(ReservationStatus.PENDING); return reservationRepository.save(reservation); } }5.4 预约查询 Repository
使用 JPQL 查询与目标时间段存在重叠的已通过预约记录。
public interface ReservationRepository extends JpaRepository<Reservation, Long> { @Query("SELECT r FROM Reservation r WHERE r.deviceId = :deviceId " + "AND r.status = :status " + "AND r.startTime < :end AND r.endTime > :start") List<Reservation> findConflicting(@Param("deviceId") Long deviceId, @Param("start") LocalDateTime start, @Param("end") LocalDateTime end, @Param("status") ReservationStatus status); }5.5 设备状态更新
设备管理员审批通过预约后,将设备状态更新为「预约中」,并在归还后恢复为「可用」。
@Service public class DeviceService { @Autowired private DeviceRepository deviceRepository; @Transactional public void updateDeviceStatus(Long deviceId, DeviceStatus status) { Device device = deviceRepository.findById(deviceId) .orElseThrow(() -> new BusinessException("设备不存在")); device.setStatus(status); deviceRepository.save(device); } }5.6 JWT 登录认证
用户登录成功后签发 JWT,后续请求通过过滤器解析令牌并设置安全上下文。
@Service public class AuthService { @Autowired private UserRepository userRepository; @Autowired private JwtUtil jwtUtil; public String login(String username, String password) { User user = userRepository.findByUsername(username) .orElseThrow(() -> new BusinessException("用户不存在")); if (!passwordEncoder.matches(password, user.getPassword())) { throw new BusinessException("密码错误"); } return jwtUtil.generateToken(user.getId(), user.getRole()); } }6. 总结
基于 Spring Boot 的实验室设备共享平台,通过设备管理、预约审批、使用记录和统计报表等模块,有效提升了实验室设备的流转效率和管理透明度。项目采用前后端分离架构,后端以 Spring Boot 为核心,结合 JPA、Redis 和 JWT 实现稳定的业务能力与安全控制。后续可进一步扩展设备借用计费、IoT 设备状态采集、消息通知等能力,使平台更加完善。