本文目录导读:

我来为您设计一个完整的Java票据(发票)管理系统案例,包含核心功能模块和代码实现。
票据管理系统架构设计
项目结构
ticket-system/
├── src/main/java/com/example/ticket/
│ ├── model/ # 实体类
│ ├── dao/ # 数据访问层
│ ├── service/ # 业务逻辑层
│ ├── controller/ # 控制层
│ └── util/ # 工具类
└── src/main/resources/ # 配置文件
核心实体类设计
1 票据实体类(Ticket)
package com.example.ticket.model;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
/**
* 票据实体类
*/
public class Ticket {
// 票据ID
private Long id;
// 票据编号
private String ticketNo;
// 票据类型
private TicketType type;
// 开票方
private String issuer;
// 收票方
private String payer;
// 票据金额
private BigDecimal amount;
// 税率
private BigDecimal taxRate;
// 税额
private BigDecimal taxAmount;
// 价税合计
private BigDecimal totalAmount;
// 开票日期
private LocalDateTime issueDate;
// 有效期
private LocalDateTime validDate;
// 状态
private TicketStatus status;
// 备注
private String remark;
// 创建时间
private LocalDateTime createTime;
// 更新时间
private LocalDateTime updateTime;
// 票据明细
private List<TicketItem> items;
// 构造函数
public Ticket() {
this.createTime = LocalDateTime.now();
this.updateTime = LocalDateTime.now();
this.status = TicketStatus.PENDING;
}
// Getter和Setter方法
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTicketNo() {
return ticketNo;
}
public void setTicketNo(String ticketNo) {
this.ticketNo = ticketNo;
}
public TicketType getType() {
return type;
}
public void setType(TicketType type) {
this.type = type;
}
public String getIssuer() {
return issuer;
}
public void setIssuer(String issuer) {
this.issuer = issuer;
}
public String getPayer() {
return payer;
}
public void setPayer(String payer) {
this.payer = payer;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
calculateTax();
}
public BigDecimal getTaxRate() {
return taxRate;
}
public void setTaxRate(BigDecimal taxRate) {
this.taxRate = taxRate;
calculateTax();
}
public BigDecimal getTaxAmount() {
return taxAmount;
}
public void setTaxAmount(BigDecimal taxAmount) {
this.taxAmount = taxAmount;
}
public BigDecimal getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(BigDecimal totalAmount) {
this.totalAmount = totalAmount;
}
public LocalDateTime getIssueDate() {
return issueDate;
}
public void setIssueDate(LocalDateTime issueDate) {
this.issueDate = issueDate;
}
public LocalDateTime getValidDate() {
return validDate;
}
public void setValidDate(LocalDateTime validDate) {
this.validDate = validDate;
}
public TicketStatus getStatus() {
return status;
}
public void setStatus(TicketStatus status) {
this.status = status;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public LocalDateTime getUpdateTime() {
return updateTime;
}
public void setUpdateTime(LocalDateTime updateTime) {
this.updateTime = updateTime;
}
public List<TicketItem> getItems() {
return items;
}
public void setItems(List<TicketItem> items) {
this.items = items;
}
// 计算税额和总金额
private void calculateTax() {
if (amount != null && taxRate != null) {
this.taxAmount = amount.multiply(taxRate);
this.totalAmount = amount.add(taxAmount);
}
}
}
2 票据明细类(TicketItem)
package com.example.ticket.model;
import java.math.BigDecimal;
/**
* 票据明细实体类
*/
public class TicketItem {
// 明细ID
private Long id;
// 票据ID
private Long ticketId;
// 项目名称
private String itemName;
// 规格型号
private String specification;
// 单位
private String unit;
// 数量
private Integer quantity;
// 单价
private BigDecimal price;
// 金额
private BigDecimal amount;
// 税率
private BigDecimal taxRate;
// 税额
private BigDecimal taxAmount;
// 构造函数
public TicketItem() {
}
public TicketItem(String itemName, Integer quantity, BigDecimal price, BigDecimal taxRate) {
this.itemName = itemName;
this.quantity = quantity;
this.price = price;
this.taxRate = taxRate;
calculateAmount();
}
// 计算金额和税额
private void calculateAmount() {
if (quantity != null && price != null) {
this.amount = price.multiply(BigDecimal.valueOf(quantity));
if (taxRate != null) {
this.taxAmount = amount.multiply(taxRate);
}
}
}
// Getter和Setter方法
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getTicketId() {
return ticketId;
}
public void setTicketId(Long ticketId) {
this.ticketId = ticketId;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public String getSpecification() {
return specification;
}
public void setSpecification(String specification) {
this.specification = specification;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
calculateAmount();
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
calculateAmount();
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public BigDecimal getTaxRate() {
return taxRate;
}
public void setTaxRate(BigDecimal taxRate) {
this.taxRate = taxRate;
calculateAmount();
}
public BigDecimal getTaxAmount() {
return taxAmount;
}
public void setTaxAmount(BigDecimal taxAmount) {
this.taxAmount = taxAmount;
}
}
3 枚举类型定义
package com.example.ticket.model;
/**
* 票据类型枚举
*/
public enum TicketType {
INVOICE("发票"),
RECEIPT("收据"),
VOUCHER("凭证"),
TICKET("车票"),
CHECK("支票");
private String description;
TicketType(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
/**
* 票据状态枚举
*/
public enum TicketStatus {
PENDING("待审核"),
APPROVED("已通过"),
REJECTED("已拒绝"),
CANCELLED("已作废"),
EXPIRED("已过期");
private String description;
TicketStatus(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
数据访问层(DAO)
package com.example.ticket.dao;
import com.example.ticket.model.Ticket;
import com.example.ticket.model.TicketStatus;
import com.example.ticket.model.TicketType;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* 票据数据访问层(使用内存存储模拟数据库)
*/
public class TicketDao {
// 使用ConcurrentHashMap模拟数据库存储
private static final Map<Long, Ticket> ticketStore = new ConcurrentHashMap<>();
private static long idGenerator = 1;
// 保存票据
public Ticket save(Ticket ticket) {
if (ticket.getId() == null) {
ticket.setId(idGenerator++);
}
ticket.setUpdateTime(java.time.LocalDateTime.now());
ticketStore.put(ticket.getId(), ticket);
return ticket;
}
// 根据ID查询票据
public Ticket findById(Long id) {
return ticketStore.get(id);
}
// 查询所有票据
public List<Ticket> findAll() {
return new ArrayList<>(ticketStore.values());
}
// 根据状态查询
public List<Ticket> findByStatus(TicketStatus status) {
return ticketStore.values().stream()
.filter(ticket -> ticket.getStatus() == status)
.collect(Collectors.toList());
}
// 根据类型查询
public List<Ticket> findByType(TicketType type) {
return ticketStore.values().stream()
.filter(ticket -> ticket.getType() == type)
.collect(Collectors.toList());
}
// 根据票据编号查询
public Ticket findByTicketNo(String ticketNo) {
return ticketStore.values().stream()
.filter(ticket -> ticket.getTicketNo().equals(ticketNo))
.findFirst()
.orElse(null);
}
// 删除票据
public boolean delete(Long id) {
return ticketStore.remove(id) != null;
}
// 更新票据
public Ticket update(Ticket ticket) {
if (ticketStore.containsKey(ticket.getId())) {
ticket.setUpdateTime(java.time.LocalDateTime.now());
ticketStore.put(ticket.getId(), ticket);
return ticket;
}
return null;
}
// 条件查询
public List<Ticket> search(TicketQuery query) {
return ticketStore.values().stream()
.filter(ticket -> {
if (query.getType() != null && ticket.getType() != query.getType()) {
return false;
}
if (query.getStatus() != null && ticket.getStatus() != query.getStatus()) {
return false;
}
if (query.getIssuer() != null && !ticket.getIssuer().contains(query.getIssuer())) {
return false;
}
if (query.getStartDate() != null && ticket.getIssueDate().isBefore(query.getStartDate())) {
return false;
}
if (query.getEndDate() != null && ticket.getIssueDate().isAfter(query.getEndDate())) {
return false;
}
return true;
})
.collect(Collectors.toList());
}
// 统计数量
public long count() {
return ticketStore.size();
}
// 统计金额
public java.math.BigDecimal sumAmount() {
return ticketStore.values().stream()
.map(Ticket::getTotalAmount)
.reduce(java.math.BigDecimal.ZERO, java.math.BigDecimal::add);
}
}
/**
* 票据查询条件类
*/
class TicketQuery {
private TicketType type;
private TicketStatus status;
private String issuer;
private java.time.LocalDateTime startDate;
private java.time.LocalDateTime endDate;
// Getter和Setter方法
public TicketType getType() {
return type;
}
public void setType(TicketType type) {
this.type = type;
}
public TicketStatus getStatus() {
return status;
}
public void setStatus(TicketStatus status) {
this.status = status;
}
public String getIssuer() {
return issuer;
}
public void setIssuer(String issuer) {
this.issuer = issuer;
}
public java.time.LocalDateTime getStartDate() {
return startDate;
}
public void setStartDate(java.time.LocalDateTime startDate) {
this.startDate = startDate;
}
public java.time.LocalDateTime getEndDate() {
return endDate;
}
public void setEndDate(java.time.LocalDateTime endDate) {
this.endDate = endDate;
}
}
业务逻辑层(Service)
package com.example.ticket.service;
import com.example.ticket.dao.TicketDao;
import com.example.ticket.model.Ticket;
import com.example.ticket.model.TicketStatus;
import com.example.ticket.model.TicketType;
import com.example.ticket.util.TicketNumberGenerator;
import com.example.ticket.util.ValidationUtil;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
/**
* 票据业务逻辑层
*/
public class TicketService {
private final TicketDao ticketDao;
private final TicketNumberGenerator numberGenerator;
public TicketService() {
this.ticketDao = new TicketDao();
this.numberGenerator = new TicketNumberGenerator();
}
/**
* 创建票据
*/
public Ticket createTicket(Ticket ticket) {
// 验证票据数据
ValidationUtil.validateTicket(ticket);
// 生成票据编号
ticket.setTicketNo(numberGenerator.generateTicketNo(ticket.getType()));
// 设置默认状态
if (ticket.getStatus() == null) {
ticket.setStatus(TicketStatus.PENDING);
}
// 设置开票日期
if (ticket.getIssueDate() == null) {
ticket.setIssueDate(LocalDateTime.now());
}
// 设置有效期(默认一年)
if (ticket.getValidDate() == null) {
ticket.setValidDate(LocalDateTime.now().plusYears(1));
}
return ticketDao.save(ticket);
}
/**
* 更新票据
*/
public Ticket updateTicket(Ticket ticket) {
ValidationUtil.validateTicket(ticket);
Ticket existingTicket = ticketDao.findById(ticket.getId());
if (existingTicket == null) {
throw new RuntimeException("票据不存在");
}
// 检查状态
if (existingTicket.getStatus() == TicketStatus.CANCELLED) {
throw new RuntimeException("已作废的票据不能修改");
}
return ticketDao.update(ticket);
}
/**
* 获取所有票据
*/
public List<Ticket> getAllTickets() {
return ticketDao.findAll();
}
/**
* 根据ID获取票据
*/
public Ticket getTicketById(Long id) {
Ticket ticket = ticketDao.findById(id);
if (ticket == null) {
throw new RuntimeException("票据不存在");
}
return ticket;
}
/**
* 审核通过
*/
public boolean approveTicket(Long id) {
Ticket ticket = ticketDao.findById(id);
if (ticket == null) {
throw new RuntimeException("票据不存在");
}
if (ticket.getStatus() == TicketStatus.CANCELLED) {
throw new RuntimeException("已作废的票据不能审核");
}
// 检查是否过期
if (ticket.getValidDate().isBefore(LocalDateTime.now())) {
ticket.setStatus(TicketStatus.EXPIRED);
ticketDao.update(ticket);
throw new RuntimeException("票据已过期");
}
ticket.setStatus(TicketStatus.APPROVED);
ticketDao.update(ticket);
return true;
}
/**
* 拒绝票据
*/
public boolean rejectTicket(Long id, String reason) {
Ticket ticket = ticketDao.findById(id);
if (ticket == null) {
throw new RuntimeException("票据不存在");
}
ticket.setStatus(TicketStatus.REJECTED);
if (reason != null) {
ticket.setRemark(reason);
}
ticketDao.update(ticket);
return true;
}
/**
* 作废票据
*/
public boolean cancelTicket(Long id) {
Ticket ticket = ticketDao.findById(id);
if (ticket == null) {
throw new RuntimeException("票据不存在");
}
ticket.setStatus(TicketStatus.CANCELLED);
ticketDao.update(ticket);
return true;
}
/**
* 删除票据
*/
public boolean deleteTicket(Long id) {
return ticketDao.delete(id);
}
/**
* 检查票据过期
*/
public void checkExpiration() {
List<Ticket> tickets = ticketDao.findAll();
LocalDateTime now = LocalDateTime.now();
for (Ticket ticket : tickets) {
if (ticket.getStatus() == TicketStatus.PENDING &&
ticket.getValidDate().isBefore(now)) {
ticket.setStatus(TicketStatus.EXPIRED);
ticketDao.update(ticket);
}
}
}
/**
* 获取票据统计信息
*/
public TicketStatistics getStatistics() {
List<Ticket> tickets = ticketDao.findAll();
TicketStatistics stats = new TicketStatistics();
stats.setTotalCount(tickets.size());
stats.setTotalAmount(tickets.stream()
.map(Ticket::getTotalAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add));
// 统计各状态数量
for (TicketStatus status : TicketStatus.values()) {
long count = tickets.stream()
.filter(t -> t.getStatus() == status)
.count();
stats.getStatusCounts().put(status, count);
}
// 统计各类型数量
for (TicketType type : TicketType.values()) {
long count = tickets.stream()
.filter(t -> t.getType() == type)
.count();
stats.getTypeCounts().put(type, count);
}
return stats;
}
}
工具类
package com.example.ticket.util;
import com.example.ticket.model.Ticket;
import com.example.ticket.model.TicketType;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random;
/**
* 票据编号生成器
*/
public class TicketNumberGenerator {
private static final DateTimeFormatter DATE_FORMAT =
DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
private static final Random RANDOM = new Random();
/**
* 生成票据编号
*/
public String generateTicketNo(TicketType type) {
StringBuilder sb = new StringBuilder();
// 添加类型前缀
String typePrefix = getTypePrefix(type);
sb.append(typePrefix);
// 添加日期时间
sb.append(LocalDateTime.now().format(DATE_FORMAT));
// 添加随机数
sb.append(String.format("%04d", RANDOM.nextInt(10000)));
return sb.toString();
}
/**
* 获取类型前缀
*/
private String getTypePrefix(TicketType type) {
switch (type) {
case INVOICE: return "INV";
case RECEIPT: return "RCT";
case VOUCHER: return "VCH";
case TICKET: return "TKT";
case CHECK: return "CHK";
default: return "TIC";
}
}
}
package com.example.ticket.util;
import com.example.ticket.model.Ticket;
import java.math.BigDecimal;
import java.util.List;
/**
* 数据验证工具类
*/
public class ValidationUtil {
/**
* 验证票据数据
*/
public static void validateTicket(Ticket ticket) {
if (ticket == null) {
throw new IllegalArgumentException("票据不能为空");
}
// 验证必填字段
if (ticket.getType() == null) {
throw new IllegalArgumentException("票据类型不能为空");
}
if (ticket.getIssuer() == null || ticket.getIssuer().trim().isEmpty()) {
throw new IllegalArgumentException("开票方不能为空");
}
if (ticket.getPayer() == null || ticket.getPayer().trim().isEmpty()) {
throw new IllegalArgumentException("收票方不能为空");
}
if (ticket.getAmount() == null || ticket.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
throw new IllegalArgumentException("票据金额必须大于0");
}
if (ticket.getTaxRate() == null ||
ticket.getTaxRate().compareTo(BigDecimal.ZERO) < 0 ||
ticket.getTaxRate().compareTo(new BigDecimal("1")) > 0) {
throw new IllegalArgumentException("税率必须在0到1之间");
}
}
/**
* 验证票据列表
*/
public static void validateTickets(List<Ticket> tickets) {
if (tickets == null || tickets.isEmpty()) {
throw new IllegalArgumentException("票据列表不能为空");
}
for (Ticket ticket : tickets) {
validateTicket(ticket);
}
}
}
主程序测试类
package com.example.ticket;
import com.example.ticket.model.Ticket;
import com.example.ticket.model.TicketItem;
import com.example.ticket.model.TicketType;
import com.example.ticket.service.TicketService;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* 票据管理系统主程序
*/
public class Main {
public static void main(String[] args) {
TicketService ticketService = new TicketService();
System.out.println("========== 票据管理系统演示 ==========");
// 创建票据
try {
// 创建一张发票
Ticket invoice = new Ticket();
invoice.setType(TicketType.INVOICE);
invoice.setIssuer("科技公司");
invoice.setPayer("客户A");
invoice.setAmount(new BigDecimal("1000.00"));
invoice.setTaxRate(new BigDecimal("0.13"));
// 创建票据明细
List<TicketItem> items = new ArrayList<>();
items.add(new TicketItem("软件服务", 10, new BigDecimal("100"), new BigDecimal("0.13")));
invoice.setItems(items);
Ticket createdInvoice = ticketService.createTicket(invoice);
System.out.println("创建发票成功:" + createdInvoice.getTicketNo());
// 审核通过
ticketService.approveTicket(createdInvoice.getId());
System.out.println("票据审核通过");
// 创建一张收据
Ticket receipt = new Ticket();
receipt.setType(TicketType.RECEIPT);
receipt.setIssuer("咨询公司");
receipt.setPayer("客户B");
receipt.setAmount(new BigDecimal("500.00"));
receipt.setTaxRate(new BigDecimal("0.06"));
Ticket createdReceipt = ticketService.createTicket(receipt);
System.out.println("创建收据成功:" + createdReceipt.getTicketNo());
// 获取所有票据
System.out.println("\n所有票据列表:");
ticketService.getAllTickets().forEach(t -> {
System.out.println("- " + t.getTicketNo() + " | " +
t.getType().getDescription() + " | " +
t.getIssuer() + " | " +
t.getTotalAmount() + "元 | " +
t.getStatus().getDescription());
});
// 获取统计信息
var stats = ticketService.getStatistics();
System.out.println("\n统计分析:");
System.out.println("- 票据总数:" + stats.getTotalCount());
System.out.println("- 总金额:" + stats.getTotalAmount() + "元");
System.out.println("- 各状态统计:" + stats.getStatusCounts());
System.out.println("- 各类型统计:" + stats.getTypeCounts());
} catch (Exception e) {
System.err.println("错误:" + e.getMessage());
}
System.out.println("\n========== 演示结束 ==========");
}
}
统计类
package com.example.ticket.service;
import com.example.ticket.model.TicketStatus;
import com.example.ticket.model.TicketType;
import java.math.BigDecimal;
import java.util.EnumMap;
import java.util.Map;
/**
* 票据统计信息类
*/
public class TicketStatistics {
private long totalCount;
private BigDecimal totalAmount;
private Map<TicketStatus, Long> statusCounts = new EnumMap<>(TicketStatus.class);
private Map<TicketType, Long> typeCounts = new EnumMap<>(TicketType.class);
// Getters and Setters
public long getTotalCount() {
return totalCount;
}
public void setTotalCount(long totalCount) {
this.totalCount = totalCount;
}
public BigDecimal getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(BigDecimal totalAmount) {
this.totalAmount = totalAmount;
}
public Map<TicketStatus, Long> getStatusCounts() {
return statusCounts;
}
public void setStatusCounts(Map<TicketStatus, Long> statusCounts) {
this.statusCounts = statusCounts;
}
public Map<TicketType, Long> getTypeCounts() {
return typeCounts;
}
public void setTypeCounts(Map<TicketType, Long> typeCounts) {
this.typeCounts = typeCounts;
}
}
系统特点
- 完整性:覆盖票据的创建、审核、作废、查询、统计等完整生命周期
- 可扩展性:采用分层架构,便于扩展和维护
- 业务规则:包含税率计算、有效期检查、状态管理等业务规则
- 数据验证:提供完善的数据验证机制
- 统计功能:支持多维度统计分析
使用场景
- 企业财务管理系统
- 电商平台发票管理
- 票据扫描识别系统
- 报销管理系统
这个案例可以作为票据管理系统的核心框架,您可以根据实际需求在此基础上扩展数据库集成、Web界面、报表生成等功能。
版权声明: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直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播