使用AppGallery Connect构建在线学习平台
基于HarmonyOS Next的教育类应用开发实战:使用AppGallery Connect构建在线学习平台
一、项目概述与准备工作
在当今数字化教育时代,移动学习应用已成为教育领域的重要组成部分。本次我们将基于HarmonyOS Next系统,使用AppGallery Connect服务开发一个功能完善的在线教育应用。该应用将包含课程展示、用户认证、学习进度跟踪等核心功能,适合各类教育机构和个人开发者参考学习。
在开始开发前,我们需要做好以下准备工作:
- 安装最新版本的DevEco Studio开发工具
- 注册华为开发者账号并开通AppGallery Connect服务
- 创建HarmonyOS应用项目并配置基本参数
- 在AppGallery Connect控制台初始化项目并启用所需服务
二、项目架构设计
我们的教育应用将采用模块化设计,主要包含以下几个核心模块:
- 用户认证模块:处理用户注册、登录和权限管理
- 课程管理模块:展示课程列表、详情和学习资源
- 学习记录模块:跟踪用户学习进度和成绩
- 互动交流模块:实现师生问答和讨论功能
下面我们将重点实现前三个核心模块,展示如何利用AppGallery Connect服务简化开发流程。
三、用户认证模块实现
用户认证是教育应用的基础功能,我们将使用AppGallery Connect提供的Auth Service来实现安全的用户认证系统。
1. 配置Auth Service
首先在项目的entry/build.gradle
文件中添加依赖:
dependencies { implementation 'com.huawei.agconnect:agconnect-auth-harmony:1.6.5.300' }
然后在resources/config.json
中配置Auth Service:
{ "app": { "bundleName": "com.example.educationapp", "vendor": "example", "version": { "code": 1000000, "name": "1.0.0" }, "apiVersion": { "compatible": 8, "target": 9, "releaseType": "Release" } }, "deviceConfig": {}, "module": { "name": "entry", "type": "entry", "abilities": [ { "name": "MainAbility", "type": "page", "label": "$string:MainAbility_label", "icon": "$media:icon", "launchType": "standard", "metaData": { "customizeData": [ { "name": "hwc-theme", "value": "androidhwext:style/Theme.Emui.Light.NoTitleBar", "extra": "" } ] } } ], "distro": { "deliveryWithInstall": true, "moduleName": "entry", "moduleType": "entry", "installationFree": false }, "reqPermissions": [ { "name": "ohos.permission.INTERNET" } ] } }
2. 实现用户注册功能
创建UserAuth.ts
文件,实现用户注册逻辑:
import agconnect from '@hw-agconnect/api-harmony'; import '@hw-agconnect/auth-harmony'; // 初始化AGConnectAuth let agcAuth = agconnect.auth(); // 用户注册函数 async function registerUser(email: string, password: string, username: string): Promise<boolean> { try { // 创建用户请求对象 let userRequest = { email: email, password: password, verifyCode: '', // 实际项目中需要通过邮件或短信获取验证码 displayName: username }; // 调用注册接口 let user = await agcAuth.createUser(userRequest); console.log('注册成功,用户ID:', user.getUid()); return true; } catch (error) { console.error('注册失败:', error); return false; } } // 用户登录函数 async function loginUser(email: string, password: string): Promise<boolean> { try { // 创建登录请求对象 let loginRequest = { email: email, password: password, verifyCode: '' // 如果需要验证码验证 }; // 调用登录接口 let user = await agcAuth.signIn(loginRequest); console.log('登录成功,用户:', user); return true; } catch (error) { console.error('登录失败:', error); return false; } } // 获取当前用户信息 function getCurrentUser(): any { return agcAuth.getCurrentUser(); } // 用户登出 async function logoutUser(): Promise<void> { try { await agcAuth.signOut(); console.log('登出成功'); } catch (error) { console.error('登出失败:', error); } } export { registerUser, loginUser, getCurrentUser, logoutUser };
3. 创建注册登录界面
在pages
目录下创建LoginPage.ets
和RegisterPage.ets
文件:
// LoginPage.ets @Entry @Component struct LoginPage { @State email: string = '' @State password: string = '' @State isLoading: boolean = false build() { Column() { Text('教育学习平台登录') .fontSize(24) .margin({ bottom: 30 }) TextInput({ placeholder: '请输入邮箱' }) .width('90%') .height(50) .margin({ bottom: 20 }) .onChange((value: string) => { this.email = value }) TextInput({ placeholder: '请输入密码' }) .width('90%') .height(50) .type(InputType.Password) .margin({ bottom: 30 }) .onChange((value: string) => { this.password = value }) Button('登录', { type: ButtonType.Capsule }) .width('80%') .height(50) .backgroundColor('#007DFF') .fontColor(Color.White) .onClick(async () => { this.isLoading = true let success = await loginUser(this.email, this.password) this.isLoading = false if (success) { // 跳转到主页 router.replaceUrl({ url: 'pages/MainPage' }) } else { prompt.showToast({ message: '登录失败,请检查邮箱和密码' }) } }) .loading(this.isLoading) Row() { Text('还没有账号?') Text('立即注册') .fontColor('#007DFF') .onClick(() => { router.pushUrl({ url: 'pages/RegisterPage' }) }) }.margin({ top: 20 }) } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) } }
四、课程管理模块实现
课程管理是教育应用的核心功能,我们将使用AppGallery Connect的Cloud DB服务来存储和管理课程数据。
1. 配置Cloud DB
首先在AppGallery Connect控制台创建课程数据模型:
- 对象类型名称:Course
- 字段设计: courseId: 字符串,主键title: 字符串,课程标题description: 字符串,课程描述coverUrl: 字符串,封面图URLteacher: 字符串,授课教师duration: 整型,课程时长(分钟)price: 浮点型,课程价格category: 字符串,课程分类
然后在项目中添加Cloud DB依赖:
dependencies { implementation 'com.huawei.agconnect:agconnect-clouddb-harmony:1.5.8.300' }
2. 实现课程数据操作
创建CourseService.ts
文件:
import agconnect from '@hw-agconnect/api-harmony'; import '@hw-agconnect/clouddb-harmony'; // 定义课程对象类型 interface Course { courseId: string; title: string; description: string; coverUrl: string; teacher: string; duration: number; price: number; category: string; } class CourseService { private cloudDB: any; private zoneName: string = 'CourseZone'; // 初始化Cloud DB async initCloudDB() { try { const agcCloudDB = agconnect.cloudDB(); this.cloudDB = await agcCloudDB.createInstance({ zoneName: this.zoneName, objectTypeName: 'Course' }); console.log('Cloud DB初始化成功'); } catch (error) { console.error('Cloud DB初始化失败:', error); } } // 添加课程 async addCourse(course: Course): Promise<boolean> { try { await this.cloudDB.upsert(course); return true; } catch (error) { console.error('添加课程失败:', error); return false; } } // 获取所有课程 async getAllCourses(): Promise<Course[]> { try { const query = this.cloudDB.createQuery(); const result = await this.cloudDB.executeQuery(query); return result.getSnapshotObjects(); } catch (error) { console.error('获取课程列表失败:', error); return []; } } // 根据ID获取课程详情 async getCourseById(courseId: string): Promise<Course | null> { try { const query = this.cloudDB.createQuery(); query.equalTo('courseId', courseId); const result = await this.cloudDB.executeQuery(query); const courses = result.getSnapshotObjects(); return courses.length > 0 ? courses[0] : null; } catch (error) { console.error('获取课程详情失败:', error); return null; } } // 根据分类获取课程 async getCoursesByCategory(category: string): Promise<Course[]> { try { const query = this.cloudDB.createQuery(); query.equalTo('category', category); const result = await this.cloudDB.executeQuery(query); return result.getSnapshotObjects(); } catch (error) { console.error('按分类获取课程失败:', error); return []; } } } export default new CourseService();
3. 创建课程列表和详情页面
在pages
目录下创建CourseListPage.ets
和CourseDetailPage.ets
:
// CourseListPage.ets @Entry @Component struct CourseListPage { @State courses: Course[] = [] @State isLoading: boolean = true @State selectedCategory: string = 'all' private categories: string[] = ['all', 'programming', 'language', 'business', 'design'] async aboutToAppear() { await CourseService.initCloudDB() this.loadCourses() } loadCourses() { this.isLoading = true if (this.selectedCategory === 'all') { CourseService.getAllCourses().then(courses => { this.courses = courses this.isLoading = false }) } else { CourseService.getCoursesByCategory(this.selectedCategory).then(courses => { this.courses = courses this.isLoading = false }) } } build() { Column() { // 分类筛选 Scroll() { Row() { ForEach(this.categories, (category: string) => { Button(category === 'all' ? '全部' : this.getCategoryName(category)) .type(ButtonType.Normal) .stateEffect(true) .backgroundColor(this.selectedCategory === category ? '#007DFF' : '#F5F5F5') .fontColor(this.selectedCategory === category ? Color.White : Color.Black) .onClick(() => { this.selectedCategory = category this.loadCourses() }) .margin(5) }) } .padding(10) } .scrollable(ScrollDirection.Horizontal) // 课程列表 List({ space: 10 }) { ForEach(this.courses, (course: Course) => { ListItem() { CourseItem({ course: course }) } .onClick(() => { router.pushUrl({ url: `pages/CourseDetailPage?courseId=${course.courseId}` }) }) }) } .layoutWeight(1) .visibility(this.isLoading ? Visibility.None : Visibility.Visible) // 加载指示器 if (this.isLoading) { LoadingProgress() .width(50) .height(50) } } .width('100%') .height('100%') } private getCategoryName(category: string): string { const map: Record<string, string> = { programming: '编程', language: '语言', business: '商业', design: '设计' } return map[category] || category } } @Component struct CourseItem { private course: Course build() { Row() { Image(this.course.coverUrl) .width(120) .height(80) .objectFit(ImageFit.Cover) .borderRadius(5) Column() { Text(this.course.title) .fontSize(18) .fontWeight(FontWeight.Bold) .margin({ bottom: 5 }) Text(this.course.teacher) .fontSize(14) .fontColor('#666666') .margin({ bottom: 5 }) Row() { Text(`${this.course.duration}分钟`) .fontSize(12) .fontColor('#999999') Text(`¥${this.course.price.toFixed(2)}`) .fontSize(16) .fontColor('#FF6600') .margin({ left: 20 }) } } .margin({ left: 15 }) .layoutWeight(1) } .width('100%') .padding(10) .backgroundColor(Color.White) .borderRadius(10) .shadow({ radius: 5, color: '#F1F1F1', offsetX: 2, offsetY: 2 }) } }
五、学习记录模块实现
学习记录功能可以帮助用户跟踪学习进度,我们将使用AppGallery Connect的Cloud Storage和Cloud Functions来实现这一功能。
1. 设计学习记录数据结构
在AppGallery Connect控制台创建学习记录对象类型:
- 对象类型名称:LearningRecord
- 字段设计: recordId: 字符串,主键userId: 字符串,用户IDcourseId: 字符串,课程IDprogress: 整型,学习进度(0-100)lastStudyTime: 日期,最后学习时间completed: 布尔型,是否已完成
2. 实现学习记录服务
创建LearningRecordService.ts
文件:
import agconnect from '@hw-agconnect/api-harmony'; import '@hw-agconnect/clouddb-harmony'; interface LearningRecord { recordId: string; userId: string; courseId: string; progress: number; lastStudyTime: Date; completed: boolean; } class LearningRecordService { private cloudDB: any; private zoneName: string = 'LearningRecordZone'; async initCloudDB() { try { const agcCloudDB = agconnect.cloudDB(); this.cloudDB = await agcCloudDB.createInstance({ zoneName: this.zoneName, objectTypeName: 'LearningRecord' }); console.log('学习记录Cloud DB初始化成功'); } catch (error) { console.error('学习记录Cloud DB初始化失败:', error); } } // 更新学习进度 async updateLearningProgress(userId: string, courseId: string, progress: number): Promise<boolean> { try { // 先查询是否已有记录 const query = this.cloudDB.createQuery(); query.equalTo('userId', userId); query.equalTo('courseId', courseId); const result = await this.cloudDB.executeQuery(query); const records = result.getSnapshotObjects(); let record: LearningRecord; if (records.length > 0) { // 更新现有记录 record = records[0]; record.progress = Math.min(progress, 100); record.lastStudyTime = new Date(); record.completed = record.progress >= 100; } else { // 创建新记录 record = { recordId: this.generateId(), userId: userId, courseId: courseId, progress: Math.min(progress, 100), lastStudyTime: new Date(), completed: progress >= 100 }; } await this.cloudDB.upsert(record); return true; } catch (error) { console.error('更新学习进度失败:', error); return false; } } // 获取用户的学习记录 async getUserLearningRecords(userId: string): Promise<LearningRecord[]> { try { const query = this.cloudDB.createQuery(); query.equalTo('userId', userId); const result = await this.cloudDB.executeQuery(query); return result.getSnapshotObjects(); } catch (error) { console.error('获取学习记录失败:', error); return []; } } // 获取特定课程的学习进度 async getCourseProgress(userId: string, courseId: string): Promise<number> { try { const query = this.cloudDB.createQuery(); query.equalTo('userId', userId); query.equalTo('courseId', courseId); const result = await this.cloudDB.executeQuery(query); const records = result.getSnapshotObjects(); return records.length > 0 ? records[0].progress : 0; } catch (error) { console.error('获取课程进度失败:', error); return 0; } } private generateId(): string { return Math.random().toString(36).substring(2) + Date.now().toString(36); } } export default new LearningRecordService();
3. 在课程详情页集成学习记录功能
更新CourseDetailPage.ets
:
@Entry @Component struct CourseDetailPage { @State course: Course | null = null @State isLoading: boolean = true @State progress: number = 0 private courseId: string = '' async aboutToAppear() { // 从路由参数获取课程ID const params = router.getParams() as Record<string, string>; this.courseId = params['courseId'] || ''; await Promise.all([ CourseService.initCloudDB(), LearningRecordService.initCloudDB() ]); this.loadCourseDetail(); this.loadLearningProgress(); } async loadCourseDetail() { this.course = await CourseService.getCourseById(this.courseId); this.isLoading = false; } async loadLearningProgress() { const user = getCurrentUser(); if (user) { this.progress = await LearningRecordService.getCourseProgress(user.uid, this.courseId); } } async updateProgress(newProgress: number) { const user = getCurrentUser(); if (user) { const success = await LearningRecordService.updateLearningProgress( user.uid, this.courseId, newProgress ); if (success) { this.progress = newProgress; prompt.showToast({ message: '学习进度已保存' }); } } else { prompt.showToast({ message: '请先登录' }); } } build() { Column() { if (this.isLoading) { LoadingProgress() .width(50) .height(50) } else if (this.course) { Scroll() { Column() { // 课程封面 Image(this.course.coverUrl) .width('100%') .height(200) .objectFit(ImageFit.Cover) // 课程基本信息 Column() { Text(this.course.title) .fontSize(22) .fontWeight(FontWeight.Bold) .margin({ bottom: 10 }) Row() { Text(this.course.teacher) .fontSize(16) .fontColor('#666666') Text(`${this.course.duration}分钟`) .fontSize(16) .fontColor('#666666') .margin({ left: 20 }) } .margin({ bottom: 15 }) Text(this.course.description) .fontSize(14) .fontColor('#333333') .margin({ bottom: 20 }) } .padding(15) // 学习进度 Column() { Text('学习进度') .fontSize(18) .fontWeight(FontWeight.Bold) .margin({ bottom: 10 }) Progress({ value: this.progress, total: 100, type: ProgressType.Linear }) .width('100%') .height(10) .margin({ bottom: 10 }) Text(`${this.progress}%`) .fontSize(16) .fontColor('#007DFF') .alignSelf(ItemAlign.End) Row() { Button('标记为25%') .type(ButtonType.Normal) .onClick(() => this.updateProgress(25)) .margin(5) Button('标记为50%') .type(ButtonType.Normal) .onClick(() => this.updateProgress(50)) .margin(5) Button('标记为75%') .type(ButtonType.Normal) .onClick(() => this.updateProgress(75)) .margin(5) Button('标记为完成') .type(ButtonType.Normal) .onClick(() => this.updateProgress(100)) .margin(5) } .margin({ top: 15 }) .justifyContent(FlexAlign.SpaceBetween) } .padding(15) .backgroundColor('#F9F9F9') .borderRadius(10) .margin({ top: 10, bottom: 20 }) } } } else { Text('课程加载失败') .fontSize(18) .fontColor(Color.Red) } } .width('100%') .height('100%') .padding(10) } }
六、项目总结与扩展建议
通过本教程,我们完成了一个基于HarmonyOS Next的教育类应用基础开发,实现了以下核心功能:
- 用户认证系统:使用AppGallery Connect Auth Service实现安全的用户注册和登录
- 课程管理系统:利用Cloud DB存储和管理课程数据
- 学习进度跟踪:通过自定义对象类型记录用户学习进度
扩展功能建议
- 课程内容管理:可以集成视频播放SDK,实现课程视频的在线播放和离线下载功能
- 测试与评估:添加课后测试功能,使用Cloud Functions自动评分
- 消息推送:集成Push Kit,向用户发送课程更新和学习提醒
- 数据分析:使用AppGallery Connect的分析服务,了解用户学习行为
- 支付功能:对于付费课程,可以集成华为支付服务
性能优化建议
- 对于课程列表,实现分页加载,避免一次性加载过多数据
- 使用本地缓存机制,减少网络请求次数
- 对图片资源进行压缩和懒加载
- 在用户网络不佳时,提供适当的降级方案
通过本项目的学习,开发者可以掌握HarmonyOS Next应用开发的核心技术,以及如何利用AppGallery Connect的各种服务快速构建功能完善的应用程序。希望本教程能为您的HarmonyOS开发之旅提供有价值的参考。