Project
config里放配置文件,entity包里放实体类,resources里放管理端和用户端的静态页面等文件,common放通用类和全局异常处理器,filter放过滤器。
后台登录功能
需求分析
前端的login.html中的登录功能,要求服务端处理完登录的账号、密码后,给前端响应的数据里应当含有code,data,msg。而且数据的格式应该是jason格式
点击登录按钮,请求地址是http://localhost:8080/employee/login
POST请求方式
成功登录后,本地浏览器缓存中由employee的数据
代码开发
(1)创建实体类Employee,和数据库中的employee表进行映射。
(2)创建出大致结构。
EmployeeMapper接口
EmployeeService接口
EmployeeServiceImpl实现类
EmployeeController
(3)导入返回结果类R
此类是一个通用类,服务端响应的所有结果最终都会包装成这种类型返回给前端页面。
(4)在Controller中创建登录方法
处理逻辑如下:
1、将页面提交的密码password进行md5加密处理
2、根据页面提交的用户名username查询数据库
3、如果没有查询到则返回登录失败结果
4、密码比对,如果不一致则返回登录失败结果
5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果
6、登录成功,将员工id存入Session并返回登录成功结果
后台退出功能
需求分析
员工登录成功后,页面跳转系统首界面(/backend/index.html),此时会显示当前用户的姓名。
如果员工需要退出系统,直接点击右侧的退出按钮可以直接退出系统。退出系统后页面应该跳转到登录界面(/backend//page/login/login.html)
代码开发
用户点击页面中退出按钮,发送请求,请求地址为/employee/logout,请求方式为POST。我们只需要在Controller中创建对应的处理方法即可,具体的处理逻辑:
1、清理Session中的用户id
2、返回结果
功能测试
退出登录后,页面跳转到登陆界面,并且浏览器缓存中的userinfo被清理
完善登录功能
问题分析
前面我们已经完成了后台系统的员工登录功能开发,但是还存在一个问题:用户如果不登录,直接访问系统首页面,照样可以正常访问。
这种设计并不合理,我们希望看到的效果应该是,只有登录成功后才可以访问系统中的页面,如果没有登录则跳转到登录页面。那么,具体应该怎么实现呢?
答案就是使用过滤器或者拦截器,在过滤器或者拦截器中判断用户是否已经完成登录,如果没有登录则跳转到登录页面。
代码实现
实现步骤:
1、创建自定义过滤器LoginCheckFilter
2、在启动类上加入注解@ServletComponentScan
3、完善过滤器的处理逻辑
过滤器具体的处理逻辑如下:
1、获取本次请求的URI
2、判断本次请求是否需要处理
3、如果不需要处理,则直接放行
4、判断登录状态,如果已登录,则直接放行
5、如果未登录则返回未登录结果
新增员工
需求分析
后台系统中可以管理员工信息,通过新增员工来添加后台系统用户。
点击[添加员工]按钮跳转到新增页面,如下:
数据模型
新增员工,其实就是将我们新增页面录入的员工数据插入到employee表。
需要注意,employee表中对username字段加入了唯一约束,因为username是员工的登录账号,必须是唯一的。
employee表中的status字段已经设置了默认值1,表示正常
代码开发
先尝试在前端添加员工,这个请求以POST的方式发送到http://localhost:8080/employee
发送请求的参数是JSON格式的
在开发代码之前,需要梳理一下整个程序的执行过程:
1、页面发送ajax请求,将新增员工页面中输入的数据以json的形式提交到服务端
2、服务端Controller接收页面提交的数据并调用Service将数据进行保存
3、Service调用Mapper操作数据库,保存数据
前面的程序还存在一个问题,就是当我们在新增员工时输入的账号已经存在,由于employee表中对该字段加入了唯—约束,此时程序会抛出异常:
此时需要我们的程序进行异常捕获,通常有两种处理方式:
1、在Controller方法中加入try.catch进行异常捕获。但是这种方法不是很好,如果新增数据很多,那trycatch会写很多遍。下面的代码只是针对当前这一种情况来处理。
2、使用异常处理器进行全局异常捕获
员工信息分页查询
需求分析
系统中的员工很多的时候,如果在一个页面中全部展示出来会显得比较乱,不便于查看,所以一般的系统中都会以分页的方式来展示列表数据。
代码开发
在开发代码之前,需要梳理一下整个程序的执行过程:
1、页面发送ajax请求,将分页查询参数(page、pagesize、name)提交到服务端
2、服务端Controller接收页面提交的数据并调用Service查询数据
3、Service调用Mapper操作数据库,查询分页数据
4、Controller将查询到的分页数据响应给页面
5、页面接收到分页数据并通过ElementUI的Table组件展示到页面上
(1)配置MybatisPlus分页插件
(2)分页查询
启用/禁用员工账户
需求分析
在员工管理列表页面,可以对某个员工账号进行启用或者禁用操作。账号禁用的员工不能登录系统,启用后的员工可以正常登录。
需要注意,只有管理员(admin用户)可以对其他普通用户进行启用、禁用操作,所以普通用户登录系统后启用、禁用按钮不显示。
在开发代码之前,需要梳理一下整个程序的执行过程:
1、页面发送ajax请求,将参数(id、 status)提交到服务端
2、服务端Controller接收页面提交的数据并调用Service更新数据
3、Service调用Mapper操作数据库
代码开发
update方法
启用、禁用员工账号,本质上就是一个更新操作,也就是对status状态字段进行操作在Controller中创建update方法,此方法是一个通用的修改员工信息的方法。
由于前端的js精度16位,而ID是19位,需要添加对象转换器。否则点击禁用/编辑按钮返回的id数据精度不够,无法在数据库匹配到,导致更改无效。
对象转换器
具体实现步骤:
1)提供对象转换器JacksonObjectMapper,基于Jackson进行Java对象到json数据的转换
2)在WebMvcConfig配置类中扩展Spring mvc的消息转换器,在此消息转换器中使用提供的对象转换器进行Java对象到json数据的转换
编辑员工信息
需求分析
在员工管理列表页面点击编辑按钮,跳转到编辑页面,在编辑页面回显员工信息并进行修改,最后点击保存按钮完成操作。
代码开发
在开发代码之前需要梳理一下操作过程和对应的程序的执行流程:
1、点击编辑按钮时,页面跳转到add.html,并在url中携带参数[员工id]
2、在add.html页面获取url中的参数[员工id]
3、发送ajax请求,请求服务端,同时提交员工id参数
4、服务端接收请求,根据员工id查询员工信息,将员工信息以json形式响应给页面
5、页面接收服务端响应的json数据,通过VUE的数据绑定进行员工信息回显
6、点击保存按钮,发送ajax请求,将页面中的员工信息以json方式提交给服务端
7、服务端接收员工信息,并进行处理,完成后给页面响应
8、页面接收到服务端响应信息后进行相应处理
注意: add.html页面为公共页面,新增员工和编辑员工都是在此页面操作
因为在编写禁用员工状态时,写了update方法,可以通用,这里编辑功能的实现就可以借用update方法实现。
分类管理
公共字段自动填充
需求分析
前面已经完成了后台系统的员工管理功能开发,在新增员工时需要设置创建时间、创建人、修改时间、修改人等字段,在编辑员工时需要设置修改时间和修改人等字段。这些字段属于公共字段,也就是很多表中都有这些字段,如下:
对于这些公共字段在某个地方统一处理,来简化开发——使用Mybatis Plus提供的公共字段自动填充功能。
代码开发
Mybatis Plus公共字段自动填充,也就是在插入或者更新的时候为指定字段赋予指定的值,使用它的好处就是可以统一对这些字段进行处理,避免了重复代码。
实现步骤:
1、在实体类的属性上加入@TableField注解,指定自动填充的策略
2、按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,此类需要实现MetaObjectHandler接口
下图是已经解决了无法取得id后的代码(MyMetaObjectHandler.java)
功能完善:
createuser和updateuser
把controller中的新增员工类,设置公共字段改为自动填充。
新增分类
需求分析
后台系统中可以管理分类信息,分类包括两种类型,分别是菜品分类和套餐分类。当我们在后台系统中添加菜品时需要选择一个菜品分类,当我们在后台系统中添加一个套餐时需要选择一个套餐分类,在移动端也会按照菜品分类和套餐分类来展示对应的菜品和套餐。
数据模型
新增分类,其实就是将我们新增窗口录入的分类数据插入到category表,表结构如下:
代码开发
在开发业务功能前,先将需要用到的类和接口基本结构创建好:
1、实体类Category
2、Mapper接口CategoryMapper
3、业务层接口CategoryService
4、业务层实现类CategoryServicelmpl控制层CategoryController
在开发代码之前,需要梳理一下整个程序的执行过程:
1、页面(backend/page/category/list.html)发送ajax请求,将新增分类窗口输入的数据以json形式提交到服务端
2、服务端Controller接收页面提交的数据并调用Service将数据进行保存
3、Service调用Mapper操作数据库,保存数据
可以看到新增菜品分类和新增套餐分类请求的服务端地址和提交的json数据结构相同,所以服务端只需要提供一个方法统—外理即可
分类信息分页查询
需求分析
系统中的分类很多的时候,如果在一个页面中全部展示出来会显得比较乱,不便于查看,所以一般的系统中都会以分页的方式来展示列表数据。
代码开发
在开发代码之前,需要梳理一下整个程序的执行过程:
1、页面发送ajax请求,将分页查询参数(page.pageSize)提交到服务端
2、服务端Controller接收页面提交的数据并调用Service查询数据
3、Service调用Mapper操作数据库,查询分页数据
4、Controller将查询到的分页数据响应给页面
5、页面接收到分页数据并通过ElementUI的Table组件展示到页面上
删除分类
需求分析
在分类管理列表页面,可以对某个分类进行删除操作。需要注意的是当分类关联了菜品或者套餐时,此分类不允许删除。
代码开发
在开发代码之前,需要梳理一下整个程序的执行过程:
1、页面发送ajax请求,将参数(ids)提交到服务端
2、服务端Controller接收页面提交的数据并调用Service删除数据3、Service调用Mapper操作数据库
功能完善
前面我们已经实现了根据id删除分类的功能,但是并没有检查删除的分类是否关联了菜品或者套餐,所以我们需要进行功能完善。
要完善分类删除功能,需要先准备基础的类和接口:
1、实体类Dish和Setmeal
2、Mapper接口DishMapper和SetmealMapper
3、Service接口Dishservice和SetmealService
4、Service实现类DishServicelmpl和SetmealServicelmpl
判断是否关联:
抛出异常功能:
删除功能完善:
修改分类
需求分析
在分类管理列表页面点击修改按钮,弹出修改窗口回显分类信息并进行修改,最后点击确认按钮完成修改操作。