1.新增套餐的功能
分析点击新增套餐时,就已经发送了这几个请求(分别查询了分类名,菜品,套餐分类)
根据分类Id查询菜品
@GetMapping("/list")
public R> getByCategoryId(Dish dish){
//创建条件构造器
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(dish.getCategoryId()!= null,Dish::getCategoryId,dish.getCategoryId());
//只显示起售状态下的菜品 和未删除的
queryWrapper.eq(Dish::getStatus,1);
queryWrapper.eq(Dish::getIsDeleted,0);
queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
List dishList = dishService.list(queryWrapper);
List dishDtoList = dishList.stream().map((item) ->{
DishDto dishDto = new DishDto();
//获取分类id
Long categoryId = item.getCategoryId();
//根据id查询分类信息
Category category = categoryService.getById(categoryId);
if(category != null){
String categoryName = category.getName();
dishDto.setCategoryName(categoryName);
}
BeanUtils.copyProperties(item,dishDto);
Long dishId = item.getId();
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(DishFlavor::getDishId,dishId);
List dishFlavors = dishFlavorService.list(lambdaQueryWrapper);
dishDto.setFlavors(dishFlavors);
return dishDto;
}).collect(Collectors.toList());
return R.success(dishDtoList);
}
根据分类进行查询套餐fenlei以及分类名
@GetMapping("/list")
public R> list(Category category){
//条件构造器
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(category.getType() != null,Category::getType,category.getType());
queryWrapper.orderByAsc(Category::getSort).orderByDesc(Category::getUpdateTime);
List list = categoryService.list(queryWrapper);
return R.success(list);
}
分析前端传来的参数
我们需要用SetmealDto来接收JSON数据,而且需要操作两张表即我们需要自定义一个新增套餐的方法
实现类
/**
* 自定义新增菜品实现
* @param setmealDto
*/
@Transactional
public void saveSetmealWithSetmealDish(SetmealDto setmealDto) {
//添加套餐到数据库
this.save(setmealDto);
//获取套餐包含的菜品表
List setmealDishes = setmealDto.getSetmealDishes();
Long setmealDtoId = setmealDto.getId();
setmealDishes = setmealDishes.stream().map((item) ->{
item.setSetmealId(setmealDtoId);
return item;
}).collect(Collectors.toList());
setmealDishService.saveBatch(setmealDishes);
}
使用Controller进行调用
/**
*
* 新增套餐
* @param setmealDto
* @return
*/
@PostMapping
public R save(@RequestBody SetmealDto setmealDto){
setmealService.saveSetmealWithSetmealDish(setmealDto);
return R.success("新增套餐成功!");
}
2.分页查询进行页面展示
分析前端传来的参数
Controller实现
/**
* 分页查询套餐信息
* @param page
* @param pageSize
* @param name
* @return
*/
@GetMapping("/page")
public R page(int page,int pageSize,String name){
//创建分页对象
Page pageInfo = new Page<>(page,pageSize);
//创建条件构造器
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
//条件构造器
queryWrapper.like(StringUtils.isNotEmpty(name),Setmeal::getName,name);
//排序构造器
queryWrapper.orderByDesc(Setmeal::getUpdateTime);
setmealService.page(pageInfo,queryWrapper);
Page pageDto = new Page<>(page,pageSize);
//对象拷贝
BeanUtils.copyProperties(pageInfo,pageDto,"records");
List records = pageInfo.getRecords();
List list = records.stream().map((item) ->{
Long categoryId = item.getCategoryId();
Category category = categoryService.getById(categoryId);
String categoryName = category.getName();
SetmealDto setmealDto = new SetmealDto();
setmealDto.setCategoryName(categoryName);
BeanUtils.copyProperties(item,setmealDto);
return setmealDto;
}).collect(Collectors.toList());
pageDto.setRecords(list);
return R.success(pageDto);
}
3修改套餐功能实现
首先我们需要进行数据的回显
实现类
/**
* 查询套餐和菜品用于页面的回显
* @param id
* @return
*/
public SetmealDto getByIdWithSetMealDish(Long id) {
//根据id查询套餐表
Setmeal setmeal = this.getById(id);
//根据套餐id查询所对应的菜品
//构造条件封装
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SetmealDish::getSetmealId,id);
queryWrapper.eq(SetmealDish::getIsDeleted,0);
List setmealDishes = setmealDishService.list(queryWrapper);
//获取分类id,根据分类id查询分类名称
Long categoryId = setmeal.getCategoryId();
Category category = categoryService.getById(categoryId);
String categoryName = category.getName();
SetmealDto setmealDto = new SetmealDto();
//对象拷贝
BeanUtils.copyProperties(setmeal,setmealDto);
setmealDto.setSetmealDishes(setmealDishes);
setmealDto.setCategoryName(categoryName);
return setmealDto;
}
Controller调用
/**
*获取套餐以及所包含的菜品信息用于页面回显
* @param id
* @return
*/
@GetMapping("/{id}")
public R getByid(@PathVariable Long id){
SetmealDto setmealDto = setmealService.getByIdWithSetMealDish(id);
return R.success(setmealDto);
}
进行修改
分析前端传来的参数
自定义一个修改套餐的方法
实现类
/**
* 修改套餐信息
* @param setmealDto
*/
@Override
public void updateSetmealWithDish(SetmealDto setmealDto) {
//对套餐表直接修改
this.updateById(setmealDto);
//对包含的菜品表先清除在添加
Long setmealId = setmealDto.getId();
//构建条件构造器
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SetmealDish::getSetmealId,setmealId);
setmealDishService.remove(queryWrapper);
List setmealDishes = setmealDto.getSetmealDishes();
setmealDishes = setmealDishes.stream().map((item) ->{
item.setSetmealId(setmealId);
return item;
}).collect(Collectors.toList());
setmealDishService.saveBatch(setmealDishes);
}
使用Controller进行调用
/**
* 修改套餐
* @param setmealDto
* @return
*/
@PutMapping
public R update(@RequestBody SetmealDto setmealDto){
setmealService.updateSetmealWithDish(setmealDto);
return R.success("修改套餐成功");
}
4.(批量)停售启售 套餐
/**
* 停售套餐
* @param ids
* @return
*/
@PostMapping("/status/0")
public R updateStatusIsStop(@RequestParam List ids){
for (Long id : ids) {
Setmeal setmeal = new Setmeal();
setmeal.setId(id);
setmeal.setStatus(0);
setmealService.updateById(setmeal);
}
return R.success("停售套餐成功");
}
/**
* 启售套餐
* @param ids
* @return
*/
@PostMapping("/status/1")
public R updateStatusIsStart(@RequestParam List ids){
for (Long id : ids) {
Setmeal setmeal = new Setmeal();
setmeal.setId(id);
setmeal.setStatus(1);
setmealService.updateById(setmeal);
}
return R.success("启售套餐品成功");
}
5.(批量)删除套餐(删除套餐以及套餐包含的菜品表)并且只有停售的套餐才可以删除,自定义一个删除的方法
/**
* 删除套餐以及关联的菜品
* @param ids
*/
public void deleteWithDish(List ids) {
//根据id查询套餐是否是在售状态,select count(*) from setmeal where id in (ids) and status =1;
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(Setmeal::getId,ids);
queryWrapper.eq(Setmeal::getStatus,1);
int count = this.count(queryWrapper);
//如果在售状态,则不能删除,抛一个业务异常
if(count>0){
throw new CustomExepction("套餐正在售卖中,不能删除");
}
//否则删除
this.removeByIds(ids);
//构造条件构造器
LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.in(SetmealDish::getSetmealId,ids);
//删除套餐关联的菜品
setmealDishService.remove(lambdaQueryWrapper);
}
Controller的调用
/**
* 删除与批量删除套餐及菜品
* @param ids
* @return
*/
@DeleteMapping
public R deleteAll(@RequestParam List ids){
setmealService.deleteWithDish(ids);
return R.success("删除套餐成功");
}
6.用户登录功能实现(使用阿里云发送验证码)
首先先对手机端的路径放行
在拦截器上判断用户是否登录
//3-2.判断用户是否登录
if(request.getSession().getAttribute("user") != null){
Long userId = (Long) request.getSession().getAttribute("user");
BaseContext.setCurrentId(userId);
//log.info("用户已登录,用户的id为:{}",request.getSession().getAttribute("employee"));
filterChain.doFilter(request,response);
return;
}
//4.如果未登录则返回未登录的结果,通过输出流的方式向客户端响应数据
//log.info("用户未登录");
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
return;
}
用户输入手机号点击发送验证码发送请求
在Controller完成此功能
@PostMapping("/sendMsg")
public R sendMsg(@RequestBody User user, HttpSession session){
//获取手机号
String phone = user.getPhone();
//判断手机号是否存在
if(StringUtils.isNotEmpty(phone)){
//若存在,生成一个随机4位验证码
String code = ValidateCodeUtils.generateValidateCode(4).toString();
log.info("code= {}",code);
//发送验证码
SMSUtils.sendMessage("签名名称","模板Code",phone,code);
//将验证码存入到session中
session.setAttribute(phone,code);
return R.success("验证码发送成功");
}
return R.error("验证码发送失败");
}
使用ValidateCodeUtils工具类生成一个指定长度的验证码
/**
* 随机生成验证码工具类
*/
public class ValidateCodeUtils {
/**
* 随机生成验证码
* @param length 长度为4位或者6位
* @return
*/
public static Integer generateValidateCode(int length){
Integer code =null;
if(length == 4){
code = new Random().nextInt(9999);//生成随机数,最大为9999
if(code < 1000){
code = code + 1000;//保证随机数为4位数字
}
}else if(length == 6){
code = new Random().nextInt(999999);//生成随机数,最大为999999
if(code < 100000){
code = code + 100000;//保证随机数为6位数字
}
}else{
throw new RuntimeException("只能生成4位或6位数字验证码");
}
return code;
}
/**
* 随机生成指定长度字符串验证码
* @param length 长度
* @return
*/
public static String generateValidateCode4String(int length){
Random rdm = new Random();
String hash1 = Integer.toHexString(rdm.nextInt());
String capstr = hash1.substring(0, length);
return capstr;
}
}
使用SMSUtils工具类进行短信的发送
/**
* 短信发送工具类
*/
public class SMSUtils {
/**
* 发送短信
* @param signName 签名
* @param templateCode 模板
* @param phoneNumbers 手机号
* @param param 参数
*/
public static void sendMessage(String signName, String templateCode,String phoneNumbers,String param){
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "", "");
IAcsClient client = new DefaultAcsClient(profile);
SendSmsRequest request = new SendSmsRequest();
request.setSysRegionId("cn-hangzhou");
request.setPhoneNumbers(phoneNumbers);
request.setSignName(signName);
request.setTemplateCode(templateCode);
request.setTemplateParam("{\"code\":\""+param+"\"}");
try {
SendSmsResponse response = client.getAcsResponse(request);
System.out.println("短信发送成功");
}catch (ClientException e) {
e.printStackTrace();
}
}
}
实现登录功能(校验验证码是否正确,先判断该用户是否存在,如果不存在直接注册)
@PostMapping("/login")
public R login(@RequestBody Map map,HttpSession session){
//获取手机号
String phone = map.get("phone").toString();
//获取验证码
String code = map.get("code").toString();
//从Session中获取验证码
Object codeInSession = session.getAttribute(phone);
//进行验证码校验
if(codeInSession != null && code.equals(codeInSession)){
//如果正确则登录成功,判断用户是否为新用户
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getPhone,phone);
User user = userService.getOne(queryWrapper);
if(user == null){
user = new User();
user.setPhone(phone);
userService.save(user);
}
session.setAttribute("user",user.getId());
return R.success(user);
}
return R.error("登录失败");
}
退出登录功能的实现
/**
* 退出登录
* @return
*/
@PostMapping("/loginout")
public R logout(HttpServletRequest request){
//清理session中的指定数据
request.getSession().removeAttribute("user");
return R.success("退出成功");
}