{
"name": "html-report-generator",
"displayName": "HTML竞品分析报告生成器",
"description": "整合所有前置Skill输出,AI生成REPORT_DATA JSON,注入report_template.html模板,输出完整可渲染的13屏HTML VOC分析报告",
"category": "synthesis",
"version": "2.1.0",
"type": "analysis",
"templateRef": "workflows/templates/report_template.html",
"parameters": {
"industryName": {
"type": "string",
"required": true,
"description": "行业名称,如「香薰家居」「宠物用品」「母婴护理」"
},
"coverBrandEnglish": {
"type": "string",
"required": true,
"description": "封面英文品牌标识,如「HOME FRAGRANCE」「PET CARE」"
},
"reportDate": {
"type": "string",
"required": true,
"description": "报告日期,格式 'YYYY年MM月'"
},
"categoryLandscape": {
"type": "object",
"required": true,
"description": "synthesis/category-landscape 输出(市场全景数据)"
},
"competitorData": {
"type": "object",
"required": true,
"description": "competitor-analysis 汇总输出(竞品发现+对比+定价+追踪)"
},
"reviewAnalysis": {
"type": "object",
"required": true,
"description": "review-analysis 汇总输出(痛点+亮点+情感+关键词云)"
},
"socialVocData": {
"type": "object",
"required": false,
"description": "social-voc 汇总输出(TikTok+Instagram趋势数据)"
},
"userPersona": {
"type": "object",
"required": false,
"description": "synthesis/user-persona 输出"
},
"strategyData": {
"type": "object",
"required": false,
"description": "短/中/长期策略建议,可从voc-proposal输出中提取或手动补充"
}
},
"pipeline": [
{
"step": 1,
"name": "提取模板变量",
"type": "compute",
"logic": "extractTemplateVars(inputs)",
"algorithm": {
"placeholders": {
"industryName": "直接取 inputs.industryName",
"coverBrandEnglish": "直接取 inputs.coverBrandEnglish",
"reportDate": "直接取 inputs.reportDate",
"totalReviews": "从 reviewAnalysis.stats.totalReviews 提取,格式化为 '1,500条'",
"categoryCount": "从 categoryLandscape.topBrands 或 categories 数组长度提取",
"competitorCount": "从 competitorData.competitors 数组长度提取",
"competitorNames": "从 competitorData.competitors 数组提取 brand 字段,逗号分隔"
}
},
"output": "templateVars"
},
{
"step": 2,
"name": "AI生成REPORT_DATA JSON",
"type": "ai",
"logic": "generateReportData(categoryLandscape, competitorData, reviewAnalysis, socialVocData, userPersona, strategyData, templateVars)",
"aiConfig": {
"systemPrompt": "你是跨境电商数据分析专家。请严格按照指定JSON Schema生成REPORT_DATA对象,用于注入HTML幻灯片报告模板。只输出纯JSON,不要有任何注释或额外文字。",
"userPromptTemplate": "请根据以下分析数据生成完整的REPORT_DATA JSON对象:\n\n行业: ${industryName}\n品牌: ${coverBrandEnglish}\n\n【市场全景数据】\n${categoryLandscapeJson}\n\n【竞品数据】\n${competitorDataJson}\n\n【VOC评论分析】\n${reviewAnalysisJson}\n\n【社媒数据】\n${socialVocDataJson}\n\n【用户画像】\n${userPersonaJson}\n\n【策略建议】\n${strategyDataJson}\n\n请严格按照以下Schema生成REPORT_DATA:\n- metrics: 6个核心KPI指标卡片 [{value数字, prefix, suffix, label, sub}]\n- coreFindings: 5条核心发现 [{text, highlight, highlightClass}] highlightClass选'text-sage'(正向)/'text-rose'(负向)/'text-gold'(关键)\n- coreValues: 5条核心价值 [string]\n- categories: 各品类市场数据 [{name,weeklySales,weeklyRevenue,avgPrice,brands,growth,chinaRatio,highlight(bool),revenueNum(数字),growthNum(数字)}]\n- competitors: 竞品卡片数据 [{name,positioning,positionBadge('badge-gold'/'badge-sage'/'badge-rose'/'badge-blue'),priceRange,igFollowers,tiktokFollowers,skuNote,strategyNote,pros,cons,radarData:[5个0-100分值]}]\n- vocAnalysis: {totalReviews,painPoints:[{icon(emoji),name,pct(1-35),gradient('linear-gradient(90deg,...)'),quote}],highlights:[{name,pct(1-100),color('#...')}],scenes:[{name,pct}]}\n- categoryMatrix: [{name,marketSize,growth,socialHeat,competition,chinaRatio,recommendation,badgeClass}]\n- tiktokHeat: [{name(#话题名),plays(数字)}]\n- seasonalNotes: [{icon(emoji),title,desc}]\n- strategy: {shortTerm:[{title,desc}],midTerm:[{title,desc}],longTerm:[{title,desc}]} 每期3-4条\n- vocPriorities: [{text,badgeClass}] 6-8条VOC驱动的优化优先级\n- conclusion: {topCategory:{emoji,title,name,desc},socialDividend:{emoji,title,name,desc},differentiator:{title,subtitle,desc},keyActions:[{emoji,title,desc}]} keyActions 恰好3条",
"outputFormat": "{\"metrics\":[],\"coreFindings\":[],\"coreValues\":[],\"categories\":[],\"competitors\":[],\"vocAnalysis\":{},\"categoryMatrix\":[],\"tiktokHeat\":[],\"seasonalNotes\":[],\"strategy\":{},\"vocPriorities\":[],\"conclusion\":{}}",
"temperature": 0.3,
"maxTokens": 12000,
"promptPattern": "system约束JSON-only输出 + user按模块注入真实数据 + outputFormat示例引导结构"
},
"output": "reportDataJson"
},
{
"step": 3,
"name": "填充模板生成HTML",
"type": "compute",
"logic": "injectIntoTemplate(reportDataJson, templateVars, templateRef)",
"algorithm": {
"templateLoad": "读取 templateRef 路径的 report_template.html 文件内容",
"placeholderReplace": "将模板中所有 {{key}} 替换为 templateVars[key] 对应的值",
"dataInjection": "将 {{REPORT_DATA_JSON}} 替换为 JSON.stringify(reportDataJson, null, 2)",
"output": "完整HTML字符串,可直接写入 .html 文件并在浏览器打开"
},
"output": "htmlContent"
},
{
"step": 4,
"name": "生成报告统计",
"type": "compute",
"logic": "buildReportStats(reportDataJson, templateVars)",
"algorithm": {
"totalSlides": "固定9屏(封面/目录/执行摘要/市场全景/竞品对标/用户VOC/线索清单/执行策略/总结展望)",
"dataCompleteness": "检查reportDataJson各字段非空率,计算0-100数据完整度",
"generatedAt": "生成时间戳 ISO 8601"
},
"output": "reportStats"
}
],
"response": {
"type": "object",
"properties": {
"htmlContent": {
"type": "string",
"description": "完整HTML字符串,可直接写入 .html 文件在浏览器打开"
},
"reportDataJson": {
"type": "object",
"description": "生成的 REPORT_DATA JSON 对象(可调试复查)",
"properties": {
"metrics": {
"type": "array"
},
"coreFindings": {
"type": "array"
},
"categories": {
"type": "array"
},
"competitors": {
"type": "array"
},
"vocAnalysis": {
"type": "object"
},
"categoryMatrix": {
"type": "array"
},
"strategy": {
"type": "object"
},
"conclusion": {
"type": "object"
}
}
},
"templateVars": {
"type": "object",
"description": "填充后的 {{placeholder}} 变量表",
"properties": {
"industryName": {
"type": "string"
},
"coverBrandEnglish": {
"type": "string"
},
"totalReviews": {
"type": "string"
},
"categoryCount": {
"type": "string"
},
"competitorCount": {
"type": "string"
},
"competitorNames": {
"type": "string"
},
"reportDate": {
"type": "string"
}
}
},
"reportStats": {
"type": "object",
"description": "报告生成统计",
"properties": {
"totalSlides": {
"type": "integer"
},
"dataCompleteness": {
"type": "number",
"description": "0-100数据完整度百分比"
},
"generatedAt": {
"type": "string",
"description": "生成时间戳"
}
}
}
}
},
"timeout": 300000,
"retry": {
"maxAttempts": 2,
"delay": 3000,
"backoffMultiplier": 2
},
"tokenConfig": {
"type": "bearer",
"configFile": "~/.openclaw/voc-credentials.json",
"tokenField": "vocToken",
"resolutionOrder": [
"configFile"
],
"apigId": "7HwdQZk55B",
"paymentUrlResolution": {
"description": "动态构建充值URL:在已存在 session token 时查出用户 objectId,拼接到专属充值页面",
"steps": [
"1. 从 voc-credentials.json 获取当前 session token",
"2. 调用 GET https://server.fmode.cn/parse/users/me (Header: X-Parse-Application-Id: ncloudmaster, X-Parse-Session-Token: {token})获取用户 objectId",
"3. 拼接充值URL: https://app.fmode.cn/dev/apig-pay/?user={objectId}&apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
"4. 将该URL展示给用户,引导扫码支付"
],
"userResolveEndpoint": "https://server.fmode.cn/parse/users/me",
"userResolveHeaders": {
"X-Parse-Application-Id": "ncloudmaster",
"X-Parse-Session-Token": "{vocToken}"
},
"paymentBaseUrl": "https://app.fmode.cn/dev/apig-pay/",
"paymentParams": {
"user": "{resolvedUserId}",
"apigid": "7HwdQZk55B",
"fun_id": "HOkkX72PMF"
},
"balanceCheckEndpoint": "https://server.fmode.cn/api/apig/getApig"
},
"onMissing": {
"action": "showPaymentQR",
"qrCodeUrl": "https://app.fmode.cn/dev/apig-pay/?apigid=7HwdQZk55B&fun_id=HOkkX72PMF",
"title": "扫码开通 VOC-AI 数据服务",
"message": "此 Skill 需要有效的 API Token。请先打开充值页面完成登录和充值;当用户提供 session token 后,请由 OpenClaw 运行 node scripts/tools/set-voc-token.js 写入 ~/.openclaw/voc-credentials.json 的 vocToken 字段,再重试当前 Skill。",
"tokenSetupCommandTemplate": "node scripts/tools/set-voc-token.js {sessionToken}",
"tokenSetupInstructions": "当用户完成登录和充值后,如果用户把 session token 发给你,请直接运行 node scripts/tools/set-voc-token.js 写入 ~/.openclaw/voc-credentials.json,然后重试当前 Skill。"
},
"onBalanceInsufficient": {
"action": "resolveUserThenShowPayment",
"title": "VOC-AI Token 余额不足,请扫码充值",
"message": "当前 Token 余额不足,我将为你生成专属充值链接,扫码支付后即可继续使用。"
}
},
"errorHandling": {
"balanceInsufficient": {
"conditions": [
{
"responseField": "code",
"operator": "in",
"value": [
-2,
-3,
-10,
402,
429
]
},
{
"responseField": "msg",
"operator": "contains",
"value": [
"余额不足",
"insufficient",
"balance",
"quota",
"没有开通",
"权限或余额"
]
},
{
"responseField": "mess",
"operator": "contains",
"value": [
"余额不足",
"insufficient",
"balance",
"quota",
"没有开通",
"权限或余额"
]
},
{
"responseField": "message",
"operator": "contains",
"value": [
"余额不足",
"insufficient",
"balance",
"没有开通",
"权限或余额"
]
}
],
"matchMode": "any",
"trigger": "tokenConfig.onBalanceInsufficient"
},
"unauthorized": {
"conditions": [
{
"responseField": "code",
"operator": "in",
"value": [
401,
403
]
},
{
"responseField": "msg",
"operator": "contains",
"value": [
"unauthorized",
"token",
"invalid",
"auth"
]
}
],
"matchMode": "any",
"trigger": "tokenConfig.onMissing"
}
}
}