Files
cms-SiteForge/app/templates/editor.html
T
浅念 5c7643fcf2 upgrade: adopt V8.12.0-dev.1 (V8.11 unified professional UI + V8.12 workflow usability)
- Overlay 26 changed files from SiteForge_Enterprise_V8_12 (UI layer only:
  professional-ui.js/css, workspace/factory-v2/operations/editor templates,
  +2 test files, compose/ci/scripts/docs)
- Re-apply v8_workflows type-mapping fix (类型/分类) lost in upgrade
- Pin compose project name to siteforge-v8-10 so existing data volumes
  (hesupipe site 483295c29ea0, 193 entries) keep attached
- Drop stray .s10_* state files; ignore .s10_*/.sf_*/.s87_* patterns
- Plan/spec revisions per plan-review round 1 (icons are new design,
  real test assertions, recorded deviations)

Tests: 226 passed / 1 env-only failure (test needs node binary in PATH,
absent in python:3.12-slim container; host node v24 --check all 9 JS OK)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-22 17:02:45 +08:00

72 lines
9.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>SiteForge Studio · 可视化建站</title><link rel="stylesheet" href="/ui/editor.css"><script defer src="/ui/editor.js"></script><link rel="stylesheet" href="/ui/professional-ui.css"><script defer src="/ui/professional-ui.js"></script></head>
<body data-sf-page="editor">
<div class="studio">
<header class="studio-top">
<div class="brand"><a href="/" title="返回网站管理">◈</a><div><b>SiteForge</b><small>VISUAL STUDIO</small></div></div>
<span class="divide"></span><div class="file-name"><span id="siteName">加载中</span><small> / </small><strong id="pageName">页面编辑器</strong></div>
<div class="top-center"><button id="deviceDesktop" class="icon-btn on" onclick="Studio.device('desktop')" title="PC预览">▣</button><button id="deviceTablet" class="icon-btn" onclick="Studio.device('tablet')" title="平板预览">▤</button><button id="devicePhone" class="icon-btn" onclick="Studio.device('phone')" title="手机预览">▯</button></div>
<button class="ui-btn ghost" onclick="Studio.undo()" title="撤销 Ctrl+Z">↶ 撤销</button><button class="ui-btn ghost" onclick="Studio.redo()" title="重做 Ctrl+Y">↷ 重做</button><button class="ui-btn ghost" onclick="Studio.showTokens()">设计规范</button><button class="ui-btn ghost" onclick="Studio.showSiteDesign()">全站页眉与页脚</button><span id="saveStatus" class="save-status">未修改</span><button class="ui-btn ghost" onclick="Studio.refreshPreview()">↻ 刷新预览</button><button class="ui-btn ghost" onclick="Studio.buildSite()">构建静态站</button><button class="ui-btn ghost" onclick="Studio.discardDraft()">放弃草稿</button><button class="ui-btn ghost" onclick="Studio.save()">保存草稿</button><button class="ui-btn primary" onclick="Studio.publishDesign()">发布设计 ↗</button>
</header>
<div class="studio-body">
<aside class="left-pane"><div class="pane-heading"><div><span class="overline">STRUCTURE</span><h3>页面结构</h3></div><span class="chip" id="blockCount">0 区块</span></div>
<div class="field"><label>页面</label><select id="pageSelect" onchange="Studio.choosePage(this.value)"></select></div>
<div class="field"><label>页面模板</label><select id="pageTemplate" onchange="Studio.changeTemplateKind(this.value)"></select></div>
<div style="padding:0 19px 7px"><button class="ui-btn ghost" style="width:100%" onclick="Studio.resetPreset()">◈ 应用此页面模板的预设区块</button></div>
<div class="field"><label>页面布局模式</label><select id="layoutMode" onchange="Studio.setLayoutMode(this.value)"><option value="append">保留主题原页面 + 追加区块</option><option value="replace">全页自由排版(保留导航与页脚)</option></select></div><div class="section-label">内容区块 · 拖拽可调整排序</div><div id="blockList" class="block-list"></div>
<div class="section-label">添加功能区块</div><div class="palette" id="palette"></div><div class="section-label">可复用组件库</div><button class="ui-btn ghost" style="margin:10px" onclick="Studio.saveReusable()">将当前区块存为组件</button><div class="palette" id="reusablePalette"></div>
<div class="sidebar-foot">页面由区块驱动,所见预览使用服务端与正式构建相同的数据绑定引擎。</div>
</aside>
<section class="preview-workspace"><div class="preview-head"><span class="live-dot"></span><span>实时预览</span><code id="routeDisplay">/</code><span class="preview-note">正在展示正式主题中的完整页面,草稿不会影响正式构建,发布设计后才会参与下次构建</span></div><div class="stage"><div class="device-frame" id="deviceFrame"><iframe id="sitePreview" title="页面预览" sandbox="allow-scripts" referrerpolicy="no-referrer"></iframe></div></div></section>
<aside class="right-pane"><div class="pane-heading"><div><span class="overline">PROPERTIES</span><h3>属性设置</h3></div><span class="chip" id="blockTypeLabel">页面</span></div>
<div class="inspector" id="inspector"><div class="no-selection">在左侧选择一个区块,在这里编辑它的文字、图片、布局及数据来源。</div></div>
<div class="right-foot"><div>动态数据绑定</div><p>支持 <code>{{site.name}}</code>、<code>{{page.title}}</code> 等变量;“动态内容列表”按类型自动查询当前网站的数据。</p></div>
</aside>
</div>
<dialog id="designModal" style="border:1px solid #e2e8f0;border-radius:14px;padding:24px;width:min(460px,90vw);box-shadow:0 16px 52px #142a492f"><h2>全站设计规范</h2><p>调整后保存并刷新预览,发布构建自动采用该规范。</p><form id="designForm" method="dialog" style="display:grid;gap:12px"><label>标题缩放 <input name="heading_scale" type="number" min="0.8" max="1.5" step="0.1"></label><label>圆角 <input name="radius" type="number" min="0" max="32"></label><label>版心宽度 <input name="container_width" type="number" min="880" max="1600"></label><label>板块间距 <input name="section_spacing" type="number" min="20" max="140"></label><label>字体 <select name="font"><option value="system">系统字体</option><option value="serif">衬线字体</option><option value="modern">现代字体</option></select></label><label>按钮风格 <select name="button_style"><option value="rounded">圆角</option><option value="square">直角</option><option value="pill">胶囊</option></select></label><label>导航风格 <select name="header_style"><option value="standard">标准</option><option value="compact">紧凑</option></select></label><div style="display:flex;gap:12px"><button class="ui-btn primary" type="button" onclick="Studio.saveTokens()">保存全站规范</button><button class="ui-btn ghost" value="cancel">取消</button></div></form></dialog>
<dialog id="siteDesignModal" style="border:1px solid #e2e8f0;border-radius:14px;padding:22px;width:min(750px,96vw);max-height:88vh;overflow:auto;box-shadow:0 18px 56px #142a492f">
<h2>全站设计 · 页眉、导航、页脚与响应式</h2>
<p style="color:#64748b">先保存独立草稿;预览只显示在编辑器内。发布后,所有页面的下次静态构建才会使用新设计。</p>
<div id="siteDesignStatus" role="status" style="font-weight:600;margin-bottom:12px">读取中...</div>
<form id="siteDesignForm" method="dialog" style="display:grid;gap:12px">
<fieldset style="display:grid;gap:9px;border:1px solid #e2e8f0;border-radius:8px"><legend>页眉与导航</legend>
<label><input type="checkbox" name="show_announcement"> 显示顶部提示栏</label>
<label>提示栏文字 <input name="announcement" maxlength="140" style="width:100%"></label>
<label><input type="checkbox" name="show_search"> 显示站内搜索</label>
<label><input type="checkbox" name="show_cta"> 显示联系按钮</label>
<label>按钮文字 <input name="cta_text" maxlength="40"></label>
<label>按钮路径 <input name="cta_href" placeholder="/contact/"></label>
<label>导航结构(JSON,每项含 title、route、可选 children)
<textarea name="nav" rows="6" style="display:block;width:100%;font-family:monospace" spellcheck="false"></textarea>
</label>
</fieldset>
<fieldset style="display:grid;gap:9px;border:1px solid #e2e8f0;border-radius:8px"><legend>全站页脚</legend>
<label>企业名称或页脚标题 <input name="footer_title" maxlength="120" style="width:100%"></label>
<label>页脚简介 <textarea name="footer_description" rows="2" maxlength="650" style="display:block;width:100%"></textarea></label>
<label>联系邮箱 <input name="footer_email" type="email" maxlength="150"></label>
<label><input name="footer_show_nav" type="checkbox"> 页脚显示导航链接</label>
</fieldset>
<fieldset style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:9px;border:1px solid #e2e8f0;border-radius:8px"><legend>不同设备布局</legend>
<label>平板板块间距 <input name="tablet_gap" type="number" min="20" max="120"></label>
<label>手机板块间距 <input name="mobile_gap" type="number" min="16" max="100"></label>
<label>手机内容边距 <input name="mobile_container_padding" type="number" min="8" max="48"></label>
<label><input name="mobile_hide_announcement" type="checkbox"> 手机隐藏提示栏</label>
<label><input name="mobile_hide_footer_links" type="checkbox"> 手机隐藏页脚导航</label>
</fieldset>
<div style="display:flex;flex-wrap:wrap;gap:8px">
<button class="ui-btn ghost" type="button" onclick="Studio.previewSiteDesign()">预览草稿</button>
<button class="ui-btn ghost" type="button" onclick="Studio.discardSiteDesign()">放弃全站草稿</button>
<button class="ui-btn ghost" type="button" onclick="Studio.saveSiteDesign()">保存全站草稿</button>
<button class="ui-btn primary" type="button" onclick="Studio.publishSiteDesign()">发布全站设计</button>
<button class="ui-btn ghost" value="cancel">关闭</button>
</div>
</form>
</dialog>
<dialog id="siteMediaModal" style="border:1px solid #dce5f1;border-radius:14px;padding:24px;width:min(720px,94vw);max-height:85vh;overflow:auto">
<h2>本站图片素材库</h2><p style="font-size:13px;color:#66758a">选择图片后更新当前组件;保存草稿、发布设计后才会参与静态构建。</p>
<div id="siteMediaGrid" style="display:grid;grid-template-columns:repeat(auto-fill,minmax(135px,1fr));gap:12px"></div>
<button type="button" class="ui-btn ghost" onclick="document.querySelector('#siteMediaModal').close()" style="margin-top:15px">关闭</button>
</dialog>
<div id="toast" class="toast"></div>
</div></body></html>