Просмотр исходного кода

docs: DimensionWeightPicker 重设计规格文档

Sisyphus 4 месяцев назад
Родитель
Сommit
4300fdd2f6
1 измененных файлов с 109 добавлено и 0 удалено
  1. 109 0
      docs/superpowers/specs/2026-07-02-dimension-weight-picker-redesign.md

+ 109 - 0
docs/superpowers/specs/2026-07-02-dimension-weight-picker-redesign.md

@@ -0,0 +1,109 @@
+# DimensionWeightPicker 重设计
+
+## 1. 背景
+
+现有 `DimensionWeightPicker.vue` 采用 checkbox 选择维度 + slider 调整权重的组合,存在两个体验问题:
+
+1. checkbox + slider 双控件增加认知负担,交互路径不直观
+2. slider 可自由拖动超过 100%,总和无法约束,用户反复调整才能合规
+
+用户要求:**滑动条 + 数字输入框,拖动条表示对应维度分配比例,全部比例之和不超过 100%**。
+
+## 2. 设计方案
+
+### 2.1 交互规则
+
+- **无 checkbox**:设值 > 0 即视为启用,设为 0 即禁用
+- **滑动条上限动态锁定**:每个 slider 的 `max` = `100 - Σ(其他已启用维度的当前值)`
+  - 用户拖动到最大限度后无法继续,不会超 100%
+- **数字输入框同步**:与 slider 双向绑定,超限自动 clamp 到 max 值
+- **总和提示**:底部显示当前合计,超 100% 显示红色警告(实际不会发生)
+
+### 2.2 数据契约
+
+Props `value` 格式不变(向后兼容):
+```js
+value: [{ dimension: 'body', weight: 25, enabled: true }, ...]
+```
+
+emit 格式也不变:
+```js
+this.$emit('input', [{ dimension: 'body', weight: 25, enabled: true }, ...])
+```
+
+### 2.3 UI 布局
+
+每行:`[维度名称] [滑动条━━━━━━━━●━━━━] [数字输入]`
+- 维度名称含颜色标识(品牌五维色)
+- 滑动条宽度自适应
+- 数字输入框固定宽度 60px,末尾带 `%` 单位
+- 底部合计行 + 快捷预设按钮(保留)
+
+### 2.4 组件样式
+
+```vue
+身·土  [━━━━━━━━━━●━━━]  30%    ← max=100-0=100
+智·金  [━━━━━━━━●━━━━━━]  20%    ← max=100-30=70
+行·木  [━━━━━━━━━━━━━━━]   0%    ← max=100-50=50(灰色禁用)
+富·水  [━━━━━━━━━━━━━━━]   0%
+心·火  [━━━━━━━━━━━━━━━]   0%
+                        合计: 50%
+```
+
+### 2.5 预设快捷
+
+| 预设 | body | mind | action | wealth | heart |
+|------|------|------|--------|--------|-------|
+| 均衡 | 20 | 20 | 20 | 20 | 20 |
+| 偏身 | 40 | 15 | 15 | 15 | 15 |
+| 偏智 | 15 | 40 | 15 | 15 | 15 |
+| 偏行 | 15 | 15 | 40 | 15 | 15 |
+| 偏富 | 15 | 15 | 15 | 40 | 15 |
+| 偏心 | 15 | 15 | 15 | 15 | 40 |
+
+预设一键应用,重新计算每个 slider 的 max 值。
+
+## 3. 实现要点
+
+### 3.1 动态 max 计算
+
+```js
+getMaxForDim(code) {
+  const otherTotal = this.dimensions
+    .filter(d => d.code !== code && d.currentValue > 0)
+    .reduce((sum, d) => sum + d.currentValue, 0)
+  return 100 - otherTotal
+}
+```
+
+### 3.2 双向绑定处理
+
+- slider change → 更新 `currentValue` → recalculate all maxes → emit
+- input change → 更新 `currentValue` → recalculate all maxes → emit
+
+### 3.3 数字输入框校验
+
+- 输入 < 0 → clamp 到 0
+- 输入 > max → clamp 到 max
+- 输入非数字 → 忽略
+
+### 3.4 禁用状态
+
+`currentValue === 0` 的维度 slider 显示灰色且 `disabled=true`,其他维度正常可调。
+
+## 4. 影响范围
+
+- `cfc-web/src/components/DimensionWeightPicker.vue` — 重写核心实现
+- `cfc-web/src/views/admin/Activities.vue` — 用到该组件,无需改动
+- `cfc-web/src/views/admin/ArticleEdit.vue` — 用到该组件,无需改动
+- `cfc-web/src/views/admin/EnergyRuleManagement.vue` — 用到该组件,无需改动
+
+## 5. 成功标准
+
+- [x] 5 个维度各有一个 slider + 数字输入框
+- [x] 任意 slider 拖动不能超过 100%,动态 max 生效
+- [x] 数字输入框与 slider 双向同步
+- [x] 总和显示正确,超标时红色警告
+- [x] 预设快捷按钮正常工作
+- [x] 与父组件的 value props / emit 接口保持兼容
+- [x] 样式与现有 Element UI 风格一致