提交
This commit is contained in:
130
jeepay-bill/pom.xml
Normal file
130
jeepay-bill/pom.xml
Normal file
@@ -0,0 +1,130 @@
|
||||
<?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>
|
||||
|
||||
<groupId>com.jeequan</groupId> <!-- 组织名, 类似于包名 -->
|
||||
<artifactId>jeepay-9220-bill</artifactId>
|
||||
<packaging>jar</packaging> <!-- 项目的最终打包类型/发布形式, 可选[jar, war, pom, maven-plugin]等 -->
|
||||
<version>${isys.version}</version> <!-- 项目当前版本号 -->
|
||||
<description>Jeepay计全支付系统 [对账系统]</description> <!-- 项目描述 -->
|
||||
<url>https://www.jeequan.com</url>
|
||||
|
||||
<parent>
|
||||
<groupId>com.jeequan</groupId>
|
||||
<artifactId>jeepay</artifactId>
|
||||
<version>Final</version>
|
||||
</parent>
|
||||
|
||||
<!-- 项目属性 -->
|
||||
<properties>
|
||||
<projectRootDir>${basedir}/../</projectRootDir>
|
||||
</properties>
|
||||
|
||||
<!-- 项目依赖声明 -->
|
||||
<dependencies>
|
||||
|
||||
<!-- 显式 依赖[ service ]包, 会自动传递依赖[ core ]包。 -->
|
||||
<dependency>
|
||||
<groupId>com.jeequan</groupId>
|
||||
<artifactId>jeepay-components-db</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 依赖[ rpc-thirdparty ]包, 会自动传递依赖[ core , service ]包。 -->
|
||||
<dependency>
|
||||
<groupId>com.jeequan</groupId>
|
||||
<artifactId>jeepay-components-3rd</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 依赖[ oss ]包 -->
|
||||
<dependency>
|
||||
<groupId>com.jeequan</groupId>
|
||||
<artifactId>jeepay-components-oss</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 依赖[ mq ]包 -->
|
||||
<dependency>
|
||||
<groupId>com.jeequan</groupId>
|
||||
<artifactId>jeepay-components-mq</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 依赖[ bizcommons ]包 -->
|
||||
<dependency>
|
||||
<groupId>com.jeequan</groupId>
|
||||
<artifactId>jeepay-components-bizcommons</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 依赖 sping-boot-web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion> <!-- 删除spring boot默认json映射器: Jackson, 引入fastJSON -->
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jdk8</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-parameter-names</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- spring-security -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- xxl-job-core -->
|
||||
<dependency>
|
||||
<groupId>com.xuxueli</groupId>
|
||||
<artifactId>xxl-job-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
<!-- 作为可执行jar -->
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
|
||||
<!-- resources资源配置项 -->
|
||||
<resources>
|
||||
<!-- 通用资源文件 -->
|
||||
<resource><directory>src/main/resources</directory><includes><include>**/*.*</include></includes></resource>
|
||||
|
||||
<!-- 放置通用配置yml文件, 开发时仅配置一套参数即可。 实际生产环境下应在每个项目下 与jar同级目录下新建application.yml覆写对应参数。 -->
|
||||
<resource>
|
||||
<directory>../conf/devCommons</directory>
|
||||
<includes><include>**/*.yml</include></includes>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<includeSystemScope>true</includeSystemScope>
|
||||
<outputDirectory>${session.executionRootDirectory}/target/</outputDirectory>
|
||||
</configuration> <!-- 包含本地jar文件 -->
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.jeequan.jeepay.bill.bootstrap;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.crypto.SmUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.serializer.SerializeConfig;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
|
||||
import com.jeequan.jeepay.bill.config.SystemYmlConfig;
|
||||
import com.jeequan.jeepay.service.impl.SysConfigService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/*
|
||||
* 项目初始化操作
|
||||
* 比如初始化配置文件, 读取基础数据, 资源初始化等。 避免在Main函数中写业务代码。
|
||||
* CommandLineRunner / ApplicationRunner都可以达到要求, 只是调用参数有所不同。
|
||||
*
|
||||
*
|
||||
* @author terrfly
|
||||
* @date 2021/6/8 17:17
|
||||
*/
|
||||
@Component
|
||||
public class InitRunner implements CommandLineRunner {
|
||||
|
||||
@Autowired private SystemYmlConfig systemYmlConfig;
|
||||
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
|
||||
// 配置是否使用缓存模式
|
||||
SysConfigService.IS_USE_CACHE = systemYmlConfig.getCacheConfig();
|
||||
|
||||
// 初始化系统秘钥
|
||||
SysConfigService.DB_ENCRYPT_SECRET = systemYmlConfig.getDbEncryptSecret();
|
||||
SysConfigService.DB_ENCRYPT_SM4 = SmUtil.sm4(SysConfigService.DB_ENCRYPT_SECRET.getBytes());
|
||||
|
||||
//初始化处理fastjson格式
|
||||
SerializeConfig serializeConfig = SerializeConfig.getGlobalInstance();
|
||||
serializeConfig.put(Date.class, new SimpleDateFormatSerializer(DatePattern.NORM_DATETIME_PATTERN));
|
||||
|
||||
//解决json 序列化时候的 $ref:问题
|
||||
JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect.getMask();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package com.jeequan.jeepay.bill.bootstrap;
|
||||
|
||||
import com.alibaba.fastjson.parser.ParserConfig;
|
||||
import com.alibaba.fastjson.support.config.FastJsonConfig;
|
||||
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import com.jeequan.jeepay.bill.config.SystemYmlConfig;
|
||||
import com.jeequan.jeepay.core.task.XxlJobExecutorProp;
|
||||
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @Author terrfly
|
||||
* @Date 2019/11/7 15:19
|
||||
* @Description spring-boot 主启动程序
|
||||
**/
|
||||
@SpringBootApplication
|
||||
@EnableScheduling
|
||||
@MapperScan("com.jeequan.jeepay.service.mapper") //Mybatis mapper接口路径
|
||||
@ComponentScan(basePackages = "com.jeequan.jeepay.*") //由于MainApplication没有在项目根目录, 需要配置basePackages属性使得成功扫描所有Spring组件;
|
||||
@Configuration
|
||||
public class JeepayBillApplication {
|
||||
|
||||
@Autowired private SystemYmlConfig systemYmlConfig;
|
||||
|
||||
/** main启动函数 **/
|
||||
public static void main(String[] args) {
|
||||
|
||||
//启动项目
|
||||
SpringApplication.run(JeepayBillApplication.class, args);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public ExecutorService executorService() {
|
||||
return new ThreadPoolExecutor(4,
|
||||
4, 1L
|
||||
, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), Thread::new, new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
}
|
||||
|
||||
/** fastJson 配置信息 **/
|
||||
@Bean
|
||||
public HttpMessageConverters fastJsonConfig(){
|
||||
|
||||
// 开启 FastJSON 安全模式!
|
||||
ParserConfig.getGlobalInstance().setSafeMode(true);
|
||||
|
||||
//新建fast-json转换器
|
||||
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
|
||||
|
||||
//fast-json 配置信息
|
||||
FastJsonConfig config = new FastJsonConfig();
|
||||
config.setDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
converter.setFastJsonConfig(config);
|
||||
|
||||
//设置响应的 Content-Type
|
||||
converter.setSupportedMediaTypes(Arrays.asList(new MediaType[]{MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8}));
|
||||
return new HttpMessageConverters(converter);
|
||||
}
|
||||
|
||||
/** Mybatis plus 分页插件 **/
|
||||
@Bean
|
||||
public MybatisPlusInterceptor paginationInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
|
||||
// paginationInterceptor.setOverflow(false);
|
||||
// 设置最大单页限制数量,默认 500 条,-1 不受限制
|
||||
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
|
||||
interceptor.addInnerInterceptor(paginationInnerInterceptor);
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
/*** 注入 定时任务 执行器 **/
|
||||
|
||||
/** xxl-job执行器配置信息 **/
|
||||
@ConfigurationProperties(prefix = "xxl-job.executor")
|
||||
@Bean
|
||||
public XxlJobExecutorProp xxlJobExecutorProp() { return new XxlJobExecutorProp(); }
|
||||
|
||||
@Autowired
|
||||
private XxlJobExecutorProp xxlJobExecutorProp;
|
||||
|
||||
@Bean
|
||||
public XxlJobSpringExecutor xxlJobExecutor() {
|
||||
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
|
||||
xxlJobSpringExecutor.setAdminAddresses(xxlJobExecutorProp.getAdminAddress());
|
||||
xxlJobSpringExecutor.setAppname(xxlJobExecutorProp.getAppname());
|
||||
|
||||
if(xxlJobExecutorProp.getPort() != null){
|
||||
xxlJobSpringExecutor.setPort(xxlJobExecutorProp.getPort());
|
||||
}
|
||||
|
||||
xxlJobSpringExecutor.setAccessToken(xxlJobExecutorProp.getAccessToken());
|
||||
xxlJobSpringExecutor.setLogPath(xxlJobExecutorProp.getLogPath());
|
||||
xxlJobSpringExecutor.setLogRetentionDays(xxlJobExecutorProp.getLogretentiondays());
|
||||
return xxlJobSpringExecutor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.jeequan.jeepay.bill.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 系统Yml配置参数定义Bean
|
||||
*
|
||||
* @author terrfly
|
||||
* @date 2021-04-27 15:50
|
||||
*/
|
||||
@Component
|
||||
@ConfigurationProperties(prefix="isys")
|
||||
@Data
|
||||
public class SystemYmlConfig {
|
||||
|
||||
/** DB SM4 加解密秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!] **/
|
||||
private String dbEncryptSecret;
|
||||
|
||||
/** 是否内存缓存配置信息: true表示开启如支付网关地址/商户应用配置/服务商配置等, 开启后需检查MQ的广播模式是否正常; false表示直接查询DB. **/
|
||||
private Boolean cacheConfig;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.jeequan.jeepay.bill.mq;
|
||||
|
||||
import com.jeequan.jeepay.components.mq.model.ResetIsvMchAppInfoConfigMQ;
|
||||
import com.jeequan.jeepay.core.interfaces.IConfigContextService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 接收MQ消息
|
||||
* 业务: 更新服务商/商户/商户应用配置信息;
|
||||
*
|
||||
* @author terrfly
|
||||
* @date 2021/7/27 9:23
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ResetIsvMchAppInfoMQReceiver implements ResetIsvMchAppInfoConfigMQ.IMQReceiver {
|
||||
|
||||
@Autowired(required = false)
|
||||
private IConfigContextService configContextService;
|
||||
|
||||
@Override
|
||||
public void receive(ResetIsvMchAppInfoConfigMQ.MsgPayload payload) {
|
||||
|
||||
if (payload.getResetType() == ResetIsvMchAppInfoConfigMQ.RESET_TYPE_ISV_INFO) {
|
||||
this.modifyIsvInfo(payload.getIsvNo());
|
||||
} else if (payload.getResetType() == ResetIsvMchAppInfoConfigMQ.RESET_TYPE_MCH_INFO) {
|
||||
this.modifyMchInfo(payload.getMchNo());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 接收 [商户配置信息] 的消息
|
||||
**/
|
||||
private void modifyMchInfo(String mchNo) {
|
||||
log.info("成功接收 [商户配置信息] 的消息, msg={}", mchNo);
|
||||
if (configContextService != null) configContextService.initMchInfoConfigContext(mchNo);
|
||||
log.info(" [商户配置信息] 已重置");
|
||||
}
|
||||
|
||||
/**
|
||||
* 接收 [商户应用支付参数配置信息] 的消息
|
||||
**/
|
||||
private void modifyMchApp(String mchNo, String appId) {
|
||||
log.info("成功接收 [商户应用支付参数配置信息] 的消息, mchNo={}, appId={}", mchNo, appId);
|
||||
if (configContextService != null) configContextService.initMchAppConfigContext(mchNo, appId);
|
||||
log.info(" [商户应用支付参数配置信息] 已重置");
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置ISV信息
|
||||
**/
|
||||
private void modifyIsvInfo(String isvNo) {
|
||||
log.info("成功接收 [ISV信息] 重置, msg={}", isvNo);
|
||||
if (configContextService != null) configContextService.initIsvConfigContext(isvNo);
|
||||
log.info("[ISV信息] 已重置");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.jeequan.jeepay.bill.service;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.jeequan.jeepay.core.constants.CS;
|
||||
import com.jeequan.jeepay.core.interfaces.bill.IReconciliationService;
|
||||
import com.jeequan.jeepay.core.model.bill.ChannelBillRQ;
|
||||
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
|
||||
import com.jeequan.jeepay.db.entity.CheckBatch;
|
||||
import com.jeequan.jeepay.db.entity.PayInterfaceDefine;
|
||||
import com.jeequan.jeepay.service.impl.CheckBatchService;
|
||||
import com.jeequan.jeepay.service.impl.PayInterfaceConfigService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/***
|
||||
* 对账接口
|
||||
*
|
||||
* @author zx
|
||||
* @date 2022/3/12 14:54
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ReconciliationRestockService {
|
||||
|
||||
@Autowired private PayInterfaceConfigService payInterfaceConfigService;
|
||||
@Autowired private CheckBatchService checkBatchService;
|
||||
|
||||
/**
|
||||
* 重新对账,解决对账任务中断或某些支付接口账单下载/解析失败问题
|
||||
* */
|
||||
public void queryChannelBillAndCheck(PayInterfaceDefine payInterfaceDefine, Date billDate) {
|
||||
|
||||
String ifCode = payInterfaceDefine.getIfCode();
|
||||
|
||||
// 查询去重的渠道商户号 和 本地支付配置
|
||||
List<ChannelBillRQ> channelBillRQList = buildDistinctIfParams(payInterfaceDefine);
|
||||
if(CollUtil.isEmpty(channelBillRQList)){
|
||||
log.info("支付接口:{},无支付参数配置!", ifCode);
|
||||
return;
|
||||
}
|
||||
|
||||
// 查询 解析失败&&渠道号 的对账批次
|
||||
List<CheckBatch> checkBatchList = checkBatchService.list(CheckBatch.gw()
|
||||
.eq(CheckBatch::getIfCode, ifCode)
|
||||
.eq(CheckBatch::getReleaseState, CS.YES)
|
||||
.ge(CheckBatch::getBillDate, DateUtil.beginOfDay(billDate))
|
||||
.le(CheckBatch::getBillDate, DateUtil.endOfDay(billDate))
|
||||
);
|
||||
|
||||
// 全部 对账解析失败的商户号
|
||||
List<String> successChannelMchNoList = checkBatchList.stream().map(CheckBatch::getChannelMchNo).collect(Collectors.toList());
|
||||
|
||||
// 解析失败的批次重新对账
|
||||
for (ChannelBillRQ channelBillRQ : channelBillRQList) {
|
||||
if (CollUtil.isEmpty(checkBatchList)) {
|
||||
checkBills4ReleaseFailBatch(ifCode, billDate, channelBillRQ);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!successChannelMchNoList.contains(channelBillRQ.getChannelMchNo())) {
|
||||
checkBills4ReleaseFailBatch(ifCode, billDate, channelBillRQ);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** 构建全部服务商、商户的渠道商户号与服务商或应用的配置关系 */
|
||||
public List<ChannelBillRQ> buildDistinctIfParams(PayInterfaceDefine payInterfaceDefine) {
|
||||
List<ChannelBillRQ> channelBillRQList = new ArrayList<>();
|
||||
if (payInterfaceDefine.getIsIsvMode() != null && payInterfaceDefine.getIsIsvMode() == CS.YES) {
|
||||
channelBillRQList.addAll(payInterfaceConfigService.selectDistinctIsvIfParams(payInterfaceDefine.getIfCode())); // 查询服务商渠道号 与 服务商号及配置参数对应关系
|
||||
channelBillRQList.addAll(payInterfaceConfigService.selectDistinctIsvSubMchIfParams(payInterfaceDefine.getIfCode())); // 查询特约商户 与 商户应用及配置参数对应关系
|
||||
}else if (payInterfaceDefine.getIsMchMode() != null && payInterfaceDefine.getIsMchMode() == CS.YES){
|
||||
channelBillRQList.addAll(payInterfaceConfigService.selectDistinctNormalMchIfParams(payInterfaceDefine.getIfCode())); // 查询普通商户 与 商户应用及配置参数对应关系
|
||||
}
|
||||
return channelBillRQList;
|
||||
}
|
||||
|
||||
/** 解析失败的批次 补充对账 */
|
||||
public void checkBills4ReleaseFailBatch(String ifCode, Date billDate, ChannelBillRQ channelBillRQ) {
|
||||
|
||||
try {
|
||||
com.jeequan.jeepay.core.entity.CheckBatch coreCheckBatch = new CheckBatch();
|
||||
coreCheckBatch.setBatchNo(checkBatchService.getBatchNo(ifCode, channelBillRQ.getChannelMchNo(), billDate));
|
||||
coreCheckBatch.setIfCode(ifCode);
|
||||
coreCheckBatch.setBillDate(billDate);
|
||||
coreCheckBatch.setChannelMchNo(channelBillRQ.getChannelMchNo());
|
||||
coreCheckBatch.setReleaseState(CS.NO);
|
||||
|
||||
IReconciliationService reconciliationService = SpringBeansUtil.getBean("reconciliationService", IReconciliationService.class);
|
||||
reconciliationService.reloadBill4Batch(coreCheckBatch, "release");
|
||||
|
||||
}catch (Exception e) {
|
||||
log.error("对账单处理失败,支付接口:{},渠道商户号:{},对账日期:{}", ifCode, channelBillRQ.getChannelMchNo(), billDate, e);
|
||||
}
|
||||
}
|
||||
|
||||
/** 处理差异 */
|
||||
public void processCheckDiffBills(Date billDate) {
|
||||
IReconciliationService reconciliationService = SpringBeansUtil.getBean("reconciliationService", IReconciliationService.class);
|
||||
reconciliationService.processCheckDiffBills(billDate);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.jeequan.jeepay.bill.task;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.jeequan.jeepay.bill.service.ReconciliationRestockService;
|
||||
import com.jeequan.jeepay.core.constants.CS;
|
||||
import com.jeequan.jeepay.db.entity.PayInterfaceDefine;
|
||||
import com.jeequan.jeepay.service.impl.PayInterfaceDefineService;
|
||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 对账失败的批次 重新跑批 定时任务
|
||||
*
|
||||
* @author zx
|
||||
* @date 2022/9/9 9:40
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ReconciliationRestockTask {
|
||||
|
||||
@Autowired private PayInterfaceDefineService payInterfaceDefineService;
|
||||
@Autowired private ReconciliationRestockService reconciliationRestockService;
|
||||
|
||||
@XxlJob("reconciliationStockTaskHandler")
|
||||
public void reconciliationStockTask() {
|
||||
log.info("执行补充对账,开始...");
|
||||
|
||||
// 对账日期
|
||||
Date billDate = DateUtil.beginOfDay(DateUtil.yesterday());
|
||||
// Date billDate = DateUtil.beginOfDay(DateUtil.offsetDay(DateUtil.date(), -3));
|
||||
log.info("补充对账日期:{}", DateUtil.formatDate(billDate));
|
||||
|
||||
// 查询所有支持分账、开启分账的支付接口
|
||||
List<PayInterfaceDefine> defineList = payInterfaceDefineService.list(PayInterfaceDefine.gw()
|
||||
.eq(PayInterfaceDefine::getIsSupportCheckBill, CS.YES)
|
||||
.eq(PayInterfaceDefine::getIsOpenCheckBill, CS.YES)
|
||||
);
|
||||
if (CollUtil.isEmpty(defineList)) {
|
||||
log.info("执行补充对账结束。无支付接口支持对账");
|
||||
return;
|
||||
}
|
||||
|
||||
// 遍历支付接口查询渠道对账数据 --> 对账 --> 差异入库
|
||||
for (PayInterfaceDefine payInterfaceDefine : defineList) {
|
||||
reconciliationRestockService.queryChannelBillAndCheck(payInterfaceDefine, billDate);
|
||||
}
|
||||
|
||||
// 处理差异账单(处理 对账日期前三天内的、本地多帐和渠道多帐情况)
|
||||
reconciliationRestockService.processCheckDiffBills(billDate);
|
||||
|
||||
log.info("执行补充对账,结束。");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.jeequan.jeepay.bill.task;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.jeequan.jeepay.core.constants.CS;
|
||||
import com.jeequan.jeepay.core.interfaces.bill.IReconciliationService;
|
||||
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
|
||||
import com.jeequan.jeepay.db.entity.PayInterfaceDefine;
|
||||
import com.jeequan.jeepay.service.impl.PayInterfaceDefineService;
|
||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* 对账 定时任务
|
||||
*
|
||||
* @author zx
|
||||
* @date 2022/9/9 9:40
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ReconciliationTask {
|
||||
|
||||
@Autowired private PayInterfaceDefineService payInterfaceDefineService;
|
||||
|
||||
@XxlJob("reconciliationTaskHandler")
|
||||
public void reconciliationTask() {
|
||||
log.info("执行对账,开始...");
|
||||
|
||||
// 对账日期
|
||||
Date billDate = DateUtil.beginOfDay(DateUtil.yesterday());
|
||||
// Date billDate = DateUtil.beginOfDay(DateUtil.offsetDay(DateUtil.date(), -3));
|
||||
log.info("对账日期:{}", DateUtil.formatDate(billDate));
|
||||
|
||||
// 查询所有支持分账、开启分账的支付接口
|
||||
List<PayInterfaceDefine> defineList = payInterfaceDefineService.list(PayInterfaceDefine.gw()
|
||||
.eq(PayInterfaceDefine::getIsSupportCheckBill, CS.YES)
|
||||
.eq(PayInterfaceDefine::getIsOpenCheckBill, CS.YES)
|
||||
);
|
||||
if (CollUtil.isEmpty(defineList)) {
|
||||
log.info("执行对账结束。无支付接口支持对账");
|
||||
return;
|
||||
}
|
||||
|
||||
IReconciliationService reconciliationService = SpringBeansUtil.getBean("reconciliationService", IReconciliationService.class);
|
||||
|
||||
// 遍历支付接口查询渠道对账数据 --> 对账 --> 差异入库
|
||||
for (PayInterfaceDefine payInterfaceDefine : defineList) {
|
||||
reconciliationService.queryChannelBillAndCheck(payInterfaceDefine.getIfCode(), billDate);
|
||||
}
|
||||
|
||||
// 处理差异账单(处理 对账日期前三天内的、本地多帐和渠道多帐情况)
|
||||
reconciliationService.processCheckDiffBills(billDate);
|
||||
|
||||
log.info("执行对账,结束。");
|
||||
}
|
||||
|
||||
}
|
||||
121
jeepay-bill/src/main/resources/application-dev.yml
Normal file
121
jeepay-bill/src/main/resources/application-dev.yml
Normal file
@@ -0,0 +1,121 @@
|
||||
#################################
|
||||
# spring boot支持外部application.yml 读取优先级为:
|
||||
# 1、file:./config/(当前目录下的config文件夹)
|
||||
# 2、file:./(当前目录)
|
||||
# 3、classpath:/config/(classpath下的config目录)
|
||||
# 4、classpath:/(classpath根目录)
|
||||
# 建议: 如果是jar则放置到与jar相同的目录下, 如果解压文件放置到classpath: config目录下。 (需要将文件重命名为 application.yml )
|
||||
#
|
||||
# 该yml文件只配置与环境相关的参数, 其他配置读取项目下的配置项
|
||||
#
|
||||
#################################
|
||||
# 数据库的配置项, 自定义配置放置在配置顶层
|
||||
db-config:
|
||||
master: #主库配置(必填)
|
||||
# yml填写url连接串, 无需将&符号进行转义
|
||||
url: jdbc:mysql://127.0.0.1:3306/yinshangfu?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: YinShangFuMysql@123456
|
||||
encrypt-account: false # 连接账号和密码是否已加密。 true:db的账密需配置密文,函数详见 DBProp.main(); false: db账密请填写明文
|
||||
# 连接池配置项
|
||||
initial-size: 5 #初始化时建立物理连接的个数
|
||||
min-idle: 5 #最小连接池数量
|
||||
max-active: 30 #最大连接池数量
|
||||
max-wait: 60000 #获取连接时最大等待时间,单位毫秒
|
||||
# 检测相关
|
||||
test-while-idle: true # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
|
||||
test-on-borrow: false # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
|
||||
test-on-return: false # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
|
||||
time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
min-evictable-idle-time-millis: 300000 #连接保持空闲而不被驱逐的最小时间
|
||||
validation-query: SELECT 1 FROM DUAL
|
||||
# 是否缓存preparedStatement
|
||||
pool-prepared-statements: false # 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
|
||||
max-pool-prepared-statement-per-connection-size: 20 # 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。
|
||||
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计 通过connectProperties属性来打开mergeSql功能;慢SQL记录
|
||||
filters: stat,wall
|
||||
connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
|
||||
|
||||
slave: #从库配置(可选), 若没有显式配置则使用master的配置项。 配置参数与master一致。
|
||||
|
||||
# spring-boot组件配置
|
||||
spring:
|
||||
servlet:
|
||||
multipart:
|
||||
enabled: true #是否启用http上传处理
|
||||
max-request-size: 10MB #最大请求文件的大小
|
||||
max-file-size: 10MB #设置单个文件最大长度
|
||||
resources:
|
||||
static-locations: classpath:/static #项目静态资源路径 (可直接通过http访问)
|
||||
freemarker:
|
||||
template-loader-path: classpath:/templates #freemarker模板目录
|
||||
template-encoding: UTF-8
|
||||
suffix: .ftl
|
||||
settings:
|
||||
classic_compatible: true # 如果变量为null,转化为空字符串,比如做比较的时候按照空字符做比较
|
||||
number_format: '#' #数字格式进行原样显示,不加格式化字符例如 100,00
|
||||
|
||||
# #activeMQ配置 ( 注意: activeMQ配置项需在spring的下级 )
|
||||
rabbitmq:
|
||||
addresses: 127.0.0.1:5672
|
||||
username: root
|
||||
password: YinShangFuRabbit@123456
|
||||
dynamic: true
|
||||
virtual-host: /
|
||||
#
|
||||
# #rabbitmq配置 ( 注意: rabbitmq配置项需在spring的下级 )
|
||||
# rabbitmq:
|
||||
# addresses: 127.0.0.1:5672
|
||||
# username: guest
|
||||
# password: guest
|
||||
# dynamic: true
|
||||
# virtual-host: /
|
||||
|
||||
## rocketmq配置 ( 注意:rocketmq配置项请放置到根目录, 不是spring的二级配置! )
|
||||
#rocketmq:
|
||||
# name-server: 127.0.0.1:9876
|
||||
# producer:
|
||||
# group: JEEPAY-GROUP
|
||||
|
||||
## 阿里云rocketmq配置 ( 注意:aliyun-rocketmq配置项请放置到根目录, 不是spring的二级配置!需要阿里云开通rocketMQ产品,创建Group和Topic )
|
||||
#aliyun-rocketmq:
|
||||
# namesrvAddr: xxx
|
||||
# accessKey: xxx
|
||||
# secretKey: xxx
|
||||
# groupIdPrefix: GID_JEEPAY_ # (分组前缀, 具体名称详见AliyunRocketMQFactory.java )
|
||||
|
||||
#日志配置参数。
|
||||
# 当存在logback-spring.xml文件时: 该配置将引进到logback配置, springboot配置不生效。
|
||||
# 不存在logback-spring.xml 文件时, 使用springboot的配置, 同样可用。
|
||||
logging:
|
||||
level:
|
||||
root: info #主日志级别
|
||||
com.jeequan.jeepay: info #该项目日志级别,当需要打印sql时请开启为debug
|
||||
path: ./bill/logs #日志存放地址
|
||||
# xxl-job 执行器配置项
|
||||
xxl-job:
|
||||
executor:
|
||||
admin-address: http://127.0.0.1:9300/xxl-job-admin # 调度中心部署根地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
|
||||
access-token: jeepayTaskToken@2022 # 执行器通讯TOKEN
|
||||
appname: jeepay-plus-bill-executor # 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
|
||||
port: 9320 # 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
|
||||
log-path: ${logging.file.path} # 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
|
||||
logretentiondays: 7 # 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
|
||||
|
||||
|
||||
#系统业务参数
|
||||
isys:
|
||||
|
||||
db-encrypt-secret: 1234567890123456 #DB SM4 加解密秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
|
||||
|
||||
#是否内存缓存配置信息: true表示开启如支付网关地址/商户应用配置/服务商配置等, 开启后需检查MQ的广播模式是否正常; false表示直接查询DB.
|
||||
cache-config: false
|
||||
|
||||
oss:
|
||||
file-root-path: /home/jeepay/upload #存储根路径 ( 无需以‘/’结尾 )
|
||||
file-public-path: ${isys.oss.file-root-path}/public #公共读取块 ( 一般配合root-path参数进行设置,需以‘/’ 开头, 无需以‘/’结尾 )
|
||||
file-private-path: ${isys.oss.file-root-path}/private #私有化本地访问,不允许url方式公共读取 ( 一般配合root-path参数进行设置,需以‘/’ 开头, 无需以‘/’结尾 )
|
||||
|
||||
mq:
|
||||
vender: rabbitMQ # 切换MQ厂商, 支持:【 activeMQ rabbitMQ rocketMQ aliYunRocketMQ 】, 需正确配置 【对应的yml参数】 和 【jeepay-components-mq项目下pom.xml中的依赖包】。
|
||||
|
||||
114
jeepay-bill/src/main/resources/application-prod.yml
Normal file
114
jeepay-bill/src/main/resources/application-prod.yml
Normal file
@@ -0,0 +1,114 @@
|
||||
# spring-boot组件配置
|
||||
spring:
|
||||
servlet:
|
||||
multipart:
|
||||
enabled: true #是否启用http上传处理
|
||||
max-request-size: 10MB #最大请求文件的大小
|
||||
max-file-size: 10MB #设置单个文件最大长度
|
||||
resources:
|
||||
static-locations: classpath:/static #项目静态资源路径 (可直接通过http访问)
|
||||
freemarker:
|
||||
template-loader-path: classpath:/templates #freemarker模板目录
|
||||
template-encoding: UTF-8
|
||||
suffix: .ftl
|
||||
settings:
|
||||
classic_compatible: true # 如果变量为null,转化为空字符串,比如做比较的时候按照空字符做比较
|
||||
number_format: '#' #数字格式进行原样显示,不加格式化字符例如 100,00
|
||||
cache:
|
||||
type: redis
|
||||
redis:
|
||||
host: 127.0.0.1
|
||||
port: 6379
|
||||
timeout: 1000
|
||||
password: ax123456ax
|
||||
activemq:
|
||||
broker-url: failover:(tcp://127.0.0.1:61616?wireFormat.maxInactivityDuration=0) #
|
||||
in-memory: false # Jeepay
|
||||
user: admin # activeMQ
|
||||
password: 123456
|
||||
pool:
|
||||
enabled: true
|
||||
max-connections: 10
|
||||
idle-timeout: 30000 #
|
||||
logging:
|
||||
level:
|
||||
root: info #主日志级别
|
||||
# xxl-job 执行器配置项
|
||||
xxl-job:
|
||||
executor:
|
||||
admin-address: http://127.0.0.1:8282/xxl-job-admin # 调度中心部署根地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
|
||||
access-token: jeepayTaskToken@2022 # 执行器通讯TOKEN
|
||||
# appname: jeepay-plus-bill-executor # 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
|
||||
# port: # 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
|
||||
log-path: ${logging.file.path} # 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
|
||||
logretentiondays: 7 # 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
|
||||
|
||||
db-config:
|
||||
master: #主库配置(必填)
|
||||
# yml填写url连接串, 无需将&符号进行转义
|
||||
url: jdbc:p6spy:mysql://rm-bp1c8prh6j399epb5.mysql.rds.aliyuncs.com/yinshangfu?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
|
||||
username: yinshangfu
|
||||
password: YinShangFuMysql@123456
|
||||
encrypt-account: false # 连接账号和密码是否已加密。 true:db的账密需配置密文,函数详见 DBProp.main(); false: db账密请填写明文
|
||||
# 连接池配置项
|
||||
initial-size: 5 #初始化时建立物理连接的个数
|
||||
min-idle: 5 #最小连接池数量
|
||||
max-active: 30 #最大连接池数量
|
||||
max-wait: 60000 #获取连接时最大等待时间,单位毫秒
|
||||
# 检测相关
|
||||
test-while-idle: true # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
|
||||
test-on-borrow: false # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
|
||||
test-on-return: false # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
|
||||
time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
min-evictable-idle-time-millis: 300000 #连接保持空闲而不被驱逐的最小时间
|
||||
validation-query: SELECT 1 FROM DUAL
|
||||
# 是否缓存preparedStatement
|
||||
pool-prepared-statements: false # 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
|
||||
max-pool-prepared-statement-per-connection-size: 20 # 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。
|
||||
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计 通过connectProperties属性来打开mergeSql功能;慢SQL记录
|
||||
filters: stat,wall
|
||||
connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
|
||||
|
||||
slave: #从库配置(可选), 若没有显式配置则使用master的配置项。 配置参数与master一致。
|
||||
# yml填写url连接串, 无需将&符号进行转义
|
||||
url: jdbc:p6spy:mysql://rm-bp1c8prh6j399epb5.mysql.rds.aliyuncs.com/yinshangfu?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
|
||||
username: yinshangfu
|
||||
password: YinShangFuMysql@123456
|
||||
encrypt-account: false # 连接账号和密码是否已加密。 true:db的账密需配置密文,函数详见 DBProp.main(); false: db账密请填写明文
|
||||
# 连接池配置项
|
||||
initial-size: 5 #初始化时建立物理连接的个数
|
||||
min-idle: 5 #最小连接池数量
|
||||
max-active: 30 #最大连接池数量
|
||||
max-wait: 60000 #获取连接时最大等待时间,单位毫秒
|
||||
# 检测相关
|
||||
test-while-idle: true # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
|
||||
test-on-borrow: false # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
|
||||
test-on-return: false # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
|
||||
time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
min-evictable-idle-time-millis: 300000 #连接保持空闲而不被驱逐的最小时间
|
||||
validation-query: SELECT 1 FROM DUAL
|
||||
# 是否缓存preparedStatement
|
||||
pool-prepared-statements: false # 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
|
||||
max-pool-prepared-statement-per-connection-size: 20 # 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。
|
||||
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计 通过connectProperties属性来打开mergeSql功能;慢SQL记录
|
||||
filters: stat,wall
|
||||
connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
|
||||
isys:
|
||||
#是否允许跨域请求 [生产环境建议关闭, 若api与前端项目没有在同一个域名下时,应开启此配置或在nginx统一配置允许跨域]
|
||||
allow-cors: true
|
||||
|
||||
db-encrypt-secret: 1234567890123456 #DB SM4 加解密秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
|
||||
http-message-encrypt-secret: 1234567890123456 #web传输加解密 秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
|
||||
|
||||
# 支付网关的公钥和私钥(系统级别!), 请妥善保存,用于回调商户的商户侧的验证, 首次设置好之后不可随意变更!
|
||||
sys-RSA2-private-key: MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCLU0lXJu9vcJCwrwFGwT1CqXUSY+JMW2iSRPtgLw6lxjU403hS1VyKxA5uTZokv80Wd+bcxDMrM9DwHeGqhjlWvbB/lqaRliJJRdgLVUedrDY+3YSN75uHBtLmxZbnaUpV6/aWA/a+lkNqHxYCWB1jggFB9DhVg2SgoMGDOYHDNA5ZDl47sKpanW0kfG9lINSV4xgDPmAJxUnhkG/7eVEBDev9EIhc+LIMC7Zj+UYc+s/TK4c31fFTW4dZAp3LVEdct9qXU5qm/fXIXxeo3E0bWyOP3VL4Xmx2S9Host1YzjzXPSi1TJjX7rxQkhmbE/dQJ+ws/VvKPuUpmLEPGsm/AgMBAAECggEBAIONCFq58KoQZw3ssA/WtbkTt+69URc31+0EJTYUOIheNjKJubq8qrx7kgSkUT8RutvUKq+YsZfBPS77h/Ay/EDiqpxN6sjcMVNuFyfcRdqimDWTg21hKEC+OLSdLHcj+4RVYGcVJw2dY9n3sBhWiqlCP12+8tILViA0qYL18YgVYJM3bL2MCXfUnm8/Rn1ut5LuDtU/UuaVz9vuCqNirZJedZx3WEq69ZRt9m44XN934NikbUGxQRlz32WRXDo+ssSTu3174UbDYc8nhqO0jUvuzfjOOMf9NYRJsgqVihxMLvvMaUhEE3w6qZPLMj6KhTiG5QHexBbyLgDxH4TZ4gECgYEAz7vZFMoKYifCi+eFykH/ad8QYYoYLlrU1EN2fpIJqwSHZbpBfB8NM5Ov26xU/aNHGKxtSOrUFva5sWub5f9OlsOAmaUOPuVuaJbsq+e3cNQ41jBcdppGJLNx1p/69zR1rF9TbI9Ambd8sOgX3OZmImA2Ldlk2KvMKRruxwc4uN8CgYEAq7J0u5KTwI3PxENLWQ/6tOBNdbCoyqFM+FdANVHRA4dhhdoJ1x0bpdt3tapPFJTBURSEspNxPl4iT+GdpoF6KwqTsQFmB5TLlfx8wY9SIc+sI/ifZvMA5Dv8vVfYWNig7rGV+vIyJCCNbJ5OMa1xvxTDc7Dx4XPxcJ4sR1ZyqyECgYAe447O8ZADsmfSR9X0EkY5ZurXpiIcWnNFMNbg0TRQ0raTYNO18iQTZEWFA6YLpQjAWXtSmWB6HavU/uxKkeEMt/taXVm17oWxVafRk/4J7/SXnM9S73O4p1opENbPhWRuAiq0fMSdVtRatdg+h5/uQqIrxSSit0D/Z7rTq3Y6vwKBgQCd8AlbJckOHiTZd8GOypkm2xHFydxqkJfZ9YCVy44Fvfnig5/7pcXx+oEStfgKiY+OQt6R2fkYksTjUDmRmZbEkvUqpIuzO5dOf7RO5MR7X6oMaL5QmAXg7KFflrfnelYHW4oIDdQ70UnmeXSaU97HE5V7DXBioCGfI5C9inLuoQKBgQCwJmQ2heyTbG1DIBuqf+GFXLuOp76M/7S9c+5R7yfxyTzAbiKRIPeSF5wlxNXEnGwK7qB9CmctlBdnV7A0qnZVFMXf7AbBDUzOCjiy1RSh04BNPnu0dTIygX2PE5inltrHiZtTgciKwj9MexT97F4mTR76kIMz5SGNZe3PscQr7g==
|
||||
sys-RSA2-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi1NJVybvb3CQsK8BRsE9Qql1EmPiTFtokkT7YC8OpcY1ONN4UtVcisQObk2aJL/NFnfm3MQzKzPQ8B3hqoY5Vr2wf5amkZYiSUXYC1VHnaw2Pt2Eje+bhwbS5sWW52lKVev2lgP2vpZDah8WAlgdY4IBQfQ4VYNkoKDBgzmBwzQOWQ5eO7CqWp1tJHxvZSDUleMYAz5gCcVJ4ZBv+3lRAQ3r/RCIXPiyDAu2Y/lGHPrP0yuHN9XxU1uHWQKdy1RHXLfal1Oapv31yF8XqNxNG1sjj91S+F5sdkvR6LLdWM481z0otUyY1+68UJIZmxP3UCfsLP1byj7lKZixDxrJvwIDAQAB
|
||||
|
||||
#是否内存缓存配置信息: true表示开启如支付网关地址/商户应用配置/服务商配置等, 开启后需检查MQ的广播模式是否正常; false表示直接查询DB.
|
||||
cache-config: false
|
||||
mq:
|
||||
vender: activeMQ
|
||||
|
||||
oss:
|
||||
file-root-path: /home/www/.upload #存储根路径 ( 无需以‘/’结尾 )
|
||||
file-public-path: ${isys.oss.file-root-path}/public #公共读取块 ( 一般配合root-path参数进行设置,需以‘/’ 开头, 无需以‘/’结尾 )
|
||||
111
jeepay-bill/src/main/resources/application-test.yml
Normal file
111
jeepay-bill/src/main/resources/application-test.yml
Normal file
@@ -0,0 +1,111 @@
|
||||
# spring-boot组件配置
|
||||
spring:
|
||||
servlet:
|
||||
multipart:
|
||||
enabled: true #是否启用http上传处理
|
||||
max-request-size: 10MB #最大请求文件的大小
|
||||
max-file-size: 10MB #设置单个文件最大长度
|
||||
resources:
|
||||
static-locations: classpath:/static #项目静态资源路径 (可直接通过http访问)
|
||||
freemarker:
|
||||
template-loader-path: classpath:/templates #freemarker模板目录
|
||||
template-encoding: UTF-8
|
||||
suffix: .ftl
|
||||
settings:
|
||||
classic_compatible: true # 如果变量为null,转化为空字符串,比如做比较的时候按照空字符做比较
|
||||
number_format: '#' #数字格式进行原样显示,不加格式化字符例如 100,00
|
||||
cache:
|
||||
type: redis
|
||||
redis:
|
||||
host: 47.111.143.211
|
||||
port: 6379
|
||||
timeout: 1000
|
||||
password: ax123456ax
|
||||
rabbitmq:
|
||||
addresses: 47.111.143.211:5672
|
||||
username: root
|
||||
password: YinShangFuRabbit@123456
|
||||
dynamic: true
|
||||
virtual-host: /
|
||||
logging:
|
||||
level:
|
||||
root: info #主日志级别
|
||||
# xxl-job 执行器配置项
|
||||
xxl-job:
|
||||
executor:
|
||||
admin-address: http://47.111.143.211:8282/xxl-job-admin # 调度中心部署根地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
|
||||
access-token: jeepayTaskToken@2022 # 执行器通讯TOKEN
|
||||
# appname: jeepay-plus-bill-executor # 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
|
||||
# port: # 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
|
||||
log-path: ${logging.file.path} # 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
|
||||
logretentiondays: 7 # 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
|
||||
|
||||
db-config:
|
||||
master: #主库配置(必填)
|
||||
# yml填写url连接串, 无需将&符号进行转义
|
||||
url: jdbc:mysql://47.111.143.211:3306/yinshangfu?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: YinShangFuMysql@123456
|
||||
encrypt-account: false # 连接账号和密码是否已加密。 true:db的账密需配置密文,函数详见 DBProp.main(); false: db账密请填写明文
|
||||
# 连接池配置项
|
||||
initial-size: 5 #初始化时建立物理连接的个数
|
||||
min-idle: 5 #最小连接池数量
|
||||
max-active: 30 #最大连接池数量
|
||||
max-wait: 60000 #获取连接时最大等待时间,单位毫秒
|
||||
# 检测相关
|
||||
test-while-idle: true # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
|
||||
test-on-borrow: false # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
|
||||
test-on-return: false # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
|
||||
time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
min-evictable-idle-time-millis: 300000 #连接保持空闲而不被驱逐的最小时间
|
||||
validation-query: SELECT 1 FROM DUAL
|
||||
# 是否缓存preparedStatement
|
||||
pool-prepared-statements: false # 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
|
||||
max-pool-prepared-statement-per-connection-size: 20 # 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。
|
||||
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计 通过connectProperties属性来打开mergeSql功能;慢SQL记录
|
||||
filters: stat,wall
|
||||
connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
|
||||
|
||||
slave: #从库配置(可选), 若没有显式配置则使用master的配置项。 配置参数与master一致。
|
||||
# yml填写url连接串, 无需将&符号进行转义
|
||||
url: jdbc:mysql://47.111.143.211:3306/yinshangfu?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: YinShangFuMysql@123456
|
||||
encrypt-account: false # 连接账号和密码是否已加密。 true:db的账密需配置密文,函数详见 DBProp.main(); false: db账密请填写明文
|
||||
# 连接池配置项
|
||||
initial-size: 5 #初始化时建立物理连接的个数
|
||||
min-idle: 5 #最小连接池数量
|
||||
max-active: 30 #最大连接池数量
|
||||
max-wait: 60000 #获取连接时最大等待时间,单位毫秒
|
||||
# 检测相关
|
||||
test-while-idle: true # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
|
||||
test-on-borrow: false # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
|
||||
test-on-return: false # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
|
||||
time-between-eviction-runs-millis: 60000 #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
||||
min-evictable-idle-time-millis: 300000 #连接保持空闲而不被驱逐的最小时间
|
||||
validation-query: SELECT 1 FROM DUAL
|
||||
# 是否缓存preparedStatement
|
||||
pool-prepared-statements: false # 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
|
||||
max-pool-prepared-statement-per-connection-size: 20 # 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。
|
||||
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计 通过connectProperties属性来打开mergeSql功能;慢SQL记录
|
||||
filters: stat,wall
|
||||
connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
|
||||
isys:
|
||||
#是否允许跨域请求 [生产环境建议关闭, 若api与前端项目没有在同一个域名下时,应开启此配置或在nginx统一配置允许跨域]
|
||||
allow-cors: true
|
||||
|
||||
db-encrypt-secret: 1234567890123456 #DB SM4 加解密秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
|
||||
http-message-encrypt-secret: 1234567890123456 #web传输加解密 秘钥 (必须16位) [每个系统配置必须相同,否则加解密不一致导致业务异常!]
|
||||
|
||||
# 支付网关的公钥和私钥(系统级别!), 请妥善保存,用于回调商户的商户侧的验证, 首次设置好之后不可随意变更!
|
||||
sys-RSA2-private-key: MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCLU0lXJu9vcJCwrwFGwT1CqXUSY+JMW2iSRPtgLw6lxjU403hS1VyKxA5uTZokv80Wd+bcxDMrM9DwHeGqhjlWvbB/lqaRliJJRdgLVUedrDY+3YSN75uHBtLmxZbnaUpV6/aWA/a+lkNqHxYCWB1jggFB9DhVg2SgoMGDOYHDNA5ZDl47sKpanW0kfG9lINSV4xgDPmAJxUnhkG/7eVEBDev9EIhc+LIMC7Zj+UYc+s/TK4c31fFTW4dZAp3LVEdct9qXU5qm/fXIXxeo3E0bWyOP3VL4Xmx2S9Host1YzjzXPSi1TJjX7rxQkhmbE/dQJ+ws/VvKPuUpmLEPGsm/AgMBAAECggEBAIONCFq58KoQZw3ssA/WtbkTt+69URc31+0EJTYUOIheNjKJubq8qrx7kgSkUT8RutvUKq+YsZfBPS77h/Ay/EDiqpxN6sjcMVNuFyfcRdqimDWTg21hKEC+OLSdLHcj+4RVYGcVJw2dY9n3sBhWiqlCP12+8tILViA0qYL18YgVYJM3bL2MCXfUnm8/Rn1ut5LuDtU/UuaVz9vuCqNirZJedZx3WEq69ZRt9m44XN934NikbUGxQRlz32WRXDo+ssSTu3174UbDYc8nhqO0jUvuzfjOOMf9NYRJsgqVihxMLvvMaUhEE3w6qZPLMj6KhTiG5QHexBbyLgDxH4TZ4gECgYEAz7vZFMoKYifCi+eFykH/ad8QYYoYLlrU1EN2fpIJqwSHZbpBfB8NM5Ov26xU/aNHGKxtSOrUFva5sWub5f9OlsOAmaUOPuVuaJbsq+e3cNQ41jBcdppGJLNx1p/69zR1rF9TbI9Ambd8sOgX3OZmImA2Ldlk2KvMKRruxwc4uN8CgYEAq7J0u5KTwI3PxENLWQ/6tOBNdbCoyqFM+FdANVHRA4dhhdoJ1x0bpdt3tapPFJTBURSEspNxPl4iT+GdpoF6KwqTsQFmB5TLlfx8wY9SIc+sI/ifZvMA5Dv8vVfYWNig7rGV+vIyJCCNbJ5OMa1xvxTDc7Dx4XPxcJ4sR1ZyqyECgYAe447O8ZADsmfSR9X0EkY5ZurXpiIcWnNFMNbg0TRQ0raTYNO18iQTZEWFA6YLpQjAWXtSmWB6HavU/uxKkeEMt/taXVm17oWxVafRk/4J7/SXnM9S73O4p1opENbPhWRuAiq0fMSdVtRatdg+h5/uQqIrxSSit0D/Z7rTq3Y6vwKBgQCd8AlbJckOHiTZd8GOypkm2xHFydxqkJfZ9YCVy44Fvfnig5/7pcXx+oEStfgKiY+OQt6R2fkYksTjUDmRmZbEkvUqpIuzO5dOf7RO5MR7X6oMaL5QmAXg7KFflrfnelYHW4oIDdQ70UnmeXSaU97HE5V7DXBioCGfI5C9inLuoQKBgQCwJmQ2heyTbG1DIBuqf+GFXLuOp76M/7S9c+5R7yfxyTzAbiKRIPeSF5wlxNXEnGwK7qB9CmctlBdnV7A0qnZVFMXf7AbBDUzOCjiy1RSh04BNPnu0dTIygX2PE5inltrHiZtTgciKwj9MexT97F4mTR76kIMz5SGNZe3PscQr7g==
|
||||
sys-RSA2-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi1NJVybvb3CQsK8BRsE9Qql1EmPiTFtokkT7YC8OpcY1ONN4UtVcisQObk2aJL/NFnfm3MQzKzPQ8B3hqoY5Vr2wf5amkZYiSUXYC1VHnaw2Pt2Eje+bhwbS5sWW52lKVev2lgP2vpZDah8WAlgdY4IBQfQ4VYNkoKDBgzmBwzQOWQ5eO7CqWp1tJHxvZSDUleMYAz5gCcVJ4ZBv+3lRAQ3r/RCIXPiyDAu2Y/lGHPrP0yuHN9XxU1uHWQKdy1RHXLfal1Oapv31yF8XqNxNG1sjj91S+F5sdkvR6LLdWM481z0otUyY1+68UJIZmxP3UCfsLP1byj7lKZixDxrJvwIDAQAB
|
||||
|
||||
#是否内存缓存配置信息: true表示开启如支付网关地址/商户应用配置/服务商配置等, 开启后需检查MQ的广播模式是否正常; false表示直接查询DB.
|
||||
cache-config: false
|
||||
mq:
|
||||
vender: rabbitMQ
|
||||
|
||||
oss:
|
||||
file-root-path: D:/jeepayFiles #存储根路径 ( 无需以‘/’结尾 )
|
||||
file-public-path: ${isys.oss.file-root-path}/public #公共读取块 ( 一般配合root-path参数进行设置,需以‘/’ 开头, 无需以‘/’结尾 )
|
||||
7
jeepay-bill/src/main/resources/application.yml
Normal file
7
jeepay-bill/src/main/resources/application.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
server:
|
||||
port: 9220 #设置端口
|
||||
servlet:
|
||||
context-path: / #设置应用的目录. 前缀需要带/, 无需设置后缀, 示例 【 /xxx 】 or 【 / 】
|
||||
spring:
|
||||
profiles:
|
||||
active: dev
|
||||
7
jeepay-bill/src/main/resources/banner.txt
Normal file
7
jeepay-bill/src/main/resources/banner.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
__
|
||||
/ /___ ___ ____ ____ ___ __
|
||||
__ / // _ \/ _ \/ __ \/ __ `/ / / /
|
||||
/ /_/ // __/ __/ /_/ / /_/ / /_/ /
|
||||
\____/ \___/\___/ .___/\__,_/\__, /
|
||||
/_/ /____/
|
||||
:: Jeepay Plus :: (v2.9.1.RELEASE)
|
||||
69
jeepay-bill/src/main/resources/logback-spring.xml
Normal file
69
jeepay-bill/src/main/resources/logback-spring.xml
Normal file
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration scan="false" debug="false">
|
||||
|
||||
<!-- 日志存放路径, 读取application.yml 需要使用springProperty获取 -->
|
||||
<springProperty scope="context" name="currentLoggerFilePath" source="logging.file.path"/>
|
||||
|
||||
<!-- 主日志级别配置 -->
|
||||
<springProperty scope="context" name="currentRootLevel" source="logging.level.root"/>
|
||||
|
||||
<!-- 项目配置, 如修改包名,请搜索并全部替换掉 -->
|
||||
<springProperty scope="context" name="currentProjectLevel" source="logging.level.com.jeequan.jeepay"/>
|
||||
|
||||
<!-- 日志文件名称 logback属性 -->
|
||||
<property name="currentLoggerFileName" value="bill" />
|
||||
<!-- 日志格式, 参考:https://logback.qos.ch/manual/layouts.html -->
|
||||
<property name="currentLoggerPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{15} - %msg%n" />
|
||||
|
||||
<!-- appender: 控制台日志 -->
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder charset="UTF-8" >
|
||||
<pattern>${currentLoggerPattern}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- appender:主日志文件 -->
|
||||
<appender name="ALL_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 日志文件路径及文件名 -->
|
||||
<file>${currentLoggerFilePath}/${currentLoggerFileName}.all.log</file>
|
||||
<!-- 内容编码及格式 -->
|
||||
<encoder charset="UTF-8" ><pattern>${currentLoggerPattern}</pattern></encoder>
|
||||
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 每天日志归档路径以及格式 -->
|
||||
<fileNamePattern>${currentLoggerFilePath}/${currentLoggerFileName}.all.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<maxHistory>5</maxHistory> <!--日志文件保留天数-->
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
<!-- appender:错误信息日志文件 -->
|
||||
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 日志文件路径及文件名 -->
|
||||
<file>${currentLoggerFilePath}/${currentLoggerFileName}.error.log</file>
|
||||
<!-- 内容编码及格式 -->
|
||||
<encoder charset="UTF-8" ><pattern>${currentLoggerPattern}</pattern></encoder>
|
||||
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 每天日志归档路径以及格式 -->
|
||||
<fileNamePattern>${currentLoggerFilePath}/${currentLoggerFileName}.error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||
<maxHistory>20</maxHistory> <!--日志文件保留天数-->
|
||||
</rollingPolicy>
|
||||
<!-- 此日志文件只记录ERROR级别的 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>ERROR</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- 主日志级别配置 -->
|
||||
<root level="${currentRootLevel}">
|
||||
<appender-ref ref="STDOUT" />
|
||||
<appender-ref ref="ALL_FILE" />
|
||||
<appender-ref ref="ERROR_FILE" />
|
||||
</root>
|
||||
|
||||
<!-- 项目日志级别配置 -->
|
||||
<logger name="com.jeequan.jeepay" level="${currentProjectLevel}"/>
|
||||
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user