SimpleAuditService.java 12.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
package cn.ibizlab.util.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import cn.ibizlab.util.annotation.Audit;
import cn.ibizlab.util.annotation.DEField;
import cn.ibizlab.util.domain.EntityBase;
import cn.ibizlab.util.domain.IBZDataAudit;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import cn.ibizlab.util.mapper.IBZDataAuditMapper;
import cn.ibizlab.util.security.AuthenticationUser;
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.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 实体[DataAudit] 服务对象接口实现
 */
@Service
@Slf4j
public class SimpleAuditService extends ServiceImpl<IBZDataAuditMapper, IBZDataAudit> implements IBZDataAuditService {

    private final ExpressionParser parser = new SpelExpressionParser();

    private static List cacheMap = Collections.synchronizedList(new ArrayList());

    /**
     * 定时保存审计记录
     */
    @Scheduled(fixedRate = 10000)
    public void saveAudit() {
45
        if(cacheMap.size()>0) {
46 47
            log.info(String.format("正在保存审计数据,当前审计集合数量为[%s]",cacheMap.size()));
            List temp=new ArrayList();
48
            if(cacheMap.size()<500) {
49 50
              temp.addAll(cacheMap);
            }
51
            else {
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
              temp.addAll(cacheMap.subList(0,500));
            }
            this.saveBatch(temp);
            cacheMap.removeAll(temp);
            log.info(String.format("保存完成,当前审计集合数量为[%s]",cacheMap.size()));
        }
    }

    /**
     * 新建审计日志
     * @param request
     * @param entity
     * @param idValue
     * @param auditFields
     */
    @Override
    public void createAudit(HttpServletRequest request, EntityBase entity, Object idValue, Map<String, Audit> auditFields) {
69
        IBZDataAudit dataAudit = new IBZDataAudit();
70
        dataAudit.setOppersonid(AuthenticationUser.getAuthenticationUser().getUserid());
71
        dataAudit.setOppersonname(String.format("%s[%s]", AuthenticationUser.getAuthenticationUser().getPersonname(), AuthenticationUser.getAuthenticationUser().getOrgname()));
72 73 74 75
        dataAudit.setAudittype("CREATE");
        dataAudit.setAuditobject(entity.getClass().getSimpleName());
        dataAudit.setAuditobjectdata(idValue);
        dataAudit.setOptime(new Timestamp(new Date().getTime()));
76
        if(request != null) {
77 78
            dataAudit.setIpaddress(getIpAddress(request, AuthenticationUser.getAuthenticationUser()));
        }
79
        dataAudit.setAuditinfo(getAuditInfo(entity, auditFields));
80 81 82 83 84 85 86 87 88 89 90 91 92
        dataAudit.setIsdatachanged(1);
        cacheMap.add(dataAudit);
    }

    /**
     * 更新审计日志
     * @param request
     * @param beforeEntity
     * @param serviceObj
     * @param idValue
     * @param auditFields
     */
    @SneakyThrows
93
    public void updateAudit(HttpServletRequest request, EntityBase beforeEntity, Object serviceObj, Object idValue, Map<String, Audit> auditFields) {
94
        //获取更新后的实体
95
        EntityBase afterEntity = getEntity(serviceObj, idValue);
96
        //获取更新后的审计内容
97 98
        String auditInfo = getUpdateAuditInfo(beforeEntity, afterEntity, auditFields);//比较更新前后差异内容
        int isDataChanged = 1;
99
        //审计内容是否发生变化
100 101
        if(StringUtils.isEmpty(auditInfo)) {
            isDataChanged = 0;
102
        }
103
        IBZDataAudit dataAudit = new IBZDataAudit();
104
        dataAudit.setOppersonid(AuthenticationUser.getAuthenticationUser().getUserid());
105
        dataAudit.setOppersonname(String.format("%s[%s]", AuthenticationUser.getAuthenticationUser().getPersonname(), AuthenticationUser.getAuthenticationUser().getOrgname()));
106 107 108 109
        dataAudit.setAudittype("UPDATE");
        dataAudit.setAuditobject(afterEntity.getClass().getSimpleName());
        dataAudit.setAuditobjectdata(idValue);
        dataAudit.setOptime(new Timestamp(new Date().getTime()));
110
        if(request!=null) {
111 112 113 114 115 116 117 118 119 120 121 122 123 124
            dataAudit.setIpaddress(getIpAddress(request, AuthenticationUser.getAuthenticationUser()));
        }
        dataAudit.setAuditinfo(auditInfo);
        dataAudit.setIsdatachanged(isDataChanged);
        cacheMap.add(dataAudit);
    }

    /**
     * 删除审计日志
     * @param request
     * @param entity
     * @param idValue
     * @param auditFields
     */
125 126
    public void removeAudit(HttpServletRequest request, EntityBase entity, Object idValue, Map<String, Audit> auditFields) {
        IBZDataAudit dataAudit = new IBZDataAudit();
127
        dataAudit.setOppersonid(AuthenticationUser.getAuthenticationUser().getUserid());
128
        dataAudit.setOppersonname(String.format("%s[%s]", AuthenticationUser.getAuthenticationUser().getPersonname(), AuthenticationUser.getAuthenticationUser().getOrgname()));
129 130 131 132
        dataAudit.setAudittype("REMOVE");
        dataAudit.setAuditobject(entity.getClass().getSimpleName());
        dataAudit.setAuditobjectdata(idValue);
        dataAudit.setOptime(new Timestamp(new Date().getTime()));
133
        if(request!=null) {
134 135
            dataAudit.setIpaddress(getIpAddress(request, AuthenticationUser.getAuthenticationUser()));
        }
136
        dataAudit.setAuditinfo(getAuditInfo(entity, auditFields));
137 138 139 140
        dataAudit.setIsdatachanged(1);
        cacheMap.add(dataAudit);
    }

141 142 143
    private String getAuditInfo(EntityBase entity, Map<String, Audit> auditFields) {
        String auditResult = "";
        if(auditFields.size() == 0) {
144 145
            return auditResult;
        }
146 147
        Map<String, DEField> deFields = DEFieldCacheMap.getDEFields(entity.getClass());
        if(deFields.size() == 0) {
148 149
            return auditResult;
        }
150
        JSONArray auditFieldArray = new JSONArray();
151
        for (Map.Entry<String, Audit> auditField : auditFields.entrySet()) {
152 153 154 155 156
            Object objFieldName = auditField.getKey();
            String fieldName = String.valueOf(objFieldName);
            DEField deField = null;
            if(deFields.containsKey(fieldName)) {
                deField = deFields.get(fieldName);
157
            }
158
            if(ObjectUtils.isEmpty(deField)) {
159 160
                continue;
            }
161 162 163 164 165 166 167
            Object value = dataTransfer(entity.get(fieldName), deField.fieldType(), deField.format());
            if(!StringUtils.isEmpty(value)) {
                JSONObject auditFieldObj = new JSONObject();
                auditFieldObj.put("field", deField.value());
                auditFieldObj.put("value", value);
                if(!StringUtils.isEmpty(deField.dict())) {
                    auditFieldObj.put("dict", deField.dict());
168 169 170 171
                }
                auditFieldArray.add(auditFieldObj);
            }
        }
172 173
        if(auditFieldArray.size()>0) {
            auditResult = auditFieldArray.toString();
174 175 176 177 178 179 180 181 182 183 184 185
        }
        return auditResult;
    }

    /**
     * 获取更新审计内容
     * @param oldData
     * @param newData
     * @param auditFields
     * @return
     */
    private String getUpdateAuditInfo(EntityBase oldData, EntityBase newData, Map<String, Audit> auditFields){
186 187 188
        String auditResult = "";
        JSONArray auditFieldArray = new JSONArray();
        if(auditFields.size() == 0) {
189 190 191
            return auditResult;
        }

192 193
        Map<String, DEField> deFields = DEFieldCacheMap.getDEFields(oldData.getClass());
        if(deFields.size() == 0){
194 195 196 197
            return auditResult;
        }

        for (Map.Entry<String, Audit> auditField : auditFields.entrySet()) {
198 199 200 201 202
            Object objFieldName = auditField.getKey();//获取注解字段
            String fieldName = String.valueOf(objFieldName); //属性名称
            DEField deField = null;
            if(deFields.containsKey(fieldName)) {
                deField = deFields.get(fieldName);
203
            }
204
            if(ObjectUtils.isEmpty(deField)) {
205 206
                continue;
            }
207 208 209 210 211 212 213 214 215 216 217
            Object oldValue = oldData.get(fieldName);//老属性值
            Object newValue = newData.get(fieldName);//新属性值
            if(!compare(oldValue, newValue)) {
                oldValue = dataTransfer(oldValue, deField.fieldType(), deField.format());//属性值转换
                newValue = dataTransfer(newValue, deField.fieldType(), deField.format());//属性值转换
                JSONObject auditFieldObj = new JSONObject();
                auditFieldObj.put("field", deField.value());
                auditFieldObj.put("beforevalue", oldValue);
                auditFieldObj.put("value", newValue);
                if(!StringUtils.isEmpty(deField.dict())) {
                    auditFieldObj.put("dict", deField.dict());
218 219 220 221
                }
                auditFieldArray.add(auditFieldObj);
            }
        }
222 223
        if(auditFieldArray.size()>0) {
            auditResult = auditFieldArray.toString();
224 225 226 227 228 229 230 231 232 233 234
        }
        return auditResult;
    }

    /**
     * 数据转换
     * @param value 转换值
     * @param dataType 转换字段类型
     * @param strFormat   转换字段格式化文本
     * @return
     */
235 236
    private String dataTransfer(Object value, String dataType, String strFormat) {
        if(value==null) {
237 238 239
            return "";
        }
        String transResult=value.toString();
240 241 242 243 244
        if((dataType.equals("DATE") || dataType.equals("DATETIME") || dataType.equals("TIME")) && (!StringUtils.isEmpty(strFormat))) {  //时间类型转换
            Timestamp timestamp = (Timestamp)value;
            Date date = timestamp;
            SimpleDateFormat format = new SimpleDateFormat(strFormat);
            transResult = format.format(date);
245 246 247 248 249 250 251 252 253 254
        }
        return transResult;
    }

    /**
     * 对象比较
     * @param sourceObj 比较源对象
     * @param targetObj 比较目标对象
     * @return
     */
255 256
    private boolean compare(Object sourceObj, Object targetObj) {
        if(sourceObj == null && targetObj == null) {
257 258
            return true;
        }
259
        if(sourceObj == null && targetObj != null) {
260 261 262 263 264 265 266 267 268 269 270 271
            return false;
        }
        return sourceObj.equals(targetObj);
    }

    /**
     * 获取实体
     * @param service
     * @param id
     * @return
     */
    @SneakyThrows
272 273 274
    private EntityBase getEntity(Object service, Object id) {
        EntityBase entity = null;
        if(!ObjectUtils.isEmpty(service)) {
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
            EvaluationContext oldContext = new StandardEvaluationContext();
            oldContext.setVariable("service",service);
            oldContext.setVariable("id",id);
            Expression oldExp = parser.parseExpression("#service.get(#id)");
            return oldExp.getValue(oldContext, EntityBase.class);
        }
        return entity;
    }

    /**
     * 获取Ip地址
     * @param request
     * @return
     */
    public String getIpAddress(HttpServletRequest request, AuthenticationUser authenticationUser) {
        //客户端有提交ip,以提交的ip为准
291
        if(authenticationUser != null && !StringUtils.isEmpty(authenticationUser.getAddr())) {
292 293
            return authenticationUser.getAddr();
        }
294
        if(request == null) {
295 296 297 298
            return "";
        }
        String Xip = request.getHeader("X-Real-IP");
        String XFor = request.getHeader("X-Forwarded-For");
299
        if(!StringUtils.isEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
300 301 302 303 304 305 306 307 308
            //多次反向代理后会有多个ip值,第一个ip才是真实ip
            int index = XFor.indexOf(",");
            if(index != -1){
                return XFor.substring(0,index);
            }else{
                return XFor;
            }
        }
        XFor = Xip;
309
        if(!StringUtils.isEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
            return XFor;
        }
        if (StringUtils.isEmpty(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isEmpty(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isEmpty(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("HTTP_CLIENT_IP");
        }
        if (StringUtils.isEmpty(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (StringUtils.isEmpty(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getRemoteAddr();
        }
        return XFor;
    }
}