重构异步任务
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/framework/task/TaskExecuteTimes.java b/payapi/src/main/java/com/supwisdom/dlpay/framework/task/TaskExecuteTimes.java
new file mode 100644
index 0000000..3cea384
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/framework/task/TaskExecuteTimes.java
@@ -0,0 +1,24 @@
+package com.supwisdom.dlpay.framework.task;
+
+public class TaskExecuteTimes {
+  private Integer times = 0;
+
+  public Integer getTimes() {
+    return times;
+  }
+
+  public void setTimes(Integer times) {
+    this.times = times;
+  }
+
+  public void incr() {
+    this.times += 1;
+  }
+
+  public void decr() {
+    this.times -= 1;
+    if (this.times < 0) {
+      this.times = 0;
+    }
+  }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/framework/task/TaskRetryException.java b/payapi/src/main/java/com/supwisdom/dlpay/framework/task/TaskRetryException.java
new file mode 100644
index 0000000..0a5b2e8
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/framework/task/TaskRetryException.java
@@ -0,0 +1,22 @@
+package com.supwisdom.dlpay.framework.task;
+
+public class TaskRetryException extends Throwable {
+  public TaskRetryException() {
+  }
+
+  public TaskRetryException(String message) {
+    super(message);
+  }
+
+  public TaskRetryException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  public TaskRetryException(Throwable cause) {
+    super(cause);
+  }
+
+  public TaskRetryException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+    super(message, cause, enableSuppression, writableStackTrace);
+  }
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/system/controller/SettlementLogController.java b/payapi/src/main/java/com/supwisdom/dlpay/system/controller/SettlementLogController.java
index e94a27f..a53ad90 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/system/controller/SettlementLogController.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/system/controller/SettlementLogController.java
@@ -7,6 +7,7 @@
 import com.supwisdom.dlpay.framework.util.WebConstant;
 import com.supwisdom.dlpay.system.bean.SettleLogSearchBean;
 import com.supwisdom.dlpay.system.service.SettlementLogService;
+import com.supwisdom.multitenant.TenantContextHolder;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Controller;
@@ -14,7 +15,7 @@
 
 /**
  * 结算日志
- * */
+ */
 @Controller
 public class SettlementLogController {
   @Autowired
@@ -36,7 +37,7 @@
       Integer pageSize = searchBean.getLimit();
       if (null == pageNo || pageNo < 1) pageNo = WebConstant.PAGENO_DEFAULT;
       if (null == pageSize || pageSize < 1) pageSize = WebConstant.PAGESIZE_DEFAULT;
-      return settlementLogService.getSettleLogPage(searchBean,pageNo,pageSize);
+      return settlementLogService.getSettleLogPage(searchBean, pageNo, pageSize);
     } catch (Exception e) {
       e.printStackTrace();
       return new PageResult<>(99, "系统查询错误");
@@ -48,7 +49,7 @@
   @ResponseBody
   public JsonResult doSettlement() {
     try {
-      settlementAsyncTask.doHandSettleTask();
+      settlementAsyncTask.doHandSettleTask(TenantContextHolder.getContext().getTenant());
       return JsonResult.ok("异步结算中,请查询日志查看结算结果");
     } catch (Exception e) {
       e.printStackTrace();
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/PayApiApplication.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/PayApiApplication.kt
index 4cd2abe..6118efb 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/PayApiApplication.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/PayApiApplication.kt
@@ -46,6 +46,8 @@
 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer
 import org.springframework.data.redis.serializer.StringRedisSerializer
 import org.springframework.http.client.SimpleClientHttpRequestFactory
+import org.springframework.retry.annotation.EnableRetry
+import org.springframework.scheduling.annotation.EnableAsync
 import org.springframework.scheduling.annotation.EnableScheduling
 import org.springframework.stereotype.Component
 import org.springframework.web.client.RestTemplate
@@ -243,6 +245,8 @@
 @EnableSessionTenantInterceptor
 @EnableJwtTenantInterceptor
 @ServletComponentScan
+@EnableRetry
+@EnableAsync
 class PayApiApplication : SpringBootServletInitializer() {
 
     override fun configure(builder: SpringApplicationBuilder): SpringApplicationBuilder {
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/wechat_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/wechat_service.kt
index 8f08241..683d186 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/wechat_service.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/wechat_service.kt
@@ -4,7 +4,6 @@
 import com.supwisdom.dlpay.agent.AgentPayService
 import com.supwisdom.dlpay.agent.AgentResponse
 import com.supwisdom.dlpay.agent.domain.QrcodePayTrans
-import com.supwisdom.dlpay.api.bean.BaseResp
 import com.supwisdom.dlpay.api.domain.TTransactionMain
 import com.supwisdom.dlpay.api.service.ConsumePayService
 import com.supwisdom.dlpay.framework.util.TradeCode
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/async_tasks.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/async_tasks.kt
index b2b5ed4..d9c159e 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/async_tasks.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/async_tasks.kt
@@ -13,26 +13,27 @@
 import com.supwisdom.dlpay.exception.TransactionException
 import com.supwisdom.dlpay.framework.service.DayendSettleService
 import com.supwisdom.dlpay.framework.service.SystemUtilService
-import com.supwisdom.dlpay.framework.util.Constants
+import com.supwisdom.dlpay.framework.task.TaskRetryException
 import com.supwisdom.dlpay.framework.util.StringUtil
 import com.supwisdom.dlpay.util.ConstantUtil
 import com.supwisdom.multitenant.TenantContextHolder
-import com.supwisdom.multitenant.TenantDetailsProvider
+import com.supwisdom.multitenant.TenantDetails
 import mu.KotlinLogging
 import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.context.annotation.Bean
 import org.springframework.context.annotation.Configuration
+import org.springframework.retry.annotation.Backoff
+import org.springframework.retry.annotation.Recover
+import org.springframework.retry.annotation.Retryable
 import org.springframework.scheduling.annotation.Async
 import org.springframework.scheduling.annotation.AsyncConfigurer
-import org.springframework.scheduling.annotation.EnableAsync
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
 import org.springframework.stereotype.Component
 import java.lang.reflect.Method
 import java.util.concurrent.Executor
 
 @Configuration
-@EnableAsync
 class SpringAsyncConfig : AsyncConfigurer {
     @Bean(value = ["shopAccBalanceUpdater"])
     fun threadPoolExecutor(): Executor {
@@ -90,16 +91,14 @@
     @Autowired
     private lateinit var shopaccService: ShopaccService
 
-    @Autowired
-    private lateinit var tenantDetailsProvider: TenantDetailsProvider
-
     @Async("shopAccBalanceUpdater")
-    fun updateShopBalance(shopdtl: TShopdtl) {
-        TenantContextHolder.getContext().tenant = tenantDetailsProvider.createDetailsById(shopdtl.tenantid)
+    fun updateShopBalance(details: TenantDetails, shopdtl: TShopdtl) {
+        TenantContextHolder.getContext().tenant = details
         shopaccService.recalcShopBalance(shopdtl.refno, true)
     }
 }
 
+
 @Component
 class AgentQueryResultTask {
     private val logger = KotlinLogging.logger { }
@@ -116,68 +115,66 @@
     @Autowired
     private lateinit var systemUtilService: SystemUtilService
 
-    @Autowired
-    private lateinit var tenantDetailsProvider: TenantDetailsProvider
+    @Recover
+    fun quertRecover(ex: TaskRetryException, details: TenantDetails,
+                     transaction: TTransactionMain) {
+        TenantContextHolder.getContext().tenant = details
+        logger.error("查询refno=[${transaction.refno}]流水结果超最大查询次数[${YnrccUtil.QUERY_MAX_COUNT}]")
+        dtlQueryResultService.saveOrUpdateDtlQuery(TDtlQuery().apply {
+            this.accdate = transaction.accdate
+            this.refno = transaction.refno
+            this.status = ConstantUtil.QUERYTYPE_NEED_QUERY
+            this.remark = null
+            this.qcnt = 0
+            this.lastsaved = systemUtilService.sysdatetime.sysdate
+        })
+    }
 
     @Async("queryAgentPayResult")
-    fun queryResult(transaction: TTransactionMain, qcnt: Int) {
-        try {
-            TenantContextHolder.getContext().tenant = tenantDetailsProvider.createDetailsById(transaction.tenantid)
+    @Retryable(value = [TaskRetryException::class], maxAttempts = YnrccUtil.QUERY_MAX_COUNT, backoff = Backoff(value = 3000))
+    fun queryResult(details: TenantDetails, transaction: TTransactionMain) {
+        TenantContextHolder.getContext().tenant = details
 
-            if (qcnt >= YnrccUtil.QUERY_MAX_COUNT) {
-                //查询超最大次数
-                logger.error("查询refno=[${transaction.refno}]流水结果超最大查询次数[${YnrccUtil.QUERY_MAX_COUNT}]")
-
-                //保存进查询表,定时扫描任务去查询
-                dtlQueryResultService.saveOrUpdateDtlQuery(TDtlQuery().apply {
-                    this.accdate = transaction.accdate
-                    this.refno = transaction.refno
-                    this.status = ConstantUtil.QUERYTYPE_NEED_QUERY
-                    this.remark = null
-                    this.qcnt = 0
-                    this.lastsaved = systemUtilService.sysdatetime.sysdate
-                })
-                return
-            }
-
+        val resp = try {
             val service = agentPayServiceContext.findAgentPayService<Any>(transaction.sourceType)
-
-            logger.info("refno=[${transaction.refno}]开始第" + (qcnt + 1) + "次查询支付结果:")
-            val resp = service.query(transaction)
-            when (resp.code) {
-                AgentCode.SUCCESS -> {
-                    //查询成功
-                    when (resp.dtlStatus) {
-                        DtlStatus.SUCCESS ->
-                            transactionService.success(transaction.refno, resp.agentRefno, false) //流水成功
-                        DtlStatus.REFUND -> {
-                            //流水已退款 TODO:流水成功后才退款,无查询原成功流水逻辑
-                            logger.error("refno=[${transaction.refno}]查询结果为:已退款!!!")
-                            return
-                        }
-                        DtlStatus.PARTIAL_REFUND -> {
-                            //流水已部分退款 TODO:暂无逻辑
-                            logger.error("refno=[${transaction.refno}]查询结果为:已部分退款!!!")
-                            return
-                        }
-                        else -> {
-                            //流水失败
-                            transactionService.fail(transaction.refno, "查询流水状态为交易失败")
-                        }
-                    }
-                }
-                AgentCode.REFNO_NOT_EXISTS ->
-                    transactionService.fail(transaction.refno, "银行流水不存在") //银行返回流水不存在
-                AgentCode.REQUIRE_QUERY -> {
-                    queryResult(transaction, qcnt + 1)  //查询次数加1
-                }
-                else -> {
-                    //其他明确错误,查询失败
-                    logger.error("查询refno=[${transaction.refno}]流水结果返回失败:code=[${resp.agentCode}],message=[${resp.agentMsg}]")
-                }
-            }
+            logger.info("refno=[${transaction.refno}]开始查询支付结果:")
+            service.query(transaction)
         } catch (ex: Exception) {
             ex.printStackTrace()
+            throw ex
+        }
+
+        when (resp.code) {
+            AgentCode.SUCCESS -> {
+                //查询成功
+                when (resp.dtlStatus) {
+                    DtlStatus.SUCCESS ->
+                        transactionService.success(transaction.refno, resp.agentRefno, false) //流水成功
+                    DtlStatus.REFUND -> {
+                        //流水已退款 TODO:流水成功后才退款,无查询原成功流水逻辑
+                        logger.error("refno=[${transaction.refno}]查询结果为:已退款!!!")
+                        return
+                    }
+                    DtlStatus.PARTIAL_REFUND -> {
+                        //流水已部分退款 TODO:暂无逻辑
+                        logger.error("refno=[${transaction.refno}]查询结果为:已部分退款!!!")
+                        return
+                    }
+                    else -> {
+                        //流水失败
+                        transactionService.fail(transaction.refno, "查询流水状态为交易失败")
+                    }
+                }
+            }
+            AgentCode.REFNO_NOT_EXISTS ->
+                transactionService.fail(transaction.refno, "银行流水不存在") //银行返回流水不存在
+            AgentCode.REQUIRE_QUERY -> {
+                throw TaskRetryException()
+            }
+            else -> {
+                //其他明确错误,查询失败
+                logger.error("查询refno=[${transaction.refno}]流水结果返回失败:code=[${resp.agentCode}],message=[${resp.agentMsg}]")
+            }
         }
     }
 }
@@ -192,13 +189,10 @@
 
     private val logger = KotlinLogging.logger { }
 
-    @Autowired
-    private lateinit var tenantDetailsProvider: TenantDetailsProvider
-
     @Async("handSettlementAsyncTask")
-    fun doHandSettleTask() {
+    fun doHandSettleTask(details: TenantDetails) {
         logger.info("进入手动发起的异步结算:")
-        TenantContextHolder.getContext().tenant = tenantDetailsProvider.createDetailsById(Constants.DEFAULT_TENANTID)
+        TenantContextHolder.getContext().tenant = details
         val settleLog = dayendSettleService.doCreateSettleLog() //记录日志
         try {
             val ret = dayendSettleService.doDayendSettle()
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
index 7cad44b..ac73959 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
@@ -17,7 +17,9 @@
 import com.supwisdom.dlpay.exception.TransactionCheckException
 import com.supwisdom.dlpay.framework.ResponseBodyBuilder
 import com.supwisdom.dlpay.framework.service.SystemUtilService
+import com.supwisdom.dlpay.framework.task.TaskExecuteTimes
 import com.supwisdom.dlpay.framework.util.*
+import com.supwisdom.multitenant.TenantContextHolder
 import org.apache.commons.lang3.StringUtils
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.data.redis.core.RedisTemplate
@@ -71,7 +73,7 @@
             return ResponseEntity.ok(ResponseBodyBuilder.create()
                     .success(QueryTransDtlResponse(it.refno, it.outTradeNo, it.shopDtl.amount,
                             it.status, it.sourceType, it.personDtl.payinfo, it.reverseFlag,
-                            it.shopDtl.transdesc,it.personDtl.remark), "查询成功"))
+                            it.shopDtl.transdesc, it.personDtl.remark), "查询成功"))
         } ?: return ResponseEntity.ok(ResponseBodyBuilder.create()
                 .fail(TradeErrorCode.TRANSACTION_NOT_EXISTS, "流水不存在"))
     }
@@ -247,7 +249,7 @@
                 }
             AgentCode.REQUIRE_QUERY -> {
                 //去查询
-                agentQueryResultTask.queryResult(dtl, 0)
+                agentQueryResultTask.queryResult(TenantContextHolder.getContext().tenant, dtl)
                 return ResponseEntity.ok(ResponseBodyBuilder.create()
                         .fail(CitizenPayResponse(dtl.refno,
                                 dtl.outTradeNo,
@@ -300,7 +302,7 @@
                 }
                 AgentCode.REQUIRE_QUERY -> {
                     //待查询
-                    agentQueryResultTask.queryResult(cancelTrans, 0)
+                    agentQueryResultTask.queryResult(TenantContextHolder.getContext().tenant, cancelTrans)
                     return ResponseEntity.ok(ResponseBodyBuilder.create()
                             .fail(PayReverseResponse(cancelTrans.refno),
                                     TradeErrorCode.WAIT_QUERY_RESULT, "请查询撤销结果"))
@@ -341,7 +343,8 @@
                 setTransInfo(param.transdate, param.transtime, mainDtl.transCode, mainDtl.sourceType)
                 setOutTransInfo(mainDtl.outId, param.requestbillno)
             }
-            val refundTrans = builder.refundInit(mainDtl.refno, param.refundAmount / 100.0, transactionService)
+            val refundTrans = builder.refundInit(mainDtl.refno,
+                    param.refundAmount / 100.0, transactionService)
             transactionService.wip(refundTrans.refno)
             val service = createAgentService<Any>(mainDtl.sourceType)
             val resp = service.refund(refundTrans)
@@ -355,7 +358,7 @@
                 }
                 AgentCode.REQUIRE_QUERY -> {
                     //待查询
-                    agentQueryResultTask.queryResult(refundTrans, 0)
+                    agentQueryResultTask.queryResult(TenantContextHolder.getContext().tenant, refundTrans)
                     return ResponseEntity.ok(ResponseBodyBuilder.create()
                             .fail(PayReverseResponse(refundTrans.refno),
                                     TradeErrorCode.WAIT_QUERY_RESULT, "请查询退款结果"))
@@ -457,7 +460,8 @@
     }
 
     @RequestMapping("/qrcode/init", method = [RequestMethod.POST, RequestMethod.GET])
-    fun qrcodePayInit(@Validated(InitAction::class) @RequestBody param: QrcodePayParam): ResponseEntity<ApiResponse> {
+    fun qrcodePayInit(@Validated(InitAction::class) @RequestBody param: QrcodePayParam)
+            : ResponseEntity<ApiResponse> {
         val apiResp = QrcodePayResponse()
         // 1. 检查 qrcode
         val qrcode = agentServiceProxy.qrcodeMatch(param.qrcode)
@@ -538,7 +542,8 @@
     private fun qrcodeSummary(st: TSourceType): String = st.paydesc + "扫码付"
 
     @PostMapping("/qrcode/confirm")
-    fun qrcodePayConfirm(@Validated(ConfirmAction::class) @RequestBody param: QrcodePayParam): ResponseEntity<ApiResponse> {
+    fun qrcodePayConfirm(@Validated(ConfirmAction::class) @RequestBody param: QrcodePayParam)
+            : ResponseEntity<ApiResponse> {
         //1. 交易检查
         val apiResponse = QrcodePayResponse()
         val qrcodeTrans = agentServiceProxy.qrcodePayTransFindByMerchIdAndBillno(param.shopaccno,
@@ -764,12 +769,14 @@
                 return ResponseEntity.ok(ResponseBodyBuilder.create()
                         .fail(ThirdPayResponse(dtl.refno,
                                 dtl.outTradeNo,
-                                dtl.shopDtl.amount, resp.agentBody), TradeErrorCode.WAIT_QUERY_RESULT, "请查询支付结果"))
+                                dtl.shopDtl.amount, resp.agentBody),
+                                TradeErrorCode.WAIT_QUERY_RESULT, "请查询支付结果"))
             }
             else -> //失败
                 transactionService.fail(param.refno, resp.agentMsg).let {
                     return ResponseEntity.ok(ResponseBodyBuilder.create()
-                            .fail(ThirdPayResponse(dtl.refno, dtl.outTradeNo, dtl.shopDtl.amount, resp.agentBody),
+                            .fail(ThirdPayResponse(dtl.refno, dtl.outTradeNo,
+                                    dtl.shopDtl.amount, resp.agentBody),
                                     TradeErrorCode.BUSINESS_DEAL_ERROR, "交易扣费失败-${resp.agentMsg}"))
                 }
         }
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_sourcetype_chk.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_sourcetype_chk.kt
index e3ab9e4..c57ddb1 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_sourcetype_chk.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_sourcetype_chk.kt
@@ -15,6 +15,7 @@
 import com.supwisdom.dlpay.framework.util.DateUtil
 import com.supwisdom.dlpay.util.ConstantUtil
 import com.supwisdom.multitenant.TenantContextHolder
+import com.supwisdom.multitenant.TenantDetails
 import com.supwisdom.multitenant.TenantDetailsProvider
 import mu.KotlinLogging
 import net.javacrumbs.shedlock.core.SchedulerLock
@@ -176,10 +177,10 @@
             // 对账文件是否下载完成
             if (it.checkFileOk && !it.forceRecheck) {
                 // 开始对账
-                sourceTypeCheckExecutor.reconciliation(it)
+                sourceTypeCheckExecutor.reconciliation(TenantContextHolder.getContext().tenant, it)
             } else {
                 // 开始下载对账文件
-                sourceTypeCheckExecutor.checkAndDownloadChkfile(it)
+                sourceTypeCheckExecutor.checkAndDownloadChkfile(TenantContextHolder.getContext().tenant, it)
             }
         }.toMutableList()
 
@@ -192,7 +193,8 @@
                     if (result.code == SourceTypeCheckExecutor.SUCCESS) {
                         // 完成对账文件下载 但 还未对账
                         if (result.status.checkFileOk && !result.status.settleStatus) {
-                            newPrcResult.add(sourceTypeCheckExecutor.reconciliation(result.status))
+                            newPrcResult.add(sourceTypeCheckExecutor.reconciliation(
+                                    TenantContextHolder.getContext().tenant, result.status))
                         } else if (!result.status.checkFileOk) {
                             logger.error {
                                 "sourcetype <${result.status.sourceType}> get checkfile error," +
@@ -205,7 +207,8 @@
                             }
                         }
                     } else if (result.code == SourceTypeCheckExecutor.WAIT) {
-                        newPrcResult.add(sourceTypeCheckExecutor.checkAndDownloadChkfile(result.status))
+                        newPrcResult.add(sourceTypeCheckExecutor.checkAndDownloadChkfile(
+                                TenantContextHolder.getContext().tenant, result.status))
                     } else {
                         logger.error {
                             "sourcetype <${result.status.sourceType}> 对账状任务错误, error=" +
@@ -249,9 +252,6 @@
     @Autowired
     private lateinit var sourceTypeService: SourceTypeService
 
-    @Autowired
-    private lateinit var tenantDetailsProvider: TenantDetailsProvider
-
     private val logger = KotlinLogging.logger { }
 
     private fun getProvider(sourcetype: String): CheckFileProvider? {
@@ -274,10 +274,10 @@
     }
 
     @Async("sourcetypeCheckTaskExecutor")
-    fun checkAndDownloadChkfile(checkStatus: TSourceTypeCheckStatus): Future<ExecutorResult> {
+    fun checkAndDownloadChkfile(tenantDetails: TenantDetails, checkStatus: TSourceTypeCheckStatus): Future<ExecutorResult> {
         // 2. 根据对账日期下载对账文件
         try {
-            TenantContextHolder.getContext().tenant = tenantDetailsProvider.defaultTenant()
+            TenantContextHolder.getContext().tenant = tenantDetails
             if (checkStatus.settleStatus) {
                 return AsyncResult(ExecutorResult(checkStatus, FAIL, "[${checkStatus.checkAccdate}]日对账已完成"))
             }
@@ -318,9 +318,9 @@
     }
 
     @Async("sourcetypeCheckTaskExecutor")
-    fun reconciliation(checkStatus: TSourceTypeCheckStatus): Future<ExecutorResult> {
+    fun reconciliation(tenantDetails: TenantDetails, checkStatus: TSourceTypeCheckStatus): Future<ExecutorResult> {
         // 3. 完成对账
-        TenantContextHolder.getContext().tenant = tenantDetailsProvider.defaultTenant()
+        TenantContextHolder.getContext().tenant = tenantDetails
         if (!checkStatus.checkFileOk) {
             return AsyncResult(ExecutorResult(checkStatus, FAIL, "checkAccdate=[${checkStatus.checkAccdate}]对账单未完成下载,不能对账"))
         } else if (checkStatus.settleStatus) {
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_task.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_task.kt
index 7b477dd..ba4b5e9 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_task.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_task.kt
@@ -78,75 +78,85 @@
         if (ConstantUtil.QUERYTYPE_NEED_QUERY != dtlQuery.status) {
             return //已结束
         }
-        val dtl = consumePayService.getTransactionMainDtl(dtlQuery.refno, null, null)
-        if (null == dtl) {
-            dtlQuery.qcnt = dtlQuery.qcnt + 1
-            dtlQuery.status = ConstantUtil.QUERYTYPE_QUERY_FINISH
-            dtlQuery.remark = "refno未找到流水"
-            dtlQueryResultService.saveOrUpdateDtlQuery(dtlQuery)
-            return
-        } else if (TradeDict.DTL_STATUS_WIP != dtl.status) {
-            dtlQuery.qcnt = dtlQuery.qcnt + 1
-            dtlQuery.status = ConstantUtil.QUERYTYPE_QUERY_FINISH
-            dtlQuery.remark = "原始流水非wip状态"
-            dtlQueryResultService.saveOrUpdateDtlQuery(dtlQuery)
-            return
-        } else if (TradeDict.PAYTYPE_CITIZEN_CARD != dtl.sourceType) {
-            //fixme: 现仅供大理农商卡对接查询
-            dtlQuery.qcnt = dtlQuery.qcnt + 1
-            dtlQuery.status = ConstantUtil.QUERYTYPE_QUERY_FINISH
-            dtlQuery.remark = "非大理市民卡支付流水"
-            dtlQueryResultService.saveOrUpdateDtlQuery(dtlQuery)
-            return
-        }
-
-        val service = agentPayServiceContext.findAgentPayService<Any>(dtl.sourceType)
-        val resp = service.query(dtl)
-        when (resp.code) {
-            AgentCode.SUCCESS -> {
-                //查询成功
-                when (resp.dtlStatus) {
-                    DtlStatus.SUCCESS -> {
-                        transactionService.success(dtl.refno, resp.agentRefno, false) //流水成功
-                        dtlQuery.qcnt = dtlQuery.qcnt + 1
-                        dtlQuery.status = ConstantUtil.QUERYTYPE_QUERY_FINISH
-                        dtlQuery.remark = "查询成功,流水为付款成功状态"
-                        dtlQueryResultService.saveOrUpdateDtlQuery(dtlQuery)
-                        return
+        val dtl = consumePayService.getTransactionMainDtl(dtlQuery.refno, null, null)//其他明确错误,后续再查询
+        //银行返回流水不存在
+        //流水失败
+        //流水成功
+        //查询成功
+        when {
+            null == dtl -> {
+                dtlQuery.qcnt = dtlQuery.qcnt + 1
+                dtlQuery.status = ConstantUtil.QUERYTYPE_QUERY_FINISH
+                dtlQuery.remark = "refno未找到流水"
+                dtlQueryResultService.saveOrUpdateDtlQuery(dtlQuery)
+                return
+            }
+            TradeDict.DTL_STATUS_WIP != dtl.status -> {
+                dtlQuery.qcnt = dtlQuery.qcnt + 1
+                dtlQuery.status = ConstantUtil.QUERYTYPE_QUERY_FINISH
+                dtlQuery.remark = "原始流水非wip状态"
+                dtlQueryResultService.saveOrUpdateDtlQuery(dtlQuery)
+                return
+            }
+            TradeDict.PAYTYPE_CITIZEN_CARD != dtl.sourceType -> {
+                //fixme: 现仅供大理农商卡对接查询
+                dtlQuery.qcnt = dtlQuery.qcnt + 1
+                dtlQuery.status = ConstantUtil.QUERYTYPE_QUERY_FINISH
+                dtlQuery.remark = "非大理市民卡支付流水"
+                dtlQueryResultService.saveOrUpdateDtlQuery(dtlQuery)
+                return
+            }
+            else -> {
+                val service = agentPayServiceContext.findAgentPayService<Any>(dtl.sourceType)
+                val resp = service.query(dtl)
+                when (resp.code) {
+                    AgentCode.SUCCESS -> {
+                        //查询成功
+                        when (resp.dtlStatus) {
+                            DtlStatus.SUCCESS -> {
+                                transactionService.success(dtl.refno, resp.agentRefno, false) //流水成功
+                                dtlQuery.qcnt = dtlQuery.qcnt + 1
+                                dtlQuery.status = ConstantUtil.QUERYTYPE_QUERY_FINISH
+                                dtlQuery.remark = "查询成功,流水为付款成功状态"
+                                dtlQueryResultService.saveOrUpdateDtlQuery(dtlQuery)
+                                return
+                            }
+                            DtlStatus.REFUND, DtlStatus.PARTIAL_REFUND -> {
+                                dtlQuery.qcnt = dtlQuery.qcnt + 1
+                                dtlQuery.status = ConstantUtil.QUERYTYPE_QUERY_FINISH
+                                dtlQuery.remark = "查询成功,流水为已退款或部分退款状态"
+                                dtlQueryResultService.saveOrUpdateDtlQuery(dtlQuery)
+                                return
+                            }
+                            else -> {
+                                //流水失败
+                                transactionService.fail(dtl.refno, "查询流水状态为交易失败")
+                                dtlQuery.qcnt = dtlQuery.qcnt + 1
+                                dtlQuery.status = ConstantUtil.QUERYTYPE_QUERY_FINISH
+                                dtlQuery.remark = "查询成功,流水为失败状态"
+                                dtlQueryResultService.saveOrUpdateDtlQuery(dtlQuery)
+                                return
+                            }
+                        }
                     }
-                    DtlStatus.REFUND, DtlStatus.PARTIAL_REFUND -> {
+                    AgentCode.REFNO_NOT_EXISTS -> {
+                        transactionService.fail(dtl.refno, "银行流水不存在") //银行返回流水不存在
                         dtlQuery.qcnt = dtlQuery.qcnt + 1
                         dtlQuery.status = ConstantUtil.QUERYTYPE_QUERY_FINISH
-                        dtlQuery.remark = "查询成功,流水为已退款或部分退款状态"
+                        dtlQuery.remark = "查询成功,返回流水不存在"
                         dtlQueryResultService.saveOrUpdateDtlQuery(dtlQuery)
                         return
                     }
                     else -> {
-                        //流水失败
-                        transactionService.fail(dtl.refno, "查询流水状态为交易失败")
+                        //其他明确错误,后续再查询
                         dtlQuery.qcnt = dtlQuery.qcnt + 1
-                        dtlQuery.status = ConstantUtil.QUERYTYPE_QUERY_FINISH
-                        dtlQuery.remark = "查询成功,流水为失败状态"
+                        dtlQuery.remark = "查询失败!${resp.agentMsg}"
                         dtlQueryResultService.saveOrUpdateDtlQuery(dtlQuery)
                         return
                     }
                 }
             }
-            AgentCode.REFNO_NOT_EXISTS -> {
-                transactionService.fail(dtl.refno, "银行流水不存在") //银行返回流水不存在
-                dtlQuery.qcnt = dtlQuery.qcnt + 1
-                dtlQuery.status = ConstantUtil.QUERYTYPE_QUERY_FINISH
-                dtlQuery.remark = "查询成功,返回流水不存在"
-                dtlQueryResultService.saveOrUpdateDtlQuery(dtlQuery)
-                return
-            }
-            else -> {
-                //其他明确错误,后续再查询
-                dtlQuery.qcnt = dtlQuery.qcnt + 1
-                dtlQuery.remark = "查询失败!${resp.agentMsg}"
-                dtlQueryResultService.saveOrUpdateDtlQuery(dtlQuery)
-                return
-            }
         }
+
     }
 }
\ No newline at end of file
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt
index 2e0ff91..ad2402d 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt
@@ -6,6 +6,7 @@
 import com.supwisdom.dlpay.api.domain.TTransactionMain
 import com.supwisdom.dlpay.exception.TransactionProcessException
 import com.supwisdom.dlpay.framework.util.TradeErrorCode
+import com.supwisdom.multitenant.TenantContextHolder
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.dao.DataAccessException
 import org.springframework.stereotype.Service
@@ -100,7 +101,7 @@
     fun success(refno: String, sourcetypeRefno: String, accdateUpdate: Boolean? = true): TTransactionMain {
         return transactionService.success(refno, sourcetypeRefno, accdateUpdate).also {
             if (it.shop) {
-                shopAccBalanceAsyncTask.updateShopBalance(it.shopDtl)
+                shopAccBalanceAsyncTask.updateShopBalance(TenantContextHolder.getContext().tenant, it.shopDtl)
             }
 
             if (it.person && !it.personDtl.userid.isNullOrEmpty()) {
@@ -139,7 +140,7 @@
     fun repair(refno: String, agentAccdate: String, sourcetypeRefno: String, remark: String): TTransactionMain {
         return transactionService.repair(refno, agentAccdate, sourcetypeRefno, remark).also {
             if (it.shop) {
-                shopAccBalanceAsyncTask.updateShopBalance(it.shopDtl)
+                shopAccBalanceAsyncTask.updateShopBalance(TenantContextHolder.getContext().tenant, it.shopDtl)
             }
         }
     }
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/framework/service/impl/framework_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/framework/service/impl/framework_service_impl.kt
index 93ad8e6..363e617 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/framework/service/impl/framework_service_impl.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/framework/service/impl/framework_service_impl.kt
@@ -30,7 +30,7 @@
     }
 
     override fun getRequestAppid(request: HttpServletRequest): String {
-        jwtTokenContext.jwt.get()?.also {
+        jwtTokenContext.jwt.orElseGet(null)?.let {
             val uid = it.uid
             if (!StringUtil.isEmpty(uid)) {
                 return uid as String
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/security.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/security.kt
index 7f12778..da40c22 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/security.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/security.kt
@@ -8,13 +8,10 @@
 import com.supwisdom.dlpay.mobile.AuthLoginSuccessHandler
 import com.supwisdom.dlpay.mobile.service.MobileUserService
 import com.supwisdom.multitenant.jwt.JwtTokenContext
-import org.jose4j.jwt.consumer.InvalidJwtException
-import org.jose4j.lang.JoseException
 import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.context.annotation.Bean
 import org.springframework.context.annotation.Configuration
 import org.springframework.core.annotation.Order
-import org.springframework.http.HttpStatus
 import org.springframework.security.authentication.AuthenticationManager
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
 import org.springframework.security.authentication.dao.DaoAuthenticationProvider
@@ -50,27 +47,16 @@
     private lateinit var jwtTokenContext: JwtTokenContext
 
     override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, filterChain: FilterChain) {
-        jwtTokenContext.jwt.ifPresent { jwt ->
-            try {
+        try {
+            jwtTokenContext.jwt.ifPresent { jwt ->
                 val auth = UsernamePasswordAuthenticationToken(jwt.uid, null,
                         (jwt.authorities as ArrayList<*>)
                                 .map { SimpleGrantedAuthority(it as String) })
                 SecurityContextHolder.getContext().authentication = auth
-                filterChain.doFilter(request, response)
-            } catch (e: InvalidJwtException) {
-                SecurityContextHolder.clearContext()
-                response.status = HttpStatus.UNAUTHORIZED.value()
-            } catch (e: JoseException) {
-                SecurityContextHolder.clearContext()
-                // jwt 失效后返回 401
-                response.status = HttpStatus.UNAUTHORIZED.value()
-                response.contentType = "application/json;charset=UTF-8"
-            } catch (e: Exception) {
-                SecurityContextHolder.clearContext()
-                // jwt 失效后返回 401
-                response.status = HttpStatus.UNAUTHORIZED.value()
-                response.contentType = "application/json;charset=UTF-8"
             }
+            filterChain.doFilter(request, response)
+        } finally {
+            SecurityContextHolder.clearContext()
         }
     }
 }
@@ -99,8 +85,8 @@
             filterChain.doFilter(request, response)
             return
         }
-        jwtTokenContext.jwt.ifPresent { jwt ->
-            try {
+        try {
+            jwtTokenContext.jwt.ifPresent { jwt ->
                 val auth = UsernamePasswordAuthenticationToken(jwt.uid, null,
                         (jwt.authorities as ArrayList<*>)
                                 .map { SimpleGrantedAuthority(it as String) })
@@ -109,21 +95,10 @@
                 response.setHeader("Access-Control-Allow-Methods", "GET,POST,DELETE,PUT,OPTIONS");
                 response.setHeader("Access-Control-Allow-Headers", "*");
                 response.setHeader("Access-Control-Allow-Credentials", "true")
-                filterChain.doFilter(request, response)
-            } catch (e: InvalidJwtException) {
-                SecurityContextHolder.clearContext()
-                response.status = HttpStatus.UNAUTHORIZED.value()
-            } catch (e: JoseException) {
-                SecurityContextHolder.clearContext()
-                // jwt 失效后返回 401
-                response.status = HttpStatus.UNAUTHORIZED.value()
-                response.contentType = "application/json;charset=UTF-8"
-            } catch (e: Exception) {
-                SecurityContextHolder.clearContext()
-                // jwt 失效后返回 401
-                response.status = HttpStatus.UNAUTHORIZED.value()
-                response.contentType = "application/json;charset=UTF-8"
             }
+            filterChain.doFilter(request, response)
+        } finally {
+            SecurityContextHolder.clearContext()
         }
     }
 }