0


基于ssm + Vue + bootstrap 的部门管理系统

基于ssm + Vue + bootstrap 的部门管理系统


一、技术栈

后端:SpringMVC + Spring + MyBatis + Maven + MySQL

后端分页插件:pagehelper

前端:bootstrap + Vue + ajax

二、功能点

  • 分页查询
  • 数据校验 - Vue前端校验 + JSR303后端校验
  • 使用ajax发送请求
  • Restful 风格的URL,使用HTTP协议请求方式的动词,来表示对资 源的操作(GET(查询),POST(新增),PUT(修改),DELETE (删除))
  • URI: - /employee/{id} GET 查询员工- /employee POST 保存员工- /employee/{id} PUT 修改员工- /employee/{id} DELETE 删除员工

三、基础环境搭建

基础环境搭建 :

  • 1、创建一个maven工程
  • 2、引入项目依赖的jar包- spring- springmvc- mybatis- 数据库连接池,驱动包- 其他(jstl,servlet-api,junit)
  • 3、引入bootstrap 和 Vue 前端框架
  • 4、编写ssm整合的关键配置文件- web.xml,spring,springmvc,mybatis,使用mybatis的逆向工程生成对应的bean以 及mapper

• 5、测试mapper

五、底层架构

在这里插入图片描述

六、页面展示和运行结果展示

运行结果展示视频

  • 首页

在这里插入图片描述

  • 添加员工:

在这里插入图片描述

  • 修改员工信息:

在这里插入图片描述

七、基础环境搭建过程中出现的问题

1、报错一

报错如下:

Result Maps collection already contains value for com.ssm.crud.mapper.Depart

产生原因:mapper 接口所在的包 和映射文件所在的包名字一样发生冲突

解决方案:修改了 映射文件所在的文件路径名称

2、报错二

报错如下:java.lang.NoClassDefFoundError: javax/servlet/SessionCookieConfig

产生原因:使用 MockMvc 进行请求 测试的时候,需要 servlet3.0及以上 的支持

更新maven配置依赖

<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency>

3、报错三

报错如下:nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]

产生原因:我们的Spring配置文件之前是放在WEB-INF下的,但是由于使用了maven构建工具,所以当前我们的Spring配置文件是放在了resources这个目录下,如果不特意指定参数名为contextConfigLoction的 元素,那么spring的ContextLoderListener监听器就会在/WEB-INF/下去寻找并加载该目录下的名为applicationContext.xml这个文件。所以才会出现文件找不到的错误

解决方案:和设置springMVC配置文件位置的方式一样

<!-- 配置识别Spring配置文件的位置 --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param>

八、查询功能的实现

  • 用户访问 index.html 页面
  • index.html页面通过 ajax 发送请求,获取员工列表信息
  • EmployeeController 接收请求,查询员工信息
  • 通过 pageHelper 分页插件进行分页查询
  • 将数据返回给 indedx.html 页面
/**
    * @author wk
    * @Description 返回json格式的员工信息
    * @Date 22:23 2022/4/29
    * @Param
    * @Return
    */@RequestMapping("/employeeList")@ResponseBodypublicMessagegetEmployeeListByJson(@RequestParam(value ="pageNumber",defaultValue ="1")Integer pageNumber){// 开启分页查询,传入页码,以及每页的数量PageHelper.startPage(pageNumber,5);// 查询员工的信息列表(分页后的数据)List<Employee> employeeList = employeeService.getEmployeeList();// 使用pageInfo包装查询后的结果,只需要将pageInfo交给页面就可以了// 封装了详细的分页信息,包括有我们查询出来的数据。 设置 分页导航数目为 5PageInfo<Employee> employeePageInfo =newPageInfo<>(employeeList,5);returnMessage.success().add("employeePageInfo",employeePageInfo);}

九、新增员工信息的实现

  • 在 index.html 页面点击新增按钮
  • 弹出新增模态框
  • 去数据库查询部门列表,显示在模态框中
  • 用户输入数据,并进行校验- Vue前端校验,ajax用户名重复校验,后端校验(JSR303)
  • 校验通过,完成保存
/**
    * @author wk
    * @Description 保存员工信息
     *             1、支持JSR303校验
     *             2、导入 Hibernate-Validator 依赖
    * @Date 16:58 2022/4/30
    * @Param
    * @Return
    */@RequestMapping(value ="/employee",method =RequestMethod.POST)@ResponseBodypublicMessagesaveEmployee(@ValidEmployee employee,BindingResult result){// 后端校验(用户名和邮箱是否合法)if(result.hasErrors()){// 校验失败,返回失败信息,在模态框中显示检验失败信息HashMap<String,Object> map =newHashMap<>();List<FieldError> errorList = result.getFieldErrors();for(FieldError fieldError : errorList){System.out.println("错误字段名:"+ fieldError.getField());System.out.println("错误信息:"+ fieldError.getDefaultMessage());
                map.put(fieldError.getField(),fieldError.getDefaultMessage());}returnMessage.fail().add("failMap",map);}else{
            employeeService.saveEmployee(employee);returnMessage.success();}}
/**
    * @author wk
    * @Description 检查员工姓名是否重复
    * @Date 21:50 2022/4/30
    * @Param
    * @Return
    */@RequestMapping("/checkEmployeeName")@ResponseBodypublicMessagecheckEmployeeName(String employeeName){// 首先校验名字格式是否合法String regName ="(^[a-zA-Z0-9_-]{6,16}$)|(^[\\u4e00-\\u9fa5]{2,5})";if(!employeeName.matches(regName)){returnMessage.fail().add("va_message","用户名必须是6-16位数字和字母的组合或2-5位中文");}// 再校验名字是否重复Boolean aBoolean = employeeService.checkEmployeeName(employeeName);if(aBoolean){returnMessage.success();}else{returnMessage.fail().add("va_message","用户名已经存在,请更换一个试试");}}

十、修改员工信息的实现

  • 用户点击编辑按钮
  • 弹出用户修改的模态框(并显示待修改员工的信息)
  • 邮箱进行前端校验(这里暂时没有进行后端校验)
  • 点击更新,完成用户修改
@RequestMapping(value ="/employee/{employeeId}",method =RequestMethod.PUT)@ResponseBodypublicMessageupdateEmployee(Employee employee){
        employeeService.updateEmployee(employee);returnMessage.success();}

注意:修改用到了 PUT 请求,而Tomcat默认不支持将PUT和DELETE请求的数据封装为一个map,所以为了能够获取到数据,需要在web.xml中配置一个过滤器:

<!-- 使ajax可以直接发送PUT或DELETE请求,不用通过传递 _method=PUT或 _method=DELETE 参数来发送POST请求 --><filter><filter-name>HttpPutFormContentFilter</filter-name><filter-class>org.springframework.web.filter.FormContentFilter</filter-class></filter><filter-mapping><filter-name>HttpPutFormContentFilter</filter-name><url-pattern>/</url-pattern></filter-mapping>

十一、删除功能的实现

  • 单个删除 - 前端将待删除的员工id通过ajax发送到后端,然后进行删除
  • 批量删除 - 前端将待删除的多个员工id,以字符串的形式通过ajax发送给后端,后端将字符串转换为 Integer类型数组,并放到 list 集合中,作为删除的条件,进行批量删除
  • URL:/employee/{employeeIds} method = RequestMethod.DELETE
/**
    * @author wk
    * @Description 删除指定员工(单个删除或批量删除)
     *             批量删除 1-2-3
     *             单个删除 1
    * @Date 22:44 2022/5/1
    * @Param
    * @Return
    */@RequestMapping(value ="/employee/{employeeIds}",method =RequestMethod.DELETE)@ResponseBodypublicMessagedeleteEmployeeById(@PathVariable("employeeIds")String employeeIds){ArrayList<Integer> employeeIdList =newArrayList<>();if(employeeIds.contains(",")){String[] employeeIdStrArray = employeeIds.split(",");for(String employeeId : employeeIdStrArray){
                employeeIdList.add(Integer.parseInt(employeeId));}Integer integer = employeeService.deleteEmployeeBatch(employeeIdList);if(integer >0){returnMessage.success();}}else{Integer employeeId =Integer.parseInt(employeeIds);Integer integer = employeeService.deleteEmployeeById(employeeId);if(integer >0){returnMessage.success();}}returnMessage.fail();}

十二、回到指定页面逻辑

  • 如果 type === “delete”,则表示删除一条数据后要回到页面 - 如果 page(当前页码) > pageCount(删除一条数据后的总页码数),则跳转到 pageCount 页码(即最后一页),反之跳转到当前页码 - 使用场景:当某一页数据全部删除后应该向前一页跳转,反之则跳转到当前页- 如果 page(当前页码) < 1,则跳转到第一页,反之跳转到当前页码 - 使用场景:当数据删除到只剩第一页,则跳转到第一页,否则还是跳转到当前页
  • 如果 type === “add”,则表示添加一条数据后要回到页面 - 如果 page(当前页码) > pageCount(新增一条数据后的总页码数),则跳转到 page 页码(当前页码),反之跳转到当前页码 - 使用场景:当新增数据正好使页码增加 1,则应该跳转到新增加的页码所对应的页面
// 回到指定页码的页面goBackPage(page, pageCount, type){// pageCount 删除或添加后的页码总数// page:当前页码// type:执行操作的类型if("delete"=== type){
                    page =(page > pageCount)? pageCount : page;
                    page =(page <1)?1: page;}elseif("add"=== type){
                    page =(page > pageCount)? page : pageCount;}
                axios.get(`http://localhost:8080/SSM/employeeList?pageNumber=${page}`).then(response=>{this.pageInfo = response.data.data.employeePageInfo;this.employees = response.data.data.employeePageInfo.list;}),error=>{
                    console.log("请求失败:", error.message);}},

十三、项目源码

点个关注再走呗 ()

码云仓库

github仓库


本文转载自: https://blog.csdn.net/m0_47214030/article/details/124621228
版权归原作者 ☆*往事随風*☆ 所有, 如有侵权,请联系我们删除。

“基于ssm + Vue + bootstrap 的部门管理系统”的评论:

还没有评论