基于SpringBoot的宿舍管理系统
项目介绍
宿舍管理主要在各个中学和高校中经常提到。宿舍管理是后勤部门的一个重要工作。但是现在很多后勤部门都还是在使用最原始的宿舍管理方法。而且在学生入住的过程中学生住宿的信息得不到有效的更新,同时学生经常会更换宿舍等等。这样,无法保证学生住宿信息的完整性。也就是说现在没有一个很好的办法来管理学生的住宿信息。这也是后勤管理的一个缺陷。每个学校都会有自己的一套管理方法和管理制度。同时很多学校的管理方法都是大同小异。在宿舍管理过程中宿舍管理制度是一个依据,同时也是一种规范。每次新学期开始都会有很多新的面孔进入学校或者公司。他们的迎接安排工作也非常重要。在住宿过程中,很多时候学生或者员工会要求调整宿舍。他们可能出于不同的原因,在这个过程中很多合理的要求都会被楼管和宿舍管理部门所接受。当学生毕业或者员工离开的时候,需要做好宿舍信息的统计。统计还有多少宿舍铺位可以利用,已经有多少铺位被占用。每天都有很多的同学出入宿舍,宿舍的安全是楼层管理人员和学校非常关心的问题。在很多学校开始实行一卡通,这个也是防范意外发生的好方法。在公司中的出入管理就相对比较复杂,这些只能依靠门卫来处理。不管是员工宿舍还是学生宿舍,财务管理是重中之重。其中包括水费管理,电费管理,还可能包括维修费管理。在宿舍的管理过程中,宿舍建设管理是也是很重要的事情。但是在实际的宿舍管理过程中没有得到很好的重视。
系统人物职责介绍
超级管理员
超级管理员是宿舍管理过程中的核心人物。他要管理公共场所的卫生,还有监督学生宿舍建设。同时也是宿舍管理制度的执行者。
宿舍管理员
宿舍管理员在宿舍管理过程中起到了协助作用。他们协助宿舍管理部门,楼管执行宿舍管理中的査宿等等。
学生
在学校,学生是学校宿舍管理的主体。相对而言,在公司,员工的宿舍管理要适当放松,因为很多员工的生活习惯是不相同的。只有在共同的文化建设上下功夫,宿舍管理才能更好的实施。
数据库ER图
相关截图
登录
学生信息
处理报修
职工信息
个人信息
部分代码
数据库配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/dorm?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMTspring.datasource.username=rootspring.datasource.password=123456spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.mvc.view.prefix=/WEB-INF/view/spring.mvc.view.suffix=.jsp#是否显示SQLspring.jpa.show-sql=true
Maven依赖配置
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.shixin</groupId> <artifactId>dormitory-management</artifactId> <version>0.0.1-SNAPSHOT</version> <name>dormitory-management</name> <description>大学生宿舍管理系统</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--easypoi--> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-base</artifactId> <version>3.2.0</version> </dependency> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-web</artifactId> <version>3.2.0</version> </dependency> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-annotation</artifactId> <version>3.2.0</version> </dependency> <!-- tomcat支持 --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope></dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </pluginRepository> </pluginRepositories></project>
登录拦截
public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session = request.getSession(); UserExpand info = (UserExpand) session.getAttribute("LOGIN_USER"); if (info != null) { // 登录成功不拦截 return true; } else { response.sendRedirect(request.getContextPath() + "/login/toLogin"); return false; } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // TODO Auto-generated method stub HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // TODO Auto-generated method stub HandlerInterceptor.super.afterCompletion(request, response, handler, ex); }
视图层配置
@Overridepublic void addInterceptors(InterceptorRegistry registry) { InterceptorRegistration interceptor = registry.addInterceptor(loginInterceptor); interceptor.excludePathPatterns("/login/toLogin"); interceptor.excludePathPatterns("/login"); interceptor.excludePathPatterns("/static/"); interceptor.addPathPatterns("/");}@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/").addResourceLocations("classpath:/static/");}@Beanpublic InternalResourceViewResolver setupViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/view/"); resolver.setSuffix(".jsp"); return resolver;}
常用工具类
public class ExportExcelUtil { / * 下载 * * @param response HttpServletResponse * @param fileName 文件名 * @param workbook Workbook */ public static void downLoadExcel(HttpServletResponse response, String fileName, Workbook workbook) { try { response.setCharacterEncoding("UTF-8"); response.setHeader("content-Type", "application/vnd.ms-excel"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xls", "UTF-8")); workbook.write(response.getOutputStream()); } catch (Exception e) { e.printStackTrace(); } } / * 设置sum公式 * * @param wk Workbook * @param sumCol 合计 * @param itemCol 合计的项 */ public static void setSumFormula(Workbook wk, Character sumCol, Character... itemCol) { StringBuffer buffer = new StringBuffer(); Sheet sheet = wk.getSheetAt(0); Row row = null; for (int i = sheet.getFirstRowNum() + 2; i <= sheet.getLastRowNum(); i++) { row = sheet.getRow(i); for (Character item : itemCol) { CellAddress address = row.createCell(colCharToNum(item)).getAddress(); buffer.append(address + ":"); } String substring = buffer.toString().substring(0, buffer.toString().lastIndexOf(":")); row.createCell(colCharToNum(sumCol)).setCellFormula(String.format("sum(%s)", substring)); buffer.setLength(0); } } / * 列英文标识转数字列号 * * @param character char * @return */ private static Integer colCharToNum(Character character) { return (int) character - 65; }}
业务层(service)
@Overridepublic List<Stuinfo> findAll(UserExpand user) { if (user.getStaffinfo() != null) { Specification specification = (root, criteriaQuery, criteriaBuilder) -> criteriaBuilder.like(root.get("dormid"), user.getStaffinfo().getDormname() + user.getStaffinfo().getDormno() + "%"); return stuRepository.findAll(specification); } else { return stuRepository.findAll(); }}@Overridepublic Page<Stuinfo> findStus(Pageable pageable, UserExpand user, String searchId, String searchDormName) { if (user.getStaffinfo() != null) { return stuRepository.findAll(createSpe(searchId, searchDormName, user.getStaffinfo()), pageable); } else { return stuRepository.findAll(createSpe(searchId, searchDormName, null), pageable); }}public Specification createSpe(String searchId, String searchDormName, Staffinfo staffinfo) { List<Predicate> predicates = new ArrayList<>(); return (root, criteriaQuery, criteriaBuilder) -> { if (StringUtils.isNotEmpty(searchId)) { predicates.add(criteriaBuilder.equal(root.get("id"), searchId)); } if (StringUtils.isNotEmpty(searchDormName)) { predicates.add(criteriaBuilder.equal(root.get("grade"), searchDormName)); } if (null != staffinfo) { predicates.add(criteriaBuilder.like(root.get("dormid"), staffinfo.getDormname() + staffinfo.getDormno() + "%")); } predicates.add(criteriaBuilder.equal(root.get("status"), 0)); return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); };}@Override@Transactionalpublic Boolean importExcel(MultipartFile file) { try { List<Stuinfo> stuList = ExcelImportUtil.importExcel(file.getInputStream(), Stuinfo.class, new ImportParams()); stuRepository.saveAll(stuList); List<User> userList = stuList.stream().map(e -> { User user = new User(); user.setUsername(e.getId()); user.setPassword("123456"); user.setPermission(0); return user; }).collect(Collectors.toList()); userRepository.saveAll(userList); } catch (Exception e) { e.printStackTrace(); return false; } return true;}@Overridepublic Boolean leaveSchool(List<String> ids) { try { stuRepository.update(1, ids); } catch (Exception e2) { e2.printStackTrace(); return false; } return true;}@Overridepublic Boolean resetPwd(String stuId) { try { User user = userRepository.findByUsername(stuId); user.setPassword("123456"); userRepository.save(user); } catch (Exception e) { e.printStackTrace(); return false; } return true;}@Override@Transactionalpublic Boolean del(String stuId) { try { Stuinfo stuinfo = new Stuinfo(); stuinfo.setId(stuId); stuRepository.delete(stuinfo); User user = userRepository.findByUsername(stuId); userRepository.delete(user); } catch (Exception e) { e.printStackTrace(); return false; } return true;}@Overridepublic Boolean update(Stuinfo stuinfo) { try { stuRepository.save(stuinfo); } catch (Exception e) { e.printStackTrace(); return false; } return true;}@Overridepublic Boolean updatePhone(Stuinfo stuinfo) { try { stuRepository.updatePhone(stuinfo.getId(), stuinfo.getPhone()); } catch (Exception e) { e.printStackTrace(); return false; } return true;}
控制层(Controller)
@PostMapping("/exportInfo")public void exportInfo(HttpSession session, HttpServletResponse response) { UserExpand user = (UserExpand) session.getAttribute("LOGIN_USER"); List<Stuinfo> list = stuServiceI.findAll(user); Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("学生信息", "学生信息表1"), Stuinfo.class, list); ExportExcelUtil.downLoadExcel(response, "学生信息表", workbook);}@GetMapping("/infoView")public String getInfoView(HttpSession session, Model model) throws Exception { UserExpand user = (UserExpand) session.getAttribute("LOGIN_USER"); Stuinfo stuinfo = stuServiceI.findById(user.getUsername()); model.addAttribute("stuinfo", new ObjectMapper().writeValueAsString(stuinfo)); return "stu/infoView";}@GetMapping("/updatePwd")public String updatePwd(HttpSession session, Model model) { UserExpand user = (UserExpand) session.getAttribute("LOGIN_USER"); Stuinfo stuinfo = stuServiceI.findById(user.getUsername()); model.addAttribute("id", stuinfo.getId()); return "stu/updatePwd";}@PostMapping("/updatePhone")@ResponseBodypublic Boolean updatePhone(Stuinfo stuinfo) { return stuServiceI.updatePhone(stuinfo);}@PostMapping("/updatePwd")@ResponseBodypublic Boolean updatePwd(String id, String oldPwd, String newPwd) { return stuServiceI.updatePwd(id, oldPwd, newPwd);}@GetMapping("/list")@ResponseBodypublic Page<Stuinfo> getStuInfo(@PageableDefault Pageable pageable, HttpSession session, String searchId, String searchDormName) { UserExpand user = (UserExpand) session.getAttribute("LOGIN_USER"); return stuServiceI.findStus(pageable, user, searchId, searchDormName);}@PostMapping("/importExcel")@ResponseBodypublic Boolean importExcel(@RequestParam("file") MultipartFile file) { return stuServiceI.importExcel(file);}@PostMapping("/leaveSchool")@ResponseBodypublic Boolean leaveSchool(@RequestBody(required = true) List<String> ids) { return stuServiceI.leaveSchool(ids);}@GetMapping("/resetPwd")@ResponseBodypublic Boolean resetPwd(String stuId) { return stuServiceI.resetPwd(stuId);}
视图层(View)
//初始化Tablefunction tableInit() { $('#tb_repairHistory').bootstrapTable({ url : '/stu/repairHistory', //请求后台的URL(*) method : 'get', //请求方式(*) cache : false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*) clickToSelect:true, sortable : true, //是否启用排序 sortOrder : "asc", //排序方式 sidePagination : "server", //分页方式:client客户端分页,server服务端分页(*) pagination : true, //是否显示分页(*) pageNumber : 1, //初始化加载第一页,默认第一页 pageSize : 10, //每页的记录行数(*) pageList : [10, 25, 50], //可供选择的每页的行数(*) uniqueId : 'dormid', //每一行的唯一标识,一般为主键列 sortName: 'dormid', // 要排序的字段 queryParams : function(params) { return { size: params.limit, // 每页要显示的数据条数 page: params.offset/params.limit, //pageable 下标从0开始 sort: params.sort + "," + params.order // 排序规则 } },//传递参数(*) responseHandler: function(res) { return {total : res.totalElements, //总页数,前面的key必须为"total"rows : res.content//行数据,前面的key要与之前设置的dataField的值一致. }; }, columns : [ { field : 'id', visible:false }, { field : 'dormid', title : '宿舍号', sortable : true }, { field : 'reason', title : '报修类型', formatter: function (value,row,index) { var result=""; if (value == 0) { result = "灯"; }else if(value == 1) { result = "床,桌椅"; }else if(value == 2) { result = "门窗"; }else if (value == 3){ result = "其它"; } return result; } }, { field : 'date', title : '报修时间', sortable : true, formatter: function (value,row,index) { if (value != null) { var date = new Date(value); return dateFtt("yyyy-MM-dd hh:mm",date);} } },{ field : 'note', title : '说明' },{ field : 'status', title : '状态', formatter: function (value,row,index) { var result=""; if (value == 2) { result = "处理完成"; } return result; } }] }); };/ * 时间格式化处理 */function dateFtt(fmt,date) { var o = { "M+" : date.getMonth()+1, //月份 "d+" : date.getDate(), //日 "h+" : date.getHours(), //小时 "m+" : date.getMinutes(), //分 "s+" : date.getSeconds(), //秒 "q+" : Math.floor((date.getMonth()+3)/3), //季度 "S" : date.getMilliseconds() //毫秒 }; if(/(y+)/.test(fmt))fmt=fmt.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length)); for(var k in o)if(new RegExp("("+ k +")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length))); return fmt; }</script></html>