在这里插入图片描述

📖 引言

在知识问答学习应用中,用户数据是连接所有功能的核心纽带。从用户登录、学习进度追踪,到成就系统、排行榜,都离不开完善的用户数据模型。

本文将详细讲解 User 模型的完整设计,包括用户基本信息、学习统计、成就管理、个性化设置等核心内容。通过本文,你将掌握:

  • 如何设计完整且可扩展的用户数据模型
  • 如何使用嵌套接口组织复杂数据结构
  • 如何实现学习统计和成就系统
  • 如何在实际项目中管理用户数据

🎯 学习目标

完成本文后,你将能够:

  • ✅ 理解 User 模型的完整字段定义和用途
  • ✅ 掌握嵌套接口的设计和使用
  • ✅ 实现用户数据的校验逻辑
  • ✅ 在实际项目中创建和管理用户数据

💡 需求分析

功能模块设计

模块 功能描述 技术要点
用户基本信息 存储用户的基本信息,如昵称、头像、等级等 基础字段、数据类型
学习进度追踪 记录用户的关卡解锁、完成状态和星级 数组、Map 结构
成就系统 管理用户获得的成就列表 字符串数组、成就触发
个性化设置 存储用户的偏好配置 嵌套接口、枚举
学习统计 记录用户的学习数据和统计信息 嵌套接口、Map 结构

🛠️ 核心实现

步骤1: 定义 User 主接口

功能说明

User 接口是用户数据的核心模型,包含了用户的所有信息,从基本信息到学习统计,从成就系统到个性化设置。

完整代码
// models/User.ts

/**
 * 年龄组枚举
 */
export enum AgeGroup {
  CHILD = '少儿',
  TEENAGER = '青少年',
  ADULT = '成人'
}

/**
 * 用户工具道具接口
 */
export interface UserTools {
  removeError: number;    // 消除错误次数
  extendTime: number;     // 延长时间次数
  hint: number;           // 提示次数
  skip: number;           // 跳过次数
}

/**
 * 用户设置接口
 */
export interface UserSettings {
  soundEnabled: boolean;      // 音效开关
  vibrationEnabled: boolean;  // 震动开关
  questionTimer: number;      // 答题计时器(秒)
  showExplanation: boolean;   // 是否显示解析
  ageGroup: AgeGroup;         // 年龄组
  difficultyLock: boolean;    // 难度锁定
}

/**
 * 学科统计接口
 */
export interface SubjectStat {
  subjectId: string;        // 学科 ID
  totalQuestions: number;   // 该学科答题数
  correctQuestions: number; // 该学科正确数
  accuracy: number;         // 该学科正确率
}

/**
 * 用户统计接口
 */
export interface UserStatistics {
  totalQuestions: number;       // 总答题数
  correctQuestions: number;     // 正确答题数
  totalStudyTime: number;       // 总学习时长(分钟)
  averageAccuracy: number;      // 平均正确率
  subjectStats: Map<string, SubjectStat>; // 各学科统计
}

/**
 * 每日记录接口
 */
export interface DailyRecord {
  date: string;           // 日期,格式 YYYY-MM-DD
  studyTime: number;      // 学习时长(分钟)
  questionsAnswered: number; // 答题数量
  correctCount: number;   // 正确数量
}

/**
 * 答题结果接口
 */
export interface QuestionResult {
  questionId: string;        // 题目 ID
  userAnswer: string | string[]; // 用户答案
  isCorrect: boolean;        // 是否正确
  timeUsed: number;          // 答题用时(秒)
  usedTools: string[];       // 使用的工具列表
}

/**
 * 测验记录接口
 */
export interface QuizRecord {
  id: string;                     // 记录 ID
  userId: string;                 // 用户 ID
  levelId: string;                // 关卡 ID
  startTime: string;              // 开始时间
  endTime: string;                // 结束时间
  totalQuestions: number;         // 总题数
  correctQuestions: number;       // 正确数
  accuracy: number;               // 正确率
  score: number;                  // 得分
  experience: number;             // 获得经验
  stars: number;                  // 获得星级(1-3)
  timeUsed: number;               // 用时(秒)
  questionResults: QuestionResult[]; // 每题结果
  subjectId?: string;             // 学科 ID(可选)
  difficulty?: string;            // 难度等级(可选)
  timestamp?: string;             // 时间戳(可选)
}

/**
 * 用户接口
 */
export interface User {
  id: string;                    // 用户唯一标识
  nickname: string;              // 用户昵称
  avatar: string;                // 头像 URL
  level: number;                 // 用户等级
  totalScore: number;            // 总积分
  totalExperience: number;       // 总经验值
  rank: number;                  // 排行榜排名
  consecutiveDays: number;       // 连续登录天数
  lastLoginDate: string;         // 最后登录日期
  createdAt: string;             // 创建时间
  settings: UserSettings;        // 用户设置
  statistics: UserStatistics;    // 学习统计
  unlockedLevels: string[];      // 已解锁关卡 ID 列表
  completedLevels: string[];     // 已完成关卡 ID 列表
  levelStars: Map<string, number>; // 各关卡星级 Map
  achievements: string[];        // 已获得成就 ID 列表
  wrongQuestions: string[];      // 错题 ID 列表
  favorites: string[];           // 收藏题目 ID 列表
  tools: UserTools;              // 工具数量
  quizHistory: QuizRecord[];     // 测验记录列表
  dailyRecords: DailyRecord[];   // 每日学习记录
  ownedItems: string[];          // 拥有物品 ID 列表
}
代码解析

1. User 接口字段说明

字段名 类型 必填 说明
id string 用户唯一标识,UUID 格式
nickname string 用户显示名称
avatar string 头像图片 URL
level number 用户等级,从 1 开始
totalScore number 累计获得的积分
totalExperience number 累计获得的经验值
rank number 当前排行榜排名
consecutiveDays number 连续登录天数
lastLoginDate string 最后登录日期,格式 YYYY-MM-DD
createdAt string 用户创建时间,格式 YYYY-MM-DD
settings UserSettings 用户个性化设置
statistics UserStatistics 学习统计数据
unlockedLevels string[] 已解锁的关卡 ID 数组
completedLevels string[] 已完成的关卡 ID 数组
levelStars Map<string, number> 关卡星级映射
achievements string[] 已获得成就 ID 数组
wrongQuestions string[] 错题 ID 数组
favorites string[] 收藏题目 ID 数组
tools UserTools 工具道具数量
quizHistory QuizRecord[] 测验历史记录
dailyRecords DailyRecord[] 每日学习记录
ownedItems string[] 拥有的物品 ID 数组

2. 嵌套接口设计

// ✅ 正确:使用嵌套接口组织数据
export interface User {
  settings: UserSettings;      // 用户设置
  statistics: UserStatistics;  // 学习统计
  tools: UserTools;            // 工具道具
}

// ❌ 错误:将所有字段都放在主接口中
export interface User {
  soundEnabled: boolean;
  vibrationEnabled: boolean;
  questionTimer: number;
  showExplanation: boolean;
  ageGroup: AgeGroup;
  difficultyLock: boolean;
  // ... 其他字段
}

原理:

  • 使用嵌套接口将相关字段分组
  • 提高代码可读性和可维护性
  • 便于功能扩展和修改

注意事项:

  • 嵌套接口应该有明确的语义
  • 避免过度嵌套(不超过 3 层)
  • 保持接口的单一职责

步骤2: 创建用户实例

功能说明

创建一个完整的用户实例,包含所有必要的数据。

完整代码
// 创建用户实例示例
const user: User = {
  id: 'user_001',
  nickname: '知识小达人',
  avatar: 'https://example.com/avatar.png',
  level: 5,
  totalScore: 2580,
  totalExperience: 12500,
  rank: 128,
  consecutiveDays: 15,
  lastLoginDate: '2024-01-15',
  createdAt: '2024-01-01',
  settings: {
    soundEnabled: true,
    vibrationEnabled: false,
    questionTimer: 60,
    showExplanation: true,
    ageGroup: AgeGroup.TEENAGER,
    difficultyLock: false
  },
  statistics: {
    totalQuestions: 520,
    correctQuestions: 442,
    totalStudyTime: 1800,
    averageAccuracy: 0.85,
    subjectStats: new Map([
      ['math', { 
        subjectId: 'math', 
        totalQuestions: 150, 
        correctQuestions: 135, 
        accuracy: 0.9 
      }],
      ['history', { 
        subjectId: 'history', 
        totalQuestions: 120, 
        correctQuestions: 96, 
        accuracy: 0.8 
      }]
    ])
  },
  unlockedLevels: ['math_level_1', 'math_level_2', 'history_level_1'],
  completedLevels: ['math_level_1', 'history_level_1'],
  levelStars: new Map([
    ['math_level_1', 3],
    ['history_level_1', 2]
  ]),
  achievements: ['achievement_first_login', 'achievement_100_questions'],
  wrongQuestions: ['math_1001', 'history_2003'],
  favorites: ['math_1005', 'science_3001'],
  tools: {
    removeError: 5,
    extendTime: 3,
    hint: 10,
    skip: 2
  },
  quizHistory: [],
  dailyRecords: [],
  ownedItems: ['item_avatar_001']
};
代码解析

1. UserSettings 接口

settings: {
  soundEnabled: true,           // 音效开关
  vibrationEnabled: false,      // 震动开关
  questionTimer: 60,            // 答题计时器(秒)
  showExplanation: true,        // 是否显示解析
  ageGroup: AgeGroup.TEENAGER,  // 年龄组
  difficultyLock: false         // 难度锁定
}

原理:

  • soundEnabled: 控制音效播放
  • vibrationEnabled: 控制震动反馈
  • questionTimer: 每道题的答题时间限制
  • showExplanation: 答题后是否显示解析
  • ageGroup: 根据年龄推荐适合的内容
  • difficultyLock: 是否锁定难度等级

示例:

// ✅ 正确:使用枚举值
ageGroup: AgeGroup.TEENAGER

// ❌ 错误:使用字符串
ageGroup: '青少年' as AgeGroup

2. UserStatistics 接口

statistics: {
  totalQuestions: 520,      // 总答题数
  correctQuestions: 442,    // 正确答题数
  totalStudyTime: 1800,     // 总学习时长(分钟)
  averageAccuracy: 0.85,    // 平均正确率
  subjectStats: new Map([   // 各学科统计
    ['math', { 
      subjectId: 'math', 
      totalQuestions: 150, 
      correctQuestions: 135, 
      accuracy: 0.9 
    }]
  ])
}

原理:

  • averageAccuracy 应该等于 correctQuestions / totalQuestions
  • subjectStats 使用 Map 存储各学科的统计数据
  • 每个学科的 accuracy 应该等于该学科的 correctQuestions / totalQuestions

注意事项:

  • averageAccuracy 范围:0-1
  • subjectStats 的键是学科 ID
  • 保持统计数据的一致性

3. levelStars Map 设计

levelStars: new Map([
  ['math_level_1', 3],    // 数学入门级:3星
  ['history_level_1', 2]  // 历史入门级:2星
])

原理:

  • 使用 Map 存储关卡星级
  • 键:关卡 ID
  • 值:星级(1-3)

示例:

// ✅ 正确:使用 Map
levelStars: new Map([
  ['math_level_1', 3]
])

// ❌ 错误:使用对象
levelStars: {
  'math_level_1': 3
}

// 获取星级
const stars = user.levelStars.get('math_level_1');  // 3

// 设置星级
user.levelStars.set('math_level_2', 2);

步骤3: 创建测验记录

功能说明

创建一个完整的测验记录,记录用户在一次测验中的表现。

完整代码
// 创建测验记录示例
const quizRecord: QuizRecord = {
  id: 'quiz_001',
  userId: 'user_001',
  levelId: 'math_level_2',
  startTime: '2024-01-15 10:00:00',
  endTime: '2024-01-15 10:05:30',
  totalQuestions: 10,
  correctQuestions: 8,
  accuracy: 0.8,
  score: 80,
  experience: 200,
  stars: 2,
  timeUsed: 330,
  questionResults: [
    { 
      questionId: 'math_1001', 
      userAnswer: 'B', 
      isCorrect: true, 
      timeUsed: 25, 
      usedTools: [] 
    },
    { 
      questionId: 'math_1002', 
      userAnswer: 'A', 
      isCorrect: false, 
      timeUsed: 30, 
      usedTools: ['hint'] 
    }
  ],
  subjectId: 'math',
  difficulty: '2',
  timestamp: '2024-01-15T10:05:30Z'
};
代码解析

1. QuizRecord 接口字段说明

字段名 类型 必填 说明
id string 记录唯一标识
userId string 用户 ID
levelId string 关卡 ID
startTime string 开始时间
endTime string 结束时间
totalQuestions number 总题数
correctQuestions number 正确数
accuracy number 正确率
score number 得分
experience number 获得经验
stars number 获得星级(1-3)
timeUsed number 用时(秒)
questionResults QuestionResult[] 每题结果
subjectId string 学科 ID(可选)
difficulty string 难度等级(可选)
timestamp string 时间戳(可选)

2. QuestionResult 接口

questionResults: [
  { 
    questionId: 'math_1001',   // 题目 ID
    userAnswer: 'B',           // 用户答案
    isCorrect: true,           // 是否正确
    timeUsed: 25,              // 答题用时(秒)
    usedTools: []              // 使用的工具列表
  }
]

原理:

  • questionId: 题目的唯一标识
  • userAnswer: 用户的答案
  • isCorrect: 答案是否正确
  • timeUsed: 答题用时
  • usedTools: 使用的工具列表(如 ['hint']

注意事项:

  • usedTools 可以包含多个工具
  • timeUsed 单位为秒
  • userAnswer 格式与题目类型相关

3. 星级计算逻辑

// 星级计算示例
function calculateStars(accuracy: number): number {
  if (accuracy >= 0.9) {
    return 3;  // 90% 以上:3星
  } else if (accuracy >= 0.7) {
    return 2;  // 70%-90%:2星
  } else {
    return 1;  // 70% 以下:1星
  }
}

原理:

  • 3 星:正确率 ≥ 90%
  • 2 星:正确率 ≥ 70%
  • 1 星:正确率 < 70%

示例:

calculateStars(0.95);  // 3
calculateStars(0.8);   // 2
calculateStars(0.6);   // 1

步骤4: 实现数据校验

功能说明

为了确保用户数据的完整性和正确性,需要实现数据校验逻辑。

完整代码
// utils/UserValidator.ts

import { User, UserStatistics, AgeGroup } from '../models/User';

/**
 * 用户数据校验类
 */
export class UserValidator {
  /**
   * 校验用户数据
   * @param user 待校验的用户
   * @returns 校验结果
   */
  static validate(user: User): { isValid: boolean; errors: string[] } {
    const errors: string[] = [];

    // 1. 检查必填字段
    if (!user.id) {
      errors.push('用户 ID 不能为空');
    }
    if (!user.nickname) {
      errors.push('用户昵称不能为空');
    }
    if (!user.avatar) {
      errors.push('用户头像不能为空');
    }

    // 2. 检查等级范围
    if (user.level < 1) {
      errors.push('用户等级必须大于等于 1');
    }

    // 3. 检查统计数据一致性
    if (user.statistics.totalQuestions > 0) {
      const calculatedAccuracy = user.statistics.correctQuestions / user.statistics.totalQuestions;
      if (Math.abs(calculatedAccuracy - user.statistics.averageAccuracy) > 0.01) {
        errors.push('平均正确率与统计数据不一致');
      }
    }

    // 4. 检查关卡星级范围
    for (const [levelId, stars] of user.levelStars) {
      if (stars < 1 || stars > 3) {
        errors.push(`关卡 ${levelId} 的星级必须在 1-3 之间`);
      }
    }

    // 5. 检查日期格式
    const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
    if (!dateRegex.test(user.lastLoginDate)) {
      errors.push('最后登录日期格式必须为 YYYY-MM-DD');
    }
    if (!dateRegex.test(user.createdAt)) {
      errors.push('创建时间格式必须为 YYYY-MM-DD');
    }

    // 6. 检查年龄组
    if (!Object.values(AgeGroup).includes(user.settings.ageGroup)) {
      errors.push('年龄组必须是有效的枚举值');
    }

    // 7. 检查工具数量
    if (user.tools.removeError < 0) {
      errors.push('消除错误次数不能为负数');
    }
    if (user.tools.extendTime < 0) {
      errors.push('延长时间次数不能为负数');
    }
    if (user.tools.hint < 0) {
      errors.push('提示次数不能为负数');
    }
    if (user.tools.skip < 0) {
      errors.push('跳过次数不能为负数');
    }

    return {
      isValid: errors.length === 0,
      errors
    };
  }

  /**
   * 校验测验记录
   * @param record 待校验的测验记录
   * @returns 校验结果
   */
  static validateQuizRecord(record: QuizRecord): { isValid: boolean; errors: string[] } {
    const errors: string[] = [];

    // 1. 检查必填字段
    if (!record.id) {
      errors.push('记录 ID 不能为空');
    }
    if (!record.userId) {
      errors.push('用户 ID 不能为空');
    }
    if (!record.levelId) {
      errors.push('关卡 ID 不能为空');
    }

    // 2. 检查数值范围
    if (record.totalQuestions <= 0) {
      errors.push('总题数必须大于 0');
    }
    if (record.correctQuestions < 0 || record.correctQuestions > record.totalQuestions) {
      errors.push('正确题数必须在 0 到总题数之间');
    }
    if (record.accuracy < 0 || record.accuracy > 1) {
      errors.push('正确率必须在 0 到 1 之间');
    }
    if (record.stars < 1 || record.stars > 3) {
      errors.push('星级必须在 1 到 3 之间');
    }

    // 3. 检查统计数据一致性
    const calculatedAccuracy = record.correctQuestions / record.totalQuestions;
    if (Math.abs(calculatedAccuracy - record.accuracy) > 0.01) {
      errors.push('正确率与统计数据不一致');
    }

    return {
      isValid: errors.length === 0,
      errors
    };
  }
}
代码解析

1. 必填字段检查

if (!user.id) {
  errors.push('用户 ID 不能为空');
}

原理:

  • 检查所有必填字段是否有值
  • 空字符串、nullundefined 都会被判定为无效
  • 收集所有错误信息,一次性返回

示例:

// ✅ 正确:所有必填字段都有值
const user: User = {
  id: 'user_001',
  nickname: '知识小达人',
  avatar: 'https://example.com/avatar.png',
  // ...
};

// ❌ 错误:缺少必填字段
const user: User = {
  id: 'user_001',
  // 缺少 nickname
  avatar: 'https://example.com/avatar.png',
  // ...
};

2. 统计数据一致性检查

if (user.statistics.totalQuestions > 0) {
  const calculatedAccuracy = user.statistics.correctQuestions / user.statistics.totalQuestions;
  if (Math.abs(calculatedAccuracy - user.statistics.averageAccuracy) > 0.01) {
    errors.push('平均正确率与统计数据不一致');
  }
}

原理:

  • 计算实际正确率:correctQuestions / totalQuestions
  • 与存储的 averageAccuracy 比较
  • 允许 0.01 的误差(浮点数精度问题)

示例:

// ✅ 正确:统计数据一致
statistics: {
  totalQuestions: 100,
  correctQuestions: 85,
  averageAccuracy: 0.85  // 85/100 = 0.85
}

// ❌ 错误:统计数据不一致
statistics: {
  totalQuestions: 100,
  correctQuestions: 85,
  averageAccuracy: 0.9  // 85/100 = 0.85 ≠ 0.9
}

3. 关卡星级范围检查

for (const [levelId, stars] of user.levelStars) {
  if (stars < 1 || stars > 3) {
    errors.push(`关卡 ${levelId} 的星级必须在 1-3 之间`);
  }
}

原理:

  • 遍历 levelStars Map
  • 检查每个关卡的星级是否在 1-3 之间

示例:

// ✅ 正确:星级在 1-3 之间
levelStars: new Map([
  ['math_level_1', 3],
  ['history_level_1', 2]
])

// ❌ 错误:星级超出范围
levelStars: new Map([
  ['math_level_1', 4],  // 错误:最大值为 3
  ['history_level_1', 0]  // 错误:最小值为 1
])

4. 年龄组校验

if (!Object.values(AgeGroup).includes(user.settings.ageGroup)) {
  errors.push('年龄组必须是有效的枚举值');
}

原理:

  • 检查 ageGroup 是否是 AgeGroup 枚举的有效值
  • 防止使用无效的年龄组

示例:

// ✅ 正确:使用枚举值
ageGroup: AgeGroup.TEENAGER

// ❌ 错误:使用无效值
ageGroup: '中年' as AgeGroup

⚠️ 常见问题与解决方案

问题1: averageAccuracy 与统计数据不一致

现象:
用户的 averageAccuracycorrectQuestions / totalQuestions 的计算结果不一致。

错误代码:

// ❌ 错误:统计数据不一致
const user: User = {
  statistics: {
    totalQuestions: 100,
    correctQuestions: 85,
    averageAccuracy: 0.9  // 错误:应该是 0.85
  }
};

正确代码:

// ✅ 正确:统计数据一致
const user: User = {
  statistics: {
    totalQuestions: 100,
    correctQuestions: 85,
    averageAccuracy: 0.85  // 正确:85/100 = 0.85
  }
};

规则/建议:

  • averageAccuracy 应该等于 correctQuestions / totalQuestions
  • 使用 UserValidator.validate() 进行校验
  • 更新统计数据时同步更新 averageAccuracy

问题2: levelStars 使用对象而不是 Map

现象:
使用普通对象存储关卡星级,导致类型错误。

错误代码:

// ❌ 错误:使用对象
const user: User = {
  levelStars: {
    'math_level_1': 3,
    'history_level_1': 2
  } as any  // 强制类型转换
};

正确代码:

// ✅ 正确:使用 Map
const user: User = {
  levelStars: new Map([
    ['math_level_1', 3],
    ['history_level_1', 2]
  ])
};

规则/建议:

  • levelStars 必须使用 Map<string, number> 类型
  • 使用 Mapget()set() 方法操作
  • 避免使用类型强制转换

问题3: 工具数量为负数

现象:
用户的工具数量为负数,导致逻辑错误。

错误代码:

// ❌ 错误:工具数量为负数
const user: User = {
  tools: {
    removeError: -1,  // 错误:不能为负数
    extendTime: 3,
    hint: 10,
    skip: 2
  }
};

正确代码:

// ✅ 正确:工具数量为非负数
const user: User = {
  tools: {
    removeError: 0,  // 正确:可以为 0
    extendTime: 3,
    hint: 10,
    skip: 2
  }
};

规则/建议:

  • 所有工具数量必须 ≥ 0
  • 使用工具时先检查数量
  • 数量不足时提示用户

问题4: 日期格式不正确

现象:
日期字段使用不标准的格式,导致解析错误。

错误代码:

// ❌ 错误:日期格式不标准
const user: User = {
  lastLoginDate: '2024/01/15',  // 使用斜杠
  createdAt: '2024-1-1'  // 月份和日期没有补零
};

正确代码:

// ✅ 正确:使用标准格式 YYYY-MM-DD
const user: User = {
  lastLoginDate: '2024-01-15',  // 标准格式
  createdAt: '2024-01-01'  // 标准格式
};

规则/建议:

  • 日期格式:YYYY-MM-DD
  • 月份和日期必须补零
  • 使用正则表达式校验:/^\d{4}-\d{2}-\d{2}$/

问题5: 测验记录的星级计算错误

现象:
测验记录的星级与正确率不匹配。

错误代码:

// ❌ 错误:星级与正确率不匹配
const quizRecord: QuizRecord = {
  accuracy: 0.8,  // 正确率 80%
  stars: 3  // 错误:应该是 2 星
};

正确代码:

// ✅ 正确:星级与正确率匹配
const quizRecord: QuizRecord = {
  accuracy: 0.8,  // 正确率 80%
  stars: 2  // 正确:2 星
};

规则/建议:

  • 3 星:正确率 ≥ 90%
  • 2 星:正确率 ≥ 70%
  • 1 星:正确率 < 70%
  • 使用统一的星级计算函数

📝 本章小结

核心知识点

本文详细讲解了 User 模型的设计与实现,主要包括:

1. User 接口设计

  • 包含 24 个字段,覆盖用户的所有信息
  • 使用嵌套接口组织复杂数据结构
  • 支持可选字段(subjectIddifficultytimestamp

2. 嵌套接口设计

  • UserSettings: 用户个性化设置
  • UserStatistics: 学习统计数据
  • UserTools: 工具道具数量
  • QuizRecord: 测验记录
  • QuestionResult: 答题结果

3. 数据校验

  • 必填字段检查
  • 统计数据一致性检查
  • 数值范围检查
  • 日期格式检查

最佳实践总结

使用 Map 存储关卡星级

levelStars: new Map([
  ['math_level_1', 3]
])

统计数据一致性

averageAccuracy: correctQuestions / totalQuestions

星级计算规则

function calculateStars(accuracy: number): number {
  if (accuracy >= 0.9) return 3;
  if (accuracy >= 0.7) return 2;
  return 1;
}

数据校验

const result = UserValidator.validate(user);
if (!result.isValid) {
  console.error(result.errors);
}

下一步预告

在下一篇文章中,我们将:

  • 🎨 讲解 Level 模型设计与关卡系统
  • 📚 介绍关卡解锁和完成机制
  • 🏷️ 探索关卡难度和知识点管理

🔗 相关链接


💡 提示: 建议结合项目源码阅读,动手实践效果更好!

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐