员工登录

重温session

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    /**
* 员工登录
*
* @param request
* @param employee
* @return
*/
@PostMapping("/login")
public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee) {

// 1、将页面提交的密码password进行md5加密处理
String password = employee.getPassword();
password = DigestUtils.md5DigestAsHex(password.getBytes());

//2、根据页面提交的用户名username查询数据库
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Employee::getUsername, employee.getUsername());
Employee emp = employeeService.getOne(queryWrapper);

//3、如果没有查询到则返回登陆失败结果
if (emp == null) {
return R.error("用户名不存在,登陆失败");
}

//4、密码比对,如果不一致则返回登录失败结果
if (!emp.getPassword().equals(password)) {
return R.error("密码错误,登陆失败");
}

//5、查看员工状态,如果为已禁用状态,则返回员工已禁用结果
if (emp.getStatus() == 0) {
return R.error("账号已禁用,无法登录");
}

//6、登陆成功,将员工的id存入Session并返回登录成功结果
request.getSession().setAttribute("employee", emp.getId());//数据是通过键值对存储的
return R.success(emp);
}

停售启售套餐操作

Controller部分
难点在于要考虑菜品是否是停用状态,要查询两次数据库,然后stream流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* 更新套餐停售启售状态
* @param status
* @param ids
* @return
*/
@PostMapping("/status/{status}")
public R<String> status(@PathVariable Integer status,@RequestParam List<Long> ids){
//首先根据ids把setmeal对象获取出来,然后根据status更新数据
ids.stream().map((item) ->{
LambdaQueryWrapper<Setmeal> queryWrapper =new LambdaQueryWrapper<>();
queryWrapper.eq(Setmeal::getId,item);
Setmeal one = setmealService.getOne(queryWrapper);
//但是如果套餐里面有一个菜品是停售的状态,那么则修改状态失败,抛出业务异常
LambdaQueryWrapper<SetmealDish> queryWrapper1 =new LambdaQueryWrapper<>();
queryWrapper1.eq(SetmealDish::getSetmealId,one.getId());
List<SetmealDish> setmealDishes = setmealDishService.list(queryWrapper1);

for (SetmealDish setmealDish : setmealDishes) {
LambdaQueryWrapper<Dish> queryWrapper2 =new LambdaQueryWrapper<>();
queryWrapper2.eq(Dish::getId, setmealDish.getDishId());
Dish dish = dishService.getOne(queryWrapper2);
if (dish.getStatus() == 1) {
//表示有菜品在售,无法调整套餐状态,不能变成停售
throw new CustomException("该套餐中有菜品在售,无法停售");
}
}
one.setStatus(status);
setmealService.update(one, queryWrapper);
return one;
}).collect(Collectors.toList());
return R.success("套餐状态更新成功");
}

添加购物车操作

Controller部分
难点在于查询菜品和套餐,这里算法居然在前端?黑马前端真的顶

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
* 添加购物车
*
* @param shoppingCart
* @return
*/
@PostMapping("/add")
public R<ShoppingCart> add(@RequestBody ShoppingCart shoppingCart) {

//设置用户id,指定当前是哪个用户的购物车数据
Long currentId = BaseContext.getCurrentId();
shoppingCart.setUserId(currentId);

LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ShoppingCart::getUserId, currentId);
//查询当前菜品或菜品是否在购物车中
Long dishId = shoppingCart.getDishId();
if (dishId != null) {
//添加到购物车的是菜品
queryWrapper.eq(ShoppingCart::getDishId, dishId);
} else {
//添加到购物车的是套餐
queryWrapper.eq(ShoppingCart::getSetmealId, shoppingCart.getSetmealId());
}
ShoppingCart cartServiceOne = shoppingCartService.getOne(queryWrapper);

if (cartServiceOne != null) {
//如果已经存在,就在原来的数量基础上加一
Integer number = cartServiceOne.getNumber();
cartServiceOne.setNumber(number + 1);
shoppingCartService.updateById(cartServiceOne);
} else {
//如果不存在,则添加购物车,数量默认就是一
shoppingCart.setNumber(1);
shoppingCart.setCreateTime(LocalDateTime.now());
shoppingCartService.save(shoppingCart);
cartServiceOne = shoppingCart;
}

//如果不存在,则添加到购物车,数量默认就是一
return R.success(cartServiceOne);
}

删减购物车操作

难点在于只有一个商品再减直接删除数据库数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**
* 购物车商品减一功能,只有一个商品再减直接删除数据库数据
* @param shoppingCart
* @return
*/
@PostMapping("/sub")
public R<ShoppingCart> sub(@RequestBody ShoppingCart shoppingCart) {
//设置用户id,指定当前是哪个用户的购物车数据
Long currentId = BaseContext.getCurrentId();
shoppingCart.setUserId(currentId);

LambdaQueryWrapper<ShoppingCart> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ShoppingCart::getUserId, currentId);
//查询当前菜品或菜品是否在购物车中
Long dishId = shoppingCart.getDishId();
if (dishId != null) {
//减少操作到购物车的是菜品
queryWrapper.eq(ShoppingCart::getDishId, dishId);
} else {
//减少操作到购物车的是套餐
queryWrapper.eq(ShoppingCart::getSetmealId, shoppingCart.getSetmealId());
}
ShoppingCart cartServiceOne = shoppingCartService.getOne(queryWrapper);

//如果已经存在,就在原来的数量基础上减一
Integer number = cartServiceOne.getNumber();
if (number > 1) {
cartServiceOne.setNumber(number - 1);
shoppingCartService.updateById(cartServiceOne);
} else {
//number = 1 在减的话就不要这个订单了,直接删库数据
cartServiceOne.setNumber(0);
shoppingCartService.updateById(cartServiceOne);
shoppingCartService.removeById(cartServiceOne);
}

return R.success(cartServiceOne);
}

文件上传和下载(重点)

重温了一下IO流,并且和web结合使用,收获满满

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
    /**
* 文件上传和下载
*/
@RestController
@RequestMapping("/common")
@Slf4j
public class CommonController {
@Value("${reggie.path}")
private String basePath;

/**
* 文件上传
*
* @param file
* @return
*/
@PostMapping("/upload")
public R<String> upload(MultipartFile file) {//参数名必须和前端的name要保持一致
//file是一个临时文件,需要转存到指定位置,否则本次请求完成后临时文件会删除
log.info(file.toString());

//原始文件名
String originalFilename = file.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));//切割后为 .jpg

//使用UUID重新生成文件名,防止文件名重复造成文件覆盖
String fileName = UUID.randomUUID().toString() + suffix;//拼接成新的文件名称

//创建一个目录对象
File dir = new File(basePath);
//判断当前目录是否存在
if (!dir.exists()) {
//目录不存在,创建新文件夹
dir.mkdir();
}

try {
//将临时文件转存到指定位置
file.transferTo(new File(basePath + fileName));
} catch (IOException e) {
e.printStackTrace();
}

return R.success(fileName);
}

/**
* 文件下载
*
* @param name
* @param response
*/
@GetMapping("/download")
public void download(String name, HttpServletResponse response) {
try {
//输入流,通过输入流读取文件内容
FileInputStream fileInputStream = new FileInputStream(new File(basePath + name));
//输出流,通过输出流将文件写回浏览器,在浏览器里面显示图片,这里已经从形参中拿到了响应数据
ServletOutputStream outputStream = response.getOutputStream();

response.setContentType("image/jpeg");

int len =0;
byte[] bytes =new byte[1024];
while ((len =fileInputStream.read(bytes)) != -1){
outputStream.write(bytes,0,len);
outputStream.flush();
}
//关闭流
outputStream.close();
fileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}

这里挑选了一些我认为重要的知识点,也是对瑞吉外卖完结的一个痕迹。真的学到了好多,Blog的知识点也是有一点在这里累计起来的。
下一个是SpringBoot2!