Index.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <template>
  2. <div class="dashboard-content">
  3. <div class="welcome-section">
  4. <h2>欢迎回来,{{ authStore.user?.username }}!</h2>
  5. <p>这是您的四川路桥AI后台管理平台</p>
  6. </div>
  7. <!-- 统计卡片 -->
  8. <div class="stats-grid">
  9. <el-card class="stats-card">
  10. <div class="stats-content">
  11. <div class="stats-icon">
  12. <el-icon size="24" color="#409EFF"><Grid /></el-icon>
  13. </div>
  14. <div class="stats-info">
  15. <div class="stats-number">{{ stats.appCount }}</div>
  16. <div class="stats-label">我的应用</div>
  17. </div>
  18. </div>
  19. </el-card>
  20. <el-card class="stats-card">
  21. <div class="stats-content">
  22. <div class="stats-icon">
  23. <el-icon size="24" color="#67C23A"><Key /></el-icon>
  24. </div>
  25. <div class="stats-info">
  26. <div class="stats-number">{{ stats.tokenCount }}</div>
  27. <div class="stats-label">活跃令牌</div>
  28. </div>
  29. </div>
  30. </el-card>
  31. <el-card class="stats-card">
  32. <div class="stats-content">
  33. <div class="stats-icon">
  34. <el-icon size="24" color="#E6A23C"><Clock /></el-icon>
  35. </div>
  36. <div class="stats-info">
  37. <div class="stats-number">{{ stats.loginCount }}</div>
  38. <div class="stats-label">今日登录</div>
  39. </div>
  40. </div>
  41. </el-card>
  42. <el-card class="stats-card">
  43. <div class="stats-content">
  44. <div class="stats-icon">
  45. <el-icon size="24" color="#F56C6C"><Warning /></el-icon>
  46. </div>
  47. <div class="stats-info">
  48. <div class="stats-number">{{ stats.alertCount }}</div>
  49. <div class="stats-label">安全警告</div>
  50. </div>
  51. </div>
  52. </el-card>
  53. </div>
  54. <!-- 快速操作 -->
  55. <el-card class="quick-actions">
  56. <template #header>
  57. <span>快速操作</span>
  58. </template>
  59. <div class="actions-grid">
  60. <el-button type="primary" @click="$router.push('/apps/create')">
  61. <el-icon><Plus /></el-icon>
  62. 创建应用
  63. </el-button>
  64. <el-button @click="$router.push('/profile')">
  65. <el-icon><User /></el-icon>
  66. 编辑资料
  67. </el-button>
  68. <el-button @click="$router.push('/apps')">
  69. <el-icon><Grid /></el-icon>
  70. 管理应用
  71. </el-button>
  72. </div>
  73. </el-card>
  74. <!-- 最近活动 -->
  75. <el-card class="recent-activity">
  76. <template #header>
  77. <span>最近活动</span>
  78. </template>
  79. <el-timeline>
  80. <el-timeline-item
  81. v-for="activity in recentActivities"
  82. :key="activity.id"
  83. :timestamp="activity.timestamp"
  84. :type="activity.type"
  85. >
  86. {{ activity.description }}
  87. </el-timeline-item>
  88. </el-timeline>
  89. </el-card>
  90. </div>
  91. </template>
  92. <script setup lang="ts">
  93. import { ref, onMounted } from 'vue'
  94. import { useRouter } from 'vue-router'
  95. import { useAuthStore } from '@/stores/auth'
  96. const router = useRouter()
  97. const authStore = useAuthStore()
  98. // 统计数据
  99. const stats = ref({
  100. appCount: 3,
  101. tokenCount: 12,
  102. loginCount: 8,
  103. alertCount: 0
  104. })
  105. // 最近活动
  106. const recentActivities = ref([
  107. {
  108. id: 1,
  109. description: '创建了新应用 "测试应用"',
  110. timestamp: '2024-01-15 14:30',
  111. type: 'primary'
  112. },
  113. {
  114. id: 2,
  115. description: '更新了个人资料',
  116. timestamp: '2024-01-15 10:20',
  117. type: 'success'
  118. },
  119. {
  120. id: 3,
  121. description: '登录系统',
  122. timestamp: '2024-01-15 09:00',
  123. type: 'info'
  124. }
  125. ])
  126. onMounted(() => {
  127. // 加载统计数据
  128. loadStats()
  129. })
  130. const loadStats = async () => {
  131. // TODO: 从API加载真实统计数据
  132. console.log('加载统计数据')
  133. }
  134. </script>
  135. <style scoped>
  136. .dashboard-content {
  137. padding: 20px;
  138. }
  139. .welcome-section {
  140. margin-bottom: 24px;
  141. }
  142. .welcome-section h2 {
  143. margin: 0 0 8px 0;
  144. color: #333;
  145. font-size: 24px;
  146. font-weight: 600;
  147. }
  148. .welcome-section p {
  149. margin: 0;
  150. color: #666;
  151. font-size: 14px;
  152. }
  153. .stats-grid {
  154. display: grid;
  155. grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  156. gap: 16px;
  157. margin-bottom: 24px;
  158. }
  159. .stats-card {
  160. cursor: pointer;
  161. transition: transform 0.2s;
  162. }
  163. .stats-card:hover {
  164. transform: translateY(-2px);
  165. }
  166. .stats-content {
  167. display: flex;
  168. align-items: center;
  169. gap: 16px;
  170. }
  171. .stats-icon {
  172. width: 48px;
  173. height: 48px;
  174. border-radius: 8px;
  175. display: flex;
  176. align-items: center;
  177. justify-content: center;
  178. background: #f0f9ff;
  179. }
  180. .stats-info {
  181. flex: 1;
  182. }
  183. .stats-number {
  184. font-size: 24px;
  185. font-weight: 600;
  186. color: #333;
  187. line-height: 1;
  188. }
  189. .stats-label {
  190. font-size: 14px;
  191. color: #666;
  192. margin-top: 4px;
  193. }
  194. .quick-actions {
  195. margin-bottom: 24px;
  196. }
  197. .actions-grid {
  198. display: flex;
  199. gap: 12px;
  200. flex-wrap: wrap;
  201. }
  202. .recent-activity {
  203. margin-bottom: 24px;
  204. }
  205. </style>