Browse Source

CRM: 线索、联系人、回款、回款计划新增数据权限转移

puhui999 1 year ago
parent
commit
8fa8f2890b
24 changed files with 274 additions and 46 deletions
  1. 2 3
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java
  2. 8 0
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java
  3. 31 0
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueTransferReqVO.java
  4. 12 4
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java
  5. 4 4
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
  6. 2 3
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerTransferReqVO.java
  7. 9 4
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java
  8. 9 4
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java
  9. 31 0
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanTransferReqVO.java
  10. 31 0
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableTransferReqVO.java
  11. 9 5
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/clue/CrmClueConvert.java
  12. 2 2
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java
  13. 2 2
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java
  14. 6 0
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivableConvert.java
  15. 6 0
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivablePlanConvert.java
  16. 9 0
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java
  17. 15 0
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java
  18. 9 0
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java
  19. 18 7
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java
  20. 4 4
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
  21. 9 0
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanService.java
  22. 15 0
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java
  23. 9 0
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java
  24. 22 4
      yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java

+ 2 - 3
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java

@@ -2,16 +2,15 @@ package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
 
 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
 import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
 import jakarta.validation.constraints.NotNull;
+import lombok.Data;
 
 @Schema(description = "管理后台 - 商机转移 Request VO")
 @Data
 public class CrmBusinessTransferReqVO {
 
     @Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
-    @NotNull(message = "联系人编号不能为空")
+    @NotNull(message = "商机编号不能为空")
     private Long id;
 
     /**

+ 8 - 0
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java

@@ -88,4 +88,12 @@ public class CrmClueController {
         ExcelUtils.write(response, "线索.xls", "数据", CrmClueExcelVO.class, datas);
     }
 
+    @PutMapping("/transfer")
+    @Operation(summary = "线索转移")
+    @PreAuthorize("@ss.hasPermission('crm:clue:update')")
+    public CommonResult<Boolean> transfer(@Valid @RequestBody CrmClueTransferReqVO reqVO) {
+        clueService.transferClue(reqVO, getLoginUserId());
+        return success(true);
+    }
+
 }

+ 31 - 0
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueTransferReqVO.java

@@ -0,0 +1,31 @@
+package cn.iocoder.yudao.module.crm.controller.admin.clue.vo;
+
+import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Schema(description = "管理后台 - 线索转移 Request VO")
+@Data
+public class CrmClueTransferReqVO {
+
+    @Schema(description = "线索编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
+    @NotNull(message = "线索编号不能为空")
+    private Long id;
+
+    /**
+     * 新负责人的用户编号
+     */
+    @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
+    @NotNull(message = "新负责人的用户编号不能为空")
+    private Long newOwnerUserId;
+
+    /**
+     * 老负责人加入团队后的权限级别。如果 null 说明移除
+     *
+     * 关联 {@link CrmPermissionLevelEnum}
+     */
+    @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
+    private Integer oldOwnerPermissionLevel;
+
+}

+ 12 - 4
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java

@@ -9,7 +9,7 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*;
-import cn.iocoder.yudao.module.crm.convert.contact.ContactConvert;
+import cn.iocoder.yudao.module.crm.convert.contact.CrmContactConvert;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
 import cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants;
@@ -100,7 +100,7 @@ public class CrmContactController {
         // 3. 直属上级
         List<CrmContactDO> parentContactList = contactService.getContactList(
                 Collections.singletonList(contact.getParentId()), getLoginUserId());
-        return success(ContactConvert.INSTANCE.convert(contact, userMap, customerList, parentContactList));
+        return success(CrmContactConvert.INSTANCE.convert(contact, userMap, customerList, parentContactList));
     }
 
     @GetMapping("/simple-all-list")
@@ -110,7 +110,7 @@ public class CrmContactController {
         CrmContactPageReqVO pageReqVO = new CrmContactPageReqVO();
         pageReqVO.setPageSize(PAGE_SIZE_NONE);
         List<CrmContactDO> list = contactService.getContactPage(pageReqVO, getLoginUserId()).getList();
-        return success(ContactConvert.INSTANCE.convertAllList(list));
+        return success(CrmContactConvert.INSTANCE.convertAllList(list));
     }
 
     @GetMapping("/page")
@@ -161,7 +161,15 @@ public class CrmContactController {
         // 3. 直属上级
         List<CrmContactDO> parentContactList = contactService.getContactList(
                 convertSet(contactList, CrmContactDO::getParentId), getLoginUserId());
-        return ContactConvert.INSTANCE.convertPage(pageResult, userMap, crmCustomerDOList, parentContactList);
+        return CrmContactConvert.INSTANCE.convertPage(pageResult, userMap, crmCustomerDOList, parentContactList);
+    }
+
+    @PutMapping("/transfer")
+    @Operation(summary = "联系人转移")
+    @PreAuthorize("@ss.hasPermission('crm:contact:update')")
+    public CommonResult<Boolean> transfer(@Valid @RequestBody CrmContactTransferReqVO reqVO) {
+        contactService.transferContact(reqVO, getLoginUserId());
+        return success(true);
     }
 
 }

+ 4 - 4
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java

@@ -8,7 +8,7 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*;
-import cn.iocoder.yudao.module.crm.convert.contract.ContractConvert;
+import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
 import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
@@ -80,7 +80,7 @@ public class CrmContractController {
     @PreAuthorize("@ss.hasPermission('crm:contract:query')")
     public CommonResult<ContractRespVO> getContract(@RequestParam("id") Long id) {
         CrmContractDO contract = contractService.getContract(id);
-        return success(ContractConvert.INSTANCE.convert(contract));
+        return success(CrmContractConvert.INSTANCE.convert(contract));
     }
 
     @GetMapping("/page")
@@ -108,7 +108,7 @@ public class CrmContractController {
         PageResult<CrmContractDO> pageResult = contractService.getContractPage(exportReqVO, getLoginUserId());
         // 导出 Excel
         ExcelUtils.write(response, "合同.xls", "数据", CrmContractExcelVO.class,
-                ContractConvert.INSTANCE.convertList02(pageResult.getList()));
+                CrmContractConvert.INSTANCE.convertList02(pageResult.getList()));
     }
 
     /**
@@ -128,7 +128,7 @@ public class CrmContractController {
         // 2. 获取创建人、负责人列表
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList,
                 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
-        return ContractConvert.INSTANCE.convertPage(pageResult, userMap, customerList);
+        return CrmContractConvert.INSTANCE.convertPage(pageResult, userMap, customerList);
     }
 
     @PutMapping("/transfer")

+ 2 - 3
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerTransferReqVO.java

@@ -2,16 +2,15 @@ package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
 
 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
 import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
 import jakarta.validation.constraints.NotNull;
+import lombok.Data;
 
 @Schema(description = "管理后台 - CRM 客户转移 Request VO")
 @Data
 public class CrmCustomerTransferReqVO {
 
     @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
-    @NotNull(message = "联系人编号不能为空")
+    @NotNull(message = "客户编号不能为空")
     private Long id;
 
     /**

+ 9 - 4
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java

@@ -7,10 +7,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
-import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableCreateReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO;
+import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.*;
 import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivableConvert;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
@@ -144,4 +141,12 @@ public class CrmReceivableController {
         return CrmReceivableConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList);
     }
 
+    @PutMapping("/transfer")
+    @Operation(summary = "回款转移")
+    @PreAuthorize("@ss.hasPermission('crm:receivable:update')")
+    public CommonResult<Boolean> transfer(@Valid @RequestBody CrmReceivableTransferReqVO reqVO) {
+        receivableService.transferReceivable(reqVO, getLoginUserId());
+        return success(true);
+    }
+
 }

+ 9 - 4
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java

@@ -7,10 +7,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
-import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanCreateReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanRespVO;
-import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanUpdateReqVO;
+import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.*;
 import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivablePlanConvert;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
@@ -151,4 +148,12 @@ public class CrmReceivablePlanController {
         return CrmReceivablePlanConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList, receivableList);
     }
 
+    @PutMapping("/transfer")
+    @Operation(summary = "回款计划转移")
+    @PreAuthorize("@ss.hasPermission('crm:receivable-plan:update')")
+    public CommonResult<Boolean> transfer(@Valid @RequestBody CrmReceivablePlanTransferReqVO reqVO) {
+        receivablePlanService.transferReceivablePlan(reqVO, getLoginUserId());
+        return success(true);
+    }
+
 }

+ 31 - 0
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanTransferReqVO.java

@@ -0,0 +1,31 @@
+package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan;
+
+import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Schema(description = "管理后台 - CRM 回款计划转移 Request VO")
+@Data
+public class CrmReceivablePlanTransferReqVO {
+
+    @Schema(description = "回款计划编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
+    @NotNull(message = "回款计划编号不能为空")
+    private Long id;
+
+    /**
+     * 新负责人的用户编号
+     */
+    @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
+    @NotNull(message = "新负责人的用户编号不能为空")
+    private Long newOwnerUserId;
+
+    /**
+     * 老负责人加入团队后的权限级别。如果 null 说明移除
+     *
+     * 关联 {@link CrmPermissionLevelEnum}
+     */
+    @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
+    private Integer oldOwnerPermissionLevel;
+
+}

+ 31 - 0
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableTransferReqVO.java

@@ -0,0 +1,31 @@
+package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable;
+
+import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+@Schema(description = "管理后台 - CRM 回款转移 Request VO")
+@Data
+public class CrmReceivableTransferReqVO {
+
+    @Schema(description = "回款编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
+    @NotNull(message = "回款编号不能为空")
+    private Long id;
+
+    /**
+     * 新负责人的用户编号
+     */
+    @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
+    @NotNull(message = "新负责人的用户编号不能为空")
+    private Long newOwnerUserId;
+
+    /**
+     * 老负责人加入团队后的权限级别。如果 null 说明移除
+     *
+     * 关联 {@link CrmPermissionLevelEnum}
+     */
+    @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
+    private Integer oldOwnerPermissionLevel;
+
+}

+ 9 - 5
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/clue/CrmClueConvert.java

@@ -1,13 +1,14 @@
 package cn.iocoder.yudao.module.crm.convert.clue;
 
-import java.util.*;
-
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-
-import org.mapstruct.Mapper;
-import org.mapstruct.factory.Mappers;
 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.*;
 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;
+import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
 
 /**
  * 线索 Convert
@@ -29,4 +30,7 @@ public interface CrmClueConvert {
 
     List<CrmClueExcelVO> convertList02(List<CrmClueDO> list);
 
+    @Mapping(target = "bizId", source = "reqVO.id")
+    CrmPermissionTransferReqBO convert(CrmClueTransferReqVO reqVO, Long userId);
+
 }

+ 2 - 2
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/ContactConvert.java → yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java

@@ -25,9 +25,9 @@ import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAnd
  * @author 芋道源码
  */
 @Mapper
-public interface ContactConvert {
+public interface CrmContactConvert {
 
-    ContactConvert INSTANCE = Mappers.getMapper(ContactConvert.class);
+    CrmContactConvert INSTANCE = Mappers.getMapper(CrmContactConvert.class);
 
     CrmContactDO convert(CrmContactCreateReqVO bean);
 

+ 2 - 2
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/ContractConvert.java → yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java

@@ -22,9 +22,9 @@ import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAnd
  * @author dhb52
  */
 @Mapper
-public interface ContractConvert {
+public interface CrmContractConvert {
 
-    ContractConvert INSTANCE = Mappers.getMapper(ContractConvert.class);
+    CrmContractConvert INSTANCE = Mappers.getMapper(CrmContractConvert.class);
 
     CrmContractDO convert(CrmContractCreateReqVO bean);
 

+ 6 - 0
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivableConvert.java

@@ -3,12 +3,15 @@ package cn.iocoder.yudao.module.crm.convert.receivable;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableCreateReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
+import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableTransferReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
+import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
 import org.mapstruct.factory.Mappers;
 
 import java.util.List;
@@ -58,4 +61,7 @@ public interface CrmReceivableConvert {
         findAndThen(userMap, Long.parseLong(receivable.getCreator()), user -> receivable.setCreatorName(user.getNickname()));
     }
 
+    @Mapping(target = "bizId", source = "reqVO.id")
+    CrmPermissionTransferReqBO convert(CrmReceivableTransferReqVO reqVO, Long userId);
+
 }

+ 6 - 0
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivablePlanConvert.java

@@ -3,13 +3,16 @@ package cn.iocoder.yudao.module.crm.convert.receivable;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanCreateReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanRespVO;
+import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanTransferReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanUpdateReqVO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO;
+import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
 import org.mapstruct.factory.Mappers;
 
 import java.util.List;
@@ -63,4 +66,7 @@ public interface CrmReceivablePlanConvert {
         findAndThen(userMap, Long.parseLong(receivablePlan.getCreator()), user -> receivablePlan.setCreatorName(user.getNickname()));
     }
 
+    @Mapping(target = "bizId", source = "reqVO.id")
+    CrmPermissionTransferReqBO convert(CrmReceivablePlanTransferReqVO reqVO, Long userId);
+
 }

+ 9 - 0
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.service.clue;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueCreateReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO;
+import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueUpdateReqVO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;
 import jakarta.validation.Valid;
@@ -64,4 +65,12 @@ public interface CrmClueService {
      */
     PageResult<CrmClueDO> getCluePage(CrmCluePageReqVO pageReqVO, Long userId);
 
+    /**
+     * 线索转移
+     *
+     * @param reqVO  请求
+     * @param userId 用户编号
+     */
+    void transferClue(CrmClueTransferReqVO reqVO, Long userId);
+
 }

+ 15 - 0
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java

@@ -5,6 +5,7 @@ import cn.hutool.core.collection.ListUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueCreateReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO;
+import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueUpdateReqVO;
 import cn.iocoder.yudao.module.crm.convert.clue.CrmClueConvert;
 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;
@@ -101,4 +102,18 @@ public class CrmClueServiceImpl implements CrmClueService {
         return clueMapper.selectPage(pageReqVO, userId);
     }
 
+    @Override
+    public void transferClue(CrmClueTransferReqVO reqVO, Long userId) {
+        // 1 校验线索是否存在
+        validateClueExists(reqVO.getId());
+
+        // 2.1 数据权限转移
+        crmPermissionService.transferPermission(
+                CrmClueConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_LEADS.getType()));
+        // 2.2 设置新的负责人
+        clueMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
+
+        // 3. TODO 记录转移日志
+    }
+
 }

+ 9 - 0
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.service.contact;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactCreateReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO;
+import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactTransferReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactUpdateReqVO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
@@ -79,4 +80,12 @@ public interface CrmContactService {
      */
     PageResult<CrmContactDO> getContactPageByCustomerId(CrmContactPageReqVO pageVO);
 
+    /**
+     * 联系人转移
+     *
+     * @param reqVO  请求
+     * @param userId 用户编号
+     */
+    void transferContact(CrmContactTransferReqVO reqVO, Long userId);
+
 }

+ 18 - 7
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java

@@ -3,11 +3,8 @@ package cn.iocoder.yudao.module.crm.service.contact;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.ListUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactBaseVO;
-import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactCreateReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO;
-import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactUpdateReqVO;
-import cn.iocoder.yudao.module.crm.convert.contact.ContactConvert;
+import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*;
+import cn.iocoder.yudao.module.crm.convert.contact.CrmContactConvert;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
 import cn.iocoder.yudao.module.crm.dal.mysql.contact.CrmContactMapper;
 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
@@ -56,7 +53,7 @@ public class CrmContactServiceImpl implements CrmContactService {
         // 1.1 校验
         validateRelationDataExists(createReqVO);
         // 1.2 插入
-        CrmContactDO contact = ContactConvert.INSTANCE.convert(createReqVO);
+        CrmContactDO contact = CrmContactConvert.INSTANCE.convert(createReqVO);
         contactMapper.insert(contact);
 
         // 2. 创建数据权限
@@ -73,7 +70,7 @@ public class CrmContactServiceImpl implements CrmContactService {
         validateContactExists(updateReqVO.getId());
         validateRelationDataExists(updateReqVO);
         // 2. 更新
-        CrmContactDO updateObj = ContactConvert.INSTANCE.convert(updateReqVO);
+        CrmContactDO updateObj = CrmContactConvert.INSTANCE.convert(updateReqVO);
         contactMapper.updateById(updateObj);
     }
 
@@ -139,4 +136,18 @@ public class CrmContactServiceImpl implements CrmContactService {
         return contactMapper.selectPageByCustomerId(pageVO);
     }
 
+    @Override
+    public void transferContact(CrmContactTransferReqVO reqVO, Long userId) {
+        // 1 校验联系人是否存在
+        validateContactExists(reqVO.getId());
+
+        // 2.1 数据权限转移
+        crmPermissionService.transferPermission(
+                CrmContactConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTACT.getType()));
+        // 2.2 设置新的负责人
+        contactMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
+
+        // 3. TODO 记录转移日志
+    }
+
 }

+ 4 - 4
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java

@@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractCreat
 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractUpdateReqVO;
-import cn.iocoder.yudao.module.crm.convert.contract.ContractConvert;
+import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper;
 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
@@ -44,7 +44,7 @@ public class CrmContractServiceImpl implements CrmContractService {
     @Override
     public Long createContract(CrmContractCreateReqVO createReqVO, Long userId) {
         // 插入
-        CrmContractDO contract = ContractConvert.INSTANCE.convert(createReqVO);
+        CrmContractDO contract = CrmContractConvert.INSTANCE.convert(createReqVO);
         contractMapper.insert(contract);
 
         // 创建数据权限
@@ -61,7 +61,7 @@ public class CrmContractServiceImpl implements CrmContractService {
         // 校验存在
         validateContractExists(updateReqVO.getId());
         // 更新
-        CrmContractDO updateObj = ContractConvert.INSTANCE.convert(updateReqVO);
+        CrmContractDO updateObj = CrmContractConvert.INSTANCE.convert(updateReqVO);
         contractMapper.updateById(updateObj);
     }
 
@@ -118,7 +118,7 @@ public class CrmContractServiceImpl implements CrmContractService {
 
         // 2.1 数据权限转移
         crmPermissionService.transferPermission(
-                ContractConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()));
+                CrmContractConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()));
         // 2.2 设置负责人
         contractMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
 

+ 9 - 0
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanService.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.service.receivable;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanCreateReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO;
+import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanTransferReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanUpdateReqVO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO;
@@ -77,4 +78,12 @@ public interface CrmReceivablePlanService {
      */
     PageResult<CrmReceivablePlanDO> getReceivablePlanPageByCustomerId(CrmReceivablePlanPageReqVO pageReqVO);
 
+    /**
+     * 回款计划转移
+     *
+     * @param reqVO  请求
+     * @param userId 用户编号
+     */
+    void transferReceivablePlan(CrmReceivablePlanTransferReqVO reqVO, Long userId);
+
 }

+ 15 - 0
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java

@@ -6,6 +6,7 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanCreateReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO;
+import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanTransferReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanUpdateReqVO;
 import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivablePlanConvert;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
@@ -135,4 +136,18 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
         return receivablePlanMapper.selectPageByCustomerId(pageReqVO);
     }
 
+    @Override
+    public void transferReceivablePlan(CrmReceivablePlanTransferReqVO reqVO, Long userId) {
+        // 1 校验回款计划是否存在
+        validateReceivablePlanExists(reqVO.getId());
+
+        // 2.1 数据权限转移
+        crmPermissionService.transferPermission(
+                CrmReceivablePlanConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType()));
+        // 2.2 设置新的负责人
+        receivablePlanMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
+
+        // 3. TODO 记录转移日志
+    }
+
 }

+ 9 - 0
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.service.receivable;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableCreateReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
+import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableTransferReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
@@ -77,4 +78,12 @@ public interface CrmReceivableService {
      */
     PageResult<CrmReceivableDO> getReceivablePageByCustomerId(CrmReceivablePageReqVO pageReqVO);
 
+    /**
+     * 回款转移
+     *
+     * @param reqVO  请求
+     * @param userId 用户编号
+     */
+    void transferReceivable(CrmReceivableTransferReqVO reqVO, Long userId);
+
 }

+ 22 - 4
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java

@@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableCreateReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
+import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableTransferReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO;
 import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivableConvert;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
@@ -20,6 +21,7 @@ import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
 import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
 import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
+import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
 import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
@@ -48,6 +50,8 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
     private CrmCustomerService customerService;
     @Resource
     private CrmReceivablePlanService receivablePlanService;
+    @Resource
+    private CrmPermissionService crmPermissionService;
 
     // TODO @liuhongfeng:创建还款后,是不是什么时候,要更新 plan?
     @Override
@@ -70,22 +74,22 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
     // TODO @liuhongfeng:这里的括号要注意排版;
     private void checkReceivable(CrmReceivableDO receivable) {
         // TODO @liuhongfeng:这个放在参数校验合适
-        if(ObjectUtil.isNull(receivable.getContractId())){
+        if (ObjectUtil.isNull(receivable.getContractId())) {
             throw exception(CONTRACT_NOT_EXISTS);
         }
 
         CrmContractDO contract = contractService.getContract(receivable.getContractId());
-        if(ObjectUtil.isNull(contract)){
+        if (ObjectUtil.isNull(contract)) {
             throw exception(CONTRACT_NOT_EXISTS);
         }
 
         CrmCustomerDO customer = customerService.getCustomer(receivable.getCustomerId());
-        if(ObjectUtil.isNull(customer)){
+        if (ObjectUtil.isNull(customer)) {
             throw exception(CUSTOMER_NOT_EXISTS);
         }
 
         CrmReceivablePlanDO receivablePlan = receivablePlanService.getReceivablePlan(receivable.getPlanId());
-        if(ObjectUtil.isNull(receivablePlan)){
+        if (ObjectUtil.isNull(receivablePlan)) {
             throw exception(RECEIVABLE_PLAN_NOT_EXISTS);
         }
 
@@ -140,4 +144,18 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
         return receivableMapper.selectPageByCustomerId(pageReqVO);
     }
 
+    @Override
+    public void transferReceivable(CrmReceivableTransferReqVO reqVO, Long userId) {
+        // 1 校验回款是否存在
+        validateReceivableExists(reqVO.getId());
+
+        // 2.1 数据权限转移
+        crmPermissionService.transferPermission(
+                CrmReceivableConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_RECEIVABLE.getType()));
+        // 2.2 设置新的负责人
+        receivableMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
+
+        // 3. TODO 记录转移日志
+    }
+
 }