Commit ba47402a7fa5a986fcc99aea2c4de5c57d16c67e

Authored by YunaiV
1 parent 85c9524a

✨ CRM:完善回款 plan 列表

yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
... ... @@ -229,6 +229,7 @@ public class CrmContractController {
229 229 return success(contractService.getRemindContractCount(getLoginUserId()));
230 230 }
231 231  
  232 + // TODO @芋艿:需要看下;
232 233 @GetMapping("/list-all-simple-by-customer")
233 234 @Operation(summary = "获得合同精简列表", description = "只包含有读权限的客户的合同,主要用于前端的下拉选项")
234 235 @Parameter(name = "customerId", description = "客户编号", required = true)
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java
... ... @@ -11,7 +11,7 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
11 11 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO;
12 12 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanRespVO;
13 13 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanSaveReqVO;
14   -import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivablePlanConvert;
  14 +import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
15 15 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
16 16 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
17 17 import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
... ... @@ -34,6 +34,7 @@ import org.springframework.validation.annotation.Validated;
34 34 import org.springframework.web.bind.annotation.*;
35 35  
36 36 import java.io.IOException;
  37 +import java.util.Collections;
37 38 import java.util.List;
38 39 import java.util.Map;
39 40 import java.util.stream.Stream;
... ... @@ -42,6 +43,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
42 43 import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
43 44 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
44 45 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  46 +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
45 47 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
46 48 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
47 49  
... ... @@ -101,7 +103,7 @@ public class CrmReceivablePlanController {
101 103 @PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
102 104 public CommonResult<PageResult<CrmReceivablePlanRespVO>> getReceivablePlanPage(@Valid CrmReceivablePlanPageReqVO pageReqVO) {
103 105 PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPage(pageReqVO, getLoginUserId());
104   - return success(convertDetailReceivablePlanPage(pageResult));
  106 + return success(new PageResult<>(buildReceivableDetailList(pageResult.getList()), pageResult.getTotal()));
105 107 }
106 108  
107 109 @GetMapping("/page-by-customer")
... ... @@ -109,10 +111,9 @@ public class CrmReceivablePlanController {
109 111 public CommonResult<PageResult<CrmReceivablePlanRespVO>> getReceivablePlanPageByCustomer(@Valid CrmReceivablePlanPageReqVO pageReqVO) {
110 112 Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
111 113 PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPageByCustomerId(pageReqVO);
112   - return success(convertDetailReceivablePlanPage(pageResult));
  114 + return success(new PageResult<>(buildReceivableDetailList(pageResult.getList()), pageResult.getTotal()));
113 115 }
114 116  
115   - // TODO 芋艿:后面在优化导出
116 117 @GetMapping("/export-excel")
117 118 @Operation(summary = "导出回款计划 Excel")
118 119 @PreAuthorize("@ss.hasPermission('crm:receivable-plan:export')")
... ... @@ -120,39 +121,42 @@ public class CrmReceivablePlanController {
120 121 public void exportReceivablePlanExcel(@Valid CrmReceivablePlanPageReqVO exportReqVO,
121 122 HttpServletResponse response) throws IOException {
122 123 exportReqVO.setPageSize(PAGE_SIZE_NONE);
123   - PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPage(exportReqVO, getLoginUserId());
  124 + List<CrmReceivablePlanDO> list = receivablePlanService.getReceivablePlanPage(exportReqVO, getLoginUserId()).getList();
124 125 // 导出 Excel
125 126 ExcelUtils.write(response, "回款计划.xls", "数据", CrmReceivablePlanRespVO.class,
126   - convertDetailReceivablePlanPage(pageResult).getList());
  127 + buildReceivableDetailList(list));
127 128 }
128 129  
129   - /**
130   - * 构建详细的回款计划分页结果
131   - *
132   - * @param pageResult 简单的回款计划分页结果
133   - * @return 详细的回款计划分页结果
134   - */
135   - private PageResult<CrmReceivablePlanRespVO> convertDetailReceivablePlanPage(PageResult<CrmReceivablePlanDO> pageResult) {
136   - List<CrmReceivablePlanDO> receivablePlanList = pageResult.getList();
  130 + private List<CrmReceivablePlanRespVO> buildReceivableDetailList(List<CrmReceivablePlanDO> receivablePlanList) {
137 131 if (CollUtil.isEmpty(receivablePlanList)) {
138   - return PageResult.empty(pageResult.getTotal());
  132 + return Collections.emptyList();
139 133 }
140   - // 1. 获取客户列表
141   - List<CrmCustomerDO> customerList = customerService.getCustomerList(
  134 + // 1.1 获取客户 Map
  135 + Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap(
142 136 convertSet(receivablePlanList, CrmReceivablePlanDO::getCustomerId));
143   - // 2. 获取创建人、负责人列表
  137 + // 1.2 获取创建人、负责人列表
144 138 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivablePlanList,
145 139 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
146   - // 3. 获得合同列表
147   - List<CrmContractDO> contractList = contractService.getContractList(
  140 + // 1.3 获得合同 Map
  141 + Map<Long, CrmContractDO> contractMap = contractService.getContractMap(
148 142 convertSet(receivablePlanList, CrmReceivablePlanDO::getContractId));
149   - // 4. 获得还款列表
150   - List<CrmReceivableDO> receivableList = receivableService.getReceivableList(
  143 + // 1.4 获得还款 Map
  144 + Map<Long, CrmReceivableDO> receivableMap = receivableService.getReceivableMap(
151 145 convertSet(receivablePlanList, CrmReceivablePlanDO::getReceivableId));
152   - return CrmReceivablePlanConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList, receivableList);
  146 + // 2. 拼接数据
  147 + return BeanUtils.toBean(receivablePlanList, CrmReceivablePlanRespVO.class, (receivablePlanVO) -> {
  148 + // 2.1 拼接客户信息
  149 + findAndThen(customerMap, receivablePlanVO.getCustomerId(), customer -> receivablePlanVO.setCustomerName(customer.getName()));
  150 + // 2.2 拼接用户信息
  151 + findAndThen(userMap, receivablePlanVO.getOwnerUserId(), user -> receivablePlanVO.setOwnerUserName(user.getNickname()));
  152 + findAndThen(userMap, Long.parseLong(receivablePlanVO.getCreator()), user -> receivablePlanVO.setCreatorName(user.getNickname()));
  153 + // 2.3 拼接合同信息
  154 + findAndThen(contractMap, receivablePlanVO.getContractId(), contract -> receivablePlanVO.setContractNo(contract.getNo()));
  155 + // 2.4 拼接回款信息
  156 + receivablePlanVO.setReceivable(BeanUtils.toBean(receivableMap.get(receivablePlanVO.getReceivableId()), CrmReceivableRespVO.class));
  157 + });
153 158 }
154 159  
155   -
156 160 @GetMapping("/remind-receivable-plan-count")
157 161 @Operation(summary = "获得待回款提醒数量")
158 162 @PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
... ... @@ -160,6 +164,7 @@ public class CrmReceivablePlanController {
160 164 return success(receivablePlanService.getRemindReceivablePlanCount(getLoginUserId()));
161 165 }
162 166  
  167 + // TODO @芋艿:需要看下;
163 168 @GetMapping("/list-all-simple-by-customer")
164 169 @Operation(summary = "获得回款计划精简列表", description = "获得回款计划精简列表,主要用于前端的下拉选项")
165 170 @Parameters({
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanRespVO.java
1 1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan;
2 2  
  3 +import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
  4 +import com.alibaba.excel.annotation.ExcelProperty;
3 5 import io.swagger.v3.oas.annotations.media.Schema;
4 6 import lombok.Data;
5 7  
... ... @@ -35,14 +37,16 @@ public class CrmReceivablePlanRespVO {
35 37 @Schema(description = "计划回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
36 38 private LocalDateTime returnTime;
37 39  
38   - @Schema(description = "回款方式", example = "1")
39   - private Integer returnType; // 来自 Receivable 的 returnType 字段
  40 + @Schema(description = "计划回款方式", example = "1")
  41 + private Integer returnType;
40 42  
41 43 @Schema(description = "计划回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
42 44 private BigDecimal price;
43 45  
44 46 @Schema(description = "回款编号", example = "19852")
45 47 private Long receivableId;
  48 + @Schema(description = "回款信息")
  49 + private CrmReceivableRespVO receivable;
46 50  
47 51 @Schema(description = "完成状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
48 52 private Boolean finishStatus;
... ... @@ -57,12 +61,18 @@ public class CrmReceivablePlanRespVO {
57 61 private String remark;
58 62  
59 63 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  64 + @ExcelProperty("创建时间")
60 65 private LocalDateTime createTime;
61 66  
62   - @Schema(description = "创建人", example = "25682")
63   - private String creator;
  67 + @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
  68 + @ExcelProperty("更新时间")
  69 + private LocalDateTime updateTime;
64 70  
65   - @Schema(description = "创建人名字", example = "test")
  71 + @Schema(description = "创建人", example = "1024")
  72 + @ExcelProperty("创建人")
  73 + private String creator;
  74 + @Schema(description = "创建人名字", example = "芋道源码")
  75 + @ExcelProperty("创建人名字")
66 76 private String creatorName;
67 77  
68 78 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivablePlanConvert.java deleted
1   -package cn.iocoder.yudao.module.crm.convert.receivable;
2   -
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5   -import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanRespVO;
6   -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
7   -import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
8   -import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
9   -import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO;
10   -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
11   -import org.mapstruct.Mapper;
12   -import org.mapstruct.factory.Mappers;
13   -
14   -import java.util.List;
15   -import java.util.Map;
16   -
17   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
18   -import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
19   -
20   -/**
21   - * 回款计划 Convert
22   - *
23   - * @author 芋道源码
24   - */
25   -@Mapper
26   -public interface CrmReceivablePlanConvert {
27   -
28   - CrmReceivablePlanConvert INSTANCE = Mappers.getMapper(CrmReceivablePlanConvert.class);
29   -
30   - default PageResult<CrmReceivablePlanRespVO> convertPage(PageResult<CrmReceivablePlanDO> pageResult, Map<Long, AdminUserRespDTO> userMap,
31   - List<CrmCustomerDO> customerList, List<CrmContractDO> contractList,
32   - List<CrmReceivableDO> receivableList) {
33   - PageResult<CrmReceivablePlanRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmReceivablePlanRespVO.class);
34   - // 拼接关联字段
35   - Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);
36   - Map<Long, CrmContractDO> contractMap = convertMap(contractList, CrmContractDO::getId);
37   - Map<Long, CrmReceivableDO> receivableMap = convertMap(receivableList, CrmReceivableDO::getId);
38   - voPageResult.getList().forEach(receivablePlan -> {
39   - findAndThen(userMap, receivablePlan.getOwnerUserId(), user -> receivablePlan.setOwnerUserName(user.getNickname()));
40   - findAndThen(userMap, Long.parseLong(receivablePlan.getCreator()), user -> receivablePlan.setCreatorName(user.getNickname()));
41   - findAndThen(customerMap, receivablePlan.getCustomerId(), customer -> receivablePlan.setCustomerName(customer.getName()));
42   - findAndThen(contractMap, receivablePlan.getContractId(), contract -> receivablePlan.setContractNo(contract.getNo()));
43   - findAndThen(receivableMap, receivablePlan.getReceivableId(), receivable -> receivablePlan.setReturnType(receivable.getReturnType()));
44   - });
45   - return voPageResult;
46   - }
47   -
48   -}
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/receivable/CrmReceivablePlanDO.java
... ... @@ -61,7 +61,7 @@ public class CrmReceivablePlanDO extends BaseDO {
61 61 */
62 62 private LocalDateTime returnTime;
63 63 /**
64   - * 回款类型
  64 + * 计划回款类型
65 65 *
66 66 * 枚举 {@link CrmReceivableReturnTypeEnum}
67 67 */
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivablePlanMapper.java
... ... @@ -47,7 +47,6 @@ public interface CrmReceivablePlanMapper extends BaseMapperX&lt;CrmReceivablePlanDO
47 47 .eqIfPresent(CrmReceivablePlanDO::getCustomerId, pageReqVO.getCustomerId())
48 48 .eqIfPresent(CrmReceivablePlanDO::getContractId, pageReqVO.getContractId())
49 49 .orderByDesc(CrmReceivablePlanDO::getPeriod);
50   -
51 50 if (Objects.nonNull(pageReqVO.getContractNo())) { // 根据合同编号检索
52 51 query.innerJoin(CrmContractDO.class, on -> on.like(CrmContractDO::getNo, pageReqVO.getContractNo())
53 52 .eq(CrmContractDO::getId, CrmReceivablePlanDO::getContractId));
... ... @@ -67,9 +66,7 @@ public interface CrmReceivablePlanMapper extends BaseMapperX&lt;CrmReceivablePlanDO
67 66 } else if (CrmReceivablePlanPageReqVO.REMIND_TYPE_RECEIVED.equals(pageReqVO.getRemindType())) { // 已回款
68 67 query.isNotNull(CrmReceivablePlanDO::getReceivableId)
69 68 .between(CrmReceivablePlanDO::getReturnTime, beginOfToday, endOfToday.plusDays(REMIND_DAYS));
70   - ;
71 69 }
72   -
73 70 return selectJoinPage(pageReqVO, CrmReceivablePlanDO.class, query);
74 71 }
75 72  
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java
... ... @@ -13,6 +13,9 @@ import jakarta.validation.Valid;
13 13 import java.time.LocalDateTime;
14 14 import java.util.Collection;
15 15 import java.util.List;
  16 +import java.util.Map;
  17 +
  18 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
16 19  
17 20 /**
18 21 * CRM 合同 Service 接口
... ... @@ -94,6 +97,16 @@ public interface CrmContractService {
94 97 List<CrmContractDO> getContractList(Collection<Long> ids);
95 98  
96 99 /**
  100 + * 获得合同 Map
  101 + *
  102 + * @param ids 编号
  103 + * @return 合同 Map
  104 + */
  105 + default Map<Long, CrmContractDO> getContractMap(Collection<Long> ids) {
  106 + return convertMap(getContractList(ids), CrmContractDO::getId);
  107 + }
  108 +
  109 + /**
97 110 * 获得合同分页
98 111 *
99 112 * 数据权限:基于 {@link CrmContractDO} 读取
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java
... ... @@ -9,6 +9,9 @@ import jakarta.validation.Valid;
9 9  
10 10 import java.util.Collection;
11 11 import java.util.List;
  12 +import java.util.Map;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
12 15  
13 16 /**
14 17 * CRM 回款 Service 接口
... ... @@ -72,6 +75,16 @@ public interface CrmReceivableService {
72 75 List<CrmReceivableDO> getReceivableList(Collection<Long> ids);
73 76  
74 77 /**
  78 + * 获得回款 Map
  79 + *
  80 + * @param ids 编号
  81 + * @return 回款 Map
  82 + */
  83 + default Map<Long, CrmReceivableDO> getReceivableMap(Collection<Long> ids) {
  84 + return convertMap(getReceivableList(ids), CrmReceivableDO::getId);
  85 + }
  86 +
  87 + /**
75 88 * 获得回款分页
76 89 *
77 90 * 数据权限:基于 {@link CrmReceivableDO} 读取
... ...