Files
cms-SiteForge/integrations/art-design-pro/src/views/siteforge/VisualEditor.vue
T
浅念 601451f22b upgrade: adopt V8.21.3 (V8.13→8.21.3: P5 SFTP/S3, P6 multilingual, editor overhaul, enterprise hardening)
Overlay ~150 upstream items onto our V8.12 base, preserving trade-pro
theme, registry tests, and design docs. Re-applied our patch set
(discovery/env_for/blocks.css/type-mapping/theme_color/frontend entries,
test_theme_pro_v3 mods) — all anchors survived upstream evolution.

New platform enhancement (fixes upgrade-introduced regression):
multilingual.site_locale now honors settings_json.locale, plus
PUT /api/i18n/sites/{id}/locale — standalone English sites get
<html lang='en'> under the V8.15 locale-rewrite pipeline.

compose: adopt V8.21.3 (image 8.21.3-dev.1, /api/ready probes, MySQL/S3
env) with project name pinned to siteforge-v8-10 (data volumes).

Tests: 356 passed / 11 failed — all 11 confirmed pre-existing in
pristine V8.21.3 on this host (10 upstream Windows env + our build test
now green after locale fix). Patch registry updated in plan doc.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-23 12:31:03 +08:00

36 lines
2.7 KiB
Vue
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.
<template>
<section class="siteforge-editor">
<el-card shadow="never">
<div class="toolbar">
<div><h2>可视化网站编辑器</h2><p>在统一管理后台内编辑,支持多列布局、图片替换、撤销/重做、设备预览和全局设计规范。</p></div>
<div class="actions"><el-select v-model="siteId" placeholder="选择网站" filterable @change="refreshPages" style="width:210px"><el-option v-for="s in sites" :key="s.id" :label="s.name" :value="s.id" /></el-select>
<el-select v-model="entryId" placeholder="选择页面" filterable style="width:220px"><el-option v-for="p in pages" :key="p.id" :label="p.title+' · '+p.route" :value="p.id" /></el-select>
<el-button type="primary" :disabled="!entryId" @click="loadEditor">打开页面</el-button></div>
</div>
</el-card>
<div class="editor-viewport" v-if="url"><iframe :key="url" :src="url" title="SiteForge Visual Studio" /></div>
<el-empty v-else description="选择网站和页面,打开可视化编辑器" />
</section>
</template>
<script setup lang="ts">
import {watch,ref,onMounted} from 'vue'
import {ElMessage} from 'element-plus'
import {preferredSite,rememberSite,sfApi} from './_shared'
interface Site{id:string;name:string}
interface Page{id:string;title:string;route:string}
const sites=ref<Site[]>([]),pages=ref<Page[]>([]),siteId=ref(''),entryId=ref(''),url=ref('')
async function get<T>(path:string):Promise<T>{return sfApi<T>(path)}
async function refreshPages(){url.value='';pages.value=[];entryId.value='';if(!siteId.value)return;try{pages.value=await get(`/api/sites/${siteId.value}/entries`);entryId.value=pages.value.find(p=>p.route==='/')?.id||pages.value[0]?.id||''}catch(e:any){ElMessage.error(e.message)}}
function loadEditor(){if(entryId.value)url.value=`/editor/${siteId.value}/${entryId.value}`}
watch(siteId,(id)=>rememberSite(id))
onMounted(async()=>{try{sites.value=await get('/api/sites');if(sites.value.length){siteId.value=preferredSite(sites.value);await refreshPages()}}catch(e:any){ElMessage.error(e.message)}})
</script>
<style scoped>
.siteforge-editor{display:flex;flex-direction:column;gap:12px;height:calc(100vh - 140px);min-height:680px}
.toolbar{display:flex;justify-content:space-between;gap:14px;align-items:center}
h2{margin:0;font-size:22px}p{margin:7px 0 0;color:var(--el-text-color-secondary);font-size:13px}.actions{display:flex;gap:10px;align-items:center}
.editor-viewport{flex:1;min-height:540px;border:1px solid var(--el-border-color);border-radius:12px;overflow:hidden;background:#fff}
.editor-viewport iframe{width:100%;height:100%;border:0}
@media(max-width:1020px){.toolbar,.actions{flex-wrap:wrap}.siteforge-editor{height:calc(100vh - 80px)}}
</style>