ys 2 هفته پیش
والد
کامیت
d7e6f1e859

+ 4 - 0
yushu-uivue3/src/assets/icons/svg/workbench.svg

@@ -0,0 +1,4 @@
+<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
+  <path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"/>
+  <path d="M686.7 638.6L544.1 535.5V288c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v275.4c0 2.6 1.2 5 3.3 6.5l165.4 120.6c3.6 2.6 8.6 1.8 11.2-1.7l28.6-39c2.6-3.7 1.8-8.7-1.9-11.2z"/>
+</svg>

+ 0 - 1
yushu-uivue3/src/assets/styles/sidebar.scss

@@ -87,7 +87,6 @@
     }
 
     .svg-icon {
-      margin-right: 12px;
       font-size: 18px;
       vertical-align: -0.3em;
       transition: all 0.3s;

+ 0 - 1
yushu-uivue3/src/components/SvgIcon/index.vue

@@ -39,7 +39,6 @@ export default defineComponent({
 .nav-icon {
   display: inline-block;
   font-size: 15px;
-  margin-right: 12px;
   position: relative;
 }
 

+ 1 - 1
yushu-uivue3/src/router/index.js

@@ -68,7 +68,7 @@ export const constantRoutes = [
         path: '/index',
         component: () => import('@/views/index'),
         name: 'Index',
-        meta: { title: '首页', icon: 'dashboard', affix: true }
+        meta: { title: '工作台', icon: 'workbench', affix: true }
       }
     ]
   },

+ 604 - 273
yushu-uivue3/src/views/index.vue

@@ -1,54 +1,123 @@
 <template>
-  <div class="dashboard-container">
-    <!-- 顶部统计卡片 -->
-    <a-row :gutter="20">
-      <a-col :xs="24" :sm="12" :md="6" v-for="(item, index) in statCards" :key="index">
-        <a-card hoverable class="stat-card-item">
-          <div class="stat-card-content">
-            <div class="stat-icon-wrapper" :style="{ background: item.color }">
-              <component :is="item.icon" :style="{ fontSize: '24px', color: '#fff' }" />
+  <div class="workbench-container">
+    <!-- 顶部问候区域 -->
+    <a-card class="greeting-card">
+      <a-row align="middle" justify="space-between">
+        <a-col>
+          <a-typography-title :level="3" style="margin: 0">
+            {{ greetingText }},{{ userName }}
+          </a-typography-title>
+          <a-typography-text type="secondary">
+            {{ currentDate }} {{ currentWeek }}
+          </a-typography-text>
+        </a-col>
+        <a-col>
+          <a-statistic :value="currentTime" :prefix="h(ClockCircleOutlined)" />
+        </a-col>
+      </a-row>
+    </a-card>
+
+    <!-- 今日概览卡片 -->
+    <a-row :gutter="[16, 16]" style="margin-top: 16px">
+      <a-col :xs="24" :sm="12" :md="6" v-for="(item, index) in todayStats" :key="index">
+        <a-card hoverable @click="item.onClick">
+          <a-statistic
+            :title="item.label"
+            :value="item.value"
+            :prefix="h(item.icon)"
+            :value-style="{ color: item.color }"
+          />
+        </a-card>
+      </a-col>
+    </a-row>
+
+    <!-- 主要内容区域 -->
+    <a-row :gutter="20" class="main-content">
+      <!-- 左侧:今日待办 + 最近消息 -->
+      <a-col :xs="24" :lg="12">
+        <!-- 今日待办 -->
+        <a-card hoverable class="todo-card">
+          <template #title>
+            <div class="card-header">
+              <span><CheckSquareOutlined /> 今日待办</span>
+              <a-button type="link" size="small" @click="goRoute('/system/todo')">查看全部</a-button>
             </div>
-            <div class="stat-info">
-              <div class="stat-label">{{ item.label }}</div>
-              <div class="stat-value">
-                {{ item.value }}
+          </template>
+          <div class="todo-list">
+            <a-empty v-if="todoList.length === 0" description="暂无待办事项" :image="Empty.PRESENTED_IMAGE_SIMPLE" />
+            <div v-else v-for="item in todoList" :key="item.id" class="todo-item" @click="goRoute('/system/todo')">
+              <div class="todo-checkbox">
+                <CheckCircleOutlined v-if="item.status === '1'" class="checked" />
+                <ClockCircleOutlined v-else class="pending" />
               </div>
+              <div class="todo-content">
+                <div class="todo-title">{{ item.title }}</div>
+                <div class="todo-time">
+                  <CalendarOutlined />
+                  <span>{{ item.dueDate }}</span>
+                </div>
+              </div>
+              <a-tag :color="getPriorityColor(item.priority)" size="small">
+                {{ getPriorityText(item.priority) }}
+              </a-tag>
             </div>
           </div>
-          <div class="stat-card-footer">
-            <span>较昨日</span>
-            <span :class="item.trend >= 0 ? 'trend-up' : 'trend-down'">
-              {{ Math.abs(item.trend) }}%
-              <component :is="item.trend >= 0 ? CaretUpOutlined : CaretDownOutlined" />
-            </span>
-          </div>
         </a-card>
-      </a-col>
-    </a-row>
 
-    <!-- 中部图表和快捷入口 -->
-    <a-row :gutter="20" class="mt-20">
-      <a-col :xs="24" :lg="16">
-        <a-card hoverable class="chart-card">
+        <!-- 最近消息 -->
+        <a-card hoverable class="message-card mt-20">
           <template #title>
             <div class="card-header">
-              <span>访问趋势</span>
-              <a-radio-group v-model:value="chartPeriod" size="small">
-                <a-radio-button value="week">本周</a-radio-button>
-                <a-radio-button value="month">本月</a-radio-button>
-              </a-radio-group>
+              <span><MessageOutlined /> 最近消息</span>
+              <a-button type="link" size="small" @click="goRoute('/message')">查看全部</a-button>
             </div>
           </template>
-          <div class="chart-wrapper">
-             <line-chart :chart-data="lineChartData" />
+          <div class="message-list">
+            <a-empty v-if="recentMessages.length === 0" description="暂无消息" :image="Empty.PRESENTED_IMAGE_SIMPLE" />
+            <div v-else v-for="item in recentMessages" :key="item.id" class="message-item" @click="goRoute('/message')">
+              <a-avatar :src="item.avatar" :size="40">{{ item.sender?.charAt(0) }}</a-avatar>
+              <div class="message-content">
+                <div class="message-header">
+                  <span class="message-sender">{{ item.sender }}</span>
+                  <span class="message-time">{{ item.time }}</span>
+                </div>
+                <div class="message-text">{{ item.content }}</div>
+              </div>
+              <a-badge v-if="!item.isRead" dot />
+            </div>
           </div>
         </a-card>
       </a-col>
-      <a-col :xs="24" :lg="8">
-        <a-card hoverable class="quick-entry-card">
+
+      <!-- 右侧:日程安排 + 快捷入口 -->
+      <a-col :xs="24" :lg="12">
+        <!-- 本周日程 -->
+        <a-card hoverable class="schedule-card">
           <template #title>
             <div class="card-header">
-              <span>快捷导航</span>
+              <span><CalendarOutlined /> 本周日程</span>
+              <span class="week-range">{{ weekRange }}</span>
+            </div>
+          </template>
+          <a-timeline class="schedule-timeline">
+            <a-timeline-item v-for="item in scheduleList" :key="item.id" :color="item.color">
+              <div class="schedule-item">
+                <div class="schedule-time">
+                  <ClockCircleOutlined />
+                  <span>{{ item.time }}</span>
+                </div>
+                <div class="schedule-title">{{ item.title }}</div>
+                <div class="schedule-desc">{{ item.description }}</div>
+              </div>
+            </a-timeline-item>
+          </a-timeline>
+        </a-card>
+
+        <!-- 快捷入口 -->
+        <a-card hoverable class="quick-entry-card mt-20">
+          <template #title>
+            <div class="card-header">
+              <span><AppstoreOutlined /> 快捷入口</span>
             </div>
           </template>
           <div class="quick-nav-grid">
@@ -59,177 +128,288 @@
               @click="goRoute(item.path)"
             >
               <div class="nav-icon" :style="{ background: item.bg }">
-                <component :is="item.icon" :style="{ fontSize: '20px', color: item.color }" />
+                <component :is="item.icon" :style="{ fontSize: '24px', color: item.color }" />
               </div>
               <span class="nav-label">{{ item.name }}</span>
             </div>
           </div>
         </a-card>
-        
-        <a-card hoverable class="mt-20 system-info-card">
-          <template #title>
-            <div class="card-header">
-              <span>系统概览</span>
-              <a-tag size="small">v3.9.0</a-tag>
-            </div>
-          </template>
-          <div class="info-list">
-            <div class="info-item">
-              <span class="label">Vue版本</span>
-              <span class="value">3.x</span>
-            </div>
-            <div class="info-item">
-              <span class="label">Ant Design Vue</span>
-              <span class="value">4.x</span>
-            </div>
-            <div class="info-item">
-              <span class="label">Vite</span>
-              <span class="value">5.x</span>
-            </div>
-            <div class="info-item">
-              <span class="label">当前环境</span>
-              <span class="value">{{ env }}</span>
-            </div>
-          </div>
-        </a-card>
-      </a-col>
-    </a-row>
-
-    <!-- 底部项目介绍 -->
-    <a-row :gutter="20" class="mt-20">
-      <a-col :span="24">
-        <a-card hoverable class="project-card">
-          <div class="project-intro">
-            <div class="project-logo">
-              <img src="@/assets/logo/logo.png" alt="logo" />
-            </div>
-            <div class="project-desc">
-              <h3>予书后台管理系统</h3>
-              <p>一款基于 Vue3 + Vite + Ant Design Vue 的现代化后台管理系统。提供丰富的组件和功能,开箱即用,助力开发者快速构建高质量的 Web 应用。</p>
-              <div class="project-actions">
-                <a-button type="primary" @click="goTarget('http://yushu.vip')">
-                  <template #icon><ShareAltOutlined /></template>
-                  访问官网
-                </a-button>
-                <a-button @click="goTarget('https://gitee.com/y_project/yushu-Vue')">
-                  <template #icon><StarOutlined /></template>
-                  Gitee Star
-                </a-button>
-              </div>
-            </div>
-          </div>
-        </a-card>
       </a-col>
     </a-row>
   </div>
 </template>
 
-<script setup name="Index">
-import { ref, onMounted } from 'vue'
+<script setup name="Workbench">
+import { ref, onMounted, onUnmounted, computed } from 'vue'
 import { useRouter } from 'vue-router'
+import { Empty } from 'ant-design-vue'
 import { 
-  UserOutlined, MessageOutlined, FolderOutlined, MonitorOutlined, SettingOutlined, 
-  FileTextOutlined, BellOutlined, CommentOutlined, CaretUpOutlined, CaretDownOutlined, 
-  ShareAltOutlined, StarOutlined, LineChartOutlined, ShoppingOutlined, ReadOutlined
+  ClockCircleOutlined, CalendarOutlined, CheckSquareOutlined, MessageOutlined,
+  CheckCircleOutlined, BellOutlined, FileTextOutlined, AppstoreOutlined,
+  UserOutlined, SettingOutlined, FolderOutlined, TeamOutlined
 } from '@ant-design/icons-vue'
-import LineChart from './dashboard/LineChart.vue'
-import { getDashboardStats, getVisitsTrend } from '@/api/system/statistics'
+import { getMyTodo } from '@/api/system/todo'
+import { getConversationList } from '@/api/system/message'
+import { getRouters } from '@/api/menu'
+import { formatTimeAgo } from '@/utils/formatTime'
+import useUserStore from '@/store/modules/user'
 
 const router = useRouter()
-const env = import.meta.env.MODE
-const loading = ref(false)
-
-// 统计数据
-const statCards = ref([
-  { label: '用户总数', value: 0, icon: UserOutlined, color: '#409eff', trend: 0 },
-  { label: '消息数量', value: 0, icon: MessageOutlined, color: '#67c23a', trend: 0 },
-  { label: '文件数量', value: 0, icon: FolderOutlined, color: '#e6a23c', trend: 0 },
-  { label: '今日访问', value: 0, icon: MonitorOutlined, color: '#f56c6c', trend: 0 }
+const userStore = useUserStore()
+
+// 当前时间
+const currentTime = ref('')
+const currentDate = ref('')
+const currentWeek = ref('')
+const greetingText = ref('')
+const userName = computed(() => userStore.nickName || userStore.name || '用户')
+
+// 今日统计
+const todayStats = ref([
+  { 
+    label: '今日待办', 
+    value: 0, 
+    icon: CheckSquareOutlined, 
+    color: '#409eff',
+    onClick: () => router.push('/system/todo')
+  },
+  { 
+    label: '未读消息', 
+    value: 0, 
+    icon: MessageOutlined, 
+    color: '#67c23a',
+    onClick: () => router.push('/message')
+  },
+  { 
+    label: '系统通知', 
+    value: 0, 
+    icon: BellOutlined, 
+    color: '#e6a23c',
+    onClick: () => router.push('/system/notification')
+  },
+  { 
+    label: '待审批', 
+    value: 0, 
+    icon: FileTextOutlined, 
+    color: '#f56c6c',
+    onClick: () => {}
+  }
 ])
 
-// 图表数据
-const chartPeriod = ref('week')
-const lineChartData = ref({
-  expectedData: [0, 0, 0, 0, 0, 0, 0],
-  actualData: [0, 0, 0, 0, 0, 0, 0]
-})
+// 待办列表
+const todoList = ref([])
 
-// 快捷入口
-const quickLinks = ref([
-  { name: '用户管理', path: '/system/user', icon: UserOutlined, color: '#409eff', bg: '#ecf5ff' },
-  { name: '角色管理', path: '/system/role', icon: UserOutlined, color: '#67c23a', bg: '#f0f9eb' },
-  { name: '菜单管理', path: '/system/menu', icon: SettingOutlined, color: '#e6a23c', bg: '#fdf6ec' },
-  { name: '文件管理', path: '/file', icon: FolderOutlined, color: '#f56c6c', bg: '#fef0f0' },
-  { name: '消息中心', path: '/message', icon: MessageOutlined, color: '#409eff', bg: '#ecf5ff' },
-  { name: '通知公告', path: '/system/notice', icon: BellOutlined, color: '#e6a23c', bg: '#fdf6ec' },
-  { name: '操作日志', path: '/system/log/operlog', icon: FileTextOutlined, color: '#909399', bg: '#f4f4f5' },
-  { name: 'AI 对话', path: '/ai/chat', icon: CommentOutlined, color: '#764ba2', bg: '#f8f5fa' }
+// 最近消息
+const recentMessages = ref([])
+
+// 本周日程
+const weekRange = ref('')
+const scheduleList = ref([
+  { id: 1, time: '周一 09:00', title: '团队周会', description: '讨论本周工作计划', color: 'blue' },
+  { id: 2, time: '周二 14:00', title: '项目评审', description: '新功能需求评审', color: 'green' },
+  { id: 3, time: '周三 10:30', title: '技术分享', description: 'Vue3 最佳实践', color: 'orange' },
+  { id: 4, time: '周四 15:00', title: '客户沟通', description: '产品演示和反馈收集', color: 'purple' },
+  { id: 5, time: '周五 16:00', title: '周总结', description: '本周工作总结和复盘', color: 'red' }
 ])
 
-/** 加载统计数据 */
-async function loadDashboardStats() {
-  loading.value = true
+// 快捷入口
+const quickLinks = ref([])
+
+// 图标映射
+const iconMap = {
+  'user': UserOutlined,
+  'peoples': TeamOutlined,
+  'tree-table': SettingOutlined,
+  'folder': FolderOutlined,
+  'message': MessageOutlined,
+  'bell': BellOutlined,
+  'log': FileTextOutlined,
+  'setting': SettingOutlined
+}
+
+// 颜色映射
+const colorMap = [
+  { color: '#409eff', bg: '#ecf5ff' },
+  { color: '#67c23a', bg: '#f0f9eb' },
+  { color: '#e6a23c', bg: '#fdf6ec' },
+  { color: '#f56c6c', bg: '#fef0f0' },
+  { color: '#409eff', bg: '#ecf5ff' },
+  { color: '#e6a23c', bg: '#fdf6ec' },
+  { color: '#909399', bg: '#f4f4f5' },
+  { color: '#909399', bg: '#f4f4f5' }
+]
+
+// 更新时间
+function updateTime() {
+  const now = new Date()
+  const hours = now.getHours()
+  const minutes = now.getMinutes().toString().padStart(2, '0')
+  const seconds = now.getSeconds().toString().padStart(2, '0')
+  
+  currentTime.value = `${hours}:${minutes}:${seconds}`
+  
+  const year = now.getFullYear()
+  const month = (now.getMonth() + 1).toString().padStart(2, '0')
+  const day = now.getDate().toString().padStart(2, '0')
+  currentDate.value = `${year}年${month}月${day}日`
+  
+  const weekDays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
+  currentWeek.value = weekDays[now.getDay()]
+  
+  // 问候语
+  if (hours < 6) {
+    greetingText.value = '凌晨好'
+  } else if (hours < 9) {
+    greetingText.value = '早上好'
+  } else if (hours < 12) {
+    greetingText.value = '上午好'
+  } else if (hours < 14) {
+    greetingText.value = '中午好'
+  } else if (hours < 18) {
+    greetingText.value = '下午好'
+  } else if (hours < 22) {
+    greetingText.value = '晚上好'
+  } else {
+    greetingText.value = '夜深了'
+  }
+}
+
+// 获取本周日期范围
+function getWeekRange() {
+  const now = new Date()
+  const day = now.getDay()
+  const diff = now.getDate() - day + (day === 0 ? -6 : 1)
+  const monday = new Date(now.setDate(diff))
+  const sunday = new Date(monday)
+  sunday.setDate(monday.getDate() + 6)
+  
+  const format = (date) => {
+    const m = (date.getMonth() + 1).toString().padStart(2, '0')
+    const d = date.getDate().toString().padStart(2, '0')
+    return `${m}.${d}`
+  }
+  
+  weekRange.value = `${format(monday)} - ${format(sunday)}`
+}
+
+// 加载快捷入口(从菜单获取)
+async function loadQuickLinks() {
   try {
-    const res = await getDashboardStats()
+    const res = await getRouters()
     if (res.code === 200 && res.data) {
-      const data = res.data
-      const trends = data.trends || {}
-      
-      statCards.value[0].value = data.userCount || 0
-      statCards.value[0].trend = trends.userTrend || 0
-      
-      statCards.value[1].value = data.messageCount || 0
-      statCards.value[1].trend = trends.messageTrend || 0
-      
-      statCards.value[2].value = data.fileCount || 0
-      statCards.value[2].trend = trends.fileTrend || 0
+      const menus = []
+      // 递归提取所有菜单
+      const extractMenus = (list) => {
+        list.forEach(item => {
+          if (item.path && item.meta && item.meta.title) {
+            menus.push({
+              name: item.meta.title,
+              path: item.path,
+              icon: iconMap[item.meta.icon] || SettingOutlined
+            })
+          }
+          if (item.children && item.children.length > 0) {
+            extractMenus(item.children)
+          }
+        })
+      }
+      extractMenus(res.data)
       
-      statCards.value[3].value = data.todayVisits || 0
-      statCards.value[3].trend = trends.visitTrend || 0
+      // 取前8个菜单作为快捷入口
+      quickLinks.value = menus.slice(0, 8).map((item, index) => ({
+        ...item,
+        color: colorMap[index].color,
+        bg: colorMap[index].bg
+      }))
     }
   } catch (error) {
-    console.error('加载统计数据失败:', error)
-  } finally {
-    loading.value = false
+    console.error('加载快捷入口失败:', error)
   }
 }
 
-/** 加载访问趋势 */
-async function loadVisitsTrend() {
+// 加载待办事项
+async function loadTodoList() {
   try {
-    const res = await getVisitsTrend()
-    if (res.code === 200 && res.data && res.data.data) {
-      const trendData = res.data.data
-      const actualData = new Array(7).fill(0)
-      trendData.forEach((item, index) => {
-        if (index < 7) {
-          actualData[index] = item.count || 0
-        }
-      })
-      lineChartData.value.actualData = actualData
-      lineChartData.value.expectedData = actualData.map(v => Math.round(v * 1.1))
-    }
+    const res = await getMyTodo()
+    const list = res.rows || res.data || []
+    todoList.value = list
+      .filter(item => item.status === '0')
+      .slice(0, 5)
+      .map(item => ({
+        id: item.todoId,
+        title: item.title,
+        dueDate: item.dueDate ? item.dueDate.substring(0, 10) : '无截止日期',
+        priority: item.priority,
+        status: item.status
+      }))
+    
+    todayStats.value[0].value = list.filter(item => item.status === '0').length
   } catch (error) {
-    console.error('加载访问趋势失败:', error)
+    console.error('加载待办失败:', error)
   }
 }
 
-function goTarget(url) {
-  window.open(url, '_blank')
+// 加载最近消息
+async function loadRecentMessages() {
+  try {
+    const res = await getConversationList()
+    const list = res.data || res.rows || []
+    recentMessages.value = list
+      .filter(item => item.conversation_id !== 'sys_notification')
+      .slice(0, 5)
+      .map(item => ({
+        id: item.conversation_id,
+        sender: item.other_members || '未知用户',
+        avatar: item.avatar || '',
+        content: item.last_message || '',
+        time: formatTimeAgo(item.last_message_time),
+        isRead: (item.unread_count || 0) === 0
+      }))
+    
+    const unreadCount = list.filter(item => (item.unread_count || 0) > 0).length
+    todayStats.value[1].value = unreadCount
+  } catch (error) {
+    console.error('加载消息失败:', error)
+  }
+}
+
+// 获取优先级颜色
+function getPriorityColor(priority) {
+  const colors = { '0': 'default', '1': 'blue', '2': 'orange', '3': 'red' }
+  return colors[priority] || 'default'
+}
+
+// 获取优先级文本
+function getPriorityText(priority) {
+  const texts = { '0': '低', '1': '普通', '2': '重要', '3': '紧急' }
+  return texts[priority] || '普通'
 }
 
 function goRoute(path) {
   router.push(path)
 }
 
+let timer = null
+
 onMounted(() => {
-  loadDashboardStats()
-  loadVisitsTrend()
+  updateTime()
+  getWeekRange()
+  loadQuickLinks()
+  loadTodoList()
+  loadRecentMessages()
+  
+  timer = setInterval(updateTime, 1000)
+})
+
+onUnmounted(() => {
+  if (timer) {
+    clearInterval(timer)
+  }
 })
 </script>
 
 <style lang="scss" scoped>
-.dashboard-container {
+.workbench-container {
   padding: 24px;
   background-color: #f0f2f5;
   min-height: 100vh;
@@ -239,188 +419,339 @@ onMounted(() => {
   }
 }
 
-.stat-card-item {
+// 问候区域
+.greeting-section {
+  background: #fff;
+  border-radius: 8px;
+  padding: 32px;
   margin-bottom: 20px;
-  border: none;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
   
-  :deep(.ant-card-body) {
-    padding: 20px;
-  }
-
-  .stat-card-content {
+  .greeting-content {
     display: flex;
+    justify-content: space-between;
     align-items: center;
-    margin-bottom: 16px;
     
-    .stat-icon-wrapper {
-      width: 48px;
-      height: 48px;
-      border-radius: 12px;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      margin-right: 16px;
-      box-shadow: 0 4px 10px rgba(0,0,0,0.1);
-    }
-    
-    .stat-info {
-      .stat-label {
+    .greeting-text {
+      h1 {
+        font-size: 28px;
+        font-weight: 500;
+        color: #303133;
+        margin: 0 0 8px 0;
+      }
+      
+      .greeting-subtitle {
         font-size: 14px;
         color: #909399;
-        margin-bottom: 4px;
+        margin: 0;
       }
-      .stat-value {
-        font-size: 24px;
-        font-weight: 600;
-        color: #303133;
+    }
+    
+    .greeting-time {
+      .time-display {
+        display: flex;
+        align-items: center;
+        gap: 12px;
+        background: #409eff;
+        padding: 12px 20px;
+        border-radius: 8px;
+        
+        .time-icon {
+          font-size: 20px;
+          color: #fff;
+        }
+        
+        .current-time {
+          font-size: 24px;
+          font-weight: 500;
+          color: #fff;
+          font-family: 'Courier New', monospace;
+        }
       }
     }
   }
+}
+
+// 概览卡片
+.overview-cards {
+  margin-bottom: 20px;
   
-  .stat-card-footer {
-    border-top: 1px solid #ebeef5;
-    padding-top: 12px;
-    font-size: 12px;
-    color: #909399;
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
+  .stat-card-item {
+    border: none;
+    border-radius: 8px;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+    transition: all 0.3s;
+    cursor: pointer;
     
-    .trend-up {
-      color: #67c23a;
-      display: flex;
-      align-items: center;
+    &:hover {
+      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
+    }
+    
+    :deep(.ant-card-body) {
+      padding: 20px;
     }
     
-    .trend-down {
-      color: #f56c6c;
+    .stat-card-content {
       display: flex;
       align-items: center;
+      gap: 16px;
+      
+      .stat-icon-wrapper {
+        width: 52px;
+        height: 52px;
+        border-radius: 8px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+      }
+      
+      .stat-info {
+        flex: 1;
+        
+        .stat-value {
+          font-size: 26px;
+          font-weight: 600;
+          color: #303133;
+          margin-bottom: 4px;
+        }
+        
+        .stat-label {
+          font-size: 14px;
+          color: #909399;
+        }
+      }
     }
   }
 }
 
-.chart-card {
+// 主要内容区域
+.main-content {
   .card-header {
     display: flex;
     justify-content: space-between;
     align-items: center;
-  }
-  .chart-wrapper {
-    height: 350px;
+    font-weight: 500;
+    
+    span {
+      display: flex;
+      align-items: center;
+      gap: 8px;
+    }
   }
 }
 
-.quick-entry-card {
-  .quick-nav-grid {
-    display: grid;
-    grid-template-columns: repeat(4, 1fr);
-    gap: 16px;
-    
-    .quick-nav-item {
+// 待办卡片
+.todo-card {
+  border-radius: 8px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+  
+  .todo-list {
+    .todo-item {
       display: flex;
-      flex-direction: column;
       align-items: center;
+      gap: 12px;
+      padding: 14px;
+      border-radius: 6px;
+      margin-bottom: 10px;
+      background: #f5f7fa;
       cursor: pointer;
       transition: all 0.3s;
       
       &:hover {
-        transform: translateY(-2px);
+        background: #ecf5ff;
       }
       
-      .nav-icon {
-        width: 40px;
-        height: 40px;
-        border-radius: 10px;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        margin-bottom: 8px;
+      &:last-child {
+        margin-bottom: 0;
       }
       
-      .nav-label {
-        font-size: 12px;
-        color: #606266;
+      .todo-checkbox {
+        font-size: 18px;
+        
+        .checked {
+          color: #67c23a;
+        }
+        
+        .pending {
+          color: #e6a23c;
+        }
+      }
+      
+      .todo-content {
+        flex: 1;
+        
+        .todo-title {
+          font-size: 14px;
+          color: #303133;
+          margin-bottom: 4px;
+        }
+        
+        .todo-time {
+          font-size: 12px;
+          color: #909399;
+          display: flex;
+          align-items: center;
+          gap: 4px;
+        }
       }
     }
   }
 }
 
-.system-info-card {
-  .card-header {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-  }
+// 消息卡片
+.message-card {
+  border-radius: 8px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
   
-  .info-list {
-    .info-item {
+  .message-list {
+    .message-item {
       display: flex;
-      justify-content: space-between;
-      padding: 12px 0;
-      border-bottom: 1px solid #f0f2f5;
+      align-items: flex-start;
+      gap: 12px;
+      padding: 14px;
+      border-radius: 6px;
+      margin-bottom: 10px;
+      background: #f5f7fa;
+      cursor: pointer;
+      transition: all 0.3s;
       
-      &:last-child {
-        border-bottom: none;
+      &:hover {
+        background: #ecf5ff;
       }
       
-      .label {
-        color: #909399;
-        font-size: 14px;
+      &:last-child {
+        margin-bottom: 0;
       }
       
-      .value {
-        color: #303133;
-        font-weight: 500;
-        font-size: 14px;
+      .message-content {
+        flex: 1;
+        min-width: 0;
+        
+        .message-header {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          margin-bottom: 4px;
+          
+          .message-sender {
+            font-size: 14px;
+            font-weight: 500;
+            color: #303133;
+          }
+          
+          .message-time {
+            font-size: 12px;
+            color: #909399;
+          }
+        }
+        
+        .message-text {
+          font-size: 13px;
+          color: #606266;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+        }
       }
     }
   }
 }
 
-.project-card {
-  .project-intro {
-    display: flex;
-    align-items: center;
-    gap: 32px;
-    padding: 10px;
-    
-    .project-logo {
-      img {
-        width: 80px;
-        height: 80px;
-      }
+// 日程卡片
+.schedule-card {
+  border-radius: 8px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+  
+  .card-header {
+    .week-range {
+      font-size: 13px;
+      color: #909399;
+      font-weight: normal;
     }
+  }
+  
+  .schedule-timeline {
+    margin-top: 16px;
     
-    .project-desc {
-      h3 {
-        margin: 0 0 12px 0;
-        font-size: 20px;
+    .schedule-item {
+      .schedule-time {
+        display: flex;
+        align-items: center;
+        gap: 6px;
+        font-size: 13px;
+        color: #606266;
+        margin-bottom: 6px;
+      }
+      
+      .schedule-title {
+        font-size: 14px;
+        font-weight: 500;
         color: #303133;
+        margin-bottom: 4px;
       }
       
-      p {
-        margin: 0 0 20px 0;
-        color: #606266;
-        line-height: 1.6;
+      .schedule-desc {
+        font-size: 13px;
+        color: #909399;
+      }
+    }
+  }
+}
+
+// 快捷入口
+.quick-entry-card {
+  border-radius: 8px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+  
+  .quick-nav-grid {
+    display: grid;
+    grid-template-columns: repeat(4, 1fr);
+    gap: 20px;
+    padding: 16px;
+    
+    .quick-nav-item {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      cursor: pointer;
+      padding: 20px 10px;
+      border-radius: 6px;
+      transition: all 0.3s;
+      
+      &:hover {
+        background: #f5f7fa;
       }
       
-      .project-actions {
+      .nav-icon {
+        width: 56px;
+        height: 56px;
+        border-radius: 8px;
         display: flex;
-        gap: 12px;
+        align-items: center;
+        justify-content: center;
+        margin-bottom:10px;
+      }
+      
+      .nav-label {
+        font-size: 14px;
+        color: #606266;
+        text-align: center;
       }
     }
   }
 }
 
 @media (max-width: 768px) {
-  .project-intro {
+  .greeting-content {
     flex-direction: column;
+    gap: 20px;
     text-align: center;
-    
-    .project-actions {
-      justify-content: center;
-    }
+  }
+  
+  .quick-nav-grid {
+    grid-template-columns: repeat(2, 1fr) !important;
   }
 }
 </style>
+