Files
doodle-mini/miniprogram/core/models/worksheet.ts
T
2026-03-27 17:31:52 +08:00

188 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 题型与模板引擎相关模型:对齐技术架构 §5.4 与云开发 worksheets 集合 §3.3
*/
/** 小程序现状:专注力单独成类;云端 category 枚举无 focus 时可映射为 puzzle + subcategory */
export type WorksheetCategory =
| 'math'
| 'focus'
| 'chinese'
| 'english'
| 'puzzle'
| 'craft';
/** 云 worksheets.category 严格枚举(§3.3 */
export type WorksheetCloudCategory =
| 'math'
| 'chinese'
| 'english'
| 'puzzle'
| 'craft';
export type DifficultyLevel =
| 'beginner'
| 'basic'
| 'intermediate'
| 'advanced';
export type WorksheetStatus = 'active' | 'draft' | 'hidden';
/** 排版模板(技术架构 §5.4) */
export type TemplateType =
| 'grid-exercise'
| 'match-connect'
| 'grid-coloring'
| 'card-layout'
| 'tracing-writing'
| 'full-page-asset'
| 'sequence-pattern'
| 'special-graphic';
/** 数据生成器(技术架构 §5.4) */
export type GeneratorType =
| 'arithmetic'
| 'number-sequence'
| 'number-decompose'
| 'counting'
| 'comparison'
| 'shape-grid'
| 'color-pattern'
| 'character-tracing'
| 'letter-tracing'
| 'pinyin-tracing'
| 'static-asset'
| 'maze'
| 'dot-connect'
| 'clock'
| 'custom';
export interface LayoutConfig {
columns?: number;
rows?: number;
fontSize?: number;
showBorder?: boolean;
showTitle?: boolean;
padding?: number;
itemSpacing?: number;
showInstruction?: boolean;
instructionText?: string;
}
export interface UserConfigField {
key: string;
label: string;
type: 'select' | 'slider' | 'switch';
options?: { label: string; value: unknown }[];
min?: number;
max?: number;
defaultValue: unknown;
}
/** 与架构文档 WorksheetConfig 一致,供云端下发 / 本地内置 */
export interface WorksheetConfig {
id: string;
title: string;
desc: string;
category: WorksheetCloudCategory;
subcategory: string;
ageMin: number;
ageMax: number;
difficulty: 1 | 2 | 3 | 4;
previewImage: string;
tags: string[];
isNew: boolean;
isHot: boolean;
sortOrder: number;
status: WorksheetStatus;
template: TemplateType;
generator: GeneratorType;
generatorConfig: Record<string, unknown>;
layoutConfig: LayoutConfig;
userConfigurable?: UserConfigField[] | null;
legacyPage?: string | null;
downloadCount: number;
}
/** 云集合 `worksheets` 文档(§3.3,含数据库字段) */
export interface WorksheetRecord extends WorksheetConfig {
_id: string;
createdAt: Date;
updatedAt: Date;
}
/** 列表卡片 / 导航用(兼容存量页面) */
export interface WorksheetType {
id: string;
title: string;
desc: string;
category: WorksheetCategory;
page?: string;
subpackage?: string;
icon?: string;
img?: string;
ageRange?: [number, number];
difficulty?: DifficultyLevel;
mode?: string;
previewBg?: string;
previewText?: string;
}
/** 内置兜底 + 模板引擎字段(本地 core/data/worksheets */
export interface WorksheetDefinition extends WorksheetType {
subcategory: string;
ageMin: number;
ageMax: number;
/** 14,对应云 worksheets.difficulty */
difficultyLevel: 1 | 2 | 3 | 4;
previewImage: string;
tags: string[];
isNew: boolean;
isHot: boolean;
sortOrder: number;
downloadCount: number;
status: WorksheetStatus;
template: TemplateType;
generator: GeneratorType;
generatorConfig: Record<string, unknown>;
layoutConfig: LayoutConfig;
userConfigurable?: UserConfigField[] | null;
legacyPage?: string | null;
}
/** 写入云库时的 categoryfocus 归为 puzzle,子类区分 */
export function toCloudCategory(
category: WorksheetCategory,
): WorksheetCloudCategory {
if (category === 'focus') return 'puzzle';
return category;
}
/** 由内置定义生成云侧 worksheets 文档形状(不含 _id/时间,供同步层补全) */
export function worksheetDefinitionToConfig(
def: WorksheetDefinition,
): Omit<WorksheetRecord, '_id' | 'createdAt' | 'updatedAt'> {
return {
id: def.id,
title: def.title,
desc: def.desc,
category: toCloudCategory(def.category),
subcategory: def.subcategory,
ageMin: def.ageMin,
ageMax: def.ageMax,
difficulty: def.difficultyLevel,
previewImage: def.previewImage,
tags: def.tags,
isNew: def.isNew,
isHot: def.isHot,
sortOrder: def.sortOrder,
downloadCount: def.downloadCount,
status: def.status,
template: def.template,
generator: def.generator,
generatorConfig: def.generatorConfig,
layoutConfig: def.layoutConfig,
userConfigurable: def.userConfigurable ?? null,
legacyPage: def.legacyPage ?? null,
};
}