mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-23 00:53:33 +00:00
fix: 1.修复ClaudeConsole账号设置为专属绑定的功能
2. 修复Claude 官方账号会话窗口计算错误的问题
This commit is contained in:
@@ -267,13 +267,24 @@
|
||||
:disabled="form.permissions === 'gemini'"
|
||||
>
|
||||
<option value="">使用共享账号池</option>
|
||||
<option
|
||||
v-for="account in accounts.claude.filter(a => a.isDedicated)"
|
||||
:key="account.id"
|
||||
:value="account.id"
|
||||
>
|
||||
{{ account.name }} ({{ account.status === 'active' ? '正常' : '异常' }})
|
||||
</option>
|
||||
<optgroup v-if="accounts.claude.filter(a => a.isDedicated && a.platform === 'claude-oauth').length > 0" label="Claude OAuth 账号">
|
||||
<option
|
||||
v-for="account in accounts.claude.filter(a => a.isDedicated && a.platform === 'claude-oauth')"
|
||||
:key="account.id"
|
||||
:value="account.id"
|
||||
>
|
||||
{{ account.name }} ({{ account.status === 'active' ? '正常' : '异常' }})
|
||||
</option>
|
||||
</optgroup>
|
||||
<optgroup v-if="accounts.claude.filter(a => a.isDedicated && a.platform === 'claude-console').length > 0" label="Claude Console 账号">
|
||||
<option
|
||||
v-for="account in accounts.claude.filter(a => a.isDedicated && a.platform === 'claude-console')"
|
||||
:key="account.id"
|
||||
:value="`console:${account.id}`"
|
||||
>
|
||||
{{ account.name }} ({{ account.status === 'active' ? '正常' : '异常' }})
|
||||
</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
@@ -603,11 +614,25 @@ const createApiKey = async () => {
|
||||
dailyCostLimit: form.dailyCostLimit !== '' && form.dailyCostLimit !== null ? parseFloat(form.dailyCostLimit) : 0,
|
||||
expiresAt: form.expiresAt || undefined,
|
||||
permissions: form.permissions,
|
||||
claudeAccountId: form.claudeAccountId || undefined,
|
||||
geminiAccountId: form.geminiAccountId || undefined,
|
||||
tags: form.tags.length > 0 ? form.tags : undefined
|
||||
}
|
||||
|
||||
// 处理Claude账户绑定(区分OAuth和Console)
|
||||
if (form.claudeAccountId) {
|
||||
if (form.claudeAccountId.startsWith('console:')) {
|
||||
// Claude Console账户
|
||||
data.claudeConsoleAccountId = form.claudeAccountId.substring(8);
|
||||
} else {
|
||||
// Claude OAuth账户
|
||||
data.claudeAccountId = form.claudeAccountId;
|
||||
}
|
||||
}
|
||||
|
||||
// Gemini账户绑定
|
||||
if (form.geminiAccountId) {
|
||||
data.geminiAccountId = form.geminiAccountId;
|
||||
}
|
||||
|
||||
// 模型限制 - 始终提交这些字段
|
||||
data.enableModelRestriction = form.enableModelRestriction
|
||||
data.restrictedModels = form.restrictedModels
|
||||
|
||||
@@ -224,13 +224,24 @@
|
||||
:disabled="form.permissions === 'gemini'"
|
||||
>
|
||||
<option value="">使用共享账号池</option>
|
||||
<option
|
||||
v-for="account in accounts.claude"
|
||||
:key="account.id"
|
||||
:value="account.id"
|
||||
>
|
||||
{{ account.name }} ({{ account.status === 'active' ? '正常' : '异常' }})
|
||||
</option>
|
||||
<optgroup v-if="accounts.claude.filter(a => a.isDedicated && a.platform === 'claude-oauth').length > 0" label="Claude OAuth 账号">
|
||||
<option
|
||||
v-for="account in accounts.claude.filter(a => a.isDedicated && a.platform === 'claude-oauth')"
|
||||
:key="account.id"
|
||||
:value="account.id"
|
||||
>
|
||||
{{ account.name }} ({{ account.status === 'active' ? '正常' : '异常' }})
|
||||
</option>
|
||||
</optgroup>
|
||||
<optgroup v-if="accounts.claude.filter(a => a.isDedicated && a.platform === 'claude-console').length > 0" label="Claude Console 账号">
|
||||
<option
|
||||
v-for="account in accounts.claude.filter(a => a.isDedicated && a.platform === 'claude-console')"
|
||||
:key="account.id"
|
||||
:value="`console:${account.id}`"
|
||||
>
|
||||
{{ account.name }} ({{ account.status === 'active' ? '正常' : '异常' }})
|
||||
</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
@@ -242,7 +253,7 @@
|
||||
>
|
||||
<option value="">使用共享账号池</option>
|
||||
<option
|
||||
v-for="account in accounts.gemini"
|
||||
v-for="account in accounts.gemini.filter(a => a.isDedicated)"
|
||||
:key="account.id"
|
||||
:value="account.id"
|
||||
>
|
||||
@@ -476,8 +487,6 @@ const updateApiKey = async () => {
|
||||
concurrencyLimit: form.concurrencyLimit !== '' && form.concurrencyLimit !== null ? parseInt(form.concurrencyLimit) : 0,
|
||||
dailyCostLimit: form.dailyCostLimit !== '' && form.dailyCostLimit !== null ? parseFloat(form.dailyCostLimit) : 0,
|
||||
permissions: form.permissions,
|
||||
claudeAccountId: form.claudeAccountId || null,
|
||||
geminiAccountId: form.geminiAccountId || null,
|
||||
tags: form.tags
|
||||
}
|
||||
|
||||
@@ -489,6 +498,25 @@ const updateApiKey = async () => {
|
||||
data.enableClientRestriction = form.enableClientRestriction
|
||||
data.allowedClients = form.allowedClients
|
||||
|
||||
// 处理Claude账户绑定(区分OAuth和Console)
|
||||
if (form.claudeAccountId) {
|
||||
if (form.claudeAccountId.startsWith('console:')) {
|
||||
// Claude Console账户
|
||||
data.claudeConsoleAccountId = form.claudeAccountId.substring(8);
|
||||
data.claudeAccountId = null; // 清空OAuth绑定
|
||||
} else {
|
||||
// Claude OAuth账户
|
||||
data.claudeAccountId = form.claudeAccountId;
|
||||
data.claudeConsoleAccountId = null; // 清空Console绑定
|
||||
}
|
||||
} else {
|
||||
data.claudeAccountId = null;
|
||||
data.claudeConsoleAccountId = null;
|
||||
}
|
||||
|
||||
// Gemini账户绑定
|
||||
data.geminiAccountId = form.geminiAccountId || null;
|
||||
|
||||
const result = await apiClient.put(`/admin/api-keys/${props.apiKey.id}`, data)
|
||||
|
||||
if (result.success) {
|
||||
@@ -517,7 +545,15 @@ onMounted(async () => {
|
||||
form.concurrencyLimit = props.apiKey.concurrencyLimit || ''
|
||||
form.dailyCostLimit = props.apiKey.dailyCostLimit || ''
|
||||
form.permissions = props.apiKey.permissions || 'all'
|
||||
form.claudeAccountId = props.apiKey.claudeAccountId || ''
|
||||
// 处理Claude账户绑定初始化
|
||||
if (props.apiKey.claudeAccountId) {
|
||||
form.claudeAccountId = props.apiKey.claudeAccountId;
|
||||
} else if (props.apiKey.claudeConsoleAccountId) {
|
||||
form.claudeAccountId = `console:${props.apiKey.claudeConsoleAccountId}`;
|
||||
} else {
|
||||
form.claudeAccountId = '';
|
||||
}
|
||||
|
||||
form.geminiAccountId = props.apiKey.geminiAccountId || ''
|
||||
form.restrictedModels = props.apiKey.restrictedModels || []
|
||||
form.allowedClients = props.apiKey.allowedClients || []
|
||||
|
||||
@@ -397,8 +397,9 @@ const loadAccounts = async () => {
|
||||
|
||||
if (claudeConsoleData.success) {
|
||||
const claudeConsoleAccounts = (claudeConsoleData.data || []).map(acc => {
|
||||
// Claude Console账户暂时不支持直接绑定
|
||||
return { ...acc, platform: 'claude-console', boundApiKeysCount: 0 }
|
||||
// 计算每个Claude Console账户绑定的API Key数量
|
||||
const boundApiKeysCount = apiKeys.value.filter(key => key.claudeConsoleAccountId === acc.id).length
|
||||
return { ...acc, platform: 'claude-console', boundApiKeysCount }
|
||||
})
|
||||
allAccounts.push(...claudeConsoleAccounts)
|
||||
}
|
||||
|
||||
@@ -98,9 +98,9 @@
|
||||
<div class="text-sm font-semibold text-gray-900">{{ key.name }}</div>
|
||||
<div class="text-xs text-gray-500">{{ key.id }}</div>
|
||||
<div class="text-xs text-gray-500 mt-1">
|
||||
<span v-if="key.claudeAccountId">
|
||||
<span v-if="key.claudeAccountId || key.claudeConsoleAccountId">
|
||||
<i class="fas fa-link mr-1"></i>
|
||||
绑定: {{ getBoundAccountName(key.claudeAccountId) }}
|
||||
绑定: {{ getBoundAccountName(key.claudeAccountId, key.claudeConsoleAccountId) }}
|
||||
</span>
|
||||
<span v-else>
|
||||
<i class="fas fa-share-alt mr-1"></i>
|
||||
@@ -546,17 +546,42 @@ const sortedApiKeys = computed(() => {
|
||||
// 加载账户列表
|
||||
const loadAccounts = async () => {
|
||||
try {
|
||||
const [claudeData, geminiData] = await Promise.all([
|
||||
const [claudeData, claudeConsoleData, geminiData] = await Promise.all([
|
||||
apiClient.get('/admin/claude-accounts'),
|
||||
apiClient.get('/admin/claude-console-accounts'),
|
||||
apiClient.get('/admin/gemini-accounts')
|
||||
])
|
||||
|
||||
// 合并Claude OAuth账户和Claude Console账户
|
||||
const claudeAccounts = []
|
||||
|
||||
if (claudeData.success) {
|
||||
accounts.value.claude = claudeData.data || []
|
||||
claudeData.data?.forEach(account => {
|
||||
claudeAccounts.push({
|
||||
...account,
|
||||
platform: 'claude-oauth',
|
||||
isDedicated: account.accountType === 'dedicated'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if (claudeConsoleData.success) {
|
||||
claudeConsoleData.data?.forEach(account => {
|
||||
claudeAccounts.push({
|
||||
...account,
|
||||
platform: 'claude-console',
|
||||
isDedicated: account.accountType === 'dedicated'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
accounts.value.claude = claudeAccounts
|
||||
|
||||
if (geminiData.success) {
|
||||
accounts.value.gemini = geminiData.data || []
|
||||
accounts.value.gemini = (geminiData.data || []).map(account => ({
|
||||
...account,
|
||||
isDedicated: account.accountType === 'dedicated'
|
||||
}))
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载账户列表失败:', error)
|
||||
@@ -611,23 +636,28 @@ const calculateApiKeyCost = (usage) => {
|
||||
}
|
||||
|
||||
// 获取绑定账户名称
|
||||
const getBoundAccountName = (accountId) => {
|
||||
if (!accountId) return '未知账户'
|
||||
|
||||
// 从Claude账户列表中查找
|
||||
const claudeAccount = accounts.value.claude.find(acc => acc.id === accountId)
|
||||
if (claudeAccount) {
|
||||
return claudeAccount.name
|
||||
const getBoundAccountName = (claudeAccountId, claudeConsoleAccountId) => {
|
||||
// 优先显示Claude OAuth账户
|
||||
if (claudeAccountId) {
|
||||
const claudeAccount = accounts.value.claude.find(acc => acc.id === claudeAccountId)
|
||||
if (claudeAccount) {
|
||||
return claudeAccount.name
|
||||
}
|
||||
// 如果找不到,返回账户ID的前8位
|
||||
return `账户-${claudeAccountId.substring(0, 8)}`
|
||||
}
|
||||
|
||||
// 从Gemini账户列表中查找
|
||||
const geminiAccount = accounts.value.gemini.find(acc => acc.id === accountId)
|
||||
if (geminiAccount) {
|
||||
return geminiAccount.name
|
||||
// 其次显示Claude Console账户
|
||||
if (claudeConsoleAccountId) {
|
||||
const consoleAccount = accounts.value.claude.find(acc => acc.id === claudeConsoleAccountId)
|
||||
if (consoleAccount) {
|
||||
return `${consoleAccount.name} (Console)`
|
||||
}
|
||||
// 如果找不到,返回账户ID的前8位
|
||||
return `Console-${claudeConsoleAccountId.substring(0, 8)}`
|
||||
}
|
||||
|
||||
// 如果找不到,返回账户ID的前8位
|
||||
return `账户-${accountId.substring(0, 8)}`
|
||||
return '未知账户'
|
||||
}
|
||||
|
||||
// 检查API Key是否过期
|
||||
|
||||
Reference in New Issue
Block a user