创建项目:创建boot项目,选中web和Mysql。导入项目需要的相关依赖Mybatis-plus:baomidou、druid等。

一、后台管理

1、后台员工登录退出

创建Filter过滤器检查用户是否已经完成登录(session中是否有id)才允许放行本次请求:若用户员工已经登录,则将员工的id存在session中,放行。否则向前端响应NOTLOGIN字段,前端进行处理跳回登录页面。判断用户登录时要进行密码和status校验。

点击退出登录:删除session中的id。

2、页面进行分页查询(MP拦截器完成分页查询):配置MP的分页插件分页拦截器。创建分页构造器和条件构造器完成满足条件的分页查询。

3、对后台员工信息进行添加(新增)、修改(编辑信息或改变启用禁用状态)、删除、(前端发送ajax请求、Controller服务端调用Service方法,Service调用Mapper对数据库进行操作完成该次请求,返回处理结果相关数据)

【套餐/餐品的分类管理、菜品管理、套餐管理、订单明细的分页查询、修改、删除、批量修改和删除操作都可归结为:前端发送ajax请求,以json或键值对、路径拼接的方式传递参数,服务端Controller调用相应的Service方法、Service调用Mapper对数据库进行操作完成该次请求,最终返回处理结果数据】

异常处理机制:首先创建全局异常处理类,添加注解拦截所有Controller和RestController中的异常进行处理,在该类中定义不同的异常处理方法,方法上添加注解表示该方法具体处理哪一种异常。自定义业务异常也可再全局异常处理类中定义方法来捕捉。

菜品和套餐的启售和停售需注意:当停售某个菜品后,包含该菜品的所有套餐也应该停售,涉及到两张表的更新要在方法上开启事务管理保证对数据库的多次操作同成功同失败。当启售套餐时,应先保证该套餐里包含的所有菜品都在启售状态中才可以启售,否则向前端返回结果【套餐内存在商品停售中不能启售】等提示信息。

由于一个菜品dish可以包含多个口味,为了方便进行处理,创建DishDto类继承dish并加入口味dishFlavor列表信息。如在进行菜品修改时,要通过菜品id查询该菜品的口味信息后封装成dishDto返回到前端进行菜品信息的详细展示。新增/删除菜品时还要根据菜品id新增/删除关联的口味信息。

在进行套餐setmeal管理时,同样一个套餐包含多个dish,因此创建SetmealDto进行setmeal并加入dish菜品列表信息。在套餐更新修改时,同样要通过套餐id查询该套餐的信息和对应的菜品List<dish>信息,封装成setmealDto返回到前端进行套餐信息的详细展示。新增/删除套餐时同样要新增/删除对应包含的菜品信息。

4、静态资源映射:【WebMvcConfigurationSupport】重写方法,由于默认情况下,只能访问到templates和static下的静态资源,因此需要设置静态资源映射

5、消息转换器:【WebMvcConfigurationSupport】重写方法,扩展消息转换器。由于js对long型数据进行处理时丢失精度,因此在服务端给页面响应json数据时进行处理,将long型数据统一转为String字符串。基于jackson进行java到json数据的转换。

6、公共字段填充:Mybatis Plus公共字段自动填充,也就是在插入或更新的时候为指定字段赋予指定的值,使用它的好处就是可以统一对这些字段进行处理,避免了重复代码。首先在实体类的属性上加入了@TableField注解,指定自动填充的策略,编写元数据对象处理器,新建一个类,在此类中统一为公共字段赋值,此类需要实现MetaObjectHandler接口并重写方法:在进行插入和更新操作时为哪些字段赋值如updateTime。

7、ThreadLocal:由于MyMetaObjectHandler类中是不能获得HttpSession对象的,所以需要通过其它方式来获取登录用户id。

ThreadLocal并不是一个Thread,而是Thread的局部变量。当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问。

因此编写一个基于ThreadLocal封装的工具类使用ThreadLocal的set和get方法来保存和获取用户id。在检查用户登录的Filter就可以调用ThreadLocal中的set方法保存id,在公共字段填充类中调用ThreadLocal的get方法获取id赋值。

 二、移动端管理

1、移动端用户进行访问页面同样要经过过滤器盘Filter判断登录状态,通过session验证用户是否登录,若登录则放行操作,若未登录则向前端响应对应数据。

在用户进行登录时发送ajax请求,服务端Controller经过手机号和验证码比对若成功则将id写入session,用户退出则移除对应session。

2、用户地址管理:查询所有地址、获取默认地址、设置默认地址、新增地址、删除地址都是前端发送相应的ajax请求,服务端Controller调用Service方法,Service调用Mapper对数据库进行操作,最终向前端响应结果。

3、购物车管理:添加购入车要先查询购物车中是否已经存在该菜品,若存在则将数量加一,否则插入该条数据。同理删除购物车也要判断菜品数据是否为1,若为了则删除数据否则只将菜品数量减一。

4、用户下单后会对两张表进行操作:orders订单表和orderDetail订单明细表。订单表中的订单包含下单用户等基本信息,订单明细表包含具体的菜品信息。前端发送ajax请求下单,服务端Controllerr调用Service方法,service调用Mapper对数据库表操作向订单表中插入一条数据,然后通过用户id查询购物车进而将具体菜品数据插入订单明细表,最后清空购物车完成用户下单操作。

5、用户查询历史订单时,一个订单对应多条订单明细,因此将order和orderDetail封装成orderDto。分页查询完成后向前端返回分页orderDto详细订单数据。

6、当用户点击再来一单时,前端发送ajax请求,参数为订单id,服务端Controller调用service,service调用mapper对数据库进行操作,最终向前端返回操作结果:

通过订单id获取原订单以及原订单明细。创建新的订单表,根据原订单设置新订单的id和number、时间等信息后插入订单表。创建新的订单明细表,更改新订单明细表中的orderId为新订单的id后插入响应的数据库表。