diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java index 616c8685c..6c0c24f0b 100644 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java @@ -86,4 +86,7 @@ public interface ErrorCodeConstants { ErrorCode FOLLOW_UP_RECORD_NOT_EXISTS = new ErrorCode(1_020_013_000, "跟进记录不存在"); ErrorCode FOLLOW_UP_RECORD_DELETE_DENIED = new ErrorCode(1_020_013_001, "删除跟进记录失败,原因:没有权限"); + // ========== 待办消息 1_020_014_000 ========== + ErrorCode BACKLOG_CONTACT_STATUS_INVALID = new ErrorCode(1_020_014_000, "客户联系状态有误"); + } diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/message/CrmContactStatusEnum.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/message/CrmContactStatusEnum.java deleted file mode 100644 index 6ca5f52dc..000000000 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/message/CrmContactStatusEnum.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.module.crm.enums.message; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -import java.util.Arrays; - -/** - * CRM 联系状态 - * - * @author dhb52 - */ -@RequiredArgsConstructor -@Getter -public enum CrmContactStatusEnum implements IntArrayValuable { - - NEEDED_TODAY(1, "今日需联系"), - EXPIRED(2, "已逾期"), - ALREADY_CONTACT(3, "已联系"), - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmContactStatusEnum::getType).toArray(); - - /** - * 状态 - */ - private final Integer type; - /** - * 状态名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/message/CrmMessageController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/backlog/CrmBacklogController.java similarity index 71% rename from yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/message/CrmMessageController.java rename to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/backlog/CrmBacklogController.java index 32a0eb6ca..9b8841e2e 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/message/CrmMessageController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/backlog/CrmBacklogController.java @@ -1,12 +1,12 @@ -package cn.iocoder.yudao.module.crm.controller.admin.message; +package cn.iocoder.yudao.module.crm.controller.admin.backlog; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerRespVO; -import cn.iocoder.yudao.module.crm.controller.admin.message.vo.CrmTodayCustomerPageReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.backlog.vo.CrmTodayCustomerPageReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; -import cn.iocoder.yudao.module.crm.service.message.CrmMessageService; +import cn.iocoder.yudao.module.crm.service.message.CrmBacklogService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; @@ -20,19 +20,19 @@ import org.springframework.web.bind.annotation.RestController; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; -@Tag(name = "管理后台 - CRM消息") +@Tag(name = "管理后台 - CRM待办消息") @RestController -@RequestMapping("/crm/message") +@RequestMapping("/crm/backlog") @Validated -public class CrmMessageController { +public class CrmBacklogController { @Resource - private CrmMessageService crmMessageService; + private CrmBacklogService crmMessageService; // TODO 芋艿:未来可能合并到 CrmCustomerController - @GetMapping("/todayCustomer") // TODO @dbh52:【优先级低】url 使用中划线,项目规范。然后叫 today-customer-page,通过 page 体现出它是个分页接口 + @GetMapping("/today-customer-page") @Operation(summary = "今日需联系客户") - @PreAuthorize("@ss.hasPermission('crm:message:todayCustomer')") + @PreAuthorize("@ss.hasPermission('crm:customer:query')") public CommonResult> getTodayCustomerPage(@Valid CrmTodayCustomerPageReqVO pageReqVO) { PageResult pageResult = crmMessageService.getTodayCustomerPage(pageReqVO, getLoginUserId()); return success(BeanUtils.toBean(pageResult, CrmCustomerRespVO.class)); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/message/vo/CrmTodayCustomerPageReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/backlog/vo/CrmTodayCustomerPageReqVO.java similarity index 65% rename from yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/message/vo/CrmTodayCustomerPageReqVO.java rename to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/backlog/vo/CrmTodayCustomerPageReqVO.java index f47dfb468..e054792a9 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/message/vo/CrmTodayCustomerPageReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/backlog/vo/CrmTodayCustomerPageReqVO.java @@ -1,9 +1,8 @@ -package cn.iocoder.yudao.module.crm.controller.admin.message.vo; +package cn.iocoder.yudao.module.crm.controller.admin.backlog.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum; -import cn.iocoder.yudao.module.crm.enums.message.CrmContactStatusEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -15,10 +14,12 @@ import lombok.ToString; @ToString(callSuper = true) public class CrmTodayCustomerPageReqVO extends PageParam { - // TODO @dbh52:CrmContactStatusEnum 可以直接枚举三个 Integer;一般来说,枚举类尽量给数据模型用,这样枚举类少,更聚焦;这里的枚举,更多是专门给这个接口用的哈 + public static final int CONTACT_TODAY = 1; + public static final int CONTACT_EXPIRED = 2; + public static final int CONTACT_ALREADY = 3; + @Schema(description = "联系状态", example = "1") - @InEnum(CrmContactStatusEnum.class) private Integer contactStatus; @Schema(description = "场景类型", example = "1") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java index 2e5b2d212..715500711 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java @@ -4,21 +4,24 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; +import cn.iocoder.yudao.module.crm.controller.admin.backlog.vo.CrmTodayCustomerPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.message.vo.CrmTodayCustomerPageReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -import cn.iocoder.yudao.module.crm.enums.message.CrmContactStatusEnum; import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; import org.springframework.lang.Nullable; import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.Collection; import java.util.List; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BACKLOG_CONTACT_STATUS_INVALID; + /** * 客户 Mapper * @@ -82,41 +85,22 @@ public interface CrmCustomerMapper extends BaseMapperX { CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), CrmCustomerDO::getId, userId, pageReqVO.getSceneType(), null); - query.selectAll(CrmCustomerDO.class) - .leftJoin(CrmFollowUpRecordDO.class, CrmFollowUpRecordDO::getBizId, CrmCustomerDO::getId) - .eq(CrmFollowUpRecordDO::getType, CrmBizTypeEnum.CRM_CUSTOMER.getType()); + query.selectAll(CrmCustomerDO.class); // 拼接自身的查询条件 - // TODO @dbh52:这里不仅仅要获得 today、tomorrow。而是 today 要获取今天的 00:00:00 这种; - LocalDate today = LocalDate.now(); - LocalDate tomorrow = today.plusDays(1); - LocalDate yesterday = today.minusDays(1); - if (pageReqVO.getContactStatus().equals(CrmContactStatusEnum.NEEDED_TODAY.getType())) { - // 今天需联系: - // 1.【客户】的【下一次联系时间】 是【今天】 - // 2. 无法找到【今天】创建的【跟进】记录 - query.between(CrmCustomerDO::getContactNextTime, today, tomorrow) - // TODO @dbh52:是不是查询 CrmCustomerDO::contactLastTime < today?因为今天联系过,应该会更新该字段,减少链表查询; - .between(CrmFollowUpRecordDO::getCreateTime, today, tomorrow) - .isNull(CrmFollowUpRecordDO::getId); - } else if (pageReqVO.getContactStatus().equals(CrmContactStatusEnum.EXPIRED.getType())) { - // 已逾期: - // 1. 【客户】的【下一次联系时间】 <= 【昨天】 - // 2. 无法找到【今天】创建的【跟进】记录 - // TODO @dbh52:是不是 contactNextTime 在当前时间之前,且 contactLastTime < contactNextTime?说白了,就是下次联系时间超过当前时间,且最后联系时间没去联系; - query.le(CrmCustomerDO::getContactNextTime, yesterday) - .between(CrmFollowUpRecordDO::getCreateTime, today, tomorrow) - .isNull(CrmFollowUpRecordDO::getId); - } else if (pageReqVO.getContactStatus().equals(CrmContactStatusEnum.ALREADY_CONTACT.getType())) { - // 已联系: - // 1.【客户】的【下一次联系时间】 是【今天】 - // 2. 找到【今天】创建的【跟进】记录 - query.between(CrmCustomerDO::getContactNextTime, today, tomorrow) - // TODO @dbh52:contactLastTime 是今天 - .between(CrmFollowUpRecordDO::getCreateTime, today, tomorrow) - .isNotNull(CrmFollowUpRecordDO::getId); + LocalDateTime beginOfToday = LocalDate.now().atTime(LocalTime.MIN); + LocalDateTime endOfToday = LocalDate.now().atTime(LocalTime.MAX); + if (pageReqVO.getContactStatus().equals(CrmTodayCustomerPageReqVO.CONTACT_TODAY)) { + // 今天需联系 + query.between(CrmCustomerDO::getContactNextTime, beginOfToday, endOfToday); + } else if (pageReqVO.getContactStatus().equals(CrmTodayCustomerPageReqVO.CONTACT_EXPIRED)) { + // 已逾期 + query.lt(CrmCustomerDO::getContactNextTime, beginOfToday); + } else if (pageReqVO.getContactStatus().equals(CrmTodayCustomerPageReqVO.CONTACT_ALREADY)) { + // 已联系 + query.between(CrmCustomerDO::getContactLastTime, beginOfToday, endOfToday); } else { - // TODO: 参数错误,是不是要兜一下底;直接抛出异常就好啦; + throw exception(BACKLOG_CONTACT_STATUS_INVALID); } return selectJoinPage(pageReqVO, CrmCustomerDO.class, query); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/message/CrmMessageService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/message/CrmBacklogService.java similarity index 60% rename from yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/message/CrmMessageService.java rename to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/message/CrmBacklogService.java index c0bdb42e8..f13514c25 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/message/CrmMessageService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/message/CrmBacklogService.java @@ -1,22 +1,22 @@ package cn.iocoder.yudao.module.crm.service.message; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.crm.controller.admin.message.vo.CrmTodayCustomerPageReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.backlog.vo.CrmTodayCustomerPageReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import jakarta.validation.Valid; /** - * CRM 代办消息 Service 接口 + * CRM 待办消息 Service 接口 * * @author dhb52 */ -public interface CrmMessageService { +public interface CrmBacklogService { /** - * TODO @dbh52:注释要写下 + * 根据【联系状态】、【场景类型】筛选客户分页 * - * @param pageReqVO - * @return + * @param pageReqVO 分页查询 + * @return 分页数据 */ PageResult getTodayCustomerPage(@Valid CrmTodayCustomerPageReqVO pageReqVO, Long userId); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/message/CrmMessageServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/message/CrmBacklogServiceImpl.java similarity index 80% rename from yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/message/CrmMessageServiceImpl.java rename to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/message/CrmBacklogServiceImpl.java index 523a64671..ff2560f09 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/message/CrmMessageServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/message/CrmBacklogServiceImpl.java @@ -1,17 +1,20 @@ package cn.iocoder.yudao.module.crm.service.message; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.crm.controller.admin.message.vo.CrmTodayCustomerPageReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.backlog.vo.CrmTodayCustomerPageReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper; import jakarta.annotation.Resource; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; -// TODO @dbh52:注释要写下 +/** + * 待办消息 Service 实现类 + */ + @Component @Validated -public class CrmMessageServiceImpl implements CrmMessageService { +public class CrmBacklogServiceImpl implements CrmBacklogService { @Resource private CrmCustomerMapper customerMapper;