1. 项目概述
作为一名长期从事高校信息化建设的开发者,我深知传统宿舍管理模式的痛点。手工登记本、Excel表格、纸质审批单...这些落后的管理方式不仅效率低下,还容易造成数据丢失和统计错误。去年为某高校开发这套宿舍管理系统时,宿管老师向我展示的"传家宝"——一本已经翻烂的登记簿,更加坚定了我开发这个系统的决心。
本系统采用主流的前后端分离架构,前端使用Vue.js+ElementUI构建响应式界面,后端基于SpringBoot提供RESTful API服务,数据层采用MyBatis+MySQL组合。系统包含五大核心模块:学生信息管理、宿舍分配、费用管理、报修服务和访客登记,支持学生、宿管员、管理员三级权限控制。特别在安全性方面,我们采用JWT+RBAC实现细粒度的权限管理。
2. 技术架构解析
2.1 前端技术栈选型
选择Vue.js 3.x作为前端框架主要基于三点考虑:
- 组件化开发模式完美契合管理系统模块化需求
- 响应式特性可适配宿管办公室的各种终端设备
- 丰富的生态系统(特别是ElementUI)能快速构建管理后台界面
实际开发中,我们采用如下技术组合:
- Vue Router实现多级路由导航
- Axios封装HTTP请求拦截器
- Vuex管理全局状态(如用户权限信息)
- ECharts可视化展示宿舍入住率等数据
提示:前端项目建议使用Vite作为构建工具,相比Webpack启动速度快10倍以上,特别适合需要频繁调试的管理系统开发。
2.2 后端技术架构
SpringBoot 2.7.x作为后端框架,其优势在于:
- 自动配置简化了传统SSM框架的繁琐配置
- 内嵌Tomcat服务器方便部署
- Actuator端点提供系统健康监控
核心依赖配置示例(pom.xml关键片段):
xml复制<dependencies>
<!-- Web支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis整合 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 安全认证 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
2.3 数据库设计精要
2.3.1 学生住宿信息表优化
原始设计中的stu_id字段建议改为字符串类型,因为:
- 学号通常包含字母前缀(如"STU20230001")
- 避免数值溢出风险(BIGINT最大值为2^63-1)
- 更符合业务实际场景
改进后的DDL语句:
sql复制CREATE TABLE `student_dorm` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`stu_id` VARCHAR(20) NOT NULL COMMENT '学号',
`stu_name` VARCHAR(50) NOT NULL,
`dorm_number` VARCHAR(20) NOT NULL COMMENT '宿舍编号',
`building_name` VARCHAR(30) NOT NULL,
`check_in_date` DATE NOT NULL,
`status` TINYINT DEFAULT 1 COMMENT '0-退宿 1-在住',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_stu_id` (`stu_id`),
KEY `idx_dorm` (`building_name`, `dorm_number`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2.3.2 报修记录表增强
增加以下字段提升业务完整性:
imagesVARCHAR(255) 存储报修图片URLcontact_phoneVARCHAR(20) 联系电话emergency_levelTINYINT 紧急程度(1-5级)
3. 核心功能实现
3.1 JWT认证实现
安全认证流程:
- 用户登录成功后生成JWT令牌
- 前端存储令牌于localStorage
- 每次请求携带Authorization头
- 服务端通过拦截器验证令牌
核心代码示例:
java复制// JWT工具类
public class JwtUtil {
private static final String SECRET_KEY = "dorm-secret-2023";
private static final long EXPIRATION = 86400000; // 24小时
public static String generateToken(UserDetails user) {
return Jwts.builder()
.setSubject(user.getUsername())
.claim("roles", user.getAuthorities())
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public static boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
return true;
} catch (Exception e) {
log.error("JWT验证失败: {}", e.getMessage());
return false;
}
}
}
3.2 动态路由实现
根据用户角色动态生成前端路由:
javascript复制// 路由守卫
router.beforeEach(async (to, from, next) => {
const hasToken = localStorage.getItem('token');
if (hasToken) {
if (to.path === '/login') {
next('/dashboard');
} else {
const hasRoles = store.getters.roles && store.getters.roles.length > 0;
if (hasRoles) {
next();
} else {
try {
const { roles } = await store.dispatch('user/getInfo');
const accessRoutes = await store.dispatch('permission/generateRoutes', roles);
accessRoutes.forEach(route => {
router.addRoute(route);
});
next({ ...to, replace: true });
} catch (error) {
await store.dispatch('user/resetToken');
next(`/login?redirect=${to.path}`);
}
}
}
} else {
/* 未登录处理 */
}
});
4. 部署实战指南
4.1 后端部署
推荐使用Docker Compose部署:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: dorm
ports:
- "3306:3306"
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/dorm
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: root123
4.2 前端部署
Nginx配置示例:
nginx复制server {
listen 80;
server_name dorm.example.com;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://backend:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
5. 踩坑经验分享
5.1 MyBatis批量插入优化
初期使用foreach循环插入性能极差,200条数据需要8秒。优化方案:
xml复制<insert id="batchInsert" useGeneratedKeys="true" keyProperty="id">
INSERT INTO repair_record
(stu_id, repair_type, description)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.stuId}, #{item.repairType}, #{item.description})
</foreach>
</insert>
同时需要在JDBC URL添加参数:
code复制rewriteBatchedStatements=true&allowMultiQueries=true
5.2 Vue性能优化
发现宿舍列表页渲染卡顿,通过以下措施优化:
- 使用
v-virtual-scroll实现虚拟滚动 - 复杂计算属性用
computed缓存 - 图片懒加载:
<img v-lazy="imageUrl">
6. 扩展功能建议
- 微信小程序端:开发配套小程序,方便学生随时提交报修、查询访客记录
- 数据大屏:使用Apache ECharts构建宿舍管理数据可视化大屏
- 智能分配算法:基于学生专业、班级等属性实现自动化宿舍分配
- 物联网集成:对接门禁系统实现刷脸进出记录
我在实际部署中发现,系统高峰期(如开学季)的并发请求会暴增至平时的5倍。建议在SpringBoot中配置Tomcat线程池:
properties复制server.tomcat.max-threads=200
server.tomcat.min-spare-threads=20
对于中小规模高校(学生数<1万),使用2核4G的云服务器即可平稳运行。如果预算允许,建议将MySQL单独部署,并配置主从复制保障数据安全。