Commit 6a6f669c7f2214316b6cae0dc19c6cb4e5b04a62

Authored by 芋道源码
Committed by Gitee
2 parents 814b6f68 11ce24ad

!854 CRM:【线索】

Merge pull request !854 from Minh-X/develop
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java
@@ -99,7 +99,7 @@ public class CrmClueController { @@ -99,7 +99,7 @@ public class CrmClueController {
99 @PostMapping("/transform") 99 @PostMapping("/transform")
100 @Operation(summary = "线索转化为客户") 100 @Operation(summary = "线索转化为客户")
101 @PreAuthorize("@ss.hasPermission('crm:clue:update')") 101 @PreAuthorize("@ss.hasPermission('crm:clue:update')")
102 - public CommonResult<Boolean> translateCustomer(@Valid @RequestBody CrmClueTransformReqVO reqVO) { 102 + public CommonResult<Boolean> translateCustomer(@Valid @RequestBody CrmClueTranslateReqVO reqVO) {
103 clueService.translateCustomer(reqVO, getLoginUserId()); 103 clueService.translateCustomer(reqVO, getLoginUserId());
104 return success(Boolean.TRUE); 104 return success(Boolean.TRUE);
105 } 105 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmCluePageReqVO.java
@@ -30,4 +30,13 @@ public class CrmCluePageReqVO extends PageParam { @@ -30,4 +30,13 @@ public class CrmCluePageReqVO extends PageParam {
30 @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") 30 @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
31 private Boolean pool; // null 则表示为不是公海数据 31 private Boolean pool; // null 则表示为不是公海数据
32 32
  33 + @Schema(description = "所属行业", example = "1")
  34 + private Integer industryId;
  35 +
  36 + @Schema(description = "客户等级", example = "1")
  37 + private Integer level;
  38 +
  39 + @Schema(description = "客户来源", example = "1")
  40 + private Integer source;
  41 +
33 } 42 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueRespVO.java
@@ -77,4 +77,38 @@ public class CrmClueRespVO { @@ -77,4 +77,38 @@ public class CrmClueRespVO {
77 @ExcelProperty("创建时间") 77 @ExcelProperty("创建时间")
78 private LocalDateTime createTime; 78 private LocalDateTime createTime;
79 79
  80 + @Schema(description = "所属行业", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
  81 + @ExcelProperty(value = "所属行业", converter = DictConvert.class)
  82 + @DictFormat(cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY)
  83 + private Integer industryId;
  84 +
  85 + @Schema(description = "客户等级", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
  86 + @ExcelProperty(value = "客户等级", converter = DictConvert.class)
  87 + @DictFormat(cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_LEVEL)
  88 + private Integer level;
  89 +
  90 + @Schema(description = "客户来源", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
  91 + @ExcelProperty(value = "客户来源", converter = DictConvert.class)
  92 + @DictFormat(cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_SOURCE)
  93 + private Integer source;
  94 +
  95 + @Schema(description = "网址", example = "25682")
  96 + @ExcelProperty("网址")
  97 + private String website;
  98 +
  99 + @Schema(description = "QQ", example = "25682")
  100 + @ExcelProperty("QQ")
  101 + private String qq;
  102 +
  103 + @Schema(description = "wechat", example = "25682")
  104 + @ExcelProperty("wechat")
  105 + private String wechat;
  106 +
  107 + @Schema(description = "email", example = "25682")
  108 + @ExcelProperty("email")
  109 + private String email;
  110 +
  111 + @Schema(description = "客户描述", example = "25682")
  112 + @ExcelProperty("客户描述")
  113 + private String description;
80 } 114 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueSaveReqVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.clue.vo; 1 package cn.iocoder.yudao.module.crm.controller.admin.clue.vo;
2 2
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
3 import cn.iocoder.yudao.framework.common.validation.Mobile; 4 import cn.iocoder.yudao.framework.common.validation.Mobile;
4 import cn.iocoder.yudao.framework.common.validation.Telephone; 5 import cn.iocoder.yudao.framework.common.validation.Telephone;
  6 +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
  7 +import cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLevelEnum;
  8 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerIndustryParseFunction;
  9 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerLevelParseFunction;
  10 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerSourceParseFunction;
5 import com.mzt.logapi.starter.annotation.DiffLogField; 11 import com.mzt.logapi.starter.annotation.DiffLogField;
6 import io.swagger.v3.oas.annotations.media.Schema; 12 import io.swagger.v3.oas.annotations.media.Schema;
  13 +import jakarta.validation.constraints.Email;
7 import jakarta.validation.constraints.NotEmpty; 14 import jakarta.validation.constraints.NotEmpty;
  15 +import jakarta.validation.constraints.Size;
8 import lombok.Data; 16 import lombok.Data;
9 import org.springframework.format.annotation.DateTimeFormat; 17 import org.springframework.format.annotation.DateTimeFormat;
10 18
11 import java.time.LocalDateTime; 19 import java.time.LocalDateTime;
12 20
13 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; 21 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  22 +import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY;
14 23
15 @Schema(description = "管理后台 - CRM 线索 创建/更新 Request VO") 24 @Schema(description = "管理后台 - CRM 线索 创建/更新 Request VO")
16 @Data 25 @Data
@@ -55,4 +64,42 @@ public class CrmClueSaveReqVO { @@ -55,4 +64,42 @@ public class CrmClueSaveReqVO {
55 @DiffLogField(name = "备注") 64 @DiffLogField(name = "备注")
56 private String remark; 65 private String remark;
57 66
  67 + @Schema(description = "所属行业", example = "1")
  68 + @DiffLogField(name = "所属行业", function = CrmCustomerIndustryParseFunction.NAME)
  69 + @DictFormat(CRM_CUSTOMER_INDUSTRY)
  70 + private Integer industryId;
  71 +
  72 + @Schema(description = "客户等级", example = "2")
  73 + @DiffLogField(name = "客户等级", function = CrmCustomerLevelParseFunction.NAME)
  74 + @InEnum(CrmCustomerLevelEnum.class)
  75 + private Integer level;
  76 +
  77 + @Schema(description = "客户来源", example = "3")
  78 + @DiffLogField(name = "客户来源", function = CrmCustomerSourceParseFunction.NAME)
  79 + private Integer source;
  80 +
  81 + @Schema(description = "网址", example = "https://www.baidu.com")
  82 + @DiffLogField(name = "网址")
  83 + private String website;
  84 +
  85 + @Schema(description = "QQ", example = "123456789")
  86 + @DiffLogField(name = "QQ")
  87 + @Size(max = 20, message = "QQ长度不能超过 20 个字符")
  88 + private String qq;
  89 +
  90 + @Schema(description = "微信", example = "123456789")
  91 + @DiffLogField(name = "微信")
  92 + @Size(max = 255, message = "微信长度不能超过 255 个字符")
  93 + private String wechat;
  94 +
  95 + @Schema(description = "邮箱", example = "123456789@qq.com")
  96 + @DiffLogField(name = "邮箱")
  97 + @Email(message = "邮箱格式不正确")
  98 + @Size(max = 255, message = "邮箱长度不能超过 255 个字符")
  99 + private String email;
  100 +
  101 + @Schema(description = "客户描述", example = "任意文字")
  102 + @DiffLogField(name = "客户描述")
  103 + @Size(max = 4096, message = "客户描述长度不能超过 4096 个字符")
  104 + private String description;
58 } 105 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueTransformReqVO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueTranslateReqVO.java
@@ -8,7 +8,7 @@ import java.util.Set; @@ -8,7 +8,7 @@ import java.util.Set;
8 8
9 @Schema(description = "管理后台 - 线索转化为客户 Request VO") 9 @Schema(description = "管理后台 - 线索转化为客户 Request VO")
10 @Data 10 @Data
11 -public class CrmClueTransformReqVO { 11 +public class CrmClueTranslateReqVO {
12 12
13 @Schema(description = "线索编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1024, 1025]") 13 @Schema(description = "线索编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1024, 1025]")
14 @NotEmpty(message = "线索编号不能为空") 14 @NotEmpty(message = "线索编号不能为空")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/clue/CrmClueDO.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.dataobject.clue; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.dataobject.clue;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 4 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
  5 +import cn.iocoder.yudao.module.crm.enums.DictTypeConstants;
5 import com.baomidou.mybatisplus.annotation.KeySequence; 6 import com.baomidou.mybatisplus.annotation.KeySequence;
6 import com.baomidou.mybatisplus.annotation.TableId; 7 import com.baomidou.mybatisplus.annotation.TableId;
7 import com.baomidou.mybatisplus.annotation.TableName; 8 import com.baomidou.mybatisplus.annotation.TableName;
@@ -72,16 +73,44 @@ public class CrmClueDO extends BaseDO { @@ -72,16 +73,44 @@ public class CrmClueDO extends BaseDO {
72 * 备注 73 * 备注
73 */ 74 */
74 private String remark; 75 private String remark;
75 -  
76 /** 76 /**
77 * 负责人的用户编号 77 * 负责人的用户编号
78 - *  
79 * 关联 AdminUserDO 的 id 字段 78 * 关联 AdminUserDO 的 id 字段
80 */ 79 */
81 private Long ownerUserId; 80 private Long ownerUserId;
82 -  
83 - // TODO 芋艿:客户级别;  
84 - // TODO 芋艿:线索来源;  
85 - // TODO 芋艿:客户行业;  
86 - 81 + /**
  82 + * 所属行业
  83 + * 对应字典 {@link DictTypeConstants#CRM_CUSTOMER_INDUSTRY}
  84 + */
  85 + private Integer industryId;
  86 + /**
  87 + * 客户等级
  88 + * 对应字典 {@link DictTypeConstants#CRM_CUSTOMER_LEVEL}
  89 + */
  90 + private Integer level;
  91 + /**
  92 + * 客户来源
  93 + * 对应字典 {@link DictTypeConstants#CRM_CUSTOMER_SOURCE}
  94 + */
  95 + private Integer source;
  96 + /**
  97 + * 网址
  98 + */
  99 + private String website;
  100 + /**
  101 + * QQ
  102 + */
  103 + private String qq;
  104 + /**
  105 + * wechat
  106 + */
  107 + private String wechat;
  108 + /**
  109 + * email
  110 + */
  111 + private String email;
  112 + /**
  113 + * 客户描述
  114 + */
  115 + private String description;
87 } 116 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/clue/CrmClueMapper.java
@@ -37,6 +37,9 @@ public interface CrmClueMapper extends BaseMapperX&lt;CrmClueDO&gt; { @@ -37,6 +37,9 @@ public interface CrmClueMapper extends BaseMapperX&lt;CrmClueDO&gt; {
37 .likeIfPresent(CrmClueDO::getName, pageReqVO.getName()) 37 .likeIfPresent(CrmClueDO::getName, pageReqVO.getName())
38 .likeIfPresent(CrmClueDO::getTelephone, pageReqVO.getTelephone()) 38 .likeIfPresent(CrmClueDO::getTelephone, pageReqVO.getTelephone())
39 .likeIfPresent(CrmClueDO::getMobile, pageReqVO.getMobile()) 39 .likeIfPresent(CrmClueDO::getMobile, pageReqVO.getMobile())
  40 + .eqIfPresent(CrmClueDO::getIndustryId, pageReqVO.getIndustryId())
  41 + .eqIfPresent(CrmClueDO::getLevel, pageReqVO.getLevel())
  42 + .eqIfPresent(CrmClueDO::getSource, pageReqVO.getSource())
40 .orderByDesc(CrmClueDO::getId); 43 .orderByDesc(CrmClueDO::getId);
41 return selectJoinPage(pageReqVO, CrmClueDO.class, query); 44 return selectJoinPage(pageReqVO, CrmClueDO.class, query);
42 } 45 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java
@@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO; 4 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO;
5 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueSaveReqVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueSaveReqVO;
6 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO;
7 -import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransformReqVO; 7 +import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTranslateReqVO;
8 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;
9 import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; 9 import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO;
10 import jakarta.validation.Valid; 10 import jakarta.validation.Valid;
@@ -88,6 +88,6 @@ public interface CrmClueService { @@ -88,6 +88,6 @@ public interface CrmClueService {
88 * @param reqVO 线索编号 88 * @param reqVO 线索编号
89 * @param userId 用户编号 89 * @param userId 用户编号
90 */ 90 */
91 - void translateCustomer(CrmClueTransformReqVO reqVO, Long userId); 91 + void translateCustomer(CrmClueTranslateReqVO reqVO, Long userId);
92 92
93 } 93 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java
@@ -10,7 +10,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; @@ -10,7 +10,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
10 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO; 10 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO;
11 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueSaveReqVO; 11 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueSaveReqVO;
12 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO; 12 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO;
13 -import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransformReqVO; 13 +import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTranslateReqVO;
14 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerSaveReqVO; 14 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerSaveReqVO;
15 import cn.iocoder.yudao.module.crm.convert.clue.CrmClueConvert; 15 import cn.iocoder.yudao.module.crm.convert.clue.CrmClueConvert;
16 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; 16 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;
@@ -175,7 +175,7 @@ public class CrmClueServiceImpl implements CrmClueService { @@ -175,7 +175,7 @@ public class CrmClueServiceImpl implements CrmClueService {
175 @Override 175 @Override
176 @Transactional(rollbackFor = Exception.class) 176 @Transactional(rollbackFor = Exception.class)
177 @CrmPermission(bizType = CrmBizTypeEnum.CRM_LEADS, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) 177 @CrmPermission(bizType = CrmBizTypeEnum.CRM_LEADS, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
178 - public void translateCustomer(CrmClueTransformReqVO reqVO, Long userId) { 178 + public void translateCustomer(CrmClueTranslateReqVO reqVO, Long userId) {
179 // 1.1 校验线索都存在 179 // 1.1 校验线索都存在
180 Set<Long> clueIds = reqVO.getIds(); 180 Set<Long> clueIds = reqVO.getIds();
181 List<CrmClueDO> clues = getClueList(clueIds, userId); 181 List<CrmClueDO> clues = getClueList(clueIds, userId);