index.vue 5.39 KB
<template>
  <div class="min-h-screen bg-[#f9fafb] pb-[calc(160rpx+env(safe-area-inset-bottom))]">
    <!-- Navigation Header -->
    <NavHeader :title="pageTitle" />

    <!-- Loading State -->
    <div v-if="loading" class="px-[40rpx] mt-[80rpx] flex items-center justify-center">
      <text class="text-[#9CA3AF] text-[28rpx]">加载中...</text>
    </div>

    <!-- Content List -->
    <div v-else-if="sections.length > 0" class="px-[40rpx] mt-[40rpx] relative z-10">
      <SectionCard
        v-for="(section, index) in sections"
        :key="index"
        :title="section.title"
        :items="section.items"
        @item-click="handleItemClick"
      />
    </div>

    <!-- Empty State -->
    <div v-else class="px-[40rpx] mt-[80rpx] flex items-center justify-center">
      <!-- <text class="text-[#9CA3AF] text-[28rpx]">暂无分类</text> -->
      <nut-empty description="暂无分类" image="empty" />
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'
import { useLoad } from '@tarojs/taro'
import NavHeader from '@/components/NavHeader.vue'
import SectionCard from '@/components/SectionCard.vue'
import { fileListAPI } from '@/api/file'
import { useGo } from '@/hooks/useGo'
import Taro from '@tarojs/taro'

const go = useGo()

/**
 * 页面状态
 */
const loading = ref(false)
const data = ref({})

/**
 * 页面标题
 */
const pageTitle = ref('分类列表')

/**
 * 最大层级
 */
const maxLevel = computed(() => data.value?.max_level || 0)

/**
 * 将 API 返回的 children 数据转换为 SectionCard 需要的格式
 * @description 将嵌套的 children 数组转换为 sections 格式
 *
 * 数据结构:
 * - 第一层(大标题):level=1,如"入职前"、"入职中"、"入职后"
 * - 第二层(小标题):level=2,如"考试报名"、"资格考试报名入口"
 *
 * @returns {Array<{title: string, items: Array}>}
 */
const sections = computed(() => {
  const children = data.value?.children || []

  if (children.length === 0) {
    return []
  }

  // 为每个第一层分类创建一个 section
  return children.map(level1Category => ({
    title: level1Category.category_name, // 大标题:"入职前"
    items: (level1Category.children || []).map(level2Category => ({
      id: level2Category.id,
      title: level2Category.category_name, // 小标题:"考试报名"
      subtitle: level2Category.list?.length ? `${level2Category.list.length} 个文件` : '',
      icon: level2Category.icon || '',
      level: level2Category.level,
      maxDepth: level2Category.max_depth,
      // 保留原始数据供点击事件使用
      _raw: level2Category
    }))
  }))
})

/**
 * 获取文档分类列表
 * @param {Object} options - 页面参数
 * @param {string} options.cid - 分类ID(首次进入)
 * @param {string} options.id - 子分类ID(后续层级)
 * @param {string} options.title - 页面标题
 */
const fetchCategoryList = async (options) => {
  try {
    loading.value = true

    // 构建请求参数
    const params = {}
    if (options.cid) {
      params.cid = options.cid // 首次进入使用 cid
    } else if (options.id) {
      params.cid = options.id // 后续层级使用 id
    }

    console.log('[Category List] 请求参数:', params)

    // 调用接口(直接调用,不使用 fn() 包装)
    const res = await fileListAPI(params)

    if (res.code === 1 && res.data) {
      data.value = res.data
      // console.log('[Category List] 分类数据:', res.data)
      // console.log('[Category List] 最大层级:', maxLevel.value)
      // console.log('[Category List] 转换后的 sections:', JSON.stringify(sections.value, null, 2))
    } else {
      Taro.showToast({
        title: res.msg || '获取分类列表失败',
        icon: 'none',
        duration: 2000
      })
    }
  } catch (error) {
    console.error('[Category List] 获取分类列表失败:', error)
    throw error
  } finally {
    loading.value = false
  }
}

/**
 * 处理分类点击事件
 * @description 根据该分类的层级和是否有子分类决定跳转
 *
 * 数据结构说明:
 * - level=1: 第一层(大标题),如"入职前"、"入职中"、"入职后"
 * - level=2: 第二层(小标题),如"考试报名"、"资格考试报名入口"
 * - max_level: 总的最大层级数
 * - max_depth: 当前分支的最大深度
 *
 * 跳转规则:
 * - 如果当前是第二层(level=2),直接跳转到 material-list(最终层)
 * - category-list 只显示两层结构
 *
 * @param {Object} item - 被点击的项目数据(第二层分类)
 */
const handleItemClickWithNav = (item, go) => {
  console.log('[Category List] 点击分类:', item)
  console.log('[Category List] 分类层级:', item.level)
  console.log('[Category List] 最大深度:', item.maxDepth)

  // 当前点击的是第二层(level=2),直接跳转到文档列表
  console.log('[Category List] 跳转到文档列表')
  go('/pages/material-list/index', {
    id: item.id,
    title: item.title
  })
}

// 导出 handleItemClick 供 SectionCard 使用
const handleItemClick = (item) => handleItemClickWithNav(item, go)

/**
 * 页面加载时接收参数并初始化
 */
useLoad((options) => {
  console.log('[Category List] 页面参数:', options)

  // 设置页面标题
  if (options.title) {
    pageTitle.value = options.title
  }

  // 获取分类列表
  fetchCategoryList(options)
})
</script>

<script>
export default {
  name: 'CategoryListIndex'
}
</script>