Commit 1a5fe6fa9a729417eb9e6d558bb12f7503aefe2e

Authored by puhui999
1 parent 9bba1ce8

CRM: 完善客户、联系人、合同、回款计划、回款的操作日志

Showing 13 changed files with 255 additions and 163 deletions
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java
1 package cn.iocoder.yudao.module.crm.enums; 1 package cn.iocoder.yudao.module.crm.enums;
2 2
  3 +import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameConstants.GET_CONTRACT_BY_ID;
  4 +
3 /** 5 /**
4 * CRM 操作日志枚举 6 * CRM 操作日志枚举
5 * 目的:统一管理,也减少 Service 里各种“复杂”字符串 7 * 目的:统一管理,也减少 Service 里各种“复杂”字符串
@@ -22,9 +24,9 @@ public interface LogRecordConstants { @@ -22,9 +24,9 @@ public interface LogRecordConstants {
22 String CRM_CUSTOMER_DELETE_SUB_TYPE = "删除客户"; 24 String CRM_CUSTOMER_DELETE_SUB_TYPE = "删除客户";
23 String CRM_CUSTOMER_DELETE_SUCCESS = "删除了客户【{{#customerName}}】"; 25 String CRM_CUSTOMER_DELETE_SUCCESS = "删除了客户【{{#customerName}}】";
24 String CRM_CUSTOMER_TRANSFER_SUB_TYPE = "转移客户"; 26 String CRM_CUSTOMER_TRANSFER_SUB_TYPE = "转移客户";
25 - String CRM_CUSTOMER_TRANSFER_SUCCESS = "将客户【{{#crmCustomer.name}}】的负责人从【{getAdminUserById{#crmCustomer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】";  
26 - String CRM_CUSTOMER_LOCK_SUB_TYPE = "{{#crmCustomer.lockStatus ? '解锁客户' : '锁定客户'}}";  
27 - String CRM_CUSTOMER_LOCK_SUCCESS = "{{#crmCustomer.lockStatus ? '将客户【' + #crmCustomer.name + '】解锁' : '将客户【' + #crmCustomer.name + '】锁定'}}"; 27 + String CRM_CUSTOMER_TRANSFER_SUCCESS = "将客户【{{#customer.name}}】的负责人从【{getAdminUserById{#customer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】";
  28 + String CRM_CUSTOMER_LOCK_SUB_TYPE = "{{#customer.lockStatus ? '解锁客户' : '锁定客户'}}";
  29 + String CRM_CUSTOMER_LOCK_SUCCESS = "{{#customer.lockStatus ? '将客户【' + #customer.name + '】解锁' : '将客户【' + #customer.name + '】锁定'}}";
28 String CRM_CUSTOMER_POOL_SUB_TYPE = "客户放入公海"; 30 String CRM_CUSTOMER_POOL_SUB_TYPE = "客户放入公海";
29 String CRM_CUSTOMER_POOL_SUCCESS = "将客户【{{#customerName}}】放入了公海"; 31 String CRM_CUSTOMER_POOL_SUCCESS = "将客户【{{#customerName}}】放入了公海";
30 String CRM_CUSTOMER_RECEIVE_SUB_TYPE = "{{#ownerUserName != null ? '分配客户' : '领取客户'}}"; 32 String CRM_CUSTOMER_RECEIVE_SUB_TYPE = "{{#ownerUserName != null ? '分配客户' : '领取客户'}}";
@@ -49,14 +51,40 @@ public interface LogRecordConstants { @@ -49,14 +51,40 @@ public interface LogRecordConstants {
49 // ======================= CRM_CONTACT 联系人 ======================= 51 // ======================= CRM_CONTACT 联系人 =======================
50 52
51 String CRM_CONTACT_TYPE = "CRM 联系人"; 53 String CRM_CONTACT_TYPE = "CRM 联系人";
  54 + String CRM_CONTACT_CREATE_SUB_TYPE = "创建联系人";
  55 + String CRM_CONTACT_CREATE_SUCCESS = "创建了联系人{{#contact.name}}";
  56 + String CRM_CONTACT_UPDATE_SUB_TYPE = "更新联系人";
  57 + String CRM_CONTACT_UPDATE_SUCCESS = "更新了联系人【{{#contactName}}】: {_DIFF{#updateReqVO}}";
  58 + String CRM_CONTACT_DELETE_SUB_TYPE = "删除联系人";
  59 + String CRM_CONTACT_DELETE_SUCCESS = "删除了联系人【{{#contactName}}】";
  60 + String CRM_CONTACT_TRANSFER_SUB_TYPE = "转移联系人";
  61 + String CRM_CONTACT_TRANSFER_SUCCESS = "将联系人【{{#contact.name}}】的负责人从【{getAdminUserById{#contact.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】";
  62 +
52 63
53 // ======================= CRM_BUSINESS 商机 ======================= 64 // ======================= CRM_BUSINESS 商机 =======================
54 65
55 String CRM_BUSINESS_TYPE = "CRM 商机"; 66 String CRM_BUSINESS_TYPE = "CRM 商机";
  67 + String CRM_BUSINESS_CREATE_SUB_TYPE = "创建商机";
  68 + String CRM_BUSINESS_CREATE_SUCCESS = "创建了商机{{#business.name}}";
  69 + String CRM_BUSINESS_UPDATE_SUB_TYPE = "更新商机";
  70 + String CRM_BUSINESS_UPDATE_SUCCESS = "更新了商机【{{#businessName}}】: {_DIFF{#updateReqVO}}";
  71 + String CRM_BUSINESS_DELETE_SUB_TYPE = "删除商机";
  72 + String CRM_BUSINESS_DELETE_SUCCESS = "删除了商机【{{#businessName}}】";
  73 + String CRM_BUSINESS_TRANSFER_SUB_TYPE = "转移商机";
  74 + String CRM_BUSINESS_TRANSFER_SUCCESS = "将商机【{{#business.name}}】的负责人从【{getAdminUserById{#business.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】";
56 75
57 // ======================= CRM_CONTRACT 合同 ======================= 76 // ======================= CRM_CONTRACT 合同 =======================
58 77
59 String CRM_CONTRACT_TYPE = "CRM 合同"; 78 String CRM_CONTRACT_TYPE = "CRM 合同";
  79 + String CRM_CONTRACT_CREATE_SUB_TYPE = "创建合同";
  80 + String CRM_CONTRACT_CREATE_SUCCESS = "创建了合同{{#contract.name}}";
  81 + String CRM_CONTRACT_UPDATE_SUB_TYPE = "更新合同";
  82 + String CRM_CONTRACT_UPDATE_SUCCESS = "更新了合同【{{#contractName}}】: {_DIFF{#updateReqVO}}";
  83 + String CRM_CONTRACT_DELETE_SUB_TYPE = "删除合同";
  84 + String CRM_CONTRACT_DELETE_SUCCESS = "删除了合同【{{#contractName}}】";
  85 + String CRM_CONTRACT_TRANSFER_SUB_TYPE = "转移合同";
  86 + String CRM_CONTRACT_TRANSFER_SUCCESS = "将合同【{{#contract.name}}】的负责人从【{getAdminUserById{#contract.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】";
  87 +
60 88
61 // ======================= CRM_PRODUCT 产品 ======================= 89 // ======================= CRM_PRODUCT 产品 =======================
62 90
@@ -79,9 +107,21 @@ public interface LogRecordConstants { @@ -79,9 +107,21 @@ public interface LogRecordConstants {
79 // ======================= CRM_RECEIVABLE 回款 ======================= 107 // ======================= CRM_RECEIVABLE 回款 =======================
80 108
81 String CRM_RECEIVABLE_TYPE = "CRM 回款"; 109 String CRM_RECEIVABLE_TYPE = "CRM 回款";
  110 + String CRM_RECEIVABLE_CREATE_SUB_TYPE = "创建回款";
  111 + String CRM_RECEIVABLE_CREATE_SUCCESS = "创建了合同【{" + GET_CONTRACT_BY_ID + "{#receivable.contractId}}】的第【{{#receivable.period}}】期回款";
  112 + String CRM_RECEIVABLE_UPDATE_SUB_TYPE = "更新回款";
  113 + String CRM_RECEIVABLE_UPDATE_SUCCESS = "更新了合同【{" + GET_CONTRACT_BY_ID + "{#receivable.contractId}}】的第【{{#receivable.period}}】期回款: {_DIFF{#updateReqVO}}";
  114 + String CRM_RECEIVABLE_DELETE_SUB_TYPE = "删除回款";
  115 + String CRM_RECEIVABLE_DELETE_SUCCESS = "删除了合同【{" + GET_CONTRACT_BY_ID + "{#receivable.contractId}}】的第【{{#receivable.period}}】期回款";
82 116
83 // ======================= CRM_RECEIVABLE_PLAN 回款计划 ======================= 117 // ======================= CRM_RECEIVABLE_PLAN 回款计划 =======================
84 118
85 String CRM_RECEIVABLE_PLAN_TYPE = "CRM 回款计划"; 119 String CRM_RECEIVABLE_PLAN_TYPE = "CRM 回款计划";
  120 + String CRM_RECEIVABLE_PLAN_CREATE_SUB_TYPE = "创建回款计划";
  121 + String CRM_RECEIVABLE_PLAN_CREATE_SUCCESS = "创建了合同【{" + GET_CONTRACT_BY_ID + "{#receivablePlan.contractId}}】的第【{{#receivablePlan.period}}】期回款计划";
  122 + String CRM_RECEIVABLE_PLAN_UPDATE_SUB_TYPE = "更新回款计划";
  123 + String CRM_RECEIVABLE_PLAN_UPDATE_SUCCESS = "更新了合同【{" + GET_CONTRACT_BY_ID + "{#receivablePlan.contractId}}】的第【{{#receivablePlan.period}}】期回款计划: {_DIFF{#updateReqVO}}";
  124 + String CRM_RECEIVABLE_PLAN_DELETE_SUB_TYPE = "删除回款计划";
  125 + String CRM_RECEIVABLE_PLAN_DELETE_SUCCESS = "删除了合同【{" + GET_CONTRACT_BY_ID + "{#receivablePlan.contractId}}】的第【{{#receivablePlan.period}}】期回款计划";
86 126
87 } 127 }
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/operatelog/CrmParseFunctionNameConstants.java
@@ -13,5 +13,6 @@ public interface CrmParseFunctionNameConstants { @@ -13,5 +13,6 @@ public interface CrmParseFunctionNameConstants {
13 String GET_CUSTOMER_INDUSTRY = "getCustomerIndustry"; // 获取客户行业信息 13 String GET_CUSTOMER_INDUSTRY = "getCustomerIndustry"; // 获取客户行业信息
14 String GET_CUSTOMER_LEVEL = "getCustomerLevel"; // 获取客户级别 14 String GET_CUSTOMER_LEVEL = "getCustomerLevel"; // 获取客户级别
15 String GET_CUSTOMER_SOURCE = "getCustomerSource"; // 获取客户来源 15 String GET_CUSTOMER_SOURCE = "getCustomerSource"; // 获取客户来源
  16 + String GET_CONTRACT_BY_ID = "getContractById"; // 获取合同信息
16 17
17 } 18 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java
@@ -7,7 +7,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -7,7 +7,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 7 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
8 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 8 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
9 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 9 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
10 -import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.*; 10 +import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableCreateReqVO;
  11 +import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
  12 +import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
  13 +import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO;
11 import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivableConvert; 14 import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivableConvert;
12 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 15 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
13 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 16 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
@@ -59,7 +62,7 @@ public class CrmReceivableController { @@ -59,7 +62,7 @@ public class CrmReceivableController {
59 @Operation(summary = "创建回款") 62 @Operation(summary = "创建回款")
60 @PreAuthorize("@ss.hasPermission('crm:receivable:create')") 63 @PreAuthorize("@ss.hasPermission('crm:receivable:create')")
61 public CommonResult<Long> createReceivable(@Valid @RequestBody CrmReceivableCreateReqVO createReqVO) { 64 public CommonResult<Long> createReceivable(@Valid @RequestBody CrmReceivableCreateReqVO createReqVO) {
62 - return success(receivableService.createReceivable(createReqVO)); 65 + return success(receivableService.createReceivable(createReqVO, getLoginUserId()));
63 } 66 }
64 67
65 @PutMapping("/update") 68 @PutMapping("/update")
@@ -141,12 +144,4 @@ public class CrmReceivableController { @@ -141,12 +144,4 @@ public class CrmReceivableController {
141 return CrmReceivableConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList); 144 return CrmReceivableConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList);
142 } 145 }
143 146
144 - @PutMapping("/transfer")  
145 - @Operation(summary = "回款转移")  
146 - @PreAuthorize("@ss.hasPermission('crm:receivable:update')")  
147 - public CommonResult<Boolean> transfer(@Valid @RequestBody CrmReceivableTransferReqVO reqVO) {  
148 - receivableService.transferReceivable(reqVO, getLoginUserId());  
149 - return success(true);  
150 - }  
151 -  
152 } 147 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java
@@ -7,7 +7,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -7,7 +7,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 7 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
8 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 8 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
9 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 9 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
10 -import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.*; 10 +import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanCreateReqVO;
  11 +import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO;
  12 +import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanRespVO;
  13 +import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanUpdateReqVO;
11 import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivablePlanConvert; 14 import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivablePlanConvert;
12 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 15 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
13 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 16 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
@@ -148,12 +151,4 @@ public class CrmReceivablePlanController { @@ -148,12 +151,4 @@ public class CrmReceivablePlanController {
148 return CrmReceivablePlanConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList, receivableList); 151 return CrmReceivablePlanConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList, receivableList);
149 } 152 }
150 153
151 - @PutMapping("/transfer")  
152 - @Operation(summary = "回款计划转移")  
153 - @PreAuthorize("@ss.hasPermission('crm:receivable-plan:update')")  
154 - public CommonResult<Boolean> transfer(@Valid @RequestBody CrmReceivablePlanTransferReqVO reqVO) {  
155 - receivablePlanService.transferReceivablePlan(reqVO, getLoginUserId());  
156 - return success(true);  
157 - }  
158 -  
159 } 154 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.service.business; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.service.business;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.collection.ListUtil; 4 import cn.hutool.core.collection.ListUtil;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessCreateReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessCreateReqVO;
7 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO; 8 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO;
8 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; 9 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO;
@@ -17,6 +18,9 @@ import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPerm @@ -17,6 +18,9 @@ import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPerm
17 import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService; 18 import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService;
18 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; 19 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
19 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 20 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
  21 +import com.mzt.logapi.context.LogRecordContext;
  22 +import com.mzt.logapi.service.impl.DiffParseFunction;
  23 +import com.mzt.logapi.starter.annotation.LogRecord;
20 import jakarta.annotation.Resource; 24 import jakarta.annotation.Resource;
21 import org.springframework.stereotype.Service; 25 import org.springframework.stereotype.Service;
22 import org.springframework.transaction.annotation.Transactional; 26 import org.springframework.transaction.annotation.Transactional;
@@ -28,6 +32,7 @@ import java.util.List; @@ -28,6 +32,7 @@ import java.util.List;
28 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 32 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
29 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 33 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
30 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_NOT_EXISTS; 34 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_NOT_EXISTS;
  35 +import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
31 36
32 /** 37 /**
33 * 商机 Service 实现类 38 * 商机 Service 实现类
@@ -48,7 +53,8 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -48,7 +53,8 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
48 53
49 @Override 54 @Override
50 @Transactional(rollbackFor = Exception.class) 55 @Transactional(rollbackFor = Exception.class)
51 - // TODO @商机待定:操作日志; 56 + @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_CREATE_SUB_TYPE, bizNo = "{{#business.id}}",
  57 + success = CRM_BUSINESS_CREATE_SUCCESS)
52 public Long createBusiness(CrmBusinessCreateReqVO createReqVO, Long userId) { 58 public Long createBusiness(CrmBusinessCreateReqVO createReqVO, Long userId) {
53 // 1. 插入商机 59 // 1. 插入商机
54 CrmBusinessDO business = CrmBusinessConvert.INSTANCE.convert(createReqVO); 60 CrmBusinessDO business = CrmBusinessConvert.INSTANCE.convert(createReqVO);
@@ -60,17 +66,20 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -60,17 +66,20 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
60 // 2. 创建数据权限 66 // 2. 创建数据权限
61 permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()) 67 permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType())
62 .setBizId(business.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 68 .setBizId(business.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
  69 +
  70 + // 4. 记录操作日志上下文
  71 + LogRecordContext.putVariable("business", business);
63 return business.getId(); 72 return business.getId();
64 } 73 }
65 74
66 @Override 75 @Override
67 @Transactional(rollbackFor = Exception.class) 76 @Transactional(rollbackFor = Exception.class)
68 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#updateReqVO.id",  
69 - level = CrmPermissionLevelEnum.WRITE)  
70 - // TODO @商机待定:操作日志; 77 + @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
  78 + success = CRM_BUSINESS_UPDATE_SUCCESS)
  79 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
71 public void updateBusiness(CrmBusinessUpdateReqVO updateReqVO) { 80 public void updateBusiness(CrmBusinessUpdateReqVO updateReqVO) {
72 // 1. 校验存在 81 // 1. 校验存在
73 - validateBusinessExists(updateReqVO.getId()); 82 + CrmBusinessDO oldBusiness = validateBusinessExists(updateReqVO.getId());
74 83
75 // 2. 更新商机 84 // 2. 更新商机
76 CrmBusinessDO updateObj = CrmBusinessConvert.INSTANCE.convert(updateReqVO); 85 CrmBusinessDO updateObj = CrmBusinessConvert.INSTANCE.convert(updateReqVO);
@@ -78,20 +87,28 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -78,20 +87,28 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
78 // TODO 商机待定:插入商机与产品的关联表;校验商品存在 87 // TODO 商机待定:插入商机与产品的关联表;校验商品存在
79 88
80 // TODO @商机待定:如果状态发生变化,插入商机状态变更记录表 89 // TODO @商机待定:如果状态发生变化,插入商机状态变更记录表
  90 + // 3. 记录操作日志上下文
  91 + LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldBusiness, CrmBusinessUpdateReqVO.class));
  92 + LogRecordContext.putVariable("businessName", oldBusiness.getName());
81 } 93 }
82 94
83 @Override 95 @Override
84 @Transactional(rollbackFor = Exception.class) 96 @Transactional(rollbackFor = Exception.class)
  97 + @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_DELETE_SUB_TYPE, bizNo = "{{#id}}",
  98 + success = CRM_BUSINESS_DELETE_SUCCESS)
85 @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) 99 @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
86 public void deleteBusiness(Long id) { 100 public void deleteBusiness(Long id) {
87 // 校验存在 101 // 校验存在
88 - validateBusinessExists(id); 102 + CrmBusinessDO business = validateBusinessExists(id);
89 // TODO @商机待定:需要校验有没关联合同。CrmContractDO 的 businessId 字段 103 // TODO @商机待定:需要校验有没关联合同。CrmContractDO 的 businessId 字段
90 104
91 // 删除 105 // 删除
92 businessMapper.deleteById(id); 106 businessMapper.deleteById(id);
93 // 删除数据权限 107 // 删除数据权限
94 permissionService.deletePermission(CrmBizTypeEnum.CRM_BUSINESS.getType(), id); 108 permissionService.deletePermission(CrmBizTypeEnum.CRM_BUSINESS.getType(), id);
  109 +
  110 + // 记录操作日志上下文
  111 + LogRecordContext.putVariable("businessName", business.getName());
95 } 112 }
96 113
97 private CrmBusinessDO validateBusinessExists(Long id) { 114 private CrmBusinessDO validateBusinessExists(Long id) {
@@ -102,6 +119,28 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -102,6 +119,28 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
102 return crmBusiness; 119 return crmBusiness;
103 } 120 }
104 121
  122 +
  123 + @Override
  124 + @Transactional(rollbackFor = Exception.class)
  125 + @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}",
  126 + success = CRM_BUSINESS_TRANSFER_SUCCESS)
  127 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER)
  128 + public void transferBusiness(CrmBusinessTransferReqVO reqVO, Long userId) {
  129 + // 1 校验商机是否存在
  130 + CrmBusinessDO business = validateBusinessExists(reqVO.getId());
  131 +
  132 + // 2.1 数据权限转移
  133 + permissionService.transferPermission(
  134 + CrmBusinessConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()));
  135 + // 2.2 设置新的负责人
  136 + businessMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
  137 +
  138 + // 记录操作日志上下文
  139 + LogRecordContext.putVariable("business", business);
  140 + }
  141 +
  142 + //======================= 查询相关 =======================
  143 +
105 @Override 144 @Override
106 @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.READ) 145 @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.READ)
107 public CrmBusinessDO getBusiness(Long id) { 146 public CrmBusinessDO getBusiness(Long id) {
@@ -141,18 +180,4 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -141,18 +180,4 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
141 convertSet(contactBusinessList, CrmContactBusinessDO::getBusinessId)); 180 convertSet(contactBusinessList, CrmContactBusinessDO::getBusinessId));
142 } 181 }
143 182
144 - @Override  
145 - @Transactional(rollbackFor = Exception.class)  
146 - // TODO @puhui999:操作日志  
147 - public void transferBusiness(CrmBusinessTransferReqVO reqVO, Long userId) {  
148 - // 1 校验商机是否存在  
149 - validateBusinessExists(reqVO.getId());  
150 -  
151 - // 2.1 数据权限转移  
152 - permissionService.transferPermission(  
153 - CrmBusinessConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()));  
154 - // 2.2 设置新的负责人  
155 - businessMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());  
156 - }  
157 -  
158 } 183 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java
@@ -33,7 +33,7 @@ import java.util.List; @@ -33,7 +33,7 @@ import java.util.List;
33 33
34 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 34 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
35 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; 35 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
36 -import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CONTACT_TYPE; 36 +import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
37 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS; 37 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS;
38 import static java.util.Collections.singletonList; 38 import static java.util.Collections.singletonList;
39 39
@@ -65,7 +65,8 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -65,7 +65,8 @@ public class CrmContactServiceImpl implements CrmContactService {
65 65
66 @Override 66 @Override
67 @Transactional(rollbackFor = Exception.class) 67 @Transactional(rollbackFor = Exception.class)
68 - @LogRecord(type = CRM_CONTACT_TYPE, subType = "创建联系人", bizNo = "{{#contactId}}", success = "创建了联系人[{{#contactName}}]") 68 + @LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_CREATE_SUB_TYPE, bizNo = "{{#contact.id}}",
  69 + success = CRM_CONTACT_CREATE_SUCCESS)
69 public Long createContact(CrmContactSaveReqVO createReqVO, Long userId) { 70 public Long createContact(CrmContactSaveReqVO createReqVO, Long userId) {
70 // 1. 校验 71 // 1. 校验
71 validateRelationDataExists(createReqVO); 72 validateRelationDataExists(createReqVO);
@@ -86,18 +87,18 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -86,18 +87,18 @@ public class CrmContactServiceImpl implements CrmContactService {
86 } 87 }
87 88
88 // 5. 记录操作日志 89 // 5. 记录操作日志
89 - LogRecordContext.putVariable("contactId", contact.getId());  
90 - LogRecordContext.putVariable("contactName", contact.getName()); 90 + LogRecordContext.putVariable("contact", contact);
91 return contact.getId(); 91 return contact.getId();
92 } 92 }
93 93
94 @Override 94 @Override
95 @Transactional(rollbackFor = Exception.class) 95 @Transactional(rollbackFor = Exception.class)
96 - @LogRecord(type = CRM_CONTACT_TYPE, subType = "更新联系人", bizNo = "{{#updateReqVO.id}}", success = "更新了联系人{_DIFF{#updateReqVO}}") 96 + @LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
  97 + success = CRM_CONTACT_UPDATE_SUCCESS)
97 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) 98 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
98 public void updateContact(CrmContactSaveReqVO updateReqVO) { 99 public void updateContact(CrmContactSaveReqVO updateReqVO) {
99 // 1. 校验存在 100 // 1. 校验存在
100 - CrmContactDO contactDO = validateContactExists(updateReqVO.getId()); 101 + CrmContactDO oldContact = validateContactExists(updateReqVO.getId());
101 validateRelationDataExists(updateReqVO); 102 validateRelationDataExists(updateReqVO);
102 103
103 // 2. 更新联系人 104 // 2. 更新联系人
@@ -105,7 +106,8 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -105,7 +106,8 @@ public class CrmContactServiceImpl implements CrmContactService {
105 contactMapper.updateById(updateObj); 106 contactMapper.updateById(updateObj);
106 107
107 // 3. 记录操作日志 108 // 3. 记录操作日志
108 - LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(contactDO, CrmContactSaveReqVO.class)); 109 + LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldContact, CrmContactSaveReqVO.class));
  110 + LogRecordContext.putVariable("contactName", oldContact.getName());
109 } 111 }
110 112
111 /** 113 /**
@@ -133,11 +135,13 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -133,11 +135,13 @@ public class CrmContactServiceImpl implements CrmContactService {
133 } 135 }
134 136
135 @Override 137 @Override
136 - @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)  
137 @Transactional(rollbackFor = Exception.class) 138 @Transactional(rollbackFor = Exception.class)
  139 + @LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_DELETE_SUB_TYPE, bizNo = "{{#id}}",
  140 + success = CRM_CONTACT_DELETE_SUCCESS)
  141 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
138 public void deleteContact(Long id) { 142 public void deleteContact(Long id) {
139 // 1.1 校验存在 143 // 1.1 校验存在
140 - validateContactExists(id); 144 + CrmContactDO contact = validateContactExists(id);
141 // 1.2 校验是否关联合同 145 // 1.2 校验是否关联合同
142 if (contractService.getContractCountByContactId(id) > 0) { 146 if (contractService.getContractCountByContactId(id) > 0) {
143 throw exception(CONTACT_DELETE_FAIL_CONTRACT_LINK_EXISTS); 147 throw exception(CONTACT_DELETE_FAIL_CONTRACT_LINK_EXISTS);
@@ -151,6 +155,9 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -151,6 +155,9 @@ public class CrmContactServiceImpl implements CrmContactService {
151 // 4.2 删除商机关联 155 // 4.2 删除商机关联
152 contactBusinessService.deleteContactBusinessByContactId(id); 156 contactBusinessService.deleteContactBusinessByContactId(id);
153 // TODO @puhui999:删除跟进记录 157 // TODO @puhui999:删除跟进记录
  158 +
  159 + // 记录操作日志上下文
  160 + LogRecordContext.putVariable("contactName", contact.getName());
154 } 161 }
155 162
156 private CrmContactDO validateContactExists(Long id) { 163 private CrmContactDO validateContactExists(Long id) {
@@ -162,6 +169,27 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -162,6 +169,27 @@ public class CrmContactServiceImpl implements CrmContactService {
162 } 169 }
163 170
164 @Override 171 @Override
  172 + @Transactional(rollbackFor = Exception.class)
  173 + @LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}",
  174 + success = CRM_CONTACT_TRANSFER_SUCCESS)
  175 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER)
  176 + public void transferContact(CrmContactTransferReqVO reqVO, Long userId) {
  177 + // 1 校验联系人是否存在
  178 + CrmContactDO contact = validateContactExists(reqVO.getId());
  179 +
  180 + // 2.1 数据权限转移
  181 + permissionService.transferPermission(
  182 + CrmContactConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTACT.getType()));
  183 + // 2.2 设置新的负责人
  184 + contactMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
  185 +
  186 + // 3. 记录转移日志
  187 + LogRecordContext.putVariable("contact", contact);
  188 + }
  189 +
  190 + //======================= 查询相关 =======================
  191 +
  192 + @Override
165 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.READ) 193 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.READ)
166 public CrmContactDO getContact(Long id) { 194 public CrmContactDO getContact(Long id) {
167 return contactMapper.selectById(id); 195 return contactMapper.selectById(id);
@@ -191,20 +219,4 @@ public class CrmContactServiceImpl implements CrmContactService { @@ -191,20 +219,4 @@ public class CrmContactServiceImpl implements CrmContactService {
191 return contactMapper.selectPageByCustomerId(pageVO); 219 return contactMapper.selectPageByCustomerId(pageVO);
192 } 220 }
193 221
194 - @Override  
195 - // TODO @puhui999:权限校验  
196 - // TODO @puhui999:记录操作日志;将联系人【名字】转移给【新负责人】  
197 - public void transferContact(CrmContactTransferReqVO reqVO, Long userId) {  
198 - // 1 校验联系人是否存在  
199 - validateContactExists(reqVO.getId());  
200 -  
201 - // 2.1 数据权限转移  
202 - permissionService.transferPermission(  
203 - CrmContactConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTACT.getType()));  
204 - // 2.2 设置新的负责人  
205 - contactMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());  
206 -  
207 - // 3. TODO 记录转移日志  
208 - }  
209 -  
210 } 222 }
211 \ No newline at end of file 223 \ No newline at end of file
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.service.contract; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.service.contract;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.collection.ListUtil; 4 import cn.hutool.core.collection.ListUtil;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractCreateReqVO; 7 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractCreateReqVO;
7 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; 8 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
8 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; 9 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO;
@@ -15,6 +16,9 @@ import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; @@ -15,6 +16,9 @@ import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
15 import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; 16 import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission;
16 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; 17 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
17 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 18 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
  19 +import com.mzt.logapi.context.LogRecordContext;
  20 +import com.mzt.logapi.service.impl.DiffParseFunction;
  21 +import com.mzt.logapi.starter.annotation.LogRecord;
18 import jakarta.annotation.Resource; 22 import jakarta.annotation.Resource;
19 import org.springframework.stereotype.Service; 23 import org.springframework.stereotype.Service;
20 import org.springframework.transaction.annotation.Transactional; 24 import org.springframework.transaction.annotation.Transactional;
@@ -25,6 +29,7 @@ import java.util.List; @@ -25,6 +29,7 @@ import java.util.List;
25 29
26 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 30 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
27 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CONTRACT_NOT_EXISTS; 31 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CONTRACT_NOT_EXISTS;
  32 +import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
28 33
29 /** 34 /**
30 * CRM 合同 Service 实现类 35 * CRM 合同 Service 实现类
@@ -42,7 +47,9 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -42,7 +47,9 @@ public class CrmContractServiceImpl implements CrmContractService {
42 private CrmPermissionService crmPermissionService; 47 private CrmPermissionService crmPermissionService;
43 48
44 @Override 49 @Override
45 - // TODO @puhui999:添加操作日志 50 + @Transactional(rollbackFor = Exception.class)
  51 + @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_CREATE_SUB_TYPE, bizNo = "{{#contract.id}}",
  52 + success = CRM_CONTRACT_CREATE_SUCCESS)
46 public Long createContract(CrmContractCreateReqVO createReqVO, Long userId) { 53 public Long createContract(CrmContractCreateReqVO createReqVO, Long userId) {
47 // TODO @合同待定:插入合同商品;需要搞个 BusinessProductDO 54 // TODO @合同待定:插入合同商品;需要搞个 BusinessProductDO
48 // 插入合同 55 // 插入合同
@@ -53,38 +60,52 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -53,38 +60,52 @@ public class CrmContractServiceImpl implements CrmContractService {
53 crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId) 60 crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId)
54 .setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()).setBizId(contract.getId()) 61 .setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()).setBizId(contract.getId())
55 .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); 62 .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
  63 +
  64 + // 4. 记录操作日志上下文
  65 + LogRecordContext.putVariable("contract", contract);
56 return contract.getId(); 66 return contract.getId();
57 } 67 }
58 68
59 @Override 69 @Override
60 @Transactional(rollbackFor = Exception.class) 70 @Transactional(rollbackFor = Exception.class)
  71 + @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
  72 + success = CRM_CONTRACT_UPDATE_SUCCESS)
61 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) 73 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
62 - // TODO @puhui999:添加操作日志  
63 public void updateContract(CrmContractUpdateReqVO updateReqVO) { 74 public void updateContract(CrmContractUpdateReqVO updateReqVO) {
64 // TODO @合同待定:只有草稿、审批中,可以编辑; 75 // TODO @合同待定:只有草稿、审批中,可以编辑;
65 // 校验存在 76 // 校验存在
66 - validateContractExists(updateReqVO.getId()); 77 + CrmContractDO oldContract = validateContractExists(updateReqVO.getId());
67 // 更新合同 78 // 更新合同
68 CrmContractDO updateObj = CrmContractConvert.INSTANCE.convert(updateReqVO); 79 CrmContractDO updateObj = CrmContractConvert.INSTANCE.convert(updateReqVO);
69 contractMapper.updateById(updateObj); 80 contractMapper.updateById(updateObj);
70 // TODO @合同待定:插入合同商品;需要搞个 BusinessProductDO 81 // TODO @合同待定:插入合同商品;需要搞个 BusinessProductDO
  82 +
  83 + // 3. 记录操作日志上下文
  84 + LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldContract, CrmContractUpdateReqVO.class));
  85 + LogRecordContext.putVariable("contractName", oldContract.getName());
71 } 86 }
72 87
73 // TODO @合同待定:缺一个取消合同的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum 88 // TODO @合同待定:缺一个取消合同的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum
74 89
75 // TODO @合同待定:缺一个发起审批的接口;只有草稿可以发起审批;CrmAuditStatusEnum 90 // TODO @合同待定:缺一个发起审批的接口;只有草稿可以发起审批;CrmAuditStatusEnum
76 91
  92 +
77 @Override 93 @Override
78 @Transactional(rollbackFor = Exception.class) 94 @Transactional(rollbackFor = Exception.class)
  95 + @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_DELETE_SUB_TYPE, bizNo = "{{#id}}",
  96 + success = CRM_CONTRACT_DELETE_SUCCESS)
79 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) 97 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
80 public void deleteContract(Long id) { 98 public void deleteContract(Long id) {
81 // TODO @合同待定:如果被 CrmReceivableDO 所使用,则不允许删除 99 // TODO @合同待定:如果被 CrmReceivableDO 所使用,则不允许删除
82 // 校验存在 100 // 校验存在
83 - validateContractExists(id); 101 + CrmContractDO contract = validateContractExists(id);
84 // 删除 102 // 删除
85 contractMapper.deleteById(id); 103 contractMapper.deleteById(id);
86 // 删除数据权限 104 // 删除数据权限
87 crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CONTRACT.getType(), id); 105 crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CONTRACT.getType(), id);
  106 +
  107 + // 记录操作日志上下文
  108 + LogRecordContext.putVariable("contractName", contract.getName());
88 } 109 }
89 110
90 private CrmContractDO validateContractExists(Long id) { 111 private CrmContractDO validateContractExists(Long id) {
@@ -96,6 +117,27 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -96,6 +117,27 @@ public class CrmContractServiceImpl implements CrmContractService {
96 } 117 }
97 118
98 @Override 119 @Override
  120 + @Transactional(rollbackFor = Exception.class)
  121 + @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}",
  122 + success = CRM_CONTRACT_TRANSFER_SUCCESS)
  123 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER)
  124 + public void transferContract(CrmContractTransferReqVO reqVO, Long userId) {
  125 + // 1. 校验合同是否存在
  126 + CrmContractDO contract = validateContractExists(reqVO.getId());
  127 +
  128 + // 2.1 数据权限转移
  129 + crmPermissionService.transferPermission(
  130 + CrmContractConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()));
  131 + // 2.2 设置负责人
  132 + contractMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
  133 +
  134 + // 3. 记录转移日志
  135 + LogRecordContext.putVariable("contract", contract);
  136 + }
  137 +
  138 + //======================= 查询相关 =======================
  139 +
  140 + @Override
99 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.READ) 141 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.READ)
100 public CrmContractDO getContract(Long id) { 142 public CrmContractDO getContract(Long id) {
101 return contractMapper.selectById(id); 143 return contractMapper.selectById(id);
@@ -121,21 +163,6 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -121,21 +163,6 @@ public class CrmContractServiceImpl implements CrmContractService {
121 } 163 }
122 164
123 @Override 165 @Override
124 - @Transactional(rollbackFor = Exception.class)  
125 - // 3. TODO @puhui999:记录转移日志  
126 - // TODO @puhui999:权限校验,这里要搞哇?  
127 - public void transferContract(CrmContractTransferReqVO reqVO, Long userId) {  
128 - // 1. 校验合同是否存在  
129 - validateContractExists(reqVO.getId());  
130 -  
131 - // 2.1 数据权限转移  
132 - crmPermissionService.transferPermission(  
133 - CrmContractConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()));  
134 - // 2.2 设置负责人  
135 - contractMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());  
136 - }  
137 -  
138 - @Override  
139 public Long getContractCountByContactId(Long contactId) { 166 public Long getContractCountByContactId(Long contactId) {
140 return contractMapper.selectCountByContactId(contactId); 167 return contractMapper.selectCountByContactId(contactId);
141 } 168 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
@@ -145,10 +145,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -145,10 +145,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
145 // 2.2 转移后重新设置负责人 145 // 2.2 转移后重新设置负责人
146 customerMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); 146 customerMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
147 147
148 - // 3. TODO 记录转移日志  
149 - // 记录操作日志上下文  
150 - // TODO @puhui999:crmCustomer=》customer,也看看其他有没类似的情况哈  
151 - LogRecordContext.putVariable("crmCustomer", customer); 148 + // 3. 记录转移日志
  149 + LogRecordContext.putVariable("customer", customer);
152 } 150 }
153 151
154 @Override 152 @Override
@@ -172,7 +170,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -172,7 +170,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
172 170
173 // 3. 记录操作日志上下文 171 // 3. 记录操作日志上下文
174 // tips: 因为这里使用的是老的状态所以记录时反着记录,也就是 lockStatus 为 true 那么就是解锁反之为锁定 172 // tips: 因为这里使用的是老的状态所以记录时反着记录,也就是 lockStatus 为 true 那么就是解锁反之为锁定
175 - LogRecordContext.putVariable("crmCustomer", customer); 173 + LogRecordContext.putVariable("customer", customer);
176 } 174 }
177 175
178 // ==================== 公海相关操作 ==================== 176 // ==================== 公海相关操作 ====================
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanService.java
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.crm.service.receivable; @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.crm.service.receivable;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanCreateReqVO; 4 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanCreateReqVO;
5 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO;
6 -import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanTransferReqVO;  
7 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanUpdateReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanUpdateReqVO;
8 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
9 import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO;
@@ -78,12 +77,4 @@ public interface CrmReceivablePlanService { @@ -78,12 +77,4 @@ public interface CrmReceivablePlanService {
78 */ 77 */
79 PageResult<CrmReceivablePlanDO> getReceivablePlanPageByCustomerId(CrmReceivablePlanPageReqVO pageReqVO); 78 PageResult<CrmReceivablePlanDO> getReceivablePlanPageByCustomerId(CrmReceivablePlanPageReqVO pageReqVO);
80 79
81 - /**  
82 - * 回款计划转移  
83 - *  
84 - * @param reqVO 请求  
85 - * @param userId 用户编号  
86 - */  
87 - void transferReceivablePlan(CrmReceivablePlanTransferReqVO reqVO, Long userId);  
88 -  
89 } 80 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java
@@ -4,9 +4,9 @@ import cn.hutool.core.collection.CollUtil; @@ -4,9 +4,9 @@ import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.collection.ListUtil; 4 import cn.hutool.core.collection.ListUtil;
5 import cn.hutool.core.util.ObjectUtil; 5 import cn.hutool.core.util.ObjectUtil;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanCreateReqVO; 8 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanCreateReqVO;
8 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO; 9 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO;
9 -import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanTransferReqVO;  
10 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanUpdateReqVO; 10 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanUpdateReqVO;
11 import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivablePlanConvert; 11 import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivablePlanConvert;
12 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 12 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
@@ -20,6 +20,9 @@ import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; @@ -20,6 +20,9 @@ import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
20 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; 20 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
21 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; 21 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
22 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 22 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
  23 +import com.mzt.logapi.context.LogRecordContext;
  24 +import com.mzt.logapi.service.impl.DiffParseFunction;
  25 +import com.mzt.logapi.starter.annotation.LogRecord;
23 import jakarta.annotation.Resource; 26 import jakarta.annotation.Resource;
24 import org.springframework.stereotype.Service; 27 import org.springframework.stereotype.Service;
25 import org.springframework.validation.annotation.Validated; 28 import org.springframework.validation.annotation.Validated;
@@ -29,6 +32,7 @@ import java.util.List; @@ -29,6 +32,7 @@ import java.util.List;
29 32
30 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 33 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
31 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; 34 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
  35 +import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
32 36
33 // TODO @liuhongfeng:参考 CrmReceivableServiceImpl 写的 todo 哈; 37 // TODO @liuhongfeng:参考 CrmReceivableServiceImpl 写的 todo 哈;
34 38
@@ -49,10 +53,11 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { @@ -49,10 +53,11 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
49 @Resource 53 @Resource
50 private CrmCustomerService customerService; 54 private CrmCustomerService customerService;
51 @Resource 55 @Resource
52 - private CrmPermissionService crmPermissionService; 56 + private CrmPermissionService permissionService;
53 57
54 @Override 58 @Override
55 - // TODO @puhui999:操作日志 59 + @LogRecord(type = CRM_RECEIVABLE_PLAN_TYPE, subType = CRM_RECEIVABLE_PLAN_CREATE_SUB_TYPE, bizNo = "{{#receivablePlan.id}}",
  60 + success = CRM_RECEIVABLE_PLAN_CREATE_SUCCESS)
56 public Long createReceivablePlan(CrmReceivablePlanCreateReqVO createReqVO, Long userId) { 61 public Long createReceivablePlan(CrmReceivablePlanCreateReqVO createReqVO, Long userId) {
57 // TODO @liuhongfeng:第几期的计算;基于是 contractId + contractDO 的第几个还款 62 // TODO @liuhongfeng:第几期的计算;基于是 contractId + contractDO 的第几个还款
58 // TODO @liuhongfeng contractId:校验合同是否存在 63 // TODO @liuhongfeng contractId:校验合同是否存在
@@ -64,9 +69,12 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { @@ -64,9 +69,12 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
64 69
65 receivablePlanMapper.insert(receivablePlan); 70 receivablePlanMapper.insert(receivablePlan);
66 // 创建数据权限 71 // 创建数据权限
67 - crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId) 72 + permissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId)
68 .setBizType(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType()).setBizId(receivablePlan.getId()) 73 .setBizType(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType()).setBizId(receivablePlan.getId())
69 .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); 74 .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
  75 +
  76 + // 4. 记录操作日志上下文
  77 + LogRecordContext.putVariable("receivablePlan", receivablePlan);
70 return receivablePlan.getId(); 78 return receivablePlan.getId();
71 } 79 }
72 80
@@ -89,31 +97,44 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { @@ -89,31 +97,44 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
89 } 97 }
90 98
91 @Override 99 @Override
  100 + @LogRecord(type = CRM_RECEIVABLE_PLAN_TYPE, subType = CRM_RECEIVABLE_PLAN_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
  101 + success = CRM_RECEIVABLE_PLAN_UPDATE_SUCCESS)
92 @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) 102 @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
93 - // TODO @puhui999:操作日志  
94 public void updateReceivablePlan(CrmReceivablePlanUpdateReqVO updateReqVO) { 103 public void updateReceivablePlan(CrmReceivablePlanUpdateReqVO updateReqVO) {
95 // TODO @liuhongfeng:如果已经有对应的还款,则不允许编辑; 104 // TODO @liuhongfeng:如果已经有对应的还款,则不允许编辑;
96 // 校验存在 105 // 校验存在
97 - validateReceivablePlanExists(updateReqVO.getId()); 106 + CrmReceivablePlanDO oldReceivablePlan = validateReceivablePlanExists(updateReqVO.getId());
98 107
99 // 更新 108 // 更新
100 CrmReceivablePlanDO updateObj = CrmReceivablePlanConvert.INSTANCE.convert(updateReqVO); 109 CrmReceivablePlanDO updateObj = CrmReceivablePlanConvert.INSTANCE.convert(updateReqVO);
101 receivablePlanMapper.updateById(updateObj); 110 receivablePlanMapper.updateById(updateObj);
  111 +
  112 + // 3. 记录操作日志上下文
  113 + LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldReceivablePlan, CrmReceivablePlanUpdateReqVO.class));
  114 + LogRecordContext.putVariable("receivablePlan", oldReceivablePlan);
102 } 115 }
103 116
104 @Override 117 @Override
  118 + @LogRecord(type = CRM_RECEIVABLE_PLAN_TYPE, subType = CRM_RECEIVABLE_PLAN_DELETE_SUB_TYPE, bizNo = "{{#id}}",
  119 + success = CRM_RECEIVABLE_PLAN_DELETE_SUCCESS)
105 @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) 120 @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
106 public void deleteReceivablePlan(Long id) { 121 public void deleteReceivablePlan(Long id) {
107 // 校验存在 122 // 校验存在
108 - validateReceivablePlanExists(id); 123 + CrmReceivablePlanDO receivablePlan = validateReceivablePlanExists(id);
109 // 删除 124 // 删除
110 receivablePlanMapper.deleteById(id); 125 receivablePlanMapper.deleteById(id);
  126 + // 删除数据权限
  127 + permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id);
  128 + // 记录操作日志上下文
  129 + LogRecordContext.putVariable("receivablePlan", receivablePlan);
111 } 130 }
112 131
113 - private void validateReceivablePlanExists(Long id) {  
114 - if (receivablePlanMapper.selectById(id) == null) { 132 + private CrmReceivablePlanDO validateReceivablePlanExists(Long id) {
  133 + CrmReceivablePlanDO receivablePlan = receivablePlanMapper.selectById(id);
  134 + if (receivablePlan == null) {
115 throw exception(RECEIVABLE_PLAN_NOT_EXISTS); 135 throw exception(RECEIVABLE_PLAN_NOT_EXISTS);
116 } 136 }
  137 + return receivablePlan;
117 } 138 }
118 139
119 @Override 140 @Override
@@ -141,19 +162,4 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { @@ -141,19 +162,4 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
141 return receivablePlanMapper.selectPageByCustomerId(pageReqVO); 162 return receivablePlanMapper.selectPageByCustomerId(pageReqVO);
142 } 163 }
143 164
144 - // TODO @puhui999:这个没有 transfer 接口;可能是的哈  
145 - @Override  
146 - public void transferReceivablePlan(CrmReceivablePlanTransferReqVO reqVO, Long userId) {  
147 - // 1 校验回款计划是否存在  
148 - validateReceivablePlanExists(reqVO.getId());  
149 -  
150 - // 2.1 数据权限转移  
151 - crmPermissionService.transferPermission(  
152 - CrmReceivablePlanConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType()));  
153 - // 2.2 设置新的负责人  
154 - receivablePlanMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());  
155 -  
156 - // 3. TODO 记录转移日志  
157 - }  
158 -  
159 } 165 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.crm.service.receivable; @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.crm.service.receivable;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableCreateReqVO; 4 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableCreateReqVO;
5 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO; 5 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
6 -import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableTransferReqVO;  
7 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO; 6 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO;
8 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
9 import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO; 8 import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
@@ -23,9 +22,10 @@ public interface CrmReceivableService { @@ -23,9 +22,10 @@ public interface CrmReceivableService {
23 * 创建回款 22 * 创建回款
24 * 23 *
25 * @param createReqVO 创建信息 24 * @param createReqVO 创建信息
  25 + * @param userId 用户编号
26 * @return 编号 26 * @return 编号
27 */ 27 */
28 - Long createReceivable(@Valid CrmReceivableCreateReqVO createReqVO); 28 + Long createReceivable(@Valid CrmReceivableCreateReqVO createReqVO, Long userId);
29 29
30 /** 30 /**
31 * 更新回款 31 * 更新回款
@@ -78,12 +78,4 @@ public interface CrmReceivableService { @@ -78,12 +78,4 @@ public interface CrmReceivableService {
78 */ 78 */
79 PageResult<CrmReceivableDO> getReceivablePageByCustomerId(CrmReceivablePageReqVO pageReqVO); 79 PageResult<CrmReceivableDO> getReceivablePageByCustomerId(CrmReceivablePageReqVO pageReqVO);
80 80
81 - /**  
82 - * 回款转移  
83 - *  
84 - * @param reqVO 请求  
85 - * @param userId 用户编号  
86 - */  
87 - void transferReceivable(CrmReceivableTransferReqVO reqVO, Long userId);  
88 -  
89 } 81 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java
@@ -5,9 +5,9 @@ import cn.hutool.core.collection.ListUtil; @@ -5,9 +5,9 @@ import cn.hutool.core.collection.ListUtil;
5 import cn.hutool.core.util.ObjectUtil; 5 import cn.hutool.core.util.ObjectUtil;
6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
7 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  8 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
8 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableCreateReqVO; 9 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableCreateReqVO;
9 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO; 10 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
10 -import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableTransferReqVO;  
11 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO; 11 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO;
12 import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivableConvert; 12 import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivableConvert;
13 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 13 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
@@ -22,6 +22,10 @@ import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPerm @@ -22,6 +22,10 @@ import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPerm
22 import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; 22 import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
23 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; 23 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
24 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; 24 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
  25 +import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
  26 +import com.mzt.logapi.context.LogRecordContext;
  27 +import com.mzt.logapi.service.impl.DiffParseFunction;
  28 +import com.mzt.logapi.starter.annotation.LogRecord;
25 import jakarta.annotation.Resource; 29 import jakarta.annotation.Resource;
26 import org.springframework.stereotype.Service; 30 import org.springframework.stereotype.Service;
27 import org.springframework.validation.annotation.Validated; 31 import org.springframework.validation.annotation.Validated;
@@ -31,6 +35,7 @@ import java.util.List; @@ -31,6 +35,7 @@ import java.util.List;
31 35
32 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 36 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
33 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; 37 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
  38 +import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
34 39
35 /** 40 /**
36 * CRM 回款 Service 实现类 41 * CRM 回款 Service 实现类
@@ -51,11 +56,12 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -51,11 +56,12 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
51 @Resource 56 @Resource
52 private CrmReceivablePlanService receivablePlanService; 57 private CrmReceivablePlanService receivablePlanService;
53 @Resource 58 @Resource
54 - private CrmPermissionService crmPermissionService; 59 + private CrmPermissionService permissionService;
55 60
56 @Override 61 @Override
57 - // TODO @puhui999:操作日志  
58 - public Long createReceivable(CrmReceivableCreateReqVO createReqVO) { 62 + @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_CREATE_SUB_TYPE, bizNo = "{{#receivable.id}}",
  63 + success = CRM_RECEIVABLE_CREATE_SUCCESS)
  64 + public Long createReceivable(CrmReceivableCreateReqVO createReqVO, Long userId) {
59 // 插入还款 65 // 插入还款
60 CrmReceivableDO receivable = CrmReceivableConvert.INSTANCE.convert(createReqVO); 66 CrmReceivableDO receivable = CrmReceivableConvert.INSTANCE.convert(createReqVO);
61 if (ObjectUtil.isNull(receivable.getAuditStatus())) { 67 if (ObjectUtil.isNull(receivable.getAuditStatus())) {
@@ -67,8 +73,12 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -67,8 +73,12 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
67 checkReceivable(receivable); 73 checkReceivable(receivable);
68 74
69 receivableMapper.insert(receivable); 75 receivableMapper.insert(receivable);
70 - 76 + // 3. 创建数据权限
  77 + permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_RECEIVABLE.getType())
  78 + .setBizId(receivable.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
71 // TODO @liuhongfeng:需要更新关联的 plan 79 // TODO @liuhongfeng:需要更新关联的 plan
  80 + // 记录操作日志上下文
  81 + LogRecordContext.putVariable("receivable", receivable);
72 return receivable.getId(); 82 return receivable.getId();
73 } 83 }
74 84
@@ -98,11 +108,12 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -98,11 +108,12 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
98 } 108 }
99 109
100 @Override 110 @Override
101 - // TODO @puhui999:操作日志  
102 - // TODO @puhui999:权限校验 111 + @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
  112 + success = CRM_RECEIVABLE_UPDATE_SUCCESS)
  113 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
103 public void updateReceivable(CrmReceivableUpdateReqVO updateReqVO) { 114 public void updateReceivable(CrmReceivableUpdateReqVO updateReqVO) {
104 // 校验存在 115 // 校验存在
105 - validateReceivableExists(updateReqVO.getId()); 116 + CrmReceivableDO oldReceivable = validateReceivableExists(updateReqVO.getId());
106 // TODO @liuhongfeng:只有在草稿、审核中,可以提交修改 117 // TODO @liuhongfeng:只有在草稿、审核中,可以提交修改
107 118
108 // 更新还款 119 // 更新还款
@@ -110,6 +121,9 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -110,6 +121,9 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
110 receivableMapper.updateById(updateObj); 121 receivableMapper.updateById(updateObj);
111 122
112 // TODO @liuhongfeng:需要更新关联的 plan 123 // TODO @liuhongfeng:需要更新关联的 plan
  124 + // 3. 记录操作日志上下文
  125 + LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldReceivable, CrmReceivableUpdateReqVO.class));
  126 + LogRecordContext.putVariable("receivable", oldReceivable);
113 } 127 }
114 128
115 // TODO @liuhongfeng:缺一个取消合同的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum 129 // TODO @liuhongfeng:缺一个取消合同的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum
@@ -117,24 +131,33 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -117,24 +131,33 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
117 // TODO @liuhongfeng:缺一个发起审批的接口;只有草稿可以发起审批;CrmAuditStatusEnum 131 // TODO @liuhongfeng:缺一个发起审批的接口;只有草稿可以发起审批;CrmAuditStatusEnum
118 132
119 @Override 133 @Override
120 - // TODO @puhui999:操作日志  
121 - // TODO @puhui999:权限校验 134 + @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_DELETE_SUB_TYPE, bizNo = "{{#id}}",
  135 + success = CRM_RECEIVABLE_DELETE_SUCCESS)
  136 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
122 public void deleteReceivable(Long id) { 137 public void deleteReceivable(Long id) {
123 // TODO @liuhongfeng:如果被 CrmReceivablePlanDO 所使用,则不允许删除 138 // TODO @liuhongfeng:如果被 CrmReceivablePlanDO 所使用,则不允许删除
124 // 校验存在 139 // 校验存在
125 - validateReceivableExists(id); 140 + CrmReceivableDO receivable = validateReceivableExists(id);
126 // 删除 141 // 删除
127 receivableMapper.deleteById(id); 142 receivableMapper.deleteById(id);
  143 +
  144 + // 删除数据权限
  145 + permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id);
  146 +
  147 + // 记录操作日志上下文
  148 + LogRecordContext.putVariable("receivable", receivable);
128 } 149 }
129 150
130 - private void validateReceivableExists(Long id) {  
131 - if (receivableMapper.selectById(id) == null) { 151 + private CrmReceivableDO validateReceivableExists(Long id) {
  152 + CrmReceivableDO receivable = receivableMapper.selectById(id);
  153 + if (receivable == null) {
132 throw exception(RECEIVABLE_NOT_EXISTS); 154 throw exception(RECEIVABLE_NOT_EXISTS);
133 } 155 }
  156 + return receivable;
134 } 157 }
135 158
136 - // TODO @芋艿:数据权限  
137 @Override 159 @Override
  160 + @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE, bizId = "#id", level = CrmPermissionLevelEnum.READ)
138 public CrmReceivableDO getReceivable(Long id) { 161 public CrmReceivableDO getReceivable(Long id) {
139 return receivableMapper.selectById(id); 162 return receivableMapper.selectById(id);
140 } 163 }
@@ -158,18 +181,4 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -158,18 +181,4 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
158 return receivableMapper.selectPageByCustomerId(pageReqVO); 181 return receivableMapper.selectPageByCustomerId(pageReqVO);
159 } 182 }
160 183
161 - @Override  
162 - public void transferReceivable(CrmReceivableTransferReqVO reqVO, Long userId) {  
163 - // 1 校验回款是否存在  
164 - validateReceivableExists(reqVO.getId());  
165 -  
166 - // 2.1 数据权限转移  
167 - crmPermissionService.transferPermission(  
168 - CrmReceivableConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_RECEIVABLE.getType()));  
169 - // 2.2 设置新的负责人  
170 - receivableMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());  
171 -  
172 - // 3. TODO 记录转移日志  
173 - }  
174 -  
175 } 184 }
yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/receivable/CrmCrmReceivableServiceImplTest.java
@@ -13,6 +13,7 @@ import org.junit.jupiter.api.Test; @@ -13,6 +13,7 @@ import org.junit.jupiter.api.Test;
13 import org.springframework.context.annotation.Import; 13 import org.springframework.context.annotation.Import;
14 14
15 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; 15 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  16 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
16 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; 17 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
17 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; 18 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
18 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; 19 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
@@ -42,7 +43,7 @@ public class CrmCrmReceivableServiceImplTest extends BaseDbUnitTest { @@ -42,7 +43,7 @@ public class CrmCrmReceivableServiceImplTest extends BaseDbUnitTest {
42 CrmReceivableCreateReqVO reqVO = randomPojo(CrmReceivableCreateReqVO.class); 43 CrmReceivableCreateReqVO reqVO = randomPojo(CrmReceivableCreateReqVO.class);
43 44
44 // 调用 45 // 调用
45 - Long receivableId = receivableService.createReceivable(reqVO); 46 + Long receivableId = receivableService.createReceivable(reqVO, getLoginUserId());
46 // 断言 47 // 断言
47 assertNotNull(receivableId); 48 assertNotNull(receivableId);
48 // 校验记录的属性是否正确 49 // 校验记录的属性是否正确