当前位置: 首页 > news >正文

(阶段二:落地) CMS 模板系统核心数据结构与流程梳理(SceneStack)

 📌 目标:以 tenantId 为核心构建 theme + scene + section 的配置系统,实现从 schema 显示、内容编辑、再到保存的完整闭环。

🌐 一、核心数据结构(数据库设计)

1. Section 模板定义(结构层)

每个 theme + scene 下的模块结构由系统预设,写在 section_registry 表中:

CREATE TABLE section_registry (id SERIAL PRIMARY KEY,theme_name TEXT NOT NULL,scene_name TEXT NOT NULL,section_name TEXT NOT NULL,schema JSONB NOT NULL,           -- 字段结构定义display_order INTEGER NOT NULL DEFAULT 0,  -- 顺序排列UNIQUE (theme_name, scene_name, section_name)
);

 

用于:提供结构化的 schema,用来渲染输入表单。


2. SectionInstance(内容层)

interface SectionInstance {id: string;tenantId: string;themeName: string;       // 冗余,方便检索sceneName: string;       // 如 landing、shopsectionName: string;     // 如 HeroSectionorder: number;           // 顺序props: Record<string, any>;  // 用户填写的数据
  updatedAt: Date;
}

 

用于:保存每一个模块的用户填写内容。

3. PageInstance(页面层)

interface PageInstance {id: string;pageType: string;      // 如 landingthemeName: string;sections: sectionInstanceId[];
}

 

用于:按页面聚合 SectionInstance 列表。


4. ThemeOptions(入口层)

interface ThemeOptions {tenantId: string;themeName: string; // "cool", "general"pageInstanceMap: Record<string, PageInstanceId>; // 如 { landing: 'abc-123' }
  updatedAt: Date;themeVariant?: string;version?: number;
}

 

用于:记录当前租户的主题信息和页面入口(页面 ID 映射表)。


🔁 二、前端 CMS 操作流程(开发视角)


✅ Step 1:选择主题 + 页面类型

用户在 CMS 中选择:

  • themeName = "cool"

  • sceneName = "landing"


✅ Step 2:查结构模板 schema(用于展示表单结构)

请求:

GET /api/section-schema?template=cool&pageType=landing

查询语句:

SELECT * FROM section_registry WHERE theme_name = 'cool' AND scene_name = 'landing' ORDER BY display_order ASC;

 

返回:结构列表 section_registry[],用于构建输入表单。

✅ Step 3:查是否已有用户内容(SectionInstance)

🌿 场景一:无 PageInstance(页面第一次生成)

  • 创建 sectionInstance[](根据模板结构一一创建,props 初始为空或带 defaultValue)

  • 创建 pageInstance,关联这些 sectionInstance

  • 更新 ThemeOptions.pageInstanceMap[landing] = pageInstance.id

🌳 场景二:已有 PageInstance

const pageInstanceId = themeOptions.pageInstanceMap['landing']
const pageInstance = await db.pageInstance.find(pageInstanceId)
  • pageInstance.themeName !== themeOptions.themeName,说明主题已更换,重新创建

  • 否则查出 section 实例:

const sectionInstanceList = await db.sectionInstance.find({where: {id: { in: pageInstance.sections }},orderBy: {order: 'asc'}
})

 


✅ Step 4:构建渲染结构

sectionRegistryList.map((sectionSchema, i) => {const sectionData = sectionInstanceList[i]; // 一一对应const props = sectionData.props;Object.entries(sectionSchema.schema).forEach(([fieldKey, fieldMeta]) => {const fieldValue = props[fieldKey]; // 取出实际值// 渲染 label + input(fieldMeta.type) + value(fieldValue)
  });
});

 


💾 三、保存逻辑

每个 SectionInstance 可单独保存:

PATCH /api/section-instance/:idbody = {props: {primaryText: "...",imageUrl: "...",...}
}

 

也可以批量保存 PageInstance 下所有 section(optional)。

📦 四、总结

层级模型说明
结构层 section_registry 模板定义,用于生成字段结构
内容层 SectionInstance 用户填写的实际内容
页面层 PageInstance 聚合多个模块组成页面
映射层 ThemeOptions.pageInstanceMap 用于识别当前页面入口 ID

⚠️ 所有动态变动都基于数据库,schema 注册在 section_registry,数据存储在 SectionInstance,映射控制由 ThemeOptions 统一管理。

http://www.wuyegushi.com/news/1075.html

相关文章:

  • CAXA3D 实体设计2025最新版本下载安装图文教程,一键快速安装激活
  • 前端开发者的利器:6款最强类EXCEL表格插件对比,轻松实现Excel级交互
  • 软考系统分析师每日学习卡 | [日期:2025-07-28] | [今日主题:操作系统概述]
  • xshell的正则表达式
  • Linux查看PCIe版本及速率
  • 盈鹏飞嵌入式带你玩转T113系列tina5 SDK(7)-使用ADB来传输文件
  • CLion与Beta版:使用Unicode UTF-8提供全球语言支持
  • PowerShell脚本执行打包命令
  • 盈鹏飞嵌入式带你玩转T113系列tina5 SDK(6)-添加心跳灯
  • “轻”是态度,“强”是底气:折叠屏的“成人礼”
  • zip伪加密writeup
  • 25_1 C++函数参数传递方式
  • annocanda配置一个python环境的案例
  • wsl2 非系统盘下安装ubuntu22.04的极简方法
  • 盈鹏飞嵌入式带你玩转T113系列tina5 SDK(4)-如何适配自己的开发板
  • 盈鹏飞嵌入式带你玩转T113系列tina5 SDK(5)-Uboot单独编译
  • 使用Python和Gradio构建基于OpenAI GPT-4的AI聊天机器人
  • 19C++循环结构-多重循环(2)
  • 数据库计算机三级等级考试–网络技术
  • 树03
  • 如何快速做一个矢量格式的Logo?我盘点了6个最火的AI Logo设计工具,可快速生成品牌设计!
  • 【2025-07-25】暑假安排
  • B2013 温度表达转化
  • B2005 字符三角形
  • P5704 【深基2.例6】字母转换
  • B2021 输出保留 3 位小数的浮点数
  • 最新版idea2025有效激活码,idea永久破解激活教程(内附激活码+激活工具)
  • Feign返回text/plain导致DecodeException问题与解决方案总结
  • git ignore 文件,只跟踪特定文件
  • CAXA工艺图表2025 下载安装激活详细教程,5分钟即可安装使用