苍穹外卖学习笔记(六)

一. HttpClient

介绍

HttpClient是Apache Jakarta Common下的子项目,可以用来提供高效的、最新的、功能丰富的支持HTTP协议的客户端编程工具包,并且它支持HTTP协议最新的版本和建议。

1
2
3
4
5
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>

该项目导入了阿里的sdk,传递依赖
核心API:

  1. HttpClient
  2. HttpClients
  3. CloseableHttpClient
  4. HttpGet
  5. HttpPost

发生请求步骤:

  1. 创建HttpClient对象
  2. 创建Http请求对象
  3. 调用HttpClient的execute方法发送请求

入门案例

HttpClientTest.java

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
76
77
package com.sky.test;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class HttpClientTest {

/**
* 测试HttpClient发送get请求
*/
@Test
public void testGet() {
// 创建HttpClient对象
CloseableHttpClient aDefault = HttpClients.createDefault();
// 创建HttpGet对象
HttpGet httpGet = new HttpGet("http://localhost:8080/user/shop/status");
// 发送请求
try {
CloseableHttpResponse execute = aDefault.execute(httpGet);
// 获取响应数据
int statusCode = execute.getStatusLine().getStatusCode();
System.out.println("状态码:" + statusCode);
HttpEntity entity = execute.getEntity();
String string = EntityUtils.toString(entity);
System.out.println("响应数据:" + string);

// 关闭资源
execute.close();
aDefault.close();
} catch (Exception e) {
e.printStackTrace();
}
}


/**
* 测试HttpClient发送post请求
*/
@Test
public void testPost() throws Exception {
// 创建HttpClient对象
CloseableHttpClient aDefault = HttpClients.createDefault();
// 创建HttpPost对象
HttpPost httpPost = new HttpPost("http://localhost:8080/admin/employee/login");
JSONObject jsonObject = new JSONObject();
jsonObject.put("username", "admin");
jsonObject.put("password", "123456");
StringEntity entity = new StringEntity(jsonObject.toString());
// 设置请求头
entity.setContentEncoding("UTF-8");
// 设置请求体
entity.setContentType("application/json");
httpPost.setEntity(entity);
// 发送请求
CloseableHttpResponse execute = aDefault.execute(httpPost);
// 获取响应数据
int statusCode = execute.getStatusLine().getStatusCode();
System.out.println("状态码:" + statusCode);
HttpEntity entity1 = execute.getEntity();
String string = EntityUtils.toString(entity1);
System.out.println("响应数据:" + string);

// 关闭资源
execute.close();
aDefault.close();
}
}

二. 微信登录

applivation.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
sky:
jwt:
# 设置jwt签名加密时使用的秘钥
admin-secret-key: itcast
# 设置jwt过期时间
admin-ttl: 720000000
# 设置前端传递过来的令牌名称
admin-token-name: token
# 设置jwt签名加密时使用的秘钥
user-secret-key: itheima
# 设置jwt过期时间
user-ttl: 720000000
# 设置前端传递过来的令牌名称
user-token-name: authentication
alioss:
endpoint: ${sky.alioss.endpoint}
access-key-id: ${sky.alioss.access-key-id}
access-key-secret: ${sky.alioss.access-key-secret}
bucket-name: ${sky.alioss.bucket-name}
wechat:
appid: ${sky.wechat.appid}
secret: ${sky.wechat.secret}

UserController.java

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
package com.sky.controller.user;

import com.sky.constant.JwtClaimsConstant;
import com.sky.dto.UserLoginDTO;
import com.sky.entity.User;
import com.sky.properties.JwtProperties;
import com.sky.result.Result;
import com.sky.service.UserService;
import com.sky.utils.JwtUtil;
import com.sky.vo.UserLoginVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
* @author Jie.
* @description: TODO
* @date 2024/9/24
* @version: 1.0
*/
@RestController
@RequestMapping("/user/user")
@Api(tags = "用户管理")
@Slf4j
public class UserController {

@Autowired
private UserService userService;

@Autowired
private JwtProperties jwtProperties;

/**
* 用户登录
*
* @param userLoginDTO
* @return
*/
@PostMapping("/login")
@ApiOperation(value = "用户登录")
public Result<UserLoginVO> login(@RequestBody UserLoginDTO userLoginDTO) {
log.info("用户登录:{}", userLoginDTO.getCode());
// 微信登录
User user = userService.wxLogin(userLoginDTO);
//jwt令牌
Map<String, Object> claims = new HashMap<>();
claims.put(JwtClaimsConstant.USER_ID, user.getId());
String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);
UserLoginVO userLoginVO = UserLoginVO.builder()
.id(user.getId())
.openid(user.getOpenid())
.token(token)
.build();
return Result.success(userLoginVO);
}
}

UserMapper.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.sky.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sky.entity.User;
import org.apache.ibatis.annotations.Mapper;

/**
* @author Jie.
* @description: TODO
* @date 2024/9/24
* @version: 1.0
*/
@Mapper
public interface UserMapper extends BaseMapper<User> {
}

UserService.java

1
2
3
4
5
6
7
8
9
public interface UserService {

/**
* 用户登录
*
* @param userLoginDTO
*/
User wxLogin(UserLoginDTO userLoginDTO);
}

UserServiceImpl.java

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
76
77
78
79
80
81
82
83
84
85
package com.sky.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.sky.constant.MessageConstant;
import com.sky.dto.UserLoginDTO;
import com.sky.entity.User;
import com.sky.exception.LoginFailedException;
import com.sky.mapper.UserMapper;
import com.sky.properties.WeChatProperties;
import com.sky.service.UserService;
import com.sky.utils.HttpClientUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
* @author Jie.
* @description: TODO
* @date 2024/9/24
* @version: 1.0
*/

@Service
@Slf4j
public class UserServiceImpl implements UserService {

public static final String WX_LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";

@Autowired
private WeChatProperties weChatProperties;

@Autowired
private UserMapper userMapper;

/**
* 用户登录
*
* @param userLoginDTO
*/
@Override
public User wxLogin(UserLoginDTO userLoginDTO) {
//获取openid
String openid = getOpenid(userLoginDTO.getCode());
//判断openid是否为空,为空登录失败,抛出异常
if (openid == null) {
log.error("登录失败,openid为空");
throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
}
//根据openid查询用户信息,判断用户是否存在,不存在则新增用户
User user = userMapper.selectById(openid);
if (user == null) {
user = User.builder()
.openid(openid)
.createTime(LocalDateTime.now())
.build();
userMapper.insert(user);
}
//返回用户信息
return user;
}

/**
* 获取openid
*
* @param code
* @return
*/
private String getOpenid(String code) {
//调用微信接口服务获取openid
//封装参数
Map<String, String> map = new HashMap<>();
map.put("appid", weChatProperties.getAppid());
map.put("secret", weChatProperties.getSecret());
map.put("js_code", code);
map.put("grant_type", "authorization_code");
String json = HttpClientUtil.doGet(WX_LOGIN_URL, map);
JSONObject jsonObject = JSONObject.parseObject(json);
String openid = jsonObject.getString("openid");
return openid;
}
}

JwtTokenUserInterceptor.java

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
package com.sky.interceptor;

import com.sky.constant.JwtClaimsConstant;
import com.sky.context.BaseContext;
import com.sky.properties.JwtProperties;
import com.sky.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* jwt令牌校验的拦截器
*/
@Component
@Slf4j
public class JwtTokenUserInterceptor implements HandlerInterceptor {

@Autowired
private JwtProperties jwtProperties;

/**
* 校验jwt
*
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

// System.out.println("当前线程的id:" + Thread.currentThread().getId());

//判断当前拦截到的是Controller的方法还是其他资源
if (!(handler instanceof HandlerMethod)) {
//当前拦截到的不是动态方法,直接放行
return true;
}

//1、从请求头中获取令牌
String token = request.getHeader(jwtProperties.getUserTokenName());

//2、校验令牌
try {
log.info("jwt校验:{}", token);
Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);
Long userId = Long.valueOf(claims.get(JwtClaimsConstant.USER_ID).toString());
log.info("当前用户id:", userId);
BaseContext.setCurrentId(userId);
//3、通过,放行
return true;
} catch (Exception ex) {
//4、不通过,响应401状态码
response.setStatus(401);
return false;
}
}
}

WebMvcConfiguration.java

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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package com.sky.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import com.sky.interceptor.JwtTokenAdminInterceptor;
import com.sky.interceptor.JwtTokenUserInterceptor;
import com.sky.json.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.List;

/**
* 配置类,注册web层相关组件
*/
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {

@Autowired
private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;

@Autowired
private JwtTokenUserInterceptor jwtTokenUserInterceptor;

/**
* 注册自定义拦截器
*
* @param registry
*/
protected void addInterceptors(InterceptorRegistry registry) {
log.info("开始注册自定义拦截器...");
registry.addInterceptor(jwtTokenAdminInterceptor)
.addPathPatterns("/admin/**")
.excludePathPatterns("/admin/employee/login");
registry.addInterceptor(jwtTokenUserInterceptor)
.addPathPatterns("/user/**")
.excludePathPatterns("/user/user/login")
.excludePathPatterns("/user/shop/status");
}


/**
* 通过knife4j生成接口文档
*
* @return
*/
@Bean
public Docket docket1() {
ApiInfo apiInfo = new ApiInfoBuilder()
.title("苍穹外卖项目接口文档")
.version("2.0")
.description("苍穹外卖项目接口文档")
.build();
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.groupName("admin")
.apiInfo(apiInfo)
.select()
.apis(RequestHandlerSelectors.basePackage("com.sky.controller.admin"))
.paths(PathSelectors.any())
.build();
return docket;
}

@Bean
public Docket docket2() {
ApiInfo apiInfo = new ApiInfoBuilder()
.title("苍穹外卖项目接口文档")
.version("2.0")
.description("苍穹外卖项目接口文档")
.build();
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.groupName("user")
.apiInfo(apiInfo)
.select()
.apis(RequestHandlerSelectors.basePackage("com.sky.controller.user"))
.paths(PathSelectors.any())
.build();
return docket;
}
/**
* 设置静态资源映射
*
* @param registry
*/
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}

/**
* 配置消息转换器
*
* @param converters
*/
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
log.info("配置消息转换器...");
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(new JacksonObjectMapper());
converters.add(0, converter);
}

/**
* 配置 MyBatis-Plus 的全局设置
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
log.info("配置 MyBatis-Plus 的全局设置...");
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
// 多租户插件
// interceptor.addInnerInterceptor(new TenantLineInnerInterceptor());
// 防止全表更新与删除插件
// interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
return interceptor;
}
}

三. 导入商品浏览功能代码

由于user的Controller与admin的相同,记得修改RestController注释

1. 查询分类

CategoryController

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
package com.sky.controller.user;

import com.sky.entity.Category;
import com.sky.result.Result;
import com.sky.service.CategoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
* @author Jie.
* @description: TODO
* @date 2024/9/24
* @version: 1.0
*/
@RestController("userCategoryController")
@RequestMapping("/user/category")
@Api(tags = "分类管理")
@Slf4j
public class CategoryController {

@Autowired
private CategoryService categoryService;

@GetMapping("/list")
@ApiOperation("条件查询")
public Result<List<Category>> listCategory(Integer type) {
log.info("条件查询:type={}", type);
List<Category> list = categoryService.listCategory(type);
return Result.success(list);
}

}

业务层方法与admin的相同,使用同一个

2. 根据分类ID查询菜品

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
43
44
45
46
package com.sky.controller.user;

import com.sky.constant.StatusConstant;
import com.sky.entity.Dish;
import com.sky.result.Result;
import com.sky.service.DishService;
import com.sky.vo.DishVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
* @author Jie.
* @description: TODO
* @date 2024/9/25
* @version: 1.0
*/
@RestController("userDishController")
@RequestMapping("/user/dish")
@Api(tags = "菜品管理")
@Slf4j
public class DishController {

@Autowired
private DishService dishService;

/**
* 根据分类id查询菜品
*/
@GetMapping("/list")
@ApiOperation("根据分类id查询菜品")
public Result<List<DishVO>> list(Long categoryId) {
Dish dish = new Dish();
dish.setCategoryId(categoryId);
dish.setStatus(StatusConstant.ENABLE);
List<DishVO> list = dishService.listWithFlavor(dish);
return Result.success(list);
}
}

Service

1
2
3
4
/**
* 根据菜品id查询菜品
*/
List<DishVO> listWithFlavor(Dish dish);

Impl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 根据菜品id查询菜品
*/
@Override
public List<DishVO> listWithFlavor(Dish dish) {
// 查询菜品
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Dish::getCategoryId, dish.getCategoryId());
queryWrapper.eq(Dish::getStatus, StatusConstant.ENABLE);
List<Dish> dishes = dishMapper.selectList(queryWrapper);
List<DishVO> dishVOList = new ArrayList<>();
for (Dish d : dishes) {
DishVO dishVO = new DishVO();
BeanUtils.copyProperties(d, dishVO);
// 查询口味
LambdaQueryWrapper<DishFlavor> flavorQueryWrapper = new LambdaQueryWrapper<>();
flavorQueryWrapper.eq(DishFlavor::getDishId, d.getId());
List<DishFlavor> flavors = dishFlavorMapper.selectList(flavorQueryWrapper);
// 封装结果
dishVO.setFlavors(flavors);
dishVOList.add(dishVO);
}
return dishVOList;
}

3. 根据分类ID查询套餐

SetmealController

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
package com.sky.controller.user;

import com.sky.constant.StatusConstant;
import com.sky.entity.Setmeal;
import com.sky.result.Result;
import com.sky.service.SetmealService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
* @author Jie.
* @description: TODO
* @date 2024/9/25
* @version: 1.0
*/
@RestController("userSetmealController")
@RequestMapping("/user/setmeal")
@Api(tags = "套餐管理")
@Slf4j
public class SetmealController {

@Autowired
private SetmealService setmealService;

/*
* 根据分类id查询套餐
*/
@GetMapping("/list")
@ApiOperation("套餐列表")
public Result<List<Setmeal>> list(Long categoryId) {
Setmeal setmeal = new Setmeal();
setmeal.setCategoryId(categoryId);
setmeal.setStatus(StatusConstant.ENABLE);

List<Setmeal> list = setmealService.list(setmeal);
return Result.success(list);
}
}

Service

1
2
3
4
 /**
* 查询套餐列表
*/
List<Setmeal> list(Setmeal setmeal);

Impl

1
2
3
4
5
6
7
8
9
10
/**
* 查询套餐列表
*/
@Override
public List<Setmeal> list(Setmeal setmeal) {
LambdaQueryWrapper<Setmeal> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(setmeal.getCategoryId() != null, Setmeal::getCategoryId, setmeal.getCategoryId());
lambdaQueryWrapper.eq(setmeal.getStatus() != null, Setmeal::getStatus, setmeal.getStatus());
return setmealMapper.selectList(lambdaQueryWrapper);
}

4. 根据套餐ID查询菜品

controller

1
2
3
4
5
6
7
8
9
/**
* 根据套餐id查询包含的菜品
*/
@GetMapping("/dish/{id}")
@ApiOperation("根据套餐id查询包含的菜品")
public Result<List<DishItemVO>> dishList(@PathVariable Long id) {
List<DishItemVO> list = setmealService.getDishItemById(id);
return Result.success(list);
}

service

1
2
3
4
5

/**
* 根据套餐id查询包含的菜品
*/
List<DishItemVO> getDishItemById(Long id);

impl

1
2
3
4
5
6
7
/**
* 根据套餐id查询包含的菜品列表
*/
@Override
public List<DishItemVO> getDishItemById(Long id) {
return setmealMapper.getDishItemBySetmealId(id);
}

mapper

1
2
3
4
5
6
7
/**
* 根据id查询菜品选项
*/
@Select("select sd.name, sd.copies, d.image, d.description " +
"from setmeal_dish sd left join dish d on sd.dish_id = d.id " +
"where sd.setmeal_id = #{setmealId}")
List<DishItemVO> getDishItemBySetmealId(Long id);