Parcourir la source

新增客户部分代码

YPZ il y a 1 semaine
Parent
commit
98c4ff5ea2

+ 104 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/controller/SopDetailController.java

@@ -0,0 +1,104 @@
+package com.storlead.trade.controller;
+
+import com.storlead.framework.common.result.Result;
+import com.storlead.trade.dto.SopDetailCreateDTO;
+import com.storlead.trade.dto.SopDetailDTO;
+import com.storlead.trade.dto.SopDetailUpdateDTO;
+import com.storlead.trade.entity.SopDetailEntity;
+import com.storlead.trade.service.SopDetailService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * SOP步骤明细(sop_detail)Controller
+ * 直接对 sop_detail 表做增删改查
+ *
+ * @author Generated
+ */
+@Slf4j
+@RestController
+@RequestMapping("/sopDetail")
+@Api(tags = "营销: SOP步骤明细")
+public class SopDetailController {
+
+    @Resource
+    private SopDetailService sopDetailService;
+
+    /**
+     * 分页查询 SOP 明细
+     */
+    @PostMapping("/list")
+    @ApiOperation(value = "SOP步骤明细分页查询", notes = "支持按 sopId/step/name/emailContent/days/type 筛选,name/emailContent 模糊")
+    public Result<Object> list(@RequestBody SopDetailDTO dto) {
+        return sopDetailService.getList(dto);
+    }
+
+    /**
+     * 新增 SOP 明细
+     */
+    @PostMapping("/add")
+    @ApiOperation(value = "新增SOP步骤明细", notes = "sopId 必填,step 必填")
+    public Result<Object> add(@RequestBody SopDetailCreateDTO dto) {
+        return sopDetailService.add(dto);
+    }
+
+    /**
+     * 更新 SOP 明细
+     */
+    @PostMapping("/edit")
+    @ApiOperation(value = "更新SOP步骤明细", notes = "id 必填,其余字段非空才更新")
+    public Result<Object> edit(@RequestBody SopDetailUpdateDTO dto) {
+        return sopDetailService.edit(dto);
+    }
+
+    /**
+     * 删除 SOP 明细(单条/批量,逻辑删除)
+     * 请求体示例:{"id":1} 或 {"idList":[1,2,3]}
+     */
+    @PostMapping("/delete")
+    @ApiOperation(value = "删除SOP步骤明细", notes = "支持 id 单删或 idList 批量删(逻辑删除)")
+    public Result<Object> delete(@RequestBody SopDetailDTO dto) {
+        if (dto == null) {
+            return Result.error("请求体不能为空");
+        }
+        List<Long> ids = new ArrayList<>();
+        if (!ObjectUtils.isEmpty(dto.getId())) {
+            ids.add(dto.getId());
+        }
+        if (!CollectionUtils.isEmpty(dto.getIdList())) {
+            ids.addAll(dto.getIdList());
+        }
+        if (ids.isEmpty()) {
+            return Result.error("id 或 idList 不能为空");
+        }
+        return sopDetailService.delete(ids);
+    }
+
+    /**
+     * SOP 明细详情
+     */
+    @GetMapping("/getById")
+    @ApiOperation(value = "SOP步骤明细详情")
+    public Result<Object> getById(Long id) {
+        if (ObjectUtils.isEmpty(id)) {
+            return Result.error("id 不能为空");
+        }
+        SopDetailEntity entity = sopDetailService.getById(id);
+        if (entity == null) {
+            return Result.error("明细不存在");
+        }
+        return Result.result(entity);
+    }
+}

+ 6 - 1
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SopDetailCreateDTO.java

@@ -15,6 +15,11 @@ import java.io.Serializable;
 @ApiModel(value = "SopDetailCreateDTO", description = "SOP步骤明细创建请求")
 public class SopDetailCreateDTO implements Serializable {
 
+    @ApiModelProperty(value = "SOP id", required = true)
+    @NotNull(message = "SOP id不能为空")
+    @TableField("sop_id")
+    private Long sopId;
+
     @ApiModelProperty(value = "步骤序号", required = true)
     @NotNull(message = "步骤序号不能为空")
     private Integer step;
@@ -31,4 +36,4 @@ public class SopDetailCreateDTO implements Serializable {
 
     @ApiModelProperty(value = "触达渠道")
     private String type;
-}
+}

+ 53 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SopDetailDTO.java

@@ -0,0 +1,53 @@
+package com.storlead.trade.dto;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.storlead.framework.mybatis.page.Page;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * SOP明细分页查询 DTO(sop_detail 表增删改查页面用)
+ *
+ * @author Generated
+ */
+@Data
+@ApiModel(value = "SopDetailDTO", description = "SOP步骤明细查询/分页请求")
+@TableName("sop_detail")
+public class SopDetailDTO extends Page {
+
+    @ApiModelProperty(value = "主键id")
+    @TableId
+    private Long id;
+
+    @ApiModelProperty(value = "id列表(批量操作用)")
+    private List<Long> idList;
+
+    @ApiModelProperty(value = "SOP id(按所属SOP筛选)")
+    @TableField("sop_id")
+    private Long sopId;
+
+    @ApiModelProperty(value = "步骤序号")
+    @TableField("step")
+    private Integer step;
+
+    @ApiModelProperty(value = "步骤名称(模糊)")
+    @TableField("name")
+    private String name;
+
+    @ApiModelProperty(value = "邮件内容模板(模糊)")
+    @TableField("email_content")
+    private String emailContent;
+
+    @ApiModelProperty(value = "间隔天数")
+    @TableField("days")
+    private String days;
+
+    @ApiModelProperty(value = "触达渠道(email/sms/...)")
+    @TableField("type")
+    private String type;
+}

+ 6 - 2
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SopDetailUpdateDTO.java

@@ -17,12 +17,16 @@ public class SopDetailUpdateDTO implements Serializable {
     @ApiModelProperty(value = "明细ID(更新时必填,新增时为空)")
     private Long id;
 
+    @ApiModelProperty(value = "SOP id(变更所属SOP时使用,一般无需修改)")
+    @TableField("sop_id")
+    private Long sopId;
+
     @ApiModelProperty(value = "步骤序号")
     private Integer step;
 
     @ApiModelProperty(value = "步骤名称")
     private String name;
-    
+
     @ApiModelProperty(value = "邮件内容模板")
     @TableField("email_content")
     private String emailContent;
@@ -32,4 +36,4 @@ public class SopDetailUpdateDTO implements Serializable {
 
     @ApiModelProperty(value = "触达渠道")
     private String type;
-}
+}

+ 31 - 2
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/SopDetailService.java

@@ -1,10 +1,39 @@
 package com.storlead.trade.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.storlead.framework.common.result.Result;
+import com.storlead.trade.dto.SopDetailCreateDTO;
+import com.storlead.trade.dto.SopDetailDTO;
+import com.storlead.trade.dto.SopDetailResponseDTO;
+import com.storlead.trade.dto.SopDetailUpdateDTO;
 import com.storlead.trade.entity.SopDetailEntity;
 
+import java.util.List;
+
 /**
- * SOP明细 Service接口
+ * SOP明细 Service接口(直接对 sop_detail 表做增删改查)
+ *
+ * @author Generated
  */
 public interface SopDetailService extends IService<SopDetailEntity> {
-}
+
+    /**
+     * 分页查询 SOP 明细
+     */
+    Result<Object> getList(SopDetailDTO dto);
+
+    /**
+     * 新增 SOP 明细(sopId 必填)
+     */
+    Result<Object> add(SopDetailCreateDTO dto);
+
+    /**
+     * 更新 SOP 明细
+     */
+    Result<Object> edit(SopDetailUpdateDTO dto);
+
+    /**
+     * 删除 SOP 明细(单条/批量,逻辑删除)
+     */
+    Result<Object> delete(List<Long> ids);
+}

+ 11 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/MarketingCampaignServiceImpl.java

@@ -130,6 +130,16 @@ public class MarketingCampaignServiceImpl
         wrapper.eq(MarketingCampaignSopDetailEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
         List<MarketingCampaignSopDetailEntity> relationList = marketingCampaignSopDetailService.list(wrapper);
 
+        // 2. 查询关联的客户详情列表(通过中间表)
+        LambdaQueryWrapper<CustomerBaseEntity> customerBaseEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        customerBaseEntityLambdaQueryWrapper.eq(CustomerBaseEntity::getMarketingCampaignId, id);
+        customerBaseEntityLambdaQueryWrapper.eq(CustomerBaseEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
+        List<CustomerBaseEntity> customerBaseEntityList = customerBaseService.list(customerBaseEntityLambdaQueryWrapper);
+        //通过客户idList查询客户List
+        List<Long> customerIdList = customerBaseEntityList.stream().map(CustomerBaseEntity::getCustomerId).collect(Collectors.toList());
+        List<CustomerEntity> customerEntityList = customerTradeService.listByIds(customerIdList);
+
+
 //        List<SopDetailEntity> sopDetailList = Collections.emptyList();
 //        if (!CollectionUtils.isEmpty(relationList)) {
 //            List<Long> sopDetailIds = relationList.stream()
@@ -142,6 +152,7 @@ public class MarketingCampaignServiceImpl
         MarketingCampaignDetailVO detailVO = new MarketingCampaignDetailVO();
         detailVO.setCampaign(campaign);
         detailVO.setSopDetailList(relationList);
+        detailVO.setCustomerList(customerEntityList);
 
         return Result.result(detailVO);
     }

+ 150 - 1
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/SopDetailServiceImpl.java

@@ -1,16 +1,37 @@
 package com.storlead.trade.service.impl;
 
 import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.storlead.framework.common.constant.CommonConstant;
 import com.storlead.framework.common.constant.DSConstants;
+import com.storlead.framework.common.result.Result;
+import com.storlead.trade.dto.SopDetailCreateDTO;
+import com.storlead.trade.dto.SopDetailDTO;
+import com.storlead.trade.dto.SopDetailResponseDTO;
+import com.storlead.trade.dto.SopDetailUpdateDTO;
 import com.storlead.trade.entity.SopDetailEntity;
 import com.storlead.trade.mapper.SopDetailMapper;
 import com.storlead.trade.service.SopDetailService;
 import com.storlead.trade.service.impl.support.TradeDataSourceServiceImpl;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.ObjectUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 /**
  * SOP明细 Service实现类
+ * 直接对 sop_detail 表做增删改查(逻辑删除,软删 is_delete=1)
+ *
+ * @author Generated
  */
 @Slf4j
 @Service
@@ -18,4 +39,132 @@ import org.springframework.stereotype.Service;
 public class SopDetailServiceImpl
         extends TradeDataSourceServiceImpl<SopDetailMapper, SopDetailEntity>
         implements SopDetailService {
-}
+
+    @Override
+    public Result<Object> getList(SopDetailDTO dto) {
+        if (dto == null) {
+            dto = new SopDetailDTO();
+        }
+        Page<SopDetailEntity> page = new Page<>(dto.getPageIndex(), dto.getPageSize());
+        LambdaQueryWrapper<SopDetailEntity> wrapper = new LambdaQueryWrapper<>();
+        // 软删过滤
+        wrapper.eq(SopDetailEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
+        // 默认按 step 升序、再按 id 升序(步骤号稳定)
+        wrapper.orderByAsc(SopDetailEntity::getStep);
+        wrapper.orderByAsc(SopDetailEntity::getId);
+
+        if (!ObjectUtils.isEmpty(dto.getId())) {
+            wrapper.eq(SopDetailEntity::getId, dto.getId());
+        }
+        if (!ObjectUtils.isEmpty(dto.getSopId())) {
+            wrapper.eq(SopDetailEntity::getSopId, dto.getSopId());
+        }
+        if (!ObjectUtils.isEmpty(dto.getStep())) {
+            wrapper.eq(SopDetailEntity::getStep, dto.getStep());
+        }
+        if (dto.getName() != null && !dto.getName().trim().isEmpty()) {
+            wrapper.like(SopDetailEntity::getName, dto.getName().trim());
+        }
+        if (dto.getEmailContent() != null && !dto.getEmailContent().trim().isEmpty()) {
+            wrapper.like(SopDetailEntity::getEmailContent, dto.getEmailContent().trim());
+        }
+        if (dto.getDays() != null && !dto.getDays().trim().isEmpty()) {
+            wrapper.eq(SopDetailEntity::getDays, dto.getDays().trim());
+        }
+        if (dto.getType() != null && !dto.getType().trim().isEmpty()) {
+            wrapper.eq(SopDetailEntity::getType, dto.getType().trim());
+        }
+
+        IPage<SopDetailEntity> iPage = this.page(page, wrapper);
+        // 转响应 DTO
+        IPage<SopDetailResponseDTO> respPage = iPage.convert(this::toResponse);
+        return Result.result(respPage);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result<Object> add(SopDetailCreateDTO dto) {
+        if (dto == null) {
+            return Result.error("请求体不能为空");
+        }
+        SopDetailEntity entity = new SopDetailEntity();
+        // sopId 入参
+        entity.setSopId(dto.getSopId());
+        entity.setStep(dto.getStep());
+        entity.setName(dto.getName());
+        entity.setEmailContent(dto.getEmailContent());
+        entity.setDays(dto.getDays());
+        entity.setType(dto.getType());
+        boolean ok = this.save(entity);
+        if (!ok) {
+            return Result.error("新增 SOP 明细失败");
+        }
+        return Result.result(entity.getId());
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result<Object> edit(SopDetailUpdateDTO dto) {
+        if (dto == null || ObjectUtils.isEmpty(dto.getId())) {
+            return Result.error("id 不能为空");
+        }
+        SopDetailEntity exist = this.getById(dto.getId());
+        if (exist == null || CommonConstant.DEL_FLAG_1.equals(exist.getIsDelete())) {
+            return Result.error("明细不存在或已删除");
+        }
+        // 只更新非空字段,避免误清空
+        if (!ObjectUtils.isEmpty(dto.getStep())) {
+            exist.setStep(dto.getStep());
+        }
+        if (dto.getName() != null) {
+            exist.setName(dto.getName());
+        }
+        if (dto.getEmailContent() != null) {
+            exist.setEmailContent(dto.getEmailContent());
+        }
+        if (dto.getDays() != null) {
+            exist.setDays(dto.getDays());
+        }
+        if (dto.getType() != null) {
+            exist.setType(dto.getType());
+        }
+        // sopId 一般不修改(明细属于 SOP 主表),如需变更走 sopId 入参
+        if (dto.getSopId() != null) {
+            exist.setSopId(dto.getSopId());
+        }
+        boolean ok = this.updateById(exist);
+        if (!ok) {
+            return Result.error("更新 SOP 明细失败");
+        }
+        return Result.ok();
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result<Object> delete(List<Long> ids) {
+        if (CollectionUtils.isEmpty(ids)) {
+            return Result.error("id 列表不能为空");
+        }
+        // 软删:is_delete = 1
+        LambdaUpdateWrapper<SopDetailEntity> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.in(SopDetailEntity::getId, ids);
+        wrapper.set(SopDetailEntity::getIsDelete, CommonConstant.DEL_FLAG_1);
+        boolean ok = this.update(wrapper);
+        if (!ok) {
+            return Result.error("删除 SOP 明细失败");
+        }
+        return Result.ok();
+    }
+
+    /**
+     * Entity → ResponseDTO
+     */
+    private SopDetailResponseDTO toResponse(SopDetailEntity e) {
+        if (e == null) {
+            return null;
+        }
+        SopDetailResponseDTO r = new SopDetailResponseDTO();
+        BeanUtils.copyProperties(e, r);
+        return r;
+    }
+}

+ 4 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/vo/MarketingCampaignDetailVO.java

@@ -1,5 +1,6 @@
 package com.storlead.trade.vo;
 
+import com.storlead.trade.entity.CustomerEntity;
 import com.storlead.trade.entity.MarketingCampaignEntity;
 import com.storlead.trade.entity.MarketingCampaignSopDetailEntity;
 import com.storlead.trade.entity.SopDetailEntity;
@@ -18,4 +19,7 @@ public class MarketingCampaignDetailVO {
 
     @ApiModelProperty(value = "关联的SOP详情列表")
     private List<MarketingCampaignSopDetailEntity> sopDetailList;
+
+    @ApiModelProperty(value = "关联的客户详情列表")
+    private List<CustomerEntity> customerList;
 }