From 216ffdbe0e2c3aae25fb51982349653d9e2f7987 Mon Sep 17 00:00:00 2001 From: Tang Cheng Date: Tue, 6 Aug 2019 17:04:14 +0800 Subject: [PATCH] =?utf8?q?=E5=AE=9E=E7=8E=B0=E5=AF=B9=E8=B4=A6=E6=A1=86?= =?utf8?q?=E6=9E=B6=EF=BC=8C=E4=BD=86=E6=9C=AA=E5=AE=8C=E6=88=90=E6=B5=8B?= =?utf8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../dlpay/agent/CheckFileProvider.java | 9 + .../dlpay/api/dao/SourceTypeCheckDao.java | 11 + .../dlpay/api/dao/SourceTypeDao.java | 2 + .../dlpay/api/domain/TSourceType.java | 12 ++ .../api/domain/TSourceTypeCheckStatus.java | 130 ++++++++++++ .../dlpay/api/service/SourceTypeService.java | 11 + .../service/impl/SourceTypeServiceImpl.java | 32 ++- .../com/supwisdom/dlpay/api/async_tasks.kt | 9 + .../dlpay/api/scheduler_sourcetype_chk.kt | 199 ++++++++++++++++++ .../dlpay/api/scheduler_ynrccchk_task.kt | 4 +- .../transaction_reconciliation_service.kt | 2 +- 11 files changed, 408 insertions(+), 13 deletions(-) create mode 100644 payapi/src/main/java/com/supwisdom/dlpay/agent/CheckFileProvider.java create mode 100644 payapi/src/main/java/com/supwisdom/dlpay/api/dao/SourceTypeCheckDao.java create mode 100644 payapi/src/main/java/com/supwisdom/dlpay/api/domain/TSourceTypeCheckStatus.java create mode 100644 payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_sourcetype_chk.kt diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/CheckFileProvider.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/CheckFileProvider.java new file mode 100644 index 00000000..964b460d --- /dev/null +++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/CheckFileProvider.java @@ -0,0 +1,9 @@ +package com.supwisdom.dlpay.agent; + +public interface CheckFileProvider { + AgentResponse acquireCheckFile(String checkDate); + + AgentResponse queryCheckFile(String checkDate); + + AgentResponse downloadCheckFile(String checkDate); +} diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/SourceTypeCheckDao.java b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/SourceTypeCheckDao.java new file mode 100644 index 00000000..361cb427 --- /dev/null +++ b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/SourceTypeCheckDao.java @@ -0,0 +1,11 @@ +package com.supwisdom.dlpay.api.dao; + +import com.supwisdom.dlpay.api.domain.TSourceTypeCheckStatus; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface SourceTypeCheckDao extends CrudRepository { + TSourceTypeCheckStatus getBySourceTypeAndTenantId(String sourceType, String tenantid); + +} diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/SourceTypeDao.java b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/SourceTypeDao.java index b823f3d4..38e1b385 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/SourceTypeDao.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/SourceTypeDao.java @@ -20,4 +20,6 @@ public interface SourceTypeDao extends JpaRepository { @Query("select t from TSourceType t") List getConsumeSourceTypes(); + + List findByEnableAndTenantid(Boolean enabled, String tenantid); } diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TSourceType.java b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TSourceType.java index d20efaf5..49f1d81a 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TSourceType.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TSourceType.java @@ -58,6 +58,10 @@ public class TSourceType implements DictionaryTable, Serializable { @Column(name = "PAYDESC", length = 200) private String paydesc; + + @Column(name = "tplusn", precision = 5) + private Integer tplusN; // 系统结算日期, T+0 ~ T+N + @Column(name = "tenantid", length = 20) @NotNull private String tenantid = ""; @@ -167,4 +171,12 @@ public class TSourceType implements DictionaryTable, Serializable { public void setDepositeSubjno(String depositeSubjno) { this.depositeSubjno = depositeSubjno; } + + public Integer getTplusN() { + return tplusN; + } + + public void setTplusN(Integer tplusN) { + this.tplusN = tplusN; + } } diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TSourceTypeCheckStatus.java b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TSourceTypeCheckStatus.java new file mode 100644 index 00000000..4a4f41c3 --- /dev/null +++ b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TSourceTypeCheckStatus.java @@ -0,0 +1,130 @@ +package com.supwisdom.dlpay.api.domain; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.sql.Timestamp; + +@Entity +@Table(name = "tb_sourcetype_check", + indexes = {@Index(name = "sourcetype_check_idx", columnList = "source_type, tenantid", unique = true)}) +public class TSourceTypeCheckStatus { + @Id + @SequenceGenerator(name = "st_checker_id", sequenceName = "SEQ_SOURCETYPE_CHECK", allocationSize = 1) + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "st_checker_id") + private Integer id; + + @Column(name = "source_type", length = 30) + @NotNull + private String sourceType; + + @Column(name = "start_accdate", length = 8) + @NotNull + private String startAccdate; // 对账起始日期 + + @Column(name = "check_file_date", length = 8) + private String checkFileDate; // 当前对账文件日期 + + @Column(name = "check_file_status") + private Boolean checkFileOk; // 当前对账文件下载成功标志 + + @Column(name = "check_accdate", length = 8) + @NotNull + private String checkAccdate; // 当前对账记账日期 + + @Column(name = "check_status") + @NotNull + private Boolean checkStatus; // 当前对账完成状态 + + @Column(name = "force_recheck") + @NotNull + private Boolean forceRecheck; // 是否对当前日期强制对账 + + @Column(name = "last_update") + @NotNull + @Version + private Timestamp lastUpdate; + + @Column(name = "tenantid", length = 20) + @NotNull + private String tenantId; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getSourceType() { + return sourceType; + } + + public void setSourceType(String sourceType) { + this.sourceType = sourceType; + } + + public String getCheckAccdate() { + return checkAccdate; + } + + public void setCheckAccdate(String checkAccdate) { + this.checkAccdate = checkAccdate; + } + + public Boolean getForceRecheck() { + return forceRecheck; + } + + public void setForceRecheck(Boolean forceRecheck) { + this.forceRecheck = forceRecheck; + } + + public Timestamp getLastUpdate() { + return lastUpdate; + } + + public void setLastUpdate(Timestamp lastUpdate) { + this.lastUpdate = lastUpdate; + } + + public String getTenantId() { + return tenantId; + } + + public void setTenantId(String tenantId) { + this.tenantId = tenantId; + } + + public String getStartAccdate() { + return startAccdate; + } + + public void setStartAccdate(String startAccdate) { + this.startAccdate = startAccdate; + } + + public String getCheckFileDate() { + return checkFileDate; + } + + public void setCheckFileDate(String checkFileDate) { + this.checkFileDate = checkFileDate; + } + + public Boolean getCheckFileOk() { + return checkFileOk; + } + + public void setCheckFileOk(Boolean checkFileOk) { + this.checkFileOk = checkFileOk; + } + + public Boolean getCheckStatus() { + return checkStatus; + } + + public void setCheckStatus(Boolean checkStatus) { + this.checkStatus = checkStatus; + } +} diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/service/SourceTypeService.java b/payapi/src/main/java/com/supwisdom/dlpay/api/service/SourceTypeService.java index 833eb0a8..c0d78b76 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/api/service/SourceTypeService.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/api/service/SourceTypeService.java @@ -1,9 +1,11 @@ package com.supwisdom.dlpay.api.service; import com.supwisdom.dlpay.api.domain.TSourceType; +import com.supwisdom.dlpay.api.domain.TSourceTypeCheckStatus; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; +import java.util.List; import java.util.Map; /** @@ -23,6 +25,9 @@ public interface SourceTypeService { @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, readOnly = true) boolean checkShopSourceType(String shopaccno, String sourceType, boolean anonymousflag) throws Exception; + @Transactional + List getAllEnabledSourcetype(); + /** * 获取支付能力充值参数全局配置 */ @@ -41,4 +46,10 @@ public interface SourceTypeService { @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, readOnly = true) boolean checkShopCanReverse(String sourcetype, String shopaccno) throws Exception; + @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, readOnly = true) + TSourceTypeCheckStatus getSourceTypeCheckStatus(String sourceType); + + @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class) + TSourceTypeCheckStatus saveOrUpdateSourceTypeCheckStatus(TSourceTypeCheckStatus s); + } diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/service/impl/SourceTypeServiceImpl.java b/payapi/src/main/java/com/supwisdom/dlpay/api/service/impl/SourceTypeServiceImpl.java index 96f36564..545f848a 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/api/service/impl/SourceTypeServiceImpl.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/api/service/impl/SourceTypeServiceImpl.java @@ -1,15 +1,10 @@ package com.supwisdom.dlpay.api.service.impl; -import com.supwisdom.dlpay.api.dao.ShopSourceTypeConfigDao; -import com.supwisdom.dlpay.api.dao.ShopSourceTypeDao; -import com.supwisdom.dlpay.api.dao.SourceTypeConfigDao; -import com.supwisdom.dlpay.api.dao.SourceTypeDao; -import com.supwisdom.dlpay.api.domain.TShopSourceType; -import com.supwisdom.dlpay.api.domain.TShopSourceTypeConfig; -import com.supwisdom.dlpay.api.domain.TSourceType; -import com.supwisdom.dlpay.api.domain.TSourceTypeConfig; +import com.supwisdom.dlpay.api.dao.*; +import com.supwisdom.dlpay.api.domain.*; import com.supwisdom.dlpay.api.service.SourceTypeService; import com.supwisdom.dlpay.exception.TransactionProcessException; +import com.supwisdom.dlpay.framework.tenant.TenantContext; import com.supwisdom.dlpay.framework.util.StringUtil; import com.supwisdom.dlpay.framework.util.TradeErrorCode; import org.springframework.beans.factory.annotation.Autowired; @@ -29,14 +24,16 @@ public class SourceTypeServiceImpl implements SourceTypeService { private final SourceTypeConfigDao sourceTypeConfigDao; private final ShopSourceTypeDao shopSourceTypeDao; private final ShopSourceTypeConfigDao shopSourceTypeConfigDao; + private final SourceTypeCheckDao sourceTypeCheckDao; @Autowired public SourceTypeServiceImpl(SourceTypeDao sourceTypeDao, SourceTypeConfigDao sourceTypeConfigDao, - ShopSourceTypeDao shopSourceTypeDao, ShopSourceTypeConfigDao shopSourceTypeConfigDao) { + ShopSourceTypeDao shopSourceTypeDao, ShopSourceTypeConfigDao shopSourceTypeConfigDao, SourceTypeCheckDao sourceTypeCheckDao) { this.sourceTypeDao = sourceTypeDao; this.sourceTypeConfigDao = sourceTypeConfigDao; this.shopSourceTypeDao = shopSourceTypeDao; this.shopSourceTypeConfigDao = shopSourceTypeConfigDao; + this.sourceTypeCheckDao = sourceTypeCheckDao; } @@ -196,4 +193,21 @@ public class SourceTypeServiceImpl implements SourceTypeService { return true; } + @Override + public List getAllEnabledSourcetype() { + return sourceTypeDao.findByEnableAndTenantid(true, TenantContext.getTenantSchema()); + } + + @Override + public TSourceTypeCheckStatus getSourceTypeCheckStatus(String sourceType) { + return sourceTypeCheckDao.getBySourceTypeAndTenantId(sourceType, TenantContext.getTenantSchema()); + } + + @Override + public TSourceTypeCheckStatus saveOrUpdateSourceTypeCheckStatus(TSourceTypeCheckStatus s) { + if (s.getTenantId() == null || s.getTenantId().isEmpty()) { + s.setTenantId(TenantContext.getTenantSchema()); + } + return sourceTypeCheckDao.save(s); + } } 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 759e0478..65f41d89 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 @@ -40,6 +40,15 @@ class SpringAsyncConfig : AsyncConfigurer { } } + @Bean(name = ["sourcetypeCheckTaskExecutor"]) + fun threadPoolTaskExecutor(): Executor { + return ThreadPoolTaskExecutor().apply { + corePoolSize = 5 + maxPoolSize = 10 + setWaitForTasksToCompleteOnShutdown(true) + } + } + override fun getAsyncUncaughtExceptionHandler(): AsyncUncaughtExceptionHandler? { return MyAsyncUncaughtExceptionHandler() } 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 new file mode 100644 index 00000000..5e72e705 --- /dev/null +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_sourcetype_chk.kt @@ -0,0 +1,199 @@ +package com.supwisdom.dlpay.api + +import com.supwisdom.dlpay.agent.AgentCode +import com.supwisdom.dlpay.agent.CheckFileProvider +import com.supwisdom.dlpay.api.domain.TSourceType +import com.supwisdom.dlpay.api.domain.TSourceTypeCheckStatus +import com.supwisdom.dlpay.api.service.SourceTypeService +import com.supwisdom.dlpay.framework.service.SystemUtilService +import com.supwisdom.dlpay.framework.util.DateUtil +import mu.KotlinLogging +import net.javacrumbs.shedlock.core.SchedulerLock +import org.springframework.beans.BeansException +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.context.ApplicationContext +import org.springframework.scheduling.annotation.Async +import org.springframework.scheduling.annotation.AsyncResult +import org.springframework.scheduling.annotation.Scheduled +import org.springframework.stereotype.Component +import java.util.concurrent.Future +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException + +@Component +class SourceTypeCheck { + private val logger = KotlinLogging.logger { } + + @Autowired + private lateinit var sourceTypeService: SourceTypeService + + @Autowired + private lateinit var systemUtilService: SystemUtilService + + @Autowired + private lateinit var sourceTypeCheckExecutor: SourceTypeCheckExecutor + + private fun newSourceTypeStatus(sourceType: TSourceType): TSourceTypeCheckStatus { + return TSourceTypeCheckStatus().also { + it.sourceType = sourceType.sourceType + it.tenantId = sourceType.tenantid + it.startAccdate = systemUtilService.accdate + it.forceRecheck = false + it.checkFileDate = it.startAccdate + it.checkFileOk = false + }.let { + sourceTypeService.saveOrUpdateSourceTypeCheckStatus(it) + } + } + + private fun determineSourceTypeCheck(sourcetype: TSourceType): TSourceTypeCheckStatus? { + if (!sourcetype.checkable) { + return null + } + val status = sourceTypeService.getSourceTypeCheckStatus(sourcetype.sourceType) + ?: newSourceTypeStatus(sourcetype) + + // 小于对账日期 + val interval = DateUtil.getIntervalDay(status.checkAccdate, systemUtilService.accdate) + // 已对账 + if (status.checkStatus) { + // 大于等于结算日期进行对账 + return if (interval >= sourcetype.tplusN) { + status.checkAccdate = DateUtil.getNewDay(status.checkAccdate, 1) + status.checkStatus = false + status.checkFileOk = false + status.checkFileDate = DateUtil.getNewDay(status.checkFileDate, 1) + sourceTypeService.saveOrUpdateSourceTypeCheckStatus(status) + } else { + null + } + } + return status + } + + @Scheduled(cron = "\${payapi.sourcetype.checker.scheduler:-}") + @SchedulerLock(name = "payapiSourceTypeCheckLock", lockAtMostForString = "PT30M") + fun runCheck() { + val allSourcetype = sourceTypeService.allEnabledSourcetype + ?: return + + val checkFileStatus = allSourcetype.mapNotNull { + determineSourceTypeCheck(it) + } + + val checkProcessResult = checkFileStatus.map { + // 对账文件是否下载完成 + if (it.checkFileOk) { + // 开始对账 + sourceTypeCheckExecutor.reconciliation(it) + } else { + // 开始下载对账文件 + sourceTypeCheckExecutor.checkSourceType(it) + } + }.toMutableList() + + while (checkProcessResult.isNotEmpty()) { + val finishResult: MutableList> = mutableListOf() + val newPrcResult: MutableList> = mutableListOf() + checkProcessResult.forEach { + try { + val result = it.get(10, TimeUnit.SECONDS) + if (result.code == SourceTypeCheckExecutor.SUCCESS) { + // 完成对账问价下载 但 还未对账 + if (result.status.checkFileOk && !result.status.checkStatus) { + newPrcResult.add(sourceTypeCheckExecutor.reconciliation(result.status)) + } else if (!result.status.checkFileOk) { + logger.error { + "sourcetype <${result.status.sourceType}> get checkfile error," + + "<${result.message}>" + } + } else if (result.status.checkFileOk && result.status.checkStatus) { + logger.info { + "sourcetype <${result.status.sourceType}> " + + "date <${result.status.checkAccdate}> 对账成功" + } + } + } else { + logger.error { + "sourcetype <${result.status.sourceType}> 对账状任务错误, error=" + + "<${result.message}>" + } + } + finishResult.add(it) + } catch (ex: TimeoutException) { + // async task not finished + } + } + checkProcessResult.removeIf { finishResult.contains(it) } + finishResult.clear() + checkProcessResult.addAll(newPrcResult) + } + } +} + +@Component +class SourceTypeCheckExecutor { + companion object { + const val SUCCESS = "success" + const val FAIL = "fail" + const val WAIT = "wait" + } + + class ExecutorResult(val status: TSourceTypeCheckStatus, + val code: String, val message: String); + + @Autowired + private lateinit var applicationContext: ApplicationContext + + private val logger = KotlinLogging.logger { } + + private fun getProvider(sourcetype: String): CheckFileProvider? { + return try { + applicationContext.getBean("${sourcetype}CheckFileProvider") as CheckFileProvider + } catch (ex: BeansException) { + logger.error { "未定义 sourcetype <$sourcetype> 对账处理 Provider" } + null + } + } + + private fun downloadFile(provider: CheckFileProvider, checkStatus: TSourceTypeCheckStatus): ExecutorResult { + return provider.downloadCheckFile(checkStatus.checkFileDate).let { resp -> + when { + resp.code == AgentCode.SUCCESS -> ExecutorResult(checkStatus, SUCCESS, "成功") + resp.code == AgentCode.REQUIRE_QUERY -> ExecutorResult(checkStatus, WAIT, "等待查询对账文件") + else -> ExecutorResult(checkStatus, FAIL, resp.agentMsg) + } + } + } + + @Async("sourcetypeCheckTaskExecutor") + fun checkSourceType(checkStatus: TSourceTypeCheckStatus): Future { + // 2. 根据对账日期下载对账文件 + val result = getProvider(checkStatus.sourceType)?.let { provider -> + val acResp = provider.acquireCheckFile(checkStatus.checkFileDate) + if (acResp.code == AgentCode.REQUIRE_QUERY) { + var success = false + repeat(10) { + if (!success) { + Thread.sleep(3000) + success = provider.queryCheckFile(checkStatus.checkFileDate).code == AgentCode.SUCCESS + } + } + if (success) { + downloadFile(provider, checkStatus) + } else { + ExecutorResult(checkStatus, FAIL, "下载失败,未能查到对账文件") + } + } else { + downloadFile(provider, checkStatus) + } + } ?: ExecutorResult(checkStatus, FAIL, "未定义 CheckFileProvider") + return AsyncResult(result) + } + + @Async("sourcetypeCheckTaskExecutor") + fun reconciliation(checkStatus: TSourceTypeCheckStatus): Future { + // 3. 完成对账 + return AsyncResult(ExecutorResult(checkStatus, SUCCESS, "成功")) + } +} \ No newline at end of file diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_ynrccchk_task.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_ynrccchk_task.kt index 067f1ef0..e7ad75f3 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_ynrccchk_task.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_ynrccchk_task.kt @@ -52,8 +52,6 @@ class DownloadYnrccChkfileTask { @SchedulerLock(name = "DownloadYnrccChkfileSchedulerTask", lockAtMostForString = "PT10M") fun doDownloadYnrccChkfile() { try { - if(null==TenantContext.getTenantSchema()) TenantContext.setTenantSchema(Constants.DEFAULT_TENANTID) - //下载对账单逻辑 val hostdate = systemUtilService.sysdatetime.hostdate val downloadLastdate = ynrccBusinessService.getLastDownloadBillDate() @@ -63,7 +61,7 @@ class DownloadYnrccChkfileTask { for (i in 1 until diffDays) { val billDate = DateUtil.getNewDay(downloadLastdate, i) //要取对账单的日期 - var chkfile = transactionReconciliationService.doInitTransactionChkfile(billDate, TradeDict.PAYTYPE_CITIZEN_CARD) + val chkfile = transactionReconciliationService.doInitTransactionChkfile(billDate, TradeDict.PAYTYPE_CITIZEN_CARD) val resp = citizencardPayService.getChkfilename(billDate, null) if (YnrccUtil.CODE_SUCCESS == resp.code) { diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_reconciliation_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_reconciliation_service.kt index 173d15aa..8147a59c 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_reconciliation_service.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_reconciliation_service.kt @@ -22,6 +22,6 @@ interface TransactionReconciliationService { fun doBatchSaveYnrccTransactionChkDtl(chkfile: TTransactionChkfile, list: ArrayList): Boolean @Transactional(rollbackFor = [Exception::class]) - fun doSuccessTransactionChkfile(chkfile: TTransactionChkfile, reamrk:String) + fun doSuccessTransactionChkfile(chkfile: TTransactionChkfile, remark:String) } \ No newline at end of file -- 2.17.1