@@ -28,6 +65,17 @@ body {
margin: 0;
}
+.global-progress-bar {
+ position: fixed;
+ top: 0;
+ left: 0;
+ height: 3px;
+ background: linear-gradient(to right, #3b82f6, #60a5fa);
+ z-index: 9999;
+ transition: width 0.3s ease;
+ box-shadow: 0 0 8px rgba(59, 130, 246, 0.6);
+}
+
.smartmate-layout {
height: 100vh;
height: 100dvh;
@@ -41,6 +89,32 @@ body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
+/* 全局自定义滚动条样式 */
+::-webkit-scrollbar {
+ width: 6px;
+ height: 6px;
+}
+
+::-webkit-scrollbar-track {
+ background: transparent;
+}
+
+::-webkit-scrollbar-thumb {
+ background: rgba(15, 23, 42, 0.08);
+ border-radius: 10px;
+ transition: background 0.3s;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: rgba(15, 23, 42, 0.15);
+}
+
+/* Firefox 兼容性 */
+* {
+ scrollbar-width: thin;
+ scrollbar-color: rgba(15, 23, 42, 0.08) transparent;
+}
+
.smartmate-content {
flex: 1;
min-width: 0;
diff --git a/frontend/src/assets/feature-ai.png b/frontend/src/assets/feature-ai.png
new file mode 100644
index 0000000..2511051
Binary files /dev/null and b/frontend/src/assets/feature-ai.png differ
diff --git a/frontend/src/assets/feature-schedule.png b/frontend/src/assets/feature-schedule.png
new file mode 100644
index 0000000..54e047b
Binary files /dev/null and b/frontend/src/assets/feature-schedule.png differ
diff --git a/frontend/src/assets/feature-tools.png b/frontend/src/assets/feature-tools.png
new file mode 100644
index 0000000..4c4e99a
Binary files /dev/null and b/frontend/src/assets/feature-tools.png differ
diff --git a/frontend/src/assets/hero-dashboard.png b/frontend/src/assets/hero-dashboard.png
new file mode 100644
index 0000000..a7690bf
Binary files /dev/null and b/frontend/src/assets/hero-dashboard.png differ
diff --git a/frontend/src/components/common/MainSidebar.vue b/frontend/src/components/common/MainSidebar.vue
index 0209a2a..d63ea04 100644
--- a/frontend/src/components/common/MainSidebar.vue
+++ b/frontend/src/components/common/MainSidebar.vue
@@ -4,16 +4,18 @@ import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
interface SidebarItem {
- key: 'home' | 'task' | 'calendar' | 'ai'
+ key: 'home' | 'task' | 'calendar' | 'ai' | 'forum' | 'store'
label: string
short: string
- to?: '/dashboard' | '/assistant' | '/schedule'
+ to?: '/dashboard' | '/assistant' | '/schedule' | '/forum' | '/store'
}
const sidebarItems: SidebarItem[] = [
{ key: 'home', label: '总览', short: '总', to: '/dashboard' },
{ key: 'calendar', label: '日程', short: '程', to: '/schedule' },
{ key: 'ai', label: '助手', short: 'AI', to: '/assistant' },
+ { key: 'forum', label: '社区', short: '区', to: '/forum' },
+ { key: 'store', label: '商店', short: '商', to: '/store' },
]
const route = useRoute()
@@ -22,6 +24,8 @@ const router = useRouter()
const activeSidebarKey = computed(() => {
if (route.path.startsWith('/assistant')) return 'ai'
if (route.path.startsWith('/schedule')) return 'calendar'
+ if (route.path.startsWith('/forum')) return 'forum'
+ if (route.path.startsWith('/store')) return 'store'
return 'home'
})
@@ -30,6 +34,7 @@ const activeSidebarIndex = computed(() => {
})
const activeIndicatorStyle = computed(() => {
+ // 每个项高度 60px + 间隔 12px = 72px
return {
transform: `translateY(${activeSidebarIndex.value * 72}px)`
}
diff --git a/frontend/src/components/dashboard/TaskQuadrantCard.vue b/frontend/src/components/dashboard/TaskQuadrantCard.vue
index 0cde0be..ff31c90 100644
--- a/frontend/src/components/dashboard/TaskQuadrantCard.vue
+++ b/frontend/src/components/dashboard/TaskQuadrantCard.vue
@@ -333,6 +333,11 @@ const visibleTasks = computed(() => props.tasks)
.action-btn.delete:hover { background: #fee2e2; transform: scale(1.1); }
/* --- 骨架屏 --- */
+.quadrant-card__skeleton {
+ display: grid;
+ gap: 12px;
+}
+
.quadrant-card__skeleton-item {
border-radius: 18px;
min-height: 72px;
diff --git a/frontend/src/components/dashboard/TodayTimeline.vue b/frontend/src/components/dashboard/TodayTimeline.vue
index c0b321e..293e14c 100644
--- a/frontend/src/components/dashboard/TodayTimeline.vue
+++ b/frontend/src/components/dashboard/TodayTimeline.vue
@@ -109,35 +109,38 @@ const renderSlots = computed(() =>
-
-
+
-
-
-
- {{ slot.timeText }}
- {{ slot.title }}
-
-
+
+
+
+ {{ slot.timeText }}
+ {{ slot.title }}
+
+
-
- {{ slot.title }}
-
-
-
-
+
+ {{ slot.title }}
+
+
+
@@ -187,16 +190,9 @@ const renderSlots = computed(() =>
flex-direction: column;
justify-content: space-between;
min-height: 140px;
- transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
cursor: default;
}
-.pastel-item:hover {
- transform: scale(1.03) translateY(-4px);
- box-shadow: 0 15px 30px -10px rgba(0, 0, 0, 0.1);
- z-index: 10;
-}
-
.item-time {
font-size: 12px;
font-weight: 800;
@@ -266,20 +262,16 @@ const renderSlots = computed(() =>
animation: pill-shimmer 1.5s infinite linear;
}
+.skeleton-pill.is-pause {
+ min-height: 80px;
+}
+
@keyframes pill-shimmer {
0% { opacity: 0.5; }
50% { opacity: 1; }
100% { opacity: 0.5; }
}
-/* 动画效果 */
-.grid-pop-enter-active {
- transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
-}
-.grid-pop-enter-from {
- opacity: 0;
- transform: scale(0.9);
-}
@media (max-width: 1200px) {
.pastel-grid { grid-template-columns: repeat(4, 1fr); }
diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts
index b545505..cd87674 100644
--- a/frontend/src/router/index.ts
+++ b/frontend/src/router/index.ts
@@ -7,12 +7,15 @@ import DashboardView from '@/views/DashboardView.vue'
import ScheduleView from '@/views/ScheduleView.vue'
import AssistantReasoningDebug from '@/views/debug/AssistantReasoningDebug.vue'
+import HomeView from '@/views/HomeView.vue'
+
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
- redirect: '/dashboard',
+ name: 'home',
+ component: HomeView,
},
{
path: '/auth',
@@ -46,6 +49,30 @@ const router = createRouter({
requiresAuth: true,
},
},
+ {
+ path: '/forum',
+ name: 'forum',
+ component: () => import('@/views/ForumView.vue'),
+ meta: {
+ requiresAuth: true,
+ },
+ },
+ {
+ path: '/forum/:id',
+ name: 'plan-detail',
+ component: () => import('@/views/PlanDetailView.vue'),
+ meta: {
+ requiresAuth: true,
+ },
+ },
+ {
+ path: '/store',
+ name: 'store',
+ component: () => import('@/views/StoreView.vue'),
+ meta: {
+ requiresAuth: true,
+ },
+ },
{
path: '/debug/tool-card',
name: 'debug-tool-card',
diff --git a/frontend/src/views/DashboardView.vue b/frontend/src/views/DashboardView.vue
index f4ef3a4..6ef6e45 100644
--- a/frontend/src/views/DashboardView.vue
+++ b/frontend/src/views/DashboardView.vue
@@ -1,7 +1,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ post.summary }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+
+ 确认发布
+
+
+
+
+
+
+
diff --git a/frontend/src/views/HomeView.vue b/frontend/src/views/HomeView.vue
new file mode 100644
index 0000000..9d4dd37
--- /dev/null
+++ b/frontend/src/views/HomeView.vue
@@ -0,0 +1,610 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 12,000+
+ 活跃大学生用户
+
+
+ 850,000+
+ AI 编排日程任务
+
+
+ 98.2%
+ 计划执行达成率
+
+
+
+
+
+
+
+
+
+
+
+
传统工具的困境
+
+ -
+ 日历太“空”:
+ 只有格子,不知道课间 20 分钟能干什么。
+
+ -
+ 清单太“满”:
+ 列了一堆 DDL,却不知道该从哪一个开始。
+
+ -
+ AI 太“乱”:
+ 直接改乱日程,让人感到失去掌控。
+
+
+
+
+
时伴的解决之道
+
+ -
+ 感知课表缝隙:
+ 自动识别课间与空课,填入最适合的任务。
+
+ -
+ 智能排序优先级:
+ 基于 DDL 与个人状态,自动给出当日最优解。
+
+ -
+ 预览确认机制:
+ AI 负责提案,你负责最终决定,完美平衡。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
→
+
+
→
+
+
→
+
+
→
+
+
+
+
+
+
+
+
+
核心能力
+
+
+
+
{{ feature.title }}
+
{{ feature.desc }}
+
+
+
+
+
+
+
+
+
+
+
+
让计划不再停在待办列表里
+
加入数万名大学生,开启高效的智能校园生活。
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/views/PlanDetailView.vue b/frontend/src/views/PlanDetailView.vue
new file mode 100644
index 0000000..c68b4b5
--- /dev/null
+++ b/frontend/src/views/PlanDetailView.vue
@@ -0,0 +1,868 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/views/StoreView.vue b/frontend/src/views/StoreView.vue
new file mode 100644
index 0000000..fd03b90
--- /dev/null
+++ b/frontend/src/views/StoreView.vue
@@ -0,0 +1,672 @@
+
+
+
+
+
+
+
+
+
+
+
+
累计获取 Credit
+
+
+ {{ summary.recorded_credit_total }}
+
+
+
+
+
+ 有效期至: {{ summary.valid_until }}
+
+
+
+ 待同步: {{ summary.pending_apply_credit_total }}
+
+
+
+ 已同步: {{ summary.applied_credit_total }}
+
+
+
+
+
+
+
+
+
+
+
+
+ Credit 套餐
+
+
+
{{ product.badge }}
+
+
{{ product.name }}
+
{{ product.description }}
+
+
+
+ {{ product.credit_amount }}
+
+
+
+
+
+
+
+
+ 获取记录
+
+
+
+
+
+
+
+
+ {{ grant.source_label }}
+ +{{ grant.amount }} Credit
+
+
+ {{ grant.description }}
+ {{ formatDate(grant.created_at) }}
+
+
+
+
+
+
+
+
+
+
+
+
互动区 ({{ selectedPost.counters.comment_count }})
+ +