hookehuyr

feat(pages): 实现分类资料列表跳转功能

- 为 onboarding、family-office、signing 三个页面的 item 添加 categoryId
- 点击 item 时跳转到 material-list 页面并传递分类 ID 参数
- material-list 页面使用 useLoad 接收 categoryId 并预留 API 调用接口
- 保持向后兼容,无 categoryId 时显示所有资料

技术实现:
- 使用 useSectionList composable 的自定义点击处理函数
- 统一的 ID 命名规范:{page}-{module}-{feature}
- 完善的日志输出和错误处理

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
......@@ -29,11 +29,13 @@ const FAMILY_OFFICE_SECTIONS = [
title: '家庭成员',
items: [
{
id: 'family-member-list',
title: '成员列表',
subtitle: '管理家庭成员信息',
icon: 'my'
},
{
id: 'family-member-add',
title: '新增成员',
subtitle: '添加家庭成员',
icon: 'edit'
......@@ -44,11 +46,13 @@ const FAMILY_OFFICE_SECTIONS = [
title: '健康档案',
items: [
{
id: 'family-health-checkup',
title: '体检报告',
subtitle: '查看家庭成员体检记录',
icon: 'order'
},
{
id: 'family-health-medical',
title: '就医记录',
subtitle: '家庭成员就医历史',
icon: 'clock'
......@@ -59,11 +63,13 @@ const FAMILY_OFFICE_SECTIONS = [
title: '资产管理',
items: [
{
id: 'family-asset-policy',
title: '保单管理',
subtitle: '家庭保单汇总',
icon: 'star'
},
{
id: 'family-asset-overview',
title: '资产总览',
subtitle: '家庭资产分布',
icon: 'find'
......@@ -74,11 +80,13 @@ const FAMILY_OFFICE_SECTIONS = [
title: '生活服务',
items: [
{
id: 'family-service-medical',
title: '高端医疗',
subtitle: '预约高端医疗服务',
icon: 'service'
},
{
id: 'family-service-health',
title: '康养服务',
subtitle: '健康养生服务',
icon: 'playCircleFill'
......@@ -87,8 +95,19 @@ const FAMILY_OFFICE_SECTIONS = [
}
]
// 使用 useSectionList composable 管理列表数据
const { sections, handleItemClick } = useSectionList(FAMILY_OFFICE_SECTIONS)
/**
* 处理项目点击事件
*
* @description 点击列表项时跳转到资料列表页,并带上分类 ID
* @param {Object} item - 被点击的项目数据
* @param {Function} go - 导航函数
*/
const handleItemClickWithNav = (item, go) => {
go('/pages/material-list/index', { categoryId: item.id })
}
// 使用 useSectionList composable 管理列表数据,传入自定义点击处理
const { sections, handleItemClick } = useSectionList(FAMILY_OFFICE_SECTIONS, handleItemClickWithNav)
</script>
<script>
......
......@@ -17,6 +17,19 @@
</div>
</div>
<!-- Category Tabs -->
<!-- 根据是否有分类数据决定是否显示 tab -->
<div v-if="categories && categories.length > 0" class="px-[32rpx] mt-[32rpx]">
<div class="flex overflow-x-auto no-scrollbar mb-[40rpx] space-x-[24rpx]">
<div v-for="(category, index) in categories" :key="index"
class="px-[32rpx] py-[16rpx] rounded-full text-[28rpx] whitespace-nowrap transition-colors"
:class="activeCategoryIndex === index ? 'bg-[#2563EB] text-white' : 'bg-[#F3F4F6] text-[#6B7280]'"
@tap="activeCategoryIndex = index">
{{ category.name }}
</div>
</div>
</div>
<!-- Material List -->
<div class="px-[32rpx] mt-[32rpx]">
<div class="flex flex-col gap-[24rpx]">
......@@ -78,6 +91,7 @@
<script setup>
import { ref } from 'vue'
import { useLoad } from '@tarojs/taro'
import NavHeader from '@/components/NavHeader.vue'
import TabBar from '@/components/TabBar.vue'
import IconFont from '@/components/IconFont.vue'
......@@ -87,6 +101,7 @@ import { getDocumentIcon, getDocumentLabel } from '@/utils/documentIcons'
import Taro from '@tarojs/taro'
const searchValue = ref('')
const categoryId = ref('')
/**
* 资料列表数据
......@@ -197,12 +212,67 @@ const list = ref([
])
/**
* 页面加载时接收参数
*
* @description 使用 Taro 的 useLoad hook 接收路由参数
*/
useLoad((options) => {
console.log('[Material List] 页面参数:', options)
// 接收 categoryId 参数
if (options.categoryId) {
categoryId.value = options.categoryId
console.log('[Material List] 分类 ID:', categoryId.value)
// 根据 categoryId 加载对应的资料列表
loadMaterialsByCategory(categoryId.value)
} else {
console.log('[Material List] 无分类 ID,显示所有资料')
}
})
/**
* 根据分类 ID 加载资料列表
*
* @description 根据 categoryId 从 API 获取对应的资料列表
* @param {string} categoryId - 分类 ID
*/
const loadMaterialsByCategory = async (id) => {
try {
Taro.showLoading({ title: '加载中...', mask: true })
// TODO: 调用真实的 API 接口
// const res = await getMaterialsByCategoryAPI({ categoryId: id })
// if (res.code === 1) {
// list.value = res.data
// }
// 模拟 API 调用延迟
await new Promise(resolve => setTimeout(resolve, 500))
console.log(`[Material List] 已加载分类 "${id}" 的资料列表`)
Taro.hideLoading()
} catch (error) {
console.error('[Material List] 加载资料列表失败:', error)
Taro.showToast({
title: '加载失败,请重试',
icon: 'none'
})
} finally {
Taro.hideLoading()
}
}
/**
* 搜索处理函数
*
* @description 处理用户搜索操作
*/
const onSearch = () => {
console.log('Searching for:', searchValue.value)
console.log('当前分类:', categoryId.value)
// TODO: 根据 categoryId 和 searchValue 进行搜索
}
/**
......
......@@ -29,16 +29,19 @@ const ONBOARDING_SECTIONS = [
title: '入职前',
items: [
{
id: 'onboarding-exam',
icon: '',
title: '考试报名',
subtitle: '报名参加代理人资格考试'
},
{
id: 'onboarding-interview',
icon: '',
title: '面试结果查询',
subtitle: '查看面试状态和结果'
},
{
id: 'onboarding-materials',
icon: '',
title: '入职材料提交',
subtitle: '上传入职所需证件和资料'
......@@ -49,16 +52,19 @@ const ONBOARDING_SECTIONS = [
title: '入职中',
items: [
{
id: 'onboarding-timeline',
icon: '',
title: '各个进度时间线表格',
subtitle: '查看入职流程关键节点'
},
{
id: 'onboarding-tasks',
icon: '',
title: '待办事项清单',
subtitle: '你需要完成的任务列表'
},
{
id: 'onboarding-contract',
icon: '',
title: '签署合同',
subtitle: '电子合同在线签署'
......@@ -69,16 +75,19 @@ const ONBOARDING_SECTIONS = [
title: '入职后',
items: [
{
id: 'onboarding-training',
icon: '',
title: '新人培训',
subtitle: '参加新人岗前培训课程'
},
{
id: 'onboarding-target',
icon: '',
title: '业绩目标设定',
subtitle: '制定首月业绩目标'
},
{
id: 'onboarding-team',
icon: '',
title: '团队介绍',
subtitle: '了解你的团队和主管'
......@@ -87,8 +96,19 @@ const ONBOARDING_SECTIONS = [
}
]
// 使用 useSectionList composable 管理列表数据
const { sections, handleItemClick } = useSectionList(ONBOARDING_SECTIONS)
/**
* 处理项目点击事件
*
* @description 点击列表项时跳转到资料列表页,并带上分类 ID
* @param {Object} item - 被点击的项目数据
* @param {Function} go - 导航函数
*/
const handleItemClickWithNav = (item, go) => {
go('/pages/material-list/index', { categoryId: item.id })
}
// 使用 useSectionList composable 管理列表数据,传入自定义点击处理
const { sections, handleItemClick } = useSectionList(ONBOARDING_SECTIONS, handleItemClickWithNav)
</script>
<script>
......
......@@ -29,11 +29,13 @@ const SIGNING_SECTIONS = [
title: '培训板块',
items: [
{
id: 'signing-training-company',
icon: 'shop',
title: '公司介绍',
subtitle: '企业背景及发展历程'
},
{
id: 'signing-training-product',
icon: 'category',
title: '产品介绍及更新',
subtitle: '最新产品资料库'
......@@ -44,11 +46,13 @@ const SIGNING_SECTIONS = [
title: '签单前',
items: [
{
id: 'signing-pre-underwriting',
icon: 'check',
title: '预核保',
subtitle: '核保流程指引'
},
{
id: 'signing-pre-plan',
icon: 'edit',
title: '做计划书',
subtitle: '方案设计工具'
......@@ -59,16 +63,19 @@ const SIGNING_SECTIONS = [
title: '签单中',
items: [
{
id: 'signing-process-info',
icon: 'checklist',
title: '信息收集及健康告知模板',
subtitle: '标准表格及注意事项'
},
{
id: 'signing-process-payment',
icon: 'cart',
title: '缴费方式银行开户',
subtitle: '支付渠道办理指南'
},
{
id: 'signing-process-checkup',
icon: 'people',
title: '体检经验',
subtitle: '体检流程及常见问题'
......@@ -79,16 +86,19 @@ const SIGNING_SECTIONS = [
title: '签单后',
items: [
{
id: 'signing-post-endorsement',
icon: 'order',
title: '批单跟进',
subtitle: '保单变更处理流程'
},
{
id: 'signing-post-pending',
icon: 'clock',
title: '核保/pending',
subtitle: '核保进度查询'
},
{
id: 'signing-post-renewal',
icon: 'refresh',
title: '续保',
subtitle: '续期服务指引'
......@@ -99,6 +109,7 @@ const SIGNING_SECTIONS = [
title: '售后',
items: [
{
id: 'signing-aftercare-doctor',
icon: 'location',
title: '香港医生资源',
subtitle: '专业医疗机构名录'
......@@ -107,8 +118,19 @@ const SIGNING_SECTIONS = [
}
]
// 使用 useSectionList composable 管理列表数据
const { sections, handleItemClick } = useSectionList(SIGNING_SECTIONS)
/**
* 处理项目点击事件
*
* @description 点击列表项时跳转到资料列表页,并带上分类 ID
* @param {Object} item - 被点击的项目数据
* @param {Function} go - 导航函数
*/
const handleItemClickWithNav = (item, go) => {
go('/pages/material-list/index', { categoryId: item.id })
}
// 使用 useSectionList composable 管理列表数据,传入自定义点击处理
const { sections, handleItemClick } = useSectionList(SIGNING_SECTIONS, handleItemClickWithNav)
</script>
<script>
......