diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java
index 20355610b..e7bc01e18 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java
@@ -99,7 +99,6 @@ public class CrmBusinessController {
         return success(buildBusinessDetailPageResult(pageResult));
     }
 
-
     @GetMapping("/page-by-contact")
     @Operation(summary = "获得联系人的商机分页")
     @PreAuthorize("@ss.hasPermission('crm:business:query')")
@@ -121,6 +120,12 @@ public class CrmBusinessController {
                 buildBusinessDetailPageResult(pageResult).getList());
     }
 
+    /**
+     * 构建详细的商机分页结果
+     *
+     * @param pageResult 简单的商机分页结果
+     * @return 详细的商机分页结果
+     */
     private PageResult<CrmBusinessRespVO> buildBusinessDetailPageResult(PageResult<CrmBusinessDO> pageResult) {
         if (CollUtil.isEmpty(pageResult.getList())) {
             return PageResult.empty(pageResult.getTotal());
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java
index 6974b4902..80e8b623b 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java
@@ -121,7 +121,7 @@ public class CrmContactController {
     @PreAuthorize("@ss.hasPermission('crm:contact:query')")
     public CommonResult<PageResult<CrmContactRespVO>> getContactPage(@Valid CrmContactPageReqVO pageVO) {
         PageResult<CrmContactDO> pageResult = contactService.getContactPage(pageVO, getLoginUserId());
-        return success(convertDetailContactPage(pageResult));
+        return success(buildContactDetailPage(pageResult));
     }
 
     @GetMapping("/page-by-customer")
@@ -129,7 +129,7 @@ public class CrmContactController {
     public CommonResult<PageResult<CrmContactRespVO>> getContactPageByCustomer(@Valid CrmContactPageReqVO pageVO) {
         Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
         PageResult<CrmContactDO> pageResult = contactService.getContactPageByCustomerId(pageVO);
-        return success(convertDetailContactPage(pageResult));
+        return success(buildContactDetailPage(pageResult));
     }
 
     @GetMapping("/export-excel")
@@ -141,16 +141,16 @@ public class CrmContactController {
         exportReqVO.setPageNo(PAGE_SIZE_NONE);
         PageResult<CrmContactDO> pageResult = contactService.getContactPage(exportReqVO, getLoginUserId());
         ExcelUtils.write(response, "联系人.xls", "数据", CrmContactRespVO.class,
-                convertDetailContactPage(pageResult).getList());
+                buildContactDetailPage(pageResult).getList());
     }
 
     /**
-     * 转换成详细的联系人分页,即读取关联信息
+     * 构建详细的联系人分页结果
      *
-     * @param pageResult 联系人分页
-     * @return 详细的联系人分页
+     * @param pageResult 简单的联系人分页结果
+     * @return 详细的联系人分页结果
      */
-    private PageResult<CrmContactRespVO> convertDetailContactPage(PageResult<CrmContactDO> pageResult) {
+    private PageResult<CrmContactRespVO> buildContactDetailPage(PageResult<CrmContactDO> pageResult) {
         List<CrmContactDO> contactList = pageResult.getList();
         if (CollUtil.isEmpty(contactList)) {
             return PageResult.empty(pageResult.getTotal());
@@ -175,10 +175,10 @@ public class CrmContactController {
         return success(true);
     }
 
-    // ================== 关联/取关商机  ===================
+    // ================== 关联/取关联系人  ===================
 
     @PostMapping("/create-business-list")
-    @Operation(summary = "创建联系人与商机的关联")
+    @Operation(summary = "创建联系人与联系人的关联")
     @PreAuthorize("@ss.hasPermission('crm:contact:create-business')")
     public CommonResult<Boolean> createContactBusinessList(@Valid @RequestBody CrmContactBusinessReqVO createReqVO) {
         contactBusinessLinkService.createContactBusinessList(createReqVO);
@@ -186,7 +186,7 @@ public class CrmContactController {
     }
 
     @DeleteMapping("/delete-business-list")
-    @Operation(summary = "删除联系人与商机的关联")
+    @Operation(summary = "删除联系人与联系人的关联")
     @PreAuthorize("@ss.hasPermission('crm:contact:delete-business')")
     public CommonResult<Boolean> deleteContactBusinessList(@Valid @RequestBody CrmContactBusinessReqVO deleteReqVO) {
         contactBusinessLinkService.deleteContactBusinessList(deleteReqVO);
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
index 849e424a2..0a4043772 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
@@ -88,7 +88,7 @@ public class CrmContractController {
     @PreAuthorize("@ss.hasPermission('crm:contract:query')")
     public CommonResult<PageResult<ContractRespVO>> getContractPage(@Valid CrmContractPageReqVO pageVO) {
         PageResult<CrmContractDO> pageResult = contractService.getContractPage(pageVO, getLoginUserId());
-        return success(convertDetailContractPage(pageResult));
+        return success(buildContractDetailPage(pageResult));
     }
 
     @GetMapping("/page-by-customer")
@@ -96,7 +96,7 @@ public class CrmContractController {
     public CommonResult<PageResult<ContractRespVO>> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) {
         Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
         PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageVO);
-        return success(convertDetailContractPage(pageResult));
+        return success(buildContractDetailPage(pageResult));
     }
 
     @GetMapping("/export-excel")
@@ -112,12 +112,12 @@ public class CrmContractController {
     }
 
     /**
-     * 转换成详细的合同分页,即读取关联信息
+     * 构建详细的合同分页结果
      *
-     * @param pageResult 合同分页
-     * @return 详细的合同分页
+     * @param pageResult 简单的合同分页结果
+     * @return 详细的合同分页结果
      */
-    private PageResult<ContractRespVO> convertDetailContractPage(PageResult<CrmContractDO> pageResult) {
+    private PageResult<ContractRespVO> buildContractDetailPage(PageResult<CrmContractDO> pageResult) {
         List<CrmContractDO> contactList = pageResult.getList();
         if (CollUtil.isEmpty(contactList)) {
             return PageResult.empty(pageResult.getTotal());
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
index dfa02c0b2..1ba9cc010 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
@@ -136,7 +136,7 @@ public class CrmCustomerController {
     }
 
     @PutMapping("/transfer")
-    @Operation(summary = "客户转移")
+    @Operation(summary = "转移客户")
     @OperateLog(enable = false) // TODO 关闭原有日志记录
     @PreAuthorize("@ss.hasPermission('crm:customer:update')")
     public CommonResult<Boolean> transfer(@Valid @RequestBody CrmCustomerTransferReqVO reqVO) {
@@ -184,6 +184,7 @@ public class CrmCustomerController {
         return success(true);
     }
 
+    // TODO @puhui999:需要搞个 VO 类
     @PutMapping("/distribute")
     @Operation(summary = "分配公海给对应负责人")
     @Parameters({
@@ -193,7 +194,6 @@ public class CrmCustomerController {
     @PreAuthorize("@ss.hasPermission('crm:customer:distribute')")
     public CommonResult<Boolean> distributeCustomer(@RequestParam(value = "ids") List<Long> ids,
                                                     @RequestParam(value = "ownerUserId") Long ownerUserId) {
-        // 领取公海数据
         customerService.receiveCustomer(ids, ownerUserId);
         return success(true);
     }
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerTransferReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerTransferReqVO.java
index 9bdc43532..09eca73ea 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerTransferReqVO.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerTransferReqVO.java
@@ -28,4 +28,6 @@ public class CrmCustomerTransferReqVO {
     @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
     private Integer oldOwnerPermissionLevel;
 
+    // TODO @puhui999:联系人、商机、合同的转移
+
 }
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java
index 5dc3807f5..7350e6915 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/permission/CrmPermissionController.java
@@ -103,6 +103,7 @@ public class CrmPermissionController {
         // 拼接数据
         List<AdminUserRespDTO> userList = adminUserApi.getUserList(convertSet(permission, CrmPermissionDO::getUserId));
         Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userList, AdminUserRespDTO::getDeptId));
+        // TODO @puhui999:可能 postIds 为空的时候,会导致报错,看看怎么 fix 下
         Set<Long> postIds = CollectionUtils.convertSetByFlatMap(userList, AdminUserRespDTO::getPostIds, Collection::stream);
         Map<Long, PostRespDTO> postMap = postApi.getPostMap(postIds);
         return success(CrmPermissionConvert.INSTANCE.convert(permission, userList, deptMap, postMap));
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java
index 98355077e..e5ae4fd9b 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java
@@ -93,7 +93,7 @@ public class CrmReceivableController {
     @PreAuthorize("@ss.hasPermission('crm:receivable:query')")
     public CommonResult<PageResult<CrmReceivableRespVO>> getReceivablePage(@Valid CrmReceivablePageReqVO pageReqVO) {
         PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(pageReqVO, getLoginUserId());
-        return success(convertDetailReceivablePage(pageResult));
+        return success(buildReceivableDetailPage(pageResult));
     }
 
     @GetMapping("/page-by-customer")
@@ -101,7 +101,7 @@ public class CrmReceivableController {
     public CommonResult<PageResult<CrmReceivableRespVO>> getReceivablePageByCustomer(@Valid CrmReceivablePageReqVO pageReqVO) {
         Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
         PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePageByCustomerId(pageReqVO);
-        return success(convertDetailReceivablePage(pageResult));
+        return success(buildReceivableDetailPage(pageResult));
     }
 
     // TODO 芋艿:后面在优化导出
@@ -115,16 +115,16 @@ public class CrmReceivableController {
         PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(exportReqVO, getLoginUserId());
         // 导出 Excel
         ExcelUtils.write(response, "回款.xls", "数据", CrmReceivableRespVO.class,
-                convertDetailReceivablePage(pageResult).getList());
+                buildReceivableDetailPage(pageResult).getList());
     }
 
     /**
-     * 转换成详细的回款分页,即读取关联信息
+     * 构建详细的回款分页结果
      *
-     * @param pageResult 回款分页
-     * @return 详细的回款分页
+     * @param pageResult 简单的回款分页结果
+     * @return 详细的回款分页结果
      */
-    private PageResult<CrmReceivableRespVO> convertDetailReceivablePage(PageResult<CrmReceivableDO> pageResult) {
+    private PageResult<CrmReceivableRespVO> buildReceivableDetailPage(PageResult<CrmReceivableDO> pageResult) {
         List<CrmReceivableDO> receivableList = pageResult.getList();
         if (CollUtil.isEmpty(receivableList)) {
             return PageResult.empty(pageResult.getTotal());
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java
index 6dc540e42..7ff0a9385 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java
@@ -123,10 +123,10 @@ public class CrmReceivablePlanController {
     }
 
     /**
-     * 转换成详细的回款计划分页,即读取关联信息
+     * 构建详细的回款计划分页结果
      *
-     * @param pageResult 回款计划分页
-     * @return 详细的回款计划分页
+     * @param pageResult 简单的回款计划分页结果
+     * @return 详细的回款计划分页结果
      */
     private PageResult<CrmReceivablePlanRespVO> convertDetailReceivablePlanPage(PageResult<CrmReceivablePlanDO> pageResult) {
         List<CrmReceivablePlanDO> receivablePlanList = pageResult.getList();
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessConvert.java
index 3effb21e0..a67812f8b 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessConvert.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessConvert.java
@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.crm.convert.business;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*;
 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
@@ -9,7 +10,6 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
-import org.mapstruct.Mappings;
 import org.mapstruct.factory.Mappers;
 
 import java.util.List;
@@ -34,25 +34,23 @@ public interface CrmBusinessConvert {
     CrmBusinessRespVO convert(CrmBusinessDO bean);
     List<CrmBusinessRespVO> convert(List<CrmBusinessDO> bean);
 
-    PageResult<CrmBusinessRespVO> convertPage(PageResult<CrmBusinessDO> page);
-
     List<CrmBusinessExcelVO> convertList02(List<CrmBusinessDO> list);
 
     @Mapping(target = "bizId", source = "reqVO.id")
     CrmPermissionTransferReqBO convert(CrmBusinessTransferReqVO reqVO, Long userId);
 
-    default PageResult<CrmBusinessRespVO> convertPage(PageResult<CrmBusinessDO> page, List<CrmCustomerDO> customerList,
+    default PageResult<CrmBusinessRespVO> convertPage(PageResult<CrmBusinessDO> pageResult, List<CrmCustomerDO> customerList,
                                                       List<CrmBusinessStatusTypeDO> statusTypeList, List<CrmBusinessStatusDO> statusList) {
-        PageResult<CrmBusinessRespVO> result = convertPage(page);
+        PageResult<CrmBusinessRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmBusinessRespVO.class);
         // 拼接关联字段
         Map<Long, String> customerMap = convertMap(customerList, CrmCustomerDO::getId, CrmCustomerDO::getName);
         Map<Long, String> statusTypeMap = convertMap(statusTypeList, CrmBusinessStatusTypeDO::getId, CrmBusinessStatusTypeDO::getName);
         Map<Long, String> statusMap = convertMap(statusList, CrmBusinessStatusDO::getId, CrmBusinessStatusDO::getName);
-        result.getList().forEach(type -> type
+        voPageResult.getList().forEach(type -> type
                 .setCustomerName(customerMap.get(type.getCustomerId()))
                 .setStatusTypeName(statusTypeMap.get(type.getStatusTypeId()))
                 .setStatusName(statusMap.get(type.getStatusId())));
-        return result;
+        return voPageResult;
     }
 
 }
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java
index d41a4f6b3..8d023618f 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.convert.contact;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
@@ -18,7 +19,6 @@ import java.util.Map;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
 
-// TODO 芋艿:convert 后面在梳理下,略微有点乱
 /**
  * CRM 联系人 Convert
  *
@@ -39,64 +39,39 @@ public interface CrmContactConvert {
 
     PageResult<CrmContactRespVO> convertPage(PageResult<CrmContactDO> page);
 
-    default PageResult<CrmContactRespVO> convertPage(PageResult<CrmContactDO> pageResult, Map<Long, AdminUserRespDTO> userMap,
-                                                     List<CrmCustomerDO> customerList, List<CrmContactDO> parentContactList) {
-        List<CrmContactRespVO> list = converList(pageResult.getList(), userMap, customerList, parentContactList);
-        return convertPage(pageResult).setList(list);
-    }
-
     List<CrmContactSimpleRespVO> convertAllList(List<CrmContactDO> list);
 
     @Mapping(target = "bizId", source = "reqVO.id")
     CrmPermissionTransferReqBO convert(CrmContactTransferReqVO reqVO, Long userId);
 
-    /**
-     * 转换详情信息
-     *
-     * @param contactDO         联系人
-     * @param userMap           用户列表
-     * @param customerDOList 客户
-     * @return ContactRespVO
-     */
+    default PageResult<CrmContactRespVO> convertPage(PageResult<CrmContactDO> pageResult, Map<Long, AdminUserRespDTO> userMap,
+                                                     List<CrmCustomerDO> customerList, List<CrmContactDO> parentContactList) {
+        PageResult<CrmContactRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmContactRespVO.class);
+        // 拼接关联字段
+        Map<Long, CrmContactDO> parentContactMap = convertMap(parentContactList, CrmContactDO::getId);
+        Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);
+        voPageResult.getList().forEach(item -> {
+            setUserInfo(item, userMap);
+            findAndThen(customerMap, item.getCustomerId(), customer -> item.setCustomerName(customer.getName()));
+            findAndThen(parentContactMap, item.getParentId(), contactDO -> item.setParentName(contactDO.getName()));
+        });
+        return voPageResult;
+    }
+
     default CrmContactRespVO convert(CrmContactDO contactDO, Map<Long, AdminUserRespDTO> userMap,
-                                     List<CrmCustomerDO> customerDOList, List<CrmContactDO> contactList) {
+                                     List<CrmCustomerDO> customerList, List<CrmContactDO> parentContactList) {
         CrmContactRespVO contactVO = convert(contactDO);
         setUserInfo(contactVO, userMap);
-        Map<Long, CrmCustomerDO> customerMap = CollectionUtils.convertMap(customerDOList, CrmCustomerDO::getId);
-        Map<Long, CrmContactDO> contactMap = CollectionUtils.convertMap(contactList, CrmContactDO::getId);
+        Map<Long, CrmCustomerDO> customerMap = CollectionUtils.convertMap(customerList, CrmCustomerDO::getId);
+        Map<Long, CrmContactDO> contactMap = CollectionUtils.convertMap(parentContactList, CrmContactDO::getId);
         findAndThen(customerMap, contactDO.getCustomerId(), customer -> contactVO.setCustomerName(customer.getName()));
         findAndThen(contactMap, contactDO.getParentId(), contact -> contactVO.setParentName(contact.getName()));
         return contactVO;
     }
 
-    default List<CrmContactRespVO> converList(List<CrmContactDO> contactList, Map<Long, AdminUserRespDTO> userMap,
-                                              List<CrmCustomerDO> customerList, List<CrmContactDO> parentContactList) {
-        List<CrmContactRespVO> result = convertList(contactList);
-        Map<Long, CrmContactDO> parentContactMap = convertMap(parentContactList, CrmContactDO::getId);
-        Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);
-        result.forEach(item -> {
-            setUserInfo(item, userMap);
-            findAndThen(customerMap, item.getCustomerId(), customer ->
-                item.setCustomerName(customer.getName())
-            );
-            findAndThen(parentContactMap, item.getParentId(), contactDO ->
-                item.setParentName(contactDO.getName())
-            );
-        });
-        return result;
-    }
-
-    /**
-     * 设置用户信息
-     *
-     * @param contactRespVO 联系人Response VO
-     * @param userMap       用户信息 map
-     */
     static void setUserInfo(CrmContactRespVO contactRespVO, Map<Long, AdminUserRespDTO> userMap) {
         contactRespVO.setAreaName(AreaUtils.format(contactRespVO.getAreaId()));
-        findAndThen(userMap, contactRespVO.getOwnerUserId(), user -> {
-            contactRespVO.setOwnerUserName(user == null ? "" : user.getNickname());
-        });
+        findAndThen(userMap, contactRespVO.getOwnerUserId(), user -> contactRespVO.setOwnerUserName(user.getNickname()));
         findAndThen(userMap, Long.parseLong(contactRespVO.getCreator()), user -> contactRespVO.setCreatorName(user.getNickname()));
     }
 
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java
index 74b7a4663..b898ef4e3 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java
@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.crm.convert.contract;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
@@ -43,23 +44,15 @@ public interface CrmContractConvert {
 
     default PageResult<ContractRespVO> convertPage(PageResult<CrmContractDO> pageResult, Map<Long, AdminUserRespDTO> userMap,
                                                      List<CrmCustomerDO> customerList) {
-        return new PageResult<>(converList(pageResult.getList(), userMap, customerList), pageResult.getTotal());
-    }
-
-    default List<ContractRespVO> converList(List<CrmContractDO> contractList, Map<Long, AdminUserRespDTO> userMap,
-                                            List<CrmCustomerDO> customerList) {
-        List<ContractRespVO> result = convertList(contractList);
+        PageResult<ContractRespVO> voPageResult = BeanUtils.toBean(pageResult, ContractRespVO.class);
+        // 拼接关联字段
         Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);
-        result.forEach(item -> {
-            setUserInfo(item, userMap);
-            findAndThen(customerMap, item.getCustomerId(), customer -> item.setCustomerName(customer.getName()));
+        voPageResult.getList().forEach(contract -> {
+            findAndThen(userMap, contract.getOwnerUserId(), user -> contract.setOwnerUserName(user.getNickname()));
+            findAndThen(userMap, Long.parseLong(contract.getCreator()), user -> contract.setCreatorName(user.getNickname()));
+            findAndThen(customerMap, contract.getCustomerId(), customer -> contract.setCustomerName(customer.getName()));
         });
-        return result;
-    }
-
-    static void setUserInfo(ContractRespVO contract, Map<Long, AdminUserRespDTO> userMap) {
-        findAndThen(userMap, contract.getOwnerUserId(), user -> contract.setOwnerUserName(user.getNickname()));
-        findAndThen(userMap, Long.parseLong(contract.getCreator()), user -> contract.setCreatorName(user.getNickname()));
+        return voPageResult;
     }
 
 }
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivableConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivableConvert.java
index e7340fc86..9f343238a 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivableConvert.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivableConvert.java
@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.crm.convert.receivable;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 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;
@@ -36,29 +37,19 @@ public interface CrmReceivableConvert {
 
     CrmReceivableRespVO convert(CrmReceivableDO bean);
 
-    List<CrmReceivableRespVO> convertList(List<CrmReceivableDO> list);
-
     default PageResult<CrmReceivableRespVO> convertPage(PageResult<CrmReceivableDO> pageResult, Map<Long, AdminUserRespDTO> userMap,
                                                         List<CrmCustomerDO> customerList, List<CrmContractDO> contractList) {
-        return new PageResult<>(converList(pageResult.getList(), userMap, customerList, contractList), pageResult.getTotal());
-    }
-
-    default List<CrmReceivableRespVO> converList(List<CrmReceivableDO> receivableList, Map<Long, AdminUserRespDTO> userMap,
-                                                 List<CrmCustomerDO> customerList, List<CrmContractDO> contractList) {
-        List<CrmReceivableRespVO> result = convertList(receivableList);
+        PageResult<CrmReceivableRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmReceivableRespVO.class);
+        // 拼接关联字段
         Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);
         Map<Long, CrmContractDO> contractMap = convertMap(contractList, CrmContractDO::getId);
-        result.forEach(item -> {
-            setUserInfo(item, userMap);
-            findAndThen(customerMap, item.getCustomerId(), customer -> item.setCustomerName(customer.getName()));
-            findAndThen(contractMap, item.getContractId(), contract -> item.setContractNo(contract.getNo()));
+        voPageResult.getList().forEach(receivable -> {
+            findAndThen(userMap, receivable.getOwnerUserId(), user -> receivable.setOwnerUserName(user.getNickname()));
+            findAndThen(userMap, Long.parseLong(receivable.getCreator()), user -> receivable.setCreatorName(user.getNickname()));
+            findAndThen(customerMap, receivable.getCustomerId(), customer -> receivable.setCustomerName(customer.getName()));
+            findAndThen(contractMap, receivable.getContractId(), contract -> receivable.setContractNo(contract.getNo()));
         });
-        return result;
-    }
-
-    static void setUserInfo(CrmReceivableRespVO receivable, Map<Long, AdminUserRespDTO> userMap) {
-        findAndThen(userMap, receivable.getOwnerUserId(), user -> receivable.setOwnerUserName(user.getNickname()));
-        findAndThen(userMap, Long.parseLong(receivable.getCreator()), user -> receivable.setCreatorName(user.getNickname()));
+        return voPageResult;
     }
 
     @Mapping(target = "bizId", source = "reqVO.id")
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivablePlanConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivablePlanConvert.java
index 70e930880..eb459e071 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivablePlanConvert.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivablePlanConvert.java
@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.crm.convert.receivable;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 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;
@@ -37,33 +38,22 @@ public interface CrmReceivablePlanConvert {
 
     CrmReceivablePlanRespVO convert(CrmReceivablePlanDO bean);
 
-    List<CrmReceivablePlanRespVO> convertList(List<CrmReceivablePlanDO> list);
-
     default PageResult<CrmReceivablePlanRespVO> convertPage(PageResult<CrmReceivablePlanDO> pageResult, Map<Long, AdminUserRespDTO> userMap,
                                                             List<CrmCustomerDO> customerList, List<CrmContractDO> contractList,
                                                             List<CrmReceivableDO> receivableList) {
-        return new PageResult<>(converList(pageResult.getList(), userMap, customerList, contractList, receivableList), pageResult.getTotal());
-    }
-
-    default List<CrmReceivablePlanRespVO> converList(List<CrmReceivablePlanDO> receivablePlanList, Map<Long, AdminUserRespDTO> userMap,
-                                                     List<CrmCustomerDO> customerList, List<CrmContractDO> contractList,
-                                                     List<CrmReceivableDO> receivableList) {
-        List<CrmReceivablePlanRespVO> result = convertList(receivablePlanList);
+        PageResult<CrmReceivablePlanRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmReceivablePlanRespVO.class);
+        // 拼接关联字段
         Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);
         Map<Long, CrmContractDO> contractMap = convertMap(contractList, CrmContractDO::getId);
         Map<Long, CrmReceivableDO> receivableMap = convertMap(receivableList, CrmReceivableDO::getId);
-        result.forEach(item -> {
-            setUserInfo(item, userMap);
-            findAndThen(customerMap, item.getCustomerId(), customer -> item.setCustomerName(customer.getName()));
-            findAndThen(contractMap, item.getContractId(), contract -> item.setContractNo(contract.getNo()));
-            findAndThen(receivableMap, item.getReceivableId(), receivable -> item.setReturnType(receivable.getReturnType()));
+        voPageResult.getList().forEach(receivablePlan -> {
+            findAndThen(userMap, receivablePlan.getOwnerUserId(), user -> receivablePlan.setOwnerUserName(user.getNickname()));
+            findAndThen(userMap, Long.parseLong(receivablePlan.getCreator()), user -> receivablePlan.setCreatorName(user.getNickname()));
+            findAndThen(customerMap, receivablePlan.getCustomerId(), customer -> receivablePlan.setCustomerName(customer.getName()));
+            findAndThen(contractMap, receivablePlan.getContractId(), contract -> receivablePlan.setContractNo(contract.getNo()));
+            findAndThen(receivableMap, receivablePlan.getReceivableId(), receivable -> receivablePlan.setReturnType(receivable.getReturnType()));
         });
-        return result;
-    }
-
-    static void setUserInfo(CrmReceivablePlanRespVO receivablePlan, Map<Long, AdminUserRespDTO> userMap) {
-        findAndThen(userMap, receivablePlan.getOwnerUserId(), user -> receivablePlan.setOwnerUserName(user.getNickname()));
-        findAndThen(userMap, Long.parseLong(receivablePlan.getCreator()), user -> receivablePlan.setCreatorName(user.getNickname()));
+        return voPageResult;
     }
 
     @Mapping(target = "bizId", source = "reqVO.id")
diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
index bb900b784..ad0ee9a76 100644
--- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
+++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
@@ -105,11 +105,13 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
     public void deleteCustomer(Long id) {
         // 校验存在
         validateCustomerExists(id);
+        // TODO @puhui999:如果有联系人、商机,则不允许删除;
 
         // 删除
         customerMapper.deleteById(id);
         // 删除数据权限
         permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id);
+        // TODO @puhui999:删除跟进记录
     }
 
     private CrmCustomerDO validateCustomerExists(Long id) {
@@ -151,7 +153,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    @LogRecord(type = CRM_CUSTOMER, subType = "客户转移", bizNo = "{{#reqVO.id}}", success = TRANSFER_CUSTOMER_LOG_SUCCESS)
+    @LogRecord(type = CRM_CUSTOMER, subType = "转移客户", bizNo = "{{#reqVO.id}}", success = TRANSFER_CUSTOMER_LOG_SUCCESS)
     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER)
     public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) {
         // 1.1 校验客户是否存在
@@ -235,7 +237,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    @LogRecord(type = CRM_CUSTOMER, subType = "客户放入公海", bizNo = "{{#id}}", success = "将客户放入了公海")
+    @LogRecord(type = CRM_CUSTOMER, subType = "客户放入公海", bizNo = "{{#id}}", success = "将客户放入了公海") // TODO @puhui999:将客户【】放入了公海
     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
     public void putCustomerPool(Long id) {
         // 1. 校验存在
@@ -256,10 +258,16 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
         // 3. 删除负责人数据权限
         permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(),
                 CrmPermissionLevelEnum.OWNER.getLevel());
+        // TODO @puhui999:联系人的负责人,也要设置为 null;这块和领取是对应的;因为领取后,负责人也要关联过来;
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
+    // TODO @puhui999:权限校验
+
+    // TODO @puhui999:如果是分配,操作日志是 “将客户【】分配给【】”
+    // TODO @puhui999:如果是领取,操作日志是“领取客户【】”;
+    // TODO @puhui999:如果是多条,则需要记录多条操作日志;不然 bizId 不好关联
     public void receiveCustomer(List<Long> ids, Long ownerUserId) {
         // 1.1 校验存在
         List<CrmCustomerDO> customers = customerMapper.selectBatchIds(ids);
@@ -280,7 +288,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
         // 1.4  校验负责人是否到达上限
         validateCustomerExceedOwnerLimit(ownerUserId, customers.size());
 
-        // 2. 领取公海数据
+        // 2.1 领取公海数据
         List<CrmCustomerDO> updateCustomers = new ArrayList<>();
         List<CrmPermissionCreateReqBO> createPermissions = new ArrayList<>();
         customers.forEach(customer -> {
@@ -290,11 +298,11 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
             createPermissions.add(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())
                     .setBizId(customer.getId()).setUserId(ownerUserId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
         });
-
-        // 3.1 更新客户负责人
+        // 2.2 更新客户负责人
         customerMapper.updateBatch(updateCustomers);
-        // 3.2 创建负责人数据权限
+        // 2.3 创建负责人数据权限
         permissionService.createPermissionBatch(createPermissions);
+        // TODO @芋艿:要不要处理关联的联系人???
     }
 
     private void validateCustomerOwnerExists(CrmCustomerDO customer, Boolean pool) {