import { router } from '@kit.ArkUI'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { MonitorDataType } from './HomePage'; import settingsService, { SettingsModel, TextResources } from '../common/SettingsService'; import logManager, { LogCategory, LogEventType } from '../common/logtext'; import { DatabaseService } from '../common/DatabaseService'; import classRoomService, { ClassSessionModel, QuestionOption } from '../common/ClassRoomService'; // 用户角色类型 enum UserRole { STUDENT = 'student', TEACHER = 'teacher', UNKNOWN = 'unknown' } @Entry @Component struct ClassPage { @State currentClassInfo: ClassInfo = new ClassInfo('数学', '张老师', 'A101'); @State classData: ClassDataType = { name: '', time: '', content: '', status: false }; // 新增状态 @State userRole: UserRole = UserRole.UNKNOWN; @State classCode: string = ''; @State className: string = ''; @State showCreateClassDialog: boolean = false; @State showJoinClassDialog: boolean = false; @State errorMessage: string = ''; @State isLoading: boolean = false; // 数据库服务 private dbService: DatabaseService = DatabaseService.getInstance(); // 从设置服务获取设置 @State settings: SettingsModel = settingsService.getSettings(); // 获取文本资源 @State texts: TextResources = settingsService.getTextResources(); aboutToAppear() { // 注册语言变化的回调 settingsService.registerLanguageChangeCallback(() => { this.texts = settingsService.getTextResources(); }); // 注册主题颜色变化的回调 settingsService.registerColorChangeCallback(() => { this.settings = settingsService.getSettings(); }); // 检查用户角色 const currentAccount = settingsService.getCurrentAccount(); const category = this.dbService.getUserCategory(currentAccount); if (category === 'student') { this.userRole = UserRole.STUDENT; } else if (category === 'teacher') { this.userRole = UserRole.TEACHER; } else { this.userRole = UserRole.UNKNOWN; } // 同步设置到课堂服务 classRoomService.checkIsTeacher(); this.Log_Event('aboutToAppear'); } build() { Stack({ alignContent: Alignment.TopStart }) { Column() { // 顶部导航栏 Row() { Text(this.texts.classPageTitle).fontSize(22).fontColor(Color.White).fontWeight(FontWeight.Bold) } .width('100%') .backgroundColor(this.settings.themeColor) .height(60) .justifyContent(FlexAlign.Center) .padding({ left: 20 }) // 页面内容区 Scroll() { Column() { // 根据用户角色显示不同界面 if (this.userRole === UserRole.STUDENT) { this.StudentView() } else if (this.userRole === UserRole.TEACHER) { this.TeacherView() } else { this.UnknownRoleView() } } .width('100%') .padding({ left: 16, right: 16 }) } .layoutWeight(1) .scrollBar(BarState.Off) // 底部导航栏 BottomNavigation({ activePage: 'class', themeColor: this.settings.themeColor, texts: this.texts }) } .width('100%') .height('100%') // 创建课堂对话框 if (this.showCreateClassDialog) { this.CreateClassDialog() } // 加入课堂对话框 if (this.showJoinClassDialog) { this.JoinClassDialog() } } .width('100%') .height('100%') } // 学生视图 @Builder StudentView() { Column() { // 学生上课指引卡片 Column() { Text("学生上课") .fontSize(24) .fontWeight(FontWeight.Bold) .margin({ bottom: 16 }) Text("请输入老师提供的课堂暗号进入课堂") .fontSize(16) .fontColor('#666') .margin({ bottom: 20 }) // 暗号输入框 Column({ space: 8 }) { Text("课堂暗号") .fontSize(16) .fontColor('#666666') .alignSelf(ItemAlign.Start) TextInput({ placeholder: '请输入4-6位数字暗号' }) .type(InputType.Number) .maxLength(6) .placeholderColor('#999999') .placeholderFont({ size: 16 }) .width('100%') .height(50) .fontSize(16) .fontColor('#333333') .backgroundColor('#F5F5F5') .borderRadius(8) .padding({ left: 16, right: 16 }) .onChange((value: string) => { this.classCode = value; this.errorMessage = ''; }) } .width('100%') .margin({ bottom: 16 }) // 错误信息 if (this.errorMessage !== '') { Text(this.errorMessage) .fontSize(14) .fontColor('#FF0000') .width('100%') .margin({ bottom: 16 }) } // 加入课堂按钮 Button("加入课堂") .width('100%') .height(50) .fontSize(18) .fontWeight(FontWeight.Medium) .backgroundColor(this.settings.themeColor) .borderRadius(8) .fontColor(Color.White) .enabled(!this.isLoading) .opacity(this.isLoading ? 0.6 : 1) .onClick(() => { this.joinClass(); }) } .width('100%') .backgroundColor(Color.White) .borderRadius(12) .padding(20) .shadow({ radius: 6, color: '#eeeeee' }) .margin({ top: 20, bottom: 20 }) // 当前课程信息卡片(只在没有正在进行的课程时显示) Column() { Text("近期课程").fontSize(20).fontWeight(FontWeight.Bold).margin({ bottom: 16 }) Row() { Column() { Text(this.currentClassInfo.name) .fontSize(18) .fontWeight(FontWeight.Bold) Text(`${this.texts.teacher}: ${this.currentClassInfo.teacher}`) .fontSize(14) .fontColor('#666') .margin({ top: 8 }) Text(`${this.texts.classroom}: ${this.currentClassInfo.room}`) .fontSize(14) .fontColor('#666') .margin({ top: 4 }) } .layoutWeight(1) .alignItems(HorizontalAlign.Start) Column() { Text("未开始") .fontSize(14) .fontColor('#999') .backgroundColor('#f5f5f5') .borderRadius(12) .padding({ left: 12, right: 12, top: 6, bottom: 6 }) } .justifyContent(FlexAlign.Center) } .width('100%') .padding(16) .borderRadius(8) .backgroundColor('#f9f9f9') } .width('100%') .backgroundColor(Color.White) .borderRadius(12) .padding(20) .shadow({ radius: 6, color: '#eeeeee' }) } } // 教师视图 @Builder TeacherView() { Column() { // 教师上课指引卡片 Column() { Text("教师上课") .fontSize(24) .fontWeight(FontWeight.Bold) .margin({ bottom: 16 }) Text("点击下方按钮创建新课堂") .fontSize(16) .fontColor('#666') .margin({ bottom: 20 }) // 创建课堂按钮 Button("创建新课堂") .width('100%') .height(50) .fontSize(18) .fontWeight(FontWeight.Medium) .backgroundColor(this.settings.themeColor) .borderRadius(8) .fontColor(Color.White) .enabled(!this.isLoading) .opacity(this.isLoading ? 0.6 : 1) .onClick(() => { this.showCreateClassDialog = true; }) } .width('100%') .backgroundColor(Color.White) .borderRadius(12) .padding(20) .shadow({ radius: 6, color: '#eeeeee' }) .margin({ top: 20, bottom: 20 }) // 历史课堂记录 Column() { Text("历史课堂").fontSize(20).fontWeight(FontWeight.Bold).margin({ bottom: 16 }) // 示例历史课堂卡片 Row() { Column() { Text("高等数学") .fontSize(18) .fontWeight(FontWeight.Bold) Text("课堂暗号: 123456") .fontSize(14) .fontColor('#666') .margin({ top: 8 }) Text("2025-04-01 10:30") .fontSize(14) .fontColor('#666') .margin({ top: 4 }) } .layoutWeight(1) .alignItems(HorizontalAlign.Start) Column() { Text("已结束") .fontSize(14) .fontColor('#999') .backgroundColor('#f5f5f5') .borderRadius(12) .padding({ left: 12, right: 12, top: 6, bottom: 6 }) } .justifyContent(FlexAlign.Center) } .width('100%') .padding(16) .borderRadius(8) .backgroundColor('#f9f9f9') .margin({ bottom: 12 }) // 示例历史课堂卡片 Row() { Column() { Text("线性代数") .fontSize(18) .fontWeight(FontWeight.Bold) Text("课堂暗号: 654321") .fontSize(14) .fontColor('#666') .margin({ top: 8 }) Text("2025-03-30 14:30") .fontSize(14) .fontColor('#666') .margin({ top: 4 }) } .layoutWeight(1) .alignItems(HorizontalAlign.Start) Column() { Text("已结束") .fontSize(14) .fontColor('#999') .backgroundColor('#f5f5f5') .borderRadius(12) .padding({ left: 12, right: 12, top: 6, bottom: 6 }) } .justifyContent(FlexAlign.Center) } .width('100%') .padding(16) .borderRadius(8) .backgroundColor('#f9f9f9') } .width('100%') .backgroundColor(Color.White) .borderRadius(12) .padding(20) .shadow({ radius: 6, color: '#eeeeee' }) } } // 未知角色视图 @Builder UnknownRoleView() { Column() { Text("用户角色未知") .fontSize(24) .fontWeight(FontWeight.Bold) .margin({ bottom: 16 }) Text("系统无法识别您的用户角色,请联系管理员或重新登录") .fontSize(16) .fontColor('#666') .margin({ bottom: 20 }) Button("返回登录") .width('60%') .height(50) .fontSize(18) .fontWeight(FontWeight.Medium) .backgroundColor(this.settings.themeColor) .borderRadius(8) .fontColor(Color.White) .onClick(() => { // 返回登录页 router.replaceUrl({ url: 'pages/login' }); }) } .width('100%') .backgroundColor(Color.White) .borderRadius(12) .padding(20) .shadow({ radius: 6, color: '#eeeeee' }) .margin({ top: 20 }) } // 创建课堂对话框 @Builder CreateClassDialog() { // 遮罩层 Column() { // 对话框内容 Column() { // 标题 Text("创建新课堂") .fontSize(22) .fontWeight(FontWeight.Bold) .margin({ bottom: 24 }) // 课堂名称 Column({ space: 8 }) { Text("课堂名称") .fontSize(16) .fontColor('#666666') .alignSelf(ItemAlign.Start) TextInput({ placeholder: '请输入课堂名称' }) .maxLength(20) .placeholderColor('#999999') .placeholderFont({ size: 16 }) .width('100%') .height(50) .fontSize(16) .fontColor('#333333') .backgroundColor('#F5F5F5') .borderRadius(8) .padding({ left: 16, right: 16 }) .onChange((value: string) => { this.className = value; }) } .width('100%') .margin({ bottom: 16 }) // 课堂暗号 Column({ space: 8 }) { Text("课堂暗号") .fontSize(16) .fontColor('#666666') .alignSelf(ItemAlign.Start) TextInput({ placeholder: '请输入4-6位数字暗号' }) .type(InputType.Number) .maxLength(6) .placeholderColor('#999999') .placeholderFont({ size: 16 }) .width('100%') .height(50) .fontSize(16) .fontColor('#333333') .backgroundColor('#F5F5F5') .borderRadius(8) .padding({ left: 16, right: 16 }) .onChange((value: string) => { this.classCode = value; }) } .width('100%') .margin({ bottom: 16 }) // 错误信息 if (this.errorMessage !== '') { Text(this.errorMessage) .fontSize(14) .fontColor('#FF0000') .width('100%') .margin({ bottom: 16 }) } // 按钮组 Row({ space: 20 }) { Button("取消") .width('45%') .height(45) .fontSize(16) .fontWeight(FontWeight.Medium) .backgroundColor('#f5f5f5') .borderRadius(8) .fontColor('#333') .onClick(() => { this.showCreateClassDialog = false; this.errorMessage = ''; }) Button("创建") .width('45%') .height(45) .fontSize(16) .fontWeight(FontWeight.Medium) .backgroundColor(this.settings.themeColor) .borderRadius(8) .fontColor(Color.White) .enabled(!this.isLoading) .opacity(this.isLoading ? 0.6 : 1) .onClick(() => { this.createClass(); }) } .width('100%') } .width('85%') .backgroundColor(Color.White) .borderRadius(16) .padding(24) } .width('100%') .height('100%') .backgroundColor('rgba(0,0,0,0.5)') .justifyContent(FlexAlign.Center) .onClick(() => { // 点击遮罩不关闭对话框 // 只能通过按钮关闭 }) } // 加入课堂对话框 @Builder JoinClassDialog() { // 遮罩层 Column() { // 对话框内容 Column() { // 标题 Text("加入课堂") .fontSize(22) .fontWeight(FontWeight.Bold) .margin({ bottom: 24 }) // 课堂暗号 Column({ space: 8 }) { Text("课堂暗号") .fontSize(16) .fontColor('#666666') .alignSelf(ItemAlign.Start) TextInput({ placeholder: '请输入4-6位数字暗号' }) .type(InputType.Number) .maxLength(6) .placeholderColor('#999999') .placeholderFont({ size: 16 }) .width('100%') .height(50) .fontSize(16) .fontColor('#333333') .backgroundColor('#F5F5F5') .borderRadius(8) .padding({ left: 16, right: 16 }) .onChange((value: string) => { this.classCode = value; }) } .width('100%') .margin({ bottom: 16 }) // 错误信息 if (this.errorMessage !== '') { Text(this.errorMessage) .fontSize(14) .fontColor('#FF0000') .width('100%') .margin({ bottom: 16 }) } // 按钮组 Row({ space: 20 }) { Button("取消") .width('45%') .height(45) .fontSize(16) .fontWeight(FontWeight.Medium) .backgroundColor('#f5f5f5') .borderRadius(8) .fontColor('#333') .onClick(() => { this.showJoinClassDialog = false; this.errorMessage = ''; }) Button("加入") .width('45%') .height(45) .fontSize(16) .fontWeight(FontWeight.Medium) .backgroundColor(this.settings.themeColor) .borderRadius(8) .fontColor(Color.White) .enabled(!this.isLoading) .opacity(this.isLoading ? 0.6 : 1) .onClick(() => { this.joinClass(); }) } .width('100%') } .width('85%') .backgroundColor(Color.White) .borderRadius(16) .padding(24) } .width('100%') .height('100%') .backgroundColor('rgba(0,0,0,0.5)') .justifyContent(FlexAlign.Center) .onClick(() => { // 点击遮罩不关闭对话框 // 只能通过按钮关闭 }) } // 创建课堂方法 private async createClass() { // 参数验证 if (!this.className || this.className.trim() === '') { this.errorMessage = '请输入课堂名称'; return; } if (!this.classCode || this.classCode.trim() === '') { this.errorMessage = '请输入课堂暗号'; return; } if (!/^\d{4,6}$/.test(this.classCode)) { this.errorMessage = '课堂暗号必须是4-6位数字'; return; } this.isLoading = true; // 连接服务 await classRoomService.connect(); // 创建课堂 try { const classSession = await classRoomService.createClassSession(this.className, this.classCode); if (classSession) { // 创建成功 this.showCreateClassDialog = false; this.errorMessage = ''; // 跳转到教师上课页面 router.pushUrl({ url: 'pages/ClassLivePage', params: { mode: 'teacher' } }); } else { this.errorMessage = '创建课堂失败,请稍后再试'; } } catch (error) { this.errorMessage = '创建过程中发生错误,请稍后再试'; logManager.error(LogCategory.CLASS, `Create class error: ${error}`); } finally { this.isLoading = false; } } // 加入课堂方法 private async joinClass() { // 参数验证 if (!this.classCode || this.classCode.trim() === '') { this.errorMessage = '请输入课堂暗号'; return; } if (!/^\d{4,6}$/.test(this.classCode)) { this.errorMessage = '课堂暗号必须是4-6位数字'; return; } this.isLoading = true; // 连接服务 await classRoomService.connect(); // 加入课堂 try { const result = await classRoomService.joinClassSession(this.classCode); if (result) { // 加入成功 this.showJoinClassDialog = false; this.errorMessage = ''; // 跳转到学生上课页面 router.pushUrl({ url: 'pages/ClassLivePage', params: { mode: 'student' } }); } else { this.errorMessage = '加入课堂失败,请检查暗号是否正确'; } } catch (error) { this.errorMessage = '加入过程中发生错误,请稍后再试'; logManager.error(LogCategory.CLASS, `Join class error: ${error}`); } finally { this.isLoading = false; } } // 页面生命周期方法 onPageShow(): void { this.Log_Event('onPageShow'); } onPageHide(): void { this.Log_Event('onPageHide'); } onBackPress(): void { this.Log_Event('onBackPress'); } aboutToDisappear(): void { this.Log_Event('aboutToDisappear'); } // 日志记录方法 public Log_Event(eventName: string): void { // 根据事件名称选择合适的日志事件类型 switch (eventName) { case 'aboutToAppear': logManager.info(LogCategory.CLASS, LogEventType.PAGE_APPEAR, 'ClassPage'); break; case 'aboutToDisappear': logManager.info(LogCategory.CLASS, LogEventType.PAGE_DISAPPEAR, 'ClassPage'); break; case 'onPageShow': logManager.info(LogCategory.CLASS, LogEventType.PAGE_SHOW, 'ClassPage'); break; case 'onPageHide': logManager.info(LogCategory.CLASS, LogEventType.PAGE_HIDE, 'ClassPage'); break; case 'onBackPress': logManager.info(LogCategory.CLASS, LogEventType.PAGE_BACK, 'ClassPage'); break; default: logManager.info(LogCategory.CLASS, LogEventType.SYSTEM_INFO, `ClassPage: ${eventName}`); } } } // Define a class for currentClassInfo class ClassInfo { name: string; teacher: string; room: string; constructor(name: string, teacher: string, room: string) { this.name = name; this.teacher = teacher; this.room = room; } } // Define proper interfaces instead of using any interface ClassDataType { name: string; time: string; content: string; status: boolean; } // 卡片组件 @Component struct Card { title: string = ''; data: ClassDataType | MonitorDataType = {} as ClassDataType; themeColor: string = '#409eff'; build() { Column() { // 卡片标题 Row() { Text(this.title) .fontSize(18) .fontWeight(FontWeight.Bold) .fontColor('#333') } .width('100%') .padding({ top: 8, bottom: 16 }) // 图表内容 Column() { Text('图表内容') .fontSize(16) .fontColor('#999') .height(150) .width('100%') .textAlign(TextAlign.Center) } .backgroundColor('#f5f5f5') .borderRadius(8) .width('100%') } .width('100%') .backgroundColor(Color.White) .borderRadius(12) .padding(16) .shadow({ radius: 6, color: '#eeeeee' }) } } // 底部导航栏组件 @Component struct BottomNavigation { @Prop activePage: string = 'class'; @Prop themeColor: string; @Prop texts: TextResources = {} as TextResources; build() { Row() { // 首页按钮 Column() { Image($r('app.media.home')) .width(24) .height(24) .fillColor(this.activePage === 'home' ? this.themeColor : '#999') Text(this.texts.home) .fontSize(12) .fontColor(this.activePage === 'home' ? this.themeColor : '#999') .margin({ top: 4 }) } .layoutWeight(1) .onClick(() => { if (this.activePage !== 'home') { router.replaceUrl({ url: 'pages/HomePage', params: { direction: 'left' // 从上课页向左切换到首页 } }); } }) // 上课按钮 Column() { Image($r('app.media.class')) .width(24) .height(24) .fillColor(this.activePage === 'class' ? this.themeColor : '#999') Text(this.texts.class) .fontSize(12) .fontColor(this.activePage === 'class' ? this.themeColor : '#999') .margin({ top: 4 }) } .layoutWeight(1) .onClick(() => { if (this.activePage !== 'class') { router.replaceUrl({ url: 'pages/ClassPage' }); } }) // 设置按钮 Column() { Image($r('app.media.settings')) .width(24) .height(24) .fillColor(this.activePage === 'settings' ? this.themeColor : '#999') Text(this.texts.settings) .fontSize(12) .fontColor(this.activePage === 'settings' ? this.themeColor : '#999') .margin({ top: 4 }) } .layoutWeight(1) .onClick(() => { if (this.activePage !== 'settings') { router.replaceUrl({ url: 'pages/SettingsPage' }); } }) } .width('100%') .height(60) .backgroundColor(Color.White) .borderWidth({ top: 0.5 }) .borderColor('#eeeeee') .padding({ top: 8, bottom: 8 }) } }