Commit 3f3899f5d3a17faf19e065b614c8e391d0204472
Committed by
YunaiV
1 parent
4a51b201
crm联系人review修改,新增地区字段
Showing
19 changed files
with
334 additions
and
251 deletions
sql/mysql/crm.sql
| 1 | SET NAMES utf8mb4; | 1 | SET NAMES utf8mb4; |
| 2 | +-- `ruoyi-vue-pro`.crm_contact definition | ||
| 3 | + | ||
| 4 | +CREATE TABLE `crm_contact` ( | ||
| 5 | + `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', | ||
| 6 | + `name` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '联系人名称', | ||
| 7 | + `next_time` datetime DEFAULT NULL COMMENT '下次联系时间', | ||
| 8 | + `mobile` varchar(16) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '手机号', | ||
| 9 | + `telephone` varchar(16) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '电话', | ||
| 10 | + `email` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '电子邮箱', | ||
| 11 | + `post` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '职务', | ||
| 12 | + `customer_id` bigint(20) DEFAULT NULL COMMENT '客户编号', | ||
| 13 | + `address` varchar(256) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '地址', | ||
| 14 | + `remark` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注', | ||
| 15 | + `creator` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建人', | ||
| 16 | + `owner_user_id` varchar(256) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '负责人用户编号', | ||
| 17 | + `create_time` timestamp NULL DEFAULT NULL COMMENT '创建时间', | ||
| 18 | + `update_time` timestamp NULL DEFAULT NULL COMMENT '更新时间', | ||
| 19 | + `last_time` timestamp NULL DEFAULT NULL COMMENT '最后跟进时间', | ||
| 20 | + `updater` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '更新人', | ||
| 21 | + `deleted` bit(1) NOT NULL DEFAULT b'0', | ||
| 22 | + `tenant_id` bigint(20) DEFAULT NULL, | ||
| 23 | + `parent_id` bigint(20) DEFAULT NULL COMMENT '直系上属', | ||
| 24 | + `qq` int(11) DEFAULT NULL, | ||
| 25 | + `wechat` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL, | ||
| 26 | + `sex` int(11) DEFAULT NULL COMMENT '性别', | ||
| 27 | + `master` bit(1) DEFAULT NULL COMMENT '是否关键决策人', | ||
| 28 | + `area_id` bigint(20) DEFAULT NULL COMMENT '地区', | ||
| 29 | + PRIMARY KEY (`id`) USING BTREE | ||
| 30 | +) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='CRM 联系人'; | ||
| 2 | \ No newline at end of file | 31 | \ No newline at end of file |
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/contact/ContactConstants.java
0 → 100644
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/ContactController.java
| @@ -7,10 +7,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | @@ -7,10 +7,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 7 | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | 7 | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| 8 | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | 8 | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; |
| 9 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*; | 9 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*; |
| 10 | -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO; | ||
| 11 | import cn.iocoder.yudao.module.crm.convert.contact.ContactConvert; | 10 | import cn.iocoder.yudao.module.crm.convert.contact.ContactConvert; |
| 12 | import cn.iocoder.yudao.module.crm.dal.dataobject.contact.ContactDO; | 11 | import cn.iocoder.yudao.module.crm.dal.dataobject.contact.ContactDO; |
| 13 | import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; | 12 | import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; |
| 13 | +import cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants; | ||
| 14 | import cn.iocoder.yudao.module.crm.service.contact.ContactService; | 14 | import cn.iocoder.yudao.module.crm.service.contact.ContactService; |
| 15 | import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; | 15 | import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; |
| 16 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | 16 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| @@ -19,6 +19,7 @@ import com.google.common.collect.Lists; | @@ -19,6 +19,7 @@ import com.google.common.collect.Lists; | ||
| 19 | import io.swagger.v3.oas.annotations.Operation; | 19 | import io.swagger.v3.oas.annotations.Operation; |
| 20 | import io.swagger.v3.oas.annotations.Parameter; | 20 | import io.swagger.v3.oas.annotations.Parameter; |
| 21 | import io.swagger.v3.oas.annotations.tags.Tag; | 21 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 22 | +import lombok.extern.slf4j.Slf4j; | ||
| 22 | import org.springframework.security.access.prepost.PreAuthorize; | 23 | import org.springframework.security.access.prepost.PreAuthorize; |
| 23 | import org.springframework.validation.annotation.Validated; | 24 | import org.springframework.validation.annotation.Validated; |
| 24 | import org.springframework.web.bind.annotation.*; | 25 | import org.springframework.web.bind.annotation.*; |
| @@ -27,13 +28,14 @@ import javax.annotation.Resource; | @@ -27,13 +28,14 @@ import javax.annotation.Resource; | ||
| 27 | import javax.servlet.http.HttpServletResponse; | 28 | import javax.servlet.http.HttpServletResponse; |
| 28 | import javax.validation.Valid; | 29 | import javax.validation.Valid; |
| 29 | import java.io.IOException; | 30 | import java.io.IOException; |
| 31 | +import java.util.Collections; | ||
| 30 | import java.util.List; | 32 | import java.util.List; |
| 31 | import java.util.Map; | 33 | import java.util.Map; |
| 32 | -import java.util.Optional; | ||
| 33 | import java.util.stream.Collectors; | 34 | import java.util.stream.Collectors; |
| 35 | +import java.util.stream.Stream; | ||
| 34 | 36 | ||
| 37 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 35 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 38 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 36 | -import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; | ||
| 37 | import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; | 39 | import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; |
| 38 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | 40 | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| 39 | 41 | ||
| @@ -42,6 +44,7 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti | @@ -42,6 +44,7 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti | ||
| 42 | @RestController | 44 | @RestController |
| 43 | @RequestMapping("/crm/contact") | 45 | @RequestMapping("/crm/contact") |
| 44 | @Validated | 46 | @Validated |
| 47 | +@Slf4j | ||
| 45 | public class ContactController { | 48 | public class ContactController { |
| 46 | 49 | ||
| 47 | @Resource | 50 | @Resource |
| @@ -83,23 +86,25 @@ public class ContactController { | @@ -83,23 +86,25 @@ public class ContactController { | ||
| 83 | @PreAuthorize("@ss.hasPermission('crm:contact:query')") | 86 | @PreAuthorize("@ss.hasPermission('crm:contact:query')") |
| 84 | public CommonResult<ContactRespVO> getContact(@RequestParam("id") Long id) { | 87 | public CommonResult<ContactRespVO> getContact(@RequestParam("id") Long id) { |
| 85 | ContactDO contact = contactService.getContact(id); | 88 | ContactDO contact = contactService.getContact(id); |
| 86 | - // TODO @zyna:需要考虑 null 的情况; | ||
| 87 | - ContactRespVO contactRespVO = ContactConvert.INSTANCE.convert(contact); | ||
| 88 | - // TODO @zyna:可以把数据读完后,convert 统一交给 ContactConvert,让 controller 更简洁;而 convert 专门去做一些转换逻辑 | 89 | + if(contact == null){ |
| 90 | + throw exception(ErrorCodeConstants.CONTACT_NOT_EXISTS); | ||
| 91 | + } | ||
| 92 | + //1.获取用户名 | ||
| 89 | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(CollUtil.removeNull(Lists.newArrayList( | 93 | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(CollUtil.removeNull(Lists.newArrayList( |
| 90 | - NumberUtil.parseLong(contact.getCreator())))); | ||
| 91 | - contactRespVO.setCreatorName(Optional.ofNullable(userMap.get(NumberUtil.parseLong(contact.getCreator()))).map(AdminUserRespDTO::getNickname).orElse(null)); | ||
| 92 | - contactRespVO.setCustomerName(Optional.ofNullable(crmCustomerService.getCustomer(contact.getCustomerId())).map(CrmCustomerDO::getName).orElse(null)); | 94 | + NumberUtil.parseLong(contact.getCreator()),contact.getOwnerUserId()))); |
| 95 | + //2.获取客户信息 | ||
| 96 | + List<CrmCustomerDO> crmCustomerDOList = crmCustomerService.getCustomerList(Collections.singletonList(contact.getCustomerId())); | ||
| 97 | + //3.直属上级 | ||
| 98 | + List<ContactDO> contactList = contactService.getContactList(Collections.singletonList(contact.getParentId())); | ||
| 99 | + ContactRespVO contactRespVO = ContactConvert.INSTANCE.convert(contact,userMap,crmCustomerDOList,contactList); | ||
| 93 | return success(contactRespVO); | 100 | return success(contactRespVO); |
| 94 | } | 101 | } |
| 95 | - | ||
| 96 | - // TODO @zyna:url 使用中划线噢;然后,单词的拼写也要注意呀,AllList 是不是更好呀; | ||
| 97 | - @GetMapping("/simpleAlllist") | 102 | + @GetMapping("/simple-all-list") |
| 98 | @Operation(summary = "获得联系人列表") | 103 | @Operation(summary = "获得联系人列表") |
| 99 | @PreAuthorize("@ss.hasPermission('crm:contact:query')") | 104 | @PreAuthorize("@ss.hasPermission('crm:contact:query')") |
| 100 | public CommonResult<List<ContactSimpleRespVO>> simpleAlllist() { | 105 | public CommonResult<List<ContactSimpleRespVO>> simpleAlllist() { |
| 101 | // TODO @zyna:方法名改成,getContactList;方法命名,要动名词,get 动词;all 可以去掉,因为没条件,自然是全部 | 106 | // TODO @zyna:方法名改成,getContactList;方法命名,要动名词,get 动词;all 可以去掉,因为没条件,自然是全部 |
| 102 | - List<ContactDO> list = contactService.allContactList(); | 107 | + List<ContactDO> list = contactService.getContactList(); |
| 103 | return success(ContactConvert.INSTANCE.convertAllList(list)); | 108 | return success(ContactConvert.INSTANCE.convertAllList(list)); |
| 104 | } | 109 | } |
| 105 | 110 | ||
| @@ -108,18 +113,10 @@ public class ContactController { | @@ -108,18 +113,10 @@ public class ContactController { | ||
| 108 | @PreAuthorize("@ss.hasPermission('crm:contact:query')") | 113 | @PreAuthorize("@ss.hasPermission('crm:contact:query')") |
| 109 | public CommonResult<PageResult<ContactRespVO>> getContactPage(@Valid ContactPageReqVO pageVO) { | 114 | public CommonResult<PageResult<ContactRespVO>> getContactPage(@Valid ContactPageReqVO pageVO) { |
| 110 | PageResult<ContactDO> pageData = contactService.getContactPage(pageVO); | 115 | PageResult<ContactDO> pageData = contactService.getContactPage(pageVO); |
| 111 | - PageResult<ContactRespVO> pageResult = ContactConvert.INSTANCE.convertPage(pageData); | ||
| 112 | - // TODO @zyna:需要考虑 null 的情况; | ||
| 113 | - // TODO @zyna:可以把数据读完后,convert 统一交给 ContactConvert,让 controller 更简洁;而 convert 专门去做一些转换逻辑 | ||
| 114 | - //待接口实现后修改 | ||
| 115 | - CrmCustomerPageReqVO reqVO = new CrmCustomerPageReqVO(); | ||
| 116 | - reqVO.setPageSize(PAGE_SIZE_NONE); | ||
| 117 | - List<CrmCustomerDO> crmCustomerDOList = crmCustomerService.getCustomerPage(reqVO, getLoginUserId()).getList(); | ||
| 118 | - Map<Long, CrmCustomerDO> crmCustomerDOMap = crmCustomerDOList.stream().collect(Collectors.toMap(CrmCustomerDO::getId, v -> v)); | ||
| 119 | - pageResult.getList().forEach(item -> { | ||
| 120 | - item.setCustomerName(Optional.ofNullable(crmCustomerDOMap.get(item.getCustomerId())).map(CrmCustomerDO::getName).orElse(null)); | ||
| 121 | - }); | ||
| 122 | - return success(pageResult); | 116 | + List<ContactRespVO> contactRespVOList = convertFieldValue2Name(pageData.getList()); |
| 117 | + PageResult<ContactRespVO> pageDataReturn = ContactConvert.INSTANCE.convertPage(pageData); | ||
| 118 | + pageDataReturn.setList(contactRespVOList); | ||
| 119 | + return success(pageDataReturn); | ||
| 123 | } | 120 | } |
| 124 | 121 | ||
| 125 | // TODO @zyna:可以看下新的导出写法,这里调整下 | 122 | // TODO @zyna:可以看下新的导出写法,这里调整下 |
| @@ -127,12 +124,30 @@ public class ContactController { | @@ -127,12 +124,30 @@ public class ContactController { | ||
| 127 | @Operation(summary = "导出联系人 Excel") | 124 | @Operation(summary = "导出联系人 Excel") |
| 128 | @PreAuthorize("@ss.hasPermission('crm:contact:export')") | 125 | @PreAuthorize("@ss.hasPermission('crm:contact:export')") |
| 129 | @OperateLog(type = EXPORT) | 126 | @OperateLog(type = EXPORT) |
| 130 | - public void exportContactExcel(@Valid ContactExportReqVO exportReqVO, | ||
| 131 | - HttpServletResponse response) throws IOException { | 127 | + public void exportContactExcel(@Valid ContactPageReqVO exportReqVO, |
| 128 | + HttpServletResponse response) throws IOException { | ||
| 132 | List<ContactDO> list = contactService.getContactList(exportReqVO); | 129 | List<ContactDO> list = contactService.getContactList(exportReqVO); |
| 133 | // 导出 Excel | 130 | // 导出 Excel |
| 134 | - List<ContactExcelVO> datas = ContactConvert.INSTANCE.convertList02(list); | ||
| 135 | - ExcelUtils.write(response, "crm联系人.xls", "数据", ContactExcelVO.class, datas); | 131 | + List<ContactRespVO> contactRespVOList = convertFieldValue2Name(list); |
| 132 | + ExcelUtils.write(response, "crm联系人.xls", "数据", ContactRespVO.class, contactRespVOList); | ||
| 136 | } | 133 | } |
| 137 | 134 | ||
| 135 | + /** | ||
| 136 | + * 翻译字段名称 | ||
| 137 | + * @param contactDOList 联系人List | ||
| 138 | + * @return List<ContactRespVO> | ||
| 139 | + */ | ||
| 140 | + private List<ContactRespVO> convertFieldValue2Name(List<ContactDO> contactDOList){ | ||
| 141 | + //1.获取客户列表 | ||
| 142 | + List<Long> customerIdList = contactDOList.stream().map(ContactDO::getCustomerId).distinct().collect(Collectors.toList()); | ||
| 143 | + List<CrmCustomerDO> crmCustomerDOList = crmCustomerService.getCustomerList(customerIdList); | ||
| 144 | + //2.获取创建人、责任人列表 | ||
| 145 | + List<Long> userIdsList = contactDOList.stream().flatMap(item-> Stream.of(Long.parseLong(item.getCreator()),item.getOwnerUserId()).distinct()).collect(Collectors.toList()); | ||
| 146 | + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIdsList); | ||
| 147 | + //3.直属上级 | ||
| 148 | + List<Long> contactIdsList = contactDOList.stream().map(ContactDO::getParentId).distinct().collect(Collectors.toList()); | ||
| 149 | + List<ContactDO> contactList = contactService.getContactList(contactIdsList); | ||
| 150 | + List<ContactRespVO> pageResult =ContactConvert.INSTANCE.converList(contactDOList,userMap,crmCustomerDOList,contactList); | ||
| 151 | + return pageResult; | ||
| 152 | + } | ||
| 138 | } | 153 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/ContactBaseVO.java
| 1 | package cn.iocoder.yudao.module.crm.controller.admin.contact.vo; | 1 | package cn.iocoder.yudao.module.crm.controller.admin.contact.vo; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.validation.Mobile; | ||
| 4 | +import cn.iocoder.yudao.framework.common.validation.Telephone; | ||
| 5 | +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; | ||
| 6 | +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; | ||
| 7 | +import com.alibaba.excel.annotation.ExcelIgnore; | ||
| 8 | +import com.alibaba.excel.annotation.ExcelProperty; | ||
| 3 | import io.swagger.v3.oas.annotations.media.Schema; | 9 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | import lombok.Data; | 10 | import lombok.Data; |
| 11 | +import org.apache.skywalking.apm.toolkit.trace.IgnoredException; | ||
| 5 | import org.springframework.format.annotation.DateTimeFormat; | 12 | import org.springframework.format.annotation.DateTimeFormat; |
| 6 | 13 | ||
| 14 | +import javax.validation.constraints.Email; | ||
| 15 | +import javax.validation.constraints.NotNull; | ||
| 7 | import java.time.LocalDateTime; | 16 | import java.time.LocalDateTime; |
| 8 | 17 | ||
| 9 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; | 18 | 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_ | @@ -17,57 +26,83 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ | ||
| 17 | @Data | 26 | @Data |
| 18 | public class ContactBaseVO { | 27 | public class ContactBaseVO { |
| 19 | 28 | ||
| 20 | - // TODO @zyna:example 最好都写下 | ||
| 21 | - // TODO @zyna:必要的字段校验,例如说 @Mobile,@Emal 等等 | 29 | + @ExcelProperty(value = "姓名",order = 1) |
| 30 | + @Schema(description = "姓名", example = "芋艿") | ||
| 31 | + @NotNull(message = "姓名不能为空") | ||
| 32 | + private String name; | ||
| 22 | 33 | ||
| 23 | - @Schema(description = "下次联系时间") | ||
| 24 | - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) | ||
| 25 | - private LocalDateTime nextTime; | 34 | + @Schema(description = "客户编号", example = "10795") |
| 35 | + @ExcelIgnore | ||
| 36 | + private Long customerId; | ||
| 37 | + | ||
| 38 | + @ExcelProperty(value = "性别",converter = DictConvert.class ,order = 3) | ||
| 39 | + @DictFormat(cn.iocoder.yudao.module.system.enums.DictTypeConstants.USER_SEX) | ||
| 40 | + @Schema(description = "性别") | ||
| 41 | + private Integer sex; | ||
| 26 | 42 | ||
| 27 | - @Schema(description = "手机号") | 43 | + @Schema(description = "职位") |
| 44 | + @ExcelProperty(value = "职位",order = 3) | ||
| 45 | + private String post; | ||
| 46 | + | ||
| 47 | + @Schema(description = "是否关键决策人") | ||
| 48 | + @ExcelProperty(value = "是否关键决策人",converter = DictConvert.class,order = 3) | ||
| 49 | + @DictFormat(cn.iocoder.yudao.module.system.enums.DictTypeConstants.INFRA_BOOLEAN_STRING) | ||
| 50 | + private Boolean master; | ||
| 51 | + | ||
| 52 | + @Schema(description = "直属上级", example = "23457") | ||
| 53 | + @ExcelIgnore | ||
| 54 | + private Long parentId; | ||
| 55 | + | ||
| 56 | + | ||
| 57 | + @Schema(description = "手机号",example = "1387171766") | ||
| 58 | + @Mobile | ||
| 59 | + @ExcelProperty(value = "手机号",order = 4) | ||
| 28 | private String mobile; | 60 | private String mobile; |
| 29 | 61 | ||
| 30 | - @Schema(description = "电话") | 62 | + @Schema(description = "座机",example = "021-0029922") |
| 63 | + @Telephone | ||
| 64 | + @ExcelProperty(value = "座机",order = 4) | ||
| 31 | private String telephone; | 65 | private String telephone; |
| 32 | 66 | ||
| 33 | - @Schema(description = "电子邮箱") | ||
| 34 | - private String email; | 67 | + @ExcelProperty(value = "QQ",order = 4) |
| 68 | + @Schema(description = "QQ",example = "197272662") | ||
| 69 | + private Long qq; | ||
| 35 | 70 | ||
| 36 | - @Schema(description = "客户编号", example = "10795") | ||
| 37 | - private Long customerId; | 71 | + @ExcelProperty(value = "微信",order = 4) |
| 72 | + @Schema(description = "微信",example = "zzz3883") | ||
| 73 | + private String wechat; | ||
| 38 | 74 | ||
| 75 | + @Schema(description = "电子邮箱",example = "1111@22.com") | ||
| 76 | |||
| 77 | + @ExcelProperty(value = "邮箱",order = 4) | ||
| 78 | + private String email; | ||
| 79 | + | ||
| 80 | + @ExcelProperty(value = "地址",order = 5) | ||
| 39 | @Schema(description = "地址") | 81 | @Schema(description = "地址") |
| 40 | private String address; | 82 | private String address; |
| 41 | 83 | ||
| 84 | + @Schema(description = "下次联系时间") | ||
| 85 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) | ||
| 86 | + @ExcelProperty(value = "下次联系时间",order = 6) | ||
| 87 | + private LocalDateTime nextTime; | ||
| 88 | + | ||
| 42 | @Schema(description = "备注", example = "你说的对") | 89 | @Schema(description = "备注", example = "你说的对") |
| 90 | + @ExcelProperty(value = "备注",order = 6) | ||
| 43 | private String remark; | 91 | private String remark; |
| 44 | 92 | ||
| 45 | @Schema(description = "最后跟进时间") | 93 | @Schema(description = "最后跟进时间") |
| 46 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | 94 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 95 | + @ExcelProperty(value = "最后跟进时间",order = 6) | ||
| 47 | private LocalDateTime lastTime; | 96 | private LocalDateTime lastTime; |
| 48 | 97 | ||
| 49 | - @Schema(description = "直属上级", example = "23457") | ||
| 50 | - private Long parentId; | ||
| 51 | - | ||
| 52 | - @Schema(description = "姓名", example = "芋艿") | ||
| 53 | - private String name; | ||
| 54 | - | ||
| 55 | - @Schema(description = "职位") | ||
| 56 | - private String post; | ||
| 57 | - | ||
| 58 | - @Schema(description = "QQ") | ||
| 59 | - private Long qq; | ||
| 60 | - | ||
| 61 | - @Schema(description = "微信") | ||
| 62 | - private String webchat; | ||
| 63 | - | ||
| 64 | - @Schema(description = "性别") | ||
| 65 | - private Integer sex; | ||
| 66 | - | ||
| 67 | - @Schema(description = "是否关键决策人") | ||
| 68 | - private Boolean policyMakers; | ||
| 69 | 98 | ||
| 70 | @Schema(description = "负责人用户编号", example = "14334") | 99 | @Schema(description = "负责人用户编号", example = "14334") |
| 71 | - private String ownerUserId; | 100 | + @NotNull(message = "负责人不能为空") |
| 101 | + @ExcelIgnore | ||
| 102 | + private Long ownerUserId; | ||
| 103 | + | ||
| 104 | + @Schema(description = "地区编号", example = "20158") | ||
| 105 | + @ExcelIgnore | ||
| 106 | + private Integer areaId; | ||
| 72 | 107 | ||
| 73 | } | 108 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/ContactExcelVO.java deleted
| 1 | -package cn.iocoder.yudao.module.crm.controller.admin.contact.vo; | ||
| 2 | - | ||
| 3 | -import com.alibaba.excel.annotation.ExcelProperty; | ||
| 4 | -import lombok.Data; | ||
| 5 | - | ||
| 6 | -import java.time.LocalDateTime; | ||
| 7 | - | ||
| 8 | -// TODO @zyna:参考新的 VO 结构,把 ContactExcelVO 融合到 ContactRespVO 中 | ||
| 9 | -/** | ||
| 10 | - * crm联系人 Excel VO | ||
| 11 | - * | ||
| 12 | - * @author 芋道源码 | ||
| 13 | - */ | ||
| 14 | -@Data | ||
| 15 | -@Deprecated | ||
| 16 | -public class ContactExcelVO { | ||
| 17 | - | ||
| 18 | - @ExcelProperty("下次联系时间") | ||
| 19 | - private LocalDateTime nextTime; | ||
| 20 | - | ||
| 21 | - @ExcelProperty("手机号") | ||
| 22 | - private String mobile; | ||
| 23 | - | ||
| 24 | - @ExcelProperty("电话") | ||
| 25 | - private String telephone; | ||
| 26 | - | ||
| 27 | - @ExcelProperty("电子邮箱") | ||
| 28 | - private String email; | ||
| 29 | - | ||
| 30 | - @ExcelProperty("客户编号") | ||
| 31 | - private Long customerId; | ||
| 32 | - | ||
| 33 | - @ExcelProperty("地址") | ||
| 34 | - private String address; | ||
| 35 | - | ||
| 36 | - @ExcelProperty("备注") | ||
| 37 | - private String remark; | ||
| 38 | - | ||
| 39 | - @ExcelProperty("创建时间") | ||
| 40 | - private LocalDateTime createTime; | ||
| 41 | - | ||
| 42 | - @ExcelProperty("最后跟进时间") | ||
| 43 | - private LocalDateTime lastTime; | ||
| 44 | - | ||
| 45 | - @ExcelProperty("主键") | ||
| 46 | - private Long id; | ||
| 47 | - | ||
| 48 | - @ExcelProperty("直属上级") | ||
| 49 | - private Long parentId; | ||
| 50 | - | ||
| 51 | - @ExcelProperty("姓名") | ||
| 52 | - private String name; | ||
| 53 | - | ||
| 54 | - @ExcelProperty("职位") | ||
| 55 | - private String post; | ||
| 56 | - | ||
| 57 | - @ExcelProperty("QQ") | ||
| 58 | - private Long qq; | ||
| 59 | - | ||
| 60 | - @ExcelProperty("微信") | ||
| 61 | - private String webchat; | ||
| 62 | - | ||
| 63 | - @ExcelProperty("性别") | ||
| 64 | - private Integer sex; | ||
| 65 | - | ||
| 66 | - @ExcelProperty("是否关键决策人") | ||
| 67 | - private Boolean policyMakers; | ||
| 68 | - | ||
| 69 | - @ExcelProperty("负责人用户编号") | ||
| 70 | - private String ownerUserId; | ||
| 71 | - | ||
| 72 | -} |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/ContactExportReqVO.java deleted
| 1 | -package cn.iocoder.yudao.module.crm.controller.admin.contact.vo; | ||
| 2 | - | ||
| 3 | -import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | -import lombok.Data; | ||
| 5 | -import org.springframework.format.annotation.DateTimeFormat; | ||
| 6 | - | ||
| 7 | -import java.time.LocalDateTime; | ||
| 8 | - | ||
| 9 | -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | ||
| 10 | - | ||
| 11 | -// TODO @zyna:参考新的 VO 结构,使用 ContactPageReqVO 查询导出的数据 | ||
| 12 | -@Schema(description = "管理后台 - crm联系人 Excel 导出 Request VO,参数和 ContactPageReqVO 是一致的") | ||
| 13 | -@Data | ||
| 14 | -@Deprecated | ||
| 15 | -public class ContactExportReqVO { | ||
| 16 | - | ||
| 17 | - @Schema(description = "下次联系时间") | ||
| 18 | - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||
| 19 | - private LocalDateTime[] nextTime; | ||
| 20 | - | ||
| 21 | - @Schema(description = "手机号") | ||
| 22 | - private String mobile; | ||
| 23 | - | ||
| 24 | - @Schema(description = "电话") | ||
| 25 | - private String telephone; | ||
| 26 | - | ||
| 27 | - @Schema(description = "电子邮箱") | ||
| 28 | - private String email; | ||
| 29 | - | ||
| 30 | - @Schema(description = "客户编号", example = "10795") | ||
| 31 | - private Long customerId; | ||
| 32 | - | ||
| 33 | - @Schema(description = "地址") | ||
| 34 | - private String address; | ||
| 35 | - | ||
| 36 | - @Schema(description = "备注", example = "你说的对") | ||
| 37 | - private String remark; | ||
| 38 | - | ||
| 39 | - @Schema(description = "创建时间") | ||
| 40 | - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||
| 41 | - private LocalDateTime[] createTime; | ||
| 42 | - | ||
| 43 | - @Schema(description = "最后跟进时间") | ||
| 44 | - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||
| 45 | - private LocalDateTime[] lastTime; | ||
| 46 | - | ||
| 47 | - @Schema(description = "直属上级", example = "23457") | ||
| 48 | - private Long parentId; | ||
| 49 | - | ||
| 50 | - @Schema(description = "姓名", example = "芋艿") | ||
| 51 | - private String name; | ||
| 52 | - | ||
| 53 | - @Schema(description = "职位") | ||
| 54 | - private String post; | ||
| 55 | - | ||
| 56 | - @Schema(description = "QQ") | ||
| 57 | - private Long qq; | ||
| 58 | - | ||
| 59 | - @Schema(description = "微信") | ||
| 60 | - private String webchat; | ||
| 61 | - | ||
| 62 | - @Schema(description = "性别") | ||
| 63 | - private Integer sex; | ||
| 64 | - | ||
| 65 | - @Schema(description = "是否关键决策人") | ||
| 66 | - private Boolean policyMakers; | ||
| 67 | - | ||
| 68 | - @Schema(description = "负责人用户编号", example = "14334") | ||
| 69 | - private String ownerUserId; | ||
| 70 | - | ||
| 71 | -} |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/ContactPageReqVO.java
| @@ -26,13 +26,13 @@ public class ContactPageReqVO extends PageParam { | @@ -26,13 +26,13 @@ public class ContactPageReqVO extends PageParam { | ||
| 26 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | 26 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 27 | private LocalDateTime[] nextTime; | 27 | private LocalDateTime[] nextTime; |
| 28 | 28 | ||
| 29 | - @Schema(description = "手机号") | 29 | + @Schema(description = "手机号",example = "13898273941") |
| 30 | private String mobile; | 30 | private String mobile; |
| 31 | 31 | ||
| 32 | - @Schema(description = "电话") | 32 | + @Schema(description = "电话",example = "021-383773") |
| 33 | private String telephone; | 33 | private String telephone; |
| 34 | 34 | ||
| 35 | - @Schema(description = "电子邮箱") | 35 | + @Schema(description = "电子邮箱",example = "111@22.com") |
| 36 | private String email; | 36 | private String email; |
| 37 | 37 | ||
| 38 | @Schema(description = "客户编号", example = "10795") | 38 | @Schema(description = "客户编号", example = "10795") |
| @@ -61,19 +61,19 @@ public class ContactPageReqVO extends PageParam { | @@ -61,19 +61,19 @@ public class ContactPageReqVO extends PageParam { | ||
| 61 | @Schema(description = "职位") | 61 | @Schema(description = "职位") |
| 62 | private String post; | 62 | private String post; |
| 63 | 63 | ||
| 64 | - @Schema(description = "QQ") | 64 | + @Schema(description = "QQ",example = "3882872") |
| 65 | private Long qq; | 65 | private Long qq; |
| 66 | 66 | ||
| 67 | - @Schema(description = "微信") | ||
| 68 | - private String webchat; | 67 | + @Schema(description = "微信",example = "zzZ98373") |
| 68 | + private String wechat; | ||
| 69 | 69 | ||
| 70 | @Schema(description = "性别") | 70 | @Schema(description = "性别") |
| 71 | private Integer sex; | 71 | private Integer sex; |
| 72 | 72 | ||
| 73 | @Schema(description = "是否关键决策人") | 73 | @Schema(description = "是否关键决策人") |
| 74 | - private Boolean policyMakers; | 74 | + private Boolean master; |
| 75 | 75 | ||
| 76 | @Schema(description = "负责人用户编号", example = "14334") | 76 | @Schema(description = "负责人用户编号", example = "14334") |
| 77 | - private String ownerUserId; | 77 | + private Long ownerUserId; |
| 78 | 78 | ||
| 79 | } | 79 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/ContactRespVO.java
| 1 | package cn.iocoder.yudao.module.crm.controller.admin.contact.vo; | 1 | package cn.iocoder.yudao.module.crm.controller.admin.contact.vo; |
| 2 | 2 | ||
| 3 | +import com.alibaba.excel.annotation.ExcelIgnore; | ||
| 4 | +import com.alibaba.excel.annotation.ExcelProperty; | ||
| 3 | import io.swagger.v3.oas.annotations.media.Schema; | 5 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | import lombok.*; | 6 | import lombok.*; |
| 5 | import java.time.LocalDateTime; | 7 | import java.time.LocalDateTime; |
| @@ -11,17 +13,34 @@ import java.time.LocalDateTime; | @@ -11,17 +13,34 @@ import java.time.LocalDateTime; | ||
| 11 | public class ContactRespVO extends ContactBaseVO { | 13 | public class ContactRespVO extends ContactBaseVO { |
| 12 | 14 | ||
| 13 | @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167") | 15 | @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167") |
| 16 | + @ExcelIgnore | ||
| 14 | private Long id; | 17 | private Long id; |
| 15 | 18 | ||
| 16 | @Schema(description = "创建时间") | 19 | @Schema(description = "创建时间") |
| 20 | + @ExcelProperty(value = "创建时间",order = 8) | ||
| 17 | private LocalDateTime createTime; | 21 | private LocalDateTime createTime; |
| 18 | 22 | ||
| 19 | - // TODO @zyna:example 最好写下; | 23 | + @Schema(description = "创建人", example = "25682") |
| 24 | + @ExcelIgnore | ||
| 25 | + private String creator; | ||
| 20 | 26 | ||
| 21 | - @Schema(description = "创建人") | 27 | + @Schema(description = "创建人名字", example = "test") |
| 28 | + @ExcelProperty(value = "创建人",order = 8) | ||
| 22 | private String creatorName; | 29 | private String creatorName; |
| 23 | 30 | ||
| 24 | - @Schema(description = "客户名字") | 31 | + @ExcelProperty(value = "客户名称",order = 2) |
| 32 | + @Schema(description = "客户名字", example = "test") | ||
| 25 | private String customerName; | 33 | private String customerName; |
| 26 | 34 | ||
| 35 | + @Schema(description = "负责人", example = "test") | ||
| 36 | + @ExcelProperty(value = "负责人",order = 7) | ||
| 37 | + private String ownerUserName; | ||
| 38 | + | ||
| 39 | + @Schema(description = "直属上级名",example = "芋头") | ||
| 40 | + @ExcelProperty(value = "直属上级",order = 4) | ||
| 41 | + private String parentName; | ||
| 42 | + | ||
| 43 | + @Schema(description = "地区名",example = "上海上海市浦东新区") | ||
| 44 | + @ExcelProperty(value = "地区",order = 5) | ||
| 45 | + private String areaName; | ||
| 27 | } | 46 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
| @@ -172,5 +172,12 @@ public class CrmCustomerController { | @@ -172,5 +172,12 @@ public class CrmCustomerController { | ||
| 172 | customerService.receiveCustomer(ids, ownerUserId); | 172 | customerService.receiveCustomer(ids, ownerUserId); |
| 173 | return success(true); | 173 | return success(true); |
| 174 | } | 174 | } |
| 175 | - | 175 | + @GetMapping("/query-all-list") |
| 176 | + @Operation(summary = "查询客户列表") | ||
| 177 | + @PreAuthorize("@ss.hasPermission('crm:customer:all')") | ||
| 178 | + public CommonResult<List<CrmCustomerQueryAllRespVO>> queryAll(){ | ||
| 179 | + List<CrmCustomerDO> crmCustomerDOList = customerService.getCustomerList(); | ||
| 180 | + List<CrmCustomerQueryAllRespVO> data = CrmCustomerConvert.INSTANCE.convertQueryAll(crmCustomerDOList); | ||
| 181 | + return success(data); | ||
| 182 | + } | ||
| 176 | } | 183 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerQueryAllRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.crm.controller.admin.customer.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Data; | ||
| 5 | + | ||
| 6 | + | ||
| 7 | +@Schema(description = "管理后台 - CRM 全部客户 Response VO") | ||
| 8 | +@Data | ||
| 9 | +public class CrmCustomerQueryAllRespVO{ | ||
| 10 | + @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") | ||
| 11 | + private String name; | ||
| 12 | + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563") | ||
| 13 | + private Long id; | ||
| 14 | + | ||
| 15 | +} |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/ContactConvert.java
| 1 | package cn.iocoder.yudao.module.crm.convert.contact; | 1 | package cn.iocoder.yudao.module.crm.convert.contact; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | +import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; | ||
| 4 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*; | 5 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*; |
| 5 | import cn.iocoder.yudao.module.crm.dal.dataobject.contact.ContactDO; | 6 | import cn.iocoder.yudao.module.crm.dal.dataobject.contact.ContactDO; |
| 7 | +import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; | ||
| 6 | import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; | 8 | import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; |
| 9 | +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | ||
| 7 | import org.mapstruct.Mapper; | 10 | import org.mapstruct.Mapper; |
| 8 | import org.mapstruct.Mapping; | 11 | import org.mapstruct.Mapping; |
| 9 | import org.mapstruct.Mappings; | 12 | import org.mapstruct.Mappings; |
| 10 | import org.mapstruct.factory.Mappers; | 13 | import org.mapstruct.factory.Mappers; |
| 11 | - | ||
| 12 | import java.util.List; | 14 | import java.util.List; |
| 15 | +import java.util.Map; | ||
| 16 | +import java.util.stream.Collectors; | ||
| 17 | + | ||
| 18 | +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; | ||
| 13 | 19 | ||
| 14 | /** | 20 | /** |
| 15 | * crm联系人 Convert | 21 | * crm联系人 Convert |
| @@ -31,8 +37,6 @@ public interface ContactConvert { | @@ -31,8 +37,6 @@ public interface ContactConvert { | ||
| 31 | 37 | ||
| 32 | PageResult<ContactRespVO> convertPage(PageResult<ContactDO> page); | 38 | PageResult<ContactRespVO> convertPage(PageResult<ContactDO> page); |
| 33 | 39 | ||
| 34 | - List<ContactExcelVO> convertList02(List<ContactDO> list); | ||
| 35 | - | ||
| 36 | List<ContactSimpleRespVO> convertAllList(List<ContactDO> list); | 40 | List<ContactSimpleRespVO> convertAllList(List<ContactDO> list); |
| 37 | 41 | ||
| 38 | @Mappings({ | 42 | @Mappings({ |
| @@ -41,4 +45,46 @@ public interface ContactConvert { | @@ -41,4 +45,46 @@ public interface ContactConvert { | ||
| 41 | }) | 45 | }) |
| 42 | CrmPermissionTransferReqBO convert(CrmContactTransferReqVO reqVO, Long userId); | 46 | CrmPermissionTransferReqBO convert(CrmContactTransferReqVO reqVO, Long userId); |
| 43 | 47 | ||
| 48 | + /** | ||
| 49 | + * 详情信息 | ||
| 50 | + * @param contactDO 联系人 | ||
| 51 | + * @param userMap 用户列表 | ||
| 52 | + * @param crmCustomerDOList 客户 | ||
| 53 | + * @return ContactRespVO | ||
| 54 | + */ | ||
| 55 | + default ContactRespVO convert(ContactDO contactDO, Map<Long, AdminUserRespDTO> userMap, List<CrmCustomerDO> crmCustomerDOList, | ||
| 56 | + List<ContactDO> contactList) { | ||
| 57 | + ContactRespVO contactRespVO = convert(contactDO); | ||
| 58 | + setUserInfo(contactRespVO,userMap); | ||
| 59 | + Map<Long,CrmCustomerDO> crmCustomerDOMap = crmCustomerDOList.stream().collect(Collectors.toMap(CrmCustomerDO::getId,v->v)); | ||
| 60 | + Map<Long,ContactDO> contactDOMap = contactList.stream().collect(Collectors.toMap(ContactDO::getId,v->v)); | ||
| 61 | + findAndThen(crmCustomerDOMap,contactDO.getCustomerId(),customer -> {contactRespVO.setCustomerName(customer.getName());}); | ||
| 62 | + findAndThen(contactDOMap,contactDO.getParentId(),contactDOInner -> {contactRespVO.setParentName(contactDOInner.getName());}); | ||
| 63 | + return contactRespVO; | ||
| 64 | + } | ||
| 65 | + default List<ContactRespVO> converList(List<ContactDO> contactDOList, Map<Long, AdminUserRespDTO> userMap, | ||
| 66 | + List<CrmCustomerDO> crmCustomerDOList , List<ContactDO> contactList){ | ||
| 67 | + List<ContactRespVO> result = convertList(contactDOList); | ||
| 68 | + Map<Long,ContactDO> contactMap = contactList.stream().collect(Collectors.toMap(ContactDO::getId,v->v)); | ||
| 69 | + Map<Long,CrmCustomerDO> customerMap = crmCustomerDOList.stream().collect(Collectors.toMap(CrmCustomerDO::getId,v->v)); | ||
| 70 | + result.forEach(item -> { | ||
| 71 | + setUserInfo(item, userMap); | ||
| 72 | + findAndThen(customerMap,item.getCustomerId(),customer -> {item.setCustomerName(customer.getName());}); | ||
| 73 | + findAndThen(contactMap,item.getParentId(),contactDO -> {item.setParentName(contactDO.getName());}); | ||
| 74 | + }); | ||
| 75 | + return result; | ||
| 76 | + } | ||
| 77 | + /** | ||
| 78 | + * 设置用户信息 | ||
| 79 | + * | ||
| 80 | + * @param contactRespVO 联系人Response VO | ||
| 81 | + * @param userMap 用户信息 map | ||
| 82 | + */ | ||
| 83 | + static void setUserInfo(ContactRespVO contactRespVO, Map<Long, AdminUserRespDTO> userMap){ | ||
| 84 | + contactRespVO.setAreaName(AreaUtils.format(contactRespVO.getAreaId())); | ||
| 85 | + findAndThen(userMap, contactRespVO.getOwnerUserId(), user -> { | ||
| 86 | + contactRespVO.setOwnerUserName(user == null?"":user.getNickname()); | ||
| 87 | + }); | ||
| 88 | + findAndThen(userMap, Long.parseLong(contactRespVO.getCreator()), user -> contactRespVO.setCreatorName(user.getNickname())); | ||
| 89 | + } | ||
| 44 | } | 90 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/customer/CrmCustomerConvert.java
| @@ -82,4 +82,6 @@ public interface CrmCustomerConvert { | @@ -82,4 +82,6 @@ public interface CrmCustomerConvert { | ||
| 82 | 82 | ||
| 83 | CrmCustomerPoolConfigDO convert(CrmCustomerPoolConfigSaveReqVO updateReqVO); | 83 | CrmCustomerPoolConfigDO convert(CrmCustomerPoolConfigSaveReqVO updateReqVO); |
| 84 | 84 | ||
| 85 | + CrmCustomerQueryAllRespVO convertQueryAll(CrmCustomerDO crmCustomerDO); | ||
| 86 | + List<CrmCustomerQueryAllRespVO> convertQueryAll(List<CrmCustomerDO> crmCustomerDO); | ||
| 85 | } | 87 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contact/ContactDO.java
| @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||
| 4 | import com.baomidou.mybatisplus.annotation.KeySequence; | 4 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 5 | import com.baomidou.mybatisplus.annotation.TableId; | 5 | import com.baomidou.mybatisplus.annotation.TableId; |
| 6 | import com.baomidou.mybatisplus.annotation.TableName; | 6 | import com.baomidou.mybatisplus.annotation.TableName; |
| 7 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 7 | import lombok.*; | 8 | import lombok.*; |
| 8 | 9 | ||
| 9 | import java.time.LocalDateTime; | 10 | import java.time.LocalDateTime; |
| @@ -22,8 +23,11 @@ import java.time.LocalDateTime; | @@ -22,8 +23,11 @@ import java.time.LocalDateTime; | ||
| 22 | @NoArgsConstructor | 23 | @NoArgsConstructor |
| 23 | @AllArgsConstructor | 24 | @AllArgsConstructor |
| 24 | public class ContactDO extends BaseDO { | 25 | public class ContactDO extends BaseDO { |
| 25 | - | ||
| 26 | - // TODO @zyna:这个字段的顺序,是不是整理下; | 26 | + /** |
| 27 | + * 主键 | ||
| 28 | + */ | ||
| 29 | + @TableId | ||
| 30 | + private Long id; | ||
| 27 | /** | 31 | /** |
| 28 | * 下次联系时间 | 32 | * 下次联系时间 |
| 29 | */ | 33 | */ |
| @@ -56,15 +60,8 @@ public class ContactDO extends BaseDO { | @@ -56,15 +60,8 @@ public class ContactDO extends BaseDO { | ||
| 56 | * 最后跟进时间 | 60 | * 最后跟进时间 |
| 57 | */ | 61 | */ |
| 58 | private LocalDateTime lastTime; | 62 | private LocalDateTime lastTime; |
| 59 | - // TODO @zyna:这个放在最前面吧 | ||
| 60 | - /** | ||
| 61 | - * 主键 | ||
| 62 | - */ | ||
| 63 | - @TableId | ||
| 64 | - private Long id; | ||
| 65 | - // TODO @zyna:直接上级,最好写下它关联的字段,例如说这个,应该关联 ContactDO 的 id 字段 | ||
| 66 | /** | 63 | /** |
| 67 | - * 直属上级 | 64 | + * 直属上级 @link ContactDO#id |
| 68 | */ | 65 | */ |
| 69 | private Long parentId; | 66 | private Long parentId; |
| 70 | /** | 67 | /** |
| @@ -79,25 +76,23 @@ public class ContactDO extends BaseDO { | @@ -79,25 +76,23 @@ public class ContactDO extends BaseDO { | ||
| 79 | 76 | ||
| 80 | */ | 77 | */ |
| 81 | private Long qq; | 78 | private Long qq; |
| 82 | - // TODO @zyna:wechat | ||
| 83 | /** | 79 | /** |
| 84 | * 微信 | 80 | * 微信 |
| 85 | */ | 81 | */ |
| 86 | - private String webchat; | ||
| 87 | - // TODO @zyna:关联的枚举 | 82 | + private String wechat; |
| 88 | /** | 83 | /** |
| 89 | * 性别 | 84 | * 性别 |
| 85 | + * @See 字典配置 | ||
| 90 | */ | 86 | */ |
| 91 | private Integer sex; | 87 | private Integer sex; |
| 92 | - // TODO @zyna:这个字段改成 master 哈; | ||
| 93 | /** | 88 | /** |
| 94 | * 是否关键决策人 | 89 | * 是否关键决策人 |
| 95 | */ | 90 | */ |
| 96 | - private Boolean policyMakers; | ||
| 97 | - // TODO @zyna:应该是 Long | 91 | + private Boolean master; |
| 98 | /** | 92 | /** |
| 99 | * 负责人用户编号 | 93 | * 负责人用户编号 |
| 100 | */ | 94 | */ |
| 101 | - private String ownerUserId; | 95 | + private Long ownerUserId; |
| 102 | 96 | ||
| 97 | + private Integer areaId; | ||
| 103 | } | 98 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/ContactMapper.java
| @@ -32,14 +32,14 @@ public interface ContactMapper extends BaseMapperX<ContactDO> { | @@ -32,14 +32,14 @@ public interface ContactMapper extends BaseMapperX<ContactDO> { | ||
| 32 | .likeIfPresent(ContactDO::getName, reqVO.getName()) | 32 | .likeIfPresent(ContactDO::getName, reqVO.getName()) |
| 33 | .eqIfPresent(ContactDO::getPost, reqVO.getPost()) | 33 | .eqIfPresent(ContactDO::getPost, reqVO.getPost()) |
| 34 | .eqIfPresent(ContactDO::getQq, reqVO.getQq()) | 34 | .eqIfPresent(ContactDO::getQq, reqVO.getQq()) |
| 35 | - .eqIfPresent(ContactDO::getWebchat, reqVO.getWebchat()) | 35 | + .eqIfPresent(ContactDO::getWechat, reqVO.getWechat()) |
| 36 | .eqIfPresent(ContactDO::getSex, reqVO.getSex()) | 36 | .eqIfPresent(ContactDO::getSex, reqVO.getSex()) |
| 37 | - .eqIfPresent(ContactDO::getPolicyMakers, reqVO.getPolicyMakers()) | 37 | + .eqIfPresent(ContactDO::getMaster, reqVO.getMaster()) |
| 38 | .eqIfPresent(ContactDO::getOwnerUserId, reqVO.getOwnerUserId()) | 38 | .eqIfPresent(ContactDO::getOwnerUserId, reqVO.getOwnerUserId()) |
| 39 | .orderByDesc(ContactDO::getId)); | 39 | .orderByDesc(ContactDO::getId)); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | - default List<ContactDO> selectList(ContactExportReqVO reqVO) { | 42 | + default List<ContactDO> selectList(ContactPageReqVO reqVO) { |
| 43 | return selectList(new LambdaQueryWrapperX<ContactDO>() | 43 | return selectList(new LambdaQueryWrapperX<ContactDO>() |
| 44 | .betweenIfPresent(ContactDO::getNextTime, reqVO.getNextTime()) | 44 | .betweenIfPresent(ContactDO::getNextTime, reqVO.getNextTime()) |
| 45 | .eqIfPresent(ContactDO::getMobile, reqVO.getMobile()) | 45 | .eqIfPresent(ContactDO::getMobile, reqVO.getMobile()) |
| @@ -54,9 +54,9 @@ public interface ContactMapper extends BaseMapperX<ContactDO> { | @@ -54,9 +54,9 @@ public interface ContactMapper extends BaseMapperX<ContactDO> { | ||
| 54 | .likeIfPresent(ContactDO::getName, reqVO.getName()) | 54 | .likeIfPresent(ContactDO::getName, reqVO.getName()) |
| 55 | .eqIfPresent(ContactDO::getPost, reqVO.getPost()) | 55 | .eqIfPresent(ContactDO::getPost, reqVO.getPost()) |
| 56 | .eqIfPresent(ContactDO::getQq, reqVO.getQq()) | 56 | .eqIfPresent(ContactDO::getQq, reqVO.getQq()) |
| 57 | - .eqIfPresent(ContactDO::getWebchat, reqVO.getWebchat()) | 57 | + .eqIfPresent(ContactDO::getWechat, reqVO.getWechat()) |
| 58 | .eqIfPresent(ContactDO::getSex, reqVO.getSex()) | 58 | .eqIfPresent(ContactDO::getSex, reqVO.getSex()) |
| 59 | - .eqIfPresent(ContactDO::getPolicyMakers, reqVO.getPolicyMakers()) | 59 | + .eqIfPresent(ContactDO::getMaster, reqVO.getMaster()) |
| 60 | .eqIfPresent(ContactDO::getOwnerUserId, reqVO.getOwnerUserId()) | 60 | .eqIfPresent(ContactDO::getOwnerUserId, reqVO.getOwnerUserId()) |
| 61 | .orderByDesc(ContactDO::getId)); | 61 | .orderByDesc(ContactDO::getId)); |
| 62 | } | 62 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/ContactService.java
| @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.crm.service.contact; | @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.crm.service.contact; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactCreateReqVO; | 4 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactCreateReqVO; |
| 5 | -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactExportReqVO; | ||
| 6 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactPageReqVO; | 5 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactPageReqVO; |
| 7 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactUpdateReqVO; | 6 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactUpdateReqVO; |
| 8 | import cn.iocoder.yudao.module.crm.dal.dataobject.contact.ContactDO; | 7 | import cn.iocoder.yudao.module.crm.dal.dataobject.contact.ContactDO; |
| @@ -71,11 +70,11 @@ public interface ContactService { | @@ -71,11 +70,11 @@ public interface ContactService { | ||
| 71 | * @param exportReqVO 查询条件 | 70 | * @param exportReqVO 查询条件 |
| 72 | * @return crm联系人列表 | 71 | * @return crm联系人列表 |
| 73 | */ | 72 | */ |
| 74 | - List<ContactDO> getContactList(ContactExportReqVO exportReqVO); | 73 | + List<ContactDO> getContactList(ContactPageReqVO exportReqVO); |
| 75 | 74 | ||
| 76 | /** | 75 | /** |
| 77 | * 获取所有联系人列表,只返回姓名和id | 76 | * 获取所有联系人列表,只返回姓名和id |
| 78 | * @return 所有联系人列表 | 77 | * @return 所有联系人列表 |
| 79 | */ | 78 | */ |
| 80 | - List<ContactDO> allContactList(); | 79 | + List<ContactDO> getContactList(); |
| 81 | } | 80 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/ContactServiceImpl.java
| @@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil; | @@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil; | ||
| 4 | import cn.hutool.core.collection.ListUtil; | 4 | import cn.hutool.core.collection.ListUtil; |
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactCreateReqVO; | 6 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactCreateReqVO; |
| 7 | -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactExportReqVO; | ||
| 8 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactPageReqVO; | 7 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactPageReqVO; |
| 9 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactUpdateReqVO; | 8 | import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.ContactUpdateReqVO; |
| 10 | import cn.iocoder.yudao.module.crm.convert.contact.ContactConvert; | 9 | import cn.iocoder.yudao.module.crm.convert.contact.ContactConvert; |
| @@ -57,7 +56,7 @@ public class ContactServiceImpl implements ContactService { | @@ -57,7 +56,7 @@ public class ContactServiceImpl implements ContactService { | ||
| 57 | 56 | ||
| 58 | @Override | 57 | @Override |
| 59 | @Transactional(rollbackFor = Exception.class) | 58 | @Transactional(rollbackFor = Exception.class) |
| 60 | - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS, level = CrmPermissionLevelEnum.WRITE) | 59 | + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS,bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) |
| 61 | public void updateContact(ContactUpdateReqVO updateReqVO) { | 60 | public void updateContact(ContactUpdateReqVO updateReqVO) { |
| 62 | // 校验存在 | 61 | // 校验存在 |
| 63 | validateContactExists(updateReqVO.getId()); | 62 | validateContactExists(updateReqVO.getId()); |
| @@ -68,7 +67,7 @@ public class ContactServiceImpl implements ContactService { | @@ -68,7 +67,7 @@ public class ContactServiceImpl implements ContactService { | ||
| 68 | 67 | ||
| 69 | @Override | 68 | @Override |
| 70 | @Transactional(rollbackFor = Exception.class) | 69 | @Transactional(rollbackFor = Exception.class) |
| 71 | - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS, level = CrmPermissionLevelEnum.WRITE) | 70 | + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS,bizId = "#id", level = CrmPermissionLevelEnum.WRITE) |
| 72 | public void deleteContact(Long id) { | 71 | public void deleteContact(Long id) { |
| 73 | // 校验存在 | 72 | // 校验存在 |
| 74 | validateContactExists(id); | 73 | validateContactExists(id); |
| @@ -83,7 +82,7 @@ public class ContactServiceImpl implements ContactService { | @@ -83,7 +82,7 @@ public class ContactServiceImpl implements ContactService { | ||
| 83 | } | 82 | } |
| 84 | 83 | ||
| 85 | @Override | 84 | @Override |
| 86 | - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS, level = CrmPermissionLevelEnum.READ) | 85 | + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACTS,bizId = "#id", level = CrmPermissionLevelEnum.READ) |
| 87 | public ContactDO getContact(Long id) { | 86 | public ContactDO getContact(Long id) { |
| 88 | return contactMapper.selectById(id); | 87 | return contactMapper.selectById(id); |
| 89 | } | 88 | } |
| @@ -102,13 +101,12 @@ public class ContactServiceImpl implements ContactService { | @@ -102,13 +101,12 @@ public class ContactServiceImpl implements ContactService { | ||
| 102 | } | 101 | } |
| 103 | 102 | ||
| 104 | @Override | 103 | @Override |
| 105 | - public List<ContactDO> getContactList(ContactExportReqVO exportReqVO) { | 104 | + public List<ContactDO> getContactList(ContactPageReqVO exportReqVO) { |
| 106 | return contactMapper.selectList(exportReqVO); | 105 | return contactMapper.selectList(exportReqVO); |
| 107 | } | 106 | } |
| 108 | 107 | ||
| 109 | @Override | 108 | @Override |
| 110 | - public List<ContactDO> allContactList() { | 109 | + public List<ContactDO> getContactList() { |
| 111 | return contactMapper.selectList(); | 110 | return contactMapper.selectList(); |
| 112 | } | 111 | } |
| 113 | - | ||
| 114 | } | 112 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java
| @@ -107,4 +107,10 @@ public interface CrmCustomerService { | @@ -107,4 +107,10 @@ public interface CrmCustomerService { | ||
| 107 | */ | 107 | */ |
| 108 | void receiveCustomer(List<Long> ids, Long ownerUserId); | 108 | void receiveCustomer(List<Long> ids, Long ownerUserId); |
| 109 | 109 | ||
| 110 | + /** | ||
| 111 | + * 获取客户列表 | ||
| 112 | + * @return 客户列表 | ||
| 113 | + * @author zyna | ||
| 114 | + */ | ||
| 115 | + List<CrmCustomerDO> getCustomerList(); | ||
| 110 | } | 116 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
| @@ -228,4 +228,57 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -228,4 +228,57 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 228 | } | 228 | } |
| 229 | } | 229 | } |
| 230 | 230 | ||
| 231 | + // TODO @puhui999:合并到 receiveCustomer 里 | ||
| 232 | + @Override | ||
| 233 | + @Transactional(rollbackFor = Exception.class) | ||
| 234 | + public void receive(Long id, Long userId) { | ||
| 235 | + // 1. 校验存在 | ||
| 236 | + CrmCustomerDO customer = customerMapper.selectById(id); | ||
| 237 | + if (customer == null) { | ||
| 238 | + throw exception(CUSTOMER_NOT_EXISTS); | ||
| 239 | + } | ||
| 240 | + // 1.2. 校验是否为公海数据 | ||
| 241 | + if (customer.getOwnerUserId() != null) { | ||
| 242 | + throw exception(CUSTOMER_NOT_IN_POOL); | ||
| 243 | + } | ||
| 244 | + | ||
| 245 | + // 2. 领取公海数据-设置负责人 | ||
| 246 | + customerMapper.updateById(new CrmCustomerDO().setId(customer.getId()).setOwnerUserId(userId)); | ||
| 247 | + // 3. 创建负责人数据权限 | ||
| 248 | + crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) | ||
| 249 | + .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 | ||
| 250 | + } | ||
| 251 | + | ||
| 252 | + @Override | ||
| 253 | + @Transactional(rollbackFor = Exception.class) | ||
| 254 | + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) | ||
| 255 | + public void putCustomerPool(Long id) { | ||
| 256 | + // 1. 校验存在 | ||
| 257 | + CrmCustomerDO customer = customerMapper.selectById(id); | ||
| 258 | + if (customer == null) { | ||
| 259 | + throw exception(CUSTOMER_NOT_EXISTS); | ||
| 260 | + } | ||
| 261 | + // TODO puhui999:校验合并到 validateCustomerOwnerExists、validateCustomerIsLocked | ||
| 262 | + // 1.2. 校验是否为公海数据 | ||
| 263 | + if (customer.getOwnerUserId() == null) { | ||
| 264 | + throw exception(CUSTOMER_IN_POOL); | ||
| 265 | + } | ||
| 266 | + // 1.3. 校验客户是否锁定 | ||
| 267 | + if (customer.getLockStatus()) { | ||
| 268 | + throw exception(CUSTOMER_LOCKED_PUT_POOL_FAIL); | ||
| 269 | + } | ||
| 270 | + | ||
| 271 | + // 2. 设置负责人为 NULL | ||
| 272 | + // TODO @puhui999:updateById 这么操作,是无法设置 null 的; | ||
| 273 | + customerMapper.updateById(new CrmCustomerDO().setId(customer.getId()).setOwnerUserId(null)); | ||
| 274 | + // 3. 删除负责人数据权限 | ||
| 275 | + crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(), | ||
| 276 | + CrmPermissionLevelEnum.OWNER.getLevel()); | ||
| 277 | + } | ||
| 278 | + | ||
| 279 | + @Override | ||
| 280 | + public List<CrmCustomerDO> getCustomerList() { | ||
| 281 | + return customerMapper.selectList(); | ||
| 282 | + } | ||
| 283 | + | ||
| 231 | } | 284 | } |
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/DictTypeConstants.java
| @@ -26,4 +26,6 @@ public interface DictTypeConstants { | @@ -26,4 +26,6 @@ public interface DictTypeConstants { | ||
| 26 | String SMS_SEND_STATUS = "system_sms_send_status"; // 短信发送状态 | 26 | String SMS_SEND_STATUS = "system_sms_send_status"; // 短信发送状态 |
| 27 | String SMS_RECEIVE_STATUS = "system_sms_receive_status"; // 短信接收状态 | 27 | String SMS_RECEIVE_STATUS = "system_sms_receive_status"; // 短信接收状态 |
| 28 | 28 | ||
| 29 | + String INFRA_BOOLEAN_STRING = "infra_boolean_string"; // boolean字典 | ||
| 30 | + | ||
| 29 | } | 31 | } |