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

This commit is contained in:
puhui999 2024-01-10 15:28:53 +08:00
parent 9bba1ce8a4
commit 1a5fe6fa9a
13 changed files with 255 additions and 163 deletions

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.crm.enums; package cn.iocoder.yudao.module.crm.enums;
import static cn.iocoder.yudao.module.crm.enums.operatelog.CrmParseFunctionNameConstants.GET_CONTRACT_BY_ID;
/** /**
* CRM 操作日志枚举 * CRM 操作日志枚举
* 目的统一管理也减少 Service 里各种复杂字符串 * 目的统一管理也减少 Service 里各种复杂字符串
@ -22,9 +24,9 @@ public interface LogRecordConstants {
String CRM_CUSTOMER_DELETE_SUB_TYPE = "删除客户"; String CRM_CUSTOMER_DELETE_SUB_TYPE = "删除客户";
String CRM_CUSTOMER_DELETE_SUCCESS = "删除了客户【{{#customerName}}】"; String CRM_CUSTOMER_DELETE_SUCCESS = "删除了客户【{{#customerName}}】";
String CRM_CUSTOMER_TRANSFER_SUB_TYPE = "转移客户"; String CRM_CUSTOMER_TRANSFER_SUB_TYPE = "转移客户";
String CRM_CUSTOMER_TRANSFER_SUCCESS = "将客户【{{#crmCustomer.name}}】的负责人从【{getAdminUserById{#crmCustomer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; String CRM_CUSTOMER_TRANSFER_SUCCESS = "将客户【{{#customer.name}}】的负责人从【{getAdminUserById{#customer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】";
String CRM_CUSTOMER_LOCK_SUB_TYPE = "{{#crmCustomer.lockStatus ? '解锁客户' : '锁定客户'}}"; String CRM_CUSTOMER_LOCK_SUB_TYPE = "{{#customer.lockStatus ? '解锁客户' : '锁定客户'}}";
String CRM_CUSTOMER_LOCK_SUCCESS = "{{#crmCustomer.lockStatus ? '将客户【' + #crmCustomer.name + '】解锁' : '将客户【' + #crmCustomer.name + '】锁定'}}"; String CRM_CUSTOMER_LOCK_SUCCESS = "{{#customer.lockStatus ? '将客户【' + #customer.name + '】解锁' : '将客户【' + #customer.name + '】锁定'}}";
String CRM_CUSTOMER_POOL_SUB_TYPE = "客户放入公海"; String CRM_CUSTOMER_POOL_SUB_TYPE = "客户放入公海";
String CRM_CUSTOMER_POOL_SUCCESS = "将客户【{{#customerName}}】放入了公海"; String CRM_CUSTOMER_POOL_SUCCESS = "将客户【{{#customerName}}】放入了公海";
String CRM_CUSTOMER_RECEIVE_SUB_TYPE = "{{#ownerUserName != null ? '分配客户' : '领取客户'}}"; String CRM_CUSTOMER_RECEIVE_SUB_TYPE = "{{#ownerUserName != null ? '分配客户' : '领取客户'}}";
@ -49,14 +51,40 @@ public interface LogRecordConstants {
// ======================= CRM_CONTACT 联系人 ======================= // ======================= CRM_CONTACT 联系人 =======================
String CRM_CONTACT_TYPE = "CRM 联系人"; String CRM_CONTACT_TYPE = "CRM 联系人";
String CRM_CONTACT_CREATE_SUB_TYPE = "创建联系人";
String CRM_CONTACT_CREATE_SUCCESS = "创建了联系人{{#contact.name}}";
String CRM_CONTACT_UPDATE_SUB_TYPE = "更新联系人";
String CRM_CONTACT_UPDATE_SUCCESS = "更新了联系人【{{#contactName}}】: {_DIFF{#updateReqVO}}";
String CRM_CONTACT_DELETE_SUB_TYPE = "删除联系人";
String CRM_CONTACT_DELETE_SUCCESS = "删除了联系人【{{#contactName}}】";
String CRM_CONTACT_TRANSFER_SUB_TYPE = "转移联系人";
String CRM_CONTACT_TRANSFER_SUCCESS = "将联系人【{{#contact.name}}】的负责人从【{getAdminUserById{#contact.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】";
// ======================= CRM_BUSINESS 商机 ======================= // ======================= CRM_BUSINESS 商机 =======================
String CRM_BUSINESS_TYPE = "CRM 商机"; String CRM_BUSINESS_TYPE = "CRM 商机";
String CRM_BUSINESS_CREATE_SUB_TYPE = "创建商机";
String CRM_BUSINESS_CREATE_SUCCESS = "创建了商机{{#business.name}}";
String CRM_BUSINESS_UPDATE_SUB_TYPE = "更新商机";
String CRM_BUSINESS_UPDATE_SUCCESS = "更新了商机【{{#businessName}}】: {_DIFF{#updateReqVO}}";
String CRM_BUSINESS_DELETE_SUB_TYPE = "删除商机";
String CRM_BUSINESS_DELETE_SUCCESS = "删除了商机【{{#businessName}}】";
String CRM_BUSINESS_TRANSFER_SUB_TYPE = "转移商机";
String CRM_BUSINESS_TRANSFER_SUCCESS = "将商机【{{#business.name}}】的负责人从【{getAdminUserById{#business.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】";
// ======================= CRM_CONTRACT 合同 ======================= // ======================= CRM_CONTRACT 合同 =======================
String CRM_CONTRACT_TYPE = "CRM 合同"; String CRM_CONTRACT_TYPE = "CRM 合同";
String CRM_CONTRACT_CREATE_SUB_TYPE = "创建合同";
String CRM_CONTRACT_CREATE_SUCCESS = "创建了合同{{#contract.name}}";
String CRM_CONTRACT_UPDATE_SUB_TYPE = "更新合同";
String CRM_CONTRACT_UPDATE_SUCCESS = "更新了合同【{{#contractName}}】: {_DIFF{#updateReqVO}}";
String CRM_CONTRACT_DELETE_SUB_TYPE = "删除合同";
String CRM_CONTRACT_DELETE_SUCCESS = "删除了合同【{{#contractName}}】";
String CRM_CONTRACT_TRANSFER_SUB_TYPE = "转移合同";
String CRM_CONTRACT_TRANSFER_SUCCESS = "将合同【{{#contract.name}}】的负责人从【{getAdminUserById{#contract.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】";
// ======================= CRM_PRODUCT 产品 ======================= // ======================= CRM_PRODUCT 产品 =======================
@ -79,9 +107,21 @@ public interface LogRecordConstants {
// ======================= CRM_RECEIVABLE 回款 ======================= // ======================= CRM_RECEIVABLE 回款 =======================
String CRM_RECEIVABLE_TYPE = "CRM 回款"; String CRM_RECEIVABLE_TYPE = "CRM 回款";
String CRM_RECEIVABLE_CREATE_SUB_TYPE = "创建回款";
String CRM_RECEIVABLE_CREATE_SUCCESS = "创建了合同【{" + GET_CONTRACT_BY_ID + "{#receivable.contractId}}】的第【{{#receivable.period}}】期回款";
String CRM_RECEIVABLE_UPDATE_SUB_TYPE = "更新回款";
String CRM_RECEIVABLE_UPDATE_SUCCESS = "更新了合同【{" + GET_CONTRACT_BY_ID + "{#receivable.contractId}}】的第【{{#receivable.period}}】期回款: {_DIFF{#updateReqVO}}";
String CRM_RECEIVABLE_DELETE_SUB_TYPE = "删除回款";
String CRM_RECEIVABLE_DELETE_SUCCESS = "删除了合同【{" + GET_CONTRACT_BY_ID + "{#receivable.contractId}}】的第【{{#receivable.period}}】期回款";
// ======================= CRM_RECEIVABLE_PLAN 回款计划 ======================= // ======================= CRM_RECEIVABLE_PLAN 回款计划 =======================
String CRM_RECEIVABLE_PLAN_TYPE = "CRM 回款计划"; String CRM_RECEIVABLE_PLAN_TYPE = "CRM 回款计划";
String CRM_RECEIVABLE_PLAN_CREATE_SUB_TYPE = "创建回款计划";
String CRM_RECEIVABLE_PLAN_CREATE_SUCCESS = "创建了合同【{" + GET_CONTRACT_BY_ID + "{#receivablePlan.contractId}}】的第【{{#receivablePlan.period}}】期回款计划";
String CRM_RECEIVABLE_PLAN_UPDATE_SUB_TYPE = "更新回款计划";
String CRM_RECEIVABLE_PLAN_UPDATE_SUCCESS = "更新了合同【{" + GET_CONTRACT_BY_ID + "{#receivablePlan.contractId}}】的第【{{#receivablePlan.period}}】期回款计划: {_DIFF{#updateReqVO}}";
String CRM_RECEIVABLE_PLAN_DELETE_SUB_TYPE = "删除回款计划";
String CRM_RECEIVABLE_PLAN_DELETE_SUCCESS = "删除了合同【{" + GET_CONTRACT_BY_ID + "{#receivablePlan.contractId}}】的第【{{#receivablePlan.period}}】期回款计划";
} }

View File

@ -13,5 +13,6 @@ public interface CrmParseFunctionNameConstants {
String GET_CUSTOMER_INDUSTRY = "getCustomerIndustry"; // 获取客户行业信息 String GET_CUSTOMER_INDUSTRY = "getCustomerIndustry"; // 获取客户行业信息
String GET_CUSTOMER_LEVEL = "getCustomerLevel"; // 获取客户级别 String GET_CUSTOMER_LEVEL = "getCustomerLevel"; // 获取客户级别
String GET_CUSTOMER_SOURCE = "getCustomerSource"; // 获取客户来源 String GET_CUSTOMER_SOURCE = "getCustomerSource"; // 获取客户来源
String GET_CONTRACT_BY_ID = "getContractById"; // 获取合同信息
} }

View File

@ -7,7 +7,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.*; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO;
import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivableConvert; import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivableConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
@ -59,7 +62,7 @@ public class CrmReceivableController {
@Operation(summary = "创建回款") @Operation(summary = "创建回款")
@PreAuthorize("@ss.hasPermission('crm:receivable:create')") @PreAuthorize("@ss.hasPermission('crm:receivable:create')")
public CommonResult<Long> createReceivable(@Valid @RequestBody CrmReceivableCreateReqVO createReqVO) { public CommonResult<Long> createReceivable(@Valid @RequestBody CrmReceivableCreateReqVO createReqVO) {
return success(receivableService.createReceivable(createReqVO)); return success(receivableService.createReceivable(createReqVO, getLoginUserId()));
} }
@PutMapping("/update") @PutMapping("/update")
@ -141,12 +144,4 @@ public class CrmReceivableController {
return CrmReceivableConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList); return CrmReceivableConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList);
} }
@PutMapping("/transfer")
@Operation(summary = "回款转移")
@PreAuthorize("@ss.hasPermission('crm:receivable:update')")
public CommonResult<Boolean> transfer(@Valid @RequestBody CrmReceivableTransferReqVO reqVO) {
receivableService.transferReceivable(reqVO, getLoginUserId());
return success(true);
}
} }

View File

@ -7,7 +7,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.*; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanUpdateReqVO;
import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivablePlanConvert; import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivablePlanConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
@ -148,12 +151,4 @@ public class CrmReceivablePlanController {
return CrmReceivablePlanConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList, receivableList); return CrmReceivablePlanConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList, receivableList);
} }
@PutMapping("/transfer")
@Operation(summary = "回款计划转移")
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:update')")
public CommonResult<Boolean> transfer(@Valid @RequestBody CrmReceivablePlanTransferReqVO reqVO) {
receivablePlanService.transferReceivablePlan(reqVO, getLoginUserId());
return success(true);
}
} }

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.service.business;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessCreateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; 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
import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService; import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService;
import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
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 jakarta.annotation.Resource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -28,6 +32,7 @@ import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_NOT_EXISTS; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_NOT_EXISTS;
import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
/** /**
* 商机 Service 实现类 * 商机 Service 实现类
@ -48,7 +53,8 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
// TODO @商机待定操作日志 @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_CREATE_SUB_TYPE, bizNo = "{{#business.id}}",
success = CRM_BUSINESS_CREATE_SUCCESS)
public Long createBusiness(CrmBusinessCreateReqVO createReqVO, Long userId) { public Long createBusiness(CrmBusinessCreateReqVO createReqVO, Long userId) {
// 1. 插入商机 // 1. 插入商机
CrmBusinessDO business = CrmBusinessConvert.INSTANCE.convert(createReqVO); CrmBusinessDO business = CrmBusinessConvert.INSTANCE.convert(createReqVO);
@ -60,17 +66,20 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
// 2. 创建数据权限 // 2. 创建数据权限
permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()) permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType())
.setBizId(business.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 .setBizId(business.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
// 4. 记录操作日志上下文
LogRecordContext.putVariable("business", business);
return business.getId(); return business.getId();
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#updateReqVO.id", @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
level = CrmPermissionLevelEnum.WRITE) success = CRM_BUSINESS_UPDATE_SUCCESS)
// TODO @商机待定操作日志 @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
public void updateBusiness(CrmBusinessUpdateReqVO updateReqVO) { public void updateBusiness(CrmBusinessUpdateReqVO updateReqVO) {
// 1. 校验存在 // 1. 校验存在
validateBusinessExists(updateReqVO.getId()); CrmBusinessDO oldBusiness = validateBusinessExists(updateReqVO.getId());
// 2. 更新商机 // 2. 更新商机
CrmBusinessDO updateObj = CrmBusinessConvert.INSTANCE.convert(updateReqVO); CrmBusinessDO updateObj = CrmBusinessConvert.INSTANCE.convert(updateReqVO);
@ -78,20 +87,28 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
// TODO 商机待定插入商机与产品的关联表校验商品存在 // TODO 商机待定插入商机与产品的关联表校验商品存在
// TODO @商机待定如果状态发生变化插入商机状态变更记录表 // TODO @商机待定如果状态发生变化插入商机状态变更记录表
// 3. 记录操作日志上下文
LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldBusiness, CrmBusinessUpdateReqVO.class));
LogRecordContext.putVariable("businessName", oldBusiness.getName());
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_DELETE_SUB_TYPE, bizNo = "{{#id}}",
success = CRM_BUSINESS_DELETE_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
public void deleteBusiness(Long id) { public void deleteBusiness(Long id) {
// 校验存在 // 校验存在
validateBusinessExists(id); CrmBusinessDO business = validateBusinessExists(id);
// TODO @商机待定需要校验有没关联合同CrmContractDO businessId 字段 // TODO @商机待定需要校验有没关联合同CrmContractDO businessId 字段
// 删除 // 删除
businessMapper.deleteById(id); businessMapper.deleteById(id);
// 删除数据权限 // 删除数据权限
permissionService.deletePermission(CrmBizTypeEnum.CRM_BUSINESS.getType(), id); permissionService.deletePermission(CrmBizTypeEnum.CRM_BUSINESS.getType(), id);
// 记录操作日志上下文
LogRecordContext.putVariable("businessName", business.getName());
} }
private CrmBusinessDO validateBusinessExists(Long id) { private CrmBusinessDO validateBusinessExists(Long id) {
@ -102,6 +119,28 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
return crmBusiness; return crmBusiness;
} }
@Override
@Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}",
success = CRM_BUSINESS_TRANSFER_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER)
public void transferBusiness(CrmBusinessTransferReqVO reqVO, Long userId) {
// 1 校验商机是否存在
CrmBusinessDO business = validateBusinessExists(reqVO.getId());
// 2.1 数据权限转移
permissionService.transferPermission(
CrmBusinessConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()));
// 2.2 设置新的负责人
businessMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
// 记录操作日志上下文
LogRecordContext.putVariable("business", business);
}
//======================= 查询相关 =======================
@Override @Override
@CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.READ) @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#id", level = CrmPermissionLevelEnum.READ)
public CrmBusinessDO getBusiness(Long id) { public CrmBusinessDO getBusiness(Long id) {
@ -141,18 +180,4 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
convertSet(contactBusinessList, CrmContactBusinessDO::getBusinessId)); convertSet(contactBusinessList, CrmContactBusinessDO::getBusinessId));
} }
@Override
@Transactional(rollbackFor = Exception.class)
// TODO @puhui999操作日志
public void transferBusiness(CrmBusinessTransferReqVO reqVO, Long userId) {
// 1 校验商机是否存在
validateBusinessExists(reqVO.getId());
// 2.1 数据权限转移
permissionService.transferPermission(
CrmBusinessConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()));
// 2.2 设置新的负责人
businessMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
}
} }

View File

@ -33,7 +33,7 @@ import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CONTACT_TYPE; import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
@ -65,7 +65,8 @@ public class CrmContactServiceImpl implements CrmContactService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CONTACT_TYPE, subType = "创建联系人", bizNo = "{{#contactId}}", success = "创建了联系人[{{#contactName}}]") @LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_CREATE_SUB_TYPE, bizNo = "{{#contact.id}}",
success = CRM_CONTACT_CREATE_SUCCESS)
public Long createContact(CrmContactSaveReqVO createReqVO, Long userId) { public Long createContact(CrmContactSaveReqVO createReqVO, Long userId) {
// 1. 校验 // 1. 校验
validateRelationDataExists(createReqVO); validateRelationDataExists(createReqVO);
@ -86,18 +87,18 @@ public class CrmContactServiceImpl implements CrmContactService {
} }
// 5. 记录操作日志 // 5. 记录操作日志
LogRecordContext.putVariable("contactId", contact.getId()); LogRecordContext.putVariable("contact", contact);
LogRecordContext.putVariable("contactName", contact.getName());
return contact.getId(); return contact.getId();
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CONTACT_TYPE, subType = "更新联系人", bizNo = "{{#updateReqVO.id}}", success = "更新了联系人{_DIFF{#updateReqVO}}") @LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
success = CRM_CONTACT_UPDATE_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
public void updateContact(CrmContactSaveReqVO updateReqVO) { public void updateContact(CrmContactSaveReqVO updateReqVO) {
// 1. 校验存在 // 1. 校验存在
CrmContactDO contactDO = validateContactExists(updateReqVO.getId()); CrmContactDO oldContact = validateContactExists(updateReqVO.getId());
validateRelationDataExists(updateReqVO); validateRelationDataExists(updateReqVO);
// 2. 更新联系人 // 2. 更新联系人
@ -105,7 +106,8 @@ public class CrmContactServiceImpl implements CrmContactService {
contactMapper.updateById(updateObj); contactMapper.updateById(updateObj);
// 3. 记录操作日志 // 3. 记录操作日志
LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(contactDO, CrmContactSaveReqVO.class)); LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldContact, CrmContactSaveReqVO.class));
LogRecordContext.putVariable("contactName", oldContact.getName());
} }
/** /**
@ -133,11 +135,13 @@ public class CrmContactServiceImpl implements CrmContactService {
} }
@Override @Override
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_DELETE_SUB_TYPE, bizNo = "{{#id}}",
success = CRM_CONTACT_DELETE_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
public void deleteContact(Long id) { public void deleteContact(Long id) {
// 1.1 校验存在 // 1.1 校验存在
validateContactExists(id); CrmContactDO contact = validateContactExists(id);
// 1.2 校验是否关联合同 // 1.2 校验是否关联合同
if (contractService.getContractCountByContactId(id) > 0) { if (contractService.getContractCountByContactId(id) > 0) {
throw exception(CONTACT_DELETE_FAIL_CONTRACT_LINK_EXISTS); throw exception(CONTACT_DELETE_FAIL_CONTRACT_LINK_EXISTS);
@ -151,6 +155,9 @@ public class CrmContactServiceImpl implements CrmContactService {
// 4.2 删除商机关联 // 4.2 删除商机关联
contactBusinessService.deleteContactBusinessByContactId(id); contactBusinessService.deleteContactBusinessByContactId(id);
// TODO @puhui999删除跟进记录 // TODO @puhui999删除跟进记录
// 记录操作日志上下文
LogRecordContext.putVariable("contactName", contact.getName());
} }
private CrmContactDO validateContactExists(Long id) { private CrmContactDO validateContactExists(Long id) {
@ -161,6 +168,27 @@ public class CrmContactServiceImpl implements CrmContactService {
return contactDO; return contactDO;
} }
@Override
@Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CONTACT_TYPE, subType = CRM_CONTACT_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}",
success = CRM_CONTACT_TRANSFER_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER)
public void transferContact(CrmContactTransferReqVO reqVO, Long userId) {
// 1 校验联系人是否存在
CrmContactDO contact = validateContactExists(reqVO.getId());
// 2.1 数据权限转移
permissionService.transferPermission(
CrmContactConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTACT.getType()));
// 2.2 设置新的负责人
contactMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
// 3. 记录转移日志
LogRecordContext.putVariable("contact", contact);
}
//======================= 查询相关 =======================
@Override @Override
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.READ) @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTACT, bizId = "#id", level = CrmPermissionLevelEnum.READ)
public CrmContactDO getContact(Long id) { public CrmContactDO getContact(Long id) {
@ -191,20 +219,4 @@ public class CrmContactServiceImpl implements CrmContactService {
return contactMapper.selectPageByCustomerId(pageVO); return contactMapper.selectPageByCustomerId(pageVO);
} }
@Override
// TODO @puhui999权限校验
// TODO @puhui999记录操作日志将联系人名字转移给新负责人
public void transferContact(CrmContactTransferReqVO reqVO, Long userId) {
// 1 校验联系人是否存在
validateContactExists(reqVO.getId());
// 2.1 数据权限转移
permissionService.transferPermission(
CrmContactConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTACT.getType()));
// 2.2 设置新的负责人
contactMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
// 3. TODO 记录转移日志
}
} }

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.service.contract;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractCreateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO;
@ -15,6 +16,9 @@ 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.framework.permission.core.annotations.CrmPermission;
import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
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 jakarta.annotation.Resource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -25,6 +29,7 @@ import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CONTRACT_NOT_EXISTS; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CONTRACT_NOT_EXISTS;
import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
/** /**
* CRM 合同 Service 实现类 * CRM 合同 Service 实现类
@ -42,7 +47,9 @@ public class CrmContractServiceImpl implements CrmContractService {
private CrmPermissionService crmPermissionService; private CrmPermissionService crmPermissionService;
@Override @Override
// TODO @puhui999添加操作日志 @Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_CREATE_SUB_TYPE, bizNo = "{{#contract.id}}",
success = CRM_CONTRACT_CREATE_SUCCESS)
public Long createContract(CrmContractCreateReqVO createReqVO, Long userId) { public Long createContract(CrmContractCreateReqVO createReqVO, Long userId) {
// TODO @合同待定插入合同商品需要搞个 BusinessProductDO // TODO @合同待定插入合同商品需要搞个 BusinessProductDO
// 插入合同 // 插入合同
@ -53,38 +60,52 @@ public class CrmContractServiceImpl implements CrmContractService {
crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId) crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId)
.setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()).setBizId(contract.getId()) .setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()).setBizId(contract.getId())
.setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
// 4. 记录操作日志上下文
LogRecordContext.putVariable("contract", contract);
return contract.getId(); return contract.getId();
} }
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
success = CRM_CONTRACT_UPDATE_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
// TODO @puhui999添加操作日志
public void updateContract(CrmContractUpdateReqVO updateReqVO) { public void updateContract(CrmContractUpdateReqVO updateReqVO) {
// TODO @合同待定只有草稿审批中可以编辑 // TODO @合同待定只有草稿审批中可以编辑
// 校验存在 // 校验存在
validateContractExists(updateReqVO.getId()); CrmContractDO oldContract = validateContractExists(updateReqVO.getId());
// 更新合同 // 更新合同
CrmContractDO updateObj = CrmContractConvert.INSTANCE.convert(updateReqVO); CrmContractDO updateObj = CrmContractConvert.INSTANCE.convert(updateReqVO);
contractMapper.updateById(updateObj); contractMapper.updateById(updateObj);
// TODO @合同待定插入合同商品需要搞个 BusinessProductDO // TODO @合同待定插入合同商品需要搞个 BusinessProductDO
// 3. 记录操作日志上下文
LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldContract, CrmContractUpdateReqVO.class));
LogRecordContext.putVariable("contractName", oldContract.getName());
} }
// TODO @合同待定缺一个取消合同的接口只有草稿审批中可以取消CrmAuditStatusEnum // TODO @合同待定缺一个取消合同的接口只有草稿审批中可以取消CrmAuditStatusEnum
// TODO @合同待定缺一个发起审批的接口只有草稿可以发起审批CrmAuditStatusEnum // TODO @合同待定缺一个发起审批的接口只有草稿可以发起审批CrmAuditStatusEnum
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_DELETE_SUB_TYPE, bizNo = "{{#id}}",
success = CRM_CONTRACT_DELETE_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
public void deleteContract(Long id) { public void deleteContract(Long id) {
// TODO @合同待定如果被 CrmReceivableDO 所使用则不允许删除 // TODO @合同待定如果被 CrmReceivableDO 所使用则不允许删除
// 校验存在 // 校验存在
validateContractExists(id); CrmContractDO contract = validateContractExists(id);
// 删除 // 删除
contractMapper.deleteById(id); contractMapper.deleteById(id);
// 删除数据权限 // 删除数据权限
crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CONTRACT.getType(), id); crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CONTRACT.getType(), id);
// 记录操作日志上下文
LogRecordContext.putVariable("contractName", contract.getName());
} }
private CrmContractDO validateContractExists(Long id) { private CrmContractDO validateContractExists(Long id) {
@ -95,6 +116,27 @@ public class CrmContractServiceImpl implements CrmContractService {
return contract; return contract;
} }
@Override
@Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_TRANSFER_SUB_TYPE, bizNo = "{{#reqVO.id}}",
success = CRM_CONTRACT_TRANSFER_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER)
public void transferContract(CrmContractTransferReqVO reqVO, Long userId) {
// 1. 校验合同是否存在
CrmContractDO contract = validateContractExists(reqVO.getId());
// 2.1 数据权限转移
crmPermissionService.transferPermission(
CrmContractConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()));
// 2.2 设置负责人
contractMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
// 3. 记录转移日志
LogRecordContext.putVariable("contract", contract);
}
//======================= 查询相关 =======================
@Override @Override
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.READ) @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.READ)
public CrmContractDO getContract(Long id) { public CrmContractDO getContract(Long id) {
@ -120,21 +162,6 @@ public class CrmContractServiceImpl implements CrmContractService {
return contractMapper.selectPageByCustomerId(pageReqVO); return contractMapper.selectPageByCustomerId(pageReqVO);
} }
@Override
@Transactional(rollbackFor = Exception.class)
// 3. TODO @puhui999记录转移日志
// TODO @puhui999权限校验这里要搞哇
public void transferContract(CrmContractTransferReqVO reqVO, Long userId) {
// 1. 校验合同是否存在
validateContractExists(reqVO.getId());
// 2.1 数据权限转移
crmPermissionService.transferPermission(
CrmContractConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()));
// 2.2 设置负责人
contractMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
}
@Override @Override
public Long getContractCountByContactId(Long contactId) { public Long getContractCountByContactId(Long contactId) {
return contractMapper.selectCountByContactId(contactId); return contractMapper.selectCountByContactId(contactId);

View File

@ -145,10 +145,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
// 2.2 转移后重新设置负责人 // 2.2 转移后重新设置负责人
customerMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); customerMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
// 3. TODO 记录转移日志 // 3. 记录转移日志
// 记录操作日志上下文 LogRecordContext.putVariable("customer", customer);
// TODO @puhui999crmCustomer=customer也看看其他有没类似的情况哈
LogRecordContext.putVariable("crmCustomer", customer);
} }
@Override @Override
@ -172,7 +170,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
// 3. 记录操作日志上下文 // 3. 记录操作日志上下文
// tips: 因为这里使用的是老的状态所以记录时反着记录也就是 lockStatus true 那么就是解锁反之为锁定 // tips: 因为这里使用的是老的状态所以记录时反着记录也就是 lockStatus true 那么就是解锁反之为锁定
LogRecordContext.putVariable("crmCustomer", customer); LogRecordContext.putVariable("customer", customer);
} }
// ==================== 公海相关操作 ==================== // ==================== 公海相关操作 ====================

View File

@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.crm.service.receivable;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanCreateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanTransferReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanUpdateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanUpdateReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO; import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO;
@ -78,12 +77,4 @@ public interface CrmReceivablePlanService {
*/ */
PageResult<CrmReceivablePlanDO> getReceivablePlanPageByCustomerId(CrmReceivablePlanPageReqVO pageReqVO); PageResult<CrmReceivablePlanDO> getReceivablePlanPageByCustomerId(CrmReceivablePlanPageReqVO pageReqVO);
/**
* 回款计划转移
*
* @param reqVO 请求
* @param userId 用户编号
*/
void transferReceivablePlan(CrmReceivablePlanTransferReqVO reqVO, Long userId);
} }

View File

@ -4,9 +4,9 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanCreateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanTransferReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanUpdateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanUpdateReqVO;
import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivablePlanConvert; import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivablePlanConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
@ -20,6 +20,9 @@ import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
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 jakarta.annotation.Resource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -29,6 +32,7 @@ import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
// TODO @liuhongfeng参考 CrmReceivableServiceImpl 写的 todo // TODO @liuhongfeng参考 CrmReceivableServiceImpl 写的 todo
@ -49,10 +53,11 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
@Resource @Resource
private CrmCustomerService customerService; private CrmCustomerService customerService;
@Resource @Resource
private CrmPermissionService crmPermissionService; private CrmPermissionService permissionService;
@Override @Override
// TODO @puhui999操作日志 @LogRecord(type = CRM_RECEIVABLE_PLAN_TYPE, subType = CRM_RECEIVABLE_PLAN_CREATE_SUB_TYPE, bizNo = "{{#receivablePlan.id}}",
success = CRM_RECEIVABLE_PLAN_CREATE_SUCCESS)
public Long createReceivablePlan(CrmReceivablePlanCreateReqVO createReqVO, Long userId) { public Long createReceivablePlan(CrmReceivablePlanCreateReqVO createReqVO, Long userId) {
// TODO @liuhongfeng第几期的计算基于是 contractId + contractDO 的第几个还款 // TODO @liuhongfeng第几期的计算基于是 contractId + contractDO 的第几个还款
// TODO @liuhongfeng contractId校验合同是否存在 // TODO @liuhongfeng contractId校验合同是否存在
@ -64,9 +69,12 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
receivablePlanMapper.insert(receivablePlan); receivablePlanMapper.insert(receivablePlan);
// 创建数据权限 // 创建数据权限
crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId) permissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId)
.setBizType(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType()).setBizId(receivablePlan.getId()) .setBizType(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType()).setBizId(receivablePlan.getId())
.setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
// 4. 记录操作日志上下文
LogRecordContext.putVariable("receivablePlan", receivablePlan);
return receivablePlan.getId(); return receivablePlan.getId();
} }
@ -89,31 +97,44 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
} }
@Override @Override
@LogRecord(type = CRM_RECEIVABLE_PLAN_TYPE, subType = CRM_RECEIVABLE_PLAN_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
success = CRM_RECEIVABLE_PLAN_UPDATE_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
// TODO @puhui999操作日志
public void updateReceivablePlan(CrmReceivablePlanUpdateReqVO updateReqVO) { public void updateReceivablePlan(CrmReceivablePlanUpdateReqVO updateReqVO) {
// TODO @liuhongfeng如果已经有对应的还款则不允许编辑 // TODO @liuhongfeng如果已经有对应的还款则不允许编辑
// 校验存在 // 校验存在
validateReceivablePlanExists(updateReqVO.getId()); CrmReceivablePlanDO oldReceivablePlan = validateReceivablePlanExists(updateReqVO.getId());
// 更新 // 更新
CrmReceivablePlanDO updateObj = CrmReceivablePlanConvert.INSTANCE.convert(updateReqVO); CrmReceivablePlanDO updateObj = CrmReceivablePlanConvert.INSTANCE.convert(updateReqVO);
receivablePlanMapper.updateById(updateObj); receivablePlanMapper.updateById(updateObj);
// 3. 记录操作日志上下文
LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldReceivablePlan, CrmReceivablePlanUpdateReqVO.class));
LogRecordContext.putVariable("receivablePlan", oldReceivablePlan);
} }
@Override @Override
@LogRecord(type = CRM_RECEIVABLE_PLAN_TYPE, subType = CRM_RECEIVABLE_PLAN_DELETE_SUB_TYPE, bizNo = "{{#id}}",
success = CRM_RECEIVABLE_PLAN_DELETE_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
public void deleteReceivablePlan(Long id) { public void deleteReceivablePlan(Long id) {
// 校验存在 // 校验存在
validateReceivablePlanExists(id); CrmReceivablePlanDO receivablePlan = validateReceivablePlanExists(id);
// 删除 // 删除
receivablePlanMapper.deleteById(id); receivablePlanMapper.deleteById(id);
// 删除数据权限
permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id);
// 记录操作日志上下文
LogRecordContext.putVariable("receivablePlan", receivablePlan);
} }
private void validateReceivablePlanExists(Long id) { private CrmReceivablePlanDO validateReceivablePlanExists(Long id) {
if (receivablePlanMapper.selectById(id) == null) { CrmReceivablePlanDO receivablePlan = receivablePlanMapper.selectById(id);
if (receivablePlan == null) {
throw exception(RECEIVABLE_PLAN_NOT_EXISTS); throw exception(RECEIVABLE_PLAN_NOT_EXISTS);
} }
return receivablePlan;
} }
@Override @Override
@ -141,19 +162,4 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
return receivablePlanMapper.selectPageByCustomerId(pageReqVO); return receivablePlanMapper.selectPageByCustomerId(pageReqVO);
} }
// TODO @puhui999这个没有 transfer 接口可能是的哈
@Override
public void transferReceivablePlan(CrmReceivablePlanTransferReqVO reqVO, Long userId) {
// 1 校验回款计划是否存在
validateReceivablePlanExists(reqVO.getId());
// 2.1 数据权限转移
crmPermissionService.transferPermission(
CrmReceivablePlanConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType()));
// 2.2 设置新的负责人
receivablePlanMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
// 3. TODO 记录转移日志
}
} }

View File

@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.crm.service.receivable;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableCreateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableTransferReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO; import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
@ -23,9 +22,10 @@ public interface CrmReceivableService {
* 创建回款 * 创建回款
* *
* @param createReqVO 创建信息 * @param createReqVO 创建信息
* @param userId 用户编号
* @return 编号 * @return 编号
*/ */
Long createReceivable(@Valid CrmReceivableCreateReqVO createReqVO); Long createReceivable(@Valid CrmReceivableCreateReqVO createReqVO, Long userId);
/** /**
* 更新回款 * 更新回款
@ -78,12 +78,4 @@ public interface CrmReceivableService {
*/ */
PageResult<CrmReceivableDO> getReceivablePageByCustomerId(CrmReceivablePageReqVO pageReqVO); PageResult<CrmReceivableDO> getReceivablePageByCustomerId(CrmReceivablePageReqVO pageReqVO);
/**
* 回款转移
*
* @param reqVO 请求
* @param userId 用户编号
*/
void transferReceivable(CrmReceivableTransferReqVO reqVO, Long userId);
} }

View File

@ -5,9 +5,9 @@ import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableCreateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableTransferReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO;
import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivableConvert; import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivableConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 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
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
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 jakarta.annotation.Resource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -31,6 +35,7 @@ import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
/** /**
* CRM 回款 Service 实现类 * CRM 回款 Service 实现类
@ -51,11 +56,12 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
@Resource @Resource
private CrmReceivablePlanService receivablePlanService; private CrmReceivablePlanService receivablePlanService;
@Resource @Resource
private CrmPermissionService crmPermissionService; private CrmPermissionService permissionService;
@Override @Override
// TODO @puhui999操作日志 @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_CREATE_SUB_TYPE, bizNo = "{{#receivable.id}}",
public Long createReceivable(CrmReceivableCreateReqVO createReqVO) { success = CRM_RECEIVABLE_CREATE_SUCCESS)
public Long createReceivable(CrmReceivableCreateReqVO createReqVO, Long userId) {
// 插入还款 // 插入还款
CrmReceivableDO receivable = CrmReceivableConvert.INSTANCE.convert(createReqVO); CrmReceivableDO receivable = CrmReceivableConvert.INSTANCE.convert(createReqVO);
if (ObjectUtil.isNull(receivable.getAuditStatus())) { if (ObjectUtil.isNull(receivable.getAuditStatus())) {
@ -67,8 +73,12 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
checkReceivable(receivable); checkReceivable(receivable);
receivableMapper.insert(receivable); receivableMapper.insert(receivable);
// 3. 创建数据权限
permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_RECEIVABLE.getType())
.setBizId(receivable.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
// TODO @liuhongfeng需要更新关联的 plan // TODO @liuhongfeng需要更新关联的 plan
// 记录操作日志上下文
LogRecordContext.putVariable("receivable", receivable);
return receivable.getId(); return receivable.getId();
} }
@ -98,11 +108,12 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
} }
@Override @Override
// TODO @puhui999操作日志 @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
// TODO @puhui999权限校验 success = CRM_RECEIVABLE_UPDATE_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
public void updateReceivable(CrmReceivableUpdateReqVO updateReqVO) { public void updateReceivable(CrmReceivableUpdateReqVO updateReqVO) {
// 校验存在 // 校验存在
validateReceivableExists(updateReqVO.getId()); CrmReceivableDO oldReceivable = validateReceivableExists(updateReqVO.getId());
// TODO @liuhongfeng只有在草稿审核中可以提交修改 // TODO @liuhongfeng只有在草稿审核中可以提交修改
// 更新还款 // 更新还款
@ -110,6 +121,9 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
receivableMapper.updateById(updateObj); receivableMapper.updateById(updateObj);
// TODO @liuhongfeng需要更新关联的 plan // TODO @liuhongfeng需要更新关联的 plan
// 3. 记录操作日志上下文
LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldReceivable, CrmReceivableUpdateReqVO.class));
LogRecordContext.putVariable("receivable", oldReceivable);
} }
// TODO @liuhongfeng缺一个取消合同的接口只有草稿审批中可以取消CrmAuditStatusEnum // TODO @liuhongfeng缺一个取消合同的接口只有草稿审批中可以取消CrmAuditStatusEnum
@ -117,24 +131,33 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
// TODO @liuhongfeng缺一个发起审批的接口只有草稿可以发起审批CrmAuditStatusEnum // TODO @liuhongfeng缺一个发起审批的接口只有草稿可以发起审批CrmAuditStatusEnum
@Override @Override
// TODO @puhui999操作日志 @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_DELETE_SUB_TYPE, bizNo = "{{#id}}",
// TODO @puhui999权限校验 success = CRM_RECEIVABLE_DELETE_SUCCESS)
@CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
public void deleteReceivable(Long id) { public void deleteReceivable(Long id) {
// TODO @liuhongfeng如果被 CrmReceivablePlanDO 所使用则不允许删除 // TODO @liuhongfeng如果被 CrmReceivablePlanDO 所使用则不允许删除
// 校验存在 // 校验存在
validateReceivableExists(id); CrmReceivableDO receivable = validateReceivableExists(id);
// 删除 // 删除
receivableMapper.deleteById(id); receivableMapper.deleteById(id);
// 删除数据权限
permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id);
// 记录操作日志上下文
LogRecordContext.putVariable("receivable", receivable);
} }
private void validateReceivableExists(Long id) { private CrmReceivableDO validateReceivableExists(Long id) {
if (receivableMapper.selectById(id) == null) { CrmReceivableDO receivable = receivableMapper.selectById(id);
if (receivable == null) {
throw exception(RECEIVABLE_NOT_EXISTS); throw exception(RECEIVABLE_NOT_EXISTS);
} }
return receivable;
} }
// TODO @芋艿数据权限
@Override @Override
@CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE, bizId = "#id", level = CrmPermissionLevelEnum.READ)
public CrmReceivableDO getReceivable(Long id) { public CrmReceivableDO getReceivable(Long id) {
return receivableMapper.selectById(id); return receivableMapper.selectById(id);
} }
@ -158,18 +181,4 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
return receivableMapper.selectPageByCustomerId(pageReqVO); return receivableMapper.selectPageByCustomerId(pageReqVO);
} }
@Override
public void transferReceivable(CrmReceivableTransferReqVO reqVO, Long userId) {
// 1 校验回款是否存在
validateReceivableExists(reqVO.getId());
// 2.1 数据权限转移
crmPermissionService.transferPermission(
CrmReceivableConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_RECEIVABLE.getType()));
// 2.2 设置新的负责人
receivableMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
// 3. TODO 记录转移日志
}
} }

View File

@ -13,6 +13,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
@ -42,7 +43,7 @@ public class CrmCrmReceivableServiceImplTest extends BaseDbUnitTest {
CrmReceivableCreateReqVO reqVO = randomPojo(CrmReceivableCreateReqVO.class); CrmReceivableCreateReqVO reqVO = randomPojo(CrmReceivableCreateReqVO.class);
// 调用 // 调用
Long receivableId = receivableService.createReceivable(reqVO); Long receivableId = receivableService.createReceivable(reqVO, getLoginUserId());
// 断言 // 断言
assertNotNull(receivableId); assertNotNull(receivableId);
// 校验记录的属性是否正确 // 校验记录的属性是否正确