import { Router } from 'express'; import { body, param, query } from 'express-validator'; import { AccountService } from '../services/AccountService.js'; import { browserLoginService } from '../services/BrowserLoginService.js'; import { authenticate } from '../middleware/auth.js'; import { asyncHandler } from '../middleware/error.js'; import { validateRequest } from '../middleware/validate.js'; import type { PlatformType } from '@media-manager/shared'; const router = Router(); const accountService = new AccountService(); // 所有路由需要认证 router.use(authenticate); // ============ 账号分组 ============ // 获取分组列表 router.get( '/groups', asyncHandler(async (req, res) => { const groups = await accountService.getGroups(req.user!.userId); res.json({ success: true, data: groups }); }) ); // 创建分组 router.post( '/groups', [ body('name').notEmpty().withMessage('分组名称不能为空'), validateRequest, ], asyncHandler(async (req, res) => { const group = await accountService.createGroup(req.user!.userId, req.body); res.status(201).json({ success: true, data: group }); }) ); // 更新分组 router.put( '/groups/:id', [ param('id').isInt().withMessage('分组ID无效'), validateRequest, ], asyncHandler(async (req, res) => { const group = await accountService.updateGroup( req.user!.userId, Number(req.params.id), req.body ); res.json({ success: true, data: group }); }) ); // 删除分组 router.delete( '/groups/:id', [ param('id').isInt().withMessage('分组ID无效'), validateRequest, ], asyncHandler(async (req, res) => { await accountService.deleteGroup(req.user!.userId, Number(req.params.id)); res.json({ success: true, message: '分组已删除' }); }) ); // ============ 平台账号 ============ // 获取账号列表 router.get( '/', asyncHandler(async (req, res) => { const { platform, groupId, status } = req.query; const accounts = await accountService.getAccounts(req.user!.userId, { platform: platform as string, groupId: groupId ? Number(groupId) : undefined, status: status as string, }); res.json({ success: true, data: accounts }); }) ); // 获取单个账号 router.get( '/:id', [ param('id').isInt().withMessage('账号ID无效'), validateRequest, ], asyncHandler(async (req, res) => { const account = await accountService.getAccountById( req.user!.userId, Number(req.params.id) ); res.json({ success: true, data: account }); }) ); // 添加账号(通过 Cookie) router.post( '/', [ body('platform').notEmpty().withMessage('平台不能为空'), body('cookieData').notEmpty().withMessage('Cookie不能为空'), validateRequest, ], asyncHandler(async (req, res) => { const account = await accountService.addAccount(req.user!.userId, req.body); res.status(201).json({ success: true, data: account }); }) ); // 更新账号 router.put( '/:id', [ param('id').isInt().withMessage('账号ID无效'), validateRequest, ], asyncHandler(async (req, res) => { const account = await accountService.updateAccount( req.user!.userId, Number(req.params.id), req.body ); res.json({ success: true, data: account }); }) ); // 删除账号 router.delete( '/:id', [ param('id').isInt().withMessage('账号ID无效'), validateRequest, ], asyncHandler(async (req, res) => { await accountService.deleteAccount(req.user!.userId, Number(req.params.id)); res.json({ success: true, message: '账号已删除' }); }) ); // 刷新账号状态 router.post( '/:id/refresh', [ param('id').isInt().withMessage('账号ID无效'), validateRequest, ], asyncHandler(async (req, res) => { const result = await accountService.refreshAccount( req.user!.userId, Number(req.params.id) ); const { needReLogin, ...account } = result; res.json({ success: true, data: account, needReLogin: needReLogin || false, }); }) ); // 检查账号 Cookie 是否有效 router.get( '/:id/check-status', [ param('id').isInt().withMessage('账号ID无效'), validateRequest, ], asyncHandler(async (req, res) => { const result = await accountService.checkAccountStatus( req.user!.userId, Number(req.params.id) ); res.json({ success: true, data: { isValid: result.isValid, needReLogin: !result.isValid, } }); }) ); // 批量刷新所有账号状态 router.post( '/refresh-all', asyncHandler(async (req, res) => { const result = await accountService.refreshAllAccounts(req.user!.userId); res.json({ success: true, data: result, }); }) ); // 获取扫码登录二维码 router.post( '/qrcode', [ body('platform').notEmpty().withMessage('平台不能为空'), validateRequest, ], asyncHandler(async (req, res) => { const qrcode = await accountService.getQRCode(req.body.platform); res.json({ success: true, data: qrcode }); }) ); // 检查扫码状态 router.get( '/qrcode/status', [ query('platform').notEmpty().withMessage('平台不能为空'), query('qrcodeKey').notEmpty().withMessage('二维码Key不能为空'), validateRequest, ], asyncHandler(async (req, res) => { const { platform, qrcodeKey } = req.query; const status = await accountService.checkQRCodeStatus( platform as string, qrcodeKey as string ); res.json({ success: true, data: status }); }) ); // ============ 浏览器登录 ============ // 开始浏览器登录会话 router.post( '/browser-login', [ body('platform').notEmpty().withMessage('平台不能为空'), validateRequest, ], asyncHandler(async (req, res) => { const { platform } = req.body; const result = await browserLoginService.startLoginSession(platform as PlatformType); res.json({ success: true, data: result }); }) ); // 获取浏览器登录状态 router.get( '/browser-login/:sessionId', [ param('sessionId').notEmpty().withMessage('会话ID不能为空'), validateRequest, ], asyncHandler(async (req, res) => { const { sessionId } = req.params; const status = browserLoginService.getSessionStatus(sessionId); if (!status) { res.status(404).json({ success: false, error: { message: '会话不存在或已过期' } }); return; } res.json({ success: true, data: status }); }) ); // 取消浏览器登录会话 router.delete( '/browser-login/:sessionId', [ param('sessionId').notEmpty().withMessage('会话ID不能为空'), validateRequest, ], asyncHandler(async (req, res) => { const { sessionId } = req.params; await browserLoginService.cancelSession(sessionId); res.json({ success: true, message: '会话已取消' }); }) ); // 确认浏览器登录并保存账号 router.post( '/browser-login/:sessionId/confirm', [ param('sessionId').notEmpty().withMessage('会话ID不能为空'), body('platform').notEmpty().withMessage('平台不能为空'), validateRequest, ], asyncHandler(async (req, res) => { const { sessionId } = req.params; const { platform, groupId } = req.body; const status = browserLoginService.getSessionStatus(sessionId); if (!status || status.status !== 'success' || !status.cookies) { res.status(400).json({ success: false, error: { message: '登录未完成或会话已失效' } }); return; } // 使用获取到的 Cookie 和账号信息创建账号 const account = await accountService.addAccount(req.user!.userId, { platform, cookieData: status.cookies, groupId, // 传递从浏览器会话中获取的账号信息 accountInfo: status.accountInfo, }); res.status(201).json({ success: true, data: account }); }) ); // ============ 内嵌浏览器登录 Cookie 验证 ============ // 验证 Cookie 登录状态(用于 Electron 内嵌浏览器) router.post( '/verify-cookie', [ body('platform').notEmpty().withMessage('平台不能为空'), body('cookieData').notEmpty().withMessage('Cookie不能为空'), validateRequest, ], asyncHandler(async (req, res) => { const { platform, cookieData } = req.body; try { // 使用服务验证 cookie 并获取账号信息 const result = await accountService.verifyCookieAndGetInfo( platform as PlatformType, cookieData ); res.json({ success: true, data: { success: result.success, message: result.message, accountInfo: result.accountInfo, } }); } catch (error) { res.json({ success: true, data: { success: false, message: error instanceof Error ? error.message : '验证失败', } }); } }) ); export default router;