6c50ffa58b
- 将网页标题由“企业商城”修改为“小程序商城” - 修改仪表盘技术支持项显示名称为“企业官网” - 更新登录页默认配置中站点名称为“小程序商城”
340 lines
10 KiB
Vue
340 lines
10 KiB
Vue
<template>
|
|
<a-page-header :show-back="false">
|
|
<a-row :gutter="16">
|
|
<!-- 应用基本信息卡片 -->
|
|
<a-col :span="24" style="margin-bottom: 16px">
|
|
<a-card :bordered="false">
|
|
<template #title>
|
|
<a-space>
|
|
<span>概况</span>
|
|
<a-divider type="vertical" />
|
|
<div class="order-notify-bar">
|
|
<span class="order-notify-label">新订单提醒</span>
|
|
<a-switch v-model:checked="notifyEnabled" @change="onNotifyToggle" size="small" />
|
|
<a-tooltip title="开启后每60秒自动检测新订单,检测到后播放叮声并语音播报">
|
|
<InfoCircleOutlined class="order-notify-icon" />
|
|
</a-tooltip>
|
|
<a-button size="small" :disabled="!notifyEnabled" @click="onTestNotify">测试</a-button>
|
|
</div>
|
|
</a-space>
|
|
</template>
|
|
<a-row :gutter="16">
|
|
<a-col :span="6">
|
|
<a-image
|
|
:width="80"
|
|
:height="80"
|
|
:preview="false"
|
|
style="border-radius: 8px"
|
|
:src="siteStore.websiteLogo"
|
|
fallback="/logo.png"
|
|
/>
|
|
</a-col>
|
|
<a-col :span="14">
|
|
<div class="system-info">
|
|
<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="siteStore.websiteDarkLogo"
|
|
alt="小程序码"
|
|
width="300"
|
|
height="300"
|
|
/></p>
|
|
</template>
|
|
<a-tag>
|
|
<QrcodeOutlined />
|
|
</a-tag>
|
|
</a-popover>
|
|
</a-space>
|
|
</div>
|
|
</a-col>
|
|
<a-col :span="3">
|
|
<div class="flex justify-center items-center h-full w-full">
|
|
</div>
|
|
</a-col>
|
|
</a-row>
|
|
</a-card>
|
|
</a-col>
|
|
|
|
<!-- 统计数据卡片 -->
|
|
<a-col :span="6">
|
|
<a-card :bordered="false" class="stat-card">
|
|
<a-statistic
|
|
title="用户总数"
|
|
:value="userCount"
|
|
:value-style="{ color: '#3f8600' }"
|
|
:loading="loading"
|
|
>
|
|
<template #prefix>
|
|
<UserOutlined />
|
|
</template>
|
|
</a-statistic>
|
|
</a-card>
|
|
</a-col>
|
|
|
|
<a-col :span="6">
|
|
<a-card :bordered="false" class="stat-card">
|
|
<a-statistic
|
|
title="订单总数"
|
|
:value="orderCount"
|
|
:value-style="{ color: '#1890ff' }"
|
|
:loading="loading"
|
|
>
|
|
<template #prefix>
|
|
<AccountBookOutlined />
|
|
</template>
|
|
</a-statistic>
|
|
</a-card>
|
|
</a-col>
|
|
|
|
<a-col :span="6">
|
|
<a-card :bordered="false" class="stat-card">
|
|
<a-statistic
|
|
title="总营业额"
|
|
:value="totalSales"
|
|
:value-style="{ color: '#cf1322' }"
|
|
:loading="loading"
|
|
>
|
|
<template #prefix>
|
|
<MoneyCollectOutlined />
|
|
</template>
|
|
</a-statistic>
|
|
</a-card>
|
|
</a-col>
|
|
|
|
<a-col :span="6">
|
|
<a-card :bordered="false" class="stat-card">
|
|
<a-statistic
|
|
title="系统运行天数"
|
|
:value="runDays"
|
|
suffix="天"
|
|
:value-style="{ color: '#722ed1' }"
|
|
:loading="loading"
|
|
>
|
|
<template #prefix>
|
|
<ClockCircleOutlined />
|
|
</template>
|
|
</a-statistic>
|
|
</a-card>
|
|
</a-col>
|
|
|
|
<!-- 系统基本信息 -->
|
|
<a-col :span="12">
|
|
<a-card title="基本信息" :bordered="false">
|
|
<a-descriptions :column="1" size="small">
|
|
<a-descriptions-item label="系统名称">
|
|
{{ systemInfo.name }}
|
|
</a-descriptions-item>
|
|
<a-descriptions-item label="版本号">
|
|
{{ systemInfo.version }}
|
|
</a-descriptions-item>
|
|
<a-descriptions-item label="部署环境">
|
|
{{ systemInfo.environment }}
|
|
</a-descriptions-item>
|
|
<a-descriptions-item label="数据库">
|
|
{{ systemInfo.database }}
|
|
</a-descriptions-item>
|
|
<a-descriptions-item label="服务器">
|
|
{{ systemInfo.server }}
|
|
</a-descriptions-item>
|
|
<a-descriptions-item label="创建时间">
|
|
{{ siteInfo?.createTime }}
|
|
</a-descriptions-item>
|
|
<a-descriptions-item label="到期时间">
|
|
{{ siteInfo?.expirationTime }}
|
|
</a-descriptions-item>
|
|
<a-descriptions-item label="技术支持">
|
|
<span
|
|
class="cursor-pointer"
|
|
>企业官网</span
|
|
>
|
|
</a-descriptions-item>
|
|
</a-descriptions>
|
|
</a-card>
|
|
</a-col>
|
|
|
|
<!-- 快捷操作 -->
|
|
<a-col :span="12">
|
|
<a-card title="快捷操作" :bordered="false">
|
|
<a-space direction="vertical" style="width: 100%">
|
|
<a-button
|
|
type="primary"
|
|
block
|
|
@click="$router.push('/website/index')"
|
|
>
|
|
<ShopOutlined />
|
|
站点管理
|
|
</a-button>
|
|
<a-button block @click="$router.push('/website/order')">
|
|
<CalendarOutlined />
|
|
订单管理
|
|
</a-button>
|
|
<a-button block @click="$router.push('/system/user')">
|
|
<UserOutlined />
|
|
用户管理
|
|
</a-button>
|
|
<a-button block @click="$router.push('/system/login-record')">
|
|
<FileTextOutlined />
|
|
系统日志
|
|
</a-button>
|
|
<a-button block @click="$router.push('/system/setting')">
|
|
<SettingOutlined />
|
|
系统设置
|
|
</a-button>
|
|
</a-space>
|
|
</a-card>
|
|
</a-col>
|
|
</a-row>
|
|
</a-page-header>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { ref, onMounted, onUnmounted, computed } from 'vue';
|
|
import { useOrderNotify } from '@/views/shop/shopOrder/useOrderNotify';
|
|
import {
|
|
UserOutlined,
|
|
CalendarOutlined,
|
|
QrcodeOutlined,
|
|
ShopOutlined,
|
|
ClockCircleOutlined,
|
|
SettingOutlined,
|
|
AccountBookOutlined,
|
|
FileTextOutlined,
|
|
MoneyCollectOutlined,
|
|
InfoCircleOutlined
|
|
} from '@ant-design/icons-vue';
|
|
import { openNew } from '@/utils/common';
|
|
import { useSiteStore } from '@/store/modules/site';
|
|
import { useStatisticsStore } from '@/store/modules/statistics';
|
|
import { useUserStore } from '@/store/modules/user';
|
|
import { getTenantInfo } from '@/api/layout';
|
|
import { storeToRefs } from 'pinia';
|
|
|
|
// 使用状态管理
|
|
const siteStore = useSiteStore();
|
|
const statisticsStore = useStatisticsStore();
|
|
const userStore = useUserStore();
|
|
|
|
// 从 store 中获取响应式数据
|
|
const { siteInfo, loading: siteLoading } = storeToRefs(siteStore);
|
|
const { loading: statisticsLoading } = storeToRefs(statisticsStore);
|
|
|
|
// 系统信息
|
|
const systemInfo = ref({
|
|
name: '小程序商城',
|
|
description:
|
|
'基于Spring、SpringBoot、SpringMVC等技术栈构建的前后端分离开发平台',
|
|
version: '2.0.0',
|
|
status: '运行中',
|
|
logo: '/logo.png',
|
|
environment: '生产环境',
|
|
database: 'MySQL 8.0',
|
|
server: 'Linux CentOS 7.9',
|
|
expirationTime: '2024-01-01 09:00:00'
|
|
});
|
|
|
|
// 计算属性
|
|
const now = ref(Date.now());
|
|
const tenantCreateTime = ref<string>('');
|
|
let runDaysTimer: ReturnType<typeof setInterval>;
|
|
const runDays = computed(() => {
|
|
if (!tenantCreateTime.value) return 0;
|
|
return Math.floor((now.value - new Date(tenantCreateTime.value).getTime()) / (24 * 60 * 60 * 1000));
|
|
});
|
|
const userCount = computed(() => statisticsStore.userCount);
|
|
const orderCount = computed(() => statisticsStore.orderCount);
|
|
const totalSales = computed(() => statisticsStore.totalSales);
|
|
|
|
// 加载状态
|
|
const loading = computed(() => siteLoading.value || statisticsLoading.value);
|
|
|
|
// 加载数据
|
|
const loadData = async () => {
|
|
// 独立请求租户信息,不受其他请求失败影响
|
|
getTenantInfo()
|
|
.then((res) => {
|
|
tenantCreateTime.value = res?.createTime || '';
|
|
})
|
|
.catch((e) => {
|
|
console.warn('获取租户信息失败:', e);
|
|
});
|
|
|
|
try {
|
|
await Promise.all([
|
|
siteStore.fetchSiteInfo(),
|
|
statisticsStore.fetchStatistics()
|
|
]);
|
|
} catch (error) {
|
|
console.error('加载数据失败:', error);
|
|
}
|
|
};
|
|
|
|
// 新订单声音提醒
|
|
const { enabled: notifyEnabled, toggle: onNotifyToggle, testNotify: onTestNotify } = useOrderNotify({
|
|
onNewOrder: () => loadData()
|
|
});
|
|
|
|
onMounted(async () => {
|
|
await loadData();
|
|
// 开始自动刷新统计数据(每5分钟)
|
|
statisticsStore.startAutoRefresh();
|
|
// 运行天数每小时检查一次(跨天自动更新)
|
|
runDaysTimer = setInterval(() => { now.value = Date.now(); }, 60 * 60 * 1000);
|
|
});
|
|
|
|
onUnmounted(() => {
|
|
// 组件卸载时停止自动刷新
|
|
statisticsStore.stopAutoRefresh();
|
|
clearInterval(runDaysTimer);
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
.system-info h2 {
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
/* 新订单提醒栏(概况卡片标题中) */
|
|
.order-notify-bar {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 2px 12px;
|
|
background: #f0fdf4;
|
|
border: 1px solid #bbf7d0;
|
|
border-radius: 6px;
|
|
}
|
|
.order-notify-label {
|
|
font-size: 13px;
|
|
color: #166534;
|
|
white-space: nowrap;
|
|
}
|
|
.order-notify-icon {
|
|
color: #16a34a;
|
|
font-size: 14px;
|
|
cursor: help;
|
|
}
|
|
|
|
.stat-card {
|
|
text-align: center;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.stat-card :deep(.ant-statistic-title) {
|
|
font-size: 14px;
|
|
color: #666;
|
|
}
|
|
|
|
.stat-card :deep(.ant-statistic-content) {
|
|
font-size: 24px;
|
|
font-weight: 600;
|
|
}
|
|
</style>
|