Commit 9caaa96e5b3678365d11f23b15861070f1d8f259

Authored by puhui999
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;