From a7e4ea612c4ab32118a796c4ef41a5c589af21c0 Mon Sep 17 00:00:00 2001 From: yupeng <roc__yu@163.com> Date: 星期四, 06 三月 2025 13:54:18 +0800 Subject: [PATCH] feat: 更新创建订单接口,修改金额校验,新增银行查单接口 --- ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TPayOrderServiceImpl.java | 13 bankapi/src/main/java/com/taxi591/bankapi/dto/QueryBillResponse.java | 1027 ++++++++++++++++++++++++++++++++++++++ ruoyi-admin/src/main/resources/application-test.yml | 13 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java | 193 +++++++ bankapi/src/main/java/com/taxi591/bankapi/dto/QueryBillRequest.java | 317 +++++++++++ ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java | 8 ruoyi-applet/src/main/resources/application-test.yml | 2 7 files changed, 1,558 insertions(+), 15 deletions(-) diff --git a/bankapi/src/main/java/com/taxi591/bankapi/dto/QueryBillRequest.java b/bankapi/src/main/java/com/taxi591/bankapi/dto/QueryBillRequest.java new file mode 100644 index 0000000..841bc19 --- /dev/null +++ b/bankapi/src/main/java/com/taxi591/bankapi/dto/QueryBillRequest.java @@ -0,0 +1,317 @@ +package com.taxi591.bankapi.dto; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import java.io.Serializable; + +/** + * 直连商户平台账单查询输入对象,需要转换成json串发送给第三方系统 + * @author DELL + * + */ +@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) +public class QueryBillRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 格式 */ + @JSONField(name = "format") + private String format; + + /** 消息 */ + @JSONField(name = "message") + private Message message; + + @Override + public String toString() { + return "QueryBillRequest[format=" + format + ",message=" + message.toString() + "]"; + } + + public String getFormat() { + return format; + } + + @JSONField(name = "format") + public void setFormat(String format) { + this.format = format; + } + + public Message getMessage() { + return message; + } + + @JSONField(name = "message") + public void setMessage(Message message) { + this.message = message; + } + + /** + * + * 账单查询内部消息对象实体message内部类 + * + */ + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + public class Message implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 消息头部 */ + @JSONField(name = "head") + private Head head; + + /** 消息体 */ + @JSONField(name = "info") + private Info info; + + @Override + public String toString() { + return "QueryBillRequest.Message[head=" + head.toString() + ",info=" + info.toString() + "]"; + } + + public Head getHead() { + return head; + } + + @JSONField(name = "head") + public void setHead(Head head) { + this.head = head; + } + + public Info getInfo() { + return info; + } + + @JSONField(name = "info") + public void setInfo(Info info) { + this.info = info; + } + + /** + * message子对象head消息头内部类 + */ + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + public class Head implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 渠道编码 */ + @JSONField(name = "channel") + private String channel; + + /** 交易码 */ + @JSONField(name = "transCode") + private String transCode; + + /** 交易上行下送标志位 */ + @JSONField(name = "transFlag") + private String transFlag; + + /** 缴费中心交易序列号 */ + @JSONField(name = "transSeqNum") + private String transSeqNum; + + /** 时间戳 */ + @JSONField(name = "timeStamp") + private String timeStamp; + + /** 4为分行iGoal码 */ + @JSONField(name = "branchCode") + private String branchCode; + + @Override + public String toString() { + return "QueryBillRequest.Message.Head[channel=" + channel +",transCode=" + transCode + + ",transFlag=" + transFlag + ",transSeqNum=" + transSeqNum + ",timestamp=" + timeStamp + ",branchCode=" + branchCode + "]"; + } + + public String getChannel() { + return channel; + } + + @JSONField(name = "channel") + public void setChannel(String channel) { + this.channel = channel; + } + + public String getTransFlag() { + return transFlag; + } + + @JSONField(name = "transFlag") + public void setTransFlag(String transFlag) { + this.transFlag = transFlag; + } + + public String getTransCode() { + return transCode; + } + + @JSONField(name = "transCode") + public void setTransCode(String transCode) { + this.transCode = transCode; + } + + public String getTransSeqNum() { + return transSeqNum; + } + + @JSONField(name = "transSeqNum") + public void setTransSeqNum(String transSeqNum) { + this.transSeqNum = transSeqNum; + } + + + public String getTimeStamp() { + return timeStamp; + } + + @JSONField(name = "timeStamp") + public void setTimeStamp(String timeStamp) { + this.timeStamp = timeStamp; + } + + public String getBranchCode() { + return branchCode; + } + + @JSONField(name = "branchCode") + public void setBranchCode(String branchCode) { + this.branchCode = branchCode; + } + } + + /** + * message子对象info消息实体内部类 + */ + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + public class Info implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 缴费项目编号*/ + @JSONField(name = "epayCode") + private String epayCode; + + /** 第三方商户编号*/ + @JSONField(name = "merchantId") + private String merchantId; + + /** 输入要素1*/ + @JSONField(name = "input1") + private String input1; + + /** 输入要素2*/ + @JSONField(name = "input2") + private String input2; + + /** 输入要素3*/ + @JSONField(name = "input3") + private String input3; + + /** 输入要素4*/ + @JSONField(name = "input4") + private String input4; + + /** 输入要素5*/ + @JSONField(name = "input5") + private String input5; + + /** 16位客户号*/ + @JSONField(name = "userId") + private String userId; + + /** 缴费中心流水号*/ + @JSONField(name = "traceNo") + private String traceNo; + + @Override + public String toString() { + return "QueryBillRequest.Message.Info[epayCode=" + epayCode + ",merchantId=" + merchantId + + ",input1=" + input1 + ",input2=" + input2 + ",input3=" + input3 + ",input4=" + input4 + ",input5=" + input5 + + ",userId=" + userId + ",traceNo=" + traceNo + "]"; + } + + public String getEpayCode() { + return epayCode; + } + + @JSONField(name = "epayCode") + public void setEpayCode(String epayCode) { + this.epayCode = epayCode; + } + + public String getMerchantId() { + return merchantId; + } + + @JSONField(name = "merchantId") + public void setMerchantId(String merchantId) { + this.merchantId = merchantId; + } + + public String getInput1() { + return input1; + } + + @JSONField(name = "input1") + public void setInput1(String input1) { + this.input1 = input1; + } + + public String getInput2() { + return input2; + } + + @JSONField(name = "input2") + public void setInput2(String input2) { + this.input2 = input2; + } + + public String getInput3() { + return input3; + } + + @JSONField(name = "input3") + public void setInput3(String input3) { + this.input3 = input3; + } + + public String getInput4() { + return input4; + } + + @JSONField(name = "input4") + public void setInput4(String input4) { + this.input4 = input4; + } + + public String getInput5() { + return input5; + } + + @JSONField(name = "input5") + public void setInput5(String input5) { + this.input5 = input5; + } + + public String getUserId() { + return userId; + } + + @JSONField(name = "userId") + public void setUserId(String userId) { + this.userId = userId; + } + + public String getTraceNo() { + return traceNo; + } + + @JSONField(name = "traceNo") + public void setTraceNo(String traceNo) { + this.traceNo = traceNo; + } + } + } +} \ No newline at end of file diff --git a/bankapi/src/main/java/com/taxi591/bankapi/dto/QueryBillResponse.java b/bankapi/src/main/java/com/taxi591/bankapi/dto/QueryBillResponse.java new file mode 100644 index 0000000..b33c9d1 --- /dev/null +++ b/bankapi/src/main/java/com/taxi591/bankapi/dto/QueryBillResponse.java @@ -0,0 +1,1027 @@ +package com.taxi591.bankapi.dto; + +import com.alibaba.fastjson2.annotation.JSONField; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import java.io.Serializable; +import java.util.ArrayList; + +/** + * 直连商户平台账单查询返回对象 + * @author DELL + * + */ +@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) +public class QueryBillResponse implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 格式 */ + @JSONField(name = "format") + private String format; + + /** 消息体 */ + @JSONField(name = "message") + private Message message; + + + public QueryBillResponse(){ + + } + + /** + * 构造函数,通过输入对象,构造返回对象数据信息 + * @param request + */ + public QueryBillResponse(QueryBillRequest request) { + this.setFormat(request.getFormat()); + this.setMessage(new Message(request.getMessage())); + } + + @Override + public String toString() { + return "QueryBillResponse[format=" + format + ",message=" + message==null?"":message.toString() + "]"; + } + + public String getFormat() { + return format; + } + + @JSONField(name = "format") + public void setFormat(String format) { + this.format = format; + } + + public Message getMessage() { + return message; + } + + @JSONField(name = "message") + public void setMessage(Message message) { + this.message = message; + } + + /** + * + * 账单查询内部消息对象返回实体message内部类 + * + */ + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + public class Message implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 消息头部 */ + @JSONField(name = "head") + private Head head; + + /** 消息实体 */ + @JSONField(name = "info") + private Info info; + + public Message() { + this.head = new Head(); + this.info = new Info(); + } + + public Message(QueryBillRequest.Message requestMessage){ + this.setHead(new Head(requestMessage.getHead())); + this.setInfo(new Info(requestMessage.getInfo())); + } + + @Override + public String toString() { + return "QueryBillResponse.Message[head=" + head.toString() + ",info=" + info.toString() + "]"; + } + + public Head getHead() { + return head; + } + + @JSONField(name = "head") + public void setHead(Head head) { + this.head = head; + } + + public Info getInfo() { + return info; + } + + @JSONField(name = "info") + public void setInfo(Info info) { + this.info = info; + } + + /** + * + * 账单查询内部消息对象返回实体Head内部类 + * + */ + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + public class Head implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 渠道 */ + @JSONField(name = "channel") + private String channel; + + /** 交易码 */ + @JSONField(name = "transCode") + private String transCode; + + /** 交易上行下送标志 */ + @JSONField(name = "transFlag") + private String transFlag; + + /** 缴费中心交易序列号 */ + @JSONField(name = "transSeqNum") + private String transSeqNum; + + /** 时间戳 */ + @JSONField(name = "timeStamp") + private String timeStamp; + + /** 查询返回码 */ + @JSONField(name = "returnCode") + private String returnCode ; + + /** 返回提示信息 */ + @JSONField(name = "returnMessage") + private String returnMessage; + + + public Head(QueryBillRequest.Message.Head reqMessHead) { + this.setChannel(reqMessHead.getChannel()); + this.setTransSeqNum(reqMessHead.getTransSeqNum()); + this.setTransCode(reqMessHead.getTransCode()); + this.setReturnCode(""); + this.setReturnMessage(""); + this.setTimeStamp(""); + } + + + public Head() { + + } + @Override + public String toString() { + return "QueryBillResponse.Message.Head[channel=" + channel + ",transCode=" + transCode + ",transSeqNum=" + transSeqNum + + ",timeStamp=" + timeStamp + ",returnCode=" + returnCode + ",returnMessage=" + returnMessage + "]"; + } + public String getChannel() { + return channel; + } + + public String getTransCode() { + return transCode; + } + + @JSONField(name = "transCode") + public void setTransCode(String transCode) { + this.transCode = transCode; + } + + public String getTransFlag() { + return transFlag; + } + + @JSONField(name = "transFlag") + public void setTransFlag(String transFlag) { + this.transFlag = transFlag; + } + + @JSONField(name = "channel") + public void setChannel(String channel) { + this.channel = channel; + } + + public String getTransSeqNum() { + return transSeqNum; + } + + @JSONField(name = "transSeqNum") + public void setTransSeqNum(String transSeqNum) { + this.transSeqNum = transSeqNum; + } + + + public String getTimeStamp() { + return timeStamp; + } + + @JSONField(name = "timestamp") + public void setTimeStamp(String timeStamp) { + this.timeStamp = timeStamp; + } + + public String getReturnCode() { + return returnCode; + } + + @JSONField(name = "returnCode") + public void setReturnCode(String returnCode) { + this.returnCode = returnCode; + } + + public String getReturnMessage() { + return returnMessage; + } + + @JSONField(name = "returnMessage") + public void setReturnMessage(String returnMessage) { + this.returnMessage = returnMessage; + } + + + } + + /** + * + * 账单查询内部消息对象返回实体Info内部类 + * + */ + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + public class Info implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 缴费项目唯一标识号*/ + @JSONField(name = "epayCode") + private String epayCode; + + /** 直连商户第三方商户号*/ + @JSONField(name = "merchantId") + private String merchantId; + + /** 缴费中心流水号*/ + @JSONField(name = "traceNo") + private String traceNo; + + /** 输入要素1*/ + @JSONField(name = "input1") + private String input1; + + /** 输入要素2*/ + @JSONField(name = "input2") + private String input2; + + /** 输入要素3*/ + @JSONField(name = "input3") + private String input3; + + /** 输入要素4*/ + @JSONField(name = "input4") + private String input4; + + /** 输入要素5*/ + @JSONField(name = "input5") + private String input5; + + /** 户主名称*/ + @JSONField(name = "custName") + private String custName; + + /** 户主地址*/ + @JSONField(name = "custAddress") + private String custAddress; + + /** 账单关联客户手机号,部分项目可根据该字段,要求客户做短信验证码校验后才显示账单结果*/ + @JSONField(name = "cellPhone") + private String cellPhone; + + /** 缓存域信息*/ + @JSONField(name = "cacheMem") + private String cacheMem; + + /** 备注字段*/ + @JSONField(name = "remark") + private String remark; + + /** 跳转商户地址*/ + @JSONField(name = "callBackUrl") + private String callBackUrl; + + /** 跳转商户地址超链接提示*/ + @JSONField(name = "callBackText") + private String callBackText; + + /** 缴费金额计算规则*/ + @JSONField(name = "amtRule") + private String amtRule; + + /** 子账单数量*/ + @JSONField(name = "totalBillCount") + private String totalBillCount; + /** 定制附言信息(有定制电子回单附言信息的,需添加自定义定制附言信息字段)*/ + @JSONField(name = "merchantRemark") + private String merchantRemark; + + /** 账单信息体*/ + @JSONField(name = "bills") + private ArrayList<Bill> bills; + + + public Info() { + + } + public Info(QueryBillRequest.Message.Info reqMessInfo) { + this.setEpayCode(reqMessInfo.getEpayCode()); + this.setInput1(reqMessInfo.getInput1()); + this.setInput2(reqMessInfo.getInput2()); + this.setInput3(reqMessInfo.getInput3()); + this.setInput4(reqMessInfo.getInput4()); + this.setInput5(reqMessInfo.getInput5()); + this.bills = new ArrayList<Bill>(); + } + + /** + * @return the merchantRemark + */ + public String getMerchantRemark() { + return merchantRemark; + } + + /** + * @param merchantRemark the merchantRemark to set + */ + @JSONField(name = "merchantRemark") + public void setMerchantRemark(String merchantRemark) { + this.merchantRemark = merchantRemark; + } + + @Override + public String toString() { + return "QueryBillResponse.Message.Info[epayCode=" + epayCode + ", input1=" + + input1 + ", input2=" + input2 + ", input3=" + input3 + + ", input4=" + input4 + ", input5=" + input5 + + ", totalBillCount=" + totalBillCount + ",merchantRemark=" + + merchantRemark + ", bills=" + bills.toString() + "]"; + } + + public String getEpayCode() { + return epayCode; + } + + @JSONField(name = "epayCode") + public void setEpayCode(String epayCode) { + this.epayCode = epayCode; + } + + public String getMerchantId() { + return merchantId; + } + + @JSONField(name = "merchantId") + public void setMerchantId(String merchantId) { + this.merchantId = merchantId; + } + + public String getTraceNo() { + return traceNo; + } + + @JSONField(name = "traceNo") + public void setTraceNo(String traceNo) { + this.traceNo = traceNo; + } + + public String getInput1() { + return input1; + } + + @JSONField(name = "input1") + public void setInput1(String input1) { + this.input1 = input1; + } + + public String getInput2() { + return input2; + } + + @JSONField(name = "input2") + public void setInput2(String input2) { + this.input2 = input2; + } + + public String getInput3() { + return input3; + } + + @JSONField(name = "input3") + public void setInput3(String input3) { + this.input3 = input3; + } + + public String getInput4() { + return input4; + } + + @JSONField(name = "input4") + public void setInput4(String input4) { + this.input4 = input4; + } + + public String getInput5() { + return input5; + } + + @JSONField(name = "input5") + public void setInput5(String input5) { + this.input5 = input5; + } + + public String getCustName() { + return custName; + } + + @JSONField(name = "custName") + public void setCustName(String custName) { + this.custName = custName; + } + + public String getCustAddress() { + return custAddress; + } + + @JSONField(name = "custAddress") + public void setCustAddress(String custAddress) { + this.custAddress = custAddress; + } + + public String getCellPhone() { + return cellPhone; + } + + @JSONField(name = "cellPhone") + public void setCellPhone(String cellPhone) { + this.cellPhone = cellPhone; + } + + public String getCacheMem() { + return cacheMem; + } + + @JSONField(name = "cacheMem") + public void setCacheMem(String cacheMem) { + this.cacheMem = cacheMem; + } + + public String getRemark() { + return remark; + } + + @JSONField(name = "remark") + public void setRemark(String remark) { + this.remark = remark; + } + + public String getCallBackUrl() { + return callBackUrl; + } + + @JSONField(name = "callBackUrl") + public void setCallBackUrl(String callBackUrl) { + this.callBackUrl = callBackUrl; + } + + public String getCallBackText() { + return callBackText; + } + + @JSONField(name = "callBackText") + public void setCallBackText(String callBackText) { + this.callBackText = callBackText; + } + + public String getAmtRule() { + return amtRule; + } + + @JSONField(name = "amtRule") + public void setAmtRule(String amtRule) { + this.amtRule = amtRule; + } + + public String getTotalBillCount() { + return totalBillCount; + } + + @JSONField(name = "totalBillCount") + public void setTotalBillCount(String totalBillCount) { + this.totalBillCount = totalBillCount; + } + + public ArrayList<Bill> getBills() { + return bills; + } + + /** + * @param bills + * 设置账单循环域子账单 + */ + @JSONField(name = "bills") + public void setBill(ArrayList<Bill> bills) { + this.bills = bills; + } + + + /** + * + * 账单查询内部消息对象返回实体Bill内部类 + * + */ + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + public class Bill implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 账单编号*/ + @JSONField(name = "billNo") + private String billNo; + + /** 账单名称*/ + @JSONField(name = "billName") + private String billName; + + /** 欠费金额*/ + @JSONField(name = "oweAmt") + private String oweAmt; + + /** 手续费*/ + @JSONField(name = "feeAmt") + private String feeAmt; + + /** 最小金额*/ + @JSONField(name = "minAmt") + private String minAmt; + + /** 最大金额*/ + @JSONField(name = "maxAmt") + private String maxAmt; + + /** 余额*/ + @JSONField(name = "balance") + private String balance; + + /** 缴费账单到期日*/ + @JSONField(name = "expireDate") + private String expireDate; + + /** 收款商户号*/ + @JSONField(name = "rcvMerchantId") + private String rcvMerchantId; + + /** 收款账号*/ + @JSONField(name = "rcvAcc") + private String rcvAcc; + + /** 分账模板号*/ + @JSONField(name = "tempSplitAcc") + private String tempSplitAcc; + + /** 均匀时段缴费 */ + @JSONField(name = "unitDetail") + private UnitDetail unitDetail; + + /** 选择套餐*/ + @JSONField(name = "optionDetails") + private ArrayList<OptionDetail> optionDetails; + + /** 账单详情描述*/ + @JSONField(name = "descDetails") + private ArrayList<DescDetail> descDetails; + /** 平台商户分账子商户循环域 */ + @JSONField(name = "splitSubMerInfos") + private ArrayList<SplitSubMerInfo> splitSubMerInfos; + + /** 子账单必缴标志,多账单合并支付时默认选中不可不选 true:必选 false:非必选 */ + @JSONField(name = "mustPayFlag") + private String mustPayFlag; + + + /** + * @return + */ + public String getMustPayFlag() { + return mustPayFlag; + } + + /** + * @param mustPayFlag + */ + @JSONField(name = "mustPayFlag") + public void setMustPayFlag(String mustPayFlag) { + this.mustPayFlag = mustPayFlag; + } + + /** + * @return + */ + public String getTempSplitAcc() { + return tempSplitAcc; + } + /** + * 获取平台商户分账子商户循环域信息 + * @return + */ + public ArrayList<SplitSubMerInfo> getSplitSubMerInfos() { + return splitSubMerInfos; + } + /** + * 设置平台商户分账子商户循环域信息 + * @param splitSubMerInfos + */ + @JSONField(name = "splitSubMerInfos") + public void setSplitSubMerInfos(ArrayList<SplitSubMerInfo> splitSubMerInfos) { + this.splitSubMerInfos = splitSubMerInfos; + } + + public Bill() { + + } + + @Override + public String toString() { + return "Bill [billNo=" + billNo + ", billName=" + billName + + ", oweAmt=" + oweAmt + ", feeAmt=" + feeAmt + + ", minAmt=" + minAmt + ", maxAmt=" + maxAmt + + ", balance=" + balance + ", expireDate=" + + expireDate + ", rcvMerchantId=" + rcvMerchantId + + ", rcvAcc=" + rcvAcc + ", tempSplitAcc=" + + tempSplitAcc + ", unitDetail=" + unitDetail + + ", optionDetails=" + optionDetails + + ", descDetails=" + descDetails + + ", splitSubMerInfos=" + splitSubMerInfos + + ", mustPayFlag=" + mustPayFlag + "]"; + } + + public String getBillNo() { + return billNo; + } + + @JSONField(name = "billNo") + public void setBillNo(String billNo) { + this.billNo = billNo; + } + + public String getBillName() { + return billName; + } + + @JSONField(name = "billName") + public void setBillName(String billName) { + this.billName = billName; + } + + public String getOweAmt() { + return oweAmt; + } + + @JSONField(name = "oweAmt") + public void setOweAmt(String oweAmt) { + this.oweAmt = oweAmt; + } + + public String getFeeAmt() { + return feeAmt; + } + + @JSONField(name = "feeAmt") + public void setFeeAmt(String feeAmt) { + this.feeAmt = feeAmt; + } + + public String getMinAmt() { + return minAmt; + } + + @JSONField(name = "minAmt") + public void setMinAmt(String minAmt) { + this.minAmt = minAmt; + } + + public String getMaxAmt() { + return maxAmt; + } + + @JSONField(name = "maxAmt") + public void setMaxAmt(String maxAmt) { + this.maxAmt = maxAmt; + } + + public String getBalance() { + return balance; + } + @JSONField(name = "balance") + public void setBalance(String balance) { + this.balance = balance; + } + + public String getExpireDate() { + return expireDate; + } + @JSONField(name = "expireDate") + public void setExpireDate(String expireDate) { + this.expireDate = expireDate; + } + + public String getRcvMerchantId() { + return rcvMerchantId; + } + @JSONField(name = "rcvMerchantId") + public void setRcvMerchantId(String rcvMerchantId) { + this.rcvMerchantId = rcvMerchantId; + } + + public String getRcvAcc() { + return rcvAcc; + } + @JSONField(name = "rcvAcc") + public void setRcvAcc(String rcvAcc) { + this.rcvAcc = rcvAcc; + } + + /** + * 分账模板号 + * @return + */ + public String getTmpSplitAcc() { + return tempSplitAcc; + } + @JSONField(name = "tempSplitAcc") + public void setTempSplitAcc(String tempSplitAcc) { + this.tempSplitAcc = tempSplitAcc; + } + + public UnitDetail getUnitDetail() { + return unitDetail; + } + @JSONField(name = "unitDetail") + public void setUnitDetail(UnitDetail unitDetail) { + this.unitDetail = unitDetail; + } + + public ArrayList<DescDetail> getDescDetails() { + return descDetails; + } + /** + * 设置账单描述详情键值对 + * @param feeDetails + */ + @JSONField(name = "descDetails") + public void setDescDetails(ArrayList<DescDetail> descDetails) { + this.descDetails = descDetails; + } + + public ArrayList<OptionDetail> getOptionDetails() { + return optionDetails; + } + @JSONField(name = "optionDetails") + public void setOptionDetails(ArrayList<OptionDetail> optionDetails) { + this.optionDetails = optionDetails; + } + + /** + * 均匀时段 + * + * @date 2017年12月21日 + */ + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + public class UnitDetail implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 单位名称 */ + @JSONField(name = "unitName") + private String unitName; + + /** 单位金额 */ + @JSONField(name = "unitAmount") + private String unitAmount; + + /** 最小单位数量 */ + @JSONField(name = "minUnitNum") + private String minUnitNum; + public UnitDetail(){} + + public UnitDetail(String unitName, String unitAmount, String minUnitNum) { + super(); + this.unitName = unitName; + this.unitAmount = unitAmount; + this.minUnitNum = minUnitNum; + } + public String getUnitName() { + return unitName; + } + + @JSONField(name = "unitAmount") + public void setUnitName(String unitName) { + this.unitName = unitName; + } + + public String getUnitAmount() { + return unitAmount; + } + + @JSONField(name = "unitAmount") + public void setUnitAmount(String unitAmount) { + this.unitAmount = unitAmount; + } + + public String getMinUnitNum() { + return minUnitNum; + } + + @JSONField(name = "minUnitNum") + public void setMinUnitNum(String minUnitNum) { + this.minUnitNum = minUnitNum; + } + + @Override + public String toString() { + return "QueryBillResponse.Message.Info.Bill.unitDetail[unitName=" + unitName + + ", unitAmount=" + unitAmount + ", minUnitNum=" + minUnitNum + "]"; + } + } + + /** + * @title 选择套餐循环 + * + * @date 2017-12-18 + * + * + */ + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + public class OptionDetail implements Serializable { + + private static final long serialVersionUID = 1L; + + /**套餐编号 根据编号排序*/ + @JSONField(name = "optionCode") + private String optionCode; + + /**套餐名称*/ + @JSONField(name = "optionName") + private String optionName; + + /**套餐金额*/ + @JSONField(name = "optionAmt") + private String optionAmt; + + public OptionDetail(){ + + } + + public OptionDetail(String optionCode, String optionName, String optionAmt) { + super(); + this.optionCode = optionCode; + this.optionName = optionName; + this.optionAmt = optionAmt; + } + + public String getOptionCode() { + return optionCode; + } + + @JSONField(name = "optionCode") + public void setOptionCode(String optionCode) { + this.optionCode = optionCode; + } + + public String getOptionName() { + return optionName; + } + + @JSONField(name = "optionName") + public void setOptionName(String optionName) { + this.optionName = optionName; + } + + public String getOptionAmt() { + return optionAmt; + } + @JSONField(name = "optionAmt") + public void setOptionAmt(String optionAmt) { + this.optionAmt = optionAmt; + } + + @Override + public String toString() { + return "QueryBillResponse.Message.Info.Bill.OptionDetail[optionCode=" + optionCode + + ", optionName=" + optionName + ", optionAmt=" + optionAmt + "]"; + } + + } + /** + * @title 账单详情 + * + * @date 2017-12-18 + */ + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + public class DescDetail implements Serializable { + + private static final long serialVersionUID = 1L; + + /**账单详情-名称*/ + @JSONField(name = "sCpt") + private String sCpt; + + /**账单详情-取值*/ + @JSONField(name = "sVal") + private String sVal; + + + public DescDetail(){ + + } + + public DescDetail(String sCpt, String sVal) { + super(); + this.sCpt = sCpt; + this.sVal = sVal; + } + + public String getSCpt() { + return sCpt; + } + + @JSONField(name = "sCpt") + public void setSCpt(String sCpt) { + this.sCpt = sCpt; + } + + public String getSVal() { + return sVal; + } + + @JSONField(name = "sVal") + public void setSVal(String sVal) { + this.sVal = sVal; + } + + @Override + public String toString() { + return "QueryBillResponse.Message.Info.Bill.FeeDetail[sCpt=" + sCpt + ",sVal=" + sVal + "]"; + } + } + /** + * @title 平台商户分账子商户循环域 + * + * @date 2020-10-22 + * + * @author marui + */ + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + public class SplitSubMerInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + /**二级子商户号*/ + @JSONField(name = "splitMerchantId") + private String splitMerchantId; + + /**二级子商户分账金额*/ + @JSONField(name = "splitAmount") + private String splitAmount; + + + public SplitSubMerInfo(){ + + } + + public SplitSubMerInfo(String splitMerchantId, String splitAmount) { + super(); + this.splitMerchantId = splitMerchantId; + this.splitAmount = splitAmount; + } + + public String getSplitMerchantId() { + return splitMerchantId; + } + + @JSONField(name = "splitMerchantId") + public void setSplitMerchantId(String splitMerchantId) { + this.splitMerchantId = splitMerchantId; + } + + public String getSplitAmount() { + return splitAmount; + } + + @JSONField(name = "splitAmount") + public void setSplitAmount(String splitAmount) { + this.splitAmount = splitAmount; + } + + + @Override + public String toString() { + return "QueryBillResponse.Message.Info.Bill.SplitSubMerInfo[splitMerchantId=" + splitMerchantId + + ", splitAmount=" + splitAmount + "]"; + } + } + } + } + } +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java index bcb7af3..fd0274e 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java @@ -1,8 +1,23 @@ package com.ruoyi.web.controller.api; +import cn.hutool.core.date.DateUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.ruoyi.common.constant.AmountConstant; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.dto.TBillDto; +import com.ruoyi.system.model.TOrderBill; +import com.ruoyi.system.model.TPayOrder; import com.ruoyi.system.service.TBillService; +import com.ruoyi.system.service.TOrderBillService; +import com.ruoyi.system.service.TPayOrderService; import com.taxi591.bankapi.dto.CovertPayBackResult; +import com.taxi591.bankapi.dto.QueryBillRequest; +import com.taxi591.bankapi.dto.QueryBillResponse; import com.taxi591.bankapi.service.BankService; +import com.taxi591.bankapi.service.SignatureAndVerification; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.binary.Base64; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -10,9 +25,16 @@ import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; @RestController @RequestMapping("open/bank") +@Slf4j public class BankOutController { @Autowired @@ -20,6 +42,16 @@ @Autowired TBillService tBillService; + + @Autowired + SignatureAndVerification signatureAndVerification; + + @Autowired + TOrderBillService orderBillService; + + @Autowired + TPayOrderService payOrderService; + @PostMapping(value = "payCallback") public @ResponseBody String payCallback(HttpServletRequest request){ CovertPayBackResult result = bankService.covertPayCallBack(request, (billRequest) -> { @@ -29,9 +61,164 @@ return result.getBack(); } - @PostMapping(value = "bills") - public @ResponseBody String bills(HttpServletRequest request){ - return ""; + @PostMapping(value = "queryBill") + public void bills(HttpServletRequest request, HttpServletResponse httpServletResponse){ + log.info("进入QueryBillController账单查询接口--------(金额规则为0的)-------"); + + String responseJson = null; + try { + //接收报文request返回截取并返回requestBody和使用base64解析后的requestBody + Map<String, String> requestMap = signatureAndVerification.requestBodyOfBase64(request); + //使用base64解析完成后的requestBody + String requestBodyOfDecoded = requestMap.get("requestBodyOfDecoded"); + //解析前的requestBody + String requestBody = requestMap.get("requestBody"); + //获取缴费中心传送过来的签名 + String signatureString = requestMap.get("signatureString"); + + // 验签 + boolean flag = signatureAndVerification.read_cer_and_verify_sign(requestBody, + signatureString); + + log.info("【QueryBill:getBill4DirectJoinMerch】缴费中心响应的报文验签结果为:{}" , flag); + + QueryBillRequest queryBillRequest = JSON.parseObject(requestBodyOfDecoded, + new TypeReference<QueryBillRequest>() { + }); + //交易编号 + String traceNo = queryBillRequest.getMessage().getInfo() + .getTraceNo(); + //返回给缴费中心的响应 + QueryBillResponse response = new QueryBillResponse(queryBillRequest); + QueryBillResponse.Message respMessage = response.getMessage(); + QueryBillResponse.Message.Head respHead = response.getMessage() + .getHead(); + QueryBillResponse.Message.Info respInfo = response.getMessage() + .getInfo(); + //缴费账单子账单 + ArrayList<QueryBillResponse.Message.Info.Bill> respBills = new ArrayList<QueryBillResponse.Message.Info.Bill>(); + ArrayList<QueryBillResponse.Message.Info.Bill.DescDetail> respDescDetail = + new ArrayList<QueryBillResponse.Message.Info.Bill.DescDetail>(); + QueryBillResponse.Message.Info.Bill respBill = respInfo.new Bill(); + //缴费子商户账单 +// ArrayList<QueryBillResponse.Message.Info.Bill.SplitSubMerInfo> splitSubMerInfos = new ArrayList<QueryBillResponse.Message.Info.Bill.SplitSubMerInfo>(); + + //封装返回给缴费中心的响应 + + String epayCode = queryBillRequest.getMessage().getInfo() + .getEpayCode(); + respInfo.setEpayCode(epayCode); + String merchantId = queryBillRequest.getMessage().getInfo() + .getMerchantId(); + respInfo.setMerchantId(merchantId); + respInfo.setTraceNo(traceNo); + respInfo.setInput1(queryBillRequest.getMessage().getInfo() + .getInput1()); + respInfo.setInput2(queryBillRequest.getMessage().getInfo() + .getInput2()); + respInfo.setInput3(queryBillRequest.getMessage().getInfo() + .getInput3()); + respInfo.setInput4(queryBillRequest.getMessage().getInfo() + .getInput4()); + respInfo.setInput5(queryBillRequest.getMessage().getInfo() + .getInput5()); + String orderid= queryBillRequest.getMessage().getInfo().getInput1(); + if (StringUtils.isEmpty(orderid)){ + respHead.setReturnCode("0009"); + respHead.setReturnMessage("参数错误,input1订单号不能为空"); + }else{ + if (flag){ + + TPayOrder order = payOrderService.getById(orderid); + List<TOrderBill> orderBills = orderBillService.getByOrderNo(orderid); + List<TBillDto> bills = orderBills.stream().map(ob + -> tBillService.getDetailByBillId(ob.getBillId())).collect(Collectors.toList()); + +// 封装详细账单信息 + respBill.setBillName(order.getUserName()); + respBill.setFeeAmt(BigDecimal.valueOf(order.getAmount()).divide(AmountConstant.b100,2, RoundingMode.HALF_DOWN).toPlainString()); + respBills.add(respBill); + respInfo.setCustName(order.getUserName()); + respInfo.setCustAddress(""); + respInfo.setCacheMem(""); + respInfo.setRemark(""); + respInfo.setCallBackText("西藏国资委"); + //respInfo.setCallBackUrl("https://abcsr.keepfx.cn/b/ejy/payResult/"); + //使用base64加密信息 +// respInfo.setCallBackUrl("aHR0cDp3d3cuYWJjaGluYS5jb20vY24v"); + //金额规则字段 + String amtRule = "0"; + respInfo.setAmtRule(amtRule); + /*QueryBillResponse.Message.Info.Bill.UnitDetail unitDetail = respBill.new UnitDetail( + "unitName", "6.66", "1");*/ + BigDecimal outstandAmount = bills.stream().map(TBillDto::getOutstandingMoney).reduce(BigDecimal::add).get(); + //欠费金额 + respBill.setOweAmt(outstandAmount.setScale(2,RoundingMode.HALF_DOWN).toPlainString()); + respBill.setFeeAmt("0.00"); +// +// QueryBillResponse.Message.Info.Bill.DescDetail descDtail1 = respBill.new DescDetail( +// "缴费月份:", "2020年6月份"); +// QueryBillResponse.Message.Info.Bill.DescDetail descDtail2 = respBill.new DescDetail( +// "供电局编号:", "4340152"); +// QueryBillResponse.Message.Info.Bill.DescDetail descDtail3 = respBill.new DescDetail( +// "欠费金额:", "0.00元"); +// QueryBillResponse.Message.Info.Bill.DescDetail descDtail4 = respBill.new DescDetail( +// "缴费月份:", "2020年6月份"); +// QueryBillResponse.Message.Info.Bill.DescDetail descDtail5 = respBill.new DescDetail( +// "服务时间:", "每天0:30-23:30期间均可缴费"); +// QueryBillResponse.Message.Info.Bill.DescDetail descDtail6 = respBill.new DescDetail( +// "温馨提示:", "北京电力电费代缴,咨询电话:95598 该用户为:预付费用户"); +// respDescDetail.add(descDtail1); +// respDescDetail.add(descDtail2); +// respDescDetail.add(descDtail3); +// respDescDetail.add(descDtail4); +// respDescDetail.add(descDtail5); +// respDescDetail.add(descDtail6); + +// respBill.setRcvMerchantId("103881104410001"); + +// 商户子商户详细信息 +// QueryBillResponse.Message.Info.Bill.SplitSubMerInfo splitSubMerInfo1 =respBill.new SplitSubMerInfo("10388", "0.01"); +// QueryBillResponse.Message.Info.Bill.SplitSubMerInfo splitSubMerInfo2 =respBill.new SplitSubMerInfo("1038819201", "0.02"); +// splitSubMerInfos.add(splitSubMerInfo1); +// splitSubMerInfos.add(splitSubMerInfo2); + +// respBill.setSplitSubMerInfos(splitSubMerInfos); +// respBill.setDescDetails(respDescDetail); + respInfo.setTotalBillCount(String.valueOf(respBills.size())); + respInfo.setBill(respBills); + + // 有定制电子回单附言信息的,需添加自定义定制附言信息字段 + respInfo.setMerchantRemark(""); + respHead.setReturnCode("0000"); + respHead.setReturnMessage("账单查询成功,返回成功标志"); + }else { + respHead.setReturnCode("0009"); + respHead.setReturnMessage("缴费中心传送给商户的请求报文签名验签失败!"); + } + } + + respHead.setTransFlag("02"); + respHead.setTimeStamp(DateUtil.format(new Date(),"yyyyMMddHHmmssSSS")); + + respMessage.setInfo(respInfo); + respMessage.setHead(respHead); + response.setMessage(respMessage); + responseJson = JSON.toJSONString(response); + // 加签名 + String signatrue = signatureAndVerification + .signWhithsha1withrsa(responseJson); + log.info("signatrue" + responseJson); + log.info("responseJson打印结果是(responseJson加密前):" + responseJson); + responseJson = signatrue + "||" + + new String(Base64.encodeBase64(responseJson.getBytes("utf-8"))); + log.info("responseJson打印结果是(responseJson加密后):{}", responseJson); + httpServletResponse.setCharacterEncoding("utf-8"); + httpServletResponse.setContentType("text/plain"); + httpServletResponse.getWriter().write(responseJson); + } catch (Exception e) { + e.printStackTrace(); + } } diff --git a/ruoyi-admin/src/main/resources/application-test.yml b/ruoyi-admin/src/main/resources/application-test.yml index f4b61c4..d30a6a6 100644 --- a/ruoyi-admin/src/main/resources/application-test.yml +++ b/ruoyi-admin/src/main/resources/application-test.yml @@ -14,7 +14,6 @@ addressEnabled: false # 验证码类型 math 数字计算 char 字符验证 captchaType: math - # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 @@ -103,7 +102,7 @@ druid: # 主库数据源 master: - url: jdbc:mysql://xzgt.test.591taxi.cn:13306/xizang?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai + url: jdbc:mysql://xzgt.test.591taxi.cn:13306/xizang?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai username: root password: 8f5z9g52gx4bg # 从库数据源 @@ -227,4 +226,12 @@ appId: 1400957506 secretid: AKIDCF5EF2c0DE1e5JK8r4EGJF4mNsMgp26x secretkey: lLl184rUyFOOE0d5KNGC3kmfNsCWk4GU - sign: 畅云出行 \ No newline at end of file + sign: 畅云出行 +com: + taxi591: + bank: + cer-path: D:\workspaces\工作文件\畅云\农业银行\TrustPayTest.cer + base-url: http://hello.enjoy.abchina.com + enable: true + keystore-password: + pfx-path: D:\workspaces\工作文件\畅云\农业银行\103882200000958.pfx \ No newline at end of file diff --git a/ruoyi-applet/src/main/resources/application-test.yml b/ruoyi-applet/src/main/resources/application-test.yml index e9018b1..3bfc62b 100644 --- a/ruoyi-applet/src/main/resources/application-test.yml +++ b/ruoyi-applet/src/main/resources/application-test.yml @@ -103,7 +103,7 @@ druid: # 主库数据源 master: - url: jdbc:mysql://xzgt.test.591taxi.cn:13306/xizang?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai + url: jdbc:mysql://xzgt.test.591taxi.cn:13306/xizang?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai username: root password: 8f5z9g52gx4bg # 从库数据源 diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java index ecc4884..362d630 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java @@ -1,5 +1,6 @@ package com.ruoyi.system.service.impl; +import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.config.SmsProperties; @@ -7,10 +8,7 @@ import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.common.utils.DateUtils; -import com.ruoyi.common.utils.SmsUtil; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.TencentMailUtil; +import com.ruoyi.common.utils.*; import com.ruoyi.common.utils.uuid.UUID; import com.ruoyi.system.dto.*; import com.ruoyi.system.mapper.TBillMapper; @@ -276,6 +274,7 @@ save.setPayType(3); save.setPayer(dto.getPayer()); save.setPayTime(bankflow.getPayTime()); + save.setSysSerialNumber(OrderNos.getDid(30)); save.setBankSerialNumber(bankflow.getBankSerialNumber()); save.setFlowType(2); save.setPaymentBillId(back.getId()); @@ -332,6 +331,7 @@ saveFlow.setPayType(1); saveFlow.setPayer(order.getUserId()); saveFlow.setPayTime(DateUtils.dateToLocalDateTime(save.getPayTime())); + saveFlow.setSysSerialNumber(OrderNos.getDid(30)); saveFlow.setBankSerialNumber(save.getPayNo()); saveFlow.setFlowType(2); saveFlow.setPaymentBillId(bill.getId()); diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TPayOrderServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TPayOrderServiceImpl.java index 4d6ed9f..c8d77eb 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TPayOrderServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TPayOrderServiceImpl.java @@ -69,12 +69,13 @@ if (bill == null) { throw new ServiceException("账单不存在"); } - //计算欠费金额:租金+违约金-实收金额 - long rent = caculateRentFee(bill); + //欠费金额转成单位分比较 + long rent = bill.getOutstandingMoney().multiply(AmountConstant.b100) + .setScale(2,RoundingMode.HALF_DOWN).longValue(); if (rent==0){ throw new ServiceException("该账单已缴费"); } - if (rent>dto.getAmount()){ + if (rent<dto.getAmount()){ throw new ServiceException("支付金额超过了账单欠费金额"); } @@ -105,7 +106,11 @@ orderBills.add(new TOrderBill(orderNo,bill.getId())); return bill; }).collect(Collectors.toList()); - long sumRent = bills.stream().mapToLong((bill) -> caculateRentFee(bill)).sum(); + //欠费金额转成单位分比较 + long sumRent = bills.stream().mapToLong((bill) + -> bill.getOutstandingMoney().multiply(AmountConstant.b100) + .setScale(2,RoundingMode.HALF_DOWN).longValue()) + .sum(); if (sumRent==0){ throw new ServiceException("账单已缴费"); } -- Gitblit v1.7.1