Files
mp-vue/src/views/shop/dashboard/index.vue
赵忠林 db143a73d6 feat(cms): 新增网站密钥和字段加密功能- 在 CMS 网站模型中新增 websiteSecret 字段用于存储小程序密钥
- 为 CMS 网站字段添加 encrypted 字段以支持内容加密- 实现字段值的加密和解密功能,提升数据安全性- 更新网站编辑组件以支持密钥的输入和存储- 调整字段编辑组件,增加加密开关和类型选项
-优化字段列表展示逻辑,支持加密字段的特殊处理- 修改字段值类型为 any以适应多种数据格式
- 完善字段编辑表单验证规则和保存逻辑
- 更新相关组件的类型定义和事件处理- 调整界面布局和交互细节,提升用户体验
2025-09-30 17:25:23 +08:00

298 lines
8.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<a-page-header :show-back="false">
<a-row :gutter="16">
<!-- 应用基本信息卡片 -->
<a-col :span="24" style="margin-bottom: 16px">
<a-card title="概况" :bordered="false">
<a-row :gutter="16">
<a-col :span="6">
<a-image
:width="80"
:height="80"
:preview="false"
style="border-radius: 8px"
:src="siteStore.logo"
fallback="/logo.png"
/>
</a-col>
<a-col :span="14">
<div class="system-info">
<h2 class="ele-text-heading cursor-pointer" @click="$router.push('/website/index')">{{ siteStore.appName }}</h2>
<p class="ele-text-secondary">{{ siteStore.description }}</p>
<a-space>
<a-tag color="green">{{ siteStore.statusText }}</a-tag>
<a-tag color="blue">{{ siteStore.version }}</a-tag>
<a-popover title="小程序码">
<template #content>
<p><img :src="siteStore.mpQrCode" 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" @click="openNew(`https://websoft.top/order/3429.html`)">网宿软件</span>
</a-descriptions-item>
</a-descriptions>
</a-card>
</a-col>
<!-- 快捷操作 -->
<a-col :span="12">
<a-card title="快捷操作" :bordered="false" style="min-height: 353px">
<a-space direction="vertical" style="width: 100%">
<a-button type="primary" block @click="$router.push('/website/field')" :loading="loading">
<UngroupOutlined/>
参数配置
</a-button>
<a-button block @click="$router.push('/shopOrder')">
<CalendarOutlined/>
订单管理
</a-button>
<a-button block @click="$router.push('/system/user')">
<UserOutlined/>
用户管理
</a-button>
<a-button block @click="$router.push('/website/index')">
<ShopOutlined/>
站点管理
</a-button>
<!-- <a-button block @click="refreshStatistics" :loading="loading">-->
<!-- <ReloadOutlined/>-->
<!-- 刷新统计-->
<!-- </a-button>-->
<a-button block @click="$router.push('/system/login-record')">
<FileTextOutlined/>
登录日志
</a-button>
<a-button block @click="clearSiteInfoCache">
<ClearOutlined/>
清除缓存
</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 {
UserOutlined,
CalendarOutlined,
QrcodeOutlined,
ShopOutlined,
ClockCircleOutlined,
SettingOutlined,
AccountBookOutlined,
FileTextOutlined,
ClearOutlined,
UngroupOutlined,
MoneyCollectOutlined,
ReloadOutlined
} from '@ant-design/icons-vue';
import {message} from 'ant-design-vue/es';
import {openNew} from "@/utils/common";
import {useSiteStore} from '@/store/modules/site';
import {useStatisticsStore} from '@/store/modules/statistics';
import {storeToRefs} from 'pinia';
import {removeSiteInfoCache} from "@/api/cms/cmsWebsite";
// 使用状态管理
const siteStore = useSiteStore();
const statisticsStore = useStatisticsStore();
// 从 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 runDays = computed(() => siteStore.runDays);
const userCount = computed(() => statisticsStore.userCount);
const orderCount = computed(() => statisticsStore.orderCount);
const totalSales = computed(() => statisticsStore.totalSales);
// 加载状态
const loading = computed(() => siteLoading.value || statisticsLoading.value);
// 清除缓存
const clearSiteInfoCache = () => {
removeSiteInfoCache('SiteInfo:' + localStorage.getItem('TenantId')).then(
(msg) => {
if (msg) {
message.success(msg);
}
}
);
};
// 刷新统计数据
const refreshStatistics = async () => {
try {
await statisticsStore.forceRefresh();
message.success('统计数据刷新成功');
} catch (error) {
console.error('刷新统计数据失败:', error);
message.error('刷新统计数据失败');
}
};
onMounted(async () => {
// 加载网站信息和统计数据
try {
await Promise.all([
siteStore.fetchSiteInfo(),
statisticsStore.fetchStatistics()
]);
// 开始自动刷新统计数据每5分钟
statisticsStore.startAutoRefresh();
} catch (error) {
console.error('加载数据失败:', error);
}
});
onUnmounted(() => {
// 组件卸载时停止自动刷新
statisticsStore.stopAutoRefresh();
});
</script>
<style scoped>
.system-info h2 {
margin-bottom: 8px;
}
.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>