流水扫描查询任务
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/DtlQueryDao.java b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/DtlQueryDao.java
new file mode 100644
index 0000000..ea6c3be
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/DtlQueryDao.java
@@ -0,0 +1,13 @@
+package com.supwisdom.dlpay.api.dao;
+
+import com.supwisdom.dlpay.api.domain.TDtlQuery;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.List;
+
+public interface DtlQueryDao extends JpaRepository<TDtlQuery, String> {
+
+ @Query("from TDtlQuery t where t.accdate=?1 and t.status=?2 and t.qcnt<=?3 order by t.lastsaved desc ")
+ List<TDtlQuery> getNeedQueryDtls(String accdate, String status, int maxQcnt);
+}
diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TDtlQuery.java b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TDtlQuery.java
new file mode 100644
index 0000000..feec7c5
--- /dev/null
+++ b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TDtlQuery.java
@@ -0,0 +1,115 @@
+package com.supwisdom.dlpay.api.domain;
+
+import org.hibernate.annotations.GenericGenerator;
+
+import javax.persistence.*;
+import java.sql.Timestamp;
+
+@Entity
+@Table(name = "TB_DTL_QUERY")
+public class TDtlQuery {
+ @Id
+ @GenericGenerator(name = "idGenerator", strategy = "uuid")
+ @GeneratedValue(generator = "idGenerator")
+ @Column(name = "id", nullable = false, length = 32)
+ private String id;
+
+ @Column(name = "ACCDATE", nullable = false, length = 32)
+ private String accdate;
+
+ @Column(name = "REFNO", nullable = false, length = 32)
+ private String refno;
+
+ @Column(name = "STATUS", nullable = false, length = 32)
+ private String status;
+
+ @Column(name = "REMARK", length = 600)
+ private String remark;
+
+ @Column(name = "QCNT", length = 9)
+ private Integer qcnt;
+
+ @Column(name = "LASTSAVED")
+ @Version
+ private Timestamp lastsaved;
+
+ @Column(name = "tenantid", nullable = false, length = 20)
+ private String tenantId;
+
+ public TDtlQuery(){
+ }
+
+ public TDtlQuery(String accdate, String refno, String status, String remark, Integer qcnt, Timestamp lastsaved, String tenantId) {
+ this.accdate = accdate;
+ this.refno = refno;
+ this.status = status;
+ this.remark = remark;
+ this.qcnt = qcnt;
+ this.lastsaved = lastsaved;
+ this.tenantId = tenantId;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getAccdate() {
+ return accdate;
+ }
+
+ public void setAccdate(String accdate) {
+ this.accdate = accdate;
+ }
+
+ public String getRefno() {
+ return refno;
+ }
+
+ public void setRefno(String refno) {
+ this.refno = refno;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getRemark() {
+ return remark;
+ }
+
+ public void setRemark(String remark) {
+ this.remark = remark;
+ }
+
+ public Integer getQcnt() {
+ return qcnt;
+ }
+
+ public void setQcnt(Integer qcnt) {
+ this.qcnt = qcnt;
+ }
+
+ public Timestamp getLastsaved() {
+ return lastsaved;
+ }
+
+ public void setLastsaved(Timestamp lastsaved) {
+ this.lastsaved = lastsaved;
+ }
+
+ public String getTenantId() {
+ return tenantId;
+ }
+
+ public void setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ }
+}
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 6cacabd..3c7b5de 100644
--- a/payapi/src/main/java/com/supwisdom/dlpay/util/ConstantUtil.java
+++ b/payapi/src/main/java/com/supwisdom/dlpay/util/ConstantUtil.java
@@ -29,4 +29,8 @@
* */
public static final String CARDTYPE_CITIZENCARD = "citizencard";
public static final String CARDTYPE_BANKCARD = "bankcard";
+
+ public static final String QUERYTYPE_NEED_QUERY = "query";
+ public static final String QUERYTYPE_QUERY_FINISH = "finish";
+ public static final int QUERY_MAX_COUNT = 10;
}
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 133427f..4139d9e 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
@@ -4,10 +4,15 @@
import com.supwisdom.dlpay.agent.DtlStatus
import com.supwisdom.dlpay.agent.citizencard.YnrccUtil
+import com.supwisdom.dlpay.api.domain.TDtlQuery
import com.supwisdom.dlpay.api.domain.TTransactionMain
import com.supwisdom.dlpay.api.repositories.ShopaccService
+import com.supwisdom.dlpay.api.service.DtlQueryResultService
import com.supwisdom.dlpay.api.service.TransactionServiceProxy
+import com.supwisdom.dlpay.framework.service.SystemUtilService
import com.supwisdom.dlpay.framework.util.ApplicationUtil
+import com.supwisdom.dlpay.framework.util.TradeDict
+import com.supwisdom.dlpay.util.ConstantUtil
import mu.KotlinLogging
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler
import org.springframework.beans.factory.annotation.Autowired
@@ -70,12 +75,28 @@
@Autowired
private lateinit var applicationContext: ApplicationContext
+ @Autowired
+ private lateinit var dtlQueryResultService: DtlQueryResultService
+
+ @Autowired
+ private lateinit var systemUtilService: SystemUtilService
+
@Async("queryAgentPayResult")
fun queryResult(transaction: TTransactionMain, qcnt: Int) {
try {
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
}
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 0e6d694..38f652f 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
@@ -1,15 +1,30 @@
package com.supwisdom.dlpay.api
+import com.supwisdom.dlpay.agent.AgentCode
+import com.supwisdom.dlpay.agent.DtlStatus
+import com.supwisdom.dlpay.api.domain.TDtlQuery
import com.supwisdom.dlpay.api.domain.TShopdtl
import com.supwisdom.dlpay.api.repositories.ShopaccService
+import com.supwisdom.dlpay.api.service.ConsumePayService
+import com.supwisdom.dlpay.api.service.DtlQueryResultService
+import com.supwisdom.dlpay.api.service.TransactionServiceProxy
+import com.supwisdom.dlpay.framework.domain.TTaskLock
+import com.supwisdom.dlpay.framework.service.SystemUtilService
+import com.supwisdom.dlpay.framework.util.ApplicationUtil
+import com.supwisdom.dlpay.framework.util.TradeDict
+import com.supwisdom.dlpay.util.ConstantUtil
import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.context.ApplicationContext
import org.springframework.scheduling.annotation.Scheduled
+import org.springframework.stereotype.Component
import org.springframework.stereotype.Service
@Service
class MySchedulerTask {
@Autowired
private lateinit var shopaccService: ShopaccService
+ @Autowired
+ private lateinit var systemUtilService: SystemUtilService
fun doShopBlanceUpdate(dtl: TShopdtl) {
shopaccService.recalcShopBalance(dtl.refno, true)
@@ -17,8 +32,159 @@
@Scheduled(cron = "\${shopbalance.updater.cron:-}")
fun dealShopUnupdatedDtl() {
- shopaccService.findUnupdatedShopDtl(100).forEach {
- doShopBlanceUpdate(it)
+ var tasklock = TTaskLock()
+ try {
+ //集群控制
+ try {
+ tasklock = systemUtilService.doLockTask("SHOPBLANCEUPDATETASK", 10, "更新账户余额任务")
+ if (tasklock == null) {
+ return
+ }
+ } catch (e: Exception) {
+ return
+ }
+
+ shopaccService.findUnupdatedShopDtl(100).forEach {
+ doShopBlanceUpdate(it)
+ }
+ } catch (ex: Exception) {
+ ex.printStackTrace()
+ } finally {
+ if (tasklock?.taskcode.isNotEmpty()) {
+ tasklock.taskstatus = 0
+ tasklock.tasktime = systemUtilService.sysdatetime.hostdatetime
+ systemUtilService.updateTaskLock(tasklock)
+ }
+ }
+
+
+ }
+}
+
+/**
+ * 定时扫描TDtlQuery,查询第三方流水状态
+ * */
+@Component
+class DtlQueryResultSchedulerTask {
+ @Autowired
+ private lateinit var systemUtilService: SystemUtilService
+ @Autowired
+ private lateinit var dtlQueryResultService: DtlQueryResultService
+ @Autowired
+ lateinit var transactionService: TransactionServiceProxy
+ @Autowired
+ lateinit var consumePayService: ConsumePayService
+ @Autowired
+ private lateinit var applicationContext: ApplicationContext
+
+ @Scheduled(cron = "\${query.third.transdtl.result.cron:-}")
+ fun queryThirdTransdtlResult() {
+ var tasklock = TTaskLock()
+ try {
+ //集群控制
+ try {
+ tasklock = systemUtilService.doLockTask("QUERYTHIRDTRANSDTLRESULTTASK", 10, "查询第三方流水状态任务")
+ if (tasklock == null) {
+ return
+ }
+ } catch (e: Exception) {
+ return
+ }
+
+ //仅查询当天数据,查询次数在规定次数之下
+ dtlQueryResultService.getNeedQueryRecords(systemUtilService.accdate, ConstantUtil.QUERY_MAX_COUNT).forEach {
+ try {
+ doQuery(it)
+ } catch (exp: Exception) {
+ it.qcnt = it.qcnt + 1
+ dtlQueryResultService.saveOrUpdateDtlQuery(it) //次数加一
+ }
+ }
+ } catch (ex: Exception) {
+ ex.printStackTrace()
+ } finally {
+ if (tasklock?.taskcode.isNotEmpty()) {
+ tasklock.taskstatus = 0
+ tasklock.tasktime = systemUtilService.sysdatetime.hostdatetime
+ systemUtilService.updateTaskLock(tasklock)
+ }
}
}
+
+ private fun doQuery(dtlQuery: TDtlQuery) {
+ 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 = ApplicationUtil.findAgentPayService(applicationContext, dtl.sourceType + "Agent")
+ 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
+ }
+ }
+ }
+ 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/dtl_query_result_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/dtl_query_result_service.kt
new file mode 100644
index 0000000..9673b0f
--- /dev/null
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/dtl_query_result_service.kt
@@ -0,0 +1,15 @@
+package com.supwisdom.dlpay.api.service
+
+import com.supwisdom.dlpay.api.domain.TDtlQuery
+import org.springframework.transaction.annotation.Propagation
+import org.springframework.transaction.annotation.Transactional
+
+interface DtlQueryResultService {
+
+ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
+ fun saveOrUpdateDtlQuery(dtlQuery: TDtlQuery): TDtlQuery
+
+ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class], readOnly = true)
+ fun getNeedQueryRecords(accdate: String, maxCount:Int): List<TDtlQuery>
+
+}
\ No newline at end of file
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/dtl_query_result_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/dtl_query_result_service_impl.kt
new file mode 100644
index 0000000..a42427b
--- /dev/null
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/dtl_query_result_service_impl.kt
@@ -0,0 +1,27 @@
+package com.supwisdom.dlpay.api.service.impl
+
+import com.supwisdom.dlpay.api.dao.DtlQueryDao
+import com.supwisdom.dlpay.api.domain.TDtlQuery
+import com.supwisdom.dlpay.api.service.DtlQueryResultService
+import com.supwisdom.dlpay.framework.tenant.TenantContext
+import com.supwisdom.dlpay.util.ConstantUtil
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Service
+
+@Service
+class DtlQueryResultServiceImpl : DtlQueryResultService {
+ @Autowired
+ private lateinit var dtlQueryDao: DtlQueryDao
+
+ override fun saveOrUpdateDtlQuery(dtlQuery: TDtlQuery): TDtlQuery {
+ if (null == dtlQuery.tenantId) {
+ dtlQuery.tenantId = TenantContext.getTenantSchema()
+ }
+ return dtlQueryDao.save(dtlQuery)
+ }
+
+ override fun getNeedQueryRecords(accdate: String, maxCount: Int): List<TDtlQuery> {
+ return dtlQueryDao.getNeedQueryDtls(accdate, ConstantUtil.QUERYTYPE_NEED_QUERY, maxCount)
+ ?: ArrayList(0)
+ }
+}
\ No newline at end of file
diff --git a/payapi/src/main/resources/application.properties b/payapi/src/main/resources/application.properties
index 17217f9..5ca4e24 100644
--- a/payapi/src/main/resources/application.properties
+++ b/payapi/src/main/resources/application.properties
@@ -30,8 +30,9 @@
server.tomcat.uri-encoding=UTF-8
##################################################
## quartz task scheduler
-shopbalance.updater.cron=10/* * * * *
+shopbalance.updater.cron=10/* * * * * ?
dayend.settletask.cron=0 3/30 2-3 * * ?
+query.third.transdtl.result.cron=7 0/3 * * * ?
#dayend.settletask.cron = 0 0/2 * * * ?
################################################
# user password