初始化代码

This commit is contained in:
lulz1 2024-02-01 13:53:03 +08:00
commit 9f4f77fcc7
153 changed files with 4818 additions and 0 deletions

33
.gitignore vendored Normal file
View File

@ -0,0 +1,33 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/

BIN
.mvn/wrapper/maven-wrapper.jar vendored Normal file

Binary file not shown.

2
.mvn/wrapper/maven-wrapper.properties vendored Normal file
View File

@ -0,0 +1,2 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar

308
mvnw vendored Normal file
View File

@ -0,0 +1,308 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Apache Maven Wrapper startup batch script, version 3.2.0
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /usr/local/etc/mavenrc ] ; then
. /usr/local/etc/mavenrc
fi
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "$(uname)" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME
else
JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=$(java-config --jre-home)
fi
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
[ -n "$CLASSPATH" ] &&
CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] &&
JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="$(which javac)"
if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=$(which readlink)
if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then
if $darwin ; then
javaHome="$(dirname "\"$javaExecutable\"")"
javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac"
else
javaExecutable="$(readlink -f "\"$javaExecutable\"")"
fi
javaHome="$(dirname "\"$javaExecutable\"")"
javaHome=$(expr "$javaHome" : '\(.*\)/bin')
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=$(cd "$wdir/.." || exit 1; pwd)
fi
# end of workaround
done
printf '%s' "$(cd "$basedir" || exit 1; pwd)"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
# Remove \r in case we run on Windows within Git Bash
# and check out the repository with auto CRLF management
# enabled. Otherwise, we may read lines that are delimited with
# \r\n and produce $'-Xarg\r' rather than -Xarg due to word
# splitting rules.
tr -s '\r\n' ' ' < "$1"
fi
}
log() {
if [ "$MVNW_VERBOSE" = true ]; then
printf '%s\n' "$1"
fi
}
BASE_DIR=$(find_maven_basedir "$(dirname "$0")")
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
log "$MAVEN_PROJECTBASEDIR"
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar"
if [ -r "$wrapperJarPath" ]; then
log "Found $wrapperJarPath"
else
log "Couldn't find $wrapperJarPath, downloading it ..."
if [ -n "$MVNW_REPOURL" ]; then
wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
else
wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
fi
while IFS="=" read -r key value; do
# Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' )
safeValue=$(echo "$value" | tr -d '\r')
case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;;
esac
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
log "Downloading from: $wrapperUrl"
if $cygwin; then
wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
fi
if command -v wget > /dev/null; then
log "Found wget ... using wget"
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet"
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
else
wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
fi
elif command -v curl > /dev/null; then
log "Found curl ... using curl"
[ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent"
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
else
curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath"
fi
else
log "Falling back to using Java to download"
javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java"
javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaSource=$(cygpath --path --windows "$javaSource")
javaClass=$(cygpath --path --windows "$javaClass")
fi
if [ -e "$javaSource" ]; then
if [ ! -e "$javaClass" ]; then
log " - Compiling MavenWrapperDownloader.java ..."
("$JAVA_HOME/bin/javac" "$javaSource")
fi
if [ -e "$javaClass" ]; then
log " - Running MavenWrapperDownloader.java ..."
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath"
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
# If specified, validate the SHA-256 sum of the Maven wrapper jar file
wrapperSha256Sum=""
while IFS="=" read -r key value; do
case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;;
esac
done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties"
if [ -n "$wrapperSha256Sum" ]; then
wrapperSha256Result=false
if command -v sha256sum > /dev/null; then
if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then
wrapperSha256Result=true
fi
elif command -v shasum > /dev/null; then
if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then
wrapperSha256Result=true
fi
else
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available."
echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties."
exit 1
fi
if [ $wrapperSha256Result = false ]; then
echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2
echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2
echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2
exit 1
fi
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
[ -n "$CLASSPATH" ] &&
CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
# shellcheck disable=SC2086 # safe args
exec "$JAVACMD" \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

205
mvnw.cmd vendored Normal file
View File

@ -0,0 +1,205 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.2.0
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %WRAPPER_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file
SET WRAPPER_SHA_256_SUM=""
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B
)
IF NOT %WRAPPER_SHA_256_SUM%=="" (
powershell -Command "&{"^
"$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^
"If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^
" Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^
" Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^
" Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^
" exit 1;"^
"}"^
"}"
if ERRORLEVEL 1 goto error
)
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
cmd /C exit /B %ERROR_CODE%

96
pom.xml Normal file
View File

@ -0,0 +1,96 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.8</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.chint</groupId>
<artifactId>Route</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Route</name>
<description>Route</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.14</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>com.chint.dc</groupId>
<artifactId>common-api-sdk</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.22</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder-jammy-base:latest</builder>
</image>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,13 @@
package com.chint;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RouteApplication {
public static void main(String[] args) {
SpringApplication.run(RouteApplication.class, args);
}
}

View File

@ -0,0 +1,40 @@
package com.chint.domain.aggregates.base;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import java.time.LocalDateTime;
@Data
public class BaseEntity {
@ApiModelProperty("启用状态1启动0禁用")
public Integer status = 1;
@ApiModelProperty("排序字段")
public Integer sort = 0;
@CreatedBy
@ApiModelProperty("创建人标识")
public String createUser;
@CreatedDate
@ApiModelProperty("创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" , timezone = "GMT+8")
public LocalDateTime createTime;
@LastModifiedBy
@ApiModelProperty("最后更新人标识")
public String updateUser;
@LastModifiedDate
@ApiModelProperty("最后更新时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" , timezone = "GMT+8")
public LocalDateTime updateTime;
}

View File

@ -0,0 +1,109 @@
package com.chint.domain.aggregates.order;
import com.chint.domain.aggregates.base.BaseEntity;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import static com.chint.infrastructure.constant.Constant.*;
@Data
public class Leg extends BaseEntity {
public Long legId;
public Integer legType;
public LocalDateTime startTime;
public LocalDateTime endTime;
public Integer sequence = 0;
public Location origin;
public Location destination;
public Long routeId;
public String amount;
public String legTypeName;
public Integer legStatus;
public String legStatusName;
private List<LegEvent> eventList;
public Leg reloadStatus() {
int eventLength = eventList.size() - 1;
this.legStatus = eventLength < 0 ? LEG_STATUS_PREPARE : eventLength;
if (legStatus > 1) {
Optional<LegEvent> legEvent = this.eventList
.stream()
.filter(event -> event.getEventType().equals(LEG_EVENT_ORDERED))
.findFirst();
if (legEvent.isPresent()) {
LegEvent event = legEvent.get();
this.amount = event.getOrderAmount();
}
}
this.legStatusName = translateLegStatus(this.legStatus);
if (legType != null) {
this.legTypeName = translateLegType(this.legType);
}
return this;
}
private String translateLegStatus(int status) {
return switch (status) {
case LEG_STATUS_PREPARE -> LEG_STATUS_PREPARE_NAME;
case LEG_STATUS_ORDERED -> LEG_STATUS_ORDERED_NAME;
case LEG_STATUS_PAYED -> LEG_STATUS_PAYED_NAME;
case LEG_STATUS_FINISH -> LEG_STATUS_FINISH_NAME;
default -> "未知状态";
};
}
public String translateLegType(int type) {
return switch (type) {
case LEG_TYPE_TRAIN -> LEG_TYPE_TRAIN_NAME;
case LEG_TYPE_AIRPLANE -> LEG_TYPE_AIRPLANE_NAME;
case LEG_TYPE_HOTEL -> LEG_TYPE_HOTEL_NAME;
case LEG_TYPE_TAXI -> LEG_TYPE_TAXI_NAME;
case LEG_TYPE_OTHER -> LEG_TYPE_OTHER_NAME;
default -> "未知类型";
};
}
private Optional<Integer> getLatestEventType() {
return eventList.stream()
.map(LegEvent::getEventType)
.max(Integer::compareTo);
}
// public void handleEvent(EventDTO eventDTO) {
// switch (this.legStatus) {
// case LEG_EVENT_PREPARE:
// handlePrepareEvent(legEventRepository);
// break;
// case LEG_EVENT_ORDERED:
// handleOrderedEvent(legEventRepository, eventDTO.orderDetail, eventDTO.orderAmount);
// break;
// case LEG_EVENT_PAYED:
// handlePayedEvent(legEventRepository, eventDTO.orderAmount);
// break;
// case LEG_EVENT_FINISH:
// handleFinishEvent(legEventRepository);
// break;
// default:
// // 处理未知事件类型或记录错误
// break;
// }
// }
}

View File

@ -0,0 +1,32 @@
package com.chint.domain.aggregates.order;
import com.chint.domain.aggregates.base.BaseEntity;
import lombok.Data;
import static com.chint.infrastructure.constant.Constant.*;
@Data
public class LegEvent extends BaseEntity {
private Long legEventId;
private Long legId;
private Leg leg;
private Integer eventType;
private String eventName;
private String orderAmount;
public String translateLegEvent(int event) {
return switch (event) {
case LEG_EVENT_PREPARE -> LEG_EVENT_PREPARE_NAME;
case LEG_EVENT_ORDERED -> LEG_EVENT_ORDERED_NAME;
case LEG_EVENT_PAYED -> LEG_EVENT_PAYED_NAME;
case LEG_EVENT_FINISH -> LEG_EVENT_FINISH_NAME;
default -> "未知事件";
};
}
}

View File

@ -0,0 +1,21 @@
package com.chint.domain.aggregates.order;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Location {
private Long locationId;
private String locationPath;
private String locationPathName;
private String locationName;
private String locationShortName;
private Long parentLocationId;
private Integer level;
}

View File

@ -0,0 +1,106 @@
package com.chint.domain.aggregates.order;
import com.chint.domain.aggregates.base.BaseEntity;
import com.chint.domain.aggregates.user.User;
import com.chint.infrastructure.util.BigDecimalCalculator;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import static com.chint.infrastructure.constant.Constant.*;
@Data
@Table("route_order")
public class RouteOrder extends BaseEntity {
@Id
public Long routeId;
private LocalDateTime bookingTime;
private String amount;
private Integer orderStatus;
private String orderStatusName;
private User user;
public List<Leg> legItems;
public void addItemAtPosition(Leg newItem) {
Integer position = newItem.getSequence();
if (position == null) {
position = this.legItems.size() + 1;
newItem.setSequence(position);
}
if (position < 0 || position > this.legItems.size() + 1) {
throw new IllegalArgumentException(PARAM_ERROR);
}
Integer streamPosition = position;
this.legItems.stream()
.filter(item -> item.getSequence() >= streamPosition)
.forEach(item -> item.setSequence(item.getSequence() + 1));
newItem.setRouteId(this.routeId);
newItem.legId = newItem.getLegId();
newItem.reloadStatus();
}
public List<Leg> legOrdered() {
return this.legItems.stream()
.sorted(Comparator.comparingInt(Leg::getSequence))
.collect(Collectors.toList());
}
public RouteOrder reloadStatus() {
this.amount = this.legItems
.stream()
.filter(leg -> leg.amount != null)
.map(Leg::getAmount)
.reduce(BigDecimalCalculator::add)
.orElse(KEEP_TWO_DECIMAL_ZERO);
this.updateStatus();
this.orderStatusName = translateOrderStatus(this.orderStatus);
return this;
}
public void updateStatus() {
if (allItemsInStatus(3)) {
this.orderStatus = 3;
} else if (allItemsInStatus(2)) {
this.orderStatus = 2;
} else if (allItemsInStatus(1)) {
this.orderStatus = 1;
} else {
this.orderStatus = 0; // 或其他适当的默认状态
}
}
private boolean allItemsInStatus(int targetStatus) {
for (Leg item : this.legItems) {
if (item.getLegStatus() < targetStatus) {
return false;
}
}
return true;
}
private String translateOrderStatus(int status) {
return switch (status) {
case ORDER_STATUS_PREPARE -> ORDER_STATUS_PREPARE_NAME;
case ORDER_STATUS_ORDERED -> ORDER_STATUS_ORDERED_NAME;
case ORDER_STATUS_PAYED -> ORDER_STATUS_PAYED_NAME;
case ORDER_STATUS_FINISH -> ORDER_STATUS_FINISH_NAME;
default -> "未知状态";
};
}
}

View File

@ -0,0 +1,65 @@
package com.chint.domain.aggregates.user;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.chint.domain.aggregates.order.RouteOrder;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Map;
import static com.chint.infrastructure.constant.Constant.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
public Long userId;
public Long employeeNo;
public Integer employeeLevel;
public String name;
public String email;
public String gender;
public String phoneNumber;
public String password;
public String rankCode;
public String companyCode;
public String workStatus;
private List<RouteOrder> orders;
public User(Long employeeNo) {
this.employeeNo = employeeNo;
}
public User(Long userId, Long employeeNo, Integer employeeLevel, String name, String email, String phoneNumber) {
this.userId = userId;
this.employeeNo = employeeNo;
this.employeeLevel = employeeLevel;
this.name = name;
this.email = email;
this.phoneNumber = phoneNumber;
}
public static User withEmployeeNo(Long employeeNo) {
return new User(employeeNo);
}
public static User withJwt(DecodedJWT jwt) {
Map<String, Claim> claims = jwt.getClaims();
Claim userId = claims.get(USER_ID);
Claim phoneNumber = claims.get(USER_PHONE);
Claim email = claims.get(USER_EMAIL);
Claim employeeNo = claims.get(USER_EMPLOYEE_NO);
Claim name = claims.get(USER_NAME);
Claim employeeLevel = claims.get(USER_EMPLOYEE_LEVEL);
return new User(userId.asLong(),
employeeNo.asLong(),
employeeLevel.asInt(),
name.asString(),
email.asString(),
phoneNumber.asString());
}
}

View File

@ -0,0 +1,8 @@
package com.chint.domain.factoriy;
import com.chint.domain.aggregates.order.RouteOrder;
import com.chint.domain.value_object.OrderCreateData;
public interface OrderFactory {
RouteOrder createOrder(OrderCreateData orderData);
}

View File

@ -0,0 +1,11 @@
package com.chint.domain.factoriy;
import com.chint.domain.aggregates.order.RouteOrder;
import com.chint.domain.value_object.OrderCreateData;
public class RouteOrderFactory implements OrderFactory{
@Override
public RouteOrder createOrder(OrderCreateData orderData) {
return null;
}
}

View File

@ -0,0 +1,12 @@
package com.chint.domain.repositories;
import com.chint.domain.aggregates.order.Leg;
import com.chint.domain.aggregates.order.LegEvent;
import java.util.List;
public interface LegEventRepository {
void deleteByLegId(Leg leg);
List<LegEvent> findAllByLegId(Long id);
LegEvent save(LegEvent legEvent);
}

View File

@ -0,0 +1,13 @@
package com.chint.domain.repositories;
import com.chint.domain.aggregates.order.Leg;
import com.chint.domain.aggregates.order.RouteOrder;
import java.util.List;
public interface LegRepository {
Leg save(Leg bookingItem);
void deleteById(Long id);
List<Leg> findByOrder(RouteOrder order);
void saveAll(List<Leg> bookingItems);
}

View File

@ -0,0 +1,8 @@
package com.chint.domain.repositories;
import com.chint.domain.aggregates.order.Location;
public interface LocationRepository {
// List<Location> findByHot(List<LocationHot> locationHots);
Location findByLocationId(Long locationId);
}

View File

@ -0,0 +1,11 @@
package com.chint.domain.repositories;
import com.chint.domain.aggregates.order.RouteOrder;
import com.chint.domain.aggregates.user.User;
import com.chint.infrastructure.util.PageResult;
public interface RouteRepository {
RouteOrder queryById(Long orderId);
RouteOrder save(RouteOrder routeOrder);
PageResult<RouteOrder> pageQuery(User user);
}

View File

@ -0,0 +1,8 @@
package com.chint.domain.repositories;
import com.chint.domain.aggregates.user.User;
public interface UserRepository {
User findById(Long id);
User findByUserEmployeeNo(Long employeeNo);
}

View File

@ -0,0 +1,4 @@
package com.chint.domain.value_object;
public class OrderCreateData {
}

View File

@ -0,0 +1,145 @@
package com.chint.infrastructure.constant;
public class Constant {
// 通用消息
// 通用消息
public static final String SUCCESS = "操作成功";
public static final String FAILURE = "操作失败";
public static final String NOT_FOUND = "未找到相关数据";
public static final String INVALID_REQUEST = "无效的请求";
public static final String ACCESS_DENIED = "访问被拒绝";
public static final String SERVER_ERROR = "服务器错误";
// 数据相关消息
public static final String DATA_ALREADY_EXISTS = "数据已存在";
public static final String DATA_UPDATE_SUCCESS = "数据更新成功";
public static final String DATA_CREATION_SUCCESS = "数据创建成功";
public static final String DATA_DELETION_SUCCESS = "数据删除成功";
public static final String DATA_NOT_FOUND = "未找到数据";
public static final String DATA_INVALID = "数据不合法";
// JWT 验证消息
public static final String JWT_INVALID = "无效的 JWT 令牌";
public static final String JWT_EXPIRED = "JWT 令牌已过期";
public static final String JWT_REQUIRED = "需要 JWT 令牌";
public static final String JWT_ACCESS_DENIED = "JWT 令牌不足以访问此资源";
// 用户认证消息
public static final String AUTHENTICATION_FAILED = "认证失败";
public static final String LOGIN_SUCCESS = "登录成功";
public static final String LOGIN_FAILURE = "登录失败";
public static final String LOGOUT_SUCCESS = "成功登出";
// 系统消息
public static final String SYSTEM_MAINTENANCE = "系统维护中";
public static final String SYSTEM_UPGRADE = "系统升级中";
// Param
public static final String PARAM_ERROR = "参数错误";
// 订单状态
public static final int ORDER_STATUS_PREPARE = 0;
public static final String ORDER_STATUS_PREPARE_NAME = "规划中";
public static final int ORDER_STATUS_ORDERED = 1;
public static final String ORDER_STATUS_ORDERED_NAME = "已下单";
public static final int ORDER_STATUS_PAYED = 2;
public static final String ORDER_STATUS_PAYED_NAME = "已付款";
public static final int ORDER_STATUS_FINISH = 3;
public static final String ORDER_STATUS_FINISH_NAME = "已结束";
// 规划节点状态
public static final int LEG_STATUS_PREPARE = 0;
public static final String LEG_STATUS_PREPARE_NAME = "规划中";
public static final int LEG_STATUS_ORDERED = 1;
public static final String LEG_STATUS_ORDERED_NAME = "已下单";
public static final int LEG_STATUS_PAYED = 2;
public static final String LEG_STATUS_PAYED_NAME = "已付款";
public static final int LEG_STATUS_FINISH = 3;
public static final String LEG_STATUS_FINISH_NAME = "已结束";
// 规划节点运输方式
public static final int LEG_TYPE_TRAIN = 0;
public static final String LEG_TYPE_TRAIN_NAME = "火车";
public static final int LEG_TYPE_AIRPLANE = 1;
public static final String LEG_TYPE_AIRPLANE_NAME = "飞机";
public static final int LEG_TYPE_HOTEL = 2;
public static final String LEG_TYPE_HOTEL_NAME = "酒店";
public static final int LEG_TYPE_TAXI = 3;
public static final String LEG_TYPE_TAXI_NAME = "出租车";
public static final int LEG_TYPE_OTHER = 4;
public static final String LEG_TYPE_OTHER_NAME = "其他";
// 规划节点事件
public static final int LEG_EVENT_PREPARE = 0;
public static final String LEG_EVENT_PREPARE_NAME = "初始事件";
public static final int LEG_EVENT_ORDERED = 1;
public static final String LEG_EVENT_ORDERED_NAME = "下单事件";
public static final int LEG_EVENT_PAYED = 2;
public static final String LEG_EVENT_PAYED_NAME = "付款事件";
public static final int LEG_EVENT_FINISH = 3;
public static final String LEG_EVENT_FINISH_NAME = "结束事件";
// 金额
public static final String KEEP_TWO_DECIMAL_ZERO = "0.00";
// 登录信息
public static final String USER_ID = "userId";
public static final String USER_PHONE = "phoneNumber";
public static final String USER_EMAIL = "email";
public static final String USER_EMPLOYEE_NO = "employeeNo";
public static final String USER_NAME = "name";
public static final String USER_EMPLOYEE_LEVEL = "employeeLevel";
public static final String USER_RANK_CODE = "rankCode";
public static final String USER_COMPANY_CODE = "companyCode";
// JWT
public static final String SECRET = "Superdandan"; // 替换为你自己的密钥
public static final String SUBJECT = "EmployeeNo";
public static final long EXPIRATION_TIME_MS = 3600000L; // 1小时过期时间
public static final String HEADER_TOKEN = "token";
// URL
public static final String AK_BASE_URL = "http://10.10.100.184:7052";
public static final String GET_AK_URL = "/api/DataCenter/GetKey";
public static final String UPDATE_AK_PATH = "/api/DataCenter/UpdataKey";
public static final String ADD_AK_URL = "/api/DataCenter/AddKey";
public static final String SYSTEM_ID = "e72991a531a340b8a017139a6b51db3d";
public static final String OPENAI_BASE_URL = "https://openapi.chintcloud.net";
public static final String USER_DATA_PATH = "/open/HR/commonuserlist";
public static final String TRAVEL_RANK_BASE_URL = "http://10.10.14.178:8080";
public static final String TRAVEL_RANK_PATH = "/fssc/queryBill/queryTravelLevelByRank";
// 携程
public static final String C_TRIP_BASE_URL = "https://ct.ctrip.com";
public static final String TICKET_PATH = "/SwitchAPI/Order/Ticket";
public static final String C_TRIP_APP_KEY = "obk_zhengtai"; // 测试appkey
public static final String C_TRIP_APP_SECURITY = "obk_zhengtai"; // 测试app秘钥
public static final String USER_SAVE_PATH = "/corpservice/CorpCustService/SaveCorpCustInfoList";
public static final String HOTEL_CITY_PATH = "/corpopenapi/HotelCity/GetCountryCityExtend";
public static final String HOTEL_COUNTRY_PATH = "/corpopenapi/HotelCity/GetCountry";
public static final String AIR_AIRPORT_PATH = "/flightBaseData/queryAirPort";
public static final String AIR_CITY_PATH = "/flightBaseData/queryCity";
public static final String AIR_PROVINCE_PATH = "/flightBaseData/queryProvince";
public static final String AIR_COUNTRY_PATH = "/flightBaseData/queryCountry";
public static final String TRAIN_CITY_PATH = "/dataapi/train/inter/searchBizLocationList";
public static final String LANGUAGE_CN = "zh-CN";
public static final String C_TRIP_USER_SAVE_PATH = "/corpservice/CorpCustService/SaveCorpCustInfoList";
public static final String C_TRIP_APPROVAL_PATH = "/switchapi/approval.svc/rest/setapproval";
public static final String C_TRIP_ESTIMATE_PATH = "/bookingrelatedservice/bookingrelatedopenapi";
public static final String C_TRIP_TOKEN_PATH = "/dataservice/token/getAccessToken";
public static final String C_TRIP_ORDER_SEARCH_PATH = "/switchapi/Order/SearchOrder";
//同程
public static final String L_Y_BASE_URL = "https://api.qa.dttrip.cn";
public static final String L_Y_TOKEN_PATH = "/openapi/api/OAuth/v2/GetAccessToken";
public static final String L_Y_USER_PATH = "/openapi/api/Employee/SyncEmployeeInfo";
public static final String L_Y_ACCOUNT = "4f9cb1080b564dd0a94aa95f7a19c8b5"; // 测试appkey
public static final String L_Y_PASSWORD = "1fD3SutgzfS48qznYQiq"; // 测试app秘钥
public static final String L_Y_SECRET = "WOHzCMvHd823iHgH"; // 测试app秘钥
// status
public static final int STATUS_DISABLED = 0;
}

View File

@ -0,0 +1,20 @@
package com.chint.infrastructure.util;
import com.chint.domain.aggregates.user.User;
public class BaseContext {
private static final ThreadLocal<User> threadLocal = new ThreadLocal<>();
public static void setCurrentUser(User user) {
threadLocal.set(user);
}
public static User getCurrentUser() {
return threadLocal.get();
}
public static void removeCurrentUser() {
threadLocal.remove();
}
}

View File

@ -0,0 +1,62 @@
package com.chint.infrastructure.util;
import java.math.BigDecimal;
import static com.chint.infrastructure.constant.Constant.KEEP_TWO_DECIMAL_ZERO;
public class BigDecimalCalculator {
public static String add(String operand1, String operand2) {
try {
BigDecimal decimal1 = new BigDecimal(operand1).setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal decimal2 = new BigDecimal(operand2).setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal result = decimal1.add(decimal2).setScale(2, BigDecimal.ROUND_HALF_UP);
return result.toString();
} catch (Exception e) {
return KEEP_TWO_DECIMAL_ZERO;
}
}
public static String subtract(String operand1, String operand2) {
try {
BigDecimal decimal1 = new BigDecimal(operand1).setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal decimal2 = new BigDecimal(operand2).setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal result = decimal1.subtract(decimal2).setScale(2, BigDecimal.ROUND_HALF_UP);
return result.toString();
} catch (Exception e) {
return KEEP_TWO_DECIMAL_ZERO;
}
}
public static String multiply(String operand1, String operand2) {
try {
BigDecimal decimal1 = new BigDecimal(operand1).setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal decimal2 = new BigDecimal(operand2).setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal result = decimal1.multiply(decimal2).setScale(2, BigDecimal.ROUND_HALF_UP);
return result.toString();
} catch (Exception e) {
return KEEP_TWO_DECIMAL_ZERO;
}
}
public static String divide(String operand1, String operand2) {
try {
BigDecimal decimal1 = new BigDecimal(operand1).setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal decimal2 = new BigDecimal(operand2).setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal result = decimal1.divide(decimal2, 2, BigDecimal.ROUND_HALF_UP);
return result.toString();
} catch (Exception e) {
return KEEP_TWO_DECIMAL_ZERO;
}
}
public static String negateBigDecimal(String value) {
try {
BigDecimal original = new BigDecimal(value).setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal negated = original.negate().setScale(2, BigDecimal.ROUND_HALF_UP);
return negated.toString();
} catch (Exception e) {
return KEEP_TWO_DECIMAL_ZERO;
}
}
}

View File

@ -0,0 +1,44 @@
package com.chint.infrastructure.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Date;
import java.util.Map;
import static com.chint.infrastructure.constant.Constant.EXPIRATION_TIME_MS;
import static com.chint.infrastructure.constant.Constant.SECRET;
public class JWTUtil {
public static String createJWT(String SECRET, long EXPIRATION_TIME_MS, String subject, Map<String, Object> claims) {
Date issuedAt = new Date();
Date expiresAt = new Date(issuedAt.getTime() + EXPIRATION_TIME_MS);
return JWT.create()
.withSubject(subject)
.withIssuedAt(issuedAt)
.withExpiresAt(expiresAt)
.withPayload(claims)
.sign(Algorithm.HMAC256(SECRET));
}
public static String createJWT(String subject, Map<String, Object> claims) {
return createJWT(SECRET, EXPIRATION_TIME_MS, subject, claims);
}
public static DecodedJWT parseJWT(String SECRET, String token) {
return JWT.require(Algorithm.HMAC256(SECRET))
.build()
.verify(token);
}
public static boolean verifyJWT(String SECRET, String token) {
try {
parseJWT(SECRET, token);
return true;
} catch (Exception ex) {
return false;
}
}
}

View File

@ -0,0 +1,25 @@
package com.chint.infrastructure.util;
import java.util.List;
public class PageResult<T> {
private long total;
private List<T> records;
public PageResult(long total, List<T> records) {
this.total = total;
this.records = records;
}
public static <T> PageResult<T> page(List<T> res) {
return new PageResult<>(res.size(), res);
}
public static <T> PageResult<T> totalPageNum(long totalNum, List<T> res) {
return new PageResult<>(totalNum, res);
}
public static <T> PageResult<T> empty() {
return new PageResult<>(0, List.of());
}
}

View File

@ -0,0 +1,52 @@
package com.chint.infrastructure.util;
import java.io.Serializable;
import java.util.Objects;
public class Result<T> implements Serializable {
private String msg;
private String code;
private T data;
public Result() {}
public Result(String msg, String code, T data) {
this.msg = msg;
this.code = code;
this.data = data;
}
public Result(String msg, String code) {
this.msg = msg;
this.code = code;
}
// Getter and Setter methods
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Result<?> result = (Result<?>) o;
return Objects.equals(msg, result.msg) &&
Objects.equals(code, result.code) &&
Objects.equals(data, result.data);
}
@Override
public int hashCode() {
return Objects.hash(msg, code, data);
}
public static <T> Result<T> success(String msg, T data) {
return new Result<>(msg, "1", data);
}
public static <T> Result<T> success(String msg) {
return new Result<>(msg, "1");
}
public static <T> Result<T> error(String msg) {
return new Result<>(msg, "0");
}
}

View File

@ -0,0 +1,13 @@
package com.chint.infrastructure.util;
public class Token {
private String token;
private Token(String token) {
this.token = token;
}
public static Token of(String token) {
return new Token(token);
}
}

View File

@ -0,0 +1,41 @@
package com.chint.infrastructure.webconfig;
import com.chint.domain.aggregates.user.User;
import com.chint.infrastructure.util.BaseContext;
import com.chint.infrastructure.util.JWTUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import static com.chint.infrastructure.constant.Constant.*;
public class JwtTokenAdminInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader(HEADER_TOKEN);
if (request.getRequestURI().endsWith("/login")) {
return true;
}
if (token == null) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write(JWT_REQUIRED);
return false;
}
try {
JWTUtil.verifyJWT(SECRET, token);
var parseJWT = JWTUtil.parseJWT(SECRET, token);
var withJwt = User.withJwt(parseJWT);
BaseContext.setCurrentUser(withJwt);
return true; // If verification succeeds, continue processing the request
} catch (Exception e) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write(JWT_INVALID);
return false; // Verification failed, deny request
}
}
}

View File

@ -0,0 +1,34 @@
package com.chint.infrastructure.webconfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
// @Bean
// public JwtTokenAdminInterceptor JwtTokenAdminInterceptor() {
// return new JwtTokenAdminInterceptor();
// }
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new JwtTokenAdminInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/public/**", "/login");
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}

View File

@ -0,0 +1,38 @@
package com.chint.interfaces.rest.base;
import com.google.gson.Gson;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class PostRequest {
private final Gson gson = new Gson();
private final HttpClient client = HttpClients.createDefault();
public <T> T post(String url, Object jsonRequest, Class<T> responseType) {
HttpPost post = new HttpPost(url);
post.setEntity(new StringEntity(gson.toJson(jsonRequest), ContentType.APPLICATION_JSON));
String responseBody = null;
try {
HttpResponse response = client.execute(post);
HttpEntity responseEntity = response.getEntity();
responseBody = EntityUtils.toString(responseEntity, "UTF-8");
} catch (IOException e) {
throw new RuntimeException(e);
}
return gson.fromJson(responseBody, responseType);
}
public Gson gson() {
return gson;
}
}

View File

@ -0,0 +1,29 @@
package com.chint.interfaces.rest.ctrip;
import com.chint.interfaces.rest.base.PostRequest;
import com.chint.interfaces.rest.ctrip.dto.approval.ApprovalRequest;
import com.chint.interfaces.rest.ctrip.dto.approval.ApprovalResult;
import com.chint.interfaces.rest.ctrip.dto.Authentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import static com.chint.infrastructure.constant.Constant.*;
@Service
public class CTripApprovalRequest {
private String approvalUrl = C_TRIP_BASE_URL + C_TRIP_APPROVAL_PATH;
@Autowired
private CTripTicketRequest ticketRequest;
@Autowired
private PostRequest postRequest;
public ApprovalResult approval(ApprovalRequest approvalRequest) {
String ticket = ticketRequest.loadTicket();
approvalRequest.setStatus(0);
approvalRequest.setAuth(Authentication.of(C_TRIP_APP_KEY, ticket));
return postRequest.post(approvalUrl, approvalRequest, ApprovalResult.class);
}
}

View File

@ -0,0 +1,61 @@
package com.chint.interfaces.rest.ctrip;
import com.chint.domain.aggregates.user.User;
import com.chint.infrastructure.util.BaseContext;
import com.chint.interfaces.rest.base.PostRequest;
import com.chint.interfaces.rest.ctrip.dto.estimate.request.AuthInfo;
import com.chint.interfaces.rest.ctrip.dto.estimate.request.BookingRelatedApiRequest;
import com.chint.interfaces.rest.ctrip.dto.estimate.request.FlightProductInfo;
import com.chint.interfaces.rest.ctrip.dto.estimate.request.TrainProductInfo;
import com.chint.interfaces.rest.ctrip.dto.estimate.response.BookingRelatedApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import static com.chint.infrastructure.constant.Constant.*;
@Component
public class CTripEstimateRequest {
private String apiName = "bookingRelatedOpenApi.valuateBudget";
private String estimateUrl = C_TRIP_BASE_URL + C_TRIP_ESTIMATE_PATH;
@Autowired
private CTripTokenRequest tokenRequest;
@Autowired
private PostRequest postRequest;
public BookingRelatedApiResponse estimate(BookingRelatedApiRequest bookingRelatedApiRequest) {
return postRequest.post(estimateUrl, bookingRelatedApiRequest, BookingRelatedApiResponse.class);
}
public BookingRelatedApiRequest generateBaseRequest(FlightProductInfo flightProductInfo, TrainProductInfo trainProductInfo) {
BookingRelatedApiRequest bookingRelatedApiRequest = new BookingRelatedApiRequest();
String token = tokenRequest.getToken();
bookingRelatedApiRequest.setApiName(apiName);
bookingRelatedApiRequest.setLanguage(LANGUAGE_CN);
bookingRelatedApiRequest.setAuthInfo(AuthInfo.of(C_TRIP_APP_KEY, token));
User user = BaseContext.getCurrentUser();
return BookingRelatedApiRequest.builder()
.language(LANGUAGE_CN)
.apiName(apiName)
.authInfo()
.details(C_TRIP_APP_KEY, token)
.done()
.requestContent()
.valuationBaseInfo()
.eID(user.employeeNo.toString())
.corpID("zhengtai")
.rankName(user.getRankCode())
.done()
.valuationProductInfo()
.addFlightProductInfo(flightProductInfo)
.addTrainProductInfo(trainProductInfo)
.done()
.done()
.build();
}
}

View File

@ -0,0 +1,45 @@
package com.chint.interfaces.rest.ctrip;
import com.chint.interfaces.rest.base.PostRequest;
import com.chint.interfaces.rest.ctrip.dto.*;
import com.chint.interfaces.rest.ctrip.dto.location.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import static com.chint.infrastructure.constant.Constant.*;
@Service
public class CTripLocationHttpRequest implements LocationHttpRequest {
@Autowired
private PostRequest postRequest;
@Autowired
private CTripTicketRequest ticketRequest;
private static final String locationCityUrl = C_TRIP_BASE_URL + HOTEL_CITY_PATH;
private static final String locationCountryUrl = C_TRIP_BASE_URL + HOTEL_COUNTRY_PATH;
@Override
public void syncLocation() {
// cityRepository.saveAll(syncCity());
// countryRepository.saveAll(syncCountry());
}
public List<Country> syncCountry() {
Object jsonRequest = new GetCountry(new Authentification(C_TRIP_APP_KEY, ticketRequest.loadTicket()), LANGUAGE_CN);
CountryResponse response = postRequest.post(locationCountryUrl, jsonRequest, CountryResponse.class);
return response.getData();
}
public List<City> syncCity() {
Authentification authentification = new Authentification(C_TRIP_APP_KEY, ticketRequest.loadTicket());
GetCountryCityExtend getCountryCityExtend = new GetCountryCityExtend(authentification, LANGUAGE_CN, 2);
CityResponse response = postRequest.post(locationCityUrl, getCountryCityExtend, CityResponse.class);
return response.getData();
}
}

View File

@ -0,0 +1,55 @@
package com.chint.interfaces.rest.ctrip;
import com.chint.interfaces.rest.base.PostRequest;
import com.chint.interfaces.rest.ctrip.dto.ticket.TicketParam;
import com.chint.interfaces.rest.ctrip.dto.ticket.TicketResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import static com.chint.infrastructure.constant.Constant.*;
@Component
public class CTripTicketRequest {
@Autowired
private PostRequest postRequest;
private final String ticketUrl = C_TRIP_BASE_URL + TICKET_PATH;
private final TicketParam ticketParam = new TicketParam(C_TRIP_APP_KEY, C_TRIP_APP_SECURITY);
// Data class to store ticket and expiry time
public static class CachedTicket {
private final String ticket;
private final LocalDateTime expiryTime;
public CachedTicket(String ticket, LocalDateTime expiryTime) {
this.ticket = ticket;
this.expiryTime = expiryTime;
}
public String getTicket() {
return ticket;
}
public LocalDateTime getExpiryTime() {
return expiryTime;
}
}
// Cached ticket instance
private CachedTicket cachedTicket = null;
public String loadTicket() {
// Check if the cached ticket exists and is valid
if (cachedTicket != null && cachedTicket.getExpiryTime().isAfter(LocalDateTime.now())) {
return cachedTicket.getTicket();
}
System.out.println(ticketParam);
TicketResponse ticket = postRequest.post(ticketUrl, ticketParam, TicketResponse.class);
// Update the cache with an expiry time of 2 hours from the current time
cachedTicket = new CachedTicket(ticket.getTicket(), LocalDateTime.now().plusHours(2));
return ticket.getTicket();
}
}

View File

@ -0,0 +1,27 @@
package com.chint.interfaces.rest.ctrip;
import com.chint.interfaces.rest.base.PostRequest;
import com.chint.interfaces.rest.ctrip.dto.token.GetUnionAccessTokenRequest;
import com.chint.interfaces.rest.ctrip.dto.token.GetUnionAccessTokenResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import static com.chint.infrastructure.constant.Constant.*;
@Service
public class CTripTokenRequest {
private String tokenUrl = C_TRIP_BASE_URL + C_TRIP_TOKEN_PATH;
@Autowired
private PostRequest postRequest;
public String getToken() {
GetUnionAccessTokenRequest getUnionAccessTokenRequest =
GetUnionAccessTokenRequest.of(C_TRIP_APP_KEY, C_TRIP_APP_SECURITY, 1);
return postRequest
.post(tokenUrl, getUnionAccessTokenRequest, GetUnionAccessTokenResponse.class)
.getAccessToken();
}
}

View File

@ -0,0 +1,57 @@
package com.chint.interfaces.rest.ctrip;
import com.chint.domain.aggregates.user.User;
import com.chint.infrastructure.util.BaseContext;
import com.chint.interfaces.rest.base.PostRequest;
import com.chint.interfaces.rest.ctrip.dto.user.AuthenticationEntity;
import com.chint.interfaces.rest.ctrip.dto.user.AuthenticationInfo;
import com.chint.interfaces.rest.ctrip.dto.user.AuthenticationListRequest;
import com.chint.interfaces.rest.user.UserHttpRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.chint.interfaces.rest.ctrip.dto.AuthenticationResponseList;
import java.util.List;
import static com.chint.infrastructure.constant.Constant.*;
@Service
public class CTripUserSaveRequest {
@Autowired
private PostRequest postRequest;
@Autowired
private UserHttpRequest userHttpRequest;
@Autowired
private CTripTicketRequest ticketRequest;
private final String userUrl = C_TRIP_BASE_URL + C_TRIP_USER_SAVE_PATH;
public void saveUserToCTrip() {
User currentUser = BaseContext.getCurrentUser();
User user = userHttpRequest.loadUserInfo(currentUser);
String ticket = ticketRequest.loadTicket();
AuthenticationEntity authenticationEntity = buildAuthenticationEntityWithUser(user);
AuthenticationListRequest authenticationListRequest = new AuthenticationListRequest();
authenticationListRequest.setAppkey(C_TRIP_APP_KEY);
authenticationListRequest.setTicket(ticket);
authenticationListRequest.setCorporationID("zhengtai");
AuthenticationInfo authenticationInfo = new AuthenticationInfo();
authenticationInfo.setSequence("0");
authenticationInfo.setAuthentication(authenticationEntity);
authenticationListRequest.setAuthenticationInfoList(List.of(authenticationInfo));
AuthenticationResponseList post = postRequest.post(userUrl, authenticationInfo, AuthenticationResponseList.class);
System.out.println(post);
}
public AuthenticationEntity buildAuthenticationEntityWithUser(User user) {
AuthenticationEntity authenticationEntity = new AuthenticationEntity();
authenticationEntity.setName(user.getName());
authenticationEntity.setEmployeeID(user.getEmployeeNo().toString());
authenticationEntity.setRankName(user.getRankCode());
authenticationEntity.setValid(user.getWorkStatus());
authenticationEntity.setSubAccountName("zhengtai_提前审批测试");
return authenticationEntity;
}
}

View File

@ -0,0 +1,5 @@
package com.chint.interfaces.rest.ctrip;
public interface LocationHttpRequest {
void syncLocation();
}

View File

@ -0,0 +1,16 @@
package com.chint.interfaces.rest.ctrip.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Authentication {
private String appKey;
private String ticket;
// Getters and setters...
public static Authentication of(String appKey, String ticket) {
return new Authentication(appKey, ticket);
}
}

View File

@ -0,0 +1,11 @@
package com.chint.interfaces.rest.ctrip.dto;
import lombok.Data;
import java.util.List;
@Data
public class AuthenticationResponseList {
private String Result;
private List<ErrorMessage> ErrorMessageList;
}

View File

@ -0,0 +1,17 @@
package com.chint.interfaces.rest.ctrip.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
public class Authentification {
private String AppKey;
private String Ticket;
public Authentification(String appKey, String ticket) {
AppKey = appKey;
Ticket = ticket;
}
// Constructors, getters, and setters
}

View File

@ -0,0 +1,11 @@
package com.chint.interfaces.rest.ctrip.dto;
import lombok.Data;
@Data
public class ErrorMessage {
private int Sequence;
private String ErrorCode;
private String Message;
private String EmployeeID;
}

View File

@ -0,0 +1,12 @@
package com.chint.interfaces.rest.ctrip.dto;
import lombok.Data;
@Data
public class ResponseStatus {
private Boolean Success;
private int ErrorCode;
private String Message;
// Constructors, getters, and setters
}

View File

@ -0,0 +1,13 @@
package com.chint.interfaces.rest.ctrip.dto;
public class ResponseSuccess {
// 是否成功
private boolean success;
// 消息内容
private String message;
// 错误代码
private int errorCode;
// Getters and setters...
}

View File

@ -0,0 +1,125 @@
package com.chint.interfaces.rest.ctrip.dto.approval;
import com.chint.interfaces.rest.ctrip.dto.Authentication;
import com.chint.interfaces.rest.ctrip.dto.approval.air.FlightEndorsementDetail;
import com.chint.interfaces.rest.ctrip.dto.approval.charter.CarCharterEndorsementDetail;
import com.chint.interfaces.rest.ctrip.dto.approval.endor.BusEndorsementDetail;
import com.chint.interfaces.rest.ctrip.dto.approval.hotel.HotelEndorsementDetail;
import com.chint.interfaces.rest.ctrip.dto.approval.pick.CarPickUpEndorsementDetail;
import com.chint.interfaces.rest.ctrip.dto.approval.plan.TravelPlanEndorsementDetail;
import com.chint.interfaces.rest.ctrip.dto.approval.quick.CarQuickEndorsementDetail;
import com.chint.interfaces.rest.ctrip.dto.approval.quick.RankInfo;
import com.chint.interfaces.rest.ctrip.dto.approval.train.TrainEndorsementDetail;
import lombok.Data;
import java.util.List;
@Data
public class ApprovalRequest {
// 审批单号 - 必填
// OA审批通过时生成同步审批单编号用于标识审批单
private String approvalNumber;
// 状态 - 必填
// 0为审批中1为审批通过2为审批拒绝
private int status;
// 携程卡号 - 非必填
// N表示非必填多个携程卡号以逗号隔开长度不能超过500个字符且不重复
private String ctripCardNO;
// 员工编号 - 非必填
// N表示非必填多个员工编号以逗号隔开长度不能超过500个字符且不重复
private String employeeID;
// 机票背书信息详情列表 - 必填
// Y表示必填项用于记录一条审批单中的一条或多条航班信息详细信息格式见3.3.2节的JSON数据交互格式详细说明
private List<FlightEndorsementDetail> flightEndorsementDetails;
// 酒店背书信息详情列表 - 必填
// Y表示必填项
private List<HotelEndorsementDetail> hotelEndorsementDetails;
// 火车背书信息详情列表 - 必填
// Y表示必填项
private List<TrainEndorsementDetail> trainEndorsementDetails;
// 租车背书信息详情列表 - 必填
// Y表示必填项
private List<CarQuickEndorsementDetail> carQuickEndorsementDetails;
// 接送车背书信息详情列表 - 必填
// Y表示必填项
private List<CarPickUpEndorsementDetail> carPickUpEndorsementDetails;
// 包车背书信息详情列表 - 必填
// Y表示必填项
private List<CarCharterEndorsementDetail> carCharterEndorsementDetails;
// 巴士背书信息详情列表 - 必填
// Y表示必填项
private List<BusEndorsementDetail> busEndorsementDetails;
// 出差计划背书信息详情列表 - 必填
// Y表示必填项
private List<TravelPlanEndorsementDetail> travelPlanEndorsementDetails;
// 有效期 - 非必填
// 有效期格式为日期时间起始时间从2017-01-01开始
private String expiredTime;
// 认证信息 - 非必填
// 携程分配给客户公司具体见下表描述
private Authentication auth;
// 成本中心等扩展字段列表非必填如无该需求则不需要传
// Y表示必填项
private List<ExtendField> extendFieldList;
// 备注 - 必填
// Y表示必填项
private String remark;
// 职级信息 - 非必填
// 职级信息仅限于职级信息的前20
private RankInfo rankInfo;
public ApprovalRequest(String approvalNumber, String employeeID, RankInfo rankInfo) {
this.approvalNumber = approvalNumber;
this.employeeID = employeeID;
this.rankInfo = rankInfo;
}
public static ApprovalRequest buildApproval(String employeeID, String approvalNumber, RankInfo rankInfo) {
return new ApprovalRequest(employeeID, approvalNumber, rankInfo);
}
public ApprovalRequest withAir(List<FlightEndorsementDetail> flightEndorsementDetails) {
this.flightEndorsementDetails = flightEndorsementDetails;
return this;
}
public ApprovalRequest withTrain(List<HotelEndorsementDetail> hotelEndorsementDetails) {
this.hotelEndorsementDetails = hotelEndorsementDetails;
return this;
}
public ApprovalRequest withBus(List<BusEndorsementDetail> busEndorsementDetails) {
this.busEndorsementDetails = busEndorsementDetails;
return this;
}
public ApprovalRequest withPickCar(List<CarPickUpEndorsementDetail> carPickUpEndorsementDetails) {
this.carPickUpEndorsementDetails = carPickUpEndorsementDetails;
return this;
}
public ApprovalRequest withQuickCar(List<CarQuickEndorsementDetail> carQuickEndorsementDetails) {
this.carQuickEndorsementDetails = carQuickEndorsementDetails;
return this;
}
public ApprovalRequest withHotel(List<HotelEndorsementDetail> hotelEndorsementDetails) {
this.hotelEndorsementDetails = hotelEndorsementDetails;
return this;
}
}

View File

@ -0,0 +1,10 @@
package com.chint.interfaces.rest.ctrip.dto.approval;
import lombok.Data;
@Data
public class ApprovalResult {
private ResponseStatus Status;
}

View File

@ -0,0 +1,17 @@
package com.chint.interfaces.rest.ctrip.dto.approval;
public class CurrencyType {
public final static Integer UnKnow = 0;
public final static Integer RMB = 1;
public final static Integer CNY = 2;
public final static Integer HKD = 3;
public final static Integer USD = 4;
public final static Integer EUR = 5;
public final static Integer SGD = 6;
public final static Integer MOP = 7;
public final static Integer JPY = 8;
public final static Integer THB = 9;
public final static Integer AUD = 10;
public final static Integer GBP = 11;
}

View File

@ -0,0 +1,8 @@
package com.chint.interfaces.rest.ctrip.dto.approval;
public class ExtendField {
private String fieldName;
private String fieldValue;
private String fieldType;
// Getters and setters...
}

View File

@ -0,0 +1,65 @@
package com.chint.interfaces.rest.ctrip.dto.approval;
import java.util.List;
public class PassengerDetail {
// 姓名 - 必填
// 中文姓名例如张三 - 中文姓名最后人员填写必选项通用汉字集合
// 外籍名例如泰国人员NameEn代入
// 由三部分组成的姓名字段Name/EID/NameEn 选择其中一
private String name;
// 证件类型 - 必填
// 证件类型列举证件类型编码请详看附件类型编码数字不下发
private String credentialsType;
// 证件号码 - 必填
// 如果是证件号码则用于后续证件件号码合理性检查
// 可包含数字和字母用于检查合理性如果是证件证
// 判断所证件证件号码与实际填写情况
private String credentialsNumber;
// 出行人EID - 必填
// 出行人员信息Name/EID/NameEn 选择其中一
// 出行人员信息不会涉及隐私泄露
// AveragePrice>policyid>rankname>eid
private String EID;
// 英文姓名 - 必填
// 英文姓名例如中文张三对应英文名字Zhang/San
// 英文名不区分大小写 中美英姓名填写指导原则如外籍人员人名
// 可包含英文字母用于国际航空运输
// 通用国际音标对照lastname/firstname
// 可容纳姓名人数最多限制数据
// 由三部分组成的姓名字段Name/EID/NameEn 选择其中一
private String nameEn;
// 职级名称 - 必填
// 出行人员信息不会涉及隐私泄露
// AveragePrice>policyid>rankname>eid
private String rankName;
// 政策规则EID - 必填
// 出行人员信息不会涉及隐私泄露
// AveragePrice>policyid>rankname>eid
private String policyEID;
// 国家代码 - 必填
// 如果手机号为空国外为空则默认填写为中国大陆区号
private String countryCode;
// 手机号码 - 必填
// 手机中心存储的手机号码非必填如无法检索则不下发数据
// 支持境外港澳文件有国际区号为准
// 酒店方在出行人员中心同一字段使用机票
// 和火车票方面
private String mobilePhone;
// 扩展字段列表 - 可选
// 不支持新增扩展
private List<ExtendField> extendFieldList;
// Getters and setters for each field would be included below...
}

View File

@ -0,0 +1,10 @@
package com.chint.interfaces.rest.ctrip.dto.approval;
import lombok.Data;
@Data
public class ResponseStatus {
private Boolean Success;
private String Message;
private Integer ErrorCode;
}

View File

@ -0,0 +1,100 @@
package com.chint.interfaces.rest.ctrip.dto.approval.air;
import com.chint.interfaces.rest.ctrip.dto.approval.CurrencyType;
import com.chint.interfaces.rest.ctrip.dto.approval.PassengerDetail;
import lombok.Data;
import java.util.List;
@Data
public class FlightEndorsementDetail {
// 订票类型列表 - 1张, 2张, 3张, 超过3张
private List<String> bookingTypeList;
// 订单ID列表 - 最多20个
private List<String> orderIDList;
// 航空公司名称 - 不可为空字符串
private String airline;
// 货币类型 - 默认CNY
private CurrencyType currency;
// 航班类型 - 单程(1) or 往返(2)
private FlightWayType flightWay;
// 起飞日期开始时间 - 格式: yyyy-MM-dd
private String departDateBegin;
// 起飞日期结束时间 - 格式: yyyy-MM-dd
private String departDateEnd;
// 返回日期开始时间 - 格式: yyyy-MM-dd
private String returnDateBegin;
// 返回日期结束时间 - 格式: yyyy-MM-dd
private String returnDateEnd;
// 起飞时间开始时间 - 格式: HH:mm
private String takeOffBeginTime;
// 起飞时间结束时间 - 格式: HH:mm
private String takeOffEndTime;
// 到达时间开始时间 - 格式: HH:mm
private String arrivalBeginTime;
// 到达时间结束时间 - 格式: HH:mm
private String arrivalEndTime;
// 折扣率 - 0.1到1.0, 0代表无折扣
private float discount;
// 出发国家ID列表 - 最多1000个
private List<String> departCountryIds;
// 出发国家代码列表 - 最多1000个
private List<String> departCountryCodes;
// 出发城市代码列表 - 最多1000个
private List<String> departCityCodes;
// 到达国家ID列表 - 最多1000个
private List<String> arrivalCountryIds;
// 到达城市代码列表 - 最多1000个
private List<String> arrivalCityCodes;
// 出发城市ID列表 - 最多1000个
private List<String> departCityIds;
// 到达城市ID列表 - 最多1000个
private List<String> arrivalCityIds;
// 乘客列表 - 无数量限制
private List<PassengerDetail> passengerList;
// 价格 - 可为负数, 默认为0
private float price;
// 产品类型 - 1代表经济舱, 2代表商务舱
private ProductTypeEnum productType;
// 座位等级 - 经济舱(3), 商务舱(2), 头等舱(1)
private SeatClassType seatClass;
// 跳过的字段位 - 用于标记不包含的字段
private long skipFields;
// 旅客数量 - 无限制
private int travelerCount;
// 总旅客数量 - 用于统计
private int totalTravelerCount;
// 预验证字段位 - 用于标记需要预验证的字段
private long preVerifyFields;
// Getters and setters...
}

View File

@ -0,0 +1,16 @@
package com.chint.interfaces.rest.ctrip.dto.approval.air;
// Additional FlightPreVerifyFields constants based on the new image provided
public class FlightPreVerifyFields {
public static final long Airline = 1; // 航空公司字段
public static final long DepartDateBegin = 2; // 起飞日期开始字段
public static final long DepartDateEnd = 4; // 起飞日期结束字段
public static final long DepartCityCodes = 16; // 出发城市代码字段
public static final long PassengerList = 32; // 乘客列表字段
public static final long ReturnDateBegin = 128; // 返回日期开始字段
public static final long ReturnDateEnd = 256; // 返回日期结束字段
public static final long SeatClass = 512; // 座位等级字段
public static final long ArrivalCityCodes = 1024; // 到达城市代码字段
public static final long FlightWay = 65536; // 航班类型字段
// ... include other fields as necessary
}

View File

@ -0,0 +1,20 @@
package com.chint.interfaces.rest.ctrip.dto.approval.air;
import lombok.Data;
@Data
public class FlightSkipFields {
public static final long Airline = 1; // 航空公司字段
public static final long DepartDateBegin = 2; // 起飞日期开始字段
public static final long DepartDateEnd = 4; // 起飞日期结束字段
public static final long Discount = 8; // 折扣字段
public static final long DepartCityCodes = 16; // 出发城市代码字段
public static final long PassengerList = 32; // 乘客列表字段
public static final long Price = 64; // 价格字段
public static final long ReturnDateBegin = 128; // 返回日期开始字段
public static final long ReturnDateEnd = 256; // 返回日期结束字段
public static final long SeatClass = 512; // 座位等级字段
public static final long ArrivalCityCodes = 1024; // 到达城市代码字段
// ... Other fields follow with their corresponding bit values
// Note that this is not an exhaustive list due to the image being cut off.
}

View File

@ -0,0 +1,14 @@
package com.chint.interfaces.rest.ctrip.dto.approval.air;
public enum FlightWayType {
SingleTrip(1), // 单程
RoundTrip(2); // 往返
private final int value;
FlightWayType(int value) {
this.value = value;
}
// Getter...
}

View File

@ -0,0 +1,11 @@
package com.chint.interfaces.rest.ctrip.dto.approval.air;
public enum ProductTypeEnum {
IN(1), // 单程
OUT(2); // 往返
private final int value;
ProductTypeEnum(int value) {
this.value = value;
}
}

View File

@ -0,0 +1,17 @@
package com.chint.interfaces.rest.ctrip.dto.approval.air;
public enum SeatClassType {
UnKnown(0), // 未知
SaloonCabin(1), // 沙龙舱
BusinessClass(2), // 商务舱
SuperTouristClass(4), // 超级旅游舱
TouristClass(3); // 旅游舱
private final int value;
SeatClassType(int value) {
this.value = value;
}
// Getter...
}

View File

@ -0,0 +1,48 @@
package com.chint.interfaces.rest.ctrip.dto.approval.charter;
import com.chint.interfaces.rest.ctrip.dto.approval.CurrencyType;
import com.chint.interfaces.rest.ctrip.dto.approval.PassengerDetail;
import java.util.List;
public class CarCharterEndorsementDetail {
// 产品类型
private int productType;
// 乘客列表, 最多100名
private List<PassengerDetail> passengerList;
// 出发城市代码
private String departCities;
// 到达城市代码
private String arriveCities;
// 开始使用日期
private String beginUseDate;
// 结束使用日期
private String endUseDate;
// 开始使用时间
private String beginUseTime;
// 结束使用时间
private String endUseTime;
// 使用天数
private int useDays;
// 货币类型, 默认CNY
private CurrencyType currency;
// 价格默认为0
private float price;
// 车辆组
private String vehicleGroup;
// 跳过的字段位
private long skipFields;
// 预验证字段位
private long preVerifyFields;
// 座位数
private int seatsNum;
// 组合ID
private String comboID;
// 版本号
private int version;
// 总旅客数
private int totalTravelerCount;
// Getters and setters...
}

View File

@ -0,0 +1,16 @@
package com.chint.interfaces.rest.ctrip.dto.approval.charter;
public class CarCharterPreVerifyFieldType {
public static final long BeginUseDate = 1; // 开始使用日期字段预验证标志
public static final long EndUseDate = 2; // 结束使用日期字段预验证标志
public static final long BeginUseTime = 4; // 开始使用时间字段预验证标志
public static final long EndUseTime = 8; // 结束使用时间字段预验证标志
public static final long DepartCities = 16; // 出发城市字段预验证标志
public static final long ArriveCities = 32; // 到达城市字段预验证标志
public static final long VehicleGroup = 64; // 车辆组字段预验证标志
public static final long SeatsNum = 128; // 座位数字段预验证标志
public static final long ComboID = 256; // 组合ID字段预验证标志
public static final long PassengerList = 512; // 乘客列表字段预验证标志
public static final long UseDays = 1024; // 使用天数字段预验证标志
// ... include other fields as necessary
}

View File

@ -0,0 +1,18 @@
package com.chint.interfaces.rest.ctrip.dto.approval.charter;
public class CarCharterSkipFieldType {
public static final long BeginUseDate = 1; // 开始使用日期字段跳过标志
public static final long EndUseDate = 2; // 结束使用日期字段跳过标志
public static final long BeginUseTime = 4; // 开始使用时间字段跳过标志
public static final long EndUseTime = 8; // 结束使用时间字段跳过标志
public static final long DepartCities = 16; // 出发城市字段跳过标志
public static final long ArriveCities = 32; // 到达城市字段跳过标志
public static final long VehicleGroup = 64; // 车辆组字段跳过标志
public static final long SeatsNum = 128; // 座位数字段跳过标志
public static final long ComboID = 256; // 组合ID字段跳过标志
public static final long PassengerList = 512; // 乘客列表字段跳过标志
public static final long UseDays = 1024; // 使用天数字段跳过标志
public static final long Price = 2048; // 价格字段跳过标志
public static final long Currency = 4096; // 货币字段跳过标志
// ... include other fields as necessary
}

View File

@ -0,0 +1,36 @@
package com.chint.interfaces.rest.ctrip.dto.approval.endor;
import com.chint.interfaces.rest.ctrip.dto.approval.CurrencyType;
import com.chint.interfaces.rest.ctrip.dto.approval.PassengerDetail;
import lombok.Data;
import java.util.List;
@Data
public class BusEndorsementDetail {
// 产品类型
private int productType;
// 乘客列表最多100名
private List<PassengerDetail> passengerList;
// 出发城市代码
private List<String> departCityCodes;
// 到达城市代码
private List<String> arrivalCityCodes;
// 出发开始日期
private String departBeginDate;
// 出发结束日期
private String departEndDate;
// 货币类型默认CNY
private CurrencyType currency;
// 价格默认为0
private float price;
// 跳过的字段位
private long skipFields;
// 预验证字段位
private long preVerifyFields;
// 总旅客数
private int totalTravelerCount;
// Getters and setters...
}

View File

@ -0,0 +1,13 @@
package com.chint.interfaces.rest.ctrip.dto.approval.endor;
public class BusSkipFields {
public static final long TripWay = 1;
public static final long DepartBeginDate = 2;
public static final long DepartEndDate = 4;
public static final long PassengerList = 8;
public static final long DepartCityCodeList = 16;
public static final long ArrivalCityCodeList = 32;
public static final long Price = 64;
public static final long Currency = 128;
// ... include other fields as necessary
}

View File

@ -0,0 +1,71 @@
package com.chint.interfaces.rest.ctrip.dto.approval.hotel;
import com.chint.interfaces.rest.ctrip.dto.approval.CurrencyType;
import com.chint.interfaces.rest.ctrip.dto.approval.PassengerDetail;
import java.util.List;
public class HotelEndorsementDetail {
// 产品类型
private HotelProductTypeEnum productType;
// 入住开始日期 - 格式: yyyy-MM-dd
private String checkInDateBegin;
// 入住结束日期 - 格式: yyyy-MM-dd
private String checkInDateEnd;
// 离店开始日期 - 格式: yyyy-MM-dd
private String checkOutDateBegin;
// 离店结束日期 - 格式: yyyy-MM-dd
private String checkOutDateEnd;
// 乘客列表
private List<PassengerDetail> passengerList;
// 入住国家ID列表
private List<String> checkInCountryIds;
// 入住国家代码列表
private List<String> checkInCountryCodes;
// 入住城市代码列表
private List<String> checkInCityCodes;
// 最高价格
private String maxPrice;
// 最低价格
private String minPrice;
// 货币类型 - 默认CNY
private CurrencyType currency;
// 最大星级
private String maxStarRating;
// 最小星级
private String minStarRating;
// 平均价格
private String averagePrice;
// 房间数量
private int roomCount;
// 跳过的字段位 - 用于标记不包含的字段
private long skipFields;
// 总房晚数
private int totalRoomNightCount;
// 房晚价格
private String roomNightPrice;
// 预验证字段位 - 用于标记需要预验证的字段
private long preVerifyFields;
// Getters and setters...
}

View File

@ -0,0 +1,13 @@
package com.chint.interfaces.rest.ctrip.dto.approval.hotel;
// HotelPreVerifyFields constants
public class HotelPreVerifyFields {
public static final long CheckInDateBegin = 1;
public static final long CheckInDateEnd = 2;
public static final long CheckOutDateBegin = 4;
public static final long CheckOutDateEnd = 8;
public static final long PassengerList = 16;
public static final long CheckInCityCodes = 32;
public static final long AveragePrice = 2048;
// ... include other fields as necessary
}

View File

@ -0,0 +1,15 @@
package com.chint.interfaces.rest.ctrip.dto.approval.hotel;
// HotelProductTypeEnum definition based on the provided image
public enum HotelProductTypeEnum {
Domestic(3), // 国内酒店
International(4); // 国际酒店
private final int value;
HotelProductTypeEnum(int value) {
this.value = value;
}
// Getter...
}

View File

@ -0,0 +1,20 @@
package com.chint.interfaces.rest.ctrip.dto.approval.hotel;
// HotelSkipFields constants based on the provided image
public class HotelSkipFields {
public static final long CheckInDateBegin = 1;
public static final long CheckInDateEnd = 2;
public static final long CheckOutDateBegin = 4;
public static final long CheckOutDateEnd = 8;
public static final long PassengerList = 16;
public static final long CheckInCityCodes = 32;
public static final long MaxPrice = 64;
public static final long MinPrice = 128;
public static final long Currency = 256;
public static final long MaxStarRating = 512;
public static final long MinStarRating = 1024;
public static final long AveragePrice = 2048;
public static final long RoomCount = 4096;
public static final long RoomNightPrice = 8192;
// ... include other fields as necessary
}

View File

@ -0,0 +1,36 @@
package com.chint.interfaces.rest.ctrip.dto.approval.pick;
import com.chint.interfaces.rest.ctrip.dto.approval.CurrencyType;
import com.chint.interfaces.rest.ctrip.dto.approval.PassengerDetail;
import java.util.List;
public class CarPickUpEndorsementDetail {
// 产品类型
private int productType;
// 乘客列表, 最多100名
private List<PassengerDetail> passengerList;
// 城市代码
private String cities;
// 接车开始日期
private String pickUpBeginDate;
// 接车结束日期
private String pickUpEndDate;
// 送车开始日期
private String dropOffBeginDate;
// 送车结束日期
private String dropOffEndDate;
// 货币类型, 默认CNY
private CurrencyType currency;
// 价格默认为0
private float price;
// 车辆组
private String vehicleGroup;
// 有效性金额
private int effectivenessAmount;
// 跳过的字段位
private long skipFields;
// Getters and setters...
}

View File

@ -0,0 +1,19 @@
package com.chint.interfaces.rest.ctrip.dto.approval.pick;
// CarPickUpSkipFields bit field constants
import lombok.Data;
@Data
public class CarPickUpSkipFields {
public static final long PassengerList = 1; // 乘客列表
public static final long Cities = 2; // 城市代码
public static final long PickUpBeginDate = 4; // 接车开始日期
public static final long PickUpEndDate = 8; // 接车结束日期
public static final long DropOffBeginDate = 16; // 送车开始日期
public static final long DropOffEndDate = 32; // 送车结束日期
public static final long Price = 64; // 价格
public static final long Currency = 128; // 货币类型
public static final long VehicleGroup = 256; // 车辆组
// ... include other fields as necessary
}

View File

@ -0,0 +1,31 @@
package com.chint.interfaces.rest.ctrip.dto.approval.plan;
import com.chint.interfaces.rest.ctrip.dto.approval.PassengerDetail;
import lombok.Data;
import java.util.List;
@Data
public class TravelPlanEndorsementDetail {
// 出差开始日期
private String travelStartDate;
// 出差结束日期
private String travelEndDate;
// 出发城市代码
private String departCities;
// 到达城市代码
private String arriveCities;
// 允许的产品类型列表
private List<String> allowProductTypes;
// 租车取车模式类型列表
private List<String> carPickupPatternTypes;
// 乘客列表
private List<PassengerDetail> passengerList;
// 酒店是否允许延迟退房
private boolean hotelCheckOutDelay;
// 预验证字段
private String preVerifyFields;
// Getters and setters...
}

View File

@ -0,0 +1,42 @@
package com.chint.interfaces.rest.ctrip.dto.approval.quick;
import com.chint.interfaces.rest.ctrip.dto.approval.CurrencyType;
import com.chint.interfaces.rest.ctrip.dto.approval.PassengerDetail;
import lombok.Data;
import java.util.List;
@Data
public class CarQuickEndorsementDetail {
// 产品类型
private int productType;
// 乘客列表, 最多100名
private List<PassengerDetail> passengerList;
// 城市代码
private String cities;
// 公司地址列表
private List<CompanyAddressDetail> companyAddressList;
// 到达地址列表
private List<CompanyAddressDetail> arrivalAddressList;
// 开始使用日期
private String beginUseDate;
// 结束使用日期
private String endUseDate;
// 使用时间列表
private List<UseTimeDetail> useTimeList;
// 货币类型, 默认CNY
private CurrencyType currency;
// 价格默认为0
private float price;
// 车辆组
private String vehicleGroup;
// 有效性金额
private int effectivenessAmount;
// 跳过的字段位
private long skipFields;
// 到达城市代码
private String arrivalCities;
// Getters and setters...
}

View File

@ -0,0 +1,16 @@
package com.chint.interfaces.rest.ctrip.dto.approval.quick;
public class CarQuickSkipFields {
public static final long PassengerList = 1; // 乘客列表
public static final long Cities = 2; // 城市代码
public static final long CompanyAddressList = 4; // 公司地址列表
public static final long BeginUseDate = 8; // 开始使用日期
public static final long EndUseDate = 16; // 结束使用日期
public static final long UseTimeList = 32; // 使用时间列表
public static final long Currency = 64; // 货币类型
public static final long Price = 128; // 价格
public static final long VehicleGroup = 256; // 车辆组
public static final long ArrivalAddressList = 512; // 到达地址列表
public static final long ArrivalCities = 1024; // 到达城市代码
// ... include other fields as necessary
}

View File

@ -0,0 +1,17 @@
package com.chint.interfaces.rest.ctrip.dto.approval.quick;
public class CompanyAddressDetail {
// 坐标类型
private String coordinateType;
// 地址名称
private String addressName;
// 经度
private String longitude;
// 纬度
private String latitude;
// 允许半径
private int allowRadius;
// Getters and setters...
}

View File

@ -0,0 +1,12 @@
package com.chint.interfaces.rest.ctrip.dto.approval.quick;
import lombok.Data;
// RankInfo class
@Data
public class RankInfo {
// 职级名称
private String rankName;
// Getters and setters...
}

View File

@ -0,0 +1,20 @@
package com.chint.interfaces.rest.ctrip.dto.approval.quick;
// Enumeration for the provided table related to rank or status
public enum RankStatus {
UNKNOWN(1), // 未知
LEVEL_2(2), // 二级
LEVEL_3(3), // 三级
LEVEL_4(4), // 四级
// ... other levels
LEVEL_7(7); // 七级
private final int id;
RankStatus(int id) {
this.id = id;
}
// Getter...
}

View File

@ -0,0 +1,15 @@
package com.chint.interfaces.rest.ctrip.dto.approval.quick;
// UseTimeDetail class
import lombok.Data;
@Data
public class UseTimeDetail {
// 开始使用时间, 格式为HHmm
private String beginUseTime;
// 结束使用时间, 格式为HHmm
private String endUseTime;
// Getters and setters...
}

View File

@ -0,0 +1,44 @@
package com.chint.interfaces.rest.ctrip.dto.approval.rental;
import com.chint.interfaces.rest.ctrip.dto.approval.CurrencyType;
import com.chint.interfaces.rest.ctrip.dto.approval.PassengerDetail;
import java.util.List;
public class CarRentalEndorsementDetail {
// 产品类型
private int productType;
// 乘客列表最多100名
private List<PassengerDetail> passengerList;
// 接车城市代码
private String pickUpCities;
// 送车城市代码
private String dropOffCities;
// 接车开始日期
private String pickUpBeginDate;
// 接车结束日期
private String pickUpEndDate;
// 送车开始日期
private String dropOffBeginDate;
// 送车结束日期
private String dropOffEndDate;
// 货币类型默认CNY
private CurrencyType currency;
// 价格默认为0
private float price;
// 车辆组
private String vehicleGroup;
// 跳过的字段位
private long skipFields;
// 预验证字段位
private long preVerifyFields;
// 有效性金额
private int effectivenessAmount;
// 版本号
private int version;
// 总旅客数
private int totalTravelerCount;
// Getters and setters...
}

View File

@ -0,0 +1,15 @@
package com.chint.interfaces.rest.ctrip.dto.approval.rental;
public class CarRentalSkipFieldType {
public static final long PassengerList = 1;
public static final long PickUpCities = 2;
public static final long DropOffCities = 4;
public static final long PickUpBeginDate = 8;
public static final long PickUpEndDate = 16;
public static final long DropOffBeginDate = 32;
public static final long DropOffEndDate = 64;
public static final long Price = 128;
public static final long Currency = 256;
public static final long VehicleGroup = 512;
// ... include other fields as necessary
}

View File

@ -0,0 +1,17 @@
package com.chint.interfaces.rest.ctrip.dto.approval.train;
// SeatTypeEnum definition
public enum SeatTypeEnum {
YZ(201), // 硬座
RZ(203), // 软座
// ... other seat types with their corresponding integer values
EDSR(314); // 二等卧
private final int value;
SeatTypeEnum(int value) {
this.value = value;
}
// Getter...
}

View File

@ -0,0 +1,69 @@
package com.chint.interfaces.rest.ctrip.dto.approval.train;
import com.chint.interfaces.rest.ctrip.dto.approval.CurrencyType;
import com.chint.interfaces.rest.ctrip.dto.approval.PassengerDetail;
import java.util.List;
// TrainEndorsementDetail class definition
public class TrainEndorsementDetail {
// 火车产品类型
private TrainProductTypeEnum productType;
// 订票类型列表 - 1张, 2张, 3张, 超过3张
private List<String> bookingTypeList;
// 订单ID列表
private List<String> orderIDList;
// 行程类型 - 单程(1) or 往返(2)
private TripTypeEnum tripType;
// 出发日期开始 - 格式: yyyy-MM-dd
private String departDateBegin;
// 出发日期结束 - 格式: yyyy-MM-dd
private String departDateEnd;
// 返回日期开始 - 格式: yyyy-MM-dd
private String returnDateBegin;
// 返回日期结束 - 格式: yyyy-MM-dd
private String returnDateEnd;
// 乘客列表 - 无限制
private List<PassengerDetail> passengerList;
// 到达城市代码列表 - 最多1000个
private List<String> arrivalCityCodes;
// 出发城市代码列表 - 最多1000个
private List<String> departCityCodes;
// 价格 - 可为负数, 默认为0
private String price;
// 货币类型 - 默认CNY
private CurrencyType currency;
// 座位类型
private List<SeatTypeEnum> seatType;
// 跳过的字段位 - 用于标记不包含的字段
private long skipFields;
// 旅客数量 - 默认为0
private int travelerCount;
// 预验证字段位 - 用于标记需要预验证的字段
private long preVerifyFields;
// 列车车次列表 - 如G, D, C, Z, T, K等
private List<String> trainVehicleTypeList;
// 总旅客数量 - 用于统计
private int totalTravelerCount;
// Getters and setters...
}

View File

@ -0,0 +1,14 @@
package com.chint.interfaces.rest.ctrip.dto.approval.train;
// TrainPreVerifyFields bit field constants
public class TrainPreVerifyFields {
public static final long TripType = 1;
public static final long DepartDateBegin = 2;
public static final long DepartDateEnd = 4;
public static final long ReturnDateBegin = 8;
public static final long ReturnDateEnd = 16;
public static final long PassengerList = 32;
public static final long FromCities = 64;
public static final long ToCities = 128;
// ... include other fields as necessary
}

View File

@ -0,0 +1,14 @@
package com.chint.interfaces.rest.ctrip.dto.approval.train;
// TrainProductTypeEnum definition
public enum TrainProductTypeEnum {
Domestic(5); // 国内火车
private final int value;
TrainProductTypeEnum(int value) {
this.value = value;
}
// Getter...
}

View File

@ -0,0 +1,17 @@
package com.chint.interfaces.rest.ctrip.dto.approval.train;
// TrainSkipFields bit field constants
public class TrainSkipFields {
public static final long TripType = 1;
public static final long DepartDateBegin = 2;
public static final long DepartDateEnd = 4;
public static final long ReturnDateBegin = 8;
public static final long ReturnDateEnd = 16;
public static final long PassengerList = 32;
public static final long FromCities = 64;
public static final long ToCities = 128;
public static final long Price = 256;
public static final long Currency = 512;
public static final long SeatType = 1024;
// ... include other fields as necessary
}

View File

@ -0,0 +1,12 @@
package com.chint.interfaces.rest.ctrip.dto.approval.train;
public enum TripTypeEnum {
SingleTrip(3), // 国内酒店
RoundTrip(4); // 国际酒店
private final int value;
TripTypeEnum(int value) {
this.value = value;
}
}

View File

@ -0,0 +1,20 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.request;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class AuthInfo {
// appKey
private String appKey;
// 访问令牌
private String accessToken;
// Getters and setters...
public static AuthInfo of(String appKey, String accessToken) {
return new AuthInfo(appKey, accessToken);
}
}

View File

@ -0,0 +1,21 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.request;
import lombok.Data;
@Data
public class BookingRelatedApiRequest {
// 语言
private String language;
// API名称
private String apiName;
// 认证信息
private AuthInfo authInfo;
// 请求内容
private ValuateBudgetRequestType requestContent;
// Getters and setters...
public static BookingRelatedApiRequestBuilder builder() {
return new BookingRelatedApiRequestBuilder();
}
}

View File

@ -0,0 +1,272 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.request;
import java.util.ArrayList;
public class BookingRelatedApiRequestBuilder {
private BookingRelatedApiRequest request = new BookingRelatedApiRequest();
public BookingRelatedApiRequestBuilder language(String language) {
request.setLanguage(language);
return this;
}
public BookingRelatedApiRequestBuilder apiName(String apiName) {
request.setApiName(apiName);
return this;
}
public AuthInfoBuilder authInfo() {
return new AuthInfoBuilder(this, request);
}
public ValuateBudgetRequestTypeBuilder requestContent() {
return new ValuateBudgetRequestTypeBuilder(this, request);
}
public BookingRelatedApiRequest build() {
return request;
}
// Sub-builder for AuthInfo (Example, needs implementation)
public static class AuthInfoBuilder {
private final BookingRelatedApiRequestBuilder parentBuilder;
private final BookingRelatedApiRequest request;
public AuthInfoBuilder(BookingRelatedApiRequestBuilder parentBuilder, BookingRelatedApiRequest request) {
this.parentBuilder = parentBuilder;
this.request = request;
}
public AuthInfoBuilder details(String appKey, String accessToken) {
AuthInfo authInfo = new AuthInfo(appKey,accessToken); // Construct AuthInfo with parameters
request.setAuthInfo(authInfo);
return this;
}
public BookingRelatedApiRequestBuilder done() {
return parentBuilder;
}
}
// Sub-builder for ValuateBudgetRequestType
public static class ValuateBudgetRequestTypeBuilder {
private final BookingRelatedApiRequestBuilder parentBuilder;
private final BookingRelatedApiRequest request;
private ValuateBudgetRequestType requestContent = new ValuateBudgetRequestType();
public ValuateBudgetRequestTypeBuilder(BookingRelatedApiRequestBuilder parentBuilder, BookingRelatedApiRequest request) {
this.parentBuilder = parentBuilder;
this.request = request;
}
public ValuationBaseInfoBuilder valuationBaseInfo() {
return new ValuationBaseInfoBuilder(this, requestContent);
}
public ValuationProductInfoBuilder valuationProductInfo() {
return new ValuationProductInfoBuilder(this, requestContent);
}
public BookingRelatedApiRequestBuilder done() {
request.setRequestContent(requestContent);
return parentBuilder;
}
}
// Sub-builder for ValuationBaseInfo
public static class ValuationBaseInfoBuilder {
private final ValuateBudgetRequestTypeBuilder parentBuilder;
private final ValuateBudgetRequestType requestContent;
private ValuationBaseInfo baseInfo = new ValuationBaseInfo();
public ValuationBaseInfoBuilder(ValuateBudgetRequestTypeBuilder parentBuilder, ValuateBudgetRequestType requestContent) {
this.parentBuilder = parentBuilder;
this.requestContent = requestContent;
}
public ValuationBaseInfoBuilder corpID(String corpID) {
baseInfo.setCorpID(corpID);
return this;
}
public ValuationBaseInfoBuilder eID(String eID) {
baseInfo.setEID(eID);
return this;
}
public ValuationBaseInfoBuilder rankName(String rankName) {
baseInfo.setRankName(rankName);
return this;
}
public ValuateBudgetRequestTypeBuilder done() {
requestContent.setValuationBaseInfo(baseInfo);
return parentBuilder;
}
}
// Sub-builder for ValuationProductInfo (Example, needs further implementation for FlightProductInfo, TrainProductInfo, etc.)
public static class ValuationProductInfoBuilder {
private final ValuateBudgetRequestTypeBuilder parentBuilder;
private final ValuateBudgetRequestType requestContent;
private ValuationProductInfo productInfo = new ValuationProductInfo();
public ValuationProductInfoBuilder(ValuateBudgetRequestTypeBuilder parentBuilder, ValuateBudgetRequestType requestContent) {
this.parentBuilder = parentBuilder;
this.requestContent = requestContent;
}
// Method to add FlightProductInfo, TrainProductInfo, etc.
public ValuationProductInfoBuilder addFlightProductInfo(FlightProductInfo flightProductInfo) {
if (productInfo.getFlightProductInfo() == null) {
productInfo.setFlightProductInfo(new ArrayList<>());
}
productInfo.getFlightProductInfo().add(flightProductInfo);
return this;
}
// Similar methods for adding TrainProductInfo, etc.
public ValuationProductInfoBuilder addTrainProductInfo(TrainProductInfo trainProductInfo) {
if (productInfo.getTrainProductInfo() == null) {
productInfo.setTrainProductInfo(new ArrayList<>());
}
productInfo.getTrainProductInfo().add(trainProductInfo);
return this;
}
public ValuateBudgetRequestTypeBuilder done() {
requestContent.setValuationProductInfo(productInfo);
return parentBuilder;
}
}
// Sub-builder for FlightProductInfo
public static class FlightProductInfoBuilder {
private final ValuationProductInfoBuilder parentBuilder;
private FlightProductInfo flightProductInfo = new FlightProductInfo();
public FlightProductInfoBuilder(ValuationProductInfoBuilder parentBuilder) {
this.parentBuilder = parentBuilder;
}
public FlightProductInfoBuilder flightWay(String flightWay) {
flightProductInfo.setFlightWay(flightWay);
return this;
}
public FlightProductInfoBuilder classType(String classType) {
flightProductInfo.setClassType(classType);
return this;
}
public FlightProductInfoBuilder searchRouteNum(Integer searchRouteNum) {
flightProductInfo.setSearchRouteNum(searchRouteNum);
return this;
}
public FlightProductInfoBuilder airLineCode(String airLineCode) {
flightProductInfo.setAirLineCode(airLineCode);
return this;
}
public FlightProductInfoBuilder addRouteInfo(RouteInfo routeInfo) {
if (flightProductInfo.getRoutes() == null) {
flightProductInfo.setRoutes(new ArrayList<>());
}
flightProductInfo.getRoutes().add(routeInfo);
return this;
}
public ValuationProductInfoBuilder done() {
parentBuilder.addFlightProductInfo(flightProductInfo);
return parentBuilder;
}
}
// Sub-builder for TrainProductInfo
public static class TrainProductInfoBuilder {
private final ValuationProductInfoBuilder parentBuilder;
private TrainProductInfo trainProductInfo = new TrainProductInfo();
public TrainProductInfoBuilder(ValuationProductInfoBuilder parentBuilder) {
this.parentBuilder = parentBuilder;
}
public TrainProductInfoBuilder departStation(String departStation) {
trainProductInfo.setDepartStation(departStation);
return this;
}
public TrainProductInfoBuilder arriveStation(String arriveStation) {
trainProductInfo.setArriveStation(arriveStation);
return this;
}
public TrainProductInfoBuilder departDate(String departDate) {
trainProductInfo.setDepartDate(departDate);
return this;
}
public TrainProductInfoBuilder trainNo(String trainNo) {
trainProductInfo.setTrainNo(trainNo);
return this;
}
public TrainProductInfoBuilder departCityID(String departCityID) {
trainProductInfo.setDepartCityID(departCityID);
return this;
}
public TrainProductInfoBuilder arriveCityID(String arriveCityID) {
trainProductInfo.setArriveCityID(arriveCityID);
return this;
}
public TrainProductInfoBuilder returnNoTicket(boolean returnNoTicket) {
trainProductInfo.setReturnNoTicket(returnNoTicket);
return this;
}
public ValuationProductInfoBuilder done() {
parentBuilder.addTrainProductInfo(trainProductInfo);
return parentBuilder;
}
}
// Sub-builder for RouteInfo
public static class RouteInfoBuilder {
private RouteInfo routeInfo = new RouteInfo();
public RouteInfoBuilder arriveCityCode(String arriveCityCode) {
routeInfo.setArriveCityCode(arriveCityCode);
return this;
}
public RouteInfoBuilder departCityCode(String departCityCode) {
routeInfo.setDepartCityCode(departCityCode);
return this;
}
public RouteInfoBuilder departDate(String departDate) {
routeInfo.setDepartDate(departDate);
return this;
}
public RouteInfoBuilder arriveCityID(String arriveCityID) {
routeInfo.setArriveCityID(arriveCityID);
return this;
}
public RouteInfoBuilder departCityID(String departCityID) {
routeInfo.setDepartCityID(departCityID);
return this;
}
public RouteInfo build() {
return routeInfo;
}
}
}

View File

@ -0,0 +1,18 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.request;
import lombok.Data;
import java.util.List;
@Data
public class FlightProductInfo {
// 航班方式
private String flightWay;
// 舱位类型
private String classType;
// 航线信息
private List<RouteInfo> routes;
private Integer searchRouteNum;
private String airLineCode;
}

View File

@ -0,0 +1,5 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.request;
public enum LanguagesEnum {
ZH, EN
}

View File

@ -0,0 +1,17 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.request;
import lombok.Data;
@Data
public class RouteInfo {
// 到达城市代码
private String arriveCityCode;
// 出发城市代码
private String departCityCode;
// 出发日期
private String departDate;
private String arriveCityID;
private String departCityID;
// Getters and setters...
}

View File

@ -0,0 +1,14 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.request;
import lombok.Data;
@Data
public class TrainProductInfo {
private String departStation;
private String arriveStation;
private String departDate; //出发日期 格式 yyyy-MM-dd
private String trainNo; //车次
private String departCityID; //出发城市id车站和城市id配套二传一都传优先使用车站
private String arriveCityID; //到达城市id车站和城市id配套二传一都传优先使用车站
private boolean returnNoTicket; //是否返回无票价格默认否
}

View File

@ -0,0 +1,18 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.request;
import lombok.Data;
import org.apache.commons.codec.language.bm.Languages;
import java.util.List;
@Data
public class ValuateBudgetRequestType {
// 估算基础信息
private ValuationBaseInfo valuationBaseInfo;
// 产品信息
private ValuationProductInfo valuationProductInfo;
private LanguagesEnum languages;
// Getters and setters...
}

View File

@ -0,0 +1,16 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.request;
import lombok.Data;
@Data
public class ValuationBaseInfo {
// 公司ID
private String corpID;
// 员工ID
private String eID;
// 职级名称
private String rankName;
// Getters and setters...
}

View File

@ -0,0 +1,14 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.request;
import lombok.Data;
import java.util.List;
@Data
public class ValuationProductInfo {
// Allowable product types like "DOMESTIC_FLIGHT", "INTERNATIONAL_FLIGHT", etc.
private List<FlightProductInfo> flightProductInfo;
private List<TrainProductInfo> trainProductInfo;
// Getters and setters...
}

View File

@ -0,0 +1,21 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.response;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class AirlineInfo {
// 航班价格类型
private Integer priceType;
// 航空公司名称
private String airlineName;
// 起飞时间
private String departTime;
// 起飞机场
private String departPort;
// 到达机场
private String arrivalPort;
// 航班折扣
private BigDecimal discount;
}

View File

@ -0,0 +1,5 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.response;
public enum AvailableProductEnum {
UNKNOWN,FLIGHT,HOTEL,TRAIN
}

View File

@ -0,0 +1,18 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.response;
import com.chint.interfaces.rest.ctrip.dto.ResponseStatus;
import lombok.Data;
import java.util.List;
@Data
public class BookingRelatedApiResponse {
// 请求相关API的响应
private ResponseStatus status;
// 数据内容
private ValuateBudgetResponseType data;
// Getters and Setters...
}

View File

@ -0,0 +1,29 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.response;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
public class FlightValuationResult {
// 航班总价格
private BigDecimal totalPrice;
// 航班最高价格
private BigDecimal maxPrice;
// 航班中等价格
private BigDecimal mediumPrice;
// 航班最高舱位类别
private String highestClass;
private List<AirlineInfo> airlineInfoList;
// 航班结果描述
private String resultDescription;
// 航班较低的价格
private BigDecimal lessPrice;
// 航班更高的价格
private BigDecimal morePrice;
// Getters and Setters...
}

View File

@ -0,0 +1,18 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.response;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class HotelValuationResult {
// 币种
private String currency;
// 酒店最高价格
private BigDecimal maxPrice;
// 酒店结果描述
private String resultDescription;
// Getters and Setters...
}

View File

@ -0,0 +1,15 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.response;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class SeatMaxPriceInfo {
// 座位最高价格信息
private String seatCode; // 座位代码
private BigDecimal maxPrice; // 最高价格
// Getters and Setters...
}

View File

@ -0,0 +1,13 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.response;
import lombok.Data;
@Data
public class TrainTypeDurationMinute {
// 火车类型
private TrainTypeEnum trainType; // 火车类型枚举
private Float maxDurationMinutes; // 最大持续时间分钟
private Integer minDurationMinutes; // 最小持续时间分钟
// Getters and Setters...
}

View File

@ -0,0 +1,9 @@
package com.chint.interfaces.rest.ctrip.dto.estimate.response;
public enum TrainTypeEnum {
G, // 高铁
D, // 动车
T, // 特快
K, // 快速
// ... Add additional train types as necessary
}

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