feat(积分收集): 添加家庭积分收集功能并集成后端API
- 在PointsCollector组件中添加familyId属性用于家庭积分收集 - 新增collectPointAPI接口用于积分收集操作 - 实现单个积分项目收集和一键全部收集功能 - 添加错误处理和用户反馈
Showing
3 changed files
with
99 additions
and
29 deletions
| 1 | /* | 1 | /* |
| 2 | * @Date: 2023-12-22 10:29:37 | 2 | * @Date: 2023-12-22 10:29:37 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-09-01 13:53:17 | 4 | + * @LastEditTime: 2025-09-03 18:10:03 |
| 5 | * @FilePath: /lls_program/src/api/points.js | 5 | * @FilePath: /lls_program/src/api/points.js |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | */ | 7 | */ |
| ... | @@ -9,6 +9,7 @@ import { fn, fetch } from './fn'; | ... | @@ -9,6 +9,7 @@ import { fn, fetch } from './fn'; |
| 9 | 9 | ||
| 10 | const Api = { | 10 | const Api = { |
| 11 | SYNC_WX_STEP: '/srv/?a=point&t=sync_wx_step', | 11 | SYNC_WX_STEP: '/srv/?a=point&t=sync_wx_step', |
| 12 | + COLLECT_POINT: '/srv/?a=point&t=collect', | ||
| 12 | } | 13 | } |
| 13 | 14 | ||
| 14 | /** | 15 | /** |
| ... | @@ -16,3 +17,17 @@ const Api = { | ... | @@ -16,3 +17,17 @@ const Api = { |
| 16 | * @returns | 17 | * @returns |
| 17 | */ | 18 | */ |
| 18 | export const syncWxStepAPI = (params) => fn(fetch.post(Api.SYNC_WX_STEP, params)); | 19 | export const syncWxStepAPI = (params) => fn(fetch.post(Api.SYNC_WX_STEP, params)); |
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * @description: 汇总积分到家庭 | ||
| 23 | + * @param {*} params | ||
| 24 | + * @param {string} params.family_id - 家庭ID | ||
| 25 | + * @param {string} params.point_id - 积分ID, 为空时用于一键全积 | ||
| 26 | + * @returns {Object} response - 响应对象 | ||
| 27 | + * @returns {string} response.code - 响应状态码 | ||
| 28 | + * @returns {string} response.msg - 响应消息 | ||
| 29 | + * @returns {Object} response.data - 响应数据 | ||
| 30 | + * @returns {number} response.data.new_total_points - 最新的家庭积分 | ||
| 31 | + */ | ||
| 32 | + | ||
| 33 | +export const collectPointAPI = (params) => fn(fetch.post(Api.COLLECT_POINT, params)); | ... | ... |
| ... | @@ -36,6 +36,7 @@ | ... | @@ -36,6 +36,7 @@ |
| 36 | <script setup> | 36 | <script setup> |
| 37 | import { ref, onMounted, defineProps, defineExpose, defineEmits, watch } from 'vue' | 37 | import { ref, onMounted, defineProps, defineExpose, defineEmits, watch } from 'vue' |
| 38 | import Taro, { useDidShow } from '@tarojs/taro' | 38 | import Taro, { useDidShow } from '@tarojs/taro' |
| 39 | +import { collectPointAPI } from '@/api/points' | ||
| 39 | 40 | ||
| 40 | const emit = defineEmits(['collection-complete']) | 41 | const emit = defineEmits(['collection-complete']) |
| 41 | const props = defineProps({ | 42 | const props = defineProps({ |
| ... | @@ -50,6 +51,10 @@ const props = defineProps({ | ... | @@ -50,6 +51,10 @@ const props = defineProps({ |
| 50 | totalPoints: { | 51 | totalPoints: { |
| 51 | type: Number, | 52 | type: Number, |
| 52 | default: 0 | 53 | default: 0 |
| 54 | + }, | ||
| 55 | + familyId: { | ||
| 56 | + type: String, | ||
| 57 | + required: true | ||
| 53 | } | 58 | } |
| 54 | }) | 59 | }) |
| 55 | 60 | ||
| ... | @@ -183,20 +188,45 @@ const getItemStyle = (item) => { | ... | @@ -183,20 +188,45 @@ const getItemStyle = (item) => { |
| 183 | /** | 188 | /** |
| 184 | * 收集单个项目 | 189 | * 收集单个项目 |
| 185 | */ | 190 | */ |
| 186 | -const collectItem = (item) => { | 191 | +const collectItem = async (item) => { |
| 187 | if (item.collecting) return; | 192 | if (item.collecting) return; |
| 188 | item.collecting = true; | 193 | item.collecting = true; |
| 189 | 194 | ||
| 190 | - setTimeout(() => { | 195 | + try { |
| 191 | - const totalToAdd = item.points; | 196 | + // 调用收集积分接口 |
| 192 | - const newTotal = props.totalPoints + totalToAdd; | 197 | + const { code, data } = await collectPointAPI({ |
| 193 | - animateNumber(animatedTotalPoints.value, newTotal); | 198 | + family_id: props.familyId, |
| 194 | - | 199 | + point_id: item.id |
| 195 | - floatingItems.value = floatingItems.value.filter(i => i.id !== item.id); | 200 | + }); |
| 196 | - if (floatingItems.value.length === 0) { | 201 | + |
| 197 | - emit('collection-complete', newTotal); | 202 | + if (code) { |
| 203 | + setTimeout(() => { | ||
| 204 | + // 使用接口返回的最新积分总数 | ||
| 205 | + const newTotal = data.new_total_points; | ||
| 206 | + animateNumber(animatedTotalPoints.value, newTotal); | ||
| 207 | + | ||
| 208 | + floatingItems.value = floatingItems.value.filter(i => i.id !== item.id); | ||
| 209 | + if (floatingItems.value.length === 0) { | ||
| 210 | + emit('collection-complete', newTotal); | ||
| 211 | + } | ||
| 212 | + }, 800); // 动画时长 | ||
| 213 | + } else { | ||
| 214 | + // 接口调用失败,恢复状态 | ||
| 215 | + item.collecting = false; | ||
| 216 | + Taro.showToast({ | ||
| 217 | + title: '收取失败,请重试', | ||
| 218 | + icon: 'none' | ||
| 219 | + }); | ||
| 198 | } | 220 | } |
| 199 | - }, 800); // 动画时长 | 221 | + } catch (error) { |
| 222 | + // 异常处理,恢复状态 | ||
| 223 | + item.collecting = false; | ||
| 224 | + console.error('收集积分失败:', error); | ||
| 225 | + Taro.showToast({ | ||
| 226 | + title: '收取失败,请重试', | ||
| 227 | + icon: 'none' | ||
| 228 | + }); | ||
| 229 | + } | ||
| 200 | } | 230 | } |
| 201 | 231 | ||
| 202 | /** | 232 | /** |
| ... | @@ -206,25 +236,49 @@ const collectAll = async () => { | ... | @@ -206,25 +236,49 @@ const collectAll = async () => { |
| 206 | if (isCollecting.value) return; | 236 | if (isCollecting.value) return; |
| 207 | isCollecting.value = true; | 237 | isCollecting.value = true; |
| 208 | 238 | ||
| 209 | - let totalToAdd = 0; | 239 | + try { |
| 210 | - const itemsToCollect = [...floatingItems.value]; | 240 | + // 调用一键收取接口(point_id为空) |
| 211 | - | 241 | + const { code, data } = await collectPointAPI({ |
| 212 | - itemsToCollect.forEach((item, index) => { | 242 | + family_id: props.familyId, |
| 213 | - setTimeout(() => { | 243 | + point_id: '' // 空值表示一键收取 |
| 214 | - item.collecting = true; | 244 | + }); |
| 215 | - }, index * 80); // 依次触发动画 | 245 | + |
| 216 | - totalToAdd += item.points; | 246 | + if (code) { |
| 217 | - }); | 247 | + const itemsToCollect = [...floatingItems.value]; |
| 218 | - | 248 | + |
| 219 | - const totalAnimationTime = itemsToCollect.length * 80 + 800; | 249 | + itemsToCollect.forEach((item, index) => { |
| 220 | - setTimeout(() => { | 250 | + setTimeout(() => { |
| 221 | - const newTotal = props.totalPoints + totalToAdd; | 251 | + item.collecting = true; |
| 222 | - animateNumber(animatedTotalPoints.value, newTotal); | 252 | + }, index * 80); // 依次触发动画 |
| 223 | - | 253 | + }); |
| 224 | - floatingItems.value = []; | 254 | + |
| 255 | + const totalAnimationTime = itemsToCollect.length * 80 + 800; | ||
| 256 | + setTimeout(() => { | ||
| 257 | + // 使用接口返回的最新积分总数 | ||
| 258 | + const newTotal = data.new_total_points; | ||
| 259 | + animateNumber(animatedTotalPoints.value, newTotal); | ||
| 260 | + | ||
| 261 | + floatingItems.value = []; | ||
| 262 | + isCollecting.value = false; | ||
| 263 | + emit('collection-complete', newTotal); | ||
| 264 | + }, totalAnimationTime); | ||
| 265 | + } else { | ||
| 266 | + // 接口调用失败 | ||
| 267 | + isCollecting.value = false; | ||
| 268 | + Taro.showToast({ | ||
| 269 | + title: '一键收取失败,请重试', | ||
| 270 | + icon: 'none' | ||
| 271 | + }); | ||
| 272 | + } | ||
| 273 | + } catch (error) { | ||
| 274 | + // 异常处理 | ||
| 225 | isCollecting.value = false; | 275 | isCollecting.value = false; |
| 226 | - emit('collection-complete', newTotal); | 276 | + console.error('一键收取积分失败:', error); |
| 227 | - }, totalAnimationTime); | 277 | + Taro.showToast({ |
| 278 | + title: '一键收取失败,请重试', | ||
| 279 | + icon: 'none' | ||
| 280 | + }); | ||
| 281 | + } | ||
| 228 | } | 282 | } |
| 229 | 283 | ||
| 230 | /** | 284 | /** | ... | ... |
| ... | @@ -52,6 +52,7 @@ | ... | @@ -52,6 +52,7 @@ |
| 52 | height="30vh" | 52 | height="30vh" |
| 53 | :total-points="finalTotalPoints" | 53 | :total-points="finalTotalPoints" |
| 54 | :pending-points="pendingPoints" | 54 | :pending-points="pendingPoints" |
| 55 | + :family-id="family_id" | ||
| 55 | @collection-complete="handleCollectionComplete" | 56 | @collection-complete="handleCollectionComplete" |
| 56 | /> | 57 | /> |
| 57 | </template> | 58 | </template> | ... | ... |
-
Please register or login to post a comment