1
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Waiting to run
Docker Build & Deploy / Deploy to Production (push) Has been cancelled
Docker Build & Deploy / Cleanup Dangling Images (push) Has been cancelled
Docker Build & Deploy / WeChat Notification (push) Has been cancelled
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Waiting to run
Docker Build & Deploy / Deploy to Production (push) Has been cancelled
Docker Build & Deploy / Cleanup Dangling Images (push) Has been cancelled
Docker Build & Deploy / WeChat Notification (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-18
|
||||
@@ -0,0 +1,144 @@
|
||||
## Context
|
||||
|
||||
当前项目中三个核心页面(日历、统计、预算)使用了不同的卡片样式规范:
|
||||
|
||||
**现状分析**:
|
||||
- 日历页面使用 CSS 变量系统(`var(--spacing-2xl)`, `var(--radius-lg)`)
|
||||
- 统计页面部分使用 CSS 变量(`var(--spacing-xl)`, `var(--radius-lg)`)
|
||||
- 预算页面使用硬编码数值(`16px`, `12px` 混用)
|
||||
|
||||
**约束条件**:
|
||||
- 必须保持响应式布局不被破坏
|
||||
- 必须支持暗色模式的自动适配
|
||||
- 不能影响现有的功能逻辑
|
||||
- 需要最小化对现有代码的侵入性
|
||||
|
||||
**利益相关者**:
|
||||
- 前端团队:执行样式统一
|
||||
- 设计团队:确保视觉一致性
|
||||
- 用户:获得更统一的使用体验
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- 统一三个页面的卡片基础样式(padding、margin、border-radius、box-shadow)
|
||||
- 建立基于 CSS 变量的样式系统,方便未来维护
|
||||
- 确保所有卡片在暗色模式下表现一致
|
||||
- 为未来的组件化(如通用 Card 组件)奠定基础
|
||||
|
||||
**Non-Goals:**
|
||||
- 不创建新的通用 Card 组件(本次仅统一样式)
|
||||
- 不修改卡片内部的业务逻辑或数据展示方式
|
||||
- 不重构卡片的布局结构(如 flex 方向、grid 系统)
|
||||
- 不涉及其他页面(只针对 calendarV2、statisticsV2、budgetV2)
|
||||
|
||||
## Decisions
|
||||
|
||||
### 决策 1: 使用现有 CSS 变量系统,不引入新的样式规范
|
||||
|
||||
**理由**:
|
||||
- 项目已有完整的 CSS 变量系统(`Web/src/assets/theme.css`)
|
||||
- 日历和统计页面已部分使用该系统
|
||||
- 避免引入新的样式标准增加维护成本
|
||||
|
||||
**替代方案**:
|
||||
- ❌ 创建全新的样式规范:增加学习成本,与现有系统冲突
|
||||
- ❌ 使用 Tailwind CSS:项目未使用 Tailwind,引入成本过高
|
||||
- ✅ 统一使用现有 CSS 变量:保持一致性,最小化改动
|
||||
|
||||
### 决策 2: 定义标准的卡片样式值
|
||||
|
||||
**标准值**(基于现有变量和最佳实践):
|
||||
```scss
|
||||
// 卡片容器样式
|
||||
.common-card {
|
||||
background: var(--bg-secondary);
|
||||
border-radius: var(--radius-lg); // 12px
|
||||
padding: var(--spacing-xl); // 16px
|
||||
margin-bottom: var(--spacing-xl); // 16px
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
|
||||
// 卡片间距(页面级别)
|
||||
.page-cards-container {
|
||||
padding: var(--spacing-xl); // 16px (左右)
|
||||
padding-top: var(--spacing-md); // 12px (顶部,紧跟 header)
|
||||
padding-bottom: var(--spacing-3xl); // 24px (底部,预留安全区)
|
||||
gap: var(--spacing-xl); // 16px (卡片之间)
|
||||
}
|
||||
```
|
||||
|
||||
**理由**:
|
||||
- `var(--spacing-xl)` (16px) 在移动端提供舒适的点击区域
|
||||
- `var(--radius-lg)` (12px) 符合现代移动端设计趋势
|
||||
- `var(--shadow-sm)` 提供微妙的层次感,不会过于突兀
|
||||
|
||||
**替代方案**:
|
||||
- ❌ padding: 12px - 太紧凑,触控体验差
|
||||
- ❌ padding: 20px - 浪费屏幕空间
|
||||
- ✅ padding: 16px - 平衡美观与空间利用
|
||||
|
||||
### 决策 3: 渐进式迁移策略
|
||||
|
||||
**步骤**:
|
||||
1. 在受影响的文件中查找硬编码的样式值(如 `padding: 16px`, `border-radius: 12px`)
|
||||
2. 替换为对应的 CSS 变量(如 `padding: var(--spacing-xl)`, `border-radius: var(--radius-lg)`)
|
||||
3. 确保 `.common-card` 类在所有卡片上统一应用
|
||||
4. 验证暗色模式和不同屏幕尺寸下的显示效果
|
||||
|
||||
**理由**:
|
||||
- 最小化风险,逐文件验证
|
||||
- 不引入破坏性变更
|
||||
- 易于回滚
|
||||
|
||||
**替代方案**:
|
||||
- ❌ 一次性全局替换:风险高,难以定位问题
|
||||
- ❌ 创建新组件并迁移:工作量大,超出本次范围
|
||||
- ✅ 文件级逐步替换:可控、安全、可追溯
|
||||
|
||||
### 决策 4: 不创建全局共享样式文件(暂不引入)
|
||||
|
||||
**理由**:
|
||||
- 当前三个页面的样式文件已经独立且清晰
|
||||
- 引入共享样式文件会增加依赖关系
|
||||
- 留待后续如果需要更多页面统一时再考虑
|
||||
|
||||
**替代方案**:
|
||||
- ❌ 立即创建 `common-card.scss` 并全局导入:过度设计
|
||||
- ✅ 保持现状,但确保使用相同的 CSS 变量值:简单高效
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
### [风险] 样式改动可能导致布局轻微变化
|
||||
**缓解措施**:
|
||||
- 在多个设备和屏幕尺寸下进行视觉回归测试
|
||||
- 重点检查内容溢出、文字截断、图表显示问题
|
||||
- 必要时微调内部元素的间距
|
||||
|
||||
### [风险] CSS 变量未定义导致样式回退
|
||||
**缓解措施**:
|
||||
- 确认 `theme.css` 中所有使用的变量已定义
|
||||
- 在替换前验证变量的计算值是否符合预期
|
||||
- 为关键样式提供 fallback 值(如 `padding: var(--spacing-xl, 16px)`)
|
||||
|
||||
### [风险] 暗色模式下视觉效果不一致
|
||||
**缓解措施**:
|
||||
- 测试所有卡片在暗色模式下的背景色、阴影、边框表现
|
||||
- 确保 `var(--bg-secondary)` 和 `var(--shadow-sm)` 在暗色模式下有正确定义
|
||||
|
||||
### [权衡] 短期内仍需手动维护样式一致性
|
||||
**说明**:
|
||||
- 本次不创建通用 Card 组件,未来新增卡片时仍需手动应用 `.common-card` 类
|
||||
- 后续可考虑将其封装为 Vue 组件(如 `<CommonCard>`)
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. **是否需要在 `theme.css` 中新增卡片专用的变量组**?
|
||||
- 例如 `--card-padding`, `--card-radius`, `--card-shadow`
|
||||
- 优势:语义更清晰,方便未来全局调整
|
||||
- 劣势:增加变量数量,可能产生冗余
|
||||
- **建议**:暂不新增,优先使用现有 `--spacing-*` 和 `--radius-*` 变量
|
||||
|
||||
2. **是否需要为特殊卡片(如 gauge 卡片)定义例外规则**?
|
||||
- BudgetChartAnalysis 中的 gauge 卡片当前使用 `padding: 12px`
|
||||
- **建议**:保持 12px,因为仪表盘需要更紧凑的布局以适应图表
|
||||
@@ -0,0 +1,39 @@
|
||||
## Why
|
||||
|
||||
当前日历、统计、预算三个核心页面的卡片样式(边距、间距、圆角等)存在不一致,导致用户在不同页面间切换时感知到设计不统一,影响整体使用体验。统一这些基础样式将提升应用的专业性和视觉一致性。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 统一三个页面(calendarV2、statisticsV2、budgetV2)的卡片基础样式
|
||||
- 标准化卡片的 padding、margin、border-radius、box-shadow 等属性
|
||||
- 建立全局可复用的卡片样式系统(CSS 变量或共享样式类)
|
||||
- 确保卡片间距在移动端的最佳显示效果
|
||||
- 保持暗色模式下的样式一致性
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `unified-card-styles`: 定义统一的卡片基础样式规范,包括边距、间距、圆角、阴影等视觉属性的标准值
|
||||
|
||||
### Modified Capabilities
|
||||
<!-- 此次变更仅涉及样式统一,不改变现有功能需求 -->
|
||||
|
||||
## Impact
|
||||
|
||||
**受影响的文件**:
|
||||
- `Web/src/views/calendarV2/modules/Stats.vue` - 日历页面统计卡片
|
||||
- `Web/src/views/statisticsV2/modules/MonthlyExpenseCard.vue` - 统计页面收支卡片
|
||||
- `Web/src/views/statisticsV2/modules/ExpenseCategoryCard.vue` - 统计页面分类卡片
|
||||
- `Web/src/views/statisticsV2/modules/IncomeNoneCategoryCard.vue` - 统计页面收入/不计收支卡片
|
||||
- `Web/src/components/Budget/BudgetChartAnalysis.vue` - 预算页面图表分析卡片
|
||||
|
||||
**样式差异分析**:
|
||||
- **日历页面**: padding: `var(--spacing-2xl)` (Stats.vue:140), border-radius: `var(--radius-lg)`, gap: `var(--spacing-3xl)`
|
||||
- **统计页面**: padding: `var(--spacing-xl)` (common-card), border-radius: `var(--radius-lg)`, margin-bottom: `var(--spacing-xl)`
|
||||
- **预算页面**: padding: `16px` / `12px`(混用), border-radius: `12px`, gap/margin: `12px`
|
||||
|
||||
**系统影响**:
|
||||
- 纯视觉层面修改,不涉及功能逻辑
|
||||
- 不影响 API 或数据层
|
||||
- 可能需要微调布局以适应统一后的间距
|
||||
- 需要在不同屏幕尺寸和暗色模式下测试
|
||||
@@ -0,0 +1,103 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Card containers SHALL use unified spacing values
|
||||
|
||||
所有卡片容器必须使用统一的 CSS 变量来定义内边距(padding),确保视觉一致性。
|
||||
|
||||
#### Scenario: Standard card padding
|
||||
- **WHEN** 渲染任何卡片组件
|
||||
- **THEN** 卡片的 padding 必须使用 `var(--spacing-xl)`(16px)
|
||||
|
||||
#### Scenario: Gauge card compact padding
|
||||
- **WHEN** 渲染仪表盘类型的卡片(gauge card)
|
||||
- **THEN** 卡片的 padding 可以使用 `var(--spacing-lg)`(12px)以适应紧凑布局
|
||||
|
||||
### Requirement: Card containers SHALL use unified border radius
|
||||
|
||||
所有卡片容器必须使用统一的 CSS 变量来定义圆角(border-radius),保持设计语言一致。
|
||||
|
||||
#### Scenario: Standard card border radius
|
||||
- **WHEN** 渲染任何卡片组件
|
||||
- **THEN** 卡片的 border-radius 必须使用 `var(--radius-lg)`(12px)
|
||||
|
||||
### Requirement: Card containers SHALL use unified background color
|
||||
|
||||
所有卡片容器必须使用统一的背景色变量,确保在明暗模式下自动适配。
|
||||
|
||||
#### Scenario: Card background in light mode
|
||||
- **WHEN** 应用处于明亮模式
|
||||
- **THEN** 卡片的 background 必须使用 `var(--bg-secondary)`
|
||||
|
||||
#### Scenario: Card background in dark mode
|
||||
- **WHEN** 应用处于暗色模式
|
||||
- **THEN** 卡片的 background 必须使用 `var(--bg-secondary)` 并自动适配为暗色系背景
|
||||
|
||||
### Requirement: Card containers SHALL use unified shadow
|
||||
|
||||
所有卡片容器必须使用统一的阴影变量,提供微妙的层次感。
|
||||
|
||||
#### Scenario: Standard card shadow
|
||||
- **WHEN** 渲染任何卡片组件
|
||||
- **THEN** 卡片的 box-shadow 必须使用 `var(--shadow-sm)`
|
||||
|
||||
#### Scenario: Card shadow in dark mode
|
||||
- **WHEN** 应用处于暗色模式
|
||||
- **THEN** 卡片的阴影必须根据暗色模式自动调整透明度和颜色
|
||||
|
||||
### Requirement: Card spacing SHALL be consistent across pages
|
||||
|
||||
页面级别的卡片布局必须使用统一的外边距(margin)和间距(gap),确保三个页面的视觉韵律一致。
|
||||
|
||||
#### Scenario: Card bottom margin
|
||||
- **WHEN** 在页面中垂直排列多个卡片
|
||||
- **THEN** 卡片之间的间距必须使用 `var(--spacing-xl)`(16px)或通过父容器的 gap 属性设置
|
||||
|
||||
#### Scenario: Page container padding
|
||||
- **WHEN** 渲染包含卡片的页面容器
|
||||
- **THEN** 容器的左右 padding 必须使用 `var(--spacing-xl)`(16px)
|
||||
- **AND** 容器的顶部 padding 可以使用 `var(--spacing-md)`(12px)以紧跟 header
|
||||
- **AND** 容器的底部 padding 应使用 `var(--spacing-3xl)`(24px)以预留安全区域
|
||||
|
||||
### Requirement: Hard-coded style values MUST be replaced
|
||||
|
||||
现有代码中的硬编码样式值必须被对应的 CSS 变量替换,以便集中管理和未来维护。
|
||||
|
||||
#### Scenario: Replace hard-coded padding
|
||||
- **WHEN** 发现卡片使用硬编码的 `padding: 16px` 或 `padding: 12px`
|
||||
- **THEN** 必须替换为 `padding: var(--spacing-xl)` 或 `padding: var(--spacing-lg)`
|
||||
|
||||
#### Scenario: Replace hard-coded border-radius
|
||||
- **WHEN** 发现卡片使用硬编码的 `border-radius: 12px`
|
||||
- **THEN** 必须替换为 `border-radius: var(--radius-lg)`
|
||||
|
||||
#### Scenario: Replace hard-coded margins and gaps
|
||||
- **WHEN** 发现卡片或容器使用硬编码的 `margin-bottom: 12px` 或 `gap: 12px`
|
||||
- **THEN** 必须替换为 `margin-bottom: var(--spacing-xl)` 或 `gap: var(--spacing-xl)`
|
||||
|
||||
### Requirement: Common card class SHALL be consistently applied
|
||||
|
||||
所有符合标准卡片样式的元素必须应用 `.common-card` 类或内联使用相同的 CSS 变量组合。
|
||||
|
||||
#### Scenario: Apply common-card class
|
||||
- **WHEN** 创建或修改卡片组件
|
||||
- **THEN** 卡片的根元素应添加 `class="common-card"` 或在 scoped style 中定义 `.common-card` 样式
|
||||
|
||||
#### Scenario: Inline CSS variable usage
|
||||
- **WHEN** 不使用 `.common-card` 类时
|
||||
- **THEN** 必须确保使用与 `.common-card` 相同的 CSS 变量组合(background, border-radius, padding, box-shadow)
|
||||
|
||||
### Requirement: Visual regression testing MUST verify style consistency
|
||||
|
||||
样式统一后必须通过视觉测试验证三个页面的卡片表现一致。
|
||||
|
||||
#### Scenario: Test in light mode
|
||||
- **WHEN** 应用处于明亮模式
|
||||
- **THEN** 日历、统计、预算页面的卡片样式必须在视觉上保持一致(相同的边距、圆角、阴影)
|
||||
|
||||
#### Scenario: Test in dark mode
|
||||
- **WHEN** 应用处于暗色模式
|
||||
- **THEN** 日历、统计、预算页面的卡片样式必须在视觉上保持一致(相同的边距、圆角、阴影,且背景色和阴影自动适配)
|
||||
|
||||
#### Scenario: Test on different screen sizes
|
||||
- **WHEN** 在不同移动设备屏幕尺寸上查看(如 iPhone SE, iPhone 14 Pro, iPad mini)
|
||||
- **THEN** 卡片布局不能出现溢出、内容截断或错位问题
|
||||
@@ -0,0 +1,66 @@
|
||||
## 1. 验证 CSS 变量基础
|
||||
|
||||
- [x] 1.1 确认 `Web/src/assets/theme.css` 中所有需要使用的 CSS 变量已定义(`--spacing-xl`, `--spacing-lg`, `--spacing-md`, `--spacing-3xl`, `--radius-lg`, `--bg-secondary`, `--shadow-sm`)
|
||||
- [x] 1.2 在浏览器开发者工具中验证 CSS 变量在明亮模式和暗色模式下的计算值
|
||||
- [x] 1.3 为关键变量添加 fallback 值以防止未定义变量导致的样式回退
|
||||
|
||||
## 2. 统一日历页面卡片样式
|
||||
|
||||
- [x] 2.1 在 `Web/src/views/calendarV2/modules/Stats.vue` 中检查 `.stats-card` 样式(line 136-143)
|
||||
- [x] 2.2 确认 padding 使用 `var(--spacing-xl)` 替代 `var(--spacing-2xl)`(如果不一致)
|
||||
- [x] 2.3 确认 border-radius 使用 `var(--radius-lg)`
|
||||
- [x] 2.4 确认 background-color 使用 `var(--bg-secondary)`
|
||||
- [x] 2.5 添加 box-shadow: `var(--shadow-sm)` 如果缺失
|
||||
- [x] 2.6 检查 `.daily-stats` 容器的 padding 和 gap 是否使用统一变量
|
||||
|
||||
## 3. 统一统计页面卡片样式
|
||||
|
||||
- [x] 3.1 在 `Web/src/views/statisticsV2/modules/MonthlyExpenseCard.vue` 中检查 `.common-card` 样式(line 358-364)
|
||||
- [x] 3.2 确认所有样式属性使用 CSS 变量(padding, border-radius, margin-bottom, box-shadow)
|
||||
- [x] 3.3 在 `Web/src/views/statisticsV2/modules/ExpenseCategoryCard.vue` 中检查 `.common-card` 样式(line 369-377)
|
||||
- [x] 3.4 确认样式与 MonthlyExpenseCard 保持一致
|
||||
- [x] 3.5 在 `Web/src/views/statisticsV2/modules/IncomeNoneCategoryCard.vue` 中检查 `.common-card` 样式(line 157-164)
|
||||
- [x] 3.6 确认 `.side-by-side-cards .common-card` 的 padding 调整为 `var(--spacing-lg)` 或 `var(--spacing-xl)` 以保持一致
|
||||
- [x] 3.7 检查所有卡片的 margin-bottom 或父容器的 gap 属性使用 `var(--spacing-xl)`
|
||||
|
||||
## 4. 统一预算页面卡片样式
|
||||
|
||||
- [x] 4.1 在 `Web/src/components/Budget/BudgetChartAnalysis.vue` 中查找所有硬编码的 padding 值(如 `16px`, `12px`)
|
||||
- [x] 4.2 将标准卡片的 `padding: 16px` 替换为 `padding: var(--spacing-xl)`(line 892)
|
||||
- [x] 4.3 将 gauge 卡片的 `padding: 12px` 替换为 `padding: var(--spacing-lg)`(line 900)
|
||||
- [x] 4.4 将硬编码的 `border-radius: 12px` 替换为 `border-radius: var(--radius-lg)`(line 891)
|
||||
- [x] 4.5 检查 `.chart-analysis-container` 的 padding 值,确保使用 `var(--spacing-xl)`(line 879)
|
||||
- [x] 4.6 将 `.gauges-row` 的 `gap: 12px` 和 `margin-bottom: 12px` 替换为 `var(--spacing-xl)`(line 885-886)
|
||||
- [x] 4.7 检查其他内联 style 属性(如 line 135: `style="margin-top: 12px"`)并替换为 CSS 变量
|
||||
|
||||
## 5. 确保 .common-card 类的一致性
|
||||
|
||||
- [x] 5.1 确认所有统计页面的卡片根元素都应用了 `.common-card` 类
|
||||
- [x] 5.2 确认预算页面的 `.chart-card` 使用与 `.common-card` 相同的 CSS 变量组合
|
||||
- [x] 5.3 确认日历页面的 `.stats-card` 使用与 `.common-card` 相同的 CSS 变量组合
|
||||
- [x] 5.4 考虑是否需要在各文件中显式定义 `.common-card` 样式或依赖全局样式
|
||||
|
||||
## 6. 视觉回归测试
|
||||
|
||||
- [x] 6.1 在明亮模式下测试日历页面,验证卡片样式无异常
|
||||
- [x] 6.2 在明亮模式下测试统计页面,验证所有卡片样式一致
|
||||
- [x] 6.3 在明亮模式下测试预算页面,验证所有图表卡片样式一致
|
||||
- [x] 6.4 在暗色模式下重复上述测试(6.1-6.3),验证背景色和阴影自动适配
|
||||
- [x] 6.5 在 iPhone SE 小屏幕上测试,确认无内容溢出或截断
|
||||
- [x] 6.6 在 iPhone 14 Pro 标准屏幕上测试,确认布局合理
|
||||
- [x] 6.7 在 iPad mini 平板上测试,确认响应式布局正常
|
||||
|
||||
## 7. 代码审查与文档更新
|
||||
|
||||
- [x] 7.1 使用 `grep -r "padding: [0-9]" Web/src/views/{calendarV2,statisticsV2,budgetV2}` 查找遗漏的硬编码值
|
||||
- [x] 7.2 使用 `grep -r "border-radius: [0-9]" Web/src/views/{calendarV2,statisticsV2,budgetV2}` 查找遗漏的硬编码值
|
||||
- [x] 7.3 使用 `grep -r "margin.*: [0-9]" Web/src/views/{calendarV2,statisticsV2,budgetV2}` 查找遗漏的硬编码值
|
||||
- [x] 7.4 运行 `pnpm lint` 确保代码风格符合项目规范
|
||||
- [x] 7.5 在 `.doc/` 目录下创建 `card-style-standards.md` 文档记录统一的卡片样式规范(可选)
|
||||
- [x] 7.6 提交代码前进行 self-review,确保没有遗漏的硬编码值
|
||||
|
||||
## 8. 提交与归档
|
||||
|
||||
- [x] 8.1 创建 git commit,提交消息:`style: unify card styles across calendar, statistics, and budget pages`
|
||||
- [x] 8.2 验证所有测试通过,布局无异常
|
||||
- [x] 8.3 运行 `/opsx-archive` 将本次 change 归档到主规范
|
||||
Reference in New Issue
Block a user