diff --git a/node_api/src/modules/meeting/meeting.controller.ts b/node_api/src/modules/meeting/meeting.controller.ts index ab4c8f6..8922768 100644 --- a/node_api/src/modules/meeting/meeting.controller.ts +++ b/node_api/src/modules/meeting/meeting.controller.ts @@ -109,7 +109,7 @@ export class MeetingController { }) public async saveStudentOrder(@Body() dto: SaveStudentOrderDto) { // 1. 保存到 Redis - await this.meetingService.saveStudentOrder(dto.roomId, dto.studentLongIds); + await this.meetingService.saveStudentOrder(dto.roomId, dto.studentShortIds); // 2. 获取房间内所有 socket 并过滤出监控端 (monitor 模式) const ns = this.websocketGateway.getServer(); @@ -123,7 +123,7 @@ export class MeetingController { type: 'sev_student_order_changed', data: { fromRoomId: dto.roomId, - studentLongIds: dto.studentLongIds, + studentShortIds: dto.studentShortIds, }, }); } diff --git a/node_api/src/modules/meeting/meeting.dto.ts b/node_api/src/modules/meeting/meeting.dto.ts index 0e4a93e..fdf04d2 100644 --- a/node_api/src/modules/meeting/meeting.dto.ts +++ b/node_api/src/modules/meeting/meeting.dto.ts @@ -48,8 +48,8 @@ export class SaveStudentOrderDto { @IsString({ message: 'roomId 必须是字符串' }) roomId!: string; - @ApiProperty({ description: '学生长 ID 数组 (按排序顺序)', example: [1234567890, 1234567891, 1234567892] }) - @IsNotEmpty({ message: 'studentLongIds 不能为空' }) - @IsArray({ message: 'studentLongIds 必须是数组' }) - studentLongIds!: number[]; + @ApiProperty({ description: '学生短 ID 数组 (按排序顺序)', example: [1001, 1002, 1003] }) + @IsNotEmpty({ message: 'studentShortIds 不能为空' }) + @IsArray({ message: 'studentShortIds 必须是数组' }) + studentShortIds!: number[]; } diff --git a/node_api/src/modules/websocket/meeting-redis.service.ts b/node_api/src/modules/websocket/meeting-redis.service.ts index 553907d..254d0f9 100644 --- a/node_api/src/modules/websocket/meeting-redis.service.ts +++ b/node_api/src/modules/websocket/meeting-redis.service.ts @@ -502,14 +502,14 @@ export class MeetingRedisService { /** * 设置学生排序顺序 * @param roomId - 房间 ID - * @param studentLongIds - 学生长 ID 数组 (按排序顺序) + * @param studentShortIds - 学生短 ID 数组 (按排序顺序) */ - async setStudentOrder(roomId: string, studentLongIds: number[]): Promise { + async setStudentOrder(roomId: string, studentShortIds: number[]): Promise { const key = `${this.KEY_PREFIX.STUDENT_ORDER}${roomId}`; const client = this.getClient(); await client.del(key); // 先删除旧数据 - if (studentLongIds.length > 0) { - const stringIds = studentLongIds.map((id) => String(id)); + if (studentShortIds.length > 0) { + const stringIds = studentShortIds.map((id) => String(id)); await client.rpush(key, ...stringIds); await client.expire(key, 24 * 60 * 60); } diff --git a/node_api/src/modules/websocket/meeting.websocket.ts b/node_api/src/modules/websocket/meeting.websocket.ts index 30d2367..578c30a 100644 --- a/node_api/src/modules/websocket/meeting.websocket.ts +++ b/node_api/src/modules/websocket/meeting.websocket.ts @@ -711,10 +711,10 @@ export class MeetingWebSocketGateway implements OnGatewayConnection, OnGatewayDi */ @SubscribeMessage('client_student_order_changed') public async handleStudentOrderChanged( - @MessageBody() data: { roomId: string; studentLongIds: number[] }, + @MessageBody() data: { roomId: string; studentShortIds: number[] }, @ConnectedSocket() socket: MeetingSocket ): Promise { - if (!data?.roomId || !Array.isArray(data.studentLongIds)) { + if (!data?.roomId || !Array.isArray(data.studentShortIds)) { return; } const isHost = socket.data.user?.role !== 0; @@ -723,7 +723,7 @@ export class MeetingWebSocketGateway implements OnGatewayConnection, OnGatewayDi return; } // 保存到 Redis - await this.redisService.setStudentOrder(data.roomId, data.studentLongIds); + await this.redisService.setStudentOrder(data.roomId, data.studentShortIds); // 获取房间内所有 socket 并过滤出监控端 (monitor 模式) const ns = this.server; if (ns) { @@ -732,9 +732,9 @@ export class MeetingWebSocketGateway implements OnGatewayConnection, OnGatewayDi if (monitorSocketIds.length > 0) { // 发送给所有监控端的 socket - ns.to(monitorSocketIds).emit('message', { type: 'sev_student_order_changed', data: { fromRoomId: data.roomId, studentLongIds: data.studentLongIds } }); + ns.to(monitorSocketIds).emit('message', { type: 'sev_student_order_changed', data: { fromRoomId: data.roomId, studentShortIds: data.studentShortIds } }); } } - this.log(`创建者更新了学生排序:roomId=${data.roomId}, 学生数量=${data.studentLongIds.length}`); + this.log(`创建者更新了学生排序:roomId=${data.roomId}, 学生数量=${data.studentShortIds.length}`); } } diff --git a/node_api/src/modules/websocket/types.ts b/node_api/src/modules/websocket/types.ts index 4fc8a2f..3ec001c 100644 --- a/node_api/src/modules/websocket/types.ts +++ b/node_api/src/modules/websocket/types.ts @@ -217,8 +217,8 @@ export interface MeetingRoomEndTimestampUpdatedData { export interface MeetingStudentOrderChangedData { /** 来源房间 */ fromRoomId: string; - /** 学生长 ID 数组 (按排序顺序) */ - studentLongIds: number[]; + /** 学生短 ID 数组 (按排序顺序) */ + studentShortIds: number[]; } export type MeetingDownlinkPacket = diff --git a/src/api/meeting.ts b/src/api/meeting.ts index 4c62092..e5383f7 100644 --- a/src/api/meeting.ts +++ b/src/api/meeting.ts @@ -52,12 +52,12 @@ export function getStudentDetailsAxios(homeworkId: number, roomId: string): Prom /** * 保存学生排序顺序 * @param roomId - 房间 ID - * @param studentLongIds - 学生长 ID 数组 (按排序顺序) + * @param studentShortIds - 学生短 ID 数组 (按排序顺序) */ -export function saveStudentOrderAxios(roomId: string, studentLongIds: number[]): Promise> { +export function saveStudentOrderAxios(roomId: string, studentShortIds: number[]): Promise> { return axios.post>(`${import.meta.env.VITE_MEETING_BASE_URL}/meeting/student-order`, { roomId, - studentLongIds, + studentShortIds, }); } diff --git a/src/views/meeting/meeting-room/meeting-room-monitor.vue b/src/views/meeting/meeting-room/meeting-room-monitor.vue index cb84b3e..4a3289a 100644 --- a/src/views/meeting/meeting-room/meeting-room-monitor.vue +++ b/src/views/meeting/meeting-room/meeting-room-monitor.vue @@ -257,6 +257,15 @@ selectedUserUid.value = packet.data.targetUid; break; } + case 'sev_student_order_changed': { + // 学生排序变更,根据短 ID 数组重新排序学生列表 + const newOrder = packet.data.studentShortIds; + if (Array.isArray(newOrder) && newOrder.length > 0) { + // 这里可以添加排序逻辑,或者让 Agora 自动处理 + console.log('[监控端] 学生排序已更新:', newOrder); + } + break; + } case 'sev_class_started': { classStatus.value = 'in_class'; meetingSocket diff --git a/src/views/meeting/meeting-room/student-sort-dialog.vue b/src/views/meeting/meeting-room/student-sort-dialog.vue index 802ecb0..1838c49 100644 --- a/src/views/meeting/meeting-room/student-sort-dialog.vue +++ b/src/views/meeting/meeting-room/student-sort-dialog.vue @@ -82,9 +82,10 @@ */ async function saveAndClose() { try { - const studentLongIds = sortedStudents.value.map((s) => s.longId); + // 使用短 ID 数组进行排序 + const studentShortIds = sortedStudents.value.map((s) => s.shortId); - const result = await saveStudentOrderAxios(props.roomId, studentLongIds); + const result = await saveStudentOrderAxios(props.roomId, studentShortIds); if (result.data) { ElMessage.success('排序已保存');