优化细节

This commit is contained in:
2026-02-05 17:11:41 +08:00
parent 821205b18a
commit 151f5a5e1a
10 changed files with 634 additions and 194 deletions

View File

@@ -25,6 +25,100 @@
4. 使用 `minmax(0, 1fr)` 配分子项 `min-width: 0` 确保在任何容器宽度下网格不被撑爆。
- **强制规则**: 任何页面都不允许出现一行 3 个卡片的情况。
#### **原因十三:侧边栏响应式断点与 Overlay 冲突 (严重体验红线)**
- **现象**: 在 770px~1005px 宽度下,侧边栏遮挡内容,或内容区没有正确让出空间。
- **原因**:
1. 断点逻辑不统一:`main` 布局计算与组件显隐逻辑使用了不同的宽度阈值。
2. 动画不匹配:内容区 `margin-left` 动画时长与侧栏 `transform` 时长不一致。
3. 状态残留:跨断点时没有强制重置 Overlay 状态。
- **1:1 复刻 CRMEB 解决方案**:
1. **明确三段断点策略**:
- **Desktop (>=1200px)**: `aside=dock`, `subSider=dock` (如果开启)。`mainLeft = 270px`
- **Tablet (768px-1199px)**: `aside=dock`, `subSider=overlay` (带 mask)。`mainLeft = 70px`
- **Mobile (<768px)**: `aside=overlay`, `subSider=overlay``mainLeft = 0px`
2. **统一状态机**: 使用 `layoutMode` (desktop/tablet/mobile) 驱动所有组件渲染,而非散乱的媒体查询。
3. **计算属性驱动布局**: `mainLeft` 必须严格根据 `layoutMode``subSider` 的 Dock/Overlay 属性动态计算。
4. **跨断点清理**: 在 `onWindowResize` 监听到模式切换时,立即强制关闭所有 Overlay (mask=false),防止残影遮挡。
5. **指针事件隔离**: 隐藏态侧栏必须显式设置 `pointer-events: none``visibility: hidden`
#### **原因十四KPI 统计概况列数不一致 (CRMEB 像素级规范)**
- **现象**: 统计概况在大屏下显示 4 列或 5 列,导致无法一行平铺 6 个核心指标。
- **解决方案 (6-2-1 规则)**:
1. 使用全局类 `.kpi-grid-6` 实现专用的统计概况布局。
2. **强制断点**:
- `> 1200px`: 固定 6 列 (`repeat(6, minmax(0, 1fr))`)。
- `768px - 1199.98px`: 固定 2 列。
- `< 768px`: 固定 1 列。
3. **侧栏联动**: 当 `viewport < 768px` 时,布局容器必须切换到移动端模式(主侧栏变为 OverlaymainLeft 归零),确保 1 列布局拥有最大水平空间。
#### **原因十五ECharts 图表响应式裁切与视觉偏位**
- **现象**: 窗口缩小时饼图被砍掉一半,或在大屏下视觉不居中、底部不对齐。
- **原因**:
1. 使用了固定高度(如 `height: 521px`)而没有弹性容器。
2. ECharts 的 `center``radius` 使用了静态百分比或固定像素,无法适配极端宽高比。
3. 仅依赖 `window.resize` 而没有监听“容器级”尺寸变化(如侧边栏折叠导致的局部宽度变化)。
- **解决方案**:
1. **容器加固**: 移除根组件固定高度,改用 `min-height`;卡片内容区设置 `overflow: visible` 防止裁切。
2. **像素级算法**: 禁止在 `option` 中直接硬编码 `['50%', '60%']`,应计算:`outerRadius = min(w, h) * 0.38``centerY = legendSpace + (h - legendSpace) / 2`
3. **双重自适应**:
- **底层**: 使用 `ResizeObserver` 监听容器级 DOM 变化。
- **上层**: 监听 `store` 中的侧边栏状态,在动画结束后强制触发 `refreshSize()`
4. **文字同步**: 中间文字total-value必须通过 `computed` 样式与饼图中心点像素级同步。
5. **架构建议**: 在 UTS 环境下,涉及 ECharts 等需要向 RenderJS 传递复杂 Object 的组件,**优先使用 Options API**。Options API 在处理 `toPlainObject` 转换及 Prop 传递时具备更稳定的兼容性,可避免 `script setup` 下可能出现的对象元数据干扰。
#### **原因十六ECharts 响应式失效与百分比布局规范**
- **现象**: 侧边栏折叠时图表不缩小导致溢出,或在不同宽高比下圆环变形/裁切。
- **原因**:
1. 使用了固定的像素值定义 `radius``center`
2. 容器高度依赖父级 `flex` 且未设置 `min-height`,导致某些极端高度下被折叠。
3. 缺乏对动画中间态的捕获。
- **强制解决方案 (Web/uni-app-x)**:
1. **百分比优先**: `radius` 必须使用百分比(如 `['55%', '75%']``center` 必须使用百分比。
2. **高度钳制**: 容器使用 `height: clamp(...)` 或固定高度(如 `520px`+ `min-height`
3. **全链路 Resize**:
- `ResizeObserver` 监听 DOM 容器变化。
- `transitionend` 监听侧边栏动画结束。
- `watch` 监听全局布局状态(`layoutMode` / `collapsed`)。
4. **裁切隔离**: 所有祖先容器、`ec-wrap``ec-canvas` 必须显式设置 `overflow: visible !important`
#### **原因十七ECharts 画布溢出与容器约束 (Containing Block 丢失)**
- **现象**: `ec-canvas` (uni-view) 拥有极大的 `width/height` (如 948px) 且 `position: absolute`,但脱离了父级卡片,溢出到整个页面,且图表内容消失。
- **原因**:
1. **层叠上下文丢失**: `ec-canvas` 的父组件或 `EChartsView` 根节点未设置 `position: relative`,导致 absolute 元素相对于 `body` 定位。
2. **尺寸初始化瓶颈**: 在父容器高度为 0 (如 `flex` 自动压缩) 或动画中间态初始化 ECharts导致内部 `canvas` 宽高计算错误。
- **强制解决方案**:
1. **修正 Containing Block (Step 1)**:
- 容器(`chart-wrap`)必须显式设置 `position: relative !important`
- 使用 `:deep()` 强制约束子组件:`.ec-wrap { position: relative; } .ec-canvas { position: absolute; inset: 0; width: 100% !important; height: 100% !important; }`
2. **确定性高度策略 (Step 2)**:
- 图表容器禁止高度塌陷。使用 `height: clamp(min, preferred, max)` 或固定高度。
- 示例:`height: clamp(280px, 40vh, 450px); min-height: 280px;`
3. **Resize 闭环链路 (Step 3)**:
- 禁止使用 `setTimeout` 盲猜。
- 必须使用 `ResizeObserver` 监听 `chart-wrap` 尺寸变化。
- 必须监听 `sidebar``transitionend` 事件,确保侧边栏动画结束后的布局稳定。
- 统一使用 `requestAnimationFrame(() => chart.resize())` 确保在下一次重绘前完成布局对齐。
4. **百分比布局 (Step 4)**:
- `series.pie``radius``center` 必须使用百分比形式,杜绝 px 导致的自适应失败。
#### **原因十八CRMEB 响应式断点与图表重构规范 (1:1 复刻)**
- **现象**: 在 1200px 断点切换时布局生硬,图表在单列模式下比例过小或中心偏移。
- **解决方案**:
1. **Grid 布局容器**: 容器页面必须使用 CSS Grid 定义 `grid-template-columns: 2fr 1fr` (>=1200) 和 `1fr` (<1200),避免 flex 宽度计算误差。
2. **外部图例隔离**: 为保证 ECharts 渲染空间的确定性,禁止使用内置 `legend`。改为 `flex-direction: row` 的外部 `legend-col`,确保左上角图例与右侧饼图互不干扰。
3. **确定性中心同步**:
- ECharts `center` 设置为 `['50%', '50%']`
- 中心文字组件使用绝对定位 `top:50%; left:50%; transform:translate(-50%,-50%)` 实现物理像素级对齐。
4. **两档响应式高度**:
- `chart-col` 在桌面端 (>=1200) 使用中等高度 (约 320-360px)。
- 在移动端/窄屏 (<1200) 自动扩展为大高度 (约 500-600px),以匹配全宽展示的视觉张力。
## 🛠️ 完整修复流程
```