云上教室(学生管理)

69 阅读3分钟

人机2.gif 主要的是查课及选座功能

目录

  • ├── src\
  • │ ├── App.vue 入口文件
  • │ ├── assets\
  • │ │ └── vue.svg
  • │ ├── components\ 组件
  • │ │ ├── FixedAside.vue 侧边栏
  • │ │ ├── HeaderMain.vue 头部
  • │ │ ├── SelectMain.vue 选择菜单
  • │ │ ├── loginWindow.vue 登录窗口
  • │ │ └── selectData\ 不同的菜单组件
  • │ ├── main.js
  • │ ├── stores\
  • │ │ ├── loginUser.js 登录用户信息
  • │ │ └── setTasks.js 菜单任务信息

屏幕截图 2025-06-11 200022.png

讲述

实现是登录页面和其他页面使用vue-router路由守卫来拦截非登录状态下进入其他页面时自动跳转到登录页面,当一定时间内重复登录时由于会获取返回的token,下次登录时就不用再输入账号密码。进入主页面时会加载一个菜单任务而为了不让用户感到停顿在其默认组件的挂载生命周期前挂载也就是SelectMain,然后初始默认进入课程页面,会以一周的时间显示课程根据班级不同课程不同会显示老师名课程名及教室,也有一些账号管理功能,然后就是使用socket.io写的在线选座,根据其日期时间段、教室来确定房间号的同时连接房间,选座时或改座时触发通知给其他在线用户,未来将加入各用户的历史选择座位和使用three.js实现3d化。

后端

使用MongoDB数据库 使用的数据表

const studentModels23 = ['java1班','java2班','web1班','web2班','web3班','web4班','移动1班','移动2班','移动3班','移动4班'].map(name => {
    return connectionSeat.model(name, studentSchema, name);
});

const classAll23 =connectionSeat.model('2023级', classSChema, '2023级');
const classRoomAll = connectionSeat.model('上课教室情况', classRoomSchema, '上课教室情况');
const seatHistory=connectionSeat.model('座位记录', seatHistorySChema, '座位记录');
const activeAccount=connectionSeat.model('活跃账号', activeAccountSchema, '活跃账号');
const studentPassword=connectionSeat.model('学生密码', studentPasswordSchema, '学生密码');

登录逻辑

判断是需要输入密码的登录还是根据缓存的登录看是否前端返回的token是否在活跃用户里,第一次也就是密码登录时后端先查询学生表再生成token和一些其他数据添加进活跃用户数据库,直接登录就是检测前端发送的token是否存在和是否在活跃数据库里

初次登录接收数据后成功注册或登录时返回的

const { userName, studentId: inputValue } = req.body;
      res.json({
            code: 200,
            message: isPasswordLogin ? '密码登录成功' : '学号登录成功',
            token,
            phone: studentInfo?.手机号 || '',
            gender: studentInfo?.性别 || ''
        });
        const authHeader = req.headers['authorization'];
        
        res.json({
            code: 200,
            message: '验证成功',
            userName: account.userName,
            studentId: account.studentId,
            phone: studentInfo?.手机号 || '',
            gender: studentInfo?.性别 || ''
        });

查课逻辑

主要是通过学号学生表的学号前6位去班级表查找班级id的那条数据的班级名称如计算机应用然后再去课表数据库里面查询 这个就不详细写了 根据课表的设计不同实现的过程也不同

选座和socket的逻辑

一些配置

const io = socketIo(server, {
  cors: {
    origin: "*",
    methods: ["GET", "POST"]
  }
});
const PORT = 3000;
server.listen(PORT, () => {
  console.log(`http://192.168.31.12:${PORT}`);
  console.log('Socket.IO服务器已启动');
});

当前端查询某节课的座位表时

// 获取特定日期、时间段和教室的座位信息
app.get('/seats/occupied', async (req, res) => {
  try {
    const { date, timeSlot, room:roomID } = req.query;
    
    if (!date || !timeSlot || !roomID) {
      return res.status(400).json({ code: 400, message: '缺少日期、时间段或教室参数' });
    }

    const seats = await seatHistory.find({ date, timeSlot, roomID });
    res.json({ code: 200, message: '获取座位信息成功', data: seats });
  } catch (error) {
    console.error('获取座位信息错误:', error);
    res.status(500).json({ code: 500, message: '服务器错误' });
  }
});

选座与取消座位就是在座位记录里添加和删除修改了 在修改数据库前也就选择座位后删除座位后触发对应的socket事件

    const roomKey = `${date}-${timeSlot}-${roomID}`;
    io.to(roomKey).emit('seat-selected', {
      seatNumber: seat_id,
      studentId,
      userName: name,
      action: 'select'
    });
        // 发送Socket.IO事件通知其他用户
    const roomKey = `${date}-${timeSlot}-${roomID}`;
    io.to(roomKey).emit('seat-cancelled', {
      seatNumber,
      studentId,
      action: 'cancel'
    });

前端

通过路由守卫实现登录拦截 具体的单页面切换的话使用的是动态组件

      <keep-alive>
        <component :is='getCurrentComponent'></component>
      </keep-alive>

其他的就一些css了主要也是选座 在完成三个选项后就会连接房间

  socket.value = io('http://192.168.31.12:3000');
  
  socket.value.on('connect', () => {
    console.log('Socket.IO连接成功');
  });
  
  socket.value.on('disconnect', () => {
    console.log('Socket.IO连接断开');
  });

选择座位时和取消座位时的socket事件

  // 监听座位选择事件
  socket.value.on('seat-selected', (data) => {
    const { seatNumber, studentId: seatStudentId, userName: seatUserName } = data;
    ...}
   socket.value.on('seat-cancelled', (data) => {
    const { seatNumber, studentId: seatStudentId } = data;
    ...}

总结

  • 未来:3d选座和能力测试会将我之前写的作品结合起来展示
  • 不足:页面主题内容的设计不够
  • 难题:由于不是每个菜单都是差不多的内容需要写css使用ai写布局吧写的太麻烦自己改起来还不如重写ai每次写一部分还行不够也节省了很多时间