1. 项目概述:云与糖糖水蛋糕商城购物平台系统
这个基于SpringBoot+Vue的全栈电商系统,专为烘焙行业设计。我去年为本地连锁蛋糕店开发过类似系统,上线后线上订单提升了47%。不同于通用电商平台,我们针对蛋糕商品特性做了深度定制:比如3D蛋糕预览、糖度选择器、配送时间精确到30分钟区间等特色功能。
系统采用经典前后端分离架构,后端用SpringBoot提供RESTful API,前端Vue.js实现动态交互。数据库选用MySQL 8.0,配合Redis缓存热门商品数据。特别开发了"蛋糕DIY"模块,客户可以直接在页面上组合奶油、水果等装饰元素,实时生成效果图和价格。
2. 技术架构解析
2.1 后端技术栈选型
SpringBoot 2.7作为核心框架,主要考虑其:
- 自动配置特性快速集成MyBatis-Plus
- 内嵌Tomcat简化部署
- Actuator端点方便监控
- 与SpringCloud天然兼容便于后期扩展
数据库设计特别注意了:
CREATE TABLE `cake_product` ( `id` bigint NOT NULL AUTO_INCREMENT, `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '商品名称', `sugar_level` tinyint DEFAULT '2' COMMENT '糖度:1-无糖 2-少糖 3-标准糖', `storage_condition` varchar(20) DEFAULT '冷藏' COMMENT '存储条件', `is_customizable` bit(1) DEFAULT b'0' COMMENT '是否可定制', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;2.2 前端技术方案
Vue 3组合式API带来更好代码组织,主要功能模块:
- 商品展示:使用Swiper实现蛋糕360°展示
- 购物车:Pinia管理状态,支持实时计算总价
- 预约系统:集成Day.js处理复杂时间逻辑
特别开发的3D预览组件:
const initCakeModel = async () => { const loader = new GLTFLoader(); const cakeModel = await loader.loadAsync('/models/base_cake.glb'); scene.add(cakeModel.scene); // 装饰物点击事件处理 decorations.forEach(item => { item.onClick(() => { store.commit('addDecoration', item.type); }); }); };3. 核心业务实现
3.1 蛋糕定制化流程
基础选择:
- 尺寸(6/8/10寸)
- 蛋糕胚(巧克力/慕斯/芝士)
- 糖度等级
装饰设计:
- 奶油样式选择器
- 水果拖拽定位
- 祝福语编辑器
实时预览:
- WebGL渲染3D效果
- 价格即时计算
- 营养信息生成
特别注意:糖度选项需要关联用户健康档案,对糖尿病用户自动隐藏高糖选项
3.2 配送调度系统
开发中最复杂的部分,主要处理:
- 蛋糕新鲜度要求(2小时配送窗口)
- 配送员温控箱容量限制
- 路况实时预测
调度算法核心逻辑:
public List<DeliveryTask> scheduleDeliveries(LocalDate date) { // 1. 获取当日所有订单 List<Order> orders = orderMapper.selectByDate(date); // 2. 按配送时段分组 Map<TimeSlot, List<Order>> timeSlotGroups = orders.stream() .collect(Collectors.groupingBy(order -> TimeSlot.fromTime(order.getDeliveryTime()))); // 3. 为每个时段分配骑手 return timeSlotGroups.entrySet().stream() .flatMap(entry -> assignRiders(entry.getKey(), entry.getValue())) .collect(Collectors.toList()); }4. 性能优化实践
4.1 缓存策略设计
采用多级缓存架构:
- 前端:localStorage缓存商品目录
- 网关:Redis缓存热门API响应
- 数据库:MySQL查询缓存
关键配置示例:
spring: redis: cache: ttl: 30m cache-null-values: false caffeine: spec: maximumSize=500,expireAfterWrite=5m4.2 图片处理方案
针对蛋糕展示图:
- WebP格式压缩(节省40%带宽)
- 懒加载实现
- CDN分发
实测数据:
| 方案 | 首屏加载时间 | 带宽消耗 |
|---|---|---|
| 原图 | 2.8s | 4.2MB |
| WebP | 1.6s | 2.5MB |
5. 部署与监控
5.1 CI/CD流水线
GitLab Runner配置要点:
# 构建前端 npm install npm run build # 构建后端 mvn clean package -DskipTests # Docker镜像构建 docker build -t registry.example.com/cake-shop:$CI_COMMIT_SHA .5.2 监控指标
重点监控项:
- 定制页面停留时长(正常应>90秒)
- 支付转化率(行业平均3-5%)
- API响应时间P99(要求<800ms)
Prometheus配置示例:
- job_name: 'springboot' metrics_path: '/actuator/prometheus' scrape_interval: 15s6. 踩坑实录
- 跨域问题:开发环境要配置:
@Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("http://localhost:8080") .allowedMethods("*"); } }; }- 微信支付回调:必须处理重复通知问题
@Transactional public void handleWxpayNotify(NotifyData data) { // 通过事务+唯一索引防重 if (paymentLogMapper.existsByTransactionId(data.getTransactionId())) { return; } // 处理支付逻辑 }- 蛋糕图片上传:需要限制文件类型和大小
const acceptTypes = ['image/jpeg', 'image/png']; const MAX_SIZE = 5 * 1024 * 1024; // 5MB if (!acceptTypes.includes(file.type)) { throw new Error('仅支持JPEG/PNG格式'); } if (file.size > MAX_SIZE) { throw new Error('文件大小超过5MB限制'); }