feat(statistics): 优化统计数据响应式与新增今日统计数据
- 将核心统计数据和待处理事项改为computed,确保响应式更新 - 使用ref管理待发货订单数、退款申请数和优惠券使用数 - 异步请求接口获取待处理事项的实际数据并更新状态 - 在统计模块中新增今日销售额、订单数和新增用户的安全获取逻辑 - 将今日统计数据纳入本地状态合并,提高数据完整性 - 修正今日统计显示逻辑,替换模拟数据为真实数据来源
This commit is contained in:
@@ -183,7 +183,38 @@ export const useStatisticsStore = defineStore('statistics', {
|
|||||||
return 0;
|
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 = (() => {
|
const totalSales = (() => {
|
||||||
if (!total) {
|
if (!total) {
|
||||||
console.warn('⚠️ 订单总额API返回空数据');
|
console.warn('⚠️ 订单总额API返回空数据');
|
||||||
@@ -224,13 +255,22 @@ export const useStatisticsStore = defineStore('statistics', {
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
// 更新本地数据
|
// 更新本地数据
|
||||||
statistics = { ...existingStatistics, ...updateData };
|
statistics = {
|
||||||
|
...existingStatistics,
|
||||||
|
...updateData,
|
||||||
|
todaySales,
|
||||||
|
todayOrders,
|
||||||
|
todayUsers
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
// 如果现有数据无效,使用基础数据
|
// 如果现有数据无效,使用基础数据
|
||||||
statistics = {
|
statistics = {
|
||||||
userCount: userCount,
|
userCount: userCount,
|
||||||
orderCount: orderCount,
|
orderCount: orderCount,
|
||||||
totalSales: totalSales
|
totalSales: totalSales,
|
||||||
|
todaySales: todaySales,
|
||||||
|
todayOrders: todayOrders,
|
||||||
|
todayUsers: todayUsers
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -238,7 +278,10 @@ export const useStatisticsStore = defineStore('statistics', {
|
|||||||
statistics = {
|
statistics = {
|
||||||
userCount: userCount,
|
userCount: userCount,
|
||||||
orderCount: orderCount,
|
orderCount: orderCount,
|
||||||
totalSales: totalSales
|
totalSales: totalSales,
|
||||||
|
todaySales: todaySales,
|
||||||
|
todayOrders: todayOrders,
|
||||||
|
todayUsers: todayUsers
|
||||||
};
|
};
|
||||||
|
|
||||||
// 异步保存到数据库
|
// 异步保存到数据库
|
||||||
|
|||||||
@@ -205,7 +205,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<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 { useRouter } from 'vue-router';
|
||||||
import {
|
import {
|
||||||
ReloadOutlined,
|
ReloadOutlined,
|
||||||
@@ -220,6 +220,7 @@ import {
|
|||||||
import { message } from 'ant-design-vue/es';
|
import { message } from 'ant-design-vue/es';
|
||||||
import { useSiteStore } from '@/store/modules/site';
|
import { useSiteStore } from '@/store/modules/site';
|
||||||
import { useStatisticsStore } from '@/store/modules/statistics';
|
import { useStatisticsStore } from '@/store/modules/statistics';
|
||||||
|
import { pageShopOrder } from '@/api/shop/shopOrder';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { removeSiteInfoCache } from '@/api/cms/cmsWebsite';
|
import { removeSiteInfoCache } from '@/api/cms/cmsWebsite';
|
||||||
|
|
||||||
@@ -246,32 +247,40 @@ const runDays = computed(() => siteStore.runDays);
|
|||||||
const userCount = computed(() => statisticsStore.userCount);
|
const userCount = computed(() => statisticsStore.userCount);
|
||||||
const orderCount = computed(() => statisticsStore.orderCount);
|
const orderCount = computed(() => statisticsStore.orderCount);
|
||||||
const totalSales = computed(() => statisticsStore.totalSales);
|
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 loading = computed(() => siteLoading.value || statisticsLoading.value);
|
||||||
|
|
||||||
// 核心统计数据
|
// 核心统计数据(使用computed确保响应式更新)
|
||||||
const coreStats = reactive([
|
const coreStats = computed(() => [
|
||||||
{ icon: '🏸', label: '用户总数', value: 0, desc: '注册用户', color: 'blue', to: '/system/user' },
|
{ icon: '🏸', label: '用户总数', value: userCount.value || 0, desc: '注册用户', color: 'blue', to: '/system/user' },
|
||||||
{ icon: '📦', label: '订单总数', value: 0, desc: '全部订单', color: 'orange', to: '/shop/shopOrder' },
|
{ icon: '📦', label: '订单总数', value: orderCount.value || 0, desc: '全部订单', color: 'orange', to: '/shop/shopOrder' },
|
||||||
{ icon: '💰', label: '总营业额', value: '0.00', desc: '元', color: 'purple', to: '/shop/shopOrder' },
|
{ icon: '💰', label: '总营业额', value: totalSales.value || 0, desc: '元', color: 'purple', to: '/shop/shopOrder' },
|
||||||
{ icon: '⏱️', label: '运行天数', value: 0, desc: '系统运行', color: 'green', to: '' },
|
{ icon: '⏱️', label: '运行天数', value: runDays.value || 0, desc: '系统运行', color: 'green', to: '' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 待处理事项
|
// 待处理事项数据
|
||||||
const todoItems = reactive([
|
const pendingShipmentCount = ref(0);
|
||||||
{ label: '待发货订单', value: 0, to: '/shop/shopOrder', tagColor: 'blue', dotColor: 'dot-blue', urgent: false },
|
const pendingRefundCount = ref(0);
|
||||||
{ label: '退款申请', value: 0, to: '/shop/shopOrder', tagColor: 'orange', dotColor: 'dot-orange', urgent: false },
|
const couponUsedCount = ref(0);
|
||||||
{ label: '优惠券使用', value: 0, to: '/market/coupon', tagColor: 'cyan', dotColor: 'dot-cyan', urgent: false },
|
|
||||||
|
// 待处理事项(使用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 },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 今日统计
|
// 今日统计(使用computed确保响应式更新)
|
||||||
const todayStats = reactive({
|
const todayStats = computed(() => ({
|
||||||
salesAmount: 0.00,
|
salesAmount: todaySales.value || 0,
|
||||||
orderCount: 0,
|
orderCount: todayOrders.value || 0,
|
||||||
newUsers: 0,
|
newUsers: todayUsers.value || 0,
|
||||||
couponUsed: 0,
|
couponUsed: couponUsedCount.value || 0,
|
||||||
});
|
}));
|
||||||
|
|
||||||
// 快速入口
|
// 快速入口
|
||||||
const quickLinks = [
|
const quickLinks = [
|
||||||
@@ -320,21 +329,49 @@ const loadData = async () => {
|
|||||||
statisticsStore.fetchStatistics()
|
statisticsStore.fetchStatistics()
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 更新核心统计数据
|
// 获取待处理事项数据
|
||||||
coreStats[0].value = userCount.value || 0;
|
try {
|
||||||
coreStats[1].value = orderCount.value || 0;
|
// 获取待发货订单数(deliveryStatus=10未发货,orderStatus=1已完成/已付款)
|
||||||
coreStats[2].value = totalSales.value || 0;
|
const shipmentResult = await pageShopOrder({
|
||||||
coreStats[3].value = runDays.value || 0;
|
deliveryStatus: 10,
|
||||||
|
orderStatus: 1,
|
||||||
|
page: 1,
|
||||||
|
limit: 1
|
||||||
|
});
|
||||||
|
pendingShipmentCount.value = shipmentResult?.count || 0;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('获取待发货订单数失败:', e);
|
||||||
|
pendingShipmentCount.value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// 模拟今日数据(实际应从后端统计接口获取)
|
try {
|
||||||
todayStats.salesAmount = totalSales.value;
|
// 获取退款申请数(orderStatus=4退款申请中,orderStatus=7客户端申请退款)
|
||||||
todayStats.orderCount = orderCount.value || 0;
|
const refundResult = await pageShopOrder({
|
||||||
todayStats.newUsers = Math.floor((userCount.value || 0) * 0.1);
|
orderStatus: 4,
|
||||||
todayStats.couponUsed = 0;
|
page: 1,
|
||||||
|
limit: 1
|
||||||
|
});
|
||||||
|
pendingRefundCount.value = refundResult?.count || 0;
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('获取退款申请数失败:', e);
|
||||||
|
pendingRefundCount.value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// 待处理事项(可以从 store 中获取真实数据)
|
try {
|
||||||
// todoItems[0].value = ... // 待发货订单数
|
// 获取今日使用优惠券的订单数
|
||||||
// todoItems[1].value = ... // 退款申请数
|
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) {
|
} catch (error) {
|
||||||
console.error('加载数据失败:', error);
|
console.error('加载数据失败:', error);
|
||||||
|
|||||||
Reference in New Issue
Block a user