Commit 8f06d022930f013e253f4ac2df7fe4232b351b0c

Authored by puhui999
1 parent 7f569f32

crm-客户:完善 code review 提到的问题

yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java
... ... @@ -32,12 +32,12 @@ public interface ErrorCodeConstants {
32 32  
33 33 // ========== 客户管理 1_020_006_000 ==========
34 34 ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_020_006_000, "客户不存在");
35   - ErrorCode CUSTOMER_OWNER_EXISTS = new ErrorCode(1_020_006_001, "客户已存在所属负责人");
36   - ErrorCode CUSTOMER_LOCKED = new ErrorCode(1_020_006_002, "客户状态已锁定");
  35 + ErrorCode CUSTOMER_OWNER_EXISTS = new ErrorCode(1_020_006_001, "客户【{}】已存在所属负责人");
  36 + ErrorCode CUSTOMER_LOCKED = new ErrorCode(1_020_006_002, "客户【{}】状态已锁定");
37 37 ErrorCode CUSTOMER_ALREADY_DEAL = new ErrorCode(1_020_006_003, "客户已交易");
38   - ErrorCode CUSTOMER_NOT_IN_POOL = new ErrorCode(1_020_006_004, "客户领取失败,原因:不是公海客户");
39   - ErrorCode CUSTOMER_IN_POOL = new ErrorCode(1_020_006_005, "客户放入公海失败,原因:已经是公海客户");
40   - ErrorCode CUSTOMER_LOCKED_PUT_POOL_FAIL = new ErrorCode(1_020_006_006, "客户放入公海失败,原因:客户已锁定");
  38 + ErrorCode CUSTOMER_IN_POOL = new ErrorCode(1_020_006_004, "客户【{}】放入公海失败,原因:已经是公海客户");
  39 + ErrorCode CUSTOMER_LOCKED_PUT_POOL_FAIL = new ErrorCode(1_020_006_005, "客户【{}】放入公海失败,原因:客户已锁定");
  40 + ErrorCode CUSTOMER_UPDATE_OWNER_USER_FAIL = new ErrorCode(1_020_006_006, "更新客户【{}】负责人失败, 原因:系统异常");
41 41 // TODO @wanwan:这 2 个单独配置段噢
42 42 ErrorCode CUSTOMER_POOL_CONFIG_ERROR = new ErrorCode(1_020_006_001, "客户公海规则设置不正确");
43 43 ErrorCode CUSTOMER_LIMIT_CONFIG_NOT_EXISTS = new ErrorCode(1_020_006_002, "客户限制配置不存在");
... ... @@ -47,7 +47,7 @@ public interface ErrorCodeConstants {
47 47 ErrorCode CRM_PERMISSION_DENIED = new ErrorCode(1_020_007_001, "{}操作失败,原因:没有权限");
48 48 ErrorCode CRM_PERMISSION_MODEL_NOT_EXISTS = new ErrorCode(1_020_007_002, "{}不存在");
49 49 ErrorCode CRM_PERMISSION_MODEL_TRANSFER_FAIL_OWNER_USER_EXISTS = new ErrorCode(1_020_007_003, "{}操作失败,原因:转移对象已经是该负责人");
50   - ErrorCode CRM_PERMISSION_DELETE_FAIL = new ErrorCode(1_020_007_004, "删除数据权限失败,原因:参数异常");
  50 + ErrorCode CRM_PERMISSION_DELETE_FAIL = new ErrorCode(1_020_007_004, "删除数据权限失败,原因:批量删除权限的时候,只能属于同一个 bizId 下");
51 51 ErrorCode CRM_PERMISSION_DELETE_FAIL_EXIST_OWNER = new ErrorCode(1_020_007_005, "删除数据权限失败,原因:存在负责人");
52 52 ErrorCode CRM_PERMISSION_DELETE_DENIED = new ErrorCode(1_020_007_006, "删除数据权限失败,原因:没有权限");
53 53 ErrorCode CRM_PERMISSION_DELETE_SELF_PERMISSION_FAIL_EXIST_OWNER = new ErrorCode(1_020_007_007, "删除数据权限失败,原因:不能删除负责人");
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/ContactController.java
... ... @@ -7,7 +7,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 7 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
8 8 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
9 9 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*;
10   -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerExportReqVO;
  10 +import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
11 11 import cn.iocoder.yudao.module.crm.convert.contact.ContactConvert;
12 12 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.ContactDO;
13 13 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
... ... @@ -33,6 +33,7 @@ import java.util.Optional;
33 33 import java.util.stream.Collectors;
34 34  
35 35 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  36 +import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
36 37 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
37 38 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
38 39  
... ... @@ -83,7 +84,7 @@ public class ContactController {
83 84 public CommonResult<ContactRespVO> getContact(@RequestParam("id") Long id) {
84 85 ContactDO contact = contactService.getContact(id);
85 86 // TODO @zyna:需要考虑 null 的情况;
86   - ContactRespVO contactRespVO = ContactConvert.INSTANCE.convert(contact);
  87 + ContactRespVO contactRespVO = ContactConvert.INSTANCE.convert(contact);
87 88 // TODO @zyna:可以把数据读完后,convert 统一交给 ContactConvert,让 controller 更简洁;而 convert 专门去做一些转换逻辑
88 89 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(CollUtil.removeNull(Lists.newArrayList(
89 90 NumberUtil.parseLong(contact.getCreator()))));
... ... @@ -107,12 +108,14 @@ public class ContactController {
107 108 @PreAuthorize("@ss.hasPermission('crm:contact:query')")
108 109 public CommonResult<PageResult<ContactRespVO>> getContactPage(@Valid ContactPageReqVO pageVO) {
109 110 PageResult<ContactDO> pageData = contactService.getContactPage(pageVO);
110   - PageResult<ContactRespVO> pageResult =ContactConvert.INSTANCE.convertPage(pageData);
  111 + PageResult<ContactRespVO> pageResult = ContactConvert.INSTANCE.convertPage(pageData);
111 112 // TODO @zyna:需要考虑 null 的情况;
112 113 // TODO @zyna:可以把数据读完后,convert 统一交给 ContactConvert,让 controller 更简洁;而 convert 专门去做一些转换逻辑
113 114 //待接口实现后修改
114   - List<CrmCustomerDO> crmCustomerDOList = crmCustomerService.getCustomerList(new CrmCustomerExportReqVO());
115   - Map<Long,CrmCustomerDO> crmCustomerDOMap = crmCustomerDOList.stream().collect(Collectors.toMap(CrmCustomerDO::getId,v->v));
  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));
116 119 pageResult.getList().forEach(item -> {
117 120 item.setCustomerName(Optional.ofNullable(crmCustomerDOMap.get(item.getCustomerId())).map(CrmCustomerDO::getName).orElse(null));
118 121 });
... ... @@ -125,7 +128,7 @@ public class ContactController {
125 128 @PreAuthorize("@ss.hasPermission('crm:contact:export')")
126 129 @OperateLog(type = EXPORT)
127 130 public void exportContactExcel(@Valid ContactExportReqVO exportReqVO,
128   - HttpServletResponse response) throws IOException {
  131 + HttpServletResponse response) throws IOException {
129 132 List<ContactDO> list = contactService.getContactList(exportReqVO);
130 133 // 导出 Excel
131 134 List<ContactExcelVO> datas = ContactConvert.INSTANCE.convertList02(list);
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
... ... @@ -91,16 +91,6 @@ public class CrmCustomerController {
91 91 return success(CrmCustomerConvert.INSTANCE.convert(customer, userMap, deptMap));
92 92 }
93 93  
94   - // TODO @puhui999:合并到 receiveCustomer
95   - @PutMapping("/receive-")
96   - @Operation(summary = "领取客户公海数据")
97   - @Parameter(name = "id", description = "客户编号", required = true, example = "1024")
98   - @PreAuthorize("@ss.hasPermission('crm:customer:update')")
99   - public CommonResult<Boolean> receive(@RequestParam("id") Long id) {
100   - customerService.receive(id, getLoginUserId());
101   - return success(true);
102   - }
103   -
104 94 @GetMapping("/page")
105 95 @Operation(summary = "获得客户分页")
106 96 @PreAuthorize("@ss.hasPermission('crm:customer:query')")
... ... @@ -122,9 +112,9 @@ public class CrmCustomerController {
122 112 @Operation(summary = "导出客户 Excel")
123 113 @PreAuthorize("@ss.hasPermission('crm:customer:export')")
124 114 @OperateLog(type = EXPORT)
125   - public void exportCustomerExcel(@Valid CrmCustomerExportReqVO exportReqVO,
  115 + public void exportCustomerExcel(@Valid CrmCustomerPageReqVO pageVO,
126 116 HttpServletResponse response) throws IOException {
127   - List<CrmCustomerDO> list = customerService.getCustomerList(exportReqVO);
  117 + List<CrmCustomerDO> list = customerService.getCustomerPage(pageVO, getLoginUserId()).getList();
128 118 // 导出 Excel
129 119 List<CrmCustomerExcelVO> datas = CrmCustomerConvert.INSTANCE.convertList02(list);
130 120 ExcelUtils.write(response, "客户.xls", "数据", CrmCustomerExcelVO.class, datas);
... ... @@ -160,9 +150,9 @@ public class CrmCustomerController {
160 150  
161 151 @PutMapping("/receive")
162 152 @Operation(summary = "领取公海客户")
163   - @Parameter(name = "ids", description = "编号数组", required = true,example = "1,2,3")
  153 + @Parameter(name = "ids", description = "编号数组", required = true, example = "1,2,3")
164 154 @PreAuthorize("@ss.hasPermission('crm:customer:receive')")
165   - public CommonResult<Boolean> receiveCustomer(@RequestParam(value = "ids") List<Long> ids){
  155 + public CommonResult<Boolean> receiveCustomer(@RequestParam(value = "ids") List<Long> ids) {
166 156 customerService.receiveCustomer(ids, getLoginUserId());
167 157 return success(true);
168 158 }
... ... @@ -175,8 +165,11 @@ public class CrmCustomerController {
175 165 })
176 166 @PreAuthorize("@ss.hasPermission('crm:customer:distribute')")
177 167 public CommonResult<Boolean> distributeCustomer(@RequestParam(value = "ids") List<Long> ids,
178   - @RequestParam(value = "ownerUserId") Long ownerUserId){
179   - customerService.distributeCustomer(ids, ownerUserId);
  168 + @RequestParam(value = "ownerUserId") Long ownerUserId) {
  169 + // 校验负责人是否存在
  170 + adminUserApi.validateUserList(java.util.Collections.singletonList(ownerUserId));
  171 + // 领取公海数据
  172 + customerService.receiveCustomer(ids, ownerUserId);
180 173 return success(true);
181 174 }
182 175  
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerExportReqVO.java deleted
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   -// TODO 芋艿:导出最后做,等基本确认的差不多之后;
7   -@Schema(description = "管理后台 - CRM 客户 Excel 导出 Request VO,参数和 CrmCustomerPageReqVO 是一致的")
8   -@Data
9   -public class CrmCustomerExportReqVO {
10   -
11   - @Schema(description = "客户名称", example = "赵六")
12   - private String name;
13   -
14   - @Schema(description = "手机", example = "18000000000")
15   - private String mobile;
16   -
17   -}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java
1 1 package cn.iocoder.yudao.module.crm.dal.mysql.customer;
2 2  
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
3 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
... ... @@ -14,6 +15,8 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
14 15 import com.baomidou.mybatisplus.core.metadata.IPage;
15 16 import org.apache.ibatis.annotations.Mapper;
16 17  
  18 +import java.util.List;
  19 +
17 20 /**
18 21 * 客户 Mapper
19 22 *
... ... @@ -22,97 +25,70 @@ import org.apache.ibatis.annotations.Mapper;
22 25 @Mapper
23 26 public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
24 27  
25   - default PageResult<CrmCustomerDO> selectPage(CrmCustomerPageReqVO pageReqVO) {
26   - LambdaQueryWrapperX<CrmCustomerDO> queryWrapperX = new LambdaQueryWrapperX<>();
  28 + static void appendQueryParams(MPJLambdaWrapperX<CrmCustomerDO> mpjLambdaWrapperX, CrmCustomerPageReqVO pageReqVO, Long userId) {
27 29 if (pageReqVO.getPool()) { // 情况一:公海
28   - queryWrapperX.isNull(CrmCustomerDO::getOwnerUserId);
29   - } else {// 情况一:不是公海
30   - queryWrapperX.isNotNull(CrmCustomerDO::getOwnerUserId);
  30 + mpjLambdaWrapperX.isNull(CrmCustomerDO::getOwnerUserId);
  31 + } else { // 情况二:不是公海
  32 + mpjLambdaWrapperX.isNotNull(CrmCustomerDO::getOwnerUserId);
  33 + }
  34 + // TODO 场景数据过滤
  35 + if (CrmSceneEnum.isOwner(pageReqVO.getSceneType())) { // 场景一:我负责的数据
  36 + mpjLambdaWrapperX.eq(CrmCustomerDO::getOwnerUserId, userId);
31 37 }
32   - return selectPage(pageReqVO, queryWrapperX
33   - .likeIfPresent(CrmCustomerDO::getName, pageReqVO.getName())
34   - .eqIfPresent(CrmCustomerDO::getMobile, pageReqVO.getMobile())
35   - .eqIfPresent(CrmCustomerDO::getIndustryId, pageReqVO.getIndustryId())
36   - .eqIfPresent(CrmCustomerDO::getLevel, pageReqVO.getLevel())
37   - .eqIfPresent(CrmCustomerDO::getSource, pageReqVO.getSource()));
38 38 }
39 39  
40   - // TODO @puhui999:这个方法还要哇?
41   - default PageResult<CrmCustomerDO> selectPage1(CrmCustomerPageReqVO pageReqVO, Long userId) {
42   - LambdaQueryWrapperX<CrmCustomerDO> queryWrapperX = new LambdaQueryWrapperX<>();
43   - //queryWrapperX.sql
  40 + static void appendQueryParams(LambdaQueryWrapperX<CrmCustomerDO> lambdaQueryWrapperX, CrmCustomerPageReqVO pageReqVO, Long userId) {
44 41 if (pageReqVO.getPool()) { // 情况一:公海
45   - queryWrapperX.isNull(CrmCustomerDO::getOwnerUserId);
46   - } else {// 情况一:不是公海
47   - queryWrapperX.isNotNull(CrmCustomerDO::getOwnerUserId);
  42 + lambdaQueryWrapperX.isNull(CrmCustomerDO::getOwnerUserId);
  43 + } else { // 情况二:不是公海
  44 + lambdaQueryWrapperX.isNotNull(CrmCustomerDO::getOwnerUserId);
  45 + }
  46 + // TODO 场景数据过滤
  47 + if (CrmSceneEnum.isOwner(pageReqVO.getSceneType())) { // 场景一:我负责的数据
  48 + lambdaQueryWrapperX.eq(CrmCustomerDO::getOwnerUserId, userId);
48 49 }
49   - return selectPage(pageReqVO, queryWrapperX
50   - .likeIfPresent(CrmCustomerDO::getName, pageReqVO.getName())
51   - .eqIfPresent(CrmCustomerDO::getMobile, pageReqVO.getMobile())
52   - .eqIfPresent(CrmCustomerDO::getIndustryId, pageReqVO.getIndustryId())
53   - .eqIfPresent(CrmCustomerDO::getLevel, pageReqVO.getLevel())
54   - .eqIfPresent(CrmCustomerDO::getSource, pageReqVO.getSource()));
55 50 }
56 51  
57   - default PageResult<CrmCustomerDO> selectPage(CrmCustomerPageReqVO pageReqVO, Long userId) {
  52 + default int updateOwnerUserIdById(Long id, Long ownerUserId) {
  53 + return update(new LambdaUpdateWrapper<CrmCustomerDO>()
  54 + .eq(CrmCustomerDO::getId, id)
  55 + .set(CrmCustomerDO::getOwnerUserId, ownerUserId));
  56 + }
  57 +
  58 + default PageResult<CrmCustomerDO> selectPage(CrmCustomerPageReqVO pageReqVO, Long userId, Boolean admin) {
  59 + if (admin) { // 情况一:管理员查看
  60 + LambdaQueryWrapperX<CrmCustomerDO> queryWrapperX = new LambdaQueryWrapperX<>();
  61 + appendQueryParams(queryWrapperX, pageReqVO, userId);
  62 + return selectPage(pageReqVO, queryWrapperX
  63 + .likeIfPresent(CrmCustomerDO::getName, pageReqVO.getName())
  64 + .eqIfPresent(CrmCustomerDO::getMobile, pageReqVO.getMobile())
  65 + .eqIfPresent(CrmCustomerDO::getIndustryId, pageReqVO.getIndustryId())
  66 + .eqIfPresent(CrmCustomerDO::getLevel, pageReqVO.getLevel())
  67 + .eqIfPresent(CrmCustomerDO::getSource, pageReqVO.getSource()));
  68 + }
  69 + // 情况二:获取当前用户能看的分页数据
58 70 IPage<CrmCustomerDO> mpPage = MyBatisUtils.buildPage(pageReqVO);
59 71 MPJLambdaWrapperX<CrmCustomerDO> mpjLambdaWrapperX = new MPJLambdaWrapperX<>();
60 72 // 构建数据权限连表条件
61   - //CrmPermissionUtils.builderRightJoinQuery(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CUSTOMER.getType(), userId);
62 73 mpjLambdaWrapperX
63   - //.rightJoin("(SELECT t1.biz_id FROM crm_permission t1 WHERE (t1.biz_type = 1 AND t1.user_id = 1)) t2 on t.id = t2.biz_id");
64   - .rightJoin(CrmPermissionDO.class, CrmPermissionDO::getBizId, CrmCustomerDO::getId) // TODO @puhui999:应该是 inner join?
  74 + .innerJoin(CrmPermissionDO.class, CrmPermissionDO::getBizId, CrmCustomerDO::getId)
65 75 .eq(CrmPermissionDO::getBizType, CrmBizTypeEnum.CRM_CUSTOMER.getType())
66 76 .eq(CrmPermissionDO::getUserId, userId);
67   - /** TODO @芋艿:
68   - -- 常规连表-查询正常
69   - | ==> Preparing:
70   - SELECT t.id, t.name, t.follow_up_status, t.lock_status, t.deal_status,
71   - t.industry_id, t.level, t.source, t.mobile, t.telephone, t.website,
72   - t.qq, t.wechat, t.email, t.description, t.remark, t.owner_user_id,
73   - t.area_id, t.detail_address, t.contact_last_time, t.contact_next_time,
74   - t.create_time, t.update_time, t.creator, t.updater, t.deleted
75   - FROM crm_customer t RIGHT JOIN crm_permission t1 ON (t1.biz_id = t.id) AND t.tenant_id = 1
76   - WHERE t.deleted = 0 AND t1.deleted = 0
77   - AND (t1.biz_type = ? AND t1.user_id = ?
78   - AND t.owner_user_id IS NOT NULL AND t.level = ?) AND t1.tenant_id = 1 LIMIT ?
79   - | ==> Parameters: 2(Integer), 1(Long), 3(Integer), 10(Long)
80   -
81   - -- 连接子查询-报错,但是复制到 navicat 是可以正常执行的
82   - -- 区别点:常规连表会自动拼接租户 AND t.tenant_id = 1
83   - SELECT
84   - t.id,t.name,t.follow_up_status,t.lock_status,t.deal_status,t.industry_id,t.level,
85   - t.source,t.mobile,t.telephone,t.website,t.qq,t.wechat,t.email,t.description,t.remark,
86   - t.owner_user_id,t.area_id,t.detail_address,t.contact_last_time,t.contact_next_time,
87   - t.create_time,t.update_time,t.creator,t.updater,t.deleted
88   - FROM crm_customer t
89   - RIGHT JOIN (SELECT t1.biz_id FROM crm_permission t1 WHERE (t1.biz_type = 2 AND t1.user_id = 1)) t2 on t.id = t2.biz_id
90   - WHERE t.deleted=0
91   - AND (t.owner_user_id IS NOT NULL)
92   - */
93   - if (pageReqVO.getPool()) { // 情况一:公海
94   - mpjLambdaWrapperX.isNull(CrmCustomerDO::getOwnerUserId);
95   - } else { // 情况二:不是公海
96   - mpjLambdaWrapperX.isNotNull(CrmCustomerDO::getOwnerUserId);
97   - }
98   - // TODO 场景数据过滤
99   - if (CrmSceneEnum.isOwner(pageReqVO.getSceneType())) { // 场景一:我负责的数据
100   - mpjLambdaWrapperX.eq(CrmCustomerDO::getOwnerUserId, userId);
101   - }
102   - mpPage = selectJoinPage(mpPage, CrmCustomerDO.class, mpjLambdaWrapperX
  77 + appendQueryParams(mpjLambdaWrapperX, pageReqVO, userId);
  78 + mpjLambdaWrapperX
103 79 .selectAll(CrmCustomerDO.class)
104 80 .likeIfPresent(CrmCustomerDO::getName, pageReqVO.getName())
105 81 .eqIfPresent(CrmCustomerDO::getMobile, pageReqVO.getMobile())
106 82 .eqIfPresent(CrmCustomerDO::getIndustryId, pageReqVO.getIndustryId())
107 83 .eqIfPresent(CrmCustomerDO::getLevel, pageReqVO.getLevel())
108   - .eqIfPresent(CrmCustomerDO::getSource, pageReqVO.getSource()));
  84 + .eqIfPresent(CrmCustomerDO::getSource, pageReqVO.getSource());
  85 + // 特殊:不分页,直接查询全部
  86 + if (PageParam.PAGE_SIZE_NONE.equals(pageReqVO.getPageNo())) {
  87 + List<CrmCustomerDO> list = selectJoinList(CrmCustomerDO.class, mpjLambdaWrapperX);
  88 + return new PageResult<>(list, (long) list.size());
  89 + }
  90 + mpPage = selectJoinPage(mpPage, CrmCustomerDO.class, mpjLambdaWrapperX);
109 91 return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
110 92 }
111 93  
112   - default void updateCustomerByOwnerUserIdIsNull(Long id, CrmCustomerDO updateObj) {
113   - update(updateObj, new LambdaUpdateWrapper<CrmCustomerDO>()
114   - .eq(CrmCustomerDO::getId, id)
115   - .isNull(CrmCustomerDO::getOwnerUserId));
116   - }
117   -
118 94 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java
1 1 package cn.iocoder.yudao.module.crm.service.customer;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
  4 +import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerCreateReqVO;
  5 +import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
  6 +import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO;
  7 +import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerUpdateReqVO;
5 8 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
6 9  
7 10 import javax.validation.Valid;
... ... @@ -50,8 +53,8 @@ public interface CrmCustomerService {
50 53 * 获得客户列表
51 54 *
52 55 * @param ids 客户编号数组
53   - * @author ljlleo
54 56 * @return 客户列表
  57 + * @author ljlleo
55 58 */
56 59 List<CrmCustomerDO> getCustomerList(Collection<Long> ids);
57 60  
... ... @@ -65,14 +68,6 @@ public interface CrmCustomerService {
65 68 PageResult<CrmCustomerDO> getCustomerPage(CrmCustomerPageReqVO pageReqVO, Long userId);
66 69  
67 70 /**
68   - * 获得客户列表, 用于 Excel 导出
69   - *
70   - * @param exportReqVO 查询条件
71   - * @return 客户列表
72   - */
73   - List<CrmCustomerDO> getCustomerList(CrmCustomerExportReqVO exportReqVO);
74   -
75   - /**
76 71 * 校验客户是否存在
77 72 *
78 73 * @param customerId 客户 id
... ... @@ -107,25 +102,9 @@ public interface CrmCustomerService {
107 102 /**
108 103 * 领取公海客户
109 104 *
110   - * @param ids 要领取的客户编号数组
111   - */
112   - void receiveCustomer(List<Long>ids, Long ownerUserId);
113   -
114   - /**
115   - * 分配公海客户
116   - *
117   - * @param ids 要分配的客户编号数组
118   - * @param ownerUserId 分配的负责人编号
119   - * @author xiaqing
120   - */
121   - void distributeCustomer(List<Long>ids, Long ownerUserId);
122   -
123   - /**
124   - * 领取公海客户
125   - *
126   - * @param id 编号
127   - * @param userId 用户编号
  105 + * @param ids 要领取的客户编号数组
  106 + * @param ownerUserId 负责人
128 107 */
129   - void receive(Long id, Long userId);
  108 + void receiveCustomer(List<Long> ids, Long ownerUserId);
130 109  
131 110 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
1 1 package cn.iocoder.yudao.module.crm.service.customer;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
  4 +import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerCreateReqVO;
  5 +import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
  6 +import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO;
  7 +import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerUpdateReqVO;
5 8 import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert;
6 9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
7 10 import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper;
... ... @@ -15,8 +18,8 @@ import org.springframework.transaction.annotation.Transactional;
15 18 import org.springframework.validation.annotation.Validated;
16 19  
17 20 import javax.annotation.Resource;
  21 +import java.util.ArrayList;
18 22 import java.util.Collection;
19   -import java.util.Collections;
20 23 import java.util.List;
21 24 import java.util.Objects;
22 25  
... ... @@ -95,18 +98,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
95 98 public PageResult<CrmCustomerDO> getCustomerPage(CrmCustomerPageReqVO pageReqVO, Long userId) {
96 99 // 1.1. TODO 如果是超级管理员
97 100 boolean admin = false;
98   - if (admin) {
99   - return customerMapper.selectPage(pageReqVO);
100   - }
101   - // 1.2. 获取当前用户能看的分页数据
102   - return customerMapper.selectPage(pageReqVO, userId);
103   - }
104   -
105   - @Override
106   - public List<CrmCustomerDO> getCustomerList(CrmCustomerExportReqVO exportReqVO) {
107   - //return customerMapper.selectList(exportReqVO);
108   - // TODO puhui999: 等数据权限完善后再实现
109   - return Collections.emptyList();
  101 + return customerMapper.selectPage(pageReqVO, userId, admin);
110 102 }
111 103  
112 104 /**
... ... @@ -152,54 +144,81 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
152 144  
153 145 @Override
154 146 @Transactional(rollbackFor = Exception.class)
155   - public void receiveCustomer(List <Long> ids,Long ownerUserId) {
156   - transferCustomerOwner(ids, ownerUserId);
  147 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
  148 + public void putCustomerPool(Long id) {
  149 + // 1. 校验存在
  150 + CrmCustomerDO customer = customerMapper.selectById(id);
  151 + if (customer == null) {
  152 + throw exception(CUSTOMER_NOT_EXISTS);
  153 + }
  154 + // 1.2. 校验是否为公海数据
  155 + validateCustomerOwnerExists(customer, true);
  156 + // 1.3. 校验客户是否锁定
  157 + validateCustomerIsLocked(customer, true);
  158 +
  159 + // 2. 设置负责人为 NULL
  160 + int updateOwnerUserIncr = customerMapper.updateOwnerUserIdById(customer.getId(), null);
  161 + if (updateOwnerUserIncr == 0) {
  162 + throw exception(CUSTOMER_UPDATE_OWNER_USER_FAIL);
  163 + }
  164 + // 3. 删除负责人数据权限
  165 + crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(),
  166 + CrmPermissionLevelEnum.OWNER.getLevel());
157 167 }
158 168  
159 169 @Override
160 170 @Transactional(rollbackFor = Exception.class)
161   - public void distributeCustomer(List <Long> ids, Long ownerUserId) {
162   - transferCustomerOwner(ids, ownerUserId);
163   - }
164   -
165   - /**
166   - * 转移客户负责人
167   - *
168   - * @param ids 客户编号数组
169   - * @param ownerUserId 负责人编号
170   - */
171   - private void transferCustomerOwner(List <Long> ids, Long ownerUserId) {
172   - // 先一次性加载所有数据,校验客户是否可用
173   - List <CrmCustomerDO> customers = customerMapper.selectBatchIds(ids);
174   - for (CrmCustomerDO customer : customers) {
  171 + public void receiveCustomer(List<Long> ids, Long ownerUserId) {
  172 + // 1. 校验存在
  173 + List<CrmCustomerDO> customers = customerMapper.selectBatchIds(ids);
  174 + if (customers.size() != ids.size()) {
  175 + throw exception(CUSTOMER_NOT_EXISTS);
  176 + }
  177 + // 1.2. 校验状态
  178 + customers.forEach(customer -> {
175 179 // 校验是否已有负责人
176   - validateCustomerOwnerExists(customer);
  180 + validateCustomerOwnerExists(customer, false);
177 181 // 校验是否锁定
178   - validateCustomerIsLocked(customer);
  182 + validateCustomerIsLocked(customer, false);
179 183 // 校验成交状态
180 184 validateCustomerDeal(customer);
  185 + });
  186 +
  187 + // 2. 领取公海数据
  188 + List<CrmCustomerDO> updateCustomers = new ArrayList<>();
  189 + List<CrmPermissionCreateReqBO> createPermissions = new ArrayList<>();
  190 + customers.forEach(customer -> {
  191 + // 2.1. 设置负责人
  192 + updateCustomers.add(new CrmCustomerDO().setId(customer.getId()).setOwnerUserId(ownerUserId));
  193 + // 2.2. 创建负责人数据权限
  194 + createPermissions.add(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())
  195 + .setBizId(customer.getId()).setUserId(ownerUserId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
  196 + });
  197 +
  198 + // 3.1 更新客户负责人
  199 + customerMapper.updateBatch(updateCustomers);
  200 + // 3.2 创建负责人数据权限
  201 + crmPermissionService.createPermissionBatch(createPermissions);
  202 + }
  203 +
  204 + private void validateCustomerOwnerExists(CrmCustomerDO customer, Boolean pool) {
  205 + if (customer == null) { // 防御一下
  206 + throw exception(CUSTOMER_NOT_EXISTS);
181 207 }
182   -
183   - // TODO @QingX:这里是不是改成一次性更新;不然,如果有 20 个客户,就要执行 20 次 SQL 了;
184   - // 统一修改状态
185   - CrmCustomerDO updateDo = new CrmCustomerDO();
186   - updateDo.setOwnerUserId(ownerUserId);
187   - // TODO @QingX:如果更新的数量不对,则应该抛出异常,回滚,并错误提示;
188   - for (Long id : ids) {
189   - customerMapper.updateCustomerByOwnerUserIdIsNull(id,updateDo);
  208 + // 校验是否为公海数据
  209 + if (pool && customer.getOwnerUserId() == null) {
  210 + throw exception(CUSTOMER_IN_POOL, customer.getName());
190 211 }
191   - }
192   -
193   - // TODO @QingX:错误提示里面,可以把客户的名字带上哈;不然不知道是谁;
194   - private void validateCustomerOwnerExists(CrmCustomerDO customer) {
  212 + // 负责人已存在
195 213 if (customer.getOwnerUserId() != null) {
196   - throw exception(CUSTOMER_OWNER_EXISTS);
  214 + throw exception(CUSTOMER_OWNER_EXISTS, customer.getName());
197 215 }
  216 +
198 217 }
199 218  
200   - private void validateCustomerIsLocked(CrmCustomerDO customer) {
  219 + private void validateCustomerIsLocked(CrmCustomerDO customer, Boolean pool) {
201 220 if (customer.getLockStatus()) {
202   - throw exception(CUSTOMER_LOCKED);
  221 + throw exception(pool ? CUSTOMER_LOCKED_PUT_POOL_FAIL : CUSTOMER_LOCKED, customer.getName());
203 222 }
204 223 }
205 224  
... ... @@ -209,52 +228,4 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
209 228 }
210 229 }
211 230  
212   - // TODO @puhui999:合并到 receiveCustomer 里
213   - @Override
214   - @Transactional(rollbackFor = Exception.class)
215   - public void receive(Long id, Long userId) {
216   - // 1. 校验存在
217   - CrmCustomerDO customer = customerMapper.selectById(id);
218   - if (customer == null) {
219   - throw exception(CUSTOMER_NOT_EXISTS);
220   - }
221   - // 1.2. 校验是否为公海数据
222   - if (customer.getOwnerUserId() != null) {
223   - throw exception(CUSTOMER_NOT_IN_POOL);
224   - }
225   -
226   - // 2. 领取公海数据-设置负责人
227   - customerMapper.updateById(new CrmCustomerDO().setId(customer.getId()).setOwnerUserId(userId));
228   - // 3. 创建负责人数据权限
229   - crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())
230   - .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
231   - }
232   -
233   - @Override
234   - @Transactional(rollbackFor = Exception.class)
235   - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
236   - public void putCustomerPool(Long id) {
237   - // 1. 校验存在
238   - CrmCustomerDO customer = customerMapper.selectById(id);
239   - if (customer == null) {
240   - throw exception(CUSTOMER_NOT_EXISTS);
241   - }
242   - // TODO puhui999:校验合并到 validateCustomerOwnerExists、validateCustomerIsLocked
243   - // 1.2. 校验是否为公海数据
244   - if (customer.getOwnerUserId() == null) {
245   - throw exception(CUSTOMER_IN_POOL);
246   - }
247   - // 1.3. 校验客户是否锁定
248   - if (customer.getLockStatus()) {
249   - throw exception(CUSTOMER_LOCKED_PUT_POOL_FAIL);
250   - }
251   -
252   - // 2. 设置负责人为 NULL
253   - // TODO @puhui999:updateById 这么操作,是无法设置 null 的;
254   - customerMapper.updateById(new CrmCustomerDO().setId(customer.getId()).setOwnerUserId(null));
255   - // 3. 删除负责人数据权限
256   - crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(),
257   - CrmPermissionLevelEnum.OWNER.getLevel());
258   - }
259   -
260 231 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/business/BusinessStatusTypeServiceImplTest.java
1   -package cn.iocoder.yudao.module.crm.service.business;
2   -
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
5   -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.BusinessStatusTypePageReqVO;
6   -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.BusinessStatusTypeSaveReqVO;
7   -import cn.iocoder.yudao.module.crm.dal.dataobject.business.BusinessStatusTypeDO;
8   -import cn.iocoder.yudao.module.crm.dal.mysql.business.BusinessStatusTypeMapper;
9   -import org.junit.jupiter.api.Disabled;
10   -import org.junit.jupiter.api.Test;
11   -import org.springframework.context.annotation.Import;
12   -
13   -import javax.annotation.Resource;
14   -
15   -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
16   -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
17   -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
18   -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
19   -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_STATUS_TYPE_NOT_EXISTS;
20   -import static org.junit.jupiter.api.Assertions.*;
21   -
22   -/**
23   - * {@link BusinessStatusTypeServiceImpl} 的单元测试类
24   - *
25   - * @author ljlleo
26   - */
27   -@Import(BusinessStatusTypeServiceImpl.class)
28   -public class BusinessStatusTypeServiceImplTest extends BaseDbUnitTest {
29   -
30   - @Resource
31   - private BusinessStatusTypeServiceImpl businessStatusTypeService;
32   -
33   - @Resource
34   - private BusinessStatusTypeMapper businessStatusTypeMapper;
35   -
36   - @Test
37   - public void testCreateBusinessStatusType_success() {
38   - // 准备参数
39   - BusinessStatusTypeSaveReqVO createReqVO = randomPojo(BusinessStatusTypeSaveReqVO.class).setId(null);
40   -
41   - // 调用
42   - Long businessStatusTypeId = businessStatusTypeService.createBusinessStatusType(createReqVO);
43   - // 断言
44   - assertNotNull(businessStatusTypeId);
45   - // 校验记录的属性是否正确
46   - BusinessStatusTypeDO businessStatusType = businessStatusTypeMapper.selectById(businessStatusTypeId);
47   - assertPojoEquals(createReqVO, businessStatusType, "id");
48   - }
49   -
50   - @Test
51   - public void testUpdateBusinessStatusType_success() {
52   - // mock 数据
53   - BusinessStatusTypeDO dbBusinessStatusType = randomPojo(BusinessStatusTypeDO.class);
54   - businessStatusTypeMapper.insert(dbBusinessStatusType);// @Sql: 先插入出一条存在的数据
55   - // 准备参数
56   - BusinessStatusTypeSaveReqVO updateReqVO = randomPojo(BusinessStatusTypeSaveReqVO.class, o -> {
57   - o.setId(dbBusinessStatusType.getId()); // 设置更新的 ID
58   - });
59   -
60   - // 调用
61   - businessStatusTypeService.updateBusinessStatusType(updateReqVO);
62   - // 校验是否更新正确
63   - BusinessStatusTypeDO businessStatusType = businessStatusTypeMapper.selectById(updateReqVO.getId()); // 获取最新的
64   - assertPojoEquals(updateReqVO, businessStatusType);
65   - }
66   -
67   - @Test
68   - public void testUpdateBusinessStatusType_notExists() {
69   - // 准备参数
70   - BusinessStatusTypeSaveReqVO updateReqVO = randomPojo(BusinessStatusTypeSaveReqVO.class);
71   -
72   - // 调用, 并断言异常
73   - assertServiceException(() -> businessStatusTypeService.updateBusinessStatusType(updateReqVO), BUSINESS_STATUS_TYPE_NOT_EXISTS);
74   - }
75   -
76   - @Test
77   - public void testDeleteBusinessStatusType_success() {
78   - // mock 数据
79   - BusinessStatusTypeDO dbBusinessStatusType = randomPojo(BusinessStatusTypeDO.class);
80   - businessStatusTypeMapper.insert(dbBusinessStatusType);// @Sql: 先插入出一条存在的数据
81   - // 准备参数
82   - Long id = dbBusinessStatusType.getId();
83   -
84   - // 调用
85   - businessStatusTypeService.deleteBusinessStatusType(id);
86   - // 校验数据不存在了
87   - assertNull(businessStatusTypeMapper.selectById(id));
88   - }
89   -
90   - @Test
91   - public void testDeleteBusinessStatusType_notExists() {
92   - // 准备参数
93   - Long id = randomLongId();
94   -
95   - // 调用, 并断言异常
96   - assertServiceException(() -> businessStatusTypeService.deleteBusinessStatusType(id), BUSINESS_STATUS_TYPE_NOT_EXISTS);
97   - }
98   -
99   - @Test
100   - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
101   - public void testGetBusinessStatusTypePage() {
102   - // mock 数据
103   - BusinessStatusTypeDO dbBusinessStatusType = randomPojo(BusinessStatusTypeDO.class, o -> { // 等会查询到
104   - });
105   - businessStatusTypeMapper.insert(dbBusinessStatusType);
106   - // 准备参数
107   - BusinessStatusTypePageReqVO reqVO = new BusinessStatusTypePageReqVO();
108   -
109   - // 调用
110   - PageResult<BusinessStatusTypeDO> pageResult = businessStatusTypeService.getBusinessStatusTypePage(reqVO);
111   - // 断言
112   - assertEquals(1, pageResult.getTotal());
113   - assertEquals(1, pageResult.getList().size());
114   - assertPojoEquals(dbBusinessStatusType, pageResult.getList().get(0));
115   - }
116   -
117   -}
yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/businessstatus/CrmBusinessStatusServiceImplTest.java
1   -package cn.iocoder.yudao.module.crm.service.businessstatus;
2   -
3   -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
4   -import cn.iocoder.yudao.module.crm.controller.admin.businessstatus.vo.CrmBusinessStatusCreateReqVO;
5   -import cn.iocoder.yudao.module.crm.controller.admin.businessstatus.vo.CrmBusinessStatusExportReqVO;
6   -import cn.iocoder.yudao.module.crm.controller.admin.businessstatus.vo.CrmBusinessStatusUpdateReqVO;
7   -import cn.iocoder.yudao.module.crm.dal.dataobject.businessstatus.CrmBusinessStatusDO;
8   -import cn.iocoder.yudao.module.crm.dal.mysql.businessstatus.CrmBusinessStatusMapper;
9   -import org.junit.jupiter.api.Disabled;
10   -import org.junit.jupiter.api.Test;
11   -import org.springframework.context.annotation.Import;
12   -
13   -import javax.annotation.Resource;
14   -import java.util.List;
15   -
16   -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
17   -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
18   -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
19   -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
20   -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
21   -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_STATUS_NOT_EXISTS;
22   -import static org.junit.jupiter.api.Assertions.*;
23   -
24   -/**
25   - * {@link CrmBusinessStatusServiceImpl} 的单元测试类
26   - *
27   - * @author ljlleo
28   - */
29   -@Import(CrmBusinessStatusServiceImpl.class)
30   -public class CrmBusinessStatusServiceImplTest extends BaseDbUnitTest {
31   -
32   - @Resource
33   - private CrmBusinessStatusServiceImpl businessStatusService;
34   -
35   - @Resource
36   - private CrmBusinessStatusMapper businessStatusMapper;
37   -
38   - @Test
39   - public void testCreateBusinessStatus_success() {
40   - // 准备参数
41   - CrmBusinessStatusCreateReqVO reqVO = randomPojo(CrmBusinessStatusCreateReqVO.class);
42   -
43   - // 调用
44   - Long businessStatusId = businessStatusService.createBusinessStatus(reqVO);
45   - // 断言
46   - assertNotNull(businessStatusId);
47   - // 校验记录的属性是否正确
48   - CrmBusinessStatusDO businessStatus = businessStatusMapper.selectById(businessStatusId);
49   - assertPojoEquals(reqVO, businessStatus);
50   - }
51   -
52   - @Test
53   - public void testUpdateBusinessStatus_success() {
54   - // mock 数据
55   - CrmBusinessStatusDO dbBusinessStatus = randomPojo(CrmBusinessStatusDO.class);
56   - businessStatusMapper.insert(dbBusinessStatus);// @Sql: 先插入出一条存在的数据
57   - // 准备参数
58   - CrmBusinessStatusUpdateReqVO reqVO = randomPojo(CrmBusinessStatusUpdateReqVO.class, o -> {
59   - o.setId(dbBusinessStatus.getId()); // 设置更新的 ID
60   - });
61   -
62   - // 调用
63   - businessStatusService.updateBusinessStatus(reqVO);
64   - // 校验是否更新正确
65   - CrmBusinessStatusDO businessStatus = businessStatusMapper.selectById(reqVO.getId()); // 获取最新的
66   - assertPojoEquals(reqVO, businessStatus);
67   - }
68   -
69   - @Test
70   - public void testUpdateBusinessStatus_notExists() {
71   - // 准备参数
72   - CrmBusinessStatusUpdateReqVO reqVO = randomPojo(CrmBusinessStatusUpdateReqVO.class);
73   -
74   - // 调用, 并断言异常
75   - assertServiceException(() -> businessStatusService.updateBusinessStatus(reqVO), BUSINESS_STATUS_NOT_EXISTS);
76   - }
77   -
78   - @Test
79   - public void testDeleteBusinessStatus_success() {
80   - // mock 数据
81   - CrmBusinessStatusDO dbBusinessStatus = randomPojo(CrmBusinessStatusDO.class);
82   - businessStatusMapper.insert(dbBusinessStatus);// @Sql: 先插入出一条存在的数据
83   - // 准备参数
84   - Long id = dbBusinessStatus.getId();
85   -
86   - // 调用
87   - businessStatusService.deleteBusinessStatus(id);
88   - // 校验数据不存在了
89   - assertNull(businessStatusMapper.selectById(id));
90   - }
91   -
92   - @Test
93   - public void testDeleteBusinessStatus_notExists() {
94   - // 准备参数
95   - Long id = randomLongId();
96   -
97   - // 调用, 并断言异常
98   - assertServiceException(() -> businessStatusService.deleteBusinessStatus(id), BUSINESS_STATUS_NOT_EXISTS);
99   - }
100   -
101   - @Test
102   - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
103   - public void testGetBusinessStatusPage() {
104   - // mock 数据
105   - CrmBusinessStatusDO dbBusinessStatus = randomPojo(CrmBusinessStatusDO.class, o -> { // 等会查询到
106   - o.setTypeId(null);
107   - o.setName(null);
108   - o.setPercent(null);
109   - o.setSort(null);
110   - });
111   - businessStatusMapper.insert(dbBusinessStatus);
112   - // 测试 typeId 不匹配
113   - businessStatusMapper.insert(cloneIgnoreId(dbBusinessStatus, o -> o.setTypeId(null)));
114   - // 测试 name 不匹配
115   - businessStatusMapper.insert(cloneIgnoreId(dbBusinessStatus, o -> o.setName(null)));
116   - // 测试 percent 不匹配
117   - businessStatusMapper.insert(cloneIgnoreId(dbBusinessStatus, o -> o.setPercent(null)));
118   - // 测试 sort 不匹配
119   - businessStatusMapper.insert(cloneIgnoreId(dbBusinessStatus, o -> o.setSort(null)));
120   - // 准备参数
121   - //CrmBusinessStatusPageReqVO reqVO = new CrmBusinessStatusPageReqVO();
122   - //reqVO.setTypeId(null);
123   - //reqVO.setName(null);
124   - //reqVO.setPercent(null);
125   - //reqVO.setSort(null);
126   - //
127   - //// 调用
128   - //PageResult<CrmBusinessStatusDO> pageResult = businessStatusService.getBusinessStatusPage(reqVO);
129   - //// 断言
130   - //assertEquals(1, pageResult.getTotal());
131   - //assertEquals(1, pageResult.getList().size());
132   - //assertPojoEquals(dbBusinessStatus, pageResult.getList().get(0));
133   - }
134   -
135   - @Test
136   - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
137   - public void testGetBusinessStatusList() {
138   - // mock 数据
139   - CrmBusinessStatusDO dbBusinessStatus = randomPojo(CrmBusinessStatusDO.class, o -> { // 等会查询到
140   - o.setTypeId(null);
141   - o.setName(null);
142   - o.setPercent(null);
143   - o.setSort(null);
144   - });
145   - businessStatusMapper.insert(dbBusinessStatus);
146   - // 测试 typeId 不匹配
147   - businessStatusMapper.insert(cloneIgnoreId(dbBusinessStatus, o -> o.setTypeId(null)));
148   - // 测试 name 不匹配
149   - businessStatusMapper.insert(cloneIgnoreId(dbBusinessStatus, o -> o.setName(null)));
150   - // 测试 percent 不匹配
151   - businessStatusMapper.insert(cloneIgnoreId(dbBusinessStatus, o -> o.setPercent(null)));
152   - // 测试 sort 不匹配
153   - businessStatusMapper.insert(cloneIgnoreId(dbBusinessStatus, o -> o.setSort(null)));
154   - // 准备参数
155   - CrmBusinessStatusExportReqVO reqVO = new CrmBusinessStatusExportReqVO();
156   - reqVO.setTypeId(null);
157   - reqVO.setName(null);
158   - reqVO.setPercent(null);
159   - reqVO.setSort(null);
160   -
161   - // 调用
162   - List<CrmBusinessStatusDO> list = businessStatusService.getBusinessStatusList(reqVO);
163   - // 断言
164   - assertEquals(1, list.size());
165   - assertPojoEquals(dbBusinessStatus, list.get(0));
166   - }
167   -
168   -}
yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/businessstatustype/CrmBusinessStatusTypeServiceImplTest.java
1   -package cn.iocoder.yudao.module.crm.service.businessstatustype;
2   -
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
5   -import cn.iocoder.yudao.module.crm.controller.admin.businessstatustype.vo.CrmBusinessStatusTypeCreateReqVO;
6   -import cn.iocoder.yudao.module.crm.controller.admin.businessstatustype.vo.CrmBusinessStatusTypeExportReqVO;
7   -import cn.iocoder.yudao.module.crm.controller.admin.businessstatustype.vo.CrmBusinessStatusTypePageReqVO;
8   -import cn.iocoder.yudao.module.crm.controller.admin.businessstatustype.vo.CrmBusinessStatusTypeUpdateReqVO;
9   -import cn.iocoder.yudao.module.crm.dal.dataobject.businessstatustype.CrmBusinessStatusTypeDO;
10   -import cn.iocoder.yudao.module.crm.dal.mysql.businessstatustype.CrmBusinessStatusTypeMapper;
11   -import org.junit.jupiter.api.Disabled;
12   -import org.junit.jupiter.api.Test;
13   -import org.springframework.context.annotation.Import;
14   -
15   -import javax.annotation.Resource;
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.BUSINESS_STATUS_TYPE_NOT_EXISTS;
25   -import static org.junit.jupiter.api.Assertions.*;
26   -
27   -/**
28   - * {@link CrmBusinessStatusTypeServiceImpl} 的单元测试类
29   - *
30   - * @author ljlleo
31   - */
32   -@Import(CrmBusinessStatusTypeServiceImpl.class)
33   -public class CrmBusinessStatusTypeServiceImplTest extends BaseDbUnitTest {
34   -
35   - @Resource
36   - private CrmBusinessStatusTypeServiceImpl businessStatusTypeService;
37   -
38   - @Resource
39   - private CrmBusinessStatusTypeMapper businessStatusTypeMapper;
40   -
41   - @Test
42   - public void testCreateBusinessStatusType_success() {
43   - // 准备参数
44   - CrmBusinessStatusTypeCreateReqVO reqVO = randomPojo(CrmBusinessStatusTypeCreateReqVO.class);
45   -
46   - // 调用
47   - Long businessStatusTypeId = businessStatusTypeService.createBusinessStatusType(reqVO);
48   - // 断言
49   - assertNotNull(businessStatusTypeId);
50   - // 校验记录的属性是否正确
51   - CrmBusinessStatusTypeDO businessStatusType = businessStatusTypeMapper.selectById(businessStatusTypeId);
52   - assertPojoEquals(reqVO, businessStatusType);
53   - }
54   -
55   - @Test
56   - public void testUpdateBusinessStatusType_success() {
57   - // mock 数据
58   - CrmBusinessStatusTypeDO dbBusinessStatusType = randomPojo(CrmBusinessStatusTypeDO.class);
59   - businessStatusTypeMapper.insert(dbBusinessStatusType);// @Sql: 先插入出一条存在的数据
60   - // 准备参数
61   - CrmBusinessStatusTypeUpdateReqVO reqVO = randomPojo(CrmBusinessStatusTypeUpdateReqVO.class, o -> {
62   - o.setId(dbBusinessStatusType.getId()); // 设置更新的 ID
63   - });
64   -
65   - // 调用
66   - businessStatusTypeService.updateBusinessStatusType(reqVO);
67   - // 校验是否更新正确
68   - CrmBusinessStatusTypeDO businessStatusType = businessStatusTypeMapper.selectById(reqVO.getId()); // 获取最新的
69   - assertPojoEquals(reqVO, businessStatusType);
70   - }
71   -
72   - @Test
73   - public void testUpdateBusinessStatusType_notExists() {
74   - // 准备参数
75   - CrmBusinessStatusTypeUpdateReqVO reqVO = randomPojo(CrmBusinessStatusTypeUpdateReqVO.class);
76   -
77   - // 调用, 并断言异常
78   - assertServiceException(() -> businessStatusTypeService.updateBusinessStatusType(reqVO), BUSINESS_STATUS_TYPE_NOT_EXISTS);
79   - }
80   -
81   - @Test
82   - public void testDeleteBusinessStatusType_success() {
83   - // mock 数据
84   - CrmBusinessStatusTypeDO dbBusinessStatusType = randomPojo(CrmBusinessStatusTypeDO.class);
85   - businessStatusTypeMapper.insert(dbBusinessStatusType);// @Sql: 先插入出一条存在的数据
86   - // 准备参数
87   - Long id = dbBusinessStatusType.getId();
88   -
89   - // 调用
90   - businessStatusTypeService.deleteBusinessStatusType(id);
91   - // 校验数据不存在了
92   - assertNull(businessStatusTypeMapper.selectById(id));
93   - }
94   -
95   - @Test
96   - public void testDeleteBusinessStatusType_notExists() {
97   - // 准备参数
98   - Long id = randomLongId();
99   -
100   - // 调用, 并断言异常
101   - assertServiceException(() -> businessStatusTypeService.deleteBusinessStatusType(id), BUSINESS_STATUS_TYPE_NOT_EXISTS);
102   - }
103   -
104   - @Test
105   - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
106   - public void testGetBusinessStatusTypePage() {
107   - // mock 数据
108   - CrmBusinessStatusTypeDO dbBusinessStatusType = randomPojo(CrmBusinessStatusTypeDO.class, o -> { // 等会查询到
109   - o.setName(null);
110   - o.setDeptIds(null);
111   - o.setStatus(null);
112   - //o.setCreateTime(null);
113   - });
114   - businessStatusTypeMapper.insert(dbBusinessStatusType);
115   - // 测试 name 不匹配
116   - businessStatusTypeMapper.insert(cloneIgnoreId(dbBusinessStatusType, o -> o.setName(null)));
117   - // 测试 deptIds 不匹配
118   - businessStatusTypeMapper.insert(cloneIgnoreId(dbBusinessStatusType, o -> o.setDeptIds(null)));
119   - // 测试 status 不匹配
120   - businessStatusTypeMapper.insert(cloneIgnoreId(dbBusinessStatusType, o -> o.setStatus(null)));
121   - // 测试 createTime 不匹配
122   - //businessStatusTypeMapper.insert(cloneIgnoreId(dbBusinessStatusType, o -> o.setCreateTime(null)));
123   - // 准备参数
124   - CrmBusinessStatusTypePageReqVO reqVO = new CrmBusinessStatusTypePageReqVO();
125   - reqVO.setName(null);
126   - //reqVO.setDeptIds(null);
127   - reqVO.setStatus(null);
128   - //reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
129   -
130   - // 调用
131   - PageResult<CrmBusinessStatusTypeDO> pageResult = businessStatusTypeService.getBusinessStatusTypePage(reqVO);
132   - // 断言
133   - assertEquals(1, pageResult.getTotal());
134   - assertEquals(1, pageResult.getList().size());
135   - assertPojoEquals(dbBusinessStatusType, pageResult.getList().get(0));
136   - }
137   -
138   - @Test
139   - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
140   - public void testGetBusinessStatusTypeList() {
141   - // mock 数据
142   - CrmBusinessStatusTypeDO dbBusinessStatusType = randomPojo(CrmBusinessStatusTypeDO.class, o -> { // 等会查询到
143   - o.setName(null);
144   - o.setDeptIds(null);
145   - o.setStatus(null);
146   - //o.setCreateTime(null);
147   - });
148   - businessStatusTypeMapper.insert(dbBusinessStatusType);
149   - // 测试 name 不匹配
150   - businessStatusTypeMapper.insert(cloneIgnoreId(dbBusinessStatusType, o -> o.setName(null)));
151   - // 测试 deptIds 不匹配
152   - businessStatusTypeMapper.insert(cloneIgnoreId(dbBusinessStatusType, o -> o.setDeptIds(null)));
153   - // 测试 status 不匹配
154   - businessStatusTypeMapper.insert(cloneIgnoreId(dbBusinessStatusType, o -> o.setStatus(null)));
155   - // 测试 createTime 不匹配
156   - //businessStatusTypeMapper.insert(cloneIgnoreId(dbBusinessStatusType, o -> o.setCreateTime(null)));
157   - // 准备参数
158   - CrmBusinessStatusTypeExportReqVO reqVO = new CrmBusinessStatusTypeExportReqVO();
159   - reqVO.setName(null);
160   - reqVO.setDeptIds(null);
161   - reqVO.setStatus(null);
162   - reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
163   -
164   - // 调用
165   - List<CrmBusinessStatusTypeDO> list = businessStatusTypeService.getBusinessStatusTypeList(reqVO);
166   - // 断言
167   - assertEquals(1, list.size());
168   - assertPojoEquals(dbBusinessStatusType, list.get(0));
169   - }
170   -
171   -}
yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImplTest.java
... ... @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.crm.service.customer;
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
5 5 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerCreateReqVO;
6   -import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerExportReqVO;
7 6 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
8 7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerUpdateReqVO;
9 8 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
... ... @@ -15,8 +14,8 @@ import org.springframework.boot.test.mock.mockito.MockBean;
15 14 import org.springframework.context.annotation.Import;
16 15  
17 16 import javax.annotation.Resource;
18   -import java.util.List;
19 17  
  18 +import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
20 19 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
21 20 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
22 21 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
... ... @@ -160,17 +159,18 @@ public class CrmCustomerServiceImplTest extends BaseDbUnitTest {
160 159 // 测试 website 不匹配
161 160 customerMapper.insert(cloneIgnoreId(dbCustomer, o -> o.setWebsite(null)));
162 161 // 准备参数
163   - CrmCustomerExportReqVO reqVO = new CrmCustomerExportReqVO();
164   - reqVO.setName(null);
165   - reqVO.setMobile(null);
  162 + CrmCustomerPageReqVO reqVO = new CrmCustomerPageReqVO();
  163 + reqVO.setName("张三");
  164 + reqVO.setMobile("13888888888");
  165 + reqVO.setPageSize(PAGE_SIZE_NONE);
166 166 //reqVO.setTelephone(null);
167 167 //reqVO.setWebsite(null);
168 168  
169 169 // 调用
170   - List<CrmCustomerDO> list = customerService.getCustomerList(reqVO);
  170 + PageResult<CrmCustomerDO> pageResult = customerService.getCustomerPage(reqVO, 1L);
171 171 // 断言
172   - assertEquals(1, list.size());
173   - assertPojoEquals(dbCustomer, list.get(0));
  172 + assertEquals(1, pageResult.getList().size());
  173 + assertPojoEquals(dbCustomer, pageResult.getList().get(0));
174 174 }
175 175  
176 176 }
... ...