整理记录下学习整个瑞吉外卖项目,详细代码可在我的Gitee仓库瑞吉外卖实战克隆下载学习使用!
![![[Pasted image 20230304152742.png]]](https://img.pic99.top/hhfamen/202406/104c15d4c49f9c1.png)
新增套餐就是将新增页面录入的套餐信息插入到setmeal表,还向setmeal_dish表插入套餐和菜品关联数据,涉及到两个表:
![![[Pasted image 20230304153100.png]]](https://img.pic99.top/hhfamen/202406/22cfc918fbfdf74.png)
![![[Pasted image 20230304153116.png]]](https://img.pic99.top/hhfamen/202406/27be7f5bfb5a.png)
@Data
public class SetmealDish implements Serializable { private static final long serialVersionUID = 1L; private Long id; //套餐id private Long setmealId; //菜品id private Long dishId; //菜品名称 (冗余字段) private String name; //菜品原价 private BigDecimal price; //份数 private Integer copies; //排序 private Integer sort; @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; @TableField(fill = FieldFill.INSERT) private Long createUser; @TableField(fill = FieldFill.INSERT_UPDATE) private Long updateUser; //是否删除 private Integer isDeleted;
}
@RestController
@RequestMapping("/setmeal")
@Slf4j
@RequiredArgsConstructor
public class SetmealhController {
}
@Data
public class SetmealDto extends Setmeal { private List setmealDishes; private String categoryName;
}
@GetMapping("/list")
public Result> list(Dish dish){ //构造查询条件 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(dish.getCategoryId() != null ,Dish::getCategoryId,dish.getCategoryId()); //添加条件,查询状态为1(起售状态)的菜品 queryWrapper.eq(Dish::getStatus,1); //添加排序条件
queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime); List list = dishService.list(queryWrapper); return Result.success(list);
}
@Transactional
public void saveWithFlavor(DishDto dishDto) { //保存菜品的基本信息到菜品表dish this.save(dishDto); Long dishId = dishDto.getId();//菜品id //菜品口味 List flavors = dishDto.getFlavors(); flavors = flavors.stream().map((item) -> { item.setDishId(dishId); return item; }).collect(Collectors.toList()); //保存菜品口味数据到菜品口味表dish_flavor dishFlavorService.saveBatch(flavors);
}
@PostMapping public Result save(@RequestBody SetmealDto setmealDto) { log.info("套餐信息:{}", setmealDto); setmealService.saveWithDish(setmealDto); return Result.success("新增套餐成功"); }
添加信息,如图![![[Pasted image 20230304163744.png]]](https://img.pic99.top/hhfamen/202406/5d27ca1a6c4e43c.png)
看到数据库添加成功,如图
@GetMapping("/page")
public Result page(int page, int pageSize, String name) { Page setmealPage = new Page<>(page,pageSize); Page setmealDtoIPage = new Page<>(); LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); lambdaQueryWrapper.like(name != null,Setmeal::getName,name); setmealService.page(setmealPage,lambdaQueryWrapper); BeanUtils.copyProperties(setmealPage,setmealDtoIPage,"records"); List list = setmealPage.getRecords().stream().map((iterm)->{ SetmealDto setmealDto = new SetmealDto(); BeanUtils.copyProperties(iterm,setmealDto); Long categoryId = iterm.getCategoryId(); String categoryName = categoryService.getById(categoryId).getName(); if(categoryName != null) setmealDto.setCategoryName(categoryName); return setmealDto; }).collect(Collectors.toList()); setmealDtoIPage.setRecords(list); return Result.success(setmealDtoIPage);
}
重启项目后结果如图![![[Pasted image 20230304165749.png]]](https://img.pic99.top/hhfamen/202406/e88b56a97eedf.png)
![![[Pasted image 20230304165829.png]]](https://img.pic99.top/hhfamen/202406/4b49c8e0545bf97.png)
@Transactional
public void removeWithDish(List ids) { //select count(*) from setmeal where id in (1,2,3) and status = 1 //查询套餐状态,确定是否可用删除 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); queryWrapper.in(Setmeal::getId,ids); queryWrapper.eq(Setmeal::getStatus,1); int count = (int) this.count(queryWrapper); if(count > 0){ //如果不能删除,抛出一个业务异常 throw new CustomException("套餐正在售卖中,不能删除"); } //如果可以删除,先删除套餐表中的数据---setmeal this.removeByIds(ids); //delete from setmeal_dish where setmeal_id in (1,2,3) LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); lambdaQueryWrapper.in(SetmealDish::getSetmealId,ids); //删除关系表中的数据----setmeal_dish setmealDishService.remove(lambdaQueryWrapper);
}
@DeleteMapping
public Result delete(@RequestParam List ids) { log.info("ids:{}", ids); setmealService.removeWithDish(ids); return Result.success("套餐数据删除成功");
}
修改数据库套餐为停售状态,并进行删除操作,如图
![![[Pasted image 20230304172353.png]]
![[Pasted image 20230304172835.png]]](https://img.pic99.top/hhfamen/202406/9e8872fe84fef64.png)
删除成功![![[Pasted image 20230304172917.png]]](https://img.pic99.top/hhfamen/202406/6a72fe4a18c48b1.png)
用户通过输入手机号后收到相应的短信验证码,输入验证码后才能进行登录。一般用的是阿里云、腾讯云等平台提供的API接口来做,这里仅仅是用普通方式进行模拟操作。
这里用户只有手机号和验证码来进行验证登录,表是User表,结构如下:
![![[Pasted image 20230304212751.png]]](https://img.pic99.top/hhfamen/202406/a0799fe0c9e0.png)
@Data
public class User implements Serializable { private static final long serialVersionUID = 1L; private Long id; //姓名 private String name; //手机号 private String phone; //性别 0 女 1 男 private String sex; //身份证号 private String idNumber; //头像 private String avatar; //状态 0:禁用,1:正常 private Integer status;
}
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; }
}
@RestController
@RequestMapping("/user")
@Slf4j
@RequiredArgsConstructor
public class UserController { private final UserService userService; //移动端用户登录时发送短信 @PostMapping("/sendMsg") public Result sendMsg(@RequestBody User user, HttpSession session) throws MessagingException { String phone = user.getPhone(); if (!phone.isEmpty()) { //随机生成一个验证码 String code = ValidateCodeUtils.generateValidateCode4String(4); log.info(code); //验证码存session,方便后面拿出来比对 session.setAttribute(phone, code); return Result.success("验证码发送成功"); } return Result.error("验证码发送失败"); } /** * 移动端用户登录 * @param map * @param session * @return */ @PostMapping("/login") public Result login(@RequestBody Map map, HttpSession session){ log.info(map.toString()); //获取手机号 String phone = map.get("phone").toString(); //获取验证码 String code = map.get("code").toString(); //从Session中获取保存的验证码 Object codeInSession = session.getAttribute(phone); //进行验证码的比对(页面提交的验证码和Session中保存的验证码比对) if(codeInSession != null && codeInSession.equals(code)){ //如果能够比对成功,说明登录成功 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(User::getPhone,phone); User user = userService.getOne(queryWrapper); if(user == null){ //判断当前手机号对应的用户是否为新用户,如果是新用户就自动完成注册 user = new User(); user.setPhone(phone); user.setStatus(1); userService.save(user); } session.setAttribute("user",user.getId()); return Result.success(user); } return Result.error("登录失败"); } //移动端用户退出 @PostMapping("/loginout") public Result logout(HttpServletRequest request) { request.getSession().removeAttribute("user"); return Result.success("退出成功"); }
}
![![[Pasted image 20230304213709.png]]](https://img.pic99.top/hhfamen/202406/cbf1d025b802.png)
![![[Pasted image 20230304215757.png]]](https://img.pic99.top/hhfamen/202406/c52add66b47f.png)
打开移动端登录页面,设置浏览器模式为手机,如图

输入手机号并点击获取验证码填在前台完成登录,如图
![![[Pasted image 20230304215639.png]]](https://img.pic99.top/hhfamen/202406/6eec818defe2f21.png)
![![[Pasted image 20230304215958.png]]](https://img.pic99.top/hhfamen/202406/1fcebec11ad2799.png)
![![[Pasted image 20230304205146.png]]
![[Pasted image 20230304205226.png]]](https://img.pic99.top/hhfamen/202406/0d9a68ca281dacf.png)
用户地址信息存储在address_book表中,结构如下:
![![[Pasted image 20230304205330.png]]](https://img.pic99.top/hhfamen/202406/e31670910c03c97.png)
@Data
public class AddressBook implements Serializable { private static final long serialVersionUID = 1L; private Long id; //用户id private Long userId; //收货人 private String consignee; //手机号 private String phone; //性别 0 女 1 男 private String sex; //省级区划编号 private String provinceCode; //省级名称 private String provinceName; //市级区划编号 private String cityCode; //市级名称 private String cityName; //区级区划编号 private String districtCode; //区级名称 private String districtName; //详细地址 private String detail; //标签 private String label; //是否默认 0 否 1是 private Integer isDefault; //创建时间 @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; //更新时间 @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; //创建人 @TableField(fill = FieldFill.INSERT) private Long createUser; //修改人 @TableField(fill = FieldFill.INSERT_UPDATE) private Long updateUser; //是否删除 private Integer isDeleted;
}
@Slf4j
@RestController
@RequestMapping("/addressBook")
@RequiredArgsConstructor
public class AddressBookController { private final AddressBookService addressBookService; /** * 新增 */ @PostMapping public Result save(@RequestBody AddressBook addressBook) { addressBook.setUserId(BaseContext.getCurrentId()); log.info("addressBook:{}", addressBook); addressBookService.save(addressBook); return Result.success(addressBook); } /** * 设置默认地址 */ @PutMapping("default") public Result setDefault(@RequestBody AddressBook addressBook) { log.info("addressBook:{}", addressBook); LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>(); wrapper.eq(AddressBook::getUserId, BaseContext.getCurrentId()); wrapper.set(AddressBook::getIsDefault, 0); //SQL:update address_book set is_default = 0 where user_id = ? addressBookService.update(wrapper); addressBook.setIsDefault(1); //SQL:update address_book set is_default = 1 where id = ? addressBookService.updateById(addressBook); return Result.success(addressBook); } /** * 查询默认地址 */ @GetMapping("/default") public Result getDefault() { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(AddressBook::getUserId, BaseContext.getCurrentId()); queryWrapper.eq(AddressBook::getIsDefault, 1); //SQL:select * from address_book where user_id = ? and is_default = 1 AddressBook addressBook = addressBookService.getOne(queryWrapper); if (null == addressBook) { return Result.error("没有找到该对象"); } else { return Result.success(addressBook); } } /** * 查询指定用户的全部地址 */ @GetMapping("/list") public Result> list(AddressBook addressBook) { addressBook.setUserId(BaseContext.getCurrentId()); log.info("addressBook:{}", addressBook); //条件构造器 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(null != addressBook.getUserId(), AddressBook::getUserId, addressBook.getUserId()); queryWrapper.orderByDesc(AddressBook::getUpdateTime); //SQL:select * from address_book where user_id = ? order by update_time desc return Result.success(addressBookService.list(queryWrapper)); } //查询当前用户使用的地址 @GetMapping("/{id}") public Result getById(@PathVariable Long id) { AddressBook addressBook = addressBookService.getById(id); if (addressBook == null){ throw new CustomException("地址信息不存在"); } return Result.success(addressBook); } //修改用户地址 @PutMapping public Result updateAdd(@RequestBody AddressBook addressBook) { if (addressBook == null) { throw new CustomException("地址信息不存在,请刷新重试"); } addressBookService.updateById(addressBook); return Result.success("地址修改成功"); } //删除用户地址 @DeleteMapping public Result deleteAdd(@RequestParam("ids") Long id) { if (id == null) { throw new CustomException("地址信息不存在,请刷新重试"); } AddressBook addressBook = addressBookService.getById(id); if (addressBook == null) { throw new CustomException("地址信息不存在,请刷新重试"); } addressBookService.removeById(id); return Result.success("地址删除成功"); }
}
![![[Pasted image 20230304220317.png]]](https://img.pic99.top/hhfamen/202406/b3166ab60ddeda6.png)
![![[Pasted image 20230304220450.png]]](https://img.pic99.top/hhfamen/202406/94f15308c9a6b24.png)
![![[Pasted image 20230304235401.png]]](https://img.pic99.top/hhfamen/202406/3119e2a12dd6e8a.png)
![![[Pasted image 20230304235425.png]]](https://img.pic99.top/hhfamen/202406/be40ac6247d3dc0.png)
![![[Pasted image 20230304235530.png]]](https://img.pic99.top/hhfamen/202406/d578d0e20f552a9.png)
![![[Pasted image 20230304235545.png]]](https://img.pic99.top/hhfamen/202406/7c50c0df9e06ea.png)