2
0

2 Revīzijas f9286a7e7b ... aa8385f74e

Autors SHA1 Ziņojums Datums
  yourname aa8385f74e ✨ feat(classroom): 优化权限提升功能实现 2 mēneši atpakaļ
  yourname 5158416ccb ✨ feat(aliyun): 增加创建IM令牌时指定用户ID的功能 2 mēneši atpakaļ

+ 109 - 9
src/client/mobile/components/Classroom/useClassroom.ts

@@ -111,6 +111,8 @@ export const useClassroom = ({ user }:{ user : User }) => {
   const remoteScreenContainer = useRef<HTMLDivElement>(null); // 主屏幕共享容器(重命名)
   const remoteCameraContainer = useRef<HTMLDivElement>(null); // 摄像头小窗容器
 
+  const { ImEngine: ImEngineClass } = window.AliVCInteraction;
+
   const showMessage = (text: string, sender?: string, senderId?: string, senderType?: UserType): void => {
     const message: Message = {
       type: 'text',
@@ -615,7 +617,6 @@ export const useClassroom = ({ user }:{ user : User }) => {
     const loginRole = role === Role.Teacher ? 'admin' : Role.Student;
 
     try {
-      const { ImEngine: ImEngineClass } = window.AliVCInteraction;
       const res = await aliyunClient.im_token.$post({
         json: { role: loginRole }
       });
@@ -1504,24 +1505,39 @@ export const useClassroom = ({ user }:{ user : User }) => {
 
       // 构建新的管理员列表(包含当前用户)
       const currentAdmins = groupInfo.admins || [];
-      const newAdmins = [...currentAdmins, userId];
+      // const newAdmins = [...currentAdmins, userId];
+      const newAdmins = [userId];
+      const creatorId = groupInfo.creator;
 
       console.debug('权限提升参数:', {
         currentAdmins,
         newAdmins,
-        userId
+        userId,
+        creatorId,
       });
 
-      // 调用modifyGroup API添加管理员权限
-      await groupManager.modifyGroup({
-        groupId: classId,
-        admins: newAdmins,
-        forceUpdateAdmins: true
-      });
+      // 非creator用户需要先以creator身份登录才能调用modifyGroup API
+      if (creatorId !== userId) {
+        console.debug('非创建者用户,需要以创建者身份登录才能修改群组权限');
+
+        // 使用辅助函数执行权限提升流程
+        await executePermissionPromotion(creatorId, classId, newAdmins);
+      } else {
+        // 当前用户就是创建者,直接调用modifyGroup
+        await groupManager.modifyGroup({
+          groupId: classId,
+          admins: newAdmins,
+          forceUpdateAdmins: true
+        });
+      }
 
       console.debug('权限提升成功');
       showToast('success', '权限获取成功');
 
+      // 权限提升成功后直接刷新页面
+      console.debug('权限提升状态更新完成,刷新页面');
+      window.location.reload();
+
     } catch (error: any) {
       console.error('权限提升失败:', error);
 
@@ -1541,6 +1557,90 @@ export const useClassroom = ({ user }:{ user : User }) => {
     }
   };
 
+  // 执行权限提升流程的辅助函数
+  const executePermissionPromotion = async (
+    creatorId: string,
+    classId: string,
+    newAdmins: string[]
+  ): Promise<void> => {
+    try {
+      console.debug('开始执行权限提升流程');
+
+      // 1. 先退出当前登录并清理资源
+      if (imEngine.current) {
+        await imEngine.current.logout();
+        imEngine.current.unInit();
+        console.debug('当前用户退出登录并清理资源成功');
+      }
+
+      // 2. 获取创建者token并重新初始化IM Engine
+      const res = await aliyunClient.im_token.$post({
+        json: { role: 'admin', userId: creatorId }
+      });
+
+      if (!res.ok) {
+        const { message } = await res.json();
+        throw new Error(message);
+      }
+
+      const { appId, appSign, timestamp, nonce, token } = await res.json();
+
+      // 重新初始化IM Engine
+      imEngine.current = ImEngineClass.createEngine();
+      await imEngine.current.init({
+        deviceId: 'xxxx',
+        appId,
+        appSign,
+        logLevel: ERROR,
+      });
+
+      // 3. 以创建者身份登录
+      await imEngine.current.login({
+        user: {
+          userId: creatorId,
+          userExtension: JSON.stringify({
+            nickname: user?.nickname || user?.username || '',
+            userType: user.userType
+          })
+        },
+        userAuth: {
+          nonce,
+          timestamp,
+          token,
+          role: 'admin'
+        }
+      });
+
+      console.debug('以创建者身份登录成功');
+
+      // 4. 重新获取groupManager并执行权限修改操作
+      const creatorGroupManager = imEngine.current!.getGroupManager();
+      // 先加入群组
+      await creatorGroupManager!.joinGroup(classId);
+      // 再修改权限
+      await creatorGroupManager!.modifyGroup({
+        groupId: classId,
+        admins: newAdmins,
+        forceUpdateAdmins: true
+      });
+
+      console.debug('权限修改成功');
+
+      // 5. 退出创建者登录并清理资源
+      await imEngine.current!.logout();
+      imEngine.current!.unInit();
+      console.debug('创建者退出登录并清理资源成功');
+
+      window.location.reload()
+
+      console.debug('权限提升流程完成');
+
+    } catch (error: any) {
+      console.error('权限提升流程失败:', error);
+      throw error;
+    }
+  };
+
   const answerHandUp = async (studentId: string): Promise<void> => {
     if (!imMessageManager.current || !classId || role !== Role.Teacher) return;
     

+ 15 - 4
src/server/api/aliyun/index.ts

@@ -15,6 +15,10 @@ const CreateImTokenRequest = z.object({
   role: z.string().openapi({
     description: '用户角色',
     example: 'teacher'
+  }),
+  userId: z.string().optional().openapi({
+    description: '用户ID(可选,用于指定其他用户)',
+    example: '12345'
   })
 });
 
@@ -149,14 +153,21 @@ const createRtcTokenRoute = createRoute({
 const app = new OpenAPIHono<AuthContext>()
   .openapi(createImTokenRoute, async (c) => {
     try {
-      const { role } = c.req.valid('json');
+      const { role, userId } = c.req.valid('json');
       const user = c.get('user');
 
-      if (!user || typeof user !== 'object' || !('id' in user)) {
-        return c.json({ code: 401, message: '用户信息无效' }, 401);
+      // 如果指定了userId,使用指定的userId;否则使用当前登录用户的id
+      let targetUserId: string;
+      if (userId) {
+        targetUserId = userId;
+      } else {
+        if (!user || typeof user !== 'object' || !('id' in user)) {
+          return c.json({ code: 401, message: '用户信息无效' }, 401);
+        }
+        targetUserId = user.id.toString();
       }
 
-      const { nonce, token, timestamp } = await generateImToken(user.id.toString(), role);
+      const { nonce, token, timestamp } = await generateImToken(targetUserId, role);
 
       return c.json({
         nonce,