Java电商系统案例

wen java案例 3

本文目录导读:

Java电商系统案例

  1. 系统架构设计
  2. 核心代码实现
  3. 配置文件
  4. 数据库设计
  5. 前端页面示例(Vue 3)

我来为您提供一个完整的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>

这个电商系统案例提供了完整的核心功能实现,包括商品管理、购物车、订单处理、用户认证和支付功能,您可以根据实际需求进行扩展和完善。

抱歉,评论功能暂时关闭!