hookehuyr

feat(积分收集): 添加家庭积分收集功能并集成后端API

- 在PointsCollector组件中添加familyId属性用于家庭积分收集
- 新增collectPointAPI接口用于积分收集操作
- 实现单个积分项目收集和一键全部收集功能
- 添加错误处理和用户反馈
/*
* @Date: 2023-12-22 10:29:37
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-09-01 13:53:17
* @LastEditTime: 2025-09-03 18:10:03
* @FilePath: /lls_program/src/api/points.js
* @Description: 文件描述
*/
......@@ -9,6 +9,7 @@ import { fn, fetch } from './fn';
const Api = {
SYNC_WX_STEP: '/srv/?a=point&t=sync_wx_step',
COLLECT_POINT: '/srv/?a=point&t=collect',
}
/**
......@@ -16,3 +17,17 @@ const Api = {
* @returns
*/
export const syncWxStepAPI = (params) => fn(fetch.post(Api.SYNC_WX_STEP, params));
/**
* @description: 汇总积分到家庭
* @param {*} params
* @param {string} params.family_id - 家庭ID
* @param {string} params.point_id - 积分ID, 为空时用于一键全积
* @returns {Object} response - 响应对象
* @returns {string} response.code - 响应状态码
* @returns {string} response.msg - 响应消息
* @returns {Object} response.data - 响应数据
* @returns {number} response.data.new_total_points - 最新的家庭积分
*/
export const collectPointAPI = (params) => fn(fetch.post(Api.COLLECT_POINT, params));
......
......@@ -36,6 +36,7 @@
<script setup>
import { ref, onMounted, defineProps, defineExpose, defineEmits, watch } from 'vue'
import Taro, { useDidShow } from '@tarojs/taro'
import { collectPointAPI } from '@/api/points'
const emit = defineEmits(['collection-complete'])
const props = defineProps({
......@@ -50,6 +51,10 @@ const props = defineProps({
totalPoints: {
type: Number,
default: 0
},
familyId: {
type: String,
required: true
}
})
......@@ -183,20 +188,45 @@ const getItemStyle = (item) => {
/**
* 收集单个项目
*/
const collectItem = (item) => {
const collectItem = async (item) => {
if (item.collecting) return;
item.collecting = true;
setTimeout(() => {
const totalToAdd = item.points;
const newTotal = props.totalPoints + totalToAdd;
animateNumber(animatedTotalPoints.value, newTotal);
floatingItems.value = floatingItems.value.filter(i => i.id !== item.id);
if (floatingItems.value.length === 0) {
emit('collection-complete', newTotal);
try {
// 调用收集积分接口
const { code, data } = await collectPointAPI({
family_id: props.familyId,
point_id: item.id
});
if (code) {
setTimeout(() => {
// 使用接口返回的最新积分总数
const newTotal = data.new_total_points;
animateNumber(animatedTotalPoints.value, newTotal);
floatingItems.value = floatingItems.value.filter(i => i.id !== item.id);
if (floatingItems.value.length === 0) {
emit('collection-complete', newTotal);
}
}, 800); // 动画时长
} else {
// 接口调用失败,恢复状态
item.collecting = false;
Taro.showToast({
title: '收取失败,请重试',
icon: 'none'
});
}
}, 800); // 动画时长
} catch (error) {
// 异常处理,恢复状态
item.collecting = false;
console.error('收集积分失败:', error);
Taro.showToast({
title: '收取失败,请重试',
icon: 'none'
});
}
}
/**
......@@ -206,25 +236,49 @@ const collectAll = async () => {
if (isCollecting.value) return;
isCollecting.value = true;
let totalToAdd = 0;
const itemsToCollect = [...floatingItems.value];
itemsToCollect.forEach((item, index) => {
setTimeout(() => {
item.collecting = true;
}, index * 80); // 依次触发动画
totalToAdd += item.points;
});
const totalAnimationTime = itemsToCollect.length * 80 + 800;
setTimeout(() => {
const newTotal = props.totalPoints + totalToAdd;
animateNumber(animatedTotalPoints.value, newTotal);
floatingItems.value = [];
try {
// 调用一键收取接口(point_id为空)
const { code, data } = await collectPointAPI({
family_id: props.familyId,
point_id: '' // 空值表示一键收取
});
if (code) {
const itemsToCollect = [...floatingItems.value];
itemsToCollect.forEach((item, index) => {
setTimeout(() => {
item.collecting = true;
}, index * 80); // 依次触发动画
});
const totalAnimationTime = itemsToCollect.length * 80 + 800;
setTimeout(() => {
// 使用接口返回的最新积分总数
const newTotal = data.new_total_points;
animateNumber(animatedTotalPoints.value, newTotal);
floatingItems.value = [];
isCollecting.value = false;
emit('collection-complete', newTotal);
}, totalAnimationTime);
} else {
// 接口调用失败
isCollecting.value = false;
Taro.showToast({
title: '一键收取失败,请重试',
icon: 'none'
});
}
} catch (error) {
// 异常处理
isCollecting.value = false;
emit('collection-complete', newTotal);
}, totalAnimationTime);
console.error('一键收取积分失败:', error);
Taro.showToast({
title: '一键收取失败,请重试',
icon: 'none'
});
}
}
/**
......
......@@ -52,6 +52,7 @@
height="30vh"
:total-points="finalTotalPoints"
:pending-points="pendingPoints"
:family-id="family_id"
@collection-complete="handleCollectionComplete"
/>
</template>
......