feat(statistics): 优化统计数据响应式与新增今日统计数据

- 将核心统计数据和待处理事项改为computed,确保响应式更新
- 使用ref管理待发货订单数、退款申请数和优惠券使用数
- 异步请求接口获取待处理事项的实际数据并更新状态
- 在统计模块中新增今日销售额、订单数和新增用户的安全获取逻辑
- 将今日统计数据纳入本地状态合并,提高数据完整性
- 修正今日统计显示逻辑,替换模拟数据为真实数据来源
This commit is contained in:
2026-07-14 02:51:06 +08:00
parent 76ab68322c
commit 2cca9b2518
2 changed files with 116 additions and 36 deletions

View File

@@ -183,7 +183,38 @@ export const useStatisticsStore = defineStore('statistics', {
return 0;
})();
// 安全获取销售额,处理数组情况
// 安全获取今日销售额
const todaySales = (() => {
if (statisticsData && statisticsData.length > 0) {
const stats = statisticsData[0];
if (stats.todaySales !== undefined && stats.todaySales !== null) {
return safeNumber(stats.todaySales);
}
}
return 0;
})();
// 安全获取今日订单数
const todayOrders = (() => {
if (statisticsData && statisticsData.length > 0) {
const stats = statisticsData[0];
if (stats.todayOrders !== undefined && stats.todayOrders !== null) {
return safeNumber(stats.todayOrders);
}
}
return 0;
})();
// 安全获取今日新增用户
const todayUsers = (() => {
if (statisticsData && statisticsData.length > 0) {
const stats = statisticsData[0];
if (stats.todayUsers !== undefined && stats.todayUsers !== null) {
return safeNumber(stats.todayUsers);
}
}
return 0;
})();
const totalSales = (() => {
if (!total) {
console.warn('⚠️ 订单总额API返回空数据');
@@ -224,13 +255,22 @@ export const useStatisticsStore = defineStore('statistics', {
}, 1000);
// 更新本地数据
statistics = { ...existingStatistics, ...updateData };
statistics = {
...existingStatistics,
...updateData,
todaySales,
todayOrders,
todayUsers
};
} else {
// 如果现有数据无效,使用基础数据
statistics = {
userCount: userCount,
orderCount: orderCount,
totalSales: totalSales
totalSales: totalSales,
todaySales: todaySales,
todayOrders: todayOrders,
todayUsers: todayUsers
};
}
} else {
@@ -238,7 +278,10 @@ export const useStatisticsStore = defineStore('statistics', {
statistics = {
userCount: userCount,
orderCount: orderCount,
totalSales: totalSales
totalSales: totalSales,
todaySales: todaySales,
todayOrders: todayOrders,
todayUsers: todayUsers
};
// 异步保存到数据库

View File

@@ -205,7 +205,7 @@
</template>
<script lang="ts" setup>
import { reactive, computed, onMounted, onUnmounted } from 'vue';
import { reactive, ref, computed, onMounted, onUnmounted } from 'vue';
import { useRouter } from 'vue-router';
import {
ReloadOutlined,
@@ -220,6 +220,7 @@ import {
import { message } from 'ant-design-vue/es';
import { useSiteStore } from '@/store/modules/site';
import { useStatisticsStore } from '@/store/modules/statistics';
import { pageShopOrder } from '@/api/shop/shopOrder';
import { storeToRefs } from 'pinia';
import { removeSiteInfoCache } from '@/api/cms/cmsWebsite';
@@ -246,32 +247,40 @@ const runDays = computed(() => siteStore.runDays);
const userCount = computed(() => statisticsStore.userCount);
const orderCount = computed(() => statisticsStore.orderCount);
const totalSales = computed(() => statisticsStore.totalSales);
const todaySales = computed(() => statisticsStore.todaySales);
const todayOrders = computed(() => statisticsStore.todayOrders);
const todayUsers = computed(() => statisticsStore.todayUsers);
// 加载状态
const loading = computed(() => siteLoading.value || statisticsLoading.value);
// 核心统计数据
const coreStats = reactive([
{ icon: '🏸', label: '用户总数', value: 0, desc: '注册用户', color: 'blue', to: '/system/user' },
{ icon: '📦', label: '订单总数', value: 0, desc: '全部订单', color: 'orange', to: '/shop/shopOrder' },
{ icon: '💰', label: '总营业额', value: '0.00', desc: '元', color: 'purple', to: '/shop/shopOrder' },
{ icon: '⏱️', label: '运行天数', value: 0, desc: '系统运行', color: 'green', to: '' },
// 核心统计数据使用computed确保响应式更新
const coreStats = computed(() => [
{ icon: '🏸', label: '用户总数', value: userCount.value || 0, desc: '注册用户', color: 'blue', to: '/system/user' },
{ icon: '📦', label: '订单总数', value: orderCount.value || 0, desc: '全部订单', color: 'orange', to: '/shop/shopOrder' },
{ icon: '💰', label: '总营业额', value: totalSales.value || 0, desc: '元', color: 'purple', to: '/shop/shopOrder' },
{ icon: '⏱️', label: '运行天数', value: runDays.value || 0, desc: '系统运行', color: 'green', to: '' },
]);
// 待处理事项
const todoItems = reactive([
{ label: '待发货订单', value: 0, to: '/shop/shopOrder', tagColor: 'blue', dotColor: 'dot-blue', urgent: false },
{ label: '退款申请', value: 0, to: '/shop/shopOrder', tagColor: 'orange', dotColor: 'dot-orange', urgent: false },
{ label: '优惠券使用', value: 0, to: '/market/coupon', tagColor: 'cyan', dotColor: 'dot-cyan', urgent: false },
// 待处理事项数据
const pendingShipmentCount = ref(0);
const pendingRefundCount = ref(0);
const couponUsedCount = ref(0);
// 待处理事项使用computed确保响应式更新
const todoItems = computed(() => [
{ label: '待发货订单', value: pendingShipmentCount.value, to: '/shop/shopOrder', tagColor: 'blue', dotColor: 'dot-blue', urgent: pendingShipmentCount.value > 0 },
{ label: '退款申请', value: pendingRefundCount.value, to: '/shop/shopOrder', tagColor: 'orange', dotColor: 'dot-orange', urgent: pendingRefundCount.value > 0 },
{ label: '优惠券使用', value: couponUsedCount.value, to: '/market/coupon', tagColor: 'cyan', dotColor: 'dot-cyan', urgent: false },
]);
// 今日统计
const todayStats = reactive({
salesAmount: 0.00,
orderCount: 0,
newUsers: 0,
couponUsed: 0,
});
// 今日统计使用computed确保响应式更新
const todayStats = computed(() => ({
salesAmount: todaySales.value || 0,
orderCount: todayOrders.value || 0,
newUsers: todayUsers.value || 0,
couponUsed: couponUsedCount.value || 0,
}));
// 快速入口
const quickLinks = [
@@ -320,21 +329,49 @@ const loadData = async () => {
statisticsStore.fetchStatistics()
]);
// 更新核心统计数据
coreStats[0].value = userCount.value || 0;
coreStats[1].value = orderCount.value || 0;
coreStats[2].value = totalSales.value || 0;
coreStats[3].value = runDays.value || 0;
// 获取待处理事项数据
try {
// 获取待发货订单数deliveryStatus=10未发货orderStatus=1已完成/已付款)
const shipmentResult = await pageShopOrder({
deliveryStatus: 10,
orderStatus: 1,
page: 1,
limit: 1
});
pendingShipmentCount.value = shipmentResult?.count || 0;
} catch (e) {
console.warn('获取待发货订单数失败:', e);
pendingShipmentCount.value = 0;
}
// 模拟今日数据(实际应从后端统计接口获取)
todayStats.salesAmount = totalSales.value;
todayStats.orderCount = orderCount.value || 0;
todayStats.newUsers = Math.floor((userCount.value || 0) * 0.1);
todayStats.couponUsed = 0;
try {
// 获取退款申请数orderStatus=4退款申请中orderStatus=7客户端申请退款
const refundResult = await pageShopOrder({
orderStatus: 4,
page: 1,
limit: 1
});
pendingRefundCount.value = refundResult?.count || 0;
} catch (e) {
console.warn('获取退款申请数失败:', e);
pendingRefundCount.value = 0;
}
// 待处理事项(可以从 store 中获取真实数据)
// todoItems[0].value = ... // 待发货订单数
// todoItems[1].value = ... // 退款申请数
try {
// 获取今日使用优惠券的订单数
const today = new Date().toISOString().split('T')[0];
const couponResult = await pageShopOrder({
couponType: 1, // 抵扣优惠券
createTimeStart: today,
createTimeEnd: today,
page: 1,
limit: 1
});
couponUsedCount.value = couponResult?.count || 0;
} catch (e) {
console.warn('获取优惠券使用数失败:', e);
couponUsedCount.value = 0;
}
} catch (error) {
console.error('加载数据失败:', error);