老师端几乎ok

This commit is contained in:
zhutao
2025-11-20 23:03:49 +08:00
parent b7239292d1
commit 9c94ee31fd
7 changed files with 325 additions and 94 deletions

View File

@@ -1,30 +1,33 @@
import 'package:app/data/models/student.dart';
import 'package:app/request/dto/room/room_user_dto.dart';
import 'package:app/request/dto/room/rtc_token_dto.dart';
import 'package:app/request/websocket/room_protocol.dart';
import 'package:app/request/websocket/room_websocket.dart';
import 'package:app/utils/time.dart';
import 'package:flutter/cupertino.dart';
import 'type.dart';
class StudentsViewModel extends ChangeNotifier {
///学生摄像头列表
List<Student> _students = [];
///房间的基础信息房间id、房间开始时间
final int roomId;
late final DateTime startTime;
StudentsViewModel({required this.roomId, String? start}) {
startTime = parseTime(start!);
_startRoom();
}
List<Student> get students => _students;
///学生摄像头列表
List<RoomUserDto> _students = [];
///房间的基础信息房间id、房间开始时间
final int roomId;
late final DateTime startTime;
///老师选中的学生id
int activeSId = 0;
List<RoomUserDto> get students => _students;
///是否能开始自习室
bool get canEnterRoom {
final now = DateTime.now();
// 如果到了开始时间,则可以进入房间
if (now.isAfter(startTime)) {
return true;
}
@@ -32,11 +35,12 @@ class StudentsViewModel extends ChangeNotifier {
}
///websocket管理
late RoomWebSocket _ws;
final RoomWebSocket _ws = RoomWebSocket();
RtcTokenDto? get rtcToken => _ws.rtcToken;
///开始链接房间
void _startRoom() async {
_ws = RoomWebSocket();
//如果socket的token没有先初始化
if (_ws.wsToken.isEmpty) {
await _ws.initToken(roomId);
@@ -48,9 +52,21 @@ class StudentsViewModel extends ChangeNotifier {
//监听各种ws事件
_ws.stream.listen((msg) {
// 自习室人员变化
if (msg.event == RoomEvent.changeUser) {
final list = msg.data['user_list'].map((x) => RoomUserDto.fromJson(x)).toList();
onStudentChange(list);
} else if ([
RoomEvent.openSpeaker,
RoomEvent.closeSpeaker,
RoomEvent.openMic,
RoomEvent.closeMic,
RoomEvent.openCamera,
RoomEvent.closeCamera,
RoomEvent.handUp,
].contains(msg.event)) {
onSyncStudentStatus();
//TODO 直接同步服务器最新的数组覆盖,或者覆盖这一条学生的
}
});
notifyListeners();
@@ -66,8 +82,69 @@ class StudentsViewModel extends ChangeNotifier {
}
}
///学生选择
void selectStudent(int id) {
activeSId = id;
notifyListeners();
}
///手动关闭学生扬声器、摄像头、麦克风等操作
/// - [uId]: 学生id
/// - [action]: 操作类型
void closeStudentSpeaker({
required int uId,
required StudentAction action,
}) {
final student = _students.firstWhere((t) => t.userId == uId);
Map<String, int> data = {
'target_user_id': uId,
};
//如果是控制扬声器
if (action == StudentAction.speaker) {
student.speekerStatus = student.speekerStatus == 0 ? 1 : 0;
data['speeker'] = student.speekerStatus;
} else if (action == StudentAction.camera) {
//如果是摄像头,只能关
if (student.cameraStatus == 0) return;
student.cameraStatus = 0;
data['camera'] = 0;
} else if (action == StudentAction.microphone) {
//如果是麦克风,只能关
if (student.microphoneStatus == 0) return;
student.microphoneStatus = 0;
data['microphone'] = 0;
}
notifyListeners();
_ws.send(RoomCommand.switchStudentCamera, data);
}
//清除全部学生举手,或者是指定
void clearHandUp(int? id) {
Map<String, dynamic> data = {};
if (id == null) {
data['target_user_id'] = "all";
_students.forEach((t) => t.handup = 0);
} else {
data['target_user_id'] = id;
_students.firstWhere((t) => t.userId == id).handup = 0;
}
notifyListeners();
_ws.send(RoomCommand.clearHandUp, data);
}
///学生人员变化事件,(如加入、退出、掉线)
void onStudentChange(List<RoomUserDto> list) {}
void onStudentChange(List<RoomUserDto> list) {
_students = list.where((t) => t.userType != 2).toList();
// 如果当前没有学生,则选择第一个
if (activeSId == 0 && _students.isNotEmpty) {
activeSId = _students.first.userId;
}
notifyListeners();
}
//TODO 同步学生的最新状态
void onSyncStudentStatus() {}
//销毁
@override

View File

@@ -0,0 +1,11 @@
///老师操作学生的状态、摄像头、扬声器、麦克风
enum StudentAction {
///摄像头
camera,
///麦克风
microphone,
///扬声器
speaker,
}