使用java反射和AOP对比两个对象的属性来实现修改操作日志记录功能

场景
当执行某个修改动作时,记录那些字段存在改变的字段,生成相应的批次号,批次号对应某个修改动作,修改动作对应多个修改记录,也就是批次号对应多个修改记录

数据库设计
批次表和批次操作记录表

CREATE TABLE `ins_operation_batch_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `change_type` int(1) DEFAULT '0' COMMENT '1-手动修改,2-导入修改',
  `batch_no` varchar(30) DEFAULT NULL COMMENT '批次编号',
  `create_id` varchar(30) DEFAULT NULL COMMENT '创建人编号',
  `create_name` varchar(50) DEFAULT NULL COMMENT '创建人名称',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  KEY `index_create_time` (`create_name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=143 DEFAULT CHARSET=utf8mb4 COMMENT='操作批次表';

CREATE TABLE `ins_operation_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `change_type` int(1) DEFAULT '0' COMMENT '1-手动修改,2-导入修改',
  `batch_no` varchar(30) DEFAULT NULL COMMENT '批次编号',
  `new_value` varchar(300) DEFAULT NULL COMMENT '新值',
  `old_value` varchar(300) DEFAULT NULL COMMENT '旧值',
  `create_id` varchar(30) DEFAULT NULL COMMENT '创建人编号',
  `create_name` varchar(50) DEFAULT NULL COMMENT '创建人名称',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `key_value` varchar(100) DEFAULT NULL COMMENT '值文字描述',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=606 DEFAULT CHARSET=utf8mb4 COMMENT='操作记录表';

原理
通过AOP切面以注解作为切点 来对需要记录的方法进行代理,在执行前查询一遍修改表的记录,修改完之后在查询一遍修改后的记录,然后二者进行比对插入表中完成业务需求

具体过程如下

  1. 新增注解

该注解的作用为标记哪些字段需要作为比对对象
第二个字段是用作转义的,用作将数字转化为业务字段 ,比如某字段为1,但是在业务层代表的是小学,这时后会通过枚举类映射将1当作小学存放在日志表中

package com.skindow.annotion;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/** 该注解用于比对对象的属性,如果属性没有使用该注解则跳过该属性
 * Created by skindow on 2019/9/20.
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AttributeComparison
{
     public String name() default "未知";
         OverseasInsuranceMap.OverseasInsuranceEnum attriMapDesc() default OverseasInsuranceMap.OverseasInsuranceEnum.defaulNull;

}

该注解用于一个对象下面有多个对象,标记某个对象需要纳入比对范围,没有注解的则跳过

package com.chtwm.insurance.agency.common.annotion;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/** 使用该注解得对象纳入对比范围 例如A对象中有B对象,如果B对象含有该注解,则纳入比对
 * Created by skindow on 2019/9/20.
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AttributeComForObject
{
}

该注解用于作为AOP的切点,提供查询服务,操作人信息

package com.chtwm.insurance.agency.common.annotion;

import com.chtwm.insurance.agency.common.map.LogBatchParam;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/** 批次日志切点
 * Created by skindow on 2019/10/10.
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface AttributeComAscpet
{
    @AliasFor(
            annotation = Component.class
    )
    /**
     *  服务层bean
     */
     Class serviceOrMapperClass();

    /** 调用方法的名称
     * @return
     */
    String methodName();

    /** 修改人id
     * @return
     */
    String updateId();

    /** 修改人名称
     * @return
     */
    String updateName();

    /** 修改方式
     * @return
     */
    LogBatchParam.LogBatchParamEnum changeType() default LogBatchParam.LogBatchParamEnum .sd;
}

该注解用于查询服务的入参

package com.chtwm.insurance.agency.common.annotion;

import java.lang.annotation.*;

/** 服务层调用入参
 * Created by skindow on 2019/10/10.
 */
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AttributeComReqBody
{

}

该注解标注操作人信息

package com.chtwm.insurance.agency.common.annotion;

import java.lang.annotation.*;

/** 获取操作人信息
 * Created by skindow on 2019/10/10.
 */
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AttributeComReqEmp
{

}

  1. 新建bean对象,来存储那些有差异的属性,用作比对之后返回的对象
package com.chtwm.insurance.natives.provider.bean.result;

import lombok.Data;

import java.math.BigDecimal;
import java.text.DecimalFormat;

/**
 * Created by skindow on 2019/9/20.
 */
@Data
public class CheckResult {
    private static final DecimalFormat DF = new DecimalFormat("0.00");;
    public CheckResult(Object oldDta, Object newData,String name) {
        if (oldDta instanceof BigDecimal)
        {
            BigDecimal bo = (BigDecimal) oldDta;
            if (bo != null)
            {
                this.oldDta = DF.format(oldDta);
            }
        }
        else
        {
            this.oldDta = oldDta;
        }
        if (newData instanceof BigDecimal)
        {
            BigDecimal bn = (BigDecimal)newData;
            if (bn != null)
            {
                this.newData = DF.format(bn);
            }
        }
        else
        {
            this.newData = newData;
        }
        this.name = name;
    }
    /**
     * 原值
     */
    private Object oldDta;
    /**
     * 新值
     */
    private Object newData;
    /**
     * 名称
     */
    private String name;
}

  1. 新建比对工具类,主要是用反射原理来比对字段的相关值
/**比较个对象属性的值是否相等 配合注解AttributeComparison使用
     * @param o
     * @param n
     * @param results
     * @return
     * @throws Exception
     */
    public static List<CheckResult> attributeComparison(Object o, Object n,List<CheckResult> results) throws Exception
    {
        if (o == null || n == null)
        {
            return results;
        }
        Class<?> nClass = n.getClass();
        Class<?> oClass = o.getClass();
        Field[] nfields = nClass.getDeclaredFields();
        if (nfields == null || nfields.length == 0)
        {
            return results;
        }
        for (Field nfield : nfields)
        {
            nfield.setAccessible(true);
            if (hashAnnotionByClass(nfield,AttributeComForObject.class))
            {
                Object n1 = nfield.get(n);
                Field ofield = nClass.getDeclaredField(nfield.getName());
                if (ofield == null)
                {
                    continue;
                }
                ofield.setAccessible(true);
                Object o1 = ofield.get(o);
                attributeComparison(o1,n1,results);
            }
            else
            {
                fileCheck(o, n, oClass,nClass, results, nfield);
            }
        }
        return results;
    }

    /** 比对成员变量属性
     * @param o
     * @param n
     * @param nClass
     * @param results
     * @param ofield
     * @throws Exception
     */
    private static void fileCheck(Object o, Object n,Class<?> oClass, Class<?> nClass, List<CheckResult> results, Field nfield) throws Exception {
        if (!hashAnnotionByClass(nfield,AttributeComparison.class) || !isCheck(nfield))
        {
            return;
        }
        Field ofield = oClass.getDeclaredField(nfield.getName());
        ofield.setAccessible(true);
        if (nfield == null)
        {
            return;
        }
        compareValue(o, n, results, ofield, nfield);
    }

    /** 开始比对属性
     * @param o
     * @param n
     * @param results
     * @param ofield
     * @param nfield
     * @throws Exception
     */
    public static void compareValue(Object o, Object n, List<CheckResult> results, Field ofield, Field nfield) throws Exception {
        CheckResult checkResult;
        Object on;
        Object ol;
        on = nfield.get(n);
        ol = ofield.get(o);
        String annoStr = getAnnoStr(nfield);
        log.info("比对字段名称【{}】======================= 新值【{}】 ===================== 旧值【{}】" ,annoStr,on,ol);
        if (on == null && ol == null)
        {
            return;
        }
        OverseasInsuranceMap.OverseasInsuranceEnum annoMap = getAnnoMap(nfield);
        if(annoMap != OverseasInsuranceMap.OverseasInsuranceEnum.defaulNull)
        {
            if (on != null)
            {
                String s = mapToStr(on.toString(), annoMap.getMap(annoMap));
                on = s == null ? on : s;
            }
            if (ol != null)
            {
                String s = mapToStr(ol.toString(), annoMap.getMap(annoMap));
                ol = s == null ? ol : s;
            }
        }
        if (hashOneNull(ol,on))
        {
            checkResult = new CheckResult(ol,on, annoStr);
            results.add(checkResult);
            return;
        }
        Class<?> kc;
        if ((kc =comparableClassFor(ol)) != null)
        {
            if (compareComparables(kc,ol,on) != 0)
            {
                checkResult = new CheckResult(ol,on, annoStr);
                results.add(checkResult);
            }
            return;
        }
        //默认使用equals比较相同
        if (ol.toString().equals(on.toString()))
        {
            return;
        }
        else
        {
            checkResult = new CheckResult(ol,on,getAnnoStr(ofield));
            results.add(checkResult);
        }
    }

    public static int compareComparables(Class<?> kc, Object k, Object x)
    {
        return (x == null || x.getClass() != kc ? 0 :
                ((Comparable)k).compareTo(x));
    }

    public static Class<?> comparableClassFor(Object x)
    {
        if (x instanceof Comparable) {
            Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
            if ((c = x.getClass()) == String.class) // bypass checks
                return c;
            if ((ts = c.getGenericInterfaces()) != null)
            {
                for (int i = 0; i < ts.length; ++i)
                {
                    if (((t = ts[i]) instanceof ParameterizedType) &&
                            ((p = (ParameterizedType)t).getRawType() ==
                                    Comparable.class) &&
                            (as = p.getActualTypeArguments()) != null &&
                            as.length == 1 && as[0] == c)
                        return c;
                }
            }
        }
        return null;
    }
    /** 获取比对注解的name值
     * @param field
     * @return
     * @throws Exception
     */
    public static String getAnnoStr(Field field) throws Exception {
        AttributeComparison attributeComparison = (AttributeComparison)getAttributeComparison(field,AttributeComparison.class);
        if (attributeComparison == null)
        {
            return null;
        }
        return attributeComparison.name();
    }

    /** 获取比对注解的枚举值
     * @param field
     * @return
     * @throws Exception
     */
    public static OverseasInsuranceMap.OverseasInsuranceEnum getAnnoMap(Field field)  {
        AttributeComparison attributeComparison = (AttributeComparison)getAttributeComparison(field,AttributeComparison.class);
        if (attributeComparison == null)
        {
            return null;
        }
        return attributeComparison.attriMapDesc();
    }


    /** 其中一个对象含有值则默认两者不同
     * @param o1
     * @param o2
     * @return
     */
    public static Boolean hashOneNull (Object o1,Object o2)
    {
        if (o1 != null && o2 == null)
        {
            return true;
        }
        if (o1 == null && o2 != null)
        {
            return true;
        }
        return false;
    }

    /** 是否满足比对条件
     * @param ofield
     * @return
     */
    public static Boolean isCheck (Field ofield)
    {
        Class<?> type = ofield.getType();
        if (type.isInterface())
        {
            return false;
        }
        if (hashAnnotionByClass(ofield, AttributeComForObject.class))
        {
            return false;
        }
        return true;
    }

    /** 获取属性比较注解
     * @param field
     * @return
     */
    public static Annotation getAttributeComparison(Field field,Class c)
    {
        Annotation[] annotations = field.getAnnotations();
        if (annotations == null || annotations.length == 0)
        {
            return null;
        }
        for (Annotation annotation : annotations)
        {
            if (annotation.annotationType().getTypeName().equals(c.getName()))
            {
                return annotation;
            }
        }
        return null;
    }

    /** 判断是否存在比对注解
     * @param ofield
     * @return
     */
    private static Boolean hashAnnotionByClass(Field ofield, Class c)
    {
        Annotation attributeComparison = getAttributeComparison(ofield, c);
        if (attributeComparison == null)
        {
            return false;
        }
        return true;
    }

  1. 使用线程调用,使用线程池管理线程以达到日志插入异步的效果

新建线程工具类

package com.chtwm.insurance.natives.provider.util;

import com.chtwm.insurance.natives.api.params.LogBatchParam;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created by skindow on 2019/9/24.
 */
@Slf4j
public class OperateLogThreadUtil {
    private final static ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 10, 10000, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));

    /** 添加批次处理日志任务
     * @param logBatchParam
     */
    public static void add(LogBatchParam logBatchParam)
    {
        if (logBatchParam == null)
        {
            log.warn("logBatchParam is null");
            return;
        }
        ExcuteTask excuteTask = new ExcuteTask(logBatchParam);
        List<Callable<ExcuteTask>> list = Lists.newArrayList();
        list.add(excuteTask);
        try
        {
            executor.invokeAll(list);
        }
        catch (InterruptedException e)
        {
           log.error("启动日志批次线程任务异常,错误日志为: {}",e);
        }
    }

    /**添加批次处理日志任务
     * @param listLog
     */
    public static void addList(List<LogBatchParam> listLog)
    {
        if (listLog == null || listLog.size() == 0)
        {
            log.warn("listLog is null");
            return;
        }
        List<Callable<ExcuteTask>> list = Lists.newArrayList();
        for (LogBatchParam logBatchParam : listLog)
        {
            ExcuteTask excuteTask = new ExcuteTask(logBatchParam);
            list.add(excuteTask);
        }
        try
        {
            executor.invokeAll(list);
        }
        catch (InterruptedException e)
        {
            log.error("启动日志批次线程任务异常,错误日志为: {}",e);
        }
    }
}

创建线程实现类
这里使了用DataSourceTransactionManager事务管理器来管理事务,事务隔离级别设置成PROPAGATION_REQUIRES_NEW,设置成PROPAGATION_REQUIRES_NEW会有问题得(被代理的修改方法被当前事务给回滚了,但我这里还是会提交事务,目前我通过判断代理方法的返回参数,比如包了一层Result,通过判断Result来控制是否插入日志,这里有待优化,应该使用外层的事务,不应生成新事物来管理事务)

package com.chtwm.insurance.natives.provider.util;

import com.alibaba.fastjson.JSON;
import com.chtwm.insurance.natives.api.entity.InsOperationBatchLogEntity;
import com.chtwm.insurance.natives.api.entity.InsOperationLogEntity;
import com.chtwm.insurance.natives.api.params.LogBatchParam;
import com.chtwm.insurance.natives.provider.bean.result.CheckResult;
import com.chtwm.insurance.natives.provider.mapper.InsOperationBatchLogEntityMapper;
import com.chtwm.insurance.natives.provider.mapper.InsOperationLogEntityMapper;
import com.common.seq.sql.SqlSeqUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.List;
import java.util.concurrent.Callable;

/**
 * Created by skindow on 2019/9/24.
 */
@Slf4j
public class ExcuteTask implements Callable {
    private LogBatchParam logBatchParam;
    private InsOperationBatchLogEntityMapper insOperationBatchLogEntityMapper;
    private InsOperationLogEntityMapper insOperationLogEntityMapper;
    private DataSourceTransactionManager transactionManager;

    public ExcuteTask(LogBatchParam logBatchParam)
    {
        this.logBatchParam = logBatchParam;
        ApplicationContext ac = SpringUtil.getApplicationContext();
        this.insOperationBatchLogEntityMapper = (InsOperationBatchLogEntityMapper)ac.getBean(InsOperationBatchLogEntityMapper.class);
        this.insOperationLogEntityMapper =  (InsOperationLogEntityMapper)ac.getBean(InsOperationLogEntityMapper.class);
        this.transactionManager = (DataSourceTransactionManager)ac.getBean(DataSourceTransactionManager.class);
    }
    @Override
    public T call()
    {
        log.info("线程【{}】开始执行日志批次新增任务,参数为{}",Thread.currentThread().getName(), JSON.toJSONString(logBatchParam));
        if (logBatchParam == null)
        {
            log.warn("参数为空,请核实!");
            return null;
        }
        DefaultTransactionDefinition transDefinition = new DefaultTransactionDefinition();
        transDefinition.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRES_NEW);
        TransactionStatus transStatus = transactionManager.getTransaction(transDefinition);
        transactionManager.setRollbackOnCommitFailure(true);
        try
        {
            List<CheckResult> results = BusUtil.attributeComparison(logBatchParam.getOldObject(), logBatchParam.getNewObject());
            if (results == null || results.size() == 0)
            {
                log.warn("没有发现属性有差异的情况,请核实!");
                return null;
            }
            log.info("开始插入批次记录");
            String batchNo = getBatchNo();
            if(!inserBatch(batchNo))
            {
                return null;
            }
            log.info("开始插入日志操作记录..");
            if (!inserLog(batchNo,results))
            {
                return null;
            }
        }
        catch (Exception e)
        {
            log.error("比对对象属性出错,错误信息为:{}",e);
            transactionManager.rollback(transStatus);
            return null;
        }
        transactionManager.commit(transStatus);
        log.info("======================日志记录结束=============================");
        return null;
    }

    /** 生成批次号 C00000001
     * @return
     */
    private String getBatchNo()
    {
        String batchNo = SqlSeqUtil.get("ins_operation_batch_log") + "";
        int length = batchNo.length();
        int i = 0;
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("C");
        if ((i= 8 - length) > 0)
        {
            for (int j = 0; j < i; j++)
            {
                stringBuilder.append("0");
            }
        }
        stringBuilder.append(batchNo);
        return stringBuilder.toString();
    }

    /** 新增批次号
     * @param batchNo
     * @return
     */
    private Boolean inserBatch(String batchNo)
    {
        InsOperationBatchLogEntity insOperationBatchLogEntity = new InsOperationBatchLogEntity();
        insOperationBatchLogEntity.setBatchNo(batchNo);
        insOperationBatchLogEntity.setChangeType(logBatchParam.getChangeType());
        insOperationBatchLogEntity.setCreateId(logBatchParam.getCreateId());
        insOperationBatchLogEntity.setCreateName(logBatchParam.getCreateName());
        int insert = insOperationBatchLogEntityMapper.insert(insOperationBatchLogEntity);
        if (insert == 0)
        {
            log.error("新增批次出错");
            return false;
        }
        else
        {
            log.info("新增批次成功");
            return true;
        }
    }

    private Boolean inserLog(String batchNo,List<CheckResult> results)
    {
        List<InsOperationLogEntity> list = Lists.newArrayList();
        InsOperationLogEntity insOperationLogEntity = null;
        for (CheckResult result : results)
        {
            insOperationLogEntity = new InsOperationLogEntity();
            insOperationLogEntity.setBatchNo(batchNo);
            insOperationLogEntity.setChangeType(logBatchParam.getChangeType());
            insOperationLogEntity.setCreateId(logBatchParam.getCreateId());
            insOperationLogEntity.setCreateName(logBatchParam.getCreateName());
            insOperationLogEntity.setKeyValue(result.getName());
            insOperationLogEntity.setNewValue(result.getNewData() == null ? null : result.getNewData().toString());
            insOperationLogEntity.setOldValue(result.getOldDta() == null ? null : result.getOldDta().toString());
            list.add(insOperationLogEntity);
            insOperationLogEntity = null;
        }
        int i = insOperationLogEntityMapper.batchInsert(list);
        if (i == 0)
        {
            log.error("批量新增日志操作详情失败");
            return false;
        }
        else
        {
            log.info("批量新增日志操作详情成功");
            return true;
        }
    }
}

  1. service层调用线程
package com.chtwm.insurance.natives.provider.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.chtwm.insurance.agency.common.base.PageResult;
import com.chtwm.insurance.natives.api.entity.InsOperationBatchLogEntity;
import com.chtwm.insurance.natives.api.params.LogBatchParam;
import com.chtwm.insurance.natives.api.params.QueryLogBatchParam;
import com.chtwm.insurance.natives.api.service.InsOperationBatchLogService;
import com.chtwm.insurance.natives.provider.mapper.InsOperationBatchLogEntityMapper;
import com.chtwm.insurance.natives.provider.util.BusUtil;
import com.chtwm.insurance.natives.provider.util.OperateLogThreadUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import javax.validation.Valid;
import java.util.List;

/**
 * Created by skindow on 2019/9/23.
 */
@Service
@Slf4j
public class InsOperationBatchLogServiceImpl implements InsOperationBatchLogService{

    @Autowired
    private InsOperationBatchLogEntityMapper insOperationBatchLogEntityMapper;

    @Override
    public void inserBatchLog(LogBatchParam logBatchParam)
    {
        OperateLogThreadUtil.add(logBatchParam);
    }
}
  1. 新建SpringUtil 用于ApplicationContext ,因为调用服务方法,必须从容器中获取
package com.chtwm.insurance.natives.provider.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * Created by skindow on 2019/9/24.
 */
@Slf4j
@Component
public class SpringUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

        if(SpringUtil.applicationContext == null) {
            SpringUtil.applicationContext = applicationContext;
        }
        log.info("ApplicationContext配置成功,applicationContext对象:"+SpringUtil.applicationContext);
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    public static <T> T getBean(String name,Class<T> clazz) {
        return getApplicationContext().getBean(name,clazz);
    }

}

  1. 新建AOP
package com.chtwm.insurance.natives.provider.logAspect;

import com.alibaba.fastjson.JSON;
import com.chtwm.insurance.agency.common.annotion.AttributeComAscpet;
import com.chtwm.insurance.agency.common.annotion.AttributeComReqBody;
import com.chtwm.insurance.agency.common.annotion.AttributeComReqEmp;
import com.chtwm.insurance.agency.common.base.Result;
import com.chtwm.insurance.agency.common.map.LogBatchParam;
import com.chtwm.insurance.natives.provider.util.OperateLogThreadUtil;
import com.chtwm.insurance.natives.provider.util.SpringUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
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.stereotype.Component;
import org.springframework.util.Assert;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.List;

/**
 * Created by skindow on 2019/10/10.
 */
@Component
@Aspect
@Slf4j
public class LogAspect
{


    @Pointcut("@annotation(com.chtwm.insurance.agency.common.annotion.AttributeComAscpet))")
    public void webLog() {
    }

    @Around("webLog()")
    public Object doBefore(ProceedingJoinPoint joinPoint) throws Throwable
    {
        Object asceptBean = null;
        Object[] aspectRequestArgs = null;
        String methodName = null;
        String updateId = null;
        String updateName = null;
        Integer changeType = null;
        Object oldObject = null;
        Method method;
        Class<?>[] parameterTypes = null;
        Boolean flag = false;
        Class aspectAnnotationProvider = null;
        try
        {
            log.info("{} 执行批次日志记录", joinPoint.getSignature().toString());

            //获取切点方法
            method = getMethod(joinPoint);
            Assert.notNull(method,"method is null");
            method.setAccessible(true);

            //获取日志注解
            AttributeComAscpet attributeComAscpet = getAttributeComAscpet(method);
            Assert.notNull(attributeComAscpet,"attributeComAscpet is null");

            //获取注解接扣服务
            aspectAnnotationProvider = getAsceptAnnoProvider(attributeComAscpet);

            //获取服务
            asceptBean = getAspectBean(aspectAnnotationProvider);
            Assert.notNull(asceptBean,"aspectAnnotationProvider is null");

            //获取服务入参
            aspectRequestArgs = getAspectRequest(method,joinPoint.getArgs());
            Assert.notNull(aspectRequestArgs,"aspectRequest is null");

            //服务层方法名称
            methodName = getMethodName(attributeComAscpet);
            Assert.notNull(methodName,"methodName is null");

            //获取操作人id
            updateId = getUpdateId(attributeComAscpet, method,joinPoint.getArgs());
            Assert.notNull(updateId,"updateId is null");

            //获取操作人名称
            updateName = getUpdateName(attributeComAscpet, method,joinPoint.getArgs());
            Assert.notNull(updateName,"updateName is null");

            //获取导入类型
            changeType = getChangeType(attributeComAscpet);
            Assert.notNull(changeType,"changeType is null");

            //获取入参类型
            parameterTypes = getAspectRequestForClass(method,aspectRequestArgs);
            Assert.notNull(changeType,"parameterTypes is null");


            oldObject = getAspectValue(methodName, aspectRequestArgs,asceptBean,aspectAnnotationProvider,parameterTypes);
            Assert.notNull(oldObject,"oldObject is null");

            flag = true;
        }
        catch (Exception e)
        {
            log.error("insert Log run something error! ",e);
        }
        Object proceed = joinPoint.proceed();
        try
        {
            if (flag && isExecuteSuccess(proceed))
            {
                Object newObject = getAspectValue(methodName, aspectRequestArgs,asceptBean,aspectAnnotationProvider,parameterTypes);
                Assert.notNull(oldObject,"newObject is null");
                insertLog(updateId, updateName, changeType, oldObject, newObject);
            }
        }
        catch (Exception e)
        {
            log.error("insert Log run something error! ",e);
        }
        return proceed;
    }

    private Boolean isExecuteSuccess(Object object) throws Exception
    {
        if (object == null)
        {
            return false;
        }
        if (object instanceof Result)
        {
            Result result = (Result)object;
            return result.isSuccess();
        }
        else if (object instanceof Pair)
        {
            Pair pair = (Pair)object;
            if ( pair.getLeft() instanceof Boolean)
            {
                return (Boolean)pair.getLeft();
            }
        }
        return true;
    }

    private void insertLog(String updateId, String updateName, Integer changeType, Object oldObject, Object newObject)
    {
        LogBatchParam logBatchParam = new LogBatchParam();
        logBatchParam.setChangeType(changeType);
        logBatchParam.setCreateName(updateName);
        logBatchParam.setCreateId(updateId);
        logBatchParam.setNewObject(newObject);
        logBatchParam.setOldObject(oldObject);
        OperateLogThreadUtil.add(logBatchParam);
    }

    private Object getAspectValue(String methodName, Object[] aspectRequestArgs, Object asceptBean, Class asceptAnnoProvider,Class<?>[] parameterTypes)
    {
        try
        {
            log.info("正在调用【{}】服务,方法名为【{}】,入参为{}",asceptAnnoProvider,methodName, JSON.toJSONString(aspectRequestArgs));
            Method method = asceptBean.getClass().getMethod(methodName, parameterTypes);
            Object invoke = method.invoke(asceptBean, aspectRequestArgs);
            return invoke;
        }
        catch (IllegalAccessException e)
        {
            log.error("执行bean{}方法{}失败!",methodName,aspectRequestArgs,e);
        }
        catch (InvocationTargetException e)
        {
            log.error("执行bean{}方法{}失败!",methodName,aspectRequestArgs,e);
        }
        catch (NoSuchMethodException e)
        {
            log.error("该bean{}中没有找到方法{}失败!",methodName,aspectRequestArgs,e);
        }
        return null;
    }

    private String getMethodName(AttributeComAscpet attributeComAscpet)
    {
        return attributeComAscpet.methodName();
    }

    private String getUpdateId(AttributeComAscpet attributeComAscpet,Method method,Object[] args)
    {
        String s = attributeComAscpet.updateId();
        return getAnnotionValue(method, args, s);
    }
    private Integer getChangeType(AttributeComAscpet attributeComAscpet)
    {
        LogBatchParam.LogBatchParamEnum logBatchParamEnum = attributeComAscpet.changeType();
        return LogBatchParam.LogBatchParamEnum.getMap(logBatchParamEnum);
    }
    private String getUpdateName(AttributeComAscpet attributeComAscpet,Method method,Object[] args)
    {
        String s = attributeComAscpet.updateName();
        return getAnnotionValue(method, args, s);
    }

    private String getAnnotionValue(Method method, Object[] args, String s) {
        Parameter[] parameters = method.getParameters();
        List<Object> reqByAnnotion = getReqByAnnotion(parameters, AttributeComReqEmp.class,args);
        String o = getObjectByFile(reqByAnnotion.toArray(), s);
        if (o != null) return o;
        return null;
    }

    private String getObjectByFile(Object[] aspectRequestArgs, String s) {
        for (Object aspectRequestArg : aspectRequestArgs)
        {
            for (Field field : aspectRequestArg.getClass().getDeclaredFields())
                {
                    field.setAccessible(true);
                    if (field.getName().equals(s))
                    {
                        Object o = null;
                        try
                        {
                            o = field.get(aspectRequestArg);
                        }
                        catch (IllegalAccessException e)
                        {
                            log.error("该对象中{}获取{}属性的值失败!",aspectRequestArgs,s);
                        }
                        return o == null ? null : o.toString();
                    }
                }
            }
        log.error("未在该对象中{}找到{}属性的值",aspectRequestArgs,s);
        return null;
    }

    private Object[] getAspectRequest(Method method,Object[] args)
    {
        Parameter[] parameters = method.getParameters();
        if (parameters == null)
        {
            log.warn("this method{}  parameters is null",method);
            return null;
        }
        List<Object> list = getReqByAnnotion(parameters, AttributeComReqBody.class,args);
        return list.toArray();
    }

    private Class<?>[] getAspectRequestForClass(Method method,Object[] args)
    {
        Parameter[] parameters = method.getParameters();
        if (parameters == null)
        {
            log.warn("this method{}  parameters is null",method);
            return null;
        }
        return getReqTypeByAnnotion(parameters, AttributeComReqBody.class,args);
    }

    private Class<?>[] getReqTypeByAnnotion(Parameter[] parameters,Class cla,Object[] args) {
        Class<?>[] list = new Class<?>[1];
        for (int i = 0; i < parameters.length; i++)
        {
            Parameter parameter = parameters[i];
            Annotation[] declaredAnnotationsByType = parameter.getDeclaredAnnotationsByType(cla);
            if (declaredAnnotationsByType != null && declaredAnnotationsByType.length > 0)
            {
                list[0] = parameter.getType();
                return list;
            }
        }
        return list;
    }

    private List<Object> getReqByAnnotion(Parameter[] parameters,Class cla,Object[] args) {
        List<Object> list = Lists.newArrayList();
        for (int i = 0; i < parameters.length; i++)
        {
            Parameter parameter = parameters[i];
            Annotation[] declaredAnnotationsByType = parameter.getDeclaredAnnotationsByType(cla);
            if (declaredAnnotationsByType != null && declaredAnnotationsByType.length > 0)
            {
                list.add(args[i]);
            }
        }
        return list;
    }

    private AttributeComAscpet getAttributeComAscpet(Method methodThis)
    {
        Assert.notNull(methodThis,"methodThis is null");
        Annotation[] annotations = methodThis.getAnnotations();
        AttributeComAscpet attributeComAscpet = getAttributeComparison(annotations, AttributeComAscpet.class);
        return attributeComAscpet;
    }

    private Method getMethod(ProceedingJoinPoint joinPoint) throws NoSuchMethodException {
        Signature sig = joinPoint.getSignature();
        MethodSignature msig;
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("获取方法失败");
        }
        msig = (MethodSignature) sig;
        Object target = joinPoint.getTarget();
        Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
        return currentMethod;
    }

    private Object getAspectBean(Class asceptAnnoProvider) throws ClassNotFoundException {
        return SpringUtil.getBean(asceptAnnoProvider);
    }

    private Class getAsceptAnnoProvider(AttributeComAscpet attributeComAscpet) {
        return attributeComAscpet.serviceOrMapperClass();
    }

    private static <T> T  getAttributeComparison(Annotation[] annotations, Class<T> c)
    {
        if (annotations == null || annotations.length == 0)
        {
            return null;
        }
        for (Annotation annotation : annotations)
        {
            if (annotation.annotationType().getTypeName().equals(c.getName()))
            {
                return (T) annotation;
            }
        }
        return null;
    }
}

这里有个着重点需要讲下:
AOP不是所有方法都能代理的,AOP是基于JDK动态代理和cglib代理的,如果你代理的方法不是增强方法(比如proxy增强过的)即使你加入了切点也不会被拦截的。
这里就和我的初衷违背了,我设计的初衷是控制层也好,服务层也好,还有他们内部的普通方法也要能拦截的

比如这个场景,我在service层 updateA方法 去调用 updateB方法,此时我需要对updateB方法进行代理,如果我们什么不做,直接将注解写在updateB方法上是不会被拦截的,但是我们卸载updateA方法是会被拦截的,因为updateA方法已经被增强了,而updateB方法并没有被增强

解决方法

这里考虑到我们使用了dubbo来管理服务,所以这里我们将updateB方法在interface里声明,此时实现类就是重写是写updateB方法了,此时updateB通过接口实现了jdk的动态代理
你以为到这里就结束了?其实不然
我们还要在updateA方法里加上前缀
((XXXXService) AopContext.currentProxy())
就像这样掉用 ((XXXXService) AopContext.currentProxy()).updateB
这只是其中的一步
我们还要在启动主程序入口加上注解
@EnableAspectJAutoProxy(exposeProxy = true)
表示通过aop框架暴露该代理对象,aopContext能够访问,它会自动注册一个aop代理对象生成器。
这里就是为什么要使用 ((XXXXService) AopContext.currentProxy())去调用了

  1. 测试
    具体代码就写了=-=

这里就是调用service层里面的一个普通方法,也就是A方法去调用B方法
在这里插入图片描述
B方法需要在接口层声明
在这里插入图片描述
在这里插入图片描述
注解代码为

  @Override
    @Transactional(rollbackFor = Exception.class)
    @AttributeComAscpet(serviceOrMapperClass = InsOffshoreinsPolicyService.class,methodName ="queryReservationDetails",updateName = "name",updateId = "code",changeType = LogBatchParam.LogBatchParamEnum.dr)
    public Result aloneUpdateUnderMod(@AttributeComReqBody String resreservationId, UnderModIimportParam underModIimportParam, Map<String,DoCheckUnderModParam> resreservationIdMap, ExcelResult excelResult, Map<String,QueryUnderTrackingParam> UnderTrackingParamMap, @AttributeComReqEmp Emp user)
  

查询服务的出参也需要加入注解如下
在这里插入图片描述
在这里插入图片描述

运行效果为下

2019-10-14 16:02:53.942 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] WARN  com.rbac.dubbo.filter.RbacGetDomainFilter:31 - RbacGetDomainFilter get domain info null from invocation
2019-10-14 16:02:53.947 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] INFO  com.common.aspect.Aspect:33 - ExcelResult com.chtwm.insurance.natives.provider.service.impl.InsOffshoreinsPolicyServiceImpl.updateUnderMod(ExcelResult,Emp) 调用时间:2019-10-14 16:02:53
2019-10-14 16:02:53.958 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] INFO  c.c.i.n.p.s.impl.InsOffshoreinsPolicyServiceImpl:1115 - 开始校验承保修改信息字段的合法性...
2019-10-14 16:02:54.179 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] INFO  c.c.i.n.p.s.impl.InsOffshoreinsPolicyServiceImpl:358 - 校验承保修改信息字段结束
2019-10-14 16:02:54.179 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] INFO  com.common.aspect.Aspect:33 - Result com.chtwm.insurance.natives.provider.service.impl.InsOffshoreinsPolicyServiceImpl.aloneUpdateUnderMod(String,UnderModIimportParam,Map,ExcelResult,Map,Emp) 调用时间:2019-10-14 16:02:54
2019-10-14 16:02:54.264 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] INFO  c.c.insurance.natives.provider.logAspect.LogAspect:160 - 正在调用【interface com.chtwm.insurance.natives.api.service.InsOffshoreinsPolicyService】服务,方法名为【queryReservationDetails】,入参为["HB201909100070"]
2019-10-14 16:02:54.265 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] INFO  com.common.aspect.Aspect:33 - InsOffshorePolicyDetailsVO com.chtwm.insurance.natives.provider.service.impl.InsOffshoreinsPolicyServiceImpl.queryReservationDetails(String) 调用时间:2019-10-14 16:02:54
2019-10-14 16:02:54.279 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] INFO  com.common.aspect.Aspect:38 - InsOffshorePolicyDetailsVO com.chtwm.insurance.natives.provider.service.impl.InsOffshoreinsPolicyServiceImpl.queryReservationDetails(String) 执行时间:14ms
2019-10-14 16:02:54.284 TID: N/A [Thread-5] INFO  com.common.aspect.Aspect:43 - InsOffshorePolicyDetailsVO com.chtwm.insurance.natives.provider.service.impl.InsOffshoreinsPolicyServiceImpl.queryReservationDetails(String) 方法入参[{"String":"HB201909100070"}]
2019-10-14 16:02:54.313 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] INFO  c.c.i.n.p.s.impl.InsOffshoreinsPolicyServiceImpl:912 - 开始同步相关信息中...  underModIimportParam 参数为 {"policyId":"225553","row":2,"status":"8"}
2019-10-14 16:02:54.313 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] INFO  c.c.i.n.p.s.impl.InsOffshoreinsPolicyServiceImpl:918 - 预约单号为HB201909100070
2019-10-14 16:02:54.314 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] ERROR com.chtwm.insurance.natives.provider.util.BusUtil:144 - 转换出错,参数为8
2019-10-14 16:02:54.314 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] INFO  c.c.i.n.p.s.impl.InsOffshoreinsPolicyServiceImpl:1030 - 开始同步承保相关修改字段...
2019-10-14 16:02:54.338 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] INFO  c.c.i.n.p.s.impl.InsOffshoreinsPolicyServiceImpl:1041 - 同步承保相关修改字段成功
2019-10-14 16:02:54.338 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] INFO  c.c.insurance.natives.provider.logAspect.LogAspect:160 - 正在调用【interface com.chtwm.insurance.natives.api.service.InsOffshoreinsPolicyService】服务,方法名为【queryReservationDetails】,入参为["HB201909100070"]
2019-10-14 16:02:54.339 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] INFO  com.common.aspect.Aspect:33 - InsOffshorePolicyDetailsVO com.chtwm.insurance.natives.provider.service.impl.InsOffshoreinsPolicyServiceImpl.queryReservationDetails(String) 调用时间:2019-10-14 16:02:54
2019-10-14 16:02:54.348 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] INFO  com.common.aspect.Aspect:38 - InsOffshorePolicyDetailsVO com.chtwm.insurance.natives.provider.service.impl.InsOffshoreinsPolicyServiceImpl.queryReservationDetails(String) 执行时间:9ms
2019-10-14 16:02:54.349 TID: N/A [Thread-6] INFO  com.common.aspect.Aspect:43 - InsOffshorePolicyDetailsVO com.chtwm.insurance.natives.provider.service.impl.InsOffshoreinsPolicyServiceImpl.queryReservationDetails(String) 方法入参[{"String":"HB201909100070"}]
2019-10-14 16:02:54.362 TID: N/A [pool-3-thread-1] INFO  c.chtwm.insurance.natives.provider.util.ExcuteTask:71 - ======================日志记录开始=============================
2019-10-14 16:02:54.438 TID: N/A [pool-3-thread-1] INFO  c.chtwm.insurance.natives.provider.util.ExcuteTask:72 - 开始执行日志批次新增任务,参数为{"changeType":2,"createId":"H025004","createName":"刘佩鑫","newObject":{"insOffshoreinsPolicyVO":{"accompanyingConsultant":"dddfa","approvalDate":1563811200000,"createId":"H000000","createName":"初始化用户","deadlineDate":1563811200000,"empCode":"H000000","empName":"初始化用户","id":14502,"insuranceNo":"225553","isCode":"liujaijai","isName":"liujiajia","mainEmpDeptCode":"03500198","mainEmpDeptName":"北京管理中心直营部","mainEmpDivisionCode":"035951","mainEmpDivisionName":"北京直属事业部","mainEmpRegionCode":"035051","mainEmpRegionName":"北京财富管理事业群","policyDate":1563811200000,"productCode":"I0000004","reservationNo":"HB201909100070","reservationStatus":8,"reserveSignDate":3000,"serviceRemark":"test","telNum":"18551053537","totalPeople":3,"updateId":"H017178","updateName":"王映轩"},"insuredEntityVO":{"accessIdNo":"214321","accessIdType":1,"birthday":-28800000,"channelId":"10002","companyDetailAddress":"湖北省武汉市花山软件新城","companyPhone":"3432432-3423","costPerMonth":13999.00,"createId":"H000000","createName":"初始化用户","createTime":1568093773000,"detailAddress":"湖北省吴航食","email":"ljjlovely123@163.com","englishName":"liujiaji","height":58.0,"id":16052,"identityDetailAddress":"湖北省武汉市","identityNo":"41032219920331341","identityType":2,"incomePerMonth":9000.00,"isDebt":0,"isDelete":0,"maritalStatus":1,"name":"刘沛鑫","nationality":242,"phone":"1855103536","position":"软件开发","relation":1,"reservationId":"HB201909100070","sex":1,"smokingHabit":0,"totalAmountOfCurrentAsset":413124.00,"updateId":"H000000","updateName":"初始化用户","updateTime":1569489619000,"workAddress":"伟创科技","workAge":13,"zipCode":"28347"},"insurerEntity":{"accessIdType":1,"businessNature":"外包","channelId":10002,"companyDetailAddress":"湖北省武汉市花山软件新城","companyPhone":"3432432-3423","costPerMonth":13999.00,"customerName":"刘沛鑫","customerNo":32321,"education":1,"email":"ljjlovely123@163.com","englishName":"liujiaji","haveDrivingLicense":0,"height":58.00,"id":16902,"identityDetailAddress":"湖北省武汉市","identityNo":"41032219920331341","identityType":2,"incomePerMonth":9000.00,"insBirthday":-28800000,"isDebt":0,"isSelfInsurance":0,"maritalStatus":1,"mobileInternet":"1855103536","nationality":213,"passNumber":"3423424","phone":"1855103536","position":"软件开发","relation":1,"reservationId":"HB201909100070","sex":1,"smokingHabit":0,"totalAmountOfCurrentAsset":413124.00,"workAddress":"伟创科技","workAge":13},"policyProductRelation":{"channelName":"中国恒兆保险有限公司","combinationCode":"dfaf","createId":"H000000","createName":"初始化用户","currency":2,"firstPayWay":"1","id":15952,"insuranceCode":"I0000004","insuranceCompany":"皮包公司","insuranceName":"bape","isEffectiveInAdvance":1,"otherInstructions":"dd","paymentDate":1,"paymentDateType":2,"paymentPeriod":"1","policyAmount":3424.0,"policyCharge":4343.0,"productRate":0.00,"reservationAmount":22.0,"reservationCharge":22.0,"reservationId":"HB201909100070","safeguardDate":2,"shareOfProfit":3,"updateId":"H000000","updateName":"初始化用户"}},"oldObject":{"insOffshoreinsPolicyVO":{"accompanyingConsultant":"dddfa","approvalDate":1563811200000,"createId":"H000000","createName":"初始化用户","deadlineDate":1563811200000,"empCode":"H000000","empName":"初始化用户","id":14502,"insuranceNo":"225553","isCode":"liujaijai","isName":"liujiajia","mainEmpDeptCode":"03500198","mainEmpDeptName":"北京管理中心直营部","mainEmpDivisionCode":"035951","mainEmpDivisionName":"北京直属事业部","mainEmpRegionCode":"035051","mainEmpRegionName":"北京财富管理事业群","policyDate":1563811200000,"productCode":"I0000004","reservationNo":"HB201909100070","reservationStatus":6,"reserveSignDate":3000,"serviceRemark":"test","telNum":"18551053537","totalPeople":3,"updateId":"H017178","updateName":"王映轩"},"insuredEntityVO":{"accessIdNo":"214321","accessIdType":1,"birthday":-28800000,"channelId":"10002","companyDetailAddress":"湖北省武汉市花山软件新城","companyPhone":"3432432-3423","costPerMonth":13999.00,"createId":"H000000","createName":"初始化用户","createTime":1568093773000,"detailAddress":"湖北省吴航食","email":"ljjlovely123@163.com","englishName":"liujiaji","height":58.0,"id":16052,"identityDetailAddress":"湖北省武汉市","identityNo":"41032219920331341","identityType":2,"incomePerMonth":9000.00,"isDebt":0,"isDelete":0,"maritalStatus":1,"name":"刘沛鑫","nationality":242,"phone":"1855103536","position":"软件开发","relation":1,"reservationId":"HB201909100070","sex":1,"smokingHabit":0,"totalAmountOfCurrentAsset":413124.00,"updateId":"H000000","updateName":"初始化用户","updateTime":1569489619000,"workAddress":"伟创科技","workAge":13,"zipCode":"28347"},"insurerEntity":{"accessIdType":1,"businessNature":"外包","channelId":10002,"companyDetailAddress":"湖北省武汉市花山软件新城","companyPhone":"3432432-3423","costPerMonth":13999.00,"customerName":"刘沛鑫","customerNo":32321,"education":1,"email":"ljjlovely123@163.com","englishName":"liujiaji","haveDrivingLicense":0,"height":58.00,"id":16902,"identityDetailAddress":"湖北省武汉市","identityNo":"41032219920331341","identityType":2,"incomePerMonth":9000.00,"insBirthday":-28800000,"isDebt":0,"isSelfInsurance":0,"maritalStatus":1,"mobileInternet":"1855103536","nationality":213,"passNumber":"3423424","phone":"1855103536","position":"软件开发","relation":1,"reservationId":"HB201909100070","sex":1,"smokingHabit":0,"totalAmountOfCurrentAsset":413124.00,"workAddress":"伟创科技","workAge":13},"policyProductRelation":{"channelName":"中国恒兆保险有限公司","combinationCode":"dfaf","createId":"H000000","createName":"初始化用户","currency":2,"firstPayWay":"1","id":15952,"insuranceCode":"I0000004","insuranceCompany":"皮包公司","insuranceName":"bape","isEffectiveInAdvance":1,"otherInstructions":"dd","paymentDate":1,"paymentDateType":2,"paymentPeriod":"1","policyAmount":3424.0,"policyCharge":4343.0,"productRate":0.00,"reservationAmount":22.0,"reservationCharge":22.0,"reservationId":"HB201909100070","safeguardDate":2,"shareOfProfit":3,"updateId":"H000000","updateName":"初始化用户"}}}
2019-10-14 16:02:54.446 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【保单号】======================= 新值【225553】 ===================== 旧值【225553】
2019-10-14 16:02:54.446 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【实缴金额】======================= 新值【null】 ===================== 旧值【null】
2019-10-14 16:02:54.446 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【预约签单日期】======================= 新值【Thu Jan 01 08:00:03 CST 1970】 ===================== 旧值【Thu Jan 01 08:00:03 CST 1970】
2019-10-14 16:02:54.446 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【预约赴港人数】======================= 新值【3】 ===================== 旧值【3】
2019-10-14 16:02:54.446 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【陪同顾问】======================= 新值【dddfa】 ===================== 旧值【dddfa】
2019-10-14 16:02:54.447 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【手机号码】======================= 新值【18551053537】 ===================== 旧值【18551053537】
2019-10-14 16:02:54.447 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【IS姓名】======================= 新值【liujiajia】 ===================== 旧值【liujiajia】
2019-10-14 16:02:54.447 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【IS工号】======================= 新值【liujaijai】 ===================== 旧值【liujaijai】
2019-10-14 16:02:54.447 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【预约服务备注】======================= 新值【test】 ===================== 旧值【test】
2019-10-14 16:02:54.447 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【预约理顾工号】======================= 新值【H000000】 ===================== 旧值【H000000】
2019-10-14 16:02:54.447 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【预约理顾姓名】======================= 新值【初始化用户】 ===================== 旧值【初始化用户】
2019-10-14 16:02:54.447 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【事业群名称】======================= 新值【北京财富管理事业群】 ===================== 旧值【北京财富管理事业群】
2019-10-14 16:02:54.447 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【事业群编号】======================= 新值【035051】 ===================== 旧值【035051】
2019-10-14 16:02:54.451 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【营业部名称】======================= 新值【北京管理中心直营部】 ===================== 旧值【北京管理中心直营部】
2019-10-14 16:02:54.451 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【营业部编号】======================= 新值【03500198】 ===================== 旧值【03500198】
2019-10-14 16:02:54.451 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【事业部名称】======================= 新值【北京直属事业部】 ===================== 旧值【北京直属事业部】
2019-10-14 16:02:54.451 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【事业部编号】======================= 新值【035951】 ===================== 旧值【035951】
2019-10-14 16:02:54.451 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【预约状态】======================= 新值【8】 ===================== 旧值【6】
2019-10-14 16:02:54.466 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【保单生效日期】======================= 新值【Tue Jul 23 00:00:00 CST 2019】 ===================== 旧值【Tue Jul 23 00:00:00 CST 2019】
2019-10-14 16:02:54.467 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【冷静期截止日期】======================= 新值【Tue Jul 23 00:00:00 CST 2019】 ===================== 旧值【Tue Jul 23 00:00:00 CST 2019】
2019-10-14 16:02:54.467 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【批核日期】======================= 新值【Tue Jul 23 00:00:00 CST 2019】 ===================== 旧值【Tue Jul 23 00:00:00 CST 2019】
2019-10-14 16:02:54.467 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【险种类型】======================= 新值【null】 ===================== 旧值【null】
2019-10-14 16:02:54.467 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【产品名称】======================= 新值【bape】 ===================== 旧值【bape】
2019-10-14 16:02:54.467 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【保险公司名称】======================= 新值【皮包公司】 ===================== 旧值【皮包公司】
2019-10-14 16:02:54.467 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【合作渠道】======================= 新值【中国恒兆保险有限公司】 ===================== 旧值【中国恒兆保险有限公司】
2019-10-14 16:02:54.467 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【缴费期限类型】======================= 新值【2】 ===================== 旧值【2】
2019-10-14 16:02:54.467 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【缴费期限】======================= 新值【1】 ===================== 旧值【1】
2019-10-14 16:02:54.468 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【保险金额】======================= 新值【3424.0】 ===================== 旧值【3424.0】
2019-10-14 16:02:54.468 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【年缴保费】======================= 新值【4343.0】 ===================== 旧值【4343.0】
2019-10-14 16:02:54.468 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【保单币种】======================= 新值【2】 ===================== 旧值【2】
2019-10-14 16:02:54.468 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【红利分配方式】======================= 新值【3】 ===================== 旧值【3】
2019-10-14 16:02:54.471 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【保单是否提前生效】======================= 新值【1】 ===================== 旧值【1】
2019-10-14 16:02:54.471 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【其他说明】======================= 新值【dd】 ===================== 旧值【dd】
2019-10-14 16:02:54.472 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【渠道id】======================= 新值【null】 ===================== 旧值【null】
2019-10-14 16:02:54.472 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【缴费期别】======================= 新值【1】 ===================== 旧值【1】
2019-10-14 16:02:54.472 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【首期保费缴付方法】======================= 新值【1】 ===================== 旧值【1】
2019-10-14 16:02:54.472 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【年龄】======================= 新值【null】 ===================== 旧值【null】
2019-10-14 16:02:54.472 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人身高】======================= 新值【58.00】 ===================== 旧值【58.00】
2019-10-14 16:02:54.472 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人体重】======================= 新值【null】 ===================== 旧值【null】
2019-10-14 16:02:54.472 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人通行证号码】======================= 新值【3423424】 ===================== 旧值【3423424】
2019-10-14 16:02:54.472 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人身份证详细地址】======================= 新值【湖北省武汉市】 ===================== 旧值【湖北省武汉市】
2019-10-14 16:02:54.472 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人电话】======================= 新值【1855103536】 ===================== 旧值【1855103536】
2019-10-14 16:02:54.473 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人业务性质】======================= 新值【外包】 ===================== 旧值【外包】
2019-10-14 16:02:54.473 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人工作单位/就读学校】======================= 新值【伟创科技】 ===================== 旧值【伟创科技】
2019-10-14 16:02:54.473 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人职务】======================= 新值【软件开发】 ===================== 旧值【软件开发】
2019-10-14 16:02:54.473 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人公司详细地址】======================= 新值【湖北省武汉市花山软件新城】 ===================== 旧值【湖北省武汉市花山软件新城】
2019-10-14 16:02:54.473 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人通讯地址详细地址】======================= 新值【null】 ===================== 旧值【null】
2019-10-14 16:02:54.473 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人与被保人关系】======================= 新值【1】 ===================== 旧值【1】
2019-10-14 16:02:54.473 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人客户姓名】======================= 新值【刘沛鑫】 ===================== 旧值【刘沛鑫】
2019-10-14 16:02:54.473 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人性别】======================= 新值【1】 ===================== 旧值【1】
2019-10-14 16:02:54.473 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人出生日期】======================= 新值【Thu Jan 01 00:00:00 CST 1970】 ===================== 旧值【Thu Jan 01 00:00:00 CST 1970】
2019-10-14 16:02:54.474 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人婚姻状况】======================= 新值【1】 ===================== 旧值【1】
2019-10-14 16:02:54.474 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人国籍】======================= 新值【213】 ===================== 旧值【213】
2019-10-14 16:02:54.474 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人证件类型】======================= 新值【2】 ===================== 旧值【2】
2019-10-14 16:02:54.474 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人证件号码】======================= 新值【41032219920331341】 ===================== 旧值【41032219920331341】
2019-10-14 16:02:54.474 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人学历】======================= 新值【1】 ===================== 旧值【1】
2019-10-14 16:02:54.476 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人手机】======================= 新值【1855103536】 ===================== 旧值【1855103536】
2019-10-14 16:02:54.476 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人邮箱】======================= 新值【ljjlovely123@163.com】 ===================== 旧值【ljjlovely123@163.com】
2019-10-14 16:02:54.476 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人邮编】======================= 新值【null】 ===================== 旧值【null】
2019-10-14 16:02:54.476 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人英文姓名】======================= 新值【liujiaji】 ===================== 旧值【liujiaji】
2019-10-14 16:02:54.476 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人通行证号】======================= 新值【null】 ===================== 旧值【null】
2019-10-14 16:02:54.476 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人入港证件类型】======================= 新值【1】 ===================== 旧值【1】
2019-10-14 16:02:54.476 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人公司电话】======================= 新值【3432432-3423】 ===================== 旧值【3432432-3423】
2019-10-14 16:02:54.476 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人现时工作年期】======================= 新值【13】 ===================== 旧值【13】
2019-10-14 16:02:54.476 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人现时每月收入】======================= 新值【9000.00】 ===================== 旧值【9000.00】
2019-10-14 16:02:54.476 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人现时每月支出】======================= 新值【13999.00】 ===================== 旧值【13999.00】
2019-10-14 16:02:54.476 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【投保人流动资产总金额】======================= 新值【413124.00】 ===================== 旧值【413124.00】
2019-10-14 16:02:54.477 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人姓名】======================= 新值【刘沛鑫】 ===================== 旧值【刘沛鑫】
2019-10-14 16:02:54.477 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人性别】======================= 新值【1】 ===================== 旧值【1】
2019-10-14 16:02:54.477 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人出生日期】======================= 新值【Thu Jan 01 00:00:00 CST 1970】 ===================== 旧值【Thu Jan 01 00:00:00 CST 1970】
2019-10-14 16:02:54.477 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人与投保人关系】======================= 新值【1】 ===================== 旧值【1】
2019-10-14 16:02:54.477 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人婚姻状况】======================= 新值【1】 ===================== 旧值【1】
2019-10-14 16:02:54.477 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人身高】======================= 新值【58.0】 ===================== 旧值【58.0】
2019-10-14 16:02:54.477 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人体重】======================= 新值【null】 ===================== 旧值【null】
2019-10-14 16:02:54.477 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人国籍】======================= 新值【242】 ===================== 旧值【242】
2019-10-14 16:02:54.477 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人证件类型】======================= 新值【2】 ===================== 旧值【2】
2019-10-14 16:02:54.477 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人证件号码】======================= 新值【41032219920331341】 ===================== 旧值【41032219920331341】
2019-10-14 16:02:54.477 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人身份证地址详细地址】======================= 新值【湖北省武汉市】 ===================== 旧值【湖北省武汉市】
2019-10-14 16:02:54.478 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人学历】======================= 新值【null】 ===================== 旧值【null】
2019-10-14 16:02:54.478 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人手机号码】======================= 新值【null】 ===================== 旧值【null】
2019-10-14 16:02:54.478 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人E-mail】======================= 新值【ljjlovely123@163.com】 ===================== 旧值【ljjlovely123@163.com】
2019-10-14 16:02:54.479 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人工作单位/就读学校】======================= 新值【伟创科技】 ===================== 旧值【伟创科技】
2019-10-14 16:02:54.479 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人职业】======================= 新值【null】 ===================== 旧值【null】
2019-10-14 16:02:54.479 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人职务】======================= 新值【软件开发】 ===================== 旧值【软件开发】
2019-10-14 16:02:54.479 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人公司地址详细地址】======================= 新值【湖北省武汉市花山软件新城】 ===================== 旧值【湖北省武汉市花山软件新城】
2019-10-14 16:02:54.479 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人通讯地址详细地址】======================= 新值【湖北省吴航食】 ===================== 旧值【湖北省吴航食】
2019-10-14 16:02:54.479 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人邮编】======================= 新值【28347】 ===================== 旧值【28347】
2019-10-14 16:02:54.479 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人英文姓名】======================= 新值【liujiaji】 ===================== 旧值【liujiaji】
2019-10-14 16:02:54.480 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人通行证号】======================= 新值【214321】 ===================== 旧值【214321】
2019-10-14 16:02:54.480 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人入港证件类型】======================= 新值【1】 ===================== 旧值【1】
2019-10-14 16:02:54.480 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人住宅电话】======================= 新值【1855103536】 ===================== 旧值【1855103536】
2019-10-14 16:02:54.480 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人公司电话】======================= 新值【3432432-3423】 ===================== 旧值【3432432-3423】
2019-10-14 16:02:54.480 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人现时工作年期】======================= 新值【13】 ===================== 旧值【13】
2019-10-14 16:02:54.480 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人现时每月收入】======================= 新值【9000.00】 ===================== 旧值【9000.00】
2019-10-14 16:02:54.482 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人现时每月支出】======================= 新值【13999.00】 ===================== 旧值【13999.00】
2019-10-14 16:02:54.482 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人流动资产总金额】======================= 新值【413124.00】 ===================== 旧值【413124.00】
2019-10-14 16:02:54.482 TID: N/A [pool-3-thread-1] INFO  com.chtwm.insurance.natives.provider.util.BusUtil:317 - 比对字段名称【被保人公司业务性质】======================= 新值【null】 ===================== 旧值【null】
2019-10-14 16:02:54.501 TID: N/A [pool-3-thread-1] INFO  c.chtwm.insurance.natives.provider.util.ExcuteTask:153 - 新增批次成功
2019-10-14 16:02:54.512 TID: N/A [pool-3-thread-1] INFO  c.chtwm.insurance.natives.provider.util.ExcuteTask:198 - 批量新增日志操作详情成功
2019-10-14 16:02:54.519 TID: N/A [pool-3-thread-1] INFO  c.chtwm.insurance.natives.provider.util.ExcuteTask:109 - ======================日志记录结束=============================
2019-10-14 16:02:54.523 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] INFO  com.common.aspect.Aspect:38 - Result com.chtwm.insurance.natives.provider.service.impl.InsOffshoreinsPolicyServiceImpl.aloneUpdateUnderMod(String,UnderModIimportParam,Map,ExcelResult,Map,Emp) 执行时间:344ms
2019-10-14 16:02:54.523 TID: N/A [DubboServerHandler-192.168.50.206:20993-thread-6] INFO  com.common.aspect.Aspect:38 - ExcelResult com.chtwm.insurance.natives.provider.service.impl.InsOffshoreinsPolicyServiceImpl.updateUnderMod(ExcelResult,Emp) 执行时间:576ms
2019-10-14 16:02:54.530 TID: N/A [Thread-8] INFO  com.common.aspect.Aspect:43 - ExcelResult com.chtwm.insurance.natives.provider.service.impl.InsOffshoreinsPolicyServiceImpl.updateUnderMod(ExcelResult,Emp) 方法入参[{"result":[{"policyId":"225553","row":2,"status":"8"}],"success":true,"importCount":1,"message":"导入成功"}, {"deptName":"恒天财富投资管理股份有限公司北京恒天明泽基金销售有限公司各大区浙江财富管理事业部杭州第十五营业部杭州第十五营业部理财2部","leader":"H000112","lastEducation":"大学专科","psnType":"合同制员工","trnsevent":"1","updateId":"system","password":"E10ADC3949BA59ABBE56E057F20F883E","mp":"理财顾问","degreeName":"无学位","pkOrg":"北京恒天明泽基金销售有限公司","createId":"system","name":"刘佩鑫","postCode":"P0012371","creanTime":1524585600000,"deptCode":"0350101602","joinworkDate":1252512000000,"code":"H025004","orgCode":"03","postName":"理财顾问","email":"yuanxiaoke@chtwm.com","seq":"03","cnType":0,"enableState":"在职","sex":"1","mobile":"13123704282","updateTime":1541051863000,"cn":"330227197912074774","birthDate":313344000000,"superior":"H013095","createTime":1541051863000,"isPass":"Y","age":"38","ts":1524672329000}]
2019-10-14 16:02:54.540 TID: N/A [Thread-7] INFO  com.common.aspect.Aspect:43 - Result com.chtwm.insurance.natives.provider.service.impl.InsOffshoreinsPolicyServiceImpl.aloneUpdateUnderMod(String,UnderModIimportParam,Map,ExcelResult,Map,Emp) 方法入参[{"String":"HB201909100070"}, {"policyId":"225553","row":2,"status":"8"}, {"HashMap":[{"resreservationId":"HB201909100070","insOffshoreinsPolicyEntity":{"approvalDate":1563811200000,"auditDate":1568803662000,"createId":"H000000","createName":"初始化用户","createTime":1571024053000,"deadlineDate":1563811200000,"empCode":"H000000","empDeptCode":"03500198","empDeptName":"北京管理中心直营部","empDivisionCode":"035951","empDivisionName":"北京直属事业部","empName":"初始化用户","empRegionCode":"035051","empRegionName":"北京财富管理事业群","id":14502,"insureDate":1568100835000,"isCode":"liujaijai","isCompany":"dddfa","isDelete":0,"isName":"liujiajia","mobile":"18551053537","policyDate":1563811200000,"policyId":"225553","productCode":"I0000004","reservationCheckComment":"11","reservationId":"HB201909100070","reserveSignDate":3000,"serviceRemark":"test","status":6,"toHkNum":3,"updateId":"H017178","updateName":"王映轩","updateTime":1571024053000}}]}, {"result":[{"policyId":"225553","row":2,"status":"8"}],"success":true,"importCount":1,"message":"导入成功"}, {"HashMap":[]}, {"deptName":"恒天财富投资管理股份有限公司北京恒天明泽基金销售有限公司各大区浙江财富管理事业部杭州第十五营业部杭州第十五营业部理财2部","leader":"H000112","lastEducation":"大学专科","psnType":"合同制员工","trnsevent":"1","updateId":"system","password":"E10ADC3949BA59ABBE56E057F20F883E","mp":"理财顾问","degreeName":"无学位","pkOrg":"北京恒天明泽基金销售有限公司","createId":"system","name":"刘佩鑫","postCode":"P0012371","creanTime":1524585600000,"deptCode":"0350101602","joinworkDate":1252512000000,"code":"H025004","orgCode":"03","postName":"理财顾问","email":"yuanxiaoke@chtwm.com","seq":"03","cnType":0,"enableState":"在职","sex":"1","mobile":"13123704282","updateTime":1541051863000,"cn":"330227197912074774","birthDate":313344000000,"superior":"H013095","createTime":1541051863000,"isPass":"Y","age":"38","ts":1524672329000}]

生成的批次记录如下

在这里插入图片描述
在这里插入图片描述

到此结束(●ˇ∀ˇ●)

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值