Skip to content

Commit

Permalink
feat:preview multi page structured data transfer and nested display (#…
Browse files Browse the repository at this point in the history
…978)

* feat:预览多页结构数据传输以及嵌套显示

* fix:获取链路页面兼容页面树为空的情况

* fix:fix review
  • Loading branch information
lichunn authored Jan 2, 2025
1 parent 304e010 commit 84a403f
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 47 deletions.
52 changes: 40 additions & 12 deletions packages/design-core/src/preview/src/preview/Preview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export default {
const debugSwitch = injectDebugSwitch()
const editorComponent = computed(() => (debugSwitch?.value ? Monaco : EmptyEditor))
const store = new ReplStore()
const { getAllNestedBlocksSchema, generatePageCode } = getMetaApi('engine.service.generateCode')
const ROOT_ID = '0'
const sfcOptions = {
script: {
Expand Down Expand Up @@ -84,6 +86,43 @@ export default {
return getInitImportMap()
}
const getFamilyPages = (appData) => {
const familyPages = []
const ancestors = queryParams.ancestors
for (let i = 0; i < ancestors.length; i++) {
const nextPage = i < ancestors.length - 1 ? ancestors[i + 1].name : null
const panelValueAndType = {
panelValue:
generatePageCode(
ancestors[i].page_content,
appData?.componentsMap || [],
{
blockRelativePath: './'
},
nextPage
) || '',
panelType: 'vue'
}
if (ancestors[i]?.parentId === ROOT_ID) {
familyPages.push({
...panelValueAndType,
panelName: 'Main.vue',
index: true
})
} else {
familyPages.push({
...panelValueAndType,
panelName: `${ancestors[i].name}.vue`,
index: false
})
}
}
return familyPages
}
const promiseList = [
fetchAppSchema(queryParams?.app),
fetchMetaData(queryParams),
Expand All @@ -93,22 +132,12 @@ export default {
Promise.all(promiseList).then(async ([appData, metaData, _void, importMapData]) => {
addUtilsImportMap(importMapData, metaData.utils || [])
const { getAllNestedBlocksSchema, generatePageCode } = getMetaApi('engine.service.generateCode')
const blocks = await getAllNestedBlocksSchema(queryParams.pageInfo?.schema, fetchBlockSchema)
// TODO: 需要验证级联生成 block schema
// TODO: 物料内置 block 需要如何处理?
const pageCode = [
{
panelName: 'Main.vue',
panelValue:
generatePageCode(queryParams.pageInfo?.schema, appData?.componentsMap || [], {
blockRelativePath: './'
}) || '',
panelType: 'vue',
index: true
},
...getFamilyPages(appData),
...(blocks || []).map((blockSchema) => {
return {
panelName: `${blockSchema.fileName}.vue`,
Expand Down Expand Up @@ -171,7 +200,6 @@ export default {
Object.assign(newFiles, metaFiles)
setFiles(newFiles)
return PreviewTips.READY_FOR_PREVIEW
})
Expand Down
43 changes: 28 additions & 15 deletions packages/plugins/page/src/composable/usePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,21 @@ const getPageList = async (appId) => {
return pageSettingState.pages
}

/**
* @param {string | number} id
* @param {(string | number)[]} ancestors
* @returns {(string | number)[]}
*/
const getAncestorsRecursively = (id) => {
const pageNode = pageSettingState.treeDataMapping[id]

if (pageNode.id === pageSettingState.ROOT_ID) {
return []
}

return [pageNode].concat(getAncestorsRecursively(pageNode.parentId))
}

/**
* @param {string | number} id page Id
* @param {boolean} withFolders default `false`
Expand All @@ -222,30 +237,27 @@ const getAncestors = async (id, withFolders) => {
await getPageList(appId)
}

/**
* @param {string | number} id
* @param {(string | number)[]} ancestors
* @returns {(string | number)[]}
*/
const getAncestorsRecursively = (id) => {
const pageNode = pageSettingState.treeDataMapping[id]

if (pageNode.id === pageSettingState.ROOT_ID) {
return []
}

return [pageNode].concat(getAncestorsRecursively(pageNode.parentId))
}

const ancestorsWithSelf = getAncestorsRecursively(id)
const ancestors = ancestorsWithSelf.slice(1).reverse()

if (withFolders) {
return ancestors.map((item) => item.id)
}

return ancestors.filter((item) => item.isPage).map((item) => item.id)
}

const getFamily = async (id) => {
if (pageSettingState.pages.length === 0) {
const appId = getMetaApi(META_SERVICE.GlobalService).getBaseInfo().id
await getPageList(appId)
}

return getAncestorsRecursively(id)
.filter((item) => item.isPage)
.reverse()
}

export default () => {
return {
DEFAULT_PAGE,
Expand All @@ -261,6 +273,7 @@ export default () => {
isChangePageData,
getPageList,
getAncestors,
getFamily,
STATIC_PAGE_GROUP_ID,
COMMON_PAGE_GROUP_ID
}
Expand Down
4 changes: 3 additions & 1 deletion packages/toolbars/preview/src/Main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<script>
import { previewPage, previewBlock } from '@opentiny/tiny-engine-common/js/preview'
import { useBlock, useCanvas, useLayout, useNotify } from '@opentiny/tiny-engine-meta-register'
import { useBlock, useCanvas, useLayout, useNotify, usePage } from '@opentiny/tiny-engine-meta-register'
import { getMergeMeta, getOptions } from '@opentiny/tiny-engine-meta-register'
import meta from '../meta'
import { ToolbarBase } from '@opentiny/tiny-engine-common'
Expand All @@ -30,6 +30,7 @@ export default {
setup() {
const { isBlock, getCurrentPage, canvasApi } = useCanvas()
const { getCurrentBlock } = useBlock()
const { getFamily } = usePage()
const preview = async () => {
const { beforePreview, previewMethod, afterPreview } = getOptions(meta.id)
Expand Down Expand Up @@ -79,6 +80,7 @@ export default {
const page = getCurrentPage()
params.id = page?.id
params.pageInfo.name = page?.name
params.ancestors = await getFamily(params.id)
previewPage(params)
}
Expand Down
15 changes: 10 additions & 5 deletions packages/vue-generator/src/generator/vue/sfc/genSetupSFC.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const defaultStyleConfig = {
lang: ''
}

const generateSFCFile = (schema, componentsMap, config = {}) => {
const generateSFCFile = (schema, componentsMap, config = {}, nextPage) => {
const parsedConfig = parseConfig(config)
const { blockRelativePath, blockSuffix, scriptConfig: initScriptConfig, styleConfig: initStyleConfig } = parsedConfig
// 前置动作,对 Schema 进行解析初始化相关配置与变量
Expand Down Expand Up @@ -197,18 +197,23 @@ const generateSFCFile = (schema, componentsMap, config = {}) => {
}

// 解析 template
const templateStr = genTemplateByHook(schema, globalHooks, { ...parsedConfig, componentsMap: componentsMap })
const templateStr = genTemplateByHook(
schema,
globalHooks,
{ ...parsedConfig, componentsMap: componentsMap },
nextPage
)

// 生成 script
const scriptStr = genScriptByHook(schema, globalHooks, { ...parsedConfig, componentsMap: componentsMap })
const scriptStr = genScriptByHook(schema, globalHooks, { ...parsedConfig, componentsMap: componentsMap }, nextPage)

// 生成 style
const styleStr = generateStyleTag(schema, styleConfig)

return `${templateStr}\n${scriptStr}\n${styleStr}`
}

export const genSFCWithDefaultPlugin = (schema, componentsMap, config = {}) => {
export const genSFCWithDefaultPlugin = (schema, componentsMap, config = {}, nextPage) => {
const { templateItemValidate = [], genTemplate = [], parseScript = [], genScript = {} } = config.hooks || {}
const defaultComponentHooks = [handleComponentNameHook, handleTinyIcon]

Expand Down Expand Up @@ -265,7 +270,7 @@ export const genSFCWithDefaultPlugin = (schema, componentsMap, config = {}) => {
// 兼容单独调用的场景,单独调用时,这里会默认加上 builtInComponents
const compsMapWithBuiltIn = [...componentsMap, ...BUILTIN_COMPONENTS_MAP]

return generateSFCFile(schema, compsMapWithBuiltIn, newConfig)
return generateSFCFile(schema, compsMapWithBuiltIn, newConfig, nextPage)
}

export default generateSFCFile
19 changes: 11 additions & 8 deletions packages/vue-generator/src/generator/vue/sfc/generateScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ import { INSERT_POSITION } from '@/constant'
import { transformObjType } from './generateAttribute'
import { hasJsx } from '@/utils/hasJsx'

export const defaultGenImportHook = (schema, globalHooks) => {
export const defaultGenImportHook = (schema, globalHooks, config, nextPage) => {
const dependenciesMap = globalHooks.getImport() || {}
const importContent = Object.entries(dependenciesMap).map(([key, value]) => {
return generateImportByPkgName({ pkgName: key, imports: value }) || ''
})

return Object.entries(dependenciesMap)
.map(([key, value]) => {
return generateImportByPkgName({ pkgName: key, imports: value }) || ''
})
.join('\n')
if (nextPage) {
importContent.push(`import ${nextPage} from "./${nextPage}.vue"`)
}

return importContent.join('\n')
}

export const defaultGenPropsHook = (schema) => {
Expand Down Expand Up @@ -162,7 +165,7 @@ export const GEN_SCRIPT_HOOKS = {
GEN_LIFECYCLE: 'GEN_LIFECYCLE'
}

export const genScriptByHook = (schema, globalHooks, config) => {
export const genScriptByHook = (schema, globalHooks, config, nextPage) => {
const hooks = config.hooks || {}
const { parseScript = [], genScript = {} } = hooks

Expand Down Expand Up @@ -206,7 +209,7 @@ export const genScriptByHook = (schema, globalHooks, config) => {
statementGroupByPosition[AFTER_METHODS].push(statement?.value)
})

const importStr = genScript[GEN_SCRIPT_HOOKS.GEN_IMPORT]?.(schema, globalHooks, config) || ''
const importStr = genScript[GEN_SCRIPT_HOOKS.GEN_IMPORT]?.(schema, globalHooks, config, nextPage) || ''
const propsStr = genScript[GEN_SCRIPT_HOOKS.GEN_PROPS]?.(schema, globalHooks, config) || ''
const emitStr = genScript[GEN_SCRIPT_HOOKS.GEN_EMIT]?.(schema, globalHooks, config) || ''
const stateStr = genScript[GEN_SCRIPT_HOOKS.GEN_STATE]?.(schema, globalHooks, config) || ''
Expand Down
15 changes: 9 additions & 6 deletions packages/vue-generator/src/generator/vue/sfc/generateTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,14 @@ export const validEmptyTemplateHook = (schema = {}) => {

// TODO: 支持物料中自定义出码关联片段

export const recursiveGenTemplateByHook = (schemaWithRes, globalHooks, config = {}) => {
export const recursiveGenTemplateByHook = (schemaWithRes, globalHooks, config = {}, nextPage) => {
const schemaChildren = schemaWithRes?.schema?.children || []
const { hooks = {}, isJSX } = config
// 自定义 hooks
const { genTemplate: genTemplateHooks, templateItemValidate } = hooks

if (!Array.isArray(schemaChildren)) {
schemaWithRes.children.push(schemaChildren || '')

return
}

Expand All @@ -195,7 +194,11 @@ export const recursiveGenTemplateByHook = (schemaWithRes, globalHooks, config =
return schemaItem || ''
}

const { componentName, component } = schemaItem
let { componentName, component } = schemaItem

if (nextPage) {
componentName = componentName === 'RouterView' ? nextPage : componentName
}

const optionData = {
schema: schemaItem,
Expand All @@ -208,7 +211,7 @@ export const recursiveGenTemplateByHook = (schemaWithRes, globalHooks, config =
}

for (const hookItem of [...genTemplateHooks, recursiveGenTemplateByHook]) {
hookItem(optionData, globalHooks, config)
hookItem(optionData, globalHooks, config, nextPage)
}

const startTag = generateTag(optionData.componentName, {
Expand All @@ -230,13 +233,13 @@ ${optionData.prefix.join('')}${startTag}${optionData.children.join('')}${endTag}
schemaWithRes.children = schemaWithRes.children.concat(resArr)
}

export const genTemplateByHook = (schema, globalHooks, config) => {
export const genTemplateByHook = (schema, globalHooks, config, nextPage) => {
const parsedSchema = {
children: [],
schema: structuredClone({ children: [{ ...schema, componentName: 'div' }] })
}

recursiveGenTemplateByHook(parsedSchema, globalHooks, config)
recursiveGenTemplateByHook(parsedSchema, globalHooks, config, nextPage)

return `<template>${parsedSchema.children.join('')}</template>`
}

0 comments on commit 84a403f

Please sign in to comment.