Commit 6a6f669c7f2214316b6cae0dc19c6cb4e5b04a62
Committed by
Gitee
!854 CRM:【线索】
Merge pull request !854 from Minh-X/develop
Showing
9 changed files
with
135 additions
and
13 deletions
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 | |||
| 102 | + */ | ||
| 103 | + private String qq; | ||
| 104 | + /** | ||
| 105 | |||
| 106 | + */ | ||
| 107 | + private String wechat; | ||
| 108 | + /** | ||
| 109 | |||
| 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<CrmClueDO> { | @@ -37,6 +37,9 @@ public interface CrmClueMapper extends BaseMapperX<CrmClueDO> { | ||
| 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); |