尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

实验室工位申请系统删减方案:单体SpringBoot加Vue两表驱动的八周实现

实验室工位申请系统删减方案:单体SpringBoot加Vue两表驱动的八周实现 在第 4 周遇到进程通信死锁或前端数据格式对不上通常不是代码语法没学扎实而是最初在架构图上画了太多异构节点。当系统既需要 Spring Boot 处理业务又指望 Python 脚本跑相似度计算还要加上 Redis 做缓存时一个单人维护的毕设项目就已经处于失控边缘。图落地路径示意 · 两表驱动核心流转状态机厘清申请单与工位在审批全周期的状态跃迁图系统架构示意 · 八周收敛单体落地架构展示剥离Redis与外部脚本后的极简技术栈图请求调用链 · 跨进程调用卡死断点说明Java拉起脚本导致主线程阻塞的失败链路实验室工位申请这个典型题目按八周周期落地时唯一推荐的基准是单体 Spring Boot 3.x Vue 3单管理端 MySQL 8.0。不用微服务不跨语言拉起子进程把所有状态检查放在数据库行锁与单体事务内完成。一次把Python嵌入Java调用的死胡同记录最初的设计试图在工位分配时引入一段 Python 脚本根据学生所属课题组、打卡频次历史计算「最佳工位推荐指数」。Java 端使用ProcessBuilder跨进程调用本地 Python 脚本并捕获标准输出。在第 3 周本地联调时暴露出致命卡点本地开发环境的 Python 依赖了特定版本的pandas与numpy当打包到测试环境时路径差异和子进程并发执行导致标准输出流阻塞主线程直接挂起超过 30 秒无响应。排查跨语言调用、编码异常和环境一致性耗费了近两周时间。复盘后彻底停掉了这种混合方案。后续直接删去 Python 脚本与动态推荐逻辑工位分配改回纯关系型约束学生前端直接选定具体空闲工位后端仅做单一时间段的状态占用校验。跨进程调用在这里带来的工程维护成本远超算法本身在答辩演示里的加分项。复杂方案与收缩方案的实现基线为了保证系统在第 8 周具备完整的可演示状态必须把工位预约过程中的衍生需求压到最低。下表为功能收缩前后的对照边界维度复杂方案易延期8周收敛基线推荐工位分配机制Python 离线脚本根据历史考勤跑协同过滤推荐前端展示网格图学生自选工位后端校验冲突并发冲突控制Redis 分布式锁 延时队列释放工位MySQLSELECT ... FOR UPDATE或乐观锁版本号角色与权限学生、导师、系管理员、系统运维四套角标学生与实验室管理员两套角色单表维护字段核心表设计工位表、排班表、申请表、审批流表、日志表8张仅保留工位基础表与工位申请单表2张核心表驱动答辩演示路径依赖外部模拟脚本灌入虚构推荐分管理员录入工位 - 学生发起申请 - 管理员审核通过核心数据表与状态流转实现整个业务由两张核心表驱动lab_seat工位状态与seat_application申请单。工位状态只定义三种0-空闲、1-占用、2-维护。申请单状态定义四种0-待审核、1-已同意、2-已拒绝、3-已撤销。以下为可运行的最小核心表结构基于 MySQL 8.0 语法CREATE TABLE lab_seat ( id BIGINT AUTO_INCREMENT PRIMARY KEY, seat_no VARCHAR(32) NOT NULL UNIQUE COMMENT 工位编号如 A1-01, room_name VARCHAR(64) NOT NULL COMMENT 所属实验室房间, status TINYINT NOT NULL DEFAULT 0 COMMENT 0:空闲 1:占用 2:维护, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE seat_application ( id BIGINT AUTO_INCREMENT PRIMARY KEY, seat_id BIGINT NOT NULL COMMENT 关联合同工位ID, student_id BIGINT NOT NULL COMMENT 申请学生ID, reason VARCHAR(255) DEFAULT COMMENT 申请原因, apply_status TINYINT NOT NULL DEFAULT 0 COMMENT 0:待审核 1:已同意 2:已拒绝 3:已撤销, start_date DATE NOT NULL COMMENT 占用起始日期, end_date DATE NOT NULL COMMENT 占用结束日期, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, INDEX idx_seat_date (seat_id, start_date, end_date) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;后端审批状态防并发代码在审核同意申请时必须保证同一工位在有效周期内不能被两人同时占有。单体架构下直接利用行锁完成状态判定与变更避免引入缓存组件造成数据不一致。以下为 Spring Boot 3 中通过事务控制工位审批的核心实现示例代码基于 Spring Data JPA 或 MyBatis 原生 SQL 均适用Service public class SeatApplicationService { Autowired private SeatApplicationMapper applicationMapper; Autowired private LabSeatMapper seatMapper; Transactional(rollbackFor Exception.class) public boolean approveApplication(Long applicationId) { // 1. 悲观锁锁定申请单获取当前处理对象 SeatApplication apply applicationMapper.selectByIdForUpdate(applicationId); if (apply null || apply.getApplyStatus() ! 0) { throw new IllegalStateException(申请单不存在或已被处理); } // 2. 检查工位当前是否已被他人有效占用日期区间重叠检查 int conflictCount applicationMapper.countActiveConflicts( apply.getSeatId(), apply.getStartDate(), apply.getEndDate() ); if (conflictCount 0) { throw new IllegalStateException(该时间段内该工位已被分配); } // 3. 翻转当前申请单状态为已同意 apply.setApplyStatus(1); applicationMapper.updateById(apply); // 4. 同步变更工位表的主状态为占用 seatMapper.updateSeatStatus(apply.getSeatId(), 1); return true; } }8周推进计划排期整个毕设生命周期不留模糊的弹性时间严格按天推进核心流转链条1.第 1 周业务字段收缩与建表放弃所有用户画像、人脸识别或协同过滤插件完成lab_seat、seat_application、sys_user三张表的物理落地配置好 Spring Boot 连接池。2.第 2 周认证与基础骨架引入基础的 JWT 拦截器或 Spring Security 最小化配置打通学生与管理员登录接口返回角色 Token前端配置好单路由守卫。3.第 3 周工位网格与基础维护接口实现工位列表查询与基础增删改查。前端使用普通的栅格组件如 Element Plus 中的el-row/el-col渲染出房间工位平面图仅用红灰绿三色反映空闲状态。4.第 4 周申请主流程打通完成学生端提交工位使用申请、时间段传参以及个人历史列表查询。此时暂不接复杂审批规则只做表数据插入。5.第 5 周审批事务与冲突校验落地将上述approveApplication逻辑挂载到管理员端完成冲突判定的 SQL 联调验证并发提交时的拦截反馈。6.第 6 周退租、释放与自动过期加入学生主动撤回与管理员手动释放逻辑。使用一个极轻量的单体Scheduled定时任务在每天凌晨扫描将到达end_date的工位还原为空闲。7.第 7 周全链路联调与异常页面补充封板后端所有接口。前端集中补充表单校验、403 无权限拦截弹窗与申请失败的友好提示不再增加新字段。8.第 8 周演示流程演练与论文图表截取准备两套测试账号学生端 student01管理端 admin。按预设流程走通申请 - 审核通过 - 状态变更 - 到期释放依据实际库表截取真实 ER 图和操作流程图。边界与切换条件此方案成立的前提是答辩核心指标是业务完整性与工单流转逻辑而非分布式高并发压力测试。如果在开题阶段导师明确要求系统支撑万人级秒抢工位且必须提交基于 JMeter 的 5000 QPS 压测报告那么上述单体数据库锁方案必须收回。只有在这种明确的非功能性指标约束下才允许引入 Redis 预扣减与消息队列异步落库否则不建议在单人八周内主动增加这些外部依赖。
返回列表