mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 18:28:43 +08:00 
			
		
		
		
	crm联系人review修改,新增地区字段
This commit is contained in:
		| @@ -1 +1,30 @@ | ||||
| SET NAMES utf8mb4; | ||||
| -- `ruoyi-vue-pro`.crm_contact definition | ||||
|  | ||||
| CREATE TABLE `crm_contact` ( | ||||
|                                `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', | ||||
|                                `name` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '联系人名称', | ||||
|                                `next_time` datetime DEFAULT NULL COMMENT '下次联系时间', | ||||
|                                `mobile` varchar(16) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '手机号', | ||||
|                                `telephone` varchar(16) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '电话', | ||||
|                                `email` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '电子邮箱', | ||||
|                                `post` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '职务', | ||||
|                                `customer_id` bigint(20) DEFAULT NULL COMMENT '客户编号', | ||||
|                                `address` varchar(256) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '地址', | ||||
|                                `remark` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注', | ||||
|                                `creator` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建人', | ||||
|                                `owner_user_id` varchar(256) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '负责人用户编号', | ||||
|                                `create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间', | ||||
|                                `update_time` timestamp NULL DEFAULT NULL COMMENT '更新时间', | ||||
|                                `last_time` timestamp NULL DEFAULT NULL COMMENT '最后跟进时间', | ||||
|                                `updater` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '更新人', | ||||
|                                `deleted` bit(1) NOT NULL DEFAULT b'0', | ||||
|                                `tenant_id` bigint(20) DEFAULT NULL, | ||||
|                                `parent_id` bigint(20) DEFAULT NULL COMMENT '直系上属', | ||||
|                                `qq` int(11) DEFAULT NULL, | ||||
|                                `wechat` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL, | ||||
|                                `sex` int(11) DEFAULT NULL COMMENT '性别', | ||||
|                                `master` bit(1) DEFAULT NULL COMMENT '是否关键决策人', | ||||
|                                `area_id` bigint(20) DEFAULT NULL COMMENT '地区', | ||||
|                                PRIMARY KEY (`id`) USING BTREE | ||||
| ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='CRM 联系人'; | ||||
| @@ -0,0 +1,5 @@ | ||||
| package cn.iocoder.yudao.module.crm.enums.contact; | ||||
|  | ||||
| public class ContactConstants { | ||||
|     public static final String MULTIPLE_SPLIT = ","; | ||||
| } | ||||
| @@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerExpor | ||||
| import cn.iocoder.yudao.module.crm.convert.contact.ContactConvert; | ||||
| import cn.iocoder.yudao.module.crm.dal.dataobject.contact.ContactDO; | ||||
| import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; | ||||
| import cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants; | ||||
| import cn.iocoder.yudao.module.crm.service.contact.ContactService; | ||||
| import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; | ||||
| import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | ||||
| @@ -19,6 +20,7 @@ import com.google.common.collect.Lists; | ||||
| import io.swagger.v3.oas.annotations.Operation; | ||||
| import io.swagger.v3.oas.annotations.Parameter; | ||||
| import io.swagger.v3.oas.annotations.tags.Tag; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.springframework.security.access.prepost.PreAuthorize; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| @@ -26,12 +28,13 @@ import org.springframework.web.bind.annotation.*; | ||||
| import javax.annotation.Resource; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| import javax.validation.Valid; | ||||
| import javax.validation.constraints.NotNull; | ||||
| import java.io.IOException; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Optional; | ||||
| import java.util.*; | ||||
| import java.util.stream.Collectors; | ||||
| import java.util.stream.Stream; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||||
| 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.security.core.util.SecurityFrameworkUtils.getLoginUserId; | ||||
| @@ -41,6 +44,7 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti | ||||
| @RestController | ||||
| @RequestMapping("/crm/contact") | ||||
| @Validated | ||||
| @Slf4j | ||||
| public class ContactController { | ||||
|  | ||||
|     @Resource | ||||
| @@ -82,23 +86,25 @@ public class ContactController { | ||||
|     @PreAuthorize("@ss.hasPermission('crm:contact:query')") | ||||
|     public CommonResult<ContactRespVO> getContact(@RequestParam("id") Long id) { | ||||
|         ContactDO contact = contactService.getContact(id); | ||||
|         // TODO @zyna:需要考虑 null 的情况; | ||||
|         ContactRespVO contactRespVO  = ContactConvert.INSTANCE.convert(contact); | ||||
|         // TODO @zyna:可以把数据读完后,convert 统一交给 ContactConvert,让 controller 更简洁;而 convert 专门去做一些转换逻辑 | ||||
|         if(contact == null){ | ||||
|             throw exception(ErrorCodeConstants.CONTACT_NOT_EXISTS); | ||||
|         } | ||||
|         //1.获取用户名 | ||||
|         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(CollUtil.removeNull(Lists.newArrayList( | ||||
|                 NumberUtil.parseLong(contact.getCreator())))); | ||||
|         contactRespVO.setCreatorName(Optional.ofNullable(userMap.get(NumberUtil.parseLong(contact.getCreator()))).map(AdminUserRespDTO::getNickname).orElse(null)); | ||||
|         contactRespVO.setCustomerName(Optional.ofNullable(crmCustomerService.getCustomer(contact.getCustomerId())).map(CrmCustomerDO::getName).orElse(null)); | ||||
|                 NumberUtil.parseLong(contact.getCreator()),contact.getOwnerUserId()))); | ||||
|         //2.获取客户信息 | ||||
|         List<CrmCustomerDO> crmCustomerDOList = crmCustomerService.getCustomerList(Collections.singletonList(contact.getCustomerId())); | ||||
|         //3.直属上级 | ||||
|         List<ContactDO> contactList = contactService.getContactList(Collections.singletonList(contact.getParentId())); | ||||
|         ContactRespVO contactRespVO  = ContactConvert.INSTANCE.convert(contact,userMap,crmCustomerDOList,contactList); | ||||
|         return success(contactRespVO); | ||||
|     } | ||||
|  | ||||
|     // TODO @zyna:url 使用中划线噢;然后,单词的拼写也要注意呀,AllList 是不是更好呀; | ||||
|     @GetMapping("/simpleAlllist") | ||||
|     @GetMapping("/simple-all-list") | ||||
|     @Operation(summary = "获得联系人列表") | ||||
|     @PreAuthorize("@ss.hasPermission('crm:contact:query')") | ||||
|     public CommonResult<List<ContactSimpleRespVO>> simpleAlllist() { | ||||
|         // TODO @zyna:方法名改成,getContactList;方法命名,要动名词,get 动词;all 可以去掉,因为没条件,自然是全部 | ||||
|         List<ContactDO> list = contactService.allContactList(); | ||||
|         List<ContactDO> list = contactService.getContactList(); | ||||
|         return success(ContactConvert.INSTANCE.convertAllList(list)); | ||||
|     } | ||||
|  | ||||
| @@ -107,16 +113,10 @@ public class ContactController { | ||||
|     @PreAuthorize("@ss.hasPermission('crm:contact:query')") | ||||
|     public CommonResult<PageResult<ContactRespVO>> getContactPage(@Valid ContactPageReqVO pageVO) { | ||||
|         PageResult<ContactDO> pageData = contactService.getContactPage(pageVO); | ||||
|         PageResult<ContactRespVO> pageResult =ContactConvert.INSTANCE.convertPage(pageData); | ||||
|         // TODO @zyna:需要考虑 null 的情况; | ||||
|         // TODO @zyna:可以把数据读完后,convert 统一交给 ContactConvert,让 controller 更简洁;而 convert 专门去做一些转换逻辑 | ||||
|         //待接口实现后修改 | ||||
|         List<CrmCustomerDO> crmCustomerDOList = crmCustomerService.getCustomerList(new CrmCustomerExportReqVO()); | ||||
|         Map<Long,CrmCustomerDO> crmCustomerDOMap = crmCustomerDOList.stream().collect(Collectors.toMap(CrmCustomerDO::getId,v->v)); | ||||
|         pageResult.getList().forEach(item -> { | ||||
|             item.setCustomerName(Optional.ofNullable(crmCustomerDOMap.get(item.getCustomerId())).map(CrmCustomerDO::getName).orElse(null)); | ||||
|         }); | ||||
|         return success(pageResult); | ||||
|         List<ContactRespVO>  contactRespVOList = convertFieldValue2Name(pageData.getList()); | ||||
|         PageResult<ContactRespVO> pageDataReturn = ContactConvert.INSTANCE.convertPage(pageData); | ||||
|         pageDataReturn.setList(contactRespVOList); | ||||
|         return success(pageDataReturn); | ||||
|     } | ||||
|  | ||||
|     // TODO @zyna:可以看下新的导出写法,这里调整下 | ||||
| @@ -124,12 +124,30 @@ public class ContactController { | ||||
|     @Operation(summary = "导出联系人 Excel") | ||||
|     @PreAuthorize("@ss.hasPermission('crm:contact:export')") | ||||
|     @OperateLog(type = EXPORT) | ||||
|     public void exportContactExcel(@Valid ContactExportReqVO exportReqVO, | ||||
|     public void exportContactExcel(@Valid ContactPageReqVO exportReqVO, | ||||
|               HttpServletResponse response) throws IOException { | ||||
|         List<ContactDO> list = contactService.getContactList(exportReqVO); | ||||
|         // 导出 Excel | ||||
|         List<ContactExcelVO> datas = ContactConvert.INSTANCE.convertList02(list); | ||||
|         ExcelUtils.write(response, "crm联系人.xls", "数据", ContactExcelVO.class, datas); | ||||
|         List<ContactRespVO>  contactRespVOList = convertFieldValue2Name(list); | ||||
|         ExcelUtils.write(response, "crm联系人.xls", "数据", ContactRespVO.class, contactRespVOList); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 翻译字段名称 | ||||
|      * @param contactDOList 联系人List | ||||
|      * @return List<ContactRespVO> | ||||
|      */ | ||||
|     private List<ContactRespVO> convertFieldValue2Name(List<ContactDO> contactDOList){ | ||||
|         //1.获取客户列表 | ||||
|         List<Long> customerIdList = contactDOList.stream().map(ContactDO::getCustomerId).distinct().collect(Collectors.toList()); | ||||
|         List<CrmCustomerDO> crmCustomerDOList = crmCustomerService.getCustomerList(customerIdList); | ||||
|         //2.获取创建人、责任人列表 | ||||
|         List<Long> userIdsList =  contactDOList.stream().flatMap(item-> Stream.of(Long.parseLong(item.getCreator()),item.getOwnerUserId()).distinct()).collect(Collectors.toList()); | ||||
|         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIdsList); | ||||
|         //3.直属上级 | ||||
|         List<Long> contactIdsList =  contactDOList.stream().map(ContactDO::getParentId).distinct().collect(Collectors.toList()); | ||||
|         List<ContactDO> contactList = contactService.getContactList(contactIdsList); | ||||
|         List<ContactRespVO> pageResult =ContactConvert.INSTANCE.converList(contactDOList,userMap,crmCustomerDOList,contactList); | ||||
|         return pageResult; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,9 +1,18 @@ | ||||
| package cn.iocoder.yudao.module.crm.controller.admin.contact.vo; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.validation.Mobile; | ||||
| import cn.iocoder.yudao.framework.common.validation.Telephone; | ||||
| import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; | ||||
| import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; | ||||
| import com.alibaba.excel.annotation.ExcelIgnore; | ||||
| import com.alibaba.excel.annotation.ExcelProperty; | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
| import lombok.Data; | ||||
| import org.apache.skywalking.apm.toolkit.trace.IgnoredException; | ||||
| import org.springframework.format.annotation.DateTimeFormat; | ||||
|  | ||||
| import javax.validation.constraints.Email; | ||||
| import javax.validation.constraints.NotNull; | ||||
| import java.time.LocalDateTime; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; | ||||
| @@ -17,57 +26,83 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ | ||||
| @Data | ||||
| public class ContactBaseVO { | ||||
|  | ||||
|     // TODO @zyna:example 最好都写下 | ||||
|     // TODO @zyna:必要的字段校验,例如说 @Mobile,@Emal 等等 | ||||
|  | ||||
|     @Schema(description = "下次联系时间") | ||||
|     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) | ||||
|     private LocalDateTime nextTime; | ||||
|  | ||||
|     @Schema(description = "手机号") | ||||
|     private String mobile; | ||||
|  | ||||
|     @Schema(description = "电话") | ||||
|     private String telephone; | ||||
|  | ||||
|     @Schema(description = "电子邮箱") | ||||
|     private String email; | ||||
|     @ExcelProperty(value = "姓名",order = 1) | ||||
|     @Schema(description = "姓名", example = "芋艿") | ||||
|     @NotNull(message = "姓名不能为空") | ||||
|     private String name; | ||||
|  | ||||
|     @Schema(description = "客户编号", example = "10795") | ||||
|     @ExcelIgnore | ||||
|     private Long customerId; | ||||
|  | ||||
|     @ExcelProperty(value = "性别",converter = DictConvert.class ,order = 3) | ||||
|     @DictFormat(cn.iocoder.yudao.module.system.enums.DictTypeConstants.USER_SEX) | ||||
|     @Schema(description = "性别") | ||||
|     private Integer sex; | ||||
|  | ||||
|     @Schema(description = "职位") | ||||
|     @ExcelProperty(value = "职位",order = 3) | ||||
|     private String post; | ||||
|  | ||||
|     @Schema(description = "是否关键决策人") | ||||
|     @ExcelProperty(value = "是否关键决策人",converter = DictConvert.class,order = 3) | ||||
|     @DictFormat(cn.iocoder.yudao.module.system.enums.DictTypeConstants.INFRA_BOOLEAN_STRING) | ||||
|     private Boolean master; | ||||
|  | ||||
|     @Schema(description = "直属上级", example = "23457") | ||||
|     @ExcelIgnore | ||||
|     private Long parentId; | ||||
|  | ||||
|  | ||||
|     @Schema(description = "手机号",example = "1387171766") | ||||
|     @Mobile | ||||
|     @ExcelProperty(value = "手机号",order = 4) | ||||
|     private String mobile; | ||||
|  | ||||
|     @Schema(description = "座机",example = "021-0029922") | ||||
|     @Telephone | ||||
|     @ExcelProperty(value = "座机",order = 4) | ||||
|     private String telephone; | ||||
|  | ||||
|     @ExcelProperty(value = "QQ",order = 4) | ||||
|     @Schema(description = "QQ",example = "197272662") | ||||
|     private Long qq; | ||||
|  | ||||
|     @ExcelProperty(value = "微信",order = 4) | ||||
|     @Schema(description = "微信",example = "zzz3883") | ||||
|     private String wechat; | ||||
|  | ||||
|     @Schema(description = "电子邮箱",example = "1111@22.com") | ||||
|     @Email | ||||
|     @ExcelProperty(value = "邮箱",order = 4) | ||||
|     private String email; | ||||
|  | ||||
|     @ExcelProperty(value = "地址",order = 5) | ||||
|     @Schema(description = "地址") | ||||
|     private String address; | ||||
|  | ||||
|     @Schema(description = "下次联系时间") | ||||
|     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) | ||||
|     @ExcelProperty(value = "下次联系时间",order = 6) | ||||
|     private LocalDateTime nextTime; | ||||
|  | ||||
|     @Schema(description = "备注", example = "你说的对") | ||||
|     @ExcelProperty(value = "备注",order = 6) | ||||
|     private String remark; | ||||
|  | ||||
|     @Schema(description = "最后跟进时间") | ||||
|     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||||
|     @ExcelProperty(value = "最后跟进时间",order = 6) | ||||
|     private LocalDateTime lastTime; | ||||
|  | ||||
|     @Schema(description = "直属上级", example = "23457") | ||||
|     private Long parentId; | ||||
|  | ||||
|     @Schema(description = "姓名", example = "芋艿") | ||||
|     private String name; | ||||
|  | ||||
|     @Schema(description = "职位") | ||||
|     private String post; | ||||
|  | ||||
|     @Schema(description = "QQ") | ||||
|     private Long qq; | ||||
|  | ||||
|     @Schema(description = "微信") | ||||
|     private String webchat; | ||||
|  | ||||
|     @Schema(description = "性别") | ||||
|     private Integer sex; | ||||
|  | ||||
|     @Schema(description = "是否关键决策人") | ||||
|     private Boolean policyMakers; | ||||
|  | ||||
|     @Schema(description = "负责人用户编号", example = "14334") | ||||
|     private String ownerUserId; | ||||
|     @NotNull(message = "负责人不能为空") | ||||
|     @ExcelIgnore | ||||
|     private Long ownerUserId; | ||||
|  | ||||
|     @Schema(description = "地区编号", example = "20158") | ||||
|     @ExcelIgnore | ||||
|     private Integer areaId; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,72 +0,0 @@ | ||||
| package cn.iocoder.yudao.module.crm.controller.admin.contact.vo; | ||||
|  | ||||
| import com.alibaba.excel.annotation.ExcelProperty; | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
|  | ||||
| // TODO @zyna:参考新的 VO 结构,把 ContactExcelVO 融合到 ContactRespVO 中 | ||||
| /** | ||||
|  * crm联系人 Excel VO | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| @Data | ||||
| @Deprecated | ||||
| public class ContactExcelVO { | ||||
|  | ||||
|     @ExcelProperty("下次联系时间") | ||||
|     private LocalDateTime nextTime; | ||||
|  | ||||
|     @ExcelProperty("手机号") | ||||
|     private String mobile; | ||||
|  | ||||
|     @ExcelProperty("电话") | ||||
|     private String telephone; | ||||
|  | ||||
|     @ExcelProperty("电子邮箱") | ||||
|     private String email; | ||||
|  | ||||
|     @ExcelProperty("客户编号") | ||||
|     private Long customerId; | ||||
|  | ||||
|     @ExcelProperty("地址") | ||||
|     private String address; | ||||
|  | ||||
|     @ExcelProperty("备注") | ||||
|     private String remark; | ||||
|  | ||||
|     @ExcelProperty("创建时间") | ||||
|     private LocalDateTime createTime; | ||||
|  | ||||
|     @ExcelProperty("最后跟进时间") | ||||
|     private LocalDateTime lastTime; | ||||
|  | ||||
|     @ExcelProperty("主键") | ||||
|     private Long id; | ||||
|  | ||||
|     @ExcelProperty("直属上级") | ||||
|     private Long parentId; | ||||
|  | ||||
|     @ExcelProperty("姓名") | ||||
|     private String name; | ||||
|  | ||||
|     @ExcelProperty("职位") | ||||
|     private String post; | ||||
|  | ||||
|     @ExcelProperty("QQ") | ||||
|     private Long qq; | ||||
|  | ||||
|     @ExcelProperty("微信") | ||||
|     private String webchat; | ||||
|  | ||||
|     @ExcelProperty("性别") | ||||
|     private Integer sex; | ||||
|  | ||||
|     @ExcelProperty("是否关键决策人") | ||||
|     private Boolean policyMakers; | ||||
|  | ||||
|     @ExcelProperty("负责人用户编号") | ||||
|     private String ownerUserId; | ||||
|  | ||||
| } | ||||
| @@ -1,71 +0,0 @@ | ||||
| package cn.iocoder.yudao.module.crm.controller.admin.contact.vo; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
| import lombok.Data; | ||||
| 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; | ||||
|  | ||||
| // TODO @zyna:参考新的 VO 结构,使用 ContactPageReqVO 查询导出的数据 | ||||
| @Schema(description = "管理后台 - crm联系人 Excel 导出 Request VO,参数和 ContactPageReqVO 是一致的") | ||||
| @Data | ||||
| @Deprecated | ||||
| public class ContactExportReqVO { | ||||
|  | ||||
|     @Schema(description = "下次联系时间") | ||||
|     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||||
|     private LocalDateTime[] nextTime; | ||||
|  | ||||
|     @Schema(description = "手机号") | ||||
|     private String mobile; | ||||
|  | ||||
|     @Schema(description = "电话") | ||||
|     private String telephone; | ||||
|  | ||||
|     @Schema(description = "电子邮箱") | ||||
|     private String email; | ||||
|  | ||||
|     @Schema(description = "客户编号", example = "10795") | ||||
|     private Long customerId; | ||||
|  | ||||
|     @Schema(description = "地址") | ||||
|     private String address; | ||||
|  | ||||
|     @Schema(description = "备注", example = "你说的对") | ||||
|     private String remark; | ||||
|  | ||||
|     @Schema(description = "创建时间") | ||||
|     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||||
|     private LocalDateTime[] createTime; | ||||
|  | ||||
|     @Schema(description = "最后跟进时间") | ||||
|     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||||
|     private LocalDateTime[] lastTime; | ||||
|  | ||||
|     @Schema(description = "直属上级", example = "23457") | ||||
|     private Long parentId; | ||||
|  | ||||
|     @Schema(description = "姓名", example = "芋艿") | ||||
|     private String name; | ||||
|  | ||||
|     @Schema(description = "职位") | ||||
|     private String post; | ||||
|  | ||||
|     @Schema(description = "QQ") | ||||
|     private Long qq; | ||||
|  | ||||
|     @Schema(description = "微信") | ||||
|     private String webchat; | ||||
|  | ||||
|     @Schema(description = "性别") | ||||
|     private Integer sex; | ||||
|  | ||||
|     @Schema(description = "是否关键决策人") | ||||
|     private Boolean policyMakers; | ||||
|  | ||||
|     @Schema(description = "负责人用户编号", example = "14334") | ||||
|     private String ownerUserId; | ||||
|  | ||||
| } | ||||
| @@ -26,13 +26,13 @@ public class ContactPageReqVO extends PageParam { | ||||
|     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||||
|     private LocalDateTime[] nextTime; | ||||
|  | ||||
|     @Schema(description = "手机号") | ||||
|     @Schema(description = "手机号",example = "13898273941") | ||||
|     private String mobile; | ||||
|  | ||||
|     @Schema(description = "电话") | ||||
|     @Schema(description = "电话",example = "021-383773") | ||||
|     private String telephone; | ||||
|  | ||||
|     @Schema(description = "电子邮箱") | ||||
|     @Schema(description = "电子邮箱",example = "111@22.com") | ||||
|     private String email; | ||||
|  | ||||
|     @Schema(description = "客户编号", example = "10795") | ||||
| @@ -61,19 +61,19 @@ public class ContactPageReqVO extends PageParam { | ||||
|     @Schema(description = "职位") | ||||
|     private String post; | ||||
|  | ||||
|     @Schema(description = "QQ") | ||||
|     @Schema(description = "QQ",example = "3882872") | ||||
|     private Long qq; | ||||
|  | ||||
|     @Schema(description = "微信") | ||||
|     private String webchat; | ||||
|     @Schema(description = "微信",example = "zzZ98373") | ||||
|     private String wechat; | ||||
|  | ||||
|     @Schema(description = "性别") | ||||
|     private Integer sex; | ||||
|  | ||||
|     @Schema(description = "是否关键决策人") | ||||
|     private Boolean policyMakers; | ||||
|     private Boolean master; | ||||
|  | ||||
|     @Schema(description = "负责人用户编号", example = "14334") | ||||
|     private String ownerUserId; | ||||
|     private Long ownerUserId; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| package cn.iocoder.yudao.module.crm.controller.admin.contact.vo; | ||||
|  | ||||
| import com.alibaba.excel.annotation.ExcelIgnore; | ||||
| import com.alibaba.excel.annotation.ExcelProperty; | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
| import lombok.*; | ||||
| import java.time.LocalDateTime; | ||||
| @@ -11,17 +13,34 @@ import java.time.LocalDateTime; | ||||
| public class ContactRespVO extends ContactBaseVO { | ||||
|  | ||||
|     @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167") | ||||
|     @ExcelIgnore | ||||
|     private Long id; | ||||
|  | ||||
|     @Schema(description = "创建时间") | ||||
|     @ExcelProperty(value = "创建时间",order = 8) | ||||
|     private LocalDateTime createTime; | ||||
|  | ||||
|     // TODO  @zyna:example 最好写下; | ||||
|     @Schema(description = "创建人", example = "25682") | ||||
|     @ExcelIgnore | ||||
|     private String creator; | ||||
|  | ||||
|     @Schema(description = "创建人") | ||||
|     @Schema(description = "创建人名字", example = "test") | ||||
|     @ExcelProperty(value = "创建人",order = 8) | ||||
|     private String creatorName; | ||||
|  | ||||
|     @Schema(description = "客户名字") | ||||
|     @ExcelProperty(value = "客户名称",order = 2) | ||||
|     @Schema(description = "客户名字", example = "test") | ||||
|     private String customerName; | ||||
|  | ||||
|     @Schema(description = "负责人", example = "test") | ||||
|     @ExcelProperty(value = "负责人",order = 7) | ||||
|     private String ownerUserName; | ||||
|  | ||||
|     @Schema(description = "直属上级名",example = "芋头") | ||||
|     @ExcelProperty(value = "直属上级",order = 4) | ||||
|     private String parentName; | ||||
|  | ||||
|     @Schema(description = "地区名",example = "上海上海市浦东新区") | ||||
|     @ExcelProperty(value = "地区",order = 5) | ||||
|     private String areaName; | ||||
| } | ||||
|   | ||||
| @@ -179,5 +179,12 @@ public class CrmCustomerController { | ||||
|         customerService.distributeCustomer(ids, ownerUserId); | ||||
|         return success(true); | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/query-all-list") | ||||
|     @Operation(summary = "查询客户列表") | ||||
|     @PreAuthorize("@ss.hasPermission('crm:customer:all')") | ||||
|     public CommonResult<List<CrmCustomerQueryAllRespVO>> queryAll(){ | ||||
|         List<CrmCustomerDO> crmCustomerDOList = customerService.getCustomerList(); | ||||
|         List<CrmCustomerQueryAllRespVO> data = CrmCustomerConvert.INSTANCE.convertQueryAll(crmCustomerDOList); | ||||
|         return success(data); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,15 @@ | ||||
| package cn.iocoder.yudao.module.crm.controller.admin.customer.vo; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
| import lombok.Data; | ||||
|  | ||||
|  | ||||
| @Schema(description = "管理后台 - CRM 全部客户 Response VO") | ||||
| @Data | ||||
| public class CrmCustomerQueryAllRespVO{ | ||||
|     @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") | ||||
|     private String name; | ||||
|     @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563") | ||||
|     private Long id; | ||||
|  | ||||
| } | ||||
| @@ -1,15 +1,21 @@ | ||||
| package cn.iocoder.yudao.module.crm.convert.contact; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||
| 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.ContactDO; | ||||
| import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; | ||||
| 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.Mappings; | ||||
| import org.mapstruct.factory.Mappers; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; | ||||
|  | ||||
| /** | ||||
|  * crm联系人 Convert | ||||
| @@ -31,8 +37,6 @@ public interface ContactConvert { | ||||
|  | ||||
|     PageResult<ContactRespVO> convertPage(PageResult<ContactDO> page); | ||||
|  | ||||
|     List<ContactExcelVO> convertList02(List<ContactDO> list); | ||||
|  | ||||
|     List<ContactSimpleRespVO> convertAllList(List<ContactDO> list); | ||||
|  | ||||
|     @Mappings({ | ||||
| @@ -41,4 +45,46 @@ public interface ContactConvert { | ||||
|     }) | ||||
|     CrmPermissionTransferReqBO convert(CrmContactTransferReqVO reqVO, Long userId); | ||||
|  | ||||
|     /** | ||||
|      * 详情信息 | ||||
|      * @param contactDO 联系人 | ||||
|      * @param userMap 用户列表 | ||||
|      * @param crmCustomerDOList 客户 | ||||
|      * @return ContactRespVO | ||||
|      */ | ||||
|     default  ContactRespVO convert(ContactDO contactDO, Map<Long, AdminUserRespDTO> userMap, List<CrmCustomerDO> crmCustomerDOList, | ||||
|                                    List<ContactDO> contactList) { | ||||
|         ContactRespVO contactRespVO = convert(contactDO); | ||||
|         setUserInfo(contactRespVO,userMap); | ||||
|         Map<Long,CrmCustomerDO> crmCustomerDOMap = crmCustomerDOList.stream().collect(Collectors.toMap(CrmCustomerDO::getId,v->v)); | ||||
|         Map<Long,ContactDO> contactDOMap = contactList.stream().collect(Collectors.toMap(ContactDO::getId,v->v)); | ||||
|         findAndThen(crmCustomerDOMap,contactDO.getCustomerId(),customer -> {contactRespVO.setCustomerName(customer.getName());}); | ||||
|         findAndThen(contactDOMap,contactDO.getParentId(),contactDOInner -> {contactRespVO.setParentName(contactDOInner.getName());}); | ||||
|         return contactRespVO; | ||||
|     } | ||||
|     default  List<ContactRespVO> converList(List<ContactDO> contactDOList, Map<Long, AdminUserRespDTO> userMap, | ||||
|                                                    List<CrmCustomerDO> crmCustomerDOList , List<ContactDO> contactList){ | ||||
|         List<ContactRespVO> result = convertList(contactDOList); | ||||
|         Map<Long,ContactDO> contactMap = contactList.stream().collect(Collectors.toMap(ContactDO::getId,v->v)); | ||||
|         Map<Long,CrmCustomerDO> customerMap = crmCustomerDOList.stream().collect(Collectors.toMap(CrmCustomerDO::getId,v->v)); | ||||
|         result.forEach(item -> { | ||||
|             setUserInfo(item, userMap); | ||||
|             findAndThen(customerMap,item.getCustomerId(),customer -> {item.setCustomerName(customer.getName());}); | ||||
|             findAndThen(contactMap,item.getParentId(),contactDO -> {item.setParentName(contactDO.getName());}); | ||||
|         }); | ||||
|         return result; | ||||
|     } | ||||
|     /** | ||||
|      * 设置用户信息 | ||||
|      * | ||||
|      * @param contactRespVO  联系人Response VO | ||||
|      * @param userMap 用户信息 map | ||||
|      */ | ||||
|     static void setUserInfo(ContactRespVO contactRespVO, Map<Long, AdminUserRespDTO> userMap){ | ||||
|         contactRespVO.setAreaName(AreaUtils.format(contactRespVO.getAreaId())); | ||||
|         findAndThen(userMap, contactRespVO.getOwnerUserId(), user -> { | ||||
|             contactRespVO.setOwnerUserName(user == null?"":user.getNickname()); | ||||
|         }); | ||||
|         findAndThen(userMap, Long.parseLong(contactRespVO.getCreator()), user -> contactRespVO.setCreatorName(user.getNickname())); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -82,4 +82,6 @@ public interface CrmCustomerConvert { | ||||
|  | ||||
|     CrmCustomerPoolConfigDO convert(CrmCustomerPoolConfigSaveReqVO updateReqVO); | ||||
|  | ||||
|     CrmCustomerQueryAllRespVO convertQueryAll(CrmCustomerDO crmCustomerDO); | ||||
|     List<CrmCustomerQueryAllRespVO> convertQueryAll(List<CrmCustomerDO> crmCustomerDO); | ||||
| } | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||||
| import com.baomidou.mybatisplus.annotation.KeySequence; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
| import lombok.*; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
| @@ -22,8 +23,11 @@ import java.time.LocalDateTime; | ||||
| @NoArgsConstructor | ||||
| @AllArgsConstructor | ||||
| public class ContactDO extends BaseDO { | ||||
|  | ||||
|     // TODO @zyna:这个字段的顺序,是不是整理下; | ||||
|     /** | ||||
|      * 主键 | ||||
|      */ | ||||
|     @TableId | ||||
|     private Long id; | ||||
|     /** | ||||
|      * 下次联系时间 | ||||
|      */ | ||||
| @@ -56,15 +60,8 @@ public class ContactDO extends BaseDO { | ||||
|      * 最后跟进时间 | ||||
|      */ | ||||
|     private LocalDateTime lastTime; | ||||
|     // TODO @zyna:这个放在最前面吧 | ||||
|     /** | ||||
|      * 主键 | ||||
|      */ | ||||
|     @TableId | ||||
|     private Long id; | ||||
|     // TODO @zyna:直接上级,最好写下它关联的字段,例如说这个,应该关联 ContactDO 的 id 字段 | ||||
|     /** | ||||
|      * 直属上级 | ||||
|      * 直属上级 @link ContactDO#id | ||||
|      */ | ||||
|     private Long parentId; | ||||
|     /** | ||||
| @@ -79,25 +76,23 @@ public class ContactDO extends BaseDO { | ||||
|      * QQ | ||||
|      */ | ||||
|     private Long qq; | ||||
|     // TODO @zyna:wechat | ||||
|     /** | ||||
|      * 微信 | ||||
|      */ | ||||
|     private String webchat; | ||||
|     // TODO @zyna:关联的枚举 | ||||
|     private String wechat; | ||||
|     /** | ||||
|      * 性别 | ||||
|      * @See 字典配置 | ||||
|      */ | ||||
|     private Integer sex; | ||||
|     // TODO @zyna:这个字段改成 master 哈; | ||||
|     /** | ||||
|      * 是否关键决策人 | ||||
|      */ | ||||
|     private Boolean policyMakers; | ||||
|     // TODO @zyna:应该是 Long | ||||
|     private Boolean master; | ||||
|     /** | ||||
|      * 负责人用户编号 | ||||
|      */ | ||||
|     private String ownerUserId; | ||||
|     private Long ownerUserId; | ||||
|  | ||||
|     private Integer areaId; | ||||
| } | ||||
|   | ||||
| @@ -32,14 +32,14 @@ public interface ContactMapper extends BaseMapperX<ContactDO> { | ||||
|                 .likeIfPresent(ContactDO::getName, reqVO.getName()) | ||||
|                 .eqIfPresent(ContactDO::getPost, reqVO.getPost()) | ||||
|                 .eqIfPresent(ContactDO::getQq, reqVO.getQq()) | ||||
|                 .eqIfPresent(ContactDO::getWebchat, reqVO.getWebchat()) | ||||
|                 .eqIfPresent(ContactDO::getWechat, reqVO.getWechat()) | ||||
|                 .eqIfPresent(ContactDO::getSex, reqVO.getSex()) | ||||
|                 .eqIfPresent(ContactDO::getPolicyMakers, reqVO.getPolicyMakers()) | ||||
|                 .eqIfPresent(ContactDO::getMaster, reqVO.getMaster()) | ||||
|                 .eqIfPresent(ContactDO::getOwnerUserId, reqVO.getOwnerUserId()) | ||||
|                 .orderByDesc(ContactDO::getId)); | ||||
|     } | ||||
|  | ||||
|     default List<ContactDO> selectList(ContactExportReqVO reqVO) { | ||||
|     default List<ContactDO> selectList(ContactPageReqVO reqVO) { | ||||
|         return selectList(new LambdaQueryWrapperX<ContactDO>() | ||||
|                 .betweenIfPresent(ContactDO::getNextTime, reqVO.getNextTime()) | ||||
|                 .eqIfPresent(ContactDO::getMobile, reqVO.getMobile()) | ||||
| @@ -54,9 +54,9 @@ public interface ContactMapper extends BaseMapperX<ContactDO> { | ||||
|                 .likeIfPresent(ContactDO::getName, reqVO.getName()) | ||||
|                 .eqIfPresent(ContactDO::getPost, reqVO.getPost()) | ||||
|                 .eqIfPresent(ContactDO::getQq, reqVO.getQq()) | ||||
|                 .eqIfPresent(ContactDO::getWebchat, reqVO.getWebchat()) | ||||
|                 .eqIfPresent(ContactDO::getWechat, reqVO.getWechat()) | ||||
|                 .eqIfPresent(ContactDO::getSex, reqVO.getSex()) | ||||
|                 .eqIfPresent(ContactDO::getPolicyMakers, reqVO.getPolicyMakers()) | ||||
|                 .eqIfPresent(ContactDO::getMaster, reqVO.getMaster()) | ||||
|                 .eqIfPresent(ContactDO::getOwnerUserId, reqVO.getOwnerUserId()) | ||||
|                 .orderByDesc(ContactDO::getId)); | ||||
|     } | ||||
|   | ||||
| @@ -2,7 +2,6 @@ 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.ContactCreateReqVO; | ||||
| import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactExportReqVO; | ||||
| import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactPageReqVO; | ||||
| import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactUpdateReqVO; | ||||
| import cn.iocoder.yudao.module.crm.dal.dataobject.contact.ContactDO; | ||||
| @@ -71,11 +70,11 @@ public interface ContactService { | ||||
|      * @param exportReqVO 查询条件 | ||||
|      * @return crm联系人列表 | ||||
|      */ | ||||
|     List<ContactDO> getContactList(ContactExportReqVO exportReqVO); | ||||
|     List<ContactDO> getContactList(ContactPageReqVO exportReqVO); | ||||
|  | ||||
|     /** | ||||
|      * 获取所有联系人列表,只返回姓名和id | ||||
|      * @return 所有联系人列表 | ||||
|      */ | ||||
|     List<ContactDO> allContactList(); | ||||
|     List<ContactDO> getContactList(); | ||||
| } | ||||
|   | ||||
| @@ -4,7 +4,6 @@ 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.ContactCreateReqVO; | ||||
| import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactExportReqVO; | ||||
| import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactPageReqVO; | ||||
| import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactUpdateReqVO; | ||||
| import cn.iocoder.yudao.module.crm.convert.contact.ContactConvert; | ||||
| @@ -57,7 +56,7 @@ public class ContactServiceImpl implements ContactService { | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS, level = CrmPermissionLevelEnum.WRITE) | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS,bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) | ||||
|     public void updateContact(ContactUpdateReqVO updateReqVO) { | ||||
|         // 校验存在 | ||||
|         validateContactExists(updateReqVO.getId()); | ||||
| @@ -68,7 +67,7 @@ public class ContactServiceImpl implements ContactService { | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS, level = CrmPermissionLevelEnum.WRITE) | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS,bizId = "#id", level = CrmPermissionLevelEnum.WRITE) | ||||
|     public void deleteContact(Long id) { | ||||
|         // 校验存在 | ||||
|         validateContactExists(id); | ||||
| @@ -83,7 +82,7 @@ public class ContactServiceImpl implements ContactService { | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS, level = CrmPermissionLevelEnum.READ) | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS,bizId = "#id", level = CrmPermissionLevelEnum.READ) | ||||
|     public ContactDO getContact(Long id) { | ||||
|         return contactMapper.selectById(id); | ||||
|     } | ||||
| @@ -102,13 +101,12 @@ public class ContactServiceImpl implements ContactService { | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<ContactDO> getContactList(ContactExportReqVO exportReqVO) { | ||||
|     public List<ContactDO> getContactList(ContactPageReqVO exportReqVO) { | ||||
|         return contactMapper.selectList(exportReqVO); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<ContactDO> allContactList() { | ||||
|     public List<ContactDO> getContactList() { | ||||
|         return contactMapper.selectList(); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -128,4 +128,10 @@ public interface CrmCustomerService { | ||||
|      */ | ||||
|     void receive(Long id, Long userId); | ||||
|  | ||||
|     /** | ||||
|      * 获取客户列表 | ||||
|      * @return 客户列表 | ||||
|      * @author zyna | ||||
|      */ | ||||
|     List<CrmCustomerDO> getCustomerList(); | ||||
| } | ||||
|   | ||||
| @@ -230,6 +230,11 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||||
|                 .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<CrmCustomerDO> getCustomerList() { | ||||
|         return customerMapper.selectList(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) | ||||
|   | ||||
| @@ -26,4 +26,6 @@ public interface DictTypeConstants { | ||||
|     String SMS_SEND_STATUS = "system_sms_send_status"; // 短信发送状态 | ||||
|     String SMS_RECEIVE_STATUS = "system_sms_receive_status"; // 短信接收状态 | ||||
|  | ||||
|     String INFRA_BOOLEAN_STRING = "infra_boolean_string"; // boolean字典 | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 zyna
					zyna