17 KiB
页面内容管理方案
版本:v1.0 | 最后更新:2026-04-29 配套文档:Worksheet 发布方案 | 小程序云开发方案
一、背景与目标
worksheet 已可通过 Debug 发布进入云数据库,但三个展示页仍使用本地静态数据:
| 页面 | 当前数据来源 | 问题 |
|---|---|---|
| 首页 | pages/home/home.data.ts |
featured、hot、分区靠代码手动维护 |
| 分类页 | pages/category/category.data.ts |
新 worksheet 发布后不会自动出现 |
| 分龄页 | pages/age/age.ts 内 Mock |
推荐内容和周路线无法运营配置 |
目标: 通过 Debug 管理页配置三个页面的内容,生成统一 JSON 上传云存储,小程序启动时通过数据预拉取获取并渲染。
二、整体架构
2.1 数据流
┌──────────────────────────────────────────────────────────────────┐
│ Debug 内容管理页(三个独立 tab) │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 首页管理 │ │ 分类页管理 │ │ 分龄页管理 │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │
│ └──────┬──────┘──────┬──────┘ │
│ ▼ ▼ │
│ 点击「更新」按钮 → 调用云函数 pageContentUpdate │
│ │ │
│ ▼ │
│ 更新云存储 content/page-config.json 中对应页面的配置 │
└──────────────────────────────────────────────────────────────────┘
▼
┌──────────────────────────────────────────────────────────────────┐
│ 小程序启动 │
│ │
│ app.onLaunch │
│ └─ 数据预拉取 → 获取 content/page-config.json │
│ │
│ 页面 onLoad │
│ ├─ 1. 使用本地 *.data.ts / age.config.ts 渲染兜底首屏 │
│ ├─ 2. 读取预拉取结果中对应页面的配置 │
│ └─ 3. 成功则 setData 更新页面 │
└──────────────────────────────────────────────────────────────────┘
2.2 统一 JSON 格式
云存储路径:content/page-config.json
// content/page-config.json 结构
type PageConfig = {
home: HomePageData; // 首页配置
category: CategoryPageData; // 分类页配置
age: AgePageData; // 分龄页配置
version: number; // 版本号,每次更新递增
updatedAt: string; // 最后更新时间
};
每个管理页更新时,只修改 JSON 中自己负责的字段,通过云函数读取当前 JSON → 合并更新 → 写回云存储。
2.3 页面加载策略
三个页面统一采用数据预拉取 + 本地兜底的加载策略:
页面 onLoad
│
├─ Step 1: 使用本地静态数据渲染首屏(零延迟)
│ 首页 → home.data.ts
│ 分类页 → category.data.ts
│ 分龄页 → age.config.ts
│
├─ Step 2: 读取数据预拉取结果
│ wx.getBackgroundFetchData('pre') 获取 page-config.json
│ 取出当前页面对应的配置(home / category / age)
│
└─ Step 3: 成功 → setData 更新页面内容
失败 → 保持本地兜底数据,用户无感知
数据预拉取在
app.json中配置fetchDataUrl,小程序冷启动时由微信客户端自动发起,不占用页面加载时间。预拉取的数据指向云存储中的content/page-config.json。
2.4 云函数设计
新增一个统一云函数 pageContentUpdate:
// cloudfunctions/pageContentUpdate/index.js
type PageContentUpdatePayload = {
page: 'home' | 'category' | 'age'; // 要更新的页面
data: HomePageData | CategoryPageData | AgePageData; // 该页面的完整配置
};
执行逻辑:
接收参数 { page, data }
→ 从云存储读取当前 content/page-config.json
→ 合并:config[page] = data
→ config.version++
→ config.updatedAt = new Date()
→ 写回云存储 content/page-config.json
→ 返回 { success, version }
三、首页内容管理
3.1 管理 UI
首页管理 tab 分为四个区块:
| 区块 | 对应字段 | 管理方式 |
|---|---|---|
| 分类 tab | categoryTabs |
跟随 CATEGORY_LIST_WITH_ALL,一般不单独管理 |
| 年龄入口 | ageBands |
跟随 AGE_BANDS,可管理描述文案 |
| 今日推荐 | featured |
手动选择 3-5 个 active worksheet |
| 热门推荐 | hot |
手动选择或按 downloads 自动生成 |
| 分类分区 | sections |
每个分类选择若干 active worksheet,支持排序 |
交互流程:
首页 tab 展示当前配置
→ 每个位置点击「选择内容」
→ 弹出 worksheet 选择器(筛选 active 内容)
→ 保存配置
→ 点击「更新首页数据」
→ 调用 pageContentUpdate({ page: 'home', data: ... })
3.2 数据结构
type HomePageData = {
searchPlaceholder: string;
categoryTabs: Array<{ id: string; name: string; path?: string }>;
ageBands: Array<{ key: string; label: string; desc: string; path: string }>;
featured: HomeDisplayItem[];
hot: HomeDisplayItem[];
sections: HomeDisplaySection[];
};
自动生成规则:
| 模块 | 默认规则 |
|---|---|
categoryTabs |
由 CATEGORY_LIST_WITH_ALL 生成 |
ageBands |
由 AGE_BANDS 生成 |
featured |
优先使用手动选择,不足时补 isNew == true |
hot |
优先使用手动选择,不足时补 isHot == true 或 downloads 高的内容 |
sections |
使用配置中的 worksheetIds,不足时从该分类 active 内容补齐 |
四、分类页内容管理
4.1 管理 UI
分类页管理 tab 顶部展示分类选择器(来源 CATEGORY_LIST),默认选中 math。
分类头部统计:
| 指标 | 查询规则 |
|---|---|
| 总数 | worksheets.category == 当前分类 |
| 草稿 | status == draft |
| 线上 | status == active |
| 已隐藏 | status == hidden |
列表展示当前分类下所有 worksheet(按 status → sortOrder → updatedAt 排序),每项显示预览图、标题、ID、年龄/难度/标签、状态、排序权重。
操作按钮:
| 当前状态 | 可执行操作 |
|---|---|
draft |
激活上线 |
active |
下架为 hidden |
hidden |
恢复为 draft 或直接激活 |
| 任意 | 调整排序、预览跳转、刷新 |
4.2 数据结构
type CategoryPageData = {
searchPlaceholder: string;
categories: Array<{
id: string;
name: string;
icon: string;
items: CategoryItem[];
}>;
};
生成时从 worksheets 集合查询 status == active 的内容,按分类分组、按 sortOrder 排序,转换为 CategoryItem。
4.3 更新流程
分类页管理 tab → 管理 worksheet 状态和排序
→ 点击「更新分类数据」
→ 查询所有 active worksheets,按 category 分组
→ 调用 pageContentUpdate({ page: 'category', data: ... })
→ 云函数更新 page-config.json 中的 category 字段
五、分龄页内容管理
5.1 新增 age.config.ts
在 miniprogram/pages/age/ 下新增 age.config.ts,将年龄段划分、能力目标、默认 worksheet 写死在配置中,作为兜底数据和管理页的基础结构。
// miniprogram/pages/age/age.config.ts
import { AGE_BANDS, type AgeBandKey } from '../../core/data/difficulty';
export type AbilityItem = {
icon: string;
title: string;
desc: string;
};
export type WeekPlan = {
week: number;
theme: string;
worksheetIds: string[]; // worksheet 业务 ID
worksheetTitles: string[]; // 兜底展示标题
};
export type AgeBandConfig = {
key: AgeBandKey;
label: string;
subLabel: string;
abilities: AbilityItem[];
weeks: WeekPlan[];
};
export const AGE_CONFIG: AgeBandConfig[] = [
{
key: '3-4',
label: '3-4 岁',
subLabel: '启蒙认知',
abilities: [
{ icon: '🔢', title: '数感', desc: '认读 1-5、点数对应' },
{ icon: '✏️', title: '书写', desc: '涂鸦线条、简单描红' },
{ icon: '🧩', title: '思维', desc: '找相同、简单配对' },
],
weeks: [
{ week: 1, theme: '数感启蒙',
worksheetIds: [], worksheetTitles: ['找数字涂一涂', '5以内加法', '数数连一连'] },
{ week: 2, theme: '形状与连线',
worksheetIds: [], worksheetTitles: ['识别形状', '线条识别', '数字点连线'] },
{ week: 3, theme: '趣味专注',
worksheetIds: [], worksheetTitles: ['颜色找规律', '方格推理', '格子仿画'] },
{ week: 4, theme: '综合练习',
worksheetIds: [], worksheetTitles: ['10以内加减法', '识字卡', '连连看'] },
],
},
{
key: '4-5',
label: '4-5 岁',
subLabel: '基础练习',
abilities: [
{ icon: '🔢', title: '数感', desc: '10 以内数数、比大小' },
{ icon: '✏️', title: '书写', desc: '笔画模仿、图形描边' },
{ icon: '🧩', title: '思维', desc: '规律排序、图形分类' },
],
weeks: [
{ week: 1, theme: '数感启蒙',
worksheetIds: [], worksheetTitles: ['找数字涂一涂', '5以内加法', '数数连一连'] },
{ week: 2, theme: '形状与连线',
worksheetIds: [], worksheetTitles: ['识别形状', '线条识别', '数字点连线'] },
{ week: 3, theme: '趣味专注',
worksheetIds: [], worksheetTitles: ['颜色找规律', '方格推理', '格子仿画'] },
{ week: 4, theme: '综合练习',
worksheetIds: [], worksheetTitles: ['10以内加减法', '识字卡', '连连看'] },
],
},
// 5-6、6-7、7-8 结构相同,abilities 和 weeks 内容不同
// ... 完整配置见 age.config.ts 文件
];
worksheetIds初始为空数组,由分龄管理页选择后填入。worksheetTitles作为兜底展示。
5.2 管理 UI
分龄管理 tab 按年龄段切换:3-4 岁 | 4-5 岁 | 5-6 岁 | 6-7 岁 | 7-8 岁
每个年龄段下的管理内容:
| 模块 | 操作 | 说明 |
|---|---|---|
| 能力目标 | 只读展示 | 来自 age.config.ts,不需要在管理页修改 |
| 四周路线 | 选择 worksheet | 每周选择 4 个 worksheet,主题来自 config |
| 推荐内容 | 选择 worksheet | 动态数据,展示 likes 数量最高的 6 个worksheet |
worksheet 选择器默认筛选条件:
status == active
ageMin <= 当前年龄段 maxAge
ageMax >= 当前年龄段 minAge
核心简化: 分龄管理页不需要配置能力目标和周主题(这些写死在 age.config.ts 中),只需要为不同年龄段、不同周选择对应的 worksheet。
5.3 数据结构
type AgePageData = {
ageTabs: Array<{
key: AgeBandKey;
rangeText: string;
subLabel: string;
}>;
bands: Record<AgeBandKey, {
goalTitle: string;
abilityItems: AbilityItem[];
weekPlans: Array<{
week: number;
theme: string;
exercises: Array<{
id: string;
title: string;
path: string;
previewImg?: string;
}>;
}>;
recommendedItems: Array<{
id: string;
title: string;
image?: string;
path: string;
}>;
}>;
};
5.4 更新流程
分龄管理 tab → 选择年龄段
→ 为每周选择 worksheet
→ 选择推荐内容
→ 点击「更新分龄数据」
→ 合并 age.config.ts 的能力目标 + 管理页选择的 worksheet 详情
→ 调用 pageContentUpdate({ page: 'age', data: ... })
→ 云函数更新 page-config.json 中的 age 字段
六、Debug 页入口结构
supportPages/debug/debug
├─ 分类基础数据管理 (已有:同步 CATEGORY_LIST → categories)
├─ Worksheet 内容池 (已有:状态、分类、上下架、预览)
└─ 页面内容管理 (新增)
├─ Tab: 首页管理 → 编排 featured / hot / sections
├─ Tab: 分类页管理 → 管理 worksheet 状态和排序
└─ Tab: 分龄页管理 → 按年龄段选择周 worksheet
七、实施计划
Phase 1:基础设施
- 配置
app.json数据预拉取,指向content/page-config.json - 实现
pageContentUpdate云函数 - 上传初始
page-config.json(从现有*.data.ts转换) - 三个页面统一接入预拉取加载逻辑
Phase 2:分类页管理
- 实现分类页管理 tab(worksheet 列表、状态管理、排序)
- 实现「更新分类数据」→ 生成 category 配置 → 调用云函数更新
Phase 3:首页管理
- 实现首页管理 tab(featured / hot / sections 编排)
- 实现 worksheet 选择器弹窗
- 实现「更新首页数据」→ 生成 home 配置 → 调用云函数更新
Phase 4:分龄页管理
- 新增
age.config.ts配置文件 - 实现分龄管理 tab(年龄段切换、周 worksheet 选择)
- 实现「更新分龄数据」→ 合并 config + worksheet 详情 → 调用云函数更新
八、风险与约束
| 风险 | 处理方式 |
|---|---|
| 预拉取失败 | 本地 *.data.ts / age.config.ts 兜底,用户无感知 |
| JSON 生成失败 | 云函数返回错误,管理页提示重试,线上数据不受影响 |
| 首页配置引用了 hidden 内容 | 生成时只允许 active 内容,不足时返回警告 |
| 分龄内容不适龄 | 选择器按年龄段默认过滤 |
| 并发更新冲突 | 云函数使用 version 乐观锁,冲突时提示重新加载后重试 |
九、关键文件索引
| 文件 / 模块 | 职责 |
|---|---|
supportPages/contentManage/ |
三 tab 内容管理页 |
cloudfunctions/pageContentUpdate/ |
更新 page-config.json 中指定页面的配置 |
pages/age/age.config.ts |
分龄页兜底配置(年龄段、能力目标、默认 worksheet) |
pages/home/home.data.ts |
首页兜底数据 |
pages/category/category.data.ts |
分类页兜底数据 |
content/page-config.json(云存储) |
三个页面的统一配置 JSON |