index.vue
7.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
<template>
<view class="min-h-screen bg-[#F9FAFB] pb-[calc(160rpx+env(safe-area-inset-bottom))]">
<!-- Navigation Header -->
<NavHeader title="搜索" />
<!-- Content Area -->
<view class="px-[40rpx] mt-[40rpx]">
<!-- Search Input -->
<view class="flex items-center w-full h-[88rpx] bg-white rounded-full px-[32rpx] border border-gray-200 mb-[40rpx]">
<IconFont name="search" class="text-gray-400 mr-[16rpx]" size="18" />
<input
v-model="searchKeyword"
type="text"
placeholder="搜索培训资料、案例、产品..."
class="flex-1 text-[28rpx] text-gray-800 placeholder-gray-400"
@confirm="handleSearch"
/>
<view v-if="searchKeyword" class="ml-[16rpx]" @tap="clearSearch">
<IconFont name="close" class="text-gray-400" size="16" />
</view>
</view>
<!-- Filter Tabs -->
<view class="flex overflow-x-auto no-scrollbar mb-[40rpx] space-x-[24rpx]">
<view v-for="(tab, index) in tabs" :key="index"
class="px-[32rpx] py-[16rpx] rounded-full text-[28rpx] whitespace-nowrap transition-colors"
:class="activeTab === index ? 'bg-[#2563EB] text-white' : 'bg-[#F3F4F6] text-[#6B7280]'"
@tap="activeTab = index">
{{ tab }}
</view>
</view>
<!-- Search Results -->
<view v-if="searchResults.length > 0">
<!-- Result Count -->
<view class="text-[#6B7280] text-[24rpx] mb-[24rpx]">
找到 {{ searchResults.length }} 个相关结果
</view>
<!-- Results List -->
<view class="flex flex-col gap-[24rpx]">
<!-- Product Card -->
<view
v-for="(item, index) in searchResults"
:key="index"
class="bg-white rounded-[24rpx] overflow-hidden shadow-sm"
@tap="goToDetail(item)"
>
<!-- Image + Content Layout -->
<view class="flex gap-[24rpx] p-[24rpx]">
<!-- Image -->
<image
class="w-[200rpx] h-[140rpx] rounded-[16rpx] bg-gray-100 flex-shrink-0"
:src="item.image"
mode="aspectFill"
/>
<!-- Content -->
<view class="flex-1 flex flex-col justify-between py-[4rpx]">
<!-- Title -->
<view class="text-[#1F2937] text-[28rpx] font-medium leading-[1.4] line-clamp-2">
{{ item.title }}
</view>
<!-- Meta Info -->
<view class="flex justify-between items-center">
<view class="flex gap-[12rpx]">
<!-- Type Tag -->
<view
class="px-[12rpx] py-[4rpx] rounded-[8rpx] text-[22rpx]"
:class="item.type === '产品' ? 'bg-blue-50 text-blue-600' : 'bg-green-50 text-green-600'"
>
{{ item.type }}
</view>
<!-- Hot Tag -->
<view v-if="item.tag" class="bg-red-50 text-red-600 text-[22rpx] px-[12rpx] py-[4rpx] rounded-[8rpx]">
{{ item.tag }}
</view>
</view>
<view class="text-[#6B7280] text-[24rpx]">
{{ item.views || 0 }}人查看
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- Empty State -->
<view v-else-if="hasSearched" class="flex flex-col items-center justify-center py-[120rpx]">
<image
class="w-[320rpx] h-[320rpx] mb-[40rpx]"
src="https://picsum.photos/seed/empty/320/320"
mode="aspectFit"
/>
<view class="text-[#6B7280] text-[28rpx]">暂无搜索结果</view>
<view class="text-[#9CA3AF] text-[24rpx] mt-[12rpx]">试试其他关键词吧</view>
</view>
<!-- Initial State -->
<view v-else class="flex flex-col items-center justify-center py-[120rpx]">
<IconFont name="search" class="text-gray-300 mb-[24rpx]" size="64" />
<view class="text-[#6B7280] text-[28rpx]">搜索培训资料、案例、产品</view>
<view class="text-[#9CA3AF] text-[24rpx] mt-[12rpx]">输入关键词开始搜索</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, computed } from 'vue'
import Taro from '@tarojs/taro'
import { useGo } from '@/hooks/useGo'
import NavHeader from '@/components/NavHeader.vue'
import IconFont from '@/components/IconFont.vue'
// Navigation
const go = useGo()
// State
const searchKeyword = ref('')
const activeTab = ref(0)
const hasSearched = ref(false)
// Tabs
const tabs = ['全部', '产品', '资料']
// Mock data
const mockData = ref([
{
id: 1,
title: '家庭财富传承保障计划(分红)',
type: '产品',
tag: '热卖',
views: 256,
image: 'https://picsum.photos/seed/prod1/200/140',
category: 'product'
},
{
id: 2,
title: '2024年保险市场趋势分析报告',
type: '资料',
views: 189,
image: 'https://picsum.photos/seed/mat1/200/140',
category: 'material'
},
{
id: 3,
title: '儿童教育金储备方案(分红)',
type: '产品',
tag: '推荐',
views: 342,
image: 'https://picsum.photos/seed/prod2/200/140',
category: 'product'
},
{
id: 4,
title: '高净值客户需求分析与产品匹配',
type: '资料',
views: 142,
image: 'https://picsum.photos/seed/mat2/200/140',
category: 'material'
},
{
id: 5,
title: '百万医疗保险计划',
type: '产品',
views: 267,
image: 'https://picsum.photos/seed/prod3/200/140',
category: 'product'
},
{
id: 6,
title: '保险合同条款解读与风险提示',
type: '资料',
views: 198,
image: 'https://picsum.photos/seed/mat3/200/140',
category: 'material'
},
{
id: 7,
title: '意外伤害保障计划',
type: '产品',
tag: '热卖',
views: 223,
image: 'https://picsum.photos/seed/prod4/200/140',
category: 'product'
},
{
id: 8,
title: '保险销售实战技巧分享',
type: '资料',
views: 156,
image: 'https://picsum.photos/seed/mat4/200/140',
category: 'material'
},
])
// Search results
const searchResults = computed(() => {
if (!hasSearched.value) return []
let results = mockData.value
// Filter by tab
if (activeTab.value === 1) {
results = results.filter(item => item.category === 'product')
} else if (activeTab.value === 2) {
results = results.filter(item => item.category === 'material')
}
// Filter by keyword
if (searchKeyword.value.trim()) {
const keyword = searchKeyword.value.toLowerCase()
results = results.filter(item =>
item.title.toLowerCase().includes(keyword)
)
}
return results
})
// Handle search
const handleSearch = () => {
if (searchKeyword.value.trim()) {
hasSearched.value = true
}
}
// Clear search
const clearSearch = () => {
searchKeyword.value = ''
hasSearched.value = false
}
// Go to detail
const goToDetail = (item) => {
if (item.category === 'product') {
go('/pages/knowledge-base/index')
} else {
go('/pages/knowledge-base/index')
}
Taro.showToast({
title: `查看${item.type}详情`,
icon: 'none',
duration: 1500
})
}
</script>
<style>
.no-scrollbar::-webkit-scrollbar {
display: none;
}
.no-scrollbar {
-ms-overflow-style: none;
scrollbar-width: none;
}
</style>