# 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 风格一致