基于Vue+Nodejs实现宿舍管理系统

本文涉及的产品
可视分析地图(DataV-Atlas),3 个项目,100M 存储空间
数据可视化DataV,5个大屏 1个月
简介: 考虑到实用性,该系统需要拆分为两大子系统,一个是学生端系统,一个是后台管理端系统。学生端系统主要提供给学生使用,负责一些宿舍记录及个人信息记录的基本操作;后台管理模块则是主要负责对所有学生信息的整理,提供宿舍管理、楼层管理、数据查看等权限,提供给宿舍管理员使用的。


 
         

image.gif

项目编号:BS-QD-002

主要需求:

    • 学生信息录入、修改、删除、查询
    • 宿舍管理评分
    • 学生早起率、懒床率
    • 学生宿舍打扫频率
    • 学生晚归情况
    • 楼层管理

    考虑到实用性,该系统需要拆分为两大子系统,一个是学生端系统,一个是后台管理端系统。学生端系统主要提供给学生使用,负责一些宿舍记录及个人信息记录的基本操作;后台管理模块则是主要负责对所有学生信息的整理,提供宿舍管理、楼层管理、数据查看等权限,提供给宿舍管理员使用的。

    学生登陆

    学生系统拥有以下功能:

      • 创建账户
      • 分配宿舍
      • 填写个人信息
      • 修改个人信息
      • 起床打卡(用于统计懒床率)
      • 归宿登记(用于统计晚归情况)
      • 打扫记录(用于统计宿舍打扫频率)
      • 查看宿日常数据

      管理员登陆

      管理系统拥有以下功能:

        • 楼层管理
        • 宿舍评价
        • 宿舍信息管理
        • 学生信息查看
        • 保洁人员管理
        • 统计学生早起率
        • 统计学生宿舍打扫频率
        • 统计学生晚归

        超级管理员在享有上述管理员同等权限的同时额外拥有如下功能:

          • 创建管理员
          • 创建宿舍楼
          • 为宿舍楼分配管理员
          • 为宿舍楼分配保洁人员

          前端:

            • Vue 作为基础框架
            • vue-router 控制路由(hash 模式)
            • vuex 状态管理
            • axios 接入数据
            • Vue-element-admin作为基础框架

            后台(Nodejs):

              • Koa 作为基础框架
              • koa-router —— 服务端路由控制
              • koa-static —— 读取静态文件
              • koa-jwt —— JWT 登录校验
              • koa-body —— http body 数据处理
              • koa-compress —— Gzip 压缩
              • koa-cors —— CORS 解决跨域问题
              • sequelize —— ORM

              数据库:

                • MySQL

                数据库设计一览:

                image.gif编辑

                下面展示一下系统的部分功能:

                image.gif编辑

                仪表盘概揽:选择不同的宿舍楼查看相关信息

                image.gif编辑

                image.gif编辑

                管理员管理:

                image.gif编辑

                宿舍楼管理

                image.gif编辑

                楼层管理

                image.gif编辑

                宿舍信息

                image.gif编辑

                image.gif编辑

                宿舍入住学生信息

                image.gif编辑

                查看学生起床记录

                image.gif编辑

                查看学生归宿信息

                image.gif编辑

                查看学生宿舍打扫信息

                image.gif编辑

                查看个人信息

                image.gif编辑

                学生注册

                image.gif编辑

                注册后登陆系统

                image.gif编辑

                入住宿舍

                image.gif编辑

                起床打卡

                image.gif编辑

                归宿记录

                image.gif编辑

                打扫记录

                image.gif编辑

                后端工程:

                image.gif编辑

                前端工程

                image.gif编辑

                部门核心代码:

                const { Building } = require("../model")
                module.exports = {
                  getStudents: async function(buildingId) {
                    const FloorController = require("./floor_controller")
                    let users = []
                    const building = await Building.findOne({ where: { id: buildingId } })
                    const floors = await building.getFloors()
                    for (let floor of floors) {
                      const floorId = floor.id
                      users = [...users, ...(await FloorController.getStudents(floorId))]
                    }
                    return users
                  },
                  delBuilding: async function(id) {
                    const { setStudentRoomNull } = require("./user_controller")
                    const students = await this.getStudents(id)
                    students.forEach(student => {
                      setStudentRoomNull(student.id)
                    })
                    return await Building.destroy({ where: { id } })
                  }
                }

                image.gif

                const _ = require("lodash")
                const { User } = require("../model")
                module.exports = {
                  async getEvaluatesInfo(evaluates) {
                    const cpEvaluates = _.cloneDeep(evaluates)
                    for (let evaluate of cpEvaluates) {
                      const creator = await evaluate.getUser()
                      evaluate.dataValues.userName = creator.name
                    }
                    return cpEvaluates
                  }
                }

                image.gif

                const { Floor } = require("../model")
                module.exports = {
                  getStudents: async function(floorId) {
                    const { getStudentInfo } = require("./user_controller")
                    let users = []
                    const floor = await Floor.findOne({ where: { id: floorId } })
                    const rooms = await floor.getRooms()
                    for (let room of rooms) {
                      const roomUsers = await room.getUsers()
                      for (let user of roomUsers) {
                        users.push(await getStudentInfo(user.id))
                      }
                    }
                    return users
                  }
                }

                image.gif

                module.exports = {
                  UserController: require("./user_controller"),
                  RoomController: require("./room_controller"),
                  FloorController: require("./floor_controller"),
                  BuildingController: require("./building_controller"),
                  EvaluateController: require("./evaluate_controller"),
                  RecordController: require("./record_controller")
                }

                image.gif

                const {
                  User,
                  GetupRecord,
                  CleanRecord,
                  BackRecord,
                  Room,
                  Floor,
                  Building
                } = require("../model")
                const { Op } = require("sequelize")
                const moment = require("moment")
                const _ = require("lodash")
                const getupEarlyPoint = 8
                const backEarlyPoint = 22
                module.exports = {
                  // getup 相关
                  async addGetupRecord(userId) {
                    const user = await User.findOne({ where: { id: userId } })
                    const todyRecord = await GetupRecord.findOne({
                      where: {
                        userId: user.id,
                        roomId: user.roomId,
                        createdAt: {
                          [Op.gt]: moment()
                            .startOf("day")
                            .toDate(),
                          [Op.lt]: moment()
                            .endOf("day")
                            .toDate()
                        }
                      }
                    })
                    if (todyRecord) {
                      throw new Error("当天已经有记录,记录失败!")
                    }
                    return await GetupRecord.create({ userId: user.id, roomId: user.roomId })
                  },
                  async getUserGetupRecords(userId, days, pure = false) {
                    days = parseInt(days)
                    const user = await User.findOne({ where: { id: userId } })
                    const roomId = user.roomId
                    const room = await Room.findOne({ where: { id: roomId } })
                    // 获取最近 days 天的记录
                    const startTime = moment()
                      .subtract(days - 1 /* -1 代表查询天数包括今天 */, "days")
                      .startOf("day")
                      .toDate()
                    const allRecords = []
                    for (let i = 0; i < days; i++) {
                      const todayStart = moment(startTime)
                        .add(i, "days")
                        .toDate()
                      const todayEnd = moment(todayStart)
                        .endOf("day")
                        .toDate()
                      let record = await GetupRecord.findOne({
                        where: {
                          userId,
                          roomId,
                          createdAt: {
                            [Op.gt]: todayStart,
                            [Op.lt]: todayEnd
                          }
                        },
                        attributes: { exclude: ["updatedAt", "deletedAt"] }
                      })
                      if (record) {
                        // 如果当天有记录就推入结果
                        record = record.toJSON()
                        record.time = moment(record.createdAt).format("HH:mm")
                      } else if (!record && !pure) {
                        // 如果获取的是全部数据且当前天无数据
                        // 就建立一条空记录
                        record = GetupRecord.build({
                          id: "fake" + i,
                          roomId,
                          userId,
                          createdAt: todayStart
                        }).toJSON()
                        record.time = null
                      } else {
                        continue
                      }
                      record.date = moment(record.createdAt).format("YYYY-MM-DD")
                      record.userName = user.name
                      record.roomNumber = room.number
                      allRecords.push(record)
                    }
                    return allRecords.reverse()
                  },
                  async getRoomGetupRecords(roomId, days, pure = false) {
                    days = parseInt(days)
                    const room = await Room.findOne({ where: { id: roomId } })
                    const users = await room.getUsers()
                    const records = {}
                    for (let user of users) {
                      records[user.name] = await this.getUserGetupRecords(user.id, days, pure)
                    }
                    return records
                  },
                  async getGetupRecordLineCharData(roomId) {
                    const room = await Room.findOne({ where: { id: roomId } })
                    const users = await room.getUsers()
                    const data = { columns: ["周期"], rows: [] }
                    const dataCount = 5 // 获取的记录条数
                    const dataStep = 7 // 每条记录相隔的条数
                    // 初始化记录值
                    for (let i = 0; i < dataCount; i++) {
                      data.rows.push({ 周期: `最近${(i + 1) * dataStep}天` })
                    }
                    // 遍历当前宿舍的用户
                    for (let user of users) {
                      data.columns.push(user.name)
                      for (let i = 0; i < dataCount; i++) {
                        const days = (i + 1) * dataStep
                        // 获取某学生最近 days 天的早起记录
                        const records = await this.getUserGetupRecords(user.id, days, true)
                        let earlyTimes = 0
                        records.forEach(record => {
                          // 统计这些记录中有几天是早起的
                          const timeHour = parseInt(moment(record.createdAt).format("HH"))
                          if (timeHour < getupEarlyPoint) {
                            earlyTimes++
                          }
                        })
                        // 计算早起率
                        const probability = (earlyTimes / days).toFixed(4)
                        data.rows[i][user.name] = probability
                      }
                    }
                    return data
                  },
                  async getGetupTableData({
                    current,
                    step,
                    buildingId,
                    floorId,
                    roomId,
                    userId,
                    startTime,
                    endTime
                  }) {
                    // 初始化时间
                    startTime = startTime
                      ? moment(startTime)
                          .startOf("day")
                          .toDate()
                      : moment(0).toDate()
                    endTime = endTime
                      ? moment(endTime)
                          .endOf("day")
                          .toDate()
                      : moment()
                          .endOf("day")
                          .toDate()
                    console.log("endTime: ", endTime)
                    // 开始分情况获取数据
                    let result
                    if (userId) {
                      result = await GetupRecord.findAndCountAll({
                        where: {
                          userId: userId,
                          createdAt: {
                            [Op.gt]: startTime,
                            [Op.lt]: endTime
                          }
                        },
                        limit: step,
                        offset: step * (current - 1),
                        order: [["createdAt", "DESC"]]
                      })
                    } else if (roomId) {
                      result = await GetupRecord.findAndCountAll({
                        where: {
                          roomId: roomId,
                          createdAt: {
                            [Op.gt]: startTime,
                            [Op.lt]: endTime
                          }
                        },
                        limit: step,
                        offset: step * (current - 1),
                        order: [["createdAt", "DESC"]]
                      })
                    } else if (floorId) {
                      result = await GetupRecord.findAndCountAll({
                        where: {
                          createdAt: {
                            [Op.gt]: startTime,
                            [Op.lt]: endTime
                          }
                        },
                        include: [
                          {
                            model: Room,
                            where: { floorId }
                          }
                        ],
                        limit: step,
                        offset: step * (current - 1),
                        order: [["createdAt", "DESC"]]
                      })
                    } else if (buildingId) {
                      result = await GetupRecord.findAndCountAll({
                        where: {
                          createdAt: {
                            [Op.gt]: startTime,
                            [Op.lt]: endTime
                          }
                        },
                        include: [
                          {
                            model: Room,
                            where: { buildingId }
                          }
                        ],
                        limit: step,
                        offset: step * (current - 1),
                        order: [["createdAt", "DESC"]]
                      })
                    } else {
                      result = await GetupRecord.findAndCountAll({
                        where: {
                          createdAt: {
                            [Op.gt]: startTime,
                            [Op.lt]: endTime
                          }
                        },
                        limit: step,
                        offset: step * (current - 1),
                        order: [["createdAt", "DESC"]]
                      })
                    }
                    const getStudentInfo = require("./user_controller").getStudentInfo
                    let rows = []
                    for (let record of result.rows) {
                      record = record.toJSON()
                      delete record.room
                      const userInfo = await getStudentInfo(record.userId)
                      record = Object.assign(userInfo, record)
                      record.time = moment(record.createdAt).format("HH:mm")
                      record.date = moment(record.createdAt).format("YYYY-MM-DD")
                      if (parseInt(moment(record.createdAt).format("HH")) < getupEarlyPoint) {
                        record.early = true
                      } else {
                        record.early = false
                      }
                      rows.push(record)
                    }
                    result.rows = rows
                    return result
                  },
                  // back 相关
                  async addBackRecord(userId) {
                    const user = await User.findOne({ where: { id: userId } })
                    const todyRecord = await BackRecord.findOne({
                      where: {
                        userId: user.id,
                        roomId: user.roomId,
                        createdAt: {
                          [Op.gt]: moment()
                            .startOf("day")
                            .toDate(),
                          [Op.lt]: moment()
                            .endOf("day")
                            .toDate()
                        }
                      }
                    })
                    if (todyRecord) {
                      throw new Error("当天已经有记录,记录失败!")
                    }
                    return await BackRecord.create({ userId: user.id, roomId: user.roomId })
                  },
                  async getUserBackRecords(userId, days, pure = false) {
                    days = parseInt(days)
                    const user = await User.findOne({ where: { id: userId } })
                    const roomId = user.roomId
                    const room = await Room.findOne({ where: { id: roomId } })
                    // 获取最近 days 天的记录
                    const startTime = moment()
                      .subtract(days - 1 /* -1 代表查询天数包括今天 */, "days")
                      .startOf("day")
                      .toDate()
                    const allRecords = []
                    for (let i = 0; i < days; i++) {
                      const todayStart = moment(startTime)
                        .add(i, "days")
                        .toDate()
                      const todayEnd = moment(todayStart)
                        .endOf("day")
                        .toDate()
                      let record = await BackRecord.findOne({
                        where: {
                          userId,
                          roomId,
                          createdAt: {
                            [Op.gt]: todayStart,
                            [Op.lt]: todayEnd
                          }
                        },
                        attributes: { exclude: ["updatedAt", "deletedAt"] }
                      })
                      if (record) {
                        // 如果当天有记录就推入结果
                        record = record.toJSON()
                        record.time = moment(record.createdAt).format("HH:mm")
                      } else if (!record && !pure) {
                        // 如果获取的是全部数据且当前天无数据
                        // 就建立一条空记录
                        record = BackRecord.build({
                          id: "fake" + i,
                          roomId,
                          userId,
                          createdAt: todayStart
                        }).toJSON()
                        record.time = null
                      } else {
                        continue
                      }
                      record.date = moment(record.createdAt).format("YYYY-MM-DD")
                      record.userName = user.name
                      record.roomNumber = room.number
                      allRecords.push(record)
                    }
                    return allRecords.reverse()
                  },
                  async getRoomBackRecords(roomId, days, pure = false) {
                    days = parseInt(days)
                    const room = await Room.findOne({ where: { id: roomId } })
                    const users = await room.getUsers()
                    const records = {}
                    for (let user of users) {
                      records[user.name] = await this.getUserBackRecords(user.id, days, pure)
                    }
                    return records
                  },
                  async getBackRecordLineCharData(roomId) {
                    const room = await Room.findOne({ where: { id: roomId } })
                    const users = await room.getUsers()
                    const data = { columns: ["周期"], rows: [] }
                    const dataCount = 5 // 获取的记录条数
                    const dataStep = 7 // 每条记录相隔的条数
                    // 初始化记录值
                    for (let i = 0; i < dataCount; i++) {
                      data.rows.push({ 周期: `最近${(i + 1) * dataStep}天` })
                    }
                    // 遍历当前宿舍的用户
                    for (let user of users) {
                      data.columns.push(user.name)
                      for (let i = 0; i < dataCount; i++) {
                        const days = (i + 1) * dataStep
                        // 获取某学生最近 days 天的归宿记录
                        const records = await this.getUserBackRecords(user.id, days, true)
                        let earlyTimes = 0
                        records.forEach(record => {
                          // 统计这些记录中有几天是早归的
                          const timeHour = parseInt(moment(record.createdAt).format("HH"))
                          if (timeHour < backEarlyPoint) {
                            earlyTimes++
                          }
                        })
                        // 计算早起率
                        const probability = (earlyTimes / days).toFixed(4)
                        data.rows[i][user.name] = probability
                      }
                    }
                    return data
                  },
                  async getBackTableData({
                    current,
                    step,
                    buildingId,
                    floorId,
                    roomId,
                    userId,
                    startTime,
                    endTime
                  }) {
                    // 初始化时间
                    startTime = startTime
                      ? moment(startTime)
                          .startOf("day")
                          .toDate()
                      : moment(0).toDate()
                    endTime = endTime
                      ? moment(endTime)
                          .endOf("day")
                          .toDate()
                      : moment()
                          .endOf("day")
                          .toDate()
                    // 开始分情况获取数据
                    let result
                    if (userId) {
                      result = await BackRecord.findAndCountAll({
                        where: {
                          userId: userId,
                          createdAt: {
                            [Op.gt]: startTime,
                            [Op.lt]: endTime
                          }
                        },
                        limit: step,
                        offset: step * (current - 1),
                        order: [["createdAt", "DESC"]]
                      })
                    } else if (roomId) {
                      result = await BackRecord.findAndCountAll({
                        where: {
                          roomId: roomId,
                          createdAt: {
                            [Op.gt]: startTime,
                            [Op.lt]: endTime
                          }
                        },
                        limit: step,
                        offset: step * (current - 1),
                        order: [["createdAt", "DESC"]]
                      })
                    } else if (floorId) {
                      result = await BackRecord.findAndCountAll({
                        where: {
                          createdAt: {
                            [Op.gt]: startTime,
                            [Op.lt]: endTime
                          }
                        },
                        include: [
                          {
                            model: Room,
                            where: { floorId }
                          }
                        ],
                        limit: step,
                        offset: step * (current - 1),
                        order: [["createdAt", "DESC"]]
                      })
                    } else if (buildingId) {
                      result = await BackRecord.findAndCountAll({
                        where: {
                          createdAt: {
                            [Op.gt]: startTime,
                            [Op.lt]: endTime
                          }
                        },
                        include: [
                          {
                            model: Room,
                            where: { buildingId }
                          }
                        ],
                        limit: step,
                        offset: step * (current - 1),
                        order: [["createdAt", "DESC"]]
                      })
                    } else {
                      result = await BackRecord.findAndCountAll({
                        where: {
                          createdAt: {
                            [Op.gt]: startTime,
                            [Op.lt]: endTime
                          }
                        },
                        limit: step,
                        offset: step * (current - 1),
                        order: [["createdAt", "DESC"]]
                      })
                    }
                    const getStudentInfo = require("./user_controller").getStudentInfo
                    let rows = []
                    for (let record of result.rows) {
                      record = record.toJSON()
                      delete record.room
                      const userInfo = await getStudentInfo(record.userId)
                      record = Object.assign(userInfo, record)
                      record.time = moment(record.createdAt).format("HH:mm")
                      record.date = moment(record.createdAt).format("YYYY-MM-DD")
                      if (parseInt(moment(record.createdAt).format("HH")) < backEarlyPoint) {
                        record.early = true
                      } else {
                        record.early = false
                      }
                      rows.push(record)
                    }
                    result.rows = rows
                    return result
                  },
                  // clean 相关
                  async addCleanRecord(userId) {
                    const user = await User.findOne({ where: { id: userId } })
                    const todyRecord = await CleanRecord.findOne({
                      where: {
                        roomId: user.roomId,
                        createdAt: {
                          [Op.gt]: moment()
                            .startOf("day")
                            .toDate(),
                          [Op.lt]: moment()
                            .endOf("day")
                            .toDate()
                        }
                      }
                    })
                    if (todyRecord) {
                      throw new Error("当天已经有清扫记录,记录失败")
                    }
                    return await CleanRecord.create({
                      userId: user.id,
                      roomId: user.roomId
                    })
                  },
                  async getUserCleanRecords(userId, days) {
                    // 获取打扫记录不会自动补全每一天的信息
                    days = parseInt(days)
                    const user = await User.findOne({ where: { id: userId } })
                    const roomId = user.roomId
                    const room = await Room.findOne({ where: { id: roomId } })
                    // 获取最近 days 天的记录
                    const startTime = moment()
                      .subtract(days - 1 /* -1 代表查询天数包括今天 */, "days")
                      .startOf("day")
                      .toDate()
                    const todayEnd = moment()
                      .endOf("day")
                      .toDate()
                    const records = await CleanRecord.findAll({
                      where: {
                        userId,
                        roomId,
                        createdAt: {
                          [Op.gt]: startTime,
                          [Op.lt]: todayEnd
                        }
                      },
                      attributes: { exclude: ["updatedAt", "deletedAt"] },
                      order: [["createdAt", "DESC"]]
                    })
                    const allRecords = []
                    records.forEach(record => {
                      record = record.toJSON()
                      record.time = moment(record.createdAt).format("HH:mm")
                      record.date = moment(record.createdAt).format("YYYY-MM-DD")
                      record.userName = user.name
                      record.roomNumber = room.number
                      allRecords.push(record)
                    })
                    return allRecords
                  },
                  async getRoomCleanRecords(roomId, days) {
                    const room = await Room.findOne({ where: { id: roomId } })
                    const startTime = moment()
                      .subtract(days - 1 /* -1 代表查询天数包括今天 */, "days")
                      .startOf("day")
                      .toDate()
                    const todayEnd = moment()
                      .endOf("day")
                      .toDate()
                    const records = await room.getCleanRecords({
                      where: {
                        createdAt: {
                          [Op.gt]: startTime,
                          [Op.lt]: todayEnd
                        }
                      },
                      attributes: { exclude: ["updatedAt", "deletedAt"] },
                      order: [["createdAt", "DESC"]]
                    })
                    const allRecords = []
                    for (let record of records) {
                      const user = await record.getUser()
                      record = record.toJSON()
                      record.date = moment(record.createdAt).format("YYYY-MM-DD")
                      record.time = moment(record.createdAt).format("HH:mm")
                      record.userName = user.name
                      record.roomNumber = room.number
                      allRecords.push(record)
                    }
                    return allRecords
                  },
                  async getCleanTableData({
                    current,
                    step,
                    buildingId,
                    floorId,
                    roomId,
                    userId,
                    startTime,
                    endTime
                  }) {
                    // 初始化时间
                    startTime = startTime
                      ? moment(startTime)
                          .startOf("day")
                          .toDate()
                      : moment(0).toDate()
                    endTime = endTime
                      ? moment(endTime)
                          .endOf("day")
                          .toDate()
                      : moment()
                          .endOf("day")
                          .toDate()
                    // 开始分情况获取数据
                    let result
                    if (userId) {
                      result = await CleanRecord.findAndCountAll({
                        where: {
                          userId: userId,
                          createdAt: {
                            [Op.gt]: startTime,
                            [Op.lt]: endTime
                          }
                        },
                        limit: step,
                        offset: step * (current - 1),
                        order: [["createdAt", "DESC"]]
                      })
                    } else if (roomId) {
                      result = await CleanRecord.findAndCountAll({
                        where: {
                          roomId: roomId,
                          createdAt: {
                            [Op.gt]: startTime,
                            [Op.lt]: endTime
                          }
                        },
                        limit: step,
                        offset: step * (current - 1),
                        order: [["createdAt", "DESC"]]
                      })
                    } else if (floorId) {
                      result = await CleanRecord.findAndCountAll({
                        where: {
                          createdAt: {
                            [Op.gt]: startTime,
                            [Op.lt]: endTime
                          }
                        },
                        include: [
                          {
                            model: Room,
                            where: { floorId }
                          }
                        ],
                        limit: step,
                        offset: step * (current - 1),
                        order: [["createdAt", "DESC"]]
                      })
                    } else if (buildingId) {
                      result = await CleanRecord.findAndCountAll({
                        where: {
                          createdAt: {
                            [Op.gt]: startTime,
                            [Op.lt]: endTime
                          }
                        },
                        include: [
                          {
                            model: Room,
                            where: { buildingId }
                          }
                        ],
                        limit: step,
                        offset: step * (current - 1),
                        order: [["createdAt", "DESC"]]
                      })
                    } else {
                      result = await CleanRecord.findAndCountAll({
                        where: {
                          createdAt: {
                            [Op.gt]: startTime,
                            [Op.lt]: endTime
                          }
                        },
                        limit: step,
                        offset: step * (current - 1),
                        order: [["createdAt", "DESC"]]
                      })
                    }
                    const getStudentInfo = require("./user_controller").getStudentInfo
                    let rows = []
                    for (let record of result.rows) {
                      record = record.toJSON()
                      delete record.room
                      const userInfo = await getStudentInfo(record.userId)
                      record = Object.assign(userInfo, record)
                      record.time = moment(record.createdAt).format("HH:mm")
                      record.date = moment(record.createdAt).format("YYYY-MM-DD")
                      record.early = null
                      rows.push(record)
                    }
                    result.rows = rows
                    return result
                  },
                  // 通用
                  async getUserProbability(type, userId) {
                    const user = await User.findById(userId)
                    const startTime = user.checkTime
                    let records = []
                    let allRecords = []
                    switch (type) {
                      case "getup":
                        allRecords = await user.getGetupRecords({
                          where: {
                            createdAt: { [Op.gt]: startTime }
                          }
                        })
                        allRecords.forEach(record => {
                          let hour = parseInt(moment(record.createdAt).format("HH"))
                          if (hour < getupEarlyPoint) {
                            records.push(record)
                          }
                        })
                        break
                      case "back":
                        allRecords = await user.getBackRecords({
                          where: {
                            createdAt: { [Op.gt]: startTime }
                          }
                        })
                        allRecords.forEach(record => {
                          let hour = parseInt(moment(record.createdAt).format("HH"))
                          if (hour < backEarlyPoint) {
                            records.push(record)
                          }
                        })
                        break
                      case "clean":
                        records = await user.getCleanRecords({
                          where: {
                            createdAt: { [Op.gt]: startTime }
                          }
                        })
                        break
                      default:
                        throw new Error("参数传入错误")
                    }
                    // 计算从入住到现在有几天了
                    const days = Math.abs(moment(startTime).diff(moment(), "days"))
                    return (records.length / (days + 1)).toFixed(4)
                  }
                }

                image.gif

                const { User } = require("../model")
                const _ = require("lodash")
                const RecordController = require("./record_controller")
                module.exports = {
                  /**
                   * 获取学生用户的完整信息
                   * @param {Number} userId
                   */
                  async getStudentInfo(userId) {
                    const student = await User.findOne({
                      where: { id: userId },
                      attributes: { exclude: ["password", "deletedAt"] }
                    })
                    const room = await student.getRoom()
                    const floor = await room.getFloor()
                    const building = await floor.getBuilding()
                    const getupProb = await RecordController.getUserProbability("getup", userId)
                    const backProb = await RecordController.getUserProbability("back", userId)
                    const cleanProb = await RecordController.getUserProbability("clean", userId)
                    const info = Object.assign(student.dataValues, {
                      roomNumber: room.number,
                      floorId: floor.id,
                      floorLayer: floor.layer,
                      buildingId: building.id,
                      buildingName: building.name,
                      getupProb,
                      backProb,
                      cleanProb
                    })
                    return info
                  },
                  /**
                   * 获取学生用户们的完整信息
                   * @param {Array} users
                   */
                  async getStudentsInfo(users) {
                    const cloneUsers = _.cloneDeep(users)
                    for (let user of cloneUsers) {
                      delete user.dataValues.password
                      delete user.dataValues.deletedAt
                      const room = await user.getRoom()
                      const floor = await room.getFloor()
                      const building = await floor.getBuilding()
                      Object.assign(user.dataValues, {
                        roomNumber: room.number,
                        floorId: floor.id,
                        floorLayer: floor.layer,
                        buildingId: building.id,
                        buildingName: building.name
                      })
                    }
                    return cloneUsers
                  },
                  async setStudentRoomNull(id) {
                    const student = await User.findOne({ where: { id, role: "student" } })
                    const result = await student.update({ roomId: null })
                    return result
                  }
                }

                image.gif


                相关实践学习
                DataV Board用户界面概览
                本实验带领用户熟悉DataV Board这款可视化产品的用户界面
                阿里云实时数仓实战 - 项目介绍及架构设计
                课程简介 1)学习搭建一个数据仓库的过程,理解数据在整个数仓架构的从采集、存储、计算、输出、展示的整个业务流程。 2)整个数仓体系完全搭建在阿里云架构上,理解并学会运用各个服务组件,了解各个组件之间如何配合联动。 3&nbsp;)前置知识要求 &nbsp; 课程大纲 第一章&nbsp;了解数据仓库概念 初步了解数据仓库是干什么的 第二章&nbsp;按照企业开发的标准去搭建一个数据仓库 数据仓库的需求是什么 架构 怎么选型怎么购买服务器 第三章&nbsp;数据生成模块 用户形成数据的一个准备 按照企业的标准,准备了十一张用户行为表 方便使用 第四章&nbsp;采集模块的搭建 购买阿里云服务器 安装 JDK 安装 Flume 第五章&nbsp;用户行为数据仓库 严格按照企业的标准开发 第六章&nbsp;搭建业务数仓理论基础和对表的分类同步 第七章&nbsp;业务数仓的搭建&nbsp; 业务行为数仓效果图&nbsp;&nbsp;
                相关文章
                |
                4月前
                |
                JavaScript Java 测试技术
                基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
                基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
                92 2
                |
                4月前
                |
                JavaScript Java 测试技术
                基于springboot+vue.js+uniapp的医院综合管理系统附带文章源码部署视频讲解等
                基于springboot+vue.js+uniapp的医院综合管理系统附带文章源码部署视频讲解等
                46 5
                |
                4月前
                |
                JavaScript Java 测试技术
                基于springboot+vue.js+uniapp的大学生入伍人员管理系统附带文章源码部署视频讲解等
                基于springboot+vue.js+uniapp的大学生入伍人员管理系统附带文章源码部署视频讲解等
                91 4
                |
                4月前
                |
                JavaScript Java 测试技术
                基于springboot+vue.js+uniapp宿舍管理系统的附带文章源码部署视频讲解等
                基于springboot+vue.js+uniapp宿舍管理系统的附带文章源码部署视频讲解等
                82 3
                |
                4月前
                |
                JavaScript Java 测试技术
                基于springboot+vue.js+uniapp的地方特色美食分享管理系统附带文章源码部署视频讲解等
                基于springboot+vue.js+uniapp的地方特色美食分享管理系统附带文章源码部署视频讲解等
                36 2
                |
                4月前
                |
                JavaScript Java 测试技术
                基于springboot+vue.js+uniapp的江西郊医院血库管理系统附带文章源码部署视频讲解等
                基于springboot+vue.js+uniapp的江西郊医院血库管理系统附带文章源码部署视频讲解等
                34 2
                |
                4月前
                |
                JavaScript Java 测试技术
                基于springboot+vue.js+uniapp的人力资源管理系统附带文章源码部署视频讲解等
                基于springboot+vue.js+uniapp的人力资源管理系统附带文章源码部署视频讲解等
                46 2
                |
                4月前
                |
                JavaScript Java 测试技术
                基于springboot+vue.js+uniapp的在线作业管理系统附带文章源码部署视频讲解等
                基于springboot+vue.js+uniapp的在线作业管理系统附带文章源码部署视频讲解等
                44 1
                |
                4月前
                |
                JavaScript Java 测试技术
                基于springboot+vue.js+uniapp的员工工资管理系统附带文章源码部署视频讲解等
                基于springboot+vue.js+uniapp的员工工资管理系统附带文章源码部署视频讲解等
                59 1
                |
                4月前
                |
                JavaScript Java 测试技术
                基于springboot+vue.js+uniapp的北京市公交管理系统文章源码部署视频讲解等
                基于springboot+vue.js+uniapp的北京市公交管理系统文章源码部署视频讲解等
                23 0
                下一篇
                无影云桌面