Conversation
- 新增 APP_URL 环境变量,支持自定义 OpenAPI server URL - 动态生成 OpenAPI servers 配置,优先使用环境变量 - 开发环境自动使用 localhost,生产环境提示配置 - 更新 .env.example 和 CLAUDE.md 文档 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
- 移除 Command 组件的 flex-1 类 - 移除 PopoverContent 的固定高度 h-[500px] - 移除 CommandList 的 flex-1 类 - 让弹出框根据实际内容自适应高度
**问题描述**: 非管理员 Key 登录后台时,在日志查询页面无法选择 API 密钥, 因为 Key 下拉框显示为空(没有选项)。 **根本原因**: 1. 页面初始化时,非管理员用户没有预加载 Keys 列表 2. 筛选器组件的 Keys 加载逻辑依赖于 userId,但非管理员 场景下 userId 为空(不显示用户选择框),导致永远不会触发加载 **修复方案** (方案 A - SSR 预加载): 1. **page.tsx**: 非管理员用户在页面加载时预加载当前用户的 Keys 2. **usage-logs-view.tsx**: 新增 initialKeys prop 并传递给筛选器 3. **usage-logs-filters.tsx**: - 使用 initialKeys 初始化 keys 状态 - 修改 useEffect 逻辑,仅在管理员场景才动态加载 - 优化 disabled 和 placeholder 逻辑,兼容非管理员场景 **效果**: - ✅ 非管理员用户登录后立即可选择自己的 API 密钥 - ✅ SSR 预加载,首屏即可使用,无需等待客户端请求 - ✅ 减少不必要的异步请求,提升性能 - ✅ 符合 Next.js SSR 最佳实践 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
✅ 代码审查通过感谢提交这个修复!经过详细的代码审查,这个 PR 的实现质量很高,核心修复逻辑正确且符合最佳实践。 审查要点✅ 核心修复(非管理员用户无法选择 API 密钥)问题分析准确:
修复方案优秀:
技术亮点:
✅ 相关变更合理性版本升级(
文档更新(
依赖数据更新(
代码质量:
建议
结论✅ 推荐合并 - 这个 PR 成功解决了 Issue #57,实现质量高,无明显问题。 🤖 自动化代码审查 by Claude Code Assistant |
| const [models, setModels] = useState<string[]>([]); | ||
| const [statusCodes, setStatusCodes] = useState<number[]>([]); | ||
| const [keys, setKeys] = useState<Key[]>([]); | ||
| const [keys, setKeys] = useState<Key[]>(initialKeys); |
There was a problem hiding this comment.
✅ 核心修复:使用 initialKeys 初始化 state,确保非管理员用户在页面加载时就有可用的 Keys 列表。
修复前:useState<Key[]>([]) - 始终为空数组
修复后:useState<Key[]>(initialKeys) - 从 SSR 预加载的数据初始化
这是解决 Issue #57 的关键改动!
| : [[], [], await searchParams, await getSystemSettings()]; | ||
| // 管理员:获取用户和供应商列表 | ||
| // 非管理员:获取当前用户的 Keys 列表 | ||
| const [users, providers, initialKeys, resolvedSearchParams, systemSettings] = isAdmin |
There was a problem hiding this comment.
✅ SSR 最佳实践:在服务端预加载非管理员用户的 Keys,避免客户端异步加载导致的空状态。
优点:
- 首屏即可使用,无需等待异步请求
- 减少客户端 API 调用
- 符合 Next.js App Router 数据获取模式
建议:如果未来 Keys 数量很大,可以考虑添加分页或限制返回数量。
| if (localFilters.userId) { | ||
| // 管理员:如果选择了用户,加载该用户的 keys | ||
| // 非管理员:已经有 initialKeys,不需要额外加载 | ||
| if (isAdmin && localFilters.userId) { |
There was a problem hiding this comment.
✅ 逻辑优化:只在管理员场景才动态加载 Keys,非管理员直接使用 initialKeys。
修复前问题:
- 非管理员场景下
localFilters.userId为空 - 导致永远不会触发
getKeys()调用 - Keys 列表始终为空
修复后:
- 非管理员使用 SSR 预加载的
initialKeys - 管理员选择用户后动态加载该用户的 Keys
- 两种场景都能正常工作
代码审查总结✅ 优点
📝 代码质量page.tsx (28-36 行):
usage-logs-filters.tsx (72, 93-98, 196, 199 行):
usage-logs-view.tsx (35, 44, 51, 257 行):
|
关联 Issue
Close #57
问题描述
非管理员 Key 登录后台时,在日志查询页面无法选择 API 密钥,因为 Key 下拉框显示为空(没有选项)。
根本原因
页面初始化缺陷 (
src/app/dashboard/logs/page.tsx:26-28):users和providers被初始化为空数组筛选器组件依赖问题 (
src/app/dashboard/logs/_components/usage-logs-filters.tsx:89-95):localFilters.userId有值时加载userId为空(不显示用户选择框),永远不会触发加载结果:
keys状态始终为空数组修复方案 (方案 A - SSR 预加载)
1. page.tsx - 预加载非管理员用户的 Keys
2. usage-logs-view.tsx - 传递 initialKeys prop
3. usage-logs-filters.tsx - 使用 initialKeys 初始化
修复效果
测试建议
非管理员场景
/dashboard/logs日志查询页面管理员场景
/dashboard/logs日志查询页面相关文件
src/app/dashboard/logs/page.tsxsrc/app/dashboard/logs/_components/usage-logs-view.tsxsrc/app/dashboard/logs/_components/usage-logs-filters.tsx🤖 Generated with Claude Code