优化 agent 对账文件处理机制
diff --git a/payapi-common/src/main/java/com/supwisdom/dlpay/api/agent/Constant.java b/payapi-common/src/main/java/com/supwisdom/dlpay/api/agent/Constant.java
new file mode 100644
index 0000000..c135d58
--- /dev/null
+++ b/payapi-common/src/main/java/com/supwisdom/dlpay/api/agent/Constant.java
@@ -0,0 +1,22 @@
+package com.supwisdom.dlpay.api.agent;
+
+public class Constant {
+ public static final String FLAG_PAY = "pay";
+ public static final String FLAG_REFUND = "refund";
+ public static final String STATUS_SUCCESS = "success";
+ public static final String STATUS_FAIL = "fail";
+
+ public static final String CHKFILE_DELIMITER = ",";
+
+
+ /////////////////////////////////////////////////////////////////
+ public static final String COL_REFNO = "refno";
+ public static final String COL_AGENT_REFNO = "agentrefno";
+ public static final String COL_AMOUNT = "amount";
+ public static final String COL_PAYERID = "payerid";
+ public static final String COL_PAYEEID = "payeeid";
+ public static final String COL_SUMMARY = "summary";
+ public static final String COL_AGENT_DATE = "agentdate";
+ public static final String COL_STATUS = "status";
+ public static final String COL_FLAG = "flag";
+}
diff --git a/payapi/build.gradle b/payapi/build.gradle
index 419a470..e2cdedd 100644
--- a/payapi/build.gradle
+++ b/payapi/build.gradle
@@ -58,6 +58,8 @@
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
implementation 'commons-codec:commons-codec:1.12'
implementation 'org.apache.commons:commons-lang3:3.9'
+ implementation 'net.javacrumbs.shedlock:shedlock-spring:2.5.0'
+ implementation 'net.javacrumbs.shedlock:shedlock-provider-redis-spring:2.5.0'
implementation 'org.springframework.cloud:spring-cloud-starter-consul-discovery:2.1.2.RELEASE'
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/PayApiApplication.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/PayApiApplication.kt
index b6f81aa..d0e6f9c 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/PayApiApplication.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/PayApiApplication.kt
@@ -2,6 +2,8 @@
import com.supwisdom.dlpay.framework.tenant.TenantCacheKeyGen
import io.lettuce.core.ReadFrom
+import net.javacrumbs.shedlock.core.LockProvider
+import net.javacrumbs.shedlock.provider.redis.spring.RedisLockProvider
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
@@ -50,6 +52,11 @@
fun createTenantCacheableKey(): KeyGenerator {
return TenantCacheKeyGen()
}
+
+ @Bean
+ fun lockProvider(connectionFactory: RedisConnectionFactory): LockProvider {
+ return RedisLockProvider(connectionFactory, "prod")
+ }
}
@Configuration
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 096d924..7d93474 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
@@ -13,6 +13,7 @@
import com.supwisdom.dlpay.framework.util.ApplicationUtil
import com.supwisdom.dlpay.framework.util.TradeDict
import com.supwisdom.dlpay.util.ConstantUtil
+import net.javacrumbs.shedlock.core.SchedulerLock
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.ApplicationContext
import org.springframework.scheduling.annotation.Scheduled
@@ -23,41 +24,17 @@
class MySchedulerTask {
@Autowired
private lateinit var shopaccService: ShopaccService
- @Autowired
- private lateinit var systemUtilService: SystemUtilService
fun doShopBlanceUpdate(dtl: TShopdtl) {
shopaccService.recalcShopBalance(dtl.refno, true)
}
@Scheduled(cron = "\${shopbalance.updater.cron:-}")
+ @SchedulerLock(name = "dealShopUnupdatedDtl")
fun dealShopUnupdatedDtl() {
- 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)
- }
+ shopaccService.findUnupdatedShopDtl(100).forEach {
+ doShopBlanceUpdate(it)
}
-
-
}
}
@@ -78,35 +55,15 @@
private lateinit var applicationContext: ApplicationContext
@Scheduled(cron = "\${query.third.transdtl.result.cron:-}")
+ @SchedulerLock(name = "DtlQueryResultSchedulerTask")
fun queryThirdTransdtlResult() {
- var tasklock = TTaskLock()
- try {
- //集群控制
+ //仅查询当天数据,查询次数在规定次数之下
+ dtlQueryResultService.getNeedQueryRecords(systemUtilService.accdate, ConstantUtil.QUERY_MAX_COUNT).forEach {
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)
+ doQuery(it)
+ } catch (exp: Exception) {
+ it.qcnt = it.qcnt + 1
+ dtlQueryResultService.saveOrUpdateDtlQuery(it) //次数加一
}
}
}
diff --git a/ynrcc-agent/build.gradle b/ynrcc-agent/build.gradle
index a00c65d..4387052 100644
--- a/ynrcc-agent/build.gradle
+++ b/ynrcc-agent/build.gradle
@@ -51,6 +51,8 @@
implementation 'org.dom4j:dom4j:2.1.1'
implementation 'commons-beanutils:commons-beanutils:1.9.3'
+ implementation project(':payapi-common')
+
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.rest-assured:rest-assured:3.3.0'
testImplementation 'io.rest-assured:spring-mock-mvc:3.3.0'
diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/CheckFileHeader.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/CheckFileHeader.java
deleted file mode 100644
index d19df54..0000000
--- a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/bean/CheckFileHeader.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.supwisdom.agent.api.bean;
-
-/**
- * 第一行:总笔数|总金额|代扣总笔数|代扣总金额|退款总笔数|退款总金额|
- */
-public class CheckFileHeader {
- private int totalCount;
- private int totalAmount;
- private int payCount;
- private int payAmount;
- private int refundCount;
- private int refundAmount;
-
- public int getTotalCount() {
- return totalCount;
- }
-
- public void setTotalCount(int totalCount) {
- this.totalCount = totalCount;
- }
-
- public int getTotalAmount() {
- return totalAmount;
- }
-
- public void setTotalAmount(int totalAmount) {
- this.totalAmount = totalAmount;
- }
-
- public int getPayCount() {
- return payCount;
- }
-
- public void setPayCount(int payCount) {
- this.payCount = payCount;
- }
-
- public int getPayAmount() {
- return payAmount;
- }
-
- public void setPayAmount(int payAmount) {
- this.payAmount = payAmount;
- }
-
- public int getRefundCount() {
- return refundCount;
- }
-
- public void setRefundCount(int refundCount) {
- this.refundCount = refundCount;
- }
-
- public int getRefundAmount() {
- return refundAmount;
- }
-
- public void setRefundAmount(int refundAmount) {
- this.refundAmount = refundAmount;
- }
-
- public boolean isZero() {
- return (totalAmount == 0 && totalCount == 0
- && payAmount == 0 && payCount == 0 && refundAmount == 0 && refundCount == 0);
- }
-
- @Override
- public String toString() {
- return totalCount +
- ", " + totalAmount +
- ", " + payCount +
- ", " + payAmount +
- ", " + refundCount +
- ", " + refundAmount;
- }
-}
diff --git a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/controller/YnrccApiController.java b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/controller/YnrccApiController.java
index 52fa611..508b297 100644
--- a/ynrcc-agent/src/main/java/com/supwisdom/agent/api/controller/YnrccApiController.java
+++ b/ynrcc-agent/src/main/java/com/supwisdom/agent/api/controller/YnrccApiController.java
@@ -4,12 +4,12 @@
import com.supwisdom.agent.Util.DlpayUtil;
import com.supwisdom.agent.Util.ErrorCode;
import com.supwisdom.agent.Util.StringUtil;
-import com.supwisdom.agent.api.bean.CheckFileHeader;
import com.supwisdom.agent.api.bean.CheckFileLine;
import com.supwisdom.agent.api.bean.DlpayReq;
import com.supwisdom.agent.api.bean.DlpayResp;
import com.supwisdom.agent.api.service.YnrccApiService;
import com.supwisdom.agent.api.service.YnrccParamCheckService;
+import com.supwisdom.dlpay.api.agent.Constant;
import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -38,10 +38,10 @@
* 第一行:总笔数|总金额|代扣总笔数|代扣总金额|退款总笔数|退款总金额|
* 第二行及以后:交易日期|交易时间|报文业务类型|业务系统流水号|银行流水号|付款银行卡号|收款商户银行卡号|核心记账日期|交易金额|交易摘要|
*/
- private static final String[] chkFileColumnList = new String[]{"transdate", "transtime", "flag", "refno", "agentrefno",
- "payerid", "payeeid", "agentdate", "amount", "summary"};
- private static final String[] chkFileHeaderColumnList = new String[]{"totalCount", "totalAmount", "payCount",
- "payAmount", "refundCount", "refundAmount"};
+ private static final String[] chkFileColumnList = new String[]{"transdate", "transtime", Constant.COL_FLAG,
+ Constant.COL_REFNO, Constant.COL_AGENT_REFNO, Constant.COL_PAYERID, Constant.COL_PAYEEID,
+ Constant.COL_AGENT_DATE, Constant.COL_AMOUNT, Constant.COL_SUMMARY};
+
private static final String chkFileDelimiter = "|";
private static final String FLAG_WITHHOLD = "BC5512";
private static final String FLAG_REFUND = "BC5513";
@@ -394,7 +394,7 @@
}
private <T> void populate(String[] fields, String[] column, T bean) {
- if (fields.length != column.length) {
+ if (fields.length < column.length) {
throw new IllegalArgumentException("错误的列定义");
}
try {
@@ -413,6 +413,7 @@
try {
T bean = beanClass.newInstance();
populate(fields, column, bean);
+ return bean;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
@@ -421,10 +422,10 @@
throw new IllegalArgumentException("错误的列定义");
}
- private void writeLine(OutputStream output, String delimiter, Object... columns) throws IOException {
+ private void writeLine(OutputStream output, Object... columns) throws IOException {
for (Object item : columns) {
output.write(item.toString().getBytes(StandardCharsets.UTF_8));
- output.write(delimiter.getBytes());
+ output.write(Constant.CHKFILE_DELIMITER.getBytes(StandardCharsets.UTF_8));
}
output.write("\n".getBytes());
}
@@ -440,13 +441,15 @@
throw new IllegalArgumentException("数据文件内容为空");
}
- CheckFileHeader fileHeader = populate(chkFileHeaderColumnList,
+ CheckFileHeader fileHeader = populate(CheckFileHeader.chkFileHeaderColumnList,
header.split(chkFileDelimiter), CheckFileHeader.class);
CheckFileLine record = new CheckFileLine();
- writeLine(output, ",", "refno", "agentrefno", "agentdate", "flag", "payerid",
- "payeeid", "amount", "summary");
+ writeLine(output, Constant.COL_REFNO, Constant.COL_AGENT_REFNO,
+ Constant.COL_AGENT_DATE, Constant.COL_FLAG, Constant.COL_PAYERID,
+ Constant.COL_PAYEEID, Constant.COL_STATUS,
+ Constant.COL_AMOUNT, Constant.COL_SUMMARY);
while (true) {
String line = reader.readLine();
if (line == null) {
@@ -459,12 +462,12 @@
String flag;
if (FLAG_WITHHOLD.equals(record.getFlag())) {
amount = -record.getAmount();
- flag = "pay";
+ flag = Constant.FLAG_PAY;
fileHeader.setPayCount(fileHeader.getPayCount() - 1);
fileHeader.setPayAmount(fileHeader.getPayAmount() - record.getAmount());
} else if (FLAG_REFUND.equals(record.getFlag())) {
amount = +record.getAmount();
- flag = "refund";
+ flag = Constant.FLAG_REFUND;
fileHeader.setRefundCount(fileHeader.getRefundCount() - 1);
fileHeader.setRefundAmount(fileHeader.getRefundAmount() - record.getAmount());
} else {
@@ -472,9 +475,8 @@
}
fileHeader.setTotalCount(fileHeader.getTotalCount() - 1);
fileHeader.setTotalAmount(fileHeader.getTotalAmount() - record.getAmount());
- writeLine(output, ",", record.getRefno(),
- record.getAgentrefno(), record.getAgentdate(),
- flag, record.getPayerid(), record.getPayeeid(),
+ writeLine(output, record.getRefno(), record.getAgentrefno(), record.getAgentdate(),
+ flag, record.getPayerid(), record.getPayeeid(), Constant.STATUS_SUCCESS,
amount, record.getSummary());
}
if (!fileHeader.isZero()) {
@@ -495,4 +497,73 @@
response.sendError(HttpStatus.SERVICE_UNAVAILABLE.value(), e.getMessage());
}
}
+
+
+ /**
+ * 第一行:总笔数|总金额|代扣总笔数|代扣总金额|退款总笔数|退款总金额|
+ */
+ private static class CheckFileHeader {
+ static final String[] chkFileHeaderColumnList = new String[]{"totalCount", "totalAmount", "payCount",
+ "payAmount", "refundCount", "refundAmount"};
+
+ private int totalCount;
+ private int totalAmount;
+ private int payCount;
+ private int payAmount;
+ private int refundCount;
+ private int refundAmount;
+
+ int getTotalCount() {
+ return totalCount;
+ }
+
+ void setTotalCount(int totalCount) {
+ this.totalCount = totalCount;
+ }
+
+ int getTotalAmount() {
+ return totalAmount;
+ }
+
+ void setTotalAmount(int totalAmount) {
+ this.totalAmount = totalAmount;
+ }
+
+ int getPayCount() {
+ return payCount;
+ }
+
+ void setPayCount(int payCount) {
+ this.payCount = payCount;
+ }
+
+ int getPayAmount() {
+ return payAmount;
+ }
+
+ void setPayAmount(int payAmount) {
+ this.payAmount = payAmount;
+ }
+
+ int getRefundCount() {
+ return refundCount;
+ }
+
+ void setRefundCount(int refundCount) {
+ this.refundCount = refundCount;
+ }
+
+ int getRefundAmount() {
+ return refundAmount;
+ }
+
+ void setRefundAmount(int refundAmount) {
+ this.refundAmount = refundAmount;
+ }
+
+ boolean isZero() {
+ return (totalAmount == 0 && totalCount == 0
+ && payAmount == 0 && payCount == 0 && refundAmount == 0 && refundCount == 0);
+ }
+ }
}