From c27bd54bb3f6d34d3aa65384a6ef278b79aa2df7 Mon Sep 17 00:00:00 2001 From: sion123 <450702724@qq.com> Date: Thu, 7 May 2026 02:27:09 +0800 Subject: [PATCH] feat(web): add account CRUD API routes Co-Authored-By: Claude Opus 4.7 --- web/server/routes/accounts.ts | 85 +++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 web/server/routes/accounts.ts diff --git a/web/server/routes/accounts.ts b/web/server/routes/accounts.ts new file mode 100644 index 0000000..2434629 --- /dev/null +++ b/web/server/routes/accounts.ts @@ -0,0 +1,85 @@ +import { Router } from 'express'; +import fs from 'fs'; +import path from 'path'; + +const ACCOUNTS_DIR = path.resolve(__dirname, '..', '..', '..', 'accounts'); + +export const accountsRouter = Router(); + +function readAccountJson(id: string): Record | null { + const p = path.join(ACCOUNTS_DIR, id, 'account.json'); + if (!fs.existsSync(p)) return null; + return JSON.parse(fs.readFileSync(p, 'utf-8')); +} + +function writeAccountJson(id: string, data: Record): void { + const dir = path.join(ACCOUNTS_DIR, id); + if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true }); + fs.writeFileSync(path.join(dir, 'account.json'), JSON.stringify(data, null, 2), 'utf-8'); +} + +// List +accountsRouter.get('/', (_req, res) => { + const dirs = fs.readdirSync(ACCOUNTS_DIR, { withFileTypes: true }) + .filter((d) => d.isDirectory() && !d.name.startsWith('_') && !d.name.startsWith('.')) + .map((d) => d.name); + + const accounts = dirs + .map((id) => readAccountJson(id)) + .filter(Boolean); + res.json(accounts); +}); + +// Get +accountsRouter.get('/:id', (req, res) => { + const data = readAccountJson(req.params.id); + if (!data) return res.status(404).json({ error: 'Account not found' }); + res.json(data); +}); + +// Create +accountsRouter.post('/', (req, res) => { + const { id, ...rest } = req.body; + if (!id) return res.status(400).json({ error: 'id is required' }); + + const dir = path.join(ACCOUNTS_DIR, id); + if (fs.existsSync(dir)) return res.status(409).json({ error: 'Account already exists' }); + + const data = { + id, + name: rest.name || id, + description: rest.description || '', + defaultFormat: rest.defaultFormat || '9:16', + imageModel: rest.imageModel || 'gemini', + videoModel: rest.videoModel || 'veo3-fast', + batchSize: rest.batchSize || 30, + ttsVoice: rest.ttsVoice || '', + ttsInstruction: rest.ttsInstruction || '', + storyboardPrompt: rest.storyboardPrompt || 'prompts/分镜.md', + imageStylePrompt: rest.imageStylePrompt || 'prompts/图片提示词.md', + videoStylePrompt: rest.videoStylePrompt || 'prompts/视频提示词.md', + references: rest.references || [], + capcut: rest.capcut || {}, + }; + + writeAccountJson(id, data); + res.status(201).json(data); +}); + +// Update +accountsRouter.put('/:id', (req, res) => { + const existing = readAccountJson(req.params.id); + if (!existing) return res.status(404).json({ error: 'Account not found' }); + + const merged = { ...existing, ...req.body, id: req.params.id }; + writeAccountJson(req.params.id, merged); + res.json(merged); +}); + +// Delete +accountsRouter.delete('/:id', (req, res) => { + const dir = path.join(ACCOUNTS_DIR, req.params.id); + if (!fs.existsSync(dir)) return res.status(404).json({ error: 'Account not found' }); + fs.rmSync(dir, { recursive: true }); + res.status(204).send(); +});