crgs/src/mocks/MOCK_DATA_CONSISTENCY.md

7.0 KiB
Raw Blame History

Mock 数据一致性说明

概述

本文档说明 Mock 数据与后端 API 响应结构的一致性处理方式,确保 Mock 数据能够准确模拟真实后端行为。

数据结构一致性

1. 标准响应格式

所有 Mock 接口统一使用以下响应格式:

{
  code: 0,        // 响应码0成功-1失败
  msg: 'success',  // 响应消息
  data: {...}       // 响应数据
}

2. 分页响应格式

分页接口使用以下格式:

{
  code: 0,
  msg: 'success',
  data: {
    records: [...],  // 当前页数据列表
    total: 100,       // 总记录数
    size: 10,         // 每页大小
    current: 1,        // 当前页码
    pages: 10         // 总页数
  }
}

数据一致性处理工具

分页处理

paginatedResponse() 函数提供完整的分页处理能力:

import { paginatedResponse } from '@/mocks/utils/handler-utils'

// 支持的参数
{
  current: 1,           // 当前页码(必需)
  size: 10,             // 每页大小(必需)
  orderField: 'createTime', // 排序字段
  orderingRule: 'desc',  // 排序规则asc/desc
  orderFields: ['field1', 'field2'], // 多字段排序
  orderSorts: ['asc', 'desc'],      // 多字段排序规则
  custom: {            // 自定义筛选条件
    status: 1
  },
  likeParamMap: {      // 模糊查询条件
    name: '关键词'
  },
  inParamMap: {        // IN 查询条件
    status: [1, 2, 3]
  }
}

排序处理

sortData() 函数支持:

  • 单字段排序{ field: 'name', order: 'asc' }
  • 多字段排序{ fields: ['name', 'age'], orders: ['asc', 'desc'] }
  • 嵌套字段排序field: 'user.address.city'
  • 类型处理:自动识别数字、日期、字符串类型进行排序

筛选处理

filterData() 函数支持:

  • 精确匹配{ status: 1 }
  • 模糊查询{ likeParamMap: { name: '关键词' } }
  • IN 查询{ inParamMap: { status: [1, 2] } }
  • 自定义筛选{ customParamMap: { customFn: (item) => item.value > 100 } }

数据类型映射

企业数据结构

{
  companyId: 'com_xxx',      // 企业ID
  pripid: 'prip_xxx',         // 原系统ID
  uniscid: '91440100...',    // 统一社会信用代码
  entname: '企业名称',          // 市场主体名称
  regstate: '1',               // 企业状态码
  regstateCn: '存续',         // 企业状态(中文)
  industryphy: 'C',           // 行业门类码
  industryphyCn: '制造业',      // 行业门类(中文)
  riskLevel: '1',             // 风险等级码
  riskLevelCn: '低风险',       // 风险等级(中文)
  riskScore: 75,               // 风险评分
  estdate: '2020-01-01',     // 成立时间
  createTime: '...',           // 创建时间
  updateTime: '...'            // 更新时间
}

用户数据结构

{
  userId: 'user_xxx',         // 用户ID
  username: 'admin',           // 用户名
  realName: '张三',           // 真实姓名
  account: 'admin',            // 账号
  department: 'xxx',          // 部门
  roleId: 'role_xxx',         // 角色ID
  roleName: '管理员',          // 角色名称
  status: 1,                  // 状态
  createTime: '...',           // 创建时间
  lastLoginTime: '...'        // 最后登录时间
}

加载延迟模拟

所有 Mock 接口都使用随机延迟200-800ms来模拟真实网络请求

import { mockDelay, handlePaginatedRequest } from '@/mocks/utils/handler-utils'

// 方式1使用 mockDelay
await mockDelay()

// 方式2使用 handlePaginatedRequest自动延迟
const response = await handlePaginatedRequest(data, request)

错误场景模拟

1. 业务错误响应

import { errorResponse } from '@/mocks/utils/handler-utils'

return res(
  ctx.status(200),
  ctx.json(errorResponse('参数错误', -1))
)

2. HTTP 状态码

return res(
  ctx.status(401),  // 未授权
  ctx.json({ code: 401, msg: '未登录或登录已过期' })
)

3. 模拟特定错误

// 登录失败
if (username !== 'admin' || password !== '123456') {
  return res(
    ctx.status(200),
    ctx.json(errorResponse('用户名或密码错误'))
  )
}

Mock 数据验证检查清单

在开发 Mock 数据时,确保以下项目:

  • 响应格式:使用 successResponse()errorResponse() 统一格式
  • 分页结构:使用 paginatedResponse() 包含 records/total/size/current/pages
  • 字段命名:字段名与后端 API 文档保持一致(驼峰命名)
  • 数据类型:数字字段使用 Number,日期使用 ISO 字符串格式
  • 枚举值:状态码、类型码等与后端定义一致
  • 关联关系:外键 ID 格式正确,如 companyIduserId
  • 分页支持:支持排序、筛选、模糊查询等后端功能
  • 延迟模拟:使用 mockDelay()handlePaginatedRequest() 模拟网络延迟
  • 错误处理:提供合理的错误响应场景

Mock 数据维护建议

  1. 数据量控制:每个模块生成 20-100 条 Mock 数据
  2. 数据真实性:使用 @faker-js/faker 生成接近真实的测试数据
  3. 字段完整性:确保 Mock 数据包含后端返回的所有字段
  4. 边界测试:提供空数据、单页数据、多页数据等边界情况
  5. 定期更新:后端 API 变更时同步更新 Mock 数据结构

使用示例

完整的分页请求处理

export const examplePaginatedHandler = rest.post(
  getBasePath('/example/list'),
  async (req, res, ctx) => {
    const body = await getRequestBody(req)
    const response = await handlePaginatedRequest(mockData, body)

    return res(
      ctx.status(200),
      ctx.json(successResponse(response))
    )
  }
)

带筛选的处理

export const exampleFilterHandler = rest.post(
  getBasePath('/example/list'),
  async (req, res, ctx) => {
    const body = await getRequestBody(req)

    // 自定义筛选逻辑
    const result = filterData(mockData, body, {
      likeParamMap: { name: body.keyword },
      inParamMap: { status: [1, 2] }
    })

    return res(
      ctx.status(200),
      ctx.json(successResponse(result))
    )
  }
)

工具函数速查表

函数 说明 参数
successResponse(data, msg) 成功响应 data, msg
errorResponse(msg, code) 错误响应 msg, code
paginate(data, size, current) 简单分页 data, size, current
paginatedResponse(data, request) 完整分页(排序+筛选) data, request
sortData(data, options) 排序 data, { field, order, fields, orders }
filterData(data, filters, options) 筛选 data, filters, { customParamMap, likeParamMap, inParamMap }
handlePaginatedRequest(data, request) 处理分页请求(带延迟) data, request
mockDelay() 模拟延迟
getNestedValue(obj, path) 获取嵌套属性 obj, 'path.to.field'