2026-07-02-dimension-weight-picker-redesign.md 3.7 KB

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 格式不变(向后兼容):

value: [{ dimension: 'body', weight: 25, enabled: true }, ...]

emit 格式也不变:

this.$emit('input', [{ dimension: 'body', weight: 25, enabled: true }, ...])

2.3 UI 布局

每行:[维度名称] [滑动条━━━━━━━━●━━━━] [数字输入]

  • 维度名称含颜色标识(品牌五维色)
  • 滑动条宽度自适应
  • 数字输入框固定宽度 60px,末尾带 % 单位
  • 底部合计行 + 快捷预设按钮(保留)

2.4 组件样式

身·土  [━━━━━━━━━━●━━━]  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 计算

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. 成功标准

  • 5 个维度各有一个 slider + 数字输入框
  • 任意 slider 拖动不能超过 100%,动态 max 生效
  • 数字输入框与 slider 双向同步
  • 总和显示正确,超标时红色警告
  • 预设快捷按钮正常工作
  • 与父组件的 value props / emit 接口保持兼容
  • 样式与现有 Element UI 风格一致