mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 10:18:42 +08:00 
			
		
		
		
	📖 code review 操作日志的实现
This commit is contained in:
		| @@ -12,7 +12,10 @@ | |||||||
|     <packaging>jar</packaging> |     <packaging>jar</packaging> | ||||||
|  |  | ||||||
|     <name>${project.artifactId}</name> |     <name>${project.artifactId}</name> | ||||||
|     <description>用户的认证、权限的校验</description> |     <description> | ||||||
|  |         1. security:用户的认证、权限的校验,实现「谁」可以做「什么事」 | ||||||
|  |         2. operatelog:操作日志,实现「谁」在「什么时间」对「什么」做了「什么事」 | ||||||
|  |     </description> | ||||||
|     <url>https://github.com/YunaiV/ruoyi-vue-pro</url> |     <url>https://github.com/YunaiV/ruoyi-vue-pro</url> | ||||||
|  |  | ||||||
|     <dependencies> |     <dependencies> | ||||||
|   | |||||||
| @@ -8,9 +8,8 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; | |||||||
| import org.springframework.context.annotation.Bean; | import org.springframework.context.annotation.Bean; | ||||||
| import org.springframework.context.annotation.Primary; | import org.springframework.context.annotation.Primary; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * mzt-biz-log 配置类 |  * 操作日志配置类 | ||||||
|  * |  * | ||||||
|  * @author HUIHUI |  * @author HUIHUI | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -1 +1,4 @@ | |||||||
|  | /** | ||||||
|  |  * 占位,无特殊作用 | ||||||
|  |  */ | ||||||
| package cn.iocoder.yudao.framework.operatelog.core; | package cn.iocoder.yudao.framework.operatelog.core; | ||||||
| @@ -11,9 +11,9 @@ import jakarta.annotation.Resource; | |||||||
| import jakarta.servlet.http.HttpServletRequest; | import jakarta.servlet.http.HttpServletRequest; | ||||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||||
|  |  | ||||||
| import java.util.Collections; |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
|  | // TODO @puhui999:LogRecordServiceImpl 改成这个名字哈 | ||||||
| /** | /** | ||||||
|  * 操作日志 ILogRecordService 实现类 |  * 操作日志 ILogRecordService 实现类 | ||||||
|  * |  * | ||||||
| @@ -26,11 +26,11 @@ public class ILogRecordServiceImpl implements ILogRecordService { | |||||||
|  |  | ||||||
|     @Resource |     @Resource | ||||||
|     private OperateLogApi operateLogApi; |     private OperateLogApi operateLogApi; | ||||||
|      |  | ||||||
|     @Override |     @Override | ||||||
|     public void record(LogRecord logRecord) { |     public void record(LogRecord logRecord) { | ||||||
|  |         // 1. 补全通用字段 | ||||||
|         OperateLogV2CreateReqDTO reqDTO = new OperateLogV2CreateReqDTO(); |         OperateLogV2CreateReqDTO reqDTO = new OperateLogV2CreateReqDTO(); | ||||||
|         // 补全通用字段 |  | ||||||
|         reqDTO.setTraceId(TracerUtils.getTraceId()); |         reqDTO.setTraceId(TracerUtils.getTraceId()); | ||||||
|         // 补充用户信息 |         // 补充用户信息 | ||||||
|         fillUserFields(reqDTO); |         fillUserFields(reqDTO); | ||||||
| @@ -38,22 +38,24 @@ public class ILogRecordServiceImpl implements ILogRecordService { | |||||||
|         fillModuleFields(reqDTO, logRecord); |         fillModuleFields(reqDTO, logRecord); | ||||||
|         // 补全请求信息 |         // 补全请求信息 | ||||||
|         fillRequestFields(reqDTO); |         fillRequestFields(reqDTO); | ||||||
|         // 异步记录日志 |  | ||||||
|  |         // 2. 异步记录日志 | ||||||
|         operateLogApi.createOperateLogV2(reqDTO); |         operateLogApi.createOperateLogV2(reqDTO); | ||||||
|         // TODO 测试结束删除或搞个开关 |         // TODO 测试结束删除或搞个开关 | ||||||
|         log.info("操作日志 ===> {}", reqDTO); |         log.info("操作日志 ===> {}", reqDTO); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static void fillUserFields(OperateLogV2CreateReqDTO reqDTO) { |     private static void fillUserFields(OperateLogV2CreateReqDTO reqDTO) { | ||||||
|  |         // TODO @puhui999:使用 SecurityFrameworkUtils。因为要考虑,rpc、mq、job,它其实不是 web; | ||||||
|         reqDTO.setUserId(WebFrameworkUtils.getLoginUserId()); |         reqDTO.setUserId(WebFrameworkUtils.getLoginUserId()); | ||||||
|         reqDTO.setUserType(WebFrameworkUtils.getLoginUserType()); |         reqDTO.setUserType(WebFrameworkUtils.getLoginUserType()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void fillModuleFields(OperateLogV2CreateReqDTO reqDTO, LogRecord logRecord) { |     public static void fillModuleFields(OperateLogV2CreateReqDTO reqDTO, LogRecord logRecord) { | ||||||
|         reqDTO.setType(logRecord.getType()); // 大模块类型如 crm 客户 |         reqDTO.setType(logRecord.getType()); // 大模块类型,例如:CRM 客户 | ||||||
|         reqDTO.setSubType(logRecord.getSubType());// 操作名称如 转移客户 |         reqDTO.setSubType(logRecord.getSubType());// 操作名称,例如:转移客户 | ||||||
|         reqDTO.setBizId(Long.parseLong(logRecord.getBizNo())); // 操作模块业务编号 |         reqDTO.setBizId(Long.parseLong(logRecord.getBizNo())); // 业务编号,例如:客户编号 | ||||||
|         reqDTO.setAction(logRecord.getAction());// 例如说,修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 |         reqDTO.setAction(logRecord.getAction());// 操作内容,例如:修改编号为 1 的用户信息,将性别从男改成女,将姓名从芋道改成源码。 | ||||||
|         reqDTO.setExtra(logRecord.getExtra()); // 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ),例如说,记录订单编号,{ orderId: "1"} |         reqDTO.setExtra(logRecord.getExtra()); // 拓展字段,有些复杂的业务,需要记录一些字段 ( JSON 格式 ),例如说,记录订单编号,{ orderId: "1"} | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -72,12 +74,12 @@ public class ILogRecordServiceImpl implements ILogRecordService { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public List<LogRecord> queryLog(String bizNo, String type) { |     public List<LogRecord> queryLog(String bizNo, String type) { | ||||||
|         return Collections.emptyList(); |         throw new UnsupportedOperationException("使用 OperateLogApi 进行操作日志的查询"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public List<LogRecord> queryLogByBizNo(String bizNo, String type, String subType) { |     public List<LogRecord> queryLogByBizNo(String bizNo, String type, String subType) { | ||||||
|         return Collections.emptyList(); |         throw new UnsupportedOperationException("使用 OperateLogApi 进行操作日志的查询"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | /** | ||||||
|  |  * 基于 mzt-log 框架 | ||||||
|  |  * 实现操作日志功能 | ||||||
|  |  * | ||||||
|  |  * @author HUIHUI | ||||||
|  |  */ | ||||||
|  | package cn.iocoder.yudao.framework.operatelog; | ||||||
| @@ -1,6 +1,5 @@ | |||||||
| package cn.iocoder.yudao.module.crm.enums; | package cn.iocoder.yudao.module.crm.enums; | ||||||
|  |  | ||||||
| // TODO 芋艿:操作日志;看看这个类怎么搞个好点的规范; |  | ||||||
| /** | /** | ||||||
|  * CRM 操作日志枚举 |  * CRM 操作日志枚举 | ||||||
|  * |  * | ||||||
| @@ -23,4 +22,12 @@ public interface LogRecordConstants { | |||||||
|  |  | ||||||
|     String TRANSFER_CUSTOMER_LOG_SUCCESS = "把客户【{{#crmCustomer.name}}】的负责人从【{getAdminUserById{#crmCustomer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; |     String TRANSFER_CUSTOMER_LOG_SUCCESS = "把客户【{{#crmCustomer.name}}】的负责人从【{getAdminUserById{#crmCustomer.ownerUserId}}】变更为了【{getAdminUserById{#reqVO.newOwnerUserId}}】"; | ||||||
|  |  | ||||||
|  |     // TODO @puhui999:这里格式是不是可以这样;目的是:统一管理,也减少 Service 里各种“复杂”字符串 | ||||||
|  |     // ======================= Customer 客户 ======================= | ||||||
|  |     String CUSTOMER_TYPE = "CRM 客户"; | ||||||
|  |     String CUSTOMER_CREATE_SUB_TYPE = "创建客户"; | ||||||
|  |     String CUSTOMER_CREATE_SUCCESS = "更新了客户{_DIFF{#updateReqVO}}"; | ||||||
|  |  | ||||||
|  |     String CUSTOMER_UPDATE_SUB_TYPE = "更新客户"; | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -60,7 +60,7 @@ public class CrmCustomerController { | |||||||
|  |  | ||||||
|     @PostMapping("/create") |     @PostMapping("/create") | ||||||
|     @Operation(summary = "创建客户") |     @Operation(summary = "创建客户") | ||||||
|     @OperateLog(enable = false) // TODO 关闭原有日志记录 |     @OperateLog(enable = false) // TODO 关闭原有日志记录;@puhui999:注解都先删除。先记录,没关系。我们下个迭代,就都删除掉操作日志了; | ||||||
|     @PreAuthorize("@ss.hasPermission('crm:customer:create')") |     @PreAuthorize("@ss.hasPermission('crm:customer:create')") | ||||||
|     public CommonResult<Long> createCustomer(@Valid @RequestBody CrmCustomerCreateReqVO createReqVO) { |     public CommonResult<Long> createCustomer(@Valid @RequestBody CrmCustomerCreateReqVO createReqVO) { | ||||||
|         return success(customerService.createCustomer(createReqVO, getLoginUserId())); |         return success(customerService.createCustomer(createReqVO, getLoginUserId())); | ||||||
| @@ -102,6 +102,7 @@ public class CrmCustomerController { | |||||||
|         return success(CrmCustomerConvert.INSTANCE.convert(customer, userMap, deptMap)); |         return success(CrmCustomerConvert.INSTANCE.convert(customer, userMap, deptMap)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // TODO @puhui999:这个查询会查出多个;微信发你图了 | ||||||
|     @GetMapping("/page") |     @GetMapping("/page") | ||||||
|     @Operation(summary = "获得客户分页") |     @Operation(summary = "获得客户分页") | ||||||
|     @PreAuthorize("@ss.hasPermission('crm:customer:query')") |     @PreAuthorize("@ss.hasPermission('crm:customer:query')") | ||||||
| @@ -141,6 +142,7 @@ public class CrmCustomerController { | |||||||
|         return success(true); |         return success(true); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // TODO @puhui999:是不是接口只要传递 bizId,由 Controller 自己组装出 OperateLogV2PageReqDTO | ||||||
|     @GetMapping("/operate-log-page") |     @GetMapping("/operate-log-page") | ||||||
|     @Operation(summary = "获得客户操作日志") |     @Operation(summary = "获得客户操作日志") | ||||||
|     @PreAuthorize("@ss.hasPermission('crm:customer:query')") |     @PreAuthorize("@ss.hasPermission('crm:customer:query')") | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| package cn.iocoder.yudao.module.crm.framework.operatelog.core; | package cn.iocoder.yudao.module.crm.framework.operatelog.core; | ||||||
|  |  | ||||||
| import cn.hutool.core.util.ObjUtil; |  | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | ||||||
| import com.mzt.logapi.service.IParseFunction; | import com.mzt.logapi.service.IParseFunction; | ||||||
| @@ -10,7 +9,7 @@ import org.springframework.stereotype.Component; | |||||||
| import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY; | import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_INDUSTRY; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 自定义函数-通过行业编号获取行业信息 |  * 行业的 {@link IParseFunction} 实现类 | ||||||
|  * |  * | ||||||
|  * @author HUIHUI |  * @author HUIHUI | ||||||
|  */ |  */ | ||||||
| @@ -30,14 +29,9 @@ public class CrmIndustryParseFunction implements IParseFunction { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public String apply(Object value) { |     public String apply(Object value) { | ||||||
|         if (ObjUtil.isEmpty(value)) { |         if (StrUtil.isEmptyIfStr(value)) { | ||||||
|             return ""; |             return ""; | ||||||
|         } |         } | ||||||
|         if (StrUtil.isEmpty(value.toString())) { |  | ||||||
|             return ""; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // 获取行业信息 |  | ||||||
|         return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_INDUSTRY, value.toString()); |         return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_INDUSTRY, value.toString()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| package cn.iocoder.yudao.module.crm.framework.operatelog.core; | package cn.iocoder.yudao.module.crm.framework.operatelog.core; | ||||||
|  |  | ||||||
| import cn.hutool.core.util.ObjUtil; |  | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | ||||||
| import com.mzt.logapi.service.IParseFunction; | import com.mzt.logapi.service.IParseFunction; | ||||||
| @@ -10,7 +9,7 @@ import org.springframework.stereotype.Component; | |||||||
| import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_LEVEL; | import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_LEVEL; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 自定义函数-通过客户等级编号获取客户等级信息 |  * 客户等级的 {@link IParseFunction} 实现类 | ||||||
|  * |  * | ||||||
|  * @author HUIHUI |  * @author HUIHUI | ||||||
|  */ |  */ | ||||||
| @@ -30,14 +29,9 @@ public class CrmLevelParseFunction implements IParseFunction { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public String apply(Object value) { |     public String apply(Object value) { | ||||||
|         if (ObjUtil.isEmpty(value)) { |         if (StrUtil.isEmptyIfStr(value)) { | ||||||
|             return ""; |             return ""; | ||||||
|         } |         } | ||||||
|         if (StrUtil.isEmpty(value.toString())) { |  | ||||||
|             return ""; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // 获取客户等级信息 |  | ||||||
|         return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_LEVEL, value.toString()); |         return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_LEVEL, value.toString()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| package cn.iocoder.yudao.module.crm.framework.operatelog.core; | package cn.iocoder.yudao.module.crm.framework.operatelog.core; | ||||||
|  |  | ||||||
| import cn.hutool.core.util.ObjUtil; |  | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | ||||||
| import com.mzt.logapi.service.IParseFunction; | import com.mzt.logapi.service.IParseFunction; | ||||||
| @@ -10,7 +9,7 @@ import org.springframework.stereotype.Component; | |||||||
| import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_SOURCE; | import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_CUSTOMER_SOURCE; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 自定义函数-通过客户来源编号获取客户来源信息 |  * 客户来源的 {@link IParseFunction} 实现类 | ||||||
|  * |  * | ||||||
|  * @author HUIHUI |  * @author HUIHUI | ||||||
|  */ |  */ | ||||||
| @@ -30,14 +29,9 @@ public class CrmSourceParseFunction implements IParseFunction { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public String apply(Object value) { |     public String apply(Object value) { | ||||||
|         if (ObjUtil.isEmpty(value)) { |         if (StrUtil.isEmptyIfStr(value)) { | ||||||
|             return ""; |             return ""; | ||||||
|         } |         } | ||||||
|         if (StrUtil.isEmpty(value.toString())) { |  | ||||||
|             return ""; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // 获取客户来源信息 |  | ||||||
|         return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_SOURCE, value.toString()); |         return DictFrameworkUtils.getDictDataLabel(CRM_CUSTOMER_SOURCE, value.toString()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,7 +13,6 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti | |||||||
|  */ |  */ | ||||||
| public class CrmPermissionUtils { | public class CrmPermissionUtils { | ||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 校验用户是否是 CRM 管理员 |      * 校验用户是否是 CRM 管理员 | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -62,7 +62,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | |||||||
|         crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) |         crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType()) | ||||||
|                 .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 |                 .setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 | ||||||
|  |  | ||||||
|         // 添加日志上下文所需 |         // 记录操作日志 | ||||||
|         LogRecordContext.putVariable("customerId", customer.getId()); |         LogRecordContext.putVariable("customerId", customer.getId()); | ||||||
|         return customer.getId(); |         return customer.getId(); | ||||||
|     } |     } | ||||||
| @@ -73,15 +73,15 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { | |||||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) |     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CUSTOMER, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) | ||||||
|     public void updateCustomer(CrmCustomerUpdateReqVO updateReqVO) { |     public void updateCustomer(CrmCustomerUpdateReqVO updateReqVO) { | ||||||
|         // 校验存在 |         // 校验存在 | ||||||
|         CrmCustomerDO oldCustomerDO = validateCustomerExists(updateReqVO.getId()); |         CrmCustomerDO oldCustomer = validateCustomerExists(updateReqVO.getId()); | ||||||
|  |  | ||||||
|         // 更新 |         // 更新 | ||||||
|         CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO); |         CrmCustomerDO updateObj = CrmCustomerConvert.INSTANCE.convert(updateReqVO); | ||||||
|         customerMapper.updateById(updateObj); |         customerMapper.updateById(updateObj); | ||||||
|  |  | ||||||
|         // __DIFF 函数传递了一个参数,传递的参数是修改之后的对象,这种方式需要在方法内部向 LogRecordContext 中 put 一个变量,代表是之前的对象,这个对象可以是null |         // 记录操作日志 | ||||||
|         LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomerDO, CrmCustomerUpdateReqVO.class)); |         LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldCustomer, CrmCustomerUpdateReqVO.class)); | ||||||
|         // TODO 扩展信息测试 |         // TODO 扩展信息测试 @puhui999:看着没啥问题,可以删除啦; | ||||||
|         HashMap<String, Object> extra = new HashMap<>(); |         HashMap<String, Object> extra = new HashMap<>(); | ||||||
|         extra.put("tips", "随便记录一点啦"); |         extra.put("tips", "随便记录一点啦"); | ||||||
|         LogRecordContext.putVariable("extra", extra); |         LogRecordContext.putVariable("extra", extra); | ||||||
|   | |||||||
| @@ -90,7 +90,8 @@ public class CrmPermissionServiceImpl implements CrmPermissionService { | |||||||
|         CrmPermissionDO oldPermission = crmPermissionMapper.selectByBizTypeAndBizIdByUserId( |         CrmPermissionDO oldPermission = crmPermissionMapper.selectByBizTypeAndBizIdByUserId( | ||||||
|                 transferReqBO.getBizType(), transferReqBO.getBizId(), transferReqBO.getUserId()); |                 transferReqBO.getBizType(), transferReqBO.getBizId(), transferReqBO.getUserId()); | ||||||
|         String bizTypeName = CrmBizTypeEnum.getNameByType(transferReqBO.getBizType()); |         String bizTypeName = CrmBizTypeEnum.getNameByType(transferReqBO.getBizType()); | ||||||
|         if (oldPermission == null || (!isOwner(oldPermission.getLevel()) && !CrmPermissionUtils.isCrmAdmin())) {  // 不是拥有者,并且不是超管 |         if (oldPermission == null // 不是拥有者,并且不是超管 | ||||||
|  |                 || (!isOwner(oldPermission.getLevel()) && !CrmPermissionUtils.isCrmAdmin())) { | ||||||
|             throw exception(CRM_PERMISSION_DENIED, bizTypeName); |             throw exception(CRM_PERMISSION_DENIED, bizTypeName); | ||||||
|         } |         } | ||||||
|         // 1.1 校验转移对象是否已经是该负责人 |         // 1.1 校验转移对象是否已经是该负责人 | ||||||
|   | |||||||
| @@ -40,7 +40,7 @@ public class CrmQueryWrapperUtils { | |||||||
|                                                                                     Long userId, Integer sceneType, Boolean pool) { |                                                                                     Long userId, Integer sceneType, Boolean pool) { | ||||||
|         final String ownerUserIdField = SingletonManager.getMybatisPlusJoinProperties().getTableAlias() + ".owner_user_id"; |         final String ownerUserIdField = SingletonManager.getMybatisPlusJoinProperties().getTableAlias() + ".owner_user_id"; | ||||||
|         // 1. 构建数据权限连表条件 |         // 1. 构建数据权限连表条件 | ||||||
|         if (ObjUtil.notEqual(CrmPermissionUtils.isCrmAdmin(), Boolean.TRUE) && ObjUtil.notEqual(pool, Boolean.TRUE)) { // 管理员,公海不需要数据权限 |         if (!CrmPermissionUtils.isCrmAdmin() && ObjUtil.notEqual(pool, Boolean.TRUE)) { // 管理员,公海不需要数据权限 | ||||||
|             query.innerJoin(CrmPermissionDO.class, on -> on.eq(CrmPermissionDO::getBizType, bizType) |             query.innerJoin(CrmPermissionDO.class, on -> on.eq(CrmPermissionDO::getBizType, bizType) | ||||||
|                     .eq(CrmPermissionDO::getBizId, bizId) // 只能使用 SFunction 如果传 id 解析出来的 sql 不对 |                     .eq(CrmPermissionDO::getBizId, bizId) // 只能使用 SFunction 如果传 id 解析出来的 sql 不对 | ||||||
|                     .eq(CrmPermissionDO::getUserId, userId)); |                     .eq(CrmPermissionDO::getUserId, userId)); | ||||||
| @@ -81,7 +81,7 @@ public class CrmQueryWrapperUtils { | |||||||
|      * @param userId  用户编号 |      * @param userId  用户编号 | ||||||
|      */ |      */ | ||||||
|     public static <T extends MPJLambdaWrapper<?>> void appendPermissionCondition(T query, Integer bizType, Collection<Long> bizIds, Long userId) { |     public static <T extends MPJLambdaWrapper<?>> void appendPermissionCondition(T query, Integer bizType, Collection<Long> bizIds, Long userId) { | ||||||
|         if (ObjUtil.equal(CrmPermissionUtils.isCrmAdmin(), Boolean.TRUE)) {// 管理员不需要数据权限 |         if (CrmPermissionUtils.isCrmAdmin()) {// 管理员不需要数据权限 | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -53,7 +53,8 @@ public class OperateLogApiImpl implements OperateLogApi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         // 获取用户 |         // 获取用户 | ||||||
|         List<AdminUserDO> userList = adminUserService.getUserList(convertSet(operateLogPage.getList(), OperateLogV2DO::getUserId)); |         List<AdminUserDO> userList = adminUserService.getUserList( | ||||||
|  |                 convertSet(operateLogPage.getList(), OperateLogV2DO::getUserId)); | ||||||
|         return OperateLogConvert.INSTANCE.convertPage(operateLogPage, userList); |         return OperateLogConvert.INSTANCE.convertPage(operateLogPage, userList); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,12 +10,12 @@ import org.apache.ibatis.annotations.Mapper; | |||||||
| @Mapper | @Mapper | ||||||
| public interface OperateLogV2Mapper extends BaseMapperX<OperateLogV2DO> { | public interface OperateLogV2Mapper extends BaseMapperX<OperateLogV2DO> { | ||||||
|  |  | ||||||
|     default PageResult<OperateLogV2DO> selectPage(OperateLogV2PageReqDTO pageReqVO) { |     default PageResult<OperateLogV2DO> selectPage(OperateLogV2PageReqDTO pageReqDTO) { | ||||||
|         return selectPage(pageReqVO, new LambdaQueryWrapperX<OperateLogV2DO>() |         return selectPage(pageReqDTO, new LambdaQueryWrapperX<OperateLogV2DO>() | ||||||
|                 .eqIfPresent(OperateLogV2DO::getType, pageReqVO.getBizType()) |                 .eqIfPresent(OperateLogV2DO::getType, pageReqDTO.getBizType()) | ||||||
|                 .eqIfPresent(OperateLogV2DO::getBizId, pageReqVO.getBizId()) |                 .eqIfPresent(OperateLogV2DO::getBizId, pageReqDTO.getBizId()) | ||||||
|                 .eqIfPresent(OperateLogV2DO::getUserId, pageReqVO.getUserId()) |                 .eqIfPresent(OperateLogV2DO::getUserId, pageReqDTO.getUserId()) | ||||||
|                 .orderByDesc(OperateLogV2DO::getCreateTime)); |                 .orderByDesc(OperateLogV2DO::getId)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| package cn.iocoder.yudao.module.system.framework.operatelog.core; | package cn.iocoder.yudao.module.system.framework.operatelog.core; | ||||||
|  |  | ||||||
| import cn.hutool.core.util.ObjUtil; |  | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | ||||||
| import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | ||||||
| @@ -10,7 +9,7 @@ import lombok.extern.slf4j.Slf4j; | |||||||
| import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 自定义函数-通过用户编号获取用户信息 |  * 管理员名字的 {@link IParseFunction} 实现类 | ||||||
|  * |  * | ||||||
|  * @author HUIHUI |  * @author HUIHUI | ||||||
|  */ |  */ | ||||||
| @@ -28,25 +27,22 @@ public class AdminUserParseFunction implements IParseFunction { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public String apply(Object value) { |     public String apply(Object value) { | ||||||
|         if (ObjUtil.isEmpty(value)) { |         if (StrUtil.isEmptyIfStr(value)) { | ||||||
|             return ""; |  | ||||||
|         } |  | ||||||
|         if (StrUtil.isEmpty(value.toString())) { |  | ||||||
|             return ""; |             return ""; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // 获取用户信息 |         // 获取用户信息 | ||||||
|         AdminUserRespDTO user = adminUserApi.getUser(Long.parseLong(value.toString())); |         AdminUserRespDTO user = adminUserApi.getUser(Long.parseLong(value.toString())); | ||||||
|         if (user == null) { |         if (user == null) { | ||||||
|             log.warn("(getAdminUserById) 获取用户信息失败,参数为:{}", value); |             log.warn("[apply][获取用户{{}}为空", value); | ||||||
|             return ""; |             return ""; | ||||||
|         } |         } | ||||||
|         // 返回格式 芋道源码(13888888888) |         // 返回格式 芋道源码(13888888888) | ||||||
|         String nickname = user.getNickname(); |         String nickname = user.getNickname(); | ||||||
|         if (ObjUtil.isNotEmpty(user.getMobile())) { |         if (StrUtil.isEmpty(user.getMobile())) { | ||||||
|             return nickname.concat("(").concat(user.getMobile()).concat(")"); |             return nickname; | ||||||
|         } |         } | ||||||
|         return nickname; |         return StrUtil.format("{}({})", nickname, user.getMobile()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| package cn.iocoder.yudao.module.system.framework.operatelog.core; | package cn.iocoder.yudao.module.system.framework.operatelog.core; | ||||||
|  |  | ||||||
| import cn.hutool.core.util.ObjUtil; |  | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; | import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; | ||||||
| import com.mzt.logapi.service.IParseFunction; | import com.mzt.logapi.service.IParseFunction; | ||||||
| @@ -8,7 +7,7 @@ import lombok.extern.slf4j.Slf4j; | |||||||
| import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 自定义函数-通过区域编号获取区域信息 |  * 地名的 {@link IParseFunction} 实现类 | ||||||
|  * |  * | ||||||
|  * @author HUIHUI |  * @author HUIHUI | ||||||
|  */ |  */ | ||||||
| @@ -28,13 +27,9 @@ public class AreaParseFunction implements IParseFunction { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public String apply(Object value) { |     public String apply(Object value) { | ||||||
|         if (ObjUtil.isEmpty(value)) { |         if (StrUtil.isEmptyIfStr(value)) { | ||||||
|             return ""; |             return ""; | ||||||
|         } |         } | ||||||
|         if (StrUtil.isEmpty(value.toString())) { |  | ||||||
|             return ""; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return AreaUtils.format(Integer.parseInt(value.toString())); |         return AreaUtils.format(Integer.parseInt(value.toString())); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -35,9 +35,9 @@ public interface OperateLogService { | |||||||
|     /** |     /** | ||||||
|      * 记录操作日志 V2 |      * 记录操作日志 V2 | ||||||
|      * |      * | ||||||
|      * @param createReqBO 创建请求 |      * @param createReqDTO 创建请求 | ||||||
|      */ |      */ | ||||||
|     void createOperateLogV2(OperateLogV2CreateReqDTO createReqBO); |     void createOperateLogV2(OperateLogV2CreateReqDTO createReqDTO); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 获得操作日志分页列表 |      * 获得操作日志分页列表 | ||||||
|   | |||||||
| @@ -69,15 +69,14 @@ public class OperateLogServiceImpl implements OperateLogService { | |||||||
|     // ======================= LOG V2 ======================= |     // ======================= LOG V2 ======================= | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void createOperateLogV2(OperateLogV2CreateReqDTO createReqBO) { |     public void createOperateLogV2(OperateLogV2CreateReqDTO createReqDTO) { | ||||||
|         OperateLogV2DO log = BeanUtils.toBean(createReqBO, OperateLogV2DO.class); |         OperateLogV2DO log = BeanUtils.toBean(createReqDTO, OperateLogV2DO.class); | ||||||
|         operateLogV2Mapper.insert(log); |         operateLogV2Mapper.insert(log); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public PageResult<OperateLogV2DO> getOperateLogPage(OperateLogV2PageReqDTO pageReqVO) { |     public PageResult<OperateLogV2DO> getOperateLogPage(OperateLogV2PageReqDTO pageReqDTO) { | ||||||
|         return operateLogV2Mapper.selectPage(pageReqVO); |         return operateLogV2Mapper.selectPage(pageReqDTO); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV