feat: 完善账户多分组功能和Azure OpenAI支持

主要功能:
- 实现账户多分组调度功能完整支持
- 修复Azure OpenAI账户优先级显示问题(前端条件判断缺失)
- 修复未分组筛选功能失效(API参数处理)
- 修复Azure OpenAI账户创建错误调用Gemini API的问题
- 完善各平台分组信息支持和使用统计显示
- 统一删除账户时的分组清理逻辑
- 添加前端请求参数处理支持

技术改进:
- 前端支持多平台账户请求构造
- 后端统一groupInfos返回格式
- API客户端完善查询参数处理

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
sczheng189
2025-09-02 20:16:20 +08:00
parent e69ab2161d
commit 37e6c14eac
10 changed files with 617 additions and 517 deletions

View File

@@ -13,7 +13,7 @@ class AccountGroupService {
* 创建账户分组
* @param {Object} groupData - 分组数据
* @param {string} groupData.name - 分组名称
* @param {string} groupData.platform - 平台类型 (claude/gemini)
* @param {string} groupData.platform - 平台类型 (claude/gemini/openai)
* @param {string} groupData.description - 分组描述
* @returns {Object} 创建的分组
*/
@@ -327,12 +327,36 @@ class AccountGroupService {
}
}
/**
* 根据账户ID获取其所属的分组兼容性方法返回单个分组
* @param {string} accountId - 账户ID
* @returns {Object|null} 分组信息
*/
async getAccountGroup(accountId) {
try {
const client = redis.getClientSafe()
const allGroupIds = await client.smembers(this.GROUPS_KEY)
for (const groupId of allGroupIds) {
const isMember = await client.sismember(`${this.GROUP_MEMBERS_PREFIX}${groupId}`, accountId)
if (isMember) {
return await this.getGroup(groupId)
}
}
return null
} catch (error) {
logger.error('❌ 获取账户所属分组失败:', error)
throw error
}
}
/**
* 根据账户ID获取其所属的所有分组
* @param {string} accountId - 账户ID
* @returns {Array} 分组信息数组
*/
async getAccountGroup(accountId) {
async getAccountGroups(accountId) {
try {
const client = redis.getClientSafe()
const allGroupIds = await client.smembers(this.GROUPS_KEY)
@@ -357,6 +381,49 @@ class AccountGroupService {
throw error
}
}
/**
* 批量设置账户的分组
* @param {string} accountId - 账户ID
* @param {Array} groupIds - 分组ID数组
* @param {string} accountPlatform - 账户平台
*/
async setAccountGroups(accountId, groupIds, accountPlatform) {
try {
// 首先移除账户的所有现有分组
await this.removeAccountFromAllGroups(accountId)
// 然后添加到新的分组中
for (const groupId of groupIds) {
await this.addAccountToGroup(accountId, groupId, accountPlatform)
}
logger.success(`✅ 批量设置账户分组成功: ${accountId} -> [${groupIds.join(', ')}]`)
} catch (error) {
logger.error('❌ 批量设置账户分组失败:', error)
throw error
}
}
/**
* 从所有分组中移除账户
* @param {string} accountId - 账户ID
*/
async removeAccountFromAllGroups(accountId) {
try {
const client = redis.getClientSafe()
const allGroupIds = await client.smembers(this.GROUPS_KEY)
for (const groupId of allGroupIds) {
await client.srem(`${this.GROUP_MEMBERS_PREFIX}${groupId}`, accountId)
}
logger.success(`✅ 从所有分组移除账户成功: ${accountId}`)
} catch (error) {
logger.error('❌ 从所有分组移除账户失败:', error)
throw error
}
}
}
module.exports = new AccountGroupService()

View File

@@ -249,6 +249,10 @@ async function updateAccount(accountId, updates) {
// 删除账户
async function deleteAccount(accountId) {
// 首先从所有分组中移除此账户
const accountGroupService = require('./accountGroupService')
await accountGroupService.removeAccountFromAllGroups(accountId)
const client = redisClient.getClientSafe()
const accountKey = `${AZURE_OPENAI_ACCOUNT_KEY_PREFIX}${accountId}`

View File

@@ -611,10 +611,7 @@ class ClaudeAccountService {
try {
// 首先从所有分组中移除此账户
const accountGroupService = require('./accountGroupService')
const groups = await accountGroupService.getAccountGroup(accountId)
for (const group of groups) {
await accountGroupService.removeAccountFromGroup(accountId, group.id)
}
await accountGroupService.removeAccountFromAllGroups(accountId)
const result = await redis.deleteClaudeAccount(accountId)

View File

@@ -585,6 +585,10 @@ async function deleteAccount(accountId) {
throw new Error('Account not found')
}
// 首先从所有分组中移除此账户
const accountGroupService = require('./accountGroupService')
await accountGroupService.removeAccountFromAllGroups(accountId)
// 从 Redis 删除
const client = redisClient.getClientSafe()
await client.del(`${GEMINI_ACCOUNT_KEY_PREFIX}${accountId}`)

View File

@@ -440,6 +440,10 @@ async function deleteAccount(accountId) {
throw new Error('Account not found')
}
// 首先从所有分组中移除此账户
const accountGroupService = require('./accountGroupService')
await accountGroupService.removeAccountFromAllGroups(accountId)
// 从 Redis 删除
const client = redisClient.getClientSafe()
await client.del(`${OPENAI_ACCOUNT_KEY_PREFIX}${accountId}`)