苍穹外卖项目实战(日记十四)-(day3课后作业) 菜品停售启售功能-记录实战教程及问题的解决方法

day3-6根据分类id查询菜品

(1)DishController完善

位置:sky-server/src/main/java/com/sky/controller/admin/DishController.java

完整代码:

package com.sky.controller.admin;
 
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.result.PageResult;
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.*;
 
import java.util.List;
 
@RestController
@RequestMapping("/admin/dish")
@Api(tags = "后台菜品管理")
@Slf4j
public class DishController {
    @Autowired
    private DishService dishService;
    /**
     * 新增菜品
     * @param dishDTO
     * @return
     */
    @PostMapping
    @ApiOperation(value = "新增菜品")
    public Result save(@RequestBody DishDTO dishDTO){
        log.info("新增菜品:{}", dishDTO);
        dishService.saveWithFlavors(dishDTO);
        return Result.success();
    }
 
    /**
     * 分页查询菜品
     * @param dishPageQueryDTO
     * @return
     */
    @GetMapping("/page")
    @ApiOperation("分页查询菜品")
    public Result<PageResult> page(DishPageQueryDTO dishPageQueryDTO){
        log.info("分页查询菜品:{}", dishPageQueryDTO);
        PageResult pageResult = dishService.pageQuery(dishPageQueryDTO);
        return Result.success(pageResult);
    }
 
    /**
     * 删除菜品
     * @param ids
     * @return
     */
    @DeleteMapping
    @ApiOperation("批量删除菜品")
    public Result delete(@RequestParam List<Long> ids){
        log.info("删除菜品:{}", ids);
        dishService.deleteBatch(ids);
        return Result.success();
    }
 
    /**
     * 根据ID查询菜品详情
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @ApiOperation("根据ID查询菜品详情")
    public Result<DishVO> getById(@PathVariable Long id){
        log.info("查询菜品:{}", id);
        DishVO dishVO = dishService.getByIdWithFlavors(id);
        return Result.success(dishVO);
    }
 
    @PutMapping
    @ApiOperation("更新菜品")
    public Result update(@RequestBody DishDTO dishDTO){
        log.info("更新菜品:{}", dishDTO);
        dishService.updateWithFlavors(dishDTO);
        return Result.success();
    }
    /**
     * 根据分类id查询菜品
     * @param categoryId
     * @return
     */
    @GetMapping("/list")
    @ApiOperation("根据分类id查询菜品")
    public Result<List<Dish>> list(Long categoryId){
        List<Dish> list = dishService.list(categoryId);
        return Result.success(list);
    }
 
}

添加的代码:

/**
 * 根据分类id查询菜品
 * @param categoryId
 * @return
 */
@GetMapping("/list")
@ApiOperation("根据分类id查询菜品")
public Result<List<Dish>> list(Long categoryId){
    List<Dish> list = dishService.list(categoryId);
    return Result.success(list);
}

示意图:

(2)DishService完善

位置:sky-server/src/main/java/com/sky/service/DishService.java

添加的代码:

/**
 * 根据分类ID查询菜品列表
 * @param categoryId
 * @return
 */
List<Dish> list(Long categoryId);

示意图:

(3)DishServiceimpl完善

位置:sky-server/src/main/java/com/sky/service/impl/DishServiceimpl.java

添加的代码:

/**
 * 根据分类ID查询菜品列表
 * @param categoryId
 * @return
 */
public List<Dish> list(Long categoryId) {
    Dish dish = Dish.builder()
            .categoryId(categoryId)
            .status(StatusConstant.ENABLE)
            .build();
    return dishMapper.list(dish);
}

示意图:

(4)DishMapper.java完善

位置:sky-server/src/main/java/com/sky/mapper/DishMapper.java

添加的代码:

/**
 * 查询所有菜品
 * @param dish
 * @return
 */
List<Dish> list(Dish dish);

示意图:

(5)DishMapper.xml完善

位置:sky-server/src/main/resources/mapper/DishMapper.xml

添加的代码:

<select id="list" resultType="Dish" parameterType="Dish">
    select * from dish
    <where>
        <if test="name != null">
            and name like concat('%',#{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>

示意图:

day3-7菜品起售停售功能

(6)DishController完善

位置:sky-server/src/main/java/com/sky/controller/admin/DishController.java

添加的代码:

/**
 * 菜品起售停售
 * @param status
 * @param id
 * @return
 */
@PostMapping("/status/{status}")
@ApiOperation("菜品起售停售")
public Result<String> startOrStop(@PathVariable Integer status, Long id){
    dishService.startOrStop(status,id);
    return Result.success();
}

示意图:

(7)DishService完善

位置:sky-server/src/main/java/com/sky/service/DishService.java

添加的代码:

/**
 * 根据ID更新菜品状态
 * @param status
 * @param id
 */
void startOrStop(Integer status, Long id);

示意图:

(8)DishServiceimpl完善

位置:sky-server/src/main/java/com/sky/service/impl/DishServiceimpl.java

添加的代码:

/**
 * 菜品起售停售
 *
 * @param status
 * @param id
 */
@Transactional
public void startOrStop(Integer status, Long id) {
    Dish dish = Dish.builder()
            .id(id)
            .status(status)
            .build();
    dishMapper.update(dish);
 
    if (status == StatusConstant.DISABLE) {
        // 如果是停售操作,还需要将包含当前菜品的套餐也停售
        List<Long> dishIds = new ArrayList<>();
        dishIds.add(id);
        // select setmeal_id from setmeal_dish where dish_id in (?,?,?)
        List<Long> setmealIds = setmealDishMapper.getSetmealIdsByDishIds(dishIds);
        if (setmealIds != null && setmealIds.size() > 0) {
            for (Long setmealId : setmealIds) {
                Setmeal setmeal = Setmeal.builder()
                        .id(setmealId)
                        .status(StatusConstant.DISABLE)
                        .build();
                setmealMapper.update(setmeal);
            }
        }
    }
}

示意图:

(9)SetmealDishMapper.java完善

位置:sky-server/src/main/java/com/sky/mapper/SetmealDishMapper.java

添加的代码:

/**
 * 根据菜品id获取套餐id
 * @param dishIds
 * @return
 */
List<Long> getSetmealIdsByDishIds(List<Long> dishIds);

示意图:

(10)SetmealDishMapper.xml

位置:sky-server/src/main/resources/mapper/SetmealDishMapper.xml

添加的代码:

<select id="getSetmealIdsByDishIds" resultType="java.lang.Long">
    SELECT DISTINCT setmeal_id
    FROM setmeal_dish
    WHERE dish_id IN
    <foreach collection="dishIds" item="dishId" open="(" separator="," close=")">
        #{dishId}
    </foreach>
</select>

示意图:

(11)SetmealMapper.java完善

位置:sky-server/src/main/java/com/sky/mapper/SetmealMapper.java

添加的代码:

/**
 * 根据id修改套餐
 *
 * @param setmeal
 */
@AutoFill(OperationType.UPDATE)
void update(Setmeal setmeal);

示意图:

(12)SetmealMapper.xml完善

位置:sky-server/src/main/resources/mapper/SetmealMapper.xml

添加的代码:

<update id="update" parameterType="Setmeal">
    update setmeal
    <set>
        <if test="name != null">
            name = #{name},
        </if>
        <if test="categoryId != null">
            category_id = #{categoryId},
        </if>
        <if test="price != null">
            price = #{price},
        </if>
        <if test="status != null">
            status = #{status},
        </if>
        <if test="description != null">
            description = #{description},
        </if>
        <if test="image != null">
            image = #{image},
        </if>
        <if test="updateTime != null">
            update_time = #{updateTime},
        </if>
        <if test="updateUser != null">
            update_user = #{updateUser}
        </if>
    </set>
    where id = #{id}
</update>

示意图:

(13)功能测试

调试项目(DuBug),打开前端网页菜品管理

找到以下位置,任意点击“停售”按钮,后再点击“启售”,若都成功,这说明功能完成!

### 苍穹外卖系统菜品停售功能的操作指南 在《苍穹外卖》电商实战项目中,菜品停售是一项重要的管理功能,用于控制菜品的状态以便于运营和销。以下是关于该功能的具体操作方法及其技术实现的相关说明。 #### 功能概述 菜品停售功能允许管理员通过后台管理系统更改菜品状态,从而决定其是否可以在前端展示并供顾客下单购买。这一功能通常涉及以下几个方面: - **菜品状态字段**:在数据库设计中,每道菜品应有一个表示状态的字段(如 `status`),取值可以为“用”或“禁用”。 - **API接口支持**:提供RESTful风格的API接口,用于更新菜品状态。 此功能的设计理念来源于实际业务需求,旨在提高商家对菜单的灵活管控能力[^1]。 #### 数据库表结构设计 为了实现菜品停售功能,在数据库层面需定义如下字段: ```sql CREATE TABLE dishes ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255) NOT NULL, -- 菜品名称 price DECIMAL(10, 2) NOT NULL, -- 单价 status TINYINT DEFAULT 1 COMMENT &#39;状态: 1=用; 0=停用&#39;, -- 状态字段 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); ``` 上述SQL语句创建了一个名为`dishes`的数据表,其中`status`字段用来标记菜品当前处于“用”还是“停用”的状态[^3]。 #### 后端逻辑处理 后端服务负责接收来自前端发送的请求,并执行相应的业务逻辑以修改菜品状态。基于Spring Boot框架开发的应用程序可以通过控制器层暴露HTTP接口完成此项工作: ```java @RestController @RequestMapping("/api/dish") public class DishController { @Autowired private DishService dishService; /** * 修改菜品状态 (/停售) */ @PutMapping("/{id}/toggleStatus") public ResponseEntity<String> toggleDishStatus(@PathVariable Integer id, @RequestParam Boolean enable) { try { if (enable != null && dishService.updateStatusById(id, enable)) { return new ResponseEntity<>("成功切换菜品状态", HttpStatus.OK); } else { return new ResponseEntity<>("未找到指定ID的菜品记录", HttpStatus.NOT_FOUND); } } catch (Exception e) { return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } } } ``` 以上代码片段展示了如何利用Spring Boot快速搭建一个简单的CRUD API来满足菜品状态变更的需求[^4]。 #### 前端交互流程 从前端角度来看,当用户点击某个按钮触发菜品或者停售动作时,应该向服务器发起PUT类型的网络请求调用对应的API路径。具体来说就是将目标菜品ID以及期望设置的新状态作为参数传递给后端处理器实例化对象进行验证后再保存至持久存储介质当中去[^2]。 例如,如果要停止卖一道编号为789号的菜,则可通过Axios库编写如下JavaScript脚本发出异步通信命令: ```javascript axios.put(&#39;/api/dish/789/toggleStatus&#39;, { enable: false }) .then(response => console.log(&#39;Response:&#39;, response.data)) .catch(error => alert(`Error occurred:${error}`)); ``` 这样就完成了整个从界面操作直至最终反映到数据库中的闭环过程描述。 ### 注意事项 对于开发者而言需要注意的是,在实施这些改动之前最好先备份好原始资料以防万一出现问题无法恢复;另外还要考虑到并发情况下可能出现的竞争条件问题所以建议加入版本号机制或者其他锁策略加以防范风险发生几率降到最低限度之内。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值