Files
user-system/docs/plans/ADMIN_FRONTEND_EXECUTION_PLAN.md

29 KiB
Raw Permalink Blame History

Admin 前端唯一执行方案

更新时间2026-03-19

1. 文档定位

本文是当前唯一有效的 Admin 前端执行方案,后续前端实现、拆分任务、接口联调、验收都以本文为准。

事实来源仅限以下文件:

  • docs/API.md
  • internal/api/router/router.go
  • docs/status/REAL_PROJECT_STATUS.md
  • docs/PROJECT_REVIEW_REPORT.md

约束原则:

  1. 只实现仓库内已经真实接线、可以联调的 API。
  2. PRD 与当前后端实现不一致时,以当前后端事实为准,缺口明确列为延期项或前置依赖。
  3. 页面、类型、认证流、API 服务层必须统一,不再允许文档内同时存在 Vue / React、Axios / Fetch、假接口 / 真接口两套口径。

2. 当前真实约束

2.1 项目现状

  • 仓库中目前没有真实前端项目Admin 前端尚未开始。
  • 后端当前已经通过 go build ./...go vet ./...go test ./...
  • 当前项目真实状态是“后端核心链路可用前端未开始PRD 仍有未完成范围”。

2.2 必须接受的后端事实

  • 用户管理没有 POST /api/v1/users,因此当前不支持“管理员单个创建用户”页面。
  • 没有批量启用、批量禁用、批量删除接口,因此不做批量用户操作。
  • PUT /api/v1/users/:id/password 当前只允许本人改自己的密码,不支持管理员重置他人密码。
  • /api/v1/users/:id/avatar 的处理逻辑实际上只更新当前登录用户头像,因此头像上传只放到“个人中心”,不放到用户管理页。
  • 仪表盘统计只提供:
    • 用户总数、各状态人数
    • 今日 / 本周 / 本月新增用户
    • 今日成功 / 失败登录数
    • 本周成功登录数
  • 没有系统设置配置接口,因此不做 /settings 页面。
  • 没有“当前用户权限快照”接口。前端可稳定获取的是:
    • GET /api/v1/auth/userinfo
    • GET /api/v1/users/:id/roles
  • OAuth 回调当前由后端直接返回 JSON不是标准 SPA redirect 完成态,因此社交登录 / 绑定不纳入当前 MVP。
  • 设备接口没有“全局设备列表”,只有:
    • GET /api/v1/devices 当前用户设备
    • GET /api/v1/devices/users/:id 指定用户设备 因此前端不做全局设备管理页面。

3. 单一技术栈

当前只接受以下一套前端技术栈:

关注点 统一方案 说明
框架 React 18 + TypeScript 统一组件模型和类型系统
构建工具 Vite 快速启动,适合从零搭建
路由 React Router 6 足够覆盖登录、后台布局、受保护路由
UI 组件 Ant Design 5 后台场景成熟,减少重复造轮子
请求层 浏览器原生 fetch + 自建请求客户端 避免 Axios 二次封装分叉
状态管理 React Context 仅管理会话态 不引入 Redux / Zustand / Pinia
页面数据 页面局部状态 + 受控请求 首版不引入 React Query
表单 Ant Design Form 与 UI 组件一致
样式 CSS Modules + CSS Variables + AntD Theme Token 不引入 styled-components
图表 MVP 不引入额外图表库 当前统计接口不足以支撑复杂图表

明确不采用:

  • Vue 3
  • Pinia
  • Axios
  • styled-components
  • React Query
  • “HTML + CSS + JavaScript 手写管理后台”

3.1 前端技术架构总览

前端统一采用单体 SPA 架构,不拆微前端,不做 SSR不做多应用并行。

运行时分层固定为:

  1. App Shell
    • 应用启动、主题、路由挂载、全局异常边界
  2. Session Layer
    • 会话恢复、刷新令牌、登录态广播、路由准入
  3. HTTP Client Layer
    • 鉴权头注入、统一解包、401 重试、下载上传
  4. Service Layer
    • 按资源拆分 API 方法,不放 UI 逻辑
  5. Page / Feature Layer
    • 页面编排、表格、表单、弹窗、抽屉
  6. Shared UI Layer
    • 布局、通用表格状态、空态、错误态、确认弹窗

数据流固定为:

Page -> Service -> HTTP Client -> API

禁止反向依赖:

  • services 依赖页面组件
  • 页面直接拼接 URL 自己发请求
  • 多套 token 管理并存
  • 多套类型定义并存

3.2 项目目录架构

前端项目统一新建在:

  • frontend/admin

目录结构固定为:

frontend/admin/
  package.json
  tsconfig.json
  vite.config.ts
  .env.example
  src/
    app/
      App.tsx
      main.tsx
      router.tsx
      providers/
        AuthProvider.tsx
        ThemeProvider.tsx
    layouts/
      AdminLayout/
      AuthLayout/
    pages/
      auth/
        LoginPage/
        ForgotPasswordPage/
        ResetPasswordPage/
      admin/
        DashboardPage/
        UsersPage/
        RolesPage/
        PermissionsPage/
        LoginLogsPage/
        OperationLogsPage/
        WebhooksPage/
        ImportExportPage/
        ProfilePage/
        ProfileSecurityPage/
    features/
      auth/
      users/
      roles/
      permissions/
      logs/
      webhooks/
      profile/
      import-export/
      devices/
      totp/
    services/
      auth.ts
      users.ts
      roles.ts
      permissions.ts
      stats.ts
      logs.ts
      webhooks.ts
      import-export.ts
      profile.ts
      devices.ts
    lib/
      http/
        client.ts
        auth-session.ts
        errors.ts
      storage/
        token-storage.ts
    components/
      common/
      feedback/
      forms/
    types/
      http.ts
      auth.ts
      user.ts
      role.ts
      permission.ts
      device.ts
      log.ts
      webhook.ts
      stats.ts
    styles/
      tokens.css
      global.css

目录原则:

  • pages 只放路由页面,不放复用业务组件
  • features 放页面内复用的业务组件与交互逻辑
  • services 只放接口调用
  • types 只放接口类型与领域类型
  • components/common 只放通用 UI不感知业务资源

3.3 依赖白名单

首版允许引入的前端运行时依赖只保留:

  • react
  • react-dom
  • react-router-dom
  • antd
  • @ant-design/icons
  • dayjs

首版允许引入的开发依赖只保留:

  • typescript
  • vite
  • @vitejs/plugin-react
  • eslint
  • @types/react
  • @types/react-dom
  • vitest

依赖准入规则:

  1. 没有明确解决当前问题的依赖,不引入。
  2. 能用浏览器原生能力解决的问题,不引入包装库。
  3. 同类库只保留一套。

3.4 技术简化结论

这版前端技术架构刻意做了收缩,最终结论如下:

  • 不做微前端
  • 不做 monorepo 拆分
  • 不做 SSR / SSG
  • 不做 Redux / Zustand / Pinia
  • 不做 React Query
  • 不做 Axios
  • 不做 CSS-in-JS
  • 不做图表库优先接入
  • 不做权限码驱动的复杂前端元编程

首版只保留四个必须的技术支点:

  1. React 页面和路由
  2. Context 会话管理
  3. fetch 请求客户端
  4. Ant Design 后台组件

3.5 工程准则

前端开发时必须遵守以下准则:

  1. 一个 API 资源对应一个 service 文件。
  2. 一个路由页面对应一个 page 目录。
  3. 一个复杂弹窗 / 抽屉对应一个独立 feature 组件。
  4. 一个任务只解决一类问题,不混做“页面 + 所有依赖 + 所有接口”。
  5. 所有新代码默认 TypeScript 严格模式。
  6. 所有请求先写类型,再写 service再接页面。

4. 页面与路由范围

4.1 MVP 页面

路由 访问级别 页面范围 对应 API
/login 公开 账号密码登录、邮箱验证码登录、短信验证码登录 /auth/login /auth/send-email-code /auth/login/email-code /auth/send-code /auth/login/code
/forgot-password 公开 发起密码重置 /auth/forgot-password
/reset-password 公开 校验重置 token、提交新密码 /auth/reset-password
/dashboard 管理员 统计卡片与简表,不做假趋势图 /admin/stats/dashboard /admin/stats/users
/users 管理员 用户列表、筛选、详情抽屉、编辑、状态切换、删除、分配角色 /users /users/:id /users/:id /users/:id/status /users/:id/roles /users/:id
/roles 管理员 角色列表、创建、编辑、删除、启停、分配权限 /roles /roles/:id /roles/:id/status /roles/:id/permissions
/permissions 管理员 权限列表、树、创建、编辑、删除、启停 /permissions /permissions/tree /permissions/:id/status
/logs/login 管理员 登录日志列表 /logs/login
/logs/operation 管理员 操作日志列表 /logs/operation
/webhooks 已登录 Webhook 列表、创建、编辑、删除、投递记录 /webhooks /webhooks/:id/deliveries
/import-export 管理员 导入、导出、模板下载 /admin/users/import /admin/users/export /admin/users/import/template
/profile 已登录 个人资料查看与编辑 /auth/userinfo /users/:id
/profile/security 已登录 修改密码、TOTP、头像上传、本人设备、本人日志 /users/:id/password /auth/2fa/* /users/:id/avatar /devices /logs/login/me /logs/operation/me

4.2 页面能力边界

/users 当前只允许实现:

  • 列表分页、关键字筛选、状态筛选、角色筛选、时间筛选、排序
  • 查看用户详情
  • 编辑用户资料
  • 删除用户
  • 修改用户状态
  • 分配角色

/users 当前明确不做:

  • 新建用户
  • 批量操作
  • 管理员代改他人密码
  • 为其他用户上传头像

/dashboard 当前只允许展示真实统计字段,不做以下伪需求:

  • 在线用户
  • 近 7 / 30 天时序趋势图
  • 地域分布图
  • 最近注册用户
  • 最近登录用户

4.3 延期或阻塞页面

以下页面或功能不进入当前前端实施范围:

  • /settings
  • 全局 /devices 管理页
  • 用户创建页
  • 用户批量操作
  • 管理员重置他人密码
  • “记住我 / 记住设备”
  • 社交登录回调页
  • 社交账号绑定页
  • 依赖权限码的细粒度按钮控制

5. 统一类型模型

5.1 基础响应模型

所有请求统一先经过响应解包,禁止页面直接假定不同接口的 data 结构。

export interface ApiResponse<T> {
  code: number;
  message: string;
  data: T;
}

export interface PaginatedData<T> {
  items: T[];
  total: number;
  page: number;
  page_size: number;
}

注意:

  • 分页列表真实格式是 data.items + total + page + page_size
  • 不是所有列表都是分页返回。
  • GET /webhooksGET /users/:id/rolesGET /roles/:id/permissionsGET /permissions/tree 等接口返回的不是 PaginatedData<T>

5.2 会话与认证类型

export interface SessionUser {
  id: number;
  username: string;
  email: string;
  phone: string;
  nickname: string;
  avatar: string;
  status: 0 | 1 | 2 | 3;
}

export interface TokenBundle {
  access_token: string;
  refresh_token: string;
  expires_in: number;
  user: SessionUser;
}

关键约束:

  • POST /auth/login 返回 TokenBundle
  • POST /auth/refresh 也返回 TokenBundle
  • 不允许再定义“刷新后只返回 access_token”的前端假类型

5.3 领域类型

前端类型定义以当前后端 JSON 字段为准,至少包含以下文件:

  • src/types/http.ts
  • src/types/auth.ts
  • src/types/user.ts
  • src/types/role.ts
  • src/types/permission.ts
  • src/types/device.ts
  • src/types/log.ts
  • src/types/webhook.ts
  • src/types/stats.ts

必须保留的真实枚举约束:

  • UserStatus: 0 | 1 | 2 | 3
  • RoleStatus: 0 | 1
  • PermissionStatus: 0 | 1

6. 认证与会话流

6.1 统一会话策略

采用以下单一策略:

  1. refresh_token 持久化到 localStorage
  2. access_token 保存在内存态
  3. 应用启动时优先尝试用 refresh_token 换取新的 TokenBundle
  4. 刷新成功后再加载角色信息
  5. 刷新失败则清空会话并回到登录页

这样做的原因:

  • 当前后端刷新接口已经返回完整 TokenBundle
  • 可以避免前端长期持久化过期 access_token
  • 页面刷新后可以稳定恢复登录态

6.2 启动流程

应用启动流程固定如下:

  1. 读取本地 refresh_token
  2. 若存在,则调用 POST /api/v1/auth/refresh
  3. 刷新成功后,拿到新的 access_tokenrefresh_tokenuser
  4. 调用 GET /api/v1/users/{user.id}/roles
  5. 从角色列表中推导:
    • roleCodes
    • isAdmin = roleCodes.includes("admin")
  6. 会话完成后才渲染受保护路由

补充规则:

  • 不以 GET /auth/userinfo 作为唯一启动入口,避免浪费一次可能会被 401 的请求
  • GET /auth/userinfo 作为“刷新当前资料”能力保留给 Profile 页面或手动重载

6.3 登录与登出流

登录页支持三种真实入口:

  • 账号密码登录
  • 邮箱验证码登录
  • 短信验证码登录

登录成功后统一执行:

  1. 写入新的 refresh_token
  2. 将新的 access_token 放入内存
  3. 直接使用返回体中的 user
  4. 再请求当前用户角色
  5. 完成后跳转后台首页

登出统一执行:

  1. 调用 POST /api/v1/auth/logout
  2. 请求体优先带上当前 access_tokenrefresh_token
  3. 无论接口成功与否,都清空本地会话
  4. 跳回 /login

6.4 401 处理

请求客户端必须实现单次刷新机制:

  1. 普通业务请求收到 401
  2. 若当前存在 refresh_token,触发一次全局中的刷新流程
  3. 刷新成功后重放原请求
  4. 刷新失败则清会话并跳转 /login

禁止旧方案中的以下行为:

  • 收到 401 直接跳登录,不尝试刷新
  • 刷新后只更新 access_token,不更新 refresh_token

6.5 暂不纳入 MVP 的认证能力

以下能力有 API但当前不纳入首版登录流

  • 社交登录按钮直连回调完成登录
  • 社交账号绑定
  • remember me

原因不是“前端不做”,而是“当前后端协议不适合 SPA 稳定落地”。


7. API 服务层统一方案

7.1 目录结构

目录结构以 3.2 项目目录架构 为准。

本节只强调 service / lib / types 三层在该目录中的职责:

  • lib/http
    • 统一请求客户端、会话刷新、错误模型
  • services
    • 资源级 API 访问层
  • types
    • 统一接口类型和领域类型

7.2 请求客户端职责

lib/http/client.ts 只做以下事情:

  • 拼接基础 URL
  • 注入 Authorization: Bearer <access_token>
  • 统一解包 ApiResponse<T>
  • 统一处理 401
  • 统一处理 Blob 下载和 FormData 上传
  • 将后端业务错误统一转成前端可消费的 AppError

禁止:

  • 页面组件内手写 fetch("/api/v1/...")
  • 每个页面自己处理 token 注入与刷新
  • 把分页响应和普通响应混成一个类型

7.3 服务层模块边界

services/auth.ts

  • loginByPassword
  • sendEmailCode
  • loginByEmailCode
  • sendSmsCode
  • loginBySmsCode
  • refreshSession
  • logout
  • forgotPassword
  • validateResetToken
  • resetPassword
  • getUserInfo
  • getTwoFactorStatus
  • setupTwoFactor
  • enableTwoFactor
  • disableTwoFactor
  • verifyTwoFactor

services/users.ts

  • listUsers
  • getUser
  • updateUser
  • deleteUser
  • updateUserStatus
  • getUserRoles
  • assignUserRoles

services/profile.ts

  • getMyProfile
  • updateMyProfile
  • changeMyPassword
  • uploadMyAvatar
  • getMyLoginLogs
  • getMyOperationLogs

services/roles.ts

  • listRoles
  • createRole
  • getRole
  • updateRole
  • deleteRole
  • updateRoleStatus
  • getRolePermissions
  • assignRolePermissions

services/permissions.ts

  • listPermissions
  • getPermissionTree
  • createPermission
  • getPermission
  • updatePermission
  • deletePermission
  • updatePermissionStatus

services/stats.ts

  • getDashboardStats
  • getUserStats

services/logs.ts

  • getLoginLogs
  • getOperationLogs

services/webhooks.ts

  • listWebhooks
  • createWebhook
  • updateWebhook
  • deleteWebhook
  • getWebhookDeliveries

services/import-export.ts

  • downloadUserExport
  • uploadUserImport
  • downloadImportTemplate

services/devices.ts

  • getMyDevices
  • getUserDevices
  • getDevice
  • createDevice
  • updateDevice
  • deleteDevice
  • updateDeviceStatus

7.4 下载与上传约束

  • 用户导出必须走 Blob 下载
  • 导入必须走 multipart/form-data
  • 头像上传必须走 multipart/form-data
  • 头像上传虽然路径是 /users/:id/avatar,但前端只允许传当前用户 ID

8. 权限与路由守卫

8.1 现阶段只做两级守卫

当前前端守卫只做:

  • RequireAuth
  • RequireAdmin

判断依据:

  1. 会话中必须有有效 access_token
  2. 启动后必须已成功拉到当前用户角色
  3. role.code === "admin" 视为管理员

8.2 当前不做权限码按钮系统

原因:

  • 后端没有“当前用户权限快照”公开接口
  • 中间件中的 permission_codes 仅存在于服务端请求上下文,不会自动返回给前端

因此当前只允许:

  • 管理员页面用 RequireAdmin
  • 用户自己的页面按“本人”场景控制

当前不允许:

  • 以前端硬编码方式伪造整套按钮级 permission code 控制体系

9. 实施阶段与最小任务拆解

9.1 交付顺序

前端按以下顺序交付,不允许跳步:

  1. 工程骨架
  2. 会话与请求底座
  3. 认证页面
  4. 管理后台框架
  5. 核心管理页
  6. 运营与个人安全页
  7. 收尾验证

9.2 任务拆解规则

最小任务定义:

  • 一个任务只产出一个明确可验证的结果
  • 一个任务的完成标准必须能被构建、页面行为或接口联调验证
  • 一个任务不能横跨多个资源域

任务粒度控制:

  • 基础设施任务:一个文件组或一个运行能力
  • 服务层任务:一个资源服务文件
  • 页面任务:一个路由页面
  • 复杂交互任务:一个弹窗、一个抽屉、一个上传、一个下载流

9.3 M0 工程骨架

ID 任务 产出 完成定义
M0-01 初始化 frontend/admin Vite 项目 基础工程目录 能本地启动空白 React 页面
M0-02 建立 tsconfig 路径别名 @/ 别名 导入路径不再依赖相对路径层层回退
M0-03 建立 .env.example VITE_API_BASE_URL 规范 请求基地址可配置
M0-04 接入 Ant Design 5 和全局样式 global.css / tokens.css 页面样式正常加载
M0-05 建立 AuthLayoutAdminLayout 骨架 两套布局组件 登录页和后台页布局可区分
M0-06 建立应用路由骨架 router.tsx 公开页和受保护页都可访问
M0-07 建立错误页与 404 页 错误反馈页面 未匹配路由可落到 404
M0-08 建立全局 AppError 模型 统一错误结构 页面可接收统一错误对象

9.4 M1 会话与请求底座

ID 任务 产出 完成定义
M1-01 实现 token-storage.ts 刷新令牌读写封装 refresh_token 可稳定存取
M1-02 实现 auth-session.ts 内存态 access token 管理 页内请求可拿到当前 access token
M1-03 实现 client.ts 基础请求能力 GET/POST/PUT/DELETE 封装 页面不再手写原生请求细节
M1-04 实现统一响应解包 ApiResponse<T> 解包 service 可直接返回业务数据
M1-05 实现统一业务错误映射 后端错误转 AppError 页面可稳定提示错误信息
M1-06 实现 401 单次刷新机制 请求重试逻辑 access token 过期后可自动刷新一次
M1-07 实现并发刷新锁 单飞刷新 多请求 401 时只触发一次刷新
M1-08 实现 AuthProvider 全局会话上下文 页面可读取用户、角色、登录状态
M1-09 实现应用启动会话恢复 启动自动 refresh 刷新页面后能恢复登录态
M1-10 实现 RequireAuth 登录守卫 未登录不可进入受保护页面
M1-11 实现 RequireAdmin 管理员守卫 非 admin 不可进入后台管理页
M1-12 定义 http.ts / auth.ts / user.ts 基础类型 通用类型文件 认证和用户请求不再使用 any

9.5 M2 认证页

ID 任务 产出 完成定义
M2-01 实现 services/auth.ts 认证 service 登录、刷新、登出、密码重置接口可调用
M2-02 实现密码登录表单 登录页密码 Tab 可调用 /auth/login 并进入后台
M2-03 实现邮箱验证码发送 邮箱验证码发送流程 可调用 /auth/send-email-code
M2-04 实现邮箱验证码登录表单 邮箱验证码登录 Tab 可调用 /auth/login/email-code
M2-05 实现短信验证码发送 短信验证码发送流程 可调用 /auth/send-code
M2-06 实现短信验证码登录表单 短信验证码登录 Tab 可调用 /auth/login/code
M2-07 实现忘记密码页 ForgotPasswordPage 可调用 /auth/forgot-password
M2-08 实现重置密码页 ResetPasswordPage 可校验并提交重置密码
M2-09 实现登出动作 退出登录入口 退出后会话被清空并跳转登录页
M2-10 实现会话启动加载态 启动屏 / 骨架态 启动恢复期间不闪跳错误页面

9.6 M3 后台框架

ID 任务 产出 完成定义
M3-01 实现后台菜单配置 路由与菜单映射 菜单只出现当前方案允许的页面
M3-02 实现后台头部区域 顶栏组件 能展示当前用户和退出入口
M3-03 实现侧边栏导航 菜单导航 页面间可跳转
M3-04 实现面包屑和页面容器 页面框架组件 后台页面布局一致
M3-05 实现页面级加载 / 空态 / 错误态组件 反馈组件 所有列表页使用统一反馈模式

9.7 M4 Dashboard

ID 任务 产出 完成定义
M4-01 定义 stats.ts 类型 统计类型文件 用户统计和登录统计字段齐全
M4-02 实现 services/stats.ts 统计 service 可请求 dashboard / users stats
M4-03 实现 Dashboard 统计卡片 Dashboard 页面基础版 展示真实统计卡片
M4-04 实现 Dashboard 简表区块 简单文本 / 数字区块 不引入假图表但信息完整

9.8 M5 Users

ID 任务 产出 完成定义
M5-01 完成 user.ts 领域类型 用户列表 / 详情类型 用户页所有字段有类型约束
M5-02 实现 services/users.ts 用户 service 列表、详情、编辑、状态、角色分配可调用
M5-03 实现用户筛选表单 UsersFilter 支持关键字、状态、角色、时间、排序
M5-04 实现用户列表表格 UsersTable 分页和列表展示正常
M5-05 实现用户详情抽屉 UserDetailDrawer 可查看用户详情
M5-06 实现编辑用户抽屉 UserEditDrawer 可提交 /users/:id 更新
M5-07 实现用户状态切换动作 状态更新交互 可提交 /users/:id/status
M5-08 实现用户删除动作 删除确认流 可提交 /users/:id 删除
M5-09 实现用户角色分配弹窗 AssignRolesModal 可提交 /users/:id/roles

9.9 M6 Roles

ID 任务 产出 完成定义
M6-01 定义 role.ts 类型 角色类型文件 列表、详情、权限关联字段齐全
M6-02 实现 services/roles.ts 角色 service 增删改查、启停、权限分配可调用
M6-03 实现角色列表页 RolesPage 列表、分页、状态展示正常
M6-04 实现创建 / 编辑角色弹窗 RoleFormModal 可提交创建和更新
M6-05 实现角色状态切换 状态操作 可提交 /roles/:id/status
M6-06 实现角色删除动作 删除确认流 可删除角色
M6-07 实现角色权限分配弹窗 RolePermissionsModal 可读取并提交角色权限

9.10 M7 Permissions

ID 任务 产出 完成定义
M7-01 定义 permission.ts 类型 权限类型文件 权限树和列表字段齐全
M7-02 实现 services/permissions.ts 权限 service 列表、树、增删改查、启停可调用
M7-03 实现权限列表页 PermissionsPage 列表和树切换正常
M7-04 实现创建 / 编辑权限弹窗 PermissionFormModal 可提交创建和更新
M7-05 实现权限状态切换 状态操作 可提交 /permissions/:id/status
M7-06 实现权限删除动作 删除确认流 可删除权限

9.11 M8 Logs

ID 任务 产出 完成定义
M8-01 定义 log.ts 类型 日志类型文件 登录日志和操作日志字段齐全
M8-02 实现 services/logs.ts 日志 service 登录日志、操作日志接口可调用
M8-03 实现登录日志页 LoginLogsPage 列表、分页、筛选正常
M8-04 实现操作日志页 OperationLogsPage 列表、分页、筛选正常

9.12 M9 Webhooks

ID 任务 产出 完成定义
M9-01 定义 webhook.ts 类型 Webhook 类型文件 列表和投递记录字段齐全
M9-02 实现 services/webhooks.ts Webhook service 列表、增删改、投递记录可调用
M9-03 实现 Webhook 列表页 WebhooksPage 列表可展示
M9-04 实现创建 / 编辑 Webhook 弹窗 WebhookFormModal 可提交创建和更新
M9-05 实现删除 Webhook 动作 删除确认流 可删除 Webhook
M9-06 实现投递记录抽屉 DeliveriesDrawer 可查看 /webhooks/:id/deliveries

9.13 M10 Import / Export

ID 任务 产出 完成定义
M10-01 实现 services/import-export.ts 导入导出 service 下载模板、上传导入、导出下载可调用
M10-02 实现导出表单 ExportPanel 可设置格式和筛选条件
M10-03 实现导出下载流 Blob 下载 CSV / XLSX 文件可正常下载
M10-04 实现导入上传表单 ImportPanel 可上传 .csv / .xlsx
M10-05 实现模板下载动作 TemplateDownload 可下载导入模板

9.14 M11 Profile / Security

ID 任务 产出 完成定义
M11-01 实现 services/profile.ts 个人中心 service 当前用户资料与安全接口可调用
M11-02 实现 services/devices.ts 设备 service 本人设备接口可调用
M11-03 实现个人资料页 ProfilePage 可查看并编辑个人资料
M11-04 实现修改密码表单 ChangePasswordForm 可提交本人密码修改
M11-05 实现 TOTP 状态与 setup 流程 TOTPSetupPanel 可拉取状态并展示 setup 信息
M11-06 实现 TOTP 启用 / 关闭 / 验证 TOTPActionPanel 可完整跑通 2FA 管理流
M11-07 实现头像上传 AvatarUploadPanel 可上传并刷新当前头像
M11-08 实现本人设备列表 MyDevicesPanel 可展示和操作 /devices
M11-09 实现本人登录日志 MyLoginLogsPanel 可展示 /logs/login/me
M11-10 实现本人操作日志 MyOperationLogsPanel 可展示 /logs/operation/me

9.15 M12 收尾与验证

ID 任务 产出 完成定义
M12-01 统一菜单权限与路由准入复核 菜单守卫检查 管理页不会暴露给非 admin
M12-02 统一分页交互复核 分页行为检查 所有分页页都按真实结构工作
M12-03 统一错误提示与空态复核 反馈体验检查 页面失败时不出现白屏
M12-04 添加关键基础测试 vitest 用例 至少覆盖请求客户端和会话恢复逻辑
M12-05 执行前端构建验证 npm run build 生产构建通过
M12-06 执行联调烟雾验证 手工联调清单 每个已纳入页面至少完成一次真实接口验证

9.16 当前不拆解的延期项

以下项在后端前置条件未补齐前,不进入任务拆解:

  • 社交登录 / 绑定
  • 系统设置
  • 全局设备管理
  • 用户创建
  • 批量操作
  • 细粒度权限码前端控制
  • 富图表仪表盘

10. 后端补齐前置依赖

以下接口或协议补齐后,前端范围才能继续扩张:

  1. POST /api/v1/users,用于管理员单个创建用户
  2. 用户批量操作接口
  3. 当前用户角色码 / 权限码快照接口
  4. SPA 友好的 OAuth callback redirect 协议
  5. 社交账号绑定握手协议,而不是直接要求前端提交 open_id
  6. 系统设置读写接口
  7. 全局设备列表与检索接口
  8. 时间序列统计、最近活动、地域分布等仪表盘接口

11. 验收基线

后续前端实现必须满足以下验收条件:

  1. 每个页面都能映射到当前真实后端 API不出现“文档有、后端无”的按钮。
  2. 所有分页页都按真实结构处理 items / total / page / page_size
  3. 刷新会话必须轮换 refresh_token,不能只更新 access_token
  4. Admin 页面必须以当前用户角色中的 admin 作为准入条件。
  5. 个人头像上传只能从个人中心进入,不能放进用户管理页。
  6. Dashboard 只展示当前统计接口真实提供的数据。
  7. 不新增任何与本文冲突的前端栈或页面规划文档。