From 1cab3c009c516513a2128d37278f3cfcb77d2d8b Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sun, 28 Jan 2024 01:50:27 +0800 Subject: [PATCH] =?UTF-8?q?CRM-=E5=90=88=E5=90=8C=EF=BC=9A=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=8F=91=E8=B5=B7=E5=90=88=E5=90=8C=E5=AE=A1=E6=89=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-module-crm/yudao-module-crm-biz/pom.xml | 5 +++ .../admin/contract/CrmContractController.java | 8 +++++ .../contract/vo/CrmContractSaveReqVO.java | 33 +++++++++++++------ .../business/CrmBusinessProductDO.java | 27 +++++++-------- .../dataobject/contract/CrmContractDO.java | 2 +- .../dal/dataobject/product/CrmProductDO.java | 3 +- .../dal/mysql/contract/CrmContractMapper.java | 4 +-- .../service/contract/CrmContractService.java | 14 ++++++-- .../contract/CrmContractServiceImpl.java | 25 +++++++++++--- 9 files changed, 85 insertions(+), 36 deletions(-) diff --git a/yudao-module-crm/yudao-module-crm-biz/pom.xml b/yudao-module-crm/yudao-module-crm-biz/pom.xml index c54b61c89..b905bf6da 100644 --- a/yudao-module-crm/yudao-module-crm-biz/pom.xml +++ b/yudao-module-crm/yudao-module-crm-biz/pom.xml @@ -27,6 +27,11 @@ yudao-module-crm-api ${revision} + + cn.iocoder.boot + yudao-module-bpm-api + ${revision} + diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java index c2935184f..7f2541ae7 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java @@ -140,4 +140,12 @@ public class CrmContractController { return success(true); } + @PutMapping("/approve") + @Operation(summary = "发起合同审批流程") + @PreAuthorize("@ss.hasPermission('crm:contract:update')") + public CommonResult transfer(@RequestParam("id") Long id) { + contractService.handleApprove(id, getLoginUserId()); + return success(true); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractSaveReqVO.java index e495bbfa5..607aa08f5 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractSaveReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractSaveReqVO.java @@ -7,10 +7,13 @@ import cn.iocoder.yudao.module.crm.framework.operatelog.core.SysAdminUserParseFu import com.mzt.logapi.starter.annotation.DiffLogField; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; +import java.util.List; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; @@ -35,10 +38,6 @@ public class CrmContractSaveReqVO { @DiffLogField(name = "商机", function = CrmBusinessParseFunction.NAME) private Long businessId; - @Schema(description = "工作流编号", example = "1043") - @DiffLogField(name = "工作流编号") - private Long processInstanceId; - @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED) @DiffLogField(name = "下单日期") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @@ -86,16 +85,30 @@ public class CrmContractSaveReqVO { @DiffLogField(name = "公司签约人", function = SysAdminUserParseFunction.NAME) private Long signUserId; - @Schema(description = "最后跟进时间") - @DiffLogField(name = "最后跟进时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime contactLastTime; - @Schema(description = "备注", example = "你猜") @DiffLogField(name = "备注") private String remark; - // TODO @dhb52:增加一个 status 字段:具体有哪些值,你来枚举下;主要页面上有个【草稿】【提交审核】的流程,可以看看。然后要对接工作流,这块也可以看看,不确定的地方问我。 + @Schema(description = "产品列表") + private List productItems; + @Schema(description = "商品属性") + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class CrmContractProductItem { + + @Schema(description = "产品编号", example = "20529") + @NotNull(message = "产品编号不能为空") + private Long id; + + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") + @NotNull(message = "产品数量不能为空") + private Long count; + + @Schema(description = "产品折扣") + private Integer discountPercent; + + } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java index b1275f4c5..83121dbdd 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java @@ -2,13 +2,12 @@ package cn.iocoder.yudao.module.crm.dal.dataobject.business; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; +import cn.iocoder.yudao.module.crm.enums.DictTypeConstants; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; -import java.math.BigDecimal; - /** * 商机产品关联表 DO * @@ -29,14 +28,12 @@ public class CrmBusinessProductDO extends BaseDO { */ @TableId private Long id; - /** * 商机编号 * * 关联 {@link CrmBusinessDO#getId()} */ private Long businessId; - /** * 产品编号 * @@ -50,29 +47,27 @@ public class CrmBusinessProductDO extends BaseDO { private Integer price; /** - * 销售价格 + * 销售价格, 单位:分 */ - private BigDecimal salesPrice; - + private Integer salesPrice; /** * 数量 */ - private BigDecimal count; - - // TODO @lzxhqs:改成 discountPercent + private Integer count; /** * 折扣 */ - private BigDecimal discountPercent; - - // TODO @lzxhqs:改成 totalPrice;总计价格,和现有项目风格一致; + private Integer discountPercent; /** - * 小计(折扣后价格) + * 总计价格(折扣后价格) */ - private BigDecimal totalPrice; + private Integer totalPrice; /** * 单位 + * + * 字典 {@link DictTypeConstants#CRM_PRODUCT_UNIT} */ - private String unit; + private Integer unit; + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractDO.java index bdaff7271..e70e7a3cb 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractDO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractDO.java @@ -45,7 +45,7 @@ public class CrmContractDO extends BaseDO { /** * 工作流编号 */ - private Long processInstanceId; + private String processInstanceId; /** * 下单日期 */ diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/product/CrmProductDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/product/CrmProductDO.java index a4ac3d3d7..6523782dd 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/product/CrmProductDO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/product/CrmProductDO.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.crm.dal.dataobject.product; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.crm.enums.DictTypeConstants; import cn.iocoder.yudao.module.crm.enums.product.CrmProductStatusEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; @@ -38,7 +39,7 @@ public class CrmProductDO extends BaseDO { /** * 单位 * - * 字典 {@link cn.iocoder.yudao.module.crm.enums.DictTypeConstants#CRM_PRODUCT_UNIT} + * 字典 {@link DictTypeConstants#CRM_PRODUCT_UNIT} */ private Integer unit; /** diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java index f4e33dfa0..a3e631201 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java @@ -41,7 +41,7 @@ public interface CrmContractMapper extends BaseMapperX { default PageResult selectPage(CrmContractPageReqVO pageReqVO, Long userId) { MPJLambdaWrapperX mpjLambdaWrapperX = new MPJLambdaWrapperX<>(); // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.appendPermissionCondition(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTACT.getType(), + CrmQueryWrapperUtils.appendPermissionCondition(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTRACT.getType(), CrmContractDO::getId, userId, pageReqVO.getSceneType(), Boolean.FALSE); // 拼接自身的查询条件 mpjLambdaWrapperX.selectAll(CrmContractDO.class) @@ -56,7 +56,7 @@ public interface CrmContractMapper extends BaseMapperX { default List selectBatchIds(Collection ids, Long userId) { MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); // 构建数据权限连表条件 - CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTACT.getType(), ids, userId); + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTRACT.getType(), ids, userId); // 拼接自身的查询条件 query.selectAll(CrmContractDO.class).in(CrmContractDO::getId, ids).orderByDesc(CrmContractDO::getId); return selectJoinList(CrmContractDO.class, query); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java index 6695e4f5d..9847af328 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java @@ -57,6 +57,14 @@ public interface CrmContractService { */ void updateContractFollowUp(CrmUpdateFollowUpReqBO contractUpdateFollowUpReqBO); + /** + * 发起合同审批流程 + * + * @param id 合同编号 + * @param userId 用户编号 + */ + void handleApprove(Long id, Long userId); + /** * 获得合同 * @@ -111,9 +119,11 @@ public interface CrmContractService { Long getContractCountByCustomerId(Long customerId); /** - * 根据商机ID获取关联客户的合同数量 TODO @lzxhqs:1)方法注释,和参数注释之间要有空行;2)中英文之间有空格,更清晰,例如说 商机 ID - * @param businessId 商机ID + * 根据商机ID获取关联客户的合同数量 + * + * @param businessId 商机编号 * @return 数量 */ Long selectCountByBusinessId(Long businessId); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java index 1f1561f9b..5e83eccb0 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java @@ -4,6 +4,8 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; @@ -13,6 +15,7 @@ import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; +import cn.iocoder.yudao.module.crm.service.business.CrmBusinessProductService; import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; @@ -40,28 +43,33 @@ import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; @Validated public class CrmContractServiceImpl implements CrmContractService { + public static final String CONTRACT_APPROVE = "contract-approve"; // 合同审批流程标识 + @Resource private CrmContractMapper contractMapper; @Resource private CrmPermissionService crmPermissionService; + @Resource + private CrmBusinessProductService businessProductService; + + @Resource + private BpmProcessInstanceApi bpmProcessInstanceApi; @Override @Transactional(rollbackFor = Exception.class) @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_CREATE_SUB_TYPE, bizNo = "{{#contract.id}}", success = CRM_CONTRACT_CREATE_SUCCESS) public Long createContract(CrmContractSaveReqVO createReqVO, Long userId) { - createReqVO.setId(null); // TODO @合同待定:插入合同商品;需要搞个 BusinessProductDO // 插入合同 - CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class); + CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null); contractMapper.insert(contract); // 创建数据权限 crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId) .setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()).setBizId(contract.getId()) .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); - // 4. 记录操作日志上下文 LogRecordContext.putVariable("contract", contract); return contract.getId(); @@ -141,6 +149,16 @@ public class CrmContractServiceImpl implements CrmContractService { contractMapper.updateById(BeanUtils.toBean(contractUpdateFollowUpReqBO, CrmContractDO.class).setId(contractUpdateFollowUpReqBO.getBizId())); } + @Override + public void handleApprove(Long id, Long userId) { + // 创建合同审批流程实例 + String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() + .setProcessDefinitionKey(CONTRACT_APPROVE).setBusinessKey(String.valueOf(id))); + + // 更新合同工作流编号 + contractMapper.updateById(new CrmContractDO().setId(id).setProcessInstanceId(processInstanceId)); + } + //======================= 查询相关 ======================= @Override @@ -182,6 +200,5 @@ public class CrmContractServiceImpl implements CrmContractService { public Long selectCountByBusinessId(Long businessId) { return contractMapper.selectCountByBusinessId(businessId); } - // TODO @合同待定:需要新增一个 ContractConfigDO 表,合同配置,重点是到期提醒; }