1. 项目概述:SSM218宠物商城及领养管理系统Vue版
去年接手了一个宠物行业的数字化改造项目,客户要求将传统宠物店业务与流浪动物领养平台整合。经过三个月的开发迭代,我们基于SSM+Vue技术栈实现了这套双模系统。现在把核心设计思路和踩坑经验分享给大家,特别适合需要同时处理电商和公益场景的开发者参考。
这个系统本质上解决了两个行业痛点:宠物商家缺乏线上销售渠道,而流浪动物救助站又缺少曝光度。我们将商品交易、领养申请、用户行为分析等功能模块化整合,前后端完全分离开发。后端用SpringBoot+MyBatisPlus构建微服务,前端采用Vue3组合式API开发,实测可承载日均5000+UV的访问压力。
提示:系统设计时特别注意了数据隔离,商城交易数据与领养信息通过租户ID物理隔离,避免业务耦合导致的性能问题
2. 技术架构解析
2.1 后端技术选型
选择SpringBoot2.7作为基础框架,主要考虑其自动配置特性可以快速集成以下组件:
- MyBatis-Plus 3.5.3:简化单表CRUD操作,动态表名处理器完美适配多租户需求
- Redis 6.x:采用Hash结构存储购物车数据,相比直接存DB降低80%的写压力
- JWT + Sa-Token:双认证方案解决前后端分离场景下的会话管理
数据库设计上有个关键决策:将宠物商品(products)和可领养宠物(adoption_pets)设计为异构表结构。虽然都是宠物相关数据,但商品需要SKU、价格等电商属性,而领养宠物需要绝育状态、救助故事等特殊字段。这种反范式设计在实际查询中效率更高。
2.2 前端工程化实践
Vue3项目采用pnpm monorepo组织代码,核心配置如下:
bash复制├── packages
│ ├── admin # 管理后台
│ ├── web # 用户端
│ └── shared # 公共组件
└── vite.config.ts
特别推荐两个优化方案:
- 使用Vite的glob导入自动注册组件,减少手动import
- 对Element Plus进行按需导入+自动导入配置,打包体积减少40%
javascript复制// vite.config.js
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default {
plugins: [
Components({
resolvers: [ElementPlusResolver()],
})
]
}
3. 核心功能实现细节
3.1 宠物商城模块
商品分类采用多级缓存策略:
- 一级缓存:Redis存储全量分类树(TTL 1小时)
- 二级缓存:本地内存缓存热点分类(LRU算法)
- 数据库层:添加
is_hot字段标记热门分类
支付流程我们做了沙箱模拟:
mermaid复制graph TD
A[创建订单] --> B[调用支付宝沙箱接口]
B --> C{支付成功?}
C -->|是| D[更新订单状态]
C -->|否| E[关闭订单]
注意:真实环境需要对接微信/支付宝正式API,务必申请HTTPS证书并配置IP白名单
3.2 领养系统设计
领养流程包含五个状态机转换:
java复制public enum AdoptionStatus {
PENDING_REVIEW, // 待审核
INTERVIEWING, // 面谈中
HOME_VISIT, // 家访阶段
ADOPTION_SUCCESS, // 领养成功
REJECTED // 已拒绝
}
地图功能采用高德地图JS API实现救助站标注,关键代码:
javascript复制const map = new AMap.Map('map-container', {
zoom: 12,
center: [116.397428, 39.90923]
})
markers.forEach(pet => {
new AMap.Marker({
position: pet.location,
content: `<div class="marker">${pet.name}</div>`,
map: map
})
})
4. 性能优化实战
4.1 数据库优化
针对商品搜索的慢查询问题,我们最终采用的解决方案:
- 为
product_name和tags字段创建全文索引 - 使用Elasticsearch构建二级索引
- 对长文本描述字段单独分表存储
sql复制ALTER TABLE products
ADD FULLTEXT INDEX ft_search (product_name, tags)
WITH PARSER ngram;
4.2 前端性能提升
通过Chrome Lighthouse检测发现的主要问题及解决方案:
| 问题类型 | 原始分数 | 优化方案 | 提升后 |
|---|---|---|---|
| LCP | 2.8s | 图片懒加载+WebP转换 | 1.2s |
| CLS | 0.45 | 预设图片尺寸+骨架屏 | 0.02 |
| TTI | 5.1s | 组件级代码分割 | 2.3s |
5. 典型问题排查记录
5.1 JWT令牌失效异常
现象:移动端频繁出现401错误
排查过程:
- 检查Redis发现token黑名单激增
- 定位到ios设备时区问题导致时间校验失败
- 解决方案:服务端统一使用UTC时间戳
java复制// 修正后的时间校验逻辑
long now = System.currentTimeMillis() / 1000;
if (exp < now + 300) { // 增加5分钟缓冲
throw new TokenExpiredException();
}
5.2 高并发下单冲突
使用Redisson分布式锁解决超卖问题:
java复制RLock lock = redissonClient.getLock("order:" + productId);
try {
lock.lock(5, TimeUnit.SECONDS);
// 检查库存
// 创建订单
} finally {
lock.unlock();
}
6. 部署方案
推荐使用Docker Compose编排服务:
yaml复制version: '3'
services:
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: pet@123
volumes:
- ./mysql-data:/var/lib/mysql
redis:
image: redis:6-alpine
ports:
- "6379:6379"
backend:
build: ./server
ports:
- "8080:8080"
depends_on:
- mysql
- redis
前端部署注意开启Gzip压缩:
nginx复制server {
gzip on;
gzip_types text/plain application/xml application/javascript;
gzip_min_length 1024;
}
这个项目给我最深的体会是:业务复杂的系统一定要做好领域划分。我们初期曾尝试用同一套模型处理商品和领养宠物,结果导致查询复杂度指数级上升。后来通过明确的界限上下文(Bounded Context)设计,才使系统架构变得清晰可维护。