From: wang.yu Date: Mon, 17 Aug 2026 06:23:47 +0000 (+0800) Subject: feat: 站点级样式生成范本增强(逐面板外观/配色板/标题模板修复,注入Cube名称) X-Git-Url: http://acesimba.cloud/gitweb/?a=commitdiff_plain;h=1fe243c7a79fcc20c707f78f6bf309a7f7377ebf;p=StationBuilder.git feat: 站点级样式生成范本增强(逐面板外观/配色板/标题模板修复,注入Cube名称) --- diff --git a/db-sidecar.mjs b/db-sidecar.mjs index ac8fbc5..f2edf90 100644 --- a/db-sidecar.mjs +++ b/db-sidecar.mjs @@ -79,13 +79,13 @@ Top-level structure (MUST include exactly these keys): "category_id": null, "name": "", "id": , - "grid": { "theme": "light", "bgColor": "rgb(237,246,251)", "panelBgColor": "#F5F5F5", "panel": { "bgColor": "#FFFFFF", "titleColor": "#323232" }, "borderColor": "#C8C8C8", "borderWidth": 1, "borderRadius": 4, "gap": 6, "pageType": "custom", "pageWidth": 1920, "pageHeight": 1080, "showBorder": true, "bgType": "color", "bgImgType": "cover", "linearGradientParam1": "default", "linearGradientParam2": "#008cd633", "linearGradientParam3": "#008cd6", "linearGradientParamDeg": 45, "radialGradientParam1": "default", "radialGradientParam2": "#008cd633", "radialGradientParam3": "#008cd6" }, + "grid": { "theme": "light", "bgColor": "rgb(237,246,251)", "panelBgColor": "#F5F5F5", "panel": { "bgColor": "#FFFFFF", "titleColor": "#323232" }, "borderColor": "#C8C8C8", "borderWidth": 1, "borderRadius": 4, "gap": 6, "pageType": "custom", "pageWidth": 1920, "pageHeight": 1080, "showBorder": true, "bgType": "color", "bgImgType": "cover", "linearGradientParam1": "default", "linearGradientParam2": "#5B7C9933", "linearGradientParam3": "#5B7C99", "linearGradientParamDeg": 45, "radialGradientParam1": "default", "radialGradientParam2": "#5B7C9933", "radialGradientParam3": "#5B7C99" }, "panels": [...] } Layout rules: - 24-column grid, page 1920x1080. -- First panel MUST be type "Title" at gridPos {w:24,h:2,x:0,y:0}, custom.title.label = dashboard name, fontSize 40, fontWeight "bold". +- First panel MUST be type "Title" at gridPos {w:24,h:2,x:0,y:0}. Hide the default panel title bar: set style.title.show=false. Use custom.title.label = dashboard name, and make custom.title.style (fontSize, fontWeight, letterSpacing, textShadow, color, align) exactly match the Title panel style provided in the 视觉风格要求 section if present. - All other panels must have y >= 2. - Do NOT place panels that overlap or exceed x+w > 24. - Fill roughly 25 rows total (2 title + KPI rows + chart rows). @@ -118,9 +118,9 @@ KPIIndicator panel specifics: - data.targets[0].dataType = "sum" - custom can include icon, thresholds, compare. -Charts: include proper chartConfig, series, axes, colors from palette #0062CC,#00B900,#FF9300,#EBC147,#D73C74,#8048C8,#6D84C9,#34A0D5. +Charts: include proper chartConfig, series, axes, colors. If a 视觉风格要求 section provides a 推荐配色板, use THAT palette first; otherwise use default #0062CC,#00B900,#FF9300,#EBC147,#D73C74,#8048C8,#6D84C9,#34A0D5. -Theme: use light theme (grid.theme="light", bgColor rgb(237,246,251), panelBgColor #F5F5F5, panel.bgColor #FFFFFF, titleColor #323232, borderColor #C8C8C8). Do not mix darkBlue with light background. +Theme: If a 视觉风格要求 section is provided below, follow IT exactly (its grid colors/borders/gradients take precedence) and ignore the default example colors in the grid above. Otherwise use the default light theme: grid.theme="light", bgColor rgb(237,246,251), panelBgColor #F5F5F5, panel.bgColor #FFFFFF, titleColor #323232, borderColor #C8C8C8. Do not mix darkBlue with light background. Output ONLY the raw JSON object. No markdown code fences, no explanation. `; @@ -431,12 +431,13 @@ function buildCubePrompt(site, cube) { - 页面内容/要求: ${cube.content || "(未填写,请按总览型页面设计)"} 请针对以上页面,生成对应的 Cube 仪表盘 JSON 文件(只输出该页面)。模拟数据需与上方站点资产配置保持一致;若属于同一站点的多个 Cube 页面,请保持各页面之间的数据关系合理。该 JSON 必须符合 dashboard-json-generator Skill 中 Cube 工具的规则,结构如下: -${DASHBOARD_SPEC}${buildStylePrompt(site)}`; +${DASHBOARD_SPEC}${buildStylePrompt(site, cube.name)}`; } // 站点级视觉风格范本:从所选样式库方案中提取可写入 grid 的主题参数(背景大图以占位描述代替,避免上下文膨胀), // 并在 buildCubePrompt 中复用,保证生成 / 重新生成 / 查看提示词 等路径都带同一段范本。 -function buildStylePrompt(site) { +// cubeName 可选:提供时标题直接填好页面名称,避免模型漏填。 +function buildStylePrompt(site, cubeName) { if (!site || !site.style_id) return ""; const row = db.prepare("SELECT id,name,json_text FROM page_styles WHERE id=?").get(site.style_id); if (!row) return ""; @@ -471,13 +472,69 @@ function buildStylePrompt(site) { pageType: g.pageType, }; Object.keys(theme).forEach(k => theme[k] === undefined && delete theme[k]); + + // 逐面板外观令牌:样式的"皮肤"主要来自这里(标题色 / 边框色 / 面板底色 / 组件类型) + const panels = (style.panels || []).map(p => ({ + type: p.type, + titleColor: p.style?.title?.color, + borderColor: p.style?.border?.color, + bg: p.style?.background?.color, + })); + + // 标题面板模板:必须复刻原样式第一个 Title panel。custom.title 已填好(label 为页面名称), + // 请原样写入;同时 style.title.show=false 且 style.title.color 也设为浅色,避免回退到默认灰色标题栏。 + const first = style.panels?.[0]; + const ct = first?.custom?.title; + const titleTemplate = first && first.type === "Title" && ct ? { + "style.title.show": false, + "style.title.color": ct.style?.color, + "custom.title": { + label: (cubeName && String(cubeName).trim()) ? cubeName : "<当前页面名称>", + style: ct.style, + align: ct.align, + }, + } : null; + + // 推荐配色板:扫描样式真实用到的颜色,供图表 / 文字 / 强调复用(替代默认色板) + const palette = extractColorPalette(style); + return ` -视觉风格要求(站点级,适用本站点全部 Cube 页面): -所选页面样式库方案:「${row.name}」。请严格参考以下视觉主题参数生成 dashboard JSON(仅输出符合该风格的外观,结构仍遵循上方 Cube 规范): +【视觉风格要求 · 最高优先级】所选页面样式库方案:「${row.name}」。 +下方所有视觉参数必须原样写入生成 JSON 的 grid 与各 panel 的 style 中,并忽略上方 DASHBOARD_SPEC 里的默认 Theme 示例色(如 #008cd6)。结构仍遵循上方 Cube 规范。 + +1) grid 级主题(背景 / 边框 / 圆角,请原样保留这些字段值;背景渐变由 bgType + bgColor + linearGradientParam(Deg,1,2,3) + radialGradientParam(1,2,3) 共同决定,请勿自行改成纯色): ${JSON.stringify(theme, null, 2)} -说明:bgImg 为原样式的背景底图(已省略其 base64 内容),请保持与该图一致的明暗、色调与渐变质感;其余参数均为可直接写入 grid 的样式值。`; +2) 标题面板模板(第一个 panel,type=Title,必须原样写入以下 custom.title(label 已填好,无需再改),并设 style.title.show=false。标题可见文字颜色以 custom.title.style.color 为准,请勿使用默认灰色标题栏): +${JSON.stringify(titleTemplate, null, 2)} + +3) 逐面板外观参考(生成每种 type 的面板时,尽量采用本列表中同 type 面板的 titleColor / borderColor / bg;组件类型构成以本列表为准): +${JSON.stringify(panels.slice(1), null, 2)} + +4) 推荐配色板(图表 series、文字、强调色优先使用以下颜色,而非默认色板): +${JSON.stringify(palette)} + +说明:bgImg 为原样式的背景底图(已省略其 base64 内容),请保持与该图一致的明暗、色调与渐变质感;其余参数均为可直接写入 grid / panel.style 的样式值。`; +} + +// 从样式 JSON 中扫描真实使用的颜色,提取为推荐配色板(跳过 base64 等大字段)。 +function extractColorPalette(style) { + const colors = new Map(); + const scan = (o) => { + if (typeof o === "string") { + if (o.length > 5000) return; // 跳过 bgImg 等超大字段 + const r = /#([0-9a-fA-F]{3,8})\b|rgba?\([^)]*\)/g; + let m; + while ((m = r.exec(o))) { + const c = m[0].toLowerCase(); + colors.set(c, (colors.get(c) || 0) + 1); + } + } else if (Array.isArray(o)) o.forEach(scan); + else if (o && typeof o === "object") Object.values(o).forEach(scan); + }; + scan(style); + return [...colors.entries()].sort((a, b) => b[1] - a[1]).slice(0, 12).map(e => e[0]); } async function generateCubeJson(site, cube, attempt = 1, previousErrors = "") { const promptBase = buildCubePrompt(site, cube);