| New file |
| | |
| | | # rsf-design 替代 rsf-admin 第一阶段设计 |
| | | |
| | | ## 背景 |
| | | |
| | | 当前仓库中存在两个前端: |
| | | |
| | | - `rsf-admin`:现网旧前端,技术栈为 React + react-admin + MUI |
| | | - `rsf-design`:新前端,技术栈为 Vue 3 + Art Design Pro + Element Plus |
| | | |
| | | 后端为 `rsf-server`,本次设计明确约束如下: |
| | | |
| | | - 后端代码完全不修改 |
| | | - `rsf-design` 需要直接适配当前后端真实接口与数据结构 |
| | | - 不写兜底代码,不保留模板默认协议,不做长期双协议兼容 |
| | | - `rsf-admin` 在第一阶段继续保留为旧入口并行运行 |
| | | |
| | | ## 目标 |
| | | |
| | | 第一阶段不要求 `rsf-design` 一次性覆盖 `rsf-admin` 的全部业务页面,而是先真实接管运行骨架,使其成为一个可以独立登录和动态装配的可用新入口。 |
| | | |
| | | 第一阶段目标能力如下: |
| | | |
| | | 1. 登录 |
| | | 2. 退出登录 |
| | | 3. 登录态恢复 |
| | | 4. 获取用户信息 |
| | | 5. 获取菜单 |
| | | 6. 动态注册路由 |
| | | 7. 首页展示 |
| | | 8. 按钮权限控制 |
| | | |
| | | ## 非目标 |
| | | |
| | | 第一阶段不包含以下内容: |
| | | |
| | | 1. 不迁移全部业务页面 |
| | | 2. 不通过 iframe、外链或桥接方式把 `rsf-admin` 嵌回 `rsf-design` |
| | | 3. 不保留 `rsf-design` 模板默认登录接口、用户接口、菜单接口 |
| | | 4. 不为未迁移页面提供空白占位、默认猜测组件、运行时兜底跳转 |
| | | 5. 不改 `rsf-server` 接口、权限模型、菜单返回格式 |
| | | |
| | | ## 现状结论 |
| | | |
| | | ### rsf-admin 的真实运行模型 |
| | | |
| | | `rsf-admin` 当前直接依赖以下后端接口和约定: |
| | | |
| | | - 登录:`/login` |
| | | - 菜单:`/auth/menu` |
| | | - 用户信息:`/auth/user` |
| | | - 通用 CRUD: |
| | | - `/{resource}/page` |
| | | - `/{resource}/save` |
| | | - `/{resource}/update` |
| | | - `/{resource}/remove/*` |
| | | |
| | | 其关键特征不是“后端返回前端路由路径”,而是“后端菜单叶子节点返回资源标识”。旧前端通过 `node.component` 这样的标识,例如 `userLogin`、`outBound`、`stockTransfer`,再在 `rsf-admin/src/page/ResourceContent.js` 中映射到具体 React 页面实现。 |
| | | |
| | | ### rsf-design 当前默认模型 |
| | | |
| | | `rsf-design` 作为 Art Design Pro 模板,当前默认假设: |
| | | |
| | | - 登录接口为 `/api/auth/login` |
| | | - 用户信息接口为 `/api/user/info` |
| | | - 菜单接口为 `/api/v3/system/menus/simple` |
| | | - `component` 字段可直接映射到 `src/views/**` 下的 Vue 页面路径 |
| | | |
| | | 这套默认模型与当前后端真实协议并不一致,因此不能通过简单改 baseURL 或改环境变量完成替代。 |
| | | |
| | | ## 总体方案 |
| | | |
| | | ### 总体原则 |
| | | |
| | | 第一阶段采用“新前端直接适配旧后端真实协议”的方式推进: |
| | | |
| | | - 后端协议不变 |
| | | - 新前端运行模型重建 |
| | | - 不维护模板默认协议 |
| | | - 不做双轨兼容 |
| | | - 不暴露未迁移页面 |
| | | |
| | | ### 运行主链 |
| | | |
| | | `rsf-design` 的第一阶段运行链路收敛为一条正式主链: |
| | | |
| | | 1. 用户在 `rsf-design` 登录 |
| | | 2. 前端调用当前后端真实登录接口 `/login` |
| | | 3. 登录成功后保存 token 并标记登录状态 |
| | | 4. 路由守卫在首次进入受保护页面时调用 `/auth/user` |
| | | 5. 路由守卫调用 `/auth/menu` |
| | | 6. 菜单转换模块将后端真实菜单结构转换为 Art Design Pro 可注册路由结构 |
| | | 7. 动态注册路由、生成菜单、计算首页落点 |
| | | 8. 页面与按钮权限统一从真实用户信息和真实菜单权限中读取 |
| | | |
| | | ## 架构边界 |
| | | |
| | | ### 第一阶段发布边界 |
| | | |
| | | `rsf-design` 第一阶段只发布已经真实接入的新能力: |
| | | |
| | | - 登录页 |
| | | - 首页 |
| | | - 用户信息获取 |
| | | - 菜单渲染 |
| | | - 动态路由 |
| | | - 按钮权限 |
| | | - 已明确接入的新页面 |
| | | |
| | | 未迁移业务页不出现在 `rsf-design` 的可见菜单和可注册路由中。 |
| | | |
| | | ### 并行运行边界 |
| | | |
| | | - `rsf-admin` 保留为旧入口 |
| | | - `rsf-design` 提供新入口 |
| | | - 两者并行存在,互不桥接 |
| | | - 后续每迁移一个模块,再把对应资源纳入 `rsf-design` 的发布范围 |
| | | |
| | | ## 数据契约设计 |
| | | |
| | | ### 登录契约 |
| | | |
| | | `rsf-design` 登录页必须改为提交当前后端真实字段,不再沿用模板示例字段和演示账号逻辑。 |
| | | |
| | | 要求: |
| | | |
| | | - 请求地址使用 `/login` |
| | | - 请求参数使用 `rsf-server` 当前真实需要的字段 |
| | | - 登录成功后只以真实响应字段写入 store |
| | | - 不保留模板中 `token`、`refreshToken` 的假设命名,按真实返回为准 |
| | | |
| | | ### 用户信息契约 |
| | | |
| | | 用户信息接口统一使用 `/auth/user`。 |
| | | |
| | | 该接口承担以下职责: |
| | | |
| | | - 提供当前用户基础信息 |
| | | - 提供角色信息 `roles` |
| | | - 提供按钮权限集合 `buttons` 或当前真实权限字段 |
| | | |
| | | `v-roles` 和 `useAuth` 必须直接消费真实用户信息,不再依赖模板示例数据。 |
| | | |
| | | ### 菜单契约 |
| | | |
| | | 菜单接口统一使用 `/auth/menu`。 |
| | | |
| | | 后端返回的原始菜单树保持原样,不要求后端调整为 Vue 路由路径。 |
| | | |
| | | 前端在唯一的菜单转换模块中完成: |
| | | |
| | | 1. 字段标准化 |
| | | 2. 父子路径拼接 |
| | | 3. 首页重定向推导 |
| | | 4. 资源标识到 Vue 组件的映射 |
| | | 5. 第一阶段发布范围过滤 |
| | | 6. `meta` 字段补齐 |
| | | |
| | | ## 模块拆分 |
| | | |
| | | 第一阶段建议集中修改以下模块。 |
| | | |
| | | ### 1. 认证接口模块 |
| | | |
| | | 文件: |
| | | |
| | | - `rsf-design/src/api/auth.js` |
| | | |
| | | 职责: |
| | | |
| | | - 重写登录接口 |
| | | - 新增获取用户信息接口 |
| | | - 新增获取菜单接口 |
| | | - 删除模板默认认证接口假设 |
| | | |
| | | ### 2. 登录页 |
| | | |
| | | 文件: |
| | | |
| | | - `rsf-design/src/views/auth/login/index.vue` |
| | | |
| | | 职责: |
| | | |
| | | - 去掉模板演示账号逻辑 |
| | | - 按真实业务字段提交登录请求 |
| | | - 登录成功后写入用户状态并跳转 |
| | | - 保留 Art Design Pro 风格,但以真实登录流程为准 |
| | | |
| | | ### 3. 用户状态模块 |
| | | |
| | | 文件: |
| | | |
| | | - `rsf-design/src/store/modules/user.js` |
| | | |
| | | 职责: |
| | | |
| | | - 按真实接口字段存储 token 与用户信息 |
| | | - 保证刷新后可恢复登录状态 |
| | | - 退出登录时清理权限、菜单、标签页、路由缓存 |
| | | |
| | | ### 4. 菜单转换模块 |
| | | |
| | | 建议新增文件: |
| | | |
| | | - `rsf-design/src/router/adapters/backendMenuAdapter.js` |
| | | |
| | | 职责: |
| | | |
| | | - 接收 `/auth/menu` 原始返回 |
| | | - 统一转换为 Art Design Pro 可注册路由 |
| | | - 在这里完成后端资源标识到 Vue 页面组件的映射 |
| | | - 在这里执行第一阶段发布范围过滤 |
| | | |
| | | 不单独拆页面注册模块,避免额外抽象层。 |
| | | |
| | | ### 5. 菜单处理与动态路由注册 |
| | | |
| | | 文件: |
| | | |
| | | - `rsf-design/src/router/core/MenuProcessor.js` |
| | | - `rsf-design/src/router/core/ComponentLoader.js` |
| | | - `rsf-design/src/router/guards/beforeEach.js` |
| | | |
| | | 职责: |
| | | |
| | | - 改为使用真实菜单接口 |
| | | - 改为依赖菜单转换模块的结果 |
| | | - 移除“后端 component 可直接映射 views 路径”的默认假设 |
| | | - 保证首次登录、刷新页面、直接访问深链接时都能正确动态注册 |
| | | |
| | | ### 6. 权限控制 |
| | | |
| | | 文件: |
| | | |
| | | - `rsf-design/src/hooks/core/useAuth.js` |
| | | - `rsf-design/src/directives/core/auth.js` |
| | | - `rsf-design/src/directives/core/roles.js` |
| | | |
| | | 职责: |
| | | |
| | | - 与真实用户信息和真实菜单权限结构保持一致 |
| | | - 按后端返回的角色与按钮权限做统一控制 |
| | | - 不保留模板演示权限逻辑 |
| | | |
| | | ## 菜单发布规则 |
| | | |
| | | 第一阶段采用“严格发布”策略。 |
| | | |
| | | 规则如下: |
| | | |
| | | 1. 后端返回完整菜单树 |
| | | 2. 前端先做一次严格转换 |
| | | 3. 仅保留第一阶段明确允许发布的菜单节点 |
| | | 4. 仅为允许发布的节点注册路由 |
| | | 5. 未进入发布范围的节点直接在菜单转换阶段剔除 |
| | | |
| | | 这样做的目的不是兼容,而是保证 `rsf-design` 发布出来的入口是闭合可用的真实子集。 |
| | | |
| | | ## 首页策略 |
| | | |
| | | 第一阶段首页由 `rsf-design` 独立承担,不沿用 `rsf-admin` 的 react-admin Dashboard 实现。 |
| | | |
| | | 要求: |
| | | |
| | | - 首页是新前端原生页面 |
| | | - 样式与布局遵循 Art Design Pro 规范 |
| | | - 不依赖旧前端页面桥接 |
| | | - 后续可逐步叠加统计数据与业务待办,但第一阶段只要求成为有效登录落点 |
| | | |
| | | ## 风险与应对 |
| | | |
| | | ### 风险 1:后端菜单的 component 不是 Vue 路径 |
| | | |
| | | 这是本次替代的核心差异。 |
| | | |
| | | 应对: |
| | | |
| | | - 不再假设 `component` 是 `src/views/**` 路径 |
| | | - 在菜单转换模块中显式完成资源标识映射 |
| | | |
| | | ### 风险 2:模板默认接口字段与真实接口字段不一致 |
| | | |
| | | 应对: |
| | | |
| | | - 全量替换 `rsf-design` 默认认证相关接口 |
| | | - 所有登录、用户、菜单字段以真实后端返回为准 |
| | | |
| | | ### 风险 3:未迁移菜单被错误暴露 |
| | | |
| | | 应对: |
| | | |
| | | - 第一阶段发布范围过滤必须发生在菜单转换阶段 |
| | | - 不允许注册未接入页面的路由 |
| | | |
| | | ### 风险 4:刷新后丢失动态路由 |
| | | |
| | | 应对: |
| | | |
| | | - 路由守卫必须支持基于 token 的重新拉取用户信息和菜单并重建动态路由 |
| | | |
| | | ## 验收标准 |
| | | |
| | | 第一阶段完成后,至少满足以下条件: |
| | | |
| | | 1. 用户可通过真实账号在 `rsf-design` 成功登录 |
| | | 2. token、用户信息、角色、按钮权限全部来自当前后端真实接口 |
| | | 3. `rsf-design` 可基于 `/auth/menu` 完成动态路由注册 |
| | | 4. 刷新页面后动态路由仍能恢复 |
| | | 5. 第一阶段发布菜单中的每个页面都可正常访问 |
| | | 6. 不出现组件未找到、空白占位、兜底跳转、假菜单节点 |
| | | 7. `v-auth`、`useAuth`、`v-roles` 可正确控制页面按钮显示 |
| | | 8. 未登录访问受保护页面时会跳回登录页 |
| | | 9. `rsf-admin` 旧入口仍保持可用 |
| | | |
| | | ## 后续阶段 |
| | | |
| | | 第一阶段完成后,后续迁移以“模块批次”推进。 |
| | | |
| | | 每个业务模块迁移时都遵循相同流程: |
| | | |
| | | 1. 在 `rsf-design` 中实现对应 Vue 页面 |
| | | 2. 在菜单转换模块中补充该资源标识映射 |
| | | 3. 将该模块加入发布范围 |
| | | 4. 完成联调与验证后再对外开放 |
| | | |
| | | 这可以保证替代过程始终是增量可验证的,而不是一次性大爆炸切换。 |
| | | |
| | | ## 结论 |
| | | |
| | | `rsf-design` 完全替代 `rsf-admin` 的正确第一步,不是“先把所有页面复制过去”,而是先让新前端完整接住旧后端的登录、用户、菜单、权限与动态装配模型。 |
| | | |
| | | 只要第一阶段把运行骨架接稳,后续业务页面迁移就会从“大重构”变成“按资源标识逐个迁入”的稳定增量工作。 |