基于javaweb+mysql的springboot教室图书馆预约管理系统(java+springboot+jpa+vue+maven+mysql)
私信源码获取及调试交流
运行环境
Java≥8、MySQL≥5.7、Node.js≥10
开发工具
后端:eclipse/idea/myeclipse/sts等均可配置运行
前端:WebStorm/VSCode/HBuilderX等均可
适用
课程设计,大作业,毕业设计,项目练习,学习演示等
功能说明
基于javaweb的SpringBoot教室图书馆预约管理系统(java+springboot+jpa+vue+maven+mysql)
项目简介:
这是一个前后端分离的教室预约和查看系统项目,能够实现以教室为单位活动的预约和取消,能够以视图形式显示,附带图书馆和公告管理器功能。
主要采用Vue.js
+SpringBoot
技术栈开发
使用技术点
- 前端:
Vue
、ElementUI
、axios
、Echart
、jQurey
* 后端:SpringBoot
、Spring Data + JPA
、hibernate
、MySQL
、Shiro
使用说明:
- 在mysql数据库中创建数据库
testmeeting
行项目,将自动注入数据。如需关闭此功能,请将application.properties
中的spring.datasource.initialization-mode=always
代码注释。同样,可以通过使用项目sql
目录下testmeeting
直接导入数 据库数据结构与内容,可根据需要自行使用。2. 数据库配置在后端项目的 src\main\resources 目录下的application.properties 文件中,mysql 版本为 8.0以上版本 。 3. 在IntelliJ IDEA中运行后端项目,为了保证项目成功运行,可以右键点击 pom.xml 选择 maven -> reimport ,并重启项目。 至此,服务端就启动成功了,同时,运行前端项目,访问 http://localhost:8080 ,即可进入登录页面,默认账号是 admin,密码是 123 4. 项目使用了虹软公司的人脸识别SDK与百度的人体分析SDk: * 虹软的SDK请自行前往官网获取,获取后建议将SDK导入到src/main/resources/lib-sdk
目录下,然后在src/main/java/utils
目录下新建SdkParameter.java
文件,填入appId和key以及引擎和算法等文件位置。 * 百度人体分析SDk已在maven
中引用,但是app_id
等请前往百度云AI开发者平台自行获取,该项目中表示位置为SdkParameter.java
文件。 * 以上内容不必要,可以删除并注释对应接口与服务即可。 ----
二次开发请注意:
- 进入前端项目根目录中,在命令行依次输入如下命令:
text # 安装依赖 npm install # 在 localhost:8080 启动项目 npm run dev
* 由于在前端项目中已经配置了端口转发,将数据转发到SpringBoot上,因此项目启动之后,在浏览器中输入http://localhost:8080
就可以访问我们的前端项目了,所有的请求通过端口转发将数据传到 SpringBoot 中(注意此时不要关闭 SpringBoot 项目)。 * 最后可以用 IDEA / WebStorm 等工具打开前端项目,继续开发,开发完成后,当项目要上线时,依然进入到 wj-vue 目录,然后执行如下命令:text npm run build
* 该命令执行成功之后,前端项目目录下生成一个dist
文件夹,可以将该文件夹中的两个文件static
和index.html
拷贝到前端项目中resources/static/
目录下,然后直接运行前端项目,访问http://localhost:8443
,
实际上是把前端打包后作为静态文件,但不推荐使用这种方式。
@Log4j2
public class URLPathMatchingFilter extends PathMatchingFilter {
@Autowired
AdminPermissionService adminPermissionService;
@Override
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
if (HttpMethod.OPTIONS.toString().equals((httpServletRequest).getMethod())) {
httpServletResponse.setStatus(HttpStatus.NO_CONTENT.value());
return true;
}
if (null == adminPermissionService) {
adminPermissionService = SpringContextUtils.getContext().getBean(AdminPermissionService.class);
}
String requestAPI = getPathWithinApplication(request);
Subject subject = SecurityUtils.getSubject();
if (!subject.isAuthenticated()) {
// log.info("未登录用户尝试访问需要登录的接口");
return false;
}
// 判断访问接口是否需要过滤(数据库中是否有对应信息)
boolean needFilter = adminPermissionService.needFilter(requestAPI);
if (!needFilter) {
return true;
} else {
// 判断当前用户是否有相应权限
boolean hasPermission = false;
String username = subject.getPrincipal().toString();
public Result getUnusedCount(){
return ResultFactory.buildSuccessResult(classRoomService.CountByUsedClassRoom(-1));
}
/**
* 获取没有预约的房间
* @return 封装的房间
*/
@CrossOrigin
@RequestMapping("/rooms/usable-rooms")
public Result getUsableRooms(){
return ResultFactory.buildSuccessResult(classRoomService.findAllUsableRooms(0));
}
/**
* 修改指定的房间数据
* @return 修改结果
*/
@CrossOrigin
@RequestMapping("/rooms/update")
public String update(){
return classRoomService.update(3L,classRoomService.getById(3L))!=null?"sec":"fal";
}
/**
* 获取不同的分类的房间
* @param capacity 分类的依据:房间容纳人数
* @return 教室列表
*/
@CrossOrigin
@RequestMapping("/rooms/capacity/{capacity}/rooms")
public Iterable<ClassRoom> findAllByCapacity(@PathVariable("capacity") int capacity){
System.out.println(capacity);
if (0==capacity){
return classRoomService.getAll();
}else {
return classRoomService.findAllByCapacity(capacity);
}
// @GetMapping("/api/admin/user")
// public Iterable<Student> listUsers() {
// return studentService.list();
// }
//
// @CrossOrigin
// @ResponseBody
// @PostMapping("/api/admin/user/status")
// public Result updateUserStatus(@RequestBody Student requestStudent) {
// if (studentService.updateStudentStatus(requestStudent)) {
// return ResultFactory.buildSuccessResult("用户状态更新成功");
// } else {
// return ResultFactory.buildFailResult("参数错误,更新失败");
// }
// }
// @CrossOrigin
// @ResponseBody
// @PostMapping("/api/admin/user/password")
// public Result resetPassword(@RequestBody Student requestStudent) {
// if (studentService.resetPassword(requestStudent)) {
// return ResultFactory.buildSuccessResult("重置密码成功");
// } else {
// return ResultFactory.buildFailResult("参数错误,重置失败");
// }
// }
//
// @CrossOrigin
// @ResponseBody
// @PostMapping("/api/admin/user")
// public Result editUser(@RequestBody Student requestStudent) {
// if(studentService.editUser(requestStudent)) {
// return ResultFactory.buildSuccessResult("修改用户信息成功");
// } else {
// return ResultFactory.buildFailResult("参数错误,修改失败");
// }
// }
}
* @return 成功认证的消息字符串
*/
@GetMapping("/api/authentication")
public String authentication() {
return "身份认证成功";
}
/**
* 通过登录用户名查找用户账号
* @param requestUser 用户身份凭据
* @return 封装的用户名
*/
@CrossOrigin
@RequestMapping("/api/info/username")
public Result loggedUserUsername(@RequestBody User requestUser) {
String username = HtmlUtils.htmlEscape(requestUser.getUsername());
return ResultFactory.buildSuccessResult(userService.findByUsername(username).getUsername());
}
/**
* 通过登录用户查找用户姓名
* @param requestUser 用户身份凭据
* @return 封装的用户姓名
*/
@CrossOrigin
@RequestMapping("/api/info/name")
public Result loggedUserName(@RequestBody User requestUser) {
String username = HtmlUtils.htmlEscape(requestUser.getUsername());
return ResultFactory.buildSuccessResult(userService.findByUsername(username).getName());
}
}
@Log4j2
public class URLPathMatchingFilter extends PathMatchingFilter {
@Autowired
AdminPermissionService adminPermissionService;
@Override
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
if (HttpMethod.OPTIONS.toString().equals((httpServletRequest).getMethod())) {
httpServletResponse.setStatus(HttpStatus.NO_CONTENT.value());
return true;
}
if (null == adminPermissionService) {
adminPermissionService = SpringContextUtils.getContext().getBean(AdminPermissionService.class);
}
String requestAPI = getPathWithinApplication(request);
Subject subject = SecurityUtils.getSubject();
if (!subject.isAuthenticated()) {
// log.info("未登录用户尝试访问需要登录的接口");
return false;
}
// 判断访问接口是否需要过滤(数据库中是否有对应信息)
boolean needFilter = adminPermissionService.needFilter(requestAPI);
if (!needFilter) {
return true;
} else {
// 判断当前用户是否有相应权限
boolean hasPermission = false;
String username = subject.getPrincipal().toString();
Set<String> permissionAPIs = adminPermissionService.listPermissionURLsByUser(username);
for (String api : permissionAPIs) {
// 匹配前缀
if (requestAPI.startsWith(api)) {
hasPermission = true;
break;
}
}
/**
* 检查教室是否用占用,进行状态检查并修改-重新封装模式
* @return 预约情况
*/
@RequestMapping("/checkRoomIsWillUse")
public Result checkRoomIsWillUse(){
return ResultFactory.buildSuccessResult(classRoomService.checkRoomIsWillUse());
}
/**
* 用于统计房间人数的方法-活体检测-非前端返回类型
* @param classRoom 房间Id
* @return 封装的人数
*/
@RequestMapping("/checkRoomNumber")
public Result checkRoomNumberOfParticipants(ClassRoom classRoom){
return null;
//return ResultFactory.buildSuccessResult(classRoomService.checkRoomNumberOfParticipants(classRoom.getRoomId()));
}
/**
* 用于统计房间人数的方法-活体检测-前端返回类型
* @param file 教室的图像
* @return 封装的人数
*/
@PostMapping("/classroomInfo/info")
public String coversUpload(MultipartFile file) {
AipBodyAnalysis client =BDAipBodyAnalysis.getClient();
String folder = "D:/workspace/img";
File imageFolder = new File(folder);
File f = new File(imageFolder, StringUtils.getRandomString(6) + file.getOriginalFilename()
.substring(file.getOriginalFilename().length() - 4));
if (!f.getParentFile().exists())
f.getParentFile().mkdirs();
try {
file.transferTo(f);
// String imgURL = "http://localhost:8443/api/file/" + f.getName();
// return imgURL;
return classRoomService.analysisPeople(client ,f);
} catch (IOException e) {
e.printStackTrace();
return "-1";
}
}
}
*/
@GetMapping("/api/admin/role")
public Result listRoles() {
return ResultFactory.buildSuccessResult(adminRoleService.listWithPermsAndMenus());
}
/**
* 获取角色状态
* @param requestRole 要查询的角色
* @return 封装好的消息
*/
@PutMapping("/api/admin/role/status")
public Result updateRoleStatus(@RequestBody AdminRole requestRole) {
AdminRole adminRole = adminRoleService.updateRoleStatus(requestRole);
String message = "用户" + adminRole.getNameZh() + "状态更新成功";
return ResultFactory.buildSuccessResult(message);
}
/**
* 修改角色信息
* @param requestRole 要修改的角色信息
* @return 封装好的消息
*/
@PutMapping("/api/admin/role")
public Result editRole(@RequestBody AdminRole requestRole) {
adminRoleService.addOrUpdate(requestRole);
adminRolePermissionService.savePermChanges(requestRole.getId(), requestRole.getPerms());
String message = "修改角色信息成功";
return ResultFactory.buildSuccessResult(message);
}
/**
* 修改用户用户角色
* @param requestRole 要修改的角色
* @return 封装好的修改成功消息
*/
@PostMapping("/api/admin/role")
public Result addRole(@RequestBody AdminRole requestRole) {
adminRoleService.editRole(requestRole);
return ResultFactory.buildSuccessResult("修改用户成功");
}
/**
* 查询用户权限
* @return 用户所有权限
*/
@GetMapping("/api/admin/role/perm")
@RequestMapping("/queryReservationOfCurrentDateRoom")
public Result QueryReservationOfCurrentDateRoom() {
List<String> list = new ArrayList<>();
nowTime = new Timestamp(new Date().getTime());
tomTime = new Timestamp(new Date().getTime());
nowTime.setHours(0);
nowTime.setSeconds(0);
nowTime.setMinutes(0);
nowTime.setNanos(0);
tomTime.setHours(0);
tomTime.setSeconds(0);
tomTime.setMinutes(0);
tomTime.setNanos(0);
tomTime.setDate(tomTime.getDate() + 1);
for (Meeting meeting : meetingService.findAllByStartTimeBetweenAndStatusGreaterThan(nowTime, tomTime, 0)) {
list.add(meeting.getRoomName());
;
}
return ResultFactory.buildSuccessResult(list);
}
/**
* 查询活动是否结束
* @return 封装好的活动状态提升
*/
@RequestMapping("/checkMeetBegin")
public Result checkMeetBegin() {
Iterable<Meeting> meetings = meetingService.findAllByStartTimeAfterAndEndTimeBefore(nowTime, nowTime);
nowTime = new Timestamp(new Date().getTime());
for (Meeting meeting : meetings) {
meeting.setStatus(2);
}
meetingService.saveAll(meetings);
return ResultFactory.buildSuccessResult("更新状态成功");
}
/**
* 查询活动是否过期
* @return 返回更新状态
*/
@RequestMapping("/checkMeetTimeout")
public Result checkMeetTimeout() {
@PostMapping("/api/admin/content/books/delete")
public Result deleteBook(@RequestBody @Valid Book book) {
bookService.deleteById(book.getId());
return ResultFactory.buildSuccessResult("删除成功");
}
/**
* 数据查找关键词
* @param keywords 关键词
* @return 封装的查询的结果
*/
@GetMapping("/api/search")
public Result searchResult(@RequestParam("keywords") String keywords) {
if ("".equals(keywords)) {
return ResultFactory.buildSuccessResult(bookService.list());
} else {
return ResultFactory.buildSuccessResult(bookService.Search(keywords));
}
}
/**
* 获取某个分类的书籍
* @param cid 分类ID
* @return 封装的书籍
*/
@GetMapping("/api/categories/{cid}/books")
public Result listByCategory(@PathVariable("cid") int cid) {
if (0 != cid) {
return ResultFactory.buildSuccessResult(bookService.listByCategory(cid));
} else {
return ResultFactory.buildSuccessResult(bookService.list());
}
}
/**
* 上传书籍封面
* @param file 数据封面
* @return 书籍的链接
*/
@PostMapping("/api/admin/content/books/covers")
public String coversUpload(MultipartFile file) {
String folder = "D:/workspace/img";
File imageFolder = new File(folder);
File f = new File(imageFolder, StringUtils.getRandomString(6) + file.getOriginalFilename()
.substring(file.getOriginalFilename().length() - 4));
if (!f.getParentFile().exists())
f.getParentFile().mkdirs();
try {
file.transferTo(f);
String imgURL = "http://localhost:8443/api/file/" + f.getName();
return imgURL;
} catch (IOException e) {
e.printStackTrace();
for (Meeting meeting : meetingService.findAllByStartTimeBetweenAndStatusGreaterThan(nowTime, tomTime, 0)) {
list.add(meeting.getRoomName());
;
}
return ResultFactory.buildSuccessResult(list);
}
/**
* 查询活动是否结束
* @return 封装好的活动状态提升
*/
@RequestMapping("/checkMeetBegin")
public Result checkMeetBegin() {
Iterable<Meeting> meetings = meetingService.findAllByStartTimeAfterAndEndTimeBefore(nowTime, nowTime);
nowTime = new Timestamp(new Date().getTime());
for (Meeting meeting : meetings) {
meeting.setStatus(2);
}
meetingService.saveAll(meetings);
return ResultFactory.buildSuccessResult("更新状态成功");
}
/**
* 查询活动是否过期
* @return 返回更新状态
*/
@RequestMapping("/checkMeetTimeout")
public Result checkMeetTimeout() {
nowTime = new Timestamp(new Date().getTime());
Iterable<Meeting> meetings = meetingService.findAllByEndTimeBefore(nowTime);
for (Meeting meeting : meetings) {
meeting.setStatus(-1);
System.out.println(meeting.getMeetingId() + " " + meeting.getStatus());
}
meetingService.saveAll(meetings);
return ResultFactory.buildSuccessResult("更新状态成功");
}
/**
* 查询七天内所有用户会议所有教室预约情况
*
* @return 预约情况
*/
@RequestMapping("/querySevenDayMeetOfUser")
public Result querySevenDayMeetOfUser(@RequestBody User requestUser) {
return ResultFactory.buildSuccessResult(meetingService.querySevenDayMeetOfUser(requestUser.getUsername()));
}
/**
@RestController
public class RoleController {
@Autowired
AdminRoleService adminRoleService;
@Autowired
AdminPermissionService adminPermissionService;
@Autowired
AdminRolePermissionService adminRolePermissionService;
@Autowired
AdminRoleMenuService adminRoleMenuService;
/**
* h获取角色列表
* @return 返回角色列表
*/
@GetMapping("/api/admin/role")
public Result listRoles() {
return ResultFactory.buildSuccessResult(adminRoleService.listWithPermsAndMenus());
}
/**
* 获取角色状态
* @param requestRole 要查询的角色
* @return 封装好的消息
*/
@PutMapping("/api/admin/role/status")
public Result updateRoleStatus(@RequestBody AdminRole requestRole) {
AdminRole adminRole = adminRoleService.updateRoleStatus(requestRole);
String message = "用户" + adminRole.getNameZh() + "状态更新成功";
return ResultFactory.buildSuccessResult(message);
}
/**
* 修改角色信息
* @param requestRole 要修改的角色信息
* @return 封装好的消息
*/
@PutMapping("/api/admin/role")
public Result editRole(@RequestBody AdminRole requestRole) {
adminRoleService.addOrUpdate(requestRole);
adminRolePermissionService.savePermChanges(requestRole.getId(), requestRole.getPerms());
return ResultFactory.buildFailResult("用户名和密码不能为空");
case 1:
return ResultFactory.buildSuccessResult("注册成功");
case 2:
return ResultFactory.buildFailResult("用户已存在");
}
return ResultFactory.buildFailResult("未知错误");
}
/**
* 退出登录
* @return 成功登出的封装消息
*/
@GetMapping("/api/logout")
public Result logout() {
Subject subject = SecurityUtils.getSubject();
subject.logout();
return ResultFactory.buildSuccessResult("成功登出");
}
/**
* 身份认证
* @return 成功认证的消息字符串
*/
@GetMapping("/api/authentication")
public String authentication() {
return "身份认证成功";
}
/**
* 通过登录用户名查找用户账号
* @param requestUser 用户身份凭据
* @return 封装的用户名
*/
@CrossOrigin
@RequestMapping("/api/info/username")
public Result loggedUserUsername(@RequestBody User requestUser) {
String username = HtmlUtils.htmlEscape(requestUser.getUsername());
return ResultFactory.buildSuccessResult(userService.findByUsername(username).getUsername());
}
/**
* 通过登录用户查找用户姓名
@CrossOrigin
@RequestMapping("/api/info/name")
public Result loggedUserName(@RequestBody User requestUser) {
String username = HtmlUtils.htmlEscape(requestUser.getUsername());
return ResultFactory.buildSuccessResult(userService.findByUsername(username).getName());
}
}
@RestController
public class RoleController {
@Autowired
AdminRoleService adminRoleService;
@Autowired
AdminPermissionService adminPermissionService;
@Autowired
AdminRolePermissionService adminRolePermissionService;
@Autowired
AdminRoleMenuService adminRoleMenuService;
/**
* h获取角色列表
* @return 返回角色列表
*/
@GetMapping("/api/admin/role")
public Result listRoles() {
return ResultFactory.buildSuccessResult(adminRoleService.listWithPermsAndMenus());
*
*/
}
}
@ControllerAdvice
@ResponseBody
public class DefaultExceptionHandler {
@ExceptionHandler(value = Exception.class)
public Result exceptionHandler(Exception e) {
String message = null;
if (e instanceof IllegalArgumentException) {
message = "传入了错误的参数";
}
if (e instanceof MethodArgumentNotValidException) {
message = ((MethodArgumentNotValidException) e).getBindingResult().getFieldError().getDefaultMessage();
}
if (e instanceof UnauthorizedException) {
message = "权限认证失败";
}
return ResultFactory.buildFailResult(message);
}
}
/**
* 查询用户取消的活动
*
* @param requestUser 要查询的用户
* @return 封装好的活动列表
*/
@RequestMapping("/meeting/get/user_cancel")
public Result getAllMeetingByUsernameCanceled(@RequestBody User requestUser) {
return ResultFactory.buildSuccessResult(meetingService.findAllByStuIdCancel(requestUser.getUsername()));
}
/**
* 查询用户超时活动
*
* @param requestUser 要查询的用户
* @return 封装好的查询结果
*/
@RequestMapping("/meeting/get/user_timeout")
public Result getAllMeetingByUsernameTimeout(@RequestBody User requestUser) {
return ResultFactory.buildSuccessResult(meetingService.findAllByStuIdTimeout(requestUser.getUsername()));
}
/**
* 查询所有可用的活动数量
*
* @return 封装好的可用活动数量
*/
@RequestMapping("/meeting/get/count/classify/usable")
public Result getAllMeetingCountClassifyUsable() {
return ResultFactory.buildSuccessResult(meetingService.CountByAllMeetingUsable());
}
/**
* 查询所有取消和超时的活动
*
* @return 封装好的超时和取消活动数量
*/
@RequestMapping("/meeting/get/count/classify/c&t")
public Result getAllMeetingCountClassifyCancelAndTimeout() {
return ResultFactory.buildSuccessResult(meetingService.CountByAllMeetingCancelAndTimeout());
}
/**
* 查询当前日期所有教室预约情况
*
if (HttpMethod.OPTIONS.toString().equals((httpServletRequest).getMethod())) {
httpServletResponse.setStatus(HttpStatus.NO_CONTENT.value());
return true;
}
if (null == adminPermissionService) {
adminPermissionService = SpringContextUtils.getContext().getBean(AdminPermissionService.class);
}
String requestAPI = getPathWithinApplication(request);
Subject subject = SecurityUtils.getSubject();
if (!subject.isAuthenticated()) {
// log.info("未登录用户尝试访问需要登录的接口");
return false;
}
// 判断访问接口是否需要过滤(数据库中是否有对应信息)
boolean needFilter = adminPermissionService.needFilter(requestAPI);
if (!needFilter) {
return true;
} else {
// 判断当前用户是否有相应权限
boolean hasPermission = false;
String username = subject.getPrincipal().toString();
Set<String> permissionAPIs = adminPermissionService.listPermissionURLsByUser(username);
for (String api : permissionAPIs) {
// 匹配前缀
if (requestAPI.startsWith(api)) {
hasPermission = true;
break;
}
}
if (hasPermission) {
log.trace("用户:" + username + "访问了:" + requestAPI + "接口");
return true;
} else {
log.warn( "用户:" + username + "访问了没有权限的接口:" + requestAPI);
return false;
}
}
}
}
* @return 预约情况
*/
@RequestMapping("/querySevenDayMeetOfUser")
public Result querySevenDayMeetOfUser(@RequestBody User requestUser) {
return ResultFactory.buildSuccessResult(meetingService.querySevenDayMeetOfUser(requestUser.getUsername()));
}
/**
* 依照会议时间是否冲突-重新封装模式
*
* @return 是否冲突
*/
@RequestMapping("/checkTimeConflict")
public Result checkTimeConflict(@RequestBody Meeting meeting) {
return ResultFactory.buildSuccessResult(meetingService.checkTimeConflict(meeting));
}
}
@RestController
@RequestMapping("/api")
public class ClassRoomController {
@Resource
private ClassRoomService classRoomService;
/**
* 保存新的或者修改教室
* @param classRoom 教室
* @return 保存的新房间
*/
@CrossOrigin
@RequestMapping("/rooms/save")
public ClassRoom save(@RequestBody ClassRoom classRoom){
classRoomService.save(classRoom);
return classRoom;
}