diff --git a/client/src/components/base/BaseButton.vue b/client/src/components/base/BaseButton.vue new file mode 100644 index 0000000..eb75e7b --- /dev/null +++ b/client/src/components/base/BaseButton.vue @@ -0,0 +1,4 @@ + + diff --git a/client/src/components/base/BaseCard.vue b/client/src/components/base/BaseCard.vue new file mode 100644 index 0000000..821e9a9 --- /dev/null +++ b/client/src/components/base/BaseCard.vue @@ -0,0 +1 @@ + diff --git a/client/src/components/feedback/EmptyState.vue b/client/src/components/feedback/EmptyState.vue new file mode 100644 index 0000000..045e0d2 --- /dev/null +++ b/client/src/components/feedback/EmptyState.vue @@ -0,0 +1,2 @@ + +○{{ title }}{{ description }} diff --git a/client/src/components/feedback/ErrorState.vue b/client/src/components/feedback/ErrorState.vue new file mode 100644 index 0000000..10b4eb0 --- /dev/null +++ b/client/src/components/feedback/ErrorState.vue @@ -0,0 +1,2 @@ + +暂时无法加载{{ message ?? '请检查服务是否已启动,然后重试。' }}重新加载 diff --git a/client/src/styles/main.css b/client/src/styles/main.css index 2cc5b0c..27fea75 100644 --- a/client/src/styles/main.css +++ b/client/src/styles/main.css @@ -1 +1,2 @@ -:root{font-family:Arial,"PingFang SC",sans-serif;color:#1a1f2e;background:#f7f6f2;font-synthesis:none}*{box-sizing:border-box}body{margin:0}.app-shell{min-height:100vh}.sidebar{position:fixed;inset:0 auto 0 0;width:220px;padding:16px 10px;background:#fff;border-right:1px solid #e8e6e0;display:flex;flex-direction:column;gap:7px}.brand{height:36px;display:flex;align-items:center;gap:9px}.brand span{display:grid;place-items:center;width:28px;height:28px;background:#2b4c8f;border-radius:8px;color:white}.nav-item{border:0;background:transparent;color:#6b7280;height:40px;border-radius:10px;text-align:left;padding:0 12px;cursor:pointer;font-size:13px}.nav-item.active{background:#2b4c8f;color:#fff}.sidebar-spacer{flex:1}.content{margin-left:220px;padding:32px;max-width:1250px}header{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:20px}h1{font-size:24px;margin:0 0 5px}h2{margin:0 0 8px}p{font-size:13px;color:#6b7280;margin:0;line-height:1.5}.primary{height:40px;border:0;border-radius:10px;padding:0 16px;background:#2b4c8f;color:#fff;font-weight:600;cursor:pointer}.welcome{background:#fff;border:1px solid #e8e6e0;border-radius:16px;padding:24px}.mobile-tabs{display:none}@media(max-width:767px){.sidebar{display:none}.content{margin:0;padding:28px 24px 110px}.content header{margin-bottom:24px}.content h1{font-size:22px}.mobile-tabs{position:fixed;display:flex;z-index:2;left:16px;right:16px;bottom:16px;height:70px;background:#fff;border:1px solid #e8e6e0;border-radius:30px;box-shadow:0 4px 12px rgba(27,45,91,.08);justify-content:space-around;padding:8px}.mobile-tabs button{border:0;background:transparent;color:#9ca2ad;font-size:10px;display:flex;flex-direction:column;align-items:center;gap:4px;border-radius:24px;padding:7px 9px}.mobile-tabs button.active{background:#2b4c8f;color:#fff}.mobile-tabs span{font-size:17px}.primary{height:36px;padding:0 11px;font-size:12px}} +@import url('../../../deliverables/design/design-tokens.css'); +:root{font-family:var(--font-sans);color:var(--text-primary);background:var(--bg-canvas);font-synthesis:none}*{box-sizing:border-box}body{margin:0}.app-shell{min-height:100vh}.sidebar{position:fixed;inset:0 auto 0 0;width:var(--sidebar-width-desktop);padding:16px 10px;background:var(--bg-card);border-right:1px solid var(--border-subtle);display:flex;flex-direction:column;gap:7px}.brand{height:36px;display:flex;align-items:center;gap:9px}.brand span{display:grid;place-items:center;width:28px;height:28px;background:var(--primary);border-radius:var(--radius-sm);color:var(--on-accent)}.nav-item{border:0;background:transparent;color:var(--text-secondary);height:40px;border-radius:10px;text-align:left;padding:0 12px;cursor:pointer;font-size:13px}.nav-item.active{background:var(--primary);color:var(--on-accent)}.sidebar-spacer{flex:1}.content{margin-left:var(--sidebar-width-desktop);padding:var(--padding-desktop);max-width:1250px}header{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:20px}h1{font:var(--fw-h1) var(--fs-h1)/var(--lh-h1) var(--ff-h1);margin:0 0 5px}h2{margin:0 0 8px}p{font:var(--fw-subtitle) var(--fs-subtitle)/var(--lh-subtitle) var(--ff-subtitle);color:var(--text-secondary);margin:0}.primary,.base-button{height:var(--btn-height);border:0;border-radius:var(--radius-btn);padding:0 16px;background:var(--primary);color:var(--on-accent);font:var(--fw-button) var(--fs-button)/var(--lh-button) var(--ff-button);cursor:pointer}.base-button--secondary{background:transparent;border:1px solid var(--primary);color:var(--primary)}.base-button--soft{background:var(--success-soft);color:var(--success)}.base-card{background:var(--bg-card);border:1px solid var(--border-subtle);border-radius:var(--radius-lg);padding:var(--card-padding-desktop)}.welcome{background:var(--bg-card);border:1px solid var(--border-subtle);border-radius:var(--radius-lg);padding:var(--card-padding-desktop)}.mobile-tabs{display:none}.empty-state,.error-state{text-align:center;padding:40px 20px;border:1px dashed var(--border-subtle);border-radius:var(--radius-lg);background:var(--bg-card)}.empty-state__icon{font-size:28px;color:var(--text-muted)}.empty-state h3,.error-state strong{display:block;margin:10px 0 6px}.error-state strong{color:var(--danger)}@media(max-width:767px){.sidebar{display:none}.content{margin:0;padding:28px 24px 110px}.content header{margin-bottom:24px}.content h1{font-size:22px}.mobile-tabs{position:fixed;display:flex;z-index:2;left:16px;right:16px;bottom:16px;height:70px;background:var(--bg-card);border:1px solid var(--border-subtle);border-radius:30px;box-shadow:var(--shadow-level-2);justify-content:space-around;padding:8px}.mobile-tabs button{border:0;background:transparent;color:var(--text-muted);font-size:10px;display:flex;flex-direction:column;align-items:center;gap:4px;border-radius:24px;padding:7px 9px}.mobile-tabs button.active{background:var(--primary);color:var(--on-accent)}.mobile-tabs span{font-size:17px}.primary,.base-button{height:36px;padding:0 11px;font-size:12px}.base-card{padding:var(--card-padding-mobile)}} diff --git a/client/src/views/dashboard/DashboardView.vue b/client/src/views/dashboard/DashboardView.vue index d59c6af..5b11d31 100644 --- a/client/src/views/dashboard/DashboardView.vue +++ b/client/src/views/dashboard/DashboardView.vue @@ -1,3 +1,7 @@ + + - 备考通已就绪前端工程架构已启动,后续任务将逐页还原原型并接入真实数据。 + 备考通已就绪前端工程架构已启动,后续任务将逐页还原原型并接入真实数据。 diff --git a/docs/checks/task-03.md b/docs/checks/task-03.md new file mode 100644 index 0000000..f989360 --- /dev/null +++ b/docs/checks/task-03.md @@ -0,0 +1,25 @@ +# 任务 03 检查记录:前端基础视觉系统与响应式壳层 + +日期:2026-08-28 + +## 命令检查 + +- `pnpm typecheck`:通过(server、client)。 +- `pnpm build`:通过(server、client)。 +- 设计 Token 已由全局样式引用:通过。 +- 基础卡片、按钮、空状态、错误状态组件已建立:通过。 +- PC 侧栏和 Mobile 底部导航共用业务状态:通过。 + +## 原型截图对比 + +- 对照原型的视觉基线检查了浅米白画布、白色卡片、深蓝主色、16px 卡片圆角、PC 侧栏和移动底部胶囊导航。 +- 当前页面仍是骨架,数据卡、图表和业务内容尚未实现;这些差异属于后续页面任务,未在本任务中伪造填充。 + +## 浏览器操作 + +- 之前已通过浏览器打开入口并点击导航验证选中态。 +- 本任务修改后,原有浏览器标签页因开发服务重启显示不可访问,当前自动化环境无法刷新该标签页;已通过命令构建和 CSS/组件检查确认无编译问题,浏览器回归待服务稳定后补做。 + +## 当前结论 + +前端基础目录、设计 Token、基础组件和响应式壳层已完成;页面级原型对齐将在对应业务页面实现时逐页截图复核。
{{ description }}
{{ message ?? '请检查服务是否已启动,然后重试。' }}
前端工程架构已启动,后续任务将逐页还原原型并接入真实数据。