hookehuyr

feat(积分详情): 优化积分列表查询和显示逻辑

添加积分状态参数支持按类型筛选积分记录
使用API返回的创建时间替代当前时间显示
移除计算属性改用watch监听tab切换自动刷新
/*
* @Date: 2023-12-22 10:29:37
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-09-03 18:10:03
* @LastEditTime: 2025-09-04 10:09:32
* @FilePath: /lls_program/src/api/points.js
* @Description: 文件描述
*/
......@@ -36,6 +36,7 @@ export const collectPointAPI = (params) => fn(fetch.post(Api.COLLECT_POINT, para
/**
* @description: 查询积分列表
* @param {Object} params - 请求参数
* @param {string} [params.points_status] - 积分状态, issued=已发放,used=已消耗
* @param {string} [params.page] - 页码,从0开始,默认为0
* @param {string} [params.limit] - 每页数量,默认为10
* @returns {Object} response - 响应对象
......@@ -46,9 +47,9 @@ export const collectPointAPI = (params) => fn(fetch.post(Api.COLLECT_POINT, para
* @returns {Array} response.data.logs - 积分日志列表
* @returns {number} response.data.logs[].id - 积分日志ID
* @returns {string} response.data.logs[].points_change - 积分变化
* @returns {string} response.data.logs[].balance_after - 最新的家庭积分
* @returns {string} response.data.logs[].log_type - 日志类型
* @returns {string} response.data.logs[].source_type - 积分来源类型
* @returns {string} response.data.logs[].note - 备注
* @returns {string} response.data.logs[].created_time - 创建时间
*/
export const getPointListAPI = (params) => fn(fetch.get(Api.POINT_LIST, params));
......
......@@ -71,25 +71,26 @@
</view>
<!-- Points history list -->
<view class="pt-4">
<!-- Loading state -->
<view v-if="loading && pointsHistory.length === 0" class="py-8 text-center text-gray-500">
加载中...
</view>
<!-- Empty state -->
<view v-else-if="!loading && filteredPoints.length === 0" class="py-8 text-center text-gray-500">
暂无积分记录
<view v-if="loading">
<view class="py-8 text-center text-gray-500">
加载中...
</view>
</view>
<!-- Points list -->
<view v-else>
<view v-for="item in filteredPoints" :key="item.id" class="py-4 border-b border-gray-100 flex justify-between">
<view>
<h4 class="font-medium">{{ item.title }}</h4>
<p class="text-sm text-gray-500">{{ item.date }}</p>
<view v-if="pointsHistory && pointsHistory.length > 0">
<view v-for="item in pointsHistory" :key="item.id" class="py-4 border-b border-gray-100 flex justify-between">
<view>
<h4 class="font-medium">{{ item.title }}</h4>
<p class="text-sm text-gray-500">{{ item.date }}</p>
</view>
<span :class="['font-medium', item.type === 'earned' ? 'text-green-500' : 'text-red-500']">
{{ item.type === 'earned' ? '+' : '-' }}
{{ item.points }}
</span>
</view>
<span :class="['font-medium', item.type === 'earned' ? 'text-green-500' : 'text-red-500']">
{{ item.type === 'earned' ? '+' : '-' }}
{{ item.points }}
</span>
</view>
<view v-else class="py-8 text-center text-gray-500">
暂无积分记录
</view>
</view>
</view>
......@@ -100,7 +101,7 @@
</template>
<script setup>
import { ref, computed, onMounted } from 'vue';
import { ref, computed, onMounted, watch } from 'vue';
import Taro, { useDidShow } from '@tarojs/taro';
import AppHeader from '../../components/AppHeader.vue';
import BottomNav from '../../components/BottomNav.vue';
......@@ -112,7 +113,7 @@ const pointsHistory = ref([]);
const totalPoints = ref(0);
const loading = ref(false);
const page = ref(0);
const limit = ref(20);
const limit = ref(9999);
const hasMore = ref(true);
/**
......@@ -135,6 +136,12 @@ const fetchPointsList = async (isRefresh = false) => {
limit: limit.value.toString()
};
if (activeTab.value === 'earned') {
params.points_status = 'issued';
} else if (activeTab.value === 'spent') {
params.points_status = 'used';
}
const response = await getPointListAPI(params);
if (response.code && response.data) {
......@@ -146,7 +153,7 @@ const fetchPointsList = async (isRefresh = false) => {
const formattedLogs = logs.map(log => ({
id: log.id,
title: log.note || '积分变动',
date: formatDate(new Date()), // API没有返回时间,使用当前时间
date: formatDate(new Date(log.created_time)),
points: Math.abs(parseInt(log.points_change) || 0),
type: parseInt(log.points_change) > 0 ? 'earned' : 'spent',
log_type: log.log_type,
......@@ -190,11 +197,8 @@ const formatDate = (date) => {
return `${year}-${month}-${day} ${hours}:${minutes}`;
};
const filteredPoints = computed(() => {
if (activeTab.value === 'all') {
return pointsHistory.value;
}
return pointsHistory.value.filter(p => p.type === activeTab.value);
watch(activeTab, () => {
fetchPointsList(true);
});
const handleViewAll = () => {
......