diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java index 7cb931689..861698ac0 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/BpmModelController.java @@ -43,6 +43,7 @@ public class BpmModelController { return success(model); } + // TODO @puhui999:这个接口的目的是啥呀? @GetMapping("/get-by-key") @Operation(summary = "获得模型") @Parameter(name = "key", description = "流程标识", required = true, example = "oa_leave") 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 7f2541ae7..28c71c4e2 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 @@ -132,6 +132,7 @@ public class CrmContractController { return CrmContractConvert.INSTANCE.convertPage(pageResult, userMap, customerList); } + // TODO @puhui999:transferContract @PutMapping("/transfer") @Operation(summary = "合同转移") @PreAuthorize("@ss.hasPermission('crm:contract:update')") @@ -140,6 +141,7 @@ public class CrmContractController { return success(true); } + // TODO @puhui999:方法名不对哈;要不改成 submit?提交审核的意思 @PutMapping("/approve") @Operation(summary = "发起合同审批流程") @PreAuthorize("@ss.hasPermission('crm:contract:update')") 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 ef90f2f2f..f1ab8c581 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 @@ -89,6 +89,7 @@ public class CrmContractSaveReqVO { @DiffLogField(name = "备注") private String remark; + // TODO @puhui999:这个字段,按道理不用传递? @Schema(description = "审批状态", example = "1") private Integer auditStatus; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java index 3bbd4dfd7..09057fd78 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java @@ -217,6 +217,8 @@ public class CrmCustomerController { ExcelUtils.write(response, "客户导入模板.xls", "客户列表", CrmCustomerImportExcelVO.class, list); } + // TODO @puhui999:updateSupport 要不改成前端必须传递;哈哈哈,代码排版看着有点乱; + // TODO @puhui999:加一个选择负责人;允许空,空就进入公海; @PostMapping("/import") @Operation(summary = "导入客户") @Parameters({ @@ -224,13 +226,12 @@ public class CrmCustomerController { @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true") }) @PreAuthorize("@ss.hasPermission('system:customer:import')") - public CommonResult importExcel(@RequestParam("file") MultipartFile file, - @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception { + public CommonResult importExcel(@RequestParam("file") MultipartFile file, @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) + throws Exception { List list = ExcelUtils.read(file, CrmCustomerImportExcelVO.class); return success(customerService.importCustomerList(list, updateSupport, getLoginUserId())); } - @PutMapping("/transfer") @Operation(summary = "转移客户") @PreAuthorize("@ss.hasPermission('crm:customer:update')") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerImportExcelVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerImportExcelVO.java index 378abb6dd..4f57564dd 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerImportExcelVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerImportExcelVO.java @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.crm.controller.admin.customer.vo; import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; import com.alibaba.excel.annotation.ExcelProperty; -import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -25,6 +24,7 @@ public class CrmCustomerImportExcelVO { @ExcelProperty("客户名称") private String name; + // TODO @puhui999:industryId、level、source 字段,可以研究下怎么搞下拉框 @ExcelProperty(value = "所属行业", converter = DictConvert.class) @DictFormat(CRM_CUSTOMER_INDUSTRY) private Integer industryId; @@ -46,25 +46,22 @@ public class CrmCustomerImportExcelVO { @ExcelProperty("网址") private String website; - @Size(max = 20, message = "QQ长度不能超过 20 个字符") @ExcelProperty("QQ") private String qq; - @Size(max = 255, message = "微信长度不能超过 255 个字符") @ExcelProperty("微信") private String wechat; - @Size(max = 255, message = "邮箱长度不能超过 255 个字符") @ExcelProperty("邮箱") private String email; - @Size(max = 4096, message = "客户描述长度不能超过 4096 个字符") @ExcelProperty("客户描述") private String description; @ExcelProperty("备注") private String remark; + // TODO @puhui999:需要选择省市区,需要研究下,怎么搞合理点; @ExcelProperty("地区编号") private Integer areaId; 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 9d3cdb85b..10ea9235d 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 @@ -125,6 +125,7 @@ public interface CrmContractService { */ Long getContractCountByCustomerId(Long customerId); + // TODO @puhui999:要不改成 getContractCountByBusinessId /** * 根据商机ID获取关联客户的合同数量 * 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 c58ce15f0..130f0f709 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 @@ -6,7 +6,6 @@ import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -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.crm.controller.admin.contract.vo.CrmContractPageReqVO; @@ -23,7 +22,6 @@ import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; import cn.iocoder.yudao.module.crm.service.business.CrmBusinessProductService; import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; -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; @@ -34,7 +32,6 @@ import com.mzt.logapi.context.LogRecordContext; import com.mzt.logapi.service.impl.DiffParseFunction; import com.mzt.logapi.starter.annotation.LogRecord; import jakarta.annotation.Resource; -import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -71,17 +68,14 @@ public class CrmContractServiceImpl implements CrmContractService { @Resource private CrmProductService productService; @Resource - private BpmProcessInstanceApi bpmProcessInstanceApi; - @Resource private CrmCustomerService customerService; @Resource - @Lazy - private CrmContactService contactService; - @Resource - @Lazy private CrmBusinessService businessService; + @Resource private AdminUserApi adminUserApi; + @Resource + private BpmProcessInstanceApi bpmProcessInstanceApi; @Override @Transactional(rollbackFor = Exception.class) @@ -89,19 +83,19 @@ public class CrmContractServiceImpl implements CrmContractService { success = CRM_CONTRACT_CREATE_SUCCESS) public Long createContract(CrmContractSaveReqVO createReqVO, Long userId) { validateRelationDataExists(createReqVO); - // 插入合同 + // 1.1 插入合同 CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null); contractMapper.insert(contract); + // 1.2 插入商机关联商品 + List businessProduct = convertBusinessProductList(createReqVO); + businessProductService.insertBatch(businessProduct); - // 创建数据权限 + // 2. 创建数据权限 crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId) .setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()).setBizId(contract.getId()) .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); - // 插入商机关联商品 - List businessProduct = convertBusinessProductList(createReqVO); - businessProductService.insertBatch(businessProduct); - // 4. 记录操作日志上下文 + // 3. 记录操作日志上下文 LogRecordContext.putVariable("contract", contract); return contract.getId(); } @@ -125,6 +119,7 @@ public class CrmContractServiceImpl implements CrmContractService { contractMapper.updateById(updateObj); // TODO puhui999: @芋艿:合同变更关联的商机后商品怎么处理? + // TODO @puhui999:和商品 spu、sku 编辑一样;新增的插入;修改的更新;删除的删除 //List businessProduct = convertBusinessProductList(updateReqVO); //businessProductService.selectListByBusinessId() //diffList() @@ -145,6 +140,7 @@ public class CrmContractServiceImpl implements CrmContractService { } Map productMap = convertMap(productList, CrmProductDO::getId); return convertList(reqVO.getProductItems(), productItem -> { + // TODO @puhui999:这里可以改成直接 return,不用弄一个 businessProduct 变量哈; CrmBusinessProductDO businessProduct = BeanUtils.toBean(productMap.get(productItem.getId()), CrmBusinessProductDO.class); businessProduct.setId(null).setBusinessId(reqVO.getBusinessId()).setProductId(productItem.getId()) .setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent()).setTotalPrice(calculator(businessProduct)); @@ -158,6 +154,7 @@ public class CrmContractServiceImpl implements CrmContractService { * @param businessProduct 关联商品 * @return 商品总价 */ + // TODO @puhui999:这个逻辑的计算,是不是可以封装到 calculateRatePriceFloor 里; private Integer calculator(CrmBusinessProductDO businessProduct) { int price = businessProduct.getPrice() * businessProduct.getCount(); if (businessProduct.getDiscountPercent() == null) { @@ -180,7 +177,7 @@ public class CrmContractServiceImpl implements CrmContractService { if (reqVO.getOwnerUserId() != null && adminUserApi.getUser(reqVO.getOwnerUserId()) == null) { throw exception(USER_NOT_EXISTS); } - // 4. 如果有关联商机,则需要校验存在 + // 3. 如果有关联商机,则需要校验存在 if (reqVO.getBusinessId() != null && businessService.getBusiness(reqVO.getBusinessId()) == null) { throw exception(BUSINESS_NOT_EXISTS); } @@ -239,6 +236,8 @@ public class CrmContractServiceImpl implements CrmContractService { @Override @Transactional(rollbackFor = Exception.class) public void handleApprove(Long id, Long userId) { + // TODO @puhui999:需要做状态检查 + // 创建合同审批流程实例 String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() .setProcessDefinitionKey(CONTRACT_APPROVE).setBusinessKey(String.valueOf(id))); @@ -248,12 +247,6 @@ public class CrmContractServiceImpl implements CrmContractService { .setAuditStatus(CrmAuditStatusEnum.PROCESS.getStatus())); } - @Override - @Transactional(rollbackFor = Exception.class) - public void updateContractAuditStatus(BpmResultListenerRespDTO event) { - contractMapper.updateById(new CrmContractDO().setId(Long.parseLong(event.getBusinessKey())).setAuditStatus(event.getResult())); - } - //======================= 查询相关 ======================= @Override diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java index 26e0e2346..a7ddb2da9 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java @@ -232,8 +232,10 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { return customer.getId(); } + // TODO @puhui999:操作日志 @Override - public CrmCustomerImportRespVO importCustomerList(List importCustomers, Boolean isUpdateSupport, Long userId) { + public CrmCustomerImportRespVO importCustomerList(List importCustomers, + Boolean isUpdateSupport, Long userId) { if (CollUtil.isEmpty(importCustomers)) { throw exception(CUSTOMER_IMPORT_LIST_IS_EMPTY); } @@ -241,6 +243,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { .updateCustomerNames(new ArrayList<>()).failureCustomerNames(new LinkedHashMap<>()).build(); importCustomers.forEach(importCustomer -> { // 校验,判断是否有不符合的原因 + // TODO @puhui999:可以用 ValidationUtils 做参数校验;可能要封装一个方法,返回 message;这样的话,就可以在 CrmCustomerImportExcelVO 写需要校验的参数啦; try { validateCustomerForCreate(importCustomer); } catch (ServiceException ex) { @@ -250,6 +253,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { // 判断如果不存在,在进行插入 CrmCustomerDO existCustomer = customerMapper.selectByCustomerName(importCustomer.getName()); if (existCustomer == null) { + // TODO @puhui999:可以搞个 initCustomer 方法;这样可以把 create 和导入复用下这个方法; CrmCustomerDO customer = BeanUtils.toBean(importCustomer, CrmCustomerDO.class).setOwnerUserId(userId) .setLockStatus(false).setDealStatus(false).setContactLastTime(LocalDateTime.now()); customerMapper.insert(customer); @@ -366,6 +370,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { // 1.1 获取没有锁定的不在公海的客户且没有成交的 List notDealCustomerList = customerMapper.selectListByLockAndDealStatusAndNotPool(Boolean.FALSE, Boolean.FALSE); // 1.2 获取没有锁定的不在公海的客户且成交的 + // TODO @puhui999:下面也搞到 sql 里去哈;写 or 查询,问题不大的; List dealCustomerList = customerMapper.selectListByLockAndDealStatusAndNotPool(Boolean.FALSE, Boolean.TRUE); List poolCustomerList = new ArrayList<>(); poolCustomerList.addAll(filterList(notDealCustomerList, customer -> @@ -382,7 +387,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { getSelf().putCustomerPool(customer); count++; } catch (Throwable e) { - log.error("[customerAutoPutPoolBySystem][Customer 客户({}) 放入公海异常]", customer.getId(), e); + log.error("[autoPutCustomerPool][Customer 客户({}) 放入公海异常]", customer.getId(), e); } } return count; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java index 3385899fe..39b101323 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionService.java @@ -109,14 +109,14 @@ public interface CrmPermissionService { List getPermissionListByBizTypeAndUserId(Integer bizType, Long userId); /** - * 校验权限 + * 校验是否有指定数据的操作权限 * * @param bizType 数据类型,关联 {@link CrmBizTypeEnum} * @param bizId 数据编号,关联 {@link CrmBizTypeEnum} 对应模块 DO#getId() * @param userId 用户编号 - * @param levelEnum 权限级别 - * @return boolean + * @param level 权限级别 + * @return 是否有权限 */ - boolean hasPermission(Integer bizType, Long bizId, Long userId, CrmPermissionLevelEnum levelEnum); + boolean hasPermission(Integer bizType, Long bizId, Long userId, CrmPermissionLevelEnum level); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java index 36a616938..ba3e50c6d 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java @@ -213,10 +213,10 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { } @Override - public boolean hasPermission(Integer bizType, Long bizId, Long userId, CrmPermissionLevelEnum levelEnum) { + public boolean hasPermission(Integer bizType, Long bizId, Long userId, CrmPermissionLevelEnum level) { List permissionList = permissionMapper.selectByBizTypeAndBizId(bizType, bizId); return anyMatch(permissionList, permission -> - ObjUtil.equal(permission.getUserId(), userId) && ObjUtil.equal(permission.getLevel(), levelEnum.getLevel())); + ObjUtil.equal(permission.getUserId(), userId) && ObjUtil.equal(permission.getLevel(), level.getLevel())); } }