Commit 33b056e6c44776461b3029325004cff9a1b8e573

Authored by YunaiV
1 parent 2890de81

✨ CRM:完善回款的审批

Showing 10 changed files with 122 additions and 17 deletions
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/DictTypeConstants.java
... ... @@ -14,5 +14,6 @@ public interface DictTypeConstants {
14 14 String CRM_PRODUCT_UNIT = "crm_product_unit"; // CRM 产品单位
15 15 String CRM_PRODUCT_STATUS = "crm_product_status"; // CRM 产品状态
16 16 String CRM_FOLLOW_UP_TYPE = "crm_follow_up_type"; // CRM 跟进方式
  17 + String CRM_RECEIVABLE_RETURN_TYPE = "crm_receivable_return_type"; // CRM 回款方式
17 18  
18 19 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/CrmOperateLogController.java
... ... @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 6 import cn.iocoder.yudao.module.crm.controller.admin.operatelog.vo.CrmOperateLogPageReqVO;
7   -import cn.iocoder.yudao.module.crm.controller.admin.operatelog.vo.CrmOperateLogV2RespVO;
  7 +import cn.iocoder.yudao.module.crm.controller.admin.operatelog.vo.CrmOperateLogRespVO;
8 8 import cn.iocoder.yudao.module.crm.enums.LogRecordConstants;
9 9 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
10 10 import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
... ... @@ -54,11 +54,11 @@ public class CrmOperateLogController {
54 54 @GetMapping("/page")
55 55 @Operation(summary = "获得操作日志")
56 56 @PreAuthorize("@ss.hasPermission('crm:operate-log:query')")
57   - public CommonResult<PageResult<CrmOperateLogV2RespVO>> getCustomerOperateLog(@Valid CrmOperateLogPageReqVO pageReqVO) {
  57 + public CommonResult<PageResult<CrmOperateLogRespVO>> getCustomerOperateLog(@Valid CrmOperateLogPageReqVO pageReqVO) {
58 58 OperateLogV2PageReqDTO reqDTO = new OperateLogV2PageReqDTO();
59 59 reqDTO.setPageSize(PAGE_SIZE_NONE); // 默认不分页,需要分页需注释
60 60 reqDTO.setBizType(BIZ_TYPE_MAP.get(pageReqVO.getBizType())).setBizId(pageReqVO.getBizId());
61   - return success(BeanUtils.toBean(operateLogApi.getOperateLogPage(reqDTO), CrmOperateLogV2RespVO.class));
  61 + return success(BeanUtils.toBean(operateLogApi.getOperateLogPage(reqDTO), CrmOperateLogRespVO.class));
62 62 }
63 63  
64 64 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/vo/CrmOperateLogV2RespVO.java renamed to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/operatelog/vo/CrmOperateLogRespVO.java
... ... @@ -6,10 +6,10 @@ import lombok.Data;
6 6  
7 7 import java.time.LocalDateTime;
8 8  
9   -@Schema(description = "管理后台 - CRM 跟进 Response VO")
  9 +@Schema(description = "管理后台 - CRM 操作日志 Response VO")
10 10 @Data
11 11 @ExcelIgnoreUnannotated
12   -public class CrmOperateLogV2RespVO {
  12 +public class CrmOperateLogRespVO {
13 13  
14 14 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
15 15 private Long id;
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java
... ... @@ -41,8 +41,7 @@ import java.util.stream.Stream;
41 41  
42 42 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
43 43 import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
44   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
45   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  44 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
46 45 import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
47 46 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
48 47 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
... ... @@ -95,7 +94,14 @@ public class CrmReceivableController {
95 94 @PreAuthorize("@ss.hasPermission('crm:receivable:query')")
96 95 public CommonResult<CrmReceivableRespVO> getReceivable(@RequestParam("id") Long id) {
97 96 CrmReceivableDO receivable = receivableService.getReceivable(id);
98   - return success(BeanUtils.toBean(receivable, CrmReceivableRespVO.class));
  97 + return success(buildReceivableDetail(receivable));
  98 + }
  99 +
  100 + private CrmReceivableRespVO buildReceivableDetail(CrmReceivableDO receivable) {
  101 + if (receivable == null) {
  102 + return null;
  103 + }
  104 + return buildReceivableDetailList(Collections.singletonList(receivable)).get(0);
99 105 }
100 106  
101 107 @GetMapping("/page")
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableRespVO.java
... ... @@ -51,12 +51,16 @@ public class CrmReceivableRespVO {
51 51 @ExcelProperty("负责人部门")
52 52 private String ownerUserDeptName;
53 53  
54   - @Schema(description = "备注", example = "备注")
55   - private String remark;
  54 + @Schema(description = "工作流编号", example = "1043")
  55 + @ExcelProperty("工作流编号")
  56 + private String processInstanceId;
56 57  
57 58 @Schema(description = "审批状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
58 59 private Integer auditStatus;
59 60  
  61 + @Schema(description = "备注", example = "备注")
  62 + private String remark;
  63 +
60 64 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
61 65 private LocalDateTime createTime;
62 66  
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableSaveReqVO.java
... ... @@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable;
2 2  
3 3 import cn.iocoder.yudao.framework.common.validation.InEnum;
4 4 import cn.iocoder.yudao.module.crm.enums.receivable.CrmReceivableReturnTypeEnum;
  5 +import cn.iocoder.yudao.module.crm.framework.operatelog.core.*;
  6 +import com.mzt.logapi.starter.annotation.DiffLogField;
5 7 import io.swagger.v3.oas.annotations.media.Schema;
6 8 import jakarta.validation.constraints.NotNull;
7 9 import lombok.Data;
... ... @@ -17,32 +19,40 @@ public class CrmReceivableSaveReqVO {
17 19 private Long id;
18 20  
19 21 @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  22 + @DiffLogField(name = "负责人", function = SysAdminUserParseFunction.NAME)
20 23 @NotNull(message = "负责人编号不能为空")
21 24 private Long ownerUserId;
22 25  
23 26 @Schema(description = "客户编号", example = "2")
  27 + @DiffLogField(name = "客户", function = CrmCustomerParseFunction.NAME)
24 28 private Long customerId; // 该字段不通过前端传递,而是 contractId 查询出来设置进去
25 29  
26 30 @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  31 + @DiffLogField(name = "合同", function = CrmContractParseFunction.NAME)
27 32 @NotNull(message = "合同编号不能为空")
28 33 private Long contractId;
29 34  
30 35 @Schema(description = "回款计划编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  36 + @DiffLogField(name = "合同", function = CrmReceivablePlanParseFunction.NAME)
31 37 private Long planId;
32 38  
33 39 @Schema(description = "回款方式", example = "2")
  40 + @DiffLogField(name = "回款方式", function = CrmReceivableReturnTypeParseFunction.NAME)
34 41 @InEnum(CrmReceivableReturnTypeEnum.class)
35 42 private Integer returnType;
36 43  
37 44 @Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
  45 + @DiffLogField(name = "回款金额")
38 46 @NotNull(message = "回款金额不能为空")
39 47 private BigDecimal price;
40 48  
41 49 @Schema(description = "回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
42 50 @NotNull(message = "回款日期不能为空")
  51 + @DiffLogField(name = "回款日期")
43 52 private LocalDateTime returnTime;
44 53  
45 54 @Schema(description = "备注", example = "备注")
  55 + @DiffLogField(name = "备注")
46 56 private String remark;
47 57  
48 58 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmReceivablePlanParseFunction.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.framework.operatelog.core;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO;
  5 +import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivablePlanService;
  6 +import com.mzt.logapi.service.IParseFunction;
  7 +import jakarta.annotation.Resource;
  8 +import lombok.extern.slf4j.Slf4j;
  9 +import org.springframework.stereotype.Component;
  10 +
  11 +/**
  12 + * CRM 回款计划的 {@link IParseFunction} 实现类
  13 + *
  14 + * @author HUIHUI
  15 + */
  16 +@Component
  17 +@Slf4j
  18 +public class CrmReceivablePlanParseFunction implements IParseFunction {
  19 +
  20 + public static final String NAME = "getReceivablePlanServiceById";
  21 +
  22 + @Resource
  23 + private CrmReceivablePlanService receivablePlanService;
  24 +
  25 + @Override
  26 + public boolean executeBefore() {
  27 + return true; // 先转换值后对比
  28 + }
  29 +
  30 + @Override
  31 + public String functionName() {
  32 + return NAME;
  33 + }
  34 +
  35 + @Override
  36 + public String apply(Object value) {
  37 + if (StrUtil.isEmptyIfStr(value)) {
  38 + return "";
  39 + }
  40 + CrmReceivablePlanDO receivablePlan = receivablePlanService.getReceivablePlan(Long.parseLong(value.toString()));
  41 + return receivablePlan == null ? "" : receivablePlan.getPeriod().toString();
  42 + }
  43 +
  44 +}
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/operatelog/core/CrmReceivableReturnTypeParseFunction.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.framework.operatelog.core;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
  5 +import com.mzt.logapi.service.IParseFunction;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +import org.springframework.stereotype.Component;
  8 +
  9 +import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_RECEIVABLE_RETURN_TYPE;
  10 +
  11 +/**
  12 + * CRM 回款方式的 {@link IParseFunction} 实现类
  13 + *
  14 + * @author HUIHUI
  15 + */
  16 +@Slf4j
  17 +@Component
  18 +public class CrmReceivableReturnTypeParseFunction implements IParseFunction {
  19 +
  20 + public static final String NAME = "getReceivableReturnType";
  21 +
  22 + @Override
  23 + public boolean executeBefore() {
  24 + return true; // 先转换值后对比
  25 + }
  26 +
  27 + @Override
  28 + public String functionName() {
  29 + return NAME;
  30 + }
  31 +
  32 + @Override
  33 + public String apply(Object value) {
  34 + if (StrUtil.isEmptyIfStr(value)) {
  35 + return "";
  36 + }
  37 + return DictFrameworkUtils.getDictDataLabel(CRM_RECEIVABLE_RETURN_TYPE, value.toString());
  38 + }
  39 +
  40 +}
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java
... ... @@ -37,7 +37,6 @@ import org.springframework.validation.annotation.Validated;
37 37  
38 38 import java.util.Collection;
39 39 import java.util.List;
40   -import java.util.Objects;
41 40  
42 41 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
43 42 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
... ... @@ -54,11 +53,10 @@ import static cn.iocoder.yudao.module.crm.util.CrmAuditStatusUtils.convertBpmRes
54 53 @Slf4j
55 54 public class CrmReceivableServiceImpl implements CrmReceivableService {
56 55  
57   - // TODO @芋艿:改个名字
58 56 /**
59   - * BPM 回款审批流程标识
  57 + * BPM 合同审批流程标识
60 58 */
61   - public static final String RECEIVABLE_APPROVE = "receivable-approve";
  59 + public static final String BPM_PROCESS_DEFINITION_KEY = "crm-receivable-audit";
62 60  
63 61 @Resource
64 62 private CrmReceivableMapper receivableMapper;
... ... @@ -79,6 +77,7 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
79 77 @Resource
80 78 private BpmProcessInstanceApi bpmProcessInstanceApi;
81 79  
  80 + // TODO @puhui999:操作日志没记录上
82 81 @Override
83 82 @Transactional(rollbackFor = Exception.class)
84 83 @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_CREATE_SUB_TYPE, bizNo = "{{#receivable.id}}",
... ... @@ -134,6 +133,7 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
134 133 }
135 134 }
136 135  
  136 + // TODO @puhui999:操作日志没记录上
137 137 @Override
138 138 @Transactional(rollbackFor = Exception.class)
139 139 @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
... ... @@ -184,7 +184,7 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
184 184 // 1.1 校验存在
185 185 CrmReceivableDO receivable = validateReceivableExists(id);
186 186 // 1.2 如果被 CrmReceivablePlanDO 所使用,则不允许删除
187   - if (Objects.nonNull(receivable.getPlanId()) && receivablePlanService.getReceivablePlan(receivable.getPlanId()) != null) {
  187 + if (receivable.getPlanId() != null && receivablePlanService.getReceivablePlan(receivable.getPlanId()) != null) {
188 188 throw exception(RECEIVABLE_DELETE_FAIL);
189 189 }
190 190  
... ... @@ -210,7 +210,7 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
210 210  
211 211 // 2. 创建回款审批流程实例
212 212 String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()
213   - .setProcessDefinitionKey(RECEIVABLE_APPROVE).setBusinessKey(String.valueOf(id)));
  213 + .setProcessDefinitionKey(BPM_PROCESS_DEFINITION_KEY).setBusinessKey(String.valueOf(id)));
214 214  
215 215 // 3. 更新回款工作流编号
216 216 receivableMapper.updateById(new CrmReceivableDO().setId(id).setProcessInstanceId(processInstanceId)
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/listener/CrmReceivableResultListener.java
... ... @@ -20,7 +20,7 @@ public class CrmReceivableResultListener extends BpmProcessInstanceResultEventLi
20 20  
21 21 @Override
22 22 public String getProcessDefinitionKey() {
23   - return CrmReceivableServiceImpl.RECEIVABLE_APPROVE;
  23 + return CrmReceivableServiceImpl.BPM_PROCESS_DEFINITION_KEY;
24 24 }
25 25  
26 26 @Override
... ...