优化:getSiteInfo、statistics使用了状态管理模式,提升性能。

This commit is contained in:
2025-07-31 11:08:08 +08:00
parent 75aeccbb1a
commit 6f4ff3f8fb
11 changed files with 1367 additions and 163 deletions

View File

@@ -11,20 +11,20 @@
:height="80"
:preview="false"
style="border-radius: 8px"
:src="siteInfo.websiteLogo"
:src="siteStore.websiteLogo"
fallback="/logo.png"
/>
</a-col>
<a-col :span="14">
<div class="system-info">
<h2 class="ele-text-heading">{{ siteInfo.websiteName }}</h2>
<p class="ele-text-secondary">{{ siteInfo.comments }}</p>
<h2 class="ele-text-heading">{{ siteStore.websiteName }}</h2>
<p class="ele-text-secondary">{{ siteStore.websiteComments }}</p>
<a-space>
<a-tag color="blue">版本 {{ systemInfo.version }}</a-tag>
<a-tag color="green">{{ systemInfo.status }}</a-tag>
<a-popover title="小程序码">
<template #content>
<p><img :src="siteInfo.websiteDarkLogo" alt="小程序码" width="300" height="300"></p>
<p><img :src="siteStore.websiteDarkLogo" alt="小程序码" width="300" height="300"></p>
</template>
<a-tag>
<QrcodeOutlined/>
@@ -47,8 +47,9 @@
<a-card :bordered="false" class="stat-card">
<a-statistic
title="用户总数"
:value="form.userCount"
:value="userCount"
:value-style="{ color: '#3f8600' }"
:loading="loading"
>
<template #prefix>
<UserOutlined/>
@@ -61,8 +62,9 @@
<a-card :bordered="false" class="stat-card">
<a-statistic
title="订单总数"
:value="form.orderCount"
:value="orderCount"
:value-style="{ color: '#1890ff' }"
:loading="loading"
>
<template #prefix>
<AccountBookOutlined/>
@@ -75,8 +77,9 @@
<a-card :bordered="false" class="stat-card">
<a-statistic
title="总营业额"
:value="form.totalSales"
:value="totalSales"
:value-style="{ color: '#cf1322' }"
:loading="loading"
>
<template #prefix>
<MoneyCollectOutlined/>
@@ -92,6 +95,7 @@
:value="runDays"
suffix="天"
:value-style="{ color: '#722ed1' }"
:loading="loading"
>
<template #prefix>
<ClockCircleOutlined/>
@@ -164,7 +168,7 @@
</template>
<script lang="ts" setup>
import {ref, reactive, onMounted} from 'vue';
import {ref, onMounted, onUnmounted, computed} from 'vue';
import {
UserOutlined,
CalendarOutlined,
@@ -176,18 +180,18 @@ import {
FileTextOutlined,
MoneyCollectOutlined
} from '@ant-design/icons-vue';
import {assignObject} from 'ele-admin-pro';
import {getSiteInfo} from "@/api/layout";
import {CmsWebsite} from "@/api/cms/cmsWebsite/model";
import {pageUsers} from "@/api/system/user";
import {addShopOrder, pageShopOrder, shopOrderTotal} from "@/api/shop/shopOrder";
import {openNew} from "@/utils/common";
import {addCmsStatistics, listCmsStatistics, updateCmsStatistics} from "@/api/cms/cmsStatistics";
import {CmsStatistics} from "@/api/cms/cmsStatistics/model";
import {addCmsArticle, updateCmsArticle} from "@/api/cms/cmsArticle";
import { useSiteStore } from '@/store/modules/site';
import { useStatisticsStore } from '@/store/modules/statistics';
import { storeToRefs } from 'pinia';
// 当前小程序项目
const siteInfo = ref<CmsWebsite>({});
// 使用状态管理
const siteStore = useSiteStore();
const statisticsStore = useStatisticsStore();
// 从 store 中获取响应式数据
const { siteInfo, loading: siteLoading } = storeToRefs(siteStore);
const { loading: statisticsLoading } = storeToRefs(statisticsStore);
// 系统信息
const systemInfo = ref({
@@ -202,118 +206,34 @@ const systemInfo = ref({
expirationTime: '2024-01-01 09:00:00'
});
const runDays = ref<number>(0)
// 计算属性
const runDays = computed(() => siteStore.runDays);
const userCount = computed(() => statisticsStore.userCount);
const orderCount = computed(() => statisticsStore.orderCount);
const totalSales = computed(() => statisticsStore.totalSales);
// 统计数据
const form = reactive<CmsStatistics>({
websiteId: undefined,
// 用户总数
userCount: undefined,
// 订单总数
orderCount: undefined,
// 商品总数
productCount: undefined,
// 总销售额
totalSales: undefined,
// 本月销售额
monthSales: undefined,
// 今日销售额
todaySales: undefined,
// 昨日销售额
yesterdaySales: undefined,
// 本周销售额
weekSales: undefined,
// 本年销售额
yearSales: undefined,
// 今日订单数
todayOrders: undefined,
// 本月订单数
monthOrders: undefined,
// 今日新增用户
todayUsers: undefined,
// 本月新增用户
monthUsers: undefined,
// 今日访问量
todayVisits: undefined,
// 总访问量
totalVisits: undefined,
// 商户总数
merchantCount: undefined,
// 活跃用户数
activeUsers: undefined,
// 转化率(%)
conversionRate: undefined,
// 平均订单金额
avgOrderAmount: undefined,
// 统计日期
statisticsDate: undefined,
// 统计类型: 1日统计, 2月统计, 3年统计
statisticsType: undefined,
// 运行天数
runDays: undefined,
// 排序号
sortNumber: undefined,
// 操作用户ID
userId: undefined,
// 商户ID
merchantId: undefined,
// 状态: 0禁用, 1启用
status: undefined,
// 是否删除: 0否, 1是
deleted: undefined,
// 租户ID
tenantId: undefined,
// 创建时间
createTime: undefined,
// 修改时间
updateTime: undefined,
// 加载状态
const loading = computed(() => siteLoading.value || statisticsLoading.value);
onMounted(async () => {
// 加载网站信息和统计数据
try {
await Promise.all([
siteStore.fetchSiteInfo(),
statisticsStore.fetchStatistics()
]);
// 开始自动刷新统计数据每5分钟
statisticsStore.startAutoRefresh();
} catch (error) {
console.error('加载数据失败:', error);
}
});
onMounted(() => {
// 加载系统信息和统计数据
loadSystemInfo();
loadStatistics();
onUnmounted(() => {
// 组件卸载时停止自动刷新
statisticsStore.stopAutoRefresh();
});
const loadSystemInfo = async () => {
// TODO: 调用API获取系统信息
siteInfo.value = await getSiteInfo();
if (siteInfo.value.createTime) {
// 根据创建时间计算运行天数
runDays.value = Math.floor((new Date().getTime() - new Date(siteInfo.value.createTime).getTime()) / (24 * 60 * 60 * 1000))
}
};
const loadStatistics = async () => {
// TODO: 调用API获取统计数据
const users = await pageUsers({})
const orders = await pageShopOrder({})
const total = await shopOrderTotal()
const data = await listCmsStatistics({});
// 获取统计表数据
if (data) {
const saveOrUpdate = data.length > 0 ? updateCmsStatistics : addCmsStatistics;
if (data.length > 0) {
const saveData = data[0]
assignObject(form, saveData);
// 更新数据
setTimeout(() => {
if (saveData && users && orders) {
const id = saveData.id
saveOrUpdate({
id,
userCount: users.count,
orderCount: orders.count,
totalSales: Number(total),
})
}
},2000)
}
}
};
</script>
<style scoped>

View File

@@ -164,7 +164,7 @@ import {
} from "@/utils/domain";
import {openNew, openPreview} from "@/utils/common";
import {FileRecord} from "@/api/system/file/model";
import {getSiteInfo} from "@/api/layout";
import { useSiteStore } from '@/store/modules/site';
const useForm = Form.useForm;
@@ -173,6 +173,7 @@ import {getSiteInfo} from "@/api/layout";
const themeStore = useThemeStore();
const { styleResponsive } = storeToRefs(themeStore);
const userStore = useUserStore();
const siteStore = useSiteStore();
// 当前开发环境
const env = import.meta.env.MODE;
// tab 页选中
@@ -326,21 +327,28 @@ const onDeleteItem = (index: number) => {
form.websiteLogo = '';
}
const query = () => {
const query = async () => {
logo.value = [];
getSiteInfo().then(data => {
assignFields(data)
logo.value.push({
uid: 1,
url: data.websiteLogo,
status: 'done'
});
darkLogo.value.push({
uid: 1,
url: data.websiteDarkLogo,
status: 'done'
})
})
try {
const data = await siteStore.fetchSiteInfo();
assignFields(data);
if (data.websiteLogo) {
logo.value.push({
uid: 1,
url: data.websiteLogo,
status: 'done'
});
}
if (data.websiteDarkLogo) {
darkLogo.value.push({
uid: 1,
url: data.websiteDarkLogo,
status: 'done'
});
}
} catch (error) {
console.error('获取网站信息失败:', error);
}
};
query();

View File

@@ -136,7 +136,7 @@ import {updateCmsDomain} from '@/api/cms/cmsDomain';
import {updateTenant} from "@/api/system/tenant";
import {getPageTitle, push} from "@/utils/common";
import router from "@/router";
import {getSiteInfo} from "@/api/layout";
import { useSiteStore } from '@/store/modules/site';
import useFormData from "@/utils/use-form-data";
import type {User} from "@/api/system/user/model";
@@ -146,6 +146,7 @@ const useForm = Form.useForm;
// 是否开启响应式布局
const themeStore = useThemeStore();
const {styleResponsive} = storeToRefs(themeStore);
const siteStore = useSiteStore();
const emit = defineEmits<{
(e: 'done'): void;
@@ -349,19 +350,23 @@ const save = () => {
};
const reload = async () => {
const data = await getSiteInfo()
if (data) {
console.log(data)
assignFields({
...data
});
images.value.push(
{
uid: uuid(),
url: data.websiteLogo,
status: 'done'
try {
const data = await siteStore.fetchSiteInfo();
if (data) {
console.log(data);
assignFields({
...data
});
if (data.websiteLogo) {
images.value.push({
uid: uuid(),
url: data.websiteLogo,
status: 'done'
});
}
)
}
} catch (error) {
console.error('获取网站信息失败:', error);
}
}

View File

@@ -0,0 +1,263 @@
<template>
<div class="store-test-page">
<a-card title="状态管理测试页面" :bordered="false">
<a-space direction="vertical" style="width: 100%">
<!-- 网站信息测试 -->
<a-card title="网站信息 Store 测试" size="small">
<a-spin :spinning="siteLoading">
<a-descriptions :column="2" size="small">
<a-descriptions-item label="网站名称">
{{ websiteName || '暂无数据' }}
</a-descriptions-item>
<a-descriptions-item label="网站Logo">
<img v-if="websiteLogo" :src="websiteLogo" alt="logo" style="width: 50px; height: 50px;" />
<span v-else>暂无Logo</span>
</a-descriptions-item>
<a-descriptions-item label="网站描述">
{{ websiteComments || '暂无描述' }}
</a-descriptions-item>
<a-descriptions-item label="运行天数">
{{ runDays }}
</a-descriptions-item>
<a-descriptions-item label="网站域名">
{{ websiteDomain || '暂无域名' }}
</a-descriptions-item>
<a-descriptions-item label="网站ID">
{{ websiteId || '暂无ID' }}
</a-descriptions-item>
</a-descriptions>
<a-space style="margin-top: 16px">
<a-button @click="refreshSiteInfo" :loading="siteLoading">
刷新网站信息
</a-button>
<a-button @click="clearSiteCache">
清除网站缓存
</a-button>
</a-space>
</a-spin>
</a-card>
<!-- 统计数据测试 -->
<a-card title="统计数据 Store 测试" size="small">
<a-spin :spinning="statisticsLoading">
<a-row :gutter="16">
<a-col :span="6">
<a-statistic
title="用户总数"
:value="userCount"
:value-style="{ color: '#3f8600' }"
/>
</a-col>
<a-col :span="6">
<a-statistic
title="订单总数"
:value="orderCount"
:value-style="{ color: '#1890ff' }"
/>
</a-col>
<a-col :span="6">
<a-statistic
title="总销售额"
:value="totalSales"
:value-style="{ color: '#cf1322' }"
/>
</a-col>
<a-col :span="6">
<a-statistic
title="今日销售额"
:value="todaySales"
:value-style="{ color: '#722ed1' }"
/>
</a-col>
</a-row>
<a-space style="margin-top: 16px">
<a-button @click="refreshStatistics" :loading="statisticsLoading">
刷新统计数据
</a-button>
<a-button @click="clearStatisticsCache">
清除统计缓存
</a-button>
<a-button
@click="toggleAutoRefresh"
:type="autoRefreshEnabled ? 'primary' : 'default'"
>
{{ autoRefreshEnabled ? '停止自动刷新' : '开始自动刷新' }}
</a-button>
</a-space>
</a-spin>
</a-card>
<!-- 缓存状态信息 -->
<a-card title="缓存状态信息" size="small">
<a-descriptions :column="2" size="small">
<a-descriptions-item label="网站信息缓存有效">
<a-tag :color="siteStore.isCacheValid ? 'green' : 'red'">
{{ siteStore.isCacheValid ? '有效' : '无效' }}
</a-tag>
</a-descriptions-item>
<a-descriptions-item label="统计数据缓存有效">
<a-tag :color="statisticsStore.isCacheValid ? 'green' : 'red'">
{{ statisticsStore.isCacheValid ? '有效' : '无效' }}
</a-tag>
</a-descriptions-item>
<a-descriptions-item label="网站信息最后更新">
{{ siteStore.lastUpdateTime ? new Date(siteStore.lastUpdateTime).toLocaleString() : '从未更新' }}
</a-descriptions-item>
<a-descriptions-item label="统计数据最后更新">
{{ statisticsStore.lastUpdateTime ? new Date(statisticsStore.lastUpdateTime).toLocaleString() : '从未更新' }}
</a-descriptions-item>
</a-descriptions>
</a-card>
<!-- 操作日志 -->
<a-card title="操作日志" size="small">
<a-list
:data-source="logs"
size="small"
:pagination="{ pageSize: 5 }"
>
<template #renderItem="{ item }">
<a-list-item>
<a-list-item-meta>
<template #title>
<span>{{ item.action }}</span>
<a-tag size="small" style="margin-left: 8px">
{{ item.timestamp }}
</a-tag>
</template>
<template #description>
{{ item.result }}
</template>
</a-list-item-meta>
</a-list-item>
</template>
</a-list>
</a-card>
</a-space>
</a-card>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { useSiteData } from '@/composables/useSiteData';
import { useSiteStore } from '@/store/modules/site';
import { useStatisticsStore } from '@/store/modules/statistics';
// 使用组合式函数
const {
websiteName,
websiteLogo,
websiteComments,
websiteDomain,
websiteId,
runDays,
userCount,
orderCount,
totalSales,
todaySales,
siteLoading,
statisticsLoading,
fetchSiteInfo,
fetchStatistics,
clearCache
} = useSiteData();
// 直接使用 store用于访问更多详细信息
const siteStore = useSiteStore();
const statisticsStore = useStatisticsStore();
// 本地状态
const autoRefreshEnabled = ref(false);
const logs = ref<Array<{ action: string; timestamp: string; result: string }>>([]);
// 添加日志
const addLog = (action: string, result: string) => {
logs.value.unshift({
action,
timestamp: new Date().toLocaleTimeString(),
result
});
// 只保留最近20条日志
if (logs.value.length > 20) {
logs.value = logs.value.slice(0, 20);
}
};
// 刷新网站信息
const refreshSiteInfo = async () => {
try {
await fetchSiteInfo(true);
addLog('刷新网站信息', '成功');
} catch (error) {
addLog('刷新网站信息', `失败: ${error}`);
}
};
// 刷新统计数据
const refreshStatistics = async () => {
try {
await fetchStatistics(true);
addLog('刷新统计数据', '成功');
} catch (error) {
addLog('刷新统计数据', `失败: ${error}`);
}
};
// 清除网站缓存
const clearSiteCache = () => {
siteStore.clearCache();
addLog('清除网站缓存', '成功');
};
// 清除统计缓存
const clearStatisticsCache = () => {
statisticsStore.clearCache();
addLog('清除统计缓存', '成功');
};
// 切换自动刷新
const toggleAutoRefresh = () => {
if (autoRefreshEnabled.value) {
statisticsStore.stopAutoRefresh();
autoRefreshEnabled.value = false;
addLog('停止自动刷新', '成功');
} else {
statisticsStore.startAutoRefresh(10000); // 10秒间隔用于测试
autoRefreshEnabled.value = true;
addLog('开始自动刷新', '10秒间隔');
}
};
onMounted(async () => {
addLog('页面加载', '开始初始化');
try {
await Promise.all([
fetchSiteInfo(),
fetchStatistics()
]);
addLog('初始化数据', '成功');
} catch (error) {
addLog('初始化数据', `失败: ${error}`);
}
});
onUnmounted(() => {
// 清理自动刷新
if (autoRefreshEnabled.value) {
statisticsStore.stopAutoRefresh();
}
addLog('页面卸载', '清理完成');
});
</script>
<style scoped>
.store-test-page {
padding: 20px;
}
</style>