master最新稳定代码

This commit is contained in:
amos wong
2025-05-10 21:08:14 +08:00
commit 0e3dba5b88
950 changed files with 70449 additions and 0 deletions

42
.gitignore vendored Normal file
View File

@@ -0,0 +1,42 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
#日志文件
logs

View File

@@ -0,0 +1,46 @@
FROM deepinnet-k8s-images-registry.cn-hangzhou.cr.aliyuncs.com/deepinnet/rdc-base:no-java
#FROM deepinnet-k8s-image-registry.cn-hangzhou.cr.aliyuncs.com/deepinnet/openjdk:8-jdk-alpine
#FROM openjdk:8-jdk-alpine
ARG jdk_versions="1.8"
RUN for version in ${jdk_versions}; \
do \
cd /tmp && \
wget -q https://rdc-public-software.oss-cn-hangzhou.aliyuncs.com/jdk/jdk${version}.tar.gz && \
mkdir -p /jdk/jdk${version} && \
tar xf jdk${version}.tar.gz -C /jdk/jdk${version} --strip-components 1 && \
ln -s /jdk/jdk${version} /jdk/jdk${version}/jvm && \
rm -f jdk${version}.tar.gz; \
done
RUN export JAVA_HOME=/jdk/jdk1.8 && \
export PATH=$JAVA_HOME/bin:$PATH && \
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
##
ENV BUILD_APP_NAME tptradecore
ENV SPRING_PROFILE dev
ARG APP_JAR=tptradecore.jar
RUN mkdir -p /home/$BUILD_APP_NAME/target
RUN echo "#!/bin/bash" >> /home/$BUILD_APP_NAME/start.sh
RUN echo "cd /home/$BUILD_APP_NAME/target/" >> /home/$BUILD_APP_NAME/start.sh
RUN echo "tar -xvf /home/$BUILD_APP_NAME/target/$BUILD_APP_NAME.tgz" >> /home/$BUILD_APP_NAME/start.sh
RUN echo "chmod 777 /home/$BUILD_APP_NAME/target/$BUILD_APP_NAME.jar" >> /home/$BUILD_APP_NAME/start.sh
RUN echo "exec /jdk/jdk1.8/bin/java -Djava.security.egd=file:/dev/./urandom -Dspring.profiles.active=${SPRING_PROFILE} -jar /home/$BUILD_APP_NAME/target/$BUILD_APP_NAME.jar" >> /home/$BUILD_APP_NAME/start.sh
RUN chmod +x /home/$BUILD_APP_NAME/*.sh
###
ADD $APP_JAR /home/$BUILD_APP_NAME/target/$BUILD_APP_NAME.tgz
WORKDIR /home/$BUILD_APP_NAME
ENTRYPOINT ["/bin/sh", "/home/tptradecore/start.sh"]
EXPOSE 8080

View File

@@ -0,0 +1,49 @@
FROM shendu-prod-registry.cn-hangzhou.cr.aliyuncs.com/deepinnet/rdc-base:no-java
#FROM deepinnet-k8s-image-registry.cn-hangzhou.cr.aliyuncs.com/deepinnet/openjdk:8-jdk-alpine
#FROM openjdk:8-jdk-alpine
ARG jdk_versions="11"
RUN for version in ${jdk_versions}; \
do \
cd /tmp && \
wget -q https://rdc-public-software.oss-cn-hangzhou.aliyuncs.com/jdk/jdk${version}.tar.gz && \
mkdir -p /jdk/jdk${version} && \
tar xf jdk${version}.tar.gz -C /jdk/jdk${version} --strip-components 1 && \
ln -s /jdk/jdk${version} /jdk/jdk${version}/jvm && \
rm -f jdk${version}.tar.gz; \
done
RUN export JAVA_HOME=/jdk/jdk${jdk_versions} && \
export PATH=$JAVA_HOME/bin:$PATH && \
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
RUN apt-get update && \
apt-get install -y fontconfig ttf-dejavu
##
ENV BUILD_APP_NAME tptradecore
ENV SPRING_PROFILE pre
ARG APP_JAR=tptradecore.jar
RUN mkdir -p /home/$BUILD_APP_NAME/target
RUN echo "#!/bin/bash" >> /home/$BUILD_APP_NAME/start.sh
RUN echo "cd /home/$BUILD_APP_NAME/target/" >> /home/$BUILD_APP_NAME/start.sh
RUN echo "tar -xvf /home/$BUILD_APP_NAME/target/$BUILD_APP_NAME.tgz" >> /home/$BUILD_APP_NAME/start.sh
RUN echo "chmod 777 /home/$BUILD_APP_NAME/target/$BUILD_APP_NAME.jar" >> /home/$BUILD_APP_NAME/start.sh
RUN echo "exec /jdk/jdk${jdk_versions}/bin/java -Djava.security.egd=file:/dev/./urandom -Dspring.profiles.active=${SPRING_PROFILE} -jar /home/$BUILD_APP_NAME/target/$BUILD_APP_NAME.jar" >> /home/$BUILD_APP_NAME/start.sh
RUN chmod +x /home/$BUILD_APP_NAME/*.sh
###
ADD $APP_JAR /home/$BUILD_APP_NAME/target/$BUILD_APP_NAME.tgz
WORKDIR /home/$BUILD_APP_NAME
ENTRYPOINT ["/bin/sh", "/home/tptradecore/start.sh"]
EXPOSE 8080

View File

@@ -0,0 +1,49 @@
FROM shendu-prod-registry.cn-hangzhou.cr.aliyuncs.com/deepinnet/rdc-base:no-java
#FROM deepinnet-k8s-image-registry.cn-hangzhou.cr.aliyuncs.com/deepinnet/openjdk:8-jdk-alpine
#FROM openjdk:8-jdk-alpine
ARG jdk_versions="11"
RUN for version in ${jdk_versions}; \
do \
cd /tmp && \
wget -q https://rdc-public-software.oss-cn-hangzhou.aliyuncs.com/jdk/jdk${version}.tar.gz && \
mkdir -p /jdk/jdk${version} && \
tar xf jdk${version}.tar.gz -C /jdk/jdk${version} --strip-components 1 && \
ln -s /jdk/jdk${version} /jdk/jdk${version}/jvm && \
rm -f jdk${version}.tar.gz; \
done
RUN export JAVA_HOME=/jdk/jdk${jdk_versions} && \
export PATH=$JAVA_HOME/bin:$PATH && \
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
RUN apt-get update && \
apt-get install -y fontconfig ttf-dejavu
##
ENV BUILD_APP_NAME tptradecore
ENV SPRING_PROFILE prod
ARG APP_JAR=tptradecore.jar
RUN mkdir -p /home/$BUILD_APP_NAME/target
RUN echo "#!/bin/bash" >> /home/$BUILD_APP_NAME/start.sh
RUN echo "cd /home/$BUILD_APP_NAME/target/" >> /home/$BUILD_APP_NAME/start.sh
RUN echo "tar -xvf /home/$BUILD_APP_NAME/target/$BUILD_APP_NAME.tgz" >> /home/$BUILD_APP_NAME/start.sh
RUN echo "chmod 777 /home/$BUILD_APP_NAME/target/$BUILD_APP_NAME.jar" >> /home/$BUILD_APP_NAME/start.sh
RUN echo "exec /jdk/jdk${jdk_versions}/bin/java -Djava.security.egd=file:/dev/./urandom -Dspring.profiles.active=${SPRING_PROFILE} -jar /home/$BUILD_APP_NAME/target/$BUILD_APP_NAME.jar" >> /home/$BUILD_APP_NAME/start.sh
RUN chmod +x /home/$BUILD_APP_NAME/*.sh
###
ADD $APP_JAR /home/$BUILD_APP_NAME/target/$BUILD_APP_NAME.tgz
WORKDIR /home/$BUILD_APP_NAME
ENTRYPOINT ["/bin/sh", "/home/tptradecore/start.sh"]
EXPOSE 8080

View File

@@ -0,0 +1,46 @@
FROM deepinnet-k8s-images-registry.cn-hangzhou.cr.aliyuncs.com/deepinnet/rdc-base:no-java
#FROM deepinnet-k8s-image-registry.cn-hangzhou.cr.aliyuncs.com/deepinnet/openjdk:8-jdk-alpine
#FROM openjdk:8-jdk-alpine
ARG jdk_versions="11"
RUN for version in ${jdk_versions}; \
do \
cd /tmp && \
wget -q https://rdc-public-software.oss-cn-hangzhou.aliyuncs.com/jdk/jdk${version}.tar.gz && \
mkdir -p /jdk/jdk${version} && \
tar xf jdk${version}.tar.gz -C /jdk/jdk${version} --strip-components 1 && \
ln -s /jdk/jdk${version} /jdk/jdk${version}/jvm && \
rm -f jdk${version}.tar.gz; \
done
RUN export JAVA_HOME=/jdk/jdk${jdk_versions} && \
export PATH=$JAVA_HOME/bin:$PATH && \
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
##
ENV BUILD_APP_NAME tptradecore
ENV SPRING_PROFILE test
ARG APP_JAR=tptradecore.jar
RUN mkdir -p /home/$BUILD_APP_NAME/target
RUN echo "#!/bin/bash" >> /home/$BUILD_APP_NAME/start.sh
RUN echo "cd /home/$BUILD_APP_NAME/target/" >> /home/$BUILD_APP_NAME/start.sh
RUN echo "tar -xvf /home/$BUILD_APP_NAME/target/$BUILD_APP_NAME.tgz" >> /home/$BUILD_APP_NAME/start.sh
RUN echo "chmod 777 /home/$BUILD_APP_NAME/target/$BUILD_APP_NAME.jar" >> /home/$BUILD_APP_NAME/start.sh
RUN echo "exec /jdk/jdk${jdk_versions}/bin/java -Djava.security.egd=file:/dev/./urandom -Dspring.profiles.active=${SPRING_PROFILE} -jar /home/$BUILD_APP_NAME/target/$BUILD_APP_NAME.jar" >> /home/$BUILD_APP_NAME/start.sh
RUN chmod +x /home/$BUILD_APP_NAME/*.sh
###
ADD $APP_JAR /home/$BUILD_APP_NAME/target/$BUILD_APP_NAME.tgz
WORKDIR /home/$BUILD_APP_NAME
ENTRYPOINT ["/bin/sh", "/home/tptradecore/start.sh"]
EXPOSE 8080

30
README.md Normal file
View File

@@ -0,0 +1,30 @@
## 命名规则:
groupId:统一使用com.deepinnet
<br/>
artifactIddeepinnet-应用名
包命名规范com.deepinnet.应用名.模块名
<br/>
举例com.deepinnet.tptradecore.biz
## 项目分层说明:
- tptradecore-app-starterSpringBoot应用启动类
- tptradecore-biz业务层
- tptradecore-biz-service-impl业务层的实现具体业务流程编排
- tptradecore-common通用层
- tptradecore-common-dal仓储层
- tptradecore-common-service
- tptradecore-common-service-facade需要向外界暴露的领域服务
- tptradecore-common-service-integration集成的第三方接口
- tptradecore-common-util工具
- tptradecore-core领域层
- tptradecore-core-service本系统内使用的service接口
- tptradecore-core-model领域模型
## 各模块依赖关系:
- biz负责业务流程编排依赖于common-service-facade、common-service-integration、
common-service-util、core-service
- core-service本系统内的服务 不需要向外暴露依赖core-model、
common-dal、common-util

463
pom.xml Normal file
View File

@@ -0,0 +1,463 @@
<?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.deepinnet</groupId>
<artifactId>tptradecore</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>tptradecore-api</module>
<module>tptradecore-app-starter</module>
<module>tptradecore-biz</module>
<module>tptradecore-common</module>
<module>tptradecore-core</module>
</modules>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--spring相关依赖-->
<spring.boot.version>2.6.11</spring.boot.version>
<spring.cloud.version>2021.0.4</spring.cloud.version>
<spring.cloud.alibaba.version>2021.0.4.0</spring.cloud.alibaba.version>
<spring-data-redis.version>2.6.0</spring-data-redis.version>
<!--中间件相关依赖-->
<mysql.version>8.0.28</mysql.version>
<druid.version>1.2.17</druid.version>
<mybatis-plus.version>3.5.3</mybatis-plus.version>
<rocketmq.version>2.3.0</rocketmq.version>
<jedis.verision>3.6.3</jedis.verision>
<dubbo.version>3.1.4</dubbo.version>
<schedulerx2.version>1.7.9</schedulerx2.version>
<schedulerx-plugin-kubernetes>1.0.1</schedulerx-plugin-kubernetes>
<!--第三方库-->
<lombok.version>1.18.24</lombok.version>
<jackson.version>2.13.4</jackson.version>
<common-lang3.version>3.12.0</common-lang3.version>
<commons-collections4.version>4.4</commons-collections4.version>
<hutool-all.version>5.8.9</hutool-all.version>
<hutool.version>5.8.9</hutool.version>
<knife.version>3.0.3</knife.version>
<bcprov-jdk15on.version>1.70</bcprov-jdk15on.version>
<jasypt.version>3.0.5</jasypt.version>
<pageHelper.version>1.4.7</pageHelper.version>
<redssion-spring-boot-starter.version>3.18.0</redssion-spring-boot-starter.version>
<redisson-spring-data.version>3.18.0</redisson-spring-data.version>
<okhttp.version>4.9.3</okhttp.version>
<curator.version>2.6.0</curator.version>
<perf4j.version>0.9.16</perf4j.version>
<commons-io.version>2.4</commons-io.version>
<aliyun-oss.version>3.15.1</aliyun-oss.version>
<mapstruct.version>1.5.0.Final</mapstruct.version>
<guava.version>32.1.1-jre</guava.version>
<IJPay.version>2.9.7</IJPay.version>
<xk-time.version>3.2.4</xk-time.version>
<alipay-sdk.version>4.39.123.ALL</alipay-sdk.version>
<spring-retry.version>1.3.4</spring-retry.version>
<easy-excel.version>3.1.4</easy-excel.version>
<!-- 深度智联内部二方包 -->
<deepinnet-common-boot-starter-version>1.0.0.20240227</deepinnet-common-boot-starter-version>
<tp-common-lang-version>1.0.0.20231218.1-SNAPSHOT</tp-common-lang-version>
<!--本项目各模块的版本-->
<tptradecore.version>1.0-SNAPSHOT</tptradecore.version>
<tptradecore-common-service-facade-version>1.0.0.20241014.1-SNAPSHOT</tptradecore-common-service-facade-version>
<tpcommoncore-common-service-facade-version>1.0.0.20240730-RELEASE</tpcommoncore-common-service-facade-version>
<tpbaseopcore-common-service-facade-version>202407.0.0-SNAPSHOT</tpbaseopcore-common-service-facade-version>
<tpconfigcore-common-service-facade-version>202405.0.1-RELEASE</tpconfigcore-common-service-facade-version>
<tpproductcore-common-service-facade-version>202407.0.0-RELEASE</tpproductcore-common-service-facade-version>
</properties>
<dependencyManagement>
<dependencies>
<!-- 引入deepinnet-common-boot-starter -->
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>deepinnet-common-boot-starter</artifactId>
<version>${deepinnet-common-boot-starter-version}</version>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tp-common-lang</artifactId>
<version>${tp-common-lang-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--中间件相关依赖-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bom</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-common-service-integration</artifactId>
<version>${tptradecore.version}</version>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-common-util</artifactId>
<version>${tptradecore.version}</version>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-biz-service-impl</artifactId>
<version>${tptradecore.version}</version>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-api</artifactId>
<version>${tptradecore.version}</version>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-core-service</artifactId>
<version>${tptradecore.version}</version>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-common-dal</artifactId>
<version>${tptradecore.version}</version>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-core-model</artifactId>
<version>${tptradecore.version}</version>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-common-service-facade</artifactId>
<version>${tptradecore-common-service-facade-version}</version>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tpcommoncore-common-service-facade</artifactId>
<version>${tpcommoncore-common-service-facade-version}</version>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tpbaseopcore-common-service-facade</artifactId>
<version>${tpbaseopcore-common-service-facade-version}</version>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tpconfigcore-common-service-facade</artifactId>
<version>${tpconfigcore-common-service-facade-version}</version>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tpproductcore-common-service-facade</artifactId>
<version>${tpproductcore-common-service-facade-version}</version>
</dependency>
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>${jasypt.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<!--dubbo-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.perf4j</groupId>
<artifactId>perf4j</artifactId>
<version>${perf4j.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>${bcprov-jdk15on.version}</version>
</dependency>
<!-- oss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>${aliyun-oss.version}</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>${rocketmq.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>${spring-retry.version}</version>
</dependency>
<!-- knife -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>${knife.version}</version>
</dependency>
<!--schedulerx2-->
<dependency>
<groupId>com.aliyun.schedulerx</groupId>
<artifactId>schedulerx2-spring-boot-starter</artifactId>
<version>${schedulerx2.version}</version>
<!--如果用的是logback需要把log4j和log4j2排除掉 -->
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.aliyun.schedulerx</groupId>
<artifactId>schedulerx2-plugin-kubernetes</artifactId>
<version>${schedulerx-plugin-kubernetes}</version>
</dependency>
<!-- redisson -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.redssion</groupId>
<artifactId>redisson-spring-data-27</artifactId>
</exclusion>
</exclusions>
<version>${redssion-spring-boot-starter.version}</version>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-data-26</artifactId>
<version>${redisson-spring-data.version}</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pageHelper.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>${easy-excel.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>com.github.javen205</groupId>
<artifactId>IJPay-All</artifactId>
<version>${IJPay.version}</version>
</dependency>
<dependency>
<groupId>com.github.xkzhangsan</groupId>
<artifactId>xk-time</artifactId>
<version>${xk-time.version}</version>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>${alipay-sdk.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>deepinnet-common-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tp-common-lang</artifactId>
<exclusions>
<exclusion>
<artifactId>okhttp</artifactId>
<groupId>com.squareup.okhttp3</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!--jackson-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${common-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
</dependencies>
</project>

37
tptradecore-api/pom.xml Normal file
View File

@@ -0,0 +1,37 @@
<?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.deepinnet</groupId>
<artifactId>tptradecore</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>tptradecore-api</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-biz-service-impl</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,48 @@
package com.deepinnet.tptradecore.controller;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tptradecore.common.dto.order.*;
import com.deepinnet.tptradecore.common.service.facade.order.TpOrderDispatchFacade;
import com.deepinnet.tptradecore.common.service.facade.order.TpOrderReceivedFacade;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
/**
* <p>
* 订单派单
* </p>
*
* @author xiehuaqiao
* @since 2023/11/13
*/
@Api(tags = "订单派单")
@CrossOrigin
@RestController("/order/")
public class OrderDispatchController {
@Resource
private TpOrderDispatchFacade tpOrderDispatchFacade;
@Resource
private TpOrderReceivedFacade tpOrderReceivedFacade;
@ApiOperation(value = "订单分配")
@PostMapping("/dispatchOrder")
public TpResult<Boolean> dispatchOrder (@RequestBody @NotNull(message = "入参不能为空") TpOrderDispatchCreatedDTO dto) {
return tpOrderDispatchFacade.dispatchOrder(dto);
}
@ApiOperation(value = "用户接单")
@PostMapping("/receiveOrder")
public TpResult<Boolean> receiveOrder (@RequestBody @NotNull(message = "入参不能为空") TpOrderReceivedCreatedDTO dto) {
return tpOrderReceivedFacade.receiveOrder(dto);
}
}

View File

@@ -0,0 +1,141 @@
package com.deepinnet.tptradecore.controller.pay;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.log.LogFormatHelper;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.service.impl.*;
import org.slf4j.*;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.*;
import java.util.*;
/**
* @author amos wong
* @create 2022-11-16 17:12
* <p>
* 第三方支付平台的api接口
*/
@RestController
@CrossOrigin
public class PaymentController {
@Resource
private AlipayCallbackService alipayCallbackService;
@Resource
private WechatPayCallbackService wechatPayCallbackService;
@Resource
private WechatRefundCallbackService wechatRefundCallbackService;
private static final Logger BIZ_DIGEST_LOG = LoggerFactory.getLogger("BIZ-DIGEST-LOG");
/**
* 接收支付宝支付结果的回调接口
*
* @param request
*/
@PostMapping("/alipay/pay/callback")
public String processAlipayCallback(HttpServletRequest request) {
Long startTime = System.currentTimeMillis();
Exception ex = null;
try {
LogUtil.info("接收到支付宝回调请求:{}", request);
alipayCallbackService.processPayResultCallback(request);
} catch (Exception e) {
ex = e;
LogUtil.error("支付宝支付回调接口处理失败,原因:{}", e);
return "fail";
} finally {
boolean isSuccess = ex == null;
LogUtil.info(BIZ_DIGEST_LOG, "{}", LogFormatHelper.logFormat(startTime, "PaymentController", "processAlipayCallback", isSuccess, ex));
}
LogUtil.info("支付宝回调请求处理成功");
return "success";
}
/**
* 接收微信支付结果的回调接口
*
* @param request
*/
@PostMapping(value = "/wechat/pay/callback")
public Map<String, String> processWechatPaySuccessCallback(HttpServletRequest request) {
Long startTime = System.currentTimeMillis();
Exception ex = null;
try {
LogUtil.info("接收到微信支付支付成功回调通知");
wechatPayCallbackService.processPayResultCallback(request);
LogUtil.info("微信回调请求处理成功");
return generateSuccessResultMap();
} catch (TpTradeCoreException e) {
ex = e;
if (e.getErrorCode() == TpTradeCoreErrorCode.IDEMPOTENT_REQUEST_ERROR) {
// 幂等处理,告知微信已经处理成功了
return generateSuccessResultMap();
}
LogUtil.error("微信支付回调接口处理失败,原因:{}", e);
return generateFailResultMap();
} catch (Exception e) {
ex = e;
LogUtil.error("微信支付回调接口处理失败,原因:{}", e);
return generateFailResultMap();
} finally {
boolean isSuccess = ex == null;
LogUtil.info(BIZ_DIGEST_LOG, "{}", LogFormatHelper.logFormat(startTime, "PaymentController", "processWechatPaySuccessCallback", isSuccess, ex));
}
}
/**
* 接收微信支付退款结果的回调接口
*
* @param request
*/
@PostMapping(value = "/wechat/refund/callback")
public Map<String, String> processWechatRefundCallback(HttpServletRequest request) {
Long startTime = System.currentTimeMillis();
Exception ex = null;
try {
LogUtil.info("接收到微信支付退款回调通知");
wechatRefundCallbackService.processRefundSuccessCallback(request);
LogUtil.info("微信支付退款成功回调处理成功");
return generateSuccessResultMap();
} catch (TpTradeCoreException e) {
ex = e;
if (e.getErrorCode() == TpTradeCoreErrorCode.IDEMPOTENT_REQUEST_ERROR) {
// 幂等处理,告知微信已经处理成功了
return generateSuccessResultMap();
}
return generateFailResultMap();
} catch (Exception e) {
LogUtil.error("微信支付退款成功回调接口处理失败,原因:{}", e);
return generateFailResultMap();
} finally {
boolean isSuccess = ex == null;
LogUtil.info(BIZ_DIGEST_LOG, "{}", LogFormatHelper.logFormat(startTime, "PaymentController", "processWechatRefundCallback", isSuccess, ex));
}
}
private Map<String, String> generateSuccessResultMap() {
Map<String, String> resultMap = new HashMap<>();
resultMap.put("code", "SUCCESS");
resultMap.put("message", "成功");
return resultMap;
}
private Map<String, String> generateFailResultMap() {
Map<String, String> resultMap = new HashMap<>();
resultMap.put("code", "FAIL");
resultMap.put("message", "失败");
return resultMap;
}
}

View File

@@ -0,0 +1,43 @@
package com.deepinnet.tptradecore.controller.test;
import com.deepinnet.tp.common.lang.util.TpMoney;
import com.deepinnet.tptradecore.common.service.integration.client.TpAliPayClient;
import com.deepinnet.tptradecore.common.service.integration.dto.*;
import org.springframework.security.core.parameters.P;
import com.deepinnet.tptradecore.core.service.task.CommonScheduleTaskExecuteTemplate;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.time.LocalDateTime;
/**
* @author amos wong
* @create 2022-11-16 17:12
* <p>
* 第三方支付平台的api接口
*/
@RestController
@CrossOrigin
@RequestMapping(value = "/alipay")
public class AlipayTestController {
@Resource
private TpAliPayClient aliPayClient;
@Resource
private CommonScheduleTaskExecuteTemplate scheduleTaskExecuteTemplate;
@PostMapping("/prepay")
public String alipayPrepay(@RequestBody PayPlatformPreparePayDTO preparePayDTO) {
TpMoney payAmount = new TpMoney("0.01", TpMoney.ValueUnitEnum.YUAN);
preparePayDTO.setPayAmount(payAmount);
preparePayDTO.setPayTimeout(LocalDateTime.now().plusHours(1));
preparePayDTO.setUserIp("192.168.3.200");
return aliPayClient.preparePay(preparePayDTO);
}
@PostMapping("/task")
public void executeScheduleTask() {
scheduleTaskExecuteTemplate.process();
}
}

View File

@@ -0,0 +1,52 @@
package com.deepinnet.tptradecore.controller.test;
import com.deepinnet.tp.common.lang.page.CommonPage;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tptradecore.common.dto.contract.*;
import com.deepinnet.tptradecore.common.dto.voucher.TpVoucherDTO;
import com.deepinnet.tptradecore.common.service.facade.contract.TpContractFacade;
import com.deepinnet.tptradecore.common.vo.contract.*;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* @author amos wong
* @create 2023/8/7 17:23
* @Description
*/
@RestController
@CrossOrigin
public class ContractTestController {
@Resource
private TpContractFacade contractFacade;
@PostMapping("/contract/refund")
public TpResult<String> refundTicket(@RequestBody @Validated TpRefundApplyDTO refundApplyDTO) {
return contractFacade.refundTicket(refundApplyDTO);
}
@PostMapping("/contract/query")
public TpResult<List<TpRefundApplyOrderDTO>> queryRefundApplyOrders(@RequestBody @Validated TpQueryRefundApplyOrderDTO queryDTO) {
return contractFacade.getRefundApplyOrderList(queryDTO);
}
@PostMapping("/contract/page")
public TpResult<CommonPage<TpRefundApplyOrderDTO>> pageQueryApplyOrders(@RequestBody @Validated TpPageQueryRefundApplyOrderDTO queryDTO) {
return contractFacade.pageQueryApplyRefundOrders(queryDTO);
}
@PostMapping("/contract/detail")
public TpResult<TpQueryRefundDetailVO> getRefundDetail(@RequestBody @Validated TpQueryRefundDetailDTO queryDTO) {
return contractFacade.getRefundDetail(queryDTO);
}
@PostMapping("/contract/refund/available")
public TpResult<List<TpVoucherDTO>> getRefundAvailableVoucherList(@RequestBody @Validated TpQueryAvailableRefundVoucherDTO queryDTO) {
return contractFacade.queryAvailableRefundVoucherList(queryDTO);
}
}

View File

@@ -0,0 +1,124 @@
package com.deepinnet.tptradecore.controller.test;
import com.deepinnet.tp.common.lang.page.CommonPage;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tptradecore.common.dto.order.*;
import com.deepinnet.tptradecore.common.service.facade.order.*;
import com.deepinnet.tptradecore.common.vo.order.*;
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* <p>
* 测试接口
* </p>
*
* @author chenjiaju
* @since 2023/8/21
*/
@Api(tags = "订单接口")
@CrossOrigin
@RestController
@RequestMapping(value = "/order")
public class OrderTestController {
@Resource
private TpUserPassengerFacade tpUserPassengerFacade;
@Resource
private TpOrderFacade tpOrderFacade;
@GetMapping("/test")
public TpResult<TpOrderDetailVO> test() {
return tpOrderFacade.getOrderDetail(TpOrderQueryDTO.builder()
.originalOrderNo("20231108006000009008")
.tenantId("test").build());
}
@ApiOperation(value = "创建订单")
@PostMapping("/createOrder")
public TpResult<TpOrderCreateVO> createOrder(@RequestBody @NotNull(message = "入参不能为空") TpOrderCreateDTO dto) {
return tpOrderFacade.createOrder(dto);
}
@ApiOperation(value = "改签订单")
@PostMapping("/endorse")
public TpResult<TpOrderEndorseVO> endorseOrdder(@RequestBody @NotNull(message = "入参不能为空") TpOrderCreateDTO dto) {
return tpOrderFacade.endorseOrder(dto);
}
@ApiOperation(value = "保存用户乘客信息")
@PostMapping("/saveUserPassenger")
public TpResult<String> savePassenger(@RequestBody @NotNull(message = "入参不能为空") TpUserPassengerDTO dto) {
return tpUserPassengerFacade.saveUserPassenger(dto);
}
@ApiOperation(value = "支付订单")
@PostMapping("/payOrder")
public TpResult<TpOrderPayVO> payOrder(@RequestBody @NotNull(message = "入参不能为空") TpOrderPayDTO dto) {
return tpOrderFacade.payOrder(dto);
}
@ApiOperation(value = "删除乘客信息")
@PostMapping("/delUserPassenger")
public TpResult<Boolean> delUserPassenger(@RequestBody @NotNull(message = "入参不能为空") TpUserPassengerQueryDTO dto) {
return tpUserPassengerFacade.delUserPassenger(dto);
}
@ApiOperation(value = "编辑乘客信息")
@PostMapping("/modifyPassenger")
public TpResult<Boolean> modifyPassenger(@RequestBody @NotNull(message = "入参不能为空") TpUserPassengerDTO dto) {
return tpUserPassengerFacade.modifyPassenger(dto);
}
@ApiOperation(value = "查询乘客列表")
@PostMapping("/passengerList")
public TpResult<List<TpUserPassengerVO>> queryPassengerList(@RequestBody @NotNull(message = "入参不能为空") TpUserPassengerQueryDTO dto) {
return tpUserPassengerFacade.queryPassengerList(dto);
}
@ApiOperation(value = "查询订单列表")
@PostMapping("/orderList")
public TpResult<CommonPage<TpOrderListVO>> orderList(@RequestBody @NotNull(message = "入参不能为空") TpOrderListQueryDTO dto) {
return tpOrderFacade.orderList(dto);
}
@ApiOperation(value = "查询订单列表--预约包车--C端")
@PostMapping("/charterBusOrderListToC")
public TpResult<CommonPage<TpOrderListVO>> charterBusOrderListToC(@RequestBody @NotNull(message = "入参不能为空") TpOrderListQueryDTO dto) {
return tpOrderFacade.charterBusOrderListToC(dto);
}
@ApiOperation(value = "查询订单列表--预约包车--B端")
@PostMapping("/charterBusOrderListToB")
public TpResult<CommonPage<TpOrderListVO>> charterBusOrderListToB(@RequestBody @NotNull(message = "入参不能为空") TpOrderListQueryDTO dto) {
return tpOrderFacade.charterBusOrderListToB(dto);
}
@ApiOperation(value = "查询订单详情")
@PostMapping("/orderDetail")
public TpResult<TpOrderDetailVO> getOrderDetail(@RequestBody @NotNull(message = "入参不能为空") TpOrderQueryDTO dto) {
return tpOrderFacade.getOrderDetail(dto);
}
@ApiModelProperty(value = "上传发票")
@PostMapping("/saveInvoice")
public TpResult<Boolean> saveInvoice(@RequestBody TpOrderInvoiceDTO dto) {
return tpOrderFacade.saveInvoice(dto);
}
@PostMapping("/carpool/check")
public TpResult<Boolean> carpoolCheckCallback(@RequestBody TpCheckSuccessCallbackDTO checkSuccessCallbackDTO) {
return tpOrderFacade.checkSuccessCallback(checkSuccessCallbackDTO);
}
@PostMapping("/carpool/cancel")
public TpResult<Boolean> cancelCarpoolOrder(@RequestBody TpCancelCarpoolDTO cancelCarpoolDTO) {
return tpOrderFacade.cancelOrCarpoolFailOrder(cancelCarpoolDTO);
}
}

View File

@@ -0,0 +1,217 @@
package com.deepinnet.tptradecore.controller.test;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.json.*;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tp.common.lang.util.*;
import com.deepinnet.tpbaseopcore.common.dto.pay.OrgWxPayDTO;
import com.deepinnet.tptradecore.common.dto.trans.*;
import com.deepinnet.tptradecore.common.service.facade.trans.TpPaymentFacade;
import com.deepinnet.tptradecore.common.service.integration.client.*;
import com.deepinnet.tptradecore.common.service.integration.dto.*;
import com.deepinnet.tptradecore.common.vo.trans.*;
import com.ijpay.core.IJPayHttpResponse;
import com.ijpay.core.enums.RequestMethodEnum;
import com.ijpay.core.kit.*;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.enums.WxDomainEnum;
import com.ijpay.wxpay.enums.v3.OtherApiEnum;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;
import java.time.LocalDateTime;
/**
* @author amos wong
* @create 2023/10/10 16:53
* @Description
*/
@RestController
@CrossOrigin
public class PaymentTestController {
@Resource
private TpPaymentFacade paymentFacade;
@Resource
private TpWechatPayClientV2 wechatPayClientV2;
@Resource
private TpWechatPayClient wechatPayClient;
@Resource
private TpOrgClient orgClient;
@PostMapping("/wechat/v2/prepay")
public String prepay(@RequestBody PayPlatformPreparePayDTO preparePayRequestDTO) {
preparePayRequestDTO.setPayTimeout(LocalDateTime.now().plusHours(24));
preparePayRequestDTO.setPayAmount(new TpMoney("0.01", TpMoney.ValueUnitEnum.YUAN));
return wechatPayClientV2.preparePay(preparePayRequestDTO);
}
@PostMapping("/wechat/v3/prepay")
public String prepayV3(@RequestBody PayPlatformPreparePayDTO preparePayRequestDTO) {
preparePayRequestDTO.setPayTimeout(LocalDateTime.now().plusHours(24));
preparePayRequestDTO.setPayAmount(new TpMoney("0.01", TpMoney.ValueUnitEnum.YUAN));
return wechatPayClient.preparePay(preparePayRequestDTO);
}
@PostMapping("/wechat/v3/refund")
public TpRefundResultDTO refundV3(@RequestBody PayPlatformRefundDTO refundDTO) {
return wechatPayClient.refund(refundDTO);
}
@RequestMapping("/get/platformCert")
@ResponseBody
public String v3Get() {
// 获取平台证书列表
try {
IJPayHttpResponse response = WxPayApi.v3(
RequestMethodEnum.GET,
WxDomainEnum.CHINA.toString(),
OtherApiEnum.GET_CERTIFICATES.toString(),
"1668231818",
"6812B7131474C248CE239C715831AD73CA56F856",
null,
PayKit.getPrivateKeyByKeyContent("-----BEGIN PRIVATE KEY-----\n" +
"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC1Lzv8fbtZrYKL\n" +
"q2HuccYJFzIRCk5sazyIlKxZKYhOpDjquP+wnUGQ+ffcQYCI2j1zjkz0cDYR7+ZC\n" +
"OuirmV0tKhZTbTAJCFfxShQ7VZ1mJ48RONiUxxnNph5xeJ/6HuGyopUiCbTKdK++\n" +
"goWkV//iOOE/qf993WLk+oa3DTgB8va/0ahK3+XUZb2y1DXI85eilgqTIMfj5+cv\n" +
"dLyMqy/+sw+fSDY+lk2Wec/mTQUZ+RjDbFLpHgTot90nx9udg7+tpT/2q+zHKdS/\n" +
"Av+M0FRqV/D1Kl4SemykjVcvk8Vk71FfYRElmnxChmvc9IFWyC+e+SAakLnUx5lm\n" +
"b3MOcp8JAgMBAAECggEAB3va+3PqECs1kDVVBzdV2bxGiiOl156aUn3pnIk1oyHv\n" +
"Y+qeTRpBwg5BKaze9Ugmb6Z6EUKtSRJirWunfqcIDTyGzY1eBZF9qG7J5SWFKdoK\n" +
"c8ioUYTj0PXCnidAXGF4KxvCEzTZbd9h/vl/Mamc3ShCTZHlBrrlQdYDSH5YSORB\n" +
"duJ7aMdnoPp6JRnVSg4o8+Cg0wVaxo7UXdcB6agPHxzeKmMwpiuJT/Y8tiAhOmRw\n" +
"z14+nrVgWZjgl8kUQfy7bvLgLMiui9zW66QrINQIrUwBLmrAugZtYdDsDK8qzAyu\n" +
"1PnC8Jse5r/OUqJlP79177X5/XBCWS56K5h3epA4TQKBgQDcrVtldktnVoY4jv5M\n" +
"175zHWWcfyZrkbalHQaX5ZKEDX8HCHvjXstBT47jGiScdXiUt3s398y3hBLijKlX\n" +
"oG4N65IJ1U6hSvakG0qeuAgIM9BByG0dRI0P4m8qP/bEPg3DfhXaMNQ8wouxwauE\n" +
"AQ9wwBXQqcGj9XiUuBduZjTsQwKBgQDSL5gvCmhi11NzZpqT70YR4vKD3Lt9tmEF\n" +
"3MYdx+oqFPOa9W3AKaJulRMl4hzusWUSTCZBJzj+DT2YqecwMZJkVfPlrwsVJpP0\n" +
"itcKZRSRT+egkjf9rlONuOp1ad8QKv8qbNKNQ3NbaQbTOHBvp+4c201yG8RrUlJj\n" +
"t3TzEHw4wwKBgFhtKuN0THDDLhN50RLPnKQaEn5sQOP3xp1RDTROrLA3jEAwORx5\n" +
"/q5UB+iesC71r3TANSLPK/wZc0vOm4jeY1s2mxVPoStmk4Bc40DIc4d946SIgJiq\n" +
"wG+uB2eBrAsk5nUAkBcXW+Rg/IMlHOpPVnWSsusjKtHdag0F23XEhM5rAoGBAJFl\n" +
"ORn5UiJln6WpqW6CS29eFbLfw5b/zXf3s9iwDS0VFzrvYf9XDbT/TKKdGrSHZEpX\n" +
"APN7BXLAiAaOKY3uDL15s+EDyF/WMu0sCft31tV6d9lcrHzA1a2o6A9WsGaHx8F6\n" +
"S+BKc4cdTQpZ9XVXrmCp15YC3Un8RWATbUQi+DtvAoGBAIK4uPODRCfZM6q8a57U\n" +
"vlyw/BD21WwujIzctsDINYaoG2ncanBI5CynXW4o6X+tGAZrNQZkIai+tl2JCbTt\n" +
"/qVIIV9qmEUyJ9t97UMEPKCYqYTDdXQGzk3i+1XGMqS1luRFfMohUv5JUAdwmS7b\n" +
"pnFZK2M1/Dr9GwBiz8UqgUqx\n" +
"-----END PRIVATE KEY-----\n"),
""
);
String timestamp = response.getHeader("Wechatpay-Timestamp");
String nonceStr = response.getHeader("Wechatpay-Nonce");
String serialNumber = response.getHeader("Wechatpay-Serial");
String signature = response.getHeader("Wechatpay-Signature");
String body = response.getBody();
int status = response.getStatus();
int isOk = 200;
if (status == isOk) {
JSONObject jsonObject = JSONUtil.parseObj(body);
JSONArray dataArray = jsonObject.getJSONArray("data");
// 默认认为只有一个平台证书
JSONObject encryptObject = dataArray.getJSONObject(0);
JSONObject encryptCertificate = encryptObject.getJSONObject("encrypt_certificate");
String associatedData = encryptCertificate.getStr("associated_data");
String cipherText = encryptCertificate.getStr("ciphertext");
String nonce = encryptCertificate.getStr("nonce");
String serialNo = encryptObject.getStr("serial_no");
final String platSerialNo = savePlatformCert(associatedData, nonce, cipherText, "/Users/amos/Downloads/项目文档/微信支付/微信支付密钥/平台证书序列号222.txt");
LogUtil.info("serialNo:{}", serialNo);
LogUtil.info("platSerialNo:{}", platSerialNo);
}
// 根据证书序列号查询对应的证书来验证签名结果
boolean verifySignature = WxPayKit.verifySignature(response, "/Users/amos/Downloads/项目文档/微信支付/微信支付密钥/平台证书序列号222.txt");
System.out.println("verifySignature:" + verifySignature);
return body;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private String savePlatformCert(String associatedData, String nonce, String cipherText, String certPath) {
try {
AesUtil aesUtil = new AesUtil("Shenduzhilian168188Shenduzhilian".getBytes(StandardCharsets.UTF_8));
// 平台证书密文解密
// encrypt_certificate 中的 associated_data nonce ciphertext
String publicKey = aesUtil.decryptToString(
associatedData.getBytes(StandardCharsets.UTF_8),
nonce.getBytes(StandardCharsets.UTF_8),
cipherText
);
// 保存证书
FileWriter writer = new FileWriter(certPath);
writer.write(publicKey);
// 获取平台证书序列号
X509Certificate certificate = PayKit.getCertificate(new ByteArrayInputStream(publicKey.getBytes()));
return certificate.getSerialNumber().toString(16).toUpperCase();
} catch (Exception e) {
e.printStackTrace();
return e.getMessage();
}
}
@PostMapping(value = "/prepay", headers = "Referer=https://dev-travel-h5.deepinnet.com")
public TpResult<TpPreparePayVO> prepay(@RequestBody TpPreparePayDTO prepayDTO) {
TpPayOrderCreateDTO createDTO = prepayDTO.getCreateDTO();
createDTO.setPaymentAmount(new TpMoney("136.00", TpMoney.ValueUnitEnum.YUAN));
createDTO.setDiscountAmount(new TpMoney("0.00", TpMoney.ValueUnitEnum.YUAN));
return paymentFacade.preparePay(prepayDTO);
}
@PostMapping("/refund")
public String refund(@RequestBody TpPayRefundDTO refundDTO) {
refundDTO.setRefundAmount(new TpMoney("136", TpMoney.ValueUnitEnum.YUAN));
refundDTO.setChargeAmount(new TpMoney("0", TpMoney.ValueUnitEnum.YUAN));
paymentFacade.refund(refundDTO);
return "success";
}
@PostMapping("/get/refund")
public void queryRefundResult(@RequestBody TpQueryRefundResultDTO refundResultDTO) {
TpResult<TpQueryRefundResultVO> result = paymentFacade.queryRefundResult(refundResultDTO);
LogUtil.info("查询退款结果:{}", result);
}
@PostMapping("/get/pay/result")
public void queryPayResult(@RequestBody TpQueryPayResultDTO payResultDTO) {
TpResult<TpQueryPayResultVO> resultVO = paymentFacade.queryPayResult(payResultDTO);
LogUtil.info("查询支付结果:{}", resultVO);
}
@PostMapping("/close")
public void closePayOrder(@RequestBody TpPayOrderCloseDTO dto) {
TpResult<Boolean> result = paymentFacade.closePayOrder(dto);
}
@ApiOperation("根据微信平台证书序列号获取微信支付配置")
@PostMapping("/pay/platSerialNo")
public TpResult<OrgWxPayDTO> getWechatConfigByPlatSerialNo(String platSerialNo) {
OrgWxPayDTO wxPayConfig = orgClient.getWxPayByPlatSerialNo(platSerialNo);
return TpResult.success(wxPayConfig);
}
@ApiOperation("线下支付,标记支付成功")
@PostMapping("/pay/offline")
public TpResult<Boolean> paidOffline(@RequestBody TpPaidOfflineDTO paidOfflineDTO) {
return paymentFacade.paidOffline(paidOfflineDTO);
}
@PostMapping("/pay/reschedule")
public TpResult<Boolean> reschedulePaidSuccess(@RequestBody TpReschedulePaidSuccessDTO reschedulePaidSuccessDTO) {
return paymentFacade.reschedulePaidSuccess(reschedulePaidSuccessDTO);
}
}

View File

@@ -0,0 +1,223 @@
package com.deepinnet.tptradecore.controller.test;
import cn.hutool.json.JSONUtil;
import com.deepinnet.tp.common.lang.page.CommonPage;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tpproductcore.common.dto.rule.*;
import com.deepinnet.tpproductcore.common.enums.TpRuleExpressionGroupEnum;
import com.deepinnet.tptradecore.common.dal.convert.task.TpScheduleTaskMapStructConvert;
import com.deepinnet.tptradecore.common.dal.dataobject.task.TpScheduleTaskDO;
import com.deepinnet.tptradecore.common.dal.repository.task.TpScheduleTaskRepository;
import com.deepinnet.tptradecore.common.dal.repository.voucher.TpVoucherVerificationRecordRepository;
import com.deepinnet.tptradecore.common.dto.voucher.*;
import com.deepinnet.tptradecore.common.enums.voucher.*;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.common.service.facade.voucher.TpVoucherFacade;
import com.deepinnet.tptradecore.common.service.integration.client.TpBizRuleClient;
import com.deepinnet.tptradecore.common.service.integration.mq.constants.*;
import com.deepinnet.tptradecore.common.service.integration.mq.entity.*;
import com.deepinnet.tptradecore.common.service.integration.mq.template.MessageClient;
import com.deepinnet.tptradecore.common.vo.voucher.*;
import com.deepinnet.tptradecore.core.model.task.TpScheduleTask;
import com.deepinnet.tptradecore.core.model.voucher.TpVoucher;
import com.deepinnet.tptradecore.core.service.task.worker.VoucherExpiredWorker;
import com.deepinnet.tptradecore.core.service.voucher.TpVoucherDomainService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
/**
* @author amos wong
* @create 2023/8/7 17:23
* @Description
*/
@RestController
@CrossOrigin
public class VoucherTestController {
@Resource
private TpVoucherFacade voucherFacade;
@Resource
private TpVoucherDomainService voucherDomainService;
@Resource
private MessageClient messageClient;
@Resource
private TpBizRuleClient bizRuleClient;
@Resource
private VoucherExpiredWorker voucherExpiredWorker;
@Resource
private TpScheduleTaskMapStructConvert taskMapStructConvert;
@Resource
private TpScheduleTaskRepository scheduleTaskRepository;
@Resource
private TpVoucherVerificationRecordRepository verificationRecordRepository;
@PostMapping("/voucher/create")
public TpResult<Boolean> createVoucher(@RequestBody @Validated TpVoucherCreateDTO createDTO) {
return voucherFacade.createVoucher(createDTO);
}
@PostMapping("/voucher/list")
public TpResult<List<TpVoucherDTO>> listVoucher(@RequestBody @Validated TpVoucherQueryDTO queryDTO) {
return voucherFacade.getOrderDetailVoucherList(queryDTO);
}
@PostMapping("/voucher/check")
public TpResult<TpVoucherCheckVO> checkVoucher(@RequestBody @Validated TpVoucherCheckDTO checkDTO) {
return voucherFacade.check(checkDTO);
}
@PostMapping("/voucher/village/check")
public TpResult<Boolean> villageCheck(@RequestBody @Validated TpVoucherCheckSuccessDTO checkDTO) {
return voucherFacade.villageBatchCheckSuccess(checkDTO);
}
@PostMapping("/voucher/invalid")
public TpResult<Boolean> invalidVoucher(@RequestBody @Validated List<TpVoucherUpdateDTO> updateDTOS) {
return voucherFacade.invalidVoucher(updateDTOS);
}
@PostMapping("/voucher/count")
public TpResult<TpBuyLimitQueryVoucherVO> queryBuyLimitNeedVoucherCount(@RequestBody TpBuyLimitQueryVoucherDTO queryDTO) {
return voucherFacade.queryBuyLimitNeedVoucherCount(queryDTO);
}
@PostMapping("/voucher/expire/msg")
public void testExpireMsg(String voucherNo, String tenantId) {
TpVoucherQueryDTO queryDTO = new TpVoucherQueryDTO();
TpVoucher voucher = voucherDomainService.getVoucher(queryDTO.setVoucherNo(voucherNo).setTenantId(tenantId));
String orderNo = voucher.getOrderNo();
TpVoucherQueryDTO queryVoucherDTO = new TpVoucherQueryDTO();
List<TpVoucher> voucherList = voucherDomainService.getVoucherList(queryVoucherDTO.setOrderNo(orderNo).setTenantId(tenantId));
TpVoucher curVoucher = voucherList.get(0);
if (StringUtils.equals(curVoucher.getType(), TpVoucherTypeEnum.DAY.getCode())) {
BaseMessageEntity expireMessageEntity = buildVoucherExpireMsg(voucherNo, orderNo, tenantId);
messageClient.send(messageClient.getMessageTopic(), MessageConstants.EVENT_CODE_VOUCHER_EXPIRED_SUCCESS, expireMessageEntity);
} else {
// 如果是月票
voucherList.sort(Comparator.comparing(TpVoucher::getEffectiveEndTime));
TpVoucher tpVoucher = voucherList.get(voucherList.size() - 1);
if (StringUtils.equals(tpVoucher.getVoucherNo(), curVoucher.getVoucherNo())) {
BaseMessageEntity expireMessageEntity = buildVoucherExpireMsg(voucherNo, orderNo, tenantId);
messageClient.send(messageClient.getMessageTopic(), MessageConstants.EVENT_CODE_VOUCHER_EXPIRED_SUCCESS, expireMessageEntity);
}
}
voucherDomainService.expireVoucher(voucherNo, tenantId);
}
private BaseMessageEntity buildVoucherExpireMsg(String voucherNo, String orderNo, String tenantId) {
BaseMessageEntity baseMessageEntity = new BaseMessageEntity();
baseMessageEntity.setSource(MessageSysConstants.SOURCE_VOUCHER);
baseMessageEntity.setKey(voucherNo);
baseMessageEntity.setSendTime(LocalDateTime.now());
VoucherExpireMessageEntity expireMessageEntity = new VoucherExpireMessageEntity();
List<TpVoucher> voucherList = getVoucherList(orderNo, tenantId);
boolean existValid = voucherList.stream()
.anyMatch(voucher -> StringUtils.equals(voucher.getStatus(), TpVoucherStatusEnum.CREATED.getCode())
|| StringUtils.equals(voucher.getStatus(), TpVoucherStatusEnum.PARTIAL_VERIFIED.getCode()));
expireMessageEntity.setExistValid(existValid);
expireMessageEntity.setVoucherNo(voucherNo);
expireMessageEntity.setOrderNo(orderNo);
expireMessageEntity.setTenantId(tenantId);
baseMessageEntity.setBody(JSONUtil.toJsonStr(expireMessageEntity));
return baseMessageEntity;
}
private List<TpVoucher> getVoucherList(String orderNo, String tenantId) {
TpVoucherQueryDTO queryDTO = new TpVoucherQueryDTO();
List<TpVoucher> curVoucherList = voucherDomainService.getVoucherList(queryDTO.setOrderNo(orderNo).setTenantId(tenantId));
if (CollectionUtils.isEmpty(curVoucherList)) {
throw new TpTradeCoreException(TpTradeCoreErrorCode.NOT_FOUND_VOUCHER);
}
return curVoucherList;
}
@PostMapping("/voucher/check/time")
public void testCheckTimeRule() {
TpRuleExecuteDTO<TpTicketCheckParamDTO> ruleExecuteDTO = new TpRuleExecuteDTO<>();
TpTicketCheckParamDTO checkParamDTO = new TpTicketCheckParamDTO();
checkParamDTO.setDepartureTime(System.currentTimeMillis() - 1000);
ruleExecuteDTO.setRuleList(Lists.newArrayList("long now = new Date().getTime();\n" +
" if (now > departureTime) {\n" +
" return false;\n" +
" }\n" +
" long checkRangeStart = departureTime - 90000000;\n" +
" if (now >= checkRangeStart && now <= endTime) {\n" +
" return true;\n" +
" }\n" +
" return false;"));
ruleExecuteDTO.setParameter(checkParamDTO);
ruleExecuteDTO.setRuleExpressionGroup(TpRuleExpressionGroupEnum.TICKET_CHECK);
TpRuleExecuteResultVO<Boolean> result = bizRuleClient.executeRule(ruleExecuteDTO);
System.out.println(result.getResult());
}
@PostMapping("/voucher/check/count")
public void testCheckCountRule() {
TpRuleExecuteDTO<TpRollShuttleTripsParamDTO> ruleExecuteDTO = new TpRuleExecuteDTO<>();
TpRollShuttleTripsParamDTO checkParamDTO = new TpRollShuttleTripsParamDTO();
ruleExecuteDTO.setRuleList(Lists.newArrayList(" return 1 * passengerCount;"));
ruleExecuteDTO.setParameter(checkParamDTO);
checkParamDTO.setPassengerCount(1);
ruleExecuteDTO.setRuleExpressionGroup(TpRuleExpressionGroupEnum.ROLL_SHUTTLE_TRIPS);
TpRuleExecuteResultVO<Integer> result = bizRuleClient.executeRule(ruleExecuteDTO);
System.out.println(result.getResult());
}
@PostMapping("/voucher/range/verification")
public TpResult<TpTimeRangeExistVerificationRecordDateQueryVO> getTimeRangeVoucherVerification(@RequestBody TpTimeRangeExistVerificationRecordDateQueryDTO queryDTO) {
return voucherFacade.getTimeRangeExistVerificationRecordDate(queryDTO);
}
@PostMapping("/voucher/verification")
public TpResult<TpTimeRangeUserVerificationRecordDetailQueryVO> getVoucherVerificationDetail(@RequestBody TpTimeRangeUserVerificationRecordDetailQueryDTO queryDTO) {
return voucherFacade.getTimeRangeUserVerificationRecordDetail(queryDTO);
}
@PostMapping("/voucher/verification/record")
public TpResult<List<TpVoucherVerificationRecordDTO>> getVoucherVerificationRecordList(@RequestBody TpVoucherVerificationRecordQueryDTO queryDTO) {
return voucherFacade.getVoucherVerificationRecordList(queryDTO);
}
@PostMapping("/schedule/voucher/expire")
public void voucherExpireTask(Long taskId) {
TpScheduleTaskDO taskDO = scheduleTaskRepository.getById(taskId);
if (taskDO == null) {
LogUtil.error("定时任务id对应的定时任务不存在任务id为{}", taskId);
throw new TpTradeCoreException(TpTradeCoreErrorCode.ILLEGAL_PARAMS);
}
TpScheduleTask scheduleTask = taskMapStructConvert.convert2Domain(taskDO);
voucherExpiredWorker.doCommit(scheduleTask);
}
@PostMapping("/mng/voucher/verification")
public TpResult<CommonPage<TpMngVerificationRecordDTO>> queryMngVoucherVerificationRecords(@RequestBody TpMngVerificationRecordQueryDTO queryDTO) {
return voucherFacade.queryMngVerificationRecords(queryDTO);
}
@PostMapping("/voucher/reschedule/invalid")
public TpResult<Boolean> rescheduleInvalidVouchers(@RequestBody TpRescheduleInvalidVoucherDTO rescheduleInvalidVoucherDTO) {
return voucherFacade.rescheduleInvalidVouchers(rescheduleInvalidVoucherDTO);
}
}

View File

@@ -0,0 +1,381 @@
package com.deepinnet.tptradecore.service.impl;
import cn.hutool.core.date.*;
import cn.hutool.core.net.URLDecoder;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.json.JSONUtil;
import com.alipay.api.internal.util.AlipaySignature;
import com.deepinnet.tp.common.lang.constants.GlobalConstants;
import com.deepinnet.tp.common.lang.util.*;
import com.deepinnet.tptradecore.common.dto.trans.*;
import com.deepinnet.tptradecore.common.enums.trans.*;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.common.service.integration.config.TpAlipayMiniProgramConfig;
import com.deepinnet.tptradecore.common.service.integration.constants.PayPlatformConstants;
import com.deepinnet.tptradecore.common.service.integration.initializer.*;
import com.deepinnet.tptradecore.common.service.integration.mq.constants.*;
import com.deepinnet.tptradecore.common.service.integration.mq.entity.*;
import com.deepinnet.tptradecore.common.service.integration.mq.template.MessageClient;
import com.deepinnet.tptradecore.core.model.trans.TpPayOrder;
import com.deepinnet.tptradecore.core.service.trans.TpPayOrderDomainService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import javax.servlet.http.*;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;
/**
* @author amos wong
* @create 2022-11-17 10:29
* 处理支付宝回调的服务
*/
@Service("alipayCallbackService")
public class AlipayCallbackService {
@Resource
private TpPayOrderDomainService payOrderDomainService;
@Resource
private TpPayConfigInitializer payConfigInitializer;
@Resource
private MessageClient messageClient;
public void processPayResultCallback(HttpServletRequest request) {
try {
// 取出参数
Map<String, String> paramMap = buildParamMap(request);
// 为了避免死锁这里只能先取出响应体里的orgCode然后再验签
Map<String, String> passBackParamMap = generatePassBackParamMap(request);
String orgCode = passBackParamMap.get(PayPlatformConstants.ORG_CODE);
Assert.hasText("支付回调接口回传参数组织code不能为空", orgCode);
String tenantId = passBackParamMap.get(PayPlatformConstants.TENANT_ID);
Assert.hasText("支付回调接口回传参数租户id不能为空", tenantId);
String payScene = passBackParamMap.get(PayPlatformConstants.PAY_SCENE);
Assert.hasText("支付回调接口,回传参数:支付场景不能为空", payScene);
String bizType = passBackParamMap.get(PayPlatformConstants.BIZ_TYPE);
Assert.hasText("支付回调接口,回传参数:业务类型不能为空", bizType);
String publicKey;
if (StringUtils.equals(payScene, TpPaySceneEnum.ALI_MINI_PROGRAM.getCode())) {
String appId = passBackParamMap.get(PayPlatformConstants.APP_ID);
Assert.hasText("支付回调接口回传参数appId不能为空", appId);
TpAlipayMiniProgramConfig alipayConfig = payConfigInitializer.getAlipayMiniProgramPayConfig(null, appId);
Assert.notNull(alipayConfig, "支付回调接口appId对应的支付宝配置不存在");
publicKey = alipayConfig.getPublicKey();
} else {
publicKey = payConfigInitializer.getPayConfig(orgCode, bizType, tenantId).getAlipayConfig().getPublicKey();
}
// 验签
boolean flag = AlipaySignature.rsaCheckV1(paramMap, publicKey, PayPlatformConstants.DEFAULT_CHARSET, PayPlatformConstants.DEFAULT_SIGN_TYPE);
if (!flag) {
throw new TpTradeCoreException(TpTradeCoreErrorCode.SIGN_VERIFIED_ERROR);
}
// 判断是否是退款成功的回调通知
boolean isRefundCallback = false;
String refundTimeParam = request.getParameter(PayPlatformConstants.ALIPAY_NOTIFY_REFUND_TIME);
if (StringUtils.isNotBlank(refundTimeParam)) {
String refundTime = new String(refundTimeParam.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
if (StringUtils.isNotEmpty(refundTime)) {
isRefundCallback = true;
}
}
// 获取支付单:正向支付单或者退款支付单
List<TpPayOrder> payOrders = getPayOrders(request, isRefundCallback);
// 针对退款或者支付进行不同的业务处理
if (!isRefundCallback) {
processPaySuccessCallback(request, payOrders);
} else {
processAlipayRefundSuccessCallback(request, payOrders);
}
} catch (Exception e) {
if (e instanceof TpTradeCoreException) {
TpTradeCoreException tradeCoreException = (TpTradeCoreException) e;
if (tradeCoreException.getErrorCode() == TpTradeCoreErrorCode.IDEMPOTENT_REQUEST_ERROR) {
LogUtil.warn("接收支付宝支付结果的回调接口,该支付单状态已经更新进行幂等处理");
} else {
LogUtil.error("支付宝回调处理失败,异常原因:{}", tradeCoreException);
}
throw tradeCoreException;
}
LogUtil.error("接收支付宝支付结果的回调接口,异步验签失败,失败原因:{}", e);
throw new TpTradeCoreException(TpTradeCoreErrorCode.PROCESS_PLATFORM_CALLBACK_ERROR);
}
}
private List<TpPayOrder> getPayOrders(HttpServletRequest request, boolean isRefundCallback) {
String outTradeNo = new String(request.getParameter(PayPlatformConstants.OUT_TRADE_NO).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
String totalAmount = new String(request.getParameter(PayPlatformConstants.TOTAL_AMOUNT).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
String passBackAppId = new String(request.getParameter(PayPlatformConstants.APP_ID).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
String payTime = new String(request.getParameter(PayPlatformConstants.ALIPAY_NOTIFY_PAY_TIME).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
String outBizNo = null;
if (isRefundCallback) {
// 退款流水号
outBizNo = new String(request.getParameter(PayPlatformConstants.OUT_BIZ_NO).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
}
String encodePassBackParams = new String(request.getParameter(PayPlatformConstants.PASS_BACK_PARAMS).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
Assert.hasText(outTradeNo, "外部交易单号不能为空");
Assert.hasText(totalAmount, "支付总金额不能为空");
Assert.hasText(payTime, "支付时间不能为空");
Assert.hasText(encodePassBackParams, "支付回传参数为空");
Map<String, String> passBackParamMap = generatePassBackParamMap(request);
String tenantId = passBackParamMap.get(PayPlatformConstants.TENANT_ID);
String orgCode = passBackParamMap.get(PayPlatformConstants.ORG_CODE);
String payScene = passBackParamMap.get(PayPlatformConstants.PAY_SCENE);
String bizType = passBackParamMap.get(PayPlatformConstants.BIZ_TYPE);
Assert.hasText("支付回调接口回传参数租户id不能为空", tenantId);
Assert.hasText("支付回调接口回传参数组织code不能为空", bizType);
Assert.hasText("支付回调接口回传参数payScene不能为空", payScene);
// 校验appId是否正确
if (StringUtils.equals(payScene, TpPaySceneEnum.ALI_MINI_PROGRAM.getCode())) {
Assert.hasText("支付回调接口,回传参数:appId不能为空", passBackAppId);
String configAppId = payConfigInitializer.getAlipayMiniProgramPayConfig(null, passBackAppId).getAppId();
if (!StringUtils.equals(passBackAppId, configAppId)) {
LogUtil.error("处理支付平台回调失败支付宝返回的appId错误订单号{}", outTradeNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.PROCESS_PLATFORM_CALLBACK_ERROR);
}
} else {
if (!StringUtils.equals(passBackAppId, payConfigInitializer.getPayConfig(orgCode, bizType, tenantId).getAlipayConfig().getAppId())) {
LogUtil.error("处理支付平台回调失败支付宝返回的appId错误订单号{}", outTradeNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.PROCESS_PLATFORM_CALLBACK_ERROR);
}
}
// 查询所有支付类型中在途的和已经支付成功的支付单
// 针对支付平台返回的outTradeNo需要处理
List<TpPayOrder> payOrders;
if (!isRefundCallback) {
String[] splitOutTradeNo = outTradeNo.split(GlobalConstants.HORIZONTAL_LINE);
payOrders = payOrderDomainService.queryPayOrderList(TpPayOrderQueryDTO.builder()
.bizNo(splitOutTradeNo[0])
.targetStatusList(Lists.newArrayList(TpPayOrderStatusEnum.PAYING.getCode(), TpPayOrderStatusEnum.PAID.getCode()))
.tenantId(tenantId)
.build());
} else {
payOrders = payOrderDomainService.queryPayOrderList(TpPayOrderQueryDTO.builder()
.bizNo(outBizNo)
.targetStatusList(Lists.newArrayList(TpPayOrderStatusEnum.REFUNDING.getCode(), TpPayOrderStatusEnum.REFUND.getCode()))
.tenantId(tenantId)
.build());
}
// 校验支付单是否存在
if (CollectionUtils.isEmpty(payOrders)) {
LogUtil.error("处理支付平台回调失败,支付单不存在,支付宝返回的订单号:{}", outTradeNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.PAY_ORDER_NOT_FOUND);
}
return payOrders;
}
private void processPaySuccessCallback(HttpServletRequest request, List<TpPayOrder> payOrders) {
// 取出响应的参数并校验
TpPayOrder payOrder = checkCallbackResponse(request, payOrders);
// 判断支付结果
String tradeStatus = new String(request.getParameter(PayPlatformConstants.TRADE_STATUS).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
String payTime = new String(request.getParameter(PayPlatformConstants.ALIPAY_NOTIFY_PAY_TIME).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
// 更新支付单、账单信息
if (StringUtils.equals(tradeStatus, PayPlatformConstants.ALIPAY_TRADE_SUCCESS) || StringUtils.equals(tradeStatus, PayPlatformConstants.ALIPAY_TRADE_FINISHED)) {
updatePayOrderSuccess(request, payOrder, DateUtil.parse(payTime).getTime());
}
// 发送支付成功消息
BaseMessageEntity messageEntity = buildPaySuccessMessage(payOrder.getOrderNo(), payOrder.getPayOrderNo(), payOrder.getBizType(), DateUtil.parse(payTime).getTime(), payOrder.getTenantId());
messageClient.send(messageClient.getMessageTopic(), MessageConstants.EVENT_CODE_TRANS_PAY_SUCCESS, messageEntity);
LogUtil.info("发送支付宝支付成功的消息成功,支付单号为:{}", payOrder.getPayOrderNo());
}
private void processAlipayRefundSuccessCallback(HttpServletRequest request, List<TpPayOrder> payOrders) {
String outBizNo = new String(request.getParameter(PayPlatformConstants.OUT_BIZ_NO).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
String refundFee = new String(request.getParameter(PayPlatformConstants.REFUND_FEE).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
String refundTimeParam = request.getParameter(PayPlatformConstants.ALIPAY_NOTIFY_REFUND_TIME);
Assert.hasText(outBizNo, "退款业务单号不能为空");
Assert.hasText(refundFee, "退款金额不能为空");
Assert.hasText(refundTimeParam, "退款时间参数不能为空");
String refundTime = new String(refundTimeParam.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
Assert.hasText(refundTime, "退款时间不能为空");
if (payOrders.size() > 1) {
LogUtil.error("同一个业务单号发现多笔退款中的支付单,退款业务单号为:{}", outBizNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.FOUND_DUPLICATE_REFUNDING_PAY_ORDER);
}
TpPayOrder refundPayOrder = payOrders.get(0);
if (StringUtils.equals(refundPayOrder.getStatus(), TpPayOrderStatusEnum.REFUND.getCode())) {
LogUtil.info("支付单已经修改为已退款,幂等处理,支付单号为:{}", refundPayOrder.getPayOrderNo());
return;
}
TpMoney refundAmount = refundPayOrder.getPayAmount();
TpMoney alipayRefundFee = new TpMoney(refundFee, TpMoney.ValueUnitEnum.YUAN);
if (refundAmount.compare(alipayRefundFee) != TpMoney.CompareResult.EQUAL) {
LogUtil.error("支付宝退款金额错误,与退款支付单的金额不匹配,支付宝退款金额为:{},支付单金额为:{},退款业务单号:{}", refundFee, refundAmount.getCent(), outBizNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.ERROR_REFUND_AMOUNT);
}
// 这里更新业务单号以及发送退款成功的消息
// 退款支付单改为退款成功
long refundTimestamp = DateUtil.parse(refundTime).getTime();
payOrderDomainService.refundSuccess(TpRefundSuccessDTO.builder()
.refundPayOrderNo(refundPayOrder.getPayOrderNo())
.refundTime(refundTimestamp)
.tenantId(refundPayOrder.getTenantId())
.build());
// 发送退款成功消息推进流程
BaseMessageEntity messageEntity = buildRefundSuccessMessage(refundPayOrder.getOrderNo(), refundPayOrder.getPayOrderNo(),
refundPayOrder.getBizNo(), refundPayOrder.getBizType(), refundPayOrder.getTenantId());
messageClient.send(messageClient.getMessageTopic(), MessageConstants.EVENT_CODE_TRANS_REFUND_SUCCESS, messageEntity);
LogUtil.info("发送支付宝退款成功的消息,退款支付单号为:{}", refundPayOrder.getPayOrderNo());
LogUtil.info("支付宝退款成功回调处理成功...");
}
private BaseMessageEntity buildPaySuccessMessage(String orderNo, String payOrderNo, String bizType, Long payTime, String tenantId) {
BaseMessageEntity messageEntity = new BaseMessageEntity();
messageEntity.setKey(payOrderNo);
messageEntity.setSource(MessageSysConstants.SOURCE_TRANS);
messageEntity.setSendTime(LocalDateTime.now());
PaySuccessMessageEntity payOrderSuccessEntity = new PaySuccessMessageEntity();
payOrderSuccessEntity.setPayOrderNo(payOrderNo);
payOrderSuccessEntity.setBizType(bizType);
payOrderSuccessEntity.setOrderNo(orderNo);
payOrderSuccessEntity.setPayTime(payTime);
payOrderSuccessEntity.setTenantId(tenantId);
String body = JSONUtil.toJsonStr(payOrderSuccessEntity);
messageEntity.setBody(body);
return messageEntity;
}
private Map<String, String> buildParamMap(HttpServletRequest request) {
Map<String, String[]> parameterMap = request.getParameterMap();
Map<String, String> params = new HashMap<>();
for (String name : parameterMap.keySet()) {
String[] values = parameterMap.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
}
params.put(name, valueStr);
}
return params;
}
private TpPayOrder checkCallbackResponse(HttpServletRequest request, List<TpPayOrder> payOrders) {
// 这里对应系统中的订单号即bizNo字段
String outTradeNo = new String(request.getParameter(PayPlatformConstants.OUT_TRADE_NO).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
String totalAmount = new String(request.getParameter(PayPlatformConstants.TOTAL_AMOUNT).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
// 微信、支付宝重复支付的校验
checkWechatDuplicatePaidOrder(payOrders, outTradeNo);
// 校验支付宝的支付单是否有支付完成的支付单
boolean aliPayExistsPaidOrder = payOrders
.stream()
.anyMatch(payOrder -> StringUtils.equals(payOrder.getStatus(), TpPayOrderStatusEnum.PAID.getCode())
&& StringUtils.equals(payOrder.getPayType(), TpPayTypeEnum.ALIPAY.getCode()));
if (aliPayExistsPaidOrder) {
LogUtil.error("幂等处理,当前订单状态已经为已支付,订单号:{}", outTradeNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.IDEMPOTENT_REQUEST_ERROR);
}
// 如果发现了两笔支付中的支付单直接报错
if (payOrders.size() > 1) {
LogUtil.error("业务数据异常,发现多笔支付单,投保单号:{}", outTradeNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.DUPLICATED_UNPAID_PAY_ORDER);
}
// 校验支付金额是否正确
TpPayOrder payOrder = payOrders.get(0);
TpMoney money = new TpMoney(totalAmount, TpMoney.ValueUnitEnum.YUAN);
if (payOrder.getPayAmount().compare(money) != TpMoney.CompareResult.EQUAL) {
LogUtil.error("处理支付平台回调失败,用户支付金额错误,订单号:{}", outTradeNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.PROCESS_PLATFORM_CALLBACK_ERROR);
}
return payOrder;
}
private Map<String, String> generatePassBackParamMap(HttpServletRequest request) {
String encodePassBackParams = new String(request.getParameter(PayPlatformConstants.PASS_BACK_PARAMS).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
Assert.hasText(encodePassBackParams, "支付回传参数为空");
Map<String, String> paramMap = new HashMap<>();
String decodePassBackParams = URLDecoder.decode(encodePassBackParams, CharsetUtil.CHARSET_UTF_8);
String[] splitParam = decodePassBackParams.split(GlobalConstants.AND);
for (String sp : splitParam) {
String[] param = sp.split(GlobalConstants.EQUAL_SIGN);
paramMap.put(param[0], param[1]);
}
return paramMap;
}
private void updatePayOrderSuccess(HttpServletRequest request, TpPayOrder payOrder, Long payTime) {
String outPayFlowId = new String(request.getParameter(PayPlatformConstants.TRADE_NO).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
payOrderDomainService.paySuccess(TpPaySuccessDTO.builder()
.payOrderNo(payOrder.getPayOrderNo())
.outPayFlowId(outPayFlowId)
.payTime(payTime)
.tenantId(payOrder.getTenantId())
.build());
payOrder.setStatus(TpPayOrderStatusEnum.PAID.getCode());
payOrder.setOutPayFlowId(outPayFlowId);
payOrder.setPayTime(payTime);
}
private boolean checkWechatDuplicatePaidOrder(List<TpPayOrder> payOrders, String bizNo) {
boolean hasWechatPaidOrder = payOrders
.stream()
.anyMatch(payOrder -> Objects.equals(payOrder.getPayType(), TpPayTypeEnum.WECHAT_PAY.getCode())
&& StringUtils.equals(payOrder.getStatus(), TpPayOrderStatusEnum.PAID.getCode()));
if (hasWechatPaidOrder) {
LogUtil.error("支付宝支付成功回调接口,处理失败,发现有已经支付的微信订单,请及时处理,订单号:{}", bizNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.FOUND_DUPLICATED_PAID);
}
return false;
}
private BaseMessageEntity buildRefundSuccessMessage(String orderNo, String refundPayOrderNo, String refundBizNo, String bizType, String tenantId) {
BaseMessageEntity baseMessageEntity = new BaseMessageEntity();
baseMessageEntity.setSource(MessageSysConstants.SOURCE_TRANS);
baseMessageEntity.setKey(refundBizNo);
baseMessageEntity.setSendTime(LocalDateTime.now());
RefundSuccessMessageEntity messageEntity = new RefundSuccessMessageEntity();
messageEntity.setRefundPayOrderNo(refundPayOrderNo);
messageEntity.setOrderNo(orderNo);
messageEntity.setRefundBizNo(refundBizNo);
messageEntity.setBizType(bizType);
messageEntity.setTenantId(tenantId);
baseMessageEntity.setBody(JSONUtil.toJsonStr(messageEntity));
return baseMessageEntity;
}
}

View File

@@ -0,0 +1,261 @@
package com.deepinnet.tptradecore.service.impl;
import cn.hutool.core.date.*;
import cn.hutool.core.net.URLDecoder;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.json.*;
import com.deepinnet.tp.common.lang.constants.GlobalConstants;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tpbaseopcore.common.dto.pay.OrgWxPayDTO;
import com.deepinnet.tptradecore.common.dto.trans.*;
import com.deepinnet.tptradecore.common.enums.trans.*;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.common.service.integration.client.TpOrgClient;
import com.deepinnet.tptradecore.common.service.integration.constants.PayPlatformConstants;
import com.deepinnet.tptradecore.common.service.integration.mq.constants.*;
import com.deepinnet.tptradecore.common.service.integration.mq.entity.*;
import com.deepinnet.tptradecore.common.service.integration.mq.template.MessageClient;
import com.deepinnet.tptradecore.core.model.trans.TpPayOrder;
import com.deepinnet.tptradecore.core.service.trans.TpPayOrderDomainService;
import com.google.common.collect.Lists;
import com.ijpay.core.kit.*;
import com.ijpay.core.utils.DateTimeZoneUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author amos wong
* @create 2022-11-17 10:29
* <p>
* 处理微信回调的服务
*/
@Service("wechatPayCallbackService")
public class WechatPayCallbackService {
@Resource
private TpPayOrderDomainService payOrderDomainService;
@Resource
private MessageClient messageClient;
@Resource
private TpOrgClient orgClient;
public void processPayResultCallback(HttpServletRequest request) {
Map<String, String> paramsMap = new HashMap<>();
try {
// 验签 & 解密得到解密后的数据
String plainText = verifySignatureAndDecrypt(request);
// 将数据转换为map
convertWechatPayMsgToMap(plainText, paramsMap);
// 幂等校验
String tenantId = paramsMap.get(PayPlatformConstants.TENANT_ID);
String outTradeNo = paramsMap.get(PayPlatformConstants.OUT_TRADE_NO);
// 获取业务系统内部的bizNo
String[] splitOutTradeNo = outTradeNo.split(GlobalConstants.HORIZONTAL_LINE);
String bizNo = splitOutTradeNo[0];
TpPayOrder payOrder = checkIdempotent(bizNo, tenantId);
// 处理业务逻辑
String tradeState = paramsMap.get(PayPlatformConstants.TRADE_STATE);
String transactionId = paramsMap.get(PayPlatformConstants.TRANSACTION_ID);
String successTime = paramsMap.get(PayPlatformConstants.WECHAT_SUCCESS_TIME);
if (StringUtils.equals(tradeState, PayPlatformConstants.WECHAT_PAY_SUCCESS)) {
// 微信的时间格式需要转换
String wechatPaySuccessTime = DateTimeZoneUtil.timeZoneDateToStr(successTime);
DateTime dateTime = DateUtil.parse(wechatPaySuccessTime);
// 更新支付单、账单信息
payOrderDomainService.paySuccess(TpPaySuccessDTO.builder()
.payOrderNo(payOrder.getPayOrderNo())
.outPayFlowId(transactionId)
.payTime(dateTime.getTime())
.tenantId(tenantId)
.build());
}
// 发送支付成功消息
BaseMessageEntity messageEntity = buildPaySuccessMessage(payOrder.getOrderNo(), payOrder.getPayOrderNo(), payOrder.getBizType(), DateUtil.parse(successTime).getTime(), payOrder.getTenantId());
messageClient.send(messageClient.getMessageTopic(), MessageConstants.EVENT_CODE_TRANS_PAY_SUCCESS, messageEntity);
LogUtil.info("微信支付成功回调,发送支付成功消息成功,支付单号为:{}", payOrder.getPayOrderNo());
} catch (TpTradeCoreException e) {
throw e;
} catch (Exception e) {
LogUtil.error("微信支付成功回调异常,订单号为:{},异常信息为:{}", paramsMap.get(PayPlatformConstants.OUT_TRADE_NO), e);
throw new TpTradeCoreException(TpTradeCoreErrorCode.PROCESS_PLATFORM_CALLBACK_ERROR);
}
}
private String verifySignatureAndDecrypt(HttpServletRequest request) {
// 平台证书序列号,每个商户是唯一的
String platSerialNo = request.getHeader(PayPlatformConstants.WECHAT_CALLBACK_SERIAL);
Assert.hasText(platSerialNo, "微信支付回调接口,平台证书序列号为空");
OrgWxPayDTO wxPayDTO = orgClient.getWxPayByPlatSerialNo(platSerialNo);
Assert.notNull(wxPayDTO, "根据平台序列号查询到的微信支付配置不能为空");
// 取出加密数据内容
String encryptData = HttpKit.readData(request);
LogUtil.info("接收到微信回调请求,加密数据为:{}", encryptData);
// 验签 & 解密
return verifySignatureAndDecrypt(request, encryptData, wxPayDTO);
}
private BaseMessageEntity buildPaySuccessMessage(String orderNo, String payOrderNo, String bizType, Long payTime, String tenantId) {
BaseMessageEntity messageEntity = new BaseMessageEntity();
messageEntity.setKey(payOrderNo);
messageEntity.setSource(MessageSysConstants.SOURCE_TRANS);
messageEntity.setSendTime(LocalDateTime.now());
PaySuccessMessageEntity payOrderSuccessEntity = new PaySuccessMessageEntity();
payOrderSuccessEntity.setPayOrderNo(payOrderNo);
payOrderSuccessEntity.setOrderNo(orderNo);
payOrderSuccessEntity.setBizType(bizType);
payOrderSuccessEntity.setPayTime(payTime);
payOrderSuccessEntity.setTenantId(tenantId);
String body = JSONUtil.toJsonStr(payOrderSuccessEntity);
messageEntity.setBody(body);
return messageEntity;
}
/**
* 验签&将密文进行解密
*
* @param request
* @return
*/
private String verifySignatureAndDecrypt(HttpServletRequest request, String encryptData, OrgWxPayDTO orgWxPayDTO) {
String signature = request.getHeader(PayPlatformConstants.WECHAT_CALLBACK_SIGNATURE);
String nonce = request.getHeader(PayPlatformConstants.WECHAT_CALLBACK_NONCE);
String timestamp = request.getHeader(PayPlatformConstants.WECHAT_CALLBACK_TIMESTAMP);
String platSerialNo = request.getHeader(PayPlatformConstants.WECHAT_CALLBACK_SERIAL);
String plainText;
try {
InputStream certInputStream = new ByteArrayInputStream(orgWxPayDTO.getCertContent().getBytes());
plainText = WxPayKit.verifyNotify(platSerialNo, encryptData, signature, nonce, timestamp,
orgWxPayDTO.getApiV3(), certInputStream);
} catch (Exception e) {
LogUtil.error("微信支付结果回调,验签失败,异常堆栈:{}", e);
throw new TpTradeCoreException(TpTradeCoreErrorCode.SIGN_VERIFIED_ERROR);
}
LogUtil.info("微信支付结果回调接口,解密后的明文为:{}", plainText);
return plainText;
}
/**
* 转换body为map
*
* @param plainBody 解密后的明文
*/
private void convertWechatPayMsgToMap(String plainBody, Map<String, String> paramsMap) {
JSONObject jsonObject = JSONUtil.parseObj(plainBody);
String outTradeNo = jsonObject.getStr(PayPlatformConstants.OUT_TRADE_NO);
String tradeState = jsonObject.getStr(PayPlatformConstants.TRADE_STATE);
String transactionId = jsonObject.getStr(PayPlatformConstants.TRANSACTION_ID);
String successTime = jsonObject.getStr(PayPlatformConstants.WECHAT_SUCCESS_TIME);
String attach = jsonObject.getStr(PayPlatformConstants.ATTACH);
Assert.hasText(outTradeNo, "商户订单号不能为空");
Assert.hasText(tradeState, "交易状态不能为空");
Assert.hasText(transactionId, "微信支付流水号不能为空");
Assert.hasText(attach, "支付成功回传参数不能为空");
Map<String, String> passBackParamMap = generatePassBackParamMap(attach);
// 租户id
String tenantId = passBackParamMap.get(PayPlatformConstants.TENANT_ID);
Assert.hasText(tenantId, "支付成功回传参数中租户id不能为空");
paramsMap.put(PayPlatformConstants.TENANT_ID, tenantId);
// 商户订单号
paramsMap.put(PayPlatformConstants.OUT_TRADE_NO, outTradeNo);
// 交易状态
paramsMap.put(PayPlatformConstants.TRADE_STATE, tradeState);
// 微信支付流水号
paramsMap.put(PayPlatformConstants.TRANSACTION_ID, transactionId);
// 支付成功时间
paramsMap.put(PayPlatformConstants.WECHAT_SUCCESS_TIME, successTime);
}
private TpPayOrder checkIdempotent(String bizNo, String tenantId) {
// 根据退款申请单号
List<TpPayOrder> payOrders = payOrderDomainService.queryPayOrderList(
TpPayOrderQueryDTO.builder()
.bizNo(bizNo)
.tenantId(tenantId)
.targetStatusList(Lists.newArrayList(TpPayOrderStatusEnum.PAYING.getCode(), TpPayOrderStatusEnum.PAID.getCode()))
.build());
if (CollectionUtils.isEmpty(payOrders)) {
LogUtil.error("处理支付平台回调失败,支付单不存在,微信返回的订单号:{}", bizNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.PAY_ORDER_NOT_FOUND);
}
// 校验是否已经有使用支付宝进行支付
boolean existsAlipayPaidOrder = payOrders
.parallelStream()
.anyMatch(payOrder -> StringUtils.equals(payOrder.getPayType(), TpPayTypeEnum.ALIPAY.getCode())
&& StringUtils.equals(payOrder.getStatus(), TpPayOrderStatusEnum.PAID.getCode()));
if (existsAlipayPaidOrder) {
LogUtil.error("微信支付回调接口,发现该用户已经使用支付宝进行支付,请及时处理,订单号:{}", bizNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.FOUND_DUPLICATED_PAID);
}
// 过滤出使用微信支付的订单
List<TpPayOrder> wechatPayOrders = payOrders
.stream()
.filter(payOrder -> StringUtils.equals(payOrder.getPayType(), TpPayTypeEnum.WECHAT_PAY.getCode()))
.collect(Collectors.toList());
// 微信支付的幂等校验
boolean existsWechatPaidOrder = wechatPayOrders
.stream()
.anyMatch(wechatPayOrder -> StringUtils.equals(wechatPayOrder.getStatus(), TpPayOrderStatusEnum.PAID.getCode()));
if (existsWechatPaidOrder) {
LogUtil.error("微信支付回调接口,微信支付幂等处理,订单号:{}", bizNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.IDEMPOTENT_REQUEST_ERROR);
}
// 出现两笔待支付的支付单,业务数据异常
if (payOrders.size() > 1) {
LogUtil.error("业务数据异常,发现多笔待支付的支付单,订单号:{}", bizNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.NOT_FOUND_IN_PROCESS_PAY_ORDER);
}
return payOrders.get(0);
}
private Map<String, String> generatePassBackParamMap(String attach) {
String encodePassBackParams = new String(attach.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
Map<String, String> paramMap = new HashMap<>();
String decodePassBackParams = URLDecoder.decode(encodePassBackParams, CharsetUtil.CHARSET_UTF_8);
String[] splitParam = decodePassBackParams.split(GlobalConstants.AND);
for (String sp : splitParam) {
String[] param = sp.split(GlobalConstants.EQUAL_SIGN);
paramMap.put(param[0], param[1]);
}
return paramMap;
}
}

View File

@@ -0,0 +1,193 @@
package com.deepinnet.tptradecore.service.impl;
import cn.hutool.core.date.*;
import cn.hutool.json.*;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tpbaseopcore.common.dto.pay.OrgWxPayDTO;
import com.deepinnet.tptradecore.common.dto.trans.*;
import com.deepinnet.tptradecore.common.enums.trans.TpPayOrderStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.common.service.integration.client.TpOrgClient;
import com.deepinnet.tptradecore.common.service.integration.constants.PayPlatformConstants;
import com.deepinnet.tptradecore.common.service.integration.mq.constants.*;
import com.deepinnet.tptradecore.common.service.integration.mq.entity.*;
import com.deepinnet.tptradecore.common.service.integration.mq.template.MessageClient;
import com.deepinnet.tptradecore.core.model.trans.TpPayOrder;
import com.deepinnet.tptradecore.core.service.trans.TpPayOrderDomainService;
import com.google.common.collect.Lists;
import com.ijpay.core.kit.*;
import com.ijpay.core.utils.DateTimeZoneUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.time.LocalDateTime;
import java.util.*;
/**
* @author amos wong
* @create 2022-11-17 10:29
* <p>
* 处理微信回调的服务
*/
@Service("wechatRefundCallbackService")
public class WechatRefundCallbackService {
@Resource
private TpPayOrderDomainService payOrderDomainService;
@Resource
private TpOrgClient orgClient;
@Resource
private MessageClient messageClient;
public void processRefundSuccessCallback(HttpServletRequest request) {
Map<String, String> paramsMap = new HashMap<>();
try {
// 验签 & 解密得到解密后的数据
String plainText = verifySignatureAndDecrypt(request);
// 将数据转换为map
convertWechatRefundMsgToMap(plainText, paramsMap);
// 幂等校验
String outRefundNo = paramsMap.get(PayPlatformConstants.OUT_REFUND_NO);
String outTradeNo = paramsMap.get(PayPlatformConstants.OUT_TRADE_NO);
TpPayOrder refundPayOrder = checkRefundIdempotent(outRefundNo);
// 处理业务逻辑
String tradeState = paramsMap.get(PayPlatformConstants.TRADE_STATE);
String successTime = paramsMap.get(PayPlatformConstants.WECHAT_SUCCESS_TIME);
if (StringUtils.equals(tradeState, PayPlatformConstants.WECHAT_REFUND_SUCCESS)) {
// 微信的时间格式需要转换
String wechatRefundSuccessTime = DateTimeZoneUtil.timeZoneDateToStr(successTime);
DateTime dateTime = DateUtil.parse(wechatRefundSuccessTime);
// 更新支付单、账单信息
payOrderDomainService.refundSuccess(TpRefundSuccessDTO.builder()
.refundPayOrderNo(refundPayOrder.getPayOrderNo())
.refundTime(dateTime.getTime())
.tenantId(refundPayOrder.getTenantId())
.build());
// 发送退款成功消息推进流程
BaseMessageEntity messageEntity = buildRefundSuccessMessage(refundPayOrder.getOrderNo(), outRefundNo, refundPayOrder.getBizType(), refundPayOrder.getTenantId());
messageClient.send(messageClient.getMessageTopic(), MessageConstants.EVENT_CODE_TRANS_REFUND_SUCCESS, messageEntity);
LogUtil.info("微信支付退款成功回调,发送退款成功消息,消息内容为:{}", JSONUtil.toJsonStr(messageEntity));
}
} catch (Exception e) {
LogUtil.error("微信支付退款成功回调处理失败,异常堆栈:{}", e);
throw new TpTradeCoreException(TpTradeCoreErrorCode.PROCESS_PLATFORM_REFUND_CALLBACK_ERROR);
}
}
private String verifySignatureAndDecrypt(HttpServletRequest request) {
// 平台证书序列号,每个商户是唯一的
String platSerialNo = request.getHeader(PayPlatformConstants.WECHAT_CALLBACK_SERIAL);
Assert.hasText(platSerialNo, "微信支付回调接口,平台证书序列号为空");
OrgWxPayDTO wxPayDTO = orgClient.getWxPayByPlatSerialNo(platSerialNo);
Assert.notNull(wxPayDTO, "根据平台序列号查询到的微信支付配置不能为空");
// 取出加密数据内容
String encryptData = HttpKit.readData(request);
LogUtil.info("接收到微信回调请求,加密数据为:{}", encryptData);
// 验签 & 解密
return verifySignatureAndDecrypt(request, encryptData, wxPayDTO);
}
/**
* 验签&将密文进行解密
*
* @param request
* @return
*/
private String verifySignatureAndDecrypt(HttpServletRequest request, String encryptData, OrgWxPayDTO orgWxPayDTO) {
String signature = request.getHeader(PayPlatformConstants.WECHAT_CALLBACK_SIGNATURE);
String nonce = request.getHeader(PayPlatformConstants.WECHAT_CALLBACK_NONCE);
String timestamp = request.getHeader(PayPlatformConstants.WECHAT_CALLBACK_TIMESTAMP);
String platSerialNo = request.getHeader(PayPlatformConstants.WECHAT_CALLBACK_SERIAL);
String plainText;
try {
InputStream certInputStream = new ByteArrayInputStream(orgWxPayDTO.getCertContent().getBytes());
plainText = WxPayKit.verifyNotify(platSerialNo, encryptData, signature, nonce, timestamp,
orgWxPayDTO.getApiV3(), certInputStream);
} catch (Exception e) {
LogUtil.error("微信支付结果回调,验签失败,异常堆栈:{}", e);
throw new TpTradeCoreException(TpTradeCoreErrorCode.SIGN_VERIFIED_ERROR);
}
LogUtil.info("微信支付结果回调接口,解密后的明文为:{}", plainText);
return plainText;
}
private void convertWechatRefundMsgToMap(String plainBody, Map<String, String> paramsMap) {
JSONObject jsonObject = JSONUtil.parseObj(plainBody);
String outTradeNo = jsonObject.getStr(PayPlatformConstants.OUT_TRADE_NO);
String refundStatus = jsonObject.getStr(PayPlatformConstants.REFUND_STATUS);
String outRefundNo = jsonObject.getStr(PayPlatformConstants.OUT_REFUND_NO);
String successTime = jsonObject.getStr(PayPlatformConstants.WECHAT_SUCCESS_TIME);
Assert.hasText(outTradeNo, "商户订单号不能为空");
Assert.hasText(refundStatus, "交易状态不能为空");
Assert.hasText(outRefundNo, "微信外部退款号不能为空");
Assert.hasText(successTime, "微信退款成功时间不能为空");
// 商户订单号
paramsMap.put(PayPlatformConstants.OUT_TRADE_NO, outTradeNo);
// 交易状态
paramsMap.put(PayPlatformConstants.TRADE_STATE, refundStatus);
// 微信外部退款单号:退票申请单号
paramsMap.put(PayPlatformConstants.OUT_REFUND_NO, outRefundNo);
// 退款成功时间
paramsMap.put(PayPlatformConstants.WECHAT_SUCCESS_TIME, successTime);
}
private TpPayOrder checkRefundIdempotent(String bizNo) {
// 查询退款中和已退款的支付单
List<TpPayOrder> payOrders = payOrderDomainService.queryPayOrderList(
TpPayOrderQueryDTO.builder()
.bizNo(bizNo)
.targetStatusList(Lists.newArrayList(TpPayOrderStatusEnum.REFUNDING.getCode(), TpPayOrderStatusEnum.REFUND.getCode()))
.build());
if (CollectionUtils.isEmpty(payOrders)) {
LogUtil.error("微信支付退款回调幂等处理失败,退票申请单号对应的支付单不存在,退票申请单号:{}", bizNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.PAY_ORDER_NOT_FOUND);
}
TpPayOrder payOrder = payOrders.get(0);
if (StringUtils.equals(payOrder.getStatus(), TpPayOrderStatusEnum.REFUND.getCode())) {
LogUtil.error("微信支付退款回调幂等处理,当前退票申请单已经退款成功:{}", bizNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.IDEMPOTENT_REQUEST_ERROR);
}
return payOrder;
}
private BaseMessageEntity buildRefundSuccessMessage(String orderNo, String refundApplyOrderNo, String bizType, String tenantId) {
BaseMessageEntity baseMessageEntity = new BaseMessageEntity();
baseMessageEntity.setSource(MessageSysConstants.SOURCE_TRANS);
baseMessageEntity.setKey(refundApplyOrderNo);
baseMessageEntity.setSendTime(LocalDateTime.now());
RefundSuccessMessageEntity messageEntity = new RefundSuccessMessageEntity();
messageEntity.setOrderNo(orderNo);
messageEntity.setRefundBizNo(refundApplyOrderNo);
messageEntity.setBizType(bizType);
messageEntity.setTenantId(tenantId);
baseMessageEntity.setBody(JSONUtil.toJsonStr(messageEntity));
return baseMessageEntity;
}
}

View File

@@ -0,0 +1,194 @@
<?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.deepinnet</groupId>
<artifactId>tptradecore</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>tptradecore-app-starter</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-biz-service-impl</artifactId>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.github.jsonzou</groupId>
<artifactId>jmockdata</artifactId>
<version>4.3.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!--nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--dubbo-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
</dependency>
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
</dependency>
<!-- knife -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl-framework-starter</artifactId>
<version>1.2.40.Beetl.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>tptradecore</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.6</version>
<configuration>
<mainClass>com.deepinnet.tptradecore.ApplicationStarter</mainClass>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
<executions>
<execution>
<goals>
<!--可以把依赖的包都打包到生成的Jar包中-->
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- 测试需要的插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<argLine>${argLine} -Djacoco.agent.destfile=target/jacoco.exec</argLine>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<executions>
<execution>
<id>report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<phase>verify</phase>
<goals>
<goal>report-aggregate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.yml</include>
<include>**/*.json</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>

View File

@@ -0,0 +1,23 @@
package com.deepinnet.tptradecore;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@MapperScan({"com.deepinnet.tptradecore.common.dal.dao"})
@EnableDubbo(scanBasePackages = "com.deepinnet")
@EnableScheduling
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableRetry
public class ApplicationStarter {
public static void main(String[] args) {
SpringApplication.run(ApplicationStarter.class, args);
}
}

View File

@@ -0,0 +1,100 @@
package com.deepinnet.tptradecore.advise;
import com.deepinnet.tp.common.lang.exception.TpException;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.rpc.RpcException;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;
import javax.validation.*;
import java.util.stream.Collectors;
/**
* Description: 全局异常统一处理
* <p>
* Date: 2022/11/2
* Author: lijunheng
*/
@Slf4j
@RestControllerAdvice
public class GlobalControllerAdvise {
/**
* RPC异常处理
*/
@ExceptionHandler(RpcException.class)
public TpResult RpcExceptionHandler(RpcException e) {
log.error("RPC服务异常", e);
return TpResult.fail(TpTradeCoreErrorCode.INTERNAL_SERVER_ERROR.getCode(), TpTradeCoreErrorCode.INTERNAL_SERVER_ERROR.getDesc());
}
/**
* 处理请求参数格式错误 @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public TpResult methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(";"));
return TpResult.fail(TpTradeCoreErrorCode.ILLEGAL_PARAMS.getCode(), message);
}
/**
* 处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常
*/
@ExceptionHandler(BindException.class)
public TpResult bindExceptionHandler(BindException e) {
log.error("系统业务异常", e);
String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(";"));
return TpResult.fail(TpTradeCoreErrorCode.ILLEGAL_PARAMS.getCode(), message);
}
/**
* 处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是ConstraintViolationException
*/
@ExceptionHandler(ConstraintViolationException.class)
public TpResult constraintViolationExceptionHandler(ConstraintViolationException e) {
log.error("系统业务异常", e);
String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(";"));
return TpResult.fail(TpTradeCoreErrorCode.ILLEGAL_PARAMS.getCode(), message);
}
/**
* 系统具体异常提示
*
* @param e
* @return
*/
@ExceptionHandler(TpTradeCoreException.class)
public TpResult tradecoreExceptionHandler(TpTradeCoreException e) {
log.error("系统业务异常", e);
return TpResult.fail(e.getErrorCode().getCode(), e.getMessage());
}
/**
* 系统具体异常提示
*
* @param e
* @return
*/
@ExceptionHandler(TpException.class)
public TpResult tpExpection(TpException e) {
log.error("系统业务异常", e);
return TpResult.fail(e.getErrorCode(), e.getMessage());
}
/**
* 内部兜底异常处理
*
* @param e
* @return
*/
@ExceptionHandler(Exception.class)
public TpResult exceptionHandler(Exception e) {
log.error("系统异常", e);
return TpResult.fail(TpTradeCoreErrorCode.INTERNAL_SERVER_ERROR.getCode(), TpTradeCoreErrorCode.INTERNAL_SERVER_ERROR.getDesc());
}
}

View File

@@ -0,0 +1,88 @@
package com.deepinnet.tptradecore.config;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;
/**
* Knife Configuration
*
* @author chenjiaju
* @version 2023/07/25
*/
@Configuration
@EnableSwagger2
public class Knife4jConfiguration {
@Bean(value = "docketBean")
public Docket docketBean() {
//指定使用Swagger2规范
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(new ApiInfoBuilder()
.title("tptradecore-接口文档")
//描述字段支持Markdown语法
.description("# tptradecore-Rest API")
.termsOfServiceUrl("http://localhost:8080/")
.contact(new Contact("chenjiaju", "http://localhost:8080","ccc-ju@outlook.com"))
.version("1.0")
.build())
//分组名称
.groupName("tptradecore")
.select()
//这里指定Controller扫描包路径
.apis(RequestHandlerSelectors.basePackage("com.deepinnet"))
.paths(PathSelectors.any())
.build();
}
@Bean
public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof WebMvcRequestHandlerProvider) {
customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
}
return bean;
}
private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
List<T> copy = mappings.stream()
.filter(mapping -> mapping.getPatternParser() == null)
.collect(Collectors.toList());
mappings.clear();
mappings.addAll(copy);
}
@SuppressWarnings("unchecked")
private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
try {
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
field.setAccessible(true);
return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
};
}
}

View File

@@ -0,0 +1,36 @@
package com.deepinnet.tptradecore.config;
import org.springframework.context.annotation.*;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.backoff.*;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
import javax.annotation.Resource;
/**
* @author amos wong
* @create 2023/12/19 16:40
* @Description
*/
@Configuration
@EnableRetry
public class RetryConfig {
@Resource
private RetryListener retryListener;
/**
* 失败重试机制调用模板
*
* @return
*/
@Bean
public RetryTemplate retryTemplate() {
return RetryTemplate.builder()
.exponentialBackoff(1000, 2, 10000)
.maxAttempts(5)
.retryOn(Exception.class)
.withListener(retryListener).build();
}
}

View File

@@ -0,0 +1,29 @@
package com.deepinnet.tptradecore.config;
import com.deepinnet.tp.common.lang.util.LogUtil;
import org.springframework.retry.*;
import org.springframework.stereotype.Component;
/**
* @author amos wong
* @create 2023/12/19 17:12
* @Description
*/
@Component
public class RetryListener implements org.springframework.retry.RetryListener {
@Override
public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
LogUtil.info("尝试已打开,当前重试次数:{}", context.getRetryCount());
return true;
}
@Override
public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
LogUtil.info("尝试已关闭,当前尝试次数:{}", context.getRetryCount());
}
@Override
public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
LogUtil.warn("第{}次尝试失败,异常信息:{}", context.getRetryCount(), throwable.getMessage());
}
}

View File

@@ -0,0 +1,39 @@
package com.deepinnet.tptradecore.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.apache.rocketmq.spring.support.RocketMQMessageConverter;
import org.springframework.context.annotation.*;
import org.springframework.messaging.converter.*;
import java.util.List;
/**
* RocketMQ序列化器处理
*
* @author tianxincoord@163.com
* @since 2022/5/13
*/
@Configuration
public class RocketMQConfig {
/**
* 解决RocketMQ Jackson不支持Java时间类型配置
*/
@Bean
@Primary
public RocketMQMessageConverter createRocketMQMessageConverter() {
RocketMQMessageConverter converter = new RocketMQMessageConverter();
CompositeMessageConverter compositeMessageConverter = (CompositeMessageConverter) converter.getMessageConverter();
List<MessageConverter> messageConverterList = compositeMessageConverter.getConverters();
for (MessageConverter messageConverter : messageConverterList) {
if (messageConverter instanceof MappingJackson2MessageConverter) {
MappingJackson2MessageConverter jackson2MessageConverter = (MappingJackson2MessageConverter) messageConverter;
ObjectMapper objectMapper = jackson2MessageConverter.getObjectMapper();
// 增加Java8时间模块支持实体类可以传递LocalDate/LocalDateTime
objectMapper.registerModules(new JavaTimeModule());
}
}
return converter;
}
}

View File

@@ -0,0 +1,33 @@
package com.deepinnet.tptradecore.config;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.*;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import javax.validation.*;
@Configuration
public class ValidatorConfig {
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
postProcessor.setBeforeExistingAdvisors(false);
postProcessor.setProxyTargetClass(true);
postProcessor.setValidator(validator());
return postProcessor;
}
/**
* 开启快速失败模式,一旦失败立即抛出异常
*/
@Bean
public Validator validator() {
return Validation.byProvider(HibernateValidator.class)
.configure()
.failFast(true)
.buildValidatorFactory()
.getValidator();
}
}

View File

@@ -0,0 +1,88 @@
spring:
redis:
host: 192.168.3.200
port: 6379
password: ENC(ao+A54rgdnsZ/wIydpBlnxYqM34u5B4O)
#=======druid数据源配置=======
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
# 公网地址 记得替换地址和密码!!!
url: jdbc:mysql://rm-bp193v7i846v01k442o.mysql.rds.aliyuncs.com:3306/tp_order?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
# 内网地址
#url: jdbc:mysql://rm-bp193v7i846v01k44.mysql.rds.aliyuncs.com:3306/ins?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: tp_deepinnet_dev
password: B%dkLnXRt@nWjeUA
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
filters: stat,wall
initialSize: 5
keepAlive: true
maxActive: 20
maxPoolPreparedStatementPerConnectionSize: 20
maxWait: 60000
minEvictableIdleTimeMillis: 300000
minIdle: 5
poolPreparedStatements: true
testOnBorrow: true
testOnReturn: true
testWhileIdle: true
timeBetweenEvictionRunsMillis: 60000
useGlobalDataSourceStat: true
validationQuery: SELECT 1
stat-view-servlet:
enabled: true
url-pattern: /druid/*
# dubbo
dubbo:
application:
name: ${spring.application.name}
registry:
address: nacos://192.168.3.200:8848
parameters:
namespace: ${spring.cloud.nacos.discovery.namespace}
protocol:
port: 20880
provider:
timeout: 3000
retries: 0
check: false
consumer:
timeout: 3000
retries: 0
check: false
#MQ
rocketmq:
name-server: 192.168.3.200:9876
producer:
group: ${spring.application.name}-provider-group
access-key: ENC(1tdvMPxo2WaCW3exv64HG7LQHgg/T/zdUsubpXmYHjU=)
secret-key: ENC(SIbQF8Bjxfgf6ehjLtwj5azXCl2tEV79XcRL2IbEQHU=)
enable-msg-trace: true
consumer:
group: ${spring.application.name}-consumer-group
message:
consumerGroup: GID_${spring.application.name}-consumer-group-${spring.profiles.active}
delayConsumerGroup: GID_${spring.application.name}-delay-consumer-group-${spring.profiles.active}
mybatis-plus:
mapper-locations: classpath*:mybatis/mapper/*/*Mapper.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
sql:
print: true
# 打印日志的配置
logging:
level:
com:
alibaba:
cloud:
nacos:
client: debug
pos:
guolang:
url: http://posdemo3.hzgolong.com:41001/api/pos/notice
secretKey: 141dd8dd814b20baf326daa1f563b5ec

View File

@@ -0,0 +1,88 @@
spring:
redis:
host: 192.168.3.200
port: 6379
password: ENC(ao+A54rgdnsZ/wIydpBlnxYqM34u5B4O)
#=======druid数据源配置=======
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
url: jdbc:mysql://rm-bp193v7i846v01k442o.mysql.rds.aliyuncs.com:3306/tp_order-env-dev?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
# 内网地址
#url: jdbc:mysql://rm-bp193v7i846v01k44.mysql.rds.aliyuncs.com:3306/ins?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: tp_deepinnet_dev
password: B%dkLnXRt@nWjeUA
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
filters: stat,slf4j
initialSize: 5
keepAlive: true
maxActive: 20
maxPoolPreparedStatementPerConnectionSize: 20
maxWait: 60000
minEvictableIdleTimeMillis: 300000
minIdle: 5
poolPreparedStatements: true
testOnBorrow: true
testOnReturn: true
testWhileIdle: true
timeBetweenEvictionRunsMillis: 60000
useGlobalDataSourceStat: true
validationQuery: SELECT 1
stat-view-servlet:
enabled: true
url-pattern: /druid/*
# dubbo
dubbo:
application:
name: ${spring.application.name}
registry:
address: nacos://192.168.3.200:8848
parameters:
namespace: ${spring.cloud.nacos.discovery.namespace}
protocol:
port: 20880
provider:
timeout: 30000
retries: 0
check: false
consumer:
timeout: 30000
retries: 0
check: false
#MQ
rocketmq:
name-server: 192.168.3.200:9876
producer:
group: ${spring.application.name}-provider-group
access-key: ENC(1tdvMPxo2WaCW3exv64HG7LQHgg/T/zdUsubpXmYHjU=)
secret-key: ENC(SIbQF8Bjxfgf6ehjLtwj5azXCl2tEV79XcRL2IbEQHU=)
enable-msg-trace: true
consumer:
group: ${spring.application.name}-consumer-group
message:
consumerGroup: GID_${spring.application.name}-consumer-group-${spring.profiles.active}
delayConsumerGroup: GID_${spring.application.name}-delay-consumer-group-${spring.profiles.active}
mybatis-plus:
mapper-locations: classpath*:mybatis/mapper/*/*Mapper.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
sql:
print: true
# 打印日志的配置
logging:
level:
com:
alibaba:
cloud:
nacos:
client: debug
pos:
guolang:
url: http://posdemo3.hzgolong.com:41001/api/pos/notice
secretKey: 141dd8dd814b20baf326daa1f563b5ec

View File

@@ -0,0 +1,80 @@
spring:
redis:
host: r-bp1ev5drg1lfxkny1p.redis.rds.aliyuncs.com
port: 6379
username: ENC(SCb67WmqS3xLcOWcrGfpRpEszS+bfTEuwycZPawDOPo=)
password: ENC(Va6APbdZCz2kBtKJQIVb97XY4KM6t6qXRnIO5IGY/+U=)
database: 0
autoconfigure:
exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
#=======druid数据源配置=======
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
url: jdbc:mysql://rm-bp13l2n5s8gvc0g7a.mysql.rds.aliyuncs.com:3306/tp_order-env-prod?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
username: ENC(SSQ+shVgs44I1MYoh21T5197DmHjJBBiDcyfXcePf1M=)
password: ENC(rkHZZpYsDbG+npIGG/P4RAGMf9ySzKDmtiwcTDGoliA=)
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
filters: stat,slf4j
initialSize: 5
keepAlive: true
maxActive: 20
maxPoolPreparedStatementPerConnectionSize: 20
maxWait: 60000
minEvictableIdleTimeMillis: 300000
minIdle: 5
poolPreparedStatements: true
testOnBorrow: true
testOnReturn: true
testWhileIdle: true
timeBetweenEvictionRunsMillis: 60000
useGlobalDataSourceStat: true
validationQuery: SELECT 1
stat-view-servlet:
enabled: true
url-pattern: /druid/*
# dubbo
dubbo:
application:
name: ${spring.application.name}
registry:
address: nacos://192.168.3.200:8848
parameters:
namespace: ${spring.cloud.nacos.discovery.namespace}
protocol:
port: 20880
provider:
timeout: 5000
retries: 0
check: false
consumer:
timeout: 5000
retries: 0
check: false
#MQ
rocketmq:
name-server: ep-bp1ie6850ec21aa6c1cd.epsrv-bp1g2k84c7kid2igyiun.cn-hangzhou.privatelink.aliyuncs.com:8080
producer:
group: GID_${spring.application.name}-provider-group-${spring.profiles.active}
access-key: ENC(kIlPWF9cvjyrFjCGo+XO6y43TzYf99t0W3M/eOdi8wI=)
secret-key: ENC(ZWjaBSFtTZh7asRax8+mC1eGf+uSAuLVvUimRr1QB/4=)
enable-msg-trace: true
consumer:
group: GID_${spring.application.name}-consumer-group-${spring.profiles.active}
access-key: ENC(kIlPWF9cvjyrFjCGo+XO6y43TzYf99t0W3M/eOdi8wI=)
secret-key: ENC(ZWjaBSFtTZh7asRax8+mC1eGf+uSAuLVvUimRr1QB/4=)
message:
consumerGroup: GID_${spring.application.name}-consumer-group-${spring.profiles.active}
delayConsumerGroup: GID_${spring.application.name}-delay-consumer-group-${spring.profiles.active}
mybatis-plus:
mapper-locations: classpath*:mybatis/mapper/*/*Mapper.xml
pos:
guolang:
url: http://10.0.30.157:41001/api/pos/notice
secretKey: 246dd25f10552ba553912d018f4df26f

View File

@@ -0,0 +1,80 @@
spring:
redis:
host: r-bp1ev5drg1lfxkny1p.redis.rds.aliyuncs.com
port: 6379
username: ENC(SCb67WmqS3xLcOWcrGfpRpEszS+bfTEuwycZPawDOPo=)
password: ENC(Va6APbdZCz2kBtKJQIVb97XY4KM6t6qXRnIO5IGY/+U=)
database: 1
autoconfigure:
exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
#=======druid数据源配置=======
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
url: jdbc:mysql://rm-bp13l2n5s8gvc0g7a.mysql.rds.aliyuncs.com:3306/tp_order-env-prod?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
username: ENC(SSQ+shVgs44I1MYoh21T5197DmHjJBBiDcyfXcePf1M=)
password: ENC(rkHZZpYsDbG+npIGG/P4RAGMf9ySzKDmtiwcTDGoliA=)
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
filters: stat,slf4j
initialSize: 15
keepAlive: true
maxActive: 20
maxPoolPreparedStatementPerConnectionSize: 20
maxWait: 60000
minEvictableIdleTimeMillis: 300000
minIdle: 5
poolPreparedStatements: true
testOnBorrow: true
testOnReturn: true
testWhileIdle: true
timeBetweenEvictionRunsMillis: 60000
useGlobalDataSourceStat: true
validationQuery: SELECT 1
stat-view-servlet:
enabled: true
url-pattern: /druid/*
# dubbo
dubbo:
application:
name: ${spring.application.name}
registry:
address: nacos://192.168.3.200:8848
parameters:
namespace: ${spring.cloud.nacos.discovery.namespace}
protocol:
port: 20880
provider:
timeout: 5000
retries: 0
check: false
consumer:
timeout: 5000
retries: 0
check: false
#MQ
rocketmq:
name-server: ep-bp1ie6850ec21aa6c1cd.epsrv-bp1g2k84c7kid2igyiun.cn-hangzhou.privatelink.aliyuncs.com:8080
producer:
group: GID_${spring.application.name}-provider-group-${spring.profiles.active}
access-key: ENC(kIlPWF9cvjyrFjCGo+XO6y43TzYf99t0W3M/eOdi8wI=)
secret-key: ENC(ZWjaBSFtTZh7asRax8+mC1eGf+uSAuLVvUimRr1QB/4=)
enable-msg-trace: true
consumer:
group: GID_${spring.application.name}-consumer-group-${spring.profiles.active}
access-key: ENC(kIlPWF9cvjyrFjCGo+XO6y43TzYf99t0W3M/eOdi8wI=)
secret-key: ENC(ZWjaBSFtTZh7asRax8+mC1eGf+uSAuLVvUimRr1QB/4=)
message:
consumerGroup: GID_${spring.application.name}-consumer-group-${spring.profiles.active}
delayConsumerGroup: GID_${spring.application.name}-delay-consumer-group-${spring.profiles.active}
mybatis-plus:
mapper-locations: classpath*:mybatis/mapper/*/*Mapper.xml
pos:
guolang:
url: http://10.0.30.157:41001/api/pos/notice
secretKey: 246dd25f10552ba553912d018f4df26f

View File

@@ -0,0 +1,78 @@
spring:
redis:
host: r-bp1jtsv1a3ougumlzw.redis.rds.aliyuncs.com
port: 6379
username: ENC(9d6KFkbMHm78VQO26J2gNbV9UGuiDZJL)
password: ENC(08E69p0zaGkABm5yj/nV4B3UWGoQeBhWvc7F5JbTp3g=)
database: 1
#=======druid数据源配置=======
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
# 公网地址 记得替换地址和密码!!!
url: jdbc:mysql://rm-bp193v7i846v01k442o.mysql.rds.aliyuncs.com:3306/tp_order-env-test?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
# 内网地址
#url: jdbc:mysql://rm-bp193v7i846v01k44.mysql.rds.aliyuncs.com:3306/ins?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: tp_deepinnet_test
password: 20230424MnfFfdWZsyH2KvuF
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
filters: stat,slf4j
initialSize: 5
keepAlive: true
maxActive: 20
maxPoolPreparedStatementPerConnectionSize: 20
maxWait: 60000
minEvictableIdleTimeMillis: 300000
minIdle: 5
poolPreparedStatements: true
testOnBorrow: true
testOnReturn: true
testWhileIdle: true
timeBetweenEvictionRunsMillis: 60000
useGlobalDataSourceStat: true
validationQuery: SELECT 1
stat-view-servlet:
enabled: true
url-pattern: /druid/*
# dubbo
dubbo:
application:
name: ${spring.application.name}
registry:
address: nacos://192.168.3.200:8848
parameters:
namespace: ${spring.cloud.nacos.discovery.namespace}
protocol:
port: 20880
provider:
timeout: 10000
retries: 0
check: false
consumer:
timeout: 10000
retries: 0
check: false
#MQ
rocketmq:
name-server: rmq-cn-lbj3h31640b-vpc.cn-hangzhou.rmq.aliyuncs.com:8080
producer:
group: ${spring.application.name}-provider-group
access-key: ENC(1g0pNKHGlvtuY4YKgOlGr/MH2BbcDNu0+qPTvjR/EIo=)
secret-key: ENC(MeO1kHiQbBCu4qPRFcCWlgGzbKNl6rOg7YyXxCDNH0M=)
enable-msg-trace: true
consumer:
group: ${spring.application.name}-consumer-group
message:
consumerGroup: GID_${spring.application.name}-consumer-group-${spring.profiles.active}
delayConsumerGroup: GID_${spring.application.name}-delay-consumer-group-${spring.profiles.active}
mybatis-plus:
mapper-locations: classpath*:mybatis/mapper/*/*Mapper.xml
pos:
guolang:
url: http://posdemo3.hzgolong.com:41001/api/pos/notice
secretKey: 141dd8dd814b20baf326daa1f563b5ec

View File

@@ -0,0 +1,26 @@
# oss配置
oss:
accessSecret: ENC(ys+mbFnF71afPL22YUWw0P0B/RSRMh8vgOswK7KhFIq5tq3/SAZQQg==)
accessKey: ENC(NaC4iCnLX+bUXi5ifbwjJQXenTTsKE5xpt7QXQs0nMPxzCfgxzQfVQ==)
# 文件过期时间 3600 * 1000 默认1个小时 (毫秒)
expireMilliSecond: 3600000
spring:
# 防止 Knife4j 2.0及以上版本访问报错
mvc:
pathmatch:
matching-strategy: ant_path_matcher
jasypt:
encryptor:
# 自定义加密盐值(密钥)
password: shendu188
# 加密算法设置
algorithm: PBEWithMD5AndDES
iv-generator-classname: org.jasypt.iv.NoIvGenerator
message:
user-topic: TP_USER_EVENT_TOPIC-${spring.profiles.active}
tradecore-topic: TP_TRADECORE_EVENT_TOPIC-${spring.profiles.active}

View File

@@ -0,0 +1,23 @@
server:
port: 8080
spring:
application:
name: tptradecore
# nacos
cloud:
nacos:
# 注册中心的配置
discovery:
server-addr: http://192.168.3.200:8848
namespace: tp_dev
group: DEFAULT_GROUP
register-enabled: false
config:
import-check:
enabled: false
server-addr: http://192.168.3.200:8848
refresh-enabled: true
namespace: ${spring.cloud.nacos.discovery.namespace}
name: ${spring.application.name}
file-extension: properties

View File

@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="CONSOLE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread][%X{traceId}][BizType:%X{bizType}] %-5level %logger{36} - %msg%n"/>
<!--dev文件路径src同级目录logs,如果上级目录不存在会自动创建-->
<property name="LOG_FILE_PATH" value="./logs/tptradecore" />
<!-- 控制台输出 -->
<appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 按照每天生成系统默认日志文件 -->
<appender name="defaultAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE_PATH}/common-default.log</file>
<encoder charset="UTF-8">
<!--格式化输出:%d表示日期%thread表示线程%-5level级别从左显示五个字符宽度%logger{36}logger是class的全名,后面的数字代表限制最长的字符,%msg日志消息%n换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread][%X{traceId}][Tenant-Id:%X{Tenant-Id}][BizType:%X{bizType}] %-5level %logger{36}:%L - %msg%n</pattern>
</encoder>
<!--滚动策略按照时间滚动-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily 文件名称 -->
<fileNamePattern>${LOG_FILE_PATH}/common-default.log.%d{yyyy-MM-dd}</fileNamePattern>
</rollingPolicy>
</appender>
<!-- 按照每天生成系统默认日志文件 -->
<appender name="dalAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE_PATH}/common-dal.log</file>
<encoder charset="UTF-8">
<!--格式化输出:%d表示日期%thread表示线程%-5level级别从左显示五个字符宽度%logger{36}logger是class的全名,后面的数字代表限制最长的字符,%msg日志消息%n换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread][%X{traceId}][Tenant-Id:%X{Tenant-Id}][BizType:%X{bizType}] %-5level %logger{36}:%L - %msg%n</pattern>
</encoder>
<!--滚动策略按照时间滚动-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily 文件名称 -->
<fileNamePattern>${LOG_FILE_PATH}/common-dal.log.%d{yyyy-MM-dd}</fileNamePattern>
</rollingPolicy>
</appender>
<!-- 按照每天生成业务摘要日志文件 -->
<appender name="bizDigestAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE_PATH}/biz-digest.log</file>
<encoder charset="UTF-8">
<!--格式化输出:%d表示日期%thread表示线程%-5level级别从左显示五个字符宽度%logger{36}logger是class的全名,后面的数字代表限制最长的字符,%msg日志消息%n换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread][%X{traceId}][Tenant-Id:%X{Tenant-Id}][BizType:%X{bizType}] %-5level %logger{36}:%L - %msg%n</pattern>
</encoder>
<!--滚动策略按照时间滚动-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily 文件名称 -->
<fileNamePattern>${LOG_FILE_PATH}/biz-digest.log.%d{yyyy-MM-dd}</fileNamePattern>
</rollingPolicy>
</appender>
<!-- 按照每天生成消息日志文件 -->
<appender name="messageAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE_PATH}/message.log</file>
<encoder charset="UTF-8">
<!--格式化输出:%d表示日期%thread表示线程%-5level级别从左显示五个字符宽度%logger{36}logger是class的全名,后面的数字代表限制最长的字符,%msg日志消息%n换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread][%X{traceId}][Tenant-Id:%X{Tenant-Id}][BizType:%X{bizType}] %-5level %logger{36}:%L - %msg%n</pattern>
</encoder>
<!--滚动策略按照时间滚动-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily 文件名称 -->
<fileNamePattern>${LOG_FILE_PATH}/message.log.%d{yyyy-MM-dd}</fileNamePattern>
</rollingPolicy>
</appender>
<!-- 按照每天生成定时任务的日志文件 -->
<appender name="scheduleTaskAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE_PATH}/task.log</file>
<encoder charset="UTF-8">
<!--格式化输出:%d表示日期%thread表示线程%-5level级别从左显示五个字符宽度%logger{36}logger是class的全名,后面的数字代表限制最长的字符,%msg日志消息%n换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread][%X{traceId}][Tenant-Id:%X{Tenant-Id}][BizType:%X{bizType}] %-5level %logger{36}:%L - %msg%n</pattern>
</encoder>
<!--滚动策略按照时间滚动-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily 文件名称 -->
<fileNamePattern>${LOG_FILE_PATH}/task.log.%d{yyyy-MM-dd}</fileNamePattern>
</rollingPolicy>
</appender>
<!-- 按照每天生成二方/三方集成日志文件 -->
<appender name="integrationAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE_PATH}/integration.log</file>
<encoder charset="UTF-8">
<!--格式化输出:%d表示日期%thread表示线程%-5level级别从左显示五个字符宽度%logger{36}logger是class的全名,后面的数字代表限制最长的字符,%msg日志消息%n换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread][%X{traceId}][Tenant-Id:%X{Tenant-Id}][BizType:%X{bizType}] %-5level %logger{36}:%L - %msg%n</pattern>
</encoder>
<!--滚动策略按照时间滚动-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily 文件名称 -->
<fileNamePattern>${LOG_FILE_PATH}/integration.log.%d{yyyy-MM-dd}</fileNamePattern>
</rollingPolicy>
</appender>
<!-- 按照每天生成错误日志文件 -->
<appender name="errorAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE_PATH}/common-error.log</file>
<!-- 此日志文件只记录ERROR级别的 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder charset="UTF-8">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread][%X{traceId}][Tenant-Id:%X{Tenant-Id}][BizType:%X{bizType}] %-5level %logger{36}:%L - %msg%n</pattern>
</encoder>
<!--输出日志到src同级目录logs中的error.log文件中-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE_PATH}/common-error.log.%d{yyyy-MM-dd}</fileNamePattern>
</rollingPolicy>
</appender>
<logger name="BIZ-DIGEST-LOG" level="info" additivity="false">
<appender-ref ref="bizDigestAppender" />
</logger>
<logger name="MESSAGE-LOG" level="info" additivity="false">
<appender-ref ref="messageAppender" />
</logger>
<logger name="SCHEDULE-TASK-LOG" level="info" additivity="false">
<appender-ref ref="scheduleTaskAppender" />
</logger>
<logger name="INTEGRATION-LOG" level="info" additivity="false">
<appender-ref ref="integrationAppender" />
</logger>
<logger name="DAL-LOG" level="info" additivity="false">
<appender-ref ref="dalAppender" />
</logger>
<root level="INFO">
<appender-ref ref="consoleAppender" />
<appender-ref ref="defaultAppender" />
<appender-ref ref="errorAppender" />
</root>
</configuration>

View File

@@ -0,0 +1,751 @@
/*
Navicat Premium Data Transfer
Source Server : laobinggun
Source Server Type : MySQL
Source Server Version : 80028 (8.0.28)
Source Host : 120.48.79.82:3307
Source Schema : tp_order
Target Server Type : MySQL
Target Server Version : 80028 (8.0.28)
File Encoding : 65001
Date: 14/08/2023 17:56:44
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for tp_audit_record
-- ----------------------------
DROP TABLE IF EXISTS `tp_audit_record`;
CREATE TABLE `tp_audit_record` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`audit_no` varchar(32) COLLATE utf8mb4_general_ci NOT NULL COMMENT '审核单号',
`biz_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '业务单号',
`biz_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '业务类型',
`audit_time` datetime DEFAULT NULL COMMENT '审核时间',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
`status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '状态',
`auditor_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '审核员编号',
`auditor_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '审核员姓名',
`biz_data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '业务拓展字段',
`tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户id',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='审核单';
-- ----------------------------
-- Table structure for tp_bill
-- ----------------------------
DROP TABLE IF EXISTS `tp_bill`;
CREATE TABLE `tp_bill` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`bill_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '账单编号',
`amount` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '账单金额',
`order_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单号',
`pay_order_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '支付单号',
`status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '账单状态',
`biz_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '业务类型',
`bill_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '账单类型',
`remark` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
`tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户id',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`biz_data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=107 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='账单';
-- ----------------------------
-- Table structure for tp_charge
-- ----------------------------
DROP TABLE IF EXISTS `tp_charge`;
CREATE TABLE `tp_charge` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`charge_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '计费单号',
`pay_order_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '支付单号',
`biz_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '业务类型',
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '计费标题',
`charge_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '计费类型',
`amount` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '收退费金额',
`ratio` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '计费比例',
`charging_entity_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '收费主体id',
`charging_entity_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '收费主体类型',
`status` varchar(32) COLLATE utf8mb4_general_ci NOT NULL COMMENT '状态',
`tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户id',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`biz_data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=48 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='计费单';
-- ----------------------------
-- Table structure for tp_financial_account
-- ----------------------------
DROP TABLE IF EXISTS `tp_financial_account`;
CREATE TABLE `tp_financial_account` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`biz_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '关联的业务单号',
`biz_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '业务类型',
`account_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '账号类型:收款方或者付款方',
`account` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '账号',
`account_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '账号名称',
`channel` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '支付宝、微信、银行',
`card_issuer_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '卡机构id',
`bank_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '开户行名称',
`bank_account` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '银行账号',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户id',
`biz_data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=209 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='资金账号';
-- ----------------------------
-- Table structure for tp_order
-- ----------------------------
DROP TABLE IF EXISTS `tp_order`;
CREATE TABLE `tp_order` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`product_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '产品编码',
`product_name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '产品名称',
`product_category_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '产品类目编码',
`product_category` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '产品类目名称',
`out_request_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '外部业务单号',
`user_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户编码',
`order_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编码',
`parent_order_no` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '父订单编号',
`original_order_no` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '原订单号',
`main` tinyint NOT NULL COMMENT '是否主订单0-否;1-是)',
`status` int NOT NULL COMMENT '订单状态',
`approve_status` tinyint DEFAULT NULL COMMENT '审核状态0-待审核;1-审核通过;2-审核不通过)',
`type` tinyint NOT NULL COMMENT '订单类型(尾款订单 / 改签订单 / 普通订单)',
`pay_amount` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '付款金额',
`original_amount` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '订单优惠前原金额',
`source` tinyint NOT NULL COMMENT '订单来源APP / 微信小程序 / 支付宝小程序 / H5',
`pay_type` tinyint DEFAULT NULL COMMENT '支付方式',
`identity_verificat` tinyint NOT NULL COMMENT '是否实名认证0-否;1-是)',
`ticket_type` tinyint DEFAULT NULL COMMENT '车票类型',
`order_time` bigint NOT NULL COMMENT '下单时间',
`pay_time` bigint DEFAULT NULL COMMENT '支付时间',
`close_time` bigint DEFAULT NULL COMMENT '订单关闭时间',
`expire_time` bigint DEFAULT NULL COMMENT '订单过期时间',
`biz_data` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`tenant_id` varchar(32) COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除0-否;1-是)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_order_no` (`order_no`) USING BTREE COMMENT '订单唯一编号',
KEY `idx_user_no` (`user_no`) USING BTREE COMMENT '用户编号索引',
KEY `idx_parent_order_no` (`parent_order_no`) USING BTREE COMMENT '父订单号索引',
KEY `idx_original_order_no` (`original_order_no`) USING BTREE COMMENT '原订单号索引'
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='订单';
-- ----------------------------
-- Table structure for tp_order_discount
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_discount`;
CREATE TABLE `tp_order_discount` (
`id` bigint NOT NULL COMMENT '主键ID',
`pricing_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '计价记录编号',
`order_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编码',
`type` tinyint NOT NULL COMMENT '优惠类型',
`discount_amount` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '优惠金额',
`biz_data` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`tenant_id` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'CURRENT_TIMESTAMP',
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除0-否;1-是)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='优惠信息';
-- ----------------------------
-- Table structure for tp_order_dispatch_record
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_dispatch_record`;
CREATE TABLE `tp_order_dispatch_record` (
`id` bigint NOT NULL COMMENT '主键ID',
`dispatch_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '派单编码',
`order_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编码',
`dispatch_status` tinyint NOT NULL COMMENT '派单状态',
`biz_data` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` tinyint NOT NULL COMMENT '是否删除0-否;1-是)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='派单记录';
-- ----------------------------
-- Table structure for tp_order_driver_info
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_driver_info`;
CREATE TABLE `tp_order_driver_info` (
`id` bigint NOT NULL COMMENT '主键ID',
`transportation_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '承运交通工具编码',
`name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '司机',
`concat` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '司机联系方式',
`biz_data` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`tenant_id` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除0-否;1-是)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='司机信息';
-- ----------------------------
-- Table structure for tp_order_element
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_element`;
CREATE TABLE `tp_order_element` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`order_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编号',
`element_type` tinyint NOT NULL COMMENT '要素类型(下单 / 退款 / 改签)',
`element_code` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '要素code',
`element_name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '要素名称',
`element_key` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '要素Key',
`element_value` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '要素值',
`tenant_id` varchar(32) COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` tinyint NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Table structure for tp_order_item_element
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_item_element`;
CREATE TABLE `tp_order_item_element` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`order_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编号',
`item_no` varchar(20) COLLATE utf8mb4_general_ci NOT NULL COMMENT '标的项编码',
`element_name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '要素名称',
`element_value` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '要素值',
`element_unit` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '要素单位',
`biz_data` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`tenant_id` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除0-否;1-是)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Table structure for tp_order_passenger
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_passenger`;
CREATE TABLE `tp_order_passenger` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`passenger_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '乘客编号',
`order_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编号',
`passenger_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '乘客姓名',
`passenger_contact` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '联系方式',
`identification_type` tinyint DEFAULT NULL COMMENT '乘客证件类型',
`identification_number` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '乘客证件编号',
`biz_data` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`tenant_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除0-否;1-是)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='乘客';
-- ----------------------------
-- Table structure for tp_order_passenger_trip_relation
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_passenger_trip_relation`;
CREATE TABLE `tp_order_passenger_trip_relation` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`passenger_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '干系人编号',
`trip_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '行程单编号',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Table structure for tp_order_placer
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_placer`;
CREATE TABLE `tp_order_placer` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`placer_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '下单人编号',
`order_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编号',
`placer_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '下单人姓名',
`placer_contact` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '联系方式',
`biz_data` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`tenant_id` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除0-否;1-是)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='下单人';
-- ----------------------------
-- Table structure for tp_order_price_record
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_price_record`;
CREATE TABLE `tp_order_price_record` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`pricing_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '计价记录编号',
`order_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编码',
`pricing_amount` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '计价金额',
`pricing_type` tinyint NOT NULL COMMENT '计价类型',
`pricing_params` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '计价参数',
`biz_data` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`tenant_id` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除0-否;1-是)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='计价记录';
-- ----------------------------
-- Table structure for tp_order_requirement_user
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_requirement_user`;
CREATE TABLE `tp_order_requirement_user` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`order_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编号',
`requirement_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用车人名称',
`requirement_contact_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
`requirement_contact` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '联系方式',
`biz_data` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`tenant_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除0-否;1-是)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='需求方';
-- ----------------------------
-- Table structure for tp_order_route
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_route`;
CREATE TABLE `tp_order_route` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`order_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编号',
`route_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '线路编号',
`route_name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '线路名称',
`round_trip` tinyint DEFAULT NULL COMMENT '去程 / 返程',
`tenant_id` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`biz_data` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Table structure for tp_order_route_schedule
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_route_schedule`;
CREATE TABLE `tp_order_route_schedule` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`order_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编号',
`route_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '线路编号',
`schedule_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '班次编号',
`schedule_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '班次名称',
`schedule_time` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '班次时间',
`biz_data` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
`tenant_id` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` tinyint NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Table structure for tp_order_service_target
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_service_target`;
CREATE TABLE `tp_order_service_target` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`order_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编号',
`target_name` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '服务主体名称',
`target_number` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '服务对象唯一编码',
`tenant_id` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`biz_data` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除0-否;1-是)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='服务对象';
-- ----------------------------
-- Table structure for tp_order_subject_item
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_subject_item`;
CREATE TABLE `tp_order_subject_item` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`item_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '标的编码',
`order_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编码',
`passenger_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '乘客编码(干系人)',
`name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '标的名称',
`type` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '标的类型',
`count` int NOT NULL COMMENT '标的项购买数量',
`biz_data` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`tenant_id` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除0-否;1-是)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Table structure for tp_order_transportation
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_transportation`;
CREATE TABLE `tp_order_transportation` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`dispatch_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '派单编码',
`transportation_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '承运交通工具编码',
`driver` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '司机',
`status` tinyint DEFAULT NULL COMMENT '状态',
`position` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '位置',
`type` tinyint DEFAULT NULL COMMENT '类型',
`biz_data` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`tenant_id` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除0-否;1-是)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Table structure for tp_order_travel_trip
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_travel_trip`;
CREATE TABLE `tp_order_travel_trip` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`trip_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '行程单编号',
`passenger_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '乘客编号',
`order_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单编号',
`pick_up_location_code` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '上车点code',
`pick_up_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '上车点名称',
`drop_off_location_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '下车点code',
`drop_off_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '下车点名称',
`start_time` datetime DEFAULT NULL COMMENT '出发时间',
`end_time` datetime DEFAULT NULL COMMENT '到达时间',
`biz_data` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`tenant_id` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除0-否;1-是)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='行程单';
-- ----------------------------
-- Table structure for tp_order_trip_position
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_trip_position`;
CREATE TABLE `tp_order_trip_position` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`trip_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '行程单编号',
`location_code` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '位置编码',
`location_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '位置名称',
`lng` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '经度',
`lat` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '维度',
`biz_data` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`tenant_id` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除0-否;1-是)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Table structure for tp_order_vehicle_info
-- ----------------------------
DROP TABLE IF EXISTS `tp_order_vehicle_info`;
CREATE TABLE `tp_order_vehicle_info` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`transportation_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '交通工具编码',
`vehicle_number` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '车牌号',
`biz_data` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`tenant_id` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除0-否;1-是)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Table structure for tp_pay_order
-- ----------------------------
DROP TABLE IF EXISTS `tp_pay_order`;
CREATE TABLE `tp_pay_order` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`pay_order_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '支付单号',
`biz_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '业务单号',
`biz_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '业务类型',
`discount_amount` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '优惠金额',
`charge_amount` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '计费金额',
`pay_amount` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '实付金额',
`pay_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '支付方式',
`pay_scene` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '支付场景',
`pay_title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '支付标题',
`status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '支付单状态',
`pay_time` datetime DEFAULT NULL COMMENT '支付时间',
`pay_timeout` datetime DEFAULT NULL COMMENT '支付超时时间',
`out_pay_flow_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '三方支付流水号',
`charge_required` tinyint(1) NOT NULL COMMENT '是否需要计收费',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户id',
`biz_data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=115 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='支付单';
-- ----------------------------
-- Table structure for tp_refund_apply_order
-- ----------------------------
DROP TABLE IF EXISTS `tp_refund_apply_order`;
CREATE TABLE `tp_refund_apply_order` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`refund_apply_order_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '退票申请单号',
`product_category_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '产品类目编码',
`product_category_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '产品类目名称',
`user_no` varchar(64) COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',
`order_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '原订单号',
`biz_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '业务类型',
`reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '退票原因',
`apply_time` bigint NOT NULL COMMENT '申请时间',
`status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '状态',
`apply_amount` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '申请金额',
`charge_amount` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '计费金额',
`refund_amount` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '实退金额',
`refund_type` varchar(32) COLLATE utf8mb4_general_ci NOT NULL COMMENT '退款方式',
`tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户id',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`biz_data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='退票申请单';
-- ----------------------------
-- Table structure for tp_refund_element
-- ----------------------------
DROP TABLE IF EXISTS `tp_refund_element`;
CREATE TABLE `tp_refund_element` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`refund_apply_order_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '退款申请单号',
`element_type` tinyint NOT NULL COMMENT '要素类型(下单 / 退款 / 改签)',
`element_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '要素code',
`element_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '要素名称',
`element_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '要素Key',
`element_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '要素值',
`tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` tinyint NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Table structure for tp_refund_passenger
-- ----------------------------
DROP TABLE IF EXISTS `tp_refund_passenger`;
CREATE TABLE `tp_refund_passenger` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`refund_apply_order_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '退票申请单编号',
`refund_subject_item_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '退票标的项编号',
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '姓名',
`contact_info` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '联系方式',
`cert_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '证件号',
`cert_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '证件类型',
`tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户id',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`biz_data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='退款申请单关联的乘客信息';
-- ----------------------------
-- Table structure for tp_refund_requirement_user
-- ----------------------------
DROP TABLE IF EXISTS `tp_refund_requirement_user`;
CREATE TABLE `tp_refund_requirement_user` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`refund_apply_order_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '退票申请单编号',
`refund_subject_item_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '退票标的项id',
`requirement_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '交通需求方编号',
`requirement_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '交通需求方名称',
`contact_info` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '联系方式',
`contact_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '联系人姓名',
`tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户id',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`biz_data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='退款申请单关联的交通需求方(用车方)';
-- ----------------------------
-- Table structure for tp_refund_route
-- ----------------------------
DROP TABLE IF EXISTS `tp_refund_route`;
CREATE TABLE `tp_refund_route` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`refund_apply_order_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '退票申请单号',
`route_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '线路编号',
`route_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '线路名称',
`round_trip` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '去程 / 返程',
`tenant_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`biz_data` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '扩展字段',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '是否删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Table structure for tp_refund_route_schedule
-- ----------------------------
DROP TABLE IF EXISTS `tp_refund_route_schedule`;
CREATE TABLE `tp_refund_route_schedule` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`refund_apply_order_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '退票申请单号',
`route_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '线路编号',
`schedule_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '班次编号',
`schedule_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '班次名称',
`schedule_time` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '班次时间',
`biz_data` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
`tenant_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户ID',
`gmt_created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` tinyint NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Table structure for tp_refund_subject_item
-- ----------------------------
DROP TABLE IF EXISTS `tp_refund_subject_item`;
CREATE TABLE `tp_refund_subject_item` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`refund_apply_order_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '退票申请单号',
`subject_item_no` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '退票标的项编号',
`subject_item_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '标的项id',
`subject_item_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '标的项类型',
`quantity` int NOT NULL COMMENT '数量',
`tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户id',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`biz_data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='退票标的项';
-- ----------------------------
-- Table structure for tp_refund_subject_item_element
-- ----------------------------
DROP TABLE IF EXISTS `tp_refund_subject_item_element`;
CREATE TABLE `tp_refund_subject_item_element` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`subject_item_no` varchar(64) COLLATE utf8mb4_general_ci NOT NULL COMMENT '标的项编号',
`name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '要素名称',
`code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '要素编码',
`value` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '要素值',
`unit_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '单位编码',
`tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户id',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`biz_data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='退票标的项要素';
-- ----------------------------
-- Table structure for tp_voucher
-- ----------------------------
DROP TABLE IF EXISTS `tp_voucher`;
CREATE TABLE `tp_voucher` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`voucher_no` varchar(64) COLLATE utf8mb4_general_ci NOT NULL COMMENT '凭证编号',
`user_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户编号',
`order_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单号',
`voucher_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '凭证编码',
`type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '凭证类型',
`effective_start_time` datetime NOT NULL COMMENT '有效期开始时间',
`effective_end_time` datetime NOT NULL COMMENT '有效期结束时间',
`earliest_check_time` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '当天最早检票时间',
`latest_check_time` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '当天最晚检票时间',
`route_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '线路id',
`route_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '线路名称',
`schedule_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '班次id',
`schedule_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '班次名称',
`validation_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '验票方式',
`total_count` int NOT NULL COMMENT '总可用次数',
`redemption_count` int NOT NULL COMMENT '已核销次数',
`required_real_name` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否需要实名0表示非实名1表示实名',
`status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '凭证状态',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户id',
`biz_data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='出行凭证';
-- ----------------------------
-- Table structure for tp_voucher_inspection_record
-- ----------------------------
DROP TABLE IF EXISTS `tp_voucher_inspection_record`;
CREATE TABLE `tp_voucher_inspection_record` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`voucher_no` varchar(64) COLLATE utf8mb4_general_ci NOT NULL COMMENT '凭证编号',
`user_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户编号',
`param` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '送检参数',
`result` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '返回结果',
`api` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '送检api',
`inspection_time` datetime NOT NULL COMMENT '送检时间',
`inst_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '三方机构名称',
`inst_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '三方机构编码',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户id',
`biz_data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='第三方送检记录';
-- ----------------------------
-- Table structure for tp_voucher_passenger
-- ----------------------------
DROP TABLE IF EXISTS `tp_voucher_passenger`;
CREATE TABLE `tp_voucher_passenger` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`voucher_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '凭证编号',
`name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '姓名',
`contact_info` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '联系方式',
`cert_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '证件号',
`cert_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '证件类型',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户id',
`biz_data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='凭证干系人';
-- ----------------------------
-- Table structure for tp_voucher_verification_record
-- ----------------------------
DROP TABLE IF EXISTS `tp_voucher_verification_record`;
CREATE TABLE `tp_voucher_verification_record` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`voucher_no` varchar(64) COLLATE utf8mb4_general_ci NOT NULL COMMENT '凭证编号',
`user_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户编号',
`verification_time` bigint NOT NULL COMMENT '验票时间',
`result` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '检票结果',
`reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '失败原因',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`tenant_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '租户id',
`biz_data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='检票记录';
SET FOREIGN_KEY_CHECKS = 1;

View File

@@ -0,0 +1,146 @@
package com.deepinnet.tptradecore.core.service.order;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig.Builder;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.engine.BeetlTemplateEngine;
import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler;
import org.junit.jupiter.api.Test;
import java.util.Collections;
/**
*         ┏┓   ┏┓+ +
*        ┏┛┻━━━┛┻┓ + +
*        ┃       ┃
*        ┃   ━   ┃ ++ + + +
*        ████━████ ┃+
*        ┃       ┃ +
*        ┃   ┻   ┃
*        ┃       ┃ + +
*        ┗━┓    ┏━┛
*          ┃   ┃
*          ┃   ┃ + + + +
*                 Code is far away from bug with the animal protecting
*          ┃   ┃ +     神兽保佑,代码无bug
*          ┃   ┃
*          ┃   ┃  +
*          ┃    ┗━━━┓ + +
*          ┃        ┣┓
*          ┃        ┏┛
*          ┗┓┓┏━┳┓┏┛ + + + +
*           ┃┫┫ ┃┫┫
*           ┗┻┛ ┗┻┛+ + + +
*
* @author 唐国翔
* @since 2022-11-05 星期六
* <p>
* dao层模版生成
* 直接运行test方法即可拥有mybatis-plus模版方法
* <p>
* 本地修改后请勿提交!!!
**/
@SuppressWarnings("all")
public class MybatisPlusGenerator {
//============================================ 数据库连接信息 根据实际情况改===============================================//
private final String url = "jdbc:mysql://rm-bp193v7i846v01k442o.mysql.rds.aliyuncs.com:3306/tp_order-env-dev";
private final String userName = "tp_deepinnet_dev";
private final String password = "B%dkLnXRt@nWjeUA";
//============================================ 数据库连接信息 根据实际情况改===============================================//
//======================================= 项目路径根据自己实际情况改 window D:// =========================================//
private final String path
= "/Users/laobinggun/work_space/tptradecore/tptradecore-common/tptradecore-common-dal";
//============================= ============ 项目路径根据自己实际情况改 window D:// ========================================//
//====================================== 包名(例如rule)(会新建包不需要请置空)==============================================//
private final String moduleName = "order";
//===================================== 包名(例如rule会新建包不需要请置空==============================================//
//===================================== 作者 ====================================================//
private final String auth = "abel";
//===================================== 作者 ====================================================//
//============================================ 需要生成的表多个用,分割 ==================================================//
private final String needTables = "tp_order_invoice";
//============================================ 需要生成的表多个用,分割 ==================================================//
@Test
public void generator() {
FastAutoGenerator.create(new Builder(url, userName, password)
.keyWordsHandler(new MySqlKeyWordsHandler()) //关键字处理
.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
switch (metaInfo.getJdbcType()) {
//数据库tinyint类型映射为java的Integer类型
case TINYINT:
case BIT:
return DbColumnType.INTEGER;
//数据库时间类型统一映射为java的Date类型
case DATE:
case TIME:
case TIMESTAMP:
return DbColumnType.LOCAL_DATE_TIME;
default:
return typeRegistry.getColumnType(metaInfo);
}
}))
.globalConfig(builder -> {
builder
.author(auth) // 设置作者
.outputDir(path + "/src/main/java"); // 指定输出目录
})
.packageConfig(builder -> {
builder.parent("com.deepinnet.tptradecore.common.dal") // 设置父包名
.entity("dataobject" + getModuleName())
.mapper("dao" + getModuleName())
.service("repository" + getModuleName())
.serviceImpl(
"repository" + getModuleName() + ".impl")
.pathInfo(
Collections.singletonMap(OutputFile.xml,
path + "/src/main/resources/mybatis/mapper/" + moduleName)); // 设置mapperXml生成路径
})
.strategyConfig(builder -> builder.addInclude(needTables) // 设置需要生成的表名 多个用,隔开
//.addTablePrefix("t_", "c_") // 设置过滤表前缀
//实体类 配置
.entityBuilder()
.idType(IdType.AUTO)
.enableActiveRecord()
//.superClass(BaseEntity.class)
.formatFileName("%sDO")
.enableFileOverride() //是否覆盖
.enableLombok()
.logicDeleteColumnName("is_deleted")
.enableTableFieldAnnotation()
//mapper 配置
.mapperBuilder()
.formatMapperFileName("%sDao")
//.enableFileOverride() //是否覆盖
.enableBaseColumnList()
.enableBaseResultMap()
//repository 配置
.serviceBuilder()
//.enableFileOverride()
.formatServiceFileName("%sRepository")
.formatServiceImplFileName("%sRepositoryImpl"))
.templateConfig(builder -> {
//不生成controller
builder.controller("");
//默认不生成xml 需要的话把下面代码注释掉
//builder.xml("");
})
.templateEngine(new BeetlTemplateEngine()) // 使用beetl引擎模板默认的是Velocity引擎模板
.execute();
}
private String getModuleName() {
return StringUtils.isNotBlank(moduleName) ? "." + moduleName : moduleName;
}
}

View File

@@ -0,0 +1,84 @@
package com.deepinnet.tptradecore.core.service.order;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.json.JSONUtil;
import com.deepinnet.tp.common.lang.page.CommonPage;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tptradecore.common.dto.audit.TpAuditCreatedDTO;
import com.deepinnet.tptradecore.common.dto.audit.TpOrderAuditListQueryDTO;
import com.deepinnet.tptradecore.common.dto.audit.TpOrderAuditPagedQueryDTO;
import com.deepinnet.tptradecore.common.enums.audit.TpAuditBizObjectTypeEnum;
import com.deepinnet.tptradecore.common.enums.audit.TpAuditStatusEnum;
import com.deepinnet.tptradecore.common.enums.audit.TpAuditTypeEnum;
import com.deepinnet.tptradecore.common.service.facade.audit.TpAuditFacade;
import com.deepinnet.tptradecore.common.vo.audit.TpAuditOrderListVO;
import com.deepinnet.tptradecore.core.model.audit.TpAudit;
import com.deepinnet.tptradecore.core.service.audit.TpAuditDomainService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestPropertySource;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* <p>
* 审核领域服务测试类
* </p>
*
* @author chenjiaju
* @since 2023/7/28
*/
@SpringBootTest
//@ActiveProfiles("local")
@TestPropertySource(properties = {
"spring.profiles.active=local"
})
public class TpAuditDomainServiceTest {
@Autowired
private TpAuditDomainService tpAuditDomainService;
@Autowired
private TpAuditFacade tpAuditFacade;
@Test
public void createAuditTest() {
TpAuditCreatedDTO tpAuditCreatedDTO = TpAuditCreatedDTO.builder().tenantId("test").auditorNo("xhqtest01").auditorName("xiehuaqiao")
.bizObjectNo("1234567").bizObjType(TpAuditBizObjectTypeEnum.ORDER_CHANGE_APPLY.getType()).status(TpAuditStatusEnum.WAITING_APPROVED.getType())
.build();
Boolean createFlag = tpAuditDomainService.createAudit(tpAuditCreatedDTO);
Assert.isTrue(createFlag,"创建审核单失败");
}
@Test
public void listOrderAuditTest() {
TpOrderAuditListQueryDTO tpAuditCreatedDTO = TpOrderAuditListQueryDTO.builder().tenantId("1000293")
.auditTypes(Arrays.asList(TpAuditTypeEnum.CHARTER_BUS_ORDER_CANCEL_RSC_APPROVAL.getBizType()))
.build();
List<TpAudit> tpAudits = tpAuditDomainService.listOrderAudit(tpAuditCreatedDTO);
Assert.isTrue(CollUtil.isNotEmpty(tpAudits),"查询列表失败");
}
@Test
public void pageOrderAuditListTest() {
TpOrderAuditPagedQueryDTO dto = TpOrderAuditPagedQueryDTO.builder().tenantId("1000293")
.auditTypes(Arrays.asList(TpAuditTypeEnum.CHARTER_BUS_ORDER_CHANGE_RSC_APPROVAL.getBizType()))
// .orgCodes(Arrays.asList("1111"))
.build();
dto.setPageSize(10);
TpResult<CommonPage<TpAuditOrderListVO>> commonPageTpResult = tpAuditFacade.pageOrderAuditList(dto);
System.err.println(JSONUtil.toJsonPrettyStr(commonPageTpResult.getData()));
}
}

View File

@@ -0,0 +1,167 @@
package com.deepinnet.tptradecore.core.service.order;
import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tptradecore.common.dto.order.*;
import com.deepinnet.tptradecore.common.enums.order.TpOrderChangeTypeEnum;
import com.deepinnet.tptradecore.common.service.facade.order.TpOrderChangedFacade;
import com.deepinnet.tptradecore.common.vo.order.TpOrderChangeApplyVO;
import com.deepinnet.tptradecore.core.model.order.TpOrderChangeApply;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import java.util.Arrays;
import java.util.List;
/**
* <p>
* 审核领域服务测试类
* </p>
*
* @author chenjiaju
* @since 2023/7/28
*/
@SpringBootTest
//@ActiveProfiles("local")
@TestPropertySource(properties = {
"spring.profiles.active=local"
})
public class TpOrderChangeApplyServiceTest {
@Autowired
private TpOrderChangedApplyDomainService tpOrderChangedDomainService;
@Autowired
private TpOrderChangedFacade tpOrderChangedFacade;
@Test
public void createOrderChangeApplyTest() {
String applyJson = "{\n" +
" \"orderNo\":\"20231208006000011214\",\n" +
" \"originalOrderNo\":\"20231208006000011214\",\n" +
" \"applyStatus\":\"waiting_approved\",\n" +
" \"applyTime\":1702021188516,\n" +
" \"applyType\":\"order_change\",\n" +
" \"autoAudit\":false,\n" +
" \"orderChangeItems\":[\n" +
" {\n" +
" \"orderNo\":\"20231208006000011214\",\n" +
" \"itemType\":\"go_trip_changed\",\n" +
" \"itemFactors\":[\n" +
" {\n" +
" \"factorCode\":\"passenger_count\",\n" +
" \"factorName\":\"乘车人数\",\n" +
" \"beforeValue\":\"12\",\n" +
" \"afterValue\":\"32\",\n" +
" \"orderNo\":\"20231208006000011214\",\n" +
" \"tenantId\":\"test\"\n" +
" },\n" +
" {\n" +
" \"factorCode\":\"car_info\",\n" +
" \"factorName\":\"车辆信息\",\n" +
" \"beforeValue\":\"宝斯通K2\",\n" +
" \"afterValue\":\"宝斯通K3\",\n" +
" \"orderNo\":\"20231208006000011214\",\n" +
" \"tenantId\":\"test\"\n" +
" },\n" +
" {\n" +
" \"factorCode\":\"way_point\",\n" +
" \"factorName\":\"途径点\",\n" +
" \"beforeValue\":\"杭州萧山国际机场\",\n" +
" \"afterValue\":\"杭州西湖风景名胜区\",\n" +
" \"sortIndex\":1,\n" +
" \"orderNo\":\"20231208006000011214\",\n" +
" \"tenantId\":\"test\"\n" +
" },\n" +
" {\n" +
" \"factorCode\":\"way_point\",\n" +
" \"factorName\":\"途径点\",\n" +
" \"afterValue\":\"杭州萧山国际机场\",\n" +
" \"sortIndex\":2,\n" +
" \"orderNo\":\"20231208006000011214\",\n" +
" \"tenantId\":\"test\"\n" +
" }\n" +
" ],\n" +
" \"tenantId\":\"test\"\n" +
" }\n" +
" ],\n" +
" \"orderChangeApplicant\":{\n" +
" \"applicantNo\":\"21857\",\n" +
" \"applicantName\":\"18191253790\"\n" +
" },\n" +
" \"tenantId\":\"test\"\n" +
"}";
TpOrderChangeApplyCreatedDTO orderChangeApplyCreatedDTO = JSONObject.parseObject(applyJson, TpOrderChangeApplyCreatedDTO.class);
Boolean createFlag = tpOrderChangedDomainService.createOrderChangeApply(orderChangeApplyCreatedDTO);
Assert.isTrue(createFlag,"创建申请单失败");
}
@Test
public void getOrderChangeApplyDetailTest() {
TpOrderChangeApplyDetailDTO orderChangeApplyQueryDTO = new TpOrderChangeApplyDetailDTO();
// orderChangeApplyQueryDTO.setOrderNo("20231212006000011421");
orderChangeApplyQueryDTO.setOrderNo("20240122006000034026");
orderChangeApplyQueryDTO.setApplyType(TpOrderChangeTypeEnum.ORDER_CHANGE.getType());
orderChangeApplyQueryDTO.setTenantId("21");
TpOrderChangeApply tpOrderChangeApply = tpOrderChangedDomainService.getOrderChangedApplyDetail(orderChangeApplyQueryDTO);
Assert.notNull(tpOrderChangeApply,"该订单没有申请单");
System.err.println(JSON.toJSONString(tpOrderChangeApply));
TpResult<TpOrderChangeApplyVO> orderChangeApplyVOs = tpOrderChangedFacade.getOrderChangedApplyDetail(orderChangeApplyQueryDTO);
Assert.notNull(orderChangeApplyVOs,"该订单没有申请单");
System.err.println(JSON.toJSONString(orderChangeApplyVOs));
}
@Test
public void getLatestOrderChangeApplyDetailTest() {
TpOrderChangeApplyLatestDetailDTO orderChangeApplyQueryDTO = new TpOrderChangeApplyLatestDetailDTO();
orderChangeApplyQueryDTO.setOriginalOrderNo("20240220006000037023");
// orderChangeApplyQueryDTO.setOrderNo("20240220006000037023");
orderChangeApplyQueryDTO.setApplyTypes(Arrays.asList(TpOrderChangeTypeEnum.ORDER_CHANGE.getType(),TpOrderChangeTypeEnum.ORDER_CANCEL.getType()));
orderChangeApplyQueryDTO.setTenantId("1000293");
TpOrderChangeApply tpOrderChangeApply = tpOrderChangedDomainService.getLatestOrderChangedApplyDetail(orderChangeApplyQueryDTO);
Assert.notNull(tpOrderChangeApply,"该订单没有申请单");
System.err.println(JSON.toJSONString(tpOrderChangeApply));
TpResult<TpOrderChangeApplyVO> orderChangeApplyVOs = tpOrderChangedFacade.getLatestOrderChangedApplyDetail(orderChangeApplyQueryDTO);
Assert.notNull(orderChangeApplyVOs,"该订单没有申请单");
System.err.println(JSON.toJSONString(orderChangeApplyVOs));
}
@Test
public void batchQueryOrderChangeApplyByOrderNosTest() {
TpOrderChangeApplyBatchListDTO orderChangeApplyQueryDTO = new TpOrderChangeApplyBatchListDTO();
// orderChangeApplyQueryDTO.setOrderNos(Arrays.asList("20231212006000011421"));
orderChangeApplyQueryDTO.setOriginalOrderNos(Arrays.asList("20231212006000011421"));
orderChangeApplyQueryDTO.setTenantId("test");
List<TpOrderChangeApply> orderChangeApplies = tpOrderChangedDomainService.batchQueryOrderChangeApplyByOrderNos(orderChangeApplyQueryDTO);
Assert.notNull(orderChangeApplies,"该订单没有申请单");
System.err.println(JSON.toJSONString(orderChangeApplies));
}
@Test
public void listOrderChangeApplyTest() {
TpOrderChangeApplyListDTO orderChangeApplyQueryDTO = new TpOrderChangeApplyListDTO();
// orderChangeApplyQueryDTO.setOrderNo("20231212006000011421");
orderChangeApplyQueryDTO.setOriginalOrderNo("20231212006000011421");
orderChangeApplyQueryDTO.setApplyTypes(Arrays.asList(TpOrderChangeTypeEnum.ORDER_CHANGE.getType(),TpOrderChangeTypeEnum.ORDER_CANCEL.getType()));
orderChangeApplyQueryDTO.setTenantId("test");
TpResult<List<TpOrderChangeApplyVO>> orderChangeApplyVOs = tpOrderChangedFacade.listOrderChangeApply(orderChangeApplyQueryDTO);
Assert.notNull(orderChangeApplyVOs,"该订单没有申请单");
System.err.println(JSON.toJSONString(orderChangeApplyVOs));
}
}

View File

@@ -0,0 +1,105 @@
package com.deepinnet.tptradecore.core.service.order;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.json.JSONUtil;
import com.deepinnet.tptradecore.common.dto.audit.TpAuditCreatedDTO;
import com.deepinnet.tptradecore.common.dto.audit.TpOrderAuditListQueryDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderDispatchCallBackDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderDispatchCreatedDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderDispatchFleetCreatedDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderDispatchGiveBackDTO;
import com.deepinnet.tptradecore.common.enums.audit.TpAuditBizObjectTypeEnum;
import com.deepinnet.tptradecore.common.enums.audit.TpAuditStatusEnum;
import com.deepinnet.tptradecore.common.enums.audit.TpAuditTypeEnum;
import com.deepinnet.tptradecore.core.model.audit.TpAudit;
import com.deepinnet.tptradecore.core.model.order.TpOrderDispatch;
import com.deepinnet.tptradecore.core.service.audit.TpAuditDomainService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import java.util.Arrays;
import java.util.List;
/**
* <p>
* 审核领域服务测试类
* </p>
*
* @author chenjiaju
* @since 2023/7/28
*/
@SpringBootTest
//@ActiveProfiles("local")
@TestPropertySource(properties = {
"spring.profiles.active=local","alipay.returnUrl=test"
})
public class TpOrderDispatchDomainServiceTest {
@Autowired
private TpOrderDispatchDomainService tpOrderDispatchDomainService;
@Test
public void dispatchFleetTest() {
TpOrderDispatchFleetCreatedDTO tpAuditCreatedDTO = new TpOrderDispatchFleetCreatedDTO();
tpAuditCreatedDTO.setDispatchNo("20231206015000000334");
tpAuditCreatedDTO.setOrderNo("20231206006000011112");
tpAuditCreatedDTO.setTenantId("test");
tpAuditCreatedDTO.setTargetFleetNo("5111");
Boolean createFlag = tpOrderDispatchDomainService.dispatchFleet(tpAuditCreatedDTO);
Assert.isTrue(createFlag,"指派车队失败");
}
@Test
public void dispatchOrderTest() {
String dispatchJson = "{\"originalOrderNo\":\"20231209006000011249\",\"dispatchScene\":\"user_create_order\",\"dispatchTime\":1702102001294,\"dispatchStatus\":10,\"originOrgNo\":\"21\",\"originOrgName\":\"杭州公交集团公司\",\"originOrgType\":\"0\",\"targetOrgNo\":\"21\",\"targetOrgName\":\"杭州公交集团公司\",\"targetOrgType\":\"0\",\"operatorNo\":\"sysadmin\",\"operatorName\":\"sysadmin\",\"tenantId\":\"test\"}";
TpOrderDispatchCreatedDTO tpOrderDispatch = JSONUtil.toBean(dispatchJson,TpOrderDispatchCreatedDTO.class);
Boolean createFlag = tpOrderDispatchDomainService.dispatchOrder(tpOrderDispatch);
Assert.isTrue(createFlag,"派单失败");
}
@Test
public void getDispatchOrderTest() {
String orderNo = "20231218006000013336";
String tenantId = "1000293";
List<Integer> statuses = Arrays.asList(20);
TpOrderDispatch orderDispatch = tpOrderDispatchDomainService.getDispatchOrder(tenantId,null,orderNo,statuses);
Assert.notNull(orderDispatch,"派单失败");
}
@Test
public void giveBackOrderTest() {
TpOrderDispatchGiveBackDTO tpAuditCreatedDTO = new TpOrderDispatchGiveBackDTO();
tpAuditCreatedDTO.setDispatchNo("20231211015000001011");
tpAuditCreatedDTO.setOriginalOrderNo("20231211006000011340");
tpAuditCreatedDTO.setGiveBackTime(DateUtil.current());
tpAuditCreatedDTO.setTenantId("test");
Boolean createFlag = tpOrderDispatchDomainService.giveBackOrder(tpAuditCreatedDTO);
Assert.isTrue(createFlag,"退单失败");
}
@Test
public void callBackOrderTest() {
TpOrderDispatchCallBackDTO tpAuditCreatedDTO = new TpOrderDispatchCallBackDTO();
tpAuditCreatedDTO.setDispatchNo("20231211015000001011");
tpAuditCreatedDTO.setOriginalOrderNo("20231211006000011340");
tpAuditCreatedDTO.setCallBackTime(DateUtil.current());
tpAuditCreatedDTO.setTenantId("test");
Boolean createFlag = tpOrderDispatchDomainService.callBackOrder(tpAuditCreatedDTO);
Assert.isTrue(createFlag,"退单失败");
}
}

View File

@@ -0,0 +1,35 @@
package com.deepinnet.tptradecore.core.service.order;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tp.common.lang.util.JsonUtil;
import com.deepinnet.tptradecore.common.dto.order.TpOrderDispatchDetailDTO;
import com.deepinnet.tptradecore.common.service.facade.order.TpOrderDispatchFacade;
import com.deepinnet.tptradecore.common.vo.order.TpOrderDispatchVO;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import javax.annotation.Resource;
/**
* Description:
* Date: 2024/6/14
* Author: lijunheng
*/
@SpringBootTest
@TestPropertySource(properties = {"spring.profiles.active=local"})
public class TpOrderDispatchFacadeTest {
@Resource
private TpOrderDispatchFacade orderDispatchFacade;
@Test
public void testGetOrderDispatchDetail() {
TpOrderDispatchDetailDTO dto = new TpOrderDispatchDetailDTO();
dto.setOriginalOrderNo("20231213006000011487");
dto.setTenantId("1000293");
TpResult<TpOrderDispatchVO> orderDispatchDetail = orderDispatchFacade.getOrderDispatchDetail(dto);
System.out.println(JsonUtil.toJsonStr(orderDispatchDetail));
}
}

View File

@@ -0,0 +1,139 @@
package com.deepinnet.tptradecore.core.service.order;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONObject;
import com.deepinnet.tptradecore.common.enums.order.TpOrderModulesEnum;
import com.deepinnet.tptradecore.core.model.order.TpBatchQueryOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderQueryList;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 订单领域服务测试类
* </p>
*
* @author chenjiaju
* @since 2023/7/28
*/
@SpringBootTest
@TestPropertySource(properties = {"spring.profiles.active=local"})
public class TpOrderDomainServiceTest {
@Autowired
private TpOrderDomainService tpOrderDomainService;
private static TpOrder tpCreateOrder;
private static TpOrder tpSubOrders;
@BeforeAll
public static void beforeAll() {
Path path = Paths.get("src", "test", "resources", "json");
String tpOrderJson = FileUtil.readString(path.toAbsolutePath() + "/createOrder.json", Charset.defaultCharset());
tpCreateOrder = JSONObject.parseObject(tpOrderJson, TpOrder.class);
String tpSubOrdersJson = FileUtil.readString(path.toAbsolutePath() + "/createSubOrders.json", Charset.defaultCharset());
tpSubOrders = JSONObject.parseObject(tpSubOrdersJson, TpOrder.class);
}
/**
* 创建订单
*/
@Test
public void createOrder() {
TpOrder order = tpOrderDomainService.createOrder(tpCreateOrder);
Assertions.assertTrue(ObjectUtil.isNotNull(order));
}
/**
* 创建订单(子订单)
*/
@Test
public void createSubOrders() {
TpOrder order = tpOrderDomainService.createOrder(tpSubOrders);
Assertions.assertTrue(ObjectUtil.isNotNull(order));
}
/**
* 订单详情查询,按模块查询
*/
@Test
public void queryOrderDetail(){
List<TpOrderModulesEnum> needModules = new ArrayList<>();
needModules.add(TpOrderModulesEnum.ORDER_SUBJECT_ITEM);
TpOrder order = tpOrderDomainService.getOrder("test", null,"ORDER001", needModules);
Assertions.assertTrue(ObjectUtil.isNotNull(order));
}
/**
* 订单列表
*/
@Test
public void queryOrderList() {
TpOrderQueryList tpOrderQueryList = new TpOrderQueryList();
tpOrderQueryList.setTenantId("test");
tpOrderQueryList.setPageNum(1);
tpOrderQueryList.setPageSize(10);
Assertions.assertDoesNotThrow(() -> tpOrderDomainService.getOrderList(tpOrderQueryList));
}
/**
* 超时关单
*/
@Test
public void closeExpireTimeTest() {
Assertions.assertDoesNotThrow(() -> tpOrderDomainService.closeOrderExpireTime("test", "ORDER001"));
}
/**
* 定制包车取消订单
*/
@Test
public void cancelCharterBusTest() {
Assertions.assertDoesNotThrow(() -> tpOrderDomainService.cancelCharterBus("test", "ORDER001"));
}
/**
* 支付订单状态推进
*/
@Test
public void payOrderTest() {
Assertions.assertDoesNotThrow(() -> tpOrderDomainService.payOrder("test", "ORDER001", null));
}
/**
* 根据线路查询是否有未核销的订单
*/
@Test
public void queryRouteHasUnverifiedOrderTest() {
Assertions.assertDoesNotThrow(() -> tpOrderDomainService.queryRouteHasUnverifiedOrder("123456", "test"));
}
/**
* 根据线路、班次查询是否存在未核销的订单
*/
@Test
public void queryRouteScheduleHasUnverifiedOrderTest() {
Assertions.assertDoesNotThrow(() -> tpOrderDomainService.queryRouteScheduleHasUnverifiedOrder("123456", "438957438", "test"));
}
@Test
public void batchQueryTest() {
Assertions.assertDoesNotThrow(() -> tpOrderDomainService.batchQueryListByOriginalOrderNos(TpBatchQueryOrder.builder()
.originalOrderNos(ListUtil.toList("20231206006000011107", "20231206006000011115"))
.tenantId("test").build()));
}
}

View File

@@ -0,0 +1,74 @@
package com.deepinnet.tptradecore.core.service.order;
import com.deepinnet.tptradecore.core.model.order.TpUserDelPassengerCondition;
import com.deepinnet.tptradecore.core.model.order.TpUserPassengerCondition;
import com.deepinnet.tptradecore.core.model.order.TpUserPassenger;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
/**
* <p>
* 乘客信息领域服务测试类
* </p>
*
* @author chenjiaju
* @since 2023/7/28
*/
@SpringBootTest
@ActiveProfiles("local")
public class TpUserPassengerDomainServiceTest {
@Autowired
private TpUserPassengerDomainService tpUserPassengerDomainService;
@Test
public void savePassengerTest() {
TpUserPassenger tpUserPassenger = new TpUserPassenger();
tpUserPassenger.setUserNo("USER_001");
tpUserPassenger.setPassengerNo("PASSENGER_001");
tpUserPassenger.setPassengerType("1");
tpUserPassenger.setName("juju");
tpUserPassenger.setIdentityType("001");
tpUserPassenger.setIdentityNumber("311000199901011111");
tpUserPassenger.setTenantId("test");
Assertions.assertDoesNotThrow(() -> tpUserPassengerDomainService.savePassenger(tpUserPassenger));
}
@Test
public void modifyPassenger() {
TpUserPassenger tpUserPassenger = new TpUserPassenger();
tpUserPassenger.setUserNo("USER_001");
tpUserPassenger.setPassengerNo("PASSENGER_001");
tpUserPassenger.setPassengerType("1");
tpUserPassenger.setName("ccc-ju");
tpUserPassenger.setIdentityType("001");
tpUserPassenger.setIdentityNumber("311000199901011111");
tpUserPassenger.setTenantId("test");
Assertions.assertDoesNotThrow(() -> tpUserPassengerDomainService.modifyPassenger(tpUserPassenger));
}
@Test
public void getPassengerListTest() {
TpUserPassengerCondition tpUserPassengerCondition = new TpUserPassengerCondition();
tpUserPassengerCondition.setUserNo("USER_001");
tpUserPassengerCondition.setTenantId("test");
Assertions.assertDoesNotThrow(() -> tpUserPassengerDomainService.getPassengerList(tpUserPassengerCondition));
}
@Test
public void delPassenger() {
TpUserDelPassengerCondition tpUserDelPassengerCondition = new TpUserDelPassengerCondition();
tpUserDelPassengerCondition.setUserNo("USER_001");
tpUserDelPassengerCondition.setPassengerNo("PASSENGER_001");
tpUserDelPassengerCondition.setTenantId("test");
Assertions.assertDoesNotThrow(() -> tpUserPassengerDomainService.delPassenger(tpUserDelPassengerCondition));
}
}

View File

@@ -0,0 +1,50 @@
package com.deepinnet.tptradecore.core.service.order;
import com.deepinnet.tptradecore.core.model.order.TpUserRouteCollection;
import com.deepinnet.tptradecore.core.model.order.TpUserRouteCollectionCondition;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
/**
* <p>
* 线路收集领域服务测试类
* </p>
*
* @author chenjiaju
* @since 2023/7/28
*/
@SpringBootTest
@ActiveProfiles("local")
public class TpUserRouteCollectionDomainServiceTest {
@Autowired
private TpUserRouteCollectionDomainService tpUserRouteCollectionDomainService;
@Test
public void saveRouteCollectionTest() {
TpUserRouteCollection tpUserRouteCollection = new TpUserRouteCollection();
tpUserRouteCollection.setUserNo("ORDER001");
tpUserRouteCollection.setUpLocation("东京");
tpUserRouteCollection.setUpLocationLng("120.8934");
tpUserRouteCollection.setUpLocationLat("32.9846");
tpUserRouteCollection.setDownLocation("北京");
tpUserRouteCollection.setDownLocationLng("125.6745");
tpUserRouteCollection.setDownLocationLat("35.6782");
tpUserRouteCollection.setExpectArriveTime("2024-01-01 00:00:00");
tpUserRouteCollection.setExpectBackTime("2024-01-01 06:00:00");
tpUserRouteCollection.setTravelPurpose("上班");
tpUserRouteCollection.setTenantId("test");
tpUserRouteCollectionDomainService.collectRoute(tpUserRouteCollection);
}
@Test
public void queryListTest() {
TpUserRouteCollectionCondition tpUserRouteCollectionCondition = new TpUserRouteCollectionCondition();
tpUserRouteCollectionCondition.setTenantId("test");
Assertions.assertDoesNotThrow(() -> tpUserRouteCollectionDomainService.getCollectionRouteList(tpUserRouteCollectionCondition));
}
}

View File

@@ -0,0 +1,81 @@
package com.deepinnet.tptradecore.core.service.order;
import com.deepinnet.tptradecore.common.service.integration.config.TpWechatPayConfig;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
/**
* @author amos wong
* @create 2023/11/20 10:39
* @Description
*/
@SpringBootTest
@ActiveProfiles("local")
public class TpWechatV3ConfigTest {
@Test
public void getWechatPayConfig() {
TpWechatPayConfig wechatPayConfig = new TpWechatPayConfig();
wechatPayConfig.setAppId("wx63bcbd1ee3143658");
wechatPayConfig.setMchId("1658735192");
//wechatPayConfig.setPayNotifyUrl("https://test.deepinnet.com/tptradecore/wechat/pay/callback");
wechatPayConfig.setPayNotifyUrl("https://deepinnet-callback.vip.cpolar.cn/wechat/pay/callback");
wechatPayConfig.setRefundNotifyUrl("https://deepinnet-callback.vip.cpolar.cn/wechat/refund/callback");
wechatPayConfig.setSerialNo("1145A15B95F7A3B3F2888DCFA94BC71474C68B50");
wechatPayConfig.setPlatSerialNo("30784F90AEF14CB3EE383094878F6247AA3747D7");
wechatPayConfig.setApiKey("Shenduzhilian168188Shenduzhilian");
wechatPayConfig.setCertificate("-----BEGIN CERTIFICATE-----\n" +
"MIIEFDCCAvygAwIBAgIUMHhPkK7xTLPuODCUh49iR6o3R9cwDQYJKoZIhvcNAQEL\n" +
"BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT\n" +
"FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg\n" +
"Q0EwHhcNMjMxMTA3MDkxMTI1WhcNMjgxMTA1MDkxMTI1WjBuMRgwFgYDVQQDDA9U\n" +
"ZW5wYXkuY29tIHNpZ24xEzARBgNVBAoMClRlbnBheS5jb20xHTAbBgNVBAsMFFRl\n" +
"bnBheS5jb20gQ0EgQ2VudGVyMQswCQYDVQQGDAJDTjERMA8GA1UEBwwIU2hlblpo\n" +
"ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzuI4U+RVrlRQ3pVRH\n" +
"Uy4Q9/pPS8KmKgZ/PqTHYLRR4JTibYXg+RTUvY4nC8gLwX8IaE72Nbiv3COXfPk8\n" +
"8DlRnVEvqneZ9q2sTdcCCbMApkylnhpR25+x5Cha/uJDC5o54ThXPQngCtoWZSzV\n" +
"LI60WIB1ti3uQQVg2AVcPz1fxJLxs06Hjn+Qkq3O0GyxnQndKJI0LVwFyVKkXLsm\n" +
"3hD6YhN5pP/7mx8OznMLH01FatSQyJIqWSXLUN8zfkhdLDYBcnvG7MZNkKiRLcDN\n" +
"7UgymalAVAlUw4jLkOIehOlY1boM4aTMhzYX4R22OgIcnL8wGyLzhjNNmY7HNwZY\n" +
"XK6rAgMBAAGjgbkwgbYwCQYDVR0TBAIwADALBgNVHQ8EBAMCA/gwgZsGA1UdHwSB\n" +
"kzCBkDCBjaCBiqCBh4aBhGh0dHA6Ly9ldmNhLml0cnVzLmNvbS5jbi9wdWJsaWMv\n" +
"aXRydXNjcmw/Q0E9MUJENDIyMEU1MERCQzA0QjA2QUQzOTc1NDk4NDZDMDFDM0U4\n" +
"RUJEMiZzZz1IQUNDNDcxQjY1NDIyRTEyQjI3QTlEMzNBODdBRDFDREY1OTI2RTE0\n" +
"MDM3MTANBgkqhkiG9w0BAQsFAAOCAQEAXlmlrufIMaYwj3Hc4oKRQIIs18kxTArz\n" +
"1m6Wrri8OX0gq2A3rsWmyejWKlJ+kEEwiREbOqm25y2OktQZwoSZvcyliwGltBQ6\n" +
"F3jvybnq4hcfFtFZQVSLSeyxEnaRbFnzKkNI7E7UJCSa+CgQWXdDgCCOM3AiEN7C\n" +
"sLmsdDpPszUpTAXrf/27WDJb1xGnLYhYH+rW/grN39RjazDE2MPXQ4xPC+mLSv34\n" +
"qONxX4UxhDij+wlvU8KpcH1rHiE/mZNQdN0nouq/l+5tSBfVREIWqXTsOumA8qyk\n" +
"2GruLEwUiwL3Ffo04dcmp9SVFIQTAMju/T4QgkXFJI9cy167wdCqWg==\n" +
"-----END CERTIFICATE-----");
wechatPayConfig.setPrivateKey("-----BEGIN PRIVATE KEY-----\n" +
"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtbfwLE5cgg78z\n" +
"9f4lqkfD+AfhHqKM0Q173HcEmWYof6b6SvhcqxVCvEj3UAyh6Aq6Cf/aoFighMxv\n" +
"MnbKXi+WWSfWHwZA9BY7gjP/jnlH6ihlKJgecn7N8jeLAuc23R9LSocn7hNFklEh\n" +
"C9SUV2gmej42n0F8bTTMCOb2NqyjhUOq8tnnUzKg98RVyu8YgRMmH1yZiZxUM/1C\n" +
"J6LNCg0qyd4Z4Cs/psVYFDJnE5js2ttORI0ersFpuXpvqCBLlTJ5m4mmTTcY4qe6\n" +
"Ui4WWHtQWcEu4bFsJrXyRYtfFqVAHtTtTI/PFWUhZKv1VagoRqtkIip4EggwJ2+0\n" +
"Dux12nb5AgMBAAECggEBAIbVY4cZC/3zb8vuDFEsOe9Z/oY/UxE31svdc4rX2FzU\n" +
"IfWmI8GoITdpOzFLwwZ9aRmKfKh00XK6zFYHXeOnpke1uQr3w9zr5/0MFXEyS4hl\n" +
"vFIpZVsGmR90mUoyT6CP+ayHnNymc8U7JGgU0okiC48eqw+8cSVToiCfKzFxAHd/\n" +
"9IxB/gSsXXYWKRlhcPcMfjlerl9Wgk5Bxw5Hs2wNTf3QzM5FKbmuJp6cHR7YSxIX\n" +
"tv2aZCcd1qIzXD3IzF7wClHnnnEPRV/arzyL8FrrmKhtQhh85AHZgQdLL8jnXlJ6\n" +
"rYJO9YR5ganTYJoDoO5beH2/5bIxs+VhtCDeLABVMAECgYEA13Gkv2uOFU50qx5V\n" +
"mX9MzAT3v9pyH8hgFaJBmG7uzpXDVCVgF9QqWMtyVdz4MJ+uLFbFBYM/woSNrmwZ\n" +
"zTfDXA/SZyQQaG4x/QXZ318EIGPxDy2s62lJSMPoc11/SN2o9stqMGowntBFTgNb\n" +
"y1Y1npdSO0+MdY4C+0a5oE2GBUECgYEAzhOmZlZqyU2XFFCwFlRdDIlQkm0mgtUz\n" +
"5zjtEOaGCA/8t9yx9R5u9REZqcI7WkLzeyENcsdbOy/iDCirp+O5g3ENGi9eGKtp\n" +
"zuJQ7qgTbDon7dNjqHlzqOgKvU5yoHcTRSqfz6QBFMKbZUYVD0FDYSmerauuGT//\n" +
"v9wO2heu67kCgYAhoF47dlkd4Dn7f2eS5rig22Gj8z9+0HKWzdV5Kk9htSRgnNjL\n" +
"v1TAuThmSHAAftvblct4mcy42qGWiM7aJgr68ok/ifR5qEFrIZ+o6palS5QTb2ie\n" +
"8bb7gYBliUFVqSs3Ifa4Ccr+7rjyfTm1mgYSc8Hk+fyNWJYEjDxq1c7GQQKBgQCj\n" +
"Slq+GJfBLuQZyt3cs7iPaHcZr7emT/4yp57hl2h5FwHvRscULatKMOSe6TNSkF6S\n" +
"IFyhqGoX+hcp/0gVXpLvHjN9ni73aUwMDLSIh1HsniBpiOkc5C/LlSJ9Yp3dnLz+\n" +
"P4omZBQfOR0dIG0ri1EyumHrx2/KvjWO93YlRkLqsQKBgDQ0iwHAPXWLPltCIeqr\n" +
"Ry0quo5Kh0yOM4bM2q2jxCAO7mVgdDGeu9iOTZS1VdCKbLy9La9jftll3FrPvLXM\n" +
"eakMEjK7qlQfZKP3sq76bM7UpcFVmUVCjv4tPCKMoROx+4kTEXyRaEtfo2JSN3CH\n" +
"7ljBSpmgSUKnHxdDyjkeqfmx\n" +
"-----END PRIVATE KEY-----\n");
}
}

View File

@@ -0,0 +1,102 @@
package com.deepinnet.tptradecore.core.service.order;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.common.service.integration.config.TpWechatPayConfig;
import com.ijpay.core.kit.WxPayKit;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import java.io.*;
/**
* @author amos wong
* @create 2023/11/17 14:43
* @Description
*/
@SpringBootTest
@ActiveProfiles("local")
public class VerifySignatureAndDecryptTest {
@Test
public void testVerifySignature() throws Exception {
TpWechatPayConfig wechatPayConfig = getWechatPayConfig();
String serialNo = "30784F90AEF14CB3EE383094878F6247AA3747D7";
String encryptData = "{\"id\":\"16d4f48a-302a-5d9b-8091-d7c64e10a5fb\",\"create_time\":\"2023-11-17T14:57:03+08:00\",\"resource_type\":\"encrypt-resource\",\"event_type\":\"TRANSACTION.SUCCESS\",\"summary\":\"支付成功\",\"resource\":{\"original_type\":\"transaction\",\"algorithm\":\"AEAD_AES_256_GCM\",\"ciphertext\":\"cB3g4Etq2gz55524dOh20fK6LV0ZQ2a1jVsA7Jzi9URrP6jd7OD04loIqNh7M93ZPQSBVGtblAIbAZGj1dMAM0wT6V25tRepJTf07URdJz1Zqdq7Bb5MjIh3vP1TcgoC+4cm3AWxOOpMdK16v9U5yphm145wPYTmEZGfwhnSgljN6xGQFcnalMrbPXo2AC4WFx5aV4ouiXrkc3zBmV1jbxQyZN16BOMER1fHPQ1bIRHyxM8jR+iisDiIGt3itRCCXPa6L8XOMdz9qorEQj41QojIsaOj5SRb4r0ywiN068zExx69OR7YaVrjAA8xManAG4ILAaQY43stImW6WzKmWPUUbOI3Rmhlhs+2B9TsBARz9l3gYp077hv0ufmQ9mbyML/ahWwZ2ppxHs0E9LYVY07GCKMBM2sbzWYp+PbMHkfde92dNistHzhcWIki5QI7i7Nkss0ELK++zHBw9Yft/cddN1NH3uEgtKPQOQobgOwniKcS/5P0Wqasrw6nEnOoawlCUGuyCTg5MmMizNVXIqcT02/zj7v/Ptn7BwsC1MWE91evq42rcO/nGeT8FwPgF14vtwh/iMeiFNM7Xwkfrbzfp9mfExNvHSud0v6mQOH/IA==\",\"associated_data\":\"transaction\",\"nonce\":\"iV2lnWPDXilJ\"}}";
String signature = "Rlw4HJHHtCBjLyhHZ/UEbI3zF1PeF+GYhyHe87L6+GYOqk/cXSSMSah7J/pIRbfDOZtf6RAf0e2boQqmuISBxAuhloDu5AtdfOaN7rRcDiSmr2XrbIR5bsYxMDHFdB0HBayQ/yIJ/QaWb9RGaiJbs8gxkCg5FyQ7lP2i0EJrMC3USi0t8MoP7ku4N3luHOUQS+Pf6x3GNfPBRIbdc0TKMpTQslHcdkxirS5m48p5InmiPlT4gskOOcTQL0E/Qp56DBSxkLwMk8vmZAJB1EpumgI/d/olkFiVnJzoYuFe28PZ75bNtKpQ2ThERVuyEKX58Qd+rFaLEhOtovhdHACVbQ=";
String nonce = "SsnDazxpxAPXnyFMe5kBwHk82rYJ4Cfa";
String timestamp = "1700204223";
InputStream certInputStream = new ByteArrayInputStream(wechatPayConfig.getCertificate().getBytes());
LogUtil.info("certificate:{}, apiV3Key:{}, certInputStream:{}", wechatPayConfig.getCertificate(), wechatPayConfig.getApiKey(), certInputStream);
String plainText = WxPayKit.verifyNotify(serialNo, encryptData, signature, nonce, timestamp,
wechatPayConfig.getApiKey(), certInputStream);
System.out.println(plainText);
}
private TpWechatPayConfig getWechatPayConfig() {
TpWechatPayConfig wechatPayConfig = new TpWechatPayConfig();
wechatPayConfig.setAppId("wx63bcbd1ee3143658");
wechatPayConfig.setMchId("1658735192");
//wechatPayConfig.setPayNotifyUrl("https://test.deepinnet.com/tptradecore/wechat/pay/callback");
wechatPayConfig.setPayNotifyUrl("https://deepinnet-callback.vip.cpolar.cn/wechat/pay/callback");
wechatPayConfig.setRefundNotifyUrl("https://deepinnet-callback.vip.cpolar.cn/wechat/refund/callback");
wechatPayConfig.setSerialNo("1145A15B95F7A3B3F2888DCFA94BC71474C68B50");
wechatPayConfig.setPlatSerialNo("30784F90AEF14CB3EE383094878F6247AA3747D7");
wechatPayConfig.setApiKey("Shenduzhilian168188Shenduzhilian");
wechatPayConfig.setCertificate("-----BEGIN CERTIFICATE-----\n" +
"MIIEFDCCAvygAwIBAgIUMHhPkK7xTLPuODCUh49iR6o3R9cwDQYJKoZIhvcNAQEL\n" +
"BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT\n" +
"FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg\n" +
"Q0EwHhcNMjMxMTA3MDkxMTI1WhcNMjgxMTA1MDkxMTI1WjBuMRgwFgYDVQQDDA9U\n" +
"ZW5wYXkuY29tIHNpZ24xEzARBgNVBAoMClRlbnBheS5jb20xHTAbBgNVBAsMFFRl\n" +
"bnBheS5jb20gQ0EgQ2VudGVyMQswCQYDVQQGDAJDTjERMA8GA1UEBwwIU2hlblpo\n" +
"ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzuI4U+RVrlRQ3pVRH\n" +
"Uy4Q9/pPS8KmKgZ/PqTHYLRR4JTibYXg+RTUvY4nC8gLwX8IaE72Nbiv3COXfPk8\n" +
"8DlRnVEvqneZ9q2sTdcCCbMApkylnhpR25+x5Cha/uJDC5o54ThXPQngCtoWZSzV\n" +
"LI60WIB1ti3uQQVg2AVcPz1fxJLxs06Hjn+Qkq3O0GyxnQndKJI0LVwFyVKkXLsm\n" +
"3hD6YhN5pP/7mx8OznMLH01FatSQyJIqWSXLUN8zfkhdLDYBcnvG7MZNkKiRLcDN\n" +
"7UgymalAVAlUw4jLkOIehOlY1boM4aTMhzYX4R22OgIcnL8wGyLzhjNNmY7HNwZY\n" +
"XK6rAgMBAAGjgbkwgbYwCQYDVR0TBAIwADALBgNVHQ8EBAMCA/gwgZsGA1UdHwSB\n" +
"kzCBkDCBjaCBiqCBh4aBhGh0dHA6Ly9ldmNhLml0cnVzLmNvbS5jbi9wdWJsaWMv\n" +
"aXRydXNjcmw/Q0E9MUJENDIyMEU1MERCQzA0QjA2QUQzOTc1NDk4NDZDMDFDM0U4\n" +
"RUJEMiZzZz1IQUNDNDcxQjY1NDIyRTEyQjI3QTlEMzNBODdBRDFDREY1OTI2RTE0\n" +
"MDM3MTANBgkqhkiG9w0BAQsFAAOCAQEAXlmlrufIMaYwj3Hc4oKRQIIs18kxTArz\n" +
"1m6Wrri8OX0gq2A3rsWmyejWKlJ+kEEwiREbOqm25y2OktQZwoSZvcyliwGltBQ6\n" +
"F3jvybnq4hcfFtFZQVSLSeyxEnaRbFnzKkNI7E7UJCSa+CgQWXdDgCCOM3AiEN7C\n" +
"sLmsdDpPszUpTAXrf/27WDJb1xGnLYhYH+rW/grN39RjazDE2MPXQ4xPC+mLSv34\n" +
"qONxX4UxhDij+wlvU8KpcH1rHiE/mZNQdN0nouq/l+5tSBfVREIWqXTsOumA8qyk\n" +
"2GruLEwUiwL3Ffo04dcmp9SVFIQTAMju/T4QgkXFJI9cy167wdCqWg==\n" +
"-----END CERTIFICATE-----");
wechatPayConfig.setPrivateKey("-----BEGIN PRIVATE KEY-----\n" +
"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtbfwLE5cgg78z\n" +
"9f4lqkfD+AfhHqKM0Q173HcEmWYof6b6SvhcqxVCvEj3UAyh6Aq6Cf/aoFighMxv\n" +
"MnbKXi+WWSfWHwZA9BY7gjP/jnlH6ihlKJgecn7N8jeLAuc23R9LSocn7hNFklEh\n" +
"C9SUV2gmej42n0F8bTTMCOb2NqyjhUOq8tnnUzKg98RVyu8YgRMmH1yZiZxUM/1C\n" +
"J6LNCg0qyd4Z4Cs/psVYFDJnE5js2ttORI0ersFpuXpvqCBLlTJ5m4mmTTcY4qe6\n" +
"Ui4WWHtQWcEu4bFsJrXyRYtfFqVAHtTtTI/PFWUhZKv1VagoRqtkIip4EggwJ2+0\n" +
"Dux12nb5AgMBAAECggEBAIbVY4cZC/3zb8vuDFEsOe9Z/oY/UxE31svdc4rX2FzU\n" +
"IfWmI8GoITdpOzFLwwZ9aRmKfKh00XK6zFYHXeOnpke1uQr3w9zr5/0MFXEyS4hl\n" +
"vFIpZVsGmR90mUoyT6CP+ayHnNymc8U7JGgU0okiC48eqw+8cSVToiCfKzFxAHd/\n" +
"9IxB/gSsXXYWKRlhcPcMfjlerl9Wgk5Bxw5Hs2wNTf3QzM5FKbmuJp6cHR7YSxIX\n" +
"tv2aZCcd1qIzXD3IzF7wClHnnnEPRV/arzyL8FrrmKhtQhh85AHZgQdLL8jnXlJ6\n" +
"rYJO9YR5ganTYJoDoO5beH2/5bIxs+VhtCDeLABVMAECgYEA13Gkv2uOFU50qx5V\n" +
"mX9MzAT3v9pyH8hgFaJBmG7uzpXDVCVgF9QqWMtyVdz4MJ+uLFbFBYM/woSNrmwZ\n" +
"zTfDXA/SZyQQaG4x/QXZ318EIGPxDy2s62lJSMPoc11/SN2o9stqMGowntBFTgNb\n" +
"y1Y1npdSO0+MdY4C+0a5oE2GBUECgYEAzhOmZlZqyU2XFFCwFlRdDIlQkm0mgtUz\n" +
"5zjtEOaGCA/8t9yx9R5u9REZqcI7WkLzeyENcsdbOy/iDCirp+O5g3ENGi9eGKtp\n" +
"zuJQ7qgTbDon7dNjqHlzqOgKvU5yoHcTRSqfz6QBFMKbZUYVD0FDYSmerauuGT//\n" +
"v9wO2heu67kCgYAhoF47dlkd4Dn7f2eS5rig22Gj8z9+0HKWzdV5Kk9htSRgnNjL\n" +
"v1TAuThmSHAAftvblct4mcy42qGWiM7aJgr68ok/ifR5qEFrIZ+o6palS5QTb2ie\n" +
"8bb7gYBliUFVqSs3Ifa4Ccr+7rjyfTm1mgYSc8Hk+fyNWJYEjDxq1c7GQQKBgQCj\n" +
"Slq+GJfBLuQZyt3cs7iPaHcZr7emT/4yp57hl2h5FwHvRscULatKMOSe6TNSkF6S\n" +
"IFyhqGoX+hcp/0gVXpLvHjN9ni73aUwMDLSIh1HsniBpiOkc5C/LlSJ9Yp3dnLz+\n" +
"P4omZBQfOR0dIG0ri1EyumHrx2/KvjWO93YlRkLqsQKBgDQ0iwHAPXWLPltCIeqr\n" +
"Ry0quo5Kh0yOM4bM2q2jxCAO7mVgdDGeu9iOTZS1VdCKbLy9La9jftll3FrPvLXM\n" +
"eakMEjK7qlQfZKP3sq76bM7UpcFVmUVCjv4tPCKMoROx+4kTEXyRaEtfo2JSN3CH\n" +
"7ljBSpmgSUKnHxdDyjkeqfmx\n" +
"-----END PRIVATE KEY-----\n");
return wechatPayConfig;
}
}

View File

@@ -0,0 +1,420 @@
package com.deepinnet.tptradecore.core.service.trans.impl;
import cn.hutool.core.bean.BeanUtil;
import com.deepinnet.tptradecore.common.dal.condition.trans.UpdatePayOrderCondition;
import com.deepinnet.tptradecore.common.dal.repository.trans.TpBillRepository;
import com.deepinnet.tptradecore.common.dal.repository.trans.TpChargeRepository;
import com.deepinnet.tptradecore.common.dal.repository.trans.TpFinancialAccountRepository;
import com.deepinnet.tptradecore.common.dal.repository.trans.TpPayOrderRepository;
import com.deepinnet.tptradecore.common.dto.trans.*;
import com.deepinnet.tptradecore.common.enums.trans.TpPayOrderStatusEnum;
import com.deepinnet.tptradecore.common.enums.trans.TpPayTypeEnum;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.common.service.integration.dto.TpPayResultDTO;
import com.deepinnet.tptradecore.common.service.integration.dto.TpRefundResultDTO;
import com.deepinnet.tptradecore.common.service.integration.strategy.AlipayStrategy;
import com.deepinnet.tptradecore.common.service.integration.strategy.PayStrategy;
import com.deepinnet.tptradecore.core.model.trans.TpBill;
import com.deepinnet.tptradecore.core.model.trans.TpCharge;
import com.deepinnet.tptradecore.core.model.trans.TpFinancialAccount;
import com.deepinnet.tptradecore.core.model.trans.TpPayOrder;
import com.google.common.collect.Lists;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.*;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
/**
* Creator zengjuerui
* Date 2023-12-28
**/
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
public class TpPayOrderDomainServiceImplTest {
@InjectMocks
private TpPayOrderDomainServiceImpl tpPayOrderDomainService;
@Mock
private TpPayOrderRepository payOrderRepository;
@Mock
private TpBillRepository billRepository;
@Mock
private TpChargeRepository chargeRepository;
@Mock
private TpFinancialAccountRepository financialAccountRepository;
@Spy
private TransactionTemplate tpTransactionTemplate;
@Mock
private PlatformTransactionManager platformTransactionManager;
@Mock
private Map<String, PayStrategy> payStrategyMap;
@BeforeEach
public void setUp() {
tpTransactionTemplate = new TransactionTemplate(platformTransactionManager);
tpPayOrderDomainService = new TpPayOrderDomainServiceImpl();
MockitoAnnotations.openMocks(this);
}
@Test
public void testCreatePayOrder() {
TpPayOrder payOrder = mock(TpPayOrder.class);
TpBill tpBill = new TpBill();
TpFinancialAccount payeeAccount = new TpFinancialAccount();
TpFinancialAccount payerAccount = new TpFinancialAccount();
TpCharge tpCharge = new TpCharge();
when(payOrder.getTpBill()).thenReturn(tpBill);
when(payOrder.getPayeeAccount()).thenReturn(payeeAccount);
when(payOrder.getPayerAccount()).thenReturn(payerAccount);
when(payOrder.getTpCharge()).thenReturn(tpCharge);
tpPayOrderDomainService.createPayOrder(payOrder);
verify(payOrderRepository).save(payOrder);
verify(billRepository).save(tpBill);
verify(financialAccountRepository).batchSave(Lists.newArrayList(payeeAccount, payerAccount));
verify(chargeRepository).save(tpCharge);
}
@Test
public void testQueryPayResult() {
TpQueryPayResultDTO queryPayResultDTO = mock(TpQueryPayResultDTO.class);
TpPayOrder payOrder = mock(TpPayOrder.class);
TpPayOrder payOrder1 = mock(TpPayOrder.class);
when(payOrderRepository.listPayOrderByCondition(any())).thenReturn(Lists.newArrayList(payOrder, payOrder1));
when(payOrder.getStatus()).thenReturn(TpPayOrderStatusEnum.PAID.getCode());
when(payOrder1.getStatus()).thenReturn(TpPayOrderStatusEnum.PAID.getCode());
mockListPayResult();
assertThrows(TpTradeCoreException.class, () -> tpPayOrderDomainService.queryPayResult(queryPayResultDTO));
}
@Test
public void testQueryPayResult1() {
TpQueryPayResultDTO queryPayResultDTO = mock(TpQueryPayResultDTO.class);
TpPayOrder payOrder = mock(TpPayOrder.class);
TpPayOrder payOrder1 = mock(TpPayOrder.class);
MockedStatic<BeanUtil> beanUtilMockedStatic = Mockito.mockStatic(BeanUtil.class);
beanUtilMockedStatic.when(() -> BeanUtil.copyProperties(queryPayResultDTO, TpPayOrderQueryDTO.class)).thenReturn(new TpPayOrderQueryDTO());
when(payOrderRepository.listPayOrderByCondition(any())).thenReturn(Lists.newArrayList(payOrder, payOrder1));
when(payOrder.getStatus()).thenReturn(TpPayOrderStatusEnum.PAID.getCode());
when(payOrder1.getStatus()).thenReturn(TpPayOrderStatusEnum.PAYING.getCode());
mockListPayResult();
TpPayResultDTO except = mock(TpPayResultDTO.class);
beanUtilMockedStatic.when(() -> BeanUtil.copyProperties(payOrder, TpPayResultDTO.class))
.thenReturn(except);
TpPayResultDTO actual = tpPayOrderDomainService.queryPayResult(queryPayResultDTO);
assertEquals(except, actual);
verify(except).setPaySuccess(true);
}
@Test
public void testQueryPayResult2() {
TpQueryPayResultDTO queryPayResultDTO = mock(TpQueryPayResultDTO.class);
TpPayOrder payOrder = mock(TpPayOrder.class);
TpPayOrder payOrder1 = mock(TpPayOrder.class);
when(payOrderRepository.listPayOrderByCondition(any())).thenReturn(Lists.newArrayList(payOrder, payOrder1));
when(payOrder.getStatus()).thenReturn(TpPayOrderStatusEnum.REFUND.getCode());
when(payOrder1.getStatus()).thenReturn(TpPayOrderStatusEnum.REFUND.getCode());
mockListPayResult();
assertThrows(TpTradeCoreException.class, () -> tpPayOrderDomainService.queryPayResult(queryPayResultDTO));
}
@Test
public void testQueryPayResult3() {
TpQueryPayResultDTO queryPayResultDTO = mock(TpQueryPayResultDTO.class);
TpPayOrder payOrder = mock(TpPayOrder.class);
TpPayOrder payOrder1 = mock(TpPayOrder.class);
when(payOrderRepository.listPayOrderByCondition(any())).thenReturn(Lists.newArrayList(payOrder, payOrder1));
when(payOrder.getStatus()).thenReturn(TpPayOrderStatusEnum.PAYING.getCode());
when(payOrder1.getStatus()).thenReturn(TpPayOrderStatusEnum.PAYING.getCode());
mockListPayResult();
assertThrows(TpTradeCoreException.class, () -> tpPayOrderDomainService.queryPayResult(queryPayResultDTO));
}
@Test
public void testQueryPayResult4() {
TpQueryPayResultDTO queryPayResultDTO = mock(TpQueryPayResultDTO.class);
TpPayOrder payOrder = mock(TpPayOrder.class);
TpPayOrder payOrder1 = mock(TpPayOrder.class);
when(payOrderRepository.listPayOrderByCondition(any())).thenReturn(Lists.newArrayList(payOrder, payOrder1));
when(payOrder.getStatus()).thenReturn(TpPayOrderStatusEnum.PAYING.getCode());
when(payOrder.getPayType()).thenReturn(TpPayTypeEnum.ALIPAY.getCode());
when(payOrder1.getStatus()).thenReturn(TpPayOrderStatusEnum.REFUND.getCode());
mockListPayResult();
AlipayStrategy alipayStrategy = mock(AlipayStrategy.class);
when(payStrategyMap.values()).thenReturn(Lists.newArrayList(alipayStrategy));
when(alipayStrategy.getPayType()).thenReturn(TpPayTypeEnum.ALIPAY);
tpPayOrderDomainService.afterPropertiesSet();
TpPayResultDTO except = mock(TpPayResultDTO.class);
when(alipayStrategy.queryPayResult(any())).thenReturn(except);
when(payOrder.getPayeeAccount()).thenReturn(new TpFinancialAccount());
when(except.isPaySuccess()).thenReturn(true);
TpPayResultDTO actual = tpPayOrderDomainService.queryPayResult(queryPayResultDTO);
assertEquals(except, actual);
verify(payOrderRepository).updatePayOrderByCondition(any());
verify(billRepository).updateByCondition(any());
}
@Test
public void testQueryRefundResult() {
TpQueryRefundResultDTO queryRefundResultDTO = mock(TpQueryRefundResultDTO.class);
TpPayOrder payOrder = mock(TpPayOrder.class);
TpPayOrder payOrder1 = mock(TpPayOrder.class);
when(payOrderRepository.listPayOrderByCondition(any())).thenReturn(Lists.newArrayList(payOrder, payOrder1));
when(payOrder.getStatus()).thenReturn(TpPayOrderStatusEnum.REFUND.getCode());
when(payOrder1.getStatus()).thenReturn(TpPayOrderStatusEnum.REFUND.getCode());
mockListPayResult();
assertThrows(TpTradeCoreException.class, () -> tpPayOrderDomainService.queryRefundResult(queryRefundResultDTO));
}
@Test
public void testQueryRefundResult1() {
TpQueryRefundResultDTO queryRefundResultDTO = mock(TpQueryRefundResultDTO.class);
TpPayOrder payOrder = mock(TpPayOrder.class);
TpPayOrder payOrder1 = mock(TpPayOrder.class);
MockedStatic<BeanUtil> beanUtilMockedStatic = Mockito.mockStatic(BeanUtil.class);
beanUtilMockedStatic.when(() -> BeanUtil.copyProperties(queryRefundResultDTO, TpRefundResultDTO.class)).thenReturn(new TpPayOrderQueryDTO());
when(payOrderRepository.listPayOrderByCondition(any())).thenReturn(Lists.newArrayList(payOrder, payOrder1));
when(payOrder.getStatus()).thenReturn(TpPayOrderStatusEnum.REFUND.getCode());
when(payOrder1.getStatus()).thenReturn(TpPayOrderStatusEnum.REFUNDING.getCode());
mockListPayResult();
TpRefundResultDTO except = mock(TpRefundResultDTO.class);
beanUtilMockedStatic.when(() -> BeanUtil.copyProperties(payOrder, TpRefundResultDTO.class))
.thenReturn(except);
TpRefundResultDTO actual = tpPayOrderDomainService.queryRefundResult(queryRefundResultDTO);
assertEquals(except, actual);
verify(except).setSuccess(true);
}
@Test
public void testQueryRefundResult2() {
TpQueryRefundResultDTO queryRefundResultDTO = mock(TpQueryRefundResultDTO.class);
TpPayOrder payOrder = mock(TpPayOrder.class);
TpPayOrder payOrder1 = mock(TpPayOrder.class);
when(payOrderRepository.listPayOrderByCondition(any())).thenReturn(Lists.newArrayList(payOrder, payOrder1));
when(payOrder.getStatus()).thenReturn(TpPayOrderStatusEnum.PAID.getCode());
when(payOrder1.getStatus()).thenReturn(TpPayOrderStatusEnum.PAID.getCode());
mockListPayResult();
assertThrows(TpTradeCoreException.class, () -> tpPayOrderDomainService.queryRefundResult(queryRefundResultDTO));
}
@Test
public void testQueryRefundResult3() {
TpQueryRefundResultDTO queryRefundResultDTO = mock(TpQueryRefundResultDTO.class);
TpPayOrder payOrder = mock(TpPayOrder.class);
TpPayOrder payOrder1 = mock(TpPayOrder.class);
when(payOrderRepository.listPayOrderByCondition(any())).thenReturn(Lists.newArrayList(payOrder, payOrder1));
when(payOrder.getStatus()).thenReturn(TpPayOrderStatusEnum.REFUNDING.getCode());
when(payOrder1.getStatus()).thenReturn(TpPayOrderStatusEnum.REFUNDING.getCode());
mockListPayResult();
assertThrows(TpTradeCoreException.class, () -> tpPayOrderDomainService.queryRefundResult(queryRefundResultDTO));
}
@Test
public void testQueryRefundResult4() {
TpQueryRefundResultDTO queryRefundResultDTO = mock(TpQueryRefundResultDTO.class);
TpPayOrder payOrder = mock(TpPayOrder.class);
TpPayOrder payOrder1 = mock(TpPayOrder.class);
TpPayOrder payOrder3 = mock(TpPayOrder.class);
when(payOrderRepository.listPayOrderByCondition(any()))
.thenReturn(Lists.newArrayList(payOrder, payOrder1))
.thenReturn(Lists.newArrayList(payOrder3));
when(payOrder.getStatus()).thenReturn(TpPayOrderStatusEnum.REFUNDING.getCode());
when(payOrder.getPayType()).thenReturn(TpPayTypeEnum.ALIPAY.getCode());
when(payOrder1.getStatus()).thenReturn(TpPayOrderStatusEnum.PAID.getCode());
mockListPayResult();
AlipayStrategy alipayStrategy = mock(AlipayStrategy.class);
when(payStrategyMap.values()).thenReturn(Lists.newArrayList(alipayStrategy));
when(alipayStrategy.getPayType()).thenReturn(TpPayTypeEnum.ALIPAY);
tpPayOrderDomainService.afterPropertiesSet();
TpRefundResultDTO except = mock(TpRefundResultDTO.class);
when(alipayStrategy.queryRefundResult(any())).thenReturn(except);
when(payOrder.getPayerAccount()).thenReturn(new TpFinancialAccount());
when(except.isSuccess()).thenReturn(true);
when(payOrderRepository.getByCondition(any())).thenReturn(new TpPayOrder());
when(chargeRepository.queryByCondition(any())).thenReturn(new TpCharge());
TpRefundResultDTO actual = tpPayOrderDomainService.queryRefundResult(queryRefundResultDTO);
assertEquals(except, actual);
verify(payOrderRepository).updatePayOrderByCondition(any());
verify(billRepository).updateByCondition(any());
verify(chargeRepository).updateByCondition(any());
}
@Test
public void testQueryPayOrderList() {
TpPayOrderQueryDTO queryDTO = mock(TpPayOrderQueryDTO.class);
TpPayOrder payOrder = mock(TpPayOrder.class);
when(payOrder.getPayOrderNo()).thenReturn("pon");
when(payOrder.getTenantId()).thenReturn("ti");
List<TpPayOrder> except = Lists.newArrayList(payOrder);
when(payOrderRepository.listPayOrderByCondition(any())).thenReturn(except);
mockListPayResult();
List<TpPayOrder> actual = tpPayOrderDomainService.queryPayOrderList(queryDTO);
assertEquals(except, actual);
}
@Test
public void testClosePayOrder() {
TpPayOrderCloseDTO closeDTO = mock(TpPayOrderCloseDTO.class);
UpdatePayOrderCondition updateCondition = mock(UpdatePayOrderCondition.class);
mockStatic(BeanUtil.class)
.when(() -> BeanUtil.copyProperties(closeDTO, UpdatePayOrderCondition.class))
.thenReturn(updateCondition);
when(payOrderRepository.updatePayOrderByCondition(any())).thenReturn(true);
Boolean actual = tpPayOrderDomainService.closePayOrder(closeDTO);
assertTrue(actual);
}
@Test
public void testUpdatePayOrder() {
TpPayOrderUpdateDTO updateDTO = mock(TpPayOrderUpdateDTO.class);
mockStatic(BeanUtil.class)
.when(() -> BeanUtil.copyProperties(updateDTO, UpdatePayOrderCondition.class))
.thenReturn(new UpdatePayOrderCondition());
when(payOrderRepository.updatePayOrderByCondition(any())).thenReturn(true);
assertTrue(tpPayOrderDomainService.updatePayOrder(updateDTO));
}
@Test
public void testPaySuccess() {
TpPaySuccessDTO successDTO = mock(TpPaySuccessDTO.class);
assertTrue(tpPayOrderDomainService.paySuccess(successDTO));
verify(payOrderRepository).updatePayOrderByCondition(any());
verify(billRepository).updateByCondition(any());
}
@Test
public void testRefundSuccess() {
when(payOrderRepository.getByCondition(any())).thenReturn(null);
assertThrows(TpTradeCoreException.class, () -> tpPayOrderDomainService.refundSuccess(new TpRefundSuccessDTO()));
}
@Test
public void testRefundSuccess1() {
when(payOrderRepository.getByCondition(any())).thenReturn(new TpPayOrder());
when(chargeRepository.queryByCondition(any())).thenReturn(null);
assertTrue(tpPayOrderDomainService.refundSuccess(new TpRefundSuccessDTO()));
verify(payOrderRepository).updatePayOrderByCondition(any());
verify(billRepository).updateByCondition(any());
verify(chargeRepository, never()).updateByCondition(any());
}
@Test
public void testRefundSuccess2() {
when(payOrderRepository.getByCondition(any())).thenReturn(new TpPayOrder());
when(chargeRepository.queryByCondition(any())).thenReturn(new TpCharge());
assertTrue(tpPayOrderDomainService.refundSuccess(new TpRefundSuccessDTO()));
verify(payOrderRepository).updatePayOrderByCondition(any());
verify(billRepository).updateByCondition(any());
verify(chargeRepository).updateByCondition(any());
}
private void mockListPayResult() {
TpBill tpBill = mock(TpBill.class);
when(billRepository.listByPayOrderNos(anyList(), any())).thenReturn(Lists.newArrayList(tpBill));
when(tpBill.getPayOrderNo()).thenReturn("pon");
TpCharge tpCharge = mock(TpCharge.class);
when(chargeRepository.listByPayOrderNos(anyList(), any())).thenReturn(Lists.newArrayList(tpCharge));
when(tpCharge.getPayOrderNo()).thenReturn("pon");
TpFinancialAccount tpFinancialAccount = mock(TpFinancialAccount.class);
when(financialAccountRepository.listByPayOrderNos(anyList(), any())).thenReturn(Lists.newArrayList(tpFinancialAccount));
when(tpFinancialAccount.getBizNo()).thenReturn("bn");
}
}

View File

@@ -0,0 +1,148 @@
{
"productNo": "CXCP001",
"productName": "彪彪专线",
"ticketType": 1,
"productCategoryNo": "001001",
"productCategory": "校园巴士",
"outRequestNo": "1234567890",
"userNo": "USER001",
"orderNo": "ORDER001",
"main": 1,
"type": 1,
"status": 0,
"quotationNo": "Q001",
"payAmount": "15.50",
"originalAmount": "20.00",
"source": 1,
"identityVerificat": 1,
"orderTime": 1690527870000,
"expireTime": 1722150270000,
"tenantId": "test",
"orderElements": [
{
"orderNo": "ORDER001",
"elementType": 1,
"elementCode": "E001",
"elementName": "line",
"elementKey": "BUS",
"elementValue": "386",
"tenantId": "test"
},
{
"orderNo": "ORDER001",
"elementType": 1,
"elementCode": "E002",
"elementName": "lineA",
"elementKey": "BUS",
"elementValue": "386",
"tenantId": "test"
}
],
"orderPriceRecord": [
{
"pricingNo": "PRICE001",
"orderNo": "ORDER001",
"pricingAmount": "20.00",
"pricingType": 1,
"pricingParams": "example json",
"tenantId": "test",
"orderDiscounts": [
{
"pricingNo": "PRICE001",
"orderNo": "ORDER001",
"type": 1,
"discountAmount": "4.50",
"tenantId": "test"
}
]
}
],
"orderPlacer": {
"placerNo": "USER001",
"orderNo": "ORDER001",
"placerName": "juju",
"placerContact": "13140000520",
"tenantId": "test"
},
"orderSubjectItem": [
{
"itemNo": "ITEM001",
"orderNo": "ORDER001",
"passengerNo": "PASSENGER001",
"name": "线路",
"type": 1,
"count": 1,
"tenantId": "test",
"passenger": {
"passengerNo": "PASSENGER001",
"orderNo": "ORDER001",
"passengerType": 1,
"passengerName": "juju",
"passengerContact": "13140000520",
"tenantId": "test"
},
"orderItemElements": [
{
"orderNo": "ORDER001",
"itemNo": "ITEM001",
"elementName": "线路组成要素1",
"elementValue": "386",
"tenantId": "test"
}
]
}
],
"orderTravelTrips": [
{
"tripNo": "TRIP001",
"orderNo": "ORDER001",
"passengerNo": "PASSENGER001",
"pickUpLocationCode": "LOCATION001",
"pickUpLocation": "五常",
"dropOffLocationCode": "LOCATION002",
"dropOffLocation": "西湖",
"startTime": "1693537870000",
"tenantId": "test",
"tripPositions": [
{
"tripNo": "TRIP001",
"locationCode": "LOCATION001",
"locationName": "五常",
"lng": "34.1233",
"lat": "123.33",
"tenantId": "test"
},
{
"tripNo": "TRIP001",
"locationCode": "LOCATION002",
"locationName": "西湖",
"lng": "33.1233",
"lat": "124.33",
"tenantId": "test"
}
]
}
],
"tpOrderTargetService": {
"orderNo": "ORDER001",
"targetName": "深度智联",
"targetNumber": "91330110MABULXQY2F",
"tenantId": "test"
},
"tpOrderRoutes": [
{
"orderNo": "ORDER001",
"routeNo": "ROUTE001",
"routeName": "深度智联定制班车",
"tenantId": "test",
"tpOrderRouteShuttle": {
"orderNo": "ORDER001",
"routeNo": "ROUTE001",
"shuttleNo": "SCHEDULE001",
"shuttleName": "9点班次",
"shuttleTime": "9:00",
"tenantId": "test",
}
}
]
}

View File

@@ -0,0 +1,183 @@
{
"productNo": "CXCP001",
"productCategoryNo": "001001",
"outRequestNo": "1234567890",
"userNo": "USER001",
"orderNo": "ORDER001",
"main": 1,
"type": 1,
"status": 0,
"quotationNo": "Q001",
"payAmount": "15.50",
"originalAmount": "20.00",
"source": 1,
"identityVerificat": 1,
"orderTime": 1690527870000,
"expireTime": 1722150270000,
"tenantId": "test",
"orderElements": [
{
"orderNo": "ORDER001",
"elementType": 1,
"elementCode": "E001",
"elementName": "line",
"elementKey": "BUS",
"elementValue": "386",
"tenantId": "test",
},
{
"orderNo": "ORDER001",
"elementType": 1,
"elementCode": "E002",
"elementName": "lineA",
"elementKey": "BUS",
"elementValue": "386",
"tenantId": "test",
}
],
"orderPriceRecord": [
{
"pricingNo": "PRICE001",
"orderNo": "ORDER001",
"pricingAmount": "20.00",
"pricingType": 1,
"pricingParams": "example json",
"tenantId": "test",
"orderDiscounts": [
{
"pricingNo": "PRICE001",
"orderNo": "ORDER001",
"type": 1,
"discountAmount": "4.50",
"tenantId": "test",
}
]
}
],
"orderPlacer": {
"orderNo": "ORDER001",
"placerName": "juju",
"placerContact": "13140000520",
"tenantId": "test",
},
"tpOrderTargetService": {
"orderNo": "ORDER001",
"targetName": "深度智联",
"targetNumber": "91330110MABULXQY2F",
},
"tpOrderRoutes": [
{
"orderNo": "ORDER001",
"routeNo": "ROUTE001",
"routeName": "深度智联定制班车",
"tenantId": "test",
"tpOrderRouteShuttle": {
"orderNo": "ORDER001",
"routeNo": "ROUTE001",
"scheduleNo": "SCHEDULE001",
"scheduleName": "9点班次",
"scheduleTime": "9:00",
"tenantId": "test"
}
}
],
"subOrders":[
{
"outRequestNo": "1234567890",
"parentOrderNo": "ORDER001",
"productNo": "CXCP001",
"productCategoryNo": "001001",
"userNo": "USER001",
"orderNo": "ORDER002",
"main": 0,
"type": 1,
"status": 0,
"source": 1,
"identityVerificat": 1,
"orderTime": 1690527870000,
"expireTime": 1722150270000,
"tenantId": "test",
"orderSubjectItem": [
{
"itemNo": "ITEM001",
"orderNo": "ORDER002",
"passengerNo": "PASSENGER001",
"name": "线路",
"type": 1,
"count": 1,
"tenantId": "test",
"passenger": {
"passengerNo": "PASSENGER001",
"orderNo": "ORDER002",
"passengerType": 1,
"passengerName": "juju",
"passengerContact": "13140000520",
"tenantId": "test"
},
"orderItemElements": [
{
"orderNo": "ORDER002",
"itemNo": "ITEM001",
"elementName": "线路组成要素1",
"elementValue": "386",
"tenantId": "test"
}
]
}
],
"orderTravelTrips": [
{
"tripNo": "TRIP001",
"orderNo": "ORDER002",
"passengerNo": "PASSENGER001",
"pickUpLocationCode": "LOCATION001",
"pickUpLocation": "五常",
"dropOffLocationCode": "LOCATION002",
"dropOffLocation": "西湖",
"startTime": "1693537870000",
"tenantId": "test",
"tripPositions": [
{
"tripNo": "TRIP001",
"locationCode": "LOCATION001",
"locationName": "五常",
"lng": "34.1233",
"lat": "123.33",
"tenantId": "test"
},
{
"tripNo": "TRIP001",
"locationCode": "LOCATION002",
"locationName": "西湖",
"lng": "33.1233",
"lat": "124.33",
"tenantId": "test"
}
]
}
],
"tpOrderTargetService": {
"orderNo": "ORDER001",
"targetName": "深度智联",
"targetNumber": "91330110MABULXQY2F",
"tenantId": "test"
},
"tpOrderRoutes": [
{
"orderNo": "ORDER001",
"routeNo": "ROUTE001",
"routeName": "深度智联定制班车",
"tenantId": "test",
"tpOrderRouteShuttle": {
"orderNo": "ORDER001",
"routeNo": "ROUTE001",
"shuttleNo": "SCHEDULE001",
"shuttleName": "9点班次",
"shuttleTime": "9:00",
"tenantId": "test"
}
}
]
}
]
}

19
tptradecore-biz/pom.xml Normal file
View File

@@ -0,0 +1,19 @@
<?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.deepinnet</groupId>
<artifactId>tptradecore</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>tptradecore-biz</artifactId>
<packaging>pom</packaging>
<modules>
<module>tptradecore-biz-service-impl</module>
</modules>
</project>

View File

@@ -0,0 +1,98 @@
<?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.deepinnet</groupId>
<artifactId>tptradecore-biz</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>tptradecore-biz-service-impl</artifactId>
<dependencies>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-common-service-integration</artifactId>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-common-service-facade</artifactId>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-common-util</artifactId>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-core-service</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.jsonzou</groupId>
<artifactId>jmockdata</artifactId>
<version>4.3.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.25</version>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.redssion</groupId>
<artifactId>redisson-spring-data-27</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-data-26</artifactId>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-common-service-facade</artifactId>
</dependency>
<dependency>
<groupId>com.deepinnet</groupId>
<artifactId>tptradecore-common-service-facade</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,41 @@
package com.deepinnet.tptradecore.biz.advice;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.log.LogFormatHelper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.*;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class IntegrationClientInterceptor {
private static final Logger INTEGRATION_LOG = LoggerFactory.getLogger("INTEGRATION-LOG");
@Pointcut("execution(* com.deepinnet.*.common.service.integration..*.*(..))")
public void pointCut() {
}
@Around("pointCut()")
public Object integrationClientHandle(ProceedingJoinPoint pj) throws Throwable {
boolean res = true;
Long startTime = System.currentTimeMillis();
String className = pj.getTarget().getClass().getSimpleName();
String methodName = pj.getSignature().getName();
Object proceed;
Throwable ex = null;
try {
proceed = pj.proceed();
return proceed;
} catch (Throwable e) {
res = false;
ex = e;
throw e;
} finally {
LogUtil.info(INTEGRATION_LOG, "{}",
LogFormatHelper.logFormat(startTime, className, methodName, res, ex));
}
}
}

View File

@@ -0,0 +1,78 @@
package com.deepinnet.tptradecore.biz.advice;
import com.deepinnet.tp.common.lang.exception.TpException;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.log.LogFormatHelper;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.*;
import org.springframework.stereotype.Component;
/**
* @author amos wong
* @create 2022-11-14 15:00
* <p>
* 异常处理切面
*/
@Component
@Aspect
public class RpcExceptionHandleAspect {
private static final String TPTRADECORE_CORE_SIMPLE_NAME = "TpTradeCoreException";
private static final Logger REQUEST_LOG = LoggerFactory.getLogger("REQUEST-LOG");
private static final Logger BIZ_DIGEST_LOG = LoggerFactory.getLogger("BIZ-DIGEST-LOG");
@Pointcut(value = "@within(org.apache.dubbo.config.annotation.DubboService)")
private void myPointcut() {
}
@Around(value = "myPointcut()")
private Object around(ProceedingJoinPoint joinPoint) {
Long startTime = System.currentTimeMillis();
String className = joinPoint.getTarget().getClass().getSimpleName();
String methodName = joinPoint.getSignature().getName();
boolean isSuccess = true;
Throwable ex = null;
try {
LogUtil.info(REQUEST_LOG, "{},{},{}", className, methodName, joinPoint.getArgs());
Object proceedResult = joinPoint.proceed();
if (proceedResult instanceof TpResult) {
TpResult result = (TpResult) proceedResult;
if (!result.isSuccess()) {
isSuccess = false;
}
}
return proceedResult;
} catch (Throwable e) {
isSuccess = false;
ex = e;
LogUtil.error("RPC服务调用异常", e);
// 业务异常
if (e instanceof TpTradeCoreException) {
TpTradeCoreException exception = (TpTradeCoreException) e;
// ATTENTION如果是幂等异常需要返回成功但是要带上异常信息
TpTradeCoreErrorCode errorCode = exception.getErrorCode();
if (TpTradeCoreErrorCode.IDEMPOTENT_REQUEST_ERROR == errorCode) {
return new TpResult<>(true, TpTradeCoreErrorCode.IDEMPOTENT_REQUEST_ERROR.getCode(), TpTradeCoreErrorCode.IDEMPOTENT_REQUEST_ERROR.getDesc(), TPTRADECORE_CORE_SIMPLE_NAME);
}
return TpResult.fail(errorCode.getCode(), exception.getMessage(), TPTRADECORE_CORE_SIMPLE_NAME);
} else if (e instanceof IllegalArgumentException) {
return TpResult.fail(TpTradeCoreErrorCode.ILLEGAL_PARAMS.getCode(), TpTradeCoreErrorCode.ILLEGAL_PARAMS.getDesc(), TPTRADECORE_CORE_SIMPLE_NAME);
} else if (e instanceof TpException) {
return TpResult.fail(((TpException) e).getErrorCode(), e.getMessage(), TPTRADECORE_CORE_SIMPLE_NAME);
} else {
// 未知异常
return TpResult.fail(TpTradeCoreErrorCode.INTERNAL_SERVER_ERROR.getCode(), TpTradeCoreErrorCode.INTERNAL_SERVER_ERROR.getDesc(), TPTRADECORE_CORE_SIMPLE_NAME);
}
} finally {
LogUtil.info(BIZ_DIGEST_LOG, "{}", LogFormatHelper.logFormat(startTime, className, methodName, isSuccess, ex));
}
}
}

View File

@@ -0,0 +1,79 @@
package com.deepinnet.tptradecore.biz.config;
import cn.hutool.core.thread.ExecutorBuilder;
import cn.hutool.core.thread.RejectPolicy;
import cn.hutool.core.thread.ThreadFactoryBuilder;
import com.deepinnet.trace.wrapper.ExecutorServiceWrapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
*         ┏┓   ┏┓+ +
*        ┏┛┻━━━┛┻┓ + +
*        ┃       ┃
*        ┃   ━   ┃ ++ + + +
*        ████━████ ┃+
*        ┃       ┃ +
*        ┃   ┻   ┃
*        ┃       ┃ + +
*        ┗━┓    ┏━┛
*          ┃   ┃
*          ┃   ┃ + + + +
*                 Code is far away from bug with the animal protecting
*          ┃   ┃ +     神兽保佑,代码无bug
*          ┃   ┃
*          ┃   ┃  +
*          ┃    ┗━━━┓ + +
*          ┃        ┣┓
*          ┃        ┏┛
*          ┗┓┓┏━┳┓┏┛ + + + +
*           ┃┫┫ ┃┫┫
*           ┗┻┛ ┗┻┛+ + + +
* 线程池配置类
*
* @author 唐国翔
* @since 2023-01-08 星期日
**/
@Configuration
public class ThreadPoolConfig {
public static final int CPU_CORE_NUMBER = Runtime.getRuntime().availableProcessors();
public static final int CORE_POOL_SIZE = CPU_CORE_NUMBER;
public static final String SMS_SEND_POOL_NAME_PREFIX = "sms-send-pool-";
/**
* 扩展查询线程池
*/
@Bean(name = "smsSendPool")
public ExecutorService smsSendPool() {
ThreadPoolExecutor threadPoolExecutor = ExecutorBuilder
.create().setCorePoolSize(CORE_POOL_SIZE)
.setMaxPoolSize(200)
.setThreadFactory(ThreadFactoryBuilder.create().setNamePrefix(SMS_SEND_POOL_NAME_PREFIX).build())
.setHandler(RejectPolicy.CALLER_RUNS.getValue()) //如果达到阻塞队列上限直接由调用线程执行)
.setKeepAliveTime(60, TimeUnit.SECONDS)
.useSynchronousQueue()//不存储阻塞队列直接new线程调用
.build();
//预热核心线程 等待任务提交
threadPoolExecutor.prestartCoreThread();
return ExecutorServiceWrapper.getTtlExecutorService(threadPoolExecutor);
}
@Bean
public ThreadPoolTaskExecutor payRefundThreadPool() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(Runtime.getRuntime().availableProcessors() * 2);
executor.setMaxPoolSize(Runtime.getRuntime().availableProcessors() * 3 + 1);
executor.setKeepAliveSeconds(10);
executor.setQueueCapacity(128);
executor.setThreadNamePrefix("refund-send-task-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
return executor;
}
}

View File

@@ -0,0 +1,98 @@
package com.deepinnet.tptradecore.biz.constants;
/**
* <p>
* 计算公式枚举
* </p>
*
* @author chenjiaju
* @since 2024/2/2
*/
public class TpOrderCalcFormula {
/**
* 行程结束 应退金额(手续费)
*/
public final static String ORDER_END_NEED_REFUND_AMOUNT_WITH_SERVICE_CHARGE = "应退金额=已付金额-订单金额-手续费";
/**
* 行程结束 应退金额(无手续费)
*/
public final static String ORDER_END_NEED_REFUND_AMOUNT_WITHOUT_SERVICE_CHARGE = "应退金额=已付金额-订单金额";
/**
* 取消 退款中 有手续费
*/
public final static String ORDER_CANCEL_REFUNDING_WITH_SERVICE_CHARGE = "应退金额=已付金额-手续费";
/**
* 取消 退款中 无手续费
*/
public final static String ORDER_CANCEL_REFUNDING_WITHOUT_SERVICE_CHARGE = "应退金额=已付金额";
/**
* 行程结束 已退款 实付金额(手续费)
*/
public final static String ORDER_END_REFUNDED_AMOUNT_WITH_SERVICE_CHARGE = "应退金额=已付金额-订单金额-手续费";
/**
* 行程结束 已退款 实付金额(无手续费)
*/
public final static String ORDER_END_REFUNDED_AMOUNT_WITHOUT_SERVICE_CHARGE = "已退金额=已付金额-订单金额";
/**
* 取消 应退(手续费)
*/
public final static String ORDER_CANCEL_NEED_REFUND_AMOUNT_WITH_SERVICE_CHARGE = "应退金额=已付金额-手续费";
/**
* 取消 应退(无手续费)
*/
public final static String ORDER_CANCEL_NEED_REFUND_AMOUNT_WITHOUT_SERVICE_CHARGE = "应退金额=已付金额";
/**
* 取消 已退金额(手续费)
*/
public final static String ORDER_CANCEL_REFUNDED_AMOUNT_WITH_SERVICE_CHARGE = "已退金额=已付金额-手续费";
/**
* 取消 已退金额(无手续费)
*/
public final static String ORDER_CANCEL_REFUNDED_AMOUNT_WITHOUT_SERVICE_CHARGE = "已退金额=已付金额";
/**
* 取消 应付
*/
public final static String ORDER_CANCEL_NEED_PAY_AMOUNT_WITH_SERVICE_CHARGE = "应付金额=手续费-已付金额";
/**
* 取消 实付金额
*/
public final static String ORDER_CANCEL_PAID_AMOUNT_WITH_SERVICE_CHARGE = "实付金额=手续费-已支付订金金额";
/**
* 应付尾款(手续费)
*/
public final static String ORDER_NEED_PAY_BALANCE_AMOUNT_WITH_SERVICE_CHARGE = "应付尾款=订单金额-已付金额+手续费";
/**
* 应付尾款(无手续费)
*/
public final static String ORDER_NEED_PAY_BALANCE_AMOUNT_WITHOUT_SERVICE_CHARGE = "应付尾款=订单金额-已付金额";
/**
* 实付金额(手续费)
*/
public final static String ORDER_ACTUAL_PAID_AMOUNT_WITH_SERVICE_CHARGE = "实付金额=订单金额+手续费";
/**
* 实付金额(无手续费)
*/
public final static String ORDER_ACTUAL_PAID_AMOUNT_WITHOUT_SERVICE_CHARGE = "实付金额=订单金额";
/**
* 订单结束 不退不补 实付金额
*/
public final static String ORDER_ACTUAL_PAID_AMOUNT_WITHOUT_BALANCE_WITHOUT_SERVICE_CHARGE = "实付金额=已支付订金金额";
}

View File

@@ -0,0 +1 @@
package com.deepinnet.tptradecore.biz.constants;

View File

@@ -0,0 +1,38 @@
package com.deepinnet.tptradecore.biz.convert;
import com.deepinnet.tptradecore.common.vo.audit.TpAuditOrderListVO;
import com.deepinnet.tptradecore.common.vo.audit.TpAuditVO;
import com.deepinnet.tptradecore.common.vo.order.TpOrderListVO;
import com.deepinnet.tptradecore.common.vo.order.TpOrderReceivedVO;
import com.deepinnet.tptradecore.core.model.audit.TpAudit;
import com.deepinnet.tptradecore.core.model.audit.TpAuditOrderList;
import org.mapstruct.Mapper;
import org.mapstruct.MappingConstants;
import java.util.List;
/**
* <p>
* 审核单转换器
* </p>
*
* @author xiehuaqiao
* @since 2023/7/26
*/
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
public interface TpAuditBizConverter {
/**
* TpAudit to TpAuditVO
* @param tpAudit model
* @return do
*/
TpAuditVO model2VO(TpAudit tpAudit);
List<TpAuditVO> model2VOList(List<TpAudit> tpAudits);
List<TpAuditOrderListVO> modelList2VOList(List<TpAudit> orderList);
}

View File

@@ -0,0 +1,44 @@
package com.deepinnet.tptradecore.biz.convert;
import com.deepinnet.tptradecore.common.vo.order.TpOrderChangeApplyVO;
import com.deepinnet.tptradecore.common.vo.order.TpOrderChangeItemVO;
import com.deepinnet.tptradecore.common.vo.order.TpOrderDispatchVO;
import com.deepinnet.tptradecore.core.model.order.TpOrderChangeApply;
import com.deepinnet.tptradecore.core.model.order.TpOrderChangeItem;
import org.mapstruct.Mapper;
import org.mapstruct.MappingConstants;
import java.util.List;
/**
* <p>
* 订单变更申请单转换器
* </p>
*
* @author xiehuaqiao
* @since 2023/7/26
*/
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
public interface TpOrderChangeBizConverter {
/**
* TpOrderChangeApply to TpOrderChangeApplyVO
* @param tpOrderChangeApply model
* @return vo
*/
TpOrderChangeApplyVO model2VO(TpOrderChangeApply tpOrderChangeApply);
/**
* TpOrderChangeItem to TpOrderChangeItemVO
* @param tpOrderChangeItem model
* @return vo
*/
TpOrderChangeItemVO model2VO(TpOrderChangeItem tpOrderChangeItem);
List<TpOrderChangeItemVO> model2ItemVOList(List<TpOrderChangeItem> tpOrderChangeItemList);
List<TpOrderChangeApplyVO> model2VOList(List<TpOrderChangeApply> tpOrderChangeApplyList);
}

View File

@@ -0,0 +1,39 @@
package com.deepinnet.tptradecore.biz.convert;
import com.deepinnet.tptradecore.common.vo.order.TpOrderDispatchVO;
import com.deepinnet.tptradecore.common.vo.order.TpOrderReceivedVO;
import com.deepinnet.tptradecore.core.model.order.TpOrderDispatch;
import org.mapstruct.Mapper;
import org.mapstruct.MappingConstants;
import java.util.List;
/**
* <p>
* 订单派单转换器
* </p>
*
* @author xiehuaqiao
* @since 2023/7/26
*/
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
public interface TpOrderDispatchBizConverter {
/**
* TpOrderDispatch to TpOrderDispatchVO
* @param tpOrderDispatch model
* @return do
*/
TpOrderDispatchVO model2VO(TpOrderDispatch tpOrderDispatch);
/**
* TpOrderDispatch to TpOrderDispatchVO
* @param tpOrderDispatchList model
* @return do
*/
List<TpOrderDispatchVO> model2VOList(List<TpOrderDispatch> tpOrderDispatchList);
}

View File

@@ -0,0 +1,30 @@
package com.deepinnet.tptradecore.biz.convert;
import com.deepinnet.tptradecore.common.vo.order.TpOrderReceivedVO;
import com.deepinnet.tptradecore.core.model.order.TpOrderReceived;
import org.mapstruct.Mapper;
import org.mapstruct.MappingConstants;
/**
* <p>
* 订单接单转换器
* </p>
*
* @author xiehuaqiao
* @since 2023/7/26
*/
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
public interface TpOrderReceivedBizConverter {
/**
* TpOrderReceived to TpOrderReceivedVO
* @param tpOrderReceived model
* @return do
*/
TpOrderReceivedVO model2VO(TpOrderReceived tpOrderReceived);
}

View File

@@ -0,0 +1,55 @@
package com.deepinnet.tptradecore.biz.enums;
/**
* <p>
* 枚举
* </p>
*
* @author chenjiaju
* @since 2023/7/26
*/
public enum TpOrderIdentityFlagEnum {
/**
* 实名认证
*/
REAL_NAME_ORDER(1, "实名认证"),
/**
* 非实名认证
*/
NOT_REAL_NAME_ORDER(0, "非实名认证"),
;
/**
* 实名认证标识
*/
private Integer identityFlag;
/**
* 实名认证标识中文描述
*/
private String identityDesc;
TpOrderIdentityFlagEnum(Integer identityFlag, String identityDesc) {
this.identityFlag = identityFlag;
this.identityDesc = identityDesc;
}
public Integer getIdentityFlag() {
return identityFlag;
}
public void setIdentityFlag(Integer identityFlag) {
this.identityFlag = identityFlag;
}
public String getIdentityDesc() {
return identityDesc;
}
public void setIdentityDesc(String identityDesc) {
this.identityDesc = identityDesc;
}
}

View File

@@ -0,0 +1,55 @@
package com.deepinnet.tptradecore.biz.enums;
import cn.hutool.core.util.ObjectUtil;
/**
* <p>
* 订单服务费是否免费
* </p>
*
* @author chenjiaju
* @since 2023/10/30
*/
public enum TpOrderServiceChargeFreeEnum {
FREE(1, "免费"),
NOT_FREE(0, "按规则收取手续费"),
;
private Integer code;
private String desc;
TpOrderServiceChargeFreeEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
public static TpOrderServiceChargeFreeEnum getTripEnumByTripCode(Integer code) {
for (TpOrderServiceChargeFreeEnum bizTypeEnum : TpOrderServiceChargeFreeEnum.values()) {
if (ObjectUtil.equals(bizTypeEnum.getCode(), code)) {
return bizTypeEnum;
}
}
return null;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}

View File

@@ -0,0 +1,34 @@
package com.deepinnet.tptradecore.biz.factory;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* <p>
* 工厂类,用于订单状态推进
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderPushStatusStrategyFactory implements InitializingBean {
@Resource
private Map<String, TpOrderPushStatusStrategy> strategyMap;
public Map<TpOrderPushStatusEnum, TpOrderPushStatusStrategy> orderPushStatusStrategyMap = new ConcurrentHashMap<>();
@Override
public void afterPropertiesSet() throws Exception {
strategyMap.values().parallelStream().forEach(strategy -> orderPushStatusStrategyMap.put(strategy.statusStrategy(), strategy));
}
}

View File

@@ -0,0 +1,42 @@
package com.deepinnet.tptradecore.biz.log;
import com.deepinnet.tp.common.lang.exception.TpException;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
public class LogFormatHelper {
/**
* 日志格式
* [类名,方法名,执行结果,耗时,异常类名,异常码,异常信息]
*/
private static final String LOG_PATTERN = "[%s,%s,%s,%sms,%s,%s,%s]";
/**
* 占位符
*/
private static final String PLACE_HOLDER = "null";
public static String logFormat(Long startTime, String className, String methodName, Boolean isSuccess, Throwable ex) {
Long endTime = System.currentTimeMillis();
if (ex instanceof TpTradeCoreException) {
TpTradeCoreException e = (TpTradeCoreException) ex;
return String.format(LOG_PATTERN,
className, methodName, isSuccess, (endTime - startTime),
ex.getClass().getSimpleName(), e.getErrorCode(), e.getMessage());
} else if (ex instanceof TpException) {
TpException e = (TpException) ex;
return String.format(LOG_PATTERN,
className, methodName, isSuccess, (endTime - startTime),
ex.getClass().getSimpleName(), e.getErrorCode(), e.getMessage());
} else if (ex != null) {
return String.format(LOG_PATTERN,
className, methodName, isSuccess, (endTime - startTime),
ex.getClass().getSimpleName(), PLACE_HOLDER, ex.getMessage() == null ? PLACE_HOLDER : ex.getMessage());
} else {
return String.format(LOG_PATTERN,
className, methodName, isSuccess, (endTime - startTime),
PLACE_HOLDER, PLACE_HOLDER, PLACE_HOLDER);
}
}
}

View File

@@ -0,0 +1,177 @@
package com.deepinnet.tptradecore.biz.quarz;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.alibaba.excel.EasyExcel;
import com.deepinnet.tpcommoncore.common.service.dto.TpStoreQueryDTO;
import com.deepinnet.tpcommoncore.common.service.dto.TpStoreUploadDTO;
import com.deepinnet.tpcommoncore.common.service.enums.TpStoreBizTypeEnum;
import com.deepinnet.tpcommoncore.common.service.enums.TpStoreBucketTypeEnum;
import com.deepinnet.tptradecore.common.service.integration.client.TpGlobalStoreClient;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.mail.MessagingException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Component
@Slf4j
@Profile("pre")
public class OrderStasticsTimer {
@Resource
private TpGlobalStoreClient tpGlobalStoreClient;
@Resource
private javax.sql.DataSource dbDataSource;
@PostConstruct
public void init() {
log.info("======================佛山统计定时任务启动====================");
}
// 每10分钟执行一次
@Scheduled(fixedRate = 10, timeUnit = TimeUnit.MINUTES)
public void sendEmail() throws SQLException, MessagingException {
String SQL = "SELECT\n" +
" FROM_UNIXTIME( verification_time / 1000, '%Y年-%m月-%d日-%H点' ) AS '核销时间',\n" +
" COUNT( 1 ) AS '核销数量',\n" +
" (case WHEN tv.type = 'day' THEN '次票' WHEN tv.type = 'month' THEN '月票' WHEN tv.type = 'term' THEN '学期票' END) as '票类型',\n" +
" (case WHEN tor.round_trip = 'go' THEN '去程' WHEN tor.round_trip = 'back' THEN '返程' END) as '行程类型'\n" +
"FROM\n" +
" tp_voucher_verification_record tvr\n" +
" LEFT JOIN tp_voucher tv ON tvr.voucher_no = tv.voucher_no and tvr.tenant_id = '1648' and tv.tenant_id = '1648'\n" +
" LEFT JOIN tp_order_route tor ON tv.order_no = tor.order_no and tor.tenant_id = '1648' and tv.tenant_id = '1648'\n" +
"GROUP BY\n" +
" FROM_UNIXTIME( verification_time / 1000, '%Y-%m-%d-%H' ),\n" +
" tor.round_trip,\n" +
" tv.type\n" +
"ORDER BY\n" +
" FROM_UNIXTIME( verification_time / 1000, '%Y-%m-%d-%H' ) DESC";
Connection connection = dbDataSource.getConnection();
try {
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(SQL);
// 生成Excel表格
List<ExcelData> list = new ArrayList<>();
while (resultSet.next()) {
ExcelData data = new ExcelData();
data.setUseTime(resultSet.getString("核销时间"));
data.setUseCount(resultSet.getInt("核销数量"));
data.setTicketType(resultSet.getString("票类型"));
data.setTripType(resultSet.getString("行程类型"));
list.add(data);
}
String fileName = "order_foshan.xlsx";
String filePath = generateLocalFilePath(fileName);
EasyExcel.write(filePath, ExcelData.class).sheet("sheet1").doWrite(list);
// 上传OSS
uploadToOss(filePath);
} finally {
connection.close();
}
}
@NotNull
private static String generateLocalFilePath(String fileName) {
return FileUtil.getUserHomePath() + "/" + fileName;
}
protected String uploadToOss(String filePath) {
// 上传【以分钟时间作为key同一分钟内的请求不重复生成文件】
String ossKey = uploadOss(filePath);
// 获取url
String ossDownloadUrl = getOssDownloadUrl(ossKey);
log.info("订单统计结果OSS下载地址" + ossDownloadUrl);
return ossDownloadUrl;
}
/**
* @param localFilePath
* @return
*/
protected String uploadOss(String localFilePath) {
// 上传文件
TpStoreUploadDTO tpStoreUploadDTO = new TpStoreUploadDTO();
tpStoreUploadDTO.setBucketType(TpStoreBucketTypeEnum.PUBLIC_BUCKET.getBucketType());
tpStoreUploadDTO.setBizType(TpStoreBizTypeEnum.OSS_STORE.getBizType());
String ossKey = getOssKey(localFilePath);
tpStoreUploadDTO.setKey(ossKey);
tpStoreUploadDTO.setInputStream(FileUtil.readBytes(localFilePath));
tpGlobalStoreClient.putObject(tpStoreUploadDTO);
return ossKey;
}
protected String getOssKey(String localFilePath) {
return DateUtil.format(LocalDateTime.now(), "yyyyMMddHH") + localFilePath.substring(localFilePath.lastIndexOf("/"));
}
protected String getOssDownloadUrl(String ossKey) {
TpStoreQueryDTO tpStoreQueryDTO = new TpStoreQueryDTO();
tpStoreQueryDTO.setBucketType(TpStoreBucketTypeEnum.PUBLIC_BUCKET.getBucketType());
tpStoreQueryDTO.setKey(ossKey);
return tpGlobalStoreClient.getUrl(tpStoreQueryDTO);
}
}
class ExcelData {
private String useTime;
private int useCount;
private String ticketType;
private String tripType;
public String getUseTime() {
return useTime;
}
public void setUseTime(String useTime) {
this.useTime = useTime;
}
public int getUseCount() {
return useCount;
}
public void setUseCount(int useCount) {
this.useCount = useCount;
}
public String getTicketType() {
return ticketType;
}
public void setTicketType(String ticketType) {
this.ticketType = ticketType;
}
public String getTripType() {
return tripType;
}
public void setTripType(String tripType) {
this.tripType = tripType;
}
}

View File

@@ -0,0 +1,236 @@
package com.deepinnet.tptradecore.biz.service.impl.audit;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.deepinnet.tp.common.lang.page.CommonPage;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.convert.TpAuditBizConverter;
import com.deepinnet.tptradecore.common.dto.audit.*;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.service.facade.audit.TpAuditFacade;
import com.deepinnet.tptradecore.common.vo.audit.TpAuditOrderListVO;
import com.deepinnet.tptradecore.common.vo.audit.TpAuditOrderVO;
import com.deepinnet.tptradecore.common.vo.audit.TpAuditVO;
import com.deepinnet.tptradecore.core.model.audit.TpAudit;
import com.deepinnet.tptradecore.core.model.order.TpBatchQueryOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderChangeApply;
import com.deepinnet.tptradecore.core.model.order.TpOrderDispatch;
import com.deepinnet.tptradecore.core.service.audit.TpAuditDomainService;
import com.deepinnet.tptradecore.core.service.order.TpOrderChangedApplyDomainService;
import com.deepinnet.tptradecore.core.service.order.TpOrderDispatchDomainService;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.dubbo.config.annotation.DubboService;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@DubboService
public class TpAuditFacadeImpl implements TpAuditFacade {
@Resource
private TpAuditBizConverter tpAuditBizConverter;
@Resource
private TpAuditDomainService auditDomainService;
@Resource
private TpOrderChangedApplyDomainService orderChangedDomainService;
@Resource
private TpOrderDispatchDomainService orderDispatchDomainService;
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpResult<TpAuditVO> getAuditDetail(TpAuditQueryDetailDTO tpAuditQueryDetailDTO) {
TpAudit tpAudit = auditDomainService.getAuditDetail(tpAuditQueryDetailDTO);
return TpResult.success(tpAuditBizConverter.model2VO(tpAudit));
}
@Override
public TpResult<TpAuditVO> getLatestAuditDetail(TpAuditLatestDetailDTO auditLatestDetailDTO) {
TpAudit tpAudit = auditDomainService.getLatestAuditDetail(auditLatestDetailDTO);
return TpResult.success(tpAuditBizConverter.model2VO(tpAudit));
}
@Override
public TpResult<List<TpAuditVO>> listAudits(TpAuditListQueryDTO tpAuditListQueryDTO) {
List<TpAudit> tpAudits = auditDomainService.listAudits(tpAuditListQueryDTO);
return TpResult.success(tpAuditBizConverter.model2VOList(tpAudits));
}
@Override
public TpResult<Boolean> createAudit(TpAuditCreatedDTO tpAuditCreatedDTO) {
Boolean createFlag = auditDomainService.createAudit(tpAuditCreatedDTO);
if (createFlag) {
return TpResult.success(createFlag.booleanValue());
}
return TpResult.fail(TpTradeCoreErrorCode.SUBMIT_APPROVAL_ERROR.getCode(), TpTradeCoreErrorCode.SUBMIT_APPROVAL_ERROR.getDesc());
}
@Override
public TpResult<Boolean> confirmAudit(TpAuditApprovedSubmitDTO confirmAuditDTO) {
Boolean createFlag = auditDomainService.submitApproved(confirmAuditDTO);
if (createFlag) {
return TpResult.success(createFlag.booleanValue());
}
return TpResult.fail(TpTradeCoreErrorCode.APPROVAL_ERROR.getCode(), TpTradeCoreErrorCode.APPROVAL_ERROR.getDesc());
}
@Override
public TpResult<CommonPage<TpAuditOrderListVO>> pageOrderAuditList(TpOrderAuditPagedQueryDTO dto) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(dto.getOriginalOrderNo())){
dto.setOriginalOrderNo(dto.getOrderNo());
}
Page<Object> page = PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
List<TpAudit> auditList = auditDomainService.listOrderAudit(buildTpOrderAuditListQuery(dto));
List<TpAuditOrderListVO> auditOrderList = tpAuditBizConverter.modelList2VOList(auditList);
if (CollUtil.isNotEmpty(auditList)) {
String tenantId = dto.getTenantId();
//1. 获取审核单关联订单列表
List<String> originalOrderNoList = listOriginalOrderNo(auditOrderList, tenantId);
if (CollUtil.isNotEmpty(originalOrderNoList)) {
LogUtil.info("originalOrderNoList:" + JSONUtil.toJsonStr(originalOrderNoList));
//2。填充订单信息
fillOrderInfo(auditOrderList, originalOrderNoList, tenantId);
//3.填充组织信息
fillTargetOrg(auditOrderList, originalOrderNoList, tenantId);
}
}
return TpResult.success( buildListPage(page, sortAuditOrderListVOS(auditOrderList)));
}
@Nullable
private List<TpAuditOrderListVO> sortAuditOrderListVOS(List<TpAuditOrderListVO> auditOrderList) {
if(CollUtil.isEmpty(auditOrderList)){
return Collections.EMPTY_LIST;
}
auditOrderList = CollUtil.sort(auditOrderList, new Comparator<TpAuditOrderListVO>() {
@Override
public int compare(TpAuditOrderListVO source, TpAuditOrderListVO target) {
return target.getSubmitTime().compareTo(source.getSubmitTime());
}
});
return auditOrderList;
}
private List<String> listOriginalOrderNo(List<TpAuditOrderListVO> auditOrderList, String tenantId) {
List<String> applyNos = auditOrderList.stream().map(TpAuditOrderListVO::getBizObjectNo).collect(Collectors.toList());
if (CollUtil.isEmpty(applyNos)) {
return CollUtil.newArrayList();
}
List<TpOrderChangeApply> applyList = orderChangedDomainService.listByApplyNos(tenantId, applyNos);
if (CollUtil.isEmpty(applyList)) {
return CollUtil.newArrayList();
}
Map<String, TpOrderChangeApply> applyMap = applyList.stream().collect(Collectors.toMap(TpOrderChangeApply::getApplyNo, Function.identity()));
auditOrderList.stream().forEach(tpAuditOrderListVO -> {
TpOrderChangeApply apply = applyMap.get(tpAuditOrderListVO.getBizObjectNo());
if (apply != null) {
TpAuditOrderVO auditOrder = tpAuditOrderListVO.getAuditOrder();
if (auditOrder == null) {
auditOrder = new TpAuditOrderVO();
}
auditOrder.setOrderNo(apply.getOrderNo());
auditOrder.setOriginalOrderNo(apply.getOriginalOrderNo());
tpAuditOrderListVO.setAuditOrder(auditOrder);
}
});
return applyList.stream().map(TpOrderChangeApply::getOriginalOrderNo).collect(Collectors.toList());
}
private void fillOrderInfo(List<TpAuditOrderListVO> auditOrderList, List<String> originalOrderNoList, String tenantId) {
TpBatchQueryOrder batchQueryOrder = TpBatchQueryOrder.builder().build();
batchQueryOrder.setTenantId(tenantId);
batchQueryOrder.setOriginalOrderNos(originalOrderNoList);
List<TpOrder> tpOrders = tpOrderDomainService.batchQueryListByOriginalOrderNos(batchQueryOrder);
if (CollUtil.isEmpty(tpOrders)) {
return;
}
Map<String, TpOrder> tpOrderMap = tpOrders.stream().collect(Collectors.toMap(TpOrder::getOriginalOrderNo, Function.identity()));
auditOrderList.stream().forEach(tpAuditOrderListVO -> {
TpAuditOrderVO auditOrder = tpAuditOrderListVO.getAuditOrder();
if (auditOrder == null) {
return;
}
TpOrder tpOrder = tpOrderMap.get(auditOrder.getOriginalOrderNo());
if (tpOrder == null) {
return;
}
auditOrder.setPayableAmount(tpOrder.getPayableAmount());
auditOrder.setCharterBusType(tpOrder.getProductCategoryNo());
auditOrder.setCharterBusTypeName(tpOrder.getProductCategory());
auditOrder.setServiceCharge(tpOrder.getServiceCharge());
});
}
private void fillTargetOrg(List<TpAuditOrderListVO> auditOrderList, List<String> originalOrderNoList, String tenantId) {
List<TpOrderDispatch> tpOrderDispatchList = orderDispatchDomainService.listOrderDispatchDetail(tenantId, originalOrderNoList, null);
if (CollUtil.isEmpty(tpOrderDispatchList)) {
return;
}
Map<String, TpOrderDispatch> tpOrderDispatchMap = tpOrderDispatchList.stream().collect(Collectors.toMap(TpOrderDispatch::getOriginalOrderNo, Function.identity()));
auditOrderList.stream().forEach(tpAuditOrderListVO -> {
TpAuditOrderVO auditOrder = tpAuditOrderListVO.getAuditOrder();
if (auditOrder == null) {
return;
}
TpOrderDispatch tpOrderDispatch = tpOrderDispatchMap.get(auditOrder.getOriginalOrderNo());
if (tpOrderDispatch == null) {
return;
}
auditOrder.setOrgNo(tpOrderDispatch.getTargetOrgNo());
auditOrder.setOrgName(tpOrderDispatch.getTargetOrgName());
});
}
private TpOrderAuditListQueryDTO buildTpOrderAuditListQuery(TpOrderAuditPagedQueryDTO dto) {
TpOrderAuditListQueryDTO tpOrderAuditListQueryDTO = new TpOrderAuditListQueryDTO();
tpOrderAuditListQueryDTO.setOrderNo(dto.getOrderNo());
tpOrderAuditListQueryDTO.setOriginalOrderNo(dto.getOriginalOrderNo());
tpOrderAuditListQueryDTO.setAuditTypes(dto.getAuditTypes());
tpOrderAuditListQueryDTO.setAuditStatus(dto.getAuditStatus());
tpOrderAuditListQueryDTO.setCharterBusType(dto.getCharterBusType());
tpOrderAuditListQueryDTO.setOrgCode(dto.getOrgNo());
tpOrderAuditListQueryDTO.setOrgCodes(dto.getOrgCodes());
tpOrderAuditListQueryDTO.setTenantId(dto.getTenantId());
return tpOrderAuditListQueryDTO;
}
@NotNull
private CommonPage<TpAuditOrderListVO> buildListPage(Page<Object> page, List<TpAuditOrderListVO> auditOrderList) {
CommonPage<TpAuditOrderListVO> result = new CommonPage<>();
result.setPageNum(page.getPageNum());
result.setPageSize(page.getPageSize());
result.setTotal(page.getTotal());
result.setList(auditOrderList);
return result;
}
}

View File

@@ -0,0 +1,385 @@
package com.deepinnet.tptradecore.biz.service.impl.contract;
import cn.hutool.json.JSONUtil;
import com.deepinnet.tp.common.lang.constants.GlobalConstants;
import com.deepinnet.tp.common.lang.page.CommonPage;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.common.dal.convert.contract.*;
import com.deepinnet.tptradecore.common.dal.convert.voucher.TpVoucherPassengerMapStructConvert;
import com.deepinnet.tptradecore.common.dto.contract.*;
import com.deepinnet.tptradecore.common.dto.trans.*;
import com.deepinnet.tptradecore.common.dto.voucher.*;
import com.deepinnet.tptradecore.common.enums.TpBizTypeEnum;
import com.deepinnet.tptradecore.common.enums.contract.*;
import com.deepinnet.tptradecore.common.enums.trans.*;
import com.deepinnet.tptradecore.common.enums.voucher.TpVoucherVerifiedResultEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.common.service.facade.contract.TpContractFacade;
import com.deepinnet.tptradecore.common.service.integration.client.*;
import com.deepinnet.tptradecore.common.vo.contract.TpQueryRefundDetailVO;
import com.deepinnet.tptradecore.core.model.contract.*;
import com.deepinnet.tptradecore.core.service.contract.TpContractDomainService;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @author amos wong
* @create 2023/8/9 11:38
* @Description
*/
@DubboService
public class TpContractFacadeImpl implements TpContractFacade {
@Resource
private TpContractDomainService contractDomainService;
@Resource
private TpRefundApplyOrderConvert refundApplyOrderConvert;
@Resource
private TpRefundSubjectItemConvert refundSubjectItemConvert;
@Resource
private TpRefundApplicantConvert refundApplicantConvert;
@Resource
private TpPaymentClient paymentClient;
@Resource
private TpVoucherClient voucherClient;
@Resource
private TpSequenceClient sequenceClient;
@Override
public TpResult<List<TpVoucherDTO>> queryAvailableRefundVoucherList(TpQueryAvailableRefundVoucherDTO queryDTO) {
// 查询凭证信息
TpVoucherQueryDTO voucherQueryDTO = new TpVoucherQueryDTO();
voucherQueryDTO.setTargetStatusList(queryDTO.getAvailableStatusList());
List<TpVoucherDTO> voucherList = voucherClient.getVoucherList(voucherQueryDTO
.setOrderNo(queryDTO.getOrderNo())
.setTenantId(queryDTO.getTenantId())
.setNeedProperties(Lists.newArrayList(TpVoucherNeedPropertiesEnum.PASSENGER.getCode())));
if (CollectionUtils.isEmpty(voucherList)) {
LogUtil.error("不存在可退的凭证,入参:{}", JSONUtil.toJsonStr(queryDTO));
throw new TpTradeCoreException(TpTradeCoreErrorCode.NOT_FOUND_REFUND_AVAILABLE_VOUCHER);
}
Boolean requiredRealName = voucherList.get(0).getRequiredRealName();
// 已乘坐的凭证不允许退票
List<String> curOrderVoucherNos = voucherList.stream()
.map(TpVoucherDTO::getVoucherNo)
.distinct()
.collect(Collectors.toList());
TpVoucherVerificationRecordQueryDTO verificationRecordQueryDTO = new TpVoucherVerificationRecordQueryDTO();
verificationRecordQueryDTO.setVoucherNos(curOrderVoucherNos);
verificationRecordQueryDTO.setTenantId(queryDTO.getTenantId());
List<TpVoucherVerificationRecordDTO> verificationRecordList = voucherClient.getVerificationRecordList(verificationRecordQueryDTO);
List<TpVoucherDTO> availableRefundVoucherList = Lists.newArrayList();
if (CollectionUtils.isNotEmpty(verificationRecordList)) {
List<TpVoucherVerificationRecordDTO> successRecords = verificationRecordList.stream()
.filter(v -> StringUtils.equals(v.getResult(), TpVoucherVerifiedResultEnum.SUCCESS.getCode()))
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(successRecords)) {
List<String> haveVerifiedVoucherNos = successRecords.stream()
.map(TpVoucherVerificationRecordDTO::getVoucherNo)
.distinct()
.collect(Collectors.toList());
// 实名制坐过就不能退了
if (requiredRealName) {
// 过滤出未乘车的凭证
availableRefundVoucherList = voucherList.stream()
.filter(v -> !haveVerifiedVoucherNos.contains(v.getVoucherNo()))
.collect(Collectors.toList());
} else {
// 非实名的多个乘车人只有一张凭证即使核销过也可能可以退,需要判断是否还有剩余次数
availableRefundVoucherList = voucherList.stream().filter(v -> isRefundPassengerCountValid(v, 1)).collect(Collectors.toList());
}
}
} else {
availableRefundVoucherList = voucherList;
}
// 组装结果
return TpResult.success(availableRefundVoucherList);
}
private boolean isRefundPassengerCountValid(TpVoucherDTO voucherDTO, int refundPassengerCount) {
int passengerCount = voucherDTO.getPassengerCount();
int totalCount = voucherDTO.getTotalCount();
int refundCount = voucherDTO.getRefundCount();
int redemptionCount = voucherDTO.getRedemptionCount();
int eachPassengerTotalCount = totalCount / passengerCount;
// 计算最大剩余可退的乘车人数
int divisor = voucherDTO.getRedemptionCount() % eachPassengerTotalCount;
int redemptionPassengerCount = divisor == 0 ? redemptionCount / eachPassengerTotalCount : redemptionCount / eachPassengerTotalCount + 1;
int availableRefundPassengerCount = passengerCount - refundCount / eachPassengerTotalCount - redemptionPassengerCount;
return availableRefundPassengerCount >= refundPassengerCount;
}
@Override
public TpResult<String> refundTicket(TpRefundApplyDTO refundApplyDTO) {
// 幂等校验
idempotentCheck(refundApplyDTO.getOrderNo(), refundApplyDTO.getTenantId());
// 构建退票申请单
String refundApplyOrderNo = sequenceClient.generateRefundApplyOrderNo();
List<TpRefundSubjectItem> refundSubjectItems = convertRefundItemDTOs2Domain(refundApplyOrderNo, refundApplyDTO.getRefundSubjectItems());
TpRefundApplyOrder refundApplyOrder = refundApplyOrderConvert.buildRefundApplyOrder(refundApplyDTO, refundSubjectItems, refundApplyOrderNo);
assembleRefundApplyOrder(refundApplyOrder, refundApplyDTO.getRefundApplicantDTO());
// 持久化退票申请单
contractDomainService.applyTicketRefund(refundApplyOrder);
return TpResult.success(refundApplyOrderNo);
}
private void idempotentCheck(String orderNo, String tenantId) {
List<TpRefundApplyOrder> refundApplyOrderList = contractDomainService.getRefundApplyOrderList(TpQueryRefundApplyOrderDTO.builder()
.orderNo(orderNo)
.tenantId(tenantId)
.build());
if (CollectionUtils.isNotEmpty(refundApplyOrderList)) {
boolean existRefundingApplyOrder = refundApplyOrderList
.stream()
.anyMatch(refundApplyOrder -> StringUtils.equals(TpRefundApplyOrderStatusEnum.REFUNDING.getCode(), refundApplyOrder.getStatus()));
if (existRefundingApplyOrder) {
LogUtil.error("存在在途的退票申请单,不能继续申请,订单号:{}", orderNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.DUPLICATED_REFUNDING_APPLY_ORDER);
}
}
}
private TpRefundApplyOrder assembleRefundApplyOrder(TpRefundApplyOrder refundApplyOrder, TpRefundApplicantDTO refundApplicantDTO) {
TpRefundApplicant refundApplicant = refundApplicantConvert.convertDTO2Domain(refundApplicantDTO);
refundApplicant.setRefundApplyOrderNo(refundApplyOrder.getRefundApplyOrderNo());
refundApplicant.setTenantId(refundApplyOrder.getTenantId());
refundApplyOrder.setRefundApplicant(refundApplicant);
return refundApplyOrder;
}
@Override
public TpResult<Boolean> refundTicketSuccess(TpRefundTicketSuccessDTO refundTicketSuccessDTO) {
String refundApplyOrderNo = refundTicketSuccessDTO.getRefundApplyOrderNo();
String tenantId = refundTicketSuccessDTO.getTenantId();
List<TpRefundApplyOrder> refundApplyOrderList = contractDomainService.getRefundApplyOrderList(TpQueryRefundApplyOrderDTO.builder().refundApplyOrderNo(refundApplyOrderNo).tenantId(tenantId).build());
if (CollectionUtils.isEmpty(refundApplyOrderList)) {
LogUtil.error("退票申请单不存在,退票申请单号为:{}", refundApplyOrderNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.NOT_FOUND_REFUND_APPLY_ORDER);
}
if (refundApplyOrderList.size() != 1) {
LogUtil.error("同一个退票申请单号对应多笔退票申请单,退票申请单号:{}", refundApplyOrderNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.DUPLICATED_REFUND_APPLY_ORDER_ORDER);
}
TpRefundApplyOrder refundApplyOrder = refundApplyOrderList.get(0);
if (!StringUtils.equals(refundApplyOrder.getStatus(), TpRefundApplyOrderStatusEnum.REFUNDING.getCode())) {
LogUtil.error("退票申请单状态非法,无法更新为退票成功", refundApplyOrderNo);
throw new TpTradeCoreException(TpTradeCoreErrorCode.INVALID_REFUND_APPLY_ORDER_STATUS_ORDER);
}
Boolean res = contractDomainService.refundSuccess(refundApplyOrderNo, tenantId);
return TpResult.success(res);
}
public List<TpRefundSubjectItem> convertRefundItemDTOs2Domain(String refundApplyOrderNo, List<TpRefundSubjectItemDTO> refundSubjectItemDTOs) {
List<TpRefundSubjectItem> subjectItems = refundSubjectItemConvert.convertDTOs2DomainList(refundSubjectItemDTOs);
subjectItems.forEach(subjectItem -> subjectItem.setRefundApplyOrderNo(refundApplyOrderNo));
return subjectItems;
}
@Override
public TpResult<CommonPage<TpRefundApplyOrderDTO>> pageQueryApplyRefundOrders(TpPageQueryRefundApplyOrderDTO queryDTO) {
PageInfo<TpRefundApplyOrderDTO> pageInfo = contractDomainService.pageQueryRefundApplyOrders(queryDTO);
if (pageInfo == null) {
return TpResult.success(CommonPage.buildEmptyPage());
}
// 正向支付单
assemblePaidOrders(pageInfo.getList(), queryDTO.getTenantId());
// 退款支付单
assembleRefundPayOrders(Lists.newArrayList(TpPayOrderStatusEnum.REFUNDING.getCode(), TpPayOrderStatusEnum.REFUND.getCode()),
pageInfo.getList(), queryDTO.getTenantId());
return TpResult.success(CommonPage.buildPage(queryDTO.getPageNum(), queryDTO.getPageSize(), pageInfo.getPages(), pageInfo.getTotal(), pageInfo.getList()));
}
private void assemblePaidOrders(List<TpRefundApplyOrderDTO> refundApplyOrderDTOS, String tenantId) {
List<String> orderNos = refundApplyOrderDTOS.stream()
.map(TpRefundApplyOrderDTO::getOrderNo)
.distinct()
.collect(Collectors.toList());
List<String> bizNos = Lists.newArrayList();
orderNos.forEach(orderNo -> bizNos.add(orderNo + TpBizTypeEnum.CUSTOM_BUS_PAY.getCode()));
List<TpPayOrderDTO> paidOrderList = getPayOrderList(bizNos, Lists.newArrayList(TpPayOrderStatusEnum.PAID.getCode()), tenantId);
if (CollectionUtils.isEmpty(paidOrderList)) {
LogUtil.error("查询退票申请单业务,不存在已支付的支付单,数据错误,订单号列表:{}", JSONUtil.toJsonStr(bizNos));
throw new TpTradeCoreException(TpTradeCoreErrorCode.PAY_ORDER_NOT_FOUND);
}
Map<String, TpPayOrderDTO> payOrderMap = paidOrderList.stream()
.collect(Collectors.toMap(TpPayOrderDTO::getOrderNo, Function.identity()));
refundApplyOrderDTOS.forEach(refundApplyOrder -> {
TpPayOrderDTO paidOrder = payOrderMap.get(refundApplyOrder.getOrderNo());
refundApplyOrder.setPaidOrder(paidOrder);
});
}
@Override
public TpResult<List<TpRefundApplyOrderDTO>> getRefundApplyOrderList(TpQueryRefundApplyOrderDTO queryDTO) {
List<TpRefundApplyOrder> refundApplyOrders = contractDomainService.getRefundApplyOrderList(queryDTO);
if (CollectionUtils.isEmpty(refundApplyOrders)) {
return TpResult.success(null);
}
// 查询退款支付单
List<TpRefundApplyOrderDTO> refundApplyOrderDTOs = refundApplyOrderConvert.convert2DTOList(refundApplyOrders);
if (CollectionUtils.isNotEmpty(queryDTO.getNeedProperties()) && queryDTO.getNeedProperties().contains(TpRefundApplyOrderModulesEnum.REFUND_PAY_ORDER.getModule())) {
assembleRefundPayOrders(Lists.newArrayList(TpPayOrderStatusEnum.REFUND.getCode(), TpPayOrderStatusEnum.REFUNDING.getCode()), refundApplyOrderDTOs, queryDTO.getTenantId());
}
return TpResult.success(refundApplyOrderDTOs);
}
@Override
public TpResult<TpQueryRefundDetailVO> getRefundDetail(TpQueryRefundDetailDTO queryDTO) {
// 查询退票申请单
List<String> needProperties = Lists.newArrayList(TpRefundApplyOrderModulesEnum.REFUND_PAY_ORDER.getModule(), TpRefundApplyOrderModulesEnum.REFUND_VOUCHER.getModule(),
TpRefundApplyOrderModulesEnum.REFUND_ROUTE.getModule(), TpRefundApplyOrderModulesEnum.REFUND_APPLICANT.getModule());
List<TpRefundApplyOrder> refundApplyOrders = contractDomainService.getRefundApplyOrderList(TpQueryRefundApplyOrderDTO.builder()
.needProperties(needProperties)
.refundApplyOrderNo(queryDTO.getRefundApplyOrderNo())
.tenantId(queryDTO.getTenantId())
.build());
if (CollectionUtils.isEmpty(refundApplyOrders)) {
return TpResult.success(null);
}
Assert.isTrue(refundApplyOrders.size() == 1, "同一个退票申请单号查询到两个退票申请单,数据错误");
TpRefundApplyOrder refundApplyOrder = refundApplyOrders.get(0);
TpRefundApplyOrderDTO refundApplyOrderDTO = refundApplyOrderConvert.convert2DTO(refundApplyOrder);
// 查询凭证
List<String> voucherNos = refundApplyOrder.getRefundVoucherList().stream()
.map(TpRefundVoucher::getVoucherNo)
.collect(Collectors.toList());
TpVoucherQueryDTO voucherQueryDTO = new TpVoucherQueryDTO();
List<String> voucherNeedProperties = TpVoucherNeedPropertiesEnum.buildNeedPropertiesList(TpVoucherNeedPropertiesEnum.PASSENGER);
List<TpVoucherDTO> voucherDTOs = voucherClient.getVoucherList(voucherQueryDTO
.setVoucherNos(voucherNos)
.setTenantId(queryDTO.getTenantId())
.setNeedProperties(voucherNeedProperties));
Assert.isTrue(CollectionUtils.isNotEmpty(voucherDTOs), "退票申请单对应的凭证列表为空");
TpVoucherDTO voucherDTO = voucherDTOs.get(0);
Map<String, TpVoucherDTO> voucherMap = voucherDTOs.stream().collect(Collectors.toMap(TpVoucherDTO::getVoucherNo, Function.identity()));
// 查询正向支付单
TpPayOrderDTO paidOrder = getPaidOrder(refundApplyOrder.getOrderNo(), queryDTO.getTenantId());
// 查询退款支付单
List<TpPayOrderDTO> refundPayOrders = paymentClient.getPayOrderList(TpPayOrderQueryDTO.builder().bizNo(refundApplyOrder.getRefundApplyOrderNo()).tenantId(queryDTO.getTenantId()).build());
Assert.notEmpty(refundPayOrders, "退票申请单关联的退款支付单不能为空");
refundApplyOrderDTO.setRefundPayOrderDTOs(refundPayOrders);
// 组装退票的信息
List<TpRefundVoucher> refundVoucherList = refundApplyOrder.getRefundVoucherList();
Assert.notEmpty(refundVoucherList, "退票凭证不能为空");
// 实名制
List<TpNonRealNameTicketRefundChoiceDTO> nonRealNameTicketRefundChoiceDTOs = Lists.newArrayList();
List<TpRealNameTicketRefundChoiceDTO> realNameTicketRefundChoiceDTOs = Lists.newArrayList();
if (voucherDTO.getRequiredRealName()) {
Map<String, List<TpVoucherDTO>> passengerVoucherMap = voucherDTOs.stream().collect(Collectors.groupingBy(v -> v.getPassenger().getPassengerNo()));
passengerVoucherMap.forEach((passengerNo, voucherList) -> {
TpRealNameTicketRefundChoiceDTO choiceDTO = new TpRealNameTicketRefundChoiceDTO();
List<String> refundDateList = Lists.newArrayList();
voucherList.forEach(v -> {
TpRefundPassengerDTO refundPassengerDTO = TpVoucherPassengerMapStructConvert.INSTANCE.convert2RefundPassengerDTO(v.getPassenger());
choiceDTO.setRefundPassengerDTO(refundPassengerDTO);
String refundDate = v.getEffectiveStartTime() + GlobalConstants.HORIZONTAL_LINE + v.getEffectiveEndTime();
choiceDTO.setTripType(v.getTripType());
refundDateList.add(refundDate);
});
choiceDTO.setVoucherTravelDateList(refundDateList);
realNameTicketRefundChoiceDTOs.add(choiceDTO);
});
} else {
for (TpRefundVoucher refundVoucher : refundVoucherList) {
TpNonRealNameTicketRefundChoiceDTO choiceDTO = new TpNonRealNameTicketRefundChoiceDTO();
TpVoucherDTO voucher = voucherMap.get(refundVoucher.getVoucherNo());
int perPassengerCount = voucher.getTotalCount() / voucher.getPassengerCount();
choiceDTO.setRefundPassengerCount(refundVoucher.getRefundCount() / perPassengerCount);
choiceDTO.setVoucherTravelDate(voucher.getEffectiveStartTime() + GlobalConstants.HORIZONTAL_LINE + voucher.getEffectiveEndTime());
choiceDTO.setTripType(voucher.getTripType());
nonRealNameTicketRefundChoiceDTOs.add(choiceDTO);
}
}
// 组装退票日期
return TpResult.success(TpQueryRefundDetailVO.builder()
.nonRealNameTicketRefundChoiceDTOs(nonRealNameTicketRefundChoiceDTOs)
.realNameTicketRefundChoiceDTOs(realNameTicketRefundChoiceDTOs)
.realNameRefund(voucherDTO.getRequiredRealName())
.refundApplyOrderDTO(refundApplyOrderDTO)
.paidOrderDTO(paidOrder)
.voucherType(voucherDTO.getType())
.build());
}
private List<TpPayOrderDTO> getPayOrderList(List<String> bizNos, List<String> targetStatusList, String tenantId) {
return paymentClient.getPayOrderList(TpPayOrderQueryDTO.builder()
.bizNos(bizNos)
.targetStatusList(targetStatusList)
.tenantId(tenantId)
.build());
}
private TpPayOrderDTO getPaidOrder(String orderNo, String tenantId) {
String bizNo = orderNo + TpBizTypeEnum.CUSTOM_BUS_PAY.getCode();
List<TpPayOrderDTO> paidOrders = getPayOrderList(Lists.newArrayList(bizNo), Lists.newArrayList(TpPayOrderStatusEnum.PAID.getCode()), tenantId);
if (CollectionUtils.isEmpty(paidOrders)) {
return null;
}
if (paidOrders.size() > 1) {
LogUtil.error("存在重复支付的支付单,数据错误,无法进行退票,订单号:{}", JSONUtil.toJsonStr(bizNo));
throw new TpTradeCoreException(TpTradeCoreErrorCode.CALCULATE_REFUND_AMOUNT_DUPLICATE_PAID_ORDER);
}
return paidOrders.get(0);
}
private void assembleRefundPayOrders(List<String> targetStatusList, List<TpRefundApplyOrderDTO> refundApplyOrders, String tenantId) {
List<String> refundApplyOrderNos = refundApplyOrders.stream()
.map(TpRefundApplyOrderDTO::getRefundApplyOrderNo)
.collect(Collectors.toList());
List<TpPayOrderDTO> payOrders = getPayOrderList(refundApplyOrderNos, targetStatusList, tenantId);
if (CollectionUtils.isNotEmpty(payOrders)) {
Map<String, List<TpPayOrderDTO>> payOrderMap = payOrders.stream()
.collect(Collectors.groupingBy(TpPayOrderDTO::getBizNo));
refundApplyOrders.forEach(refundApplyOrder -> {
List<TpPayOrderDTO> payOrderDTOS = payOrderMap.get(refundApplyOrder.getRefundApplyOrderNo());
refundApplyOrder.setRefundPayOrderDTOs(payOrderDTOS);
});
}
}
}

View File

@@ -0,0 +1,137 @@
package com.deepinnet.tptradecore.biz.service.impl.order;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tptradecore.biz.convert.TpOrderChangeBizConverter;
import com.deepinnet.tptradecore.common.dto.order.*;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.service.facade.order.TpOrderChangedApplyFacade;
import com.deepinnet.tptradecore.common.vo.order.TpOrderChangeApplyVO;
import com.deepinnet.tptradecore.common.vo.order.TpOrderChangeItemVO;
import com.deepinnet.tptradecore.core.model.order.TpOrderChangeApply;
import com.deepinnet.tptradecore.core.model.order.TpOrderChangeItem;
import com.deepinnet.tptradecore.core.service.order.TpOrderChangedApplyDomainService;
import org.apache.dubbo.config.annotation.DubboService;
import javax.annotation.Resource;
import java.util.List;
@DubboService
public class TpOrderChangedApplyFacadeImpl implements TpOrderChangedApplyFacade {
@Resource
private TpOrderChangeBizConverter orderChangeBizConverter;
@Resource
private TpOrderChangedApplyDomainService orderChangedDomainService;
@Override
public TpResult<TpOrderChangeApplyVO> getOrderChangedApplyDetail(TpOrderChangeApplyDetailDTO orderChangeApplyQueryDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(orderChangeApplyQueryDTO.getOriginalOrderNo())){
orderChangeApplyQueryDTO.setOriginalOrderNo(orderChangeApplyQueryDTO.getOrderNo());
}
TpOrderChangeApply tpOrderChangeApply = orderChangedDomainService.getOrderChangedApplyDetail(orderChangeApplyQueryDTO);
return TpResult.success(orderChangeBizConverter.model2VO(tpOrderChangeApply));
}
@Override
public TpResult<List<TpOrderChangeApplyVO>> listOrderChangeApply(TpOrderChangeApplyListDTO tpOrderChangeApplyListDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(tpOrderChangeApplyListDTO.getOriginalOrderNo())){
tpOrderChangeApplyListDTO.setOriginalOrderNo(tpOrderChangeApplyListDTO.getOrderNo());
}
List<TpOrderChangeApply> tpOrderChangeApplyList = orderChangedDomainService.listOrderChangeApply(tpOrderChangeApplyListDTO);
return TpResult.success(orderChangeBizConverter.model2VOList(tpOrderChangeApplyList));
}
@Override
public TpResult<List<TpOrderChangeApplyVO>> batchQueryOrderChangeApplyByOrderNos(TpOrderChangeApplyBatchListDTO tpOrderChangeApplyListDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(CollUtil.isEmpty(tpOrderChangeApplyListDTO.getOriginalOrderNos())){
tpOrderChangeApplyListDTO.setOriginalOrderNos(tpOrderChangeApplyListDTO.getOrderNos());
}
List<TpOrderChangeApply> tpOrderChangeApplyList = orderChangedDomainService.batchQueryOrderChangeApplyByOrderNos(tpOrderChangeApplyListDTO);
return TpResult.success(orderChangeBizConverter.model2VOList(tpOrderChangeApplyList));
}
@Override
public TpResult<TpOrderChangeApplyVO> getLatestOrderChangedApplyDetail(TpOrderChangeApplyLatestDetailDTO tpOrderChangeApplyLatestDetailDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(tpOrderChangeApplyLatestDetailDTO.getOriginalOrderNo())){
tpOrderChangeApplyLatestDetailDTO.setOriginalOrderNo(tpOrderChangeApplyLatestDetailDTO.getOrderNo());
}
TpOrderChangeApply tpOrderChangeApply = orderChangedDomainService.getLatestOrderChangedApplyDetail(tpOrderChangeApplyLatestDetailDTO);
return TpResult.success(orderChangeBizConverter.model2VO(tpOrderChangeApply));
}
@Override
public TpResult<List<TpOrderChangeItemVO>> listOrderChangedItems(TpOrderChangeItemListDTO orderChangeItemListDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(orderChangeItemListDTO.getOriginalOrderNo())){
orderChangeItemListDTO.setOriginalOrderNo(orderChangeItemListDTO.getOrderNo());
}
List<TpOrderChangeItem> tpOrderChangeItemList = orderChangedDomainService.listOrderChangedItems(orderChangeItemListDTO);
return TpResult.success(orderChangeBizConverter.model2ItemVOList(tpOrderChangeItemList));
}
@Override
public TpResult<Boolean> createOrderChangeApply(TpOrderChangeApplyCreatedDTO orderChangeApplyCreatedDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(orderChangeApplyCreatedDTO.getOriginalOrderNo())){
orderChangeApplyCreatedDTO.setOriginalOrderNo(orderChangeApplyCreatedDTO.getOrderNo());
}
Boolean createFlag = orderChangedDomainService.createOrderChangeApply(orderChangeApplyCreatedDTO);
if(createFlag){
return TpResult.success(createFlag.booleanValue());
}
return TpResult.fail(TpTradeCoreErrorCode.ORDER_CHANGE_APPLY_CREATE_ERROR.getCode(),TpTradeCoreErrorCode.ORDER_CHANGE_APPLY_CREATE_ERROR.getDesc());
}
@Override
public TpResult<Boolean> pushOrderChangedApplyStatus(TpOrderChangeApplyStatusUpdateDTO statusUpdateDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(statusUpdateDTO.getOriginalOrderNo())){
statusUpdateDTO.setOriginalOrderNo(statusUpdateDTO.getOrderNo());
}
Boolean statusUpdateFlag = orderChangedDomainService.pushOrderChangedApplyStatus(statusUpdateDTO);
if(statusUpdateFlag){
return TpResult.success(statusUpdateFlag.booleanValue());
}
return TpResult.fail(TpTradeCoreErrorCode.ORDER_CHANGE_APPLY_STATUS_PUSH_ERROR.getCode(),TpTradeCoreErrorCode.ORDER_CHANGE_APPLY_STATUS_PUSH_ERROR.getDesc());
}
@Override
public TpResult<Boolean> submitApprovedApply(TpOrderChangeApplyApprovedSubmitDTO approvedSubmitDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(approvedSubmitDTO.getOriginalOrderNo())){
approvedSubmitDTO.setOriginalOrderNo(approvedSubmitDTO.getOrderNo());
}
Boolean statusUpdateFlag = orderChangedDomainService.submitApprovedApply(approvedSubmitDTO);
if(statusUpdateFlag){
return TpResult.success(statusUpdateFlag.booleanValue());
}
return TpResult.fail(TpTradeCoreErrorCode.ORDER_CHANGE_APPLY_STATUS_PUSH_ERROR.getCode(),TpTradeCoreErrorCode.ORDER_CHANGE_APPLY_APPROVED_UPDATE_ERROR.getDesc());
}
@Override
public TpResult<Boolean> submitReduceFscApply(TpOrderChangeApplyRscApplyDTO rfscApplyDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(rfscApplyDTO.getOriginalOrderNo())){
rfscApplyDTO.setOriginalOrderNo(rfscApplyDTO.getOrderNo());
}
Boolean statusUpdateFlag = orderChangedDomainService.submitReduceFscApply(rfscApplyDTO);
if(statusUpdateFlag){
return TpResult.success(statusUpdateFlag.booleanValue());
}
return TpResult.fail(TpTradeCoreErrorCode.ORDER_CHANGE_APPLY_STATUS_PUSH_ERROR.getCode(),TpTradeCoreErrorCode.ORDER_CHANGE_APPLY_APPROVED_UPDATE_ERROR.getDesc());
}
}

View File

@@ -0,0 +1,108 @@
package com.deepinnet.tptradecore.biz.service.impl.order;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tptradecore.biz.convert.TpOrderChangeBizConverter;
import com.deepinnet.tptradecore.common.dto.order.*;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.service.facade.order.TpOrderChangedFacade;
import com.deepinnet.tptradecore.common.vo.order.TpOrderChangeApplyVO;
import com.deepinnet.tptradecore.common.vo.order.TpOrderChangeItemVO;
import com.deepinnet.tptradecore.core.model.order.TpOrderChangeApply;
import com.deepinnet.tptradecore.core.model.order.TpOrderChangeItem;
import com.deepinnet.tptradecore.core.service.order.TpOrderChangedApplyDomainService;
import org.apache.dubbo.config.annotation.DubboService;
import javax.annotation.Resource;
import java.util.List;
@DubboService
@Deprecated
public class TpOrderChangedFacadeImpl implements TpOrderChangedFacade {
@Resource
private TpOrderChangeBizConverter orderChangeBizConverter;
@Resource
private TpOrderChangedApplyDomainService orderChangedDomainService;
@Override
public TpResult<TpOrderChangeApplyVO> getOrderChangedApplyDetail(TpOrderChangeApplyDetailDTO orderChangeApplyQueryDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(orderChangeApplyQueryDTO.getOriginalOrderNo())){
orderChangeApplyQueryDTO.setOriginalOrderNo(orderChangeApplyQueryDTO.getOrderNo());
}
TpOrderChangeApply tpOrderChangeApply = orderChangedDomainService.getOrderChangedApplyDetail(orderChangeApplyQueryDTO);
return TpResult.success(orderChangeBizConverter.model2VO(tpOrderChangeApply));
}
@Override
public TpResult<List<TpOrderChangeApplyVO>> listOrderChangeApply(TpOrderChangeApplyListDTO tpOrderChangeApplyListDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(tpOrderChangeApplyListDTO.getOriginalOrderNo())){
tpOrderChangeApplyListDTO.setOriginalOrderNo(tpOrderChangeApplyListDTO.getOrderNo());
}
List<TpOrderChangeApply> tpOrderChangeApplyList = orderChangedDomainService.listOrderChangeApply(tpOrderChangeApplyListDTO);
return TpResult.success(orderChangeBizConverter.model2VOList(tpOrderChangeApplyList));
}
@Override
public TpResult<List<TpOrderChangeApplyVO>> batchQueryOrderChangeApplyByOrderNos(TpOrderChangeApplyBatchListDTO tpOrderChangeApplyListDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(CollUtil.isEmpty(tpOrderChangeApplyListDTO.getOriginalOrderNos())){
tpOrderChangeApplyListDTO.setOriginalOrderNos(tpOrderChangeApplyListDTO.getOrderNos());
}
List<TpOrderChangeApply> tpOrderChangeApplyList = orderChangedDomainService.batchQueryOrderChangeApplyByOrderNos(tpOrderChangeApplyListDTO);
return TpResult.success(orderChangeBizConverter.model2VOList(tpOrderChangeApplyList));
}
@Override
public TpResult<TpOrderChangeApplyVO> getLatestOrderChangedApplyDetail(TpOrderChangeApplyLatestDetailDTO tpOrderChangeApplyLatestDetailDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(tpOrderChangeApplyLatestDetailDTO.getOriginalOrderNo())){
tpOrderChangeApplyLatestDetailDTO.setOriginalOrderNo(tpOrderChangeApplyLatestDetailDTO.getOrderNo());
}
TpOrderChangeApply tpOrderChangeApply = orderChangedDomainService.getLatestOrderChangedApplyDetail(tpOrderChangeApplyLatestDetailDTO);
return TpResult.success(orderChangeBizConverter.model2VO(tpOrderChangeApply));
}
@Override
public TpResult<List<TpOrderChangeItemVO>> listOrderChangedItems(TpOrderChangeItemListDTO orderChangeItemListDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(orderChangeItemListDTO.getOriginalOrderNo())){
orderChangeItemListDTO.setOriginalOrderNo(orderChangeItemListDTO.getOrderNo());
}
List<TpOrderChangeItem> tpOrderChangeItemList = orderChangedDomainService.listOrderChangedItems(orderChangeItemListDTO);
return TpResult.success(orderChangeBizConverter.model2ItemVOList(tpOrderChangeItemList));
}
@Override
public TpResult<Boolean> createOrderChangeApply(TpOrderChangeApplyCreatedDTO orderChangeApplyCreatedDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(orderChangeApplyCreatedDTO.getOriginalOrderNo())){
orderChangeApplyCreatedDTO.setOriginalOrderNo(orderChangeApplyCreatedDTO.getOrderNo());
}
Boolean createFlag = orderChangedDomainService.createOrderChangeApply(orderChangeApplyCreatedDTO);
if(createFlag){
return TpResult.success(createFlag.booleanValue());
}
return TpResult.fail(TpTradeCoreErrorCode.ORDER_CHANGE_APPLY_CREATE_ERROR.getCode(),TpTradeCoreErrorCode.ORDER_CHANGE_APPLY_CREATE_ERROR.getDesc());
}
@Override
public TpResult<Boolean> pushOrderChangedApplyStatus(TpOrderChangeApplyStatusUpdateDTO statusUpdateDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(statusUpdateDTO.getOriginalOrderNo())){
statusUpdateDTO.setOriginalOrderNo(statusUpdateDTO.getOrderNo());
}
Boolean statusUpdateFlag = orderChangedDomainService.pushOrderChangedApplyStatus(statusUpdateDTO);
if(statusUpdateFlag){
return TpResult.success(statusUpdateFlag.booleanValue());
}
return TpResult.fail(TpTradeCoreErrorCode.ORDER_CHANGE_APPLY_STATUS_PUSH_ERROR.getCode(),TpTradeCoreErrorCode.ORDER_CHANGE_APPLY_STATUS_PUSH_ERROR.getDesc());
}
}

View File

@@ -0,0 +1,143 @@
package com.deepinnet.tptradecore.biz.service.impl.order;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tptradecore.biz.convert.TpOrderDispatchBizConverter;
import com.deepinnet.tptradecore.common.dto.order.*;
import com.deepinnet.tptradecore.common.enums.order.TpOrderDispatchStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.service.facade.order.TpOrderDispatchFacade;
import com.deepinnet.tptradecore.common.vo.order.TpOrderDispatchVO;
import com.deepinnet.tptradecore.core.model.order.TpOrderDispatch;
import com.deepinnet.tptradecore.core.model.order.TpOrderReceived;
import com.deepinnet.tptradecore.core.service.order.TpOrderDispatchDomainService;
import org.apache.dubbo.config.annotation.DubboService;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
@DubboService
public class TpOrderDispatchFacadeImpl implements TpOrderDispatchFacade
{
@Resource
private TpOrderDispatchBizConverter orderDispatchBizConverter;
@Resource
private TpOrderDispatchDomainService orderDispatchDomainService;
@Override
public TpResult<Boolean> dispatchOrder(TpOrderDispatchCreatedDTO dispatchCreatedDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(dispatchCreatedDTO.getOriginalOrderNo())){
dispatchCreatedDTO.setOriginalOrderNo(dispatchCreatedDTO.getOrderNo());
}
Boolean dispatchFlag = orderDispatchDomainService.dispatchOrder(dispatchCreatedDTO);
if(dispatchFlag){
return TpResult.success(dispatchFlag.booleanValue());
}
return TpResult.fail(TpTradeCoreErrorCode.ORDER_DISPATCH_CREATE_ERROR.getCode(),TpTradeCoreErrorCode.ORDER_DISPATCH_CREATE_ERROR.getDesc());
}
@Override
public TpResult<Boolean> callBackOrder(TpOrderDispatchCallBackDTO callBackDTO) {
Boolean callBackFlag = orderDispatchDomainService.callBackOrder(callBackDTO);
if(callBackFlag){
return TpResult.success(callBackFlag.booleanValue());
}
return TpResult.fail(TpTradeCoreErrorCode.ORDER_DISPATCH_CALLBACK_ERROR.getCode(),TpTradeCoreErrorCode.ORDER_DISPATCH_CALLBACK_ERROR.getDesc());
}
@Override
public TpResult<Boolean> giveBackOrder(TpOrderDispatchGiveBackDTO giveBackDTO) {
Boolean callBackFlag = orderDispatchDomainService.giveBackOrder(giveBackDTO);
if(callBackFlag){
return TpResult.success(callBackFlag.booleanValue());
}
return TpResult.fail(TpTradeCoreErrorCode.ORDER_DISPATCH_GIVEBACK_ERROR.getCode(),TpTradeCoreErrorCode.ORDER_DISPATCH_GIVEBACK_ERROR.getDesc());
}
@Override
public TpResult<TpOrderDispatchVO> getOrderDispatchDetail(TpOrderDispatchDetailDTO orderDispatchDetailDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(orderDispatchDetailDTO.getOriginalOrderNo())){
orderDispatchDetailDTO.setOriginalOrderNo(orderDispatchDetailDTO.getOrderNo());
}
String tenantId = orderDispatchDetailDTO.getTenantId();
String dispatchNo = orderDispatchDetailDTO.getDispatchNo();
String originalOrderNo = orderDispatchDetailDTO.getOriginalOrderNo();
List<String> statuses = orderDispatchDetailDTO.getStatuses();
List<Integer> statusCodes = new ArrayList<>();
if(CollectionUtil.isNotEmpty(statuses)){
statuses.forEach(statusType->{
TpOrderDispatchStatusEnum statusEnum = TpOrderDispatchStatusEnum.getOrderDispatchStatusByType(statusType);
if(statusEnum != null){
statusCodes.add(statusEnum.getStatus());
}
});
}
TpOrderDispatch tpOrderDispatch = orderDispatchDomainService.getDispatchOrder(tenantId,dispatchNo,originalOrderNo,statusCodes);
return TpResult.success(orderDispatchBizConverter.model2VO(tpOrderDispatch));
}
@Override
public TpResult<List<TpOrderDispatchVO>> listOrderDispatchDetail(TpOrderDispatchListDTO dto) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(CollUtil.isEmpty(dto.getOriginalOrderNoList())){
dto.setOriginalOrderNoList(dto.getOrderNoList());
}
String tenantId = dto.getTenantId();
List<String> originalOrderNoList = dto.getOriginalOrderNoList();
List<Integer> statuses = dto.getStatuses();
List<TpOrderDispatch> tpOrderDispatchList = orderDispatchDomainService.listOrderDispatchDetail(tenantId,originalOrderNoList,statuses);
return TpResult.success(orderDispatchBizConverter.model2VOList(tpOrderDispatchList));
}
@Override
public TpResult<Boolean> dispatchFleet(TpOrderDispatchFleetCreatedDTO fleetCreatedDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(fleetCreatedDTO.getOriginalOrderNo())){
fleetCreatedDTO.setOriginalOrderNo(fleetCreatedDTO.getOrderNo());
}
Boolean dispatchFlag = orderDispatchDomainService.dispatchFleet(fleetCreatedDTO);
if(dispatchFlag){
return TpResult.success(dispatchFlag.booleanValue());
}
return TpResult.fail(TpTradeCoreErrorCode.ORDER_DISPATCH_FLEET_CREATE_ERROR.getCode(),TpTradeCoreErrorCode.ORDER_DISPATCH_FLEET_CREATE_ERROR.getDesc());
}
@Override
public TpResult<Boolean> pushDispatchStatus(TpOrderDispatchStatusUpdateDTO statusUpdateDTO) {
//TODO 兼容逻辑,带前端修改好后,删除此逻辑
if(StrUtil.isEmpty(statusUpdateDTO.getOriginalOrderNo())){
statusUpdateDTO.setOriginalOrderNo(statusUpdateDTO.getOrderNo());
}
String tenantId = statusUpdateDTO.getTenantId();
String dispatchNo = statusUpdateDTO.getDispatchNo();
String originalOrderNo = statusUpdateDTO.getOriginalOrderNo();
TpOrderDispatchStatusEnum tpOrderDispatchStatusEnum = TpOrderDispatchStatusEnum.getOrderDispatchStatusByType(statusUpdateDTO.getTargetStatus());
Boolean pushDispatchStatus = orderDispatchDomainService.pushDispatchStatus(tenantId,dispatchNo,originalOrderNo,tpOrderDispatchStatusEnum);
if(pushDispatchStatus){
return TpResult.success(pushDispatchStatus.booleanValue());
}
return TpResult.fail(TpTradeCoreErrorCode.ORDER_DISPATCH_CREATE_ERROR.getCode(),TpTradeCoreErrorCode.ORDER_DISPATCH_CREATE_ERROR.getDesc());
}
}

View File

@@ -0,0 +1,45 @@
package com.deepinnet.tptradecore.biz.service.impl.order;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tptradecore.biz.convert.TpOrderReceivedBizConverter;
import com.deepinnet.tptradecore.common.dto.order.TpOrderReceivedCreatedDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderReceivedDetailDTO;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.service.facade.order.TpOrderReceivedFacade;
import com.deepinnet.tptradecore.common.vo.order.TpOrderReceivedVO;
import com.deepinnet.tptradecore.core.model.order.TpOrderReceived;
import com.deepinnet.tptradecore.core.service.order.TpOrderReceivedDomainService;
import org.apache.dubbo.config.annotation.DubboService;
import javax.annotation.Resource;
@DubboService
public class TpOrderReceivedFacadeImpl implements TpOrderReceivedFacade
{
@Resource
private TpOrderReceivedBizConverter tpOrderReceivedBizConverter;
@Resource
private TpOrderReceivedDomainService orderReceivedDomainService;
@Override
public TpResult<Boolean> receiveOrder(TpOrderReceivedCreatedDTO tpOrderReceiveCreatedDTO) {
Boolean receivedFlag = orderReceivedDomainService.receiveOrder(tpOrderReceiveCreatedDTO);
if(receivedFlag){
return TpResult.success(receivedFlag.booleanValue());
}
return TpResult.fail(TpTradeCoreErrorCode.ORDER_RECEIVED_CREATE_ERROR.getCode(),TpTradeCoreErrorCode.ORDER_RECEIVED_CREATE_ERROR.getDesc());
}
@Override
public TpResult<TpOrderReceivedVO> getOrderReceivedDetail(TpOrderReceivedDetailDTO orderReceivedDetailDTO) {
String tenantId = orderReceivedDetailDTO.getTenantId();
String receivedNo = orderReceivedDetailDTO.getReceiveNo();
String bizObjNo = orderReceivedDetailDTO.getBizObjNo();
String bizObjType = orderReceivedDetailDTO.getBizObjType();
TpOrderReceived tpOrderReceived = orderReceivedDomainService.getReceivedOrder(tenantId,receivedNo,bizObjNo,bizObjType);
return TpResult.success(tpOrderReceivedBizConverter.model2VO(tpOrderReceived));
}
}

View File

@@ -0,0 +1,133 @@
package com.deepinnet.tptradecore.biz.service.impl.order;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tptradecore.common.dal.convert.order.TpUserPassengerConverter;
import com.deepinnet.tptradecore.common.dto.order.TpUserPassengerDTO;
import com.deepinnet.tptradecore.common.dto.order.TpUserPassengerQueryDTO;
import com.deepinnet.tptradecore.common.service.facade.order.TpUserPassengerFacade;
import com.deepinnet.tptradecore.common.service.integration.client.TpSequenceClient;
import com.deepinnet.tptradecore.common.service.integration.client.TpUserCertificationClient;
import com.deepinnet.tptradecore.common.vo.order.TpUserPassengerVO;
import com.deepinnet.tptradecore.core.model.order.TpUserDelPassengerCondition;
import com.deepinnet.tptradecore.core.model.order.TpUserPassenger;
import com.deepinnet.tptradecore.core.model.order.TpUserPassengerCondition;
import com.deepinnet.tptradecore.core.service.order.TpUserPassengerDomainService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author chenjiaju
* @since 2023/8/21
*/
@DubboService
public class TpUserPassengerFacadeImpl implements TpUserPassengerFacade {
@Resource
private TpUserPassengerConverter tpUserPassengerConverter;
@Resource
private TpUserCertificationClient tpUserCertificationClient;
@Resource
private TpSequenceClient tpSequenceClient;
@Resource
private TpUserPassengerDomainService tpUserPassengerDomainService;
@Override
public TpResult<String> saveUserPassenger(TpUserPassengerDTO dto) {
// 参数校验
checkUserSavePassengerParam(dto);
// 实名校验
tpUserCertificationClient.validate(dto);
// 生成乘客编号
dto.setPassengerNo(tpSequenceClient.generateUserPassengerNo());
// 保存乘客
tpUserPassengerDomainService.savePassenger(tpUserPassengerConverter.dto2Model(dto));
return TpResult.success(dto.getPassengerNo());
}
@Override
public TpResult<Boolean> delUserPassenger(TpUserPassengerQueryDTO dto) {
// 校验参数
checkUserDelPassengerParam(dto);
// 删除乘客
tpUserPassengerDomainService.delPassenger(buildTpUserDelPassenger(dto));
return TpResult.success(Boolean.TRUE);
}
@Override
public TpResult<Boolean> modifyPassenger(TpUserPassengerDTO dto) {
// 校验参数
checkModifyPassengerParam(dto);
// 实名校验
tpUserCertificationClient.validate(dto);
// 修改乘客
tpUserPassengerDomainService.modifyPassenger(tpUserPassengerConverter.dto2Model(dto));
return TpResult.success(Boolean.TRUE);
}
@Override
public TpResult<List<TpUserPassengerVO>> queryPassengerList(TpUserPassengerQueryDTO dto) {
// 校验参数
checkListPassengerParam(dto);
// 查询用户对应的乘客数据
List<TpUserPassenger> passengerList = tpUserPassengerDomainService.getPassengerList(buildTpUserQueryPassengerDTO(dto));
return TpResult.success(tpUserPassengerConverter.modelList2voList(passengerList));
}
private TpUserPassengerCondition buildTpUserQueryPassengerDTO(TpUserPassengerQueryDTO dto) {
TpUserPassengerCondition tpUserPassengerCondition = new TpUserPassengerCondition();
tpUserPassengerCondition.setUserNo(dto.getUserNo());
tpUserPassengerCondition.setTenantId(dto.getTenantId());
return tpUserPassengerCondition;
}
private void checkListPassengerParam(TpUserPassengerQueryDTO dto) {
Assert.hasText(dto.getUserNo(), "userNo is null");
Assert.hasText(dto.getTenantId(), "tenantId is null");
}
private void checkModifyPassengerParam(TpUserPassengerDTO dto) {
Assert.hasText(dto.getPassengerNo(), "passengerNo is null");
Assert.hasText(dto.getUserNo(), "userNo is null");
Assert.hasText(dto.getTenantId(), "tenantId is null");
}
private TpUserDelPassengerCondition buildTpUserDelPassenger(TpUserPassengerQueryDTO dto) {
TpUserDelPassengerCondition tpUserDelPassengerCondition = new TpUserDelPassengerCondition();
tpUserDelPassengerCondition.setUserNo(dto.getUserNo());
tpUserDelPassengerCondition.setPassengerNo(dto.getPassengerNo());
tpUserDelPassengerCondition.setTenantId(dto.getTenantId());
return tpUserDelPassengerCondition;
}
private void checkUserDelPassengerParam(TpUserPassengerQueryDTO dto) {
Assert.hasText(dto.getUserNo(), "userNo is null");
Assert.hasText(dto.getPassengerNo(), "passengerNo is null");
Assert.hasText(dto.getTenantId(), "tenantId is null");
}
private static void checkUserSavePassengerParam(TpUserPassengerDTO dto) {
Assert.hasText(dto.getUserNo(), "userNo is null");
Assert.hasText(dto.getTenantId(), "tenantId is null");
Assert.hasText(dto.getPassengerName(), "passengerName is null");
}
}

View File

@@ -0,0 +1,79 @@
package com.deepinnet.tptradecore.biz.service.impl.order;
import com.deepinnet.tp.common.lang.page.CommonPage;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tptradecore.common.dal.convert.order.TpUserRouteCollectionConverter;
import com.deepinnet.tptradecore.common.dto.order.TpUserRouteCollectionDTO;
import com.deepinnet.tptradecore.common.dto.order.TpUserRouteCollectionQueryDTO;
import com.deepinnet.tptradecore.common.service.facade.order.TpUserRouteCollectionFacade;
import com.deepinnet.tptradecore.common.service.integration.client.TpSequenceClient;
import com.deepinnet.tptradecore.common.vo.order.TpUserRouteCollectionVO;
import com.deepinnet.tptradecore.core.model.order.TpUserRouteCollection;
import com.deepinnet.tptradecore.core.service.order.TpUserRouteCollectionDomainService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author chenjiaju
* @since 2023/8/28
*/
@DubboService
public class TpUserRouteCollectionFacadeImpl implements TpUserRouteCollectionFacade {
@Resource
private TpUserRouteCollectionDomainService tpUserRouteCollectionDomainService;
@Resource
private TpUserRouteCollectionConverter tpUserRouteCollectionConverter;
@Resource
private TpSequenceClient tpSequenceClient;
@Override
public TpResult<Boolean> collectionRoute(TpUserRouteCollectionDTO dto) {
// 校验参数
checkRouteCollectionParams(dto);
// 设置线路编号
dto.setCollectionNo(tpSequenceClient.generateRouteCollectionNo());
// 收集线路
tpUserRouteCollectionDomainService.collectRoute(tpUserRouteCollectionConverter.dto2Model(dto));
return TpResult.success(Boolean.TRUE);
}
@Override
public TpResult<CommonPage<TpUserRouteCollectionVO>> queryCollectionRouteByPage(TpUserRouteCollectionQueryDTO dto) {
Assert.hasText(dto.getTenantId(), "tenantId is null");
Page<Object> page = PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
List<TpUserRouteCollection> routeList = tpUserRouteCollectionDomainService.getCollectionRouteList(tpUserRouteCollectionConverter.queryDTO2queryCondition(dto));
CommonPage<TpUserRouteCollectionVO> result = new CommonPage<>();
result.setPageNum(page.getPageNum());
result.setPageSize(page.getPageSize());
result.setTotal(page.getTotal());
result.setList(tpUserRouteCollectionConverter.modelList2VOList(routeList));
return TpResult.success(result);
}
private static void checkRouteCollectionParams(TpUserRouteCollectionDTO dto) {
Assert.hasText(dto.getTenantId(), "tenantId is null");
Assert.hasText(dto.getUserNo(), "userNo is null");
Assert.hasText(dto.getUpLocation(), "upLocation is null");
Assert.hasText(dto.getDownLocation(), "downLocation is null");
}
}

View File

@@ -0,0 +1,658 @@
package com.deepinnet.tptradecore.biz.service.impl.trans;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.json.JSONUtil;
import com.deepinnet.tp.common.lang.constants.GlobalConstants;
import com.deepinnet.tp.common.lang.result.TpResult;
import com.deepinnet.tp.common.lang.util.*;
import com.deepinnet.tptradecore.common.dal.convert.trans.TpPayOrderMapStructConvert;
import com.deepinnet.tptradecore.common.dto.trans.*;
import com.deepinnet.tptradecore.common.enums.order.TpOrderModulesEnum;
import com.deepinnet.tptradecore.common.enums.trans.*;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.common.service.facade.trans.TpPaymentFacade;
import com.deepinnet.tptradecore.common.service.integration.client.TpSequenceClient;
import com.deepinnet.tptradecore.common.service.integration.dto.*;
import com.deepinnet.tptradecore.common.service.integration.mq.constants.*;
import com.deepinnet.tptradecore.common.service.integration.mq.entity.*;
import com.deepinnet.tptradecore.common.service.integration.mq.template.MessageClient;
import com.deepinnet.tptradecore.common.service.integration.strategy.PayStrategy;
import com.deepinnet.tptradecore.common.vo.trans.*;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.trans.TpPayOrder;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import com.deepinnet.tptradecore.core.service.trans.TpPayOrderDomainService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
import static com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode.*;
/**
* 支付服务
*
* @author amos
* @since 2023-07-27 09:43:20
*/
@DubboService
public class TpPaymentFacadeImpl implements TpPaymentFacade, InitializingBean {
@Resource
private TpPayOrderDomainService payOrderDomainService;
@Resource
private TpPayOrderMapStructConvert payOrderConvert;
@Resource
private TpSequenceClient sequenceClient;
@Resource
private ThreadPoolTaskExecutor payRefundThreadPool;
@Resource
private MessageClient messageClient;
@Resource
private TpOrderDomainService orderDomainService;
@Resource
private Map<String, PayStrategy> payStrategyMap;
private final Map<TpPayTypeEnum, PayStrategy> payTypeStrategyMap = new ConcurrentHashMap<>();
private static final long DEFAULT_PAY_ORDER_SEQUENCE = 0L;
@Override
public void afterPropertiesSet() {
payStrategyMap
.values()
.parallelStream()
.forEach(payStrategy -> payTypeStrategyMap.put(payStrategy.getPayType(), payStrategy));
}
@Override
public TpResult<TpPreparePayVO> preparePay(TpPreparePayDTO preparePayDTO) {
// 参数校验
paramCheck(preparePayDTO);
// 创建支付单
TpPayOrder payOrder = createPayOrder(preparePayDTO);
// 向第三方支付平台发起预支付调用
String prepayResult = platformPrepay(preparePayDTO, payOrder.getPaySequence());
// 更新支付单状态为支付中
if (StringUtils.equals(payOrder.getStatus(), TpPayOrderStatusEnum.INIT.getCode())) {
payOrderDomainService.updatePayOrder(TpPayOrderUpdateDTO.builder()
.payOrderNo(payOrder.getPayOrderNo())
.originalStatus(TpPayOrderStatusEnum.INIT.getCode())
.targetStatus(TpPayOrderStatusEnum.PAYING.getCode())
.tenantId(preparePayDTO.getTenantId())
.build());
}
// 发送支付单超时关单的消息
BaseMessageEntity baseMessageEntity = buildDelayMessageEntity(payOrder.getPayOrderNo(), payOrder.getTenantId());
messageClient.send(messageClient.getDelayMessageTopic(), MessageConstants.EVENT_PAY_ORDER_DELAY_TAG_SUCCESS, baseMessageEntity, preparePayDTO.getCreateDTO().getPayTimeout());
// 返回收银台地址
return TpResult.success(TpPreparePayVO.builder().prepayResult(prepayResult).build());
}
@Override
public TpResult<TpQueryPayResultVO> queryPayResult(TpQueryPayResultDTO dto) {
TpPayResultDTO payResultDTO = payOrderDomainService.queryPayResult(dto);
return TpResult.success(BeanUtil.copyProperties(payResultDTO, TpQueryPayResultVO.class));
}
@Override
public TpResult<Void> refund(TpPayRefundDTO refundDTO) {
String refundBizNo = refundDTO.getRefundBizNo();
// 查询正向的支付单,校验是否已经支付
TpPayOrder paidPayOrder = getPaidPayOrder(refundDTO);
// 根据退票申请单号控制幂等
refundDTO.setPayType(paidPayOrder.getPayType());
refundIdempotentControl(refundDTO);
List<TpPayOrder> refundingPayOrders = payOrderDomainService.queryPayOrderList(TpPayOrderQueryDTO.builder()
.bizNo(refundBizNo)
.targetStatusList(Lists.newArrayList(TpPayOrderStatusEnum.REFUNDING.getCode()))
.tenantId(refundDTO.getTenantId())
.build());
if (CollectionUtils.isNotEmpty(refundingPayOrders)) {
Assert.isTrue(refundingPayOrders.size() == 1, "同一个退票申请单号对应的退款支付单不能存在多个");
}
// 手续费可以配置成100%可能存在退0元的情况
if (refundDTO.getRefundAmount().compare(new TpMoney("0", TpMoney.ValueUnitEnum.YUAN)) == TpMoney.CompareResult.EQUAL) {
TpPayOrder refundPayOrder = CollectionUtils.isNotEmpty(refundingPayOrders) ? refundingPayOrders.get(0) :
createRefundSuccessPayOrder(paidPayOrder, refundBizNo, refundDTO.getRefundBizType(), refundDTO.getRefundAmount(), refundDTO.getChargeAmount(), refundDTO.getOrgCode(), refundDTO.getTenantId());
// 发送退款成功消息推进流程
if (StringUtils.equals(refundDTO.getPayType(), TpPayTypeEnum.ALIPAY.getCode())) {
BaseMessageEntity messageEntity = buildRefundSuccessMessage(refundPayOrder.getOrderNo(), refundPayOrder.getPayOrderNo(),
refundDTO.getRefundBizNo(), refundDTO.getRefundBizType(), refundDTO.getTenantId());
LogUtil.info("发送支付宝退款成功的消息,消息体为:{}", JSONUtil.toJsonStr(messageEntity));
messageClient.send(messageClient.getMessageTopic(), MessageConstants.EVENT_CODE_TRANS_REFUND_SUCCESS, messageEntity);
}
LogUtil.info("当前订单的退款金额为0元退款接口入参为{}", JSONUtil.toJsonStr(refundDTO));
return TpResult.success(null);
}
// 正常退款流程
TpPayOrder refundPayOrder = CollectionUtils.isNotEmpty(refundingPayOrders) ? refundingPayOrders.get(0) :
createRefundPayOrder(paidPayOrder, refundBizNo, refundDTO.getRefundBizType(), refundDTO.getRefundAmount(), refundDTO.getChargeAmount(), refundDTO.getOrgCode(), refundDTO.getTenantId());
String outPayFlowId = paidPayOrder.getOutPayFlowId();
// 调用第三方平台接口异步退款
CompletableFuture.runAsync(() -> {
// 改签订单需要传递原始订单的支付金额
TpMoney payAmount;
if (refundDTO.getIsRescheduleOrder()) {
payAmount = refundDTO.getOriginalPayAmount();
} else {
payAmount = paidPayOrder.getPayAmount();
}
String payeeAppId = paidPayOrder.getPayeeAccount().getAccount();
TpRefundResultDTO refundResultDTO = payTypeStrategyMap.get(TpPayTypeEnum.getByCode(paidPayOrder.getPayType())).refund(PayPlatformRefundDTO.builder()
.outPayFlowId(outPayFlowId)
.payScene(paidPayOrder.getPayScene())
.appId(payeeAppId)
.refundOutRequestNo(refundBizNo)
.refundBizType(refundDTO.getRefundBizType())
.refundAmount(refundPayOrder.getPayAmount())
.payAmount(payAmount)
.orgCode(refundDTO.getOrgCode())
.tenantId(refundDTO.getTenantId())
.build());
// 更新单据模型为已退款,并更新退款时间
if (refundResultDTO.isSuccess()) {
// 退款支付单改为退款成功
payOrderDomainService.refundSuccess(TpRefundSuccessDTO.builder()
.refundPayOrderNo(refundPayOrder.getPayOrderNo())
.refundTime(refundResultDTO.getRefundTime())
.tenantId(refundDTO.getTenantId()).build());
if (StringUtils.equals(refundDTO.getPayType(), TpPayTypeEnum.ALIPAY.getCode())) {
// 发送退款成功消息推进流程
BaseMessageEntity messageEntity = buildRefundSuccessMessage(refundPayOrder.getOrderNo(), refundPayOrder.getPayOrderNo(),
refundDTO.getRefundBizNo(), refundDTO.getRefundBizType(), refundDTO.getTenantId());
LogUtil.info("发送支付宝退款成功的消息,消息体为:{}", JSONUtil.toJsonStr(messageEntity));
messageClient.send(messageClient.getMessageTopic(), MessageConstants.EVENT_CODE_TRANS_REFUND_SUCCESS, messageEntity);
}
}
}, payRefundThreadPool).exceptionally(ex -> {
LogUtil.error("退款失败,入参为:{},异常堆栈信息:{}", JSONUtil.toJsonStr(refundDTO), ex);
throw new TpTradeCoreException(TpTradeCoreErrorCode.REFUND_ERROR);
});
return TpResult.success(null);
}
@Override
public TpResult<TpQueryRefundResultVO> queryRefundResult(TpQueryRefundResultDTO dto) {
TpRefundResultDTO refundResultDTO = payOrderDomainService.queryRefundResult(dto);
return TpResult.success(BeanUtil.copyProperties(refundResultDTO, TpQueryRefundResultVO.class));
}
@Override
public TpResult<List<TpPayOrderDTO>> queryPayOrderList(TpPayOrderQueryDTO queryDTO) {
List<TpPayOrder> payOrders = payOrderDomainService.queryPayOrderList(queryDTO);
return TpResult.success(payOrderConvert.convert2DTOList(payOrders));
}
@Override
public TpResult<Boolean> closePayOrder(TpPayOrderCloseDTO dto) {
List<TpPayOrder> payOrders = payOrderDomainService.queryPayOrderList(TpPayOrderQueryDTO.builder()
.payOrderNo(dto.getPayOrderNo())
.tenantId(dto.getTenantId())
.build());
if (CollectionUtils.isEmpty(payOrders)) {
LogUtil.error("不存在支付单,无法进行关单,入参为:{}", JSONUtil.toJsonStr(dto));
throw new TpTradeCoreException(PAY_ORDER_NOT_FOUND);
}
Assert.isTrue(payOrders.size() == 1, "同一个支付单号对应的支付单不能存在多个");
TpPayOrder payOrder = payOrders.get(0);
if (StringUtils.equals(payOrder.getStatus(), TpPayOrderStatusEnum.CLOSED.getCode())) {
LogUtil.error("当前支付单已关单,幂等处理,入参为:{}", payOrder.getStatus(), JSONUtil.toJsonStr(dto));
throw new TpTradeCoreException(IDEMPOTENT_REQUEST_ERROR);
}
if (StringUtils.equals(payOrder.getStatus(), TpPayOrderStatusEnum.PAYING.getCode())) {
Boolean res = payOrderDomainService.closePayOrder(dto);
return TpResult.success(res);
}
// 其他状态无法关单, 直接返回成功
return TpResult.success(Boolean.TRUE);
}
@Override
public TpResult<Boolean> paidOffline(TpPaidOfflineDTO paidOfflineDTO) {
// 参数校验
Assert.notNull(paidOfflineDTO, "入参不能为空");
Assert.hasText(paidOfflineDTO.getOrderNo(), "订单编号不能为空");
Assert.hasText(paidOfflineDTO.getBizType(), "业务类型不能为空");
Assert.hasText(paidOfflineDTO.getOperatorNo(), "操作员编号不能为空");
Assert.hasText(paidOfflineDTO.getPayAmount(), "支付金额不能为空");
Assert.hasText(paidOfflineDTO.getTenantId(), "租户id不能为空");
// 业务校验
bizCheck(paidOfflineDTO);
TpOrder order = orderDomainService.getOrder(paidOfflineDTO.getTenantId(), null, paidOfflineDTO.getOrderNo(), Lists.newArrayList(TpOrderModulesEnum.ORDER_PLACER));
if (order == null) {
LogUtil.error("线下标记支付成功失败,原因为订单不存在,入参为:{}", JSONUtil.toJsonStr(paidOfflineDTO));
throw new TpTradeCoreException(ORDER_NOT_FOUND, ORDER_NOT_FOUND.getDesc());
}
// 生成新的支付单,线下支付
paidOfflineDTO.setPlacerNo(order.getOrderPlacer().getPlacerNo());
paidOfflineDTO.setPlacerName(order.getOrderPlacer().getPlacerName());
TpPayOrder payOrder = buildOfflinePayOrder(paidOfflineDTO);
// 持久化
payOrderDomainService.createPayOrder(payOrder);
return TpResult.success(true);
}
@Override
public TpResult<Boolean> reschedulePaidSuccess(TpReschedulePaidSuccessDTO reschedulePaidSuccessDTO) {
// 参数校验
Assert.notNull(reschedulePaidSuccessDTO, "入参不能为空");
Assert.hasText(reschedulePaidSuccessDTO.getOriginalOrderNo(), "改签订单对应的原始订单号不能为空");
Assert.hasText(reschedulePaidSuccessDTO.getOrderNo(), "改签订单编号不能为空");
Assert.hasText(reschedulePaidSuccessDTO.getPayAmount(), "支付金额不能为空");
Assert.hasText(reschedulePaidSuccessDTO.getTenantId(), "租户id不能为空");
// 幂等处理
List<TpPayOrder> paidOrders = payOrderDomainService.queryPayOrderList(TpPayOrderQueryDTO.builder()
.tenantId(reschedulePaidSuccessDTO.getTenantId())
.orderNos(Lists.newArrayList(reschedulePaidSuccessDTO.getOrderNo(), reschedulePaidSuccessDTO.getOriginalOrderNo()))
.targetStatusList(Lists.newArrayList(TpPayOrderStatusEnum.PAID.getCode()))
.build());
if (CollectionUtils.isEmpty(paidOrders)) {
LogUtil.error("改签订单对应的原始订单未支付,无法进行改签,入参为:{}", JSONUtil.toJsonStr(reschedulePaidSuccessDTO));
throw new TpTradeCoreException(PAY_ORDER_NOT_FOUND, "改签订单对应的原始订单未支付,无法进行改签");
}
boolean existReschedulePayOrder = paidOrders.stream()
.anyMatch(o -> StringUtils.equals(o.getOrderNo(), reschedulePaidSuccessDTO.getOrderNo()));
if (existReschedulePayOrder) {
LogUtil.error("已经生成当前改签订单对应的支付单,幂等处理,入参为:{}", JSONUtil.toJsonStr(reschedulePaidSuccessDTO));
throw new TpTradeCoreException(IDEMPOTENT_REQUEST_ERROR, IDEMPOTENT_REQUEST_ERROR.getDesc());
}
// 改签订单对应的原始订单的已支付的支付单
TpPayOrder originalOrderPayOrder = paidOrders.get(0);
TpPayOrder reschedulePayOrder = buildReschedulePayOrder(originalOrderPayOrder, reschedulePaidSuccessDTO);
// 持久化
payOrderDomainService.createPayOrder(reschedulePayOrder);
return TpResult.success(true);
}
private void bizCheck(TpPaidOfflineDTO paidOfflineDTO) {
List<TpPayOrder> positivePayOrders = payOrderDomainService.queryPayOrderList(TpPayOrderQueryDTO.builder()
.tenantId(paidOfflineDTO.getTenantId())
.bizNo(paidOfflineDTO.getOrderNo() + paidOfflineDTO.getBizType())
.targetStatusList(Lists.newArrayList(TpPayOrderStatusEnum.PAYING.getCode(), TpPayOrderStatusEnum.PAID.getCode()))
.build());
if (CollectionUtils.isNotEmpty(positivePayOrders)) {
List<TpPayOrder> paidPayOrders = positivePayOrders.stream()
.filter(p -> StringUtils.equals(p.getStatus(), TpPayOrderStatusEnum.PAID.getCode()))
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(paidPayOrders)) {
List<TpPayOrder> offlinePaidOrder = paidPayOrders.stream()
.filter(p -> StringUtils.equals(p.getPayType(), TpPayTypeEnum.OFFLINE_PAY.getCode()))
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(offlinePaidOrder)) {
LogUtil.error("幂等处理,入参为:{}", JSONUtil.toJsonStr(paidOfflineDTO));
throw new TpTradeCoreException(IDEMPOTENT_OFFLINE_PAID_REQUEST_ERROR, IDEMPOTENT_OFFLINE_PAID_REQUEST_ERROR.getDesc());
}
LogUtil.error("用户的支付单已经在线上进行支付,无法线下确认支付,入参为:{}", JSONUtil.toJsonStr(paidOfflineDTO));
throw new TpTradeCoreException(FOUND_USER_ONLINE_PAID_PAY_ORDER, FOUND_USER_ONLINE_PAID_PAY_ORDER.getDesc());
}
// 关闭所有该bizNo对应的在途的支付单
List<String> payOrderNos = positivePayOrders.stream().map(TpPayOrder::getPayOrderNo).collect(Collectors.toList());
payOrderDomainService.batchClosePayOrder(payOrderNos, paidOfflineDTO.getTenantId());
}
}
private void paramCheck(TpPreparePayDTO preparePayDTO) {
TpPayTypeEnum payTypeEnum = TpPayTypeEnum.getByCode(preparePayDTO.getCreateDTO().getPayType());
if (payTypeEnum == null) {
LogUtil.error("支付方式不存在,入参为:{}", JSONUtil.toJsonStr(preparePayDTO));
throw new TpTradeCoreException(TpTradeCoreErrorCode.PAY_TYPE_NOT_EXIST);
}
TpPaySceneEnum paySceneEnum = TpPaySceneEnum.getByCode(preparePayDTO.getCreateDTO().getPayScene());
if (paySceneEnum == null) {
LogUtil.error("支付场景不存在,入参为:{}", JSONUtil.toJsonStr(preparePayDTO));
throw new TpTradeCoreException(PAY_SCENE_NOT_EXIST);
}
if (paySceneEnum == TpPaySceneEnum.ALI_MINI_PROGRAM || paySceneEnum == TpPaySceneEnum.WECHAT_MINI_PROGRAM
|| paySceneEnum == TpPaySceneEnum.WECHAT_OFFICIAL_ACCOUNT) {
if (StringUtils.isBlank(preparePayDTO.getAppId())) {
LogUtil.error("小程序或JSAPI支付场景appId不能为空入参为{}", JSONUtil.toJsonStr(preparePayDTO));
throw new TpTradeCoreException(ILLEGAL_PARAMS, ILLEGAL_PARAMS.getDesc());
}
}
}
private TpPayOrder createPayOrder(TpPreparePayDTO preparePayDTO) {
// 查询在途的支付单
List<TpPayOrder> payOrders = queryPayOrderList(preparePayDTO);
// 业务校验
bizCheck(payOrders, preparePayDTO.getCreateDTO().getBizNo());
// 生成支付单
TpPayOrder payOrder = buildPayOrder(preparePayDTO);
if (CollectionUtils.isEmpty(payOrders)) {
payOrder.setPaySequence(DEFAULT_PAY_ORDER_SEQUENCE);
payOrderDomainService.createPayOrder(payOrder);
return payOrder;
}
// 过滤出在途的支付单
List<TpPayOrder> inProgressPayOrders = payOrders.stream()
.filter(inProgressPayOrder -> StringUtils.equals(inProgressPayOrder.getStatus(), TpPayOrderStatusEnum.PAYING.getCode()))
.collect(Collectors.toList());
// 计算出最新的paySequence
List<Long> sortedPaySequenceList = payOrders.stream()
.sorted(Comparator.comparing(TpPayOrder::getPaySequence))
.map(TpPayOrder::getPaySequence)
.collect(Collectors.toList());
Long curMaxPaySequence = sortedPaySequenceList.get(sortedPaySequenceList.size() - 1);
Long newPaySequence = curMaxPaySequence + 1;
// 持久化支付单
if (CollectionUtils.isEmpty(inProgressPayOrders)) {
payOrder.setPaySequence(newPaySequence);
payOrderDomainService.createPayOrder(payOrder);
return payOrder;
}
// 用户不是第一次拉起收银台,有未支付完成的支付单
TpPayOrder unFinishedPayOrder = inProgressPayOrders.get(0);
// 关闭旧的支付单,重新创建新的支付单
payOrder.setPaySequence(newPaySequence);
// 关单前的幂等支付校验
idempotentPaidCheckBeforeClosePayOrder(preparePayDTO, unFinishedPayOrder);
recreatePayOrder(unFinishedPayOrder.getPayOrderNo(), unFinishedPayOrder.getTenantId(), payOrder);
return payOrder;
}
private void idempotentPaidCheckBeforeClosePayOrder(TpPreparePayDTO preparePayDTO, TpPayOrder unFinishedPayOrder) {
try {
String platformOutTradeNo = preparePayDTO.getCreateDTO().getBizNo() + GlobalConstants.HORIZONTAL_LINE + unFinishedPayOrder.getPaySequence();
TpPayResultDTO payResultDTO = payTypeStrategyMap.get(TpPayTypeEnum.getByCode(unFinishedPayOrder.getPayType()))
.queryPayResult(new PayPlatformQueryResultDTO(platformOutTradeNo, null, null, preparePayDTO.getCreateDTO().getBizType(), unFinishedPayOrder.getPayScene(),
unFinishedPayOrder.getPayeeAccount().getAccount(), preparePayDTO.getCreateDTO().getOrgCode(), preparePayDTO.getTenantId()));
if (payResultDTO.isPaySuccess()) {
payOrderDomainService.paySuccess(TpPaySuccessDTO.builder()
.payOrderNo(unFinishedPayOrder.getPayOrderNo())
.outPayFlowId(payResultDTO.getOutPayFlowId())
.payTime(payResultDTO.getPayTime())
.tenantId(unFinishedPayOrder.getTenantId())
.build());
BaseMessageEntity messageEntity = buildPaySuccessMessage(unFinishedPayOrder.getOrderNo(), unFinishedPayOrder.getPayOrderNo(), unFinishedPayOrder.getBizType(),
payResultDTO.getPayTime(), unFinishedPayOrder.getTenantId());
messageClient.send(messageClient.getMessageTopic(), MessageConstants.EVENT_CODE_TRANS_PAY_SUCCESS, messageEntity);
LogUtil.info("查询支付结果后发现用户已支付但是当前支付单的状态未变更为已支付,发送支付成功消息成功,支付单号为:{}", unFinishedPayOrder.getPayOrderNo());
throw new TpTradeCoreException(DUPLICATE_PAY_REQUEST, DUPLICATE_PAY_REQUEST.getDesc());
}
} catch (Exception e) {
if (e instanceof TpTradeCoreException) {
TpTradeCoreException tradeCoreException = (TpTradeCoreException) e;
if (tradeCoreException.getErrorCode() == DUPLICATE_PAY_REQUEST) {
throw tradeCoreException;
}
}
LogUtil.error("预支付接口查询支付结果失败,降级处理,入参:{},异常堆栈:{}", JSONUtil.toJsonStr(preparePayDTO), e);
}
}
private BaseMessageEntity buildDelayMessageEntity(String payOrderNo, String tenantId) {
BaseMessageEntity baseMessageEntity = new BaseMessageEntity();
baseMessageEntity.setSource(MessageSysConstants.SOURCE_TRANS);
baseMessageEntity.setKey(payOrderNo);
baseMessageEntity.setSendTime(LocalDateTime.now());
PayOrderDelayMessageEntity delayMessageEntity = new PayOrderDelayMessageEntity();
delayMessageEntity.setPayOrderNo(payOrderNo);
delayMessageEntity.setTenantId(tenantId);
baseMessageEntity.setBody(JSONUtil.toJsonStr(delayMessageEntity));
return baseMessageEntity;
}
private String platformPrepay(TpPreparePayDTO preparePayDTO, Long paySequence) {
TpPayTypeEnum payTypeEnum = TpPayTypeEnum.getByCode(preparePayDTO.getCreateDTO().getPayType());
PayPlatformPreparePayDTO platformPrepayDTO = PayPlatformPreparePayDTO.builder()
.orderNo(preparePayDTO.getCreateDTO().getOrderNo())
.bizNo(preparePayDTO.getCreateDTO().getBizNo() + GlobalConstants.HORIZONTAL_LINE + paySequence)
.bizType(preparePayDTO.getCreateDTO().getBizType())
.orgCode(preparePayDTO.getCreateDTO().getOrgCode())
.buyerId(preparePayDTO.getBuyerId())
.appId(preparePayDTO.getAppId())
.payTitle(preparePayDTO.getCreateDTO().getPayTitle())
.payScene(preparePayDTO.getCreateDTO().getPayScene())
.payAmount(preparePayDTO.getCreateDTO().getPaymentAmount())
.returnUrl(preparePayDTO.getCreateDTO().getReturnUrl())
.userIp(preparePayDTO.getUserIp())
.payTimeout(LocalDateTimeUtil.of(preparePayDTO.getCreateDTO().getPayTimeout()))
.tenantId(preparePayDTO.getTenantId())
.build();
return payTypeStrategyMap.get(payTypeEnum).preparePay(platformPrepayDTO);
}
private TpPayOrder getPaidPayOrder(TpPayRefundDTO refundDTO) {
// 查询支付单,校验是否已经支付/进行退款幂等控制
TpPayOrderQueryDTO payOrderQueryDTO = TpPayOrderQueryDTO.builder()
.bizNos(Lists.newArrayList(refundDTO.getPayBizNo(), refundDTO.getRefundBizNo()))
.targetStatusList(Lists.newArrayList(TpPayOrderStatusEnum.PAID.getCode(), TpPayOrderStatusEnum.REFUND.getCode()))
.tenantId(refundDTO.getTenantId())
.build();
List<TpPayOrder> payOrders = payOrderDomainService.queryPayOrderList(payOrderQueryDTO);
if (CollectionUtils.isEmpty(payOrders)) {
LogUtil.error("不存在已支付的支付单,无法进行退款,入参为:{}", JSONUtil.toJsonStr(refundDTO));
throw new TpTradeCoreException(NOT_FOUND_PAID_PAY_ORDER);
}
List<TpPayOrder> paidOrders = payOrders.stream().filter(payOrder -> StringUtils.equals(payOrder.getStatus(), TpPayOrderStatusEnum.PAID.getCode()))
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(paidOrders)) {
LogUtil.error("不存在已支付的支付单,无法进行退款,入参为:{}", JSONUtil.toJsonStr(refundDTO));
throw new TpTradeCoreException(NOT_FOUND_PAID_PAY_ORDER);
}
if (paidOrders.size() > 1) {
LogUtil.error("同一个业务单号出现了多笔支付成功的支付单,请及时排查,入参为:{}", JSONUtil.toJsonStr(refundDTO));
throw new TpTradeCoreException(DUPLICATED_PAID_PAY_ORDER, DUPLICATED_PAID_PAY_ORDER.getDesc());
}
List<TpPayOrder> refundPayOrders = payOrders.stream().filter(payOrder -> StringUtils.equals(payOrder.getStatus(), TpPayOrderStatusEnum.REFUND.getCode()))
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(refundPayOrders)) {
LogUtil.error("当前支付单已退款,无法进行退款,幂等处理,入参为:{}", JSONUtil.toJsonStr(refundDTO));
throw new TpTradeCoreException(IDEMPOTENT_REQUEST_ERROR);
}
return paidOrders.get(0);
}
private void refundIdempotentControl(TpPayRefundDTO dto) {
TpRefundResultDTO refundResult = payOrderDomainService.queryRefundResult(BeanUtil.copyProperties(dto, TpQueryRefundResultDTO.class));
if (refundResult.isSuccess()) {
LogUtil.info("用户退款处理,退票申请单号为:{},入参为:{},查询到当前退票申请单已退款,进行幂等处理", dto.getRefundBizNo(), JSONUtil.toJsonStr(dto));
throw new TpTradeCoreException(IDEMPOTENT_REQUEST_ERROR);
}
}
private TpPayOrder createRefundPayOrder(TpPayOrder paidPayOrder, String refundBizNo, String refundBizType,
TpMoney refundAmount, TpMoney chargeAmount, String orgCode, String tenantId) {
List<TpPayOrder> refundPayOrders = payOrderDomainService.queryPayOrderList(TpPayOrderQueryDTO.builder().bizNo(refundBizNo).tenantId(tenantId).build());
if (CollectionUtils.isNotEmpty(refundPayOrders)) {
Assert.isTrue(refundPayOrders.size() == 1, "同一个退票申请单号对应的退款支付单不能存在多个");
return refundPayOrders.get(0);
}
// 创建退款支付单
String payOrderNo = sequenceClient.generatePayOrderNo();
String billNo = sequenceClient.generateBillOrderNo();
String chargeNo = sequenceClient.generateChargeOrderNo();
TpPayOrder tpPayOrder = payOrderConvert.buildRefundPayOrder(paidPayOrder, refundAmount, chargeAmount, refundBizNo, refundBizType, payOrderNo, billNo, chargeNo, orgCode);
payOrderDomainService.createPayOrder(tpPayOrder);
return tpPayOrder;
}
private TpPayOrder createRefundSuccessPayOrder(TpPayOrder paidPayOrder, String refundBizNo, String refundBizType,
TpMoney refundAmount, TpMoney chargeAmount, String orgCode, String tenantId) {
// 创建退款支付单
String payOrderNo = sequenceClient.generatePayOrderNo();
String billNo = sequenceClient.generateBillOrderNo();
String chargeNo = sequenceClient.generateChargeOrderNo();
TpPayOrder tpPayOrder = payOrderConvert.buildRefundSuccessPayOrder(paidPayOrder, refundAmount, chargeAmount, refundBizNo, refundBizType, payOrderNo, billNo, chargeNo, orgCode);
payOrderDomainService.createPayOrder(tpPayOrder);
return tpPayOrder;
}
private List<TpPayOrder> queryPayOrderList(TpPreparePayDTO preparePayDTO) {
TpPayOrderQueryDTO queryDTO = TpPayOrderQueryDTO.builder()
.bizNo(preparePayDTO.getCreateDTO().getBizNo())
.tenantId(preparePayDTO.getTenantId())
.build();
return payOrderDomainService.queryPayOrderList(queryDTO);
}
private void bizCheck(List<TpPayOrder> payOrders, String bizNo) {
if (CollectionUtils.isNotEmpty(payOrders)) {
boolean existPaidOrder = payOrders
.stream()
.anyMatch(tpPayOrder -> StringUtils.equals(tpPayOrder.getStatus(), TpPayOrderStatusEnum.PAID.getCode()));
if (existPaidOrder) {
throw new TpTradeCoreException(DUPLICATE_PAY_REQUEST, DUPLICATE_PAY_REQUEST.getDesc());
}
}
List<TpPayOrder> payingPayOrders = payOrders.stream()
.filter(payOrder -> StringUtils.equals(TpPayOrderStatusEnum.PAYING.getCode(), payOrder.getStatus()))
.collect(Collectors.toList());
// 同一个订单至多对应一笔支付中PAYING)状态的支付单据
if (CollectionUtils.isNotEmpty(payingPayOrders) && payingPayOrders.size() > 1) {
LogUtil.error("业务数据异常,发现多笔支付单,订单号:{}", bizNo);
throw new TpTradeCoreException(DUPLICATED_UNPAID_PAY_ORDER, DUPLICATED_UNPAID_PAY_ORDER.getDesc());
}
}
private TpPayOrder buildPayOrder(TpPreparePayDTO preparePayDTO) {
// 用户第一次拉起收银台,还没有对应的支付单,去创建支付单
String payOrderNo = sequenceClient.generatePayOrderNo();
String billNo = sequenceClient.generateBillOrderNo();
String orgCode = preparePayDTO.getCreateDTO().getOrgCode();
String tenantId = preparePayDTO.getCreateDTO().getTenantId();
return payOrderConvert.convertPrepayDTO2Domain(preparePayDTO, payOrderNo, billNo, orgCode, preparePayDTO.getCreateDTO().getPayTimeout(), tenantId);
}
private TpPayOrder buildOfflinePayOrder(TpPaidOfflineDTO paidOfflineDTO) {
// 用户第一次拉起收银台,还没有对应的支付单,去创建支付单
String payOrderNo = sequenceClient.generatePayOrderNo();
String billNo = sequenceClient.generateBillOrderNo();
String tenantId = paidOfflineDTO.getTenantId();
return payOrderConvert.buildOfflinePayOrder(paidOfflineDTO, payOrderNo, billNo, System.currentTimeMillis() + 86400000, tenantId);
}
private TpPayOrder buildReschedulePayOrder(TpPayOrder originalPayOrder, TpReschedulePaidSuccessDTO reschedulePaidSuccessDTO) {
// 用户第一次拉起收银台,还没有对应的支付单,去创建支付单
String payOrderNo = sequenceClient.generatePayOrderNo();
String billNo = sequenceClient.generateBillOrderNo();
String tenantId = reschedulePaidSuccessDTO.getTenantId();
return payOrderConvert.buildReschedulePayOrder(reschedulePaidSuccessDTO, originalPayOrder, payOrderNo, billNo, System.currentTimeMillis() + 86400000, tenantId);
}
private void recreatePayOrder(String oldPayOrderNo, String tenantId, TpPayOrder payOrder) {
payOrderDomainService.closePayOrder(TpPayOrderCloseDTO
.builder()
.payOrderNo(oldPayOrderNo)
.tenantId(tenantId)
.build());
payOrderDomainService.createPayOrder(payOrder);
}
private BaseMessageEntity buildRefundSuccessMessage(String orderNo, String refundPayOrderNo, String refundBizNo, String bizType, String tenantId) {
BaseMessageEntity baseMessageEntity = new BaseMessageEntity();
baseMessageEntity.setSource(MessageSysConstants.SOURCE_TRANS);
baseMessageEntity.setKey(refundBizNo);
baseMessageEntity.setSendTime(LocalDateTime.now());
RefundSuccessMessageEntity messageEntity = new RefundSuccessMessageEntity();
messageEntity.setRefundPayOrderNo(refundPayOrderNo);
messageEntity.setOrderNo(orderNo);
messageEntity.setRefundBizNo(refundBizNo);
messageEntity.setBizType(bizType);
messageEntity.setTenantId(tenantId);
baseMessageEntity.setBody(JSONUtil.toJsonStr(messageEntity));
return baseMessageEntity;
}
private BaseMessageEntity buildPaySuccessMessage(String orderNo, String payOrderNo, String bizType, Long payTime, String tenantId) {
BaseMessageEntity messageEntity = new BaseMessageEntity();
messageEntity.setKey(payOrderNo);
messageEntity.setSource(MessageSysConstants.SOURCE_TRANS);
messageEntity.setSendTime(LocalDateTime.now());
PaySuccessMessageEntity payOrderSuccessEntity = new PaySuccessMessageEntity();
payOrderSuccessEntity.setPayOrderNo(payOrderNo);
payOrderSuccessEntity.setOrderNo(orderNo);
payOrderSuccessEntity.setBizType(bizType);
payOrderSuccessEntity.setPayTime(payTime);
payOrderSuccessEntity.setTenantId(tenantId);
String body = JSONUtil.toJsonStr(payOrderSuccessEntity);
messageEntity.setBody(body);
return messageEntity;
}
}

View File

@@ -0,0 +1,27 @@
package com.deepinnet.tptradecore.biz.strategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
/**
* <p>
* 订单状态推进策略
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
public interface TpOrderPushStatusStrategy {
/**
* 当前订单推进策略支持的策略状态
* @return 策略状态
*/
TpOrderPushStatusEnum statusStrategy();
/**
* 订单推进
*/
void pushOrderStatus(TpOrderPushStatusStrategyDTO dto);
}

View File

@@ -0,0 +1,41 @@
package com.deepinnet.tptradecore.biz.strategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 订单已改签,不包含退款
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderRescheduleNoRefundStrategyImpl implements TpOrderPushStatusStrategy {
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_RESCHEDULE_NO_REFUND;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.RESCHEDULE_NOT_REFUND);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,43 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 全部过期
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderAllExpireStrategyImpl implements TpOrderPushStatusStrategy {
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ALL_EXPIRE;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
// 推进到全部过期
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ALL_EXPIRE);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,42 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 全部退款
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderAllRefundStrategyImpl implements TpOrderPushStatusStrategy {
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ALL_REFUND_PUSH_STATUS;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ALL_REFUND);
pushStatus.setTenantId(dto.getTenantId());
// 推进到全部退款(领域内部实现订单及状态流转校验)
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,43 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 全部核销,不存在退款
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderAllVerifiedStrategyImpl implements TpOrderPushStatusStrategy {
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ALL_VERIFIED_PUSH_STATUS;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.FINISH_NOT_REFUND);
pushStatus.setTenantId(dto.getTenantId());
// 推进到全部核销(领域内部实现订单及状态流转校验)
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,61 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 订单取消审核通过
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderCancelAuditedStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderCancelAuditedStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_CANCEL_AUDITED;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
// 查询订单
TpOrder order = tpOrderDomainService.getOrder(dto.getTenantId(), null, dto.getOrderNo(), null);
// 审核取消订单 [取消订单待审核] 状态下
if (ObjectUtil.notEqual(TpOrderStatusEnum.ORDER_CANCEL_AUDITING.getStatus(), order.getStatus())) {
LogUtil.error(LOGGER, "订单状态异常, 当前订单:{}, 状态: {}", order.getOrderNo(), order.getStatus());
throw new TpTradeCoreException(TpTradeCoreErrorCode.ORDER_STATUS_ERROR);
}
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_CANCEL_AUDITED);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,76 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpAuditOrChangePriceBizTypeEnum;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderChargeRecord;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.apache.commons.compress.utils.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.util.List;
/**
* <p>
* 订单取消待审核
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderCancelNeedAuditStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderCancelNeedAuditStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Resource
private TransactionTemplate transactionTemplate;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_CANCEL_AUDITING;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
// 查询订单
TpOrder order = tpOrderDomainService.getOrder(dto.getTenantId(), null, dto.getOrderNo(), null);
// 取消订单只可在行程 [行程中] 状态及之前的状态可取消
if (order.getStatus().compareTo(TpOrderPushStatusEnum.ORDER_TRIP_STARTED.getStatus()) >= 0) {
LogUtil.error(LOGGER, "订单状态异常, 当前订单:{}, 状态: {}", order.getOrderNo(), order.getStatus());
throw new TpTradeCoreException(TpTradeCoreErrorCode.ORDER_STATUS_ERROR);
}
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_CANCEL_AUDITING);
pushStatus.setCurrentStatus(order.getStatus());
pushStatus.setTenantId(dto.getTenantId());
List<TpOrderChargeRecord> orderChargeRecords = Lists.newArrayList();
transactionTemplate.executeWithoutResult(e -> {
// 取消订单状态推进
tpOrderDomainService.changeOrderStatus(pushStatus);
});
}
}

View File

@@ -0,0 +1,62 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 订单取消待支付
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderCancelNeedPayStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderCancelNeedPayStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_CANCEL_NEED_PAY;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
// 查询订单
TpOrder order = tpOrderDomainService.getOrder(dto.getTenantId(), null, dto.getOrderNo(), null);
// 取消订单待支付需要在 [取消订单审核通过] && 无需审核时状态需在[行程中]之前 状态下
if (ObjectUtil.notEqual(TpOrderStatusEnum.ORDER_CANCEL_AUDITED.getStatus(), order.getStatus())
&& order.getStatus().compareTo(TpOrderPushStatusEnum.ORDER_TRIP_STARTED.getStatus()) >= 0) {
LogUtil.error(LOGGER, "订单状态异常, 当前订单:{}, 状态: {}", order.getOrderNo(), order.getStatus());
throw new TpTradeCoreException(TpTradeCoreErrorCode.ORDER_STATUS_ERROR);
}
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_CANCEL_NEED_PAY);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,63 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 订单取消待退款
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderCancelNeedRefundStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderCancelNeedRefundStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_CANCEL_REFUNDING;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
// 查询订单
TpOrder order = tpOrderDomainService.getOrder(dto.getTenantId(), null, dto.getOrderNo(), null);
// 无需审核时 取消订单待退款只可在行程 [行程中] 状态及之前的状态可取消
// 需要审核时 取消订单待退款只可在 [订单取消审核通过] 下推进
if (ObjectUtil.notEqual(TpOrderStatusEnum.ORDER_CANCEL_AUDITED.getStatus(), order.getStatus())
&& order.getStatus().compareTo(TpOrderPushStatusEnum.ORDER_TRIP_STARTED.getStatus()) >= 0) {
LogUtil.error(LOGGER, "订单状态异常, 当前订单:{}, 状态: {}", order.getOrderNo(), order.getStatus());
throw new TpTradeCoreException(TpTradeCoreErrorCode.ORDER_STATUS_ERROR);
}
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_CANCEL_REFUNDING);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,61 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 订单取消已支付
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderCancelPaidStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderCancelPaidStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_CANCEL_PAID;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
// 查询订单
TpOrder order = tpOrderDomainService.getOrder(dto.getTenantId(), null, dto.getOrderNo(), null);
// 需要在 [取消订单待支付] 状态下
if (ObjectUtil.notEqual(TpOrderStatusEnum.ORDER_CANCEL_NEED_PAY.getStatus(), order.getStatus())) {
LogUtil.error(LOGGER, "订单状态异常, 当前订单:{}, 状态: {}", order.getOrderNo(), order.getStatus());
throw new TpTradeCoreException(TpTradeCoreErrorCode.ORDER_STATUS_ERROR);
}
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_CANCEL_PAID);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,61 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 订单取消已退款
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderCancelRefundedStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderCancelRefundedStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_CANCEL_REFUNDED;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
// 查询订单
TpOrder order = tpOrderDomainService.getOrder(dto.getTenantId(), null, dto.getOrderNo(), null);
// 取消订单已退款只可在 [取消订单待退款] 状态下推进
if (ObjectUtil.notEqual(TpOrderStatusEnum.ORDER_CANCEL_REFUNDING.getStatus(), order.getStatus())) {
LogUtil.error(LOGGER, "订单状态异常, 当前订单:{}, 状态: {}", order.getOrderNo(), order.getStatus());
throw new TpTradeCoreException(TpTradeCoreErrorCode.ORDER_STATUS_ERROR);
}
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_CANCEL_REFUNDED);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,62 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 订单已取消
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderCancelStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderCancelStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_CANCELED;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
// 查询订单
TpOrder order = tpOrderDomainService.getOrder(dto.getTenantId(), null, dto.getOrderNo(), null);
// 需要在 [取消订单审核通过] 状态下
// 无需审核 [行程中] 及之前状态可推进到订单已取消
if (ObjectUtil.notEqual(TpOrderStatusEnum.ORDER_CANCEL_AUDITED.getStatus(), order.getStatus())
&& order.getStatus().compareTo(TpOrderPushStatusEnum.ORDER_TRIP_STARTED.getStatus()) >= 0) {
LogUtil.error(LOGGER, "订单状态异常, 当前订单:{}, 状态: {}", order.getOrderNo(), order.getStatus());
throw new TpTradeCoreException(TpTradeCoreErrorCode.ORDER_STATUS_ERROR);
}
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_CANCELED);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,61 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 订单变更审核通过
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderChangeAuditedStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderChangeAuditedStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_CHANGE_AUDITED;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
// 查询订单
TpOrder order = tpOrderDomainService.getOrder(dto.getTenantId(), null, dto.getOrderNo(), null);
// 审核变更订单 [变更订单待审核] 状态下
if (ObjectUtil.notEqual(TpOrderStatusEnum.ORDER_CHANGE_AUDITING.getStatus(), order.getStatus())) {
LogUtil.error(LOGGER, "订单状态异常, 当前订单:{}, 状态: {}", order.getOrderNo(), order.getStatus());
throw new TpTradeCoreException(TpTradeCoreErrorCode.ORDER_STATUS_ERROR);
}
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_CHANGE_AUDITED);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,61 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 订单变更待审核
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderChangeNeedAuditStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderChangeNeedAuditStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_CHANGE_AUDITING;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
// 查询订单
TpOrder order = tpOrderDomainService.getOrder(dto.getTenantId(), null, dto.getOrderNo(), null);
// 判断当前状态仅为 [已发车] 及之前状态可变更
if (order.getStatus().compareTo(TpOrderPushStatusEnum.ORDER_TRIP_STARTED.getStatus()) >= 0) {
LogUtil.error(LOGGER, "订单状态异常, 当前订单:{}, 状态: {}", order.getOrderNo(), order.getStatus());
throw new TpTradeCoreException(TpTradeCoreErrorCode.ORDER_STATUS_ERROR);
}
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_CHANGE_AUDITING);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,61 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 订单已驳回
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderConfirmRejectStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderConfirmRejectStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_REJECTED;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
// 查询订单
TpOrder order = tpOrderDomainService.getOrder(dto.getTenantId(), null, dto.getOrderNo(), null);
// 判断当前状态是否为 [订单待确认]
if (ObjectUtil.notEqual(TpOrderStatusEnum.ORDER_NEED_CONFIRM.getStatus(), order.getStatus())) {
LogUtil.error(LOGGER, "订单状态异常, 当前订单:{}, 状态: {}", order.getOrderNo(), order.getStatus());
throw new TpTradeCoreException(TpTradeCoreErrorCode.ORDER_STATUS_ERROR);
}
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_REJECTED);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,61 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 订单已确认
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderConfirmedStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderConfirmedStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_ALREADY_CONFIRM;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
// 查询订单
TpOrder order = tpOrderDomainService.getOrder(dto.getTenantId(), null, dto.getOrderNo(), null);
// 判断当前状态是否为 [订单待确认]
if (ObjectUtil.notEqual(TpOrderStatusEnum.ORDER_NEED_CONFIRM.getStatus(), order.getStatus())) {
LogUtil.error(LOGGER, "订单状态异常, 当前订单:{}, 状态: {}", order.getOrderNo(), order.getStatus());
throw new TpTradeCoreException(TpTradeCoreErrorCode.ORDER_STATUS_ERROR);
}
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_CONFIRMED);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,63 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 订金待支付
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderDepositNeedPayStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderDepositNeedPayStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_DEPOSIT_NEED_PAY;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
// 查询订单
TpOrder order = tpOrderDomainService.getOrder(dto.getTenantId(), null, dto.getOrderNo(), null);
// 判断当前状态是否为 [初始化] || [订单已确认]
if (ObjectUtil.notEqual(TpOrderStatusEnum.INIT.getStatus(), order.getStatus())
&& ObjectUtil.notEqual(TpOrderStatusEnum.ORDER_CONFIRMED.getStatus(), order.getStatus())
&& ObjectUtil.notEqual(TpOrderStatusEnum.ORDER_CHANGE_AUDITED.getStatus(), order.getStatus())) {
LogUtil.error(LOGGER, "订单状态异常, 当前订单:{}, 状态: {}", order.getOrderNo(), order.getStatus());
throw new TpTradeCoreException(TpTradeCoreErrorCode.ORDER_STATUS_ERROR);
}
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_DEPOSIT_NEED_PAY);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,75 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
/**
* <p>
* 订金已支付
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderDepositPayedStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderDepositPayedStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Resource
private TransactionTemplate transactionTemplate;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_DEPOSIT_PAID;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
// 查询订单
TpOrder order = tpOrderDomainService.getOrder(dto.getTenantId(), null, dto.getOrderNo(), null);
// 判断当前状态是否为 [订金待支付]
if (ObjectUtil.notEqual(TpOrderStatusEnum.ORDER_DEPOSIT_NEED_PAY.getStatus(), order.getStatus())) {
LogUtil.error(LOGGER, "订单状态异常, 当前订单:{}, 状态: {}", order.getOrderNo(), order.getStatus());
throw new TpTradeCoreException(TpTradeCoreErrorCode.ORDER_STATUS_ERROR);
}
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_DEPOSIT_PAID);
pushStatus.setPayTime(dto.getPayTime());
pushStatus.setTenantId(dto.getTenantId());
// 同时更新订金订单状态
transactionTemplate.executeWithoutResult(e -> {
// 订单更改为已支付
tpOrderDomainService.changeOrderStatus(pushStatus);
// 订金更改为已支付
tpOrderDomainService.updateDepositPaidOrderByOriginalOrderNo(order.getOriginalOrderNo(), dto.getTenantId());
});
}
}

View File

@@ -0,0 +1,61 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 订金超时未支付
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderDepositTimeoutStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderDepositTimeoutStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_DEPOSIT_TIMEOUT;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
// 查询订单
TpOrder order = tpOrderDomainService.getOrder(dto.getTenantId(), null, dto.getOrderNo(), null);
// 判断当前状态是否为 [订金待支付]
if (ObjectUtil.notEqual(TpOrderStatusEnum.ORDER_DEPOSIT_NEED_PAY.getStatus(), order.getStatus())) {
LogUtil.error(LOGGER, "订单状态异常, 当前订单:{}, 状态: {}", order.getOrderNo(), order.getStatus());
throw new TpTradeCoreException(TpTradeCoreErrorCode.ORDER_STATUS_ERROR);
}
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_DEPOSIT_TIMEOUT);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,53 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 已派车
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderDispatchedStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderDispatchedStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_DISPATCHED;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_DISPATCHED);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,53 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 订单过期,推进订单状态
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderExpireStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderExpireStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_EXPIRE_PUSH_STATUS;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_TIMEOUT);
pushStatus.setTenantId(dto.getTenantId());
// 推进订单过期
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,61 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 订单待确认
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderNeedConfirmStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderNeedConfirmStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_NEED_CONFIRM;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
// 查询订单
TpOrder order = tpOrderDomainService.getOrder(dto.getTenantId(), null, dto.getOrderNo(), null);
// 判断当前状态是否为 [初始化]
if (ObjectUtil.notEqual(TpOrderStatusEnum.INIT.getStatus(), order.getStatus())) {
LogUtil.error(LOGGER, "订单状态异常, 当前订单:{}, 状态: {}", order.getOrderNo(), order.getStatus());
throw new TpTradeCoreException(TpTradeCoreErrorCode.ORDER_STATUS_ERROR);
}
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_NEED_CONFIRM);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,52 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushPaidStatusStrategyDTO;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 待派车
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderNeedDispatchStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderNeedDispatchStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.ORDER_NEED_DISPATCH;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.ORDER_NEED_DISPATCH);
pushStatus.setTenantId(dto.getTenantId());
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

View File

@@ -0,0 +1,59 @@
package com.deepinnet.tptradecore.biz.strategy.impl;
import cn.hutool.core.util.ObjectUtil;
import com.deepinnet.tp.common.lang.util.LogUtil;
import com.deepinnet.tptradecore.biz.strategy.TpOrderPushStatusStrategy;
import com.deepinnet.tptradecore.common.dto.order.TpOrderPushStatusStrategyDTO;
import com.deepinnet.tptradecore.common.enums.order.TpOrderPushStatusEnum;
import com.deepinnet.tptradecore.common.error.TpTradeCoreErrorCode;
import com.deepinnet.tptradecore.common.exception.TpTradeCoreException;
import com.deepinnet.tptradecore.core.model.enums.order.TpOrderStatusEnum;
import com.deepinnet.tptradecore.core.model.order.TpOrder;
import com.deepinnet.tptradecore.core.model.order.TpOrderPushStatus;
import com.deepinnet.tptradecore.core.service.order.TpOrderDomainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* <p>
* 待支付
* </p>
*
* @author chenjiaju
* @since 2023/9/1
*/
@Component
public class TpOrderNeedPayStrategyImpl implements TpOrderPushStatusStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(TpOrderNeedPayStrategyImpl.class);
@Resource
private TpOrderDomainService tpOrderDomainService;
@Override
public TpOrderPushStatusEnum statusStrategy() {
return TpOrderPushStatusEnum.NEED_PAY_PUSH_STATUS;
}
@Override
public void pushOrderStatus(TpOrderPushStatusStrategyDTO dto) {
TpOrder order = tpOrderDomainService.getOrder(dto.getTenantId(), null, dto.getOrderNo(), null);
if (ObjectUtil.notEqual(order.getStatus(), TpOrderStatusEnum.INIT.getStatus())) {
LogUtil.error(LOGGER, "订单状态流转失败, 订单号: {}, 当前状态为: {}, 无法更改为目标值: {}", dto, order.getStatus(), TpOrderStatusEnum.INIT.getStatus());
throw new TpTradeCoreException(TpTradeCoreErrorCode.ORDER_STATUS_CHANGE_ERROR);
}
TpOrderPushStatus pushStatus = new TpOrderPushStatus();
pushStatus.setOrderNo(dto.getOrderNo());
pushStatus.setStatusEnum(TpOrderStatusEnum.PENDING_PAY);
pushStatus.setTenantId(dto.getTenantId());
// 推进到待支付
tpOrderDomainService.changeOrderStatus(pushStatus);
}
}

Some files were not shown because too many files have changed in this diff Show More