Files
quyun-v2/docs/review_report.md
2026-01-08 09:57:04 +08:00

6.4 KiB
Raw Blame History

QuyUn v2 代码审查与优化建议backend + frontend/portal

审查范围:backend/frontend/portal/specs/docs/frontend/superadmin/SUPERADMIN_PAGES.md

一、关键问题(按严重程度)

P0 / 安全与数据隔离

  1. (暂时不需要管,后续统一优化)多租户路由与上下文缺失,无法满足 /t/:tenant_code/v1 规范,存在跨租户数据泄漏风险。
  • 后端路由基座仍为 /v1backend/app/http/v1/routes.manual.go
  • 前端路由与 API 基座未含 tenant_codefrontend/portal/src/router/index.jsfrontend/portal/src/utils/request.js
  • 多数服务查询未强制带 tenant_id 条件(仅依赖 query 传参):如 backend/app/services/content.gobackend/app/services/order.gobackend/app/services/common.go
  1. 鉴权为“可选”,导致受保护接口可能被匿名访问;超级管理员接口无角色校验。
  • Auth 中间件未携带 Authorization 时直接放行:backend/app/middlewares/middlewares.go
  • /super/v1/* 复用普通 Auth,无 super_admin 权限检查:backend/app/http/super/v1/routes.manual.go
  1. 超级管理员登录与鉴权核心逻辑为空实现,接口可用性与安全性均不足。
  • services.Super.Login / CheckToken 返回空结构:backend/app/services/super.go

P1 / 功能缺失与接口不一致

  1. 后端多个关键接口未实现或返回空结果,前端调用会失败或表现异常。
  • services.Order.Status 返回 nilbackend/app/services/order.go
  • 超管统计/订单详情/退款等均为空:backend/app/services/super.go
  • 超管内容/订单列表 DTO 映射 TODObackend/app/services/super.go
  1. 认证方式与规格偏离:现实现 OTP 登录 + JWT规格为 WeChat OAuth + Cookie(已经移除,仅使用jwt认证)。
  • 认证流程:backend/app/http/v1/auth/auth.gobackend/app/services/user.go
  • 前端调用 OTP 登录:frontend/portal/src/api/auth.js
  1. API 调用参数与后端 @Bind 约定不一致,导致请求失效。
  • contentId 参数期望为 contentId,前端用 content_idfrontend/portal/src/api/user.jsbackend/app/http/v1/user.go

P2 / 代码规范与可维护性

  1. ID 类型全链路使用 string,与 DB BIGINT 不一致,导致重复转换与潜在路由冲突。
  • controller/service/DTO 使用 stringbackend/app/http/v1/*backend/app/http/v1/dto/*backend/app/services/*
  • 路由注解未使用 :id<int>backend/app/http/**
  1. DTO 结构缺少字段级中文注释,业务注释大量为英文,违反 backend/llm.txt 规范。
  • DTO 示例:backend/app/http/v1/dto/user.gobackend/app/http/v1/dto/content.go
  1. Service 读取 ctx 获取用户信息,违反“上下文提取必须在 Controller 层”的规则。
  • services.audit.Log 直接读 ctx.Valuebackend/app/services/audit.go
  1. 数据库迁移与规格不一致,初始迁移为空,实际表结构仅在 specs/DB.sql(此文件仅做迁移参考,根据业务需求进行优化)。
  • backend/database/migrations/20251227112605_init.sql 为空。
  1. N+1 查询与聚合性能风险。
  • 订单列表逐条查询租户/内容/订单项:backend/app/services/order.go
  • 租户列表逐条统计 followers/contentsbackend/app/services/tenant.go
  1. 代码残留调试输出。
  • fmt.Printf 直接打印配置:backend/app/services/tenant.go

二、架构与实现优化建议

1) 多租户“强隔离”落地

  • 路由:将 /v1 全部改为 /t/:tenantCode/v1(注意 @Router:tenantCode<int> 规则)。
  • 中间件:新增 TenantResolver(解析 tenant_code → tenant_id → ctx locals
  • 服务层:所有查询必须带 tenant_id(禁止依赖 query 传参)。
  • 前端Router base + API base 统一从 URL 中解析 tenant_code。

2) 鉴权与权限体系补全

  • 拆分 AuthOptionalAuthRequired 两种中间件,受保护接口必须硬校验。
  • 超管接口增加 super_admin 角色校验JWT claims 中带 roles
  • 完成 Super.Login / CheckToken 逻辑,支持 token 续期与失效。

3) ID 类型统一int64 / model 注入)

  • 统一所有 path/query/body 里的 ID 为 int64
  • 控制器签名支持 @Bind id path + int64@Bind tenant model(id) 进行 model 注入。
  • swagger @Router 必须使用 :id<int> / :tenantID<int>

4) 规格一致性修复 (仅使用JWT

  • 统一认证模型OTP vs WeChat要么按规格实现 WeChat OAuth要么更新规格文档。
  • 统一存储方案OSS + tenant_uuid + md5 命名);当前本地存储仅作开发 fallback。
  • specs/DB.sql 迁入真实迁移文件并补齐中文字段注释。

5) 性能与稳定性

  • 列表场景引入预加载或批量查询,规避 N+1。
  • 订单/租户统计使用聚合 SQL 一次性获取。
  • 关键写操作增加幂等与重试策略。

6) 规范化与可维护性

  • DTO 增加字段级中文注释(含业务语义/约束)。
  • Service 层中文注释补齐业务意图与边界条件。
  • Audit 改为显式传入 operatorID 参数。

三、ID 类型统一与 Model 注入的推荐步骤(遵循 backend/llm.txt

  1. 定义目标规范
  • 所有业务 ID 使用 int64JSON 输出为数值)。
  • 路由中数字 ID 使用 :id<int>
  1. 先改 Controller/DTO
  • backend/app/http/v1/**backend/app/http/super/v1/** 中 path/query 的 string 改为 int64
  • DTO 中 ID 字段统一改为 int64;所有 DTO 增加中文字段注释。
  • @Router 的路径参数补全 <int> 约束。
  1. 再改 Service
  • id string 改为 id int64,移除 cast.ToInt64
  • 依赖 model 的场景改为 @Bind xxx model(id) + *models.Xxx 直接注入。
  1. 同步前端调用
  • URL/query 参数统一为 contentId / userId / tenantId(与 @Bind 的 key 对齐)。
  • 处理 ID 显示与输入时的类型转换(数值 ↔ 字符串)。
  1. 生成与验证
  • 运行 atomctl gen routeatomctl gen provideratomctl swag init
  • 回归测试:关键列表、详情、操作接口。

四、建议的修复优先级

  1. 多租户路由 + tenant_id 强隔离
  2. 超管鉴权/角色校验 + Login/Token 实现
  3. ID 类型统一与 :id<int> 路由规范
  4. 规格一致性(认证/存储/迁移)
  5. 性能优化N+1/聚合)与可维护性补齐