合并代码

This commit is contained in:
shaoleiliu-netizen123 2026-08-04 11:40:39 +08:00
parent 423facda3c
commit c44622cad6
2 changed files with 285 additions and 555 deletions

View File

@ -50,32 +50,26 @@ const routes: RouteRecordRaw[] = [
meta: { title: '用户管理', icon: 'PersonOutline' }
},
// 刀具管理(静态路由)
{
path: 'biz/tool',
name: 'BizTool',
component: () => import('@/views/biz/tool/index.vue'),
meta: { title: '刀具管理', icon: 'BuildOutline' }
},
// {
// path: 'biz/tool',
// name: 'BizTool',
// component: () => import('@/views/biz/tool/index.vue'),
// meta: { title: '刀具管理', icon: 'BuildOutline' }
// },
// 刀具生产管理(静态路由,确保稳定访问)
{
path: 'biz/tool/usage',
name: 'BizToolUsage',
component: () => import('@/views/biz/tool/usage/index.vue'),
meta: { title: '刀具生产管理', icon: 'BuildOutline' }
},
{
path: 'biz/toolUsage',
name: 'BizToolUsageAlias',
component: () => import('@/views/biz/tool/usage/index.vue'),
meta: { title: '刀具生产管理', icon: 'BuildOutline' }
},
// NC代码库
{
path: 'biz/ncCode',
name: 'BizNcCode',
component: () => import('@/views/biz/ncCode/index.vue'),
meta: { title: 'NC代码库', icon: 'DocumentOutline' }
},
// {
// path: 'biz/tool/usage',
// name: 'BizToolUsage',
// component: () => import('@/views/biz/tool/usage/index.vue'),
// meta: { title: '刀具生产管理', icon: 'BuildOutline' }
// },
// {
// path: 'biz/toolUsage',
// name: 'BizToolUsageAlias',
// component: () => import('@/views/biz/tool/usage/index.vue'),
// meta: { title: '刀具生产管理', icon: 'BuildOutline' }
// },
{
path: 'system/role',
name: 'SystemRole',

View File

@ -1,337 +1,253 @@
<template>
<div class="page-container">
<!-- 欢迎区域 -->
<div class="welcome-section">
<!-- 左侧欢迎信息 -->
<div class="welcome-info">
<div class="welcome-header">
<n-avatar round :size="56" :src="userStore.avatar || undefined">
{{ userStore.nickname?.charAt(0) || 'U' }}
</n-avatar>
<div class="welcome-text">
<h1 class="welcome-title">
{{ getGreeting() }}{{ userStore.nickname }} 👋
</h1>
<p class="welcome-desc">
这是您的管理控制台您可以在这里管理系统的各项功能
</p>
</div>
</div>
<div class="welcome-time">
<div class="time-display">{{ currentTime }}</div>
<div class="date-display">{{ currentDate }}</div>
</div>
</div>
<!-- 右侧轮播Banner -->
<div class="welcome-banner">
<n-carousel autoplay :interval="5000" dot-type="line" show-arrow="hover" class="banner-carousel">
<div v-for="(banner, index) in banners" :key="index" class="banner-item"
:style="{ background: banner.bgColor }">
<div class="banner-content">
<div class="banner-text">
<h3 class="banner-title">{{ banner.title }}</h3>
<p class="banner-subtitle">{{ banner.subtitle }}</p>
</div>
<div class="banner-icon">
<n-icon :size="64" :color="banner.iconColor">
<component :is="banner.icon"/>
<div style="margin:15px 10px;">
<n-grid x-gap="20">
<n-gi :span="19">
<n-grid x-gap="20">
<n-gi :span="3" style="padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;">
<n-button type="success" style="width: 100%;margin:10px 0 30px;">今天</n-button>
<n-button type="tertiary" style="width: 100%; margin-bottom: 30px;">昨天</n-button>
<n-button type="tertiary" style="width: 100%; margin-bottom: 30px;">近7天</n-button>
<n-button type="tertiary" style="width: 100%; margin-bottom: 20px;">近30天</n-button>
</n-gi>
<n-gi :span="21">
<n-grid x-gap="20">
<n-gi :span="8" style="display: flex;align-items: center;justify-content: space-between;padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;">
<div>
<div style="display: flex;align-items: center;font-size: 20px;color: #1890ff;">
<n-icon size="20">
<BarChartOutline />
</n-icon>
</div>
</div>
</div>
</n-carousel>
</div>
<div style="padding-left: 8px;">工单总数</div>
</div>
<!-- 统计卡片 -->
<div class="stat-cards">
<n-card v-for="stat in stats" :key="stat.title" class="stat-card">
<div class="stat-content">
<div class="stat-icon" :style="{ background: stat.bgColor }">
<n-icon size="24" :color="stat.color">
<component :is="stat.icon"/>
<div style="color: #1890ff;">
<span style="font-size: 36px;font-weight: bold;">890</span>
<span style="padding-left: 5px;"></span>
</div>
<div style="font-size: 12px;">所选时间范围内全部工单</div>
</div>
<div style="padding-left: 20px;border-left:1px solid #e1e0e0;">
<div>已完成</div>
<div style="padding-bottom: 20px;color: #161718;">260</div>
<div>进行中</div>
<div style="color: #161718;">5800</div>
</div>
</n-gi>
<n-gi :span="8" style="display: flex;align-items: center;justify-content: space-between;padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;">
<div>
<div style="display: flex;align-items: center;font-size: 20px;color: #0891b2;">
<n-icon size="20">
<BookmarksOutline />
</n-icon>
</div>
<div class="stat-info">
<n-skeleton v-if="loading" :width="60" :height="28"/>
<div v-else class="stat-value">
{{ stat.value }}{{ stat.unit ? ' ' + stat.unit : '' }}
</div>
<div class="stat-title">{{ stat.title }}</div>
<div v-if="stat.subText" class="stat-sub-text">{{ stat.subText }}</div>
</div>
</div>
</n-card>
<div style="padding-left: 8px;">进行中工单</div>
</div>
<!-- 中间区域快捷入口 + 更新日志 -->
<n-grid :x-gap="20" :cols="2" class="middle-section">
<!-- 快捷入口 -->
<n-gi>
<n-card title="快捷入口" class="shortcuts-card">
<div style="color: #0891b2;">
<span style="font-size: 36px;font-weight: bold;">560</span>
<span style="padding-left: 5px;"></span>
</div>
<div style="font-size: 12px;">当前正在执行的工单数里</div>
</div>
<div style="padding-left: 20px;border-left:1px solid #e1e0e0;">
<div>已完成</div>
<div style="padding-bottom: 20px;color: #161718;">260</div>
<div>工单完成率</div>
<div style="color: #161718;">68%</div>
</div>
</n-gi>
<n-gi :span="8" style="display: flex;align-items: center;justify-content: space-between;padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;">
<div>
<div style="display: flex;align-items: center;font-size: 20px;color: #18181b;">
<n-icon size="20">
<CellularSharp />
</n-icon>
<div style="padding-left: 8px;">工单完成率</div>
</div>
<div style="color: #18181b;">
<span style="font-size: 36px;font-weight: bold;">65</span>
<span style="padding-left: 5px;">%</span>
</div>
<div style="font-size: 12px;">按工单数量统计的完成比例</div>
</div>
<div style="padding-left: 20px;border-left:1px solid #e1e0e0;">
<div>已结工单</div>
<div style="padding-bottom: 20px;color: #161718;">260</div>
<div>工单总数</div>
<div style="color: #161718;">5800</div>
</div>
</n-gi>
<n-gi :span="8" style="display: flex;align-items: center;justify-content: space-between;margin-top: 20px;padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;">
<div>
<div style="display: flex;align-items: center;font-size: 20px;color: #15803d;">
<n-icon size="22">
<CubeOutline />
</n-icon>
<div style="padding-left: 8px;">完工数量</div>
</div>
<div style="color: #15803d;">
<span style="font-size: 36px;font-weight: bold;">560</span>
<span style="padding-left: 5px;"></span>
</div>
<div style="font-size: 12px;">所选时间范围内合格完工产量</div>
</div>
<div style="padding-left: 20px;border-left:1px solid #e1e0e0;">
<div>产能达成率</div>
<div style="padding-bottom: 20px;color: #161718;">26%</div>
<div>已结工单</div>
<div style="color: #161718;">46</div>
</div>
</n-gi>
<n-gi :span="8" style="display: flex;align-items: center;justify-content: space-between;margin-top: 20px;padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;">
<div>
<div style="display: flex;align-items: center;font-size: 20px;color: #ea580c;">
<n-icon size="22">
<ReaderOutline />
</n-icon>
<div style="padding-left: 8px;">库存预警</div>
</div>
<div style="color: #ea580c;">
<span style="font-size: 36px;font-weight: bold;">89</span>
<span style="padding-left: 5px;"></span>
</div>
<div style="font-size: 12px;">需关注与处理的库存预警</div>
</div>
<div style="padding-left: 20px;border-left:1px solid #e1e0e0;">
<div>库存周转</div>
<div style="padding-bottom: 20px;color: #161718;">40%</div>
<div>库存总量</div>
<div style="color: #161718;">630</div>
</div>
</n-gi>
<n-gi :span="8" style="display: flex;align-items: center;justify-content: space-between;margin-top: 20px;padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;">
<div>
<div style="display: flex;align-items: center;font-size: 20px;color: #8b8d07;">
<n-icon size="25">
<LayersOutline />
</n-icon>
<div style="padding-left: 8px;">质量概览</div>
</div>
<div style="color: #8b8d07;">
<span style="font-size: 36px;font-weight: bold;">98</span>
<span style="padding-left: 5px;">%</span>
</div>
<div style="font-size: 12px;">所选时间范围内质量表现</div>
</div>
<div style="padding-left: 20px;border-left:1px solid #e1e0e0;">
<div>未关闭异常</div>
<div style="padding-bottom: 20px;color: #161718;">0</div>
<div>累计异常</div>
<div style="color: #161718;">75</div>
</div>
</n-gi>
</n-grid>
</n-gi>
</n-grid>
</n-gi>
<n-gi :span="5" style="padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;">
<div style="display: flex;align-items: center;font-size: 18px;color: #663706;">
<n-icon size="23">
<Contract />
</n-icon>
<div style="padding-left: 5px;">快捷入口</div>
</div>
<div class="shortcuts-grid">
<div
v-for="shortcut in shortcuts"
:key="shortcut.path"
v-for="n in list"
:key="n.path"
class="shortcut-item"
@click="router.push(shortcut.path)"
@click="topage(n.path)"
>
<div class="shortcut-icon" :style="{ background: shortcut.bgColor }">
<n-icon size="24" :color="shortcut.color">
<component :is="shortcut.icon"/>
<div class="shortcut-icon" :style="{ background: n.bgColor }">
<n-icon size="24" :color="n.color">
<component :is="n.icon"/>
</n-icon>
</div>
<div class="shortcut-name">{{ shortcut.name }}</div>
<div class="shortcut-name">{{ n.name }}</div>
</div>
</div>
</n-card>
</n-gi>
<!-- 更新日志 -->
<n-gi>
<n-card title="更新日志" class="changelog-card">
<n-timeline>
<n-timeline-item
v-for="log in changelog"
:key="log.version"
:type="log.type"
:title="log.version"
:time="log.date"
>
<ul class="changelog-list">
<li v-for="(item, idx) in log.changes" :key="idx">{{ item }}</li>
</ul>
</n-timeline-item>
</n-timeline>
</n-card>
</n-gi>
</n-grid>
<n-grid style="margin-top: 20px;">
<n-gi :span="24" style="padding:10px;border-radius: 10px;box-shadow: 0 0 20px -5px rgba(84, 151, 232, 0.5);background: #fff;">
<div style="display: flex;align-items: center;justify-content: space-between;">
<div style="display: flex;align-items: center;font-size: 18px;color: #056a83;">
<n-icon size="23">
<DiceOutline />
</n-icon>
<div style="padding-left: 5px;">代办事项</div>
</div>
<!-- 底部区域系统信息 + 作者介绍 -->
<n-grid :x-gap="20" :cols="2" class="bottom-section">
<!-- 系统信息 -->
<n-gi>
<n-card title="系统信息" class="system-card">
<n-descriptions :column="1" label-placement="left">
<n-descriptions-item label="系统名称">mes Admin</n-descriptions-item>
<n-descriptions-item label="系统版本">v1.0.7</n-descriptions-item>
<n-descriptions-item label="前端框架">Vue 3.4 + Naive UI</n-descriptions-item>
<n-descriptions-item label="后端框架">Spring Boot 3.2</n-descriptions-item>
<n-descriptions-item label="数据库">MySQL 8.0</n-descriptions-item>
<n-descriptions-item label="缓存">Redis 7.0</n-descriptions-item>
</n-descriptions>
</n-card>
</n-gi>
<div style="display: flex;align-items: center;font-size: 14px;color: #4c7c8b;cursor: pointer;">
<!-- 作者介绍 -->
<n-gi>
<n-card title="关于作者" class="author-card">
<div class="author-content">
<div class="author-avatar">
<n-avatar
round
:size="80"
>
</n-avatar>
</div>
<div class="author-info">
<h3 class="author-name">程序员mes</h3>
<p class="author-desc">开源作者全栈开发抖音技术博主专注于后台管理系统的开发与优化</p>
<div class="author-links">
<n-space>
<a href="https://gitee.com/mesfactory/evo-mes" target="_blank" class="author-link">
<n-icon size="16">
<LogoGitlab/>
<div>查看全部</div>
<n-icon size="18">
<ChevronForward />
</n-icon>
<span>Gitee</span>
</a>
<a href="https://mes-coder.cn/" target="_blank" class="author-link">
<n-icon size="16">
<Globe/>
</n-icon>
<span>火星编程导航</span>
</a>
<n-popover trigger="hover" placement="top">
<template #trigger>
<span class="author-link">
<n-icon size="16"><ChatbubbleOutline/></n-icon>
<span>微信</span>
</span>
</template>
<div class="wechat-info">
<n-icon size="16" color="#07C160">
<LogoWechat/>
</n-icon>
<span>mes8377</span>
</div>
</n-popover>
</n-space>
</div>
</div>
</div>
<n-divider/>
<div class="project-info">
<p class="project-desc">
mes Admin 是一个基于 Spring Boot 3 + Vue 3 的现代化后台管理系统
采用最新的技术栈提供完整的权限管理系统监控等功能
</p>
<div class="project-stats">
<div class="project-stat-item">
<n-icon size="18" color="#F59E0B">
<Star/>
</n-icon>
<span>开源免费</span>
</div>
<div class="project-stat-item">
<n-icon size="18" color="#10B981">
<Refresh/>
</n-icon>
<span>持续更新</span>
</div>
<div class="project-stat-item">
<n-icon size="18" color="#3B82F6">
<DocumentText/>
</n-icon>
<span>文档完善</span>
</div>
</div>
</div>
</n-card>
</n-gi>
</n-grid>
</div>
</template>
</template>
<script setup lang="ts">
import {ref, onMounted, onUnmounted, markRaw} from 'vue'
import {ref, markRaw, reactive} from 'vue'
import {useRouter} from 'vue-router'
import {
PersonOutline,
PeopleOutline,
MenuOutline,
ShieldCheckmarkOutline,
LogoGithub,
LogoGitlab,
LogoWechat,
Globe,
Mail,
Star,
Refresh,
DocumentText,
SettingsOutline,
TimerOutline,
ServerOutline,
RocketOutline,
SparklesOutline,
CodeSlashOutline,
CloudOutline,
ChatbubbleOutline
Contract,
BarChartOutline,
BookmarksOutline,
CellularSharp,
CubeOutline,
ReaderOutline,
LayersOutline,
DiceOutline,
ChevronForward,
//MenuOutline,
GitNetworkOutline,
GameControllerOutline,
//ShieldCheckmarkOutline,
ListOutline,
IdCardOutline,
// LogoWechat,
// Globe,
// Mail,
// Star,
// Refresh,
// DocumentText,
// SettingsOutline,
// TimerOutline,
// ServerOutline,
// RocketOutline,
// SparklesOutline,
// CodeSlashOutline,
// CloudOutline,
// ChatbubbleOutline
} from '@vicons/ionicons5'
import {useUserStore} from '@/stores/user'
import {dashboardStatsApi} from '@/api/dashboardStats'
const router = useRouter()
const userStore = useUserStore()
const currentTime = ref('')
const currentDate = ref('')
const loading = ref(true)
//
function getGreeting() {
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 '下午好'
if (hour < 22) return '晚上好'
return '夜深了'
function topage(path:any) {
router.push(path)
}
// Banner
const banners = [
{
title: 'mes Admin',
subtitle: '现代化后台管理系统',
bgColor: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',
icon: markRaw(RocketOutline),
iconColor: 'rgba(255,255,255,0.3)'
},
{
title: '技术栈',
subtitle: 'Spring Boot 3 + Vue 3',
bgColor: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
icon: markRaw(CodeSlashOutline),
iconColor: 'rgba(255,255,255,0.3)'
},
{
title: '开源免费',
subtitle: '持续更新 · 文档完善',
bgColor: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',
icon: markRaw(SparklesOutline),
iconColor: 'rgba(255,255,255,0.3)'
},
{
title: '云端部署',
subtitle: '支持 Docker 一键部署',
bgColor: 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)',
icon: markRaw(CloudOutline),
iconColor: 'rgba(255,255,255,0.3)'
}
]
// - 5
const stats = ref([
{
title: '工单总数',
value: 0,
icon: markRaw(DocumentText),
color: '#2563EB',
bgColor: '#DBEAFE',
unit: '单',
subText: '所有工单统计'
},
{
title: '进行中工单',
value: 0,
icon: markRaw(RocketOutline),
color: '#D97706',
bgColor: '#FEF3C7',
unit: '单',
subText: '正在执行的工单'
},
{
title: '工单完成率',
value: 0,
icon: markRaw(ShieldCheckmarkOutline),
color: '#059669',
bgColor: '#D1FAE5',
unit: '%',
subText: '已完成比例'
},
{
title: '完工数量',
value: 0,
icon: markRaw(Star),
color: '#7C3AED',
bgColor: '#EDE9FE',
unit: '件',
subText: '已完工的产品数'
},
{
title: '产能达成率',
value: 0,
icon: markRaw(SparklesOutline),
color: '#DC2626',
bgColor: '#FEE2E2',
unit: '%',
subText: '实际/计划产量比'
}
])
//
const shortcuts = [
const list:any =ref(
[
{
name: '用户管理',
path: '/system/user',
@ -347,205 +263,31 @@ const shortcuts = [
bgColor: '#D1FAE5'
},
{
name: '菜单管理',
path: '/system/menu',
icon: markRaw(MenuOutline),
name: '部门管理',
path: '/org/dept',
icon: markRaw(GitNetworkOutline),
color: '#2563EB',
bgColor: '#DBEAFE'
},
{
name: '系统配置',
path: '/system/config',
icon: markRaw(SettingsOutline),
name: '岗位管理',
path: '/org/post',
icon: markRaw(IdCardOutline),
color: '#7C3AED',
bgColor: '#EDE9FE'
},
{
name: '定时任务',
path: '/monitor/job',
icon: markRaw(TimerOutline),
name: '操作日志',
path: '/log/operlog',
icon: markRaw(ListOutline),
color: '#DC2626',
bgColor: '#FEE2E2'
},
{
name: '服务监控',
path: '/monitor/server',
icon: markRaw(ServerOutline),
color: '#0891B2',
bgColor: '#CFFAFE'
}
]
//
const changelog = [
{
version: 'v1.0.7',
date: '2026-03-01',
type: 'success' as const,
changes: [
'代码生成:新增表单布局配置,支持「一行两列」和「从上到下」两种布局',
'代码生成:编辑配置弹窗新增「布局配置」标签页',
'代码生成:修复 LocalDate/LocalDateTime 字段 JSON 解析错误',
'代码生成:日期时间字段提交格式与 Jackson 配置yyyy-MM-dd HH:mm:ss兼容',
'代码生成:编辑时日期字符串正确转换为时间戳供日期选择器使用'
]
},
{
version: 'v1.0.6',
date: '2026-03-01',
type: 'success' as const,
changes: [
'系统通知移除短信渠道Webhook 拆分为飞书/钉钉/企业微信分别选择',
'钉钉推送支持加签密钥SEC确保安全校验',
'mes-push 模块重构:支持文本和图片,统一 Webhook 发送逻辑',
'新增通知记录:可查看各渠道推送触达情况及成功/失败状态',
'推送失败支持重试:通知记录中失败渠道可一键重试'
]
},
{
version: 'v1.0.5',
date: '2026-02-28',
type: 'success' as const,
changes: [
'整合 Druid 数据库连接池监控平台',
'定时任务新增 Cron 表达式常用预设选择',
'定时任务新增调度日志查看功能',
'定时任务新增调度统计图表(执行数、成功/失败比例)',
'缓存监控页面新增 ECharts 统计图内存、QPS、命中率、连接数',
'修复通知类型表单校验问题',
'优化统计卡片样式(透明背景)'
]
},
{
version: 'v1.0.4',
date: '2026-02-24',
type: 'success' as const,
changes: [
'新增用户批量导入导出功能EasyExcel',
'导入模板支持角色和岗位字段',
'新增用户多选导出功能',
'新增用户批量删除功能',
'优化文件下载认证处理'
]
},
{
version: 'v1.0.3',
date: '2026-02-24',
type: 'success' as const,
changes: [
'新增前端反调试控制(安全配置开关)',
'优化系统配置页面按钮布局',
'优化弹窗按钮主题色适配',
'新增多种主题颜色选择',
'修复操作日志耗时统计问题'
]
},
{
version: 'v1.0.2',
date: '2026-02-13',
type: 'success' as const,
changes: [
'新增 RustFS 对象存储支持',
'新增腾讯云 COS 存储支持',
'优化存储配置页面布局,访问域名按存储类型分组',
'修复 Office 文档预览样式问题',
'修复 PDF 预览需要登录的问题',
'支持大文件上传(最大 500MB',
'优化文件列表全选效果',
'文件管理新增拖拽上传提示'
]
},
{
version: 'v1.0.1',
date: '2026-01-31',
type: 'success' as const,
changes: [
'新增暗黑主题模式,支持一键切换',
'优化首页布局,新增轮播 Banner',
'新增邮件配置及测试发送功能',
'新增接口加密功能(全局/部分加密)',
'新增 RSA 密钥自动生成功能',
'优化即时聊天页面暗黑模式适配'
]
},
{
version: 'v1.0.0',
date: '2026-01-29',
type: 'info' as const,
changes: [
'新增文件存储策略工厂(本地/MinIO/OSS/COS',
'新增推送服务策略工厂(极光/友盟/个推)',
'新增短信/支付服务策略工厂',
'优化登录页面(三种样式+滑块验证码)',
'完善系统配置分组管理'
]
},
{
version: 'v0.9.0',
date: '2026-01-25',
type: 'info' as const,
changes: [
'新增即时通讯功能WebSocket私聊/群聊)',
'完成字典管理和系统配置功能',
'实现部门和岗位管理',
'完成定时任务管理功能'
]
},
{
version: 'v0.8.0',
date: '2026-01-20',
type: 'default' as const,
changes: [
'搭建项目基础框架',
'集成 Sa-Token 实现认证授权',
'完成基础权限管理(用户、角色、菜单)',
'实现登录日志和操作日志记录',
'添加系统监控功能'
]
}
]
//
async function loadStats() {
try {
loading.value = true
const data = await dashboardStatsApi.getStats()
stats.value[0].value = data.totalOrders
stats.value[1].value = data.inProgressOrders
stats.value[2].value = data.completionRate
stats.value[3].value = data.completedQuantity
stats.value[4].value = data.achievementRate
} catch (error) {
console.error('加载统计数据失败', error)
} finally {
loading.value = false
}
}
//
function updateTime() {
const now = new Date()
currentTime.value = now.toLocaleTimeString('zh-CN', {hour12: false})
currentDate.value = now.toLocaleDateString('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long'
})
}
]
)
let timer: number
onMounted(() => {
updateTime()
timer = window.setInterval(updateTime, 1000)
loadStats()
})
onUnmounted(() => {
clearInterval(timer)
})
</script>
<style lang="scss" scoped>
//
.welcome-section {
@ -686,7 +428,7 @@ onUnmounted(() => {
.stat-cards {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-columns: repeat(4, 1fr);
gap: 20px;
margin-bottom: 20px;
}
@ -725,12 +467,6 @@ onUnmounted(() => {
margin-top: 4px;
}
.stat-sub-text {
font-size: 12px;
color: #9CA3AF;
margin-top: 2px;
}
.middle-section {
margin-bottom: 20px;
}