feat: Codex账号管理优化与API Key激活机制

 新功能
- 支持通过refreshToken新增Codex账号,创建时立即验证token有效性
- API Key新增首次使用自动激活机制,支持activation模式设置有效期
- 前端账号表单增加token验证功能,确保账号创建成功

🐛 修复
- 修复Codex token刷新失败问题,增加分布式锁防止并发刷新
- 优化token刷新错误处理,提供更详细的错误信息和建议
- 修复OpenAI账号token过期检测和自动刷新逻辑

📝 文档更新
- 更新README中Codex使用说明,改为config.toml配置方式
- 优化Cherry Studio等第三方工具接入文档
- 添加详细的配置示例和账号类型说明

🎨 界面优化
- 改进账号创建表单UI,支持手动和OAuth两种模式
- 优化API Key过期时间编辑弹窗,支持激活操作
- 调整教程页面布局,提升移动端响应式体验

💡 代码改进
- 重构token刷新服务,增强错误处理和重试机制
- 优化代理配置处理,确保OAuth请求正确使用代理
- 改进webhook通知,增加token刷新失败告警
This commit is contained in:
shaw
2025-09-06 17:39:05 +08:00
parent 0e746b1056
commit d2f3f6866c
19 changed files with 1231 additions and 463 deletions

View File

@@ -34,7 +34,7 @@
>
<input
v-model="form.name"
class="form-input w-full text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
class="form-input w-full border-gray-300 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
maxlength="100"
placeholder="请输入API Key名称"
required
@@ -53,7 +53,7 @@
>
<select
v-model="form.ownerId"
class="form-input w-full dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200"
class="form-input w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200"
>
<option v-for="user in availableUsers" :key="user.id" :value="user.id">
{{ user.displayName }} ({{ user.username }})
@@ -122,7 +122,7 @@
<div class="flex gap-2">
<input
v-model="newTag"
class="form-input flex-1 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
class="form-input flex-1 border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
placeholder="输入新标签名称"
type="text"
@keypress.enter.prevent="addTag"
@@ -166,7 +166,7 @@
>
<input
v-model="form.rateLimitWindow"
class="form-input w-full text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
class="form-input w-full border-gray-300 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
min="1"
placeholder="无限制"
type="number"
@@ -180,7 +180,7 @@
>
<input
v-model="form.rateLimitRequests"
class="form-input w-full text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
class="form-input w-full border-gray-300 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
min="1"
placeholder="无限制"
type="number"
@@ -194,7 +194,7 @@
>
<input
v-model="form.rateLimitCost"
class="form-input w-full text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
class="form-input w-full border-gray-300 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
min="0"
placeholder="无限制"
step="0.01"
@@ -259,7 +259,7 @@
</div>
<input
v-model="form.dailyCostLimit"
class="form-input w-full dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
class="form-input w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
min="0"
placeholder="0 表示无限制"
step="0.01"
@@ -308,7 +308,7 @@
</div>
<input
v-model="form.weeklyOpusCostLimit"
class="form-input w-full dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
class="form-input w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
min="0"
placeholder="0 表示无限制"
step="0.01"
@@ -326,7 +326,7 @@
>
<input
v-model="form.concurrencyLimit"
class="form-input w-full dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
class="form-input w-full border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
min="0"
placeholder="0 表示无限制"
type="number"
@@ -558,7 +558,7 @@
<div class="flex gap-2">
<input
v-model="form.modelInput"
class="form-input flex-1 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
class="form-input flex-1 border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-200 dark:placeholder-gray-400"
placeholder="输入模型名称,按回车添加"
type="text"
@keydown.enter.prevent="addRestrictedModel"