diff --git a/VERSION b/VERSION index 38c3e77e..0aff1c08 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.270 +1.1.271 diff --git a/src/routes/admin/openaiAccounts.js b/src/routes/admin/openaiAccounts.js index 6d98e682..f0c350e9 100644 --- a/src/routes/admin/openaiAccounts.js +++ b/src/routes/admin/openaiAccounts.js @@ -327,6 +327,7 @@ router.post('/', authenticateAdmin, async (req, res) => { proxy, accountType, groupId, + groupIds, // 支持多分组 rateLimitDuration, priority, needsImmediateRefresh, // 是否需要立即刷新 @@ -376,9 +377,13 @@ router.post('/', authenticateAdmin, async (req, res) => { throw new Error('无法获取 ID Token,请检查 Refresh Token 是否有效') } - // 如果是分组类型,添加到分组 - if (accountType === 'group' && groupId) { - await accountGroupService.addAccountToGroup(tempAccount.id, groupId, 'openai') + // 如果是分组类型,添加到分组(支持多分组) + if (accountType === 'group') { + if (groupIds && groupIds.length > 0) { + await accountGroupService.setAccountGroups(tempAccount.id, groupIds, 'openai') + } else if (groupId) { + await accountGroupService.addAccountToGroup(tempAccount.id, groupId, 'openai') + } } // 清除敏感信息后返回 @@ -434,9 +439,13 @@ router.post('/', authenticateAdmin, async (req, res) => { // 不需要强制刷新的情况(OAuth 模式或其他平台) const createdAccount = await openaiAccountService.createAccount(accountData) - // 如果是分组类型,添加到分组 - if (accountType === 'group' && groupId) { - await accountGroupService.addAccountToGroup(createdAccount.id, groupId, 'openai') + // 如果是分组类型,添加到分组(支持多分组) + if (accountType === 'group') { + if (groupIds && groupIds.length > 0) { + await accountGroupService.setAccountGroups(createdAccount.id, groupIds, 'openai') + } else if (groupId) { + await accountGroupService.addAccountToGroup(createdAccount.id, groupId, 'openai') + } } // 如果需要刷新但不强制成功(OAuth 模式可能已有完整信息) @@ -487,9 +496,15 @@ router.put('/:id', authenticateAdmin, async (req, res) => { .json({ error: 'Invalid account type. Must be "shared", "dedicated" or "group"' }) } - // 如果更新为分组类型,验证groupId - if (mappedUpdates.accountType === 'group' && !mappedUpdates.groupId) { - return res.status(400).json({ error: 'Group ID is required for group type accounts' }) + // 如果更新为分组类型,验证groupId或groupIds + if ( + mappedUpdates.accountType === 'group' && + !mappedUpdates.groupId && + (!mappedUpdates.groupIds || mappedUpdates.groupIds.length === 0) + ) { + return res + .status(400) + .json({ error: 'Group ID or Group IDs are required for group type accounts' }) } // 获取账户当前信息以处理分组变更 @@ -587,16 +602,25 @@ router.put('/:id', authenticateAdmin, async (req, res) => { // 处理分组的变更 if (mappedUpdates.accountType !== undefined) { - // 如果之前是分组类型,需要从原分组中移除 + // 如果之前是分组类型,移除所有原分组关联 if (currentAccount.accountType === 'group') { - const oldGroup = await accountGroupService.getAccountGroup(id) - if (oldGroup) { - await accountGroupService.removeAccountFromGroup(id, oldGroup.id) - } + await accountGroupService.removeAccountFromAllGroups(id) } - // 如果新类型是分组,添加到新分组 - if (mappedUpdates.accountType === 'group' && mappedUpdates.groupId) { - await accountGroupService.addAccountToGroup(id, mappedUpdates.groupId, 'openai') + // 如果新类型是分组,处理多分组支持 + if (mappedUpdates.accountType === 'group') { + if (Object.prototype.hasOwnProperty.call(mappedUpdates, 'groupIds')) { + // 如果明确提供了 groupIds 参数(包括空数组) + if (mappedUpdates.groupIds && mappedUpdates.groupIds.length > 0) { + // 设置新的多分组 + await accountGroupService.setAccountGroups(id, mappedUpdates.groupIds, 'openai') + } else { + // groupIds 为空数组,从所有分组中移除 + await accountGroupService.removeAccountFromAllGroups(id) + } + } else if (mappedUpdates.groupId) { + // 向后兼容:仅当没有 groupIds 但有 groupId 时使用单分组逻辑 + await accountGroupService.addAccountToGroup(id, mappedUpdates.groupId, 'openai') + } } }