mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-22 16:43:35 +00:00
feat: api-stats页面增加周限总限查询
This commit is contained in:
20
README.md
20
README.md
@@ -17,10 +17,17 @@
|
||||
|
||||
---
|
||||
|
||||
## ⭐ 如果觉得有用,点个Star支持一下吧!
|
||||
## 💎 Claude 拼车 - Claude Code 合租服务推荐
|
||||
|
||||
> 开源不易,你的Star是我持续更新的动力 🚀
|
||||
> 欢迎加入 [Telegram 公告频道](https://t.me/claude_relay_service) 获取最新动态
|
||||
<div align="center">
|
||||
|
||||
| 平台 | 类型 | 介绍 |
|
||||
|:---:|:---:|:---|
|
||||
| **[PinCC.ai](https://pincc.ai/)** | 🏆 **官方运营** | 项目官方直营的Claude拼车服务<br>提供200刀 Claude Code Max 套餐共享服务 |
|
||||
| **[CToK.ai](https://ctok.ai/)** | 🤝 合作伙伴 | 社区认可的Claude拼车服务,稳定可靠 |
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
@@ -42,11 +49,6 @@
|
||||
|
||||
如果有以上困惑,那这个项目可能适合你。
|
||||
|
||||
> 💡 **Claude Code 拼车服务**
|
||||
> 目前有两个稳定的 Claude Code Max 20X 200刀 拼车渠道:
|
||||
> 1. **PinCC** - 项目官方运营的拼车服务:[https://pincc.ai/](https://pincc.ai/)
|
||||
> 2. **CToK** - 社区认可的合作伙伴服务:[https://ctok.ai/](https://ctok.ai/)
|
||||
|
||||
### 适合的场景
|
||||
|
||||
✅ **找朋友拼车**: 三五好友一起分摊Claude Code Max订阅
|
||||
@@ -76,8 +78,6 @@
|
||||
|
||||
## 🚀 核心功能
|
||||
|
||||
> 📸 **[查看演示站点](https://demo.pincc.ai/admin-next/login)**
|
||||
|
||||
### 基础功能
|
||||
|
||||
- ✅ **多账户管理**: 可以添加多个Claude账户自动轮换
|
||||
|
||||
@@ -376,12 +376,14 @@ router.post('/api/user-stats', async (req, res) => {
|
||||
rateLimitCost: parseFloat(fullKeyData.rateLimitCost) || 0, // 新增:费用限制
|
||||
dailyCostLimit: fullKeyData.dailyCostLimit || 0,
|
||||
totalCostLimit: fullKeyData.totalCostLimit || 0,
|
||||
weeklyOpusCostLimit: parseFloat(fullKeyData.weeklyOpusCostLimit) || 0, // Opus 周费用限制
|
||||
// 当前使用量
|
||||
currentWindowRequests,
|
||||
currentWindowTokens,
|
||||
currentWindowCost, // 新增:当前窗口费用
|
||||
currentDailyCost,
|
||||
currentTotalCost: totalCost,
|
||||
weeklyOpusCost: (await redis.getWeeklyOpusCost(keyId)) || 0, // 当前 Opus 周费用
|
||||
// 时间窗口信息
|
||||
windowStartTime,
|
||||
windowEndTime,
|
||||
|
||||
@@ -135,6 +135,59 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 总费用限制 -->
|
||||
<div>
|
||||
<div class="mb-2 flex items-center justify-between">
|
||||
<span class="text-sm font-medium text-gray-600 dark:text-gray-400 md:text-base"
|
||||
>总费用限制</span
|
||||
>
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400 md:text-sm">
|
||||
<span v-if="statsData.limits.totalCostLimit > 0">
|
||||
${{ statsData.limits.currentTotalCost.toFixed(4) }} / ${{
|
||||
statsData.limits.totalCostLimit.toFixed(2)
|
||||
}}
|
||||
</span>
|
||||
<span v-else class="flex items-center gap-1">
|
||||
${{ statsData.limits.currentTotalCost.toFixed(4) }} / <i class="fas fa-infinity" />
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="statsData.limits.totalCostLimit > 0"
|
||||
class="h-2 w-full rounded-full bg-gray-200 dark:bg-gray-700"
|
||||
>
|
||||
<div
|
||||
class="h-2 rounded-full transition-all duration-300"
|
||||
:class="getTotalCostProgressColor()"
|
||||
:style="{ width: getTotalCostProgress() + '%' }"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="h-2 w-full rounded-full bg-gray-200">
|
||||
<div class="h-2 rounded-full bg-blue-500" style="width: 0%" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Opus 模型周费用限制 -->
|
||||
<div v-if="statsData.limits.weeklyOpusCostLimit > 0">
|
||||
<div class="mb-2 flex items-center justify-between">
|
||||
<span class="text-sm font-medium text-gray-600 dark:text-gray-400 md:text-base"
|
||||
>Opus 模型周费用限制</span
|
||||
>
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400 md:text-sm">
|
||||
${{ statsData.limits.weeklyOpusCost.toFixed(4) }} / ${{
|
||||
statsData.limits.weeklyOpusCostLimit.toFixed(2)
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="h-2 w-full rounded-full bg-gray-200 dark:bg-gray-700">
|
||||
<div
|
||||
class="h-2 rounded-full transition-all duration-300"
|
||||
:class="getOpusWeeklyCostProgressColor()"
|
||||
:style="{ width: getOpusWeeklyCostProgress() + '%' }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 时间窗口限制 -->
|
||||
<div
|
||||
v-if="
|
||||
@@ -334,6 +387,43 @@ const getDailyCostProgressColor = () => {
|
||||
return 'bg-green-500'
|
||||
}
|
||||
|
||||
// 获取总费用进度
|
||||
const getTotalCostProgress = () => {
|
||||
if (!statsData.value.limits.totalCostLimit || statsData.value.limits.totalCostLimit === 0)
|
||||
return 0
|
||||
const percentage =
|
||||
(statsData.value.limits.currentTotalCost / statsData.value.limits.totalCostLimit) * 100
|
||||
return Math.min(percentage, 100)
|
||||
}
|
||||
|
||||
// 获取总费用进度条颜色
|
||||
const getTotalCostProgressColor = () => {
|
||||
const progress = getTotalCostProgress()
|
||||
if (progress >= 100) return 'bg-red-500'
|
||||
if (progress >= 80) return 'bg-yellow-500'
|
||||
return 'bg-blue-500'
|
||||
}
|
||||
|
||||
// 获取Opus周费用进度
|
||||
const getOpusWeeklyCostProgress = () => {
|
||||
if (
|
||||
!statsData.value.limits.weeklyOpusCostLimit ||
|
||||
statsData.value.limits.weeklyOpusCostLimit === 0
|
||||
)
|
||||
return 0
|
||||
const percentage =
|
||||
(statsData.value.limits.weeklyOpusCost / statsData.value.limits.weeklyOpusCostLimit) * 100
|
||||
return Math.min(percentage, 100)
|
||||
}
|
||||
|
||||
// 获取Opus周费用进度条颜色
|
||||
const getOpusWeeklyCostProgressColor = () => {
|
||||
const progress = getOpusWeeklyCostProgress()
|
||||
if (progress >= 100) return 'bg-red-500'
|
||||
if (progress >= 80) return 'bg-yellow-500'
|
||||
return 'bg-indigo-500' // 使用紫色表示Opus模型
|
||||
}
|
||||
|
||||
// 格式化数字
|
||||
const formatNumber = (num) => {
|
||||
if (typeof num !== 'number') {
|
||||
|
||||
@@ -260,6 +260,12 @@ export const useApiStatsStore = defineStore('apistats', () => {
|
||||
if (result.success) {
|
||||
statsData.value = result.data
|
||||
|
||||
// 调试:打印返回的限制数据
|
||||
console.log('API Stats - Full response:', result.data)
|
||||
console.log('API Stats - limits data:', result.data.limits)
|
||||
console.log('API Stats - weeklyOpusCostLimit:', result.data.limits?.weeklyOpusCostLimit)
|
||||
console.log('API Stats - weeklyOpusCost:', result.data.limits?.weeklyOpusCost)
|
||||
|
||||
// 同时加载今日和本月的统计数据
|
||||
await loadAllPeriodStats()
|
||||
|
||||
|
||||
@@ -430,16 +430,14 @@
|
||||
<div
|
||||
class="overflow-x-auto rounded bg-gray-900 p-2 font-mono text-xs text-green-400 sm:p-3 sm:text-sm"
|
||||
>
|
||||
<div class="whitespace-nowrap text-gray-300">model_provider = "crs"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">model = "gpt-5-codex"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">model_reasoning_effort = "high"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">disable_response_storage = true</div>
|
||||
<div class="whitespace-nowrap text-gray-300">preferred_auth_method = "apikey"</div>
|
||||
<div class="mt-2"></div>
|
||||
<div class="whitespace-nowrap text-gray-300">[model_providers.crs]</div>
|
||||
<div class="whitespace-nowrap text-gray-300">name = "crs"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">base_url = "{{ openaiBaseUrl }}"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">wire_api = "responses"</div>
|
||||
<div
|
||||
v-for="line in codexConfigContent.configToml"
|
||||
:key="line"
|
||||
class="whitespace-nowrap text-gray-300"
|
||||
:class="{ 'mt-2': line === '' }"
|
||||
>
|
||||
{{ line }}
|
||||
</div>
|
||||
</div>
|
||||
<p class="mt-3 text-sm text-yellow-700">
|
||||
在
|
||||
@@ -449,13 +447,59 @@
|
||||
<div
|
||||
class="mt-2 overflow-x-auto rounded bg-gray-900 p-2 font-mono text-xs text-green-400 sm:p-3 sm:text-sm"
|
||||
>
|
||||
<div class="whitespace-nowrap text-gray-300">{</div>
|
||||
<div class="whitespace-nowrap text-gray-300">"OPENAI_API_KEY": "你的API密钥"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">}</div>
|
||||
<div
|
||||
v-for="line in codexConfigContent.authJson"
|
||||
:key="line"
|
||||
class="whitespace-nowrap text-gray-300"
|
||||
>
|
||||
{{ line }}
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-yellow-700">
|
||||
💡 使用与 Claude Code 相同的 API 密钥即可,格式如 cr_xxxxxxxxxx。
|
||||
</div>
|
||||
<div class="mt-3 space-y-3 text-xs text-yellow-700 dark:text-yellow-300">
|
||||
<!-- 描述文字 -->
|
||||
<p>{{ codexConfigContent.authInstructions.description }}</p>
|
||||
|
||||
<!-- 标题 -->
|
||||
<h6 class="text-sm font-medium text-yellow-800 dark:text-yellow-200">
|
||||
{{ codexConfigContent.authInstructions.title }}
|
||||
</h6>
|
||||
|
||||
<!-- 当前平台对应的环境变量设置 -->
|
||||
<div class="space-y-2">
|
||||
<p class="font-medium">
|
||||
{{ codexConfigContent.authInstructions.platform.title }}:
|
||||
</p>
|
||||
<div
|
||||
class="overflow-x-auto rounded bg-gray-900 p-2 font-mono text-xs text-green-400 sm:p-3 sm:text-sm"
|
||||
>
|
||||
<div class="whitespace-nowrap text-gray-300">
|
||||
{{ codexConfigContent.authInstructions.platform.command }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Shell 配置文件(仅对于 macOS/Linux 显示) -->
|
||||
<div v-if="codexConfigContent.authInstructions.persistent" class="space-y-2">
|
||||
<p class="font-medium">
|
||||
{{ codexConfigContent.authInstructions.persistent.title }}:
|
||||
</p>
|
||||
<p class="text-xs">
|
||||
{{ codexConfigContent.authInstructions.persistent.description }}
|
||||
</p>
|
||||
<div
|
||||
class="overflow-x-auto rounded bg-gray-900 p-2 font-mono text-xs text-green-400 sm:p-3 sm:text-sm"
|
||||
>
|
||||
<div
|
||||
v-for="command in codexConfigContent.authInstructions.persistent.commands"
|
||||
:key="command"
|
||||
class="whitespace-nowrap text-gray-300"
|
||||
:class="{ 'mt-2': command === '' }"
|
||||
>
|
||||
{{ command }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -917,16 +961,14 @@
|
||||
<div
|
||||
class="overflow-x-auto rounded bg-gray-900 p-2 font-mono text-xs text-green-400 sm:p-3 sm:text-sm"
|
||||
>
|
||||
<div class="whitespace-nowrap text-gray-300">model_provider = "crs"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">model = "gpt-5-codex"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">model_reasoning_effort = "high"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">disable_response_storage = true</div>
|
||||
<div class="whitespace-nowrap text-gray-300">preferred_auth_method = "apikey"</div>
|
||||
<div class="mt-2"></div>
|
||||
<div class="whitespace-nowrap text-gray-300">[model_providers.crs]</div>
|
||||
<div class="whitespace-nowrap text-gray-300">name = "crs"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">base_url = "{{ openaiBaseUrl }}"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">wire_api = "responses"</div>
|
||||
<div
|
||||
v-for="line in codexConfigContent.configToml"
|
||||
:key="line"
|
||||
class="whitespace-nowrap text-gray-300"
|
||||
:class="{ 'mt-2': line === '' }"
|
||||
>
|
||||
{{ line }}
|
||||
</div>
|
||||
</div>
|
||||
<p class="mt-3 text-sm text-yellow-700">
|
||||
在
|
||||
@@ -936,13 +978,59 @@
|
||||
<div
|
||||
class="mt-2 overflow-x-auto rounded bg-gray-900 p-2 font-mono text-xs text-green-400 sm:p-3 sm:text-sm"
|
||||
>
|
||||
<div class="whitespace-nowrap text-gray-300">{</div>
|
||||
<div class="whitespace-nowrap text-gray-300">"OPENAI_API_KEY": "你的API密钥"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">}</div>
|
||||
<div
|
||||
v-for="line in codexConfigContent.authJson"
|
||||
:key="line"
|
||||
class="whitespace-nowrap text-gray-300"
|
||||
>
|
||||
{{ line }}
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-yellow-700">
|
||||
💡 使用与 Claude Code 相同的 API 密钥即可,格式如 cr_xxxxxxxxxx。
|
||||
</div>
|
||||
<div class="mt-3 space-y-3 text-xs text-yellow-700 dark:text-yellow-300">
|
||||
<!-- 描述文字 -->
|
||||
<p>{{ codexConfigContent.authInstructions.description }}</p>
|
||||
|
||||
<!-- 标题 -->
|
||||
<h6 class="text-sm font-medium text-yellow-800 dark:text-yellow-200">
|
||||
{{ codexConfigContent.authInstructions.title }}
|
||||
</h6>
|
||||
|
||||
<!-- 当前平台对应的环境变量设置 -->
|
||||
<div class="space-y-2">
|
||||
<p class="font-medium">
|
||||
{{ codexConfigContent.authInstructions.platform.title }}:
|
||||
</p>
|
||||
<div
|
||||
class="overflow-x-auto rounded bg-gray-900 p-2 font-mono text-xs text-green-400 sm:p-3 sm:text-sm"
|
||||
>
|
||||
<div class="whitespace-nowrap text-gray-300">
|
||||
{{ codexConfigContent.authInstructions.platform.command }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Shell 配置文件(仅对于 macOS/Linux 显示) -->
|
||||
<div v-if="codexConfigContent.authInstructions.persistent" class="space-y-2">
|
||||
<p class="font-medium">
|
||||
{{ codexConfigContent.authInstructions.persistent.title }}:
|
||||
</p>
|
||||
<p class="text-xs">
|
||||
{{ codexConfigContent.authInstructions.persistent.description }}
|
||||
</p>
|
||||
<div
|
||||
class="overflow-x-auto rounded bg-gray-900 p-2 font-mono text-xs text-green-400 sm:p-3 sm:text-sm"
|
||||
>
|
||||
<div
|
||||
v-for="command in codexConfigContent.authInstructions.persistent.commands"
|
||||
:key="command"
|
||||
class="whitespace-nowrap text-gray-300"
|
||||
:class="{ 'mt-2': command === '' }"
|
||||
>
|
||||
{{ command }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1395,16 +1483,14 @@
|
||||
<div
|
||||
class="overflow-x-auto rounded bg-gray-900 p-2 font-mono text-xs text-green-400 sm:p-3 sm:text-sm"
|
||||
>
|
||||
<div class="whitespace-nowrap text-gray-300">model_provider = "crs"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">model = "gpt-5-codex"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">model_reasoning_effort = "high"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">disable_response_storage = true</div>
|
||||
<div class="whitespace-nowrap text-gray-300">preferred_auth_method = "apikey"</div>
|
||||
<div class="mt-2"></div>
|
||||
<div class="whitespace-nowrap text-gray-300">[model_providers.crs]</div>
|
||||
<div class="whitespace-nowrap text-gray-300">name = "crs"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">base_url = "{{ openaiBaseUrl }}"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">wire_api = "responses"</div>
|
||||
<div
|
||||
v-for="line in codexConfigContent.configToml"
|
||||
:key="line"
|
||||
class="whitespace-nowrap text-gray-300"
|
||||
:class="{ 'mt-2': line === '' }"
|
||||
>
|
||||
{{ line }}
|
||||
</div>
|
||||
</div>
|
||||
<p class="mt-3 text-sm text-yellow-700">
|
||||
在
|
||||
@@ -1414,13 +1500,59 @@
|
||||
<div
|
||||
class="mt-2 overflow-x-auto rounded bg-gray-900 p-2 font-mono text-xs text-green-400 sm:p-3 sm:text-sm"
|
||||
>
|
||||
<div class="whitespace-nowrap text-gray-300">{</div>
|
||||
<div class="whitespace-nowrap text-gray-300">"OPENAI_API_KEY": "你的API密钥"</div>
|
||||
<div class="whitespace-nowrap text-gray-300">}</div>
|
||||
<div
|
||||
v-for="line in codexConfigContent.authJson"
|
||||
:key="line"
|
||||
class="whitespace-nowrap text-gray-300"
|
||||
>
|
||||
{{ line }}
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-yellow-700">
|
||||
💡 使用与 Claude Code 相同的 API 密钥即可,格式如 cr_xxxxxxxxxx。
|
||||
</div>
|
||||
<div class="mt-3 space-y-3 text-xs text-yellow-700 dark:text-yellow-300">
|
||||
<!-- 描述文字 -->
|
||||
<p>{{ codexConfigContent.authInstructions.description }}</p>
|
||||
|
||||
<!-- 标题 -->
|
||||
<h6 class="text-sm font-medium text-yellow-800 dark:text-yellow-200">
|
||||
{{ codexConfigContent.authInstructions.title }}
|
||||
</h6>
|
||||
|
||||
<!-- 当前平台对应的环境变量设置 -->
|
||||
<div class="space-y-2">
|
||||
<p class="font-medium">
|
||||
{{ codexConfigContent.authInstructions.platform.title }}:
|
||||
</p>
|
||||
<div
|
||||
class="overflow-x-auto rounded bg-gray-900 p-2 font-mono text-xs text-green-400 sm:p-3 sm:text-sm"
|
||||
>
|
||||
<div class="whitespace-nowrap text-gray-300">
|
||||
{{ codexConfigContent.authInstructions.platform.command }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Shell 配置文件(仅对于 macOS/Linux 显示) -->
|
||||
<div v-if="codexConfigContent.authInstructions.persistent" class="space-y-2">
|
||||
<p class="font-medium">
|
||||
{{ codexConfigContent.authInstructions.persistent.title }}:
|
||||
</p>
|
||||
<p class="text-xs">
|
||||
{{ codexConfigContent.authInstructions.persistent.description }}
|
||||
</p>
|
||||
<div
|
||||
class="overflow-x-auto rounded bg-gray-900 p-2 font-mono text-xs text-green-400 sm:p-3 sm:text-sm"
|
||||
>
|
||||
<div
|
||||
v-for="command in codexConfigContent.authInstructions.persistent.commands"
|
||||
:key="command"
|
||||
class="whitespace-nowrap text-gray-300"
|
||||
:class="{ 'mt-2': command === '' }"
|
||||
>
|
||||
{{ command }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1627,7 +1759,6 @@ const getBaseUrlPrefix = () => {
|
||||
origin = currentUrl.substring(0, pathStart)
|
||||
} else {
|
||||
// 最后的降级方案,使用相对路径
|
||||
console.warn('无法获取完整的 origin,将使用相对路径')
|
||||
return ''
|
||||
}
|
||||
}
|
||||
@@ -1649,6 +1780,92 @@ const geminiBaseUrl = computed(() => {
|
||||
const openaiBaseUrl = computed(() => {
|
||||
return getBaseUrlPrefix() + '/openai'
|
||||
})
|
||||
|
||||
// Codex 配置内容
|
||||
const codexConfigContent = computed(() => {
|
||||
// 根据当前激活的教程系统获取对应的环境变量设置说明
|
||||
const getCurrentPlatformAuthInstructions = () => {
|
||||
const baseInstructions = {
|
||||
title: '环境变量设置方法',
|
||||
description:
|
||||
'💡 将 OPENAI_API_KEY 设置为 null,然后设置环境变量 CRS_OAI_KEY 为您的 API 密钥(格式如 cr_xxxxxxxxxx)。'
|
||||
}
|
||||
|
||||
switch (activeTutorialSystem.value) {
|
||||
case 'windows':
|
||||
return {
|
||||
...baseInstructions,
|
||||
platform: {
|
||||
title: 'Windows',
|
||||
command: 'set CRS_OAI_KEY=cr_xxxxxxxxxx'
|
||||
}
|
||||
}
|
||||
case 'macos':
|
||||
return {
|
||||
...baseInstructions,
|
||||
platform: {
|
||||
title: 'macOS',
|
||||
command: 'export CRS_OAI_KEY=cr_xxxxxxxxxx'
|
||||
},
|
||||
persistent: {
|
||||
title: 'Shell 配置文件(持久保存)',
|
||||
description: '添加到您的 shell 配置文件中:',
|
||||
commands: [
|
||||
'# 对于 zsh (默认)',
|
||||
'echo "export CRS_OAI_KEY=cr_xxxxxxxxxx" >> ~/.zshrc',
|
||||
'source ~/.zshrc',
|
||||
'',
|
||||
'# 对于 bash',
|
||||
'echo "export CRS_OAI_KEY=cr_xxxxxxxxxx" >> ~/.bash_profile',
|
||||
'source ~/.bash_profile'
|
||||
]
|
||||
}
|
||||
}
|
||||
case 'linux':
|
||||
return {
|
||||
...baseInstructions,
|
||||
platform: {
|
||||
title: 'Linux',
|
||||
command: 'export CRS_OAI_KEY=cr_xxxxxxxxxx'
|
||||
},
|
||||
persistent: {
|
||||
title: 'Shell 配置文件(持久保存)',
|
||||
description: '添加到您的 shell 配置文件中:',
|
||||
commands: [
|
||||
'# 对于 bash (默认)',
|
||||
'echo "export CRS_OAI_KEY=cr_xxxxxxxxxx" >> ~/.bashrc',
|
||||
'source ~/.bashrc',
|
||||
'',
|
||||
'# 对于 zsh',
|
||||
'echo "export CRS_OAI_KEY=cr_xxxxxxxxxx" >> ~/.zshrc',
|
||||
'source ~/.zshrc'
|
||||
]
|
||||
}
|
||||
}
|
||||
default:
|
||||
return baseInstructions
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
configToml: [
|
||||
'model_provider = "crs"',
|
||||
'model = "gpt-5-codex"',
|
||||
'model_reasoning_effort = "high"',
|
||||
'disable_response_storage = true',
|
||||
'preferred_auth_method = "apikey"',
|
||||
'',
|
||||
'[model_providers.crs]',
|
||||
'name = "crs"',
|
||||
`base_url = "${openaiBaseUrl.value}"`,
|
||||
'wire_api = "responses"',
|
||||
'requires_openai_auth = true',
|
||||
'env_key = "CRS_OAI_KEY"'
|
||||
],
|
||||
authJson: ['{', ' "OPENAI_API_KEY": null', '}'],
|
||||
authInstructions: getCurrentPlatformAuthInstructions()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -388,7 +388,6 @@ const handleLogout = async () => {
|
||||
showToast('Logged out successfully', 'success')
|
||||
router.push('/user-login')
|
||||
} catch (error) {
|
||||
console.error('Logout error:', error)
|
||||
showToast('Logout failed', 'error')
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user