mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 18:49:06 +08:00 
			
		
		
		
	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
This commit is contained in:
		| @ -2,10 +2,10 @@ package cn.iocoder.yudao.module.crm.controller.admin.clue; | |||||||
|  |  | ||||||
| import cn.iocoder.yudao.framework.common.pojo.CommonResult; | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
|  | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||||||
| import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | ||||||
| import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | ||||||
| import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.*; | import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.*; | ||||||
| import cn.iocoder.yudao.module.crm.convert.clue.CrmClueConvert; |  | ||||||
| import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; | import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; | ||||||
| import cn.iocoder.yudao.module.crm.service.clue.CrmClueService; | import cn.iocoder.yudao.module.crm.service.clue.CrmClueService; | ||||||
| import io.swagger.v3.oas.annotations.Operation; | import io.swagger.v3.oas.annotations.Operation; | ||||||
| @ -65,7 +65,7 @@ public class CrmClueController { | |||||||
|     @PreAuthorize("@ss.hasPermission('crm:clue:query')") |     @PreAuthorize("@ss.hasPermission('crm:clue:query')") | ||||||
|     public CommonResult<CrmClueRespVO> getClue(@RequestParam("id") Long id) { |     public CommonResult<CrmClueRespVO> getClue(@RequestParam("id") Long id) { | ||||||
|         CrmClueDO clue = clueService.getClue(id); |         CrmClueDO clue = clueService.getClue(id); | ||||||
|         return success(CrmClueConvert.INSTANCE.convert(clue)); |         return success(BeanUtils.toBean(clue, CrmClueRespVO.class)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @GetMapping("/page") |     @GetMapping("/page") | ||||||
| @ -73,7 +73,7 @@ public class CrmClueController { | |||||||
|     @PreAuthorize("@ss.hasPermission('crm:clue:query')") |     @PreAuthorize("@ss.hasPermission('crm:clue:query')") | ||||||
|     public CommonResult<PageResult<CrmClueRespVO>> getCluePage(@Valid CrmCluePageReqVO pageVO) { |     public CommonResult<PageResult<CrmClueRespVO>> getCluePage(@Valid CrmCluePageReqVO pageVO) { | ||||||
|         PageResult<CrmClueDO> pageResult = clueService.getCluePage(pageVO, getLoginUserId()); |         PageResult<CrmClueDO> pageResult = clueService.getCluePage(pageVO, getLoginUserId()); | ||||||
|         return success(CrmClueConvert.INSTANCE.convertPage(pageResult)); |         return success(BeanUtils.toBean(pageResult, CrmClueRespVO.class)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @GetMapping("/export-excel") |     @GetMapping("/export-excel") | ||||||
| @ -84,7 +84,7 @@ public class CrmClueController { | |||||||
|         pageReqVO.setPageSize(PAGE_SIZE_NONE); |         pageReqVO.setPageSize(PAGE_SIZE_NONE); | ||||||
|         List<CrmClueDO> list = clueService.getCluePage(pageReqVO, getLoginUserId()).getList(); |         List<CrmClueDO> list = clueService.getCluePage(pageReqVO, getLoginUserId()).getList(); | ||||||
|         // 导出 Excel |         // 导出 Excel | ||||||
|         List<CrmClueExcelVO> datas = CrmClueConvert.INSTANCE.convertList02(list); |         List<CrmClueExcelVO> datas = BeanUtils.toBean(list, CrmClueExcelVO.class); | ||||||
|         ExcelUtils.write(response, "线索.xls", "数据", CrmClueExcelVO.class, datas); |         ExcelUtils.write(response, "线索.xls", "数据", CrmClueExcelVO.class, datas); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -99,9 +99,8 @@ public class CrmClueController { | |||||||
|     @PostMapping("/transform") |     @PostMapping("/transform") | ||||||
|     @Operation(summary = "线索转化为客户") |     @Operation(summary = "线索转化为客户") | ||||||
|     @PreAuthorize("@ss.hasPermission('crm:clue:update')") |     @PreAuthorize("@ss.hasPermission('crm:clue:update')") | ||||||
|     // TODO @min:方法改成 translateCustomer |     public CommonResult<Boolean> translateCustomer(@Valid @RequestBody CrmClueTransformReqVO reqVO) { | ||||||
|     public CommonResult<Boolean> translate(@Valid @RequestBody CrmClueTransformReqVO reqVO) { |         clueService.translateCustomer(reqVO, getLoginUserId()); | ||||||
|         clueService.translate(reqVO, getLoginUserId()); |  | ||||||
|         return success(Boolean.TRUE); |         return success(Boolean.TRUE); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -22,10 +22,6 @@ public class CrmClueSaveReqVO { | |||||||
|     @NotEmpty(message = "线索名称不能为空") |     @NotEmpty(message = "线索名称不能为空") | ||||||
|     private String name; |     private String name; | ||||||
|  |  | ||||||
|     // TODO @min:是不是不传递 customerId? |  | ||||||
|     @Schema(description = "客户 id", example = "520") |  | ||||||
|     private Long customerId; |  | ||||||
|  |  | ||||||
|     @Schema(description = "下次联系时间", example = "2023-10-18 01:00:00") |     @Schema(description = "下次联系时间", example = "2023-10-18 01:00:00") | ||||||
|     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||||||
|     private LocalDateTime contactNextTime; |     private LocalDateTime contactNextTime; | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ import java.util.Set; | |||||||
| public class CrmClueTransformReqVO { | public class CrmClueTransformReqVO { | ||||||
|  |  | ||||||
|     @Schema(description = "线索编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1024, 1025]") |     @Schema(description = "线索编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1024, 1025]") | ||||||
|     @NotEmpty(message = "线索编号不能为空") Set<Long> ids; // TODO @min:应该空行噢 |     @NotEmpty(message = "线索编号不能为空") | ||||||
|  |     private Set<Long> ids; | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,18 +1,11 @@ | |||||||
| package cn.iocoder.yudao.module.crm.convert.clue; | package cn.iocoder.yudao.module.crm.convert.clue; | ||||||
|  |  | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; |  | ||||||
| import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueExcelVO; |  | ||||||
| import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueRespVO; |  | ||||||
| import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueSaveReqVO; |  | ||||||
| import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO; | import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO; | ||||||
| import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; |  | ||||||
| import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; | import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; | ||||||
| import org.mapstruct.Mapper; | import org.mapstruct.Mapper; | ||||||
| import org.mapstruct.Mapping; | import org.mapstruct.Mapping; | ||||||
| import org.mapstruct.factory.Mappers; | import org.mapstruct.factory.Mappers; | ||||||
|  |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 线索 Convert |  * 线索 Convert | ||||||
|  * |  * | ||||||
| @ -23,15 +16,6 @@ public interface CrmClueConvert { | |||||||
|  |  | ||||||
|     CrmClueConvert INSTANCE = Mappers.getMapper(CrmClueConvert.class); |     CrmClueConvert INSTANCE = Mappers.getMapper(CrmClueConvert.class); | ||||||
|  |  | ||||||
|     // TODO @min:这几个 convert,都使用 BeanUtils 替代哈 |  | ||||||
|     CrmClueDO convert(CrmClueSaveReqVO bean); |  | ||||||
|  |  | ||||||
|     CrmClueRespVO convert(CrmClueDO bean); |  | ||||||
|  |  | ||||||
|     PageResult<CrmClueRespVO> convertPage(PageResult<CrmClueDO> page); |  | ||||||
|  |  | ||||||
|     List<CrmClueExcelVO> convertList02(List<CrmClueDO> list); |  | ||||||
|  |  | ||||||
|     @Mapping(target = "bizId", source = "reqVO.id") |     @Mapping(target = "bizId", source = "reqVO.id") | ||||||
|     CrmPermissionTransferReqBO convert(CrmClueTransferReqVO reqVO, Long userId); |     CrmPermissionTransferReqBO convert(CrmClueTransferReqVO reqVO, Long userId); | ||||||
|  |  | ||||||
|  | |||||||
| @ -79,6 +79,6 @@ public interface CrmClueService { | |||||||
|      * @param reqVO  线索编号 |      * @param reqVO  线索编号 | ||||||
|      * @param userId 用户编号 |      * @param userId 用户编号 | ||||||
|      */ |      */ | ||||||
|     void translate(CrmClueTransformReqVO reqVO, Long userId); |     void translateCustomer(CrmClueTransformReqVO reqVO, Long userId); | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.service.clue; | |||||||
|  |  | ||||||
| import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||||
| import cn.hutool.core.collection.ListUtil; | import cn.hutool.core.collection.ListUtil; | ||||||
|  | import cn.hutool.core.util.ObjectUtil; | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
| import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||||||
| import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO; | import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO; | ||||||
| @ -29,7 +30,6 @@ import java.util.Objects; | |||||||
|  |  | ||||||
| import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||||||
| import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CLUE_NOT_EXISTS; | import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CLUE_NOT_EXISTS; | ||||||
| import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CUSTOMER_NOT_EXISTS; |  | ||||||
| import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS; | import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @ -60,7 +60,7 @@ public class CrmClueServiceImpl implements CrmClueService { | |||||||
|         validateRelationDataExists(createReqVO); |         validateRelationDataExists(createReqVO); | ||||||
|  |  | ||||||
|         // 插入 |         // 插入 | ||||||
|         CrmClueDO clue = CrmClueConvert.INSTANCE.convert(createReqVO); |         CrmClueDO clue = BeanUtils.toBean(createReqVO, CrmClueDO.class); | ||||||
|         clueMapper.insert(clue); |         clueMapper.insert(clue); | ||||||
|         // 返回 |         // 返回 | ||||||
|         return clue.getId(); |         return clue.getId(); | ||||||
| @ -75,7 +75,7 @@ public class CrmClueServiceImpl implements CrmClueService { | |||||||
|         validateRelationDataExists(updateReqVO); |         validateRelationDataExists(updateReqVO); | ||||||
|  |  | ||||||
|         // 更新 |         // 更新 | ||||||
|         CrmClueDO updateObj = CrmClueConvert.INSTANCE.convert(updateReqVO); |         CrmClueDO updateObj = BeanUtils.toBean(updateReqVO, CrmClueDO.class); | ||||||
|         clueMapper.updateById(updateObj); |         clueMapper.updateById(updateObj); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -130,7 +130,7 @@ public class CrmClueServiceImpl implements CrmClueService { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void translate(CrmClueTransformReqVO reqVO, Long userId) { |     public void translateCustomer(CrmClueTransformReqVO reqVO, Long userId) { | ||||||
|         // 校验线索都存在 |         // 校验线索都存在 | ||||||
|         List<CrmClueDO> clues = getClueList(reqVO.getIds(), userId); |         List<CrmClueDO> clues = getClueList(reqVO.getIds(), userId); | ||||||
|         if (CollUtil.isEmpty(clues)) { |         if (CollUtil.isEmpty(clues)) { | ||||||
| @ -138,29 +138,25 @@ public class CrmClueServiceImpl implements CrmClueService { | |||||||
|         } |         } | ||||||
|         // TODO @min:如果已经转化,则不能重复转化 |         // TODO @min:如果已经转化,则不能重复转化 | ||||||
|  |  | ||||||
|         // 遍历线索,创建对应的客户 |         // 遍历线索(过滤掉已转化的线索),创建对应的客户 | ||||||
|         clues.forEach(clue -> { |         clues.stream().filter(clue -> ObjectUtil.notEqual(Boolean.TRUE, clue.getTransformStatus())) | ||||||
|             clue.setId(null); |                 .forEach(clue -> { | ||||||
|             // 创建客户 |                     // 1.创建客户 | ||||||
|             // TODO @puhui999:上面的 id 置空,适合 bean copy 后,在设置为 null,不直接修改 clu 哈 |                     CrmCustomerSaveReqVO customerSaveReqVO = BeanUtils.toBean(clue, CrmCustomerSaveReqVO.class) | ||||||
|             customerService.createCustomer(BeanUtils.toBean(clue, CrmCustomerSaveReqVO.class), userId); |                             .setId(null); | ||||||
|             // 更新线索状态 |                     Long customerId = customerService.createCustomer(customerSaveReqVO, userId); | ||||||
|             // TODO @min:新建一个 CrmClueDO 去更新。尽量规避直接用原本的对象去更新。因为这样万一并发更新,会存在覆盖的问题。 |  | ||||||
|             // TODO @min:customerId 没有更新进去 |  | ||||||
|                     // TODO @puhui999:如果有跟进记录,需要一起转过去; |                     // TODO @puhui999:如果有跟进记录,需要一起转过去; | ||||||
|             clue.setTransformStatus(Boolean.TRUE); |                     // 2.更新线索,新建一个 CrmClueDO 去更新。尽量规避直接用原本的对象去更新。因为这样万一并发更新,会存在覆盖的问题。 | ||||||
|             clueMapper.updateById(clue); |                     clueMapper.updateById(BeanUtils.toBean(clue, CrmClueDO.class) | ||||||
|  |                             // 线索状态设置为已转化 | ||||||
|  |                             .setTransformStatus(Boolean.TRUE) | ||||||
|  |                             // 设置关联的客户编号 | ||||||
|  |                             .setCustomerId(customerId)); | ||||||
|                 }); |                 }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void validateRelationDataExists(CrmClueSaveReqVO reqVO) { |     private void validateRelationDataExists(CrmClueSaveReqVO reqVO) { | ||||||
|         // 校验客户 |  | ||||||
|         if (Objects.nonNull(reqVO.getCustomerId()) && |  | ||||||
|                 Objects.isNull(customerService.getCustomer(reqVO.getCustomerId()))) { |  | ||||||
|             throw exception(CUSTOMER_NOT_EXISTS); |  | ||||||
|         } |  | ||||||
|         // 校验负责人 |         // 校验负责人 | ||||||
|         // 2. 校验负责人 |  | ||||||
|         if (Objects.nonNull(reqVO.getOwnerUserId()) && |         if (Objects.nonNull(reqVO.getOwnerUserId()) && | ||||||
|                 Objects.isNull(adminUserApi.getUser(reqVO.getOwnerUserId()))) { |                 Objects.isNull(adminUserApi.getUser(reqVO.getOwnerUserId()))) { | ||||||
|             throw exception(USER_NOT_EXISTS); |             throw exception(USER_NOT_EXISTS); | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV