Commit 8d2008f2b5bc02d59b40f410f28a7222254e64d9

Authored by YunaiV
2 parents 6891b75e 0ee7fede

Merge branch 'develop' of https://gitee.com/Minh-X/ruoyi-vue-pro into develop

# Conflicts:
#	yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/customer/CrmCustomerConvert.java
#	yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java
@@ -2,10 +2,10 @@ package cn.iocoder.yudao.module.crm.controller.admin.clue; @@ -2,10 +2,10 @@ package cn.iocoder.yudao.module.crm.controller.admin.clue;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 6 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
6 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 7 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
7 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.*; 8 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.*;
8 -import cn.iocoder.yudao.module.crm.convert.clue.CrmClueConvert;  
9 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; 9 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;
10 import cn.iocoder.yudao.module.crm.service.clue.CrmClueService; 10 import cn.iocoder.yudao.module.crm.service.clue.CrmClueService;
11 import io.swagger.v3.oas.annotations.Operation; 11 import io.swagger.v3.oas.annotations.Operation;
@@ -65,7 +65,7 @@ public class CrmClueController { @@ -65,7 +65,7 @@ public class CrmClueController {
65 @PreAuthorize("@ss.hasPermission('crm:clue:query')") 65 @PreAuthorize("@ss.hasPermission('crm:clue:query')")
66 public CommonResult<CrmClueRespVO> getClue(@RequestParam("id") Long id) { 66 public CommonResult<CrmClueRespVO> getClue(@RequestParam("id") Long id) {
67 CrmClueDO clue = clueService.getClue(id); 67 CrmClueDO clue = clueService.getClue(id);
68 - return success(CrmClueConvert.INSTANCE.convert(clue)); 68 + return success(BeanUtils.toBean(clue, CrmClueRespVO.class));
69 } 69 }
70 70
71 @GetMapping("/page") 71 @GetMapping("/page")
@@ -73,7 +73,7 @@ public class CrmClueController { @@ -73,7 +73,7 @@ public class CrmClueController {
73 @PreAuthorize("@ss.hasPermission('crm:clue:query')") 73 @PreAuthorize("@ss.hasPermission('crm:clue:query')")
74 public CommonResult<PageResult<CrmClueRespVO>> getCluePage(@Valid CrmCluePageReqVO pageVO) { 74 public CommonResult<PageResult<CrmClueRespVO>> getCluePage(@Valid CrmCluePageReqVO pageVO) {
75 PageResult<CrmClueDO> pageResult = clueService.getCluePage(pageVO, getLoginUserId()); 75 PageResult<CrmClueDO> pageResult = clueService.getCluePage(pageVO, getLoginUserId());
76 - return success(CrmClueConvert.INSTANCE.convertPage(pageResult)); 76 + return success(BeanUtils.toBean(pageResult, CrmClueRespVO.class));
77 } 77 }
78 78
79 @GetMapping("/export-excel") 79 @GetMapping("/export-excel")
@@ -84,7 +84,7 @@ public class CrmClueController { @@ -84,7 +84,7 @@ public class CrmClueController {
84 pageReqVO.setPageSize(PAGE_SIZE_NONE); 84 pageReqVO.setPageSize(PAGE_SIZE_NONE);
85 List<CrmClueDO> list = clueService.getCluePage(pageReqVO, getLoginUserId()).getList(); 85 List<CrmClueDO> list = clueService.getCluePage(pageReqVO, getLoginUserId()).getList();
86 // 导出 Excel 86 // 导出 Excel
87 - List<CrmClueExcelVO> datas = CrmClueConvert.INSTANCE.convertList02(list); 87 + List<CrmClueExcelVO> datas = BeanUtils.toBean(list, CrmClueExcelVO.class);
88 ExcelUtils.write(response, "线索.xls", "数据", CrmClueExcelVO.class, datas); 88 ExcelUtils.write(response, "线索.xls", "数据", CrmClueExcelVO.class, datas);
89 } 89 }
90 90
@@ -99,9 +99,8 @@ public class CrmClueController { @@ -99,9 +99,8 @@ public class CrmClueController {
99 @PostMapping("/transform") 99 @PostMapping("/transform")
100 @Operation(summary = "线索转化为客户") 100 @Operation(summary = "线索转化为客户")
101 @PreAuthorize("@ss.hasPermission('crm:clue:update')") 101 @PreAuthorize("@ss.hasPermission('crm:clue:update')")
102 - // TODO @min:方法改成 translateCustomer  
103 - public CommonResult<Boolean> translate(@Valid @RequestBody CrmClueTransformReqVO reqVO) {  
104 - clueService.translate(reqVO, getLoginUserId()); 102 + public CommonResult<Boolean> translateCustomer(@Valid @RequestBody CrmClueTransformReqVO reqVO) {
  103 + clueService.translateCustomer(reqVO, getLoginUserId());
105 return success(Boolean.TRUE); 104 return success(Boolean.TRUE);
106 } 105 }
107 106
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueSaveReqVO.java
@@ -22,10 +22,6 @@ public class CrmClueSaveReqVO { @@ -22,10 +22,6 @@ public class CrmClueSaveReqVO {
22 @NotEmpty(message = "线索名称不能为空") 22 @NotEmpty(message = "线索名称不能为空")
23 private String name; 23 private String name;
24 24
25 - // TODO @min:是不是不传递 customerId?  
26 - @Schema(description = "客户 id", example = "520")  
27 - private Long customerId;  
28 -  
29 @Schema(description = "下次联系时间", example = "2023-10-18 01:00:00") 25 @Schema(description = "下次联系时间", example = "2023-10-18 01:00:00")
30 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 26 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
31 private LocalDateTime contactNextTime; 27 private LocalDateTime contactNextTime;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueTransformReqVO.java
@@ -11,6 +11,7 @@ import java.util.Set; @@ -11,6 +11,7 @@ import java.util.Set;
11 public class CrmClueTransformReqVO { 11 public class CrmClueTransformReqVO {
12 12
13 @Schema(description = "线索编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1024, 1025]") 13 @Schema(description = "线索编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1024, 1025]")
14 - @NotEmpty(message = "线索编号不能为空") Set<Long> ids; // TODO @min:应该空行噢 14 + @NotEmpty(message = "线索编号不能为空")
  15 + private Set<Long> ids;
15 16
16 } 17 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/clue/CrmClueConvert.java
1 package cn.iocoder.yudao.module.crm.convert.clue; 1 package cn.iocoder.yudao.module.crm.convert.clue;
2 2
3 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
4 -import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueExcelVO;  
5 -import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueRespVO;  
6 -import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueSaveReqVO;  
7 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO; 3 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO;
8 -import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;  
9 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; 4 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
10 import org.mapstruct.Mapper; 5 import org.mapstruct.Mapper;
11 import org.mapstruct.Mapping; 6 import org.mapstruct.Mapping;
12 import org.mapstruct.factory.Mappers; 7 import org.mapstruct.factory.Mappers;
13 8
14 -import java.util.List;  
15 -  
16 /** 9 /**
17 * 线索 Convert 10 * 线索 Convert
18 * 11 *
@@ -23,15 +16,6 @@ public interface CrmClueConvert { @@ -23,15 +16,6 @@ public interface CrmClueConvert {
23 16
24 CrmClueConvert INSTANCE = Mappers.getMapper(CrmClueConvert.class); 17 CrmClueConvert INSTANCE = Mappers.getMapper(CrmClueConvert.class);
25 18
26 - // TODO @min:这几个 convert,都使用 BeanUtils 替代哈  
27 - CrmClueDO convert(CrmClueSaveReqVO bean);  
28 -  
29 - CrmClueRespVO convert(CrmClueDO bean);  
30 -  
31 - PageResult<CrmClueRespVO> convertPage(PageResult<CrmClueDO> page);  
32 -  
33 - List<CrmClueExcelVO> convertList02(List<CrmClueDO> list);  
34 -  
35 @Mapping(target = "bizId", source = "reqVO.id") 19 @Mapping(target = "bizId", source = "reqVO.id")
36 CrmPermissionTransferReqBO convert(CrmClueTransferReqVO reqVO, Long userId); 20 CrmPermissionTransferReqBO convert(CrmClueTransferReqVO reqVO, Long userId);
37 21
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java
@@ -79,6 +79,6 @@ public interface CrmClueService { @@ -79,6 +79,6 @@ public interface CrmClueService {
79 * @param reqVO 线索编号 79 * @param reqVO 线索编号
80 * @param userId 用户编号 80 * @param userId 用户编号
81 */ 81 */
82 - void translate(CrmClueTransformReqVO reqVO, Long userId); 82 + void translateCustomer(CrmClueTransformReqVO reqVO, Long userId);
83 83
84 } 84 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.service.clue; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.service.clue;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.collection.ListUtil; 4 import cn.hutool.core.collection.ListUtil;
  5 +import cn.hutool.core.util.ObjectUtil;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO; 8 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO;
@@ -29,7 +30,6 @@ import java.util.Objects; @@ -29,7 +30,6 @@ import java.util.Objects;
29 30
30 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 31 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
31 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CLUE_NOT_EXISTS; 32 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CLUE_NOT_EXISTS;
32 -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CUSTOMER_NOT_EXISTS;  
33 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS; 33 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS;
34 34
35 /** 35 /**
@@ -60,7 +60,7 @@ public class CrmClueServiceImpl implements CrmClueService { @@ -60,7 +60,7 @@ public class CrmClueServiceImpl implements CrmClueService {
60 validateRelationDataExists(createReqVO); 60 validateRelationDataExists(createReqVO);
61 61
62 // 插入 62 // 插入
63 - CrmClueDO clue = CrmClueConvert.INSTANCE.convert(createReqVO); 63 + CrmClueDO clue = BeanUtils.toBean(createReqVO, CrmClueDO.class);
64 clueMapper.insert(clue); 64 clueMapper.insert(clue);
65 // 返回 65 // 返回
66 return clue.getId(); 66 return clue.getId();
@@ -75,7 +75,7 @@ public class CrmClueServiceImpl implements CrmClueService { @@ -75,7 +75,7 @@ public class CrmClueServiceImpl implements CrmClueService {
75 validateRelationDataExists(updateReqVO); 75 validateRelationDataExists(updateReqVO);
76 76
77 // 更新 77 // 更新
78 - CrmClueDO updateObj = CrmClueConvert.INSTANCE.convert(updateReqVO); 78 + CrmClueDO updateObj = BeanUtils.toBean(updateReqVO, CrmClueDO.class);
79 clueMapper.updateById(updateObj); 79 clueMapper.updateById(updateObj);
80 } 80 }
81 81
@@ -130,7 +130,7 @@ public class CrmClueServiceImpl implements CrmClueService { @@ -130,7 +130,7 @@ public class CrmClueServiceImpl implements CrmClueService {
130 130
131 @Override 131 @Override
132 @Transactional(rollbackFor = Exception.class) 132 @Transactional(rollbackFor = Exception.class)
133 - public void translate(CrmClueTransformReqVO reqVO, Long userId) { 133 + public void translateCustomer(CrmClueTransformReqVO reqVO, Long userId) {
134 // 校验线索都存在 134 // 校验线索都存在
135 List<CrmClueDO> clues = getClueList(reqVO.getIds(), userId); 135 List<CrmClueDO> clues = getClueList(reqVO.getIds(), userId);
136 if (CollUtil.isEmpty(clues)) { 136 if (CollUtil.isEmpty(clues)) {
@@ -138,29 +138,25 @@ public class CrmClueServiceImpl implements CrmClueService { @@ -138,29 +138,25 @@ public class CrmClueServiceImpl implements CrmClueService {
138 } 138 }
139 // TODO @min:如果已经转化,则不能重复转化 139 // TODO @min:如果已经转化,则不能重复转化
140 140
141 - // 遍历线索,创建对应的客户  
142 - clues.forEach(clue -> {  
143 - clue.setId(null);  
144 - // 创建客户  
145 - // TODO @puhui999:上面的 id 置空,适合 bean copy 后,在设置为 null,不直接修改 clu 哈  
146 - customerService.createCustomer(BeanUtils.toBean(clue, CrmCustomerSaveReqVO.class), userId);  
147 - // 更新线索状态  
148 - // TODO @min:新建一个 CrmClueDO 去更新。尽量规避直接用原本的对象去更新。因为这样万一并发更新,会存在覆盖的问题。  
149 - // TODO @min:customerId 没有更新进去  
150 - // TODO @puhui999:如果有跟进记录,需要一起转过去;  
151 - clue.setTransformStatus(Boolean.TRUE);  
152 - clueMapper.updateById(clue);  
153 - }); 141 + // 遍历线索(过滤掉已转化的线索),创建对应的客户
  142 + clues.stream().filter(clue -> ObjectUtil.notEqual(Boolean.TRUE, clue.getTransformStatus()))
  143 + .forEach(clue -> {
  144 + // 1.创建客户
  145 + CrmCustomerSaveReqVO customerSaveReqVO = BeanUtils.toBean(clue, CrmCustomerSaveReqVO.class)
  146 + .setId(null);
  147 + Long customerId = customerService.createCustomer(customerSaveReqVO, userId);
  148 + // TODO @puhui999:如果有跟进记录,需要一起转过去;
  149 + // 2.更新线索,新建一个 CrmClueDO 去更新。尽量规避直接用原本的对象去更新。因为这样万一并发更新,会存在覆盖的问题。
  150 + clueMapper.updateById(BeanUtils.toBean(clue, CrmClueDO.class)
  151 + // 线索状态设置为已转化
  152 + .setTransformStatus(Boolean.TRUE)
  153 + // 设置关联的客户编号
  154 + .setCustomerId(customerId));
  155 + });
154 } 156 }
155 157
156 private void validateRelationDataExists(CrmClueSaveReqVO reqVO) { 158 private void validateRelationDataExists(CrmClueSaveReqVO reqVO) {
157 - // 校验客户  
158 - if (Objects.nonNull(reqVO.getCustomerId()) &&  
159 - Objects.isNull(customerService.getCustomer(reqVO.getCustomerId()))) {  
160 - throw exception(CUSTOMER_NOT_EXISTS);  
161 - }  
162 // 校验负责人 159 // 校验负责人
163 - // 2. 校验负责人  
164 if (Objects.nonNull(reqVO.getOwnerUserId()) && 160 if (Objects.nonNull(reqVO.getOwnerUserId()) &&
165 Objects.isNull(adminUserApi.getUser(reqVO.getOwnerUserId()))) { 161 Objects.isNull(adminUserApi.getUser(reqVO.getOwnerUserId()))) {
166 throw exception(USER_NOT_EXISTS); 162 throw exception(USER_NOT_EXISTS);