欢迎光临
我们一直在努力

【免费】基于Python的校园宿舍管理系统(FastAPI+Vue3) 适合python毕业设计 FastAPI源码 python课程设计 锋哥原创出品,必属精品

大家好,我是Java1234_小锋老师,分享一套锋哥原创的基于Python的校园宿舍管理系统(FastAPI+Vue3) 。

项目介绍

高校学生规模持续扩大,宿舍作为学生学习与生活的基本场所,其管理质量直接关系到校园秩序与学生满意度。传统宿舍管理多依赖纸质台账和分散的电子表格,存在信息更新滞后、床位占用情况不清、报修流转效率低、水电缴费难以核对等问题。为提升宿舍管理的信息化水平,本文设计并实现了一套基于Python的校园宿舍管理系统。

系统采用前后端分离架构。后端以Python语言为基础,使用FastAPI构建RESTful接口,结合SQLAlchemy完成对象关系映射,使用JWT实现统一身份认证;前端采用Vue 3、Vue Router、Pinia和Element Plus实现单页应用,并利用ECharts完成首页数据可视化。数据库选用MySQL 8,数据库名为db_dormitory,业务表统一以t_开头。系统面向管理员、宿管员和学生三类角色,覆盖宿舍楼与房间管理、学生与宿管员管理、入住分配、调宿申请、退宿登记、报修处理、水电费管理、卫生检查、晚归登记、公告通知以及个人中心等功能。

系统在业务层引入宿舍占用服务,对性别限制、床位占用、宿舍满员和停用状态进行统一校验,保证入住、调宿和退宿过程中床位数据的一致性。测试结果表明,系统功能完整、流程清晰,能够满足本科毕业设计对实用性与规范性的要求,也可作为高校宿舍日常管理的信息化参考方案。

源码下载

链接: https://pan.baidu.com/s/1lQzCeoMdznEc8_wiHBn81g?pwd=1234 提取码: 1234

系统展示

核心代码

"""宿舍楼控制器"""
from typing import Optional

from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session

from common.context import UserContext
from common.exceptions import BusinessException
from common.result import success
from database import get_db
from models import Building
from utils.helpers import apply_updates, camel_to_snake_dict, convert_row, model_to_dict, now

router = APIRouter(prefix="/building", tags=["宿舍楼"])

@router.get("/list")
def list_building(keyword: Optional[str] = None, db: Session = Depends(get_db)):
"""查询宿舍楼列表"""
where = " WHERE 1 = 1"
params = {}
if keyword:
where += " AND (b.name LIKE CONCAT('%', :keyword, '%') OR b.address LIKE CONCAT('%', :keyword, '%'))"
params["keyword"] = keyword
sql = (
"SELECT b.*, a.nickname AS managerName, "
"(SELECT COUNT(*) FROM t_dorm d WHERE d.building_id = b.id) AS dormCount, "
"(SELECT IFNULL(SUM(d.live_count), 0) FROM t_dorm d WHERE d.building_id = b.id) AS liveCount, "
"(SELECT IFNULL(SUM(d.bed_count), 0) FROM t_dorm d WHERE d.building_id = b.id) AS bedCount "
"FROM t_building b LEFT JOIN t_admin a ON b.manager_id = a.id"
+ where + " ORDER BY b.id ASC"
)
from sqlalchemy import text
rows = [convert_row(r) for r in db.execute(text(sql), params).mappings().all()]
if UserContext.is_manager() and UserContext.get_building_id() is not None:
bid = UserContext.get_building_id()
rows = [b for b in rows if b.get("id") == bid]
return success(rows)

@router.post("")
def add(body: dict, db: Session = Depends(get_db)):
"""新增宿舍楼"""
data = camel_to_snake_dict(body)
building = Building()
apply_updates(building, data)
if building.gender_limit is None or building.gender_limit == "":
building.gender_limit = "男"
building.create_time = now()
db.add(building)
db.flush()
return success()

@router.put("")
def update(body: dict, db: Session = Depends(get_db)):
"""修改宿舍楼"""
data = camel_to_snake_dict(body)
building = db.get(Building, data.get("id"))
if building is None:
raise BusinessException("宿舍楼不存在")
apply_updates(building, data)
return success()

@router.delete("/{ids}")
def delete(ids: str, db: Session = Depends(get_db)):
"""删除宿舍楼"""
id_list = [int(x) for x in ids.split(",") if x]
db.query(Building).filter(Building.id.in_(id_list)).delete(synchronize_session=False)
return success()

@router.get("/{id}")
def get_one(id: int, db: Session = Depends(get_db)):
"""根据ID查询宿舍楼"""
building = db.get(Building, id)
if building is None:
raise BusinessException("宿舍楼不存在")
return success(model_to_dict(building))

<template>
<div class="page-card">
<div class="search-bar">
<el-input v-model="query.keyword" placeholder="用户名/昵称/手机号" clearable style="max-width: 220px;" @keyup.enter="load" />
<el-button type="primary" @click="load">查询</el-button>
<el-button type="success" @click="openEdit()">新增</el-button>
</div>
<el-table :data="list" border class="table-wrap" show-overflow-tooltip>
<el-table-column prop="username" label="用户名" min-width="120" />
<el-table-column prop="nickname" label="昵称" min-width="110" />
<el-table-column prop="gender" label="性别" min-width="70" />
<el-table-column prop="phone" label="手机号" min-width="120" />
<el-table-column prop="buildingName" label="负责楼栋" min-width="140" />
<el-table-column label="状态" min-width="80">
<template #default="{ row }">{{ row.status === 1 ? '启用' : '禁用' }}</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" min-width="170" />
<el-table-column label="操作" min-width="140">
<template #default="{ row }">
<el-button link type="primary" @click="openEdit(row)">编辑</el-button>
<el-button link type="danger" @click="remove(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="pager">
<el-pagination background layout="total, prev, pager, next" :total="total" v-model:current-page="query.pageNum" :page-size="query.pageSize" @current-change="load" />
</div>
<el-dialog v-model="visible" :title="form.id ? '编辑宿管员' : '新增宿管员'" width="520px">
<el-form :model="form" label-width="90px">
<el-form-item label="用户名"><el-input v-model="form.username" /></el-form-item>
<el-form-item v-if="!form.id" label="密码"><el-input v-model="form.password" placeholder="默认123456" /></el-form-item>
<el-form-item label="昵称"><el-input v-model="form.nickname" /></el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="form.gender">
<el-radio value="男">男</el-radio>
<el-radio value="女">女</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="手机号"><el-input v-model="form.phone" /></el-form-item>
<el-form-item label="负责楼栋">
<el-select v-model="form.buildingId" clearable style="width: 100%;">
<el-option v-for="b in buildings" :key="b.id" :label="b.name" :value="b.id" />
</el-select>
</el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio :value="1">启用</el-radio>
<el-radio :value="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="save">保存</el-button>
</template>
</el-dialog>
</div>
</template>

<script setup>
import { onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { adminPage, adminAdd, adminUpdate, adminDelete, buildingList } from '@/api'

const query = reactive({ pageNum: 1, pageSize: 10, keyword: '', role: 2 })
const list = ref([])
const total = ref(0)
const buildings = ref([])
const visible = ref(false)
const form = reactive({})

onMounted(async () => {
buildings.value = (await buildingList()).data
load()
})

async function load() {
const res = await adminPage(query)
list.value = res.data.records
total.value = res.data.total
}

function openEdit(row) {
Object.keys(form).forEach((k) => delete form[k])
Object.assign(form, row ? { …row } : { role: 2, gender: '男', status: 1, password: '123456' })
visible.value = true
}

async function save() {
form.role = 2
if (form.id) await adminUpdate(form)
else await adminAdd(form)
ElMessage.success('保存成功')
visible.value = false
load()
}

function remove(row) {
ElMessageBox.confirm('确定删除该宿管员吗?', '提示', { type: 'warning' }).then(async () => {
await adminDelete(row.id)
ElMessage.success('删除成功')
load()
}).catch(() => {})
}
</script>

赞(0)
未经允许不得转载:171主机测评 » 【免费】基于Python的校园宿舍管理系统(FastAPI+Vue3) 适合python毕业设计 FastAPI源码 python课程设计 锋哥原创出品,必属精品
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址