From 5f1c615417bc235260db3ec4bd63bbd939df457f Mon Sep 17 00:00:00 2001 From: Tang Cheng Date: Fri, 17 Jan 2020 10:38:56 +0800 Subject: [PATCH] =?utf8?q?=E9=87=8D=E6=9E=84=E5=BC=82=E6=AD=A5=E4=BB=BB?= =?utf8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../framework/task/TaskExecuteTimes.java | 24 ++++ .../framework/task/TaskRetryException.java | 22 +++ .../controller/SettlementLogController.java | 7 +- .../com/supwisdom/dlpay/PayApiApplication.kt | 4 + .../dlpay/agent/service/wechat_service.kt | 1 - .../com/supwisdom/dlpay/api/async_tasks.kt | 130 +++++++++--------- .../api/controller/consume_api_controller.kt | 25 ++-- .../dlpay/api/scheduler_sourcetype_chk.kt | 22 +-- .../com/supwisdom/dlpay/api/scheduler_task.kt | 122 ++++++++-------- .../dlpay/api/service/transaction_service.kt | 5 +- .../service/impl/framework_service_impl.kt | 2 +- .../kotlin/com/supwisdom/dlpay/security.kt | 45 ++---- 12 files changed, 223 insertions(+), 186 deletions(-) create mode 100644 payapi/src/main/java/com/supwisdom/dlpay/framework/task/TaskExecuteTimes.java create mode 100644 payapi/src/main/java/com/supwisdom/dlpay/framework/task/TaskRetryException.java 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 00000000..3cea3842 --- /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 00000000..0a5b2e88 --- /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 e94a27f1..a53ad90f 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.PageResult; 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 @@ import org.springframework.web.bind.annotation.*; /** * 结算日志 - * */ + */ @Controller public class SettlementLogController { @Autowired @@ -36,7 +37,7 @@ public class SettlementLogController { 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 @@ public class SettlementLogController { @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 4cd2abea..6118efb8 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.GenericJackson2JsonRedisSeriali 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 @@ class MyTenantJwtConfigAdapter : JwtTenantConfigAdapter { @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 8f082418..683d1860 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.AgentCode 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 b2b5ed43..d9c159e4 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.api.service.TransactionServiceProxy 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 @@ class ShopAccBalanceAsyncTask { @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 @@ class AgentQueryResultTask { @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) - - 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 - } + @Retryable(value = [TaskRetryException::class], maxAttempts = YnrccUtil.QUERY_MAX_COUNT, backoff = Backoff(value = 3000)) + fun queryResult(details: TenantDetails, transaction: TTransactionMain) { + TenantContextHolder.getContext().tenant = details + val resp = try { val service = agentPayServiceContext.findAgentPayService(transaction.sourceType) + logger.info("refno=[${transaction.refno}]开始查询支付结果:") + service.query(transaction) + } catch (ex: Exception) { + ex.printStackTrace() + throw ex + } - 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, "查询流水状态为交易失败") - } + 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}]") } } - } catch (ex: Exception) { - ex.printStackTrace() + 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 @@ class SettlementAsyncTask { 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 7cad44b0..ac739593 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.api.service.* 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 @@ class ConsumeAPIController { 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 @@ class ConsumeAPIController { } 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 @@ class ConsumeAPIController { } 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 @@ class ConsumeAPIController { 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(mainDtl.sourceType) val resp = service.refund(refundTrans) @@ -355,7 +358,7 @@ class ConsumeAPIController { } 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 @@ class ConsumeAPIController { } @RequestMapping("/qrcode/init", method = [RequestMethod.POST, RequestMethod.GET]) - fun qrcodePayInit(@Validated(InitAction::class) @RequestBody param: QrcodePayParam): ResponseEntity { + fun qrcodePayInit(@Validated(InitAction::class) @RequestBody param: QrcodePayParam) + : ResponseEntity { val apiResp = QrcodePayResponse() // 1. 检查 qrcode val qrcode = agentServiceProxy.qrcodeMatch(param.qrcode) @@ -538,7 +542,8 @@ class ConsumeAPIController { private fun qrcodeSummary(st: TSourceType): String = st.paydesc + "扫码付" @PostMapping("/qrcode/confirm") - fun qrcodePayConfirm(@Validated(ConfirmAction::class) @RequestBody param: QrcodePayParam): ResponseEntity { + fun qrcodePayConfirm(@Validated(ConfirmAction::class) @RequestBody param: QrcodePayParam) + : ResponseEntity { //1. 交易检查 val apiResponse = QrcodePayResponse() val qrcodeTrans = agentServiceProxy.qrcodePayTransFindByMerchIdAndBillno(param.shopaccno, @@ -764,12 +769,14 @@ class ConsumeAPIController { 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 e3ab9e49..c57ddb1b 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.Constants 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 @@ class SourceTypeCheck { // 对账文件是否下载完成 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 @@ class SourceTypeCheck { 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 @@ class SourceTypeCheck { } } } 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 @@ class SourceTypeCheckExecutor { @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 @@ class SourceTypeCheckExecutor { } @Async("sourcetypeCheckTaskExecutor") - fun checkAndDownloadChkfile(checkStatus: TSourceTypeCheckStatus): Future { + fun checkAndDownloadChkfile(tenantDetails: TenantDetails, checkStatus: TSourceTypeCheckStatus): Future { // 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 @@ class SourceTypeCheckExecutor { } @Async("sourcetypeCheckTaskExecutor") - fun reconciliation(checkStatus: TSourceTypeCheckStatus): Future { + fun reconciliation(tenantDetails: TenantDetails, checkStatus: TSourceTypeCheckStatus): Future { // 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 7b477dda..ba4b5e97 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 @@ class DtlQueryResultSchedulerTask { 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(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(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 2e0ff912..ad2402d4 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.dao.TransactionMainDao 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 @@ class TransactionServiceProxy { 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 @@ class TransactionServiceProxy { 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 93ad8e66..363e617b 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 @@ class CommonServiceImpl : CommonService { } 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 7f127789..da40c22a 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.AuthLoginFailHandler 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 @@ class ApiJwtAuthenticationFilter : OncePerRequestFilter() { 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 @@ class MobileSecurityFilter : OncePerRequestFilter() { 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 @@ class MobileSecurityFilter : OncePerRequestFilter() { 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() } } } -- 2.17.1