commit 53777df214264641a4dd6e81e5c8c49664310406 Author: Yuan <1450637472@qq.com> Date: Mon Sep 15 18:52:59 2025 +0800 init:宁夏武警跳转初始化 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/.gitignore @@ -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/ diff --git a/mvnw b/mvnw new file mode 100644 index 0000000..a16b543 --- /dev/null +++ b/mvnw @@ -0,0 +1,310 @@ +#!/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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# 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 /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 + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -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 "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; 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="`which 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 + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# 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/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# 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. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +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 "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -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 + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..c8d4337 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,182 @@ +@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 Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@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 "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\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 DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_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 DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_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('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@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 "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\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% + +exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e7f81ec --- /dev/null +++ b/pom.xml @@ -0,0 +1,114 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.5.3 + + + com.saye + hgd-dmz + 0.0.1-SNAPSHOT + war + hgd-dmz + Demo project for Spring Boot + + 1.8 + UTF-8 + UTF-8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-tomcat + provided + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.apache.commons + commons-pool2 + + + com.alibaba + fastjson + 1.2.73 + + + + org.projectlombok + lombok + + + + commons-net + commons-net + 3.8.0 + + + + com.alipay.sdk + alipay-sdk-java + 4.16.2.ALL + + + + com.github.wechatpay-apiv3 + wechatpay-apache-httpclient + 0.2.2 + + + + org.apache.httpcomponents + httpasyncclient + + + + org.apache.poi + poi + 3.14 + + + org.apache.poi + poi-ooxml + 3.14 + + + commons-io + commons-io + 2.6 + + + cn.hutool + hutool-all + 5.8.28 + + + + + + ROOT + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/src/main/java/com/saye/hgddmz/HgdDmzApplication.java b/src/main/java/com/saye/hgddmz/HgdDmzApplication.java new file mode 100644 index 0000000..2fe0e28 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/HgdDmzApplication.java @@ -0,0 +1,13 @@ +package com.saye.hgddmz; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class HgdDmzApplication { + + public static void main(String[] args) { + SpringApplication.run(HgdDmzApplication.class, args); + } + +} diff --git a/src/main/java/com/saye/hgddmz/ServletInitializer.java b/src/main/java/com/saye/hgddmz/ServletInitializer.java new file mode 100644 index 0000000..e71caf9 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/ServletInitializer.java @@ -0,0 +1,13 @@ +package com.saye.hgddmz; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +public class ServletInitializer extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(HgdDmzApplication.class); + } + +} diff --git a/src/main/java/com/saye/hgddmz/commons/JsonResult.java b/src/main/java/com/saye/hgddmz/commons/JsonResult.java new file mode 100644 index 0000000..424bba4 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/JsonResult.java @@ -0,0 +1,120 @@ +package com.saye.hgddmz.commons; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.Serializable; + +/** + * 用于封装AJAX调用以后的JSON返回值 + * 其中正确返回值: + * {state:0, data:返回数据, message:错误消息} + * 错误返回值: + * {state:1, data:null, message:错误消息} + **/ +public class JsonResult implements Serializable { + + private static final long serialVersionUID = -3644950655568598241L; + //定义jackson对象 + private static final ObjectMapper MAPPER = new ObjectMapper(); + + + /** + * 返回是否成功的状态, 0表示成功, + * 1或其他值 表示失败 + */ + private boolean state; + /** + * 成功时候,返回的JSON数据 + */ + private Object data; + /** + * 是错误时候的错误消息 + */ + private String message; + + + public JsonResult() { + } + + public JsonResult(boolean state, Object data, String message) { + this.state = state; + this.data = data; + this.message = message; + } + + public JsonResult(Throwable e){ + state = false; + data=null; + message=e.getMessage(); + } + + public JsonResult(Object data){ + state = true; + this.data=data; + message=""; + } + + public boolean isState() { + return state; + } + + public void setState(boolean state) { + this.state = state; + } + + public Object getData() { + return data; + } + + + public void setData(Object data) { + this.data = data; + } + + + public String getMessage() { + return message; + } + + + public void setMessage(String message) { + this.message = message; + } + + public static String jsonResultSuccess(Object data, String message){ + JsonResult jsonResult=new JsonResult(); + jsonResult.setState(true); + jsonResult.setMessage(message); + jsonResult.setData(data); + return ObjectToJson(jsonResult); + } + + + public static String jsonResultFalse(String message){ + JsonResult jsonResult=new JsonResult(); + jsonResult.setState(false); + jsonResult.setMessage(message); + return ObjectToJson(jsonResult); + } + + /** + * 将对象转化为json字符串 + * @param data + * @return + */ + public static String ObjectToJson(Object data){ + try{ + String string = MAPPER.writeValueAsString(data); + return string; + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return null; + } + + @Override + public String toString() { + return "JsonResult [state=" + state + ", data=" + data + ", message=" + message + "]"; + } +} \ No newline at end of file diff --git a/src/main/java/com/saye/hgddmz/commons/TokenGenerateUtil.java b/src/main/java/com/saye/hgddmz/commons/TokenGenerateUtil.java new file mode 100644 index 0000000..489f62b --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/TokenGenerateUtil.java @@ -0,0 +1,95 @@ +package com.saye.hgddmz.commons; + +import org.apache.commons.codec.CharEncoding; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; + +/** + *

+ * token生成工具类 + *

+ * + * @author caoshiyan + * @version V1.0 + * @date 2015年12月29日 上午10:16:14 + * @modificationHistory=========================逻辑或功能性重大变更记录 + * @modify by user: {修改人} 2015年12月29日 + * @since + */ +public class TokenGenerateUtil { + + /** + *

+ * MD5加密工具类 + *

+ * @author caoshiyan + * @version V1.0 + * @date 2015年11月30日 下午4:40:16 + * @param s + * @return + * + * @modificationHistory=========================逻辑或功能性重大变更记录 + * @modify by user: {修改人} 2015年11月30日 + * @modify by reason:{方法名}:{原因} + * @since + */ + public final static String md5(String s) { + char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + try { + MessageDigest mdTemp = MessageDigest.getInstance("MD5"); + try { + // 最重要的是这句,需要加上编码类型 + mdTemp.update(s.getBytes(CharEncoding.UTF_8)); + } catch (UnsupportedEncodingException e) { + mdTemp.update(s.getBytes()); + } + byte[] md = mdTemp.digest(); + int j = md.length; + char str[] = new char[j * 2]; + int k = 0; + for (int i = 0; i < j; i++) { + byte byte0 = md[i]; + str[k++] = hexDigits[byte0 >>> 4 & 0xf]; + str[k++] = hexDigits[byte0 & 0xf]; + } + return new String(str).toUpperCase(); + } catch (Exception e) { + return null; + } + } + + /** + *

+ * 生成token + *

+ * @author caoshiyan + * @version V1.0 + * @date 2015年11月18日 下午6:28:01 + * @param url GET请求URL带参数串;POST请求URL不带参数串,参数以JSON格式传入paramJson + * @param paramJson POST参数JSON格式 + * @param secret 加密secret + * @return String 生成的token值 + * + * @modificationHistory=========================逻辑或功能性重大变更记录 + * @modify by user: {修改人} 2015年11月18日 + * @modify by reason:{方法名}:{原因} + * @since + */ + public final static String buildToken(String url, String paramJson, String secret) { + String tempUrl = null; + tempUrl = url.substring("http://".length()); + int index = tempUrl.indexOf("/"); + String URI = tempUrl.substring(index); + String[] ss = URI.split("\\?"); + if (ss.length > 1) { + return md5(ss[0] + ss[1] + secret); + } else { + return md5(ss[0] + paramJson + secret); + } + } + public static void main(String[] args) { + System.out.println(md5("/webapi/service/vss/getPlatEncodeDeviceResList{\"pageNo\":1,\"pageSize\":1000,\"appkey\":\"8a3018ac\",\"time\":1610594097178}69befa1eca0644af8000fd23d7b8c0f7")); + } +} +///webapi/service/vss/getPlatEncodeDeviceResList{"pageNo":1,"pageSize":1000,"appkey":"8a3018ac","time":1610594044620}69befa1eca0644af8000fd23d7b8c0f7 diff --git a/src/main/java/com/saye/hgddmz/commons/date/DateDUtil.java b/src/main/java/com/saye/hgddmz/commons/date/DateDUtil.java new file mode 100644 index 0000000..48acf42 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/date/DateDUtil.java @@ -0,0 +1,296 @@ +package com.saye.hgddmz.commons.date; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +public class DateDUtil { + + + public static String yyyy_MM_dd = "yyyy-MM-dd"; + public static String yyyyMMdd = "yyyyMMdd"; + public static String yyyyMM = "yyyyMM"; + public static String yyyy_MM = "yyyy-MM"; + public static String yyyy_MM_dd_HH_00 = "yyyy-MM-dd HH:00"; + public static String yyyy_MM_dd_HH_mm = "yyyy-MM-dd HH:mm"; + public static String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss"; + public static String yyyy_MM_dd_HH_mm_ss_SS = "yyyy-MM-dd HH:mm:ss.SS"; + public static String yyyyMMddHHmm = "yyyyMMddHHmm"; + public static String yyyyMMddHHmmss = "yyyyMMddHHmmss"; + public static String yyyyMMddHHmmssSS = "yyyyMMddHHmmssSS"; + public static String yyMMdd = "yyMMdd"; + public static String yyyy_MM_dd_00_00 = "yyyy-MM-dd 00:00"; + + /** + * 将字符串时间改成Date类型 + * @param format + * @param dateStr + * @return + */ + public static Date strToDate(String format,String dateStr) { + + Date date = null; + + try { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format); + date = simpleDateFormat.parse(dateStr); + } catch (ParseException e) { + e.printStackTrace(); + } + + return date; + } + + + /** + * 将Date时间转成字符串 + * @param format + * @param date + * @return + */ + public static String DateToStr(String format,Date date){ + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format); + + return simpleDateFormat.format(date); + } + + + + /** + * 获取2个字符日期的天数差 + * @param p_startDate + * @param p_endDate + * @return 天数差 + */ + public static long getDaysOfTowDiffDate( String p_startDate, String p_endDate ){ + + Date l_startDate = DateDUtil.strToDate(DateDUtil.yyyy_MM_dd, p_startDate); + Date l_endDate = DateDUtil.strToDate(DateDUtil.yyyy_MM_dd, p_endDate); + long l_startTime = l_startDate.getTime(); + long l_endTime = l_endDate.getTime(); + long betweenDays = (long) ( ( l_endTime - l_startTime ) / ( 1000 * 60 * 60 * 24 ) ); + return betweenDays; + } + + + /** + * 获取2个字符日期的天数差 + * @param l_startDate + * @param l_endDate + * @return 天数差 + */ + public static long getDaysOfTowDiffDate( Date l_startDate, Date l_endDate ){ + + long l_startTime = l_startDate.getTime(); + long l_endTime = l_endDate.getTime(); + long betweenDays = (long) ( ( l_endTime - l_startTime ) / ( 1000 * 60 * 60 * 24 ) ); + return betweenDays; + } + + + /** + * 给出日期添加一段时间后的日期 + * @param dateStr + * @param plus + * @return + */ + public static String getPlusDays(String format,String dateStr,long plus){ + + Date date = DateDUtil.strToDate(format, dateStr); + + long time = date.getTime()+ plus*24*60*60*1000; + + + return DateDUtil.DateToStr(format,new Date(time)); + } + + + /** + * 给出日期添加一段时间后的日期 + * @param format + * @param date + * @param plus + * @return + */ + public static String getPlusDays(String format,Date date,long plus){ + + + long time = date.getTime()+ plus*24*60*60*1000; + + + return DateDUtil.DateToStr(format,new Date(time)); + } + + /** + * 给出日期添加一段时间前的日期 + * @param format + * @param date + * @param forth + * @return + */ + public static String getForthDays(String format,Date date,long forth){ + + + long time = date.getTime()- forth*24*60*60*1000; + + + return DateDUtil.DateToStr(format,new Date(time)); + } + + /** + * 给出时间添加几个小时后的时间 + * @param format + * @param dateStr + * @param plus + * @return + */ + public static String getPlusHours(String format,String dateStr,long plus){ + + Date date = DateDUtil.strToDate(format, dateStr); + + long time = date.getTime()+ plus*60*60*1000; + + + return DateDUtil.DateToStr(format,new Date(time)); + } + + /** + * 给出时间添加几个分钟后的时间 + * @param format + * @param dateStr + * @param plus + * @return + */ + public static String getPlusMinutes(String format,String dateStr,long plus){ + + Date date = DateDUtil.strToDate(format, dateStr); + + long time = date.getTime()+ plus*60*1000; + + + return DateDUtil.DateToStr(format,new Date(time)); + } + + /** + * 得到当前时间,格式如:yyyy-MM-dd HH:mm:ss:SS + * @return + */ + public static String getCurrentTime(){ + + String nowTime = DateDUtil.DateToStr(DateDUtil.yyyy_MM_dd_HH_mm_ss_SS, new Date()); + return nowTime; + } + + /** + * 得到当前时间,格式如:yyyy-MM-dd HH:mm:ss + * @return + */ + public static String getTheCurrentTime(){ + + String nowTime = DateDUtil.DateToStr(DateDUtil.yyyy_MM_dd_HH_mm_ss, new Date()); + return nowTime; + } + + /** + * 得到当前日期,格式如:yyyyMMdd + * @return + */ + public static String getCurrentDate(){ + + String nowDate = DateDUtil.DateToStr(DateDUtil.yyyyMMdd, new Date()); + return nowDate; + } + + /** + * 得到当前日期,格式如:yyyyMMdd + * @return + */ + public static String getCurrentDate(String format){ + + String nowDate = DateDUtil.DateToStr(format, new Date()); + return nowDate; + } + + /** + * 获取2个字符日期的分钟数差 + * @param p_startDate + * @param p_endDate + * @return 相差的分钟 + */ + public static long getMinutesOfTowDiffDate(String p_startDate, String p_endDate ){ + + Date l_startDate = DateDUtil.strToDate(DateDUtil.yyyy_MM_dd_HH_mm_ss_SS, p_startDate); + Date l_endDate = DateDUtil.strToDate(DateDUtil.yyyy_MM_dd_HH_mm_ss_SS, p_endDate); + long l_startTime = l_startDate.getTime(); + long l_endTime = l_endDate.getTime(); + long betweenMinutes = (long) ( ( l_endTime - l_startTime ) / ( 1000 * 60) ); + return betweenMinutes; + } + + /** + * 获取2个字符日期的分钟数差 + * @param p_startDate + * @param p_endDate + * @return 相差的分钟 + */ + public static long getMinutesOfTowDiffDateMin(String format,String p_startDate, String p_endDate ){ + + Date l_startDate = DateDUtil.strToDate(format, p_startDate); + Date l_endDate = DateDUtil.strToDate(format, p_endDate); + long l_startTime = l_startDate.getTime(); + long l_endTime = l_endDate.getTime(); + long betweenMinutes = (long) ( ( l_endTime - l_startTime ) / ( 1000 * 60) ); + return betweenMinutes; + } + public static long getMonthIntervalOfTowDiffDate(String p_startMonth, String p_endMonth){ + + Date l_startDate = DateDUtil.strToDate(DateDUtil.yyyy_MM, p_startMonth); + Date l_endDate = DateDUtil.strToDate(DateDUtil.yyyy_MM, p_endMonth); + + + Calendar calender = Calendar.getInstance(); + calender.setTime(l_startDate); + + long l_startMonth = calender.get(Calendar.MONTH)+1; + long l_startYear = calender.get(Calendar.YEAR); + + calender.setTime(l_endDate); + + long l_endMonth =calender.get(Calendar.MONTH)+1; + long l_endYear = calender.get(Calendar.YEAR); + + long betweenYear = l_endYear - l_startYear; + long betweenMonth = (long) ( l_endMonth - l_startMonth ) ; + + return betweenYear * 12 + betweenMonth; + } + + /** + * 将字符串日期转为cron表达式 + */ + public static String getCron(String execute_time) throws Exception{ + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(yyyy_MM_dd_HH_mm_ss); + Date date = simpleDateFormat.parse(execute_time); + SimpleDateFormat dateFormat = new SimpleDateFormat("ss mm HH dd MM ? yyyy"); + return dateFormat.format(date); + } + /** + * 获取当前年月日日期 + */ + + public static String getCDate(){ + Calendar now = Calendar.getInstance(); + String year=now.get(Calendar.YEAR)+""; + String month=(now.get(Calendar.MONTH) + 1) + ""; + String day=now.get(Calendar.DAY_OF_MONTH)+""; + if ((now.get(Calendar.MONTH) + 1) < 10) month = "0" + month; + if (now.get(Calendar.DAY_OF_MONTH) < 10) day= "0" + day; + String nowDate = year+"年"+month+"月"+day+"日"; + return nowDate; + } + + +} diff --git a/src/main/java/com/saye/hgddmz/commons/encrypt/EncryptUtil.java b/src/main/java/com/saye/hgddmz/commons/encrypt/EncryptUtil.java new file mode 100644 index 0000000..429157a --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/encrypt/EncryptUtil.java @@ -0,0 +1,31 @@ +package com.saye.hgddmz.commons.encrypt; + +import org.apache.commons.codec.binary.Base64; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +public class EncryptUtil { + + // AES ecb模式解密 key:秘钥 initVector:偏移量 encrypted:加密内容 + public static String decrypt(String key,String initVector,String encrypted) { + try { + IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8")); + SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); + + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); + cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); + byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted)); + + return new String(original); + } catch (Exception ex) { + ex.printStackTrace(); + } + return null; + } + + public static void main(String[] args) throws Exception { + System.out.println(decrypt("a6xdabhysfescfbu","encryptionIntVec","oYzamqnnyJ8GG6646PDYBQ==")); + } +} \ No newline at end of file diff --git a/src/main/java/com/saye/hgddmz/commons/entity/DepartEntity.java b/src/main/java/com/saye/hgddmz/commons/entity/DepartEntity.java new file mode 100644 index 0000000..fd44b44 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/entity/DepartEntity.java @@ -0,0 +1,37 @@ +package com.saye.hgddmz.commons.entity; + +import java.util.List; + +public class DepartEntity { + + private String id; + private String title; + private boolean spread; + private List children; + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getTitle() { + return title; + } + public void setTitle(String title) { + this.title = title; + } + public boolean isSpread() { + return spread; + } + public void setSpread(boolean spread) { + this.spread = spread; + } + public List getChildren() { + return children; + } + public void setChildren(List children) { + this.children = children; + } + + +} diff --git a/src/main/java/com/saye/hgddmz/commons/entity/RoleEntity.java b/src/main/java/com/saye/hgddmz/commons/entity/RoleEntity.java new file mode 100644 index 0000000..fbf933f --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/entity/RoleEntity.java @@ -0,0 +1,37 @@ +package com.saye.hgddmz.commons.entity; + +import java.util.List; + +public class RoleEntity { + + private String id; + private String title; + private boolean spread; + private List children; + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getTitle() { + return title; + } + public void setTitle(String title) { + this.title = title; + } + public boolean isSpread() { + return spread; + } + public void setSpread(boolean spread) { + this.spread = spread; + } + public List getChildren() { + return children; + } + public void setChildren(List children) { + this.children = children; + } + + +} diff --git a/src/main/java/com/saye/hgddmz/commons/excel/ExportXLS.java b/src/main/java/com/saye/hgddmz/commons/excel/ExportXLS.java new file mode 100644 index 0000000..0d6e621 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/excel/ExportXLS.java @@ -0,0 +1,785 @@ +package com.saye.hgddmz.commons.excel; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.poi.hssf.usermodel.*; +import org.apache.poi.hssf.util.HSSFColor; +import org.apache.poi.ss.util.CellRangeAddress; + +import javax.servlet.http.HttpServletResponse; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.math.BigDecimal; +import java.sql.Date; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + + +public class ExportXLS implements IExport ,ISetExport{ + + Log logger = LogFactory.getLog(this.getClass()); + + + public final static short ROWHEIGHT = 20; /*行高*/ + public final static double PAGEMARGIN = 0.1;/*页边距*/ + public final static short TITLESIZE = 16;/*标题文字大小*/ + public final static short HEADERSIZE = 12;/*列头文字大小*/ + public final static short DATA_CHARACTERSIZE = 9;/*汉字大小*/ + public final static short DATA_NUMSIZE = 9;/*数字大小*/ + public final static short DATA_DATESIZE = 9;/*日期大小*/ + public final static String ALIGN_LEFT = "LEFT";/*水平居左*/ + public final static String ALIGN_RIGHT = "RIGHT";/*水平居右*/ + public final static String ALIGN_CENTER = "CENTER";/*水平居右*/ + public final static String VERTICAL_TOP = "TOP";/*垂直居上*/ + public final static String VERTICAL_CENTER = "MIDDLE";/*垂直居中*/ + public final static String VERTICAL_BOTTOM = "BOTTOM";/*垂直居下*/ + public final static short A4 = HSSFPrintSetup.A4_PAPERSIZE; + public final static short A5 = HSSFPrintSetup.A5_PAPERSIZE; + public final static short A3 = 8; + + + + public final static String MERGEDEND = "_mergedend_";//表示合并次单元格 + + + + + + private List data; + private Object[] statisticData; + private String titleName; + private short titleHeight = 500; + private short headerHeight = 300; + private short cellHeight = 300; + private HSSFWorkbook wb; + private HSSFSheet sheet; + private HSSFCellStyle headerCellStyle; + private HSSFCellStyle cellStyle; + private String[] header; + private String[] subHeader; + private String[] width; + private String[] sqlKey; + private IConversionByExport conversion; + private List mergeRanges = new ArrayList(); + + private Boolean isHeaderMergeTwo = Boolean.FALSE; + private int headerRowIndex = 1; + private int subHeaderRowIndex = 2; + + private int titleMergeColumnIndex = 0; + private HashMap modifiedDataHeightHM = new HashMap(); //要修改的数据行的高度 + private short subHeaderHeight = 300; + + private Boolean isCreateFreezePane = true; + + private HashMap skipedDataIndexMap; //要空行的数据列序号:KEY为data的序号 , VALUE默认为1 + private List> resetCellStyleList = new ArrayList>(); //要重新设置样式的单元格:KEY为行号,VALUE为列号 + private HSSFCellStyle resetCellStyle; + + /** + * + *构造函数:得到一个纵向打印在A4纸上的xls + * + */ + public ExportXLS(String[] header){ + + this.wb = new HSSFWorkbook(); + this.sheet = this.createSheet(false, ExportXLS.A4); + + this.headerCellStyle = this.createCellStyle(ExportXLS.ALIGN_CENTER, VERTICAL_CENTER, 1111, HEADERSIZE, new HSSFColor.GREY_25_PERCENT().getIndex()); + this.cellStyle = this.createCellStyle(ExportXLS.ALIGN_CENTER, VERTICAL_CENTER, 1111, HEADERSIZE, new HSSFColor.WHITE().getIndex()); + + this.setTitleName("export"); + this.setHeader(header); + } + + + /** + * 设置打印纸大小,横向还是纵向 + * @param header + * @param sqlKey + * @param pageSize + * @param landscapeFlag + */ + public ExportXLS(String[] header,String[] sqlKey,Short pageSize,boolean landscapeFlag){ + + this.wb = new HSSFWorkbook(); + this.sheet = this.createSheet(landscapeFlag, pageSize); + + this.headerCellStyle = this.createCellStyle(ExportXLS.ALIGN_CENTER, VERTICAL_CENTER, 1111, HEADERSIZE, new HSSFColor.GREY_25_PERCENT().getIndex()); + HSSFFont titlefont = this.wb.createFont(); //设置字体 + titlefont.setFontHeightInPoints(ExportXLS.HEADERSIZE); + titlefont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); + headerCellStyle.setFont(titlefont); + + this.cellStyle = this.createCellStyle(ExportXLS.ALIGN_CENTER, VERTICAL_CENTER, 1111, HEADERSIZE, new HSSFColor.WHITE().getIndex()); + + this.setTitleName("export"); + this.setHeader(header); + this.setSqlKey(sqlKey); + } + + + + private void setHeader(String[] header){ + this.header = header; + + //默认设置每个单元格的宽度为3500 + int length = this.header.length; + this.width = new String[length]; + for(int i=0;i this.header.length){ + + for (int i = this.header.length; i < this.subHeader.length; i++) { + + HSSFCell headerCell = headerRow.createCell(i); + headerCell.setCellStyle(this.headerCellStyle); + headerCell.setCellValue(""); + } + } + + //填入副标题数据 + HSSFRow subHeaderRow = this.sheet.createRow(this.subHeaderRowIndex); + subHeaderRow.setHeight(this.subHeaderHeight); + for(int i=0;i resetCellStyleHM = resetCellStyleList.get(i); + Iterator> it = resetCellStyleHM.entrySet().iterator(); + while (it.hasNext()) { + + Map.Entry entry = it.next(); + Integer rowIndex = entry.getKey(); + Integer columnIndex = entry.getValue(); + this.sheet.getRow(rowIndex).getCell(columnIndex).setCellStyle(this.resetCellStyle); + } + } + } + + + //设置合并开始标识 + boolean mergedStartFlag = false; + int[] startAndEnd = null; + List mergedIndex = new ArrayList(); + + if(null != this.statisticData){ + + //追加统计行 + HSSFRow appendRow = this.sheet.createRow(this.sheet.getLastRowNum()+1); + for(int i=0;i dataList){ + this.data = dataList; + } + + + + + /* (非 Javadoc) + * @see com.saye.common.export.IEport#appendStatisticRow(Object StatisticData) + */ + public void appendStatisticRow(Object statisticData) { + + //如果不存在转换对象,则使用默认的转换方法 + if(this.conversion != null){ + this.statisticData = this.conversion.conversion(statisticData, this.sqlKey); + }else{ + this.statisticData = this.conversion(statisticData); + } + + } + /* (非 Javadoc) + * @see com.saye.common.export.IEport#returnClientDownload(javax.servlet.http.HttpServletResponse) + */ + public void returnClientDownload(HttpServletResponse response) throws IOException{ + + //将数据装填到sheet中 + this.fillSheet(); + + response.reset(); + response.setContentType("application/vnd.ms-excel"); + response.setHeader("Content-Disposition","attachment; filename=" + new String(this.titleName.getBytes("gb2312"),"ISO8859-1")+".xls"); + OutputStream os = null; + try { + os = response.getOutputStream(); + this.wb.write(os); + } catch (Exception e) { + } finally { + if(os != null) { + os.close(); + os = null; + } + } + } + + + /* (非 Javadoc) + * @see com.saye.common.export.IEport#returnClientOpen(javax.servlet.http.HttpServletResponse) + */ + public void returnClientOpen(HttpServletResponse response) throws IOException{ + + //将数据装填到sheet中 + this.fillSheet(); + + response.reset(); + response.setContentType("application/vnd.ms-excel"); + response.setHeader("Content-Disposition","online; filename=" + new String(this.titleName.getBytes("gb2312"),"ISO8859-1")+".xls"); + try { + wb.write(response.getOutputStream()); + } catch (Exception e) { + e.printStackTrace(); + } + } + /* (非 Javadoc) + * @see com.saye.common.export.IEport#modifTitleHeight(short height) + */ + public void modifTitleHeight(short height) { + this.titleHeight = height; + } + + /** + * 设置副标题 + * @param subHeader + */ + public void setSubHeader(String[] subHeader){ + + this.subHeader = subHeader; + + //默认设置每个单元格的宽度为3500 + int headerLength = this.header.length; + int subHeaderLength = 0; + if(null != subHeader && 0 != subHeader.length){ + subHeaderLength = this.subHeader.length; + } + int length = headerLength > subHeaderLength ? headerLength : subHeaderLength; + this.width = new String[length]; + for(int i=0;i modifiedDataHeightHM) { + this.modifiedDataHeightHM = modifiedDataHeightHM; + } + + /** + * 设置头部副标题高度 + * @param subHeaderHeight + */ + public void modifySubHeaderHeight(short subHeaderHeight) { + this.subHeaderHeight = subHeaderHeight; + } + + /** + * 设置是否创建冻结窗体 + * @param isCreateFreezePane + */ + public void setIsCreateFreezePane(Boolean isCreateFreezePane) { + this.isCreateFreezePane = isCreateFreezePane; + } + + /** + * 设置要空行的数据列序号 + * @param skipedDataIndexMap + */ + public void setSkipedDataIndexMap(HashMap skipedDataIndexMap) { + this.skipedDataIndexMap = skipedDataIndexMap; + } + + /** + * 设置 重新设置样式的单元格序号及样式:样式为空时,默认为头部标题样式 + * @param resetCellStyleList + * @param resetCellStyle + */ + public void resetCellForCellStyle(List> resetCellStyleList, HSSFCellStyle resetCellStyle) { + + this.resetCellStyleList = resetCellStyleList; + if(null == resetCellStyle){ + resetCellStyle = this.headerCellStyle; + } + this.resetCellStyle = resetCellStyle; + } + + /** + * 设置 工作薄 密码保护 + * @param pwd + */ + public void protectSheet(String pwd) { + + this.sheet.protectSheet(pwd); + } + + /** + * 设定抬头是否合并两行:在new ExportXLS之后就SET + * @param isHeaderMergeTwo + */ + public void setIsHeaderMergeTwo(Boolean isHeaderMergeTwo) { + + this.isHeaderMergeTwo = isHeaderMergeTwo; + if(!this.isHeaderMergeTwo){ + this.headerRowIndex = 1; + this.subHeaderRowIndex = 2; + } + } + +} diff --git a/src/main/java/com/saye/hgddmz/commons/excel/ExportXLSX.java b/src/main/java/com/saye/hgddmz/commons/excel/ExportXLSX.java new file mode 100644 index 0000000..3379a26 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/excel/ExportXLSX.java @@ -0,0 +1,790 @@ + +package com.saye.hgddmz.commons.excel; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.*; + +import javax.servlet.http.HttpServletResponse; +import java.awt.*; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.math.BigDecimal; +import java.sql.Date; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.*; + + +public class ExportXLSX implements IExport ,ISetExport{ + + Log logger = LogFactory.getLog(this.getClass()); + + + public final static short ROWHEIGHT = 20; /*行高*/ + public final static double PAGEMARGIN = 0.1;/*页边距*/ + public final static short TITLESIZE = 16;/*标题文字大小*/ + public final static short HEADERSIZE = 12;/*列头文字大小*/ + public final static short DATA_CHARACTERSIZE = 9;/*汉字大小*/ + public final static short DATA_NUMSIZE = 9;/*数字大小*/ + public final static short DATA_DATESIZE = 9;/*日期大小*/ + public final static String ALIGN_LEFT = "LEFT";/*水平居左*/ + public final static String ALIGN_RIGHT = "RIGHT";/*水平居右*/ + public final static String ALIGN_CENTER = "CENTER";/*水平居右*/ + public final static String VERTICAL_TOP = "TOP";/*垂直居上*/ + public final static String VERTICAL_CENTER = "MIDDLE";/*垂直居中*/ + public final static String VERTICAL_BOTTOM = "BOTTOM";/*垂直居下*/ + public final static short A4 = XSSFPrintSetup.A4_PAPERSIZE; + public final static short A5 = XSSFPrintSetup.A5_PAPERSIZE; + public final static short A3 = 8; + + + + public final static String MERGEDEND = "_mergedend_";//表示合并次单元格 + + + + + + private List data; + private Object[] statisticData; + private String titleName; + private short titleHeight = 500; + private short headerHeight = 300; + private short cellHeight = 300; + private XSSFWorkbook wb; + private XSSFSheet sheet; + private XSSFCellStyle headerCellStyle; + private XSSFCellStyle cellStyle; + private String[] header; + private String[] subHeader; + private String[] width; + private String[] sqlKey; + private IConversionByExport conversion; + private List mergeRanges = new ArrayList(); + + private Boolean isHeaderMergeTwo = Boolean.FALSE; + private int headerRowIndex = 1; + private int subHeaderRowIndex = 2; + + private int titleMergeColumnIndex = 0; + private HashMap modifiedDataHeightHM = new HashMap(); //要修改的数据行的高度 + private short subHeaderHeight = 300; + + private Boolean isCreateFreezePane = true; + + private HashMap skipedDataIndexMap; //要空行的数据列序号:KEY为data的序号 , VALUE默认为1 + private List> resetCellStyleList = new ArrayList>(); //要重新设置样式的单元格:KEY为行号,VALUE为列号 + private XSSFCellStyle resetCellStyle; + + /** + * + *构造函数:得到一个纵向打印在A4纸上的xlsx + * + */ + public ExportXLSX(String[] header){ + + this.wb = new XSSFWorkbook(); + this.sheet = this.createSheet(false, ExportXLSX.A4); + + this.headerCellStyle = this.createCellStyle(ExportXLSX.ALIGN_CENTER, VERTICAL_CENTER, 1111, HEADERSIZE, new XSSFColor(new Color(192, 192, 192))); + this.cellStyle = this.createCellStyle(ExportXLSX.ALIGN_CENTER, VERTICAL_CENTER, 1111, HEADERSIZE, new XSSFColor(new Color(255, 255, 255))); + + this.setTitleName("export"); + this.setHeader(header); + } + + + /** + * 设置打印纸大小,横向还是纵向 + * @param header + * @param sqlKey + * @param pageSize + * @param landscapeFlag + */ + public ExportXLSX(String[] header,String[] sqlKey,Short pageSize,boolean landscapeFlag){ + + + XSSFWorkbook x= new XSSFWorkbook(); + this.wb = x; + this.sheet = this.createSheet(landscapeFlag, pageSize); + + this.headerCellStyle = this.createCellStyle(ExportXLSX.ALIGN_CENTER, VERTICAL_CENTER, 1111, HEADERSIZE, new XSSFColor(new Color(192, 192, 192))); + XSSFFont titlefont = this.wb.createFont(); //设置字体 + titlefont.setFontHeightInPoints(ExportXLSX.HEADERSIZE); + titlefont.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD); + headerCellStyle.setFont(titlefont); + + this.cellStyle = this.createCellStyle(ExportXLSX.ALIGN_CENTER, VERTICAL_CENTER, 1111, HEADERSIZE, new XSSFColor(new Color(255, 255, 255))); + + this.setTitleName("export"); + this.setHeader(header); + this.setSqlKey(sqlKey); + } + + + + private void setHeader(String[] header){ + this.header = header; + + //默认设置每个单元格的宽度为3500 + int length = this.header.length; + this.width = new String[length]; + for(int i=0;i this.header.length){ + + for (int i = this.header.length; i < this.subHeader.length; i++) { + + XSSFCell headerCell = headerRow.createCell(i); + headerCell.setCellStyle(this.headerCellStyle); + headerCell.setCellValue(""); + } + } + + //填入副标题数据 + XSSFRow subHeaderRow = this.sheet.createRow(this.subHeaderRowIndex); + subHeaderRow.setHeight(this.subHeaderHeight); + for(int i=0;i resetCellStyleHM = resetCellStyleList.get(i); + Iterator> it = resetCellStyleHM.entrySet().iterator(); + while (it.hasNext()) { + + Map.Entry entry = it.next(); + Integer rowIndex = entry.getKey(); + Integer columnIndex = entry.getValue(); + this.sheet.getRow(rowIndex).getCell(columnIndex).setCellStyle(this.resetCellStyle); + } + } + } + + + //设置合并开始标识 + boolean mergedStartFlag = false; + int[] startAndEnd = null; + List mergedIndex = new ArrayList(); + + if(null != this.statisticData){ + + //追加统计行 + XSSFRow appendRow = this.sheet.createRow(this.sheet.getLastRowNum()+1); + for(int i=0;i dataList){ + this.data = dataList; + } + + + + + /* (非 Javadoc) + * @see com.saye.common.export.IEport#appendStatisticRow(Object StatisticData) + */ + public void appendStatisticRow(Object statisticData) { + + //如果不存在转换对象,则使用默认的转换方法 + if(this.conversion != null){ + this.statisticData = this.conversion.conversion(statisticData, this.sqlKey); + }else{ + this.statisticData = this.conversion(statisticData); + } + + } + /* (非 Javadoc) + * @see com.saye.common.export.IEport#returnClientDownload(javax.servlet.http.HttpServletResponse) + */ + public void returnClientDownload(HttpServletResponse response) throws IOException{ + + //将数据装填到sheet中 + this.fillSheet(); + + response.reset(); + response.setContentType("application/vnd.ms-excel"); + response.setHeader("Content-Disposition","attachment; filename=" + new String(this.titleName.getBytes("gb2312"),"ISO8859-1")+".xlsx"); + OutputStream os = null; + try { + os = response.getOutputStream(); + this.wb.write(os); + } catch (Exception e) { + } finally { + if(os != null) { + os.close(); + os = null; + } + } + } + + + /* (非 Javadoc) + * @see com.saye.common.export.IEport#returnClientOpen(javax.servlet.http.HttpServletResponse) + */ + public void returnClientOpen(HttpServletResponse response) throws IOException{ + + //将数据装填到sheet中 + this.fillSheet(); + + response.reset(); + response.setContentType("application/vnd.ms-excel"); + response.setHeader("Content-Disposition","online; filename=" + new String(this.titleName.getBytes("gb2312"),"ISO8859-1")+".xlsx"); + try { + wb.write(response.getOutputStream()); + } catch (Exception e) { + e.printStackTrace(); + } + } + /* (非 Javadoc) + * @see com.saye.common.export.IEport#modifTitleHeight(short height) + */ + public void modifTitleHeight(short height) { + this.titleHeight = height; + } + + /** + * 设置副标题 + * @param subHeader + */ + public void setSubHeader(String[] subHeader){ + + this.subHeader = subHeader; + + //默认设置每个单元格的宽度为3500 + int headerLength = this.header.length; + int subHeaderLength = 0; + if(null != subHeader && 0 != subHeader.length){ + subHeaderLength = this.subHeader.length; + } + int length = headerLength > subHeaderLength ? headerLength : subHeaderLength; + this.width = new String[length]; + for(int i=0;i modifiedDataHeightHM) { + this.modifiedDataHeightHM = modifiedDataHeightHM; + } + + /** + * 设置头部副标题高度 + * @param subHeaderHeight + */ + public void modifySubHeaderHeight(short subHeaderHeight) { + this.subHeaderHeight = subHeaderHeight; + } + + /** + * 设置是否创建冻结窗体 + * @param isCreateFreezePane + */ + public void setIsCreateFreezePane(Boolean isCreateFreezePane) { + this.isCreateFreezePane = isCreateFreezePane; + } + + /** + * 设置要空行的数据列序号 + * @param skipedDataIndexMap + */ + public void setSkipedDataIndexMap(HashMap skipedDataIndexMap) { + this.skipedDataIndexMap = skipedDataIndexMap; + } + + /** + * 设置 重新设置样式的单元格序号及样式:样式为空时,默认为头部标题样式 + * @param resetCellStyleList + * @param resetCellStyle + */ + public void resetCellForCellStyle(List> resetCellStyleList, XSSFCellStyle resetCellStyle) { + + this.resetCellStyleList = resetCellStyleList; + if(null == resetCellStyle){ + resetCellStyle = this.headerCellStyle; + } + this.resetCellStyle = resetCellStyle; + } + + /** + * 设置 工作薄 密码保护 + * @param pwd + */ + public void protectSheet(String pwd) { + + this.sheet.protectSheet(pwd); + } + + /** + * 设定抬头是否合并两行:在new ExportXLS之后就SET + * @param isHeaderMergeTwo + */ + public void setIsHeaderMergeTwo(Boolean isHeaderMergeTwo) { + + this.isHeaderMergeTwo = isHeaderMergeTwo; + if(!this.isHeaderMergeTwo){ + this.headerRowIndex = 1; + this.subHeaderRowIndex = 2; + } + } + + + +} diff --git a/src/main/java/com/saye/hgddmz/commons/excel/HashMapConversionImpl.java b/src/main/java/com/saye/hgddmz/commons/excel/HashMapConversionImpl.java new file mode 100644 index 0000000..6f7f719 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/excel/HashMapConversionImpl.java @@ -0,0 +1,27 @@ +package com.saye.hgddmz.commons.excel; + +import java.util.HashMap; + +public class HashMapConversionImpl implements IConversionByExport { + + @Override + public Object[] conversion(Object obj) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object[] conversion(Object obj, String[] sqlArray) { + + HashMap hm = (HashMap) obj; + + int len = sqlArray.length; + Object[] result = new Object[len]; + for (int i = 0; i < len; i++) { + + result[i] = hm.get(sqlArray[i]); + } + return result; + } + +} diff --git a/src/main/java/com/saye/hgddmz/commons/excel/IConversionByExport.java b/src/main/java/com/saye/hgddmz/commons/excel/IConversionByExport.java new file mode 100644 index 0000000..a62377b --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/excel/IConversionByExport.java @@ -0,0 +1,6 @@ +package com.saye.hgddmz.commons.excel; + +public interface IConversionByExport { + public Object[] conversion(Object obj); + public Object[] conversion(Object obj, String[] sqlArray); +} diff --git a/src/main/java/com/saye/hgddmz/commons/excel/IExport.java b/src/main/java/com/saye/hgddmz/commons/excel/IExport.java new file mode 100644 index 0000000..dd61ac5 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/excel/IExport.java @@ -0,0 +1,53 @@ +package com.saye.hgddmz.commons.excel; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.sql.SQLException; +import java.util.List; + +public interface IExport { + + + /** + * 设置转换对象 + * @param conversion + */ + public void setConversion(IConversionByExport conversion); + + + /** + * 设置数据数据 + * @param dataList + * @throws SQLException + */ + public void setData(List dataList); + + + /** + * 在表格尾部追加数据,主要用于统计数据 + */ + public void appendStatisticRow(Object statisticData); + + /** + * 以下载形式导出 + * @param response + * @throws IOException + */ + public void returnClientDownload(HttpServletResponse response) + throws IOException; + + /** + * 以打开方式导出 + * @param response + */ + public void returnClientOpen(HttpServletResponse response) + throws IOException; + + /** + * 后台生成EXCEL文件 + * @param exportFilePath + * @throws IOException + */ + public void execGenerateExcel(String exportFilePath) throws IOException; + +} \ No newline at end of file diff --git a/src/main/java/com/saye/hgddmz/commons/excel/ISetExport.java b/src/main/java/com/saye/hgddmz/commons/excel/ISetExport.java new file mode 100644 index 0000000..65679e6 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/excel/ISetExport.java @@ -0,0 +1,58 @@ +package com.saye.hgddmz.commons.excel; + +public interface ISetExport { + + /** + * 设置台头 + * @param titleName + */ + public void setTitleName(String titleName); + + /** + * 设置标题高 + * @param height + */ + public void modifTitleHeight(short height); + + /** + * 修改某个位置的标题栏名称 + * @param header + * @param index + */ + public void modifyHeader(String header, int index); + + /** + * 修改某个位置的标题栏宽度 + * @param width + * @param index + */ + public void modifyWidthOfHeader(String width, int index); + + /** + * 设置副标题 + * @param subHeader + */ + public void setSubHeader(String[] subHeader); + + /** + * 设置要合并的单元格区域 + * @param firstRow 开始行 + * @param lastRow 结束行 + * @param firstCol 开始列 + * @param lastCol 结束列 + */ + public void setMergeRange(int firstRow, int lastRow, int firstCol, int lastCol); + + /** + * 设置 工作薄 密码保护 + * @param pwd + */ + public void protectSheet(String pwd); + + /** + * 设定抬头是否合并两行:在new ExportXLS之后就SET + * @param isHeaderMergeTwo + */ + public void setIsHeaderMergeTwo(Boolean isHeaderMergeTwo); + +} diff --git a/src/main/java/com/saye/hgddmz/commons/exprot/HashMapConversionImpl.java b/src/main/java/com/saye/hgddmz/commons/exprot/HashMapConversionImpl.java new file mode 100644 index 0000000..b913e10 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/exprot/HashMapConversionImpl.java @@ -0,0 +1,27 @@ +package com.saye.hgddmz.commons.exprot; + +import java.util.HashMap; + +public class HashMapConversionImpl implements IConversionByExport { + + @Override + public Object[] conversion(Object obj) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object[] conversion(Object obj, String[] sqlArray) { + + HashMap hm = (HashMap) obj; + + int len = sqlArray.length; + Object[] result = new Object[len]; + for (int i = 0; i < len; i++) { + + result[i] = hm.get(sqlArray[i]); + } + return result; + } + +} diff --git a/src/main/java/com/saye/hgddmz/commons/exprot/IConversionByExport.java b/src/main/java/com/saye/hgddmz/commons/exprot/IConversionByExport.java new file mode 100644 index 0000000..83d16b3 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/exprot/IConversionByExport.java @@ -0,0 +1,6 @@ +package com.saye.hgddmz.commons.exprot; + +public interface IConversionByExport { + public Object[] conversion(Object obj); + public Object[] conversion(Object obj, String[] sqlArray); +} diff --git a/src/main/java/com/saye/hgddmz/commons/file/FileDUtil.java b/src/main/java/com/saye/hgddmz/commons/file/FileDUtil.java new file mode 100644 index 0000000..50e5405 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/file/FileDUtil.java @@ -0,0 +1,36 @@ +package com.saye.hgddmz.commons.file; + +import java.io.File; + +public class FileDUtil { + + /** + * 得到文件的扩展名:大写字母的自动转换为小写字母 + * @param f + * @return + */ + public static String getExtension(File f) { + return (f != null) ? getExtension(f.getName()) : ""; + } + + public static String getExtension(String filename) { + return getExtension(filename,""); + } + + public static String getExtension(String filename, String defExt) { + if ((filename != null) && (filename.length() > 0)) { + int i = filename.lastIndexOf('.'); + + if ((i >-1) && (i < (filename.length() - 1))) { + return filename.substring(i + 1).trim().toLowerCase(); + } + } + return defExt; + } + + public static void main(String[] args) { + + File f = new File("d:\test.XLSX"); + System.out.println(getExtension(f)); + } +} diff --git a/src/main/java/com/saye/hgddmz/commons/getBean/GetBeanUtil.java b/src/main/java/com/saye/hgddmz/commons/getBean/GetBeanUtil.java new file mode 100644 index 0000000..07fabec --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/getBean/GetBeanUtil.java @@ -0,0 +1,29 @@ +package com.saye.hgddmz.commons.getBean; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +@Component +public class GetBeanUtil implements ApplicationContextAware { + protected static ApplicationContext applicationContext ; + + @Override + public void setApplicationContext(ApplicationContext arg0) throws BeansException { + if (applicationContext == null) { + applicationContext = arg0; + } + + } + public static Object getBean(String name) { + //name表示其他要注入的注解name名 + return applicationContext.getBean(name); + } + /** + * 拿到ApplicationContext对象实例后就可以手动获取Bean的注入实例对象 + */ + public static T getBean(Class clazz) { + return applicationContext.getBean(clazz); + } +} diff --git a/src/main/java/com/saye/hgddmz/commons/image/ImageBase64DUtil.java b/src/main/java/com/saye/hgddmz/commons/image/ImageBase64DUtil.java new file mode 100644 index 0000000..56c8a68 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/image/ImageBase64DUtil.java @@ -0,0 +1,149 @@ +//package com.saye.hgddmz.commons.image; +// +// +// +//import java.io.*; +//import java.net.HttpURLConnection; +//import java.net.URL; +// +// +///** +// * Description: 图片与base64的转换 +// * @author dqzhang +// * @created 2018-10-9 下午4:07:55 +// */ +//public class ImageBase64DUtil { +// +// +// +// /** +// * 本地图片转换成base64字符串 +// * @param imgFile 图片本地路径 +// * @return +// * @dateTime 2018-02-23 14:40:46 +// */ +// public static String ImageToBase64ByLocal(String imgFile) throws Exception{// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 +// InputStream in = null; +// byte[] data = null; +// +// // 读取图片字节数组 +// try { +// in = new FileInputStream(imgFile); +// +// data = new byte[in.available()]; +// in.read(data); +// in.close(); +// } catch (IOException e) { +//// e.printStackTrace(); +// } +// // 对字节数组Base64编码 +// BASE64Encoder encoder = new BASE64Encoder(); +// +// return encoder.encode(data);// 返回Base64编码过的字节数组字符串 +// } +// +// +// +// /** +// * 在线图片转换成base64字符串 +// * @param imgURL 图片线上路径 +// * @return +// * @dateTime 2018-02-23 14:43:18 +// */ +// public static String ImageToBase64ByOnline(String imgURL) { +// ByteArrayOutputStream data = new ByteArrayOutputStream(); +// try { +// // 创建URL +// URL url = new URL(imgURL); +// byte[] by = new byte[1024]; +// // 创建链接 +// HttpURLConnection conn = (HttpURLConnection) url.openConnection(); +// conn.setRequestMethod("GET"); +// conn.setConnectTimeout(5000); +// InputStream is = conn.getInputStream(); +// // 将内容读取内存中 +// int len = -1; +// while ((len = is.read(by)) != -1) { +// data.write(by, 0, len); +// } +// // 关闭流 +// is.close(); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// // 对字节数组Base64编码 +// BASE64Encoder encoder = new BASE64Encoder(); +// return encoder.encode(data.toByteArray()); +// } +// +// +// /** +// * base64字符串转换成图片 +// * @param imgStr base64字符串 +// * @param imgFilePath 图片存放路径 +// * @return +// * @dateTime 2018-02-23 14:42:17 +// */ +// public static boolean Base64ToImage(String imgStr,String imgFilePath) { // 对字节数组字符串进行Base64解码并生成图片 +// +// +// +// BASE64Decoder decoder = new BASE64Decoder(); +// try { +// // Base64解码 +// byte[] b = decoder.decodeBuffer(imgStr); +// for (int i = 0; i < b.length; ++i) { +// if (b[i] < 0) {// 调整异常数据 +// b[i] += 256; +// } +// } +// OutputStream out = new FileOutputStream(imgFilePath); +// out.write(b); +// out.flush(); +// out.close(); +// +// return true; +// } catch (Exception e) { +// return false; +// } +// +// } +// +// /** +// * @description 下载在线图片到本地 +// */ +// public static void readInputStream(URL url,File file) throws Exception { +// // 打开链接 +// HttpURLConnection conn = (HttpURLConnection) url.openConnection(); +// // 设置请求方式为"GET" +// conn.setRequestMethod("GET"); +// // 超时响应时间为5秒 +// conn.setConnectTimeout(5 * 1000); +// // 通过输入流获取图片数据 +// InputStream inStream = conn.getInputStream(); +// ByteArrayOutputStream outStream = new ByteArrayOutputStream(); +// // 创建一个Buffer字符串 +// byte[] buffer = new byte[1024]; +// // 每次读取的字符串长度,如果为-1,代表全部读取完毕 +// int len = 0; +// // 使用一个输入流从buffer里把数据读取出来 +// while ((len = inStream.read(buffer)) != -1) { +// // 用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度 +// outStream.write(buffer, 0, len); +// } +// // 关闭输入流 +// inStream.close(); +// // 创建输出流 +// FileOutputStream outStream2 = new FileOutputStream(file); +// // 写入数据 +// outStream2.write(outStream.toByteArray()); +// // 关闭输出流 +// outStream2.close(); +// } +// +// public static void main(String[] args) throws Exception{ +// } +// +// +// +//} diff --git a/src/main/java/com/saye/hgddmz/commons/log/ExceptionDUtil.java b/src/main/java/com/saye/hgddmz/commons/log/ExceptionDUtil.java new file mode 100644 index 0000000..1f31c81 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/log/ExceptionDUtil.java @@ -0,0 +1,27 @@ +package com.saye.hgddmz.commons.log; + +public class ExceptionDUtil { + + /** + * 返回异常的详细信息 + * @param e + * @return + */ + public static String getDetailExceptionMsg(Exception e){ + + StringBuffer exceptionMessage = new StringBuffer(); + + StackTraceElement[] stackTraceElementes = e.getStackTrace(); + int length = stackTraceElementes.length; + StackTraceElement ste; + //只要最顶上的错误栈 + for(int i=0;i 65280 && c[i] < 65375){ + c[i] = (char) (c[i] - 65248); + } + } + return new String(c); + } + + + /** + * 为每添加一个元素前面增加指定的分隔 除第一个元素之外 + * @param str + * @param appStr + * @param compart + * @return + */ + public static StringBuffer appendElement(StringBuffer strB,String appStr,String compart){ + + //当出入参数为NULL时 + if(strB == null){ + return new StringBuffer(appStr); + } + + //当没有元素时直接添加追加元素 否则先添加分隔符 + if(strB.length() == 0){ + strB.append(appStr); + }else{ + strB.append(compart); + strB.append(appStr); + } + + return strB; + } + + + /** + * 移除元素 + * @param str + * @param moveStr + * @param compart + * @return + */ + public static StringBuffer moveElement(StringBuffer strB,String moveStr,String compart){ + + //当出入参数为NULL时 + if(strB == null){ + return strB; + } + + StringBuffer newStrB = new StringBuffer(); + + String[] strArray = strB.toString().split(compart); + for(int i=0;i 0 && begin != -1 && end == -1){ + end = i; + } + + + //如果已经找到中文的开始 但直到最后也没找到中文的结束,则将字符的结束位当成中文的截止位 + if(begin != -1 && i == srcLength - 1){ + end = i; + } + + + //将中文提取出来 + if(begin != -1 && end != -1){ + + + int tempLength = end-begin+1; + if(tempLength % 2 != 0){ + tempLength = tempLength - 1; + } + + + byte[] tempByte = new byte[tempLength]; + System.arraycopy(srcByte, begin, tempByte, 0, tempLength); + + list.add(new String(tempByte)); + + begin = -1; + end = -1; + } + + } + + + //将中文以数组输出 + int size = list.size(); + String[] chineseArray = new String[size]; + for(int i=0;i hm, String fieldString) { + + String[] strArr = fieldString.split(","); + for (int i = 0; i < strArr.length; i++) { + + String key = strArr[i]; + Object obj = hm.get(key); + if(isEmpty(obj)){ + + return key; + } + } + + return ""; + } + + /** + * 判断字符串是否为正整数 + * @param str + * @return + */ + public static boolean isPositiveInteger (String str){ + Pattern pattern = Pattern.compile("^[0-9]*[1-9][0-9]*$"); + return pattern.matcher(str).matches(); + } + + /** + * 判断字符串是否为正整数或正浮点数 + * @param str + * @return + */ + public static boolean isPositiveIntegerOrPositiveFloat (String str){ + Pattern pattern = Pattern.compile("^(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*))$"); + return pattern.matcher(str).matches(); + } + + /** + * + * @description 截取字符串 + * @author mczheng + * @created 2016-6-25 下午6:13:29 + * @param str 要截取的字符串 + * @param maxLength 字符长度,英文字符算0.5个长度,当截取剩下最后一位是0.5个长度而最后一个字符是中文时,则舍弃掉。 + * @return + */ + public static String substring(String str, int maxLength) { + if (!hasLength(str)) + return str; + + int subSLength = maxLength * 2; + int tempSubLength = subSLength;//截取字符数 + String subStr = ""; + try { + int strLen = str.getBytes("GBK").length; + if (strLen <= subSLength) return str; + subStr = str.substring(0, str.length() < subSLength ? str.length() : subSLength); //截取的子串 + int subStrByetsL = subStr.getBytes("GBK").length; //截取子串的字节长度 + //说明截取的字符串中包含有汉字 + while (subStrByetsL > tempSubLength) { + int subSLengthTemp = --subSLength; + subStr = str.substring(0, subSLengthTemp > str.length() ? str.length() : subSLengthTemp); + subStrByetsL = subStr.getBytes("GBK").length; + } + subStr += "..."; + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return subStr; + } + + public static boolean hasLength(String str) { + return (str != null) && (str.length() > 0); + } + + public static void main(String[] args) { +// +// StringBuffer str = new StringBuffer("a,c,d,c"); +// str = StringDUtil.moveFirstElement(str, "c", ","); +// System.out.println(str.toString()); +// +// System.out.println(isEmpty("\"null\"")); + System.out.println(StringDUtil.substring("一二三四五六七八九十一二三四五六七八九十一二三四五六七八九十", 15)); + } + + /** + * @description 判断字符串是否有值且值不为空格 + * @author thuang + * @created 2020年1月7日 下午1:09:49 + * @param str + * @return + */ + public static boolean isNotBlank(String str) { + if (str != null && str.length() > 0 && str.trim().length() > 0) { + return true; + } + return false; + } + +} diff --git a/src/main/java/com/saye/hgddmz/commons/uuid/UUIDGenerator.java b/src/main/java/com/saye/hgddmz/commons/uuid/UUIDGenerator.java new file mode 100644 index 0000000..ad1ca98 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/commons/uuid/UUIDGenerator.java @@ -0,0 +1,24 @@ +package com.saye.hgddmz.commons.uuid; + +import java.util.UUID; + +public class UUIDGenerator { + public UUIDGenerator() { + } + /** + * 获得一个UUID + * @return String UUID + */ + public static String getUUID(){ + String s = UUID.randomUUID().toString(); + //去掉“-”符号 + return s.substring(0,8)+s.substring(9,13)+s.substring(14,18)+s.substring(19,23)+s.substring(24); + } + + public static void main(String[] args){ + + String ss = UUIDGenerator.getUUID(); + System.out.println(ss); + System.out.println(ss.length()); + } +} \ No newline at end of file diff --git a/src/main/java/com/saye/hgddmz/controller/GetDateController.java b/src/main/java/com/saye/hgddmz/controller/GetDateController.java new file mode 100644 index 0000000..15a1d57 --- /dev/null +++ b/src/main/java/com/saye/hgddmz/controller/GetDateController.java @@ -0,0 +1,1112 @@ +package com.saye.hgddmz.controller; + +import cn.hutool.core.util.RandomUtil; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.http.HttpUtil; +import com.saye.hgddmz.commons.date.DateDUtil; +import com.saye.hgddmz.commons.string.StringDUtil; +import com.saye.hgddmz.entity.BankbillHistory; +import com.saye.hgddmz.util.DownloadFtpUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.hssf.usermodel.*; +import org.apache.poi.ss.usermodel.Cell; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.io.File; +import java.io.FileInputStream; +import java.util.*; + + +/** + * @author thuang + * @version 1.0 + * @description: TODO + * @date 2021/9/22 13:55 + */ + +@Controller +@Slf4j +public class GetDateController { + + + private static String grant_type = "client_credential"; + private static String appid = "wx45acd2b4907cb8f4"; + private static String secret = "895b90585c4698485c07e113711eac85"; + private static String key = "Nxwj20250903Jojubanking12091209x"; + + /** + * 安全获取单元格字符串值 + * @param row 行对象 + * @param cellIndex 单元格索引 + * @return 单元格字符串值,如果单元格为空则返回空字符串 + */ + private static String getCellStringValue(HSSFRow row, int cellIndex) { + if (row == null) { + return ""; + } + HSSFCell cell = row.getCell(cellIndex); + if (cell == null) { + return ""; + } + try { + cell.setCellType(Cell.CELL_TYPE_STRING); + String value = cell.getStringCellValue(); + return value != null ? value.trim() : ""; + } catch (Exception e) { + log.warn("获取单元格值失败,行: {}, 列: {}, 错误: {}", row.getRowNum(), cellIndex, e.getMessage()); + return ""; + } + } + + /** + * 安全获取单元格日期值 + * @param row 行对象 + * @param cellIndex 单元格索引 + * @return 日期字符串,如果单元格为空或不是日期格式则返回空字符串 + */ + private static String getCellDateValue(HSSFRow row, int cellIndex) { + if (row == null) { + return ""; + } + HSSFCell cell = row.getCell(cellIndex); + if (cell == null) { + return ""; + } + try { + cell.setCellType(Cell.CELL_TYPE_NUMERIC); + if (HSSFDateUtil.isCellDateFormatted(cell)) { + Date dateCellValue = cell.getDateCellValue(); + return DateDUtil.DateToStr(DateDUtil.yyyy_MM_dd, dateCellValue); + } + return ""; + } catch (Exception e) { + log.warn("获取单元格日期值失败,行: {}, 列: {}, 错误: {}", row.getRowNum(), cellIndex, e.getMessage()); + return ""; + } + } + + /** + * @description: 获取银行端商户对账数据 + * @author thuang + * @date 2021/9/22 13:57 + * @version 1.0 + */ + @PostMapping("/getBankDataBySH") + @ResponseBody + public HashMap getBankDataBySH(@RequestBody HashMap map) { + HashMap responseMap = new HashMap<>(); + String errCode = "0"; + String errMsg = ""; + + // 先下载文件 + String host = StringDUtil.changeNullToEmpty(map.get("FTP_HOST")); + String portStr = StringDUtil.changeNullToEmpty(map.get("FTP_PORT")); + int port = Integer.parseInt("".equals(portStr) ? "21" : portStr); + String username = StringDUtil.changeNullToEmpty(map.get("FTP_USER")); + String password = StringDUtil.changeNullToEmpty(map.get("FTP_PASSWORD")); + String localPath = StringDUtil.changeNullToEmpty(map.get("LOCAL_PATH")); + String mch_id = StringDUtil.changeNullToEmpty(map.get("MCH_ID")); + String ftp_path = StringDUtil.changeNullToEmpty(map.get("FTP_PATH")); + String ftp_file_name = StringDUtil.changeNullToEmpty(map.get("FTP_FILE_NAME")); + String bill_table_name = StringDUtil.changeNullToEmpty(map.get("BILL_TABLE_NAME")); + String thirdConfigId = StringDUtil.changeNullToEmpty(map.get("ID")); + String trade_date = StringDUtil.changeNullToEmpty(map.get("trade_date")); + + HSSFWorkbook sheets = null; + try { + // 下载文件 + log.info("开始下载FTP文件: " + ftp_file_name); + boolean b = DownloadFtpUtil.downloadFtpFile(host, username, password, port, ftp_path, localPath, ftp_file_name); + // 判断是否下载到文件 + if (!b) { + log.error("FTP文件下载失败: " + ftp_file_name); + errCode = "1"; + errMsg = "FTP文件下载失败,请检查FTP连接参数和文件是否存在"; + responseMap.put("errCode", errCode); + responseMap.put("errMsg", errMsg); + return responseMap; + } + + // 判断本地是否有文件 + File file = new File(localPath + "/" + ftp_file_name); + if (file.exists()) { + // 存在 开始解析 存入数据库 + FileInputStream fileInputStream = new FileInputStream(localPath + "/" + ftp_file_name); + + sheets = new HSSFWorkbook(fileInputStream); + HSSFSheet sheet = sheets.getSheetAt(0); + // 获取sheet中第一行行号 + int firstRowNum = sheet.getFirstRowNum(); + // 获取sheet中最后一行行号 + int lastRowNum = sheet.getLastRowNum(); + + List list = new ArrayList<>(); + + for (int i = firstRowNum + 3; i <= lastRowNum - 2; i++) {// 因为表格中第一行为说明,第二行为列标题 + HSSFRow row = sheet.getRow(i); + if (row == null) { + continue; + } + + BankbillHistory bankbillHistory = new BankbillHistory(); + + // 清算日期 + String qsrqStr = getCellStringValue(row, 0); + + // 拿第一个字段判断这条记录是否为空 如果为空直接跳出 一般这字段为空就是数据结束了或根本没有 + // 为合计也跳出 + if ("".equals(qsrqStr) || "合计".equals(qsrqStr)) { + break; + } + + bankbillHistory.setCQsrq(qsrqStr); + + // 交易日期 + String jyrqStr = getCellDateValue(row, 1); + bankbillHistory.setCJyrq(jyrqStr); + + if (i == firstRowNum + 3) { + trade_date = jyrqStr; + } + + // 交易时间 + String jysjStr = getCellStringValue(row, 2); + bankbillHistory.setCJysj(jysjStr); + + // 卡号 + String khStr = getCellStringValue(row, 3); + bankbillHistory.setCCard(khStr); + + // 交易类型 + String jylxStr = getCellStringValue(row, 4); + bankbillHistory.setCJylx(jylxStr); + + // 交易金额 + String jyjeStr = getCellStringValue(row, 5); + bankbillHistory.setCJyje(jyjeStr); + + // 终端号 + String zdhStr = getCellStringValue(row, 6); + bankbillHistory.setCZdh(zdhStr); + + // 清算金额 + String qsjeStr = getCellStringValue(row, 7); + bankbillHistory.setCQsje(qsjeStr); + + // 手续费 + String sxfStr = getCellStringValue(row, 8); + bankbillHistory.setCSxf(sxfStr); + + // 参考号 + String ckhStr = getCellStringValue(row, 9); + bankbillHistory.setCCkh(ckhStr); + + // 流水号 + String lshStr = getCellStringValue(row, 10); + bankbillHistory.setCLsh(lshStr); + + // 卡类型 + String klxStr = getCellStringValue(row, 11); + bankbillHistory.setCKlx(klxStr); + + // 商户订单号 + String shddhStr = getCellStringValue(row, 12); + bankbillHistory.setCShddh(shddhStr); + + // 支付方式 + String zffsStr = getCellStringValue(row, 13); + bankbillHistory.setCZffs(zffsStr); + + // 银商订单号 + String ysddhStr = getCellStringValue(row, 14); + bankbillHistory.setCYsddh(ysddhStr); + + // 退货订单号 + String thddhStr = getCellStringValue(row, 15); + bankbillHistory.setCThddh(thddhStr); + + // 实际支付金额 + String sjzfjeStr = getCellStringValue(row, 16); + bankbillHistory.setCSjzfje(sjzfjeStr); + + // 备注字段 + String bzzdStr = getCellStringValue(row, 17); + bankbillHistory.setCBzzd(bzzdStr); + + // 付款附言 + String fkfyStr = getCellStringValue(row, 18); + bankbillHistory.setCFkfy(fkfyStr); + + // 钱包优惠金额 + String qbyhjeStr = getCellStringValue(row, 19); + bankbillHistory.setCQbyhje(qbyhjeStr); + + // 商户优惠金额 + String shyhjeStr = getCellStringValue(row, 20); + bankbillHistory.setCShyhje(shyhjeStr); + + // 发卡行 + String fkhStr = getCellStringValue(row, 21); + bankbillHistory.setCFkh(fkhStr); + + // 分店简称 + String fdjcStr = getCellStringValue(row, 22); + bankbillHistory.setCFdjc(fdjcStr); + + // 其他优惠金额 + String qtyhjeStr = getCellStringValue(row, 23); + bankbillHistory.setCQtyhje(qtyhjeStr); + + // 分期期数 + String fqqsStr = getCellStringValue(row, 24); + bankbillHistory.setCFqqs(fqqsStr); + + // 分期手续费 + String fqsxfStr = getCellStringValue(row, 25); + bankbillHistory.setCFqsxf(fqsxfStr); + + // 分期服务方 + String fqfwfStr = getCellStringValue(row, 26); + bankbillHistory.setCFqfwf(fqfwfStr); + + // 分期付息方 + String fqfxfStr = getCellStringValue(row, 27); + bankbillHistory.setCFqfxf(fqfxfStr); + + // 子订单号 + String zddhStr = getCellStringValue(row, 28); + bankbillHistory.setCZddh(zddhStr); + + // 表名 + bankbillHistory.setBillTableName(bill_table_name); + + list.add(bankbillHistory); + } + + responseMap.put("list", list); + } else { + System.out.println("执行失败,原因:路径" + ftp_path + "下无下载文件" + ftp_file_name); + + errCode = "999"; + errMsg = "执行失败,原因:路径" + ftp_path + "下无下载文件" + ftp_file_name; + } + } catch (Exception e) { + e.printStackTrace(); + System.out.println("执行失败,原因:" + e.getMessage()); + + errCode = "999"; + errMsg = "执行失败,原因:" + e.getMessage(); + + } finally { + try { + if (sheets != null) { + sheets.close(); + } + } catch (Exception ie) { + ie.printStackTrace(); + } + } + + responseMap.put("errCode", errCode); + responseMap.put("errMsg", errMsg); + + + return responseMap; + } + + /** + * @description: 获取银行端商户POS对账数据 + * @author thuang + * @date 2021/9/22 13:57 + * @version 1.0 + */ + @PostMapping("/getBankDataBySHPOS") + @ResponseBody + public HashMap getBankDataBySHPOS(@RequestBody HashMap map) { + HashMap responseMap = new HashMap<>(); + String errCode = "0"; + String errMsg = ""; + + // 先下载文件 + String host = StringDUtil.changeNullToEmpty(map.get("FTP_HOST")); + String portStr = StringDUtil.changeNullToEmpty(map.get("FTP_PORT")); + int port = Integer.parseInt("".equals(portStr) ? "21" : portStr); + String username = StringDUtil.changeNullToEmpty(map.get("FTP_USER")); + String password = StringDUtil.changeNullToEmpty(map.get("FTP_PASSWORD")); + String localPath = StringDUtil.changeNullToEmpty(map.get("LOCAL_PATH")); + String mch_id = StringDUtil.changeNullToEmpty(map.get("MCH_ID")); + String ftp_path = StringDUtil.changeNullToEmpty(map.get("FTP_PATH")); + String ftp_file_name = StringDUtil.changeNullToEmpty(map.get("FTP_FILE_NAME")); + String bill_table_name = StringDUtil.changeNullToEmpty(map.get("BILL_TABLE_NAME")); + String thirdConfigId = StringDUtil.changeNullToEmpty(map.get("ID")); + String trade_date = StringDUtil.changeNullToEmpty(map.get("trade_date")); + + + HSSFWorkbook sheets = null; + try { + // 下载文件 + log.info("开始下载FTP文件: " + ftp_file_name); + boolean b = DownloadFtpUtil.downloadFtpFile(host, username, password, port, ftp_path, localPath, ftp_file_name); + // 判断是否下载到文件 + if (!b) { + log.error("FTP文件下载失败: " + ftp_file_name); + errCode = "1"; + errMsg = "FTP文件下载失败,请检查FTP连接参数和文件是否存在"; + responseMap.put("errCode", errCode); + responseMap.put("errMsg", errMsg); + return responseMap; + } + + // 判断本地是否有文件 + File file = new File(localPath + "/" + ftp_file_name); + if (file.exists()) { + // 存在 开始解析 存入数据库 + FileInputStream fileInputStream = new FileInputStream(localPath + "/" + ftp_file_name); + + sheets = new HSSFWorkbook(fileInputStream); + HSSFSheet sheet = sheets.getSheetAt(0); + // 获取sheet中第一行行号 + int firstRowNum = sheet.getFirstRowNum(); + // 获取sheet中最后一行行号 + int lastRowNum = sheet.getLastRowNum(); + + List list = new ArrayList<>(); + + for (int i = firstRowNum + 3; i <= lastRowNum - 4; i++) { + log.info("正在解析第" + i + "行数据");// 因为表格中第一行为说明,第二行为列标题 + HSSFRow row = sheet.getRow(i); + if (row == null) { + continue; + } + + BankbillHistory bankbillHistory = new BankbillHistory(); + + // 清算日期 + String qsrqStr = getCellStringValue(row, 0); + + // 拿第一个字段判断这条记录是否为空 如果为空直接跳出 一般这字段为空就是数据结束了或根本没有 + if ("".equals(qsrqStr) || "汇总信息".equals(qsrqStr)) { + break; + } + bankbillHistory.setCQsrq(qsrqStr); + + // 交易日期 + String jyrqStr = getCellDateValue(row, 1); + bankbillHistory.setCJyrq(jyrqStr); + + if (i == firstRowNum + 3) { + trade_date = jyrqStr; + } + + // 交易时间 + String jysjStr = getCellStringValue(row, 2); + bankbillHistory.setCJysj(jysjStr); + + // 终端号 + String zdhStr = getCellStringValue(row, 3); + bankbillHistory.setCZdh(zdhStr); + + // 卡号 + String khStr = getCellStringValue(row, 4); + bankbillHistory.setCCard(khStr); + + // 交易类型 + String jylxStr = getCellStringValue(row, 5); + bankbillHistory.setCJylx(jylxStr); + + // 交易金额 + String jyjeStr = getCellStringValue(row, 6); + log.info("jyjeStr:" + jyjeStr); + bankbillHistory.setCJyje(jyjeStr); + + // 清算金额 + String qsjeStr = getCellStringValue(row, 7); + bankbillHistory.setCQsje(qsjeStr); + + // 手续费 + String sxfStr = getCellStringValue(row, 8); + bankbillHistory.setCSxf(sxfStr); + + // 参考号 + String ckhStr = getCellStringValue(row, 9); + bankbillHistory.setCCkh(ckhStr); + + // 流水号 + String lshStr = getCellStringValue(row, 10); + bankbillHistory.setCLsh(lshStr); + + // 卡类型 + String klxStr = getCellStringValue(row, 11); + bankbillHistory.setCKlx(klxStr); + + // 发卡行 + String fkhStr = getCellStringValue(row, 12); + bankbillHistory.setCFkh(fkhStr); + + // 支付方式 + String zffsStr = getCellStringValue(row, 13); + bankbillHistory.setCZffs(zffsStr); + + // 银商订单号 + String ysddhStr = getCellStringValue(row, 15); + log.info("ysddhStr:" + ysddhStr); + bankbillHistory.setCYsddh(ysddhStr); + + // 商户订单号 + String shddhStr = getCellStringValue(row, 16); + bankbillHistory.setCShddh(shddhStr); + + // 备注字段 + String bzzdStr = getCellStringValue(row, 18); + bankbillHistory.setCBzzd(bzzdStr); + + // 钱包优惠金额 + String fdmcjjStr = getCellStringValue(row, 19); + bankbillHistory.setCFdjc(fdmcjjStr); + + // 表名 + bankbillHistory.setBillTableName(bill_table_name); + + list.add(bankbillHistory); + } + responseMap.put("list", list); + } else { + System.out.println("执行失败,原因:路径" + ftp_path + "下无下载文件" + ftp_file_name); + + errCode = "999"; + errMsg = "执行失败,原因:路径" + ftp_path + "下无下载文件" + ftp_file_name; + } + } catch (Exception e) { + e.printStackTrace(); + System.out.println("执行失败,原因:" + e.getMessage()); + + errCode = "999"; + errMsg = "执行失败,原因:" + e.getMessage(); + + } finally { + try { + if (sheets != null) { + sheets.close(); + } + } catch (Exception ie) { + ie.printStackTrace(); + } + } + + + responseMap.put("errCode", errCode); + responseMap.put("errMsg", errMsg); + + + return responseMap; + } + + + /** + * @description: 获取银行端商户银联卡对账数据 + * @author thuang + * @date 2021/9/22 13:57 + * @version 1.0 + */ + @PostMapping("/getBankDataBySHYLK") + @ResponseBody + public HashMap getBankDataBySHYLK(@RequestBody HashMap map) { + HashMap responseMap = new HashMap<>(); + String errCode = "0"; + String errMsg = ""; + + // 先下载文件 + String host = StringDUtil.changeNullToEmpty(map.get("FTP_HOST")); + String portStr = StringDUtil.changeNullToEmpty(map.get("FTP_PORT")); + int port = Integer.parseInt("".equals(portStr) ? "21" : portStr); + String username = StringDUtil.changeNullToEmpty(map.get("FTP_USER")); + String password = StringDUtil.changeNullToEmpty(map.get("FTP_PASSWORD")); + String localPath = StringDUtil.changeNullToEmpty(map.get("LOCAL_PATH")); + String mch_id = StringDUtil.changeNullToEmpty(map.get("MCH_ID")); + String ftp_path = StringDUtil.changeNullToEmpty(map.get("FTP_PATH")); + String ftp_file_name = StringDUtil.changeNullToEmpty(map.get("FTP_FILE_NAME")); + String bill_table_name = StringDUtil.changeNullToEmpty(map.get("BILL_TABLE_NAME")); + String thirdConfigId = StringDUtil.changeNullToEmpty(map.get("ID")); + String trade_date = StringDUtil.changeNullToEmpty(map.get("trade_date")); + + + HSSFWorkbook sheets = null; + try { + // 下载文件 + log.info("开始下载FTP文件: " + ftp_file_name); + boolean b = DownloadFtpUtil.downloadFtpFile(host, username, password, port, ftp_path, localPath, ftp_file_name); + // 判断是否下载到文件 + if (!b) { + log.error("FTP文件下载失败: " + ftp_file_name); + errCode = "1"; + errMsg = "FTP文件下载失败,请检查FTP连接参数和文件是否存在"; + responseMap.put("errCode", errCode); + responseMap.put("errMsg", errMsg); + return responseMap; + } + + // 判断本地是否有文件 + File file = new File(localPath + "/" + ftp_file_name); + if (file.exists()) { + // 存在 开始解析 存入数据库 + FileInputStream fileInputStream = new FileInputStream(localPath + "/" + ftp_file_name); + + sheets = new HSSFWorkbook(fileInputStream); + HSSFSheet sheet = sheets.getSheetAt(0); + // 获取sheet中第一行行号 + int firstRowNum = sheet.getFirstRowNum(); + // 获取sheet中最后一行行号 + int lastRowNum = sheet.getLastRowNum(); + + List list = new ArrayList<>(); + + for (int i = firstRowNum + 3; i <= lastRowNum - 2; i++) {// 因为表格中第一行为说明,第二行为列标题 + HSSFRow row = sheet.getRow(i); + if (row == null) { + continue; + } + + BankbillHistory bankbillHistory = new BankbillHistory(); + + // 清算日期 + String qsrqStr = getCellStringValue(row, 0); + + // 拿第一个字段判断这条记录是否为空 如果为空直接跳出 一般这字段为空就是数据结束了或根本没有 + if ("".equals(qsrqStr) || "合计".equals(qsrqStr)) { + break; + } + bankbillHistory.setCQsrq(qsrqStr); + + // 交易日期 + String jyrqStr = getCellDateValue(row, 1); + bankbillHistory.setCJyrq(jyrqStr); + + if (i == firstRowNum + 3) { + trade_date = jyrqStr; + } + + // 交易时间 + String jysjStr = getCellStringValue(row, 2); + bankbillHistory.setCJysj(jysjStr); + + // 终端号 + String zdhStr = getCellStringValue(row, 3); + bankbillHistory.setCZdh(zdhStr); + + // 卡号 + String khStr = getCellStringValue(row, 4); + bankbillHistory.setCCard(khStr); + + // 交易类型 + String jylxStr = getCellStringValue(row, 5); + bankbillHistory.setCJylx(jylxStr); + + // 交易金额 + String jyjeStr = getCellStringValue(row, 6); + bankbillHistory.setCJyje(jyjeStr); + + // 清算金额 + String qsjeStr = getCellStringValue(row, 7); + bankbillHistory.setCQsje(qsjeStr); + + // 手续费 + String sxfStr = getCellStringValue(row, 8); + bankbillHistory.setCSxf(sxfStr); + + // 流水号 + String lshStr = getCellStringValue(row, 9); + bankbillHistory.setCLsh(lshStr); + + // 卡类型 + String klxStr = getCellStringValue(row, 10); + bankbillHistory.setCKlx(klxStr); + + // 发卡行 + String fkhStr = getCellStringValue(row, 11); + bankbillHistory.setCFkh(fkhStr); + + // 系统参考号 (对应银商订单号) + String xtckhStr = getCellStringValue(row, 12); + + // 支付方式 + bankbillHistory.setCZffs("银行卡支付"); + + // 银商订单号 + bankbillHistory.setCYsddh(xtckhStr); + + // 表名 + bankbillHistory.setBillTableName(bill_table_name); + + list.add(bankbillHistory); + } + responseMap.put("list", list); + } else { + System.out.println("执行失败,原因:路径" + ftp_path + "下无下载文件" + ftp_file_name); + + errCode = "999"; + errMsg = "执行失败,原因:路径" + ftp_path + "下无下载文件" + ftp_file_name; + } + } catch (Exception e) { + e.printStackTrace(); + System.out.println("执行失败,原因:" + e.getMessage()); + + errCode = "999"; + errMsg = "执行失败,原因:" + e.getMessage(); + + } finally { + try { + if (sheets != null) { + sheets.close(); + } + } catch (Exception ie) { + ie.printStackTrace(); + } + } + responseMap.put("errCode", errCode); + responseMap.put("errMsg", errMsg); + return responseMap; + } + + /** + * @description: 获取银行端商户银联外卡对账数据 + * @author yuan + * @date 2025/7/18 13:57 + * @version 1.0 + */ + @PostMapping("/getBankDataBySHYLWK") + @ResponseBody + public HashMap getBankDataBySHYLWK(@RequestBody HashMap map) { + HashMap responseMap = new HashMap<>(); + String errCode = "0"; + String errMsg = ""; + + // 先下载文件 + String host = StringDUtil.changeNullToEmpty(map.get("FTP_HOST")); + String portStr = StringDUtil.changeNullToEmpty(map.get("FTP_PORT")); + int port = Integer.parseInt("".equals(portStr) ? "21" : portStr); + String username = StringDUtil.changeNullToEmpty(map.get("FTP_USER")); + String password = StringDUtil.changeNullToEmpty(map.get("FTP_PASSWORD")); + String localPath = StringDUtil.changeNullToEmpty(map.get("LOCAL_PATH")); + String mch_id = StringDUtil.changeNullToEmpty(map.get("MCH_ID")); + String ftp_path = StringDUtil.changeNullToEmpty(map.get("FTP_PATH")); + String ftp_file_name = StringDUtil.changeNullToEmpty(map.get("FTP_FILE_NAME")); + String bill_table_name = StringDUtil.changeNullToEmpty(map.get("BILL_TABLE_NAME")); + String thirdConfigId = StringDUtil.changeNullToEmpty(map.get("ID")); + String trade_date = StringDUtil.changeNullToEmpty(map.get("trade_date")); + + HSSFWorkbook sheets = null; + try { + // 下载文件 + log.info("开始下载FTP文件: " + ftp_file_name); + boolean b = DownloadFtpUtil.downloadFtpFile(host, username, password, port, ftp_path, localPath, ftp_file_name); + // 判断是否下载到文件 + if (!b) { + log.error("FTP文件下载失败: " + ftp_file_name); + errCode = "1"; + errMsg = "FTP文件下载失败,请检查FTP连接参数和文件是否存在"; + responseMap.put("errCode", errCode); + responseMap.put("errMsg", errMsg); + return responseMap; + } + + // 判断本地是否有文件 + File file = new File(localPath + "/" + ftp_file_name); + if (file.exists()) { + // 存在 开始解析 存入数据库 + FileInputStream fileInputStream = new FileInputStream(localPath + "/" + ftp_file_name); + + sheets = new HSSFWorkbook(fileInputStream); + HSSFSheet sheet = sheets.getSheetAt(0); + // 获取sheet中第一行行号 + int firstRowNum = sheet.getFirstRowNum(); + // 获取sheet中最后一行行号 + int lastRowNum = sheet.getLastRowNum(); + + List list = new ArrayList<>(); + + // 银联外卡对账单从第4行开始解析数据(前3行是标题和表头) + for (int i = firstRowNum + 3; i <= lastRowNum - 2; i++) { + HSSFRow row = sheet.getRow(i); + if (row == null) { + continue; + } + + BankbillHistory bankbillHistory = new BankbillHistory(); + + // 清算日期 + String qsrqStr = getCellStringValue(row, 0); + + // 拿第一个字段判断这条记录是否为空 如果为空直接跳出 + if ("".equals(qsrqStr) || "合计".equals(qsrqStr)) { + break; + } + bankbillHistory.setCQsrq(qsrqStr); + + // 交易日期 + String jyrqStr = getCellDateValue(row, 1); + bankbillHistory.setCJyrq(jyrqStr); + + // 交易时间 + String jysjStr = getCellStringValue(row, 2); + bankbillHistory.setCJysj(jysjStr); + + // 终端号 + String zdhStr = getCellStringValue(row, 3); + bankbillHistory.setCZdh(zdhStr); + + // 卡号 + String khStr = getCellStringValue(row, 4); + bankbillHistory.setCCard(khStr); + + // 交易类型 + String jylxStr = getCellStringValue(row, 5); + bankbillHistory.setCJylx(jylxStr); + + // 交易金额 + String jyjeStr = getCellStringValue(row, 6); + bankbillHistory.setCJyje(jyjeStr); + + // 清算金额 + String qsjeStr = getCellStringValue(row, 7); + bankbillHistory.setCQsje(qsjeStr); + + // 手续费 + String sxfStr = getCellStringValue(row, 8); + bankbillHistory.setCSxf(sxfStr); + + // 参考号 + String ckhStr = getCellStringValue(row, 9); + bankbillHistory.setCCkh(ckhStr); + + // 流水号 + String lshStr = getCellStringValue(row, 10); + bankbillHistory.setCLsh(lshStr); + + // 卡类型 + String klxStr = getCellStringValue(row, 11); + bankbillHistory.setCKlx(klxStr); + + // 授权码 + String sqmStr = getCellStringValue(row, 12); + bankbillHistory.setCBzzd(sqmStr); // 使用备注字段存储授权码 + + // 分店名称 + String fdmcStr = getCellStringValue(row, 13); + bankbillHistory.setCFdjc(fdmcStr); + + // 设置支付方式 + bankbillHistory.setCZffs("银联外卡支付"); + + // 设置表名 + bankbillHistory.setBillTableName(bill_table_name); + + list.add(bankbillHistory); + } + responseMap.put("list", list); + } else { + System.out.println("执行失败,原因:路径" + ftp_path + "下无下载文件" + ftp_file_name); + + errCode = "999"; + errMsg = "执行失败,原因:路径" + ftp_path + "下无下载文件" + ftp_file_name; + } + } catch (Exception e) { + e.printStackTrace(); + System.out.println("执行失败,原因:" + e.getMessage()); + + errCode = "999"; + errMsg = "执行失败,原因:" + e.getMessage(); + + } finally { + try { + if (sheets != null) { + sheets.close(); + } + } catch (Exception ie) { + ie.printStackTrace(); + } + } + responseMap.put("errCode", errCode); + responseMap.put("errMsg", errMsg); + return responseMap; + } + + /** + * @description: 获取微信支付对账数据 + * @author thuang + * @date 2021/9/22 13:57 + * @version 1.0 + */ + @PostMapping("/getBankDataByWXAPI") + @ResponseBody + public HashMap getBankDataByWXAPI(@RequestBody HashMap map) { + List list = new ArrayList<>(); + log.info("开始获取微信账单"); + HashMap responseMap = new HashMap<>(); + String errCode = "0"; + String errMsg = ""; + + try { + String localPath = StringDUtil.changeNullToEmpty(map.get("LOCAL_PATH")); + String mch_id = StringDUtil.changeNullToEmpty(map.get("MCH_ID")); + String trade_date = StringDUtil.changeNullToEmpty(map.get("trade_date")); + + HashMap reqMap = new HashMap<>(); + reqMap.put("grant_type", grant_type); + reqMap.put("appid", appid); + reqMap.put("secret", secret); + + String randomStr = RandomUtil.randomString(32); + + String signString = "appid=" + appid + "&bill_date=" + trade_date + "&bill_type=ALL&mch_id=" + mch_id + "&nonce_str=" + randomStr + "&key="+ key; + String sign = SecureUtil.md5(signString).toUpperCase(); + String reqXml = "\n" + + " " + appid + "\n" + + " " + trade_date + "\n" + + " ALL\n" + + " " + mch_id + "\n" + + " " + randomStr + "\n" + + " " + sign + "\n" + + ""; + // 获取access_token + log.info("开始调用微信账单接口,参数: mch_id={}, trade_date={}", mch_id, trade_date); + String body1 = HttpUtil.createPost("https://api.mch.weixin.qq.com/pay/downloadbill") + .header("Content-Type", "text/xml") + .timeout(30000) // 设置30秒超时 + .body(reqXml) + .execute() + .body(); + log.info("微信账单接口返回数据长度: {}", body1 != null ? body1.length() : 0); + + // 检查微信接口返回状态 + + if (body1.contains("")) { + log.info("账单正在生成中,请稍后重试"); + errCode = "999"; + errMsg = "微信账单正在生成中,请稍后重试"; + responseMap.put("errCode", errCode); + responseMap.put("errMsg", errMsg); + return responseMap; + } + + String[] split = body1.split("\n"); + for (int i = 1; i < split.length - 2; i++) { + String[] split1 = split[i].split(","); + if (Arrays.toString(split1).equals("[]")) { + break; + } + // 检查是否是账单正在生成状态 + if (Arrays.toString(split1).contains("Bill Creating")) { + log.info("账单正在生成中,跳过处理"); + break; + } + + BankbillHistory bankbillHistory = new BankbillHistory(); + int flag = 0; + + // 解析CSV数据到BankbillHistory实体 + for (int j = 0; j < split1.length; j++) { + String value = split1[j].replaceAll("`", "").trim(); + + switch (j) { + case 0: // 交易时间 + if (value.contains(" ")) { + String[] timeSplit = value.split(" "); + bankbillHistory.setCQsrq(timeSplit[0]); // 清算日期 + bankbillHistory.setCJyrq(timeSplit[0]); // 交易日期 + bankbillHistory.setCJysj(timeSplit[1]); // 交易时间 + } + break; + case 4: // 设备号 + bankbillHistory.setCZdh(value); + break; + case 5: // 微信订单号 + bankbillHistory.setCYsddh(value); + break; + case 6: // 商户订单号 + bankbillHistory.setCShddh(value); + break; + case 7: // 用户标识 + bankbillHistory.setCCard(value); + break; + case 8: // 交易类型 + bankbillHistory.setCJylx(value); + break; + case 9: // 交易状态 + if ("REFUND".equals(value)) { + flag = -1; + } + break; + case 10: // 付款银行 + bankbillHistory.setCFkh(value); + break; + case 12: // 应结订单金额 + bankbillHistory.setCQsje(value); + break; + case 24: // 订单金额 + if (flag < 0) { + bankbillHistory.setCJyje("-" + value); + } else { + bankbillHistory.setCJyje(value); + } + break; + case 20: // 商品名称 + bankbillHistory.setCBzzd(value); + break; + case 22: // 手续费 + bankbillHistory.setCSxf(value); + break; + case 15: // 微信退款单号 + bankbillHistory.setCThddh(value); + break; + case 16: // 商户退款单号 + bankbillHistory.setCYjylsh(value); + break; + case 17: // 退款金额 + if (!"0.00".equals(value)) { + bankbillHistory.setCJyje("-" + value); + } + break; + } + } + + // 设置支付方式 + bankbillHistory.setCZffs("微信支付"); + + // 设置表名 + bankbillHistory.setBillTableName("微信支付账单"); + + list.add(bankbillHistory); + } +// // 获取access_token +// String body = HttpUtil.createPost("https://api.weixin.qq.com/cgi-bin/stable_token").body(JSONUtil.toJsonStr(reqMap)).execute().body(); +// +// String access_token = JSONUtil.parseObj(body).getStr("access_token"); +// // 获取医保账单下载地址 +// // https://api.weixin.qq.com/payinsurance/billdownload?access_token=ACCESS_TOKEN +// String signYBString = "appid=" + appid + "&bill_date=" + trade_date + "&bill_type=ALL&mch_id=" + mch_id + "&nonce_str=" + randomStr + "&key="+key; +// log.info("微信账单签名:" + signYBString); +// String signYB = SecureUtil.md5(signYBString).toUpperCase(); +// String reqYbXml = "\n" + +// " " + appid + "\n" + +// " " + trade_date + "\n" + +// " ALL\n" + +// " " + mch_id + "\n" + +// " " + randomStr + "\n" + +// " " + signYB + "\n" + +// ""; +// String resBody = HttpUtil.createPost("https://api.weixin.qq.com/payinsurance/billdownload?access_token=" + access_token).header("Content-Type", "text/xml").body(reqYbXml).execute().body(); +// log.info("微信账单下载返回结果:" + resBody); +// Document document = XmlUtil.parseXml(resBody); +// Element elementG = XmlUtil.getRootElement(document); +// Element returnCode = XmlUtil.getElement(elementG, "return_code"); +// +// if (returnCode.getTextContent().equals("SUCCESS")) {// 响应成功 +// // 下载文件 +// Element downloadUrl = XmlUtil.getElement(elementG, "download_url"); +// String dwUrl = downloadUrl.getTextContent(); +// log.info("开始下载文件"); +// HttpUtil.downloadFileFromUrl(dwUrl, localPath + File.separator + trade_date + ".csv"); +// HttpUtil.downloadFileFromUrl(dwUrl, localPath + File.separator + trade_date + ".txt"); +// // HttpUtil.downloadFileFromUrl(dwUrl, localPath); +// log.info("下载文件成功"); +// CsvReader reader = CsvUtil.getReader(); +// try { +// CsvData read = reader.read(FileUtil.file(localPath + File.separator + trade_date + ".csv")); +// List rows = read.getRows(); +// if (rows.size() > 1) { +// for (int i = 1; i < rows.size(); i++) { +// CsvRow row = rows.get(i); +// BankbillHistory bankbillHistory = new BankbillHistory(); +// String s = row.get(0).replaceAll("`", ""); +// String[] s1 = s.split(" "); +// log.info("s1 is :" + Arrays.toString(s1)); +// bankbillHistory.setCJyrq(s1[0]); +// bankbillHistory.setCQsrq(s1[0]); +// bankbillHistory.setCJysj(s1[1]); +// bankbillHistory.setCZdh(row.get(1).replaceAll("`", "")); +// bankbillHistory.setCCkh(row.get(2).replaceAll("`", "")); +// bankbillHistory.setCLsh(row.get(5).replaceAll("`", "")); +// bankbillHistory.setCShddh(row.get(6).replaceAll("`", "")); +// bankbillHistory.setCCard(row.get(7).replaceAll("`", "")); +// bankbillHistory.setCYsddh(row.get(25).replaceAll("`", "")); +// if (row.get(46).replaceAll("`", "").equals("0.00")) { +// continue; +// } +// if (row.get(45).replaceAll("`", "").equals("REFUND")) { +// bankbillHistory.setCJyje("-" + row.get(46).replaceAll("`", "")); +// } else { +// bankbillHistory.setCJyje(row.get(46).replaceAll("`", "")); +// } +// bankbillHistory.setBillTableName("微信支付账单"); +// list.add(bankbillHistory); +// } +// } +// responseMap.put("list", list); +// } catch (IORuntimeException e) { +// throw new RuntimeException(e); +// } finally { +// try { +// reader.close(); +// } catch (IOException e) { +// throw new RuntimeException(e); +// } +// } +// } + if (list.size() > 0) { + responseMap.put("list", list); + } else { + errCode = "999"; + errMsg = "账单数据为空,或未获取到账单!"; + } + responseMap.put("errCode", errCode); + responseMap.put("errMsg", errMsg); + return responseMap; + + } catch (Exception e) { + log.error("微信账单获取异常", e); + errCode = "999"; + errMsg = "微信账单获取异常: " + e.getMessage(); + responseMap.put("errCode", errCode); + responseMap.put("errMsg", errMsg); + return responseMap; + } + } + + +// public static void main(String[] args) { +// +// String a = "?交易时间,公众账号ID,商户号,特约商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,应结订单金额,代金券金额,微信退款单号,商户退款单号,退款金额,充值券退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率,订单金额,申请退款金额,费率备注\n" + +// "`2024-08-09 17:55:10,`wx83bc9715be856b14,`1648728329,`0,`,`4200002314202408091169938410,`JJ20240809175501,`o-ZxO47Otvo5Rsq7kN-4PHvZIOt8,`JSAPI,`SUCCESS,`ICBC_DEBIT,`CNY,`61.00,`0.00,`0,`0,`0.00,`0.00,`,`,`库尔勒市妇幼保健院-门诊付款,`{\\\"patid\\\":\\\"385606\\\"\\ \\\"sjh\\\":\\\"20240809yypt120016\\\"\\ \\\"ysje\\\":\\\"61.0000\\\"\\ \\\"zfje\\\":\\\"61.0000\\\"\\ \\\"zje\\\":\\\"61.0000\\\"},`0.00000,`0.00%,`61.00,`0.00,`\n" + +// "`2024-08-09 19:09:18,`wx83bc9715be856b14,`1648728329,`0,`,`4200002314202408091169938410,`JJ20240809175501,`o-ZxO47Otvo5Rsq7kN-4PHvZIOt8,`JSAPI,`REFUND,`ICBC_DEBIT,`CNY,`0.00,`0.00,`50303000492024080988526514493,`C0_20240809yypt120016,`61.00,`0.00,`ORIGINAL,`SUCCESS,`库尔勒市妇幼保健院-门诊付款,`{\\\"patid\\\":\\\"385606\\\"\\ \\\"sjh\\\":\\\"20240809yypt120016\\\"\\ \\\"ysje\\\":\\\"61.0000\\\"\\ \\\"zfje\\\":\\\"61.0000\\\"\\ \\\"zje\\\":\\\"61.0000\\\"},`0.00000,`0.00%,`0.00,`61.00,`\n" + +// "`2024-08-09 18:07:51,`wx83bc9715be856b14,`1648728329,`0,`,`4200002320202408095363202348,`JJ20240809180744,`o-ZxO47Otvo5Rsq7kN-4PHvZIOt8,`JSAPI,`SUCCESS,`ICBC_DEBIT,`CNY,`104.00,`0.00,`0,`0,`0.00,`0.00,`,`,`库尔勒市妇幼保健院-门诊付款,`{\\\"patid\\\":\\\"447719\\\"\\ \\\"sjh\\\":\\\"20240809yypt120017\\\"\\ \\\"ysje\\\":\\\"104.0000\\\"\\ \\\"zfje\\\":\\\"104.0000\\\"\\ \\\"zje\\\":\\\"104.0000\\\"},`0.00000,`0.00%,`104.00,`0.00,`\n" + +// "`2024-08-09 19:07:39,`wx83bc9715be856b14,`1648728329,`0,`,`4200002320202408095363202348,`JJ20240809180744,`o-ZxO47Otvo5Rsq7kN-4PHvZIOt8,`JSAPI,`REFUND,`ICBC_DEBIT,`CNY,`0.00,`0.00,`50303500422024080937274513002,`C0_20240809yypt120017,`104.00,`0.00,`ORIGINAL,`SUCCESS,`库尔勒市妇幼保健院-门诊付款,`{\\\"patid\\\":\\\"447719\\\"\\ \\\"sjh\\\":\\\"20240809yypt120017\\\"\\ \\\"ysje\\\":\\\"104.0000\\\"\\ \\\"zfje\\\":\\\"104.0000\\\"\\ \\\"zje\\\":\\\"104.0000\\\"},`0.00000,`0.00%,`0.00,`104.00,`\n" + +// "`2024-08-09 17:54:18,`wx83bc9715be856b14,`1648728329,`0,`,`4200002326202408099114331548,`JJ20240809175411,`o-ZxO47Otvo5Rsq7kN-4PHvZIOt8,`JSAPI,`SUCCESS,`ICBC_DEBIT,`CNY,`298.38,`0.00,`0,`0,`0.00,`0.00,`,`,`库尔勒市妇幼保健院-门诊付款,`{\\\"patid\\\":\\\"447719\\\"\\ \\\"sjh\\\":\\\"20240809yypt120015\\\"\\ \\\"ysje\\\":\\\"298.3800\\\"\\ \\\"zfje\\\":\\\"298.3800\\\"\\ \\\"zje\\\":\\\"298.3800\\\"},`0.00000,`0.00%,`298.38,`0.00,`\n" + +// "`2024-08-09 19:47:02,`wx83bc9715be856b14,`1648728329,`0,`,`4200002326202408099114331548,`JJ20240809175411,`o-ZxO47Otvo5Rsq7kN-4PHvZIOt8,`JSAPI,`REFUND,`ICBC_DEBIT,`CNY,`0.00,`0.00,`50303500342024080940745293001,`C0_20240809yypt120015,`298.38,`0.00,`ORIGINAL,`SUCCESS,`库尔勒市妇幼保健院-门诊付款,`{\\\"patid\\\":\\\"447719\\\"\\ \\\"sjh\\\":\\\"20240809yypt120015\\\"\\ \\\"ysje\\\":\\\"298.3800\\\"\\ \\\"zfje\\\":\\\"298.3800\\\"\\ \\\"zje\\\":\\\"298.3800\\\"},`0.00000,`0.00%,`0.00,`298.38,`\n" + +// "总交易单数,应结订单总金额,退款总金额,充值券退款总金额,手续费总金额,订单总金额,申请退款总金额\n" + +// "`6,`463.38,`463.38,`0.00,`0.00000,`463.38,`463.38"; +// String[] split = a.split("\n"); +// for (int i = 1; i < split.length - 2; i++) { +// String[] split1 = split[i].split(","); +// for (int j = 0; j < split1.length; j++) { +// +// System.out.println("=============="); +// System.out.println("第" + j + "个:"); +// System.out.println(split1[j]); +// System.out.println("=============="); +// if (j == 21) { +// String s = split1[j].replaceAll("`", ""); +// String s1 = s.replaceAll(" ", ",").replaceAll("\\\\", ""); +// JSONObject entries = JSONUtil.parseObj(s1); +// Object zfje = entries.get("zfje"); +// +// System.out.println(zfje.toString().substring(0, 5)); +// +// } +// } +// } +// System.out.println(); +// } +} diff --git a/src/main/java/com/saye/hgddmz/entity/BankbillHistory.java b/src/main/java/com/saye/hgddmz/entity/BankbillHistory.java new file mode 100644 index 0000000..42803da --- /dev/null +++ b/src/main/java/com/saye/hgddmz/entity/BankbillHistory.java @@ -0,0 +1,143 @@ +package com.saye.hgddmz.entity; + +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; + +/** + * (BankbillHistory)实体类 + * + * @author makejava + * @since 2021-09-09 16:03:37 + */ +@Getter +@Setter +public class BankbillHistory implements Serializable { + private static final long serialVersionUID = -33254602055133483L; + /** + * 清算日期 + */ + private String cQsrq; + /** + * 交易日期 + */ + private String cJyrq; + /** + * 交易时间 + */ + private String cJysj; + /** + * 终端号 + */ + private String cZdh; + /** + * 卡号(部分加密 应该没用 ) + */ + private String cCard; + /** + * 交易类型 + */ + private String cJylx; + /** + * 交易金额 + */ + private String cJyje; + /** + * 清算金额 + */ + private String cQsje; + /** + * 手续费 + */ + private String cSxf; + /** + * 实际支付金额 + */ + private String cSjzfje; + /** + * 参考号 + */ + private String cCkh; + /** + * 流水号 + */ + private String cLsh; + /** + * 卡类型 + */ + private String cKlx; + /** + * 发卡行 + */ + private String cFkh; + /** + * 支付方式 + */ + private String cZffs; + /** + * 银商订单号 + */ + private String cYsddh; + /** + * 商户订单号 + */ + private String cShddh; + /** + * 备注字段 + */ + private String cBzzd; + /** + * 钱包优惠金额 + */ + private String cQbyhje; + /** + * 商户优惠金额 + */ + private String cShyhje; + /** + * 原交易流水号 + */ + private String cYjylsh; + /** + * 分期期数 + */ + private String cFqqs; + /** + * 分期手续费 + */ + private String cFqsxf; + /** + * 分期服务方 + */ + private String cFqfwf; + /** + * 分期付息方 + */ + private String cFqfxf; + /** + * 其他优惠金额 + */ + private String cQtyhje; + /** + * 退货订单号 + */ + private String cThddh; + /** + * 付款附言 + */ + private String cFkfy; + /** + * 分店简称 + */ + private String cFdjc; + /** + * 子订单号 + */ + private String cZddh; + /** + * 对账表名 + */ + private String billTableName; +} + diff --git a/src/main/java/com/saye/hgddmz/testController.java b/src/main/java/com/saye/hgddmz/testController.java new file mode 100644 index 0000000..a2260fe --- /dev/null +++ b/src/main/java/com/saye/hgddmz/testController.java @@ -0,0 +1,25 @@ +package com.saye.hgddmz; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.HashMap; + +/** + * @author thuang + * @version 1.0 + * @description: TODO + * @date 2021/9/22 13:12 + */ +@Controller +public class testController { + + @RequestMapping("/index") + public String toIndex(){ + + return "index"; + } + + +} diff --git a/src/main/java/com/saye/hgddmz/util/DownloadFtpUtil.java b/src/main/java/com/saye/hgddmz/util/DownloadFtpUtil.java new file mode 100644 index 0000000..30d272b --- /dev/null +++ b/src/main/java/com/saye/hgddmz/util/DownloadFtpUtil.java @@ -0,0 +1,301 @@ +package com.saye.hgddmz.util; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.net.ftp.FTPReply; + +import java.io.*; +import java.net.SocketException; + +/** + * @author thuang + * @version 1.0 + * @description: + * 下载ftp文件 + * @date 2021/8/6 14:17 + */ +@Slf4j +public class DownloadFtpUtil { + + /** + * 获取FTPClient对象 + * + * @param ftpHost + * FTP主机服务器 + * @param ftpPassword + * FTP 登录密码 + * @param ftpUserName + * FTP登录用户名 + * @param ftpPort + * FTP端口 默认为21 + * @return + */ + public static FTPClient getFTPClient(String ftpHost, String ftpUserName, + String ftpPassword, int ftpPort) { + FTPClient ftpClient = null; + try { + ftpClient = new FTPClient(); + // 设置更长的连接超时时间 + ftpClient.setConnectTimeout(60000); // 60秒连接超时 + ftpClient.setDataTimeout(120000); // 120秒数据传输超时 + ftpClient.setControlKeepAliveTimeout(300); // 保持连接活跃 + ftpClient.setControlKeepAliveReplyTimeout(10000); // 保持连接回复超时 + + log.info("=== FTP连接详细信息 ==="); + log.info("FTP服务器地址: {}", ftpHost); + log.info("FTP服务器端口: {}", ftpPort); + log.info("FTP用户名: {}", ftpUserName); + log.info("连接超时时间: {}ms", 60000); + log.info("数据传输超时时间: {}ms", 120000); + log.info("开始连接FTP服务器: {}:{}", ftpHost, ftpPort); + + ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器 + + // 检查连接是否成功 + if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { + log.error("FTP连接失败,服务器响应码: {}", ftpClient.getReplyCode()); + log.error("FTP服务器响应信息: {}", ftpClient.getReplyString()); + if (ftpClient.isConnected()) { + ftpClient.disconnect(); + } + return null; + } + + log.info("FTP服务器连接成功,响应码: {}", ftpClient.getReplyCode()); + log.info("FTP服务器响应信息: {}", ftpClient.getReplyString()); + log.info("正在登录FTP服务器,用户名: {}", ftpUserName); + + boolean loginSuccess = ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器 + if (!loginSuccess) { + log.error("FTP登录失败,请检查用户名和密码"); + log.error("登录失败响应码: {}", ftpClient.getReplyCode()); + log.error("登录失败响应信息: {}", ftpClient.getReplyString()); + if (ftpClient.isConnected()) { + ftpClient.disconnect(); + } + return null; + } + + log.info("FTP登录成功,响应码: {}", ftpClient.getReplyCode()); + log.info("FTP登录响应信息: {}", ftpClient.getReplyString()); + + // 设置FTP传输模式 + ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); // 二进制传输模式 + ftpClient.enterLocalPassiveMode(); // 被动模式 + ftpClient.setBufferSize(1024 * 1024); // 设置缓冲区大小 + + log.info("=== FTP连接和登录成功 ==="); + return ftpClient; + + } catch (SocketException e) { + log.error("FTP连接Socket异常: {}", e.getMessage()); + log.error("异常堆栈信息:", e); + // 发生异常时断开连接 + if (ftpClient != null && ftpClient.isConnected()) { + try { + ftpClient.disconnect(); + } catch (IOException ie) { + log.error("断开FTP连接失败: {}", ie.getMessage()); + } + } + } catch (IOException e) { + log.error("FTP连接IO异常: {}", e.getMessage()); + log.error("异常堆栈信息:", e); + // 发生异常时断开连接 + if (ftpClient != null && ftpClient.isConnected()) { + try { + ftpClient.disconnect(); + } catch (IOException ie) { + log.error("断开FTP连接失败: {}", ie.getMessage()); + } + } + } catch (Exception e) { + log.error("FTP连接未知异常: {}", e.getMessage()); + log.error("异常堆栈信息:", e); + // 发生异常时断开连接 + if (ftpClient != null && ftpClient.isConnected()) { + try { + ftpClient.disconnect(); + } catch (IOException ie) { + log.error("断开FTP连接失败: {}", ie.getMessage()); + } + } + } + + return null; + } + + + /* + * 从FTP服务器下载文件 + * + * @param ftpHost FTP IP地址 + * + * @param ftpUserName FTP 用户名 + * + * @param ftpPassword FTP用户名密码 + * + * @param ftpPort FTP端口 + * + * @param ftpPath FTP服务器中文件所在路径 格式: ftptest/aa + * + * @param localPath 下载到本地的位置 格式:H:/download + * + * @param fileName 文件名称 + */ + public static boolean downloadFtpFile(String ftpHost, String ftpUserName, + String ftpPassword, int ftpPort, String ftpPath, String localPath, + String fileName) { + + int maxRetries = 3; // 最大重试次数 + + for (int retryCount = 0; retryCount < maxRetries; retryCount++) { + FTPClient ftpClient = null; + OutputStream os = null; + boolean shouldRetry = false; + + try { + log.info("尝试第 {} 次下载文件: {}", retryCount + 1, fileName); + + //先判断下载的路径是否存在 不存在创建 + File file = new File(localPath); + if (!file.exists()) { + file.mkdirs(); + } + + ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort); + + // 检查连接是否成功 + if (ftpClient == null) { + log.error("FTP客户端为null,连接失败"); + shouldRetry = true; + } else if (!ftpClient.isConnected()) { + log.error("FTP客户端未连接,连接状态: {}", ftpClient.isConnected()); + shouldRetry = true; + } else { + log.info("FTP连接状态检查通过,开始下载文件"); + log.info("FTP连接状态: {}", ftpClient.isConnected()); + + // 切换到指定目录 + if (ftpPath != null && !ftpPath.trim().isEmpty()) { + if (!ftpClient.isConnected()) { + log.error("FTP连接已断开,无法切换目录"); + shouldRetry = true; + } else { + boolean changed = ftpClient.changeWorkingDirectory(ftpPath); + if (!changed) { + log.warn("切换FTP目录失败: " + ftpPath); + } + } + } + + if (!shouldRetry) { + // 跳过文件存在性检查,直接尝试下载 + log.info("跳过文件存在性检查,直接尝试下载文件: {}", fileName); + + // 下载文件 + File localFile = new File(localPath + File.separatorChar + fileName); + log.info("准备下载文件到本地路径: {}", localFile.getAbsolutePath()); + + os = new FileOutputStream(localFile); + + if (!ftpClient.isConnected()) { + log.error("FTP连接已断开,无法下载文件"); + shouldRetry = true; + } else { + log.info("开始下载文件: {}", fileName); + boolean downloadSuccess = ftpClient.retrieveFile(fileName, os); + + // 立即关闭输出流 + if (os != null) { + try { + os.close(); + os = null; + } catch (IOException e) { + log.error("关闭输出流失败: {}", e.getMessage()); + } + } + + if (downloadSuccess) { + log.info("文件下载成功: {}", fileName); + // 检查下载的文件大小 + if (localFile.exists()) { + long fileSize = localFile.length(); + log.info("下载的文件大小: {} 字节", fileSize); + if (fileSize == 0) { + log.warn("警告:下载的文件大小为0字节,可能下载失败"); + shouldRetry = true; + } else { + return true; // 下载成功 + } + } else { + log.error("下载的文件不存在: {}", localFile.getAbsolutePath()); + shouldRetry = true; + } + } else { + log.error("文件下载失败: {}", fileName); + // 获取FTP服务器的回复码 + int replyCode = ftpClient.getReplyCode(); + log.error("FTP服务器回复码: {}", replyCode); + shouldRetry = true; + } + } + } + } + + } catch (FileNotFoundException e) { + log.error("没有找到文件: " + ftpPath + "/" + fileName + ", 错误: " + e.getMessage()); + e.printStackTrace(); + shouldRetry = true; + } catch (SocketException e) { + log.error("连接FTP失败: " + e.getMessage()); + e.printStackTrace(); + shouldRetry = true; + } catch (IOException e) { + log.error("文件读取错误: " + e.getMessage()); + e.printStackTrace(); + shouldRetry = true; + } catch (Exception e) { + log.error("FTP下载过程中发生未知错误: " + e.getMessage()); + e.printStackTrace(); + shouldRetry = true; + } finally { + // 确保资源正确关闭 + if (os != null) { + try { + os.close(); + } catch (IOException e) { + log.error("关闭输出流失败: " + e.getMessage()); + } + } + if (ftpClient != null && ftpClient.isConnected()) { + try { + ftpClient.logout(); + ftpClient.disconnect(); + } catch (IOException e) { + log.error("关闭FTP连接失败: " + e.getMessage()); + } + } + } + + // 如果需要重试且还有重试次数 + if (shouldRetry && retryCount < maxRetries - 1) { + log.info("等待2秒后重试..."); + try { + Thread.sleep(2000); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + break; + } + } + } + + log.error("所有重试都失败了"); + return false; + } + + public static void main(String[] args) { + boolean b = downloadFtpFile("uisftp.chinaums.com", "101200-898650180620093", "Aa112233.", 21, "build", "d:\\1", "898650180620093_20250709_68.xls"); + + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..ded3597 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,11 @@ +server: + port: 8081 + servlet: + context-path: / + +#日志 +logging: + level: + com.saye: debug + pattern: + console: "%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger- %msg%n" \ No newline at end of file diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html new file mode 100644 index 0000000..491608e --- /dev/null +++ b/src/main/resources/templates/index.html @@ -0,0 +1,10 @@ + + + + + 测试 + + +
1
+ + \ No newline at end of file diff --git a/src/test/java/com/saye/hgddmz/FtpConnectionTest.java b/src/test/java/com/saye/hgddmz/FtpConnectionTest.java new file mode 100644 index 0000000..22aeacb --- /dev/null +++ b/src/test/java/com/saye/hgddmz/FtpConnectionTest.java @@ -0,0 +1,312 @@ +package com.saye.hgddmz; + +import com.saye.hgddmz.util.DownloadFtpUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.net.ftp.FTPReply; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; + +/** + * FTP Connection Test Class + * @author thuang + * @version 1.0 + * @description: Test FTP connection functionality + * @date 2024/1/1 + */ +@Slf4j +public class FtpConnectionTest { + + private static final String FTP_HOST = "uisftp.chinaums.com"; + private static final int FTP_PORT = 21; + private static final String FTP_USERNAME = "101200-898650180620093"; + private static final String FTP_PASSWORD = "Aa112233."; + + /** + * Test network connectivity + */ + @Test + public void testNetworkConnectivity() { + log.info("=== Start testing network connectivity ==="); + + // Test DNS resolution + try { + log.info("Testing DNS resolution: {}", FTP_HOST); + InetAddress address = InetAddress.getByName(FTP_HOST); + log.info("DNS resolution successful, IP address: {}", address.getHostAddress()); + log.info("Hostname: {}", address.getHostName()); + log.info("Is reachable: {}", address.isReachable(5000)); + } catch (UnknownHostException e) { + log.error("DNS resolution failed: {}", e.getMessage()); + } catch (IOException e) { + log.error("Network reachability test failed: {}", e.getMessage()); + } + + // Test port connectivity + try { + log.info("Testing port connectivity: {}:{}", FTP_HOST, FTP_PORT); + Socket socket = new Socket(FTP_HOST, FTP_PORT); + log.info("Port connectivity test successful, local port: {}", socket.getLocalPort()); + socket.close(); + } catch (IOException e) { + log.error("Port connectivity test failed: {}", e.getMessage()); + } + + log.info("=== Network connectivity test completed ==="); + } + + /** + * Test FTP connection + */ + @Test + public void testFtpConnection() { + log.info("=== Start testing FTP connection ==="); + + FTPClient ftpClient = null; + try { + ftpClient = DownloadFtpUtil.getFTPClient(FTP_HOST, FTP_USERNAME, FTP_PASSWORD, FTP_PORT); + + if (ftpClient != null && ftpClient.isConnected()) { + log.info("FTP connection test successful"); + log.info("FTP server information:"); + log.info(" - Server address: {}", FTP_HOST); + log.info(" - Server port: {}", FTP_PORT); + log.info(" - Connection status: {}", ftpClient.isConnected()); + log.info(" - Current directory: {}", ftpClient.printWorkingDirectory()); + + // Test listing files in root directory + try { + String[] files = ftpClient.listNames(); + if (files != null) { + log.info("Root directory file list ({} files):", files.length); + for (String file : files) { + log.info(" - {}", file); + } + } else { + log.info("Root directory is empty"); + } + } catch (IOException e) { + log.warn("Failed to list files in root directory: {}", e.getMessage()); + } + + // Test listing files in build directory + try { + log.info("Switching to build directory..."); + boolean changed = ftpClient.changeWorkingDirectory("build"); + if (changed) { + log.info("Successfully switched to build directory"); + String[] files = ftpClient.listNames(); + if (files != null) { + log.info("Build directory file list ({} files):", files.length); + for (String file : files) { + log.info(" - {}", file); + } + } else { + log.info("Build directory is empty"); + } + } else { + log.error("Failed to switch to build directory"); + } + } catch (IOException e) { + log.warn("Failed to list files in build directory: {}", e.getMessage()); + } + + } else { + log.error("FTP connection test failed"); + } + + } catch (Exception e) { + log.error("FTP connection test exception: {}", e.getMessage()); + } finally { + if (ftpClient != null && ftpClient.isConnected()) { + try { + ftpClient.logout(); + ftpClient.disconnect(); + log.info("FTP connection closed"); + } catch (IOException e) { + log.error("Failed to close FTP connection: {}", e.getMessage()); + } + } + } + + log.info("=== FTP connection test completed ==="); + } + + /** + * Test FTP file download + */ + @Test + public void testFtpFileDownload() { + log.info("=== Start testing FTP file download ==="); + + String ftpPath = "build"; + String localPath = "d:\\1"; + String fileName = "898650180620093_20250723_1.xls"; + + log.info("Download parameters:"); + log.info(" - FTP path: {}", ftpPath); + log.info(" - Local path: {}", localPath); + log.info(" - File name: {}", fileName); + log.info(" - Full local path: {}\\{}", localPath, fileName); + + try { + boolean result = DownloadFtpUtil.downloadFtpFile( + FTP_HOST, FTP_USERNAME, FTP_PASSWORD, FTP_PORT, + ftpPath, localPath, fileName + ); + + if (result) { + log.info("FTP file download test successful"); + log.info("Download file information:"); + log.info(" - Server path: {}/{}", ftpPath, fileName); + log.info(" - Local path: {}/{}", localPath, fileName); + + // Check if file actually exists + java.io.File downloadedFile = new java.io.File(localPath + "\\" + fileName); + if (downloadedFile.exists()) { + log.info("File exists on local system"); + log.info(" - File size: {} bytes", downloadedFile.length()); + log.info(" - Last modified: {}", new java.util.Date(downloadedFile.lastModified())); + } else { + log.error("File does not exist on local system"); + } + } else { + log.error("FTP file download test failed"); + } + + } catch (Exception e) { + log.error("FTP file download test exception: {}", e.getMessage()); + e.printStackTrace(); + } + + log.info("=== FTP file download test completed ==="); + } + + /** + * Test FTP connection parameters + */ + @Test + public void testFtpConnectionParameters() { + log.info("=== Start testing FTP connection parameters ==="); + + log.info("FTP connection parameters:"); + log.info(" - Host address: {}", FTP_HOST); + log.info(" - Port: {}", FTP_PORT); + log.info(" - Username: {}", FTP_USERNAME); + log.info(" - Password: {}", FTP_PASSWORD.replaceAll(".", "*")); + + // Test different timeout settings + FTPClient ftpClient = null; + try { + ftpClient = new FTPClient(); + + // Set shorter timeout for testing + ftpClient.setConnectTimeout(10000); // 10 seconds + ftpClient.setDataTimeout(30000); // 30 seconds + + log.info("Connection timeout setting: {}ms", 10000); + log.info("Data transfer timeout setting: {}ms", 30000); + + ftpClient.connect(FTP_HOST, FTP_PORT); + + if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { + log.info("Connection successful, response code: {}", ftpClient.getReplyCode()); + + boolean loginSuccess = ftpClient.login(FTP_USERNAME, FTP_PASSWORD); + if (loginSuccess) { + log.info("Login successful"); + } else { + log.error("Login failed, response code: {}", ftpClient.getReplyCode()); + } + } else { + log.error("Connection failed, response code: {}", ftpClient.getReplyCode()); + } + + } catch (Exception e) { + log.error("FTP connection parameters test exception: {}", e.getMessage()); + } finally { + if (ftpClient != null && ftpClient.isConnected()) { + try { + ftpClient.logout(); + ftpClient.disconnect(); + } catch (IOException e) { + log.error("Failed to close FTP connection: {}", e.getMessage()); + } + } + } + + log.info("=== FTP connection parameters test completed ==="); + } + + /** + * Simple FTP connection test + */ + @Test + public void testSimpleFtpConnection() { + log.info("=== Start simple FTP connection test ==="); + + FTPClient ftpClient = null; + try { + ftpClient = DownloadFtpUtil.getFTPClient(FTP_HOST, FTP_USERNAME, FTP_PASSWORD, FTP_PORT); + + if (ftpClient != null) { + log.info("FTP client created successfully"); + log.info("Connection status: {}", ftpClient.isConnected()); + + if (ftpClient.isConnected()) { + log.info("FTP connection is active"); + // Test a simple command + String currentDir = ftpClient.printWorkingDirectory(); + log.info("Current directory: {}", currentDir); + } else { + log.error("FTP connection is not active"); + } + } else { + log.error("FTP client is null"); + } + + } catch (Exception e) { + log.error("Simple FTP connection test exception: {}", e.getMessage()); + e.printStackTrace(); + } finally { + if (ftpClient != null && ftpClient.isConnected()) { + try { + ftpClient.logout(); + ftpClient.disconnect(); + log.info("FTP connection closed"); + } catch (IOException e) { + log.error("Failed to close FTP connection: {}", e.getMessage()); + } + } + } + + log.info("=== Simple FTP connection test completed ==="); + } + + /** + * Main method, can run tests directly + */ + public static void main(String[] args) { + FtpConnectionTest test = new FtpConnectionTest(); + + log.info("Starting FTP connection test..."); + + // Test network connectivity + test.testNetworkConnectivity(); + + // Test FTP connection + test.testFtpConnection(); + + // Test FTP connection parameters + test.testFtpConnectionParameters(); + + // Test file download (optional) + // test.testFtpFileDownload(); + + log.info("FTP connection test completed"); + } +} \ No newline at end of file diff --git a/src/test/java/com/saye/hgddmz/HgdDmzApplicationTests.java b/src/test/java/com/saye/hgddmz/HgdDmzApplicationTests.java new file mode 100644 index 0000000..9dc5083 --- /dev/null +++ b/src/test/java/com/saye/hgddmz/HgdDmzApplicationTests.java @@ -0,0 +1,13 @@ +package com.saye.hgddmz; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class HgdDmzApplicationTests { + + @Test + void contextLoads() { + } + +}