ldz 3 dagar sedan
förälder
incheckning
62af1dfb25

+ 73 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/StoreProductDelicaciesVo.java

@@ -0,0 +1,73 @@
+package shop.alien.entity.store.vo;
+
+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.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 美食商品表VO(用于子表列表)
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@JsonInclude
+@ApiModel(value = "StoreProductDelicaciesVo对象", description = "美食商品表VO")
+public class StoreProductDelicaciesVo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "美食商品表主键")
+    private Integer id;
+
+    @ApiModelProperty(value = "商品表主键(关联字段)")
+    private Integer extId;
+
+    @ApiModelProperty(value = "名称")
+    private String name;
+
+    @ApiModelProperty(value = "价格(¥)")
+    private BigDecimal price;
+
+    @ApiModelProperty(value = "成本价(¥)")
+    private BigDecimal costPrice;
+
+    @ApiModelProperty(value = "单位,如份/瓶/杯")
+    private String unit;
+
+    @ApiModelProperty(value = "数量")
+    private Integer quantity;
+
+    @ApiModelProperty(value = "类别")
+    private String category;
+
+    @ApiModelProperty(value = "菜品分组")
+    private String extGroup;
+
+    @ApiModelProperty(value = "状态:0禁用,1启用")
+    private Integer status;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建人")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "更新人")
+    private Integer updatedUserId;
+
+    @ApiModelProperty(value = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+}
+

+ 146 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/StoreProductItemDelicaciesVo.java

@@ -0,0 +1,146 @@
+package shop.alien.entity.store.vo;
+
+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.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 商品表与美食商品表关联查询VO
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@JsonInclude
+@ApiModel(value = "StoreProductItemDelicaciesVo对象", description = "商品表与美食商品表关联查询VO")
+public class StoreProductItemDelicaciesVo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    // ========== store_product_item 表字段 ==========
+    @ApiModelProperty(value = "商品表主键")
+    private Integer id;
+
+    @ApiModelProperty(value = "门店id")
+    private Integer storeId;
+
+    @ApiModelProperty(value = "商品名称")
+    private String prodName;
+
+    @ApiModelProperty(value = "总价")
+    private BigDecimal totalPrice;
+
+    @ApiModelProperty(value = "商品类型,整型枚举:1酒吧-酒水 2酒吧-餐食 3美食-餐食 4运动健身-单次 5运动健身-多次")
+    private Integer prodType;
+
+    @ApiModelProperty(value = "图片列表,最多 9 张 URL")
+    private String images;
+
+    @ApiModelProperty(value = "图文详情-图片")
+    private String imageContent;
+
+    @ApiModelProperty(value = "图文详情-文字")
+    private String detailContent;
+
+    @ApiModelProperty(value = "补充说明")
+    private String extraNote;
+
+    @ApiModelProperty(value = "是否需要预约:0=否,1=是")
+    private Integer needReserve;
+
+    @ApiModelProperty(value = "预约规则")
+    private String reserveRule;
+
+    @ApiModelProperty(value = "适用人数")
+    private Integer peopleLimit;
+
+    @ApiModelProperty(value = "使用规则")
+    private String usageRule;
+
+    @ApiModelProperty(value = "状态:0-待审核 1-审核通过 2-审核拒绝")
+    private Integer status;
+
+    @ApiModelProperty(value = "拒绝原因")
+    private String rejectionReason;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建人")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "更新人")
+    private Integer updatedUserId;
+
+    @ApiModelProperty(value = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "美食商品子表列表(一对多关系)")
+    private List<StoreProductDelicaciesVo> delicaciesList;
+
+
+    // ========== store_product_delicacies 表字段 ==========
+    @ApiModelProperty(value = "美食商品表主键")
+    private Integer delicaciesId;
+
+    @ApiModelProperty(value = "商品表主键(关联字段)")
+    private Integer extId;
+
+    @ApiModelProperty(value = "名称")
+    private String name;
+
+    @ApiModelProperty(value = "价格(¥)")
+    private BigDecimal price;
+
+    @ApiModelProperty(value = "成本价(¥)")
+    private BigDecimal costPrice;
+
+    @ApiModelProperty(value = "单位,如份/瓶/杯")
+    private String unit;
+
+    @ApiModelProperty(value = "数量")
+    private Integer quantity;
+
+    @ApiModelProperty(value = "类别")
+    private String category;
+
+    @ApiModelProperty(value = "菜品分组")
+    private String extGroup;
+
+    @ApiModelProperty(value = "美食商品状态:0禁用,1启用")
+    private Integer delicaciesStatus;
+
+    @ApiModelProperty(value = "美食商品删除标记, 0:未删除, 1:已删除")
+    private Integer delicaciesDeleteFlag;
+
+    @ApiModelProperty(value = "美食商品创建人")
+    private Integer delicaciesCreatedUserId;
+
+    @ApiModelProperty(value = "美食商品更新人")
+    private Integer delicaciesUpdatedUserId;
+
+    @ApiModelProperty(value = "美食商品创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date delicaciesCreatedTime;
+
+    @ApiModelProperty(value = "美食商品更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date delicaciesUpdatedTime;
+
+    // ========== 辅助字段 ==========
+    @ApiModelProperty(value = "数据类型:1-菜品(来自store_product_delicacies),2-套餐/商品(来自store_product_item)")
+    private Integer dataType;
+}
+

+ 44 - 0
alien-entity/src/main/java/shop/alien/mapper/StoreProductItemMapper.java

@@ -9,7 +9,9 @@ import shop.alien.entity.store.StoreProductItem;
 import shop.alien.entity.store.dto.StoreProductItemDto;
 
 import java.util.ArrayList;
+import java.util.List;
 import shop.alien.entity.store.vo.StoreProductItemGymVo;
+import shop.alien.entity.store.vo.StoreProductItemDelicaciesVo;
 
 /**
  * <p>
@@ -44,5 +46,47 @@ public interface StoreProductItemMapper extends BaseMapper<StoreProductItem> {
      * @return StoreProductItemGymVo
      */
     StoreProductItemGymVo getDetailWithGym(@Param("id") Long id);
+
+    /**
+     * 查询store_product_delicacies的所有菜品(用于合并查询)
+     *
+     * @param storeId 门店ID
+     * @param name 名称(模糊查询)
+     * @param category 类别
+     * @param extGroup 菜品分组
+     * @param status 状态(0:禁用,1:启用)
+     * @return List<StoreProductItemDelicaciesVo>
+     */
+    List<StoreProductItemDelicaciesVo> getDelicaciesList(@Param("storeId") Integer storeId,
+                                                          @Param("name") String name,
+                                                          @Param("category") String category,
+                                                          @Param("extGroup") String extGroup,
+                                                          @Param("status") Integer status);
+
+    /**
+     * 查询store_product_item的所有美食相关的套餐和商品(prodType = 3)(用于合并查询)
+     *
+     * @param storeId 门店ID
+     * @param name 名称(模糊查询)
+     * @param status 状态(0:禁用,1:启用)
+     * @param packageType 套餐类型(预留,用于根据类型查询套餐)
+     * @return List<StoreProductItemDelicaciesVo>
+     */
+    List<StoreProductItemDelicaciesVo> getFoodPackageList(@Param("storeId") Integer storeId,
+                                                            @Param("name") String name,
+                                                            @Param("status") Integer status,
+                                                            @Param("packageType") Integer packageType);
+
+
+
+
+
+    List<StoreProductItemDelicaciesVo> getAllDelicacies(@Param("storeId") Integer storeId,
+                                                          @Param("name") String name,
+                                                          @Param("category") String category,
+                                                          @Param("extGroup") String extGroup,
+                                                          @Param("status") Integer status,
+                                                        @Param("packageType") Integer packageType
+    );
 }
 

+ 167 - 0
alien-entity/src/main/resources/mapper/StoreProductItemMapper.xml

@@ -262,5 +262,172 @@
         WHERE item.id = #{id} AND item.delete_flag = 0
     </select>
 
+    <!-- 商品表与美食商品表关联查询结果映射 -->
+    <resultMap id="StoreProductItemDelicaciesVoResultMap" type="shop.alien.entity.store.vo.StoreProductItemDelicaciesVo">
+        <!-- store_product_item 表字段 -->
+        <id column="id" property="id" />
+        <result column="store_id" property="storeId" />
+        <result column="prod_name" property="prodName" />
+        <result column="total_price" property="totalPrice" />
+        <result column="prod_type" property="prodType" />
+        <result column="images" property="images" />
+        <result column="image_content" property="imageContent" />
+        <result column="detail_content" property="detailContent" />
+        <result column="extra_note" property="extraNote" />
+        <result column="need_reserve" property="needReserve" />
+        <result column="reserve_rule" property="reserveRule" />
+        <result column="people_limit" property="peopleLimit" />
+        <result column="usage_rule" property="usageRule" />
+        <result column="item_status" property="status" />
+        <result column="rejection_reason" property="rejectionReason" />
+        <result column="item_delete_flag" property="deleteFlag" />
+        <result column="item_created_user_id" property="createdUserId" />
+        <result column="item_updated_user_id" property="updatedUserId" />
+        <result column="item_created_time" property="createdTime" />
+        <result column="item_updated_time" property="updatedTime" />
+        <!-- store_product_delicacies 表字段 -->
+        <result column="delicacies_id" property="delicaciesId" />
+        <result column="ext_id" property="extId" />
+        <result column="name" property="name" />
+        <result column="price" property="price" />
+        <result column="cost_price" property="costPrice" />
+        <result column="unit" property="unit" />
+        <result column="quantity" property="quantity" />
+        <result column="category" property="category" />
+        <result column="ext_group" property="extGroup" />
+        <result column="delicacies_status" property="delicaciesStatus" />
+        <result column="delicacies_delete_flag" property="delicaciesDeleteFlag" />
+        <result column="delicacies_created_user_id" property="delicaciesCreatedUserId" />
+        <result column="delicacies_updated_user_id" property="delicaciesUpdatedUserId" />
+        <result column="delicacies_created_time" property="delicaciesCreatedTime" />
+        <result column="delicacies_updated_time" property="delicaciesUpdatedTime" />
+        <!-- 辅助字段 -->
+        <result column="data_type" property="dataType" />
+    </resultMap>
+
+    <!-- 查询store_product_delicacies的所有菜品 -->
+    <select id="getDelicaciesList" resultMap="StoreProductItemDelicaciesVoResultMap">
+        SELECT
+            -- store_product_item 表字段
+            item.id,
+            item.store_id,
+            item.prod_name,
+            item.total_price,
+            item.prod_type,
+            item.images,
+            item.image_content,
+            item.detail_content,
+            item.extra_note,
+            item.need_reserve,
+            item.reserve_rule,
+            item.people_limit,
+            item.usage_rule,
+            item.status AS item_status,
+            item.rejection_reason,
+            item.delete_flag AS item_delete_flag,
+            item.created_user_id AS item_created_user_id,
+            item.updated_user_id AS item_updated_user_id,
+            item.created_time AS item_created_time,
+            item.updated_time AS item_updated_time,
+            -- store_product_delicacies 表字段
+            delicacies.id AS delicacies_id,
+            delicacies.ext_id,
+            delicacies.name,
+            delicacies.price,
+            delicacies.cost_price,
+            delicacies.unit,
+            delicacies.quantity,
+            delicacies.category,
+            delicacies.ext_group,
+            delicacies.status AS delicacies_status,
+            delicacies.delete_flag AS delicacies_delete_flag,
+            delicacies.created_user_id AS delicacies_created_user_id,
+            delicacies.updated_user_id AS delicacies_updated_user_id,
+            delicacies.created_time AS delicacies_created_time,
+            delicacies.updated_time AS delicacies_updated_time,
+            -- 数据类型:1-菜品
+            1 AS data_type
+        FROM store_product_delicacies delicacies
+        LEFT JOIN store_product_item item ON delicacies.ext_id = item.id AND item.delete_flag = 0
+        WHERE delicacies.delete_flag = 0
+        <if test="storeId != null">
+            AND (item.store_id = #{storeId} OR item.store_id IS NULL)
+        </if>
+        <if test="name != null and name != ''">
+            AND delicacies.name LIKE CONCAT('%', #{name}, '%')
+        </if>
+        <if test="category != null and category != ''">
+            AND delicacies.category = #{category}
+        </if>
+        <if test="extGroup != null and extGroup != ''">
+            AND delicacies.ext_group = #{extGroup}
+        </if>
+        <if test="status != null">
+            AND delicacies.status = #{status}
+        </if>
+        ORDER BY delicacies.created_time DESC
+    </select>
+
+    <!-- 查询store_product_item的所有美食相关的套餐和商品(prodType = 3) -->
+    <select id="getFoodPackageList" resultMap="StoreProductItemDelicaciesVoResultMap">
+        SELECT
+            -- store_product_item 表字段
+            item.id,
+            item.store_id,
+            item.prod_name,
+            item.total_price,
+            item.prod_type,
+            item.images,
+            item.image_content,
+            item.detail_content,
+            item.extra_note,
+            item.need_reserve,
+            item.reserve_rule,
+            item.people_limit,
+            item.usage_rule,
+            item.status AS item_status,
+            item.rejection_reason,
+            item.delete_flag AS item_delete_flag,
+            item.created_user_id AS item_created_user_id,
+            item.updated_user_id AS item_updated_user_id,
+            item.created_time AS item_created_time,
+            item.updated_time AS item_updated_time,
+            -- store_product_delicacies 表字段(可能为空,因为是套餐)
+            NULL AS delicacies_id,
+            NULL AS ext_id,
+            NULL AS name,
+            NULL AS price,
+            NULL AS cost_price,
+            NULL AS unit,
+            NULL AS quantity,
+            NULL AS category,
+            NULL AS ext_group,
+            NULL AS delicacies_status,
+            NULL AS delicacies_delete_flag,
+            NULL AS delicacies_created_user_id,
+            NULL AS delicacies_updated_user_id,
+            NULL AS delicacies_created_time,
+            NULL AS delicacies_updated_time,
+            -- 数据类型:2-套餐/商品
+            2 AS data_type
+        FROM store_product_item item
+        WHERE item.delete_flag = 0
+        AND item.prod_type = 3
+        <if test="storeId != null">
+            AND item.store_id = #{storeId}
+        </if>
+        <if test="name != null and name != ''">
+            AND item.prod_name LIKE CONCAT('%', #{name}, '%')
+        </if>
+        <if test="status != null">
+            AND item.status = #{status}
+        </if>
+        <if test="packageType != null">
+            -- 预留:根据类型查询套餐的口子,可以根据需要扩展
+            -- 例如:可以根据某个字段来区分不同类型的套餐
+        </if>
+        ORDER BY item.created_time DESC
+    </select>
+
 </mapper>
 

+ 30 - 0
alien-store/src/main/java/shop/alien/store/controller/StoreProductItemController.java

@@ -9,6 +9,7 @@ import shop.alien.entity.result.R;
 import shop.alien.entity.store.StoreProductItem;
 import shop.alien.entity.store.dto.StoreProductItemDto;
 import shop.alien.entity.store.vo.StoreProductItemGymVo;
+import shop.alien.entity.store.vo.StoreProductItemDelicaciesVo;
 import shop.alien.store.service.StoreProductItemService;
 
 import java.util.List;
@@ -130,5 +131,34 @@ public class StoreProductItemController {
         log.info("StoreProductItemController.getDetailWithGym?id={}", id);
         return storeProductItemService.getDetailWithGym(id);
     }
+
+    @ApiOperation("用户端查询美食商品列表(包含菜品和套餐)")
+    @ApiOperationSupport(order = 10)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "pageNum", value = "页码", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "pageSize", value = "页容", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "storeId", value = "门店ID", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "name", value = "名称(模糊查询)", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "category", value = "类别", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "extGroup", value = "菜品分组", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "status", value = "状态(0:禁用,1:启用)", dataType = "Integer", paramType = "query"),
+            @ApiImplicitParam(name = "packageType", value = "套餐类型(预留,用于根据类型查询套餐)", dataType = "Integer", paramType = "query")
+    })
+    @GetMapping("/getFoodAndPackagePage")
+    public R<IPage<StoreProductItemDelicaciesVo>> getFoodAndPackagePage(
+            @RequestParam(defaultValue = "1") int pageNum,
+            @RequestParam(defaultValue = "10") int pageSize,
+            @RequestParam(required = false) Integer storeId,
+            @RequestParam(required = false) String name,
+            @RequestParam(required = false) String category,
+            @RequestParam(required = false) String extGroup,
+            @RequestParam(required = false) Integer status,
+            @RequestParam(required = false) Integer packageType) {
+        log.info("StoreProductItemController.getFoodAndPackagePage?pageNum={}, pageSize={}, storeId={}, name={}, category={}, extGroup={}, status={}, packageType={}",
+                pageNum, pageSize, storeId, name, category, extGroup, status, packageType);
+        IPage<StoreProductItemDelicaciesVo> page = storeProductItemService.getPageWithDelicacies(
+                pageNum, pageSize, storeId, name, category, extGroup, status, packageType);
+        return R.data(page);
+    }
 }
 

+ 21 - 0
alien-store/src/main/java/shop/alien/store/service/StoreProductItemService.java

@@ -6,6 +6,7 @@ import shop.alien.entity.result.R;
 import shop.alien.entity.store.StoreProductItem;
 import shop.alien.entity.store.dto.StoreProductItemDto;
 import shop.alien.entity.store.vo.StoreProductItemGymVo;
+import shop.alien.entity.store.vo.StoreProductItemDelicaciesVo;
 
 import java.util.List;
 
@@ -92,5 +93,25 @@ public interface StoreProductItemService extends IService<StoreProductItem> {
     IPage<StoreProductItem> pageStoreProductItems(int pageNum, int pageSize,
                                                   Integer storeId, String prodName, Integer prodType,
                                                   Integer status, Integer needReserve);
+
+    /**
+     * 分页查询商品表与美食商品表关联数据
+     * 包含:1. store_product_delicacies的所有菜品
+     *      2. store_product_item的所有美食相关的套餐和商品(prodType = 3)
+     *
+     * @param pageNum     页码
+     * @param pageSize    页容
+     * @param storeId     门店ID
+     * @param name        名称(模糊查询)
+     * @param category    类别
+     * @param extGroup    菜品分组
+     * @param status      状态(0:禁用,1:启用)
+     * @param packageType 套餐类型(预留,用于根据类型查询套餐)
+     * @return IPage<StoreProductItemDelicaciesVo>
+     */
+    IPage<StoreProductItemDelicaciesVo> getPageWithDelicacies(int pageNum, int pageSize,
+                                                              Integer storeId, String name,
+                                                              String category, String extGroup,
+                                                              Integer status, Integer packageType);
 }
 

+ 219 - 0
alien-store/src/main/java/shop/alien/store/service/impl/StoreProductItemServiceImpl.java

@@ -18,6 +18,8 @@ import shop.alien.entity.store.StoreProductDelicacies;
 import shop.alien.entity.store.StoreProductGym;
 import shop.alien.entity.store.StoreProductItem;
 import shop.alien.entity.store.vo.StoreProductItemGymVo;
+import shop.alien.entity.store.vo.StoreProductItemDelicaciesVo;
+import shop.alien.entity.store.vo.StoreProductDelicaciesVo;
 import shop.alien.entity.store.dto.StoreProductItemDto;
 import shop.alien.mapper.StoreProductItemMapper;
 import shop.alien.store.service.StoreProductBarService;
@@ -26,7 +28,9 @@ import shop.alien.store.service.StoreProductGymService;
 import shop.alien.store.service.StoreProductItemService;
 
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
+import java.util.Map;
 import java.util.function.BiConsumer;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -238,5 +242,220 @@ public class StoreProductItemServiceImpl extends ServiceImpl<StoreProductItemMap
         return R.fail("查询失败,数据不存在");
     }
 
+    @Override
+    public IPage<StoreProductItemDelicaciesVo> getPageWithDelicacies(int pageNum, int pageSize,
+                                                                      Integer storeId, String name,
+                                                                      String category, String extGroup,
+                                                                      Integer status, Integer packageType) {
+        log.info("StoreProductItemServiceImpl.getPageWithDelicacies?pageNum={}, pageSize={}, storeId={}, name={}, category={}, extGroup={}, status={}, packageType={}",
+                pageNum, pageSize, storeId, name, category, extGroup, status, packageType);
+        
+        // 1. 查询主表store_product_item中关于美食的数据(prodType = 4)
+        LambdaQueryWrapper<StoreProductItem> itemWrapper = new LambdaQueryWrapper<>();
+        itemWrapper.eq(StoreProductItem::getProdType, 4)
+                .eq(StoreProductItem::getDeleteFlag, 0);
+        
+        if (storeId != null) {
+            itemWrapper.eq(StoreProductItem::getStoreId, storeId);
+        }
+        if (StringUtils.hasText(name)) {
+            itemWrapper.like(StoreProductItem::getProdName, name);
+        }
+        if (status != null) {
+            itemWrapper.eq(StoreProductItem::getStatus, status);
+        }
+        
+        // 查询所有主表数据(不分页,用于后续合并)
+        List<StoreProductItem> allItemList = this.list(itemWrapper);
+        List<Integer> allItemIds = allItemList != null ? allItemList.stream()
+                .map(StoreProductItem::getId)
+                .collect(Collectors.toList()) : new ArrayList<>();
+        
+        // 2. 查询所有关联的子表数据
+        LambdaQueryWrapper<StoreProductDelicacies> relatedDelicaciesWrapper = new LambdaQueryWrapper<>();
+        if (!allItemIds.isEmpty()) {
+            relatedDelicaciesWrapper.in(StoreProductDelicacies::getExtId, allItemIds)
+                    .eq(StoreProductDelicacies::getDeleteFlag, 0);
+        } else {
+            // 如果没有主表数据,设置一个不可能的条件
+            relatedDelicaciesWrapper.eq(StoreProductDelicacies::getExtId, -1)
+                    .eq(StoreProductDelicacies::getDeleteFlag, 0);
+        }
+        
+        // 子表筛选条件
+        if (StringUtils.hasText(name)) {
+            relatedDelicaciesWrapper.like(StoreProductDelicacies::getName, name);
+        }
+        if (StringUtils.hasText(category)) {
+            relatedDelicaciesWrapper.eq(StoreProductDelicacies::getCategory, category);
+        }
+        if (StringUtils.hasText(extGroup)) {
+            relatedDelicaciesWrapper.eq(StoreProductDelicacies::getExtGroup, extGroup);
+        }
+        if (status != null) {
+            relatedDelicaciesWrapper.eq(StoreProductDelicacies::getStatus, status);
+        }
+        
+        List<StoreProductDelicacies> relatedDelicaciesList = storeProductDelicaciesService.list(relatedDelicaciesWrapper);
+        
+        // 3. 查询独立的子表数据(extId为null或不在主表ID列表中的)
+        LambdaQueryWrapper<StoreProductDelicacies> independentDelicaciesWrapper = new LambdaQueryWrapper<>();
+        independentDelicaciesWrapper.eq(StoreProductDelicacies::getDeleteFlag, 0);
+        
+        // 独立的子表:extId为null,或者extId不在主表ID列表中
+        if (allItemIds.isEmpty()) {
+            // 如果没有主表数据,查询所有extId为null的子表数据
+            independentDelicaciesWrapper.isNull(StoreProductDelicacies::getExtId);
+        } else {
+            // extId为null,或者extId不在主表ID列表中
+            independentDelicaciesWrapper.and(wrapper -> wrapper.isNull(StoreProductDelicacies::getExtId)
+                    .or().notIn(StoreProductDelicacies::getExtId, allItemIds));
+        }
+        
+        // 子表筛选条件
+        if (StringUtils.hasText(name)) {
+            independentDelicaciesWrapper.like(StoreProductDelicacies::getName, name);
+        }
+        if (StringUtils.hasText(category)) {
+            independentDelicaciesWrapper.eq(StoreProductDelicacies::getCategory, category);
+        }
+        if (StringUtils.hasText(extGroup)) {
+            independentDelicaciesWrapper.eq(StoreProductDelicacies::getExtGroup, extGroup);
+        }
+        if (status != null) {
+            independentDelicaciesWrapper.eq(StoreProductDelicacies::getStatus, status);
+        }
+        
+        List<StoreProductDelicacies> independentDelicaciesList = storeProductDelicaciesService.list(independentDelicaciesWrapper);
+        
+        // 4. 按extId分组,构建关联子表数据映射
+        Map<Integer, List<StoreProductDelicaciesVo>> delicaciesMap = relatedDelicaciesList.stream()
+                .collect(Collectors.groupingBy(
+                        StoreProductDelicacies::getExtId,
+                        Collectors.mapping(delicacies -> convertToDelicaciesVo(delicacies), Collectors.toList())
+                ));
+        
+        // 5. 组装结果列表
+        List<StoreProductItemDelicaciesVo> resultList = new ArrayList<>();
+        
+        // 5.1 添加主表数据及其关联的子表数据
+        if (allItemList != null) {
+            for (StoreProductItem item : allItemList) {
+                StoreProductItemDelicaciesVo vo = convertItemToVo(item);
+                // 设置子表列表(一对多关系)
+                List<StoreProductDelicaciesVo> subList = delicaciesMap.getOrDefault(item.getId(), new ArrayList<>());
+                vo.setDelicaciesList(subList);
+                resultList.add(vo);
+            }
+        }
+        
+        // 5.2 添加独立的子表数据(作为独立的记录,主表字段为空)
+        for (StoreProductDelicacies delicacies : independentDelicaciesList) {
+            StoreProductItemDelicaciesVo vo = new StoreProductItemDelicaciesVo();
+            // 主表字段为空或null
+            vo.setId(null);
+            vo.setStoreId(null);
+            // 子表字段
+            vo.setDelicaciesId(delicacies.getId());
+            vo.setExtId(delicacies.getExtId());
+            vo.setName(delicacies.getName());
+            vo.setPrice(delicacies.getPrice());
+            vo.setCostPrice(delicacies.getCostPrice());
+            vo.setUnit(delicacies.getUnit());
+            vo.setQuantity(delicacies.getQuantity());
+            vo.setCategory(delicacies.getCategory());
+            vo.setExtGroup(delicacies.getExtGroup());
+            vo.setDelicaciesStatus(delicacies.getStatus());
+            vo.setDelicaciesDeleteFlag(delicacies.getDeleteFlag());
+            vo.setDelicaciesCreatedUserId(delicacies.getCreatedUserId());
+            vo.setDelicaciesUpdatedUserId(delicacies.getUpdatedUserId());
+            vo.setDelicaciesCreatedTime(delicacies.getCreatedTime());
+            vo.setDelicaciesUpdatedTime(delicacies.getUpdatedTime());
+            // 子表列表只包含自己
+            List<StoreProductDelicaciesVo> subList = new ArrayList<>();
+            subList.add(convertToDelicaciesVo(delicacies));
+            vo.setDelicaciesList(subList);
+            resultList.add(vo);
+        }
+        
+        // 6. 按创建时间倒序排序(主表或子表的创建时间)
+        resultList.sort((a, b) -> {
+            Date dateA = a.getDelicaciesCreatedTime() != null ? a.getDelicaciesCreatedTime() : a.getCreatedTime();
+            Date dateB = b.getDelicaciesCreatedTime() != null ? b.getDelicaciesCreatedTime() : b.getCreatedTime();
+            if (dateA == null && dateB == null) return 0;
+            if (dateA == null) return 1;
+            if (dateB == null) return -1;
+            return dateB.compareTo(dateA); // 倒序
+        });
+        
+        // 7. 手动分页
+        int total = resultList.size();
+        int start = (pageNum - 1) * pageSize;
+        int end = Math.min(start + pageSize, total);
+        
+        List<StoreProductItemDelicaciesVo> pageList = start < total ? resultList.subList(start, end) : new ArrayList<>();
+        
+        // 8. 构建分页结果
+        Page<StoreProductItemDelicaciesVo> resultPage = new Page<>(pageNum, pageSize);
+        resultPage.setRecords(pageList);
+        resultPage.setTotal(total);
+        resultPage.setPages((int) Math.ceil((double) total / pageSize));
+        resultPage.setCurrent(pageNum);
+        resultPage.setSize(pageSize);
+        
+        return resultPage;
+    }
+
+    /**
+     * 将StoreProductItem转换为VO
+     */
+    private StoreProductItemDelicaciesVo convertItemToVo(StoreProductItem item) {
+        StoreProductItemDelicaciesVo vo = new StoreProductItemDelicaciesVo();
+        vo.setId(item.getId());
+        vo.setStoreId(item.getStoreId());
+        vo.setProdName(item.getProdName());
+        vo.setTotalPrice(item.getTotalPrice());
+        vo.setProdType(item.getProdType());
+        vo.setImages(item.getImages());
+        vo.setImageContent(item.getImageContent());
+        vo.setDetailContent(item.getDetailContent());
+        vo.setExtraNote(item.getExtraNote());
+        vo.setNeedReserve(item.getNeedReserve());
+        vo.setReserveRule(item.getReserveRule());
+        vo.setPeopleLimit(item.getPeopleLimit());
+        vo.setUsageRule(item.getUsageRule());
+        vo.setStatus(item.getStatus());
+        vo.setRejectionReason(item.getRejectionReason());
+        vo.setDeleteFlag(item.getDeleteFlag());
+        vo.setCreatedUserId(item.getCreatedUserId());
+        vo.setUpdatedUserId(item.getUpdatedUserId());
+        vo.setCreatedTime(item.getCreatedTime());
+        vo.setUpdatedTime(item.getUpdatedTime());
+        return vo;
+    }
+
+    /**
+     * 将StoreProductDelicacies转换为VO
+     */
+    private StoreProductDelicaciesVo convertToDelicaciesVo(StoreProductDelicacies delicacies) {
+        StoreProductDelicaciesVo vo = new StoreProductDelicaciesVo();
+        vo.setId(delicacies.getId());
+        vo.setExtId(delicacies.getExtId());
+        vo.setName(delicacies.getName());
+        vo.setPrice(delicacies.getPrice());
+        vo.setCostPrice(delicacies.getCostPrice());
+        vo.setUnit(delicacies.getUnit());
+        vo.setQuantity(delicacies.getQuantity());
+        vo.setCategory(delicacies.getCategory());
+        vo.setExtGroup(delicacies.getExtGroup());
+        vo.setStatus(delicacies.getStatus());
+        vo.setDeleteFlag(delicacies.getDeleteFlag());
+        vo.setCreatedUserId(delicacies.getCreatedUserId());
+        vo.setUpdatedUserId(delicacies.getUpdatedUserId());
+        vo.setCreatedTime(delicacies.getCreatedTime());
+        vo.setUpdatedTime(delicacies.getUpdatedTime());
+        return vo;
+    }
+
 }