YPZ 1 hónapja
szülő
commit
dc6e6595b7
22 módosított fájl, 1070 hozzáadás és 11 törlés
  1. 1 1
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/controller/MarketEmailsController.java
  2. 2 5
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/controller/MarketingCampaignSopDetailController.java
  3. 111 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/controller/SysDictController.java
  4. 103 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/controller/SysDictDetailController.java
  5. 34 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SysDictCreateDTO.java
  6. 45 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SysDictDTO.java
  7. 34 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SysDictDetailCreateDTO.java
  8. 45 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SysDictDetailDTO.java
  9. 36 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SysDictDetailResponseDTO.java
  10. 33 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SysDictDetailUpdateDTO.java
  11. 36 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SysDictResponseDTO.java
  12. 34 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SysDictUpdateDTO.java
  13. 33 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/entity/SysDictDetailEntity.java
  14. 33 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/entity/SysDictEntity.java
  15. 12 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/mapper/TradeSysDictDetailMapper.java
  16. 12 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/mapper/TradeSysDictMapper.java
  17. 39 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/SysDictDetailService.java
  18. 41 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/SysDictService.java
  19. 3 2
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/MarketEmailsServiceImpl.java
  20. 20 3
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/MarketingCampaignSopDetailServiceImpl.java
  21. 154 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/SysDictDetailServiceImpl.java
  22. 209 0
      java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/SysDictServiceImpl.java

+ 1 - 1
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/controller/MarketEmailsController.java

@@ -52,7 +52,7 @@ public class MarketEmailsController {
     }
 
     @PostMapping("/cancel")
-    @ApiOperation("营销: 取消发送邮件(按 id 或 idList,status 置 -2)")
+    @ApiOperation("营销: 取消/重新发送邮件(按 id 或 idList,status 置 -2)")
     public Result<Object> cancel(@RequestBody MarketEmailsDTO marketEmailsDTO) {
         return marketEmailsService.cancel(marketEmailsDTO);
     }

+ 2 - 5
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/controller/MarketingCampaignSopDetailController.java

@@ -25,10 +25,7 @@ import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 /**
  * 营销活动SOP明细 Controller
@@ -159,7 +156,7 @@ public class MarketingCampaignSopDetailController {
             generated += generateEmailsForCustomer(customer, sopDetails, dto, baseTime, scheduleType);
         }
 
-        java.util.Map<String, Object> result = new java.util.HashMap<>();
+        Map<String, Object> result = new HashMap<>();
         result.put("scheduleType", scheduleType);
         result.put("customerCount", customers.size());
         result.put("sopStepCount", sopDetails.size());

+ 111 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/controller/SysDictController.java

@@ -0,0 +1,111 @@
+package com.storlead.trade.controller;
+
+import com.storlead.framework.common.result.Result;
+import com.storlead.trade.dto.SysDictCreateDTO;
+import com.storlead.trade.dto.SysDictDTO;
+import com.storlead.trade.dto.SysDictUpdateDTO;
+import com.storlead.trade.entity.SysDictEntity;
+import com.storlead.trade.service.SysDictService;
+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;
+
+/**
+ * 字典组(sys_dict)Controller
+ *
+ * @author Generated
+ */
+@Slf4j
+@RestController
+@RequestMapping("/sysDict")
+@Api(tags = "系统: 字典组")
+public class SysDictController {
+
+    @Resource
+    private SysDictService sysDictService;
+
+    /**
+     * 分页查询字典组
+     */
+    @PostMapping("/list")
+    @ApiOperation(value = "字典组分页查询", notes = "支持 code/name/description 筛选,name/description 模糊")
+    public Result<Object> list(@RequestBody SysDictDTO dto) {
+        return sysDictService.getList(dto);
+    }
+
+    /**
+     * 新增字典组
+     */
+    @PostMapping("/add")
+    @ApiOperation(value = "新增字典组", notes = "code、name 必填")
+    public Result<Object> add(@RequestBody SysDictCreateDTO dto) {
+        return sysDictService.add(dto);
+    }
+
+    /**
+     * 更新字典组
+     */
+    @PostMapping("/edit")
+    @ApiOperation(value = "更新字典组", notes = "dictId 必填,其余字段非空才更新")
+    public Result<Object> edit(@RequestBody SysDictUpdateDTO dto) {
+        return sysDictService.edit(dto);
+    }
+
+    /**
+     * 删除字典组(单条/批量,逻辑删除,级联删除明细)
+     */
+    @PostMapping("/delete")
+    @ApiOperation(value = "删除字典组", notes = "支持 dictId 单删或 idList 批量删(逻辑删除)")
+    public Result<Object> delete(@RequestBody SysDictDTO dto) {
+        if (dto == null) {
+            return Result.error("请求体不能为空");
+        }
+        List<Long> ids = new ArrayList<>();
+        if (!ObjectUtils.isEmpty(dto.getDictId())) {
+            ids.add(dto.getDictId());
+        }
+        if (!CollectionUtils.isEmpty(dto.getIdList())) {
+            ids.addAll(dto.getIdList());
+        }
+        if (ids.isEmpty()) {
+            return Result.error("dictId 或 idList 不能为空");
+        }
+        return sysDictService.delete(ids);
+    }
+
+    /**
+     * 字典组详情
+     */
+    @GetMapping("/getById")
+    @ApiOperation(value = "字典组详情")
+    public Result<Object> getById(Long dictId) {
+        if (ObjectUtils.isEmpty(dictId)) {
+            return Result.error("dictId 不能为空");
+        }
+        SysDictEntity entity = sysDictService.getById(dictId);
+        if (entity == null) {
+            return Result.error("字典组不存在");
+        }
+        return Result.result(entity);
+    }
+
+    /**
+     * 按字典 code 查询该组下全部可用明细(enabled=1 且未删除)
+     */
+    @GetMapping("/listByCode")
+    @ApiOperation(value = "按字典code查询全部可用明细", notes = "通过 code 定位字典组,返回其下 enabled=1 且未删除的全部 sys_dict_detail")
+    public Result<Object> listByCode(String code) {
+        return Result.ok(sysDictService.getListByCode(code));
+    }
+}

+ 103 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/controller/SysDictDetailController.java

@@ -0,0 +1,103 @@
+package com.storlead.trade.controller;
+
+import com.storlead.framework.common.result.Result;
+import com.storlead.trade.dto.SysDictDetailCreateDTO;
+import com.storlead.trade.dto.SysDictDetailDTO;
+import com.storlead.trade.dto.SysDictDetailUpdateDTO;
+import com.storlead.trade.entity.SysDictDetailEntity;
+import com.storlead.trade.service.SysDictDetailService;
+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;
+
+/**
+ * 字典明细(sys_dict_detail)Controller
+ * 通过 dict_id 关联 sys_dict 主表
+ *
+ * @author Generated
+ */
+@Slf4j
+@RestController
+@RequestMapping("/sysDictDetail")
+@Api(tags = "系统: 字典明细")
+public class SysDictDetailController {
+
+    @Resource
+    private SysDictDetailService sysDictDetailService;
+
+    /**
+     * 分页查询字典明细
+     */
+    @PostMapping("/list")
+    @ApiOperation(value = "字典明细分页查询", notes = "支持 dictId/label/value 筛选,label/value 模糊;dictId 用于按字典组查")
+    public Result<Object> list(@RequestBody SysDictDetailDTO dto) {
+        return sysDictDetailService.getList(dto);
+    }
+
+    /**
+     * 新增字典明细
+     */
+    @PostMapping("/add")
+    @ApiOperation(value = "新增字典明细", notes = "dictId、label、value 必填")
+    public Result<Object> add(@RequestBody SysDictDetailCreateDTO dto) {
+        return sysDictDetailService.add(dto);
+    }
+
+    /**
+     * 更新字典明细
+     */
+    @PostMapping("/edit")
+    @ApiOperation(value = "更新字典明细", notes = "dictDetailId 必填,其余字段非空才更新")
+    public Result<Object> edit(@RequestBody SysDictDetailUpdateDTO dto) {
+        return sysDictDetailService.edit(dto);
+    }
+
+    /**
+     * 删除字典明细(单条/批量,逻辑删除)
+     */
+    @PostMapping("/delete")
+    @ApiOperation(value = "删除字典明细", notes = "支持 dictDetailId 单删或 idList 批量删(逻辑删除)")
+    public Result<Object> delete(@RequestBody SysDictDetailDTO dto) {
+        if (dto == null) {
+            return Result.error("请求体不能为空");
+        }
+        List<Long> ids = new ArrayList<>();
+        if (!ObjectUtils.isEmpty(dto.getDictDetailId())) {
+            ids.add(dto.getDictDetailId());
+        }
+        if (!CollectionUtils.isEmpty(dto.getIdList())) {
+            ids.addAll(dto.getIdList());
+        }
+        if (ids.isEmpty()) {
+            return Result.error("dictDetailId 或 idList 不能为空");
+        }
+        return sysDictDetailService.delete(ids);
+    }
+
+    /**
+     * 字典明细详情
+     */
+    @GetMapping("/getById")
+    @ApiOperation(value = "字典明细详情")
+    public Result<Object> getById(Long dictDetailId) {
+        if (ObjectUtils.isEmpty(dictDetailId)) {
+            return Result.error("dictDetailId 不能为空");
+        }
+        SysDictDetailEntity entity = sysDictDetailService.getById(dictDetailId);
+        if (entity == null) {
+            return Result.error("字典明细不存在");
+        }
+        return Result.result(entity);
+    }
+}

+ 34 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SysDictCreateDTO.java

@@ -0,0 +1,34 @@
+package com.storlead.trade.dto;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * 字典组创建DTO
+ */
+@Data
+@ApiModel(value = "SysDictCreateDTO", description = "字典组创建请求")
+public class SysDictCreateDTO implements Serializable {
+
+    @ApiModelProperty(value = "字典code", required = true)
+    @NotNull(message = "字典code不能为空")
+    @TableField("code")
+    private String code;
+
+    @ApiModelProperty(value = "字典名称", required = true)
+    @NotNull(message = "字典名称不能为空")
+    private String name;
+
+    @ApiModelProperty(value = "描述")
+    @TableField("description")
+    private String description;
+
+    @ApiModelProperty(value = "显示顺序")
+    @TableField("sort")
+    private Integer sort;
+}

+ 45 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SysDictDTO.java

@@ -0,0 +1,45 @@
+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;
+
+/**
+ * 字典组分页查询 DTO
+ *
+ * @author Generated
+ */
+@Data
+@ApiModel(value = "SysDictDTO", description = "字典组分页查询请求")
+@TableName("sys_dict")
+public class SysDictDTO extends Page {
+
+    @ApiModelProperty(value = "字典组主键id")
+    @TableId
+    private Long dictId;
+
+    @ApiModelProperty(value = "id列表(批量操作用)")
+    private List<Long> idList;
+
+    @ApiModelProperty(value = "字典code(精确)")
+    @TableField("code")
+    private String code;
+
+    @ApiModelProperty(value = "字典名称(模糊)")
+    @TableField("name")
+    private String name;
+
+    @ApiModelProperty(value = "描述(模糊)")
+    @TableField("description")
+    private String description;
+
+    @ApiModelProperty(value = "是否启用(1启用 0禁用)")
+    @TableField("enabled")
+    private Boolean enabled;
+}

+ 34 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SysDictDetailCreateDTO.java

@@ -0,0 +1,34 @@
+package com.storlead.trade.dto;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * 字典明细创建DTO
+ */
+@Data
+@ApiModel(value = "SysDictDetailCreateDTO", description = "字典明细创建请求")
+public class SysDictDetailCreateDTO implements Serializable {
+
+    @ApiModelProperty(value = "字典组id", required = true)
+    @NotNull(message = "字典组id不能为空")
+    @TableField("dict_id")
+    private Long dictId;
+
+    @ApiModelProperty(value = "文本(label)", required = true)
+    @NotNull(message = "文本不能为空")
+    private String label;
+
+    @ApiModelProperty(value = "值(value)", required = true)
+    @NotNull(message = "值不能为空")
+    private String value;
+
+    @ApiModelProperty(value = "显示顺序")
+    @TableField("sort")
+    private Integer sort;
+}

+ 45 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SysDictDetailDTO.java

@@ -0,0 +1,45 @@
+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;
+
+/**
+ * 字典明细分页查询 DTO
+ *
+ * @author Generated
+ */
+@Data
+@ApiModel(value = "SysDictDetailDTO", description = "字典明细分页查询请求")
+@TableName("sys_dict_detail")
+public class SysDictDetailDTO extends Page {
+
+    @ApiModelProperty(value = "字典明细主键id")
+    @TableId
+    private Long dictDetailId;
+
+    @ApiModelProperty(value = "id列表(批量操作用)")
+    private List<Long> idList;
+
+    @ApiModelProperty(value = "字典组id(按所属字典组筛选)")
+    @TableField("dict_id")
+    private Long dictId;
+
+    @ApiModelProperty(value = "文本(label)(模糊)")
+    @TableField("label")
+    private String label;
+
+    @ApiModelProperty(value = "值(value)(模糊)")
+    @TableField("value")
+    private String value;
+
+    @ApiModelProperty(value = "是否启用(1启用 0禁用)")
+    @TableField("enabled")
+    private Boolean enabled;
+}

+ 36 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SysDictDetailResponseDTO.java

@@ -0,0 +1,36 @@
+package com.storlead.trade.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 字典明细响应DTO
+ */
+@Data
+@ApiModel(value = "SysDictDetailResponseDTO", description = "字典明细响应")
+public class SysDictDetailResponseDTO {
+
+    @ApiModelProperty(value = "字典明细主键id")
+    private Long dictDetailId;
+
+    @ApiModelProperty(value = "字典组id")
+    private Long dictId;
+
+    @ApiModelProperty(value = "文本(label)")
+    private String label;
+
+    @ApiModelProperty(value = "值(value)")
+    private String value;
+
+    @ApiModelProperty(value = "是否启用(1启用 0禁用)")
+    private Boolean enabled;
+
+    @ApiModelProperty(value = "显示顺序")
+    private Integer sort;
+
+    @ApiModelProperty(value = "创建时间")
+    private LocalDateTime createTime;
+}

+ 33 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SysDictDetailUpdateDTO.java

@@ -0,0 +1,33 @@
+package com.storlead.trade.dto;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 字典明细更新DTO
+ */
+@Data
+@ApiModel(value = "SysDictDetailUpdateDTO", description = "字典明细更新请求")
+public class SysDictDetailUpdateDTO implements Serializable {
+
+    @ApiModelProperty(value = "字典明细ID(更新时必填)")
+    private Long dictDetailId;
+
+    @ApiModelProperty(value = "字典组id")
+    @TableField("dict_id")
+    private Long dictId;
+
+    @ApiModelProperty(value = "文本(label)")
+    private String label;
+
+    @ApiModelProperty(value = "值(value)")
+    private String value;
+
+    @ApiModelProperty(value = "显示顺序")
+    @TableField("sort")
+    private Integer sort;
+}

+ 36 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SysDictResponseDTO.java

@@ -0,0 +1,36 @@
+package com.storlead.trade.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 字典组响应DTO
+ */
+@Data
+@ApiModel(value = "SysDictResponseDTO", description = "字典组响应")
+public class SysDictResponseDTO {
+
+    @ApiModelProperty(value = "字典组主键id")
+    private Long dictId;
+
+    @ApiModelProperty(value = "字典code")
+    private String code;
+
+    @ApiModelProperty(value = "字典名称")
+    private String name;
+
+    @ApiModelProperty(value = "描述")
+    private String description;
+
+    @ApiModelProperty(value = "是否启用(1启用 0禁用)")
+    private Boolean enabled;
+
+    @ApiModelProperty(value = "显示顺序")
+    private Integer sort;
+
+    @ApiModelProperty(value = "创建时间")
+    private LocalDateTime createTime;
+}

+ 34 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/dto/SysDictUpdateDTO.java

@@ -0,0 +1,34 @@
+package com.storlead.trade.dto;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 字典组更新DTO
+ */
+@Data
+@ApiModel(value = "SysDictUpdateDTO", description = "字典组更新请求")
+public class SysDictUpdateDTO implements Serializable {
+
+    @ApiModelProperty(value = "字典组ID(更新时必填)")
+    private Long dictId;
+
+    @ApiModelProperty(value = "字典code")
+    @TableField("code")
+    private String code;
+
+    @ApiModelProperty(value = "字典名称")
+    private String name;
+
+    @ApiModelProperty(value = "描述")
+    @TableField("description")
+    private String description;
+
+    @ApiModelProperty(value = "显示顺序")
+    @TableField("sort")
+    private Integer sort;
+}

+ 33 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/entity/SysDictDetailEntity.java

@@ -0,0 +1,33 @@
+package com.storlead.trade.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.storlead.framework.mybatis.entity.SysBaseField;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 字典明细(sys_dict_detail)
+ */
+@Data
+@TableName("sys_dict_detail")
+public class SysDictDetailEntity extends SysBaseField {
+
+    @ApiModelProperty(value = "字典明细主键id")
+    @TableId(value = "dict_detail_id", type = IdType.AUTO)
+    private Long dictDetailId;
+
+    @ApiModelProperty(value = "字典组id")
+    @TableField("dict_id")
+    private Long dictId;
+
+    @ApiModelProperty(value = "文本(label)")
+    @TableField("label")
+    private String label;
+
+    @ApiModelProperty(value = "值(value)")
+    @TableField("value")
+    private String value;
+}

+ 33 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/entity/SysDictEntity.java

@@ -0,0 +1,33 @@
+package com.storlead.trade.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.storlead.framework.mybatis.entity.SysBaseField;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 字典组(sys_dict)
+ */
+@Data
+@TableName("sys_dict")
+public class SysDictEntity extends SysBaseField {
+
+    @ApiModelProperty(value = "字典组主键id")
+    @TableId(value = "dict_id", type = IdType.AUTO)
+    private Long dictId;
+
+    @ApiModelProperty(value = "字典code")
+    @TableField("code")
+    private String code;
+
+    @ApiModelProperty(value = "字典名称")
+    @TableField("name")
+    private String name;
+
+    @ApiModelProperty(value = "描述")
+    @TableField("description")
+    private String description;
+}

+ 12 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/mapper/TradeSysDictDetailMapper.java

@@ -0,0 +1,12 @@
+package com.storlead.trade.mapper;
+
+import com.storlead.trade.entity.SysDictDetailEntity;
+import com.storlead.trade.mapper.support.TradeBaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 字典明细 Mapper接口
+ */
+@Mapper
+public interface TradeSysDictDetailMapper extends TradeBaseMapper<SysDictDetailEntity> {
+}

+ 12 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/mapper/TradeSysDictMapper.java

@@ -0,0 +1,12 @@
+package com.storlead.trade.mapper;
+
+import com.storlead.trade.entity.SysDictEntity;
+import com.storlead.trade.mapper.support.TradeBaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 字典组 Mapper接口
+ */
+@Mapper
+public interface TradeSysDictMapper extends TradeBaseMapper<SysDictEntity> {
+}

+ 39 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/SysDictDetailService.java

@@ -0,0 +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.SysDictDetailCreateDTO;
+import com.storlead.trade.dto.SysDictDetailDTO;
+import com.storlead.trade.dto.SysDictDetailResponseDTO;
+import com.storlead.trade.dto.SysDictDetailUpdateDTO;
+import com.storlead.trade.entity.SysDictDetailEntity;
+
+import java.util.List;
+
+/**
+ * 字典明细 Service接口
+ *
+ * @author Generated
+ */
+public interface SysDictDetailService extends IService<SysDictDetailEntity> {
+
+    /**
+     * 分页查询字典明细(支持按 dictId/label/value 筛选)
+     */
+    Result<Object> getList(SysDictDetailDTO dto);
+
+    /**
+     * 新增字典明细(dictId、label、value 必填)
+     */
+    Result<Object> add(SysDictDetailCreateDTO dto);
+
+    /**
+     * 更新字典明细
+     */
+    Result<Object> edit(SysDictDetailUpdateDTO dto);
+
+    /**
+     * 删除字典明细(单条/批量,逻辑删除)
+     */
+    Result<Object> delete(List<Long> ids);
+}

+ 41 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/SysDictService.java

@@ -0,0 +1,41 @@
+package com.storlead.trade.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.storlead.framework.common.result.Result;
+import com.storlead.trade.dto.*;
+import com.storlead.trade.entity.SysDictEntity;
+
+import java.util.List;
+
+/**
+ * 字典组 Service接口
+ *
+ * @author Generated
+ */
+public interface SysDictService extends IService<SysDictEntity> {
+
+    /**
+     * 分页查询字典组
+     */
+    Result<Object> getList(SysDictDTO dto);
+
+    /**
+     * 新增字典组(code、name 必填)
+     */
+    Result<Object> add(SysDictCreateDTO dto);
+
+    /**
+     * 更新字典组
+     */
+    Result<Object> edit(SysDictUpdateDTO dto);
+
+    /**
+     * 删除字典组(单条/批量,逻辑删除,级联删除明细)
+     */
+    Result<Object> delete(List<Long> ids);
+
+    /**
+     * 按字典 code 查询该组下全部可用(enabled=1 且未删除)的明细
+     */
+    List<SysDictDetailResponseDTO> getListByCode(String code);
+}

+ 3 - 2
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/MarketEmailsServiceImpl.java

@@ -353,10 +353,11 @@ public class MarketEmailsServiceImpl extends MyBaseServiceImpl<MarketEmailsMappe
         wrapper.in(MarketEmailsEntity::getId, ids);
         wrapper.eq(MarketEmailsEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
         // status = -3 表示取消发送
-        wrapper.set(MarketEmailsEntity::getStatus, -3);
+//        wrapper.set(MarketEmailsEntity::getStatus, -3);
+        wrapper.set(MarketEmailsEntity::getStatus, dto.getStatus());
         boolean ok = this.update(wrapper);
         if (!ok) {
-            return Result.error("取消发送失败");
+            return Result.error("操作失败");
         }
         return Result.ok();
     }

+ 20 - 3
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/MarketingCampaignSopDetailServiceImpl.java

@@ -10,18 +10,19 @@ import com.storlead.mail.pojo.entity.MktMailMessageEntity;
 import com.storlead.mail.service.MktMailMessageService;
 import com.storlead.trade.dto.CustomerDTO;
 import com.storlead.trade.dto.MarketingCampaignSopDetailDTO;
+import com.storlead.trade.dto.SysDictDetailResponseDTO;
 import com.storlead.trade.entity.CustomerEntity;
 import com.storlead.trade.entity.MarketEmailsEntity;
 import com.storlead.trade.entity.MarketingCampaignSopDetailEntity;
+import com.storlead.trade.entity.SysDictDetailEntity;
 import com.storlead.trade.mapper.MarketingCampaignSopDetailMapper;
-import com.storlead.trade.service.CustomerTradeService;
-import com.storlead.trade.service.MarketEmailsService;
-import com.storlead.trade.service.MarketingCampaignSopDetailService;
+import com.storlead.trade.service.*;
 import com.storlead.trade.service.impl.support.TradeDataSourceServiceImpl;
 import com.storlead.trade.vo.CustomerVO;
 import org.springframework.beans.BeanUtils;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 import org.springframework.util.ObjectUtils;
 
 import javax.annotation.Resource;
@@ -43,6 +44,9 @@ public class MarketingCampaignSopDetailServiceImpl
     private CustomerTradeService customerService;
     @Resource
     private MktMailMessageService mktMailMessageService;
+    @Resource
+    private SysDictService sysDictService;
+
 
     @Override
     public Result<?> editMarketingCampaignSopDetail(MarketingCampaignSopDetailDTO dto) {
@@ -83,6 +87,19 @@ public class MarketingCampaignSopDetailServiceImpl
 
 
 //        List<CustomerEntity> customerEntityList = customerService.listByIds(customerIdList);
+        //查询本地信息
+        String yourName = "";
+        String yourTitle = "";
+        String yourCompany = "";
+        String yourPhone = "";
+        String yourEmail = "";
+        String fullCompanyAddress = "";
+        List<SysDictDetailResponseDTO> sysDictDetailResponseDTOList = sysDictService.getListByCode("company_base");
+        if (!CollectionUtils.isEmpty(sysDictDetailResponseDTOList)){
+
+        }
+
+
         Map<Long,CustomerVO> customerEntityMap = customerVOList.stream().collect(Collectors.toMap(CustomerVO::getId, customerVO -> customerVO));
         for (MarketEmailsEntity marketEmailsEntity : marketEmailsEntityList) {
             CustomerVO customerEntity = customerEntityMap.get(marketEmailsEntity.getCustomerId());

+ 154 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/SysDictDetailServiceImpl.java

@@ -0,0 +1,154 @@
+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.SysDictDetailCreateDTO;
+import com.storlead.trade.dto.SysDictDetailDTO;
+import com.storlead.trade.dto.SysDictDetailResponseDTO;
+import com.storlead.trade.dto.SysDictDetailUpdateDTO;
+import com.storlead.trade.entity.SysDictDetailEntity;
+import com.storlead.trade.mapper.TradeSysDictDetailMapper;
+import com.storlead.trade.service.SysDictDetailService;
+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.List;
+
+/**
+ * 字典明细 Service实现类
+ * 直接对 sys_dict_detail 表做增删改查(逻辑删除,软删 is_delete=1)
+ * 通过 dict_id 关联 sys_dict 主表
+ *
+ * @author Generated
+ */
+@Slf4j
+@Service("tradeSysDictDetailService")
+@DS(DSConstants.DATASOURCE_TRADE)
+public class SysDictDetailServiceImpl
+        extends TradeDataSourceServiceImpl<TradeSysDictDetailMapper, SysDictDetailEntity>
+        implements SysDictDetailService {
+
+    @Override
+    public Result<Object> getList(SysDictDetailDTO dto) {
+        if (dto == null) {
+            dto = new SysDictDetailDTO();
+        }
+        Page<SysDictDetailEntity> page = new Page<>(dto.getPageIndex(), dto.getPageSize());
+        LambdaQueryWrapper<SysDictDetailEntity> wrapper = new LambdaQueryWrapper<>();
+        // 软删过滤
+        wrapper.eq(SysDictDetailEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
+        // 默认按 sort 升序、再按 dictDetailId 降序(顺序稳定)
+        wrapper.orderByAsc(SysDictDetailEntity::getSort);
+        wrapper.orderByDesc(SysDictDetailEntity::getDictDetailId);
+
+        if (!ObjectUtils.isEmpty(dto.getDictDetailId())) {
+            wrapper.eq(SysDictDetailEntity::getDictDetailId, dto.getDictDetailId());
+        }
+        if (!ObjectUtils.isEmpty(dto.getDictId())) {
+            wrapper.eq(SysDictDetailEntity::getDictId, dto.getDictId());
+        }
+        if (dto.getLabel() != null && !dto.getLabel().trim().isEmpty()) {
+            wrapper.like(SysDictDetailEntity::getLabel, dto.getLabel().trim());
+        }
+        if (dto.getValue() != null && !dto.getValue().trim().isEmpty()) {
+            wrapper.like(SysDictDetailEntity::getValue, dto.getValue().trim());
+        }
+        if (dto.getEnabled() != null) {
+            wrapper.eq(SysDictDetailEntity::getEnabled, dto.getEnabled());
+        }
+
+        IPage<SysDictDetailEntity> iPage = this.page(page, wrapper);
+        // 转响应 DTO
+        IPage<SysDictDetailResponseDTO> respPage = iPage.convert(this::toResponse);
+        return Result.result(respPage);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result<Object> add(SysDictDetailCreateDTO dto) {
+        if (dto == null) {
+            return Result.error("请求体不能为空");
+        }
+        SysDictDetailEntity entity = new SysDictDetailEntity();
+        entity.setDictId(dto.getDictId());
+        entity.setLabel(dto.getLabel());
+        entity.setValue(dto.getValue());
+        entity.setSort(dto.getSort());
+        boolean ok = this.save(entity);
+        if (!ok) {
+            return Result.error("新增字典明细失败");
+        }
+        return Result.result(entity.getDictDetailId());
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result<Object> edit(SysDictDetailUpdateDTO dto) {
+        if (dto == null || ObjectUtils.isEmpty(dto.getDictDetailId())) {
+            return Result.error("dictDetailId 不能为空");
+        }
+        SysDictDetailEntity exist = this.getById(dto.getDictDetailId());
+        if (exist == null || CommonConstant.DEL_FLAG_1.equals(exist.getIsDelete())) {
+            return Result.error("字典明细不存在或已删除");
+        }
+        // 只更新非空字段,避免误清空
+        if (!ObjectUtils.isEmpty(dto.getDictId())) {
+            exist.setDictId(dto.getDictId());
+        }
+        if (dto.getLabel() != null) {
+            exist.setLabel(dto.getLabel());
+        }
+        if (dto.getValue() != null) {
+            exist.setValue(dto.getValue());
+        }
+        if (dto.getSort() != null) {
+            exist.setSort(dto.getSort());
+        }
+        boolean ok = this.updateById(exist);
+        if (!ok) {
+            return Result.error("更新字典明细失败");
+        }
+        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<SysDictDetailEntity> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.in(SysDictDetailEntity::getDictDetailId, ids);
+        wrapper.set(SysDictDetailEntity::getIsDelete, CommonConstant.DEL_FLAG_1);
+        boolean ok = this.update(wrapper);
+        if (!ok) {
+            return Result.error("删除字典明细失败");
+        }
+        return Result.ok();
+    }
+
+    /**
+     * Entity → ResponseDTO
+     */
+    private SysDictDetailResponseDTO toResponse(SysDictDetailEntity e) {
+        if (e == null) {
+            return null;
+        }
+        SysDictDetailResponseDTO r = new SysDictDetailResponseDTO();
+        BeanUtils.copyProperties(e, r);
+        return r;
+    }
+}

+ 209 - 0
java/storlead-sasa/storlead-trade/src/main/java/com/storlead/trade/service/impl/SysDictServiceImpl.java

@@ -0,0 +1,209 @@
+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.SysDictCreateDTO;
+import com.storlead.trade.dto.SysDictDTO;
+import com.storlead.trade.dto.SysDictResponseDTO;
+import com.storlead.trade.dto.SysDictDetailResponseDTO;
+import com.storlead.trade.dto.SysDictUpdateDTO;
+import com.storlead.trade.entity.SysDictDetailEntity;
+import com.storlead.trade.entity.SysDictEntity;
+import com.storlead.trade.mapper.TradeSysDictDetailMapper;
+import com.storlead.trade.mapper.TradeSysDictMapper;
+import com.storlead.trade.service.SysDictDetailService;
+import com.storlead.trade.service.SysDictService;
+import com.storlead.trade.service.impl.support.TradeDataSourceServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.ObjectUtils;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 字典组 Service实现类
+ * 直接对 sys_dict 表做增删改查(逻辑删除,软删 is_delete=1;删除时级联软删明细)
+ *
+ * @author Generated
+ */
+@Slf4j
+@Service("tradeSysDictService")
+@DS(DSConstants.DATASOURCE_TRADE)
+public class SysDictServiceImpl
+        extends TradeDataSourceServiceImpl<TradeSysDictMapper, SysDictEntity>
+        implements SysDictService {
+
+    @Resource
+    @Lazy
+    private SysDictDetailService sysDictDetailService;
+
+    @Resource
+    @Lazy
+    private TradeSysDictDetailMapper tradeSysDictDetailMapper;
+
+    @Override
+    public Result<Object> getList(SysDictDTO dto) {
+        if (dto == null) {
+            dto = new SysDictDTO();
+        }
+        Page<SysDictEntity> page = new Page<>(dto.getPageIndex(), dto.getPageSize());
+        LambdaQueryWrapper<SysDictEntity> wrapper = new LambdaQueryWrapper<>();
+        // 软删过滤
+        wrapper.eq(SysDictEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
+        // 默认按 sort 升序、再按 dictId 降序(顺序稳定)
+        wrapper.orderByAsc(SysDictEntity::getSort);
+        wrapper.orderByDesc(SysDictEntity::getDictId);
+
+        if (!ObjectUtils.isEmpty(dto.getDictId())) {
+            wrapper.eq(SysDictEntity::getDictId, dto.getDictId());
+        }
+        if (dto.getCode() != null && !dto.getCode().trim().isEmpty()) {
+            wrapper.eq(SysDictEntity::getCode, dto.getCode().trim());
+        }
+        if (dto.getName() != null && !dto.getName().trim().isEmpty()) {
+            wrapper.like(SysDictEntity::getName, dto.getName().trim());
+        }
+        if (dto.getDescription() != null && !dto.getDescription().trim().isEmpty()) {
+            wrapper.like(SysDictEntity::getDescription, dto.getDescription().trim());
+        }
+        if (dto.getEnabled() != null) {
+            wrapper.eq(SysDictEntity::getEnabled, dto.getEnabled());
+        }
+
+        IPage<SysDictEntity> iPage = this.page(page, wrapper);
+        // 转响应 DTO
+        IPage<SysDictResponseDTO> respPage = iPage.convert(this::toResponse);
+        return Result.result(respPage);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result<Object> add(SysDictCreateDTO dto) {
+        if (dto == null) {
+            return Result.error("请求体不能为空");
+        }
+        SysDictEntity entity = new SysDictEntity();
+        entity.setCode(dto.getCode());
+        entity.setName(dto.getName());
+        entity.setDescription(dto.getDescription());
+        entity.setSort(dto.getSort());
+        boolean ok = this.save(entity);
+        if (!ok) {
+            return Result.error("新增字典组失败");
+        }
+        return Result.result(entity.getDictId());
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result<Object> edit(SysDictUpdateDTO dto) {
+        if (dto == null || ObjectUtils.isEmpty(dto.getDictId())) {
+            return Result.error("dictId 不能为空");
+        }
+        SysDictEntity exist = this.getById(dto.getDictId());
+        if (exist == null || CommonConstant.DEL_FLAG_1.equals(exist.getIsDelete())) {
+            return Result.error("字典组不存在或已删除");
+        }
+        // 只更新非空字段,避免误清空
+        if (dto.getCode() != null) {
+            exist.setCode(dto.getCode());
+        }
+        if (dto.getName() != null) {
+            exist.setName(dto.getName());
+        }
+        if (dto.getDescription() != null) {
+            exist.setDescription(dto.getDescription());
+        }
+        if (dto.getSort() != null) {
+            exist.setSort(dto.getSort());
+        }
+        boolean ok = this.updateById(exist);
+        if (!ok) {
+            return Result.error("更新字典组失败");
+        }
+        return Result.ok();
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result<Object> delete(List<Long> ids) {
+        if (CollectionUtils.isEmpty(ids)) {
+            return Result.error("id 列表不能为空");
+        }
+        // 软删主表
+        LambdaUpdateWrapper<SysDictEntity> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.in(SysDictEntity::getDictId, ids);
+        wrapper.set(SysDictEntity::getIsDelete, CommonConstant.DEL_FLAG_1);
+        boolean ok = this.update(wrapper);
+        if (!ok) {
+            return Result.error("删除字典组失败");
+        }
+        // 级联软删从表(sys_dict_detail 同组明细一并逻辑删除)
+        LambdaUpdateWrapper<SysDictDetailEntity> detailWrapper = new LambdaUpdateWrapper<>();
+        detailWrapper.in(SysDictDetailEntity::getDictId, ids);
+        detailWrapper.set(SysDictDetailEntity::getIsDelete, CommonConstant.DEL_FLAG_1);
+        sysDictDetailService.update(detailWrapper);
+        return Result.ok();
+    }
+
+    @Override
+    public List<SysDictDetailResponseDTO> getListByCode(String code) {
+        List<SysDictDetailResponseDTO> resp = new ArrayList<>();
+        if (code == null || code.trim().isEmpty()) {
+            return resp;
+        }
+        // 1. 主表按 code 定位字典组(取启用且未删除的最早一条)
+        LambdaQueryWrapper<SysDictEntity> dictWrapper = new LambdaQueryWrapper<>();
+        dictWrapper.eq(SysDictEntity::getCode, code.trim());
+        dictWrapper.eq(SysDictEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
+        dictWrapper.eq(SysDictEntity::getEnabled, true);
+        dictWrapper.orderByAsc(SysDictEntity::getDictId);
+        dictWrapper.last("LIMIT 1");
+        SysDictEntity dict = this.getOne(dictWrapper);
+        if (dict == null) {
+            return resp;
+        }
+        // 2. 从表查该组下全部可用明细(enabled=1 且未删除),按 sort 升序
+        LambdaQueryWrapper<SysDictDetailEntity> detailWrapper = new LambdaQueryWrapper<>();
+        detailWrapper.eq(SysDictDetailEntity::getDictId, dict.getDictId());
+        detailWrapper.eq(SysDictDetailEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
+        detailWrapper.eq(SysDictDetailEntity::getEnabled, true);
+        detailWrapper.orderByAsc(SysDictDetailEntity::getSort);
+        detailWrapper.orderByDesc(SysDictDetailEntity::getDictDetailId);
+        List<SysDictDetailEntity> details = sysDictDetailService.list(detailWrapper);
+        resp = details.stream().map(e -> {
+            if (e == null) {
+                return null;
+            }
+            SysDictDetailResponseDTO r = new SysDictDetailResponseDTO();
+            BeanUtils.copyProperties(e, r);
+            return r;
+        }).collect(Collectors.toList());
+        return resp;
+    }
+
+    /**
+     * Entity → ResponseDTO
+     */
+    private SysDictResponseDTO toResponse(SysDictEntity e) {
+        if (e == null) {
+            return null;
+        }
+        SysDictResponseDTO r = new SysDictResponseDTO();
+        BeanUtils.copyProperties(e, r);
+        return r;
+    }
+}