Browse Source

八大类 酒店团购

qxy 3 weeks ago
parent
commit
19784f0b1f

+ 145 - 0
alien-entity/src/main/java/shop/alien/entity/store/StoreHotelGroupRoomInfo.java

@@ -0,0 +1,145 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 酒店团购子表
+ * </p>
+ *
+ * @author qxy
+ * @since 2025-07-10
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@ApiModel(value="StoreHotelGroupRoomInfo对象", description="酒店团购子表")
+public class StoreHotelGroupRoomInfo extends Model<StoreHotelGroupRoomInfo> {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private String id;
+
+    @ApiModelProperty(value = "团购id")
+    @TableField("group_id")
+    private String groupId;
+
+    @ApiModelProperty(value = "面积")
+    @TableField("area")
+    private Double area;
+
+    @ApiModelProperty(value = "床尺寸code")
+    @TableField("bed_size_code")
+    private String bedSizeCode;
+
+    @ApiModelProperty(value = "床尺寸")
+    @TableField("bed_size")
+    private String bedSize;
+
+    @ApiModelProperty(value = "床数量")
+    @TableField("bed_num")
+    private Integer bedNum;
+
+    @ApiModelProperty(value = "窗:0:否,1:是")
+    @TableField("window_flag")
+    private Integer windowFlag;
+
+    @ApiModelProperty(value = "独立卫生间: 0:否,1:是")
+    @TableField("bathroom_flag")
+    private Integer bathroomFlag;
+
+    @ApiModelProperty(value = "wifi: 0:否,1:是")
+    @TableField("wifi_flag")
+    private Integer wifiFlag;
+
+    @ApiModelProperty(value = "早餐: 0:否,1:是")
+    @TableField("breakfast_flag")
+    private Integer breakfastFlag;
+
+    @ApiModelProperty(value = "起始楼层")
+    @TableField("floor_str")
+    private String floorStr;
+
+    @ApiModelProperty(value = "最低楼层")
+    @TableField("floor_end")
+    private String floorEnd;
+
+    @ApiModelProperty(value = "居住人数")
+    @TableField("residence_num")
+    private Integer residenceNum;
+
+    @ApiModelProperty(value = "吸烟:0:否,1:是")
+    @TableField("smoking_flag")
+    private Integer smokingFlag;
+
+    @ApiModelProperty(value = "删除状态")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    private Date createdTime;
+
+    @ApiModelProperty(value = "更新时间")
+    @TableField(value = "updated_time", fill = FieldFill.INSERT_UPDATE)
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField(value = "created_user_id", fill = FieldFill.INSERT)
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField(value = "updated_user_id", fill = FieldFill.INSERT_UPDATE)
+    private Integer updatedUserId;
+
+    @ApiModelProperty(value = "类别")
+    @TableField("category")
+    private String category;
+
+    @ApiModelProperty(value = "服务名称")
+    @TableField("service_name")
+    private String serviceName;
+
+    @ApiModelProperty(value = "数量")
+    @TableField("num")
+    private Integer num;
+
+    @ApiModelProperty(value = "分组名")
+    @TableField("group_name")
+    private String groupName;
+
+    @ApiModelProperty(value = "时长")
+    @TableField("duration")
+    private String duration;
+
+    @ApiModelProperty(value = "sonOrder")
+    @TableField("son_order")
+    private Integer sonOrder;
+
+    @ApiModelProperty(value = "fatherOrder")
+    @TableField("father_order")
+    private Integer fatherOrder;
+
+    @ApiModelProperty(value = "早餐说明")
+    @TableField("break_fast_str")
+    private String breakFastStr;
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 1 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/LifeCouponVo.java

@@ -10,6 +10,7 @@ import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
 import shop.alien.entity.store.LifeCoupon;
 import shop.alien.entity.store.StoreGroupInfo;
+import shop.alien.entity.store.StoreHotelGroupRoomInfo;
 
 
 import java.util.Date;

+ 3 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/LifeTuanGouParamVo.java

@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
 import lombok.Data;
 import shop.alien.entity.store.LifeCoupon;
 import shop.alien.entity.store.LifeGroupPackage;
+import shop.alien.entity.store.StoreHotelGroupRoomInfo;
 
 import java.util.List;
 
@@ -17,4 +18,6 @@ public class LifeTuanGouParamVo {
     LifeCoupon tuangou;
 
     List<LifeGroupPackage> tuangouPackageList;
+
+    List<StoreHotelGroupRoomInfo> tuangouHotelRoomList;
 }

+ 4 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/StoreGroupPackageVO.java

@@ -7,6 +7,7 @@ import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 import shop.alien.entity.store.LifeCoupon;
 import shop.alien.entity.store.StoreGroupInfo;
+import shop.alien.entity.store.StoreHotelGroupRoomInfo;
 
 import java.util.List;
 
@@ -22,4 +23,7 @@ public class StoreGroupPackageVO {
     @ApiModelProperty(value = "子表信息")
     private List<StoreGroupInfo> storeGroupInfos;
 
+    @ApiModelProperty(value = "酒店团购子表信息")
+    private List<StoreHotelGroupRoomInfo> storeHotelGroupRoomInfos;
+
 }

+ 16 - 0
alien-entity/src/main/java/shop/alien/mapper/StoreHotelGroupRoomInfoMapper.java

@@ -0,0 +1,16 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import shop.alien.entity.store.StoreHotelGroupRoomInfo;
+
+/**
+ * <p>
+ * 八大类团(酒店)房间表 Mapper 接口
+ * </p>
+ *
+ * @author ssk
+ * @since 2025-05-22
+ */
+public interface StoreHotelGroupRoomInfoMapper extends BaseMapper<StoreHotelGroupRoomInfo> {
+
+}

+ 46 - 0
alien-store/src/main/java/shop/alien/store/controller/LifeGroupPackageController.java

@@ -13,10 +13,12 @@ import org.springframework.web.bind.annotation.*;
 import shop.alien.entity.result.R;
 import shop.alien.entity.store.LifeCoupon;
 import shop.alien.entity.store.StoreGroupInfo;
+import shop.alien.entity.store.StoreHotelGroupRoomInfo;
 import shop.alien.entity.store.vo.LifeCouponVo;
 import shop.alien.entity.store.vo.LifeTuanGouParamVo;
 import shop.alien.mapper.LifeCouponMapper;
 import shop.alien.mapper.StoreGroupInfoMapper;
+import shop.alien.mapper.StoreHotelGroupRoomInfoMapper;
 import shop.alien.store.service.LifeCouponService;
 import shop.alien.store.service.LifeGroupPackageService;
 import shop.alien.util.common.ListToPage;
@@ -45,6 +47,8 @@ public class LifeGroupPackageController {
 
     private final StoreGroupInfoMapper storeGroupInfoMapper;
 
+    private final StoreHotelGroupRoomInfoMapper storeHotelGroupRoomInfoMapper;
+
     @ApiOperation("新建团购")
     @PostMapping("/addOrUpdateGroupPackage")
     public R<Boolean> addOrUpdateGroupPackage(@RequestBody LifeTuanGouParamVo lifeTuanGouParamVo) {
@@ -78,6 +82,20 @@ public class LifeGroupPackageController {
         return R.fail("失败");
     }
 
+    @ApiOperation("删除酒店团购")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "酒店团购主键id", dataType = "Integer", paramType = "query", required = true)
+    })
+    @GetMapping("/deleteHotelGroupPackage")
+    public R<Boolean> deleteHotelGroupPackage(@RequestParam("id") Integer id) {
+        log.info("LifeGroupPackageController.deleteHotelGroupPackage?id={}", id);
+        if (lifeCouponService.removeById(id)) {
+            storeHotelGroupRoomInfoMapper.delete(new LambdaQueryWrapper<StoreHotelGroupRoomInfo>().eq(StoreHotelGroupRoomInfo::getGroupId, id));
+            return R.success("成功");
+        }
+        return R.fail("失败");
+    }
+
     /**
      * @param storeId
      * @param status  状态:-1.待审核  -2.已驳回  0.待使用(已通过), 1.已核销, 2.已过期, 3.待退款, 4.已退款
@@ -104,6 +122,27 @@ public class LifeGroupPackageController {
         return R.data(lifeGroupPackageService.getGroupPackageList(page, size, storeId, status, couponCode, name));
     }
 
+    @ApiOperation("酒店团购列表")
+    @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 = "String", paramType = "query", required = true),
+            @ApiImplicitParam(name = "status", value = "状态", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "couponCode", value = "券id", dataType = "String", paramType = "query"),
+            @ApiImplicitParam(name = "name", value = "券名称", dataType = "String", paramType = "query")
+    })
+    @GetMapping("/getHotelGroupPackageList")
+    private R<IPage<LifeCouponVo>> getHotelGroupPackageList(
+            @RequestParam(defaultValue = "1") Integer page,
+            @RequestParam(defaultValue = "10") Integer size,
+            @RequestParam("storeId") String storeId,
+            @RequestParam("status") String status,
+            @RequestParam("couponCode") String couponCode,
+            @RequestParam("name") String name) {
+        log.info("LifeGroupPackageController.getHotelGroupPackageList?pageNum={},pageSize={},storeId={},status={}", storeId, status, page, size);
+        return R.data(lifeGroupPackageService.getHotelGroupPackageList(page, size, storeId, status, couponCode, name));
+    }
+
     @ApiOperation("暂停团购")
     @GetMapping("/updateGroupPackageStatus")
     public R<Boolean> updateGroupPackageStatus(@RequestParam("id") String id, @RequestParam("status") Integer status) {
@@ -121,6 +160,13 @@ public class LifeGroupPackageController {
         return R.data(lifeGroupPackageService.getGroupPackageDetail(id,userId));
     }
 
+    @ApiOperation("酒店团购详情")
+    @GetMapping("/getGroupHotelPackageDetail")
+    private R<Map<String, Object>> getGroupHotelPackageDetail(@RequestParam("id") String id, @RequestParam("userId") String userId) {
+        log.info("LifeGroupPackageController.getGroupHotelPackageDetail?id={}&userId={}", id, userId);
+        return R.data(lifeGroupPackageService.getGroupHotelPackageDetail(id,userId));
+    }
+
     @ApiOperation("猜你喜欢")
     @GetMapping("/getRecommendForYou")
     private R<IPage<LifeCoupon>> getRecommendForYou() {

+ 12 - 0
alien-store/src/main/java/shop/alien/store/controller/StoreGroupPackageController.java

@@ -38,4 +38,16 @@ public class StoreGroupPackageController {
             return R.fail(e.getMessage());
         }
     }
+
+    @ApiOperation("创建团购(酒店)-二期")
+    @PostMapping("/addHotelGroup")
+    public R<StoreGroupPackageVO> addHotelGroup(@RequestBody StoreGroupPackageVO storeGroupPackageVO) {
+        log.info("StoreGroupPackageController.addHotelGroup,storeGroupPackageVO={}", storeGroupPackageVO.toString());
+        try {
+            StoreGroupPackageVO packageVO = storeGroupPackageService.addHotelGroup(storeGroupPackageVO);
+            return R.data(packageVO);
+        } catch (Exception e) {
+            return R.fail(e.getMessage());
+        }
+    }
 }

+ 6 - 0
alien-store/src/main/java/shop/alien/store/service/LifeGroupPackageService.java

@@ -15,10 +15,16 @@ public interface LifeGroupPackageService extends IService<LifeGroupPackage> {
 
     int addOrUpdateGroupPackage(LifeTuanGouParamVo lifeTuanGouParamVo);
 
+    int addOrUpdateHotelGroupPackage(LifeTuanGouParamVo lifeTuanGouParamVo);
+
     IPage<LifeCouponVo> getGroupPackageList(Integer pageNum, Integer pageSize, String storeId, String status, String couponCode, String name);
 
+    IPage<LifeCouponVo> getHotelGroupPackageList(Integer pageNum, Integer pageSize, String storeId, String status, String couponCode, String name);
+
     int updateGroupPackageStatus(String id, Integer status);
 
     Map<String, Object> getGroupPackageDetail(String id, String userId);
 
+    Map<String, Object> getGroupHotelPackageDetail(String id, String userId);
+
 }

+ 9 - 0
alien-store/src/main/java/shop/alien/store/service/StoreGroupPackageService.java

@@ -21,4 +21,13 @@ public interface StoreGroupPackageService extends IService<StoreGroupPackage> {
      * @return 创建结果
      */
     StoreGroupPackageVO addGroup(StoreGroupPackageVO storeGroupPackageVO);
+
+
+    /**
+     * 创建酒店团购套餐
+     *
+     * @param storeGroupPackageVO 酒店团购套餐信息
+     * @return 创建结果
+     */
+    StoreGroupPackageVO addHotelGroup(StoreGroupPackageVO storeGroupPackageVO);
 }

+ 214 - 0
alien-store/src/main/java/shop/alien/store/service/impl/LifeGroupPackageServiceImpl.java

@@ -15,6 +15,7 @@ import shop.alien.entity.store.vo.LifeCouponVo;
 import shop.alien.entity.store.vo.LifeTuanGouParamVo;
 import shop.alien.mapper.*;
 import shop.alien.store.service.LifeGroupPackageService;
+import shop.alien.store.util.GroupConstant;
 import shop.alien.util.common.UniqueRandomNumGenerator;
 import shop.alien.util.common.constant.DiscountCouponEnum;
 
@@ -46,6 +47,7 @@ public class LifeGroupPackageServiceImpl extends ServiceImpl<LifeGroupPackageMap
     private final StoreInfoMapper storeInfoMapper;
     private final StoreGroupInfoMapper storeGroupInfoMapper;
     private final StoreImgMapper storeImgMapper;
+    private final StoreHotelGroupRoomInfoMapper storeHotelGroupRoomInfoMapper;
     private final LifeCollectMapper lifeCollectMapper;
 
 
@@ -186,6 +188,133 @@ public class LifeGroupPackageServiceImpl extends ServiceImpl<LifeGroupPackageMap
         }
     }
 
+
+    @Override
+    public int addOrUpdateHotelGroupPackage(LifeTuanGouParamVo lifeTuanGouParamVo) {
+        LifeCoupon lifeCoupon = lifeTuanGouParamVo.getTuangou();
+        List<StoreHotelGroupRoomInfo> storeHotelGroupRoomInfoList = lifeTuanGouParamVo.getTuangouHotelRoomList();
+
+        if (StringUtils.isEmpty(lifeCoupon.getId())) {
+            lifeCoupon.setType(GroupConstant.LIFE_GROUP_TYPE);
+            lifeCoupon.setStatus(GroupConstant.LIFE_COUPON_STATUS_PENDING_APPROVAL);
+            lifeCoupon.setCouponCode(UniqueRandomNumGenerator.generateUniqueCode(12));
+            int ret = lifeCouponMapper.insert(lifeCoupon);
+            if (ret == 0) {
+                return 0;
+            }
+
+            if (!storeHotelGroupRoomInfoList.isEmpty()) {
+                for (StoreHotelGroupRoomInfo storeHotelGroupRoomInfos : storeHotelGroupRoomInfoList) {
+                    if (StringUtils.isEmpty(storeHotelGroupRoomInfos.getId())) {
+                        storeHotelGroupRoomInfos.setGroupId(lifeCoupon.getId());
+                        storeHotelGroupRoomInfoMapper.insert(storeHotelGroupRoomInfos);
+                    }
+                }
+            }
+            return ret;
+        } else {
+            //状态变更为待审核
+            lifeCoupon.setStatus(GroupConstant.LIFE_COUPON_STATUS_PENDING_APPROVAL);
+            int ret = lifeCouponMapper.updateById(lifeCoupon);
+            if (ret == 0) {
+                return 0;
+            }
+            // 添加保价逻辑
+            // 查询
+            LifeCoupon lifeCouponById = lifeCouponMapper.selectById(lifeCoupon.getId());
+            // 当用户购买该团购,并且在开启保价
+            if (lifeCouponById.getOpenPriceProtection() != null && lifeCouponById.getPriceBelow() != null && lifeCouponById.getCouponComp() != null && lifeCouponById.getCouponCompDate() != null && lifeCouponById.getOpenPriceProtection() > 0) {
+                // 查询购买这个团购的用户订单
+                LambdaUpdateWrapper<LifeUserOrder> wrapper = new LambdaUpdateWrapper<>();
+                wrapper.eq(LifeUserOrder::getQuanId, lifeCouponById.getId());
+                List<LifeUserOrder> lifeUserOrders = lifeUserOrderMapper.selectList(wrapper);
+                if (!lifeUserOrders.isEmpty()) {
+                    // 在保价有效期内
+                    // 七天前的时间
+                    LocalDateTime sevenDaysAgo = LocalDateTime.now().minusDays(7);
+                    for (LifeUserOrder lifeUserOrder : lifeUserOrders) {
+                        Date createdTime = lifeUserOrder.getCreatedTime();
+                        LocalDateTime orderCreatedTime = createdTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+                        if (orderCreatedTime.isAfter(sevenDaysAgo)) {
+                            // 商家修改的价格
+                            String price = lifeCoupon.getPrice();
+                            BigDecimal decimalPrice = new BigDecimal(price);
+                            // 用户购买时价格
+                            String userPrice = lifeUserOrder.getPrice();
+                            BigDecimal decimalUserPrice = new BigDecimal(userPrice);
+                            // 商户修改价格 低于最开始规定的降价范围时,触发保价服务
+                            // 计算差值,并取绝对值
+                            BigDecimal priceDifference = decimalPrice.subtract(decimalUserPrice).abs();
+
+                            // 将lifeCouponById.getPriceBelow() 转换为 BigDecimal
+                            BigDecimal priceBelow = BigDecimal.valueOf(lifeCouponById.getPriceBelow());
+
+                            // 商户修改价格 低于最开始规定的降价范围时,触发保价服务
+                            if (priceDifference.compareTo(priceBelow) > 0) {                                // 给对应用户添加这个商家的优惠券 发送通知
+                                // 优惠券
+                                LifeDiscountCoupon newLifeCoupon = new LifeDiscountCoupon();
+                                newLifeCoupon.setName("价保补偿优惠券");
+                                newLifeCoupon.setStoreId(lifeCouponById.getStoreId());
+                                newLifeCoupon.setNominalValue(new BigDecimal(lifeCouponById.getCouponComp()));
+                                // 待定 有效期
+                                newLifeCoupon.setExpirationDate(lifeCouponById.getCouponCompDate());
+                                newLifeCoupon.setStartDate(LocalDate.now());
+                                // 设置结束日期为当前时间加上有效期
+                                newLifeCoupon.setEndDate(LocalDate.now().plusDays(lifeCouponById.getCouponCompDate()));
+                                newLifeCoupon.setSingleQty(1);
+                                newLifeCoupon.setType(1);
+                                newLifeCoupon.setCreatedTime(new Date());
+                                if (lifeDiscountCouponMapper.insert(newLifeCoupon) > 0) {
+                                    // 把优惠券分给对应用户
+                                    // 获取刚刚插入的优惠券的 ID
+                                    Integer couponId = newLifeCoupon.getId();
+                                    // 根据 ID 查询刚刚插入的优惠券
+                                    LifeDiscountCoupon insertedCoupon = lifeDiscountCouponMapper.selectById(couponId);
+
+                                    // 把优惠券分给对应用户
+                                    LifeDiscountCouponUser lifeDiscountCouponUser = new LifeDiscountCouponUser();
+                                    // 设置该优惠券记录的优惠券 ID
+                                    lifeDiscountCouponUser.setCouponId(insertedCoupon.getId());
+                                    // 设置该优惠券记录的用户 ID 为当前用户 ID
+                                    lifeDiscountCouponUser.setUserId(Integer.valueOf(lifeUserOrder.getUserId()));
+                                    // 设置该优惠券的领取时间为当前时间
+                                    lifeDiscountCouponUser.setReceiveTime(new Date());
+                                    // 设置该优惠券的过期时间为优惠券本身的结束日期
+                                    lifeDiscountCouponUser.setExpirationTime(insertedCoupon.getEndDate());
+                                    // 设置该优惠券的状态为待使用
+                                    lifeDiscountCouponUser.setStatus(Integer.parseInt(DiscountCouponEnum.WAITING_USED.getValue()));
+                                    // 将该用户优惠券记录插入到数据库中
+                                    if (lifeDiscountCouponUserMapper.insert(lifeDiscountCouponUser) > 0) {
+                                        // 发送通知
+                                        LifeNotice lifeMessage = new LifeNotice();
+                                        LifeUser lifeUser = lifeUserMapper.selectById(lifeUserOrder.getUserId());
+                                        lifeMessage.setReceiverId("user_" + lifeUser.getUserPhone());
+                                        String text = "您的编号为" + lifeUserOrder.getOrderNo() + "的订单降价了,平台已为您发放优惠价补偿,现已发放至您的的优惠券中,快去查收吧";
+                                        lifeMessage.setContext(text);
+                                        lifeMessage.setSenderId("system");
+                                        lifeMessage.setIsRead(0);
+                                        lifeMessage.setNoticeType(2);
+                                        lifeNoticeMapper.insert(lifeMessage);
+                                    }
+                                }
+                            }
+                        }
+
+                    }
+                }
+
+            }
+
+            LambdaUpdateWrapper<StoreHotelGroupRoomInfo> updateWrapper = new LambdaUpdateWrapper<>();
+            updateWrapper.eq(StoreHotelGroupRoomInfo::getGroupId, lifeCoupon.getId());
+            storeHotelGroupRoomInfoList.stream().forEach(RoomInfoList -> {
+                RoomInfoList.setGroupId(lifeCoupon.getId());
+                storeHotelGroupRoomInfoMapper.updateById(RoomInfoList);
+            });
+            return ret;
+        }
+    }
+
     @Override
     public IPage<LifeCouponVo> getGroupPackageList(Integer pageNum, Integer pageSize, String storeId, String status, String couponCode, String name) {
         IPage<LifeCouponVo> iPage = new Page<>(pageNum, pageSize);
@@ -227,6 +356,46 @@ public class LifeGroupPackageServiceImpl extends ServiceImpl<LifeGroupPackageMap
     }
 
     @Override
+    public IPage<LifeCouponVo> getHotelGroupPackageList(Integer pageNum, Integer pageSize, String storeId, String status, String couponCode, String name) {
+        IPage<LifeCouponVo> iPage = new Page<>(pageNum, pageSize);
+        QueryWrapper<LifeCouponVo> wrapper = new QueryWrapper<>();
+        wrapper.eq(StringUtils.isNotEmpty(storeId), "coupon.store_id ", storeId)
+                .eq("coupon.type", 2)
+                .eq("coupon.delete_flag", 0)
+                .and(StringUtils.isNotEmpty(couponCode) || StringUtils.isNotEmpty(name), wq -> wq.like(StringUtils.isNotEmpty(couponCode), "coupon.coupon_code", couponCode)
+                        .or()
+                        .like(StringUtils.isNotEmpty(name), "coupon.name", name))
+                .orderByDesc("coupon.created_time");
+        if (StringUtils.isNotEmpty(status)) {
+            if (status.equals("0")) {
+                wrapper.ge("coupon.status", 0);
+            } else if (status.equals("2")) {
+                wrapper.in("coupon.status", Arrays.asList(0, 2));
+            } else {
+                wrapper.eq("coupon.status", status);
+            }
+        }
+        IPage<LifeCouponVo> groupPackageList = lifeCouponMapper.getGroupPackageList(iPage, wrapper);
+        for (LifeCouponVo record : groupPackageList.getRecords()) {
+            record.setStoreHotelGroupRoomInfos(storeHotelGroupRoomInfoMapper.selectList(new LambdaQueryWrapper<StoreHotelGroupRoomInfo>().eq(StoreHotelGroupRoomInfo::getGroupId, record.getId())));
+            if (StringUtils.isNotEmpty(record.getUploadedPiclist())) {
+                List<String> collect = Arrays.stream(record.getUploadedPiclist().split(","))
+                        .map(String::trim)
+                        .collect(Collectors.toList());
+                List<StoreImg> storeImgs = storeImgMapper.selectList(new LambdaQueryWrapper<StoreImg>().in(StoreImg::getId, collect));
+                if (storeImgs!=null) {
+                    String imgs = storeImgs.stream()
+                            .map(StoreImg::getImgUrl)
+                            .collect(Collectors.joining(","));
+                    record.setImgs(imgs);
+                }
+            }
+        }
+        return groupPackageList;
+    }
+
+
+    @Override
     public int updateGroupPackageStatus(String id, Integer status) {
         LifeCoupon lifeCoupon = new LifeCoupon();
         lifeCoupon.setId(id);
@@ -299,4 +468,49 @@ public class LifeGroupPackageServiceImpl extends ServiceImpl<LifeGroupPackageMap
         returnMap.put("tuangouPackageList", resultList);
         return returnMap;
     }
+
+    @Override
+    public Map<String, Object> getGroupHotelPackageDetail(String id, String userId) {
+        Map<String, Object> returnMap = new HashMap<>();
+        LifeCoupon tuangou = lifeCouponMapper.selectById(id);
+        LambdaUpdateWrapper<StoreHotelGroupRoomInfo> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper.eq(StoreHotelGroupRoomInfo::getGroupId, tuangou.getId());
+        List<StoreHotelGroupRoomInfo> storeHotelGroupRoomInfoList = storeHotelGroupRoomInfoMapper.selectList(updateWrapper);
+        // 是否收藏了该团购
+        LifeCollect lifeCollect = lifeCollectMapper.selectOne(new QueryWrapper<LifeCollect>().eq("user_id", userId).eq("coupon_id", id));
+
+        // 添加商户信息
+        StoreInfo storeUser = storeInfoMapper.selectById(tuangou.getStoreId());
+        String receiverId = "store_" + storeUser.getStoreTel();
+
+        LifeCouponVo lifeCouponVo = new LifeCouponVo();
+        lifeCouponVo.setReceiverId(receiverId);
+        lifeCouponVo.setStoreName(storeUser.getStoreName());
+
+        LifeCouponVo tuangouVO = new LifeCouponVo();
+        BeanUtils.copyProperties(tuangou,tuangouVO);
+
+        tuangouVO.setIsCollect("0");
+        if(!Objects.isNull(lifeCollect)){
+            tuangouVO.setIsCollect("1");
+        }
+
+        if (StringUtils.isNotEmpty(tuangou.getUploadedPiclist())) {
+            List<String> collect = Arrays.stream(tuangou.getUploadedPiclist().split(","))
+                    .map(String::trim)
+                    .collect(Collectors.toList());
+            List<StoreImg> storeImgs = storeImgMapper.selectList(new LambdaQueryWrapper<StoreImg>().in(StoreImg::getId, collect));
+            if (storeImgs!=null) {
+                String imgs = storeImgs.stream()
+                        .map(StoreImg::getImgUrl)
+                        .collect(Collectors.joining(","));
+                tuangouVO.setImgs(imgs);
+            }
+        }
+
+        returnMap.put("lianxishangjia", lifeCouponVo);
+        returnMap.put("tuangou", tuangouVO);
+        returnMap.put("storeHotelGroupRoomInfoList", storeHotelGroupRoomInfoList);
+        return returnMap;
+    }
 }

+ 66 - 0
alien-store/src/main/java/shop/alien/store/service/impl/StoreGroupPackageServiceImpl.java

@@ -16,6 +16,7 @@ import shop.alien.mapper.StoreGroupPackageMapper;
 import shop.alien.mapper.StoreLabelTypeMapper;
 import shop.alien.store.service.LifeGroupPackageService;
 import shop.alien.store.service.StoreGroupPackageService;
+import shop.alien.store.util.GroupConstant;
 import shop.alien.util.common.UniqueRandomNumGenerator;
 
 import java.lang.reflect.Field;
@@ -100,6 +101,71 @@ public class StoreGroupPackageServiceImpl extends ServiceImpl<StoreGroupPackageM
         return storeGroupPackageVO;
     }
 
+    @Transactional
+    @Override
+    public StoreGroupPackageVO addHotelGroup(StoreGroupPackageVO storeGroupPackageVO) {
+        try {
+            log.info("开始创建酒店团购套餐,: {}", storeGroupPackageVO);
+
+            // 参数校验
+            validateStoreGroupPackageVO(storeGroupPackageVO);
+            LifeCoupon lifeCoupon = storeGroupPackageVO.getStoreGroupPackage();
+
+            // 有效期类型为天时,计算天数
+            calculateExpirationDateIfNecessary(lifeCoupon);
+
+            LifeTuanGouParamVo lifeTuanGouParamVo = new LifeTuanGouParamVo();
+            LifeCoupon tuangou = new LifeCoupon();
+            BeanUtils.copyProperties(lifeCoupon, tuangou);
+            lifeTuanGouParamVo.setTuangou(tuangou);
+            lifeCoupon.setCouponCode(UniqueRandomNumGenerator.generateUniqueCode(12));
+
+            // 处理标签中间表数据
+            try {
+                processLabelType(lifeCoupon);
+            } catch (Exception e) {
+                log.error("创建酒店团购套餐失败: 处理标签信息异常", e);
+                throw new RuntimeException("处理标签信息失败");
+            }
+            //创建子表集合
+            List<StoreHotelGroupRoomInfo> storeHotelGroupRoomInfos = new ArrayList<>();
+
+            // 将前端传入的子表信息,转换成酒店子表信息
+            List<StoreHotelGroupRoomInfo> hotelGroupRoomInfos = storeGroupPackageVO.getStoreHotelGroupRoomInfos();
+            hotelGroupRoomInfos.forEach(storeHotelGroupInfo -> {
+                StoreHotelGroupRoomInfo storeHotelGroupRoomInfo = new StoreHotelGroupRoomInfo();
+                BeanUtils.copyProperties(storeHotelGroupInfo, storeHotelGroupRoomInfo);
+                storeHotelGroupRoomInfos.add(storeHotelGroupRoomInfo);
+            });
+
+            //将主表信息子表信息存入库中
+            lifeTuanGouParamVo.setTuangouHotelRoomList(storeHotelGroupRoomInfos);
+            lifeGroupPackageService.addOrUpdateHotelGroupPackage(lifeTuanGouParamVo);
+        } catch (
+                Exception e) {
+            log.error("创建酒店团购套餐发生异常", e);
+            throw new RuntimeException(e.getMessage());
+        }
+        log.info("创建酒店团购套餐成功, 返回结果: {}", storeGroupPackageVO);
+        return storeGroupPackageVO;
+    }
+
+    private static void validateStoreGroupPackageVO(StoreGroupPackageVO storeGroupPackageVO) {
+        if (storeGroupPackageVO == null || storeGroupPackageVO.getStoreGroupPackage() == null ||
+                CollectionUtils.isEmpty(storeGroupPackageVO.getStoreHotelGroupRoomInfos())) {
+            throw new RuntimeException("请求参数不能为空");
+        }
+    }
+
+    private static void calculateExpirationDateIfNecessary(LifeCoupon lifeCoupon) {
+        if (StringUtil.isNotEmpty(lifeCoupon.getValidityPeriod()) &&
+                GroupConstant.VALIDITY_PERIOD_TYPE_DAY.equals(lifeCoupon.getValidityPeriodType())) {
+            String[] split = lifeCoupon.getValidityPeriod().split(",");
+            long diffSeconds = Math.abs(Long.parseLong(split[1]) - Long.parseLong(split[0]));
+            lifeCoupon.setExpirationDate((int) (diffSeconds / 86400000) + 1);
+        }
+    }
+
     /**
      * 处理标签整合
      *

+ 38 - 0
alien-store/src/main/java/shop/alien/store/util/GroupConstant.java

@@ -0,0 +1,38 @@
+package shop.alien.store.util;
+
+/**
+ * 八大团购常量
+ * @author zhangchen
+ * @since 2025/7/1
+ */
+public class GroupConstant {
+
+    /**
+     * 有效期类型,1:指定天数,2:指定时间段
+     */
+    public static final String VALIDITY_PERIOD_TYPE_DAY = "1";
+    public static final String VALIDITY_PERIOD_TYPE_TIME = "2";
+
+    /**
+     * 优惠券类型,1-代金券  2-团购(套餐)
+     */
+    public static final Integer LIFE_COUPON_TYPE = 1;
+    public static final Integer LIFE_GROUP_TYPE = 2;
+
+    /**
+     * 优惠券状态,-1:待审核,-2:审核不通过,0:未使用,1:使用中,2:暂停,3:已结束
+     */
+    public static final Integer LIFE_COUPON_STATUS_PENDING_APPROVAL = -1;
+    public static final Integer LIFE_COUPON_STATUS_REJECTED = -2;
+    public static final Integer LIFE_COUPON_STATUS_UNUSED = 0;
+    public static final Integer LIFE_COUPON_STATUS_USING = 1;
+    public static final Integer LIFE_COUPON_STATUS_PAUSE = 2;
+    public static final Integer LIFE_COUPON_STATUS_END = 3;
+
+    /**
+     * 标签类型 1:套餐, 2:门店
+     */
+    public static final String LABEL_TYPE_MENU = "1";
+    public static final String LABEL_TYPE_SHOP = "2";
+
+}