diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java index 5a7809c02..65bdc1b89 100644 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java @@ -95,7 +95,6 @@ public interface LogRecordConstants { String CRM_BUSINESS_FOLLOW_UP_SUCCESS = "商机跟进【{{#businessName}}】"; String CRM_BUSINESS_UPDATE_STATUS_SUB_TYPE = "更新商机状态"; String CRM_BUSINESS_UPDATE_STATUS_SUCCESS = "更新了商机【{{#businessName}}】的状态从【{{#oldStatusName}}】变更为了【{{#newStatusName}}】"; -// String CRM_BUSINESS_UPDATE_STATUS_SUCCESS = "阿巴阿巴"; // ======================= CRM_CONTRACT 合同 ======================= @@ -110,6 +109,8 @@ public interface LogRecordConstants { String CRM_CONTRACT_TRANSFER_SUCCESS = "将合同【{{#contract.name}}】的负责人从【{getAdminUserById{#contract.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; String CRM_CONTRACT_SUBMIT_SUB_TYPE = "提交合同审批"; String CRM_CONTRACT_SUBMIT_SUCCESS = "提交合同【{{#contractName}}】审批成功"; + String CRM_CONTRACT_FOLLOW_UP_SUB_TYPE = "合同跟进"; + String CRM_CONTRACT_FOLLOW_UP_SUCCESS = "合同跟进【{{#contractName}}】"; // ======================= CRM_PRODUCT 产品 ======================= diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java index 7603f3c3b..ec1b35db4 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java @@ -135,7 +135,6 @@ public class CrmBusinessController { return success(BeanUtils.toBean(businessService.getBusinessList(ids, getLoginUserId()), CrmBusinessRespVO.class)); } - // TODO 芋艿:处理下 @GetMapping("/simple-all-list") @Operation(summary = "获得联系人的精简列表") @PreAuthorize("@ss.hasPermission('crm:contact:query')") @@ -144,7 +143,8 @@ public class CrmBusinessController { reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页 PageResult pageResult = businessService.getBusinessPage(reqVO, getLoginUserId()); return success(convertList(pageResult.getList(), business -> // 只返回 id、name 字段 - new CrmBusinessRespVO().setId(business.getId()).setName(business.getName()))); + new CrmBusinessRespVO().setId(business.getId()).setName(business.getName()) + .setCustomerId(business.getCustomerId()))); } @GetMapping("/page") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java index bbea613c8..49cdcb80b 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java @@ -130,7 +130,7 @@ public class CrmBusinessRespVO { @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") private BigDecimal productPrice; - @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + @Schema(description = "商机价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") private BigDecimal businessPrice; @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java index 8b0c53d21..a9ebaae05 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java @@ -53,7 +53,7 @@ public class CrmBusinessSaveReqVO { @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime dealTime; - @Schema(description = "整单折扣") + @Schema(description = "整单折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "55.00") @DiffLogField(name = "整单折扣") @NotNull(message = "整单折扣不能为空") private BigDecimal discountPercent; @@ -82,8 +82,8 @@ public class CrmBusinessSaveReqVO { @NotNull(message = "产品单价不能为空") private BigDecimal productPrice; - @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") - @NotNull(message = "合同价格不能为空") + @Schema(description = "商机价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + @NotNull(message = "商机价格不能为空") private BigDecimal businessPrice; @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java index 4d9385199..6c27fbb01 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java @@ -120,7 +120,8 @@ public class CrmContactController { public CommonResult> getSimpleContactList() { List list = contactService.getContactList(getLoginUserId()); return success(convertList(list, contact -> // 只返回 id、name 字段 - new CrmContactRespVO().setId(contact.getId()).setName(contact.getName()))); + new CrmContactRespVO().setId(contact.getId()).setName(contact.getName()) + .setCustomerId(contact.getCustomerId()))); } @GetMapping("/page") 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 d691a1701..147c598d6 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 @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; @@ -12,7 +13,6 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageR import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractRespVO; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; -import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; @@ -24,6 +24,8 @@ import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; import cn.iocoder.yudao.module.crm.service.product.CrmProductService; +import cn.iocoder.yudao.module.system.api.dept.DeptApi; +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import io.swagger.v3.oas.annotations.Operation; @@ -44,6 +46,7 @@ import java.util.stream.Stream; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import static java.util.Collections.singletonList; @@ -64,8 +67,11 @@ public class CrmContractController { private CrmBusinessService businessService; @Resource private CrmProductService productService; + @Resource private AdminUserApi adminUserApi; + @Resource + private DeptApi deptApi; @PostMapping("/create") @Operation(summary = "创建合同") @@ -96,15 +102,24 @@ public class CrmContractController { @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('crm:contract:query')") public CommonResult getContract(@RequestParam("id") Long id) { - // 1. 查询合同 CrmContractDO contract = contractService.getContract(id); - if (contract == null) { - return success(null); - } + return success(buildContractDetail(contract)); + } - // 2. 拼接合同信息 - List respVOList = buildContractDetailList(singletonList(contract)); - return success(respVOList.get(0)); + private CrmContractRespVO buildContractDetail(CrmContractDO contract) { + if (contract == null) { + return null; + } + CrmContractRespVO contractVO = buildContractDetailList(singletonList(contract)).get(0); + // 拼接产品项 + List businessProducts = contractService.getContractProductListByContractId(contractVO.getId()); + Map productMap = productService.getProductMap( + convertSet(businessProducts, CrmContractProductDO::getProductId)); + contractVO.setProducts(BeanUtils.toBean(businessProducts, CrmContractRespVO.Product.class, businessProductVO -> + MapUtils.findAndThen(productMap, businessProductVO.getProductId(), + product -> businessProductVO.setProductName(product.getName()) + .setProductNo(product.getNo()).setProductUnit(product.getUnit())))); + return contractVO; } @GetMapping("/page") @@ -161,27 +176,35 @@ public class CrmContractController { if (CollUtil.isEmpty(contractList)) { return Collections.emptyList(); } - // 1. 获取客户列表 - List customerList = customerService.getCustomerList( + // 1.1 获取客户列表 + Map customerMap = customerService.getCustomerMap( convertSet(contractList, CrmContractDO::getCustomerId)); - // 2. 获取创建人、负责人列表 + // 1.2 获取创建人、负责人列表 Map userMap = adminUserApi.getUserMap(convertListByFlatMap(contractList, contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); - // 3. 获取联系人 + Map deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); + // 1.3 获取联系人 Map contactMap = convertMap(contactService.getContactList(convertSet(contractList, - CrmContractDO::getContactId)), CrmContactDO::getId); - // 4. 获取商机 + CrmContractDO::getSignContactId)), CrmContactDO::getId); + // 1.4 获取商机 Map businessMap = convertMap(businessService.getBusinessList(convertSet(contractList, CrmContractDO::getBusinessId)), CrmBusinessDO::getId); - // 5. 获取合同关联的商品 - Map contractProductMap = null; - List productList = null; - if (contractList.size() == 1) { - List contractProductList = contractService.getContractProductListByContractId(contractList.get(0).getId()); - contractProductMap = convertMap(contractProductList, CrmContractProductDO::getProductId); - productList = productService.getProductList(convertSet(contractProductList, CrmContractProductDO::getProductId)); - } - return CrmContractConvert.INSTANCE.convertList(contractList, userMap, customerList, contactMap, businessMap, contractProductMap, productList); + // 2. 拼接数据 + return BeanUtils.toBean(contractList, CrmContractRespVO.class, contractVO -> { + // 2.1 设置客户信息 + findAndThen(customerMap, contractVO.getCustomerId(), customer -> contractVO.setCustomerName(customer.getName())); + // 2.2 设置用户信息 + findAndThen(userMap, Long.parseLong(contractVO.getCreator()), user -> contractVO.setCreatorName(user.getNickname())); + MapUtils.findAndThen(userMap, contractVO.getOwnerUserId(), user -> { + contractVO.setOwnerUserName(user.getNickname()); + MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> contractVO.setOwnerUserDeptName(dept.getName())); + }); + findAndThen(userMap, contractVO.getSignUserId(), user -> contractVO.setSignUserName(user.getNickname())); + // 2.3 设置联系人信息 + findAndThen(contactMap, contractVO.getSignContactId(), contact -> contractVO.setSignContactName(contact.getName())); + // 2.4 设置商机信息 + findAndThen(businessMap, contractVO.getBusinessId(), business -> contractVO.setBusinessName(business.getName())); + }); } @GetMapping("/check-contract-count") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractRespVO.java index 554e285dd..f32549e77 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractRespVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractRespVO.java @@ -6,13 +6,11 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.format.annotation.DateTimeFormat; +import java.math.BigDecimal; 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; - @Schema(description = "管理后台 - CRM 合同 Response VO") @Data @ExcelIgnoreUnannotated @@ -26,6 +24,10 @@ public class CrmContractRespVO { @ExcelProperty("合同名称") private String name; + @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20230101") + @ExcelProperty("合同编号") + private String no; + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336") @ExcelProperty("客户编号") private Long customerId; @@ -40,72 +42,70 @@ public class CrmContractRespVO { @ExcelProperty("商机名称") private String businessName; + @Schema(description = "最后跟进时间") + @ExcelProperty("最后跟进时间") + private LocalDateTime contactLastTime; + + @Schema(description = "负责人的用户编号", example = "25682") + @ExcelProperty("负责人的用户编号") + private Long ownerUserId; + @Schema(description = "负责人名字", example = "25682") + @ExcelProperty("负责人名字") + private String ownerUserName; + @Schema(description = "负责人部门") + @ExcelProperty("负责人部门") + private String ownerUserDeptName; + @Schema(description = "工作流编号", example = "1043") @ExcelProperty("工作流编号") private Long processInstanceId; + @Schema(description = "审批状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + @ExcelProperty("审批状态") + private Integer auditStatus; + @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("下单日期") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime orderDate; - @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17144") - @ExcelProperty("负责人的用户编号") - private Long ownerUserId; - - // TODO @芋艿:未来应该支持自动生成; - @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20230101") - @ExcelProperty("合同编号") - private String no; - @Schema(description = "开始时间") @ExcelProperty("开始时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime startTime; @Schema(description = "结束时间") @ExcelProperty("结束时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endTime; - @Schema(description = "合同金额", example = "5617") - @ExcelProperty("合同金额") - private Integer price; - - @Schema(description = "整单折扣") - @ExcelProperty("整单折扣") - private Integer discountPercent; - @Schema(description = "产品总金额", example = "19510") @ExcelProperty("产品总金额") - private Integer productPrice; + private BigDecimal totalProductPrice; - @Schema(description = "联系人编号", example = "18546") - @ExcelProperty("联系人编号") - private Long contactId; - @Schema(description = "联系人编号", example = "18546") - @ExcelProperty("联系人编号") - private String contactName; + @Schema(description = "整单折扣") + @ExcelProperty("整单折扣") + private BigDecimal discountPercent; + + @Schema(description = "合同金额", example = "5617") + @ExcelProperty("合同金额") + private BigDecimal totalPrice; + + @Schema(description = "客户签约人编号", example = "18546") + private Long signContactId; + @Schema(description = "客户签约人", example = "小豆") + @ExcelProperty("客户签约人") + private String signContactName; @Schema(description = "公司签约人", example = "14036") - @ExcelProperty("公司签约人") private Long signUserId; - @Schema(description = "公司签约人", example = "14036") + @Schema(description = "公司签约人", example = "小明") @ExcelProperty("公司签约人") private String signUserName; - @Schema(description = "最后跟进时间") - @ExcelProperty("最后跟进时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime contactLastTime; - @Schema(description = "备注", example = "你猜") @ExcelProperty("备注") private String remark; @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("创建时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime createTime; @Schema(description = "创建人", example = "25682") @@ -118,46 +118,40 @@ public class CrmContractRespVO { @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("更新时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime updateTime; - @Schema(description = "负责人", example = "test") - @ExcelProperty("负责人") - private String ownerUserName; - - @Schema(description = "审批状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") - @ExcelProperty("审批状态") - private Integer auditStatus; - @Schema(description = "产品列表") - private List items; + private List products; @Schema(description = "产品列表") @Data @NoArgsConstructor @AllArgsConstructor - public static class Item { + public static class Product { - @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529") + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888") private Long id; - @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是产品") - private String name; + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529") + private Long productId; + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") + private String productName; + @Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529") + private String productNo; + @Schema(description = "产品单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") + private Integer productUnit; - @Schema(description = "产品编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "N881") - private String no; + @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + private BigDecimal productPrice; - @Schema(description = "单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") - private Integer unit; + @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + private BigDecimal contractPrice; - @Schema(description = "价格,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") - private Integer price; + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") + private BigDecimal count; - @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20") - private Integer count; - - @Schema(description = "产品折扣", example = "99") - private Integer discountPercent; + @Schema(description = "总计价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + private BigDecimal totalPrice; } 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 20b20580e..322127f42 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 @@ -12,6 +12,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; +import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; @@ -38,22 +39,16 @@ public class CrmContractSaveReqVO { @DiffLogField(name = "商机", function = CrmBusinessParseFunction.NAME) private Long businessId; - @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED) - @DiffLogField(name = "下单日期") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @NotNull(message = "下单日期不能为空") - private LocalDateTime orderDate; - @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17144") @DiffLogField(name = "负责人", function = SysAdminUserParseFunction.NAME) @NotNull(message = "负责人不能为空") private Long ownerUserId; - // TODO @芋艿:未来应该支持自动生成; - @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20230101") - @DiffLogField(name = "合同编号") - @NotNull(message = "合同编号不能为空") - private String no; + @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED) + @DiffLogField(name = "下单日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @NotNull(message = "下单日期不能为空") + private LocalDateTime orderDate; @Schema(description = "开始时间") @DiffLogField(name = "开始时间") @@ -65,21 +60,18 @@ public class CrmContractSaveReqVO { @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endTime; + @Schema(description = "整单折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "55.00") + @DiffLogField(name = "整单折扣") + @NotNull(message = "整单折扣不能为空") + private BigDecimal discountPercent; + @Schema(description = "合同金额", example = "5617") @DiffLogField(name = "合同金额") - private Integer price; + private BigDecimal totalPrice; - @Schema(description = "整单折扣") - @DiffLogField(name = "整单折扣") - private Integer discountPercent; - - @Schema(description = "产品总金额", example = "19510") - @DiffLogField(name = "产品总金额") - private Integer productPrice; - - @Schema(description = "联系人编号", example = "18546") - @DiffLogField(name = "联系人", function = CrmContactParseFunction.NAME) - private Long contactId; + @Schema(description = "客户签约人编号", example = "18546") + @DiffLogField(name = "客户签约人", function = CrmContactParseFunction.NAME) + private Long signContactId; @Schema(description = "公司签约人", example = "14036") @DiffLogField(name = "公司签约人", function = SysAdminUserParseFunction.NAME) @@ -89,27 +81,31 @@ public class CrmContractSaveReqVO { @DiffLogField(name = "备注") private String remark; - @Schema(description = "产品列表") - private List productItems; + private List products; @Schema(description = "产品列表") @Data @NoArgsConstructor @AllArgsConstructor - public static class CrmContractProductItem { + public static class Product { - @Schema(description = "产品编号", example = "20529") + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529") @NotNull(message = "产品编号不能为空") - private Long id; + private Long productId; + + @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + @NotNull(message = "产品单价不能为空") + private BigDecimal productPrice; + + @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + @NotNull(message = "合同价格不能为空") + private BigDecimal contractPrice; @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") @NotNull(message = "产品数量不能为空") private Integer count; - @Schema(description = "产品折扣") - private Integer discountPercent; - } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java deleted file mode 100644 index 0b816f37a..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java +++ /dev/null @@ -1,70 +0,0 @@ -package cn.iocoder.yudao.module.crm.convert.contract; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractRespVO; -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; -import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; - -/** - * 合同 Convert - * - * @author dhb52 - */ -@Mapper -public interface CrmContractConvert { - - CrmContractConvert INSTANCE = Mappers.getMapper(CrmContractConvert.class); - - @Mapping(target = "bizId", source = "reqVO.id") - CrmPermissionTransferReqBO convert(CrmContractTransferReqVO reqVO, Long userId); - - default List convertList(List contractList, Map userMap, - List customerList, Map contactMap, - Map businessMap, Map contractProductMap, - List productList) { - List respVOList = BeanUtils.toBean(contractList, CrmContractRespVO.class); - // 拼接关联字段 - Map customerMap = convertMap(customerList, CrmCustomerDO::getId); - respVOList.forEach(contract -> { - findAndThen(userMap, contract.getOwnerUserId(), user -> contract.setOwnerUserName(user.getNickname())); - findAndThen(userMap, Long.parseLong(contract.getCreator()), user -> contract.setCreatorName(user.getNickname())); - findAndThen(userMap, contract.getSignUserId(), user -> contract.setSignUserName(user.getNickname())); - findAndThen(customerMap, contract.getCustomerId(), customer -> contract.setCustomerName(customer.getName())); - findAndThen(contactMap, contract.getContactId(), contact -> contract.setContactName(contact.getName())); - findAndThen(businessMap, contract.getBusinessId(), business -> contract.setBusinessName(business.getName())); - }); - if (CollUtil.isNotEmpty(respVOList) && respVOList.size() == 1) { - setContractRespVOProductItems(respVOList.get(0), contractProductMap, productList); - } - return respVOList; - } - - default void setContractRespVOProductItems(CrmContractRespVO respVO, Map contractProductMap, - List productList) { - respVO.setItems(CollectionUtils.convertList(productList, product -> { - CrmContractRespVO.Item productItemRespVO = BeanUtils.toBean(product, CrmContractRespVO.Item.class); - findAndThen(contractProductMap, product.getId(), contractProduct -> - productItemRespVO.setCount(contractProduct.getCount()).setDiscountPercent(contractProduct.getDiscountPercent())); - return productItemRespVO; - })); - } - -} 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 16990dcc5..2f66fc34d 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 @@ -50,7 +50,7 @@ public class CrmBusinessProductDO extends BaseDO { */ private BigDecimal productPrice; /** - * 合同价格, 单位:元 + * 商机价格, 单位:元 */ private BigDecimal businessPrice; /** 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 0c01a3394..89f4fd98a 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 @@ -10,9 +10,9 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; +import java.math.BigDecimal; import java.time.LocalDateTime; -// TODO 芋艿:实体的梳理 /** * CRM 合同 DO * @@ -33,14 +33,14 @@ public class CrmContractDO extends BaseDO { */ @TableId private Long id; - /** - * 合同编号 - */ - private String no; /** * 合同名称 */ private String name; + /** + * 合同编号 + */ + private String no; /** * 客户编号 * @@ -48,17 +48,37 @@ public class CrmContractDO extends BaseDO { */ private Long customerId; /** - * 商机编号 + * 商机编号,非必须 * * 关联 {@link CrmBusinessDO#getId()} */ private Long businessId; + + /** + * 最后跟进时间 + */ + private LocalDateTime contactLastTime; + + /** + * 负责人的用户编号 + * + * 关联 AdminUserDO 的 id 字段 + */ + private Long ownerUserId; + /** * 工作流编号 * * 关联 ProcessInstance 的 id 属性 */ private String processInstanceId; + /** + * 审批状态 + * + * 枚举 {@link CrmAuditStatusEnum} + */ + private Integer auditStatus; + /** * 下单日期 */ @@ -72,50 +92,32 @@ public class CrmContractDO extends BaseDO { */ private LocalDateTime endTime; /** - * 合同金额,单位:分 + * 产品总金额,单位:元 */ - private Integer price; + private BigDecimal totalProductPrice; /** * 整单折扣 */ - private Integer discountPercent; + private BigDecimal discountPercent; /** - * 产品总金额,单位:分 + * 合同总金额,单位:分 */ - private Integer productPrice; + private BigDecimal totalPrice; /** - * 客户签约人 + * 客户签约人,非必须 * * 关联 {@link CrmContactDO#getId()} */ - private Long contactId; + private Long signContactId; /** - * 公司签约人 + * 公司签约人,非必须 * * 关联 AdminUserDO 的 id 字段 */ private Long signUserId; - /** - * 最后跟进时间 - */ - private LocalDateTime contactLastTime; /** * 备注 */ private String remark; - /** - * 负责人的用户编号 - * - * 关联 AdminUserDO 的 id 字段 - */ - private Long ownerUserId; - - /** - * 审批状态 - * - * 枚举 {@link CrmAuditStatusEnum} - */ - private Integer auditStatus; - } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractProductDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractProductDO.java index d0489e490..ec50e50be 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractProductDO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractProductDO.java @@ -7,8 +7,10 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; +import java.math.BigDecimal; + /** - * 合同产品关联表 DO + * CRM 合同产品关联表 DO * * @author HUIHUI */ @@ -27,12 +29,6 @@ public class CrmContractProductDO extends BaseDO { */ @TableId private Long id; - /** - * 产品编号 - * - * 关联 {@link CrmProductDO#getId()} - */ - private Long productId; /** * 合同编号 * @@ -40,27 +36,28 @@ public class CrmContractProductDO extends BaseDO { */ private Long contractId; /** - * 产品单价 + * 产品编号 + * + * 关联 {@link CrmProductDO#getId()} */ - private Integer price; + private Long productId; /** - * 销售价格, 单位:分 + * 产品单价,单位:元 */ - private Integer salesPrice; + private BigDecimal productPrice; + /** + * 合同价格, 单位:分 + */ + private BigDecimal contractPrice; /** * 数量 */ - private Integer count; + private BigDecimal count; /** - * 折扣 + * 总计价格,单位:元 + * + * totalPrice = businessPrice * count */ - private Integer discountPercent; - /** - * 总计价格(折扣后价格) - * = {@link #price} - * * {@link #count} - * * ({@link #discountPercent / 100}) - */ - private Integer totalPrice; + private BigDecimal totalPrice; } 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 690bc5302..d1556be3e 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 @@ -81,7 +81,7 @@ public interface CrmContractMapper extends BaseMapperX { } default Long selectCountByContactId(Long contactId) { - return selectCount(CrmContractDO::getContactId, contactId); + return selectCount(CrmContractDO::getSignContactId, contactId); } default Long selectCountByBusinessId(Long businessId) { diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java index bcb7f0903..63ef761a7 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java @@ -11,7 +11,6 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.enums.business.CrmBusinessEndStatusEnum; -import cn.iocoder.yudao.module.crm.service.business.bo.CrmBusinessUpdateProductReqBO; import jakarta.validation.Valid; import java.time.LocalDateTime; @@ -80,13 +79,6 @@ public interface CrmBusinessService { */ void transferBusiness(CrmBusinessTransferReqVO reqVO, Long userId); - /** - * 更新商机关联商品 - * - * @param updateProductReqBO 请求 - */ - void updateBusinessProduct(CrmBusinessUpdateProductReqBO updateProductReqBO); - /** * 获得商机 * @@ -95,6 +87,14 @@ public interface CrmBusinessService { */ CrmBusinessDO getBusiness(Long id); + /** + * 校验商机是否有效 + * + * @param id 编号 + * @return 商机 + */ + CrmBusinessDO validateBusiness(Long id); + /** * 获得商机列表 * diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java index a15fe8068..11b6193fc 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java @@ -19,7 +19,6 @@ import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessProductMapper; 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.bo.CrmBusinessUpdateProductReqBO; import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService; import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; @@ -91,10 +90,10 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { // 1.1 校验产品项的有效性 List businessProducts = validateBusinessProducts(createReqVO.getProducts()); // 1.2 校验关联字段 - validateBusinessForCreate(createReqVO); + validateRelationDataExists(createReqVO); // 2.1 插入商机 - CrmBusinessDO business = BeanUtils.toBean(createReqVO, CrmBusinessDO.class).setOwnerUserId(userId); + CrmBusinessDO business = BeanUtils.toBean(createReqVO, CrmBusinessDO.class); business.setStatusId(businessStatusService.getBusinessStatusListByTypeId(createReqVO.getStatusTypeId()).get(0).getId()); // 默认状态 calculateTotalPrice(business, businessProducts); businessMapper.insert(business); @@ -105,9 +104,9 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { } // 3. 创建数据权限 - // 设置当前操作的人为负责人 - permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()) - .setBizId(business.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); + permissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(business.getOwnerUserId()) + .setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()).setBizId(business.getId()) + .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 4. 在联系人的详情页,如果直接【新建商机】,则需要关联下 if (createReqVO.getContactId() != null) { @@ -132,7 +131,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { // 1.2 校验产品项的有效性 List businessProducts = validateBusinessProducts(updateReqVO.getProducts()); // 1.3 校验关联字段 - validateBusinessForCreate(updateReqVO); + validateRelationDataExists(updateReqVO); // 2.1 更新商机 CrmBusinessDO updateObj = BeanUtils.toBean(updateReqVO, CrmBusinessDO.class); @@ -141,7 +140,6 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { // 2.2 更新商机关联商品 updateBusinessProduct(updateObj.getId(), businessProducts); - // TODO @商机待定:如果状态发生变化,插入商机状态变更记录表 // 3. 记录操作日志上下文 LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldBusiness, CrmBusinessSaveReqVO.class)); LogRecordContext.putVariable("businessName", oldBusiness.getName()); @@ -185,7 +183,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { } } - private void validateBusinessForCreate(CrmBusinessSaveReqVO saveReqVO) { + private void validateRelationDataExists(CrmBusinessSaveReqVO saveReqVO) { // 校验商机状态 if (saveReqVO.getStatusTypeId() != null) { businessStatusService.validateBusinessStatusType(saveReqVO.getStatusTypeId()); @@ -208,9 +206,8 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { // 1. 校验产品存在 productService.validProductList(convertSet(list, CrmBusinessSaveReqVO.Product::getProductId)); // 2. 转化为 CrmBusinessProductDO 列表 - return convertList(list, o -> BeanUtils.toBean(o, CrmBusinessProductDO.class, item -> { - item.setTotalPrice(MoneyUtils.priceMultiply(item.getBusinessPrice(), item.getCount())); - })); + return convertList(list, o -> BeanUtils.toBean(o, CrmBusinessProductDO.class, + item -> item.setTotalPrice(MoneyUtils.priceMultiply(item.getBusinessPrice(), item.getCount())))); } private void calculateTotalPrice(CrmBusinessDO business, List businessProducts) { @@ -219,7 +216,6 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { business.setTotalPrice(business.getTotalProductPrice().subtract(discountPrice)); } - @Override @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_UPDATE_STATUS_SUB_TYPE, bizNo = "{{#reqVO.id}}", success = CRM_BUSINESS_UPDATE_STATUS_SUCCESS) @@ -264,7 +260,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { // 1.2 校验是否关联合同 validateContractExists(id); - // 删除 + // 删除商机 businessMapper.deleteById(id); // 删除数据权限 permissionService.deletePermission(CrmBizTypeEnum.CRM_BUSINESS.getType(), id); @@ -313,14 +309,6 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { LogRecordContext.putVariable("business", business); } - @Override - public void updateBusinessProduct(CrmBusinessUpdateProductReqBO updateProductReqBO) { - // 更新商机关联商品 TODO yunai -// List productList = buildBusinessProductList( -// BeanUtils.toBean(updateProductReqBO.getProductItems(), CrmBusinessSaveReqVO.Product.class), updateProductReqBO.getId()); -// updateBusinessProduct(productList, updateProductReqBO.getId()); - } - //======================= 查询相关 ======================= @Override @@ -329,6 +317,11 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { return businessMapper.selectById(id); } + @Override + public CrmBusinessDO validateBusiness(Long id) { + return validateBusinessExists(id); + } + @Override public List getBusinessList(Collection ids, Long userId) { if (CollUtil.isEmpty(ids)) { diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateProductReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateProductReqBO.java deleted file mode 100644 index 0c8d7efbf..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateProductReqBO.java +++ /dev/null @@ -1,49 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.business.bo; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; - -/** - * 更新商机商品 Update Req BO - * - * @author HUIHUI - */ -@Data -public class CrmBusinessUpdateProductReqBO { - - /** - * 商机编号 - */ - @NotNull(message = "商机编号不能为空") - private Long id; - - // TODO @芋艿:再想想 - @NotEmpty(message = "产品列表不能为空") - private List items; - - @Schema(description = "产品列表") - @Data - @NoArgsConstructor - @AllArgsConstructor - public static class Item { - - @Schema(description = "产品编号", example = "20529") - @NotNull(message = "产品编号不能为空") - private Long id; - - @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") - @NotNull(message = "产品数量不能为空") - private Integer count; - - @Schema(description = "产品折扣") - private Integer discountPercent; - - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java index 7251eee26..70ebeb44d 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java @@ -19,7 +19,6 @@ import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; import cn.iocoder.yudao.module.crm.service.customer.bo.CrmCustomerCreateReqBO; import cn.iocoder.yudao.module.crm.service.followup.CrmFollowUpRecordService; import cn.iocoder.yudao.module.crm.service.followup.bo.CrmFollowUpCreateReqBO; -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; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; @@ -133,7 +132,6 @@ public class CrmClueServiceImpl implements CrmClueService { .setContactLastTime(LocalDateTime.now()).setContactLastContent(contactLastContent)); // 3. 记录操作日志上下文 - LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldClue, CrmUpdateFollowUpReqBO.class)); LogRecordContext.putVariable("clueName", oldClue.getName()); } 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 300ca86a2..e9f4e6f59 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 @@ -8,9 +8,9 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTrans import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; -import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; import jakarta.validation.Valid; +import java.time.LocalDateTime; import java.util.Collection; import java.util.List; @@ -55,9 +55,11 @@ public interface CrmContractService { /** * 更新合同相关的更进信息 * - * @param contractUpdateFollowUpReqBO 信息 + * @param id 合同编号 + * @param contactNextTime 下次联系时间 + * @param contactLastContent 最后联系内容 */ - void updateContractFollowUp(CrmUpdateFollowUpReqBO contractUpdateFollowUpReqBO); + void updateContractFollowUp(Long id, LocalDateTime contactNextTime, String contactLastContent); /** * 发起合同审批流程 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 211cec690..d89b90351 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 @@ -11,13 +11,12 @@ import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO; import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; 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; -import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper; import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractProductMapper; import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; @@ -25,11 +24,11 @@ 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.CrmBusinessService; -import cn.iocoder.yudao.module.crm.service.business.bo.CrmBusinessUpdateProductReqBO; +import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; -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; +import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; import cn.iocoder.yudao.module.crm.service.product.CrmProductService; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import com.mzt.logapi.context.LogRecordContext; @@ -40,17 +39,15 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; +import java.math.BigDecimal; +import java.time.LocalDateTime; import java.util.Collection; import java.util.List; -import java.util.Map; -import java.util.Set; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; -import static cn.iocoder.yudao.module.crm.util.CrmAuditStatusUtils.convertAuditStatus; -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS; /** * CRM 合同 Service 实现类 @@ -79,6 +76,8 @@ public class CrmContractServiceImpl implements CrmContractService { private CrmCustomerService customerService; @Resource private CrmBusinessService businessService; + @Resource + private CrmContactService contactService; @Resource private AdminUserApi adminUserApi; @@ -90,30 +89,29 @@ public class CrmContractServiceImpl implements CrmContractService { @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) { + // 1.1 校验产品项的有效性 + List contractProducts = validateContractProducts(createReqVO.getProducts()); + // 1.2 校验关联字段 validateRelationDataExists(createReqVO); - // 1.1 插入合同 - CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null); + // TODO 芋艿:生成 no + + // 2.1 插入合同 + CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class); + contract.setNo(System.currentTimeMillis() + ""); // TODO + calculateTotalPrice(contract, contractProducts); contractMapper.insert(contract); - // 1.2 插入合同关联商品 - if (CollUtil.isNotEmpty(createReqVO.getProductItems())) { // 如果有的话 - List productList = convertContractProductList(createReqVO, contract.getId()); - contractProductMapper.insertBatch(productList); - // 更新合同商品总金额 - contractMapper.updateById(new CrmContractDO().setId(contract.getId()).setProductPrice( - getSumValue(productList, CrmContractProductDO::getTotalPrice, Integer::sum))); - // 如果存在合同关联了商机则更新商机商品关联 - if (contract.getBusinessId() != null) { - businessService.updateBusinessProduct(new CrmBusinessUpdateProductReqBO().setId(contract.getBusinessId()) - .setItems(BeanUtils.toBean(createReqVO.getProductItems(), CrmBusinessUpdateProductReqBO.Item.class))); - } + // 2.2 插入合同关联商品 + if (CollUtil.isNotEmpty(contractProducts)) { + contractProducts.forEach(item -> item.setContractId(contract.getId())); + contractProductMapper.insertBatch(contractProducts); } - // 2. 创建数据权限 - crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId) + // 3. 创建数据权限 + crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(contract.getOwnerUserId()) .setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()).setBizId(contract.getId()) .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); - // 3. 记录操作日志上下文 + // 4. 记录操作日志上下文 LogRecordContext.putVariable("contract", contract); return contract.getId(); } @@ -125,6 +123,7 @@ public class CrmContractServiceImpl implements CrmContractService { @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) public void updateContract(CrmContractSaveReqVO updateReqVO) { Assert.notNull(updateReqVO.getId(), "合同编号不能为空"); + updateReqVO.setOwnerUserId(null); // 不允许更新的字段 // 1.1 校验存在 CrmContractDO contract = validateContractExists(updateReqVO.getId()); // 1.2 只有草稿、审批中,可以编辑; @@ -132,63 +131,41 @@ public class CrmContractServiceImpl implements CrmContractService { CrmAuditStatusEnum.PROCESS.getStatus())) { throw exception(CONTRACT_UPDATE_FAIL_EDITING_PROHIBITED); } + // 1.3 校验产品项的有效性 + List contractProducts = validateContractProducts(updateReqVO.getProducts()); + // 1.4 校验关联字段 validateRelationDataExists(updateReqVO); // 2.1 更新合同 CrmContractDO updateObj = BeanUtils.toBean(updateReqVO, CrmContractDO.class); + calculateTotalPrice(updateObj, contractProducts); contractMapper.updateById(updateObj); // 2.2 更新合同关联商品 - updateContractProduct(updateReqVO, updateObj.getId()); + updateContractProduct(updateReqVO.getId(), contractProducts); // 3. 记录操作日志上下文 LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(contract, CrmContractSaveReqVO.class)); LogRecordContext.putVariable("contractName", contract.getName()); } - private void updateContractProduct(CrmContractSaveReqVO updateReqVO, Long contractId) { - if (CollUtil.isEmpty(updateReqVO.getProductItems())) { - return; - } - List newProductList = convertContractProductList(updateReqVO, contractId); - List oldProductList = contractProductMapper.selectListByContractId(contractId); - List> diffList = diffList(oldProductList, newProductList, (oldObj, newObj) -> { - boolean match = ObjUtil.equal(oldObj.getProductId(), newObj.getProductId()); - if (match) { - newObj.setId(oldObj.getId()); // 设置一下老的编号更新时需要使用 - } - return match; - }); + private void updateContractProduct(Long id, List newList) { + List oldList = contractProductMapper.selectListByContractId(id); + List> diffList = diffList(oldList, newList, // id 不同,就认为是不同的记录 + (oldVal, newVal) -> oldVal.getId().equals(newVal.getId())); if (CollUtil.isNotEmpty(diffList.get(0))) { + diffList.get(0).forEach(o -> o.setContractId(id)); contractProductMapper.insertBatch(diffList.get(0)); } if (CollUtil.isNotEmpty(diffList.get(1))) { contractProductMapper.updateBatch(diffList.get(1)); } if (CollUtil.isNotEmpty(diffList.get(2))) { - contractProductMapper.deleteBatchIds(convertList(diffList.get(2), CrmContractProductDO::getId)); + contractProductMapper.deleteBatchIds(convertSet(diffList.get(2), CrmContractProductDO::getId)); } } // TODO @合同待定:缺一个取消合同的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum - private List convertContractProductList(CrmContractSaveReqVO reqVO, Long contractId) { - // 校验商品存在 - Set productIds = convertSet(reqVO.getProductItems(), CrmContractSaveReqVO.CrmContractProductItem::getId); - List productList = productService.getProductList(productIds); - if (CollUtil.isEmpty(productIds) || productList.size() != productIds.size()) { - throw exception(PRODUCT_NOT_EXISTS); - } - Map productMap = convertMap(productList, CrmProductDO::getId); - return convertList(reqVO.getProductItems(), productItem -> { - CrmProductDO product = productMap.get(productItem.getId()); - return BeanUtils.toBean(product, CrmContractProductDO.class) - .setId(null).setProductId(productItem.getId()).setContractId(contractId) - .setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent()) - // TODO 芋艿:这里临时注释掉 - .setTotalPrice(MoneyUtils.calculator(null, productItem.getCount(), productItem.getDiscountPercent())); - }); - } - /** * 校验关联数据是否存在 * @@ -196,17 +173,38 @@ public class CrmContractServiceImpl implements CrmContractService { */ private void validateRelationDataExists(CrmContractSaveReqVO reqVO) { // 1. 校验客户 - if (reqVO.getCustomerId() != null && customerService.getCustomer(reqVO.getCustomerId()) == null) { - throw exception(CUSTOMER_NOT_EXISTS); + if (reqVO.getCustomerId() != null) { + customerService.validateCustomer(reqVO.getCustomerId()); } // 2. 校验负责人 - if (reqVO.getOwnerUserId() != null && adminUserApi.getUser(reqVO.getOwnerUserId()) == null) { - throw exception(USER_NOT_EXISTS); + if (reqVO.getOwnerUserId() != null) { + adminUserApi.validateUser(reqVO.getOwnerUserId()); } // 3. 如果有关联商机,则需要校验存在 - if (reqVO.getBusinessId() != null && businessService.getBusiness(reqVO.getBusinessId()) == null) { - throw exception(BUSINESS_NOT_EXISTS); + if (reqVO.getBusinessId() != null) { + businessService.validateBusiness(reqVO.getBusinessId()); } + // 4. 校验签约相关字段 + if (reqVO.getSignContactId() != null) { + contactService.validateContact(reqVO.getSignContactId()); + } + if (reqVO.getSignUserId() != null) { + adminUserApi.validateUser(reqVO.getSignUserId()); + } + } + + private List validateContractProducts(List list) { + // 1. 校验产品存在 + productService.validProductList(convertSet(list, CrmContractSaveReqVO.Product::getProductId)); + // 2. 转化为 CrmContractProductDO 列表 + return convertList(list, o -> BeanUtils.toBean(o, CrmContractProductDO.class, + item -> item.setTotalPrice(MoneyUtils.priceMultiply(item.getContractPrice(), item.getCount())))); + } + + private void calculateTotalPrice(CrmContractDO contract, List contractProducts) { + contract.setTotalProductPrice(getSumValue(contractProducts, CrmContractProductDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)); + BigDecimal discountPrice = MoneyUtils.priceMultiplyPercent(contract.getTotalProductPrice(), contract.getDiscountPercent()); + contract.setTotalPrice(contract.getTotalProductPrice().subtract(discountPrice)); } @Override @@ -245,8 +243,8 @@ public class CrmContractServiceImpl implements CrmContractService { CrmContractDO contract = validateContractExists(reqVO.getId()); // 2.1 数据权限转移 - crmPermissionService.transferPermission( - CrmContractConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType())); + crmPermissionService.transferPermission(new CrmPermissionTransferReqBO(userId, CrmBizTypeEnum.CRM_CONTRACT.getType(), + reqVO.getId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel())); // 2.2 设置负责人 contractMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); @@ -255,8 +253,18 @@ public class CrmContractServiceImpl implements CrmContractService { } @Override - public void updateContractFollowUp(CrmUpdateFollowUpReqBO contractUpdateFollowUpReqBO) { - contractMapper.updateById(BeanUtils.toBean(contractUpdateFollowUpReqBO, CrmContractDO.class).setId(contractUpdateFollowUpReqBO.getBizId())); + @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_FOLLOW_UP_SUB_TYPE, bizNo = "{{#id}", + success = CRM_CONTRACT_FOLLOW_UP_SUCCESS) + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.WRITE) + public void updateContractFollowUp(Long id, LocalDateTime contactNextTime, String contactLastContent) { + // 1. 校验存在 + CrmContractDO contract = validateContractExists(id); + + // 2. 更新联系人的跟进信息 + contractMapper.updateById(new CrmContractDO().setId(id).setContactLastTime(LocalDateTime.now())); + + // 3. 记录操作日志上下文 + LogRecordContext.putVariable("contractName", contract.getName()); } @Override @@ -284,12 +292,36 @@ public class CrmContractServiceImpl implements CrmContractService { @Override public void updateContractAuditStatus(BpmResultListenerRespDTO event) { - convertAuditStatus(event); + // 判断下状态是否符合预期 + if (!isEndResult(event.getResult())) { + return; + } + // 状态转换 + if (ObjUtil.equal(event.getResult(), BpmProcessInstanceResultEnum.APPROVE.getResult())) { + event.setResult(CrmAuditStatusEnum.APPROVE.getStatus()); + } + if (ObjUtil.equal(event.getResult(), BpmProcessInstanceResultEnum.REJECT.getResult())) { + event.setResult(CrmAuditStatusEnum.REJECT.getStatus()); + } + if (ObjUtil.equal(event.getResult(), BpmProcessInstanceResultEnum.CANCEL.getResult())) { + event.setResult(CrmAuditStatusEnum.CANCEL.getStatus()); + } // 更新合同状态 contractMapper.updateById(new CrmContractDO().setId(Long.parseLong(event.getBusinessKey())) .setAuditStatus(event.getResult())); } + /** + * 判断该结果是否处于 End 最终结果 + * + * @param result 结果 + * @return 是否 + */ + public static boolean isEndResult(Integer result) { + return ObjectUtils.equalsAny(result, BpmProcessInstanceResultEnum.APPROVE.getResult(), + BpmProcessInstanceResultEnum.REJECT.getResult(), BpmProcessInstanceResultEnum.CANCEL.getResult()); + } + //======================= 查询相关 ======================= @Override diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java index 1f39e4684..ab9c5df5b 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java @@ -17,14 +17,12 @@ import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; import cn.iocoder.yudao.module.crm.service.followup.bo.CrmFollowUpCreateReqBO; -import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import jakarta.annotation.Resource; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import java.time.LocalDateTime; import java.util.Collection; import java.util.List; @@ -71,9 +69,6 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { crmFollowUpRecordMapper.insert(record); // 2. 更新 bizId 对应的记录 - CrmUpdateFollowUpReqBO updateFollowUpReqBO = new CrmUpdateFollowUpReqBO().setBizId(record.getBizId()) - .setContactLastTime(LocalDateTime.now()) - .setContactNextTime(record.getNextTime()).setContactLastContent(record.getContent()); if (ObjUtil.equal(CrmBizTypeEnum.CRM_BUSINESS.getType(), record.getBizType())) { // 更新商机跟进信息 businessService.updateBusinessFollowUp(record.getBizId(), record.getNextTime(), record.getContent()); } @@ -84,7 +79,7 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { contactService.updateContactFollowUp(record.getBizId(), record.getNextTime(), record.getContent()); } if (ObjUtil.equal(CrmBizTypeEnum.CRM_CONTRACT.getType(), record.getBizType())) { // 更新合同跟进信息 - contractService.updateContractFollowUp(updateFollowUpReqBO); + contractService.updateContractFollowUp(record.getBizId(), record.getNextTime(), record.getContent()); } if (ObjUtil.equal(CrmBizTypeEnum.CRM_CUSTOMER.getType(), record.getBizType())) { // 更新客户跟进信息 customerService.updateCustomerFollowUp(record.getBizId(), record.getNextTime(), record.getContent()); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/bo/CrmUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/bo/CrmUpdateFollowUpReqBO.java deleted file mode 100644 index 57f1849eb..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/bo/CrmUpdateFollowUpReqBO.java +++ /dev/null @@ -1,34 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.followup.bo; - -import com.mzt.logapi.starter.annotation.DiffLogField; -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotNull; -import lombok.Data; - -import java.time.LocalDateTime; - -/** - * 跟进信息 Update Req BO - * - * @author HUIHUI - */ -@Data -public class CrmUpdateFollowUpReqBO { - - @Schema(description = "数据编号", example = "3167") - @NotNull(message = "数据编号不能为空") - private Long bizId; - - @Schema(description = "最后跟进时间") - @DiffLogField(name = "最后跟进时间") - private LocalDateTime contactLastTime; - - @Schema(description = "下次联系时间") - @DiffLogField(name = "下次联系时间") - private LocalDateTime contactNextTime; - - @Schema(description = "最后更进内容") - @DiffLogField(name = "最后更进内容") - private String contactLastContent; - -}