diff --git a/build.gradle b/build.gradle
index d572218..c946c29 100644
--- a/build.gradle
+++ b/build.gradle
@@ -83,7 +83,6 @@
     implementation group: 'taglibs', name: 'standard', version: '1.1.2'
     implementation group: 'commons-codec', name: 'commons-codec', version: '1.6'
     implementation 'org.apache.commons:commons-lang3:3.9'
-    implementation group: 'log4j', name: 'log4j', version: '1.2.16'
     implementation files('libs/ojdbc6.jar')
 
 
diff --git a/src/main/java/com/supwisdom/dlpay/framework/core/DayendSettleTask.java b/src/main/java/com/supwisdom/dlpay/framework/core/DayendSettleTask.java
deleted file mode 100644
index 313b5aa..0000000
--- a/src/main/java/com/supwisdom/dlpay/framework/core/DayendSettleTask.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package com.supwisdom.dlpay.framework.core;
-
-import com.supwisdom.dlpay.framework.domain.TSettleLog;
-import com.supwisdom.dlpay.framework.domain.TTaskLock;
-import com.supwisdom.dlpay.framework.service.DayendSettleService;
-import com.supwisdom.dlpay.framework.service.SystemUtilService;
-import com.supwisdom.dlpay.framework.util.StringUtil;
-import org.apache.log4j.Logger;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public class DayendSettleTask {
-  @Autowired
-  private SystemUtilService systemUtilService;
-  @Autowired
-  private DayendSettleService dayendSettleService;
-
-  private TSettleLog settleLog;
-
-  private static final Logger logger = Logger.getLogger(DayendSettleTask.class);
-
-
-  public void doSettleTask() {
-    if (logger.isDebugEnabled()) logger.debug("进入日结算任务！");
-
-    TTaskLock lock = null;
-    try {
-      try {
-        lock = systemUtilService.doLockTask("DAYENDSETTLETASK", 30, "日终结算");
-        if (lock == null) {
-          if (logger.isDebugEnabled()) logger.debug("日终结算正在其他服务器上执行");
-          return;
-        }
-      } catch (Exception e) {
-        return;
-      }
-
-      settleLog = dayendSettleService.doCreateSettleLog(); //记录日志
-
-      //step1: 账户校验
-      long t1 = System.currentTimeMillis();
-      if (!checkAccounts()) {
-        logger.error("账户余额校验出错，退出结算！");
-        return;
-      }
-      long t2 = System.currentTimeMillis();
-      logger.info("===== step1: 日终结算【账户校验】耗时 " + (t2 - t1) + " ms");
-
-      //step2: 对账判断
-      long t3 = System.currentTimeMillis();
-      if(!checkChkfiles()){
-        logger.error("对账未完成，退出结算！");
-        return;
-      }
-      long t4 = System.currentTimeMillis();
-      logger.info("===== step2: 日终结算【对账判断】耗时 " + (t4 - t3) + " ms");
-
-      //step3: 日结
-      long t5 = System.currentTimeMillis();
-      if (!doSettleProcess()) {
-        logger.error("日结出错：" + settleLog.getErrmsg());
-        return;
-      }
-      long t6 = System.currentTimeMillis();
-      logger.info("===== step3: 日终结算【日结】耗时 " + (t6 - t5) + " ms");
-
-
-    } catch (Exception e) {
-      logger.error("日终结算报错：" + (!StringUtil.isEmpty(e.getMessage()) ? e.getMessage() : e.getClass().getName()));
-      e.printStackTrace();
-    } finally {
-      if (null != lock) {
-        lock.setTaskstatus(0);
-        lock.setTasktime(systemUtilService.getSysdatetime().getHostdatetime());
-        systemUtilService.updateTaskLock(lock);
-      }
-    }
-  }
-
-  private boolean checkAccounts(){
-    //TODO: 账户余额校验，生成账户日结表数据
-    return true;
-  }
-
-  private boolean checkChkfiles(){
-    //TODO: 结算前是否要求所有对账完成
-    return true;
-  }
-
-  private boolean doSettleProcess() {
-    try {
-      boolean ret = dayendSettleService.doDayendSettle();
-      if (ret) {
-        dayendSettleService.doUpdateSettleLog(settleLog.update("0", "成功结算"));
-      }
-      return ret;
-    } catch (Exception e) {
-      if (!StringUtil.isEmpty(e.getMessage())) {
-        dayendSettleService.doUpdateSettleLog(settleLog.update("-9", e.getMessage()));
-      } else {
-        e.printStackTrace();
-        dayendSettleService.doUpdateSettleLog(settleLog.update("-8", e.getClass().getName()));
-      }
-      return false;
-    }
-  }
-}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/service/DayendSettleService.java b/src/main/java/com/supwisdom/dlpay/framework/service/DayendSettleService.java
deleted file mode 100644
index d3318f0..0000000
--- a/src/main/java/com/supwisdom/dlpay/framework/service/DayendSettleService.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.supwisdom.dlpay.framework.service;
-
-import com.supwisdom.dlpay.framework.domain.TSettleLog;
-import org.springframework.transaction.annotation.Propagation;
-import org.springframework.transaction.annotation.Transactional;
-
-/**
- * 日终结算
- * */
-public interface DayendSettleService {
-  TSettleLog doCreateSettleLog();
-  TSettleLog doUpdateSettleLog(TSettleLog log);
-
-  @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
-  boolean doDayendSettle() throws Exception; //日结
-
-  @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
-  boolean doVoucherSettle(String voucherid) throws Exception; //指定凭证入账
-}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/service/impl/DayendSettleServiceImpl.java b/src/main/java/com/supwisdom/dlpay/framework/service/impl/DayendSettleServiceImpl.java
deleted file mode 100644
index cbb0805..0000000
--- a/src/main/java/com/supwisdom/dlpay/framework/service/impl/DayendSettleServiceImpl.java
+++ /dev/null
@@ -1,544 +0,0 @@
-package com.supwisdom.dlpay.framework.service.impl;
-
-import com.supwisdom.dlpay.api.dao.DebitCreditDtlDao;
-import com.supwisdom.dlpay.framework.dao.*;
-import com.supwisdom.dlpay.framework.data.*;
-import com.supwisdom.dlpay.framework.domain.*;
-import com.supwisdom.dlpay.framework.service.DayendSettleService;
-import com.supwisdom.dlpay.framework.service.SystemUtilService;
-import com.supwisdom.dlpay.framework.util.*;
-import org.apache.log4j.Logger;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-@Service
-public class DayendSettleServiceImpl implements DayendSettleService {
-  @Autowired
-  private SystemUtilService systemUtilService;
-  @Autowired
-  private SettleLogDao settleLogDao;
-  @Autowired
-  private SettleCtlDao settleCtlDao;
-  @Autowired
-  private PeriodDao periodDao;
-  @Autowired
-  private VouchernoCtlDao vouchernoCtlDao;
-  @Autowired
-  private ShopaccDao shopaccDao;
-  @Autowired
-  private ShopaccbalDao shopaccbalDao;
-  @Autowired
-  private SubjectDao subjectDao;
-  @Autowired
-  private SubjectbalDao subjectbalDao;
-  @Autowired
-  private VoucherDao voucherDao;
-  @Autowired
-  private VoucherEntryDao voucherEntryDao;
-
-  @Autowired
-  private ShopaccdayDao shopaccdayDao;
-  @Autowired
-  private SubjectdayDao subjectdayDao;
-  @Autowired
-  private DebitCreditDtlDao debitCreditDtlDao;
-
-
-  private static final Logger logger = Logger.getLogger(DayendSettleServiceImpl.class);
-
-  private int hostdate;
-  private int periodYear; // 记账年份
-  private int periodMonth; // 记账月份
-  private int settledate; //结算日期
-  private int lastsettday; //结算前一天
-
-  @Override
-  public TSettleLog doCreateSettleLog() {
-    TSettleLog log = new TSettleLog();
-    log.setStarttime(systemUtilService.getSysdatetime().getHostdatetime());
-    return settleLogDao.save(log);
-  }
-
-  @Override
-  public TSettleLog doUpdateSettleLog(TSettleLog log) {
-    if (null == log) return null;
-    log.setEndtime(systemUtilService.getSysdatetime().getHostdatetime());
-    return settleLogDao.save(log);
-  }
-
-  private boolean doSwitchPeriod() throws Exception {
-    TPeriod period = periodDao.getTPeriodWithLock(periodYear, periodMonth);
-    if (period.getSettleflag() == 1) {
-      throw new Exception("月末结转已完成");
-    }
-    period.setSettleflag(1);
-    periodDao.save(period); //已结
-
-    if (periodMonth >= 12) {
-      periodMonth = 1;
-      periodYear = periodYear + 1; //年份加一
-    } else {
-      periodMonth = periodMonth + 1; //year不变
-    }
-
-    TPeriod nextPerid = periodDao.getPeriod(periodYear, periodMonth);
-    if (null != nextPerid) {
-      if (settledate != Integer.valueOf(nextPerid.getStartdate())) {
-        throw new Exception("下一个会计期间的开始日期不正确");
-      } else if (nextPerid.getSettleflag() == 1) {
-        throw new Exception("下一个会计期间的月末结转已完成");
-      }
-    } else {
-      Integer startdate = periodYear * 10000 + periodMonth * 100 + 1;
-      Integer enddate = DateUtil.getLastDayOfMonth(periodYear, periodMonth);
-      if (settledate != startdate) {
-        throw new Exception("下一个会计期间的开始日期不正确");
-      }
-      nextPerid = new TPeriod();
-      nextPerid.setPeriodYear(periodYear);
-      nextPerid.setPeriodMonth(periodMonth);
-      nextPerid.setStartdate(startdate.toString());
-      nextPerid.setEnddate(enddate.toString());
-      nextPerid.setSettleflag(0);
-      periodDao.save(nextPerid); //保存下个会计期间
-    }
-
-    settleCtlDao.updateSettlePeriod(periodYear, periodMonth);
-    vouchernoCtlDao.updateVoucherno(periodMonth, 0);
-    return true;
-  }
-
-  private void saveVoucher(VoucherTemp voucherTemp) {
-    TVoucher voucher = new TVoucher(periodYear, periodMonth, 0, settledate, settledate, voucherTemp.getTranscnt(), Math.abs(voucherTemp.getTransamt()), voucherTemp.getSummary(), "auto", hostdate);
-    voucher = voucherDao.save(voucher);
-    TVoucherEntry entry1;
-    TVoucherEntry entry2;
-    if (voucherTemp.getTransamt() >= 0) {
-      entry1 = new TVoucherEntry(voucher.getVoucherid(), 1, voucherTemp.getDrsubjno(), null, Math.abs(voucherTemp.getTransamt()), 0D, voucherTemp.getSummary(), voucherTemp.getCrsubjno(), null);
-      entry2 = new TVoucherEntry(voucher.getVoucherid(), 2, voucherTemp.getCrsubjno(), null, 0D, Math.abs(voucherTemp.getTransamt()), voucherTemp.getSummary(), voucherTemp.getDrsubjno(), null);
-    } else {
-      entry1 = new TVoucherEntry(voucher.getVoucherid(), 1, voucherTemp.getCrsubjno(), null, 0D, Math.abs(voucherTemp.getTransamt()), voucherTemp.getSummary(), voucherTemp.getDrsubjno(), null);
-      entry2 = new TVoucherEntry(voucher.getVoucherid(), 2, voucherTemp.getDrsubjno(), null, Math.abs(voucherTemp.getTransamt()), 0D, voucherTemp.getSummary(), voucherTemp.getCrsubjno(), null);
-    }
-    voucherEntryDao.save(entry1);
-    voucherEntryDao.save(entry2);
-  }
-
-  @Override
-  public boolean doDayendSettle() throws Exception {
-    TSettlectl tSettlectl = settleCtlDao.findByBooksetnoWithLock(1);
-    if (null == tSettlectl || null == tSettlectl.getBooksetno()) {
-      throw new Exception("初始化错误，T_SETTLECTL 无初始化数据");
-    }
-    tSettlectl.setStatus(1); //结算标记
-    settleCtlDao.save(tSettlectl);
-
-    hostdate = Integer.valueOf(systemUtilService.getSysdatetime().getHostdate());
-    periodYear = tSettlectl.getPeriodYear();
-    periodMonth = tSettlectl.getPeriodMonth();
-    settledate = tSettlectl.getSettledate();
-    lastsettday = Integer.valueOf(DateUtil.getNewDay(tSettlectl.getSettledate().toString(), -1));
-
-    if (settledate >= hostdate) {
-      throw new Exception("日终结算已完成");
-    }
-
-    TPeriod period = periodDao.getPeriod(periodYear, periodMonth);
-    if (null == period) throw new Exception("year=[" + periodYear + "],month=[" + periodMonth + "] t_period not find ");
-    if (settledate > Integer.valueOf(period.getEnddate())) {
-      //月切
-      if (!doSwitchPeriod()) {
-        throw new Exception("月切失败");
-      }
-    }
-
-//    //新增商户插入商户余额表
-//    List<String> newShopaccList = shopaccDao.getNewShopacc();
-//    if (!StringUtil.isEmpty(newShopaccList)) {
-//      for (String accno : newShopaccList) {
-//        TShopaccbal shopaccbal = new TShopaccbal(accno);
-//        shopaccbalDao.save(shopaccbal);
-//      }
-//    }
-//    if (shopaccDao.checkSettleShopacc().getExisted() > 0) {
-//      throw new Exception("初始化数据错误:商户余额表数据没有包含所有有效的商户账户余额");
-//    }
-
-    //新增科目插入科目余额表（末级科目）
-    List<String> newEndsubjectList = subjectDao.getNewSubject();
-    if (!StringUtil.isEmpty(newEndsubjectList)) {
-      for (String subjno : newEndsubjectList) {
-        TSubjectbal subjectbal = new TSubjectbal(subjno);
-        subjectbalDao.save(subjectbal);
-      }
-    }
-    if (subjectDao.checkSettleSubject().getExisted() > 0) {
-      throw new Exception("初始化数据错误:科目余额表数据没有包含所有的科目余额");
-    }
-
-    //删除未入账凭证
-    if (voucherDao.checkExistUnpostVouhcer().getExisted() > 0) {
-      voucherEntryDao.deleteUnpostVoucherentry();
-      voucherDao.deleteUnpostVoucher();
-    }
-
-    //用户交易凭证
-    List<VoucherTemp> userList = debitCreditDtlDao.getVoucherData(String.valueOf(settledate));
-    if (!StringUtil.isEmpty(userList)) {
-      for (VoucherTemp temp : userList) {
-        saveVoucher(temp);
-      }
-    }
-
-    //凭证号
-    TVouchernoCtl vouchernoCtl = vouchernoCtlDao.getVoucherno();
-    if (null == vouchernoCtl) {
-      vouchernoCtl = new TVouchernoCtl();
-      vouchernoCtl.setVouchertype(1);
-      vouchernoCtl.setPeriodMonth(periodMonth);
-      vouchernoCtl.setVoucherno(0);
-      vouchernoCtlDao.save(vouchernoCtl);
-    }
-    int voucherno = vouchernoCtl.getVoucherno();
-    List<TVoucher> voucherList = voucherDao.getSettleVouchers();
-    if (!StringUtil.isEmpty(voucherList)) {
-      for (TVoucher voucher : voucherList) {
-        voucherno++;
-        voucher.setVoucherno(voucherno);
-        voucher.setPostflag(1);
-        voucherDao.save(voucher);
-      }
-      vouchernoCtl.setVoucherno(voucherno);
-      vouchernoCtlDao.save(vouchernoCtl);
-    }
-
-//    Map<String, Double> v_merchbaldict = new HashMap<String, Double>(0);
-//    //根据商户昨天日结表生成当天日结表（交易前余额）， 新增商户添加记录（交易前余额为商户余额）
-//    List<TShopaccday> lastShopaccdays = shopaccdayDao.getShopaccdayByAccdate(String.valueOf(lastsettday));
-//    if (!StringUtil.isEmpty(lastShopaccdays)) {
-//      for (TShopaccday lastday : lastShopaccdays) {
-//        TShopaccday today = new TShopaccday(String.valueOf(settledate), lastday.getShopaccno(), periodYear, periodMonth, lastday.getBalance(), 0D, 0D, 0D);
-//        shopaccdayDao.save(today);
-//        v_merchbaldict.put(lastday.getShopaccno(), lastday.getBalance());
-//      }
-//    }
-//    List<TShopaccbal> newShopbals = shopaccbalDao.getUnsettleShopacc(String.valueOf(lastsettday));
-//    if (!StringUtil.isEmpty(newShopbals)) {
-//      for (TShopaccbal newShopbal : newShopbals) {
-//        TShopaccday today = new TShopaccday(String.valueOf(settledate), newShopbal.getShopaccno(), periodYear, periodMonth, newShopbal.getBeginbal(), 0D, 0D, 0D);
-//        shopaccdayDao.save(today);
-//        v_merchbaldict.put(newShopbal.getShopaccno(), newShopbal.getBeginbal());
-//      }
-//    }
-//    List<MerchBean> merchBeanList = voucherDao.getShopVoucherByAccdate(settledate);
-//    if (!StringUtil.isEmpty(merchBeanList)) {
-//      for (MerchBean merch : merchBeanList) {
-//        TShopaccday merchday = shopaccdayDao.getTShopaccdayById(String.valueOf(settledate), merch.getShopaccno());
-//        if (null == merchday) {
-//          throw new Exception("商户余额表无此商户账号[" + merch.getShopaccno() + "]");
-//        }
-//        merchday.setDramt(merch.getDramt() == null ? 0D : merch.getDramt());
-//        merchday.setCramt(merch.getCramt() == null ? 0D : merch.getCramt());
-//        shopaccdayDao.save(merchday);
-//      }
-//    }
-//    shopaccdayDao.updateShopaccdayBalance(String.valueOf(settledate), systemUtilService.getSysdatetime().getHostdatetime()); //批量更新余额,商户日结表生成
-
-    //根据科目昨天日结表生成当天日结表（交易前借贷方余额），新增末级科目插入记录（交易前余额为科目贷方余额）
-    List<TSubjectday> lastSubjectDays = subjectdayDao.getAllByAccdate(String.valueOf(lastsettday));
-    if (!StringUtil.isEmpty(lastSubjectDays)) {
-      for (TSubjectday lastday : lastSubjectDays) {
-        TSubjectday today = new TSubjectday(String.valueOf(settledate), lastday.getSubjno(), periodYear, periodMonth, lastday.getDrbal(), lastday.getCrbal(), 0D, 0D, 0D, 0D);
-        subjectdayDao.save(today);
-      }
-    }
-    List<TSubjectbal> newSubjectBals = subjectbalDao.getUnsettleSubjectbal(String.valueOf(lastsettday));
-    if (!StringUtil.isEmpty(newSubjectBals)) {
-      for (TSubjectbal newSubject : newSubjectBals) {
-        TSubjectday today = new TSubjectday(String.valueOf(settledate), newSubject.getSubjno(), periodYear, periodMonth, newSubject.getBegindrbal(), newSubject.getBegincrbal(), 0D, 0D, 0D, 0D);
-        subjectdayDao.save(today);
-      }
-    }
-    List<String> newFSubjnos = subjectDao.getNewSubjnos(String.valueOf(settledate)); //新增非末级科目
-    if (!StringUtil.isEmpty(newFSubjnos)) {
-      for (String subjno : newFSubjnos) {
-        double beginDrbal = 0;
-        double beginCrbal = 0;
-        MerchBean balInfo = subjectbalDao.getSubjectInfo(subjno); //统计下级所有科目的交易前余额
-        if (null != balInfo) {
-          beginDrbal = (balInfo.getDramt() == null ? 0 : balInfo.getDramt().doubleValue());
-          beginCrbal = (balInfo.getCramt() == null ? 0 : balInfo.getCramt().doubleValue());
-        }
-        TSubjectday today = new TSubjectday(String.valueOf(settledate), subjno, periodYear, periodMonth, beginDrbal, beginCrbal, 0D, 0D, 0D, 0D);
-        subjectdayDao.save(today);
-      }
-    }
-
-    //初始化末级科目期初余额(包含商户科目)
-    Map<String, Double> v_subjbaldict = new HashMap<String, Double>(0);
-    Map<String, Integer> v_subjbalflagdict = new HashMap<String, Integer>(0);
-    List<MerchBean> subjectList = subjectdayDao.getEndSubjectbalInfos(String.valueOf(settledate));
-    if (!StringUtil.isEmpty(subjectList)) {
-      for (MerchBean bean : subjectList) {
-        v_subjbaldict.put(bean.getShopaccno(), MoneyUtil.formatYuan(bean.getDramt() + bean.getCramt()));
-      }
-    }
-
-    List<SubjectInfoBean> subjInfoList = subjectbalDao.getSubjectbalAndFlag();
-    for (SubjectInfoBean subj : subjInfoList) {
-      TSubjectday tSubjectday = subjectdayDao.getSubjectDayById(String.valueOf(settledate), subj.getSubjno());
-      if (null == tSubjectday) {
-        throw new Exception("科目日结表无此科目记录[" + subj.getSubjno() + "]");
-      }
-
-      v_subjbalflagdict.put(subj.getSubjno(), subj.getBalflag());
-      MerchBean suminfo = voucherDao.getSettleSuminfo(settledate, subj.getSubjno());
-      double sumDramt = ((null == suminfo || null == suminfo.getDramt()) ? 0 : suminfo.getDramt().doubleValue());
-      double sumCramt = ((null == suminfo || null == suminfo.getCramt()) ? 0 : suminfo.getCramt().doubleValue());
-      tSubjectday.setDramt(sumDramt);
-      tSubjectday.setCramt(sumCramt);
-      tSubjectday.setUpdtime(systemUtilService.getSysdatetime().getHostdatetime());
-      if (subj.getBalflag() == 1) {
-        tSubjectday.setDrbal(MoneyUtil.formatYuan(tSubjectday.getBegindrbal() + sumDramt - sumCramt));
-      } else {
-        tSubjectday.setCrbal(MoneyUtil.formatYuan(tSubjectday.getBegincrbal() - sumDramt + sumCramt));
-      }
-      subjectdayDao.save(tSubjectday);
-    }
-    //根据二级更新一级科目日结
-    List<TSubjectday> parentSubject = subjectdayDao.getParentSubjectday(String.valueOf(settledate));
-    for (TSubjectday fsub : parentSubject) {
-      FSubjectInfoBean sumInfo = subjectdayDao.getParentSumInfo(String.valueOf(settledate), fsub.getSubjno());
-      fsub.setBegindrbal((null == sumInfo || null == sumInfo.getBegindrbal()) ? 0D : sumInfo.getBegindrbal());
-      fsub.setBegincrbal((null == sumInfo || null == sumInfo.getBegincrbal()) ? 0D : sumInfo.getBegincrbal());
-      fsub.setDramt((null == sumInfo || null == sumInfo.getDramt()) ? 0D : sumInfo.getDramt());
-      fsub.setCramt((null == sumInfo || null == sumInfo.getCramt()) ? 0D : sumInfo.getCramt());
-      fsub.setDrbal((null == sumInfo || null == sumInfo.getDrbal()) ? 0D : sumInfo.getDrbal());
-      fsub.setCrbal((null == sumInfo || null == sumInfo.getCrbal()) ? 0D : sumInfo.getCrbal());
-      fsub.setUpdtime(systemUtilService.getSysdatetime().getHostdatetime());
-      subjectdayDao.save(fsub);
-    }
-
-    //批量更新凭证明细中商户或科目账户的余额
-    List<TVoucherEntry> entryList = voucherEntryDao.getVoucherEntryByVoucherdate(settledate);
-    if (!StringUtil.isEmpty(entryList)) {
-      for (TVoucherEntry vce : entryList) {
-//        if (TradeDict.SUBJNO_SHOP.equals(vce.getSubjno())) {
-//          //商户科目
-//          Double befbal = v_merchbaldict.get(vce.getAccno());
-//          if (null == befbal) throw new Exception("商户表商户账号[" + vce.getAccno() + "]不存在");
-//          v_merchbaldict.put(vce.getAccno(), MoneyUtil.formatYuan(befbal + vce.getCramt() - vce.getDramt())); //更新余额
-//          vce.setBalflag(2);
-//          vce.setBalance(v_merchbaldict.get(vce.getAccno()));
-//          if (!StringUtil.isEmpty(vce.getOppaccno())) {
-//            vce.setOppname(shopaccDao.getShopname(vce.getOppaccno()).getAccname());
-//          } else {
-//            vce.setOppname(subjectDao.getSubjectname(vce.getOppsubjno()).getAccname());
-//          }
-//          voucherEntryDao.save(vce);
-//          Double befMerchbal = v_subjbaldict.get(vce.getSubjno());
-//          if (null == befMerchbal) throw new Exception("商户科目号[" + vce.getSubjno() + "]不存在");
-//          v_subjbaldict.put(vce.getSubjno(), MoneyUtil.formatYuan(befMerchbal - vce.getDramt() + vce.getCramt())); //商户科目总余额更新
-//        } else {
-          //其他科目
-          Integer balflag = v_subjbalflagdict.get(vce.getSubjno());
-          Double befbal = v_subjbaldict.get(vce.getSubjno());
-          if (null == balflag || null == befbal) throw new Exception("科目表科目号[" + vce.getSubjno() + "]不存在");
-          if (balflag == 1) {
-            v_subjbaldict.put(vce.getSubjno(), MoneyUtil.formatYuan(befbal + vce.getDramt() - vce.getCramt()));
-          } else {
-            v_subjbaldict.put(vce.getSubjno(), MoneyUtil.formatYuan(befbal - vce.getDramt() + vce.getCramt()));
-          }
-          vce.setBalflag(balflag);
-          vce.setBalance(v_subjbaldict.get(vce.getSubjno()));
-//          if (!StringUtil.isEmpty(vce.getOppaccno())) {
-//            vce.setOppname(shopaccDao.getShopname(vce.getOppaccno()).getAccname());
-//          } else {
-            vce.setOppname(subjectDao.getSubjectname(vce.getOppsubjno()));
-//          }
-          voucherEntryDao.save(vce);
-//        }
-      }
-    }
-
-    //开始校验
-    //核算商户日结表商户余额 和凭证明细余额是否一致 TODO(新商户收入校验逻辑)
-//    for (String shopaccno : v_merchbaldict.keySet()) {
-//      TShopaccday tShopaccday = shopaccdayDao.getTShopaccdayById(String.valueOf(settledate), shopaccno);
-//      if (!MoneyUtil.moneyEqual(v_merchbaldict.get(shopaccno), tShopaccday.getBalance())) {
-//        throw new Exception("结算后检查失败:商户余额不等,商户余额[" + tShopaccday.getBalance() + "]凭证商户余额[" + v_merchbaldict.get(shopaccno) + "]");
-//      }
-//      TShopaccbal tShopaccbal = shopaccbalDao.getOne(shopaccno);
-//      tShopaccbal.setBalance(tShopaccday.getBalance());
-//      tShopaccbal.setUpdtime(systemUtilService.getSysdatetime().getHostdatetime());
-//      shopaccbalDao.save(tShopaccbal);
-//    }
-
-    //核算科目日结表科目余额和凭证明细余额是否一致
-    for (String subjno : v_subjbaldict.keySet()) {
-      TSubjectday tSubjectday = subjectdayDao.getSubjectDayById(String.valueOf(settledate), subjno);
-      if (!MoneyUtil.moneyEqual(v_subjbaldict.get(subjno), tSubjectday.getDrbal() + tSubjectday.getCrbal())) {
-        throw new Exception("结算后检查失败:科目日结表期末余额不等,科目号[" + subjno + "],科目余额[" + (tSubjectday.getDrbal() + tSubjectday.getCrbal()) + "],凭证科目余额[" + v_subjbaldict.get(subjno) + "]");
-      }
-      TSubjectbal tSubjectbal = subjectbalDao.getOne(subjno);
-      tSubjectbal.setBegindrbal(tSubjectday.getBegindrbal());
-      tSubjectbal.setBegincrbal(tSubjectday.getBegincrbal());
-      tSubjectbal.setDramt(tSubjectday.getDramt());
-      tSubjectbal.setCramt(tSubjectday.getCramt());
-      tSubjectbal.setDrbal(tSubjectday.getDrbal());
-      tSubjectbal.setCrbal(tSubjectday.getCrbal());
-      tSubjectbal.setUpdtime(systemUtilService.getSysdatetime().getHostdatetime());
-      subjectbalDao.save(tSubjectbal);
-    }
-
-    //核对商户日结表余额表和科目日结表商户余额是否一致
-//    TSubjectday shopSubjectday = subjectdayDao.getSubjectDayById(String.valueOf(settledate), TradeDict.SUBJNO_SHOP);
-//    AmountBean merchbal = shopaccdayDao.getSumBalance(String.valueOf(settledate));
-//    double shopSubbal = (shopSubjectday == null ? 0 : shopSubjectday.getCrbal());
-//    double shopMerchbal = ((null == merchbal || null == merchbal.getAmount()) ? 0 : merchbal.getAmount());
-//    if (!MoneyUtil.moneyEqual(shopSubbal, shopMerchbal)) {
-//      throw new Exception("结算后检查失败:商户日结表和科目日结表期末余额不平衡,商户[" + shopMerchbal + "] 科目[" + shopSubbal + "]");
-//    }
-
-    //核算一级科目余额是否平衡
-    FSubjectInfoBean allParentSubjbal = subjectdayDao.getAllParentSubjectSumInfo(String.valueOf(settledate));
-    if (!MoneyUtil.moneyEqual(allParentSubjbal.getBegindrbal(), allParentSubjbal.getBegincrbal())) {
-      throw new Exception("结算后检查失败:一级科目余额表期初余额不平衡,借方[" + allParentSubjbal.getBegindrbal() + "],贷方[" + allParentSubjbal.getBegincrbal() + "]");
-    }
-    if (!MoneyUtil.moneyEqual(allParentSubjbal.getDramt(), allParentSubjbal.getCramt())) {
-      throw new Exception("结算后检查失败:一级科目余额表发生额不平衡,借方[" + allParentSubjbal.getDramt() + "],贷方[" + allParentSubjbal.getCramt() + "]");
-    }
-    if (!MoneyUtil.moneyEqual(allParentSubjbal.getDrbal(), allParentSubjbal.getCrbal())) {
-      throw new Exception("结算后检查失败:一级科目余额表期末额不平衡,借方[" + allParentSubjbal.getDrbal() + "]贷方[" + allParentSubjbal.getCrbal() + "]");
-    }
-    //校验科目余额表的balflag=1的总期末余额和balflag=2的总期末余额是否一致
-    Double balflag_1_sumbal = subjectbalDao.getSumEndsubjectBalByEndflag(1);
-    Double balflag_2_sumbal = subjectbalDao.getSumEndsubjectBalByEndflag(2);
-    if (null == balflag_1_sumbal || null == balflag_1_sumbal) throw new Exception("结算后检查失败:科目余额表无数据");
-    if (!MoneyUtil.moneyEqual(balflag_1_sumbal, balflag_2_sumbal)) {
-      throw new Exception("结算后检查失败:科目余额表期末余额不平衡,借方[" + balflag_1_sumbal + "],贷方[" + balflag_2_sumbal + "]");
-    }
-    //TODO: 校验 账户余额汇总值和科目日结表值是否一致
-
-    //日切
-    tSettlectl.setStatus(0); //清标记
-    tSettlectl.setSettledate(Integer.valueOf(DateUtil.getNewDay(String.valueOf(settledate), 1)));
-    tSettlectl.setUpdtime(systemUtilService.getSysdatetime().getHostdatetime());
-    return true;
-  }
-
-  @Override
-  public boolean doVoucherSettle(String voucherid) throws Exception {
-    if (StringUtil.isEmpty(voucherid)) throw new Exception("参数为空");
-
-    TSettlectl settlectl = settleCtlDao.findByBooksetno(1);
-    if (null == settlectl || null == settlectl.getBooksetno()) {
-      throw new Exception("系统初始化参数错误");
-    }
-
-//    int hostDate = Integer.valueOf(systemUtilService.getSysdatetime().getHostdatetime());
-//    int prdyear = settlectl.getPeriodYear();
-//    int prdmonth = settlectl.getPeriodMonth();
-    int settday = settlectl.getSettledate();
-
-    List<String> newShopList = shopaccDao.getNewAddShopacc(String.valueOf(settday));
-    if (!StringUtil.isEmpty(newShopList)) {
-      for (String accno : newShopList) {
-        TShopaccbal shopBal = new TShopaccbal(accno);
-        shopaccbalDao.save(shopBal);
-      }
-    }
-    if (shopaccDao.checkSettleShopacc().getExisted() > 0) {
-      throw new Exception("初始化数据错误:商户余额表数据没有包含所有有效的商户账户余额");
-    }
-
-    //新增科目插入科目余额表（末级科目）
-    List<String> newEndsubjectList = subjectDao.getNewSubject();
-    if (!StringUtil.isEmpty(newEndsubjectList)) {
-      for (String subjno : newEndsubjectList) {
-        TSubjectbal subjectbal = new TSubjectbal(subjno);
-        subjectbalDao.save(subjectbal);
-      }
-    }
-    if (subjectDao.checkSettleSubject().getExisted() > 0) {
-      throw new Exception("初始化数据错误:科目余额表数据没有包含所有的科目余额");
-    }
-
-    TVoucher voucher = voucherDao.findByVoucheridWithLock(voucherid);
-    List<TVoucherEntry> entryList = voucherEntryDao.getVoucherEntryByVoucherid(voucherid);
-    if (null == voucher) {
-      throw new Exception("凭证查询无记录");
-    } else if ("auto".equals(voucher.getSourcetype())) {
-      throw new Exception("该凭证不是手工录入凭证");
-    } else if (voucher.getCheckflag() != 1) {
-      throw new Exception("该凭证未审核");
-    } else if (StringUtil.isEmpty(voucher.getSummary())) {
-      throw new Exception("摘要不能为空");
-    } else if (voucher.getPostflag() == 1) {
-      throw new Exception("凭证已入账");
-    }
-
-    if (StringUtil.isEmpty(entryList)) {
-      throw new Exception("凭证无借贷明细！");
-    }
-
-    //凭证号
-    TVouchernoCtl vouchernoCtl = vouchernoCtlDao.getVoucherno();
-    if (null == vouchernoCtl) {
-      vouchernoCtl = new TVouchernoCtl(1, periodMonth, 0);
-      vouchernoCtlDao.save(vouchernoCtl);
-    }
-    int voucherno = vouchernoCtl.getVoucherno() + 1;
-    vouchernoCtl.setVoucherno(voucherno);
-    vouchernoCtlDao.save(vouchernoCtl);
-
-    voucher.setVoucherno(voucherno);
-    voucher.setPostflag(1);
-    voucherDao.save(voucher); //修改凭证表凭证号、入账标志
-
-    //明细
-    for (TVoucherEntry entry : entryList) {
-      if (Subject.SUBJNO_MACHANT_INCOME.equals(entry.getSubjno())) {
-        TShopaccbal tShopaccbal = shopaccbalDao.getTShopaccbalByIdWithLock(entry.getAccno());
-        if (null == tShopaccbal) {
-          throw new Exception("商户表商户账号[" + entry.getAccno() + "]不存在");
-        }
-        tShopaccbal.setBalance(tShopaccbal.getBeginbal() + entry.getCramt() - entry.getDramt());
-        shopaccbalDao.save(tShopaccbal);
-        entry.setBalflag(2);
-        entry.setBalance(tShopaccbal.getBalance());
-      } else {
-        TSubjectbal tSubjectbal = subjectbalDao.getTSubjectbalBySubjnoWithLock(entry.getSubjno());
-        TSubject subject = subjectDao.getOne(entry.getSubjno());
-        if (null == tSubjectbal || null == subject) {
-          throw new Exception("科目表科目号[" + entry.getSubjno() + "]不存在");
-        } else if (subject.getEndflag() != 1) {
-          throw new Exception("科目[" + entry.getSubjno() + "]非末级科目");
-        }
-        entry.setBalflag(subject.getBalflag());
-        if (subject.getBalflag() == 1) {
-          tSubjectbal.setDrbal(tSubjectbal.getDrbal() + entry.getDramt() - entry.getCramt());
-          entry.setBalance(tSubjectbal.getDrbal());
-        } else {
-          tSubjectbal.setCrbal(tSubjectbal.getCrbal() - entry.getDramt() + entry.getCramt());
-          entry.setBalance(tSubjectbal.getCrbal());
-        }
-        subjectbalDao.save(tSubjectbal);
-      }
-
-      if (!StringUtil.isEmpty(entry.getOppaccno())) {
-        entry.setOppname(shopaccDao.getShopname(entry.getOppaccno()));
-      } else {
-        entry.setOppname(subjectDao.getSubjectname(entry.getOppsubjno()));
-      }
-      voucherEntryDao.save(entry);
-    }
-
-    return true;
-  }
-
-}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/service/impl/SystemUtilServiceImpl.java b/src/main/java/com/supwisdom/dlpay/framework/service/impl/SystemUtilServiceImpl.java
index bd16781..6ed5bb6 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/service/impl/SystemUtilServiceImpl.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/service/impl/SystemUtilServiceImpl.java
@@ -8,9 +8,9 @@
 import com.supwisdom.dlpay.framework.util.DateUtil;
 import com.supwisdom.dlpay.framework.util.NumberUtil;
 import com.supwisdom.dlpay.framework.util.StringUtil;
-import org.apache.log4j.Logger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import java.text.SimpleDateFormat;
@@ -32,7 +32,7 @@
   @Autowired
   private BusinessparaDao businessparaDao;
 
-  private static final Logger logger = Logger.getLogger(SystemUtilServiceImpl.class);
+  private static final Logger logger = LoggerFactory.getLogger(SystemUtilServiceImpl.class);
 
   public static class SystemDateTimeImpl implements SystemDateTime {
     private Date now;
@@ -140,6 +140,7 @@
         return taskLockDao.getOracleRefno();
     }
   }
+
   @Override
   public String getCardverno() {
     switch (databaseConfig.getPlatform()) {
@@ -183,29 +184,31 @@
   @Override
   public int getSysparaValueAsInt(int paraid, int defaultValue) {
     TSyspara syspara = sysparaDao.findByParaid(paraid);
-    if (null != syspara && NumberUtil.isNumber(syspara.getParaval())) return Integer.parseInt(syspara.getParaval());
+    if (null != syspara && NumberUtil.isNumber(syspara.getParaval()))
+      return Integer.parseInt(syspara.getParaval());
     return defaultValue;
   }
 
   @Override
   public double getSysparaValueAsDouble(int paraid, double defaultValue) {
     TSyspara syspara = sysparaDao.findByParaid(paraid);
-    if (null != syspara && NumberUtil.isDecimal(syspara.getParaval())) return Double.parseDouble(syspara.getParaval());
+    if (null != syspara && NumberUtil.isDecimal(syspara.getParaval()))
+      return Double.parseDouble(syspara.getParaval());
     return defaultValue;
   }
 
   @Override
-  public TSyspara getSyspara(int paraid){
+  public TSyspara getSyspara(int paraid) {
     return sysparaDao.findByParaid(paraid);
   }
 
   @Override
-  public TSyspara getSysparaValueForUpdate(int paraid){
+  public TSyspara getSysparaValueForUpdate(int paraid) {
     return sysparaDao.findByParaidWithLock(paraid);
   }
 
   @Override
-  public TSyspara getSysparaValueForUpdateNowait(int paraid){
+  public TSyspara getSysparaValueForUpdateNowait(int paraid) {
     return sysparaDao.findByParaidWithLockNowait(paraid);
   }
 
@@ -232,7 +235,7 @@
   }
 
   @Override
-  public TBusinesspara getBusinessValueForUpdate(String parakey){
+  public TBusinesspara getBusinessValueForUpdate(String parakey) {
     if (!StringUtil.isEmpty(parakey)) return businessparaDao.findByParakeyForUpdate(parakey.trim());
     return null;
   }
@@ -244,7 +247,7 @@
   }
 
   @Override
-  public String getSubsystemSignKey(String syscode){
+  public String getSubsystemSignKey(String syscode) {
     // fixme: 验证数据无误性签名秘钥
     return "";
   }
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/DateUtil.java b/src/main/java/com/supwisdom/dlpay/framework/util/DateUtil.java
index 38e3dfe..6faf336 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/DateUtil.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/DateUtil.java
@@ -1,6 +1,7 @@
 package com.supwisdom.dlpay.framework.util;
 
-import org.apache.log4j.Logger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -9,332 +10,333 @@
 import java.util.TimeZone;
 
 public class DateUtil {
-    private static final Logger logger = Logger.getLogger(DateUtil.class);
-    public static final String DATE_FMT = "yyyyMMdd";
-    public static final String TIME_FMT = "HHmmss";
-    public static final String DATETIME_FMT = "yyyyMMddHHmmss";
+  private static final Logger logger = LoggerFactory.getLogger(DateUtil.class);
+  public static final String DATE_FMT = "yyyyMMdd";
+  public static final String TIME_FMT = "HHmmss";
+  public static final String DATETIME_FMT = "yyyyMMddHHmmss";
 
-    /**
-     * Description: 返回一个当前时间 @return String 格式：yyyyMMddHHmmss @exception Modify
-     * History:
-     */
-    public static String getNow() {
-        java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
-        return sdf.format(new Date());
+  /**
+   * Description: 返回一个当前时间 @return String 格式：yyyyMMddHHmmss @exception Modify
+   * History:
+   */
+  public static String getNow() {
+    java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
+    return sdf.format(new Date());
+  }
+
+
+  /**
+   * Description: 根据类型返回一个当前时间 @param partten String @return String 格式：partten
+   */
+  public static String getNow(String partten) {
+    SimpleDateFormat sdf = new SimpleDateFormat(partten);
+    return sdf.format(new Date());
+  }
+
+  /**
+   * Description: 得到一个特殊的时间 @param startTime String 格式：yyyyMMddHHmmss @param
+   * interval int 秒 @return String 格式：partten @exception Modify History:
+   */
+  public static String getNewTime(String startTime, int interval) {
+    try {
+      java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
+      Date d = sdf.parse(startTime);
+      Calendar calendar = Calendar.getInstance();
+      calendar.setTimeInMillis(d.getTime());
+      calendar.add(Calendar.SECOND, interval);
+      return sdf.format(calendar.getTime());
+    } catch (ParseException e) {
+      return startTime;
     }
+  }
 
-
-    /**
-     * Description: 根据类型返回一个当前时间 @param partten String @return String 格式：partten
-     */
-    public static String getNow(String partten) {
-        SimpleDateFormat sdf = new SimpleDateFormat(partten);
-        return sdf.format(new Date());
+  /**
+   * Description: 得到一个特殊的时间 @param startTime String 格式：partten @param
+   * interval int 秒 @return String 格式：partten @exception Modify History:
+   */
+  public static String getNewTime(String startTime, int interval, String partten) {
+    try {
+      java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(partten);
+      Date d = sdf.parse(startTime);
+      Calendar calendar = Calendar.getInstance();
+      calendar.setTimeInMillis(d.getTime());
+      calendar.add(Calendar.SECOND, interval);
+      return sdf.format(calendar.getTime());
+    } catch (ParseException e) {
+      return startTime;
     }
+  }
 
-    /**
-     * Description: 得到一个特殊的时间 @param startTime String 格式：yyyyMMddHHmmss @param
-     * interval int 秒 @return String 格式：partten @exception Modify History:
-     */
-    public static String getNewTime(String startTime, int interval) {
-        try {
-            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
-            Date d = sdf.parse(startTime);
-            Calendar calendar = Calendar.getInstance();
-            calendar.setTimeInMillis(d.getTime());
-            calendar.add(Calendar.SECOND, interval);
-            return sdf.format(calendar.getTime());
-        } catch (ParseException e) {
-            return startTime;
+  public static String getNewDay(String startDay, int intervalday) {
+    try {
+      java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMdd");
+      Date d = sdf.parse(startDay);
+      Calendar calendar = Calendar.getInstance();
+      calendar.setTimeInMillis(d.getTime());
+      calendar.add(Calendar.DATE, intervalday);
+      return sdf.format(calendar.getTime());
+    } catch (ParseException e) {
+      return startDay;
+    }
+  }
+
+  /**
+   * 获取当天前后的时间
+   *
+   * @param intervalday
+   * @param format
+   * @return
+   */
+  public static String getNewDay(int intervalday, String format) {
+    SimpleDateFormat sdf = new SimpleDateFormat(format);
+    Calendar calendar = Calendar.getInstance();
+    calendar.setTime(new Date());
+    calendar.add(Calendar.DATE, intervalday);
+    return sdf.format(calendar.getTime());
+  }
+
+  /**
+   * 得到两个日期相差的天数 格式 yyyyMMdd @return diffdays = secondDay - firstDay
+   */
+  public static long getIntervalDay(String firstDay, String secondDay) {
+    try {
+      java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMdd");
+      Date f = sdf.parse(firstDay);
+      Date s = sdf.parse(secondDay);
+      long time = s.getTime() - f.getTime();
+      return time / (24 * 60 * 60 * 1000);
+    } catch (ParseException e) {
+      return 0;
+    }
+  }
+
+  /**
+   * Description: 比较两个时间字符串的前后关系 @param firstTime String 格式：yyyyMMddHHmmss
+   *
+   * @param secondTime String 格式: yyyyMMddHHmmss @return int |
+   *                   firstTime=second int=0 | firstTime>secondTime int>0 |
+   *                   firstTime<secondTime int<0 @exception Modify History:
+   */
+  public static int compareDatetime(String firstTime, String secondTime) {
+    try {
+      java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
+      Date f = sdf.parse(firstTime);
+      Date s = sdf.parse(secondTime);
+      return f.compareTo(s);
+    } catch (ParseException e) {
+      return 0;
+    }
+  }
+
+  /**
+   * Description: 比较两个时间字符串的前后关系 @param firstTime String 格式：pattern
+   *
+   * @param secondTime String 格式: yyyyMMddHHmmss @return int |
+   *                   firstTime=second int=0 | firstTime>secondTime int>0 |
+   *                   firstTime<secondTime int<0 @exception Modify History:
+   */
+  public static int compareDatetime(String firstTime, String secondTime, String pattern) {
+    try {
+      java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(pattern);
+      Date f = sdf.parse(firstTime);
+      Date s = sdf.parse(secondTime);
+      return f.compareTo(s);
+    } catch (ParseException e) {
+      return 0;
+    }
+  }
+
+  /**
+   * Description: 比较两个时间字符串的时间差 @param firstTime String 格式：yyyyMMddHHmmss
+   *
+   * @param secondTime String 格式: yyyyMMddHHmmss @param second int 格式 @return
+   *                   int | firstTime+seconds=secondTime int=0 | firstTime+seconds>secondTime
+   *                   int>0 | firstTime+seconds<secondTime int<0 @exception Modify History:
+   */
+  public static int compareDatetime(String firstTime, String secondTime, int seconds) {
+    try {
+      java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
+      Date f = sdf.parse(firstTime);
+      Date s = sdf.parse(secondTime);
+      Calendar calendar = Calendar.getInstance();
+      calendar.setTimeInMillis(f.getTime());
+      calendar.add(Calendar.SECOND, seconds);
+      Date temp = calendar.getTime();
+      return temp.compareTo(s);
+    } catch (Exception e) {
+      return 0;
+    }
+  }
+
+  /**
+   * Description: 对time重新格式化
+   */
+  public static String reformatDatetime(String time, String fromPattern, String toPattern) {
+    try {
+      java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(fromPattern);
+      Date d = sdf.parse(time);
+      Calendar calendar = Calendar.getInstance();
+      calendar.setTimeInMillis(d.getTime());
+      sdf = new SimpleDateFormat(toPattern);
+      return sdf.format(calendar.getTime());
+    } catch (Exception e) {
+      e.printStackTrace();
+      return time;
+    }
+  }
+
+  /**
+   * 获得两个字符串日期之间的时间差(单位毫秒) 格式 yyyyMMddHHmmss
+   */
+  public static long getInterval(String startTime, String endTime) {
+    long duration = 0;
+    try {
+      java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
+      duration = sdf.parse(endTime).getTime() - sdf.parse(startTime).getTime();
+    } catch (ParseException e) {
+      logger.error("Hi guys,there is an error when you try to parse the date string");
+    }
+    return duration;
+  }
+
+  /**
+   * 获得两个字符串日期之间的时间差(单位毫秒)
+   */
+  public static long getIntervalTime(String startTime, String endTime, String pattern) {
+    long duration = 0;
+    try {
+      java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(pattern);
+      duration = sdf.parse(endTime).getTime() - sdf.parse(startTime).getTime();
+    } catch (ParseException e) {
+      logger.error("Hi guys,there is an error when you try to parse the date string");
+    }
+    return duration;
+  }
+
+  /**
+   * 转换成日期格式
+   * 短格式：20140401 -> 2014-04-01
+   * 中格式：201404011200 -> 2014-04-01 12:00
+   * 长格式：20140401123025 -> 2014-04-01 12:30:25
+   **/
+  public static String parseToDateFormat(String str) {
+    switch (str.length()) {
+      case 8:
+        str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8);
+        break;
+      case 12:
+        str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8) + " " + str.substring(8, 10) + ":" + str.substring(10, 12);
+        break;
+      case 14:
+        str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8) + " " + str.substring(8, 10) + ":" + str.substring(10, 12) + ":" + str.substring(12, 14);
+        break;
+      default:
+        break;
+    }
+    return str;
+  }
+
+  /**
+   * 解日期格式
+   * 短格式：2014-04-01 -> 20140401
+   * 中格式：2014-04-01 12:00 -> 201404011200
+   * 长格式：2014-04-01 12:30:25 -> 20140401123025
+   **/
+  public static String unParseToDateFormat(String str) {
+    return str.replaceAll("-", "").replaceAll(" ", "").replaceAll(":", "");
+  }
+
+  /**
+   * 检验时间格式
+   */
+  public static boolean checkDatetimeValid(String datetime, String pattern) {
+    if (null == datetime) return false;
+    try {
+      java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(pattern);
+      Date d = sdf.parse(datetime);
+      return datetime.trim().equals(sdf.format(d));
+    } catch (Exception e) {
+    }
+    return false;
+  }
+
+  /**
+   * 获取指定日期是星期几 格式 yyyyMMdd
+   * MON|TUE|WED|THU|FRI|SAT|SUN
+   * 1		2		3		4		5		6		7
+   */
+  public static int getWeekday(String datestr) {
+    try {
+      java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMdd");
+      Calendar calendar = Calendar.getInstance();
+      boolean isFirstSunday = (calendar.getFirstDayOfWeek() == Calendar.SUNDAY); //一周第一天是否为星期天
+      Date d = sdf.parse(datestr);
+      calendar.setTimeInMillis(d.getTime());
+      int weekDay = calendar.get(calendar.DAY_OF_WEEK);
+      if (isFirstSunday) {
+        weekDay = weekDay - 1;
+        if (weekDay == 0) {
+          weekDay = 7;
         }
+      }
+      return weekDay;
+    } catch (Exception e) {
+      return -1;
     }
+  }
 
-    /**
-     * Description: 得到一个特殊的时间 @param startTime String 格式：partten @param
-     * interval int 秒 @return String 格式：partten @exception Modify History:
-     */
-    public static String getNewTime(String startTime, int interval, String partten) {
-        try {
-            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(partten);
-            Date d = sdf.parse(startTime);
-            Calendar calendar = Calendar.getInstance();
-            calendar.setTimeInMillis(d.getTime());
-            calendar.add(Calendar.SECOND, interval);
-            return sdf.format(calendar.getTime());
-        } catch (ParseException e) {
-            return startTime;
-        }
+  /**
+   * 获取指定日期
+   */
+  public static Date getSpecifyDate(String datestr, String pattern) {
+    try {
+      java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(pattern);
+      Date result = sdf.parse(datestr);
+      return result;
+    } catch (Exception e) {
+      return new Date();
     }
+  }
 
-    public static String getNewDay(String startDay, int intervalday) {
-        try {
-            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMdd");
-            Date d = sdf.parse(startDay);
-            Calendar calendar = Calendar.getInstance();
-            calendar.setTimeInMillis(d.getTime());
-            calendar.add(Calendar.DATE, intervalday);
-            return sdf.format(calendar.getTime());
-        } catch (ParseException e) {
-            return startDay;
-        }
-    }
+  public static Integer getLastDayOfMonth(Integer year, Integer month) {
+    Calendar cal = Calendar.getInstance();
+    cal.set(Calendar.YEAR, year);
+    cal.set(Calendar.MONTH, month - 1);
+    cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DATE));
+    String str = new SimpleDateFormat("yyyyMMdd ").format(cal.getTime()).toString();
+    Integer result = Integer.parseInt(str.substring(0, 4) + str.substring(4, 6) + str.substring(6, 8));
+    return result;
+  }
 
-    /**
-     * 获取当天前后的时间
-     * @param intervalday
-     * @param format
-     * @return
-     */
-    public static String getNewDay(int intervalday, String format) {
-            SimpleDateFormat sdf = new SimpleDateFormat(format);
-            Calendar calendar = Calendar.getInstance();
-            calendar.setTime(new Date());
-            calendar.add(Calendar.DATE, intervalday);
-            return sdf.format(calendar.getTime());
-    }
-
-    /**
-     * 得到两个日期相差的天数 格式 yyyyMMdd @return diffdays = secondDay - firstDay
-     */
-    public static long getIntervalDay(String firstDay, String secondDay) {
-        try {
-            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMdd");
-            Date f = sdf.parse(firstDay);
-            Date s = sdf.parse(secondDay);
-            long time = s.getTime() - f.getTime();
-            return time / (24 * 60 * 60 * 1000);
-        } catch (ParseException e) {
-            return 0;
-        }
-    }
-
-    /**
-     * Description: 比较两个时间字符串的前后关系 @param firstTime String 格式：yyyyMMddHHmmss
-     *
-     * @param secondTime String 格式: yyyyMMddHHmmss @return int |
-     *                   firstTime=second int=0 | firstTime>secondTime int>0 |
-     *                   firstTime<secondTime int<0 @exception Modify History:
-     */
-    public static int compareDatetime(String firstTime, String secondTime) {
-        try {
-            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
-            Date f = sdf.parse(firstTime);
-            Date s = sdf.parse(secondTime);
-            return f.compareTo(s);
-        } catch (ParseException e) {
-            return 0;
-        }
-    }
-
-    /**
-     * Description: 比较两个时间字符串的前后关系 @param firstTime String 格式：pattern
-     *
-     * @param secondTime String 格式: yyyyMMddHHmmss @return int |
-     *                   firstTime=second int=0 | firstTime>secondTime int>0 |
-     *                   firstTime<secondTime int<0 @exception Modify History:
-     */
-    public static int compareDatetime(String firstTime, String secondTime, String pattern) {
-        try {
-            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(pattern);
-            Date f = sdf.parse(firstTime);
-            Date s = sdf.parse(secondTime);
-            return f.compareTo(s);
-        } catch (ParseException e) {
-            return 0;
-        }
-    }
-
-    /**
-     * Description: 比较两个时间字符串的时间差 @param firstTime String 格式：yyyyMMddHHmmss
-     *
-     * @param secondTime String 格式: yyyyMMddHHmmss @param second int 格式 @return
-     *                   int | firstTime+seconds=secondTime int=0 | firstTime+seconds>secondTime
-     *                   int>0 | firstTime+seconds<secondTime int<0 @exception Modify History:
-     */
-    public static int compareDatetime(String firstTime, String secondTime, int seconds) {
-        try {
-            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
-            Date f = sdf.parse(firstTime);
-            Date s = sdf.parse(secondTime);
-            Calendar calendar = Calendar.getInstance();
-            calendar.setTimeInMillis(f.getTime());
-            calendar.add(Calendar.SECOND, seconds);
-            Date temp = calendar.getTime();
-            return temp.compareTo(s);
-        } catch (Exception e) {
-            return 0;
-        }
-    }
-
-    /**
-     * Description: 对time重新格式化
-     */
-    public static String reformatDatetime(String time, String fromPattern, String toPattern) {
-        try {
-            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(fromPattern);
-            Date d = sdf.parse(time);
-            Calendar calendar = Calendar.getInstance();
-            calendar.setTimeInMillis(d.getTime());
-            sdf = new SimpleDateFormat(toPattern);
-            return sdf.format(calendar.getTime());
-        } catch (Exception e) {
-            e.printStackTrace();
-            return time;
-        }
-    }
-
-    /**
-     * 获得两个字符串日期之间的时间差(单位毫秒) 格式 yyyyMMddHHmmss
-     */
-    public static long getInterval(String startTime, String endTime) {
-        long duration = 0;
-        try {
-            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
-            duration = sdf.parse(endTime).getTime() - sdf.parse(startTime).getTime();
-        } catch (ParseException e) {
-            logger.error("Hi guys,there is an error when you try to parse the date string");
-        }
-        return duration;
-    }
-
-    /**
-     * 获得两个字符串日期之间的时间差(单位毫秒)
-     */
-    public static long getIntervalTime(String startTime, String endTime, String pattern) {
-        long duration = 0;
-        try {
-            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(pattern);
-            duration = sdf.parse(endTime).getTime() - sdf.parse(startTime).getTime();
-        } catch (ParseException e) {
-            logger.error("Hi guys,there is an error when you try to parse the date string");
-        }
-        return duration;
-    }
-
-    /**
-     * 转换成日期格式
-     * 短格式：20140401 -> 2014-04-01
-     * 中格式：201404011200 -> 2014-04-01 12:00
-     * 长格式：20140401123025 -> 2014-04-01 12:30:25
-     **/
-    public static String parseToDateFormat(String str) {
-        switch (str.length()) {
-            case 8:
-                str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8);
-                break;
-            case 12:
-                str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8) + " " + str.substring(8, 10) + ":" + str.substring(10, 12);
-                break;
-            case 14:
-                str = str.substring(0, 4) + "-" + str.substring(4, 6) + "-" + str.substring(6, 8) + " " + str.substring(8, 10) + ":" + str.substring(10, 12) + ":" + str.substring(12, 14);
-                break;
-            default:
-                break;
-        }
-        return str;
-    }
-
-    /**
-     * 解日期格式
-     * 短格式：2014-04-01 -> 20140401
-     * 中格式：2014-04-01 12:00 -> 201404011200
-     * 长格式：2014-04-01 12:30:25 -> 20140401123025
-     **/
-    public static String unParseToDateFormat(String str) {
-        return str.replaceAll("-", "").replaceAll(" ", "").replaceAll(":", "");
-    }
-
-    /**
-     * 检验时间格式
-     */
-    public static boolean checkDatetimeValid(String datetime, String pattern) {
-        if (null == datetime) return false;
-        try {
-            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(pattern);
-            Date d = sdf.parse(datetime);
-            return datetime.trim().equals(sdf.format(d));
-        } catch (Exception e) {
-        }
-        return false;
-    }
-
-    /**
-     * 获取指定日期是星期几 格式 yyyyMMdd
-     * MON|TUE|WED|THU|FRI|SAT|SUN
-     * 1		2		3		4		5		6		7
-     */
-    public static int getWeekday(String datestr) {
-        try {
-            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMdd");
-            Calendar calendar = Calendar.getInstance();
-            boolean isFirstSunday = (calendar.getFirstDayOfWeek() == Calendar.SUNDAY); //一周第一天是否为星期天
-            Date d = sdf.parse(datestr);
-            calendar.setTimeInMillis(d.getTime());
-            int weekDay = calendar.get(calendar.DAY_OF_WEEK);
-            if (isFirstSunday) {
-                weekDay = weekDay - 1;
-                if (weekDay == 0) {
-                    weekDay = 7;
-                }
-            }
-            return weekDay;
-        } catch (Exception e) {
-            return -1;
-        }
-    }
-
-    /**
-     * 获取指定日期
-     */
-    public static Date getSpecifyDate(String datestr, String pattern) {
-        try {
-            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(pattern);
-            Date result = sdf.parse(datestr);
-            return result;
-        } catch (Exception e) {
-            return new Date();
-        }
-    }
-
-    public static Integer getLastDayOfMonth(Integer year, Integer month) {
-        Calendar cal = Calendar.getInstance();
-        cal.set(Calendar.YEAR, year);
-        cal.set(Calendar.MONTH, month - 1);
-        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DATE));
-        String str = new SimpleDateFormat("yyyyMMdd ").format(cal.getTime()).toString();
-        Integer result = Integer.parseInt(str.substring(0, 4) + str.substring(4, 6) + str.substring(6, 8));
-        return result;
-    }
-
-    private static Date set(Date date, int calendarField, int amount) {
-        Calendar c = Calendar.getInstance();
-        c.setLenient(false);
-        c.setTime(date);
-        c.add(calendarField, amount);
-        return c.getTime();
-    }
+  private static Date set(Date date, int calendarField, int amount) {
+    Calendar c = Calendar.getInstance();
+    c.setLenient(false);
+    c.setTime(date);
+    c.add(calendarField, amount);
+    return c.getTime();
+  }
 
 
-    public static Date setMinutes(Date date, int amount) {
-        return set(date, Calendar.MINUTE, amount);
-    }
+  public static Date setMinutes(Date date, int amount) {
+    return set(date, Calendar.MINUTE, amount);
+  }
 
 
-    public static long getNowSecond() {
-        Calendar calendar = Calendar.getInstance();
-        return calendar.getTimeInMillis() / 1000;
-    }
+  public static long getNowSecond() {
+    Calendar calendar = Calendar.getInstance();
+    return calendar.getTimeInMillis() / 1000;
+  }
 
 
-    public static String getUTCTime(Long timeInMillisSecond) {
-        Calendar time = Calendar.getInstance();
-        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
-        fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
-        time.setTimeInMillis(timeInMillisSecond);
-        return fmt.format(time.getTime());
-    }
+  public static String getUTCTime(Long timeInMillisSecond) {
+    Calendar time = Calendar.getInstance();
+    SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
+    fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
+    time.setTimeInMillis(timeInMillisSecond);
+    return fmt.format(time.getTime());
+  }
 
-    public static String getUTCTime() {
-        return getUTCTime(System.currentTimeMillis());
-    }
+  public static String getUTCTime() {
+    return getUTCTime(System.currentTimeMillis());
+  }
 }
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/controller/common_api_controller.kt b/src/main/kotlin/com/supwisdom/dlpay/api/controller/common_api_controller.kt
index 9709b57..ec7ee8d 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/controller/common_api_controller.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/controller/common_api_controller.kt
@@ -4,17 +4,18 @@
 import com.supwisdom.dlpay.api.service.CommonApiService
 import com.supwisdom.dlpay.framework.ResponseBodyBuilder
 import com.supwisdom.dlpay.framework.util.TradeErrorCode
-import org.apache.log4j.Logger
+import mu.KotlinLogging
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.ResponseEntity
-import org.springframework.web.bind.annotation.*
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
 
 @RestController
 @RequestMapping("/api/common")
 class CommonAPIController {
-    companion object {
-        private val logger = Logger.getLogger(CommonAPIController::class.java)
-    }
+    private val logger = KotlinLogging.logger { }
 
     @Autowired
     lateinit var commonApiService: CommonApiService
@@ -62,7 +63,7 @@
      * ============================================================================
      * */
     @PostMapping("/downloadwhitelist")
-    fun downloadWhiteList(@RequestBody param: DownloadWhiteListParam): ResponseEntity<Any>{
+    fun downloadWhiteList(@RequestBody param: DownloadWhiteListParam): ResponseEntity<Any> {
         return ResponseEntity.ok(ResponseBodyBuilder.create()
                 .fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "业务处理错误"))
     }
@@ -73,7 +74,7 @@
      * ============================================================================
      * */
     @PostMapping("/querypossales")
-    fun queryPosSales(@RequestBody param: QueryPosSalesParam): ResponseEntity<Any>{
+    fun queryPosSales(@RequestBody param: QueryPosSalesParam): ResponseEntity<Any> {
         return ResponseEntity.ok(ResponseBodyBuilder.create()
                 .fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "业务处理错误"))
     }
@@ -84,16 +85,10 @@
      * ============================================================================
      * */
     @PostMapping("/queryposdtl")
-    fun queryPosDtl(@RequestBody param: QueryPosDtlParam): ResponseEntity<Any>{
+    fun queryPosDtl(@RequestBody param: QueryPosDtlParam): ResponseEntity<Any> {
         return ResponseEntity.ok(ResponseBodyBuilder.create()
                 .fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "业务处理错误"))
     }
 
 
-
-
-
-
-
-
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt b/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt
index df4aef2..78ea7ee 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/framework/framework_util.kt
@@ -5,14 +5,15 @@
 import com.supwisdom.dlpay.exception.TransactionCheckException
 import com.supwisdom.dlpay.exception.TransactionException
 import com.supwisdom.dlpay.framework.util.TradeErrorCode
-import org.apache.log4j.Logger
+import mu.KotlinLogging
 
 
 class ResponseBodyBuilder private constructor() {
+    private val LOGGER = KotlinLogging.logger { }
+
     companion object {
         private const val INVALIDE_RETCODE = -0x7FFFFFFF
         private val RESERVED_KEY = setOf("retcode", "retmsg", "exception")
-        private val LOGGER = Logger.getLogger(ResponseBodyBuilder::class.java)
         fun create() = ResponseBodyBuilder()
     }
 
@@ -75,7 +76,7 @@
             throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "未设置返回码!")
         } else if (retCode != 0) {
             LOGGER.error(" ==== ERROR ==== 【retcode=[$retCode],retmsg=[$retMsg]】: data=" + Gson().toJson(this.respData))
-        }else{
+        } else {
             LOGGER.info("retcode=[0],retmsg=[$retMsg] return success!!! \n" + Gson().toJson(this.respData))
         }
         return this.respData.plus(mapOf("retcode" to retCode, "retmsg" to retMsg))
