1. 项目背景与核心需求
水产品海鲜烧烤作为近年来快速崛起的餐饮细分市场,其线上化进程却明显滞后于其他餐饮品类。传统的外卖平台无法满足这类商品对新鲜度展示、即时配送和特色服务的特殊需求。这正是我们设计这套专门针对水产品烧烤的商城系统的初衷。
这个SpringBoot项目需要解决几个行业痛点:
- 海鲜类商品对保质期和储存条件的特殊要求
- 烧烤食材通常需要组合销售(如海鲜拼盘)
- 线下门店与线上库存的实时同步需求
- 配送时效性的严格把控(通常要求2小时内送达)
我在实际开发中发现,相比普通电商系统,海鲜烧烤商城有几个关键差异点:商品详情页需要突出"新鲜度指标"(如捕捞/宰杀时间),订单状态需要增加"预处理中"(清洗、切割等)环节,配送模块要集成温度监控功能。这些特性都需要在系统设计阶段就充分考虑。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 整体技术栈选型
采用SpringBoot 1.6.7作为基础框架,这个版本在稳定性和功能完整性上已经非常成熟。主要技术组件包括:
- 持久层:MyBatis + PageHelper分页插件
- 缓存:Redis集群(商品详情和库存信息)
- 搜索:Elasticsearch(海鲜品类搜索优化)
- 消息队列:RabbitMQ(订单状态变更通知)
- 文件存储:FastDFS(商品图片和视频)
特别注意:海鲜类商品图片需要更高清的展示,我们采用FastDFS的分布式存储方案,相比本地存储可以更好地应对大文件(如菜品制作视频)的上传下载需求。
2.2 数据库设计要点
核心表结构设计考虑了海鲜商品的特殊性:
sql复制CREATE TABLE `seafood_product` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT '商品名称',
`origin_place` varchar(50) NOT NULL COMMENT '原产地',
`catch_time` datetime NOT NULL COMMENT '捕捞/宰杀时间',
`storage_temp` decimal(3,1) NOT NULL COMMENT '最佳存储温度',
`shelf_life` int(11) NOT NULL COMMENT '保质期(小时)',
`processing_required` tinyint(1) DEFAULT 0 COMMENT '是否需要预处理',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
针对烧烤特色,我们特别设计了组合商品表:
sql复制CREATE TABLE `combo_product` (
`combo_id` bigint(20) NOT NULL,
`product_id` bigint(20) NOT NULL,
`weight` int(11) NOT NULL COMMENT '单品重量(g)',
`is_main` tinyint(1) DEFAULT 0 COMMENT '是否为主食材'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3. 核心功能实现
3.1 商品新鲜度展示模块
通过定时任务更新商品新鲜度状态:
java复制@Scheduled(cron = "0 0/30 * * * ?")
public void updateProductFreshStatus() {
List<SeafoodProduct> products = productMapper.selectNeedUpdate();
products.forEach(product -> {
long hours = ChronoUnit.HOURS.between(
product.getCatchTime().toInstant(),
Instant.now()
);
product.setFreshLevel(calculateFreshLevel(hours, product.getShelfLife()));
productMapper.updateFreshLevel(product);
});
}
前端展示采用颜色分级:
javascript复制function getFreshnessColor(hours, shelfLife) {
const ratio = hours / shelfLife;
if (ratio < 0.3) return '#4CAF50'; // 新鲜
if (ratio < 0.7) return '#FFC107'; // 一般
return '#F44336'; // 不推荐
}
3.2 特色购物车设计
考虑到烧烤食材通常需要按人数配置,购物车增加了智能推荐功能:
java复制public List<Product> recommendCombo(int personCount) {
List<Product> baseProducts = productMapper.selectByTag("烧烤基础");
List<Product> recommendations = new ArrayList<>();
// 按人均200g计算基础食材
baseProducts.forEach(p -> {
p.setRecommendWeight(personCount * 200);
recommendations.add(p);
});
// 推荐蘸料和配菜
if (personCount >= 3) {
recommendations.addAll(productMapper.selectByTag("蘸料"));
}
return recommendations;
}
4. 订单与配送系统
4.1 订单状态机设计
海鲜烧烤订单有特殊状态流转:
code复制待支付 → 已支付 → 预处理中 → 配送中 → 已完成
↘ ↙
已取消
使用状态模式实现:
java复制public interface OrderState {
void handle(OrderContext context);
}
@Component
@Scope("prototype")
public class PreprocessingState implements OrderState {
@Override
public void handle(OrderContext context) {
if (!checkInventory(context.getOrder())) {
context.setState(OrderStateFactory.getState("已取消"));
return;
}
// 启动预处理流程
preprocessingService.start(context.getOrder());
context.setState(OrderStateFactory.getState("配送中"));
}
}
4.2 温度监控集成
配送箱温度通过IoT设备实时上报:
java复制@RabbitListener(queues = "temp.monitor")
public void processTempMessage(TempMessage message) {
Delivery delivery = deliveryMapper.selectByDeviceId(message.getDeviceId());
if (delivery != null) {
delivery.setCurrentTemp(message.getTemperature());
deliveryMapper.updateTemp(delivery);
if (message.getTemperature() > delivery.getMaxAllowedTemp()) {
alertService.sendTempAlert(delivery);
}
}
}
5. 性能优化实践
5.1 库存缓存设计
采用多级缓存策略解决海鲜库存高频更新问题:
- Redis缓存热点商品库存(5秒过期)
- 本地缓存(Caffeine)作为二级缓存(1秒过期)
- 数据库使用乐观锁控制并发更新
java复制public boolean reduceStock(Long productId, int quantity) {
// 一级缓存检查
String cacheKey = "stock:" + productId;
Integer current = redisTemplate.opsForValue().get(cacheKey);
if (current != null && current < quantity) {
return false;
}
// 二级缓存检查
current = stockCache.getIfPresent(productId);
if (current == null) {
current = productMapper.selectStock(productId);
stockCache.put(productId, current);
}
// 最终数据库检查
if (current >= quantity) {
int rows = productMapper.updateStock(productId, quantity, current);
if (rows > 0) {
// 更新缓存
redisTemplate.opsForValue().set(cacheKey, current - quantity, 5, TimeUnit.SECONDS);
stockCache.put(productId, current - quantity);
return true;
}
}
return false;
}
5.2 高并发订单处理
使用分布式锁控制订单创建:
java复制public String createOrder(OrderDTO dto) {
String lockKey = "order:lock:" + dto.getUserId();
RLock lock = redissonClient.getLock(lockKey);
try {
boolean locked = lock.tryLock(3, 10, TimeUnit.SECONDS);
if (locked) {
// 校验库存
if (!stockService.checkStock(dto.getItems())) {
throw new BusinessException("库存不足");
}
// 创建订单
Order order = convertToOrder(dto);
orderMapper.insert(order);
// 扣减库存
stockService.reduceStock(dto.getItems());
return order.getOrderNo();
}
} finally {
lock.unlock();
}
}
6. 安全与风控措施
6.1 海鲜品类防刷单机制
针对高价海鲜商品设计的风控规则:
- 同一IP/设备短时间内大量下单
- 收货地址异常变更
- 支付后立即申请退款
实现方案:
java复制public void checkOrderRisk(Order order) {
// 基础规则检查
RiskRuleResult result = riskRuleEngine.checkRules(order);
// 自定义海鲜品类规则
if (order.getTotalAmount() > 1000) {
long recentOrderCount = orderMapper.countRecentOrders(
order.getUserId(), 24);
if (recentOrderCount > 3) {
result.addRiskPoint(20, "高价商品短时多单");
}
}
if (result.getTotalPoints() > 50) {
order.setStatus(OrderStatus.REVIEW);
orderMapper.updateStatus(order);
riskService.notifyReview(order);
}
}
6.2 敏感操作日志
记录关键操作以备审计:
java复制@Aspect
@Component
public class OperationLogAspect {
@Autowired
private OperationLogService logService;
@Pointcut("@annotation(com.xxx.SensitiveOperation)")
public void sensitiveOperation() {}
@Around("sensitiveOperation()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
SensitiveOperation annotation = method.getAnnotation(SensitiveOperation.class);
OperationLog log = new OperationLog();
log.setOperationType(annotation.value());
log.setOperator(getCurrentUser());
log.setParams(JsonUtils.toJson(joinPoint.getArgs()));
try {
Object result = joinPoint.proceed();
log.setSuccess(true);
return result;
} catch (Exception e) {
log.setSuccess(false);
log.setErrorMsg(e.getMessage());
throw e;
} finally {
logService.save(log);
}
}
}
7. 部署与监控方案
7.1 容器化部署
使用Docker Compose编排服务:
yaml复制version: '3'
services:
app:
image: seafood-shop:1.0
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
depends_on:
- redis
- mysql
redis:
image: redis:6
ports:
- "6379:6379"
volumes:
- redis_data:/data
mysql:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_DATABASE=seafood
volumes:
- mysql_data:/var/lib/mysql
7.2 监控指标采集
针对海鲜商城的特殊指标监控:
- 订单平均预处理时间
- 配送温度超标次数
- 商品新鲜度合格率
使用Prometheus配置:
yaml复制- job_name: 'seafood_metrics'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['app:8080']
metric_relabel_configs:
- source_labels: [__name__]
regex: '(order_preprocess_time|delivery_temp_violation|product_fresh_rate).*'
action: keep
在项目开发过程中,我们发现海鲜类电商系统与常规电商有几个关键区别点需要特别注意:1) 时间敏感型商品的库存管理不能简单套用传统电商的"超卖"解决方案;2) 配送环节的监控要求远高于普通商品;3) 商品展示需要突出时效性信息。这些特性使得系统设计时需要更多考虑实时性和状态监控的需求。
