mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 10:18:42 +08:00 
			
		
		
		
	feat: 客户详情 + review 修改
This commit is contained in:
		| @@ -19,13 +19,12 @@ public enum CrmCustomerLevelEnum implements IntArrayValuable { | |||||||
|     GENERAL(2, "B(普通客户)"), |     GENERAL(2, "B(普通客户)"), | ||||||
|     LOW_PRIORITY(3, "C(非优先客户)"); |     LOW_PRIORITY(3, "C(非优先客户)"); | ||||||
|  |  | ||||||
|     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmCustomerLevelEnum::getStatus).toArray(); |     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmCustomerLevelEnum::getLevel).toArray(); | ||||||
|  |  | ||||||
|     // TODO @wanwan:这里的 status 字段,可以考虑改成 level |  | ||||||
|     /** |     /** | ||||||
|      * 状态 |      * 状态 | ||||||
|      */ |      */ | ||||||
|     private final Integer status; |     private final Integer level; | ||||||
|     /** |     /** | ||||||
|      * 状态名 |      * 状态名 | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -57,6 +57,12 @@ | |||||||
|             <artifactId>yudao-spring-boot-starter-excel</artifactId> |             <artifactId>yudao-spring-boot-starter-excel</artifactId> | ||||||
|         </dependency> |         </dependency> | ||||||
|  |  | ||||||
|  |         <!-- 地址相关 --> | ||||||
|  |         <dependency> | ||||||
|  |             <groupId>cn.iocoder.boot</groupId> | ||||||
|  |             <artifactId>yudao-spring-boot-starter-biz-ip</artifactId> | ||||||
|  |         </dependency> | ||||||
|  |  | ||||||
|         <!-- Test 测试相关 --> |         <!-- Test 测试相关 --> | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>cn.iocoder.boot</groupId> |             <groupId>cn.iocoder.boot</groupId> | ||||||
|   | |||||||
| @@ -1,13 +1,22 @@ | |||||||
| package cn.iocoder.yudao.module.crm.controller.admin.customer; | package cn.iocoder.yudao.module.crm.controller.admin.customer; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.collection.CollUtil; | ||||||
|  | import cn.hutool.core.util.NumberUtil; | ||||||
|  | import cn.hutool.core.util.ObjectUtil; | ||||||
| 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.excel.core.util.ExcelUtils; | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | ||||||
|  | import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; | ||||||
| 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.customer.vo.*; | import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*; | ||||||
| import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert; | import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert; | ||||||
| import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; | import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; | ||||||
| import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; | 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 com.google.common.collect.Lists; | ||||||
| import io.swagger.v3.oas.annotations.Operation; | import io.swagger.v3.oas.annotations.Operation; | ||||||
| import io.swagger.v3.oas.annotations.Parameter; | import io.swagger.v3.oas.annotations.Parameter; | ||||||
| import io.swagger.v3.oas.annotations.tags.Tag; | import io.swagger.v3.oas.annotations.tags.Tag; | ||||||
| @@ -19,7 +28,9 @@ import javax.annotation.Resource; | |||||||
| import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | ||||||
| import javax.validation.Valid; | import javax.validation.Valid; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.util.List; | import java.util.*; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  | import java.util.stream.Stream; | ||||||
|  |  | ||||||
| import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||||||
| import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; | import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; | ||||||
| @@ -33,6 +44,10 @@ public class CrmCustomerController { | |||||||
|  |  | ||||||
|     @Resource |     @Resource | ||||||
|     private CrmCustomerService customerService; |     private CrmCustomerService customerService; | ||||||
|  |     @Resource | ||||||
|  |     private DeptApi deptApi; | ||||||
|  |     @Resource | ||||||
|  |     private AdminUserApi adminUserApi; | ||||||
|  |  | ||||||
|     @PostMapping("/create") |     @PostMapping("/create") | ||||||
|     @Operation(summary = "创建客户") |     @Operation(summary = "创建客户") | ||||||
| @@ -64,7 +79,21 @@ public class CrmCustomerController { | |||||||
|     @PreAuthorize("@ss.hasPermission('crm:customer:query')") |     @PreAuthorize("@ss.hasPermission('crm:customer:query')") | ||||||
|     public CommonResult<CrmCustomerRespVO> getCustomer(@RequestParam("id") Long id) { |     public CommonResult<CrmCustomerRespVO> getCustomer(@RequestParam("id") Long id) { | ||||||
|         CrmCustomerDO customer = customerService.getCustomer(id); |         CrmCustomerDO customer = customerService.getCustomer(id); | ||||||
|         return success(CrmCustomerConvert.INSTANCE.convert(customer)); |         CrmCustomerRespVO customerRespVO = CrmCustomerConvert.INSTANCE.convert(customer); | ||||||
|  |         if (ObjectUtil.isAllNotEmpty(customer, customer.getAreaId())) { | ||||||
|  |             customerRespVO.setAreaName(AreaUtils.format(customer.getAreaId())); | ||||||
|  |         } | ||||||
|  |         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(CollUtil.removeNull(Lists.newArrayList(NumberUtil.parseLong(customerRespVO.getCreator()), customerRespVO.getOwnerUserId()))); | ||||||
|  |         customerRespVO.setCreatorName(Optional.ofNullable(userMap.get(NumberUtil.parseLong(customerRespVO.getCreator()))).map(AdminUserRespDTO::getNickname).orElse(null)); | ||||||
|  |         AdminUserRespDTO ownerUser = userMap.get(customer.getOwnerUserId()); | ||||||
|  |         if (Objects.nonNull(ownerUser)) { | ||||||
|  |             customerRespVO.setOwnerUserName(ownerUser.getNickname()); | ||||||
|  |             DeptRespDTO dept = deptApi.getDept(ownerUser.getDeptId()); | ||||||
|  |             if (Objects.nonNull(dept)) { | ||||||
|  |                 customerRespVO.setOwnerUserDept(dept.getName()); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return success(customerRespVO); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @GetMapping("/page") |     @GetMapping("/page") | ||||||
| @@ -72,7 +101,23 @@ public class CrmCustomerController { | |||||||
|     @PreAuthorize("@ss.hasPermission('crm:customer:query')") |     @PreAuthorize("@ss.hasPermission('crm:customer:query')") | ||||||
|     public CommonResult<PageResult<CrmCustomerRespVO>> getCustomerPage(@Valid CrmCustomerPageReqVO pageVO) { |     public CommonResult<PageResult<CrmCustomerRespVO>> getCustomerPage(@Valid CrmCustomerPageReqVO pageVO) { | ||||||
|         PageResult<CrmCustomerDO> pageResult = customerService.getCustomerPage(pageVO); |         PageResult<CrmCustomerDO> pageResult = customerService.getCustomerPage(pageVO); | ||||||
|         return success(CrmCustomerConvert.INSTANCE.convertPage(pageResult)); |         PageResult<CrmCustomerRespVO> pageVo = CrmCustomerConvert.INSTANCE.convertPage(pageResult); | ||||||
|  |         Set<Long> userSet = pageVo.getList().stream().flatMap(i -> Stream.of(NumberUtil.parseLong(i.getCreator()), i.getOwnerUserId())).collect(Collectors.toSet()); | ||||||
|  |         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userSet); | ||||||
|  |         Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(userMap.values().stream().map(AdminUserRespDTO::getDeptId).collect(Collectors.toSet())); | ||||||
|  |         pageVo.getList().forEach(customerRespVO -> { | ||||||
|  |             customerRespVO.setAreaName(AreaUtils.format(customerRespVO.getAreaId())); | ||||||
|  |             customerRespVO.setCreatorName(Optional.ofNullable(userMap.get(NumberUtil.parseLong(customerRespVO.getCreator()))).map(AdminUserRespDTO::getNickname).orElse(null)); | ||||||
|  |             AdminUserRespDTO ownerUser = userMap.get(customerRespVO.getOwnerUserId()); | ||||||
|  |             if (Objects.nonNull(ownerUser)) { | ||||||
|  |                 customerRespVO.setOwnerUserName(ownerUser.getNickname()); | ||||||
|  |                 DeptRespDTO dept = deptMap.get(ownerUser.getDeptId()); | ||||||
|  |                 if (Objects.nonNull(dept)) { | ||||||
|  |                     customerRespVO.setOwnerUserDept(dept.getName()); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |         return success(pageVo); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @GetMapping("/export-excel") |     @GetMapping("/export-excel") | ||||||
|   | |||||||
| @@ -68,7 +68,7 @@ public class CrmCustomerBaseVO { | |||||||
|     private String remark; |     private String remark; | ||||||
|  |  | ||||||
|     @Schema(description = "地区编号", example = "20158") |     @Schema(description = "地区编号", example = "20158") | ||||||
|     private Long areaId; |     private Integer areaId; | ||||||
|  |  | ||||||
|     @Schema(description = "详细地址", example = "北京市海淀区") |     @Schema(description = "详细地址", example = "北京市海淀区") | ||||||
|     private String detailAddress; |     private String detailAddress; | ||||||
|   | |||||||
| @@ -5,12 +5,16 @@ import lombok.Data; | |||||||
| import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||||
| import lombok.ToString; | import lombok.ToString; | ||||||
|  |  | ||||||
|  | import javax.validation.constraints.NotNull; | ||||||
|  |  | ||||||
| @Schema(description = "管理后台 - CRM 客户创建 Request VO") | @Schema(description = "管理后台 - CRM 客户创建 Request VO") | ||||||
| @Data | @Data | ||||||
| @EqualsAndHashCode(callSuper = true) | @EqualsAndHashCode(callSuper = true) | ||||||
| @ToString(callSuper = true) | @ToString(callSuper = true) | ||||||
| public class CrmCustomerCreateReqVO extends CrmCustomerBaseVO { | public class CrmCustomerCreateReqVO extends CrmCustomerBaseVO { | ||||||
|  |  | ||||||
|     // TODO @wanwan:负责人 |     @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563") | ||||||
|  |     @NotNull(message = "负责人不能为空") | ||||||
|  |     private Long ownerUserId; | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -76,7 +76,7 @@ public class CrmCustomerExcelVO { | |||||||
|     private Long ownerUserId; |     private Long ownerUserId; | ||||||
|  |  | ||||||
|     @ExcelProperty("地区编号") |     @ExcelProperty("地区编号") | ||||||
|     private Long areaId; |     private Integer areaId; | ||||||
|  |  | ||||||
|     @ExcelProperty("详细地址") |     @ExcelProperty("详细地址") | ||||||
|     private String detailAddress; |     private String detailAddress; | ||||||
|   | |||||||
| @@ -18,5 +18,14 @@ public class CrmCustomerPageReqVO extends PageParam { | |||||||
|     @Schema(description = "手机", example = "18000000000") |     @Schema(description = "手机", example = "18000000000") | ||||||
|     private String mobile; |     private String mobile; | ||||||
|  |  | ||||||
|  |     @Schema(description = "所属行业", example = "1") | ||||||
|  |     private Integer industryId; | ||||||
|  |  | ||||||
|  |     @Schema(description = "客户等级", example = "1") | ||||||
|  |     private Integer level; | ||||||
|  |  | ||||||
|  |     @Schema(description = "客户来源", example = "1") | ||||||
|  |     private Integer source; | ||||||
|  |  | ||||||
|     // TODO @芋艿:场景; |     // TODO @芋艿:场景; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -31,6 +31,15 @@ public class CrmCustomerRespVO extends CrmCustomerBaseVO { | |||||||
|     @Schema(description = "负责人的用户编号", example = "25682") |     @Schema(description = "负责人的用户编号", example = "25682") | ||||||
|     private Long ownerUserId; |     private Long ownerUserId; | ||||||
|  |  | ||||||
|  |     @Schema(description = "负责人名字", example = "25682") | ||||||
|  |     private String ownerUserName; | ||||||
|  |  | ||||||
|  |     @Schema(description = "负责人部门") | ||||||
|  |     private String ownerUserDept; | ||||||
|  |  | ||||||
|  |     @Schema(description = "地区名称", example = "北京市") | ||||||
|  |     private String areaName; | ||||||
|  |  | ||||||
|     @Schema(description = "最后跟进时间") |     @Schema(description = "最后跟进时间") | ||||||
|     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||||||
|     private LocalDateTime contactLastTime; |     private LocalDateTime contactLastTime; | ||||||
| @@ -38,4 +47,12 @@ public class CrmCustomerRespVO extends CrmCustomerBaseVO { | |||||||
|     @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) |     @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||||||
|     private LocalDateTime createTime; |     private LocalDateTime createTime; | ||||||
|  |  | ||||||
|  |     @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||||||
|  |     private LocalDateTime updateTime; | ||||||
|  |  | ||||||
|  |     @Schema(description = "创建人") | ||||||
|  |     private String creator; | ||||||
|  |  | ||||||
|  |     @Schema(description = "创建人名字") | ||||||
|  |     private String creatorName; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -96,10 +96,22 @@ public class CrmCustomerDO extends BaseDO { | |||||||
|      * 备注 |      * 备注 | ||||||
|      */ |      */ | ||||||
|     private String remark; |     private String remark; | ||||||
|  |     /** | ||||||
|  |      * 负责人的用户编号 | ||||||
|  |      */ | ||||||
|  |     private Long ownerUserId; | ||||||
|  |     /** | ||||||
|  |      * 只读权限的用户编号数组 | ||||||
|  |      */ | ||||||
|  |     private String roUserIds; | ||||||
|  |     /** | ||||||
|  |      * 读写权限的用户编号数组 | ||||||
|  |      */ | ||||||
|  |     private String rwUserIds; | ||||||
|     /** |     /** | ||||||
|      * 地区编号 |      * 地区编号 | ||||||
|      */ |      */ | ||||||
|     private Long areaId; |     private Integer areaId; | ||||||
|     /** |     /** | ||||||
|      * 详细地址 |      * 详细地址 | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -19,10 +19,12 @@ import java.util.List; | |||||||
| public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> { | public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> { | ||||||
|  |  | ||||||
|     default PageResult<CrmCustomerDO> selectPage(CrmCustomerPageReqVO reqVO) { |     default PageResult<CrmCustomerDO> selectPage(CrmCustomerPageReqVO reqVO) { | ||||||
|         // TODO @Wanwan 填充负责人,所属部门字段;这个可以在 controller 填哈; |  | ||||||
|         return selectPage(reqVO, new LambdaQueryWrapperX<CrmCustomerDO>() |         return selectPage(reqVO, new LambdaQueryWrapperX<CrmCustomerDO>() | ||||||
|                 .likeIfPresent(CrmCustomerDO::getName, reqVO.getName()) |                 .likeIfPresent(CrmCustomerDO::getName, reqVO.getName()) | ||||||
|                 .eqIfPresent(CrmCustomerDO::getMobile, reqVO.getMobile()) |                 .eqIfPresent(CrmCustomerDO::getMobile, reqVO.getMobile()) | ||||||
|  |                 .eqIfPresent(CrmCustomerDO::getIndustryId, reqVO.getIndustryId()) | ||||||
|  |                 .eqIfPresent(CrmCustomerDO::getLevel, reqVO.getLevel()) | ||||||
|  |                 .eqIfPresent(CrmCustomerDO::getSource, reqVO.getSource()) | ||||||
|                 .orderByDesc(CrmCustomerDO::getId)); |                 .orderByDesc(CrmCustomerDO::getId)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -46,14 +46,6 @@ public interface CrmCustomerService { | |||||||
|      */ |      */ | ||||||
|     CrmCustomerDO getCustomer(Long id); |     CrmCustomerDO getCustomer(Long id); | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 获得客户列表 |  | ||||||
|      * |  | ||||||
|      * @param ids 编号 |  | ||||||
|      * @return 客户列表 |  | ||||||
|      */ |  | ||||||
|     List<CrmCustomerDO> getCustomerList(Collection<Long> ids); |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 获得客户分页 |      * 获得客户分页 | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -37,8 +37,6 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | |||||||
|     @Resource |     @Resource | ||||||
|     private CrmCustomerMapper customerMapper; |     private CrmCustomerMapper customerMapper; | ||||||
|     @Resource |     @Resource | ||||||
|     private DeptApi deptApi; // TODO @wanwan:拼接数据,可以放到 controller;所以这里的引入,可以考虑放到 controller 哈; |  | ||||||
|     @Resource |  | ||||||
|     private CrmPermissionService crmPermissionService; |     private CrmPermissionService crmPermissionService; | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
| @@ -93,14 +91,6 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | |||||||
|         return customerMapper.selectById(id); |         return customerMapper.selectById(id); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public List<CrmCustomerDO> getCustomerList(Collection<Long> ids) { |  | ||||||
|         if (CollUtil.isEmpty(ids)) { |  | ||||||
|             return ListUtil.empty(); |  | ||||||
|         } |  | ||||||
|         return customerMapper.selectBatchIds(ids); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public PageResult<CrmCustomerDO> getCustomerPage(CrmCustomerPageReqVO pageReqVO) { |     public PageResult<CrmCustomerDO> getCustomerPage(CrmCustomerPageReqVO pageReqVO) { | ||||||
|         // TODO 芋艿:数据权限,是否可以查询到; |         // TODO 芋艿:数据权限,是否可以查询到; | ||||||
| @@ -112,8 +102,6 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | |||||||
|         return customerMapper.selectList(exportReqVO); |         return customerMapper.selectList(exportReqVO); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // TODO wanwan:service 接口已经注释,实现类就不需要了。 |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 校验客户是否存在 |      * 校验客户是否存在 | ||||||
|      * |      * | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Wanwan
					Wanwan