浏览代码

酒水餐食管理curd

panzhilin 1 周之前
父节点
当前提交
dd9744d0d5

+ 103 - 0
alien-entity/src/main/java/shop/alien/entity/store/DrinkInfo.java

@@ -0,0 +1,103 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 二期-酒水餐食信息
+ *
+ * @author ssk
+ * @since 2025-05-14
+ */
+@Data
+@JsonInclude
+@TableName("drink_info")
+@ApiModel(value = "DrinkInfo对象", description = "酒水餐食信息")
+public class DrinkInfo  {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "类型(枚举值:酒水/餐食)")
+    @TableField("type")
+    private String type;
+
+    @ApiModelProperty(value = "名称")
+    @TableField("name")
+    private String name;
+
+    @ApiModelProperty(value = "售价")
+    @TableField("price")
+    private BigDecimal price;
+
+    @ApiModelProperty(value = "成本价")
+    @TableField("cost_price")
+    private BigDecimal costPrice;
+
+    @ApiModelProperty(value = "酒精度")
+    @TableField("alcohol_volume")
+    private BigDecimal alcoholVolume;
+
+    @ApiModelProperty(value = "图片")
+    @TableField("pic_url")
+    private String picUrl;
+
+    @ApiModelProperty(value = "分类")
+    @TableField("category")
+    private String category;
+
+    @ApiModelProperty(value = "口味")
+    @TableField("flavor")
+    private String flavor;
+
+    @ApiModelProperty(value = "描述")
+    @TableField("description")
+    private String description;
+
+    @ApiModelProperty(value = "排序")
+    @TableField("sort")
+    private Integer sort;
+
+    @ApiModelProperty(value = "是否推荐 0:否 1:是")
+    @TableField("is_recommended")
+    private Integer isRecommended;
+
+    @ApiModelProperty(value = "状态 0:下架 1:上架")
+    @TableField("status")
+    private Integer status;
+
+    @ApiModelProperty(value = "门店ID")
+    @TableField("store_id")
+    private Integer storeId;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("create_user_id")
+    private Integer createUserId;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "create_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("update_user_id")
+    private Integer updateUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "update_time", fill = FieldFill.UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updateTime;
+
+    @ApiModelProperty(value = "是否删除 0:未删除 1:已删除")
+    @TableField("is_deleted")
+    @TableLogic
+    private Integer isDeleted;
+}

+ 82 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/DrinkInfoVo.java

@@ -0,0 +1,82 @@
+package shop.alien.entity.store.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 酒水餐食信息表 VO
+ *
+ * @author ssk
+ * @since 2025-06-13
+ */
+@Data
+@ApiModel(value = "DrinkInfoVo", description = "酒水餐食信息表视图对象")
+public class DrinkInfoVo {
+
+    @ApiModelProperty(value = "主键ID")
+    private Integer id;
+
+    @ApiModelProperty(value = "类型(枚举值:酒水/餐食)")
+    private String type;
+
+    @ApiModelProperty(value = "商品名称")
+    private String name;
+
+    @ApiModelProperty(value = "商品价格")
+    private BigDecimal price;
+
+    @ApiModelProperty(value = "商品成本价")
+    private BigDecimal costPrice;
+
+    @ApiModelProperty(value = "商品分类")
+    private String category;
+
+    @ApiModelProperty(value = "酒精度数")
+    private BigDecimal alcoholVolume;
+
+    @ApiModelProperty(value = "商品图片")
+    private String picUrl;
+
+    @ApiModelProperty(value = "商品描述")
+    private String description;
+
+    @ApiModelProperty(value = "商品口味")
+    private String flavor;
+
+    @ApiModelProperty(value = "门店ID")
+    private Integer storeId;
+
+    @ApiModelProperty(value = "门店名称")
+    private String storeName;
+
+    @ApiModelProperty(value = "是否推荐(0:否, 1:是)")
+    private Integer isRecommended;
+
+    @ApiModelProperty(value = "状态(0:下架, 1:上架)")
+    private Integer status;
+
+    @ApiModelProperty(value = "排序值")
+    private Integer sort;
+
+    @ApiModelProperty(value = "是否删除(0:否, 1:是)")
+    private Integer isDeleted;
+
+    @ApiModelProperty(value = "创建人ID")
+    private Integer createUserId;
+
+    @ApiModelProperty(value = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createTime;
+
+    @ApiModelProperty(value = "更新人ID")
+    private Integer updateUserId;
+
+    @ApiModelProperty(value = "更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updateTime;
+}

+ 14 - 0
alien-entity/src/main/java/shop/alien/mapper/DrinkInfoMapper.java

@@ -0,0 +1,14 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import shop.alien.entity.store.DrinkInfo;
+
+/**
+ * 酒水餐食信息表 Mapper 接口
+ *
+ * @author ssk
+ * @since 2025-06-13
+ */
+public interface DrinkInfoMapper extends BaseMapper<DrinkInfo> {
+
+}

+ 34 - 0
alien-entity/src/main/resources/mapper/DrinkInfoMapper.xml

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="shop.alien.mapper.DrinkInfoMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="shop.alien.entity.store.DrinkInfo">
+        <id column="id" property="id" />
+        <result column="type" property="type" />
+        <result column="name" property="name" />
+        <result column="price" property="price" />
+        <result column="cost_price" property="costPrice" />
+        <result column="category" property="category" />
+        <result column="alcohol_volume" property="alcoholVolume" />
+        <result column="pic_url" property="picUrl" />
+        <result column="description" property="description" />
+        <result column="flavor" property="flavor" />
+        <result column="store_id" property="storeId" />
+        <result column="is_recommended" property="isRecommended" />
+        <result column="status" property="status" />
+        <result column="sort" property="sort" />
+        <result column="is_deleted" property="isDeleted" />
+        <result column="create_user_id" property="createUserId" />
+        <result column="create_time" property="createTime" />
+        <result column="update_user_id" property="updateUserId" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, type, name, price, cost_price, category, alcohol_volume, pic_url, description, flavor, store_id, 
+        is_recommended, status, sort, is_deleted, create_user_id, create_time, update_user_id, update_time
+    </sql>
+
+</mapper>

+ 190 - 0
alien-store/src/main/java/shop/alien/store/controller/DrinkInfoController.java

@@ -0,0 +1,190 @@
+package shop.alien.store.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.DrinkInfo;
+import shop.alien.entity.store.vo.DrinkInfoVo;
+import shop.alien.store.service.DrinkInfoService;
+
+import java.util.List;
+
+/**
+ * 酒水餐食信息表Controller
+ *
+ * @author ssk
+ * @since 2025-06-13
+ */
+@Slf4j
+@Api(tags = {"酒水餐食管理"})
+@ApiSort(1)
+@CrossOrigin
+@RestController
+@RequestMapping("/store/drink")
+@RequiredArgsConstructor
+public class DrinkInfoController {
+
+    private final DrinkInfoService drinkInfoService;
+
+    @ApiOperation("分页查询酒水餐食列表")
+    @ApiOperationSupport(order = 1)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page", value = "页码", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "size", value = "页容", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "storeId", value = "门店ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "type", value = "类型(枚举值:酒水/餐食)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "category", value = "分类", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "name", value = "名称关键词", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "createUserId", value = "创建人ID(只查询自己创建的)", dataType = "Integer", paramType = "query")
+    })
+    @GetMapping("/page")
+    public R<IPage<DrinkInfoVo>> getDrinkInfoPage(
+            @RequestParam("page") int page,
+            @RequestParam("size") int size,
+            @RequestParam(value = "storeId", required = false) Integer storeId,
+            @RequestParam(value = "type", required = false) String type,
+            @RequestParam(value = "category", required = false) String category,
+            @RequestParam(value = "name", required = false) String name,
+            @RequestParam(value = "createUserId", required = false) Integer createUserId) {
+        log.info("DrinkInfoController.getDrinkInfoPage?page={}, size={}, storeId={}, type={}, category={}, name={}, createUserId={}", 
+                page, size, storeId, type, category, name, createUserId);
+        IPage<DrinkInfoVo> drinkInfoPage = drinkInfoService.getDrinkInfoPage(page, size, storeId, type, category, name, createUserId);
+        return R.data(drinkInfoPage);
+    }
+
+    @ApiOperation("根据ID查询酒水餐食详情")
+    @ApiOperationSupport(order = 2)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键ID", dataType = "Integer", paramType = "path", required = true)
+    })
+    @GetMapping("/{id}")
+    public R<DrinkInfoVo> getDrinkInfoById(@PathVariable("id") Integer id) {
+        log.info("DrinkInfoController.getDrinkInfoById?id={}", id);
+        DrinkInfoVo drinkInfoVo = drinkInfoService.getDrinkInfoById(id);
+        if (drinkInfoVo == null) {
+            return R.fail("未找到该酒水餐食信息");
+        }
+        return R.data(drinkInfoVo);
+    }
+
+    @ApiOperation("新增酒水餐食")
+    @ApiOperationSupport(order = 3)
+    @PostMapping
+    public R<String> saveDrinkInfo(@RequestBody DrinkInfo drinkInfo) {
+        log.info("DrinkInfoController.saveDrinkInfo?drinkInfo={}", drinkInfo);
+        boolean result = drinkInfoService.saveDrinkInfo(drinkInfo);
+        if (result) {
+            return R.success("新增成功");
+        }
+        return R.fail("新增失败");
+    }
+
+    @ApiOperation("修改酒水餐食")
+    @ApiOperationSupport(order = 4)
+    @PutMapping
+    public R<String> updateDrinkInfo(@RequestBody DrinkInfo drinkInfo) {
+        log.info("DrinkInfoController.updateDrinkInfo?drinkInfo={}", drinkInfo);
+        boolean result = drinkInfoService.updateDrinkInfo(drinkInfo);
+        if (result) {
+            return R.success("修改成功");
+        }
+        return R.fail("修改失败");
+    }
+
+    @ApiOperation("删除酒水餐食")
+    @ApiOperationSupport(order = 5)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键ID", dataType = "Integer", paramType = "path", required = true)
+    })
+    @DeleteMapping("/{id}")
+    public R<String> deleteDrinkInfo(@PathVariable("id") Integer id) {
+        log.info("DrinkInfoController.deleteDrinkInfo?id={}", id);
+        boolean result = drinkInfoService.deleteDrinkInfo(id);
+        if (result) {
+            return R.success("删除成功");
+        }
+        return R.fail("删除失败");
+    }
+
+    @ApiOperation("设置酒水餐食推荐")
+    @ApiOperationSupport(order = 7)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键ID", dataType = "Integer", paramType = "path", required = true),
+            @ApiImplicitParam(name = "isRecommended", value = "是否推荐(0:否, 1:是)", dataType = "Integer", paramType = "query", required = true)
+    })
+    @PutMapping("/{id}/recommended")
+    public R<String> updateIsRecommended(
+            @PathVariable("id") Integer id,
+            @RequestParam("isRecommended") Integer isRecommended) {
+        log.info("DrinkInfoController.updateIsRecommended?id={}, isRecommended={}", id, isRecommended);
+        boolean result = drinkInfoService.updateIsRecommended(id, isRecommended);
+        if (result) {
+            return R.success("操作成功");
+        }
+        return R.fail("操作失败");
+    }
+
+    @ApiOperation("更新酒水餐食排序")
+    @ApiOperationSupport(order = 8)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "主键ID", dataType = "Integer", paramType = "path", required = true),
+            @ApiImplicitParam(name = "sort", value = "排序值", dataType = "Integer", paramType = "query", required = true)
+    })
+    @PutMapping("/{id}/sort")
+    public R<String> updateSort(
+            @PathVariable("id") Integer id,
+            @RequestParam("sort") Integer sort) {
+        log.info("DrinkInfoController.updateSort?id={}, sort={}", id, sort);
+        boolean result = drinkInfoService.updateSort(id, sort);
+        if (result) {
+            return R.success("操作成功");
+        }
+        return R.fail("操作失败");
+    }
+
+    @ApiOperation("根据门店ID查询所有酒水餐食")
+    @ApiOperationSupport(order = 9)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "storeId", value = "门店ID", dataType = "Integer", paramType = "query", required = true),
+            @ApiImplicitParam(name = "type", value = "类型(枚举值:酒水/餐食)", dataType = "String", paramType = "query")
+    })
+    @GetMapping("/listByStoreId")
+    public R<List<DrinkInfoVo>> getDrinkInfoListByStoreId(
+            @RequestParam("storeId") Integer storeId,
+            @RequestParam(value = "type", required = false) String type) {
+        log.info("DrinkInfoController.getDrinkInfoListByStoreId?storeId={}, type={}", storeId, type);
+        List<DrinkInfoVo> drinkInfoList = drinkInfoService.getDrinkInfoListByStoreId(storeId, type);
+        return R.data(drinkInfoList);
+    }
+
+    @ApiOperation("查询推荐酒水餐食列表")
+    @ApiOperationSupport(order = 10)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "storeId", value = "门店ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "createUserId", value = "创建人ID(只查询自己创建的)", dataType = "Integer", paramType = "query")
+    })
+    @GetMapping("/recommended")
+    public R<List<DrinkInfoVo>> getRecommendedList(
+            @RequestParam(value = "storeId", required = false) Integer storeId,
+            @RequestParam(value = "createUserId", required = false) Integer createUserId) {
+        log.info("DrinkInfoController.getRecommendedList?storeId={}, createUserId={}", storeId, createUserId);
+        List<DrinkInfoVo> drinkInfoList = drinkInfoService.getRecommendedList(storeId, createUserId);
+        return R.data(drinkInfoList);
+    }
+
+    @ApiOperation("批量更新酒水餐食排序")
+    @ApiOperationSupport(order = 11)
+    @PostMapping("/batchSort")
+    public R<String> batchUpdateSort(@RequestBody List<DrinkInfo> drinkInfoList) {
+        log.info("DrinkInfoController.batchUpdateSort?size={}", drinkInfoList.size());
+        boolean result = drinkInfoService.batchUpdateSort(drinkInfoList);
+        if (result) {
+            return R.success("批量更新排序成功");
+        }
+        return R.fail("批量更新排序失败");
+    }
+
+}

+ 141 - 0
alien-store/src/main/java/shop/alien/store/service/DrinkInfoService.java

@@ -0,0 +1,141 @@
+package shop.alien.store.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.store.DrinkInfo;
+import shop.alien.entity.store.vo.DrinkInfoVo;
+
+import java.util.List;
+
+/**
+ * 酒水餐食信息表 服务类
+ *
+ * @author ssk
+ * @since 2025-06-13
+ */
+public interface DrinkInfoService extends IService<DrinkInfo> {
+
+    /**
+     * 分页查询酒水餐食列表
+     *
+     * @param page         页码
+     * @param size         页容
+     * @param storeId      门店ID
+     * @param type         类型(枚举值:酒水/餐食)
+     * @param category     分类
+     * @param name         名称关键词
+     * @param createUserId 创建人ID(只查询指定用户创建的)
+     * @return IPage<DrinkInfoVo>
+     */
+    IPage<DrinkInfoVo> getDrinkInfoPage(int page, int size, Integer storeId, String type, String category, String name, Integer createUserId);
+
+    /**
+     * 根据ID查询酒水餐食详情
+     *
+     * @param id 主键ID
+     * @return DrinkInfoVo
+     */
+    DrinkInfoVo getDrinkInfoById(Integer id);
+
+    /**
+     * 新增酒水餐食
+     *
+     * @param drinkInfo 酒水餐食信息
+     * @return boolean
+     */
+    boolean saveDrinkInfo(DrinkInfo drinkInfo);
+
+    /**
+     * 修改酒水餐食
+     *
+     * @param drinkInfo 酒水餐食信息
+     * @return boolean
+     */
+    boolean updateDrinkInfo(DrinkInfo drinkInfo);
+
+    /**
+     * 删除酒水餐食(软删除)
+     *
+     * @param id 主键ID
+     * @return boolean
+     */
+    boolean deleteDrinkInfo(Integer id);
+
+    /**
+     * 上下架酒水餐食
+     *
+     * @param id     主键ID
+     * @param status 状态(0:下架, 1:上架)
+     * @return boolean
+     */
+    boolean updateStatus(Integer id, Integer status);
+
+    /**
+     * 设置酒水餐食推荐
+     *
+     * @param id            主键ID
+     * @param isRecommended 是否推荐(0:否, 1:是)
+     * @return boolean
+     */
+    boolean updateIsRecommended(Integer id, Integer isRecommended);
+
+    /**
+     * 更新酒水餐食排序
+     *
+     * @param id   主键ID
+     * @param sort 排序值
+     * @return boolean
+     */
+    boolean updateSort(Integer id, Integer sort);
+
+    /**
+     * 根据门店ID查询所有酒水餐食
+     *
+     * @param storeId 门店ID
+     * @param type    类型(枚举值:酒水/餐食)
+     * @return List<DrinkInfoVo>
+     */
+    List<DrinkInfoVo> getDrinkInfoListByStoreId(Integer storeId, String type);
+
+    /**
+     * 查询推荐酒水餐食列表
+     *
+     * @param storeId      门店ID
+     * @param createUserId 创建人ID(只查询指定用户创建的)
+     * @return List<DrinkInfoVo>
+     */
+    List<DrinkInfoVo> getRecommendedList(Integer storeId, Integer createUserId);
+
+    /**
+     * 批量更新酒水餐食排序
+     *
+     * @param drinkInfoList 酒水餐食列表(包含id和sort字段)
+     * @return boolean
+     */
+    boolean batchUpdateSort(List<DrinkInfo> drinkInfoList);
+
+    /**
+     * 获取酒水餐食类型统计
+     *
+     * @param storeId 门店ID
+     * @return Map<String, Long> 类型统计信息
+     */
+    java.util.Map<String, Long> getStatistics(Integer storeId);
+
+    /**
+     * 批量删除酒水餐食
+     *
+     * @param ids 主键ID列表
+     * @return boolean
+     */
+    boolean batchDelete(List<Integer> ids);
+
+    /**
+     * 批量上下架
+     *
+     * @param ids    主键ID列表
+     * @param status 状态(0:下架, 1:上架)
+     * @return boolean
+     */
+    boolean batchUpdateStatus(List<Integer> ids, Integer status);
+}

+ 260 - 0
alien-store/src/main/java/shop/alien/store/service/impl/DrinkInfoServiceImpl.java

@@ -0,0 +1,260 @@
+package shop.alien.store.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import shop.alien.entity.store.DrinkInfo;
+import shop.alien.entity.store.vo.DrinkInfoVo;
+import shop.alien.mapper.DrinkInfoMapper;
+import shop.alien.store.service.DrinkInfoService;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 酒水餐食信息表 服务实现类
+ *
+ * @author ssk
+ * @since 2025-06-13
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+@Transactional
+public class DrinkInfoServiceImpl extends ServiceImpl<DrinkInfoMapper, DrinkInfo> implements DrinkInfoService {
+
+    private final DrinkInfoMapper drinkInfoMapper;
+
+    @Override
+    public IPage<DrinkInfoVo> getDrinkInfoPage(int page, int size, Integer storeId, String type, String category, String name, Integer createUserId) {
+        LambdaQueryWrapper<DrinkInfo> queryWrapper = new LambdaQueryWrapper<>();
+        // 软删除条件
+        queryWrapper.eq(DrinkInfo::getIsDeleted, 0);
+        // 筛选条件
+        if (createUserId != null) {
+            queryWrapper.eq(DrinkInfo::getCreateUserId, createUserId);
+        }
+        if (storeId != null) {
+            queryWrapper.eq(DrinkInfo::getStoreId, storeId);
+        }
+        if (type != null && !type.isEmpty()) {
+            queryWrapper.eq(DrinkInfo::getType, type);
+        }
+        if (category != null && !category.isEmpty()) {
+            queryWrapper.eq(DrinkInfo::getCategory, category);
+        }
+        if (name != null && !name.isEmpty()) {
+            queryWrapper.like(DrinkInfo::getName, name);
+        }
+        // 按排序和创建时间倒序
+        queryWrapper.orderByAsc(DrinkInfo::getSort);
+        queryWrapper.orderByDesc(DrinkInfo::getCreateTime);
+
+        IPage<DrinkInfo> drinkInfoPage = drinkInfoMapper.selectPage(new Page<>(page, size), queryWrapper);
+        // 转换为Vo
+        IPage<DrinkInfoVo> drinkInfoVoPage = new Page<>(page, size);
+        drinkInfoVoPage.setTotal(drinkInfoPage.getTotal());
+        List<DrinkInfoVo> drinkInfoVoList = drinkInfoPage.getRecords().stream()
+                .map(this::convertToVo)
+                .collect(Collectors.toList());
+        drinkInfoVoPage.setRecords(drinkInfoVoList);
+
+        return drinkInfoVoPage;
+    }
+
+    @Override
+    public DrinkInfoVo getDrinkInfoById(Integer id) {
+        DrinkInfo drinkInfo = drinkInfoMapper.selectById(id);
+        if (drinkInfo == null || drinkInfo.getIsDeleted() == 1) {
+            return null;
+        }
+        return convertToVo(drinkInfo);
+    }
+
+    @Override
+    public boolean saveDrinkInfo(DrinkInfo drinkInfo) {
+        // 设置默认值
+        drinkInfo.setIsDeleted(0);
+        drinkInfo.setStatus(1); // 默认上架
+        drinkInfo.setSort(0); // 默认排序
+        return this.save(drinkInfo);
+    }
+
+    @Override
+    public boolean updateDrinkInfo(DrinkInfo drinkInfo) {
+        return this.updateById(drinkInfo);
+    }
+
+    @Override
+    public boolean deleteDrinkInfo(Integer id) {
+        LambdaUpdateWrapper<DrinkInfo> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper.eq(DrinkInfo::getId, id)
+                .set(DrinkInfo::getIsDeleted, 1);
+        return this.update(updateWrapper);
+    }
+
+    @Override
+    public boolean updateStatus(Integer id, Integer status) {
+        LambdaUpdateWrapper<DrinkInfo> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper.eq(DrinkInfo::getId, id)
+                .eq(DrinkInfo::getIsDeleted, 0)
+                .set(DrinkInfo::getStatus, status);
+        return this.update(updateWrapper);
+    }
+
+    @Override
+    public boolean updateIsRecommended(Integer id, Integer isRecommended) {
+        LambdaUpdateWrapper<DrinkInfo> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper.eq(DrinkInfo::getId, id)
+                .eq(DrinkInfo::getIsDeleted, 0)
+                .set(DrinkInfo::getIsRecommended, isRecommended);
+        return this.update(updateWrapper);
+    }
+
+    @Override
+    public boolean updateSort(Integer id, Integer sort) {
+        LambdaUpdateWrapper<DrinkInfo> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper.eq(DrinkInfo::getId, id)
+                .eq(DrinkInfo::getIsDeleted, 0)
+                .set(DrinkInfo::getSort, sort);
+        return this.update(updateWrapper);
+    }
+
+    @Override
+    public List<DrinkInfoVo> getDrinkInfoListByStoreId(Integer storeId, String type) {
+        LambdaQueryWrapper<DrinkInfo> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(DrinkInfo::getStoreId, storeId)
+                .eq(DrinkInfo::getIsDeleted, 0)
+                .eq(DrinkInfo::getStatus, 1); // 只查询上架的
+        if (type != null && !type.isEmpty()) {
+            queryWrapper.eq(DrinkInfo::getType, type);
+        }
+        queryWrapper.orderByAsc(DrinkInfo::getSort);
+        queryWrapper.orderByDesc(DrinkInfo::getCreateTime);
+
+        List<DrinkInfo> drinkInfoList = drinkInfoMapper.selectList(queryWrapper);
+        return drinkInfoList.stream()
+                .map(this::convertToVo)
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public List<DrinkInfoVo> getRecommendedList(Integer storeId, Integer createUserId) {
+        LambdaQueryWrapper<DrinkInfo> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(DrinkInfo::getIsRecommended, 1)
+                .eq(DrinkInfo::getIsDeleted, 0)
+                .eq(DrinkInfo::getStatus, 1); // 只查询上架的推荐商品
+        
+        // 只查询指定用户创建的商品
+        if (createUserId != null) {
+            queryWrapper.eq(DrinkInfo::getCreateUserId, createUserId);
+        }
+        
+        if (storeId != null) {
+            // 查询指定门店的商品,或者store_id为null的公共商品
+            queryWrapper.and(wrapper -> wrapper.eq(DrinkInfo::getStoreId, storeId));
+        }
+        queryWrapper.orderByAsc(DrinkInfo::getSort);
+        queryWrapper.orderByDesc(DrinkInfo::getCreateTime);
+
+        List<DrinkInfo> drinkInfoList = drinkInfoMapper.selectList(queryWrapper);
+        return drinkInfoList.stream()
+                .map(this::convertToVo)
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public boolean batchUpdateSort(List<DrinkInfo> drinkInfoList) {
+        if (drinkInfoList == null || drinkInfoList.isEmpty()) {
+            return false;
+        }
+        try {
+            for (DrinkInfo drinkInfo : drinkInfoList) {
+                if (drinkInfo.getId() != null && drinkInfo.getSort() != null) {
+                    LambdaUpdateWrapper<DrinkInfo> updateWrapper = new LambdaUpdateWrapper<>();
+                    updateWrapper.eq(DrinkInfo::getId, drinkInfo.getId())
+                            .eq(DrinkInfo::getIsDeleted, 0)
+                            .set(DrinkInfo::getSort, drinkInfo.getSort());
+                    this.update(updateWrapper);
+                }
+            }
+            return true;
+        } catch (Exception e) {
+            log.error("批量更新排序失败", e);
+            return false;
+        }
+    }
+
+    @Override
+    public java.util.Map<String, Long> getStatistics(Integer storeId) {
+        LambdaQueryWrapper<DrinkInfo> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(DrinkInfo::getIsDeleted, 0)
+                .eq(DrinkInfo::getStatus, 1); // 只统计上架的
+        if (storeId != null) {
+            queryWrapper.eq(DrinkInfo::getStoreId, storeId);
+        }
+
+        List<DrinkInfo> allList = drinkInfoMapper.selectList(queryWrapper);
+        
+        java.util.Map<String, Long> statistics = new java.util.HashMap<>();
+        statistics.put("total", (long) allList.size());
+        statistics.put("drink", allList.stream().filter(d -> "酒水".equals(d.getType())).count());
+        statistics.put("food", allList.stream().filter(d -> "餐食".equals(d.getType())).count());
+        statistics.put("recommended", allList.stream().filter(d -> d.getIsRecommended() == 1).count());
+        
+        return statistics;
+    }
+
+    @Override
+    public boolean batchDelete(List<Integer> ids) {
+        if (ids == null || ids.isEmpty()) {
+            return false;
+        }
+        try {
+            for (Integer id : ids) {
+                deleteDrinkInfo(id);
+            }
+            return true;
+        } catch (Exception e) {
+            log.error("批量删除失败", e);
+            return false;
+        }
+    }
+
+    @Override
+    public boolean batchUpdateStatus(List<Integer> ids, Integer status) {
+        if (ids == null || ids.isEmpty()) {
+            return false;
+        }
+        try {
+            for (Integer id : ids) {
+                updateStatus(id, status);
+            }
+            return true;
+        } catch (Exception e) {
+            log.error("批量更新状态失败", e);
+            return false;
+        }
+    }
+
+    /**
+     * 将DrinkInfo转换为DrinkInfoVo
+     *
+     * @param drinkInfo DrinkInfo对象
+     * @return DrinkInfoVo对象
+     */
+    private DrinkInfoVo convertToVo(DrinkInfo drinkInfo) {
+        DrinkInfoVo drinkInfoVo = new DrinkInfoVo();
+        BeanUtils.copyProperties(drinkInfo, drinkInfoVo);
+        // 确保图片字段正确映射
+        drinkInfoVo.setPicUrl(drinkInfo.getPicUrl());
+        return drinkInfoVo;
+    }
+}