Merge tag '1.0.31' into develop

二维码取8位sign修改和结算清算确认
diff --git a/bus-qrcode/build.gradle b/bus-qrcode/build.gradle
index 0817cb6..8559f1d 100644
--- a/bus-qrcode/build.gradle
+++ b/bus-qrcode/build.gradle
@@ -7,7 +7,7 @@
 
 group = rootProject.group
 
-def sdkVersion = '1.3.5'
+def sdkVersion = '1.3.6'
 sourceCompatibility = 1.8
 targetCompatibility = 1.8
 
diff --git a/bus-qrcode/src/main/java/com/supwisdom/dlpay/busqrcode/QrCode.java b/bus-qrcode/src/main/java/com/supwisdom/dlpay/busqrcode/QrCode.java
index 93070d0..e920f0e 100644
--- a/bus-qrcode/src/main/java/com/supwisdom/dlpay/busqrcode/QrCode.java
+++ b/bus-qrcode/src/main/java/com/supwisdom/dlpay/busqrcode/QrCode.java
@@ -13,7 +13,6 @@
 import java.time.Duration;
 import java.time.Instant;
 import java.util.*;
-import java.util.concurrent.TimeUnit;
 
 import static com.supwisdom.dlpay.busqrcode.BinUtil.*;
 import static com.supwisdom.dlpay.busqrcode.CryptoUtil.*;
@@ -37,7 +36,7 @@
     qrDataKeys.add(FIELD_CARDTYPE);
     qrDataKeys.add(FIELD_TOTP);
     qrDataKeys.add(FIELD_RANDOM);
-//    qrDataKeys.add(FIELD_SIGN);
+    qrDataKeys.add(FIELD_SIGN);
   }
 
   private Builder qrBuilder;
@@ -271,18 +270,17 @@
     }
 
     final byte[] sign = sha256(byteConcat(qrData.getBytes(), factor));
-//    final byte[] signT = new byte[20];
-//    System.arraycopy(sign, 0, signT, 0, 20); //取前20位
-    final byte[] encDataPlain = byteConcat(qrData.getBytes(), DELIMITER.getBytes(), sign);
-//    final byte[] encData = aesEncryptCFB(qrBuilder.rootKey, encDataPlain, qrBuilder.iv);
-    final byte[] encData = aesEncryptCFB(qrBuilder.rootKey, qrData.getBytes(), qrBuilder.iv);
+    final byte[] signT = new byte[8];
+    System.arraycopy(sign, 0, signT, 0, 8); //取前8位
+    final byte[] encDataPlain = byteConcat(qrData.getBytes(), DELIMITER.getBytes(), signT);
+    final byte[] encData = aesEncryptCFB(qrBuilder.rootKey, encDataPlain, qrBuilder.iv);
     final String code = encodeBase64(encData);
     String result = code;
     if (qrBuilder.prefix != null) {
       result = qrBuilder.prefix + code;
     }
     if (qrBuilder.debug) {
-      System.out.println("hex sign=[" + encodeHex(sign) + "]");
+      System.out.println("hex sign=[" + encodeHex(signT) + "]");
       System.out.println("hex encDataPlain=[" + encodeHex(encData) + "]");
       System.out.println("QR code=[" + result + "]");
       System.out.println("======================  Build QR Code End  =================================");
@@ -321,8 +319,8 @@
     if (qrBuilder.debug) {
       System.out.println("encDataPlain=[" + encData + "]");
     }
-    final String[] fields = encData.split(DELIMITER, 5);
-    if (fields.length < 5) {
+    final String[] fields = encData.split(DELIMITER, 6);
+    if (fields.length < 6) {
       throw new RuntimeException("二维码数据异常!");
     }
     Map<String, String> result = new HashMap<>();
@@ -340,16 +338,16 @@
     final String uid = result.get(FIELD_UID);
     final byte[] factor = getSignFactor(uid);
     final byte[] calcSign = sha256(byteConcat(qrData.getBytes(), factor));
-//    final byte[] signT = new byte[20];
-//    System.arraycopy(calcSign, 0, signT, 0, 20); //取前20位
+    final byte[] signT = new byte[8];
+    System.arraycopy(calcSign, 0, signT, 0, 8); //取前8位
     if (qrBuilder.debug) {
-//      System.out.println("calcSign=[" + new String(calcSign) + "]");
+      System.out.println("calcSign=[" + new String(signT) + "]");
       System.out.println("    sign=[" + result.get(FIELD_SIGN) + "]");
       System.out.println("======================  Decode QR Code End  =================================");
     }
-//    if (!new String(signT).equalsIgnoreCase(result.get(FIELD_SIGN))) {
-//      throw new RuntimeException("二维码验证错误!");
-//    }
+    if (!new String(signT).equalsIgnoreCase(result.get(FIELD_SIGN))) {
+      throw new RuntimeException("二维码验证错误!");
+    }
 
     return result;
   }
diff --git a/config/application-devel-pg-xkx.properties b/config/application-devel-pg-xkx.properties
index 16830f5..e03fe08 100644
--- a/config/application-devel-pg-xkx.properties
+++ b/config/application-devel-pg-xkx.properties
@@ -45,6 +45,7 @@
 #send.delay.notice.task.cron=29 0/1 * * * ?
 #points.outdate.cron=0 0 0 * * ?
 #points.consume.cron=0 0 0 * * ?
+citizencard.confirm.chkdtl.cron=*/30 * * * * ?
 #############################################
 spring.cloud.consul.enabled=false
 spring.cloud.consul.host=172.28.201.70
@@ -76,3 +77,4 @@
 # \u6307\u5B9A\u6D88\u606Fkey\u548C\u6D88\u606F\u4F53\u7684\u7F16\u89E3\u7801\u65B9\u5F0F
 spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
 spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
+
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/agent/Constant.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/agent/Constant.java
index 7f572da..39169ac 100644
--- a/payapi-common/src/main/java/com/supwisdom/dlpay/api/agent/Constant.java
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/agent/Constant.java
@@ -20,4 +20,5 @@
   public static final String COL_STATUS = "status";
   public static final String COL_FLAG = "flag";
   public static final String COL_RECORDNO = "recordno"; //记录号
+  public static final String COL_BANKSEQNO = "payeeno"; //商户银行序号
 }
diff --git a/payapi/build.gradle b/payapi/build.gradle
index 62de5b2..d7eb36a 100644
--- a/payapi/build.gradle
+++ b/payapi/build.gradle
@@ -125,7 +125,7 @@
     implementation group: 'com.alipay.sdk', name: 'alipay-sdk-java', version: '3.7.110.ALL'
 
     /*大理二维码jar*/
-    implementation 'com.supwisdom:dlsmk-qrcode:1.3.5'
+    implementation 'com.supwisdom:dlsmk-qrcode:1.3.6'
 
     annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
     annotationProcessor 'org.projectlombok:lombok:1.18.8'
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/PersondtlDao.java b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/PersondtlDao.java
index 3be4457..e91b882 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/PersondtlDao.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/PersondtlDao.java
@@ -2,7 +2,6 @@
 
 import com.supwisdom.dlpay.api.domain.TPersondtl;
 import com.supwisdom.dlpay.framework.data.CountAmountBean;
-import com.supwisdom.dlpay.framework.domain.TPointsdtl;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaRepository;
@@ -27,4 +26,8 @@
     List<TPersondtl> findAllByTransdateAndReverseFlagAndStatusAndTradeflag(String transdate,String reverseFlag,String status,String tradeflag);
 
     TPersondtl findTopByUseridAndStatusAndTradeflag(String userid, String status, String tradeFlag);
+
+    @Query(value = "select sum(case when t.amount<=0 then 1 else -1 end) as totalcnt,sum(-1*t.amount) as totalamt from TPersondtl t where t.status='success' and t.accdate=?1 and t.sourceType=?2 ")
+    CountAmountBean getChkClearSumInfo(String accdate, String sourcetype);
+
 }
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/service/CitizencardManagerService.java b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/service/CitizencardManagerService.java
index c799ee2..779e6dd 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/service/CitizencardManagerService.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/service/CitizencardManagerService.java
@@ -19,4 +19,7 @@
 
   @Transactional(rollbackFor = Exception.class)
   TCitizencardLossApply doFinishCitizencardLoss(TCitizencardLossApply lossApply);
+
+  @Transactional(rollbackFor = Exception.class)
+  boolean doConfirmCitizencardCheckProcess(String checkdate) throws Exception;
 }
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/service/impl/CitizencardManagerServiceImpl.java b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/service/impl/CitizencardManagerServiceImpl.java
index c628015..c19bc54 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/service/impl/CitizencardManagerServiceImpl.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/service/impl/CitizencardManagerServiceImpl.java
@@ -1,14 +1,26 @@
 package com.supwisdom.dlpay.citizencard.service.impl;
 
+import com.google.gson.Gson;
+import com.supwisdom.dlpay.agent.citizencard.DlpayResp;
+import com.supwisdom.dlpay.agent.citizencard.YnrccUtil;
+import com.supwisdom.dlpay.agent.service.CitizencardPayService;
 import com.supwisdom.dlpay.api.dao.CardDao;
+import com.supwisdom.dlpay.api.dao.PersondtlDao;
 import com.supwisdom.dlpay.api.domain.TCard;
 import com.supwisdom.dlpay.citizencard.dao.CitizencardLossApplyDao;
 import com.supwisdom.dlpay.citizencard.domain.TCitizencardLossApply;
 import com.supwisdom.dlpay.citizencard.service.CitizencardManagerService;
+import com.supwisdom.dlpay.framework.dao.BusinessparaDao;
+import com.supwisdom.dlpay.framework.data.CountAmountBean;
+import com.supwisdom.dlpay.framework.domain.TBusinesspara;
 import com.supwisdom.dlpay.framework.service.SystemUtilService;
+import com.supwisdom.dlpay.framework.util.DateUtil;
 import com.supwisdom.dlpay.framework.util.StringUtil;
 import com.supwisdom.dlpay.framework.util.TradeDict;
 import com.supwisdom.dlpay.util.ConstantUtil;
+import com.supwisdom.dlpay.util.WebCheckException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -22,8 +34,17 @@
   @Autowired
   private CardDao cardDao;
   @Autowired
+  private BusinessparaDao businessparaDao;
+  @Autowired
+  private PersondtlDao persondtlDao;
+
+  @Autowired
+  private CitizencardPayService citizencardPayService;
+  @Autowired
   private SystemUtilService systemUtilService;
 
+  private static final Logger logger = LoggerFactory.getLogger(CitizencardManagerServiceImpl.class);
+
   @Override
   public List<TCitizencardLossApply> getNewApplyCitizencardLossRecords() {
     List<TCitizencardLossApply> list = citizencardLossApplyDao.findCardlossApplyRecordsByStatus(ConstantUtil.CITIZENCARD_LOSSAPPLY_STATUS_APPLY);
@@ -58,4 +79,32 @@
     }
     return citizencardLossApplyDao.save(lossApply);
   }
+
+  @Override
+  public boolean doConfirmCitizencardCheckProcess(String checkdate) throws Exception {
+    TBusinesspara param = businessparaDao.findByParakeyForUpdate(ConstantUtil.BUSINESS_CITIZENCARD_CLEARDATE);
+    if (null == param || !DateUtil.checkDatetimeValid(param.getParaval(), "yyyyMMdd") || !DateUtil.checkDatetimeValid(checkdate, "yyyyMMdd")) {
+      throw new WebCheckException("确认清算参数错误!");
+    }
+    if (!checkdate.trim().equals(DateUtil.getNewDay(param.getParaval(), 1))) {
+      throw new WebCheckException("非连续清算确认!!! 上次清算确认日期【" + checkdate + "】,本次清算确认日期【" + checkdate + "】!");
+    }
+
+    CountAmountBean sumInfo = persondtlDao.getChkClearSumInfo(checkdate.trim(), TradeDict.PAYTYPE_CITIZEN_CARD);
+    if (null == sumInfo) throw new Exception("确认清算:统计本地流水信息异常!");
+    final int totalcnt = sumInfo.getTotalcnt() == null ? 0 : sumInfo.getTotalcnt().intValue();
+    final long totalamt = sumInfo.getTotalamt() == null ? 0 : Math.round(100 * sumInfo.getTotalamt());
+
+    logger.info("【" + checkdate + "】请求清算确认:jnlcount=[" + totalcnt + "],stlamt=[" + totalamt + "]");
+    DlpayResp resp = citizencardPayService.makeSureCheckResult(checkdate.trim(), totalcnt, totalamt);
+    if (YnrccUtil.CODE_SUCCESS.equals(resp.getCode())) {
+      logger.info("【" + checkdate + "】确认清算成功!");
+      param.setParaval(checkdate);
+      businessparaDao.save(param);
+      return true;
+    }
+
+    logger.error("【" + checkdate + "】确认清算失败:" + new Gson().toJson(resp));
+    throw new WebCheckException(resp.getMessage());
+  }
 }
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/citizencard/task/CitizencardCheckConfirmTask.java b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/task/CitizencardCheckConfirmTask.java
new file mode 100644
index 0000000..3cb0417
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/citizencard/task/CitizencardCheckConfirmTask.java
@@ -0,0 +1,84 @@
+package com.supwisdom.dlpay.citizencard.task;
+
+import com.supwisdom.dlpay.api.domain.TSourceTypeCheckStatus;
+import com.supwisdom.dlpay.api.service.SourceTypeService;
+import com.supwisdom.dlpay.citizencard.service.CitizencardManagerService;
+import com.supwisdom.dlpay.framework.domain.TBusinesspara;
+import com.supwisdom.dlpay.framework.service.SystemUtilService;
+import com.supwisdom.dlpay.framework.tenant.TenantContext;
+import com.supwisdom.dlpay.framework.util.Constants;
+import com.supwisdom.dlpay.framework.util.DateUtil;
+import com.supwisdom.dlpay.framework.util.TradeDict;
+import com.supwisdom.dlpay.util.ConstantUtil;
+import com.supwisdom.dlpay.util.WebCheckException;
+import net.javacrumbs.shedlock.core.SchedulerLock;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+/**
+ * 市民卡代扣对账成功后向银行确认任务
+ */
+@Component
+public class CitizencardCheckConfirmTask {
+  @Autowired
+  private CitizencardManagerService citizencardManagerService;
+  @Autowired
+  private SystemUtilService systemUtilService;
+  @Autowired
+  private SourceTypeService sourceTypeService;
+
+  private static final Logger logger = LoggerFactory.getLogger(CitizencardCheckConfirmTask.class);
+
+  @Scheduled(cron = "${citizencard.confirm.chkdtl.cron}")
+  @SchedulerLock(name = "CitizencardChkClearConfirmTask", lockAtMostForString = "PT10M")
+  public void doConfirmCitizenCardChkdtlTask() {
+    try { long t1 = System.currentTimeMillis();
+      if (null == TenantContext.getTenantSchema()) TenantContext.setTenantSchema(Constants.DEFAULT_TENANTID);
+
+      TBusinesspara businessParam = systemUtilService.getBusinessValueForUpdateNowait(ConstantUtil.BUSINESS_CITIZENCARD_CLEARDATE);
+      if (null == businessParam || !DateUtil.checkDatetimeValid(businessParam.getParaval(), "yyyyMMdd")) {
+        logger.error("市民卡代扣对账清算确认:未找到上次清算确认日期!");
+        return;
+      }
+
+      final String lastChkDate = businessParam.getParaval().trim(); //已确认清算的日期
+
+      TSourceTypeCheckStatus checkStatus = sourceTypeService.getSourceTypeCheckStatus(TradeDict.PAYTYPE_CITIZEN_CARD);
+      if (null == checkStatus) {
+        logger.error("市民卡代扣对账清算确认:未找到【市民卡代扣】对账状态!!!");
+        return;
+      }
+      final String canChkDate = checkStatus.getSettleStatus() ? checkStatus.getCheckAccdate() : DateUtil.getNewDay(checkStatus.getCheckAccdate(), -1);
+
+      long diffDays = DateUtil.getIntervalDay(lastChkDate, canChkDate);
+      if (diffDays > 0) logger.info("执行市民卡代扣对账清算确认任务开始:");
+
+      for (int i = 1; i <= diffDays; i++) {
+        final String clearDate = DateUtil.getNewDay(lastChkDate, i);
+        try {
+          citizencardManagerService.doConfirmCitizencardCheckProcess(clearDate);
+        } catch (WebCheckException be) {
+          logger.error("市民卡代扣对账清算确认【" + clearDate + "】失败! " + be.getMessage());
+          break;
+        } catch (Exception e) {
+          logger.error("市民卡代扣对账清算确认【" + clearDate + "】失败! " + e.getMessage());
+          e.printStackTrace();
+          break;
+        }
+      }
+
+      if (diffDays > 0) {
+        long t2 = System.currentTimeMillis();
+        logger.info("执行市民卡代扣对账清算确认结束,耗时 " + (t2 - t1) + " ms");
+      }
+
+    } catch (Exception ex) {
+      logger.error("执行市民卡代扣对账确认任务报错!");
+      ex.printStackTrace();
+    }
+  }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/StringUtil.java b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/StringUtil.java
index 180679b..9b9059f 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/framework/util/StringUtil.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/framework/util/StringUtil.java
@@ -198,7 +198,7 @@
     }
 
     //18位社会信用代码判断
-    java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("^([0-9ABCDEFGHJKLMNPQRTUWXY]{2})([0-9]{6})([0-9ABCDEFGHJKLMNPQRTUWXY]{9})([0-9Y])$");
+    java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$");
     java.util.regex.Matcher match = pattern.matcher(businessLicenseNo);
     if (!match.matches()) return false; //社会信用代码校验错误!
 
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/system/service/impl/SourcetypeCheckManagerServiceImpl.java b/payapi/src/main/java/com/supwisdom/dlpay/system/service/impl/SourcetypeCheckManagerServiceImpl.java
index b8790ae..412522f 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/system/service/impl/SourcetypeCheckManagerServiceImpl.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/system/service/impl/SourcetypeCheckManagerServiceImpl.java
@@ -8,6 +8,7 @@
 import com.supwisdom.dlpay.api.domain.TSourceTypeCheckStatus;
 import com.supwisdom.dlpay.api.domain.TTransactionChkdtl;
 import com.supwisdom.dlpay.api.domain.TTransactionChkfile;
+import com.supwisdom.dlpay.framework.service.SystemUtilService;
 import com.supwisdom.dlpay.framework.tenant.TenantContext;
 import com.supwisdom.dlpay.framework.util.DateUtil;
 import com.supwisdom.dlpay.framework.util.PageResult;
@@ -44,6 +45,8 @@
 
   @PersistenceContext
   private EntityManager entityManager;
+  @Autowired
+  private SystemUtilService systemUtilService;
 
 
   @Override
@@ -65,6 +68,22 @@
     query.setFirstResult((pageNo - 1) * pageSize);
     query.setMaxResults(pageSize); //分页显示
     List<TSourceTypeCheckStatus> list = query.getResultList();
+    if (null != list && list.size() > 0) {
+      //处理【对账到】和【已对账】问题,避免修改对账逻辑和结算逻辑,这里直接处理显示问题
+      final String today = systemUtilService.getSysdatetime().getHostdate();
+      for (TSourceTypeCheckStatus stat : list) {
+        if (today.equals(stat.getCheckAccdate())) {
+          //对账到了当前日期,说明昨天已对账完成。切换下展示内容
+          stat.setCheckAccdate(DateUtil.getNewDay(stat.getCheckAccdate(), -1));
+          stat.setCheckFileOk(true);
+          stat.setCheckStatus(true);
+          stat.setRepairStatus(true);
+          stat.setSettleStatus(true);
+          stat.setRemark("对账完成"); //显示昨天已对账完成
+        }
+      }
+    }
+
     Long count = (Long) countQuery.getSingleResult();
     return new PageResult<>(count.longValue(), list);
   }
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/util/ConstantUtil.java b/payapi/src/main/java/com/supwisdom/dlpay/util/ConstantUtil.java
index 4f6d410..8efd374 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/util/ConstantUtil.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/util/ConstantUtil.java
@@ -104,4 +104,6 @@
    * */
   public static final String KAFKA_MAGTYPE_NOTICE = "dlsmk_phone_notice";
   public static final String KAFKA_MAGTYPE_CONSUME = "dlsmk_card_consume";
+
+  public static final String BUSINESS_CITIZENCARD_CLEARDATE = "citizencard.check.clear.lastdate";
 }
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/kafka_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/kafka_service_impl.kt
index fc5afd8..068ab00 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/kafka_service_impl.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/kafka_service_impl.kt
@@ -42,7 +42,7 @@
 
     @Async("kafkaSendMessageAsyncTask")
     override fun sendJpushMessage(userid: String, title: String, content: String, refno: String, extras: MutableMap<String, String>, tenantId: String?) {
-        val musers = mobileApiService.findByUseridAndStatus(userid, TradeDict.STATUS_NORMAL)
+       // val musers = mobileApiService.findByUseridAndStatus(userid, TradeDict.STATUS_NORMAL)
         var msg = TBMsg().apply {
             this.content = content
             this.title = title
@@ -52,39 +52,36 @@
             this.refno = refno
             this.extras = gson.toJson(extras)
         }
-        if (musers == null || musers.isEmpty()) {
-            msg.pushresult = "没有手机用户,消息未推送"
-            msgDao.save(msg)
-            return
-        }
+//        if (musers == null || musers.isEmpty()) {
+//            msg.pushresult = "没有手机用户,消息未推送"
+//            msgDao.save(msg)
+//            return
+//        }
         msg = msgDao.save(msg)
         var uids = ""
-        musers.forEach {
-            uids += "${it.uid},"
-            var platform = "android"
-            if ("ios".equals(it.lastloginplatform, true)) {
-                platform = "ios"
-            }
-            val message = KafkaXgMessage()
-            message.alltarget = false
-            message.callback = true
-            message.content = msg.content
-            message.title = msg.title
-            message.platform = platform
-            message.retries = 3
-            extras["refno"] = refno
-            message.custom = gson.toJson(extras)
-            message.expiretime = DateUtil.getNewTime(DateUtil.getNow(), 300)
-            message.gids = it.uid
-            if (it.lastloginplatform.isNullOrEmpty()) {
-                message.platform = "all"
-                kafkaTemplate.send(topic, msg.msgid, gson.toJson(message))
-            } else {
-                kafkaTemplate.send(topic, msg.msgid, gson.toJson(message))
-            }
-        }
-        msg.pusheduids = uids
-        msgDao.save(msg)
+//        musers.forEach {
+//            uids += "${it.uid},"
+//            var platform = "android"
+//            if ("ios".equals(it.lastloginplatform, true)) {
+//                platform = "ios"
+//            }
+//
+//        }
+//        msg.pusheduids = uids
+//        msgDao.save(msg)
+        val message = KafkaXgMessage()
+        message.alltarget = false
+        message.callback = true
+        message.content = msg.content
+        message.title = msg.title
+        message.retries = 3
+        extras["refno"] = refno
+        message.custom = gson.toJson(extras)
+        message.expiretime = DateUtil.getNewTime(DateUtil.getNow(), 300)
+        message.gids = userid
+        message.platform = "all"
+        kafkaTemplate.send(topic, msg.msgid, gson.toJson(message))
+
     }
 
     @Async("kafkaSendMessageAsyncTask")
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt
index 1214614..781ef04 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/mobile/MobileApi.kt
@@ -431,7 +431,7 @@
             //  如果银行返回已签约,保存密钥到UserSecret表
             mobileApiService.signBxy(card, SignBxyParam().apply {
                 this.uid = user.uid
-                this.userid = user.userid
+                this.userid = person.userid
                 this.secertkey = user.secertkey
                 this.rsapublic = user.rsapublic
                 this.rsaprivate = user.rsaprivate
@@ -488,7 +488,7 @@
             //  如果银行返回已签约,保存密钥到UserSecret表
             mobileApiService.signBxy(card, SignBxyParam().apply {
                 this.uid=user.uid
-                this.userid = user.userid
+                this.userid = person.userid
                 this.secertkey = user.secertkey
                 this.rsapublic = user.rsapublic
                 this.rsaprivate = user.rsaprivate
@@ -625,7 +625,7 @@
             mobileApiService.saveUser(user)
             mobileApiService.signBxy(card, SignBxyParam().apply {
                 this.uid=user.uid
-                this.userid = user.userid
+                this.userid = person.userid
                 this.secertkey = user.secertkey
                 this.rsapublic = user.rsapublic
                 this.rsaprivate = user.rsaprivate
diff --git a/payapi/src/main/resources/application.properties b/payapi/src/main/resources/application.properties
index 0881a1c..6e19153 100644
--- a/payapi/src/main/resources/application.properties
+++ b/payapi/src/main/resources/application.properties
@@ -1,9 +1,9 @@
-#######################################springboot配置 start#################################
+#######################################springboot\u914D\u7F6E start#################################
 spring.application.name=supwisdom.payapi
 spring.cloud.consul.discovery.health-check-path=${management.context-path}/api/common/version
 spring.cloud.consul.discovery.health-check-interval=10s
 spring.cloud.consul.discovery.instanceId=${spring.application.name}:${spring.application.instance_id:${random.value}}
-# 单库数据库配置
+# \u5355\u5E93\u6570\u636E\u5E93\u914D\u7F6E
 spring.jpa.show-sql=true
 spring.datasource.hikari.connection-timeout=60000
 spring.datasource.hikari.maximum-pool-size=5
@@ -23,7 +23,7 @@
 spring.thymeleaf.mode=HTML5
 spring.thymeleaf.cache=false
 spring.thymeleaf.enabled=true
-################## 全局字符编码设置 ######################
+################## \u5168\u5C40\u5B57\u7B26\u7F16\u7801\u8BBE\u7F6E ######################
 spring.http.encoding.force=true
 spring.http.encoding.charset=UTF-8
 spring.http.encoding.enabled=true
@@ -38,6 +38,7 @@
 send.delay.notice.task.cron=29 0/1 * * * ?
 points.outdate.cron=0 0 0 * * ?
 points.consume.cron=0 0 0 * * ?
+citizencard.confirm.chkdtl.cron=* */30 * * * ?
 ################################################
 # user password
 auth.password.bcrypt.length=10
diff --git a/payapi/src/main/resources/templates/system/param/busparaform.html b/payapi/src/main/resources/templates/system/param/busparaform.html
index 39dd9de..daccbb1 100644
--- a/payapi/src/main/resources/templates/system/param/busparaform.html
+++ b/payapi/src/main/resources/templates/system/param/busparaform.html
@@ -2,7 +2,7 @@
     <div class="layui-form-item">
         <label class="layui-form-label">参数名</label>
         <div class="layui-input-block">
-            <input name="parakey" placeholder="请输入参数名" type="text" class="layui-input" maxlength="30"
+            <input name="parakey" placeholder="请输入参数名" type="text" class="layui-input" maxlength="50"
                    lay-verify="required|businame" required/>
         </div>
     </div>
diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/CheckFileLine.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/CheckFileLine.java
index e3d9b69..3e6cad5 100644
--- a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/CheckFileLine.java
+++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/CheckFileLine.java
@@ -1,10 +1,10 @@
 package com.supwisdom.agent.api.bean;
 
 /**
- * * 第二行及以后:交易日期|交易时间|报文业务类型|业务系统流水号|银行流水号|付款银行卡号|收款商户银行卡号|核心记账日期|交易金额|交易摘要|
+ * * 第二行及以后:交易日期|交易时间|报文业务类型|业务系统流水号|银行流水号|付款银行卡号|收款商户银行卡号|[账号序号]|核心记账日期|交易金额|交易摘要|
  * <p>
  * private static final String[]chkFileColumnList=new String[]{"transdate","transtime","flag","refno","agentrefno",
- * "payerid","payeeid","agentdate","amount","summary"};
+ * "payerid","payeeid",["payeeno"],"agentdate","amount","summary"};
  */
 public class CheckFileLine {
   private String transdate;
@@ -14,6 +14,7 @@
   private String agentrefno;
   private String payerid;
   private String payeeid;
+  private String payeeno; //fixme: 银行测试环境修改对账单新增账号序号 2020.11.27
   private String agentdate;
   private Integer amount;
   private String summary;
@@ -97,4 +98,12 @@
   public void setSummary(String summary) {
     this.summary = summary;
   }
+
+  public String getPayeeno() {
+    return payeeno;
+  }
+
+  public void setPayeeno(String payeeno) {
+    this.payeeno = payeeno;
+  }
 }
diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/DlpayReq.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/DlpayReq.java
index e1e28e9..eb0f31b 100644
--- a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/DlpayReq.java
+++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/DlpayReq.java
@@ -106,12 +106,12 @@
         .append("<ID_NO>").append(idNo).append("</ID_NO>")
         .append("<MERCHANT_BCNO>").append(merchantBcno).append("</MERCHANT_BCNO>")
         .append("<MERCHANT_NAME>").append(merchantName).append("</MERCHANT_NAME>")
-//        .append("<MERCHANT_BCNOSEQ>").append(merchantBcnoSeqno).append("</MERCHANT_BCNOSEQ>")   //fixme: 银行测试环境新加 2020.11.27
+        .append("<MERCHANT_BCNOSEQ>").append(merchantBcnoSeqno).append("</MERCHANT_BCNOSEQ>")   //fixme: 银行测试环境新加 2020.11.27
         .append("<AMOUNT>").append(amount).append("</AMOUNT>")
-//        .append("<SCENARIO>").append(scenario).append("</SCENARIO>")  //fixme: 银行测试环境新加字段 2020.11.27
+        .append("<SCENARIO>").append(scenario).append("</SCENARIO>")  //fixme: 银行测试环境新加字段 2020.11.27
         .append("<DESCRIPTION>").append(description).append("</DESCRIPTION>")
-        .append("<MAC>").append(MD5.encodeByMD5ForYnrcc(merchantBcno + bcNo + amount)).append("</MAC>")
-//        .append("<MAC>").append(MD5.encodeByMD5ForYnrcc(merchantBcno + bcNo + amount + "ynnx@2020|dlsmk" + sn)).append("</MAC>")  //fixme: 银行测试环境修改MAC算法 2020.11.27
+//        .append("<MAC>").append(MD5.encodeByMD5ForYnrcc(merchantBcno + bcNo + amount)).append("</MAC>")
+        .append("<MAC>").append(MD5.encodeByMD5ForYnrcc(merchantBcno + bcNo + amount + "ynnx@2020|dlsmk" + sn)).append("</MAC>")  //fixme: 银行测试环境修改MAC算法 2020.11.27
         .append("</root>");
     return String.format("%08d", xml.toString().getBytes("GBK").length) + xml.toString();
   }
@@ -163,7 +163,7 @@
         .append("<SN>").append(sn).append("</SN>")
         .append("<DZDATE>").append(chkdate).append("</DZDATE>")
         .append("<MERCHANT_BCNO>").append("</MERCHANT_BCNO>")
-//        .append("<MERCHANT_BCNOSEQ>").append("</MERCHANT_BCNOSEQ>")   //fixme: 银行测试环境新加商户银行卡序号字段 2020.11.27
+        .append("<MERCHANT_BCNOSEQ>").append("</MERCHANT_BCNOSEQ>")   //fixme: 银行测试环境新加商户银行卡序号字段 2020.11.27
         .append("</root>");
     return String.format("%08d", xml.toString().getBytes("GBK").length) + xml.toString();
   }
@@ -179,8 +179,8 @@
         .append("<TRANSDATE>").append(transdate).append("</TRANSDATE>")
         .append("<TRANSTIME>").append(transtime).append("</TRANSTIME>")
         .append("<SN>").append(sn).append("</SN>")
-        .append("<STLTRXDATE>").append(stltrxdate).append("</STLTRXDATE>")
-//        .append("<STLSNDATE>").append(stltrxdate).append("</STLSNDATE>")  //fixme: 银行测试环境改了字段名(STLTRXDATE 改为 STLSNDATE) 2020.11.27
+//        .append("<STLTRXDATE>").append(stltrxdate).append("</STLTRXDATE>")
+        .append("<STLSNDATE>").append(stltrxdate).append("</STLSNDATE>")  //fixme: 银行测试环境改了字段名(STLTRXDATE 改为 STLSNDATE) 2020.11.27
         .append("<STLAMT>").append(stlamt).append("</STLAMT>")
         .append("<JNLCOUNT>").append(jnlcount).append("</JNLCOUNT>")
         .append("</root>");
diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/controller/YnrccApiController.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/controller/YnrccApiController.java
index e3f9ea1..f445df7 100644
--- a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/controller/YnrccApiController.java
+++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/controller/YnrccApiController.java
@@ -40,10 +40,10 @@
 
   /**
    * 第一行:总笔数|总金额|代扣总笔数|代扣总金额|退款总笔数|退款总金额|
-   * 第二行及以后:交易日期|交易时间|报文业务类型|业务系统流水号|银行流水号|付款银行卡号|收款商户银行卡号|核心记账日期|交易金额|交易摘要|
+   * 第二行及以后:交易日期|交易时间|报文业务类型|业务系统流水号|银行流水号|付款银行卡号|收款商户银行卡号|[账号序号]|核心记账日期|交易金额|交易摘要|
    */
   private static final String[] chkFileColumnList = new String[]{"transdate", "transtime", Constant.COL_FLAG,
-      Constant.COL_REFNO, Constant.COL_AGENT_REFNO, Constant.COL_PAYERID, Constant.COL_PAYEEID,
+      Constant.COL_REFNO, Constant.COL_AGENT_REFNO, Constant.COL_PAYERID, Constant.COL_PAYEEID, Constant.COL_BANKSEQNO,
       Constant.COL_AGENT_DATE, Constant.COL_AMOUNT, Constant.COL_SUMMARY};
 
   private static final String chkFileDelimiter = "\\|";
@@ -483,16 +483,18 @@
           flag = Constant.FLAG_PAY;
           fileHeader.setPayCount(fileHeader.getPayCount() - 1);
           fileHeader.setPayAmount(fileHeader.getPayAmount() - record.getAmount());
+          fileHeader.setTotalAmount(fileHeader.getTotalAmount() - record.getAmount());
         } else if (FLAG_REFUND.equals(record.getFlag())) {
           amount = record.getAmount();
           flag = Constant.FLAG_REFUND;
           fileHeader.setRefundCount(fileHeader.getRefundCount() - 1);
           fileHeader.setRefundAmount(fileHeader.getRefundAmount() - record.getAmount());
+          fileHeader.setTotalAmount(fileHeader.getTotalAmount() + record.getAmount());
         } else {
           throw new IllegalArgumentException("对账文件【报文业务类型】错误,行数 " + lineno + " 。");
         }
         fileHeader.setTotalCount(fileHeader.getTotalCount() - 1);
-        fileHeader.setTotalAmount(fileHeader.getTotalAmount() - record.getAmount());
+//        fileHeader.setTotalAmount(fileHeader.getTotalAmount() - record.getAmount());
         writeLine(output, record.getRefno(), record.getAgentrefno(), record.getAgentdate(),
             flag, record.getPayerid(), record.getPayeeid(), Constant.STATUS_SUCCESS,
             amount, record.getSummary(), lineno - 1);