From c9743d30317ed0aaa70a2f6f3649915051ea59b8 Mon Sep 17 00:00:00 2001 From: xuhy <3313886187@qq.com> Date: 星期一, 10 二月 2025 11:57:49 +0800 Subject: [PATCH] Merge branch 'xizang-changyun' of https://gitee.com/xiaochen991015/xizang --- ruoyi-common/src/main/java/com/ruoyi/common/constant/WxConstant.java | 3 ruoyi-system/src/main/java/com/ruoyi/system/dto/MakeOrderResp.java | 23 ruoyi-admin/src/main/resources/application-test.yml | 2 bankapi/src/main/java/com/taxi591/bankapi/utils/Base64.java | 210 +++ ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TOrderBillServiceImpl.java | 20 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFlowManagementServiceImpl.java | 27 ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml | 25 bankapi/src/main/java/com/taxi591/bankapi/service/BankService.java | 117 ++ ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java | 9 bankapi/src/main/java/com/taxi591/bankapi/utils/Base64Util.java | 50 generator/src/main/java/com/ruoyi/system/mapper/TPayOrderMapper.java | 16 generator/src/main/java/com/ruoyi/system/model/TPayOrder.java | 86 + bankapi/src/main/resources/META-INF/spring.factories | 2 bankapi/src/main/java/com/taxi591/bankapi/BankConfig.java | 17 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java | 19 generator/src/main/java/com/ruoyi/system/mapper/TOrderBillMapper.java | 16 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TPayOrderMapper.java | 16 bankapi/src/main/java/com/taxi591/bankapi/BankProperties.java | 36 ruoyi-common/src/main/java/com/ruoyi/common/constant/AmountConstant.java | 15 generator/src/main/java/com/ruoyi/system/controller/TOrderBillController.java | 21 ruoyi-system/src/main/java/com/ruoyi/system/query/TInvoiceQuery.java | 55 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBankFlowMapper.java | 16 bankapi/src/main/java/com/taxi591/bankapi/dto/CovertPayBackResult.java | 18 ruoyi-system/src/main/java/com/ruoyi/system/model/TOrderBill.java | 54 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBillServiceImpl.java | 39 ruoyi-ui/vue.config.js | 2 ruoyi-admin/src/main/java/com/ruoyi/web/task/TbillTask.java | 135 ++ generator/src/main/resources/mapping/TBankFlowMapper.xml | 29 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TPayOrderServiceImpl.java | 130 ++ generator/src/main/java/com/ruoyi/system/model/TOrderBill.java | 47 ruoyi-system/src/main/java/com/ruoyi/system/dto/MakeOrderDto.java | 38 generator/src/main/java/com/ruoyi/system/service/impl/TPayOrderServiceImpl.java | 20 ruoyi-admin/src/main/resources/application-prod.yml | 2 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBankFlowServiceImpl.java | 46 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java | 7 ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java | 11 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInvoiceServiceImpl.java | 26 ruoyi-system/src/main/java/com/ruoyi/system/service/TPayOrderService.java | 19 ruoyi-system/src/main/java/com/ruoyi/system/query/TBankFlowQuery.java | 60 + bankapi/pom.xml | 64 + ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java | 33 bankapi/src/main/java/com/taxi591/bankapi/dto/ChargeBillRequest.java | 175 +++ generator/src/main/resources/mapping/TOrderBillMapper.xml | 19 pom.xml | 1 bankapi/src/main/java/com/taxi591/bankapi/utils/HttpClientUtils.java | 302 +++++ ruoyi-system/src/main/java/com/ruoyi/system/model/TBankFlow.java | 90 + generator/src/main/java/com/ruoyi/system/service/impl/TOrderBillServiceImpl.java | 20 ruoyi-system/src/main/java/com/ruoyi/system/query/TBillQuery.java | 16 generator/src/test/java/com/xizang/CodeGeneratorTests.java | 4 ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java | 89 - ruoyi-system/src/main/java/com/ruoyi/system/service/TBankFlowService.java | 26 ruoyi-system/src/main/java/com/ruoyi/system/service/TFlowManagementService.java | 8 generator/src/main/java/com/ruoyi/system/service/TPayOrderService.java | 16 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFlowManagementController.java | 22 ruoyi-system/src/main/java/com/ruoyi/system/query/TFlowManagementQuery.java | 63 + ruoyi-common/src/main/java/com/ruoyi/common/utils/OrderNos.java | 164 ++ ruoyi-admin/pom.xml | 6 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBankFlowController.java | 43 bankapi/src/main/java/com/taxi591/bankapi/dto/ChargeBillResponse.java | 158 ++ ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java | 76 + ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TInvoiceController.java | 30 bankapi/src/main/java/com/taxi591/bankapi/service/SignatureAndVerification.java | 198 +++ ruoyi-applet/pom.xml | 6 ruoyi-system/src/main/java/com/ruoyi/system/dto/TBillDto.java | 17 ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java | 6 ruoyi-system/src/main/java/com/ruoyi/system/mapper/TOrderBillMapper.java | 16 generator/src/main/resources/mapping/TPayOrderMapper.xml | 28 generator/src/main/java/com/ruoyi/system/service/TOrderBillService.java | 16 ruoyi-system/src/main/java/com/ruoyi/system/service/TInvoiceService.java | 7 ruoyi-system/src/main/java/com/ruoyi/system/service/TOrderBillService.java | 16 ruoyi-system/src/main/java/com/ruoyi/system/model/TPayOrder.java | 88 + ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/PayController.java | 35 generator/src/main/java/com/ruoyi/system/controller/TPayOrderController.java | 21 ruoyi-system/src/main/resources/mapper/system/TBankFlowMapper.xml | 29 74 files changed, 3,275 insertions(+), 117 deletions(-) diff --git a/bankapi/pom.xml b/bankapi/pom.xml new file mode 100644 index 0000000..d31f24e --- /dev/null +++ b/bankapi/pom.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>com.ruoyi</groupId> + <artifactId>ruoyi</artifactId> + <version>3.8.6</version> + </parent> + <description> + 银行接口模块 + </description> + <groupId>org.taxi591</groupId> + <artifactId>bankapi</artifactId> + <version>1.0.0-SNAPSHOT</version> + <properties> + <httpclient_version>4.5.2</httpclient_version> + </properties> + <dependencies> + <dependency> + <groupId>com.ruoyi</groupId> + <artifactId>ruoyi-framework</artifactId> + </dependency> + <dependency> + <groupId>com.ruoyi</groupId> + <artifactId>ruoyi-common</artifactId> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>${httpclient_version}</version> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <version>2.5.15</version> + <configuration> + <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 --> + </configuration> + <executions> + <execution> + <goals> + <goal>repackage</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-war-plugin</artifactId> + <version>3.1.0</version> + <configuration> + <failOnMissingWebXml>false</failOnMissingWebXml> + <warName>${project.artifactId}</warName> + </configuration> + </plugin> + </plugins> + <finalName>${project.artifactId}</finalName> + </build> +</project> \ No newline at end of file diff --git a/bankapi/src/main/java/com/taxi591/bankapi/BankConfig.java b/bankapi/src/main/java/com/taxi591/bankapi/BankConfig.java new file mode 100644 index 0000000..a59a542 --- /dev/null +++ b/bankapi/src/main/java/com/taxi591/bankapi/BankConfig.java @@ -0,0 +1,17 @@ +package com.taxi591.bankapi; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableConfigurationProperties({BankProperties.class}) +@ConditionalOnProperty(value = BankProperties.ENBALE_PREFIX, matchIfMissing = true) +@ComponentScan("com.taxi591.bankapi.service") +public class BankConfig { + + + + +} diff --git a/bankapi/src/main/java/com/taxi591/bankapi/BankProperties.java b/bankapi/src/main/java/com/taxi591/bankapi/BankProperties.java new file mode 100644 index 0000000..6e959eb --- /dev/null +++ b/bankapi/src/main/java/com/taxi591/bankapi/BankProperties.java @@ -0,0 +1,36 @@ +package com.taxi591.bankapi; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import static com.taxi591.bankapi.BankProperties.PREFIX; + +@Data +@ConfigurationProperties(prefix = PREFIX) +public class BankProperties { + + public static final String PREFIX = "com.taxi591.bank"; + + public static final String ENBALE_PREFIX = PREFIX+".enable"; + + private Boolean enable = true; + + + private String baseUrl="http://hello.enjoy.abchina.com"; + + /** + * 证书路径 + */ + private String pfxPath; + /** + * 密码 + */ + private String keystorePassword; + + /** + * 公钥路径 + */ + private String cerPath; + + +} diff --git a/bankapi/src/main/java/com/taxi591/bankapi/dto/ChargeBillRequest.java b/bankapi/src/main/java/com/taxi591/bankapi/dto/ChargeBillRequest.java new file mode 100644 index 0000000..9aadf9b --- /dev/null +++ b/bankapi/src/main/java/com/taxi591/bankapi/dto/ChargeBillRequest.java @@ -0,0 +1,175 @@ +package com.taxi591.bankapi.dto; + +import com.alibaba.fastjson2.JSON; +import lombok.Data; + +import java.io.Serializable; + +/** + * 直连商户平台缴费销账输入对象,需要转换成json串发送给第三方系统 + * @author DELL + * + */ +@Data +public class ChargeBillRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 格式 */ + private String format; + + /** 消息 */ + private Message message; + + @Override + public String toString() { + return "ChargeBillRequest[format=" + format + ",message=" + message.toString() + "]"; + } + + /** + * + * 账单查询内部消息对象实体message内部类 + * + */ + @Data + public class Message implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 消息头部 */ + private Head head; + + /** 消息体 */ + private Info info; + + @Override + public String toString() { + return JSON.toJSONString(this); + } + + /** + * message子对象head消息头内部类 + */ + @Data + public class Head implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 渠道编码 */ + private String channel; + + /** 交易码 */ + private String transCode; + + /** 交易上行下送标志位 */ + private String transFlag; + + /** 缴费中心交易序列号 */ + private String transSeqNum; + + /** 时间戳 */ + private String timeStamp; + + /** 4为分行iGoal码 */ + private String branchCode; + + @Override + public String toString() { + return JSON.toJSONString(this); + } + } + + /** + * message子对象info消息实体内部类 + */ + @Data + public class Info implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 缴费项目编号*/ + private String epayCode; + + /** 第三方商户编号*/ + private String merchantId; + + /** 缴费中心流水号*/ + private String traceNo; + + /** 输入要素1*/ + private String input1; + + /** 输入要素2*/ + private String input2; + + /** 输入要素3*/ + private String input3; + + /** 输入要素4*/ + private String input4; + + /** 输入要素5*/ + private String input5; + + /** 农行16位客户号*/ + private String userId; + + /** 缴费金额计算规则*/ + private String amtRule; + + /** 合并支付的子账单数*/ + private String payBillCount; + + /** 合并支付的子账单累加总金额*/ + private String payBillAmt; + + /** 合并支付的子账单*/ + private String payBillNo; + + /** 套餐名称*/ + private String optionName; + + /** 套餐编码*/ + private String optionCode; + + /** 套餐金额*/ + private String optionAmt; + + /** 支付方式交易码*/ + private String payType; + + /** 缴费支付账号*/ + private String payAcc; + + /** 支付系统流水号*/ + private String transPaySeq; + + /** 支付系统日期*/ + private String transDate; + + /** 支付系统时间*/ + private String transTime; + + /** 会计日期*/ + private String settleDate; + + /** 清算模式*/ + private String clearType; + + /** 缓存域信息*/ + private String cacheMem; + + /** 销账报文重发次数,通过此字段识别销账报文是否为重发的,0表示首次、1表示重发一次,2表示重发2次,最多重发3次*/ + private String resendTimes; + + /** 第三方支付平台商户订单号 第三方平台例如微信支付宝的支付订单号 add 2020-01-13*/ + private String numOpenMerchantOrder; + + + @Override + public String toString() { + return JSON.toJSONString(this); + } + } + } +} \ No newline at end of file diff --git a/bankapi/src/main/java/com/taxi591/bankapi/dto/ChargeBillResponse.java b/bankapi/src/main/java/com/taxi591/bankapi/dto/ChargeBillResponse.java new file mode 100644 index 0000000..ec6d9d8 --- /dev/null +++ b/bankapi/src/main/java/com/taxi591/bankapi/dto/ChargeBillResponse.java @@ -0,0 +1,158 @@ +package com.taxi591.bankapi.dto; + +import com.alibaba.fastjson2.JSON; +import lombok.Data; + +import java.io.Serializable; + +/** + * 直连商户平台账单销账返回对象 + * @author DELL + * + */ +@Data +public class ChargeBillResponse implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 格式 */ + private String format; + + /** 消息体 */ + private Message message; + + + public ChargeBillResponse(){ + + } + + /** + * 构造函数,通过输入对象,构造返回对象数据信息 + * @param request + */ + public ChargeBillResponse(ChargeBillRequest request) { + this.setFormat(request.getFormat()); + this.setMessage(new Message(request.getMessage())); + } + + @Override + public String toString() { + return JSON.toJSONString(this); + } + /** + * + * 账单查询内部消息对象返回实体message内部类 + * + */ + @Data + public class Message implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 消息头部 */ + private Head head; + + /** 消息实体 */ + private Info info; + + public Message() { + this.head = new Head(); + this.info = new Info(); + } + + public Message(ChargeBillRequest.Message requestMessage){ + this.setHead(new Head(requestMessage.getHead())); + this.setInfo(new Info(requestMessage.getInfo())); + } + + @Override + public String toString() { + return JSON.toJSONString(this); + } + + /** + * + * 账单销账内部消息对象返回实体Head内部类 + * + */ + @Data + public class Head implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 渠道 */ + private String channel; + + /** 交易码 */ + private String transCode; + + /** 交易上行下送标志 */ + private String transFlag; + + /** 缴费中心交易序列号 */ + private String transSeqNum; + + /** 时间戳 */ + private String timeStamp; + + /** 查询返回码 */ + private String returnCode ; + + /** 返回提示信息 */ + private String returnMessage; + + public Head() { + + } + + public Head(ChargeBillRequest.Message.Head reqMessHead) { + this.setChannel(reqMessHead.getChannel()); + this.setTransSeqNum(reqMessHead.getTransSeqNum()); + this.setTransCode(reqMessHead.getTransCode()); + } + + @Override + public String toString() { + return JSON.toJSONString(this); + } + + } + + /** + * + * 账单查询内部消息对象返回实体Info内部类 + * + */ + @Data + public class Info implements Serializable { + + private static final long serialVersionUID = 1L; + + /** 缴费项目唯一标识号*/ + private String epayCode; + + /** 缴费中心流水号*/ + private String traceNo; + + /** 退款标志位*/ + private String refundFlag; + + /** 第三方支付平台商户订单号 第三方平台例如微信支付宝的支付订单号 add 2020-01-13*/ + private String numOpenMerchantOrder; + + public Info() { + + } + + public Info(ChargeBillRequest.Message.Info reqMessInfo) { + this.setEpayCode(reqMessInfo.getEpayCode()); + this.setTraceNo(reqMessInfo.getTraceNo()); + } + + @Override + public String toString() { + return JSON.toJSONString(this); + } + } + } +} \ No newline at end of file diff --git a/bankapi/src/main/java/com/taxi591/bankapi/dto/CovertPayBackResult.java b/bankapi/src/main/java/com/taxi591/bankapi/dto/CovertPayBackResult.java new file mode 100644 index 0000000..d4fb154 --- /dev/null +++ b/bankapi/src/main/java/com/taxi591/bankapi/dto/CovertPayBackResult.java @@ -0,0 +1,18 @@ +package com.taxi591.bankapi.dto; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class CovertPayBackResult implements Serializable { + /** + * 解析结果 + */ + private ChargeBillRequest result; + /** + * 返回银行应答内容 + */ + private String back; + +} diff --git a/bankapi/src/main/java/com/taxi591/bankapi/service/BankService.java b/bankapi/src/main/java/com/taxi591/bankapi/service/BankService.java new file mode 100644 index 0000000..657cfc2 --- /dev/null +++ b/bankapi/src/main/java/com/taxi591/bankapi/service/BankService.java @@ -0,0 +1,117 @@ +package com.taxi591.bankapi.service; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.TypeReference; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DateUtils; +import com.taxi591.bankapi.dto.ChargeBillRequest; +import com.taxi591.bankapi.dto.ChargeBillResponse; +import com.taxi591.bankapi.dto.CovertPayBackResult; +import com.taxi591.bankapi.utils.Base64; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import java.io.UnsupportedEncodingException; +import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Service +@Slf4j +public class BankService { + + @Autowired + SignatureAndVerification signatureAndVerification; + + static final String TIMESTAMP_PATTERN = "yyyyMMddHHmmssSSS"; + + /** + * 创建银行应答 + * @param request 银行请求对象 + * @param dealResult 是否处理成功 + * @return + */ + public String createResponse(ChargeBillRequest request,Boolean dealResult){ + ChargeBillResponse response = new ChargeBillResponse(request); + response.getMessage().getHead().setReturnCode(dealResult?"0000":"1111"); + response.getMessage().getHead().setReturnMessage(dealResult?"处理成功":"处理失败"); + response.getMessage().getInfo().setRefundFlag("false"); + response.getMessage().getHead().setTimeStamp(DateUtils.dateTimeNow(TIMESTAMP_PATTERN)); + if (!dealResult){ + if (Integer.parseInt(request.getMessage().getInfo().getResendTimes())==3){ + response.getMessage().getInfo().setRefundFlag("true"); + }else{ + response.getMessage().getInfo().setRefundFlag("false"); + } + } + String respJSON = JSON.toJSONString(response); + String sign = signatureAndVerification.signWhithsha1withrsa(respJSON); + String respStr = null; + try { + respStr = sign + "||" + new String(org.apache.commons.codec.binary.Base64.encodeBase64(respJSON.getBytes("utf-8"))); + } catch (UnsupportedEncodingException e) { + } + return respStr; + } + + /** + * 处理支付回调数据 + * @param httpRequest http请求对象 + * @param consumer 处理函数 + * @return + */ + public CovertPayBackResult covertPayCallBack(HttpServletRequest httpRequest, Function<ChargeBillRequest,Boolean> consumer) { + CovertPayBackResult result = new CovertPayBackResult(); + String requestContent = ""; + try { + // 接收报文 + requestContent = SignatureAndVerification.getRequestBody(httpRequest).trim(); + String sign = requestContent.substring(0, + requestContent.indexOf("||"));; + String requestBody = requestContent.substring(sign + .length() + 2);; + Pattern p=Pattern.compile("\""); + Matcher m=p.matcher(requestBody); + while(m.find()){ + requestBody=requestBody.replace(m.group(), ""); + } + String request = new String(Base64.decodeFast(requestBody)); + log.info("-----ChargeBillController------------解析完成后的requestBody-------{}" + request); + ChargeBillRequest chargeBillRequest = JSON.parseObject(request, + new TypeReference<ChargeBillRequest>() { + }); + if (chargeBillRequest==null){ + log.error("支付回调解析失败:{}",requestContent); + throw new ServiceException("支付回调解析失败"); + } + boolean isok = signatureAndVerification.read_cer_and_verify_sign(requestBody,sign); + if (!isok){ + throw new ServiceException("支付回调验签失败"); + } + Boolean dealBack = true; + if (consumer!=null){ + dealBack = consumer.apply(chargeBillRequest); + } + result.setResult(chargeBillRequest); + result.setBack(createResponse(chargeBillRequest,dealBack)); + }catch (ServiceException e){ + result.setBack(e.getMessage()); + throw e; + }catch (Exception e){ + log.error("解析异常:{}",requestContent,e); + throw new ServiceException("支付回调解析异常"); + } + return result; + } + + + public void covertBillTo(){ + + + } + + + +} diff --git a/bankapi/src/main/java/com/taxi591/bankapi/service/SignatureAndVerification.java b/bankapi/src/main/java/com/taxi591/bankapi/service/SignatureAndVerification.java new file mode 100644 index 0000000..948bdee --- /dev/null +++ b/bankapi/src/main/java/com/taxi591/bankapi/service/SignatureAndVerification.java @@ -0,0 +1,198 @@ +package com.taxi591.bankapi.service; + +import com.taxi591.bankapi.BankProperties; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.binary.Base64; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.io.*; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +/** + * 验签和加签工具类 + * @author yzz + * + */ +@Component +@Slf4j +public class SignatureAndVerification { + + @Autowired + BankProperties bankProperties; + + + + public static String getRequestBody(HttpServletRequest request) + throws IOException { + /** 读取httpbody内容 */ + StringBuilder httpBody = new StringBuilder(); + BufferedReader br = null; + try { + br = new BufferedReader(new InputStreamReader( + request.getInputStream())); + String line = null; + while ((line = br.readLine()) != null) { + httpBody.append(line); + } + } catch (IOException ex) { + throw ex; + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + } + return httpBody.toString(); + } + /** + * 加签名 + * @param dataString + * @return + */ + public String signWhithsha1withrsa(String dataString) { + String signatureString = null; + String filePath=bankProperties.getPfxPath(); + try { + KeyStore ks = KeyStore.getInstance("PKCS12"); + FileInputStream fis = new FileInputStream(filePath); + char[] nPassword = null; + if ((bankProperties.getKeystorePassword() == null) + || bankProperties.getKeystorePassword().trim().equals("")) { + nPassword = null; + } else { + nPassword = bankProperties.getKeystorePassword().toCharArray(); + } + ks.load(fis, nPassword); + fis.close(); + + Enumeration<String> enums = ks.aliases(); + String keyAlias = null; + if (enums.hasMoreElements()) + { + keyAlias = (String) enums.nextElement(); + } + System.out.println("is key entry=" + ks.isKeyEntry(keyAlias)); + PrivateKey prikey = (PrivateKey) ks.getKey(keyAlias, nPassword); + java.security.cert.Certificate cert = ks.getCertificate(keyAlias); + // SHA1withRSA算法进行签名 + Signature sign = Signature.getInstance("SHA1withRSA"); + sign.initSign(prikey); + byte[] data = dataString.getBytes("utf-8"); + byte[] dataBase= Base64.encodeBase64(data); + // 更新用于签名的数据 + sign.update(dataBase); + byte[] signature = sign.sign(); + signatureString = new String(Base64.encodeBase64(signature)); + System.out.println("加密完成,signature is : " + signatureString); + } catch (Exception e) { + e.printStackTrace(); + } + return signatureString; + } + + /** + * 读取cer并验证公钥签名 + * @return + */ + public boolean read_cer_and_verify_sign(String requestBody, String signature) { + String filePath=bankProperties.getCerPath(); + X509Certificate cert = null; + boolean flag = false; + try { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + cert = (X509Certificate) cf + .generateCertificate(new FileInputStream(new File( + filePath))); + PublicKey publicKey = cert.getPublicKey(); + String publicKeyString = new String(Base64.encodeBase64(publicKey + .getEncoded())); + System.out.println("-----------------公钥--------------------"); + System.out.println(publicKeyString); + System.out.println("-----------------公钥--------------------"); + Signature verifySign = Signature.getInstance("SHA1withRSA"); + verifySign.initVerify(publicKey); + // 用于验签的数据 + verifySign.update(requestBody.getBytes("utf-8")); + flag = verifySign.verify(Base64 + .decodeBase64(signature)); + } catch (Exception e) { + log.error("验签失败,发生异常:{},{}",requestBody,signature,e); + flag = false; + } + return flag; + } + + /** + * 接收报文返回requestBody和使用base64解析后的requestBody以及缴费中心传送的签名 + */ + + public Map<String,String> requestBodyOfBase64(HttpServletRequest request){ + Map<String,String> requestMap=new HashMap<String,String>(); + // 接收报文 + String requestContent=null; + try { + requestContent = getRequestBody(request) + .trim(); + } catch (IOException e) { + e.printStackTrace(); + } + String signatureString = null; + String requestBody = null; + if (requestContent.contains("||")) { + signatureString = requestContent.substring(0, + requestContent.indexOf("||")); + requestBody = requestContent.substring(signatureString + .length() + 2); + }else { + try { + requestBody = new String(requestContent.getBytes("GB2312")); + + log.info("转码后的报文:{}",requestBody); + + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + log.info("截取报文的requestBody解密前:{}", requestBody); + + String requestBodyOfDecoded = new String( + Base64.decodeBase64(requestBody)); + + /*if (requestBodyOfDecoded.contains("</Message>")) { + requestBody = requestBodyOfDecoded.substring( + requestContent.indexOf("</Message>"),requestContent.indexOf("</Message>")+10); + + signatureString = requestBodyOfDecoded.substring( + requestContent.indexOf("<Signature>")+11,requestContent.indexOf("</Signature>")); + }*/ + + log.info("截取报文的signatureString:{}", signatureString); + + + System.out.println("-----解析完成后的requestBody-------" + requestBodyOfDecoded); + + //使用base64解析完成后的requestBody + requestMap.put("requestBodyOfDecoded",requestBodyOfDecoded); + //解析前的requestBody + requestMap.put("requestBody",requestBody); + //获取缴费中心传送过来的签名 + requestMap.put("signatureString",signatureString); + return requestMap; + + } + +} diff --git a/bankapi/src/main/java/com/taxi591/bankapi/utils/Base64.java b/bankapi/src/main/java/com/taxi591/bankapi/utils/Base64.java new file mode 100644 index 0000000..9b92495 --- /dev/null +++ b/bankapi/src/main/java/com/taxi591/bankapi/utils/Base64.java @@ -0,0 +1,210 @@ + +package com.taxi591.bankapi.utils; + +import java.util.Arrays; + +/** + * + * @version 2.2 + * @author Mikael Grev Date: 2004-aug-02 Time: 11:31:11 + */ +public class Base64 { + + public static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); + public static final int[] IA = new int[256]; + static { + Arrays.fill(IA, -1); + for (int i = 0, iS = CA.length; i < iS; i++) + IA[CA[i]] = i; + IA['='] = 0; + } + + /** + * Decodes a BASE64 encoded char array that is known to be resonably well formatted. The method is about twice as + * fast as #decode(char[]). The preconditions are:<br> + * + The array must have a line length of 76 chars OR no line separators at all (one line).<br> + * + Line separator must be "\r\n", as specified in RFC 2045 + The array must not contain illegal characters within + * the encoded string<br> + * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br> + * + * @param chars The source array. Length 0 will return an empty array. <code>null</code> will throw an exception. + * @return The decoded array of bytes. May be of length 0. + */ + public static byte[] decodeFast(char[] chars, int offset, int charsLen) { + // Check special case + if (charsLen == 0) { + return new byte[0]; + } + + int sIx = offset, eIx = offset + charsLen - 1; // Start and end index after trimming. + + // Trim illegal chars from start + while (sIx < eIx && IA[chars[sIx]] < 0) + sIx++; + + // Trim illegal chars from end + while (eIx > 0 && IA[chars[eIx]] < 0) + eIx--; + + // get the padding count (=) (0, 1 or 2) + int pad = chars[eIx] == '=' ? (chars[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end. + int cCnt = eIx - sIx + 1; // Content count including possible separators + int sepCnt = charsLen > 76 ? (chars[76] == '\r' ? cCnt / 78 : 0) << 1 : 0; + + int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes + byte[] bytes = new byte[len]; // Preallocate byte[] of exact length + + // Decode all but the last 0 - 2 bytes. + int d = 0; + for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) { + // Assemble three bytes into an int from four "valid" characters. + int i = IA[chars[sIx++]] << 18 | IA[chars[sIx++]] << 12 | IA[chars[sIx++]] << 6 | IA[chars[sIx++]]; + + // Add the bytes + bytes[d++] = (byte) (i >> 16); + bytes[d++] = (byte) (i >> 8); + bytes[d++] = (byte) i; + + // If line separator, jump over it. + if (sepCnt > 0 && ++cc == 19) { + sIx += 2; + cc = 0; + } + } + + if (d < len) { + // Decode last 1-3 bytes (incl '=') into 1-3 bytes + int i = 0; + for (int j = 0; sIx <= eIx - pad; j++) + i |= IA[chars[sIx++]] << (18 - j * 6); + + for (int r = 16; d < len; r -= 8) + bytes[d++] = (byte) (i >> r); + } + + return bytes; + } + + public static byte[] decodeFast(String chars, int offset, int charsLen) { + // Check special case + if (charsLen == 0) { + return new byte[0]; + } + + int sIx = offset, eIx = offset + charsLen - 1; // Start and end index after trimming. + + // Trim illegal chars from start + while (sIx < eIx && IA[chars.charAt(sIx)] < 0) + sIx++; + + // Trim illegal chars from end + while (eIx > 0 && IA[chars.charAt(eIx)] < 0) + eIx--; + + // get the padding count (=) (0, 1 or 2) + int pad = chars.charAt(eIx) == '=' ? (chars.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end. + int cCnt = eIx - sIx + 1; // Content count including possible separators + int sepCnt = charsLen > 76 ? (chars.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0; + + int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes + byte[] bytes = new byte[len]; // Preallocate byte[] of exact length + + // Decode all but the last 0 - 2 bytes. + int d = 0; + for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) { + // Assemble three bytes into an int from four "valid" characters. + int i = IA[chars.charAt(sIx++)] << 18 | IA[chars.charAt(sIx++)] << 12 | IA[chars.charAt(sIx++)] << 6 | IA[chars.charAt(sIx++)]; + + // Add the bytes + bytes[d++] = (byte) (i >> 16); + bytes[d++] = (byte) (i >> 8); + bytes[d++] = (byte) i; + + // If line separator, jump over it. + if (sepCnt > 0 && ++cc == 19) { + sIx += 2; + cc = 0; + } + } + + if (d < len) { + // Decode last 1-3 bytes (incl '=') into 1-3 bytes + int i = 0; + for (int j = 0; sIx <= eIx - pad; j++) + i |= IA[chars.charAt(sIx++)] << (18 - j * 6); + + for (int r = 16; d < len; r -= 8) + bytes[d++] = (byte) (i >> r); + } + + return bytes; + } + + /** + * Decodes a BASE64 encoded string that is known to be resonably well formatted. The method is about twice as fast + * as decode(String). The preconditions are:<br> + * + The array must have a line length of 76 chars OR no line separators at all (one line).<br> + * + Line separator must be "\r\n", as specified in RFC 2045 + The array must not contain illegal characters within + * the encoded string<br> + * + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br> + * + * @param s The source string. Length 0 will return an empty array. <code>null</code> will throw an exception. + * @return The decoded array of bytes. May be of length 0. + */ + public static byte[] decodeFast(String s) { + // Check special case + int sLen = s.length(); + if (sLen == 0) { + return new byte[0]; + } + + int sIx = 0, eIx = sLen - 1; // Start and end index after trimming. + + // Trim illegal chars from start + while (sIx < eIx && IA[s.charAt(sIx) & 0xff] < 0) + sIx++; + + // Trim illegal chars from end + while (eIx > 0 && IA[s.charAt(eIx) & 0xff] < 0) + eIx--; + + // get the padding count (=) (0, 1 or 2) + int pad = s.charAt(eIx) == '=' ? (s.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end. + int cCnt = eIx - sIx + 1; // Content count including possible separators + int sepCnt = sLen > 76 ? (s.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0; + + int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes + byte[] dArr = new byte[len]; // Preallocate byte[] of exact length + + // Decode all but the last 0 - 2 bytes. + int d = 0; + for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) { + // Assemble three bytes into an int from four "valid" characters. + int i = IA[s.charAt(sIx++)] << 18 | IA[s.charAt(sIx++)] << 12 | IA[s.charAt(sIx++)] << 6 + | IA[s.charAt(sIx++)]; + + // Add the bytes + dArr[d++] = (byte) (i >> 16); + dArr[d++] = (byte) (i >> 8); + dArr[d++] = (byte) i; + + // If line separator, jump over it. + if (sepCnt > 0 && ++cc == 19) { + sIx += 2; + cc = 0; + } + } + + if (d < len) { + // Decode last 1-3 bytes (incl '=') into 1-3 bytes + int i = 0; + for (int j = 0; sIx <= eIx - pad; j++) + i |= IA[s.charAt(sIx++)] << (18 - j * 6); + + for (int r = 16; d < len; r -= 8) + dArr[d++] = (byte) (i >> r); + } + + return dArr; + } +} \ No newline at end of file diff --git a/bankapi/src/main/java/com/taxi591/bankapi/utils/Base64Util.java b/bankapi/src/main/java/com/taxi591/bankapi/utils/Base64Util.java new file mode 100644 index 0000000..4cec7d4 --- /dev/null +++ b/bankapi/src/main/java/com/taxi591/bankapi/utils/Base64Util.java @@ -0,0 +1,50 @@ +package com.taxi591.bankapi.utils; + +import org.apache.commons.codec.binary.Base64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; + +/** + * 将String进行base64编码解码,使用utf-8 + * yuan + */ +public class Base64Util { + + private static final Logger LOGGER = LoggerFactory.getLogger(Base64Util.class); + private static final String UTF_8 = "UTF-8"; + + /** + * 对给定的字符串进行base64解码操作 + */ + public static String decodeData(String inputData) { + try { + if (null == inputData) { + return null; + } + return new String(Base64.decodeBase64(inputData.getBytes(UTF_8)), UTF_8); + } catch (UnsupportedEncodingException e) { + LOGGER.error(inputData, e); + } + + return null; + } + + /** + * 对给定的字符串进行base64加密操作 + */ + public static String encodeData(String inputData) { + try { + if (null == inputData) { + return null; + } + return new String(Base64.encodeBase64(inputData.getBytes(UTF_8)), UTF_8); + } catch (UnsupportedEncodingException e) { + LOGGER.error(inputData, e); + } + + return null; + } + +} \ No newline at end of file diff --git a/bankapi/src/main/java/com/taxi591/bankapi/utils/HttpClientUtils.java b/bankapi/src/main/java/com/taxi591/bankapi/utils/HttpClientUtils.java new file mode 100644 index 0000000..7458c49 --- /dev/null +++ b/bankapi/src/main/java/com/taxi591/bankapi/utils/HttpClientUtils.java @@ -0,0 +1,302 @@ +package com.taxi591.bankapi.utils; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.*; +import java.util.Map.Entry; + +/** + *httpClient操作远程url工具类 + */ +public class HttpClientUtils { + private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class); + /** + * 发送str格式的post请求 + * @param url + * @param jsonStr + * @return + */ + public static String doPostStr(String url, String str) { + // 建立HttpPost对象 + HttpPost httppost = new HttpPost(url); + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + CloseableHttpClient client = httpClientBuilder.build(); +// int statusCode = 0; + String responseBody = null; + try { + // 设置发送内容、编码等 + StringEntity stringEntity = new StringEntity(str, "utf-8"); + stringEntity.setContentType("text/plain"); + httppost.setEntity(stringEntity); + // 发送Post,并返回一个HttpResponse对象 + HttpResponse response = client.execute(httppost); +// // 获取返回码 +// statusCode = response.getStatusLine().getStatusCode(); + // 获取返回报文 + responseBody = EntityUtils.toString(response.getEntity()); + return responseBody; + }catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 下载文件 + * @param url + * @param jsonStr + * @param 前台的返回流 + * @return + */ + public static void doPostFile(String url, String str,HttpServletResponse httpResponse) { + ServletOutputStream out = null; + // 建立HttpPost对象 + HttpPost httppost = new HttpPost(url); + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + CloseableHttpClient client = httpClientBuilder.build(); + try { + // 设置发送内容、编码等 + StringEntity stringEntity = new StringEntity(str, "utf-8"); + stringEntity.setContentType("text/plain"); + httppost.setEntity(stringEntity); + // 发送Post,并返回一个HttpResponse对象 + HttpResponse response = client.execute(httppost); + // 获取返回报文 + String responseStr = EntityUtils.toString(response.getEntity()); + + //如果系统返回未加密异常则会返回"{"+json+"}" + if (responseStr.startsWith("{")){ + //设置响应头信息为页面形式 + httpResponse.setCharacterEncoding("UTF-8"); + httpResponse.setContentType("text/html;charset=utf-8"); + httpResponse.sendRedirect("downloadTraceFail.jsp"); + + //如果返回内容为异常信息则返回内容为"签名||base64加密"形式 + }else if (responseStr.contains("||")) { + //截取签名信息 + String headSub = responseStr.substring(0, responseStr.indexOf("||")); + logger.warn("获取签名的前半部分:"+headSub); + //截取加密的json信息,进行解密 + String tailSub = responseStr.substring(responseStr.indexOf("||")+2); + logger.warn("获取签名的后半部分:"+tailSub); + //将获取到的json报文进行解析,获取报文体信息 + responseStr = Base64Util.decodeData(tailSub); + logger.warn("获取签名解密后:"+responseStr); + + //设置响应头信息为页面形式 + httpResponse.setCharacterEncoding("UTF-8"); + httpResponse.setContentType("text/html;charset=utf-8"); + httpResponse.sendRedirect("downloadTraceFail.jsp"); + + //返回内容为正常内容,将response消息头读取直接写入httpResponse中 + }else{ + Header[] encode = response.getAllHeaders(); + for (Header header : encode) { + httpResponse.setHeader(header.getName(), header.getValue()); + } + } + //将获取到的信息封装到httpEntity中,反映到页面中去 + logger.warn("最终获取到的信息:"+responseStr); + HttpEntity entity = new StringEntity(responseStr,"UTF-8"); + //通过输出流将结果反映到页面上 + out = httpResponse.getOutputStream(); + entity.writeTo(out); + out.flush(); + }catch (Exception e) { + e.printStackTrace(); + }finally{ + if(out != null){ + try { + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + /** + * get 请求方法 + * @param url + * @return + */ + public static String doGet(String url) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + String result = ""; + + try { + //通过址默认配置创建一个httpClient实例 + httpClient = HttpClients.createDefault(); + //创建httpGet远程连接实例 + HttpGet httpGet = new HttpGet(url); + //设置配置请求参数 + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(35000)//连接主机服务超时时间 + .setConnectionRequestTimeout(35000)//请求超时时间 + .setSocketTimeout(60000)//数据读取超时时间 + .build(); + //为httpGet实例设置配置 + httpGet.setConfig(requestConfig); + //执行get请求得到返回对象 + response = httpClient.execute(httpGet); + //通过返回对象获取返回数据 + HttpEntity entity = response.getEntity(); + //通过EntityUtils中的toString方法将结果转换为字符串 + result = EntityUtils.toString(entity); + + } catch (ClientProtocolException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + //关闭资源 + if(null != response) { + try { + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + if(null != httpClient) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + return result; + } + + /** + * post请求 + * @param url + * @param paramMap + * @return + */ + public static String doPost(String url, Map<String,Object> paramMap) { + CloseableHttpClient httpClient = null; + CloseableHttpResponse response = null; + String result = ""; + + try { + //创建httpClient实例 + httpClient = HttpClients.createDefault(); + //创建httpPost远程连接实例 + HttpPost httpPost = new HttpPost(url); + //配置请求参数实例 + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(35000)//设置连接主机服务超时时间 + .setConnectionRequestTimeout(35000)//设置连接请求超时时间 + .setSocketTimeout(60000)//设置读取数据连接超时时间 + .build(); + //为httpPost实例设置配置 + httpPost.setConfig(requestConfig); + + //封装post请求参数 + if(null != paramMap && paramMap.size() > 0) { + List<NameValuePair> nvps = new ArrayList<NameValuePair>(); + //通过map集成entrySet方法获取entity + Set<Entry<String, Object>> entrySet = paramMap.entrySet(); + //循环遍历,获取迭代器 + Iterator<Entry<String, Object>> iterator = entrySet.iterator(); + while (iterator.hasNext()) { + Entry<String, Object> mapEntry = iterator.next(); + nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString())); + } + + //为httpPost设置封装好的请求参数 + httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8")); + } + + //执行post请求得到返回对象 + response = httpClient.execute(httpPost); + //通过返回对象获取数据 + HttpEntity entity = response.getEntity(); + //将返回的数据转换为字符串 + result = EntityUtils.toString(entity); + } catch (Exception e) { + e.printStackTrace(); + } finally { + //关闭资源 + if(null != response) { + try { + response.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + if(null != httpClient) { + try { + httpClient.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return result; + } + + + /** + * + * @param request + * @return + * @throws IOException + */ + public static String getRequestBody(HttpServletRequest request) + throws IOException { + /** 读取httpbody内容 */ + StringBuilder httpBody = new StringBuilder(); + BufferedReader br = null; + try { + br = new BufferedReader(new InputStreamReader( + request.getInputStream())); + String line = null; + while ((line = br.readLine()) != null) { + httpBody.append(line); + } + } catch (IOException ex) { + throw ex; + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + } + return httpBody.toString(); + } + + + +} diff --git a/bankapi/src/main/resources/META-INF/spring.factories b/bankapi/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..719afa0 --- /dev/null +++ b/bankapi/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.taxi591.bankapi.BankConfig \ No newline at end of file diff --git a/generator/src/main/java/com/ruoyi/system/controller/TOrderBillController.java b/generator/src/main/java/com/ruoyi/system/controller/TOrderBillController.java new file mode 100644 index 0000000..4dab479 --- /dev/null +++ b/generator/src/main/java/com/ruoyi/system/controller/TOrderBillController.java @@ -0,0 +1,21 @@ +package com.ruoyi.system.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; + +import org.springframework.web.bind.annotation.RestController; + +/** + * <p> + * 订单表与账单的关联表 前端控制器 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +@RestController +@RequestMapping("/t-order-bill") +public class TOrderBillController { + +} + diff --git a/generator/src/main/java/com/ruoyi/system/controller/TPayOrderController.java b/generator/src/main/java/com/ruoyi/system/controller/TPayOrderController.java new file mode 100644 index 0000000..906d0c2 --- /dev/null +++ b/generator/src/main/java/com/ruoyi/system/controller/TPayOrderController.java @@ -0,0 +1,21 @@ +package com.ruoyi.system.controller; + + +import org.springframework.web.bind.annotation.RequestMapping; + +import org.springframework.web.bind.annotation.RestController; + +/** + * <p> + * 支付订单表 前端控制器 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +@RestController +@RequestMapping("/t-pay-order") +public class TPayOrderController { + +} + diff --git a/generator/src/main/java/com/ruoyi/system/mapper/TOrderBillMapper.java b/generator/src/main/java/com/ruoyi/system/mapper/TOrderBillMapper.java new file mode 100644 index 0000000..b1ee709 --- /dev/null +++ b/generator/src/main/java/com/ruoyi/system/mapper/TOrderBillMapper.java @@ -0,0 +1,16 @@ +package com.ruoyi.system.mapper; + +import com.ruoyi.system.model.TOrderBill; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * <p> + * 订单表与账单的关联表 Mapper 接口 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +public interface TOrderBillMapper extends BaseMapper<TOrderBill> { + +} diff --git a/generator/src/main/java/com/ruoyi/system/mapper/TPayOrderMapper.java b/generator/src/main/java/com/ruoyi/system/mapper/TPayOrderMapper.java new file mode 100644 index 0000000..99f5e6a --- /dev/null +++ b/generator/src/main/java/com/ruoyi/system/mapper/TPayOrderMapper.java @@ -0,0 +1,16 @@ +package com.ruoyi.system.mapper; + +import com.ruoyi.system.model.TPayOrder; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * <p> + * 支付订单表 Mapper 接口 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +public interface TPayOrderMapper extends BaseMapper<TPayOrder> { + +} diff --git a/generator/src/main/java/com/ruoyi/system/model/TOrderBill.java b/generator/src/main/java/com/ruoyi/system/model/TOrderBill.java new file mode 100644 index 0000000..9c1bb9c --- /dev/null +++ b/generator/src/main/java/com/ruoyi/system/model/TOrderBill.java @@ -0,0 +1,47 @@ +package com.ruoyi.system.model; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.TableField; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * <p> + * 订单表与账单的关联表 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("t_order_bill") +@ApiModel(value="TOrderBill对象", description="订单表与账单的关联表") +public class TOrderBill implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId("id") + private String id; + + @ApiModelProperty(value = "订单号") + @TableField("order_no") + private String orderNo; + + @ApiModelProperty(value = "账单编号") + @TableField("bill_id") + private String billId; + + @TableField("create_time") + private LocalDateTime createTime; + + @TableField("update_time") + private LocalDateTime updateTime; + + +} diff --git a/generator/src/main/java/com/ruoyi/system/model/TPayOrder.java b/generator/src/main/java/com/ruoyi/system/model/TPayOrder.java new file mode 100644 index 0000000..ea80bf8 --- /dev/null +++ b/generator/src/main/java/com/ruoyi/system/model/TPayOrder.java @@ -0,0 +1,86 @@ +package com.ruoyi.system.model; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableId; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.TableField; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * <p> + * 支付订单表 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("t_pay_order") +@ApiModel(value="TPayOrder对象", description="支付订单表") +public class TPayOrder implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "订单号") + @TableId("id") + private String id; + + @ApiModelProperty(value = "发起支付的用户ID") + @TableField("user_id") + private String userId; + + @ApiModelProperty(value = "用户名称") + @TableField("user_name") + private String userName; + + @ApiModelProperty(value = "用户微信openid或支付宝userid") + @TableField("open_id") + private String openId; + + @ApiModelProperty(value = "用户手机号码") + @TableField("phone") + private String phone; + + @ApiModelProperty(value = "订单金额") + @TableField("amount") + private Long amount; + + @ApiModelProperty(value = "实付金额") + @TableField("act_pay_amount") + private Long actPayAmount; + + @ApiModelProperty(value = "支付时间") + @TableField("pay_time") + private LocalDateTime payTime; + + @ApiModelProperty(value = "支付方式") + @TableField("pay_type") + private String payType; + + @ApiModelProperty(value = "支付的回调信息") + @TableField("pay_info") + private String payInfo; + + @ApiModelProperty(value = "银行的支付流水编号") + @TableField("pay_no") + private String payNo; + + @ApiModelProperty(value = "支付的回调时间") + @TableField("callback_time") + private LocalDateTime callbackTime; + + @ApiModelProperty(value = "订单创建时间") + @TableField("create_time") + private LocalDateTime createTime; + + @ApiModelProperty(value = "订单更新时间") + @TableField("update_time") + private LocalDateTime updateTime; + + +} diff --git a/generator/src/main/java/com/ruoyi/system/service/TOrderBillService.java b/generator/src/main/java/com/ruoyi/system/service/TOrderBillService.java new file mode 100644 index 0000000..38df822 --- /dev/null +++ b/generator/src/main/java/com/ruoyi/system/service/TOrderBillService.java @@ -0,0 +1,16 @@ +package com.ruoyi.system.service; + +import com.ruoyi.system.model.TOrderBill; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * <p> + * 订单表与账单的关联表 服务类 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +public interface TOrderBillService extends IService<TOrderBill> { + +} diff --git a/generator/src/main/java/com/ruoyi/system/service/TPayOrderService.java b/generator/src/main/java/com/ruoyi/system/service/TPayOrderService.java new file mode 100644 index 0000000..eed48ac --- /dev/null +++ b/generator/src/main/java/com/ruoyi/system/service/TPayOrderService.java @@ -0,0 +1,16 @@ +package com.ruoyi.system.service; + +import com.ruoyi.system.model.TPayOrder; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * <p> + * 支付订单表 服务类 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +public interface TPayOrderService extends IService<TPayOrder> { + +} diff --git a/generator/src/main/java/com/ruoyi/system/service/impl/TOrderBillServiceImpl.java b/generator/src/main/java/com/ruoyi/system/service/impl/TOrderBillServiceImpl.java new file mode 100644 index 0000000..5b67f76 --- /dev/null +++ b/generator/src/main/java/com/ruoyi/system/service/impl/TOrderBillServiceImpl.java @@ -0,0 +1,20 @@ +package com.ruoyi.system.service.impl; + +import com.ruoyi.system.model.TOrderBill; +import com.ruoyi.system.mapper.TOrderBillMapper; +import com.ruoyi.system.service.TOrderBillService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * <p> + * 订单表与账单的关联表 服务实现类 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +@Service +public class TOrderBillServiceImpl extends ServiceImpl<TOrderBillMapper, TOrderBill> implements TOrderBillService { + +} diff --git a/generator/src/main/java/com/ruoyi/system/service/impl/TPayOrderServiceImpl.java b/generator/src/main/java/com/ruoyi/system/service/impl/TPayOrderServiceImpl.java new file mode 100644 index 0000000..e7941bb --- /dev/null +++ b/generator/src/main/java/com/ruoyi/system/service/impl/TPayOrderServiceImpl.java @@ -0,0 +1,20 @@ +package com.ruoyi.system.service.impl; + +import com.ruoyi.system.model.TPayOrder; +import com.ruoyi.system.mapper.TPayOrderMapper; +import com.ruoyi.system.service.TPayOrderService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + * <p> + * 支付订单表 服务实现类 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +@Service +public class TPayOrderServiceImpl extends ServiceImpl<TPayOrderMapper, TPayOrder> implements TPayOrderService { + +} diff --git a/generator/src/main/resources/mapping/TBankFlowMapper.xml b/generator/src/main/resources/mapping/TBankFlowMapper.xml new file mode 100644 index 0000000..61d5859 --- /dev/null +++ b/generator/src/main/resources/mapping/TBankFlowMapper.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.system.mapper.TBankFlowMapper"> + + <!-- 通用查询映射结果 --> + <resultMap id="BaseResultMap" type="com.ruoyi.system.model.TBankFlow"> + <id column="id" property="id" /> + <result column="bank_serial_number" property="bankSerialNumber" /> + <result column="flow_money" property="flowMoney" /> + <result column="deduction_money" property="deductionMoney" /> + <result column="remaining_money" property="remainingMoney" /> + <result column="pay_time" property="payTime" /> + <result column="payer" property="payer" /> + <result column="flow_status" property="flowStatus" /> + <result column="pay_type" property="payType" /> + <result column="payment_bill_id" property="paymentBillId" /> + <result column="create_time" property="createTime" /> + <result column="update_time" property="updateTime" /> + <result column="create_by" property="createBy" /> + <result column="update_by" property="updateBy" /> + <result column="disabled" property="disabled" /> + </resultMap> + + <!-- 通用查询结果列 --> + <sql id="Base_Column_List"> + id, bank_serial_number, flow_money, deduction_money, remaining_money, pay_time, payer, flow_status, pay_type, payment_bill_id, create_time, update_time, create_by, update_by, disabled + </sql> + +</mapper> diff --git a/generator/src/main/resources/mapping/TOrderBillMapper.xml b/generator/src/main/resources/mapping/TOrderBillMapper.xml new file mode 100644 index 0000000..a0338ce --- /dev/null +++ b/generator/src/main/resources/mapping/TOrderBillMapper.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.system.mapper.TOrderBillMapper"> + + <!-- 通用查询映射结果 --> + <resultMap id="BaseResultMap" type="com.ruoyi.system.model.TOrderBill"> + <id column="id" property="id" /> + <result column="order_no" property="orderNo" /> + <result column="bill_id" property="billId" /> + <result column="create_time" property="createTime" /> + <result column="update_time" property="updateTime" /> + </resultMap> + + <!-- 通用查询结果列 --> + <sql id="Base_Column_List"> + id, order_no, bill_id, create_time, update_time + </sql> + +</mapper> diff --git a/generator/src/main/resources/mapping/TPayOrderMapper.xml b/generator/src/main/resources/mapping/TPayOrderMapper.xml new file mode 100644 index 0000000..4f6a2e7 --- /dev/null +++ b/generator/src/main/resources/mapping/TPayOrderMapper.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.system.mapper.TPayOrderMapper"> + + <!-- 通用查询映射结果 --> + <resultMap id="BaseResultMap" type="com.ruoyi.system.model.TPayOrder"> + <id column="id" property="id" /> + <result column="user_id" property="userId" /> + <result column="user_name" property="userName" /> + <result column="open_id" property="openId" /> + <result column="phone" property="phone" /> + <result column="amount" property="amount" /> + <result column="act_pay_amount" property="actPayAmount" /> + <result column="pay_time" property="payTime" /> + <result column="pay_type" property="payType" /> + <result column="pay_info" property="payInfo" /> + <result column="pay_no" property="payNo" /> + <result column="callback_time" property="callbackTime" /> + <result column="create_time" property="createTime" /> + <result column="update_time" property="updateTime" /> + </resultMap> + + <!-- 通用查询结果列 --> + <sql id="Base_Column_List"> + id, user_id, user_name, open_id, phone, amount, act_pay_amount, pay_time, pay_type, pay_info, pay_no, callback_time, create_time, update_time + </sql> + +</mapper> diff --git a/generator/src/test/java/com/xizang/CodeGeneratorTests.java b/generator/src/test/java/com/xizang/CodeGeneratorTests.java index 1a91271..eae6969 100644 --- a/generator/src/test/java/com/xizang/CodeGeneratorTests.java +++ b/generator/src/test/java/com/xizang/CodeGeneratorTests.java @@ -35,7 +35,7 @@ // 全局配置 GlobalConfig gc = new GlobalConfig(); - String projectPath = "F:\\workSpace\\xizang\\generator"; + String projectPath = "D:\\畅云\\项目\\xizangweb\\xizang\\generator"; gc.setOutputDir(projectPath + "/src/main/java") .setAuthor("xiaochen") .setMapperName("%sMapper") @@ -144,7 +144,7 @@ // strategy.setTablePrefix(pc.getModuleName() + ""); // strategy.setLikeTable(new LikeTable("room")); //strategy.setLikeTable(new LikeTable("member")); - strategy.setLikeTable(new LikeTable("t_"));// 生成表名 + strategy.setLikeTable(new LikeTable("t_bank_flow"));// 生成表名 // strategy.setLikeTable(new LikeTable("t_hotel"));// 生成表名 // strategy.setLikeTable(new LikeTable("t_scan_message"));// 生成表名 // strategy.setNotLikeTable(new LikeTable("hotel_info"));// 不生成表名 diff --git a/pom.xml b/pom.xml index a5aa325..0bcee27 100644 --- a/pom.xml +++ b/pom.xml @@ -187,6 +187,7 @@ <module>ruoyi-generator</module> <module>ruoyi-common</module> <module>ruoyi-applet</module> + <module>bankapi</module> </modules> <packaging>pom</packaging> diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 89a6462..3aa3a62 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -16,7 +16,11 @@ </description> <dependencies> - + <dependency> + <groupId>org.taxi591</groupId> + <artifactId>bankapi</artifactId> + <version>1.0.0-SNAPSHOT</version> + </dependency> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> 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 new file mode 100644 index 0000000..8aa5914 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/BankOutController.java @@ -0,0 +1,33 @@ +package com.ruoyi.web.controller.api; + +import com.taxi591.bankapi.dto.CovertPayBackResult; +import com.taxi591.bankapi.service.BankService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; + +@RestController +@RequestMapping("open/bank") +public class BankOutController { + + @Autowired + BankService bankService; + + + @PostMapping(value = "payCallback") + public @ResponseBody String payCallback(HttpServletRequest request){ + CovertPayBackResult result = bankService.covertPayCallBack(request, (billRequest) -> { + + return true; + }); + return result.getBack(); + } + + + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBankFlowController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBankFlowController.java new file mode 100644 index 0000000..46bf97f --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBankFlowController.java @@ -0,0 +1,43 @@ +package com.ruoyi.web.controller.api; + + +import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.model.TBankFlow; +import com.ruoyi.system.model.TFlowManagement; +import com.ruoyi.system.query.TBankFlowQuery; +import com.ruoyi.system.query.TFlowManagementQuery; +import com.ruoyi.system.service.TBankFlowService; +import com.ruoyi.system.service.TFlowManagementService; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +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; + +/** + * <p> + * 流水管理 前端控制器 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +@RestController +@RequestMapping("/t-bank-flow") +public class TBankFlowController { + @Autowired + private TBankFlowService flowService; + /** + * 获取流水列表 + */ + @PreAuthorize("@ss.hasPermi('system:bankFlow:list')") + @ApiOperation(value = "获取银行流水列表") + @PostMapping("/list") + public R<PageInfo<TBankFlow>> list(@RequestBody TBankFlowQuery query) { + return R.ok(flowService.pageList(query)); + } +} + diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java index dba1a39..a922d24 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TBillController.java @@ -1,6 +1,15 @@ package com.ruoyi.web.controller.api; +import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.dto.TBillDto; +import com.ruoyi.system.model.TBill; +import com.ruoyi.system.query.TBillQuery; +import com.ruoyi.system.service.TBillService; +import org.springframework.beans.factory.annotation.Autowired; +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; @@ -16,5 +25,15 @@ @RequestMapping("/t-bill") public class TBillController { + @Autowired + TBillService tBillService; + + @PostMapping("list") + public R<PageInfo<TBillDto>> list(@RequestBody TBillQuery query){ + PageInfo<TBillDto> pageInfo = tBillService.queryPage(query); + return R.ok(pageInfo); + } + + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFlowManagementController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFlowManagementController.java index 3b98ead..652d417 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFlowManagementController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TFlowManagementController.java @@ -1,6 +1,16 @@ package com.ruoyi.web.controller.api; +import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.model.TFlowManagement; +import com.ruoyi.system.query.TFlowManagementQuery; +import com.ruoyi.system.service.TFlowManagementService; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +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; @@ -16,6 +26,18 @@ @RestController @RequestMapping("/t-flow-management") public class TFlowManagementController { + @Autowired + private TFlowManagementService flowService; + /** + * 获取流水列表 + */ + @PreAuthorize("@ss.hasPermi('system:flow:list')") + @ApiOperation(value = "获取流水列表") + @PostMapping("/list") + public R<PageInfo<TFlowManagement>> list(@RequestBody TFlowManagementQuery query) { + return R.ok(flowService.pageList(query)); + } + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TInvoiceController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TInvoiceController.java index b6f8562..72f9fb4 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TInvoiceController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TInvoiceController.java @@ -1,9 +1,17 @@ package com.ruoyi.web.controller.api; -import org.springframework.web.bind.annotation.RequestMapping; - -import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.system.model.TInvoice; +import com.ruoyi.system.query.TInvoiceQuery; +import com.ruoyi.system.service.TInvoiceService; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; /** * <p> @@ -16,6 +24,22 @@ @RestController @RequestMapping("/t-invoice") public class TInvoiceController { + @Autowired + private TInvoiceService invoiceService; + @PreAuthorize("@ss.hasPermi('system:invoice:list')") + @ApiOperation(value = "获取开票列表") + @PostMapping("/list") + public R<PageInfo<TInvoice>> list(@RequestBody TInvoiceQuery query) { + return R.ok(invoiceService.pageList(query)); + } + + @PreAuthorize("@ss.hasPermi('system:invoice:delete')") + @Log(title = "开票信息-删除开票", businessType = BusinessType.DELETE) + @ApiOperation(value = "删除开票") + @DeleteMapping(value = "/deleteById") + public R<Boolean> deleteById(@RequestParam String id) { + return R.ok(invoiceService.removeById(id)); + } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/task/TbillTask.java b/ruoyi-admin/src/main/java/com/ruoyi/web/task/TbillTask.java new file mode 100644 index 0000000..bfb5688 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/task/TbillTask.java @@ -0,0 +1,135 @@ +package com.ruoyi.web.task; + +import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.system.model.TBill; +import com.ruoyi.system.model.TContract; +import com.ruoyi.system.query.TBillQuery; +import com.ruoyi.system.query.TContractQuery; +import com.ruoyi.system.service.TBillService; +import com.ruoyi.system.service.TContractService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; + +@Slf4j +@Component("billTask") +public class TbillTask { + + @Autowired + TBillService tBillService; + + @Autowired + TContractService tContractService; + + public void generateBill(){ + try { + int index = 1; + int rows = 20; + long pages = 0; + TContractQuery query = new TContractQuery(); + query.setPageSize(rows); + query.setStatus(4); + Calendar c = Calendar.getInstance(); + Date time = c.getTime(); + do { + query.setPageNum(index); + PageInfo<TContract> pageinfo = tContractService.contractList(query); + if (pages==0){ + pages = pageinfo.getPages(); + } + if (pageinfo.getRecords()!=null && pageinfo.getRecords().size()>0){ + pageinfo.getRecords().forEach(tContract -> { + + //todo 生成账单 + + }); + + } + index++; + }while (index<=pages); + }catch (Exception e){ + log.error(""); + } + + } + + /** + * 判断账单是否到期 + */ + public void checkBillOverdue(){ + try { + int index = 1; + int rows = 20; + long pages = 0; + TBillQuery query = new TBillQuery(); + query.setPageSize(rows); + //查询未缴费的 + query.setPayFeesStatus(1); + Calendar c = Calendar.getInstance(); + Date time = c.getTime(); + do { + query.setPageNum(index); + PageInfo<TBill> pageinfo = tBillService.queryPage(query); + if (pages==0){ + pages = pageinfo.getPages(); + } + if (pageinfo.getRecords()!=null && pageinfo.getRecords().size()>0){ + pageinfo.getRecords().forEach(tBill -> { + + //todo 生成账单 + + }); + + } + index++; + }while (index<=pages); + }catch (Exception e){ + log.error(""); + } + + } + + + /** + * 计算违约金 + */ + public void caculatePenaltyFee(){ + try { + int index = 1; + int rows = 20; + long pages = 0; + TBillQuery query = new TBillQuery(); + query.setPageSize(rows); + //查询已逾期的 + query.setPayFeesStatus(4); + Calendar c = Calendar.getInstance(); + Date time = c.getTime(); + do { + query.setPageNum(index); + PageInfo<TContract> pageinfo = tContractService.contractList(query); + if (pages==0){ + pages = pageinfo.getPages(); + } + if (pageinfo.getRecords()!=null && pageinfo.getRecords().size()>0){ + pageinfo.getRecords().forEach(tContract -> { + + //todo 生成账单 + + }); + + } + index++; + }while (index<=pages); + }catch (Exception e){ + log.error(""); + } + + } + + + +} diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml index 027c4d6..caf8b52 100644 --- a/ruoyi-admin/src/main/resources/application-prod.yml +++ b/ruoyi-admin/src/main/resources/application-prod.yml @@ -21,7 +21,7 @@ port: 8081 servlet: # 应用的访问路径 - context-path: / + context-path: /admin tomcat: # tomcat的URI编码 uri-encoding: UTF-8 diff --git a/ruoyi-admin/src/main/resources/application-test.yml b/ruoyi-admin/src/main/resources/application-test.yml index 4ca4b21..e30bce7 100644 --- a/ruoyi-admin/src/main/resources/application-test.yml +++ b/ruoyi-admin/src/main/resources/application-test.yml @@ -21,7 +21,7 @@ port: 8081 servlet: # 应用的访问路径 - context-path: / + context-path: /admin tomcat: # tomcat的URI编码 uri-encoding: UTF-8 diff --git a/ruoyi-applet/pom.xml b/ruoyi-applet/pom.xml index 6c75435..f18e8ca 100644 --- a/ruoyi-applet/pom.xml +++ b/ruoyi-applet/pom.xml @@ -16,7 +16,11 @@ </description> <dependencies> - + <dependency> + <groupId>org.taxi591</groupId> + <artifactId>bankapi</artifactId> + <version>1.0.0-SNAPSHOT</version> + </dependency> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> diff --git a/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/PayController.java b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/PayController.java new file mode 100644 index 0000000..12cf9b6 --- /dev/null +++ b/ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/PayController.java @@ -0,0 +1,35 @@ +package com.ruoyi.web.controller.api; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.system.dto.MakeOrderDto; +import com.ruoyi.system.dto.MakeOrderResp; +import com.ruoyi.system.service.TPayOrderService; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/t-pay") +public class PayController { + + + + @Autowired + TPayOrderService tPayOrderService; + + @ApiOperation(value = "创建支付订单") + @PostMapping("makeOrder") + public R<MakeOrderResp> makeOrder(@Validated @RequestBody MakeOrderDto dto){ + MakeOrderResp resp = tPayOrderService.makeOrder(dto); + return R.ok(resp); + } + + + + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/AmountConstant.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/AmountConstant.java new file mode 100644 index 0000000..64c916f --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/AmountConstant.java @@ -0,0 +1,15 @@ +package com.ruoyi.common.constant; + +import java.math.BigDecimal; + +public class AmountConstant { + + public static final BigDecimal b100 = new BigDecimal("100"); + + public static final BigDecimal b1000 = new BigDecimal("1000"); + + public static final BigDecimal b001 = new BigDecimal("0.01"); + + + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/WxConstant.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/WxConstant.java index b2e4e1a..3e54fb9 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/WxConstant.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/WxConstant.java @@ -16,4 +16,7 @@ * 高德地图坐标转换 */ public static final String ADDRESS_CONVERT_TO_COORDINATE = "https://restapi.amap.com/v3/geocode/geo?key=KEY&address=ADDRESS"; + + + } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/OrderNos.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/OrderNos.java new file mode 100644 index 0000000..8a80490 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/OrderNos.java @@ -0,0 +1,164 @@ +package com.ruoyi.common.utils; + +import com.ruoyi.common.utils.ip.IpUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.atomic.AtomicLong; + +public class OrderNos { + + public static final char PADCHAR = '0'; + + + + /** + * 长度24位全球唯一标识 + */ + + /** + * 统一不重复内部订单号 + * + * @param systemCode + * 4字节系统编码 + * @return 24字节不重复编码 + */ + public static String oid(String systemCode) { + StringBuilder sb = new StringBuilder(); + sb.append(padding(systemCode, 4)); + sb.append(Did.getInstance().getId(20)); + return sb.toString(); + } + + public static String oid() { + return oid("O001"); + } + + /** + * 获取分布式Id + * + * @return 默认20字符长度的数字不重复编码 + */ + public static String getDid() { + return Did.getInstance().getId(); + } + + public static String getDid(int size) { + return Did.getInstance().getId(size); + } + + public static String getDid(String prefix) { + return prefix + Did.getInstance().getId(); + } + + private static String padding(String text, int size) { + String txt = StringUtils.trimToEmpty(text); + if (StringUtils.length(txt) > size) { + txt = StringUtils.substring(txt, StringUtils.length(txt) - size); + } + return StringUtils.leftPad(txt, size, PADCHAR); + } + + /** + * ID生成器 + * + * 20字符长度 yyMMddHHmmss+3位本机IP末三位+5位随机数字 + * + * @author zhangpu + * + */ + public static class Did { + private static final Logger logger = LoggerFactory.getLogger(OrderNos.class); + private static final int MIN_LENGTH = 19; + private static final int SEQU_MAX = 99999; + private static final int SEQU_19_MAX = 9999; + private volatile static long BASE = 0; + private AtomicLong sequence = new AtomicLong(0); + private String nodeFlag; + private Object nodeFlagLock = new Object(); + private static Did did = new Did(); + + + public static Did getInstance() { + return did; + } + + /** + * 生产新Id + * + * @return + */ + public String getId() { + return getId(20); + } + + public String getId(int size) { + if (size < MIN_LENGTH) { + throw new RuntimeException("did最小长度为" + MIN_LENGTH); + } + StringBuilder sb = new StringBuilder(); + sb.append(DateUtils.dateTimeNow("yyMMddHHmmss")); + sb.append(getNodeFlag()); + sb.append(getSequ(size-15)); + return sb.toString(); + } + + public synchronized String getSequ(int size) { + long timeCount = System.currentTimeMillis() / 1000; + + while (true) { + long now = sequence.get(); + if (timeCount > now) { + // 已经过了本秒,则设置新的值 + if (sequence.compareAndSet(now, timeCount)) { + break; + } + } else { + if (sequence.compareAndSet(now, now + 1)) { + timeCount = now + 1; + break; + } + } + } + int sn = (int) (timeCount % (size>=5?SEQU_MAX:SEQU_19_MAX)); + return StringUtils.leftPad(String.valueOf(sn), size, '0'); + } + + private String getNodeFlag(){ + if (this.nodeFlag == null) { + synchronized (Did.class){ + if (this.nodeFlag==null){ + this.nodeFlag = generateNodeFlag(); + } + } + } + return this.nodeFlag; + } + + /** + * 简单节点编码 + * + * 逻辑:Ip地址后三位,便于快速知道是哪个节点 + * + * @return + */ + private String generateNodeFlag() { + String ipPostfix = null; + try { + String ip = IpUtils.getFirstNoLoopbackIPV4Address(); + ipPostfix = StringUtils.substringAfterLast(ip, "."); + } catch (Exception e) { + logger.warn("生产DID要素本机IP获取失败:" + e.getMessage()); + } + return StringUtils.leftPad(ipPostfix, 3, "0"); + } + + private Did() { + super(); + } + } + + + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java index 8e89e30..8874697 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java @@ -1,16 +1,20 @@ package com.ruoyi.common.utils.ip; -import java.net.InetAddress; -import java.net.UnknownHostException; +import java.net.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; import javax.servlet.http.HttpServletRequest; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.StringUtils; +import lombok.extern.slf4j.Slf4j; /** * 获取IP方法 * * @author ruoyi */ +@Slf4j public class IpUtils { public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)"; @@ -379,4 +383,72 @@ } return false; } + + + private static final String LOOP_BACK = "127.0.0.1"; + private static String firstNoLoopbackIPV4Address = null; + + private static Collection<InetAddress> allHostIPV4Address = null; + /** + * 获取ipv4地址,如果有多个网卡的情况,获取第一个非loopback ip地址 + * + * @return + */ + public static String getFirstNoLoopbackIPV4Address() { + if (firstNoLoopbackIPV4Address != null) { + return firstNoLoopbackIPV4Address; + } + Collection<String> allNoLoopbackAddresses = null; + try { + allNoLoopbackAddresses = getAllNoLoopbackIPV4Addresses(); + } catch (Exception e) { + log.error("获取ip失败", e); + return LOOP_BACK; + } + if (allNoLoopbackAddresses.isEmpty()) { + return LOOP_BACK; + } + + return firstNoLoopbackIPV4Address = allNoLoopbackAddresses.iterator().next(); + } + + + public static Collection<String> getAllNoLoopbackIPV4Addresses() { + Collection<String> noLoopbackAddresses = new ArrayList<String>(); + Collection<InetAddress> allInetAddresses = getAllHostIPV4Address(); + + for (InetAddress address : allInetAddresses) { + if (!address.isLoopbackAddress()) { + noLoopbackAddresses.add(address.getHostAddress()); + } + } + + return noLoopbackAddresses; + } + + public static Collection<InetAddress> getAllHostIPV4Address() { + if (allHostIPV4Address == null) { + try { + Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces(); + Collection<InetAddress> addresses = new ArrayList<InetAddress>(); + + while (networkInterfaces.hasMoreElements()) { + NetworkInterface networkInterface = networkInterfaces.nextElement(); + Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses(); + while (inetAddresses.hasMoreElements()) { + InetAddress inetAddress = inetAddresses.nextElement(); + if (inetAddress instanceof Inet4Address) { + addresses.add(inetAddress); + } + } + } + allHostIPV4Address = addresses; + } catch (SocketException e) { + log.error("获取ip地址失败", e); + throw new RuntimeException(e.getMessage(), e); + } + + } + return allHostIPV4Address; + } } \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java index 27273cf..0c89771 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java @@ -1,93 +1,10 @@ package com.ruoyi.common.utils.poi; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.ParameterizedType; -import java.math.BigDecimal; -import java.text.DecimalFormat; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.stream.Collectors; -import javax.servlet.http.HttpServletResponse; - -import com.sun.rowset.internal.Row; -import javafx.scene.control.Cell; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.RegExUtils; -import org.apache.commons.lang3.reflect.FieldUtils; -//import org.apache.poi.hssf.usermodel.HSSFClientAnchor; -//import org.apache.poi.hssf.usermodel.HSSFPicture; -//import org.apache.poi.hssf.usermodel.HSSFPictureData; -//import org.apache.poi.hssf.usermodel.HSSFShape; -//import org.apache.poi.hssf.usermodel.HSSFSheet; -//import org.apache.poi.hssf.usermodel.HSSFWorkbook; -//import org.apache.poi.ooxml.POIXMLDocumentPart; -//import org.apache.poi.ss.usermodel.BorderStyle; -//import org.apache.poi.ss.usermodel.Cell; -//import org.apache.poi.ss.usermodel.CellStyle; -//import org.apache.poi.ss.usermodel.CellType; -//import org.apache.poi.ss.usermodel.ClientAnchor; -//import org.apache.poi.ss.usermodel.DataValidation; -//import org.apache.poi.ss.usermodel.DataValidationConstraint; -//import org.apache.poi.ss.usermodel.DataValidationHelper; -//import org.apache.poi.ss.usermodel.DateUtil; -//import org.apache.poi.ss.usermodel.Drawing; -//import org.apache.poi.ss.usermodel.FillPatternType; -//import org.apache.poi.ss.usermodel.Font; -//import org.apache.poi.ss.usermodel.HorizontalAlignment; -//import org.apache.poi.ss.usermodel.IndexedColors; -//import org.apache.poi.ss.usermodel.Name; -//import org.apache.poi.ss.usermodel.PictureData; -//import org.apache.poi.ss.usermodel.Row; -//import org.apache.poi.ss.usermodel.Sheet; -//import org.apache.poi.ss.usermodel.VerticalAlignment; -//import org.apache.poi.ss.usermodel.Workbook; -//import org.apache.poi.ss.usermodel.WorkbookFactory; -//import org.apache.poi.ss.util.CellRangeAddress; -//import org.apache.poi.ss.util.CellRangeAddressList; -//import org.apache.poi.util.IOUtils; -//import org.apache.poi.xssf.streaming.SXSSFWorkbook; -//import org.apache.poi.xssf.usermodel.XSSFClientAnchor; -//import org.apache.poi.xssf.usermodel.XSSFDataValidation; -//import org.apache.poi.xssf.usermodel.XSSFDrawing; -//import org.apache.poi.xssf.usermodel.XSSFPicture; -//import org.apache.poi.xssf.usermodel.XSSFShape; -//import org.apache.poi.xssf.usermodel.XSSFSheet; -//import org.apache.poi.xssf.usermodel.XSSFWorkbook; -//import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -//import com.ruoyi.common.annotation.Excel; -//import com.ruoyi.common.annotation.Excel.ColumnType; -//import com.ruoyi.common.annotation.Excel.Type; -import com.ruoyi.common.annotation.Excels; -import com.ruoyi.common.config.RuoYiConfig; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.text.Convert; -import com.ruoyi.common.exception.UtilException; -import com.ruoyi.common.utils.DateUtils; -import com.ruoyi.common.utils.DictUtils; -import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.common.utils.file.FileTypeUtils; -import com.ruoyi.common.utils.file.FileUtils; -import com.ruoyi.common.utils.file.ImageUtils; -import com.ruoyi.common.utils.reflect.ReflectUtils; + +import java.util.HashMap; +import java.util.Map; /** * Excel相关处理 diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java index 972e404..1a4e0fa 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java @@ -111,8 +111,15 @@ // 过滤请求 .authorizeRequests() // 对于登录login 注册register 验证码captchaImage 允许匿名访问 - .antMatchers("/getPrivacyAgreement/{agreementType}","/applet/queryProtocolConfigByType","/applet/login","/login","/applet/queryProtocolConfigByType", "/register","/applet/getCode","/applet/loginCode","/applet/changepwd", "/captchaImage","/getCode","/loginCode","/operations/getBySingleNum/**", - "/user/getUserInfoByNumber/**").permitAll() + .antMatchers("/getPrivacyAgreement/{agreementType}", + "/applet/queryProtocolConfigByType","/applet/login", + "/login","/applet/queryProtocolConfigByType", + "/register","/applet/getCode","/applet/loginCode", + "/applet/changepwd", "/captchaImage","/getCode","/loginCode", + "/operations/getBySingleNum/**", + "/user/getUserInfoByNumber/**", + "/open/**" + ).permitAll() // 静态资源,可匿名访问 .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() .antMatchers("/swagger-ui.html","/doc.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java index 853243b..b03ebb3 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java @@ -25,4 +25,10 @@ { System.out.println("执行无参方法"); } + + + + + + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/dto/MakeOrderDto.java b/ruoyi-system/src/main/java/com/ruoyi/system/dto/MakeOrderDto.java new file mode 100644 index 0000000..f8a68e5 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/dto/MakeOrderDto.java @@ -0,0 +1,38 @@ +package com.ruoyi.system.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.List; + +@Data +@ApiModel(value = "使用账单创建订单请求") +public class MakeOrderDto implements Serializable { + /** + * 用户ID + */ + @ApiModelProperty(value = "用户ID") + @NotBlank(message = "用户ID不能为空") + private String userId; + /** + * 用户openid + */ + @ApiModelProperty(value = "用户微信或支付宝openid") + private String openId; + + @ApiModelProperty(value = "支付金额,单位:分") + @NotNull(message = "用户ID不能为空") + private Long amount; + + @ApiModelProperty(value = "账单ID列表",notes = "如果只有1个账单ID,金额可以小于账单金额,进行部分缴费;如果是多个账单,将会核对金额,未交费金额需要与缴费金额一致") + @NotEmpty(message = "用户ID不能为空") + private List<String> billIds; + + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/dto/MakeOrderResp.java b/ruoyi-system/src/main/java/com/ruoyi/system/dto/MakeOrderResp.java new file mode 100644 index 0000000..a772713 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/dto/MakeOrderResp.java @@ -0,0 +1,23 @@ +package com.ruoyi.system.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +@Data +@ApiModel(value = "使用账单创建订单请求") +public class MakeOrderResp implements Serializable { + /** + * 订单编号 + */ + @ApiModelProperty("订单编号") + private String orderNo; + @ApiModelProperty("金额,分") + private Long amount; + @ApiModelProperty("微信小程序支付跳转链接,用于生成二维码") + private String appletUrl; + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/dto/TBillDto.java b/ruoyi-system/src/main/java/com/ruoyi/system/dto/TBillDto.java new file mode 100644 index 0000000..fa60266 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/dto/TBillDto.java @@ -0,0 +1,17 @@ +package com.ruoyi.system.dto; + +import com.ruoyi.system.model.TBill; +import lombok.Data; + +import java.util.List; + +@Data +public class TBillDto extends TBill { + + private String residentName; + + private String phone; + + private String account; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBankFlowMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBankFlowMapper.java new file mode 100644 index 0000000..0bf605c --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBankFlowMapper.java @@ -0,0 +1,16 @@ +package com.ruoyi.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.system.model.TBankFlow; + +/** + * <p> + * 流水管理 Mapper 接口 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +public interface TBankFlowMapper extends BaseMapper<TBankFlow> { + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java index f89dd32..ab6c3dc 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TBillMapper.java @@ -1,7 +1,12 @@ package com.ruoyi.system.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.system.dto.TBillDto; import com.ruoyi.system.model.TBill; +import com.ruoyi.system.query.TBillQuery; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; /** * <p> @@ -13,4 +18,6 @@ */ public interface TBillMapper extends BaseMapper<TBill> { + PageInfo<TBillDto> page(@Param("pageInfo") PageInfo<TBill> pageInfo, @Param("query") TBillQuery query); + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TOrderBillMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TOrderBillMapper.java new file mode 100644 index 0000000..7f1f170 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TOrderBillMapper.java @@ -0,0 +1,16 @@ +package com.ruoyi.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.system.model.TOrderBill; + +/** + * <p> + * 订单表与账单的关联表 Mapper 接口 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +public interface TOrderBillMapper extends BaseMapper<TOrderBill> { + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TPayOrderMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TPayOrderMapper.java new file mode 100644 index 0000000..0bc6f9d --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/TPayOrderMapper.java @@ -0,0 +1,16 @@ +package com.ruoyi.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.system.model.TPayOrder; + +/** + * <p> + * 支付订单表 Mapper 接口 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +public interface TPayOrderMapper extends BaseMapper<TPayOrder> { + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TBankFlow.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TBankFlow.java new file mode 100644 index 0000000..30e499d --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TBankFlow.java @@ -0,0 +1,90 @@ +package com.ruoyi.system.model; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * <p> + * 流水管理 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("t_bank_flow") +@ApiModel(value="TBankFlow对象", description="流水管理") +public class TBankFlow implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId("id") + private String id; + + @ApiModelProperty(value = "银行流水号") + @TableField("bank_serial_number") + private String bankSerialNumber; + + @ApiModelProperty(value = "流水金额") + @TableField("flow_money") + private Double flowMoney; + + @ApiModelProperty(value = "抵扣金额") + @TableField("deduction_money") + private Double deductionMoney; + + @ApiModelProperty(value = "剩余金额") + @TableField("remaining_money") + private Double remainingMoney; + + @ApiModelProperty(value = "支付时间") + @TableField("pay_time") + private LocalDateTime payTime; + + @ApiModelProperty(value = "付款人") + @TableField("payer") + private String payer; + + @ApiModelProperty(value = "流水状态 1=正常 2=异常") + @TableField("flow_status") + private Integer flowStatus; + + @ApiModelProperty(value = "支付方式 1=微信支付 2=支付宝支付 3=线下支付") + @TableField("pay_type") + private Integer payType; + + @ApiModelProperty(value = "缴费账单id") + @TableField("payment_bill_id") + private String paymentBillId; + + @ApiModelProperty(value = "创建时间") + @TableField("create_time") + private LocalDateTime createTime; + + @ApiModelProperty(value = "修改时间") + @TableField("update_time") + private LocalDateTime updateTime; + + @ApiModelProperty(value = "创建人") + @TableField("create_by") + private String createBy; + + @ApiModelProperty(value = "修改人") + @TableField("update_by") + private String updateBy; + + @ApiModelProperty(value = "是否删除 0=否 1=是") + @TableField("disabled") + private Integer disabled; + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TOrderBill.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TOrderBill.java new file mode 100644 index 0000000..4390921 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TOrderBill.java @@ -0,0 +1,54 @@ +package com.ruoyi.system.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * <p> + * 订单表与账单的关联表 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = false) +@TableName("t_order_bill") +@ApiModel(value="TOrderBill对象", description="订单表与账单的关联表") +public class TOrderBill implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.ASSIGN_ID) + private String id; + + @ApiModelProperty(value = "订单号") + @TableField("order_no") + private String orderNo; + + @ApiModelProperty(value = "账单编号") + @TableField("bill_id") + private String billId; + + @TableField("create_time") + private LocalDateTime createTime; + + @TableField("update_time") + private LocalDateTime updateTime; + + public TOrderBill(String orderNo, String billId) { + this.orderNo = orderNo; + this.billId = billId; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/model/TPayOrder.java b/ruoyi-system/src/main/java/com/ruoyi/system/model/TPayOrder.java new file mode 100644 index 0000000..a161f9f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/model/TPayOrder.java @@ -0,0 +1,88 @@ +package com.ruoyi.system.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * <p> + * 支付订单表 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("t_pay_order") +@ApiModel(value="TPayOrder对象", description="支付订单表") +public class TPayOrder implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "订单号") + @TableId("id") + private String id; + + @ApiModelProperty(value = "发起支付的用户ID") + @TableField("user_id") + private String userId; + + @ApiModelProperty(value = "用户名称") + @TableField("user_name") + private String userName; + + @ApiModelProperty(value = "用户微信openid或支付宝userid") + @TableField("open_id") + private String openId; + + @ApiModelProperty(value = "用户手机号码") + @TableField("phone") + private String phone; + + @ApiModelProperty(value = "订单金额") + @TableField("amount") + private Long amount; + + @ApiModelProperty(value = "实付金额") + @TableField("act_pay_amount") + private Long actPayAmount; + + @ApiModelProperty(value = "支付时间") + @TableField("pay_time") + private LocalDateTime payTime; + + @ApiModelProperty(value = "支付方式") + @TableField("pay_type") + private String payType; + + @ApiModelProperty(value = "支付的回调信息") + @TableField("pay_info") + private String payInfo; + + @ApiModelProperty(value = "银行的支付流水编号") + @TableField("pay_no") + private String payNo; + + @ApiModelProperty(value = "支付的回调时间") + @TableField("callback_time") + private LocalDateTime callbackTime; + + @ApiModelProperty(value = "订单创建时间") + @TableField("create_time") + private LocalDateTime createTime; + + @ApiModelProperty(value = "订单更新时间") + @TableField("update_time") + private LocalDateTime updateTime; + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/TBankFlowQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/TBankFlowQuery.java new file mode 100644 index 0000000..ae33250 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/TBankFlowQuery.java @@ -0,0 +1,60 @@ +package com.ruoyi.system.query; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.core.domain.BasePage; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * <p> + * 流水管理 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +@Data +@ApiModel(value="银行流水列表query") +public class TBankFlowQuery extends BasePage { + + @ApiModelProperty(value = "银行流水号") + private String bankSerialNumber; + + @ApiModelProperty(value = "流水金额") + private Double flowMoney; + + @ApiModelProperty(value = "抵扣金额") + private Double deductionMoney; + + @ApiModelProperty(value = "剩余金额") + private Double remainingMoney; + + @ApiModelProperty(value = "支付时间") + private LocalDateTime payTime; + + @ApiModelProperty(value = "付款人") + private String payer; + + @ApiModelProperty(value = "流水状态 1=正常 2=异常") + private Integer flowStatus; + + @ApiModelProperty(value = "支付方式 1=微信支付 2=支付宝支付 3=线下支付") + private Integer payType; + + @ApiModelProperty(value = "缴费账单id") + private String paymentBillId; + + @ApiModelProperty(value = "支付开始时间") + private String payStartTime; + + @ApiModelProperty(value = "支付结束时间") + private String payEndTime; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/TBillQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/TBillQuery.java index b6302c6..b43c565 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/query/TBillQuery.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/TBillQuery.java @@ -1,15 +1,21 @@ package com.ruoyi.system.query; import com.ruoyi.common.core.domain.BasePage; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data -@ApiModel(value = "账单查询对象query") public class TBillQuery extends BasePage { + /** + * 缴费状态 1=未缴费 2=待确认 3=已缴费 4=已逾期 + */ + private Integer payFeesStatus; - @ApiModelProperty(value = "缴费状态 1=未缴费 2=待确认 3=已缴费 4=已逾期 5=已失效") - private String payFeesStatus; + private String phone; + + private String residentName; + + private String contractNumber; + + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/TFlowManagementQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/TFlowManagementQuery.java new file mode 100644 index 0000000..19fd59f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/TFlowManagementQuery.java @@ -0,0 +1,63 @@ +package com.ruoyi.system.query; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.core.domain.BasePage; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * <p> + * 流水管理 + * </p> + * + * @author xiaochen + * @since 2025-01-20 + */ +@Data +@ApiModel(value="流水列表query") +public class TFlowManagementQuery extends BasePage { + + @ApiModelProperty(value = "系统流水号") + private String sysSerialNumber; + + @ApiModelProperty(value = "银行流水号") + private String bankSerialNumber; + + @ApiModelProperty(value = "流水金额") + private BigDecimal flowMoney; + + @ApiModelProperty(value = "抵扣金额") + private BigDecimal deductionMoney; + + @ApiModelProperty(value = "剩余金额") + private BigDecimal remainingMoney; + + @ApiModelProperty(value = "支付时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime payTime; + + @ApiModelProperty(value = "付款人") + private String payer; + + @ApiModelProperty(value = "流水状态 1=正常 2=异常") + private Integer flowStatus; + + + @ApiModelProperty(value = "支付方式 1=微信支付 2=支付宝支付 3=线下支付") + private Integer payType; + + @ApiModelProperty(value = "缴费账单id") + private String paymentBillId; + + @ApiModelProperty(value = "支付开始时间") + private String payStartTime; + + @ApiModelProperty(value = "支付结束时间") + private String payEndTime; + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/TInvoiceQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/TInvoiceQuery.java new file mode 100644 index 0000000..108302c --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/TInvoiceQuery.java @@ -0,0 +1,55 @@ +package com.ruoyi.system.query; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.core.domain.BasePage; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + + +@Data +@ApiModel(value="开票查询列表Query") +public class TInvoiceQuery extends BasePage { + @ApiModelProperty(value = "申请编号") + private String invoiceNumber; + + @ApiModelProperty(value = "金额") + private Double invoiceMoney; + + @ApiModelProperty(value = "申请人") + private String applyName; + + @ApiModelProperty(value = "抬头类型 1=企业 2=个人") + private Integer titleType; + + @ApiModelProperty(value = "抬头名称") + private String titleName; + + @ApiModelProperty(value = "税号/身份证号") + private String serialNumber; + + @ApiModelProperty(value = "开票状态 1=待开票 2=已开票") + private Integer status; + + @ApiModelProperty(value = "开票日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private LocalDateTime invoiceTime; + + @ApiModelProperty(value = "开票凭证") + private String invoiceVoucher; + + @ApiModelProperty(value = "邮箱") + private String email; + + @ApiModelProperty(value = "开票合同编号逗号分割") + private String contractNumber; + + @ApiModelProperty(value = "开票开始日期") + private String invoiceStartTime; + + @ApiModelProperty(value = "开票结束日期") + private String invoiceEndTime; + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TBankFlowService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TBankFlowService.java new file mode 100644 index 0000000..6e945d3 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TBankFlowService.java @@ -0,0 +1,26 @@ +package com.ruoyi.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.system.model.TBankFlow; +import com.ruoyi.system.model.TFlowManagement; +import com.ruoyi.system.query.TBankFlowQuery; +import com.ruoyi.system.query.TFlowManagementQuery; + +import java.util.List; + +/** + * <p> + * 流水管理 服务类 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +public interface TBankFlowService extends IService<TBankFlow> { + + PageInfo<TBankFlow> pageList(TBankFlowQuery query); + List<TBankFlow> makeQuery(TBankFlowQuery query); + + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java index 427e596..22feecc 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TBillService.java @@ -2,9 +2,9 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.system.dto.TBillDto; import com.ruoyi.system.model.TBill; import com.ruoyi.system.query.TBillQuery; -import com.ruoyi.system.vo.TBillVO; /** * <p> @@ -16,11 +16,6 @@ */ public interface TBillService extends IService<TBill> { - /** - * 获取账单列表 - * @param query - * @return - */ - PageInfo<TBillVO> pageList(TBillQuery query); + PageInfo<TBillDto> queryPage(TBillQuery query); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TFlowManagementService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TFlowManagementService.java index 39069a5..5560db0 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TFlowManagementService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TFlowManagementService.java @@ -1,7 +1,11 @@ package com.ruoyi.system.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.model.TFlowManagement; +import com.ruoyi.system.query.TFlowManagementQuery; + +import java.util.List; /** * <p> @@ -12,5 +16,9 @@ * @since 2025-01-17 */ public interface TFlowManagementService extends IService<TFlowManagement> { + PageInfo<TFlowManagement> pageList(TFlowManagementQuery query); + List<TFlowManagement> makeQuery(TFlowManagementQuery query); + + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TInvoiceService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TInvoiceService.java index ce2774b..c537efa 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/TInvoiceService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TInvoiceService.java @@ -1,7 +1,11 @@ package com.ruoyi.system.service; import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.common.basic.PageInfo; import com.ruoyi.system.model.TInvoice; +import com.ruoyi.system.query.TInvoiceQuery; + +import java.util.List; /** * <p> @@ -12,5 +16,6 @@ * @since 2025-01-17 */ public interface TInvoiceService extends IService<TInvoice> { - + PageInfo<TInvoice> pageList(TInvoiceQuery query); + List<TInvoice> makeQuery(TInvoiceQuery query); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TOrderBillService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TOrderBillService.java new file mode 100644 index 0000000..8c2e80d --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TOrderBillService.java @@ -0,0 +1,16 @@ +package com.ruoyi.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.system.model.TOrderBill; + +/** + * <p> + * 订单表与账单的关联表 服务类 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +public interface TOrderBillService extends IService<TOrderBill> { + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/TPayOrderService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/TPayOrderService.java new file mode 100644 index 0000000..ccc9c4f --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/TPayOrderService.java @@ -0,0 +1,19 @@ +package com.ruoyi.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.ruoyi.system.dto.MakeOrderDto; +import com.ruoyi.system.dto.MakeOrderResp; +import com.ruoyi.system.model.TPayOrder; + +/** + * <p> + * 支付订单表 服务类 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +public interface TPayOrderService extends IService<TPayOrder> { + + MakeOrderResp makeOrder(MakeOrderDto dto); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBankFlowServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBankFlowServiceImpl.java new file mode 100644 index 0000000..723c203 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TBankFlowServiceImpl.java @@ -0,0 +1,46 @@ +package com.ruoyi.system.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.system.mapper.TBankFlowMapper; +import com.ruoyi.system.model.TBankFlow; +import com.ruoyi.system.model.TFlowManagement; +import com.ruoyi.system.query.TBankFlowQuery; +import com.ruoyi.system.service.TBankFlowService; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * <p> + * 流水管理 服务实现类 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +@Service +public class TBankFlowServiceImpl extends ServiceImpl<TBankFlowMapper, TBankFlow> implements TBankFlowService { + @Override + public PageInfo<TBankFlow> pageList(TBankFlowQuery query) { + PageInfo<TBankFlow> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); + List<TBankFlow> list = makeQuery(query); + pageInfo.setRecords(list); + pageInfo.setTotal(list.size()); + return pageInfo; + } + @Override + public List<TBankFlow> makeQuery(TBankFlowQuery query) { + LambdaQueryWrapper<TBankFlow> queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(StringUtils.isNotEmpty(query.getBankSerialNumber()),TBankFlow::getBankSerialNumber,query.getBankSerialNumber()) + .like(StringUtils.isNotEmpty(query.getPayer()),TBankFlow::getPayer,query.getPayer()) + .ge(StringUtils.isNotEmpty(query.getPayStartTime()),TBankFlow::getPayTime,query.getPayStartTime()) + .lt(StringUtils.isNotEmpty(query.getPayEndTime()),TBankFlow::getPayTime,query.getPayEndTime()) + .eq(null != query.getFlowStatus(),TBankFlow::getFlowStatus,query.getFlowStatus()) + .orderByDesc(TBankFlow::getCreateTime) + ; + return this.baseMapper.selectList(queryWrapper); + } +} 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 da5f143..3a0bdc6 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,13 +1,22 @@ package com.ruoyi.system.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.system.dto.TBillDto; import com.ruoyi.system.mapper.TBillMapper; import com.ruoyi.system.model.TBill; +import com.ruoyi.system.model.TContract; +import com.ruoyi.system.model.THouse; import com.ruoyi.system.query.TBillQuery; import com.ruoyi.system.service.TBillService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.ruoyi.system.vo.TBillVO; +import io.jsonwebtoken.lang.Assert; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; /** * <p> @@ -20,8 +29,30 @@ @Service public class TBillServiceImpl extends ServiceImpl<TBillMapper, TBill> implements TBillService { - @Override - public PageInfo<TBillVO> pageList(TBillQuery query) { - return null; + @Autowired + RedisCache redisCache; + + @Autowired + TBillMapper tBillMapper; + + public PageInfo<TBillDto> queryPage(TBillQuery query){ + PageInfo<TBill> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); + PageInfo<TBillDto> info = tBillMapper.page(pageInfo, query); + return info; } + + + + /** + * 传的金额 + * @param tBill + * @return + */ + public Boolean checkAndUpdateBill(TBill tBill){ + return true; + } + + + + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFlowManagementServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFlowManagementServiceImpl.java index 599e144..f793220 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFlowManagementServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TFlowManagementServiceImpl.java @@ -1,10 +1,16 @@ package com.ruoyi.system.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.mapper.TFlowManagementMapper; import com.ruoyi.system.model.TFlowManagement; +import com.ruoyi.system.query.TFlowManagementQuery; import com.ruoyi.system.service.TFlowManagementService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; + +import java.util.List; /** * <p> @@ -17,4 +23,25 @@ @Service public class TFlowManagementServiceImpl extends ServiceImpl<TFlowManagementMapper, TFlowManagement> implements TFlowManagementService { + @Override + public PageInfo<TFlowManagement> pageList(TFlowManagementQuery query) { + PageInfo<TFlowManagement> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); + List<TFlowManagement> list = makeQuery(query); + pageInfo.setRecords(list); + pageInfo.setTotal(list.size()); + return pageInfo; + } + @Override + public List<TFlowManagement> makeQuery(TFlowManagementQuery query){ + LambdaQueryWrapper<TFlowManagement> queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(StringUtils.isNotEmpty(query.getSysSerialNumber()),TFlowManagement::getSysSerialNumber,query.getSysSerialNumber()) + .eq(StringUtils.isNotEmpty(query.getBankSerialNumber()),TFlowManagement::getBankSerialNumber,query.getBankSerialNumber()) + .like(StringUtils.isNotEmpty(query.getPayer()),TFlowManagement::getPayer,query.getPayer()) + .ge(StringUtils.isNotEmpty(query.getPayStartTime()),TFlowManagement::getPayTime,query.getPayStartTime()) + .lt(StringUtils.isNotEmpty(query.getPayEndTime()),TFlowManagement::getPayTime,query.getPayEndTime()) + .eq(null != query.getFlowStatus(),TFlowManagement::getFlowStatus,query.getFlowStatus()) + .orderByDesc(TFlowManagement::getCreateTime) + ; + return this.baseMapper.selectList(queryWrapper); + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInvoiceServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInvoiceServiceImpl.java index 10b6e5c..b7c307b 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInvoiceServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TInvoiceServiceImpl.java @@ -1,10 +1,16 @@ package com.ruoyi.system.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.basic.PageInfo; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.mapper.TInvoiceMapper; import com.ruoyi.system.model.TInvoice; +import com.ruoyi.system.query.TInvoiceQuery; import com.ruoyi.system.service.TInvoiceService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; + +import java.util.List; /** * <p> @@ -17,4 +23,24 @@ @Service public class TInvoiceServiceImpl extends ServiceImpl<TInvoiceMapper, TInvoice> implements TInvoiceService { + @Override + public PageInfo<TInvoice> pageList(TInvoiceQuery query) { + PageInfo<TInvoice> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); + List<TInvoice> list = makeQuery(query); + pageInfo.setRecords(list); + pageInfo.setTotal(list.size()); + return pageInfo; + } + + @Override + public List<TInvoice> makeQuery(TInvoiceQuery query) { + LambdaQueryWrapper<TInvoice> queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(null != query.getTitleType(),TInvoice::getTitleType,query.getTitleType()) + .like(StringUtils.isNotEmpty(query.getTitleName()),TInvoice::getTitleName,query.getTitleName()) + .eq(null != query.getStatus(),TInvoice::getStatus,query.getStatus()) + .ge(StringUtils.isNotEmpty(query.getInvoiceStartTime()),TInvoice::getInvoiceTime,query.getInvoiceStartTime()) + .le(StringUtils.isNotEmpty(query.getInvoiceEndTime()),TInvoice::getInvoiceTime,query.getInvoiceEndTime()) + .orderByDesc(TInvoice::getCreateTime); + return this.baseMapper.selectList(queryWrapper); + } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TOrderBillServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TOrderBillServiceImpl.java new file mode 100644 index 0000000..287417b --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TOrderBillServiceImpl.java @@ -0,0 +1,20 @@ +package com.ruoyi.system.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.system.mapper.TOrderBillMapper; +import com.ruoyi.system.model.TOrderBill; +import com.ruoyi.system.service.TOrderBillService; +import org.springframework.stereotype.Service; + +/** + * <p> + * 订单表与账单的关联表 服务实现类 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +@Service +public class TOrderBillServiceImpl extends ServiceImpl<TOrderBillMapper, TOrderBill> implements TOrderBillService { + +} 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 new file mode 100644 index 0000000..9237241 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TPayOrderServiceImpl.java @@ -0,0 +1,130 @@ +package com.ruoyi.system.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.ruoyi.common.constant.AmountConstant; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.OrderNos; +import com.ruoyi.system.dto.MakeOrderDto; +import com.ruoyi.system.dto.MakeOrderResp; +import com.ruoyi.system.mapper.TPayOrderMapper; +import com.ruoyi.system.model.TBill; +import com.ruoyi.system.model.TOrderBill; +import com.ruoyi.system.model.TPayOrder; +import com.ruoyi.system.model.TTenant; +import com.ruoyi.system.service.TBillService; +import com.ruoyi.system.service.TOrderBillService; +import com.ruoyi.system.service.TPayOrderService; +import com.ruoyi.system.service.TTenantService; +import org.apache.poi.ss.formula.functions.T; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * <p> + * 支付订单表 服务实现类 + * </p> + * + * @author xiaochen + * @since 2025-02-07 + */ +@Service +public class TPayOrderServiceImpl extends ServiceImpl<TPayOrderMapper, TPayOrder> implements TPayOrderService { + + @Autowired + TBillService billService; + + @Autowired + TTenantService tTenantService; + + @Autowired + TOrderBillService tOrderBillService; + + + public long caculateRentFee(TBill bill){ + return bill.getPayableFeesMoney().add(bill.getPayableFeesPenalty()) + .subtract(bill.getActualMoney()) + .multiply(AmountConstant.b100) + .setScale(0, RoundingMode.HALF_DOWN) + .longValue(); + } + + + public String createAppletUrl(String orderNo){ + return ""+orderNo; + } + + @Override + public MakeOrderResp makeOrder(MakeOrderDto dto) { + + TTenant user = tTenantService.getById(dto.getUserId()); + if (user==null){ + throw new ServiceException("租户不存在"); + } + MakeOrderResp resp = new MakeOrderResp(); + if (dto.getBillIds().size()==1){ + TBill bill = billService.getById(dto.getBillIds().get(0)); + if (bill == null) { + throw new ServiceException("账单不存在"); + } + //计算欠费金额:租金+违约金-实收金额 + long rent = caculateRentFee(bill); + if (rent==0){ + throw new ServiceException("该订单已缴费"); + } + if (rent>dto.getAmount()){ + throw new ServiceException("支付金额超过了账单欠费金额"); + } + + TPayOrder order = new TPayOrder(); + order.setId(OrderNos.getDid(32)); + order.setAmount(dto.getAmount()); + order.setUserId(user.getId()); + order.setPhone(user.getPhone()); + order.setUserName(user.getResidentName()); + save(order); + TOrderBill tOrderBill = new TOrderBill(); + tOrderBill.setBillId(bill.getId()); + tOrderBill.setOrderNo(order.getId()); + tOrderBillService.save(tOrderBill); + resp.setAmount(dto.getAmount()); + resp.setOrderNo(order.getId()); + resp.setAppletUrl(createAppletUrl(order.getId())); + return resp; + } + List<TOrderBill> orderBills = new ArrayList<>(); + String orderNo = OrderNos.getDid(32); + List<TBill> bills = dto.getBillIds().stream().map(id -> { + TBill bill = billService.getById(id); + if (bill == null) { + throw new ServiceException("billId:" + id + "不存在"); + } + orderBills.add(new TOrderBill(orderNo,bill.getId())); + return bill; + }).collect(Collectors.toList()); + long sumRent = bills.stream().mapToLong((bill) -> caculateRentFee(bill)).sum(); + if (sumRent==0){ + throw new ServiceException("账单已缴费"); + } + if (dto.getAmount()>sumRent){ + throw new ServiceException("支付金额超过所选账单欠费金额"); + } + TPayOrder order = new TPayOrder(); + order.setId(orderNo); + order.setAmount(dto.getAmount()); + order.setUserId(user.getId()); + order.setPhone(user.getPhone()); + order.setUserName(user.getResidentName()); + save(order); + tOrderBillService.saveBatch(orderBills); + resp.setAmount(dto.getAmount()); + resp.setOrderNo(orderNo); + resp.setAppletUrl(createAppletUrl(orderNo)); + return resp; + } +} diff --git a/ruoyi-system/src/main/resources/mapper/system/TBankFlowMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TBankFlowMapper.xml new file mode 100644 index 0000000..61d5859 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/TBankFlowMapper.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> +<mapper namespace="com.ruoyi.system.mapper.TBankFlowMapper"> + + <!-- 通用查询映射结果 --> + <resultMap id="BaseResultMap" type="com.ruoyi.system.model.TBankFlow"> + <id column="id" property="id" /> + <result column="bank_serial_number" property="bankSerialNumber" /> + <result column="flow_money" property="flowMoney" /> + <result column="deduction_money" property="deductionMoney" /> + <result column="remaining_money" property="remainingMoney" /> + <result column="pay_time" property="payTime" /> + <result column="payer" property="payer" /> + <result column="flow_status" property="flowStatus" /> + <result column="pay_type" property="payType" /> + <result column="payment_bill_id" property="paymentBillId" /> + <result column="create_time" property="createTime" /> + <result column="update_time" property="updateTime" /> + <result column="create_by" property="createBy" /> + <result column="update_by" property="updateBy" /> + <result column="disabled" property="disabled" /> + </resultMap> + + <!-- 通用查询结果列 --> + <sql id="Base_Column_List"> + id, bank_serial_number, flow_money, deduction_money, remaining_money, pay_time, payer, flow_status, pay_type, payment_bill_id, create_time, update_time, create_by, update_by, disabled + </sql> + +</mapper> diff --git a/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml b/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml index 27290d9..a027bc6 100644 --- a/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/TBillMapper.xml @@ -33,4 +33,29 @@ id, contract_id,contract_number, payable_fees_money, payable_fees_time, pay_fees_status, pay_fees_money, pay_fees_time, pay_fees_type, bill_type, over_days, payable_fees_penalty, start_time, end_time, bank_serial_number, outstanding_money, voucher, create_time, update_time, create_by, update_by, disabled </sql> + <select id="page" resultType="com.ruoyi.system.dto.TBillDto"> + SELECT + b.*, + t.resident_name as residentName, + t.phone, + t.account + FROM + t_bill b + LEFT JOIN t_contract c ON c.contract_number = b.contract_number + LEFT JOIN t_tenant t ON t.id = c.tenant_id + <where> + <if test="query.payFeesStatus != null"> + and b.pay_fees_status = #{query.payFeesStatus} + </if> + <if test="query.phone != null and query.phone !=''"> + and t.phone = #{query.phone} + </if> + <if test="query.residentName != null and query.residentName !=''"> + and t.resident_name like concat('%',#{query.residentName},'%') + </if> + <if test="query.contractNumber != null and query.contractNumber !=''"> + and b.contract_number = #{contractNumber} + </if> + </where> + </select> </mapper> diff --git a/ruoyi-ui/vue.config.js b/ruoyi-ui/vue.config.js index 70bdfb9..5e30cf7 100644 --- a/ruoyi-ui/vue.config.js +++ b/ruoyi-ui/vue.config.js @@ -35,7 +35,7 @@ proxy: { // detail: https://cli.vuejs.org/config/#devserver-proxy [process.env.VUE_APP_BASE_API]: { - target: `http://localhost:9001`, + target: `http://localhost:8081`, changeOrigin: true, pathRewrite: { ['^' + process.env.VUE_APP_BASE_API]: '' -- Gitblit v1.7.1