Commit 2995acc2 by pangchong

feat(editor): 实现编辑器模板保存及桥接通信功能

- 修改本地开发桥接服务配置,默认关闭本地接口直接请求
- registerEditorBridgeListeners 方法支持传入获取 HTML 和 CSS 的回调
- GET_EDITOR_GXPDF 事件返回数据中增加 HTML 和 CSS 内容字段
- 编辑区上下文菜单和节点树功能支持“保存为模板”,将节点序列化为 XML 并调用保存接口
- 编辑器初始化时注册桥接事件监听,返回预处理后的 HTML 和样式数据
- 优化本地桥接接口的 getTemplateList 函数,简化返回数据结构处理
- 添加 saveTemplate 方法接口定义准备提交模板数据
parent 7e2b7cfc
# 分区名称标识 # 分区名称标识
VITE_PARTITION_NAME = from_project_001 VITE_PARTITION_NAME = from_project_001
# 开发环境下默认启用本地开发桥接服务 (true 使用本地接口直接请求/模拟,false 降级使用父项目传递的 promise) # 开发环境下默认启用本地开发桥接服务 (true 使用本地接口直接请求/模拟,false 降级使用父项目传递的 promise)
VITE_IF_LOCAL_BRIDGE = true VITE_IF_LOCAL_BRIDGE = false
\ No newline at end of file \ No newline at end of file
...@@ -94,9 +94,9 @@ export const getEditorData = (...args: any[]) => { ...@@ -94,9 +94,9 @@ export const getEditorData = (...args: any[]) => {
* 注册编辑器的桥接事件监听器 (用于集成模式下响应父级提取 XML/PDF 数据的请求) * 注册编辑器的桥接事件监听器 (用于集成模式下响应父级提取 XML/PDF 数据的请求)
* 返回一个清理函数,用于组件卸载时注销所有监听器 * 返回一个清理函数,用于组件卸载时注销所有监听器
*/ */
export const registerEditorBridgeListeners = (): (() => void) => { export const registerEditorBridgeListeners = (getHtmlAndCss?: () => { html: string; css: string }): (() => void) => {
if (customBridge && customBridge.registerEditorBridgeListeners) { if (customBridge && customBridge.registerEditorBridgeListeners) {
return customBridge.registerEditorBridgeListeners() return customBridge.registerEditorBridgeListeners(getHtmlAndCss)
} }
if (isLocalBridge()) return () => {} if (isLocalBridge()) return () => {}
...@@ -116,10 +116,17 @@ export const registerEditorBridgeListeners = (): (() => void) => { ...@@ -116,10 +116,17 @@ export const registerEditorBridgeListeners = (): (() => void) => {
const unPdf = postMessageHelper.on('GET_EDITOR_GXPDF', () => { const unPdf = postMessageHelper.on('GET_EDITOR_GXPDF', () => {
if (store.xmlTree) { if (store.xmlTree) {
const xml = serializeTreeToXml(store.xmlTree, 0, true) const xml = serializeTreeToXml(store.xmlTree, 0, true)
let html = xml
let css = xml
if (getHtmlAndCss) {
const res = getHtmlAndCss()
html = res.html
css = res.css
}
postMessageHelper.emit('GET_EDITOR_GXPDF', { postMessageHelper.emit('GET_EDITOR_GXPDF', {
jcXml: xml, jcXml: xml,
xmlContent: xml, jcHtml: html,
content: xml jcCss: css
}) })
} }
}) })
......
...@@ -379,7 +379,8 @@ export function useEditAreaContextMenu(props: EditAreaContextMenuProps, emit: (e ...@@ -379,7 +379,8 @@ export function useEditAreaContextMenu(props: EditAreaContextMenuProps, emit: (e
// 6. 保存为 XML 模板 // 6. 保存为 XML 模板
else if (actionName === 'saveTemplate') { else if (actionName === 'saveTemplate') {
window.$message.info('保存为模板功能开发中') const xml = serializeTreeToXml(mapped.node)
saveTemplate(mapped.node.tagName, xml)
} }
// 7. 智能翻译 // 7. 智能翻译
......
...@@ -1222,9 +1222,13 @@ export function useNodeTree( ...@@ -1222,9 +1222,13 @@ export function useNodeTree(
break break
} }
// ── 保存为模板(暂提示)── // ── 保存为模板 ──
case 'saveAsTemplate': { case 'saveAsTemplate': {
window.$message?.info('保存为模板功能开发中') const mapped = editorStore.nodeMap.get(nodeId)
if (mapped) {
const xml = serializeTreeToXml(mapped.node)
saveTemplate(mapped.node.tagName, xml)
}
break break
} }
} }
......
...@@ -13,9 +13,6 @@ export function useEditor() { ...@@ -13,9 +13,6 @@ export function useEditor() {
const store = useEditorStore() const store = useEditorStore()
const cleanupFns: (() => void)[] = [] const cleanupFns: (() => void)[] = []
// 注册桥接通信事件监听 (GET_EDITOR_GXXML 和 GET_EDITOR_GXPDF)
const unregisterBridge = registerEditorBridgeListeners()
cleanupFns.push(unregisterBridge)
onUnmounted(() => { onUnmounted(() => {
cleanupFns.forEach((un) => un()) cleanupFns.forEach((un) => un())
...@@ -392,6 +389,17 @@ export function useEditor() { ...@@ -392,6 +389,17 @@ export function useEditor() {
}) })
} }
// 注册桥接通信事件监听 (GET_EDITOR_GXXML 和 GET_EDITOR_GXPDF)
const unregisterBridge = registerEditorBridgeListeners(() => {
const cleaned = prepareCleanedHtml()
if (!cleaned) return { html: '', css: '' }
return {
html: `<div class="print-preview-root">${cleaned.innerHTML}</div>`,
css: `${cleaned.styles}\n<style>${printStyles}</style>`
}
})
cleanupFns.push(unregisterBridge)
return { return {
initialize, initialize,
save, save,
......
...@@ -15,22 +15,11 @@ export interface TemplateResponse { ...@@ -15,22 +15,11 @@ export interface TemplateResponse {
// 本地接口的具体实现 // 本地接口的具体实现
const localBridge = { const localBridge = {
getTemplateList: async (page: number, rows: number): Promise<TemplateResponse> => { getTemplateList: async (page: number, rows: number): Promise<any> => {
const res = await apiService.post<any>('/plugins/EM_JOBCARD_GX_TEMPLATE_SELECT_PAGE', { return await apiService.post<any>('/plugins/EM_JOBCARD_GX_TEMPLATE_SELECT_PAGE', {
page, page,
rows rows
}) })
if (res) {
const listData = Array.isArray(res.data) ? res.data : res.rows || []
const totalCount = res.total !== undefined ? res.total : listData.length
return {
code: 200,
msg: res.msg || 'Success',
total: totalCount,
data: listData
}
}
throw new Error('接口未返回有效的数据结构')
}, },
saveTemplate: async (name: string, content: string): Promise<any> => { saveTemplate: async (name: string, content: string): Promise<any> => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment