# Frontend 角色信息与计算结果展示链路专项分析 ## 1. 分析范围与假设 - 范围仅覆盖 frontend。 - 本文重点是角色信息与计算结果展示链路,补充分列布局、联动逻辑、异常反馈与改造建议。 - 职业上下文由路由参数 alter 驱动,计算请求统一走 /calc。 核心入口证据: - 路由入口与职业参数:[frontend/src/router/index.ts](frontend/src/router/index.ts#L13) - 结果面板挂载位置:[frontend/src/pages/Character/Index.vue](frontend/src/pages/Character/Index.vue#L18) - 计算请求入口:[frontend/src/api/calc/index.ts](frontend/src/api/calc/index.ts#L7) ## 2. 模块清单与职责映射 ### 2.1 主流程文件 - 角色页主容器(输入区 + 结果区 + 开关区):[frontend/src/pages/Character/Index.vue](frontend/src/pages/Character/Index.vue) - 结果容器(Info 与 Skill/BufferSkill 分支):[frontend/src/pages/Character/Result/Index.vue](frontend/src/pages/Character/Result/Index.vue) - 角色信息渲染组件: [frontend/src/pages/Character/Result/components/Info.vue](frontend/src/pages/Character/Result/components/Info.vue) - 输出职业结果组件: [frontend/src/pages/Character/Result/components/Skill.vue](frontend/src/pages/Character/Result/components/Skill.vue) - 辅助职业结果组件: [frontend/src/pages/Character/Result/components/BufferSkill.vue](frontend/src/pages/Character/Result/components/BufferSkill.vue) ### 2.2 数据与状态 - 配置输入与计算执行: [frontend/src/stores/config.ts](frontend/src/stores/config.ts#L236) - 角色基础信息与职业上下文: [frontend/src/stores/info.ts](frontend/src/stores/info.ts#L9) - 结果数据类型(skills/info/suits/buffer): [frontend/src/api/calc/type.ts](frontend/src/api/calc/type.ts#L3) ## 3. 角色信息与计算结果展示链路 ### 3.1 触发到计算 1. 用户在装备、技能、打造区域改动配置后,主容器监听 config 变化。 - 证据: [frontend/src/pages/Character/Index.vue](frontend/src/pages/Character/Index.vue#L61) 2. 监听回调触发 execute,进入异步计算流程。 - 证据: [frontend/src/pages/Character/Index.vue](frontend/src/pages/Character/Index.vue#L70) 3. config store 调用 calc,向 /calc 提交 IConfig。 - 证据: [frontend/src/stores/config.ts](frontend/src/stores/config.ts#L236) - 证据: [frontend/src/api/calc/index.ts](frontend/src/api/calc/index.ts#L7) ### 3.2 计算结果入仓与消费 1. 结果写入 result.state,结构包含 skills、info、suits、buffer。 - 证据: [frontend/src/stores/config.ts](frontend/src/stores/config.ts#L260) - 证据: [frontend/src/api/calc/type.ts](frontend/src/api/calc/type.ts#L3) - 证据: [frontend/src/api/calc/type.ts](frontend/src/api/calc/type.ts#L4) - 证据: [frontend/src/api/calc/type.ts](frontend/src/api/calc/type.ts#L5) - 证据: [frontend/src/api/calc/type.ts](frontend/src/api/calc/type.ts#L10) 2. 角色信息由 Info 组件消费并渲染 info 列表。 - 证据(绑定入口): [frontend/src/pages/Character/Result/Index.vue](frontend/src/pages/Character/Result/Index.vue#L25) - 证据(渲染循环): [frontend/src/pages/Character/Result/components/Info.vue](frontend/src/pages/Character/Result/components/Info.vue#L13) - 证据(字段定义): [frontend/src/api/calc/type.ts](frontend/src/api/calc/type.ts#L27) 3. 技能结果根据 buffer 分支渲染 Skill 或 BufferSkill。 - 证据(普通输出): [frontend/src/pages/Character/Result/Index.vue](frontend/src/pages/Character/Result/Index.vue#L35) - 证据(辅助输出): [frontend/src/pages/Character/Result/Index.vue](frontend/src/pages/Character/Result/Index.vue#L40) ## 4. 分列布局与联动逻辑 ### 4.1 顶层分列 - 角色页中部为双列:左列 RouterView 输入,右列 Result 输出。 - 证据: [frontend/src/pages/Character/Index.vue](frontend/src/pages/Character/Index.vue#L10) - 证据: [frontend/src/pages/Character/Index.vue](frontend/src/pages/Character/Index.vue#L15) - 证据: [frontend/src/pages/Character/Index.vue](frontend/src/pages/Character/Index.vue#L18) ### 4.2 结果区分列 - 结果容器内部再次分列:左侧 Info(角色信息与穿戴信息),右侧 Skill/BufferSkill(技能结果)。 - 证据: [frontend/src/pages/Character/Result/Index.vue](frontend/src/pages/Character/Result/Index.vue#L1) - 证据: [frontend/src/pages/Character/Result/Index.vue](frontend/src/pages/Character/Result/Index.vue#L25) - 证据: [frontend/src/pages/Character/Result/Index.vue](frontend/src/pages/Character/Result/Index.vue#L35) ### 4.3 联动规则 - 输入任意改动 -> config 变化 -> execute -> result.state 刷新 -> Info 与 Skill 重新渲染。 - 结果显示类型联动:buffer 布尔值驱动结果面板分支。 - 证据: [frontend/src/pages/Character/Index.vue](frontend/src/pages/Character/Index.vue#L61) - 证据: [frontend/src/pages/Character/Index.vue](frontend/src/pages/Character/Index.vue#L70) - 证据: [frontend/src/api/calc/type.ts](frontend/src/api/calc/type.ts#L10) ## 5. 异常反馈现状评估 ### 5.1 已有反馈 - 结果组件存在数据门控:无数据时不渲染主表。 - 证据(Skill): [frontend/src/pages/Character/Result/components/Skill.vue](frontend/src/pages/Character/Result/components/Skill.vue#L4) - 证据(BufferSkill): [frontend/src/pages/Character/Result/components/BufferSkill.vue](frontend/src/pages/Character/Result/components/BufferSkill.vue#L4) ### 5.2 缺口 - 缺少请求失败显式提示(无 toast/错误区/错误码展示)。 - 缺少结果区加载态反馈(执行中与完成时刻不可见)。 - 缺少重试按钮或自动降级策略。 - 缺少字段级异常占位(比如 info 值缺失时统一展示策略)。 侧面证据: - execute 在主容器中仅做并发互斥,不包含错误反馈 UI: [frontend/src/pages/Character/Index.vue](frontend/src/pages/Character/Index.vue#L61) - calc 直接返回接口数据,未见 UI 级异常转换: [frontend/src/api/calc/index.ts](frontend/src/api/calc/index.ts#L7) ## 6. 重点问题与改造建议 ### P0 1. 结果计算缺少显式异常反馈链路。 - 影响:接口失败时用户难以判断是无结果还是请求异常。 - 建议:在 config store 增加 status 字段(idle/loading/success/error),并在 Result 区显示错误提示与重试按钮。 2. 结果刷新过程不可感知。 - 影响:连续编辑时体验抖动,用户无法确认是否正在计算。 - 建议:在 Result 容器增加轻量 loading 条或角标,绑定 execute 生命周期。 ### P1 1. 角色信息面板缺少异常值占位规范。 - 影响:后端字段不全时易出现空白或排版错位。 - 建议:Info 渲染时对 name/value 增加兜底格式化层。 2. 分列宽度与自适应策略未统一抽象。 - 影响:不同分辨率下信息密度不稳定。 - 建议:将主容器与结果列宽抽为布局 token,统一响应式断点行为。 ### P2 1. 结果组件中计算与展示逻辑耦合较高。 - 影响:后续扩展“多维对比/快照回放”时修改成本上升。 - 建议:提取结果计算 composable,将排序、汇总、同比逻辑从视图组件中抽离。 ## 7. 证据索引 ### 路由 - [frontend/src/router/index.ts](frontend/src/router/index.ts#L13) ### Store - [frontend/src/stores/config.ts](frontend/src/stores/config.ts#L236) - [frontend/src/stores/config.ts](frontend/src/stores/config.ts#L260) - [frontend/src/stores/info.ts](frontend/src/stores/info.ts#L9) ### API - [frontend/src/api/calc/index.ts](frontend/src/api/calc/index.ts#L7) - [frontend/src/api/calc/type.ts](frontend/src/api/calc/type.ts#L3) - [frontend/src/api/calc/type.ts](frontend/src/api/calc/type.ts#L4) - [frontend/src/api/calc/type.ts](frontend/src/api/calc/type.ts#L5) - [frontend/src/api/calc/type.ts](frontend/src/api/calc/type.ts#L10) - [frontend/src/api/calc/type.ts](frontend/src/api/calc/type.ts#L27) ### 页面与组件 - [frontend/src/pages/Character/Index.vue](frontend/src/pages/Character/Index.vue#L10) - [frontend/src/pages/Character/Index.vue](frontend/src/pages/Character/Index.vue#L18) - [frontend/src/pages/Character/Index.vue](frontend/src/pages/Character/Index.vue#L22) - [frontend/src/pages/Character/Index.vue](frontend/src/pages/Character/Index.vue#L23) - [frontend/src/pages/Character/Index.vue](frontend/src/pages/Character/Index.vue#L61) - [frontend/src/pages/Character/Index.vue](frontend/src/pages/Character/Index.vue#L70) - [frontend/src/pages/Character/Result/Index.vue](frontend/src/pages/Character/Result/Index.vue#L25) - [frontend/src/pages/Character/Result/Index.vue](frontend/src/pages/Character/Result/Index.vue#L35) - [frontend/src/pages/Character/Result/Index.vue](frontend/src/pages/Character/Result/Index.vue#L40) - [frontend/src/pages/Character/Result/components/Info.vue](frontend/src/pages/Character/Result/components/Info.vue#L13) - [frontend/src/pages/Character/Result/components/Info.vue](frontend/src/pages/Character/Result/components/Info.vue#L166) - [frontend/src/pages/Character/Result/components/Info.vue](frontend/src/pages/Character/Result/components/Info.vue#L212) - [frontend/src/pages/Character/Result/components/Skill.vue](frontend/src/pages/Character/Result/components/Skill.vue#L4) - [frontend/src/pages/Character/Result/components/Skill.vue](frontend/src/pages/Character/Result/components/Skill.vue#L47) - [frontend/src/pages/Character/Result/components/Skill.vue](frontend/src/pages/Character/Result/components/Skill.vue#L150) - [frontend/src/pages/Character/Result/components/Skill.vue](frontend/src/pages/Character/Result/components/Skill.vue#L166) - [frontend/src/pages/Character/Result/components/Skill.vue](frontend/src/pages/Character/Result/components/Skill.vue#L173) - [frontend/src/pages/Character/Result/components/BufferSkill.vue](frontend/src/pages/Character/Result/components/BufferSkill.vue#L4) - [frontend/src/pages/Character/Result/components/BufferSkill.vue](frontend/src/pages/Character/Result/components/BufferSkill.vue#L89) - [frontend/src/pages/Character/Result/components/BufferSkill.vue](frontend/src/pages/Character/Result/components/BufferSkill.vue#L159)