使用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开发之旅提供有价值的参考。
查看19道真题和解析