mockData.js 8.31 KB
/**
 * @Description: Mock 数据生成工具 - 用于测试地图活动功能
 * @Date: 2026-02-09
 *
 * 支持的 API Mock:
 * - listAPI: 地图活动列表
 * - detailAPI: 地图活动详情
 * - isCheckedAPI: 是否已打卡
 * - posterAPI: 获取海报
 */

// ============================================================================
// 工具函数
// ============================================================================

/**
 * 随机图片 URL 生成器
 * @param {number} width - 图片宽度
 * @param {number} height - 图片高度
 * @param {number} seed - 随机种子
 * @returns {string} 图片 URL
 */
function randomImage(width = 400, height = 300, seed = 1) {
  return `https://picsum.photos/${width}/${height}?random=${seed}`
}

/**
 * 模拟网络延迟
 * @param {number} min - 最小延迟(ms)
 * @param {number} max - 最大延迟(ms)
 * @returns {Promise}
 */
function mockDelay(min = 100, max = 300) {
  const delay = Math.random() * (max - min) + min
  return new Promise(resolve => setTimeout(resolve, delay))
}

// ============================================================================
// 1. 地图活动列表 Mock (listAPI)
// ============================================================================

const ACTIVITY_NAMES = [
  '重阳登高打卡',
  '公园晨跑打卡',
  '社区健身打卡',
  '周末徒步打卡',
  '秋日赏菊打卡',
  '古镇文化打卡',
  '健康骑行活动',
  '亲子运动会',
  '户外拓展训练',
  '城市定向挑战',
]

/**
 * 生成地图活动列表项
 * @param {number} id - 活动 ID
 * @returns {Object} 活动对象
 */
function generateMapActivityItem(id) {
  const activityName = ACTIVITY_NAMES[Math.floor(Math.random() * ACTIVITY_NAMES.length)]
  const now = new Date()
  const startDate = new Date(now.getTime() + Math.random() * 30 * 24 * 60 * 60 * 1000)
  const endDate = new Date(startDate.getTime() + (30 + Math.random() * 60) * 24 * 60 * 60 * 1000)

  // 格式化日期为 YYYY.MM.DD
  const formatDate = date => {
    const year = date.getFullYear()
    const month = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    return `${year}.${month}.${day}`
  }

  return {
    id: String(id),
    title: activityName,
    cover: randomImage(400, 300, id),
    begin_date: formatDate(startDate),
    end_date: formatDate(endDate),
    url: '',
  }
}

/**
 * Mock: listAPI (地图活动列表)
 * @param {Object} params - 请求参数
 * @returns {Promise<{code: number, msg: string, data: Array}>}
 */
export async function mockMapActivityListAPI() {
  await mockDelay()

  const list = []
  const total = 6

  for (let i = 0; i < total; i++) {
    list.push(generateMapActivityItem(i + 1))
  }

  console.log(`[Mock] listAPI - 地图活动列表,共${list.length}条`)

  return {
    code: 1,
    msg: 'success',
    data: list,
  }
}

// ============================================================================
// 2. 地图活动详情 Mock (detailAPI)
// ============================================================================

/**
 * Mock: detailAPI (地图活动详情)
 * @param {Object} params - 请求参数
 * @param {string} params.id - 活动 ID
 * @returns {Promise<{code: number, msg: string, data: Object}>}
 */
export async function mockMapActivityDetailAPI(params) {
  await mockDelay()

  const { id } = params
  const item = generateMapActivityItem(parseInt(id) || 1)

  console.log(`[Mock] detailAPI - 活动详情,ID:${id}`)

  return {
    code: 1,
    msg: 'success',
    data: {
      ...item,
      url: 'https://example.com/map',
      is_ended: false,
      is_begin: true,
      first_checkin_points: 10,
      required_checkin_count: 5,
      complete_points: 50,
      discount_title: '打卡点优惠信息',
    },
  }
}

// ============================================================================
// 3. 是否已打卡 Mock (isCheckedAPI)
// ============================================================================

/**
 * Mock: isCheckedAPI (是否已打卡)
 * @param {Object} params - 请求参数
 * @param {string} params.detail_id - 打卡点 ID
 * @returns {Promise<{code: number, msg: string, data: Object}>}
 */
export async function mockIsCheckedAPI(params) {
  await mockDelay()

  const { detail_id } = params
  const isChecked = parseInt(detail_id) % 3 === 0

  console.log(`[Mock] isCheckedAPI - 打卡点${detail_id},${isChecked ? '已打卡' : '未打卡'}`)

  return {
    code: 1,
    msg: 'success',
    data: {
      is_checked: isChecked,
    },
  }
}

// ============================================================================
// 4. 获取海报 Mock (posterAPI)
// ============================================================================

/**
 * Mock: posterAPI (获取海报)
 * @param {Object} params - 请求参数
 * @param {string} params.activity_id - 活动 ID
 * @returns {Promise<{code: number, msg: string, data: Object}>}
 */
export async function mockPosterAPI(params) {
  await mockDelay()

  const { activity_id } = params

  console.log(`[Mock] posterAPI - 获取海报,活动ID:${activity_id}`)

  return {
    code: 1,
    msg: 'success',
    data: {
      details: [
        {
          id: 1,
          name: '起点打卡',
          background_url: randomImage(750, 1200, 20),
          main_slogan: '开启健康之旅',
          sub_slogan: '坚持就是胜利',
          is_checked: true,
        },
        {
          id: 2,
          name: '山顶打卡',
          background_url: randomImage(750, 1200, 21),
          main_slogan: '登高望远',
          sub_slogan: '风景这边独好',
          is_checked: false,
        },
      ],
      family: {
        id: 123,
        name: '快乐家庭',
        avatar_url: randomImage(200, 200, 30),
      },
      show_detail_index: 0,
      end_date: '2025.10.31',
      qrcode_url: 'https://example.com/qrcode.jpg',
      title: '重阳登高打卡',
      begin_date: '2025.09.06',
    },
  }
}

// ============================================================================
// 导出统一 Mock API 调用器
// ============================================================================

/**
 * Mock API 调用器
 * @param {string} apiName - API 名称
 * @param {Object} params - 请求参数
 * @returns {Promise}
 */
export async function mockAPI(apiName, params) {
  switch (apiName) {
    case 'listAPI':
      return await mockMapActivityListAPI(params)
    case 'detailAPI':
      return await mockMapActivityDetailAPI(params)
    case 'isCheckedAPI':
      return await mockIsCheckedAPI(params)
    case 'posterAPI':
      return await mockPosterAPI(params)
    default:
      console.warn(`[Mock] 未知的 API: ${apiName}`)
      return { code: 0, msg: 'Unknown API', data: null }
  }
}

/**
 * Mock 地图活动详情数据
 * @param {string} activityId - 活动 ID
 * @returns {Object} 地图活动详情
 */
export const mockMapActivityDetail = () => {
  return {
    url: 'https://example.com/map',
    id: '1',
    cover: randomImage(750, 500, 10),
    title: '重阳登高打卡',
    begin_date: '2025.09.06',
    end_date: '2025.10.31',
    is_ended: false,
    is_begin: true,
    first_checkin_points: 10,
    required_checkin_count: 5,
    complete_points: 50,
    discount_title: '打卡点优惠信息',
  }
}

/**
 * Mock 是否已打卡数据
 * @param {string} detailId - 打卡点 ID
 * @returns {boolean} 是否已打卡
 */
export const mockIsChecked = detailId => {
  // 偶尔返回已打卡
  return parseInt(detailId) % 3 === 0
}

/**
 * Mock 海报数据
 * @param {string} activityId - 活动 ID
 * @returns {Object} 海报数据
 */
export const mockPoster = activityId => {
  return {
    details: [
      {
        id: 1,
        name: '起点打卡',
        background_url: randomImage(750, 1200, 20),
        main_slogan: '开启健康之旅',
        sub_slogan: '坚持就是胜利',
        is_checked: true,
      },
      {
        id: 2,
        name: '山顶打卡',
        background_url: randomImage(750, 1200, 21),
        main_slogan: '登高望远',
        sub_slogan: '风景这边独好',
        is_checked: false,
      },
    ],
    family: {
      id: 123,
      name: '快乐家庭',
      avatar_url: randomImage(200, 200, 30),
    },
    show_detail_index: 0,
    end_date: '2025.10.31',
    qrcode_url: 'https://example.com/qrcode.jpg',
    title: '重阳登高打卡',
    begin_date: '2025.09.06',
  }
}