Commit 439edcd1be2c503260a5c0411468c979c175a87f
1 parent
48661f98
code review:crm 线索的 crud
Showing
6 changed files
with
66 additions
and
68 deletions
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java
| @@ -12,6 +12,7 @@ public interface ErrorCodeConstants { | @@ -12,6 +12,7 @@ public interface ErrorCodeConstants { | ||
| 12 | // ========== 合同管理 1-020-000-000 ========== | 12 | // ========== 合同管理 1-020-000-000 ========== |
| 13 | ErrorCode CONTRACT_NOT_EXISTS = new ErrorCode(1_020_000_000, "合同不存在"); | 13 | ErrorCode CONTRACT_NOT_EXISTS = new ErrorCode(1_020_000_000, "合同不存在"); |
| 14 | 14 | ||
| 15 | + // TODO @wanwan:要单独一个分段噢 | ||
| 15 | ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_000_001, "线索不存在"); | 16 | ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_000_001, "线索不存在"); |
| 16 | 17 | ||
| 17 | } | 18 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java
| 1 | package cn.iocoder.yudao.module.crm.controller.admin.clue; | 1 | package cn.iocoder.yudao.module.crm.controller.admin.clue; |
| 2 | 2 | ||
| 3 | -import org.springframework.web.bind.annotation.*; | ||
| 4 | -import javax.annotation.Resource; | ||
| 5 | -import org.springframework.validation.annotation.Validated; | ||
| 6 | -import org.springframework.security.access.prepost.PreAuthorize; | ||
| 7 | -import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 8 | -import io.swagger.v3.oas.annotations.Parameter; | ||
| 9 | -import io.swagger.v3.oas.annotations.Operation; | ||
| 10 | - | ||
| 11 | -import javax.validation.constraints.*; | ||
| 12 | -import javax.validation.*; | ||
| 13 | -import javax.servlet.http.*; | ||
| 14 | -import java.util.*; | ||
| 15 | -import java.io.IOException; | ||
| 16 | - | ||
| 17 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 18 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 19 | -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||
| 20 | - | 4 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 21 | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | 5 | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| 22 | - | ||
| 23 | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | 6 | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; |
| 24 | -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*; | ||
| 25 | - | ||
| 26 | import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.*; | 7 | import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.*; |
| 27 | -import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; | ||
| 28 | import cn.iocoder.yudao.module.crm.convert.clue.CrmClueConvert; | 8 | import cn.iocoder.yudao.module.crm.convert.clue.CrmClueConvert; |
| 9 | +import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; | ||
| 29 | import cn.iocoder.yudao.module.crm.service.clue.CrmClueService; | 10 | import cn.iocoder.yudao.module.crm.service.clue.CrmClueService; |
| 11 | +import io.swagger.v3.oas.annotations.Operation; | ||
| 12 | +import io.swagger.v3.oas.annotations.Parameter; | ||
| 13 | +import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 14 | +import org.springframework.security.access.prepost.PreAuthorize; | ||
| 15 | +import org.springframework.validation.annotation.Validated; | ||
| 16 | +import org.springframework.web.bind.annotation.*; | ||
| 17 | + | ||
| 18 | +import javax.annotation.Resource; | ||
| 19 | +import javax.servlet.http.HttpServletResponse; | ||
| 20 | +import javax.validation.Valid; | ||
| 21 | +import java.io.IOException; | ||
| 22 | +import java.util.List; | ||
| 23 | + | ||
| 24 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||
| 25 | +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; | ||
| 30 | 26 | ||
| 31 | @Tag(name = "管理后台 - 线索") | 27 | @Tag(name = "管理后台 - 线索") |
| 32 | @RestController | 28 | @RestController |
| @@ -70,15 +66,6 @@ public class CrmClueController { | @@ -70,15 +66,6 @@ public class CrmClueController { | ||
| 70 | return success(CrmClueConvert.INSTANCE.convert(clue)); | 66 | return success(CrmClueConvert.INSTANCE.convert(clue)); |
| 71 | } | 67 | } |
| 72 | 68 | ||
| 73 | - @GetMapping("/list") | ||
| 74 | - @Operation(summary = "获得线索列表") | ||
| 75 | - @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048") | ||
| 76 | - @PreAuthorize("@ss.hasPermission('crm:clue:query')") | ||
| 77 | - public CommonResult<List<CrmClueRespVO>> getClueList(@RequestParam("ids") Collection<Long> ids) { | ||
| 78 | - List<CrmClueDO> list = clueService.getClueList(ids); | ||
| 79 | - return success(CrmClueConvert.INSTANCE.convertList(list)); | ||
| 80 | - } | ||
| 81 | - | ||
| 82 | @GetMapping("/page") | 69 | @GetMapping("/page") |
| 83 | @Operation(summary = "获得线索分页") | 70 | @Operation(summary = "获得线索分页") |
| 84 | @PreAuthorize("@ss.hasPermission('crm:clue:query')") | 71 | @PreAuthorize("@ss.hasPermission('crm:clue:query')") |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueBaseVO.java
| @@ -2,15 +2,12 @@ package cn.iocoder.yudao.module.crm.controller.admin.clue.vo; | @@ -2,15 +2,12 @@ package cn.iocoder.yudao.module.crm.controller.admin.clue.vo; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.validation.Mobile; | 3 | import cn.iocoder.yudao.framework.common.validation.Mobile; |
| 4 | import io.swagger.v3.oas.annotations.media.Schema; | 4 | import io.swagger.v3.oas.annotations.media.Schema; |
| 5 | -import lombok.*; | ||
| 6 | -import java.util.*; | ||
| 7 | -import java.time.LocalDateTime; | ||
| 8 | -import java.time.LocalDateTime; | ||
| 9 | -import java.time.LocalDateTime; | ||
| 10 | -import java.time.LocalDateTime; | ||
| 11 | -import javax.validation.constraints.*; | 5 | +import lombok.Data; |
| 12 | import org.springframework.format.annotation.DateTimeFormat; | 6 | import org.springframework.format.annotation.DateTimeFormat; |
| 13 | 7 | ||
| 8 | +import javax.validation.constraints.NotNull; | ||
| 9 | +import java.time.LocalDateTime; | ||
| 10 | + | ||
| 14 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | 11 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| 15 | 12 | ||
| 16 | /** | 13 | /** |
| @@ -20,18 +17,21 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ | @@ -20,18 +17,21 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ | ||
| 20 | @Data | 17 | @Data |
| 21 | public class CrmClueBaseVO { | 18 | public class CrmClueBaseVO { |
| 22 | 19 | ||
| 20 | + // TODO @wanwan:转化状态,新增和修改的时候,应该不传递的哈;而是在未来的时候,才会更新到 | ||
| 23 | @Schema(description = "转化状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") | 21 | @Schema(description = "转化状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") |
| 24 | @NotNull(message = "转化状态不能为空") | 22 | @NotNull(message = "转化状态不能为空") |
| 25 | private Boolean transformStatus; | 23 | private Boolean transformStatus; |
| 26 | 24 | ||
| 25 | + // TODO @wanwan:同 transformStatus | ||
| 27 | @Schema(description = "跟进状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") | 26 | @Schema(description = "跟进状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") |
| 28 | @NotNull(message = "跟进状态不能为空") | 27 | @NotNull(message = "跟进状态不能为空") |
| 29 | private Boolean followUpStatus; | 28 | private Boolean followUpStatus; |
| 30 | 29 | ||
| 31 | @Schema(description = "线索名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "线索xxx") | 30 | @Schema(description = "线索名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "线索xxx") |
| 32 | - @NotNull(message = "线索名称不能为空") | 31 | + @NotNull(message = "线索名称不能为空") // TODO @wanwan:应该是 NotEmpty 噢。空串都无法接受 |
| 33 | private String name; | 32 | private String name; |
| 34 | 33 | ||
| 34 | + // TODO @wanwan:中英文之间,要有个空格;例如说,客户 id 不能为空 | ||
| 35 | @Schema(description = "客户id", requiredMode = Schema.RequiredMode.REQUIRED, example = "520") | 35 | @Schema(description = "客户id", requiredMode = Schema.RequiredMode.REQUIRED, example = "520") |
| 36 | @NotNull(message = "客户id不能为空") | 36 | @NotNull(message = "客户id不能为空") |
| 37 | private Long customerId; | 37 | private Long customerId; |
| @@ -40,10 +40,12 @@ public class CrmClueBaseVO { | @@ -40,10 +40,12 @@ public class CrmClueBaseVO { | ||
| 40 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | 40 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 41 | private LocalDateTime contactNextTime; | 41 | private LocalDateTime contactNextTime; |
| 42 | 42 | ||
| 43 | + // TODO @wanwan:@Schema 在 @Mobile 之前,要保持统一的顺序;2)可以加个 @Telephone 的校验格式;应该不是手机的格式哈 | ||
| 43 | @Mobile(message = "电话格式不正确") | 44 | @Mobile(message = "电话格式不正确") |
| 44 | @Schema(description = "电话", example = "18000000000") | 45 | @Schema(description = "电话", example = "18000000000") |
| 45 | private String telephone; | 46 | private String telephone; |
| 46 | 47 | ||
| 48 | + // TODO @wanwan:@Schema 在 @Mobile 之前,要保持统一的顺序;2)类似 @Mobile 这个提示如果是默认的,就可以不写 message | ||
| 47 | @Mobile(message = "手机号格式不正确") | 49 | @Mobile(message = "手机号格式不正确") |
| 48 | @Schema(description = "手机号", example = "18000000000") | 50 | @Schema(description = "手机号", example = "18000000000") |
| 49 | private String mobile; | 51 | private String mobile; |
| @@ -52,6 +54,7 @@ public class CrmClueBaseVO { | @@ -52,6 +54,7 @@ public class CrmClueBaseVO { | ||
| 52 | private String address; | 54 | private String address; |
| 53 | 55 | ||
| 54 | @Schema(description = "负责人的用户编号", example = "27199") | 56 | @Schema(description = "负责人的用户编号", example = "27199") |
| 57 | + // TODO @wanwan:这个是必填字段哈; | ||
| 55 | private Long ownerUserId; | 58 | private Long ownerUserId; |
| 56 | 59 | ||
| 57 | @Schema(description = "最后跟进时间") | 60 | @Schema(description = "最后跟进时间") |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmCluePageReqVO.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 lombok.*; | ||
| 4 | -import java.util.*; | ||
| 5 | -import io.swagger.v3.oas.annotations.media.Schema; | ||
| 6 | import cn.iocoder.yudao.framework.common.pojo.PageParam; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 4 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 5 | +import lombok.Data; | ||
| 6 | +import lombok.EqualsAndHashCode; | ||
| 7 | +import lombok.ToString; | ||
| 7 | import org.springframework.format.annotation.DateTimeFormat; | 8 | import org.springframework.format.annotation.DateTimeFormat; |
| 9 | + | ||
| 8 | import java.time.LocalDateTime; | 10 | import java.time.LocalDateTime; |
| 9 | 11 | ||
| 10 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | 12 | import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; |
| @@ -15,6 +17,8 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ | @@ -15,6 +17,8 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ | ||
| 15 | @ToString(callSuper = true) | 17 | @ToString(callSuper = true) |
| 16 | public class CrmCluePageReqVO extends PageParam { | 18 | public class CrmCluePageReqVO extends PageParam { |
| 17 | 19 | ||
| 20 | + // TODO @wanwan:目前只要支持 name、mobile、telephone 的搜索即可;其它字段应该暂时不需要哈; | ||
| 21 | + | ||
| 18 | @Schema(description = "转化状态", example = "true") | 22 | @Schema(description = "转化状态", example = "true") |
| 19 | private Boolean transformStatus; | 23 | private Boolean transformStatus; |
| 20 | 24 |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/clue/CrmClueDO.java
| 1 | package cn.iocoder.yudao.module.crm.dal.dataobject.clue; | 1 | package cn.iocoder.yudao.module.crm.dal.dataobject.clue; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||
| 4 | +import com.baomidou.mybatisplus.annotation.KeySequence; | ||
| 5 | +import com.baomidou.mybatisplus.annotation.TableId; | ||
| 6 | +import com.baomidou.mybatisplus.annotation.TableName; | ||
| 3 | import com.sun.xml.bind.v2.TODO; | 7 | import com.sun.xml.bind.v2.TODO; |
| 4 | import lombok.*; | 8 | import lombok.*; |
| 5 | -import java.util.*; | ||
| 6 | -import java.time.LocalDateTime; | ||
| 7 | -import java.time.LocalDateTime; | ||
| 8 | -import java.time.LocalDateTime; | 9 | + |
| 9 | import java.time.LocalDateTime; | 10 | import java.time.LocalDateTime; |
| 10 | -import com.baomidou.mybatisplus.annotation.*; | ||
| 11 | -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||
| 12 | 11 | ||
| 12 | +// TODO 芋艿:字段的顺序,需要整理下; | ||
| 13 | /** | 13 | /** |
| 14 | * 线索 DO | 14 | * 线索 DO |
| 15 | * | 15 | * |
| @@ -68,6 +68,8 @@ public class CrmClueDO extends BaseDO { | @@ -68,6 +68,8 @@ public class CrmClueDO extends BaseDO { | ||
| 68 | private String address; | 68 | private String address; |
| 69 | /** | 69 | /** |
| 70 | * 负责人的用户编号 | 70 | * 负责人的用户编号 |
| 71 | + * | ||
| 72 | + * 关联 AdminUserDO 的 id 字段 | ||
| 71 | */ | 73 | */ |
| 72 | private Long ownerUserId; | 74 | private Long ownerUserId; |
| 73 | /** | 75 | /** |
| @@ -79,4 +81,8 @@ public class CrmClueDO extends BaseDO { | @@ -79,4 +81,8 @@ public class CrmClueDO extends BaseDO { | ||
| 79 | */ | 81 | */ |
| 80 | private String remark; | 82 | private String remark; |
| 81 | 83 | ||
| 84 | + // TODO 芋艿:客户级别; | ||
| 85 | + // TODO 芋艿:线索来源; | ||
| 86 | + // TODO 芋艿:客户行业; | ||
| 87 | + | ||
| 82 | } | 88 | } |
yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImplTest.java
| 1 | package cn.iocoder.yudao.module.crm.service.clue; | 1 | package cn.iocoder.yudao.module.crm.service.clue; |
| 2 | 2 | ||
| 3 | -import org.junit.jupiter.api.Disabled; | ||
| 4 | -import org.junit.jupiter.api.Test; | ||
| 5 | -import org.springframework.boot.test.mock.mockito.MockBean; | ||
| 6 | - | ||
| 7 | -import javax.annotation.Resource; | ||
| 8 | - | 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 9 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | 4 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; |
| 10 | - | ||
| 11 | -import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.*; | 5 | +import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueCreateReqVO; |
| 6 | +import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueExportReqVO; | ||
| 7 | +import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO; | ||
| 8 | +import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueUpdateReqVO; | ||
| 12 | import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; | 9 | import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; |
| 13 | import cn.iocoder.yudao.module.crm.dal.mysql.clue.CrmClueMapper; | 10 | import cn.iocoder.yudao.module.crm.dal.mysql.clue.CrmClueMapper; |
| 14 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | 11 | +import org.junit.jupiter.api.Disabled; |
| 12 | +import org.junit.jupiter.api.Test; | ||
| 13 | +import org.springframework.context.annotation.Import; | ||
| 15 | 14 | ||
| 16 | import javax.annotation.Resource; | 15 | import javax.annotation.Resource; |
| 17 | -import org.springframework.context.annotation.Import; | ||
| 18 | -import java.util.*; | ||
| 19 | -import java.time.LocalDateTime; | ||
| 20 | - | ||
| 21 | -import static cn.hutool.core.util.RandomUtil.*; | ||
| 22 | -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; | ||
| 23 | -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; | ||
| 24 | -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; | ||
| 25 | -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; | ||
| 26 | -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; | ||
| 27 | -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*; | 16 | +import java.util.List; |
| 17 | + | ||
| 18 | +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; | ||
| 19 | +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; | ||
| 20 | +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; | ||
| 21 | +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; | ||
| 22 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; | ||
| 23 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | ||
| 24 | +import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CLUE_NOT_EXISTS; | ||
| 28 | import static org.junit.jupiter.api.Assertions.*; | 25 | import static org.junit.jupiter.api.Assertions.*; |
| 29 | -import static org.mockito.Mockito.*; | ||
| 30 | 26 | ||
| 27 | +// TODO 芋艿:单测后续补; | ||
| 31 | /** | 28 | /** |
| 32 | * {@link CrmClueServiceImpl} 的单元测试类 | 29 | * {@link CrmClueServiceImpl} 的单元测试类 |
| 33 | * | 30 | * |