index.vue
11.8 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
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
<!--
* @Description: 积分攻略列表页面
-->
<template>
<view class="points-list-page">
<!-- 搜索框 -->
<view class="search-section">
<view class="search-box">
<input
v-model="searchKeyword"
placeholder="搜索积分攻略"
class="search-input"
@input="handleSearch"
/>
</view>
</view>
<!-- 攻略分类 -->
<view class="category-section">
<view class="category-title">攻略分类</view>
<view class="category-grid">
<view
v-for="category in categories"
:key="category.id"
class="category-item"
@click="filterByCategory(category.id)"
:class="{ active: selectedCategory === category.id }"
>
<text class="category-name">{{ category.name }}</text>
</view>
</view>
</view>
<!-- 攻略列表 -->
<view class="points-list-section">
<scroll-view
class="points-list"
:scroll-y="true"
:style="scrollStyle"
>
<view class="points-items">
<view
v-for="item in filteredPointsItems"
:key="item.id"
class="points-item"
@click="showPointsDetail(item)"
>
<view class="points-item-left">
<view class="points-content">
<text class="points-title">{{ item.title }}</text>
<text class="points-desc">{{ item.description }}</text>
<view class="points-reward">
<text class="reward-text">可获得: {{ item.reward }}积分</text>
</view>
</view>
</view>
<view class="points-item-right">
<text class="arrow-text"><RectRight /></text>
</view>
</view>
</view>
<!-- 空状态 -->
<view
v-if="filteredPointsItems.length === 0"
class="empty-state"
>
<text class="empty-text">暂无相关积分攻略</text>
</view>
</scroll-view>
</view>
<!-- 右侧弹出详情 -->
<nut-popup
v-model:visible="showDetailPopup"
position="right"
:style="{ width: '85%', height: '100%' }"
@close="closeDetail"
>
<view class="detail-popup">
<!-- 详情头部 -->
<view class="detail-header">
<view class="detail-title">{{ currentPointsItem?.title }}</view>
<view class="close-btn1" @click="closeDetail">
<text class="close-text">关闭</text>
</view>
</view>
<!-- 详情内容 -->
<scroll-view class="detail-content" :scroll-y="true">
<view class="detail-body">
<!-- 攻略描述 -->
<view class="detail-section">
<view class="section-title">攻略描述</view>
<text class="section-content">{{ currentPointsItem?.description }}</text>
</view>
<!-- 获取步骤 -->
<view class="detail-section">
<view class="section-title">获取步骤</view>
<view class="solution-content">
<view
v-for="(step, index) in currentPointsItem?.steps"
:key="index"
class="solution-step"
>
<view class="step-number">{{ index + 1 }}</view>
<text class="step-content">{{ step }}</text>
</view>
</view>
</view>
<!-- 积分奖励 -->
<view class="detail-section">
<view class="section-title">积分奖励</view>
<view class="reward-section">
<view class="reward-item">
<text class="reward-label">基础积分:</text>
<text class="reward-value">{{ currentPointsItem?.reward }}分</text>
</view>
<view v-if="currentPointsItem?.bonusReward" class="reward-item">
<text class="reward-label">额外奖励:</text>
<text class="reward-value bonus">{{ currentPointsItem?.bonusReward }}分</text>
</view>
</view>
</view>
<!-- 注意事项 -->
<view v-if="currentPointsItem?.notes?.length" class="detail-section">
<view class="section-title">注意事项</view>
<view class="notes-content">
<view
v-for="(note, index) in currentPointsItem.notes"
:key="index"
class="note-item"
>
<text class="note-text">• {{ note }}</text>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</nut-popup>
<!-- Toast提示 -->
<nut-toast
v-model:visible="toastVisible"
:msg="toastMessage"
:type="toastType"
/>
</view>
</template>
<script setup>
// import '@tarojs/taro/html.css'
import { ref, computed, onMounted } from 'vue'
import Taro from '@tarojs/taro'
import { RectRight } from '@nutui/icons-vue-taro'
import './index.less'
/**
* 积分攻略列表页面组件
* 功能:展示各种积分获取攻略、搜索和分类筛选
*/
// ==================== 响应式数据 ====================
/**
* 搜索关键词
*/
const searchKeyword = ref('')
/**
* 选中的分类
*/
const selectedCategory = ref('all')
/**
* 详情弹窗显示状态
*/
const showDetailPopup = ref(false)
/**
* 当前查看的积分攻略项
*/
const currentPointsItem = ref(null)
/**
* Toast提示
*/
const toastVisible = ref(false)
const toastMessage = ref('')
const toastType = ref('success')
/**
* 攻略分类数据
*/
const categories = ref([
{ id: 'all', name: '全部' },
{ id: 'daily', name: '日常任务' },
{ id: 'activity', name: '活动参与' },
{ id: 'family', name: '家庭互动' },
{ id: 'special', name: '特殊奖励' }
])
/**
* 积分攻略数据
*/
const pointsItems = ref([
{
id: 'p001',
category: 'daily',
title: '每日步数积分攻略',
description: '通过日常走路获得积分,简单易行的积分获取方式',
reward: 50,
bonusReward: 20,
steps: [
'打开微信运动,确保步数同步正常',
'每日保持至少3000步的运动量',
'在老来赛APP中同步当日步数',
'系统自动计算并发放积分奖励',
'连续7天可获得额外奖励积分'
],
notes: [
'每日步数积分上限为50分',
'步数需在当日23:59前同步',
'连续签到可获得额外奖励'
]
},
{
id: 'p002',
category: 'family',
title: '家庭成员邀请攻略',
description: '邀请家庭成员加入,共同获得积分奖励',
reward: 200,
bonusReward: 100,
steps: [
'进入家庭页面,点击邀请成员',
'分享家庭邀请码给家人',
'家人通过邀请码成功加入家庭',
'双方都可获得邀请奖励积分',
'家庭成员达到5人可获得额外奖励'
],
notes: [
'每邀请一位成员可获得200积分',
'被邀请者也可获得100积分',
'家庭成员上限为10人'
]
},
{
id: 'p003',
category: 'activity',
title: '参与社区活动攻略',
description: '参加线下社区活动,获得丰厚积分奖励',
reward: 500,
bonusReward: 300,
steps: [
'关注活动页面的最新活动信息',
'报名参加感兴趣的社区活动',
'按时到达活动地点参与活动',
'完成活动打卡和照片上传',
'活动结束后获得积分奖励'
],
notes: [
'不同活动积分奖励不同',
'需要实地参与才能获得积分',
'上传照片可获得额外积分'
]
},
{
id: 'p004',
category: 'daily',
title: '每日签到积分攻略',
description: '每天登录APP签到,轻松获得积分',
reward: 10,
bonusReward: 50,
steps: [
'每日打开老来赛APP',
'点击首页的签到按钮',
'完成当日签到获得基础积分',
'连续签到可获得递增奖励',
'连续签到7天获得额外奖励'
],
notes: [
'每日签到基础积分为10分',
'连续签到奖励递增',
'中断签到需重新开始计算'
]
},
{
id: 'p005',
category: 'family',
title: '家庭步数排行攻略',
description: '参与家庭步数排行,获得排名奖励',
reward: 100,
bonusReward: 200,
steps: [
'确保家庭成员都已加入',
'每日同步个人步数数据',
'查看家庭步数排行榜',
'努力提升个人排名',
'周末结算排名奖励积分'
],
notes: [
'排名前三可获得额外奖励',
'家庭总步数也有奖励',
'鼓励家庭成员互相督促'
]
},
{
id: 'p006',
category: 'special',
title: '轮椅陪伴运动攻略',
description: '陪伴轮椅老人运动,获得三倍积分奖励',
reward: 150,
bonusReward: 300,
steps: [
'在个人资料中标注陪伴轮椅老人',
'与轮椅老人一起进行运动',
'记录陪伴运动的时间和距离',
'上传陪伴运动的照片或视频',
'系统验证后发放三倍积分奖励'
],
notes: [
'需要提供陪伴证明',
'积分为普通运动的三倍',
'体现社会关爱精神'
]
},
{
id: 'p007',
category: 'activity',
title: '完成城市漫步攻略',
description: '参与城市漫步活动,探索城市获得积分',
reward: 300,
bonusReward: 200,
steps: [
'选择感兴趣的城市漫步路线',
'按照路线进行实地探索',
'在指定地点完成打卡',
'上传风景照片和感想',
'完成全部打卡点获得奖励'
],
notes: [
'需要完成所有打卡点',
'照片需要包含地标建筑',
'可以邀请家人一起参与'
]
},
{
id: 'p008',
category: 'special',
title: '节日特殊活动攻略',
description: '参与节日特殊活动,获得限时积分奖励',
reward: 888,
steps: [
'关注节日活动公告',
'参与节日主题活动',
'完成节日特殊任务',
'分享节日祝福内容',
'获得节日限定积分奖励'
],
notes: [
'节日活动时间有限',
'积分奖励通常较高',
'增加节日氛围和参与感'
]
}
])
/**
* 滚动样式
*/
const scrollStyle = computed(() => {
return {
height: 'calc(100vh - 260rpx)' // 减去header、搜索框、分类的高度
}
})
/**
* 过滤后的积分攻略项
*/
const filteredPointsItems = computed(() => {
let items = pointsItems.value
// 按分类过滤
if (selectedCategory.value !== 'all') {
items = items.filter(item => item.category === selectedCategory.value)
}
// 按搜索关键词过滤
if (searchKeyword.value.trim()) {
const keyword = searchKeyword.value.toLowerCase()
items = items.filter(item =>
item.title.toLowerCase().includes(keyword) ||
item.description.toLowerCase().includes(keyword)
)
}
return items
})
// ==================== 方法 ====================
/**
* 返回上一页
*/
const goBack = () => {
Taro.navigateBack()
}
/**
* 处理搜索
*/
const handleSearch = () => {
// 搜索逻辑已在computed中处理
}
/**
* 按分类过滤
*/
const filterByCategory = (categoryId) => {
selectedCategory.value = categoryId
}
/**
* 显示积分攻略详情
*/
const showPointsDetail = (item) => {
currentPointsItem.value = item
showDetailPopup.value = true
}
/**
* 关闭详情
*/
const closeDetail = () => {
showDetailPopup.value = false
currentPointsItem.value = null
}
// ==================== 生命周期 ====================
onMounted(() => {
// 页面初始化逻辑
})
</script>
<script>
export default {
name: 'PointsListPage'
}
</script>