📌 目标:以 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(页面层)
用于:按页面聚合 SectionInstance 列表。
4. ThemeOptions(入口层)
用于:记录当前租户的主题信息和页面入口(页面 ID 映射表)。
🔁 二、前端 CMS 操作流程(开发视角)
✅ Step 1:选择主题 + 页面类型
用户在 CMS 中选择:
-
themeName = "cool"
-
sceneName = "landing"
✅ Step 2:查结构模板 schema(用于展示表单结构)
请求:
查询语句:
✅ Step 3:查是否已有用户内容(SectionInstance)
🌿 场景一:无 PageInstance(页面第一次生成)
-
创建 sectionInstance[](根据模板结构一一创建,props 初始为空或带 defaultValue)
-
创建 pageInstance,关联这些 sectionInstance
-
更新 ThemeOptions.pageInstanceMap[
landing
] = pageInstance.id
🌳 场景二:已有 PageInstance
✅ Step 4:构建渲染结构
💾 三、保存逻辑
每个 SectionInstance 可单独保存:
也可以批量保存 PageInstance 下所有 section(optional)。
📦 四、总结
层级 | 模型 | 说明 |
---|---|---|
结构层 | section_registry |
模板定义,用于生成字段结构 |
内容层 | SectionInstance |
用户填写的实际内容 |
页面层 | PageInstance |
聚合多个模块组成页面 |
映射层 | ThemeOptions.pageInstanceMap |
用于识别当前页面入口 ID |
⚠️ 所有动态变动都基于数据库,schema 注册在 section_registry,数据存储在 SectionInstance,映射控制由 ThemeOptions 统一管理。