From: Tang Cheng Date: Tue, 18 Jun 2019 01:17:30 +0000 (+0800) Subject: 修改商户更新逻辑,改进业务模式 X-Git-Tag: 1.0.0^2~177 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=c3ab962f986d2ee2b3df75ce691631c05b9256fb;p=epayment%2Ffood_payapi.git 修改商户更新逻辑,改进业务模式 --- diff --git a/src/main/java/com/supwisdom/dlpay/api/dao/ShopdtlDao.java b/src/main/java/com/supwisdom/dlpay/api/dao/ShopdtlDao.java index d8dda28b..611d3cb1 100644 --- a/src/main/java/com/supwisdom/dlpay/api/dao/ShopdtlDao.java +++ b/src/main/java/com/supwisdom/dlpay/api/dao/ShopdtlDao.java @@ -3,8 +3,13 @@ package com.supwisdom.dlpay.api.dao; import com.supwisdom.dlpay.api.domain.TShopdtl; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Lock; import org.springframework.stereotype.Repository; +import javax.persistence.LockModeType; + @Repository -public interface ShopdtlDao extends JpaRepository,JpaSpecificationExecutor { +public interface ShopdtlDao extends JpaRepository, JpaSpecificationExecutor { + @Lock(LockModeType.OPTIMISTIC) + TShopdtl findTShopdtlByRefno(String refno); } diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TAccount.java b/src/main/java/com/supwisdom/dlpay/api/domain/TAccount.java index b7dac869..2a89febc 100644 --- a/src/main/java/com/supwisdom/dlpay/api/domain/TAccount.java +++ b/src/main/java/com/supwisdom/dlpay/api/domain/TAccount.java @@ -2,12 +2,11 @@ package com.supwisdom.dlpay.api.domain; import com.supwisdom.dlpay.framework.util.MD5; import com.supwisdom.dlpay.framework.util.MoneyUtil; -import com.supwisdom.dlpay.system.common.DictPool; import org.hibernate.annotations.GenericGenerator; -import org.springframework.beans.factory.annotation.Autowired; import javax.persistence.*; import java.io.Serializable; +import java.sql.Timestamp; @Entity @Table(name = "TB_ACCOUNT", @@ -54,8 +53,8 @@ public class TAccount implements Serializable { @Column(name = "MAX_BAL", precision = 15, scale = 2) private Double maxbal; // 最大余额限制 - @Column(name = "LAST_TRANSDATE", length = 8) - private String lasttransdate; //最后交易日期 + @Column(name = "LAST_TRANSTIME", length = 8) + private Timestamp lasttranstime; //最后交易日期 @Column(name = "LASTDAY_TRANSAMT", precision = 9, scale = 2) private Double lastdayTransamt; //最后一天消费金额 @@ -72,10 +71,6 @@ public class TAccount implements Serializable { @Column(name = "CLOSEDATE", length = 8) private String closedate; - @Version - @Column(name = "optlock", columnDefinition = "integer DEFAULT 0", nullable = false) - private Long version; - @OneToOne @JoinColumn(name = "USERID", insertable = false, updatable = false) private TPerson person; @@ -83,7 +78,7 @@ public class TAccount implements Serializable { public TAccount() { } - public TAccount(String accname, String subjno, String userid, String status, Double balance, Double availbal, Double frozebal, Boolean lowfreeFlag, Double lowfreeLimit, Double daylimit, Double maxbal, String lasttransdate, Double lastdayTransamt, Double lastdayDpsamt, String tac, String opendate, String closedate) { + public TAccount(String accname, String subjno, String userid, String status, Double balance, Double availbal, Double frozebal, Boolean lowfreeFlag, Double lowfreeLimit, Double daylimit, Double maxbal, Timestamp lasttranstime, Double lastdayTransamt, Double lastdayDpsamt, String tac, String opendate, String closedate) { this.accname = accname; this.subjno = subjno; this.userid = userid; @@ -95,7 +90,7 @@ public class TAccount implements Serializable { this.lowfreeLimit = lowfreeLimit; this.daylimit = daylimit; this.maxbal = maxbal; - this.lasttransdate = lasttransdate; + this.lasttranstime = lasttranstime; this.lastdayTransamt = lastdayTransamt; this.lastdayDpsamt = lastdayDpsamt; this.tac = tac; @@ -199,12 +194,12 @@ public class TAccount implements Serializable { this.maxbal = maxbal; } - public String getLasttransdate() { - return lasttransdate; + public Timestamp getLasttranstime() { + return lasttranstime; } - public void setLasttransdate(String lasttransdate) { - this.lasttransdate = lasttransdate; + public void setLasttranstime(Timestamp lasttranstime) { + this.lasttranstime = lasttranstime; } public Double getLastdayTransamt() { @@ -297,11 +292,4 @@ public class TAccount implements Serializable { this.person = person; } - public Long getVersion() { - return version; - } - - public void setVersion(Long version) { - this.version = version; - } } diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TShopdtl.java b/src/main/java/com/supwisdom/dlpay/api/domain/TShopdtl.java index 76f97a4e..aeae783c 100644 --- a/src/main/java/com/supwisdom/dlpay/api/domain/TShopdtl.java +++ b/src/main/java/com/supwisdom/dlpay/api/domain/TShopdtl.java @@ -6,7 +6,8 @@ import javax.persistence.*; @Table(name = "TB_SHOPDTL", indexes = {@Index(name = "shopdtl_accdate", columnList = "accdate"), @Index(name = "shopdtl_shopaccno", columnList = "shopaccno"), - @Index(name = "shopdtl_transdate", columnList = "transdate")}) + @Index(name = "shopdtl_transdate", columnList = "transdate"), + @Index(name = "shopdtl_updateflag", columnList = "updatebala")}) public class TShopdtl { @Id @Column(name = "REFNO", length = 32, nullable = false) @@ -51,6 +52,9 @@ public class TShopdtl { @Column(name = "STATUS", length = 20) private String status; + @Column(name = "updatebala") + private Boolean updateBala; + @Column(name = "OPPOSITEACCNO", length = 64) private String oppositeAccNo; @@ -195,4 +199,12 @@ public class TShopdtl { public void setRemark(String remark) { this.remark = remark; } + + public Boolean getUpdateBala() { + return updateBala; + } + + public void setUpdateBala(Boolean updateBala) { + this.updateBala = updateBala; + } } diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/DateUtil.java b/src/main/java/com/supwisdom/dlpay/framework/util/DateUtil.java index 3a7e0136..fd187715 100644 --- a/src/main/java/com/supwisdom/dlpay/framework/util/DateUtil.java +++ b/src/main/java/com/supwisdom/dlpay/framework/util/DateUtil.java @@ -3,6 +3,7 @@ package com.supwisdom.dlpay.framework.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; @@ -324,4 +325,21 @@ public class DateUtil { public static String getUTCTime() { return getUTCTime(System.currentTimeMillis()); } + + public static int compareDay(Timestamp d1, Timestamp d2) { + Calendar cd1 = Calendar.getInstance(); + cd1.setTimeInMillis(d1.getTime()); + Calendar cd2 = Calendar.getInstance(); + cd2.setTimeInMillis(d2.getTime()); + + if (cd1.get(Calendar.YEAR) != cd2.get(Calendar.YEAR)) { + return cd1.compareTo(cd2); + } + + return Integer.compare(cd1.get(Calendar.DAY_OF_YEAR), cd2.get(Calendar.DAY_OF_YEAR)); + } + + public static Boolean sameDay(Timestamp d1, Timestamp d2) { + return (compareDay(d1, d2) == 0); + } } diff --git a/src/main/java/com/supwisdom/dlpay/system/service/impl/UserDataServiceImpl.java b/src/main/java/com/supwisdom/dlpay/system/service/impl/UserDataServiceImpl.java index 54694f56..06def11a 100644 --- a/src/main/java/com/supwisdom/dlpay/system/service/impl/UserDataServiceImpl.java +++ b/src/main/java/com/supwisdom/dlpay/system/service/impl/UserDataServiceImpl.java @@ -110,7 +110,6 @@ public class UserDataServiceImpl implements UserDataService { account.setFrozebal(0.0); account.setLowfreeFlag(false); account.setMaxbal(systemUtilService.getSysparaValueAsDouble(SysparaUtil.SYSPARAID_NO1, SysparaUtil.SYSPARA_NO1_DEFAULT)); - account.setLasttransdate(systemDateTime.getHostdate()); account.setLastdayDpsamt(0.0); account.setLastdayTransamt(0.0); account.setOpendate(systemDateTime.getHostdate()); diff --git a/src/main/kotlin/com/supwisdom/dlpay/account_process_async.kt b/src/main/kotlin/com/supwisdom/dlpay/account_process_async.kt new file mode 100644 index 00000000..a1bd2f02 --- /dev/null +++ b/src/main/kotlin/com/supwisdom/dlpay/account_process_async.kt @@ -0,0 +1,70 @@ +package com.supwisdom.dlpay + +import com.supwisdom.dlpay.api.dao.ShopdtlDao +import com.supwisdom.dlpay.api.dao.TransactionMainDao +import com.supwisdom.dlpay.api.repositories.ShopaccService +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.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("shopAccBalanceUpdater") + fun threadPoolExecutor(): Executor { + return ThreadPoolTaskExecutor().apply { + corePoolSize = 10 + maxPoolSize = 30 + setWaitForTasksToCompleteOnShutdown(true) + } + } + + override fun getAsyncUncaughtExceptionHandler(): AsyncUncaughtExceptionHandler? { + return MyAsyncUncaughtExceptionHandler() + } +} + +class MyAsyncUncaughtExceptionHandler : AsyncUncaughtExceptionHandler { + private val logger = KotlinLogging.logger { } + override fun handleUncaughtException(ex: Throwable, method: Method, vararg params: Any?) { + logger.error { "Async Task execute error: <${method.name}>, exception <${ex.message}>" } + } +} + + +@Component +class ShopAccBalanceAsyncTask { + private val logger = KotlinLogging.logger { } + + @Autowired + private lateinit var transactionMainDao: TransactionMainDao + + @Autowired + lateinit var shopdltDao: ShopdtlDao + + @Autowired + private lateinit var shopaccService: ShopaccService + + @Async("shopAccBalanceUpdater") + fun updateShopBalance(shopdtlRefno: String) { + shopdltDao.findTShopdtlByRefno(shopdtlRefno)?.also { + if (it.updateBala) { + logger.warn { "shop balance update refno <$shopdtlRefno> has been updated" } + return + } + }?.also { + shopaccService.recalcShopBalance(it, it.amount, true) + it.updateBala = true + shopdltDao.save(it) + } ?: logger.warn { "shop balance updater refno<$shopdtlRefno> not found" } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/controller/shop_api_controller.kt b/src/main/kotlin/com/supwisdom/dlpay/api/controller/shop_api_controller.kt index d7f333b3..ef9b1947 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/api/controller/shop_api_controller.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/api/controller/shop_api_controller.kt @@ -44,9 +44,6 @@ class ShopAPIController { .data("shopaccno", it.shopaccno ?: "") .success("注册成功")) } - - return ResponseEntity.ok(ResponseBodyBuilder.create() - .fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "商户注册失败")) } catch (ex: RequestParamCheckException) { return ResponseEntity.ok(ResponseBodyBuilder.create() .requestException(ex, "请求参数错误")) diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt index 9622f619..b7b4604f 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt @@ -6,6 +6,8 @@ import com.supwisdom.dlpay.api.repositories.ShopaccService import com.supwisdom.dlpay.exception.TransactionProcessException import com.supwisdom.dlpay.framework.domain.TShopacc import com.supwisdom.dlpay.framework.service.SystemUtilService +import com.supwisdom.dlpay.framework.util.DateUtil +import com.supwisdom.dlpay.framework.util.TradeDict import com.supwisdom.dlpay.framework.util.TradeErrorCode import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Repository @@ -58,14 +60,25 @@ class AccountServiceImpl : AccountService { doRecalcAccountBalance(dtl, account) account.availbal += dtl.amount account.balance += dtl.amount - account.lasttransdate = dtl.accdate + + val sameDay = DateUtil.sameDay(account.lasttranstime, + systemUtilServcie.sysdatetime.currentTimestamp) ?: false + + if (!sameDay) { + account.lastdayTransamt = 0.0 + account.lastdayDpsamt = 0.0 + } + if (dtl.tradeflag == TradeDict.TRADE_FLAG_OUT) { + account.lastdayTransamt += amount + } else { + account.lastdayDpsamt += amount + } try { entityManager.persist(account) } catch (ex: OptimisticLockException) { throw TransactionProcessException(TradeErrorCode.ACCOUNT_TRADE_BUSY, "个人账户被被更新") } - } ?: throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "交易流水<${dtl.refno}>未找到指定个人账户") } diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt index ab253c01..17b45f0a 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt @@ -1,5 +1,6 @@ package com.supwisdom.dlpay.api.service.impl +import com.supwisdom.dlpay.ShopAccBalanceAsyncTask import com.supwisdom.dlpay.api.TransactionBuilder import com.supwisdom.dlpay.api.dao.PersondtlDao import com.supwisdom.dlpay.api.dao.TransactionMainDao @@ -46,6 +47,9 @@ class TransactionServiceImpl : TransactionService { @Autowired private lateinit var sourceTypeService: SourceTypeService + @Autowired + private lateinit var shopAccBalanceAsyncTask: ShopAccBalanceAsyncTask + private fun preCheck(builder: TransactionBuilder) { builder.preCheck() @@ -384,10 +388,11 @@ class TransactionServiceImpl : TransactionService { transaction.shopDtl.shopaccno, Subject.SUBJNO_MACHANT_INCOME, SHOP_BALANCE_FLAG, "both") if (amount.compareTo(0.0) != 0) { - transaction.shopDtl?.let { - shopaccService.recalcShopBalance(it, it.amount, overdraft) - } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, - "商户流水<${transaction.refno}>不存在") +// transaction.shopDtl?.let { +// shopaccService.recalcShopBalance(it, amount, overdraft) +// } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, +// "商户流水<${transaction.refno}>不存在") +// shopAccBalanceAsyncTask.updateShopBalance(transaction.shopDtl.refno) } transaction.shopDtl.status = TradeDict.DTL_STATUS_SUCCESS transaction.shopDtl.accdate = transaction.accdate diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/user_service_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/user_service_impl.kt index 91fef265..1049c262 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/user_service_impl.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/user_service_impl.kt @@ -69,7 +69,7 @@ class UserServiceImpl : UserService { lowfreeLimit = lowfreeLimit daylimit = daylimit maxbal = systemUtilService.getSysparaValueAsDouble(SysparaUtil.SYSPARAID_NO1, SysparaUtil.SYSPARA_NO1_DEFAULT) - lasttransdate = systemdatetime.hostdate + lasttranstime = systemdatetime.currentTimestamp lastdayTransamt = 0.0 lastdayDpsamt = 0.0 opendate = systemdatetime.hostdate diff --git a/src/main/resources/templates/system/user/account.html b/src/main/resources/templates/system/user/account.html index 2475cf9c..db0e644c 100644 --- a/src/main/resources/templates/system/user/account.html +++ b/src/main/resources/templates/system/user/account.html @@ -51,7 +51,7 @@ {field: 'availbal', title: '可用余额', width: 100,fixed: 'left', sort: true}, {field: 'balance', title: '总余额', width: 100,fixed: 'left', sort: true}, {field: 'frozebal', title: '冻结余额', width: 100,fixed: 'left', sort: true}, - {field: 'lasttransdate', title: '最后交易日期', width: 120,fixed: 'left', sort: true}, + {field: 'lasttranstime', title: '最后交易日期', width: 120,fixed: 'left', sort: true}, {field: 'opendate', title: '开户日期', width: 100,fixed: 'left', sort: true}, { field: 'accno', align: 'center', title: '操作', fixed: 'right', templet: function (item) {