import com.supwisdom.dlpay.framework.util.MD5;
import com.supwisdom.dlpay.framework.util.MoneyUtil;
+import com.supwisdom.dlpay.framework.util.TradeDict;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
@Entity
@Table(name = "TB_ACCOUNT",
indexes = {@Index(name = "acc_userid_idx", columnList = "userid"),
- @Index(name = "acc_status_idx", columnList = "status"),
+ @Index(name = "acc_status_idx", columnList = "transStatus"),
@Index(name = "acc_subjno_uk", unique = true, columnList = "subjno,userid")})
public class TAccount implements Serializable {
@Id
@Column(name = "USERID", nullable = false, length = 32)
private String userid; //用户ID
- @Column(name = "STATUS", nullable = false, length = 20)
- private String status; //状态:normal-正常;closed-注销;locked-冻结
+ @Column(name = "TRANS_STATUS", nullable = false, length = 20)
+ private String transStatus = TradeDict.STATUS_NORMAL; //状态:normal-正常;closed-注销;locked-冻结
@Column(name = "BALANCE", nullable = false, precision = 15, scale = 2)
private Double balance; //总余额
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, Timestamp lasttranstime, Double lastdayTransamt, Double lastdayDpsamt, String tac, String opendate, String closedate) {
+ public TAccount(String accname, String subjno, String userid, String transStatus, 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;
- this.status = status;
+ this.transStatus = transStatus;
this.balance = balance;
this.availbal = availbal;
this.frozebal = frozebal;
this.userid = userid;
}
- public String getStatus() {
- return status;
+ public String getTransStatus() {
+ return transStatus;
}
- public void setStatus(String status) {
- this.status = status;
+ public void setTransStatus(String transStatus) {
+ this.transStatus = transStatus;
}
public Double getBalance() {
package com.supwisdom.dlpay.api.domain;
+import com.supwisdom.dlpay.framework.util.TradeDict;
+
import javax.persistence.*;
@Entity
private String transtime;
@Column(name = "STATUS", length = 20, nullable = false)
- private String status;
+ private String status = TradeDict.DTL_STATUS_NONE;
@Column(name = "BEFBAL", precision = 9, scale = 2)
private Double befbal;
package com.supwisdom.dlpay.api.domain;
import com.supwisdom.dlpay.framework.util.Subject;
+import com.supwisdom.dlpay.framework.util.TradeDict;
import javax.persistence.*;
@Column(name = "checkdate", length = 8)
private String checkDate;
+ @Column(name = "transcode")
+ private Integer transCode;
+
@Column(name = "person")
private Boolean person = false;
private Boolean subject = false;
@Column(name = "status", length = 20)
- private String status = "none";
+ private String status = TradeDict.DTL_STATUS_NONE;
@Column(name = "sourcetype", length = 20)
private String sourceType = "";
@Column(name = "end_time")
private Timestamp endTime;
+ @Column(name = "reverse_type", nullable = false)
+ private String reverseType = TradeDict.REVERSE_FLAG_NONE; // 流水标识, none - 正常交易流水, cancel - 撤销流水, refund - 退款流水
+
+ // 撤销、退款原流水参考号
+ @Column(name = "reverse_refno")
+ private String reverseRefno = "";
+
@Column(name = "reverse_flag", nullable = false, length = 10)
- private String reverseFlag = "none"; // 冲正标识, none - 未冲正, refund - 被退款, cancel - 被冲正
+ private String reverseFlag = TradeDict.REVERSE_FLAG_NONE; // 冲正标识, none - 未冲正, refund - 被退款, cancel - 被冲正
+
+ @Column(name = "refund_amount", nullable = false)
+ private Double refundAmount = 0.0;
@OneToOne(targetEntity = TPersondtl.class, fetch = LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "refno", referencedColumnName = "refno")
this.sourceType = sourceType;
}
+ public Integer getTransCode() {
+ return transCode;
+ }
+
+ public void setTransCode(Integer transCode) {
+ this.transCode = transCode;
+ }
+
+ public String getReverseType() {
+ return reverseType;
+ }
+
+ public void setReverseType(String reverseType) {
+ this.reverseType = reverseType;
+ }
+
+ public String getReverseRefno() {
+ return reverseRefno;
+ }
+
+ public void setReverseRefno(String reverseRefno) {
+ this.reverseRefno = reverseRefno;
+ }
+
+ public Double getRefundAmount() {
+ return refundAmount;
+ }
+
+ public void setRefundAmount(Double refundAmount) {
+ this.refundAmount = refundAmount;
+ }
+
public Double sumAmountByAccno(String accno, String subjno,
String debitOrCredit) {
Double debitSum = 0.0;
try {\r
validate(request);\r
} catch (ValidateCodeException e) {\r
- //response.setStatus(HttpStatus.OK.value());\r
+ //response.setTransStatus(HttpStatus.OK.value());\r
//response.setContentType("application/json;charset=UTF-8");\r
//response.getWriter().write(objectMapper.writeValueAsString(JsonResult.error(400, e.getMessage())));\r
//response.sendError(HttpStatus.UNAUTHORIZED.value(),e.getMessage());\r
}
setDefaultFailureUrl("/login");
super.onAuthenticationFailure(request, response, new ValidateCodeException(errmsg));
- /*response.setStatus(HttpStatus.OK.value());
+ /*response.setTransStatus(HttpStatus.OK.value());
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(JsonResult.error(400, errmsg)));*/
}
account.setAccname(person.getName());
account.setSubjno(Subject.SUBJNO_PERSONAL_DEPOSIT);
account.setUserid(person.getUserid());
- account.setStatus(person.getStatus());
+ account.setTransStatus(person.getStatus());
account.setBalance(0.0);
account.setAvailbal(0.0);
account.setFrozebal(0.0);
public JsonResult deleteUser(String userid) {
TAccount account = accountDao.findByUserid(userid);
if (account != null) {
- if (!TradeDict.STATUS_CLOSED.equals(account.getStatus()) && account.getBalance() != 0) {
+ if (!TradeDict.STATUS_CLOSED.equals(account.getTransStatus()) && account.getBalance() != 0) {
return JsonResult.error("该用户账户未注销且余额不为0,无法删除");
} else {
accountDao.delete(account);
Optional<TAccount> opt = accountDao.findById(accno);
if (opt.isPresent()) {
TAccount acc = opt.get();
- acc.setStatus(TradeDict.STATUS_CLOSED);
+ acc.setTransStatus(TradeDict.STATUS_CLOSED);
accountDao.save(acc);
return JsonResult.ok("操作成功");
} else {
class QueryDtlResultParam : APIRequestParam() {
@Sign
- var refno:String?=null //二选一
+ var refno: String? = null //二选一
@Sign
- var billno:String?=null //二选一 (billno+shopaccno) 传billno时,shopaccno必传
+ var billno: String? = null //二选一 (billno+shopaccno) 传billno时,shopaccno必传
@Sign
- var shopaccno: String?=null
+ var shopaccno: String? = null
override fun checkParam(): Boolean {
if (StringUtil.isEmpty(refno) && (StringUtil.isEmpty(billno) || StringUtil.isEmpty(shopaccno))) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "流水唯一号不能为空")
class CitizenCardPayfinishParam : APIRequestParam() {
@Sign
- var refno:String=""
+ var refno: String = ""
override fun checkParam(): Boolean {
if (StringUtil.isEmpty(refno)) 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]")
if (StringUtil.isEmpty(stuempno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "一卡通唯一号不能为空")
- if(!StringUtil.isEmpty(yktshopid) && !NumberUtil.isDigits(yktshopid)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "一卡通商户号非整数")
+ if (!StringUtil.isEmpty(yktshopid) && !NumberUtil.isDigits(yktshopid)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "一卡通商户号非整数")
return true
}
class ConsumePayCancelParam : APIRequestParam() {
@Sign
- var refno:String? = null //流水号
+ var refno: String? = null //流水号
@Sign
- var billno:String?=null //订单号
+ var billno: String? = null //订单号
@Sign
- var shopaccno:String?=null //商户号
+ var shopaccno: String? = null //商户号
@Sign
- var requestbillno:String="" //退款请求唯一标识
+ var requestbillno: String = "" //退款请求唯一标识
@Sign
var transdate: String = "" //必传
@Sign
}
}
+class ConsumePayRefundParam : APIRequestParam() {
+ @Sign
+ var refno: String? = null //流水号
+ @Sign
+ var billno: String? = null //订单号
+ @Sign
+ var shopaccno: String? = null //商户号
+
+ @Sign
+ var refundAmount: Int = 0 // 退款金额
+
+ @Sign
+ var requestbillno: String = "" //退款请求唯一标识
+ @Sign
+ var transdate: String = "" //必传
+ @Sign
+ var transtime: String = "" //必传
+
+ override fun checkParam(): Boolean {
+ if (StringUtil.isEmpty(refno) && (StringUtil.isEmpty(billno) || StringUtil.isEmpty(shopaccno))) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "原流水唯一号不能为空")
+ if (StringUtil.isEmpty(requestbillno)) 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
+ }
+}
// ============================ RECHARGE ============================ //
class CommonRechargeConfirmParam : APIRequestParam() {
@Sign
- var refno:String = "" //流水号
+ var refno: String = "" //流水号
override fun checkParam(): Boolean {
- if(StringUtil.isEmpty(refno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "流水号不能为空")
+ if (StringUtil.isEmpty(refno)) throw RequestParamCheckException(TradeErrorCode.REQUEST_PARAM_ERROR, "流水号不能为空")
return true
}
import com.supwisdom.dlpay.api.TransactionBuilder
import com.supwisdom.dlpay.api.bean.*
import com.supwisdom.dlpay.api.dao.TransactionMainDao
-import com.supwisdom.dlpay.api.domain.TAccount
import com.supwisdom.dlpay.api.service.AccountUtilServcie
import com.supwisdom.dlpay.api.service.ConsumePayService
import com.supwisdom.dlpay.api.service.TransactionServiceProxy
import com.supwisdom.dlpay.api.service.UserService
-import com.supwisdom.dlpay.exception.RequestParamCheckException
-import com.supwisdom.dlpay.exception.TransactionException
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.Subject
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
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
@RestController
@RequestMapping("/api/consume")
lateinit var systemUtilService: SystemUtilService
@Autowired
lateinit var consumePayService: ConsumePayService
- @Autowired
- lateinit var commonService: CommonService
-
- @Autowired
- lateinit var transactionMainDao: TransactionMainDao
-
@Autowired
lateinit var transactionService: TransactionServiceProxy
@PostMapping("/paycancel")
fun payCancel(@RequestBody param: ConsumePayCancelParam): ResponseEntity<Any> {
consumePayService.getTransactionMainDtl(param.refno, param.billno, param.shopaccno)?.let {
+ val builder = TransactionBuilder().apply {
+ setTransInfo(param.transdate, param.transtime, it.transCode, it.sourceType)
+ setOutTransInfo(it.outId, param.requestbillno)
+ }
+ val cancelTrans = builder.cancelInit(it.refno, transactionService)
//fixme: 撤销逻辑
-
-
+ if (it.sourceType.isNotEmpty()) {
+ // 第三方冲正
+ }
+ transactionService.success(cancelTrans.refno)
return ResponseEntity.ok(ResponseBodyBuilder.create()
.success("交易确认成功"))
} ?: return ResponseEntity.ok(ResponseBodyBuilder.create()
* ============================================================================
* */
@PostMapping("/payrefund")
- fun payRefund(@RequestBody param: ConsumePayCancelParam): ResponseEntity<Any> {
- return ResponseEntity.ok(ResponseBodyBuilder.create()
- .fail(TradeErrorCode.BUSINESS_DEAL_ERROR, "退款逻辑未实现"))
+ fun payRefund(@RequestBody param: ConsumePayRefundParam): ResponseEntity<Any> {
+ consumePayService.getTransactionMainDtl(param.refno, param.billno, param.shopaccno)?.let {
+ val builder = TransactionBuilder().apply {
+ setTransInfo(param.transdate, param.transtime, it.transCode, it.sourceType)
+ setOutTransInfo(it.outId, param.requestbillno)
+ }
+ val refundTrans = builder.refundInit(it.refno,
+ param.refundAmount / 100.0, transactionService)
+ //fixme: 撤销逻辑
+ if (it.sourceType.isNotEmpty()) {
+ // 第三方冲正
+ }
+ transactionService.success(refundTrans.refno)
+ return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .success("交易确认成功"))
+ } ?: return ResponseEntity.ok(ResponseBodyBuilder.create()
+ .fail(TradeErrorCode.TRANSACTION_NOT_EXISTS, "流水不存在"))
}
/**
package com.supwisdom.dlpay.api.service.impl
+import com.supwisdom.dlpay.api.AccountProxy
import com.supwisdom.dlpay.api.TransactionBuilder
+import com.supwisdom.dlpay.api.dao.AccountDao
import com.supwisdom.dlpay.api.dao.TransactionMainDao
import com.supwisdom.dlpay.api.domain.*
import com.supwisdom.dlpay.api.repositories.AccountService
import com.supwisdom.dlpay.api.service.TransactionService
import com.supwisdom.dlpay.exception.TransactionCheckException
import com.supwisdom.dlpay.exception.TransactionProcessException
+import com.supwisdom.dlpay.framework.dao.ShopaccDao
+import com.supwisdom.dlpay.framework.dao.SubjectDao
import com.supwisdom.dlpay.framework.service.SystemUtilService
import com.supwisdom.dlpay.framework.util.Subject
import com.supwisdom.dlpay.framework.util.TradeDict
import com.supwisdom.dlpay.framework.util.TradeErrorCode
-import org.hibernate.Transaction
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.sql.SQLException
@Autowired
private lateinit var accountService: AccountService
+ @Autowired
+ private lateinit var accountDao: AccountDao
+
+ @Autowired
+ private lateinit var shopaccDao: ShopaccDao
+
+ @Autowired
+ private lateinit var subjectDao: SubjectDao
+
@Autowired
private lateinit var systemUtilService: SystemUtilService
@Autowired
private lateinit var sourceTypeService: SourceTypeService
+ /// 公共函数部分
private fun preCheck(builder: TransactionBuilder) {
builder.preCheck()
-
}
private fun builderRecords(builder: TransactionBuilder, status: String): TTransactionMain {
createTime = systemUtilService.sysdatetime.sysdate
operid = builder.operId
opertype = builder.operType
- reverseFlag = builder.tradeType
+ reverseFlag = builder.reverseType
checkable = sourceType.checkable
+ transCode = builder.transCode
+ reverseType = TradeDict.REVERSE_FLAG_NONE
+ refundAmount = 0.0
checkDate = null
settleDate = null
this.sourceType = sourceType.sourceType
}
}
- override fun init(builder: TransactionBuilder): TTransactionMain {
- return builderRecords(builder, TradeDict.DTL_STATUS_INIT)
- }
-
- override fun wip(builder: TransactionBuilder): TTransactionMain {
- return builderRecords(builder, TradeDict.DTL_STATUS_WIP)
- }
-
private fun updateRecordStatus(transaction: TTransactionMain, status: String) {
if (transaction.person) {
transaction.personDtl?.also {
transaction.status = status
}
+ /////////////////////////////////////////////////////////////////////
+ // 业务接口
+ override fun init(builder: TransactionBuilder): TTransactionMain {
+ return builderRecords(builder, TradeDict.DTL_STATUS_INIT)
+ }
+
+ override fun wip(builder: TransactionBuilder): TTransactionMain {
+ return builderRecords(builder, TradeDict.DTL_STATUS_WIP)
+ }
+
override fun wip(refno: String): TTransactionMain {
val transaction = transactionMainDao.findByRefnoForUpdate(refno)
?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "流水<$refno>参考号错误")
return fail(refno, "")
}
-
- override fun success(refno: String): TTransactionMain {
- return success(refno, "")
- }
-
override fun fail(refno: String, remark: String): TTransactionMain {
val transaction = transactionMainDao.findByRefnoForUpdate(refno)
?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "流水<$refno>参考号错误")
return transaction
}
+ //////////////////////////////////////////////////////////////////
+ // 成功
+ private fun transactionOnSuccess(transaction: TTransactionMain, remark: String, overdraft: Boolean) {
+ if (transaction.person) {
+ // update account balance
+ val amount = transaction.sumAmountByAccno(
+ transaction.personDtl.accountNo, Subject.SUBJNO_PERSONAL_DEPOSIT,
+ "both")
+ if (amount.absoluteValue.compareTo(0.0) != 0) {
+ transaction.personDtl?.let {
+ transaction.personDtl.accdate = transaction.accdate
+ accountService.recalcAccountBalance(it, amount, overdraft)
+ } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS,
+ "个人流水<${transaction.refno}>不存在")
+ }
+ transaction.personDtl.status = TradeDict.DTL_STATUS_SUCCESS
+ transaction.personDtl.remark = remark
+ }
+ if (transaction.shop) {
+ transaction.shopDtl.updateBala = false
+ transaction.shopDtl.status = TradeDict.DTL_STATUS_SUCCESS
+ transaction.shopDtl.accdate = transaction.accdate
+ transaction.shopDtl.remark = remark
+ }
+
+ if (transaction.subject) {
+ // update subject balance
+ }
+ }
+
override fun success(refno: String, remark: String): TTransactionMain {
val transaction = transactionMainDao.findByRefnoForUpdate(refno)
?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_IS_FINISHED, "参考号<$refno>错误,流水不存在")
return transaction
}
- private fun preCheckRefund(transaction: TTransactionMain, amount: Double) {
-
- }
-
- override fun refund(originRefno: String): TTransactionMain {
- val originTransation = transactionMainDao.findByRefnoForUpdate(originRefno)
- ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS,
- "退款流水<$originRefno>不存在")
-
- preCheckRefund(originTransation, 0.0)
- TODO("")
+ override fun success(refno: String): TTransactionMain {
+ return success(refno, "")
}
- override fun refundInit(originRefno: String): TTransactionMain {
+ //////////////////////////////////////////////////////////////////
+ // 回退业务接口,包括撤销和退款
+ override fun refundInit(originRefno: String, builder: TransactionBuilder): TTransactionMain {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
- override fun refundConfirm(refno: String): TTransactionMain {
- TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
- }
+ override fun cancelInit(originRefno: String, builder: TransactionBuilder): TTransactionMain {
+ val originTrans = transactionMainDao.findByRefnoForUpdate(originRefno)
+ ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS
+ , "被冲正流水不存在")
+ if (originTrans.status != TradeDict.DTL_STATUS_SUCCESS) {
+ throw TransactionProcessException(TradeErrorCode.TRANSDTL_STATUS_ERROR,
+ "原流水不是成功状态")
+ }
+ if (originTrans.reverseFlag != TradeDict.REVERSE_FLAG_NONE) {
+ throw TransactionProcessException(TradeErrorCode.TRANSDTL_STATUS_ERROR,
+ "原流水已被冲正")
+ }
- override fun refundFail(refno: String): TTransactionMain {
- TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
- }
+ doReversePreCheck(originTrans, builder)
- override fun cancel(originRefno: String): TTransactionMain {
- TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
- }
+ builder.preCheck()
+ val transaction = doReverseProcess(originTrans, builder)
- override fun cancelInit(originRefno: String): TTransactionMain {
- TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+ originTrans.reverseFlag = TradeDict.REVERSE_FLAG_CANCEL
+ transactionMainDao.save(originTrans)
+ return transaction
}
- override fun cancelConfirm(refno: String): TTransactionMain {
- TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+ private fun getOppositeTradeFlag(flag: String): String {
+ return if (flag == TradeDict.TRADE_FLAG_IN) {
+ TradeDict.TRADE_FLAG_OUT
+ } else {
+ TradeDict.TRADE_FLAG_IN
+ }
}
- override fun cancelFail(refno: String): TTransactionMain {
- TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
- }
+ private fun doReverseProcess(originTrans: TTransactionMain, builder: TransactionBuilder): TTransactionMain {
- private fun transactionOnSuccess(transaction: TTransactionMain, remark: String, overdraft: Boolean) {
- if (transaction.person) {
- // update account balance
- val amount = transaction.sumAmountByAccno(
- transaction.personDtl.accountNo, Subject.SUBJNO_PERSONAL_DEPOSIT,
- "both")
- if (amount.absoluteValue.compareTo(0.0) != 0) {
- transaction.personDtl?.let {
- transaction.personDtl.accdate = transaction.accdate
- accountService.recalcAccountBalance(it, amount, overdraft)
- } ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS,
- "个人流水<${transaction.refno}>不存在")
+ if (originTrans.person) {
+ builder.person().apply {
+ setAmount(-originTrans.personDtl.amount, getOppositeTradeFlag(originTrans.personDtl.tradeflag))
+ opposite = AccountProxy(builder.shop().shopacc)
}
- transaction.personDtl.status = TradeDict.DTL_STATUS_SUCCESS
- transaction.personDtl.remark = remark
}
- if (transaction.shop) {
- transaction.shopDtl.updateBala = false
- transaction.shopDtl.status = TradeDict.DTL_STATUS_SUCCESS
- transaction.shopDtl.accdate = transaction.accdate
- transaction.shopDtl.remark = remark
+ if (originTrans.shop) {
+ builder.shop().apply {
+ setAmount(-originTrans.shopDtl.amount, getOppositeTradeFlag(originTrans.shopDtl.tradeflag))
+ opposite = AccountProxy(builder.person().person)
+ }
}
+ TODO("")
+// originTrans.details.forEach {
+// builder.addDebitCreditRecord()
+// }
+ }
- if (transaction.subject) {
- // update subject balance
+ private fun doReversePreCheck(originTrans: TTransactionMain, builder: TransactionBuilder) {
+ if (originTrans.person) {
+ val account = accountDao.findByUserid(originTrans.personDtl.userid)
+ ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS,
+ "账户不存在")
+ builder.person(account)
+ }
+ if (originTrans.shop) {
+ val shopacc = shopaccDao.findByShopaccno(originTrans.shopDtl.shopaccno)
+ ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS,
+ "商户不存在")
+ builder.shop(shopacc)
+ }
+
+ if (originTrans.subject) {
+ val subject = subjectDao.findBySubjno(originTrans.subjectDtl.subjectno)
+ ?: throw TransactionProcessException(TradeErrorCode.ACCOUNT_NOT_EXISTS,
+ "科目不存在")
+ builder.subject(subject)
}
}
accname = person.name
subjno = Subject.SUBJNO_PERSONAL_DEPOSIT
userid = person.userid
- status = person.status
+ transStatus = person.status
balance = 0.0
availbal = 0.0
frozebal = 0.0
* 退款类业务
*/
@Transactional
- fun refund(originRefno: String): TTransactionMain
-
- @Transactional
- fun refundInit(originRefno: String): TTransactionMain
-
- @Transactional
- fun refundConfirm(refno: String): TTransactionMain
-
- @Transactional
- fun refundFail(refno: String): TTransactionMain
+ fun refundInit(originRefno: String, builder: TransactionBuilder): TTransactionMain
/**
* 撤销业务
*/
@Transactional
- fun cancel(originRefno: String): TTransactionMain
-
- @Transactional
- fun cancelInit(originRefno: String): TTransactionMain
-
- @Transactional
- fun cancelConfirm(refno: String): TTransactionMain
-
- @Transactional
- fun cancelFail(refno: String): TTransactionMain
+ fun cancelInit(originRefno: String, builder: TransactionBuilder): TTransactionMain
// 补帐接口
@Transactional
return transactionService.wip(refno)
}
- fun wip(builder: TransactionBuilder): TTransactionMain {
- return transactionService.wip(builder)
- }
-
fun fail(refno: String): TTransactionMain {
return transactionService.fail(refno)
}
return success(refno, "")
}
- fun cancel(refno: String): TTransactionMain {
- TODO("not implementation")
+ fun cancel(originRefno: String, builder: TransactionBuilder, confirm: Boolean): TTransactionMain {
+ val trans = transactionService.cancelInit(originRefno, builder)
+ if (confirm) {
+ return success(trans.refno)
+ }
+ return trans
}
fun refund(originRefno: String, newRefno: String): TTransactionMain {
return this
}
- var tradeType: String = "none"
+ var reverseType: String = "none"
private set
- fun refund(): TransactionBuilder {
- this.tradeType = TradeDict.REVERSE_FLAG_REFUND
- return this
- }
-
- fun cancel(): TransactionBuilder {
- this.tradeType = TradeDict.REVERSE_FLAG_CANCEL
- return this
- }
-
// 以下属性可以在子表中不同
var payinfo: String = ""
}
private fun checkAmount(amount: Double): Boolean {
- return if (tradeType == TradeDict.REVERSE_FLAG_NONE) {
+ return if (reverseType == TradeDict.REVERSE_FLAG_NONE) {
amount >= 0.0
} else {
amount <= 0.0
"交易码错误")
}
- if (tradeType !in VALID_REVERSEFLAG) {
+ if (reverseType !in VALID_REVERSEFLAG) {
throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
"冲正标志错误")
}
}
if (hasPerson()) {
person().also {
+ if (it.person.transStatus != TradeDict.STATUS_NORMAL) {
+ throw TransactionCheckException(TradeErrorCode.PERSON_STATUS_ERROR,
+ "个人状态错误")
+ }
if (it.tradeFlag !in VALID_TRADEFLAG) {
throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
"个人交易收支方向错误")
if (hasShop()) {
shop().also {
+ if (it.shopacc.status != TradeDict.STATUS_NORMAL) {
+ throw TransactionCheckException(TradeErrorCode.PERSON_STATUS_ERROR,
+ "商户状态错误")
+ }
if (it.tradeFlag !in VALID_TRADEFLAG) {
throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
"商户交易收支方向错误")
return transactionService.init(this)
}
- fun wip(transactionService: TransactionServiceProxy): TTransactionMain {
- return transactionService.wip(this)
+ fun refund(originRefno: String, amount: Double, transactionService: TransactionServiceProxy): TTransactionMain {
+ this.reverseType = TradeDict.REVERSE_FLAG_REFUND
+ return transactionService.refund(originRefno, "")
}
- fun cancel(transactionService: TransactionServiceProxy, originRefno: String): TTransactionMain {
- TODO("not implement")
+ fun refundInit(originRefno: String, amount: Double, transactionService: TransactionServiceProxy): TTransactionMain {
+ this.reverseType = TradeDict.REVERSE_FLAG_REFUND
+ return transactionService.refund(originRefno, "")
}
- fun refund(transactionService: TransactionServiceProxy, originRefno: String, amount: Double): TTransactionMain {
- TODO("not implement")
+ fun cancel(originRefno: String, transactionService: TransactionServiceProxy): TTransactionMain {
+ this.reverseType = TradeDict.REVERSE_FLAG_CANCEL
+ return transactionService.cancel(originRefno, this, true)
}
+
+ fun cancelInit(originRefno: String, transactionService: TransactionServiceProxy): TTransactionMain {
+ this.reverseType = TradeDict.REVERSE_FLAG_CANCEL
+ return transactionService.cancel(originRefno, this, false)
+ }
+
}
-insert into tb_apiclient(appid, secret, status, roles)
+insert into tb_apiclient(appid, secret, transStatus, roles)
values ('100001', 'oUw2NmA09ficiVWD4TUQLDOkPyzQa3VzbjjsW0B2qTk=', 'normal', 'ROLE_THIRD_ADMIN');
INSERT INTO tb_operator(
- operid, closedate, opendate, opercode, opername, operpwd, opertype, status)
+ operid, closedate, opendate, opercode, opername, operpwd, opertype, transStatus)
VALUES ('LOR2IwRkbOjp+sVG9KR2BpHZbwGKepS4', '20500101', '20190101', 'system', '系统管理员', '$2a$10$Ex9xp11.vCaD8D0a7ahiUOKqDij1TcCUBwRAmrqXeDvAkmzLibn4.', 'oper', 'normal');
INSERT INTO tb_role(
<div class="layui-inline">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
- <select name="status" id="shopdtl-search-status" class="layui-select">
+ <select name="transStatus" id="shopdtl-search-transStatus" class="layui-select">
<option value=""> 全部</option>
<option th:each="st:${dtlstatuslist}" th:value="${st.dictval}"
th:text="${st.dictcaption}"></option>
sourcetype: $("#shopdtl-search-sourcetype").val(),
tradeflag: $("#shopdtl-search-tradeflag").val(),
transcode: $("#shopdtl-search-transcode").val(),
- status: $("#shopdtl-search-status").val()
+ transStatus: $("#shopdtl-search-transStatus").val()
}, page: {curr: 1}
});
});
"sourcetype": "",
"tradeflag": "",
"transcode": "",
- "status": ""
+ "transStatus": ""
});
form.render("select");
treeSelect.revokeNode('shopdtl-search-shopaccno-filter');
{field: 'shopname', title: '商户名称', align: 'center', width: 250},
{field: 'amount', title: '交易金额', align: 'center', width: 120, sort: true},
{
- field: 'status', title: '状态', align: 'center', width: 90, templet: function (item) {
- if (item.status == 'init') {
+ field: 'transStatus', title: '状态', align: 'center', width: 90, templet: function (item) {
+ if (item.transStatus == 'init') {
return '<span class="layui-badge layui-bg-gray">初始化</span>';
- } else if (item.status == 'success') {
+ } else if (item.transStatus == 'success') {
return '<span class="layui-badge layui-bg-green">成功</span>';
- } else if (item.status == 'fail') {
+ } else if (item.transStatus == 'fail') {
return '<span class="layui-badge">失败</span>';
- } else if (item.status == 'wip') {
+ } else if (item.transStatus == 'wip') {
return '<span class="layui-badge layui-bg-orange">待支付</span>';
} else {
- return item.status;
+ return item.transStatus;
}
}
},
<div class="layui-inline">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
- <select name="status" id="userdtl-search-status" class="layui-select">
+ <select name="transStatus" id="userdtl-search-transStatus" class="layui-select">
<option value=""> 全部</option>
<option th:each="st:${dtlstatuslist}" th:value="${st.dictval}"
th:text="${st.dictcaption}"></option>
sourcetype: $("#userdtl-search-sourcetype").val(),
tradeflag: $("#userdtl-search-tradeflag").val(),
transcode: $("#userdtl-search-transcode").val(),
- status: $("#userdtl-search-status").val()
+ transStatus: $("#userdtl-search-transStatus").val()
}, page: {curr: 1}
});
});
"sourcetype": "",
"tradeflag": "",
"transcode": "",
- "status": ""
+ "transStatus": ""
});
form.render("select");
});
{field: 'userName', title: '姓名', align: 'center', width: 150},
{field: 'amount', title: '交易金额', align: 'center', width: 120, sort: true},
{
- field: 'status', title: '状态', align: 'center', width: 90, templet: function (item) {
- if (item.status == 'init') {
+ field: 'transStatus', title: '状态', align: 'center', width: 90, templet: function (item) {
+ if (item.transStatus == 'init') {
return '<span class="layui-badge layui-bg-gray">初始化</span>';
- } else if (item.status == 'success') {
+ } else if (item.transStatus == 'success') {
return '<span class="layui-badge layui-bg-green">成功</span>';
- } else if (item.status == 'fail') {
+ } else if (item.transStatus == 'fail') {
return '<span class="layui-badge">失败</span>';
- } else if (item.status == 'wip') {
+ } else if (item.transStatus == 'wip') {
return '<span class="layui-badge layui-bg-orange">待支付</span>';
} else {
- return item.status;
+ return item.transStatus;
}
}
},
<script type="text/html" id="oper-tpl-state">
{{# if(d.opercode == 'system') { }}
<input type="checkbox" lay-filter="oper-tpl-state" value="{{d.operid}}" lay-skin="switch" lay-text="正常|注销"
- {{d.status=='normal'?'checked':''}} disabled/>
+ {{d.transStatus=='normal'?'checked':''}} disabled/>
{{# }else{ }}
<input type="checkbox" lay-filter="oper-tpl-state" value="{{d.operid}}" lay-skin="switch" lay-text="正常|注销"
- {{d.status=='normal'?'checked':''}} />
+ {{d.transStatus=='normal'?'checked':''}} />
{{# } }}
</script>
{type: 'numbers', fixed: 'left'},
{field: 'opercode', title: '管理员账号', fixed: 'left', sort: true},
{field: 'opername', title: '管理员名称', sort: true},
- {field: 'status', title: '状态', sort: true, width: 100, templet: '#oper-tpl-state'},
+ {field: 'transStatus', title: '状态', sort: true, width: 100, templet: '#oper-tpl-state'},
{
field: 'sex', title: '性别', sort: true, width: 80, align: 'center', templet: function (item) {
if (item.sex == 'male') {
<!-- 表格状态列 -->
<script type="text/html" id="api-tpl-state">
<input type="checkbox" lay-filter="api-tpl-state" value="{{d.appid}}" lay-skin="switch" lay-text="启用|关闭"
- {{d.status=='normal'?'checked':''}} />
+ {{d.transStatus=='normal'?'checked':''}} />
</script>
<script>
[
{field: 'appid', title: 'APPID', width: 120, align: 'right', fixed: 'left', sort: true},
{field: 'secret', title: '密钥', align: 'center', edit: 'text'},
- {field: 'status', title: '状态', width: 100, templet: '#api-tpl-state',sort: true},
+ {field: 'transStatus', title: '状态', width: 100, templet: '#api-tpl-state',sort: true},
{field: 'roles', title: '角色', align: 'center' },
{align: 'center', title: '操作', width: 150, toolbar: '#apiclient-table-bar', fixed: 'right'}
]
}
return item.person.name;
}},
- {field: 'status', title: '状态',fixed: 'left',width: 80 , templet: function (item) {
- if (item.status == 'normal') {
+ {field: 'transStatus', title: '状态',fixed: 'left',width: 80 , templet: function (item) {
+ if (item.transStatus == 'normal') {
return '<span class="layui-badge layui-bg-green">正常</span>'
- } else if (item.status == 'closed') {
+ } else if (item.transStatus == 'closed') {
return '<span class="layui-badge">注销</span>'
- } else if (item.status == 'locked') {
+ } else if (item.transStatus == 'locked') {
return '<span class="layui-badge layui-bg-orange">锁定</span>'
} else {
return '异常'
{field: 'opendate', title: '开户日期', width: 100,fixed: 'left', sort: true},
{
field: 'accno', align: 'center', title: '操作', fixed: 'right', templet: function (item) {
- if (item.status != 'closed') {
+ if (item.transStatus != 'closed') {
let html = ' <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del"><i class="layui-icon layui-icon-delete"></i>注销</a> ';
return html;
}else {
}, function (ret) {
console.log(ret);
layer.closeAll('loading');
- if(ret.status==403){
+ if(ret.transStatus==403){
layer.msg('没有权限', {icon: 2});
}else{
layer.msg('请求失败了,请稍后再试', {icon: 2});
}
}
},
- {field: 'status', title: '状态',fixed: 'left',width: 80 , templet: function (item) {
- if (item.status == 'normal') {
+ {field: 'transStatus', title: '状态',fixed: 'left',width: 80 , templet: function (item) {
+ if (item.transStatus == 'normal') {
return '<span class="layui-badge layui-bg-green">正常</span>'
- } else if (item.status == 'closed') {
+ } else if (item.transStatus == 'closed') {
return '<span class="layui-badge">注销</span>'
- } else if (item.status == 'locked') {
+ } else if (item.transStatus == 'locked') {
return '<span class="layui-badge layui-bg-orange">锁定</span>'
} else {
return '异常'
}, function (ret) {
console.log(ret);
layer.closeAll('loading');
- if(ret.status==403){
+ if(ret.transStatus==403){
layer.msg('没有权限', {icon: 2});
}else{
layer.msg('请求失败了,请稍后再试', {icon: 2});
}, function (ret) {
console.log(ret);
layer.closeAll('loading');
- if(ret.status==403){
+ if(ret.transStatus==403){
layer.msg('没有权限', {icon: 2});
}else{
layer.msg('请求失败了,请稍后再试', {icon: 2});
}, function (ret) {
console.log(ret);
layer.closeAll('loading');
- if(ret.status==403){
+ if(ret.transStatus==403){
layer.msg('没有权限', {icon: 2});
}else{
layer.msg('请求失败了,请稍后再试', {icon: 2});