Commit 9caaa96e5b3678365d11f23b15861070f1d8f259
1 parent
84f3b230
CRM-合同: 新增更新合同商品如果有关联商机的话则更新商机商品
Showing
12 changed files
with
163 additions
and
140 deletions
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java
| @@ -93,6 +93,8 @@ public interface LogRecordConstants { | @@ -93,6 +93,8 @@ public interface LogRecordConstants { | ||
| 93 | String CRM_CONTRACT_DELETE_SUCCESS = "删除了合同【{{#contractName}}】"; | 93 | String CRM_CONTRACT_DELETE_SUCCESS = "删除了合同【{{#contractName}}】"; |
| 94 | String CRM_CONTRACT_TRANSFER_SUB_TYPE = "转移合同"; | 94 | String CRM_CONTRACT_TRANSFER_SUB_TYPE = "转移合同"; |
| 95 | String CRM_CONTRACT_TRANSFER_SUCCESS = "将合同【{{#contract.name}}】的负责人从【{getAdminUserById{#contract.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; | 95 | String CRM_CONTRACT_TRANSFER_SUCCESS = "将合同【{{#contract.name}}】的负责人从【{getAdminUserById{#contract.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; |
| 96 | + String CRM_CONTRACT_SUBMIT_SUB_TYPE = "提交合同审批"; | ||
| 97 | + String CRM_CONTRACT_SUBMIT_SUCCESS = "提交合同【{{#contractName}}】审批成功"; | ||
| 96 | 98 | ||
| 97 | // ======================= CRM_PRODUCT 产品 ======================= | 99 | // ======================= CRM_PRODUCT 产品 ======================= |
| 98 | 100 |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
| @@ -8,7 +8,10 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | @@ -8,7 +8,10 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | ||
| 8 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 8 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 9 | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | 9 | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| 10 | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; | 10 | import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; |
| 11 | -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*; | 11 | +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; |
| 12 | +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractRespVO; | ||
| 13 | +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO; | ||
| 14 | +import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; | ||
| 12 | import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert; | 15 | import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert; |
| 13 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; | 16 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; |
| 14 | import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; | 17 | import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; |
| @@ -127,8 +130,8 @@ public class CrmContractController { | @@ -127,8 +130,8 @@ public class CrmContractController { | ||
| 127 | HttpServletResponse response) throws IOException { | 130 | HttpServletResponse response) throws IOException { |
| 128 | PageResult<CrmContractDO> pageResult = contractService.getContractPage(exportReqVO, getLoginUserId()); | 131 | PageResult<CrmContractDO> pageResult = contractService.getContractPage(exportReqVO, getLoginUserId()); |
| 129 | // 导出 Excel | 132 | // 导出 Excel |
| 130 | - ExcelUtils.write(response, "合同.xls", "数据", CrmContractExcelVO.class, | ||
| 131 | - BeanUtils.toBean(pageResult.getList(), CrmContractExcelVO.class)); | 133 | + ExcelUtils.write(response, "合同.xls", "数据", CrmContractRespVO.class, |
| 134 | + BeanUtils.toBean(pageResult.getList(), CrmContractRespVO.class)); | ||
| 132 | } | 135 | } |
| 133 | 136 | ||
| 134 | @PutMapping("/transfer") | 137 | @PutMapping("/transfer") |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractExcelVO.java deleted
| 1 | -package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; | ||
| 2 | - | ||
| 3 | -import com.alibaba.excel.annotation.ExcelProperty; | ||
| 4 | -import lombok.Data; | ||
| 5 | - | ||
| 6 | -import java.time.LocalDateTime; | ||
| 7 | - | ||
| 8 | -// TODO @puhui999:合并到 RespVO 里哈; | ||
| 9 | -/** | ||
| 10 | - * CRM 合同 Excel VO | ||
| 11 | - * | ||
| 12 | - * @author dhb52 | ||
| 13 | - */ | ||
| 14 | -@Data | ||
| 15 | -public class CrmContractExcelVO { | ||
| 16 | - | ||
| 17 | - @ExcelProperty("合同编号") | ||
| 18 | - private Long id; | ||
| 19 | - | ||
| 20 | - @ExcelProperty("合同名称") | ||
| 21 | - private String name; | ||
| 22 | - | ||
| 23 | - @ExcelProperty("客户编号") | ||
| 24 | - private Long customerId; | ||
| 25 | - | ||
| 26 | - @ExcelProperty("商机编号") | ||
| 27 | - private Long businessId; | ||
| 28 | - | ||
| 29 | - @ExcelProperty("工作流编号") | ||
| 30 | - private Long processInstanceId; | ||
| 31 | - | ||
| 32 | - @ExcelProperty("下单日期") | ||
| 33 | - private LocalDateTime orderDate; | ||
| 34 | - | ||
| 35 | - @ExcelProperty("负责人的用户编号") | ||
| 36 | - private Long ownerUserId; | ||
| 37 | - | ||
| 38 | - @ExcelProperty("合同编号") | ||
| 39 | - private String no; | ||
| 40 | - | ||
| 41 | - @ExcelProperty("开始时间") | ||
| 42 | - private LocalDateTime startTime; | ||
| 43 | - | ||
| 44 | - @ExcelProperty("结束时间") | ||
| 45 | - private LocalDateTime endTime; | ||
| 46 | - | ||
| 47 | - @ExcelProperty("合同金额") | ||
| 48 | - private Integer price; | ||
| 49 | - | ||
| 50 | - @ExcelProperty("整单折扣") | ||
| 51 | - private Integer discountPercent; | ||
| 52 | - | ||
| 53 | - @ExcelProperty("产品总金额") | ||
| 54 | - private Integer productPrice; | ||
| 55 | - | ||
| 56 | - @ExcelProperty("联系人编号") | ||
| 57 | - private Long contactId; | ||
| 58 | - | ||
| 59 | - @ExcelProperty("公司签约人") | ||
| 60 | - private Long signUserId; | ||
| 61 | - | ||
| 62 | - @ExcelProperty("最后跟进时间") | ||
| 63 | - private LocalDateTime contactLastTime; | ||
| 64 | - | ||
| 65 | - @ExcelProperty("备注") | ||
| 66 | - private String remark; | ||
| 67 | - | ||
| 68 | - @ExcelProperty("创建时间") | ||
| 69 | - private LocalDateTime createTime; | ||
| 70 | - | ||
| 71 | -} |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
| @@ -21,7 +21,6 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | @@ -21,7 +21,6 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | ||
| 21 | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | 21 | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| 22 | import io.swagger.v3.oas.annotations.Operation; | 22 | import io.swagger.v3.oas.annotations.Operation; |
| 23 | import io.swagger.v3.oas.annotations.Parameter; | 23 | import io.swagger.v3.oas.annotations.Parameter; |
| 24 | -import io.swagger.v3.oas.annotations.Parameters; | ||
| 25 | import io.swagger.v3.oas.annotations.tags.Tag; | 24 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 26 | import jakarta.annotation.Resource; | 25 | import jakarta.annotation.Resource; |
| 27 | import jakarta.servlet.http.HttpServletResponse; | 26 | import jakarta.servlet.http.HttpServletResponse; |
| @@ -30,7 +29,6 @@ import org.mapstruct.ap.internal.util.Collections; | @@ -30,7 +29,6 @@ import org.mapstruct.ap.internal.util.Collections; | ||
| 30 | import org.springframework.security.access.prepost.PreAuthorize; | 29 | import org.springframework.security.access.prepost.PreAuthorize; |
| 31 | import org.springframework.validation.annotation.Validated; | 30 | import org.springframework.validation.annotation.Validated; |
| 32 | import org.springframework.web.bind.annotation.*; | 31 | import org.springframework.web.bind.annotation.*; |
| 33 | -import org.springframework.web.multipart.MultipartFile; | ||
| 34 | 32 | ||
| 35 | import java.io.IOException; | 33 | import java.io.IOException; |
| 36 | import java.time.LocalDateTime; | 34 | import java.time.LocalDateTime; |
| @@ -218,19 +216,13 @@ public class CrmCustomerController { | @@ -218,19 +216,13 @@ public class CrmCustomerController { | ||
| 218 | ExcelUtils.write(response, "客户导入模板.xls", "客户列表", CrmCustomerImportExcelVO.class, list); | 216 | ExcelUtils.write(response, "客户导入模板.xls", "客户列表", CrmCustomerImportExcelVO.class, list); |
| 219 | } | 217 | } |
| 220 | 218 | ||
| 221 | - // TODO @puhui999:updateSupport 要不改成前端必须传递;哈哈哈,代码排版看着有点乱; | ||
| 222 | - // TODO @puhui999:加一个选择负责人;允许空,空就进入公海; | ||
| 223 | @PostMapping("/import") | 219 | @PostMapping("/import") |
| 224 | @Operation(summary = "导入客户") | 220 | @Operation(summary = "导入客户") |
| 225 | - @Parameters({ | ||
| 226 | - @Parameter(name = "file", description = "Excel 文件", required = true), | ||
| 227 | - @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true") | ||
| 228 | - }) | ||
| 229 | @PreAuthorize("@ss.hasPermission('system:customer:import')") | 221 | @PreAuthorize("@ss.hasPermission('system:customer:import')") |
| 230 | - public CommonResult<CrmCustomerImportRespVO> importExcel(@RequestParam("file") MultipartFile file, @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) | 222 | + public CommonResult<CrmCustomerImportRespVO> importExcel(@Valid @RequestBody CrmCustomerImportReqVO importReqVO) |
| 231 | throws Exception { | 223 | throws Exception { |
| 232 | - List<CrmCustomerImportExcelVO> list = ExcelUtils.read(file, CrmCustomerImportExcelVO.class); | ||
| 233 | - return success(customerService.importCustomerList(list, updateSupport, getLoginUserId())); | 224 | + List<CrmCustomerImportExcelVO> list = ExcelUtils.read(importReqVO.getFile(), CrmCustomerImportExcelVO.class); |
| 225 | + return success(customerService.importCustomerList(list, importReqVO)); | ||
| 234 | } | 226 | } |
| 235 | 227 | ||
| 236 | @PutMapping("/transfer") | 228 | @PutMapping("/transfer") |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerImportReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.crm.controller.admin.customer.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import jakarta.validation.constraints.NotNull; | ||
| 5 | +import lombok.Builder; | ||
| 6 | +import lombok.Data; | ||
| 7 | +import org.springframework.web.multipart.MultipartFile; | ||
| 8 | + | ||
| 9 | +@Schema(description = "管理后台 - 客户导入 Request VO") | ||
| 10 | +@Data | ||
| 11 | +@Builder | ||
| 12 | +public class CrmCustomerImportReqVO { | ||
| 13 | + | ||
| 14 | + @Schema(description = "Excel 文件", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 15 | + @NotNull(message = "Excel 文件不能为空") | ||
| 16 | + private MultipartFile file; | ||
| 17 | + | ||
| 18 | + @Schema(description = "是否支持更新", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") | ||
| 19 | + @NotNull(message = "是否支持更新不能为空") | ||
| 20 | + private Boolean updateSupport; | ||
| 21 | + | ||
| 22 | + @Schema(description = "负责人", example = "1") | ||
| 23 | + private Long ownerUserId; // 为 null 则客户进入公海 | ||
| 24 | + | ||
| 25 | +} |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java
| @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi | @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi | ||
| 7 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; | 7 | import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; |
| 8 | import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; | 8 | import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; |
| 9 | import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; | 9 | import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; |
| 10 | +import cn.iocoder.yudao.module.crm.service.business.bo.CrmBusinessUpdateProductReqBO; | ||
| 10 | import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; | 11 | import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; |
| 11 | import jakarta.validation.Valid; | 12 | import jakarta.validation.Valid; |
| 12 | 13 | ||
| @@ -51,6 +52,21 @@ public interface CrmBusinessService { | @@ -51,6 +52,21 @@ public interface CrmBusinessService { | ||
| 51 | void deleteBusiness(Long id); | 52 | void deleteBusiness(Long id); |
| 52 | 53 | ||
| 53 | /** | 54 | /** |
| 55 | + * 商机转移 | ||
| 56 | + * | ||
| 57 | + * @param reqVO 请求 | ||
| 58 | + * @param userId 用户编号 | ||
| 59 | + */ | ||
| 60 | + void transferBusiness(CrmBusinessTransferReqVO reqVO, Long userId); | ||
| 61 | + | ||
| 62 | + /** | ||
| 63 | + * 更新商机关联商品 | ||
| 64 | + * | ||
| 65 | + * @param updateProductReqBO 请求 | ||
| 66 | + */ | ||
| 67 | + void updateBusinessProduct(CrmBusinessUpdateProductReqBO updateProductReqBO); | ||
| 68 | + | ||
| 69 | + /** | ||
| 54 | * 获得商机 | 70 | * 获得商机 |
| 55 | * | 71 | * |
| 56 | * @param id 编号 | 72 | * @param id 编号 |
| @@ -106,14 +122,6 @@ public interface CrmBusinessService { | @@ -106,14 +122,6 @@ public interface CrmBusinessService { | ||
| 106 | PageResult<CrmBusinessDO> getBusinessPageByContact(CrmBusinessPageReqVO pageReqVO); | 122 | PageResult<CrmBusinessDO> getBusinessPageByContact(CrmBusinessPageReqVO pageReqVO); |
| 107 | 123 | ||
| 108 | /** | 124 | /** |
| 109 | - * 商机转移 | ||
| 110 | - * | ||
| 111 | - * @param reqVO 请求 | ||
| 112 | - * @param userId 用户编号 | ||
| 113 | - */ | ||
| 114 | - void transferBusiness(CrmBusinessTransferReqVO reqVO, Long userId); | ||
| 115 | - | ||
| 116 | - /** | ||
| 117 | * 获取关联客户的商机数量 | 125 | * 获取关联客户的商机数量 |
| 118 | * | 126 | * |
| 119 | * @param customerId 客户编号 | 127 | * @param customerId 客户编号 |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
| @@ -20,6 +20,7 @@ import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessProductMapper; | @@ -20,6 +20,7 @@ import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessProductMapper; | ||
| 20 | import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; | 20 | import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; |
| 21 | import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; | 21 | import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; |
| 22 | import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; | 22 | import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; |
| 23 | +import cn.iocoder.yudao.module.crm.service.business.bo.CrmBusinessUpdateProductReqBO; | ||
| 23 | import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService; | 24 | import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService; |
| 24 | import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; | 25 | import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; |
| 25 | import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; | 26 | import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; |
| @@ -80,7 +81,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | @@ -80,7 +81,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | ||
| 80 | businessMapper.insert(business); | 81 | businessMapper.insert(business); |
| 81 | // 1.2 插入商机关联商品 | 82 | // 1.2 插入商机关联商品 |
| 82 | if (CollUtil.isNotEmpty(createReqVO.getProductItems())) { // 如果有的话 | 83 | if (CollUtil.isNotEmpty(createReqVO.getProductItems())) { // 如果有的话 |
| 83 | - List<CrmBusinessProductDO> productList = convertBusinessProductList(createReqVO, business.getId()); | 84 | + List<CrmBusinessProductDO> productList = convertBusinessProductList(createReqVO.getProductItems(), business.getId()); |
| 84 | businessProductMapper.insertBatch(productList); | 85 | businessProductMapper.insertBatch(productList); |
| 85 | // 更新合同商品总金额 | 86 | // 更新合同商品总金额 |
| 86 | businessMapper.updateById(new CrmBusinessDO().setId(business.getId()).setProductPrice( | 87 | businessMapper.updateById(new CrmBusinessDO().setId(business.getId()).setProductPrice( |
| @@ -120,7 +121,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | @@ -120,7 +121,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | ||
| 120 | CrmBusinessDO updateObj = BeanUtils.toBean(updateReqVO, CrmBusinessDO.class); | 121 | CrmBusinessDO updateObj = BeanUtils.toBean(updateReqVO, CrmBusinessDO.class); |
| 121 | businessMapper.updateById(updateObj); | 122 | businessMapper.updateById(updateObj); |
| 122 | // 2.2 更新商机关联商品 | 123 | // 2.2 更新商机关联商品 |
| 123 | - List<CrmBusinessProductDO> productList = convertBusinessProductList(updateReqVO, updateObj.getId()); | 124 | + List<CrmBusinessProductDO> productList = convertBusinessProductList(updateReqVO.getProductItems(), updateObj.getId()); |
| 124 | updateBusinessProduct(productList, updateObj.getId()); | 125 | updateBusinessProduct(productList, updateObj.getId()); |
| 125 | 126 | ||
| 126 | // TODO @商机待定:如果状态发生变化,插入商机状态变更记录表 | 127 | // TODO @商机待定:如果状态发生变化,插入商机状态变更记录表 |
| @@ -174,15 +175,15 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | @@ -174,15 +175,15 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | ||
| 174 | } | 175 | } |
| 175 | } | 176 | } |
| 176 | 177 | ||
| 177 | - private List<CrmBusinessProductDO> convertBusinessProductList(CrmBusinessSaveReqVO reqVO, Long businessId) { | 178 | + private List<CrmBusinessProductDO> convertBusinessProductList(List<CrmBusinessSaveReqVO.CrmBusinessProductItem> productItems, Long businessId) { |
| 178 | // 校验商品存在 | 179 | // 校验商品存在 |
| 179 | - Set<Long> productIds = convertSet(reqVO.getProductItems(), CrmBusinessSaveReqVO.CrmBusinessProductItem::getId); | 180 | + Set<Long> productIds = convertSet(productItems, CrmBusinessSaveReqVO.CrmBusinessProductItem::getId); |
| 180 | List<CrmProductDO> productList = productService.getProductList(productIds); | 181 | List<CrmProductDO> productList = productService.getProductList(productIds); |
| 181 | if (CollUtil.isEmpty(productIds) || productList.size() != productIds.size()) { | 182 | if (CollUtil.isEmpty(productIds) || productList.size() != productIds.size()) { |
| 182 | throw exception(PRODUCT_NOT_EXISTS); | 183 | throw exception(PRODUCT_NOT_EXISTS); |
| 183 | } | 184 | } |
| 184 | Map<Long, CrmProductDO> productMap = convertMap(productList, CrmProductDO::getId); | 185 | Map<Long, CrmProductDO> productMap = convertMap(productList, CrmProductDO::getId); |
| 185 | - return convertList(reqVO.getProductItems(), productItem -> { | 186 | + return convertList(productItems, productItem -> { |
| 186 | CrmProductDO product = productMap.get(productItem.getId()); | 187 | CrmProductDO product = productMap.get(productItem.getId()); |
| 187 | return BeanUtils.toBean(product, CrmBusinessProductDO.class) | 188 | return BeanUtils.toBean(product, CrmBusinessProductDO.class) |
| 188 | .setId(null).setProductId(productItem.getId()).setBusinessId(businessId) | 189 | .setId(null).setProductId(productItem.getId()).setBusinessId(businessId) |
| @@ -231,6 +232,14 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | @@ -231,6 +232,14 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { | ||
| 231 | LogRecordContext.putVariable("business", business); | 232 | LogRecordContext.putVariable("business", business); |
| 232 | } | 233 | } |
| 233 | 234 | ||
| 235 | + @Override | ||
| 236 | + public void updateBusinessProduct(CrmBusinessUpdateProductReqBO updateProductReqBO) { | ||
| 237 | + // 更新商机关联商品 | ||
| 238 | + List<CrmBusinessProductDO> productList = convertBusinessProductList( | ||
| 239 | + BeanUtils.toBean(updateProductReqBO.getProductItems(), CrmBusinessSaveReqVO.CrmBusinessProductItem.class), updateProductReqBO.getId()); | ||
| 240 | + updateBusinessProduct(productList, updateProductReqBO.getId()); | ||
| 241 | + } | ||
| 242 | + | ||
| 234 | //======================= 查询相关 ======================= | 243 | //======================= 查询相关 ======================= |
| 235 | 244 | ||
| 236 | @Override | 245 | @Override |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateProductReqBO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.crm.service.business.bo; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import jakarta.validation.constraints.NotEmpty; | ||
| 5 | +import jakarta.validation.constraints.NotNull; | ||
| 6 | +import lombok.AllArgsConstructor; | ||
| 7 | +import lombok.Data; | ||
| 8 | +import lombok.NoArgsConstructor; | ||
| 9 | + | ||
| 10 | +import java.util.List; | ||
| 11 | + | ||
| 12 | +/** | ||
| 13 | + * 更新商机商品 Update Req BO | ||
| 14 | + * | ||
| 15 | + * @author HUIHUI | ||
| 16 | + */ | ||
| 17 | +@Data | ||
| 18 | +public class CrmBusinessUpdateProductReqBO { | ||
| 19 | + | ||
| 20 | + /** | ||
| 21 | + * 商机编号 | ||
| 22 | + */ | ||
| 23 | + @NotNull(message = "商机编号不能为空") | ||
| 24 | + private Long id; | ||
| 25 | + | ||
| 26 | + @NotEmpty(message = "产品列表不能为空") | ||
| 27 | + private List<CrmBusinessProductItem> productItems; | ||
| 28 | + | ||
| 29 | + @Schema(description = "产品列表") | ||
| 30 | + @Data | ||
| 31 | + @NoArgsConstructor | ||
| 32 | + @AllArgsConstructor | ||
| 33 | + public static class CrmBusinessProductItem { | ||
| 34 | + | ||
| 35 | + @Schema(description = "产品编号", example = "20529") | ||
| 36 | + @NotNull(message = "产品编号不能为空") | ||
| 37 | + private Long id; | ||
| 38 | + | ||
| 39 | + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") | ||
| 40 | + @NotNull(message = "产品数量不能为空") | ||
| 41 | + private Integer count; | ||
| 42 | + | ||
| 43 | + @Schema(description = "产品折扣") | ||
| 44 | + private Integer discountPercent; | ||
| 45 | + | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | +} |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
| @@ -11,6 +11,7 @@ import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | @@ -11,6 +11,7 @@ import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | ||
| 11 | import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO; | 11 | import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO; |
| 12 | import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; | 12 | import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; |
| 13 | import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; | 13 | import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; |
| 14 | +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; | ||
| 14 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; | 15 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; |
| 15 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO; | 16 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO; |
| 16 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; | 17 | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; |
| @@ -25,6 +26,7 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; | @@ -25,6 +26,7 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; | ||
| 25 | import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; | 26 | import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; |
| 26 | import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; | 27 | import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; |
| 27 | import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; | 28 | import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; |
| 29 | +import cn.iocoder.yudao.module.crm.service.business.bo.CrmBusinessUpdateProductReqBO; | ||
| 28 | import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; | 30 | import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; |
| 29 | import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; | 31 | import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; |
| 30 | import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; | 32 | import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; |
| @@ -96,7 +98,11 @@ public class CrmContractServiceImpl implements CrmContractService { | @@ -96,7 +98,11 @@ public class CrmContractServiceImpl implements CrmContractService { | ||
| 96 | // 更新合同商品总金额 | 98 | // 更新合同商品总金额 |
| 97 | contractMapper.updateById(new CrmContractDO().setId(contract.getId()).setProductPrice( | 99 | contractMapper.updateById(new CrmContractDO().setId(contract.getId()).setProductPrice( |
| 98 | getSumValue(productList, CrmContractProductDO::getTotalPrice, Integer::sum))); | 100 | getSumValue(productList, CrmContractProductDO::getTotalPrice, Integer::sum))); |
| 99 | - // TODO @puhui999: 如果存在合同关联了商机则更新商机商品关联 | 101 | + // 如果存在合同关联了商机则更新商机商品关联 |
| 102 | + if (contract.getBusinessId() != null) { | ||
| 103 | + businessService.updateBusinessProduct(new CrmBusinessUpdateProductReqBO().setId(contract.getBusinessId()) | ||
| 104 | + .setProductItems(BeanUtils.toBean(createReqVO.getProductItems(), CrmBusinessUpdateProductReqBO.CrmBusinessProductItem.class))); | ||
| 105 | + } | ||
| 100 | } | 106 | } |
| 101 | 107 | ||
| 102 | // 2. 创建数据权限 | 108 | // 2. 创建数据权限 |
| @@ -251,7 +257,8 @@ public class CrmContractServiceImpl implements CrmContractService { | @@ -251,7 +257,8 @@ public class CrmContractServiceImpl implements CrmContractService { | ||
| 251 | 257 | ||
| 252 | @Override | 258 | @Override |
| 253 | @Transactional(rollbackFor = Exception.class) | 259 | @Transactional(rollbackFor = Exception.class) |
| 254 | - // TODO @puhui999:操作日志; | 260 | + @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_SUBMIT_SUB_TYPE, bizNo = "{{#id}}", |
| 261 | + success = CRM_CONTRACT_SUBMIT_SUCCESS) | ||
| 255 | public void submitContract(Long id, Long userId) { | 262 | public void submitContract(Long id, Long userId) { |
| 256 | // 1. 校验合同是否在审批 | 263 | // 1. 校验合同是否在审批 |
| 257 | CrmContractDO contract = validateContractExists(id); | 264 | CrmContractDO contract = validateContractExists(id); |
| @@ -266,15 +273,43 @@ public class CrmContractServiceImpl implements CrmContractService { | @@ -266,15 +273,43 @@ public class CrmContractServiceImpl implements CrmContractService { | ||
| 266 | // 3. 更新合同工作流编号 | 273 | // 3. 更新合同工作流编号 |
| 267 | contractMapper.updateById(new CrmContractDO().setId(id).setProcessInstanceId(processInstanceId) | 274 | contractMapper.updateById(new CrmContractDO().setId(id).setProcessInstanceId(processInstanceId) |
| 268 | .setAuditStatus(CrmAuditStatusEnum.PROCESS.getStatus())); | 275 | .setAuditStatus(CrmAuditStatusEnum.PROCESS.getStatus())); |
| 276 | + | ||
| 277 | + // 3. 记录日志 | ||
| 278 | + LogRecordContext.putVariable("contractName", contract.getName()); | ||
| 269 | } | 279 | } |
| 270 | 280 | ||
| 271 | @Override | 281 | @Override |
| 272 | public void updateContractAuditStatus(BpmResultListenerRespDTO event) { | 282 | public void updateContractAuditStatus(BpmResultListenerRespDTO event) { |
| 273 | - // TODO @puhui999:可能要判断下状态是否符合预期 | 283 | + // 判断下状态是否符合预期 |
| 284 | + if (!isEndResult(event.getResult())) { | ||
| 285 | + return; | ||
| 286 | + } | ||
| 287 | + // 状态转换 | ||
| 288 | + if (ObjUtil.equal(event.getResult(), BpmProcessInstanceResultEnum.APPROVE.getResult())) { | ||
| 289 | + event.setResult(CrmAuditStatusEnum.APPROVE.getStatus()); | ||
| 290 | + } | ||
| 291 | + if (ObjUtil.equal(event.getResult(), BpmProcessInstanceResultEnum.REJECT.getResult())) { | ||
| 292 | + event.setResult(CrmAuditStatusEnum.REJECT.getStatus()); | ||
| 293 | + } | ||
| 294 | + if (ObjUtil.equal(event.getResult(), BpmProcessInstanceResultEnum.CANCEL.getResult())) { | ||
| 295 | + event.setResult(CrmAuditStatusEnum.CANCEL.getStatus()); | ||
| 296 | + } | ||
| 297 | + // 更新合同状态 | ||
| 274 | contractMapper.updateById(new CrmContractDO().setId(Long.parseLong(event.getBusinessKey())) | 298 | contractMapper.updateById(new CrmContractDO().setId(Long.parseLong(event.getBusinessKey())) |
| 275 | .setAuditStatus(event.getResult())); | 299 | .setAuditStatus(event.getResult())); |
| 276 | } | 300 | } |
| 277 | 301 | ||
| 302 | + /** | ||
| 303 | + * 判断该结果是否处于 End 最终结果 | ||
| 304 | + * | ||
| 305 | + * @param result 结果 | ||
| 306 | + * @return 是否 | ||
| 307 | + */ | ||
| 308 | + public static boolean isEndResult(Integer result) { | ||
| 309 | + return ObjectUtils.equalsAny(result, BpmProcessInstanceResultEnum.APPROVE.getResult(), | ||
| 310 | + BpmProcessInstanceResultEnum.REJECT.getResult(), BpmProcessInstanceResultEnum.CANCEL.getResult()); | ||
| 311 | + } | ||
| 312 | + | ||
| 278 | //======================= 查询相关 ======================= | 313 | //======================= 查询相关 ======================= |
| 279 | 314 | ||
| 280 | @Override | 315 | @Override |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/listener/CrmContractResultListener.java
| 1 | package cn.iocoder.yudao.module.crm.service.contract.listener; | 1 | package cn.iocoder.yudao.module.crm.service.contract.listener; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.util.ObjUtil; | ||
| 4 | -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | ||
| 5 | import cn.iocoder.yudao.module.bpm.api.listener.BpmResultListenerApi; | 3 | import cn.iocoder.yudao.module.bpm.api.listener.BpmResultListenerApi; |
| 6 | import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO; | 4 | import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO; |
| 7 | -import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; | ||
| 8 | -import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; | ||
| 9 | import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; | 5 | import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; |
| 10 | import cn.iocoder.yudao.module.crm.service.contract.CrmContractServiceImpl; | 6 | import cn.iocoder.yudao.module.crm.service.contract.CrmContractServiceImpl; |
| 11 | import jakarta.annotation.Resource; | 7 | import jakarta.annotation.Resource; |
| @@ -30,31 +26,7 @@ public class CrmContractResultListener implements BpmResultListenerApi { | @@ -30,31 +26,7 @@ public class CrmContractResultListener implements BpmResultListenerApi { | ||
| 30 | 26 | ||
| 31 | @Override | 27 | @Override |
| 32 | public void onEvent(BpmResultListenerRespDTO event) { | 28 | public void onEvent(BpmResultListenerRespDTO event) { |
| 33 | - boolean currentTaskFinish = isEndResult(event.getResult()); | ||
| 34 | - if (!currentTaskFinish) { | ||
| 35 | - return; | ||
| 36 | - } | ||
| 37 | - if (ObjUtil.equal(event.getResult(), BpmProcessInstanceResultEnum.APPROVE.getResult())) { | ||
| 38 | - event.setResult(CrmAuditStatusEnum.APPROVE.getStatus()); | ||
| 39 | - } | ||
| 40 | - if (ObjUtil.equal(event.getResult(), BpmProcessInstanceResultEnum.REJECT.getResult())) { | ||
| 41 | - event.setResult(CrmAuditStatusEnum.REJECT.getStatus()); | ||
| 42 | - } | ||
| 43 | - if (ObjUtil.equal(event.getResult(), BpmProcessInstanceResultEnum.CANCEL.getResult())) { | ||
| 44 | - event.setResult(CrmAuditStatusEnum.CANCEL.getStatus()); | ||
| 45 | - } | ||
| 46 | contractService.updateContractAuditStatus(event); | 29 | contractService.updateContractAuditStatus(event); |
| 47 | } | 30 | } |
| 48 | 31 | ||
| 49 | - /** | ||
| 50 | - * 判断该结果是否处于 End 最终结果 | ||
| 51 | - * | ||
| 52 | - * @param result 结果 | ||
| 53 | - * @return 是否 | ||
| 54 | - */ | ||
| 55 | - public static boolean isEndResult(Integer result) { | ||
| 56 | - return ObjectUtils.equalsAny(result, BpmProcessInstanceResultEnum.APPROVE.getResult(), | ||
| 57 | - BpmProcessInstanceResultEnum.REJECT.getResult(), BpmProcessInstanceResultEnum.CANCEL.getResult()); | ||
| 58 | - } | ||
| 59 | - | ||
| 60 | } | 32 | } |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java
| @@ -110,11 +110,10 @@ public interface CrmCustomerService { | @@ -110,11 +110,10 @@ public interface CrmCustomerService { | ||
| 110 | * 批量导入客户 | 110 | * 批量导入客户 |
| 111 | * | 111 | * |
| 112 | * @param importCustomers 导入客户列表 | 112 | * @param importCustomers 导入客户列表 |
| 113 | - * @param isUpdateSupport 是否支持更新 | ||
| 114 | - * @param userId 用户编号 | 113 | + * @param importReqVO 请求 |
| 115 | * @return 导入结果 | 114 | * @return 导入结果 |
| 116 | */ | 115 | */ |
| 117 | - CrmCustomerImportRespVO importCustomerList(List<CrmCustomerImportExcelVO> importCustomers, Boolean isUpdateSupport, Long userId); | 116 | + CrmCustomerImportRespVO importCustomerList(List<CrmCustomerImportExcelVO> importCustomers, CrmCustomerImportReqVO importReqVO); |
| 118 | 117 | ||
| 119 | // ==================== 公海相关操作 ==================== | 118 | // ==================== 公海相关操作 ==================== |
| 120 | 119 |
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
| @@ -108,7 +108,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -108,7 +108,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 108 | /** | 108 | /** |
| 109 | * 初始化客户的通用字段 | 109 | * 初始化客户的通用字段 |
| 110 | * | 110 | * |
| 111 | - * @param customer 客户信息 | 111 | + * @param customer 客户信息 |
| 112 | * @param ownerUserId 负责人编号 | 112 | * @param ownerUserId 负责人编号 |
| 113 | * @return 客户信息 DO | 113 | * @return 客户信息 DO |
| 114 | */ | 114 | */ |
| @@ -244,8 +244,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -244,8 +244,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | @Override | 246 | @Override |
| 247 | - public CrmCustomerImportRespVO importCustomerList(List<CrmCustomerImportExcelVO> importCustomers, | ||
| 248 | - Boolean isUpdateSupport, Long userId) { | 247 | + public CrmCustomerImportRespVO importCustomerList(List<CrmCustomerImportExcelVO> importCustomers, CrmCustomerImportReqVO importReqVO) { |
| 249 | if (CollUtil.isEmpty(importCustomers)) { | 248 | if (CollUtil.isEmpty(importCustomers)) { |
| 250 | throw exception(CUSTOMER_IMPORT_LIST_IS_EMPTY); | 249 | throw exception(CUSTOMER_IMPORT_LIST_IS_EMPTY); |
| 251 | } | 250 | } |
| @@ -264,19 +263,21 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | @@ -264,19 +263,21 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | ||
| 264 | CrmCustomerDO existCustomer = customerMapper.selectByCustomerName(importCustomer.getName()); | 263 | CrmCustomerDO existCustomer = customerMapper.selectByCustomerName(importCustomer.getName()); |
| 265 | if (existCustomer == null) { | 264 | if (existCustomer == null) { |
| 266 | // 1.1 插入客户信息 | 265 | // 1.1 插入客户信息 |
| 267 | - CrmCustomerDO customer = initCustomer(importCustomer, userId); | 266 | + CrmCustomerDO customer = initCustomer(importCustomer, importReqVO.getOwnerUserId()); |
| 268 | customerMapper.insert(customer); | 267 | customerMapper.insert(customer); |
| 269 | respVO.getCreateCustomerNames().add(importCustomer.getName()); | 268 | respVO.getCreateCustomerNames().add(importCustomer.getName()); |
| 270 | - // 1.2 创建数据权限 | ||
| 271 | - permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) | ||
| 272 | - .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 | 269 | + if (importReqVO.getOwnerUserId() != null) { |
| 270 | + // 1.2 创建数据权限 | ||
| 271 | + permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) | ||
| 272 | + .setBizId(customer.getId()).setUserId(importReqVO.getOwnerUserId()).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 | ||
| 273 | + } | ||
| 273 | // 1.3 记录操作日志 | 274 | // 1.3 记录操作日志 |
| 274 | getSelf().importCustomerLog(customer, false); | 275 | getSelf().importCustomerLog(customer, false); |
| 275 | return; | 276 | return; |
| 276 | } | 277 | } |
| 277 | 278 | ||
| 278 | // 情况二:如果存在,判断是否允许更新 | 279 | // 情况二:如果存在,判断是否允许更新 |
| 279 | - if (!isUpdateSupport) { | 280 | + if (!importReqVO.getUpdateSupport()) { |
| 280 | respVO.getFailureCustomerNames().put(importCustomer.getName(), | 281 | respVO.getFailureCustomerNames().put(importCustomer.getName(), |
| 281 | StrUtil.format(CUSTOMER_NAME_EXISTS.getMsg(), importCustomer.getName())); | 282 | StrUtil.format(CUSTOMER_NAME_EXISTS.getMsg(), importCustomer.getName())); |
| 282 | return; | 283 | return; |