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 15 <!-- 各种 module 拓展 -->
16 16 <module>yudao-module-system</module>
17 17 <module>yudao-module-infra</module>
18   -<!-- <module>yudao-module-member</module>-->
  18 + <module>yudao-module-member</module>
19 19 <!-- <module>yudao-module-bpm</module>-->
20 20 <!-- <module>yudao-module-report</module>-->
21 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 26 <!-- <module>yudao-example</module>-->
27 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 13 import com.baomidou.mybatisplus.extension.toolkit.Db;
14 14 import com.github.yulichang.base.MPJBaseMapper;
15 15 import com.github.yulichang.interfaces.MPJBaseJoin;
  16 +import com.github.yulichang.wrapper.MPJLambdaWrapper;
16 17 import org.apache.ibatis.annotations.Param;
17 18  
18 19 import java.util.Collection;
... ... @@ -40,6 +41,20 @@ public interface BaseMapperX&lt;T&gt; extends MPJBaseMapper&lt;T&gt; {
40 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 58 default <DTO> PageResult<DTO> selectJoinPage(PageParam pageParam, Class<DTO> resultTypeClass, MPJBaseJoin<T> joinQueryWrapper) {
44 59 IPage<DTO> mpPage = MyBatisUtils.buildPage(pageParam);
45 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  
8 8 import java.util.Arrays;
9 9  
10   -// TODO @puhui999:这个枚举,要不改成 CrmSceneTypeEnum
11 10 /**
12 11 * CRM 列表检索场景
13 12 *
... ... @@ -15,14 +14,13 @@ import java.util.Arrays;
15 14 */
16 15 @Getter
17 16 @AllArgsConstructor
18   -public enum CrmSceneEnum implements IntArrayValuable {
  17 +public enum CrmSceneTypeEnum implements IntArrayValuable {
19 18  
20 19 OWNER(1, "我负责的"),
21   - FOLLOW(2, "我关注的"),
22   - // TODO @puhui999:还有一个我参与的
  20 + INVOLVED(2, "我参与的"),
23 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 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 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 9 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*;
10 10 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusQueryVO;
11 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 12 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert;
14 13 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
15 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 21 import io.swagger.v3.oas.annotations.Operation;
23 22 import io.swagger.v3.oas.annotations.Parameter;
24 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 27 import org.springframework.security.access.prepost.PreAuthorize;
26 28 import org.springframework.validation.annotation.Validated;
27 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 31 import java.io.IOException;
33 32 import java.util.List;
34 33 import java.util.Objects;
... ... @@ -36,6 +35,7 @@ import java.util.Set;
36 35 import java.util.stream.Collectors;
37 36  
38 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 39 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
40 40 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
41 41  
... ... @@ -102,7 +102,7 @@ public class CrmBusinessController {
102 102 // TODO @ljlleo:可以使用 CollectionUtils.convertSet 替代常用的 stream 操作,更简洁一点;下面几个也是哈;
103 103 Set<Long> customerIds = pageResult.getList().stream()
104 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 107 Set<Long> statusTypeIds = pageResult.getList().stream()
108 108 .map(CrmBusinessDO::getStatusTypeId).filter(Objects::nonNull).collect(Collectors.toSet());
... ... @@ -120,14 +120,14 @@ public class CrmBusinessController {
120 120  
121 121 @GetMapping("/page-by-customer")
122 122 @Operation(summary = "获得商机分页,基于指定客户")
123   - public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByCustomer(@Valid CrmContractPageReqVO pageReqVO) {
  123 + public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByCustomer(@Valid CrmBusinessPageReqVO pageReqVO) {
124 124 Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
125   - PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPageByCustomer(pageReqVO);
  125 + PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPageByCustomer(pageReqVO, getLoginUserId());
126 126 // 处理客户名称回显
127 127 // TODO @ljlleo:可以使用 CollectionUtils.convertSet 替代常用的 stream 操作,更简洁一点;下面几个也是哈;
128 128 Set<Long> customerIds = pageResult.getList().stream()
129 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 132 Set<Long> statusTypeIds = pageResult.getList().stream()
133 133 .map(CrmBusinessDO::getStatusTypeId).filter(Objects::nonNull).collect(Collectors.toSet());
... ... @@ -143,20 +143,13 @@ public class CrmBusinessController {
143 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 146 @GetMapping("/export-excel")
155 147 @Operation(summary = "导出商机 Excel")
156 148 @PreAuthorize("@ss.hasPermission('crm:business:export')")
157 149 @OperateLog(type = EXPORT)
158 150 public void exportBusinessExcel(@Valid CrmBusinessPageReqVO exportReqVO,
159 151 HttpServletResponse response) throws IOException {
  152 + exportReqVO.setPageSize(PAGE_SIZE_NONE);
160 153 PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(exportReqVO, getLoginUserId());
161 154 // 导出 Excel
162 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 1 package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
2 2  
3 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 6 import io.swagger.v3.oas.annotations.media.Schema;
5 7 import lombok.Data;
6 8 import lombok.EqualsAndHashCode;
... ... @@ -18,4 +20,11 @@ public class CrmBusinessPageReqVO extends PageParam {
18 20 @Schema(description = "客户编号", example = "10795")
19 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 11 import io.swagger.v3.oas.annotations.Operation;
12 12 import io.swagger.v3.oas.annotations.Parameter;
13 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 17 import org.springframework.security.access.prepost.PreAuthorize;
15 18 import org.springframework.validation.annotation.Validated;
16 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 21 import java.io.IOException;
22 22 import java.util.List;
23 23  
24 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 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 29 @Tag(name = "管理后台 - 线索")
28 30 @RestController
... ... @@ -70,7 +72,7 @@ public class CrmClueController {
70 72 @Operation(summary = "获得线索分页")
71 73 @PreAuthorize("@ss.hasPermission('crm:clue:query')")
72 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 76 return success(CrmClueConvert.INSTANCE.convertPage(pageResult));
75 77 }
76 78  
... ... @@ -78,9 +80,9 @@ public class CrmClueController {
78 80 @Operation(summary = "导出线索 Excel")
79 81 @PreAuthorize("@ss.hasPermission('crm:clue:export')")
80 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 86 // 导出 Excel
85 87 List<CrmClueExcelVO> datas = CrmClueConvert.INSTANCE.convertList02(list);
86 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 1 package cn.iocoder.yudao.module.crm.controller.admin.clue.vo;
2 2  
3 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 6 import io.swagger.v3.oas.annotations.media.Schema;
5 7 import lombok.Data;
6 8 import lombok.EqualsAndHashCode;
... ... @@ -21,4 +23,11 @@ public class CrmCluePageReqVO extends PageParam {
21 23 @Schema(description = "手机号", example = "18000000000")
22 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 4 import cn.hutool.core.lang.Assert;
5 5 import cn.hutool.core.util.NumberUtil;
6 6 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
7   -import cn.iocoder.yudao.framework.common.pojo.PageParam;
8 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
9 8 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
10 9 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
... ... @@ -22,14 +21,14 @@ import com.google.common.collect.Lists;
22 21 import io.swagger.v3.oas.annotations.Operation;
23 22 import io.swagger.v3.oas.annotations.Parameter;
24 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 27 import lombok.extern.slf4j.Slf4j;
26 28 import org.springframework.security.access.prepost.PreAuthorize;
27 29 import org.springframework.validation.annotation.Validated;
28 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 32 import java.io.IOException;
34 33 import java.util.Collections;
35 34 import java.util.List;
... ... @@ -38,6 +37,7 @@ import java.util.stream.Stream;
38 37  
39 38 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
40 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 41 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
42 42 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
43 43 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
... ... @@ -95,9 +95,11 @@ public class CrmContactController {
95 95 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(CollUtil.removeNull(Lists.newArrayList(
96 96 NumberUtil.parseLong(contact.getCreator()), contact.getOwnerUserId())));
97 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 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 103 return success(ContactConvert.INSTANCE.convert(contact, userMap, customerList, parentContactList));
102 104 }
103 105  
... ... @@ -105,7 +107,9 @@ public class CrmContactController {
105 107 @Operation(summary = "获得联系人列表")
106 108 @PreAuthorize("@ss.hasPermission('crm:contact:query')")
107 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 113 return success(ContactConvert.INSTANCE.convertAllList(list));
110 114 }
111 115  
... ... @@ -113,7 +117,7 @@ public class CrmContactController {
113 117 @Operation(summary = "获得联系人分页")
114 118 @PreAuthorize("@ss.hasPermission('crm:contact:query')")
115 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 121 return success(convertDetailContactPage(pageResult));
118 122 }
119 123  
... ... @@ -121,7 +125,7 @@ public class CrmContactController {
121 125 @Operation(summary = "获得联系人分页,基于指定客户")
122 126 public CommonResult<PageResult<CrmContactRespVO>> getContactPageByCustomer(@Valid CrmContactPageReqVO pageVO) {
123 127 Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
124   - PageResult<CrmContactDO> pageResult = contactService.getContactPageByCustomer(pageVO);
  128 + PageResult<CrmContactDO> pageResult = contactService.getContactPageByCustomerId(pageVO, getLoginUserId());
125 129 return success(convertDetailContactPage(pageResult));
126 130 }
127 131  
... ... @@ -131,8 +135,8 @@ public class CrmContactController {
131 135 @OperateLog(type = EXPORT)
132 136 public void exportContactExcel(@Valid CrmContactPageReqVO exportReqVO,
133 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 140 ExcelUtils.write(response, "联系人.xls", "数据", CrmContactRespVO.class,
137 141 convertDetailContactPage(pageResult).getList());
138 142 }
... ... @@ -150,13 +154,13 @@ public class CrmContactController {
150 154 }
151 155 // 1. 获取客户列表
152 156 List<CrmCustomerDO> crmCustomerDOList = customerService.getCustomerList(
153   - convertSet(contactList, CrmContactDO::getCustomerId));
  157 + convertSet(contactList, CrmContactDO::getCustomerId), getLoginUserId());
154 158 // 2. 获取创建人、负责人列表
155 159 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList,
156 160 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
157 161 // 3. 直属上级
158 162 List<CrmContactDO> parentContactList = contactService.getContactList(
159   - convertSet(contactList, CrmContactDO::getParentId));
  163 + convertSet(contactList, CrmContactDO::getParentId), getLoginUserId());
160 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 1 package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
2 2  
3 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 6 import io.swagger.v3.oas.annotations.media.Schema;
5 7 import lombok.Data;
6 8 import lombok.EqualsAndHashCode;
... ... @@ -33,4 +35,11 @@ public class CrmContactPageReqVO extends PageParam {
33 35 @Schema(description = "微信", example = "zzZ98373")
34 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 18 import io.swagger.v3.oas.annotations.Operation;
19 19 import io.swagger.v3.oas.annotations.Parameter;
20 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 24 import org.springframework.security.access.prepost.PreAuthorize;
22 25 import org.springframework.validation.annotation.Validated;
23 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 28 import java.io.IOException;
29 29 import java.util.List;
30 30 import java.util.Map;
... ... @@ -87,7 +87,7 @@ public class CrmContractController {
87 87 @Operation(summary = "获得合同分页")
88 88 @PreAuthorize("@ss.hasPermission('crm:contract:query')")
89 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 91 return success(convertDetailContractPage(pageResult));
92 92 }
93 93  
... ... @@ -95,7 +95,7 @@ public class CrmContractController {
95 95 @Operation(summary = "获得联系人分页,基于指定客户")
96 96 public CommonResult<PageResult<ContractRespVO>> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) {
97 97 Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
98   - PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomer(pageVO);
  98 + PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomer(pageVO, getLoginUserId());
99 99 return success(convertDetailContractPage(pageResult));
100 100 }
101 101  
... ... @@ -105,7 +105,7 @@ public class CrmContractController {
105 105 @OperateLog(type = EXPORT)
106 106 public void exportContractExcel(@Valid CrmContractPageReqVO exportReqVO,
107 107 HttpServletResponse response) throws IOException {
108   - PageResult<CrmContractDO> pageResult = contractService.getContractPage(exportReqVO);
  108 + PageResult<CrmContractDO> pageResult = contractService.getContractPage(exportReqVO, getLoginUserId());
109 109 // 导出 Excel
110 110 ExcelUtils.write(response, "合同.xls", "数据", CrmContractExcelVO.class,
111 111 ContractConvert.INSTANCE.convertList02(pageResult.getList()));
... ... @@ -124,7 +124,7 @@ public class CrmContractController {
124 124 }
125 125 // 1. 获取客户列表
126 126 List<CrmCustomerDO> customerList = customerService.getCustomerList(
127   - convertSet(contactList, CrmContractDO::getCustomerId));
  127 + convertSet(contactList, CrmContractDO::getCustomerId), getLoginUserId());
128 128 // 2. 获取创建人、负责人列表
129 129 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList,
130 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 1 package cn.iocoder.yudao.module.crm.controller.admin.contract.vo;
2 2  
3 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 6 import io.swagger.v3.oas.annotations.media.Schema;
5 7 import lombok.Data;
6 8 import lombok.EqualsAndHashCode;
... ... @@ -24,4 +26,11 @@ public class CrmContractPageReqVO extends PageParam {
24 26 @Schema(description = "商机编号", example = "10864")
25 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 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 6 import io.swagger.v3.oas.annotations.media.Schema;
5 7 import lombok.Data;
6 8 import lombok.EqualsAndHashCode;
... ... @@ -10,7 +12,7 @@ import lombok.ToString;
10 12 @Data
11 13 @EqualsAndHashCode(callSuper = true)
12 14 @ToString(callSuper = true)
13   -public class CrmCustomerPageReqVO extends CrmBasePageReqVO {
  15 +public class CrmCustomerPageReqVO extends PageParam {
14 16  
15 17 @Schema(description = "客户名称", example = "赵六")
16 18 private String name;
... ... @@ -27,4 +29,11 @@ public class CrmCustomerPageReqVO extends CrmBasePageReqVO {
27 29 @Schema(description = "客户来源", example = "1")
28 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 23 import io.swagger.v3.oas.annotations.Operation;
24 24 import io.swagger.v3.oas.annotations.Parameter;
25 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 29 import org.springframework.security.access.prepost.PreAuthorize;
27 30 import org.springframework.validation.annotation.Validated;
28 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 33 import java.io.IOException;
34 34 import java.util.List;
35 35 import java.util.Map;
... ... @@ -39,6 +39,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
39 39 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
40 40 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
41 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 44 @Tag(name = "管理后台 - CRM 回款")
44 45 @RestController
... ... @@ -111,7 +112,7 @@ public class CrmReceivableController {
111 112 @PreAuthorize("@ss.hasPermission('crm:receivable:export')")
112 113 @OperateLog(type = EXPORT)
113 114 public void exportReceivableExcel(@Valid CrmReceivablePageReqVO exportReqVO,
114   - HttpServletResponse response) throws IOException {
  115 + HttpServletResponse response) throws IOException {
115 116 PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(exportReqVO);
116 117 // 导出 Excel
117 118 ExcelUtils.write(response, "回款.xls", "数据", CrmReceivableRespVO.class,
... ... @@ -131,7 +132,7 @@ public class CrmReceivableController {
131 132 }
132 133 // 1. 获取客户列表
133 134 List<CrmCustomerDO> customerList = customerService.getCustomerList(
134   - convertSet(receivableList, CrmReceivableDO::getCustomerId));
  135 + convertSet(receivableList, CrmReceivableDO::getCustomerId), getLoginUserId());
135 136 // 2. 获取创建人、负责人列表
136 137 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivableList,
137 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 25 import io.swagger.v3.oas.annotations.Operation;
26 26 import io.swagger.v3.oas.annotations.Parameter;
27 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 31 import org.springframework.security.access.prepost.PreAuthorize;
29 32 import org.springframework.validation.annotation.Validated;
30 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 35 import java.io.IOException;
36 36 import java.util.List;
37 37 import java.util.Map;
... ... @@ -41,6 +41,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
41 41 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
42 42 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
43 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 46 @Tag(name = "管理后台 - CRM 回款计划")
46 47 @RestController
... ... @@ -115,7 +116,7 @@ public class CrmReceivablePlanController {
115 116 @PreAuthorize("@ss.hasPermission('crm:receivable-plan:export')")
116 117 @OperateLog(type = EXPORT)
117 118 public void exportReceivablePlanExcel(@Valid CrmReceivablePlanPageReqVO exportReqVO,
118   - HttpServletResponse response) throws IOException {
  119 + HttpServletResponse response) throws IOException {
119 120 PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPage(exportReqVO);
120 121 // 导出 Excel
121 122 ExcelUtils.write(response, "回款计划.xls", "数据", CrmReceivablePlanRespVO.class,
... ... @@ -135,7 +136,7 @@ public class CrmReceivablePlanController {
135 136 }
136 137 // 1. 获取客户列表
137 138 List<CrmCustomerDO> customerList = customerService.getCustomerList(
138   - convertSet(receivablePlanList, CrmReceivablePlanDO::getCustomerId));
  139 + convertSet(receivablePlanList, CrmReceivablePlanDO::getCustomerId), getLoginUserId());
139 140 // 2. 获取创建人、负责人列表
140 141 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivablePlanList,
141 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 1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan;
2 2  
3 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 6 import io.swagger.v3.oas.annotations.media.Schema;
5 7 import lombok.Data;
6 8 import lombok.EqualsAndHashCode;
... ... @@ -19,4 +21,11 @@ public class CrmReceivablePlanPageReqVO extends PageParam {
19 21 @Schema(description = "合同名称", example = "3473")
20 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 1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable;
2 2  
3 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 6 import io.swagger.v3.oas.annotations.media.Schema;
5 7 import lombok.Data;
6 8 import lombok.EqualsAndHashCode;
... ... @@ -21,4 +23,11 @@ public class CrmReceivablePageReqVO extends PageParam {
21 23 @Schema(description = "客户编号", example = "4963")
22 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 38  
39 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 42 CrmPermissionTransferReqBO convert(CrmBusinessTransferReqVO reqVO, Long userId);
46 43  
47 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 54  
55 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 58 CrmPermissionTransferReqBO convert(CrmCustomerTransferReqVO reqVO, Long userId);
62 59  
63 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 97 */
98 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 73 */
74 74 private String remark;
75 75  
  76 + /**
  77 + * 负责人的用户编号
  78 + *
  79 + * 关联 AdminUserDO 的 id 字段
  80 + */
  81 + private Long ownerUserId;
  82 +
76 83 // TODO 芋艿:客户级别;
77 84 // TODO 芋艿:线索来源;
78 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 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 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 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 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 11 import org.apache.ibatis.annotations.Mapper;
10 12  
11 13 import java.util.Collection;
  14 +import java.util.List;
12 15  
13 16 /**
14 17 * 商机 Mapper
... ... @@ -18,18 +21,30 @@ import java.util.Collection;
18 21 @Mapper
19 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 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 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 6 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO;
8 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 11 import org.apache.ibatis.annotations.Mapper;
10 12  
  13 +import java.util.Collection;
11 14 import java.util.List;
12 15  
13 16 /**
... ... @@ -18,27 +21,31 @@ import java.util.List;
18 21 @Mapper
19 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 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 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 6 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO;
7 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 11 import org.apache.ibatis.annotations.Mapper;
9 12  
  13 +import java.util.Collection;
  14 +import java.util.List;
  15 +
10 16 /**
11 17 * CRM 联系人 Mapper
12 18 *
... ... @@ -15,29 +21,35 @@ import org.apache.ibatis.annotations.Mapper;
15 21 @Mapper
16 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 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 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 6 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
7 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 11 import org.apache.ibatis.annotations.Mapper;
9 12  
  13 +import java.util.Collection;
  14 +import java.util.List;
  15 +
10 16 /**
11 17 * CRM 合同 Mapper
12 18 *
... ... @@ -15,22 +21,32 @@ import org.apache.ibatis.annotations.Mapper;
15 21 @Mapper
16 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 1 package cn.iocoder.yudao.module.crm.dal.mysql.customer;
2 2  
3   -import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6 5 import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
7   -import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
8 6 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO;
9 7 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
10 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 10 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
13   -import com.baomidou.mybatisplus.core.metadata.IPage;
14 11 import org.apache.ibatis.annotations.Mapper;
15 12  
16 13 import java.util.Collection;
... ... @@ -30,35 +27,26 @@ public interface CrmCustomerMapper extends BaseMapperX&lt;CrmCustomerDO&gt; {
30 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 37 .likeIfPresent(CrmCustomerDO::getName, pageReqVO.getName())
50 38 .eqIfPresent(CrmCustomerDO::getMobile, pageReqVO.getMobile())
51 39 .eqIfPresent(CrmCustomerDO::getIndustryId, pageReqVO.getIndustryId())
52 40 .eqIfPresent(CrmCustomerDO::getLevel, pageReqVO.getLevel())
53 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 35  
36 36 /**
37 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 5 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO;
6 6 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO;
7 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 8 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
10 9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
11   -
12 10 import jakarta.validation.Valid;
  11 +
13 12 import java.util.Collection;
14 13 import java.util.List;
15 14  
... ... @@ -57,7 +56,7 @@ public interface CrmBusinessService {
57 56 * @param ids 编号
58 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 75 * 数据权限:基于 {@link CrmCustomerDO} 读取
77 76 *
78 77 * @param pageReqVO 分页查询
  78 + * @param userId 用户编号
79 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 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.collection.ListUtil;
5 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 10 import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert;
9 11 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
10   -import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
11 12 import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper;
12   -import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
13 13 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
14 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 17 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
16 18 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
  19 +import jakarta.annotation.Resource;
17 20 import org.springframework.stereotype.Service;
18 21 import org.springframework.transaction.annotation.Transactional;
19 22 import org.springframework.validation.annotation.Validated;
20 23  
21   -import jakarta.annotation.Resource;
22 24 import java.util.Collection;
23 25 import java.util.List;
24   -import java.util.Set;
25 26  
26 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 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 38  
39 39 @Resource
40 40 private CrmBusinessMapper businessMapper;
  41 + @Resource
  42 + private CrmCustomerService customerService;
41 43  
42 44 @Resource
43 45 private CrmPermissionService crmPermissionService;
... ... @@ -71,12 +73,14 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
71 73  
72 74 @Override
73 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 77 public void deleteBusiness(Long id) {
76 78 // 校验存在
77 79 validateBusinessExists(id);
78 80 // 删除
79 81 businessMapper.deleteById(id);
  82 + // 删除数据权限
  83 + crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_BUSINESS.getType(), id);
80 84 }
81 85  
82 86 private CrmBusinessDO validateBusinessExists(Long id) {
... ... @@ -88,38 +92,30 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
88 92 }
89 93  
90 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 96 public CrmBusinessDO getBusiness(Long id) {
93 97 return businessMapper.selectById(id);
94 98 }
95 99  
96 100 @Override
97   - public List<CrmBusinessDO> getBusinessList(Collection<Long> ids) {
  101 + public List<CrmBusinessDO> getBusinessList(Collection<Long> ids, Long userId) {
98 102 if (CollUtil.isEmpty(ids)) {
99 103 return ListUtil.empty();
100 104 }
101   - return businessMapper.selectBatchIds(ids);
  105 + return businessMapper.selectBatchIds(ids, userId);
102 106 }
103 107  
104 108 @Override
105 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 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 121 @Override
... ... @@ -128,10 +124,13 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
128 124 // 1 校验商机是否存在
129 125 validateBusinessExists(reqVO.getId());
130 126  
131   - // 2. 数据权限转移
  127 + // 2.1 数据权限转移
132 128 crmPermissionService.transferPermission(
133 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 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 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 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 14 * 线索 Service 接口
... ... @@ -49,22 +53,15 @@ public interface CrmClueService {
49 53 * @param ids 编号
50 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 61 * @param pageReqVO 分页查询
  62 + * @param userId 用户编号
58 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 4 import cn.hutool.core.collection.ListUtil;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 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 7 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO;
9 8 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueUpdateReqVO;
10 9 import cn.iocoder.yudao.module.crm.convert.clue.CrmClueConvert;
11 10 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;
12 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 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 18 import org.springframework.stereotype.Service;
15 19 import org.springframework.validation.annotation.Validated;
16 20  
17   -import jakarta.annotation.Resource;
18 21 import java.util.Collection;
19 22 import java.util.List;
20 23  
21 24 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
22 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 28 * 线索 Service 实现类
... ... @@ -33,8 +35,11 @@ public class CrmClueServiceImpl implements CrmClueService {
33 35  
34 36 @Resource
35 37 private CrmClueMapper clueMapper;
  38 +
36 39 @Resource
37 40 private CrmCustomerService customerService;
  41 + @Resource
  42 + private CrmPermissionService crmPermissionService;
38 43  
39 44 @Override
40 45 public Long createClue(CrmClueCreateReqVO createReqVO) {
... ... @@ -48,6 +53,7 @@ public class CrmClueServiceImpl implements CrmClueService {
48 53 }
49 54  
50 55 @Override
  56 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_LEADS, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
51 57 public void updateClue(CrmClueUpdateReqVO updateReqVO) {
52 58 // 校验存在
53 59 validateClueExists(updateReqVO.getId());
... ... @@ -60,11 +66,14 @@ public class CrmClueServiceImpl implements CrmClueService {
60 66 }
61 67  
62 68 @Override
  69 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_LEADS, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
63 70 public void deleteClue(Long id) {
64 71 // 校验存在
65 72 validateClueExists(id);
66 73 // 删除
67 74 clueMapper.deleteById(id);
  75 + // 删除数据权限
  76 + crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_LEADS.getType(), id);
68 77 }
69 78  
70 79 private void validateClueExists(Long id) {
... ... @@ -74,26 +83,22 @@ public class CrmClueServiceImpl implements CrmClueService {
74 83 }
75 84  
76 85 @Override
  86 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_LEADS, bizId = "#id", level = CrmPermissionLevelEnum.READ)
77 87 public CrmClueDO getClue(Long id) {
78 88 return clueMapper.selectById(id);
79 89 }
80 90  
81 91 @Override
82   - public List<CrmClueDO> getClueList(Collection<Long> ids) {
  92 + public List<CrmClueDO> getClueList(Collection<Long> ids, Long userId) {
83 93 if (CollUtil.isEmpty(ids)) {
84 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 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 5 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO;
6 6 import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactUpdateReqVO;
7 7 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
8   -import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
9   -
10 8 import jakarta.validation.Valid;
  9 +
11 10 import java.util.Collection;
12 11 import java.util.List;
13 12  
... ... @@ -22,7 +21,7 @@ public interface CrmContactService {
22 21 * 创建联系人
23 22 *
24 23 * @param createReqVO 创建信息
25   - * @param userId 用户编号
  24 + * @param userId 用户编号
26 25 * @return 编号
27 26 */
28 27 Long createContact(@Valid CrmContactCreateReqVO createReqVO, Long userId);
... ... @@ -52,10 +51,11 @@ public interface CrmContactService {
52 51 /**
53 52 * 获得联系人列表
54 53 *
55   - * @param ids 编号
  54 + * @param ids 编号
  55 + * @param userId 用户编号
56 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 63 * 数据权限:基于 {@link CrmContactDO}
64 64 *
65 65 * @param pageReqVO 分页查询
  66 + * @param userId 用户编号
66 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 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 10 import cn.iocoder.yudao.module.crm.convert.contact.ContactConvert;
11 11 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
12 12 import cn.iocoder.yudao.module.crm.dal.mysql.contact.CrmContactMapper;
13   -import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
14 13 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
15 14 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
  15 +import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
16 16 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
17 17 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
18 18 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
19 19 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  20 +import jakarta.annotation.Resource;
20 21 import org.springframework.stereotype.Service;
21 22 import org.springframework.transaction.annotation.Transactional;
22 23 import org.springframework.validation.annotation.Validated;
23 24  
24   -import jakarta.annotation.Resource;
25 25 import java.util.Collection;
26 26 import java.util.List;
27 27  
... ... @@ -82,7 +82,7 @@ public class CrmContactServiceImpl implements CrmContactService {
82 82 *
83 83 * @param saveReqVO 新增/修改请求 VO
84 84 */
85   - private void validateRelationDataExists(CrmContactBaseVO saveReqVO){
  85 + private void validateRelationDataExists(CrmContactBaseVO saveReqVO) {
86 86 // 1. 校验客户
87 87 if (saveReqVO.getCustomerId() != null && customerService.getCustomer(saveReqVO.getCustomerId()) == null) {
88 88 throw exception(CUSTOMER_NOT_EXISTS);
... ... @@ -98,12 +98,14 @@ public class CrmContactServiceImpl implements CrmContactService {
98 98 }
99 99  
100 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 102 public void deleteContact(Long id) {
103 103 // 校验存在
104 104 validateContactExists(id);
105 105 // 删除
106 106 contactMapper.deleteById(id);
  107 + // 删除数据权限
  108 + crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CONTACT.getType(), id);
107 109 }
108 110  
109 111 private void validateContactExists(Long id) {
... ... @@ -112,7 +114,6 @@ public class CrmContactServiceImpl implements CrmContactService {
112 114 }
113 115 }
114 116  
115   - // TODO 芋艿:是否要做数据权限的校验???
116 117 @Override
117 118 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.READ)
118 119 public CrmContactDO getContact(Long id) {
... ... @@ -120,28 +121,24 @@ public class CrmContactServiceImpl implements CrmContactService {
120 121 }
121 122  
122 123 @Override
123   - public List<CrmContactDO> getContactList(Collection<Long> ids) {
  124 + public List<CrmContactDO> getContactList(Collection<Long> ids, Long userId) {
124 125 if (CollUtil.isEmpty(ids)) {
125 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 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 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 12 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
13 13 import cn.iocoder.yudao.module.crm.dal.dataobject.contactbusinesslink.CrmContactBusinessLinkDO;
14 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 18 import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
  19 +import jakarta.annotation.Resource;
16 20 import org.springframework.stereotype.Service;
17 21 import org.springframework.validation.annotation.Validated;
18 22  
19   -import jakarta.annotation.Resource;
20 23 import java.util.List;
21 24  
22 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 27 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CONTACT_BUSINESS_LINK_NOT_EXISTS;
24 28  
25 29 // TODO @puhui999:数据权限的校验;每个操作;
... ... @@ -54,6 +58,7 @@ public class CrmContactBusinessLinkServiceImpl implements CrmContactBusinessLink
54 58 }
55 59  
56 60 @Override
  61 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
57 62 public void updateContactBusinessLink(CrmContactBusinessLinkSaveReqVO updateReqVO) {
58 63 // 校验存在
59 64 validateContactBusinessLinkExists(updateReqVO.getId());
... ... @@ -80,6 +85,7 @@ public class CrmContactBusinessLinkServiceImpl implements CrmContactBusinessLink
80 85 }
81 86  
82 87 @Override
  88 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.READ)
83 89 public CrmContactBusinessLinkDO getContactBusinessLink(Long id) {
84 90 return contactBusinessLinkMapper.selectById(id);
85 91 }
... ... @@ -90,7 +96,7 @@ public class CrmContactBusinessLinkServiceImpl implements CrmContactBusinessLink
90 96 crmContactBusinessLinkPageReqVO.setContactId(pageReqVO.getContactId());
91 97 PageResult<CrmContactBusinessLinkDO> businessLinkDOS = contactBusinessLinkMapper.selectPageByContact(crmContactBusinessLinkPageReqVO);
92 98 List<CrmBusinessDO> businessDOS = crmBusinessService.getBusinessList(CollectionUtils.convertList(businessLinkDOS.getList(),
93   - CrmContactBusinessLinkDO::getBusinessId));
  99 + CrmContactBusinessLinkDO::getBusinessId), getLoginUserId());
94 100 PageResult<CrmBusinessRespVO> pageResult = new PageResult<CrmBusinessRespVO>();
95 101 pageResult.setList(CrmBusinessConvert.INSTANCE.convert(businessDOS));
96 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 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractCreateReqVO;
5 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 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 8 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
9 9 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
10   -
11 10 import jakarta.validation.Valid;
  11 +
12 12 import java.util.Collection;
13 13 import java.util.List;
14 14  
... ... @@ -64,9 +64,10 @@ public interface CrmContractService {
64 64 * 数据权限:基于 {@link CrmContractDO} 读取
65 65 *
66 66 * @param pageReqVO 分页查询
  67 + * @param userId 用户编号
67 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 75 * 数据权限:基于 {@link CrmCustomerDO} 读取
75 76 *
76 77 * @param pageReqVO 分页查询
  78 + * @param userId 用户编号
77 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 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractCreateReqVO;
7 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 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 10 import cn.iocoder.yudao.module.crm.convert.contract.ContractConvert;
11 11 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
12 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 15 import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
16 16 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
17 17 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
  18 +import jakarta.annotation.Resource;
18 19 import org.springframework.stereotype.Service;
19 20 import org.springframework.transaction.annotation.Transactional;
20 21 import org.springframework.validation.annotation.Validated;
21 22  
22   -import jakarta.annotation.Resource;
23 23 import java.util.Collection;
24 24 import java.util.List;
25 25  
... ... @@ -56,7 +56,7 @@ public class CrmContractServiceImpl implements CrmContractService {
56 56  
57 57 @Override
58 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 60 public void updateContract(CrmContractUpdateReqVO updateReqVO) {
61 61 // 校验存在
62 62 validateContractExists(updateReqVO.getId());
... ... @@ -67,12 +67,14 @@ public class CrmContractServiceImpl implements CrmContractService {
67 67  
68 68 @Override
69 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 71 public void deleteContract(Long id) {
72 72 // 校验存在
73 73 validateContractExists(id);
74 74 // 删除
75 75 contractMapper.deleteById(id);
  76 + // 删除数据权限
  77 + crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CONTRACT.getType(), id);
76 78 }
77 79  
78 80 private CrmContractDO validateContractExists(Long id) {
... ... @@ -83,7 +85,6 @@ public class CrmContractServiceImpl implements CrmContractService {
83 85 return contract;
84 86 }
85 87  
86   - // TODO 芋艿:是否要做数据权限的校验???
87 88 @Override
88 89 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.READ)
89 90 public CrmContractDO getContract(Long id) {
... ... @@ -99,27 +100,24 @@ public class CrmContractServiceImpl implements CrmContractService {
99 100 }
100 101  
101 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 107 @Override
113 108 @Transactional(rollbackFor = Exception.class)
114 109 public void transferContract(CrmContractTransferReqVO reqVO, Long userId) {
115   - // 1 校验合同是否存在
  110 + // 1. 校验合同是否存在
116 111 validateContractExists(reqVO.getId());
117 112  
118   - // 2. 数据权限转移
  113 + // 2.1 数据权限转移
119 114 crmPermissionService.transferPermission(
120 115 ContractConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()));
  116 + // 2.2 设置负责人
  117 + contractMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
121 118  
122 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 6 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO;
7 7 import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerUpdateReqVO;
8 8 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
9   -
10 9 import jakarta.validation.Valid;
  10 +
11 11 import java.util.Collection;
12 12 import java.util.List;
13 13  
... ... @@ -56,7 +56,7 @@ public interface CrmCustomerService {
56 56 * @return 客户列表
57 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 71 * 校验客户是否存在
72 72 *
73 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 15 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
16 16 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
17 17 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  18 +import jakarta.annotation.Resource;
18 19 import org.springframework.stereotype.Service;
19 20 import org.springframework.transaction.annotation.Transactional;
20 21 import org.springframework.validation.annotation.Validated;
21 22  
22   -import jakarta.annotation.Resource;
23 23 import java.util.*;
24 24  
25 25 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
... ... @@ -78,6 +78,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
78 78  
79 79 // 删除
80 80 customerMapper.deleteById(id);
  81 + // 删除数据权限
  82 + crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id);
81 83 }
82 84  
83 85 private void validateCustomerExists(Long id) {
... ... @@ -93,32 +95,34 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
93 95 }
94 96  
95 97 @Override
96   - public List<CrmCustomerDO> getCustomerList(Collection<Long> ids) {
  98 + public List<CrmCustomerDO> getCustomerList(Collection<Long> ids, Long userId) {
97 99 if (CollUtil.isEmpty(ids)) {
98 100 return Collections.emptyList();
99 101 }
100   - return customerMapper.selectBatchIds(ids);
  102 + return customerMapper.selectBatchIds(ids, userId);
101 103 }
102 104  
103 105 @Override
104 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 113 * @param customerId 客户 id
113   - * @return 客户
114 114 */
115 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 123 if (Objects.isNull(customer)) {
119 124 throw exception(CUSTOMER_NOT_EXISTS);
120 125 }
121   - return customer;
122 126 }
123 127  
124 128 @Override
... ... @@ -128,9 +132,11 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
128 132 // 1. 校验客户是否存在
129 133 validateCustomer(reqVO.getId());
130 134  
131   - // 2. 数据权限转移
  135 + // 2.1 数据权限转移
132 136 crmPermissionService.transferPermission(
133 137 CrmCustomerConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()));
  138 + // 2.2 转移后重新设置负责人
  139 + customerMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
134 140  
135 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 7 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
8 8 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
9 9 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
10   -
11 10 import jakarta.validation.Valid;
  11 +
12 12 import java.util.Collection;
13 13 import java.util.List;
14 14  
... ... @@ -58,9 +58,17 @@ public interface CrmPermissionService {
58 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 72 * @param userId 用户编号
65 73 */
66 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 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
12 12 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
13 13 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
  14 +import jakarta.annotation.Resource;
14 15 import org.springframework.stereotype.Service;
15 16 import org.springframework.transaction.annotation.Transactional;
16 17 import org.springframework.validation.annotation.Validated;
17 18  
18   -import jakarta.annotation.Resource;
19 19 import java.util.Collection;
20 20 import java.util.Collections;
21 21 import java.util.List;
... ... @@ -126,9 +126,9 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
126 126 @Override
127 127 @Transactional(rollbackFor = Exception.class)
128 128 public void deletePermission(Integer bizType, Long bizId, Integer level) {
  129 + // 校验存在
129 130 List<CrmPermissionDO> permissions = crmPermissionMapper.selectListByBizTypeAndBizIdAndLevel(
130 131 bizType, bizId, level);
131   - // 校验存在
132 132 if (CollUtil.isEmpty(permissions)) {
133 133 throw exception(CRM_PERMISSION_NOT_EXISTS);
134 134 }
... ... @@ -138,6 +138,18 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
138 138 }
139 139  
140 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 153 public void deletePermissionBatch(Collection<Long> ids, Long userId) {
142 154 List<CrmPermissionDO> permissions = crmPermissionMapper.selectBatchIds(ids);
143 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 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
5 5 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueCreateReqVO;
6   -import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueExportReqVO;
7 6 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO;
8 7 import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueUpdateReqVO;
9 8 import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO;
10 9 import cn.iocoder.yudao.module.crm.dal.mysql.clue.CrmClueMapper;
  10 +import jakarta.annotation.Resource;
11 11 import org.junit.jupiter.api.Disabled;
12 12 import org.junit.jupiter.api.Test;
13 13 import org.springframework.context.annotation.Import;
14 14  
15   -import jakarta.annotation.Resource;
16 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 18 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
20 19 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
21 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 24 import static org.junit.jupiter.api.Assertions.*;
26 25  
27 26 // TODO 芋艿:单测后续补;
  27 +
28 28 /**
29 29 * {@link CrmClueServiceImpl} 的单元测试类
30 30 *
... ... @@ -90,8 +90,8 @@ public class CrmClueServiceImplTest extends BaseDbUnitTest {
90 90  
91 91 // 调用
92 92 clueService.deleteClue(id);
93   - // 校验数据不存在了
94   - assertNull(clueMapper.selectById(id));
  93 + // 校验数据不存在了
  94 + assertNull(clueMapper.selectById(id));
95 95 }
96 96  
97 97 @Test
... ... @@ -106,110 +106,102 @@ public class CrmClueServiceImplTest extends BaseDbUnitTest {
106 106 @Test
107 107 @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
108 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 157 @Test
158 158 @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
159 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 7 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractUpdateReqVO;
8 8 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
9 9 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper;
  10 +import jakarta.annotation.Resource;
10 11 import org.junit.jupiter.api.Disabled;
11 12 import org.junit.jupiter.api.Test;
12 13 import org.springframework.context.annotation.Import;
13 14  
14   -import jakarta.annotation.Resource;
15   -
16 15 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
17 16 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
18 17 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
... ... @@ -127,7 +126,7 @@ public class ContractServiceImplTest extends BaseDbUnitTest {
127 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 131 assertEquals(1, pageResult.getTotal());
133 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 77 // ==================== 子表($subTable.classComment) ====================
78 78 ## 情况一:MASTER_ERP 时,需要分查询页子表
79 79 #if ( $table.templateType == 11 )
80   -
81 80 // 获得${subTable.classComment}分页
82 81 export function get${subSimpleClassName}Page(params) {
83 82 return request({
... ... @@ -89,20 +88,18 @@ export function export${simpleClassName}Excel(params) {
89 88 ## 情况二:非 MASTER_ERP 时,需要列表查询子表
90 89 #else
91 90 #if ( $subTable.subJoinMany )
92   -
93 91 // 获得${subTable.classComment}列表
94 92 export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}) {
95 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 95 method: 'get'
98 96 })
99 97 }
100 98 #else
101   -
102 99 // 获得${subTable.classComment}
103 100 export function get${subSimpleClassName}By${SubJoinColumnName}(${subJoinColumn.javaField}) {
104 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 103 method: 'get'
107 104 })
108 105 }
... ... @@ -113,7 +110,7 @@ export function export${simpleClassName}Excel(params) {
113 110 // 新增${subTable.classComment}
114 111 export function create${subSimpleClassName}(data) {
115 112 return request({
116   - url: `${baseURL}/${subSimpleClassName_strikeCase}/create`,
  113 + url: '${baseURL}/${subSimpleClassName_strikeCase}/create',
117 114 method: 'post',
118 115 data
119 116 })
... ... @@ -122,7 +119,7 @@ export function export${simpleClassName}Excel(params) {
122 119 // 修改${subTable.classComment}
123 120 export function update${subSimpleClassName}(data) {
124 121 return request({
125   - url: `${baseURL}/${subSimpleClassName_strikeCase}/update`,
  122 + url: '${baseURL}/${subSimpleClassName_strikeCase}/update',
126 123 method: 'post',
127 124 data
128 125 })
... ... @@ -131,7 +128,7 @@ export function export${simpleClassName}Excel(params) {
131 128 // 删除${subTable.classComment}
132 129 export function delete${subSimpleClassName}(id) {
133 130 return request({
134   - url: `${baseURL}/${subSimpleClassName_strikeCase}/delete?id=` + id,
  131 + url: '${baseURL}/${subSimpleClassName_strikeCase}/delete?id=' + id,
135 132 method: 'delete'
136 133 })
137 134 }
... ... @@ -139,7 +136,7 @@ export function export${simpleClassName}Excel(params) {
139 136 // 获得${subTable.classComment}
140 137 export function get${subSimpleClassName}(id) {
141 138 return request({
142   - url: `${baseURL}/${subSimpleClassName_strikeCase}/get?id=` + id,
  139 + url: '${baseURL}/${subSimpleClassName_strikeCase}/get?id=' + id,
143 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 6 import java.util.Collection;
7 7 import java.util.List;
8 8 import java.util.Map;
9   -import java.util.Set;
10 9  
11 10 /**
12 11 * Admin 用户 API 接口
... ... @@ -23,14 +22,13 @@ public interface AdminUserApi {
23 22 */
24 23 AdminUserRespDTO getUser(Long id);
25 24  
26   - // TODO @puhui999:这里返回 List<AdminUserRespDTO> 方法名可以改成 getUserListBySubordinate
27 25 /**
28 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 34 * 通过用户 ID 查询用户们
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java
1 1 package cn.iocoder.yudao.module.system.api.user;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.hutool.core.util.ObjUtil;
4 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 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 8 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
8 9 import cn.iocoder.yudao.module.system.service.dept.DeptService;
9 10 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
  11 +import jakarta.annotation.Resource;
10 12 import org.springframework.stereotype.Service;
11 13  
12   -import jakarta.annotation.Resource;
  14 +import java.util.ArrayList;
13 15 import java.util.Collection;
14 16 import java.util.Collections;
15 17 import java.util.List;
16   -import java.util.Set;
17 18  
18 19 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
19 20  
... ... @@ -37,21 +38,31 @@ public class AdminUserApiImpl implements AdminUserApi {
37 38 }
38 39  
39 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 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 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 68 @Override
... ...
yudao-server/pom.xml
... ... @@ -37,11 +37,11 @@
37 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 47 <!-- <dependency>-->
... ... @@ -56,11 +56,11 @@
56 56 <!-- <version>${revision}</version>-->
57 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 66 <!-- <dependency>-->
... ... @@ -70,33 +70,33 @@
70 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 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 101 <!-- spring boot 配置所需依赖 -->
102 102 <dependency>
... ...