本文目录导读:

我来为您提供一个完整的Java电商系统案例,包含核心模块和代码实现。
系统架构设计
技术栈
- 后端: Spring Boot 2.x, MyBatis Plus, Spring Security
- 前端: Vue.js 3, Element Plus
- 数据库: MySQL 8.0
- 缓存: Redis
- 搜索引擎: Elasticsearch
项目结构
ecommerce-system/
├── src/main/java/com/shop/
│ ├── controller/ # 控制器层
│ ├── service/ # 业务逻辑层
│ ├── mapper/ # 数据访问层
│ ├── entity/ # 实体类
│ ├── config/ # 配置类
│ ├── security/ # 安全配置
│ ├── dto/ # 数据传输对象
│ └── common/ # 通用工具类
├── resources/
│ ├── mapper/ # MyBatis映射文件
│ ├── static/ # 静态资源
│ └── application.yml # 配置文件
└── pom.xml
核心代码实现
商品模块
// 商品实体类
@Data
@TableName("product")
public class Product {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private String description;
private BigDecimal price;
private Integer stock;
private Long categoryId;
private String imageUrl;
private Integer status;
private Date createTime;
private Date updateTime;
}
// 商品控制器
@RestController
@RequestMapping("/api/product")
@Slf4j
public class ProductController {
@Autowired
private ProductService productService;
// 分页查询商品
@GetMapping("/list")
public Result<Page<Product>> getProductList(
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer size,
@RequestParam(required = false) Long categoryId,
@RequestParam(required = false) String keyword) {
Page<Product> productPage = productService.getProductList(page, size, categoryId, keyword);
return Result.success(productPage);
}
// 获取商品详情
@GetMapping("/{id}")
public Result<ProductDetail> getProductDetail(@PathVariable Long id) {
ProductDetail detail = productService.getProductDetail(id);
return Result.success(detail);
}
// 新增商品(管理端)
@PostMapping("/admin")
@PreAuthorize("hasRole('ADMIN')")
public Result<String> addProduct(@RequestBody Product product) {
productService.addProduct(product);
return Result.success("商品添加成功");
}
// 更新商品
@PutMapping("/admin")
@PreAuthorize("hasRole('ADMIN')")
public Result<String> updateProduct(@RequestBody Product product) {
productService.updateProduct(product);
return Result.success("商品更新成功");
}
}
购物车模块
// 购物车服务
@Service
@Slf4j
public class CartService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private ProductService productService;
private static final String CART_KEY_PREFIX = "cart:";
// 添加到购物车
public boolean addToCart(Long userId, Long productId, Integer quantity) {
// 检查商品库存
Product product = productService.getById(productId);
if (product == null || product.getStatus() != 1) {
throw new BusinessException("商品不存在或已下架");
}
if (quantity > product.getStock()) {
throw new BusinessException("商品库存不足");
}
String cartKey = CART_KEY_PREFIX + userId;
String hashKey = String.valueOf(productId);
// 使用Redis Hash存储购物车
CartItem cartItem = new CartItem();
cartItem.setProductId(productId);
cartItem.setProductName(product.getName());
cartItem.setPrice(product.getPrice());
cartItem.setQuantity(quantity);
redisTemplate.opsForHash().put(cartKey, hashKey, cartItem);
return true;
}
// 获取购物车列表
public List<CartItem> getCartList(Long userId) {
String cartKey = CART_KEY_PREFIX + userId;
Map<Object, Object> cartMap = redisTemplate.opsForHash().entries(cartKey);
List<CartItem> cartItems = cartMap.values().stream()
.map(obj -> (CartItem) obj)
.collect(Collectors.toList());
return cartItems;
}
// 更新购物车数量
public boolean updateCartQuantity(Long userId, Long productId, Integer quantity) {
String cartKey = CART_KEY_PREFIX + userId;
String hashKey = String.valueOf(productId);
if (!redisTemplate.opsForHash().hasKey(cartKey, hashKey)) {
throw new BusinessException("购物车中不存在该商品");
}
Product product = productService.getById(productId);
if (quantity > product.getStock()) {
throw new BusinessException("商品库存不足");
}
CartItem cartItem = (CartItem) redisTemplate.opsForHash().get(cartKey, hashKey);
cartItem.setQuantity(quantity);
redisTemplate.opsForHash().put(cartKey, hashKey, cartItem);
return true;
}
// 删除购物车商品
public boolean removeFromCart(Long userId, Long productId) {
String cartKey = CART_KEY_PREFIX + userId;
String hashKey = String.valueOf(productId);
redisTemplate.opsForHash().delete(cartKey, hashKey);
return true;
}
// 清空购物车
public boolean clearCart(Long userId) {
String cartKey = CART_KEY_PREFIX + userId;
redisTemplate.delete(cartKey);
return true;
}
}
订单模块
// 订单服务
@Service
@Slf4j
@Transactional
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private OrderItemMapper orderItemMapper;
@Autowired
private ProductService productService;
@Autowired
private CartService cartService;
// 创建订单
public Order createOrder(Long userId, List<CartItem> cartItems,
String address, String phone) {
try {
// 1. 计算订单金额
BigDecimal totalAmount = BigDecimal.ZERO;
for (CartItem item : cartItems) {
totalAmount = totalAmount.add(item.getPrice().multiply(
new BigDecimal(item.getQuantity())));
}
// 2. 创建订单
Order order = new Order();
order.setUserId(userId);
order.setOrderNo(generateOrderNo());
order.setTotalAmount(totalAmount);
order.setStatus(OrderStatus.PENDING_PAYMENT);
order.setAddress(address);
order.setPhone(phone);
order.setCreateTime(new Date());
orderMapper.insert(order);
// 3. 创建订单明细
for (CartItem item : cartItems) {
OrderItem orderItem = new OrderItem();
orderItem.setOrderId(order.getId());
orderItem.setProductId(item.getProductId());
orderItem.setProductName(item.getProductName());
orderItem.setPrice(item.getPrice());
orderItem.setQuantity(item.getQuantity());
orderItemMapper.insert(orderItem);
// 4. 扣减库存
productService.decreaseStock(item.getProductId(), item.getQuantity());
}
// 5. 清空购物车
cartService.clearCart(userId);
return order;
} catch (Exception e) {
log.error("创建订单失败", e);
throw new BusinessException("创建订单失败");
}
}
// 支付订单
public boolean payOrder(Long orderId, Long userId) {
Order order = orderMapper.selectById(orderId);
if (order == null || !order.getUserId().equals(userId)) {
throw new BusinessException("订单不存在");
}
if (order.getStatus() != OrderStatus.PENDING_PAYMENT) {
throw new BusinessException("订单状态不正确");
}
// 模拟支付操作
order.setStatus(OrderStatus.PAID);
orderMapper.updateById(order);
return true;
}
// 取消订单
public boolean cancelOrder(Long orderId, Long userId) {
Order order = orderMapper.selectById(orderId);
if (order == null || !order.getUserId().equals(userId)) {
throw new BusinessException("订单不存在");
}
if (order.getStatus() != OrderStatus.PENDING_PAYMENT) {
throw new BusinessException("订单状态不正确");
}
order.setStatus(OrderStatus.CANCELED);
orderMapper.updateById(order);
// 恢复库存
List<OrderItem> orderItems = orderItemMapper.selectByOrderId(orderId);
for (OrderItem item : orderItems) {
productService.increaseStock(item.getProductId(), item.getQuantity());
}
return true;
}
// 生成订单号
private String generateOrderNo() {
return System.currentTimeMillis() +
String.format("%06d", new Random().nextInt(1000000));
}
}
用户认证模块
// 用户实体类
@Data
@TableName("user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String username;
private String password;
private String email;
private String phone;
private Integer status;
private Date createTime;
}
// 安全配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtAuthenticationFilter jwtFilter;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/user/register", "/api/user/login").permitAll()
.antMatchers("/api/product/**").permitAll()
.antMatchers("/api/cart/**", "/api/order/**").hasRole("USER")
.antMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
支付模块
// 支付服务
@Service
@Slf4j
public class PaymentService {
@Autowired
private OrderService orderService;
// 支付宝支付
public String alipay(Long orderId, BigDecimal amount) {
AlipayClient alipayClient = createAlipayClient();
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setNotifyUrl("https://api.shop.com/payment/notify");
request.setReturnUrl("https://www.shop.com/payment/result");
// 构建支付参数
JSONObject bizContent = new JSONObject();
bizContent.put("out_trade_no", getOrderNo(orderId));
bizContent.put("total_amount", amount.toString());
bizContent.put("subject", "商城购物");
bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
request.setBizContent(bizContent.toString());
try {
AlipayTradePagePayResponse response =
alipayClient.pageExecute(request);
return response.getBody();
} catch (AlipayApiException e) {
log.error("支付宝支付异常", e);
throw new BusinessException("支付宝支付异常");
}
}
// 微信支付
public Map<String, String> wxpay(Long orderId, BigDecimal amount) {
// 构建微信支付参数
Map<String, String> params = new HashMap<>();
params.put("appid", config.getWxAppId());
params.put("mch_id", config.getWxMchId());
params.put("out_trade_no", getOrderNo(orderId));
params.put("total_fee", String.valueOf(amount.multiply(new BigDecimal(100)).intValue()));
try {
// 生成支付二维码
String qrCodeUrl = generateQrCode(createWxPayOrder(params));
Map<String, String> result = new HashMap<>();
result.put("code_url", qrCodeUrl);
return result;
} catch (Exception e) {
log.error("微信支付异常", e);
throw new BusinessException("微信支付异常");
}
}
// 支付回调处理
public String handleNotify(Map<String, String> params) {
String orderNo = params.get("out_trade_no");
String tradeStatus = params.get("trade_status");
if ("TRADE_SUCCESS".equals(tradeStatus)) {
// 找到订单并更新状态
Order order = orderService.getByOrderNo(orderNo);
orderService.payOrder(order.getId(), order.getUserId());
return "success";
}
return "fail";
}
}
配置文件
# application.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/ecommerce?useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
redis:
host: localhost
port: 6379
database: 0
timeout: 5000ms
elasticsearch:
uris: http://localhost:9200
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.shop.entity
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 自定义配置
shop:
jwt:
secret: shop-secret-key
expiration: 86400000 # 24小时
wxpay:
app-id: your-wx-appid
mch-id: your-mch-id
api-key: your-api-key
alipay:
app-id: your-alipay-appid
private-key: your-private-key
public-key: your-public-key
数据库设计
-- 商品表 CREATE TABLE `product` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(200) NOT NULL COMMENT '商品名称', `description` text COMMENT '商品描述', `price` decimal(10,2) NOT NULL COMMENT '价格', `stock` int(11) NOT NULL DEFAULT 0 COMMENT '库存', `category_id` bigint(20) NOT NULL COMMENT '分类ID', `image_url` varchar(500) DEFAULT NULL COMMENT '图片URL', `status` tinyint(4) NOT NULL DEFAULT 1 COMMENT '状态:1上架 0下架', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 用户表 CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL COMMENT '用户名', `password` varchar(200) NOT NULL COMMENT '密码', `email` varchar(100) DEFAULT NULL, `phone` varchar(20) DEFAULT NULL, `status` tinyint(4) NOT NULL DEFAULT 1, `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 订单表 CREATE TABLE `order` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `order_no` varchar(50) NOT NULL COMMENT '订单号', `user_id` bigint(20) NOT NULL, `total_amount` decimal(12,2) NOT NULL COMMENT '订单金额', `status` tinyint(4) NOT NULL COMMENT '订单状态', `address` varchar(500) NOT NULL COMMENT '收货地址', `phone` varchar(20) NOT NULL, `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `pay_time` datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_order_no` (`order_no`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 订单明细表 CREATE TABLE `order_item` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `order_id` bigint(20) NOT NULL, `product_id` bigint(20) NOT NULL, `product_name` varchar(200) NOT NULL, `price` decimal(10,2) NOT NULL, `quantity` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
前端页面示例(Vue 3)
<!-- 商品列表组件 -->
<template>
<div class="product-list">
<el-row :gutter="20">
<el-col :span="6" v-for="product in products" :key="product.id">
<el-card class="product-card" shadow="hover">
<img :src="product.imageUrl" class="product-image"/>
<div class="product-info">
<h3>{{ product.name }}</h3>
<p class="price">¥{{ product.price }}</p>
<el-button type="primary" @click="addToCart(product)">
加入购物车
</el-button>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import axios from 'axios'
export default {
name: 'ProductList',
setup() {
const products = ref([])
const getProducts = async () => {
try {
const res = await axios.get('/api/product/list', {
params: { page: 1, size: 10 }
})
products.value = res.data.data.records
} catch (error) {
ElMessage.error('获取商品列表失败')
}
}
const addToCart = async (product) => {
try {
await axios.post('/api/cart/add', {
productId: product.id,
quantity: 1
})
ElMessage.success('已加入购物车')
} catch (error) {
ElMessage.error('加入购物车失败')
}
}
onMounted(() => {
getProducts()
})
return {
products,
addToCart
}
}
}
</script>
这个电商系统案例提供了完整的核心功能实现,包括商品管理、购物车、订单处理、用户认证和支付功能,您可以根据实际需求进行扩展和完善。