• 高校会议管理系统毕业设计


    一、系统背景

    在现代高校中,随着学校招生人数增多,学校老师外出参加培训成了急切需要。除了外出参加培训,老师到各地参加会议、比赛等进行学术交流之类的活动也必不可少。学校内部组织会议数也越来越多,使用传统的会议管理方式将产生大量的纸质文件且步骤众多繁琐,这种人工管理的方式效率低下并且容易犯错,如参会人员的通知,向参会人员挨个打电话通知效率肯定是十分低下的。
    对学校来说,如何合理运用会议资源高效地举办会议已经成为了一个重要的研究课题,因此研发一套信息化会议管理系统成了急切需要。该系统需要达到对用户举办会议和外出参会的统一管理,外出参加会议和举办会议进行不同的审核流程,到达流程节点时第一时间通知审批人进行审批。

    二、需求分析

    对于一所高校来说,教师的教学质量与学校能否更好发展息息相关,这免不了组织培训和学习交流。传统的会议召开都是通过口头通知或者电话通知,这些通知方式不仅效率低还可能出现通知不到位的情况。除了会议通知方面,会议室的选择也是一大问题,申请人只有通过询问负责人来确定会议召开的地点和时间,当会议室需要维护时也无法第一时间通知各部门人员。
    该系统面向于系统管理员、部门用户和管理员。系统管理员主要是对会议室、会议类型等进行维护,部门管理员则是对整个部门人员和审批流程进行管理,用户主要是使用会议和参会申请功能,来达到对会议和参会申请的办结办理。

    三、系统设计

    系统设计部分主要分为3个部分。在系统架构设计部分主要介绍系统实现所用到的工具或技术,功能结构设计方面主要介绍系统所包含的主要功能,通过E-R关系图体现数据库设计思路。

    3.1 系统架构设计

    下图给出整个系统架构设计图,主要包括前端页面,服务网关,微服务治理和持久层设计。
    前端主要使用React框架,绘制图表使用Echarts框架,Axios用于异步请求后端接口数据。当请求至Gateway网关时,根据API接口进行请求分发。服务治理方面使用Nacos用作注册中心,当用户鉴权服务和应用服务注册进Nacos后服务直接接口调用可以用Feign实现。持久层主要使用MySQL,MySQL运行速度快、体积小,非常适合会议管理系统这种中小型系统。
    在这里插入图片描述

    3.2 系统功能结构设计

    整个系统功能可以分为5大模块,系统管理、会议参会管理、通知管理、流程管理和人员管理。系统管理主要用于系统管理员管理整个会议系统参照数据,如部门、会议类型等这些不易改变的数据。会议参会管理主要是该系统的核心功能,用于整个系统用户进行会议业务处理。通知管理的主要作用在于通知用户参加、举办和办结会议,用户在登录系统时能够及时接收系统消息。流程管理和人员管理主要提供给部门管理员,普通用户无权访问。系统功能结构图如图所示:
    在这里插入图片描述

    3.3 系统数据库设计

    本节将介绍系统实体关系图和数据库表设计。关系图中体现实体关系以及实体主要字段,着重表示了部门、人员、角色和权限之间的对应关系。数据库表设计部分主要介绍了数据库表字段名称、类型和描述。
    该会议管理系统实体主要包括了部门、部门角色、用户、权限、会议、参会、会议室和附件等,数据库E-R图如图所示:
    在这里插入图片描述

    四、系统实现

    4.1 开发环境和工具

    本系统后端实现主要使用Java语言,使用集成开发环境Interllij IDEA进行接口开发,主要用到的框架有SpringBoot、SpringCloud Gateway和SpringSecurity。前端使用React框架以及各种工具包和组件。数据库方面使用MySQL,MySQL运行速度快,体积小,适用于中小型系统,非常适用于当前系统开发场景。系统开发中使用到的开发工具、开发环境详细描述如下表所示:

    分类说明描述
    开发语言前端HTML、CSS、JavaScript、React
    后端Java
    开发环境和工具浏览器Mozilla Firefox
    服务器Tomcat 9.0.56
    JDK工具包JDK 8
    后端开发工具Interllij IDEA
    数据库MySQL 8.0.23
    数据库图形操作工具Navicat for MySQL
    服务注册中心Nacos
    服务网关SpringCloud Gateway

    4.2 后台管理系统

    本节主要介绍系统后台管理实现,主要功能包括会议室管理、会议类型管理和部门管理等,除了对具体功能的实现思路外还有对系统权限的介绍。

    4.2.1 会议室管理

    该部分实现了对学校所有会议室的统一管理,后台管理员可以对会议室进行增删改查以及修改会议室状态,当会议室处于维护中时用户无法选择该会议室。

    4.2.2 会议类型管理

    该部分主要实现了会议类型的统一管理,管理员在进行流程管理时,会根据会议类型的不同创建不同的审批流程。

    4.2.3 部门管理

    部门是一个树结构。一般高校部门结构为:根节点为校本部,之下是各个学院,在下面是专业系或者实验室。部门结构图如下图所示:
    在这里插入图片描述
    该部分实现思路是在部门实体中添加父部门ID,在查询部门列表时根据该字段迭代查询父部门的子部门列表,根节点部门父部门ID为空。

    4.2.4 部门角色管理

    角色主要分为公有角色和私有角色,私有角色如校长,只有在校本部才有这个角色,像普通用户、系主任这种部门普遍拥有的角色称为公有角色。该部分主要实现对角色的增删改查以及对部门和角色之间进行关联。

    4.2.5 系统用户操作日志

    后台管理员通过查看用户操作日志能够清晰的看到调用接口参数、接口耗时以及操作失败时的异常信息,管理员可以通过该异常信息快速找出程序问题所在。用户操作日志实现思路是通过Spring的Aop机制,在用户每次访问接口时获取用户的操作信息并存放进数据库。日志保存核心代码如下所示:

    1.void saveLog(JoinPoint joinPoint, long time,String errorInfo) throws Exception {  
    2.    MethodSignature signature = (MethodSignature) joinPoint.getSignature();  
    3.    Method method = signature.getMethod();  
    4.    UserLog userLog = new UserLog();  
    5.    CmLog cmLog = method.getAnnotation(CmLog.class);  
    6.    if (cmLog != null) {  
    7.        // 注解上的描述  
    8.        userLog.setDes(cmLog.description());  
    9.    }  
    10.    // 获取request  
    11.    HttpServletRequest request = HttpContextUtils.getRequest();  
    12.    // 设置IP地址  
    13.    userLog.setIp(NetworkUtil.getIpAddr(request));  
    14.    // 设置根路径  
    15.    String path = request.getContextPath();  
    16.    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path;  
    17.    userLog.setRoot(basePath);  
    18.    // 获取uri  
    19.    userLog.setUri(request.getRequestURI());  
    20.    // 请求方式  
    21.    userLog.setMethod(request.getMethod());  
    22.    // 用户名  
    23.    String username = tokenManager.getUserInfoFromToken(request.getHeader("token"));  
    24.    // 请求的参数  
    25.    userLog.setParams(getServiceMethodParams(joinPoint));  
    26.    if (StringUtils.isBlank(username)) {  
    27.        userLog.setUsername("获取到的用户名为空");  
    28.    } else {  
    29.        userLog.setUsername(username);  
    30.    }  
    31.    userLog.setSpendTime((int) time);  
    32.    // 相应状态 1:成功, 0:失败  
    33.    userLog.setResult(1);  
    34.    // 日志类型  
    35.    userLog.setType("info");  
    36.    // 错误信息  
    37.    if(errorInfo != null){  
    38.        userLog.setErrorInfo(errorInfo);  
    39.        userLog.setResult(0);  
    40.        userLog.setType("error");  
    41.    }  
    42.    // 保存系统日志  
    43.    logService.save(userLog);  
    44.}  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    4.2.6 系统权限

    系统拥有6个权限,管理员在创建角色时为其分配不同的权限。一个用户对应于一个角色,用户的操作便通过其权限控制,下面将介绍具体的权限控制机制:
    1、添加权限
    申请会议或申请参会权限,当用户没有该权限时,无法进行会议和参会的申请。
    2、删除权限
    删除会议或参会申请的权限,当用户删除会议或参会时,首先判断该用户是否拥有该权限,如果拥有该权限,则判断当前会议所处的审批状态,如果处于审批中状态则无法删除。之后继续判断用户是否拥有manage管理权限,因为普通用户只能删除自己的申请。删除用户申请流程图如图所示:
    在这里插入图片描述

    3、修改权限
    修改会议或参会申请的权限,默认用户只能修改自己发起且未提交的申请。
    4、查询所有权限
    查询权限,对于举办会议来说,没有该权限用户只能查询到本部门的会议申请,拥有该权限则能够查询所有会议申请。对于外出参会来说,没有该权限只能查询到本人发起的参会申请,有该权限则能够查看到本部门所有的参会申请。
    5、管理权限
    管理权限,拥有该权限能够对部门人员和流程进行管理。
    6、导出权限
    报表导出权限,拥有该权限能够实现数据报表的导出功能。

    4.3 前台用户系统

    本节主要介绍该会议管理系统的核心用户系统。前台用户系统采用简单微服务架构,将后端划分成用户鉴权服务和应用服务,前端访问后端接口时先通过网关分发请求,之后调用具体的业务处理逻辑。用户鉴权服务主要处理用户登录和注册的逻辑,应用服务则处理用户的操作逻辑。

    4.3.1 用户登录鉴权

    系统登录鉴权服务实现的基本思路是当用户登录前台系统时,根据登录成功的用户名查询数据库获取用户的操作权限列表,然后将用户名和权限列表放入JWT并返回给浏览器,浏览器获取到JWT后将其保存到本地,之后每次向后端发送请求时都带上请求头,后端TokenManager对请求头中的token进行解析,最后在通过解析出来的权限列表判断用户是否有访问该接口的权限。用户鉴权序列图如图所示:
    在这里插入图片描述
    用户进行认证时,首先根据用户名判断用户是否存在,不存在则抛出异常,存在则判断用户状态,如果是可用状态则继续根据用户名查询用户权限列表并返回,框架根据输入的密码和数据库查询出来的密码进行对比。用户认证成功后,根据用户名生成JWT令牌并记录用户登录日志。
    用户认证核心代码:

    1.@Override  
    2.public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {  
    3.    //根据用户名查询数据  
    4.    User user = userService.selectByUsername(username);  
    5.    //判断  
    6.    if(user == null)  
    7.        throw new UsernameNotFoundException("用户不存在"); 
    8.    User curUser = new User();  
    9.    BeanUtils.copyProperties(user,curUser);  
    10.    //根据用户查询用户权限列表  
    11.    List<String> permissionValueList = userService.selectAuthByUsername(user.getNickName());  
    12.    permissionValueList.forEach(System.out::println);  
    13.    SecurityUser securityUser = new SecurityUser();  
    14.    securityUser.setCurrentUserInfo(curUser);  
    15.    securityUser.setPermissionValueList(permissionValueList);  
    16.    return securityUser;  
    17.}  
    认证成功核心代码:
    1.@Override  
    2.public User loginSuccess(SecurityUser user, HttpServletRequest request, TokenManager tokenManager) {  
    3.    //根据用户名生成token  
    4.    String token = tokenManager.createToken(user.getCurrentUserInfo().getNickName(),user.getPermissionValueList());  
    5.    // 记录用户登录日志  
    6.    User userInfo = user.getCurrentUserInfo();  
    7.    String ipAddr = NetworkUtil.getIpAddr(request);  
    8.    userLoginRecordService.userLoginRecord(userInfo.getId(),ipAddr);  
    9.    //返回token  
    10.    userInfo.setToken(token);  
    11.    //设置权限列表  
    12.    userInfo.setPermissionList(user.getPermissionValueList());  
    13.    return userInfo;  
    14.}  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    4.3.2 会议室列表

    会议室列表能够直观的展示可用和维护中的会议室以及各个时间段会议室的占用情况,方便用户选择可用时间段会议室,避免了举办会议时间冲突。用户可以通过会议室名称、会议室地点和容量对会议室进行检索,选择指定时间段进行会议申请。会议室界面实现如图所示:
    在这里插入图片描述
    如上图所示,占用和维护中的会议室无法选择使用,只有空闲中的会议室可供选择,选择指定时间段的会议室时跳转会议申请页面,传递会议室和时间段两个参数,相关的前端代码如下所示:

    1./** 
    2. * 表格点击事件 
    3. * @param {会议室名称} room  
    4. * @param {会议区间} date  
    5. */  
    6.tableBoxClick = (room,date) => {  
    7.  // 跳转会议申请界面  
    8.  this.props.dispatch( routerRedux.push({pathname:"/meeting/list/apply",state:{"mr":room,"start":date[0],"end":date[1]}}) );  
    9.} 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4.3.3 会议申请

    当用户进行会议申请时,会议申请人默认为当前登录用户,用户需要填写会议名称,当会议密级为内部时还需要填写会议脱密名称,会议密级为公开时脱密名称默认与会议名称相同,用户还需要选择会议主持人、记录员、参会人员和会议主题,参会人员人数根据选择自动计算,会议室和会议时段可以根据会议室列表页面选择跳转。用户也可以根据会议需要填写备注,以及上传会议所需附件。会议申请界面如图所示:
    在这里插入图片描述
    持续更新…

  • 相关阅读:
    Java课设 保存计算过程的计算器(附完整源码)
    install flash_atten
    深入理解计算机网络:从基本原理到实践应用
    Day22:算法篇之动态回溯
    Git要提交到B分支。但是误提交到A分支,然后推送到远程仓库。然后撤回并重新提交到B分支。
    深入理解 Django 信号机制
    vue 放大镜(简易)
    Spring MVC 的使用
    顺序读写函数的介绍:fputs & fgets
    stack和queue的使用和模拟实现
  • 原文地址:https://blog.csdn.net/oNew_Lifeo/article/details/125488231