feat: 实现连接列表中标签的内联编辑和创建

允许用户直接在连接列表的标签分组标题上进行编辑
This commit is contained in:
Baobhan Sith
2025-05-03 09:48:47 +08:00
parent b40be119d4
commit bc85d52aa5
10 changed files with 477 additions and 71 deletions
@@ -412,3 +412,76 @@ export const cloneConnection = async (req: Request, res: Response): Promise<void
}
}
};
/**
* 为多个连接添加一个标签 (POST /api/v1/connections/add-tag)
* 注意:我们改变了路由和方法 (POST),并使用请求体传递所有信息,以避免嵌套事务。
*/
export const addTagToConnections = async (req: Request, res: Response): Promise<void> => {
try {
const { connection_ids, tag_id } = req.body;
// 验证输入
if (!Array.isArray(connection_ids) || !connection_ids.every(id => typeof id === 'number')) {
res.status(400).json({ message: 'connection_ids 必须是一个数字数组。' });
return;
}
if (typeof tag_id !== 'number' || tag_id <= 0) {
res.status(400).json({ message: 'tag_id 必须是一个有效的正整数。' });
return;
}
if (connection_ids.length === 0) {
res.status(400).json({ message: 'connection_ids 不能为空数组。' });
return;
}
// 调用服务层批量添加标签
await ConnectionService.addTagToConnections(connection_ids, tag_id);
res.status(200).json({ message: '标签已成功添加到指定连接。' });
} catch (error: any) {
console.error(`Controller: 为多个连接添加标签 ${req.body?.tag_id} 时发生错误:`, error);
// 可以根据服务层抛出的错误类型返回更具体的错误码
if (error.message.includes('标签 ID') && error.message.includes('不存在')) {
res.status(400).json({ message: error.message }); // Bad request if tag doesn't exist
} else {
res.status(500).json({ message: error.message || '为连接添加标签时发生内部服务器错误。' });
}
}
};
/**
* 更新单个连接的标签 (PUT /api/v1/connections/:id/tags)
* (保留此接口,但主要逻辑由 addTagToConnections 处理)
*/
export const updateConnectionTags = async (req: Request, res: Response): Promise<void> => {
try {
const connectionId = parseInt(req.params.id, 10);
const { tag_ids } = req.body;
if (isNaN(connectionId)) {
res.status(400).json({ message: '无效的连接 ID。' });
return;
}
if (!Array.isArray(tag_ids) || !tag_ids.every(id => typeof id === 'number')) {
res.status(400).json({ message: 'tag_ids 必须是一个数字数组。' });
return;
}
const success = await ConnectionService.updateConnectionTags(connectionId, tag_ids);
if (!success) {
res.status(404).json({ message: '连接未找到或更新标签失败。' });
} else {
res.status(200).json({ message: '连接标签更新成功。' });
}
} catch (error: any) {
console.error(`Controller: 更新连接 ${req.params.id} 的标签时发生错误:`, error);
if (error.message.includes('未找到')) {
res.status(404).json({ message: error.message });
} else {
res.status(500).json({ message: error.message || '更新连接标签时发生内部服务器错误。' });
}
}
};
@@ -12,7 +12,9 @@ import {
exportConnections,
importConnections,
getRdpSessionToken, // Import the new controller function
cloneConnection // +++ Import the clone controller function +++
cloneConnection, // +++ Import the clone controller function +++
// updateConnectionTags, // No longer directly used by primary flow
addTagToConnections // +++ Import the new controller function for adding tag to multiple connections +++
} from './connections.controller';
const router = Router();
@@ -84,4 +86,10 @@ router.post('/:id/rdp-session', getRdpSessionToken);
// +++ POST /api/v1/connections/:id/clone - 克隆连接 +++
router.post('/:id/clone', cloneConnection);
// +++ POST /api/v1/connections/add-tag - 为多个连接添加一个标签 +++
router.post('/add-tag', addTagToConnections);
// Note: PUT /:id/tags route is removed as the primary flow uses the bulk add endpoint now.
// It could be kept if there's a separate use case for updating a single connection's tags.
export default router;