spring aop给返回值添加额外字段

海的味道 / 2024-09-24 / 原文

1、默认情况下直接修改返回值为新对象时无法达到预期结果、但可通过序列化方式达到给原对象增加字段的目的

import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;

import cn.as.foundation.web.api.BusinessCode;
import cn.as.foundation.web.exception.BusinessException;
import cn.as.geekbidder.core.annotation.Dict;
import cn.as.geekbidder.core.util.JacksonTool;
import cn.as.maple.platform.api.model.User;
import cn.as.maple.platform.api.service.UserService;
import cn.as.maple.process.api.model.FlowTask;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.flowable.engine.TaskService;
import org.flowable.identitylink.api.IdentityLink;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

@Aspect
@Component
@Slf4j
public class AddCurrentUser {

   @Autowired
   private TaskService taskService;

   @Autowired
   private UserService userService;

   /**
    * Pointcut
    */
   @Pointcut("execution(* cn.togeek.maple.process.controller.FlowTaskController.*(..))")
   public void joinPoint() {}


   private void addOtherInfo(Object result) {
      if (result instanceof IPage) {
         List<ObjectNode> items = new ArrayList<>();
         List<?> records = ((IPage<?>) result).getRecords();

         if(CollectionUtils.isEmpty(records)) {
            return;
         }

         for (Object record : records) {
            ObjectNode item = doAdd(record);
            items.add(item);
         }

         ((IPage<ObjectNode>) result).setRecords(items);
      }
   }

   public ObjectNode doAdd(Object record) {
      //解决@JsonFormat注解解析不了的问题
      String json = JacksonTool.object2String(record);
      ObjectNode item = JacksonTool.string2Object(json, ObjectNode.class);

      if(Objects.isNull(item)) {
         throw new BusinessException(BusinessCode.SYSTEM_ERROR.getCode(), "返回值解析失败");
      }
      String taskId = (String) ReflectUtil.getFieldValue(record, "taskId");
      List<IdentityLink> idList = this.taskService.getIdentityLinksForTask(taskId);
      List<User> collect = idList.stream().map(e -> {
         List<User> users;
         if(e.getUserId() != null) {
            users = userService.getUsersByIds(Collections.singletonList(e.getUserId()));
         }
         else {
            users = userService.getUserByRole(e.getGroupId());
         }
         return users;
      }).flatMap(Collection::stream).collect(Collectors.toList());
      String users = collect.stream().map(User::getName).collect(Collectors.joining(","));
      item.put("currentUser", users);
      return item;
   }

   @AfterReturning(value = "joinPoint()", returning = "methodResult")
   public void afterRt(JoinPoint jp, Object methodResult) {
      addOtherInfo(methodResult);
   }

}