Forráskód Böngészése

新增情侣套餐管理相关接口

codingliang 10 hónapja
szülő
commit
86a148cbe5

+ 51 - 9
src/main/java/com/sqx/modules/lovers/controller/LoversSetController.java

@@ -1,27 +1,69 @@
 package com.sqx.modules.lovers.controller;
 
+import com.sqx.common.utils.PageUtils;
 import com.sqx.common.utils.Result;
-import com.sqx.modules.lovers.entity.LoversSet;
+import com.sqx.modules.lovers.dto.LoversSetAddDTO;
+import com.sqx.modules.lovers.dto.LoversSetQueryDTO;
 import com.sqx.modules.lovers.service.LoversSetService;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import javax.validation.constraints.Pattern;
+import java.util.List;
 
 @Slf4j
 @Api(tags = {"管理端-情侣套餐"})
 @RestController
-@RequestMapping("/admin/loverSet")
+@RequestMapping("lover-set")
+@RequiredArgsConstructor
 public class LoversSetController {
 
-    @Autowired
-    LoversSetService loversSetService;
+    private final LoversSetService loversSetService;
+
+    @ApiOperation("套餐分页查询")
+    @GetMapping("page")
+    public Result page(@Valid LoversSetQueryDTO queryDTO){
+        PageUtils pages = loversSetService.pages(queryDTO);
+        return Result.success().put("data", pages);
+    }
 
-    @PostMapping("/save")
-    public Result saveLoverSet(@RequestBody LoversSet loversSet){
-        return loversSetService.saveLoverSet(loversSet);
+    @ApiOperation("新增")
+    @PostMapping
+    public Result add(@RequestBody @Valid LoversSetAddDTO loversSetDTO){
+        loversSetService.add(loversSetDTO);
+        return Result.success();
     }
 
+    @ApiOperation("修改")
+    @PutMapping
+    public Result update(@RequestBody @Valid LoversSetAddDTO loversSetDTO){
+        loversSetService.update(loversSetDTO);
+        return Result.success();
+    }
 
+    @ApiOperation("修改套餐状态")
+    @PutMapping("update-status/{id}/status")
+    public Result updateStatus(@PathVariable Long id,
+                               @PathVariable @Pattern(regexp = "^[1-2]$", message = "状态格式只能为1-2") String status){
+        loversSetService.updateStatus(id, status);
+        return Result.success();
+    }
 
+    @ApiOperation("删除")
+    @DeleteMapping
+    public Result delete(@RequestBody List<Long> ids){
+        loversSetService.deleteByIds(ids);
+        return Result.success();
+    }
 }

+ 6 - 0
src/main/java/com/sqx/modules/lovers/dao/LoversSetDao.java

@@ -1,9 +1,15 @@
 package com.sqx.modules.lovers.dao;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.sqx.modules.lovers.dto.LoversSetQueryDTO;
 import com.sqx.modules.lovers.entity.LoversSet;
+import com.sqx.modules.lovers.vo.LoversSetVO;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 @Mapper
 public interface LoversSetDao extends BaseMapper<LoversSet> {
+    IPage<LoversSetVO> pages(@Param("pages") Page<LoversSetVO> pages, @Param("queryDTO") LoversSetQueryDTO queryDTO);
 }

+ 96 - 0
src/main/java/com/sqx/modules/lovers/dto/LoversSetAddDTO.java

@@ -0,0 +1,96 @@
+package com.sqx.modules.lovers.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraints.Size;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 情侣套餐新增DTO
+ * @author codingliang
+ * @date 2025-08-24
+ */
+@Data
+public class LoversSetAddDTO {
+
+    @ApiModelProperty("主键id")
+    private Long id;
+
+    @ApiModelProperty("套餐名称")
+    @NotBlank(message = "套餐名称不能为空")
+    private String name;
+
+    @ApiModelProperty("套餐子名称")
+    @NotBlank(message = "套餐子名称不能为空")
+    private String subName;
+
+    @ApiModelProperty("套餐标签;多个标签之间使用,分割")
+    private String setTag;
+
+    @ApiModelProperty("服务标签;多个标签之间使用,分割")
+    private String serviceTag;
+
+    @ApiModelProperty("价格")
+    @NotNull(message = "价格不能为空")
+    @Min(value = 0, message = "价格不能小于0")
+    private BigDecimal price;
+
+    @ApiModelProperty("原价")
+    @NotNull(message = "原价不能为空")
+    @Min(value = 0, message = "原价不能小于0")
+    private BigDecimal originalPrice;
+
+    @ApiModelProperty("图片;多张图片使用,分割,第一张为主图")
+    @NotBlank(message = "图片不能为空")
+    private String imgs;
+
+    @ApiModelProperty("套餐类型;1月度套餐,2季度套餐,3年度套餐,4自定义")
+    @NotBlank(message = "套餐类型不能为空")
+    @Pattern(regexp = "^[1-4]$", message = "套餐类型格式只能为1-4")
+    private String setType;
+
+    @ApiModelProperty("适用性别;1男、2女")
+    @NotBlank(message = "适用性别不能为空")
+    @Pattern(regexp = "^[1-2]$", message = "适用性别格式只能为1-2")
+    private String suitSex;
+
+    @ApiModelProperty("规则id")
+    @NotNull(message = "规则id不能为空")
+    private Long ruleId;
+
+    @ApiModelProperty("状态;1可用、2不可用")
+    @NotBlank(message = "状态不能为空")
+    @Pattern(regexp = "^[1-2]$", message = "状态格式只能为1-2")
+    private String setStatus;
+
+    @ApiModelProperty("子订单生成时机;单位:小时")
+    @NotNull(message = "子订单生成时机不能为空")
+    @Min(value = 0, message = "子订单生成时机不能小于0")
+    private Integer subOrderGenerateTime;
+
+    @ApiModelProperty("套餐开始时间")
+    @NotNull(message = "套餐开始时间不能为空")
+    private LocalDateTime startTime;
+
+    @ApiModelProperty("套餐结束时间")
+    @NotNull(message = "套餐结束时间不能为空")
+    private LocalDateTime endTime;
+
+    @ApiModelProperty("自定义时间段开始时间;type为4自定义时必填")
+    private LocalDateTime selfStartTime;
+
+    @ApiModelProperty("自定义时间段结束时间;type为4自定义时必填")
+    private LocalDateTime selfEndTime;
+
+    @ApiModelProperty("套餐详情列表")
+    @NotNull(message = "套餐详情列表不能为空")
+    @Size(min = 1, message = "套餐详情列表不能为空")
+    private List<LoversSetContentDTO> loversSetContentDTOS;
+}

+ 37 - 0
src/main/java/com/sqx/modules/lovers/dto/LoversSetContentDTO.java

@@ -0,0 +1,37 @@
+package com.sqx.modules.lovers.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.util.List;
+
+/**
+ * 情侣套餐内容
+ * @author codingliang
+ * @date 2025-08-24
+ */
+@Data
+public class LoversSetContentDTO {
+
+    @ApiModelProperty("主键id,修改时不能为空")
+    private Long id;
+
+    @ApiModelProperty("套餐id,修改时不能为空")
+    private Long loversSetId;
+
+    @ApiModelProperty("排序")
+    @NotNull(message = "排序不能为空")
+    private Integer sort;
+
+    @ApiModelProperty("内容名称")
+    @NotBlank(message = "内容名称不能为空")
+    private String contentName;
+
+    @ApiModelProperty("内容详情内容列表")
+    @NotNull(message = "内容详情内容列表不能为空")
+    @Size(min = 1, message = "内容详情内容列表不能为空")
+    private List<LoversSetContentDetailDTO> loversSetContentDetailDTOS;
+}

+ 58 - 0
src/main/java/com/sqx/modules/lovers/dto/LoversSetContentDetailDTO.java

@@ -0,0 +1,58 @@
+package com.sqx.modules.lovers.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 情侣套餐内容详情
+ */
+@Data
+@ApiModel("lovers_set_content_detail")
+public class LoversSetContentDetailDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("主键id,修改时不能为空")
+    private Long id;
+
+    @ApiModelProperty("情侣套餐内容id,修改时不能为空")
+    private Long loversSetContentId;
+
+    @ApiModelProperty("商品id")
+    @NotNull(message = "商品id不能为空")
+    private Long goodsId;
+
+    @ApiModelProperty("商品名称")
+    @NotBlank(message = "商品名称不能为空")
+    private String goodsName;
+
+    @ApiModelProperty("店铺id")
+    @NotNull(message = "店铺id不能为空")
+    private Long shopId;
+
+    @ApiModelProperty("店铺名称")
+    @NotBlank(message = "店铺名称不能为空")
+    private String shopName;
+
+    @ApiModelProperty("数量")
+    @NotNull(message = "数量不能为空")
+    @Min(value = 1, message = "数量不能小于1")
+    private Integer num;
+
+    @ApiModelProperty("价格")
+    @NotNull(message = "价格不能为空")
+    @Min(value = 0, message = "价格不能小于0")
+    private BigDecimal price;
+
+    @ApiModelProperty("原价")
+    @NotNull(message = "原价不能为空")
+    @Min(value = 0, message = "原价不能小于0")
+    private BigDecimal originalPrice;
+
+}

+ 22 - 0
src/main/java/com/sqx/modules/lovers/dto/LoversSetQueryDTO.java

@@ -0,0 +1,22 @@
+package com.sqx.modules.lovers.dto;
+
+import com.sqx.common.query.PageQuery;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author codingliang
+ * @date 2025-08-25
+ */
+@Data
+public class LoversSetQueryDTO extends PageQuery {
+
+    @ApiModelProperty("套餐名称")
+    private String name;
+
+    @ApiModelProperty("套餐类型;1月度套餐,2季度套餐,3年度套餐,4自定义")
+    private String setType;
+
+    @ApiModelProperty("适用性别;1男、2女")
+    private String suitSex;
+}

+ 0 - 2
src/main/java/com/sqx/modules/lovers/entity/LoversSet.java

@@ -73,6 +73,4 @@ public class LoversSet implements Serializable {
 
     @ApiModelProperty("自定义时间段结束时间;type为4自定义时必填")
     private String selfEndTime;
-
-
 }

+ 1 - 1
src/main/java/com/sqx/modules/lovers/entity/LoversSetContent.java

@@ -26,7 +26,7 @@ public class LoversSetContent implements Serializable {
     private String delFlag;
 
     @ApiModelProperty("套餐id")
-    private String loversSetId;
+    private Long loversSetId;
 
     @ApiModelProperty("排序")
     private Integer sort;

+ 12 - 0
src/main/java/com/sqx/modules/lovers/service/LoversSetContentDetailService.java

@@ -1,7 +1,19 @@
 package com.sqx.modules.lovers.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.sqx.modules.lovers.dto.LoversSetContentDetailDTO;
 import com.sqx.modules.lovers.entity.LoversSetContentDetail;
 
+import java.util.List;
+
 public interface LoversSetContentDetailService extends IService<LoversSetContentDetail> {
+    void add(List<LoversSetContentDetailDTO> detailDTOS);
+
+    void update(List<LoversSetContentDetailDTO> detailDTOS);
+
+    /**
+     * 根据内容id删除
+     * @param contentIds 内容id列表
+     */
+    void deleteByContentIds(List<Long> contentIds);
 }

+ 13 - 0
src/main/java/com/sqx/modules/lovers/service/LoversSetContentService.java

@@ -1,7 +1,20 @@
 package com.sqx.modules.lovers.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.sqx.modules.lovers.dto.LoversSetContentDTO;
 import com.sqx.modules.lovers.entity.LoversSetContent;
 
+import java.util.List;
+
 public interface LoversSetContentService extends IService<LoversSetContent> {
+    void add(List<LoversSetContentDTO> loversSetContentDTOS);
+
+    void update(List<LoversSetContentDTO> loversSetContentDTOS);
+
+    void deleteByIds(List<Long> ids);
+
+    /**
+     * 根据套餐id删除
+     */
+    void deleteByLoversSetIds(List<Long> loversSetIds);
 }

+ 19 - 2
src/main/java/com/sqx/modules/lovers/service/LoversSetService.java

@@ -1,9 +1,26 @@
 package com.sqx.modules.lovers.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.sqx.common.utils.Result;
+import com.sqx.common.utils.PageUtils;
+import com.sqx.modules.lovers.dto.LoversSetAddDTO;
+import com.sqx.modules.lovers.dto.LoversSetQueryDTO;
 import com.sqx.modules.lovers.entity.LoversSet;
 
+import java.util.List;
+
 public interface LoversSetService extends IService<LoversSet> {
-    Result saveLoverSet(LoversSet loversSet);
+    PageUtils pages(LoversSetQueryDTO loversSetQueryDTO);
+
+    void add(LoversSetAddDTO loversSetDTO);
+
+    void update(LoversSetAddDTO loversSetDTO);
+
+    void deleteByIds(List<Long> ids);
+
+    /**
+     * 修改状态
+     * @param id 主键id
+     * @param status 状态 1-正常 2-停用
+     */
+    void updateStatus(Long id, String status);
 }

+ 59 - 0
src/main/java/com/sqx/modules/lovers/service/impl/LoversSetContentDetailServiceImpl.java

@@ -1,11 +1,70 @@
 package com.sqx.modules.lovers.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.sqx.modules.lovers.dao.LoversSetContentDetailDao;
+import com.sqx.modules.lovers.dto.LoversSetContentDetailDTO;
 import com.sqx.modules.lovers.entity.LoversSetContentDetail;
 import com.sqx.modules.lovers.service.LoversSetContentDetailService;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
 
 @Service
 public class LoversSetContentDetailServiceImpl extends ServiceImpl<LoversSetContentDetailDao, LoversSetContentDetail> implements LoversSetContentDetailService {
+
+    @Override
+    @Transactional
+    public void add(List<LoversSetContentDetailDTO> detailDTOS) {
+        List<LoversSetContentDetail> entities = detailDTOS.stream().map(e -> {
+            LoversSetContentDetail loversSetContentDetail = new LoversSetContentDetail();
+            BeanUtil.copyProperties(e, loversSetContentDetail);
+            loversSetContentDetail.setDelFlag("0");
+            return loversSetContentDetail;
+        }).collect(Collectors.toList());
+
+        this.saveBatch(entities);
+    }
+
+    @Override
+    @Transactional
+    public void update(List<LoversSetContentDetailDTO> detailDTOS) {
+        List<LoversSetContentDetail> updateList = new ArrayList<>();
+        List<LoversSetContentDetail> addList = new ArrayList<>();
+
+        for (LoversSetContentDetailDTO detailDTO : detailDTOS) {
+            LoversSetContentDetail loversSetContentDetail = new LoversSetContentDetail();
+            BeanUtil.copyProperties(detailDTO, loversSetContentDetail);
+
+            if (ObjectUtil.isNotNull(detailDTO.getId())) {
+                updateList.add(loversSetContentDetail);
+            } else {
+                loversSetContentDetail.setDelFlag("0");
+                addList.add(loversSetContentDetail);
+            }
+        }
+
+        // 更新数据
+        if (!updateList.isEmpty()) {
+            this.updateBatchById(updateList);
+        }
+
+        // 新增数据
+        if (!addList.isEmpty()) {
+            this.saveBatch(addList);
+        }
+    }
+
+    @Override
+    @Transactional
+    public void deleteByContentIds(List<Long> contentIds) {
+        LambdaQueryWrapper<LoversSetContentDetail> deleteWrapper = new LambdaQueryWrapper<>();
+        deleteWrapper.in(LoversSetContentDetail::getLoversSetContentId, contentIds);
+        this.remove(deleteWrapper);
+    }
 }

+ 131 - 0
src/main/java/com/sqx/modules/lovers/service/impl/LoversSetContentServiceImpl.java

@@ -1,11 +1,142 @@
 package com.sqx.modules.lovers.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.sqx.modules.lovers.dao.LoversSetContentDao;
+import com.sqx.modules.lovers.dto.LoversSetContentDTO;
+import com.sqx.modules.lovers.dto.LoversSetContentDetailDTO;
 import com.sqx.modules.lovers.entity.LoversSetContent;
+import com.sqx.modules.lovers.service.LoversSetContentDetailService;
 import com.sqx.modules.lovers.service.LoversSetContentService;
+import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
 
 @Service
+@RequiredArgsConstructor
 public class LoversSetContentServiceImpl extends ServiceImpl<LoversSetContentDao, LoversSetContent> implements LoversSetContentService {
+
+    private final LoversSetContentDetailService loversSetContentDetailService;
+
+    @Override
+    @Transactional
+    public void add(List<LoversSetContentDTO> loversSetContentDTOS) {
+        List<LoversSetContent> loversSetContents = loversSetContentDTOS.stream().map(e -> {
+            LoversSetContent loversSetContent = new LoversSetContent();
+            BeanUtil.copyProperties(e, loversSetContent);
+            loversSetContent.setDelFlag("0");
+            return loversSetContent;
+        }).collect(Collectors.toList());
+
+        this.saveBatch(loversSetContents);
+
+        // 保存套餐内容详情
+        List<LoversSetContentDetailDTO> allDetails = getLoversSetContentDetailDTOS(loversSetContentDTOS, loversSetContents);
+        loversSetContentDetailService.add(allDetails);
+    }
+
+    @Override
+    @Transactional
+    public void update(List<LoversSetContentDTO> loversSetContentDTOS) {
+        Long loversSetId = loversSetContentDTOS.get(0).getLoversSetId();
+        LambdaQueryWrapper<LoversSetContent> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(LoversSetContent::getLoversSetId, loversSetId);
+        List<LoversSetContent> oldList = this.list(queryWrapper);
+
+        // 提取DTO中的ID列表
+        List<Long> dtoIds = loversSetContentDTOS.stream()
+                .filter(dto -> ObjectUtil.isNotNull(dto.getId()))
+                .map(LoversSetContentDTO::getId)
+                .collect(Collectors.toList());
+        // 待删除数据id列表
+        List<Long> deleteIds = oldList.stream()
+                .filter(old -> !dtoIds.contains(old.getId()))
+                .map(LoversSetContent::getId)
+                .collect(Collectors.toList());
+
+        // 区分更新和新增数据
+        List<LoversSetContent> updateList = new ArrayList<>();
+        List<LoversSetContent> addList = new ArrayList<>();
+        List<LoversSetContentDTO> updateDTOList = new ArrayList<>();
+        List<LoversSetContentDTO> addDTOList = new ArrayList<>();
+        List<Long> existingIds = oldList.stream().map(LoversSetContent::getId).collect(Collectors.toList());
+        for (LoversSetContentDTO dto : loversSetContentDTOS) {
+            LoversSetContent entity = new LoversSetContent();
+            BeanUtil.copyProperties(dto, entity);
+
+            if (ObjectUtil.isNotNull(dto.getId()) && existingIds.contains(dto.getId())) {
+                // 更新操作
+                updateList.add(entity);
+                updateDTOList.add(dto);
+            } else {
+                // 新增操作
+                entity.setId(null); // 清除可能存在的无效ID
+                entity.setDelFlag("0");
+                addList.add(entity);
+                addDTOList.add(dto);
+            }
+        }
+
+        // 删除数据
+        if (CollUtil.isNotEmpty(deleteIds)) {
+            deleteByIds(deleteIds);
+        }
+
+        // 更新数据
+        if (!updateList.isEmpty()) {
+            this.updateBatchById(updateList);
+        }
+
+        // 新增数据
+        if (!addList.isEmpty()) {
+            this.saveBatch(addList);
+        }
+
+        // 合并更新和新增的内容详情
+        List<LoversSetContentDetailDTO> unionDetails = CollUtil.union(
+                    getLoversSetContentDetailDTOS(updateDTOList, updateList),
+                    getLoversSetContentDetailDTOS(addDTOList, addList)
+                )
+                .stream()
+                .collect(Collectors.toList());
+        loversSetContentDetailService.update(unionDetails);
+    }
+
+    @Override
+    @Transactional
+    public void deleteByIds(List<Long> ids) {
+        removeByIds(ids);
+        // 删除内容详情
+        loversSetContentDetailService.deleteByContentIds(ids);
+    }
+
+    @Override
+    @Transactional
+    public void deleteByLoversSetIds(List<Long> loversSetIds) {
+        LambdaQueryWrapper<LoversSetContent> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.in(LoversSetContent::getLoversSetId, loversSetIds);
+        List<LoversSetContent> list = list(queryWrapper);
+        List<Long> ids = list.stream().map(LoversSetContent::getId).collect(Collectors.toList());
+
+        deleteByIds(ids);
+    }
+
+    private List<LoversSetContentDetailDTO> getLoversSetContentDetailDTOS(List<LoversSetContentDTO> loversSetContentDTOS, List<LoversSetContent> loversSetContents) {
+        List<LoversSetContentDetailDTO> allDetails = new ArrayList<>();
+        for (int i = 0; i < loversSetContentDTOS.size(); i++) {
+            LoversSetContentDTO dto = loversSetContentDTOS.get(i);
+            LoversSetContent entity = loversSetContents.get(i);
+            List<LoversSetContentDetailDTO> details = dto.getLoversSetContentDetailDTOS();
+            details.forEach(detail -> detail.setLoversSetContentId(entity.getId()));
+            allDetails.addAll(details);
+        }
+        return allDetails;
+    }
 }

+ 63 - 6
src/main/java/com/sqx/modules/lovers/service/impl/LoversSetServiceImpl.java

@@ -1,21 +1,78 @@
 package com.sqx.modules.lovers.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.sqx.common.utils.Result;
+import com.sqx.common.utils.PageUtils;
 import com.sqx.modules.lovers.dao.LoversSetDao;
+import com.sqx.modules.lovers.dto.LoversSetAddDTO;
+import com.sqx.modules.lovers.dto.LoversSetQueryDTO;
 import com.sqx.modules.lovers.entity.LoversSet;
+import com.sqx.modules.lovers.service.LoversSetContentService;
 import com.sqx.modules.lovers.service.LoversSetService;
-import org.springframework.beans.factory.annotation.Autowired;
+import com.sqx.modules.lovers.vo.LoversSetVO;
+import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
 
 @Service
+@RequiredArgsConstructor
 public class LoversSetServiceImpl extends ServiceImpl<LoversSetDao, LoversSet> implements LoversSetService {
-    @Autowired
-    LoversSetDao loversSetDao;
+
+    private final LoversSetContentService loversSetContentService;
+
+    @Override
+    public PageUtils pages(LoversSetQueryDTO queryDTO) {
+        IPage<LoversSetVO> page = baseMapper.pages(new Page<>(queryDTO.getPage(), queryDTO.getLimit()), queryDTO);
+        PageUtils pageUtils = new PageUtils(page);
+        return pageUtils;
+    }
+
+    @Override
+    @Transactional
+    public void add(LoversSetAddDTO loversSetDTO) {
+        // 新增主信息
+        LoversSet loversSet = new LoversSet();
+        BeanUtil.copyProperties(loversSetDTO, loversSet);
+        loversSet.setDelFlag("0");
+        this.save(loversSet);
+
+        loversSetDTO.getLoversSetContentDTOS().forEach(e -> e.setLoversSetId(loversSet.getId()));
+        // 新增套餐内容
+        loversSetContentService.add(loversSetDTO.getLoversSetContentDTOS());
+    }
 
     @Override
-    public Result saveLoverSet(LoversSet loversSet) {
+    @Transactional
+    public void update(LoversSetAddDTO loversSetDTO) {
+        LoversSet loversSet = new LoversSet();
+        BeanUtil.copyProperties(loversSetDTO, loversSet);
 
-        return null;
+        this.updateById(loversSet);
+
+        loversSetDTO.getLoversSetContentDTOS().stream().filter(e -> ObjectUtil.isNull(e.getId())).forEach(e -> e.setLoversSetId(loversSet.getId()));
+        // 修改套餐内容
+        loversSetContentService.update(loversSetDTO.getLoversSetContentDTOS());
+    }
+
+    @Override
+    @Transactional
+    public void deleteByIds(List<Long> ids) {
+        this.removeByIds(ids);
+
+        // 删除套餐内容
+        loversSetContentService.deleteByLoversSetIds(ids);
+    }
+
+    @Override
+    public void updateStatus(Long id, String status) {
+        LoversSet loversSet = new LoversSet();
+        loversSet.setId(id);
+        loversSet.setSetStatus(status);
+        this.updateById(loversSet);
     }
 }

+ 38 - 0
src/main/java/com/sqx/modules/lovers/vo/LoversSetContentDetailVO.java

@@ -0,0 +1,38 @@
+package com.sqx.modules.lovers.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+@ApiModel("lovers_set_content_detail")
+public class LoversSetContentDetailVO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("内容详情id")
+    private Long contentDetailId;
+
+    @ApiModelProperty("商品id")
+    private Long goodsId;
+
+    @ApiModelProperty("商品名称")
+    private String goodsName;
+
+    @ApiModelProperty("店铺id")
+    private Long shopId;
+
+    @ApiModelProperty("店铺名称")
+    private String shopName;
+
+    @ApiModelProperty("数量")
+    private Integer num;
+
+    @ApiModelProperty("价格")
+    private BigDecimal price;
+
+    @ApiModelProperty("原价")
+    private BigDecimal originalPrice;
+}

+ 26 - 0
src/main/java/com/sqx/modules/lovers/vo/LoversSetContentVO.java

@@ -0,0 +1,26 @@
+package com.sqx.modules.lovers.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@ApiModel("lovers_set_content")
+public class LoversSetContentVO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("主键id")
+    private Long contentId;
+
+    @ApiModelProperty("排序")
+    private Integer sort;
+
+    @ApiModelProperty("内容名称")
+    private String contentName;
+
+    @ApiModelProperty("内容详情列表")
+    private List<LoversSetContentDetailVO> contentDetailList;
+}

+ 69 - 0
src/main/java/com/sqx/modules/lovers/vo/LoversSetVO.java

@@ -0,0 +1,69 @@
+package com.sqx.modules.lovers.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * @author codingliang
+ * @date 2025-08-25
+ */
+@Data
+public class LoversSetVO {
+
+    @ApiModelProperty("主键id")
+    private Long id;
+
+    @ApiModelProperty("套餐名称")
+    private String name;
+
+    @ApiModelProperty("套餐子名称")
+    private String subName;
+
+    @ApiModelProperty("套餐标签;多个标签之间使用,分割")
+    private String setTag;
+
+    @ApiModelProperty("服务标签;多个标签之间使用,分割")
+    private String serviceTag;
+
+    @ApiModelProperty("价格")
+    private BigDecimal price;
+
+    @ApiModelProperty("原价")
+    private BigDecimal originalPrice;
+
+    @ApiModelProperty("图片;多张图片使用,分割,第一张为主图")
+    private String imgs;
+
+    @ApiModelProperty("套餐类型;1月度套餐,2季度套餐,3年度套餐,4自定义")
+    private String setType;
+
+    @ApiModelProperty("适用性别;1男、2女")
+    private String suitSex;
+
+    @ApiModelProperty("规则id")
+    private Long ruleId;
+
+    @ApiModelProperty("状态;1可用、2不可用")
+    private String setStatus;
+
+    @ApiModelProperty("子订单生成时机;单位:小时")
+    private Integer subOrderGenerateTime;
+
+    @ApiModelProperty("套餐开始时间")
+    private String startTime;
+
+    @ApiModelProperty("套餐结束时间")
+    private String endTime;
+
+    @ApiModelProperty("自定义时间段开始时间;type为4自定义时必填")
+    private String selfStartTime;
+
+    @ApiModelProperty("自定义时间段结束时间;type为4自定义时必填")
+    private String selfEndTime;
+
+    @ApiModelProperty("套餐内容列表")
+    private List<LoversSetContentVO> contentList;
+}

+ 88 - 1
src/main/resources/mapper/lovers/LoversSetDao.xml

@@ -3,4 +3,91 @@
 
 <mapper namespace="com.sqx.modules.lovers.dao.LoversSetDao">
 
-</mapper>
+    <resultMap id="LoversSetVOMap" type="com.sqx.modules.lovers.vo.LoversSetVO">
+        <id column="id" property="id"/>
+        <result column="name" property="name"/>
+        <result column="sub_name" property="subName"/>
+        <result column="set_tag" property="setTag"/>
+        <result column="service_tag" property="serviceTag"/>
+        <result column="price" property="price"/>
+        <result column="original_price" property="originalPrice"/>
+        <result column="imgs" property="imgs"/>
+        <result column="set_type" property="setType"/>
+        <result column="suit_sex" property="suitSex"/>
+        <result column="rule_id" property="ruleId"/>
+        <result column="set_status" property="setStatus"/>
+        <result column="sub_order_generate_time" property="subOrderGenerateTime"/>
+        <result column="start_time" property="startTime"/>
+        <result column="end_time" property="endTime"/>
+        <result column="self_start_time" property="selfStartTime"/>
+        <result column="self_end_time" property="selfEndTime"/>
+
+        <!-- 内容列表映射 -->
+        <collection property="contentList" ofType="com.sqx.modules.lovers.vo.LoversSetContentVO">
+            <result column="contentId" property="contentId"/>
+            <result column="sort" property="sort"/>
+            <result column="content_name" property="contentName"/>
+
+            <!-- 详情列表映射 -->
+            <collection property="contentDetailList" ofType="com.sqx.modules.lovers.vo.LoversSetContentDetailVO">
+                <result column="content_detail_id" property="contentDetailId"/>
+                <result column="goods_id" property="goodsId"/>
+                <result column="goods_name" property="goodsName"/>
+                <result column="shop_id" property="shopId"/>
+                <result column="shop_name" property="shopName"/>
+                <result column="num" property="num"/>
+                <result column="detail_price" property="price"/>
+                <result column="detail_original_price" property="originalPrice"/>
+            </collection>
+        </collection>
+    </resultMap>
+
+    <select id="pages" resultMap="LoversSetVOMap">
+        SELECT
+            s.id,
+            s.name,
+            s.sub_name,
+            s.set_tag,
+            s.service_tag,
+            s.price,
+            s.original_price,
+            s.imgs,
+            s.set_type,
+            s.suit_sex,
+            s.rule_id,
+            s.set_status,
+            s.sub_order_generate_time,
+            s.start_time,
+            s.end_time,
+            s.self_start_time,
+            s.self_end_time,
+            sc.id as contentId,
+            sc.sort,
+            sc.content_name as contentName,
+            scd.id as contentDetailId,
+            scd.goods_id,
+            scd.goods_name,
+            scd.shop_id,
+            scd.shop_name,
+            scd.num,
+            scd.detail_price,
+            scd.detail_original_price
+        FROM
+            lovers_set s
+            left join lovers_set_content sc on sc.lovers_set_id = s.id
+            left join lovers_set_content_detail scd on scd.lovers_set_content_id = sc.id
+        WHERE
+            s.del_flag = 0
+            and sc.del_flag = 0
+            and scd.del_flag = 0
+        <if test="queryDTO.name != null and queryDTO.name != ''">
+            and s.name like concat('%', #{queryDTO.name}, '%')
+        </if>
+        <if test="queryDTO.setType != null and queryDTO.setType != ''">
+            and s.set_type = #{queryDTO.setType}
+        </if>
+        <if test="queryDTO.suitSex != null and queryDTO.suitSex != ''">
+            and s.suit_sex = #{queryDTO.suitSex}
+        </if>
+    </select>
+</mapper>