发布于 2026-01-06 8 阅读
0

如何构建学校管理系统:包含代码片段的完整指南

如何构建学校管理系统:包含代码片段的完整指南

构建学校管理系统 (SMS)可以帮助教育机构实现运营数字化,简化管理人员、教师、学生和家长与学校数据的交互方式。在本指南中,您将学习如何使用MERN 技术栈(MongoDB、Express.js、React、Node.js)构建完整的学校管理系统。

我们将涵盖以下内容:

  • 用户身份验证
  • 学生和教师管理
  • 课程安排
  • 考勤跟踪
  • 一个基于 React 的基本仪表板

目录

  1. 项目设置
  2. 身份验证系统
  3. 学生管理
  4. 教师管理
  5. 课程安排
  6. 考勤跟踪
  7. React 前端设置
  8. 结论
  9. 作者及资源

1. 项目设置

后端设置

mkdir backend && cd backend
npm init -y
npm install express mongoose dotenv bcryptjs jsonwebtoken cors
Enter fullscreen mode Exit fullscreen mode

前端设置

npx create-react-app frontend
cd frontend
npm install axios react-router-dom
Enter fullscreen mode Exit fullscreen mode

2. 身份验证系统(Node.js)

/models/User.js

const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');

const userSchema = new mongoose.Schema({
  name: String,
  email: { type: String, unique: true },
  password: String,
  role: { type: String, enum: ['admin', 'teacher', 'student'], default: 'student' },
});

userSchema.pre('save', async function () {
  if (!this.isModified('password')) return;
  this.password = await bcrypt.hash(this.password, 12);
});

module.exports = mongoose.model('User', userSchema);
Enter fullscreen mode Exit fullscreen mode

/routes/userRoutes.js

const express = require('express');
const router = express.Router();
const User = require('../models/User');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');

router.post('/register', async (req, res) => {
  const { name, email, password, role } = req.body;
  const user = new User({ name, email, password, role });
  await user.save();
  res.status(201).json({ message: 'User registered' });
});

router.post('/login', async (req, res) => {
  const { email, password } = req.body;
  const user = await User.findOne({ email });
  if (!user || !(await bcrypt.compare(password, user.password)))
    return res.status(401).json({ error: 'Invalid credentials' });

  const token = jwt.sign({ id: user._id, role: user.role }, process.env.JWT_SECRET);
  res.json({ token });
});

module.exports = router;
Enter fullscreen mode Exit fullscreen mode

3. 学生管理

/models/Student.js

const mongoose = require('mongoose');

const studentSchema = new mongoose.Schema({
  name: String,
  age: Number,
  grade: String,
  parentContact: String,
});

module.exports = mongoose.model('Student', studentSchema);
Enter fullscreen mode Exit fullscreen mode

/routes/studentRoutes.js

const express = require('express');
const router = express.Router();
const Student = require('../models/Student');

router.get('/', async (req, res) => {
  const students = await Student.find();
  res.json(students);
});

router.post('/', async (req, res) => {
  const student = new Student(req.body);
  await student.save();
  res.status(201).json(student);
});

module.exports = router;
Enter fullscreen mode Exit fullscreen mode

4. 教师管理

/models/Teacher.js

const mongoose = require('mongoose');

const teacherSchema = new mongoose.Schema({
  name: String,
  subject: String,
  email: String,
  phone: String,
});

module.exports = mongoose.model('Teacher', teacherSchema);
Enter fullscreen mode Exit fullscreen mode

/routes/teacherRoutes.js

const express = require('express');
const router = express.Router();
const Teacher = require('../models/Teacher');

router.get('/', async (req, res) => {
  const teachers = await Teacher.find();
  res.json(teachers);
});

router.post('/', async (req, res) => {
  const teacher = new Teacher(req.body);
  await teacher.save();
  res.status(201).json(teacher);
});

module.exports = router;
Enter fullscreen mode Exit fullscreen mode

5. 课程安排

/models/Class.js

const mongoose = require('mongoose');

const classSchema = new mongoose.Schema({
  className: String,
  teacher: { type: mongoose.Schema.Types.ObjectId, ref: 'Teacher' },
  students: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Student' }],
  scheduleTime: String,
});

module.exports = mongoose.model('Class', classSchema);
Enter fullscreen mode Exit fullscreen mode

/routes/classRoutes.js

const express = require('express');
const router = express.Router();
const Class = require('../models/Class');

router.get('/', async (req, res) => {
  const classes = await Class.find().populate('teacher students');
  res.json(classes);
});

router.post('/', async (req, res) => {
  const newClass = new Class(req.body);
  await newClass.save();
  res.status(201).json(newClass);
});

module.exports = router;
Enter fullscreen mode Exit fullscreen mode

6. 考勤跟踪

/models/Attendance.js

const mongoose = require('mongoose');

const attendanceSchema = new mongoose.Schema({
  student: { type: mongoose.Schema.Types.ObjectId, ref: 'Student' },
  date: { type: Date, default: Date.now },
  status: { type: String, enum: ['present', 'absent'], default: 'present' },
});

module.exports = mongoose.model('Attendance', attendanceSchema);
Enter fullscreen mode Exit fullscreen mode

/routes/attendanceRoutes.js

const express = require('express');
const router = express.Router();
const Attendance = require('../models/Attendance');

router.post('/', async (req, res) => {
  const attendance = new Attendance(req.body);
  await attendance.save();
  res.status(201).json(attendance);
});

router.get('/:studentId', async (req, res) => {
  const records = await Attendance.find({ student: req.params.studentId });
  res.json(records);
});

module.exports = router;
Enter fullscreen mode Exit fullscreen mode

7. 前端集成(React)

/frontend/src/pages/Dashboard.js

import React, { useEffect, useState } from 'react';
import axios from 'axios';

const Dashboard = () => {
  const [students, setStudents] = useState([]);
  const [teachers, setTeachers] = useState([]);

  useEffect(() => {
    axios.get('http://localhost:5000/api/students').then(res => setStudents(res.data));
    axios.get('http://localhost:5000/api/teachers').then(res => setTeachers(res.data));
  }, []);

  return (
    <div>
      <h1>Dashboard</h1>

      <section>
        <h2>Students</h2>
        <ul>
          {students.map(s => (
            <li key={s._id}>{s.name} - Grade {s.grade}</li>
          ))}
        </ul>
      </section>

      <section>
        <h2>Teachers</h2>
        <ul>
          {teachers.map(t => (
            <li key={t._id}>{t.name} - {t.subject}</li>
          ))}
        </ul>
      </section>
    </div>
  );
};

export default Dashboard;
Enter fullscreen mode Exit fullscreen mode

8. 结论

该学校管理系统提供以下功能:

  • 基于角色的用户访问
  • 学生和教师的 CRUD 操作
  • 课程安排及其关系
  • 每位学生的出勤跟踪
  • 一个简洁的 React 前端将它们连接起来。

您可以使用Render(后端)和Netlify/Vercel(前端)部署此堆栈,并以 MongoDB Atlas 作为数据库。

对于生产级版本,请考虑:

  • 基于角色的访问中间件
  • 表单验证
  • 生成报告的 PDF 文件
  • 用于日程安排的日历用户界面

9. 作者及资源

作者: Dhanian
📚 购买我的电子书和代码项目:codewithdhanian.gumroad.com

欢迎您在这个项目的基础上进行拓展,用于学校项目、自由职业项目或创业项目。

文章来源:https://dev.to/code_2/how-to-build-a-school-management-system-a-complete-guide-with-code-snippets-1ln6