Commit 1316f920818c127d1d3ad71da5d6474cf7d898eb

Authored by owen
2 parents f8604e17 23df8633

Merge remote-tracking branch 'origin/develop' into develop

Showing 49 changed files with 725 additions and 616 deletions
@@ -15,13 +15,13 @@ @@ -15,13 +15,13 @@
15 <!-- 各种 module 拓展 --> 15 <!-- 各种 module 拓展 -->
16 <module>yudao-module-system</module> 16 <module>yudao-module-system</module>
17 <module>yudao-module-infra</module> 17 <module>yudao-module-infra</module>
18 -<!-- <module>yudao-module-member</module>--> 18 + <module>yudao-module-member</module>
19 <!-- <module>yudao-module-bpm</module>--> 19 <!-- <module>yudao-module-bpm</module>-->
20 <!-- <module>yudao-module-report</module>--> 20 <!-- <module>yudao-module-report</module>-->
21 <!-- <module>yudao-module-mp</module>--> 21 <!-- <module>yudao-module-mp</module>-->
22 -<!-- <module>yudao-module-pay</module>-->  
23 -<!-- <module>yudao-module-mall</module>-->  
24 -<!-- <module>yudao-module-crm</module>--> 22 + <module>yudao-module-pay</module>
  23 + <module>yudao-module-mall</module>
  24 + <module>yudao-module-crm</module>
25 <!-- 示例项目 --> 25 <!-- 示例项目 -->
26 <!-- <module>yudao-example</module>--> 26 <!-- <module>yudao-example</module>-->
27 </modules> 27 </modules>
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
@@ -13,6 +13,7 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction; @@ -13,6 +13,7 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
13 import com.baomidou.mybatisplus.extension.toolkit.Db; 13 import com.baomidou.mybatisplus.extension.toolkit.Db;
14 import com.github.yulichang.base.MPJBaseMapper; 14 import com.github.yulichang.base.MPJBaseMapper;
15 import com.github.yulichang.interfaces.MPJBaseJoin; 15 import com.github.yulichang.interfaces.MPJBaseJoin;
  16 +import com.github.yulichang.wrapper.MPJLambdaWrapper;
16 import org.apache.ibatis.annotations.Param; 17 import org.apache.ibatis.annotations.Param;
17 18
18 import java.util.Collection; 19 import java.util.Collection;
@@ -40,6 +41,20 @@ public interface BaseMapperX&lt;T&gt; extends MPJBaseMapper&lt;T&gt; { @@ -40,6 +41,20 @@ public interface BaseMapperX&lt;T&gt; extends MPJBaseMapper&lt;T&gt; {
40 return new PageResult<>(mpPage.getRecords(), mpPage.getTotal()); 41 return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
41 } 42 }
42 43
  44 + default <D> PageResult<D> selectJoinPage(PageParam pageParam, Class<D> clazz, MPJLambdaWrapper<T> lambdaWrapper) {
  45 + // 特殊:不分页,直接查询全部
  46 + if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageNo())) {
  47 + List<D> list = selectJoinList(clazz, lambdaWrapper);
  48 + return new PageResult<>(list, (long) list.size());
  49 + }
  50 +
  51 + // MyBatis Plus Join 查询
  52 + IPage<D> mpPage = MyBatisUtils.buildPage(pageParam);
  53 + mpPage = selectJoinPage(mpPage, clazz, lambdaWrapper);
  54 + // 转换返回
  55 + return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
  56 + }
  57 +
43 default <DTO> PageResult<DTO> selectJoinPage(PageParam pageParam, Class<DTO> resultTypeClass, MPJBaseJoin<T> joinQueryWrapper) { 58 default <DTO> PageResult<DTO> selectJoinPage(PageParam pageParam, Class<DTO> resultTypeClass, MPJBaseJoin<T> joinQueryWrapper) {
44 IPage<DTO> mpPage = MyBatisUtils.buildPage(pageParam); 59 IPage<DTO> mpPage = MyBatisUtils.buildPage(pageParam);
45 selectJoinPage(mpPage, resultTypeClass, joinQueryWrapper); 60 selectJoinPage(mpPage, resultTypeClass, joinQueryWrapper);
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/common/CrmSceneEnum.java renamed to yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/common/CrmSceneTypeEnum.java
@@ -7,7 +7,6 @@ import lombok.Getter; @@ -7,7 +7,6 @@ import lombok.Getter;
7 7
8 import java.util.Arrays; 8 import java.util.Arrays;
9 9
10 -// TODO @puhui999:这个枚举,要不改成 CrmSceneTypeEnum  
11 /** 10 /**
12 * CRM 列表检索场景 11 * CRM 列表检索场景
13 * 12 *
@@ -15,14 +14,13 @@ import java.util.Arrays; @@ -15,14 +14,13 @@ import java.util.Arrays;
15 */ 14 */
16 @Getter 15 @Getter
17 @AllArgsConstructor 16 @AllArgsConstructor
18 -public enum CrmSceneEnum implements IntArrayValuable { 17 +public enum CrmSceneTypeEnum implements IntArrayValuable {
19 18
20 OWNER(1, "我负责的"), 19 OWNER(1, "我负责的"),
21 - FOLLOW(2, "我关注的"),  
22 - // TODO @puhui999:还有一个我参与的 20 + INVOLVED(2, "我参与的"),
23 SUBORDINATE(3, "下属负责的"); 21 SUBORDINATE(3, "下属负责的");
24 22
25 - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmSceneEnum::getType).toArray(); 23 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmSceneTypeEnum::getType).toArray();
26 24
27 /** 25 /**
28 * 场景类型 26 * 场景类型
@@ -37,8 +35,8 @@ public enum CrmSceneEnum implements IntArrayValuable { @@ -37,8 +35,8 @@ public enum CrmSceneEnum implements IntArrayValuable {
37 return ObjUtil.equal(OWNER.getType(), type); 35 return ObjUtil.equal(OWNER.getType(), type);
38 } 36 }
39 37
40 - public static boolean isFollow(Integer type) {  
41 - return ObjUtil.equal(FOLLOW.getType(), type); 38 + public static boolean isInvolved(Integer type) {
  39 + return ObjUtil.equal(INVOLVED.getType(), type);
42 } 40 }
43 41
44 public static boolean isSubordinate(Integer type) { 42 public static boolean isSubordinate(Integer type) {
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java
@@ -9,7 +9,6 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; @@ -9,7 +9,6 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
9 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*; 9 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*;
10 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusQueryVO; 10 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusQueryVO;
11 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeQueryVO; 11 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeQueryVO;
12 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;  
13 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert; 12 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert;
14 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 13 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
15 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; 14 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
@@ -22,13 +21,13 @@ import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; @@ -22,13 +21,13 @@ import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
22 import io.swagger.v3.oas.annotations.Operation; 21 import io.swagger.v3.oas.annotations.Operation;
23 import io.swagger.v3.oas.annotations.Parameter; 22 import io.swagger.v3.oas.annotations.Parameter;
24 import io.swagger.v3.oas.annotations.tags.Tag; 23 import io.swagger.v3.oas.annotations.tags.Tag;
  24 +import jakarta.annotation.Resource;
  25 +import jakarta.servlet.http.HttpServletResponse;
  26 +import jakarta.validation.Valid;
25 import org.springframework.security.access.prepost.PreAuthorize; 27 import org.springframework.security.access.prepost.PreAuthorize;
26 import org.springframework.validation.annotation.Validated; 28 import org.springframework.validation.annotation.Validated;
27 import org.springframework.web.bind.annotation.*; 29 import org.springframework.web.bind.annotation.*;
28 30
29 -import jakarta.annotation.Resource;  
30 -import jakarta.servlet.http.HttpServletResponse;  
31 -import jakarta.validation.Valid;  
32 import java.io.IOException; 31 import java.io.IOException;
33 import java.util.List; 32 import java.util.List;
34 import java.util.Objects; 33 import java.util.Objects;
@@ -36,6 +35,7 @@ import java.util.Set; @@ -36,6 +35,7 @@ import java.util.Set;
36 import java.util.stream.Collectors; 35 import java.util.stream.Collectors;
37 36
38 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 37 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  38 +import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
39 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 39 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
40 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 40 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
41 41
@@ -102,7 +102,7 @@ public class CrmBusinessController { @@ -102,7 +102,7 @@ public class CrmBusinessController {
102 // TODO @ljlleo:可以使用 CollectionUtils.convertSet 替代常用的 stream 操作,更简洁一点;下面几个也是哈; 102 // TODO @ljlleo:可以使用 CollectionUtils.convertSet 替代常用的 stream 操作,更简洁一点;下面几个也是哈;
103 Set<Long> customerIds = pageResult.getList().stream() 103 Set<Long> customerIds = pageResult.getList().stream()
104 .map(CrmBusinessDO::getCustomerId).filter(Objects::nonNull).collect(Collectors.toSet()); 104 .map(CrmBusinessDO::getCustomerId).filter(Objects::nonNull).collect(Collectors.toSet());
105 - List<CrmCustomerDO> customerList = customerService.getCustomerList(customerIds); 105 + List<CrmCustomerDO> customerList = customerService.getCustomerList(customerIds, getLoginUserId());
106 // 处理商机状态类型名称回显 106 // 处理商机状态类型名称回显
107 Set<Long> statusTypeIds = pageResult.getList().stream() 107 Set<Long> statusTypeIds = pageResult.getList().stream()
108 .map(CrmBusinessDO::getStatusTypeId).filter(Objects::nonNull).collect(Collectors.toSet()); 108 .map(CrmBusinessDO::getStatusTypeId).filter(Objects::nonNull).collect(Collectors.toSet());
@@ -120,14 +120,14 @@ public class CrmBusinessController { @@ -120,14 +120,14 @@ public class CrmBusinessController {
120 120
121 @GetMapping("/page-by-customer") 121 @GetMapping("/page-by-customer")
122 @Operation(summary = "获得商机分页,基于指定客户") 122 @Operation(summary = "获得商机分页,基于指定客户")
123 - public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByCustomer(@Valid CrmContractPageReqVO pageReqVO) { 123 + public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByCustomer(@Valid CrmBusinessPageReqVO pageReqVO) {
124 Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空"); 124 Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
125 - PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPageByCustomer(pageReqVO); 125 + PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPageByCustomer(pageReqVO, getLoginUserId());
126 // 处理客户名称回显 126 // 处理客户名称回显
127 // TODO @ljlleo:可以使用 CollectionUtils.convertSet 替代常用的 stream 操作,更简洁一点;下面几个也是哈; 127 // TODO @ljlleo:可以使用 CollectionUtils.convertSet 替代常用的 stream 操作,更简洁一点;下面几个也是哈;
128 Set<Long> customerIds = pageResult.getList().stream() 128 Set<Long> customerIds = pageResult.getList().stream()
129 .map(CrmBusinessDO::getCustomerId).filter(Objects::nonNull).collect(Collectors.toSet()); 129 .map(CrmBusinessDO::getCustomerId).filter(Objects::nonNull).collect(Collectors.toSet());
130 - List<CrmCustomerDO> customerList = customerService.getCustomerList(customerIds); 130 + List<CrmCustomerDO> customerList = customerService.getCustomerList(customerIds, getLoginUserId());
131 // 处理商机状态类型名称回显 131 // 处理商机状态类型名称回显
132 Set<Long> statusTypeIds = pageResult.getList().stream() 132 Set<Long> statusTypeIds = pageResult.getList().stream()
133 .map(CrmBusinessDO::getStatusTypeId).filter(Objects::nonNull).collect(Collectors.toSet()); 133 .map(CrmBusinessDO::getStatusTypeId).filter(Objects::nonNull).collect(Collectors.toSet());
@@ -143,20 +143,13 @@ public class CrmBusinessController { @@ -143,20 +143,13 @@ public class CrmBusinessController {
143 return success(CrmBusinessConvert.INSTANCE.convertPage(pageResult, customerList, statusTypeList, statusList)); 143 return success(CrmBusinessConvert.INSTANCE.convertPage(pageResult, customerList, statusTypeList, statusList));
144 } 144 }
145 145
146 - @GetMapping("/pool-page")  
147 - @Operation(summary = "获得商机公海分页")  
148 - @PreAuthorize("@ss.hasPermission('crm:business:query')")  
149 - public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPoolPage(@Valid CrmBusinessPageReqVO pageVO) {  
150 - // TODO puhui999: 等数据权限完善后再实现  
151 - return null;  
152 - }  
153 -  
154 @GetMapping("/export-excel") 146 @GetMapping("/export-excel")
155 @Operation(summary = "导出商机 Excel") 147 @Operation(summary = "导出商机 Excel")
156 @PreAuthorize("@ss.hasPermission('crm:business:export')") 148 @PreAuthorize("@ss.hasPermission('crm:business:export')")
157 @OperateLog(type = EXPORT) 149 @OperateLog(type = EXPORT)
158 public void exportBusinessExcel(@Valid CrmBusinessPageReqVO exportReqVO, 150 public void exportBusinessExcel(@Valid CrmBusinessPageReqVO exportReqVO,
159 HttpServletResponse response) throws IOException { 151 HttpServletResponse response) throws IOException {
  152 + exportReqVO.setPageSize(PAGE_SIZE_NONE);
160 PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(exportReqVO, getLoginUserId()); 153 PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(exportReqVO, getLoginUserId());
161 // 导出 Excel 154 // 导出 Excel
162 ExcelUtils.write(response, "商机.xls", "数据", CrmBusinessExcelVO.class, 155 ExcelUtils.write(response, "商机.xls", "数据", CrmBusinessExcelVO.class,
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessPageReqVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business; 1 package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
4 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 7 import lombok.Data;
6 import lombok.EqualsAndHashCode; 8 import lombok.EqualsAndHashCode;
@@ -18,4 +20,11 @@ public class CrmBusinessPageReqVO extends PageParam { @@ -18,4 +20,11 @@ public class CrmBusinessPageReqVO extends PageParam {
18 @Schema(description = "客户编号", example = "10795") 20 @Schema(description = "客户编号", example = "10795")
19 private Long customerId; 21 private Long customerId;
20 22
  23 + @Schema(description = "场景类型", example = "1")
  24 + @InEnum(CrmSceneTypeEnum.class)
  25 + private Integer sceneType; // 场景类型,为 null 时则表示全部
  26 +
  27 + @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
  28 + private Boolean pool; // null 则表示为不是公海数据
  29 +
21 } 30 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java
@@ -11,18 +11,20 @@ import cn.iocoder.yudao.module.crm.service.clue.CrmClueService; @@ -11,18 +11,20 @@ import cn.iocoder.yudao.module.crm.service.clue.CrmClueService;
11 import io.swagger.v3.oas.annotations.Operation; 11 import io.swagger.v3.oas.annotations.Operation;
12 import io.swagger.v3.oas.annotations.Parameter; 12 import io.swagger.v3.oas.annotations.Parameter;
13 import io.swagger.v3.oas.annotations.tags.Tag; 13 import io.swagger.v3.oas.annotations.tags.Tag;
  14 +import jakarta.annotation.Resource;
  15 +import jakarta.servlet.http.HttpServletResponse;
  16 +import jakarta.validation.Valid;
14 import org.springframework.security.access.prepost.PreAuthorize; 17 import org.springframework.security.access.prepost.PreAuthorize;
15 import org.springframework.validation.annotation.Validated; 18 import org.springframework.validation.annotation.Validated;
16 import org.springframework.web.bind.annotation.*; 19 import org.springframework.web.bind.annotation.*;
17 20
18 -import jakarta.annotation.Resource;  
19 -import jakarta.servlet.http.HttpServletResponse;  
20 -import jakarta.validation.Valid;  
21 import java.io.IOException; 21 import java.io.IOException;
22 import java.util.List; 22 import java.util.List;
23 23
24 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 24 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  25 +import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
25 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 26 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  27 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
26 28
27 @Tag(name = "管理后台 - 线索") 29 @Tag(name = "管理后台 - 线索")
28 @RestController 30 @RestController
@@ -70,7 +72,7 @@ public class CrmClueController { @@ -70,7 +72,7 @@ public class CrmClueController {
70 @Operation(summary = "获得线索分页") 72 @Operation(summary = "获得线索分页")
71 @PreAuthorize("@ss.hasPermission('crm:clue:query')") 73 @PreAuthorize("@ss.hasPermission('crm:clue:query')")
72 public CommonResult<PageResult<CrmClueRespVO>> getCluePage(@Valid CrmCluePageReqVO pageVO) { 74 public CommonResult<PageResult<CrmClueRespVO>> getCluePage(@Valid CrmCluePageReqVO pageVO) {
73 - PageResult<CrmClueDO> pageResult = clueService.getCluePage(pageVO); 75 + PageResult<CrmClueDO> pageResult = clueService.getCluePage(pageVO, getLoginUserId());
74 return success(CrmClueConvert.INSTANCE.convertPage(pageResult)); 76 return success(CrmClueConvert.INSTANCE.convertPage(pageResult));
75 } 77 }
76 78
@@ -78,9 +80,9 @@ public class CrmClueController { @@ -78,9 +80,9 @@ public class CrmClueController {
78 @Operation(summary = "导出线索 Excel") 80 @Operation(summary = "导出线索 Excel")
79 @PreAuthorize("@ss.hasPermission('crm:clue:export')") 81 @PreAuthorize("@ss.hasPermission('crm:clue:export')")
80 @OperateLog(type = EXPORT) 82 @OperateLog(type = EXPORT)
81 - public void exportClueExcel(@Valid CrmClueExportReqVO exportReqVO,  
82 - HttpServletResponse response) throws IOException {  
83 - List<CrmClueDO> list = clueService.getClueList(exportReqVO); 83 + public void exportClueExcel(@Valid CrmCluePageReqVO pageReqVO, HttpServletResponse response) throws IOException {
  84 + pageReqVO.setPageSize(PAGE_SIZE_NONE);
  85 + List<CrmClueDO> list = clueService.getCluePage(pageReqVO, getLoginUserId()).getList();
84 // 导出 Excel 86 // 导出 Excel
85 List<CrmClueExcelVO> datas = CrmClueConvert.INSTANCE.convertList02(list); 87 List<CrmClueExcelVO> datas = CrmClueConvert.INSTANCE.convertList02(list);
86 ExcelUtils.write(response, "线索.xls", "数据", CrmClueExcelVO.class, datas); 88 ExcelUtils.write(response, "线索.xls", "数据", CrmClueExcelVO.class, datas);
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueExportReqVO.java deleted
1 -package cn.iocoder.yudao.module.crm.controller.admin.clue.vo;  
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;  
7 -import java.time.LocalDateTime;  
8 -import org.springframework.format.annotation.DateTimeFormat;  
9 -  
10 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;  
11 -  
12 -@Schema(description = "管理后台 - 线索 Excel 导出 Request VO,参数和 CrmCluePageReqVO 是一致的")  
13 -@Data  
14 -public class CrmClueExportReqVO {  
15 -  
16 - @Schema(description = "转化状态", example = "true")  
17 - private Boolean transformStatus;  
18 -  
19 - @Schema(description = "跟进状态", example = "true")  
20 - private Boolean followUpStatus;  
21 -  
22 - @Schema(description = "线索名称", example = "线索xxx")  
23 - private String name;  
24 -  
25 - @Schema(description = "客户id", example = "520")  
26 - private Long customerId;  
27 -  
28 - @Schema(description = "下次联系时间", example = "2023-10-18 01:00:00")  
29 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
30 - private LocalDateTime[] contactNextTime;  
31 -  
32 - @Schema(description = "电话", example = "18000000000")  
33 - private String telephone;  
34 -  
35 - @Schema(description = "手机号", example = "18000000000")  
36 - private String mobile;  
37 -  
38 - @Schema(description = "地址", example = "北京市海淀区")  
39 - private String address;  
40 -  
41 - @Schema(description = "负责人的用户编号", example = "27199")  
42 - private Long ownerUserId;  
43 -  
44 - @Schema(description = "最后跟进时间")  
45 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
46 - private LocalDateTime[] contactLastTime;  
47 -  
48 - @Schema(description = "创建时间")  
49 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
50 - private LocalDateTime[] createTime;  
51 -  
52 -}  
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 cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
4 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 7 import lombok.Data;
6 import lombok.EqualsAndHashCode; 8 import lombok.EqualsAndHashCode;
@@ -21,4 +23,11 @@ public class CrmCluePageReqVO extends PageParam { @@ -21,4 +23,11 @@ public class CrmCluePageReqVO extends PageParam {
21 @Schema(description = "手机号", example = "18000000000") 23 @Schema(description = "手机号", example = "18000000000")
22 private String mobile; 24 private String mobile;
23 25
  26 + @Schema(description = "场景类型", example = "1")
  27 + @InEnum(CrmSceneTypeEnum.class)
  28 + private Integer sceneType; // 场景类型,为 null 时则表示全部
  29 +
  30 + @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
  31 + private Boolean pool; // null 则表示为不是公海数据
  32 +
24 } 33 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java
@@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil; @@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.lang.Assert; 4 import cn.hutool.core.lang.Assert;
5 import cn.hutool.core.util.NumberUtil; 5 import cn.hutool.core.util.NumberUtil;
6 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 6 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
7 -import cn.iocoder.yudao.framework.common.pojo.PageParam;  
8 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
9 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 8 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
10 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 9 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
@@ -22,14 +21,14 @@ import com.google.common.collect.Lists; @@ -22,14 +21,14 @@ import com.google.common.collect.Lists;
22 import io.swagger.v3.oas.annotations.Operation; 21 import io.swagger.v3.oas.annotations.Operation;
23 import io.swagger.v3.oas.annotations.Parameter; 22 import io.swagger.v3.oas.annotations.Parameter;
24 import io.swagger.v3.oas.annotations.tags.Tag; 23 import io.swagger.v3.oas.annotations.tags.Tag;
  24 +import jakarta.annotation.Resource;
  25 +import jakarta.servlet.http.HttpServletResponse;
  26 +import jakarta.validation.Valid;
25 import lombok.extern.slf4j.Slf4j; 27 import lombok.extern.slf4j.Slf4j;
26 import org.springframework.security.access.prepost.PreAuthorize; 28 import org.springframework.security.access.prepost.PreAuthorize;
27 import org.springframework.validation.annotation.Validated; 29 import org.springframework.validation.annotation.Validated;
28 import org.springframework.web.bind.annotation.*; 30 import org.springframework.web.bind.annotation.*;
29 31
30 -import jakarta.annotation.Resource;  
31 -import jakarta.servlet.http.HttpServletResponse;  
32 -import jakarta.validation.Valid;  
33 import java.io.IOException; 32 import java.io.IOException;
34 import java.util.Collections; 33 import java.util.Collections;
35 import java.util.List; 34 import java.util.List;
@@ -38,6 +37,7 @@ import java.util.stream.Stream; @@ -38,6 +37,7 @@ import java.util.stream.Stream;
38 37
39 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 38 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
40 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 39 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  40 +import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
41 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap; 41 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
42 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 42 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
43 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 43 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@@ -95,9 +95,11 @@ public class CrmContactController { @@ -95,9 +95,11 @@ public class CrmContactController {
95 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(CollUtil.removeNull(Lists.newArrayList( 95 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(CollUtil.removeNull(Lists.newArrayList(
96 NumberUtil.parseLong(contact.getCreator()), contact.getOwnerUserId()))); 96 NumberUtil.parseLong(contact.getCreator()), contact.getOwnerUserId())));
97 // 2. 获取客户信息 97 // 2. 获取客户信息
98 - List<CrmCustomerDO> customerList = customerService.getCustomerList(Collections.singletonList(contact.getCustomerId())); 98 + List<CrmCustomerDO> customerList = customerService.getCustomerList(
  99 + Collections.singletonList(contact.getCustomerId()), getLoginUserId());
99 // 3. 直属上级 100 // 3. 直属上级
100 - List<CrmContactDO> parentContactList = contactService.getContactList(Collections.singletonList(contact.getParentId())); 101 + List<CrmContactDO> parentContactList = contactService.getContactList(
  102 + Collections.singletonList(contact.getParentId()), getLoginUserId());
101 return success(ContactConvert.INSTANCE.convert(contact, userMap, customerList, parentContactList)); 103 return success(ContactConvert.INSTANCE.convert(contact, userMap, customerList, parentContactList));
102 } 104 }
103 105
@@ -105,7 +107,9 @@ public class CrmContactController { @@ -105,7 +107,9 @@ public class CrmContactController {
105 @Operation(summary = "获得联系人列表") 107 @Operation(summary = "获得联系人列表")
106 @PreAuthorize("@ss.hasPermission('crm:contact:query')") 108 @PreAuthorize("@ss.hasPermission('crm:contact:query')")
107 public CommonResult<List<CrmContactSimpleRespVO>> getSimpleContactList() { 109 public CommonResult<List<CrmContactSimpleRespVO>> getSimpleContactList() {
108 - List<CrmContactDO> list = contactService.getContactList(); 110 + CrmContactPageReqVO pageReqVO = new CrmContactPageReqVO();
  111 + pageReqVO.setPageSize(PAGE_SIZE_NONE);
  112 + List<CrmContactDO> list = contactService.getContactPage(pageReqVO, getLoginUserId()).getList();
109 return success(ContactConvert.INSTANCE.convertAllList(list)); 113 return success(ContactConvert.INSTANCE.convertAllList(list));
110 } 114 }
111 115
@@ -113,7 +117,7 @@ public class CrmContactController { @@ -113,7 +117,7 @@ public class CrmContactController {
113 @Operation(summary = "获得联系人分页") 117 @Operation(summary = "获得联系人分页")
114 @PreAuthorize("@ss.hasPermission('crm:contact:query')") 118 @PreAuthorize("@ss.hasPermission('crm:contact:query')")
115 public CommonResult<PageResult<CrmContactRespVO>> getContactPage(@Valid CrmContactPageReqVO pageVO) { 119 public CommonResult<PageResult<CrmContactRespVO>> getContactPage(@Valid CrmContactPageReqVO pageVO) {
116 - PageResult<CrmContactDO> pageResult = contactService.getContactPage(pageVO); 120 + PageResult<CrmContactDO> pageResult = contactService.getContactPage(pageVO, getLoginUserId());
117 return success(convertDetailContactPage(pageResult)); 121 return success(convertDetailContactPage(pageResult));
118 } 122 }
119 123
@@ -121,7 +125,7 @@ public class CrmContactController { @@ -121,7 +125,7 @@ public class CrmContactController {
121 @Operation(summary = "获得联系人分页,基于指定客户") 125 @Operation(summary = "获得联系人分页,基于指定客户")
122 public CommonResult<PageResult<CrmContactRespVO>> getContactPageByCustomer(@Valid CrmContactPageReqVO pageVO) { 126 public CommonResult<PageResult<CrmContactRespVO>> getContactPageByCustomer(@Valid CrmContactPageReqVO pageVO) {
123 Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空"); 127 Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
124 - PageResult<CrmContactDO> pageResult = contactService.getContactPageByCustomer(pageVO); 128 + PageResult<CrmContactDO> pageResult = contactService.getContactPageByCustomerId(pageVO, getLoginUserId());
125 return success(convertDetailContactPage(pageResult)); 129 return success(convertDetailContactPage(pageResult));
126 } 130 }
127 131
@@ -131,8 +135,8 @@ public class CrmContactController { @@ -131,8 +135,8 @@ public class CrmContactController {
131 @OperateLog(type = EXPORT) 135 @OperateLog(type = EXPORT)
132 public void exportContactExcel(@Valid CrmContactPageReqVO exportReqVO, 136 public void exportContactExcel(@Valid CrmContactPageReqVO exportReqVO,
133 HttpServletResponse response) throws IOException { 137 HttpServletResponse response) throws IOException {
134 - exportReqVO.setPageNo(PageParam.PAGE_SIZE_NONE);  
135 - PageResult<CrmContactDO> pageResult = contactService.getContactPage(exportReqVO); 138 + exportReqVO.setPageNo(PAGE_SIZE_NONE);
  139 + PageResult<CrmContactDO> pageResult = contactService.getContactPage(exportReqVO, getLoginUserId());
136 ExcelUtils.write(response, "联系人.xls", "数据", CrmContactRespVO.class, 140 ExcelUtils.write(response, "联系人.xls", "数据", CrmContactRespVO.class,
137 convertDetailContactPage(pageResult).getList()); 141 convertDetailContactPage(pageResult).getList());
138 } 142 }
@@ -150,13 +154,13 @@ public class CrmContactController { @@ -150,13 +154,13 @@ public class CrmContactController {
150 } 154 }
151 // 1. 获取客户列表 155 // 1. 获取客户列表
152 List<CrmCustomerDO> crmCustomerDOList = customerService.getCustomerList( 156 List<CrmCustomerDO> crmCustomerDOList = customerService.getCustomerList(
153 - convertSet(contactList, CrmContactDO::getCustomerId)); 157 + convertSet(contactList, CrmContactDO::getCustomerId), getLoginUserId());
154 // 2. 获取创建人、负责人列表 158 // 2. 获取创建人、负责人列表
155 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList, 159 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList,
156 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); 160 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
157 // 3. 直属上级 161 // 3. 直属上级
158 List<CrmContactDO> parentContactList = contactService.getContactList( 162 List<CrmContactDO> parentContactList = contactService.getContactList(
159 - convertSet(contactList, CrmContactDO::getParentId)); 163 + convertSet(contactList, CrmContactDO::getParentId), getLoginUserId());
160 return ContactConvert.INSTANCE.convertPage(pageResult, userMap, crmCustomerDOList, parentContactList); 164 return ContactConvert.INSTANCE.convertPage(pageResult, userMap, crmCustomerDOList, parentContactList);
161 } 165 }
162 166
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactPageReqVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.contact.vo; 1 package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
4 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 7 import lombok.Data;
6 import lombok.EqualsAndHashCode; 8 import lombok.EqualsAndHashCode;
@@ -33,4 +35,11 @@ public class CrmContactPageReqVO extends PageParam { @@ -33,4 +35,11 @@ public class CrmContactPageReqVO extends PageParam {
33 @Schema(description = "微信", example = "zzZ98373") 35 @Schema(description = "微信", example = "zzZ98373")
34 private String wechat; 36 private String wechat;
35 37
  38 + @Schema(description = "场景类型", example = "1")
  39 + @InEnum(CrmSceneTypeEnum.class)
  40 + private Integer sceneType; // 场景类型,为 null 时则表示全部
  41 +
  42 + @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
  43 + private Boolean pool; // null 则表示为不是公海数据
  44 +
36 } 45 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
@@ -18,13 +18,13 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; @@ -18,13 +18,13 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
18 import io.swagger.v3.oas.annotations.Operation; 18 import io.swagger.v3.oas.annotations.Operation;
19 import io.swagger.v3.oas.annotations.Parameter; 19 import io.swagger.v3.oas.annotations.Parameter;
20 import io.swagger.v3.oas.annotations.tags.Tag; 20 import io.swagger.v3.oas.annotations.tags.Tag;
  21 +import jakarta.annotation.Resource;
  22 +import jakarta.servlet.http.HttpServletResponse;
  23 +import jakarta.validation.Valid;
21 import org.springframework.security.access.prepost.PreAuthorize; 24 import org.springframework.security.access.prepost.PreAuthorize;
22 import org.springframework.validation.annotation.Validated; 25 import org.springframework.validation.annotation.Validated;
23 import org.springframework.web.bind.annotation.*; 26 import org.springframework.web.bind.annotation.*;
24 27
25 -import jakarta.annotation.Resource;  
26 -import jakarta.servlet.http.HttpServletResponse;  
27 -import jakarta.validation.Valid;  
28 import java.io.IOException; 28 import java.io.IOException;
29 import java.util.List; 29 import java.util.List;
30 import java.util.Map; 30 import java.util.Map;
@@ -87,7 +87,7 @@ public class CrmContractController { @@ -87,7 +87,7 @@ public class CrmContractController {
87 @Operation(summary = "获得合同分页") 87 @Operation(summary = "获得合同分页")
88 @PreAuthorize("@ss.hasPermission('crm:contract:query')") 88 @PreAuthorize("@ss.hasPermission('crm:contract:query')")
89 public CommonResult<PageResult<ContractRespVO>> getContractPage(@Valid CrmContractPageReqVO pageVO) { 89 public CommonResult<PageResult<ContractRespVO>> getContractPage(@Valid CrmContractPageReqVO pageVO) {
90 - PageResult<CrmContractDO> pageResult = contractService.getContractPage(pageVO); 90 + PageResult<CrmContractDO> pageResult = contractService.getContractPage(pageVO, getLoginUserId());
91 return success(convertDetailContractPage(pageResult)); 91 return success(convertDetailContractPage(pageResult));
92 } 92 }
93 93
@@ -95,7 +95,7 @@ public class CrmContractController { @@ -95,7 +95,7 @@ public class CrmContractController {
95 @Operation(summary = "获得联系人分页,基于指定客户") 95 @Operation(summary = "获得联系人分页,基于指定客户")
96 public CommonResult<PageResult<ContractRespVO>> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) { 96 public CommonResult<PageResult<ContractRespVO>> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) {
97 Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空"); 97 Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
98 - PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomer(pageVO); 98 + PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomer(pageVO, getLoginUserId());
99 return success(convertDetailContractPage(pageResult)); 99 return success(convertDetailContractPage(pageResult));
100 } 100 }
101 101
@@ -105,7 +105,7 @@ public class CrmContractController { @@ -105,7 +105,7 @@ public class CrmContractController {
105 @OperateLog(type = EXPORT) 105 @OperateLog(type = EXPORT)
106 public void exportContractExcel(@Valid CrmContractPageReqVO exportReqVO, 106 public void exportContractExcel(@Valid CrmContractPageReqVO exportReqVO,
107 HttpServletResponse response) throws IOException { 107 HttpServletResponse response) throws IOException {
108 - PageResult<CrmContractDO> pageResult = contractService.getContractPage(exportReqVO); 108 + PageResult<CrmContractDO> pageResult = contractService.getContractPage(exportReqVO, getLoginUserId());
109 // 导出 Excel 109 // 导出 Excel
110 ExcelUtils.write(response, "合同.xls", "数据", CrmContractExcelVO.class, 110 ExcelUtils.write(response, "合同.xls", "数据", CrmContractExcelVO.class,
111 ContractConvert.INSTANCE.convertList02(pageResult.getList())); 111 ContractConvert.INSTANCE.convertList02(pageResult.getList()));
@@ -124,7 +124,7 @@ public class CrmContractController { @@ -124,7 +124,7 @@ public class CrmContractController {
124 } 124 }
125 // 1. 获取客户列表 125 // 1. 获取客户列表
126 List<CrmCustomerDO> customerList = customerService.getCustomerList( 126 List<CrmCustomerDO> customerList = customerService.getCustomerList(
127 - convertSet(contactList, CrmContractDO::getCustomerId)); 127 + convertSet(contactList, CrmContractDO::getCustomerId), getLoginUserId());
128 // 2. 获取创建人、负责人列表 128 // 2. 获取创建人、负责人列表
129 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList, 129 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList,
130 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); 130 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractPageReqVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; 1 package cn.iocoder.yudao.module.crm.controller.admin.contract.vo;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
4 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 7 import lombok.Data;
6 import lombok.EqualsAndHashCode; 8 import lombok.EqualsAndHashCode;
@@ -24,4 +26,11 @@ public class CrmContractPageReqVO extends PageParam { @@ -24,4 +26,11 @@ public class CrmContractPageReqVO extends PageParam {
24 @Schema(description = "商机编号", example = "10864") 26 @Schema(description = "商机编号", example = "10864")
25 private Long businessId; 27 private Long businessId;
26 28
  29 + @Schema(description = "场景类型", example = "1")
  30 + @InEnum(CrmSceneTypeEnum.class)
  31 + private Integer sceneType; // 场景类型,为 null 时则表示全部
  32 +
  33 + @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
  34 + private Boolean pool; // null 则表示为不是公海数据 TODO @puhui999:合同没有公海。目前只有【客户】【线索】有公海,其它都没
  35 +
27 } 36 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerPageReqVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.customer.vo; 1 package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
2 2
3 -import cn.iocoder.yudao.module.crm.framework.vo.CrmBasePageReqVO; 3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
4 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 7 import lombok.Data;
6 import lombok.EqualsAndHashCode; 8 import lombok.EqualsAndHashCode;
@@ -10,7 +12,7 @@ import lombok.ToString; @@ -10,7 +12,7 @@ import lombok.ToString;
10 @Data 12 @Data
11 @EqualsAndHashCode(callSuper = true) 13 @EqualsAndHashCode(callSuper = true)
12 @ToString(callSuper = true) 14 @ToString(callSuper = true)
13 -public class CrmCustomerPageReqVO extends CrmBasePageReqVO { 15 +public class CrmCustomerPageReqVO extends PageParam {
14 16
15 @Schema(description = "客户名称", example = "赵六") 17 @Schema(description = "客户名称", example = "赵六")
16 private String name; 18 private String name;
@@ -27,4 +29,11 @@ public class CrmCustomerPageReqVO extends CrmBasePageReqVO { @@ -27,4 +29,11 @@ public class CrmCustomerPageReqVO extends CrmBasePageReqVO {
27 @Schema(description = "客户来源", example = "1") 29 @Schema(description = "客户来源", example = "1")
28 private Integer source; 30 private Integer source;
29 31
  32 + @Schema(description = "场景类型", example = "1")
  33 + @InEnum(CrmSceneTypeEnum.class)
  34 + private Integer sceneType; // 场景类型,为 null 时则表示全部
  35 +
  36 + @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
  37 + private Boolean pool; // null 则表示为不是公海数据
  38 +
30 } 39 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java
@@ -23,13 +23,13 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; @@ -23,13 +23,13 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
23 import io.swagger.v3.oas.annotations.Operation; 23 import io.swagger.v3.oas.annotations.Operation;
24 import io.swagger.v3.oas.annotations.Parameter; 24 import io.swagger.v3.oas.annotations.Parameter;
25 import io.swagger.v3.oas.annotations.tags.Tag; 25 import io.swagger.v3.oas.annotations.tags.Tag;
  26 +import jakarta.annotation.Resource;
  27 +import jakarta.servlet.http.HttpServletResponse;
  28 +import jakarta.validation.Valid;
26 import org.springframework.security.access.prepost.PreAuthorize; 29 import org.springframework.security.access.prepost.PreAuthorize;
27 import org.springframework.validation.annotation.Validated; 30 import org.springframework.validation.annotation.Validated;
28 import org.springframework.web.bind.annotation.*; 31 import org.springframework.web.bind.annotation.*;
29 32
30 -import jakarta.annotation.Resource;  
31 -import jakarta.servlet.http.HttpServletResponse;  
32 -import jakarta.validation.Valid;  
33 import java.io.IOException; 33 import java.io.IOException;
34 import java.util.List; 34 import java.util.List;
35 import java.util.Map; 35 import java.util.Map;
@@ -39,6 +39,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -39,6 +39,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
39 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap; 39 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
40 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 40 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
41 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 41 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  42 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
42 43
43 @Tag(name = "管理后台 - CRM 回款") 44 @Tag(name = "管理后台 - CRM 回款")
44 @RestController 45 @RestController
@@ -111,7 +112,7 @@ public class CrmReceivableController { @@ -111,7 +112,7 @@ public class CrmReceivableController {
111 @PreAuthorize("@ss.hasPermission('crm:receivable:export')") 112 @PreAuthorize("@ss.hasPermission('crm:receivable:export')")
112 @OperateLog(type = EXPORT) 113 @OperateLog(type = EXPORT)
113 public void exportReceivableExcel(@Valid CrmReceivablePageReqVO exportReqVO, 114 public void exportReceivableExcel(@Valid CrmReceivablePageReqVO exportReqVO,
114 - HttpServletResponse response) throws IOException { 115 + HttpServletResponse response) throws IOException {
115 PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(exportReqVO); 116 PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(exportReqVO);
116 // 导出 Excel 117 // 导出 Excel
117 ExcelUtils.write(response, "回款.xls", "数据", CrmReceivableRespVO.class, 118 ExcelUtils.write(response, "回款.xls", "数据", CrmReceivableRespVO.class,
@@ -131,7 +132,7 @@ public class CrmReceivableController { @@ -131,7 +132,7 @@ public class CrmReceivableController {
131 } 132 }
132 // 1. 获取客户列表 133 // 1. 获取客户列表
133 List<CrmCustomerDO> customerList = customerService.getCustomerList( 134 List<CrmCustomerDO> customerList = customerService.getCustomerList(
134 - convertSet(receivableList, CrmReceivableDO::getCustomerId)); 135 + convertSet(receivableList, CrmReceivableDO::getCustomerId), getLoginUserId());
135 // 2. 获取创建人、负责人列表 136 // 2. 获取创建人、负责人列表
136 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivableList, 137 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivableList,
137 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); 138 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java
@@ -25,13 +25,13 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; @@ -25,13 +25,13 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
25 import io.swagger.v3.oas.annotations.Operation; 25 import io.swagger.v3.oas.annotations.Operation;
26 import io.swagger.v3.oas.annotations.Parameter; 26 import io.swagger.v3.oas.annotations.Parameter;
27 import io.swagger.v3.oas.annotations.tags.Tag; 27 import io.swagger.v3.oas.annotations.tags.Tag;
  28 +import jakarta.annotation.Resource;
  29 +import jakarta.servlet.http.HttpServletResponse;
  30 +import jakarta.validation.Valid;
28 import org.springframework.security.access.prepost.PreAuthorize; 31 import org.springframework.security.access.prepost.PreAuthorize;
29 import org.springframework.validation.annotation.Validated; 32 import org.springframework.validation.annotation.Validated;
30 import org.springframework.web.bind.annotation.*; 33 import org.springframework.web.bind.annotation.*;
31 34
32 -import jakarta.annotation.Resource;  
33 -import jakarta.servlet.http.HttpServletResponse;  
34 -import jakarta.validation.Valid;  
35 import java.io.IOException; 35 import java.io.IOException;
36 import java.util.List; 36 import java.util.List;
37 import java.util.Map; 37 import java.util.Map;
@@ -41,6 +41,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -41,6 +41,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
41 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap; 41 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
42 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 42 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
43 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 43 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
  44 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
44 45
45 @Tag(name = "管理后台 - CRM 回款计划") 46 @Tag(name = "管理后台 - CRM 回款计划")
46 @RestController 47 @RestController
@@ -115,7 +116,7 @@ public class CrmReceivablePlanController { @@ -115,7 +116,7 @@ public class CrmReceivablePlanController {
115 @PreAuthorize("@ss.hasPermission('crm:receivable-plan:export')") 116 @PreAuthorize("@ss.hasPermission('crm:receivable-plan:export')")
116 @OperateLog(type = EXPORT) 117 @OperateLog(type = EXPORT)
117 public void exportReceivablePlanExcel(@Valid CrmReceivablePlanPageReqVO exportReqVO, 118 public void exportReceivablePlanExcel(@Valid CrmReceivablePlanPageReqVO exportReqVO,
118 - HttpServletResponse response) throws IOException { 119 + HttpServletResponse response) throws IOException {
119 PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPage(exportReqVO); 120 PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPage(exportReqVO);
120 // 导出 Excel 121 // 导出 Excel
121 ExcelUtils.write(response, "回款计划.xls", "数据", CrmReceivablePlanRespVO.class, 122 ExcelUtils.write(response, "回款计划.xls", "数据", CrmReceivablePlanRespVO.class,
@@ -135,7 +136,7 @@ public class CrmReceivablePlanController { @@ -135,7 +136,7 @@ public class CrmReceivablePlanController {
135 } 136 }
136 // 1. 获取客户列表 137 // 1. 获取客户列表
137 List<CrmCustomerDO> customerList = customerService.getCustomerList( 138 List<CrmCustomerDO> customerList = customerService.getCustomerList(
138 - convertSet(receivablePlanList, CrmReceivablePlanDO::getCustomerId)); 139 + convertSet(receivablePlanList, CrmReceivablePlanDO::getCustomerId), getLoginUserId());
139 // 2. 获取创建人、负责人列表 140 // 2. 获取创建人、负责人列表
140 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivablePlanList, 141 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivablePlanList,
141 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); 142 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanPageReqVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan; 1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
4 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 7 import lombok.Data;
6 import lombok.EqualsAndHashCode; 8 import lombok.EqualsAndHashCode;
@@ -19,4 +21,11 @@ public class CrmReceivablePlanPageReqVO extends PageParam { @@ -19,4 +21,11 @@ public class CrmReceivablePlanPageReqVO extends PageParam {
19 @Schema(description = "合同名称", example = "3473") 21 @Schema(description = "合同名称", example = "3473")
20 private Long contractId; 22 private Long contractId;
21 23
  24 + @Schema(description = "场景类型", example = "1")
  25 + @InEnum(CrmSceneTypeEnum.class)
  26 + private Integer sceneType; // 场景类型,为 null 时则表示全部
  27 +
  28 + @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
  29 + private Boolean pool; // null 则表示为不是公海数据
  30 +
22 } 31 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivablePageReqVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable; 1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
4 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 7 import lombok.Data;
6 import lombok.EqualsAndHashCode; 8 import lombok.EqualsAndHashCode;
@@ -21,4 +23,11 @@ public class CrmReceivablePageReqVO extends PageParam { @@ -21,4 +23,11 @@ public class CrmReceivablePageReqVO extends PageParam {
21 @Schema(description = "客户编号", example = "4963") 23 @Schema(description = "客户编号", example = "4963")
22 private Long customerId; 24 private Long customerId;
23 25
  26 + @Schema(description = "场景类型", example = "1")
  27 + @InEnum(CrmSceneTypeEnum.class)
  28 + private Integer sceneType; // 场景类型,为 null 时则表示全部
  29 +
  30 + @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
  31 + private Boolean pool; // null 则表示为不是公海数据
  32 +
24 } 33 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessConvert.java
@@ -38,10 +38,7 @@ public interface CrmBusinessConvert { @@ -38,10 +38,7 @@ public interface CrmBusinessConvert {
38 38
39 List<CrmBusinessExcelVO> convertList02(List<CrmBusinessDO> list); 39 List<CrmBusinessExcelVO> convertList02(List<CrmBusinessDO> list);
40 40
41 - @Mappings({  
42 - @Mapping(target = "bizId", source = "reqVO.id"),  
43 - @Mapping(target = "newOwnerUserId", source = "reqVO.id")  
44 - }) 41 + @Mapping(target = "bizId", source = "reqVO.id")
45 CrmPermissionTransferReqBO convert(CrmBusinessTransferReqVO reqVO, Long userId); 42 CrmPermissionTransferReqBO convert(CrmBusinessTransferReqVO reqVO, Long userId);
46 43
47 default PageResult<CrmBusinessRespVO> convertPage(PageResult<CrmBusinessDO> page, List<CrmCustomerDO> customerList, 44 default PageResult<CrmBusinessRespVO> convertPage(PageResult<CrmBusinessDO> page, List<CrmCustomerDO> customerList,
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/customer/CrmCustomerConvert.java
@@ -54,10 +54,7 @@ public interface CrmCustomerConvert { @@ -54,10 +54,7 @@ public interface CrmCustomerConvert {
54 54
55 List<CrmCustomerExcelVO> convertList02(List<CrmCustomerDO> list); 55 List<CrmCustomerExcelVO> convertList02(List<CrmCustomerDO> list);
56 56
57 - @Mappings({  
58 - @Mapping(target = "bizId", source = "reqVO.id"),  
59 - @Mapping(target = "newOwnerUserId", source = "reqVO.id")  
60 - }) 57 + @Mapping(target = "bizId", source = "reqVO.id")
61 CrmPermissionTransferReqBO convert(CrmCustomerTransferReqVO reqVO, Long userId); 58 CrmPermissionTransferReqBO convert(CrmCustomerTransferReqVO reqVO, Long userId);
62 59
63 PageResult<CrmCustomerRespVO> convertPage(PageResult<CrmCustomerDO> page); 60 PageResult<CrmCustomerRespVO> convertPage(PageResult<CrmCustomerDO> page);
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessDO.java
@@ -97,4 +97,11 @@ public class CrmBusinessDO extends BaseDO { @@ -97,4 +97,11 @@ public class CrmBusinessDO extends BaseDO {
97 */ 97 */
98 private Integer followUpStatus; 98 private Integer followUpStatus;
99 99
  100 + /**
  101 + * 负责人的用户编号
  102 + *
  103 + * 关联 AdminUserDO 的 id 字段
  104 + */
  105 + private Long ownerUserId;
  106 +
100 } 107 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/clue/CrmClueDO.java
@@ -73,6 +73,13 @@ public class CrmClueDO extends BaseDO { @@ -73,6 +73,13 @@ public class CrmClueDO extends BaseDO {
73 */ 73 */
74 private String remark; 74 private String remark;
75 75
  76 + /**
  77 + * 负责人的用户编号
  78 + *
  79 + * 关联 AdminUserDO 的 id 字段
  80 + */
  81 + private Long ownerUserId;
  82 +
76 // TODO 芋艿:客户级别; 83 // TODO 芋艿:客户级别;
77 // TODO 芋艿:线索来源; 84 // TODO 芋艿:线索来源;
78 // TODO 芋艿:客户行业; 85 // TODO 芋艿:客户行业;
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java
@@ -2,13 +2,16 @@ package cn.iocoder.yudao.module.crm.dal.mysql.business; @@ -2,13 +2,16 @@ package cn.iocoder.yudao.module.crm.dal.mysql.business;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
6 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO;
7 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;  
8 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
  8 +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
  9 +import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils;
  10 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
9 import org.apache.ibatis.annotations.Mapper; 11 import org.apache.ibatis.annotations.Mapper;
10 12
11 import java.util.Collection; 13 import java.util.Collection;
  14 +import java.util.List;
12 15
13 /** 16 /**
14 * 商机 Mapper 17 * 商机 Mapper
@@ -18,18 +21,30 @@ import java.util.Collection; @@ -18,18 +21,30 @@ import java.util.Collection;
18 @Mapper 21 @Mapper
19 public interface CrmBusinessMapper extends BaseMapperX<CrmBusinessDO> { 22 public interface CrmBusinessMapper extends BaseMapperX<CrmBusinessDO> {
20 23
21 - default PageResult<CrmBusinessDO> selectPage(CrmBusinessPageReqVO reqVO, Collection<Long> ids) {  
22 - return selectPage(reqVO, new LambdaQueryWrapperX<CrmBusinessDO>()  
23 - .in(CrmBusinessDO::getId, ids)  
24 - .likeIfPresent(CrmBusinessDO::getName, reqVO.getName())  
25 - .orderByDesc(CrmBusinessDO::getId)); 24 + default int updateOwnerUserIdById(Long id, Long ownerUserId) {
  25 + return update(new LambdaUpdateWrapper<CrmBusinessDO>()
  26 + .eq(CrmBusinessDO::getId, id)
  27 + .set(CrmBusinessDO::getOwnerUserId, ownerUserId));
26 } 28 }
27 29
28 - default PageResult<CrmBusinessDO> selectPageByCustomer(CrmContractPageReqVO reqVO) {  
29 - return selectPage(reqVO, new LambdaQueryWrapperX<CrmBusinessDO>()  
30 - .eq(CrmBusinessDO::getCustomerId, reqVO.getCustomerId()) // 必须传递  
31 - .likeIfPresent(CrmBusinessDO::getName, reqVO.getName())  
32 - .orderByDesc(CrmBusinessDO::getId)); 30 + default PageResult<CrmBusinessDO> selectPage(CrmBusinessPageReqVO pageReqVO, Long userId) {
  31 + MPJLambdaWrapperX<CrmBusinessDO> query = new MPJLambdaWrapperX<>();
  32 + // 拼接数据权限的查询条件
  33 + CrmQueryWrapperUtils.builderPageQuery(query, CrmBizTypeEnum.CRM_BUSINESS.getType(), CrmBusinessDO::getId,
  34 + userId, pageReqVO.getSceneType(), pageReqVO.getPool());
  35 + // 拼接自身的查询条件
  36 + query.selectAll(CrmBusinessDO.class)
  37 + .eqIfPresent(CrmBusinessDO::getCustomerId, pageReqVO.getCustomerId()) // 指定客户编号
  38 + .likeIfPresent(CrmBusinessDO::getName, pageReqVO.getName())
  39 + .orderByDesc(CrmBusinessDO::getId);
  40 + return selectJoinPage(pageReqVO, CrmBusinessDO.class, query);
  41 + }
  42 +
  43 + default List<CrmBusinessDO> selectBatchIds(Collection<Long> ids, Long userId) {
  44 + MPJLambdaWrapperX<CrmBusinessDO> query = new MPJLambdaWrapperX<>();
  45 + // 拼接数据权限的查询条件
  46 + CrmQueryWrapperUtils.builderListQueryBatch(query, CrmBizTypeEnum.CRM_BUSINESS.getType(), ids, userId);
  47 + return selectJoinList(CrmBusinessDO.class, query);
33 } 48 }
34 49
35 } 50 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/clue/CrmClueMapper.java
@@ -2,12 +2,15 @@ package cn.iocoder.yudao.module.crm.dal.mysql.clue; @@ -2,12 +2,15 @@ package cn.iocoder.yudao.module.crm.dal.mysql.clue;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;  
6 -import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueExportReqVO; 5 +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
7 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO;
8 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;
  8 +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
  9 +import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils;
  10 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
9 import org.apache.ibatis.annotations.Mapper; 11 import org.apache.ibatis.annotations.Mapper;
10 12
  13 +import java.util.Collection;
11 import java.util.List; 14 import java.util.List;
12 15
13 /** 16 /**
@@ -18,27 +21,31 @@ import java.util.List; @@ -18,27 +21,31 @@ import java.util.List;
18 @Mapper 21 @Mapper
19 public interface CrmClueMapper extends BaseMapperX<CrmClueDO> { 22 public interface CrmClueMapper extends BaseMapperX<CrmClueDO> {
20 23
21 - default PageResult<CrmClueDO> selectPage(CrmCluePageReqVO reqVO) {  
22 - return selectPage(reqVO, new LambdaQueryWrapperX<CrmClueDO>()  
23 - .likeIfPresent(CrmClueDO::getName, reqVO.getName())  
24 - .likeIfPresent(CrmClueDO::getTelephone, reqVO.getTelephone())  
25 - .likeIfPresent(CrmClueDO::getMobile, reqVO.getMobile())  
26 - .orderByDesc(CrmClueDO::getId)); 24 + default int updateOwnerUserIdById(Long id, Long ownerUserId) {
  25 + return update(new LambdaUpdateWrapper<CrmClueDO>()
  26 + .eq(CrmClueDO::getId, id)
  27 + .set(CrmClueDO::getOwnerUserId, ownerUserId));
27 } 28 }
28 29
29 - default List<CrmClueDO> selectList(CrmClueExportReqVO reqVO) {  
30 - return selectList(new LambdaQueryWrapperX<CrmClueDO>()  
31 - .eqIfPresent(CrmClueDO::getTransformStatus, reqVO.getTransformStatus())  
32 - .eqIfPresent(CrmClueDO::getFollowUpStatus, reqVO.getFollowUpStatus())  
33 - .likeIfPresent(CrmClueDO::getName, reqVO.getName())  
34 - .eqIfPresent(CrmClueDO::getCustomerId, reqVO.getCustomerId())  
35 - .betweenIfPresent(CrmClueDO::getContactNextTime, reqVO.getContactNextTime())  
36 - .likeIfPresent(CrmClueDO::getTelephone, reqVO.getTelephone())  
37 - .likeIfPresent(CrmClueDO::getMobile, reqVO.getMobile())  
38 - .likeIfPresent(CrmClueDO::getAddress, reqVO.getAddress())  
39 - .betweenIfPresent(CrmClueDO::getContactLastTime, reqVO.getContactLastTime())  
40 - .betweenIfPresent(CrmClueDO::getCreateTime, reqVO.getCreateTime())  
41 - .orderByDesc(CrmClueDO::getId)); 30 + default PageResult<CrmClueDO> selectPage(CrmCluePageReqVO pageReqVO, Long userId) {
  31 + MPJLambdaWrapperX<CrmClueDO> query = new MPJLambdaWrapperX<>();
  32 + // 拼接数据权限的查询条件
  33 + CrmQueryWrapperUtils.builderPageQuery(query, CrmBizTypeEnum.CRM_LEADS.getType(), CrmClueDO::getId,
  34 + userId, pageReqVO.getSceneType(), pageReqVO.getPool());
  35 + // 拼接自身的查询条件
  36 + query.selectAll(CrmClueDO.class)
  37 + .likeIfPresent(CrmClueDO::getName, pageReqVO.getName())
  38 + .likeIfPresent(CrmClueDO::getTelephone, pageReqVO.getTelephone())
  39 + .likeIfPresent(CrmClueDO::getMobile, pageReqVO.getMobile())
  40 + .orderByDesc(CrmClueDO::getId);
  41 + return selectJoinPage(pageReqVO, CrmClueDO.class, query);
  42 + }
  43 +
  44 + default List<CrmClueDO> selectBatchIds(Collection<Long> ids, Long userId) {
  45 + MPJLambdaWrapperX<CrmClueDO> query = new MPJLambdaWrapperX<>();
  46 + // 拼接数据权限的查询条件
  47 + CrmQueryWrapperUtils.builderListQueryBatch(query, CrmBizTypeEnum.CRM_LEADS.getType(), ids, userId);
  48 + return selectJoinList(CrmClueDO.class, query);
42 } 49 }
43 50
44 } 51 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java
@@ -2,11 +2,17 @@ package cn.iocoder.yudao.module.crm.dal.mysql.contact; @@ -2,11 +2,17 @@ package cn.iocoder.yudao.module.crm.dal.mysql.contact;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
6 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO;
7 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
  8 +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
  9 +import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils;
  10 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
8 import org.apache.ibatis.annotations.Mapper; 11 import org.apache.ibatis.annotations.Mapper;
9 12
  13 +import java.util.Collection;
  14 +import java.util.List;
  15 +
10 /** 16 /**
11 * CRM 联系人 Mapper 17 * CRM 联系人 Mapper
12 * 18 *
@@ -15,29 +21,35 @@ import org.apache.ibatis.annotations.Mapper; @@ -15,29 +21,35 @@ import org.apache.ibatis.annotations.Mapper;
15 @Mapper 21 @Mapper
16 public interface CrmContactMapper extends BaseMapperX<CrmContactDO> { 22 public interface CrmContactMapper extends BaseMapperX<CrmContactDO> {
17 23
18 - // TODO @puhui999:数据权限  
19 - default PageResult<CrmContactDO> selectPage(CrmContactPageReqVO reqVO) {  
20 - return selectPage(reqVO, new LambdaQueryWrapperX<CrmContactDO>()  
21 - .eqIfPresent(CrmContactDO::getMobile, reqVO.getMobile())  
22 - .eqIfPresent(CrmContactDO::getTelephone, reqVO.getTelephone())  
23 - .eqIfPresent(CrmContactDO::getEmail, reqVO.getEmail())  
24 - .eqIfPresent(CrmContactDO::getCustomerId, reqVO.getCustomerId())  
25 - .likeIfPresent(CrmContactDO::getName, reqVO.getName())  
26 - .eqIfPresent(CrmContactDO::getQq, reqVO.getQq())  
27 - .eqIfPresent(CrmContactDO::getWechat, reqVO.getWechat())  
28 - .orderByDesc(CrmContactDO::getId)); 24 + default int updateOwnerUserIdById(Long id, Long ownerUserId) {
  25 + return update(new LambdaUpdateWrapper<CrmContactDO>()
  26 + .eq(CrmContactDO::getId, id)
  27 + .set(CrmContactDO::getOwnerUserId, ownerUserId));
  28 + }
  29 +
  30 + default PageResult<CrmContactDO> selectPage(CrmContactPageReqVO pageReqVO, Long userId) {
  31 + MPJLambdaWrapperX<CrmContactDO> query = new MPJLambdaWrapperX<>();
  32 + // 拼接数据权限的查询条件
  33 + CrmQueryWrapperUtils.builderPageQuery(query, CrmBizTypeEnum.CRM_CONTACT.getType(), CrmContactDO::getId,
  34 + userId, pageReqVO.getSceneType(), pageReqVO.getPool());
  35 + // 拼接自身的查询条件
  36 + query.selectAll(CrmContactDO.class)
  37 + .eqIfPresent(CrmContactDO::getCustomerId, pageReqVO.getCustomerId()) // 指定客户编号
  38 + .likeIfPresent(CrmContactDO::getName, pageReqVO.getName())
  39 + .eqIfPresent(CrmContactDO::getMobile, pageReqVO.getMobile())
  40 + .eqIfPresent(CrmContactDO::getTelephone, pageReqVO.getTelephone())
  41 + .eqIfPresent(CrmContactDO::getEmail, pageReqVO.getEmail())
  42 + .eqIfPresent(CrmContactDO::getQq, pageReqVO.getQq())
  43 + .eqIfPresent(CrmContactDO::getWechat, pageReqVO.getWechat())
  44 + .orderByDesc(CrmContactDO::getId);
  45 + return selectJoinPage(pageReqVO, CrmContactDO.class, query);
29 } 46 }
30 47
31 - default PageResult<CrmContactDO> selectPageByCustomer(CrmContactPageReqVO pageVO) {  
32 - return selectPage(pageVO, new LambdaQueryWrapperX<CrmContactDO>()  
33 - .eq(CrmContactDO::getCustomerId, pageVO.getCustomerId()) // 必须传递  
34 - .likeIfPresent(CrmContactDO::getName, pageVO.getName())  
35 - .eqIfPresent(CrmContactDO::getMobile, pageVO.getMobile())  
36 - .eqIfPresent(CrmContactDO::getTelephone, pageVO.getTelephone())  
37 - .eqIfPresent(CrmContactDO::getEmail, pageVO.getEmail())  
38 - .eqIfPresent(CrmContactDO::getQq, pageVO.getQq())  
39 - .eqIfPresent(CrmContactDO::getWechat, pageVO.getWechat())  
40 - .orderByDesc(CrmContactDO::getId)); 48 + default List<CrmContactDO> selectBatchIds(Collection<Long> ids, Long userId) {
  49 + MPJLambdaWrapperX<CrmContactDO> query = new MPJLambdaWrapperX<>();
  50 + // 拼接数据权限的查询条件
  51 + CrmQueryWrapperUtils.builderListQueryBatch(query, CrmBizTypeEnum.CRM_CONTACT.getType(), ids, userId);
  52 + return selectJoinList(CrmContactDO.class, query);
41 } 53 }
42 54
43 } 55 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java
@@ -2,11 +2,17 @@ package cn.iocoder.yudao.module.crm.dal.mysql.contract; @@ -2,11 +2,17 @@ package cn.iocoder.yudao.module.crm.dal.mysql.contract;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
6 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
7 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
  8 +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
  9 +import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils;
  10 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
8 import org.apache.ibatis.annotations.Mapper; 11 import org.apache.ibatis.annotations.Mapper;
9 12
  13 +import java.util.Collection;
  14 +import java.util.List;
  15 +
10 /** 16 /**
11 * CRM 合同 Mapper 17 * CRM 合同 Mapper
12 * 18 *
@@ -15,22 +21,32 @@ import org.apache.ibatis.annotations.Mapper; @@ -15,22 +21,32 @@ import org.apache.ibatis.annotations.Mapper;
15 @Mapper 21 @Mapper
16 public interface CrmContractMapper extends BaseMapperX<CrmContractDO> { 22 public interface CrmContractMapper extends BaseMapperX<CrmContractDO> {
17 23
18 - default PageResult<CrmContractDO> selectPage(CrmContractPageReqVO reqVO) {  
19 - return selectPage(reqVO, new LambdaQueryWrapperX<CrmContractDO>()  
20 - .likeIfPresent(CrmContractDO::getNo, reqVO.getNo())  
21 - .likeIfPresent(CrmContractDO::getName, reqVO.getName())  
22 - .eqIfPresent(CrmContractDO::getCustomerId, reqVO.getCustomerId())  
23 - .eqIfPresent(CrmContractDO::getBusinessId, reqVO.getBusinessId())  
24 - .orderByDesc(CrmContractDO::getId)); 24 + default int updateOwnerUserIdById(Long id, Long ownerUserId) {
  25 + return update(new LambdaUpdateWrapper<CrmContractDO>()
  26 + .eq(CrmContractDO::getId, id)
  27 + .set(CrmContractDO::getOwnerUserId, ownerUserId));
  28 + }
  29 +
  30 + default PageResult<CrmContractDO> selectPage(CrmContractPageReqVO pageReqVO, Long userId) {
  31 + MPJLambdaWrapperX<CrmContractDO> mpjLambdaWrapperX = new MPJLambdaWrapperX<>();
  32 + // 构建数据权限连表条件
  33 + CrmQueryWrapperUtils.builderPageQuery(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTACT.getType(), CrmContractDO::getId,
  34 + userId, pageReqVO.getSceneType(), pageReqVO.getPool());
  35 + mpjLambdaWrapperX.selectAll(CrmContractDO.class)
  36 + .eqIfPresent(CrmContractDO::getCustomerId, pageReqVO.getCustomerId())
  37 + .likeIfPresent(CrmContractDO::getNo, pageReqVO.getNo())
  38 + .likeIfPresent(CrmContractDO::getName, pageReqVO.getName())
  39 + .eqIfPresent(CrmContractDO::getCustomerId, pageReqVO.getCustomerId())
  40 + .eqIfPresent(CrmContractDO::getBusinessId, pageReqVO.getBusinessId())
  41 + .orderByDesc(CrmContractDO::getId);
  42 + return selectJoinPage(pageReqVO, CrmContractDO.class, mpjLambdaWrapperX);
25 } 43 }
26 44
27 - default PageResult<CrmContractDO> selectPageByCustomer(CrmContractPageReqVO reqVO) {  
28 - return selectPage(reqVO, new LambdaQueryWrapperX<CrmContractDO>()  
29 - .eq(CrmContractDO::getCustomerId, reqVO.getCustomerId()) // 必须传递  
30 - .likeIfPresent(CrmContractDO::getNo, reqVO.getNo())  
31 - .likeIfPresent(CrmContractDO::getName, reqVO.getName())  
32 - .eqIfPresent(CrmContractDO::getBusinessId, reqVO.getBusinessId())  
33 - .orderByDesc(CrmContractDO::getId)); 45 + default List<CrmContractDO> selectBatchIds(Collection<Long> ids, Long userId) {
  46 + MPJLambdaWrapperX<CrmContractDO> mpjLambdaWrapperX = new MPJLambdaWrapperX<>();
  47 + // 构建数据权限连表条件
  48 + CrmQueryWrapperUtils.builderListQueryBatch(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTACT.getType(), ids, userId);
  49 + return selectJoinList(CrmContractDO.class, mpjLambdaWrapperX);
34 } 50 }
35 51
36 } 52 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java
1 package cn.iocoder.yudao.module.crm.dal.mysql.customer; 1 package cn.iocoder.yudao.module.crm.dal.mysql.customer;
2 2
3 -import cn.iocoder.yudao.framework.common.pojo.PageParam;  
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6 import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
7 -import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;  
8 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
10 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 8 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
11 -import cn.iocoder.yudao.module.crm.util.CrmQueryPageUtils; 9 +import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils;
12 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; 10 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
13 -import com.baomidou.mybatisplus.core.metadata.IPage;  
14 import org.apache.ibatis.annotations.Mapper; 11 import org.apache.ibatis.annotations.Mapper;
15 12
16 import java.util.Collection; 13 import java.util.Collection;
@@ -30,35 +27,26 @@ public interface CrmCustomerMapper extends BaseMapperX&lt;CrmCustomerDO&gt; { @@ -30,35 +27,26 @@ public interface CrmCustomerMapper extends BaseMapperX&lt;CrmCustomerDO&gt; {
30 .set(CrmCustomerDO::getOwnerUserId, ownerUserId)); 27 .set(CrmCustomerDO::getOwnerUserId, ownerUserId));
31 } 28 }
32 29
33 - /**  
34 - * 获取客户分页  
35 - *  
36 - * @param pageReqVO 请求  
37 - * @param userId 用户编号  
38 - * @param subordinateIds 下属用户编号  
39 - * @param isAdmin 是否为管理  
40 - * @return 客户分页数据  
41 - */  
42 - default PageResult<CrmCustomerDO> selectPage(CrmCustomerPageReqVO pageReqVO, Long userId, Collection<Long> subordinateIds, Boolean isAdmin) {  
43 - IPage<CrmCustomerDO> mpPage = MyBatisUtils.buildPage(pageReqVO);  
44 - MPJLambdaWrapperX<CrmCustomerDO> mpjLambdaWrapperX = new MPJLambdaWrapperX<>();  
45 - // 构建数据权限连表条件  
46 - CrmQueryPageUtils.builderQuery(mpjLambdaWrapperX, pageReqVO, userId,  
47 - CrmBizTypeEnum.CRM_CUSTOMER.getType(), CrmCustomerDO::getId, subordinateIds, isAdmin);  
48 - mpjLambdaWrapperX.selectAll(CrmCustomerDO.class) 30 + default PageResult<CrmCustomerDO> selectPage(CrmCustomerPageReqVO pageReqVO, Long userId) {
  31 + MPJLambdaWrapperX<CrmCustomerDO> query = new MPJLambdaWrapperX<>();
  32 + // 拼接数据权限的查询条件
  33 + CrmQueryWrapperUtils.builderPageQuery(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), CrmCustomerDO::getId,
  34 + userId, pageReqVO.getSceneType(), pageReqVO.getPool());
  35 + // 拼接自身的查询条件
  36 + query.selectAll(CrmCustomerDO.class)
49 .likeIfPresent(CrmCustomerDO::getName, pageReqVO.getName()) 37 .likeIfPresent(CrmCustomerDO::getName, pageReqVO.getName())
50 .eqIfPresent(CrmCustomerDO::getMobile, pageReqVO.getMobile()) 38 .eqIfPresent(CrmCustomerDO::getMobile, pageReqVO.getMobile())
51 .eqIfPresent(CrmCustomerDO::getIndustryId, pageReqVO.getIndustryId()) 39 .eqIfPresent(CrmCustomerDO::getIndustryId, pageReqVO.getIndustryId())
52 .eqIfPresent(CrmCustomerDO::getLevel, pageReqVO.getLevel()) 40 .eqIfPresent(CrmCustomerDO::getLevel, pageReqVO.getLevel())
53 .eqIfPresent(CrmCustomerDO::getSource, pageReqVO.getSource()); 41 .eqIfPresent(CrmCustomerDO::getSource, pageReqVO.getSource());
54 - // 特殊:不分页,直接查询全部  
55 - // TODO @puhui999:下面这个,封装一个方法;从 56 到 61 这里哈;  
56 - if (PageParam.PAGE_SIZE_NONE.equals(pageReqVO.getPageNo())) {  
57 - List<CrmCustomerDO> list = selectJoinList(CrmCustomerDO.class, mpjLambdaWrapperX);  
58 - return new PageResult<>(list, (long) list.size());  
59 - }  
60 - mpPage = selectJoinPage(mpPage, CrmCustomerDO.class, mpjLambdaWrapperX);  
61 - return new PageResult<>(mpPage.getRecords(), mpPage.getTotal()); 42 + return selectJoinPage(pageReqVO, CrmCustomerDO.class, query);
  43 + }
  44 +
  45 + default List<CrmCustomerDO> selectBatchIds(Collection<Long> ids, Long userId) {
  46 + MPJLambdaWrapperX<CrmCustomerDO> query = new MPJLambdaWrapperX<>();
  47 + // 拼接数据权限的查询条件
  48 + CrmQueryWrapperUtils.builderListQueryBatch(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), ids, userId);
  49 + return selectJoinList(CrmCustomerDO.class, query);
62 } 50 }
63 51
64 } 52 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/core/annotations/CrmPermission.java
@@ -35,9 +35,8 @@ public @interface CrmPermission { @@ -35,9 +35,8 @@ public @interface CrmPermission {
35 35
36 /** 36 /**
37 * 数据编号,通过 Spring EL 表达式获取 37 * 数据编号,通过 Spring EL 表达式获取
38 - * TODO 数据权限完成后去除 default ""  
39 */ 38 */
40 - String bizId() default ""; 39 + String bizId();
41 40
42 /** 41 /**
43 * 操作所需权限级别 42 * 操作所需权限级别
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/vo/CrmBasePageReqVO.java deleted
1 -package cn.iocoder.yudao.module.crm.framework.vo;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.PageParam;  
4 -import cn.iocoder.yudao.framework.common.validation.InEnum;  
5 -import cn.iocoder.yudao.module.crm.enums.common.CrmSceneEnum;  
6 -import io.swagger.v3.oas.annotations.media.Schema;  
7 -import lombok.Data;  
8 -import lombok.EqualsAndHashCode;  
9 -  
10 -@Schema(description = "管理后台 - CRM 分页 Base Request VO")  
11 -@Data  
12 -@EqualsAndHashCode(callSuper = true)  
13 -public class CrmBasePageReqVO extends PageParam {  
14 -  
15 - /**  
16 - * 场景类型,为 null 时则表示全部  
17 - */  
18 - @Schema(description = "场景类型", example = "1")  
19 - @InEnum(CrmSceneEnum.class)  
20 - private Integer sceneType;  
21 -  
22 - @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")  
23 - private Boolean pool; // null 则表示为不是公海数据  
24 -  
25 -}  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java
@@ -5,11 +5,10 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi @@ -5,11 +5,10 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi
5 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO;
6 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO;
7 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateReqVO;
8 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;  
9 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
10 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
11 -  
12 import jakarta.validation.Valid; 10 import jakarta.validation.Valid;
  11 +
13 import java.util.Collection; 12 import java.util.Collection;
14 import java.util.List; 13 import java.util.List;
15 14
@@ -57,7 +56,7 @@ public interface CrmBusinessService { @@ -57,7 +56,7 @@ public interface CrmBusinessService {
57 * @param ids 编号 56 * @param ids 编号
58 * @return 商机列表 57 * @return 商机列表
59 */ 58 */
60 - List<CrmBusinessDO> getBusinessList(Collection<Long> ids); 59 + List<CrmBusinessDO> getBusinessList(Collection<Long> ids, Long userId);
61 60
62 /** 61 /**
63 * 获得商机分页 62 * 获得商机分页
@@ -76,9 +75,10 @@ public interface CrmBusinessService { @@ -76,9 +75,10 @@ public interface CrmBusinessService {
76 * 数据权限:基于 {@link CrmCustomerDO} 读取 75 * 数据权限:基于 {@link CrmCustomerDO} 读取
77 * 76 *
78 * @param pageReqVO 分页查询 77 * @param pageReqVO 分页查询
  78 + * @param userId 用户编号
79 * @return 联系人分页 79 * @return 联系人分页
80 */ 80 */
81 - PageResult<CrmBusinessDO> getBusinessPageByCustomer(CrmContractPageReqVO pageReqVO); 81 + PageResult<CrmBusinessDO> getBusinessPageByCustomer(CrmBusinessPageReqVO pageReqVO, Long userId);
82 82
83 /** 83 /**
84 * 商机转移 84 * 商机转移
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
@@ -3,28 +3,28 @@ package cn.iocoder.yudao.module.crm.service.business; @@ -3,28 +3,28 @@ package cn.iocoder.yudao.module.crm.service.business;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.collection.ListUtil; 4 import cn.hutool.core.collection.ListUtil;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*;  
7 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; 6 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessCreateReqVO;
  7 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO;
  8 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO;
  9 +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateReqVO;
8 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert; 10 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert;
9 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 11 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
10 -import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;  
11 import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper; 12 import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper;
12 -import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;  
13 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 13 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
14 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; 14 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
  15 +import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
  16 +import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
15 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; 17 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
16 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 18 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
  19 +import jakarta.annotation.Resource;
17 import org.springframework.stereotype.Service; 20 import org.springframework.stereotype.Service;
18 import org.springframework.transaction.annotation.Transactional; 21 import org.springframework.transaction.annotation.Transactional;
19 import org.springframework.validation.annotation.Validated; 22 import org.springframework.validation.annotation.Validated;
20 23
21 -import jakarta.annotation.Resource;  
22 import java.util.Collection; 24 import java.util.Collection;
23 import java.util.List; 25 import java.util.List;
24 -import java.util.Set;  
25 26
26 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 27 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
27 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;  
28 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_NOT_EXISTS; 28 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_NOT_EXISTS;
29 29
30 /** 30 /**
@@ -38,6 +38,8 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -38,6 +38,8 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
38 38
39 @Resource 39 @Resource
40 private CrmBusinessMapper businessMapper; 40 private CrmBusinessMapper businessMapper;
  41 + @Resource
  42 + private CrmCustomerService customerService;
41 43
42 @Resource 44 @Resource
43 private CrmPermissionService crmPermissionService; 45 private CrmPermissionService crmPermissionService;
@@ -71,12 +73,14 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -71,12 +73,14 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
71 73
72 @Override 74 @Override
73 @Transactional(rollbackFor = Exception.class) 75 @Transactional(rollbackFor = Exception.class)
74 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, level = CrmPermissionLevelEnum.WRITE) 76 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
75 public void deleteBusiness(Long id) { 77 public void deleteBusiness(Long id) {
76 // 校验存在 78 // 校验存在
77 validateBusinessExists(id); 79 validateBusinessExists(id);
78 // 删除 80 // 删除
79 businessMapper.deleteById(id); 81 businessMapper.deleteById(id);
  82 + // 删除数据权限
  83 + crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_BUSINESS.getType(), id);
80 } 84 }
81 85
82 private CrmBusinessDO validateBusinessExists(Long id) { 86 private CrmBusinessDO validateBusinessExists(Long id) {
@@ -88,38 +92,30 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -88,38 +92,30 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
88 } 92 }
89 93
90 @Override 94 @Override
91 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS,bizId = "#id", level = CrmPermissionLevelEnum.READ) 95 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.READ)
92 public CrmBusinessDO getBusiness(Long id) { 96 public CrmBusinessDO getBusiness(Long id) {
93 return businessMapper.selectById(id); 97 return businessMapper.selectById(id);
94 } 98 }
95 99
96 @Override 100 @Override
97 - public List<CrmBusinessDO> getBusinessList(Collection<Long> ids) { 101 + public List<CrmBusinessDO> getBusinessList(Collection<Long> ids, Long userId) {
98 if (CollUtil.isEmpty(ids)) { 102 if (CollUtil.isEmpty(ids)) {
99 return ListUtil.empty(); 103 return ListUtil.empty();
100 } 104 }
101 - return businessMapper.selectBatchIds(ids); 105 + return businessMapper.selectBatchIds(ids, userId);
102 } 106 }
103 107
104 @Override 108 @Override
105 public PageResult<CrmBusinessDO> getBusinessPage(CrmBusinessPageReqVO pageReqVO, Long userId) { 109 public PageResult<CrmBusinessDO> getBusinessPage(CrmBusinessPageReqVO pageReqVO, Long userId) {
106 - // 1. 获取当前用户能看的分页数据  
107 - // TODO @puhui999:如果业务的数据量比较大,in 太多可能有性能问题噢;看看是不是搞成 join 连表了;可以微信讨论下;  
108 - List<CrmPermissionDO> permissions = crmPermissionService.getPermissionListByBizTypeAndUserId(  
109 - CrmBizTypeEnum.CRM_BUSINESS.getType(), userId);  
110 - Set<Long> ids = convertSet(permissions, CrmPermissionDO::getBizId);  
111 - if (CollUtil.isEmpty(ids)) { // 没得说明没有什么给他看的  
112 - return PageResult.empty();  
113 - }  
114 -  
115 - // 2. 获取商机分页数据  
116 - return businessMapper.selectPage(pageReqVO, ids); 110 + return businessMapper.selectPage(pageReqVO, userId);
117 } 111 }
118 112
119 @Override 113 @Override
120 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageReqVO.customerId", level = CrmPermissionLevelEnum.READ)  
121 - public PageResult<CrmBusinessDO> getBusinessPageByCustomer(CrmContractPageReqVO pageReqVO) {  
122 - return businessMapper.selectPageByCustomer(pageReqVO); 114 + public PageResult<CrmBusinessDO> getBusinessPageByCustomer(CrmBusinessPageReqVO pageReqVO, Long userId) {
  115 + // 校验客户存在 TODO @puhui999:这里不校验
  116 + customerService.validateCustomer(pageReqVO.getCustomerId());
  117 + // TODO @puhui999:感觉这里貌似不太复用用 selectPage,因为他可能没商机权限,只是因为能看 customer,所以可以看到列表
  118 + return businessMapper.selectPage(pageReqVO, userId);
123 } 119 }
124 120
125 @Override 121 @Override
@@ -128,10 +124,13 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -128,10 +124,13 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
128 // 1 校验商机是否存在 124 // 1 校验商机是否存在
129 validateBusinessExists(reqVO.getId()); 125 validateBusinessExists(reqVO.getId());
130 126
131 - // 2. 数据权限转移 127 + // 2.1 数据权限转移
132 crmPermissionService.transferPermission( 128 crmPermissionService.transferPermission(
133 CrmBusinessConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType())); 129 CrmBusinessConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()));
134 130
  131 + // 2.2 设置新的负责人
  132 + businessMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
  133 +
135 // 3. TODO 记录转移日志 134 // 3. TODO 记录转移日志
136 } 135 }
137 136
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java
1 package cn.iocoder.yudao.module.crm.service.clue; 1 package cn.iocoder.yudao.module.crm.service.clue;
2 2
3 -import java.util.*;  
4 -import jakarta.validation.*;  
5 -import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.*;  
6 -import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;  
7 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueCreateReqVO;
  5 +import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO;
  6 +import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueUpdateReqVO;
  7 +import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;
  8 +import jakarta.validation.Valid;
  9 +
  10 +import java.util.Collection;
  11 +import java.util.List;
8 12
9 /** 13 /**
10 * 线索 Service 接口 14 * 线索 Service 接口
@@ -49,22 +53,15 @@ public interface CrmClueService { @@ -49,22 +53,15 @@ public interface CrmClueService {
49 * @param ids 编号 53 * @param ids 编号
50 * @return 线索列表 54 * @return 线索列表
51 */ 55 */
52 - List<CrmClueDO> getClueList(Collection<Long> ids); 56 + List<CrmClueDO> getClueList(Collection<Long> ids, Long userId);
53 57
54 /** 58 /**
55 * 获得线索分页 59 * 获得线索分页
56 * 60 *
57 * @param pageReqVO 分页查询 61 * @param pageReqVO 分页查询
  62 + * @param userId 用户编号
58 * @return 线索分页 63 * @return 线索分页
59 */ 64 */
60 - PageResult<CrmClueDO> getCluePage(CrmCluePageReqVO pageReqVO);  
61 -  
62 - /**  
63 - * 获得线索列表, 用于 Excel 导出  
64 - *  
65 - * @param exportReqVO 查询条件  
66 - * @return 线索列表  
67 - */  
68 - List<CrmClueDO> getClueList(CrmClueExportReqVO exportReqVO); 65 + PageResult<CrmClueDO> getCluePage(CrmCluePageReqVO pageReqVO, Long userId);
69 66
70 } 67 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java
@@ -4,23 +4,25 @@ import cn.hutool.core.collection.CollUtil; @@ -4,23 +4,25 @@ import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.collection.ListUtil; 4 import cn.hutool.core.collection.ListUtil;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueCreateReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueCreateReqVO;
7 -import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueExportReqVO;  
8 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO;
9 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueUpdateReqVO; 8 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueUpdateReqVO;
10 import cn.iocoder.yudao.module.crm.convert.clue.CrmClueConvert; 9 import cn.iocoder.yudao.module.crm.convert.clue.CrmClueConvert;
11 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; 10 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;
12 import cn.iocoder.yudao.module.crm.dal.mysql.clue.CrmClueMapper; 11 import cn.iocoder.yudao.module.crm.dal.mysql.clue.CrmClueMapper;
  12 +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
  13 +import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
  14 +import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
13 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; 15 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
  16 +import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
  17 +import jakarta.annotation.Resource;
14 import org.springframework.stereotype.Service; 18 import org.springframework.stereotype.Service;
15 import org.springframework.validation.annotation.Validated; 19 import org.springframework.validation.annotation.Validated;
16 20
17 -import jakarta.annotation.Resource;  
18 import java.util.Collection; 21 import java.util.Collection;
19 import java.util.List; 22 import java.util.List;
20 23
21 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 24 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
22 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CLUE_NOT_EXISTS; 25 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CLUE_NOT_EXISTS;
23 -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CUSTOMER_NOT_EXISTS;  
24 26
25 /** 27 /**
26 * 线索 Service 实现类 28 * 线索 Service 实现类
@@ -33,8 +35,11 @@ public class CrmClueServiceImpl implements CrmClueService { @@ -33,8 +35,11 @@ public class CrmClueServiceImpl implements CrmClueService {
33 35
34 @Resource 36 @Resource
35 private CrmClueMapper clueMapper; 37 private CrmClueMapper clueMapper;
  38 +
36 @Resource 39 @Resource
37 private CrmCustomerService customerService; 40 private CrmCustomerService customerService;
  41 + @Resource
  42 + private CrmPermissionService crmPermissionService;
38 43
39 @Override 44 @Override
40 public Long createClue(CrmClueCreateReqVO createReqVO) { 45 public Long createClue(CrmClueCreateReqVO createReqVO) {
@@ -48,6 +53,7 @@ public class CrmClueServiceImpl implements CrmClueService { @@ -48,6 +53,7 @@ public class CrmClueServiceImpl implements CrmClueService {
48 } 53 }
49 54
50 @Override 55 @Override
  56 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_LEADS, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
51 public void updateClue(CrmClueUpdateReqVO updateReqVO) { 57 public void updateClue(CrmClueUpdateReqVO updateReqVO) {
52 // 校验存在 58 // 校验存在
53 validateClueExists(updateReqVO.getId()); 59 validateClueExists(updateReqVO.getId());
@@ -60,11 +66,14 @@ public class CrmClueServiceImpl implements CrmClueService { @@ -60,11 +66,14 @@ public class CrmClueServiceImpl implements CrmClueService {
60 } 66 }
61 67
62 @Override 68 @Override
  69 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_LEADS, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
63 public void deleteClue(Long id) { 70 public void deleteClue(Long id) {
64 // 校验存在 71 // 校验存在
65 validateClueExists(id); 72 validateClueExists(id);
66 // 删除 73 // 删除
67 clueMapper.deleteById(id); 74 clueMapper.deleteById(id);
  75 + // 删除数据权限
  76 + crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_LEADS.getType(), id);
68 } 77 }
69 78
70 private void validateClueExists(Long id) { 79 private void validateClueExists(Long id) {
@@ -74,26 +83,22 @@ public class CrmClueServiceImpl implements CrmClueService { @@ -74,26 +83,22 @@ public class CrmClueServiceImpl implements CrmClueService {
74 } 83 }
75 84
76 @Override 85 @Override
  86 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_LEADS, bizId = "#id", level = CrmPermissionLevelEnum.READ)
77 public CrmClueDO getClue(Long id) { 87 public CrmClueDO getClue(Long id) {
78 return clueMapper.selectById(id); 88 return clueMapper.selectById(id);
79 } 89 }
80 90
81 @Override 91 @Override
82 - public List<CrmClueDO> getClueList(Collection<Long> ids) { 92 + public List<CrmClueDO> getClueList(Collection<Long> ids, Long userId) {
83 if (CollUtil.isEmpty(ids)) { 93 if (CollUtil.isEmpty(ids)) {
84 return ListUtil.empty(); 94 return ListUtil.empty();
85 } 95 }
86 - return clueMapper.selectBatchIds(ids);  
87 - }  
88 -  
89 - @Override  
90 - public PageResult<CrmClueDO> getCluePage(CrmCluePageReqVO pageReqVO) {  
91 - return clueMapper.selectPage(pageReqVO); 96 + return clueMapper.selectBatchIds(ids, userId);
92 } 97 }
93 98
94 @Override 99 @Override
95 - public List<CrmClueDO> getClueList(CrmClueExportReqVO exportReqVO) {  
96 - return clueMapper.selectList(exportReqVO); 100 + public PageResult<CrmClueDO> getCluePage(CrmCluePageReqVO pageReqVO, Long userId) {
  101 + return clueMapper.selectPage(pageReqVO, userId);
97 } 102 }
98 103
99 } 104 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java
@@ -5,9 +5,8 @@ import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactCreateR @@ -5,9 +5,8 @@ import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactCreateR
5 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO;
6 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactUpdateReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactUpdateReqVO;
7 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
8 -import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;  
9 -  
10 import jakarta.validation.Valid; 8 import jakarta.validation.Valid;
  9 +
11 import java.util.Collection; 10 import java.util.Collection;
12 import java.util.List; 11 import java.util.List;
13 12
@@ -22,7 +21,7 @@ public interface CrmContactService { @@ -22,7 +21,7 @@ public interface CrmContactService {
22 * 创建联系人 21 * 创建联系人
23 * 22 *
24 * @param createReqVO 创建信息 23 * @param createReqVO 创建信息
25 - * @param userId 用户编号 24 + * @param userId 用户编号
26 * @return 编号 25 * @return 编号
27 */ 26 */
28 Long createContact(@Valid CrmContactCreateReqVO createReqVO, Long userId); 27 Long createContact(@Valid CrmContactCreateReqVO createReqVO, Long userId);
@@ -52,10 +51,11 @@ public interface CrmContactService { @@ -52,10 +51,11 @@ public interface CrmContactService {
52 /** 51 /**
53 * 获得联系人列表 52 * 获得联系人列表
54 * 53 *
55 - * @param ids 编号 54 + * @param ids 编号
  55 + * @param userId 用户编号
56 * @return 联系人列表 56 * @return 联系人列表
57 */ 57 */
58 - List<CrmContactDO> getContactList(Collection<Long> ids); 58 + List<CrmContactDO> getContactList(Collection<Long> ids, Long userId);
59 59
60 /** 60 /**
61 * 获得联系人分页 61 * 获得联系人分页
@@ -63,25 +63,20 @@ public interface CrmContactService { @@ -63,25 +63,20 @@ public interface CrmContactService {
63 * 数据权限:基于 {@link CrmContactDO} 63 * 数据权限:基于 {@link CrmContactDO}
64 * 64 *
65 * @param pageReqVO 分页查询 65 * @param pageReqVO 分页查询
  66 + * @param userId 用户编号
66 * @return 联系人分页 67 * @return 联系人分页
67 */ 68 */
68 - PageResult<CrmContactDO> getContactPage(CrmContactPageReqVO pageReqVO); 69 + PageResult<CrmContactDO> getContactPage(CrmContactPageReqVO pageReqVO, Long userId);
69 70
70 /** 71 /**
71 - * 获得联系人分页,基于指定客户 72 + * 获得联系人分页
72 * 73 *
73 - * 数据权限:基于 {@link CrmCustomerDO} 读取 74 + * 数据权限:基于 {@link CrmContactDO}
74 * 75 *
75 - * @param pageReqVO 分页查询 76 + * @param pageVO 分页查询
  77 + * @param userId 用户编号
76 * @return 联系人分页 78 * @return 联系人分页
77 */ 79 */
78 - PageResult<CrmContactDO> getContactPageByCustomer(CrmContactPageReqVO pageReqVO);  
79 -  
80 - /**  
81 - * 获取所有联系人列表  
82 - *  
83 - * @return 所有联系人列表  
84 - */  
85 - List<CrmContactDO> getContactList(); 80 + PageResult<CrmContactDO> getContactPageByCustomerId(CrmContactPageReqVO pageVO, Long userId);
86 81
87 } 82 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java
@@ -10,18 +10,18 @@ import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactUpdateR @@ -10,18 +10,18 @@ import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactUpdateR
10 import cn.iocoder.yudao.module.crm.convert.contact.ContactConvert; 10 import cn.iocoder.yudao.module.crm.convert.contact.ContactConvert;
11 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; 11 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
12 import cn.iocoder.yudao.module.crm.dal.mysql.contact.CrmContactMapper; 12 import cn.iocoder.yudao.module.crm.dal.mysql.contact.CrmContactMapper;
13 -import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;  
14 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 13 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
15 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; 14 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
  15 +import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
16 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; 16 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
17 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; 17 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
18 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 18 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
19 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 19 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  20 +import jakarta.annotation.Resource;
20 import org.springframework.stereotype.Service; 21 import org.springframework.stereotype.Service;
21 import org.springframework.transaction.annotation.Transactional; 22 import org.springframework.transaction.annotation.Transactional;
22 import org.springframework.validation.annotation.Validated; 23 import org.springframework.validation.annotation.Validated;
23 24
24 -import jakarta.annotation.Resource;  
25 import java.util.Collection; 25 import java.util.Collection;
26 import java.util.List; 26 import java.util.List;
27 27
@@ -82,7 +82,7 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -82,7 +82,7 @@ public class CrmContactServiceImpl implements CrmContactService {
82 * 82 *
83 * @param saveReqVO 新增/修改请求 VO 83 * @param saveReqVO 新增/修改请求 VO
84 */ 84 */
85 - private void validateRelationDataExists(CrmContactBaseVO saveReqVO){ 85 + private void validateRelationDataExists(CrmContactBaseVO saveReqVO) {
86 // 1. 校验客户 86 // 1. 校验客户
87 if (saveReqVO.getCustomerId() != null && customerService.getCustomer(saveReqVO.getCustomerId()) == null) { 87 if (saveReqVO.getCustomerId() != null && customerService.getCustomer(saveReqVO.getCustomerId()) == null) {
88 throw exception(CUSTOMER_NOT_EXISTS); 88 throw exception(CUSTOMER_NOT_EXISTS);
@@ -98,12 +98,14 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -98,12 +98,14 @@ public class CrmContactServiceImpl implements CrmContactService {
98 } 98 }
99 99
100 @Override 100 @Override
101 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.WRITE) 101 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
102 public void deleteContact(Long id) { 102 public void deleteContact(Long id) {
103 // 校验存在 103 // 校验存在
104 validateContactExists(id); 104 validateContactExists(id);
105 // 删除 105 // 删除
106 contactMapper.deleteById(id); 106 contactMapper.deleteById(id);
  107 + // 删除数据权限
  108 + crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CONTACT.getType(), id);
107 } 109 }
108 110
109 private void validateContactExists(Long id) { 111 private void validateContactExists(Long id) {
@@ -112,7 +114,6 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -112,7 +114,6 @@ public class CrmContactServiceImpl implements CrmContactService {
112 } 114 }
113 } 115 }
114 116
115 - // TODO 芋艿:是否要做数据权限的校验???  
116 @Override 117 @Override
117 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.READ) 118 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.READ)
118 public CrmContactDO getContact(Long id) { 119 public CrmContactDO getContact(Long id) {
@@ -120,28 +121,24 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -120,28 +121,24 @@ public class CrmContactServiceImpl implements CrmContactService {
120 } 121 }
121 122
122 @Override 123 @Override
123 - public List<CrmContactDO> getContactList(Collection<Long> ids) { 124 + public List<CrmContactDO> getContactList(Collection<Long> ids, Long userId) {
124 if (CollUtil.isEmpty(ids)) { 125 if (CollUtil.isEmpty(ids)) {
125 return ListUtil.empty(); 126 return ListUtil.empty();
126 } 127 }
127 - return contactMapper.selectBatchIds(ids);  
128 - }  
129 -  
130 - @Override  
131 - public PageResult<CrmContactDO> getContactPage(CrmContactPageReqVO pageReqVO) {  
132 - // TODO puhui999:后面要改成,基于数据权限的查询  
133 - return contactMapper.selectPage(pageReqVO); 128 + return contactMapper.selectBatchIds(ids, userId);
134 } 129 }
135 130
136 @Override 131 @Override
137 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageReqVO.customerId", level = CrmPermissionLevelEnum.READ)  
138 - public PageResult<CrmContactDO> getContactPageByCustomer(CrmContactPageReqVO pageReqVO) {  
139 - return contactMapper.selectPageByCustomer(pageReqVO); 132 + public PageResult<CrmContactDO> getContactPage(CrmContactPageReqVO pageReqVO, Long userId) {
  133 + return contactMapper.selectPage(pageReqVO, userId);
140 } 134 }
141 135
142 @Override 136 @Override
143 - public List<CrmContactDO> getContactList() {  
144 - return contactMapper.selectList(); 137 + public PageResult<CrmContactDO> getContactPageByCustomerId(CrmContactPageReqVO pageVO, Long userId) {
  138 + // 校验用户存在
  139 + customerService.validateCustomer(pageVO.getCustomerId());
  140 + // TODO @puhui999:getBusinessPageByCustomer 同理
  141 + return contactMapper.selectPage(pageVO, userId);
145 } 142 }
146 143
147 } 144 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contactbusinesslink/CrmContactBusinessLinkServiceImpl.java
@@ -12,14 +12,18 @@ import cn.iocoder.yudao.module.crm.convert.contactbusinessslink.CrmContactBusine @@ -12,14 +12,18 @@ import cn.iocoder.yudao.module.crm.convert.contactbusinessslink.CrmContactBusine
12 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 12 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
13 import cn.iocoder.yudao.module.crm.dal.dataobject.contactbusinesslink.CrmContactBusinessLinkDO; 13 import cn.iocoder.yudao.module.crm.dal.dataobject.contactbusinesslink.CrmContactBusinessLinkDO;
14 import cn.iocoder.yudao.module.crm.dal.mysql.contactbusinesslink.CrmContactBusinessLinkMapper; 14 import cn.iocoder.yudao.module.crm.dal.mysql.contactbusinesslink.CrmContactBusinessLinkMapper;
  15 +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
  16 +import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
  17 +import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
15 import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; 18 import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
  19 +import jakarta.annotation.Resource;
16 import org.springframework.stereotype.Service; 20 import org.springframework.stereotype.Service;
17 import org.springframework.validation.annotation.Validated; 21 import org.springframework.validation.annotation.Validated;
18 22
19 -import jakarta.annotation.Resource;  
20 import java.util.List; 23 import java.util.List;
21 24
22 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 25 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  26 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
23 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CONTACT_BUSINESS_LINK_NOT_EXISTS; 27 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CONTACT_BUSINESS_LINK_NOT_EXISTS;
24 28
25 // TODO @puhui999:数据权限的校验;每个操作; 29 // TODO @puhui999:数据权限的校验;每个操作;
@@ -54,6 +58,7 @@ public class CrmContactBusinessLinkServiceImpl implements CrmContactBusinessLink @@ -54,6 +58,7 @@ public class CrmContactBusinessLinkServiceImpl implements CrmContactBusinessLink
54 } 58 }
55 59
56 @Override 60 @Override
  61 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
57 public void updateContactBusinessLink(CrmContactBusinessLinkSaveReqVO updateReqVO) { 62 public void updateContactBusinessLink(CrmContactBusinessLinkSaveReqVO updateReqVO) {
58 // 校验存在 63 // 校验存在
59 validateContactBusinessLinkExists(updateReqVO.getId()); 64 validateContactBusinessLinkExists(updateReqVO.getId());
@@ -80,6 +85,7 @@ public class CrmContactBusinessLinkServiceImpl implements CrmContactBusinessLink @@ -80,6 +85,7 @@ public class CrmContactBusinessLinkServiceImpl implements CrmContactBusinessLink
80 } 85 }
81 86
82 @Override 87 @Override
  88 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.READ)
83 public CrmContactBusinessLinkDO getContactBusinessLink(Long id) { 89 public CrmContactBusinessLinkDO getContactBusinessLink(Long id) {
84 return contactBusinessLinkMapper.selectById(id); 90 return contactBusinessLinkMapper.selectById(id);
85 } 91 }
@@ -90,7 +96,7 @@ public class CrmContactBusinessLinkServiceImpl implements CrmContactBusinessLink @@ -90,7 +96,7 @@ public class CrmContactBusinessLinkServiceImpl implements CrmContactBusinessLink
90 crmContactBusinessLinkPageReqVO.setContactId(pageReqVO.getContactId()); 96 crmContactBusinessLinkPageReqVO.setContactId(pageReqVO.getContactId());
91 PageResult<CrmContactBusinessLinkDO> businessLinkDOS = contactBusinessLinkMapper.selectPageByContact(crmContactBusinessLinkPageReqVO); 97 PageResult<CrmContactBusinessLinkDO> businessLinkDOS = contactBusinessLinkMapper.selectPageByContact(crmContactBusinessLinkPageReqVO);
92 List<CrmBusinessDO> businessDOS = crmBusinessService.getBusinessList(CollectionUtils.convertList(businessLinkDOS.getList(), 98 List<CrmBusinessDO> businessDOS = crmBusinessService.getBusinessList(CollectionUtils.convertList(businessLinkDOS.getList(),
93 - CrmContactBusinessLinkDO::getBusinessId)); 99 + CrmContactBusinessLinkDO::getBusinessId), getLoginUserId());
94 PageResult<CrmBusinessRespVO> pageResult = new PageResult<CrmBusinessRespVO>(); 100 PageResult<CrmBusinessRespVO> pageResult = new PageResult<CrmBusinessRespVO>();
95 pageResult.setList(CrmBusinessConvert.INSTANCE.convert(businessDOS)); 101 pageResult.setList(CrmBusinessConvert.INSTANCE.convert(businessDOS));
96 pageResult.setTotal(businessLinkDOS.getTotal()); 102 pageResult.setTotal(businessLinkDOS.getTotal());
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java
@@ -3,12 +3,12 @@ package cn.iocoder.yudao.module.crm.service.contract; @@ -3,12 +3,12 @@ package cn.iocoder.yudao.module.crm.service.contract;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractCreateReqVO; 4 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractCreateReqVO;
5 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
6 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractUpdateReqVO;  
7 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO;
  7 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractUpdateReqVO;
8 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
10 -  
11 import jakarta.validation.Valid; 10 import jakarta.validation.Valid;
  11 +
12 import java.util.Collection; 12 import java.util.Collection;
13 import java.util.List; 13 import java.util.List;
14 14
@@ -64,9 +64,10 @@ public interface CrmContractService { @@ -64,9 +64,10 @@ public interface CrmContractService {
64 * 数据权限:基于 {@link CrmContractDO} 读取 64 * 数据权限:基于 {@link CrmContractDO} 读取
65 * 65 *
66 * @param pageReqVO 分页查询 66 * @param pageReqVO 分页查询
  67 + * @param userId 用户编号
67 * @return 合同分页 68 * @return 合同分页
68 */ 69 */
69 - PageResult<CrmContractDO> getContractPage(CrmContractPageReqVO pageReqVO); 70 + PageResult<CrmContractDO> getContractPage(CrmContractPageReqVO pageReqVO, Long userId);
70 71
71 /** 72 /**
72 * 获得合同分页,基于指定客户 73 * 获得合同分页,基于指定客户
@@ -74,9 +75,12 @@ public interface CrmContractService { @@ -74,9 +75,12 @@ public interface CrmContractService {
74 * 数据权限:基于 {@link CrmCustomerDO} 读取 75 * 数据权限:基于 {@link CrmCustomerDO} 读取
75 * 76 *
76 * @param pageReqVO 分页查询 77 * @param pageReqVO 分页查询
  78 + * @param userId 用户编号
77 * @return 联系人分页 79 * @return 联系人分页
78 */ 80 */
79 - PageResult<CrmContractDO> getContractPageByCustomer(CrmContractPageReqVO pageReqVO); 81 + default PageResult<CrmContractDO> getContractPageByCustomer(CrmContractPageReqVO pageReqVO, Long userId) {
  82 + return getContractPage(pageReqVO, userId);
  83 + }
80 84
81 /** 85 /**
82 * 合同转移 86 * 合同转移
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
@@ -5,8 +5,8 @@ import cn.hutool.core.collection.ListUtil; @@ -5,8 +5,8 @@ import cn.hutool.core.collection.ListUtil;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractCreateReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractCreateReqVO;
7 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
8 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractUpdateReqVO;  
9 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; 8 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO;
  9 +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractUpdateReqVO;
10 import cn.iocoder.yudao.module.crm.convert.contract.ContractConvert; 10 import cn.iocoder.yudao.module.crm.convert.contract.ContractConvert;
11 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 11 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
12 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper; 12 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper;
@@ -15,11 +15,11 @@ import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; @@ -15,11 +15,11 @@ import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
15 import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission; 15 import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
16 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; 16 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
17 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 17 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
  18 +import jakarta.annotation.Resource;
18 import org.springframework.stereotype.Service; 19 import org.springframework.stereotype.Service;
19 import org.springframework.transaction.annotation.Transactional; 20 import org.springframework.transaction.annotation.Transactional;
20 import org.springframework.validation.annotation.Validated; 21 import org.springframework.validation.annotation.Validated;
21 22
22 -import jakarta.annotation.Resource;  
23 import java.util.Collection; 23 import java.util.Collection;
24 import java.util.List; 24 import java.util.List;
25 25
@@ -56,7 +56,7 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -56,7 +56,7 @@ public class CrmContractServiceImpl implements CrmContractService {
56 56
57 @Override 57 @Override
58 @Transactional(rollbackFor = Exception.class) 58 @Transactional(rollbackFor = Exception.class)
59 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, level = CrmPermissionLevelEnum.WRITE) 59 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
60 public void updateContract(CrmContractUpdateReqVO updateReqVO) { 60 public void updateContract(CrmContractUpdateReqVO updateReqVO) {
61 // 校验存在 61 // 校验存在
62 validateContractExists(updateReqVO.getId()); 62 validateContractExists(updateReqVO.getId());
@@ -67,12 +67,14 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -67,12 +67,14 @@ public class CrmContractServiceImpl implements CrmContractService {
67 67
68 @Override 68 @Override
69 @Transactional(rollbackFor = Exception.class) 69 @Transactional(rollbackFor = Exception.class)
70 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.WRITE) 70 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
71 public void deleteContract(Long id) { 71 public void deleteContract(Long id) {
72 // 校验存在 72 // 校验存在
73 validateContractExists(id); 73 validateContractExists(id);
74 // 删除 74 // 删除
75 contractMapper.deleteById(id); 75 contractMapper.deleteById(id);
  76 + // 删除数据权限
  77 + crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CONTRACT.getType(), id);
76 } 78 }
77 79
78 private CrmContractDO validateContractExists(Long id) { 80 private CrmContractDO validateContractExists(Long id) {
@@ -83,7 +85,6 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -83,7 +85,6 @@ public class CrmContractServiceImpl implements CrmContractService {
83 return contract; 85 return contract;
84 } 86 }
85 87
86 - // TODO 芋艿:是否要做数据权限的校验???  
87 @Override 88 @Override
88 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.READ) 89 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.READ)
89 public CrmContractDO getContract(Long id) { 90 public CrmContractDO getContract(Long id) {
@@ -99,27 +100,24 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -99,27 +100,24 @@ public class CrmContractServiceImpl implements CrmContractService {
99 } 100 }
100 101
101 @Override 102 @Override
102 - public PageResult<CrmContractDO> getContractPage(CrmContractPageReqVO pageReqVO) {  
103 - return contractMapper.selectPage(pageReqVO);  
104 - }  
105 -  
106 - @Override  
107 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageReqVO.customerId", level = CrmPermissionLevelEnum.READ)  
108 - public PageResult<CrmContractDO> getContractPageByCustomer(CrmContractPageReqVO pageReqVO) {  
109 - return contractMapper.selectPageByCustomer(pageReqVO); 103 + public PageResult<CrmContractDO> getContractPage(CrmContractPageReqVO pageReqVO, Long userId) {
  104 + return contractMapper.selectPage(pageReqVO, userId);
110 } 105 }
111 106
112 @Override 107 @Override
113 @Transactional(rollbackFor = Exception.class) 108 @Transactional(rollbackFor = Exception.class)
114 public void transferContract(CrmContractTransferReqVO reqVO, Long userId) { 109 public void transferContract(CrmContractTransferReqVO reqVO, Long userId) {
115 - // 1 校验合同是否存在 110 + // 1. 校验合同是否存在
116 validateContractExists(reqVO.getId()); 111 validateContractExists(reqVO.getId());
117 112
118 - // 2. 数据权限转移 113 + // 2.1 数据权限转移
119 crmPermissionService.transferPermission( 114 crmPermissionService.transferPermission(
120 ContractConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType())); 115 ContractConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()));
  116 + // 2.2 设置负责人
  117 + contractMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
121 118
122 // 3. TODO 记录转移日志 119 // 3. TODO 记录转移日志
  120 +
123 } 121 }
124 122
125 } 123 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java
@@ -6,8 +6,8 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageR @@ -6,8 +6,8 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageR
6 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO;
7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerUpdateReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerUpdateReqVO;
8 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
9 -  
10 import jakarta.validation.Valid; 9 import jakarta.validation.Valid;
  10 +
11 import java.util.Collection; 11 import java.util.Collection;
12 import java.util.List; 12 import java.util.List;
13 13
@@ -56,7 +56,7 @@ public interface CrmCustomerService { @@ -56,7 +56,7 @@ public interface CrmCustomerService {
56 * @return 客户列表 56 * @return 客户列表
57 * @author ljlleo 57 * @author ljlleo
58 */ 58 */
59 - List<CrmCustomerDO> getCustomerList(Collection<Long> ids); 59 + List<CrmCustomerDO> getCustomerList(Collection<Long> ids, Long userId);
60 60
61 /** 61 /**
62 * 获得客户分页 62 * 获得客户分页
@@ -71,9 +71,8 @@ public interface CrmCustomerService { @@ -71,9 +71,8 @@ public interface CrmCustomerService {
71 * 校验客户是否存在 71 * 校验客户是否存在
72 * 72 *
73 * @param customerId 客户 id 73 * @param customerId 客户 id
74 - * @return 客户  
75 */ 74 */
76 - CrmCustomerDO validateCustomer(Long customerId); 75 + void validateCustomer(Long customerId);
77 76
78 /** 77 /**
79 * 客户转移 78 * 客户转移
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
@@ -15,11 +15,11 @@ import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission; @@ -15,11 +15,11 @@ import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
15 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; 15 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
16 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 16 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
17 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 17 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  18 +import jakarta.annotation.Resource;
18 import org.springframework.stereotype.Service; 19 import org.springframework.stereotype.Service;
19 import org.springframework.transaction.annotation.Transactional; 20 import org.springframework.transaction.annotation.Transactional;
20 import org.springframework.validation.annotation.Validated; 21 import org.springframework.validation.annotation.Validated;
21 22
22 -import jakarta.annotation.Resource;  
23 import java.util.*; 23 import java.util.*;
24 24
25 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 25 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -78,6 +78,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -78,6 +78,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
78 78
79 // 删除 79 // 删除
80 customerMapper.deleteById(id); 80 customerMapper.deleteById(id);
  81 + // 删除数据权限
  82 + crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id);
81 } 83 }
82 84
83 private void validateCustomerExists(Long id) { 85 private void validateCustomerExists(Long id) {
@@ -93,32 +95,34 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -93,32 +95,34 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
93 } 95 }
94 96
95 @Override 97 @Override
96 - public List<CrmCustomerDO> getCustomerList(Collection<Long> ids) { 98 + public List<CrmCustomerDO> getCustomerList(Collection<Long> ids, Long userId) {
97 if (CollUtil.isEmpty(ids)) { 99 if (CollUtil.isEmpty(ids)) {
98 return Collections.emptyList(); 100 return Collections.emptyList();
99 } 101 }
100 - return customerMapper.selectBatchIds(ids); 102 + return customerMapper.selectBatchIds(ids, userId);
101 } 103 }
102 104
103 @Override 105 @Override
104 public PageResult<CrmCustomerDO> getCustomerPage(CrmCustomerPageReqVO pageReqVO, Long userId) { 106 public PageResult<CrmCustomerDO> getCustomerPage(CrmCustomerPageReqVO pageReqVO, Long userId) {
105 - boolean admin = false; // TODO 如果是管理员  
106 - return customerMapper.selectPage(pageReqVO, userId, adminUserApi.getSubordinateIds(userId), admin); 107 + return customerMapper.selectPage(pageReqVO, userId);
107 } 108 }
108 109
109 /** 110 /**
110 * 校验客户是否存在 111 * 校验客户是否存在
111 * 112 *
112 * @param customerId 客户 id 113 * @param customerId 客户 id
113 - * @return 客户  
114 */ 114 */
115 @Override 115 @Override
116 - public CrmCustomerDO validateCustomer(Long customerId) {  
117 - CrmCustomerDO customer = getCustomer(customerId); 116 + public void validateCustomer(Long customerId) {
  117 + // TODO puhui999: 不返回客户不走校验应该可行
  118 + // 校验客户是否存在
  119 + if (customerId == null) {
  120 + throw exception(CUSTOMER_NOT_EXISTS);
  121 + }
  122 + CrmCustomerDO customer = customerMapper.selectById(customerId);
118 if (Objects.isNull(customer)) { 123 if (Objects.isNull(customer)) {
119 throw exception(CUSTOMER_NOT_EXISTS); 124 throw exception(CUSTOMER_NOT_EXISTS);
120 } 125 }
121 - return customer;  
122 } 126 }
123 127
124 @Override 128 @Override
@@ -128,9 +132,11 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -128,9 +132,11 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
128 // 1. 校验客户是否存在 132 // 1. 校验客户是否存在
129 validateCustomer(reqVO.getId()); 133 validateCustomer(reqVO.getId());
130 134
131 - // 2. 数据权限转移 135 + // 2.1 数据权限转移
132 crmPermissionService.transferPermission( 136 crmPermissionService.transferPermission(
133 CrmCustomerConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())); 137 CrmCustomerConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()));
  138 + // 2.2 转移后重新设置负责人
  139 + customerMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
134 140
135 // 3. TODO 记录转移日志 141 // 3. TODO 记录转移日志
136 } 142 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java
@@ -7,8 +7,8 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; @@ -7,8 +7,8 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
7 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; 7 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
8 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 8 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
9 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; 9 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
10 -  
11 import jakarta.validation.Valid; 10 import jakarta.validation.Valid;
  11 +
12 import java.util.Collection; 12 import java.util.Collection;
13 import java.util.List; 13 import java.util.List;
14 14
@@ -58,9 +58,17 @@ public interface CrmPermissionService { @@ -58,9 +58,17 @@ public interface CrmPermissionService {
58 void deletePermission(Integer bizType, Long bizId, Integer level); 58 void deletePermission(Integer bizType, Long bizId, Integer level);
59 59
60 /** 60 /**
  61 + * 删除数据权限
  62 + *
  63 + * @param bizType 数据类型,关联 {@link CrmBizTypeEnum}
  64 + * @param bizId 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId()
  65 + */
  66 + void deletePermission(Integer bizType, Long bizId);
  67 +
  68 + /**
61 * 批量删除数据权限 69 * 批量删除数据权限
62 * 70 *
63 - * @param ids 权限编号 71 + * @param ids 权限编号
64 * @param userId 用户编号 72 * @param userId 用户编号
65 */ 73 */
66 void deletePermissionBatch(Collection<Long> ids, Long userId); 74 void deletePermissionBatch(Collection<Long> ids, Long userId);
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java
@@ -11,11 +11,11 @@ import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; @@ -11,11 +11,11 @@ import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
11 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 11 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
12 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; 12 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
13 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 13 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  14 +import jakarta.annotation.Resource;
14 import org.springframework.stereotype.Service; 15 import org.springframework.stereotype.Service;
15 import org.springframework.transaction.annotation.Transactional; 16 import org.springframework.transaction.annotation.Transactional;
16 import org.springframework.validation.annotation.Validated; 17 import org.springframework.validation.annotation.Validated;
17 18
18 -import jakarta.annotation.Resource;  
19 import java.util.Collection; 19 import java.util.Collection;
20 import java.util.Collections; 20 import java.util.Collections;
21 import java.util.List; 21 import java.util.List;
@@ -126,9 +126,9 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { @@ -126,9 +126,9 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
126 @Override 126 @Override
127 @Transactional(rollbackFor = Exception.class) 127 @Transactional(rollbackFor = Exception.class)
128 public void deletePermission(Integer bizType, Long bizId, Integer level) { 128 public void deletePermission(Integer bizType, Long bizId, Integer level) {
  129 + // 校验存在
129 List<CrmPermissionDO> permissions = crmPermissionMapper.selectListByBizTypeAndBizIdAndLevel( 130 List<CrmPermissionDO> permissions = crmPermissionMapper.selectListByBizTypeAndBizIdAndLevel(
130 bizType, bizId, level); 131 bizType, bizId, level);
131 - // 校验存在  
132 if (CollUtil.isEmpty(permissions)) { 132 if (CollUtil.isEmpty(permissions)) {
133 throw exception(CRM_PERMISSION_NOT_EXISTS); 133 throw exception(CRM_PERMISSION_NOT_EXISTS);
134 } 134 }
@@ -138,6 +138,18 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { @@ -138,6 +138,18 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
138 } 138 }
139 139
140 @Override 140 @Override
  141 + public void deletePermission(Integer bizType, Long bizId) {
  142 + // TODO @puhui999:这种直接写条件删除;不需要先查询,再删除
  143 + List<CrmPermissionDO> permissionList = crmPermissionMapper.selectByBizTypeAndBizId(bizType, bizId);
  144 + if (CollUtil.isEmpty(permissionList)) {
  145 + return;
  146 + }
  147 +
  148 + // 删除数据权限
  149 + crmPermissionMapper.deleteBatchIds(convertSet(permissionList, CrmPermissionDO::getId));
  150 + }
  151 +
  152 + @Override
141 public void deletePermissionBatch(Collection<Long> ids, Long userId) { 153 public void deletePermissionBatch(Collection<Long> ids, Long userId) {
142 List<CrmPermissionDO> permissions = crmPermissionMapper.selectBatchIds(ids); 154 List<CrmPermissionDO> permissions = crmPermissionMapper.selectBatchIds(ids);
143 if (CollUtil.isEmpty(permissions)) { 155 if (CollUtil.isEmpty(permissions)) {
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/util/CrmQueryPageUtils.java deleted
1 -package cn.iocoder.yudao.module.crm.util;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.hutool.core.util.ObjUtil;  
5 -import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;  
6 -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;  
7 -import cn.iocoder.yudao.module.crm.enums.common.CrmSceneEnum;  
8 -import cn.iocoder.yudao.module.crm.framework.vo.CrmBasePageReqVO;  
9 -import com.baomidou.mybatisplus.core.toolkit.support.SFunction;  
10 -import com.github.yulichang.wrapper.MPJLambdaWrapper;  
11 -  
12 -import jakarta.annotation.Nullable;  
13 -import java.util.Collection;  
14 -  
15 -/**  
16 - * CRM 分页查询工具类  
17 - *  
18 - * @author HUIHUI  
19 - */  
20 -public class CrmQueryPageUtils {  
21 -  
22 - // TODO @puhui999:是不是弱化 CrmBasePageReqVO,把 sceneType 作为参数传入。默认其实 pool 不一定要传递的  
23 - /**  
24 - * 构造 CRM 数据类型数据分页查询条件  
25 - *  
26 - * @param queryMapper 连表查询对象  
27 - * @param reqVO 查询条件  
28 - * @param userId 用户编号  
29 - * @param bizType 数据类型 {@link CrmBizTypeEnum}  
30 - * @param bizId 数据编号  
31 - * @param subordinateIds 下属用户编号,可为空  
32 - */  
33 - public static <T extends MPJLambdaWrapper<?>, V extends CrmBasePageReqVO, S> void builderQuery(  
34 - T queryMapper, V reqVO, Long userId,  
35 - Integer bizType, SFunction<S, ?> bizId,  
36 - @Nullable Collection<Long> subordinateIds, // TODO @puhui999:subordinateIds 可以优化成 subordinateUserIds  
37 - Boolean isAdmin) {  
38 - // TODO @puhui999:是不是特殊处理,让这个 util 有状态,这样 isAdmin 直接从这里读取;subordinateIds 也是;这样,可以简化参数;  
39 - // 1. 构建数据权限连表条件  
40 - if (ObjUtil.notEqual(isAdmin, Boolean.TRUE)) { // 管理员不需要数据权限  
41 - queryMapper.innerJoin(CrmPermissionDO.class, on ->  
42 - on.eq(CrmPermissionDO::getBizType, bizType).eq(CrmPermissionDO::getBizId, bizId)  
43 - .eq(CrmPermissionDO::getUserId, userId));  
44 - }  
45 - // 2. 拼接公海的查询条件  
46 - if (ObjUtil.equal(reqVO.getPool(), Boolean.TRUE)) { // 情况一:公海  
47 - queryMapper.isNull("owner_user_id");  
48 - } else { // 情况二:不是公海  
49 - queryMapper.isNotNull("owner_user_id");  
50 - }  
51 - // 3. 拼接场景的查询条件  
52 - // TODO @puhui999::1 处的数据权限,应该和 3 处的场景是结合的?  
53 - // null 时:一种处理  
54 - // 1:一种条件;  
55 - // 2:一种条件;  
56 - // 3:一种条件;  
57 - if (CrmSceneEnum.isOwner(reqVO.getSceneType())) { // 场景一:我负责的数据  
58 - queryMapper.eq("owner_user_id", userId);  
59 - }  
60 - // TODO puhui999: 这里有一个疑问:如果下属负责的数据权限中没有自己的话还能看吗?回复:不能  
61 - if (CrmSceneEnum.isSubordinate(reqVO.getSceneType()) && CollUtil.isNotEmpty(subordinateIds)) { // 场景三:下属负责的数据  
62 - queryMapper.in("owner_user_id", subordinateIds);  
63 - }  
64 - }  
65 -  
66 -}  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/util/CrmQueryWrapperUtils.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.util;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjUtil;
  5 +import cn.hutool.extra.spring.SpringUtil;
  6 +import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
  7 +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
  8 +import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
  9 +import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  10 +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
  11 +import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
  12 +import com.github.yulichang.wrapper.MPJLambdaWrapper;
  13 +
  14 +import java.util.Collection;
  15 +import java.util.List;
  16 +
  17 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  18 +
  19 +/**
  20 + * CRM 分页查询工具类
  21 + *
  22 + * @author HUIHUI
  23 + */
  24 +public class CrmQueryWrapperUtils {
  25 +
  26 + /**
  27 + * 构造 CRM 数据类型数据分页查询条件
  28 + *
  29 + * @param query 连表查询对象
  30 + * @param bizType 数据类型 {@link CrmBizTypeEnum}
  31 + * @param bizId 数据编号
  32 + * @param userId 用户编号
  33 + * @param sceneType 场景类型
  34 + * @param pool 公海
  35 + */
  36 + // TODO @puhui999:bizId 直接传递会不会简单点
  37 + // TODO @puhui999:builderPageQuery 应该不仅仅适合于分页查询,应该适用于所有的查询;可以改成 appendPermissionCondition
  38 + public static <T extends MPJLambdaWrapper<?>, S> void builderPageQuery(T query, Integer bizType, SFunction<S, ?> bizId,
  39 + Long userId, Integer sceneType, Boolean pool) {
  40 + // 1. 构建数据权限连表条件
  41 + if (ObjUtil.notEqual(validateAdminUser(userId), Boolean.TRUE)) { // 管理员不需要数据权限
  42 + query.innerJoin(CrmPermissionDO.class, on ->
  43 + on.eq(CrmPermissionDO::getBizType, bizType).eq(CrmPermissionDO::getBizId, bizId)
  44 + .eq(CrmPermissionDO::getUserId, userId));
  45 + }
  46 + // 2.1 场景一:我负责的数据
  47 + if (CrmSceneTypeEnum.isOwner(sceneType)) {
  48 + query.eq("owner_user_id", userId);
  49 + }
  50 + // 2.2 场景二:我参与的数据
  51 + // TODO @puhui999:参与,指的是有读写权限噢;可以把 1. 的合并到 2.2 里;因为 2.1 不需要;
  52 + if (CrmSceneTypeEnum.isInvolved(sceneType)) {
  53 + query.ne("owner_user_id", userId);
  54 + }
  55 + // 2.3 场景三:下属负责的数据
  56 + if (CrmSceneTypeEnum.isSubordinate(sceneType)) {
  57 + List<AdminUserRespDTO> subordinateUsers = getAdminUserApi().getUserListBySubordinate(userId);
  58 + // TODO @puhui999:如果为空,不拼接,就是查询了所有数据呀?
  59 + if (CollUtil.isNotEmpty(subordinateUsers)) {
  60 + query.in("owner_user_id", convertSet(subordinateUsers, AdminUserRespDTO::getId));
  61 + }
  62 + }
  63 +
  64 + // 2. 拼接公海的查询条件
  65 + if (ObjUtil.equal(pool, Boolean.TRUE)) { // 情况一:公海
  66 + query.isNull("owner_user_id");
  67 + } else { // 情况二:不是公海
  68 + query.isNotNull("owner_user_id");
  69 + }
  70 + }
  71 +
  72 + /**
  73 + * 构造 CRM 数据类型批量数据查询条件
  74 + *
  75 + * @param query 连表查询对象
  76 + * @param bizType 数据类型 {@link CrmBizTypeEnum}
  77 + * @param bizIds 数据编号
  78 + * @param userId 用户编号
  79 + */
  80 + // TODO @puhui999:可以改成 appendPermissionCondition
  81 + // TODO @puhui999:S 是不是可以删除
  82 + public static <T extends MPJLambdaWrapper<?>, S> void builderListQueryBatch(T query, Integer bizType, Collection<Long> bizIds, Long userId) {
  83 + // TODO @puhui999:这里先 if return 简单点
  84 + if (ObjUtil.notEqual(validateAdminUser(userId), Boolean.TRUE)) { // 管理员不需要数据权限
  85 + query.innerJoin(CrmPermissionDO.class, on ->
  86 + on.eq(CrmPermissionDO::getBizType, bizType).in(CrmPermissionDO::getBizId, bizIds)
  87 + .in(CollUtil.isNotEmpty(bizIds), CrmPermissionDO::getUserId, userId));
  88 + }
  89 + }
  90 +
  91 + // TODO @puhui999:需要加个变量,不用每次都拿哈;
  92 + private static AdminUserApi getAdminUserApi() {
  93 + return SpringUtil.getBean(AdminUserApi.class);
  94 + }
  95 +
  96 + // TODO @puhui999:需要实现;
  97 + /**
  98 + * 校验用户是否是管理员
  99 + *
  100 + * @param userId 用户编号
  101 + * @return 是/否
  102 + */
  103 + private static boolean validateAdminUser(Long userId) {
  104 + return false;
  105 + }
  106 +
  107 +}
yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImplTest.java
@@ -3,19 +3,18 @@ package cn.iocoder.yudao.module.crm.service.clue; @@ -3,19 +3,18 @@ package cn.iocoder.yudao.module.crm.service.clue;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; 4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
5 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueCreateReqVO; 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; 6 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO;
8 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueUpdateReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueUpdateReqVO;
9 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;
10 import cn.iocoder.yudao.module.crm.dal.mysql.clue.CrmClueMapper; 9 import cn.iocoder.yudao.module.crm.dal.mysql.clue.CrmClueMapper;
  10 +import jakarta.annotation.Resource;
11 import org.junit.jupiter.api.Disabled; 11 import org.junit.jupiter.api.Disabled;
12 import org.junit.jupiter.api.Test; 12 import org.junit.jupiter.api.Test;
13 import org.springframework.context.annotation.Import; 13 import org.springframework.context.annotation.Import;
14 14
15 -import jakarta.annotation.Resource;  
16 import java.util.List; 15 import java.util.List;
17 16
18 -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; 17 +import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
19 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; 18 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
20 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; 19 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
21 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; 20 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
@@ -25,6 +24,7 @@ import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CLUE_NOT_EXIS @@ -25,6 +24,7 @@ import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CLUE_NOT_EXIS
25 import static org.junit.jupiter.api.Assertions.*; 24 import static org.junit.jupiter.api.Assertions.*;
26 25
27 // TODO 芋艿:单测后续补; 26 // TODO 芋艿:单测后续补;
  27 +
28 /** 28 /**
29 * {@link CrmClueServiceImpl} 的单元测试类 29 * {@link CrmClueServiceImpl} 的单元测试类
30 * 30 *
@@ -90,8 +90,8 @@ public class CrmClueServiceImplTest extends BaseDbUnitTest { @@ -90,8 +90,8 @@ public class CrmClueServiceImplTest extends BaseDbUnitTest {
90 90
91 // 调用 91 // 调用
92 clueService.deleteClue(id); 92 clueService.deleteClue(id);
93 - // 校验数据不存在了  
94 - assertNull(clueMapper.selectById(id)); 93 + // 校验数据不存在了
  94 + assertNull(clueMapper.selectById(id));
95 } 95 }
96 96
97 @Test 97 @Test
@@ -106,110 +106,102 @@ public class CrmClueServiceImplTest extends BaseDbUnitTest { @@ -106,110 +106,102 @@ public class CrmClueServiceImplTest extends BaseDbUnitTest {
106 @Test 106 @Test
107 @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 107 @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
108 public void testGetCluePage() { 108 public void testGetCluePage() {
109 - // mock 数据  
110 - CrmClueDO dbClue = randomPojo(CrmClueDO.class, o -> { // 等会查询到  
111 - o.setTransformStatus(null);  
112 - o.setFollowUpStatus(null);  
113 - o.setName(null);  
114 - o.setCustomerId(null);  
115 - o.setContactNextTime(null);  
116 - o.setTelephone(null);  
117 - o.setMobile(null);  
118 - o.setAddress(null);  
119 - o.setContactLastTime(null);  
120 - o.setCreateTime(null);  
121 - });  
122 - clueMapper.insert(dbClue);  
123 - // 测试 transformStatus 不匹配  
124 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setTransformStatus(null)));  
125 - // 测试 followUpStatus 不匹配  
126 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setFollowUpStatus(null)));  
127 - // 测试 name 不匹配  
128 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setName(null)));  
129 - // 测试 customerId 不匹配  
130 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setCustomerId(null)));  
131 - // 测试 contactNextTime 不匹配  
132 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setContactNextTime(null)));  
133 - // 测试 telephone 不匹配  
134 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setTelephone(null)));  
135 - // 测试 mobile 不匹配  
136 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setMobile(null)));  
137 - // 测试 address 不匹配  
138 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setAddress(null)));  
139 - // 测试 contactLastTime 不匹配  
140 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setContactLastTime(null)));  
141 - // 测试 createTime 不匹配  
142 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setCreateTime(null)));  
143 - // 准备参数  
144 - CrmCluePageReqVO reqVO = new CrmCluePageReqVO();  
145 - reqVO.setName(null);  
146 - reqVO.setTelephone(null);  
147 - reqVO.setMobile(null);  
148 -  
149 - // 调用  
150 - PageResult<CrmClueDO> pageResult = clueService.getCluePage(reqVO);  
151 - // 断言  
152 - assertEquals(1, pageResult.getTotal());  
153 - assertEquals(1, pageResult.getList().size());  
154 - assertPojoEquals(dbClue, pageResult.getList().get(0)); 109 + // mock 数据
  110 + CrmClueDO dbClue = randomPojo(CrmClueDO.class, o -> { // 等会查询到
  111 + o.setTransformStatus(null);
  112 + o.setFollowUpStatus(null);
  113 + o.setName(null);
  114 + o.setCustomerId(null);
  115 + o.setContactNextTime(null);
  116 + o.setTelephone(null);
  117 + o.setMobile(null);
  118 + o.setAddress(null);
  119 + o.setContactLastTime(null);
  120 + o.setCreateTime(null);
  121 + });
  122 + clueMapper.insert(dbClue);
  123 + // 测试 transformStatus 不匹配
  124 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setTransformStatus(null)));
  125 + // 测试 followUpStatus 不匹配
  126 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setFollowUpStatus(null)));
  127 + // 测试 name 不匹配
  128 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setName(null)));
  129 + // 测试 customerId 不匹配
  130 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setCustomerId(null)));
  131 + // 测试 contactNextTime 不匹配
  132 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setContactNextTime(null)));
  133 + // 测试 telephone 不匹配
  134 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setTelephone(null)));
  135 + // 测试 mobile 不匹配
  136 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setMobile(null)));
  137 + // 测试 address 不匹配
  138 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setAddress(null)));
  139 + // 测试 contactLastTime 不匹配
  140 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setContactLastTime(null)));
  141 + // 测试 createTime 不匹配
  142 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setCreateTime(null)));
  143 + // 准备参数
  144 + CrmCluePageReqVO reqVO = new CrmCluePageReqVO();
  145 + reqVO.setName(null);
  146 + reqVO.setTelephone(null);
  147 + reqVO.setMobile(null);
  148 +
  149 + // 调用
  150 + PageResult<CrmClueDO> pageResult = clueService.getCluePage(reqVO, 1L);
  151 + // 断言
  152 + assertEquals(1, pageResult.getTotal());
  153 + assertEquals(1, pageResult.getList().size());
  154 + assertPojoEquals(dbClue, pageResult.getList().get(0));
155 } 155 }
156 156
157 @Test 157 @Test
158 @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 158 @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
159 public void testGetClueList() { 159 public void testGetClueList() {
160 - // mock 数据  
161 - CrmClueDO dbClue = randomPojo(CrmClueDO.class, o -> { // 等会查询到  
162 - o.setTransformStatus(null);  
163 - o.setFollowUpStatus(null);  
164 - o.setName(null);  
165 - o.setCustomerId(null);  
166 - o.setContactNextTime(null);  
167 - o.setTelephone(null);  
168 - o.setMobile(null);  
169 - o.setAddress(null);  
170 - o.setContactLastTime(null);  
171 - o.setCreateTime(null);  
172 - });  
173 - clueMapper.insert(dbClue);  
174 - // 测试 transformStatus 不匹配  
175 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setTransformStatus(null)));  
176 - // 测试 followUpStatus 不匹配  
177 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setFollowUpStatus(null)));  
178 - // 测试 name 不匹配  
179 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setName(null)));  
180 - // 测试 customerId 不匹配  
181 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setCustomerId(null)));  
182 - // 测试 contactNextTime 不匹配  
183 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setContactNextTime(null)));  
184 - // 测试 telephone 不匹配  
185 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setTelephone(null)));  
186 - // 测试 mobile 不匹配  
187 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setMobile(null)));  
188 - // 测试 address 不匹配  
189 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setAddress(null)));  
190 - // 测试 contactLastTime 不匹配  
191 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setContactLastTime(null)));  
192 - // 测试 createTime 不匹配  
193 - clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setCreateTime(null)));  
194 - // 准备参数  
195 - CrmClueExportReqVO reqVO = new CrmClueExportReqVO();  
196 - reqVO.setTransformStatus(null);  
197 - reqVO.setFollowUpStatus(null);  
198 - reqVO.setName(null);  
199 - reqVO.setCustomerId(null);  
200 - reqVO.setContactNextTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));  
201 - reqVO.setTelephone(null);  
202 - reqVO.setMobile(null);  
203 - reqVO.setAddress(null);  
204 - reqVO.setOwnerUserId(null);  
205 - reqVO.setContactLastTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));  
206 - reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));  
207 -  
208 - // 调用  
209 - List<CrmClueDO> list = clueService.getClueList(reqVO);  
210 - // 断言  
211 - assertEquals(1, list.size());  
212 - assertPojoEquals(dbClue, list.get(0)); 160 + // mock 数据
  161 + CrmClueDO dbClue = randomPojo(CrmClueDO.class, o -> { // 等会查询到
  162 + o.setTransformStatus(null);
  163 + o.setFollowUpStatus(null);
  164 + o.setName(null);
  165 + o.setCustomerId(null);
  166 + o.setContactNextTime(null);
  167 + o.setTelephone(null);
  168 + o.setMobile(null);
  169 + o.setAddress(null);
  170 + o.setContactLastTime(null);
  171 + o.setCreateTime(null);
  172 + });
  173 + clueMapper.insert(dbClue);
  174 + // 测试 transformStatus 不匹配
  175 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setTransformStatus(null)));
  176 + // 测试 followUpStatus 不匹配
  177 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setFollowUpStatus(null)));
  178 + // 测试 name 不匹配
  179 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setName(null)));
  180 + // 测试 customerId 不匹配
  181 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setCustomerId(null)));
  182 + // 测试 contactNextTime 不匹配
  183 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setContactNextTime(null)));
  184 + // 测试 telephone 不匹配
  185 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setTelephone(null)));
  186 + // 测试 mobile 不匹配
  187 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setMobile(null)));
  188 + // 测试 address 不匹配
  189 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setAddress(null)));
  190 + // 测试 contactLastTime 不匹配
  191 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setContactLastTime(null)));
  192 + // 测试 createTime 不匹配
  193 + clueMapper.insert(cloneIgnoreId(dbClue, o -> o.setCreateTime(null)));
  194 + // 准备参数
  195 + CrmCluePageReqVO reqVO = new CrmCluePageReqVO();
  196 + reqVO.setName(null);
  197 + reqVO.setTelephone(null);
  198 + reqVO.setMobile(null);
  199 + reqVO.setPageSize(PAGE_SIZE_NONE);
  200 + // 调用
  201 + List<CrmClueDO> list = clueService.getCluePage(reqVO, 1L).getList();
  202 + // 断言
  203 + assertEquals(1, list.size());
  204 + assertPojoEquals(dbClue, list.get(0));
213 } 205 }
214 206
215 } 207 }
yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/contract/ContractServiceImplTest.java
@@ -7,12 +7,11 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageR @@ -7,12 +7,11 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageR
7 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractUpdateReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractUpdateReqVO;
8 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
9 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper; 9 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper;
  10 +import jakarta.annotation.Resource;
10 import org.junit.jupiter.api.Disabled; 11 import org.junit.jupiter.api.Disabled;
11 import org.junit.jupiter.api.Test; 12 import org.junit.jupiter.api.Test;
12 import org.springframework.context.annotation.Import; 13 import org.springframework.context.annotation.Import;
13 14
14 -import jakarta.annotation.Resource;  
15 -  
16 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; 15 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
17 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 16 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
18 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; 17 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
@@ -127,7 +126,7 @@ public class ContractServiceImplTest extends BaseDbUnitTest { @@ -127,7 +126,7 @@ public class ContractServiceImplTest extends BaseDbUnitTest {
127 reqVO.setNo(null); 126 reqVO.setNo(null);
128 127
129 // 调用 128 // 调用
130 - PageResult<CrmContractDO> pageResult = contractService.getContractPage(reqVO); 129 + PageResult<CrmContractDO> pageResult = contractService.getContractPage(reqVO, getLoginUserId());
131 // 断言 130 // 断言
132 assertEquals(1, pageResult.getTotal()); 131 assertEquals(1, pageResult.getTotal());
133 assertEquals(1, pageResult.getList().size()); 132 assertEquals(1, pageResult.getList().size());
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue/api/api.js.vm
@@ -77,7 +77,6 @@ export function export${simpleClassName}Excel(params) { @@ -77,7 +77,6 @@ export function export${simpleClassName}Excel(params) {
77 // ==================== 子表($subTable.classComment) ==================== 77 // ==================== 子表($subTable.classComment) ====================
78 ## 情况一:MASTER_ERP 时,需要分查询页子表 78 ## 情况一:MASTER_ERP 时,需要分查询页子表
79 #if ( $table.templateType == 11 ) 79 #if ( $table.templateType == 11 )
80 -  
81 // 获得${subTable.classComment}分页 80 // 获得${subTable.classComment}分页
82 export function get${subSimpleClassName}Page(params) { 81 export function get${subSimpleClassName}Page(params) {
83 return request({ 82 return request({
@@ -89,20 +88,18 @@ export function export${simpleClassName}Excel(params) { @@ -89,20 +88,18 @@ export function export${simpleClassName}Excel(params) {
89 ## 情况二:非 MASTER_ERP 时,需要列表查询子表 88 ## 情况二:非 MASTER_ERP 时,需要列表查询子表
90 #else 89 #else
91 #if ( $subTable.subJoinMany ) 90 #if ( $subTable.subJoinMany )
92 -  
93 // 获得${subTable.classComment}列表 91 // 获得${subTable.classComment}列表
94 export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}) { 92 export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}) {
95 return request({ 93 return request({
96 - url: `${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField}, 94 + url: '${baseURL}/${subSimpleClassName_strikeCase}/list-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=' + ${subJoinColumn.javaField},
97 method: 'get' 95 method: 'get'
98 }) 96 })
99 } 97 }
100 #else 98 #else
101 -  
102 // 获得${subTable.classComment} 99 // 获得${subTable.classComment}
103 export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}) { 100 export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}) {
104 return request({ 101 return request({
105 - url: `${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=` + ${subJoinColumn.javaField}, 102 + url: '${baseURL}/${subSimpleClassName_strikeCase}/get-by-${subJoinColumn_strikeCase}?${subJoinColumn.javaField}=' + ${subJoinColumn.javaField},
106 method: 'get' 103 method: 'get'
107 }) 104 })
108 } 105 }
@@ -113,7 +110,7 @@ export function export${simpleClassName}Excel(params) { @@ -113,7 +110,7 @@ export function export${simpleClassName}Excel(params) {
113 // 新增${subTable.classComment} 110 // 新增${subTable.classComment}
114 export function create${subSimpleClassName}(data) { 111 export function create${subSimpleClassName}(data) {
115 return request({ 112 return request({
116 - url: `${baseURL}/${subSimpleClassName_strikeCase}/create`, 113 + url: '${baseURL}/${subSimpleClassName_strikeCase}/create',
117 method: 'post', 114 method: 'post',
118 data 115 data
119 }) 116 })
@@ -122,7 +119,7 @@ export function export${simpleClassName}Excel(params) { @@ -122,7 +119,7 @@ export function export${simpleClassName}Excel(params) {
122 // 修改${subTable.classComment} 119 // 修改${subTable.classComment}
123 export function update${subSimpleClassName}(data) { 120 export function update${subSimpleClassName}(data) {
124 return request({ 121 return request({
125 - url: `${baseURL}/${subSimpleClassName_strikeCase}/update`, 122 + url: '${baseURL}/${subSimpleClassName_strikeCase}/update',
126 method: 'post', 123 method: 'post',
127 data 124 data
128 }) 125 })
@@ -131,7 +128,7 @@ export function export${simpleClassName}Excel(params) { @@ -131,7 +128,7 @@ export function export${simpleClassName}Excel(params) {
131 // 删除${subTable.classComment} 128 // 删除${subTable.classComment}
132 export function delete${subSimpleClassName}(id) { 129 export function delete${subSimpleClassName}(id) {
133 return request({ 130 return request({
134 - url: `${baseURL}/${subSimpleClassName_strikeCase}/delete?id=` + id, 131 + url: '${baseURL}/${subSimpleClassName_strikeCase}/delete?id=' + id,
135 method: 'delete' 132 method: 'delete'
136 }) 133 })
137 } 134 }
@@ -139,7 +136,7 @@ export function export${simpleClassName}Excel(params) { @@ -139,7 +136,7 @@ export function export${simpleClassName}Excel(params) {
139 // 获得${subTable.classComment} 136 // 获得${subTable.classComment}
140 export function get${subSimpleClassName}(id) { 137 export function get${subSimpleClassName}(id) {
141 return request({ 138 return request({
142 - url: `${baseURL}/${subSimpleClassName_strikeCase}/get?id=` + id, 139 + url: '${baseURL}/${subSimpleClassName_strikeCase}/get?id=' + id,
143 method: 'get' 140 method: 'get'
144 }) 141 })
145 } 142 }
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java
@@ -6,7 +6,6 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; @@ -6,7 +6,6 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
6 import java.util.Collection; 6 import java.util.Collection;
7 import java.util.List; 7 import java.util.List;
8 import java.util.Map; 8 import java.util.Map;
9 -import java.util.Set;  
10 9
11 /** 10 /**
12 * Admin 用户 API 接口 11 * Admin 用户 API 接口
@@ -23,14 +22,13 @@ public interface AdminUserApi { @@ -23,14 +22,13 @@ public interface AdminUserApi {
23 */ 22 */
24 AdminUserRespDTO getUser(Long id); 23 AdminUserRespDTO getUser(Long id);
25 24
26 - // TODO @puhui999:这里返回 List<AdminUserRespDTO> 方法名可以改成 getUserListBySubordinate  
27 /** 25 /**
28 * 通过用户 ID 查询用户下属 26 * 通过用户 ID 查询用户下属
29 * 27 *
30 - * @param id 用户编号  
31 - * @return 用户下属用户编号列表 28 + * @param userId 用户编号
  29 + * @return 用户下属用户列表
32 */ 30 */
33 - Set<Long> getSubordinateIds(Long id); 31 + List<AdminUserRespDTO> getUserListBySubordinate(Long userId);
34 32
35 /** 33 /**
36 * 通过用户 ID 查询用户们 34 * 通过用户 ID 查询用户们
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java
1 package cn.iocoder.yudao.module.system.api.user; 1 package cn.iocoder.yudao.module.system.api.user;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.hutool.core.util.ObjUtil; 4 import cn.hutool.core.util.ObjUtil;
4 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 6 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
@@ -7,13 +8,13 @@ import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; @@ -7,13 +8,13 @@ import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
7 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; 8 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
8 import cn.iocoder.yudao.module.system.service.dept.DeptService; 9 import cn.iocoder.yudao.module.system.service.dept.DeptService;
9 import cn.iocoder.yudao.module.system.service.user.AdminUserService; 10 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
  11 +import jakarta.annotation.Resource;
10 import org.springframework.stereotype.Service; 12 import org.springframework.stereotype.Service;
11 13
12 -import jakarta.annotation.Resource; 14 +import java.util.ArrayList;
13 import java.util.Collection; 15 import java.util.Collection;
14 import java.util.Collections; 16 import java.util.Collections;
15 import java.util.List; 17 import java.util.List;
16 -import java.util.Set;  
17 18
18 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 19 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
19 20
@@ -37,21 +38,31 @@ public class AdminUserApiImpl implements AdminUserApi { @@ -37,21 +38,31 @@ public class AdminUserApiImpl implements AdminUserApi {
37 } 38 }
38 39
39 @Override 40 @Override
40 - public Set<Long> getSubordinateIds(Long id) {  
41 - AdminUserDO user = userService.getUser(id); 41 + public List<AdminUserRespDTO> getUserListBySubordinate(Long userId) {
  42 + // 1.1 获取用户负责的部门
  43 + AdminUserDO user = userService.getUser(userId);
42 if (user == null) { 44 if (user == null) {
43 - return null; 45 + return Collections.emptyList();
44 } 46 }
45 -  
46 - Set<Long> subordinateIds = null; // 下属用户编号 47 + ArrayList<Long> deptIds = new ArrayList<>();
47 DeptDO dept = deptService.getDept(user.getDeptId()); 48 DeptDO dept = deptService.getDept(user.getDeptId());
48 - // TODO @puhui999:需要递归查询到子部门;并且要排除到自己噢。  
49 - // TODO @puhui999:保持 if return 原则,这里其实要判断不等于,则返回 null;最好返回 空集合,上面也是  
50 - if (ObjUtil.equal(dept.getLeaderUserId(), id)) { // 校验是否是该部门的负责人  
51 - List<AdminUserDO> users = userService.getUserListByDeptIds(Collections.singletonList(dept.getId()));  
52 - subordinateIds = convertSet(users, AdminUserDO::getId); 49 + if (dept == null) {
  50 + return Collections.emptyList();
  51 + }
  52 + if (ObjUtil.notEqual(dept.getLeaderUserId(), userId)) { // 校验为负责人
  53 + return Collections.emptyList();
53 } 54 }
54 - return subordinateIds; 55 + deptIds.add(dept.getId());
  56 + // 1.2 获取所有子部门
  57 + List<DeptDO> childDeptList = deptService.getChildDeptList(dept.getId());
  58 + if (CollUtil.isNotEmpty(childDeptList)) {
  59 + deptIds.addAll(convertSet(childDeptList, DeptDO::getId));
  60 + }
  61 +
  62 + // 2. 获取部门对应的用户信息
  63 + List<AdminUserDO> users = userService.getUserListByDeptIds(deptIds);
  64 + users.removeIf(item -> ObjUtil.equal(item.getId(), userId)); // 排除自己
  65 + return BeanUtils.toBean(users, AdminUserRespDTO.class);
55 } 66 }
56 67
57 @Override 68 @Override
yudao-server/pom.xml
@@ -37,11 +37,11 @@ @@ -37,11 +37,11 @@
37 </dependency> 37 </dependency>
38 38
39 <!-- 会员中心。默认注释,保证编译速度 --> 39 <!-- 会员中心。默认注释,保证编译速度 -->
40 -<!-- <dependency>-->  
41 -<!-- <groupId>cn.iocoder.boot</groupId>-->  
42 -<!-- <artifactId>yudao-module-member-biz</artifactId>-->  
43 -<!-- <version>${revision}</version>-->  
44 -<!-- </dependency>--> 40 + <dependency>
  41 + <groupId>cn.iocoder.boot</groupId>
  42 + <artifactId>yudao-module-member-biz</artifactId>
  43 + <version>${revision}</version>
  44 + </dependency>
45 45
46 <!-- 数据报表。默认注释,保证编译速度 --> 46 <!-- 数据报表。默认注释,保证编译速度 -->
47 <!-- <dependency>--> 47 <!-- <dependency>-->
@@ -56,11 +56,11 @@ @@ -56,11 +56,11 @@
56 <!-- <version>${revision}</version>--> 56 <!-- <version>${revision}</version>-->
57 <!-- </dependency>--> 57 <!-- </dependency>-->
58 <!-- 支付服务。默认注释,保证编译速度 --> 58 <!-- 支付服务。默认注释,保证编译速度 -->
59 -<!-- <dependency>-->  
60 -<!-- <groupId>cn.iocoder.boot</groupId>-->  
61 -<!-- <artifactId>yudao-module-pay-biz</artifactId>-->  
62 -<!-- <version>${revision}</version>-->  
63 -<!-- </dependency>--> 59 + <dependency>
  60 + <groupId>cn.iocoder.boot</groupId>
  61 + <artifactId>yudao-module-pay-biz</artifactId>
  62 + <version>${revision}</version>
  63 + </dependency>
64 64
65 <!-- 微信公众号模块。默认注释,保证编译速度 --> 65 <!-- 微信公众号模块。默认注释,保证编译速度 -->
66 <!-- <dependency>--> 66 <!-- <dependency>-->
@@ -70,33 +70,33 @@ @@ -70,33 +70,33 @@
70 <!-- </dependency>--> 70 <!-- </dependency>-->
71 71
72 <!-- 商城相关模块。默认注释,保证编译速度--> 72 <!-- 商城相关模块。默认注释,保证编译速度-->
73 -<!-- <dependency>-->  
74 -<!-- <groupId>cn.iocoder.boot</groupId>-->  
75 -<!-- <artifactId>yudao-module-promotion-biz</artifactId>-->  
76 -<!-- <version>${revision}</version>-->  
77 -<!-- </dependency>-->  
78 -<!-- <dependency>-->  
79 -<!-- <groupId>cn.iocoder.boot</groupId>-->  
80 -<!-- <artifactId>yudao-module-product-biz</artifactId>-->  
81 -<!-- <version>${revision}</version>-->  
82 -<!-- </dependency>-->  
83 -<!-- <dependency>-->  
84 -<!-- <groupId>cn.iocoder.boot</groupId>-->  
85 -<!-- <artifactId>yudao-module-trade-biz</artifactId>-->  
86 -<!-- <version>${revision}</version>-->  
87 -<!-- </dependency>-->  
88 -<!-- <dependency>-->  
89 -<!-- <groupId>cn.iocoder.boot</groupId>-->  
90 -<!-- <artifactId>yudao-module-statistics-biz</artifactId>-->  
91 -<!-- <version>${revision}</version>-->  
92 -<!-- </dependency>--> 73 + <dependency>
  74 + <groupId>cn.iocoder.boot</groupId>
  75 + <artifactId>yudao-module-promotion-biz</artifactId>
  76 + <version>${revision}</version>
  77 + </dependency>
  78 + <dependency>
  79 + <groupId>cn.iocoder.boot</groupId>
  80 + <artifactId>yudao-module-product-biz</artifactId>
  81 + <version>${revision}</version>
  82 + </dependency>
  83 + <dependency>
  84 + <groupId>cn.iocoder.boot</groupId>
  85 + <artifactId>yudao-module-trade-biz</artifactId>
  86 + <version>${revision}</version>
  87 + </dependency>
  88 + <dependency>
  89 + <groupId>cn.iocoder.boot</groupId>
  90 + <artifactId>yudao-module-statistics-biz</artifactId>
  91 + <version>${revision}</version>
  92 + </dependency>
93 93
94 <!-- CRM 相关模块。默认注释,保证编译速度 --> 94 <!-- CRM 相关模块。默认注释,保证编译速度 -->
95 -<!-- <dependency>-->  
96 -<!-- <groupId>cn.iocoder.boot</groupId>-->  
97 -<!-- <artifactId>yudao-module-crm-biz</artifactId>-->  
98 -<!-- <version>${revision}</version>-->  
99 -<!-- </dependency>--> 95 + <dependency>
  96 + <groupId>cn.iocoder.boot</groupId>
  97 + <artifactId>yudao-module-crm-biz</artifactId>
  98 + <version>${revision}</version>
  99 + </dependency>
100 100
101 <!-- spring boot 配置所需依赖 --> 101 <!-- spring boot 配置所需依赖 -->
102 <dependency> 102 <dependency>