mock-data.md 4.2 KB

Mock 数据规范

设计原则

  1. 每个列表页对应一个 mock 数据文件,放在 src/mock/ 目录下

  2. 使用工厂函数生成数据,默认生成 100 条

  3. 数据字段要贴合业务实际,不要使用 "test1"、"aaa" 等无意义数据

  4. ID 使用递增数字或带业务前缀的编号(如 SO20260401001

  5. 日期使用合理的时间范围(如近 3 个月内)

  6. 金额使用合理的数值范围

  7. 状态字段使用枚举值,并配备对应的中文映射

数据生成模板

// mock/orderList.js

// 状态枚举
export const ORDER_STATUS = {
  DRAFT: { value: 'draft', label: '草稿', color: 'default' },
  PENDING: { value: 'pending', label: '待审核', color: 'processing' },
  APPROVED: { value: 'approved', label: '已审核', color: 'success' },
  REJECTED: { value: 'rejected', label: '已驳回', color: 'error' },
  COMPLETED: { value: 'completed', label: '已完成', color: 'success' },
  CANCELLED: { value: 'cancelled', label: '已取消', color: 'default' },
};

// 模拟客户名称池
const CUSTOMERS = [
  '华润万家', '沃尔玛', '永辉超市', '大润发', '盒马鲜生',
  '天虹商场', '万达广场', '银泰百货', '苏宁易购', '国美电器',
  '中石化', '中石油', '比亚迪', '格力电器', '美的集团',
];

// 模拟商品名称池
const PRODUCTS = [
  '矿泉水550ml', '纯净水5L', '碳酸饮料330ml', '果汁1L',
  '方便面桶装', '饼干礼盒', '牛奶250ml*12', '酸奶100g*6',
];

// 随机工具函数
const random = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
const randomItem = (arr) => arr[Math.floor(Math.random() * arr.length)];
const randomDate = (startDays, endDays) => {
  const now = new Date();
  const start = new Date(now.getTime() - startDays * 86400000);
  const end = new Date(now.getTime() - endDays * 86400000);
  const d = new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
  return d.toISOString().slice(0, 10);
};

// 生成订单号
const genOrderNo = (index) => {
  const date = new Date();
  const prefix = 'SO';
  const dateStr = date.toISOString().slice(0, 10).replace(/-/g, '');
  return `${prefix}${dateStr}${String(index + 1).padStart(3, '0')}`;
};

// 生成数据
export const generateOrderList = (count = 100) => {
  const statusValues = Object.values(ORDER_STATUS);
  return Array.from({ length: count }, (_, i) => ({
    id: i + 1,
    orderNo: genOrderNo(i),
    customerName: randomItem(CUSTOMERS),
    productName: randomItem(PRODUCTS),
    quantity: random(10, 500),
    unitPrice: (random(500, 5000) / 100).toFixed(2),
    totalAmount: 0,  // 下面计算
    status: randomItem(statusValues).value,
    createTime: randomDate(90, 0),
    createBy: randomItem(['张三', '李四', '王五', '赵六']),
    remark: '',
  })).map(item => ({
    ...item,
    totalAmount: (item.quantity * parseFloat(item.unitPrice)).toFixed(2),
  }));
};

分页逻辑

列表页需要实现前端分页,在页面组件中处理:

const [currentPage, setCurrentPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const [allData] = useState(() => generateOrderList(100));

// 当前页数据
const currentData = useMemo(() => {
  const start = (currentPage - 1) * pageSize;
  return allData.slice(start, start + pageSize);
}, [allData, currentPage, pageSize]);

// 筛选逻辑
const filteredData = useMemo(() => {
  let data = allData;
  if (filters.status) {
    data = data.filter(item => item.status === filters.status);
  }
  if (filters.keyword) {
    data = data.filter(item =>
      item.orderNo.includes(filters.keyword) ||
      item.customerName.includes(filters.keyword)
    );
  }
  return data;
}, [allData, filters]);

命名约定

业务模块 文件名 导出函数
销售订单 orderList.js generateOrderList
客户管理 customerList.js generateCustomerList
采购单 purchaseList.js generatePurchaseList
供应商 supplierList.js generateSupplierList
库存 inventoryList.js generateInventoryList
入库单 inboundList.js generateInboundList
出库单 outboundList.js generateOutboundList