Commit ddb6fe7ec8e520df680857f9d0932c2ae5ccddde

Authored by YunaiV
1 parent bada3275

📖 CRM:code review 客户管理的数据权限、操作权限

Showing 19 changed files with 63 additions and 64 deletions
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java
1 package cn.iocoder.yudao.module.crm.enums; 1 package cn.iocoder.yudao.module.crm.enums;
2 2
  3 +// TODO 芋艿:操作日志;看看这个类怎么搞个好点的规范;
3 /** 4 /**
4 * CRM 操作日志枚举 5 * CRM 操作日志枚举
5 * 6 *
@@ -9,18 +10,18 @@ public interface LogRecordConstants { @@ -9,18 +10,18 @@ public interface LogRecordConstants {
9 10
10 //======================= 客户模块类型 ======================= 11 //======================= 客户模块类型 =======================
11 // TODO puhui999: 确保模块命名方式为 module + 子模块名称的方式。统一定义模块名称是为了方便查询各自记录的操作日志,列如说:查询客户【张三的操作日志】就可以 module + bizId 12 // TODO puhui999: 确保模块命名方式为 module + 子模块名称的方式。统一定义模块名称是为了方便查询各自记录的操作日志,列如说:查询客户【张三的操作日志】就可以 module + bizId
12 - String CRM_LEADS = "CRM-线索";  
13 - String CRM_CUSTOMER = "CRM-客户";  
14 - String CRM_CONTACT = "CRM-联系人";  
15 - String CRM_BUSINESS = "CRM-商机";  
16 - String CRM_CONTRACT = "CRM-合同";  
17 - String CRM_PRODUCT = "CRM-产品";  
18 - String CRM_RECEIVABLE = "CRM-回款";  
19 - String CRM_RECEIVABLE_PLAN = "CRM-回款计划"; 13 + String CRM_LEADS = "CRM 线索";
  14 + String CRM_CUSTOMER = "CRM 客户";
  15 + String CRM_CONTACT = "CRM 联系人";
  16 + String CRM_BUSINESS = "CRM 商机";
  17 + String CRM_CONTRACT = "CRM 合同";
  18 + String CRM_PRODUCT = "CRM 产品";
  19 + String CRM_RECEIVABLE = "CRM 回款";
  20 + String CRM_RECEIVABLE_PLAN = "CRM 回款计划";
20 21
21 //======================= 客户转移操作日志 ======================= 22 //======================= 客户转移操作日志 =======================
22 23
23 String TRANSFER_CUSTOMER_LOG_SUCCESS = "把客户【{{#crmCustomer.name}}】的负责人从【{getAdminUserById{#crmCustomer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; 24 String TRANSFER_CUSTOMER_LOG_SUCCESS = "把客户【{{#crmCustomer.name}}】的负责人从【{getAdminUserById{#crmCustomer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】";
24 - String TRANSFER_CUSTOMER_LOG_FAIL = ""; 25 + String TRANSFER_CUSTOMER_LOG_FAIL = ""; // TODO @puhui999:这个可以删除哈,一般不搞失败的日志
25 26
26 } 27 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/clue/vo/CrmClueTransferReqVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.clue.vo; 1 package cn.iocoder.yudao.module.crm.controller.admin.clue.vo;
2 2
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
3 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; 4 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
4 import io.swagger.v3.oas.annotations.media.Schema; 5 import io.swagger.v3.oas.annotations.media.Schema;
5 import jakarta.validation.constraints.NotNull; 6 import jakarta.validation.constraints.NotNull;
@@ -13,19 +14,12 @@ public class CrmClueTransferReqVO { @@ -13,19 +14,12 @@ public class CrmClueTransferReqVO {
13 @NotNull(message = "线索编号不能为空") 14 @NotNull(message = "线索编号不能为空")
14 private Long id; 15 private Long id;
15 16
16 - /**  
17 - * 新负责人的用户编号  
18 - */  
19 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") 17 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
20 @NotNull(message = "新负责人的用户编号不能为空") 18 @NotNull(message = "新负责人的用户编号不能为空")
21 private Long newOwnerUserId; 19 private Long newOwnerUserId;
22 20
23 - /**  
24 - * 老负责人加入团队后的权限级别。如果 null 说明移除  
25 - *  
26 - * 关联 {@link CrmPermissionLevelEnum}  
27 - */  
28 @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 21 @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
29 - private Integer oldOwnerPermissionLevel; 22 + @InEnum(value = CrmPermissionLevelEnum.class)
  23 + private Integer oldOwnerPermissionLevel; // 老负责人加入团队后的权限级别。如果 null 说明移除
30 24
31 } 25 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/customer/CrmCustomerController.java
@@ -135,18 +135,22 @@ public class CrmCustomerController { @@ -135,18 +135,22 @@ public class CrmCustomerController {
135 return success(true); 135 return success(true);
136 } 136 }
137 137
  138 + // TODO @puhui999:operate-log-list 或者 operate-log-page 如果分页
138 @GetMapping("/operate-log") 139 @GetMapping("/operate-log")
139 @Operation(summary = "获得客户操作日志") 140 @Operation(summary = "获得客户操作日志")
140 @Parameter(name = "id", description = "编号", required = true, example = "1024") 141 @Parameter(name = "id", description = "编号", required = true, example = "1024")
141 @PreAuthorize("@ss.hasPermission('crm:customer:query')") 142 @PreAuthorize("@ss.hasPermission('crm:customer:query')")
  143 + // TODO @puhui999:最好有读权限;方法名改成 getCustomerOperateLog
142 public CommonResult<List<OperateLogV2RespDTO>> getOperateLog(@RequestParam("id") Long id) { 144 public CommonResult<List<OperateLogV2RespDTO>> getOperateLog(@RequestParam("id") Long id) {
143 // 1. 获取客户 145 // 1. 获取客户
  146 + // TODO @puhui999:这个校验可以去掉哈;
144 CrmCustomerDO customer = customerService.getCustomer(id); 147 CrmCustomerDO customer = customerService.getCustomer(id);
145 if (customer == null) { 148 if (customer == null) {
146 return success(null); 149 return success(null);
147 } 150 }
148 151
149 // 2. 获取操作日志 152 // 2. 获取操作日志
  153 + // TODO @puhui999:操作日志,返回可能要分页哈;
150 return success(operateLogApi.getOperateLogByModuleAndBizId(CRM_CUSTOMER, id)); 154 return success(operateLogApi.getOperateLogByModuleAndBizId(CRM_CUSTOMER, id));
151 } 155 }
152 156
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanTransferReqVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan; 1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan;
2 2
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
3 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; 4 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
4 import io.swagger.v3.oas.annotations.media.Schema; 5 import io.swagger.v3.oas.annotations.media.Schema;
5 import jakarta.validation.constraints.NotNull; 6 import jakarta.validation.constraints.NotNull;
@@ -13,19 +14,12 @@ public class CrmReceivablePlanTransferReqVO { @@ -13,19 +14,12 @@ public class CrmReceivablePlanTransferReqVO {
13 @NotNull(message = "回款计划编号不能为空") 14 @NotNull(message = "回款计划编号不能为空")
14 private Long id; 15 private Long id;
15 16
16 - /**  
17 - * 新负责人的用户编号  
18 - */  
19 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") 17 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
20 @NotNull(message = "新负责人的用户编号不能为空") 18 @NotNull(message = "新负责人的用户编号不能为空")
21 private Long newOwnerUserId; 19 private Long newOwnerUserId;
22 20
23 - /**  
24 - * 老负责人加入团队后的权限级别。如果 null 说明移除  
25 - *  
26 - * 关联 {@link CrmPermissionLevelEnum}  
27 - */  
28 @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 21 @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
29 - private Integer oldOwnerPermissionLevel; 22 + @InEnum(value = CrmPermissionLevelEnum.class)
  23 + private Integer oldOwnerPermissionLevel; // 老负责人加入团队后的权限级别。如果 null 说明移除
30 24
31 } 25 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableTransferReqVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable; 1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable;
2 2
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
3 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; 4 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
4 import io.swagger.v3.oas.annotations.media.Schema; 5 import io.swagger.v3.oas.annotations.media.Schema;
5 import jakarta.validation.constraints.NotNull; 6 import jakarta.validation.constraints.NotNull;
@@ -13,19 +14,12 @@ public class CrmReceivableTransferReqVO { @@ -13,19 +14,12 @@ public class CrmReceivableTransferReqVO {
13 @NotNull(message = "回款编号不能为空") 14 @NotNull(message = "回款编号不能为空")
14 private Long id; 15 private Long id;
15 16
16 - /**  
17 - * 新负责人的用户编号  
18 - */  
19 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") 17 @Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
20 @NotNull(message = "新负责人的用户编号不能为空") 18 @NotNull(message = "新负责人的用户编号不能为空")
21 private Long newOwnerUserId; 19 private Long newOwnerUserId;
22 20
23 - /**  
24 - * 老负责人加入团队后的权限级别。如果 null 说明移除  
25 - *  
26 - * 关联 {@link CrmPermissionLevelEnum}  
27 - */  
28 @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 21 @Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
29 - private Integer oldOwnerPermissionLevel; 22 + @InEnum(value = CrmPermissionLevelEnum.class)
  23 + private Integer oldOwnerPermissionLevel; // 老负责人加入团队后的权限级别。如果 null 说明移除
30 24
31 } 25 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/bizlog/function/CrmIndustryParseFunction.java
@@ -8,6 +8,7 @@ import org.springframework.stereotype.Component; @@ -8,6 +8,7 @@ import org.springframework.stereotype.Component;
8 8
9 import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY; 9 import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY;
10 10
  11 +// TODO @puhui999:包名使用 operatelog 更合适哈;
11 /** 12 /**
12 * 自定义函数-通过行业编号获取行业信息 13 * 自定义函数-通过行业编号获取行业信息
13 * 14 *
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/framework/core/aop/CrmPermissionAspect.java
@@ -26,6 +26,7 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString @@ -26,6 +26,7 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString
26 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_DENIED; 26 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_DENIED;
27 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_MODEL_NOT_EXISTS; 27 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_MODEL_NOT_EXISTS;
28 28
  29 +// TODO 这个包,改成 permission,然后搞 config 和 core 包,这个类在 core 包里;目的是:framework 最好分类下
29 /** 30 /**
30 * Crm 数据权限校验 AOP 切面 31 * Crm 数据权限校验 AOP 切面
31 * 32 *
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java
@@ -137,12 +137,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { @@ -137,12 +137,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
137 137
138 @Override 138 @Override
139 @Transactional(rollbackFor = Exception.class) 139 @Transactional(rollbackFor = Exception.class)
  140 + // TODO @puhui999:@LogRecord(type = CRM_CUSTOMER, subType = "客户转移", bizNo = "{{#reqVO.id}}", success = TRANSFER_CUSTOMER_LOG_SUCCESS)
140 @LogRecord(success = TRANSFER_CUSTOMER_LOG_SUCCESS, type = CRM_CUSTOMER, subType = "客户转移", bizNo = "{{#reqVO.id}}") 141 @LogRecord(success = TRANSFER_CUSTOMER_LOG_SUCCESS, type = CRM_CUSTOMER, subType = "客户转移", bizNo = "{{#reqVO.id}}")
141 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER) 142 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#reqVO.id", level = CrmPermissionLevelEnum.OWNER)
142 public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) { 143 public void transferCustomer(CrmCustomerTransferReqVO reqVO, Long userId) {
143 // 1. 校验客户是否存在 144 // 1. 校验客户是否存在
144 validateCustomer(reqVO.getId()); 145 validateCustomer(reqVO.getId());
145 // 添加 crmCustomer 到日志上下文 TODO 日志记录放在 service 里是因为已经过了权限校验查询时不用走两次校验 146 // 添加 crmCustomer 到日志上下文 TODO 日志记录放在 service 里是因为已经过了权限校验查询时不用走两次校验
  147 + // TODO @puhui999:customer 不用查询,从 1. 拿到哈;然后 put这个动作,可以放到 3.;这样逻辑结构就是,校验、逻辑、日志,更加清晰
146 LogRecordContext.putVariable("crmCustomer", customerMapper.selectById(reqVO.getId())); 148 LogRecordContext.putVariable("crmCustomer", customerMapper.selectById(reqVO.getId()));
147 // 2.1 数据权限转移 149 // 2.1 数据权限转移
148 crmPermissionService.transferPermission( 150 crmPermissionService.transferPermission(
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/permission/CrmPermissionServiceImpl.java
@@ -138,11 +138,10 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { @@ -138,11 +138,10 @@ public class CrmPermissionServiceImpl implements CrmPermissionService {
138 } 138 }
139 139
140 @Override 140 @Override
141 - @Transactional(rollbackFor = Exception.class) 141 + @Transactional(rollbackFor = Exception.class) // TODO @puhui999:这里不用加的,就一个操作哈;
142 public void deletePermission(Integer bizType, Long bizId) { 142 public void deletePermission(Integer bizType, Long bizId) {
143 - // 删除数据权限  
144 - int deletedCol = crmPermissionMapper.deletePermission(bizType, bizId);  
145 - if (deletedCol == 0) { 143 + int deletedCount = crmPermissionMapper.deletePermission(bizType, bizId);
  144 + if (deletedCount == 0) {
146 throw exception(CRM_PERMISSION_NOT_EXISTS); 145 throw exception(CRM_PERMISSION_NOT_EXISTS);
147 } 146 }
148 } 147 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivablePlanServiceImpl.java
@@ -61,9 +61,9 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService { @@ -61,9 +61,9 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
61 61
62 receivablePlanMapper.insert(receivablePlan); 62 receivablePlanMapper.insert(receivablePlan);
63 // 创建数据权限 63 // 创建数据权限
64 - crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType())  
65 - .setBizId(receivablePlan.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));  
66 - // 返回 64 + crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId)
  65 + .setBizType(CrmBizTypeEnum.CRM_RECEIVABLE_PLAN.getType()).setBizId(receivablePlan.getId())
  66 + .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
67 return receivablePlan.getId(); 67 return receivablePlan.getId();
68 } 68 }
69 69
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/util/CrmQueryWrapperUtils.java
@@ -35,14 +35,14 @@ public class CrmQueryWrapperUtils { @@ -35,14 +35,14 @@ public class CrmQueryWrapperUtils {
35 * @param pool 公海 35 * @param pool 公海
36 * @return 是否 (是:需要执行查询,否:不需要查询调用方法直接返回空) 36 * @return 是否 (是:需要执行查询,否:不需要查询调用方法直接返回空)
37 */ 37 */
38 - // TODO @puhui999:bizId 直接传递会不会简单点 回复:还是需要 SFunction 因为分页连表时不知道 bizId 是多少 38 + // TODO @puhui999:bizId 直接传递会不会简单点 回复:还是需要 SFunction 因为分页连表时不知道 bizId 是多少;是不是把 bizId 传入就好啦?
39 public static <T extends MPJLambdaWrapper<?>, S> boolean appendPermissionCondition(T query, Integer bizType, SFunction<S, ?> bizId, 39 public static <T extends MPJLambdaWrapper<?>, S> boolean appendPermissionCondition(T query, Integer bizType, SFunction<S, ?> bizId,
40 Long userId, Integer sceneType, Boolean pool) { 40 Long userId, Integer sceneType, Boolean pool) {
41 // 1. 构建数据权限连表条件 41 // 1. 构建数据权限连表条件
42 if (ObjUtil.notEqual(validateAdminUser(userId), Boolean.TRUE)) { // 管理员不需要数据权限 42 if (ObjUtil.notEqual(validateAdminUser(userId), Boolean.TRUE)) { // 管理员不需要数据权限
43 - query.innerJoin(CrmPermissionDO.class, on ->  
44 - on.eq(CrmPermissionDO::getBizType, bizType).eq(CrmPermissionDO::getBizId, bizId)  
45 - .eq(CrmPermissionDO::getUserId, userId)); 43 + query.innerJoin(CrmPermissionDO.class, on -> on.eq(CrmPermissionDO::getBizType, bizType)
  44 + .eq(CrmPermissionDO::getBizId, bizId)
  45 + .eq(CrmPermissionDO::getUserId, userId));
46 } 46 }
47 // 2.1 场景一:我负责的数据 47 // 2.1 场景一:我负责的数据
48 if (CrmSceneTypeEnum.isOwner(sceneType)) { 48 if (CrmSceneTypeEnum.isOwner(sceneType)) {
@@ -50,15 +50,15 @@ public class CrmQueryWrapperUtils { @@ -50,15 +50,15 @@ public class CrmQueryWrapperUtils {
50 } 50 }
51 // 2.2 场景二:我参与的数据 51 // 2.2 场景二:我参与的数据
52 if (CrmSceneTypeEnum.isInvolved(sceneType)) { 52 if (CrmSceneTypeEnum.isInvolved(sceneType)) {
53 - query  
54 - .ne("owner_user_id", userId) 53 + query.ne("owner_user_id", userId)
  54 + // TODO @puhui999:IN 是不是更合适哈;
55 .and(q -> q.eq(CrmPermissionDO::getLevel, CrmPermissionLevelEnum.READ.getLevel()) 55 .and(q -> q.eq(CrmPermissionDO::getLevel, CrmPermissionLevelEnum.READ.getLevel())
56 .or() 56 .or()
57 .eq(CrmPermissionDO::getLevel, CrmPermissionLevelEnum.WRITE.getLevel())); 57 .eq(CrmPermissionDO::getLevel, CrmPermissionLevelEnum.WRITE.getLevel()));
58 -  
59 } 58 }
60 // 2.3 场景三:下属负责的数据 59 // 2.3 场景三:下属负责的数据
61 if (CrmSceneTypeEnum.isSubordinate(sceneType)) { 60 if (CrmSceneTypeEnum.isSubordinate(sceneType)) {
  61 + // TODO @puhui999:要不如果没有下属,拼一个 owner_user_id in null,不返回结果就好啦;
62 List<AdminUserRespDTO> subordinateUsers = getAdminUserApi().getUserListBySubordinate(userId); 62 List<AdminUserRespDTO> subordinateUsers = getAdminUserApi().getUserListBySubordinate(userId);
63 if (CollUtil.isEmpty(subordinateUsers)) { 63 if (CollUtil.isEmpty(subordinateUsers)) {
64 return false; 64 return false;
@@ -72,7 +72,6 @@ public class CrmQueryWrapperUtils { @@ -72,7 +72,6 @@ public class CrmQueryWrapperUtils {
72 } else { // 情况二:不是公海 72 } else { // 情况二:不是公海
73 query.isNotNull("owner_user_id"); 73 query.isNotNull("owner_user_id");
74 } 74 }
75 -  
76 return true; 75 return true;
77 } 76 }
78 77
@@ -106,6 +105,7 @@ public class CrmQueryWrapperUtils { @@ -106,6 +105,7 @@ public class CrmQueryWrapperUtils {
106 */ 105 */
107 private static boolean validateAdminUser(Long userId) { 106 private static boolean validateAdminUser(Long userId) {
108 // TODO 查询权限配置表用户的角色信息 107 // TODO 查询权限配置表用户的角色信息
  108 + // TODO @puhui999:查询用户的角色;CRM_ADMIN("crm_admin", "CRM 管理员"),
109 //CrmPermissionConfig permissionConfig = crmPermissionConfigService.getPermissionConfigByUserId(userId); 109 //CrmPermissionConfig permissionConfig = crmPermissionConfigService.getPermissionConfigByUserId(userId);
110 //if (permissionConfig == null) { 110 //if (permissionConfig == null) {
111 // return false; 111 // return false;
yudao-module-system/yudao-module-system-api/pom.xml
@@ -22,6 +22,7 @@ @@ -22,6 +22,7 @@
22 <artifactId>yudao-common</artifactId> 22 <artifactId>yudao-common</artifactId>
23 </dependency> 23 </dependency>
24 24
  25 + <!-- TODO @puhui999 & 芋艿:操作日志,要不要这么引入? -->
25 <!-- Springboot-注解-通用操作日志组件 --> 26 <!-- Springboot-注解-通用操作日志组件 -->
26 <!-- 此组件解决的问题是: 「谁」在「什么时间」对「什么」做了「什么事」 --> 27 <!-- 此组件解决的问题是: 「谁」在「什么时间」对「什么」做了「什么事」 -->
27 <dependency> 28 <dependency>
@@ -29,6 +30,7 @@ @@ -29,6 +30,7 @@
29 <artifactId>bizlog-sdk</artifactId> 30 <artifactId>bizlog-sdk</artifactId>
30 </dependency> 31 </dependency>
31 32
  33 + <!-- TODO @puhui999 & 芋艿:要不要移除掉 -->
32 <!--工具类相关--> 34 <!--工具类相关-->
33 <dependency> 35 <dependency>
34 <groupId>com.fasterxml.jackson.core</groupId> 36 <groupId>com.fasterxml.jackson.core</groupId>
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/dto/OperateLogV2RespDTO.java
@@ -19,20 +19,14 @@ public class OperateLogV2RespDTO { @@ -19,20 +19,14 @@ public class OperateLogV2RespDTO {
19 19
20 /** 20 /**
21 * 链路追踪编号 21 * 链路追踪编号
22 - *  
23 - * 一般来说,通过链路追踪编号,可以将访问日志,错误日志,链路追踪日志,logger 打印日志等,结合在一起,从而进行排错。  
24 */ 22 */
25 private String traceId; 23 private String traceId;
26 /** 24 /**
27 * 用户编号 25 * 用户编号
28 - *  
29 - * 关联 MemberUserDO 的 id 属性,或者 AdminUserDO 的 id 属性  
30 */ 26 */
31 private Long userId; 27 private Long userId;
32 /** 28 /**
33 * 用户类型 29 * 用户类型
34 - *  
35 - * 关联 {@link UserTypeEnum}  
36 */ 30 */
37 private Integer userType; 31 private Integer userType;
38 /** 32 /**
@@ -48,13 +42,11 @@ public class OperateLogV2RespDTO { @@ -48,13 +42,11 @@ public class OperateLogV2RespDTO {
48 */ 42 */
49 private Long bizId; 43 private Long bizId;
50 /** 44 /**
51 - * 操作内容,记录整个操作的明细  
52 - * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 45 + * 操作内容
53 */ 46 */
54 private String content; 47 private String content;
55 /** 48 /**
56 - * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 )  
57 - * 例如说,记录订单编号,{ orderId: "1"} 49 + * 拓展字段
58 */ 50 */
59 private String extra; 51 private String extra;
60 52
@@ -81,8 +73,10 @@ public class OperateLogV2RespDTO { @@ -81,8 +73,10 @@ public class OperateLogV2RespDTO {
81 // TODO puhui999: 木得效果怎么肥事 73 // TODO puhui999: 木得效果怎么肥事
82 @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) 74 @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT)
83 private LocalDateTime createTime; 75 private LocalDateTime createTime;
  76 +
  77 + // TODO @puhui999:下面 2 个字段不用返回;用 userId 哈;返回一个 userName
84 /** 78 /**
85 - * 创建者,关联 AdminUserDO#getId 79 + * 创建者
86 */ 80 */
87 private String creator; 81 private String creator;
88 /** 82 /**
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/logger/OperateLogV2DO.java
@@ -42,6 +42,7 @@ public class OperateLogV2DO extends BaseDO { @@ -42,6 +42,7 @@ public class OperateLogV2DO extends BaseDO {
42 * 关联 {@link UserTypeEnum} 42 * 关联 {@link UserTypeEnum}
43 */ 43 */
44 private Integer userType; 44 private Integer userType;
  45 + // TODO @puhui999:module 改成 type,name 改成 subType;
45 /** 46 /**
46 * 操作模块 47 * 操作模块
47 */ 48 */
@@ -56,13 +57,16 @@ public class OperateLogV2DO extends BaseDO { @@ -56,13 +57,16 @@ public class OperateLogV2DO extends BaseDO {
56 private Long bizId; 57 private Long bizId;
57 /** 58 /**
58 * 操作内容,记录整个操作的明细 59 * 操作内容,记录整个操作的明细
  60 + *
59 * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 61 * 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。
60 */ 62 */
61 private String content; 63 private String content;
62 /** 64 /**
63 * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ) 65 * 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 )
  66 + *
64 * 例如说,记录订单编号,{ orderId: "1"} 67 * 例如说,记录订单编号,{ orderId: "1"}
65 */ 68 */
  69 + // TODO @puhui999:看看能不能类似 exts 搞 json 格式;
66 private String extra; 70 private String extra;
67 /** 71 /**
68 * 请求方法名 72 * 请求方法名
@@ -81,4 +85,9 @@ public class OperateLogV2DO extends BaseDO { @@ -81,4 +85,9 @@ public class OperateLogV2DO extends BaseDO {
81 */ 85 */
82 private String userAgent; 86 private String userAgent;
83 87
  88 + // TODO @芋艿:requestUrl、requestMethod
  89 + // TODO @芋艿:javaMethod、javaMethodArgs
  90 + // TODO @芋艿:startTime、duration
  91 + // TODO @芋艿:resultMsg、resultData
  92 +
84 } 93 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/config/YudaoOperateLogV2Configuration.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.framework.bizlog.config; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.framework.bizlog.config;
3 import com.mzt.logapi.starter.annotation.EnableLogRecord; 3 import com.mzt.logapi.starter.annotation.EnableLogRecord;
4 import org.springframework.context.annotation.Configuration; 4 import org.springframework.context.annotation.Configuration;
5 5
  6 +// TODO @puhui999:挪到 yudao-spring-boot-starter-biz-operatelog 下,搞个 cn.iocoder.yudao.framework.operatelogv2;跑通后,我们直接就删除老的实现了;
6 /** 7 /**
7 * mzt-biz-log 配置类 8 * mzt-biz-log 配置类
8 * 9 *
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/function/AdminUserParseFunction.java
@@ -9,6 +9,7 @@ import jakarta.annotation.Resource; @@ -9,6 +9,7 @@ import jakarta.annotation.Resource;
9 import lombok.extern.slf4j.Slf4j; 9 import lombok.extern.slf4j.Slf4j;
10 import org.springframework.stereotype.Component; 10 import org.springframework.stereotype.Component;
11 11
  12 +// TODO @puhui999:这个微信讨论下,function 叫啥好哈;
12 /** 13 /**
13 * 自定义函数-通过用户编号获取用户信息 14 * 自定义函数-通过用户编号获取用户信息
14 * 15 *
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/bizlog/service/ILogRecordServiceImpl.java
@@ -15,6 +15,7 @@ import org.springframework.stereotype.Service; @@ -15,6 +15,7 @@ import org.springframework.stereotype.Service;
15 import java.util.Collections; 15 import java.util.Collections;
16 import java.util.List; 16 import java.util.List;
17 17
  18 +// TODO @puhui999:这个应该搞到 operatelog 组件里哈;
18 /** 19 /**
19 * 操作日志 ILogRecordService 实现类 20 * 操作日志 ILogRecordService 实现类
20 * 21 *
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogService.java
@@ -31,7 +31,7 @@ public interface OperateLogService { @@ -31,7 +31,7 @@ public interface OperateLogService {
31 */ 31 */
32 PageResult<OperateLogDO> getOperateLogPage(OperateLogPageReqVO pageReqVO); 32 PageResult<OperateLogDO> getOperateLogPage(OperateLogPageReqVO pageReqVO);
33 33
34 - //======================= LOG V2 ======================= 34 + // ======================= LOG V2 =======================
35 35
36 /** 36 /**
37 * 记录操作日志 V2 37 * 记录操作日志 V2
@@ -40,6 +40,7 @@ public interface OperateLogService { @@ -40,6 +40,7 @@ public interface OperateLogService {
40 */ 40 */
41 void createOperateLogV2(OperateLogV2CreateReqBO createReqBO); 41 void createOperateLogV2(OperateLogV2CreateReqBO createReqBO);
42 42
  43 + // TODO @puhui999:module 改成 type
43 /** 44 /**
44 * 获取指定模块的指定数据的操作日志 45 * 获取指定模块的指定数据的操作日志
45 * 46 *
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/logger/OperateLogServiceImpl.java
@@ -66,7 +66,7 @@ public class OperateLogServiceImpl implements OperateLogService { @@ -66,7 +66,7 @@ public class OperateLogServiceImpl implements OperateLogService {
66 return operateLogMapper.selectPage(pageReqVO, userIds); 66 return operateLogMapper.selectPage(pageReqVO, userIds);
67 } 67 }
68 68
69 - //======================= LOG V2 ======================= 69 + // ======================= LOG V2 =======================
70 70
71 @Override 71 @Override
72 public void createOperateLogV2(OperateLogV2CreateReqBO createReqBO) { 72 public void createOperateLogV2(OperateLogV2CreateReqBO createReqBO) {