mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 18:28:43 +08:00 
			
		
		
		
	📖 CRM:线索 clue 列表的完善
This commit is contained in:
		| @@ -1,13 +1,22 @@ | ||||
| package cn.iocoder.yudao.module.crm.controller.admin.clue; | ||||
|  | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||
| import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | ||||
| import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | ||||
| import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||||
| 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.clue.vo.*; | ||||
| import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; | ||||
| import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; | ||||
| import cn.iocoder.yudao.module.crm.service.clue.CrmClueService; | ||||
| import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; | ||||
| import cn.iocoder.yudao.module.system.api.dept.DeptApi; | ||||
| import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; | ||||
| import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | ||||
| import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | ||||
| import io.swagger.v3.oas.annotations.Operation; | ||||
| import io.swagger.v3.oas.annotations.Parameter; | ||||
| import io.swagger.v3.oas.annotations.tags.Tag; | ||||
| @@ -19,10 +28,15 @@ import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
|  | ||||
| import java.io.IOException; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.stream.Stream; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||||
| import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; | ||||
| import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap; | ||||
| import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | ||||
| import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; | ||||
| import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | ||||
|  | ||||
| @@ -34,6 +48,13 @@ public class CrmClueController { | ||||
|  | ||||
|     @Resource | ||||
|     private CrmClueService clueService; | ||||
|     @Resource | ||||
|     private CrmCustomerService customerService; | ||||
|  | ||||
|     @Resource | ||||
|     private AdminUserApi adminUserApi; | ||||
|     @Resource | ||||
|     private DeptApi deptApi; | ||||
|  | ||||
|     @PostMapping("/create") | ||||
|     @Operation(summary = "创建线索") | ||||
| @@ -73,7 +94,7 @@ public class CrmClueController { | ||||
|     @PreAuthorize("@ss.hasPermission('crm:clue:query')") | ||||
|     public CommonResult<PageResult<CrmClueRespVO>> getCluePage(@Valid CrmCluePageReqVO pageVO) { | ||||
|         PageResult<CrmClueDO> pageResult = clueService.getCluePage(pageVO, getLoginUserId()); | ||||
|         return success(BeanUtils.toBean(pageResult, CrmClueRespVO.class)); | ||||
|         return success(new PageResult<>(buildClueDetailList(pageResult.getList()), pageResult.getTotal())); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/export-excel") | ||||
| @@ -84,8 +105,32 @@ public class CrmClueController { | ||||
|         pageReqVO.setPageSize(PAGE_SIZE_NONE); | ||||
|         List<CrmClueDO> list = clueService.getCluePage(pageReqVO, getLoginUserId()).getList(); | ||||
|         // 导出 Excel | ||||
|         List<CrmClueRespVO> datas = BeanUtils.toBean(list, CrmClueRespVO.class); | ||||
|         ExcelUtils.write(response, "线索.xls", "数据", CrmClueRespVO.class, datas); | ||||
|         ExcelUtils.write(response, "线索.xls", "数据", CrmClueRespVO.class, buildClueDetailList(list)); | ||||
|     } | ||||
|  | ||||
|     private List<CrmClueRespVO> buildClueDetailList(List<CrmClueDO> list) { | ||||
|         if (CollUtil.isEmpty(list)) { | ||||
|             return Collections.emptyList(); | ||||
|         } | ||||
|         // 1.1 获取客户列表 | ||||
|         Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap( | ||||
|                 convertSet(list, CrmClueDO::getCustomerId)); | ||||
|         // 1.2 获取创建人、负责人列表 | ||||
|         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(list, | ||||
|                 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); | ||||
|         Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); | ||||
|         // 2. 转换成 VO | ||||
|         return BeanUtils.toBean(list, CrmClueRespVO.class, clueVO -> { | ||||
|             // 2.1 设置客户名称 | ||||
|             MapUtils.findAndThen(customerMap, clueVO.getCustomerId(), customer -> clueVO.setCustomerName(customer.getName())); | ||||
|             // 2.2 设置创建人、负责人名称 | ||||
|             MapUtils.findAndThen(userMap, NumberUtils.parseLong(clueVO.getCreator()), | ||||
|                     user -> clueVO.setCreatorName(user.getNickname())); | ||||
|             MapUtils.findAndThen(userMap, clueVO.getOwnerUserId(), user -> { | ||||
|                 clueVO.setOwnerUserName(user.getNickname()); | ||||
|                 MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> clueVO.setOwnerUserDeptName(dept.getName())); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     @PutMapping("/transfer") | ||||
|   | ||||
| @@ -8,12 +8,9 @@ import com.alibaba.excel.annotation.ExcelProperty; | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
| import lombok.Data; | ||||
| import lombok.ToString; | ||||
| import org.springframework.format.annotation.DateTimeFormat; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | ||||
|  | ||||
| @Schema(description = "管理后台 - 线索 Response VO") | ||||
| @Data | ||||
| @ToString(callSuper = true) | ||||
| @@ -34,19 +31,25 @@ public class CrmClueRespVO { | ||||
|     private Boolean followUpStatus; | ||||
|  | ||||
|     @Schema(description = "最后跟进时间") | ||||
|     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||||
|     @ExcelProperty("最后跟进时间") | ||||
|     private LocalDateTime contactLastTime; | ||||
|  | ||||
|     @Schema(description = "最后跟进内容", example = "吃饭、睡觉、打逗逗") | ||||
|     @ExcelProperty("最后跟进内容") | ||||
|     private String contactLastContent; | ||||
|  | ||||
|     @Schema(description = "下次联系时间", example = "2023-10-18 01:00:00") | ||||
|     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||||
|     @ExcelProperty("下次联系时间") | ||||
|     private LocalDateTime contactNextTime; | ||||
|  | ||||
|     @Schema(description = "负责人编号") | ||||
|     @ExcelProperty("负责人的用户编号") | ||||
|     // TODO 这里需要导出成负责人的名字 | ||||
|     private Long ownerUserId; | ||||
|     @Schema(description = "负责人名字", example = "25682") | ||||
|     @ExcelProperty("负责人名字") | ||||
|     private String ownerUserName; | ||||
|     @Schema(description = "负责人部门") | ||||
|     @ExcelProperty("负责人部门") | ||||
|     private String ownerUserDeptName; | ||||
|  | ||||
|     @Schema(description = "转化状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") | ||||
|     @ExcelProperty(value = "转化状态", converter = DictConvert.class) | ||||
| @@ -54,9 +57,10 @@ public class CrmClueRespVO { | ||||
|     private Boolean transformStatus; | ||||
|  | ||||
|     @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "520") | ||||
|     // TODO 这里需要导出成客户名称 | ||||
|     @ExcelProperty("客户编号") | ||||
|     private Long customerId; | ||||
|     @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "客户名称") | ||||
|     @ExcelProperty("客户名称") | ||||
|     private String customerName; | ||||
|  | ||||
|     @Schema(description = "手机号", example = "18000000000") | ||||
|     @ExcelProperty("手机号") | ||||
| @@ -109,8 +113,19 @@ public class CrmClueRespVO { | ||||
|     @ExcelProperty("备注") | ||||
|     private String remark; | ||||
|  | ||||
|     @Schema(description = "创建人", example = "1024") | ||||
|     @ExcelProperty("创建人") | ||||
|     private String creator; | ||||
|     @Schema(description = "创建人名字", example = "芋道源码") | ||||
|     @ExcelProperty("创建人名字") | ||||
|     private String creatorName; | ||||
|  | ||||
|     @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     @ExcelProperty("创建时间") | ||||
|     private LocalDateTime createTime; | ||||
|  | ||||
|     @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||||
|     @ExcelProperty("更新时间") | ||||
|     private LocalDateTime updateTime; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -56,6 +56,7 @@ public class CrmCustomerController { | ||||
|     private CrmCustomerService customerService; | ||||
|     @Resource | ||||
|     private CrmCustomerPoolConfigService customerPoolConfigService; | ||||
|  | ||||
|     @Resource | ||||
|     private DeptApi deptApi; | ||||
|     @Resource | ||||
|   | ||||
| @@ -40,9 +40,13 @@ public class CrmClueDO extends BaseDO { | ||||
|      */ | ||||
|     private Boolean followUpStatus; | ||||
|     /** | ||||
|      * 最后跟进时间 TODO 添加跟进记录时更新该值 | ||||
|      * 最后跟进时间 | ||||
|      */ | ||||
|     private LocalDateTime contactLastTime; | ||||
|     /** | ||||
|      * 最后跟进内容 | ||||
|      */ | ||||
|     private String contactLastContent; | ||||
|     /** | ||||
|      * 下次联系时间 | ||||
|      */ | ||||
|   | ||||
| @@ -35,6 +35,7 @@ import org.springframework.stereotype.Service; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.*; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||||
| @@ -81,7 +82,8 @@ public class CrmClueServiceImpl implements CrmClueService { | ||||
|         } | ||||
|  | ||||
|         // 2. 插入 | ||||
|         CrmClueDO clue = BeanUtils.toBean(createReqVO, CrmClueDO.class).setId(null); | ||||
|         CrmClueDO clue = BeanUtils.toBean(createReqVO, CrmClueDO.class) | ||||
|                 .setContactLastTime(LocalDateTime.now()); | ||||
|         clueMapper.insert(clue); | ||||
|  | ||||
|         // 3. 创建数据权限 | ||||
|   | ||||
| @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageR | ||||
| import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO; | ||||
| import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; | ||||
| import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; | ||||
| import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO; | ||||
| import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; | ||||
| import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; | ||||
| import jakarta.validation.Valid; | ||||
| @@ -127,13 +128,20 @@ public interface CrmContractService { | ||||
|     Long getContractCountByCustomerId(Long customerId); | ||||
|  | ||||
|     /** | ||||
|      * 根据商机ID获取关联客户的合同数量 | ||||
|      * 根据商机编号,获取关联客户的合同数量 | ||||
|      * | ||||
|      * @param businessId 商机编号 | ||||
|      * @return 数量 | ||||
|      */ | ||||
|     Long getContractCountByBusinessId(Long businessId); | ||||
|  | ||||
|     /** | ||||
|      * 根据合同编号,获得合同的产品列表 | ||||
|      * | ||||
|      * @param contactId 合同编号 | ||||
|      * @return 产品列表 | ||||
|      */ | ||||
|     List<CrmContractProductDO> getContractProductListByContractId(Long contactId); | ||||
|  | ||||
|     /** | ||||
|      * 获得待审核合同数量 | ||||
|   | ||||
| @@ -10,6 +10,9 @@ import jakarta.validation.Valid; | ||||
|  | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | ||||
|  | ||||
| /** | ||||
|  * 客户 Service 接口 | ||||
| @@ -58,6 +61,16 @@ public interface CrmCustomerService { | ||||
|      */ | ||||
|     List<CrmCustomerDO> getCustomerList(Collection<Long> ids); | ||||
|  | ||||
|     /** | ||||
|      * 获得客户 Map | ||||
|      * | ||||
|      * @param ids 客户编号数组 | ||||
|      * @return 客户 Map | ||||
|      */ | ||||
|     default Map<Long, CrmCustomerDO> getCustomerMap(Collection<Long> ids) { | ||||
|         return convertMap(getCustomerList(ids), CrmCustomerDO::getId); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获得客户分页 | ||||
|      * | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV