commit 29d9bbe22e0be209e1c4a1d0893699259cc9b2c4 Author: 一梦千年 <421281095@qq.com> Date: Sat Nov 29 09:34:49 2025 +0800 给的代码没有git 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/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 0000000..a45eb6b --- /dev/null +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,118 @@ +/* + * Copyright 2007-present the original author or authors. + * + * Licensed 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. + */ + +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + private static final String WRAPPER_VERSION = "0.5.6"; + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" + + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if (mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if (mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if (!outputFile.getParentFile().exists()) { + if (!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { + String username = System.getenv("MVNW_USERNAME"); + char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); + } + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000..2cc7d4a Binary files /dev/null and b/.mvn/wrapper/maven-wrapper.jar differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..a9f1ef8 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/README.en.md b/README.en.md new file mode 100644 index 0000000..0d723d2 --- /dev/null +++ b/README.en.md @@ -0,0 +1,36 @@ +# h5es + +#### Description +{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} + +#### Software Architecture +Software architecture description + +#### Installation + +1. xxxx +2. xxxx +3. xxxx + +#### Instructions + +1. xxxx +2. xxxx +3. xxxx + +#### Contribution + +1. Fork the repository +2. Create Feat_xxx branch +3. Commit your code +4. Create Pull Request + + +#### Gitee Feature + +1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md +2. Gitee blog [blog.gitee.com](https://blog.gitee.com) +3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) +4. The most valuable open source project [GVP](https://gitee.com/gvp) +5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) +6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md new file mode 100644 index 0000000..535e69d --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +# h5es + +#### 介绍 +{**以下是 Gitee 平台说明,您可以替换此简介** +Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 +无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} + +#### 软件架构 +软件架构说明 + + +#### 安装教程 + +1. xxxx +2. xxxx +3. xxxx + +#### 使用说明 + +1. xxxx +2. xxxx +3. xxxx + +#### 参与贡献 + +1. Fork 本仓库 +2. 新建 Feat_xxx 分支 +3. 提交代码 +4. 新建 Pull Request + + +#### 特技 + +1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md +2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) +3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 +4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 +5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) +6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) 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..d171ade --- /dev/null +++ b/pom.xml @@ -0,0 +1,373 @@ + + + + + org.springframework.boot + spring-boot-starter-parent + 2.3.6.RELEASE + + + 4.0.0 + + senlinfanghuo + + + + + 1.8 + 1.8 + 1.8 + 3.2.0 + 1.1.10 + 1.2.0.Final + + + + + + + + + + org.apache.commons + commons-pool2 + 2.6.0 + + + org.apache.commons + commons-lang3 + + + io.jsonwebtoken + jjwt + 0.9.0 + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework.security + spring-security-web + + + org.springframework.security + spring-security-config + + + + com.github.xiaoymin + swagger-bootstrap-ui + 1.6 + + + io.springfox + springfox-swagger-ui + 2.9.2 + + + io.springfox + springfox-swagger2 + 2.9.2 + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.0.1 + + + org.springframework.boot + spring-boot-starter-test + test + + + org.mybatis.generator + mybatis-generator-maven-plugin + 1.3.7 + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus-boot-starter.version} + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.springframework.boot + spring-boot-starter-aop + + + + + + + + + com.fasterxml.jackson.core + jackson-databind + 2.14.2 + + + com.fasterxml.jackson.core + jackson-core + 2.14.2 + + + com.fasterxml.jackson.core + jackson-annotations + 2.14.2 + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + 2.10.2 + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + + net.logstash.logback + logstash-logback-encoder + 7.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cn.hutool + hutool-all + 5.2.5 + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + org.junit.jupiter + junit-jupiter + 5.9.2 + test + + + + com.github.pagehelper + pagehelper-spring-boot-starter + 1.4.6 + + + + org.apache.commons + commons-lang3 + + + + + commons-io + commons-io + 2.5 + + + + + org.apache.poi + poi-ooxml + 4.1.2 + + + org.projectlombok + lombok + 1.18.20 + + + org.postgresql + postgresql + + + org.geotools + gt-metadata + 20.5 + + + org.geotools + gt-referencing + 20.5 + + + org.geotools + gt-epsg-wkt + 20.5 + + + org.geotools + gt-shapefile + 20.5 + + + com.vividsolutions + jts + 1.11 + + + xercesImpl + xerces + + + + + org.geotools + gt-data + 20.5 + + + javax.measure + jsr-275 + 1.0.0 + + + org.geotools + gt-api + 20.5 + + + org.geotools + gt-main + 20.5 + + + org.geotools + gt-swing + 20.5 + + + org.geotools + gt-jdbc + 20.5 + + + org.geotools.jdbc + gt-jdbc-postgis + 20.5 + + + org.geotools + gt-opengis + 20.5 + + + org.geotools + gt-epsg-hsql + 20.5 + + + nl.pdok + geoserver-manager + 1.7.0-pdok2 + + + org.toile-libre.libe + curl + 0.0.40 + + + com.alibaba.fastjson2 + fastjson2 + 2.0.25 + + + + + + osgeo + OSGeo Release Repository + https://repo.osgeo.org/repository/release/ + false + true + + + osgeo-snapshot + OSGeo Snapshot Repository + https://repo.osgeo.org/repository/snapshot/ + true + false + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/src/main/java/com/zzlh/es/EsApplication.java b/src/main/java/com/zzlh/es/EsApplication.java new file mode 100644 index 0000000..246b0a3 --- /dev/null +++ b/src/main/java/com/zzlh/es/EsApplication.java @@ -0,0 +1,17 @@ +package com.zzlh.es; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; + +@SpringBootApplication +@EnableConfigurationProperties +@MapperScan(basePackages = "com.zzlh.es.mapper") +public class EsApplication { + + public static void main(String[] args) { + SpringApplication.run(EsApplication.class, args); + } + +} diff --git a/src/main/java/com/zzlh/es/annotation/Excel.java b/src/main/java/com/zzlh/es/annotation/Excel.java new file mode 100644 index 0000000..b1fd85e --- /dev/null +++ b/src/main/java/com/zzlh/es/annotation/Excel.java @@ -0,0 +1,183 @@ +package com.zzlh.es.annotation; + + +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.math.BigDecimal; + +/** + * 自定义导出Excel数据注解 + * + * @author hckj + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Excel +{ + /** + * 导出时在excel中排序 + */ + public int sort() default Integer.MAX_VALUE; + + /** + * 导出到Excel中的名字. + */ + public String name() default ""; + + /** + * 日期格式, 如: yyyy-MM-dd + */ + public String dateFormat() default ""; + + /** + * 读取内容转表达式 (如: 0=男,1=女,2=未知) + */ + public String readConverterExp() default ""; + + /** + * 分隔符,读取字符串组内容 + */ + public String separator() default ","; + + /** + * BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化) + */ + public int scale() default -1; + + /** + * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN + */ + public int roundingMode() default BigDecimal.ROUND_HALF_EVEN; + + /** + * 导出时在excel中每个列的高度 单位为字符 + */ + public double height() default 14; + + /** + * 导出时在excel中每个列的宽 单位为字符 + */ + public double width() default 16; + + /** + * 文字后缀,如% 90 变成90% + */ + public String suffix() default ""; + + /** + * 当值为空时,字段的默认值 + */ + public String defaultValue() default ""; + + /** + * 提示信息 + */ + public String prompt() default ""; + + /** + * 设置只能选择不能输入的列内容. + */ + public String[] combo() default {}; + + /** + * 是否需要纵向合并单元格,应对需求:含有list集合单元格) + */ + public boolean needMerge() default false; + + /** + * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写. + */ + public boolean isExport() default true; + + /** + * 另一个类中的属性名称,支持多级获取,以小数点隔开 + */ + public String targetAttr() default ""; + + /** + * 是否自动统计数据,在最后追加一行统计数据总和 + */ + public boolean isStatistics() default false; + + /** + * 导出类型(0数字 1字符串) + */ + public ColumnType cellType() default ColumnType.STRING; + + /** + * 导出列头背景色 + */ + public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT; + + /** + * 导出列头字体颜色 + */ + public IndexedColors headerColor() default IndexedColors.WHITE; + + /** + * 导出单元格背景色 + */ + public IndexedColors backgroundColor() default IndexedColors.WHITE; + + /** + * 导出单元格字体颜色 + */ + public IndexedColors color() default IndexedColors.BLACK; + + /** + * 导出字段对齐方式 + */ + public HorizontalAlignment align() default HorizontalAlignment.CENTER; + + /** + * 自定义数据处理器 + */ + + + /** + * 自定义数据处理器参数 + */ + public String[] args() default {}; + + /** + * 字段类型(0:导出导入;1:仅导出;2:仅导入) + */ + Type type() default Type.ALL; + + public enum Type + { + ALL(0), EXPORT(1), IMPORT(2); + private final int value; + + Type(int value) + { + this.value = value; + } + + public int value() + { + return this.value; + } + } + + public enum ColumnType + { + NUMERIC(0), STRING(1), IMAGE(2); + private final int value; + + ColumnType(int value) + { + this.value = value; + } + + public int value() + { + return this.value; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/zzlh/es/annotation/Excels.java b/src/main/java/com/zzlh/es/annotation/Excels.java new file mode 100644 index 0000000..6ebf1e7 --- /dev/null +++ b/src/main/java/com/zzlh/es/annotation/Excels.java @@ -0,0 +1,18 @@ +package com.zzlh.es.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Excel注解集 + * + * @author hckj + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Excels +{ + Excel[] value(); +} \ No newline at end of file diff --git a/src/main/java/com/zzlh/es/config/CalPoint.java b/src/main/java/com/zzlh/es/config/CalPoint.java new file mode 100644 index 0000000..a82ab2e --- /dev/null +++ b/src/main/java/com/zzlh/es/config/CalPoint.java @@ -0,0 +1,50 @@ +package com.zzlh.es.config; + +public class CalPoint { + + public static Bounds calculateTileBounds(int tileX, int tileY, int zoomLevel) { + double tileRes = 360.0 / (1 << zoomLevel); + double minLat = (tileY * tileRes - 90); + double maxLat = ((tileY + 1) * tileRes - 90); + double minLon = (tileX * tileRes - 180); + double maxLon = ((tileX + 1) * tileRes - 180); + return new Bounds(minLon, minLat, maxLon, maxLat); + } + + // 表示经纬度范围的类 + public static class Bounds { + public double minLon; + public double minLat; + public double maxLon; + public double maxLat; + + public Bounds(double minLon, double minLat, double maxLon, double maxLat) { + this.minLon = minLon; + this.minLat = minLat; + this.maxLon = maxLon; + this.maxLat = maxLat; + } + + // 输出函数,方便打印查看 + @Override + public String toString() { + return "Bounds{" + + "minLon=" + minLon + + ", minLat=" + minLat + + ", maxLon=" + maxLon + + ", maxLat=" + maxLat + + '}'; + } + } + + // 使用示例 + public static void main(String[] args) { + int tileX = 13556; + int tileY = 6461; + int zoomLevel = 14; + Bounds bounds = calculateTileBounds(tileX, tileY, zoomLevel); + System.out.println(bounds); + System.out.println((tileX + 1) * (360 / (2^zoomLevel))); + } + +} diff --git a/src/main/java/com/zzlh/es/config/CrossConfig.java b/src/main/java/com/zzlh/es/config/CrossConfig.java new file mode 100644 index 0000000..5b8f644 --- /dev/null +++ b/src/main/java/com/zzlh/es/config/CrossConfig.java @@ -0,0 +1,32 @@ +package com.zzlh.es.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +@Component +@Configuration +public class CrossConfig { + @Bean + public CorsFilter corsFilter() { + // 1.添加CORS配置信息 + CorsConfiguration config = new CorsConfiguration(); + // 放行哪些原始域 + config.addAllowedOrigin("*"); + // 是否发送Cookie信息 + config.setAllowCredentials(true); + // 放行哪些原始域(请求方式) + config.addAllowedMethod("*"); + // 放行哪些原始域(头部信息) + config.addAllowedHeader("*"); + // 暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)springboot配置此项会报错,不允许设置* + // 2.添加映射路径 + UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(); + configSource.registerCorsConfiguration("/**", config); + // 3.返回新的CorsFilter. + return new CorsFilter(configSource); + } +} diff --git a/src/main/java/com/zzlh/es/config/FileMvcConfig.java b/src/main/java/com/zzlh/es/config/FileMvcConfig.java new file mode 100644 index 0000000..36ccd9c --- /dev/null +++ b/src/main/java/com/zzlh/es/config/FileMvcConfig.java @@ -0,0 +1,64 @@ +package com.zzlh.es.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * @Description TODO + * @Author haijun + * @Date 2019/12/30 13:57 + * @ClassName FileMvcConfig + ***/ +@Configuration +public class FileMvcConfig implements WebMvcConfigurer { + + /** + * 网络路径配置 + */ + @Value("${fileupload.config.staticAccessPath}") + private String staticAccessPath; + + /** + * 服务器储存路径(带盘符,liunx不用) + */ + @Value("${fileupload.config.uploadFolder}") + private String uploadFolder; + + /** + * 服务器储存子路径 + */ + @Value("${fileupload.config.localPath}") + private String localPath; + /** + * 用户头像 + **/ + @Value("${fileupload.config.uploadFolder}") + private String userHeaderPic; + /** + * 档案文件数据 + */ + @Value("${fileupload.config.archivesFilePath}") + private String archivesFilePath; +// +// @Autowired +// private IConfigService configService; + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + //配置server虚拟路径,handler为前台访问的目录,locations为files相对应的本地路径 + registry.addResourceHandler(staticAccessPath) + .addResourceLocations("file:"+getUploadFolder()+localPath); + } + + public String getUploadFolder(){ +// String uploadFolderdb = configService.getValueByKey("uploadFolder"); +// System.out.println("uploadFolderdb:"+uploadFolderdb); +// if(uploadFolderdb==null||uploadFolderdb.trim().length()==0){ +// return uploadFolder; +// } +// return uploadFolderdb; + return uploadFolder; + } +} \ No newline at end of file diff --git a/src/main/java/com/zzlh/es/config/JwtAuthenticationTokenFilter.java b/src/main/java/com/zzlh/es/config/JwtAuthenticationTokenFilter.java new file mode 100644 index 0000000..e523ff7 --- /dev/null +++ b/src/main/java/com/zzlh/es/config/JwtAuthenticationTokenFilter.java @@ -0,0 +1,103 @@ +package com.zzlh.es.config; + + +import com.alibaba.fastjson2.JSON; +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.properties.JwtProperties; +import com.zzlh.es.utils.JwtTokenUtil; +import com.zzlh.es.utils.RedisUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +import static com.zzlh.es.constant.HttpStatus.*; +import static com.zzlh.es.utils.RequestUtil.matchers; + + +/** + * @author soeasy + */ +@Component +@Slf4j +public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { + + @Autowired + private UserDetailsService userDetailsService; + @Autowired + private RedisUtil redisUtil; + @Autowired + private JwtTokenUtil jwtTokenUtil; + + @Autowired + private JwtProperties jwtProperties; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { + request.setCharacterEncoding("UTF-8"); + + if (matchers("/druid/**", request)){ + response.getWriter().write(JSON.toJSONString(AjaxResult.error(AUTH_FAILED, "身份认证失败"))); + return; + }else { + chain.doFilter(request, response); + } + /*String authorization = request.getHeader("Authorization"); + + if (matchers("/getVerifyCode", request) + || matchers("/auth/login", request) + ||matchers("/swagger-ui.html", request) + ||matchers("/swagger-resources/**", request) + ||matchers("/webjars/**", request) + ||matchers("/v2/**", request) + ||matchers("/swagger-ui.html/**", request) + ) { + chain.doFilter(request, response); + return; + }else { + response.setCharacterEncoding("UTF-8"); + if (StringUtils.isEmpty(authorization)) { + response.getWriter().write(JSON.toJSONString(AjaxResult.error(AUTH_FAILED, "身份认证失败"))); + return; + } + if(!authorization.startsWith(jwtProperties.getTokenHead())){ + response.getWriter().write(JSON.toJSONString(AjaxResult.error(TOKEN_CAST_ERROR, "身份认证失败"))); + return; + } + final String token = authorization.replace(jwtProperties.getTokenHead(), ""); + String username = jwtTokenUtil.getUsernameFromToken(token); + if(null == username){ + response.getWriter().write(JSON.toJSONString(AjaxResult.error(LOSE_TOKEN, "身份认证失败"))); + return; + } + SecurityContextHolder.getContext().getAuthentication(); + if(null == redisUtil.get(username+authorization)){ + log.info("token verify key:"+username+token); + response.getWriter().write(JSON.toJSONString(AjaxResult.error(LIMIT_TOKEN_ERROR, "身份认证失败"))); + return; + } + UserDetails userDetails = this.userDetailsService.loadUserByUsername(username); + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( + userDetails, null, userDetails.getAuthorities()); + authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authentication); + //重置 token 过期时间 + //redisUtil.expire(username+authorization, jwtProperties.getExpiration()); + } + chain.doFilter(request, response); + */ + } +} + diff --git a/src/main/java/com/zzlh/es/config/RedisConfig.java b/src/main/java/com/zzlh/es/config/RedisConfig.java new file mode 100644 index 0000000..ab4c0d1 --- /dev/null +++ b/src/main/java/com/zzlh/es/config/RedisConfig.java @@ -0,0 +1,49 @@ +package com.zzlh.es.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * redis配置 + * + * @author hckj + */ +@Configuration +@EnableCaching +@AutoConfigureBefore(RedisAutoConfiguration.class) +public class RedisConfig extends CachingConfigurerSupport +{ + + @SuppressWarnings(value = { "unchecked", "rawtypes" }) + @Bean(name = "myRedisTemplate") + public RedisTemplate redisTemplate(RedisConnectionFactory factory) { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(factory); + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); + RedisSerializer stringSerializer = new StringRedisSerializer(); + ObjectMapper om = new ObjectMapper(); + om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(om); + + template.setValueSerializer(stringSerializer); + template.setKeySerializer(stringSerializer); + + template.setHashKeySerializer(stringSerializer); + template.setHashValueSerializer(stringSerializer); + template.afterPropertiesSet(); + return template; + } +} diff --git a/src/main/java/com/zzlh/es/config/SwaggerConfig.java b/src/main/java/com/zzlh/es/config/SwaggerConfig.java new file mode 100644 index 0000000..18a8be9 --- /dev/null +++ b/src/main/java/com/zzlh/es/config/SwaggerConfig.java @@ -0,0 +1,42 @@ +package com.zzlh.es.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + + +/** + * @author soeasy + */ +@Configuration +@EnableSwagger2 +public class SwaggerConfig { + + @Bean + public Docket createRestApi() { + + + return new Docket(DocumentationType.SWAGGER_2) + .apiInfo(apiInfo()) + .select() + .apis(RequestHandlerSelectors.basePackage("com.zzlh.es.controller")) + .paths(PathSelectors.any()) + .build(); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title("接口文档") + .termsOfServiceUrl("http://localhost:8080/") + .version("1.0") + .build(); + + } + +} diff --git a/src/main/java/com/zzlh/es/config/TileToLatLongConverter2.java b/src/main/java/com/zzlh/es/config/TileToLatLongConverter2.java new file mode 100644 index 0000000..ecf7857 --- /dev/null +++ b/src/main/java/com/zzlh/es/config/TileToLatLongConverter2.java @@ -0,0 +1,150 @@ +package com.zzlh.es.config; + +public class TileToLatLongConverter2 { + // 瓦片的像素尺寸(常见的Web Mercator瓦片大小为256x256像素) + private static final int TILE_SIZE = 256; + + // 地球半径(单位:米) + private static final double EARTH_RADIUS = 6378137.0; + + // 初始偏移量(用于将经纬度转换为像素坐标) + private static final double INITIAL_RESOLUTION = TILE_SIZE * 0.5 / (Math.PI * EARTH_RADIUS); + + /** + * 将经纬度转换为像素坐标。 + * + * @param lat 纬度(范围:-90到90) + * @param lng 经度(范围:-180到180) + * @param zoom 缩放级别 + * @return 像素坐标(px, py) + */ + private static double[] latLngToPixel(double lat, double lng, int zoom) { + double sinLat = Math.sin(lat * Math.PI / 180); + + // 墨卡托投影的公式 + double pixelX = ((lng + 180) / 360) * TILE_SIZE * Math.pow(2, zoom); + double pixelY = (1 + Math.sin(lat * Math.PI / 180)) / 2 * TILE_SIZE * Math.pow(2, zoom); + + return new double[]{pixelX, pixelY}; + } + + /** + * 将像素坐标转换为经纬度。 + * + * @param px 像素X坐标 + * @param py 像素Y坐标 + * @param zoom 缩放级别 + * @return 经纬度(lat, lng) + */ + private static double[] pixelToLatLng(double px, double py, int zoom) { + double n = Math.PI - (2 * Math.PI * py) / (TILE_SIZE * Math.pow(2, zoom)); + + double lat = (Math.toDegrees(Math.atan(Math.sinh(n)))); + double lng = (px / (TILE_SIZE * Math.pow(2, zoom))) * 360 - 180; +// System.out.println(lat +" "+ lng); + return new double[]{lat, lng}; + } + + /** + * 计算瓦片边界的经纬度范围。 + * + * @param tileX 瓦片X坐标 + * @param tileY 瓦片Y坐标 + * @param zoom 缩放级别 + * @return 瓦片边界的经纬度范围(minLat, minLng, maxLat, maxLng) + */ + public static double[] calculateTileBounds(int tileX, int tileY, int zoom) { + // 计算瓦片左上角的经纬度 + double[] topLeftLatLng = pixelToLatLng(tileX * TILE_SIZE, tileY * TILE_SIZE, zoom); + double minLat = topLeftLatLng[0]; + double minLng = topLeftLatLng[1]; + System.out.println(minLat+":"+minLng); + // 计算瓦片右上角的经纬度 + double[] topRightLatLng = pixelToLatLng((tileX + 1) * TILE_SIZE, tileY * TILE_SIZE, zoom); + double maxLat = topRightLatLng[0]; + double maxLng = topRightLatLng[1]; + + // 计算瓦片左下角的经纬度 + double[] bottomLeftLatLng = pixelToLatLng(tileX * TILE_SIZE, (tileY + 1) * TILE_SIZE, zoom); + double bottomLat = bottomLeftLatLng[0]; + System.out.println(bottomLat+":"+bottomLeftLatLng[1]); + // 瓦片在纬度上不是等宽的,因此我们需要取左下角和左上角的纬度中的最小值作为minLat + minLat = Math.min(minLat, bottomLat); + + // 瓦片在经度上是等宽的,所以maxLng已经在计算右上角时得到 + + // 返回瓦片边界的经纬度范围 + return new double[]{minLat, minLng, maxLat, maxLng}; + } + + public static void main(String[] args) { + double[] a = {117.861328125,35.49645605658416,117.861328125,35.51434313431818}; + double b = 35.42486791930557; + double c = 117.59765625; + double d = 117.61962890625; + double[] doubles = latLngToPixel(35.40696093270201, 117.88330078125, 14); + double[] tileNumber2 = getTileNumber2(a, 14); + System.out.println(doubles[0]/256); + System.out.println(doubles[1]/512); + //System.out.println(doubles[0]); + //System.out.println(doubles[1]); + sout(13557, 6467, 14,calculateTileBounds(13557, 6467, 14)); +// sout(6737, 3098, 13,calculateTileBounds(6737, 3098, 13)); +// sout(53901, 24785, 16,calculateTileBounds(53901, 24785, 16)); +// sout(1724854, 793148, 21,calculateTileBounds(53901, 24785, 16)); + } + + private static void sout(int tileX, int tileY, int zoom, double[] bounds) { + System.out.println(tileX+" "+tileY+" "+zoom+" "+bounds[0]+" "+bounds[1]+" "+bounds[2]+" "+bounds[3]); + } + + + // 转回去 + public static String getTileNumber(final double lat, final double lon, final int zoom) { + int xtile = (int) Math.floor((lon + 180) / 360 * (1 << zoom)); + int ytile = (int) Math.floor((1 - Math.log(Math.tan(Math.toRadians(lat)) + 1 / Math.cos(Math.toRadians(lat))) / Math.PI) / 2 * (1 << zoom)); + if (xtile < 0) + xtile = 0; + if (xtile >= (1 << zoom)) + xtile = ((1 << zoom) - 1); + if (ytile < 0) + ytile = 0; + if (ytile >= (1 << zoom)) + ytile = ((1 << zoom) - 1); + return ("" + zoom + "/" + xtile + "/" + ytile); + } + public static double[] getTileNumber2(double[] rectPts, int level) { + + //瓦片的级别分辨率(1-18) + double[] resolution = {5.36441802978515E-06, + 1.07288360595703E-05, + 2.1457672119140625E-05, + 4.29153442382814E-05, + 8.58306884765629E-05, + 0.000171661376953125, + 0.00034332275390625, + 0.0006866455078125, + 0.001373291015625, + 0.00274658203125, + 0.0054931640625, + 0.010986328125, + 0.02197265625, + 0.0439453125, + 0.087890625, + 0.17578125, + 0.3515625, + 0.703125}; + + + double startX = Math.floor((rectPts[0] + 180.0) / (resolution[18 - level] * 256)); + double startY = Math.floor((90.0 - rectPts[1]) / (resolution[18 - level] * 256)); + double endX = Math.ceil((rectPts[2] + 180.0) / (resolution[18 - level] * 256)); + double endY = Math.ceil((90.0 - rectPts[3]) / (resolution[18 - level] * 256)); + //左上角瓦片坐标和左下角瓦片坐标 + double[] result = new double[]{startX, startY, endX, endY}; + return result; + + } +} + + diff --git a/src/main/java/com/zzlh/es/config/WebSecurityConfig.java b/src/main/java/com/zzlh/es/config/WebSecurityConfig.java new file mode 100644 index 0000000..acb3d78 --- /dev/null +++ b/src/main/java/com/zzlh/es/config/WebSecurityConfig.java @@ -0,0 +1,85 @@ +package com.zzlh.es.config; + + +import com.zzlh.es.entity.properties.JwtProperties; +import com.zzlh.es.security.auth.CustomAuthenticationEntryPoint; +import com.zzlh.es.security.auth.CustomUserDetailsService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + + +/** + * @author soeasy + */ +@Configuration +@EnableWebSecurity +@EnableConfigurationProperties(JwtProperties.class) +@Slf4j +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private CustomUserDetailsService customUserDetailsService; + + @Autowired + private CustomAuthenticationEntryPoint authenticationEntryPoint; + + + //JWT + @Autowired + private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + //将自定的CustomUserDetailsService装配到AuthenticationManagerBuilder + auth.userDetailsService(customUserDetailsService).passwordEncoder(new BCryptPasswordEncoder()); + } + @Override + public void configure(HttpSecurity http) throws Exception { + http.cors().and().csrf().disable();//开启跨域 + http.sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() + /*匿名请求:不需要进行登录拦截的url*/ + .authorizeRequests() + //.antMatchers("/getVerifyCode", "/auth/login","/swagger-ui.html","/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**").permitAll() + .anyRequest().anonymous()//其他的路径都是登录后才可访问 + .and() + .exceptionHandling() + .authenticationEntryPoint(authenticationEntryPoint); + + http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); + http.headers().cacheControl(); + } + + /** + * security检验忽略的请求,比如静态资源不需要登录的可在本处配置 + * @param web + */ + @Override + public void configure(WebSecurity web){ +// platform.ignoring().antMatchers("/login"); + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder()); + auth.eraseCredentials(false); + } + //密码加密配置 + @Bean + public BCryptPasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + +} diff --git a/src/main/java/com/zzlh/es/constant/Constants.java b/src/main/java/com/zzlh/es/constant/Constants.java new file mode 100644 index 0000000..c7fa964 --- /dev/null +++ b/src/main/java/com/zzlh/es/constant/Constants.java @@ -0,0 +1,137 @@ +package com.zzlh.es.constant; + +/** + * 通用常量信息 + * + * @author hckj + */ +public class Constants +{ + /** + * UTF-8 字符集 + */ + public static final String UTF8 = "UTF-8"; + + /** + * GBK 字符集 + */ + public static final String GBK = "GBK"; + + /** + * www主域 + */ + public static final String WWW = "www."; + + /** + * RMI 远程方法调用 + */ + public static final String LOOKUP_RMI = "rmi:"; + + /** + * LDAP 远程方法调用 + */ + public static final String LOOKUP_LDAP = "ldap:"; + + /** + * LDAPS 远程方法调用 + */ + public static final String LOOKUP_LDAPS = "ldaps:"; + + /** + * http请求 + */ + public static final String HTTP = "http://"; + + /** + * https请求 + */ + public static final String HTTPS = "https://"; + + /** + * 成功标记 + */ + public static final Integer SUCCESS = 200; + + /** + * 失败标记 + */ + public static final Integer FAIL = 500; + + /** + * 登录成功状态 + */ + public static final String LOGIN_SUCCESS_STATUS = "0"; + + /** + * 登录失败状态 + */ + public static final String LOGIN_FAIL_STATUS = "1"; + + /** + * 登录成功 + */ + public static final String LOGIN_SUCCESS = "Success"; + + /** + * 注销 + */ + public static final String LOGOUT = "Logout"; + + /** + * 注册 + */ + public static final String REGISTER = "Register"; + + /** + * 登录失败 + */ + public static final String LOGIN_FAIL = "Error"; + + /** + * 当前记录起始索引 + */ + public static final String PAGE_NUM = "pageNum"; + + /** + * 每页显示记录数 + */ + public static final String PAGE_SIZE = "pageSize"; + + /** + * 排序列 + */ + public static final String ORDER_BY_COLUMN = "orderByColumn"; + + /** + * 排序的方向 "desc" 或者 "asc". + */ + public static final String IS_ASC = "isAsc"; + + /** + * 验证码有效期(分钟) + */ + public static final long CAPTCHA_EXPIRATION = 2; + + /** + * 资源映射路径 前缀 + */ + public static final String RESOURCE_PREFIX = "/profile"; + + /** + * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) + */ + public static final String[] JOB_WHITELIST_STR = { "com.hckj" }; + + /** + * 定时任务违规的字符 + */ + public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", + "org.springframework", "org.apache", "com.hckj.common.core.utils.file" }; + + /** + * 封禁 + */ + public static final String BAN = "1"; + + +} diff --git a/src/main/java/com/zzlh/es/constant/HttpStatus.java b/src/main/java/com/zzlh/es/constant/HttpStatus.java new file mode 100644 index 0000000..ee76bca --- /dev/null +++ b/src/main/java/com/zzlh/es/constant/HttpStatus.java @@ -0,0 +1,192 @@ +package com.zzlh.es.constant; + +/** + * 返回状态码 + * + * @author hckj + */ +public class HttpStatus +{ + /** + * 操作成功 + */ + public static final int SUCCESS = 200; + + /** + * 系统内部错误 + */ + public static final int ERROR = 500; + + + /** + * 系统警告消息 + */ + public static final int WARN = 601; + + /** + * 未提供token + */ + public static final int AUTH_FAILED= 10000001; + /** + * token格式不正确 + */ + public static final int TOKEN_CAST_ERROR= 10000002; + /** + *无效的Token + */ + public static final int LOSE_TOKEN= 10000003; + /** + *Token已过期 + */ + public static final int LIMIT_TOKEN_ERROR= 10000004; + /** + *当前用户被禁止 + */ + public static final int USER_BAN= 10000005; + /** + *账号密码不为空 + */ + public static final int USERNAME_PASSWORD_NOT_NULL= 10000006; + /** + *登录失败 + */ + public static final int LOGIN_FAILED= 10000007; + + /** + *图层发布失败 + */ + public static final int PASSWORD_ERROR= 10000012; + + /** + *验证码生成失败 + */ + public static final int IMAGE_FAILED= 10000008; + + /** + *输入正确的二维码 + */ + public static final int IMAGE_ERROR= 10000009; + + /** + *退出失败 + */ + public static final int LOGOUT_ERROR= 10000010; + + /** + *图层发布失败 + */ + public static final int PUBLISH_ERROR= 10000011; + + + + /** + * 应用相关code + */ + + + /** + * 图层发布失败 + */ + public static final int APPLICATION_EXIST= 20000001; + + /** + * 服务不存在 + */ + public static final int SERVER_NOT_EXIST= 20000002; + + + /** + * 图层服务名称不能为空 + */ + public static final int SERVER_NAME_NULL= 20000003; + + + + /** + *应用名称不能为空 + */ + public static final int APPLICATION_NAME_NULL= 20000004; + + /** + *坐标系不能为空 + */ + public static final int SPACE_TYPE_NULL= 20000005; + + /** + *地图框架不能为空 + */ + public static final int MAP_FRAME_NULL= 20000006; + + /** + *底图信息不能为空 + */ + public static final int UNDERLAY_NULL= 20000007; + + + + /** + *项目组名称不能为空 + */ + public static final int PROJECT_NAME_NULL= 20000008; + + /** + *应用id不能为空 + */ + public static final int APPLICATION_ID_NULL= 20000009; + + /** + *请选中对应项目组或图层再删除(id空了) + */ + public static final int ID_NULL= 20000010; + + /** + * 服务id不能为空 + */ + public static final int SERVER_ID_NULL= 20000011; + + + /** + *项目组不存在 + */ + public static final int PROJECT_NULL= 20000012; + + /** + *请选中对应图标 + */ + public static final int ID_NULL_STYLE= 20000013; + + + /** + *文件不能为空 + */ + public static final int FILE_NULL= 20000014; + + /** + *重复上传 + */ + public static final int REPEAT_UPLOAD= 20000015; + + /** + *选中不存在 + */ + public static final int SELECTED_NOT_EXIST= 20000016; + + + /** + *当前选中图标存在已经绑定图层服务 + */ + public static final int IMAGE_USED= 20000017; + + /** + *当前选中图标存在已经绑定图层服务 + */ + public static final int UPLOAD_ERROR= 20000017; + + /** + *重复添加 + */ + public static final int REPEAT_ADD= 20000015; + + + +} diff --git a/src/main/java/com/zzlh/es/controller/ApplicationController.java b/src/main/java/com/zzlh/es/controller/ApplicationController.java new file mode 100644 index 0000000..65f9a03 --- /dev/null +++ b/src/main/java/com/zzlh/es/controller/ApplicationController.java @@ -0,0 +1,163 @@ +package com.zzlh.es.controller; + + +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.ApplicationData; +import com.zzlh.es.entity.DataStore; +import com.zzlh.es.entity.ProjectDataRelation; +import com.zzlh.es.service.IApplicationDataService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +import static com.zzlh.es.constant.HttpStatus.*; + +/** + * @author soeasy + */ +@RestController +@RequestMapping("/application") +@Api(value = "/application", tags = "应用创建管理", description = "提供应用创建的管理") +public class ApplicationController extends BaseController { + @Autowired + private IApplicationDataService iApplicationDataService; + + /** + * 获取应用列表 + * + * @return + */ + + @GetMapping("/getAllApplication") + @ApiOperation(value = "/getAllApplication", notes = "获取应用列表") + public AjaxResult getApplicationInfo(@RequestParam(defaultValue = "1") Integer pageNum, + @RequestParam(defaultValue = "10") Integer pageSize) { + PageHelper.startPage(pageNum, pageSize); + List list = iApplicationDataService.getAllApplication(); + if (list == null) { + return AjaxResult.error(); + } + PageInfo pageInfo = new PageInfo<>(list); + PageHelper.clearPage(); + return AjaxResult.success(pageInfo); + } + + /** + * 根据应用id获取项目组和服务的信息 + * + * @param id + * @return + */ + @GetMapping("/getApplicationInfo/{id}") + @ApiOperation(value = "/getApplicationInfo/{id}", notes = "根据id获取树结构") + public AjaxResult getApplicationInfo(@PathVariable Integer id) { + return iApplicationDataService.getApplicationById(id); + } + + /** + * 根据应用id获取所有项目组名称 + * + * @param id + * @return + */ + @GetMapping("/getProjectName/{id}") + @ApiOperation(value = "/getProjectName/{id}", notes = "根据应用id获取所有项目组名称") + public AjaxResult getProjectName(@PathVariable Integer id) { + return iApplicationDataService.getProjectName(id); + } + + /** + * 创建应用 + * + * @param applicationData + * @return + */ + @PostMapping("/createApplication") + @ApiOperation(value = "/createApplication", notes = "创建应用") + public AjaxResult createApplication(@RequestBody ApplicationData applicationData) { + if (StringUtils.isEmpty(applicationData.getApplicationName())) { + return AjaxResult.error(APPLICATION_NAME_NULL, "应用名称不能为空"); + } else if (StringUtils.isEmpty(applicationData.getSpaceType())) { + return AjaxResult.error(SPACE_TYPE_NULL, "坐标系不能为空"); + } else if (StringUtils.isEmpty(applicationData.getMapFrame())) { + return AjaxResult.error(MAP_FRAME_NULL, "地图框架不能为空"); + } else if (StringUtils.isEmpty(applicationData.getUnderlay())) { + return AjaxResult.error(UNDERLAY_NULL, "底图信息不能为空"); + } + return iApplicationDataService.createApplication(applicationData); + } + + /** + * 创建项目组 + * + * @param projectDataRelation + * @return + */ + @PostMapping("/createProject") + @ApiOperation(value = "/createProject", notes = "创建项目组") + public AjaxResult createProject(@RequestBody ProjectDataRelation projectDataRelation) { + if (StringUtils.isEmpty(projectDataRelation.getProjectTeamName())) { + return AjaxResult.error(PROJECT_NAME_NULL, "项目组名称不能为空"); + } + return iApplicationDataService.createProject(projectDataRelation); + } + + /** + * 在对应的项目组下添加图层服务 + * + * @param projectDataRelation + * @return + */ + @PutMapping("/addServer") + @ApiOperation(value = "/addServer", notes = "项目组添加图层服务") + public AjaxResult addServer(@RequestBody ProjectDataRelation projectDataRelation) { + return iApplicationDataService.addServer(projectDataRelation); + } + + + /** + * 根据坐标系查找对应的图层服务 + * + * @param spaceType + * @return + */ + @GetMapping("/getServerByType") + @ApiOperation(value = "/getServerByType", notes = "根据坐标系查找对应的图层服务") + public AjaxResult getServerByType(@RequestParam(defaultValue = "1") Integer pageNum, + @RequestParam(defaultValue = "10") Integer pageSize, String spaceType) { + if (StringUtils.isEmpty(spaceType)) { + return AjaxResult.error(SPACE_TYPE_NULL, "坐标系类型不能为空"); + } + PageHelper.startPage(pageNum, pageSize); + List list = iApplicationDataService.getServerByType(spaceType); + if (list == null) { + return AjaxResult.error(); + } + PageInfo pageInfo = new PageInfo<>(list); + PageHelper.clearPage(); + return AjaxResult.success(pageInfo); + } + + /** + * 删除项目组 + * + * @param ids + * @return + */ + @DeleteMapping("/deleteIds/{ids}") + @ApiOperation(value = "/deleteIds/{ids}", notes = "根据id删除项目组或图层") + public AjaxResult deleteIds(@PathVariable int[] ids) { + if (ids.length < 1) { + return AjaxResult.error(ID_NULL, "请选中对应项目组或图层再删除"); + } + return iApplicationDataService.deleteIds(ids); + } + + +} diff --git a/src/main/java/com/zzlh/es/controller/ApplicationMarsController.java b/src/main/java/com/zzlh/es/controller/ApplicationMarsController.java new file mode 100644 index 0000000..f2e95a5 --- /dev/null +++ b/src/main/java/com/zzlh/es/controller/ApplicationMarsController.java @@ -0,0 +1,139 @@ +package com.zzlh.es.controller; + +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.ProjectDataRelationMars; +import com.zzlh.es.service.IProjectDataRelationMarsService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import static com.zzlh.es.constant.HttpStatus.ID_NULL; +import static com.zzlh.es.constant.HttpStatus.PROJECT_NAME_NULL; + +/** + * @author soeasy + */ +@RestController +@RequestMapping("/applicationMars") +@Api(value = "/applicationMars", tags = "火星应用创建管理", description = "提供火星应用创建管理api") +public class ApplicationMarsController { + + @Autowired + private IProjectDataRelationMarsService iProjectDataRelationMarsService; + + + + /** + * 创建项目组(火星) + * + * @param projectDataRelationMars + * @return + */ + @PostMapping("/createMars") + @ApiOperation(value = "/createMars", notes = "创建项目组") + public AjaxResult createMars(@RequestBody ProjectDataRelationMars projectDataRelationMars) { + if (StringUtils.isEmpty(projectDataRelationMars.getProjectTeamName())) { + return AjaxResult.error(PROJECT_NAME_NULL, "项目组名称不能为空"); + } + return iProjectDataRelationMarsService.createMars(projectDataRelationMars); + } + + /** + * 项目组添加图层服务 + * + * @param projectDataRelationMars + * @return + */ + @PostMapping("/addMarsServer") + @ApiOperation(value = "/addMarsServer", notes = "项目组添加图层服务") + public AjaxResult addMarsServer(@RequestBody ProjectDataRelationMars projectDataRelationMars) { + return iProjectDataRelationMarsService.addMarsServer(projectDataRelationMars); + } + + + /** + * 获取树结构 + * + * @return + */ + @GetMapping("/getApplicationInfo/{areaName}") + @ApiOperation(value = "/getApplicationInfo", notes = "获取树结构") + public AjaxResult getApplicationInfo(@PathVariable("areaName")String areaName) { + return iProjectDataRelationMarsService.getTree(areaName); + } + + @GetMapping("/getApplicationInfoApp/{areaName}") + @ApiOperation(value = "/getApplicationInfo", notes = "获取树结构") + public AjaxResult getApplicationInfoApp(@PathVariable("areaName")String areaName) { + return iProjectDataRelationMarsService.getApplicationTree(areaName); + } + + /** + * 根据id删除项目组或图层 + * + * @param ids + * @return + */ + @DeleteMapping("/deleteIds/{ids}") + @ApiOperation(value = "/deleteIds/{ids}", notes = "根据id删除项目组或图层") + public AjaxResult deleteIds(@PathVariable int[] ids) { + if (ids.length < 1) { + return AjaxResult.error(ID_NULL, "请选中对应项目组或图层再删除"); + } + return iProjectDataRelationMarsService.deleteIds(ids); + } + + + /** + * 获取所有项目组名称 + * + * @return + */ + @GetMapping("/getProjectName/{areaName}") + @ApiOperation(value = "/getProjectName", notes = "获取所有项目组名称") + public AjaxResult getProjectName(@PathVariable("areaName")String areaName) { + return iProjectDataRelationMarsService.getProjectName(areaName); + } + + + + /** + * 根据id获取样式信息 + * + * @param id + * @return + */ + @GetMapping("/getStyle") + @ApiOperation(value = "/getStyle", notes = "根据id获取样式信息") + public AjaxResult getStyle(Long id) { + return iProjectDataRelationMarsService.findStyleById(id); + } + + /** + * 根据服务id查询列名 + * + * @param id + * @return + */ + @GetMapping("/getTableName") + @ApiOperation(value = "/getTableName", notes = "根据服务id查询列名") + public AjaxResult getTableName(Long id) { + return iProjectDataRelationMarsService.getTableName(id); + } + + /** + * + * @param id + * @param style json样式 + * @param type 1是修改父样式 2是修改子样式 + * @param updateName 修改的名称 + * @return + */ + @PutMapping("/update") + @ApiOperation(value = "/update", notes = "根据id更新样式") + public AjaxResult updateStyle(Long id, String style,String type,String updateName,String properties,Integer sort) { + return iProjectDataRelationMarsService.updateStyle(id,style,type,updateName,properties,sort); + } +} diff --git a/src/main/java/com/zzlh/es/controller/BaseController.java b/src/main/java/com/zzlh/es/controller/BaseController.java new file mode 100644 index 0000000..da85a44 --- /dev/null +++ b/src/main/java/com/zzlh/es/controller/BaseController.java @@ -0,0 +1,129 @@ +package com.zzlh.es.controller; + +import com.github.pagehelper.PageInfo; + +import com.zzlh.es.constant.HttpStatus; +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.page.TableDataInfo; +import com.zzlh.es.utils.DateUtils; +import com.zzlh.es.utils.PageUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; + +import java.beans.PropertyEditorSupport; +import java.util.Date; +import java.util.List; + +/** + * web层通用数据处理 + * + * @author hckj + */ +public class BaseController { + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * 将前台传递过来的日期格式的字符串,自动转化为Date类型 + */ + @InitBinder + public void initBinder(WebDataBinder binder) { + // Date 类型转换 + binder.registerCustomEditor(Date.class, new PropertyEditorSupport() { + @Override + public void setAsText(String text) { + setValue(DateUtils.parseDate(text)); + } + }); + } + + /** + * 设置请求分页数据 + */ + protected void startPage() { + PageUtils.startPage(); + } + + /** + * 清理分页的线程变量 + */ + protected void clearPage() { + PageUtils.clearPage(); + } + + /** + * 响应请求分页数据 + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + protected TableDataInfo getDataTable(List list) { + TableDataInfo rspData = new TableDataInfo(); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setRows(list); + rspData.setMsg("查询成功"); + rspData.setTotal(new PageInfo(list).getTotal()); + return rspData; + } + + /** + * 返回成功 + */ + public AjaxResult success() { + return AjaxResult.success(); + } + + /** + * 返回成功消息 + */ + public AjaxResult success(String message) { + return AjaxResult.success(message); + } + + /** + * 返回成功消息 + */ + public AjaxResult success(Object data) { + return AjaxResult.success(data); + } + + /** + * 返回失败消息 + */ + public AjaxResult error() { + return AjaxResult.error(); + } + + /** + * 返回失败消息 + */ + public AjaxResult error(String message) { + return AjaxResult.error(message); + } + + /** + * 返回警告消息 + */ + public AjaxResult warn(String message) { + return AjaxResult.warn(message); + } + + /** + * 响应返回结果 + * + * @param rows 影响行数 + * @return 操作结果 + */ + protected AjaxResult toAjax(int rows) { + return rows > 0 ? AjaxResult.success() : AjaxResult.error(); + } + + /** + * 响应返回结果 + * + * @param result 结果 + * @return 操作结果 + */ + protected AjaxResult toAjax(boolean result) { + return result ? success() : error(); + } +} diff --git a/src/main/java/com/zzlh/es/controller/DataStoreController.java b/src/main/java/com/zzlh/es/controller/DataStoreController.java new file mode 100644 index 0000000..f120860 --- /dev/null +++ b/src/main/java/com/zzlh/es/controller/DataStoreController.java @@ -0,0 +1,103 @@ +package com.zzlh.es.controller; + + +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.DataStore; +import com.zzlh.es.entity.vo.TableDataVo; +import com.zzlh.es.page.TableDataInfo; +import com.zzlh.es.service.IDataStoreService; +import io.swagger.annotations.Api; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; +import java.util.Map; + +/** + * 图层存储表Controller + * + * @author LGD + * @date 2023-03-27 + */ +@RestController +@RequestMapping("/store") +@Api(tags = "文件数据相关接口") +public class DataStoreController extends BaseController { + @Autowired + private IDataStoreService dataStoreService; + + /** + * 查询图层存储表列表 + */ + + @GetMapping("/list") + public TableDataInfo list(DataStore dataStore) { + startPage(); + List list = dataStoreService.selectDataStoreList(dataStore); + return getDataTable(list); + } + + /** + * 导出图层存储表列表 + */ + + @PostMapping("/export") + public void export(HttpServletResponse response, DataStore dataStore) { + List list = dataStoreService.selectDataStoreList(dataStore); +// ExcelUtil util = new ExcelUtil(DataStore.class); +// util.exportExcel(response, list, "图层存储表数据"); + } + + /** + * 获取图层存储表详细信息 + */ + + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) { + return success(dataStoreService.selectDataStoreById(id)); + } + + /** + * 新增图层存储表 + */ + + + @PostMapping + public AjaxResult add(@RequestBody DataStore dataStore) { + return toAjax(dataStoreService.insertDataStore(dataStore)); + } + + /** + * 修改图层存储表 + */ + + @PutMapping + public AjaxResult edit(@RequestBody DataStore dataStore) { + return toAjax(dataStoreService.updateDataStore(dataStore)); + } + + /** + * 删除图层存储表 + */ + + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) { + return toAjax(dataStoreService.deleteDataStoreByIds(ids)); + } + + + @GetMapping("/delete/{id}") + public AjaxResult delete(@PathVariable("id") Integer id) throws Exception{ + return toAjax(dataStoreService.deleteDataStoreById(id)); + } + + @GetMapping("/listData") + public TableDataInfo listData(TableDataVo tableDataVo) { + System.out.println(tableDataVo.toString()); + startPage(); + List list = dataStoreService.selectDataStoreListByTableName(tableDataVo.getTableName()); + return getDataTable(list); + } + +} diff --git a/src/main/java/com/zzlh/es/controller/GeoServerController.java b/src/main/java/com/zzlh/es/controller/GeoServerController.java new file mode 100644 index 0000000..094a932 --- /dev/null +++ b/src/main/java/com/zzlh/es/controller/GeoServerController.java @@ -0,0 +1,257 @@ +package com.zzlh.es.controller; + + +import com.alibaba.fastjson2.JSONObject; +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.vo.PartFileVo; +import com.zzlh.es.entity.vo.StyleDataVo; +import com.zzlh.es.exception.BusinessException; +import com.zzlh.es.service.GeoServer; +import com.zzlh.es.service.LayerService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/geoserver") +@Api(tags = "geoserver相关接口") +public class GeoServerController { + + @Autowired + private GeoServer geoServer; + + @Autowired + private LayerService layerService; + + @PostMapping("/uploadFile") + public AjaxResult uploadShpFile(PartFileVo data) throws Exception { + System.out.println(data.getSpaceType()); + System.out.println(data.toString()); + Map map = layerService.fileTransfer(data.getFile(), data.getSpaceType(), data.getTableName()); + map.put("styleName", data.getStyleName()); + return AjaxResult.success(map); + } + + @PostMapping("/uploadFileAdd") + public AjaxResult uploadShpFileAdd(PartFileVo data) throws Exception { + Map map = layerService.fileTransferAdd(data.getFile(), data.getTableName()); + return AjaxResult.success(); + } + + @PostMapping("/saveData") + public AjaxResult saveData(@RequestBody Map map) throws Exception { + System.out.println(map.toString()); + Map result = layerService.insertIntoData(map); + return AjaxResult.success(result); + } + + @GetMapping("/cancelSave/{tableValue}") + public AjaxResult canCelSave(@PathVariable("tableValue") String tableValue) { + Map result = layerService.cancelSave(tableValue); + return AjaxResult.success(result); + } + + @GetMapping("/checkServerName/{serverName}") + public AjaxResult checkServerName(@PathVariable("serverName") String tableValue) { + Integer result = layerService.checkServerName(tableValue); + return AjaxResult.success(result); + } + + @GetMapping("/checkTableName/{tableName}") + public AjaxResult checkTableName(@PathVariable("tableName") String tableName) { + Integer result = layerService.checkTableName(tableName); + return AjaxResult.success(result); + } + + @GetMapping("/getDict/{dictType}") + public AjaxResult getDictData(@PathVariable("dictType") String dictType) { + List dictList = layerService.getDictList(dictType); + return AjaxResult.success(dictList); + } + + + @GetMapping("/publishLayer/{tableValue}") + public AjaxResult publishLayer(@PathVariable("tableValue") String tableValue) { + layerService.addLayer(tableValue); + return AjaxResult.success(); + } + + @PostMapping("/publishLayer") + public AjaxResult publishLayer(@RequestBody Map param) { + layerService.publishLayer(param); + return AjaxResult.success(); + } + + @PostMapping("/getLayer") + public AjaxResult getLayer(@RequestBody Map map) throws Exception { + Map layer = layerService.getLayer(map.get("tableName").toString(), map.get("spaceType").toString()); + return AjaxResult.success(layer); + } + + @GetMapping("/getLayerStyle") + public AjaxResult getLayerStyle() { + Map layer = layerService.getLayerStyle(); + return AjaxResult.success(layer); + } + + + @GetMapping("/getLayerStyleAndType") + public AjaxResult getLayerStyles() { + Map layer = layerService.getLayerStyles(); + return AjaxResult.success(layer); + } + + @PostMapping("/saveLayerStyle") + public AjaxResult saveLayerStyle(@RequestBody StyleDataVo styleDataVo) throws Exception { + System.out.println(styleDataVo.toString()); + Map map = layerService.saveLayerStyle(styleDataVo); + return AjaxResult.success(map); + } + + @PostMapping("/updateLayerStyle") + public AjaxResult updateLayerStyle(@RequestBody StyleDataVo styleDataVo) throws Exception { + Map map = layerService.updateLayerStyle(styleDataVo); + return AjaxResult.success(map); + } + + @GetMapping("/deleteLayerStyle/{styleName}") + public AjaxResult deleteLayerStyle(@PathVariable("styleName") String styleName) { + Map layer = layerService.deleteLayerStyle(styleName); + return AjaxResult.success(layer); + } + + @PostMapping("/getLayerData") + public AjaxResult getLayerStyle(@RequestBody Map map) { + Map layer = layerService.getLayerDataList(map); + return AjaxResult.success(layer); + } + + @PostMapping("/transWkb") + public AjaxResult wkbToWkt(@RequestBody Map map) throws Exception { + String layer = layerService.wkbToWkt(map.get("geom").toString()); + return AjaxResult.success(layer); + } + + @PostMapping("/getSingleDate") + public AjaxResult getSingleDate(@RequestBody Map map) throws Exception { + Map map1 = layerService.getSingleData(map); + return AjaxResult.success(map1); + } + + @PostMapping("/updateLayerData") + public AjaxResult updateLayerData(@RequestBody Map map) { + layerService.updateShpData(map); + return AjaxResult.success(); + } + + @PostMapping("/insertLayerData") + public AjaxResult insertLayerData(@RequestBody Map map) { + layerService.insertShpData(map); + return AjaxResult.success(); + } + + @PostMapping("/deleteData") + public AjaxResult deleteLayerData(@RequestBody Map map) { + layerService.deleteShpData(map); + return AjaxResult.success(); + } + + + @PostMapping("/uploadExcelFile") + public AjaxResult uploadFile(PartFileVo fileVo) throws Exception { + if (!fileVo.getFile().isEmpty()) { + Map tableName = layerService.uploadExcelFile(fileVo); + return AjaxResult.success(tableName); + } + return AjaxResult.error("上传文件失败,请联系管理员"); + } + + @GetMapping("/getGeomData/{tableValue}") + public AjaxResult getGeomData(@PathVariable("tableValue") String tableValue) { + String geomData = layerService.getGeomData(tableValue); + return AjaxResult.success(geomData); + } + + + @GetMapping("/downloadColumn/{tableName}") + public void downloadColumn(@PathVariable("tableName") String tableName, HttpServletResponse response) { + layerService.downloadModel(tableName, response); + } + + @GetMapping("/downloadRelation/{tableName}") + public AjaxResult downloadRelation(@PathVariable("tableName") String tableName, HttpServletResponse response) { + Boolean aBoolean = layerService.downloadRelation(tableName, response); + if (aBoolean) { + return AjaxResult.success(); + } else { + return AjaxResult.error("数据有误!"); + } + } + + + @PostMapping("/uploadModelData") + public AjaxResult uploadModelData(MultipartFile file) throws Exception { + Map tableName = layerService.uploadModelData(file); + return AjaxResult.success(tableName); + } + + @PostMapping("/createDataStore") + public AjaxResult createDataStore(@RequestBody Map map) throws Exception { + Map result = layerService.insertIntoDataStore(map); + String tableName = result.get("tableName").toString(); + layerService.addLayer(tableName); + + return AjaxResult.success(result); + } + + + @GetMapping("/getShpRelation/{tableName}") + public AjaxResult createDataStore(@PathVariable("tableName") String tableName) throws Exception { + String result = layerService.getShpRelation(tableName); + return AjaxResult.success(result); + } + + + @PostMapping("/getColumnByName") + public AjaxResult getColumnByName(@RequestBody Map map) throws Exception { + List result = layerService.getColumnByName(map); + return AjaxResult.success(result); + } + + @GetMapping("/downLoadShpZip/{tableName}") + public AjaxResult downLoadShpZip(@PathVariable("tableName") String tableName) throws Exception { + String result = layerService.downLoadShpZipFile(tableName); + return AjaxResult.success(result); + } + + @GetMapping("/downLoadDataShpZip/{tableName}") + public AjaxResult downLoadDataShpZip(@PathVariable("tableName") String tableName) throws Exception { + layerService.downLoadShpZipFile(tableName); + return AjaxResult.success(); + } + + @GetMapping("/publishLayerLocal/{tableValue}") + public AjaxResult publishLayerLocal(@PathVariable("tableValue") String tableValue) { + layerService.addLayerLocal(tableValue); + return AjaxResult.success(); + } + + @PostMapping("/uploadStyle") + public AjaxResult uploadStyle(PartFileVo data) throws Exception { + + Boolean aBoolean = layerService.publishStyle(data); + if (aBoolean) { + return AjaxResult.success(); + } else { + return AjaxResult.error("发布样式失败"); + } + + } +} diff --git a/src/main/java/com/zzlh/es/controller/LoginController.java b/src/main/java/com/zzlh/es/controller/LoginController.java new file mode 100644 index 0000000..908176a --- /dev/null +++ b/src/main/java/com/zzlh/es/controller/LoginController.java @@ -0,0 +1,106 @@ +package com.zzlh.es.controller; + + +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.TUser; +import com.zzlh.es.service.LoginService; +import com.zzlh.es.service.TUserService; +import com.zzlh.es.exception.BusinessException; +import com.zzlh.es.utils.RedisUtil; +import com.zzlh.es.utils.VerifyCodeUtil; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.awt.image.RenderedImage; +import java.io.IOException; +import java.util.Map; + +import static com.zzlh.es.constant.Constants.BAN; +import static com.zzlh.es.constant.HttpStatus.*; + + +/** + * @author soeasy + */ +@RestController +@Api(tags = "登录相关接口") +public class LoginController { + @Autowired + private LoginService loginService; + + @Autowired + private RedisUtil redisUtil; + + @Autowired + private TUserService tUserService; + + @PostMapping("/getVerifyCode") + @ApiOperation(value = "/getVerifyCode", notes = "获取二维码") + public void getVerifyCode(HttpServletResponse response, String username, String password) { + if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) { + throw new BusinessException(USERNAME_PASSWORD_NOT_NULL, "请先输入正确的账号和密码"); + } + TUser user = tUserService.findByName(username); + if (user == null || user.getState().equals("1")) { + throw new BusinessException(USER_BAN, "用户不存在或被封禁"); + } + Map map = VerifyCodeUtil.getVerifyCode(); + // 禁止图像缓存。 + response.setHeader("Pragma", "no-cache"); + response.setHeader("Cache-Control", "no-cache"); + response.setDateHeader("Expires", 0); + response.setContentType("image/jpeg"); + // 将图像输出到Servlet输出流中。 + if (!redisUtil.set(username + VerifyCodeUtil.SESSION_KEY, map.get(VerifyCodeUtil.SESSION_KEY), 60000)) { + throw new BusinessException(IMAGE_FAILED, "图片验证码生成失败请刷新重试"); + } + try { + ServletOutputStream sos = response.getOutputStream(); + ImageIO.write((RenderedImage) map.get(VerifyCodeUtil.BUFFIMG_KEY), "jpeg", sos); + sos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @PostMapping("/auth/login") + @ApiOperation(value = "/auth/login", notes = "登录") + public AjaxResult getToken(String username, String password, String verifyCode) { + if (!StringUtils.isEmpty(username) || !StringUtils.isEmpty(password)) { + TUser user = tUserService.findByName(username); + if (user == null || user.getState().equals(BAN)) { + return AjaxResult.error(USER_BAN, "用户被封禁"); + } else { +// if (StringUtils.isEmpty(verifyCode)) { +// return AjaxResult.error(IMAGE_ERROR, "请输入正确的图片验证信息"); +// } else { +// if (!verifyCode.equals(redisUtil.get(username + VerifyCodeUtil.SESSION_KEY))) { +// return AjaxResult.error(IMAGE_ERROR, "图片验证码不正确或已经过期"); +// } + String token = loginService.login(username, password); + //if (token != null && redisUtil.del(username + VerifyCodeUtil.SESSION_KEY)) { + return AjaxResult.success(token); + //} + // return AjaxResult.error(LOGIN_FAILED, "登录失败"); + // } + } + } + return AjaxResult.error(USERNAME_PASSWORD_NOT_NULL, "请先输入正确的账号和密码"); + } + + @PostMapping("/auth/logout") + @ApiOperation(value = "/auth/logout", notes = "登出") + public AjaxResult getToken(HttpServletRequest request) { + + String authorization = request.getHeader("Authorization"); + return loginService.logout(authorization); + } +} diff --git a/src/main/java/com/zzlh/es/controller/StyleManagerController.java b/src/main/java/com/zzlh/es/controller/StyleManagerController.java new file mode 100644 index 0000000..706f5db --- /dev/null +++ b/src/main/java/com/zzlh/es/controller/StyleManagerController.java @@ -0,0 +1,110 @@ +package com.zzlh.es.controller; + + +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.StyleServerMapbox; +import com.zzlh.es.service.IStyleImageService; +import com.zzlh.es.service.IStyleServerMapboxService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +import static com.zzlh.es.constant.HttpStatus.ID_NULL_STYLE; + +/** + * @author soeasy + */ +@RestController +@RequestMapping("/style") +@Api(value = "/style", tags = "样式管理", description = "提供样式管理的api") +public class StyleManagerController extends BaseController { + + @Autowired + private IStyleImageService iStyleImageService; + + @Autowired + private IStyleServerMapboxService iStyleServerMapboxService; + + /** + * 根据serverName修改样式内容 + * + * @param styleServerMapbox + * @return + */ + + @PutMapping("/update") + @ApiOperation(value = "/update", notes = "更新样式") + public AjaxResult updateStyle(@RequestBody StyleServerMapbox styleServerMapbox) { + return iStyleServerMapboxService.updateStyle(styleServerMapbox); + } + + /** + * 获取样式信息 + * + * @param serverName + * @return + */ + @GetMapping("/getInfo") + @ApiOperation(value = "/getInfo", notes = "根据serverName获取样式") + public AjaxResult getInfo(String serverName) { + return iStyleServerMapboxService.findStyleById(serverName); + } + + + /** + * 根据severName获取拼接url + * + * @param serverName + * @return + */ + @GetMapping("/getUrlByServerName") + @ApiOperation(value = "/getUrlByServerName", notes = "根据serverName获取url") + public AjaxResult getUrlByServerName(String serverName) { + return iStyleServerMapboxService.getUrlByServerName(serverName); + } + + + /** + * 上传图标文件 + * + * @param request + * @return + */ + @PostMapping("/uploadStyleImage") + @ApiOperation(value = "/uploadStyleImage", notes = "上传图标文件") + public AjaxResult uploadStyleImage(HttpServletRequest request) throws IOException { + return iStyleImageService.uploadStyleImage(request); + } + + + /** + * 获取资料库所有的图标url + * + * @return + */ + @GetMapping("/getAllStyleImage") + @ApiOperation(value = "/getAllStyleImage", notes = "获取资料库所有的图标url") + public AjaxResult getAllStyleImage() { + return iStyleImageService.getAllStyleImage(); + } + + + /** + * 删除选中图标 + * + * @return + */ + @DeleteMapping("/deleteIds/{ids}") + @ApiOperation(value = "/deleteIds/{ids}", notes = "请选中图标或图标已删除") + public AjaxResult deleteIds(@PathVariable int[] ids) { + if (ids.length < 1) { + return AjaxResult.error(ID_NULL_STYLE, "请选中图标或图标已删除"); + } + return iStyleImageService.deleteIds(ids); + } + +} diff --git a/src/main/java/com/zzlh/es/controller/Test.java b/src/main/java/com/zzlh/es/controller/Test.java new file mode 100644 index 0000000..3a52a01 --- /dev/null +++ b/src/main/java/com/zzlh/es/controller/Test.java @@ -0,0 +1,122 @@ +package com.zzlh.es.controller; +import it.geosolutions.geoserver.rest.GeoServerRESTManager; +import it.geosolutions.geoserver.rest.GeoServerRESTPublisher; +import it.geosolutions.geoserver.rest.encoder.GSLayerGroupEncoder; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; + +import java.net.URL; +import java.util.Base64; + +public class Test { + + private static final String GEOSERVER_URL = "http://localhost:8180/geoserver/rest"; + private static final String GEOSERVER_USERNAME = "admin"; + private static final String GEOSERVER_PASSWORD = "geoserver"; + + + public static void exist(String workspace) throws Exception{ + String url = GEOSERVER_URL+ "/workspaces/"+workspace+".xml"; + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet(url); + httpGet.setHeader("Authorization", getBasicAuthHeader(GEOSERVER_USERNAME, GEOSERVER_PASSWORD)); + + + httpClient.execute(httpGet, response -> { + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode >= 200 && statusCode < 300) { + System.out.println("图层组创建成功"); + } else { + System.out.println("图层组创建失败: " + EntityUtils.toString(response.getEntity())); + } + return statusCode; + }); + } + + public static void ceshi() throws Exception{ + URL u = new URL("http://localhost:8180/geoserver"); + GeoServerRESTManager manager = new GeoServerRESTManager(u, GEOSERVER_USERNAME, GEOSERVER_PASSWORD); + GeoServerRESTPublisher publisher = manager.getPublisher(); + GSLayerGroupEncoder groupEncoder = new GSLayerGroupEncoder(); + groupEncoder.setName("my_workspace:geoserver371212"); + groupEncoder.setWorkspace("my_workspace"); + boolean myWorkspace = publisher.createLayerGroup("my_workspace","my_workspace:geoserver371212", groupEncoder); + } + public static void publishLayerGroup(String workspace, String storeName, String layerGroupName) throws Exception { + CloseableHttpClient httpClient = HttpClients.createDefault(); + String layerGroupUrl = GEOSERVER_URL + "/workspaces/" + workspace + "/layergroups"; + // 创建图层组 + String createLayerGroupPayload = "" + + "" + + " " + layerGroupName + "" + + " " + + " " + workspace + "" + + " " + + " " + + " my_workspace:geoserver371302" + + " my_workspace:geoserver371212" + + " " + + ""; + + HttpPost createLayerGroupRequest = new HttpPost(layerGroupUrl); + createLayerGroupRequest.setHeader("Content-Type", "text/xml"); + createLayerGroupRequest.setHeader("Authorization", getBasicAuthHeader(GEOSERVER_USERNAME, GEOSERVER_PASSWORD)); + createLayerGroupRequest.setEntity(new StringEntity(createLayerGroupPayload, ContentType.APPLICATION_XML)); + + httpClient.execute(createLayerGroupRequest, response -> { + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode >= 200 && statusCode < 300) { + System.out.println("图层组创建成功"); + } else { + System.out.println("图层组创建失败: " + EntityUtils.toString(response.getEntity())); + } + return statusCode; + }); + + // 添加图层到组 + String addLayerToGroupPayload = "" + + "" + + " " + + " my_workspace:geoserver371212" + + " " + + ""; + + HttpPost addLayerToGroupRequest = new HttpPost(GEOSERVER_URL + "/layers/" + workspace + ":" + storeName + "/group/" + layerGroupName + ".xml"); + addLayerToGroupRequest.setHeader("Content-Type", "text/xml"); + addLayerToGroupRequest.setHeader("Authorization", getBasicAuthHeader(GEOSERVER_USERNAME, GEOSERVER_PASSWORD)); + addLayerToGroupRequest.setEntity(new StringEntity(addLayerToGroupPayload, ContentType.APPLICATION_XML)); + + httpClient.execute(addLayerToGroupRequest, response -> { + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode >= 200 && statusCode < 300) { + System.out.println("图层添加到组成功"); + } else { + System.out.println("图层添加到组失败: " + EntityUtils.toString(response.getEntity())); + } + return statusCode; + }); + + httpClient.close(); + } + + private static String getBasicAuthHeader(String username, String password) { + String credentials = username + ":" + password; + String encodedCredentials = new String(Base64.getEncoder().encode(credentials.getBytes())); + return "Basic " + encodedCredentials; + } + + public static void main(String[] args) throws Exception{ + try { + publishLayerGroup("my_workspace", "ceshi2", "ceshi2"); + } catch (Exception e) { + e.printStackTrace(); + } + // ceshi(); + } +} diff --git a/src/main/java/com/zzlh/es/domain/AjaxResult.java b/src/main/java/com/zzlh/es/domain/AjaxResult.java new file mode 100644 index 0000000..40c28b6 --- /dev/null +++ b/src/main/java/com/zzlh/es/domain/AjaxResult.java @@ -0,0 +1,208 @@ +package com.zzlh.es.domain; + + + +import com.zzlh.es.constant.HttpStatus; + +import java.util.HashMap; +import java.util.Objects; + +/** + * 操作消息提醒 + * + * @author hckj + */ +public class AjaxResult extends HashMap +{ + private static final long serialVersionUID = 1L; + + /** 状态码 */ + public static final String CODE_TAG = "code"; + + /** 返回内容 */ + public static final String MSG_TAG = "msg"; + + /** 数据对象 */ + public static final String DATA_TAG = "data"; + + /** + * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。 + */ + public AjaxResult() + { + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + */ + public AjaxResult(int code, String msg) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + * @param data 数据对象 + */ + public AjaxResult(int code, String msg, Object data) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + if (data!=null) + { + super.put(DATA_TAG, data); + } + } + + /** + * 返回成功消息 + * + * @return 成功消息 + */ + public static AjaxResult success() + { + return AjaxResult.success("操作成功"); + } + + /** + * 返回成功数据 + * + * @return 成功消息 + */ + public static AjaxResult success(Object data) + { + return AjaxResult.success("操作成功", data); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @return 成功消息 + */ + public static AjaxResult success(String msg) + { + return AjaxResult.success(msg, null); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 成功消息 + */ + public static AjaxResult success(String msg, Object data) + { + return new AjaxResult(HttpStatus.SUCCESS, msg, data); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @return 警告消息 + */ + public static AjaxResult warn(String msg) + { + return AjaxResult.warn(msg, null); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 警告消息 + */ + public static AjaxResult warn(String msg, Object data) + { + return new AjaxResult(HttpStatus.WARN, msg, data); + } + + /** + * 返回错误消息 + * + * @return 错误消息 + */ + public static AjaxResult error() + { + return AjaxResult.error("操作失败"); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @return 错误消息 + */ + public static AjaxResult error(String msg) + { + return AjaxResult.error(msg, null); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 错误消息 + */ + public static AjaxResult error(String msg, Object data) + { + return new AjaxResult(HttpStatus.ERROR, msg, data); + } + + /** + * 返回错误消息 + * + * @param code 状态码 + * @param msg 返回内容 + * @return 错误消息 + */ + public static AjaxResult error(int code, String msg) + { + return new AjaxResult(code, msg, null); + } + + /** + * 是否为成功消息 + * + * @return 结果 + */ + public boolean isSuccess() + { + return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG)); + } + + /** + * 是否为错误消息 + * + * @return 结果 + */ + public boolean isError() + { + return !isSuccess(); + } + + /** + * 方便链式调用 + * + * @param key + * @param value + * @return + */ + @Override + public AjaxResult put(String key, Object value) + { + super.put(key, value); + return this; + } +} diff --git a/src/main/java/com/zzlh/es/domain/R.java b/src/main/java/com/zzlh/es/domain/R.java new file mode 100644 index 0000000..f308ef0 --- /dev/null +++ b/src/main/java/com/zzlh/es/domain/R.java @@ -0,0 +1,118 @@ +package com.zzlh.es.domain; + + + +import com.zzlh.es.constant.Constants; + +import java.io.Serializable; + +/** + * 响应信息主体 + * + * @author hckj + */ +public class R implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 成功 */ + public static final int SUCCESS = Constants.SUCCESS; + + /** 失败 */ + public static final int FAIL = Constants.FAIL; + + private int code; + + private String msg; + + private T data; + + public static R ok() + { + return restResult(null, SUCCESS, null); + } + + public static R ok(T data) + { + return restResult(data, SUCCESS, null); + } + + public static R ok(T data, String msg) + { + return restResult(data, SUCCESS, msg); + } + + public static R fail() + { + return restResult(null, FAIL, null); + } + + public static R fail(String msg) + { + return restResult(null, FAIL, msg); + } + + public static R fail(T data) + { + return restResult(data, FAIL, null); + } + + public static R fail(T data, String msg) + { + return restResult(data, FAIL, msg); + } + + public static R fail(int code, String msg) + { + return restResult(null, code, msg); + } + + private static R restResult(T data, int code, String msg) + { + R apiResult = new R<>(); + apiResult.setCode(code); + apiResult.setData(data); + apiResult.setMsg(msg); + return apiResult; + } + + public int getCode() + { + return code; + } + + public void setCode(int code) + { + this.code = code; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } + + public T getData() + { + return data; + } + + public void setData(T data) + { + this.data = data; + } + + public static Boolean isError(R ret) + { + return !isSuccess(ret); + } + + public static Boolean isSuccess(R ret) + { + return R.SUCCESS == ret.getCode(); + } +} diff --git a/src/main/java/com/zzlh/es/entity/ApplicationBo.java b/src/main/java/com/zzlh/es/entity/ApplicationBo.java new file mode 100644 index 0000000..49cfdca --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/ApplicationBo.java @@ -0,0 +1,41 @@ +package com.zzlh.es.entity; + +import lombok.Data; + +/** + * @author soeasy + */ +@Data +public class ApplicationBo { + /** + * 应用id + */ + private Integer applicationId; + /** + * 应用名称 + */ + private String applicationName; + + /** + * 服务id + */ + private String serverStoreId; + /** + * 项目组id + */ + private Integer projectDataRelationId; + + /** + * 项目组名称 + */ + private String projectTeamName; + /** + * 图层名称 + */ + private String serverName; + + + + + +} diff --git a/src/main/java/com/zzlh/es/entity/ApplicationData.java b/src/main/java/com/zzlh/es/entity/ApplicationData.java new file mode 100644 index 0000000..0a617df --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/ApplicationData.java @@ -0,0 +1,52 @@ +package com.zzlh.es.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * + *

+ * + * @author wyl + * @since 2023-04-06 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("application_data") +@ApiModel(value="ApplicationData对象", description="") +public class ApplicationData implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "ID") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "应用名称") + @TableField("application_name") + private String applicationName; + + @ApiModelProperty(value = "空间坐标(4326)") + @TableField("space_type") + private String spaceType; + + @ApiModelProperty(value = "Cesium Mapbox Mars3d") + @TableField("map_frame") + private String mapFrame; + + @ApiModelProperty(value = "底图(天地图)") + @TableField("underlay") + private String underlay; + + +} diff --git a/src/main/java/com/zzlh/es/entity/BaseEntity.java b/src/main/java/com/zzlh/es/entity/BaseEntity.java new file mode 100644 index 0000000..5aad887 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/BaseEntity.java @@ -0,0 +1,59 @@ +package com.zzlh.es.entity; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * Entity基类 + * + * @author hckj + */ +@Data +public class BaseEntity implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 搜索值 */ + @JsonIgnore + private String searchValue; + + /** 创建者 */ + private String createBy; + + /** 创建时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** 更新者 */ + private String updateBy; + + /** 更新时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + /** 备注 */ + private String remark; + + /** 请求参数 */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private Map params; + + + public Map getParams() + { + if (params == null) + { + params = new HashMap<>(); + } + return params; + } + + +} diff --git a/src/main/java/com/zzlh/es/entity/DataStore.java b/src/main/java/com/zzlh/es/entity/DataStore.java new file mode 100644 index 0000000..f15fe05 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/DataStore.java @@ -0,0 +1,206 @@ +package com.zzlh.es.entity; + + +import com.baomidou.mybatisplus.annotation.TableName; +import com.zzlh.es.annotation.Excel; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import org.springframework.data.annotation.Id; + +/** + * 图层存储表对象 data_store + * + * @author LGD + * @date 2023-03-27 + */ +@TableName(value = "data_store") +public class DataStore extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** ID */ + @Id + private Long id; + + /** 服务名称 */ + @Excel(name = "服务名称") + private String severName; + + /** 空间坐标 */ + @Excel(name = "空间坐标") + private String spaceType; + + /** 服务类型 */ + @Excel(name = "服务类型") + private String severType; + + /** 存储类型 */ + @Excel(name = "存储类型") + private String storeType; + + /** 数据源类型 */ + @Excel(name = "数据源类型") + private String datasourceType; + + /** 关联数据表 */ + @Excel(name = "关联数据表") + private String tableRef; + + /** 是否发布 */ + @Excel(name = "是否发布") + private Long isDisplay; + + @Excel(name = "点线面") + private String dataType; + + private String styleName; + + private String nameRef; + + private String areaName; + + private String relation; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setSeverName(String severName) + { + this.severName = severName; + } + + public String getSeverName() + { + return severName; + } + public void setSpaceType(String spaceType) + { + this.spaceType = spaceType; + } + + public String getSpaceType() + { + return spaceType; + } + public void setSeverType(String severType) + { + this.severType = severType; + } + + public String getSeverType() + { + return severType; + } + public void setStoreType(String storeType) + { + this.storeType = storeType; + } + + public String getStoreType() + { + return storeType; + } + public void setDatasourceType(String datasourceType) + { + this.datasourceType = datasourceType; + } + + public String getDatasourceType() + { + return datasourceType; + } + public void setTableRef(String tableRef) + { + this.tableRef = tableRef; + } + + public String getTableRef() + { + return tableRef; + } + public void setIsDisplay(Long isDisplay) + { + this.isDisplay = isDisplay; + } + + public Long getIsDisplay() + { + return isDisplay; + } + + + public void setDataType(String dataType) + { + this.dataType = dataType; + } + + public String getDataType() + { + return dataType; + } + + public void setStyleName(String styleName) + { + this.styleName = styleName; + } + + public String getStyleName() + { + return styleName; + } + + public void setNameRef(String nameRef) + { + this.nameRef = nameRef; + } + + public String getNameRef() + { + return nameRef; + } + + public void setAreaName(String areaName) + { + this.areaName = areaName; + } + + public String getAreaName() + { + return areaName; + } + + public void setRelation(String relation) + { + this.relation = relation; + } + + public String getRelation() + { + return relation; + } + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("severName", getSeverName()) + .append("spaceType", getSpaceType()) + .append("severType", getSeverType()) + .append("storeType", getStoreType()) + .append("datasourceType", getDatasourceType()) + .append("createTime", getCreateTime()) + .append("tableRef", getTableRef()) + .append("isDisplay", getIsDisplay()) + .append("dataType",getDataType()) + .append("styleName",getStyleName()) + .append("nameRef",getNameRef()) + .append("areaName",getAreaName()) + .append("relation",getRelation()) + .toString(); + } +} diff --git a/src/main/java/com/zzlh/es/entity/DictData.java b/src/main/java/com/zzlh/es/entity/DictData.java new file mode 100644 index 0000000..9914cc5 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/DictData.java @@ -0,0 +1,44 @@ +package com.zzlh.es.entity; + +import java.math.BigDecimal; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * + *

+ * + * @author wyl + * @since 2023-04-07 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("dict_data") +@ApiModel(value="DictData对象", description="") +public class DictData implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.AUTO) + private BigDecimal id; + + @ApiModelProperty(value = "字典名称") + private String dictLabel; + + @ApiModelProperty(value = "字典值") + private String dictValue; + + @ApiModelProperty(value = "类型") + private String dictType; + + +} diff --git a/src/main/java/com/zzlh/es/entity/FileRecord.java b/src/main/java/com/zzlh/es/entity/FileRecord.java new file mode 100644 index 0000000..f2665c8 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/FileRecord.java @@ -0,0 +1,173 @@ +package com.zzlh.es.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 文件上传记录 + *

+ * + * @author haijun + * @since 2020-02-14 + */ +@Data +@TableName("sys_file_record") +public class FileRecord extends Model { + + private static final long serialVersionUID = 1L; + + + /** + * 记录ID + */ + @TableId(value="id",type=IdType.ID_WORKER_STR) + private String id; + + /** + * 源文件名 + */ + @TableField("org_name") + private String orgName; + + /** + * 服务器生成的文件名 + */ + @TableField("server_local_name") + private String serverLocalName; + + /** + * 服务器储存路径 + */ + @TableField("server_local_path") + private String serverLocalPath; + + /** + * 网络路径,生成的文件夹+系统生成文件名 + */ + @TableField("network_path") + private String networkPath; + + /** + * 上传类型 + */ + @TableField("upload_type") + private Integer uploadType; + + /** + * 文件MD5值 + */ + @TableField("md5_value") + private String md5Value; + + /** + * 文件大小 + */ + @TableField("file_size") + private Long fileSize; + + /** + * 是否分片 0 否 1是 + */ + @TableField("is_zone") + private Integer isZone; + + /** + * 分片总数 + */ + @TableField("zone_total") + private Integer zoneTotal; + + /** + * 分片时间 + */ + @TableField("zone_date") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date zoneDate; + + /** + * 分片合并时间 + */ + @TableField("zone_merge_date") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date zoneMergeDate; + + /** + * 文件类型 + */ + @TableField("file_type") + private String fileType; + + /** + * 设备信息 + */ + @TableField("upload_device") + private String uploadDevice; + + /** + * 上传设备IP + */ + @TableField("upload_ip") + private String uploadIp; + + /** + * 储存日期 + */ + @TableField("storage_date") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date storageDate; + + /** + * 下载统计 + */ + @TableField("download_count") + private Integer downloadCount; + + /** + * 上传统计 + */ + @TableField("upload_count") + private Integer uploadCount; + + /** + * 是否合并 + */ + @TableField("is_merge") + private Integer isMerge; + + /** + * 上传人员 + */ + @TableField("create_by") + private String createBy; + + /** + * 上传日期 + */ + @TableField("create_time") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** + * 删除标记 1正常 -1删除 + */ + @TableField("del_flag") + @TableLogic + private Integer delFlag; + + @Override + protected Serializable pkVal() { + return this.id; + } + +} diff --git a/src/main/java/com/zzlh/es/entity/FileZoneRecord.java b/src/main/java/com/zzlh/es/entity/FileZoneRecord.java new file mode 100644 index 0000000..9bf4c68 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/FileZoneRecord.java @@ -0,0 +1,137 @@ +package com.zzlh.es.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 文件分片记录 + *

+ * + * @author haijun + * @since 2020-02-14 + */ +@Data +@TableName("sys_file_zone_record") +//@ApiModel(value = "文件分片记录,FileZoneRecord") +public class FileZoneRecord extends Model { + + private static final long serialVersionUID = 1L; + + + /** + * 分片ID + */ + @TableId(value="id",type=IdType.ID_WORKER_STR) + //@ApiModelProperty(value = "分片ID") + private String id; + + /** + * 分片名称 + */ + @TableField("zone_name") + //@ApiModelProperty(value = "分片名称") + private String zoneName; + + /** + * 分片的文件路径 + */ + @TableField("zone_path") + //@ApiModelProperty(value = "分片的文件路径") + private String zonePath; + + /** + * 分片MD5 + */ + @TableField("zone_md5") + //@ApiModelProperty(value = "分片MD5") + private String zoneMd5; + + /** + * 分片记录MD5值 + */ + @TableField("zone_record_date") + //@ApiModelProperty(value = "分片记录MD5值") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date zoneRecordDate; + + /** + * 上传完成校验日期 + */ + @TableField("zone_check_date") + //@ApiModelProperty(value = "上传完成校验日期") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date zoneCheckDate; + + /** + * 总的分片数 + */ + @TableField("zone_total_count") + //@ApiModelProperty(value = "总的分片数") + private Integer zoneTotalCount; + + /** + * 总文件的MD5值 + */ + @TableField("zone_total_md5") + //@ApiModelProperty(value = "总文件的MD5值") + private String zoneTotalMd5; + + /** + * 当前分片索引 + */ + @TableField("zone_now_index") + //@ApiModelProperty(value = "当前分片索引") + private Integer zoneNowIndex; + + /** + * 文件开始位置 + */ + @TableField("zone_start_size") + //@ApiModelProperty(value = "文件开始位置") + private Long zoneStartSize; + + /** + * 文件结束位置 + */ + @TableField("zone_end_size") + //@ApiModelProperty(value = "文件结束位置") + private Long zoneEndSize; + + /** + * 文件总大小 + */ + @TableField("zone_total_size") + //@ApiModelProperty(value = "文件总大小") + private Long zoneTotalSize; + /** + * 分片文件后缀 + */ + @TableField("zone_suffix") + //@ApiModelProperty(value = "分片文件后缀") + private String zoneSuffix; + + /** + * 文件记录ID + */ + @TableField("file_record_id") + //@ApiModelProperty(value = "文件记录ID") + private String fileRecordId; + + @Override + protected Serializable pkVal() { + return this.id; + } + +} diff --git a/src/main/java/com/zzlh/es/entity/ProjectDataRelation.java b/src/main/java/com/zzlh/es/entity/ProjectDataRelation.java new file mode 100644 index 0000000..1beacb4 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/ProjectDataRelation.java @@ -0,0 +1,59 @@ +package com.zzlh.es.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + *

+ * + *

+ * + * @author wyl + * @since 2023-04-06 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor +@TableName("project_data_relation") +@ApiModel(value="ProjectDataRelation对象", description="") +public class ProjectDataRelation implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "项目组名称") + @TableField("project_team_name") + private String projectTeamName; + + @ApiModelProperty(value = "应用id") + @TableField("application_id") + private Integer applicationId; + + @ApiModelProperty(value = "服务id") + @TableField("server_store_id") + private String serverStoreId; + + @ApiModelProperty(value = "项目组id") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + + @ApiModelProperty(value = "图层服务名称") + @TableField("server_name") + private String serverName; + + + +} diff --git a/src/main/java/com/zzlh/es/entity/ProjectDataRelationMars.java b/src/main/java/com/zzlh/es/entity/ProjectDataRelationMars.java new file mode 100644 index 0000000..a376259 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/ProjectDataRelationMars.java @@ -0,0 +1,59 @@ +package com.zzlh.es.entity; + +import java.math.BigDecimal; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.io.Serializable; + +import com.zzlh.es.entity.vo.DataRelationMarsVo; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * + *

+ * + * @author wyl + * @since 2023-05-19 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("project_data_relation_mars") +@ApiModel(value="ProjectDataRelationMars对象", description="") +public class ProjectDataRelationMars implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "项目组名称") + private String projectTeamName; + + @ApiModelProperty(value = "服务id") + private String serverStoreId; + + @ApiModelProperty(value = "项目组id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @ApiModelProperty(value = "图层服务名称") + private String serverName; + + @ApiModelProperty(value = "json属性") + private String attribute; + + @ApiModelProperty(value = "父json属性") + private String pAttribute; + + + @ApiModelProperty(value = "样式属性") + private String properties; + + private String areaName; + + private Integer sort; +} diff --git a/src/main/java/com/zzlh/es/entity/StyleImage.java b/src/main/java/com/zzlh/es/entity/StyleImage.java new file mode 100644 index 0000000..70f4a6c --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/StyleImage.java @@ -0,0 +1,80 @@ +package com.zzlh.es.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.Date; + +/** + *

+ * + *

+ * + * @author wyl + * @since 2023-04-12 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("style_image") +@ApiModel(value="StyleImage对象", description="") +public class StyleImage implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "记录ID") + @TableId(value = "id", type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "源文件名") + private String orgName; + + @ApiModelProperty(value = "服务器生成的文件名") + private String serverLocalName; + + @ApiModelProperty(value = "服务器储存路径") + private String serverLocalPath; + + @ApiModelProperty(value = "网络路径,生成的文件夹+系统生成文件名") + private String networkPath; + + @ApiModelProperty(value = "文件MD5值") + private String md5Value; + + @ApiModelProperty(value = "文件大小") + private Long fileSize; + + @ApiModelProperty(value = "文件类型") + private String fileType; + + @ApiModelProperty(value = "设备信息") + private String uploadDevice; + + @ApiModelProperty(value = "上传设备IP") + private String uploadIp; + + @ApiModelProperty(value = "上传统计") + private Integer uploadCount; + + @ApiModelProperty(value = "上传人员") + private String createBy; + + @TableField("create_time") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + +} diff --git a/src/main/java/com/zzlh/es/entity/StyleParameterMapbox.java b/src/main/java/com/zzlh/es/entity/StyleParameterMapbox.java new file mode 100644 index 0000000..733436c --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/StyleParameterMapbox.java @@ -0,0 +1,40 @@ +package com.zzlh.es.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * + *

+ * + * @author wyl + * @since 2023-04-07 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("style_parameter_mapbox") +@ApiModel(value="StyleParameterMapbox对象", description="") +public class StyleParameterMapbox implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "点属性") + private String symbol; + + @ApiModelProperty(value = "线属性") + private String line; + + @ApiModelProperty(value = "面 多面属性") + private String fill; + + +} diff --git a/src/main/java/com/zzlh/es/entity/StyleParameterMars.java b/src/main/java/com/zzlh/es/entity/StyleParameterMars.java new file mode 100644 index 0000000..0fd6be0 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/StyleParameterMars.java @@ -0,0 +1,40 @@ +package com.zzlh.es.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * + *

+ * + * @author wyl + * @since 2023-05-19 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("style_parameter_mars") +@ApiModel(value="StyleParameterMars对象", description="") +public class StyleParameterMars implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "点属性json") + private String symbol; + + @ApiModelProperty(value = "线 面 多面属性") + private String lineAndFill; + + @ApiModelProperty(value = "父 json") + private String pattr; + + +} diff --git a/src/main/java/com/zzlh/es/entity/StyleRecord.java b/src/main/java/com/zzlh/es/entity/StyleRecord.java new file mode 100644 index 0000000..9d3a9f9 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/StyleRecord.java @@ -0,0 +1,109 @@ +package com.zzlh.es.entity; + +import com.zzlh.es.annotation.Excel; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + + + +/** + * 样式对象 style_record + * + * @author lgd + * @date 2023-08-09 + */ +public class StyleRecord extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 样式名称 */ + @Excel(name = "样式名称") + private String styleName; + + /** 样式类型 */ + @Excel(name = "样式类型") + private Integer type; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String fillColor; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String fillOpacity; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private String strokeColor; + + /** $column.columnComment */ + @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()") + private Double strokeWidth; + + public void setStyleName(String styleName) + { + this.styleName = styleName; + } + + public String getStyleName() + { + return styleName; + } + public void setType(Integer type) + { + this.type = type; + } + + public Integer getType() + { + return type; + } + public void setFillColor(String fillColor) + { + this.fillColor = fillColor; + } + + public String getFillColor() + { + return fillColor; + } + public void setFillOpacity(String fillOpacity) + { + this.fillOpacity = fillOpacity; + } + + public String getFillOpacity() + { + return fillOpacity; + } + public void setStrokeColor(String strokeColor) + { + this.strokeColor = strokeColor; + } + + public String getStrokeColor() + { + return strokeColor; + } + public void setStrokeWidth(Double strokeWidth) + { + this.strokeWidth = strokeWidth; + } + + public Double getStrokeWidth() + { + return strokeWidth; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("styleName", getStyleName()) + .append("type", getType()) + .append("fillColor", getFillColor()) + .append("fillOpacity", getFillOpacity()) + .append("strokeColor", getStrokeColor()) + .append("strokeWidth", getStrokeWidth()) + .toString(); + } +} diff --git a/src/main/java/com/zzlh/es/entity/StyleServerMapbox.java b/src/main/java/com/zzlh/es/entity/StyleServerMapbox.java new file mode 100644 index 0000000..d959c57 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/StyleServerMapbox.java @@ -0,0 +1,52 @@ +package com.zzlh.es.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import java.io.Serializable; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + *

+ * + *

+ * + * @author wyl + * @since 2023-04-08 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("style_server_mapbox") +@ApiModel(value="StyleServerMapbox对象", description="") +public class StyleServerMapbox implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "点属性") + private String symbol; + + @ApiModelProperty(value = "线属性") + private String line; + + @ApiModelProperty(value = "面 多面属性") + private String fill; + + @ApiModelProperty(value = "图层服务名称") + private String serverName; + + @ApiModelProperty(value = "图标url") + private String imgUrl; + + @ApiModelProperty(value = "x位移数据") + private String x; + + @ApiModelProperty(value = "y位移数据") + private String y; + + +} diff --git a/src/main/java/com/zzlh/es/entity/TUser.java b/src/main/java/com/zzlh/es/entity/TUser.java new file mode 100644 index 0000000..7bc2689 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/TUser.java @@ -0,0 +1,49 @@ +package com.zzlh.es.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import lombok.Data; +import org.springframework.data.annotation.Id; + + + +/** + * 描述:用户表实体 + * @author: shf + * @date: 2019-04-19 16:24:04 + * @version: V1.0 + */ +@Data +@TableName("t_user") +public class TUser extends Model { + /** + * 主键 + */ + @TableId(value="id",type= IdType.AUTO) + private Integer id; + /** + * 用户名 + */ + @TableField("username") + private String username; + /** + * 密码 + */ + @TableField("password") + private String password; + /** + * 用户角色 + */ + @TableField("salt") + private String salt; + /** + * 账号状态 + */ + @TableField("state") + private String state; + + +} diff --git a/src/main/java/com/zzlh/es/entity/TreeLabelMarsApp.java b/src/main/java/com/zzlh/es/entity/TreeLabelMarsApp.java new file mode 100644 index 0000000..cdc3a17 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/TreeLabelMarsApp.java @@ -0,0 +1,25 @@ +package com.zzlh.es.entity; + +import com.zzlh.es.entity.vo.DataRelationMarsVo; +import lombok.Data; + +import java.util.List; + +/** + * 封装图层树的业务bo + * + * @author soeasy + */ +@Data +public class TreeLabelMarsApp { + public String serverName; + + public List ids; + + public Long id; + public List children; + + public String attr; + + public Integer sort; +} diff --git a/src/main/java/com/zzlh/es/entity/TreeLableBo.java b/src/main/java/com/zzlh/es/entity/TreeLableBo.java new file mode 100644 index 0000000..1a42af2 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/TreeLableBo.java @@ -0,0 +1,17 @@ +package com.zzlh.es.entity; + +import lombok.Data; + +import java.util.List; +/** + * 封装图层树的业务bo + * @author soeasy + */ +@Data +public class TreeLableBo { + public String serverName; + + public List ids; + public List children; + +} diff --git a/src/main/java/com/zzlh/es/entity/TreeLableMarsBo.java b/src/main/java/com/zzlh/es/entity/TreeLableMarsBo.java new file mode 100644 index 0000000..8639e27 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/TreeLableMarsBo.java @@ -0,0 +1,24 @@ +package com.zzlh.es.entity; + +import lombok.Data; + +import java.util.List; + +/** + * 封装图层树的业务bo + * + * @author soeasy + */ +@Data +public class TreeLableMarsBo { + public String serverName; + + public List ids; + + public Long id; + public List children; + + public String attr; + + public Integer sort; +} diff --git a/src/main/java/com/zzlh/es/entity/properties/JwtProperties.java b/src/main/java/com/zzlh/es/entity/properties/JwtProperties.java new file mode 100644 index 0000000..0036fd3 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/properties/JwtProperties.java @@ -0,0 +1,28 @@ +package com.zzlh.es.entity.properties; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + + +@ConfigurationProperties(prefix = "jwt") +@Data +@Component +public class JwtProperties { + /** + * request header key + */ + private String Header; + /** + * 秘钥 + */ + private String Secret; + /** + * 过期时间 + */ + private long Expiration; + /** + * token 的header + */ + private String TokenHead; +} diff --git a/src/main/java/com/zzlh/es/entity/vo/DataRelationMarsVo.java b/src/main/java/com/zzlh/es/entity/vo/DataRelationMarsVo.java new file mode 100644 index 0000000..2a2bb2b --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/vo/DataRelationMarsVo.java @@ -0,0 +1,20 @@ +package com.zzlh.es.entity.vo; + +import com.zzlh.es.entity.ProjectDataRelationMars; +import lombok.Data; + +@Data +public class DataRelationMarsVo extends ProjectDataRelationMars { + + private String url; + + private String layers; + + private String type; + + private String image; + + private String geomType; + + private String label; +} diff --git a/src/main/java/com/zzlh/es/entity/vo/PartFileVo.java b/src/main/java/com/zzlh/es/entity/vo/PartFileVo.java new file mode 100644 index 0000000..6670239 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/vo/PartFileVo.java @@ -0,0 +1,16 @@ +package com.zzlh.es.entity.vo; + +import lombok.Data; +import org.springframework.web.multipart.MultipartFile; +@Data +public class PartFileVo { + + private MultipartFile file; + + private String spaceType; + + private String tableName; + private String styleName; + + private String serverName; +} diff --git a/src/main/java/com/zzlh/es/entity/vo/StyleDataVo.java b/src/main/java/com/zzlh/es/entity/vo/StyleDataVo.java new file mode 100644 index 0000000..d708421 --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/vo/StyleDataVo.java @@ -0,0 +1,21 @@ +package com.zzlh.es.entity.vo; + +import lombok.Data; + +@Data +public class StyleDataVo { + + private String styleName; + + private String fillColor; + + private String fillOpacity; + + private String strokeColor; + + private String strokeWidth; + + //0 点 1线 2面 + private Integer type; + +} diff --git a/src/main/java/com/zzlh/es/entity/vo/TableDataVo.java b/src/main/java/com/zzlh/es/entity/vo/TableDataVo.java new file mode 100644 index 0000000..fea373f --- /dev/null +++ b/src/main/java/com/zzlh/es/entity/vo/TableDataVo.java @@ -0,0 +1,11 @@ +package com.zzlh.es.entity.vo; + +import com.zzlh.es.entity.BaseEntity; +import lombok.Data; + +@Data +public class TableDataVo extends BaseEntity { + + private String tableName; + +} diff --git a/src/main/java/com/zzlh/es/exception/BusinessException.java b/src/main/java/com/zzlh/es/exception/BusinessException.java new file mode 100644 index 0000000..2682899 --- /dev/null +++ b/src/main/java/com/zzlh/es/exception/BusinessException.java @@ -0,0 +1,58 @@ +package com.zzlh.es.exception; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.Data; + +/** + * 业务异常处理 + * + * @author soeasy + */ +@Data +public class BusinessException extends RuntimeException { + private static final long serialVersionUID = 1L; + + private final static ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + /** + * 异常对应的返回码 + */ + private Integer code; + + /** + * 异常对应的描述信息 + */ + private String message; + + private Throwable throwable; + + public BusinessException() { + super(); + } + + public BusinessException(String message) { + super(message); + this.message = message; + } + + public BusinessException(Integer code, String message) { + super(message); + this.code = code; + this.message = message; + } + + public BusinessException(String message, Throwable cause) { + super(message, cause); + this.message = String.format("%s %s", message, cause.getMessage()); + } + + public BusinessException(int code, String message, Throwable throwable) { + super(message); + this.code = code; + this.message = message; + this.throwable = throwable; + } + + + +} diff --git a/src/main/java/com/zzlh/es/exception/GlobalExceptionHandler.java b/src/main/java/com/zzlh/es/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..103261f --- /dev/null +++ b/src/main/java/com/zzlh/es/exception/GlobalExceptionHandler.java @@ -0,0 +1,39 @@ +package com.zzlh.es.exception; + + +import com.zzlh.es.domain.AjaxResult; +import lombok.extern.slf4j.Slf4j; + +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.util.HashMap; +import java.util.Map; + + + +@Slf4j +@RestControllerAdvice +@SuppressWarnings("unchecked") +public class GlobalExceptionHandler { + + /** + * 处理所有不可知的异常 + */ + @ExceptionHandler(Exception.class) + public Map handleException(Exception e){ + // 打印堆栈信息 + e.printStackTrace(); + Map map = new HashMap(); + map.put("code",e.hashCode()); + map.put("msg","系统错误,请联系管理员"); + return map; + } + + @ExceptionHandler(BusinessException.class) + public AjaxResult handleBadRequestException(BusinessException e){ + // 打印堆栈信息 + e.printStackTrace(); + return AjaxResult.error(e.getCode(),e.getMessage()); + } +} diff --git a/src/main/java/com/zzlh/es/exception/UtilException.java b/src/main/java/com/zzlh/es/exception/UtilException.java new file mode 100644 index 0000000..617eafb --- /dev/null +++ b/src/main/java/com/zzlh/es/exception/UtilException.java @@ -0,0 +1,26 @@ +package com.zzlh.es.exception; + +/** + * 工具类异常 + * + * @author hckj + */ +public class UtilException extends RuntimeException +{ + private static final long serialVersionUID = 8247610319171014183L; + + public UtilException(Throwable e) + { + super(e.getMessage(), e); + } + + public UtilException(String message) + { + super(message); + } + + public UtilException(String message, Throwable throwable) + { + super(message, throwable); + } +} diff --git a/src/main/java/com/zzlh/es/mapper/ApplicationDataMapper.java b/src/main/java/com/zzlh/es/mapper/ApplicationDataMapper.java new file mode 100644 index 0000000..4f983d2 --- /dev/null +++ b/src/main/java/com/zzlh/es/mapper/ApplicationDataMapper.java @@ -0,0 +1,34 @@ +package com.zzlh.es.mapper; + +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.ApplicationBo; +import com.zzlh.es.entity.ApplicationData; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.ResultMap; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author wyl + * @since 2023-04-06 + */ +public interface ApplicationDataMapper extends BaseMapper{ + + boolean insertApplicationData(ApplicationData applicationData); + @Select("select*from application_data") + List getAllApplication(); + + @Select("select application_data.id application_id,application_data.application_name,project_data_relation.server_store_id,project_data_relation.id project_data_relation_id,project_data_relation.project_team_name,project_data_relation.server_name from application_data,project_data_relation where application_data.id= project_data_relation.application_id and application_data.id=#{id}") + @ResultMap("applicationBo") + List getApplicationById(@Param("id") Integer id); + + @Select("select project_data_relation.server_store_id,project_data_relation.id project_data_relation_id,project_data_relation.project_team_name,project_data_relation.server_name from project_data_relation ") + @ResultMap("applicationBo") + List getProjectById(); +} diff --git a/src/main/java/com/zzlh/es/mapper/DataStoreMapper.java b/src/main/java/com/zzlh/es/mapper/DataStoreMapper.java new file mode 100644 index 0000000..10afffe --- /dev/null +++ b/src/main/java/com/zzlh/es/mapper/DataStoreMapper.java @@ -0,0 +1,99 @@ +package com.zzlh.es.mapper; + + + +import com.zzlh.es.entity.DataStore; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; +import org.springframework.data.repository.query.Param; + +import java.util.List; +import java.util.Map; + +/** + * 图层存储表Mapper接口 + * + * @author LGD + * @date 2023-03-27 + */ +@Mapper +public interface DataStoreMapper +{ + /** + * 查询图层存储表 + * + * @param id 图层存储表主键 + * @return 图层存储表 + */ + public DataStore selectDataStoreById(Long id); + + /** + * 查询图层存储表列表 + * + * @param dataStore 图层存储表 + * @return 图层存储表集合 + */ + public List selectDataStoreList(DataStore dataStore); + + /** + * 新增图层存储表 + * + * @param dataStore 图层存储表 + * @return 结果 + */ + public int insertDataStore(DataStore dataStore); + + /** + * 修改图层存储表 + * + * @param dataStore 图层存储表 + * @return 结果 + */ + public int updateDataStore(DataStore dataStore); + + /** + * 删除图层存储表 + * + * @param id 图层存储表主键 + * @return 结果 + */ + public int deleteDataStoreById(Long id); + + public int deleteMapBoxByName(String name); + public int selectCountMapBoxById(String id); + + public int selectCountMarsById(String id); + /** + * 批量删除图层存储表 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteDataStoreByIds(Long[] ids); + + public List selectDataStoreListByTableName(@Param("value") String value); + + /** + * 根据坐标系查询对应的图层服务 + * @param serverType + * @return + */ + @Select("select *from data_store where space_type=#{spaceType}") + List selectDataStore(@Param("dataType") String serverType); + + @Select("select * from data_store where table_ref=#{sever_name}") + DataStore selectDataStoreByName(@Param("sever_name") String sever_name); + + @Select("select ${value} ,ST_X(ST_Centroid(geom)) AS lng, ST_Y(ST_Centroid(geom)) AS lat from ${sever_name}") + List selectDataByName(@Param("value") String value,@Param("sever_name") String sever_name); + + @Select("select count(*) from data_store where sever_name=#{sever_name}") + Integer selectDataStoreCount(@Param("sever_name") String sever_name); + + + @Select("SELECT COUNT(*) FROM information_schema.tables WHERE table_name =#{sever_name}") + Integer selectDataStoreCountTemp(@Param("sever_name") String sever_name); + @Select("SELECT COUNT(*) FROM information_schema.tables WHERE table_name =#{tableValue}") + Integer selectDataStoreCountByTableRef(@Param("tableValue") String tableValue); + +} diff --git a/src/main/java/com/zzlh/es/mapper/DictDataMapper.java b/src/main/java/com/zzlh/es/mapper/DictDataMapper.java new file mode 100644 index 0000000..3e0e0c6 --- /dev/null +++ b/src/main/java/com/zzlh/es/mapper/DictDataMapper.java @@ -0,0 +1,22 @@ +package com.zzlh.es.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzlh.es.entity.DictData; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @author wyl + * @since 2023-04-07 + */ +public interface DictDataMapper extends BaseMapper { + + @Select("select * from dict_data") + List getDictData(); + +} diff --git a/src/main/java/com/zzlh/es/mapper/EntityMapper.java b/src/main/java/com/zzlh/es/mapper/EntityMapper.java new file mode 100644 index 0000000..e637d18 --- /dev/null +++ b/src/main/java/com/zzlh/es/mapper/EntityMapper.java @@ -0,0 +1,35 @@ +package com.zzlh.es.mapper; + +import java.util.List; + + +public interface EntityMapper { + + /** + * DTO转Entity + * @param dto + * @return + */ + E toEntity(D dto); + + /** + * Entity转DTO + * @param entity + * @return + */ + D toDto(E entity); + + /** + * DTO集合转Entity集合 + * @param dtoList + * @return + */ + List toEntity(List dtoList); + + /** + * Entity集合转DTO集合 + * @param entityList + * @return + */ + List toDto(List entityList); +} diff --git a/src/main/java/com/zzlh/es/mapper/FileRecordMapper.java b/src/main/java/com/zzlh/es/mapper/FileRecordMapper.java new file mode 100644 index 0000000..4ed2d96 --- /dev/null +++ b/src/main/java/com/zzlh/es/mapper/FileRecordMapper.java @@ -0,0 +1,20 @@ +package com.zzlh.es.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzlh.es.entity.FileRecord; +import org.apache.ibatis.annotations.Mapper; + + +/** + *

+ * 文件上传记录 Mapper 接口 + *

+ * + * @author haijun + * @since 2020-02-14 + */ + +@Mapper +public interface FileRecordMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/src/main/java/com/zzlh/es/mapper/FileZoneRecordMapper.java b/src/main/java/com/zzlh/es/mapper/FileZoneRecordMapper.java new file mode 100644 index 0000000..a9e838c --- /dev/null +++ b/src/main/java/com/zzlh/es/mapper/FileZoneRecordMapper.java @@ -0,0 +1,20 @@ +package com.zzlh.es.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzlh.es.entity.FileZoneRecord; +import org.apache.ibatis.annotations.Mapper; + + +/** + *

+ * 文件分片记录 Mapper 接口 + *

+ * + * @author haijun + * @since 2020-02-14 + */ + +@Mapper +public interface FileZoneRecordMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/src/main/java/com/zzlh/es/mapper/GeoServerDao.java b/src/main/java/com/zzlh/es/mapper/GeoServerDao.java new file mode 100644 index 0000000..6963bca --- /dev/null +++ b/src/main/java/com/zzlh/es/mapper/GeoServerDao.java @@ -0,0 +1,231 @@ +package com.zzlh.es.mapper; + + +import org.apache.ibatis.annotations.*; +import org.springframework.data.repository.query.Param; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@Mapper +public interface GeoServerDao { + + @Update("CREATE SEQUENCE \"public\".\"${value}_seq\" ") + public void createSequence(@Param("value")String value); + + @Select("select * from \"public\".\"${value}\" ") + public List selectList(@Param("value")String value); + + @Select("select count(*) from \"public\".\"${tableName}\" where " + + " ${keyWord} like concat('%',#{value},'%')" ) + public Integer selectLayerDataListCount(Map map); + + @Select("select count(*) from \"public\".\"${tableName}\" ") + public Integer selectLayerDataListCountNoParam(Map map); + + + + @Select("select * from \"public\".\"${tableName}\" where " + + " ${keyWord} like concat('%',#{value},'%')" + + " limit #{pageSize} offset #{pageNum} ") + public List selectLayerDataList(Map map); + + @Select("select * from \"public\".\"${tableName}\" " + + " limit #{pageSize} offset #{pageNum} ") + public List selectLayerDataListNoParam(Map map); + @Update("") + public void createTable(@Param("tableName")String tableName,@Param("heads")List> heads); + + @Update("") + public void createNewTable(@Param("tableName")String tableName,@Param("heads")List> heads); + + @Insert("") + public void addTableDateList(@Param("tableName")String tableName, @Param("heads") List> heads, + @Param("data") LinkedHashMap data,@Param("spaceType")String spaceType); + + + @Insert("") + public void addTableDateList1(@Param("tableName")String tableName, @Param("heads") List> heads, + @Param("data") LinkedHashMap data,@Param("spaceType")String spaceType); + @Insert("") + public void addNewTableDateList(@Param("tableName")String tableName, @Param("heads") List> heads, + @Param("data") LinkedHashMap data,@Param("spaceType")String spaceType); + + + @Select("select dict_label dictLabel,dict_value dictValue from dict_data where dict_type=#{dictType}") + public List getDictData(@Param("dictType")String dictType); + + @Select("select sever_name from data_store where sever_name=#{serverName}") + String selectByName(@Param("serverName")String serverName); + + @Insert("") + public void addTableDataStore(@Param("tableName")String tableName,@Param("severName")String severName,@Param("spaceType")String spaceType, + @Param("severType")String severType,@Param("storeType")String storeType, + @Param("datasourceType")String datasourceType,@Param("dataType")String dataType, + @Param("styleName")String styleName, @Param("nameRef")String nameRef,@Param("areaName")String areaName, + @Param("relation")String relation); + + + @Select("select style_name,space_type from \"public\".data_store where table_ref =#{value}") + Map selectStyleName(@Param("value")String value); + + @Select("select count(*) from information_schema.tables where table_name =#{value}") + int selectTableCount(@Param("value")String value); + + @Select("select count(*) from pg_class where relname =#{value}") + int selectSeqCount(@Param("value")String value); + + @Update("Drop table \"public\".\"${value}\" ") + void deleteTable(@Param("value")String value); + + @Update("Drop sequence \"${value}\" ") + void deleteSequence(@Param("value")String value); + + + @Insert("") + public void updateTableDateList1(@Param("tableName")String tableName, + @Param("data") LinkedHashMap data,@Param("id")Integer id,@Param("spaceType")String spaceType); + + + @Insert("") + public void insertTableDateList(@Param("tableName")String tableName, + @Param("data") LinkedHashMap data,@Param("spaceType")String spaceType); + + + @Delete("delete from \"public\".\"${tableName}\" where id=#{id}") + public void deleteTableDateList(@Param("tableName")String tableName, @Param("id")Integer id); + + + @Update("update \"public\".\"${tableName}\" set is_del=1 where id=#{id}") + public void updateTableDateList(@Param("tableName")String tableName, @Param("id")Integer id); + + @Select("select * from \"public\".\"${tableName}\" where id=#{id}") + public Map selectSingleData(@Param("tableName")String tableName, @Param("id")Integer id); + + @Select("select ST_AsText(ST_Centroid(ST_Extent(geom))) from \"public\".\"${value}\"") + public String selectGeomData(String shpName); + + @Select("select count(*) from \"public\".\"data_store\" where style_name=#{value} ") + public Integer selectStyleCount(@Param("value")String value); + + @Select("select column_name from information_schema.columns\n" + + " where table_schema='public' and table_name=#{value} ") + public List selectTableCloumn(@Param("value")String value); + + + @Select("select DISTINCT ${columnName} from \"public\".\"${tableName}\"") + public List selectDataByColumn(@Param("columnName")String columnName,@Param("tableName")String tableName); + + @Select("select count(*) from \"public\".\"${value}\" ") + public Integer selectTableDataCount(@Param("value")String value); + + @Select("select sever_name from data_store where table_ref=#{value}") + String selectSeverNameByTableRef(@Param("value")String value); +} + diff --git a/src/main/java/com/zzlh/es/mapper/ProjectDataRelationMapper.java b/src/main/java/com/zzlh/es/mapper/ProjectDataRelationMapper.java new file mode 100644 index 0000000..b59cb67 --- /dev/null +++ b/src/main/java/com/zzlh/es/mapper/ProjectDataRelationMapper.java @@ -0,0 +1,25 @@ +package com.zzlh.es.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzlh.es.entity.ProjectDataRelation; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.ResultMap; +import org.apache.ibatis.annotations.Select; + +/** + *

+ * Mapper 接口 + *

+ * + * @author wyl + * @since 2023-04-06 + */ +public interface ProjectDataRelationMapper extends BaseMapper{ + + + @Select("select * from project_data_relation where project_team_name=#{projectTeamName} and application_id=#{applicationId}") + @ResultMap("projectDataRelation") + ProjectDataRelation findExist(@Param("projectTeamName") String projectTeamName,@Param("applicationId") Integer applicationId); + + Integer updateProject(ProjectDataRelation projectDataRelation); +} diff --git a/src/main/java/com/zzlh/es/mapper/ProjectDataRelationMarsMapper.java b/src/main/java/com/zzlh/es/mapper/ProjectDataRelationMarsMapper.java new file mode 100644 index 0000000..f78d158 --- /dev/null +++ b/src/main/java/com/zzlh/es/mapper/ProjectDataRelationMarsMapper.java @@ -0,0 +1,24 @@ +package com.zzlh.es.mapper; + +import com.zzlh.es.entity.ProjectDataRelation; +import com.zzlh.es.entity.ProjectDataRelationMars; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.ResultMap; +import org.apache.ibatis.annotations.Select; + +/** + *

+ * Mapper 接口 + *

+ * + * @author wyl + * @since 2023-05-19 + */ +public interface ProjectDataRelationMarsMapper extends BaseMapper { + boolean insertMars(ProjectDataRelationMars projectDataRelationMars); + + @Select("select * from project_data_relation_mars where project_team_name=#{projectTeamName} limit 1") + @ResultMap("projectDataRelationMars") + ProjectDataRelationMars findExist(@Param("projectTeamName") String projectTeamName); +} diff --git a/src/main/java/com/zzlh/es/mapper/StyleImageMapper.java b/src/main/java/com/zzlh/es/mapper/StyleImageMapper.java new file mode 100644 index 0000000..f0c6220 --- /dev/null +++ b/src/main/java/com/zzlh/es/mapper/StyleImageMapper.java @@ -0,0 +1,16 @@ +package com.zzlh.es.mapper; + +import com.zzlh.es.entity.StyleImage; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * Mapper 接口 + *

+ * + * @author wyl + * @since 2023-04-12 + */ +public interface StyleImageMapper extends BaseMapper { + +} diff --git a/src/main/java/com/zzlh/es/mapper/StyleParameterMapboxMapper.java b/src/main/java/com/zzlh/es/mapper/StyleParameterMapboxMapper.java new file mode 100644 index 0000000..5983bdc --- /dev/null +++ b/src/main/java/com/zzlh/es/mapper/StyleParameterMapboxMapper.java @@ -0,0 +1,20 @@ +package com.zzlh.es.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzlh.es.entity.StyleParameterMapbox; +import org.apache.ibatis.annotations.ResultMap; +import org.apache.ibatis.annotations.Select; + +/** + *

+ * Mapper 接口 + *

+ * + * @author wyl + * @since 2023-04-07 + */ +public interface StyleParameterMapboxMapper extends BaseMapper { + @Select("select * from style_parameter_mapbox") + @ResultMap("styleParameterMapbox") + StyleParameterMapbox getStyleByMapbox(); +} diff --git a/src/main/java/com/zzlh/es/mapper/StyleParameterMarsMapper.java b/src/main/java/com/zzlh/es/mapper/StyleParameterMarsMapper.java new file mode 100644 index 0000000..76b8002 --- /dev/null +++ b/src/main/java/com/zzlh/es/mapper/StyleParameterMarsMapper.java @@ -0,0 +1,16 @@ +package com.zzlh.es.mapper; + +import com.zzlh.es.entity.StyleParameterMars; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * Mapper 接口 + *

+ * + * @author wyl + * @since 2023-05-19 + */ +public interface StyleParameterMarsMapper extends BaseMapper { + +} diff --git a/src/main/java/com/zzlh/es/mapper/StyleRecordMapper.java b/src/main/java/com/zzlh/es/mapper/StyleRecordMapper.java new file mode 100644 index 0000000..1af01a0 --- /dev/null +++ b/src/main/java/com/zzlh/es/mapper/StyleRecordMapper.java @@ -0,0 +1,63 @@ +package com.zzlh.es.mapper; + +import com.zzlh.es.entity.StyleRecord; + +import java.util.List; + + +/** + * 样式Mapper接口 + * + * @author lgd + * @date 2023-08-09 + */ +public interface StyleRecordMapper +{ + /** + * 查询样式 + * + * @param styleName 样式主键 + * @return 样式 + */ + public StyleRecord selectStyleRecordByStyleName(String styleName); + + /** + * 查询样式列表 + * + * @param styleRecord 样式 + * @return 样式集合 + */ + public List selectStyleRecordList(StyleRecord styleRecord); + + /** + * 新增样式 + * + * @param styleRecord 样式 + * @return 结果 + */ + public int insertStyleRecord(StyleRecord styleRecord); + + /** + * 修改样式 + * + * @param styleRecord 样式 + * @return 结果 + */ + public int updateStyleRecord(StyleRecord styleRecord); + + /** + * 删除样式 + * + * @param styleName 样式主键 + * @return 结果 + */ + public int deleteStyleRecordByStyleName(String styleName); + + /** + * 批量删除样式 + * + * @param styleNames 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteStyleRecordByStyleNames(String[] styleNames); +} diff --git a/src/main/java/com/zzlh/es/mapper/StyleServerMapboxMapper.java b/src/main/java/com/zzlh/es/mapper/StyleServerMapboxMapper.java new file mode 100644 index 0000000..5867a23 --- /dev/null +++ b/src/main/java/com/zzlh/es/mapper/StyleServerMapboxMapper.java @@ -0,0 +1,16 @@ +package com.zzlh.es.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzlh.es.entity.StyleServerMapbox; + +/** + *

+ * Mapper 接口 + *

+ * + * @author wyl + * @since 2023-04-08 + */ +public interface StyleServerMapboxMapper extends BaseMapper{ + +} diff --git a/src/main/java/com/zzlh/es/mapper/TUserMapper.java b/src/main/java/com/zzlh/es/mapper/TUserMapper.java new file mode 100644 index 0000000..8bb7847 --- /dev/null +++ b/src/main/java/com/zzlh/es/mapper/TUserMapper.java @@ -0,0 +1,16 @@ +package com.zzlh.es.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zzlh.es.entity.TUser; +import org.apache.ibatis.annotations.Mapper; + +/** + * @author soeasy + */ +@Mapper +public interface TUserMapper extends BaseMapper { + + + TUser findByName(String username); +} diff --git a/src/main/java/com/zzlh/es/page/PageDomain.java b/src/main/java/com/zzlh/es/page/PageDomain.java new file mode 100644 index 0000000..b8c734a --- /dev/null +++ b/src/main/java/com/zzlh/es/page/PageDomain.java @@ -0,0 +1,102 @@ +package com.zzlh.es.page; + + +import com.zzlh.es.utils.StringUtils; + +/** + * 分页数据 + * + * @author hckj + */ +public class PageDomain +{ + /** 当前记录起始索引 */ + private Integer pageNum; + + /** 每页显示记录数 */ + private Integer pageSize; + + /** 排序列 */ + private String orderByColumn; + + /** 排序的方向desc或者asc */ + private String isAsc = "asc"; + + /** 分页参数合理化 */ + private Boolean reasonable = true; + + public String getOrderBy() + { + if (StringUtils.isEmpty(orderByColumn)) + { + return ""; + } + return StringUtils.toUnderScoreCase(orderByColumn) + " " + isAsc; + } + + public Integer getPageNum() + { + return pageNum; + } + + public void setPageNum(Integer pageNum) + { + this.pageNum = pageNum; + } + + public Integer getPageSize() + { + return pageSize; + } + + public void setPageSize(Integer pageSize) + { + this.pageSize = pageSize; + } + + public String getOrderByColumn() + { + return orderByColumn; + } + + public void setOrderByColumn(String orderByColumn) + { + this.orderByColumn = orderByColumn; + } + + public String getIsAsc() + { + return isAsc; + } + + public void setIsAsc(String isAsc) + { + if (StringUtils.isNotEmpty(isAsc)) + { + // 兼容前端排序类型 + if ("ascending".equals(isAsc)) + { + isAsc = "asc"; + } + else if ("descending".equals(isAsc)) + { + isAsc = "desc"; + } + this.isAsc = isAsc; + } + } + + public Boolean getReasonable() + { + if (StringUtils.isNull(reasonable)) + { + return Boolean.TRUE; + } + return reasonable; + } + + public void setReasonable(Boolean reasonable) + { + this.reasonable = reasonable; + } +} diff --git a/src/main/java/com/zzlh/es/page/TableDataInfo.java b/src/main/java/com/zzlh/es/page/TableDataInfo.java new file mode 100644 index 0000000..d283b98 --- /dev/null +++ b/src/main/java/com/zzlh/es/page/TableDataInfo.java @@ -0,0 +1,85 @@ +package com.zzlh.es.page; + +import java.io.Serializable; +import java.util.List; + +/** + * 表格分页数据对象 + * + * @author hckj + */ +public class TableDataInfo implements Serializable +{ + private static final long serialVersionUID = 1L; + + /** 总记录数 */ + private long total; + + /** 列表数据 */ + private List rows; + + /** 消息状态码 */ + private int code; + + /** 消息内容 */ + private String msg; + + /** + * 表格数据对象 + */ + public TableDataInfo() + { + } + + /** + * 分页 + * + * @param list 列表数据 + * @param total 总记录数 + */ + public TableDataInfo(List list, int total) + { + this.rows = list; + this.total = total; + } + + public long getTotal() + { + return total; + } + + public void setTotal(long total) + { + this.total = total; + } + + public List getRows() + { + return rows; + } + + public void setRows(List rows) + { + this.rows = rows; + } + + public int getCode() + { + return code; + } + + public void setCode(int code) + { + this.code = code; + } + + public String getMsg() + { + return msg; + } + + public void setMsg(String msg) + { + this.msg = msg; + } +} \ No newline at end of file diff --git a/src/main/java/com/zzlh/es/page/TableSupport.java b/src/main/java/com/zzlh/es/page/TableSupport.java new file mode 100644 index 0000000..12eeb5c --- /dev/null +++ b/src/main/java/com/zzlh/es/page/TableSupport.java @@ -0,0 +1,57 @@ +package com.zzlh.es.page; + + +import com.zzlh.es.text.Convert; +import com.zzlh.es.utils.ServletUtils; + +/** + * 表格数据处理 + * + * @author hckj + */ +public class TableSupport +{ + /** + * 当前记录起始索引 + */ + public static final String PAGE_NUM = "pageNum"; + + /** + * 每页显示记录数 + */ + public static final String PAGE_SIZE = "pageSize"; + + /** + * 排序列 + */ + public static final String ORDER_BY_COLUMN = "orderByColumn"; + + /** + * 排序的方向 "desc" 或者 "asc". + */ + public static final String IS_ASC = "isAsc"; + + /** + * 分页参数合理化 + */ + public static final String REASONABLE = "reasonable"; + + /** + * 封装分页对象 + */ + public static PageDomain getPageDomain() + { + PageDomain pageDomain = new PageDomain(); + pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1)); + pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10)); + pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN)); + pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC)); + pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE)); + return pageDomain; + } + + public static PageDomain buildPageRequest() + { + return getPageDomain(); + } +} diff --git a/src/main/java/com/zzlh/es/security/auth/CustomAuthenticationEntryPoint.java b/src/main/java/com/zzlh/es/security/auth/CustomAuthenticationEntryPoint.java new file mode 100644 index 0000000..b038546 --- /dev/null +++ b/src/main/java/com/zzlh/es/security/auth/CustomAuthenticationEntryPoint.java @@ -0,0 +1,33 @@ +package com.zzlh.es.security.auth; + + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +/** + * 描述:访问未授权资源处理 + * + * + * @author soeasy*/ +@Component +public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { + @Override + public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { + httpServletResponse.setContentType("application/json;charset=utf-8"); + PrintWriter out = httpServletResponse.getWriter(); + if(e.getMessage().contains("Bad credentials")){ + out.write("{\"status\":\"error\",\"msg\":\"用户名或密码错误\"}"); + }else{ + out.write("{\"status\":\"error\",\"msg\":\"请登录\"}"); + } + out.flush(); + out.close(); + } +} diff --git a/src/main/java/com/zzlh/es/security/auth/CustomUserDetails.java b/src/main/java/com/zzlh/es/security/auth/CustomUserDetails.java new file mode 100644 index 0000000..bf0bb1f --- /dev/null +++ b/src/main/java/com/zzlh/es/security/auth/CustomUserDetails.java @@ -0,0 +1,52 @@ +package com.zzlh.es.security.auth; + + +import com.zzlh.es.entity.TUser; +import lombok.Data; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; + +/** + * 描述:自定义UserDetails,使UserDetails具有TUser的实体结构 + * + + * + * @author soeasy*/ +@Data +public class CustomUserDetails extends TUser implements UserDetails { + public CustomUserDetails(TUser tUser){ + if(null != tUser){ + this.setId(tUser.getId()); + this.setUsername(tUser.getUsername()); + this.setPassword(tUser.getPassword()); + this.setState(tUser.getState()); + } + } + + @Override + public Collection getAuthorities() { + return null; + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } +} diff --git a/src/main/java/com/zzlh/es/security/auth/CustomUserDetailsService.java b/src/main/java/com/zzlh/es/security/auth/CustomUserDetailsService.java new file mode 100644 index 0000000..97bd72b --- /dev/null +++ b/src/main/java/com/zzlh/es/security/auth/CustomUserDetailsService.java @@ -0,0 +1,39 @@ +package com.zzlh.es.security.auth; + + +import com.zzlh.es.entity.TUser; +import com.zzlh.es.service.TUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Component; + +/** + * 描述:自定义UserDetailsService,从数据库读取用户信息,实现登录验证 + * + + * + * @author soeasy*/ +@Component +public class CustomUserDetailsService implements UserDetailsService { + @Autowired + private TUserService userService; + + /** + * 认证过程中 - 根据登录信息获取用户详细信息 + * + * @param s 登录用户输入的用户名 + * @return + * @throws UsernameNotFoundException + */ + @Override + public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { + //根据用户输入的用户信息,查询数据库中已注册用户信息 + TUser user = userService.findByName(s); + //如果用户不存在直接抛出UsernameNotFoundException异常 + if (user == null) throw new UsernameNotFoundException("用户名为" + s + "的用户不存在"); + + return new CustomUserDetails(user); + } +} diff --git a/src/main/java/com/zzlh/es/service/GeoServer.java b/src/main/java/com/zzlh/es/service/GeoServer.java new file mode 100644 index 0000000..c09b312 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/GeoServer.java @@ -0,0 +1,528 @@ +package com.zzlh.es.service; + +import com.zzlh.es.entity.vo.PartFileVo; +import com.zzlh.es.entity.vo.StyleDataVo; +import com.zzlh.es.webupload.util.FileUploadConfig; +import it.geosolutions.geoserver.rest.GeoServerRESTManager; +import it.geosolutions.geoserver.rest.GeoServerRESTPublisher; +import it.geosolutions.geoserver.rest.GeoServerRESTReader; +import it.geosolutions.geoserver.rest.decoder.RESTDataStore; +import it.geosolutions.geoserver.rest.decoder.RESTLayer; +import it.geosolutions.geoserver.rest.decoder.RESTStyleList; +import it.geosolutions.geoserver.rest.encoder.GSAbstractStoreEncoder; +import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder; +import it.geosolutions.geoserver.rest.encoder.datastore.GSPostGISDatastoreEncoder; +import it.geosolutions.geoserver.rest.encoder.feature.GSFeatureTypeEncoder; +import it.geosolutions.geoserver.rest.manager.GeoServerRESTStoreManager; +import org.apache.commons.httpclient.NameValuePair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.FileNotFoundException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class GeoServer { + + private static Logger logger = LoggerFactory.getLogger(GeoServer.class); + + + @Autowired + private FileUploadConfig fileUploadConfig; + /** + * geoServer配置 + */ + public static String url; + + private static String geoUsername; + + private static String geoPassword; + + //待发布矢量图层的工作区间 + public static String shpWorkspace; + + //待发布矢量图层的数据储存 + public static String shpStorename; + + //待发布影像图层的工作空间 + public static String imageWorkspace; + + public static String stylePath; + + @Value("${geoserver.url}") + public void setUrl(String url) { + GeoServer.url = url; + } + + @Value("${geoserver.username}") + public void setGeoUsername(String geoUsername) { + GeoServer.geoUsername = geoUsername; + } + + @Value("${geoserver.password}") + public void setGeoPassword(String geoPassword) { + GeoServer.geoPassword = geoPassword; + } + + @Value("${geoserver.shpworkspace}") + public void setShpWorkspace(String shpWorkspace) { + GeoServer.shpWorkspace = shpWorkspace; + } + + @Value("${geoserver.shpstorename}") + public void setShpStorename(String shpStorename) { + GeoServer.shpStorename = shpStorename; + } + + @Value("${geoserver.imageworkspace}") + public void setImageWorkspace(String imageWorkspace) { + GeoServer.imageWorkspace = imageWorkspace; + } + + @Value("${localdir.style}") + public void setStylePath(String stylePath) { + GeoServer.stylePath = stylePath; + } + + /** + * 判断工作区(workspace)是否存在,不存在则创建 + */ + public Boolean judgeWorkSpace(String workspace){ + try { + URL u = new URL(url); + GeoServerRESTManager manager = new GeoServerRESTManager(u, geoUsername, geoPassword); + GeoServerRESTPublisher publisher = manager.getPublisher(); + List workspaces = manager.getReader().getWorkspaceNames(); + if (!workspaces.contains(workspace)) { + boolean createWorkspace = publisher.createWorkspace(workspace); + logger.info("create workspace : " + createWorkspace); + return createWorkspace; + } else { + logger.info("workspace已经存在了,workspace :" + workspace); + return true; + } + }catch (MalformedURLException e) { + e.printStackTrace(); + } + return false; + } + + /** + * 判断存储是否存在 + * @param store 存储名 + * @return boolean + */ + public static boolean shpJudgeDatabase(String store) { + try { + URL u = new URL(url); + GeoServerRESTManager manager = new GeoServerRESTManager(u, geoUsername, geoPassword); + GeoServerRESTPublisher publisher = manager.getPublisher(); + RESTDataStore restStore = manager.getReader().getDatastore(shpWorkspace, store); + if (restStore == null) { + logger.info("数据存储不存在,可以创建!"); + return true; + } else { + logger.info("数据存储已经存在了,store:" + store); + } + + } catch (MalformedURLException e) { + e.printStackTrace(); + } + return false; + } + + + /** + * 方法一 + * 直接发布shp文件到geoServer + * 将shp.zip通过http传递过去 + * 不主动设置样式和编码 + *

+ * + * @param fileUrl 本地文件地址 zip格式 + * @param geocode 地理编码 + * @return boolean + */ + public static boolean releaseShpByHttp(String fileUrl, String geocode) { + try { + File zipFile = new File(fileUrl); + //存储名/图层名 +// String storeName = FileUtil.getFileNameNoEx(zipFile.getName()); + String storeName = zipFile.getName(); + GeoServerRESTReader reader = new GeoServerRESTReader(url, geoUsername, geoPassword); + GeoServerRESTPublisher publisher = new GeoServerRESTPublisher(url, geoUsername, geoPassword); + + RESTLayer layer = reader.getLayer(shpWorkspace, storeName); + if (layer == null) { + if (publisher.publishShp(shpWorkspace, storeName, storeName, zipFile, geocode)) { + logger.info("图层发布成功:" + storeName); + return true; + } else { + logger.info("图层发布失败:" + storeName); + } + } else { + logger.info("图层已经发布过了:" + storeName); + } + } catch (Exception e) { + e.printStackTrace(); + logger.error(e.getMessage()); + } + return false; + + } + + + /** + * 方法二 + * 向geoServer上传shp,并设置存储、图层名、样式和坐标系 + * + * @param zipFilePath 压缩文件夹位置 完整文件地址 + * @param storeName 存储、图层名 英文 + * @param styleType 图层样式 shp工作空间下的对应样式 + * @param coordinateSystem 坐标系 EPSG:4326 + * @return boolean + */ + public boolean publishShp(String zipFilePath, String storeName, String styleType, String coordinateSystem) { + if (coordinateSystem == null) { + coordinateSystem = GeoServerRESTPublisher.DEFAULT_CRS; + } + try { + //创建发布类,放入用户名密码和url + GeoServerRESTPublisher geoServerRESTPublisher = new GeoServerRESTPublisher(url, geoUsername, geoPassword); + boolean b = geoServerRESTPublisher.publishShp(shpWorkspace, storeName, + new NameValuePair[]{new NameValuePair("charset", "GBK")}, + //图层名称 指定用于发布资源的方法 + storeName, GeoServerRESTPublisher.UploadMethod.FILE, + //zip图集的地址,直接压缩不要文件夹 坐标系 样式 + new File(zipFilePath).toURI(), coordinateSystem, styleType); + if (b) { + return true; + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + return false; + } + + + /** + * 判断图层是否已经存在,不存在则创建并发布 + * @param workspace 工作区 + * @param storeName 数据存储 + * @param tableName 表名 + * @param spaceType 坐标系 EPSG:4326 + */ + public Boolean addLayer(String workspace,String storeName,String tableName,String style,String spaceType){ + if(workspace == null){ + workspace = shpWorkspace; + } + if(StringUtils.isEmpty(storeName)){ + storeName = shpStorename; + } + try { + GeoServerRESTManager geoServerRESTManager = new GeoServerRESTManager(new URL(url), geoUsername, geoPassword); + GeoServerRESTPublisher geoServerRESTPublisher = geoServerRESTManager.getPublisher(); + GeoServerRESTReader geoServerRESTReader=geoServerRESTManager.getReader(); + RESTDataStore restStore =geoServerRESTReader.getDatastore(shpWorkspace, storeName); + if (restStore == null) { + GSPostGISDatastoreEncoder store = new GSPostGISDatastoreEncoder(storeName); + store.setHost("localhost"); + store.setPort(5432); + store.setUser("postgres"); + store.setPassword("123456"); + store.setDatabase("postgres"); + store.setSchema("public"); + store.setConnectionTimeout(300); + store.setMaxConnections(20); + store.setMinConnections(1); + store.setExposePrimaryKeys(true); + boolean isCreateStore = geoServerRESTManager.getStoreManager().create(shpWorkspace, store); + } + // URL u = new URL(url); + //GeoServerRESTManager manager = new GeoServerRESTManager(u, geoUsername, geoPassword); + RESTLayer layer = geoServerRESTReader.getLayer(shpWorkspace, tableName); + GSFeatureTypeEncoder pds = new GSFeatureTypeEncoder(); + System.out.println(pds.toString()); + pds.setTitle(tableName); + pds.setName(tableName); + pds.setSRS(spaceType); + pds.setDescription(tableName); + GSLayerEncoder layerEncoder = new GSLayerEncoder(); + if (!StringUtils.isEmpty(style)){ + layerEncoder.setDefaultStyle(shpWorkspace,style); + } + if(layer == null){//图层不存在 + boolean b = geoServerRESTPublisher.unpublishFeatureType(shpWorkspace, storeName, tableName); + geoServerRESTPublisher.removeLayer(shpWorkspace,tableName); + boolean publish = geoServerRESTPublisher.publishDBLayer(shpWorkspace, storeName, pds, layerEncoder); + System.out.println("图层发布publish : " + publish); + return publish; + }else { + + geoServerRESTPublisher.unpublishFeatureType(shpWorkspace, storeName, tableName); + geoServerRESTPublisher.removeLayer(shpWorkspace,tableName); + boolean publish = geoServerRESTPublisher.publishDBLayer(shpWorkspace, storeName, pds, layerEncoder); + System.out.println("图层发布publish : " + publish); + return publish; + } + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + public Boolean removeLayer(String tableName) throws Exception{ + GeoServerRESTManager geoServerRESTManager = new GeoServerRESTManager(new URL(url), geoUsername, geoPassword); + GeoServerRESTPublisher geoServerRESTPublisher = geoServerRESTManager.getPublisher(); + geoServerRESTPublisher.unpublishFeatureType(shpWorkspace, shpStorename, tableName); + boolean b = geoServerRESTPublisher.removeLayer(shpWorkspace, tableName); + return b; + } + + public Map getLayer( String tableName, String spaceType) throws Exception{ + String[] split = spaceType.split(":"); + // String substring = spaceType.substring(spaceType.length() - 4); + String rootUrl = url + "/gwc/service/tms/1.0.0/"+shpWorkspace+":"+tableName+"@EPSG:"+split[1]+"@"; + String[] formats = {"pbf","utfgrid","png","jpeg","geojson","topojson"}; + List stringList = new ArrayList<>(); + for(int i=0;istyleNamestyleNamenameSingle symbol"; + String end = "strokeColorstrokeWidthbevel"; + String xml = "fillColorfillOpacity"; + String styleName = head.replaceAll("styleName", styleDataVo.getStyleName()); + String s = end.replaceAll("strokeColor", styleDataVo.getStrokeColor()).replaceAll("strokeWidth", styleDataVo.getStrokeWidth()); + String publishStyle = ""; + if (styleDataVo.getType()==1){ + publishStyle = styleName + s; + }else if (styleDataVo.getType()==2){ + String s1 = xml.replaceAll("fillColor", styleDataVo.getFillColor()).replaceAll("fillOpacity", styleDataVo.getFillOpacity()); + publishStyle = styleName + s1 + s; + } + boolean flag = false; + try { + URL u = new URL(url); + GeoServerRESTManager manager = new GeoServerRESTManager(u, geoUsername, geoPassword); + flag = manager.getStyleManager().publishStyleInWorkspace(shpWorkspace, publishStyle, styleDataVo.getStyleName()); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + return flag; + } + + + public Boolean updateLayerStyle(StyleDataVo styleDataVo){ + String head = "styleNamestyleNamenameSingle symbol"; + String end = "strokeColorstrokeWidthbevel"; + String xml = "fillColorfillOpacity"; + String styleName = head.replaceAll("styleName", styleDataVo.getStyleName()); + String s = end.replaceAll("strokeColor", styleDataVo.getStrokeColor()).replaceAll("strokeWidth", styleDataVo.getStrokeWidth()); + String publishStyle = ""; + if (styleDataVo.getType()==1){ + publishStyle = styleName + s; + }else if (styleDataVo.getType()==2){ + String s1 = xml.replaceAll("fillColor", styleDataVo.getFillColor()).replaceAll("fillOpacity", styleDataVo.getFillOpacity()); + publishStyle = styleName + s1 + s; + } + boolean flag = false; + try { + URL u = new URL(url); + GeoServerRESTManager manager = new GeoServerRESTManager(u, geoUsername, geoPassword); + flag = manager.getStyleManager().updateStyleInWorkspace(shpWorkspace, publishStyle, styleDataVo.getStyleName()); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + return flag; + } + + public Map deleteLayerStyle(String styleName){ + Map map = new HashMap(); + try { + URL u = new URL(url); + GeoServerRESTManager manager = new GeoServerRESTManager(u, geoUsername, geoPassword); + boolean pingyuan = manager.getStyleManager().removeStyleInWorkspace(shpWorkspace, styleName); + map.put("result",pingyuan); + map.put("code",200); + map.put("msg","删除成功"); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + return map; + } + /** + * 删除图层 + * @param workspace 工作区 + * @param layerName 图层名 + * @return + */ + public Boolean removeLayer(String workspace, String layerName){ + try { + URL u = new URL(url); + GeoServerRESTManager manager = new GeoServerRESTManager(u, geoUsername, geoPassword); + RESTLayer layer = manager.getReader().getLayer(workspace, layerName); + if(layer != null){ + boolean removeLayer = manager.getPublisher().removeLayer(workspace, layerName); + return removeLayer; + }else{ + System.out.println("图层不存在, layer: " + layerName); + } + } catch (MalformedURLException e) { + e.printStackTrace(); + } + return false; + } + + + /** + * 上传图层样式文件到geoServer,sld文件 + * 需要放入指定文件夹下 + * + * @param partFileVo 样式文件名(不包含sld后缀) + * @return boolean + */ + public boolean publishStyle(PartFileVo partFileVo) { + try { + MultipartFile file1 = partFileVo.getFile(); + String originalFilename = file1.getOriginalFilename(); + if (!"sld".equals(originalFilename.substring(originalFilename.lastIndexOf(".")+1))){ + return false; + } + String uploadFolder = fileUploadConfig.getUploadFolder()+fileUploadConfig.getArchivesFilePath(); + File folder = new File(uploadFolder); + if (!folder.exists()) { + folder.mkdirs(); + } + String fileName = "YS"+System.currentTimeMillis()+".sld"; + String absolutePath = uploadFolder + fileName; + file1.transferTo(new File(absolutePath)); + URL u = new URL(url); + GeoServerRESTManager manager = new GeoServerRESTManager(u, geoUsername, geoPassword); + GeoServerRESTReader reader = manager.getReader(); + GeoServerRESTPublisher publisher = manager.getPublisher(); + //读取style文件 + //String styleFile = stylePath + File.separator + styleType + ".sld"; + File file = new File(absolutePath); + //是否已经发布了改style + if (!reader.existsStyle(shpWorkspace, partFileVo.getStyleName())) { + publisher.publishStyleInWorkspace(shpWorkspace, file, partFileVo.getStyleName()); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + + /** + * 删除指定的数据存储 + * + * @param workspace 工作区 + * @param storeName 数据存储 + * @return boolean + */ + public boolean removeStore(String workspace, String storeName) { + URL u = null; + try { + u = new URL(url); + GeoServerRESTManager manager = new GeoServerRESTManager(u, geoUsername, geoPassword); + GeoServerRESTStoreManager storeManager = manager.getStoreManager(); + GSAbstractStoreEncoder gsAbstractStoreEncoder; +// manager.getPublisher().removeWorkspace(); + if (shpWorkspace.equals(workspace)) { + gsAbstractStoreEncoder = new GSAbstractStoreEncoder(GeoServerRESTPublisher.StoreType.DATASTORES, storeName) { + @Override + protected String getValidType() { + return null; + } + }; + gsAbstractStoreEncoder.setName(storeName); + return storeManager.remove(workspace, gsAbstractStoreEncoder, true); + } + + if (imageWorkspace.equals(workspace)) { + gsAbstractStoreEncoder = new GSAbstractStoreEncoder(GeoServerRESTPublisher.StoreType.COVERAGESTORES, storeName) { + @Override + protected String getValidType() { + return null; + } + }; + gsAbstractStoreEncoder.setName(storeName); + return storeManager.remove(workspace, gsAbstractStoreEncoder, true); + } + + } catch (MalformedURLException e) { + e.printStackTrace(); + } + return false; + } + public String downloadShpZip(Integer count,String tableName){ + String downUrl = url+ "/ksp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=ksp:"+tableName+"&maxFeatures="+count+"&outputFormat=SHAPE-ZIP"; + return downUrl; + } + + public static void main(String[] args) { + GSFeatureTypeEncoder pds = new GSFeatureTypeEncoder(); + pds.setTitle("abc"); + pds.setName("abc"); + pds.setSRS("4326"); + pds.setDescription("abc"); + GSLayerEncoder layerEncoder = new GSLayerEncoder(); + System.out.println(pds.toString()); + System.out.println(layerEncoder.toString()); + } +} + diff --git a/src/main/java/com/zzlh/es/service/GeoWebCache.java b/src/main/java/com/zzlh/es/service/GeoWebCache.java new file mode 100644 index 0000000..9ae9a91 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/GeoWebCache.java @@ -0,0 +1,230 @@ +package com.zzlh.es.service; + +import com.alibaba.fastjson2.JSONArray; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.StatusLine; +import org.apache.http.util.EntityUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.IOException; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.toilelibre.libe.curl.Curl.curl; + +@Component +public class GeoWebCache { + + private static String url; + private static String geoUsername; + private static String geoPassword; + //待发布矢量图层的工作区间 + public static String shpWorkspace; //待发布影像图层的工作空间 + public static String imageWorkspace; + + @Value("${geoserver.url}") + public void setUrl(String url) { + GeoWebCache.url = url; + } + + @Value("${geoserver.username}") + public void setGeoUsername(String geoUsername) { + GeoWebCache.geoUsername = geoUsername; + } + + @Value("${geoserver.password}") + public void setGeoPassword(String geoPassword) { + GeoWebCache.geoPassword = geoPassword; + } + + @Value("${geoserver.shpworkspace}") + public void setShpWorkspace(String shpWorkspace) { + GeoWebCache.shpWorkspace = shpWorkspace; + } + + @Value("${geoserver.imageworkspace}") + public void setImageWorkspace(String imageWorkspace) { + GeoWebCache.imageWorkspace = imageWorkspace; + } + + public static void main(String[] args) throws Exception{ +// String xmlString = "Tom18"; +// +// // 创建DocumentBuilderFactory对象 +// DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); +// // 创建DocumentBuilder对象 +// DocumentBuilder builder = factory.newDocumentBuilder(); +// // 解析xml字符串,得到Document对象 +// Document doc = builder.parse(new InputSource(new StringReader(xmlString))); +// +// // 获取根节点 +// Element root = doc.getDocumentElement(); +// +// // 遍历子节点 +// NodeList personList = root.getElementsByTagName("person"); +// for (int i = 0; i < personList.getLength(); i++) { +// Node personNode = personList.item(i); +// if (personNode.getNodeType() == Node.ELEMENT_NODE) { +// Element personElement = (Element) personNode; +// // 获取name节点的值 +// String name = personElement.getElementsByTagName("name").item(0).getTextContent(); +// // 获取age节点的值 +// String age = personElement.getElementsByTagName("age").item(0).getTextContent(); +// System.out.println("name: " + name + ", age: " + age); +// } +// } + String cmd = "curl -u " + "admin" + ":" + "Hopetry@A1406" + " -X DELETE http://123.132.248.154:9235/geoserver/rest/workspaces/ksp/datastores/ksp_shp/featuretypes/shp_1692064004 -H "+ "\"accept: application/json\""+ " -H "+ "\"content-type: application/json\""; + //String cmd = "curl -u " + "admin" + ":" + "Hopetry@A1406" + " -X DELETE " + "http://123.132.248.154:9235/geoserver" + "/rest/"+"ksp/datastores/ksp_shp/featuretypes/shp_1692064004"; + HttpResponse curl = curl(cmd); + HttpEntity entity = curl.getEntity(); + System.out.println(entity.toString()); + } + + /** + * 获取geoWebCache中的图层 * 并按shp和image 分类 * * @return Map + */ + public static Map> getLayers(String layerName) { + Map> map = new HashMap(); + String cmd = "curl -u " + geoUsername + ":" + geoPassword + " \"" + url + "/gwc/rest/layers/"+shpWorkspace+":"+layerName+".xml\""; + List shp = new ArrayList<>(); + List image = new ArrayList<>(); + HttpResponse curl = curl(cmd); + HttpEntity entity = curl.getEntity(); + if (entity != null) { + String result = null; + try { + result = EntityUtils.toString(entity, "UTF-8"); + String[] split = result.split(""); + String s1 = split[0] + "\n" + + "application/json;type=geojson\n" + + " application/json;type=topojson\n" + + "application/vnd.mapbox-vector-tile\n" + + " application/json;type=utfgrid" + split[1]; + System.out.println("--------------------------"); + System.out.println(result); +// DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); +// // 创建DocumentBuilder对象 +// DocumentBuilder builder = factory.newDocumentBuilder(); +// // 解析xml字符串,得到Document对象 +// Document doc = builder.parse(new InputSource(new StringReader(result))); +// System.out.println(doc.toString()); + // 获取根节点 + +// +// Element root = doc.getDocumentElement(); +// NodeList geoServerLayer1 = root.getElementsByTagName("mimeFormats"); +// Element item1 =(Element) geoServerLayer1.item(0); +// NodeList string = item1.getElementsByTagName("string"); +// for (int i = 0; i < string.getLength(); i++) { +// Node item = string.item(i); +// String nodeName = item.getTextContent(); +// +// System.out.println(nodeName); +// } +// JSONObject jsonObject = JSONObject.parseObject(result); +// System.out.println(jsonObject.toString()); +// JSONObject geoServerLayer = jsonObject.getJSONObject("GeoServerLayer"); +// JSONArray mimeFormats = geoServerLayer.getJSONArray("mimeFormats"); +// mimeFormats.remove(0); +// geoServerLayer.put("mimeFormats",mimeFormats); +// jsonObject.put("GeoServerLayer",geoServerLayer); +//// JSONArray jsonArray = JSONArray.from(result); +// for (Object o : jsonArray) { +// String str = o.toString(); +// String str1 = str.substring(0, str.indexOf(":")); +// if ("shp".equals(str1)) { +// shp.add(str); +// } +// if ("image".equals(str1)) { +// image.add(str); +// } +// } +// ObjectMapper jsonMapper = new ObjectMapper(); +// JsonNode rootNode = jsonMapper.readTree(jsonObject.toString()); +// XmlMapper xmlMapper = new XmlMapper(); +// xmlMapper.enable(SerializationFeature.INDENT_OUTPUT); +// String xmlString = xmlMapper.writeValueAsString(rootNode); +// +// System.out.println(jsonObject.toString()); + String cmd1 = "curl -u " + geoUsername + ":" + geoPassword +" -X POST -H \"Content-type: application/xml\" "+ "\"" + url + "/gwc/rest/layers/"+shpWorkspace+":"+layerName+"\" " + "-d" +" '"+s1+"'"; + HttpResponse curl1 = curl(cmd1); + HttpEntity entity1 = curl1.getEntity(); + String s = EntityUtils.toString(entity1, "UTF-8"); + map.put("shp", shp); + map.put("image", image); + } catch (Exception e) { + e.printStackTrace(); + } + } + return map; + } + + /** + * 指定图层进行切片操作 * * @param layer 指定图层 shp:test * @param zoomStart 1 切片开始层级 * @param zoomStop 15 切片结束层级 * @return boolean + */ + public static boolean slice(String layer, int zoomStart, int zoomStop) { + int threadCount = 2; + String res = ""; + String cmd = "curl -u " + geoUsername + ":" + geoPassword + " -XPOST -H \"Content-type: text/xml\" -d '" + layer + "4326" + zoomStart + "" + zoomStop + "image/png" + layer + "" + threadCount + "' \"" + url + "/gwc/rest/seed/" + layer + ".xml\""; + HttpResponse curl = curl(cmd); + StatusLine statusLine = curl.getStatusLine(); + return "HTTP/1.1 200 ".equals(statusLine.toString()); + } + + /** + * 获取切片的情况 * * @param layer 指定图层 * @return Map + */ + public static Map getSliceType(String layer) { + Map map = new HashMap(); + //返回所有图层切片情况 curl -u : -XGET http://localhost:8080/geoserver/gwc/rest/seed.json //返回指定图层的切片情况 + String cmd = "curl -u " + geoUsername + ":" + geoPassword + " -XGET " + url + "/gwc/rest/seed/" + layer + ".json"; + HttpResponse curl = curl(cmd); + StatusLine statusLine = curl.getStatusLine(); + if ("HTTP/1.1 200 ".equals(statusLine.toString())) { + HttpEntity entity = curl.getEntity(); + try { + String result = EntityUtils.toString(entity, "UTF-8"); + System.out.println(result); + JSONArray jsonArray = JSONArray.from(result); + map.put("res", jsonArray); + } catch (IOException e) { + e.printStackTrace(); + } + } + return map; + } + + /** + * 停止所有正在进行的切片任务 * * @return boolean + */ + public static boolean stopAllSlice() { + String cmd = "curl -u " + geoUsername + ":" + geoPassword + " -d \"kill_all=all\" \"" + url + "/gwc/rest/seed\""; + HttpResponse curl = curl(cmd); + StatusLine statusLine = curl.getStatusLine(); + return "HTTP/1.1 200 ".equals(statusLine.toString()); + } + + /** + * 停止指定图层的切片任务 * * @return boolean + */ + public static boolean stopSliceByLayer(String layer) { + String cmd = "curl -u " + geoUsername + ":" + geoPassword + " -d \"kill_all=all\" \"" + url + "/gwc/rest/seed/" + layer + "\""; + HttpResponse curl = curl(cmd); + StatusLine statusLine = curl.getStatusLine(); + return "HTTP/1.1 200 ".equals(statusLine.toString()); + } + + +} diff --git a/src/main/java/com/zzlh/es/service/IApplicationDataService.java b/src/main/java/com/zzlh/es/service/IApplicationDataService.java new file mode 100644 index 0000000..a9d5a70 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/IApplicationDataService.java @@ -0,0 +1,36 @@ +package com.zzlh.es.service; + +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.ApplicationData; +import com.zzlh.es.entity.DataStore; +import com.zzlh.es.entity.ProjectDataRelation; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + *

+ * 服务类 + *

+ * + * @author wyl + * @since 2023_04_06 + */ +public interface IApplicationDataService { + + AjaxResult createApplication(ApplicationData applicationData); + + AjaxResult createProject(ProjectDataRelation projectDataRelation); + + List getAllApplication(); + + AjaxResult getApplicationById(Integer id); + + List getServerByType(String spaceType); + + AjaxResult addServer(ProjectDataRelation projectDataRelation); + + AjaxResult deleteIds(int[] ids); + + AjaxResult getProjectName(Integer id); +} diff --git a/src/main/java/com/zzlh/es/service/IDataStoreService.java b/src/main/java/com/zzlh/es/service/IDataStoreService.java new file mode 100644 index 0000000..873662b --- /dev/null +++ b/src/main/java/com/zzlh/es/service/IDataStoreService.java @@ -0,0 +1,68 @@ +package com.zzlh.es.service; + + + +import com.zzlh.es.entity.DataStore; + +import java.util.List; +import java.util.Map; + +/** + * 图层存储表Service接口 + * + * @author LGD + * @date 2023-03-27 + */ +public interface IDataStoreService +{ + /** + * 查询图层存储表 + * + * @param id 图层存储表主键 + * @return 图层存储表 + */ + public DataStore selectDataStoreById(Long id); + + /** + * 查询图层存储表列表 + * + * @param dataStore 图层存储表 + * @return 图层存储表集合 + */ + public List selectDataStoreList(DataStore dataStore); + + /** + * 新增图层存储表 + * + * @param dataStore 图层存储表 + * @return 结果 + */ + public int insertDataStore(DataStore dataStore); + + /** + * 修改图层存储表 + * + * @param dataStore 图层存储表 + * @return 结果 + */ + public int updateDataStore(DataStore dataStore); + + /** + * 批量删除图层存储表 + * + * @param ids 需要删除的图层存储表主键集合 + * @return 结果 + */ + public int deleteDataStoreByIds(Long[] ids); + + /** + * 删除图层存储表信息 + * + * @param id 图层存储表主键 + * @return 结果 + */ + public int deleteDataStoreById(Integer id) throws Exception; + + + public List selectDataStoreListByTableName(String tableName); +} diff --git a/src/main/java/com/zzlh/es/service/IProjectDataRelationMarsService.java b/src/main/java/com/zzlh/es/service/IProjectDataRelationMarsService.java new file mode 100644 index 0000000..20d5778 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/IProjectDataRelationMarsService.java @@ -0,0 +1,44 @@ +package com.zzlh.es.service; + +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.ProjectDataRelationMars; +import com.baomidou.mybatisplus.extension.service.IService; +import org.aspectj.weaver.loadtime.Aj; + +/** + *

+ * 服务类 + *

+ * + * @author wyl + * @since 2023-05-19 + */ +public interface IProjectDataRelationMarsService extends IService { + /** + * 创建项目组火星 + * @param projectDataRelationMars + * @return + */ + AjaxResult createMars(ProjectDataRelationMars projectDataRelationMars); + + /** + * 项目组添加图层服务 + * @param projectDataRelationMars + * @return + */ + AjaxResult addMarsServer(ProjectDataRelationMars projectDataRelationMars); + + AjaxResult getTree(String areaName); + + AjaxResult deleteIds(int[] ids); + + AjaxResult getProjectName(String areaName); + + AjaxResult findStyleById(Long id); + + AjaxResult updateStyle(Long id, String style,String type,String updateStyle,String properties,Integer sort); + + AjaxResult getTableName(Long id); + + AjaxResult getApplicationTree(String areaName); +} diff --git a/src/main/java/com/zzlh/es/service/IStyleImageService.java b/src/main/java/com/zzlh/es/service/IStyleImageService.java new file mode 100644 index 0000000..df3e563 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/IStyleImageService.java @@ -0,0 +1,25 @@ +package com.zzlh.es.service; + +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.StyleImage; +import com.baomidou.mybatisplus.extension.service.IService; + +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +/** + *

+ * 服务类 + *

+ * + * @author wyl + * @since 2023-04-12 + */ +public interface IStyleImageService extends IService { + + AjaxResult uploadStyleImage(HttpServletRequest request)throws IOException; + + AjaxResult getAllStyleImage(); + + AjaxResult deleteIds(int[] ids); +} diff --git a/src/main/java/com/zzlh/es/service/IStyleRecordService.java b/src/main/java/com/zzlh/es/service/IStyleRecordService.java new file mode 100644 index 0000000..9507508 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/IStyleRecordService.java @@ -0,0 +1,63 @@ +package com.zzlh.es.service; + +import com.zzlh.es.entity.StyleRecord; + +import java.util.List; + + +/** + * 样式Service接口 + * + * @author lgd + * @date 2023-08-09 + */ +public interface IStyleRecordService +{ + /** + * 查询样式 + * + * @param styleName 样式主键 + * @return 样式 + */ + public StyleRecord selectStyleRecordByStyleName(String styleName); + + /** + * 查询样式列表 + * + * @param styleRecord 样式 + * @return 样式集合 + */ + public List selectStyleRecordList(StyleRecord styleRecord); + + /** + * 新增样式 + * + * @param styleRecord 样式 + * @return 结果 + */ + public int insertStyleRecord(StyleRecord styleRecord); + + /** + * 修改样式 + * + * @param styleRecord 样式 + * @return 结果 + */ + public int updateStyleRecord(StyleRecord styleRecord); + + /** + * 批量删除样式 + * + * @param styleNames 需要删除的样式主键集合 + * @return 结果 + */ + public int deleteStyleRecordByStyleNames(String[] styleNames); + + /** + * 删除样式信息 + * + * @param styleName 样式主键 + * @return 结果 + */ + public int deleteStyleRecordByStyleName(String styleName); +} diff --git a/src/main/java/com/zzlh/es/service/IStyleServerMapboxService.java b/src/main/java/com/zzlh/es/service/IStyleServerMapboxService.java new file mode 100644 index 0000000..f4e244d --- /dev/null +++ b/src/main/java/com/zzlh/es/service/IStyleServerMapboxService.java @@ -0,0 +1,23 @@ +package com.zzlh.es.service; + +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.StyleServerMapbox; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 服务类 + *

+ * + * @author wyl + * @since 2023-04-08 + */ +public interface IStyleServerMapboxService extends IService { + boolean saveStyleServerMapbox(StyleServerMapbox styleServerMapbox); + + AjaxResult findStyleById(String serverName); + + AjaxResult updateStyle(StyleServerMapbox styleServerMapbox); + + AjaxResult getUrlByServerName(String serverName); +} diff --git a/src/main/java/com/zzlh/es/service/LayerService.java b/src/main/java/com/zzlh/es/service/LayerService.java new file mode 100644 index 0000000..1d00720 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/LayerService.java @@ -0,0 +1,1155 @@ +package com.zzlh.es.service; + + +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.poi.excel.BigExcelWriter; +import cn.hutool.poi.excel.ExcelUtil; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; +import com.alibaba.fastjson2.JSONObject; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.LineString; +import com.vividsolutions.jts.geom.MultiLineString; +import com.vividsolutions.jts.geom.MultiPolygon; +import com.vividsolutions.jts.io.WKBReader; +import com.vividsolutions.jts.io.WKTWriter; +import com.zzlh.es.entity.DataStore; +import com.zzlh.es.entity.StyleRecord; +import com.zzlh.es.entity.vo.PartFileVo; +import com.zzlh.es.entity.vo.StyleDataVo; +import com.zzlh.es.exception.BusinessException; +import com.zzlh.es.mapper.DataStoreMapper; +import com.zzlh.es.mapper.GeoServerDao; +import com.zzlh.es.utils.StringUtils; +import com.zzlh.es.utils.ZipUtil; +import org.apache.commons.io.FileUtils; +import org.apache.poi.ss.SpreadsheetVersion; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.geotools.data.FeatureSource; +import org.geotools.data.FeatureWriter; +import org.geotools.data.shapefile.ShapefileDataStore; +import org.geotools.data.shapefile.ShapefileDataStoreFactory; +import org.geotools.feature.FeatureCollection; +import org.geotools.feature.FeatureIterator; +import org.geotools.feature.simple.SimpleFeatureTypeBuilder; +import org.geotools.referencing.CRS; +import org.opengis.feature.Feature; +import org.opengis.feature.Property; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.feature.type.AttributeDescriptor; +import org.opengis.feature.type.AttributeType; +import org.opengis.filter.Filter; +import org.opengis.referencing.FactoryException; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.awt.*; +import java.io.*; +import java.lang.reflect.Field; +import java.nio.charset.Charset; +import java.util.List; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.zip.ZipOutputStream; + +import static org.geotools.data.Transaction.AUTO_COMMIT; + +@Service +public class LayerService { + + @Autowired + private GeoServerDao geoserverDao; + + @Resource + private GeoServer geoServer; + + @Autowired + private DataStoreMapper dataStoreMapper; + + @Autowired + private IStyleRecordService styleRecordService; + @Autowired + private IStyleServerMapboxService iStyleServerMapboxService; + @Autowired + private GeoWebCache geoWebCache; + @Value("${geoserver.path}") + private String path; + + @Value("${postGis.url}") + private String postUrl; + + @Value("${postGis.username}") + private String pgUsername; + + @Value("${postGis.password}") + private String pgPassword; + + @Value("${postGis.dbname}") + private String pgDbname; + + @Value("${postGis.shpfile}") + private String pgShpfile; + + @Value("${postGis.pgsqlexe}") + private String pgsqlExe; + + @Value("${postGis.shpfileZip}") + private String shpfileZip; + + @Value("${postGis.downLoadUrl}") + private String downLoadUrl; + + @Transactional + public Map addLayer(String filePath, String spaceType,String tableName) throws Exception { + File dir = new File(filePath); + File[] subFiles = dir.listFiles(); + String[] split = spaceType.split(":"); + String substring = split[1]; + String charset = "UTF-8"; + String dataType = ""; + if (null != subFiles) { + for (File subFile : subFiles) { + if (subFile.getName().endsWith(".cpg")) { + charset = ZipUtil.loadFileCharset(filePath + subFile.getName()); + } + if (subFile.getName().endsWith(".shp")) { + ShapefileDataStore shpDataStore = new ShapefileDataStore(subFile.toURI().toURL()); + shpDataStore.setCharset(Charset.forName(charset)); + // 获取地图要素 + FeatureSource featureSource = shpDataStore.getFeatureSource(); + //获取头属性信息 + List attributeDescriptors = featureSource.getSchema().getAttributeDescriptors(); + List> heads = new ArrayList<>(); + for (AttributeDescriptor a : attributeDescriptors) { + Map et = new HashMap<>(); +// System.out.println("字段名:"+a.getName()); + String name = a.getName().toString(); + if ("id".equals(name)||"ID".equals(name)||"Id".equals(name)||"iD".equals(name)){ + continue; + } + + + if ("is_del".equals(name.toLowerCase())){ + continue; + } + et.put("name", name); + AttributeType type = a.getType(); + Filter filter = type.getRestrictions().isEmpty() ? null : type.getRestrictions().get(0); + String typeLength = filter != null ? filter.toString() : "0"; + Pattern pattern = Pattern.compile("[^0-9]"); + Matcher matcher = pattern.matcher(typeLength); + String tLength = matcher.replaceAll("").trim(); +// System.out.println("类型长度:"+tLength); + et.put("length", Integer.parseInt(tLength) + 64); + + String className = type.getBinding().getName(); + String tName = className.substring(className.lastIndexOf(".") + 1); + System.out.println("字段类型:"+tName); + //转数据库类型MultiLineString + if (tName.equals("MultiPolygon")||tName.equals("MultiLineString")||tName.equals("Polygon")|| + tName.equals("Point")||tName.equals("LineString")||tName.equals("MultiPoint")) { + tName = "geometry"; + et.put("name", "geom"); + et.put("length", ""); + } +// else if (tName.equals("Integer")) { +// tName = "numeric"; +// et.put("length", tLength); +// } else if (tName.equals("Double")) { +// tName = "float4"; +// et.put("length", 0); +// } + else { + tName = "varchar"; + } +// System.out.println("字段类型转数据库类型后:"+tName); + et.put("type", tName); + heads.add(et); + } + //用shp文件名当表名 + //String tableName = subFile.getPath().substring(subFile.getPath().lastIndexOf("\\")+1); + //tableName = tableName.substring(0,tableName.lastIndexOf(".")); + //随机生成表名 + //String tableName = "shp_" + System.currentTimeMillis() / 1000; + Map result = new HashMap(); + //result.put("key","SHP_"+l); + //创建图层数据表序列 + geoserverDao.createSequence(tableName + "_temp"); +// //创建图层数据表 + geoserverDao.createTable(tableName + "_temp", heads); +// +// //获取数据 + FeatureIterator iterator = featureSource.getFeatures().features(); + while (iterator.hasNext()) { + SimpleFeature feature = iterator.next(); + feature.getName(); + Iterator it = feature.getProperties().iterator(); + LinkedHashMap data = new LinkedHashMap<>(); + String geometry = ""; + while (it.hasNext()) { + Property pro = it.next(); + if (pro.getValue() !=null){ + if ("id".equals((pro.getName().toString().toLowerCase()))){ + continue; + } + + if ("is_del".equals((pro.getName().toString().toLowerCase()))){ + continue; + } + if (pro.getValue() instanceof Point ||pro.getValue().toString().indexOf("POINT")>-1) {//点 + geometry = "'" + pro.getValue().toString() + "'"; + data.put("geom", geometry); + dataType = "点"; + } else if (pro.getValue() instanceof MultiPolygon||pro.getValue().toString().indexOf("MULTIPOLYGON")>-1) {//多面 + geometry = "'" + pro.getValue() + "'"; + data.put("geom", geometry); + dataType = "面"; + } else if (pro.getValue() instanceof Polygon||pro.getValue().toString().indexOf("POLYGON")>-1) {//面 + geometry = "'" +pro.getValue() + "'"; + data.put("geom", geometry); + dataType = "面"; + } else if (pro.getValue() instanceof MultiLineString||pro.getValue().toString().indexOf("MULTILINESTRING")>-1){ + geometry = "'" + pro.getValue() + "'"; + data.put("geom", geometry); + dataType = "线"; + }else if (pro.getValue() instanceof LineString||pro.getValue().toString().indexOf("LINESTRING")>-1) {//线 + geometry = "'" + pro.getValue() + "'"; + data.put("geom", geometry); + dataType = "线"; + } + else { + data.put(pro.getName().toString(), pro.getValue()==null?"":pro.getValue()); + }}else { + if ("id".equals((pro.getName().toString().toLowerCase()))){ + continue; + } + + if ("is_del".equals((pro.getName().toString().toLowerCase()))){ + continue; + } + data.put(pro.getName().toString(), ""); + } + } + + data.put("is_del", 0); +// //新增数据到图层数据表 + geoserverDao.addTableDateList(tableName + "_temp", heads, data, substring); +// +// //发布该图层 +//// Boolean addLayer = geoServer.addLayer(null,null,tableName,null); +//// if(!addLayer){ +//// throw new KspException(WebErrorCode.INTERNAL_PROCESS_ERROR, "发布数据图层失败", null, null); +//// } + } + result.put("heads", heads); + result.put("dataType", dataType); + result.put("tableName", tableName); + return result; + } + } + } + + return null; + } + + + @Transactional + public Map insertIntoData(Map map) throws Exception { + String dataType = map.get("dataType").toString(); + String serverName = map.get("serverName").toString(); + String tableName = map.get("tableName").toString(); + String refRelation = map.get("refRelation").toString(); + if(map.get("areaName")==null){ + throw new BusinessException(500,"登录已过期,请重新登录"); + } + String areaName = map.get("areaName").toString(); + String sName=geoserverDao.selectByName(serverName); + if(!StringUtils.isEmpty(sName)){ + throw new BusinessException(500,"当前服务名称已经存在,请更换名称"); + } + System.out.println("+++++++++++++++" + tableName); + String spaceType = map.get("spaceType").toString(); + String[] split = spaceType.split(":"); + String substring = split[1]; + String severType = map.get("severType").toString(); + List> newHeads = (List>) map.get("newHeads"); + geoserverDao.createSequence(tableName); + //创建图层数据表 + geoserverDao.createNewTable(tableName, newHeads); + List maps = geoserverDao.selectList(tableName + "_temp"); + for (Map map1 : maps) { + LinkedHashMap data = new LinkedHashMap<>(); + for (int i = 0; i < newHeads.size(); i++) { + Map stringObjectMap = newHeads.get(i); + String refName = stringObjectMap.get("refName").toString(); + String name = stringObjectMap.get("name").toString(); + + if ("is_del".equals(name.toLowerCase())){ + continue; + } + if ("geom".equals(name)) { + WKBReader wkbReader = new WKBReader(); + String wkb = map1.get(name).toString(); + Geometry geometry = wkbReader.read(WKBReader.hexToBytes(wkb)); + + // 转换为WKT字符串 + WKTWriter wktWriter = new WKTWriter(); + String wkt = wktWriter.write(geometry); + data.put(refName, wkt); + } else { + data.put(refName, map1.get(name.toLowerCase())); + } + + } + + data.put("is_del", 0); + //新增数据到图层数据表 + geoserverDao.addNewTableDateList(tableName, newHeads, data, substring); + } + + if (map.get("styleName")!=null){ + geoserverDao.addTableDataStore(tableName,serverName,spaceType,severType,"geoserver","shp",dataType,map.get("styleName").toString(),refRelation,areaName, JSON.toJSONString(newHeads)); + }else { + geoserverDao.addTableDataStore(tableName,serverName,spaceType,severType,"geoserver","shp",dataType,"",refRelation,areaName,JSON.toJSONString(newHeads)); + + } +// StyleServerMapbox styleServerMapbox = new StyleServerMapbox(); +// styleServerMapbox.setServerName(serverName); +// StyleParameterMapbox styleParameterMapbox = styleParameterMapboxMapper.getStyleByMapbox(); +// if (dataType.equals("点")) { +// styleServerMapbox.setSymbol(styleParameterMapbox.getSymbol().replaceFirst("symbol-id", UUID.randomUUID().toString().replace("-", ""))); +// } else if (dataType.equals("线")) { +// styleServerMapbox.setSymbol(styleParameterMapbox.getSymbol().replaceFirst("symbol-id", UUID.randomUUID().toString().replace("-", ""))); +// styleServerMapbox.setLine(styleParameterMapbox.getLine().replaceFirst("line-id", UUID.randomUUID().toString().replace("-", ""))); +// } else if (dataType.equals("面")) { +// styleServerMapbox.setSymbol(styleParameterMapbox.getSymbol().replaceFirst("symbol-id", UUID.randomUUID().toString().replace("-", ""))); +// styleServerMapbox.setLine(styleParameterMapbox.getLine().replaceFirst("line-id", UUID.randomUUID().toString().replace("-", ""))); +// styleServerMapbox.setFill(styleParameterMapbox.getFill().replaceFirst("fill-id", UUID.randomUUID().toString().replace("-", ""))); +// } +// if (!iStyleServerMapboxService.saveStyleServerMapbox(styleServerMapbox)) { +// throw new BusinessException("图层服务样式添加失败"); +// } + String tempTable = tableName + "_temp"; + int i = geoserverDao.selectTableCount(tempTable); + if (i > 0) geoserverDao.deleteTable(tempTable); + + int i1 = geoserverDao.selectSeqCount(tempTable + "_seq"); + if (i1 > 0) geoserverDao.deleteSequence(tempTable + "_seq"); + Map result = new HashMap(); + //发布该图层 +// Boolean addLayer = geoServer.addLayer("","",tableName,""); +// if(!addLayer){ +// throw new BaseException("发布图层失败!"); +// } + result.put("success", true); + result.put("msg", "保存成功"); + return result; + } + + @Transactional + public Map cancelSave(String tableName) { + String tempTable = tableName + "_temp"; + int i = geoserverDao.selectTableCount(tempTable); + if (i > 0) geoserverDao.deleteTable(tempTable); + int i1 = geoserverDao.selectSeqCount(tempTable + "_seq"); + if (i1 > 0) geoserverDao.deleteSequence(tempTable + "_seq"); + Map result = new HashMap(); + result.put("success", true); + result.put("msg", "取消成功"); + return result; + } + + @Transactional + public Map fileTransfer(MultipartFile multipartFile, String spaceType,String tableName) throws Exception { + long l = System.currentTimeMillis() / 1000; + String parsePath = "parseFile"+l+"\\"; + File filedir = new File(path +parsePath); + if (filedir.exists()) FileUtils.deleteDirectory(filedir); + FileUtils.forceMkdir(filedir); + File file = new File(path + multipartFile.getName() + ".zip"); + file.delete(); + FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file); + String unzip = ZipUtil.unzip1(path + multipartFile.getName() + ".zip", path + parsePath); + String abusolutePath = path + parsePath; + //if (StringUtils.isNotEmpty(unzip)) abusolutePath = path +parsePath + unzip + "\\"; + Map map = addLayer(abusolutePath, spaceType,tableName.toLowerCase()); + return map; + } + + public void addLayer(String tableName) { + Map map = geoserverDao.selectStyleName(tableName); + String styleName=""; + if(map.get("style_name")!=null){ + styleName=map.get("style_name").toString(); + } + String spaceType=map.get("space_type").toString(); + geoServer.addLayer(null,null,tableName,styleName,spaceType); + GeoWebCache.getLayers(tableName); + } + + public void addLayerLocal(String tableName) { + geoServer.addLayer(null,null,tableName,"","EPSG:4326"); + GeoWebCache.getLayers(tableName); + } + + public void publishLayer(Map param) { + Map map = geoserverDao.selectStyleName(param.get("tableName").toString()); + String spaceType=map.get("space_type").toString(); + geoServer.addLayer(null,null,param.get("tableName").toString(),param.get("styleName").toString(),spaceType); + GeoWebCache.getLayers(param.get("tableName").toString()); + } + public Map getLayer(String tableName, String spaceType) throws Exception { + return geoServer.getLayer(tableName, spaceType); + } + + public Map getLayerStyle(){ + return geoServer.getLayerStyle(); + } + + public Map getLayerStyles(){ + Map map = new HashMap(); + List styleRecords = styleRecordService.selectStyleRecordList(new StyleRecord()); + map.put("data",styleRecords); + map.put("code",200); + return map; + } + public String getGeomData(String tableName){ + return geoserverDao.selectGeomData(tableName); + } + public Map saveLayerStyle(StyleDataVo styleDataVo) { + Map map = new HashMap(); + Boolean aBoolean = geoServer.saveLayerStyle(styleDataVo); + if (aBoolean){ + StyleRecord styleRecord = new StyleRecord(); + styleRecord.setStyleName(styleDataVo.getStyleName()); + styleRecord.setFillColor(styleDataVo.getFillColor()); + styleRecord.setFillOpacity(styleDataVo.getFillOpacity()); + styleRecord.setType(styleDataVo.getType()); + styleRecord.setStrokeColor(styleDataVo.getStrokeColor()); + styleRecord.setStrokeWidth(Double.parseDouble(styleDataVo.getStrokeWidth())); + styleRecordService.insertStyleRecord(styleRecord); + } + map.put("result",aBoolean); + return map; + } + + public Map updateLayerStyle(StyleDataVo styleDataVo) { + Map map = new HashMap(); + Boolean aBoolean = geoServer.updateLayerStyle(styleDataVo); + if (aBoolean){ + StyleRecord styleRecord = new StyleRecord(); + styleRecord.setStyleName(styleDataVo.getStyleName()); + styleRecord.setFillColor(styleDataVo.getFillColor()); + styleRecord.setFillOpacity(styleDataVo.getFillOpacity()); + styleRecord.setType(styleDataVo.getType()); + styleRecord.setStrokeColor(styleDataVo.getStrokeColor()); + styleRecord.setStrokeWidth(Double.parseDouble(styleDataVo.getStrokeWidth())); + styleRecordService.updateStyleRecord(styleRecord); + } + map.put("result",aBoolean); + return map; + } + + public Map deleteLayerStyle(String styleName) { + Map map = new HashMap(); + Integer integer = geoserverDao.selectStyleCount(styleName); + if (integer>0){ + map.put("msg","样式已绑定图层,无法删除"); + map.put("code",500); + map.put("result",false); + return map; + }else { + map = geoServer.deleteLayerStyle(styleName); + styleRecordService.deleteStyleRecordByStyleName(styleName); + + } + return map; + } + public List getDictList(String dictType){ + return geoserverDao.getDictData(dictType); + } + + public Map getLayerDataList(Map map) { + Map result = new HashMap(); + Integer pageNum = Integer.parseInt(map.get("pageNum").toString()); + Integer pageSize = Integer.parseInt(map.get("pageSize").toString()); + Integer pageNo = (pageNum-1) * pageSize; + map.put("pageNum",pageNo); + Integer integer = 0; + List maps = new ArrayList<>(); + if (map.get("value")==null||StringUtils.isEmpty(map.get("value").toString())){ + integer = geoserverDao.selectLayerDataListCountNoParam(map); + maps = geoserverDao.selectLayerDataListNoParam(map); + }else { + integer = geoserverDao.selectLayerDataListCount(map); + maps = geoserverDao.selectLayerDataList(map); + } + + result.put("total",integer); + result.put("list",maps); + return result; + } + + public String wkbToWkt(String wkb) throws Exception{ + // 解码WKB字符串 + WKBReader wkbReader = new WKBReader(); + Geometry geometry = wkbReader.read(WKBReader.hexToBytes(wkb)); + + // 转换为WKT字符串 + WKTWriter wktWriter = new WKTWriter(); + String wkt = wktWriter.write(geometry); + return wkt; + } + + public Map getSingleData(Map map) throws Exception{ + // 解码WKB字符串 + Map map1 = geoserverDao.selectSingleData(map.get("tableName").toString(), Integer.parseInt(map.get("id").toString())); + String geom = map1.get("geom").toString(); + WKBReader wkbReader = new WKBReader(); + Geometry geometry = wkbReader.read(WKBReader.hexToBytes(geom)); + + // 转换为WKT字符串 + WKTWriter wktWriter = new WKTWriter(); + String wkt = wktWriter.write(geometry); + map1.put("geom",wkt); + return map1; + } + + public void updateShpData(Map map){ + String id = map.get("id").toString(); + String tableName = map.get("tableName").toString(); + String spaceType = map.get("spaceType").toString(); + String[] split = spaceType.split(":"); + map.remove("spaceType"); + map.remove("id"); + map.remove("tableName"); + map.remove("lat"); + map.remove("lng"); + LinkedHashMap map1 = new LinkedHashMap(); + map1.putAll(map); + geoserverDao.updateTableDateList1(tableName,map1,Integer.parseInt(id),split[1]); + addLayer(tableName); + } + public void insertShpData(Map map){ + String tableName = map.get("tableName").toString(); + String spaceType = map.get("spaceType").toString(); + String[] split = spaceType.split(":"); + map.remove("spaceType"); + map.remove("tableName"); + LinkedHashMap map1 = new LinkedHashMap(); + map1.putAll(map); + map1.put("is_del",0); + geoserverDao.insertTableDateList(tableName,map1,split[1]); + addLayer(tableName); + } + + public void deleteShpData(Map map){ + //geoserverDao.deleteTableDateList(map.get("tableName").toString(),Integer.parseInt(map.get("id").toString())); + geoserverDao.updateTableDateList(map.get("tableName").toString(),Integer.parseInt(map.get("id").toString())); + addLayer(map.get("tableName").toString()); + } + + @Transactional + public Map uploadExcelFile(PartFileVo fileVo) throws Exception{ + MultipartFile file = fileVo.getFile(); + String spaceType = fileVo.getSpaceType(); + String[] split = spaceType.split(":"); + Workbook workbook = WorkbookFactory.create(file.getInputStream()); +// Workbook workbook = null; +// if (filename.indexOf("xlsx") >0 ){ +// workbook = new XSSFWorkbook(file.getInputStream()); +// } +// if (filename.indexOf("xls") >0 ){ +// workbook = new HSSFWorkbook(file.getInputStream()); +// } + Sheet sheetAt = workbook.getSheetAt(0); + Row rowC = sheetAt.getRow(0); + Row row = sheetAt.getRow(1); + int physicalNumberOfRows = sheetAt.getPhysicalNumberOfRows(); + int physicalNumberOfCells = row.getPhysicalNumberOfCells(); + List> heads = new ArrayList<>(); + Integer lng = 0; + Integer lat = 0; + Map relation = new HashMap(); + for (int i=0;i map = new HashMap(); + map.put("type","varchar"); + map.put("length",1024); + row.getCell(i).setCellType(CellType.STRING); + rowC.getCell(i).setCellType(CellType.STRING); + String stringCellValue = row.getCell(i).getStringCellValue(); + String stringCellValueC = rowC.getCell(i).getStringCellValue(); + map.put("name",stringCellValue.replaceAll(" ","").replaceAll("-","").replaceAll(",","")); + relation.put(stringCellValue,stringCellValueC); + if ("id".equals(stringCellValue)||"ID".equals(stringCellValue)){ + map.put("name","num"); + relation.put("num","num"); + } + if ("lng".equals(stringCellValue)){ + map.put("name", "geom"); + map.put("type","geometry"); + map.put("length", ""); + relation.put("geom","geom"); + lng = i; + } + if ("lat".equals(stringCellValue)){ + lat = i; + continue; + } + heads.add(map); + } + Map map = new HashMap(); + map.put("type","varchar"); + map.put("length",1024); + map.put("name","lng"); + Map map1 = new HashMap(); + map1.put("type","varchar"); + map1.put("length",1024); + map1.put("name","lat"); + heads.add(map); + heads.add(map1); + relation.remove("id"); + relation.remove("ID"); + //relation.remove("lng"); + //relation.remove("lat"); + String tableName = fileVo.getTableName().toLowerCase(); + //创建图层数据表序列 + geoserverDao.createSequence(tableName+"_temp"); + //创建图层数据表 + geoserverDao.createTable(tableName+"_temp", heads); + Boolean flag = false; + Boolean flag1 = true; + Boolean isAdd = true; + for (int j=2;j data = new LinkedHashMap<>(); + + for (int k=0;k<=heads.size()-2;k++){ + if (row1.getCell(k)==null) + { + if (k==lng||k==lat){ + isAdd = false; + flag = false; + flag1 = true; + break; + } + if (flag1){ + String name = heads.get(k).get("name").toString(); + data.put(name,""); + if (k==heads.size()) flag = false; + continue; + }else { + String name = heads.get(k-1).get("name").toString(); + data.put(name,""); + if (k==heads.size()) flag = false; + continue; + } + + } + String geometry = ""; + row1.getCell(k).setCellType(CellType.STRING); + if (k==lng){ + lngStr = row1.getCell(k).getStringCellValue(); + + if (StringUtils.isNotEmpty(latStr)&&StringUtils.isNotEmpty(lngStr)){ + geometry = "POINT ("+lngStr+ " "+latStr+")"; + data.put("geom",geometry); + flag = true; + flag1 = false; + }else { + continue; + } + } + + if (k==lat){ + latStr = row1.getCell(k).getStringCellValue(); + + if (StringUtils.isNotEmpty(latStr)&&StringUtils.isNotEmpty(lngStr)){ + geometry = "POINT ("+lngStr+ " "+latStr+")"; + data.put("geom",geometry); + flag = true; + flag1 = false; + } + } + Map stringObjectMap = new HashMap<>(); + if (flag){ + stringObjectMap = heads.get(k - 1); + }else { + stringObjectMap = heads.get(k); + } + if ("geom".equals(stringObjectMap.get("name").toString())){ + data.put("geom",geometry); + }else { + data.put(stringObjectMap.get("name").toString(),row1.getCell(k).getStringCellValue()==null?"":row1.getCell(k).getStringCellValue()); + } + + if (heads.size()-2==k){ + flag =false; + flag1 = true; + } + } + if (isAdd){ + data.put("lng",lngStr); + data.put("lat",latStr); + data.put("is_del",0); + geoserverDao.addTableDateList1(tableName+"_temp" , heads, data, split[1]); + }else { + isAdd = true; + } + + } + Map result = new HashMap(); + result.put("heads", heads); + result.put("dataType", "点"); + result.put("relation",relation); + result.put("tableName", tableName); + return result; + } + public Integer checkServerName(String name) { + Integer integer = dataStoreMapper.selectDataStoreCount(name); + return integer; + } + + public Integer checkTableName(String name) { + Integer integer = dataStoreMapper.selectDataStoreCountByTableRef(name); + //Integer integer1 = dataStoreMapper.selectDataStoreCountTemp(name + "_temp"); + String tempTable = name + "_temp"; + int i = geoserverDao.selectTableCount(tempTable); + if (i > 0) geoserverDao.deleteTable(tempTable); + int i1 = geoserverDao.selectSeqCount(tempTable + "_seq"); + if (i1 > 0) geoserverDao.deleteSequence(tempTable + "_seq"); + if (integer>0){ + return 1; + }else { + return 0; + } + } + + public static void main(String[] args) throws Exception { + // WKB字符串 +// String wkb = "0101000000000000000000F03F000000000000F03F"; +// +// // 解码WKB字符串 +// WKBReader wkbReader = new WKBReader(); +// Geometry geometry = wkbReader.read(WKBReader.hexToBytes(wkb)); +// +// // 转换为WKT字符串 +// WKTWriter wktWriter = new WKTWriter(); +// String wkt = wktWriter.write(geometry); +// +// System.out.println(wkt); +// getLayerUrls("http://localhost:8180/geoserver", "TEST_WORK_SPACE", "daolu"); + Process exec = Runtime.getRuntime().exec("D:\\SoftWare\\Pgsql\\bin\\pgsql2shp.exe -f D:/xian.shp -h localhost -p 5432 -u postgres -P 123456 postgres public.shp_1680592053"); + int i = exec.waitFor(); + System.out.println(i); + } + @Transactional + public Map addLayerValue(String filePath, String tableNameRef) throws Exception { + File dir = new File(filePath); + File[] subFiles = dir.listFiles(); + Map map = geoserverDao.selectStyleName(tableNameRef); + String spaceType = map.get("space_type").toString(); + String[] split = spaceType.split(":"); + String substring = split[1]; + String charset = "UTF-8"; + String dataType = ""; + if (null != subFiles) { + for (File subFile : subFiles) { + if (subFile.getName().endsWith(".cpg")) { + charset = ZipUtil.loadFileCharset(filePath + subFile.getName()); + } + if (subFile.getName().endsWith(".shp")) { + ShapefileDataStore shpDataStore = new ShapefileDataStore(subFile.toURI().toURL()); + shpDataStore.setCharset(Charset.forName(charset)); + // 获取地图要素 + FeatureSource featureSource = shpDataStore.getFeatureSource(); + //获取头属性信息 + List attributeDescriptors = featureSource.getSchema().getAttributeDescriptors(); + List> heads = new ArrayList<>(); + for (AttributeDescriptor a : attributeDescriptors) { + Map et = new HashMap<>(); +// System.out.println("字段名:"+a.getName()); + String name = a.getName().toString(); + et.put("name", name); + heads.add(et); + } + +// //获取数据 + FeatureIterator iterator = featureSource.getFeatures().features(); + while (iterator.hasNext()) { + SimpleFeature feature = iterator.next(); + feature.getName(); + Iterator it = feature.getProperties().iterator(); + LinkedHashMap data = new LinkedHashMap<>(); + String geometry = ""; + while (it.hasNext()) { + Property pro = it.next(); + if (pro.getValue() !=null){ + if (pro.getValue() instanceof Point ||pro.getValue().toString().indexOf("POINT")>-1) {//点 + geometry = "'" + pro.getValue().toString() + "'"; + data.put("geom", geometry); + dataType = "点"; + } else if (pro.getValue() instanceof MultiPolygon||pro.getValue().toString().indexOf("MULTIPOLYGON")>-1) {//多面 + geometry = "'" + pro.getValue() + "'"; + data.put("geom", geometry); + dataType = "面"; + } else if (pro.getValue() instanceof Polygon||pro.getValue().toString().indexOf("POLYGON")>-1) {//面 + geometry = "'" +pro.getValue() + "'"; + data.put("geom", geometry); + dataType = "面"; + } else if (pro.getValue() instanceof MultiLineString||pro.getValue().toString().indexOf("MULTILINESTRING")>-1){ + geometry = "'" + pro.getValue() + "'"; + data.put("geom", geometry); + dataType = "线"; + }else if (pro.getValue() instanceof LineString||pro.getValue().toString().indexOf("LINESTRING")>-1) {//线 + geometry = "'" + pro.getValue() + "'"; + data.put("geom", geometry); + dataType = "线"; + } + else { + data.put(pro.getName().toString(), pro.getValue()==null?"":pro.getValue()); + }}else { + data.put(pro.getName().toString(), ""); + } + } + + data.put("is_del", 0); +// //新增数据到图层数据表 + geoserverDao.addTableDateList(tableNameRef, heads, data, substring); +// +// //发布该图层 +//// Boolean addLayer = geoServer.addLayer(null,null,tableName,null); +//// if(!addLayer){ +//// throw new KspException(WebErrorCode.INTERNAL_PROCESS_ERROR, "发布数据图层失败", null, null); +//// } + } + + return new HashMap(); + } + } + } + + return null; + } + @Transactional + public Map fileTransferAdd(MultipartFile multipartFile, String tableName) throws Exception { + long l = System.currentTimeMillis() / 1000; + String parsePath = "parseFile"+l+"\\"; + File filedir = new File(path +parsePath); + if (filedir.exists()) FileUtils.deleteDirectory(filedir); + FileUtils.forceMkdir(filedir); + File file = new File(path + multipartFile.getName() + ".zip"); + file.delete(); + FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file); + String unzip = ZipUtil.unzip1(path + multipartFile.getName() + ".zip", path + parsePath); + String abusolutePath = path + parsePath; + //if (StringUtils.isNotEmpty(unzip)) abusolutePath = path +parsePath + unzip + "\\"; + Map map = addLayerValue(abusolutePath, tableName); + return map; + } + public static void getLayerUrls(String serverUrl, String workspace, String layerName) { + String[] formats = {"image/png", "image/jpeg", "image/gif", "image/tiff", "image/geotiff", "application/vnd.google-earth.kml+xml", "application/vnd.google-earth.kmz", "application/json", "application/javascript", "text/plain", "text/html"}; + for (String format : formats) { + String url = serverUrl + "/wms?service=WMS&version=1.1.0&request=GetMap&layers=" + workspace + ":" + layerName + "&styles=&bbox=-180.0,-90.0,180.0,90.0&width=256&height=256&srs=EPSG:4326&format=" + format; + System.out.println(format + " url: " + url); + } + } + + public void downloadModel(String tableName, HttpServletResponse response) { + try { + List stringList = geoserverDao.selectTableCloumn(tableName + "_temp"); + List res = createExportBody(stringList); + String tempPath =System.getProperty("java.io.tmpdir") + IdUtil.fastSimpleUUID() + ".xlsx"; + File file = new File(tempPath); + BigExcelWriter writer= ExcelUtil.getBigWriter(file); + // 一次性写出内容,使用默认样式,强制输出标题 + writer.write(res, true); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"); + response.setHeader("Content-Disposition","attachment;filename=file.xlsx"); + ServletOutputStream out=response.getOutputStream(); + file.deleteOnExit(); + writer.flush(out, true); + IoUtil.close(out); + } catch (Exception e) { + e.printStackTrace(); + } +// List stringList = geoserverDao.selectTableCloumn(tableName + "_temp"); +// List res = createExportBody(stringList); +// createExcel(res,response); + } + + public static void initCellMaxTextLength() { + SpreadsheetVersion excel2007 = SpreadsheetVersion.EXCEL2007; + if (Integer.MAX_VALUE != excel2007.getMaxTextLength()) { + Field field; + try { + field = excel2007.getClass().getDeclaredField("_maxTextLength"); + field.setAccessible(true); + field.set(excel2007, Integer.MAX_VALUE); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + + public Boolean downloadRelation(String tableName, HttpServletResponse response) { + try { + initCellMaxTextLength(); + DataStore dataStore = dataStoreMapper.selectDataStoreByName(tableName); + String relation = dataStore.getRelation(); + if (StringUtils.isEmpty(relation))return false; + List maps = JSONArray.parseArray(relation, Map.class); + String exportBodyString = createExportBodyString(maps); + List maps1 = dataStoreMapper.selectDataByName(exportBodyString, tableName); + Map map = new HashMap(); + map.put("refName","lng"); + map.put("initName","经度"); + map.put("name","lng"); + Map map1 = new HashMap(); + map1.put("refName","lat"); + map1.put("initName","纬度"); + map1.put("name","lat"); + maps.add(map); + maps.add(map1); + List res = createExportBodyMap(maps,maps1); + String tempPath =System.getProperty("java.io.tmpdir") + IdUtil.fastSimpleUUID() + ".xlsx"; + File file = new File(tempPath); + BigExcelWriter writer= ExcelUtil.getBigWriter(file); + // 一次性写出内容,使用默认样式,强制输出标题 + writer.write(res, true); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"); + response.setHeader("Content-Disposition","attachment;filename=file.xlsx"); + ServletOutputStream out=response.getOutputStream(); + file.deleteOnExit(); + writer.flush(out, true); + IoUtil.close(out); + } catch (Exception e) { + e.printStackTrace(); + } + return true; + } + public List createExportBody(List list){ + ArrayList res = new ArrayList<>(); + list.forEach(x -> { + LinkedHashMap map = new LinkedHashMap(); + if ("id".equals(x)||"create_time".equals(x)||"isdel".equals(x)){ + + }else { + map.put("原始字段名称",x); + map.put("英文名称",x); + map.put("中文注释",x); + res.add(map); + } + }); + return res; + } + + public List createExportBodyMap(List list,List mapList){ + ArrayList res = new ArrayList<>(); + LinkedHashMap map = new LinkedHashMap(); + LinkedHashMap map1 = new LinkedHashMap(); + LinkedHashMap map2 = new LinkedHashMap(); + list.forEach(x -> { + map.put(x.get("refName"),x.get("name")); + map1.put(x.get("refName"),x.get("refName")); + map2.put(x.get("refName"),x.get("initName")); + }); + res.add(map); + res.add(map1); + res.add(map2); + res.addAll(mapList); + return res; + } + + public String createExportBodyString(List list){ + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < list.size(); i++) { + Map map = list.get(i); + if (i==list.size()-1){ + stringBuilder.append(map.get("refName")); + }else { + stringBuilder.append(map.get("refName")+","); + } + } + return stringBuilder.toString(); + } + + public Map uploadModelData(MultipartFile file) throws Exception{ + Map map = new HashMap(); + Workbook workbook = WorkbookFactory.create(file.getInputStream()); + Sheet sheetAt = workbook.getSheetAt(0); + int physicalNumberOfRows = sheetAt.getPhysicalNumberOfRows(); + List maps = new ArrayList<>(); + for (int i=1;i> newHeads = (List>) map.get("heads"); + List> mapList = new ArrayList<>(); + JSONObject jsonObject = new JSONObject(); + for (Map maps:newHeads) { + Map map1 = new HashMap<>(); + if ("id".equals(maps.get("refName").toString().toLowerCase())||"is_del".equals(maps.get("refName").toString().toLowerCase())){ + continue; + } + if ("geom".equals(maps.get("refName").toString())){ + map1.put("refName","geom"); + map1.put("type","geometry"); + map1.put("length",""); + }else { + map1.put("refName",maps.get("refName").toString()); + map1.put("type","varchar"); + map1.put("length",1024); + } + jsonObject.put(maps.get("refName").toString(),maps.get("initName").toString()); + mapList.add(map1); + } + String refRelation = jsonObject.toString(); + geoserverDao.createSequence(tableName); + //创建图层数据表 + geoserverDao.createNewTable(tableName, mapList); + if (map.get("styleName")!=null){ + geoserverDao.addTableDataStore(tableName,serverName,spaceType,severType,"geoserver","shp",dataType,map.get("styleName").toString(),refRelation,areaName,JSON.toJSONString(newHeads)); + }else { + geoserverDao.addTableDataStore(tableName,serverName,spaceType,severType,"geoserver","shp",dataType,"",refRelation,areaName,JSON.toJSONString(newHeads)); + + } + Map result = new HashMap(); + result.put("code",200); + result.put("msg","创建成功"); + result.put("tableName",tableName); + return result; + } + + public String getShpRelation(String tableName){ + DataStore dataStore = dataStoreMapper.selectDataStoreByName(tableName); + return dataStore.getNameRef(); + } + + public List getColumnByName(Map map) { + return geoserverDao.selectDataByColumn(map.get("columnName").toString(),map.get("tableName").toString()); + } + + public String downLoadShpZip(String tableName){ + Integer integer = geoserverDao.selectTableDataCount(tableName); + String s = geoServer.downloadShpZip(integer, tableName); + return s; + } + + + public String downLoadShpZipFile(String tableName) throws Exception{ + String s1 = geoserverDao.selectSeverNameByTableRef(tableName); + if (StringUtils.isEmpty(s1)) return ""; + File file = new File(pgShpfile+tableName); + File file1 = new File(shpfileZip+tableName); + if (!file.exists()) { + file.mkdirs(); + } + if (!file1.exists()) { + file1.mkdirs(); + } + String s = pgsqlExe+" -f "+ pgShpfile+tableName+"\\"+tableName+".shp"+" -h " +postUrl + + " -p 5432 -u "+pgUsername+" -P "+pgPassword+" "+pgDbname+" public."+tableName; + System.out.println(s); + Process exec = Runtime.getRuntime().exec(pgsqlExe+" -f "+ pgShpfile+tableName+"\\"+tableName+".shp"+" -h " +postUrl + + " -p 5432 -u "+pgUsername+" -P "+pgPassword+" "+pgDbname+" public."+tableName); + int i = exec.waitFor(); + System.out.println(i); + ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(shpfileZip+tableName+"/"+s1+".zip")); + ZipUtil.compressFolder(pgShpfile+tableName,"",zipOutputStream); + zipOutputStream.finish(); + return downLoadUrl+"/"+tableName+"/"+s1+".zip"; + + } + + public void createExcel(List data,HttpServletResponse response) { + XSSFWorkbook workbook = new XSSFWorkbook(); + XSSFSheet sheet = workbook.createSheet(); + for (int i = 0; i <= data.size(); i++) { + Row row = sheet.createRow(i); + if (i==0){ + String[] abc = new String[]{"原始字段名称","英文名称","中文注释"}; + for (int j = 0; j < 3; j++) { + Cell cell = row.createCell(j); + cell.setCellValue(abc[j]); + } + continue; + } + Map rowDate = data.get(i-1); + List stringList = new ArrayList<>(); + for (Object key:rowDate.keySet()) { + stringList.add(rowDate.get(key).toString()); + } + for (int j = 0; j < stringList.size(); j++) { + Cell cell = row.createCell(j); + cell.setCellValue(stringList.get(j)); + } + + + } + try { + ServletOutputStream outputStream = response.getOutputStream(); + workbook.write(outputStream); + } catch (Exception e) { + e.printStackTrace(); + } + } + + + + public Boolean publishStyle(PartFileVo partFileVo) throws Exception { + boolean b = geoServer.publishStyle(partFileVo); + return b; + } +} + + + diff --git a/src/main/java/com/zzlh/es/service/LoginService.java b/src/main/java/com/zzlh/es/service/LoginService.java new file mode 100644 index 0000000..ebfd255 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/LoginService.java @@ -0,0 +1,10 @@ +package com.zzlh.es.service; + +import com.zzlh.es.domain.AjaxResult; + +public interface LoginService { + String login(String username, String password); + + + AjaxResult logout(String token); +} diff --git a/src/main/java/com/zzlh/es/service/TUserService.java b/src/main/java/com/zzlh/es/service/TUserService.java new file mode 100644 index 0000000..1ce1ad6 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/TUserService.java @@ -0,0 +1,13 @@ +package com.zzlh.es.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzlh.es.entity.TUser; + +public interface TUserService extends IService { + /** + * @param username + * @return + */ + public TUser findByName(String username); +} diff --git a/src/main/java/com/zzlh/es/service/ipml/ApplicationDataServiceImpl.java b/src/main/java/com/zzlh/es/service/ipml/ApplicationDataServiceImpl.java new file mode 100644 index 0000000..88405b2 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/ipml/ApplicationDataServiceImpl.java @@ -0,0 +1,192 @@ +package com.zzlh.es.service.ipml; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.*; +import com.zzlh.es.mapper.ApplicationDataMapper; +import com.zzlh.es.mapper.DataStoreMapper; +import com.zzlh.es.mapper.ProjectDataRelationMapper; +import com.zzlh.es.service.IApplicationDataService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import static com.zzlh.es.constant.HttpStatus.*; + +/** + *

+ * 服务实现类 + *

+ * + * @author wyl + * @since 2023_04_06 + */ +@Service +public class ApplicationDataServiceImpl extends ServiceImpl implements IApplicationDataService { + @Autowired + private DataStoreMapper dataStoreMapper; + @Autowired + private ApplicationDataMapper applicationDataMapper; + @Autowired + private ProjectDataRelationMapper projectDataRelationMapper; + + + @Override + public AjaxResult createApplication(ApplicationData applicationData) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("application_name", applicationData.getApplicationName()); + if (applicationDataMapper.selectOne(queryWrapper) != null) { + return AjaxResult.error(APPLICATION_EXIST, "应用已经存在,请重新命名"); + } + if (applicationDataMapper.insertApplicationData(applicationData)) { + return AjaxResult.success(applicationData.getId()); + } else { + return AjaxResult.error(); + } + } + + @Override + public AjaxResult createProject(ProjectDataRelation projectDataRelation) { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("application_id", projectDataRelation.getApplicationId()); + queryWrapper.eq("project_team_name", projectDataRelation.getProjectTeamName()); + List list = projectDataRelationMapper.selectList(queryWrapper); + if (!CollectionUtils.isEmpty(list) && list.size() > 0) { + return AjaxResult.error(REPEAT_ADD, "重复添加"); + } + if (projectDataRelationMapper.insert(projectDataRelation) > 0) { + return AjaxResult.success(projectDataRelation.getApplicationId()); + } else { + return AjaxResult.error(); + } + } + + @Override + public List getAllApplication() { + List applicationDataList = applicationDataMapper.getAllApplication(); + if (!CollectionUtils.isEmpty(applicationDataList)) { + return applicationDataList; + } else { + return null; + } + } + + @Override + public AjaxResult getApplicationById(Integer id) { + + + List applicationBoList = applicationDataMapper.getApplicationById(id); + if (!CollectionUtils.isEmpty(applicationBoList)) { + Map> groupMap = applicationBoList.stream().collect(Collectors.groupingBy(ApplicationBo::getProjectTeamName)); + ArrayList arrayList = new ArrayList<>(); + for (Map.Entry> map : groupMap.entrySet()) { + TreeLableBo treeLableBo = new TreeLableBo(); + treeLableBo.setServerName(map.getKey()); + if(StringUtils.isEmpty(map.getValue().get(0).getServerStoreId())){ + treeLableBo.setChildren(null); + }else{ + treeLableBo.setChildren(map.getValue()); + } + List ids = map.getValue().stream().map(ApplicationBo::getProjectDataRelationId).collect(Collectors.toList()); + treeLableBo.setIds(ids); + arrayList.add(treeLableBo); + } + return AjaxResult.success(arrayList); + } else { + return AjaxResult.success(); + } + } + + @Override + public List getServerByType(String spaceType) { + List dataStores = dataStoreMapper.selectDataStore(spaceType); + if (!CollectionUtils.isEmpty(dataStores)) { + return dataStores; + } else { + return null; + } + } + + @Override + public AjaxResult addServer(ProjectDataRelation projectDataRelation) { + + //根据项目组id查看是否已经存在项目组 没有则创建 + ProjectDataRelation projectData = projectDataRelationMapper.findExist(projectDataRelation.getProjectTeamName(),projectDataRelation.getApplicationId()); + if (projectData == null) { + return AjaxResult.error(PROJECT_NULL, "当前项目组不存在,请刷新页面重试"); + } + //如果当前id的项目组ServerStoreId是空的 则判定这是一个新的项目组还未添加信息 修改项目组信息 + if (projectData.getServerStoreId() == null) { + Integer integer = projectDataRelationMapper.updateProject(projectDataRelation); + if (integer == null || integer != 1) { + return AjaxResult.error(); + } + return AjaxResult.success(); + } else {//如果当前id的项目组ServerStoreId不为空的 则创建一个项目组与当前项目组名称一致的 + if (projectDataRelation.getApplicationId() == null) { + return AjaxResult.error(APPLICATION_ID_NULL, "应用id不能为空"); + } else if (projectDataRelation.getServerStoreId() == null) { + return AjaxResult.error(SERVER_ID_NULL, "服务id不能为空"); + } else if (StringUtils.isEmpty(projectDataRelation.getServerName())) { + return AjaxResult.error(SERVER_NAME_NULL, "服务名称不能为空"); + } else if (StringUtils.isEmpty(projectDataRelation.getProjectTeamName())) { + return AjaxResult.error(PROJECT_NAME_NULL, "项目组名称不能为空"); + } + //项目组不为空 为项目组添加新的图层服务 + Integer insert = projectDataRelationMapper.insert(projectDataRelation); + if (insert != null && insert > 0) { + return AjaxResult.success(); + } else { + return AjaxResult.error(); + } + } + } + + @Override + public AjaxResult deleteIds(int[] ids) { + List list = Arrays.stream(ids).boxed().collect(Collectors.toList()); + int count = projectDataRelationMapper.deleteBatchIds(list); + if (count > 0) { + return AjaxResult.success(); + } else { + return AjaxResult.error(); + } + } + + @Override + public AjaxResult getProjectName(Integer id) { + List list = projectDataRelationMapper.selectList(null); + if (CollectionUtils.isEmpty(list)) { + return AjaxResult.success(list); + } + List collect = list.stream() + .filter(distinctByKey(e -> e.getProjectTeamName())).map(ProjectDataRelation::getProjectTeamName) + .collect(Collectors.toList()); + return AjaxResult.success(collect); + } + + /** + * 自定义比较方法 + * + * @param keyExtractor + * @param + * @return + */ + public static Predicate distinctByKey(Function keyExtractor) { + Map map = new ConcurrentHashMap<>(); + return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; + } + + +} diff --git a/src/main/java/com/zzlh/es/service/ipml/DataStoreServiceImpl.java b/src/main/java/com/zzlh/es/service/ipml/DataStoreServiceImpl.java new file mode 100644 index 0000000..0879718 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/ipml/DataStoreServiceImpl.java @@ -0,0 +1,124 @@ +package com.zzlh.es.service.ipml; + + +import com.zzlh.es.entity.DataStore; +import com.zzlh.es.mapper.DataStoreMapper; +import com.zzlh.es.mapper.GeoServerDao; +import com.zzlh.es.service.GeoServer; +import com.zzlh.es.service.IDataStoreService; +import com.zzlh.es.utils.DateUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; + +/** + * 图层存储表Service业务层处理 + * + * @author LGD + * @date 2023-03-27 + */ +@Service +public class DataStoreServiceImpl implements IDataStoreService +{ + @Autowired + private DataStoreMapper dataStoreMapper; + + @Autowired + private GeoServer geoServer; + + @Autowired + private GeoServerDao geoServerDao; + /** + * 查询图层存储表 + * + * @param id 图层存储表主键 + * @return 图层存储表 + */ + @Override + public DataStore selectDataStoreById(Long id) + { + return dataStoreMapper.selectDataStoreById(id); + } + + /** + * 查询图层存储表列表 + * + * @param dataStore 图层存储表 + * @return 图层存储表 + */ + @Override + public List selectDataStoreList(DataStore dataStore) + { + return dataStoreMapper.selectDataStoreList(dataStore); + } + + /** + * 新增图层存储表 + * + * @param dataStore 图层存储表 + * @return 结果 + */ + @Override + public int insertDataStore(DataStore dataStore) + { + dataStore.setCreateTime(DateUtils.getNowDate()); + return dataStoreMapper.insertDataStore(dataStore); + } + + /** + * 修改图层存储表 + * + * @param dataStore 图层存储表 + * @return 结果 + */ + @Override + public int updateDataStore(DataStore dataStore) + { + return dataStoreMapper.updateDataStore(dataStore); + } + + /** + * 批量删除图层存储表 + * + * @param ids 需要删除的图层存储表主键 + * @return 结果 + */ + @Override + public int deleteDataStoreByIds(Long[] ids) + { + return dataStoreMapper.deleteDataStoreByIds(ids); + } + + /** + * 删除图层存储表信息 + * + * @param id 图层存储表主键 + * @return 结果 + */ + @Override + public int deleteDataStoreById(Integer id) throws Exception + { + int i = dataStoreMapper.selectCountMapBoxById(id.toString()); + int i1 = dataStoreMapper.selectCountMarsById(id.toString()); + if (i>0||i1>0){ + return 0; + } + DataStore dataStore = dataStoreMapper.selectDataStoreById(Long.valueOf(id)); + geoServer.removeLayer(dataStore.getTableRef()); + dataStoreMapper.deleteMapBoxByName(dataStore.getSeverName()); + dataStoreMapper.deleteDataStoreById(Long.valueOf(id)); + int i2 = geoServerDao.selectTableCount(dataStore.getTableRef()); + if (i2 > 0) geoServerDao.deleteTable(dataStore.getTableRef()); + + int i3 = geoServerDao.selectSeqCount(dataStore.getTableRef() + "_seq"); + if (i3 > 0) geoServerDao.deleteSequence(dataStore.getTableRef() + "_seq"); + return 1; + } + + @Override + public List selectDataStoreListByTableName(String tableName) { + return dataStoreMapper.selectDataStoreListByTableName(tableName); + } +} diff --git a/src/main/java/com/zzlh/es/service/ipml/DictDataServiceImpl.java b/src/main/java/com/zzlh/es/service/ipml/DictDataServiceImpl.java new file mode 100644 index 0000000..0883b64 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/ipml/DictDataServiceImpl.java @@ -0,0 +1,19 @@ +package com.zzlh.es.service.ipml; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zzlh.es.entity.DictData; +import com.zzlh.es.mapper.DictDataMapper; +import org.springframework.stereotype.Service; + +/** + *

+ * 服务实现类 + *

+ * + * @author wyl + * @since 2023-04-08 + */ +@Service +public class DictDataServiceImpl extends ServiceImpl implements IDictDataService { + +} diff --git a/src/main/java/com/zzlh/es/service/ipml/IDictDataService.java b/src/main/java/com/zzlh/es/service/ipml/IDictDataService.java new file mode 100644 index 0000000..b291165 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/ipml/IDictDataService.java @@ -0,0 +1,16 @@ +package com.zzlh.es.service.ipml; + +import com.zzlh.es.entity.DictData; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 服务类 + *

+ * + * @author wyl + * @since 2023-04-08 + */ +public interface IDictDataService extends IService { + +} diff --git a/src/main/java/com/zzlh/es/service/ipml/IProjectDataRelationService.java b/src/main/java/com/zzlh/es/service/ipml/IProjectDataRelationService.java new file mode 100644 index 0000000..9d26574 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/ipml/IProjectDataRelationService.java @@ -0,0 +1,16 @@ +package com.zzlh.es.service.ipml; + +import com.zzlh.es.entity.ProjectDataRelation; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 服务类 + *

+ * + * @author wyl + * @since 2023-04-08 + */ +public interface IProjectDataRelationService extends IService { + +} diff --git a/src/main/java/com/zzlh/es/service/ipml/IStyleParameterMapboxService.java b/src/main/java/com/zzlh/es/service/ipml/IStyleParameterMapboxService.java new file mode 100644 index 0000000..b1e95d8 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/ipml/IStyleParameterMapboxService.java @@ -0,0 +1,16 @@ +package com.zzlh.es.service.ipml; + +import com.zzlh.es.entity.StyleParameterMapbox; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 服务类 + *

+ * + * @author wyl + * @since 2023-04-08 + */ +public interface IStyleParameterMapboxService extends IService { + +} diff --git a/src/main/java/com/zzlh/es/service/ipml/LoginServiceImpl.java b/src/main/java/com/zzlh/es/service/ipml/LoginServiceImpl.java new file mode 100644 index 0000000..59bb345 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/ipml/LoginServiceImpl.java @@ -0,0 +1,83 @@ +package com.zzlh.es.service.ipml; + + +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.properties.JwtProperties; +import com.zzlh.es.exception.BusinessException; +import com.zzlh.es.service.LoginService; +import com.zzlh.es.utils.JwtTokenUtil; +import com.zzlh.es.utils.RedisUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; + + +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.stereotype.Service; + +import static com.zzlh.es.constant.HttpStatus.LOGOUT_ERROR; +import static com.zzlh.es.constant.HttpStatus.PASSWORD_ERROR; + +/** + * @author soeasy + */ +@Service +@Slf4j +public class LoginServiceImpl implements LoginService { + + @Autowired + private AuthenticationManagerBuilder authenticationManager; + @Autowired + private UserDetailsService userDetailsService; + @Autowired + private JwtTokenUtil jwtTokenUtil; + @Autowired + private JwtProperties jwtProperties; + + @Autowired + private RedisUtil redisUtil; + /** + * token规范前缀 + */ + + private static final String HAND = "Bearer "; + + @Override + public String login(String username, String password) { + UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(username, password); + //验证用户名和密码 + try{ + final Authentication authentication = authenticationManager.getOrBuild().authenticate(upToken); + SecurityContextHolder.getContext().setAuthentication(authentication); + }catch (AuthenticationException e){ + if(e.getMessage().contains("Bad credentials")){ + throw new BusinessException(PASSWORD_ERROR,"密码错误"); + } + } + final UserDetails userDetails = userDetailsService.loadUserByUsername(username); + final String token = HAND + jwtTokenUtil.generateToken(userDetails); + //将 token 保存到redis + if (redisUtil.set(userDetails.getUsername()+token, token, jwtProperties.getExpiration())) { + log.info("token save key:"+userDetails.getUsername()+token); + return token; + } else { + return null; + } + } + + + @Override + public AjaxResult logout(String authorization) { + final String token = authorization.replace(jwtProperties.getTokenHead(), ""); + String username = jwtTokenUtil.getUsernameFromToken(token); + if (redisUtil.del(username+authorization)) { + return AjaxResult.success("退出成功"); + } + return AjaxResult.error(LOGOUT_ERROR, "退出失败,请重试"); + } +} diff --git a/src/main/java/com/zzlh/es/service/ipml/ProjectDataRelationMarsServiceImpl.java b/src/main/java/com/zzlh/es/service/ipml/ProjectDataRelationMarsServiceImpl.java new file mode 100644 index 0000000..3b66771 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/ipml/ProjectDataRelationMarsServiceImpl.java @@ -0,0 +1,400 @@ +package com.zzlh.es.service.ipml; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.*; +import com.zzlh.es.entity.vo.DataRelationMarsVo; +import com.zzlh.es.mapper.DataStoreMapper; +import com.zzlh.es.mapper.ProjectDataRelationMarsMapper; +import com.zzlh.es.mapper.StyleParameterMarsMapper; +import com.zzlh.es.service.IProjectDataRelationMarsService; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.dao.DuplicateKeyException; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import java.util.*; +import java.util.stream.Collectors; + +import static com.zzlh.es.constant.HttpStatus.PROJECT_NULL; +import static com.zzlh.es.constant.HttpStatus.REPEAT_ADD; +import static com.zzlh.es.service.GeoServer.shpWorkspace; +import static com.zzlh.es.service.GeoServer.url; +import static com.zzlh.es.service.ipml.ApplicationDataServiceImpl.distinctByKey; + +/** + *

+ * 服务实现类 + *

+ * + * @author wyl + * @since 2023-05-19 + */ +@Service +public class ProjectDataRelationMarsServiceImpl extends ServiceImpl implements IProjectDataRelationMarsService { + + @Autowired + private DataStoreMapper dataStoreMapper; + @Autowired + private ProjectDataRelationMarsMapper projectDataRelationMarsMapper; + @Autowired + private StyleParameterMarsMapper styleParameterMarsMapper; + + + @Value("${geoserver.shpworkspace}") + private String shpworkspace; + /** + * 创建项目组 + * + * @param projectDataRelationMars + * @return + */ + @Override + public AjaxResult createMars(ProjectDataRelationMars projectDataRelationMars) { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("project_team_name", projectDataRelationMars.getProjectTeamName()); + queryWrapper.eq("area_name",projectDataRelationMars.getAreaName()); + List list = projectDataRelationMarsMapper.selectList(queryWrapper); + if (!CollectionUtils.isEmpty(list)) { + return AjaxResult.error(REPEAT_ADD, "重复添加"); + } + if (projectDataRelationMarsMapper.insertMars(projectDataRelationMars)) { + Long id = projectDataRelationMars.getId(); + StyleParameterMars styleParameterMars = styleParameterMarsMapper.selectOne(null); + String json = styleParameterMars.getPattr(); + //替换id + json = json.replace("1", id.toString()); + //替换名称 + json = json.replace("names", projectDataRelationMars.getProjectTeamName()); + projectDataRelationMars.setPAttribute(json); + if (projectDataRelationMarsMapper.updateById(projectDataRelationMars) > 0) { + return AjaxResult.success(projectDataRelationMars.getAttribute()); + } + return AjaxResult.error(); + } else { + return AjaxResult.error(); + } + } + + /** + * 添加服务 + * + * @param projectDataRelationMars + * @return + */ + @Override + public AjaxResult addMarsServer(ProjectDataRelationMars projectDataRelationMars) { + System.out.println(projectDataRelationMars.toString()); + //根据项目组id查看是否已经存在项目组 + ProjectDataRelationMars projectData = projectDataRelationMarsMapper.findExist(projectDataRelationMars.getProjectTeamName()); + if (projectData == null) { + return AjaxResult.error(PROJECT_NULL, "当前项目组不存在,请刷新页面重试"); + } + if (StringUtils.isEmpty(projectDataRelationMars.getServerStoreId())) { + return AjaxResult.error("服务id不能为空"); + } + DataStore dataStore = dataStoreMapper.selectDataStoreById(Long.valueOf(projectDataRelationMars.getServerStoreId())); + if (dataStore == null) { + return AjaxResult.error("当前服务不存在"); + } + StyleParameterMars styleParameterMars = styleParameterMarsMapper.selectOne(null); + String json; + String pattr=projectData.getPAttribute(); + //截取父ID + String p=pattr.substring(pattr.indexOf(":")+1,pattr.indexOf(",")); + if (dataStore.getDataType().equals("点")) { + json = styleParameterMars.getSymbol(); + //id + json = json.replace("111", projectDataRelationMars.getServerStoreId()); + //pid + json = json.replace("222", p); + json = json.replace("names", projectDataRelationMars.getServerName()); + String u = "geoserver"+"/"+shpWorkspace + "/ows?service=WFS&version=1.0.0" + + "&request=GetFeature&typeName=" + shpWorkspace + "%3A" + dataStore.getTableRef() + "&maxFeatures=1000000&outputFormat=application%2Fjson"; + json = json.replace("symbolUrl", u); + + } else { + json = styleParameterMars.getLineAndFill(); + //id + json = json.replace("111", projectDataRelationMars.getServerStoreId()); + //pid + json = json.replace("222", p); + //name + json = json.replace("names", projectDataRelationMars.getServerName()); + String u ="geoserver"+"/"+ shpWorkspace + "/wms"; + json = json.replace("lineAndFillUrl", u); + json = json.replace("layerss", shpWorkspace + ":" + dataStore.getTableRef()); + } + projectDataRelationMars.setPAttribute(projectData.getPAttribute()); + //如果当前id的项目组ServerStoreId是空的 则判定这是一个新的项目组还未添加信息 修改项目组信息 +// if (projectData.getServerStoreId() == null) { +// projectDataRelationMars.setAttribute(json); +// projectDataRelationMars.setId(projectData.getId()); +// if (projectDataRelationMarsMapper.updateById(projectDataRelationMars) > 0) { +// return AjaxResult.success(projectDataRelationMars.getAttribute()); +// } +// return AjaxResult.error("添加失败"); +// } else {//如果当前id的项目组ServerStoreId不为空的 则创建一个项目组 + projectDataRelationMars.setAttribute(json); + int insert = 0; + try { + insert = projectDataRelationMarsMapper.insert(projectDataRelationMars); + } catch (DuplicateKeyException e){ + e.printStackTrace(); + return AjaxResult.success(projectDataRelationMars.getAttribute()); + } + //项目组不为空 为项目组添加新的图层服务 + if (insert > 0) { + return AjaxResult.success(projectDataRelationMars.getAttribute()); + } else { + return AjaxResult.error(); + } + // } + } + + @Override + public AjaxResult getTree(String areaName) { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("area_name",areaName); + + List applicationBoList = projectDataRelationMarsMapper.selectList(queryWrapper); + if (!CollectionUtils.isEmpty(applicationBoList)) { + Map> groupMap = applicationBoList.stream().collect(Collectors.groupingBy(ProjectDataRelationMars::getProjectTeamName)); + ArrayList arrayList = new ArrayList<>(); + for (Map.Entry> map : groupMap.entrySet()) { + TreeLableMarsBo treeLableBo = new TreeLableMarsBo(); + treeLableBo.setServerName(map.getKey()); + + if (!StringUtils.isEmpty(map.getValue().get(0).getPAttribute())) { + treeLableBo.setAttr(map.getValue().get(0).getPAttribute()); + } + if (map.getValue().size()==1) { + treeLableBo.setId(map.getValue().get(0).getId()); + treeLableBo.setSort(map.getValue().get(0).getSort()); + treeLableBo.setChildren(null); + } else { + List value = map.getValue(); + for (int i = 0; i < value.size(); i++) { + if (StringUtils.isEmpty(value.get(i).getServerStoreId())){ + treeLableBo.setId(value.get(i).getId()); + treeLableBo.setSort(value.get(i).getSort()); + value.remove(i); + } + } + List collect = value.stream().sorted(Comparator.comparing(ProjectDataRelationMars::getSort,Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList()); + treeLableBo.setChildren(collect); + } + List ids = map.getValue().stream().map(ProjectDataRelationMars::getId).collect(Collectors.toList()); + treeLableBo.setIds(ids); + arrayList.add(treeLableBo); + } + List collect = arrayList.stream().sorted(Comparator.comparing(TreeLableMarsBo::getSort, Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList()); + return AjaxResult.success(collect); + } else { + return AjaxResult.success(); + } + } + + @Override + public AjaxResult deleteIds(int[] ids) { + List list = Arrays.stream(ids).boxed().collect(Collectors.toList()); + if (projectDataRelationMarsMapper.deleteBatchIds(list) > 0) { + return AjaxResult.success(); + } else { + return AjaxResult.error(); + } + } + + @Override + public AjaxResult getProjectName(String areaName) { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("area_name",areaName); + List list = projectDataRelationMarsMapper.selectList(queryWrapper); + if (CollectionUtils.isEmpty(list)) { + return AjaxResult.success(list); + } + List collect = list.stream() + .filter(distinctByKey(e -> e.getProjectTeamName())).map(ProjectDataRelationMars::getProjectTeamName) + .collect(Collectors.toList()); + return AjaxResult.success(collect); + } + + @Override + public AjaxResult findStyleById(Long id) { + return AjaxResult.success(projectDataRelationMarsMapper.selectById(id)); + } + + @Override + + public AjaxResult updateStyle(Long id, String style, String type,String updateStyle,String properties,Integer sort) { + ProjectDataRelationMars mars=projectDataRelationMarsMapper.selectById(id); + mars.setSort(sort); + if ( mars== null) { + return AjaxResult.error("当前树结构不存在"); + } + if(StringUtils.isEmpty(updateStyle)){ + return AjaxResult.error("修改名称不能为空"); + } + + if (type.equals("1") || type.equals("2")) { + ProjectDataRelationMars projectDataRelationMars = new ProjectDataRelationMars(); + projectDataRelationMars.setSort(sort); + if(!StringUtils.isEmpty(properties)){ + projectDataRelationMars.setProperties(properties); + } + if (type.equals("1")) { + projectDataRelationMars.setId(id); + projectDataRelationMars.setPAttribute(style); + if(!updateStyle.trim().equals(mars.getProjectTeamName().trim())){ + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("project_team_name", updateStyle); + List list = projectDataRelationMarsMapper.selectList(queryWrapper); + if (!CollectionUtils.isEmpty(list)) { + return AjaxResult.error( "当前名称已经存在,请重新编辑名称"); + } + if(updateStyle.contains(mars.getPAttribute())){ + return AjaxResult.error("当前名称已经存在,或存在字串冲突"); + } + String pAttr=mars.getPAttribute(); + projectDataRelationMars.setPAttribute(pAttr.replace(mars.getProjectTeamName(),updateStyle)); + projectDataRelationMars.setProjectTeamName(updateStyle); + } + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("project_team_name", mars.getProjectTeamName()); + List list = projectDataRelationMarsMapper.selectList(queryWrapper); + for (ProjectDataRelationMars project:list) { + if (id.longValue()==project.getId().longValue()){ + project.setSort(sort); + } + project.setProjectTeamName(updateStyle); + project.setPAttribute(project.getPAttribute().replace(mars.getProjectTeamName(),updateStyle)); + projectDataRelationMarsMapper.updateById(project); + } + + return AjaxResult.success(mars.getServerName()); + } else { + projectDataRelationMars.setId(id); + projectDataRelationMars.setAttribute(style); + projectDataRelationMars.setServerName(updateStyle); + if (projectDataRelationMarsMapper.updateById(projectDataRelationMars) > 0) { + return AjaxResult.success(mars.getServerName()); + } else { + return AjaxResult.error("修改失败"); + } + } + } else { + return AjaxResult.error("样式类型不存在"); + } + } + + @Override + public AjaxResult getTableName(Long id) { + return AjaxResult.success(dataStoreMapper.selectDataStoreById(id)); + } + + + @Override + public AjaxResult getApplicationTree(String areaName) { + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("area_name",areaName); + + List applicationBoList = projectDataRelationMarsMapper.selectList(queryWrapper); + if (!CollectionUtils.isEmpty(applicationBoList)) { + Map> groupMap = applicationBoList.stream().collect(Collectors.groupingBy(ProjectDataRelationMars::getProjectTeamName)); + ArrayList arrayList = new ArrayList<>(); + for (Map.Entry> map : groupMap.entrySet()) { + TreeLabelMarsApp treeLableBo = new TreeLabelMarsApp(); + treeLableBo.setServerName(map.getKey()); + + if (!StringUtils.isEmpty(map.getValue().get(0).getPAttribute())) { + + treeLableBo.setAttr(map.getValue().get(0).getPAttribute()); + } + + + if (map.getValue().size()==1) { + treeLableBo.setId(map.getValue().get(0).getId()); + treeLableBo.setSort(map.getValue().get(0).getSort()); + treeLableBo.setChildren(null); + } else { + List value = map.getValue(); + List dataRelationMarsVos = new ArrayList<>(); + for (int k = 0; k < value.size(); k++) { + DataRelationMarsVo dataRelationMarsVo = new DataRelationMarsVo(); + BeanUtils.copyProperties(value.get(k),dataRelationMarsVo); + if (!StringUtils.isEmpty(value.get(k).getAttribute())) { + ProjectDataRelationMars projectDataRelationMars = value.get(k); + DataStore dataStore = dataStoreMapper.selectDataStoreById(Long.parseLong(projectDataRelationMars.getServerStoreId())); + if (dataStore==null)continue; + JSONObject jsonObject = JSON.parseObject(value.get(k).getAttribute()); + dataRelationMarsVo.setUrl(jsonObject.getString("url")); + dataRelationMarsVo.setType(jsonObject.getString("type")); + JSONObject symbol = jsonObject.getJSONObject("symbol"); + if (symbol==null){ + dataRelationMarsVo.setImage(""); + dataRelationMarsVo.setLabel(""); + }else { + JSONObject styleOptions = symbol.getJSONObject("styleOptions"); + if (styleOptions==null){ + dataRelationMarsVo.setImage(""); + dataRelationMarsVo.setLabel(""); + }else { + dataRelationMarsVo.setImage(styleOptions.getString("image")); + JSONObject label = styleOptions.getJSONObject("label"); + if (label==null){ + dataRelationMarsVo.setLabel(""); + }else { + dataRelationMarsVo.setLabel(label.getString("text")); + } + } + } + + + String layers = ""; + if (StringUtils.isEmpty(jsonObject.getString("layers"))){ + layers = shpworkspace+":"+dataStore.getTableRef(); + }else { + layers = jsonObject.getString("layers"); + } + dataRelationMarsVo.setLayers(layers); + String type = ""; + if ("点".equals(dataStore.getDataType())){ + type = "POINT"; + }else if ("面".equals(dataStore.getDataType())){ + type = "MULTIPOLYGON"; + }else if ("线".equals(dataStore.getDataType())){ + type = "MULTILINESTRING"; + } + dataRelationMarsVo.setGeomType(type); + System.out.println(jsonObject.toJSONString()); + } + dataRelationMarsVo.setAttribute(""); + dataRelationMarsVos.add(dataRelationMarsVo); + } + for (int i = 0; i < dataRelationMarsVos.size(); i++) { + if (StringUtils.isEmpty(dataRelationMarsVos.get(i).getServerStoreId())){ + treeLableBo.setId(dataRelationMarsVos.get(i).getId()); + treeLableBo.setSort(dataRelationMarsVos.get(i).getSort()); + dataRelationMarsVos.remove(i); + } + } + List collect = dataRelationMarsVos.stream().sorted(Comparator.comparing(ProjectDataRelationMars::getSort,Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList()); + treeLableBo.setChildren(collect); + } + List ids = map.getValue().stream().map(ProjectDataRelationMars::getId).collect(Collectors.toList()); + treeLableBo.setIds(ids); + arrayList.add(treeLableBo); + } + List collect = arrayList.stream().sorted(Comparator.comparing(TreeLabelMarsApp::getSort, Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList()); + return AjaxResult.success(collect); + } else { + return AjaxResult.success(); + } + } +} diff --git a/src/main/java/com/zzlh/es/service/ipml/ProjectDataRelationServiceImpl.java b/src/main/java/com/zzlh/es/service/ipml/ProjectDataRelationServiceImpl.java new file mode 100644 index 0000000..5d79c48 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/ipml/ProjectDataRelationServiceImpl.java @@ -0,0 +1,19 @@ +package com.zzlh.es.service.ipml; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zzlh.es.entity.ProjectDataRelation; +import com.zzlh.es.mapper.ProjectDataRelationMapper; +import org.springframework.stereotype.Service; + +/** + *

+ * 服务实现类 + *

+ * + * @author wyl + * @since 2023-04-08 + */ +@Service +public class ProjectDataRelationServiceImpl extends ServiceImpl implements IProjectDataRelationService { + +} diff --git a/src/main/java/com/zzlh/es/service/ipml/StyleImageServiceImpl.java b/src/main/java/com/zzlh/es/service/ipml/StyleImageServiceImpl.java new file mode 100644 index 0000000..23cd999 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/ipml/StyleImageServiceImpl.java @@ -0,0 +1,168 @@ +package com.zzlh.es.service.ipml; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.StyleImage; +import com.zzlh.es.exception.BusinessException; +import com.zzlh.es.mapper.StyleImageMapper; +import com.zzlh.es.mapper.StyleServerMapboxMapper; +import com.zzlh.es.service.IStyleImageService; +import com.zzlh.es.webupload.util.FileHandleUtil; +import com.zzlh.es.webupload.util.FileUploadConfig; +import com.zzlh.es.webupload.util.IPUtils; +import com.zzlh.es.webupload.util.IdWorker; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.util.DigestUtils; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; + +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +import static com.zzlh.es.constant.HttpStatus.*; +import static com.zzlh.es.utils.UserHolder.getUserDetail; + +/** + *

+ * 服务实现类 + *

+ * + * @author wyl + * @since 2023-04-12 + */ +@Service +public class StyleImageServiceImpl extends ServiceImpl implements IStyleImageService { + + @Autowired + private IdWorker idWorker; + + @Autowired + private FileUploadConfig fileUploadConfig; + + + @Autowired + private StyleImageMapper styleImageMapper; + + + @Autowired + private StyleServerMapboxMapper styleServerMapboxMapper; + + @Override + public AjaxResult uploadStyleImage(HttpServletRequest request) throws IOException { + Long nowtime = System.currentTimeMillis(); + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + Map files = multipartRequest.getFileMap(); + for (Map.Entry entry : files.entrySet()) { + MultipartFile multipartFile = entry.getValue(); + if (multipartFile.isEmpty()) { + return AjaxResult.error(FILE_NULL,"文件不能为空"); + } + String contentType = multipartFile.getContentType(); + System.out.println("contentType:" + contentType); + + String fileName = multipartFile.getOriginalFilename(); + Long size = multipartFile.getSize(); + System.out.println(fileName + "-->" + size); + + + //计算MD5值 + String filemd5 = DigestUtils.md5DigestAsHex(multipartFile.getInputStream()); + //查询数据库是否已经有了,有直接写入,没有,写入磁盘 + StyleImage style = null; + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("md5_value", filemd5); + List list = styleImageMapper.selectList(queryWrapper); + if (list.size() > 0) { + style = list.get(0); + } + Map map = new HashMap<>(); + String fileType = contentType.split("/")[0]; + + if (style == null) { + String pathTypeDir = fileUploadConfig.getStyleImage() + fileType + "/"; + String localPath = fileUploadConfig.getUploadFolder() + fileUploadConfig.getLocalPath() + pathTypeDir; + String fileSuffix = ""; + if (!StringUtils.isEmpty(fileName)) { + //随机生成服务器本地路径 + fileSuffix = fileName.substring(fileName.lastIndexOf(".")); + } + String serverFileName = idWorker.nextId() + fileSuffix; + FileHandleUtil.upload(multipartFile.getInputStream(), localPath, serverFileName); + String netWorkPath = "/" + pathTypeDir + serverFileName; + StyleImage styleImage = new StyleImage(); + styleImage.setUploadCount(1); + styleImage.setFileSize(size); + styleImage.setFileType(fileType); + styleImage.setMd5Value(filemd5); + styleImage.setOrgName(fileName); + styleImage.setServerLocalName(serverFileName); + styleImage.setServerLocalPath(localPath + serverFileName); + styleImage.setNetworkPath(netWorkPath); + styleImage.setCreateTime(new Date()); + styleImage.setCreateBy("admin"); + String device = request.getHeader("User-Agent"); + styleImage.setUploadDevice(device); + String ipAddr = IPUtils.getIpAddr(request); + styleImage.setUploadIp(ipAddr); + map.put("network",fileUploadConfig.getImageServerIp()+styleImage.getNetworkPath()); + this.save(styleImage); + } else { + + return AjaxResult.error(REPEAT_UPLOAD,"重复上传"); + } + System.out.println("耗时: " + (System.currentTimeMillis() - nowtime) + " ms"); + return AjaxResult.success(map); + + } + return AjaxResult.error(UPLOAD_ERROR,"文件上传错误"); + } + + @Override + public AjaxResult getAllStyleImage() { + + + List list = styleImageMapper.selectList(new QueryWrapper<>()); + if (CollectionUtils.isEmpty(list)) { + return AjaxResult.success(); + } + List data = new ArrayList<>(); + for (StyleImage styleImage : list) { + Integer id = styleImage.getId(); + String networkPath = fileUploadConfig.getImageServerIp() + styleImage.getNetworkPath(); + Map map = new HashMap<>(); + map.put("id", id); + map.put("networkPath", networkPath); + data.add(map); + } + return AjaxResult.success(data); + + } + @Transactional + @Override + public AjaxResult deleteIds(int[] ids) { + List list = Arrays.stream(ids).boxed().collect(Collectors.toList()); + List lists=styleImageMapper.selectBatchIds(list); + if(CollectionUtils.isEmpty(lists)){ + return AjaxResult.error(SELECTED_NOT_EXIST,"当前选中的图标不存在或已删除"); + } + for(StyleImage styleImage:lists){ + QueryWrapper queryWrapper=new QueryWrapper(); + queryWrapper.eq("img_url",fileUploadConfig.getImageServerIp() +styleImage.getNetworkPath()); + if(!CollectionUtils.isEmpty(styleServerMapboxMapper.selectList(queryWrapper))){ + throw new BusinessException(IMAGE_USED,"当前选中图标存在已经绑定图层服务"); + } + if(FileHandleUtil.delete(styleImage.getServerLocalPath())){ + styleImageMapper.deleteById(styleImage.getId()); + } + } + return AjaxResult.success(); + } + +} diff --git a/src/main/java/com/zzlh/es/service/ipml/StyleParameterMapboxServiceImpl.java b/src/main/java/com/zzlh/es/service/ipml/StyleParameterMapboxServiceImpl.java new file mode 100644 index 0000000..d386773 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/ipml/StyleParameterMapboxServiceImpl.java @@ -0,0 +1,19 @@ +package com.zzlh.es.service.ipml; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zzlh.es.entity.StyleParameterMapbox; +import com.zzlh.es.mapper.StyleParameterMapboxMapper; +import org.springframework.stereotype.Service; + +/** + *

+ * 服务实现类 + *

+ * + * @author wyl + * @since 2023-04-08 + */ +@Service +public class StyleParameterMapboxServiceImpl extends ServiceImpl implements IStyleParameterMapboxService { + +} diff --git a/src/main/java/com/zzlh/es/service/ipml/StyleRecordServiceImpl.java b/src/main/java/com/zzlh/es/service/ipml/StyleRecordServiceImpl.java new file mode 100644 index 0000000..b47732f --- /dev/null +++ b/src/main/java/com/zzlh/es/service/ipml/StyleRecordServiceImpl.java @@ -0,0 +1,95 @@ +package com.zzlh.es.service.ipml; + +import java.util.List; + +import com.zzlh.es.entity.StyleRecord; +import com.zzlh.es.mapper.StyleRecordMapper; +import com.zzlh.es.service.IStyleRecordService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + + +/** + * 样式Service业务层处理 + * + * @author lgd + * @date 2023-08-09 + */ +@Service +public class StyleRecordServiceImpl implements IStyleRecordService +{ + @Autowired + private StyleRecordMapper styleRecordMapper; + + /** + * 查询样式 + * + * @param styleName 样式主键 + * @return 样式 + */ + @Override + public StyleRecord selectStyleRecordByStyleName(String styleName) + { + return styleRecordMapper.selectStyleRecordByStyleName(styleName); + } + + /** + * 查询样式列表 + * + * @param styleRecord 样式 + * @return 样式 + */ + @Override + public List selectStyleRecordList(StyleRecord styleRecord) + { + return styleRecordMapper.selectStyleRecordList(styleRecord); + } + + /** + * 新增样式 + * + * @param styleRecord 样式 + * @return 结果 + */ + @Override + public int insertStyleRecord(StyleRecord styleRecord) + { + return styleRecordMapper.insertStyleRecord(styleRecord); + } + + /** + * 修改样式 + * + * @param styleRecord 样式 + * @return 结果 + */ + @Override + public int updateStyleRecord(StyleRecord styleRecord) + { + return styleRecordMapper.updateStyleRecord(styleRecord); + } + + /** + * 批量删除样式 + * + * @param styleNames 需要删除的样式主键 + * @return 结果 + */ + @Override + public int deleteStyleRecordByStyleNames(String[] styleNames) + { + return styleRecordMapper.deleteStyleRecordByStyleNames(styleNames); + } + + /** + * 删除样式信息 + * + * @param styleName 样式主键 + * @return 结果 + */ + @Override + public int deleteStyleRecordByStyleName(String styleName) + { + return styleRecordMapper.deleteStyleRecordByStyleName(styleName); + } +} diff --git a/src/main/java/com/zzlh/es/service/ipml/StyleServerMapboxServiceImpl.java b/src/main/java/com/zzlh/es/service/ipml/StyleServerMapboxServiceImpl.java new file mode 100644 index 0000000..0d1e701 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/ipml/StyleServerMapboxServiceImpl.java @@ -0,0 +1,81 @@ +package com.zzlh.es.service.ipml; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.vividsolutions.jts.operation.valid.SimpleNestedRingTester; +import com.zzlh.es.domain.AjaxResult; +import com.zzlh.es.entity.DataStore; +import com.zzlh.es.entity.StyleServerMapbox; +import com.zzlh.es.mapper.DataStoreMapper; +import com.zzlh.es.mapper.StyleServerMapboxMapper; +import com.zzlh.es.service.GeoServer; +import com.zzlh.es.service.IStyleServerMapboxService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.util.List; + +import static com.zzlh.es.constant.HttpStatus.SERVER_NAME_NULL; +import static com.zzlh.es.constant.HttpStatus.SERVER_NOT_EXIST; + +/** + *

+ * 服务实现类 + *

+ * + * @author wyl + * @since 2023-04-08 + */ +@Service +public class StyleServerMapboxServiceImpl extends ServiceImpl implements IStyleServerMapboxService { + @Autowired + private StyleServerMapboxMapper styleServerMapboxMapper; + @Value("${geoserver.url}") + private String geoUrl; + @Override + public boolean saveStyleServerMapbox(StyleServerMapbox styleServerMapbox) { + return styleServerMapboxMapper.insert(styleServerMapbox)>0; + } + @Override + public AjaxResult findStyleById(String serverName){ + QueryWrapper queryWrapper=new QueryWrapper<>(); + queryWrapper.eq("server_name",serverName); + StyleServerMapbox styleServerMapbox=styleServerMapboxMapper.selectOne(queryWrapper); + if(styleServerMapbox!=null){ + return AjaxResult.success(styleServerMapbox); + } + return AjaxResult.error(); + } + + @Override + public AjaxResult updateStyle(StyleServerMapbox styleServerMapbox) { + QueryWrapper queryWrapper=new QueryWrapper<>(); + if(StringUtils.isEmpty(styleServerMapbox.getServerName())){ + return AjaxResult.error(SERVER_NAME_NULL,"图层服务名称不能为空"); + } + queryWrapper.eq("server_name",styleServerMapbox.getServerName()); + if(styleServerMapboxMapper.update(styleServerMapbox,queryWrapper)>0){ + return AjaxResult.success(); + } + return AjaxResult.error(); + } + + + + // private String urlHead= geoUrl+"/gwc/service/tms/1.0.0/"; + @Autowired + private DataStoreMapper dataStoreMapper; + + @Override + public AjaxResult getUrlByServerName(String serverName) { + DataStore dataStore=dataStoreMapper.selectDataStoreByName(serverName); + if(dataStore== null){ + return AjaxResult.error(SERVER_NOT_EXIST,"当前图层服务不存在请重新选择"); + } + String workspace=GeoServer.shpWorkspace; + String url =geoUrl+"/gwc/service/tms/1.0.0/"+workspace+":"+serverName+"@EPSG:900913@pbf/{z}/{x}/{y}.pbf"; + return AjaxResult.success(url); + } +} diff --git a/src/main/java/com/zzlh/es/service/ipml/TUserServiceImpl.java b/src/main/java/com/zzlh/es/service/ipml/TUserServiceImpl.java new file mode 100644 index 0000000..8cab185 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/ipml/TUserServiceImpl.java @@ -0,0 +1,25 @@ +package com.zzlh.es.service.ipml; + + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zzlh.es.entity.TUser; +import com.zzlh.es.mapper.TUserMapper; +import com.zzlh.es.service.TUserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + + + +/** + * @author soeasy + */ +@Service +public class TUserServiceImpl extends ServiceImpl implements TUserService { + @Autowired + private TUserMapper userDao; + + @Override + public TUser findByName(String username) { + return userDao.findByName(username); + } +} diff --git a/src/main/java/com/zzlh/es/service/testpublicpostgis.java b/src/main/java/com/zzlh/es/service/testpublicpostgis.java new file mode 100644 index 0000000..8d22a94 --- /dev/null +++ b/src/main/java/com/zzlh/es/service/testpublicpostgis.java @@ -0,0 +1,124 @@ +package com.zzlh.es.service; + +import it.geosolutions.geoserver.rest.GeoServerRESTManager; +import it.geosolutions.geoserver.rest.GeoServerRESTPublisher; +import it.geosolutions.geoserver.rest.GeoServerRESTReader; +import it.geosolutions.geoserver.rest.decoder.RESTDataStore; +import it.geosolutions.geoserver.rest.decoder.RESTLayer; +import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder; +import it.geosolutions.geoserver.rest.encoder.datastore.GSPostGISDatastoreEncoder; +import it.geosolutions.geoserver.rest.encoder.feature.GSFeatureTypeEncoder; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.URL; +import java.util.List; + +@Slf4j +@Data +public class testpublicpostgis { + + private String lgd = "lgd"; + public static void main(String[] args) throws Exception { + testpublicpostgis testpublicpostgis = new testpublicpostgis(); + //获取class对象 + Class aClass = testpublicpostgis.getClass(); + //获取实例 + com.zzlh.es.service.testpublicpostgis testpublicpostgis1 = aClass.newInstance(); + //获取字段数组 + Field[] declaredFields = aClass.getDeclaredFields(); + //获取方法名 + Method method = aClass.getMethod("getLgd"); + //允许访问private私有变量 + method.setAccessible(true); + //反射调用获取值 + Object invoke = method.invoke(testpublicpostgis1); + System.out.println(invoke.toString()); + for (Field field:declaredFields) { + System.out.println(field.getName()); + + } +// System.out.println(declaredFields[0]); +// String name = declaredFields[0].getName(); +// System.out.println(name); +// Object o = declaredFields[0].get(name); +// System.out.println(o.toString()); +// String wsName = "ksp" ; //待创建和发布图层的workspace +// String layerName = "shp_1680592947" ; // 数据库要发布的表名称,后面图层名称和表名保持一致 +// log.error("123"); +// boolean publishPostGISLayer = publishPostGISLayer(wsName, layerName); +// if(publishPostGISLayer=false){ +// System.out.println("此Publish layer已存在"); +// } +// System.out.println(publishPostGISLayer); + } + public static boolean publishPostGISLayer(String wsName, String layerName) throws Exception { + //geoserver连接配置 + String url = "http://localhost:8180/geoserver" ; + String username = "admin" ; + String passwd = "geoserver" ; + //postgis连接配置 + String pgHost = "localhost" ; + int pgPort = 5432; + String pgUser = "postgres" ; + String pgPwd = "123456" ; + String pgSchema="public"; + String pgDatabase="postgres"; + Boolean isPublished=null; + GeoServerRESTManager geoServerRESTManager = new GeoServerRESTManager(new URL(url), username, passwd); + GeoServerRESTPublisher geoServerRESTPublisher = geoServerRESTManager.getPublisher(); + GeoServerRESTReader geoServerRESTReader=geoServerRESTManager.getReader(); + + //判断workspace是否存在,不存在则创建 + //创建一个workspace + List workspaces = geoServerRESTReader.getWorkspaceNames(); + if(!workspaces.contains( wsName)){ + boolean createws = geoServerRESTPublisher.createWorkspace( wsName); + System.out.println("create ws : " + createws); + }else { + System.out.println("workspace已经存在了,ws :" + wsName); + + } + // 判断数据存储(datastore)是否已经存在,不存在则创建 + String storeName = wsName + "_shp"; + RESTDataStore restStore =geoServerRESTReader.getDatastore(wsName, storeName); + if (restStore == null) { + GSPostGISDatastoreEncoder store = new GSPostGISDatastoreEncoder(storeName); + store.setHost(pgHost); + store.setPort(pgPort); + store.setUser(pgUser); + store.setPassword(pgPwd); + store.setDatabase(pgDatabase); + store.setSchema(pgSchema); + store.setConnectionTimeout(300); + store.setMaxConnections(20); + store.setMinConnections(1); + store.setExposePrimaryKeys(true); + boolean isCreateStore = geoServerRESTManager.getStoreManager().create(wsName,store); + System.out.println("Create store : " + isCreateStore); + } else { + log.error("DataStore already exist, store:" + storeName); + } + RESTLayer layer = geoServerRESTReader.getLayer(wsName, layerName); + // 若图层已存在,则不发布 + if (layer == null) { + // publisher.removeLayer(wsName, layerName); + geoServerRESTPublisher.unpublishFeatureType(wsName, storeName, layerName); + } + GSFeatureTypeEncoder fte = new GSFeatureTypeEncoder(); + fte.setTitle(layerName); + fte.setName(layerName); + fte.setSRS("EPSG:4326"); + GSLayerEncoder layerEncoder = new GSLayerEncoder(); + // layerEncoder.setDefaultStyle(layerName); // 样式和图层名字相同 + isPublished = geoServerRESTPublisher.publishDBLayer(wsName, storeName, fte, layerEncoder); + log.info("Publish layer: " + isPublished); + System.out.println("Publish layer: " + isPublished); + + return isPublished; + } +} + + diff --git a/src/main/java/com/zzlh/es/test/AccessExample.java b/src/main/java/com/zzlh/es/test/AccessExample.java new file mode 100644 index 0000000..0f793ac --- /dev/null +++ b/src/main/java/com/zzlh/es/test/AccessExample.java @@ -0,0 +1,42 @@ +//package com.zzlh.es.test; +// +//import java.sql.Connection; +//import java.sql.DriverManager; +//import java.sql.ResultSet; +//import java.sql.Statement; +// +//public class AccessExample { +// +// public static void main(String[] args) { +// try { +// // 连接字符串,指定Access数据库文件的路径 +// String connectionString = "jdbc:ucanaccess://C:\\Users\\Administrator\\Desktop\\test.accdb"; +// +// // 加载JDBC驱动 +// Class.forName("net.ucanaccess.jdbc.UcanaccessDriver"); +// +// // 建立连接 +// Connection conn = DriverManager.getConnection(connectionString); +// +// // 创建Statement对象来执行SQL语句 +// Statement statement = conn.createStatement(); +// +// // 执行查询并获取结果 +// ResultSet rs = statement.executeQuery("SELECT * FROM XXXXXXSXB_QLR where QLRMC="+"'张成'" +" limit 0,100"); +// +// // 处理结果 +// while (rs.next()) { +// // 获取并打印每一列的值 +// System.out.println(rs.getString("QLRMC")); +// } +// +// // 关闭连接 +// rs.close(); +// statement.close(); +// conn.close(); +// +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +//} diff --git a/src/main/java/com/zzlh/es/text/CharsetKit.java b/src/main/java/com/zzlh/es/text/CharsetKit.java new file mode 100644 index 0000000..0b0c516 --- /dev/null +++ b/src/main/java/com/zzlh/es/text/CharsetKit.java @@ -0,0 +1,89 @@ +package com.zzlh.es.text; + + + +import org.springframework.util.StringUtils; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +/** + * 字符集工具类 + * + * @author hckj + */ +public class CharsetKit +{ + /** ISO-8859-1 */ + public static final String ISO_8859_1 = "ISO-8859-1"; + /** UTF-8 */ + public static final String UTF_8 = "UTF-8"; + /** GBK */ + public static final String GBK = "GBK"; + + /** ISO-8859-1 */ + public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1); + /** UTF-8 */ + public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8); + /** GBK */ + public static final Charset CHARSET_GBK = Charset.forName(GBK); + + /** + * 转换为Charset对象 + * + * @param charset 字符集,为空则返回默认字符集 + * @return Charset + */ + public static Charset charset(String charset) + { + return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-8859-1 + * @param destCharset 目标字符集,默认UTF-8 + * @return 转换后的字符集 + */ + public static String convert(String source, String srcCharset, String destCharset) + { + return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset)); + } + + /** + * 转换字符串的字符集编码 + * + * @param source 字符串 + * @param srcCharset 源字符集,默认ISO-8859-1 + * @param destCharset 目标字符集,默认UTF-8 + * @return 转换后的字符集 + */ + public static String convert(String source, Charset srcCharset, Charset destCharset) + { + if (null == srcCharset) + { + srcCharset = StandardCharsets.ISO_8859_1; + } + + if (null == destCharset) + { + destCharset = StandardCharsets.UTF_8; + } + + if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset)) + { + return source; + } + return new String(source.getBytes(srcCharset), destCharset); + } + + /** + * @return 系统字符集编码 + */ + public static String systemCharset() + { + return Charset.defaultCharset().name(); + } +} diff --git a/src/main/java/com/zzlh/es/text/Convert.java b/src/main/java/com/zzlh/es/text/Convert.java new file mode 100644 index 0000000..2ba8afd --- /dev/null +++ b/src/main/java/com/zzlh/es/text/Convert.java @@ -0,0 +1,1009 @@ +package com.zzlh.es.text; + + + +import org.springframework.util.StringUtils; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.text.NumberFormat; +import java.util.Set; + +/** + * 类型转换器 + * + * @author hckj + */ +public class Convert +{ + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static String toStr(Object value, String defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof String) + { + return (String) value; + } + return value.toString(); + } + + /** + * 转换为字符串
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static String toStr(Object value) + { + return toStr(value, null); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Character toChar(Object value, Character defaultValue) + { + if (null == value) + { + return defaultValue; + } + if (value instanceof Character) + { + return (Character) value; + } + + final String valueStr = toStr(value, null); + return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0); + } + + /** + * 转换为字符
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Character toChar(Object value) + { + return toChar(value, null); + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Byte toByte(Object value, Byte defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Byte) + { + return (Byte) value; + } + if (value instanceof Number) + { + return ((Number) value).byteValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Byte.parseByte(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为byte
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Byte toByte(Object value) + { + return toByte(value, null); + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Short toShort(Object value, Short defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Short) + { + return (Short) value; + } + if (value instanceof Number) + { + return ((Number) value).shortValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Short.parseShort(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Short
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Short toShort(Object value) + { + return toShort(value, null); + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Number toNumber(Object value, Number defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Number) + { + return (Number) value; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return NumberFormat.getInstance().parse(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Number
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Number toNumber(Object value) + { + return toNumber(value, null); + } + + /** + * 转换为int
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Integer toInt(Object value, Integer defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Integer) + { + return (Integer) value; + } + if (value instanceof Number) + { + return ((Number) value).intValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Integer.parseInt(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为int
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Integer toInt(Object value) + { + return toInt(value, null); + } + + /** + * 转换为Integer数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String str) + { + return toIntArray(",", str); + } + + /** + * 转换为Long数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String str) + { + return toLongArray(",", str); + } + + /** + * 转换为Integer数组
+ * + * @param split 分隔符 + * @param str 被转换的值 + * @return 结果 + */ + public static Integer[] toIntArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Integer[] {}; + } + String[] arr = str.split(split); + final Integer[] ints = new Integer[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Integer v = toInt(arr[i], 0); + ints[i] = v; + } + return ints; + } + + /** + * 转换为Long数组
+ * + * @param split 分隔符 + * @param str 被转换的值 + * @return 结果 + */ + public static Long[] toLongArray(String split, String str) + { + if (StringUtils.isEmpty(str)) + { + return new Long[] {}; + } + String[] arr = str.split(split); + final Long[] longs = new Long[arr.length]; + for (int i = 0; i < arr.length; i++) + { + final Long v = toLong(arr[i], null); + longs[i] = v; + } + return longs; + } + + /** + * 转换为String数组
+ * + * @param str 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String str) + { + return toStrArray(",", str); + } + + /** + * 转换为String数组
+ * + * @param split 分隔符 + * @param str 被转换的值 + * @return 结果 + */ + public static String[] toStrArray(String split, String str) + { + return str.split(split); + } + + /** + * 转换为long
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Long toLong(Object value, Long defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Long) + { + return (Long) value; + } + if (value instanceof Number) + { + return ((Number) value).longValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 支持科学计数法 + return new BigDecimal(valueStr.trim()).longValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为long
+ * 如果给定的值为null,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Long toLong(Object value) + { + return toLong(value, null); + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Double toDouble(Object value, Double defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Double) + { + return (Double) value; + } + if (value instanceof Number) + { + return ((Number) value).doubleValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + // 支持科学计数法 + return new BigDecimal(valueStr.trim()).doubleValue(); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为double
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Double toDouble(Object value) + { + return toDouble(value, null); + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Float toFloat(Object value, Float defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Float) + { + return (Float) value; + } + if (value instanceof Number) + { + return ((Number) value).floatValue(); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Float.parseFloat(valueStr.trim()); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Float
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Float toFloat(Object value) + { + return toFloat(value, null); + } + + /** + * 转换为boolean
+ * String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static Boolean toBool(Object value, Boolean defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof Boolean) + { + return (Boolean) value; + } + String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + valueStr = valueStr.trim().toLowerCase(); + switch (valueStr) + { + case "true": + case "yes": + case "ok": + case "1": + return true; + case "false": + case "no": + case "0": + return false; + default: + return defaultValue; + } + } + + /** + * 转换为boolean
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static Boolean toBool(Object value) + { + return toBool(value, null); + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * + * @param clazz Enum的Class + * @param value 值 + * @param defaultValue 默认值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value, E defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (clazz.isAssignableFrom(value.getClass())) + { + @SuppressWarnings("unchecked") + E myE = (E) value; + return myE; + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return Enum.valueOf(clazz, valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为Enum对象
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * + * @param clazz Enum的Class + * @param value 值 + * @return Enum + */ + public static > E toEnum(Class clazz, Object value) + { + return toEnum(clazz, value, null); + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value, BigInteger defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigInteger) + { + return (BigInteger) value; + } + if (value instanceof Long) + { + return BigInteger.valueOf((Long) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigInteger(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为BigInteger
+ * 如果给定的值为空,或者转换失败,返回默认值null
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigInteger toBigInteger(Object value) + { + return toBigInteger(value, null); + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @param defaultValue 转换错误时的默认值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) + { + if (value == null) + { + return defaultValue; + } + if (value instanceof BigDecimal) + { + return (BigDecimal) value; + } + if (value instanceof Long) + { + return new BigDecimal((Long) value); + } + if (value instanceof Double) + { + return BigDecimal.valueOf((Double) value); + } + if (value instanceof Integer) + { + return new BigDecimal((Integer) value); + } + final String valueStr = toStr(value, null); + if (StringUtils.isEmpty(valueStr)) + { + return defaultValue; + } + try + { + return new BigDecimal(valueStr); + } + catch (Exception e) + { + return defaultValue; + } + } + + /** + * 转换为BigDecimal
+ * 如果给定的值为空,或者转换失败,返回默认值
+ * 转换失败不会报错 + * + * @param value 被转换的值 + * @return 结果 + */ + public static BigDecimal toBigDecimal(Object value) + { + return toBigDecimal(value, null); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @return 字符串 + */ + public static String utf8Str(Object obj) + { + return str(obj, CharsetKit.CHARSET_UTF_8); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charsetName 字符集 + * @return 字符串 + */ + public static String str(Object obj, String charsetName) + { + return str(obj, Charset.forName(charsetName)); + } + + /** + * 将对象转为字符串
+ * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法 + * + * @param obj 对象 + * @param charset 字符集 + * @return 字符串 + */ + public static String str(Object obj, Charset charset) + { + if (null == obj) + { + return null; + } + + if (obj instanceof String) + { + return (String) obj; + } + else if (obj instanceof byte[] || obj instanceof Byte[]) + { + if (obj instanceof byte[]) + { + return str((byte[]) obj, charset); + } + else + { + Byte[] bytes = (Byte[]) obj; + int length = bytes.length; + byte[] dest = new byte[length]; + for (int i = 0; i < length; i++) + { + dest[i] = bytes[i]; + } + return str(dest, charset); + } + } + else if (obj instanceof ByteBuffer) + { + return str((ByteBuffer) obj, charset); + } + return obj.toString(); + } + + /** + * 将byte数组转为字符串 + * + * @param bytes byte数组 + * @param charset 字符集 + * @return 字符串 + */ + public static String str(byte[] bytes, String charset) + { + return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset)); + } + + /** + * 解码字节码 + * + * @param data 字符串 + * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 + * @return 解码后的字符串 + */ + public static String str(byte[] data, Charset charset) + { + if (data == null) + { + return null; + } + + if (null == charset) + { + return new String(data); + } + return new String(data, charset); + } + + /** + * 将编码的byteBuffer数据转换为字符串 + * + * @param data 数据 + * @param charset 字符集,如果为空使用当前系统字符集 + * @return 字符串 + */ + public static String str(ByteBuffer data, String charset) + { + if (data == null) + { + return null; + } + + return str(data, Charset.forName(charset)); + } + + /** + * 将编码的byteBuffer数据转换为字符串 + * + * @param data 数据 + * @param charset 字符集,如果为空使用当前系统字符集 + * @return 字符串 + */ + public static String str(ByteBuffer data, Charset charset) + { + if (null == charset) + { + charset = Charset.defaultCharset(); + } + return charset.decode(data).toString(); + } + + // ----------------------------------------------------------------------- 全角半角转换 + /** + * 半角转全角 + * + * @param input String. + * @return 全角字符串. + */ + public static String toSBC(String input) + { + return toSBC(input, null); + } + + /** + * 半角转全角 + * + * @param input String + * @param notConvertSet 不替换的字符集合 + * @return 全角字符串. + */ + public static String toSBC(String input, Set notConvertSet) + { + char[] c = input.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 跳过不替换的字符 + continue; + } + + if (c[i] == ' ') + { + c[i] = '\u3000'; + } + else if (c[i] < '\177') + { + c[i] = (char) (c[i] + 65248); + + } + } + return new String(c); + } + + /** + * 全角转半角 + * + * @param input String. + * @return 半角字符串 + */ + public static String toDBC(String input) + { + return toDBC(input, null); + } + + /** + * 替换全角为半角 + * + * @param text 文本 + * @param notConvertSet 不替换的字符集合 + * @return 替换后的字符 + */ + public static String toDBC(String text, Set notConvertSet) + { + char[] c = text.toCharArray(); + for (int i = 0; i < c.length; i++) + { + if (null != notConvertSet && notConvertSet.contains(c[i])) + { + // 跳过不替换的字符 + continue; + } + + if (c[i] == '\u3000') + { + c[i] = ' '; + } + else if (c[i] > '\uFF00' && c[i] < '\uFF5F') + { + c[i] = (char) (c[i] - 65248); + } + } + return new String(c); + } + + /** + * 数字金额大写转换 先写个完整的然后将如零拾替换成零 + * + * @param n 数字 + * @return 中文大写数字 + */ + public static String digitUppercase(double n) + { + String[] fraction = { "角", "分" }; + String[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }; + String[][] unit = { { "元", "万", "亿" }, { "", "拾", "佰", "仟" } }; + + String head = n < 0 ? "负" : ""; + n = Math.abs(n); + + String s = ""; + for (int i = 0; i < fraction.length; i++) + { + s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", ""); + } + if (s.length() < 1) + { + s = "整"; + } + int integerPart = (int) Math.floor(n); + + for (int i = 0; i < unit[0].length && integerPart > 0; i++) + { + String p = ""; + for (int j = 0; j < unit[1].length && n > 0; j++) + { + p = digit[integerPart % 10] + unit[1][j] + p; + integerPart = integerPart / 10; + } + s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s; + } + return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整"); + } +} diff --git a/src/main/java/com/zzlh/es/text/StrFormatter.java b/src/main/java/com/zzlh/es/text/StrFormatter.java new file mode 100644 index 0000000..b2da3a6 --- /dev/null +++ b/src/main/java/com/zzlh/es/text/StrFormatter.java @@ -0,0 +1,93 @@ +package com.zzlh.es.text; + + +import org.springframework.util.StringUtils; + +/** + * 字符串格式化 + * + * @author hckj + */ +public class StrFormatter +{ + public static final String EMPTY_JSON = "{}"; + public static final char C_BACKSLASH = '\\'; + public static final char C_DELIM_START = '{'; + public static final char C_DELIM_END = '}'; + + /** + * 格式化字符串
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ * + * @param strPattern 字符串模板 + * @param argArray 参数列表 + * @return 结果 + */ + public static String format(final String strPattern, final Object... argArray) + { + if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray)) + { + return strPattern; + } + final int strPatternLength = strPattern.length(); + + // 初始化定义好的长度以获得更好的性能 + StringBuilder sbuf = new StringBuilder(strPatternLength + 50); + + int handledPosition = 0; + int delimIndex;// 占位符所在位置 + for (int argIndex = 0; argIndex < argArray.length; argIndex++) + { + delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition); + if (delimIndex == -1) + { + if (handledPosition == 0) + { + return strPattern; + } + else + { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果 + sbuf.append(strPattern, handledPosition, strPatternLength); + return sbuf.toString(); + } + } + else + { + if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) + { + if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) + { + // 转义符之前还有一个转义符,占位符依旧有效 + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + else + { + // 占位符被转义 + argIndex--; + sbuf.append(strPattern, handledPosition, delimIndex - 1); + sbuf.append(C_DELIM_START); + handledPosition = delimIndex + 1; + } + } + else + { + // 正常占位符 + sbuf.append(strPattern, handledPosition, delimIndex); + sbuf.append(Convert.utf8Str(argArray[argIndex])); + handledPosition = delimIndex + 2; + } + } + } + // 加入最后一个占位符后所有的字符 + sbuf.append(strPattern, handledPosition, strPattern.length()); + + return sbuf.toString(); + } +} diff --git a/src/main/java/com/zzlh/es/utils/DateUtils.java b/src/main/java/com/zzlh/es/utils/DateUtils.java new file mode 100644 index 0000000..69eee4e --- /dev/null +++ b/src/main/java/com/zzlh/es/utils/DateUtils.java @@ -0,0 +1,180 @@ +package com.zzlh.es.utils; + +import org.apache.commons.lang3.time.DateFormatUtils; + +import java.lang.management.ManagementFactory; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.*; +import java.util.Date; + +/** + * 时间工具类 + * + * @author hckj + */ +public class DateUtils extends org.apache.commons.lang3.time.DateUtils +{ + public static String YYYY = "yyyy"; + + public static String YYYY_MM = "yyyy-MM"; + + public static String YYYY_MM_DD = "yyyy-MM-dd"; + + public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; + + public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; + + private static String[] parsePatterns = { + "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", + "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", + "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; + + /** + * 获取当前Date型日期 + * + * @return Date() 当前日期 + */ + public static Date getNowDate() + { + return new Date(); + } + + /** + * 获取当前日期, 默认格式为yyyy-MM-dd + * + * @return String + */ + public static String getDate() + { + return dateTimeNow(YYYY_MM_DD); + } + + public static final String getTime() + { + return dateTimeNow(YYYY_MM_DD_HH_MM_SS); + } + + public static final String dateTimeNow() + { + return dateTimeNow(YYYYMMDDHHMMSS); + } + + public static final String dateTimeNow(final String format) + { + return parseDateToStr(format, new Date()); + } + + public static final String dateTime(final Date date) + { + return parseDateToStr(YYYY_MM_DD, date); + } + + public static final String parseDateToStr(final String format, final Date date) + { + return new SimpleDateFormat(format).format(date); + } + + public static final Date dateTime(final String format, final String ts) + { + try + { + return new SimpleDateFormat(format).parse(ts); + } + catch (ParseException e) + { + throw new RuntimeException(e); + } + } + + /** + * 日期路径 即年/月/日 如2018/08/08 + */ + public static final String datePath() + { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyy/MM/dd"); + } + + /** + * 日期路径 即年/月/日 如20180808 + */ + public static final String dateTime() + { + Date now = new Date(); + return DateFormatUtils.format(now, "yyyyMMdd"); + } + + /** + * 日期型字符串转化为日期 格式 + */ + public static Date parseDate(Object str) + { + if (str == null) + { + return null; + } + try + { + return parseDate(str.toString(), parsePatterns); + } + catch (ParseException e) + { + return null; + } + } + + /** + * 获取服务器启动时间 + */ + public static Date getServerStartDate() + { + long time = ManagementFactory.getRuntimeMXBean().getStartTime(); + return new Date(time); + } + + /** + * 计算时间差 + * + * @param endTime 最后时间 + * @param startTime 开始时间 + * @return 时间差(天/小时/分钟) + */ + public static String timeDistance(Date endDate, Date startTime) + { + long nd = 1000 * 24 * 60 * 60; + long nh = 1000 * 60 * 60; + long nm = 1000 * 60; + // long ns = 1000; + // 获得两个时间的毫秒时间差异 + long diff = endDate.getTime() - startTime.getTime(); + // 计算差多少天 + long day = diff / nd; + // 计算差多少小时 + long hour = diff % nd / nh; + // 计算差多少分钟 + long min = diff % nd % nh / nm; + // 计算差多少秒//输出结果 + // long sec = diff % nd % nh % nm / ns; + return day + "天" + hour + "小时" + min + "分钟"; + } + + /** + * 增加 LocalDateTime ==> Date + */ + public static Date toDate(LocalDateTime temporalAccessor) + { + ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault()); + return Date.from(zdt.toInstant()); + } + + /** + * 增加 LocalDate ==> Date + */ + public static Date toDate(LocalDate temporalAccessor) + { + LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0)); + ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault()); + return Date.from(zdt.toInstant()); + } +} diff --git a/src/main/java/com/zzlh/es/utils/JwtTokenUtil.java b/src/main/java/com/zzlh/es/utils/JwtTokenUtil.java new file mode 100644 index 0000000..29faa2e --- /dev/null +++ b/src/main/java/com/zzlh/es/utils/JwtTokenUtil.java @@ -0,0 +1,130 @@ +package com.zzlh.es.utils; + + +import com.zzlh.es.entity.properties.JwtProperties; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +@Component +public class JwtTokenUtil implements Serializable { + + private static final long serialVersionUID = -3301605591108950415L; + + private static final String CLAIM_KEY_USERNAME = "sub"; + private static final String CLAIM_KEY_CREATED = "created"; + + @Autowired + private JwtProperties jwtProperties; + + public String getUsernameFromToken(String token) { + String username; + try { + final Claims claims = getClaimsFromToken(token); + username = claims.getSubject(); + } catch (Exception e) { + username = null; + } + return username; + } + + public Date getCreatedDateFromToken(String token) { + Date created; + try { + final Claims claims = getClaimsFromToken(token); + created = new Date((Long) claims.get(CLAIM_KEY_CREATED)); + } catch (Exception e) { + created = null; + } + return created; + } + + public Date getExpirationDateFromToken(String token) { + Date expiration; + try { + final Claims claims = getClaimsFromToken(token); + expiration = claims.getExpiration(); + } catch (Exception e) { + expiration = null; + } + return expiration; + } + + private Claims getClaimsFromToken(String token) { + Claims claims; + try { + claims = Jwts.parser() + .setSigningKey(jwtProperties.getSecret()) + .parseClaimsJws(token) + .getBody(); + } catch (Exception e) { + claims = null; + } + return claims; + } + + private Date generateExpirationDate() { + return new Date(System.currentTimeMillis() + jwtProperties.getExpiration()); + } + + public Boolean isTokenExpired(String token) { + final Date expiration = getExpirationDateFromToken(token); + return expiration.before(new Date()); + } + + private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) { + return (lastPasswordReset != null && created.before(lastPasswordReset)); + } + + public String generateToken(UserDetails userDetails) { + Map claims = new HashMap<>(); + claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername()); + claims.put(CLAIM_KEY_CREATED, new Date()); + return generateToken(claims); + } + + String generateToken(Map claims) { + return Jwts.builder() + .setClaims(claims) + .setExpiration(generateExpirationDate()) + .signWith(SignatureAlgorithm.HS512, jwtProperties.getSecret()) + .compact(); + } + + public Boolean canTokenBeRefreshed(String token, Date lastPasswordReset) { + final Date created = getCreatedDateFromToken(token); + return !isCreatedBeforeLastPasswordReset(created, lastPasswordReset) + && !isTokenExpired(token); + } + + public String refreshToken(String token) { + String refreshedToken; + try { + final Claims claims = getClaimsFromToken(token); + claims.put(CLAIM_KEY_CREATED, new Date()); + refreshedToken = generateToken(claims); + } catch (Exception e) { + refreshedToken = null; + } + return refreshedToken; + } + + public Boolean validateToken(String token, UserDetails userDetails) { + final String username = getUsernameFromToken(token); + final Date created = getCreatedDateFromToken(token); +// final Date expiration = getExpirationDateFromToken(token); + return ( + username.equals(userDetails.getUsername()) + && !isTokenExpired(token)); +// && !isCreatedBeforeLastPasswordReset(created, user.getLastPasswordResetDate())); + } +} + diff --git a/src/main/java/com/zzlh/es/utils/PageUtils.java b/src/main/java/com/zzlh/es/utils/PageUtils.java new file mode 100644 index 0000000..ff30be5 --- /dev/null +++ b/src/main/java/com/zzlh/es/utils/PageUtils.java @@ -0,0 +1,35 @@ +package com.zzlh.es.utils; + +import com.github.pagehelper.PageHelper; +import com.zzlh.es.page.PageDomain; +import com.zzlh.es.page.TableSupport; + + +/** + * 分页工具类 + * + * @author hckj + */ +public class PageUtils extends PageHelper +{ + /** + * 设置请求分页数据 + */ + public static void startPage() + { + PageDomain pageDomain = TableSupport.buildPageRequest(); + Integer pageNum = pageDomain.getPageNum(); + Integer pageSize = pageDomain.getPageSize(); + String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); + Boolean reasonable = pageDomain.getReasonable(); + PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable); + } + + /** + * 清理分页的线程变量 + */ + public static void clearPage() + { + PageHelper.clearPage(); + } +} diff --git a/src/main/java/com/zzlh/es/utils/RedisUtil.java b/src/main/java/com/zzlh/es/utils/RedisUtil.java new file mode 100644 index 0000000..044836e --- /dev/null +++ b/src/main/java/com/zzlh/es/utils/RedisUtil.java @@ -0,0 +1,573 @@ +package com.zzlh.es.utils; + +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * redis工具类 + * @author soeasy + */ +@Component +public class RedisUtil { + @Resource(name = "myRedisTemplate") + private RedisTemplate redisTemplate; + + /*public void setRedisTemplate(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + }*/ + + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + * @return + */ + public boolean expire(String key, long time) { + try { + if (time > 0) { + redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 根据key 获取过期时间 + * + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + public Long getExpire(String key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * 判断key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + try { + return redisTemplate.hasKey(key); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 删除缓存 + * + * @param key 可以传一个值 或多个 + */ + @SuppressWarnings("unchecked") + public boolean del(String... key) { + if (key != null && key.length > 0) { + if (key.length == 1) { + return redisTemplate.delete(key[0]); + } else { + return redisTemplate.delete(CollectionUtils.arrayToList(key))!=null; + + } + } + return false; + } + + // ============================String============================= + + /** + * 普通缓存获取 + * + * @param key 键 + * @return 值 + */ + public Object get(String key) { + return key == null ? null : redisTemplate.opsForValue().get(key); + } + + /** + * 普通缓存放入 + * + * @param key 键 + * @param value 值 + * @return true成功 false失败 + */ + public boolean set(String key, Object value) { + try { + redisTemplate.opsForValue().set(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 递增 + * + * @param key 键 + * @param delta 要增加几(大于0) + * @return + */ + public long incr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递增因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, delta); + } + + /** + * 递减 + * + * @param key 键 + * @param delta 要减少几(小于0) + * @return + */ + public long decr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递减因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, -delta); + } + + // ================================Map================================= + + /** + * HashGet + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return 值 + */ + public Object hget(String key, String item) { + return redisTemplate.opsForHash().get(key, item); + } + + /** + * 获取hashKey对应的所有键值 + * + * @param key 键 + * @return 对应的多个键值 + */ + public Map hmget(String key) { + return redisTemplate.opsForHash().entries(key); + } + + /** + * HashSet + * + * @param key 键 + * @param map 对应多个键值 + * @return true 成功 false 失败 + */ + public boolean hmset(String key, Map map) { + try { + redisTemplate.opsForHash().putAll(key, map); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * HashSet 并设置时间 + * + * @param key 键 + * @param map 对应多个键值 + * @param time 时间(秒) + * @return true成功 false失败 + */ + public boolean hmset(String key, Map map, long time) { + try { + redisTemplate.opsForHash().putAll(key, map); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value) { + try { + redisTemplate.opsForHash().put(key, item, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value, long time) { + try { + redisTemplate.opsForHash().put(key, item, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 删除hash表中的值 + * + * @param key 键 不能为null + * @param item 项 可以使多个 不能为null + */ + public void hdel(String key, Object... item) { + redisTemplate.opsForHash().delete(key, item); + } + + /** + * 判断hash表中是否有该项的值 + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return true 存在 false不存在 + */ + public boolean hHasKey(String key, String item) { + return redisTemplate.opsForHash().hasKey(key, item); + } + + /** + * hash递增 如果不存在,就会创建一个 并把新增后的值返回 + * + * @param key 键 + * @param item 项 + * @param by 要增加几(大于0) + * @return + */ + public double hincr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, by); + } + + /** + * hash递减 + * + * @param key 键 + * @param item 项 + * @param by 要减少记(小于0) + * @return + */ + public double hdecr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, -by); + } + + // ============================set============================= + + /** + * 根据key获取Set中的所有值 + * + * @param key 键 + * @return + */ + public Set sGet(String key) { + try { + return redisTemplate.opsForSet().members(key); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 根据value从一个set中查询,是否存在 + * + * @param key 键 + * @param value 值 + * @return true 存在 false不存在 + */ + public boolean sHasKey(String key, Object value) { + try { + return redisTemplate.opsForSet().isMember(key, value); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将数据放入set缓存 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSet(String key, Object... values) { + try { + return redisTemplate.opsForSet().add(key, values); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 将set数据放入缓存 + * + * @param key 键 + * @param time 时间(秒) + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSetAndTime(String key, long time, Object... values) { + try { + Long count = redisTemplate.opsForSet().add(key, values); + if (time > 0) + expire(key, time); + return count; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 获取set缓存的长度 + * + * @param key 键 + * @return + */ + public long sGetSetSize(String key) { + try { + return redisTemplate.opsForSet().size(key); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 移除值为value的 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 移除的个数 + */ + public long setRemove(String key, Object... values) { + try { + Long count = redisTemplate.opsForSet().remove(key, values); + return count; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + // ===============================list================================= + + /** + * 获取list缓存的内容 + * + * @param key 键 + * @param start 开始 + * @param end 结束 0 到 -1代表所有值 + * @return + */ + public List lGet(String key, long start, long end) { + try { + return redisTemplate.opsForList().range(key, start, end); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 获取list缓存的长度 + * + * @param key 键 + * @return + */ + public long lGetListSize(String key) { + try { + return redisTemplate.opsForList().size(key); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 通过索引 获取list中的值 + * + * @param key 键 + * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 + * @return + */ + public Object lGetIndex(String key, long index) { + try { + return redisTemplate.opsForList().index(key, index); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, Object value) { + try { + redisTemplate.opsForList().rightPush(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, Object value, long time) { + try { + redisTemplate.opsForList().rightPush(key, value); + if (time > 0) + expire(key, time); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @return + */ + public boolean lSet(String key, List value) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, List value, long time) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + if (time > 0) + expire(key, time); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 根据索引修改list中的某条数据 + * + * @param key 键 + * @param index 索引 + * @param value 值 + * @return + */ + public boolean lUpdateIndex(String key, long index, Object value) { + try { + redisTemplate.opsForList().set(key, index, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 移除N个值为value + * + * @param key 键 + * @param count 移除多少个 + * @param value 值 + * @return 移除的个数 + */ + public long lRemove(String key, long count, Object value) { + try { + Long remove = redisTemplate.opsForList().remove(key, count, value); + return remove; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } +} diff --git a/src/main/java/com/zzlh/es/utils/ReflectUtils.java b/src/main/java/com/zzlh/es/utils/ReflectUtils.java new file mode 100644 index 0000000..409777f --- /dev/null +++ b/src/main/java/com/zzlh/es/utils/ReflectUtils.java @@ -0,0 +1,406 @@ +package com.zzlh.es.utils; + + +import com.zzlh.es.text.Convert; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.apache.poi.ss.usermodel.DateUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.*; +import java.util.Date; + +/** + * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数. + * + * @author hckj + */ +@SuppressWarnings("rawtypes") +public class ReflectUtils +{ + private static final String SETTER_PREFIX = "set"; + + private static final String GETTER_PREFIX = "get"; + + private static final String CGLIB_CLASS_SEPARATOR = "$$"; + + private static Logger logger = LoggerFactory.getLogger(ReflectUtils.class); + + /** + * 调用Getter方法. + * 支持多级,如:对象名.对象名.方法 + */ + @SuppressWarnings("unchecked") + public static E invokeGetter(Object obj, String propertyName) + { + Object object = obj; + for (String name : StringUtils.split(propertyName, ".")) + { + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + return (E) object; + } + + /** + * 调用Setter方法, 仅匹配方法名。 + * 支持多级,如:对象名.对象名.方法 + */ + public static void invokeSetter(Object obj, String propertyName, E value) + { + Object object = obj; + String[] names = StringUtils.split(propertyName, "."); + for (int i = 0; i < names.length; i++) + { + if (i < names.length - 1) + { + String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]); + object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); + } + else + { + String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]); + invokeMethodByName(object, setterMethodName, new Object[] { value }); + } + } + } + + /** + * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数. + */ + @SuppressWarnings("unchecked") + public static E getFieldValue(final Object obj, final String fieldName) + { + Field field = getAccessibleField(obj, fieldName); + if (field == null) + { + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + return null; + } + E result = null; + try + { + result = (E) field.get(obj); + } + catch (IllegalAccessException e) + { + logger.error("不可能抛出的异常{}", e.getMessage()); + } + return result; + } + + /** + * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数. + */ + public static void setFieldValue(final Object obj, final String fieldName, final E value) + { + Field field = getAccessibleField(obj, fieldName); + if (field == null) + { + // throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 "); + return; + } + try + { + field.set(obj, value); + } + catch (IllegalAccessException e) + { + logger.error("不可能抛出的异常: {}", e.getMessage()); + } + } + + /** + * 直接调用对象方法, 无视private/protected修饰符. + * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用. + * 同时匹配方法名+参数类型, + */ + @SuppressWarnings("unchecked") + public static E invokeMethod(final Object obj, final String methodName, final Class[] parameterTypes, + final Object[] args) + { + if (obj == null || methodName == null) + { + return null; + } + Method method = getAccessibleMethod(obj, methodName, parameterTypes); + if (method == null) + { + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 "); + return null; + } + try + { + return (E) method.invoke(obj, args); + } + catch (Exception e) + { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 直接调用对象方法, 无视private/protected修饰符, + * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用. + * 只匹配函数名,如果有多个同名函数调用第一个。 + */ + @SuppressWarnings("unchecked") + public static E invokeMethodByName(final Object obj, final String methodName, final Object[] args) + { + Method method = getAccessibleMethodByName(obj, methodName, args.length); + if (method == null) + { + // 如果为空不报错,直接返回空。 + logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 "); + return null; + } + try + { + // 类型转换(将参数数据类型转换为目标方法参数类型) + Class[] cs = method.getParameterTypes(); + for (int i = 0; i < cs.length; i++) + { + if (args[i] != null && !args[i].getClass().equals(cs[i])) + { + if (cs[i] == String.class) + { + args[i] = Convert.toStr(args[i]); + if (StringUtils.endsWith((String) args[i], ".0")) + { + args[i] = StringUtils.substringBefore((String) args[i], ".0"); + } + } + else if (cs[i] == Integer.class) + { + args[i] = Convert.toInt(args[i]); + } + else if (cs[i] == Long.class) + { + args[i] = Convert.toLong(args[i]); + } + else if (cs[i] == Double.class) + { + args[i] = Convert.toDouble(args[i]); + } + else if (cs[i] == Float.class) + { + args[i] = Convert.toFloat(args[i]); + } + else if (cs[i] == Date.class) + { + if (args[i] instanceof String) + { + args[i] = DateUtils.parseDate(args[i]); + } + else + { + args[i] = DateUtil.getJavaDate((Double) args[i]); + } + } + else if (cs[i] == boolean.class || cs[i] == Boolean.class) + { + args[i] = Convert.toBool(args[i]); + } + } + } + return (E) method.invoke(obj, args); + } + catch (Exception e) + { + String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; + throw convertReflectionExceptionToUnchecked(msg, e); + } + } + + /** + * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + */ + public static Field getAccessibleField(final Object obj, final String fieldName) + { + // 为空不报错。直接返回 null + if (obj == null) + { + return null; + } + Validate.notBlank(fieldName, "fieldName can't be blank"); + for (Class superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) + { + try + { + Field field = superClass.getDeclaredField(fieldName); + makeAccessible(field); + return field; + } + catch (NoSuchFieldException e) + { + continue; + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 匹配函数名+参数类型。 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethod(final Object obj, final String methodName, + final Class... parameterTypes) + { + // 为空不报错。直接返回 null + if (obj == null) + { + return null; + } + Validate.notBlank(methodName, "methodName can't be blank"); + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) + { + try + { + Method method = searchType.getDeclaredMethod(methodName, parameterTypes); + makeAccessible(method); + return method; + } + catch (NoSuchMethodException e) + { + continue; + } + } + return null; + } + + /** + * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. + * 如向上转型到Object仍无法找到, 返回null. + * 只匹配函数名。 + * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) + */ + public static Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum) + { + // 为空不报错。直接返回 null + if (obj == null) + { + return null; + } + Validate.notBlank(methodName, "methodName can't be blank"); + for (Class searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) + { + Method[] methods = searchType.getDeclaredMethods(); + for (Method method : methods) + { + if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum) + { + makeAccessible(method); + return method; + } + } + } + return null; + } + + /** + * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + */ + public static void makeAccessible(Method method) + { + if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) + && !method.isAccessible()) + { + method.setAccessible(true); + } + } + + /** + * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 + */ + public static void makeAccessible(Field field) + { + if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) + || Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) + { + field.setAccessible(true); + } + } + + /** + * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处 + * 如无法找到, 返回Object.class. + */ + @SuppressWarnings("unchecked") + public static Class getClassGenricType(final Class clazz) + { + return getClassGenricType(clazz, 0); + } + + /** + * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. + * 如无法找到, 返回Object.class. + */ + public static Class getClassGenricType(final Class clazz, final int index) + { + Type genType = clazz.getGenericSuperclass(); + + if (!(genType instanceof ParameterizedType)) + { + logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType"); + return Object.class; + } + + Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); + + if (index >= params.length || index < 0) + { + logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + + params.length); + return Object.class; + } + if (!(params[index] instanceof Class)) + { + logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); + return Object.class; + } + + return (Class) params[index]; + } + + public static Class getUserClass(Object instance) + { + if (instance == null) + { + throw new RuntimeException("Instance must not be null"); + } + Class clazz = instance.getClass(); + if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) + { + Class superClass = clazz.getSuperclass(); + if (superClass != null && !Object.class.equals(superClass)) + { + return superClass; + } + } + return clazz; + + } + + /** + * 将反射时的checked exception转换为unchecked exception. + */ + public static RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e) + { + if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException + || e instanceof NoSuchMethodException) + { + return new IllegalArgumentException(msg, e); + } + else if (e instanceof InvocationTargetException) + { + return new RuntimeException(msg, ((InvocationTargetException) e).getTargetException()); + } + return new RuntimeException(msg, e); + } +} diff --git a/src/main/java/com/zzlh/es/utils/RequestUtil.java b/src/main/java/com/zzlh/es/utils/RequestUtil.java new file mode 100644 index 0000000..c019c79 --- /dev/null +++ b/src/main/java/com/zzlh/es/utils/RequestUtil.java @@ -0,0 +1,20 @@ +package com.zzlh.es.utils; + +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +import javax.servlet.http.HttpServletRequest; + + +/** + * 获取request访问路径对比 + * @author soeasy + */ +public class RequestUtil { + public static boolean matchers(String url, HttpServletRequest request) { + AntPathRequestMatcher matcher = new AntPathRequestMatcher(url); + if (matcher.matches(request)) { + return true; + } + return false; + } +} diff --git a/src/main/java/com/zzlh/es/utils/ServletUtils.java b/src/main/java/com/zzlh/es/utils/ServletUtils.java new file mode 100644 index 0000000..c8fecc7 --- /dev/null +++ b/src/main/java/com/zzlh/es/utils/ServletUtils.java @@ -0,0 +1,335 @@ +package com.zzlh.es.utils; + +import com.alibaba.fastjson2.JSON; + +import com.zzlh.es.constant.Constants; +import com.zzlh.es.domain.R; +import com.zzlh.es.text.Convert; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.util.LinkedCaseInsensitiveMap; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import reactor.core.publisher.Mono; + +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +/** + * 客户端工具类 + * + * @author hckj + */ +public class ServletUtils +{ + /** + * 获取String参数 + */ + public static String getParameter(String name) + { + return getRequest().getParameter(name); + } + + /** + * 获取String参数 + */ + public static String getParameter(String name, String defaultValue) + { + return Convert.toStr(getRequest().getParameter(name), defaultValue); + } + + /** + * 获取Integer参数 + */ + public static Integer getParameterToInt(String name) + { + return Convert.toInt(getRequest().getParameter(name)); + } + + /** + * 获取Integer参数 + */ + public static Integer getParameterToInt(String name, Integer defaultValue) + { + return Convert.toInt(getRequest().getParameter(name), defaultValue); + } + + /** + * 获取Boolean参数 + */ + public static Boolean getParameterToBool(String name) + { + return Convert.toBool(getRequest().getParameter(name)); + } + + /** + * 获取Boolean参数 + */ + public static Boolean getParameterToBool(String name, Boolean defaultValue) + { + return Convert.toBool(getRequest().getParameter(name), defaultValue); + } + + /** + * 获得所有请求参数 + * + * @param request 请求对象{@link ServletRequest} + * @return Map + */ + public static Map getParams(ServletRequest request) + { + final Map map = request.getParameterMap(); + return Collections.unmodifiableMap(map); + } + + /** + * 获得所有请求参数 + * + * @param request 请求对象{@link ServletRequest} + * @return Map + */ + public static Map getParamMap(ServletRequest request) + { + Map params = new HashMap<>(); + for (Map.Entry entry : getParams(request).entrySet()) + { + params.put(entry.getKey(), StringUtils.join(entry.getValue(), ",")); + } + return params; + } + + /** + * 获取request + */ + public static HttpServletRequest getRequest() + { + try + { + return getRequestAttributes().getRequest(); + } + catch (Exception e) + { + return null; + } + } + + /** + * 获取response + */ + public static HttpServletResponse getResponse() + { + try + { + return getRequestAttributes().getResponse(); + } + catch (Exception e) + { + return null; + } + } + + /** + * 获取session + */ + public static HttpSession getSession() + { + return getRequest().getSession(); + } + + public static ServletRequestAttributes getRequestAttributes() + { + try + { + RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); + return (ServletRequestAttributes) attributes; + } + catch (Exception e) + { + return null; + } + } + + public static String getHeader(HttpServletRequest request, String name) + { + String value = request.getHeader(name); + if (StringUtils.isEmpty(value)) + { + return StringUtils.EMPTY; + } + return urlDecode(value); + } + + public static Map getHeaders(HttpServletRequest request) + { + Map map = new LinkedCaseInsensitiveMap<>(); + Enumeration enumeration = request.getHeaderNames(); + if (enumeration != null) + { + while (enumeration.hasMoreElements()) + { + String key = enumeration.nextElement(); + String value = request.getHeader(key); + map.put(key, value); + } + } + return map; + } + + /** + * 将字符串渲染到客户端 + * + * @param response 渲染对象 + * @param string 待渲染的字符串 + */ + public static void renderString(HttpServletResponse response, String string) + { + try + { + response.setStatus(200); + response.setContentType("application/json"); + response.setCharacterEncoding("utf-8"); + response.getWriter().print(string); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + /** + * 是否是Ajax异步请求 + * + * @param request + */ + public static boolean isAjaxRequest(HttpServletRequest request) + { + String accept = request.getHeader("accept"); + if (accept != null && accept.contains("application/json")) + { + return true; + } + + String xRequestedWith = request.getHeader("X-Requested-With"); + if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) + { + return true; + } + + String uri = request.getRequestURI(); + if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")) + { + return true; + } + + String ajax = request.getParameter("__ajax"); + return StringUtils.inStringIgnoreCase(ajax, "json", "xml"); + } + + /** + * 内容编码 + * + * @param str 内容 + * @return 编码后的内容 + */ + public static String urlEncode(String str) + { + try + { + return URLEncoder.encode(str, Constants.UTF8); + } + catch (UnsupportedEncodingException e) + { + return StringUtils.EMPTY; + } + } + + /** + * 内容解码 + * + * @param str 内容 + * @return 解码后的内容 + */ + public static String urlDecode(String str) + { + try + { + return URLDecoder.decode(str, Constants.UTF8); + } + catch (UnsupportedEncodingException e) + { + return StringUtils.EMPTY; + } + } + + /** + * 设置webflux模型响应 + * + * @param response ServerHttpResponse + * @param value 响应内容 + * @return Mono + */ + public static Mono webFluxResponseWriter(ServerHttpResponse response, Object value) + { + return webFluxResponseWriter(response, HttpStatus.OK, value, R.FAIL); + } + + /** + * 设置webflux模型响应 + * + * @param response ServerHttpResponse + * @param code 响应状态码 + * @param value 响应内容 + * @return Mono + */ + public static Mono webFluxResponseWriter(ServerHttpResponse response, Object value, int code) + { + return webFluxResponseWriter(response, HttpStatus.OK, value, code); + } + + /** + * 设置webflux模型响应 + * + * @param response ServerHttpResponse + * @param status http状态码 + * @param code 响应状态码 + * @param value 响应内容 + * @return Mono + */ + public static Mono webFluxResponseWriter(ServerHttpResponse response, HttpStatus status, Object value, int code) + { + return webFluxResponseWriter(response, MediaType.APPLICATION_JSON_VALUE, status, value, code); + } + + /** + * 设置webflux模型响应 + * + * @param response ServerHttpResponse + * @param contentType content-type + * @param status http状态码 + * @param code 响应状态码 + * @param value 响应内容 + * @return Mono + */ + public static Mono webFluxResponseWriter(ServerHttpResponse response, String contentType, HttpStatus status, Object value, int code) + { + response.setStatusCode(status); + response.getHeaders().add(HttpHeaders.CONTENT_TYPE, contentType); + R result = R.fail(code, value.toString()); + DataBuffer dataBuffer = response.bufferFactory().wrap(JSON.toJSONString(result).getBytes()); + return response.writeWith(Mono.just(dataBuffer)); + } +} diff --git a/src/main/java/com/zzlh/es/utils/SqlUtil.java b/src/main/java/com/zzlh/es/utils/SqlUtil.java new file mode 100644 index 0000000..2798b0d --- /dev/null +++ b/src/main/java/com/zzlh/es/utils/SqlUtil.java @@ -0,0 +1,61 @@ +package com.zzlh.es.utils; + + +import com.zzlh.es.exception.UtilException; + +/** + * sql操作工具类 + * + * @author hckj + */ +public class SqlUtil +{ + /** + * 定义常用的 sql关键字 + */ + public static String SQL_REGEX = "and |extractvalue|updatexml|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |+|user()"; + + /** + * 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序) + */ + public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+"; + + /** + * 检查字符,防止注入绕过 + */ + public static String escapeOrderBySql(String value) + { + if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) + { + throw new UtilException("参数不符合规范,不能进行查询"); + } + return value; + } + + /** + * 验证 order by 语法是否符合规范 + */ + public static boolean isValidOrderBySql(String value) + { + return value.matches(SQL_PATTERN); + } + + /** + * SQL关键字检查 + */ + public static void filterKeyword(String value) + { + if (StringUtils.isEmpty(value)) + { + return; + } + String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|"); + for (String sqlKeyword : sqlKeywords) + { + if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) + { + throw new UtilException("参数存在SQL注入风险"); + } + } + } +} diff --git a/src/main/java/com/zzlh/es/utils/StringUtils.java b/src/main/java/com/zzlh/es/utils/StringUtils.java new file mode 100644 index 0000000..518d38d --- /dev/null +++ b/src/main/java/com/zzlh/es/utils/StringUtils.java @@ -0,0 +1,563 @@ +package com.zzlh.es.utils; + + +import com.zzlh.es.constant.Constants; +import com.zzlh.es.text.StrFormatter; +import org.springframework.util.AntPathMatcher; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 字符串工具类 + * + * @author hckj + */ +public class StringUtils extends org.apache.commons.lang3.StringUtils +{ + /** 空字符串 */ + private static final String NULLSTR = ""; + + /** 下划线 */ + private static final char SEPARATOR = '_'; + + /** + * 获取参数不为空值 + * + * @param value defaultValue 要判断的value + * @return value 返回值 + */ + public static T nvl(T value, T defaultValue) + { + return value != null ? value : defaultValue; + } + + /** + * * 判断一个Collection是否为空, 包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Collection coll) + { + return isNull(coll) || coll.isEmpty(); + } + + /** + * * 判断一个Collection是否非空,包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Collection coll) + { + return !isEmpty(coll); + } + + /** + * * 判断一个对象数组是否为空 + * + * @param objects 要判断的对象数组 + ** @return true:为空 false:非空 + */ + public static boolean isEmpty(Object[] objects) + { + return isNull(objects) || (objects.length == 0); + } + + /** + * * 判断一个对象数组是否非空 + * + * @param objects 要判断的对象数组 + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Object[] objects) + { + return !isEmpty(objects); + } + + /** + * * 判断一个Map是否为空 + * + * @param map 要判断的Map + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Map map) + { + return isNull(map) || map.isEmpty(); + } + + /** + * * 判断一个Map是否为空 + * + * @param map 要判断的Map + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Map map) + { + return !isEmpty(map); + } + + /** + * * 判断一个字符串是否为空串 + * + * @param str String + * @return true:为空 false:非空 + */ + public static boolean isEmpty(String str) + { + return isNull(str) || NULLSTR.equals(str.trim()); + } + + /** + * * 判断一个字符串是否为非空串 + * + * @param str String + * @return true:非空串 false:空串 + */ + public static boolean isNotEmpty(String str) + { + return !isEmpty(str); + } + + /** + * * 判断一个对象是否为空 + * + * @param object Object + * @return true:为空 false:非空 + */ + public static boolean isNull(Object object) + { + return object == null; + } + + /** + * * 判断一个对象是否非空 + * + * @param object Object + * @return true:非空 false:空 + */ + public static boolean isNotNull(Object object) + { + return !isNull(object); + } + + /** + * * 判断一个对象是否是数组类型(Java基本型别的数组) + * + * @param object 对象 + * @return true:是数组 false:不是数组 + */ + public static boolean isArray(Object object) + { + return isNotNull(object) && object.getClass().isArray(); + } + + /** + * 去空格 + */ + public static String trim(String str) + { + return (str == null ? "" : str.trim()); + } + + /** + * 截取字符串 + * + * @param str 字符串 + * @param start 开始 + * @return 结果 + */ + public static String substring(final String str, int start) + { + if (str == null) + { + return NULLSTR; + } + + if (start < 0) + { + start = str.length() + start; + } + + if (start < 0) + { + start = 0; + } + if (start > str.length()) + { + return NULLSTR; + } + + return str.substring(start); + } + + /** + * 截取字符串 + * + * @param str 字符串 + * @param start 开始 + * @param end 结束 + * @return 结果 + */ + public static String substring(final String str, int start, int end) + { + if (str == null) + { + return NULLSTR; + } + + if (end < 0) + { + end = str.length() + end; + } + if (start < 0) + { + start = str.length() + start; + } + + if (end > str.length()) + { + end = str.length(); + } + + if (start > end) + { + return NULLSTR; + } + + if (start < 0) + { + start = 0; + } + if (end < 0) + { + end = 0; + } + + return str.substring(start, end); + } + + /** + * 判断是否为空,并且不是空白字符 + * + * @param str 要判断的value + * @return 结果 + */ + public static boolean hasText(String str) + { + return (str != null && !str.isEmpty() && containsText(str)); + } + + private static boolean containsText(CharSequence str) + { + int strLen = str.length(); + for (int i = 0; i < strLen; i++) + { + if (!Character.isWhitespace(str.charAt(i))) + { + return true; + } + } + return false; + } + + /** + * 格式化文本, {} 表示占位符
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ * + * @param template 文本模板,被替换的部分用 {} 表示 + * @param params 参数值 + * @return 格式化后的文本 + */ + public static String format(String template, Object... params) + { + if (isEmpty(params) || isEmpty(template)) + { + return template; + } + return StrFormatter.format(template, params); + } + + /** + * 是否为http(s)://开头 + * + * @param link 链接 + * @return 结果 + */ + public static boolean ishttp(String link) + { + return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS); + } + + /** + * 判断给定的set列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value + * + * @param + * @param array 给定的数组 + * @return boolean 结果 + */ + public static boolean containsAny(Collection collection, String... array) + { + if (isEmpty(collection) || isEmpty(array)) + { + return false; + } + else + { + for (String str : array) + { + if (collection.contains(str)) + { + return true; + } + } + return false; + } + } + + /** + * 驼峰转下划线命名 + */ + public static String toUnderScoreCase(String str) + { + if (str == null) + { + return null; + } + StringBuilder sb = new StringBuilder(); + // 前置字符是否大写 + boolean preCharIsUpperCase = true; + // 当前字符是否大写 + boolean curreCharIsUpperCase = true; + // 下一字符是否大写 + boolean nexteCharIsUpperCase = true; + for (int i = 0; i < str.length(); i++) + { + char c = str.charAt(i); + if (i > 0) + { + preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1)); + } + else + { + preCharIsUpperCase = false; + } + + curreCharIsUpperCase = Character.isUpperCase(c); + + if (i < (str.length() - 1)) + { + nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1)); + } + + if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) + { + sb.append(SEPARATOR); + } + else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) + { + sb.append(SEPARATOR); + } + sb.append(Character.toLowerCase(c)); + } + + return sb.toString(); + } + + /** + * 是否包含字符串 + * + * @param str 验证字符串 + * @param strs 字符串组 + * @return 包含返回true + */ + public static boolean inStringIgnoreCase(String str, String... strs) + { + if (str != null && strs != null) + { + for (String s : strs) + { + if (str.equalsIgnoreCase(trim(s))) + { + return true; + } + } + } + return false; + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld + * + * @param name 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String convertToCamelCase(String name) + { + StringBuilder result = new StringBuilder(); + // 快速检查 + if (name == null || name.isEmpty()) + { + // 没必要转换 + return ""; + } + else if (!name.contains("_")) + { + // 不含下划线,仅将首字母大写 + return name.substring(0, 1).toUpperCase() + name.substring(1); + } + // 用下划线将原始字符串分割 + String[] camels = name.split("_"); + for (String camel : camels) + { + // 跳过原始字符串中开头、结尾的下换线或双重下划线 + if (camel.isEmpty()) + { + continue; + } + // 首字母大写 + result.append(camel.substring(0, 1).toUpperCase()); + result.append(camel.substring(1).toLowerCase()); + } + return result.toString(); + } + + /** + * 驼峰式命名法 + * 例如:user_name->userName + */ + public static String toCamelCase(String s) + { + if (s == null) + { + return null; + } + if (s.indexOf(SEPARATOR) == -1) + { + return s; + } + s = s.toLowerCase(); + StringBuilder sb = new StringBuilder(s.length()); + boolean upperCase = false; + for (int i = 0; i < s.length(); i++) + { + char c = s.charAt(i); + + if (c == SEPARATOR) + { + upperCase = true; + } + else if (upperCase) + { + sb.append(Character.toUpperCase(c)); + upperCase = false; + } + else + { + sb.append(c); + } + } + return sb.toString(); + } + + /** + * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串 + * + * @param str 指定字符串 + * @param strs 需要检查的字符串数组 + * @return 是否匹配 + */ + public static boolean matches(String str, List strs) + { + if (isEmpty(str) || isEmpty(strs)) + { + return false; + } + for (String pattern : strs) + { + if (isMatch(pattern, str)) + { + return true; + } + } + return false; + } + + /** + * 判断url是否与规则配置: + * ? 表示单个字符; + * * 表示一层路径内的任意字符串,不可跨层级; + * ** 表示任意层路径; + * + * @param pattern 匹配规则 + * @param url 需要匹配的url + * @return + */ + public static boolean isMatch(String pattern, String url) + { + AntPathMatcher matcher = new AntPathMatcher(); + return matcher.match(pattern, url); + } + + @SuppressWarnings("unchecked") + public static T cast(Object obj) + { + return (T) obj; + } + + /** + * 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。 + * + * @param num 数字对象 + * @param size 字符串指定长度 + * @return 返回数字的字符串格式,该字符串为指定长度。 + */ + public static final String padl(final Number num, final int size) + { + return padl(num.toString(), size, '0'); + } + + /** + * 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。 + * + * @param s 原始字符串 + * @param size 字符串指定长度 + * @param c 用于补齐的字符 + * @return 返回指定长度的字符串,由原字符串左补齐或截取得到。 + */ + public static final String padl(final String s, final int size, final char c) + { + final StringBuilder sb = new StringBuilder(size); + if (s != null) + { + final int len = s.length(); + if (s.length() <= size) + { + for (int i = size - len; i > 0; i--) + { + sb.append(c); + } + sb.append(s); + } + else + { + return s.substring(len - size, len); + } + } + else + { + for (int i = size; i > 0; i--) + { + sb.append(c); + } + } + return sb.toString(); + } +} diff --git a/src/main/java/com/zzlh/es/utils/UserHolder.java b/src/main/java/com/zzlh/es/utils/UserHolder.java new file mode 100644 index 0000000..4c6e7ed --- /dev/null +++ b/src/main/java/com/zzlh/es/utils/UserHolder.java @@ -0,0 +1,36 @@ +package com.zzlh.es.utils; + + +import com.zzlh.es.entity.TUser; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; + +/** + * security直接获取当前用户的信息 + * @author soeasy + */ + +public class UserHolder { + /** + * user + * @return + */ + public static TUser getUserDetail(){ + SecurityContext ctx = SecurityContextHolder.getContext(); + Authentication auth = ctx.getAuthentication(); + TUser user = (TUser) auth.getPrincipal(); + return user; + } + + /** + * id + * @return + */ + public static int getUserId(){ + SecurityContext ctx = SecurityContextHolder.getContext(); + Authentication auth = ctx.getAuthentication(); + TUser user = (TUser) auth.getPrincipal(); + return user.getId(); + } +} diff --git a/src/main/java/com/zzlh/es/utils/VerifyCodeUtil.java b/src/main/java/com/zzlh/es/utils/VerifyCodeUtil.java new file mode 100644 index 0000000..e2fbe6b --- /dev/null +++ b/src/main/java/com/zzlh/es/utils/VerifyCodeUtil.java @@ -0,0 +1,121 @@ +package com.zzlh.es.utils; + +import javax.servlet.http.HttpSession; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.*; + + +public class VerifyCodeUtil { + public static final String SESSION_KEY = "verifyCode"; + public static final String BUFFIMG_KEY = "buffImg"; + /** + * 验证码图片的宽度。 + */ + private static int width = 100; + public static final long VERIFYCODE_TIMEOUT = 30*1000;//一分钟 + + /** + * 验证码图片的高度。 + */ + private static int height = 30; + + /** + * 验证码字符个数 + */ + private static int codeCount = 4; + + /** + * 字体高度 + */ + private static int fontHeight; + + /** + * 干扰线数量 + */ + private static int interLine = 12; + + /** + * 第一个字符的x轴值,因为后面的字符坐标依次递增,所以它们的x轴值是codeX的倍数 + */ + private static int codeX; + + /** + * codeY ,验证字符的y轴值,因为并行所以值一样 + */ + private static int codeY; + + /** + * codeSequence 表示字符允许出现的序列值 + */ + static char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + public static Map getVerifyCode(){ + Map result = new HashMap<>(); + //width-4 除去左右多余的位置,使验证码更加集中显示,减得越多越集中。 + //codeCount+1 //等比分配显示的宽度,包括左右两边的空格 + codeX = (width-4) / (codeCount+1); + //height - 10 集中显示验证码 + fontHeight = height - 10; + codeY = height - 7; + // 定义图像buffer + BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics2D gd = buffImg.createGraphics(); + // 创建一个随机数生成器类 + Random random = new Random(); + // 将图像填充为白色 + gd.setColor(Color.WHITE); + gd.fillRect(0, 0, width, height); + // 创建字体,字体的大小应该根据图片的高度来定。 + Font font = new Font("Times New Roman", Font.PLAIN, fontHeight); + // 设置字体。 + gd.setFont(font); + // 画边框。 + gd.setColor(Color.BLACK); + gd.drawRect(0, 0, width - 1, height - 1); + // 随机产生16条干扰线,使图象中的认证码不易被其它程序探测到。 + gd.setColor(Color.gray); + for (int i = 0; i < interLine; i++) { + int x = random.nextInt(width); + int y = random.nextInt(height); + int xl = random.nextInt(12); + int yl = random.nextInt(12); + gd.drawLine(x, y, x + xl, y + yl); + } + // randomCode用于保存随机产生的验证码,以便用户登录后进行验证。 + StringBuffer randomCode = new StringBuffer(); + int red = 0, green = 0, blue = 0; + // 随机产生codeCount数字的验证码。 + for (int i = 0; i < codeCount; i++) { + // 得到随机产生的验证码数字。 + String strRand = String.valueOf(codeSequence[random.nextInt(36)]); + // 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。 + red = random.nextInt(255); + green = random.nextInt(255); + blue = random.nextInt(255); + // 用随机产生的颜色将验证码绘制到图像中。 + gd.setColor(new Color(red,green,blue)); + gd.drawString(strRand, (i + 1) * codeX, codeY); + // 将产生的四个随机数组合在一起。 + randomCode.append(strRand); + } + result.put(BUFFIMG_KEY, buffImg); + result.put(SESSION_KEY, randomCode.toString()); + return result; + } + /** + * 定时删除session中存在的验证码信息 + * @param session + */ + public static void removeAttrbute(final HttpSession session) { + final Timer timer = new Timer(); + timer.schedule(new TimerTask() { + @Override + public void run() { + session.removeAttribute(SESSION_KEY); + timer.cancel(); + } + }, VERIFYCODE_TIMEOUT); + } +} diff --git a/src/main/java/com/zzlh/es/utils/ZipUtil.java b/src/main/java/com/zzlh/es/utils/ZipUtil.java new file mode 100644 index 0000000..cddb3d6 --- /dev/null +++ b/src/main/java/com/zzlh/es/utils/ZipUtil.java @@ -0,0 +1,161 @@ +package com.zzlh.es.utils; + +import cn.hutool.core.io.FileUtil; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.Enumeration; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; +import java.util.zip.ZipOutputStream; + +/** + * @author LGD + */ +public class ZipUtil { + + private static int BUFFER = 1024; + + public static void main(String[] args) throws Exception{ + + // unzip("E:\\Program Files (x86)\\DingDing\\DTalkFIle\\shp\\abc.zip","D:\\"); + loadFileCharset("E:\\Program Files (x86)\\DingDing\\DTalkFIle\\shp\\abc.cpg"); + } + + public static String unzip(String filePath,String zipDir) { + String name = ""; + try { + BufferedOutputStream dest = null; + BufferedInputStream is = null; + ZipEntry entry; + ZipFile zipfile = new ZipFile(filePath, Charset.forName("GBK")); + + Enumeration dir = zipfile.entries(); + while (dir.hasMoreElements()){ + entry = (ZipEntry) dir.nextElement(); + + if( entry.isDirectory()){ + name = entry.getName(); + name = name.substring(0, name.length() - 1); + File fileObject = new File(zipDir + name); + fileObject.mkdir(); + } + } + + Enumeration e = zipfile.entries(); + while (e.hasMoreElements()) { + entry = (ZipEntry) e.nextElement(); + if( entry.isDirectory()){ + continue; + }else{ + is = new BufferedInputStream(zipfile.getInputStream(entry)); + int count; + byte[] dataByte = new byte[BUFFER]; + FileOutputStream fos = new FileOutputStream(zipDir+entry.getName()); + dest = new BufferedOutputStream(fos, BUFFER); + while ((count = is.read(dataByte, 0, BUFFER)) != -1) { + dest.write(dataByte, 0, count); + } + dest.flush(); + dest.close(); + is.close(); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return name; + } + public static String loadFileCharset(String path) throws Exception{ + FileInputStream fileInputStream = null; + StringBuffer sb = new StringBuffer(); + try { + fileInputStream = new FileInputStream(path); + byte[] bytes = new byte[4];//每一次读取四个字节 + int readCount = 0; + while ((readCount = fileInputStream.read(bytes)) != -1) { + sb.append(new String(bytes, 0, readCount)); + //System.out.print(new String(bytes,0,readCount));//将字节数组转换为字符串 + //System.out.println(new String(bytes, 0, readCount)); + } + System.out.println(sb.toString()); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } finally { + fileInputStream.close(); + } + if (sb==null){ + return "UTF-8"; + } + return sb.toString(); + } + public static void compressFolder(String sourceFolder, String folderName, ZipOutputStream zipOutputStream) throws IOException { + File folder = new File(sourceFolder); + File[] files = folder.listFiles(); + + if (files != null) { + for (File file : files) { + if (file.isDirectory()) { + // 压缩子文件夹 + compressFolder(file.getAbsolutePath(), folderName + "/" + file.getName(), zipOutputStream); + } else { + // 压缩文件 + addToZipFile(folderName + "/" + file.getName(), file.getAbsolutePath(), zipOutputStream); + System.out.println(file.getAbsolutePath()); + } + } + } + } + + private static void addToZipFile(String fileName, String fileAbsolutePath, ZipOutputStream zipOutputStream) throws IOException { + // 创建ZipEntry对象并设置文件名 + ZipEntry entry = new ZipEntry(fileName); + zipOutputStream.putNextEntry(entry); + + // 读取文件内容并写入Zip文件 + try (FileInputStream fileInputStream = new FileInputStream(fileAbsolutePath)) { + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = fileInputStream.read(buffer)) != -1) { + zipOutputStream.write(buffer, 0, bytesRead); + } + } + + // 完成当前文件的压缩 + zipOutputStream.closeEntry(); + } + + public static String unzip1(String zipFile, String outDir) throws Exception { + String name = ""; + if (!FileUtil.exist(zipFile)) { + throw new FileNotFoundException(); + } + final ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFile),Charset.forName("GBK")); + ZipEntry entry = null; + while ((entry = zipInputStream.getNextEntry()) != null) { + if (!entry.isDirectory()) { + final File file = new File(outDir, entry.getName()); + name = entry.getName(); + if (!file.exists()) { + final boolean mkdirs = file.getParentFile().mkdirs(); + } + + final FileOutputStream fileOutputStream = new FileOutputStream(file); + final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream); + int len = -1; + final byte[] bytes = new byte[1024]; + while ((len = zipInputStream.read(bytes)) != -1) { + bufferedOutputStream.write(bytes, 0, len); + } + bufferedOutputStream.close(); + fileOutputStream.close(); + } + zipInputStream.closeEntry(); + } + zipInputStream.close(); + return name; + } + + +} diff --git a/src/main/java/com/zzlh/es/webupload/consts/QueryWrapperConst.java b/src/main/java/com/zzlh/es/webupload/consts/QueryWrapperConst.java new file mode 100644 index 0000000..021b4f5 --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/consts/QueryWrapperConst.java @@ -0,0 +1,214 @@ +package com.zzlh.es.webupload.consts; + + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.zzlh.es.webupload.consts.entity.DynamicCondition; +import com.zzlh.es.webupload.consts.entity.SoulTable; +import com.zzlh.es.webupload.consts.entity.SoulTableParam; + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @Description TODO + * @Author haijun + * @Date 2019/12/21 21:30 + * @ClassName QueryWrapperConst + ***/ +public class QueryWrapperConst { + private static Pattern humpPattern = Pattern.compile("[A-Z]"); + /** + * 查询构造 + */ + public static QueryWrapper queryConst(QueryWrapper queryWrapper, String paramJSONArray){ + if(paramJSONArray==null&¶mJSONArray.trim().length()==0){//参数json字符串为空,直接返回 + return queryWrapper; + } + List dynamicList=new ArrayList<>(); + dynamicList= JSONArray.parseArray(paramJSONArray, DynamicCondition.class); + if(queryWrapper!=null&&dynamicList!=null&&dynamicList.size()>0){ + for(DynamicCondition dynamic:dynamicList){ + /*** + * 属性操作 + * equal:等于 + * like:包含 + * between:范围 + * start:开头字符 + * end:结尾字符 + * unequal:不等于 + * empty:为空 + */ + if(dynamic.getConditionFieldVal()!=null&&dynamic.getConditionOptionVal()!=null){ + String optionVal = dynamic.getConditionOptionVal(); + String conditionFieldVal = dynamic.getConditionFieldVal(); + conditionFieldVal=humpToLine(conditionFieldVal); + if(optionVal.equalsIgnoreCase("equal")){ + queryWrapper.eq(conditionFieldVal,dynamic.getConditionValueVal()); + } + if(optionVal.equalsIgnoreCase("between")){ + queryWrapper.between(conditionFieldVal,dynamic.getConditionValueLeftVal(),dynamic.getConditionValueRightVal()); + } + if(optionVal.equalsIgnoreCase("like")){ + queryWrapper.like(conditionFieldVal,dynamic.getConditionValueVal()); + } + if(optionVal.equalsIgnoreCase("start")){ + queryWrapper.likeRight(conditionFieldVal,dynamic.getConditionValueLeftVal()); + } + if(optionVal.equalsIgnoreCase("end")){ + queryWrapper.likeLeft(conditionFieldVal,dynamic.getConditionValueRightVal()); + } + if(optionVal.equalsIgnoreCase("unequal")){ + queryWrapper.ne(conditionFieldVal,dynamic.getConditionValueVal()); + } + } + } + } + return queryWrapper; + } + + /** + * SoulTable插件构建参数 + */ + public static QueryWrapper soulTableConst(QueryWrapper queryWrapper, SoulTableParam soulTableParam){ + if(soulTableParam==null){ + return queryWrapper; + } + String field = soulTableParam.getField(); + String order = soulTableParam.getOrder(); + /** + * 排序构造 + */ + if(isNotEmpty(field)&&isNotEmpty(order)){ + field=humpToLine(field); + if(order.equals("asc")){ + queryWrapper.orderByAsc(field); + }else{ + queryWrapper.orderByDesc(field); + } + } + + String jsonfilterSos = soulTableParam.getFilterSos(); + System.out.println("jsonfilterSos:"+jsonfilterSos); + if(!isNotEmpty(jsonfilterSos)){//为空,直接返回 + return queryWrapper; + } + List filterSos = JSON.parseArray(jsonfilterSos, SoulTable.class); + /*** + * 条件构造 + */ + if(filterSos!=null&&filterSos.size()>0){ + for(SoulTable soulTable:filterSos){ + if(soulTable.getMode().equals("condition")){//直接构造 + queryWrapper=constSoulTable(queryWrapper,soulTable); + } + if(soulTable.getMode().equals("group")){//分组构造,暂时不考虑无限分组的情况 + List children = soulTable.getChildren(); + if(children!=null&&children.size()>0){ + for(SoulTable soulTablec:children){ + System.out.println("soulTablec:"+soulTablec); + if(soulTablec.getMode().equals("condition")){//直接构造condition + queryWrapper=constSoulTable(queryWrapper,soulTablec); + } + + } + } + } + } + } + return queryWrapper; + } + + + /*** + * 条件构造 + */ + public static QueryWrapper constSoulTable(QueryWrapper queryWrapper,SoulTable soulTable){ +// if(soulTable.getPrefix()=="and"){ +// queryWrapper.and(null); +// } +// if(soulTable.getPrefix()=="or"){ +// queryWrapper.or(); +// } + String type=soulTable.getType(); + String field = soulTable.getField();// + field=humpToLine(field);//转化下线形式 + String value = soulTable.getValue(); + if(type.equals("eq")){//等于 = + queryWrapper.eq(field,value); + } + if(type.equals("ne")){//不等于 <> + queryWrapper.ne(field,value); + } + if(type.equals("gt")){//大于 + queryWrapper.gt(field,value); + } + + if(type.equals("ge")){//大于等于 + queryWrapper.ge(field,value); + } + + if(type.equals("lt")){//小于 + queryWrapper.lt(field,value); + } + + if(type.equals("le")){//小于等于 + queryWrapper.le(field,value); + } + + if(type.equals("contain")){//包含 + queryWrapper.like(field,value); + } + + if(type.equals("notContain")){//不包含 + queryWrapper.notLike(field,value); + } + if(type.equals("start")){//以***开始 + queryWrapper.likeRight(field,value); + } + + if(type.equals("end")){//以***结束 + queryWrapper.likeLeft(field,value); + } + + if(type.equals("in")){ + queryWrapper.in(field,new ArrayList<>(Arrays.asList(value.split(",")))); + } + + if(type.equals("null")){//为空 + queryWrapper.isNull(field); + } + + if(type.equals("notNull")){//不为空 + queryWrapper.isNotNull(field); + } + return queryWrapper; + } + + + /*** + * 驼峰命名转化成下划线 + */ + public static String humpToLine(String str){ + Matcher matcher = humpPattern.matcher(str); + StringBuffer sb = new StringBuffer(); + while(matcher.find()){ + matcher.appendReplacement(sb, "_"+matcher.group(0).toLowerCase()); + } + matcher.appendTail(sb); + return sb.toString(); + } + + /*** + * 字符判断是否为空 + * 不为空 true 否则false + */ + public static boolean isNotEmpty(String str){ + return str!=null&&str.trim().length()>0; + } +} diff --git a/src/main/java/com/zzlh/es/webupload/consts/entity/DynamicCondition.java b/src/main/java/com/zzlh/es/webupload/consts/entity/DynamicCondition.java new file mode 100644 index 0000000..250f1a2 --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/consts/entity/DynamicCondition.java @@ -0,0 +1,52 @@ +package com.zzlh.es.webupload.consts.entity; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @Description TODO 动态参数查询 + * @Author haijun + * @Date 2019/2/22 0022 23:48 + * @ClassName DynamicCondition + ***/ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DynamicCondition implements Serializable { + /** + * 属性名 + */ + private String conditionFieldVal; + /*** + * 属性操作 + * equal:等于 + * like:包含 + * between:范围 + * start:开头字符 + * end:结尾字符 + * unequal:不等于 + * empty:为空 + */ + private String conditionOptionVal; + /** + * 查询值对象 + * { + * value:"", + * text:"" + * } + */ + private String conditionValueVal; + /** + * 上限 + */ + private String conditionValueLeftVal; + /*** + * 下限 + */ + private String conditionValueRightVal; + +} diff --git a/src/main/java/com/zzlh/es/webupload/consts/entity/SoulTable.java b/src/main/java/com/zzlh/es/webupload/consts/entity/SoulTable.java new file mode 100644 index 0000000..ffac939 --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/consts/entity/SoulTable.java @@ -0,0 +1,25 @@ +package com.zzlh.es.webupload.consts.entity; + +import lombok.Data; + +import java.util.List; + +/** + * @Description + * TODO SoulTable参数构造 + * @Author haijun + * @Date 2019/12/29 12:20 + * @ClassName SoulTable + ***/ +@Data +public class SoulTable { + private boolean head; + private String prefix; + private String mode; + private String field; + private String value; + private String type; + private String groupId; + + private List children;//子集合 +} diff --git a/src/main/java/com/zzlh/es/webupload/consts/entity/SoulTableParam.java b/src/main/java/com/zzlh/es/webupload/consts/entity/SoulTableParam.java new file mode 100644 index 0000000..c1ad2d3 --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/consts/entity/SoulTableParam.java @@ -0,0 +1,37 @@ +package com.zzlh.es.webupload.consts.entity; + +import lombok.Data; + +/** + * @Description TODO + * @Author haijun + * @Date 2019/12/29 12:18 + * @ClassName SoulTableParam + ***/ +@Data +public class SoulTableParam { + /** + * 条件集合 + **/ +// private List filterSos; + private String filterSos; + + /** + * 属性名 + */ + private String field; + /*** + * 排序方式 + * asc 或者 desc + */ + private String order; + + /** + * 页码 + */ + private Long page; + /*** + * 分页大小 + */ + private Long size; +} diff --git a/src/main/java/com/zzlh/es/webupload/controller/BaseController.java b/src/main/java/com/zzlh/es/webupload/controller/BaseController.java new file mode 100644 index 0000000..b5cc9d1 --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/controller/BaseController.java @@ -0,0 +1,82 @@ +package com.zzlh.es.webupload.controller; + + + + +import com.zzlh.es.webupload.entity.PageResult; +import com.zzlh.es.webupload.entity.Result; +import com.zzlh.es.webupload.entity.ResultCode; + +import java.util.List; + +/** + * @Description TODO + * @Author haijun + * @Date 2019/12/20 13:26 + * @ClassName BaseController + ***/ +public class BaseController { + /** + * redirect跳转 + * @param url 目标url + */ + protected String redirect(String url) { + return new StringBuilder("redirect:").append(url).toString(); + } + /** + * @Description //TODO 返回成功并且有提示信息,不带返回值 + * @Author haijun + * @Computer Administrator + * @Date 17:34 2018/9/29/029 + * @Param [msg] 提示消息 + * @return java.lang.Object + **/ + public Result renderSuccess(String msg){ + return new Result(ResultCode.SUCCESS,msg); + } + + public Result renderSuccess(){ + return new Result(ResultCode.SUCCESS); + } + + /** + * @Description //TODO 返回成功并且有提示信息,不带返回值 + * @Author haijun + **/ + public Result renderError(){ + return new Result(ResultCode.FAIL); + } + + public Result renderError(String msg){ + return new Result(ResultCode.FAIL,msg); + } + public Result renderError(ResultCode resultCode){ + return new Result(resultCode); + } + + /** + * 普通数据返回 + * @author haijun + * @Description //TODO + * @Date 13:31 2019/12/20 + * @Param [data] + * @return com.carpark.common.entity.Result + **/ + public Result renderDataSuccess(Object data){ + return new Result(ResultCode.SUCCESS,data); + } + public Result renderDataSuccess(Object data,String msg){ + return new Result(ResultCode.SUCCESS,data,msg); + } + /*** + * 带分页查询返回 + * @param total + * @param records + * @return + */ + public Result renderDataPageSuccess(long total, List records){ + return new Result(ResultCode.SUCCESS,new PageResult(total,records)); + } + + +} diff --git a/src/main/java/com/zzlh/es/webupload/controller/FileRecordController.java b/src/main/java/com/zzlh/es/webupload/controller/FileRecordController.java new file mode 100644 index 0000000..46d3683 --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/controller/FileRecordController.java @@ -0,0 +1,217 @@ +package com.zzlh.es.webupload.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import com.zzlh.es.webupload.consts.QueryWrapperConst; +import com.zzlh.es.webupload.consts.entity.SoulTableParam; +import com.zzlh.es.entity.FileRecord; +import com.zzlh.es.entity.FileZoneRecord; +import com.zzlh.es.webupload.entity.Result; +import com.zzlh.es.webupload.service.IFileRecordService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.util.ArrayList; +import java.util.Arrays; + +/** + *

+ * 文件上传记录 前端控制器 + *

+ * + * @author haijun + * @since 2020-02-14 + */ +@RestController +@RequestMapping("/upload/fileRecord") +public class FileRecordController extends BaseController { + + @Autowired + private IFileRecordService fileRecordService; + +// @Autowired +// private IFileFilterService fileFilterService; + + /** + * @author haijun + * @Description TODO 条件分页查询 + * @Date 2020-02-14 + * @Param + * @return + */ + @PostMapping("/getList") + public Result getList(FileRecord fileRecord, SoulTableParam soulTableParam){ + Page objectPage = new Page<>(); + if(soulTableParam.getPage()==null){//默认分页 + soulTableParam.setPage(1L); + } + if(soulTableParam.getSize()==null){ + soulTableParam.setSize(10L); + } + if(soulTableParam.getSize()>1000){ + soulTableParam.setSize(1000L);//最大支持1000条数据 + } + objectPage.setCurrent(soulTableParam.getPage()); + objectPage.setSize(soulTableParam.getSize()); + QueryWrapper queryWrapper=new QueryWrapper(fileRecord); + queryWrapper= QueryWrapperConst.soulTableConst(queryWrapper,soulTableParam); + IPage pageResult = fileRecordService.page(objectPage, queryWrapper); + return renderDataPageSuccess(pageResult.getTotal(),pageResult.getRecords()); + } + + /*** + * 根据ID查找 + */ + @GetMapping("/{id}") + public Result findById(@PathVariable("id")String id){ + return renderDataSuccess(fileRecordService.getById(id)); + } + + /*** + * 保存数据 + * id存在就更新 + */ + @PostMapping("/save") + public Result save(@RequestBody FileRecord fileRecord){ + boolean b = fileRecordService.saveOrUpdate(fileRecord); + return b?renderSuccess():renderError(); + } + + /*** + * 根据ID删除数据 + */ + @DeleteMapping("/delById/{id}") + public Result delById(@PathVariable("id") String id){ + boolean b = fileRecordService.removeById(id); + return b?renderSuccess():renderError(); + } + + /*** + * 根据多个ID删除(批量删除) + */ + @DeleteMapping("/delByIds/{ids}") + public Result delByIds(@PathVariable("ids") String ids){ + boolean b = fileRecordService.removeByIds(new ArrayList<>(Arrays.asList(ids.split(",")))); + return b?renderSuccess():renderError(); + } + + /**************************文件上传操作*********************************/ + /*** + * 单文件上传(<5M) + */ + @PostMapping("/upload") + public Result upload(HttpServletRequest request, Integer uploadType, Integer storageYear){ + Result result=fileRecordService.upload(request,uploadType,storageYear); + return result; + } + + /*** + * 大文件分片上传 + */ + @PostMapping("/zone/upload") + public Result zoneUpload(HttpServletRequest request,String contentType, FileZoneRecord fileZoneRecord){ + return fileRecordService.zoneUpload(request,contentType,fileZoneRecord); + } + + /** + * @author haijun 校验MD5,传入分片MD5和总的MD5,校验当前分片 + * @Description //TODO + * @Date 21:54 2019/12/31 + * @Param + * @return + **/ + @PostMapping("/zone/upload/md5Check") + public Result md5Check(FileZoneRecord fileZoneRecord, Integer checkType, String contentType, HttpServletRequest request){ + return fileRecordService.md5Check(fileZoneRecord,checkType,contentType,request); + } + + /** + * 合并文件,前端所有分片上传完成时,发起请求,将所有的文件合并成一个完整的文件,并删除服务器分片文件 + * 前端需要传入总文件的MD5值 + */ + @PostMapping("/zone/upload/merge/{totalmd5}") + public Result mergeZoneFile(@PathVariable("totalmd5") String totalmd5,HttpServletRequest request){ + return fileRecordService.mergeZoneFile(totalmd5,request); + } + + /*** + * 删除文件分片 + */ + @PostMapping("/zone/upload/del/{totalmd5}") + public Result delZoneFile(@PathVariable("totalmd5") String totalmd5){ + return fileRecordService.delZoneFile(totalmd5); + } + /*** + * 删除文件 + */ + @PostMapping("/upload/del/{fileId}") + public Result delFile(@PathVariable("fileId") String fileId){ + return fileRecordService.delFile(fileId); + } + + /*** + * @author haijun + * @Description //TODO 文件下载 + * @Date 12:25 2020/1/7 + * @Param + * @return + **/ + @GetMapping("/download/{fileId}") + public Result downloadFile(HttpServletRequest request, HttpServletResponse response, @PathVariable("fileId") String fileId) throws UnsupportedEncodingException { + FileRecord fileRecorddb = fileRecordService.getById(fileId); + String filePath = fileRecorddb.getServerLocalPath();// 设置文件名,根据业务需要替换成要下载的文件名 + String fileName = fileRecorddb.getOrgName(); + if (filePath != null) { + //设置文件路径 + System.out.println("filePath:"+filePath); + File file = new File(filePath); + if (file.exists()) { + response.setContentType("application/force-download");// 设置强制下载不打开 + response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名 + response.setContentType("multipart/form-data;charset=UTF-8");//也可以明确的设置一下UTF-8,测试中不设置也可以。 + response.setHeader("Content-Disposition", "attachment;fileName="+ new String(fileName.getBytes("GB2312"),"ISO-8859-1")); + byte[] buffer = new byte[1024]; + FileInputStream fis = null; + BufferedInputStream bis = null; + try { + fis = new FileInputStream(file); + bis = new BufferedInputStream(fis); + OutputStream os = response.getOutputStream(); + int i = bis.read(buffer); + while (i != -1) { + os.write(buffer, 0, i); + os.flush(); + i = bis.read(buffer); + } +// System.out.println("下载成功"); +// fileRecordService.recordDownloadLog(fileId,fileRecorddb); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (bis != null) { + try { + bis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return renderSuccess(); + } + } + return renderError("下载错误"); + } + +} diff --git a/src/main/java/com/zzlh/es/webupload/entity/DynamicCondition.java b/src/main/java/com/zzlh/es/webupload/entity/DynamicCondition.java new file mode 100644 index 0000000..fe9aa33 --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/entity/DynamicCondition.java @@ -0,0 +1,52 @@ +package com.zzlh.es.webupload.entity; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @Description TODO 动态参数查询 + * @Author haijun + * @Date 2019/2/22 0022 23:48 + * @ClassName DynamicCondition + ***/ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DynamicCondition implements Serializable { + /** + * 属性名 + */ + private String conditionFieldVal; + /*** + * 属性操作 + * equal:等于 + * like:包含 + * between:范围 + * start:开头字符 + * end:结尾字符 + * unequal:不等于 + * empty:为空 + */ + private String conditionOptionVal; + /** + * 查询值对象 + * { + * value:"", + * text:"" + * } + */ + private String conditionValueVal; + /** + * 上限 + */ + private String conditionValueLeftVal; + /*** + * 下限 + */ + private String conditionValueRightVal; + +} diff --git a/src/main/java/com/zzlh/es/webupload/entity/PageResult.java b/src/main/java/com/zzlh/es/webupload/entity/PageResult.java new file mode 100644 index 0000000..e927eaf --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/entity/PageResult.java @@ -0,0 +1,26 @@ +package com.zzlh.es.webupload.entity; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @Description TODO + * @Author haijun + * @Date 2019/11/25 0025 20:01 + * @ClassName PageResult + ***/ +@Data +//@ApiModel(value = "分页构造 PageResult",description = "分页构造") +public class PageResult implements Serializable { + //@ApiModelProperty(value = "数据总条数") + private long total; + //@ApiModelProperty(value = "行数据集合") + private List rows; + + public PageResult(long total, List rows) { + this.total = total; + this.rows = rows; + } +} diff --git a/src/main/java/com/zzlh/es/webupload/entity/Result.java b/src/main/java/com/zzlh/es/webupload/entity/Result.java new file mode 100644 index 0000000..39f324e --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/entity/Result.java @@ -0,0 +1,71 @@ +package com.zzlh.es.webupload.entity; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @Description TODO + * @Author haijun + * @Date 2019/11/25 0025 0:15 + * @ClassName Result + ***/ +@Data +@NoArgsConstructor +public class Result implements Serializable { + //@ApiModelProperty(value = "操作标识,false失败,true成功") + private boolean success;//是否成功 + //@ApiModelProperty(value = "数据总条数,状态码") + private Integer code;// 返回码 + //@ApiModelProperty(value = "响应提示消息") + private String message;//返回信息 + //@ApiModelProperty(value = "响应数据,可能是对象,也可能是数组对象,具体看业务需求") + private Object data;// 返回数据 + + public Result(ResultCode code) { + this.success = code.success; + this.code = code.code; + this.message = code.message; + } + + public Result(ResultCode code,String message) { + this.success = code.success; + this.code = code.code; + this.message = message; + } + + public Result(ResultCode code,Object data) { + this.success = code.success; + this.code = code.code; + this.message = code.message; + this.data = data; + } + + public Result(Integer code,String message,boolean success) { + this.code = code; + this.message = message; + this.success = success; + } + + public Result(ResultCode success, Object data, String msg) { + this.data=data; + this.code = success.code; + this.message = msg; + this.success = success.success; + } + + + public static Result SUCCESS(){ + return new Result(ResultCode.SUCCESS); + } + + public static Result ERROR(){ + return new Result(ResultCode.SERVER_ERROR); + } + + public static Result FAIL(){ + return new Result(ResultCode.FAIL); + } + +} diff --git a/src/main/java/com/zzlh/es/webupload/entity/ResultCode.java b/src/main/java/com/zzlh/es/webupload/entity/ResultCode.java new file mode 100644 index 0000000..5d41dee --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/entity/ResultCode.java @@ -0,0 +1,44 @@ +package com.zzlh.es.webupload.entity; + +public enum ResultCode { + SUCCESS(true,10000,"操作成功!"), + //---系统错误返回码----- + FAIL(false,10001,"操作失败"), + UNAUTHORISE(false,10003,"权限不足"), + VERIFICATIONFAILED(false,10004,"登录失效,请重新登录"), + SERVER_ERROR(false,99999,"抱歉,系统繁忙,请稍后重试!"), + + //---用户操作返回码 2xxxx---- + LOGINERROR(false,20001,"用户名或密码错误"), + DISABLELOGIN(false,20001,"您已经被管理员禁止登录"), + NOTLOGIN(false,20002,"没有登录,请先登录"), + + //-----文件操作 3xxx----- + FILEUPLOADED(true,30000,"文件上传成功"), + FILENOTSUPPORT(false,30001,"不支持此类文件上传"); + + //操作是否成功 + boolean success; + //操作代码 + int code; + //提示信息 + String message; + + ResultCode(boolean success,int code, String message){ + this.success = success; + this.code = code; + this.message = message; + } + + public boolean success() { + return success; + } + + public int code() { + return code; + } + + public String message() { + return message; + } +} diff --git a/src/main/java/com/zzlh/es/webupload/service/IFileRecordService.java b/src/main/java/com/zzlh/es/webupload/service/IFileRecordService.java new file mode 100644 index 0000000..26ad640 --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/service/IFileRecordService.java @@ -0,0 +1,34 @@ +package com.zzlh.es.webupload.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzlh.es.entity.FileRecord; +import com.zzlh.es.entity.FileZoneRecord; +import com.zzlh.es.webupload.entity.Result; + +import javax.servlet.http.HttpServletRequest; + +/** + *

+ * 文件上传记录 服务类 + *

+ * + * @author haijun + * @since 2020-02-14 + */ +public interface IFileRecordService extends IService { + + Result upload(HttpServletRequest request, Integer uploadType, Integer storageYear); + + Result zoneUpload(HttpServletRequest request, String contentType, FileZoneRecord fileZoneRecord); + + Result md5Check(FileZoneRecord fileZoneRecord, Integer checkType, String contentType, HttpServletRequest request); + + Result mergeZoneFile(String totalmd5, HttpServletRequest request); + + Result delZoneFile(String totalmd5); + + Result delFile(String fileId); + +// void recordDownloadLog(String fileId, FileRecord fileRecord); +} diff --git a/src/main/java/com/zzlh/es/webupload/service/IFileZoneRecordService.java b/src/main/java/com/zzlh/es/webupload/service/IFileZoneRecordService.java new file mode 100644 index 0000000..b092aac --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/service/IFileZoneRecordService.java @@ -0,0 +1,22 @@ +package com.zzlh.es.webupload.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zzlh.es.entity.FileZoneRecord; + + +import java.util.List; + +/** + *

+ * 文件分片记录 服务类 + *

+ * + * @author haijun + * @since 2020-02-14 + */ +public interface IFileZoneRecordService extends IService { + + FileZoneRecord selByMD5AndZoneTotalMd5(String zoneMd5, String zoneTotalMd5); + + List selByTotalMd5(String totalmd5); +} diff --git a/src/main/java/com/zzlh/es/webupload/service/impl/FileRecordServiceImpl.java b/src/main/java/com/zzlh/es/webupload/service/impl/FileRecordServiceImpl.java new file mode 100644 index 0000000..a39c29d --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/service/impl/FileRecordServiceImpl.java @@ -0,0 +1,515 @@ +package com.zzlh.es.webupload.service.impl; + + +import cn.hutool.core.date.DateUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import com.zzlh.es.mapper.FileRecordMapper; +import com.zzlh.es.entity.FileRecord; +import com.zzlh.es.entity.FileZoneRecord; +import com.zzlh.es.webupload.entity.Result; +import com.zzlh.es.webupload.entity.ResultCode; +import com.zzlh.es.webupload.service.IFileRecordService; +import com.zzlh.es.webupload.service.IFileZoneRecordService; +import com.zzlh.es.webupload.util.FileHandleUtil; +import com.zzlh.es.webupload.util.FileUploadConfig; +import com.zzlh.es.webupload.util.IPUtils; +import com.zzlh.es.webupload.util.IdWorker; +import org.apache.commons.io.FileUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.DigestUtils; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.*; + +/** + *

+ * 文件上传记录 服务实现类 + *

+ * + * @author haijun + * @since 2020-02-14 + */ +@Service +public class FileRecordServiceImpl extends ServiceImpl implements IFileRecordService { + @Autowired + private FileRecordMapper fileRecordMapper; + + @Autowired + private FileUploadConfig fileUploadConfig; + +// @Autowired +// private IFileUploadLogService fileUploadLogService; + +// @Autowired +// private IFileFilterService fileFilterService; + + @Autowired + private IFileZoneRecordService fileZoneRecordService; +// +// @Autowired +// private IFileDownloadLogService fileDownloadLogService; + + @Autowired + private IdWorker idWorker; + + @Override + public Result upload(HttpServletRequest request, Integer uploadType, Integer storageYear) { + Long nowtime=System.currentTimeMillis(); + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + Map files = multipartRequest.getFileMap(); + for (Map.Entry entry : files.entrySet()) { + MultipartFile multipartFile = entry.getValue(); + if (multipartFile.isEmpty()) { + return renderError("文件不能为空"); + } + String contentType = multipartFile.getContentType(); + System.out.println("contentType:"+contentType); +// if(contentType==null||!isFileter(contentType)){//拦截,是否在上传名单 +// return new Result(ResultCode.FILENOTSUPPORT); +// } + + String fileName = multipartFile.getOriginalFilename(); + Long size = multipartFile.getSize(); + System.out.println(fileName + "-->" + size); + String saticAccess = fileUploadConfig.getStaticAccessPath().replace("*", ""); + try { + //本地路径 1 用户头像 2 商城图片 + uploadType = uploadType == 1 ? uploadType : 2; + //计算MD5值 + String filemd5 = DigestUtils.md5DigestAsHex(multipartFile.getInputStream()); + //查询数据库是否已经有了,有直接写入,没有,写入磁盘 + FileRecord fileRecorddb = selByMD5AndUpType(filemd5, uploadType); + Map map = new HashMap<>(); + String fileType = contentType.split("/")[0]; + + if (fileRecorddb == null) { + String pathTypeDir = (uploadType == 1 ? fileUploadConfig.getUserHeaderPicPath() : fileUploadConfig.getArchivesFilePath()) + fileType + "/"; + // 年月日/时分 如果短时间内,上传并发量大,还可分得更细 秒 毫秒 等等 + String path_date = DateUtil.format(new Date(), "yyyy") + "/" + DateUtil.format(new Date(), "MMdd") + "/" + DateUtil.format(new Date(), "HH"); + String localPath = getUploadFolder() + fileUploadConfig.getLocalPath() + pathTypeDir + path_date; + //随机生成服务器本地路径 + String fileSuffix = getFileSuffix(fileName); + String serverFileName = idWorker.nextId() + fileSuffix; + FileHandleUtil.upload(multipartFile.getInputStream(), localPath, serverFileName); + //String netWorkPath = "/" + saticAccess + pathTypeDir + path_date + "/" + serverFileName; + String netWorkPath = "/" + serverFileName; + map.put("network", netWorkPath); + + FileRecord fileRecord = new FileRecord(); + fileRecord.setDownloadCount(0); + fileRecord.setUploadCount(1); + fileRecord.setIsMerge(1);//单文件,完整文件 + fileRecord.setIsZone(0); + fileRecord.setFileSize(size); + fileRecord.setFileType(fileType); + fileRecord.setMd5Value(filemd5); + fileRecord.setOrgName(fileName); + fileRecord.setUploadType(uploadType); + fileRecord.setServerLocalName(serverFileName); + fileRecord.setServerLocalPath(localPath + serverFileName); + fileRecord.setNetworkPath(netWorkPath); + fileRecord.setStorageDate(getDateToYear(storageYear));//默认一百年 + String fileId=saveFileRecord(request, fileRecord); + map.put("fileId", fileId); + map.put("network", fileRecord.getNetworkPath()); + } else { +// fileRecorddb.setUploadCount(fileRecorddb.getUploadCount()+1); + String fileId=saveFileRecord(request, fileRecorddb); + map.put("fileId", fileId); + map.put("network", fileRecorddb.getNetworkPath()); + } + System.out.println("耗时: "+(System.currentTimeMillis()-nowtime)+" ms"); + return renderDataSuccess(map); + } catch (IllegalStateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return renderError("文件上传错误,错误消息:" + e.getMessage()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return renderError("文件上传错误,错误消息:" + e.getMessage()); + } catch (Exception e){ + e.printStackTrace(); + return renderError("文件上传错误,错误消息:" + e.getMessage()); + } + } + return renderError("文件上传错误" ); + } + + @Override + public Result zoneUpload(HttpServletRequest request,String contentType, FileZoneRecord fileZoneRecord) { + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + Map files = multipartRequest.getFileMap(); + for (Map.Entry entry : files.entrySet()) { + MultipartFile multipartFile = entry.getValue(); + if(multipartFile.isEmpty()){ + return renderError("请选择文件"); + } + String fileName = multipartFile.getOriginalFilename(); + if(fileName.equals("blob")){ + fileName=fileZoneRecord.getZoneName(); + } +// String contentType = multipartFile.getContentType(); + System.out.println("contentType"); +// if(contentType==null||!isFileter(contentType)){ +// return new Result(ResultCode.FILENOTSUPPORT); +// } + String fileType=contentType.split("/")[0]; + Long size = multipartFile.getSize(); + System.out.println(fileName + "-->" + size); + try { + + Map map=new HashMap<>(); + synchronized (UUID.randomUUID()){ + //查询数据库是否已经有了,有直接写入,没有,写入磁盘 + FileZoneRecord fileZoneRecorddb = fileZoneRecordService.selByMD5AndZoneTotalMd5(fileZoneRecord.getZoneMd5(), fileZoneRecord.getZoneTotalMd5()); + if(fileZoneRecorddb==null){ + String pathTypeDir=fileUploadConfig.getArchivesFilePath(); + // 年月日/时分 如果短时间内,上传并发量大,还可分得更细 秒 毫秒 等等 + //写入临时目录,用总文件MD5值做文件夹 + String localPath=""; + //随机生成服务器本地路径 + String fileSuffix = getFileSuffix(fileName); + //分片文件MD5,如果前端没有计,算一下 + String filemd5= ""; + if(fileZoneRecord.getZoneMd5()==null||fileZoneRecord.getZoneMd5().trim().length()==0){ + filemd5=DigestUtils.md5DigestAsHex(multipartFile.getInputStream()); + fileZoneRecord.setZoneMd5(filemd5); + }else{ + filemd5=fileZoneRecord.getZoneMd5(); + } + + String serverFileName=filemd5+fileSuffix+".temp"; + String fileRecordId = ""; + FileRecord fileRecorddb =null; + synchronized (UUID.randomUUID().toString()) { + //记录 已经文件存在,就不更新了,否则新增一条记录,合并时用 + fileRecorddb = this.selByMD5AndUpType(fileZoneRecord.getZoneTotalMd5(), 2); + } + if (fileRecorddb == null) { + localPath = getUploadFolder() + fileUploadConfig.getLocalPath() + pathTypeDir + "temp/" + fileZoneRecord.getZoneTotalMd5(); + + FileRecord fileRecord = new FileRecord(); + fileRecord.setFileSize(fileZoneRecord.getZoneTotalSize()); + fileRecord.setFileType(fileType); + fileRecord.setMd5Value(fileZoneRecord.getZoneTotalMd5()); + fileRecord.setOrgName(fileName); + fileRecord.setUploadType(2); + fileRecord.setServerLocalPath(localPath); + fileRecord.setStorageDate(getDateToYear(100));//默认一百年 + fileRecord.setIsZone(1); + fileRecord.setIsMerge(0);//没有合并 + fileRecord.setDownloadCount(0); + fileRecord.setUploadCount(1); + System.out.println("fileRecord:"+fileRecord); + fileRecord.setZoneTotal(fileZoneRecord.getZoneTotalCount()); + fileRecord.setZoneDate(new Date()); + fileRecordId = saveFileRecord(request, fileRecord); + saveFileRecord(request,fileRecord); + } else { + //分片且已经合并过了,就不再往下执行,否则继续 + if (fileRecorddb.getIsZone() == 1 && fileRecorddb.getIsMerge() == 1) {//如果文件已经合并过了,直接返回 + return renderError("文件已经上传"); + } + fileRecordId = fileRecorddb.getId(); + localPath = fileRecorddb.getServerLocalPath(); + } +// } + //将文件写入目录 + FileHandleUtil.upload(multipartFile.getInputStream(), localPath, serverFileName); + + //记录分片文件 + fileZoneRecord.setId(idWorker.nextId() + ""); + fileZoneRecord.setZoneMd5(filemd5);//计算当前分片MD5 + fileZoneRecord.setFileRecordId(fileRecordId); + fileZoneRecord.setZoneName(serverFileName); + fileZoneRecord.setZonePath(localPath);//只存文件夹,合并时,直接读取这个文件所有文件 + fileZoneRecord.setZoneRecordDate(new Date()); + fileZoneRecord.setZoneSuffix(fileSuffix); + fileZoneRecordService.save(fileZoneRecord); + map.put("fileZone", fileZoneRecord); + map.put("isExist", false);//不存在 + map.put("zoneNowIndex", fileZoneRecord.getZoneNowIndex()); + + }else{ + map.put("fileZone",fileZoneRecorddb); + map.put("isExist", true);//存在 + map.put("zoneNowIndex", fileZoneRecorddb.getZoneNowIndex()); + } + } + return renderDataSuccess(map); + } catch (IllegalStateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return renderError("文件上传错误,错误消息:"+e.getMessage()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return renderError("文件上传错误,错误消息:"+e.getMessage()); + } + } + return renderError("文件上传失败"); + } + + @Override + public Result md5Check(FileZoneRecord fileZoneRecord, Integer checkType,String contentType,HttpServletRequest request) { + if(checkType==1){//校验文件 +// if(contentType==null||!isFileter(contentType)){ +// return new Result(ResultCode.FILENOTSUPPORT); +// } + FileRecord fileRecordb = this.selByMD5AndUpType(fileZoneRecord.getZoneTotalMd5(), 2); + if(fileRecordb!=null){ + saveFileRecord(request,fileRecordb); + } + return fileRecordb!=null&&fileRecordb.getIsMerge()==1?new Result(ResultCode.FILEUPLOADED,fileRecordb):renderError("请选择文件上传"); + }else{ + FileZoneRecord fileZoneRecordb = fileZoneRecordService.selByMD5AndZoneTotalMd5(fileZoneRecord.getZoneMd5(), fileZoneRecord.getZoneTotalMd5()); + return fileZoneRecordb!=null?renderDataSuccess(fileZoneRecordb):renderError("分片文件不存在,继续上传"); + } + } + + @Override + public Result mergeZoneFile(String totalmd5,HttpServletRequest request) { + //查询所有的分片文件 + if(totalmd5!=null&&totalmd5.trim().length()>0){ + FileRecord fileRecordb = this.selByMD5AndUpType(totalmd5, 2); + Map map=new HashMap<>(); + if(fileRecordb.getIsZone()==1&&fileRecordb.getIsMerge()==1){ + map.put("netWorkPath",fileRecordb.getNetworkPath()); + map.put("fileId",fileRecordb.getId()); + map.put("fileInfo",fileRecordb); + map.put("message","文件已经上传成功了,文件路径:"+fileRecordb.getNetworkPath()); + return renderDataSuccess(map); + } + String fileType=fileRecordb.getFileType(); + List fileZoneRecords = fileZoneRecordService.selByTotalMd5(totalmd5); + if(fileZoneRecords.size()>0){ + // 年月日/时分 如果短时间内,上传并发量大,还可分得更细 秒 毫秒 等等 + String path_date= DateUtil.format(new Date(),"yyyy")+"/"+DateUtil.format(new Date(),"MMdd")+"/"+DateUtil.format(new Date(),"HH")+"/"; + String pathTypeDir=fileUploadConfig.getArchivesFilePath()+fileType+"/"; + String localPath=getUploadFolder() + fileUploadConfig.getLocalPath()+pathTypeDir+path_date; + //随机生成服务器本地路径 + String fileSuffix = getFileSuffix(fileRecordb.getOrgName()); + String serverFileName=idWorker.nextId()+fileSuffix; + String saticAccess = fileUploadConfig.getStaticAccessPath().replace("*", ""); + String netWorkPath="/"+saticAccess+pathTypeDir+path_date+"/"+ serverFileName; + fileRecordb.setServerLocalName(serverFileName); + fileRecordb.setServerLocalPath(localPath+serverFileName); + fileRecordb.setNetworkPath(netWorkPath); + FileOutputStream destTempfos =null; + try { + String zonePath = fileZoneRecords.get(0).getZonePath(); + File parentFileDir = new File(zonePath);//得到上级文件夹 + if(parentFileDir.isDirectory()){ + FileHandleUtil.createDirIfNotExists(localPath); + File destTempFile = new File(localPath, serverFileName); + if(!destTempFile.exists()){ + //先得到文件的上级目录,并创建上级目录,在创建文件, + destTempFile.getParentFile().mkdir(); + try { + //创建文件 + destTempFile.createNewFile(); //上级目录没有创建,这里会报错 + } catch (IOException e) { + e.printStackTrace(); + } + } + System.out.println(parentFileDir.listFiles().length); + List ids=new ArrayList<>(); + for(FileZoneRecord fileZoneR:fileZoneRecords){ + File partFile = new File(parentFileDir, fileZoneR.getZoneName()); + destTempfos = new FileOutputStream(destTempFile, true); + //遍历"所有分片文件"到"最终文件"中 + FileUtils.copyFile(partFile, destTempfos); + destTempfos.close(); + ids.add(fileZoneR.getId()); + } + + // 删除临时目录中的分片文件 + String tempDir=getUploadFolder() + fileUploadConfig.getLocalPath()+fileUploadConfig.getArchivesFilePath()+"/temp/"+fileRecordb.getMd5Value(); + FileHandleUtil.deleteFolder(tempDir); + fileZoneRecordService.removeByIds(ids);//删除分片信息 + fileRecordb.setZoneMergeDate(new Date()); + fileRecordb.setIsMerge(1);//更新已经合并 + this.updateById(fileRecordb);//更新到文件记录 + String fileId = saveFileRecord(request, fileRecordb); + map.put("netWorkPath",netWorkPath); + map.put("fileInfo",fileRecordb); + map.put("fileId",fileId); + return renderDataSuccess(map); + } + } catch (Exception e) { + e.printStackTrace(); + return renderError("操作失败,原因:"+e.getMessage()); + }finally { + try { + if(destTempfos!=null){ + destTempfos.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + return renderError("合并错误"); + } + + @Override + public Result delZoneFile(String totalmd5) { + return null; + } + + @Override + public Result delFile(String fileId) { + return null; + } + +// @Override +// public void recordDownloadLog(String fileId,FileRecord fileRecord) { +// FileDownloadLog fileDownloadLog=new FileDownloadLog(); +// fileDownloadLog.setSysFileRecordId(fileId); +// fileDownloadLog.setOrgFileName(fileRecord.getOrgName()); +// fileDownloadLog.setFileSize(fileRecord.getFileSize()); +// fileDownloadLog.setServerLocalName(fileRecord.getServerLocalName()); +// fileDownloadLog.setServerLocalPath(fileRecord.getServerLocalPath()); +// fileDownloadLogService.save(fileDownloadLog); +// //更新下载量 +// fileRecord.setDownloadCount(fileRecord.getDownloadCount()+1); +// this.updateById(fileRecord); +// } + + public Result renderError(String msg){ + return new Result(ResultCode.SERVER_ERROR,msg ); + } + public Result renderDataSuccess(Object obj){ + return new Result(ResultCode.SUCCESS,obj); + } + // + public FileRecord selByMD5AndUpType(String md5,Integer uploadType){ + QueryWrapper queryWrapper=new QueryWrapper(); + queryWrapper.eq("md5_value",md5); + queryWrapper.eq("upload_type",uploadType); + List list = fileRecordMapper.selectList(queryWrapper); + if(list.size()>0){ + return list.get(0); + } + return null; + } + + + public FileRecord selByMD5AndUpType(String md5){ + QueryWrapper queryWrapper=new QueryWrapper(); + queryWrapper.eq("md5_value",md5); + List list = fileRecordMapper.selectList(queryWrapper); + if(list.size()>0){ + return list.get(0); + } + return null; + } + + /*** + * 获取文件后缀 + * @param fileName + * @return + */ + public String getFileSuffix(String fileName){ + if(fileName==null||fileName.length()==0){ + return ""; + } + return fileName.substring(fileName.lastIndexOf(".")); + } + + + /** + * 将当前时间往后推一年 + */ + public Date getDateToYear(Integer year){ + if(year==null){//默认一百年 + year=100; + } + //获取时间加一年 + Date date = new Date(); + Calendar cal = Calendar.getInstance(); + cal.setTime(date);//设置起时间 + cal.add(Calendar.YEAR, year);//增加year年 + return cal.getTime(); + } + + public String getUploadFolder(){ +// String uploadFolderdb = configService.getValueByKey("uploadFolder"); +// System.out.println("uploadFolderdb:"+uploadFolderdb); +// if(uploadFolderdb==null||uploadFolderdb.trim().length()==0){ +// return fileUploadConfig.getUploadFolder(); +// } +// return uploadFolderdb; + return fileUploadConfig.getUploadFolder(); + } + + /** + * 文件保存记录 + */ + public String saveFileRecord(HttpServletRequest request, FileRecord fileRecord){ + fileRecord.setDelFlag(1); + String device = request.getHeader("User-Agent"); + fileRecord.setUploadDevice(device); + String ipAddr = IPUtils.getIpAddr(request); + if(fileRecord.getUploadCount()==1&&fileRecord.getId()==null){ + fileRecord.setUploadIp(ipAddr); + this.save(fileRecord); + } + //记录上传日志 +// FileUploadLog fileUploadLogdb = selFileUploadLog(fileRecord.getId(), fileRecord.getCreateBy(), ipAddr); +// if(fileUploadLogdb==null){//如果ID +// fileUploadLogdb=new FileUploadLog(); +// fileUploadLogdb.setCreateBy(fileRecord.getCreateBy()); +// fileUploadLogdb.setCreateTime(new Date()); +// fileUploadLogdb.setDelFlag(1); +// fileUploadLogdb.setOrgFileName(fileRecord.getOrgName()); +// fileUploadLogdb.setSysFileRecordId(fileRecord.getId()); +// fileUploadLogdb.setUploadIp(IPUtils.getIpAddr(request)); +// fileUploadLogdb.setUploadDevice(device); +// fileUploadLogService.save(fileUploadLogdb); +// } +// fileRecord.setUploadCount(selFileUploadLog(fileRecord.getId())); + this.updateById(fileRecord); + return fileRecord.getId(); + } + +// /** +// * 查询上传记录 +// */ +// public FileUploadLog selFileUploadLog(String fileId,String createBy,String uploadIp){ +// QueryWrapper queryWrapper=new QueryWrapper(); +// queryWrapper.eq("sys_file_record_id",fileId); +// queryWrapper.eq("upload_ip",uploadIp); +// queryWrapper.eq("create_by",createBy); +// FileUploadLog one = fileUploadLogService.getOne(queryWrapper); +// return one; +// } + +// /** +// * 查询上传记录 +// */ +// public Integer selFileUploadLog(String fileId){ +// QueryWrapper queryWrapper=new QueryWrapper(); +// queryWrapper.eq("sys_file_record_id",fileId); +// return fileUploadLogService.count(queryWrapper); +// } + + //是否拦截此文件 +// private boolean isFileter(String contentType){ +// QueryWrapper queryWrapper=new QueryWrapper(); +// queryWrapper.eq("content_type",contentType); +// queryWrapper.eq("is_filter",1); +// int count = fileFilterService.count(queryWrapper); +// return count>0; +// } +} diff --git a/src/main/java/com/zzlh/es/webupload/service/impl/FileZoneRecordServiceImpl.java b/src/main/java/com/zzlh/es/webupload/service/impl/FileZoneRecordServiceImpl.java new file mode 100644 index 0000000..2eb5537 --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/service/impl/FileZoneRecordServiceImpl.java @@ -0,0 +1,47 @@ +package com.zzlh.es.webupload.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import com.zzlh.es.mapper.FileZoneRecordMapper; +import com.zzlh.es.entity.FileZoneRecord; +import com.zzlh.es.webupload.service.IFileZoneRecordService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + *

+ * 文件分片记录 服务实现类 + *

+ * + * @author haijun + * @since 2020-02-14 + */ +@Service +public class FileZoneRecordServiceImpl extends ServiceImpl implements IFileZoneRecordService { + @Autowired + private FileZoneRecordMapper fileZoneRecordMapper; + + @Override + public FileZoneRecord selByMD5AndZoneTotalMd5(String zoneMd5, String zoneTotalMd5) { + QueryWrapper queryWrapper=new QueryWrapper(); + queryWrapper.eq("zone_md5",zoneMd5); + queryWrapper.eq("zone_total_md5",zoneTotalMd5); + List list = fileZoneRecordMapper.selectList(queryWrapper); + if(list.size()>0){ + return list.get(0); + } + return null; + } + + @Override + public List selByTotalMd5(String zoneTotalMd5) { + QueryWrapper queryWrapper=new QueryWrapper(); + queryWrapper.eq("zone_total_md5",zoneTotalMd5); + queryWrapper.orderByAsc("zone_now_index"); + List list = fileZoneRecordMapper.selectList(queryWrapper); + return list; + } +} diff --git a/src/main/java/com/zzlh/es/webupload/util/CommonException.java b/src/main/java/com/zzlh/es/webupload/util/CommonException.java new file mode 100644 index 0000000..98cf602 --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/util/CommonException.java @@ -0,0 +1,18 @@ +package com.zzlh.es.webupload.util; + + +import com.zzlh.es.webupload.entity.ResultCode; +import lombok.Getter; + +/** + * 自定义异常 + */ +@Getter +public class CommonException extends Exception { + + private ResultCode resultCode; + + public CommonException(ResultCode resultCode) { + this.resultCode = resultCode; + } +} diff --git a/src/main/java/com/zzlh/es/webupload/util/FileHandleUtil.java b/src/main/java/com/zzlh/es/webupload/util/FileHandleUtil.java new file mode 100644 index 0000000..9203cab --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/util/FileHandleUtil.java @@ -0,0 +1,98 @@ +package com.zzlh.es.webupload.util; + +import org.apache.commons.io.FileUtils; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +/** + * @描述 + * @参数 $ + * @返回值 $ + * @创建人 haijun + * @创建时间 $ + */ +public class FileHandleUtil { + /** + * 上传单个文件 + * + * @param inputStream 文件流 + * @param path 文件路径,如:image/ + * @param filename 文件名,如:test.jpg + * @return 成功:上传后的文件访问路径,失败返回:null + */ + public static String upload(InputStream inputStream, String path, String filename) { + //创建文件夹 + createDirIfNotExists(path); + //存文件 + File uploadFile = new File(path, filename); + try { + if(!uploadFile.exists()){//文件不存在 + FileUtils.copyInputStreamToFile(inputStream, uploadFile); + } + } catch (IOException e) { + e.printStackTrace(); + } + return uploadFile.getPath(); + } + + /** + * 创建文件夹路径 + */ + public static void createDirIfNotExists(String path) { + File file = new File(path); + if (!file.exists()) { + file.mkdirs(); + } + } + + /** + * 删除文件 + * + * @param path 文件访问的路径upload开始 如: /upload/image/test.jpg + * @return true 删除成功; false 删除失败 + */ + public static boolean delete(String path) { + File file = new File(path); + return file.exists() == true ? file.delete() : true; + } + + /*** + * 删除一个文件夹及文件夹下所有文件 + * @param path + * @return + */ + public static boolean deleteFolder(String path) { + File file = new File(path); + if (!file.exists()) { + return false; + } + if (file.isFile()) { + file.delete(); + return true; + } else { + File[] files = file.listFiles(); + for (int i = 0; i < files.length; i++) { + String root = files[i].getAbsolutePath();//得到子文件或文件夹的绝对路径 + //System.out.println(root); + deleteFolder(root); + } + file.delete(); + return true; + } + } + + /** + * 获取服务部署根路径 http:// + ip + port + * + * @param request + * @return + */ + public static String getServerIPPort(HttpServletRequest request) { + //+ ":" + request.getServerPort() + return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort(); + } + +} diff --git a/src/main/java/com/zzlh/es/webupload/util/FileUploadConfig.java b/src/main/java/com/zzlh/es/webupload/util/FileUploadConfig.java new file mode 100644 index 0000000..e409b13 --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/util/FileUploadConfig.java @@ -0,0 +1,29 @@ +package com.zzlh.es.webupload.util; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * @Description TODO 文件上传配置 + * @Author haijun + * @Date 2019/12/28 20:00 + * @ClassName FileUploadConfig + ***/ +@Getter +@Setter +@Component +@ConfigurationProperties("fileupload.config") +public class FileUploadConfig { + private String uploadFolder; + private String staticAccessPath; + private String localPath; + private String userHeaderPicPath; + private String archivesFilePath; + private String domain; + private String styleImage; + private String imageServerIp; + + +} diff --git a/src/main/java/com/zzlh/es/webupload/util/IPUtils.java b/src/main/java/com/zzlh/es/webupload/util/IPUtils.java new file mode 100644 index 0000000..5accd94 --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/util/IPUtils.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2016-2019 人人开源 All rights reserved. + * + * https://www.renren.io + * + * 版权所有,侵权必究! + */ + +package com.zzlh.es.webupload.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.StringUtils; + +import javax.servlet.http.HttpServletRequest; + +/** + * IP地址 + * + * @author Mark sunlightcs@gmail.com + */ +public class IPUtils { + private static Logger logger = LoggerFactory.getLogger(IPUtils.class); + + /** + * 获取IP地址 + * + * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址 + * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址 + */ + public static String getIpAddr(HttpServletRequest request) { + String ip = null; + try { + ip = request.getHeader("x-forwarded-for"); + if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + } catch (Exception e) { + logger.error("IPUtils ERROR ", e); + } + + return ip; + } + +} diff --git a/src/main/java/com/zzlh/es/webupload/util/IdWorker.java b/src/main/java/com/zzlh/es/webupload/util/IdWorker.java new file mode 100644 index 0000000..90e9125 --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/util/IdWorker.java @@ -0,0 +1,165 @@ +package com.zzlh.es.webupload.util; + +import org.springframework.stereotype.Component; + +import java.lang.management.ManagementFactory; +import java.net.InetAddress; +import java.net.NetworkInterface; + +/** + *

名称:IdWorker.java

+ *

描述:分布式自增长ID

+ *
+ *     Twitter的 Snowflake JAVA实现方案
+ * 
+ * 核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用—分割开部分的作用: + * 1||0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000 + * 在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间, + * 然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识), + * 然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。 + * 这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分), + * 并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。 + *

+ * 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加)) + * + * @author Polim + */ +@Component +public class IdWorker { + // 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动) + private final static long twepoch = 1288834974657L; + // 机器标识位数 + private final static long workerIdBits = 5L; + // 数据中心标识位数 + private final static long datacenterIdBits = 5L; + // 机器ID最大值 + private final static long maxWorkerId = -1L ^ (-1L << workerIdBits); + // 数据中心ID最大值 + private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); + // 毫秒内自增位 + private final static long sequenceBits = 12L; + // 机器ID偏左移12位 + private final static long workerIdShift = sequenceBits; + // 数据中心ID左移17位 + private final static long datacenterIdShift = sequenceBits + workerIdBits; + // 时间毫秒左移22位 + private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; + + private final static long sequenceMask = -1L ^ (-1L << sequenceBits); + /* 上次生产id时间戳 */ + private static long lastTimestamp = -1L; + // 0,并发控制 + private long sequence = 0L; + + private final long workerId; + // 数据标识id部分 + private final long datacenterId; + + public IdWorker() { + this.datacenterId = getDatacenterId(maxDatacenterId); + this.workerId = getMaxWorkerId(datacenterId, maxWorkerId); + } + + /** + * @param workerId 工作机器ID + * @param datacenterId 序列号 + */ + public IdWorker(long workerId, long datacenterId) { + if (workerId > maxWorkerId || workerId < 0) { + throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); + } + if (datacenterId > maxDatacenterId || datacenterId < 0) { + throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); + } + this.workerId = workerId; + this.datacenterId = datacenterId; + } + + /** + * 获取下一个ID + * + * @return + */ + public synchronized long nextId() { + long timestamp = timeGen(); + if (timestamp < lastTimestamp) { + throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); + } + + if (lastTimestamp == timestamp) { + // 当前毫秒内,则+1 + sequence = (sequence + 1) & sequenceMask; + if (sequence == 0) { + // 当前毫秒内计数满了,则等待下一秒 + timestamp = tilNextMillis(lastTimestamp); + } + } else { + sequence = 0L; + } + lastTimestamp = timestamp; + // ID偏移组合生成最终的ID,并返回ID + long nextId = ((timestamp - twepoch) << timestampLeftShift) + | (datacenterId << datacenterIdShift) + | (workerId << workerIdShift) | sequence; + + return nextId; + } + + private long tilNextMillis(final long lastTimestamp) { + long timestamp = this.timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = this.timeGen(); + } + return timestamp; + } + + private long timeGen() { + return System.currentTimeMillis(); + } + + /** + *

+ * 获取 maxWorkerId + *

+ */ + protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) { + StringBuffer mpid = new StringBuffer(); + mpid.append(datacenterId); + String name = ManagementFactory.getRuntimeMXBean().getName(); + if (!name.isEmpty()) { + /* + * GET jvmPid + */ + mpid.append(name.split("@")[0]); + } + /* + * MAC + PID 的 hashcode 获取16个低位 + */ + return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1); + } + + /** + *

+ * 数据标识id部分 + *

+ */ + protected static long getDatacenterId(long maxDatacenterId) { + long id = 0L; + try { + InetAddress ip = InetAddress.getLocalHost(); + NetworkInterface network = NetworkInterface.getByInetAddress(ip); + if (network == null) { + id = 1L; + } else { + byte[] mac = network.getHardwareAddress(); + id = ((0x000000FF & (long) mac[mac.length - 1]) + | (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6; + id = id % (maxDatacenterId + 1); + } + } catch (Exception e) { + System.out.println(" getDatacenterId: " + e.getMessage()); + } + return id; + } + +} \ No newline at end of file diff --git a/src/main/java/com/zzlh/es/webupload/util/OConvertUtils.java b/src/main/java/com/zzlh/es/webupload/util/OConvertUtils.java new file mode 100644 index 0000000..2261954 --- /dev/null +++ b/src/main/java/com/zzlh/es/webupload/util/OConvertUtils.java @@ -0,0 +1,577 @@ +package com.zzlh.es.webupload.util; + +import javax.servlet.http.HttpServletRequest; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.sql.Date; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class OConvertUtils { + public static boolean isEmpty(Object object) { + if (object == null) { + return (true); + } + if ("".equals(object)) { + return (true); + } + if ("null".equals(object)) { + return (true); + } + return (false); + } + + public static boolean isNotEmpty(Object object) { + if (object != null && !object.equals("") && !object.equals("null")) { + return (true); + } + return (false); + } + + public static String decode(String strIn, String sourceCode, String targetCode) { + String temp = code2code(strIn, sourceCode, targetCode); + return temp; + } + + public static String StrToUTF(String strIn, String sourceCode, String targetCode) { + strIn = ""; + try { + strIn = new String(strIn.getBytes("ISO-8859-1"), "GBK"); + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return strIn; + + } + + private static String code2code(String strIn, String sourceCode, String targetCode) { + String strOut = null; + if (strIn == null || (strIn.trim()).equals("")) { + return strIn; + } + try { + byte[] b = strIn.getBytes(sourceCode); + for (int i = 0; i < b.length; i++) { + System.out.print(b[i] + " "); + } + strOut = new String(b, targetCode); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + return strOut; + } + + public static int getInt(String s, int defval) { + if (s == null || s == "") { + return (defval); + } + try { + return (Integer.parseInt(s)); + } catch (NumberFormatException e) { + return (defval); + } + } + + public static int getInt(String s) { + if (s == null || s == "") { + return 0; + } + try { + return (Integer.parseInt(s)); + } catch (NumberFormatException e) { + return 0; + } + } + + public static int getInt(String s, Integer df) { + if (s == null || s == "") { + return df; + } + try { + return (Integer.parseInt(s)); + } catch (NumberFormatException e) { + return 0; + } + } + + public static Integer[] getInts(String[] s) { + Integer[] integer = new Integer[s.length]; + if (s == null) { + return null; + } + for (int i = 0; i < s.length; i++) { + integer[i] = Integer.parseInt(s[i]); + } + return integer; + + } + + public static double getDouble(String s, double defval) { + if (s == null || s == "") { + return (defval); + } + try { + return (Double.parseDouble(s)); + } catch (NumberFormatException e) { + return (defval); + } + } + + public static double getDou(Double s, double defval) { + if (s == null) { + return (defval); + } + return s; + } + + /*public static Short getShort(String s) { + if (StringUtil.isNotEmpty(s)) { + return (Short.parseShort(s)); + } else { + return null; + } + }*/ + + public static int getInt(Object object, int defval) { + if (isEmpty(object)) { + return (defval); + } + try { + return (Integer.parseInt(object.toString())); + } catch (NumberFormatException e) { + return (defval); + } + } + + public static Integer getInt(Object object) { + if (isEmpty(object)) { + return null; + } + try { + return (Integer.parseInt(object.toString())); + } catch (NumberFormatException e) { + return null; + } + } + + public static int getInt(BigDecimal s, int defval) { + if (s == null) { + return (defval); + } + return s.intValue(); + } + + public static Integer[] getIntegerArry(String[] object) { + int len = object.length; + Integer[] result = new Integer[len]; + try { + for (int i = 0; i < len; i++) { + result[i] = new Integer(object[i].trim()); + } + return result; + } catch (NumberFormatException e) { + return null; + } + } + + public static String getString(String s) { + return (getString(s, "")); + } + + /** + * 转义成Unicode编码 + * @param s + * @return + */ + /*public static String escapeJava(Object s) { + return StringEscapeUtils.escapeJava(getString(s)); + }*/ + + public static String getString(Object object) { + if (isEmpty(object)) { + return ""; + } + return (object.toString().trim()); + } + + public static String getString(int i) { + return (String.valueOf(i)); + } + + public static String getString(float i) { + return (String.valueOf(i)); + } + + public static String getString(String s, String defval) { + if (isEmpty(s)) { + return (defval); + } + return (s.trim()); + } + + public static String getString(Object s, String defval) { + if (isEmpty(s)) { + return (defval); + } + return (s.toString().trim()); + } + + public static long stringToLong(String str) { + Long test = new Long(0); + try { + test = Long.valueOf(str); + } catch (Exception e) { + } + return test.longValue(); + } + + /** + * 获取本机IP + */ + public static String getIp() { + String ip = null; + try { + InetAddress address = InetAddress.getLocalHost(); + ip = address.getHostAddress(); + + } catch (UnknownHostException e) { + e.printStackTrace(); + } + return ip; + } + + /** + * 判断一个类是否为基本数据类型。 + * + * @param clazz + * 要判断的类。 + * @return true 表示为基本数据类型。 + */ + private static boolean isBaseDataType(Class clazz) throws Exception { + return (clazz.equals(String.class) || clazz.equals(Integer.class) || clazz.equals(Byte.class) || clazz.equals(Long.class) || clazz.equals(Double.class) || clazz.equals(Float.class) || clazz.equals(Character.class) || clazz.equals(Short.class) || clazz.equals(BigDecimal.class) || clazz.equals(BigInteger.class) || clazz.equals(Boolean.class) || clazz.equals(Date.class) || clazz.isPrimitive()); + } + + /** + * @param request + * IP + * @return IP Address + */ + public static String getIpAddrByRequest(HttpServletRequest request) { + String ip = request.getHeader("x-forwarded-for"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + return ip; + } + + /** + * @return 本机IP + * @throws SocketException + */ + public static String getRealIp() throws SocketException { + String localip = null;// 本地IP,如果没有配置外网IP则返回它 + String netip = null;// 外网IP + + Enumeration netInterfaces = NetworkInterface.getNetworkInterfaces(); + InetAddress ip = null; + boolean finded = false;// 是否找到外网IP + while (netInterfaces.hasMoreElements() && !finded) { + NetworkInterface ni = netInterfaces.nextElement(); + Enumeration address = ni.getInetAddresses(); + while (address.hasMoreElements()) { + ip = address.nextElement(); + if (!ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {// 外网IP + netip = ip.getHostAddress(); + finded = true; + break; + } else if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {// 内网IP + localip = ip.getHostAddress(); + } + } + } + + if (netip != null && !"".equals(netip)) { + return netip; + } else { + return localip; + } + } + + /** + * java去除字符串中的空格、回车、换行符、制表符 + * + * @param str + * @return + */ + public static String replaceBlank(String str) { + String dest = ""; + if (str != null) { + Pattern p = Pattern.compile("\\s*|\t|\r|\n"); + Matcher m = p.matcher(str); + dest = m.replaceAll(""); + } + return dest; + + } + + /** + * 判断元素是否在数组内 + * + * @param substring + * @param source + * @return + */ + public static boolean isIn(String substring, String[] source) { + if (source == null || source.length == 0) { + return false; + } + for (int i = 0; i < source.length; i++) { + String aSource = source[i]; + if (aSource.equals(substring)) { + return true; + } + } + return false; + } + + /** + * 获取Map对象 + */ + public static Map getHashMap() { + return new HashMap(); + } + + /** + * SET转换MAP + * + * @param str + * @return + */ + public static Map SetToMap(Set setobj) { + Map map = getHashMap(); + for (Iterator iterator = setobj.iterator(); iterator.hasNext();) { + Map.Entry entry = (Map.Entry) iterator.next(); + map.put(entry.getKey().toString(), entry.getValue() == null ? "" : entry.getValue().toString().trim()); + } + return map; + + } + + public static boolean isInnerIP(String ipAddress) { + boolean isInnerIp = false; + long ipNum = getIpNum(ipAddress); + /** + * 私有IP:A类 10.0.0.0-10.255.255.255 B类 172.16.0.0-172.31.255.255 C类 192.168.0.0-192.168.255.255 当然,还有127这个网段是环回地址 + **/ + long aBegin = getIpNum("10.0.0.0"); + long aEnd = getIpNum("10.255.255.255"); + long bBegin = getIpNum("172.16.0.0"); + long bEnd = getIpNum("172.31.255.255"); + long cBegin = getIpNum("192.168.0.0"); + long cEnd = getIpNum("192.168.255.255"); + isInnerIp = isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd) || ipAddress.equals("127.0.0.1"); + return isInnerIp; + } + + private static long getIpNum(String ipAddress) { + String[] ip = ipAddress.split("\\."); + long a = Integer.parseInt(ip[0]); + long b = Integer.parseInt(ip[1]); + long c = Integer.parseInt(ip[2]); + long d = Integer.parseInt(ip[3]); + + long ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d; + return ipNum; + } + + private static boolean isInner(long userIp, long begin, long end) { + return (userIp >= begin) && (userIp <= end); + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。 + * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
+ * 例如:hello_world->helloWorld + * + * @param name + * 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String camelName(String name) { + StringBuilder result = new StringBuilder(); + // 快速检查 + if (name == null || name.isEmpty()) { + // 没必要转换 + return ""; + } else if (!name.contains("_")) { + // 不含下划线,仅将首字母小写 + //update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 + //update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 + return name.substring(0, 1).toLowerCase() + name.substring(1).toLowerCase(); + //update-end--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 + } + // 用下划线将原始字符串分割 + String camels[] = name.split("_"); + for (String camel : camels) { + // 跳过原始字符串中开头、结尾的下换线或双重下划线 + if (camel.isEmpty()) { + continue; + } + // 处理真正的驼峰片段 + if (result.length() == 0) { + // 第一个驼峰片段,全部字母都小写 + result.append(camel.toLowerCase()); + } else { + // 其他的驼峰片段,首字母大写 + result.append(camel.substring(0, 1).toUpperCase()); + result.append(camel.substring(1).toLowerCase()); + } + } + return result.toString(); + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。 + * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
+ * 例如:hello_world,test_id->helloWorld,testId + * + * @param name + * 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String camelNames(String names) { + if(names==null||names.equals("")){ + return null; + } + StringBuffer sf = new StringBuffer(); + String[] fs = names.split(","); + for (String field : fs) { + field = camelName(field); + sf.append(field + ","); + } + String result = sf.toString(); + return result.substring(0, result.length() - 1); + } + + //update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 + /** + * 将下划线大写方式命名的字符串转换为驼峰式。(首字母写) + * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
+ * 例如:hello_world->HelloWorld + * + * @param name + * 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String camelNameCapFirst(String name) { + StringBuilder result = new StringBuilder(); + // 快速检查 + if (name == null || name.isEmpty()) { + // 没必要转换 + return ""; + } else if (!name.contains("_")) { + // 不含下划线,仅将首字母小写 + return name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase(); + } + // 用下划线将原始字符串分割 + String camels[] = name.split("_"); + for (String camel : camels) { + // 跳过原始字符串中开头、结尾的下换线或双重下划线 + if (camel.isEmpty()) { + continue; + } + // 其他的驼峰片段,首字母大写 + result.append(camel.substring(0, 1).toUpperCase()); + result.append(camel.substring(1).toLowerCase()); + } + return result.toString(); + } + //update-end--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 + + /** + * 将驼峰命名转化成下划线 + * @param para + * @return + */ + public static String camelToUnderline(String para){ + if(para.length()<3){ + return para.toLowerCase(); + } + StringBuilder sb=new StringBuilder(para); + int temp=0;//定位 + //从第三个字符开始 避免命名不规范 + for(int i=2;i clazz = object.getClass(); + List fieldList = new ArrayList<>(); + while (clazz != null) { + fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields()))); + clazz = clazz.getSuperclass(); + } + Field[] fields = new Field[fieldList.size()]; + fieldList.toArray(fields); + return fields; + } + + /** + * 将map的key全部转成小写 + * @param list + * @return + */ + public static List> toLowerCasePageList(List> list){ + List> select = new ArrayList<>(); + for (Map row : list) { + Map resultMap = new HashMap<>(); + Set keySet = row.keySet(); + for (String key : keySet) { + String newKey = key.toLowerCase(); + resultMap.put(newKey, row.get(key)); + } + select.add(resultMap); + } + return select; + } +} diff --git a/src/main/resources/config/application-dev.yml b/src/main/resources/config/application-dev.yml new file mode 100644 index 0000000..0bbe3d9 --- /dev/null +++ b/src/main/resources/config/application-dev.yml @@ -0,0 +1,80 @@ +server: + port: 9006 + servlet: + context-path: + tomcat: + uri-encoding: UTF-8 +spring: + servlet: + multipart: + max-file-size: 100MB + max-request-size: 50MB + redis: + #数据库索引 + database: 0 + host: 127.0.0.1 + port: 6379 + password: HopetryRedis + jedis: + pool: + #最大连接数 + max-active: 8 + #最大阻塞等待时间(负数表示没限制) + max-wait: -1 + #最大空闲 + max-idle: 8 + #最小空闲 + min-idle: 0 + #连接超时时间 + timeout: 10000 + datasource: + driver-class-name: org.postgresql.Driver + druid: + username: postgres + password: FirePrevention2023 + url: jdbc:postgresql://localhost:5432/FirePrevention +geoserver: + #geoserver地址 + url: http://221.2.83.254:9007/geoserver + #用户名 + username: admin + #密码 + password: Irw5sC3@ZpOMT3RmY + #工作区 + shpworkspace: ksp + #数据存储 + shpstorename: ksp_shp + imageworkspace: image + path: D:\parseZip\ +localdir: + style: protectedAreaGnfq + +fileupload: + config: + # 文件上传目录 + #uploadFolder: /usr/local/upload + uploadFolder: D://webupload/ + #静态资源对外暴露的访问路径(访问图片的路径) + staticAccessPath: storage/** + # 设备截图文件保存路径(文件存在具体的文件夹的路径) + localPath: fileData/ + #用户头像存放 + userHeaderPicPath: user/ + #档案文件存放 + archivesFilePath: webuploadfile/ + #档案文件存放 + styleImage: styleImages/ + #图片服务ip + imageServerIp: http://221.2.83.254:9012 + #访问域名和端口 + domain: http://localhost:${server.port}${server.servlet.context-path} +postGis: + url: localhost + username: postgres + password: FirePrevention2023 + dbname: FirePrevention + shpfile: D:\shpfileStore\ + shpfileZip: D:\webupload\fileData\ + pgsqlexe: D:\PostgreSQL\14\bin\pgsql2shp.exe + downLoadUrl: http://221.2.83.254:9012 + diff --git a/src/main/resources/config/application-fx.yml b/src/main/resources/config/application-fx.yml new file mode 100644 index 0000000..e6fc173 --- /dev/null +++ b/src/main/resources/config/application-fx.yml @@ -0,0 +1,70 @@ +server: + port: 9236 + servlet: + context-path: + tomcat: + uri-encoding: UTF-8 +spring: + servlet: + multipart: + max-file-size: 50MB + max-request-size: 50MB + redis: + #数据库索引 + database: 0 + host: 127.0.0.1 + port: 6379 + password: + jedis: + pool: + #最大连接数 + max-active: 8 + #最大阻塞等待时间(负数表示没限制) + max-wait: -1 + #最大空闲 + max-idle: 8 + #最小空闲 + min-idle: 0 + #连接超时时间 + timeout: 10000 + datasource: + driver-class-name: org.postgresql.Driver + druid: + username: postgres + password: hopetry + url: jdbc:postgresql://localhost:5432/FirePreventionCommand +geoserver: + #geoserver地址 + url: http://123.132.248.154:9235/geoserver + #用户名 + username: admin + #密码 + password: Hopetry@A1406 + #工作区 + shpworkspace: ksp + #数据存储 + shpstorename: ksp_shp + imageworkspace: image + path: E:\parseZip\ +localdir: + style: protectedAreaGnfq + +fileupload: + config: + # 文件上传目录 + #uploadFolder: /usr/local/upload + uploadFolder: E://webupload/ + #静态资源对外暴露的访问路径(访问图片的路径) + staticAccessPath: storage/** + # 设备截图文件保存路径(文件存在具体的文件夹的路径) + localPath: fileData/ + #用户头像存放 + userHeaderPicPath: user/ + #档案文件存放 + archivesFilePath: webuploadfile/ + #档案文件存放 + styleImage: styleImages/ + #图片服务ip + imageServerIp: http://123.132.248.154:9238 + #访问域名和端口 + domain: http://localhost:${server.port}${server.servlet.context-path} diff --git a/src/main/resources/config/application-pg.yml b/src/main/resources/config/application-pg.yml new file mode 100644 index 0000000..8277464 --- /dev/null +++ b/src/main/resources/config/application-pg.yml @@ -0,0 +1,76 @@ +server: + port: 8909 + servlet: + context-path: + tomcat: + uri-encoding: UTF-8 +spring: + redis: + #数据库索引 + database: 0 + host: 127.0.0.1 + port: 6379 + password: + jedis: + pool: + #最大连接数 + max-active: 8 + #最大阻塞等待时间(负数表示没限制) + max-wait: -1 + #最大空闲 + max-idle: 8 + #最小空闲 + min-idle: 0 + #连接超时时间 + timeout: 10000 + datasource: + driver-class-name: org.postgresql.Driver + druid: + username: postgres + password: 123456 + url: jdbc:postgresql://localhost:5432/postgres +geoserver: + #geoserver地址 + url: http://localhost:9007/geoserver + #用户名 + username: admin + #密码 + password: Irw5sC3@ZpO#MT3RmY&# + #工作区 + shpworkspace: ksp + #数据存储 + shpstorename: ksp_shp + imageworkspace: image + path: D:\parseZip\ +localdir: + style: protectedAreaGnfq + +fileupload: + config: + # 文件上传目录 + #uploadFolder: /usr/local/upload + uploadFolder: D://webupload/ + #静态资源对外暴露的访问路径(访问图片的路径) + staticAccessPath: storage/** + # 设备截图文件保存路径(文件存在具体的文件夹的路径) + localPath: fileData/ + #用户头像存放 + userHeaderPicPath: user/ + #档案文件存放 + archivesFilePath: webuploadfile/ + #档案文件存放 + styleImage: styleImages/ + #图片服务ip + imageServerIp: http://192.168.10.122:9208 + #访问域名和端口 + domain: http://localhost:${server.port}${server.servlet.context-path} + +postGis: + url: localhost + username: postgres + password: 123456 + dbname: postgres + shpfile: D:\shpfileStore\ + shpfileZip: D:\shpfileStoreZip\ + pgsqlexe: D:\SoftWare\Pgsql\bin\pgsql2shp.exe + downLoadUrl: http://123.132.248.154:9238 diff --git a/src/main/resources/config/application-product.yml b/src/main/resources/config/application-product.yml new file mode 100644 index 0000000..8883e87 --- /dev/null +++ b/src/main/resources/config/application-product.yml @@ -0,0 +1,67 @@ +server: + port: 9217 + servlet: + context-path: + tomcat: + uri-encoding: UTF-8 +spring: + + redis: + #数据库索引 + database: 0 + host: 127.0.0.1 + port: 6379 + password: hc + jedis: + pool: + #最大连接数 + max-active: 8 + #最大阻塞等待时间(负数表示没限制) + max-wait: -1 + #最大空闲 + max-idle: 8 + #最小空闲 + min-idle: 0 + #连接超时时间 + timeout: 10000 + datasource: + driver-class-name: org.postgresql.Driver + druid: + username: postgres + password: HopetryA1406 + url: jdbc:postgresql://localhost:5432/FirePreventionCommand +geoserver: + #geoserver地址 + url: http://123.132.248.154:9205/geoserver + #用户名 + username: admin + #密码 + password: geoserver + #工作区 + shpworkspace: ksp + #数据存储 + shpstorename: ksp_shp + imageworkspace: image + path: E:\parseZip\ +localdir: + style: protectedAreaGnfq + +fileupload: + config: + # 文件上传目录 + #uploadFolder: /usr/local/upload + uploadFolder: E://webupload/ + #静态资源对外暴露的访问路径(访问图片的路径) + staticAccessPath: storage/** + # 设备截图文件保存路径(文件存在具体的文件夹的路径) + localPath: fileData/ + #用户头像存放 + userHeaderPicPath: user/ + #档案文件存放 + archivesFilePath: webuploadfile/ + #档案文件存放 + styleImage: styleImages/ + #图片服务ip + imageServerIp: http://123.132.248.154:9217 + #访问域名和端口 + domain: http://localhost:${server.port}${server.servlet.context-path} diff --git a/src/main/resources/config/application-py.yml b/src/main/resources/config/application-py.yml new file mode 100644 index 0000000..b265ca2 --- /dev/null +++ b/src/main/resources/config/application-py.yml @@ -0,0 +1,79 @@ +server: + port: 9006 + servlet: + context-path: + tomcat: + uri-encoding: UTF-8 +spring: + servlet: + multipart: + max-file-size: 50MB + max-request-size: 50MB + redis: + #数据库索引 + database: 0 + host: 127.0.0.1 + port: 6379 + password: + jedis: + pool: + #最大连接数 + max-active: 8 + #最大阻塞等待时间(负数表示没限制) + max-wait: -1 + #最大空闲 + max-idle: 8 + #最小空闲 + min-idle: 0 + #连接超时时间 + timeout: 10000 + datasource: + driver-class-name: org.postgresql.Driver + druid: + username: postgres + password: PYFirePrevention + url: jdbc:postgresql://localhost:5432/FirePreventionCommand +geoserver: + #geoserver地址 + url: http://111.17.207.220:9007/geoserver + #用户名 + username: admin + #密码 + password: Hopetry@A1406 + #工作区 + shpworkspace: ksp + #数据存储 + shpstorename: ksp_shp + imageworkspace: image + path: D:\parseZip\ +localdir: + style: protectedAreaGnfq + +fileupload: + config: + # 文件上传目录 + #uploadFolder: /usr/local/upload + uploadFolder: D://webupload/ + #静态资源对外暴露的访问路径(访问图片的路径) + staticAccessPath: storage/** + # 设备截图文件保存路径(文件存在具体的文件夹的路径) + localPath: fileData/ + #用户头像存放 + userHeaderPicPath: user/ + #档案文件存放 + archivesFilePath: webuploadfile/ + #档案文件存放 + styleImage: styleImages/ + #图片服务ip + imageServerIp: http://111.17.207.220:9005 + #访问域名和端口 + domain: http://localhost:${server.port}${server.servlet.context-path} +postGis: + url: localhost + username: postgres + password: PYFirePrevention + dbname: FirePreventionCommand + shpfile: D:\shpfileStore\ + shpfileZip: D:\webupload\fileData\ + pgsqlexe: D:\Program Files (x86)\PostgreSQL\14\bin\pgsql2shp.exe + downLoadUrl: http://111.17.207.220:9005 diff --git a/src/main/resources/config/application-pybak.yml b/src/main/resources/config/application-pybak.yml new file mode 100644 index 0000000..bd0d689 --- /dev/null +++ b/src/main/resources/config/application-pybak.yml @@ -0,0 +1,79 @@ +server: + port: 9234 + servlet: + context-path: + tomcat: + uri-encoding: UTF-8 +spring: + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + redis: + #数据库索引 + database: 0 + host: 127.0.0.1 + port: 6379 + password: + jedis: + pool: + #最大连接数 + max-active: 8 + #最大阻塞等待时间(负数表示没限制) + max-wait: -1 + #最大空闲 + max-idle: 8 + #最小空闲 + min-idle: 0 + #连接超时时间 + timeout: 10000 + datasource: + driver-class-name: org.postgresql.Driver + druid: + username: postgres + password: FirePrevention2023 + url: jdbc:postgresql://localhost:5432/FirePreventionCommand +geoserver: + #geoserver地址 + url: https://fx.hopetrytech.com:7005/geoserver + #用户名 + username: admin + #密码 + password: geoserver + #工作区 + shpworkspace: ksp + #数据存储 + shpstorename: ksp_shp + imageworkspace: image + path: D:\parseZip\ +localdir: + style: protectedAreaGnfq + +fileupload: + config: + # 文件上传目录 + #uploadFolder: /usr/local/upload + uploadFolder: D://webupload/ + #静态资源对外暴露的访问路径(访问图片的路径) + staticAccessPath: storage/** + # 设备截图文件保存路径(文件存在具体的文件夹的路径) + localPath: fileData/ + #用户头像存放 + userHeaderPicPath: user/ + #档案文件存放 + archivesFilePath: webuploadfile/ + #档案文件存放 + styleImage: styleImages/ + #图片服务ip + imageServerIp: https://fx.hopetrytech.com:7009 + #访问域名和端口 + domain: http://localhost:${server.port}${server.servlet.context-path} +postGis: + url: localhost + username: postgres + password: hopetry + dbname: FirePreventionCommand + shpfile: D:\shpfileStore\ + shpfileZip: D:\webupload\fileData\ + pgsqlexe: D:\Program Files\PostgreSQL\14\bin\pgsql2shp.exe + downLoadUrl: https://fx.hopetrytech.com:7009 diff --git a/src/main/resources/config/application-ys.yml b/src/main/resources/config/application-ys.yml new file mode 100644 index 0000000..58ecf81 --- /dev/null +++ b/src/main/resources/config/application-ys.yml @@ -0,0 +1,79 @@ +server: + port: 9006 + servlet: + context-path: + tomcat: + uri-encoding: UTF-8 +spring: + servlet: + multipart: + max-file-size: 200MB + max-request-size: 200MB + redis: + #数据库索引 + database: 0 + host: 127.0.0.1 + port: 6379 + password: + jedis: + pool: + #最大连接数 + max-active: 8 + #最大阻塞等待时间(负数表示没限制) + max-wait: -1 + #最大空闲 + max-idle: 8 + #最小空闲 + min-idle: 0 + #连接超时时间 + timeout: 10000 + datasource: + driver-class-name: org.postgresql.Driver + druid: + username: postgres + password: YSFirePrevention + url: jdbc:postgresql://localhost:5432/FirePreventionCommand +geoserver: + #geoserver地址 + url: http://60.217.22.153:9007/geoserver + #用户名 + username: admin + #密码 + password: Hopetry@A1406 + #工作区 + shpworkspace: ksp + #数据存储 + shpstorename: ksp_shp + imageworkspace: image + path: E:\parseZip\ +localdir: + style: protectedAreaGnfq + +fileupload: + config: + # 文件上传目录 + #uploadFolder: /usr/local/upload + uploadFolder: E://webupload/ + #静态资源对外暴露的访问路径(访问图片的路径) + staticAccessPath: storage/** + # 设备截图文件保存路径(文件存在具体的文件夹的路径) + localPath: fileData/ + #用户头像存放 + userHeaderPicPath: user/ + #档案文件存放 + archivesFilePath: webuploadfile/ + #档案文件存放 + styleImage: styleImages/ + #图片服务ip + imageServerIp: http://60.217.22.153:9012 + #访问域名和端口 + domain: http://localhost:${server.port}${server.servlet.context-path} +postGis: + url: localhost + username: postgres + password: YSFirePrevention + dbname: FirePreventionCommand + shpfile: E:\shpfileStore\ + shpfileZip: E:\webupload\fileData\ + pgsqlexe: E:\Program Files\PostgreSQL\14\bin\pgsql2shp.exe + downLoadUrl: http://60.217.22.153:9012 diff --git a/src/main/resources/config/application-zz.yml b/src/main/resources/config/application-zz.yml new file mode 100644 index 0000000..f41fb5e --- /dev/null +++ b/src/main/resources/config/application-zz.yml @@ -0,0 +1,79 @@ +server: + port: 9024 + servlet: + context-path: + tomcat: + uri-encoding: UTF-8 +spring: + servlet: + multipart: + max-file-size: 200MB + max-request-size: 200MB + redis: + #数据库索引 + database: 0 + host: 127.0.0.1 + port: 6379 + password: + jedis: + pool: + #最大连接数 + max-active: 8 + #最大阻塞等待时间(负数表示没限制) + max-wait: -1 + #最大空闲 + max-idle: 8 + #最小空闲 + min-idle: 0 + #连接超时时间 + timeout: 10000 + datasource: + driver-class-name: org.postgresql.Driver + druid: + username: postgres + password: zaozhuang2024 + url: jdbc:postgresql://localhost:5432/FirePreventionCommand +geoserver: + #geoserver地址 + url: http://221.2.83.254:9026/geoserver + #用户名 + username: admin + #密码 + password: Hopetry@A1406 + #工作区 + shpworkspace: ksp + #数据存储 + shpstorename: ksp_shp + imageworkspace: image + path: D:\parseZip\ +localdir: + style: protectedAreaGnfq + +fileupload: + config: + # 文件上传目录 + #uploadFolder: /usr/local/upload + uploadFolder: D://webupload/ + #静态资源对外暴露的访问路径(访问图片的路径) + staticAccessPath: storage/** + # 设备截图文件保存路径(文件存在具体的文件夹的路径) + localPath: fileData/ + #用户头像存放 + userHeaderPicPath: user/ + #档案文件存放 + archivesFilePath: webuploadfile/ + #档案文件存放 + styleImage: styleImages/ + #图片服务ip + imageServerIp: http://221.2.83.254:9025 + #访问域名和端口 + domain: http://localhost:${server.port}${server.servlet.context-path} +postGis: + url: localhost + username: postgres + password: YSFirePrevention + dbname: FirePreventionCommand + shpfile: D:\shpfileStore\ + shpfileZip: D:\webupload\fileData\ + pgsqlexe: D:\Softwares\PostgreSQL\14\bin\pgsql2shp.exe + downLoadUrl: http://221.2.83.254:9025 diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml new file mode 100644 index 0000000..713b833 --- /dev/null +++ b/src/main/resources/config/application.yml @@ -0,0 +1,75 @@ +server: + port: 8909 + servlet: + context-path: + tomcat: + uri-encoding: UTF-8 + +spring: + freemarker: + check-template-location: false + profiles: + active: pg + jackson: + time-zone: GMT+8 + servlet: + multipart: + max-file-size: 50MB + max-request-size: 50MB +mybatis-plus: + check-config-location: true + configuration: + map-underscore-to-camel-case: true + global-config: + db-config: + id-type: id_worker + logic-delete-value: 0 + logic-not-delete-value: 1 + mapper-locations: classpath*:mapper/*Mapper.xml + type-aliases-package: com.zzlh.es.entity +geoserver: + #geoserver地址 + url: http://192.168.10.109:8180/geoserver + #用户名 + username: admin + #密码 + password: Irw5sC3@ZpO#MT3RmY&# + #工作区 + shpworkspace: ksp + #数据存储 + shpstorename: ksp_shp + imageworkspace: image + path: D:\parseZip\ +localdir: + style: protectedAreaGnfq + +jwt: + header: Authorization + secret: mySecret + expiration: 60000000 + tokenHead: Bearer + + +logging: + level: + com.zzlh.es.mapper: warn + +fileupload: + config: + # 文件上传目录 + #uploadFolder: /usr/local/upload + uploadFolder: D://webupload/ + #静态资源对外暴露的访问路径(访问图片的路径) + staticAccessPath: storage/** + # 设备截图文件保存路径(文件存在具体的文件夹的路径) + localPath: fileData/ + #用户头像存放 + userHeaderPicPath: user/ + #档案文件存放 + archivesFilePath: webuploadfile/ + #档案文件存放 + styleImage: styleImages/ + #图片服务ip + imageServerIp: 192.168.10.122:9208 + #访问域名和端口 + domain: http://localhost:${server.port}${server.servlet.context-path} diff --git a/src/main/resources/init.sql b/src/main/resources/init.sql new file mode 100644 index 0000000..b3cc96e --- /dev/null +++ b/src/main/resources/init.sql @@ -0,0 +1,523 @@ +-- 用户表 +DROP TABLE IF EXISTS "public"."t_user"; +CREATE TABLE "public"."t_user" +( + "id" int4 NOT NULL, + "create_time" date NOT NULL, + "username" varchar(255) COLLATE "pg_catalog"."default" NOT NULL, + "password" varchar(255) COLLATE "pg_catalog"."default" NOT NULL, + "salt" varchar(255) COLLATE "pg_catalog"."default", + "state" varchar(1) COLLATE "pg_catalog"."default" NOT NULL, + CONSTRAINT "t_user_pkey" PRIMARY KEY ("id") +) +; + +ALTER TABLE "public"."t_user" + OWNER TO "postgres"; + +COMMENT ON COLUMN "public"."t_user"."id" IS '主键'; + +INSERT INTO "public"."t_user" ("id", "create_time", "username", "password", "salt", "state") +VALUES (1, '2023-03-23', 'admin', '$2a$10$n5zT45BPGXyksNsuY77D8.NR1KoMy55.QiYGAmRr.rnSPWdD65Foy', + '$2a$10$n5zT45BPGXyksNsuY77D8.NR1KoMy55.QiYGAmRr.rnSPWdD65Foy', '0'); + +--应用数据 + +DROP SEQUENCE IF EXISTS "public"."application_data_seq"; +CREATE SEQUENCE "public"."application_data_seq" + INCREMENT 1 + MINVALUE 1 + MAXVALUE 99999999 + START 1 + CACHE 1; + +DROP TABLE IF EXISTS "public"."application_data"; +CREATE TABLE "public"."application_data" +( + "id" numeric(11, 0) NOT NULL DEFAULT nextval('application_data_seq'::regclass), + "application_name" varchar(64) COLLATE "pg_catalog"."default" NOT NULL, + "space_type" varchar(32) COLLATE "pg_catalog"."default" NOT NULL, + "map_frame" varchar(32) COLLATE "pg_catalog"."default" NOT NULL, + "underlay" varchar(32) COLLATE "pg_catalog"."default" NOT NULL, + CONSTRAINT "data_store_copy1_pkey" PRIMARY KEY ("id") +) +; + + + +ALTER TABLE "public"."application_data" + OWNER TO "postgres"; + +COMMENT ON COLUMN "public"."application_data"."id" IS 'ID'; + +COMMENT ON COLUMN "public"."application_data"."application_name" IS '应用名称'; + +COMMENT ON COLUMN "public"."application_data"."space_type" IS '空间坐标(4326)'; + +COMMENT ON COLUMN "public"."application_data"."map_frame" IS 'Cesium Mapbox Mars3d'; + +COMMENT ON COLUMN "public"."application_data"."underlay" IS '底图(天地图)'; + +--图层服务 +DROP SEQUENCE IF EXISTS "public"."data_store_seq" CASCADE; +CREATE SEQUENCE "public"."data_store_seq" + INCREMENT 1 + MINVALUE 1 + MAXVALUE 99999999 + START 1 + CACHE 1; +DROP TABLE IF EXISTS "public"."data_store"; +CREATE TABLE "public"."data_store" +( + "id" numeric NOT NULL DEFAULT nextval('data_store_seq'::regclass), + "sever_name" varchar(64) COLLATE "pg_catalog"."default", + "space_type" varchar(32) COLLATE "pg_catalog"."default", + "sever_type" varchar(32) COLLATE "pg_catalog"."default", + "store_type" varchar(32) COLLATE "pg_catalog"."default", + "datasource_type" varchar(32) COLLATE "pg_catalog"."default", + "create_time" date, + "table_ref" varchar(32) COLLATE "pg_catalog"."default", + "is_display" numeric, + "data_type" varchar(16) COLLATE "pg_catalog"."default", + "style_name" varchar(64) COLLATE "pg_catalog"."default", + CONSTRAINT "data_store_pkey" PRIMARY KEY ("id") +) +; + +ALTER TABLE "public"."data_store" + OWNER TO "postgres"; +COMMENT ON COLUMN "public"."data_store"."id" IS 'ID'; + +COMMENT ON COLUMN "public"."data_store"."sever_name" IS '服务名称(图层)'; + +COMMENT ON COLUMN "public"."data_store"."space_type" IS '空间坐标(4326)'; + +COMMENT ON COLUMN "public"."data_store"."sever_type" IS '服务类型(字段)'; + +COMMENT ON COLUMN "public"."data_store"."store_type" IS '存储类型(geoserver 文件服务 pgsql)'; + +COMMENT ON COLUMN "public"."data_store"."datasource_type" IS '数据源类型(shape excel 其他)'; + +COMMENT ON COLUMN "public"."data_store"."create_time" IS '创建时间'; + +COMMENT ON COLUMN "public"."data_store"."table_ref" IS '关联数据表(图层表)'; + +COMMENT ON COLUMN "public"."data_store"."is_display" IS '是否发布(1, 0)'; + +COMMENT ON COLUMN "public"."data_store"."data_type" IS '点线面'; + +COMMENT ON COLUMN "public"."data_store"."style_name" IS '样式名称'; + +--字典 +DROP SEQUENCE IF EXISTS "public"."dict_data_seq"; +CREATE SEQUENCE "public"."dict_data_seq" + INCREMENT 1 + MINVALUE 1 + MAXVALUE 99999999 + START 1 + CACHE 1; +DROP TABLE IF EXISTS "public"."dict_data"; +CREATE TABLE "public"."dict_data" +( + "id" numeric NOT NULL DEFAULT nextval('dict_data_seq'::regclass), + "dict_label" varchar(64) COLLATE "pg_catalog"."default", + "dict_value" varchar(64) COLLATE "pg_catalog"."default", + "dict_type" varchar(32) COLLATE "pg_catalog"."default", + CONSTRAINT "dict_data_pkey" PRIMARY KEY ("id") +) +; + +ALTER TABLE "public"."dict_data" + OWNER TO "postgres"; + +COMMENT ON COLUMN "public"."dict_data"."dict_label" IS '字典名称'; + +COMMENT ON COLUMN "public"."dict_data"."dict_value" IS '字典值'; + +COMMENT ON COLUMN "public"."dict_data"."dict_type" IS '类型'; + +INSERT INTO "public"."dict_data" ("dict_label", "dict_value", "dict_type") +VALUES ('EPSG:4326', '1', 'space_type'); +INSERT INTO "public"."dict_data" ("dict_label", "dict_value", "dict_type") +VALUES ('EPSG:3857', '2', 'space_type'); +INSERT INTO "public"."dict_data" ("dict_label", "dict_value", "dict_type") +VALUES ('EPSG:900913', '3', 'space_type'); +INSERT INTO "public"."dict_data" ("dict_label", "dict_value", "dict_type") +VALUES ('矢量', '1', 'sever_type'); +INSERT INTO "public"."dict_data" ("dict_label", "dict_value", "dict_type") +VALUES ('栅格', '2', 'sever_type'); +INSERT INTO "public"."dict_data" ("dict_label", "dict_value", "dict_type") +VALUES ('倾斜摄影', '3', 'sever_type'); +INSERT INTO "public"."dict_data" ("dict_label", "dict_value", "dict_type") +VALUES ('Cesium', '1', 'map_frame_type'); +INSERT INTO "public"."dict_data" ("dict_label", "dict_value", "dict_type") +VALUES ('Mapbox', '2', 'map_frame_type'); +INSERT INTO "public"."dict_data" ("dict_label", "dict_value", "dict_type") +VALUES ('Mars3d', '3', 'map_frame_type'); + + +-- 项目组 +DROP SEQUENCE IF EXISTS "public"."project_data_relation_seq"; +CREATE SEQUENCE "public"."project_data_relation_seq" + INCREMENT 1 + MINVALUE 1 + MAXVALUE 99999999 + START 1 + CACHE 1; +DROP TABLE IF EXISTS "public"."project_data_relation"; +CREATE TABLE "public"."project_data_relation" +( + "project_team_name" varchar(64) COLLATE "pg_catalog"."default", + "application_id" int4, + "server_store_id" varchar(32) COLLATE "pg_catalog"."default", + "id" numeric(11, 0) NOT NULL DEFAULT nextval('project_data_relation_seq'::regclass), + "server_name" varchar(255) COLLATE "pg_catalog"."default", + CONSTRAINT "project_data_relation_pkey" PRIMARY KEY ("id") +) +; + +ALTER TABLE "public"."project_data_relation" + OWNER TO "postgres"; + +COMMENT ON COLUMN "public"."project_data_relation"."project_team_name" IS '项目组名称'; + +COMMENT ON COLUMN "public"."project_data_relation"."application_id" IS 'application_name_id'; + +COMMENT ON COLUMN "public"."project_data_relation"."server_store_id" IS '服务id'; + +COMMENT ON COLUMN "public"."project_data_relation"."id" IS '项目组id'; + +COMMENT ON COLUMN "public"."project_data_relation"."server_name" IS '图层服务名称'; + +-- 文件上传 +DROP SEQUENCE IF EXISTS "public"."style_image_seq"; +CREATE SEQUENCE "public"."style_image_seq" + INCREMENT 1 + MINVALUE 1 + MAXVALUE 99999999 + START 1 + CACHE 1; +DROP TABLE IF EXISTS "public"."style_image"; +CREATE TABLE "public"."style_image" +( + "id" numeric(11, 0) NOT NULL DEFAULT nextval('style_image_seq'::regclass), + "org_name" varchar(1000) COLLATE "pg_catalog"."default", + "server_local_name" varchar(100) COLLATE "pg_catalog"."default", + "server_local_path" varchar(1000) COLLATE "pg_catalog"."default", + "network_path" varchar(1000) COLLATE "pg_catalog"."default", + "md5_value" varchar(120) COLLATE "pg_catalog"."default", + "file_size" numeric(20, 0), + "file_type" varchar(100) COLLATE "pg_catalog"."default", + "upload_device" varchar(1000) COLLATE "pg_catalog"."default", + "upload_ip" varchar(100) COLLATE "pg_catalog"."default", + "upload_count" numeric(11, 0), + "create_by" varchar(40) COLLATE "pg_catalog"."default", + "create_time" date +) +; + +ALTER TABLE "public"."style_image" + OWNER TO "postgres"; + +COMMENT ON COLUMN "public"."style_image"."id" IS '记录ID'; + +COMMENT ON COLUMN "public"."style_image"."org_name" IS '源文件名'; + +COMMENT ON COLUMN "public"."style_image"."server_local_name" IS '服务器生成的文件名'; + +COMMENT ON COLUMN "public"."style_image"."server_local_path" IS '服务器储存路径'; + +COMMENT ON COLUMN "public"."style_image"."network_path" IS '网络路径,生成的文件夹+系统生成文件名'; + +COMMENT ON COLUMN "public"."style_image"."md5_value" IS '文件MD5值'; + +COMMENT ON COLUMN "public"."style_image"."file_size" IS '文件大小'; + +COMMENT ON COLUMN "public"."style_image"."file_type" IS '文件类型'; + +COMMENT ON COLUMN "public"."style_image"."upload_device" IS '设备信息'; + +COMMENT ON COLUMN "public"."style_image"."upload_ip" IS '上传设备IP'; + +COMMENT ON COLUMN "public"."style_image"."upload_count" IS '上传统计'; + +COMMENT ON COLUMN "public"."style_image"."create_by" IS '上传人员'; + +COMMENT ON COLUMN "public"."style_image"."create_time" IS '上传日期'; + +-- mapbox字典 +DROP TABLE IF EXISTS "public"."style_parameter_mapbox"; +CREATE TABLE "public"."style_parameter_mapbox" +( + "symbol" text COLLATE "pg_catalog"."default" NOT NULL, + "line" text COLLATE "pg_catalog"."default" NOT NULL, + "fill" text COLLATE "pg_catalog"."default" NOT NULL +) +; + +ALTER TABLE "public"."style_parameter_mapbox" + OWNER TO "postgres"; + +COMMENT ON COLUMN "public"."style_parameter_mapbox"."symbol" IS '点属性'; + +COMMENT ON COLUMN "public"."style_parameter_mapbox"."line" IS '线属性'; + +COMMENT ON COLUMN "public"."style_parameter_mapbox"."fill" IS '面 多面属性'; +INSERT INTO "public"."style_parameter_mapbox" +VALUES ('{ + "id": "symbol-id", + "type": "symbol", + "metadata": { + "citms:name": "test" + }, + "source": "source-name", + "source-layer": "source-layer-name", + "minzoom": 0, + "maxzoom": 24, + "layout": { + "visibility": "visible", + "symbol-placement": "point", + "symbol-spacing": 250, + "symbol-avoid-edges": false, + "symbol-sort-key": 1, + "symbol-z-order": "auto", + "icon-image": "", + "icon-size": 1, + "icon-padding": 2, + "icon-offset": [0, 0], + "icon-anchor": "center", + "icon-allow-overlap": false, + "icon-ignore-placement": false, + "icon-optional": false, + "icon-text-fit": "none", + "icon-text-fit-padding": [0, 0, 0, 0], + "icon-keep-upright": false, + "icon-rotation-alignment": "auto", + "icon-pitch-alignment": "auto", + "text-rotation-alignment": "auto", + "text-pitch-alignment": "auto", + "text-field": "", + "text-font": ["Open Sans Regular", "Arial Unicode MS Regular"], + "text-size": 16, + "text-max-width": 10, + "text-line-height": 1.2, + "text-letter-spacing": 0, + "text-justify": "center", + "text-anchor": "center", + "text-max-angle": 45, + "text-rotate": 0, + "text-padding": 2, + "text-keep-upright": false, + "text-transform": "none", + "text-offset": [0, 0], + "text-radial-offset": 0, + "text-allow-overlap": false, + "text-ignore-placement": false, + "text-optional": false + }, + "paint": { + "icon-opacity": 1, + "icon-color": "#000000", + "icon-halo-color": "rgba(0,0,0,0)", + "icon-halo-width": 0, + "icon-halo-blur": 0, + "icon-translate": [0, 0], + "icon-translate-anchor": "map", + "text-opacity": 1, + "text-color": "#000000", + "text-halo-color": "rgba(0,0,0,0)", + "text-halo-width": 0, + "text-halo-blur": 0, + "text-translate": [0, 0], + "text-translate-anchor": "map" + } +}', '{ + "id": "line-id", + "type": "line", + "metadata": { + "citms:name": "test" + }, + "source": "source-name", + "source-layer": "source-layer-name", + "minzoom": 0, + "maxzoom": 24, + "layout": { + "visibility": "visible", + "line-cap": "butt", + "line-join": "miter", + "line-miter-limit": 2, + "line-round-limit": 1.05 + }, + "paint": { + "line-opacity": 1, + "line-pattern": "", + "line-color": "#000000", + "line-translate": [0, 0], + "line-translate-anchor": "map", + "line-width": 1, + "line-gap-width": 0, + "line-offset": 0, + "line-blur": 0 + } +}', '{ + "id": "fill-id", + "type": "fill", + "metadata": { + "citms:name": "test" + }, + "source": "source-name", + "source-layer": "source-layer-name", + "minzoom": 0, + "maxzoom": 24, + "layout": { + "visibility": "visible" + }, + "paint": { + "fill-antialias": true, + "fill-opacity": 1, + "fill-pattern": "", + "fill-color": "#000000", + "fill-outline-color": "#000000", + "fill-translate": [0, 0], + "fill-translate-anchor": "map" + } +}'); + + +-- 服务样式url数据 +DROP TABLE IF EXISTS "public"."style_server_mapbox"; +CREATE TABLE "public"."style_server_mapbox" +( + "symbol" text COLLATE "pg_catalog"."default", + "line" text COLLATE "pg_catalog"."default", + "fill" text COLLATE "pg_catalog"."default", + "server_name" varchar(256) COLLATE "pg_catalog"."default" NOT NULL, + "img_url" varchar(256) COLLATE "pg_catalog"."default", + "x" varchar(256) COLLATE "pg_catalog"."default", + "y" varchar(256) COLLATE "pg_catalog"."default", + CONSTRAINT "server_name_unique" UNIQUE ("server_name") +) +; + +ALTER TABLE "public"."style_server_mapbox" + OWNER TO "postgres"; + +COMMENT ON COLUMN "public"."style_server_mapbox"."symbol" IS '点属性'; + +COMMENT ON COLUMN "public"."style_server_mapbox"."line" IS '线属性'; + +COMMENT ON COLUMN "public"."style_server_mapbox"."fill" IS '面 多面属性'; + +COMMENT ON COLUMN "public"."style_server_mapbox"."server_name" IS '图层服务id'; + +COMMENT ON COLUMN "public"."style_server_mapbox"."img_url" IS '图标url'; + +COMMENT ON COLUMN "public"."style_server_mapbox"."x" IS 'x位移数据'; + +COMMENT ON COLUMN "public"."style_server_mapbox"."y" IS 'y位移数据'; + +COMMENT ON CONSTRAINT "server_name_unique" ON "public"."style_server_mapbox" IS '唯一键'; + +-- 单文件上传 +DROP TABLE IF EXISTS "public"."sys_file_record"; +CREATE TABLE "public"."sys_file_record" +( + "id" varchar(40) COLLATE "pg_catalog"."default" NOT NULL, + "org_name" varchar(1000) COLLATE "pg_catalog"."default", + "server_local_name" varchar(100) COLLATE "pg_catalog"."default", + "server_local_path" varchar(1000) COLLATE "pg_catalog"."default", + "network_path" varchar(1000) COLLATE "pg_catalog"."default", + "upload_type" numeric(5, 0), + "md5_value" varchar(120) COLLATE "pg_catalog"."default", + "file_size" numeric(20, 0), + "is_merge" numeric(5, 0), + "is_zone" numeric(11, 0), + "zone_total" numeric(11, 0), + "zone_date" date, + "zone_merge_date" date, + "file_type" varchar(100) COLLATE "pg_catalog"."default", + "upload_device" varchar(1000) COLLATE "pg_catalog"."default", + "upload_ip" varchar(100) COLLATE "pg_catalog"."default", + "upload_count" numeric(11, 0), + "download_count" numeric(11, 0), + "storage_date" date, + "create_by" varchar(40) COLLATE "pg_catalog"."default", + "create_time" date, + "del_flag" numeric(5, 0) +) +; +COMMENT ON COLUMN "public"."sys_file_record"."id" IS '记录ID'; +COMMENT ON COLUMN "public"."sys_file_record"."org_name" IS '源文件名'; +COMMENT ON COLUMN "public"."sys_file_record"."server_local_name" IS '服务器生成的文件名'; +COMMENT ON COLUMN "public"."sys_file_record"."server_local_path" IS '服务器储存路径'; +COMMENT ON COLUMN "public"."sys_file_record"."network_path" IS '网络路径,生成的文件夹+系统生成文件名'; +COMMENT ON COLUMN "public"."sys_file_record"."upload_type" IS '上传类型'; +COMMENT ON COLUMN "public"."sys_file_record"."md5_value" IS '文件MD5值'; +COMMENT ON COLUMN "public"."sys_file_record"."file_size" IS '文件大小'; +COMMENT ON COLUMN "public"."sys_file_record"."is_merge" IS '是否合并'; +COMMENT ON COLUMN "public"."sys_file_record"."is_zone" IS '是否分片 0 否 1是'; +COMMENT ON COLUMN "public"."sys_file_record"."zone_total" IS '分片总数'; +COMMENT ON COLUMN "public"."sys_file_record"."zone_date" IS '分片时间'; +COMMENT ON COLUMN "public"."sys_file_record"."zone_merge_date" IS '分片合并时间'; +COMMENT ON COLUMN "public"."sys_file_record"."file_type" IS '文件类型'; +COMMENT ON COLUMN "public"."sys_file_record"."upload_device" IS '设备信息'; +COMMENT ON COLUMN "public"."sys_file_record"."upload_ip" IS '上传设备IP'; +COMMENT ON COLUMN "public"."sys_file_record"."upload_count" IS '上传统计'; +COMMENT ON COLUMN "public"."sys_file_record"."download_count" IS '下载统计'; +COMMENT ON COLUMN "public"."sys_file_record"."storage_date" IS '储存日期'; +COMMENT ON COLUMN "public"."sys_file_record"."create_by" IS '上传人员'; +COMMENT ON COLUMN "public"."sys_file_record"."create_time" IS '上传日期'; +COMMENT ON COLUMN "public"."sys_file_record"."del_flag" IS '删除标记 1正常 -1删除'; + +-- ---------------------------- +-- Table structure for sys_file_zone_record +-- ---------------------------- +-- 大文件上传 +DROP TABLE IF EXISTS "public"."sys_file_zone_record"; +CREATE TABLE "public"."sys_file_zone_record" +( + "id" varchar(40) COLLATE "pg_catalog"."default" NOT NULL, + "zone_name" varchar(100) COLLATE "pg_catalog"."default", + "zone_path" varchar(1000) COLLATE "pg_catalog"."default", + "zone_md5" varchar(100) COLLATE "pg_catalog"."default", + "zone_record_date" date, + "zone_check_date" date, + "zone_total_count" numeric(11, 0), + "zone_total_size" numeric(11, 0), + "zone_start_size" numeric(11, 0), + "zone_end_size" numeric(11, 0), + "zone_total_md5" varchar(100) COLLATE "pg_catalog"."default", + "zone_now_index" numeric(11, 0), + "zone_suffix" varchar(100) COLLATE "pg_catalog"."default", + "file_record_id" varchar(40) COLLATE "pg_catalog"."default" +) +; +COMMENT ON COLUMN "public"."sys_file_zone_record"."id" IS '分片ID'; +COMMENT ON COLUMN "public"."sys_file_zone_record"."zone_name" IS '分片名称'; +COMMENT ON COLUMN "public"."sys_file_zone_record"."zone_path" IS '分片的文件路径'; +COMMENT ON COLUMN "public"."sys_file_zone_record"."zone_md5" IS '分片MD5'; +COMMENT ON COLUMN "public"."sys_file_zone_record"."zone_record_date" IS '分片记录MD5值'; +COMMENT ON COLUMN "public"."sys_file_zone_record"."zone_check_date" IS '上传完成校验日期'; +COMMENT ON COLUMN "public"."sys_file_zone_record"."zone_total_count" IS '总的分片数'; +COMMENT ON COLUMN "public"."sys_file_zone_record"."zone_total_size" IS '总的文件大小'; +COMMENT ON COLUMN "public"."sys_file_zone_record"."zone_start_size" IS '分片起始位置'; +COMMENT ON COLUMN "public"."sys_file_zone_record"."zone_end_size" IS '分片结束位置'; +COMMENT ON COLUMN "public"."sys_file_zone_record"."zone_total_md5" IS '总文件的MD5值'; +COMMENT ON COLUMN "public"."sys_file_zone_record"."zone_now_index" IS '当前分片索引'; +COMMENT ON COLUMN "public"."sys_file_zone_record"."zone_suffix" IS '分片文件后缀'; +COMMENT ON COLUMN "public"."sys_file_zone_record"."file_record_id" IS '文件记录ID'; + +-- ---------------------------- +-- Primary Key structure for table sys_file_record +-- ---------------------------- +ALTER TABLE "public"."sys_file_record" + ADD CONSTRAINT "sys_file_record_pkey" PRIMARY KEY ("id"); + +-- ---------------------------- +-- Primary Key structure for table sys_file_zone_record +-- ---------------------------- +ALTER TABLE "public"."sys_file_zone_record" + ADD CONSTRAINT "sys_file_zone_record_pkey" PRIMARY KEY ("id"); + + + diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..bee8eb0 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,86 @@ + + + yshop + + + + + + + + + + ${log.pattern} + ${log.charset} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/mapper/ApplicationDataMapper.xml b/src/main/resources/mapper/ApplicationDataMapper.xml new file mode 100644 index 0000000..2c10a64 --- /dev/null +++ b/src/main/resources/mapper/ApplicationDataMapper.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + insert into application_data + + application_name, + space_type, + map_frame, + underlay + + + #{applicationName}, + #{spaceType}, + #{mapFrame}, + #{underlay} + + + + + + diff --git a/src/main/resources/mapper/DataStoreMapper.xml b/src/main/resources/mapper/DataStoreMapper.xml new file mode 100644 index 0000000..ec9ee52 --- /dev/null +++ b/src/main/resources/mapper/DataStoreMapper.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + select id, sever_name, space_type, sever_type, store_type, datasource_type, create_time, table_ref, is_display,data_type,style_name,name_ref,area_name,relation from data_store + + + + + + + + insert into data_store + + id, + sever_name, + space_type, + sever_type, + store_type, + datasource_type, + create_time, + table_ref, + is_display, + data_type, + style_name, + name_ref, + area_name, + relation, + + + #{id}, + #{severName}, + #{spaceType}, + #{severType}, + #{storeType}, + #{datasourceType}, + #{createTime}, + #{tableRef}, + #{isDisplay}, + #{dataType}, + #{styleName}, + #{nameRef}, + #{areaName}, + #{relation}, + + + + + update data_store + + sever_name = #{severName}, + space_type = #{spaceType}, + sever_type = #{severType}, + store_type = #{storeType}, + datasource_type = #{datasourceType}, + create_time = #{createTime}, + table_ref = #{tableRef}, + is_display = #{isDisplay}, + data_type = #{dataType}, + style_name = #{styleName}, + + where id = #{id} + + + + delete from data_store where id = #{id} + + + + delete from data_store where sever_name = #{name} + + + + + + + + delete from data_store where id in + + #{id} + + + + + + diff --git a/src/main/resources/mapper/DictDataMapper.xml b/src/main/resources/mapper/DictDataMapper.xml new file mode 100644 index 0000000..62f37eb --- /dev/null +++ b/src/main/resources/mapper/DictDataMapper.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/main/resources/mapper/ProjectDataRelationMapper.xml b/src/main/resources/mapper/ProjectDataRelationMapper.xml new file mode 100644 index 0000000..d30b5c9 --- /dev/null +++ b/src/main/resources/mapper/ProjectDataRelationMapper.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + update project_data_relation + + project_team_name = #{projectTeamName}, + application_id = #{applicationId}, + server_store_id = #{serverStoreId}, + server_name = #{serverName} + + where application_id = #{applicationId} + and project_team_name = #{projectTeamName} + + diff --git a/src/main/resources/mapper/ProjectDataRelationMarsMapper.xml b/src/main/resources/mapper/ProjectDataRelationMarsMapper.xml new file mode 100644 index 0000000..9db1a55 --- /dev/null +++ b/src/main/resources/mapper/ProjectDataRelationMarsMapper.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + insert into project_data_relation_mars + + project_team_name, + server_store_id, + server_name, + attribute, + p_attribute, + properties, + area_name, + sort + + + #{projectTeamName}, + #{serverStoreId}, + #{serverName}, + #{attribute}, + #{pAttribute}, + #{properties}, + #{areaName}, + #{sort} + + + + + diff --git a/src/main/resources/mapper/StyleImageMapper.xml b/src/main/resources/mapper/StyleImageMapper.xml new file mode 100644 index 0000000..bc08eec --- /dev/null +++ b/src/main/resources/mapper/StyleImageMapper.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/resources/mapper/StyleParameterMapboxMapper.xml b/src/main/resources/mapper/StyleParameterMapboxMapper.xml new file mode 100644 index 0000000..c0091ca --- /dev/null +++ b/src/main/resources/mapper/StyleParameterMapboxMapper.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/main/resources/mapper/StyleParameterMarsMapper.xml b/src/main/resources/mapper/StyleParameterMarsMapper.xml new file mode 100644 index 0000000..f8119b2 --- /dev/null +++ b/src/main/resources/mapper/StyleParameterMarsMapper.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/main/resources/mapper/StyleRecordMapper.xml b/src/main/resources/mapper/StyleRecordMapper.xml new file mode 100644 index 0000000..cd7f897 --- /dev/null +++ b/src/main/resources/mapper/StyleRecordMapper.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + select style_name, type, fill_color, fill_opacity, stroke_color, stroke_width from style_record + + + + + + + + insert into style_record + + style_name, + type, + fill_color, + fill_opacity, + stroke_color, + stroke_width, + + + #{styleName}, + #{type}, + #{fillColor}, + #{fillOpacity}, + #{strokeColor}, + #{strokeWidth}, + + + + + update style_record + + type = #{type}, + fill_color = #{fillColor}, + fill_opacity = #{fillOpacity}, + stroke_color = #{strokeColor}, + stroke_width = #{strokeWidth}, + + where style_name = #{styleName} + + + + delete from style_record where style_name = #{styleName} + + + + delete from style_record where style_name in + + #{styleName} + + + diff --git a/src/main/resources/mapper/StyleServerMapboxMapper.xml b/src/main/resources/mapper/StyleServerMapboxMapper.xml new file mode 100644 index 0000000..ca310ef --- /dev/null +++ b/src/main/resources/mapper/StyleServerMapboxMapper.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/main/resources/mapper/TUserMapper.xml b/src/main/resources/mapper/TUserMapper.xml new file mode 100644 index 0000000..cd9a191 --- /dev/null +++ b/src/main/resources/mapper/TUserMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + select id,username,password,salt,state from t_user + + + \ No newline at end of file diff --git a/src/test/java/com/zzlh/es/EsApplicationTests.java b/src/test/java/com/zzlh/es/EsApplicationTests.java new file mode 100644 index 0000000..fc4c573 --- /dev/null +++ b/src/test/java/com/zzlh/es/EsApplicationTests.java @@ -0,0 +1,56 @@ +package com.zzlh.es; + +import com.zzlh.es.service.GeoServer; +import com.zzlh.es.service.LayerService; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.jdbc.core.JdbcTemplate; + +import java.util.List; +import java.util.Map; + +import static com.zzlh.es.service.GeoWebCache.getLayers; + +@SpringBootTest +@Slf4j +class EsApplicationTests { + + @Autowired + private JdbcTemplate jdbcTemplate; + + @Autowired + private RedisTemplate redisTemplate; + + @Autowired + private LayerService layerService; + + @Autowired + private GeoServer geoServer; + @Test + void contextLoads() throws Exception{ + String layerName = "shp_1680595576"; + //Map> layers = getLayers("ksp:shp_1680592377"); + redisTemplate.opsForValue().set("a",100); + Object a = redisTemplate.opsForValue().get("a"); + System.out.println(a.toString()); +// Long aLong = jdbcTemplate.queryForObject("select count(*) from test_table", Long.class); +// System.out.println(aLong); + //layerService.addLayer("E:\\Program Files (x86)\\DingDing\\shp"); + // geoServer.addLayer(null,null,layerName,null); + //geoServer.releaseShpByHttp("E:\\Program Files (x86)\\DingDing\\DTalkFIle\\shp\\abc.zip","EPSG:4326"); + + } + + public static void main(String[] args) { + // todo 关于map为什么取不到数据 + Map map = new java.util.HashMap<>(); + map.put("a","1"); + + map.put("tableName","shp_1762498721"); + String tableName = map.get("tableName"); + System.out.println(tableName); + } +}