HarmonyOS智慧农业管理应用开发教程--高高种地-- 第24篇:学习中心 - 课程体系设计

第24篇:学习中心 - 课程体系设计

📚 本篇导读

学习中心是农业应用的重要功能模块,为用户提供系统化的农业知识学习平台。本篇教程将实现一个完整的课程体系,包括课程分类、课程列表、搜索功能等,帮助用户从新手到专家逐步提升种植技能。

本篇将实现

  • 📖 课程分类体系(入门、进阶、专业)
  • 📚 课程列表展示(卡片式布局)
  • 🔍 课程搜索功能(关键词搜索)
  • 📊 学习统计展示(总数、完成数、进行中)
  • 🎨 双模式适配(家庭园艺/专业农业)

🎯 学习目标

完成本篇教程后,你将掌握:

  1. 如何设计课程数据模型
  2. 如何实现课程分类和筛选
  3. 如何展示课程列表
  4. 如何实现搜索功能
  5. 学习进度的管理方式

一、课程体系架构

1.1 课程分类设计

复制代码
学习中心
├── 家庭园艺模式
│   ├── 入门基础(新手必学)
│   │   ├── 家庭园艺入门指南
│   │   ├── 认识土壤与培养土
│   │   └── 浇水与施肥基础
│   │
│   ├── 日常养护(日常管理)
│   │   ├── 四季养护要点
│   │   ├── 修剪与造型技巧
│   │   └── 繁殖与扦插方法
│   │
│   ├── 病虫防治(问题解决)
│   │   ├── 常见病虫害识别
│   │   ├── 生态防治方法
│   │   └── 药剂使用指南
│   │
│   └── 进阶技巧(高级技能)
│       ├── 阳台菜园打造
│       ├── 多肉组合盆栽
│       └── 水培与无土栽培
│
└── 专业农业模式
    ├── 作物种植(核心技术)
    │   ├── 小麦种植技术
    │   ├── 水稻栽培管理
    │   └── 蔬菜大棚技术
    │
    ├── 植保技术(病虫害防治)
    │   ├── 病虫害综合防治
    │   ├── 农药安全使用
    │   └── 生物防治技术
    │
    ├── 农机操作(机械化)
    │   ├── 拖拉机操作规范
    │   ├── 收割机使用技巧
    │   └── 农机维护保养
    │
    └── 市场营销(经营管理)
        ├── 农产品销售渠道
        ├── 品牌建设与推广
        └── 电商运营实战

1.2 课程难度分级

难度等级 适用人群 特点
入门级 零基础新手 基础概念、简单操作、图文并茂
进阶级 有一定经验 深入技巧、实战案例、问题解决
专业级 专业从业者 系统理论、高级技术、行业标准

1.3 课程内容结构

复制代码
课程
├── 基本信息
│   ├── 课程ID
│   ├── 课程标题
│   ├── 课程分类
│   ├── 难度等级
│   ├── 课程时长
│   └── 课程封面
│
├── 详细信息
│   ├── 课程描述
│   ├── 讲师信息
│   ├── 课程标签
│   └── 适用模式
│
├── 课程内容
│   ├── 课时列表
│   │   ├── 课时标题
│   │   ├── 课时时长
│   │   ├── 课时内容
│   │   └── 完成状态
│   └── 课程资料
│
└── 学习数据
    ├── 学习进度
    ├── 完成状态
    ├── 报名时间
    └── 完成时间

二、数据模型设计

2.1 课程数据模型

文件位置entry/src/main/ets/models/KnowledgeModels.ets

typescript 复制代码
/**
 * 课程难度枚举
 */
export enum CourseDifficulty {
  BEGINNER = 'beginner',    // 入门
  INTERMEDIATE = 'intermediate',  // 进阶
  ADVANCED = 'advanced'     // 专业
}

/**
 * 课程基本信息
 */
export interface Course {
  id: string;               // 课程ID
  title: string;            // 课程标题
  category: string;         // 课程分类
  duration: string;         // 课程时长
  difficulty: CourseDifficulty;  // 难度等级
  cover: string;            // 封面图标
  progress: number;         // 学习进度 0-100
  isCompleted: boolean;     // 是否完成
  mode: AppMode;            // 适用模式
}

/**
 * 课程详细信息
 */
export interface CourseDetail extends Course {
  description: string;      // 课程描述
  instructor: string;       // 讲师姓名
  tags: string[];          // 课程标签
  lessons: CourseLesson[]; // 课时列表
}

/**
 * 课时信息
 */
export interface CourseLesson {
  id: string;              // 课时ID
  title: string;           // 课时标题
  duration: string;        // 课时时长
  content: string;         // 课时内容
  isCompleted: boolean;    // 是否完成
  isCurrent: boolean;      // 是否当前学习
}

/**
 * 学习统计
 */
export interface CourseStats {
  total: number;           // 总课程数
  completed: number;       // 已完成数
  inProgress: number;      // 学习中数
}

模型说明

  • Course:课程基本信息,用于列表展示
  • CourseDetail:课程详细信息,包含课时列表
  • CourseLesson:课时信息,课程的最小学习单元
  • CourseStats:学习统计数据

2.2 课程进度数据

typescript 复制代码
/**
 * 课程进度数据结构
 */
interface CourseProgress {
  courseId: string;              // 课程ID
  progress: number;              // 进度百分比 0-100
  isCompleted: boolean;          // 是否完成
  completedDate?: number;        // 完成时间
  enrolledDate?: number;         // 报名时间
  completedLessons: string[];    // 已完成的课时ID列表
  currentLessonId?: string;      // 当前正在学习的课时ID
}

三、KnowledgeService 课程服务

3.1 服务类设计

文件位置entry/src/main/ets/services/KnowledgeService.ets

typescript 复制代码
import { AppMode } from '../models/CommonModels';
import { Course, CourseDetail, CourseDifficulty, CourseLesson, CourseStats } from '../models/KnowledgeModels';
import { StorageUtil } from '../utils/StorageUtil';

class KnowledgeService {
  // 课程数据存储
  private courses: CourseDetail[] = [];
  // 进度是否已加载
  private isProgressLoaded: boolean = false;

  constructor() {
    // 初始化静态课程内容
    this.initStaticContent();
    // 加载学习进度
    this.loadProgress();
  }

  /**
   * 初始化静态课程内容
   */
  private initStaticContent() {
    // 家庭园艺课程
    this.courses.push({
      id: 'hg_1',
      title: '家庭园艺入门指南(上)------新手上路',
      category: '入门基础',
      duration: '45分钟',
      difficulty: CourseDifficulty.BEGINNER,
      cover: '🌱',
      progress: 0,
      isCompleted: false,
      mode: AppMode.HOME_GARDENING,
      description: '本课程将带你了解家庭园艺的基础知识,从环境评估到工具准备,帮助新手避开常见的坑,轻松开启种植之旅。',
      instructor: '林园艺',
      tags: ['新手', '基础', '工具', '环境'],
      lessons: [
        {
          id: 'l_1_1',
          title: '什么是家庭园艺?',
          duration: '5分钟',
          isCompleted: false,
          isCurrent: true,
          content: '家庭园艺是指在室内、阳台、屋顶或庭院等家庭空间内,进行植物栽培和装饰的活动...'
        },
        {
          id: 'l_1_2',
          title: '评估你的种植环境(光照、通风)',
          duration: '10分钟',
          isCompleted: false,
          isCurrent: false,
          content: '并不是所有植物都适合你的家。在买花之前,最重要的第一步是评估环境...'
        }
        // ... 更多课时
      ]
    });

    // 专业农业课程
    this.courses.push({
      id: 'pa_1',
      title: '小麦种植技术全流程',
      category: '作物种植',
      duration: '90分钟',
      difficulty: CourseDifficulty.INTERMEDIATE,
      cover: '🌾',
      progress: 0,
      isCompleted: false,
      mode: AppMode.PROFESSIONAL_AGRICULTURE,
      description: '系统讲解小麦从播种到收获的全流程技术要点,包括品种选择、田间管理、病虫害防治等。',
      instructor: '张农技',
      tags: ['小麦', '粮食作物', '田间管理'],
      lessons: [
        {
          id: 'l_pa_1_1',
          title: '小麦品种选择与种子处理',
          duration: '15分钟',
          isCompleted: false,
          isCurrent: true,
          content: '选择适合当地气候的小麦品种是成功的第一步...'
        }
        // ... 更多课时
      ]
    });
  }

  /**
   * 获取课程列表
   */
  public getCourses(mode: AppMode): Course[] {
    return this.courses
      .filter(course => course.mode === mode)
      .map(course => ({
        id: course.id,
        title: course.title,
        category: course.category,
        duration: course.duration,
        difficulty: course.difficulty,
        cover: course.cover,
        progress: course.progress,
        isCompleted: course.isCompleted,
        mode: course.mode
      }));
  }

  /**
   * 根据ID获取课程详情
   */
  public getCourseById(courseId: string): CourseDetail | null {
    return this.courses.find(c => c.id === courseId) || null;
  }

  /**
   * 搜索课程
   */
  public searchCourses(keyword: string, mode: AppMode): Course[] {
    const lowerKeyword = keyword.toLowerCase();
    return this.courses
      .filter(course =>
        course.mode === mode &&
        (course.title.toLowerCase().includes(lowerKeyword) ||
         course.description.toLowerCase().includes(lowerKeyword) ||
         course.tags?.some(tag => tag.toLowerCase().includes(lowerKeyword)))
      )
      .map(course => ({
        id: course.id,
        title: course.title,
        category: course.category,
        duration: course.duration,
        difficulty: course.difficulty,
        cover: course.cover,
        progress: course.progress,
        isCompleted: course.isCompleted,
        mode: course.mode
      }));
  }

  /**
   * 获取课程统计
   */
  public getCourseStats(mode: AppMode): CourseStats {
    const modeCourses = this.courses.filter(c => c.mode === mode);
    return {
      total: modeCourses.length,
      completed: modeCourses.filter(c => c.isCompleted).length,
      inProgress: modeCourses.filter(c => c.progress > 0 && !c.isCompleted).length
    };
  }

  /**
   * 加载学习进度
   */
  private async loadProgress(): Promise<void> {
    if (this.isProgressLoaded) return;

    try {
      const progressData = await StorageUtil.getObject<CourseProgress[]>('course_progress', []);

      // 将进度数据应用到课程
      progressData.forEach(progress => {
        const course = this.courses.find(c => c.id === progress.courseId);
        if (course) {
          course.progress = progress.progress;
          course.isCompleted = progress.isCompleted;
          course.enrolledDate = progress.enrolledDate;
          course.completedDate = progress.completedDate;

          // 更新课时完成状态
          course.lessons.forEach(lesson => {
            lesson.isCompleted = progress.completedLessons.includes(lesson.id);
            lesson.isCurrent = lesson.id === progress.currentLessonId;
          });
        }
      });

      this.isProgressLoaded = true;
      console.info('[KnowledgeService] Progress loaded successfully');
    } catch (error) {
      console.error('[KnowledgeService] Failed to load progress:', error);
    }
  }

  /**
   * 保存学习进度
   */
  public async saveProgress(courseId: string, progress: CourseProgress): Promise<void> {
    try {
      const progressData = await StorageUtil.getObject<CourseProgress[]>('course_progress', []);

      // 更新或添加进度
      const index = progressData.findIndex(p => p.courseId === courseId);
      if (index >= 0) {
        progressData[index] = progress;
      } else {
        progressData.push(progress);
      }

      await StorageUtil.saveObject('course_progress', progressData);

      // 同步更新内存中的课程数据
      const course = this.courses.find(c => c.id === courseId);
      if (course) {
        course.progress = progress.progress;
        course.isCompleted = progress.isCompleted;
      }

      console.info('[KnowledgeService] Progress saved for course:', courseId);
    } catch (error) {
      console.error('[KnowledgeService] Failed to save progress:', error);
    }
  }
}

// 导出单例
export const knowledgeService = new KnowledgeService();

服务功能说明

  1. 课程管理:初始化、获取、搜索课程
  2. 进度管理:加载、保存学习进度
  3. 统计功能:计算学习统计数据
  4. 数据持久化:使用 StorageUtil 存储进度

四、学习中心页面实现

4.1 页面结构设计

文件位置entry/src/main/ets/pages/Learning/LearningCenterPage.ets

typescript 复制代码
import { router } from '@kit.ArkUI';
import { StorageUtil } from '../../utils/StorageUtil';
import { AppMode } from '../../models/CommonModels';
import { Course, CourseStats } from '../../models/KnowledgeModels';
import { knowledgeService } from '../../services/KnowledgeService';

@Entry
@ComponentV2
export struct LearningCenterPage {
  @Local userMode: AppMode = AppMode.HOME_GARDENING;
  @Local selectedCategory: string = '全部';
  @Local courses: Course[] = [];
  @Local searchKeyword: string = '';
  @Local isSearching: boolean = false;
  @Local courseStats: CourseStats = { total: 0, completed: 0, inProgress: 0 };

  async aboutToAppear(): Promise<void> {
    // 获取用户模式
    const mode = await StorageUtil.getString('user_mode', AppMode.HOME_GARDENING);
    this.userMode = mode as AppMode;
    this.loadCourses();
  }

  onPageShow(): void {
    // 页面显示时重新加载课程(刷新进度)
    this.loadCourses();
  }

  build() {
    Column() {
      this.buildHeader()
      if (!this.isSearching) {
        this.buildBanner()
        this.buildCategoryTabs()
      }
      this.buildCourseList()
    }
    .width('100%')
    .height('100%')
    .backgroundColor($r('app.color.background'))
  }
}

4.2 顶部导航栏

typescript 复制代码
@Builder
buildHeader() {
  Row() {
    if (this.isSearching) {
      // 搜索模式
      Search({ value: this.searchKeyword, placeholder: '搜索课程、知识点...' })
        .layoutWeight(1)
        .searchButton('搜索')
        .onSubmit((value: string) => {
          this.searchKeyword = value;
          this.performSearch();
        })
        .onChange((value: string) => {
          this.searchKeyword = value;
          if (value === '') {
            this.performSearch();
          }
        })
        .margin({ right: 8 })

      Text('取消')
        .fontColor(this.userMode === AppMode.HOME_GARDENING ?
          $r('app.color.primary_home_gardening') : $r('app.color.primary_professional'))
        .onClick(() => {
          this.isSearching = false;
          this.searchKeyword = '';
          this.loadCourses();
        })
    } else {
      // 正常模式
      Text('     ')
        .width(60)

      Text('学习中心')
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
        .layoutWeight(1)
        .textAlign(TextAlign.Center)

      Button({ type: ButtonType.Circle }) {
        Text('🔍')
          .fontSize(20)
      }
      .backgroundColor(Color.Transparent)
      .width(40)
      .height(40)
      .onClick(() => {
        this.isSearching = true;
      })
    }
  }
  .width('100%')
  .height(56)
  .padding({ left: 16, right: 16 })
  .alignItems(VerticalAlign.Center)
}

功能说明

  • 正常模式:显示标题和搜索按钮
  • 搜索模式:显示搜索框和取消按钮
  • 支持实时搜索和搜索提交
typescript 复制代码
@Builder
buildBanner() {
  Column() {
    Text(this.userMode === AppMode.HOME_GARDENING ? '🌱 家庭种植课程' : '🌾 专业农业培训')
      .fontSize(20)
      .fontWeight(FontWeight.Bold)
      .fontColor(Color.White)

    Text(this.userMode === AppMode.HOME_GARDENING ?
      '从新手到专家,一步步学习' : '提升专业技能,科学高效种植')
      .fontSize(14)
      .fontColor(Color.White)
      .opacity(0.9)
      .margin({ top: 8 })

    // 学习统计
    Row({ space: 24 }) {
      Column({ space: 4 }) {
        Text(`${this.courseStats.total}`)
          .fontSize(24)
          .fontWeight(FontWeight.Bold)
          .fontColor(Color.White)
        Text('总课程')
          .fontSize(12)
          .fontColor(Color.White)
          .opacity(0.8)
      }

      Column({ space: 4 }) {
        Text(`${this.courseStats.completed}`)
          .fontSize(24)
          .fontWeight(FontWeight.Bold)
          .fontColor(Color.White)
        Text('已完成')
          .fontSize(12)
          .fontColor(Color.White)
          .opacity(0.8)
      }

      Column({ space: 4 }) {
        Text(`${this.courseStats.inProgress}`)
          .fontSize(24)
          .fontWeight(FontWeight.Bold)
          .fontColor(Color.White)
        Text('学习中')
          .fontSize(12)
          .fontColor(Color.White)
          .opacity(0.8)
      }
    }
    .margin({ top: 16 })
  }
  .width('100%')
  .padding(20)
  .linearGradient({
    angle: 135,
    colors: this.userMode === AppMode.HOME_GARDENING ?
      [[0x52C41A, 0.0], [0x389E0D, 1.0]] :
      [[0x1890FF, 0.0], [0x096DD9, 1.0]]
  })
  .borderRadius(12)
  .margin({ left: 16, right: 16, top: 16, bottom: 16 })
}

Banner 功能

  • 显示模式标题和描述
  • 展示学习统计数据
  • 使用渐变背景区分模式

4.4 分类标签

typescript 复制代码
@Builder
buildCategoryTabs() {
  Scroll() {
    Row({ space: 8 }) {
      this.buildCategoryTab('全部')
      if (this.userMode === AppMode.HOME_GARDENING) {
        this.buildCategoryTab('入门基础')
        this.buildCategoryTab('日常养护')
        this.buildCategoryTab('病虫防治')
        this.buildCategoryTab('进阶技巧')
      } else {
        this.buildCategoryTab('作物种植')
        this.buildCategoryTab('植保技术')
        this.buildCategoryTab('农机操作')
        this.buildCategoryTab('市场营销')
      }
    }
    .padding({ left: 16, right: 16 })
  }
  .scrollable(ScrollDirection.Horizontal)
  .scrollBar(BarState.Off)
  .height(48)
}

@Builder
buildCategoryTab(category: string) {
  Text(category)
    .fontSize(14)
    .fontColor(this.selectedCategory === category ?
      Color.White : $r('app.color.text_primary'))
    .padding({ left: 16, right: 16, top: 8, bottom: 8 })
    .backgroundColor(this.selectedCategory === category ?
      (this.userMode === AppMode.HOME_GARDENING ?
        $r('app.color.primary_home_gardening') : $r('app.color.primary_professional')) :
      $r('app.color.card_background'))
    .borderRadius(16)
    .onClick(() => {
      this.selectedCategory = category;
    })
}

分类功能

  • 横向滚动的分类标签
  • 选中状态高亮显示
  • 根据模式显示不同分类

4.5 课程列表

typescript 复制代码
@Builder
buildCourseList() {
  Scroll() {
    Column({ space: 12 }) {
      if (this.courses.length === 0) {
        this.buildEmptyState()
      } else {
        ForEach(this.getFilteredCourses(), (course: Course) => {
          this.buildCourseCard(course)
        })
      }
    }
    .padding(16)
  }
  .layoutWeight(1)
  .scrollBar(BarState.Auto)
}

@Builder
buildEmptyState() {
  Column() {
    Text('🍃')
      .fontSize(48)
      .margin({ bottom: 16 })
    Text('暂无相关课程')
      .fontSize(16)
      .fontColor($r('app.color.text_secondary'))
  }
  .width('100%')
  .height(300)
  .justifyContent(FlexAlign.Center)
}

4.6 课程卡片

typescript 复制代码
@Builder
buildCourseCard(course: Course) {
  Row() {
    // 课程封面
    Text(course.cover)
      .fontSize(48)
      .width(80)
      .height(80)
      .textAlign(TextAlign.Center)
      .backgroundColor($r('app.color.background'))
      .borderRadius(8)

    // 课程信息
    Column({ space: 6 }) {
      Text(course.title)
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
        .fontColor($r('app.color.text_primary'))
        .maxLines(2)
        .textOverflow({ overflow: TextOverflow.Ellipsis })

      Row({ space: 8 }) {
        Text(course.category)
          .fontSize(12)
          .fontColor($r('app.color.text_tertiary'))

        Text('·')
          .fontSize(12)
          .fontColor($r('app.color.text_tertiary'))

        Text(course.duration)
          .fontSize(12)
          .fontColor($r('app.color.text_tertiary'))

        Text('·')
          .fontSize(12)
          .fontColor($r('app.color.text_tertiary'))

        Text(course.difficulty)
          .fontSize(12)
          .fontColor(this.getDifficultyColor(course.difficulty))
      }

      // 学习进度
      if (course.progress > 0) {
        Row() {
          Progress({ value: course.progress, total: 100, type: ProgressType.Linear })
            .width(120)
            .height(4)
            .color(this.userMode === AppMode.HOME_GARDENING ?
              $r('app.color.primary_home_gardening') : $r('app.color.primary_professional'))

          Text(`${course.progress}%`)
            .fontSize(12)
            .fontColor($r('app.color.text_tertiary'))
            .margin({ left: 8 })
        }
      }

      // 完成标记
      if (course.isCompleted) {
        Row({ space: 4 }) {
          Text('✓')
            .fontSize(12)
            .fontColor('#52C41A')
          Text('已完成')
            .fontSize(12)
            .fontColor('#52C41A')
        }
      }
    }
    .layoutWeight(1)
    .margin({ left: 12 })
    .alignItems(HorizontalAlign.Start)
  }
  .width('100%')
  .padding(12)
  .backgroundColor($r('app.color.card_background'))
  .borderRadius(12)
  .shadow({ radius: 4, color: $r('app.color.shadow_light'), offsetY: 2 })
  .onClick(() => {
    router.pushUrl({
      url: 'pages/Learning/CourseDetailPage',
      params: { courseId: course.id }
    });
  })
}

/**
 * 获取难度颜色
 */
private getDifficultyColor(difficulty: string): string {
  const colors: Record<string, string> = {
    '入门': '#52C41A',
    '中级': '#FA8C16',
    '高级': '#F5222D',
    '专家': '#722ED1'
  };
  return colors[difficulty] || '#52C41A';
}

卡片功能

  • 显示课程封面、标题、分类、时长、难度
  • 显示学习进度条
  • 显示完成状态
  • 点击跳转到课程详情

五、数据加载与筛选

5.1 加载课程数据

typescript 复制代码
/**
 * 加载课程列表
 */
private loadCourses(): void {
  this.courses = knowledgeService.getCourses(this.userMode);
  this.courseStats = knowledgeService.getCourseStats(this.userMode);
  console.info('[LearningCenterPage] Courses loaded:', this.courses.length);
}

5.2 搜索功能

typescript 复制代码
/**
 * 执行搜索
 */
private performSearch(): void {
  if (this.searchKeyword.trim() === '') {
    this.loadCourses();
  } else {
    this.courses = knowledgeService.searchCourses(this.searchKeyword, this.userMode);
  }
}

5.3 分类筛选

typescript 复制代码
/**
 * 获取筛选后的课程
 */
private getFilteredCourses(): Course[] {
  if (this.isSearching) {
    return this.courses;
  }

  if (this.selectedCategory === '全部') {
    return this.courses;
  }

  return this.courses.filter(c => c.category === this.selectedCategory);
}

六、实操练习

练习1:添加课程收藏功能

任务:实现课程收藏功能,用户可以收藏感兴趣的课程

提示

  1. 在课程卡片上添加收藏按钮
  2. 使用 StorageUtil 存储收藏列表
  3. 添加"我的收藏"筛选项

参考代码

typescript 复制代码
/**
 * 切换收藏状态
 */
private async toggleFavorite(courseId: string): Promise<void> {
  const favorites = await StorageUtil.getObject<string[]>('favorite_courses', []);
  const index = favorites.indexOf(courseId);

  if (index > -1) {
    favorites.splice(index, 1);
    promptAction.showToast({ message: '已取消收藏' });
  } else {
    favorites.push(courseId);
    promptAction.showToast({ message: '已添加收藏' });
  }

  await StorageUtil.saveObject('favorite_courses', favorites);
}

练习2:添加课程排序功能

任务:支持按不同维度排序课程列表

提示

  1. 添加排序选择器(最新、最热、难度)
  2. 实现排序逻辑
  3. 保存用户排序偏好

参考代码

typescript 复制代码
/**
 * 排序课程
 */
private sortCourses(courses: Course[], sortBy: string): Course[] {
  switch (sortBy) {
    case '最新':
      return courses.sort((a, b) => b.id.localeCompare(a.id));
    case '最热':
      // 可以根据学习人数排序(需要添加字段)
      return courses;
    case '难度':
      const difficultyOrder = { '入门': 1, '中级': 2, '高级': 3, '专家': 4 };
      return courses.sort((a, b) =>
        difficultyOrder[a.difficulty] - difficultyOrder[b.difficulty]
      );
    default:
      return courses;
  }
}

练习3:添加学习提醒功能

任务:提醒用户继续未完成的课程

提示

  1. 检测有进度但未完成的课程
  2. 在页面顶部显示提醒卡片
  3. 点击直接跳转到课程

七、常见问题

问题1:课程进度不同步

原因

  • 进度数据未正确保存
  • 页面未刷新进度数据

解决方案

typescript 复制代码
// 在 onPageShow 中重新加载课程
onPageShow(): void {
  console.info('[LearningCenterPage] onPageShow - Reloading courses');
  this.loadCourses();
}

// 确保进度保存成功
public async saveProgress(courseId: string, progress: CourseProgress): Promise<void> {
  try {
    const progressData = await StorageUtil.getObject<CourseProgress[]>('course_progress', []);
    const index = progressData.findIndex(p => p.courseId === courseId);

    if (index >= 0) {
      progressData[index] = progress;
    } else {
      progressData.push(progress);
    }

    await StorageUtil.saveObject('course_progress', progressData);
    console.info('[KnowledgeService] Progress saved successfully');
  } catch (error) {
    console.error('[KnowledgeService] Failed to save progress:', error);
    throw error;
  }
}

问题2:搜索结果不准确

原因

  • 搜索关键词处理不当
  • 搜索范围不够全面

解决方案

typescript 复制代码
/**
 * 改进的搜索功能
 */
public searchCourses(keyword: string, mode: AppMode): Course[] {
  // 去除首尾空格并转小写
  const lowerKeyword = keyword.trim().toLowerCase();

  if (!lowerKeyword) {
    return this.getCourses(mode);
  }

  return this.courses
    .filter(course => {
      if (course.mode !== mode) return false;

      // 搜索标题
      if (course.title.toLowerCase().includes(lowerKeyword)) return true;

      // 搜索描述
      if (course.description.toLowerCase().includes(lowerKeyword)) return true;

      // 搜索标签
      if (course.tags?.some(tag => tag.toLowerCase().includes(lowerKeyword))) return true;

      // 搜索分类
      if (course.category.toLowerCase().includes(lowerKeyword)) return true;

      // 搜索讲师
      if (course.instructor.toLowerCase().includes(lowerKeyword)) return true;

      return false;
    })
    .map(course => ({
      id: course.id,
      title: course.title,
      category: course.category,
      duration: course.duration,
      difficulty: course.difficulty,
      cover: course.cover,
      progress: course.progress,
      isCompleted: course.isCompleted,
      mode: course.mode
    }));
}

问题3:课程数据加载慢

原因

  • 课程数据量大
  • 每次都重新加载

解决方案

typescript 复制代码
class KnowledgeService {
  private courses: CourseDetail[] = [];
  private isInitialized: boolean = false;
  private initPromise: Promise<void> | null = null;

  /**
   * 延迟初始化
   */
  private async ensureInitialized(): Promise<void> {
    if (this.isInitialized) return;

    if (this.initPromise) {
      return this.initPromise;
    }

    this.initPromise = (async () => {
      this.initStaticContent();
      await this.loadProgress();
      this.isInitialized = true;
      console.info('[KnowledgeService] Initialization completed');
    })();

    return this.initPromise;
  }

  /**
   * 获取课程列表(确保已初始化)
   */
  public async getCourses(mode: AppMode): Promise<Course[]> {
    await this.ensureInitialized();
    return this.courses
      .filter(course => course.mode === mode)
      .map(course => ({
        id: course.id,
        title: course.title,
        category: course.category,
        duration: course.duration,
        difficulty: course.difficulty,
        cover: course.cover,
        progress: course.progress,
        isCompleted: course.isCompleted,
        mode: course.mode
      }));
  }
}

八、功能扩展建议

1. 课程推荐系统

功能描述

  • 基于学习历史推荐相关课程
  • 推荐同类型热门课程
  • 推荐适合当前水平的课程

实现思路

typescript 复制代码
/**
 * 获取推荐课程
 */
public getRecommendedCourses(userId: string, mode: AppMode): Course[] {
  const userCourses = this.getUserCompletedCourses(userId);
  const recommendations: Course[] = [];

  // 1. 推荐同分类的课程
  userCourses.forEach(course => {
    const sameCategoryCourses = this.courses.filter(c =>
      c.mode === mode &&
      c.category === course.category &&
      c.id !== course.id &&
      !userCourses.some(uc => uc.id === c.id)
    );
    recommendations.push(...sameCategoryCourses);
  });

  // 2. 推荐进阶课程
  const userLevel = this.getUserLevel(userCourses);
  const nextLevelCourses = this.courses.filter(c =>
    c.mode === mode &&
    this.getDifficultyLevel(c.difficulty) === userLevel + 1
  );
  recommendations.push(...nextLevelCourses);

  // 去重并限制数量
  return Array.from(new Set(recommendations)).slice(0, 5);
}

2. 学习路径规划

功能描述

  • 为用户规划学习路径
  • 显示前置课程要求
  • 推荐学习顺序

实现思路

typescript 复制代码
/**
 * 学习路径接口
 */
interface LearningPath {
  id: string;
  name: string;
  description: string;
  courses: string[];  // 课程ID列表(按顺序)
  estimatedDuration: string;
}

/**
 * 获取学习路径
 */
public getLearningPaths(mode: AppMode): LearningPath[] {
  if (mode === AppMode.HOME_GARDENING) {
    return [
      {
        id: 'path_beginner',
        name: '新手入门路径',
        description: '从零开始学习家庭园艺',
        courses: ['hg_1', 'hg_2', 'hg_3'],
        estimatedDuration: '3小时'
      },
      {
        id: 'path_advanced',
        name: '进阶提升路径',
        description: '掌握高级种植技巧',
        courses: ['hg_4', 'hg_5', 'hg_6'],
        estimatedDuration: '5小时'
      }
    ];
  } else {
    return [
      {
        id: 'path_crop',
        name: '作物种植专业路径',
        description: '系统学习作物种植技术',
        courses: ['pa_1', 'pa_2', 'pa_3'],
        estimatedDuration: '8小时'
      }
    ];
  }
}

3. 学习笔记功能

功能描述

  • 在学习过程中记录笔记
  • 标记重点内容
  • 导出学习笔记

4. 学习社区功能

功能描述

  • 课程评论和讨论
  • 学习心得分享
  • 问题求助和解答

九、本篇总结

9.1 核心知识点

本篇教程完整实现了学习中心的课程体系,涵盖以下核心内容:

  1. 课程体系设计

    • 分类体系规划
    • 难度等级划分
    • 课程内容结构
  2. 数据模型设计

    • Course 课程模型
    • CourseLesson 课时模型
    • CourseProgress 进度模型
  3. 服务层实现

    • KnowledgeService 课程服务
    • 课程管理功能
    • 进度管理功能
    • 搜索和筛选功能
  4. UI组件开发

    • 课程列表展示
    • 分类标签筛选
    • 搜索功能
    • 学习统计展示
  5. 双模式适配

    • 家庭园艺模式
    • 专业农业模式
    • 动态内容切换

9.2 技术要点

  • 数据持久化:使用 StorageUtil 存储学习进度
  • 状态管理:@Local 装饰器管理页面状态
  • 列表渲染:ForEach 高效渲染课程列表
  • 搜索功能:实时搜索和关键词匹配
  • 分类筛选:多维度筛选课程
  • 进度展示:Progress 组件显示学习进度

9.3 实际应用价值

学习中心系统解决了以下实际问题:

  1. 系统化学习:提供结构化的学习内容
  2. 个性化推荐:根据用户水平推荐课程
  3. 进度跟踪:记录和展示学习进度
  4. 知识检索:快速查找所需知识
  5. 技能提升:帮助用户逐步提升种植技能

9.4 下一篇预告

第25篇:学习中心 - 课程详情与学习

下一篇将实现课程详情和学习功能,包括:

  • 📖 课程详情页面设计
  • 📚 课时列表展示
  • ▶️ 课时学习页面
  • ✅ 学习进度更新
  • 📝 学习笔记功能

附录:完整代码文件清单

模型层

  • entry/src/main/ets/models/KnowledgeModels.ets - 课程数据模型

服务层

  • entry/src/main/ets/services/KnowledgeService.ets - 课程服务

页面层

  • entry/src/main/ets/pages/Learning/LearningCenterPage.ets - 学习中心页面
相关推荐
一起养小猫8 小时前
Flutter for OpenHarmony 实战:打造天气预报应用
开发语言·网络·jvm·数据库·flutter·harmonyos
小白郭莫搞科技13 小时前
鸿蒙跨端框架Flutter学习:CustomTween自定义Tween详解
学习·flutter·harmonyos
mocoding13 小时前
使用鸿蒙化flutter_fluttertoast替换Flutter原有的SnackBar提示弹窗
flutter·华为·harmonyos
辰宇信息咨询13 小时前
3D自动光学检测(AOI)市场调研报告-发展趋势、机遇及竞争分析
大数据·数据分析
阳光九叶草LXGZXJ14 小时前
达梦数据库-学习-47-DmDrs控制台命令(LSN、启停、装载)
linux·运维·数据库·sql·学习
珠海西格15 小时前
“主动预防” vs “事后补救”:分布式光伏防逆流技术的代际革命,西格电力给出标准答案
大数据·运维·服务器·分布式·云计算·能源
创客匠人老蒋15 小时前
从数据库到智能体:教育企业如何构建自己的“数字大脑”?
大数据·人工智能·创客匠人
A9better15 小时前
嵌入式开发学习日志53——互斥量
stm32·嵌入式硬件·学习
2501_9481201515 小时前
基于大数据的泄漏仪设备监控系统
大数据