VersionCheckAspect.java.ftl 5.5 KB
Newer Older
zhouweidong's avatar
zhouweidong committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.aspect;

import lombok.SneakyThrows;
import ${pub.getPKGCodeName()}.util.annotation.VersionCheck;
import ${pub.getPKGCodeName()}.util.domain.EntityBase;
import ${pub.getPKGCodeName()}.util.errors.BadRequestAlertException;
import ${pub.getPKGCodeName()}.util.helper.RuleUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
24 25 26
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
27
import java.util.Map;
zhouweidong's avatar
zhouweidong committed
28 29 30 31 32

/**
 * 数据库版本检查
 */
@Aspect
zhouweidong's avatar
zhouweidong committed
33
@Order(50)
zhouweidong's avatar
zhouweidong committed
34 35 36 37
@Component
public class VersionCheckAspect
{
    private final ExpressionParser parser = new SpelExpressionParser();
zhouweidong's avatar
zhouweidong committed
38
    private final String IgnoreField = "ignoreversioncheck";
zhouweidong's avatar
zhouweidong committed
39 40 41

    @SneakyThrows
    @Before("execution(* ${pub.getPKGCodeName()}.*.rest.*.update(..)) &&  @annotation(versionCheck)")
zhouweidong's avatar
zhouweidong committed
42
    public void BeforeUpdate(JoinPoint point, VersionCheck versionCheck) {
zhouweidong's avatar
zhouweidong committed
43
        Object[] args = point.getArgs();
zhouweidong's avatar
zhouweidong committed
44 45
        Object id = args[0];
        Object dto = args[1];
zhouweidong's avatar
zhouweidong committed
46
        if(ObjectUtils.isEmpty(id) || ObjectUtils.isEmpty(dto)) {
zhouweidong's avatar
zhouweidong committed
47
            return;
zhouweidong's avatar
zhouweidong committed
48
        }
zhouweidong's avatar
zhouweidong committed
49
        String versionField = versionCheck.versionfield();
zhouweidong's avatar
zhouweidong committed
50
        if(StringUtils.isEmpty(versionField)) {
zhouweidong's avatar
zhouweidong committed
51
            return;
zhouweidong's avatar
zhouweidong committed
52
        }
zhouweidong's avatar
zhouweidong committed
53
        versionCheck(versionCheck,point.getTarget(), dto, id);
zhouweidong's avatar
zhouweidong committed
54 55 56 57
    }

    @SneakyThrows
    @Before("execution(* ${pub.getPKGCodeName()}.*.rest.*.updateBy*(..)) &&  @annotation(versionCheck)")
zhouweidong's avatar
zhouweidong committed
58
    public void BeforeUpdateBy(JoinPoint point, VersionCheck versionCheck) {
zhouweidong's avatar
zhouweidong committed
59
        Object[] args = point.getArgs();
zhouweidong's avatar
zhouweidong committed
60 61 62
        if(args.length>=2) {
            Object id = args[args.length-2];
            Object dto = args[args.length-1];
zhouweidong's avatar
zhouweidong committed
63
            if(ObjectUtils.isEmpty(id) || ObjectUtils.isEmpty(dto)) {
64
                return;
zhouweidong's avatar
zhouweidong committed
65
            }
zhouweidong's avatar
zhouweidong committed
66
            String versionField = versionCheck.versionfield();
zhouweidong's avatar
zhouweidong committed
67
            if(StringUtils.isEmpty(versionField)) {
68
                return;
zhouweidong's avatar
zhouweidong committed
69
            }
zhouweidong's avatar
zhouweidong committed
70
            versionCheck(versionCheck, point.getTarget(), dto, id);
71
        }
zhouweidong's avatar
zhouweidong committed
72 73
    }

zhouweidong's avatar
zhouweidong committed
74
    private void versionCheck(VersionCheck versionCheck, Object resource, Object dto, Object id) {
zhouweidong's avatar
zhouweidong committed
75
        EvaluationContext context = new StandardEvaluationContext();
zhouweidong's avatar
zhouweidong committed
76
        context.setVariable("dto", dto);
77 78
        //忽略版本检查
        Expression dtoParamsExp = parser.parseExpression("#dto.extensionparams");
zhouweidong's avatar
zhouweidong committed
79
        Map dtoParam = dtoParamsExp.getValue(context, Map.class);
zhouweidong's avatar
zhouweidong committed
80
        if(!ObjectUtils.isEmpty(dtoParam) && !ObjectUtils.isEmpty(dtoParam.get(IgnoreField)) && dtoParam.get(IgnoreField).equals(1)) {
81
            return;
zhouweidong's avatar
zhouweidong committed
82
        }
zhouweidong's avatar
zhouweidong committed
83 84
        Expression newExp = parser.parseExpression(String.format("#dto.%s", versionCheck.versionfield()));
        Object newVersion = newExp.getValue(context);
zhouweidong's avatar
zhouweidong committed
85
        if(ObjectUtils.isEmpty(newVersion)) {
zhouweidong's avatar
zhouweidong committed
86
            return;
zhouweidong's avatar
zhouweidong committed
87
        }
zhouweidong's avatar
zhouweidong committed
88
        //进行版本检查
zhouweidong's avatar
zhouweidong committed
89 90 91 92
        Object oldVersion = getDBVersion(versionCheck,getService(resource, versionCheck.entity()), id);
        if(!ObjectUtils.isEmpty(oldVersion)) {
            if(RuleUtils.gt(newVersion, oldVersion)) {
                throw new BadRequestAlertException("数据已变更,可能后台数据已被修改,请重新加载数据", "VersionCheckAspect", "versionCheck");
zhouweidong's avatar
zhouweidong committed
93
            }
zhouweidong's avatar
zhouweidong committed
94 95 96 97 98 99 100 101 102 103
        }
    }

    /**
     * 获取实体服务对象
     * @param resource
     * @param entity
     * @return
     */
    @SneakyThrows
zhouweidong's avatar
zhouweidong committed
104
    private Object getService(Object resource, String entity) {
zhouweidong's avatar
zhouweidong committed
105
        Object service = null;
zhouweidong's avatar
zhouweidong committed
106 107 108 109
        Field[] fields = resource.getClass().getDeclaredFields();
        for(Field field : fields) {
            if(field.getModifiers()==1 && field.getName().equalsIgnoreCase(String.format("%sService",entity))) {
                service = field.get(resource);
zhouweidong's avatar
zhouweidong committed
110 111 112 113 114 115 116 117 118 119 120 121 122 123
                break;
            }
        }
        return service;
    }

    /**
     * 获取数据库版本
     * @param versionCheck
     * @param service
     * @param id
     * @return
     */
    @SneakyThrows
zhouweidong's avatar
zhouweidong committed
124
    private Object getDBVersion(VersionCheck versionCheck, Object service, Object id) {
125
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
zhouweidong's avatar
zhouweidong committed
126 127 128
        Timestamp dbVersion = null;
        String versionField = versionCheck.versionfield();
        if(!ObjectUtils.isEmpty(service)) {
zhouweidong's avatar
zhouweidong committed
129
            EvaluationContext oldContext = new StandardEvaluationContext();
zhouweidong's avatar
zhouweidong committed
130 131
            oldContext.setVariable("service", service);
            oldContext.setVariable("id", id);
zhouweidong's avatar
zhouweidong committed
132
            Expression oldExp = parser.parseExpression("#service.get(#id)");
zhouweidong's avatar
zhouweidong committed
133 134 135 136
            EntityBase oldEntity = oldExp.getValue(oldContext, EntityBase.class);
            Object oldDate = oldEntity.get(versionField);
            if(oldDate!=null && oldDate instanceof Timestamp) {
                Timestamp db_time = (Timestamp) oldDate;
137
                Date db_date = sdf.parse(sdf.format(db_time));
zhouweidong's avatar
zhouweidong committed
138
                dbVersion = new Timestamp(db_date.getTime());
139
            }
zhouweidong's avatar
zhouweidong committed
140 141 142 143
        }
        return dbVersion;
    }
}