已按企业级标准完成全量审查（约 1.4 万行 Python，覆盖 25 个业务模块 + 核心框架）。以下按严重程度分类汇总。

  ---
  一、严重 BUG（功能已损坏 / 需立即修复）

  1. 上传接口全部 500 —— 缺 request 参数

  apps/views/upload.py:15/23/31 三个端点签名是 async def upload_image(file: UploadFile = File(...))，没有 Request 参数。而 permission_required 装饰器（apps/middleware/permission_required.py:11-19）靠 _extract_request()
  从参数里找 Request，找不到就传 None 进 _check(None) → get_user_id(None) → None.state 抛 AttributeError → 所有用户（含 admin）上传图片/文件都报 500。

  ▎ 修复：三个函数都补上 request: Request 参数。

  2. Excel 导入功能必崩

  apps/services/level.py:190：result = await upload.upload_file(...) 返回的是 JSONResponse（R.ok/R.failed），不是 dict，result.get('code') 抛 AttributeError → 500。职级导入完全不可用（全库仅此一处）。

  ▎ 修复：改为 result.status_code == 200 后 json.loads(result.body)，或让 upload.upload_file 返回 dict。

  3. 权限字符串系统性不匹配 → 非 admin 用户全部被拒（RBAC 失效）

  - 视图层要求：sys:{module}:page（分页）、sys:{module}:batch_delete（批量删除）——见 apps/views/level.py:19/96 及全部模块。
  - 权限节点生成器 apps/services/menu.py:244/274 生成的是 sys:{module}:list 和 sys:{module}:dall。
  - 种子数据 document/djangoadmin.fastapi.elevue.sql 存的也是 sys:level:list / sys:level:dall。
  - 只有 dept 和 menu 视图用 list（与种子一致），其余 20+ 模块全不一致。

  结果：非 admin 用户即使在菜单里勾选了"查询"，拿到的是 sys:level:list，但 /level/page 端点校验 sys:level:page → 永远"权限不足"。批量删除节点（dall）更是完全无效。

  ▎ 修复：统一三处（视图、set_permission、种子 SQL）的权限字符串，建议全部收敛为 page / batch_delete。

  ---
  二、高危（安全隐患 / 影响稳定性）

  4. 操作日志中间件同步 HTTP 调用阻塞事件循环

  apps/middleware/operation_log.py:74-91 在 finally 里直接（未走 to_thread）调用 record_operation_log → utils/ip.py:59 的 get_ip_location 用同步 urllib.request.urlopen(..., timeout=3) 访问
  ipapi.co。每次写操作都可能把整个事件循环卡住最长 3 秒，并发下是稳定性隐患。（login_log 在登录服务里已用 asyncio.to_thread 包装，唯独 operation_log 中间件漏了。）

  ▎ 修复：把 record_operation_log 包进 asyncio.to_thread；或 IP 定位改为异步/本地库。

  5. 分页参数非数字 → 500（全模块）

  所有 services 都是 int(request.query_params.get("pageNo", 1))，传 ?pageNo=abc 即抛 ValueError。apps/__init__.py 全局异常只处理了 Authorization/Business/RequestValidation 三类，未捕获 ValueError → 裸 500。22
  个模块的列表页全中招。

  6. 省市区字段 NOT NULL 冲突 → IntegrityError

  apps/forms/member.py:16-18、apps/forms/user.py:20-22 的 province_code/city_code/district_code 是 Optional(None)，但模型 apps/models/member.py:66-70、user.py:74-78 是 nullable=False。当 city 数组不足 3 个元素时，字段保持 None →
   插入/更新抛 IntegrityError → 500。add_user/add_member/update_* 均受影响。

  7. 上传大小校验在整文件读入内存之后

  apps/services/upload.py:204-208 先 await file.read() 全量读入内存，再比对 UPLOAD_MAX_SIZE_MB。攻击者传超大文件即可耗尽内存（DoS）。应先用 Content-Length 头预检，或流式分段读取。

  8. 存储型 XSS 风险

  - .svg 在允许列表中，_sanitize_svg 的 apps/services/upload.py:101-128 正则可被绕过（HTML 实体、foreignObject、命名空间等），且无 X-Content-Type-Options: nosniff 保障（若 Nginx 直接服务 uploads/ 目录则风险实锤）。
  - apps/services/notice.py:91/122 富文本 content 只转义 title，正文 HTML 原样存储并原样返回（get_notice_detail 第 76 行），无服务端清洗。公告若展示给前台用户即为存储型 XSS。

  9. 密钥/配置管理

  - .env 未列入 .gitignore（当前项目是 SVN 且 .env 在根目录），内含 DB 密码 root、Redis 密码 123456、JWT 密钥。若入库即泄露。
  - .env 中 FASTAPI_UPLOAD_DIR=E:\DjangoAdmin\... 是写死的异机绝对路径（与当前目录 D:\Temp\... 不符）；FASTAPI_IMAGE_URL='http://images.fastapi.elevue' 是假域名。FASTAPI_DEBUG=True、DB_DEBUG=True 默认开。
  - 本应用没有挂载静态目录（全库无 StaticFiles/mount），上传文件必须靠外部 Nginx 服务，否则返回的 fileUrl 不可访问——部署时需确认。

  ---
  三、中低危 / 优化点

  事务与数据一致性
  - apps/services/job.py:216/239 在请求内直接 db.commit()，与 db_session_middleware 统一提交重复（冗余）；且 pause_job_by_id 里 job.update_user = job.create_user（应为当前操作人 get_user_id(request)）。
  - update_user_info（apps/services/user.py:312-329）bulk update 不触发 onupdate，update_time/update_user 不会被更新。

  性能
  - 权限 JOIN（menu.get_permissions_list_sync，apps/services/menu.py:332-345）对 user_role.user_id/role_id、role_menu.menu_id/role_id、menu.parent_id、user.dept_id 等列全无索引，非 admin 每次请求全表扫描。建议加索引。
  - perm_cache.invalidate_role_perms（utils/perm_cache.py:117-118）在异步上下文里直接同步 db.query，未走 to_thread。
  - 22 个模块的 get_*_page 分页/回退逻辑高度重复，可抽取公共分页组件。

  健壮性
  - get_access_token（utils/jwt.py:422）replace('Bearer ', '') 大小写敏感，客户端发 bearer  小写会解析失败。
  - captcha 防刷 redis.get 后 incr 存在 TOCTOU 竞态（utils/captcha.py:106-130），并发可绕过上限。
  - detail 路由 id 为裸字符串（apps/views/level.py:28），未做 int 校验，非法值直接进 SQL。
  - base_model.batch_delete_r（apps/models/base_model.py:176）只要有一个 id 不存在就整体报"记录不存在"（all-or-nothing），行为需与前端确认。
  - rich_text.save_file（utils/rich_text.py:58-69）对 URL 中的 .. 未规范化，存在目录穿越到上传目录外的可能（需源文件已存在，低危）。

  一致性/代码质量
  - JobLog 用 del_flag（apps/models/job_log.py:46），其余模型统一 is_delete；create_user/update_user 用 String(50) 而非 Integer。
  - forms/dept.py 校验 type 仅 1-2，而模型注释是 1-4。
  - config/sms.py 读的 SMS_URL/SMS_API_KEY... 与 .env 中实际变量（SMS_ALIYUN_*）不一致（当前无用，属预留模块）。
  - R.ok 允许 kwargs 覆盖 code，可能产生 {"ok": True, "code": 1} 的矛盾响应；R.failed 默认 code=1 与中间件"code==0 即成功"判断需保持口径一致。
  - 无测试套件、无 lint/format 配置（CLAUDE.md 已注明），建议至少补 pytest 覆盖鉴权中间件与 CRUD 主路径。

  ---
  四、建议修复优先级

  1. 立即：#1 上传 500、#2 Excel 导入 500、#3 权限字符串统一（功能不可用 / RBAC 失效）
  2. 尽快：#4 事件循环阻塞、#5 分页 500、#6 NOT NULL 冲突、#7 上传内存 DoS
  3. 安全：#8 富文本/SVG XSS、#9 密钥与 DEBUG 配置
  4. 后续：#11 索引、#12 公共分页组件、其余一致性项

  需要我直接开始修复吗？可以按优先级逐个处理，或先修最严重的 #1–#3（三个都是几行的改动，我可以一次性完成并自测）。