1. 项目背景与核心需求
"003网络海鲜市场"是一个典型的B2C电商平台项目,采用前后端分离架构。这个项目的核心业务场景是解决海鲜产品线上交易的几个痛点:
- 生鲜产品的实时库存与物流时效管理
- 多规格商品(如不同重量、鲜活/冰鲜)的SKU展示
- 高并发场景下的订单处理能力
- 冷链物流的状态追踪集成
选择SpringBoot+Vue的技术组合主要基于以下考虑:
- SpringBoot的自动配置特性能够快速搭建稳定的商品服务和订单服务
- Vue的响应式数据绑定非常适合动态更新的价格和库存显示
- 前后端分离架构便于团队分工和独立部署
- SpringCloud生态可以方便地扩展支付、物流等微服务
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 后端SpringBoot服务设计
采用三层架构设计:
code复制com.seafood.market
├── controller # 对外接口
├── service # 业务逻辑
│ ├── impl # 实现类
├── dao # 数据访问
│ ├── mapper # MyBatis映射
├── entity # 实体类
├── config # 配置类
└── util # 工具类
关键配置示例(application.yml):
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/seafood?useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
redis:
host: 127.0.0.1
port: 6379
password:
database: 0
2.2 前端Vue项目结构
code复制src/
├── api/ # 接口定义
├── assets/ # 静态资源
├── components/ # 公共组件
│ ├── ProductCard.vue # 商品卡片
│ ├── CountDown.vue # 抢购倒计时
├── router/ # 路由配置
├── store/ # Vuex状态管理
├── views/ # 页面视图
│ ├── Home.vue # 首页
│ ├── Detail.vue # 商品详情
└── App.vue # 根组件
3. 核心功能实现
3.1 商品模块实现
商品表设计关键字段:
sql复制CREATE TABLE `product` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT '商品名称',
`category_id` int DEFAULT NULL COMMENT '分类ID',
`origin` varchar(50) DEFAULT NULL COMMENT '产地',
`storage_method` tinyint DEFAULT '1' COMMENT '1-鲜活 2-冰鲜 3-冷冻',
`price` decimal(10,2) DEFAULT NULL COMMENT '基准价',
`stock` int DEFAULT '0' COMMENT '库存',
`sold` int DEFAULT '0' COMMENT '已售',
`status` tinyint DEFAULT '1' COMMENT '1-上架 0-下架',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
商品详情接口示例:
java复制@RestController
@RequestMapping("/product")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/detail/{id}")
public Result<ProductVO> getDetail(@PathVariable Long id) {
ProductVO vo = productService.getDetail(id);
return Result.success(vo);
}
}
3.2 购物车实现
前端购物车逻辑(Vuex):
javascript复制const cart = {
state: {
items: []
},
mutations: {
ADD_ITEM(state, product) {
const exist = state.items.find(item => item.id === product.id)
if(exist) {
exist.quantity += product.quantity
} else {
state.items.push(product)
}
localStorage.setItem('cart', JSON.stringify(state.items))
}
},
actions: {
addToCart({ commit }, product) {
commit('ADD_ITEM', product)
}
}
}
4. 特色功能开发
4.1 冷链物流追踪
集成第三方物流API示例:
java复制@Service
public class LogisticsServiceImpl implements LogisticsService {
@Value("${logistics.api.key}")
private String apiKey;
@Override
public LogisticsTrack track(String orderNo) {
String url = "https://api.logistics.com/track?no="+orderNo+"&key="+apiKey;
// 使用RestTemplate调用接口
return restTemplate.getForObject(url, LogisticsTrack.class);
}
}
前端展示组件:
vue复制<template>
<div class="track-container">
<div v-for="(step,index) in tracks" :key="index"
:class="['track-step', {active: index <= currentStep}]">
<div class="time">{{step.time}}</div>
<div class="desc">{{step.desc}}</div>
</div>
</div>
</template>
4.2 限时抢购功能
使用Redis实现秒杀:
java复制public class SeckillService {
@Autowired
private StringRedisTemplate redisTemplate;
public boolean seckill(Long productId, Long userId) {
// 1. 校验库存
String stockKey = "seckill:stock:" + productId;
Long stock = redisTemplate.opsForValue().decrement(stockKey);
if(stock < 0) {
// 库存不足回滚
redisTemplate.opsForValue().increment(stockKey);
return false;
}
// 2. 防止重复购买
String userKey = "seckill:user:" + productId;
if(redisTemplate.opsForSet().isMember(userKey, userId.toString())) {
redisTemplate.opsForValue().increment(stockKey);
return false;
}
redisTemplate.opsForSet().add(userKey, userId.toString());
// 3. 异步创建订单
sendCreateOrderMessage(productId, userId);
return true;
}
}
5. 部署与优化
5.1 后端部署方案
使用Docker Compose部署:
dockerfile复制version: '3'
services:
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: 123456
ports:
- "3306:3306"
volumes:
- ./mysql/data:/var/lib/mysql
redis:
image: redis:alpine
ports:
- "6379:6379"
app:
build: .
ports:
- "8080:8080"
depends_on:
- mysql
- redis
Jenkins部署脚本示例:
groovy复制pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'mvn clean package -DskipTests'
}
}
stage('Deploy') {
steps {
sshPublisher(
publishers: [
sshPublisherDesc(
configName: 'prod-server',
transfers: [
sshTransfer(
sourceFiles: 'target/*.jar',
removePrefix: 'target',
remoteDirectory: '/app/seafood',
execCommand: 'cd /app/seafood && docker-compose up -d --build'
)
]
)
]
)
}
}
}
}
5.2 前端性能优化
- 路由懒加载:
javascript复制const routes = [
{
path: '/detail/:id',
component: () => import('./views/Detail.vue')
}
]
- 图片懒加载:
vue复制<img v-lazy="product.image" alt="商品图片">
- 使用Webpack分包:
javascript复制configureWebpack: {
optimization: {
splitChunks: {
chunks: 'all'
}
}
}
6. 项目经验总结
在实际开发中遇到几个关键问题及解决方案:
- 跨域问题处理:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowCredentials(true)
.maxAge(3600);
}
}
- 大文件上传优化:
- 前端采用分片上传
- 后端使用临时文件存储
- 增加MD5校验避免重复上传
- 接口幂等性处理:
java复制@RestController
@RequestMapping("/order")
public class OrderController {
@PostMapping
public Result create(@RequestBody OrderDTO dto,
@RequestHeader("X-Request-Id") String requestId) {
// 基于requestId实现幂等
if(redisTemplate.opsForValue().setIfAbsent(requestId, "1", 24, TimeUnit.HOURS)) {
return orderService.create(dto);
}
throw new BusinessException("请勿重复提交订单");
}
}
- 线上问题排查技巧:
- 使用SpringBoot Actuator监控端点
- 集成ELK收集日志
- 关键业务添加埋点日志
这个项目从技术选型到最终上线历时3个月,最大的收获是掌握了复杂业务场景下的前后端协作模式。特别是在高并发场景下,通过Redis+异步处理的组合,成功支撑了促销期间10倍于平时的流量。
