充值记流水
diff --git a/src/main/java/com/supwisdom/dlpay/api/dao/TransactionMainDao.java b/src/main/java/com/supwisdom/dlpay/api/dao/TransactionMainDao.java
index 649758d..476a1fa 100644
--- a/src/main/java/com/supwisdom/dlpay/api/dao/TransactionMainDao.java
+++ b/src/main/java/com/supwisdom/dlpay/api/dao/TransactionMainDao.java
@@ -15,4 +15,10 @@
@QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value = "0")})
@Query(value = "select t from TTransactionMain t where t.refno = ?1")
TTransactionMain findByRefnoForUpdate(String refno);
+
+
+ TTransactionMain findByRefno(String refno);
+
+ @Query("select t from TTransactionMain t where t.outTradeNo=?1 and t.outId=?2")
+ TTransactionMain findByBillno(String billno, String outid);
}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/Subject.java b/src/main/java/com/supwisdom/dlpay/framework/util/Subject.java
index 4a46b28..e80344a 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/Subject.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/Subject.java
@@ -28,6 +28,11 @@
public static final String SUBJNO_RECHARGE_CASH = "112201";
/**
+ * 应收账款 - 其他第三方充值款
+ */
+ public static final String SUBJNO_RECHARGE_OTHER = "112209";
+
+ /**
* 应收账款 - 支付宝充值款
*/
public static final String SUBJNO_RECHARGE_ALIPAY = "112210";
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java b/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java
index 20cd922..cc1b344 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/TradeCode.java
@@ -12,6 +12,9 @@
public static final int TRANSCODE_WECHAT=1001;
- public static final int TRANSTYPE_PAY = 311;
- public static final int TRANSTYPE_YKTPAY=1000;
+ public static final int TRANSCODE_ERCHARGE = 3500; //账户充值
+
+
+
+
}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java b/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
index 2928642..a72913a 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/TradeDict.java
@@ -68,6 +68,7 @@
public static final String PAYTYPE_WECHAT = "wechat"; //市民卡
public static final String PAYTYPE_CITIZEN_CARD = "citizenCard"; //市民卡
public static final String PAYTYPE_YKT_CARD = "yktpay"; //一卡通
+ public static final String PAYTYPE_OTHER_THIRDPART = "thirdpart"; //其他第三方
/**
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt b/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
index 6e06756..aab9a8d 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/bean/api_request_param.kt
@@ -250,4 +250,57 @@
+// ============================ RECHARGE ============================ //
+class CommonRechargeInitParam : APIRequestParam() {
+ @Sign
+ var userid: String = "" //用户ID
+ @Sign
+ var amount: Int = 0 //必传
+
+ var feelist: List<ConsumeFeetype>? = null //TODO: 怎么拼接签名字符串??
+ @Sign
+ var sourcetype: String = "" //必传,充值方式
+ @Sign
+ var billno: String = "" //必传
+ @Sign
+ var transdate: String = "" //必传
+ @Sign
+ var transtime: String = "" //必传
+
+ override fun checkParam(): Boolean {
+ if (StringUtil.isEmpty(userid)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "请指定充值用户")
+ if (amount <= 0) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "充值金额必须大于零")
+ if (StringUtil.isEmpty(sourcetype)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "请指定充值的支付方式")
+ if (StringUtil.isEmpty(billno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "对接系统唯一订单号不能为空")
+ if (!DateUtil.checkDatetimeValid(transdate, DateUtil.DATE_FMT)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "交易日期错误[yyyyMMdd]")
+ if (!DateUtil.checkDatetimeValid(transtime, DateUtil.TIME_FMT)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "交易时间错误[HHmmss]")
+
+ return true
+ }
+}
+
+class CommonRechargeConfirmParam : APIRequestParam() {
+ @Sign
+ var refno:String = "" //流水号
+
+ override fun checkParam(): Boolean {
+ if(StringUtil.isEmpty(refno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "流水号不能为空")
+
+ return true
+ }
+}
+
+class CommonQueryRechargeResultParam : APIRequestParam() {
+ @Sign
+ var refno: String? = null //流水号
+ @Sign
+ var billno: String? = null
+
+ override fun checkParam(): Boolean {
+ if (StringUtil.isEmpty(refno) || StringUtil.isEmpty(billno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "流水号不能为空")
+
+ return true
+ }
+}
+
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/controller/charge_api_controller.kt b/src/main/kotlin/com/supwisdom/dlpay/api/controller/charge_api_controller.kt
new file mode 100644
index 0000000..cb5ad33
--- /dev/null
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/controller/charge_api_controller.kt
@@ -0,0 +1,156 @@
+package com.supwisdom.dlpay.api.controller
+
+import com.supwisdom.dlpay.api.AccountProxy
+import com.supwisdom.dlpay.api.TransactionBuilder
+import com.supwisdom.dlpay.api.bean.*
+import com.supwisdom.dlpay.api.service.AccountUtilServcie
+import com.supwisdom.dlpay.api.service.ChargeApiService
+import com.supwisdom.dlpay.api.service.TransactionService
+import com.supwisdom.dlpay.api.service.UserService
+import com.supwisdom.dlpay.exception.TransactionCheckException
+import com.supwisdom.dlpay.exception.TransactionProcessException
+import com.supwisdom.dlpay.framework.ResponseBodyBuilder
+import com.supwisdom.dlpay.framework.service.CommonService
+import com.supwisdom.dlpay.framework.service.SystemUtilService
+import com.supwisdom.dlpay.framework.util.Subject
+import com.supwisdom.dlpay.framework.util.TradeCode
+import com.supwisdom.dlpay.framework.util.TradeDict
+import com.supwisdom.dlpay.framework.util.TradeErrorCode
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.http.ResponseEntity
+import org.springframework.security.core.Authentication
+import org.springframework.web.bind.annotation.PostMapping
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RestController
+
+@RestController
+@RequestMapping("/api/recharge")
+class ChargeAPIController {
+ @Autowired
+ lateinit var accountUtilServcie: AccountUtilServcie
+ @Autowired
+ lateinit var systemUtilService: SystemUtilService
+ @Autowired
+ lateinit var transactionService: TransactionService
+ @Autowired
+ lateinit var commonService: CommonService
+ @Autowired
+ lateinit var userService: UserService
+ @Autowired
+ lateinit var chargeApiService: ChargeApiService
+
+
+ /**
+ * ============================================================================
+ * 通用充值(只记流水)
+ * ============================================================================
+ * */
+ @PostMapping("/common/init")
+ fun rechargeInit(@RequestBody param: CommonRechargeInitParam, authentication: Authentication): ResponseEntity<Any> {
+ if (param.checkSign(commonService.getSecretByAppid(authentication.name))) {
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误"))
+ }
+
+ if(chargeApiService.checkRechargeSourcetype(param.sourcetype)) {
+ val person = userService.findOnePersonByUserid(param.userid)
+ val account = accountUtilServcie.readAccount(person.userid)
+ val rechargeDrsubjno = when (param.sourcetype) {
+ //根据不同支付方式确定借方科目,fixme:可根据outid或clientId自定义
+
+ TradeDict.PAYTYPE_CASH -> accountUtilServcie.readSubject(Subject.SUBJNO_RECHARGE_CASH)
+ TradeDict.PAYTYPE_OTHER_THIRDPART -> accountUtilServcie.readSubject(Subject.SUBJNO_RECHARGE_OTHER)
+ else -> throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "充值支付方式<${param.sourcetype}>未确定所属科目")
+ }
+
+ val transaction = TransactionBuilder().apply {
+ setTransInfo(param.transdate, param.transtime,
+ TradeCode.TRANSCODE_ERCHARGE,
+ param.sourcetype)
+ setOutTransInfo(authentication.name, param.billno) //fixme: outid取clientId
+// operator("", TradeDict.OPERTYPE_OPER) //充值操作员
+ payinfo = ""
+ description = "账户充值"
+ }.person(account).apply {
+ setAmount(param.amount / 100.0, TradeDict.TRADE_FLAG_IN)
+ this.opposite = AccountProxy(rechargeDrsubjno)
+ }.and().addDebitCreditRecord(AccountProxy(rechargeDrsubjno), AccountProxy(account),
+ param.amount / 100.0, "账户充值")
+ .also { builder ->
+ param.feelist?.forEach {
+ val feeamt = it.amount / 100.0
+ when (it.feetype) {
+ TradeDict.PAYTYPE_RECHARGE_COUPON -> {
+ //优惠折扣 优惠科目 -> 个人账户
+ val feetypeConfig = accountUtilServcie.readFeetype(TradeDict.PAYTYPE_RECHARGE_COUPON, param.sourcetype)
+ val subject = accountUtilServcie.readSubject(feetypeConfig.drsubjno) //不同在借方折扣科目
+ builder.addDebitCreditRecord(AccountProxy(subject), AccountProxy(account), feeamt, feetypeConfig.summary)
+ }
+ //fixme: 服务费暂缺
+// TradeDict.PAYTYPE_RECHARGE_SERVICEFEE -> {
+// //收服务费 借方 -> 服务费科目
+// val feetypeConfig = accountUtilServcie.readFeetype(TradeDict.PAYTYPE_RECHARGE_SERVICEFEE, param.sourcetype)
+// val subject = accountUtilServcie.readSubject(feetypeConfig.crsubjno) //不同在服务费放在贷方科目
+// builder.addDebitCreditRecord(AccountProxy(rechargeDrsubjno), AccountProxy(subject), feeamt, feetypeConfig.summary)
+//
+// }
+ else -> throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "充值费用清单不支持feetype<${it.feetype}>")
+ }
+ }
+ }.init(transactionService)
+
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .data("refno", transaction.refno)
+ .data("amount", transaction.personDtl.amount)
+ .success("初始化成功"))
+
+ }
+
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "充值不支持支付方式<${param.sourcetype}>"))
+ }
+
+ @PostMapping("/common/confirm")
+ fun rechargeConfirm(@RequestBody param: CommonRechargeConfirmParam, authentication: Authentication): ResponseEntity<Any> {
+ if (param.checkSign(commonService.getSecretByAppid(authentication.name))) {
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误"))
+ }
+
+ transactionService.success(param.refno).let {
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .data("refno", it.refno)
+ .data("billno", it.outTradeNo)
+ .success("交易确认成功"))
+ }
+
+ }
+
+ /**
+ * ============================================================================
+ * 查询充值流水状态
+ * ============================================================================
+ * */
+ @PostMapping("/queryresult")
+ fun rechargeConfirm(@RequestBody param: CommonQueryRechargeResultParam, authentication: Authentication): ResponseEntity<Any> {
+ if (param.checkSign(commonService.getSecretByAppid(authentication.name))) {
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误"))
+ }
+
+ chargeApiService.getTransactionMainDtl(param.refno, param.billno, authentication.name).let {
+ if (null == it) {
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(TradeErrorCode.TRANSACTION_NOT_EXISTS, "充值流水不存在"))
+ }
+
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .data("refno", it.refno)
+ .data("billno", it.outTradeNo)
+ .data("status", it.status)
+ .success("查询成功"))
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt b/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
index 4a8241d..c1ed619 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
@@ -30,7 +30,7 @@
@RestController
@RequestMapping("/api/consume")
-class ConsumeController {
+class ConsumeAPIController {
@Autowired
lateinit var accountUtilServcie: AccountUtilServcie
@Autowired
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/charge_api_service.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/charge_api_service.kt
new file mode 100644
index 0000000..e0e010e
--- /dev/null
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/charge_api_service.kt
@@ -0,0 +1,13 @@
+package com.supwisdom.dlpay.api.service
+
+import com.supwisdom.dlpay.api.domain.TTransactionMain
+import org.springframework.transaction.annotation.Propagation
+import org.springframework.transaction.annotation.Transactional
+
+interface ChargeApiService {
+ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class], readOnly = true)
+ fun checkRechargeSourcetype(sourceType: String): Boolean
+
+ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class], readOnly = true)
+ fun getTransactionMainDtl(refno: String?, billno: String?, outid: String?): TTransactionMain?
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/consume_pay_service.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/consume_pay_service.kt
index 412fdf5..1fa74f3 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/service/consume_pay_service.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/consume_pay_service.kt
@@ -4,12 +4,12 @@
import org.springframework.transaction.annotation.Transactional
interface ConsumePayService {
- @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
+ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class], readOnly = true)
fun checkShopPaytype(shopaccno: String, sourceType: String, anonymousflag: Boolean? = false): Boolean
- @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
+ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class], readOnly = true)
fun getPaytypeConfig(paytype: String, shopaccno: String, anonymousflag: Boolean? = false, ignoreStatus: Boolean? = false): Map<String, String?>
- @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
+ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class], readOnly = true)
fun getUserdtlExtendParamMap(refno: String): Map<String, String>
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/charge_api_service_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/charge_api_service_impl.kt
new file mode 100644
index 0000000..7c393a8
--- /dev/null
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/charge_api_service_impl.kt
@@ -0,0 +1,40 @@
+package com.supwisdom.dlpay.api.service.impl
+
+import com.supwisdom.dlpay.api.dao.SourceTypeDao
+import com.supwisdom.dlpay.api.dao.TransactionMainDao
+import com.supwisdom.dlpay.api.domain.TTransactionMain
+import com.supwisdom.dlpay.api.service.ChargeApiService
+import com.supwisdom.dlpay.exception.TransactionProcessException
+import com.supwisdom.dlpay.framework.util.StringUtil
+import com.supwisdom.dlpay.framework.util.TradeErrorCode
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.stereotype.Service
+
+@Service
+class ChargeApiServiceImpl : ChargeApiService {
+ @Autowired
+ lateinit var sourceTypeDao: SourceTypeDao
+ @Autowired
+ lateinit var transactionMainDao: TransactionMainDao
+
+ override fun checkRechargeSourcetype(sourceType: String): Boolean {
+ sourceTypeDao.getBySourceType(sourceType).let {
+ if (null == it) {
+ throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "系统不支持支付方式[$sourceType]")
+ } else {
+ if (!it.enable || !it.isChargeEnable) {
+ throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "系统充值未启用支付方式[$sourceType]")
+ }
+ }
+ }
+
+ return true
+ }
+
+ override fun getTransactionMainDtl(refno: String?, billno: String?, outid: String?): TTransactionMain? {
+ return when (!StringUtil.isEmpty(refno)) {
+ true -> transactionMainDao.findByRefno(refno)
+ false -> transactionMainDao.findByBillno(billno, outid)
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/Consume_pay_service_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/consume_pay_service_impl.kt
similarity index 100%
rename from src/main/kotlin/com/supwisdom/dlpay/api/service/impl/Consume_pay_service_impl.kt
rename to src/main/kotlin/com/supwisdom/dlpay/api/service/impl/consume_pay_service_impl.kt
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 fa30ada..91fef26 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
@@ -167,4 +167,9 @@
}
}
+ override fun findOnePersonByUserid(userid: String): TPerson {
+ return personDao.findByUserid(userid)
+ ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "用户<$userid>不存在")
+ }
+
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/user_service.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/user_service.kt
index c4d9b20..6ac023e 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/service/user_service.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/user_service.kt
@@ -40,4 +40,7 @@
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class), readOnly = true)
fun findPersonByIdentityCheckStatus(thirdUniqueIdenty: String): TPerson
+ @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class), readOnly = true)
+ fun findOnePersonByUserid(userid: String): TPerson
+
}
\ No newline at end of file
diff --git a/src/main/resources/templates/ologin.html b/src/main/resources/templates/ologin.html
index 41302e1..8f9362e 100644
--- a/src/main/resources/templates/ologin.html
+++ b/src/main/resources/templates/ologin.html
@@ -85,6 +85,11 @@
base: 'custom/module/'
}).use(['form'], function () {
var $ = layui.jquery;
+
+ // 图形验证码
+ $('.login-captcha').click(function () {
+ this.src = this.src + '?t=' + (new Date).getTime();
+ });
});
</script>
</body>