首页 > 其他分享 >苍穹外卖学习笔记——第四天

苍穹外卖学习笔记——第四天

时间:2024-04-11 14:57:51浏览次数:21  
标签: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

相关文章

  • 实况窗助力美团打造鸿蒙原生外卖新体验,用户可实时掌握外卖进展
    自2023年华为宣布全新HarmonyOSNEXT蓄势待发,鸿蒙原生应用全面启动以来,已有金融、旅行、社交等多个领域的企业和开发者陆续宣布加入鸿蒙生态。其中,美团作为国内头部的科技零售企业,是首批加入鸿蒙生态的伙伴,其下的美团外卖App基于HarmonyOSSDK高效展开了鸿蒙原生应用的开发,仅用6周......
  • 苍穹外卖学习笔记——第三天
    菜品管理公共字段自动填充问题分析业务表中存在公共字段:字段名含义数据类型create_time创建时间datetimecreate_user创建人idbigintupdate_time修改时间datetimeupdate_user修改人idbigint这些公共字段会在多处被执行相同的操作,导致代码冗......
  • [C++] 小游戏 斗破苍穹 2.10.1 版本 zty出品
    目录前言先赞后看 养成习惯正文后记前言   大家好,今天zty(<-痧蔽)带来的是斗破苍穹2.10.1版本本版本为战斗更新加入了四个新怪物和四个新装备并且修复了许多bug,希望大家喜欢,今天的赞不多要要50个就够了先赞后看 养成习惯正文#include<stdio.h>#inc......
  • Java基于微信小程序的校园外卖平台设计与实现,附源码
    博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w+、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌......
  • 蓝桥杯-外卖店优先级
     代码及其解析#include<bits/stdc++.h>usingnamespacestd;constintN=100010;intorder[N];//order[id]第id号店上一次的订单,记录的是时间intprior[N];//prior[id]第id号店的优先级intflag[N];//flag[id]第id号店在不在优先缓存中structnode{......
  • 苍穹外卖学习笔记——第二天
    员工管理、分类管理新增员工需求分析和设计产品原型业务规则账号必须是唯一的。手机号为合法的11位手机号码。身份证号为合法的18位身份证号码。密码默认为123456。接口设计本项目约定:管理端发出的请求,统一使用/admin作为前缀,用户端发出的请求,统一使用/user作为前......
  • 苍穹外卖学习笔记——第一天
    项目概述、环境搭建软件开发整体介绍软件开发流程步骤任务或输出文件需求分析需求规格说明书、产品原型设计UI设计、数据库设计、接口设计编码项目代码、单元测试测试测试用例、测试报告上线运维软件环境安装、配置角色分工角色分工处于流......
  • 苍穹外卖10(Spring Task定时任务,WebSocket双向通信,订单状态定时处理,来电提醒,客户催单)
    目录一、SpringTask1.介绍2.入门1使用步骤2使用示例3.详解1@Scheduled注解2cron表达式1cron表达式6个域2各个域的取值说明4.小结二、订单状态定时处理1.需求分析1问题分析2功能需求2.代码开发1修改引导类加@EnableScheduling2创建OrderTask......
  • 外卖跑腿小程序定制开发功能大全
    同城外卖的兴起,为人们提供了更加便捷、快速的用餐选择。如果您对移动应用开发感兴趣,本文将为您提供从零开始开发同城外卖APP的详细指南。一、需求分析与规划在开始开发之前,首先需要明确同城外卖的核心功能和特性。您可以考虑以下问题来进行需求分析:用户应该能够浏览餐厅菜单......
  • [C++] 小游戏 斗破苍穹2.8.1版本 zty出品
    前言大家好,今天zty带来的是首次增加调试角色的版本,2.8.1版本主要更新了调试角色(感觉没啥用)。先赞后看 养成习惯点赞过100一天更3次正文#include<stdio.h>#include<iostream>#include<ctime>#include<bits/stdc++.h>#include<time.h>//suiji#include<windows.h>/......