fix: 修复编辑账户时分组调度选择不生效的问题

- 为 Claude Console 和 Gemini 账户的更新接口添加分组处理逻辑
- 处理账户类型变更时的分组关系(从旧分组移除,添加到新分组)
- 修复前端编辑账户时分组 ID 的初始化问题
- 优化删除账户时自动从分组中移除的逻辑

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
shaw
2025-08-05 19:02:27 +08:00
parent f46653a461
commit 4ebe6abd96
2 changed files with 95 additions and 9 deletions

View File

@@ -1252,6 +1252,38 @@ router.put('/claude-console-accounts/:accountId', authenticateAdmin, async (req,
return res.status(400).json({ error: 'Priority must be between 1 and 100' }); return res.status(400).json({ error: 'Priority must be between 1 and 100' });
} }
// 验证accountType的有效性
if (updates.accountType && !['shared', 'dedicated', 'group'].includes(updates.accountType)) {
return res.status(400).json({ error: 'Invalid account type. Must be "shared", "dedicated" or "group"' });
}
// 如果更新为分组类型验证groupId
if (updates.accountType === 'group' && !updates.groupId) {
return res.status(400).json({ error: 'Group ID is required for group type accounts' });
}
// 获取账户当前信息以处理分组变更
const currentAccount = await claudeConsoleAccountService.getAccount(accountId);
if (!currentAccount) {
return res.status(404).json({ error: 'Account not found' });
}
// 处理分组的变更
if (updates.accountType !== undefined) {
// 如果之前是分组类型,需要从原分组中移除
if (currentAccount.accountType === 'group') {
const oldGroup = await accountGroupService.getAccountGroup(accountId);
if (oldGroup) {
await accountGroupService.removeAccountFromGroup(accountId, oldGroup.id);
}
}
// 如果新类型是分组,添加到新分组
if (updates.accountType === 'group' && updates.groupId) {
// Claude Console 账户在分组中被视为 'claude' 平台
await accountGroupService.addAccountToGroup(accountId, updates.groupId, 'claude');
}
}
await claudeConsoleAccountService.updateAccount(accountId, updates); await claudeConsoleAccountService.updateAccount(accountId, updates);
logger.success(`📝 Admin updated Claude Console account: ${accountId}`); logger.success(`📝 Admin updated Claude Console account: ${accountId}`);
@@ -1267,6 +1299,15 @@ router.delete('/claude-console-accounts/:accountId', authenticateAdmin, async (r
try { try {
const { accountId } = req.params; const { accountId } = req.params;
// 获取账户信息以检查是否在分组中
const account = await claudeConsoleAccountService.getAccount(accountId);
if (account && account.accountType === 'group') {
const group = await accountGroupService.getAccountGroup(accountId);
if (group) {
await accountGroupService.removeAccountFromGroup(accountId, group.id);
}
}
await claudeConsoleAccountService.deleteAccount(accountId); await claudeConsoleAccountService.deleteAccount(accountId);
logger.success(`🗑️ Admin deleted Claude Console account: ${accountId}`); logger.success(`🗑️ Admin deleted Claude Console account: ${accountId}`);
@@ -1497,6 +1538,37 @@ router.put('/gemini-accounts/:accountId', authenticateAdmin, async (req, res) =>
const { accountId } = req.params; const { accountId } = req.params;
const updates = req.body; const updates = req.body;
// 验证accountType的有效性
if (updates.accountType && !['shared', 'dedicated', 'group'].includes(updates.accountType)) {
return res.status(400).json({ error: 'Invalid account type. Must be "shared", "dedicated" or "group"' });
}
// 如果更新为分组类型验证groupId
if (updates.accountType === 'group' && !updates.groupId) {
return res.status(400).json({ error: 'Group ID is required for group type accounts' });
}
// 获取账户当前信息以处理分组变更
const currentAccount = await geminiAccountService.getAccount(accountId);
if (!currentAccount) {
return res.status(404).json({ error: 'Account not found' });
}
// 处理分组的变更
if (updates.accountType !== undefined) {
// 如果之前是分组类型,需要从原分组中移除
if (currentAccount.accountType === 'group') {
const oldGroup = await accountGroupService.getAccountGroup(accountId);
if (oldGroup) {
await accountGroupService.removeAccountFromGroup(accountId, oldGroup.id);
}
}
// 如果新类型是分组,添加到新分组
if (updates.accountType === 'group' && updates.groupId) {
await accountGroupService.addAccountToGroup(accountId, updates.groupId, 'gemini');
}
}
const updatedAccount = await geminiAccountService.updateAccount(accountId, updates); const updatedAccount = await geminiAccountService.updateAccount(accountId, updates);
logger.success(`📝 Admin updated Gemini account: ${accountId}`); logger.success(`📝 Admin updated Gemini account: ${accountId}`);
@@ -1512,6 +1584,15 @@ router.delete('/gemini-accounts/:accountId', authenticateAdmin, async (req, res)
try { try {
const { accountId } = req.params; const { accountId } = req.params;
// 获取账户信息以检查是否在分组中
const account = await geminiAccountService.getAccount(accountId);
if (account && account.accountType === 'group') {
const group = await accountGroupService.getAccountGroup(accountId);
if (group) {
await accountGroupService.removeAccountFromGroup(accountId, group.id);
}
}
await geminiAccountService.deleteAccount(accountId); await geminiAccountService.deleteAccount(accountId);
logger.success(`🗑️ Admin deleted Gemini account: ${accountId}`); logger.success(`🗑️ Admin deleted Gemini account: ${accountId}`);

View File

@@ -1395,7 +1395,11 @@ watch(() => props.account, (newAccount) => {
if (newAccount.accountType === 'group') { if (newAccount.accountType === 'group') {
// 先加载分组列表 // 先加载分组列表
loadGroups().then(() => { loadGroups().then(() => {
// 查找账户所属的分组 // 如果账户有 groupInfo直接使用它的 groupId
if (newAccount.groupInfo && newAccount.groupInfo.id) {
form.value.groupId = newAccount.groupInfo.id
} else {
// 否则查找账户所属的分组
groups.value.forEach(group => { groups.value.forEach(group => {
apiClient.get(`/admin/account-groups/${group.id}/members`).then(response => { apiClient.get(`/admin/account-groups/${group.id}/members`).then(response => {
const members = response.data || [] const members = response.data || []
@@ -1404,6 +1408,7 @@ watch(() => props.account, (newAccount) => {
} }
}).catch(() => {}) }).catch(() => {})
}) })
}
}) })
} }
} }