hookehuyr

feat(knowledge-base): 添加产品列表点击跳转逻辑

- 为每个产品添加唯一 id 字段
- 使用 useListItemClick Composable 处理点击事件
- 配置 ListType.PRODUCT 自动跳转产品详情页
- 添加点击缩放反馈效果
- 完善代码注释(JSDoc)

点击产品卡片后跳转到 /pages/product-detail/index?id={productId}

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
...@@ -25,7 +25,8 @@ ...@@ -25,7 +25,8 @@
25 <div class="flex flex-wrap justify-between"> 25 <div class="flex flex-wrap justify-between">
26 <!-- Card Item --> 26 <!-- Card Item -->
27 <div v-for="(item, index) in filteredProducts" :key="index" 27 <div v-for="(item, index) in filteredProducts" :key="index"
28 - class="w-[48%] bg-white rounded-[24rpx] overflow-hidden mb-[24rpx] shadow-sm flex flex-col"> 28 + class="w-[48%] bg-white rounded-[24rpx] overflow-hidden mb-[24rpx] shadow-sm flex flex-col active:scale-[0.98] transition-transform duration-200"
29 + @tap="handleProductClick(item)">
29 <!-- Image Container --> 30 <!-- Image Container -->
30 <div class="relative w-full h-[200rpx]"> 31 <div class="relative w-full h-[200rpx]">
31 <img :src="item.image" class="w-full h-full object-cover bg-gray-100" referrerpolicy="no-referrer" /> 32 <img :src="item.image" class="w-full h-full object-cover bg-gray-100" referrerpolicy="no-referrer" />
...@@ -61,34 +62,54 @@ ...@@ -61,34 +62,54 @@
61 import { ref, computed } from 'vue' 62 import { ref, computed } from 'vue'
62 import NavHeader from '@/components/NavHeader.vue' 63 import NavHeader from '@/components/NavHeader.vue'
63 import TabBar from '@/components/TabBar.vue' 64 import TabBar from '@/components/TabBar.vue'
65 +import { useListItemClick, ListType } from '@/composables/useListItemClick'
64 66
65 const activeTab = ref(0) 67 const activeTab = ref(0)
66 const tabs = ['全部产品', '人寿保险', '医疗保险', '意外保险'] 68 const tabs = ['全部产品', '人寿保险', '医疗保险', '意外保险']
67 69
68 /** 70 /**
69 - * Mock Data Generation 71 + * 生成产品数据
70 - * @returns {Array} List of products 72 + *
73 + * @description 生成模拟产品列表数据,每个产品包含唯一 id
74 + * @returns {Array} 产品列表
71 */ 75 */
72 const generateProducts = () => { 76 const generateProducts = () => {
73 return [ 77 return [
74 - { title: '终身寿险尊享版', tag: '热卖', desc: '5年超值', image: `https://picsum.photos/seed/1/200/200` }, 78 + { id: 1, title: '终身寿险尊享版', tag: '热卖', desc: '5年超值', image: `https://picsum.photos/seed/1/200/200` },
75 - { title: '百万医疗保险计划', desc: '收益率3.5%', image: `https://picsum.photos/seed/2/200/200` }, 79 + { id: 2, title: '百万医疗保险计划', desc: '收益率3.5%', image: `https://picsum.photos/seed/2/200/200` },
76 - { title: '意外伤害保障计划', desc: '保证收益万能', image: `https://picsum.photos/seed/3/200/200` }, 80 + { id: 3, title: '意外伤害保障计划', desc: '保证收益万能', image: `https://picsum.photos/seed/3/200/200` },
77 - { title: '分红型年金保险', tag: '热卖', desc: '保证收益万能', image: `https://picsum.photos/seed/4/200/200` }, 81 + { id: 4, title: '分红型年金保险', tag: '热卖', desc: '保证收益万能', image: `https://picsum.photos/seed/4/200/200` },
78 - { title: '重大疾病保险', desc: '收益率4.2%', image: `https://picsum.photos/seed/5/200/200` }, 82 + { id: 5, title: '重大疾病保险', desc: '收益率4.2%', image: `https://picsum.photos/seed/5/200/200` },
79 - { title: '少儿教育金保险', tag: '热卖', desc: '教育专属', image: `https://picsum.photos/seed/6/200/200` }, 83 + { id: 6, title: '少儿教育金保险', tag: '热卖', desc: '教育专属', image: `https://picsum.photos/seed/6/200/200` },
80 - { title: '高端医疗服务', desc: '尊享服务', image: `https://picsum.photos/seed/7/200/200` }, 84 + { id: 7, title: '高端医疗服务', desc: '尊享服务', image: `https://picsum.photos/seed/7/200/200` },
81 - { title: '家庭财产保险', desc: '全家无忧', image: `https://picsum.photos/seed/8/200/200` }, 85 + { id: 8, title: '家庭财产保险', desc: '全家无忧', image: `https://picsum.photos/seed/8/200/200` },
82 ] 86 ]
83 } 87 }
84 88
85 const products = ref(generateProducts()) 89 const products = ref(generateProducts())
86 90
91 +/**
92 + * 根据当前标签筛选产品
93 + *
94 + * @description 根据选中的标签页筛选显示对应产品
95 + */
87 const filteredProducts = computed(() => { 96 const filteredProducts = computed(() => {
88 if (activeTab.value === 0) return products.value 97 if (activeTab.value === 0) return products.value
89 // Mock filtering 98 // Mock filtering
90 return products.value.filter((_, i) => (i + activeTab.value) % 2 === 0) 99 return products.value.filter((_, i) => (i + activeTab.value) % 2 === 0)
91 }) 100 })
101 +
102 +/**
103 + * 使用产品列表点击处理器
104 + *
105 + * @description 配置为产品类型列表,点击时跳转到产品详情页
106 + */
107 +const { handleClick: handleProductClick } = useListItemClick({
108 + listType: ListType.PRODUCT,
109 + onAfterClick: (item) => {
110 + console.log('用户查看了产品:', item.title)
111 + }
112 +})
92 </script> 113 </script>
93 114
94 <style> 115 <style>
......