MODULE-COVER-001: full package for external AI consumption - server.js + renderer.js + generate.js + config.js - templates/ (5 templates: xiaohongshu + dynamic + jike + poster + registry) - package.json + README.md + MODULE.hdlp - INDEX.hdlp + SYSTEM.hdlp (HLDP declarations) - Fonts: Noto Sans CJK SC priority (no tofu blocks) - No domain watermark - Updated module-registry.json - Copyright 2026-A-00037559
66 lines
2.0 KiB
JavaScript
66 lines
2.0 KiB
JavaScript
/**
|
|
* 铸渊封面工作室 · Web 服务 · v2.1
|
|
* 公开页面 + 模板列表 API + 生成 API + 意图链 + 下载端点
|
|
*/
|
|
|
|
import express from 'express'
|
|
import cors from 'cors'
|
|
import { generate, listTemplates } from './generate.js'
|
|
import { join, dirname } from 'path'
|
|
import { fileURLToPath } from 'url'
|
|
import { existsSync, mkdirSync } from 'fs'
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
const OUTPUT_DIR = join(__dirname, 'output')
|
|
const PUBLIC_DIR = join(__dirname, 'public')
|
|
const PORT = process.env.PORT || 3912
|
|
|
|
if (!existsSync(OUTPUT_DIR)) mkdirSync(OUTPUT_DIR, { recursive: true })
|
|
|
|
const app = express()
|
|
app.use(cors())
|
|
app.use(express.json({ limit: '1mb' }))
|
|
app.use('/output', express.static(OUTPUT_DIR))
|
|
app.use(express.static(PUBLIC_DIR))
|
|
|
|
app.get('/api/templates', (req, res) => {
|
|
try { res.json(listTemplates()) }
|
|
catch (err) { res.status(500).json({ error: '无法加载模板列表' }) }
|
|
})
|
|
|
|
app.post('/api/generate', async (req, res) => {
|
|
try {
|
|
const { templateId, presetId = '', title = '', body = '', subtitle = '', tag = '', layout = 'default' } = req.body
|
|
if (!title && !body) return res.status(400).json({ error: '请至少提供标题或正文内容' })
|
|
|
|
const result = await generate({ templateId, presetId, title, body, subtitle, tag, layout })
|
|
const filename = result.files[0].split('/').pop()
|
|
const url = `/output/${filename}`
|
|
|
|
res.json({
|
|
success: true,
|
|
url, filename,
|
|
templateId: result.templateId,
|
|
templateName: result.templateName,
|
|
presetId: result.presetId,
|
|
layout: result.layout,
|
|
intent_chain: result.intent_chain,
|
|
})
|
|
} catch (err) {
|
|
console.error('生成失败:', err.message)
|
|
res.status(500).json({ error: err.message || '生成失败' })
|
|
}
|
|
})
|
|
|
|
app.get('/api/health', (req, res) => {
|
|
res.json({ status: 'ok', timestamp: new Date().toISOString() })
|
|
})
|
|
|
|
app.get('*', (req, res) => {
|
|
res.sendFile(join(PUBLIC_DIR, 'index.html'))
|
|
})
|
|
|
|
app.listen(PORT, () => {
|
|
console.log(`🎨 铸渊封面工作室 v2.1 运行在 http://localhost:${PORT}`)
|
|
})
|