"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildsRouter = buildsRouter; const express_1 = require("express"); const uuid_1 = require("uuid"); const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); const buildService_1 = require("../services/buildService"); function buildsRouter(db, storageDir, onThemeSaved) { const router = (0, express_1.Router)(); const buildService = new buildService_1.BuildService(db, storageDir); // POST /api/v1/creatives/:id/builds — 触发构建 router.post("/creatives/:id/builds", async (req, res) => { try { const { id } = req.params; const { platforms, theme } = req.body; if (!platforms || !Array.isArray(platforms) || platforms.length === 0) { res.status(400).json({ error: { message: "platforms must be a non-empty array" }, }); return; } const creative = db .prepare("SELECT * FROM creatives WHERE id = ?") .get(id); if (!creative) { res.status(404).json({ error: { message: "Creative not found" } }); return; } if (creative.status === "draft") { res.status(400).json({ error: { message: "Please upload assets before building" }, }); return; } // 保存 theme if (theme) { db.prepare("UPDATE creatives SET theme = ?, updated_at = datetime('now') WHERE id = ?").run(JSON.stringify(theme), id); onThemeSaved?.(id, theme, storageDir); } const buildId = (0, uuid_1.v4)(); const themeSnapshot = theme || JSON.parse(creative.theme || "{}"); db.prepare(`INSERT INTO builds (id, creative_id, platforms, theme_snapshot, status) VALUES (?, ?, ?, ?, 'pending')`).run(buildId, id, JSON.stringify(platforms), JSON.stringify(themeSnapshot)); // 更新创意状态 db.prepare("UPDATE creatives SET status = 'building', updated_at = datetime('now') WHERE id = ?").run(id); // 异步构建(不阻塞响应) buildService.enqueue(buildId, id, platforms, themeSnapshot); res.status(201).json({ data: { id: buildId, status: "pending", platforms }, }); } catch (err) { res.status(500).json({ error: { message: err.message } }); } }); // GET /api/v1/creatives/:id/builds — 构建历史 router.get("/creatives/:id/builds", (req, res) => { const builds = db .prepare("SELECT * FROM builds WHERE creative_id = ? ORDER BY created_at DESC LIMIT 20") .all(req.params.id); res.json({ data: builds.map((b) => ({ id: b.id, creativeId: b.creative_id, status: b.status, platforms: JSON.parse(b.platforms), results: b.results ? JSON.parse(b.results) : null, errorLog: b.error_log, startedAt: b.started_at, finishedAt: b.finished_at, createdAt: b.created_at, })), }); }); // GET /api/v1/builds/:id/status — 构建状态轮询 router.get("/builds/:id/status", (req, res) => { const build = db .prepare("SELECT * FROM builds WHERE id = ?") .get(req.params.id); if (!build) { res.status(404).json({ error: { message: "Build not found" } }); return; } res.json({ data: { id: build.id, status: build.status, results: build.results ? JSON.parse(build.results) : null, errorLog: build.error_log, startedAt: build.started_at, finishedAt: build.finished_at, createdAt: build.created_at, }, }); }); // GET /api/v1/builds/:id/download/all — 下载全部产物 ZIP(必须在 :platform 之前注册) router.get("/builds/:id/download/all", (req, res) => { const build = db .prepare("SELECT * FROM builds WHERE id = ?") .get(req.params.id); if (!build || build.status !== "completed") { res.status(404).json({ error: { message: "Build not found or not completed" } }); return; } const zipPath = path_1.default.join(storageDir, "creatives", build.creative_id, "builds", build.id, "all.zip"); if (!fs_1.default.existsSync(zipPath)) { res.status(404).json({ error: { message: "ZIP file not found" } }); return; } res.download(zipPath, `playable-ad-${build.id.slice(0, 8)}.zip`); }); // GET /api/v1/builds/:id/download/:platform — 下载单个平台产物 router.get("/builds/:id/download/:platform", (req, res) => { const build = db .prepare("SELECT * FROM builds WHERE id = ?") .get(req.params.id); if (!build || build.status !== "completed") { res.status(404).json({ error: { message: "Build not found or not completed" } }); return; } const results = JSON.parse(build.results || "[]"); const result = results.find((r) => r.platform === req.params.platform); if (!result) { res.status(404).json({ error: { message: "Platform not found in build results" } }); return; } const filePath = path_1.default.join(storageDir, "creatives", build.creative_id, "builds", build.id, req.params.platform, "index.html"); if (!fs_1.default.existsSync(filePath)) { res.status(404).json({ error: { message: "File not found on disk" } }); return; } res.download(filePath, "index.html"); }); return router; } //# sourceMappingURL=builds.js.map