ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

SpringBoot汉服租赁展示平台:从零搭建完整管理系统

SpringBoot汉服租赁展示平台:从零搭建完整管理系统

又到毕业季选题的时候,总有人来问我:Java 毕设选什么题比较稳?我的回答基本一致:技术栈一定要带上 SpringBoot,业务方向最好选有真实场景、看上去不“烂大街”、又有扩展空间的。今天聊的这套“基于 SpringBoot 的汉服租赁与展示平台”,就是我在整理历届毕设项目时比较推荐的方向,也适合那些想从零完整做一套管理系统、把前后端链路跑通的开发者。

一套项目,名字可能不同,有些叫“汉服租赁与展示平台”,有些叫“汉服租赁管理系统”,其实核心都指向同一个东西:面向用户的汉服展示门户 + 租赁下单链路 + 面向管理员的后台管理。汉服已经从圈层文化走向大众消费场景,租赁这个模式又天然契合“低频高价、仪式感强”的消费习惯。作为毕设题目,它比普通的“学生管理系统”“图书管理系统”更有辨识度,但技术难度又没有超出应届生能驾驭的范围:CRUD 要做,业务状态要设计,并发问题要处理,前端界面还能做得很漂亮。这套项目既能体现业务建模能力,又能体现工程实践能力,是那种“答辩时能讲出东西来”的题目。

这套东西适合谁?首先是 Java 方向做毕设的同学,拿题目直接做或二次开发都行;其次是已经学完 SpringBoot 基础、想找一套完整项目练手的初学者;再就是准备求职面试、需要一个“有完整业务闭环”的项目写在简历上的朋友。接下来我把从选题拆解、表结构设计到核心代码实现和问题排查的完整过程都理一遍,偏向可以直接照着动手的实操路线。

1. 毕设选题思路拆解:汉服租赁平台到底要解决什么问题

1.1 从项目标题里拆出的三个核心关键词

拿到这个题目,先别急着写代码,先拆关键词。“SpringBoot”是技术底座,“汉服租赁”是业务核心,“展示平台”是交互形态。连起来理解就是:要用 SpringBoot 技术栈搞一个线上平台,用户能够在上面浏览汉服、查看详情、选择租赁档期、下单付款,管理员则能在后台维护服装信息、审核订单、处理归还和验收。

很多同学一看到“平台”两个字就发怵,觉得是不是要做成淘宝那样。实际上毕设级别的“平台”不需要那么复杂,只要把三种角色、三条流程跑通就够了。游客能浏览公开的汉服列表和详情;注册用户能登录、租赁、查看自己的订单;管理员能管理分类、服装、订单和用户公告。这三条线串起来,就是一个功能完整体面、业务逻辑清晰的管理系统。

再往后拆,还能拆成两个子系统:用户端门户和管理端后台。用户端重点在“浏览体验”和“下单链路”,要的是筛选方便、详情清楚、订单状态直观;管理端重点在“数据维护”和“运营操作”,要的是增删改查顺手、状态流转不出错。毕设答辩时老师最关心的往往不是页面多好看,而是这套业务逻辑有没有想清楚,数据表之间的关系能不能自圆其说。

1.2 为什么选“汉服租赁”而不是其他业务

选题这件事,我个人建议遵循三个原则:业务有真实场景、自己讲得清楚、代码量控制在能独立完成的范围。汉服租赁恰好三条都占。

第一,真实场景存在。汉服单件购买成本高,很多人只在演出、写真、节日活动、漫展穿一次,买一套不划算,租赁就成了刚需。租赁平台要解决的核心问题不是“卖”,而是“在某段时间内这件衣服是否可租、租金多少、押金多少、什么时候还”。这个业务逻辑比单纯卖货多了一层“时间维度”,做起来有东西可写。

第二,自己讲得清楚。我们不陌生,周围人也知道汉服是什么。向评委介绍项目时,不需要铺垫大段行业背景,直接说“用户选衣服、选档期、下单、管理员发货、到期提醒归还、验收完成”,评委立刻就能理解。

第三,代码量可控。业务不涉及复杂的支付对账、物流追踪、多级分销,核心就一张业务订单表加一张订单明细表。这个复杂度对学生来说是恰到好处的“跳一跳够得着”:太简单显得水,太难容易做不完。

1.3 核心业务闭环与功能模块地图

我把这套平台的核心业务流程整理成了一条主链路:浏览汉服 -> 收藏或加入租赁单 -> 选择租赁起止日期 -> 提交订单 -> 模拟支付 -> 管理员发货 -> 用户确认收货 -> 穿着使用 -> 到期归还 -> 管理员验收 -> 订单完成 -> 用户评价。整条链路环环相扣,每一环对数据库字段的变更都有要求,这就是项目最有价值的部分。

围绕这条主链路,功能模块可以分成两大块:

模块面向角色核心功能
门户展示端游客、注册用户汉服分类浏览、关键词搜索、列表分页、详情展示、图片预览、收藏、加入租赁单、提交订单、订单状态查询、个人资料维护、评价
后台管理端管理员管理员登录、仪表盘统计、汉服分类管理、汉服信息维护、库存管理、订单审核与状态推进、用户管理、租赁归还验收、公告发布

这里有一个容易被忽略的点:租赁单和购物车不一样。购物车买的是商品,租赁单要记录“起租日期”和“归还日期”。所以设计数据库时,租赁单表不仅要存服装 ID、数量,还要单独存两个日期字段,这是这个项目和普通商城系统最大的区别。后面讲表结构的时候我会再展开。

2. 技术选型与框架设计思路:为什么是 SpringBoot 这个组合

2.1 技术栈清单与选型理由

这个项目我建议的技术栈组合如下,每一项都有它出现在这里的理由:

  • 后端:SpringBoot 2.7.x + MyBatis Plus + Spring Validation
  • 权限认证:JWT(登录后签发令牌,无状态,前后端分离友好)
  • 数据库:MySQL 8.x + Redis(缓存热点汉服数据、存放 Token 黑名单或验证码)
  • 前端:Vue 3 + Element Plus + Axios(也可以直接用 Thymeleaf 服务端渲染)
  • 接口文档:SpringDoc / Swagger
  • 构建工具:Maven

SpringBoot 不用多说,约定优于配置,内嵌 Tomcat,一个 jar 包就能跑起来,生态成熟,遇到问题网上资料多。MyBatis Plus 是我比较推荐给毕设的持久层框架,它把单表 CRUD 封装好了,写业务时只需要关注多表查询和复杂条件,能省掉大量重复的 Mapper XML。JWT 无状态认证比 Session 更适合前后端分离,部署时不需要考虑会话保持,答辩时还能讲出一套“无状态服务”的设计理念。

Redis 在这个项目里不是必须的,但加上它能成为亮点。比如首页推荐汉服列表缓存、热门款式浏览次数统计、订单号生成时的计数器,都可以用 Redis 实现。使用 Redis 能让项目从“纯数据库 CRUD”晋升为“有缓存设计思想的系统”,成本不高,收益很明显。

2.2 前后端分离还是服务端渲染

我见过很多同学在这个问题上纠结。两种方案都能做,但我个人更推荐前后端分离:前端 Vue 打包后用 Nginx 或直接 node 静态服务部署,后端 SpringBoot 提供 JSON 接口。理由有三点:一是现在主流团队就是这么分工的,面试聊起来有话题;二是前端交互体验好,页面跳转不刷新,做展示平台更漂亮;三是后端代码只关注接口,可以专心把业务逻辑和表结构做扎实。

当然,如果时间特别紧,对 Vue 又不熟,用 SpringBoot + Thymeleaf 做服务端渲染也完全能完成毕设。只是要注意:服务端渲染会把页面控制逻辑散落在 HTML 模板里,后期改需求会有点痛苦。我的建议是:凡是有一点前端基础的同学,都尝试前后端分离,这是目前最贴近真实开发环境的做法。

2.3 分层架构与包结构规划

项目结构我强烈建议按职责分层,不要所有代码堆在一个包里。推荐包结构如下:

com.example.hanfu ├── config // 配置类:跨域、拦截器、Swagger、Redis ├── controller // 接口层:接收请求、参数校验、返回结果 ├── service // 业务层:核心逻辑 │ └── impl ├── mapper // MyBatis Plus Mapper接口 ├── entity // 数据库实体 ├── dto // 前端入参对象 ├── vo // 前端返回对象 ├── common // 统一返回体、异常、常量、枚举 └── utils // 工具类:JWT、日期处理等

这样的分层的核心价值在于:controller 只负责解析参数和返回结果,service 负责业务判断,mapper 只做数据库交互。答辩时老师问“订单状态在哪里判断”,你可以直接说在 service 层;问到“接口返回格式怎么统一”,可以指向 common 包里的统一返回类。结构清晰本身就是加分项。

3. 数据库设计:一张订单状态流转表如何撑起租赁核心链路

3.1 核心数据表概览

我设计这套项目的数据表时,最终保留了 9 张核心表,每张都有明确用途:

表名用途说明
user用户表,保存账号、密码密文、昵称、手机号、角色
category汉服分类表,如明制、宋制、唐制、魏晋风等
hanfu汉服表,名称、分类、图片、租金/天、押金、库存、状态
cart租赁单表(代替购物车),含起租日期和归还日期
orders订单主表,订单号、用户、总金额、押金、状态、下单时间
order_item订单明细表,订单关联的服装、数量、单价、时间段
comment评价表,用户对已经完成订单的汉服评价和评分
favorite收藏表,用户收藏的汉服
announcement公告表,展示平台公告

这 9 张表把“用户-服装-订单-评价”串成了一条线。其中最关键的是 orders 表的订单状态字段,以及 cart 表和 orders 表里的日期字段。面试或答辩时能把这几个字段的设计原因讲明白,整套项目的含金量立刻就不一样了。

3.2 几张核心表的建表 SQL 参考

下面给出 4 张核心表的简化版建表语句。注意我把密码、手机号、图片 URL、日期时间段都做了常规处理,实际建表时可以根据需求增加索引和注释。

CREATE TABLE `user` ( `id` bigint NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL COMMENT '登录名', `password` varchar(100) NOT NULL COMMENT '加密后的密码', `nickname` varchar(50) DEFAULT NULL COMMENT '昵称', `phone` varchar(20) DEFAULT NULL, `role` tinyint NOT NULL DEFAULT '1' COMMENT '1普通用户 2管理员', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表'; CREATE TABLE `hanfu` ( `id` bigint NOT NULL AUTO_INCREMENT, `category_id` bigint NOT NULL COMMENT '分类id', `name` varchar(100) NOT NULL, `cover_image` varchar(255) DEFAULT NULL COMMENT '封面图', `detail_images` text COMMENT '详情图,逗号分隔或JSON', `rent_price` decimal(10,2) NOT NULL COMMENT '每日租金', `deposit` decimal(10,2) NOT NULL COMMENT '押金', `stock` int NOT NULL DEFAULT '0' COMMENT '可租库存', `status` tinyint NOT NULL DEFAULT '1' COMMENT '1上架 0下架', `description` text, `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='汉服表'; CREATE TABLE `orders` ( `id` bigint NOT NULL AUTO_INCREMENT, `order_no` varchar(32) NOT NULL COMMENT '订单号', `user_id` bigint NOT NULL, `total_rent` decimal(10,2) NOT NULL COMMENT '租金总额', `total_deposit` decimal(10,2) NOT NULL COMMENT '押金总额', `status` tinyint NOT NULL DEFAULT '0' COMMENT '状态:0待支付 1待发货 2租赁中 3待归还 4已完成 5已取消', `start_date` date NOT NULL COMMENT '起租日期', `end_date` date NOT NULL COMMENT '归还日期', `rent_days` int NOT NULL COMMENT '租赁天数', `address` varchar(255) DEFAULT NULL COMMENT '收货地址', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_order_no` (`order_no`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单主表';

这里要注意一个细节:rent_days 这个字段应该在提交订单时就算好,不要每次用到时再去两个日期相减。因为租赁费用 = 每日租金 * 租赁天数,这个值在下单瞬间就要冻结,后续不允许随便变。很多新手在写统计报表时才发现天数没存,后面对账很麻烦。

3.3 订单状态机设计是项目的灵魂

订单状态是整个租赁平台最核心的业务逻辑。我的状态设计是:0 待支付 -> 1 待发货 -> 2 租赁中 -> 3 待归还 -> 4 已完成,外加 5 已取消。每个状态能触发什么动作,在 service 层必须写清楚:

  • 待支付:用户可以取消订单,也可以点击“模拟支付”,支付后状态变成待发货
  • 待发货:管理员发货后状态变成租赁中,此时租赁周期开始计算
  • 租赁中:到期前系统应提醒用户归还,用户提交归还申请或管理员确认收到后进入待归还
  • 待归还:管理员验收服装无损坏,确认归还,状态变成已完成
  • 已取消:只在待支付阶段允许,取消后服装库存要加回去

这个状态机看起来简单,但很多项目做不好就是因为没定规则:什么状态可以改成什么状态,谁有权限改,改了之后库存怎么变化。我建议用一个常量类或者枚举把状态定义清楚,然后在 service 层专门写状态校验方法。答辩时拿出状态流转图讲一讲,比自己说“我做了订单功能”有力得多。

3.4 租赁日期与库存冲突的预判

租赁业务和买卖业务最大的不同,在于服装在不同时间段的可用性不同。同一件汉服,7 月 1 日到 7 月 5 日被人租了,那 7 月 3 日别人再想租就冲突了。简单库存表只存一个总库存不够严谨,更合理的设计是记录每个租赁时间段。

做法是:在订单表确认支付时,把该汉服在对应时间段的占用记录存到一张“库存占用表”里;用户在下单时,需要校验该服装在所选时间段内是否已被占用。如果时间充裕,可以给汉服表加一个“总库存”字段,再配合 order_item 里对同一时间段的在途订单做查询校验。两者结合,既能满足毕设演示需求,也能体现你对并发冲突的思考。

4. 核心功能实操解析:从注册登录到租赁下单全流程

4.1 用户注册登录与 JWT 认证

用户模块是所有系统的入口,也是第一个要写的功能。密码存储不要用明文,至少用 BCrypt 加密。登录成功后签发 JWT,前端把 Token 存在 localStorage 里,每次请求在请求头带上Authorization: Bearer token,后端拦截器统一校验。这个方案比 Session 更适合前后端分离,也方便管理端接口保护。

核心实现里需要注意三点:一是拦截器要放行登录、注册、首页展示等公开接口,其余接口必须校验 Token;二是校验通过后要把当前用户 ID 解析出来放到请求上下文里,供后续业务获取当前登录人;三是非法 Token 要统一抛出未认证异常,返回约定的 JSON 格式,而不是直接把堆栈抛给前端。这三点做到位,整个认证链路就稳了。

4.2 汉服展示与条件筛选

门户首页展示汉服列表,需要支持分类筛选、关键词搜索、价格排序和分页。这一步用 MyBatis Plus 的分页插件非常方便。推荐做法是:搜索条件封装成一个查询对象,Mapper 层用 LambdaQueryWrapper 动态拼接条件,不需要写复杂 XML。

一个实用心得:列表接口不要select *,只返回 VO 里需要的字段。汉服详情包含多张详情图,如果列表页把详情图文本也查出来,网络传输和内存开销都不小。我用一个HanfuVO只放 id、名称、封面图、每日租金、押金、分类名和库存,详情接口再返回完整信息。这个优化虽小,但写进简历和答辩材料里能体现“有性能意识”。

4.3 租赁单、日期选择与金额计算

租赁单本质是“带日期的购物车”。用户点击“加入租赁单”时,前端要传三个关键参数:服装 id、起租日期、归还日期。后端在加入时就要校验日期合法性:归还日期必须晚于起租日期,且不能是过去的日期。提前在这里拦截,能避免后面一整套脏数据。

金额计算逻辑放在后端,不能信任前端传过来的总价。后端根据服装表的每日租金、押金和租赁天数计算租金总额和押金总额,这个做法的好处是防止有人恶意改前端价格。我在实际项目中见过不少订单金额为零的翻车案例,原因就是前端把价格传给了后端,后端直接入库。这个坑大家一定要避开,凡是涉及钱的数据,一律以后端计算为准。

4.4 创建订单的核心代码实现

下面这一段是创建订单的 service 核心逻辑,我没有写完整业务,只保留了最关键的几个步骤,方便大家理解处理顺序。

@Transactional public OrderVO createOrder(OrderCreateDTO dto, Long userId) { // 1. 校验租赁日期 if (dto.getStartDate().isBefore(LocalDate.now())) { throw new BusinessException("起租日期不能早于今天"); } if (!dto.getEndDate().isAfter(dto.getStartDate())) { throw new BusinessException("归还日期必须晚于起租日期"); } long days = ChronoUnit.DAYS.between(dto.getStartDate(), dto.getEndDate()); if (days <= 0) { throw new BusinessException("租赁天数不合法"); } // 2. 遍历租赁单明细,校验库存和占用 BigDecimal totalRent = BigDecimal.ZERO; BigDecimal totalDeposit = BigDecimal.ZERO; List<OrderItem> items = new ArrayList<>(); for (CartItemVO cartItem : dto.getItems()) { Hanfu hanfu = hanfuMapper.selectById(cartItem.getHanfuId()); if (hanfu == null || hanfu.getStatus() == 0) { throw new BusinessException("汉服已下架"); } // 并发安全:乐观锁校验库存或占用表校验,这里简化处理 int count = orderItemMapper.countOccupied(hanfu.getId(), dto.getStartDate(), dto.getEndDate()); if (count > 0) { throw new BusinessException("所选时间段库存不足"); } totalRent = totalRent.add(hanfu.getRentPrice().multiply(BigDecimal.valueOf(days))); totalDeposit = totalDeposit.add(hanfu.getDeposit()); // 组装明细 } // 3. 生成订单号并落库 String orderNo = generateOrderNo(); Orders order = new Orders(); order.setOrderNo(orderNo); order.setUserId(userId); order.setTotalRent(totalRent); order.setTotalDeposit(totalDeposit); order.setStatus(0); order.setStartDate(dto.getStartDate()); order.setEndDate(dto.getEndDate()); order.setRentDays((int) days); order.setAddress(dto.getAddress()); ordersMapper.insert(order); // 4. 批量保存明细,清空租赁单 orderItemService.saveBatch(items); cartService.clearUserCart(userId, dto.getCartIds()); return toVO(order); }

这个方法我加了一个@Transactional事务注解,理由很直接:创建主表、保存明细、清空租赁单是三个操作,任何一个失败都不能留下半张订单。事务是这里的基本保障,不是可选项。

4.5 库存并发问题与应对方案

答辩时很容易被问到一个问题:如果两个用户同时选中同一天同一件汉服,怎么办?这个问题的标准回答是:在数据库层面避免超卖。最简单的方式是使用乐观锁,在更新库存的 SQL 里带上 version 或库存条件,例如:

UPDATE hanfu SET stock = stock - 1 WHERE id = ? AND stock > 0 AND version = ?

如果更新影响行数为 0,说明库存被别人抢了,当前请求就可以抛出“手慢了”的提示。更严谨的方案是在上面提到的占用表里对汉服 ID 和日期段加唯一约束或使用数据库唯一索引,防止同一时间段插入两条占用记录。毕设阶段能做乐观锁已经足够了,能说出思路就比很多人强。

4.6 管理员端:审核、发货、归还验收

管理员端不用写太多复杂花样,把订单状态机管好就行。我的建议是后台订单列表默认按状态筛选,管理员可以对“待发货”的订单执行发货操作,对“待归还”的订单执行验收完成操作。每次状态变更都在 service 层记录操作时间和操作人,方便追溯。

归还验收这里有一个小细节:如果验收时发现服装损坏需要扣款,可以设计一个“损坏赔偿”字段,在验收时录入扣款金额。不是所有租赁项目都需要这个功能,但加上以后业务完整性更强,答辩时能多讲一个场景:押金退还和损坏赔偿的关联逻辑。这个业务闭环是加分项。

5. 实操运行与功能调试记录:把整套项目跑起来的完整步骤

5.1 本地开发环境准备

项目要跑起来,环境版本建议对齐,我用的这套配置是:JDK 1.8 或 JDK 11、Maven 3.6+、MySQL 8.0、Redis 6.x、Node.js 16+。用新版本 JDK 时注意 SpringBoot 2.7 的兼容性,如果出现模块访问报错,直接切回 JDK 8 最省心。

数据库连接配置写在application.yml里,我用的是常见配置,只需要把用户名密码改成自己的:

server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/hanfu_rental?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver redis: host: localhost port: 6379 jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 mybatis-plus: mapper-locations: classpath*:/mapper/**/*.xml configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

这里有一个非常容易踩的坑:MySQL 连接 URL 里的serverTimezone参数。如果写成 UTC,查询出来的时间会比北京时间早 8 小时,订单时间、创建时间全部对不上。我统一用Asia/Shanghai,同时 JVM 启动参数也加上-Duser.timezone=Asia/Shanghai,双保险。

5.2 初始化数据库和默认数据

运行项目前先建库导入 SQL。我习惯把建表语句和初始化数据分开两个脚本,初始化数据里包含一个管理员账号、几个分类、十几套汉服样例以及两条不同状态的演示订单。这样一启动就有数据可看,不用自己一条条录。

管理员账号密码建议写成:admin / 123456,密码用 BCrypt 加密后存入数据库。注意不要直接插明文,否则登录时 BCrypt 比对永远不通过。如果从公众号或网盘下载的源码运行不起来,七成问题出在数据库脚本没正确导入,其次是 Redis 没启动。

5.3 启动顺序与接口调试

我跑这套项目的启动顺序是:先启动 MySQL 和 Redis,再启动 SpringBoot 后端,最后启动前端。后端启动成功后,访问/swagger-ui.html能看到接口文档页面,直接在页面里挨个测接口,不用 Postman 也能完成大部分调试。

实际的调试顺序建议按照业务链路来:先调注册登录,拿到 Token;再调汉服列表和详情;然后调加入租赁单、创建订单;最后调管理员登录和订单状态推进。一条链路通了,整个项目就基本通了。我调试时遇到过最多的问题不是业务报错,而是前端请求跨域,解决方式是在后端加一个全局跨域配置类,允许本地开发端口访问。

5.4 演示数据与模拟支付设计

因为不能接真实支付,我一般做一个“模拟支付”接口:传入订单号,后端把订单状态从待支付改成待发货,并记录支付时间为当前时间。这个接口要在答辩前多演示几遍,讲清楚这是为演示方便而设计的模拟逻辑,不是真实对接第三方支付。如果想进一步拔高,可以说“真实环境只需替换支付回调接口,订单状态推进逻辑不变”,这就把项目和工业级实现衔接上了。

6. 常见问题与避坑经验速查:调试这套项目时最常踩的坑

这里我整理了一张速查表,都是我在实际调试这类项目时反复遇到过的问题,按优先级排列。

问题现象可能原因解决办法
启动报数据库连接失败MySQL 未启动、库名不对、密码错误先本地命令行连接测试,确认库和账号密码
中文乱码表字符集不是 utf8mb4、URL 没加 characterEncoding建表统一用 utf8mb4,URL 加编码参数
时间差 8 小时serverTimezone 或 JVM 时区不对统一使用 Asia/Shanghai
登录后请求 401JWT 过期、Token 没带上、拦截器放行路径不对检查请求头和拦截器 excludePathPatterns
前端请求跨域前后端端口不一致未配置跨域后端加全局 CorsFilter 或跨域配置类
创建订单报库存不足库存字段为 0、占用查询条件写错在数据库先补库存,并检查日期比较条件
上传图片失败本地目录不存在、权限不足配置绝对路径并提前创建目录
Redis 连接拒绝Redis 未启动本地启动 redis-server,确认端口 6379

6.1 拦截器放行路径是登录功能的隐性地雷

拦截器写好后,必须把所有公开接口加进放行列表,否则用户还没登录就连首页数据都拿不到。常见坑是只放行了/api/user/login,忘记放行/api/hanfu/list和/api/hanfu/detail,导致前端页面打不开。后端日志里如果看到大量 401,优先检查这里。

我习惯把所有放行 URL 放在一个常量数组里,并在拦截器里打印请求路径,方便调试时一眼看到被拦截的是哪个接口。这个方法在前后端联调时能节省大量时间。

6.2 订单号生成不能用时间戳裸奔

订单号如果直接System.currentTimeMillis()生成,高并发下会重复,答辩时也显得不专业。我建议用“日期 + Redis 自增 + 随机数”的格式,比如202507071530 + 序号。用 Redis 的INCR保证当天序号递增,用日期保证每天重新开始,这样一个订单号就包含了时间信息,又能保证唯一性。

6.3 数据库字段命名避免使用关键字

设计字段时不要用order、desc、rank这类数据库保留字。order 在 MySQL 里虽然可以加反引号用,但 MyBatis Plus 自动生成 SQL 时很容易踩坑。我在项目里全部改成orders、description、sort_no,多花几秒取名,少花几个小时排错。这个建议对所有管理系统都适用。

7. 项目后续可扩展的方向:让这份毕设从“够用”到“亮眼”

这套项目完成基础版本后,如果想继续加亮点,我比较推荐以下几个方向。第一是加数据可视化,后台首页用图表展示订单趋势、热门汉服排行、分类占比,数据可以从订单表和明细表聚合,前端用图表组件渲染,视觉效果好,工作量可控。第二是加积分与优惠券,租赁消费产生积分,积分可以抵扣押金,这又牵扯出一套营销业务,能丰富项目层次。第三是加分布式锁处理库存扣减,用 Redis 的SETNX或 Redisson 模拟真实高并发场景下的锁操作,这是面试高频考点。

如果时间富余,还可以做“归还提醒”:写一个定时任务,每天扫描即将到期的订单,给用户发送消息通知。这个功能涉及定时调度、日期计算、消息通知三个知识点,技术上比 CRUD 高一个台阶,而且业务上完全说得通——租赁平台确实需要提醒用户归还。这几个扩展方向挑一个做进去,都能让答辩时的话题更多。

最后再分享一点我个人的实操体会。做这类管理系统,最忌讳一上来就写代码。先把状态机画清楚,把表结构定下来,再动手写 SpringBoot 的 CRUD,后面基本都是“查表-调接口-填页面”的节奏,速度反而快得多。我见过太多一开始很兴奋、写到订单模块才发现状态对不上、表要重改的同学,返工成本很高。如果你准备拿这个题目做毕设,我建议你至少花一个晚上把订单状态和库存占用这两个点想透,这两块想清楚了,剩下的东西真的没有想象中难。

返回列表