From 3a7b5ed65d478a3af0b8b10f8ead977021ce8486 Mon Sep 17 00:00:00 2001 From: Tang Cheng Date: Wed, 22 May 2019 17:19:15 +0800 Subject: [PATCH] =?utf8?q?=E5=88=A0=E9=99=A4=E5=8E=9F=E6=9D=A5=E7=9A=84?= =?utf8?q?=E8=AE=B0=E8=B4=A6=E6=A8=A1=E5=9D=97=EF=BC=8C=E5=B9=B6=E6=B3=A8?= =?utf8?q?=E9=87=8A=E9=83=A8=E5=88=86=E6=9C=AA=E5=85=BC=E5=AE=B9=E6=96=B0?= =?utf8?q?=E8=AE=B0=E8=B4=A6=E6=A8=A1=E5=9D=97=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../dlpay/api/dao/UserdtlBusinessDao.java | 10 - .../supwisdom/dlpay/api/dao/UserdtlDao.java | 32 -- .../dlpay/api/domain/TSubjectdtl.java | 2 +- .../supwisdom/dlpay/api/domain/TUserdtl.java | 258 ------------ .../dlpay/api/domain/TUserdtlBusiness.java | 64 --- .../com/supwisdom/dlpay/api/ThirdPayCall.kt | 6 +- .../supwisdom/dlpay/api/comsume_builder.kt | 373 ------------------ .../api/controller/consume_api_controller.kt | 208 +++++----- .../api/controller/notify_api_controller.kt | 19 +- .../service/impl/Consume_pay_service_impl.kt | 15 +- .../api/service/impl/pay_service_impl.kt | 282 +------------ .../service/impl/transaction_service_impl.kt | 3 + .../dlpay/api/service/pay_service.kt | 52 +-- 13 files changed, 134 insertions(+), 1190 deletions(-) delete mode 100644 src/main/java/com/supwisdom/dlpay/api/dao/UserdtlBusinessDao.java delete mode 100644 src/main/java/com/supwisdom/dlpay/api/dao/UserdtlDao.java delete mode 100644 src/main/java/com/supwisdom/dlpay/api/domain/TUserdtl.java delete mode 100644 src/main/java/com/supwisdom/dlpay/api/domain/TUserdtlBusiness.java delete mode 100644 src/main/kotlin/com/supwisdom/dlpay/api/comsume_builder.kt diff --git a/src/main/java/com/supwisdom/dlpay/api/dao/UserdtlBusinessDao.java b/src/main/java/com/supwisdom/dlpay/api/dao/UserdtlBusinessDao.java deleted file mode 100644 index 347e79ae..00000000 --- a/src/main/java/com/supwisdom/dlpay/api/dao/UserdtlBusinessDao.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.supwisdom.dlpay.api.dao; - -import com.supwisdom.dlpay.api.domain.TUserdtlBusiness; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface UserdtlBusinessDao extends JpaRepository { - TUserdtlBusiness getByRefno(String refno); -} diff --git a/src/main/java/com/supwisdom/dlpay/api/dao/UserdtlDao.java b/src/main/java/com/supwisdom/dlpay/api/dao/UserdtlDao.java deleted file mode 100644 index 007cff7d..00000000 --- a/src/main/java/com/supwisdom/dlpay/api/dao/UserdtlDao.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.supwisdom.dlpay.api.dao; - -import com.supwisdom.dlpay.api.domain.TUserdtl; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Lock; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.jpa.repository.QueryHints; -import org.springframework.stereotype.Repository; - -import javax.persistence.LockModeType; -import javax.persistence.QueryHint; - -@Repository -public interface UserdtlDao extends JpaRepository { - TUserdtl findByRefno(String refno); - - @Lock(LockModeType.PESSIMISTIC_WRITE) - @Query("select dtl from TUserdtl dtl where dtl.refno = ?1") - TUserdtl findByRefnoForUpdate(String refno); - - @Lock(LockModeType.PESSIMISTIC_WRITE) - @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="0")}) - @Query("select dtl from TUserdtl dtl where dtl.refno = ?1") - TUserdtl findByRefnoForUpdateNowait(String refno); - - @Lock(LockModeType.PESSIMISTIC_WRITE) - @QueryHints({@QueryHint(name = "javax.persistence.lock.timeout", value ="0")}) - @Query("select dtl from TUserdtl dtl where dtl.outtradeno = ?1 and dtl.shopaccno=?2 ") - TUserdtl findByBillnoForUpdateNowait(String billno,String shopaccno); - - TUserdtl findByOuttradenoAndShopaccno(String outtradeno,String shopaccno); -} diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TSubjectdtl.java b/src/main/java/com/supwisdom/dlpay/api/domain/TSubjectdtl.java index dc3fe04b..3fd3be25 100644 --- a/src/main/java/com/supwisdom/dlpay/api/domain/TSubjectdtl.java +++ b/src/main/java/com/supwisdom/dlpay/api/domain/TSubjectdtl.java @@ -3,7 +3,7 @@ package com.supwisdom.dlpay.api.domain; import javax.persistence.*; @Entity -@Table(name = "TB_SUBJECtDTL", +@Table(name = "TB_SUBJECTDTL", indexes = {@Index(name = "subjdtl_accdate", columnList = "accdate"), @Index(name = "subjdtl_subjno", columnList = "subjno")}) public class TSubjectdtl { diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TUserdtl.java b/src/main/java/com/supwisdom/dlpay/api/domain/TUserdtl.java deleted file mode 100644 index 694e7a9e..00000000 --- a/src/main/java/com/supwisdom/dlpay/api/domain/TUserdtl.java +++ /dev/null @@ -1,258 +0,0 @@ -package com.supwisdom.dlpay.api.domain; - -import javax.persistence.*; - -@Entity -@Table(name = "TB_USERDTL", - indexes = {@Index(name = "userdtl_transdate_idx", columnList = "transdate"), - @Index(name = "userdtl_accdate_idx", columnList = "accdate"), - @Index(name = "userdtl_status_idx", columnList = "status"), - @Index(name = "userdtl_reverse_idx", columnList = "REVERSE_FLAG"), - @Index(name = "userdtl_outtradeno_uk", unique = true, columnList = "outtradeno,shopaccno")}) -public class TUserdtl { - @Id - @Column(name = "REFNO", nullable = false, length = 32) - private String refno; //流水号 - - @Column(name = "ACCDATE", length = 8) - private String accdate; //记账日期 - - @Column(name = "USERID", length = 32) - private String userid; //用户ID,或账号 - - @Column(name = "TRANSDATE", length = 8) - private String transdate; - - @Column(name = "TRANSTIME", length = 6) - private String transtime; - - @Column(name = "STATUS", length = 20) - private String status; - - @Column(name = "BEFBAL", precision = 9, scale = 2) - private Double befbal; - - @Column(name = "AMOUNT", precision = 9, scale = 2) - private Double amount; //实际付款金额 - - @Column(name = "TOTAL_AMOUNT", precision = 9, scale = 2) - private Double totalAmount; //订单总金额 - - @Column(name = "AFTBAL", precision = 9, scale = 2) - private Double aftbal; - - @Column(name = "PAYTYPE", length = 20) - private String paytype; //支付方式 balance,wechat,alipay - - @Column(name = "PAYINFO", length = 200) - private String payinfo; //记录支付信息备用字段 - - @Column(name = "TRANSCODE", precision = 4) - private Integer transcode; - - @Column(name = "TRANSDESC", length = 240) - private String transdesc; //交易描述 - - @Column(name = "OUTTRADENO", length = 60) - private String outtradeno; //第三方流水号 - - @Column(name = "SHOPACCNO", length = 20) - private String shopaccno; - - @Column(name = "OPERID", precision = 9) - private Integer operid; //操作员ID - - @Column(name = "REVERSE_FLAG", nullable = false, precision = 1) - private String reverseFlag = "none"; //none, cancel, reversed - - @Column(name = "REVERSE_AMOUNT", precision = 9, scale = 2) - private Double reverseAmount = 0D; //撤销金额填写 - - @Column(name = "TRADEFLAG", nullable = false, precision = 1) - private Integer tradeflag; //1-充值;2-消费 - - @Column(name = "REMARK", length = 240) - private String remark; - - @Column(name = "CREATETIME", length = 14) - private String createtime; //创建时间 - - @Column(name = "ENDTIME", length = 14) - private String endtime; //支付结束时间 - - public String getRefno() { - return refno; - } - - public void setRefno(String refno) { - this.refno = refno; - } - - public String getAccdate() { - return accdate; - } - - public void setAccdate(String accdate) { - this.accdate = accdate; - } - - public String getUserid() { - return userid; - } - - public void setUserid(String userid) { - this.userid = userid; - } - - public String getTransdate() { - return transdate; - } - - public void setTransdate(String transdate) { - this.transdate = transdate; - } - - public String getTranstime() { - return transtime; - } - - public void setTranstime(String transtime) { - this.transtime = transtime; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public Double getBefbal() { - return befbal; - } - - public void setBefbal(Double befbal) { - this.befbal = befbal; - } - - public Double getAmount() { - return amount; - } - - public void setAmount(Double amount) { - this.amount = amount; - } - - public Double getAftbal() { - return aftbal; - } - - public void setAftbal(Double aftbal) { - this.aftbal = aftbal; - } - - public String getPaytype() { - return paytype; - } - - public void setPaytype(String paytype) { - this.paytype = paytype; - } - - public String getPayinfo() { - return payinfo; - } - - public void setPayinfo(String payinfo) { - this.payinfo = payinfo; - } - - public Integer getTranscode() { - return transcode; - } - - public void setTranscode(Integer transcode) { - this.transcode = transcode; - } - - public String getTransdesc() { - return transdesc; - } - - public void setTransdesc(String transdesc) { - this.transdesc = transdesc; - } - - public String getOuttradeno() { - return outtradeno; - } - - public void setOuttradeno(String outtradeno) { - this.outtradeno = outtradeno; - } - - public String getShopaccno() { - return shopaccno; - } - - public void setShopaccno(String shopaccno) { - this.shopaccno = shopaccno; - } - - public Integer getOperid() { - return operid; - } - - public void setOperid(Integer operid) { - this.operid = operid; - } - - public String getReverseFlag() { - return reverseFlag; - } - - public void setReverseFlag(String reverseFlag) { - this.reverseFlag = reverseFlag; - } - - public Double getReverseAmount() { - return reverseAmount; - } - - public void setReverseAmount(Double reverseAmount) { - this.reverseAmount = reverseAmount; - } - - public Integer getTradeflag() { - return tradeflag; - } - - public void setTradeflag(Integer tradeflag) { - this.tradeflag = tradeflag; - } - - public String getRemark() { - return remark; - } - - public void setRemark(String remark) { - this.remark = remark; - } - - public String getCreatetime() { - return createtime; - } - - public void setCreatetime(String createtime) { - this.createtime = createtime; - } - - public String getEndtime() { - return endtime; - } - - public void setEndtime(String endtime) { - this.endtime = endtime; - } -} diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TUserdtlBusiness.java b/src/main/java/com/supwisdom/dlpay/api/domain/TUserdtlBusiness.java deleted file mode 100644 index 42ed8ca1..00000000 --- a/src/main/java/com/supwisdom/dlpay/api/domain/TUserdtlBusiness.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.supwisdom.dlpay.api.domain; - -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; -import com.supwisdom.dlpay.framework.util.StringUtil; - -import javax.persistence.*; -import java.util.HashMap; -import java.util.Map; - -@Entity -@Table(name = "TB_USERDTL_BUSINESS") -public class TUserdtlBusiness { - @Id - @Column(name = "REFNO", nullable = false, length = 32) - private String refno; - - @Column(name = "JSON_CONTENT", length = 1000) - private String jsonContent; - - @Transient - private static final Gson gsonUtil = new Gson(); - - public TUserdtlBusiness() { - } - - public TUserdtlBusiness(String refno, String jsonContent) { - this.refno = refno; - this.jsonContent = jsonContent; - } - - public TUserdtlBusiness(String refno, Map map) { - this.refno = refno; - if (null == map || map.isEmpty()) { - this.jsonContent = ""; - } else { - this.jsonContent = gsonUtil.toJson(map); - } - } - - public String getRefno() { - return refno; - } - - public void setRefno(String refno) { - this.refno = refno; - } - - public String getJsonContent() { - return jsonContent; - } - - public void setJsonContent(String jsonContent) { - this.jsonContent = jsonContent; - } - - public Map getContentMap() { - Map map = new HashMap<>(0); - if (!StringUtil.isEmpty(this.jsonContent)) - map = gsonUtil.fromJson(this.jsonContent, new TypeToken>() { - }.getType()); - return map; - } -} diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt b/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt index 3a03934a..3b5bd5e2 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/api/ThirdPayCall.kt @@ -7,8 +7,8 @@ import com.supwisdom.dlpay.api.bean.BaseResp import com.supwisdom.dlpay.api.bean.SupStatusRevResp import com.supwisdom.dlpay.api.bean.SupYktResp import com.supwisdom.dlpay.api.bean.WechatReqResp +import com.supwisdom.dlpay.api.domain.TPersondtl import com.supwisdom.dlpay.api.domain.TShopdtl -import com.supwisdom.dlpay.api.domain.TUserdtl import com.supwisdom.dlpay.framework.util.* import com.supwisdom.dlpay.util.Code @@ -24,7 +24,7 @@ class CallBackResp { class CallService { companion object { - fun callYktPay(config: Map, paydtl: TUserdtl, time: String, stuempno: String, yktshopid: String, devphyid: String?): CallBackResp { + fun callYktPay(config: Map, paydtl: TPersondtl, time: String, stuempno: String, yktshopid: String, devphyid: String?): CallBackResp { val code = CallBackResp() val appid = config["appid"] if (appid.isNullOrEmpty()) { @@ -104,7 +104,7 @@ class CallService { return code } - fun callWechatPay(config: Map, paydtl: TUserdtl, time: String, wechattype: String, + fun callWechatPay(config: Map, paydtl: TPersondtl, time: String, wechattype: String, realip: String?, qrcode: String?, openid: String?): BaseResp { val code = BaseResp() val appid = config["appid"] diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/comsume_builder.kt b/src/main/kotlin/com/supwisdom/dlpay/api/comsume_builder.kt deleted file mode 100644 index 03041415..00000000 --- a/src/main/kotlin/com/supwisdom/dlpay/api/comsume_builder.kt +++ /dev/null @@ -1,373 +0,0 @@ -package com.supwisdom.dlpay.api - -import com.supwisdom.dlpay.api.domain.TAccount -import com.supwisdom.dlpay.api.domain.TPerson -import com.supwisdom.dlpay.api.domain.TUserdtl -import com.supwisdom.dlpay.api.service.AccountUtilServcie -import com.supwisdom.dlpay.api.service.PersonBalancePayService -import com.supwisdom.dlpay.exception.TransactionCheckException -import com.supwisdom.dlpay.framework.domain.TFeetypeConfig -import com.supwisdom.dlpay.framework.domain.TShopacc -import com.supwisdom.dlpay.framework.domain.TSubject -import com.supwisdom.dlpay.framework.util.* - -class AccountHolder private constructor(val accountId: String, val idType: Int) { - companion object { - const val IDTYPE_PERSON = 1 - const val IDTYPE_SHOP = 2 - const val IDTYPE_SUBJECT = 3 - const val IDTYPE_FEETYPE = 4 - - fun person(userid: String): AccountHolder { - return AccountHolder(userid, IDTYPE_PERSON) - } - - fun shop(shopid: String): AccountHolder { - return AccountHolder(shopid, IDTYPE_SHOP) - } - - fun subject(subjNo: String): AccountHolder { - return AccountHolder(subjNo, IDTYPE_SUBJECT) - } - - fun feetype(feetype: String, paytype: String): AccountHolder { - return AccountHolder("$feetype@$paytype", IDTYPE_FEETYPE) - } - } - - internal lateinit var builder: PersonTransBuilder - - internal val childrenHolder = mutableListOf>() - - - fun with(holder: AccountHolder): AccountHolder { - holder.builder = this.builder - childrenHolder.add(holder) - return this - } - - @Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_ANY") - fun get(): T { - return when (idType) { - IDTYPE_PERSON -> builder.accountUtil.readAccountForUpdateNowait(accountId) - IDTYPE_SHOP -> builder.accountUtil.readShopAcc(accountId.toInt()) - IDTYPE_SUBJECT -> builder.accountUtil.readSubject(accountId) - IDTYPE_FEETYPE -> builder.accountUtil.readFeetype(accountId.split("@")[0], accountId.split("@")[1]) - else -> throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "账户类型未知type<$idType>") - } as T - } - - @Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_ANY") - fun withLock(): T { - return when (idType) { - IDTYPE_PERSON -> builder.accountUtil.readAccountForUpdateNowait(accountId) - IDTYPE_SHOP -> builder.accountUtil.readShopAcc(accountId.toInt()) - IDTYPE_SUBJECT -> builder.accountUtil.readSubject(accountId) - IDTYPE_FEETYPE -> builder.accountUtil.readFeetype(accountId.split("@")[0], accountId.split("@")[1]) - else -> throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "账户类型未知type<$idType>") - } as T - } -} - -class PersonTransBuilder private constructor(accUitl: AccountUtilServcie) { - companion object { - fun newBuilder(accUitl: AccountUtilServcie) = PersonTransBuilder(accUitl) - } - - inner class TransDetail(val debitAccNo: String, val debitSubjNo: String, - val creditAccNo: String, val creditSubjNo: String, - val amount: Double, val summary: String, - val rowno: Int) - - /////////////////////////////////////////////////////////////////////////////// - // 以下为输入参数,调用接口时指定的参数值 - lateinit var person: TPerson - lateinit var tradetype: Tradetype - lateinit var refno: String - lateinit var status: String - lateinit var shopaccno: String - val extendMap = mutableMapOf() //存调第三方需要的参数信息 - val resultMap = mutableMapOf() //存调第三方结果数据 - - var transcode = 0 - - var transDate = "" - var transTime = "" - /** - * 是否允许透支 - */ - var overdraft = false - var description = "" - - /** - * 支付方式 - * */ - var paytype = "" //枚举? - var payinfo = "" - - /** - * 外部流水号 - * */ - var outtradeno = "" //发起支付系统的流水号(对接系统根据此流水号查询本地流水对账) - - var tryLockAccount = false - - //////////////////////////////////////////////////////////////////////////////////// - // 以下为内部参数,不需要调用者处理 - val details = mutableListOf() - var amount: Double = 0.0 - var accountUtil = accUitl - - ///////////////////////////////////////////// - - fun setOwner(per: TPerson): PersonTransBuilder { - this.person = per - return this - } - - fun enableOverdraft(b: Boolean = false): PersonTransBuilder { - this.overdraft = b - return this - } - - fun setTransDatetime(date: String, time: String): PersonTransBuilder { - this.transDate = date - this.transTime = time - return this - } - - fun setTransinfo(transcode: Int, description: String): PersonTransBuilder { - this.transcode = transcode - this.description = description - return this - } - - fun selectPaytype(paytype: String, payinfo: String): PersonTransBuilder { - this.paytype = paytype - this.payinfo = payinfo - return this - } - - fun setOuttradeno(outtradeno: String): PersonTransBuilder { - this.outtradeno = outtradeno - return this - } - - fun chooseTradetype(tradetype: Tradetype): PersonTransBuilder { - this.tradetype = tradetype - return this - } - - fun tryLock(lock: Boolean): PersonTransBuilder { - this.tryLockAccount = lock - return this - } - - fun setRefno(refno: String): PersonTransBuilder { - this.refno = refno - return this - } - - fun addExtendParam(key: String, value: String): PersonTransBuilder { - this.extendMap.plus(mapOf(key to value)) - return this - } - - fun addExtendParam(param: Map): PersonTransBuilder { - this.extendMap.plus(param) - return this - } - - fun addResult(key: String, value: String): PersonTransBuilder { - this.resultMap.plus(mapOf(key to value)) - return this - } - - fun addResult(param: Map): PersonTransBuilder { - this.resultMap.plus(param) - return this - } - - private fun prepareData() { - if (transcode == 0) { - throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "未指定交易码") - } - - // fixme : 是否要检查 recharge , consume 之外的类型 - when (this.tradetype) { - //充值必须指明用户和支付方式 - Tradetype.RECHARGE -> { - if (StringUtil.isEmpty(this.paytype)) - throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "未指定充值方式") - } - - //消费 - Tradetype.CONSUME -> { - if (StringUtil.isEmpty(this.paytype)) - this.paytype = TradeDict.PAYTYPE_BALANCE //默认余额支付 - } - } - - if (this.details.size < 1) { - throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "未指定交易明细") - } - - amount = this.details.sumByDouble { detail -> - detail.amount - } - - if (!StringUtil.isEmpty(this.transDate) && - !DateUtil.checkDatetimeValid(this.transDate, "yyyyMMdd")) { - throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "交易日期格式错误[yyyyMMdd]") - } - if (!StringUtil.isEmpty(this.transTime) && - !DateUtil.checkDatetimeValid(this.transTime, "HHmmss")) { - throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "交易时间格式错误[HHmmss]") - } - - if (StringUtil.isEmpty(this.outtradeno)) { - throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "未传递外部流水号") - } - - - } - - private fun preCheckAccount() { - when (person.status) { - TradeDict.STATUS_CLOSED -> - throw TransactionCheckException(TradeErrorCode.PERSON_STATUS_ERROR, "用户已注销") - TradeDict.STATUS_LOCKED -> - throw TransactionCheckException(TradeErrorCode.PERSON_STATUS_ERROR, "用户已冻结锁定") - } - } - - @Suppress("UNCHECKED_CAST", "IMPLICIT_CAST_TO_ANY") - fun getAccountAndSubjNo(holder: AccountHolder): Pair { - return if (this.tryLockAccount) { - when (holder.idType) { - AccountHolder.IDTYPE_PERSON -> holder.withLock().let { - it.accno to it.subjno - } - AccountHolder.IDTYPE_SHOP -> holder.withLock().let { - if (this.shopaccno.isEmpty()) { - this.shopaccno = it.shopaccno - } - it.shopaccno to it.subjno - } - AccountHolder.IDTYPE_SUBJECT -> holder.withLock().let { - it.subjno to it.subjno - } - else -> throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "不支持的账户类型") - } - } else { - when (holder.idType) { - AccountHolder.IDTYPE_PERSON -> holder.get().let { - it.accno to it.subjno - } - AccountHolder.IDTYPE_SHOP -> holder.get().let { - if (this.shopaccno.isEmpty()) { - this.shopaccno = it.shopaccno - } - it.shopaccno to it.subjno - } - AccountHolder.IDTYPE_SUBJECT -> holder.get().let { - it.subjno to it.subjno - } - else -> throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "不支持的账户类型") - } - } - } - - fun addDetail(debit: AccountHolder, credit: AccountHolder, - amount: Double, summary: String): PersonTransBuilder { - debit.builder = this - credit.builder = this - - var debitAccNo: String - var debitSubjNo: String - getAccountAndSubjNo(debit).apply { - debitAccNo = first - debitSubjNo = second - } - var creditAccNo: String - var creditSubjNo: String - getAccountAndSubjNo(credit).apply { - creditAccNo = first - creditSubjNo = second - } - this.details.add(TransDetail(debitAccNo, debitSubjNo, creditAccNo, creditSubjNo, - amount, summary, this.details.size + 1)) - return this - } - - fun addDetail(accountHolder: AccountHolder, - amount: Double): PersonTransBuilder { - accountHolder.builder = this - val transtype = accountHolder.get() - - var debitAccNo = "" - var debitSubjNo = "" - - var creditAccNo = "" - var creditSubjNo = "" - - accountHolder.childrenHolder.map { - getAccountAndSubjNo(it) - }.forEach { - if (it.second == transtype.drsubjno) { - debitAccNo = it.first - debitSubjNo = it.second - } else if (it.second == transtype.crsubjno) { - creditAccNo = it.first - creditSubjNo = it.second - } - } - - if (debitAccNo.isEmpty()) { - throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, - "交易配置<${transtype.feetype}@${transtype.paytype}> 借方账号配置错误") - } - if (creditAccNo.isEmpty()) { - throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, - "交易配置<${transtype.feetype}@${transtype.paytype}> 贷方账号配置错误") - } - this.details.add(TransDetail(debitAccNo, debitSubjNo, creditAccNo, creditSubjNo, - amount, transtype.summary, this.details.size + 1)) - return this - } - - /** - * 一步交易完成 - */ - fun done(service: PersonBalancePayService): TUserdtl { - prepareData() - preCheckAccount() - return service.process(this) - } - - fun init(service: PersonBalancePayService): TUserdtl { - prepareData() - preCheckAccount() - return service.init(this) - } - - fun wip(service: PersonBalancePayService): TUserdtl { - if (this.refno.isEmpty()) - throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "交易参考号未指定") - return service.wip(this) - } - - fun finish(service: PersonBalancePayService, status: String): TUserdtl { - if (this.refno.isEmpty()) - throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "交易参考号未指定") - this.status = status - return service.finish(this) - } - - fun success(service: PersonBalancePayService): TUserdtl { - if (this.refno.isEmpty()) - throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR, "交易参考号未指定") - this.status = TradeDict.DTL_STATUS_SUCCESS - return service.finish(this) - } -} \ 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 bfa6eac7..873aa8f8 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 @@ -1,26 +1,29 @@ package com.supwisdom.dlpay.api.controller -import com.supwisdom.dlpay.api.* +import com.supwisdom.dlpay.api.AccountProxy +import com.supwisdom.dlpay.api.CallService +import com.supwisdom.dlpay.api.TransactionBuilder import com.supwisdom.dlpay.api.bean.* import com.supwisdom.dlpay.api.domain.TAccount -import com.supwisdom.dlpay.api.service.* +import com.supwisdom.dlpay.api.service.AccountUtilServcie +import com.supwisdom.dlpay.api.service.ConsumePayService +import com.supwisdom.dlpay.api.service.TransactionService +import com.supwisdom.dlpay.api.service.UserService import com.supwisdom.dlpay.exception.RequestParamCheckException import com.supwisdom.dlpay.exception.TransactionCheckException import com.supwisdom.dlpay.exception.TransactionException -import com.supwisdom.dlpay.exception.TransactionProcessException import com.supwisdom.dlpay.framework.ResponseBodyBuilder import com.supwisdom.dlpay.framework.domain.TShopacc import com.supwisdom.dlpay.framework.service.CommonService import com.supwisdom.dlpay.framework.service.SystemUtilService import com.supwisdom.dlpay.framework.util.* -import com.supwisdom.dlpay.util.ConstantUtil -import com.supwisdom.dlpay.util.PaytypeUtil -import org.apache.catalina.authenticator.SpnegoAuthenticator import org.springframework.beans.factory.annotation.Autowired import org.springframework.http.ResponseEntity import org.springframework.security.core.Authentication -import org.springframework.security.core.context.SecurityContextHolder -import org.springframework.web.bind.annotation.* +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 import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse @@ -30,10 +33,6 @@ class ConsumeController { @Autowired lateinit var accountUtilServcie: AccountUtilServcie @Autowired - lateinit var personBalancePayService: PersonBalancePayService - @Autowired - lateinit var paytypeService: PaytypeService - @Autowired lateinit var userService: UserService @Autowired lateinit var systemUtilService: SystemUtilService @@ -48,31 +47,35 @@ class ConsumeController { /** * 流水结果查询统一接口 * */ - fun queryDtlResult(@RequestBody param: QueryDtlResultParam, request: HttpServletRequest, response: HttpServletResponse): ResponseEntity { + fun queryDtlResult(@RequestBody param: QueryDtlResultParam, + request: HttpServletRequest, response: HttpServletResponse): ResponseEntity { try { if (param.checkParam() && param.checkSign(commonService.getAppidSecretByRequest(request))) { return ResponseEntity.ok(ResponseBodyBuilder.create() .fail(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误")) } - val dtl = if (StringUtil.isEmpty(param.refno)) { - personBalancePayService.getUserdtlForUpdateNowait(param.refno!!) - } else { - personBalancePayService.getUserdtlByBillnoForUpdateNowait(param.billno!!, param.shopaccno!!) - } - val person = dtl.userid?.let { userService.findPersonByUserid(dtl.userid) } - return ResponseEntity.ok(ResponseBodyBuilder.create() - .data("refno", dtl.refno) - .data("amount", dtl.amount) - .data("paytype", dtl.paytype) - .data("payinfo", dtl.payinfo) - .also { - if (null != person) { - it.data("name", person.name) - } - } - .success("查询成功")) - +// val dtl = if (StringUtil.isEmpty(param.refno)) { +// personBalancePayService.getUserdtlForUpdateNowait(param.refno!!) +// } else { +// personBalancePayService.getUserdtlByBillnoForUpdateNowait(param.billno!!, param.shopaccno!!) +// } +// val dtl = if( param.refno.isNullOrEmpty()) { +// transactionService. +// } +// val person = dtl.userid?.let { userService.findPersonByUserid(dtl.userid) } +// return ResponseEntity.ok(ResponseBodyBuilder.create() +// .data("refno", dtl.refno) +// .data("amount", dtl.amount) +// .data("paytype", dtl.paytype) +// .data("payinfo", dtl.payinfo) +// .also { +// if (null != person) { +// it.data("name", person.name) +// } +// } +// .success("查询成功")) + TODO("未实现功能") } catch (ex: RequestParamCheckException) { return ResponseEntity.ok(ResponseBodyBuilder.create() .requestException(ex, "请求参数错误")) @@ -83,7 +86,8 @@ class ConsumeController { } - private fun consumeMealer(param: CitizenCardPayinitParam, builder: TransactionBuilder, + private fun consumeMealer(@Suppress("UNUSED_PARAMETER") param: CitizenCardPayinitParam, + builder: TransactionBuilder, feetype: ConsumeFeetype, person: TAccount, shop: TShopacc) { val feetypeConfig = accountUtilServcie.readFeetype(TradeDict.FEETYPE_CONSUME_MEALER, TradeDict.PAYTYPE_BALANCE) @@ -105,7 +109,8 @@ class ConsumeController { } - private fun consumeDiscount(param: CitizenCardPayinitParam, builder: TransactionBuilder, + private fun consumeDiscount(@Suppress("UNUSED_PARAMETER") param: CitizenCardPayinitParam, + builder: TransactionBuilder, feetype: ConsumeFeetype, person: TAccount, shop: TShopacc) { val feetypeConfig = accountUtilServcie.readFeetype(TradeDict.FEETYPE_CONSUME_MEALER, TradeDict.PAYTYPE_BALANCE) @@ -139,7 +144,7 @@ class ConsumeController { val person = userService.findPersonByIdentityCheckStatus(param.cardNo) if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_BALANCE)) { val account = accountUtilServcie.readAccount(person.userid) - val shopacc = accountUtilServcie.readShopbyAccno(param.shopaccno) + val shopacc = accountUtilServcie.readShopbyShopaccno(param.shopaccno) val builder = TransactionBuilder().apply { transDate = param.transdate @@ -209,7 +214,7 @@ class ConsumeController { if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_CITIZEN_CARD)) { val account = accountUtilServcie.readAccount(person.userid) - val shopacc = accountUtilServcie.readShopbyAccno(param.shopaccno) + val shopacc = accountUtilServcie.readShopbyShopaccno(param.shopaccno) val subject = accountUtilServcie.readSubject(Subject.SUBJNO_PAY_CITIZEN_CARD) val transaction = TransactionBuilder().apply { transCode = TradeCode.TRANSCODE_CITIZENCARD_PAY @@ -313,45 +318,45 @@ class ConsumeController { @PostMapping("/ykt/payinit") fun yktPayInit(@RequestBody param: YktCardPayinitParam, request: HttpServletRequest, response: HttpServletResponse): ResponseEntity { try { - if (param.checkParam() && param.checkSign(commonService.getAppidSecretByRequest(request))) { - return ResponseEntity.ok(ResponseBodyBuilder.create() - .fail(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误")) - } - - val person = param.uid?.let { userService.findByThirdUniqueIdenty(it) } //没注册,可能匿名? - if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_YKT_CARD, person == null)) { - val dtl = PersonTransBuilder.newBuilder(accountUtilServcie) - .chooseTradetype(Tradetype.CONSUME) //消费 - .also { - if (null != person) it.setOwner(person) - } - .setTransinfo(TradeCode.TRANSCODE_YKTCARD_PAY, "一卡通支付") - .setTransDatetime(param.transdate, param.transtime) //交易时间 - .selectPaytype(TradeDict.PAYTYPE_YKT_CARD, param.stuempno) - .addDetail(AccountHolder.subject(Subject.SUBJNO_PAY_YKT), - AccountHolder.shop(param.shopaccno), - param.amount / 100.0, "一卡通支付") - .also { builder -> - param.feelist?.forEach { - //fixme: 科目 -> 商户 与个人无关 - builder.addDetail(AccountHolder.feetype(it.feetype, TradeDict.PAYTYPE_YKT_CARD) - .with(AccountHolder.shop(param.shopaccno)) - .with(AccountHolder.subject(Subject.SUBJNO_PAY_YKT)) - , it.amount / 100.0) - } - } - .addExtendParam("stuempno", param.stuempno) - .addExtendParam("yktshopid", param.yktshopid ?: "") - .addExtendParam("devphyid", param.devphyid ?: "") - //.addExtendParam(param.extendmap) //fixme: 保存调一卡通附加参数 (是否直接传附加参数map) - .init(personBalancePayService) - - return ResponseEntity.ok(ResponseBodyBuilder.create() - .data("refno", dtl.refno) - .data("amount", dtl.amount) - .success("交易初始化成功")) - - } +// if (param.checkParam() && param.checkSign(commonService.getAppidSecretByRequest(request))) { +// return ResponseEntity.ok(ResponseBodyBuilder.create() +// .fail(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误")) +// } +// +// val person = param.uid?.let { userService.findByThirdUniqueIdenty(it) } //没注册,可能匿名? +// if (consumePayService.checkShopPaytype(param.shopaccno, TradeDict.PAYTYPE_YKT_CARD, person == null)) { +// val dtl = PersonTransBuilder.newBuilder(accountUtilServcie) +// .chooseTradetype(Tradetype.CONSUME) //消费 +// .also { +// if (null != person) it.setOwner(person) +// } +// .setTransinfo(TradeCode.TRANSCODE_YKTCARD_PAY, "一卡通支付") +// .setTransDatetime(param.transdate, param.transtime) //交易时间 +// .selectPaytype(TradeDict.PAYTYPE_YKT_CARD, param.stuempno) +// .addDetail(AccountHolder.subject(Subject.SUBJNO_PAY_YKT), +// AccountHolder.shop(param.shopaccno), +// param.amount / 100.0, "一卡通支付") +// .also { builder -> +// param.feelist?.forEach { +// //fixme: 科目 -> 商户 与个人无关 +// builder.addDetail(AccountHolder.feetype(it.feetype, TradeDict.PAYTYPE_YKT_CARD) +// .with(AccountHolder.shop(param.shopaccno)) +// .with(AccountHolder.subject(Subject.SUBJNO_PAY_YKT)) +// , it.amount / 100.0) +// } +// } +// .addExtendParam("stuempno", param.stuempno) +// .addExtendParam("yktshopid", param.yktshopid ?: "") +// .addExtendParam("devphyid", param.devphyid ?: "") +// //.addExtendParam(param.extendmap) //fixme: 保存调一卡通附加参数 (是否直接传附加参数map) +// .init(personBalancePayService) +// +// return ResponseEntity.ok(ResponseBodyBuilder.create() +// .data("refno", dtl.refno) +// .data("amount", dtl.amount) +// .success("交易初始化成功")) +// +// } return ResponseEntity.ok(ResponseBodyBuilder.create() .fail(TradeErrorCode.BUSINESS_PAYTYPE_NOSUPPORT, "不支持支付方式<一卡通支付>")) @@ -377,33 +382,34 @@ class ConsumeController { return ResponseEntity.ok(ResponseBodyBuilder.create() .fail(TradeErrorCode.REQUEST_SIGN_ERROR, "参数签名错误")) } - - var dtl = PersonTransBuilder.newBuilder(accountUtilServcie) - .setRefno(param.refno) - .wip(personBalancePayService) - val extendMap = consumePayService.getUserdtlExtendParamMap(dtl.refno) - val code = CallService.callYktPay(consumePayService.getPaytypeConfig(TradeDict.PAYTYPE_YKT_CARD, dtl.shopaccno, dtl.userid == null), - dtl, DateUtil.getNow(), extendMap["stuempno"]!!, extendMap["yktshopid"]!!, extendMap["devphyid"]) - if (code.retcode == "0") { - dtl = PersonTransBuilder.newBuilder(accountUtilServcie) - .setRefno(param.refno) - .addResult(code.data) - .success(personBalancePayService) //流水置成功 - - return ResponseEntity.ok(ResponseBodyBuilder.create() - .data("refno", dtl.refno) - .data("billno", dtl.outtradeno) - .success()) - } else { - PersonTransBuilder.newBuilder(accountUtilServcie) - .setRefno(param.refno) - .addResult("errmsg", code.retmsg!!) - .finish(personBalancePayService, TradeDict.DTL_STATUS_FAIL) //流水置成功 - - return ResponseEntity.ok(ResponseBodyBuilder.create() - .fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "交易扣费失败-${code.retmsg}")) - } - +// +// var dtl = PersonTransBuilder.newBuilder(accountUtilServcie) +// .setRefno(param.refno) +// .wip(personBalancePayService) +// val extendMap = consumePayService.getUserdtlExtendParamMap(dtl.refno) +// val code = CallService.callYktPay(consumePayService.getPaytypeConfig(TradeDict.PAYTYPE_YKT_CARD, dtl.shopaccno, dtl.userid == null), +// dtl, DateUtil.getNow(), extendMap["stuempno"]!!, extendMap["yktshopid"]!!, extendMap["devphyid"]) +// if (code.retcode == "0") { +// dtl = PersonTransBuilder.newBuilder(accountUtilServcie) +// .setRefno(param.refno) +// .addResult(code.data) +// .success(personBalancePayService) //流水置成功 +// +// return ResponseEntity.ok(ResponseBodyBuilder.create() +// .data("refno", dtl.refno) +// .data("billno", dtl.outtradeno) +// .success()) +// } else { +// PersonTransBuilder.newBuilder(accountUtilServcie) +// .setRefno(param.refno) +// .addResult("errmsg", code.retmsg!!) +// .finish(personBalancePayService, TradeDict.DTL_STATUS_FAIL) //流水置成功 +// +// return ResponseEntity.ok(ResponseBodyBuilder.create() +// .fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "交易扣费失败-${code.retmsg}")) +// } + 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/controller/notify_api_controller.kt b/src/main/kotlin/com/supwisdom/dlpay/api/controller/notify_api_controller.kt index f099608c..23376822 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/api/controller/notify_api_controller.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/api/controller/notify_api_controller.kt @@ -1,13 +1,10 @@ package com.supwisdom.dlpay.api.controller -import com.supwisdom.dlpay.api.PersonTransBuilder import com.supwisdom.dlpay.api.service.AccountUtilServcie import com.supwisdom.dlpay.api.service.PaytypeService -import com.supwisdom.dlpay.api.service.PersonBalancePayService +import com.supwisdom.dlpay.api.service.TransactionService import com.supwisdom.dlpay.framework.util.MD5 import com.supwisdom.dlpay.framework.util.StringUtil -import com.supwisdom.dlpay.framework.util.TradeDict -import com.supwisdom.dlpay.framework.util.XmlUtils import com.supwisdom.dlpay.util.PaytypeUtil import org.dom4j.io.SAXReader import org.slf4j.LoggerFactory @@ -17,7 +14,7 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.ResponseBody import org.springframework.web.bind.annotation.RestController -import java.util.HashMap +import java.util.* import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse @@ -29,12 +26,13 @@ import javax.servlet.http.HttpServletResponse class NotifyController { private val logger = LoggerFactory.getLogger(NotifyController::class.java) @Autowired - lateinit var personBalancePayService: PersonBalancePayService - @Autowired lateinit var paytypeService: PaytypeService @Autowired lateinit var accountUtilServcie: AccountUtilServcie + @Autowired + lateinit var transactionService: TransactionService + @RequestMapping(value = ["/wechat"]) @ResponseBody fun index(@PathVariable schema: String, request: HttpServletRequest, @@ -82,16 +80,13 @@ class NotifyController { val return_code = map["return_code"] val result_code = map["result_code"] val out_trade_no = map["out_trade_no"] - if (StringUtils.isEmpty(out_trade_no)) { + if (out_trade_no == null || StringUtils.isEmpty(out_trade_no)) { return "" } if (!StringUtils.isEmpty(return_code) && "SUCCESS" == return_code && !StringUtils.isEmpty(result_code) && "SUCCESS" == result_code) { //map.get("transaction_id") 第三方流水号 - PersonTransBuilder.newBuilder(accountUtilServcie) - .setRefno(out_trade_no!!) - .addResult(map) - .success(personBalancePayService) + transactionService.success(out_trade_no) } return "" } catch (e: Exception) { 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 index 3c40253f..8d891d85 100644 --- 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 @@ -3,8 +3,6 @@ package com.supwisdom.dlpay.api.service.impl import com.supwisdom.dlpay.api.dao.PaytypeDao import com.supwisdom.dlpay.api.dao.ShopPaytypeConfigDao import com.supwisdom.dlpay.api.dao.ShopPaytypeDao -import com.supwisdom.dlpay.api.dao.UserdtlBusinessDao -import com.supwisdom.dlpay.api.domain.TUserdtlBusiness import com.supwisdom.dlpay.api.service.ConsumePayService import com.supwisdom.dlpay.exception.TransactionProcessException import com.supwisdom.dlpay.framework.util.TradeErrorCode @@ -13,17 +11,15 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service @Service -class ConsumePayServiceImpl: ConsumePayService{ +class ConsumePayServiceImpl : ConsumePayService { @Autowired lateinit var paytypeDao: PaytypeDao @Autowired lateinit var shopPaytypeDao: ShopPaytypeDao @Autowired lateinit var shopPaytypeConfigDao: ShopPaytypeConfigDao - @Autowired - lateinit var userdtlBusinessDao: UserdtlBusinessDao - override fun checkShopPaytype(shopaccno: String, paytype: String, anonymousflag: Boolean?): Boolean{ + override fun checkShopPaytype(shopaccno: String, paytype: String, anonymousflag: Boolean?): Boolean { paytypeDao.getByPaytype(paytype).let { if (null == it) { throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "系统不支持支付方式[$paytype]") @@ -88,12 +84,11 @@ class ConsumePayServiceImpl: ConsumePayService{ it.forEach { result.plus(mapOf(it.configid to it.configValue)) } return result } - } ?: throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "该商户[$shopaccno]的支付方式[$paytype]未配置参数") + } + ?: throw TransactionProcessException(TradeErrorCode.INPUT_DATA_ERROR, "该商户[$shopaccno]的支付方式[$paytype]未配置参数") } override fun getUserdtlExtendParamMap(refno: String): Map { - return userdtlBusinessDao.getByRefno(refno)?.let { - it.contentMap - } ?: mutableMapOf() + TODO("未实现方法") } } \ No newline at end of file diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/pay_service_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/pay_service_impl.kt index 6ca00038..e54f063f 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/pay_service_impl.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/pay_service_impl.kt @@ -1,30 +1,21 @@ package com.supwisdom.dlpay.api.service.impl -import com.supwisdom.dlpay.api.PersonTransBuilder import com.supwisdom.dlpay.api.dao.AccountDao -import com.supwisdom.dlpay.api.dao.DebitCreditDtlDao -import com.supwisdom.dlpay.api.dao.UserdtlBusinessDao -import com.supwisdom.dlpay.api.dao.UserdtlDao import com.supwisdom.dlpay.api.domain.TAccount -import com.supwisdom.dlpay.api.domain.TDebitCreditDtl -import com.supwisdom.dlpay.api.domain.TUserdtl -import com.supwisdom.dlpay.api.domain.TUserdtlBusiness import com.supwisdom.dlpay.api.service.AccountUtilServcie -import com.supwisdom.dlpay.api.service.PersonBalancePayService import com.supwisdom.dlpay.exception.TransactionException import com.supwisdom.dlpay.exception.TransactionProcessException -import com.supwisdom.dlpay.framework.dao.* +import com.supwisdom.dlpay.framework.dao.FeetypeConfigDao +import com.supwisdom.dlpay.framework.dao.ShopaccDao +import com.supwisdom.dlpay.framework.dao.SubjectDao import com.supwisdom.dlpay.framework.domain.TFeetypeConfig import com.supwisdom.dlpay.framework.domain.TShopacc import com.supwisdom.dlpay.framework.domain.TSubject -import com.supwisdom.dlpay.framework.service.SystemUtilService -import com.supwisdom.dlpay.framework.util.* +import com.supwisdom.dlpay.framework.util.TradeErrorCode import org.hibernate.exception.LockTimeoutException import org.springframework.beans.factory.annotation.Autowired import org.springframework.dao.CannotAcquireLockException import org.springframework.stereotype.Service -import javax.persistence.EntityManager -import javax.persistence.PersistenceContext @Service @@ -64,9 +55,9 @@ class AccountUtilServcieImpl : AccountUtilServcie { ?: throw TransactionProcessException(TradeErrorCode.SHOP_NOT_EXISTS, "商户<$shopId>不存在") } - override fun readShopbyAccno(shopacc: String): TShopacc { - return shopaccDao.findByShopaccno(shopacc) - ?: throw TransactionProcessException(TradeErrorCode.SHOP_NOT_EXISTS, "商户<$shopacc>不存在") + override fun readShopbyShopaccno(shopaccno: String): TShopacc { + return shopaccDao.findByShopaccno(shopaccno) + ?: throw TransactionProcessException(TradeErrorCode.SHOP_NOT_EXISTS, "商户<$shopaccno>不存在") } override fun readSubject(subjno: String): TSubject { @@ -79,262 +70,3 @@ class AccountUtilServcieImpl : AccountUtilServcie { ?: throw TransactionProcessException(TradeErrorCode.FEETYPE_NOT_EXISTS, "在支付方式<$paytype>下不存在费用类别<$feetype>") } } - -@Service -class PersonBalancePayServiceImpl : PersonBalancePayService { - @Autowired - lateinit var userdtlDao: UserdtlDao - @Autowired - lateinit var debitCreditDtlDao: DebitCreditDtlDao - - @Autowired - lateinit var accountDao: AccountDao - - @Autowired - lateinit var userdtlBusinessDao: UserdtlBusinessDao - - @PersistenceContext - lateinit var em: EntityManager - - @Autowired - lateinit var systemUtilService: SystemUtilService - - - private fun getlockAccount(accno: String): TAccount { - return accountDao.getByAccnoForUpdate(accno) - ?: throw throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "账号<$accno>不存在") - } - - private fun getlockAccountNowait(accno: String): TAccount { - return try { - accountDao.getByAccnoForUpdateNowait(accno) - ?: throw throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "账号<$accno>不存在") - } catch (ex: Exception) { - when (ex) { - is CannotAcquireLockException, is LockTimeoutException -> throw TransactionException(TradeErrorCode.ACCOUNT_TRADE_BUSY, "账号<$accno>交易繁忙,请稍后再试") - else -> throw ex - } - } - } - - private fun getLockUserdtlNowait(refno: String): TUserdtl { - return try { - userdtlDao.findByRefnoForUpdateNowait(refno) - ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, "交易参考号<$refno>不存在") - } catch (ex: Exception) { - when (ex) { - is CannotAcquireLockException, is LockTimeoutException -> throw TransactionException(TradeErrorCode.LOCK_READ_TIMEOUT, "交易参考号<$refno>流水被锁定,请稍后再试") - else -> throw ex - } - } - } - - private fun getLockUserdtl(refno: String): TUserdtl { - return userdtlDao.findByRefnoForUpdate(refno) - ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, "交易参考号<$refno>不存在") - } - - private fun doDealAccount(accno: String, amount: Double, overdraft: Boolean): TAccount { - val account = getlockAccount(accno) - if (account.tacCheck()) - throw TransactionProcessException(TradeErrorCode.ACCOUNT_TAC_ERROR, "账户<$accno>tac校验异常") - - account.addAmount(amount) //入账 - if (account.checkOverflow()) - throw TransactionProcessException(TradeErrorCode.OVERFLOW_BALANCE_ERROR, "账户<$accno>已超最大余额限制") - - if (!overdraft && account.checkOverdraft()) - throw TransactionProcessException(TradeErrorCode.SHORT_BALANCE_ERROR, "账户<$accno>余额不足") - - return accountDao.save(account) //入库更新 - } - - private fun doDealShopacc(shopaccno: String, amount: Double) { - return - } - - override fun process(builder: PersonTransBuilder): TUserdtl { - return finish(init(builder), TradeDict.DTL_STATUS_SUCCESS, builder.resultMap) - } - - override fun init(builder: PersonTransBuilder): TUserdtl { - //判断第三方流水号重复 标准:shopaccno + outtradeno 唯一? - var userdtl = userdtlDao.findByOuttradenoAndShopaccno(builder.outtradeno, builder.shopaccno) //加锁? - if (null != userdtl) { - if (TradeDict.DTL_STATUS_INIT != userdtl.status) { - throw TransactionProcessException(TradeErrorCode.OUTTRADENO_ALREADY_EXISTS, "外部流水号重复") //非初始化状态,直接报错 - } - //fixme: 判断是同一笔交易重发(标准??) 是->已初始化直接返回;否 -> 报错:外部流水号重复 - if (builder.amount == userdtl.amount && builder.paytype == userdtl.paytype && builder.transDate == userdtl.transdate && builder.transTime == userdtl.transtime) { - return userdtl // 交易日期,时间重发时是否会变?? - } else { - throw TransactionProcessException(TradeErrorCode.OUTTRADENO_ALREADY_EXISTS, "外部流水号重复") - } - } - - userdtl = TUserdtl() // 新建流水 - userdtl.refno = systemUtilService.refno - userdtl.accdate = systemUtilService.accdate - userdtl.userid = builder.person.userid - if (StringUtil.isEmpty(builder.transDate)) { - userdtl.transdate = systemUtilService.sysdatetime.hostdate - } else { - userdtl.transdate = builder.transDate - } - if (StringUtil.isEmpty(builder.transTime)) { - userdtl.transdate = systemUtilService.sysdatetime.hosttime - } else { - userdtl.transtime = builder.transTime - } - userdtl.paytype = builder.paytype - userdtl.payinfo = builder.payinfo - userdtl.transcode = builder.transcode - if (StringUtil.isEmpty(builder.description)) { - userdtl.transdesc = systemUtilService.getTranscodeName(builder.transcode, null) - } else { - userdtl.transdesc = builder.description - } - userdtl.outtradeno = builder.outtradeno - userdtl.shopaccno = builder.shopaccno -// userdtl.operid = - when (builder.tradetype) { - Tradetype.RECHARGE -> userdtl.tradeflag = 1 - Tradetype.CONSUME -> userdtl.tradeflag = 2 - } - userdtl.createtime = systemUtilService.sysdatetime.hostdatetime - - userdtl.amount = builder.amount - userdtl.status = TradeDict.DTL_STATUS_INIT - userdtlDao.save(userdtl) - - builder.details.forEach { - TDebitCreditDtl().apply { - refno = userdtl.refno - seqno = it.rowno - drsubjno = it.debitSubjNo - draccno = it.debitAccNo - crsubjno = it.creditSubjNo - craccno = it.creditAccNo - amount = it.amount - summary = it.summary - debitCreditDtlDao.save(this) - } - } - - if (builder.extendMap.isNotEmpty()) { - userdtlBusinessDao.save(TUserdtlBusiness(userdtl.refno, builder.extendMap)) //保存参数 - } - - return userdtl - } - - override fun finish(paydtl: TUserdtl, status: String, businessData: Map?): TUserdtl { - return finish(paydtl.refno, status, businessData) - } - - private fun fail(userdtl: TUserdtl, businessData: Map?) { - //失败 - if (TradeDict.DTL_STATUS_SUCCESS == userdtl.status) - throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "流水已经交易成功") - userdtl.status = TradeDict.DTL_STATUS_FAIL - userdtl.endtime = systemUtilService.sysdatetime.hostdatetime - userdtl.remark = businessData?.get("errmsg") - userdtlDao.save(userdtl) - } - - private fun success(userdtl: TUserdtl, businessData: Map?) { - if (TradeDict.DTL_STATUS_SUCCESS == userdtl.status) { - return - } - //TODO 校验已经成功的流水,不重复入账 - debitCreditDtlDao.findByRefno(userdtl.refno).forEach { detail -> - //个人账户入账 - if (Subject.SUBJNO_PERSONAL_DEPOSIT == detail.drsubjno) { - doDealAccount(detail.draccno, -1 * detail.amount, false) //借方消费 - } - if (Subject.SUBJNO_PERSONAL_DEPOSIT == detail.crsubjno) { - doDealAccount(detail.craccno, detail.amount, false) //贷方充值 - } - - //商户入账 - if (Subject.SUBJNO_MACHANT_INCOME == detail.drsubjno) { - doDealShopacc(detail.draccno, -1 * detail.amount) - } - if (Subject.SUBJNO_MACHANT_INCOME == detail.crsubjno) { - doDealShopacc(detail.craccno, detail.amount) - } - } - - userdtl.status = TradeDict.DTL_STATUS_SUCCESS - userdtl.accdate = systemUtilService.accdate //入账成功时更新 - userdtl.endtime = systemUtilService.sysdatetime.hostdatetime - //TODO 存储一些业务参数 - userdtlDao.save(userdtl) - } - - override fun finish(refno: String, status: String, businessData: Map?): TUserdtl { - val userdtl = getLockUserdtl(refno) - return when (status) { - TradeDict.DTL_STATUS_FAIL -> { - fail(userdtl, businessData) - userdtl - } - TradeDict.DTL_STATUS_SUCCESS -> { - //成功 - success(userdtl, businessData) - userdtl - } - else -> throw TransactionProcessException(TradeErrorCode.TRANSDTL_STATUS_ERROR, "未指定明确的交易结束状态") - } - } - - override fun wip(paydtl: TUserdtl): TUserdtl { - return wip(paydtl.refno) - } - - override fun wip(refno: String): TUserdtl { - val userdtl = getLockUserdtlNowait(refno) - if (TradeDict.DTL_STATUS_WIP == userdtl.status) { - return userdtl - } - - if (TradeDict.DTL_STATUS_INIT != userdtl.status) { - throw TransactionProcessException(TradeErrorCode.TRANSDTL_STATUS_NOT_INIT, - "交易参考号<$refno>非初始化流水") - } - userdtl.status = TradeDict.DTL_STATUS_WIP //待支付 - return userdtlDao.save(userdtl) - } - - override fun wip(builder: PersonTransBuilder): TUserdtl { - return wip(builder.refno) - } - - override fun finish(builder: PersonTransBuilder): TUserdtl { - return finish(builder.refno, builder.status, builder.resultMap) - } - - override fun getUserdtlForUpdateNowait(refno: String): TUserdtl { - return try { - userdtlDao.findByRefnoForUpdateNowait(refno) - ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "交易参考号<$refno>流水不存在") - } catch (ex: Exception) { - when (ex) { - is CannotAcquireLockException, is LockTimeoutException -> throw TransactionException(TradeErrorCode.ACCOUNT_TRADE_BUSY, "流水<$refno>被锁定,请稍后再试") - else -> throw ex - } - } - } - - override fun getUserdtlByBillnoForUpdateNowait(billno: String, shopaccno: String): TUserdtl { - return try { - userdtlDao.findByBillnoForUpdateNowait(billno, shopaccno) - ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS, "商户流水号<$billno>流水不存在") - } catch (ex: Exception) { - when (ex) { - is CannotAcquireLockException, is LockTimeoutException -> throw TransactionException(TradeErrorCode.ACCOUNT_TRADE_BUSY, "商户流水号<$billno>流水被锁定,请稍后再试") - else -> throw ex - } - } - } -} \ No newline at end of file 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 4e355cf5..ac98e143 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 @@ -384,6 +384,7 @@ class TransactionServiceImpl : TransactionService { throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "流水<$refno>状态错误") } transaction.status = TradeDict.DTL_STATUS_SUCCESS + transaction.accdate = systemUtilService.accdate if (transaction.person) { // update account balance transaction.personDtl?.let { @@ -391,6 +392,7 @@ class TransactionServiceImpl : TransactionService { throw TransactionProcessException(TradeErrorCode.ACCOUNT_TRADE_BUSY, "个人账户交易冲突") } + transaction.personDtl.accdate = transaction.accdate } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, "个人流水<${transaction.refno}>不存在") transaction.personDtl.status = TradeDict.DTL_STATUS_SUCCESS @@ -405,6 +407,7 @@ class TransactionServiceImpl : TransactionService { } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, "商户流水<${transaction.refno}>不存在") transaction.shopDtl.status = TradeDict.DTL_STATUS_SUCCESS + transaction.shopDtl.accdate = transaction.accdate } if (transaction.subject) { diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/pay_service.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/pay_service.kt index ba07cdab..f10c1a34 100644 --- a/src/main/kotlin/com/supwisdom/dlpay/api/service/pay_service.kt +++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/pay_service.kt @@ -1,12 +1,9 @@ package com.supwisdom.dlpay.api.service -import com.supwisdom.dlpay.api.PersonTransBuilder import com.supwisdom.dlpay.api.domain.TAccount -import com.supwisdom.dlpay.api.domain.TUserdtl import com.supwisdom.dlpay.framework.domain.TFeetypeConfig import com.supwisdom.dlpay.framework.domain.TShopacc import com.supwisdom.dlpay.framework.domain.TSubject -import com.supwisdom.dlpay.framework.domain.TTranstype import org.springframework.transaction.annotation.Propagation import org.springframework.transaction.annotation.Transactional @@ -20,56 +17,9 @@ interface AccountUtilServcie { fun readShopAcc(shopId: Int): TShopacc - fun readShopbyAccno(shpoacc: String): TShopacc + fun readShopbyShopaccno(shopaccno: String): TShopacc fun readSubject(subjno: String): TSubject fun readFeetype(feetype: String, paytype: String): TFeetypeConfig } - -interface PersonBalancePayService { - - /** - * 一步完成交易 - */ - @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class)) - fun process(builder: PersonTransBuilder): TUserdtl - - /** - * 两步交易,交易初始化方法,检查交易参数,记录交易流水 - */ - @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class)) - fun init(builder: PersonTransBuilder): TUserdtl - - /** - * 两步交易,完成交易过程,包括更新交易状态(成功、失败),更新借贷双方余额 - */ - @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class)) - fun finish(paydtl: TUserdtl, status: String, businessData: Map?): TUserdtl - - @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class)) - fun finish(refno: String, status: String, businessData: Map?): TUserdtl - - /** - * 两步交易,交易过程中判断交易状态,并更新交易状态为 wip - * 如果交易记录被锁,立刻抛出异常 - * @throws TransactionProcessException - */ - @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class)) - fun wip(paydtl: TUserdtl): TUserdtl - - @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class)) - fun wip(refno: String): TUserdtl - - @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class)) - fun wip(builder: PersonTransBuilder): TUserdtl - - @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class)) - fun finish(builder: PersonTransBuilder): TUserdtl - - @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class)) - fun getUserdtlForUpdateNowait(refno: String): TUserdtl - - @Transactional(propagation = Propagation.REQUIRED, rollbackFor = arrayOf(Exception::class)) - fun getUserdtlByBillnoForUpdateNowait(billno: String, shopaccno: String): TUserdtl -} \ No newline at end of file -- 2.17.1