使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目

今天给大家分享一个我最近做的一个学校宿舍管理系统,python版,这个系统实现的功能有:首页 | 学校管理 | 宿舍楼管理 | 宿舍管理 | 学生管理 | 学生调宿 | 学生退宿 | 报修等级 | 宿舍卫生评分 | 违纪记录 | 管理员管理 。一共有11个菜单。

使用的技术:

编程语言:python

后端框架: fastApi

前端:vue2

为了加强自己对python编程的理解,最近写了大量的python相关的项目。今天就先来分享这个宿舍管理系统。 先给大家看一下页面效果:

首页:

学生调宿:

卫生评分:

学生退宿:

代码量还是有的,如果你是刚刚开始学习编程,需要相关的练习项目,希望这个项目能帮助到你,可以仿照着这个项目,自己尝试着手敲一下。项目源码我打包好了,有兴趣的可以去看看。~ (非开源) wwwoop.com/home/Index/...

部分代码:

python 复制代码
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session, joinedload
from sqlalchemy import and_, func
from typing import Optional
from datetime import datetime
import math

from core.deps import get_db, get_current_admin
from core.response import ResponseModel
from core.exceptions import CustomException
from models.repair_registration import RepairRegistration
from models.dormitory_building import DormitoryBuilding
from models.dormitory import Dormitory
from models.admin import Admin
from schemas.repair_registration import (
    RepairRegistrationCreate,
    RepairRegistrationUpdate,
    RepairRegistrationResponse,
    RepairRegistrationListResponse,
    BuildingOption,
    DormitoryOption
)

router = APIRouter()


@router.get("/list", response_model=dict)
def get_repair_registration_list(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(10, ge=1, le=100, description="每页数量"),
    reporter_name: Optional[str] = Query(None, description="报修人姓名"),
    db: Session = Depends(get_db),
    current_admin: Admin = Depends(get_current_admin)
):
    """获取报修登记列表"""
    try:
        # 构建查询
        query = db.query(RepairRegistration).options(
            joinedload(RepairRegistration.building),
            joinedload(RepairRegistration.dormitory)
        ).filter(RepairRegistration.is_deleted == 0)
        
        # 添加搜索条件
        if reporter_name:
            query = query.filter(
                RepairRegistration.reporter_name.like(f"%{reporter_name}%")
            )
        

        
        # 按创建时间倒序排列
        query = query.order_by(RepairRegistration.created_time.desc())
        
        # 获取总数
        total = query.count()
        
        # 分页查询
        offset = (page - 1) * page_size
        items = query.offset(offset).limit(page_size).all()
        

        
        # 构建响应数据
        repair_list = []
        for repair in items:
            # 时间格式化
            created_time = repair.created_time.strftime("%Y-%m-%d %H:%M:%S") if repair.created_time else None
            updated_time = repair.updated_time.strftime("%Y-%m-%d %H:%M:%S") if repair.updated_time else None
            expected_repair_time = repair.expected_repair_time.strftime("%Y-%m-%d %H:%M:%S") if repair.expected_repair_time else None
            
            repair_list.append({
                "id": repair.id,
                "reporter_name": repair.reporter_name,
                "reporter_phone": repair.reporter_phone,
                "building_id": repair.building_id,
                "building_name": repair.building.building_name if repair.building else None,
                "dormitory_id": repair.dormitory_id,
                "dormitory_name": repair.dormitory.dormitory_name if repair.dormitory else None,
                "dormitory_number": repair.dormitory.dormitory_number if repair.dormitory else None,
                "repair_content": repair.repair_content,
                "remark": repair.remark,
                "expected_repair_time": expected_repair_time,

                "created_time": created_time,
                "updated_time": updated_time
            })
        
        # 计算总页数
        total_pages = math.ceil(total / page_size) if total > 0 else 1
        
        return ResponseModel.success(data={
            "items": repair_list,
            "total": total,
            "page": page,
            "page_size": page_size,
            "total_pages": total_pages
        })
        
    except Exception as e:
        raise CustomException(msg=f"获取报修登记列表失败: {str(e)}")


@router.get("/detail/{repair_id}", response_model=dict)
def get_repair_registration_detail(
    repair_id: int,
    db: Session = Depends(get_db),
    current_admin: Admin = Depends(get_current_admin)
):
    """获取报修登记详情"""
    try:
        # 查询报修登记信息
        repair = db.query(RepairRegistration).options(
            joinedload(RepairRegistration.building),
            joinedload(RepairRegistration.dormitory)
        ).filter(
            RepairRegistration.id == repair_id,
            RepairRegistration.is_deleted == 0
        ).first()
        
        if not repair:
            raise CustomException(msg="报修登记不存在")
        

        
        # 时间格式化
        created_time = repair.created_time.strftime("%Y-%m-%d %H:%M:%S") if repair.created_time else None
        updated_time = repair.updated_time.strftime("%Y-%m-%d %H:%M:%S") if repair.updated_time else None
        expected_repair_time = repair.expected_repair_time.strftime("%Y-%m-%d %H:%M:%S") if repair.expected_repair_time else None
        
        return ResponseModel.success(data={
            "id": repair.id,
            "reporter_name": repair.reporter_name,
            "reporter_phone": repair.reporter_phone,
            "building_id": repair.building_id,
            "building_name": repair.building.building_name if repair.building else None,
            "dormitory_id": repair.dormitory_id,
            "dormitory_name": repair.dormitory.dormitory_name if repair.dormitory else None,
            "dormitory_number": repair.dormitory.dormitory_number if repair.dormitory else None,
            "repair_content": repair.repair_content,
            "remark": repair.remark,
            "expected_repair_time": expected_repair_time,

            "created_time": created_time,
            "updated_time": updated_time
        })
        
    except CustomException:
        raise
    except Exception as e:
        raise CustomException(msg=f"获取报修登记详情失败: {str(e)}")


@router.post("/create", response_model=dict)
def create_repair_registration(
    repair_data: RepairRegistrationCreate,
    db: Session = Depends(get_db),
    current_admin: Admin = Depends(get_current_admin)
):
    """创建报修登记"""
    try:
        # 验证宿舍楼是否存在
        building = db.query(DormitoryBuilding).filter(
            DormitoryBuilding.id == repair_data.building_id,
            DormitoryBuilding.is_deleted == 0
        ).first()
        if not building:
            raise CustomException(msg="宿舍楼不存在")
        
        # 验证宿舍是否存在且属于指定宿舍楼
        dormitory = db.query(Dormitory).filter(
            Dormitory.id == repair_data.dormitory_id,
            Dormitory.building_id == repair_data.building_id,
            Dormitory.is_deleted == 0
        ).first()
        if not dormitory:
            raise CustomException(msg="宿舍不存在或不属于指定宿舍楼")
        
        # 创建报修登记
        repair = RepairRegistration(
            reporter_name=repair_data.reporter_name,
            reporter_phone=repair_data.reporter_phone,
            building_id=repair_data.building_id,
            dormitory_id=repair_data.dormitory_id,
            repair_content=repair_data.repair_content,
            remark=repair_data.remark,
            expected_repair_time=repair_data.expected_repair_time,
            created_id=current_admin.id,
            updated_id=current_admin.id
        )
        
        db.add(repair)
        db.commit()
        db.refresh(repair)
        
        return ResponseModel.success(msg="报修登记创建成功")
        
    except CustomException:
        raise
    except Exception as e:
        db.rollback()
        raise CustomException(msg=f"创建报修登记失败: {str(e)}")


@router.get("/building-options", response_model=dict)
def get_building_options(
    db: Session = Depends(get_db),
    current_admin: Admin = Depends(get_current_admin)
):
    """获取宿舍楼选项"""
    try:
        buildings = db.query(DormitoryBuilding).filter(
            DormitoryBuilding.is_deleted == 0
        ).order_by(DormitoryBuilding.building_name).all()
        
        options = [
            {
                "value": building.id,
                "label": building.building_name
            }
            for building in buildings
        ]
        
        return ResponseModel.success(data=options)
        
    except Exception as e:
        raise CustomException(msg=f"获取宿舍楼选项失败: {str(e)}")


@router.get("/dormitory-options", response_model=dict)
def get_dormitory_options(
    building_id: Optional[int] = Query(None, description="宿舍楼ID"),
    db: Session = Depends(get_db),
    current_admin: Admin = Depends(get_current_admin)
):
    """获取宿舍选项"""
    try:
        query = db.query(Dormitory).filter(Dormitory.is_deleted == 0)
        
        if building_id:
            query = query.filter(Dormitory.building_id == building_id)
        
        dormitories = query.order_by(Dormitory.dormitory_number).all()
        
        options = [
            {
                "value": dormitory.id,
                "label": f"{dormitory.dormitory_number} - {dormitory.dormitory_name}",
                "building_id": dormitory.building_id
            }
            for dormitory in dormitories
        ]
        
        return ResponseModel.success(data=options)
        
    except Exception as e:
        raise CustomException(msg=f"获取宿舍选项失败: {str(e)}")
相关推荐
ytadpole1 小时前
Java 25 新特性 更简洁、更高效、更现代
java·后端
风一样的树懒2 小时前
死信队列:你在正确使用么?
后端
RoyLin2 小时前
TypeScript设计模式:门面模式
前端·后端·typescript
JavaGuide2 小时前
JDK 25(长期支持版) 发布,新特性解读!
java·后端
weiwenhao3 小时前
关于 nature 编程语言
人工智能·后端·开源
薛定谔的算法3 小时前
phoneGPT:构建专业领域的检索增强型智能问答系统
前端·数据库·后端
RoyLin3 小时前
TypeScript设计模式:责任链模式
前端·后端·typescript
RoyLin3 小时前
TypeScript设计模式:装饰器模式
前端·后端·typescript
Java中文社群3 小时前
有点意思!Java8后最有用新特性排行榜!
java·后端·面试