标签:java 第四天 Long public 外卖 套餐 苍穹 id setmeal
套餐管理
新增套餐
需求分析和设计
产品原型
新增套餐
添加菜品窗口
业务规则
- 套餐名称唯一。
- 套餐必须属于某个分类。
- 套餐必须包含菜品。
- 名称、分类、价格、图片为必填项。
- 添加菜品窗口需要根据分类类型来展示菜品。
- 新增的套餐默认为停售状态。
接口设计
根据类型查询分类(已完成)
根据分类id查询菜品
图片上传(已完成)
新增套餐
数据库设计
setmeal套餐表
字段名 |
数据类型 |
说明 |
备注 |
id |
bigint |
主键 |
自增 |
name |
varchar(32) |
套餐名称 |
唯一 |
category_id |
bigint |
分类id |
逻辑外键 |
price |
decimal(10,2) |
套餐价格 |
|
image |
varchar(255) |
图片路径 |
|
description |
varchar(255) |
套餐描述 |
|
status |
int |
售卖状态 |
1启售 0停售 |
create_time |
datetime |
创建时间 |
|
update_time |
datetime |
最后修改时间 |
|
create_user |
bigint |
创建人id |
|
update_user |
bigint |
最后修改人id |
|
setmeal_dish套餐菜品关系表
字段名 |
数据类型 |
说明 |
备注 |
id |
bigint |
主键 |
自增 |
setmeal_id |
bigint |
套餐id |
逻辑外键 |
dish_id |
bigint |
菜品id |
逻辑外键 |
name |
varchar(32) |
菜品名称 |
冗余字段 |
price |
decimal(10,2) |
菜品单价 |
冗余字段 |
copies |
int |
菜品份数 |
|
代码开发
根据分类id查询菜品
DishController.java
@GetMapping("/list")
@ApiOperation("根据分类id查询菜品")
public Result<List<Dish>> list(Long categoryId) {
log.info("根据分类id查询菜品:{}", categoryId);
List<Dish> list = dishService.list(categoryId);
return Result.success(list);
}
DishService.java
List<Dish> list(Long categoryId);
DishServiceImpl.java
@Override
public List<Dish> list(Long categoryId) {
Dish dish = Dish.builder()
.categoryId(categoryId)
.status(StatusConstant.ENABLE)
.build();
return dishMapper.list(dish);
}
DishMapper.java
List<Dish> list(Dish dish);
DishMapper.xml
<select id="list" resultType="com.sky.entity.Dish">
select * from dish
<where>
<if test="name != null">and name = #{name}</if>
<if test="categoryId != null">and category_id = #{categoryId}</if>
<if test="status != null">and status = #{status}</if>
</where>
order by create_time desc
</select>
新增套餐
SetmealController.java
@RestController
@Api(tags = "套餐相关接口")
@Slf4j
@RequestMapping("/admin/setmeal")
public class SetmealController {
@Autowired
private SetmealService setmealService;
/**
* 新增套餐
*
* @param setmealDTO
* @return
*/
@PostMapping
@ApiOperation("新增套餐")
public Result save(@RequestBody SetmealDTO setmealDTO) {
log.info("新增套餐:{}", setmealDTO);
setmealService.saveWithDish(setmealDTO);
return Result.success();
}
}
SetmealService.java
public interface SetmealService {
/**
* 新增套餐
*
* @param setmealDTO
*/
void saveWithDish(SetmealDTO setmealDTO);
}
SetmealServiceImpl.java
@Service
public class SetmealServiceImpl implements SetmealService {
@Autowired
private SetmealMapper setmealMapper;
@Autowired
private SetmealDishMapper setmealDishMapper;
/**
* 新增套餐,同时需要保存套餐和菜品的关联关系
*
* @param setmealDTO
*/
@Override
@Transactional
public void saveWithDish(SetmealDTO setmealDTO) {
Setmeal setmeal = new Setmeal();
BeanUtils.copyProperties(setmealDTO, setmeal);
//向套餐表插入数据
setmealMapper.insert(setmeal);
//获取生成的套餐id
Long setmealId = setmeal.getId();
List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
setmealDishes.forEach(setmealDish -> setmealDish.setSetmealId(setmealId));
//保存套餐和菜品的关联关系
setmealDishMapper.insertBatch(setmealDishes);
}
}
SetmealMapper.java
@AutoFill(OperationType.INSERT)
void insert(Setmeal setmeal);
SetmealMapper.xml
<insert id="insert" useGeneratedKeys="true" keyProperty="id">
insert into setmeal (category_id, name, price, status, description, image, create_time, update_time, create_user, update_user) VALUES
(#{categoryId}, #{name}, #{price}, #{status}, #{description}, #{image}, #{createTime}, #{updateTime}, #{createUser}, #{updateUser})
</insert>
SetmealDishMapper.java
void insertBatch(List<SetmealDish> setmealDishes);
SetmealDishMapper.xml
<insert id="insertBatch">
insert into setmeal_dish (setmeal_id, dish_id, name, price, copies) VALUES
<foreach collection="setmealDishes" item="setmealdish" separator=",">
(#{setmealdish.setmealId}, #{setmealdish.dishId}, #{setmealdish.name}, #{setmealdish.price}, #{setmealdish.copies})
</foreach>
</insert>
功能测试
- 可以通过接口文档进行测试,最后完成前后端联调测试即可。
套餐分页查询
需求分析和设计
产品原型
业务规则
- 根据页码进行分页展示。
- 每页展示10条数据。
- 可以根据需要,按照套餐名称、分类、售卖状态进行查询。
接口设计
代码开发
SetmealController.java
@GetMapping("/page")
@ApiOperation("套餐分页查询")
public Result<PageResult> page(SetmealPageQueryDTO setmealPageQueryDTO) {
log.info("套餐分页查询:{}", setmealPageQueryDTO);
PageResult pageResult = setmealService.pageQuery(setmealPageQueryDTO);
return Result.success(pageResult);
}
SetmealService.java
PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO);
SetmealServiceImpl.java
@Override
public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) {
PageHelper.startPage(setmealPageQueryDTO.getPage(), setmealPageQueryDTO.getPageSize());
Page<SetmealVO> page = setmealMapper.pageQuery(setmealPageQueryDTO);
return new PageResult(page.getTotal(), page.getResult());
}
SetmealMapper.java
Page<SetmealVO> pageQuery(SetmealPageQueryDTO setmealPageQueryDTO);
SetmealMapper.xml
<select id="pageQuery" resultType="com.sky.vo.SetmealVO">
select s.*,c.name categoryName from setmeal s left join category c on s.category_id = c.id
<where>
<if test="name != null">and s.name like concat('%', #{name}, '%')</if>
<if test="categoryId != null">and s.category_id = #{categoryId}</if>
<if test="status != null">and s.status = #{status}</if>
</where>
order by s.create_time desc
</select>
功能测试
- 可以通过接口文档进行测试,最后完成前后端联调测试即可。
删除套餐
需求分析和设计
产品原型
业务规则
- 可以一次删除一个套餐,也可以批量删除套餐。
- 启售中的套餐不能删除。
- 同时还要删除套餐菜品关系表中相应的数据。
接口设计
代码开发
SetmealController.java
@DeleteMapping
@ApiOperation("批量删除套餐")
public Result delete(@RequestParam List<Long> ids) {
log.info("批量删除套餐:{}", ids);
setmealService.deleteBatch(ids);
return Result.success();
}
SetmealService.java
void deleteBatch(List<Long> ids);
SetmealServiceImpl.java
@Override
@Transactional
public void deleteBatch(List<Long> ids) {
for (Long id : ids) {
Setmeal setmeal = setmealMapper.getById(id);
if (setmeal.getStatus().equals(StatusConstant.ENABLE)) {
throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
}
}
for (Long id : ids) {
setmealMapper.deleteById(id);
setmealDishMapper.deleteBySetmealId(id);
}
}
SetmealMapper.java
@Delete("delete from setmeal where id = #{id}")
void deleteById(Long id);
SetmealDishMapper.java
@Delete("delete from setmeal_dish where setmeal_id = #{setmealId}")
void deleteBySetmealId(Long setmealId);
代码优化:根据套餐id集合批量删除套餐数据及套餐菜品关系表中相应的数据
//SetmealServiceImpl.java
@Override
@Transactional
public void deleteBatch(List<Long> ids) {
for (Long id : ids) {
Setmeal setmeal = setmealMapper.getById(id);
if (setmeal.getStatus().equals(StatusConstant.ENABLE)) {
throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
}
}
setmealMapper.deleteByIds(ids);
setmealDishMapper.deleteBySetmealIds(ids);
}
//SetmealMapper.java
void deleteByIds(List<Long> ids);
//SetmealDishMapper.java
void deleteBySetmealIds(List<Long> setmealIds);
<!--SetmealMapper.xml-->
<delete id="deleteByIds">
delete from setmeal where id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<!--SetmealDishMapper.xml-->
<delete id="deleteBySetmealIds">
delete from setmeal_dish where setmeal_id in
<foreach collection="setmealIds" item="setmealId" open="(" separator="," close=")">
#{setmealId}
</foreach>
</delete>
功能测试
- 可以通过接口文档进行测试,最后完成前后端联调测试即可。
修改套餐
需求分析和设计
产品原型
接口设计
根据id查询套餐
根据类型查询分类(已完成)
根据分类id查询菜品(已完成)
图片上传(已完成)
修改套餐
代码开发
根据id查询套餐
SetmealController.java
@GetMapping("/{id}")
@ApiOperation("根据id查询套餐")
public Result<SetmealVO> getById(@PathVariable Long id) {
log.info("根据id查询套餐:{}", id);
SetmealVO setmealVO = setmealService.getById(id);
return Result.success(setmealVO);
}
SetmealService.java
SetmealVO getById(Long id);
SetmealServiceImpl.java
@Override
@Transactional
public SetmealVO getById(Long id) {
Setmeal setmeal = setmealMapper.getById(id);
SetmealVO setmealVO = new SetmealVO();
BeanUtils.copyProperties(setmeal, setmealVO);
List<SetmealDish> setmealDishes = setmealDishMapper.getBySetmealId(id);
setmealVO.setSetmealDishes(setmealDishes);
return setmealVO;
}
SetmealDishMapper.java
@Select("select * from setmeal_dish where setmeal_id = #{setmealId}")
List<SetmealDish> getBySetmealId(Long setmealId);
修改套餐
SetmealController.java
@PutMapping
@ApiOperation("修改套餐")
public Result update(@RequestBody SetmealDTO setmealDTO) {
log.info("修改套餐:{}", setmealDTO);
setmealService.update(setmealDTO);
return Result.success();
}
SetmealService.java
void update(SetmealDTO setmealDTO);
SetmealServiceImpl.java
@Override
@Transactional
public void update(SetmealDTO setmealDTO) {
Setmeal setmeal = new Setmeal();
BeanUtils.copyProperties(setmealDTO, setmeal);
setmealMapper.update(setmeal);
Long setmealId = setmealDTO.getId();
setmealDishMapper.deleteBySetmealId(setmealId);
List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
setmealDishes.forEach(setmealDish -> setmealDish.setSetmealId(setmealId));
setmealDishMapper.insertBatch(setmealDishes);
}
功能测试
- 可以通过接口文档进行测试,最后完成前后端联调测试即可。
启售停售套餐
需求分析和设计
产品原型
业务规则
- 可以对状态为启售的套餐进行停售操作,可以对状态为停售的套餐进行启售操作。
- 启售的套餐可以展示在用户端,停售的套餐不能展示在用户端。
- 启售套餐时,如果套餐内包含停售的菜品,则不能启售。
接口设计
代码开发
SetmealController.java
@PostMapping("/status/{status}")
@ApiOperation("启售停售套餐")
public Result startOrStop(@PathVariable Integer status, Long id) {
log.info("启售停售套餐:{},{}", status, id);
setmealService.startOrStop(status, id);
return Result.success();
}
SetmealService.java
void startOrStop(Integer status, Long id);
SetmealServiceImpl.java
@Autowired
private DishMapper dishMapper;
@Override
@Transactional
public void startOrStop(Integer status, Long id) {
if (status.equals(StatusConstant.ENABLE)) {
List<Dish> dishes = dishMapper.getBySetmealId(id);
if (dishes != null && !dishes.isEmpty()) {
dishes.forEach(dish -> {
if (dish.getStatus().equals(StatusConstant.DISABLE)) {
throw new SetmealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);
}
});
}
}
Setmeal setmeal = Setmeal.builder()
.status(status)
.id(id)
.build();
setmealMapper.update(setmeal);
}
SetmealDishMapper.java
@Select("select d.* from dish d left join setmeal_dish sd on d.id = sd.dish_id where setmeal_id = " +
"#{setmealId}")
List<Dish> getBySetmealId(Long setmealId);
功能测试
- 可以通过接口文档进行测试,最后完成前后端联调测试即可。
标签:java,
第四天,
Long,
public,
外卖,
套餐,
苍穹,
id,
setmeal
From: https://www.cnblogs.com/zgg1h/p/18129178