| | |
| | | <script lang="ts" setup> |
| | | import type { AnalysisOverviewItem } from '@vben/common-ui'; |
| | | import type { TabOption } from '@vben/types'; |
| | | import { computed, onMounted, ref } from 'vue'; |
| | | import { useRouter } from 'vue-router'; |
| | | |
| | | import { |
| | | AnalysisChartCard, |
| | | AnalysisChartsTabs, |
| | | AnalysisOverview, |
| | | } from '@vben/common-ui'; |
| | | import { |
| | | SvgBellIcon, |
| | | SvgCakeIcon, |
| | | SvgCardIcon, |
| | | SvgDownloadIcon, |
| | | } from '@vben/icons'; |
| | | import { Page } from '@vben/common-ui'; |
| | | |
| | | import AnalyticsTrends from './analytics-trends.vue'; |
| | | import AnalyticsVisitsData from './analytics-visits-data.vue'; |
| | | import AnalyticsVisitsSales from './analytics-visits-sales.vue'; |
| | | import AnalyticsVisitsSource from './analytics-visits-source.vue'; |
| | | import AnalyticsVisits from './analytics-visits.vue'; |
| | | import { Card, Col, Row } from 'ant-design-vue'; |
| | | |
| | | const overviewItems: AnalysisOverviewItem[] = [ |
| | | { |
| | | icon: SvgCardIcon, |
| | | title: '用户量', |
| | | totalTitle: '总用户量', |
| | | totalValue: 120_000, |
| | | value: 2000, |
| | | }, |
| | | { |
| | | icon: SvgCakeIcon, |
| | | title: '访问量', |
| | | totalTitle: '总访问量', |
| | | totalValue: 500_000, |
| | | value: 20_000, |
| | | }, |
| | | { |
| | | icon: SvgDownloadIcon, |
| | | title: '下载量', |
| | | totalTitle: '总下载量', |
| | | totalValue: 120_000, |
| | | value: 8000, |
| | | }, |
| | | { |
| | | icon: SvgBellIcon, |
| | | title: '使用量', |
| | | totalTitle: '总使用量', |
| | | totalValue: 50_000, |
| | | value: 5000, |
| | | }, |
| | | ]; |
| | | import { getHomeSummary } from '#/api/mes/home'; |
| | | |
| | | const chartTabs: TabOption[] = [ |
| | | { |
| | | label: '流量趋势', |
| | | value: 'trends', |
| | | }, |
| | | { |
| | | label: '月访问量', |
| | | value: 'visits', |
| | | }, |
| | | ]; |
| | | import { defaultSummary } from './data'; |
| | | import AlertPanel from './modules/alert-panel.vue'; |
| | | import BizCards from './modules/biz-cards.vue'; |
| | | import KpiCards from './modules/kpi-cards.vue'; |
| | | import ProductionTrend from './modules/production-trend.vue'; |
| | | import QuickActions from './modules/quick-actions.vue'; |
| | | |
| | | defineOptions({ name: 'DashboardAnalytics' }); |
| | | |
| | | const router = useRouter(); |
| | | const summary = ref(defaultSummary); |
| | | |
| | | const greeting = computed(() => { |
| | | const hour = new Date().getHours(); |
| | | if (hour < 6) return '夜深了'; |
| | | if (hour < 9) return '早上好'; |
| | | if (hour < 12) return '上午好'; |
| | | if (hour < 14) return '中午好'; |
| | | if (hour < 18) return '下午好'; |
| | | return '晚上好'; |
| | | }); |
| | | |
| | | const today = computed(() => { |
| | | const d = new Date(); |
| | | const weekNames = ['日', '一', '二', '三', '四', '五', '六']; |
| | | return `${d.getFullYear()}年${d.getMonth() + 1}月${d.getDate()}日 星期${weekNames[d.getDay()]}`; |
| | | }); |
| | | |
| | | function handleNavigate(name: string) { |
| | | router.push({ name }); |
| | | } |
| | | |
| | | async function loadSummary() { |
| | | summary.value = await getHomeSummary(); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | loadSummary(); |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="p-5"> |
| | | <AnalysisOverview :items="overviewItems" /> |
| | | <AnalysisChartsTabs :tabs="chartTabs" class="mt-5"> |
| | | <template #trends> |
| | | <AnalyticsTrends /> |
| | | </template> |
| | | <template #visits> |
| | | <AnalyticsVisits /> |
| | | </template> |
| | | </AnalysisChartsTabs> |
| | | |
| | | <div class="mt-5 w-full md:flex"> |
| | | <AnalysisChartCard class="mt-5 md:mt-0 md:mr-4 md:w-1/3" title="访问数量"> |
| | | <AnalyticsVisitsData /> |
| | | </AnalysisChartCard> |
| | | <AnalysisChartCard class="mt-5 md:mt-0 md:mr-4 md:w-1/3" title="访问来源"> |
| | | <AnalyticsVisitsSource /> |
| | | </AnalysisChartCard> |
| | | <AnalysisChartCard class="mt-5 md:mt-0 md:w-1/3" title="访问来源"> |
| | | <AnalyticsVisitsSales /> |
| | | </AnalysisChartCard> |
| | | <Page auto-content-height> |
| | | <!-- 欢迎栏 --> |
| | | <div class="glass-card mb-6 flex items-center justify-between rounded-2xl p-6"> |
| | | <div> |
| | | <h1 class="bg-gradient-to-r from-blue-600 via-purple-600 to-pink-500 bg-clip-text text-2xl font-bold text-transparent dark:from-blue-400 dark:via-purple-400 dark:to-pink-400"> |
| | | {{ greeting }},欢迎回来 |
| | | </h1> |
| | | <p class="mt-1 text-sm text-gray-500 dark:text-gray-400">{{ today }}</p> |
| | | </div> |
| | | <div class="hidden items-center gap-2 sm:flex"> |
| | | <div class="flex items-center gap-1.5 rounded-full bg-emerald-50 px-3 py-1.5 text-xs font-medium text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-400"> |
| | | <span class="relative flex size-2"> |
| | | <span class="absolute inline-flex size-full animate-ping rounded-full bg-emerald-400 opacity-75" /> |
| | | <span class="relative inline-flex size-2 rounded-full bg-emerald-500" /> |
| | | </span> |
| | | 系统运行中 |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- MES 生产 KPI --> |
| | | <KpiCards :summary="summary" @navigate="handleNavigate" /> |
| | | |
| | | <!-- ERP/WMS/BPM 经营 KPI --> |
| | | <BizCards @navigate="handleNavigate" /> |
| | | |
| | | <!-- 生产趋势 + 预警面板 --> |
| | | <Row :gutter="16" class="mb-4"> |
| | | <Col :lg="14" :md="24" :sm="24" :xl="14" :xs="24" class="mb-4"> |
| | | <div class="glass-card rounded-2xl p-5"> |
| | | <h3 class="mb-4 text-base font-semibold text-gray-800 dark:text-gray-100"> |
| | | 生产趋势(近7天) |
| | | </h3> |
| | | <ProductionTrend /> |
| | | </div> |
| | | </Col> |
| | | <Col :lg="10" :md="24" :sm="24" :xl="10" :xs="24" class="mb-4"> |
| | | <AlertPanel |
| | | :andon-active-count="summary.andonActiveCount" |
| | | :repair-active-count="summary.repairActiveCount" |
| | | @navigate="handleNavigate" |
| | | /> |
| | | </Col> |
| | | </Row> |
| | | |
| | | <!-- 快捷操作 --> |
| | | <Row :gutter="16" class="mb-4"> |
| | | <Col :span="24"> |
| | | <QuickActions @navigate="handleNavigate" /> |
| | | </Col> |
| | | </Row> |
| | | </Page> |
| | | </template> |
| | | |
| | | <style scoped> |
| | | .glass-card { |
| | | background: linear-gradient(135deg, rgba(255,255,255,0.8), rgba(255,255,255,0.5)); |
| | | backdrop-filter: blur(20px); |
| | | -webkit-backdrop-filter: blur(20px); |
| | | border: 1px solid rgba(255,255,255,0.6); |
| | | box-shadow: |
| | | 0 8px 32px rgba(0,0,0,0.04), |
| | | 0 2px 8px rgba(0,0,0,0.02), |
| | | inset 0 1px 0 rgba(255,255,255,0.8); |
| | | } |
| | | |
| | | .dark .glass-card { |
| | | background: linear-gradient(135deg, rgba(30,30,50,0.7), rgba(20,20,40,0.5)); |
| | | border: 1px solid rgba(255,255,255,0.08); |
| | | box-shadow: |
| | | 0 8px 32px rgba(0,0,0,0.3), |
| | | 0 2px 8px rgba(0,0,0,0.2), |
| | | inset 0 1px 0 rgba(255,255,255,0.05); |
| | | } |
| | | </style> |