Commit 3aac1d6d authored by Administrator's avatar Administrator

创建项目

parent ee1659fd
......@@ -22,6 +22,11 @@
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!--javax-->
<dependency>
<groupId>javax.inject</groupId>
......
package cn.quant.baa.pay.aspect;
import cn.quant.baa.pay.model.BusinessRequest;
import cn.quant.baa.pay.annotation.BusinessMapping;
import cn.quant.baa.pay.component.Sequencer;
import cn.quant.baa.pay.context.TransactionSession;
import cn.quant.spring.IllegalArgException;
import cn.quant.baa.pay.model.BusinessRequest;
import cn.quant.spring.context.ServerApplicationContext;
import cn.quant.spring.util.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
......@@ -26,12 +26,17 @@ import java.lang.reflect.Method;
@Component
public class BusinessMappingAspect {
@Autowired
private Sequencer sequencer;
@Autowired
private ServerApplicationContext serverApplicationContext;
public void session(Object arg) {
if (BusinessRequest.class.isInstance(arg)) {
TransactionSession.newInstance((BusinessRequest) arg, serverApplicationContext);
TransactionSession.newInstance((BusinessRequest) arg, serverApplicationContext, sequencer);
}
}
......@@ -47,7 +52,7 @@ public class BusinessMappingAspect {
if (annotation.session() > 0) {
Object[] args = joinPoint.getArgs();
if (args.length < annotation.session()) {
throw new IllegalArgException(StringUtils.format("Business mapping session value({}) less than arguments size({}) - {}"
throw new IllegalArgumentException(StringUtils.format("Business mapping session value({}) less than arguments size({}) - {}"
, annotation.session(), args.length, method));
}
session(args[annotation.session() - 1]);
......
......@@ -28,7 +28,7 @@ public class Sequencer {
return sequencer.nextId(flake % 225L);
}
public int getPartitionKey(long id) {
public int partitionKey(long id) {
return (int) ((id >> 8 << 8) ^ id);
}
......
package cn.quant.baa.pay.context;
import cn.quant.baa.pay.component.Sequencer;
import cn.quant.baa.pay.jpa.entity.AccountEntity;
import cn.quant.baa.pay.model.BusinessRequest;
import cn.quant.spring.NullException;
import cn.quant.spring.context.BusinessSession;
import cn.quant.spring.context.ServerApplicationContext;
import cn.quant.spring.data.jpa.entity.OptimisticEntity;
......@@ -26,9 +26,24 @@ public class TransactionSession extends BusinessSession {
private AccountEntity account;
public TransactionSession(ServerApplicationContext context) {
private Sequencer sequencer;
public TransactionSession(ServerApplicationContext context, Sequencer sequencer) {
super(context);
this.repositoryProxy = new JapRepositoryProxy(context.getParent());
this.sequencer = sequencer;
}
public long nextId() {
return sequencer.nextId();
}
public long nextId(long id) {
return sequencer.nextId(id);
}
public int partitionKey(long id){
return sequencer.partitionKey(id);
}
/**
......@@ -46,10 +61,10 @@ public class TransactionSession extends BusinessSession {
local.remove();
}
public static TransactionSession newInstance(BusinessRequest request, ServerApplicationContext context) {
public static TransactionSession newInstance(BusinessRequest request, ServerApplicationContext context, Sequencer sequencer) {
TransactionSession session = local.get();
if (session == null) {
session = new TransactionSession(context);
session = new TransactionSession(context, sequencer);
Date businessDate = request.getBusinessDate();
if (businessDate == null) {
session.setBusinessDate(LocalDateTime.now());
......@@ -105,7 +120,7 @@ public class TransactionSession extends BusinessSession {
return repositoryProxy.getRepository(cls);
}
public <T> T findOne(Class<T> cls, Object key) {
public <T> T findOne(Class<T> cls, Object key) {
RepositoryProxy repositoryProxy = this.getRepositoryProxy();
T t = null;
if (repositoryProxy != null) {
......
package cn.quant.baa.pay.dict;
import java.math.BigDecimal;
/**
* Created by Administrator on 2021/8/27 0027.
*/
public enum CreditDebitFlag {
N("非金融交易", BigDecimal.ZERO),
C("贷记", BigDecimal.ONE),
D("借记", BigDecimal.ONE.negate());
public final String text;
public final BigDecimal sign;
public final boolean positive;
CreditDebitFlag(String txt, BigDecimal sign) {
this.sign = sign;
this.text = txt;
this.positive = (sign.compareTo(BigDecimal.ZERO) >= 0);
}
}
......@@ -5,13 +5,20 @@ package cn.quant.baa.pay.dict;
*/
public enum MessageEnum {
EMPTY_REQ_DATA("2000000"),
MCH_ID_ILLEGAL("2000000"),
CHAN_ID_ILLEGAL("2000000"),
BUYER_ID_ILLEGAL("2000000"),
INSTITUTION_ID_ILLEGAL("2000000"),
PRODUCT_ID_ILLEGAL("2000000"),
ILLEGAL_REQ_SUBJECT("2000000"),
ILLEGAL_REQ_MCH_ID("2000000"),
ILLEGAL_REQ_CHAN_ID("2000000"),
ILLEGAL_REQ_BUYER_ID("2000000"),
ILLEGAL_REQ_INST_ID("2000000"),
ILLEGAL_REQ_PROD_ID("2000000"),
ILLEGAL_REQ_OUT_TRADE_NO("2000000"),
ILLEGAL_REQ_ORIG_AMT("2000000"),
ILLEGAL_REQ_AMT("2000000"),
ILLEGAL_REQ_DISC_AMT("2000000"),
ILLEGAL_REQ_CASH_AMT("2000000"),
ILLEGAL_REQ_CREDIT_AMT("2000000"),
EXIST_ORDER("300"),
ACQUIRER_NOSUCH("2000000"),
ACQUIRER_NOMATCH("2000000"),
......
package cn.quant.baa.pay.dict;
/**
* Created by Administrator on 2021/8/27 0027.
*/
public enum PayMethod {
AUTO("自动"),
DRST("主动"),
MANU("手动");
public final String text;
PayMethod(String text) {
this.text = text;
}
}
package cn.quant.baa.pay.jpa.entity;
import cn.quant.spring.data.jpa.entity.DescriptionEntity;
import org.hibernate.envers.Audited;
import java.io.Serializable;
/**
* Created by Administrator on 2021/8/22 0022.
*/
@Audited
public abstract class AuditedDescriptionEntity extends DescriptionEntity implements Serializable{
private static final long serialVersionUID = -5974712123235831070L;
}
package cn.quant.baa.pay.jpa.entity;
import cn.quant.spring.data.jpa.entity.OptimisticEntity;
import cn.quant.spring.data.jpa.entity.PartitionEntity;
import org.hibernate.envers.Audited;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.io.Serializable;
/**
* <p><b>Enable Audited Annotation:</b><br/>
* <code>@org.hibernate.envers.Audited</code><br/>
* <code>@javax.persistence.EntityListeners(AuditingEntityListener.class)</code><br/>
* <code>@javax.persistence.MappedSuperclass</code><br/>
* </p>
* Created by hechao on 2020/2/13.
* @see cn.quant.baa.pay.support.AuditorAwareHandler
*/
@Audited
public abstract class AuditedOptimisticEntity extends OptimisticEntity implements Serializable {
private static final long serialVersionUID = 7857933536111031118L;
}
\ No newline at end of file
package cn.quant.baa.pay.jpa.entity;
import cn.quant.baa.pay.dict.DictType;
import cn.quant.spring.data.jpa.entity.OptimisticEntity;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
......@@ -14,7 +15,7 @@ import java.util.Objects;
*/
@Entity
@Table(name = "dictionary")
public class DictionaryEntity extends AuditedOptimisticEntity implements Serializable {
public class DictionaryEntity extends OptimisticEntity implements Serializable {
@EmbeddedId
private DictionaryIds ids;
......
package cn.quant.baa.pay.jpa.entity;
import cn.quant.baa.pay.context.TransactionSession;
import cn.quant.baa.pay.dict.*;
import cn.quant.baa.pay.model.MerchantAcquirerProfile;
import cn.quant.baa.pay.model.PayRequestData;
import cn.quant.spring.util.DateUtils;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
import static cn.quant.baa.pay.Constant.MINI_LOCAL_DATE;
/**
* Created by Administrator on 2021/8/27 0027.
*/
public class EntityBuilder {
public static AccountEntity account(AccountIds ids, String productId, long accountId, String buyerId, int partitionKey) {
LocalDate now = LocalDate.now();
AccountEntity account = new AccountEntity();
account.setIds(ids);
account.setAccountId(accountId);
account.setAcctTypeId(AcctTypeId.EMPS);
account.setAutoPaymentFlag(false);
account.setAutoPaymentWarnDate(MINI_LOCAL_DATE);
account.setAutoStatus(StatusCode.NORM);
account.setAutoStatusDate(now);
account.setCorpotateAcctFlag(false);
account.setCreditTxnCount(0);
account.setCurrencyCode(CurrencyCode.CNY);
account.setCurrentCycleNo(1);
account.setDebitTxtCount(0);
account.setExternalAcctNo(buyerId);
account.setManualStatus(null);
account.setManualStatusDate(null);
account.setNextTxnNo(1);
account.setOpenDate(now);
account.setProductId(productId);
account.setProtocolRule(null);
account.setTotalCredit(BigDecimal.ZERO);
account.setTotalDebit(BigDecimal.ZERO);
account.setTxnNo(0);
Date date = DateUtils.now();
account.setCreatedDate(date);
account.setModifiedDate(date);
account.setPartitionKey(partitionKey);
return account;
}
public static PayHistoryEntity history(MerchantAcquirerProfile profile, AccountEntity account, PayHistoryIds ids, PayRequestData data
, TransactionSession session) {
BigDecimal discount = new BigDecimal(data.getDiscounts());
BigDecimal origAmt = new BigDecimal(data.getOriginalAmount());
BigDecimal cash = new BigDecimal(data.getCashAmount());
BigDecimal credit = new BigDecimal(data.getCreditAmount());
BigDecimal amount = new BigDecimal(data.getAmount());
String signer = data.getGoodsSigner();
Long accountId = account.getAccountId();
PayHistoryEntity entity = new PayHistoryEntity();
entity.setIds(ids);
entity.setAccountId(accountId);
entity.setAddress(data.getAddress());
entity.setAttachText(data.getAttach());
entity.setCreditDebitFlag(CreditDebitFlag.C);
entity.setCurrencyCode(CurrencyCode.CNY);
entity.setCustomerGenFlag(true);
entity.setDiscAmount(discount);
entity.setGenFeeAmount(BigDecimal.ZERO);
entity.setGoodsSigner(signer);
entity.setShopName(data.getShopName());
entity.setMobilePhone(data.getPhoneNo());
entity.setNotifyUrl(data.getNotifyUrl());
entity.setOriginalTxnAmount(origAmt);
entity.setPayAcctId(profile.getPayAcctId());
entity.setPayChanCode(profile.getPayChanCode());
entity.setPayAppId(profile.getPayAppId());
entity.setPayMethod(PayMethod.DRST);
entity.setPostCashAmount(cash);
entity.setPostCreditAmount(credit);
entity.setPartitionKey(session.partitionKey(accountId));
entity.setRequestId(session.getRequestId());
entity.setRequestTime(session.getRequestTime());
entity.setShopName(data.getShopName());
entity.setStatementeFlag(true);
entity.setStatisticsCode("RPAY");
entity.setStatusCode(StatusCode.PEND);
entity.setSubject(data.getSubject());
entity.setTransactionId(session.nextId());
entity.setTxnAmount(amount);
entity.setTxnDate(session.getBusinessLocalDate());
entity.setTxnTime(session.getBusinessLocalTime());
entity.setTxnTypeCode("RETL");
if (cash.compareTo(BigDecimal.ZERO) > 0) {
entity.setTxnCode("R001");
} else {
entity.setTxnCode("R002");
}
if (cash.add(credit).compareTo(cash.max(credit)) > 0) {
entity.setTxnCode("R003");
}
return entity;
}
}
package cn.quant.baa.pay.jpa.entity;
import cn.quant.baa.pay.dict.AccessCode;
import cn.quant.spring.data.jpa.entity.DescriptionEntity;
import cn.quant.spring.util.StringUtils;
import javax.persistence.*;
......@@ -12,7 +13,7 @@ import java.util.Objects;
*/
@Entity
@Table(name = "mch_channel")
public class MchChannelEntity extends AuditedDescriptionEntity implements Serializable {
public class MchChannelEntity extends DescriptionEntity implements Serializable {
private static final long serialVersionUID = 2948677889658286512L;
private final static String CLASS_NAME = MchChannelEntity.class.getSimpleName();
......
package cn.quant.baa.pay.jpa.entity;
import cn.quant.spring.data.jpa.entity.OptimisticEntity;
import cn.quant.spring.util.StringUtils;
import org.hibernate.annotations.Type;
......@@ -17,7 +18,7 @@ import java.util.Objects;
*/
@Entity
@Table(name = "pay_app")
public class PayAppEntity extends AuditedOptimisticEntity implements Serializable {
public class PayAppEntity extends OptimisticEntity implements Serializable {
private static final long serialVersionUID = -5502377854231068271L;
......
package cn.quant.baa.pay.jpa.entity;
import cn.quant.baa.pay.dict.AccessType;
import cn.quant.spring.data.jpa.entity.DescriptionEntity;
import javax.persistence.*;
import java.io.Serializable;
......@@ -11,7 +12,7 @@ import java.util.Objects;
*/
@Entity
@Table(name = "pay_feature")
public class PayFeatureEntity extends AuditedDescriptionEntity implements Serializable {
public class PayFeatureEntity extends DescriptionEntity implements Serializable {
private static final long serialVersionUID = -3977191384143230391L;
......
package cn.quant.baa.pay.jpa.entity;
import cn.quant.baa.pay.dict.CreditDebitFlag;
import cn.quant.baa.pay.dict.CurrencyCode;
import cn.quant.baa.pay.dict.PayMethod;
import cn.quant.baa.pay.dict.StatusCode;
import cn.quant.spring.data.jpa.entity.DescribablePartitionEntity;
import org.hibernate.annotations.Type;
import javax.persistence.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Date;
......@@ -14,7 +20,7 @@ import java.util.Objects;
*/
@Entity
@Table(name = "pay_history")
public class PayHistoryEntity extends AuditedDescriptionEntity implements Serializable{
public class PayHistoryEntity extends DescribablePartitionEntity implements Serializable{
private static final long serialVersionUID = 6297586921507136281L;
@EmbeddedId
......@@ -35,17 +41,20 @@ public class PayHistoryEntity extends AuditedDescriptionEntity implements Serial
@Column(name = "PAY_ACCT_ID", nullable = false, updatable = false, length = 4)
private String payAcctId;
@Column(name = "STATUS_CODE", nullable = false, length = 4)
private String statusCode;
@Column(name = "SUBJECT", nullable = false, updatable = false, length = 128)
private String subject;
@Column(name = "TXN_UUID", nullable = false, updatable = false, length = 64)
private String txnUuid;
@Enumerated(EnumType.STRING)
@Column(name = "STATUS_CODE", nullable = false, length = 4)
private StatusCode statusCode;
@Enumerated(EnumType.STRING)
@Column(name = "CURRENCY_CODE", nullable = false, updatable = false, length = 3)
private String currencyCode;
private CurrencyCode currencyCode;
@Enumerated(EnumType.STRING)
@Column(name = "PAY_METHOD", nullable = false, updatable = false, length = 4)
private String payMethod;
private PayMethod payMethod;
@Column(name = "TXN_TYPE_CODE", nullable = false, updatable = false, length = 4)
private String txnTypeCode;
......@@ -56,9 +65,11 @@ public class PayHistoryEntity extends AuditedDescriptionEntity implements Serial
@Column(name = "STATISTICS_CODE", nullable = false, updatable = false, length = 4)
private String statisticsCode;
@Enumerated(EnumType.STRING)
@Column(name = "CREDIT_DEBIT_FLAG", nullable = false, updatable = false, length = 1)
private String creditDebitFlag;
private CreditDebitFlag creditDebitFlag;
@Type(type = "yes_no")
@Column(name = "CUSTOMER_GEN_FLAG", nullable = false, updatable = false, length = 1)
private Boolean customerGenFlag;
......@@ -68,15 +79,18 @@ public class PayHistoryEntity extends AuditedDescriptionEntity implements Serial
@Column(name = "TXN_AMOUNT", nullable = false, updatable = false, precision = 2)
private BigDecimal txnAmount;
@Column(name = "POSTING_AMOUNT", nullable = false, updatable = false, precision = 2)
private BigDecimal postingAmount;
@Column(name = "DISC_AMOUNT", nullable = false, updatable = false, precision = 2)
private BigDecimal discAmount;
@Column(name = "GEN_FEE_AMOUNT", nullable = false, updatable = false, precision = 2)
private BigDecimal genFeeAmount;
@Column(name = "POST_CASH_AMOUNT", nullable = false, updatable = false, precision = 2)
private BigDecimal postCashAmount;
@Column(name = "POST_CREDIT_AMOUNT", nullable = false, updatable = false, precision = 2)
private BigDecimal postCreditAmount;
@Column(name = "STATEMENTE_FLAG", nullable = false, updatable = false, length = 1)
private Boolean statementeFlag;
......@@ -92,12 +106,18 @@ public class PayHistoryEntity extends AuditedDescriptionEntity implements Serial
@Column(name = "REQUEST_TIME", nullable = false, updatable = false)
private Date requestTime;
@Column(name = "MERCHANT_NAME", nullable = true, length = 255)
private String merchantName;
@Column(name = "SHOP_NAME", nullable = true, length = 255)
private String shopName;
@Column(name = "MOBILE_PHONE", nullable = true, length = 13)
private String mobilePhone;
@Column(name = "GOODS_SIGNER", nullable = true, length = 60)
private String goodsSigner;
@Column(name = "ADDRESS", nullable = true, length = 500)
private String address;
@Column(name = "NOTIFY_URL", nullable = true, length = 1000)
private String notifyUrl;
......@@ -152,35 +172,35 @@ public class PayHistoryEntity extends AuditedDescriptionEntity implements Serial
this.payAcctId = payAcctId;
}
public String getStatusCode() {
return statusCode;
public String getSubject() {
return subject;
}
public void setStatusCode(String statusCode) {
this.statusCode = statusCode;
public void setSubject(String subject) {
this.subject = subject;
}
public String getTxnUuid() {
return txnUuid;
public StatusCode getStatusCode() {
return statusCode;
}
public void setTxnUuid(String txnUuid) {
this.txnUuid = txnUuid;
public void setStatusCode(StatusCode statusCode) {
this.statusCode = statusCode;
}
public String getCurrencyCode() {
public CurrencyCode getCurrencyCode() {
return currencyCode;
}
public void setCurrencyCode(String currencyCode) {
public void setCurrencyCode(CurrencyCode currencyCode) {
this.currencyCode = currencyCode;
}
public String getPayMethod() {
public PayMethod getPayMethod() {
return payMethod;
}
public void setPayMethod(String payMethod) {
public void setPayMethod(PayMethod payMethod) {
this.payMethod = payMethod;
}
......@@ -208,11 +228,11 @@ public class PayHistoryEntity extends AuditedDescriptionEntity implements Serial
this.statisticsCode = statisticsCode;
}
public String getCreditDebitFlag() {
public CreditDebitFlag getCreditDebitFlag() {
return creditDebitFlag;
}
public void setCreditDebitFlag(String creditDebitFlag) {
public void setCreditDebitFlag(CreditDebitFlag creditDebitFlag) {
this.creditDebitFlag = creditDebitFlag;
}
......@@ -240,14 +260,6 @@ public class PayHistoryEntity extends AuditedDescriptionEntity implements Serial
this.txnAmount = txnAmount;
}
public BigDecimal getPostingAmount() {
return postingAmount;
}
public void setPostingAmount(BigDecimal postingAmount) {
this.postingAmount = postingAmount;
}
public BigDecimal getDiscAmount() {
return discAmount;
}
......@@ -264,6 +276,22 @@ public class PayHistoryEntity extends AuditedDescriptionEntity implements Serial
this.genFeeAmount = genFeeAmount;
}
public BigDecimal getPostCashAmount() {
return postCashAmount;
}
public void setPostCashAmount(BigDecimal postCashAmount) {
this.postCashAmount = postCashAmount;
}
public BigDecimal getPostCreditAmount() {
return postCreditAmount;
}
public void setPostCreditAmount(BigDecimal postCreditAmount) {
this.postCreditAmount = postCreditAmount;
}
public Boolean getStatementeFlag() {
return statementeFlag;
}
......@@ -304,12 +332,12 @@ public class PayHistoryEntity extends AuditedDescriptionEntity implements Serial
this.requestTime = requestTime;
}
public String getMerchantName() {
return merchantName;
public String getShopName() {
return shopName;
}
public void setMerchantName(String merchantName) {
this.merchantName = merchantName;
public void setShopName(String merchantName) {
this.shopName = merchantName;
}
public String getMobilePhone() {
......@@ -320,6 +348,22 @@ public class PayHistoryEntity extends AuditedDescriptionEntity implements Serial
this.mobilePhone = mobilePhone;
}
public String getGoodsSigner() {
return goodsSigner;
}
public void setGoodsSigner(String goodsSigner) {
this.goodsSigner = goodsSigner;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getNotifyUrl() {
return notifyUrl;
}
......@@ -358,9 +402,9 @@ public class PayHistoryEntity extends AuditedDescriptionEntity implements Serial
sb.append(", payAppId='").append(payAppId).append('\'');
sb.append(", payChanCode='").append(payChanCode).append('\'');
sb.append(", payAcctId='").append(payAcctId).append('\'');
sb.append(", subject='").append(subject).append('\'');
sb.append(", statusCode='").append(statusCode).append('\'');
sb.append(", txnUuid='").append(txnUuid).append('\'');
sb.append(", currencyCode='").append(currencyCode).append('\'');
sb.append(", currencyCode=").append(currencyCode);
sb.append(", payMethod='").append(payMethod).append('\'');
sb.append(", txnTypeCode='").append(txnTypeCode).append('\'');
sb.append(", txnCode='").append(txnCode).append('\'');
......@@ -369,16 +413,19 @@ public class PayHistoryEntity extends AuditedDescriptionEntity implements Serial
sb.append(", customerGenFlag=").append(customerGenFlag);
sb.append(", originalTxnAmount=").append(originalTxnAmount);
sb.append(", txnAmount=").append(txnAmount);
sb.append(", postingAmount=").append(postingAmount);
sb.append(", discAmount=").append(discAmount);
sb.append(", genFeeAmount=").append(genFeeAmount);
sb.append(", postCashAmount=").append(postCashAmount);
sb.append(", postCreditAmount=").append(postCreditAmount);
sb.append(", statementeFlag=").append(statementeFlag);
sb.append(", txnDate=").append(txnDate);
sb.append(", txnTime=").append(txnTime);
sb.append(", requestId='").append(requestId).append('\'');
sb.append(", requestTime=").append(requestTime);
sb.append(", merchantName='").append(merchantName).append('\'');
sb.append(", shopName='").append(shopName).append('\'');
sb.append(", mobilePhone='").append(mobilePhone).append('\'');
sb.append(", goodsSigner='").append(goodsSigner).append('\'');
sb.append(", address='").append(address).append('\'');
sb.append(", notifyUrl='").append(notifyUrl).append('\'');
sb.append(", attachText='").append(attachText).append('\'');
sb.append(',').append(super.toString());
......
package cn.quant.baa.pay.jpa.repository;
import cn.quant.baa.pay.jpa.entity.PayFeatureEntity;
import cn.quant.baa.pay.jpa.entity.PayFeatureIds;
import cn.quant.baa.pay.jpa.entity.PayHistoryEntity;
import cn.quant.baa.pay.jpa.entity.PayHistoryIds;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* Created by Administrator on 2021/8/22 0022.
*/
@Repository
public interface PayHistoryRepository extends JpaRepository<PayHistoryEntity, PayHistoryIds> {
}
......@@ -14,9 +14,9 @@ import java.util.Locale;
*/
public class AssertUtils {
public static String getMessage(MessageEnum code, Object... args){
public static String getMessage(MessageEnum code, Object... args) {
ServerApplicationContext context = ContextLoader.getCurrentApplicationContext();
return context.getMessage(code.name(), args, Locale.SIMPLIFIED_CHINESE);
return context.getMessage(code.name(), Locale.SIMPLIFIED_CHINESE, args);
}
public static BusinessException exception(MessageEnum code, Object... args) {
......@@ -29,7 +29,7 @@ public class AssertUtils {
public static void throwMessage(MessageEnum code) throws BusinessException {
ServerApplicationContext context = ContextLoader.getCurrentApplicationContext();
throw new BusinessException(code, context.getMessage(code.name(), Locale.SIMPLIFIED_CHINESE));
throw new BusinessException(code, context.getMessage(code.name()));
}
public static void notEmpty(String requestId, Object val, Class cls) {
......@@ -39,14 +39,20 @@ public class AssertUtils {
}
public static void notEmpty(String requestId, Number val, String msg) {
if(StringUtils.isEmpty(val)){
if (StringUtils.isEmpty(val)) {
throw new NullException(msg);
}
}
public static void notEmpty(String requestId, String val, String msg) {
if(StringUtils.isEmpty(val)){
if (StringUtils.isEmpty(val)) {
throw new NullException(msg);
}
}
public static void hasLength(MessageEnum code, String val, int start, int end) {
if (val == null || val.length() < start || val.length() > end) {
throwMessage(code);
}
}
}
package cn.quant.baa.pay;
package cn.quant.baa.pay.model;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
/**
......@@ -12,6 +14,7 @@ public class GoodsDetail implements Serializable{
/**
* 商品ID
*/
@Size(min = 6, max = 64)
private String goodsId;
/**
......@@ -22,7 +25,7 @@ public class GoodsDetail implements Serializable{
/**
* 数量
*/
private Integer quantity;
private String quantity;
/**
* 商品单价
......@@ -61,11 +64,11 @@ public class GoodsDetail implements Serializable{
this.goodsName = goodsName;
}
public Integer getQuantity() {
public String getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
public void setQuantity(String quantity) {
this.quantity = quantity;
}
......
package cn.quant.baa.pay;
package cn.quant.baa.pay.model;
import java.io.Serializable;
import java.util.HashMap;
......
package cn.quant.baa.pay.model;
import cn.quant.baa.pay.MerchantAcquirer;
import cn.quant.baa.pay.MerchantAcquirerBook;
import cn.quant.baa.pay.config.DictionaryViewer;
import cn.quant.baa.pay.dict.DictType;
import cn.quant.spring.UnsupportedException;
......
package cn.quant.baa.pay;
package cn.quant.baa.pay.model;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.Arrays;
......@@ -13,53 +15,80 @@ public class PayRequestData implements Serializable{
/**
* 订单标题
*/
@Size(max = 128, message = "ILLEGAL_REQ_SUBJECT")
private String subject;
/**
* 商户ID
*/
@NotNull(message = "ILLEGAL_REQ_MCH_ID")
private String mchId;
/**
* 支付通道ID
*/
@NotNull(message = "ILLEGAL_REQ_CHAN_ID")
private String chanId;
/**
* 商户订单号
*/
@Size(min = 6, max = 64, message = "ILLEGAL_REQ_OUT_TRADE_NO")
@NotNull(message = "ILLEGAL_REQ_OUT_TRADE_NO")
private String outTradeNo;
/**
* 原订单金额
*/
@NotNull(message = "ILLEGAL_REQ_ORIG_AMT")
private String originalAmount;
/**
*实际订单金额
*/
@NotNull(message = "ILLEGAL_REQ_AMT")
private String amount;
/**
* 优惠金额
*/
@NotNull(message = "ILLEGAL_REQ_DISC_AMT")
private String discounts;
/**
* 通知地址
* 现金金额
*/
private String notifyUrl;
@NotNull(message = "ILLEGAL_REQ_CASH_AMT")
private String cashAmount;
/**
* 用信金额
*/
@NotNull(message = "ILLEGAL_REQ_CREDIT_AMT")
private String creditAmount;
/**
*买家ID
*/
@Size(min = 6, max = 32, message ="ILLEGAL_REQ_BUYER_ID" )
@NotNull(message = "ILLEGAL_REQ_BUYER_ID")
private String buyerId;
/**
* 通知地址
*/
private String notifyUrl;
/**
* 附加信息
*/
private String attach;
/**
* 店铺名
*/
private String shopName;
/**
* 收货人名称
*/
......@@ -136,6 +165,22 @@ public class PayRequestData implements Serializable{
this.discounts = discounts;
}
public String getCashAmount() {
return cashAmount;
}
public void setCashAmount(String cashAmount) {
this.cashAmount = cashAmount;
}
public String getCreditAmount() {
return creditAmount;
}
public void setCreditAmount(String creditAmount) {
this.creditAmount = creditAmount;
}
public String getNotifyUrl() {
return notifyUrl;
}
......@@ -160,6 +205,14 @@ public class PayRequestData implements Serializable{
this.attach = attach;
}
public String getShopName() {
return shopName;
}
public void setShopName(String shopName) {
this.shopName = shopName;
}
public String getGoodsSigner() {
return goodsSigner;
}
......@@ -202,9 +255,12 @@ public class PayRequestData implements Serializable{
sb.append(", originalAmount='").append(originalAmount).append('\'');
sb.append(", amount='").append(amount).append('\'');
sb.append(", discounts='").append(discounts).append('\'');
sb.append(", notifyUrl='").append(notifyUrl).append('\'');
sb.append(", cashAmount='").append(cashAmount).append('\'');
sb.append(", creditAmount='").append(creditAmount).append('\'');
sb.append(", buyerId='").append(buyerId).append('\'');
sb.append(", notifyUrl='").append(notifyUrl).append('\'');
sb.append(", attach='").append(attach).append('\'');
sb.append(", shopName='").append(shopName).append('\'');
sb.append(", goodsSigner='").append(goodsSigner).append('\'');
sb.append(", phoneNo='").append(phoneNo).append('\'');
sb.append(", address='").append(address).append('\'');
......
......@@ -7,6 +7,7 @@ import cn.quant.baa.pay.dict.CurrencyCode;
import cn.quant.baa.pay.dict.StatusCode;
import cn.quant.baa.pay.jpa.entity.AccountEntity;
import cn.quant.baa.pay.jpa.entity.AccountIds;
import cn.quant.baa.pay.jpa.entity.EntityBuilder;
import cn.quant.baa.pay.jpa.repository.AccountRepository;
import cn.quant.baa.pay.model.AssertUtils;
import cn.quant.spring.NullException;
......@@ -33,65 +34,24 @@ public abstract class BusinessService {
private static final Logger logger = LoggerFactory.getLogger(BusinessService.class);
@Autowired
private Sequencer sequencer;
public void prepare(String institutionId, String productId, String buyerId, TransactionSession session) {
public TransactionSession prepare(String institutionId, String productId, String buyerId, TransactionSession session) {
if (session == null) {
throw new NullException("Session is null.");
}
if (StringUtils.isEmpty(institutionId)) {
AssertUtils.throwMessage(INSTITUTION_ID_ILLEGAL);
}
if (StringUtils.isEmpty(productId)) {
AssertUtils.throwMessage(PRODUCT_ID_ILLEGAL);
}
if (StringUtils.isEmpty(buyerId)) {
AssertUtils.throwMessage(BUYER_ID_ILLEGAL);
}
AccountIds ids = new AccountIds();
ids.setInstitutionId(institutionId);
ids.setAccountRefNo(buyerId);
AccountEntity account = session.findOne(AccountEntity.class, ids);
if (account == null) {
Long id = sequencer.nextId(buyerId.hashCode());
LocalDate now = LocalDate.now();
account = new AccountEntity();
account.setIds(ids);
account.setAccountId(id);
account.setAcctTypeId(AcctTypeId.EMPS);
account.setAutoPaymentFlag(false);
account.setAutoPaymentWarnDate(MINI_LOCAL_DATE);
account.setAutoStatus(StatusCode.NORM);
account.setAutoStatusDate(now);
account.setCorpotateAcctFlag(false);
account.setCreditTxnCount(0);
account.setCurrencyCode(CurrencyCode.CNY);
account.setCurrentCycleNo(1);
account.setDebitTxtCount(0);
account.setExternalAcctNo(buyerId);
account.setManualStatus(null);
account.setManualStatusDate(null);
account.setNextTxnNo(1);
account.setOpenDate(now);
account.setProductId(productId);
account.setProtocolRule(null);
account.setTotalCredit(BigDecimal.ZERO);
account.setTotalDebit(BigDecimal.ZERO);
account.setTxnNo(0);
Date date = DateUtils.now();
account.setCreatedDate(date);
account.setModifiedDate(date);
account.setPartitionKey(sequencer.getPartitionKey(id));
Long id = session.nextId(buyerId.hashCode());
account = EntityBuilder.account(ids, productId, id, buyerId, session.partitionKey(id));
session.pushEntity(account);
}
session.setAccount(account);
return session;
}
}
package cn.quant.baa.pay.service;
import cn.quant.baa.pay.MerchantChannelRequestData;
import cn.quant.baa.pay.model.MerchantChannelRequestData;
import cn.quant.baa.pay.config.MerchantAcquirerBuilder;
import cn.quant.baa.pay.MerchantAcquirer;
import cn.quant.baa.pay.MerchantAcquirerBook;
import cn.quant.baa.pay.model.MerchantAcquirer;
import cn.quant.baa.pay.model.MerchantAcquirerBook;
import cn.quant.baa.pay.model.MerchantAcquirerProfile;
import cn.quant.baa.pay.model.ModelBuilder;
import cn.quant.spring.util.StringUtils;
......
package cn.quant.baa.pay.service;
import cn.quant.baa.pay.PayRequestData;
import cn.quant.baa.pay.config.MerchantAcquirerBuilder;
import cn.quant.baa.pay.context.TransactionSession;
import cn.quant.baa.pay.jpa.entity.AccountEntity;
import cn.quant.baa.pay.jpa.entity.EntityBuilder;
import cn.quant.baa.pay.jpa.entity.PayHistoryEntity;
import cn.quant.baa.pay.jpa.entity.PayHistoryIds;
import cn.quant.baa.pay.model.AssertUtils;
import cn.quant.baa.pay.model.GoodsDetail;
import cn.quant.baa.pay.model.MerchantAcquirerProfile;
import cn.quant.spring.util.StringUtils;
import cn.quant.baa.pay.model.PayRequestData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import static cn.quant.baa.pay.dict.MessageEnum.*;
......@@ -22,46 +27,55 @@ public class TransactionService extends BusinessService {
private static final Logger logger = LoggerFactory.getLogger(TransactionService.class);
@Autowired
private MerchantAcquirerBuilder merchantAcquirerBuilder;
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void check(PayHistoryIds ids, TransactionSession session) {
PayHistoryEntity historyEntity = session.findOne(PayHistoryEntity.class, ids);
if (historyEntity != null) {
AssertUtils.throwMessage(EXIST_ORDER, ids.getInstitutionId(), ids.getProductId(), ids.getExternalOrderNo());
}
}
@Transactional
public void pay(PayRequestData data) {
if (data == null) {
AssertUtils.throwMessage(EMPTY_REQ_DATA);
}
String chanId = data.getChanId();
if (StringUtils.isEmpty(chanId)) {
AssertUtils.throwMessage(CHAN_ID_ILLEGAL);
}
String mchId = data.getMchId();
if (StringUtils.isEmpty(mchId)) {
AssertUtils.throwMessage(MCH_ID_ILLEGAL);
}
MerchantAcquirerProfile profile = merchantAcquirerBuilder.get(Long.valueOf(chanId));
if (profile == null) {
AssertUtils.throwMessage(ACQUIRER_NOSUCH);
AssertUtils.throwMessage(ACQUIRER_NOSUCH, chanId);
}
String mchId = data.getMchId();
if (!mchId.equals(profile.getPayAppId())) {
AssertUtils.throwMessage(ACQUIRER_NOMATCH);
AssertUtils.throwMessage(ACQUIRER_NOMATCH, chanId, mchId);
}
TransactionSession session = TransactionSession.session();
String institutionId = profile.getInstitutionId();
String productId = profile.getProductId();
TransactionSession session = TransactionSession.session();
String buyerId = StringUtils.trimAllWhitespace(data.getBuyerId());
if (StringUtils.isEmpty(buyerId)) {
AssertUtils.throwMessage(BUYER_ID_ILLEGAL);
}
String outTradeNo = data.getOutTradeNo();
PayHistoryIds ids = new PayHistoryIds();
ids.setInstitutionId(institutionId);
ids.setProductId(productId);
ids.setExternalOrderNo(outTradeNo);
check(ids, session);
GoodsDetail[] goodsDetail = data.getGoodsDetail();
String buyerId = data.getBuyerId();
prepare(institutionId, productId, buyerId, session);
AccountEntity account = session.getAccount();
System.currentTimeMillis();
PayHistoryEntity history = EntityBuilder.history(profile, account, ids, data, session);
session.pushEntity(history);
session.commit();
......
......@@ -30,7 +30,7 @@ public class ExceptionAdvice {
@ResponseBody
public HttpResponseData handlerException(HttpServletRequest request, Exception e) {
log.error("Exception url:{}, error:{}", request.getRequestURI(), e);
log.error("!!- Exception request url - {} ", request.getRequestURI(), e);
String message = e.getMessage();
HttpResponseData responseData = new HttpResponseData(e);
......
......@@ -22,6 +22,9 @@
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<project.logging.path>./</project.logging.path>
</properties>
</profile>
</profiles>
......
package cn.quant.baa.pay.rest;
import cn.quant.baa.pay.model.AssertUtils;
import cn.quant.spring.IllegalParameterException;
import cn.quant.spring.NullException;
import cn.quant.spring.context.ContextLoader;
import cn.quant.spring.context.ServerApplicationContext;
import cn.quant.spring.rest.AbstractController;
import org.springframework.beans.factory.annotation.Autowired;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.util.Set;
import static cn.quant.baa.pay.dict.MessageEnum.EMPTY_REQ_DATA;
/**
* Created by Administrator on 2021/8/28 0028.
*/
public abstract class BusinessController extends AbstractController {
@Autowired
private Validator validator;
public <T> void validate(T t) {
if (t == null) {
throw new NullException();
}
Set<ConstraintViolation<T>> validate = validator.validate(t);
if (validate.size() > 0) {
ConstraintViolation<T> next = validate.iterator().next();
String s = next.getPropertyPath().toString();
String template = next.getMessageTemplate();
ServerApplicationContext applicationContext = ContextLoader.getCurrentApplicationContext();
String message = applicationContext.getMessage(template, "{0}-Illegal request parameter", (Object) s);
throw new IllegalParameterException(message);
}
}
}
package cn.quant.baa.pay.rest;
import cn.quant.baa.pay.MerchantAcquirer;
import cn.quant.baa.pay.MerchantAcquirerBook;
import cn.quant.baa.pay.MerchantChannelRequestData;
import cn.quant.baa.pay.model.MerchantAcquirer;
import cn.quant.baa.pay.model.MerchantAcquirerBook;
import cn.quant.baa.pay.model.MerchantChannelRequestData;
import cn.quant.baa.pay.annotation.BusinessMapping;
import cn.quant.baa.pay.context.TransactionSession;
import cn.quant.baa.pay.model.AssertUtils;
......@@ -45,10 +45,6 @@ public class MerchantController extends AbstractController {
AssertUtils.throwMessage(EMPTY_REQ_DATA);
}
String mchId = data.getMchId();
if (StringUtils.isEmpty(mchId)) {
AssertUtils.throwMessage(MCH_ID_ILLEGAL);
}
Map<String, MerchantAcquirerBook> channels = merchantService.getChannels(data);
ResponseEntity<HttpResponseData> entity = succeed(session.getRequestId(), channels);
......@@ -67,10 +63,6 @@ public class MerchantController extends AbstractController {
AssertUtils.throwMessage(EMPTY_REQ_DATA);
}
String id = data.getChanId();
if (StringUtils.isEmpty(id)) {
AssertUtils.throwMessage(CHAN_ID_ILLEGAL);
}
MerchantAcquirer channel = merchantService.getChannel(data);
ResponseEntity<HttpResponseData> entity = succeed(session.getRequestId(), channel);
......
package cn.quant.baa.pay.rest;
import cn.quant.baa.pay.PayRequestData;
import cn.quant.baa.pay.annotation.BusinessMapping;
import cn.quant.baa.pay.config.MerchantAcquirerBuilder;
import cn.quant.baa.pay.context.TransactionSession;
import cn.quant.baa.pay.model.AssertUtils;
import cn.quant.baa.pay.model.BusinessRequest;
import cn.quant.baa.pay.model.MerchantAcquirerProfile;
import cn.quant.baa.pay.model.GoodsDetail;
import cn.quant.baa.pay.model.PayRequestData;
import cn.quant.baa.pay.service.TransactionService;
import cn.quant.spring.rest.AbstractController;
import cn.quant.spring.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import static cn.quant.baa.pay.dict.MessageEnum.*;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.util.Set;
/**
* Created by Administrator on 2021/8/24 0024.
*/
@RestController
@RequestMapping("/transaction")
public class TransactionController extends AbstractController {
public class TransactionController extends BusinessController {
@Autowired
private TransactionService transactionService;
......@@ -30,8 +29,9 @@ public class TransactionController extends AbstractController {
@PostMapping("/pay")
public void pay(@RequestBody BusinessRequest<PayRequestData> request) {
PayRequestData data = request.getData();
PayRequestData data = request.getData();
validate(data);
transactionService.pay(data);
......
......@@ -5,6 +5,7 @@ spring.application.name=Application
#Devtool
spring.devtools.restart.enabled=true
spring.devtools.livereload.enabled=true
#Server
server.port=8080
server.servlet.context-path=/
......
......@@ -65,4 +65,8 @@ spring:
view:
prefix: classpath:/view/
suffix: .jsp
static-path-pattern: /**
\ No newline at end of file
static-path-pattern: /**
messages:
basename: messages, i18n/messages, cn.quant.spring/messages
fallback-to-system-locale: true
encoding: UTF-8
\ No newline at end of file
......@@ -21,6 +21,4 @@ spring:
cloud:
task:
initialize:
enable: false
messages:
basename: i18n/messages
\ No newline at end of file
enable: false
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment