1、需求:比较 实体被修改的字段是哪些
anno
import java.lang.annotation.*;
/**
* 比较类不同字段
* @author wlq
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ForUpdate {
String fieldName() default "";
}
entity
/** 合同名称 */
@ForUpdate(fieldName = "合同名称")
private String contractName;
/** 合同类型 */
@ForUpdate(fieldName = "合同类型")
private Integer contractType;
@Transient
private String contractTypeText;
/** 开始时间 */
@ForUpdate(fieldName = "开始时间")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date startTime;
/** 结束时间 */
@ForUpdate(fieldName = "结束时间")
@JsonFormat(pattern = "yyyy-MM-dd")
private Date endTime;
BeanUtil
import com.sunther.idb.tran.anno.ForUpdate;
import java.lang.reflect.Field;
import java.util.Objects;
/**
* @author csb
* @description: TODO
* @date 2023/4/14 10:18
*/
public class BeanUtil {
/**
* 获取变更内容
* @param oldBean 更改前的Bean
* @param newBean 更改后的Bean
* @param <T>
* @return
*/
public static <T> String getChangedFields(T oldBean, T newBean){
Field[] fields = newBean.getClass().getDeclaredFields();
StringBuilder builder = new StringBuilder();
for(Field field : fields) {
field.setAccessible(true);
//skip filed without @ForUpdate
if (!field.isAnnotationPresent(ForUpdate.class)) {
continue;
}
try {
Object oldValue = field.get(oldBean);
Object newValue = field.get(newBean);
if(!Objects.equals(newValue, oldValue)) {
builder.append("修改【");
builder.append(field.getAnnotation(ForUpdate.class).fieldName()); //获取字段名称
builder.append("】,'");
builder.append(oldValue);
builder.append("'为'");
builder.append(newValue);
builder.append("'");
}
} catch (Exception e) {
System.out.println(e);
}
}
return builder.toString();
}
}
2、在接口返回上添加 数据浏览量。由于涉及的接口较多,我们采用自定义注解
在需要获取浏览量的controller的方法上添加 @ViewsCount
@ViewsCount(modouleType = 1)
@GetMapping("/list")
public TableDataInfo list(ResearchReport researchReport)
{
startPage();
List<ResearchReport> list = researchReportService.selectList(researchReport);
return getDataTable(list);
}
anno
modouleType :用于注解传参
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewsCount {
int modouleType();
}
aspect
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.context.SecurityContextHolder;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.common.log.annotation.Views;
import com.ruoyi.common.log.annotation.ViewsCount;
import com.ruoyi.system.api.RemoteViewsService;
import com.ruoyi.system.api.model.BrFavorite;
import com.ruoyi.system.api.model.ViewsEntity;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.ruoyi.common.core.web.domain.AjaxResult.DATA_TAG;
/**
* @author csb
* @description: TODO
* @date 2022/12/7 11:39
*/
@Order(7)
@Aspect
@Component
@Slf4j
public class ViewsCountpect {
@Autowired
private RemoteViewsService remoteViewsService;
/**
* 字典后缀
*/
private static String DICT_TEXT_SUFFIX = "viewCount";
/**
* 切点,切入 controller 包下面的所有方法
*/
@Pointcut("execution( * com.sunther.*.controller.*.*(..)) && @annotation(com.ruoyi.common.log.annotation.ViewsCount)")
public void viewsCount() {
}
@Around("viewsCount()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
ViewsCount viewsCount = method.getAnnotation(ViewsCount.class);
int modouleType = viewsCount.modouleType();
long time1 = System.currentTimeMillis();
Object result = pjp.proceed();
long time2 = System.currentTimeMillis();
log.debug("获取JSON数据 耗时:" + (time2 - time1) + "ms");
long start = System.currentTimeMillis();
this.setViewCount(modouleType,result,pjp);
long end = System.currentTimeMillis();
log.debug("解析注入JSON数据 耗时" + (end - start) + "ms");
return result;
}
private void setViewCount(int modouleType,Object result,ProceedingJoinPoint pjp) {
if (modouleType == 0){
Object[] args = pjp.getArgs();
if (args.length > 0) {
modouleType = (int) args[0];
}
}
if (result instanceof TableDataInfo) {
TableDataInfo rr = (TableDataInfo) result;
if (rr.getTotal() > 0) {
List<?> list = (List<?>) rr.getRows();
List<JSONObject> items = new ArrayList<>();
JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(list));
List<Integer> infoIds = jsonArray.stream().map( c -> ((JSONObject)c).getInteger("id")).collect(Collectors.toList());
List<ViewsEntity> viewsList = remoteViewsService.getViews(modouleType, infoIds);
for (Object record : list) {
setDatas(items, record, viewsList);
}
rr.setRows(items);
}
}else if (result instanceof AjaxResult) {
AjaxResult aa = (AjaxResult) result;
Object obj = JSON.toJSON(aa.get(DATA_TAG));
if (obj instanceof JSONObject) {
String id = ((JSONObject) obj).get("id").toString();
ViewsEntity viewsById = remoteViewsService.getViewsById(modouleType, Integer.valueOf(id));
if (viewsById == null){
((JSONObject) obj).put("viewsCount",0);
}else {
Integer viewCount = viewsById.getViewCount();
((JSONObject) obj).put("viewsCount",viewCount);
}
}
}
}
private void setDatas(List<JSONObject> items, Object record, List<ViewsEntity> viewsList){
ObjectMapper mapper = new ObjectMapper();
String json = "{}";
try {
// 解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormat
json = mapper.writeValueAsString(record);
} catch (JsonProcessingException e) {
log.error("Json解析失败:" + e);
}
JSONObject item = JSONObject.parseObject(json);
item.put("viewsCount", 0);
for (ViewsEntity viewsEntity : viewsList) {
if (item.getInteger("id").equals(viewsEntity.getInfoId())){
item.put(DICT_TEXT_SUFFIX , viewsEntity.getViewCount());
break;
}
}
items.add(item);
}
}