1. 项目概述
汉服租赁系统是一个基于SpringBoot+Vue.js的B/S架构Web应用,旨在为汉服爱好者提供便捷的在线租赁服务。随着传统文化复兴热潮,汉服作为一种文化符号受到越来越多年轻人喜爱,但高昂的制作成本和多样的款式使得购买多套汉服并不现实。本系统通过数字化租赁服务,降低了用户体验汉服文化的门槛。
系统采用前后端分离架构,前端使用Vue.js实现响应式界面,后端基于SpringBoot框架开发,数据库选用MySQL 8.0。系统包含用户端和管理端两大模块,实现了从汉服展示、租赁下单到归还评价的全流程线上化管理。
2. 技术选型与架构设计
2.1 技术栈组成
后端技术栈:
- SpringBoot 2.7.3:简化配置,快速构建微服务
- Spring Security:认证与授权管理
- MyBatis-Plus 3.5.1:增强型ORM框架
- Redis 6.2:缓存热点数据和会话管理
- Alipay SDK:集成支付宝支付接口
- JWT:无状态身份认证
前端技术栈:
- Vue.js 3.2:渐进式前端框架
- Element Plus:UI组件库
- Axios:HTTP请求库
- Vue Router:前端路由管理
- Vuex:状态管理
数据库:
- MySQL 8.0:关系型数据库
- 数据库连接池:HikariCP
2.2 系统架构设计
系统采用经典的三层架构:
code复制┌───────────────────────────────────────┐
│ 表现层 │
│ ┌─────────────┐ ┌─────────────┐│
│ │ Vue前端 │ <--> │ REST API ││
│ └─────────────┘ └─────────────┘│
├───────────────────────────────────────┤
│ 业务逻辑层 │
│ ┌─────────────┐ ┌─────────────┐│
│ │ Service层 │ <--> │ Controller ││
│ └─────────────┘ └─────────────┘│
├───────────────────────────────────────┤
│ 数据访问层 │
│ ┌─────────────┐ ┌─────────────┐│
│ │ Mapper层 │ <--> │ MySQL ││
│ └─────────────┘ └─────────────┘│
└───────────────────────────────────────┘
2.3 技术选型考量
-
SpringBoot的优势:
- 自动配置:减少XML配置
- 内嵌Tomcat:简化部署
- Starter依赖:快速集成常用组件
- Actuator:提供系统监控端点
-
Vue.js的选择原因:
- 渐进式框架:可按需引入功能
- 虚拟DOM:提升渲染性能
- 组件化开发:提高代码复用率
- 丰富的生态系统:Element UI等成熟组件库
-
MySQL的优化措施:
- 使用InnoDB引擎支持事务
- 建立合适的索引(商品ID、用户ID等)
- 配置读写分离(通过MyCat实现)
- 定期执行OPTIMIZE TABLE减少碎片
3. 核心功能实现
3.1 用户模块
3.1.1 注册登录流程
注册流程:
- 客户端提交用户名、密码、手机号等信息
- 服务端验证数据合法性(格式校验、唯一性校验)
- 密码加盐哈希处理(BCrypt算法)
- 生成初始用户信息记录
- 发送短信验证码(集成阿里云短信服务)
java复制// 密码加密处理示例
public class PasswordUtil {
private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
public static String encode(String rawPassword) {
return encoder.encode(rawPassword);
}
public static boolean matches(String rawPassword, String encodedPassword) {
return encoder.matches(rawPassword, encodedPassword);
}
}
登录流程:
- 客户端提交凭证(用户名/手机号+密码)
- 服务端验证凭证有效性
- 生成JWT令牌(包含用户ID、角色、过期时间)
- 返回令牌给客户端存储
- 后续请求携带令牌进行鉴权
3.1.2 权限控制设计
采用RBAC(基于角色的访问控制)模型:
code复制┌───────────┐ ┌───────────┐ ┌───────────┐
│ 用户 │ │ 角色 │ │ 权限 │
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘
│ │ │
└─────┬─────┬─────┘ │
│ │ │
┌─────▼─────▼─────┐ ┌─────▼─────┐
│ 用户-角色关联 │ │ 角色-权限 │
└─────────────────┘ │ 关联 │
└───────────┘
通过Spring Security实现接口级别的权限控制:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.antMatchers("/api/user/**").hasRole("USER")
.antMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager()));
}
}
3.2 商品模块
3.2.1 商品数据结构设计
sql复制CREATE TABLE `rental_mall` (
`id` bigint NOT NULL AUTO_INCREMENT,
`product_code` varchar(64) COLLATE utf8mb4_bin NOT NULL COMMENT '商品编号',
`name` varchar(128) COLLATE utf8mb4_bin NOT NULL COMMENT '商品名称',
`category_id` int NOT NULL COMMENT '分类ID',
`cover_image` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '封面图URL',
`price` decimal(10,2) NOT NULL COMMENT '租赁价格/天',
`stock` int NOT NULL DEFAULT '0' COMMENT '库存数量',
`specs` json DEFAULT NULL COMMENT '规格参数(JSON格式)',
`detail` text COLLATE utf8mb4_bin COMMENT '商品详情',
`status` tinyint NOT NULL DEFAULT '1' COMMENT '状态(1-上架 0-下架)',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_product_code` (`product_code`),
KEY `idx_category` (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
3.2.2 商品搜索实现
采用Elasticsearch构建商品搜索引擎,实现:
- 全文检索(IK分词器)
- 多条件筛选(分类、价格区间等)
- 搜索结果排序(销量、价格、评分)
java复制@Service
public class ProductSearchServiceImpl implements ProductSearchService {
@Autowired
private RestHighLevelClient esClient;
public SearchResponse searchProducts(ProductSearchDTO dto) throws IOException {
SearchRequest request = new SearchRequest("products");
// 构建查询条件
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
// 关键词查询
if (StringUtils.isNotBlank(dto.getKeyword())) {
boolQuery.must(QueryBuilders.multiMatchQuery(dto.getKeyword(),
"name", "description", "tags"));
}
// 分类过滤
if (dto.getCategoryId() != null) {
boolQuery.filter(QueryBuilders.termQuery("category_id", dto.getCategoryId()));
}
// 价格区间
if (dto.getMinPrice() != null && dto.getMaxPrice() != null) {
boolQuery.filter(QueryBuilders.rangeQuery("price")
.gte(dto.getMinPrice()).lte(dto.getMaxPrice()));
}
// 构建分页
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
.query(boolQuery)
.from((dto.getPageNum() - 1) * dto.getPageSize())
.size(dto.getPageSize());
// 排序条件
if ("price".equals(dto.getSortBy())) {
sourceBuilder.sort("price",
"asc".equals(dto.getSortOrder()) ? SortOrder.ASC : SortOrder.DESC);
} else if ("sales".equals(dto.getSortBy())) {
sourceBuilder.sort("sales_count", SortOrder.DESC);
}
request.source(sourceBuilder);
return esClient.search(request, RequestOptions.DEFAULT);
}
}
3.3 订单模块
3.3.1 订单状态机设计
mermaid复制stateDiagram-v2
[*] --> PENDING_PAYMENT
PENDING_PAYMENT --> PAID: 支付成功
PENDING_PAYMENT --> CANCELLED: 用户取消
PAID --> SHIPPED: 发货
SHIPPED --> RECEIVED: 用户确认收货
RECEIVED --> RETURN_REQUESTED: 申请归还
RETURN_REQUESTED --> RETURNED: 归还确认
RETURNED --> COMPLETED: 订单完成
RETURN_REQUESTED --> RETURN_REJECTED: 归还驳回
RETURN_REJECTED --> RETURN_REQUESTED: 重新申请
3.3.2 库存扣减方案
采用Redis+Lua脚本实现原子性库存扣减:
lua复制-- KEYS[1]: 库存key
-- ARGV[1]: 扣减数量
local stock = tonumber(redis.call('GET', KEYS[1]))
if not stock then
return -1 -- 商品不存在
end
if stock < tonumber(ARGV[1]) then
return -2 -- 库存不足
end
redis.call('DECRBY', KEYS[1], ARGV[1])
return stock - tonumber(ARGV[1]) -- 返回剩余库存
Java调用示例:
java复制public boolean reduceInventory(String productCode, int quantity) {
String script = "local stock = tonumber(redis.call('GET', KEYS[1]))..."; // 上面的Lua脚本
RedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);
Long result = redisTemplate.execute(
redisScript,
Collections.singletonList("inventory:" + productCode),
String.valueOf(quantity));
if (result == null) {
throw new RuntimeException("库存操作异常");
}
return result >= 0;
}
4. 系统优化实践
4.1 性能优化措施
-
缓存策略:
- 商品详情:Redis缓存,TTL=30分钟
- 热门商品列表:每日凌晨预加载
- 分类信息:应用启动时加载到内存
-
数据库优化:
- 读写分离:主库写,从库读
- 慢查询优化:添加适当索引
- 分表策略:订单表按用户ID哈希分表
-
前端优化:
- 图片懒加载
- 组件按需加载
- API请求合并
- 本地缓存常用数据
4.2 安全防护方案
-
防御措施:
- XSS:前端DOMPurify过滤,后端Jackson转义
- CSRF:SameSite Cookie + 关键操作二次验证
- SQL注入:MyBatis预编译+参数化查询
- 暴力破解:登录失败次数限制(Redis记录)
-
数据安全:
- 敏感字段加密:手机号、身份证号AES加密存储
- 传输安全:全站HTTPS + HSTS
- 日志脱敏:敏感信息掩码处理
-
支付安全:
- 支付密码二次验证
- 交易金额服务端校验
- 支付结果异步通知+主动查询双重确认
5. 部署与运维
5.1 容器化部署方案
使用Docker Compose编排服务:
yaml复制version: '3.8'
services:
app:
image: hanfu-rental-app:${TAG:-latest}
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- DB_URL=jdbc:mysql://mysql:3306/hanfu_rental
- REDIS_HOST=redis
depends_on:
- mysql
- redis
mysql:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
- MYSQL_DATABASE=hanfu_rental
- MYSQL_USER=${DB_USER}
- MYSQL_PASSWORD=${DB_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
redis:
image: redis:6.2-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
nginx:
image: nginx:1.21-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./certs:/etc/nginx/certs
depends_on:
- app
volumes:
mysql_data:
redis_data:
5.2 监控体系搭建
-
应用监控:
- Spring Boot Actuator:健康检查、指标收集
- Prometheus:指标采集与存储
- Grafana:监控数据可视化
-
日志收集:
- ELK Stack(Elasticsearch+Logstash+Kibana)
- 日志分级:DEBUG/INFO/WARN/ERROR
- 关键操作审计日志单独存储
-
报警机制:
- 异常日志报警(通过Sentry)
- 服务不可用报警(Prometheus Alertmanager)
- 业务指标报警(订单异常波动等)
6. 项目总结与展望
6.1 项目成果
-
功能完整性:
- 实现了汉服租赁全流程线上化
- 开发了完善的后台管理系统
- 支持多种支付方式和灵活的租赁策略
-
技术亮点:
- 前后端分离架构,职责清晰
- 完善的权限控制系统
- 高性能的搜索体验
- 可靠的订单处理流程
-
性能指标:
- 首页加载时间 < 1s
- API平均响应时间 < 200ms
- 支持500+并发用户
6.2 经验分享
-
开发过程中的教训:
- 初期低估了库存并发控制的复杂度,后期引入Redis+Lua解决
- 支付状态同步机制设计不足,增加了对账补偿逻辑
- 图片上传未做尺寸限制,导致存储空间增长过快
-
值得推荐的做法:
- 接口文档先行(使用Swagger)
- 代码规范检查(SonarQube)
- 自动化测试(JUnit+Mockito)
- CI/CD流水线(GitLab CI)
6.3 未来优化方向
-
功能扩展:
- 增加汉服配套服务(妆发、摄影)
- 引入社交功能(用户晒单、穿搭分享)
- 开发小程序端提升移动体验
-
技术升级:
- 尝试Service Mesh架构
- 引入分布式事务解决跨服务数据一致性问题
- 探索AI推荐算法提升商品匹配精度
-
运营优化:
- 建立汉服清洁消毒标准化流程
- 开展线下体验店提升用户信任度
- 与传统文化活动合作扩大影响力