From e4d3175f06ef278e8abd536fa793a28862421198 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 11 Dec 2023 12:02:41 +0800 Subject: [PATCH 01/11] =?UTF-8?q?CRM-=E6=95=B0=E6=8D=AE=E6=9D=83=E9=99=90?= =?UTF-8?q?=EF=BC=9A=E5=AE=8C=E5=96=84=20review=20=E6=8F=90=E5=88=B0?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../crm/enums/common/CrmBizTypeEnum.java | 3 +- .../admin/business/CrmBusinessController.java | 2 +- .../vo/business/CrmBusinessPageReqVO.java | 3 - .../admin/contact/CrmContactController.java | 2 +- .../admin/contact/vo/CrmContactPageReqVO.java | 3 - .../admin/contract/CrmContractController.java | 2 +- .../contract/vo/CrmContractPageReqVO.java | 3 - .../receivable/CrmReceivableController.java | 8 ++- .../vo/plan/CrmReceivablePlanPageReqVO.java | 3 - .../vo/receivable/CrmReceivablePageReqVO.java | 3 - .../crm/convert/contact/ContactConvert.java | 6 +- .../crm/convert/contract/ContractConvert.java | 6 +- .../dal/mysql/business/CrmBusinessMapper.java | 15 ++-- .../crm/dal/mysql/clue/CrmClueMapper.java | 4 +- .../dal/mysql/contact/CrmContactMapper.java | 20 ++++-- .../dal/mysql/contract/CrmContractMapper.java | 18 +++-- .../dal/mysql/customer/CrmCustomerMapper.java | 4 +- .../mysql/permission/CrmPermissionMapper.java | 6 ++ .../mysql/receivable/CrmReceivableMapper.java | 39 +++++++++-- .../service/business/CrmBusinessService.java | 3 +- .../business/CrmBusinessServiceImpl.java | 9 +-- .../service/contact/CrmContactService.java | 6 +- .../contact/CrmContactServiceImpl.java | 8 +-- .../service/contract/CrmContractService.java | 5 +- .../contract/CrmContractServiceImpl.java | 6 ++ .../customer/CrmCustomerServiceImpl.java | 1 - .../permission/CrmPermissionServiceImpl.java | 11 ++- .../receivable/CrmReceivableService.java | 7 +- .../receivable/CrmReceivableServiceImpl.java | 11 ++- .../module/crm/util/CrmQueryWrapperUtils.java | 70 +++++++++++-------- .../CrmCrmReceivableServiceImplTest.java | 5 +- 31 files changed, 169 insertions(+), 123 deletions(-) diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/common/CrmBizTypeEnum.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/common/CrmBizTypeEnum.java index 0a441d229f..da24039b26 100644 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/common/CrmBizTypeEnum.java +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/common/CrmBizTypeEnum.java @@ -22,7 +22,8 @@ public enum CrmBizTypeEnum implements IntArrayValuable { CRM_CONTACT(3, "联系人"), CRM_BUSINESS(4, "商机"), CRM_CONTRACT(5, "合同"), - CRM_PRODUCT(6, "产品") + CRM_PRODUCT(6, "产品"), + CRM_RECEIVABLE(7, "回款") ; public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmBizTypeEnum::getType).toArray(); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java index d235952907..e4e24d29df 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java @@ -122,7 +122,7 @@ public class CrmBusinessController { @Operation(summary = "获得商机分页,基于指定客户") public CommonResult> getBusinessPageByCustomer(@Valid CrmBusinessPageReqVO pageReqVO) { Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空"); - PageResult pageResult = businessService.getBusinessPageByCustomer(pageReqVO, getLoginUserId()); + PageResult pageResult = businessService.getBusinessPageByCustomerId(pageReqVO); // 处理客户名称回显 // TODO @ljlleo:可以使用 CollectionUtils.convertSet 替代常用的 stream 操作,更简洁一点;下面几个也是哈; Set customerIds = pageResult.getList().stream() diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessPageReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessPageReqVO.java index 5790260470..3c9520607e 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessPageReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessPageReqVO.java @@ -24,7 +24,4 @@ public class CrmBusinessPageReqVO extends PageParam { @InEnum(CrmSceneTypeEnum.class) private Integer sceneType; // 场景类型,为 null 时则表示全部 - @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") - private Boolean pool; // null 则表示为不是公海数据 - } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java index dbdc0663dc..37db599630 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java @@ -125,7 +125,7 @@ public class CrmContactController { @Operation(summary = "获得联系人分页,基于指定客户") public CommonResult> getContactPageByCustomer(@Valid CrmContactPageReqVO pageVO) { Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空"); - PageResult pageResult = contactService.getContactPageByCustomerId(pageVO, getLoginUserId()); + PageResult pageResult = contactService.getContactPageByCustomerId(pageVO); return success(convertDetailContactPage(pageResult)); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactPageReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactPageReqVO.java index eb6ebd76c4..75294a1bde 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactPageReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/vo/CrmContactPageReqVO.java @@ -39,7 +39,4 @@ public class CrmContactPageReqVO extends PageParam { @InEnum(CrmSceneTypeEnum.class) private Integer sceneType; // 场景类型,为 null 时则表示全部 - @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") - private Boolean pool; // null 则表示为不是公海数据 - } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java index 623a9ab912..5086625a7d 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java @@ -95,7 +95,7 @@ public class CrmContractController { @Operation(summary = "获得联系人分页,基于指定客户") public CommonResult> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) { Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空"); - PageResult pageResult = contractService.getContractPageByCustomer(pageVO, getLoginUserId()); + PageResult pageResult = contractService.getContractPageByCustomerId(pageVO); return success(convertDetailContractPage(pageResult)); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractPageReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractPageReqVO.java index 2b3123bd93..94199ada64 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractPageReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractPageReqVO.java @@ -30,7 +30,4 @@ public class CrmContractPageReqVO extends PageParam { @InEnum(CrmSceneTypeEnum.class) private Integer sceneType; // 场景类型,为 null 时则表示全部 - @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") - private Boolean pool; // null 则表示为不是公海数据 TODO @puhui999:合同没有公海。目前只有【客户】【线索】有公海,其它都没 - } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java index 4c4be4a253..27dc063a55 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java @@ -36,6 +36,7 @@ import java.util.Map; import java.util.stream.Stream; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; @@ -94,7 +95,7 @@ public class CrmReceivableController { @Operation(summary = "获得回款分页") @PreAuthorize("@ss.hasPermission('crm:receivable:query')") public CommonResult> getReceivablePage(@Valid CrmReceivablePageReqVO pageReqVO) { - PageResult pageResult = receivableService.getReceivablePage(pageReqVO); + PageResult pageResult = receivableService.getReceivablePage(pageReqVO, getLoginUserId()); return success(convertDetailReceivablePage(pageResult)); } @@ -102,7 +103,7 @@ public class CrmReceivableController { @Operation(summary = "获得回款分页,基于指定客户") public CommonResult> getReceivablePageByCustomer(@Valid CrmReceivablePageReqVO pageReqVO) { Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空"); - PageResult pageResult = receivableService.getReceivablePageByCustomer(pageReqVO); + PageResult pageResult = receivableService.getReceivablePageByCustomerId(pageReqVO); return success(convertDetailReceivablePage(pageResult)); } @@ -113,7 +114,8 @@ public class CrmReceivableController { @OperateLog(type = EXPORT) public void exportReceivableExcel(@Valid CrmReceivablePageReqVO exportReqVO, HttpServletResponse response) throws IOException { - PageResult pageResult = receivableService.getReceivablePage(exportReqVO); + exportReqVO.setPageSize(PAGE_SIZE_NONE); + PageResult pageResult = receivableService.getReceivablePage(exportReqVO, getLoginUserId()); // 导出 Excel ExcelUtils.write(response, "回款.xls", "数据", CrmReceivableRespVO.class, convertDetailReceivablePage(pageResult).getList()); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanPageReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanPageReqVO.java index 16681ba3cc..f86aa346de 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanPageReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanPageReqVO.java @@ -25,7 +25,4 @@ public class CrmReceivablePlanPageReqVO extends PageParam { @InEnum(CrmSceneTypeEnum.class) private Integer sceneType; // 场景类型,为 null 时则表示全部 - @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") - private Boolean pool; // null 则表示为不是公海数据 - } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivablePageReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivablePageReqVO.java index 3eef5d0136..1bca32fa32 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivablePageReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivablePageReqVO.java @@ -27,7 +27,4 @@ public class CrmReceivablePageReqVO extends PageParam { @InEnum(CrmSceneTypeEnum.class) private Integer sceneType; // 场景类型,为 null 时则表示全部 - @Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") - private Boolean pool; // null 则表示为不是公海数据 - } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/ContactConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/ContactConvert.java index 636835be75..b907c3e0c3 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/ContactConvert.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/ContactConvert.java @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferRe import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import org.mapstruct.Mappings; import org.mapstruct.factory.Mappers; import java.util.List; @@ -48,10 +47,7 @@ public interface ContactConvert { List convertAllList(List list); - @Mappings({ - @Mapping(target = "bizId", source = "reqVO.id"), - @Mapping(target = "newOwnerUserId", source = "reqVO.id") - }) + @Mapping(target = "bizId", source = "reqVO.id") CrmPermissionTransferReqBO convert(CrmContactTransferReqVO reqVO, Long userId); /** diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/ContractConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/ContractConvert.java index 2041ba5deb..195a08301c 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/ContractConvert.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/ContractConvert.java @@ -8,7 +8,6 @@ import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferRe import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import org.mapstruct.Mappings; import org.mapstruct.factory.Mappers; import java.util.List; @@ -39,10 +38,7 @@ public interface ContractConvert { List convertList02(List list); - @Mappings({ - @Mapping(target = "bizId", source = "reqVO.id"), - @Mapping(target = "newOwnerUserId", source = "reqVO.id") - }) + @Mapping(target = "bizId", source = "reqVO.id") CrmPermissionTransferReqBO convert(CrmContractTransferReqVO reqVO, Long userId); default PageResult convertPage(PageResult pageResult, Map userMap, diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java index 7c06e57a0a..d347300183 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.mysql.business; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; @@ -27,14 +28,20 @@ public interface CrmBusinessMapper extends BaseMapperX { .set(CrmBusinessDO::getOwnerUserId, ownerUserId)); } + default PageResult selectPageByCustomerId(CrmBusinessPageReqVO pageReqVO) { + return selectPage(pageReqVO, new LambdaQueryWrapperX() + .eq(CrmBusinessDO::getCustomerId, pageReqVO.getCustomerId()) // 指定客户编号 + .likeIfPresent(CrmBusinessDO::getName, pageReqVO.getName()) + .orderByDesc(CrmBusinessDO::getId)); + } + default PageResult selectPage(CrmBusinessPageReqVO pageReqVO, Long userId) { MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.builderPageQuery(query, CrmBizTypeEnum.CRM_BUSINESS.getType(), CrmBusinessDO::getId, - userId, pageReqVO.getSceneType(), pageReqVO.getPool()); + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_BUSINESS.getType(), CrmBusinessDO::getId, + userId, pageReqVO.getSceneType(), Boolean.FALSE); // 拼接自身的查询条件 query.selectAll(CrmBusinessDO.class) - .eqIfPresent(CrmBusinessDO::getCustomerId, pageReqVO.getCustomerId()) // 指定客户编号 .likeIfPresent(CrmBusinessDO::getName, pageReqVO.getName()) .orderByDesc(CrmBusinessDO::getId); return selectJoinPage(pageReqVO, CrmBusinessDO.class, query); @@ -43,7 +50,7 @@ public interface CrmBusinessMapper extends BaseMapperX { default List selectBatchIds(Collection ids, Long userId) { MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.builderListQueryBatch(query, CrmBizTypeEnum.CRM_BUSINESS.getType(), ids, userId); + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_BUSINESS.getType(), ids, userId); return selectJoinList(CrmBusinessDO.class, query); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/clue/CrmClueMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/clue/CrmClueMapper.java index 479a12f1a8..b78afc4fef 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/clue/CrmClueMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/clue/CrmClueMapper.java @@ -30,7 +30,7 @@ public interface CrmClueMapper extends BaseMapperX { default PageResult selectPage(CrmCluePageReqVO pageReqVO, Long userId) { MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.builderPageQuery(query, CrmBizTypeEnum.CRM_LEADS.getType(), CrmClueDO::getId, + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_LEADS.getType(), CrmClueDO::getId, userId, pageReqVO.getSceneType(), pageReqVO.getPool()); // 拼接自身的查询条件 query.selectAll(CrmClueDO.class) @@ -44,7 +44,7 @@ public interface CrmClueMapper extends BaseMapperX { default List selectBatchIds(Collection ids, Long userId) { MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.builderListQueryBatch(query, CrmBizTypeEnum.CRM_LEADS.getType(), ids, userId); + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_LEADS.getType(), ids, userId); return selectJoinList(CrmClueDO.class, query); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java index 189f36f08b..2a0a746f57 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.mysql.contact; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; @@ -27,14 +28,25 @@ public interface CrmContactMapper extends BaseMapperX { .set(CrmContactDO::getOwnerUserId, ownerUserId)); } + default PageResult selectPageByCustomerId(CrmContactPageReqVO pageVO) { + return selectPage(pageVO, new LambdaQueryWrapperX() + .eq(CrmContactDO::getCustomerId, pageVO.getCustomerId()) // 指定客户编号 + .likeIfPresent(CrmContactDO::getName, pageVO.getName()) + .eqIfPresent(CrmContactDO::getMobile, pageVO.getMobile()) + .eqIfPresent(CrmContactDO::getTelephone, pageVO.getTelephone()) + .eqIfPresent(CrmContactDO::getEmail, pageVO.getEmail()) + .eqIfPresent(CrmContactDO::getQq, pageVO.getQq()) + .eqIfPresent(CrmContactDO::getWechat, pageVO.getWechat()) + .orderByDesc(CrmContactDO::getId)); + } + default PageResult selectPage(CrmContactPageReqVO pageReqVO, Long userId) { MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.builderPageQuery(query, CrmBizTypeEnum.CRM_CONTACT.getType(), CrmContactDO::getId, - userId, pageReqVO.getSceneType(), pageReqVO.getPool()); + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTACT.getType(), CrmContactDO::getId, + userId, pageReqVO.getSceneType(), Boolean.FALSE); // 拼接自身的查询条件 query.selectAll(CrmContactDO.class) - .eqIfPresent(CrmContactDO::getCustomerId, pageReqVO.getCustomerId()) // 指定客户编号 .likeIfPresent(CrmContactDO::getName, pageReqVO.getName()) .eqIfPresent(CrmContactDO::getMobile, pageReqVO.getMobile()) .eqIfPresent(CrmContactDO::getTelephone, pageReqVO.getTelephone()) @@ -48,7 +60,7 @@ public interface CrmContactMapper extends BaseMapperX { default List selectBatchIds(Collection ids, Long userId) { MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.builderListQueryBatch(query, CrmBizTypeEnum.CRM_CONTACT.getType(), ids, userId); + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTACT.getType(), ids, userId); return selectJoinList(CrmContactDO.class, query); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java index 37452feb7a..5bc9d5cb2d 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.mysql.contract; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; @@ -27,13 +28,22 @@ public interface CrmContractMapper extends BaseMapperX { .set(CrmContractDO::getOwnerUserId, ownerUserId)); } + default PageResult selectPageByCustomerId(CrmContractPageReqVO pageReqVO) { + return selectPage(pageReqVO, new LambdaQueryWrapperX() + .eq(CrmContractDO::getCustomerId, pageReqVO.getCustomerId()) + .likeIfPresent(CrmContractDO::getNo, pageReqVO.getNo()) + .likeIfPresent(CrmContractDO::getName, pageReqVO.getName()) + .eqIfPresent(CrmContractDO::getCustomerId, pageReqVO.getCustomerId()) + .eqIfPresent(CrmContractDO::getBusinessId, pageReqVO.getBusinessId()) + .orderByDesc(CrmContractDO::getId)); + } + default PageResult selectPage(CrmContractPageReqVO pageReqVO, Long userId) { MPJLambdaWrapperX mpjLambdaWrapperX = new MPJLambdaWrapperX<>(); // 构建数据权限连表条件 - CrmQueryWrapperUtils.builderPageQuery(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTACT.getType(), CrmContractDO::getId, - userId, pageReqVO.getSceneType(), pageReqVO.getPool()); + CrmQueryWrapperUtils.appendPermissionCondition(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTACT.getType(), CrmContractDO::getId, + userId, pageReqVO.getSceneType(), Boolean.FALSE); mpjLambdaWrapperX.selectAll(CrmContractDO.class) - .eqIfPresent(CrmContractDO::getCustomerId, pageReqVO.getCustomerId()) .likeIfPresent(CrmContractDO::getNo, pageReqVO.getNo()) .likeIfPresent(CrmContractDO::getName, pageReqVO.getName()) .eqIfPresent(CrmContractDO::getCustomerId, pageReqVO.getCustomerId()) @@ -45,7 +55,7 @@ public interface CrmContractMapper extends BaseMapperX { default List selectBatchIds(Collection ids, Long userId) { MPJLambdaWrapperX mpjLambdaWrapperX = new MPJLambdaWrapperX<>(); // 构建数据权限连表条件 - CrmQueryWrapperUtils.builderListQueryBatch(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTACT.getType(), ids, userId); + CrmQueryWrapperUtils.appendPermissionCondition(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTACT.getType(), ids, userId); return selectJoinList(CrmContractDO.class, mpjLambdaWrapperX); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java index 86c8617b77..dece490560 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java @@ -30,7 +30,7 @@ public interface CrmCustomerMapper extends BaseMapperX { default PageResult selectPage(CrmCustomerPageReqVO pageReqVO, Long userId) { MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.builderPageQuery(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), CrmCustomerDO::getId, + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), CrmCustomerDO::getId, userId, pageReqVO.getSceneType(), pageReqVO.getPool()); // 拼接自身的查询条件 query.selectAll(CrmCustomerDO.class) @@ -45,7 +45,7 @@ public interface CrmCustomerMapper extends BaseMapperX { default List selectBatchIds(Collection ids, Long userId) { MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.builderListQueryBatch(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), ids, userId); + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), ids, userId); return selectJoinList(CrmCustomerDO.class, query); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/permission/CrmPermissionMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/permission/CrmPermissionMapper.java index 3493185027..e7de279d84 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/permission/CrmPermissionMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/permission/CrmPermissionMapper.java @@ -46,4 +46,10 @@ public interface CrmPermissionMapper extends BaseMapperX { .eq(CrmPermissionDO::getId, id).eq(CrmPermissionDO::getUserId, userId)); } + default int deletePermission(Integer bizType, Long bizId) { + return delete(new LambdaQueryWrapperX() + .eq(CrmPermissionDO::getBizType, bizType) + .eq(CrmPermissionDO::getBizId, bizId)); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java index 9da1300228..4839492c74 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java @@ -3,10 +3,17 @@ package cn.iocoder.yudao.module.crm.dal.mysql.receivable; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO; +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; +import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; +import java.util.Collection; +import java.util.List; + /** * 回款 Mapper * @@ -15,15 +22,13 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface CrmReceivableMapper extends BaseMapperX { - default PageResult selectPage(CrmReceivablePageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .eqIfPresent(CrmReceivableDO::getNo, reqVO.getNo()) - .eqIfPresent(CrmReceivableDO::getPlanId, reqVO.getPlanId()) - .eqIfPresent(CrmReceivableDO::getCustomerId, reqVO.getCustomerId()) - .orderByDesc(CrmReceivableDO::getId)); + default int updateOwnerUserIdById(Long id, Long ownerUserId) { + return update(new LambdaUpdateWrapper() + .eq(CrmReceivableDO::getId, id) + .set(CrmReceivableDO::getOwnerUserId, ownerUserId)); } - default PageResult selectPageByCustomer(CrmReceivablePageReqVO reqVO) { + default PageResult selectPageByCustomerId(CrmReceivablePageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX() .eq(CrmReceivableDO::getCustomerId, reqVO.getCustomerId()) // 必须传递 .eqIfPresent(CrmReceivableDO::getNo, reqVO.getNo()) @@ -31,4 +36,24 @@ public interface CrmReceivableMapper extends BaseMapperX { .orderByDesc(CrmReceivableDO::getId)); } + default PageResult selectPage(CrmReceivablePageReqVO pageReqVO, Long userId) { + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + // 拼接数据权限的查询条件 + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE.getType(), CrmReceivableDO::getId, + userId, pageReqVO.getSceneType(), Boolean.FALSE); + // 拼接自身的查询条件 + query.selectAll(CrmReceivableDO.class) + .eqIfPresent(CrmReceivableDO::getNo, pageReqVO.getNo()) + .eqIfPresent(CrmReceivableDO::getPlanId, pageReqVO.getPlanId()) + .orderByDesc(CrmReceivableDO::getId); + return selectJoinPage(pageReqVO, CrmReceivableDO.class, query); + } + + default List selectBatchIds(Collection ids, Long userId) { + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + // 拼接数据权限的查询条件 + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE.getType(), ids, userId); + return selectJoinList(CrmReceivableDO.class, query); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java index c46f5f0bf8..d81a75d9a4 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java @@ -75,10 +75,9 @@ public interface CrmBusinessService { * 数据权限:基于 {@link CrmCustomerDO} 读取 * * @param pageReqVO 分页查询 - * @param userId 用户编号 * @return 联系人分页 */ - PageResult getBusinessPageByCustomer(CrmBusinessPageReqVO pageReqVO, Long userId); + PageResult getBusinessPageByCustomerId(CrmBusinessPageReqVO pageReqVO); /** * 商机转移 diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java index 98630ffdfb..f2db01b834 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java @@ -111,11 +111,9 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { } @Override - public PageResult getBusinessPageByCustomer(CrmBusinessPageReqVO pageReqVO, Long userId) { - // 校验客户存在 TODO @puhui999:这里不校验 - customerService.validateCustomer(pageReqVO.getCustomerId()); - // TODO @puhui999:感觉这里貌似不太复用用 selectPage,因为他可能没商机权限,只是因为能看 customer,所以可以看到列表 - return businessMapper.selectPage(pageReqVO, userId); + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageReqVO.customerId", level = CrmPermissionLevelEnum.READ) + public PageResult getBusinessPageByCustomerId(CrmBusinessPageReqVO pageReqVO) { + return businessMapper.selectPageByCustomerId(pageReqVO); } @Override @@ -127,7 +125,6 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { // 2.1 数据权限转移 crmPermissionService.transferPermission( CrmBusinessConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType())); - // 2.2 设置新的负责人 businessMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java index 4306d8aea7..46cbec699b 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactCreateR import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactUpdateReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import jakarta.validation.Valid; import java.util.Collection; @@ -71,12 +72,11 @@ public interface CrmContactService { /** * 获得联系人分页 * - * 数据权限:基于 {@link CrmContactDO} + * 数据权限:基于 {@link CrmCustomerDO} * * @param pageVO 分页查询 - * @param userId 用户编号 * @return 联系人分页 */ - PageResult getContactPageByCustomerId(CrmContactPageReqVO pageVO, Long userId); + PageResult getContactPageByCustomerId(CrmContactPageReqVO pageVO); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java index 39aac0e113..5ee1e2b299 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java @@ -134,11 +134,9 @@ public class CrmContactServiceImpl implements CrmContactService { } @Override - public PageResult getContactPageByCustomerId(CrmContactPageReqVO pageVO, Long userId) { - // 校验用户存在 - customerService.validateCustomer(pageVO.getCustomerId()); - // TODO @puhui999:getBusinessPageByCustomer 同理 - return contactMapper.selectPage(pageVO, userId); + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageVO.customerId", level = CrmPermissionLevelEnum.READ) + public PageResult getContactPageByCustomerId(CrmContactPageReqVO pageVO) { + return contactMapper.selectPageByCustomerId(pageVO); } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java index 0531dbe389..7d3f833357 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java @@ -75,12 +75,9 @@ public interface CrmContractService { * 数据权限:基于 {@link CrmCustomerDO} 读取 * * @param pageReqVO 分页查询 - * @param userId 用户编号 * @return 联系人分页 */ - default PageResult getContractPageByCustomer(CrmContractPageReqVO pageReqVO, Long userId) { - return getContractPage(pageReqVO, userId); - } + PageResult getContractPageByCustomerId(CrmContractPageReqVO pageReqVO); /** * 合同转移 diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java index 23795f94e6..7f1b20a0eb 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java @@ -104,6 +104,12 @@ public class CrmContractServiceImpl implements CrmContractService { return contractMapper.selectPage(pageReqVO, userId); } + @Override + @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageReqVO.customerId", level = CrmPermissionLevelEnum.READ) + public PageResult getContractPageByCustomerId(CrmContractPageReqVO pageReqVO) { + return contractMapper.selectPageByCustomerId(pageReqVO); + } + @Override @Transactional(rollbackFor = Exception.class) public void transferContract(CrmContractTransferReqVO reqVO, Long userId) { diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java index 93589a5b07..fd10092555 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java @@ -114,7 +114,6 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { */ @Override public void validateCustomer(Long customerId) { - // TODO puhui999: 不返回客户不走校验应该可行 // 校验客户是否存在 if (customerId == null) { throw exception(CUSTOMER_NOT_EXISTS); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java index d7ebb572b4..58bd51149f 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java @@ -139,14 +139,11 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { @Override public void deletePermission(Integer bizType, Long bizId) { - // TODO @puhui999:这种直接写条件删除;不需要先查询,再删除 - List permissionList = crmPermissionMapper.selectByBizTypeAndBizId(bizType, bizId); - if (CollUtil.isEmpty(permissionList)) { - return; - } - // 删除数据权限 - crmPermissionMapper.deleteBatchIds(convertSet(permissionList, CrmPermissionDO::getId)); + int deletedCol = crmPermissionMapper.deletePermission(bizType, bizId); + if (deletedCol == 0) { + throw exception(CRM_PERMISSION_NOT_EXISTS); + } } @Override diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java index bf9e5571b1..8f7984afe5 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java @@ -6,8 +6,8 @@ import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.Crm 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.receivable.CrmReceivableDO; - import jakarta.validation.Valid; + import java.util.Collection; import java.util.List; @@ -62,9 +62,10 @@ public interface CrmReceivableService { * 数据权限:基于 {@link CrmReceivableDO} 读取 * * @param pageReqVO 分页查询 + * @param userId 用户编号 * @return 回款分页 */ - PageResult getReceivablePage(CrmReceivablePageReqVO pageReqVO); + PageResult getReceivablePage(CrmReceivablePageReqVO pageReqVO, Long userId); /** * 获得回款分页,基于指定客户 @@ -74,6 +75,6 @@ public interface CrmReceivableService { * @param pageReqVO 分页查询 * @return 回款分页 */ - PageResult getReceivablePageByCustomer(CrmReceivablePageReqVO pageReqVO); + PageResult getReceivablePageByCustomerId(CrmReceivablePageReqVO pageReqVO); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java index ac3b71e08c..18a289be26 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java @@ -20,10 +20,10 @@ import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission; import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; +import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import jakarta.annotation.Resource; import java.util.Collection; import java.util.List; @@ -129,16 +129,15 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { return receivableMapper.selectBatchIds(ids); } - // TODO @芋艿:数据权限 @Override - public PageResult getReceivablePage(CrmReceivablePageReqVO pageReqVO) { - return receivableMapper.selectPage(pageReqVO); + public PageResult getReceivablePage(CrmReceivablePageReqVO pageReqVO, Long userId) { + return receivableMapper.selectPage(pageReqVO, userId); } @Override @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageReqVO.customerId", level = CrmPermissionLevelEnum.READ) - public PageResult getReceivablePageByCustomer(CrmReceivablePageReqVO pageReqVO) { - return receivableMapper.selectPageByCustomer(pageReqVO); + public PageResult getReceivablePageByCustomerId(CrmReceivablePageReqVO pageReqVO) { + return receivableMapper.selectPageByCustomerId(pageReqVO); } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/util/CrmQueryWrapperUtils.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/util/CrmQueryWrapperUtils.java index 5eb80b292d..e3e6be48b4 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/util/CrmQueryWrapperUtils.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/util/CrmQueryWrapperUtils.java @@ -6,6 +6,7 @@ import cn.hutool.extra.spring.SpringUtil; import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum; +import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; @@ -17,7 +18,7 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; /** - * CRM 分页查询工具类 + * CRM 查询工具类 * * @author HUIHUI */ @@ -26,17 +27,16 @@ public class CrmQueryWrapperUtils { /** * 构造 CRM 数据类型数据分页查询条件 * - * @param query 连表查询对象 - * @param bizType 数据类型 {@link CrmBizTypeEnum} - * @param bizId 数据编号 - * @param userId 用户编号 - * @param sceneType 场景类型 - * @param pool 公海 + * @param query 连表查询对象 + * @param bizType 数据类型 {@link CrmBizTypeEnum} + * @param bizId 数据编号 + * @param userId 用户编号 + * @param sceneType 场景类型 + * @param pool 公海 */ - // TODO @puhui999:bizId 直接传递会不会简单点 - // TODO @puhui999:builderPageQuery 应该不仅仅适合于分页查询,应该适用于所有的查询;可以改成 appendPermissionCondition - public static , S> void builderPageQuery(T query, Integer bizType, SFunction bizId, - Long userId, Integer sceneType, Boolean pool) { + // TODO @puhui999:bizId 直接传递会不会简单点 回复:还是需要 SFunction 因为分页连表时不知道 bizId 是多少 + public static , S> void appendPermissionCondition(T query, Integer bizType, SFunction bizId, + Long userId, Integer sceneType, Boolean pool) { // 1. 构建数据权限连表条件 if (ObjUtil.notEqual(validateAdminUser(userId), Boolean.TRUE)) { // 管理员不需要数据权限 query.innerJoin(CrmPermissionDO.class, on -> @@ -48,9 +48,13 @@ public class CrmQueryWrapperUtils { query.eq("owner_user_id", userId); } // 2.2 场景二:我参与的数据 - // TODO @puhui999:参与,指的是有读写权限噢;可以把 1. 的合并到 2.2 里;因为 2.1 不需要; if (CrmSceneTypeEnum.isInvolved(sceneType)) { - query.ne("owner_user_id", userId); + query + .ne("owner_user_id", userId) + .and(q -> q.eq(CrmPermissionDO::getLevel, CrmPermissionLevelEnum.READ.getLevel()) + .or() + .eq(CrmPermissionDO::getLevel, CrmPermissionLevelEnum.WRITE.getLevel())); + } // 2.3 场景三:下属负责的数据 if (CrmSceneTypeEnum.isSubordinate(sceneType)) { @@ -61,7 +65,7 @@ public class CrmQueryWrapperUtils { } } - // 2. 拼接公海的查询条件 + // 3. 拼接公海的查询条件 if (ObjUtil.equal(pool, Boolean.TRUE)) { // 情况一:公海 query.isNull("owner_user_id"); } else { // 情况二:不是公海 @@ -72,28 +76,27 @@ public class CrmQueryWrapperUtils { /** * 构造 CRM 数据类型批量数据查询条件 * - * @param query 连表查询对象 - * @param bizType 数据类型 {@link CrmBizTypeEnum} - * @param bizIds 数据编号 - * @param userId 用户编号 + * @param query 连表查询对象 + * @param bizType 数据类型 {@link CrmBizTypeEnum} + * @param bizIds 数据编号 + * @param userId 用户编号 */ - // TODO @puhui999:可以改成 appendPermissionCondition - // TODO @puhui999:S 是不是可以删除 - public static , S> void builderListQueryBatch(T query, Integer bizType, Collection bizIds, Long userId) { - // TODO @puhui999:这里先 if return 简单点 - if (ObjUtil.notEqual(validateAdminUser(userId), Boolean.TRUE)) { // 管理员不需要数据权限 - query.innerJoin(CrmPermissionDO.class, on -> - on.eq(CrmPermissionDO::getBizType, bizType).in(CrmPermissionDO::getBizId, bizIds) - .in(CollUtil.isNotEmpty(bizIds), CrmPermissionDO::getUserId, userId)); + public static > void appendPermissionCondition(T query, Integer bizType, Collection bizIds, Long userId) { + if (ObjUtil.equal(validateAdminUser(userId), Boolean.TRUE)) {// 管理员不需要数据权限 + return; } + + query.innerJoin(CrmPermissionDO.class, on -> + on.eq(CrmPermissionDO::getBizType, bizType).in(CrmPermissionDO::getBizId, bizIds) + .in(CollUtil.isNotEmpty(bizIds), CrmPermissionDO::getUserId, userId)); } - // TODO @puhui999:需要加个变量,不用每次都拿哈; private static AdminUserApi getAdminUserApi() { - return SpringUtil.getBean(AdminUserApi.class); + return AdminUserApiHolder.ADMIN_USER_API; } // TODO @puhui999:需要实现; + /** * 校验用户是否是管理员 * @@ -104,4 +107,15 @@ public class CrmQueryWrapperUtils { return false; } + /** + * 静态内部类实现 AdminUserApi 单例获取 + * + * @author HUIHUI + */ + private static class AdminUserApiHolder { + + private static final AdminUserApi ADMIN_USER_API = SpringUtil.getBean(AdminUserApi.class); + + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/receivable/CrmCrmReceivableServiceImplTest.java b/yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/receivable/CrmCrmReceivableServiceImplTest.java index 93ac0c99bd..1f3d821af2 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/receivable/CrmCrmReceivableServiceImplTest.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/receivable/CrmCrmReceivableServiceImplTest.java @@ -7,12 +7,11 @@ import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.Crm import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableUpdateReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO; import cn.iocoder.yudao.module.crm.dal.mysql.receivable.CrmReceivableMapper; +import jakarta.annotation.Resource; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; -import jakarta.annotation.Resource; - import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; @@ -133,7 +132,7 @@ public class CrmCrmReceivableServiceImplTest extends BaseDbUnitTest { reqVO.setCustomerId(null); // 调用 - PageResult pageResult = receivableService.getReceivablePage(reqVO); + PageResult pageResult = receivableService.getReceivablePage(reqVO, 1L); // 断言 assertEquals(1, pageResult.getTotal()); assertEquals(1, pageResult.getList().size()); From 1ac68aca97df6718153c327a25f2bf0b04b3c464 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 11 Dec 2023 15:56:12 +0800 Subject: [PATCH 02/11] =?UTF-8?q?CRM-=E5=9B=9E=E6=AC=BE=E8=AE=A1=E5=88=92?= =?UTF-8?q?=EF=BC=9A=E6=B7=BB=E5=8A=A0=E6=95=B0=E6=8D=AE=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../crm/enums/common/CrmBizTypeEnum.java | 3 +- .../CrmReceivablePlanController.java | 10 +-- .../receivable/CrmReceivablePlanMapper.java | 38 +++++++++-- .../permission/CrmPermissionServiceImpl.java | 1 + .../receivable/CrmReceivablePlanService.java | 9 +-- .../CrmReceivablePlanServiceImpl.java | 30 ++++++--- .../CrmCrmReceivablePlanServiceImplTest.java | 67 ++++++++++--------- .../main/resources/codegen/vue/api/api.js.vm | 11 ++- 8 files changed, 104 insertions(+), 65 deletions(-) diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/common/CrmBizTypeEnum.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/common/CrmBizTypeEnum.java index da24039b26..f0784cab2f 100644 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/common/CrmBizTypeEnum.java +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/common/CrmBizTypeEnum.java @@ -23,7 +23,8 @@ public enum CrmBizTypeEnum implements IntArrayValuable { CRM_BUSINESS(4, "商机"), CRM_CONTRACT(5, "合同"), CRM_PRODUCT(6, "产品"), - CRM_RECEIVABLE(7, "回款") + CRM_RECEIVABLE(7, "回款"), + CRM_RECEIVABLE_PLAN(8, "回款计划") ; public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmBizTypeEnum::getType).toArray(); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java index f8e2e6ecd1..a5167313f5 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java @@ -38,6 +38,7 @@ import java.util.Map; import java.util.stream.Stream; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; @@ -65,7 +66,7 @@ public class CrmReceivablePlanController { @Operation(summary = "创建回款计划") @PreAuthorize("@ss.hasPermission('crm:receivable-plan:create')") public CommonResult createReceivablePlan(@Valid @RequestBody CrmReceivablePlanCreateReqVO createReqVO) { - return success(receivablePlanService.createReceivablePlan(createReqVO)); + return success(receivablePlanService.createReceivablePlan(createReqVO, getLoginUserId())); } @PutMapping("/update") @@ -98,7 +99,7 @@ public class CrmReceivablePlanController { @Operation(summary = "获得回款计划分页") @PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')") public CommonResult> getReceivablePlanPage(@Valid CrmReceivablePlanPageReqVO pageReqVO) { - PageResult pageResult = receivablePlanService.getReceivablePlanPage(pageReqVO); + PageResult pageResult = receivablePlanService.getReceivablePlanPage(pageReqVO, getLoginUserId()); return success(convertDetailReceivablePlanPage(pageResult)); } @@ -106,7 +107,7 @@ public class CrmReceivablePlanController { @Operation(summary = "获得回款计划分页,基于指定客户") public CommonResult> getReceivablePlanPageByCustomer(@Valid CrmReceivablePlanPageReqVO pageReqVO) { Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空"); - PageResult pageResult = receivablePlanService.getReceivablePlanPageByCustomer(pageReqVO); + PageResult pageResult = receivablePlanService.getReceivablePlanPageByCustomerId(pageReqVO); return success(convertDetailReceivablePlanPage(pageResult)); } @@ -117,7 +118,8 @@ public class CrmReceivablePlanController { @OperateLog(type = EXPORT) public void exportReceivablePlanExcel(@Valid CrmReceivablePlanPageReqVO exportReqVO, HttpServletResponse response) throws IOException { - PageResult pageResult = receivablePlanService.getReceivablePlanPage(exportReqVO); + exportReqVO.setPageSize(PAGE_SIZE_NONE); + PageResult pageResult = receivablePlanService.getReceivablePlanPage(exportReqVO, getLoginUserId()); // 导出 Excel ExcelUtils.write(response, "回款计划.xls", "数据", CrmReceivablePlanRespVO.class, convertDetailReceivablePlanPage(pageResult).getList()); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivablePlanMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivablePlanMapper.java index 52d16f0e1b..5c6d40a71f 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivablePlanMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivablePlanMapper.java @@ -3,10 +3,17 @@ package cn.iocoder.yudao.module.crm.dal.mysql.receivable; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO; +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; +import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; +import java.util.Collection; +import java.util.List; + /** * 回款计划 Mapper * @@ -15,18 +22,37 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface CrmReceivablePlanMapper extends BaseMapperX { - default PageResult selectPage(CrmReceivablePlanPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .eqIfPresent(CrmReceivablePlanDO::getCustomerId, reqVO.getCustomerId()) - .eqIfPresent(CrmReceivablePlanDO::getContractId, reqVO.getContractId()) - .orderByDesc(CrmReceivablePlanDO::getId)); + default int updateOwnerUserIdById(Long id, Long ownerUserId) { + return update(new LambdaUpdateWrapper() + .eq(CrmReceivablePlanDO::getId, id) + .set(CrmReceivablePlanDO::getOwnerUserId, ownerUserId)); } - default PageResult selectPageByCustomer(CrmReceivablePlanPageReqVO reqVO) { + default PageResult selectPageByCustomerId(CrmReceivablePlanPageReqVO reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX() .eq(CrmReceivablePlanDO::getCustomerId, reqVO.getCustomerId()) // 必须传递 .eqIfPresent(CrmReceivablePlanDO::getContractId, reqVO.getContractId()) .orderByDesc(CrmReceivablePlanDO::getId)); } + default PageResult selectPage(CrmReceivablePlanPageReqVO pageReqVO, Long userId) { + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + // 拼接数据权限的查询条件 + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType(), CrmReceivablePlanDO::getId, + userId, pageReqVO.getSceneType(), Boolean.FALSE); + // 拼接自身的查询条件 + query.selectAll(CrmReceivablePlanDO.class) + .eqIfPresent(CrmReceivablePlanDO::getCustomerId, pageReqVO.getCustomerId()) + .eqIfPresent(CrmReceivablePlanDO::getContractId, pageReqVO.getContractId()) + .orderByDesc(CrmReceivablePlanDO::getId); + return selectJoinPage(pageReqVO, CrmReceivablePlanDO.class, query); + } + + default List selectBatchIds(Collection ids, Long userId) { + MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); + // 拼接数据权限的查询条件 + CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType(), ids, userId); + return selectJoinList(CrmReceivablePlanDO.class, query); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java index 58bd51149f..76f37f909a 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java @@ -138,6 +138,7 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { } @Override + @Transactional(rollbackFor = Exception.class) public void deletePermission(Integer bizType, Long bizId) { // 删除数据权限 int deletedCol = crmPermissionMapper.deletePermission(bizType, bizId); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanService.java index ba8a62d049..ded059b28c 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanService.java @@ -6,8 +6,8 @@ import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceiv 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.receivable.CrmReceivablePlanDO; - import jakarta.validation.Valid; + import java.util.Collection; import java.util.List; @@ -24,7 +24,7 @@ public interface CrmReceivablePlanService { * @param createReqVO 创建信息 * @return 编号 */ - Long createReceivablePlan(@Valid CrmReceivablePlanCreateReqVO createReqVO); + Long createReceivablePlan(@Valid CrmReceivablePlanCreateReqVO createReqVO, Long userId); /** * 更新回款计划 @@ -62,9 +62,10 @@ public interface CrmReceivablePlanService { * 数据权限:基于 {@link CrmReceivablePlanDO} 读取 * * @param pageReqVO 分页查询 + * @param userId 用户编号 * @return 回款计划分页 */ - PageResult getReceivablePlanPage(CrmReceivablePlanPageReqVO pageReqVO); + PageResult getReceivablePlanPage(CrmReceivablePlanPageReqVO pageReqVO, Long userId); /** * 获得回款计划分页,基于指定客户 @@ -74,6 +75,6 @@ public interface CrmReceivablePlanService { * @param pageReqVO 分页查询 * @return 回款计划分页 */ - PageResult getReceivablePlanPageByCustomer(CrmReceivablePlanPageReqVO pageReqVO); + PageResult getReceivablePlanPageByCustomerId(CrmReceivablePlanPageReqVO pageReqVO); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java index 7fe0556901..d2d1b510d5 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java @@ -17,10 +17,12 @@ import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission; 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.permission.CrmPermissionService; +import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; +import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import jakarta.annotation.Resource; import java.util.Collection; import java.util.List; @@ -28,7 +30,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; // TODO @liuhongfeng:参考 CrmReceivableServiceImpl 写的 todo 哈; -// TODO @puhui999:数据权限 + /** * 回款计划 Service 实现类 * @@ -45,9 +47,11 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { private CrmContractService contractService; @Resource private CrmCustomerService customerService; + @Resource + private CrmPermissionService crmPermissionService; @Override - public Long createReceivablePlan(CrmReceivablePlanCreateReqVO createReqVO) { + public Long createReceivablePlan(CrmReceivablePlanCreateReqVO createReqVO, Long userId) { // 插入 CrmReceivablePlanDO receivablePlan = CrmReceivablePlanConvert.INSTANCE.convert(createReqVO); receivablePlan.setFinishStatus(false); @@ -55,29 +59,33 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { checkReceivablePlan(receivablePlan); receivablePlanMapper.insert(receivablePlan); + // 创建数据权限 + crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType()) + .setBizId(receivablePlan.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 返回 return receivablePlan.getId(); } private void checkReceivablePlan(CrmReceivablePlanDO receivablePlan) { - if(ObjectUtil.isNull(receivablePlan.getContractId())){ + if (ObjectUtil.isNull(receivablePlan.getContractId())) { throw exception(CONTRACT_NOT_EXISTS); } CrmContractDO contract = contractService.getContract(receivablePlan.getContractId()); - if(ObjectUtil.isNull(contract)){ + if (ObjectUtil.isNull(contract)) { throw exception(CONTRACT_NOT_EXISTS); } CrmCustomerDO customer = customerService.getCustomer(receivablePlan.getCustomerId()); - if(ObjectUtil.isNull(customer)){ + if (ObjectUtil.isNull(customer)) { throw exception(CUSTOMER_NOT_EXISTS); } } @Override + @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) public void updateReceivablePlan(CrmReceivablePlanUpdateReqVO updateReqVO) { // 校验存在 validateReceivablePlanExists(updateReqVO.getId()); @@ -88,6 +96,7 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { } @Override + @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) public void deleteReceivablePlan(Long id) { // 校验存在 validateReceivablePlanExists(id); @@ -102,6 +111,7 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { } @Override + @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#id", level = CrmPermissionLevelEnum.READ) public CrmReceivablePlanDO getReceivablePlan(Long id) { return receivablePlanMapper.selectById(id); } @@ -115,14 +125,14 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { } @Override - public PageResult getReceivablePlanPage(CrmReceivablePlanPageReqVO pageReqVO) { - return receivablePlanMapper.selectPage(pageReqVO); + public PageResult getReceivablePlanPage(CrmReceivablePlanPageReqVO pageReqVO, Long userId) { + return receivablePlanMapper.selectPage(pageReqVO, userId); } @Override @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#pageReqVO.customerId", level = CrmPermissionLevelEnum.READ) - public PageResult getReceivablePlanPageByCustomer(CrmReceivablePlanPageReqVO pageReqVO) { - return receivablePlanMapper.selectPageByCustomer(pageReqVO); + public PageResult getReceivablePlanPageByCustomerId(CrmReceivablePlanPageReqVO pageReqVO) { + return receivablePlanMapper.selectPageByCustomerId(pageReqVO); } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/receivable/CrmCrmReceivablePlanServiceImplTest.java b/yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/receivable/CrmCrmReceivablePlanServiceImplTest.java index 7fa8986b0c..4f17abcba2 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/receivable/CrmCrmReceivablePlanServiceImplTest.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/receivable/CrmCrmReceivablePlanServiceImplTest.java @@ -7,12 +7,12 @@ import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceiv import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanUpdateReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO; import cn.iocoder.yudao.module.crm.dal.mysql.receivable.CrmReceivablePlanMapper; +import jakarta.annotation.Resource; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; -import jakarta.annotation.Resource; - +import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; @@ -22,6 +22,7 @@ import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.RECEIVABLE_PL import static org.junit.jupiter.api.Assertions.*; // TODO 芋艿:后续,需要补充测试用例 + /** * {@link CrmReceivablePlanServiceImpl} 的单元测试类 * @@ -43,7 +44,7 @@ public class CrmCrmReceivablePlanServiceImplTest extends BaseDbUnitTest { CrmReceivablePlanCreateReqVO reqVO = randomPojo(CrmReceivablePlanCreateReqVO.class); // 调用 - Long receivablePlanId = receivablePlanService.createReceivablePlan(reqVO); + Long receivablePlanId = receivablePlanService.createReceivablePlan(reqVO, 1L); // 断言 assertNotNull(receivablePlanId); // 校验记录的属性是否正确 @@ -87,8 +88,8 @@ public class CrmCrmReceivablePlanServiceImplTest extends BaseDbUnitTest { // 调用 receivablePlanService.deleteReceivablePlan(id); - // 校验数据不存在了 - assertNull(crmReceivablePlanMapper.selectById(id)); + // 校验数据不存在了 + assertNull(crmReceivablePlanMapper.selectById(id)); } @Test @@ -103,34 +104,34 @@ public class CrmCrmReceivablePlanServiceImplTest extends BaseDbUnitTest { @Test @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 public void testGetReceivablePlanPage() { - // mock 数据 - CrmReceivablePlanDO dbReceivablePlan = randomPojo(CrmReceivablePlanDO.class, o -> { // 等会查询到 - o.setPeriod(null); - o.setReturnTime(null); - o.setRemindDays(null); - o.setRemindTime(null); - o.setCustomerId(null); - o.setContractId(null); - o.setOwnerUserId(null); - o.setRemark(null); - o.setCreateTime(null); - }); - crmReceivablePlanMapper.insert(dbReceivablePlan); - // 测试 customerId 不匹配 - crmReceivablePlanMapper.insert(cloneIgnoreId(dbReceivablePlan, o -> o.setCustomerId(null))); - // 测试 contractId 不匹配 - crmReceivablePlanMapper.insert(cloneIgnoreId(dbReceivablePlan, o -> o.setContractId(null))); - // 准备参数 - CrmReceivablePlanPageReqVO reqVO = new CrmReceivablePlanPageReqVO(); - reqVO.setCustomerId(null); - reqVO.setContractId(null); - - // 调用 - PageResult pageResult = receivablePlanService.getReceivablePlanPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbReceivablePlan, pageResult.getList().get(0)); + // mock 数据 + CrmReceivablePlanDO dbReceivablePlan = randomPojo(CrmReceivablePlanDO.class, o -> { // 等会查询到 + o.setPeriod(null); + o.setReturnTime(null); + o.setRemindDays(null); + o.setRemindTime(null); + o.setCustomerId(null); + o.setContractId(null); + o.setOwnerUserId(null); + o.setRemark(null); + o.setCreateTime(null); + }); + crmReceivablePlanMapper.insert(dbReceivablePlan); + // 测试 customerId 不匹配 + crmReceivablePlanMapper.insert(cloneIgnoreId(dbReceivablePlan, o -> o.setCustomerId(null))); + // 测试 contractId 不匹配 + crmReceivablePlanMapper.insert(cloneIgnoreId(dbReceivablePlan, o -> o.setContractId(null))); + // 准备参数 + CrmReceivablePlanPageReqVO reqVO = new CrmReceivablePlanPageReqVO(); + reqVO.setCustomerId(null); + reqVO.setContractId(null); + reqVO.setPageSize(PAGE_SIZE_NONE); + // 调用 + PageResult pageResult = receivablePlanService.getReceivablePlanPage(reqVO, 1L); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbReceivablePlan, pageResult.getList().get(0)); } } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue/api/api.js.vm b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue/api/api.js.vm index fcc2e91973..835c0192eb 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue/api/api.js.vm +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue/api/api.js.vm @@ -63,7 +63,7 @@ export function export${simpleClassName}Excel(params) { responseType: 'blob' }) } -## 特殊:主子表专属逻辑 TODO @puhui999:下面方法的【空格】不太对 +## 特殊:主子表专属逻辑 #foreach ($subTable in $subTables) #set ($index = $foreach.count - 1) #set ($subSimpleClassName = $subSimpleClassNames.get($index)) @@ -76,7 +76,7 @@ export function export${simpleClassName}Excel(params) { // ==================== 子表($subTable.classComment) ==================== ## 情况一:MASTER_ERP 时,需要分查询页子表 - #if ( $table.templateType == 11 ) + #if ($table.templateType == 11) // 获得${subTable.classComment}分页 export function get${subSimpleClassName}Page(params) { return request({ @@ -87,7 +87,7 @@ export function export${simpleClassName}Excel(params) { } ## 情况二:非 MASTER_ERP 时,需要列表查询子表 #else - #if ( $subTable.subJoinMany ) + #if ($subTable.subJoinMany) // 获得${subTable.classComment}列表 export function get${subSimpleClassName}ListBy${SubJoinColumnName}(${subJoinColumn.javaField}) { return request({ @@ -106,7 +106,7 @@ export function export${simpleClassName}Excel(params) { #end #end ## 特殊:MASTER_ERP 时,支持单个的新增、修改、删除操作 - #if ( $table.templateType == 11 ) + #if ($table.templateType == 11) // 新增${subTable.classComment} export function create${subSimpleClassName}(data) { return request({ @@ -115,7 +115,6 @@ export function export${simpleClassName}Excel(params) { data }) } - // 修改${subTable.classComment} export function update${subSimpleClassName}(data) { return request({ @@ -124,7 +123,6 @@ export function export${simpleClassName}Excel(params) { data }) } - // 删除${subTable.classComment} export function delete${subSimpleClassName}(id) { return request({ @@ -132,7 +130,6 @@ export function export${simpleClassName}Excel(params) { method: 'delete' }) } - // 获得${subTable.classComment} export function get${subSimpleClassName}(id) { return request({ From 63431082e51c7d0d0d86ce92573ab1ae1f700553 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 11 Dec 2023 16:37:14 +0800 Subject: [PATCH 03/11] =?UTF-8?q?member:=20=E5=AE=8C=E5=96=84=E8=BF=9E?= =?UTF-8?q?=E7=BB=AD=E7=AD=BE=E5=88=B0=20review=20=E6=8F=90=E5=88=B0?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/common/util/date/DateUtils.java | 10 +++++ .../signin/MemberSignInRecordConvert.java | 6 +-- .../signin/MemberSignInRecordServiceImpl.java | 45 ++----------------- 3 files changed, 17 insertions(+), 44 deletions(-) diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java index c7e50a4875..53b5574f95 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java @@ -177,4 +177,14 @@ public class DateUtils { return LocalDateTimeUtil.isSameDay(date, LocalDateTime.now()); } + /** + * 是否昨天 + * + * @param date 日期 + * @return 是否 + */ + public static boolean isYesterday(LocalDateTime date) { + return LocalDateTimeUtil.isSameDay(date, LocalDateTime.now().minusDays(1)); + } + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/signin/MemberSignInRecordConvert.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/signin/MemberSignInRecordConvert.java index 63193b0296..9da5927f16 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/signin/MemberSignInRecordConvert.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/signin/MemberSignInRecordConvert.java @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordRespVO; import cn.iocoder.yudao.module.member.controller.app.signin.vo.record.AppMemberSignInRecordRespVO; import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInConfigDO; @@ -47,10 +48,9 @@ public interface MemberSignInRecordConvert { // 1. 计算是第几天签到 configs.sort(Comparator.comparing(MemberSignInConfigDO::getDay)); MemberSignInConfigDO lastConfig = CollUtil.getLast(configs); // 最大签到天数配置 - // 1.2. 计算今天是第几天签到 + // 1.2. 计算今天是第几天签到 (只有连续签到才加否则重置为 1) int day = 1; - // TODO @puhui999:要判断是不是昨天签到的;是否是昨天的判断,可以抽个方法到 util 里 - if (lastRecord != null) { + if (lastRecord != null && DateUtils.isYesterday(lastRecord.getCreateTime())) { day = lastRecord.getDay() + 1; } // 1.3 判断是否超出了最大签到配置 diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordServiceImpl.java index 79f7c8729d..cdf32105ab 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordServiceImpl.java @@ -19,14 +19,12 @@ import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; import cn.iocoder.yudao.module.member.service.level.MemberLevelService; import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService; import cn.iocoder.yudao.module.member.service.user.MemberUserService; +import jakarta.annotation.Resource; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; -import jakarta.annotation.Resource; -import java.time.LocalDate; -import java.util.Comparator; import java.util.List; import java.util.Set; @@ -77,50 +75,15 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService } summary.setTodaySignIn(DateUtils.isToday(lastRecord.getCreateTime())); - // 4. 校验今天是否签到,没有签到则直接返回 + // 4.1 校验今天是否签到,没有签到则直接返回 if (!summary.getTodaySignIn()) { return summary; } - // 4.1. 判断连续签到天数 - // TODO @puhui999:连续签到,可以基于 lastRecord 的 day 和当前时间判断呀?按 day 统计连续签到天数可能不准确 - // 1. day 只是记录第几天签到的有可能不连续,比如第一次签到是周一,第二次签到是周三这样 lastRecord 的 day 为 2 但是并不是连续的两天 - // 2. day 超出签到规则的最大天数会重置到从第一天开始签到(我理解为开始下一轮,类似一周签到七天七天结束下周又从周一开始签到) - // 1. 回复:周三签到,day 要归 1 呀。连续签到哈; - List signInRecords = signInRecordMapper.selectListByUserId(userId); - signInRecords.sort(Comparator.comparing(MemberSignInRecordDO::getCreateTime).reversed()); // 根据签到时间倒序 - summary.setContinuousDay(calculateConsecutiveDays(signInRecords)); + // 4.2 连续签到天数 + summary.setContinuousDay(lastRecord.getDay()); return summary; } - /** - * 计算连续签到天数 - * - * @param signInRecords 签到记录列表 - * @return int 连续签到天数 - */ - public int calculateConsecutiveDays(List signInRecords) { - int consecutiveDays = 1; // 初始连续天数为1 - LocalDate previousDate = null; - - for (MemberSignInRecordDO record : signInRecords) { - LocalDate currentDate = record.getCreateTime().toLocalDate(); - - if (previousDate != null) { - // 检查相邻两个日期是否连续 - if (currentDate.minusDays(1).isEqual(previousDate)) { - consecutiveDays++; - } else { - // 如果日期不连续,停止遍历 - break; - } - } - - previousDate = currentDate; - } - - return consecutiveDays; - } - @Override public PageResult getSignInRecordPage(MemberSignInRecordPageReqVO pageReqVO) { // 根据用户昵称查询出用户ids From c234f5b5f8f41c11b42f4e09357d77b902a82f84 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 11 Dec 2023 16:48:21 +0800 Subject: [PATCH 04/11] =?UTF-8?q?CRM:=20=E5=AE=8C=E5=96=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dal/mysql/business/CrmBusinessMapper.java | 7 ++++-- .../crm/dal/mysql/clue/CrmClueMapper.java | 7 ++++-- .../dal/mysql/contact/CrmContactMapper.java | 7 ++++-- .../dal/mysql/contract/CrmContractMapper.java | 10 +++++--- .../dal/mysql/customer/CrmCustomerMapper.java | 7 ++++-- .../mysql/receivable/CrmReceivableMapper.java | 7 ++++-- .../receivable/CrmReceivablePlanMapper.java | 7 ++++-- .../module/crm/util/CrmQueryWrapperUtils.java | 24 +++++++++++++------ 8 files changed, 54 insertions(+), 22 deletions(-) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java index d347300183..6dfdf8fada 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java @@ -38,8 +38,11 @@ public interface CrmBusinessMapper extends BaseMapperX { default PageResult selectPage(CrmBusinessPageReqVO pageReqVO, Long userId) { MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_BUSINESS.getType(), CrmBusinessDO::getId, - userId, pageReqVO.getSceneType(), Boolean.FALSE); + boolean condition = CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_BUSINESS.getType(), + CrmBusinessDO::getId, userId, pageReqVO.getSceneType(), Boolean.FALSE); + if (!condition) { + return PageResult.empty(); + } // 拼接自身的查询条件 query.selectAll(CrmBusinessDO.class) .likeIfPresent(CrmBusinessDO::getName, pageReqVO.getName()) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/clue/CrmClueMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/clue/CrmClueMapper.java index b78afc4fef..cd558dce40 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/clue/CrmClueMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/clue/CrmClueMapper.java @@ -30,8 +30,11 @@ public interface CrmClueMapper extends BaseMapperX { default PageResult selectPage(CrmCluePageReqVO pageReqVO, Long userId) { MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_LEADS.getType(), CrmClueDO::getId, - userId, pageReqVO.getSceneType(), pageReqVO.getPool()); + boolean condition = CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_LEADS.getType(), + CrmClueDO::getId, userId, pageReqVO.getSceneType(), pageReqVO.getPool()); + if (!condition) { + return PageResult.empty(); + } // 拼接自身的查询条件 query.selectAll(CrmClueDO.class) .likeIfPresent(CrmClueDO::getName, pageReqVO.getName()) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java index 2a0a746f57..adc4ced873 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/CrmContactMapper.java @@ -43,8 +43,11 @@ public interface CrmContactMapper extends BaseMapperX { default PageResult selectPage(CrmContactPageReqVO pageReqVO, Long userId) { MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTACT.getType(), CrmContactDO::getId, - userId, pageReqVO.getSceneType(), Boolean.FALSE); + boolean condition = CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CONTACT.getType(), + CrmContactDO::getId, userId, pageReqVO.getSceneType(), Boolean.FALSE); + if (!condition) { + return PageResult.empty(); + } // 拼接自身的查询条件 query.selectAll(CrmContactDO.class) .likeIfPresent(CrmContactDO::getName, pageReqVO.getName()) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java index 5bc9d5cb2d..60a5ab7857 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java @@ -40,9 +40,13 @@ public interface CrmContractMapper extends BaseMapperX { default PageResult selectPage(CrmContractPageReqVO pageReqVO, Long userId) { MPJLambdaWrapperX mpjLambdaWrapperX = new MPJLambdaWrapperX<>(); - // 构建数据权限连表条件 - CrmQueryWrapperUtils.appendPermissionCondition(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTACT.getType(), CrmContractDO::getId, - userId, pageReqVO.getSceneType(), Boolean.FALSE); + // 拼接数据权限的查询条件 + boolean condition = CrmQueryWrapperUtils.appendPermissionCondition(mpjLambdaWrapperX, CrmBizTypeEnum.CRM_CONTACT.getType(), + CrmContractDO::getId, userId, pageReqVO.getSceneType(), Boolean.FALSE); + if (!condition) { + return PageResult.empty(); + } + // 拼接自身的查询条件 mpjLambdaWrapperX.selectAll(CrmContractDO.class) .likeIfPresent(CrmContractDO::getNo, pageReqVO.getNo()) .likeIfPresent(CrmContractDO::getName, pageReqVO.getName()) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java index dece490560..b399ca7df6 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/customer/CrmCustomerMapper.java @@ -30,8 +30,11 @@ public interface CrmCustomerMapper extends BaseMapperX { default PageResult selectPage(CrmCustomerPageReqVO pageReqVO, Long userId) { MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), CrmCustomerDO::getId, - userId, pageReqVO.getSceneType(), pageReqVO.getPool()); + boolean condition = CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_CUSTOMER.getType(), + CrmCustomerDO::getId, userId, pageReqVO.getSceneType(), pageReqVO.getPool()); + if (!condition) { + return PageResult.empty(); + } // 拼接自身的查询条件 query.selectAll(CrmCustomerDO.class) .likeIfPresent(CrmCustomerDO::getName, pageReqVO.getName()) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java index 4839492c74..fca4e30e23 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java @@ -39,8 +39,11 @@ public interface CrmReceivableMapper extends BaseMapperX { default PageResult selectPage(CrmReceivablePageReqVO pageReqVO, Long userId) { MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE.getType(), CrmReceivableDO::getId, - userId, pageReqVO.getSceneType(), Boolean.FALSE); + boolean condition = CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE.getType(), + CrmReceivableDO::getId, userId, pageReqVO.getSceneType(), Boolean.FALSE); + if (!condition) { + return PageResult.empty(); + } // 拼接自身的查询条件 query.selectAll(CrmReceivableDO.class) .eqIfPresent(CrmReceivableDO::getNo, pageReqVO.getNo()) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivablePlanMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivablePlanMapper.java index 5c6d40a71f..e22c920b9a 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivablePlanMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivablePlanMapper.java @@ -38,8 +38,11 @@ public interface CrmReceivablePlanMapper extends BaseMapperX selectPage(CrmReceivablePlanPageReqVO pageReqVO, Long userId) { MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType(), CrmReceivablePlanDO::getId, - userId, pageReqVO.getSceneType(), Boolean.FALSE); + boolean condition = CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType(), + CrmReceivablePlanDO::getId, userId, pageReqVO.getSceneType(), Boolean.FALSE); + if (!condition) { + return PageResult.empty(); + } // 拼接自身的查询条件 query.selectAll(CrmReceivablePlanDO.class) .eqIfPresent(CrmReceivablePlanDO::getCustomerId, pageReqVO.getCustomerId()) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/util/CrmQueryWrapperUtils.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/util/CrmQueryWrapperUtils.java index e3e6be48b4..dfdb3ecb99 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/util/CrmQueryWrapperUtils.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/util/CrmQueryWrapperUtils.java @@ -33,10 +33,11 @@ public class CrmQueryWrapperUtils { * @param userId 用户编号 * @param sceneType 场景类型 * @param pool 公海 + * @return 是否 (是:需要执行查询,否:不需要查询调用方法直接返回空) */ // TODO @puhui999:bizId 直接传递会不会简单点 回复:还是需要 SFunction 因为分页连表时不知道 bizId 是多少 - public static , S> void appendPermissionCondition(T query, Integer bizType, SFunction bizId, - Long userId, Integer sceneType, Boolean pool) { + public static , S> boolean appendPermissionCondition(T query, Integer bizType, SFunction bizId, + Long userId, Integer sceneType, Boolean pool) { // 1. 构建数据权限连表条件 if (ObjUtil.notEqual(validateAdminUser(userId), Boolean.TRUE)) { // 管理员不需要数据权限 query.innerJoin(CrmPermissionDO.class, on -> @@ -59,10 +60,10 @@ public class CrmQueryWrapperUtils { // 2.3 场景三:下属负责的数据 if (CrmSceneTypeEnum.isSubordinate(sceneType)) { List subordinateUsers = getAdminUserApi().getUserListBySubordinate(userId); - // TODO @puhui999:如果为空,不拼接,就是查询了所有数据呀? - if (CollUtil.isNotEmpty(subordinateUsers)) { - query.in("owner_user_id", convertSet(subordinateUsers, AdminUserRespDTO::getId)); + if (CollUtil.isEmpty(subordinateUsers)) { + return false; } + query.in("owner_user_id", convertSet(subordinateUsers, AdminUserRespDTO::getId)); } // 3. 拼接公海的查询条件 @@ -71,6 +72,8 @@ public class CrmQueryWrapperUtils { } else { // 情况二:不是公海 query.isNotNull("owner_user_id"); } + + return true; } /** @@ -95,8 +98,6 @@ public class CrmQueryWrapperUtils { return AdminUserApiHolder.ADMIN_USER_API; } - // TODO @puhui999:需要实现; - /** * 校验用户是否是管理员 * @@ -104,6 +105,15 @@ public class CrmQueryWrapperUtils { * @return 是/否 */ private static boolean validateAdminUser(Long userId) { + // TODO 查询权限配置表用户的角色信息 + //CrmPermissionConfig permissionConfig = crmPermissionConfigService.getPermissionConfigByUserId(userId); + //if (permissionConfig == null) { + // return false; + //} + //// 校验是否为管理员 + //if (permissionConfig.getIsAdmin()){ + // return true; + //} return false; } From 8fa8f2890b3bc7095ccf07bfe5b9866218ece768 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 11 Dec 2023 17:36:09 +0800 Subject: [PATCH 05/11] =?UTF-8?q?CRM:=20=E7=BA=BF=E7=B4=A2=E3=80=81?= =?UTF-8?q?=E8=81=94=E7=B3=BB=E4=BA=BA=E3=80=81=E5=9B=9E=E6=AC=BE=E3=80=81?= =?UTF-8?q?=E5=9B=9E=E6=AC=BE=E8=AE=A1=E5=88=92=E6=96=B0=E5=A2=9E=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=9D=83=E9=99=90=E8=BD=AC=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vo/business/CrmBusinessTransferReqVO.java | 5 ++- .../admin/clue/CrmClueController.java | 8 +++++ .../admin/clue/vo/CrmClueTransferReqVO.java | 31 +++++++++++++++++++ .../admin/contact/CrmContactController.java | 16 +++++++--- .../admin/contract/CrmContractController.java | 8 ++--- .../customer/vo/CrmCustomerTransferReqVO.java | 5 ++- .../receivable/CrmReceivableController.java | 13 +++++--- .../CrmReceivablePlanController.java | 13 +++++--- .../plan/CrmReceivablePlanTransferReqVO.java | 31 +++++++++++++++++++ .../CrmReceivableTransferReqVO.java | 31 +++++++++++++++++++ .../crm/convert/clue/CrmClueConvert.java | 14 ++++++--- ...actConvert.java => CrmContactConvert.java} | 4 +-- ...ctConvert.java => CrmContractConvert.java} | 4 +-- .../receivable/CrmReceivableConvert.java | 6 ++++ .../receivable/CrmReceivablePlanConvert.java | 6 ++++ .../crm/service/clue/CrmClueService.java | 9 ++++++ .../crm/service/clue/CrmClueServiceImpl.java | 15 +++++++++ .../service/contact/CrmContactService.java | 9 ++++++ .../contact/CrmContactServiceImpl.java | 25 ++++++++++----- .../contract/CrmContractServiceImpl.java | 8 ++--- .../receivable/CrmReceivablePlanService.java | 9 ++++++ .../CrmReceivablePlanServiceImpl.java | 15 +++++++++ .../receivable/CrmReceivableService.java | 9 ++++++ .../receivable/CrmReceivableServiceImpl.java | 26 +++++++++++++--- 24 files changed, 274 insertions(+), 46 deletions(-) create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueTransferReqVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanTransferReqVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableTransferReqVO.java rename yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/{ContactConvert.java => CrmContactConvert.java} (97%) rename yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/{ContractConvert.java => CrmContractConvert.java} (95%) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java index c76c4873fb..a76c48cae9 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessTransferReqVO.java @@ -2,16 +2,15 @@ package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business; import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - import jakarta.validation.constraints.NotNull; +import lombok.Data; @Schema(description = "管理后台 - 商机转移 Request VO") @Data public class CrmBusinessTransferReqVO { @Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") - @NotNull(message = "联系人编号不能为空") + @NotNull(message = "商机编号不能为空") private Long id; /** diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java index 04f1b4db0e..7227b3d12a 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/CrmClueController.java @@ -88,4 +88,12 @@ public class CrmClueController { ExcelUtils.write(response, "线索.xls", "数据", CrmClueExcelVO.class, datas); } + @PutMapping("/transfer") + @Operation(summary = "线索转移") + @PreAuthorize("@ss.hasPermission('crm:clue:update')") + public CommonResult transfer(@Valid @RequestBody CrmClueTransferReqVO reqVO) { + clueService.transferClue(reqVO, getLoginUserId()); + return success(true); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueTransferReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueTransferReqVO.java new file mode 100644 index 0000000000..da71a1ec26 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueTransferReqVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.crm.controller.admin.clue.vo; + +import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Schema(description = "管理后台 - 线索转移 Request VO") +@Data +public class CrmClueTransferReqVO { + + @Schema(description = "线索编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") + @NotNull(message = "线索编号不能为空") + private Long id; + + /** + * 新负责人的用户编号 + */ + @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") + @NotNull(message = "新负责人的用户编号不能为空") + private Long newOwnerUserId; + + /** + * 老负责人加入团队后的权限级别。如果 null 说明移除 + * + * 关联 {@link CrmPermissionLevelEnum} + */ + @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + private Integer oldOwnerPermissionLevel; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java index 37db599630..9bb06a1bc3 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java @@ -9,7 +9,7 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*; -import cn.iocoder.yudao.module.crm.convert.contact.ContactConvert; +import cn.iocoder.yudao.module.crm.convert.contact.CrmContactConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants; @@ -100,7 +100,7 @@ public class CrmContactController { // 3. 直属上级 List parentContactList = contactService.getContactList( Collections.singletonList(contact.getParentId()), getLoginUserId()); - return success(ContactConvert.INSTANCE.convert(contact, userMap, customerList, parentContactList)); + return success(CrmContactConvert.INSTANCE.convert(contact, userMap, customerList, parentContactList)); } @GetMapping("/simple-all-list") @@ -110,7 +110,7 @@ public class CrmContactController { CrmContactPageReqVO pageReqVO = new CrmContactPageReqVO(); pageReqVO.setPageSize(PAGE_SIZE_NONE); List list = contactService.getContactPage(pageReqVO, getLoginUserId()).getList(); - return success(ContactConvert.INSTANCE.convertAllList(list)); + return success(CrmContactConvert.INSTANCE.convertAllList(list)); } @GetMapping("/page") @@ -161,7 +161,15 @@ public class CrmContactController { // 3. 直属上级 List parentContactList = contactService.getContactList( convertSet(contactList, CrmContactDO::getParentId), getLoginUserId()); - return ContactConvert.INSTANCE.convertPage(pageResult, userMap, crmCustomerDOList, parentContactList); + return CrmContactConvert.INSTANCE.convertPage(pageResult, userMap, crmCustomerDOList, parentContactList); + } + + @PutMapping("/transfer") + @Operation(summary = "联系人转移") + @PreAuthorize("@ss.hasPermission('crm:contact:update')") + public CommonResult transfer(@Valid @RequestBody CrmContactTransferReqVO reqVO) { + contactService.transferContact(reqVO, getLoginUserId()); + return success(true); } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java index 5086625a7d..f0442c4d3a 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java @@ -8,7 +8,7 @@ import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*; -import cn.iocoder.yudao.module.crm.convert.contract.ContractConvert; +import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert; 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.service.contract.CrmContractService; @@ -80,7 +80,7 @@ public class CrmContractController { @PreAuthorize("@ss.hasPermission('crm:contract:query')") public CommonResult getContract(@RequestParam("id") Long id) { CrmContractDO contract = contractService.getContract(id); - return success(ContractConvert.INSTANCE.convert(contract)); + return success(CrmContractConvert.INSTANCE.convert(contract)); } @GetMapping("/page") @@ -108,7 +108,7 @@ public class CrmContractController { PageResult pageResult = contractService.getContractPage(exportReqVO, getLoginUserId()); // 导出 Excel ExcelUtils.write(response, "合同.xls", "数据", CrmContractExcelVO.class, - ContractConvert.INSTANCE.convertList02(pageResult.getList())); + CrmContractConvert.INSTANCE.convertList02(pageResult.getList())); } /** @@ -128,7 +128,7 @@ public class CrmContractController { // 2. 获取创建人、负责人列表 Map userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList, contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); - return ContractConvert.INSTANCE.convertPage(pageResult, userMap, customerList); + return CrmContractConvert.INSTANCE.convertPage(pageResult, userMap, customerList); } @PutMapping("/transfer") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerTransferReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerTransferReqVO.java index c425520a91..9bdc43532c 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerTransferReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerTransferReqVO.java @@ -2,16 +2,15 @@ package cn.iocoder.yudao.module.crm.controller.admin.customer.vo; import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - import jakarta.validation.constraints.NotNull; +import lombok.Data; @Schema(description = "管理后台 - CRM 客户转移 Request VO") @Data public class CrmCustomerTransferReqVO { @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") - @NotNull(message = "联系人编号不能为空") + @NotNull(message = "客户编号不能为空") private Long id; /** diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java index 27dc063a55..a353491e79 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivableController.java @@ -7,10 +7,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -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.controller.admin.receivable.vo.receivable.*; 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.customer.CrmCustomerDO; @@ -144,4 +141,12 @@ public class CrmReceivableController { return CrmReceivableConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList); } + @PutMapping("/transfer") + @Operation(summary = "回款转移") + @PreAuthorize("@ss.hasPermission('crm:receivable:update')") + public CommonResult transfer(@Valid @RequestBody CrmReceivableTransferReqVO reqVO) { + receivableService.transferReceivable(reqVO, getLoginUserId()); + return success(true); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java index a5167313f5..9f3c238954 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/CrmReceivablePlanController.java @@ -7,10 +7,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -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.controller.admin.receivable.vo.plan.*; 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.customer.CrmCustomerDO; @@ -151,4 +148,12 @@ public class CrmReceivablePlanController { return CrmReceivablePlanConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList, receivableList); } + @PutMapping("/transfer") + @Operation(summary = "回款计划转移") + @PreAuthorize("@ss.hasPermission('crm:receivable-plan:update')") + public CommonResult transfer(@Valid @RequestBody CrmReceivablePlanTransferReqVO reqVO) { + receivablePlanService.transferReceivablePlan(reqVO, getLoginUserId()); + return success(true); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanTransferReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanTransferReqVO.java new file mode 100644 index 0000000000..09f85e419a --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanTransferReqVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan; + +import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Schema(description = "管理后台 - CRM 回款计划转移 Request VO") +@Data +public class CrmReceivablePlanTransferReqVO { + + @Schema(description = "回款计划编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") + @NotNull(message = "回款计划编号不能为空") + private Long id; + + /** + * 新负责人的用户编号 + */ + @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") + @NotNull(message = "新负责人的用户编号不能为空") + private Long newOwnerUserId; + + /** + * 老负责人加入团队后的权限级别。如果 null 说明移除 + * + * 关联 {@link CrmPermissionLevelEnum} + */ + @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + private Integer oldOwnerPermissionLevel; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableTransferReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableTransferReqVO.java new file mode 100644 index 0000000000..f94ce4c1b2 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableTransferReqVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable; + +import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +@Schema(description = "管理后台 - CRM 回款转移 Request VO") +@Data +public class CrmReceivableTransferReqVO { + + @Schema(description = "回款编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") + @NotNull(message = "回款编号不能为空") + private Long id; + + /** + * 新负责人的用户编号 + */ + @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") + @NotNull(message = "新负责人的用户编号不能为空") + private Long newOwnerUserId; + + /** + * 老负责人加入团队后的权限级别。如果 null 说明移除 + * + * 关联 {@link CrmPermissionLevelEnum} + */ + @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + private Integer oldOwnerPermissionLevel; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/clue/CrmClueConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/clue/CrmClueConvert.java index 76ea428c78..2649065a14 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/clue/CrmClueConvert.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/clue/CrmClueConvert.java @@ -1,13 +1,14 @@ package cn.iocoder.yudao.module.crm.convert.clue; -import java.util.*; - import cn.iocoder.yudao.framework.common.pojo.PageResult; - -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.*; import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; +import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +import java.util.List; /** * 线索 Convert @@ -29,4 +30,7 @@ public interface CrmClueConvert { List convertList02(List list); + @Mapping(target = "bizId", source = "reqVO.id") + CrmPermissionTransferReqBO convert(CrmClueTransferReqVO reqVO, Long userId); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/ContactConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java similarity index 97% rename from yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/ContactConvert.java rename to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java index b907c3e0c3..421e3cd989 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/ContactConvert.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java @@ -25,9 +25,9 @@ import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAnd * @author 芋道源码 */ @Mapper -public interface ContactConvert { +public interface CrmContactConvert { - ContactConvert INSTANCE = Mappers.getMapper(ContactConvert.class); + CrmContactConvert INSTANCE = Mappers.getMapper(CrmContactConvert.class); CrmContactDO convert(CrmContactCreateReqVO bean); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/ContractConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java similarity index 95% rename from yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/ContractConvert.java rename to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java index 195a08301c..74b7a46635 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/ContractConvert.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java @@ -22,9 +22,9 @@ import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAnd * @author dhb52 */ @Mapper -public interface ContractConvert { +public interface CrmContractConvert { - ContractConvert INSTANCE = Mappers.getMapper(ContractConvert.class); + CrmContractConvert INSTANCE = Mappers.getMapper(CrmContractConvert.class); CrmContractDO convert(CrmContractCreateReqVO bean); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivableConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivableConvert.java index 27502103d2..e7340fc86c 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivableConvert.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivableConvert.java @@ -3,12 +3,15 @@ package cn.iocoder.yudao.module.crm.convert.receivable; 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.CrmReceivableRespVO; +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.dal.dataobject.contract.CrmContractDO; 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.service.permission.bo.CrmPermissionTransferReqBO; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import org.mapstruct.Mapper; +import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; import java.util.List; @@ -58,4 +61,7 @@ public interface CrmReceivableConvert { findAndThen(userMap, Long.parseLong(receivable.getCreator()), user -> receivable.setCreatorName(user.getNickname())); } + @Mapping(target = "bizId", source = "reqVO.id") + CrmPermissionTransferReqBO convert(CrmReceivableTransferReqVO reqVO, Long userId); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivablePlanConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivablePlanConvert.java index a89140d07c..70e9308805 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivablePlanConvert.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/receivable/CrmReceivablePlanConvert.java @@ -3,13 +3,16 @@ package cn.iocoder.yudao.module.crm.convert.receivable; 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.CrmReceivablePlanRespVO; +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.dal.dataobject.contract.CrmContractDO; 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.CrmReceivablePlanDO; +import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import org.mapstruct.Mapper; +import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; import java.util.List; @@ -63,4 +66,7 @@ public interface CrmReceivablePlanConvert { findAndThen(userMap, Long.parseLong(receivablePlan.getCreator()), user -> receivablePlan.setCreatorName(user.getNickname())); } + @Mapping(target = "bizId", source = "reqVO.id") + CrmPermissionTransferReqBO convert(CrmReceivablePlanTransferReqVO reqVO, Long userId); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java index 52290e1068..f5dd48bfa6 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.service.clue; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueCreateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueUpdateReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; import jakarta.validation.Valid; @@ -64,4 +65,12 @@ public interface CrmClueService { */ PageResult getCluePage(CrmCluePageReqVO pageReqVO, Long userId); + /** + * 线索转移 + * + * @param reqVO 请求 + * @param userId 用户编号 + */ + void transferClue(CrmClueTransferReqVO reqVO, Long userId); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java index 63e2fcbd2b..414a52d170 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java @@ -5,6 +5,7 @@ import cn.hutool.core.collection.ListUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueCreateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueUpdateReqVO; import cn.iocoder.yudao.module.crm.convert.clue.CrmClueConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; @@ -101,4 +102,18 @@ public class CrmClueServiceImpl implements CrmClueService { return clueMapper.selectPage(pageReqVO, userId); } + @Override + public void transferClue(CrmClueTransferReqVO reqVO, Long userId) { + // 1 校验线索是否存在 + validateClueExists(reqVO.getId()); + + // 2.1 数据权限转移 + crmPermissionService.transferPermission( + CrmClueConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_LEADS.getType())); + // 2.2 设置新的负责人 + clueMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); + + // 3. TODO 记录转移日志 + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java index 46cbec699b..7d0c1dc0c7 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.service.contact; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactCreateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactTransferReqVO; import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactUpdateReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; @@ -79,4 +80,12 @@ public interface CrmContactService { */ PageResult getContactPageByCustomerId(CrmContactPageReqVO pageVO); + /** + * 联系人转移 + * + * @param reqVO 请求 + * @param userId 用户编号 + */ + void transferContact(CrmContactTransferReqVO reqVO, Long userId); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java index 5ee1e2b299..50b1bd4be9 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java @@ -3,11 +3,8 @@ package cn.iocoder.yudao.module.crm.service.contact; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactBaseVO; -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactCreateReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactPageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactUpdateReqVO; -import cn.iocoder.yudao.module.crm.convert.contact.ContactConvert; +import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*; +import cn.iocoder.yudao.module.crm.convert.contact.CrmContactConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; import cn.iocoder.yudao.module.crm.dal.mysql.contact.CrmContactMapper; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; @@ -56,7 +53,7 @@ public class CrmContactServiceImpl implements CrmContactService { // 1.1 校验 validateRelationDataExists(createReqVO); // 1.2 插入 - CrmContactDO contact = ContactConvert.INSTANCE.convert(createReqVO); + CrmContactDO contact = CrmContactConvert.INSTANCE.convert(createReqVO); contactMapper.insert(contact); // 2. 创建数据权限 @@ -73,7 +70,7 @@ public class CrmContactServiceImpl implements CrmContactService { validateContactExists(updateReqVO.getId()); validateRelationDataExists(updateReqVO); // 2. 更新 - CrmContactDO updateObj = ContactConvert.INSTANCE.convert(updateReqVO); + CrmContactDO updateObj = CrmContactConvert.INSTANCE.convert(updateReqVO); contactMapper.updateById(updateObj); } @@ -139,4 +136,18 @@ public class CrmContactServiceImpl implements CrmContactService { return contactMapper.selectPageByCustomerId(pageVO); } + @Override + public void transferContact(CrmContactTransferReqVO reqVO, Long userId) { + // 1 校验联系人是否存在 + validateContactExists(reqVO.getId()); + + // 2.1 数据权限转移 + crmPermissionService.transferPermission( + CrmContactConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTACT.getType())); + // 2.2 设置新的负责人 + contactMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); + + // 3. TODO 记录转移日志 + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java index 7f1b20a0eb..6f2fc16ab1 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java @@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractCreat 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.CrmContractUpdateReqVO; -import cn.iocoder.yudao.module.crm.convert.contract.ContractConvert; +import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; @@ -44,7 +44,7 @@ public class CrmContractServiceImpl implements CrmContractService { @Override public Long createContract(CrmContractCreateReqVO createReqVO, Long userId) { // 插入 - CrmContractDO contract = ContractConvert.INSTANCE.convert(createReqVO); + CrmContractDO contract = CrmContractConvert.INSTANCE.convert(createReqVO); contractMapper.insert(contract); // 创建数据权限 @@ -61,7 +61,7 @@ public class CrmContractServiceImpl implements CrmContractService { // 校验存在 validateContractExists(updateReqVO.getId()); // 更新 - CrmContractDO updateObj = ContractConvert.INSTANCE.convert(updateReqVO); + CrmContractDO updateObj = CrmContractConvert.INSTANCE.convert(updateReqVO); contractMapper.updateById(updateObj); } @@ -118,7 +118,7 @@ public class CrmContractServiceImpl implements CrmContractService { // 2.1 数据权限转移 crmPermissionService.transferPermission( - ContractConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType())); + CrmContractConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType())); // 2.2 设置负责人 contractMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanService.java index ded059b28c..93d05e6516 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanService.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.service.receivable; 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.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.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO; @@ -77,4 +78,12 @@ public interface CrmReceivablePlanService { */ PageResult getReceivablePlanPageByCustomerId(CrmReceivablePlanPageReqVO pageReqVO); + /** + * 回款计划转移 + * + * @param reqVO 请求 + * @param userId 用户编号 + */ + void transferReceivablePlan(CrmReceivablePlanTransferReqVO reqVO, Long userId); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java index d2d1b510d5..39154dd5db 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java @@ -6,6 +6,7 @@ import cn.hutool.core.util.ObjectUtil; 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.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.convert.receivable.CrmReceivablePlanConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; @@ -135,4 +136,18 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { return receivablePlanMapper.selectPageByCustomerId(pageReqVO); } + @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 记录转移日志 + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java index 8f7984afe5..79be4b338e 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.service.receivable; 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.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.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO; @@ -77,4 +78,12 @@ public interface CrmReceivableService { */ PageResult getReceivablePageByCustomerId(CrmReceivablePageReqVO pageReqVO); + /** + * 回款转移 + * + * @param reqVO 请求 + * @param userId 用户编号 + */ + void transferReceivable(CrmReceivableTransferReqVO reqVO, Long userId); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java index 18a289be26..38bf5266ef 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 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.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.convert.receivable.CrmReceivableConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; @@ -20,6 +21,7 @@ import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission; 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.permission.CrmPermissionService; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -48,6 +50,8 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { private CrmCustomerService customerService; @Resource private CrmReceivablePlanService receivablePlanService; + @Resource + private CrmPermissionService crmPermissionService; // TODO @liuhongfeng:创建还款后,是不是什么时候,要更新 plan? @Override @@ -70,22 +74,22 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { // TODO @liuhongfeng:这里的括号要注意排版; private void checkReceivable(CrmReceivableDO receivable) { // TODO @liuhongfeng:这个放在参数校验合适 - if(ObjectUtil.isNull(receivable.getContractId())){ + if (ObjectUtil.isNull(receivable.getContractId())) { throw exception(CONTRACT_NOT_EXISTS); } CrmContractDO contract = contractService.getContract(receivable.getContractId()); - if(ObjectUtil.isNull(contract)){ + if (ObjectUtil.isNull(contract)) { throw exception(CONTRACT_NOT_EXISTS); } CrmCustomerDO customer = customerService.getCustomer(receivable.getCustomerId()); - if(ObjectUtil.isNull(customer)){ + if (ObjectUtil.isNull(customer)) { throw exception(CUSTOMER_NOT_EXISTS); } CrmReceivablePlanDO receivablePlan = receivablePlanService.getReceivablePlan(receivable.getPlanId()); - if(ObjectUtil.isNull(receivablePlan)){ + if (ObjectUtil.isNull(receivablePlan)) { throw exception(RECEIVABLE_PLAN_NOT_EXISTS); } @@ -140,4 +144,18 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { 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 记录转移日志 + } + } From 72cebfca143680718310ea30b06bf216b53dd1a5 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 12 Dec 2023 16:23:48 +0800 Subject: [PATCH 06/11] =?UTF-8?q?CombinationRecordApiImpl=20=E9=87=8D?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E4=B8=80=E4=B8=8B=20recordService=20?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=20combinationRecordService=20=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E5=92=8C=20mzt-biz-log=20=E7=BB=84=E4=BB=B6=E7=9A=84?= =?UTF-8?q?=20bean=20=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/combination/CombinationRecordApiImpl.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java index a9db09ec89..354f5b3595 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java @@ -7,11 +7,10 @@ import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivity import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService; +import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import jakarta.annotation.Resource; - import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINATION_RECORD_NOT_EXISTS; @@ -25,21 +24,21 @@ import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINA public class CombinationRecordApiImpl implements CombinationRecordApi { @Resource - private CombinationRecordService recordService; + private CombinationRecordService combinationRecordService; @Override public void validateCombinationRecord(Long userId, Long activityId, Long headId, Long skuId, Integer count) { - recordService.validateCombinationRecord(userId, activityId, headId, skuId, count); + combinationRecordService.validateCombinationRecord(userId, activityId, headId, skuId, count); } @Override public CombinationRecordCreateRespDTO createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) { - return CombinationActivityConvert.INSTANCE.convert4(recordService.createCombinationRecord(reqDTO)); + return CombinationActivityConvert.INSTANCE.convert4(combinationRecordService.createCombinationRecord(reqDTO)); } @Override public boolean isCombinationRecordSuccess(Long userId, Long orderId) { - CombinationRecordDO record = recordService.getCombinationRecord(userId, orderId); + CombinationRecordDO record = combinationRecordService.getCombinationRecord(userId, orderId); if (record == null) { throw exception(COMBINATION_RECORD_NOT_EXISTS); } @@ -48,7 +47,7 @@ public class CombinationRecordApiImpl implements CombinationRecordApi { @Override public CombinationValidateJoinRespDTO validateJoinCombination(Long userId, Long activityId, Long headId, Long skuId, Integer count) { - return recordService.validateJoinCombination(userId, activityId, headId, skuId, count); + return combinationRecordService.validateJoinCombination(userId, activityId, headId, skuId, count); } } From c5cc818a4901024ee950926ef0d4989404495547 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 12 Dec 2023 22:29:40 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E6=97=A5=E5=BF=97=EF=BC=9A=E9=9B=86=E6=88=90=20mzt-biz-log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-dependencies/pom.xml | 12 ++ .../module/crm/enums/LogRecordConstants.java | 18 +++ .../admin/customer/CrmCustomerController.http | 11 +- .../admin/customer/CrmCustomerController.java | 6 +- .../customer/CrmCustomerServiceImpl.java | 6 + .../yudao-module-system-api/pom.xml | 7 + .../dal/dataobject/logger/OperateLogV2DO.java | 144 ++++++++++++++++++ .../dal/mysql/logger/OperateLogV2Mapper.java | 31 ++++ .../YudaoOperateLogV2Configuration.java | 53 +++++++ .../system/framework/bizlog/package-info.java | 1 + .../service/AdminUserParseFunction.java | 56 +++++++ .../bizlog/service/ILogRecordServiceImpl.java | 39 +++++ .../service/logger/OperateLogService.java | 7 + .../service/logger/OperateLogServiceImpl.java | 14 +- 14 files changed, 399 insertions(+), 6 deletions(-) create mode 100644 yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogV2DO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/logger/OperateLogV2Mapper.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/config/YudaoOperateLogV2Configuration.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/package-info.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/AdminUserParseFunction.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index 00ac143564..da0c4e7350 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -62,6 +62,7 @@ 0.1.55 2.9.1 2.7.0 + 3.0.6 3.5.0 4.11.0 @@ -99,6 +100,17 @@ yudao-spring-boot-starter-biz-operatelog ${revision} + + io.github.mouzt + bizlog-sdk + ${bizlog-sdk.version} + + + org.springframework.boot + spring-boot-starter + + + cn.iocoder.boot yudao-spring-boot-starter-biz-dict diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java new file mode 100644 index 0000000000..909a0d34a2 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.crm.enums; + +/** + * CRM 操作日志枚举 + * + * @author HUIHUI + */ +public interface LogRecordConstants { + + String WHO = "【{getAdminUserById{#userId}}】"; + + //======================= 客户转移操作日志 ======================= + + String TRANSFER_CUSTOMER_LOG_TYPE = "客户转移"; + String TRANSFER_CUSTOMER_LOG_SUCCESS = WHO + "把客户【{{#crmCustomer.name}}】负责人【{getAdminUserById{#crmCustomer.ownerUserId}}】转移给了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; + String TRANSFER_CUSTOMER_LOG_FAIL = ""; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.http b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.http index f6ecb473bc..770171d572 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.http +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.http @@ -1,6 +1,13 @@ -### 请求 /update -GET {{baseUrl}}/crm/customer/page?pageNo=1&pageSize=10&name="张三" +### 请求 /transfer +PUT {{baseUrl}}/crm/customer/transfer +Content-Type: application/json Authorization: Bearer {{token}} tenant-id: {{adminTenentId}} +{ + "id": 11, + "newOwnerUserId": 127, + "oldOwnerPermissionLevel": 2 +} + diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java index f06e26e4a3..e29da139e1 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java @@ -17,14 +17,14 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; import org.mapstruct.ap.internal.util.Collections; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import jakarta.annotation.Resource; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.Valid; import java.io.IOException; import java.util.List; import java.util.Map; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java index fd10092555..402cbcb31f 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java @@ -9,12 +9,15 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerUpdat import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper; +import cn.iocoder.yudao.module.crm.enums.LogRecordConstants; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import com.mzt.logapi.context.LogRecordContext; +import com.mzt.logapi.starter.annotation.LogRecord; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -126,11 +129,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @Override @Transactional(rollbackFor = Exception.class) + @LogRecord(success = LogRecordConstants.TRANSFER_CUSTOMER_LOG_SUCCESS, + type = LogRecordConstants.TRANSFER_CUSTOMER_LOG_TYPE, bizNo = "{{#reqVO.id}}") @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { // 1. 校验客户是否存在 validateCustomer(reqVO.getId()); + LogRecordContext.putVariable("crmCustomer", customerMapper.selectById(reqVO.getId())); // 2.1 数据权限转移 crmPermissionService.transferPermission( CrmCustomerConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())); diff --git a/yudao-module-system/yudao-module-system-api/pom.xml b/yudao-module-system/yudao-module-system-api/pom.xml index 655db05a72..416413cd6f 100644 --- a/yudao-module-system/yudao-module-system-api/pom.xml +++ b/yudao-module-system/yudao-module-system-api/pom.xml @@ -22,6 +22,13 @@ yudao-common + + + + io.github.mouzt + bizlog-sdk + + org.springframework.boot diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogV2DO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogV2DO.java new file mode 100644 index 0000000000..3473954a71 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogV2DO.java @@ -0,0 +1,144 @@ +package cn.iocoder.yudao.module.system.dal.dataobject.logger; + +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; +import java.util.Map; + +/** + * 操作日志表 + * + * @author 芋道源码 + */ +@TableName(value = "system_operate_log_v2", autoResultMap = true) +@KeySequence("system_operate_log_seq_v2") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +public class OperateLogV2DO extends BaseDO { + + /** + * {@link #javaMethodArgs} 的最大长度 + */ + public static final Integer JAVA_METHOD_ARGS_MAX_LENGTH = 8000; + + /** + * {@link #resultData} 的最大长度 + */ + public static final Integer RESULT_MAX_LENGTH = 4000; + + /** + * 日志主键 + */ + @TableId + private Long id; + /** + * 链路追踪编号 + * + * 一般来说,通过链路追踪编号,可以将访问日志,错误日志,链路追踪日志,logger 打印日志等,结合在一起,从而进行排错。 + */ + private String traceId; + /** + * 用户编号 + * + * 关联 MemberUserDO 的 id 属性,或者 AdminUserDO 的 id 属性 + */ + private Long userId; + /** + * 用户类型 + * + * 关联 {@link UserTypeEnum} + */ + private Integer userType; + /** + * 操作模块 + */ + private String module; + /** + * 操作名 + */ + private String name; + /** + * 操作分类 + * + * 枚举 {@link OperateTypeEnum} + */ + private Integer type; + /** + * 操作内容,记录整个操作的明细 + * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 + */ + private String content; + /** + * 拓展字段,有些复杂的业务,需要记录一些字段 + * 例如说,记录订单编号,则可以添加 key 为 "orderId",value 为订单编号 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private Map exts; + + /** + * 请求方法名 + */ + private String requestMethod; + /** + * 请求地址 + */ + private String requestUrl; + /** + * 用户 IP + */ + private String userIp; + /** + * 浏览器 UA + */ + private String userAgent; + + /** + * Java 方法名 + */ + private String javaMethod; + /** + * Java 方法的参数 + * + * 实际格式为 Map + * 不使用 @TableField(typeHandler = FastjsonTypeHandler.class) 注解的原因是,数据库存储有长度限制,会进行裁剪,会导致 JSON 反序列化失败 + * 其中,key 为参数名,value 为参数值 + */ + private String javaMethodArgs; + /** + * 开始时间 + */ + private LocalDateTime startTime; + /** + * 执行时长,单位:毫秒 + */ + private Integer duration; + /** + * 结果码 + * + * 目前使用的 {@link CommonResult#getCode()} 属性 + */ + private Integer resultCode; + /** + * 结果提示 + * + * 目前使用的 {@link CommonResult#getMsg()} 属性 + */ + private String resultMsg; + /** + * 结果数据 + * + * 如果是对象,则使用 JSON 格式化 + */ + private String resultData; + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/logger/OperateLogV2Mapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/logger/OperateLogV2Mapper.java new file mode 100644 index 0000000000..e778320a77 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/logger/OperateLogV2Mapper.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.system.dal.mysql.logger; + +import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; + +@Mapper +public interface OperateLogV2Mapper extends BaseMapperX { + + default PageResult selectPage(OperateLogPageReqVO reqVO, Collection userIds) { + LambdaQueryWrapperX query = new LambdaQueryWrapperX() + .likeIfPresent(OperateLogV2DO::getModule, reqVO.getModule()) + .inIfPresent(OperateLogV2DO::getUserId, userIds) + .eqIfPresent(OperateLogV2DO::getType, reqVO.getType()) + .betweenIfPresent(OperateLogV2DO::getStartTime, reqVO.getStartTime()); + if (Boolean.TRUE.equals(reqVO.getSuccess())) { + query.eq(OperateLogV2DO::getResultCode, GlobalErrorCodeConstants.SUCCESS.getCode()); + } else if (Boolean.FALSE.equals(reqVO.getSuccess())) { + query.gt(OperateLogV2DO::getResultCode, GlobalErrorCodeConstants.SUCCESS.getCode()); + } + query.orderByDesc(OperateLogV2DO::getId); // 降序 + return selectPage(reqVO, query); + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/config/YudaoOperateLogV2Configuration.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/config/YudaoOperateLogV2Configuration.java new file mode 100644 index 0000000000..04fbdefeaf --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/config/YudaoOperateLogV2Configuration.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.system.framework.bizlog.config; + +import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; +import cn.iocoder.yudao.module.system.api.logger.OperateLogApi; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.framework.bizlog.service.AdminUserParseFunction; +import cn.iocoder.yudao.module.system.framework.bizlog.service.ILogRecordServiceImpl; +import com.mzt.logapi.beans.Operator; +import com.mzt.logapi.service.IOperatorGetService; +import com.mzt.logapi.starter.annotation.EnableLogRecord; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Optional; + + +/** + * 使用 @Configuration 是因为 mzt-biz-log 的配置类是 @Configuration 的 + * + * @author HUIHUI + */ +@Configuration(proxyBeanMethods = false) +@EnableLogRecord(tenant = "${yudao.info.base-package}") +@Slf4j +public class YudaoOperateLogV2Configuration { + + //======================= mzt-biz-log ======================= + + @Bean + public ILogRecordServiceImpl iLogRecordServiceImpl(OperateLogApi operateLogApi) { + log.info("ILogRecordServiceImpl 初始化"); + return new ILogRecordServiceImpl(operateLogApi); + } + + @Bean + public IOperatorGetService operatorGetLoginUserIdService() { + // 获取操作用户编号 + return () -> Optional.of(WebFrameworkUtils.getLoginUserId()) + .map(a -> { + Operator operator = new Operator(); + operator.setOperatorId(a.toString()); + return operator; + }) + .orElseThrow(() -> new IllegalArgumentException("user is null")); + } + + @Bean + public AdminUserParseFunction adminUserParseFunction(AdminUserApi adminUserApi) { + return new AdminUserParseFunction(adminUserApi); + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/package-info.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/package-info.java new file mode 100644 index 0000000000..c96f3a0c1b --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.system.framework.bizlog; \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/AdminUserParseFunction.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/AdminUserParseFunction.java new file mode 100644 index 0000000000..d29e3bac16 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/AdminUserParseFunction.java @@ -0,0 +1,56 @@ +package cn.iocoder.yudao.module.system.framework.bizlog.service; + +import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import com.mzt.logapi.service.IParseFunction; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +/** + * 自定义函数-通过用户编号获取用户信息 + * + * @author HUIHUI + */ +@Slf4j +@RequiredArgsConstructor +public class AdminUserParseFunction implements IParseFunction { + + private final AdminUserApi adminUserApi; + + @Override + public boolean executeBefore() { + return true; + } + + @Override + public String functionName() { + return "getAdminUserById"; + } + + @Override + public String apply(Object value) { + if (value == null) { + log.warn("(getAdminUserById) 解析异常参数为 null"); + return ""; + } + if (StrUtil.isEmpty(value.toString())) { + log.warn("(getAdminUserById) 解析异常参数为空"); + return ""; + } + + // 获取用户信息 + AdminUserRespDTO user = adminUserApi.getUser(Long.parseLong(value.toString())); + if (user == null) { + log.warn("(getAdminUserById) 获取用户信息失败,参数为:{}", value); + return ""; + } + // 返回格式 芋道源码(13888888888) + String nickname = user.getNickname(); + if (ObjUtil.isNotEmpty(user.getMobile())) { + return nickname.concat("(").concat(user.getMobile()).concat(")"); + } + return nickname; + } +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java new file mode 100644 index 0000000000..2e2c4b5bd6 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.system.framework.bizlog.service; + +import cn.iocoder.yudao.module.system.api.logger.OperateLogApi; +import com.mzt.logapi.beans.LogRecord; +import com.mzt.logapi.service.ILogRecordService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.util.Collections; +import java.util.List; + +/** + * 操作日志 ILogRecordService 实现类 + * + * 基于 {@link OperateLogApi} 实现,记录操作日志 + * + * @author HUIHUI + */ +@Slf4j +@RequiredArgsConstructor +public class ILogRecordServiceImpl implements ILogRecordService { + + private final OperateLogApi operateLogApi; + + @Override + public void record(LogRecord logRecord) { + log.info("【logRecord】log={}", logRecord); + } + + @Override + public List queryLog(String bizNo, String type) { + return Collections.emptyList(); + } + + @Override + public List queryLogByBizNo(String bizNo, String type, String subType) { + return Collections.emptyList(); + } +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogService.java index 89e562c65a..9aada4999a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogService.java @@ -19,6 +19,13 @@ public interface OperateLogService { */ void createOperateLog(OperateLogCreateReqDTO createReqDTO); + /** + * 记录操作日志 V2 + * + * @param createReqDTO 操作日志请求 + */ + void createOperateLogV2(OperateLogCreateReqDTO createReqDTO); + /** * 获得操作日志分页列表 * diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java index 0181e30812..32f68a3b1f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java @@ -8,14 +8,16 @@ import cn.iocoder.yudao.framework.common.util.string.StrUtils; import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO; import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO; +import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.dal.mysql.logger.OperateLogMapper; +import cn.iocoder.yudao.module.system.dal.mysql.logger.OperateLogV2Mapper; import cn.iocoder.yudao.module.system.service.user.AdminUserService; +import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import jakarta.annotation.Resource; import java.util.Collection; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; @@ -34,6 +36,8 @@ public class OperateLogServiceImpl implements OperateLogService { @Resource private OperateLogMapper operateLogMapper; + @Resource + private OperateLogV2Mapper operateLogV2Mapper; @Resource private AdminUserService userService; @@ -46,6 +50,14 @@ public class OperateLogServiceImpl implements OperateLogService { operateLogMapper.insert(log); } + @Override + public void createOperateLogV2(OperateLogCreateReqDTO createReqDTO) { + OperateLogV2DO log = BeanUtils.toBean(createReqDTO, OperateLogV2DO.class); + log.setJavaMethodArgs(StrUtils.maxLength(log.getJavaMethodArgs(), JAVA_METHOD_ARGS_MAX_LENGTH)); + log.setResultData(StrUtils.maxLength(log.getResultData(), RESULT_MAX_LENGTH)); + operateLogV2Mapper.insert(log); + } + @Override public PageResult getOperateLogPage(OperateLogPageReqVO pageReqVO) { // 处理基于用户昵称的查询 From 13d6c42a4869cec4608f94cc46d2876797916a8f Mon Sep 17 00:00:00 2001 From: puhui999 Date: Tue, 12 Dec 2023 22:42:50 +0800 Subject: [PATCH 08/11] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E6=97=A5=E5=BF=97=EF=BC=9A=E9=9B=86=E6=88=90=20mzt-biz-log=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customer/CrmCustomerServiceImpl.java | 2 +- .../YudaoOperateLogV2Configuration.java | 39 +------------------ .../AdminUserParseFunction.java | 10 +++-- .../bizlog/service/ILogRecordServiceImpl.java | 8 ++-- 4 files changed, 13 insertions(+), 46 deletions(-) rename yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/{service => function}/AdminUserParseFunction.java (87%) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java index 402cbcb31f..1418525842 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java @@ -135,7 +135,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { // 1. 校验客户是否存在 validateCustomer(reqVO.getId()); - + // 添加 crmCustomer 到日志上下文 LogRecordContext.putVariable("crmCustomer", customerMapper.selectById(reqVO.getId())); // 2.1 数据权限转移 crmPermissionService.transferPermission( diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/config/YudaoOperateLogV2Configuration.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/config/YudaoOperateLogV2Configuration.java index 04fbdefeaf..a74dc343ff 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/config/YudaoOperateLogV2Configuration.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/config/YudaoOperateLogV2Configuration.java @@ -1,53 +1,16 @@ package cn.iocoder.yudao.module.system.framework.bizlog.config; -import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; -import cn.iocoder.yudao.module.system.api.logger.OperateLogApi; -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; -import cn.iocoder.yudao.module.system.framework.bizlog.service.AdminUserParseFunction; -import cn.iocoder.yudao.module.system.framework.bizlog.service.ILogRecordServiceImpl; -import com.mzt.logapi.beans.Operator; -import com.mzt.logapi.service.IOperatorGetService; import com.mzt.logapi.starter.annotation.EnableLogRecord; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import java.util.Optional; - /** - * 使用 @Configuration 是因为 mzt-biz-log 的配置类是 @Configuration 的 + * * * @author HUIHUI */ @Configuration(proxyBeanMethods = false) @EnableLogRecord(tenant = "${yudao.info.base-package}") -@Slf4j public class YudaoOperateLogV2Configuration { - //======================= mzt-biz-log ======================= - - @Bean - public ILogRecordServiceImpl iLogRecordServiceImpl(OperateLogApi operateLogApi) { - log.info("ILogRecordServiceImpl 初始化"); - return new ILogRecordServiceImpl(operateLogApi); - } - - @Bean - public IOperatorGetService operatorGetLoginUserIdService() { - // 获取操作用户编号 - return () -> Optional.of(WebFrameworkUtils.getLoginUserId()) - .map(a -> { - Operator operator = new Operator(); - operator.setOperatorId(a.toString()); - return operator; - }) - .orElseThrow(() -> new IllegalArgumentException("user is null")); - } - - @Bean - public AdminUserParseFunction adminUserParseFunction(AdminUserApi adminUserApi) { - return new AdminUserParseFunction(adminUserApi); - } - } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/AdminUserParseFunction.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AdminUserParseFunction.java similarity index 87% rename from yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/AdminUserParseFunction.java rename to yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AdminUserParseFunction.java index d29e3bac16..5e4d4f2547 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/AdminUserParseFunction.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AdminUserParseFunction.java @@ -1,12 +1,13 @@ -package cn.iocoder.yudao.module.system.framework.bizlog.service; +package cn.iocoder.yudao.module.system.framework.bizlog.function; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import com.mzt.logapi.service.IParseFunction; -import lombok.RequiredArgsConstructor; +import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; /** * 自定义函数-通过用户编号获取用户信息 @@ -14,10 +15,11 @@ import lombok.extern.slf4j.Slf4j; * @author HUIHUI */ @Slf4j -@RequiredArgsConstructor +@Component public class AdminUserParseFunction implements IParseFunction { - private final AdminUserApi adminUserApi; + @Resource + private AdminUserApi adminUserApi; @Override public boolean executeBefore() { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java index 2e2c4b5bd6..23584d247b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java @@ -3,8 +3,9 @@ package cn.iocoder.yudao.module.system.framework.bizlog.service; import cn.iocoder.yudao.module.system.api.logger.OperateLogApi; import com.mzt.logapi.beans.LogRecord; import com.mzt.logapi.service.ILogRecordService; -import lombok.RequiredArgsConstructor; +import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; import java.util.Collections; import java.util.List; @@ -17,10 +18,11 @@ import java.util.List; * @author HUIHUI */ @Slf4j -@RequiredArgsConstructor +@Service public class ILogRecordServiceImpl implements ILogRecordService { - private final OperateLogApi operateLogApi; + @Resource + private OperateLogApi operateLogApi; @Override public void record(LogRecord logRecord) { From c74881c8f0c9214515cce672ed62a60ade91a968 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 13 Dec 2023 15:18:19 +0800 Subject: [PATCH 09/11] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E6=97=A5=E5=BF=97=EF=BC=9A=E9=9B=86=E6=88=90=20mzt-biz-log=203?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/crm/enums/LogRecordConstants.java | 15 +++- .../admin/customer/CrmCustomerController.http | 5 +- .../admin/customer/CrmCustomerController.java | 1 - .../customer/CrmCustomerServiceImpl.java | 6 +- .../dal/dataobject/logger/OperateLogV2DO.java | 70 +---------------- .../dal/mysql/logger/OperateLogV2Mapper.java | 10 +-- .../YudaoOperateLogV2Configuration.java | 5 +- .../function/AdminUserParseFunction.java | 4 +- .../bizlog/service/ILogRecordServiceImpl.java | 43 +++++++++- .../service/logger/OperateLogServiceImpl.java | 2 - .../logger/bo/OperateLogV2CreateReqBO.java | 78 +++++++++++++++++++ 11 files changed, 145 insertions(+), 94 deletions(-) create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/bo/OperateLogV2CreateReqBO.java diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java index 909a0d34a2..a3a9b6db40 100644 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java @@ -7,12 +7,21 @@ package cn.iocoder.yudao.module.crm.enums; */ public interface LogRecordConstants { - String WHO = "【{getAdminUserById{#userId}}】"; + //======================= 客户模块类型 ======================= + // TODO puhui999: 确保模块命名方式为 module + 子模块名称的方式。统一定义模块名称是为了方便查询各自记录的操作日志,列如说:查询客户【张三的操作日志】就可以 module + bizId + String CRM_LEADS = "CRM-线索"; + String CRM_CUSTOMER = "CRM-客户"; + String CRM_CONTACT = "CRM-联系人"; + String CRM_BUSINESS = "CRM-商机"; + String CRM_CONTRACT = "CRM-合同"; + String CRM_PRODUCT = "CRM-产品"; + String CRM_RECEIVABLE = "CRM-回款"; + String CRM_RECEIVABLE_PLAN = "CRM-回款计划"; //======================= 客户转移操作日志 ======================= - String TRANSFER_CUSTOMER_LOG_TYPE = "客户转移"; - String TRANSFER_CUSTOMER_LOG_SUCCESS = WHO + "把客户【{{#crmCustomer.name}}】负责人【{getAdminUserById{#crmCustomer.ownerUserId}}】转移给了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; + String TRANSFER_CUSTOMER_LOG_SUCCESS = "把客户【{{#crmCustomer == null ? '' : #crmCustomer.name}}】负责人从" + + "【{getAdminUserById{#crmCustomer == null ? '' : #crmCustomer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; String TRANSFER_CUSTOMER_LOG_FAIL = ""; } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.http b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.http index 770171d572..25e16366ca 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.http +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.http @@ -5,9 +5,8 @@ Authorization: Bearer {{token}} tenant-id: {{adminTenentId}} { - "id": 11, - "newOwnerUserId": 127, - "oldOwnerPermissionLevel": 2 + "id": 10, + "newOwnerUserId": 127 } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java index e29da139e1..854c9538ae 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java @@ -123,7 +123,6 @@ public class CrmCustomerController { } @PutMapping("/transfer") - @Operation(summary = "客户转移") @PreAuthorize("@ss.hasPermission('crm:customer:update')") public CommonResult transfer(@Valid @RequestBody CrmCustomerTransferReqVO reqVO) { customerService.transferCustomer(reqVO, getLoginUserId()); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java index 1418525842..52725a675f 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerUpdat import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.dal.mysql.customer.CrmCustomerMapper; -import cn.iocoder.yudao.module.crm.enums.LogRecordConstants; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission; @@ -27,6 +26,8 @@ import java.util.*; 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.LogRecordConstants.CRM_CUSTOMER; +import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.TRANSFER_CUSTOMER_LOG_SUCCESS; import static java.util.Collections.singletonList; /** @@ -129,8 +130,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @Override @Transactional(rollbackFor = Exception.class) - @LogRecord(success = LogRecordConstants.TRANSFER_CUSTOMER_LOG_SUCCESS, - type = LogRecordConstants.TRANSFER_CUSTOMER_LOG_TYPE, bizNo = "{{#reqVO.id}}") + @LogRecord(success = TRANSFER_CUSTOMER_LOG_SUCCESS, type = CRM_CUSTOMER, subType = "客户转移", bizNo = "{{#reqVO.id}}") @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { // 1. 校验客户是否存在 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogV2DO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogV2DO.java index 3473954a71..246f456128 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogV2DO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogV2DO.java @@ -1,22 +1,15 @@ package cn.iocoder.yudao.module.system.dal.dataobject.logger; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum; import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import lombok.Data; import lombok.EqualsAndHashCode; -import java.time.LocalDateTime; -import java.util.Map; - /** - * 操作日志表 + * 操作日志表 V2 * * @author 芋道源码 */ @@ -26,16 +19,6 @@ import java.util.Map; @EqualsAndHashCode(callSuper = true) public class OperateLogV2DO extends BaseDO { - /** - * {@link #javaMethodArgs} 的最大长度 - */ - public static final Integer JAVA_METHOD_ARGS_MAX_LENGTH = 8000; - - /** - * {@link #resultData} 的最大长度 - */ - public static final Integer RESULT_MAX_LENGTH = 4000; - /** * 日志主键 */ @@ -68,22 +51,14 @@ public class OperateLogV2DO extends BaseDO { */ private String name; /** - * 操作分类 - * - * 枚举 {@link OperateTypeEnum} + * 操作模块业务编号 */ - private Integer type; + private Long bizId; /** * 操作内容,记录整个操作的明细 * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 */ private String content; - /** - * 拓展字段,有些复杂的业务,需要记录一些字段 - * 例如说,记录订单编号,则可以添加 key 为 "orderId",value 为订单编号 - */ - @TableField(typeHandler = JacksonTypeHandler.class) - private Map exts; /** * 请求方法名 @@ -102,43 +77,4 @@ public class OperateLogV2DO extends BaseDO { */ private String userAgent; - /** - * Java 方法名 - */ - private String javaMethod; - /** - * Java 方法的参数 - * - * 实际格式为 Map - * 不使用 @TableField(typeHandler = FastjsonTypeHandler.class) 注解的原因是,数据库存储有长度限制,会进行裁剪,会导致 JSON 反序列化失败 - * 其中,key 为参数名,value 为参数值 - */ - private String javaMethodArgs; - /** - * 开始时间 - */ - private LocalDateTime startTime; - /** - * 执行时长,单位:毫秒 - */ - private Integer duration; - /** - * 结果码 - * - * 目前使用的 {@link CommonResult#getCode()} 属性 - */ - private Integer resultCode; - /** - * 结果提示 - * - * 目前使用的 {@link CommonResult#getMsg()} 属性 - */ - private String resultMsg; - /** - * 结果数据 - * - * 如果是对象,则使用 JSON 格式化 - */ - private String resultData; - } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/logger/OperateLogV2Mapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/logger/OperateLogV2Mapper.java index e778320a77..e08686914e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/logger/OperateLogV2Mapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/logger/OperateLogV2Mapper.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.system.dal.mysql.logger; -import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; @@ -16,14 +15,7 @@ public interface OperateLogV2Mapper extends BaseMapperX { default PageResult selectPage(OperateLogPageReqVO reqVO, Collection userIds) { LambdaQueryWrapperX query = new LambdaQueryWrapperX() .likeIfPresent(OperateLogV2DO::getModule, reqVO.getModule()) - .inIfPresent(OperateLogV2DO::getUserId, userIds) - .eqIfPresent(OperateLogV2DO::getType, reqVO.getType()) - .betweenIfPresent(OperateLogV2DO::getStartTime, reqVO.getStartTime()); - if (Boolean.TRUE.equals(reqVO.getSuccess())) { - query.eq(OperateLogV2DO::getResultCode, GlobalErrorCodeConstants.SUCCESS.getCode()); - } else if (Boolean.FALSE.equals(reqVO.getSuccess())) { - query.gt(OperateLogV2DO::getResultCode, GlobalErrorCodeConstants.SUCCESS.getCode()); - } + .inIfPresent(OperateLogV2DO::getUserId, userIds); query.orderByDesc(OperateLogV2DO::getId); // 降序 return selectPage(reqVO, query); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/config/YudaoOperateLogV2Configuration.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/config/YudaoOperateLogV2Configuration.java index a74dc343ff..9e6a9dd85e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/config/YudaoOperateLogV2Configuration.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/config/YudaoOperateLogV2Configuration.java @@ -3,14 +3,13 @@ package cn.iocoder.yudao.module.system.framework.bizlog.config; import com.mzt.logapi.starter.annotation.EnableLogRecord; import org.springframework.context.annotation.Configuration; - /** - * + * mzt-biz-log 配置类 * * @author HUIHUI */ @Configuration(proxyBeanMethods = false) -@EnableLogRecord(tenant = "${yudao.info.base-package}") +@EnableLogRecord(tenant = "") // 貌似用不上 tenant 这玩意给个空好啦 public class YudaoOperateLogV2Configuration { } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AdminUserParseFunction.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AdminUserParseFunction.java index 5e4d4f2547..21459be6b3 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AdminUserParseFunction.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AdminUserParseFunction.java @@ -34,11 +34,11 @@ public class AdminUserParseFunction implements IParseFunction { @Override public String apply(Object value) { if (value == null) { - log.warn("(getAdminUserById) 解析异常参数为 null"); + //log.warn("(getAdminUserById) 解析异常参数为 null"); return ""; } if (StrUtil.isEmpty(value.toString())) { - log.warn("(getAdminUserById) 解析异常参数为空"); + //log.warn("(getAdminUserById) 解析异常参数为空"); return ""; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java index 23584d247b..161d4eca6f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java @@ -1,9 +1,14 @@ package cn.iocoder.yudao.module.system.framework.bizlog.service; +import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; +import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; +import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import cn.iocoder.yudao.module.system.api.logger.OperateLogApi; +import cn.iocoder.yudao.module.system.service.logger.bo.OperateLogV2CreateReqBO; import com.mzt.logapi.beans.LogRecord; import com.mzt.logapi.service.ILogRecordService; import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -26,7 +31,42 @@ public class ILogRecordServiceImpl implements ILogRecordService { @Override public void record(LogRecord logRecord) { - log.info("【logRecord】log={}", logRecord); + OperateLogV2CreateReqBO reqBO = new OperateLogV2CreateReqBO(); + // 补全通用字段 + reqBO.setTraceId(TracerUtils.getTraceId()); + // 补充用户信息 + fillUserFields(reqBO); + // 补全模块信息 + fillModuleFields(reqBO, logRecord); + // 补全请求信息 + fillRequestFields(reqBO); + // 异步记录日志 + log.info("操作日志 ===> {}", reqBO); + } + + private static void fillUserFields(OperateLogV2CreateReqBO reqBO) { + reqBO.setUserId(WebFrameworkUtils.getLoginUserId()); + reqBO.setUserType(WebFrameworkUtils.getLoginUserType()); + } + + public static void fillModuleFields(OperateLogV2CreateReqBO reqBO, LogRecord logRecord) { + reqBO.setModule(logRecord.getType()); // 大模块类型如 crm-客户 + reqBO.setName(logRecord.getSubType());// 操作名称如 转移客户 + reqBO.setBizId(Long.parseLong(logRecord.getBizNo())); // 操作模块业务编号 + reqBO.setContent(logRecord.getAction());// 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 + } + + private static void fillRequestFields(OperateLogV2CreateReqBO reqBO) { + // 获得 Request 对象 + HttpServletRequest request = ServletUtils.getRequest(); + if (request == null) { + return; + } + // 补全请求信息 + reqBO.setRequestMethod(request.getMethod()); + reqBO.setRequestUrl(request.getRequestURI()); + reqBO.setUserIp(ServletUtils.getClientIP(request)); + reqBO.setUserAgent(ServletUtils.getUserAgent(request)); } @Override @@ -38,4 +78,5 @@ public class ILogRecordServiceImpl implements ILogRecordService { public List queryLogByBizNo(String bizNo, String type, String subType) { return Collections.emptyList(); } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java index 32f68a3b1f..840913f622 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java @@ -53,8 +53,6 @@ public class OperateLogServiceImpl implements OperateLogService { @Override public void createOperateLogV2(OperateLogCreateReqDTO createReqDTO) { OperateLogV2DO log = BeanUtils.toBean(createReqDTO, OperateLogV2DO.class); - log.setJavaMethodArgs(StrUtils.maxLength(log.getJavaMethodArgs(), JAVA_METHOD_ARGS_MAX_LENGTH)); - log.setResultData(StrUtils.maxLength(log.getResultData(), RESULT_MAX_LENGTH)); operateLogV2Mapper.insert(log); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/bo/OperateLogV2CreateReqBO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/bo/OperateLogV2CreateReqBO.java new file mode 100644 index 0000000000..8c1675879b --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/bo/OperateLogV2CreateReqBO.java @@ -0,0 +1,78 @@ +package cn.iocoder.yudao.module.system.service.logger.bo; + +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; + +/** + * 系统操作日志 Create Req BO + * + * @author HUIHUI + */ +@Data +public class OperateLogV2CreateReqBO { + + /** + * 链路追踪编号 + * + * 一般来说,通过链路追踪编号,可以将访问日志,错误日志,链路追踪日志,logger 打印日志等,结合在一起,从而进行排错。 + */ + private String traceId; + /** + * 用户编号 + * + * 关联 MemberUserDO 的 id 属性,或者 AdminUserDO 的 id 属性 + */ + @NotEmpty(message = "用户编号不能为空") + private Long userId; + /** + * 用户类型 + * + * 关联 {@link UserTypeEnum} + */ + @NotEmpty(message = "用户类型不能为空") + private Integer userType; + /** + * 操作模块 + */ + @NotEmpty(message = "操作模块不能为空") + private String module; + /** + * 操作名 + */ + @NotEmpty(message = "操作名不能为空") + private String name; + /** + * 操作模块业务编号 + */ + @NotEmpty(message = "操作模块业务编号不能为空") + private Long bizId; + /** + * 操作内容,记录整个操作的明细 + * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 + */ + @NotEmpty(message = "操作内容不能为空") + private String content; + + /** + * 请求方法名 + */ + @NotEmpty(message = "请求方法名不能为空") + private String requestMethod; + /** + * 请求地址 + */ + @NotEmpty(message = "请求地址不能为空") + private String requestUrl; + /** + * 用户 IP + */ + @NotEmpty(message = "用户 IP 不能为空") + private String userIp; + /** + * 浏览器 UA + */ + @NotEmpty(message = "浏览器 UA 不能为空") + private String userAgent; + +} From 3c74b22933cd84bcf2c62293d76a823af29a100b Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 13 Dec 2023 17:45:43 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E6=97=A5=E5=BF=97=EF=BC=9A=E9=9B=86=E6=88=90=20mzt-biz-log=204?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/crm/enums/LogRecordConstants.java | 3 +- yudao-module-crm/yudao-module-crm-biz/pom.xml | 4 ++ .../admin/customer/CrmCustomerController.http | 4 ++ .../admin/customer/CrmCustomerController.java | 3 +- .../admin/customer/vo/CrmCustomerBaseVO.java | 29 ++++++++++-- .../function/CrmIndustryParseFunction.java | 46 +++++++++++++++++++ .../function/CrmLevelParseFunction.java | 46 +++++++++++++++++++ .../function/CrmSourceParseFunction.java | 46 +++++++++++++++++++ .../crm/framework/bizlog/package-info.java | 1 + .../customer/CrmCustomerServiceImpl.java | 15 ++++-- .../function/AdminUserParseFunction.java | 5 -- .../bizlog/function/AreaParseFunction.java | 39 ++++++++++++++++ 12 files changed, 224 insertions(+), 17 deletions(-) create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/function/CrmIndustryParseFunction.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/function/CrmLevelParseFunction.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/function/CrmSourceParseFunction.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/package-info.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AreaParseFunction.java diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java index a3a9b6db40..92da847fdd 100644 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java @@ -20,8 +20,7 @@ public interface LogRecordConstants { //======================= 客户转移操作日志 ======================= - String TRANSFER_CUSTOMER_LOG_SUCCESS = "把客户【{{#crmCustomer == null ? '' : #crmCustomer.name}}】负责人从" + - "【{getAdminUserById{#crmCustomer == null ? '' : #crmCustomer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; + String TRANSFER_CUSTOMER_LOG_SUCCESS = "把客户【{{#crmCustomer.name}}】的负责人从【{getAdminUserById{#crmCustomer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; String TRANSFER_CUSTOMER_LOG_FAIL = ""; } diff --git a/yudao-module-crm/yudao-module-crm-biz/pom.xml b/yudao-module-crm/yudao-module-crm-biz/pom.xml index 15bbc932de..9e1a9e1521 100644 --- a/yudao-module-crm/yudao-module-crm-biz/pom.xml +++ b/yudao-module-crm/yudao-module-crm-biz/pom.xml @@ -60,6 +60,10 @@ cn.iocoder.boot yudao-spring-boot-starter-excel + + cn.iocoder.boot + yudao-spring-boot-starter-biz-dict + diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.http b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.http index 25e16366ca..6a5c6774c8 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.http +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.http @@ -9,4 +9,8 @@ tenant-id: {{adminTenentId}} "newOwnerUserId": 127 } +### 自定义日志记录结果 +### 操作日志 ===> OperateLogV2CreateReqBO(traceId=, userId=1, userType=2, module=CRM-客户, name=客户转移, bizId=10, content=把客户【张三】的负责人从【芋道源码(15612345678)】变更为了【tttt】, requestMethod=PUT, requestUrl=/admin-api/crm/customer/transfer, userIp=127.0.0.1, userAgent=Apache-HttpClient/4.5.14 (Java/17.0.9)) +### diff 日志 +### | 操作日志 ===> OperateLogV2CreateReqBO(traceId=, userId=1, userType=2, module=CRM-客户, name=更新客户, bizId=11, content=更新了客户【所属行业】从【H 住宿和餐饮业】修改为【D 电力、热力、燃气及水生产和供应业】;【客户等级】从【C (非优先客户)】修改为【A (重点客户)】;【客户来源】从【线上咨询】修改为【预约上门】, requestMethod=PUT, requestUrl=/admin-api/crm/customer/update, userIp=0:0:0:0:0:0:0:1, userAgent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java index 854c9538ae..6ce57abf10 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java @@ -59,7 +59,7 @@ public class CrmCustomerController { } @PutMapping("/update") - @Operation(summary = "更新客户") + //@Operation(summary = "更新客户") @PreAuthorize("@ss.hasPermission('crm:customer:update')") public CommonResult updateCustomer(@Valid @RequestBody CrmCustomerUpdateReqVO updateReqVO) { customerService.updateCustomer(updateReqVO); @@ -123,6 +123,7 @@ public class CrmCustomerController { } @PutMapping("/transfer") + //@Operation(summary = "客户转移") @PreAuthorize("@ss.hasPermission('crm:customer:update')") public CommonResult transfer(@Valid @RequestBody CrmCustomerTransferReqVO reqVO) { customerService.transferCustomer(reqVO, getLoginUserId()); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerBaseVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerBaseVO.java index 3d03ba8075..8049c344b9 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerBaseVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/vo/CrmCustomerBaseVO.java @@ -3,17 +3,20 @@ package cn.iocoder.yudao.module.crm.controller.admin.customer.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.framework.common.validation.Mobile; import cn.iocoder.yudao.framework.common.validation.Telephone; +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; import cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerLevelEnum; +import com.mzt.logapi.starter.annotation.DiffLogField; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.Size; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; +import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY; /** * 客户 Base VO,提供给添加、修改、详细的子 VO 使用 @@ -23,57 +26,73 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ public class CrmCustomerBaseVO { @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") + @DiffLogField(name = "客户名称") @NotEmpty(message = "客户名称不能为空") private String name; @Schema(description = "所属行业", example = "1") + @DiffLogField(name = "所属行业", function = "getIndustryById") + @DictFormat(CRM_CUSTOMER_INDUSTRY) private Integer industryId; @Schema(description = "客户等级", example = "2") + @DiffLogField(name = "客户等级", function = "getLevel") @InEnum(CrmCustomerLevelEnum.class) private Integer level; @Schema(description = "客户来源", example = "3") + @DiffLogField(name = "客户来源", function = "getSource") private Integer source; @Schema(description = "手机", example = "18000000000") + @DiffLogField(name = "手机") @Mobile private String mobile; @Schema(description = "电话", example = "18000000000") + @DiffLogField(name = "电话") @Telephone private String telephone; @Schema(description = "网址", example = "https://www.baidu.com") + @DiffLogField(name = "网址") private String website; @Schema(description = "QQ", example = "123456789") + @DiffLogField(name = "QQ") @Size(max = 20, message = "QQ长度不能超过 20 个字符") private String qq; - @Schema(description = "wechat", example = "123456789") + @Schema(description = "微信", example = "123456789") + @DiffLogField(name = "微信") @Size(max = 255, message = "微信长度不能超过 255 个字符") private String wechat; - @Schema(description = "email", example = "123456789@qq.com") + @Schema(description = "邮箱", example = "123456789@qq.com") + @DiffLogField(name = "邮箱") @Email(message = "邮箱格式不正确") @Size(max = 255, message = "邮箱长度不能超过 255 个字符") private String email; @Schema(description = "客户描述", example = "任意文字") + @DiffLogField(name = "客户描述") @Size(max = 4096, message = "客户描述长度不能超过 4096 个字符") private String description; @Schema(description = "备注", example = "随便") + @DiffLogField(name = "备注") private String remark; @Schema(description = "地区编号", example = "20158") + @DiffLogField(name = "地区编号", function = "getAreaById") private Integer areaId; @Schema(description = "详细地址", example = "北京市海淀区") + @DiffLogField(name = "详细地址") private String detailAddress; @Schema(description = "下次联系时间") + @DiffLogField(name = "下次联系时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime contactNextTime; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/function/CrmIndustryParseFunction.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/function/CrmIndustryParseFunction.java new file mode 100644 index 0000000000..0a468dfa89 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/function/CrmIndustryParseFunction.java @@ -0,0 +1,46 @@ +package cn.iocoder.yudao.module.crm.framework.bizlog.function; + +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; +import com.mzt.logapi.service.IParseFunction; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY; + +/** + * 自定义函数-通过行业编号获取行业信息 + * + * @author HUIHUI + */ +@Slf4j +@Component +public class CrmIndustryParseFunction implements IParseFunction { + + @Override + public boolean executeBefore() { + return true; // 先转换值后对比 + } + + @Override + public String functionName() { + return "getIndustryById"; + } + + @Override + public String apply(Object value) { + if (value == null) { + return ""; + } + if (StrUtil.isEmpty(value.toString())) { + return ""; + } + + // 获取行业信息 + try { + return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_INDUSTRY, value.toString()); + } catch (Exception ignored) { + } + return ""; + } +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/function/CrmLevelParseFunction.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/function/CrmLevelParseFunction.java new file mode 100644 index 0000000000..15af42d5e6 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/function/CrmLevelParseFunction.java @@ -0,0 +1,46 @@ +package cn.iocoder.yudao.module.crm.framework.bizlog.function; + +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; +import com.mzt.logapi.service.IParseFunction; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_LEVEL; + +/** + * 自定义函数-通过客户等级编号获取客户等级信息 + * + * @author HUIHUI + */ +@Slf4j +@Component +public class CrmLevelParseFunction implements IParseFunction { + + @Override + public boolean executeBefore() { + return true; // 先转换值后对比 + } + + @Override + public String functionName() { + return "getLevel"; + } + + @Override + public String apply(Object value) { + if (value == null) { + return ""; + } + if (StrUtil.isEmpty(value.toString())) { + return ""; + } + + // 获取客户等级信息 + try { + return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_LEVEL, value.toString()); + } catch (Exception ignored) { + } + return ""; + } +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/function/CrmSourceParseFunction.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/function/CrmSourceParseFunction.java new file mode 100644 index 0000000000..0a630dfe69 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/function/CrmSourceParseFunction.java @@ -0,0 +1,46 @@ +package cn.iocoder.yudao.module.crm.framework.bizlog.function; + +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; +import com.mzt.logapi.service.IParseFunction; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_SOURCE; + +/** + * 自定义函数-通过客户来源编号获取客户来源信息 + * + * @author HUIHUI + */ +@Slf4j +@Component +public class CrmSourceParseFunction implements IParseFunction { + + @Override + public boolean executeBefore() { + return true; // 先转换值后对比 + } + + @Override + public String functionName() { + return "getSource"; + } + + @Override + public String apply(Object value) { + if (value == null) { + return ""; + } + if (StrUtil.isEmpty(value.toString())) { + return ""; + } + + // 获取客户来源信息 + try { + return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_SOURCE, value.toString()); + } catch (Exception ignored) { + } + return ""; + } +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/package-info.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/package-info.java new file mode 100644 index 0000000000..b756f540d1 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.crm.framework.bizlog; \ No newline at end of file diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java index 52725a675f..87a01653b4 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.service.customer; import cn.hutool.core.collection.CollUtil; 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.customer.vo.CrmCustomerCreateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO; @@ -16,6 +17,7 @@ import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import com.mzt.logapi.context.LogRecordContext; +import com.mzt.logapi.service.impl.DiffParseFunction; import com.mzt.logapi.starter.annotation.LogRecord; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; @@ -63,11 +65,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @Override @Transactional(rollbackFor = Exception.class) + @LogRecord(success = "更新了客户{_DIFF{#updateReqVO}}", type = CRM_CUSTOMER, subType = "更新客户", bizNo = "{{#updateReqVO.id}}") @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) public void updateCustomer(CrmCustomerUpdateReqVO updateReqVO) { // 校验存在 - validateCustomerExists(updateReqVO.getId()); + CrmCustomerDO oldCustomerDO = validateCustomerExists(updateReqVO.getId()); + // __DIFF 函数传递了一个参数,传递的参数是修改之后的对象,这种方式需要在方法内部向 LogRecordContext 中 put 一个变量,代表是之前的对象,这个对象可以是null + LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomerDO, CrmCustomerUpdateReqVO.class)); // 更新 CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO); customerMapper.updateById(updateObj); @@ -86,10 +91,12 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id); } - private void validateCustomerExists(Long id) { - if (customerMapper.selectById(id) == null) { + private CrmCustomerDO validateCustomerExists(Long id) { + CrmCustomerDO customerDO = customerMapper.selectById(id); + if (customerDO == null) { throw exception(CUSTOMER_NOT_EXISTS); } + return customerDO; } @Override @@ -135,7 +142,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { // 1. 校验客户是否存在 validateCustomer(reqVO.getId()); - // 添加 crmCustomer 到日志上下文 + // 添加 crmCustomer 到日志上下文 TODO 日志记录放在 service 里是因为已经过了权限校验查询时不用走两次校验 LogRecordContext.putVariable("crmCustomer", customerMapper.selectById(reqVO.getId())); // 2.1 数据权限转移 crmPermissionService.transferPermission( diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AdminUserParseFunction.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AdminUserParseFunction.java index 21459be6b3..60fee85be1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AdminUserParseFunction.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AdminUserParseFunction.java @@ -21,11 +21,6 @@ public class AdminUserParseFunction implements IParseFunction { @Resource private AdminUserApi adminUserApi; - @Override - public boolean executeBefore() { - return true; - } - @Override public String functionName() { return "getAdminUserById"; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AreaParseFunction.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AreaParseFunction.java new file mode 100644 index 0000000000..f486a49fa1 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AreaParseFunction.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.system.framework.bizlog.function; + +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; +import com.mzt.logapi.service.IParseFunction; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 自定义函数-通过区域编号获取区域信息 + * + * @author HUIHUI + */ +@Slf4j +@Component +public class AreaParseFunction implements IParseFunction { + + @Override + public boolean executeBefore() { + return true; // 先转换值后对比 + } + + @Override + public String functionName() { + return "getAreaById"; + } + + @Override + public String apply(Object value) { + if (value == null) { + return ""; + } + if (StrUtil.isEmpty(value.toString())) { + return ""; + } + + return AreaUtils.format(Integer.parseInt(value.toString())); + } +} From daf4651a4f08dce7af17c424ab2a6da3af02cae5 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Thu, 14 Dec 2023 18:45:13 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E6=97=A5=E5=BF=97=EF=BC=9A=E9=9B=86=E6=88=90=20mzt-biz-log=205?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=97=A5=E5=BF=97=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E5=92=8C=E6=9F=A5=E8=AF=A2=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/customer/CrmCustomerController.java | 20 ++++ .../yudao-module-system-api/pom.xml | 10 ++ .../system/api/logger/OperateLogApi.java | 13 ++- .../api/logger/dto/OperateLogV2RespDTO.java | 93 +++++++++++++++++++ .../system/api/logger/OperateLogApiImpl.java | 35 ++++++- .../dal/dataobject/logger/OperateLogV2DO.java | 6 +- .../dal/mysql/logger/OperateLogV2Mapper.java | 8 ++ .../bizlog/service/ILogRecordServiceImpl.java | 8 +- .../service/logger/OperateLogService.java | 29 ++++-- .../service/logger/OperateLogServiceImpl.java | 21 +++-- .../logger/bo/OperateLogV2CreateReqBO.java | 5 + 11 files changed, 229 insertions(+), 19 deletions(-) create mode 100644 yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogV2RespDTO.java diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java index 6ce57abf10..8386e80edd 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java @@ -11,6 +11,8 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; +import cn.iocoder.yudao.module.system.api.logger.OperateLogApi; +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import io.swagger.v3.oas.annotations.Operation; @@ -36,6 +38,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.CRM_CUSTOMER; @Tag(name = "管理后台 - CRM 客户") @RestController @@ -50,6 +53,8 @@ public class CrmCustomerController { private DeptApi deptApi; @Resource private AdminUserApi adminUserApi; + @Resource + private OperateLogApi operateLogApi; @PostMapping("/create") @Operation(summary = "创建客户") @@ -130,6 +135,21 @@ public class CrmCustomerController { return success(true); } + @GetMapping("/operate-log") + @Operation(summary = "获得客户操作日志") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('crm:customer:query')") + public CommonResult> getOperateLog(@RequestParam("id") Long id) { + // 1. 获取客户 + CrmCustomerDO customer = customerService.getCustomer(id); + if (customer == null) { + return success(null); + } + + // 2. 获取操作日志 + return success(operateLogApi.getOperateLogByModuleAndBizId(CRM_CUSTOMER, id)); + } + // TODO @Joey:单独建一个属于自己业务的 ReqVO;因为前端如果模拟请求,是不是可以更新其它字段了; @PutMapping("/lock") @Operation(summary = "锁定/解锁客户") diff --git a/yudao-module-system/yudao-module-system-api/pom.xml b/yudao-module-system/yudao-module-system-api/pom.xml index 416413cd6f..3c91bd9741 100644 --- a/yudao-module-system/yudao-module-system-api/pom.xml +++ b/yudao-module-system/yudao-module-system-api/pom.xml @@ -29,6 +29,16 @@ bizlog-sdk + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.core + jackson-core + + org.springframework.boot diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/OperateLogApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/OperateLogApi.java index 6e28c7d787..ad42c87f77 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/OperateLogApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/OperateLogApi.java @@ -1,9 +1,11 @@ package cn.iocoder.yudao.module.system.api.logger; import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO; - +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO; import jakarta.validation.Valid; +import java.util.List; + /** * 操作日志 API 接口 * @@ -18,4 +20,13 @@ public interface OperateLogApi { */ void createOperateLog(@Valid OperateLogCreateReqDTO createReqDTO); + /** + * 获取指定模块的指定数据的操作日志 + * + * @param module 操作模块 + * @param bizId 操作模块编号 + * @return 操作日志 + */ + List getOperateLogByModuleAndBizId(String module, Long bizId); + } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogV2RespDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogV2RespDTO.java new file mode 100644 index 0000000000..9a918abe3b --- /dev/null +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogV2RespDTO.java @@ -0,0 +1,93 @@ +package cn.iocoder.yudao.module.system.api.logger.dto; + +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT; + +/** + * 系统操作日志 Resp DTO + * + * @author HUIHUI + */ +@Data +public class OperateLogV2RespDTO { + + /** + * 链路追踪编号 + * + * 一般来说,通过链路追踪编号,可以将访问日志,错误日志,链路追踪日志,logger 打印日志等,结合在一起,从而进行排错。 + */ + private String traceId; + /** + * 用户编号 + * + * 关联 MemberUserDO 的 id 属性,或者 AdminUserDO 的 id 属性 + */ + private Long userId; + /** + * 用户类型 + * + * 关联 {@link UserTypeEnum} + */ + private Integer userType; + /** + * 操作模块 + */ + private String module; + /** + * 操作名 + */ + private String name; + /** + * 操作模块业务编号 + */ + private Long bizId; + /** + * 操作内容,记录整个操作的明细 + * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 + */ + private String content; + /** + * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ) + * 例如说,记录订单编号,{ orderId: "1"} + */ + private String extra; + + /** + * 请求方法名 + */ + private String requestMethod; + /** + * 请求地址 + */ + private String requestUrl; + /** + * 用户 IP + */ + private String userIp; + /** + * 浏览器 UA + */ + private String userAgent; + + /** + * 创建时间 + */ + // TODO puhui999: 木得效果怎么肥事 + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) + private LocalDateTime createTime; + /** + * 创建者,关联 AdminUserDO#getId + */ + private String creator; + /** + * 创建者名称 + */ + private String creatorName; + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/logger/OperateLogApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/logger/OperateLogApiImpl.java index 20aa2635da..d748bcc235 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/logger/OperateLogApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/logger/OperateLogApiImpl.java @@ -1,11 +1,23 @@ package cn.iocoder.yudao.module.system.api.logger; +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO; +import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogV2RespDTO; +import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO; +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.service.logger.OperateLogService; +import cn.iocoder.yudao.module.system.service.user.AdminUserService; +import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import jakarta.annotation.Resource; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; /** * 操作日志 API 实现类 @@ -18,10 +30,31 @@ public class OperateLogApiImpl implements OperateLogApi { @Resource private OperateLogService operateLogService; + @Resource + private AdminUserService adminUserService; @Override public void createOperateLog(OperateLogCreateReqDTO createReqDTO) { operateLogService.createOperateLog(createReqDTO); } + @Override + public List getOperateLogByModuleAndBizId(String module, Long bizId) { + List logList = operateLogService.getOperateLogByModuleAndBizId(module, bizId); + if (CollUtil.isEmpty(logList)) { + return Collections.emptyList(); + } + + // 获取用户 + List userList = adminUserService.getUserList(convertSet(logList, item -> Long.parseLong(item.getCreator()))); + Map userMap = convertMap(userList, AdminUserDO::getId); + return convertList(logList, item -> { + OperateLogV2RespDTO bean = BeanUtils.toBean(item, OperateLogV2RespDTO.class); + findAndThen(userMap, Long.parseLong(item.getCreator()), user -> { + bean.setCreatorName(user.getNickname()); + }); + return bean; + }); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogV2DO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogV2DO.java index 246f456128..1b7b1eaab0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogV2DO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogV2DO.java @@ -59,7 +59,11 @@ public class OperateLogV2DO extends BaseDO { * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 */ private String content; - + /** + * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ) + * 例如说,记录订单编号,{ orderId: "1"} + */ + private String extra; /** * 请求方法名 */ diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/logger/OperateLogV2Mapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/logger/OperateLogV2Mapper.java index e08686914e..362f0d2c49 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/logger/OperateLogV2Mapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/logger/OperateLogV2Mapper.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO; import org.apache.ibatis.annotations.Mapper; import java.util.Collection; +import java.util.List; @Mapper public interface OperateLogV2Mapper extends BaseMapperX { @@ -20,4 +21,11 @@ public interface OperateLogV2Mapper extends BaseMapperX { return selectPage(reqVO, query); } + default List selectListByModuleAndBizId(String module, Long bizId) { + return selectList(new LambdaQueryWrapperX() + .eq(OperateLogV2DO::getModule, module) + .eq(OperateLogV2DO::getBizId, bizId) + .orderByDesc(OperateLogV2DO::getCreateTime)); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java index 161d4eca6f..a81280f990 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.system.framework.bizlog.service; import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; -import cn.iocoder.yudao.module.system.api.logger.OperateLogApi; +import cn.iocoder.yudao.module.system.service.logger.OperateLogService; import cn.iocoder.yudao.module.system.service.logger.bo.OperateLogV2CreateReqBO; import com.mzt.logapi.beans.LogRecord; import com.mzt.logapi.service.ILogRecordService; @@ -18,7 +18,7 @@ import java.util.List; /** * 操作日志 ILogRecordService 实现类 * - * 基于 {@link OperateLogApi} 实现,记录操作日志 + * 基于 {@link OperateLogService} 实现,记录操作日志 * * @author HUIHUI */ @@ -27,7 +27,7 @@ import java.util.List; public class ILogRecordServiceImpl implements ILogRecordService { @Resource - private OperateLogApi operateLogApi; + private OperateLogService operateLogService; @Override public void record(LogRecord logRecord) { @@ -41,6 +41,7 @@ public class ILogRecordServiceImpl implements ILogRecordService { // 补全请求信息 fillRequestFields(reqBO); // 异步记录日志 + operateLogService.createOperateLogV2(reqBO); log.info("操作日志 ===> {}", reqBO); } @@ -54,6 +55,7 @@ public class ILogRecordServiceImpl implements ILogRecordService { reqBO.setName(logRecord.getSubType());// 操作名称如 转移客户 reqBO.setBizId(Long.parseLong(logRecord.getBizNo())); // 操作模块业务编号 reqBO.setContent(logRecord.getAction());// 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 + reqBO.setExtra(logRecord.getExtra()); // 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ),例如说,记录订单编号,{ orderId: "1"} } private static void fillRequestFields(OperateLogV2CreateReqBO reqBO) { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogService.java index 9aada4999a..30a1a1a7cd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogService.java @@ -4,6 +4,10 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO; import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO; +import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO; +import cn.iocoder.yudao.module.system.service.logger.bo.OperateLogV2CreateReqBO; + +import java.util.List; /** * 操作日志 Service 接口 @@ -19,13 +23,6 @@ public interface OperateLogService { */ void createOperateLog(OperateLogCreateReqDTO createReqDTO); - /** - * 记录操作日志 V2 - * - * @param createReqDTO 操作日志请求 - */ - void createOperateLogV2(OperateLogCreateReqDTO createReqDTO); - /** * 获得操作日志分页列表 * @@ -34,4 +31,22 @@ public interface OperateLogService { */ PageResult getOperateLogPage(OperateLogPageReqVO pageReqVO); + //======================= LOG V2 ======================= + + /** + * 记录操作日志 V2 + * + * @param createReqBO 创建请求 + */ + void createOperateLogV2(OperateLogV2CreateReqBO createReqBO); + + /** + * 获取指定模块的指定数据的操作日志 + * + * @param module 操作模块 + * @param bizId 操作模块编号 + * @return 操作日志 + */ + List getOperateLogByModuleAndBizId(String module, Long bizId); + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java index 840913f622..894cc48c85 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java @@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogV2DO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.dal.mysql.logger.OperateLogMapper; import cn.iocoder.yudao.module.system.dal.mysql.logger.OperateLogV2Mapper; +import cn.iocoder.yudao.module.system.service.logger.bo.OperateLogV2CreateReqBO; import cn.iocoder.yudao.module.system.service.user.AdminUserService; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; @@ -19,6 +20,7 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import java.util.Collection; +import java.util.List; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO.JAVA_METHOD_ARGS_MAX_LENGTH; @@ -50,12 +52,6 @@ public class OperateLogServiceImpl implements OperateLogService { operateLogMapper.insert(log); } - @Override - public void createOperateLogV2(OperateLogCreateReqDTO createReqDTO) { - OperateLogV2DO log = BeanUtils.toBean(createReqDTO, OperateLogV2DO.class); - operateLogV2Mapper.insert(log); - } - @Override public PageResult getOperateLogPage(OperateLogPageReqVO pageReqVO) { // 处理基于用户昵称的查询 @@ -70,4 +66,17 @@ public class OperateLogServiceImpl implements OperateLogService { return operateLogMapper.selectPage(pageReqVO, userIds); } + //======================= LOG V2 ======================= + + @Override + public void createOperateLogV2(OperateLogV2CreateReqBO createReqBO) { + OperateLogV2DO log = BeanUtils.toBean(createReqBO, OperateLogV2DO.class); + operateLogV2Mapper.insert(log); + } + + @Override + public List getOperateLogByModuleAndBizId(String module, Long bizId) { + return operateLogV2Mapper.selectListByModuleAndBizId(module, bizId); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/bo/OperateLogV2CreateReqBO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/bo/OperateLogV2CreateReqBO.java index 8c1675879b..d6c44604cf 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/bo/OperateLogV2CreateReqBO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/bo/OperateLogV2CreateReqBO.java @@ -53,6 +53,11 @@ public class OperateLogV2CreateReqBO { */ @NotEmpty(message = "操作内容不能为空") private String content; + /** + * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ) + * 例如说,记录订单编号,{ orderId: "1"} + */ + private String extra; /** * 请求方法名