基于 AI 辅助开发电商系统核心模块实战
在当前的开发环境中,利用 AI 编程助手能够显著提升效率。本文将分享如何结合 Spring Boot 与 AI 工具快速构建电商系统的三大核心模块:商品管理(上架/搜索/库存)、购物车(加购/改数量/算总价)以及订单系统(下单/状态/明细)。通过自动化生成代码与智能校验,我们可以将原本需要数天的工作压缩至数小时,同时保证代码规范与业务逻辑的准确性。
一、环境准备与需求定义
就像搭建任何项目一样,基础环境的配置是第一步。我们需要准备好 Java 开发环境、IDEA 编辑器以及 AI 编程插件。
1. 安装与配置
打开 IDEA,进入 File -> Settings -> Plugins,搜索并安装 AI 编程助手插件。注册登录后,选择适合新手的引导模式即可开始。
2. 明确需求
无需编写复杂的 PRD 文档,直接以自然语言描述功能需求。例如,针对电商场景,可以这样输入:
我要开发电商系统的 3 个核心模块,具体需求如下:
1. 商品管理模块:新增商品(名称、价格、库存等)、列表查询(模糊查、排序、分页)、上下架。
约束:价格不能为负、库存不能为负、默认上架。
2. 购物车模块:添加商品、修改数量、删除、查询列表及计算总价。
约束:校验商品存在性、上架状态及库存充足性。
3. 订单模块:创建订单(扣减库存、防重复提交)、查询列表及明细、修改支付状态。
约束:幂等校验、未支付不可发货。
技术要求:Spring Boot 2.7.x + MyBatis Plus + MySQL 8.0 + Redis 6.x。
提交后,AI 会分析需求并给出初步方案,这比手动设计架构要快得多。
二、数据库设计与表结构
AI 会根据需求自动拆解并生成数据库表结构。以下是生成的三张核心表的 SQL,包含必要的索引与约束。
-- 1. 商品表(product)
CREATE TABLE product (
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '商品 ID',
product_name VARCHAR(255) NOT NULL COMMENT '商品名称',
price DECIMAL(10,2) NOT NULL CHECK(price >= 0) COMMENT '商品价格',
stock INT NOT NULL DEFAULT 0 CHECK(stock >= 0) COMMENT '库存数量',
category_id BIGINT NOT NULL COMMENT '商品分类 ID',
product_img VARCHAR(512) COMMENT '商品图片 URL',
status TINYINT NOT NULL DEFAULT 1 COMMENT '商品状态(1=上架,0=下架)',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
INDEX idx_product_name (product_name),
INDEX idx_category_id (category_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表';
-- 2. 订单表(order_info)
CREATE TABLE order_info (
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '订单 ID',
order_no VARCHAR(64) NOT NULL UNIQUE COMMENT '订单编号',
user_id BIGINT NOT NULL COMMENT '用户 ID',
total_amount DECIMAL(10,2) NOT NULL COMMENT '订单总金额',
pay_status TINYINT NOT NULL DEFAULT 0 COMMENT '支付状态(0=待付款,1=已支付,2=已取消)',
order_status TINYINT NOT NULL DEFAULT 0 COMMENT '订单状态(0=待发货,1=已发货,2=已完成)',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
pay_time DATETIME COMMENT '支付时间',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
INDEX idx_user_id (user_id),
INDEX idx_order_no (order_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
-- 3. 订单项表(order_item)
CREATE TABLE order_item (
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '订单项 ID',
order_id BIGINT NOT NULL COMMENT '关联订单 ID',
order_no VARCHAR(64) NOT NULL COMMENT '关联订单编号',
product_id BIGINT NOT NULL COMMENT '商品 ID',
product_name VARCHAR(255) NOT NULL COMMENT '商品名称',
product_price DECIMAL(10,2) NOT NULL COMMENT '购买时的价格',
buy_num INT NOT NULL COMMENT '购买数量',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
INDEX idx_order_id (order_id),
INDEX idx_product_id (product_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单项表';
注意,AI 已经考虑了冗余字段(如订单项存商品名称)以避免后续联表查询的性能损耗,同时也加入了非负约束防止脏数据。
三、核心代码实现
表结构确定后,AI 会自动生成实体类、Mapper、Service 及 Controller 层代码。以下展示关键接口的实现逻辑。
1. 商品管理接口
Controller 层负责接收请求并调用 Service 处理业务。AI 生成的代码通常包含基础的参数校验与日志记录。
package com.example.ecommerce.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.ecommerce.common.Result;
import com.example.ecommerce.entity.Product;
import com.example.ecommerce.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/api/product")
@Slf4j
public class ProductController {
@Resource
private ProductService productService;
/**
* 新增商品
*/
@PostMapping("/add")
public Result<?> addProduct(@RequestBody Product product) {
if (product.getPrice().compareTo(java.math.BigDecimal.ZERO) < 0) {
return Result.fail("商品价格不能为负");
}
if (product.getStock() < 0) {
return Result.fail("商品库存不能为负");
}
product.setStatus(1);
boolean success = productService.save(product);
if (success) {
log.info("新增商品成功,商品 ID:{}", product.getId());
return Result.success("新增商品成功", product.getId());
}
return Result.fail("新增商品失败");
}
/**
* 商品列表查询(支持模糊查 + 排序 + 分页)
*/
@GetMapping("/list")
public Result<?> getProductList(
@RequestParam(required = false) String productName,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize,
@RequestParam(defaultValue = "id") String sortField,
@RequestParam(defaultValue = "desc") String sortType) {
Page<Product> page = new Page<>(pageNum, pageSize);
List<Product> productList = productService.getProductList(page, productName, sortField, sortType);
page.setRecords(productList);
log.info("查询商品列表成功,页码:{},条数:{}", pageNum, productList.size());
return Result.success("查询成功", page);
}
}
2. 购物车接口(Redis 存储)
购物车数据量较大且读取频繁,使用 Redis 存储是常见方案。AI 会自动生成 Redis 操作逻辑。
package com.example.ecommerce.controller;
import com.example.ecommerce.common.Result;
import com.example.ecommerce.entity.vo.CartVO;
import com.example.ecommerce.service.CartService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/cart")
@Slf4j
public class CartController {
@Resource
private CartService cartService;
/**
* 添加商品到购物车
*/
@PostMapping("/add")
public Result<?> addToCart(@RequestParam Long userId, @RequestParam Long productId, @RequestParam Integer buyNum) {
String checkMsg = cartService.checkBeforeAdd(userId, productId, buyNum);
if (checkMsg != null) {
return Result.fail(checkMsg);
}
boolean success = cartService.addCart(userId, productId, buyNum);
if (success) {
log.info("添加商品到购物车成功,用户 ID:{},商品 ID:{}", userId, productId);
return Result.success("添加购物车成功");
}
return Result.fail("添加购物车失败");
}
/**
* 查询用户购物车列表(含小计 + 总价)
*/
@GetMapping("/list")
public Result<?> getCartList(@RequestParam Long userId) {
List<CartVO> cartVOList = cartService.getCartList(userId);
BigDecimal totalAmount = cartVOList.stream()
.map(CartVO::getSubtotal)
.reduce(BigDecimal.ZERO, BigDecimal::add);
Map<String, Object> data = new HashMap<>();
data.put("cartList", cartVOList);
data.put("totalAmount", totalAmount);
return Result.success("查询购物车成功", data);
}
}
3. 订单服务与事务控制
订单创建涉及库存扣减、多表写入,必须保证事务一致性。以下是 Service 层的核心逻辑。
package com.example.ecommerce.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.ecommerce.entity.*;
import com.example.ecommerce.entity.vo.CartVO;
import com.example.ecommerce.mapper.*;
import com.example.ecommerce.service.CartService;
import com.example.ecommerce.service.OrderService;
import com.example.ecommerce.service.ProductService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
@Service
public class OrderServiceImpl implements OrderService {
@Resource
private OrderInfoMapper orderInfoMapper;
@Resource
private OrderItemMapper orderItemMapper;
@Resource
private ProductMapper productMapper;
@Resource
private CartService cartService;
@Resource
private RedisTemplate<String, Object> redisTemplate;
/**
* 创建订单(事务保证:扣库存 + 生成订单 + 清购物车要么全成,要么全失败)
*/
@Override
@Transactional(rollbackFor = Exception.class)
public String createOrder(Long userId, String productIds) {
// 1. 查询用户购物车中选中的商品
List<CartVO> cartVOList = cartService.getCheckedCartList(userId, productIds);
if (cartVOList.isEmpty()) {
throw new RuntimeException("购物车中无选中商品");
}
// 2. 计算订单总金额
BigDecimal totalAmount = cartVOList.stream()
.map(CartVO::getSubtotal)
.reduce(BigDecimal.ZERO, BigDecimal::add);
// 3. 生成唯一订单编号
String orderNo = generateOrderNo();
// 4. 扣减商品库存(加行锁防止超卖)
for (CartVO cartVO : cartVOList) {
Long productId = cartVO.getProductId();
Integer buyNum = cartVO.getBuyNum();
Product product = productMapper.selectByIdForUpdate(productId);
if (product == null || product.getStatus() == 0) {
throw new RuntimeException("商品" + cartVO.getProductName() + "已下架或不存在");
}
if (product.getStock() < buyNum) {
throw new RuntimeException("商品" + cartVO.getProductName() + "库存不足");
}
Product updateProduct = new Product();
updateProduct.setId(productId);
updateProduct.setStock(product.getStock() - buyNum);
productMapper.updateById(updateProduct);
}
// 5. 插入订单表
OrderInfo orderInfo = new OrderInfo();
orderInfo.setOrderNo(orderNo);
orderInfo.setUserId(userId);
orderInfo.setTotalAmount(totalAmount);
orderInfo.setPayStatus(0);
orderInfo.setOrderStatus(0);
orderInfo.setCreateTime(LocalDateTime.now());
orderInfoMapper.insert(orderInfo);
// 6. 插入订单项表
for (CartVO cartVO : cartVOList) {
OrderItem orderItem = new OrderItem();
orderItem.setOrderId(orderInfo.getId());
orderItem.setOrderNo(orderNo);
orderItem.setProductId(cartVO.getProductId());
orderItem.setProductName(cartVO.getProductName());
orderItem.setProductPrice(cartVO.getProductPrice());
orderItem.setBuyNum(cartVO.getBuyNum());
orderItem.setCreateTime(LocalDateTime.now());
orderItemMapper.insert(orderItem);
}
// 7. 清空购物车中已下单的商品
cartService.clearCheckedCart(userId, productIds);
return orderNo;
}
/**
* 生成唯一订单编号
*/
private String generateOrderNo() {
String timeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
String randomStr = String.format("%06d", new Random().nextInt(1000000));
return timeStr + randomStr;
}
/**
* 防重复提交校验
*/
@Override
public boolean checkRepeatRequest(String requestId) {
String redisKey = "order:repeat:" + requestId;
if (Boolean.TRUE.equals(redisTemplate.hasKey(redisKey))) {
return true;
}
redisTemplate.opsForValue().set(redisKey, "1", 5, TimeUnit.MINUTES);
return false;
}
}
四、测试与优化建议
1. 接口验证
使用 Postman 等工具对接口进行测试。例如调用 POST /api/cart/add,传入 userId=1&productId=1&buyNum=2,若库存不足,AI 生成的异常处理逻辑会返回明确的错误提示。
2. 性能优化
在实际运行中,AI 还能提供进一步的优化建议,例如:
- 库存预热:高并发下将热门商品库存缓存至 Redis。
- 超时取消:定时任务扫描未支付订单,自动恢复库存。
- 接口限流:防止恶意请求导致服务雪崩。
以下是 AI 生成的订单超时取消定时任务示例:
package com.example.ecommerce.task;
import com.example.ecommerce.entity.OrderInfo;
import com.example.ecommerce.mapper.OrderInfoMapper;
import com.example.ecommerce.mapper.OrderItemMapper;
import com.example.ecommerce.mapper.ProductMapper;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
@Component
public class OrderTimeoutTask {
@Resource
private OrderInfoMapper orderInfoMapper;
@Resource
private OrderItemMapper orderItemMapper;
@Resource
private ProductMapper productMapper;
/**
* 每 5 分钟执行一次:查询超过 30 分钟未支付的订单,改为已取消并恢复库存
*/
@Scheduled(cron = "0 0/5 * * * ?")
@Transactional(rollbackFor = Exception.class)
public void cancelTimeoutOrder() {
LocalDateTime timeoutTime = LocalDateTime.now().minusMinutes(30);
List<OrderInfo> timeoutOrders = orderInfoMapper.selectTimeoutOrders(0, timeoutTime);
for (OrderInfo order : timeoutOrders) {
order.setPayStatus(2);
order.setUpdateTime(LocalDateTime.now());
orderInfoMapper.updateById(order);
List<OrderItem> orderItems = orderItemMapper.selectByOrderId(order.getId());
for (OrderItem item : orderItems) {
Product product = productMapper.selectById(item.getProductId());
product.setStock(product.getStock() + item.getBuyNum());
productMapper.updateById(product);
}
}
}
}
五、总结
回顾整个开发过程,主要精力集中在需求梳理与结果验证上。数据库设计、代码编写、异常处理及优化建议均由 AI 辅助完成。相比传统开发模式,这种方式不仅大幅缩短了工期,还减少了人为疏忽导致的 Bug。
现在的开发早已不是单纯比拼代码书写速度,而是看谁能更好地利用工具提升生产力。AI 编程助手就像一位全能的技术顾问,让开发者能更专注于业务逻辑的设计与架构的合理性。


