"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.creativesRouter = creativesRouter; const express_1 = require("express"); const uuid_1 = require("uuid"); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); function creativesRouter(db, storageDir, onThemeSaved) { const router = (0, express_1.Router)(); // GET /api/v1/creatives — 创意列表 router.get("/", (req, res) => { const { status, page = "1", limit = "20" } = req.query; const offset = (Number(page) - 1) * Number(limit); let sql = ` SELECT c.*, t.name as template_name FROM creatives c JOIN templates t ON c.template_id = t.id `; const params = []; if (status) { sql += " WHERE c.status = ?"; params.push(status); } sql += " ORDER BY c.updated_at DESC LIMIT ? OFFSET ?"; params.push(Number(limit), offset); const rows = db.prepare(sql).all(...params); const data = rows.map((row) => ({ id: row.id, name: row.name, templateId: row.template_id, templateName: row.template_name, status: row.status, createdAt: row.created_at, updatedAt: row.updated_at, })); res.json({ data }); }); // POST /api/v1/creatives — 新建创意 router.post("/", (req, res) => { const { name, templateId } = req.body; if (!name || !templateId) { res.status(400).json({ error: { message: "name and templateId are required" }, }); return; } // 校验模板存在 const template = db .prepare("SELECT id FROM templates WHERE id = ?") .get(templateId); if (!template) { res.status(400).json({ error: { message: `Template '${templateId}' not found` }, }); return; } const id = (0, uuid_1.v4)(); db.prepare("INSERT INTO creatives (id, name, template_id) VALUES (?, ?, ?)").run(id, name, templateId); const creative = db.prepare("SELECT * FROM creatives WHERE id = ?").get(id); res.status(201).json({ data: { id: creative.id, name: creative.name, templateId: creative.template_id, status: creative.status, theme: JSON.parse(creative.theme), createdAt: creative.created_at, updatedAt: creative.updated_at, }, }); }); // GET /api/v1/creatives/:id — 创意详情 router.get("/:id", (req, res) => { const creative = db .prepare(`SELECT c.*, t.name as template_name FROM creatives c JOIN templates t ON c.template_id = t.id WHERE c.id = ?`) .get(req.params.id); if (!creative) { res.status(404).json({ error: { message: "Creative not found" } }); return; } // 获取素材列表 const assets = db .prepare("SELECT * FROM creative_assets WHERE creative_id = ?") .all(creative.id); // 获取最近构建 const recentBuilds = db .prepare("SELECT id, status, platforms, results, error_log, started_at, finished_at, created_at FROM builds WHERE creative_id = ? ORDER BY created_at DESC LIMIT 5") .all(creative.id); res.json({ data: { id: creative.id, name: creative.name, templateId: creative.template_id, template: { id: creative.template_id, name: creative.template_name, }, status: creative.status, theme: JSON.parse(creative.theme), assets: assets.map((a) => ({ key: a.file_key, fileName: a.file_name, fileSize: a.file_size, isRequired: !!a.is_required, })), recentBuilds: recentBuilds.map((b) => ({ id: b.id, status: b.status, platforms: JSON.parse(b.platforms), previewUrl: b.status === "completed" ? `/q/${b.id.replace(/-/g, "").slice(0, 8)}.html` : null, results: b.results ? JSON.parse(b.results) : null, errorLog: b.error_log, startedAt: b.started_at, finishedAt: b.finished_at, createdAt: b.created_at, })), createdAt: creative.created_at, updatedAt: creative.updated_at, }, }); }); // PATCH /api/v1/creatives/:id — 更新创意 router.patch("/:id", (req, res) => { const creative = db .prepare("SELECT * FROM creatives WHERE id = ?") .get(req.params.id); if (!creative) { res.status(404).json({ error: { message: "Creative not found" } }); return; } const { name, theme } = req.body; if (name !== undefined) { db.prepare("UPDATE creatives SET name = ?, updated_at = datetime('now') WHERE id = ?") .run(name, req.params.id); } if (theme !== undefined) { db.prepare("UPDATE creatives SET theme = ?, updated_at = datetime('now') WHERE id = ?") .run(JSON.stringify(theme), req.params.id); // 通知预览服务更新配置 onThemeSaved?.(req.params.id, theme, storageDir); } // 返回更新后的数据 const updated = db .prepare("SELECT * FROM creatives WHERE id = ?") .get(req.params.id); res.json({ data: { id: updated.id, name: updated.name, templateId: updated.template_id, status: updated.status, theme: JSON.parse(updated.theme), updatedAt: updated.updated_at, }, }); }); // DELETE /api/v1/creatives/:id — 删除创意 router.delete("/:id", (req, res) => { const creative = db .prepare("SELECT * FROM creatives WHERE id = ?") .get(req.params.id); if (!creative) { res.status(404).json({ error: { message: "Creative not found" } }); return; } // 删除磁盘文件 const creativeDir = path_1.default.join(storageDir, "creatives", creative.id); if (fs_1.default.existsSync(creativeDir)) { fs_1.default.rmSync(creativeDir, { recursive: true, force: true }); } // 级联删除数据库记录(foreign key ON DELETE CASCADE) db.prepare("DELETE FROM creatives WHERE id = ?").run(req.params.id); res.json({ data: { id: req.params.id, deleted: true } }); }); return router; } //# sourceMappingURL=creatives.js.map