本文目录导读:

我将为您提供一个完整的Java业务系统案例——在线商城订单管理系统,包含核心业务逻辑、代码实现和系统设计。
这是一个基于Spring Boot的在线商城订单管理系统,包含用户、商品、订单、购物车等核心模块。
系统架构设计
技术栈
- 后端框架: Spring Boot 2.7.x
- ORM框架: MyBatis-Plus
- 数据库: MySQL 8.0
- 安全认证: Spring Security + JWT
- 缓存: Redis
- 构建工具: Maven
核心业务模块
- 用户模块(注册、登录、权限管理)
- 商品模块(商品管理、库存管理)
- 购物车模块(添加、修改、删除、结算)
- 订单模块(下单、支付、取消、退款)
- 优惠券模块(领取、使用)
核心代码实现
实体类设计
// 用户实体类
@Data
@TableName("user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String username;
private String password;
private String nickname;
private String email;
private String phone;
private Integer status; // 1-正常 0-禁用
private LocalDateTime createTime;
private LocalDateTime updateTime;
}
// 商品实体类
@Data
@TableName("product")
public class Product {
@TableId(type = IdType.AUTO)
private Long id;
private String productName;
private String description;
private BigDecimal price;
private Integer stock; // 库存
private String category; // 分类
private Integer status; // 1-上架 0-下架
private LocalDateTime createTime;
private LocalDateTime updateTime;
@Version // 乐观锁版本号
private Integer version;
}
// 订单实体类
@Data
@TableName("orders")
public class Order {
@TableId(type = IdType.ASSIGN_ID)
private String orderNo; // 订单号
private Long userId;
private BigDecimal totalAmount; // 总金额
private Integer status; // 1-待付款 2-已付款 3-已发货 4-已完成 5-已取消
private String address; // 收货地址
private String phone; // 联系电话
private LocalDateTime createTime;
private LocalDateTime payTime;
private LocalDateTime deliveryTime;
private LocalDateTime completeTime;
}
// 订单明细
@Data
@TableName("order_item")
public class OrderItem {
@TableId(type = IdType.AUTO)
private Long id;
private String orderNo;
private Long productId;
private Integer quantity;
private BigDecimal price; // 商品单价
private BigDecimal totalPrice; // 小计
}
业务层实现
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private ProductMapper productMapper;
@Autowired
private OrderItemMapper orderItemMapper;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private IdGenerator idGenerator;
@Transactional(rollbackFor = Exception.class)
@Override
public Order createOrder(Long userId, List<CartItemDTO> cartItems) {
// 1. 计算订单金额并创建订单
BigDecimal totalAmount = BigDecimal.ZERO;
List<OrderItem> orderItems = new ArrayList<>();
// 2. 验证商品库存并锁定
for (CartItemDTO item : cartItems) {
Product product = productMapper.selectById(item.getProductId());
// 使用乐观锁防止超卖
int result = productMapper.deductStock(item.getProductId(),
item.getQuantity(),
product.getVersion());
if (result == 0) {
throw new BusinessException("商品:" + product.getProductName() + " 库存不足");
}
// 计算金额
BigDecimal itemTotal = product.getPrice()
.multiply(BigDecimal.valueOf(item.getQuantity()));
totalAmount = totalAmount.add(itemTotal);
// 构建订单明细
OrderItem orderItem = new OrderItem();
orderItem.setProductId(product.getId());
orderItem.setQuantity(item.getQuantity());
orderItem.setPrice(product.getPrice());
orderItem.setTotalPrice(itemTotal);
orderItems.add(orderItem);
}
// 3. 创建订单
String orderNo = idGenerator.generateOrderNo();
Order order = new Order();
order.setOrderNo(orderNo);
order.setUserId(userId);
order.setTotalAmount(totalAmount);
order.setStatus(1); // 待付款
order.setCreateTime(LocalDateTime.now());
orderMapper.insert(order);
// 4. 保存订单明细
orderItems.forEach(item -> {
item.setOrderNo(orderNo);
orderItemMapper.insert(item);
});
// 5. 缓存订单信息(用于超时自动取消)
redisTemplate.opsForValue()
.set("order:timeout:" + orderNo, orderNo, 30, TimeUnit.MINUTES);
log.info("订单创建成功:{}", orderNo);
return order;
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean cancelOrder(String orderNo, Long userId) {
// 1. 查询订单
Order order = orderMapper.selectByOrderNo(orderNo);
// 2. 校验订单状态
if (!order.getUserId().equals(userId)) {
throw new BusinessException("无权操作该订单");
}
if (order.getStatus() != 1) {
throw new BusinessException("订单当前状态不可取消");
}
// 3. 取消订单
order.setStatus(5); // 已取消
orderMapper.updateById(order);
// 4. 回滚库存
List<OrderItem> items = orderItemMapper.selectByOrderNo(orderNo);
for (OrderItem item : items) {
productMapper.increaseStock(item.getProductId(), item.getQuantity());
}
// 5. 删除缓存
redisTemplate.delete("order:timeout:" + orderNo);
return true;
}
@Transactional(rollbackFor = Exception.class)
@Override
public boolean payOrder(String orderNo) {
// 1. 查询订单
Order order = orderMapper.selectByOrderNo(orderNo);
if (order.getStatus() != 1) {
throw new BusinessException("订单状态不正确");
}
// 2. 调用支付系统(模拟)
PaymentResult result = mockPayment(order.getTotalAmount());
if (!result.isSuccess()) {
throw new BusinessException("支付失败");
}
// 3. 更新订单状态
order.setStatus(2); // 已付款
order.setPayTime(LocalDateTime.now());
orderMapper.updateById(order);
return true;
}
@Override
public PageInfo<OrderVO> queryOrderList(Long userId, Integer status,
Integer pageNum, Integer pageSize) {
// 构建查询条件
Page<Order> page = new Page<>(pageNum, pageSize);
LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(userId != null, Order::getUserId, userId);
queryWrapper.eq(status != null, Order::getStatus, status);
queryWrapper.orderByDesc(Order::getCreateTime);
Page<Order> orderPage = orderMapper.selectPage(page, queryWrapper);
// 转换为VO
PageInfo<OrderVO> result = new PageInfo<>();
BeanUtils.copyProperties(orderPage, result);
return result;
}
}
商品库存管理(防止超卖)
@Mapper
public interface ProductMapper extends BaseMapper<Product> {
// 乐观锁扣减库存
@Update("UPDATE product SET stock = stock - #{quantity}, " +
"version = version + 1 " +
"WHERE id = #{productId} AND stock >= #{quantity} " +
"AND version = #{version}")
int deductStock(@Param("productId") Long productId,
@Param("quantity") Integer quantity,
@Param("version") Integer version);
// 恢复库存
@Update("UPDATE product SET stock = stock + #{quantity} " +
"WHERE id = #{productId}")
int increaseStock(@Param("productId") Long productId,
@Param("quantity") Integer quantity);
// 分布式锁方式(使用Redis)
default boolean deductStockWithLock(Long productId, Integer quantity) {
// 实际使用Redisson等分布式锁组件
return false;
}
}
购物车服务
@Service
@Slf4j
public class CartServiceImpl implements CartService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
private static final String CART_PREFIX = "cart:";
@Override
public void addToCart(Long userId, Long productId, Integer quantity) {
String cartKey = CART_PREFIX + userId;
// 获取购物车
Map<Object, Object> cart = redisTemplate.opsForHash().entries(cartKey);
// 添加或更新商品
Integer existingQty = (Integer) cart.get(productId.toString());
int newQty = quantity + (existingQty == null ? 0 : existingQty);
redisTemplate.opsForHash().put(cartKey, productId.toString(), newQty);
// 设置过期时间
redisTemplate.expire(cartKey, 7, TimeUnit.DAYS);
}
@Override
public List<CartItemVO> getCartItems(Long userId) {
String cartKey = CART_PREFIX + userId;
Map<Object, Object> cart = redisTemplate.opsForHash().entries(cartKey);
List<CartItemVO> items = new ArrayList<>();
for (Map.Entry<Object, Object> entry : cart.entrySet()) {
Long productId = Long.valueOf((String) entry.getKey());
Integer quantity = (Integer) entry.getValue();
// 查询商品信息
Product product = productMapper.selectById(productId);
if (product != null) {
CartItemVO item = new CartItemVO();
item.setProductId(productId);
item.setProductName(product.getProductName());
item.setPrice(product.getPrice());
item.setQuantity(quantity);
item.setStock(product.getStock());
items.add(item);
}
}
return items;
}
@Override
public void clearCart(Long userId) {
String cartKey = CART_PREFIX + userId;
redisTemplate.delete(cartKey);
}
}
优惠券功能
@Service
public class CouponServiceImpl implements CouponService {
@Override
@Transactional(rollbackFor = Exception.class)
public boolean receiveCoupon(Long userId, Long couponTypeId) {
// 1. 查询优惠券类型
CouponType couponType = couponTypeMapper.selectById(couponTypeId);
if (couponType == null) {
throw new BusinessException("优惠券不存在");
}
// 2. 检查领取数量限制
LambdaQueryWrapper<UserCoupon> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(UserCoupon::getUserId, userId)
.eq(UserCoupon::getCouponTypeId, couponTypeId);
Long count = userCouponMapper.selectCount(wrapper);
if (count >= couponType.getReceiveLimit()) {
throw new BusinessException("已达领取上限");
}
// 3. 校验总数量
if (couponType.getRemainingCount() <= 0) {
throw new BusinessException("优惠券已领完");
}
// 4. 扣减库存并保存
int update = couponTypeMapper.decreaseCount(couponTypeId);
if (update == 0) {
throw new BusinessException("优惠券已领完");
}
UserCoupon userCoupon = new UserCoupon();
userCoupon.setUserId(userId);
userCoupon.setCouponTypeId(couponTypeId);
userCoupon.setStatus(1); // 未使用
userCoupon.setReceiveTime(LocalDateTime.now());
LocalDateTime expireTime = LocalDateTime.now()
.plusDays(couponType.getValidityDays());
userCoupon.setExpireTime(expireTime);
userCouponMapper.insert(userCoupon);
return true;
}
@Override
public BigDecimal calcDiscount(Long userId, BigDecimal totalAmount) {
// 查找用户最优的可用优惠券并计算折扣
LambdaQueryWrapper<UserCoupon> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(UserCoupon::getUserId, userId)
.eq(UserCoupon::getStatus, 1)
.gt(UserCoupon::getExpireTime, LocalDateTime.now())
.orderByDesc(UserCoupon::getReceiveTime);
List<UserCoupon> coupons = userCouponMapper.selectList(wrapper);
BigDecimal maxDiscount = BigDecimal.ZERO;
for (UserCoupon coupon : coupons) {
CouponType type = couponTypeMapper.selectById(coupon.getCouponTypeId());
BigDecimal discount = calculateDiscount(type, totalAmount);
if (discount.compareTo(maxDiscount) > 0) {
maxDiscount = discount;
}
}
return maxDiscount;
}
}
定时任务(超时未支付自动取消)
@Component
@Slf4j
public class OrderTimeoutTask {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// 每10分钟执行一次
@Scheduled(fixedDelay = 600000)
public void processTimeoutOrders() {
log.info("开始处理超时订单...");
// 获取超时订单(30分钟未支付)
LocalDateTime timeoutTime = LocalDateTime.now().minusMinutes(30);
LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Order::getStatus, 1) // 待付款
.lt(Order::getCreateTime, timeoutTime);
List<Order> timeoutOrders = orderMapper.selectList(wrapper);
for (Order order : timeoutOrders) {
try {
// 检查是否在Redis中存在(防止并发处理)
Boolean success = redisTemplate.opsForValue()
.setIfAbsent("cancel:lock:" + order.getOrderNo(), "1",
10, TimeUnit.MINUTES);
if (Boolean.TRUE.equals(success)) {
// 取消订单
order.setStatus(5);
orderMapper.updateById(order);
// 回滚库存
rollbackStock(order.getOrderNo());
log.info("订单 {} 已超时取消", order.getOrderNo());
}
} catch (Exception e) {
log.error("取消订单失败:{}", order.getOrderNo(), e);
}
}
}
private void rollbackStock(String orderNo) {
// 回滚库存逻辑
}
}
JWT认证实现
@Component
public class JwtTokenProvider {
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private Long expiration;
public String generateToken(User user) {
Date now = new Date();
Date expiryDate = new Date(now.getTime() + expiration);
return Jwts.builder()
.setSubject(user.getUsername())
.claim("userId", user.getId())
.claim("nickname", user.getNickname())
.setIssuedAt(now)
.setExpiration(expiryDate)
.signWith(SignatureAlgorithm.HS256, secret)
.compact();
}
public Long getUserIdFromToken(String token) {
Claims claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
return ((Number) claims.get("userId")).longValue();
}
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
return true;
} catch (Exception e) {
return false;
}
}
}
库存安全控制(Redis预扣减)
@Component
public class StockService {
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private ProductMapper productMapper;
private static final String STOCK_KEY = "product:stock:";
private static final String LOCK_KEY = "product:lock:";
@PostConstruct
public void initStock() {
// 初始化库存到Redis
List<Product> products = productMapper.selectList(null);
for (Product product : products) {
redisTemplate.opsForValue()
.set(STOCK_KEY + product.getId(), String.valueOf(product.getStock()));
}
}
@Transactional(rollbackFor = Exception.class)
public boolean tryDeductStock(Long productId, Integer quantity) {
// 使用Redis实现分布式锁
String lockKey = LOCK_KEY + productId;
String requestId = UUID.randomUUID().toString();
Boolean locked = redisTemplate.opsForValue()
.setIfAbsent(lockKey, requestId, 10, TimeUnit.SECONDS);
if (!Boolean.TRUE.equals(locked)) {
throw new BusinessException("系统繁忙,请稍后重试");
}
try {
// 原子性扣减库存
String stockStr = redisTemplate.opsForValue().get(STOCK_KEY + productId);
int stock = Integer.parseInt(stockStr);
if (stock < quantity) {
throw new BusinessException("库存不足");
}
// LUA脚本保证原子性
String luaScript =
"local stock = redis.call('get', KEYS[1]) " +
"if tonumber(stock) >= tonumber(ARGV[1]) then " +
" redis.call('decrby', KEYS[1], ARGV[1]) " +
" return 1 " +
"else " +
" return 0 " +
"end";
Long result = redisTemplate.execute(
new DefaultRedisScript<>(luaScript, Long.class),
Arrays.asList(STOCK_KEY + productId),
String.valueOf(quantity)
);
return result != null && result == 1L;
} finally {
// 释放锁
releaseLock(lockKey, requestId);
}
}
@Transactional(rollbackFor = Exception.class)
public void confirmStock() {
// 订单创建成功后,同步扣减数据库库存
// 并发控制使用乐观锁
}
private void releaseLock(String lockKey, String requestId) {
String luaScript =
"if redis.call('get', KEYS[1]) == ARGV[1] then " +
" return redis.call('del', KEYS[1]) " +
"else " +
" return 0 " +
"end";
redisTemplate.execute(
new DefaultRedisScript<>(luaScript, Long.class),
Arrays.asList(lockKey),
requestId
);
}
}
数据库设计
-- 用户表
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(100) NOT NULL COMMENT '密码(加密存储)',
`nickname` varchar(50) DEFAULT NULL COMMENT '昵称',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号',
`status` tinyint(4) DEFAULT '1' COMMENT '状态:1正常 0禁用',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 商品表
CREATE TABLE `product` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`product_name` varchar(100) NOT NULL COMMENT '商品名称',
`description` text COMMENT '商品描述',
`price` decimal(10,2) NOT NULL COMMENT '价格',
`stock` int(11) NOT NULL DEFAULT '0' COMMENT '库存',
`category` varchar(50) DEFAULT NULL COMMENT '分类',
`status` tinyint(4) DEFAULT '1' COMMENT '状态:1上架 0下架',
`version` int(11) DEFAULT '0' COMMENT '乐观锁版本号',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_category` (`category`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 订单表
CREATE TABLE `orders` (
`order_no` varchar(32) NOT NULL COMMENT '订单号',
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
`total_amount` decimal(10,2) NOT NULL COMMENT '订单总金额',
`status` tinyint(4) NOT NULL COMMENT '状态:1待付款 2已付款 3已发货 4已完成 5已取消',
`address` varchar(200) DEFAULT NULL COMMENT '收货地址',
`phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`pay_time` datetime DEFAULT NULL,
`delivery_time` datetime DEFAULT NULL,
`complete_time` datetime DEFAULT NULL,
PRIMARY KEY (`order_no`),
KEY `idx_user_id` (`user_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 订单明细表
CREATE TABLE `order_item` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`order_no` varchar(32) NOT NULL,
`product_id` bigint(20) NOT NULL,
`quantity` int(11) NOT NULL COMMENT '数量',
`price` decimal(10,2) NOT NULL COMMENT '成交单价',
`total_price` decimal(10,2) NOT NULL COMMENT '小计',
PRIMARY KEY (`id`),
KEY `idx_order_no` (`order_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
业务处理流程
下单流程
用户提交购物车商品
2. 系统验证用户信息(JWT)
3. 计算订单金额(含优惠券)
4. 启用Redis + LUA脚本扣减库存
5. 创建订单和订单明细(事务)
6. 同步数据库库存(乐观锁)
7. 缓存订单信息(30分钟超时)
8. 返回支付信息
支付流程
用户选择支付方式
2. 调用第三方支付(模拟)
3. 支付回调验证签名
4. 更新订单状态(状态机)
5. 发送通知(短信/邮件)
6. 清理缓存数据
安全与优化策略
安全措施
// 1. 防SQL注入
@schema-rule(value = "column", strategy = SqlGuard.STRATEGY_ALLOWED)
private String orderField;
// 2. 防XSS攻击
@Component
public class XssFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
XssWrapper xssRequest = new XssWrapper((HttpServletRequest) request);
chain.doFilter(xssRequest, response);
}
}
// 3. 接口防刷
@Component
public class RateLimitInterceptor implements HandlerInterceptor {
private static final int MAX_ATTEMPTS = 5;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
String ip = getClientIp(request);
String key = "rate:limit:" + ip;
Long count = redisTemplate.opsForValue().increment(key);
if (count != null && count == 1) {
redisTemplate.expire(key, 1, TimeUnit.MINUTES);
}
if (count != null && count > MAX_ATTEMPTS) {
throw new BusinessException("请求过于频繁,请稍后再试");
}
return true;
}
}
性能优化
// 1. 缓存优化
@Cacheable(value = "product", key = "#productId",
unless = "#result == null", cacheManager = "redisCacheManager")
public Product getProductDetail(Long productId) {
return productMapper.selectById(productId);
}
// 2. 批量操作
public List<OrderItem> batchQueryItems(String orderNo) {
// 使用MyBatis的foreach批量查询
return orderItemMapper.selectList(
new LambdaQueryWrapper<OrderItem>()
.eq(OrderItem::getOrderNo, orderNo)
.apply("id LIMIT 500")
);
}
// 3. 数据库优化
// 使用EXPLAIN分析SQL
// 合理建立联合索引
// 分库分表策略
测试用例
@SpringBootTest
@Transactional
public class OrderServiceTest {
@Autowired
private OrderService orderService;
@Autowired
private UserMapper userMapper;
@Test
public void testCreateOrder() {
// 准备数据
User user = new User();
user.setUsername("testuser");
user.setPassword("123456");
userMapper.insert(user);
List<CartItemDTO> items = new ArrayList<>();
CartItemDTO item = new CartItemDTO();
item.setProductId(1L);
item.setQuantity(2);
items.add(item);
// 执行测试
Order order = orderService.createOrder(user.getId(), items);
// 验证结果
assertNotNull(order);
assertEquals(1, order.getStatus().intValue());
assertNotNull(order.getOrderNo());
}
@Test
public void testCancelOrder() {
// 测试取消订单逻辑
}
@Test
public void testPayOrder() {
// 测试支付逻辑
}
@Test
void testConcurrentStock() throws InterruptedException {
// 并发测试库存扣减
int threadCount = 100;
CountDownLatch latch = new CountDownLatch(threadCount);
AtomicInteger successCount = new AtomicInteger(0);
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < threadCount; i++) {
executor.execute(() -> {
try {
// 模拟并发购买
boolean result = stockService.tryDeductStock(1L, 1);
if (result) {
successCount.incrementAndGet();
}
} finally {
latch.countDown();
}
});
}
latch.await();
assertEquals(10, successCount.get()); // 假设库存为10
}
}
这个电商订单系统涵盖了:
- 核心业务:用户、商品、购物车、订单、优惠券完整闭环
- 高并发处理:Redis缓存 + 乐观锁 + 分布式锁防止超卖
- 安全机制:JWT认证、权限控制、防SQL注入、防XSS
- 事务管理:保证数据一致性
- 性能优化:缓存策略、SQL优化、索引设计
此案例展示了Java业务系统开发中的常见问题解决方案,可作为实际项目开发的参考,根据具体业务需求,可以进一步扩展如:分类管理、轮播图、秒杀活动、物流跟踪等功能模块。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播