Commit cd12f3da authored by 申凯华's avatar 申凯华

老系统同步

parents
Pipeline #1427 failed with stages
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### 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/
### VS Code ###
.vscode/
/*
* 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();
}
}
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
#wemeshop
nohup java -jar -server -Xmx512M -Xms512M -Xmn256M -XX:MaxMetaspaceSize=256M -XX:MetaspaceSize=256M cnooc.jar > nohup.out &
nohup java -jar cnooc.jar >temp.txt 2>&1 &
\ No newline at end of file
This diff is collapsed.
@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%
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.shop</groupId>
<artifactId>cnooc</artifactId>
<packaging>jar</packaging>
<version>1.0.0-SNAPSHOT</version>
<name>cnooc</name>
<description>维密商城</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mybatisplus.version>3.4.2</mybatisplus.version>
<pagehelper-spring-boot-starter.version>1.2.13</pagehelper-spring-boot-starter.version>
<shiro.version>1.5.0</shiro.version>
<commons-beanutils.version>1.9.3</commons-beanutils.version>
<commons-collections4.version>4.1</commons-collections4.version>
<commons-lang3.version>3.7</commons-lang3.version>
<commons-io.version>2.6</commons-io.version>
<commons-codec.version>1.14</commons-codec.version>
<guava.version>28.2-jre</guava.version>
<druid.version>1.1.21</druid.version>
<fastjson.version>1.2.62</fastjson.version>
<swagger2.version>2.9.2</swagger2.version>
<caffeine.version>2.8.1</caffeine.version>
<dozer.starter.version>6.5.0</dozer.starter.version>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>8.4.1.jre8</version>
</dependency>
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>${caffeine.version}</version>
</dependency>
<!--pagehelper 分页插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper-spring-boot-starter.version}</version>
</dependency>
<!-- mybatis starter-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.4.1</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<!--commons 工具类-->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>${commons-beanutils.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!--swagger2-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger2.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger2.version}</version>
</dependency>
<!-- 以下两个解决 swagger空值报错 -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.22</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.22</version>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>com.github.dozermapper</groupId>
<artifactId>dozer-spring-boot-starter</artifactId>
<version>${dozer.starter.version}</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>dev</id>
<properties>
<profiles.activation>dev</profiles.activation>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>prod</id>
<properties>
<profiles.activation>prod</profiles.activation>
</properties>
</profile>
</profiles>
<build>
<finalName>cnooc</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
<fork>true</fork>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</repository>
</repositories>
</project>
#!/bin/bash
DEPLOY_DIR='/usr/local'
PROJECT='shop'
cd $DEPLOY_DIR
cd $DEPLOY_DIR
BACK_DIR=$DEPLOY_DIR/backup
if [ ! -d $BACK_DIR ]; then
mkdir $BACK_DIR
fi
MY_BACK_DIR=$BACK_DIR/$PROJECT
if [ ! -d $MY_BACK_DIR ]; then
mkdir $MY_BACK_DIR
fi
BACKUP_DATE=`date +%Y%m%d%H%M%S`
CURRENT_BACKUP_DIR=$MY_BACK_DIR/$BACKUP_DATE
if [ ! -d $CURRENT_BACKUP_DIR ]; then
mkdir $CURRENT_BACKUP_DIR
fi
#echo "backup $PROJECT ($BACKUP_DATE) ...\c"
#mv $PROJECT.jar backup/$PROJECT/$BACKUP_DATE/
#cp /root/.jenkins/jobs/shop-service/workspace/default/target/shop.jar /usr/local
#
#echo "restart $PROJECT ...\c"
#$DEPLOY_DIR/bin/$PROJECT/stop.sh skip
#$DEPLOY_DIR/bin/$PROJECT/start.sh
#!/bin/bash
source ~/.bashrc
DEPLOY_DIR='/usr/local/'
SERVER_NAME='shop'
PIDS=`ps -f | grep java | grep "$CONF_DIR" |awk '{print $2}'`
if [ -z "$PIDS" ]; then
echo "ERROR: The $SERVER_NAME does not started!"
exit 1
fi
DUMP_DIR=$DEPLOY_DIR/dump
if [ ! -d $DUMP_DIR ]; then
mkdir $DUMP_DIR
fi
DUMP_DATE=`date +%Y%m%d%H%M%S`
DATE_DIR=$DUMP_DIR/$DUMP_DATE
if [ ! -d $DATE_DIR ]; then
mkdir $DATE_DIR
fi
echo -e "Dumping the $SERVER_NAME ...\c"
for PID in $PIDS ; do
jstack $PID > $DATE_DIR/jstack-$PID.dump 2>&1
echo -e ".\c"
jinfo $PID > $DATE_DIR/jinfo-$PID.dump 2>&1
echo -e ".\c"
jstat -gcutil $PID > $DATE_DIR/jstat-gcutil-$PID.dump 2>&1
echo -e ".\c"
jstat -gccapacity $PID > $DATE_DIR/jstat-gccapacity-$PID.dump 2>&1
echo -e ".\c"
jmap $PID > $DATE_DIR/jmap-$PID.dump 2>&1
echo -e ".\c"
jmap -heap $PID > $DATE_DIR/jmap-heap-$PID.dump 2>&1
echo -e ".\c"
jmap -histo $PID > $DATE_DIR/jmap-histo-$PID.dump 2>&1
echo -e ".\c"
if [ -r /usr/sbin/lsof ]; then
/usr/sbin/lsof -p $PID > $DATE_DIR/lsof-$PID.dump
echo -e ".\c"
fi
done
if [ -r /bin/netstat ]; then
/bin/netstat -an > $DATE_DIR/netstat.dump 2>&1
echo -e ".\c"
fi
if [ -r /usr/bin/iostat ]; then
/usr/bin/iostat > $DATE_DIR/iostat.dump 2>&1
echo -e ".\c"
fi
if [ -r /usr/bin/mpstat ]; then
/usr/bin/mpstat > $DATE_DIR/mpstat.dump 2>&1
echo -e ".\c"
fi
if [ -r /usr/bin/vmstat ]; then
/usr/bin/vmstat > $DATE_DIR/vmstat.dump 2>&1
echo -e ".\c"
fi
if [ -r /usr/bin/free ]; then
/usr/bin/free -t > $DATE_DIR/free.dump 2>&1
echo -e ".\c"
fi
if [ -r /usr/bin/sar ]; then
/usr/bin/sar > $DATE_DIR/sar.dump 2>&1
echo -e ".\c"
fi
if [ -r /usr/bin/uptime ]; then
/usr/bin/uptime > $DATE_DIR/uptime.dump 2>&1
echo -e ".\c"
fi
echo "OK!"
echo "DUMP: $DATE_DIR"
#!/bin/bash
cd `dirname $0`
./stop.sh $1
./start.sh $1
#!/bin/bash
cd `dirname $0`
if [ "$1" = "start" ]; then
./start.sh
else
if [ "$1" = "stop" ]; then
./stop.sh $2
else
if [ "$1" = "debug" ]; then
./start.sh debug
else
if [ "$1" = "restart" ]; then
./restart.sh $2
else
if [ "$1" = "dump" ]; then
./dump.sh
else
echo "ERROR: Please input argument: start or stop or debug or restart or dump"
exit 1
fi
fi
fi
fi
fi
#!/bin/bash
source ~/.bashrc
DEPLOY_DIR='/usr/local/'
SERVER_NAME='shop'
JAVA_HOME='/usr/env/jdk1.8.0_221'
PIDS=`ps -f | grep java | grep "$SERVER_NAME" |awk '{print $2}'`
if [ -n "$PIDS" ]; then
echo "ERROR: The $SERVER_NAME already started!"
echo "PID: $PIDS"
exit 1
fi
JAVA_OPTS=" -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true "
JAVA_DEBUG_OPTS=""
if [ "$1" = "debug" ]; then
JAVA_DEBUG_OPTS=" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n "
fi
JAVA_JMX_OPTS=""
if [ "$1" = "jmx" ]; then
JAVA_JMX_OPTS=" -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false "
fi
JAVA_MEM_OPTS=""
BITS=`java -version 2>&1 | grep -i 64-bit`
JAVA_MEM_OPTS=" -server -Xmx2048M -Xms2048M -Xmn768M -XX:MaxMetaspaceSize=256M -XX:MetaspaceSize=256M -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses -XX:+CMSClassUnloadingEnabled -XX:+ParallelRefProcEnabled -XX:+CMSScavengeBeforeRemark -XX:+UseFastAccessorMethods -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/var/log/$SERVER_NAME/gc.log"
echo -e "Starting the $SERVER_NAME ...\c"
nohup $JAVA_HOME/bin/java -jar $JAVA_OPTS $JAVA_MEM_OPTS $JAVA_DEBUG_OPTS $JAVA_JMX_OPTS $DEPLOY_DIR$SERVER_NAME.jar > nohup.out &
echo "OK!"
PIDS=`ps -f | grep java | grep "$SERVER_NAME" | awk '{print $2}'`
echo "PID: $PIDS"
#!/bin/bash
source ~/.bashrc
DEPLOY_DIR='/usr/local/'
SERVER_NAME='shop'
PIDS=`ps -ef | grep java | grep "$SERVER_NAME" |awk '{print $2}'`
if [ -z "$PIDS" ]; then
echo "ERROR: The $SERVER_NAME does not started!"
exit 1
fi
if [ "$1" != "skip" ]; then
$DEPLOY_DIR/bin/$SERVER_NAME/dump.sh
fi
echo -e "Stopping the $SERVER_NAME ...\c"
for PID in $PIDS ; do
kill $PID > /dev/null 2>&1
done
COUNT=0
while [ $COUNT -lt 120 ]; do
((COUNT++))
for PID in $PIDS ; do
echo -e ".\c"
PID_EXIST=`ps -ef | grep $PID | grep java |awk '{print $2}'`
if [ -z "$PID_EXIST" ]; then
COUNT=120
break
fi
sleep 1
done
done
echo "OK!"
echo "PID: $PIDS"
package com.zmkm.shop;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import javax.annotation.PostConstruct;
import java.util.TimeZone;
@SpringBootApplication
@EnableScheduling
@MapperScan({"com.zmkm.shop.modules.test.mapper"})
public class ShopApplication {
@PostConstruct
void started() {
//时区设置:中国上海
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
}
public static void main(String[] args) {
SpringApplication.run(ShopApplication.class, args);
}
}
package com.zmkm.shop.base.controller;
import com.zmkm.shop.constant.ResultCodeEnum;
import com.zmkm.shop.base.result.BaseResult;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @description:基础 controller
*/
@ControllerAdvice
public abstract class BaseController {
private static Logger logger = LoggerFactory.getLogger(BaseController.class);
@InitBinder
public void initBinder(ServletRequestDataBinder binder) {
}
@ExceptionHandler({ Exception.class })
@ResponseBody
public BaseResult<Object> exception(Exception e) {
logger.error("", e);
BaseResult<Object> result = new BaseResult<Object>();
result.setCode(ResultCodeEnum.HTTP_ERROR.getCode());
result.setMsg(e.getMessage());
return result;
}
// @ExceptionHandler({
// UnknownAccountException.class, IncorrectCredentialsException.class
// })
// @ResponseStatus(HttpStatus.UNAUTHORIZED)
// public BaseResult loginException(Exception exception) {
// return new BaseResult(HttpStatus.UNAUTHORIZED.value(),exception.getMessage());
// }
@ExceptionHandler({
UnauthorizedException.class
})
@ResponseBody
public BaseResult unauthorizedException(Exception exception) {
BaseResult<Object> result = new BaseResult<Object>();
result.setCode(ResultCodeEnum.HTTP_ERROR.getCode());
result.setMsg(ResultCodeEnum.HTTP_USER_UNAUTHORIZED.getMsg());
return result;
}
}
package com.zmkm.shop.base.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/**
* 自动注入操作用户,名称以及时间
* 字段:operator,operator_name,create_time,update_time
* @author sonny
*
*/
@Getter
@Setter
public abstract class BaseUserNameTime implements Serializable {
@TableField(value = "operator",fill = FieldFill.INSERT_UPDATE)
private Long operator;
@TableField(value = "operator_name",fill = FieldFill.INSERT_UPDATE)
private String operatorName;//操作用户名
@TableField(value = "create_time",fill = FieldFill.INSERT)
private Long createTime;//创建时间
@TableField(value = "update_time",fill = FieldFill.UPDATE)
private Long updateTime;//操作时间
}
package com.zmkm.shop.base.mapper;
public interface SuperMapper<T> extends com.baomidou.mybatisplus.core.mapper.BaseMapper<T> {
}
package com.zmkm.shop.base.page;
import com.github.pagehelper.Page;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* 对Page<E>结果进行包装
* <p/>
* 新增分页的多项属性,主要参考:http://bbs.csdn.net/topics/360010907
*
* @author liuzh/abel533/isea533
* @version 3.3.0
* @since 3.2.2
* 项目地址 : http://git.oschina.net/free/Mybatis_PageHelper
*/
@SuppressWarnings({"rawtypes"})
public class BasePage<T> implements Serializable {
private static final long serialVersionUID = 1L;
//当前页
private int pageNum;
//每页的数量
private int pageSize;
//当前页的数量
private int size;
//总记录数
private long total;
//总页数
private int pages;
//结果集
private List<T> list;
//前一页
private int prePage;
//下一页
private int nextPage;
//是否为第一页
private boolean isFirstPage = false;
//是否为最后一页
private boolean isLastPage = false;
//是否有前一页
private boolean hasPreviousPage = false;
//是否有下一页
private boolean hasNextPage = false;
public BasePage() {
}
public BasePage(org.springframework.data.domain.Page<T> page){
this.pageNum = page.getNumber()+1;
this.pageSize = page.getSize();
this.pages = page.getTotalPages();
this.list = new ArrayList<T>(page.getContent());
this.size = page.getNumberOfElements();
this.total = page.getTotalElements();
//计算前后页,第一页,最后一页
calcPage();
//判断页面边界
judgePageBoudary();
}
/**
* 包装Page对象
*
* @param list page结果
* @param navigatePages 页码数量
*/
public BasePage(List<T> list) {
if (list instanceof Page) {
Page page = (Page) list;
this.pageNum = page.getPageNum();
this.pageSize = page.getPageSize();
this.pages = page.getPages();
this.list = new ArrayList<T>(list);
this.size = page.size();
this.total = page.getTotal();
} else if (list instanceof Collection) {
this.pageNum = 1;
this.pageSize = list.size();
this.pages = this.pageSize > 0 ? 1 : 0;
this.list = list;
this.size = list.size();
this.total = list.size();
}
if (list instanceof Collection) {
//计算前后页,第一页,最后一页
calcPage();
//判断页面边界
judgePageBoudary();
}
}
/**
* 计算前后页,第一页,最后一页
*/
public void calcPage() {
if (pageNum > 1) {
prePage = pageNum - 1;
}
if (pageNum < pages) {
nextPage = pageNum + 1;
}
}
/**
* 判定页面边界
*/
public void judgePageBoudary() {
isFirstPage = pageNum == 1;
isLastPage = pageNum == pages || pages == 0;;
hasPreviousPage = pageNum > 1;
hasNextPage = pageNum < pages;
}
public int getPageNum() {
return pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public long getTotal() {
return total;
}
public void setTotal(long total) {
this.total = total;
}
public int getPages() {
return pages;
}
public void setPages(int pages) {
this.pages = pages;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
public int getPrePage() {
return prePage;
}
public void setPrePage(int prePage) {
this.prePage = prePage;
}
public int getNextPage() {
return nextPage;
}
public void setNextPage(int nextPage) {
this.nextPage = nextPage;
}
public boolean isIsFirstPage() {
return isFirstPage;
}
public void setIsFirstPage(boolean isFirstPage) {
this.isFirstPage = isFirstPage;
}
public boolean isIsLastPage() {
return isLastPage;
}
public void setIsLastPage(boolean isLastPage) {
this.isLastPage = isLastPage;
}
public boolean isHasPreviousPage() {
return hasPreviousPage;
}
public void setHasPreviousPage(boolean hasPreviousPage) {
this.hasPreviousPage = hasPreviousPage;
}
public boolean isHasNextPage() {
return hasNextPage;
}
public void setHasNextPage(boolean hasNextPage) {
this.hasNextPage = hasNextPage;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("PageInfo{");
sb.append("pageNum=").append(pageNum);
sb.append(", pageSize=").append(pageSize);
sb.append(", size=").append(size);
sb.append(", total=").append(total);
sb.append(", pages=").append(pages);
sb.append(", list=").append(list);
sb.append(", prePage=").append(prePage);
sb.append(", nextPage=").append(nextPage);
sb.append(", isFirstPage=").append(isFirstPage);
sb.append(", isLastPage=").append(isLastPage);
sb.append(", hasPreviousPage=").append(hasPreviousPage);
sb.append(", hasNextPage=").append(hasNextPage);
sb.append(", navigatepageNums=");
sb.append('}');
return sb.toString();
}
}
package com.zmkm.shop.base.result;
import com.zmkm.shop.constant.ResultCodeEnum;
import java.io.Serializable;
/**
* 抽象的返回结果
*/
public class BaseResult<T> implements Serializable {
/**
*
*/
private static final long serialVersionUID = 7277594240016924327L;
/**
* 错误码
*/
private int code = ResultCodeEnum.HTTP_OK.getCode();
/**
* 错误信息
*/
private String msg = ResultCodeEnum.HTTP_OK.getMsg();
/**
* 返回的数据信息
*/
private T data;
public BaseResult(int code, String msg) {
super();
this.code = code;
this.msg = msg;
}
public BaseResult(ResultCodeEnum resultCode) {
super();
this.code = resultCode.getCode();
this.msg = resultCode.getMsg();
}
public BaseResult() {
super();
}
public BaseResult(boolean ret, int code) {
super();
this.code = code;
}
public int getCode() {
return code;
}
public BaseResult<T> setCode(int code) {
this.code = code;
return this;
}
public String getMsg() {
return msg;
}
public BaseResult<T> setMsg(String msg) {
this.msg = msg;
return this;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
\ No newline at end of file
package com.zmkm.shop.base.service;
import com.baomidou.mybatisplus.extension.service.IService;
public interface BaseService<T> extends IService<T> {
}
\ No newline at end of file
package com.zmkm.shop.base.service.impl;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zmkm.shop.base.service.BaseService;
@SuppressWarnings("unchecked")
public abstract class BaseServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M,T> implements BaseService<T> {}
package com.zmkm.shop.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
// @Override
// public void addCorsMappings(CorsRegistry registry) {
// registry.addMapping("/**");
// }
// @Override
// public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
// FastJsonConfig fastJsonConfig = new FastJsonConfig();
// fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty,
// SerializerFeature.WriteNullNumberAsZero, SerializerFeature.WriteNullBooleanAsFalse, SerializerFeature.DisableCircularReferenceDetect);
// fastJsonConfig.setSerializeFilters(new LongValueFilter());
// fastConverter.setFastJsonConfig(fastJsonConfig);
// converters.add(fastConverter);
// }
//
// public static class LongValueFilter implements ValueFilter {
// @Override
// public Object process(Object object, String propertyName, Object propertyValue) {
// if (null != propertyValue && propertyValue instanceof Long && propertyValue.toString().length() > 15) {
// return propertyValue.toString();
// }
// return propertyValue;
// }
// }
}
package com.zmkm.shop.config.dozer;
import com.github.dozermapper.spring.DozerBeanMapperFactoryBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import java.io.IOException;
@Configuration
public class DozerMapperConfig {
@Bean
public DozerBeanMapperFactoryBean dozerMapper(@Value("classpath:dozer/*.xml") Resource[] resources){
DozerBeanMapperFactoryBean dozerBeanMapperFactoryBean = new DozerBeanMapperFactoryBean();
try {
dozerBeanMapperFactoryBean.setMappingFiles(resources);
} catch (IOException e) {
e.printStackTrace();
}
return dozerBeanMapperFactoryBean;
}
}
package com.zmkm.shop.config.dozer;
import com.github.dozermapper.core.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
@Component
public class DozerMapperFactory {
@Autowired
private Mapper dozerMapper;
public <T, S> T convert(S s, Class<T> clz) {
return s == null ? null : dozerMapper.map(s, clz);
}
public <T, S> List<T> convert(List<S> s, Class<T> clz) {
return s == null ? null : s.stream().map(vs -> dozerMapper.map(vs, clz)).collect(Collectors.toList());
}
}
package com.zmkm.shop.config.mybatis;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.zmkm.shop.base.domain.BaseUserNameTime;
import org.apache.ibatis.reflection.MetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.Objects;
import java.util.function.Supplier;
@Component
public class AutoDataHandler implements MetaObjectHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(AutoDataHandler.class);
private static final String DEFAULT_CREATETIME_NAME = "createTime";
private static final String DEFAULT_UPDATETIME_NAME = "updateTime";
private static final String DEFAULT_OPERATOR_NAME = "operator";
private static final String DEFAULT_OPERATOR_NAME_NAME = "operatorName";
@Override
public void insertFill(MetaObject metaObject) {
LOGGER.info("start insert fill ....");
Long id=1L;
String loginName="admin1";
if (metaObject.getOriginalObject() instanceof BaseUserNameTime) {
this.strictInsertFill(metaObject,DEFAULT_OPERATOR_NAME,Long.class,id);
this.strictInsertFill(metaObject,DEFAULT_OPERATOR_NAME_NAME,String.class,loginName);
this.strictInsertFill(metaObject, DEFAULT_CREATETIME_NAME,Long.class, System.currentTimeMillis());
this.strictInsertFill(metaObject, DEFAULT_UPDATETIME_NAME,Long.class, System.currentTimeMillis());
}
}
@Override
public void updateFill(MetaObject metaObject) {
LOGGER.info("start update fill ....");
Long id=3L;
String loginName="admin3";
if (metaObject.getOriginalObject() instanceof BaseUserNameTime) {
this.strictUpdateFill(metaObject,DEFAULT_OPERATOR_NAME,Long.class,id);
this.strictUpdateFill(metaObject,DEFAULT_OPERATOR_NAME_NAME,String.class,loginName);
this.strictUpdateFill(metaObject, DEFAULT_CREATETIME_NAME,Long.class, System.currentTimeMillis());
this.strictUpdateFill(metaObject, DEFAULT_UPDATETIME_NAME,Long.class, System.currentTimeMillis());
}
}
@Override
public MetaObjectHandler strictFillStrategy(MetaObject metaObject, String fieldName, Supplier<?> fieldVal) {
Object obj = fieldVal.get();
if (Objects.nonNull(obj)) {
metaObject.setValue(fieldName, obj);
}
return this;
}
}
package com.zmkm.shop.config.shiro;
import com.zmkm.shop.config.shiro.cache.ShiroSpringCacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @author sonny
*
*/
@Configuration
@SuppressWarnings({ "rawtypes", "unchecked" })
public class CacheConfig {
@Bean
public CaffeineCacheManager getGuavaCacheManager() {
CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
caffeineCacheManager.setCacheSpecification("expireAfterAccess=30m");
return caffeineCacheManager;
}
@Bean
public ShiroSpringCacheManager getShiroSpringCacheManager(RedisTemplate redisTemplate, CaffeineCacheManager caffeineCacheManager) {
redisTemplate.setKeySerializer(new StringRedisSerializer());
ShiroSpringCacheManager shiroSpringCacheManager = new ShiroSpringCacheManager();
shiroSpringCacheManager.setCaffeineCacheManager(caffeineCacheManager);
shiroSpringCacheManager.setRedisTemplate(redisTemplate);
return shiroSpringCacheManager;
}
}
\ No newline at end of file
package com.zmkm.shop.config.shiro;
import com.zmkm.shop.config.shiro.session.ShiroSession;
import org.apache.shiro.cache.AbstractCacheManager;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.MapCache;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.CachingSessionDAO;
import java.io.Serializable;
import java.util.concurrent.ConcurrentHashMap;
public class CachingShiroSessionDao extends CachingSessionDAO {
public CachingShiroSessionDao() {
setCacheManager(new AbstractCacheManager() {
@Override
protected Cache<Serializable, Session> createCache(String name) throws CacheException {
return new MapCache<Serializable, Session>(name, new ConcurrentHashMap<Serializable, Session>());
}
});
}
@Override
public void update(Session session) throws UnknownSessionException {
if (session instanceof ShiroSession) {
// 如果没有主要字段(除lastAccessTime以外其他字段)发生改变
ShiroSession ss = (ShiroSession) session;
if (!ss.isChanged()) {
return;
}
}
super.update(session);
}
protected Serializable doCreate(Session session) {
Serializable sessionId = generateSessionId(session);
assignSessionId(session, sessionId);
return sessionId;
}
protected Session doReadSession(Serializable sessionId) {
return null; //should never execute because this implementation relies on parent class to access cache, which
//is where all sessions reside - it is the cache implementation that determines if the
//cache is memory only or disk-persistent, etc.
}
protected void doUpdate(Session session) {
//does nothing - parent class persists to cache.
}
protected void doDelete(Session session) {
//does nothing - parent class removes from cache.
}
}
package com.zmkm.shop.config.shiro;
import com.zmkm.shop.config.shiro.session.ShiroSessionFactory;
import com.zmkm.shop.filter.AllowOptionsFormAuthenticationFilter;
import com.zmkm.shop.filter.URLPermissionsFilter;
import com.zmkm.shop.utils.ShiroUtils;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
//@Configuration
public class ShiroConfig {
//
// @Bean
// public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
// ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// shiroFilterFactoryBean.setSecurityManager(securityManager);
// Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
// // for api docs
// filterChainDefinitionMap.put("/swagger-ui.html", "anon");
// filterChainDefinitionMap.put("/swagger-resources/**", "anon");
// filterChainDefinitionMap.put("/v2/api-docs", "anon");
// filterChainDefinitionMap.put("/webjars/springfox-swagger-ui/**", "anon");
// // for biz
// filterChainDefinitionMap.put("/test", "anon");
//// filterChainDefinitionMap.put("/**", "userFilter,urlFilter");
// shiroFilterFactoryBean.setLoginUrl("/loginUrl");
// shiroFilterFactoryBean.setSuccessUrl("");
// shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorizedUrl");
//
// Map<String, Filter> filterMap = new HashMap<>();
//// filterMap.put("urlFilter", new URLPermissionsFilter());
//// filterMap.put("userFilter", new AllowOptionsFormAuthenticationFilter());
// shiroFilterFactoryBean.setFilters(filterMap);
// shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
// return shiroFilterFactoryBean;
// }
//
// @Bean
// public SecurityManager securityManager(CacheManager cacheManager, DefaultWebSessionManager defaultWebSessionManager , ShiroDbRealm shiroDbRealm) {
// DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// securityManager.setCacheManager(cacheManager);
// securityManager.setRealm(shiroDbRealm);
// securityManager.setSessionManager(defaultWebSessionManager);
// return securityManager;
// }
//
// @Bean
// public DefaultWebSessionManager sessionManager(CachingShiroSessionDao cachingShiroSessionDao , SimpleCookie simpleCookie) {
// DefaultWebSessionManager manager = new ShiroSessionManager();
// manager.setSessionDAO(cachingShiroSessionDao);
// manager.setGlobalSessionTimeout(1000 * 60 * 60 * 24);
// manager.setSessionValidationSchedulerEnabled(false);
// manager.setSessionIdCookie(simpleCookie);
// manager.setSessionIdCookieEnabled(true);
// manager.setSessionIdUrlRewritingEnabled(false);
// manager.setSessionFactory(new ShiroSessionFactory());
// return manager;
// }
//
// @Bean
// public CachingShiroSessionDao sessionDao() {
// CachingShiroSessionDao sessionDao = new CachingShiroSessionDao();
// sessionDao.setActiveSessionsCacheName("pasc");
// return sessionDao;
// }
//
// @Bean
// public SimpleCookie sessionIdCookie() {
// SimpleCookie cookie = new SimpleCookie("com-zmkm-shop-token");
// cookie.setHttpOnly(false);
// cookie.setSameSite(null);
// return cookie;
// }
//
// @Bean
// public ShiroDbRealm ShiroRealm(HashedCredentialsMatcher hashedCredentialsMatcher) {
// ShiroDbRealm shiroDbRealm = new ShiroDbRealm();
// shiroDbRealm.setCredentialsMatcher(hashedCredentialsMatcher);
// shiroDbRealm.setAuthorizationCacheName("pacn");
// return shiroDbRealm;
// }
//
// @Bean
// public HashedCredentialsMatcher hashedCredentialsMatcher() {
// HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
// hashedCredentialsMatcher.setHashAlgorithmName(ShiroUtils.algorithmName);
// hashedCredentialsMatcher.setHashIterations(ShiroUtils.hashIterations);
// return hashedCredentialsMatcher;
// }
//
// @Bean
// public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
// return new LifecycleBeanPostProcessor();
// }
//
// @Bean
// @DependsOn({ "lifecycleBeanPostProcessor" })
// public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
// DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
// advisorAutoProxyCreator.setProxyTargetClass(true);
// return advisorAutoProxyCreator;
// }
//
// @Bean
// public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
// AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
// authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
// return authorizationAttributeSourceAdvisor;
// }
}
\ No newline at end of file
package com.zmkm.shop.config.shiro;
import com.zmkm.shop.utils.ShiroUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
public class ShiroDbRealm extends AuthorizingRealm {
@SuppressWarnings("unused")
private Logger logger = LoggerFactory.getLogger(ShiroDbRealm.class);
public ShiroDbRealm() {
}
public ShiroDbRealm(CacheManager cacheManager) {
super(cacheManager);
}
public ShiroDbRealm(CacheManager cacheManager, CredentialsMatcher matcher) {
super(cacheManager, matcher);
}
/**
* 身份认证
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
return null;
}
/**
* 权限认证
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
@Override
public void onLogout(PrincipalCollection principals) {
super.clearCachedAuthorizationInfo(principals);
}
@Override
public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();
shaCredentialsMatcher.setHashAlgorithmName(ShiroUtils.algorithmName);
shaCredentialsMatcher.setHashIterations(ShiroUtils.hashIterations);
super.setCredentialsMatcher(shaCredentialsMatcher);
}
}
package com.zmkm.shop.config.shiro;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.session.mgt.WebSessionKey;
import javax.servlet.ServletRequest;
import java.io.Serializable;
public class ShiroSessionManager extends DefaultWebSessionManager {
@Override
protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException {
Serializable sessionId = getSessionId(sessionKey);
ServletRequest request = null;
if (sessionKey instanceof WebSessionKey) {
request = ((WebSessionKey) sessionKey).getServletRequest();
}
if (request != null && null != sessionId) {
Object sessionObj = request.getAttribute(sessionId.toString());
if (sessionObj != null) {
return (Session) sessionObj;
}
}
Session session = super.retrieveSession(sessionKey);
if (request != null && null != sessionId) {
request.setAttribute(sessionId.toString(), session);
}
return session;
}
}
package com.zmkm.shop.config.shiro.cache;
import org.apache.shiro.cache.CacheException;
import org.springframework.cache.Cache.ValueWrapper;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@SuppressWarnings({ "unchecked", "rawtypes"})
public class ShiroSpringCache<K, V> implements org.apache.shiro.cache.Cache<K, V> {
public static long DEFAULT_TIMEOUT = 1;
private long timeout;
private String cacheName = "";
private CaffeineCacheManager firstCache;
private RedisTemplate redisTemplate;
public ShiroSpringCache(String cacheName, CaffeineCacheManager guavaCacheManager, RedisTemplate redisTemplate) {
this.timeout = DEFAULT_TIMEOUT;
this.cacheName = cacheName;
this.firstCache = guavaCacheManager;
this.redisTemplate = redisTemplate;
}
public ShiroSpringCache(String cacheName, CaffeineCacheManager guavaCacheManager, RedisTemplate redisTemplate, long timeout) {
this.timeout = DEFAULT_TIMEOUT;
this.cacheName = cacheName;
this.firstCache = guavaCacheManager;
this.redisTemplate = redisTemplate;
}
@Override
public V get(K key) throws CacheException {
// Long start = System.currentTimeMillis();
if (key == null) {
return null;
}
ValueWrapper valueWrapper = this.firstCache.getCache(cacheName).get(key);
if (valueWrapper != null) {
// System.out.println("查询["+key+"]耗时:" + (System.currentTimeMillis() - start));
return (V) valueWrapper.get();
}
Object result = this.redisTemplate.opsForValue().get(cacheName + key);
if(null != result) {
this.firstCache.getCache(cacheName).put(key, result);
}
// System.out.println("查询["+key+"]耗时:" + (System.currentTimeMillis() - start));
return (V) result;
}
@Override
public V put(K key, V value) throws CacheException {
// System.out.println("put:" + key);
V previous = get(key);
this.firstCache.getCache(cacheName).put(key, value);
this.redisTemplate.opsForValue().set(cacheName + key, value);
this.redisTemplate.expire(cacheName + key, this.timeout, TimeUnit.DAYS);
return previous;
}
@Override
public V remove(K key) throws CacheException {
V previous = get(key);
this.firstCache.getCache(cacheName).evict(key);
this.redisTemplate.delete(cacheName + key);
return previous;
}
@Override
public void clear() throws CacheException {
this.firstCache.getCache(cacheName).clear();
}
@Override
public int size() {
return 0;
}
@Override
public Set<K> keys() {
return Collections.emptySet();
}
@Override
public Collection<V> values() {
return Collections.emptySet();
}
}
package com.zmkm.shop.config.shiro.cache;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.util.Destroyable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.data.redis.core.RedisTemplate;
@SuppressWarnings({ "rawtypes" })
public class ShiroSpringCacheManager implements CacheManager, Destroyable {
private Logger logger = LoggerFactory.getLogger(ShiroSpringCacheManager.class);
private CaffeineCacheManager caffeineCacheManager;
private RedisTemplate redisTemplate;
private long timeout;
public void setCaffeineCacheManager(CaffeineCacheManager caffeineCacheManager) {
this.caffeineCacheManager = caffeineCacheManager;
}
public void setRedisTemplate(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
public void setTimeout(long timeout) {
this.timeout = timeout;
}
@Override
public <K, V> Cache<K, V> getCache(String name) throws CacheException {
if (logger.isTraceEnabled()) {
logger.trace("Acquiring ShiroSpringCache instance named [" + name + "]");
}
if(timeout <= 0) {
return new ShiroSpringCache<K, V>(name, caffeineCacheManager, redisTemplate);
}
return new ShiroSpringCache<K, V>(name, caffeineCacheManager, redisTemplate, timeout);
}
@Override
public void destroy() throws Exception {
}
}
package com.zmkm.shop.config.shiro.session;
import org.apache.shiro.session.mgt.SimpleSession;
import java.io.Serializable;
import java.util.Date;
import java.util.Map;
public class ShiroSession extends SimpleSession implements Serializable {
private static final long serialVersionUID = 2511215943083221727L;
public ShiroSession() {
super();
this.setChanged(true);
}
public ShiroSession(String host) {
super(host);
this.setChanged(true);
}
// 除lastAccessTime以外其他字段发生改变时为true
private boolean isChanged;
@Override
public void setId(Serializable id) {
super.setId(id);
this.setChanged(true);
}
@Override
public void setStopTimestamp(Date stopTimestamp) {
super.setStopTimestamp(stopTimestamp);
this.setChanged(true);
}
@Override
public void setExpired(boolean expired) {
super.setExpired(expired);
this.setChanged(true);
}
@Override
public void setTimeout(long timeout) {
super.setTimeout(timeout);
this.setChanged(true);
}
@Override
public void setHost(String host) {
super.setHost(host);
this.setChanged(true);
}
@Override
public void setAttributes(Map<Object, Object> attributes) {
super.setAttributes(attributes);
this.setChanged(true);
}
@Override
public void setLastAccessTime(Date lastAccessTime) {
super.setLastAccessTime(lastAccessTime);
this.setChanged(false);
}
@Override
public void touch() {
super.touch();
this.setChanged(false);
}
@Override
public void setAttribute(Object key, Object value) {
super.setAttribute(key, value);
this.setChanged(true);
}
@Override
public Object removeAttribute(Object key) {
this.setChanged(true);
return super.removeAttribute(key);
}
/**
* 停止
*/
@Override
public void stop() {
super.stop();
this.setChanged(true);
}
/**
* 设置过期
*/
@Override
protected void expire() {
this.stop();
this.setExpired(true);
}
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
@Override
protected boolean onEquals(SimpleSession ss) {
return super.onEquals(ss);
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public String toString() {
return super.toString();
}
public boolean isChanged() {
return isChanged;
}
public void setChanged(boolean isChanged) {
this.isChanged = isChanged;
}
}
package com.zmkm.shop.config.shiro.session;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SessionContext;
import org.apache.shiro.session.mgt.SessionFactory;
public class ShiroSessionFactory implements SessionFactory {
@Override
public Session createSession(SessionContext initData) {
if (initData != null) {
String host = initData.getHost();
if (host != null) {
return new ShiroSession(host);
}
}
return new ShiroSession();
}
}
package com.zmkm.shop.config.swagger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
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;
/**
* @ClassName : Swagger2Config
* @Description : swagger2
* @Author : shenkh
* @Date: 2020-02-20 15:57
*/
@Configuration
@EnableSwagger2
@Profile({"dev","skh","prod"})
public class Swagger2Config {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.zmkm.shop"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("维密商城")
.version("1.0")
.description("芝麻开门")
.termsOfServiceUrl("http://www.cjqy.com/z.html")
.build();
}
}
package com.zmkm.shop.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@AllArgsConstructor
public enum LoginResultEnum {
Login_Success(1, "登陆成功!"),
UnknownAccount_Exception(2, "用户名不存在!"),
DisabledAccount_Exception(3,"用户不可用!"),
IncorrectCredentials_Exception(4, "密码错误!"),
NotHaveOrganization_Exception(5, "没有机构请联系系统管理员!"),
NotHaveMenu_Exception(6, "没有菜单请联系系统管理员!");
@Getter
@Setter
int code;
@Getter
@Setter
String value;
}
package com.zmkm.shop.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@AllArgsConstructor
public enum ResultCodeEnum {
HTTP_OK(200, "成功"),
HTTP_LOGIN(201, "用户没有登陆"),
HTTP_PARAMS_ERROR(400, "输入参数错误"),
HTTP_USER_UNAUTHORIZED(401,"没有权限,请联系管理员!"),
HTTP_ORIGINAL_PASSWORD_ERROR(402,"原密码错误"),
HTTP_FORBIDDEN(403,"没有权限"),
HTTP_ERROR(500, "系统异常");
@Getter
@Setter
int code;
@Getter
@Setter
String msg;
}
package com.zmkm.shop.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@AllArgsConstructor
public enum StatusEnum {
AVAIL(1, "有效"), INVALID(2, "无效");
@Getter
@Setter
int code;
@Getter
@Setter
String msg;
}
package com.zmkm.shop.filter;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class AllowOptionsFormAuthenticationFilter extends FormAuthenticationFilter {
@Override
public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
httpServletResponse.setStatus(HttpStatus.OK.value());
return false;
}
return super.onPreHandle(request, response, mappedValue);
}
}
package com.zmkm.shop.filter;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Order(Ordered.HIGHEST_PRECEDENCE)
@Component
public class CorsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.addHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE,OPTIONS");
response.addHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with, X-Custom-Header");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials","true");
if (RequestMethod.OPTIONS.name().equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
filterChain.doFilter(request, response);
}
}
}
\ No newline at end of file
package com.zmkm.shop.filter;
import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @Title: URLPermissionsFilter.java
* @Package com.opensesame.platform.web.shiro.filter
* @Description: TODO(鉴权过滤器,以菜单url方式过滤)
* @author Kaihua Shen
* @date 2017年11月10日 下午5:06:54
*/
public class URLPermissionsFilter extends PermissionsAuthorizationFilter {
@Override
public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
throws IOException {
HttpServletRequest req = (HttpServletRequest) request;
String [] perms = new String [1];
perms[0] = req.getServletPath();
return super.isAccessAllowed(request, response, perms);
}
}
package com.zmkm.shop.modules.test.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.zmkm.shop.base.controller.BaseController;
import com.zmkm.shop.base.result.BaseResult;
import com.zmkm.shop.modules.test.domain.Dict;
import com.zmkm.shop.modules.test.service.DictService;
import com.zmkm.shop.modules.test.service.impl.DictServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("dict")
@Api(value = "字典", tags = "字典")
public class DictController extends BaseController {
@Autowired
DictServiceImpl dictService;
@PostMapping("/list")
@ApiOperation(value = "列表", notes = "列表", response = String.class)
public BaseResult<Object> list(){
BaseResult<Object> br = new BaseResult<>();
dictService.receiveDataSyn();
return br;
}
}
package com.zmkm.shop.modules.test.domain;
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 lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "t_dict")
public class Dict {
@TableId(value = "id",type = IdType.AUTO)
private Long id;
@TableField(value = "`key`")
private String key;
@TableField(value = "`value`")
private String value;
@TableField(value = "create_time")
private Long createTime;
@TableField(value = "update_time")
private Long updateTime;
@TableField(value = "oper_user_id")
private Long operUserId;
@TableField(value = "oper_user")
private String operUser;
}
package com.zmkm.shop.modules.test.domain;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
/**
* @Title: NetReceiveAddress
* @Package com.zmkm.shop.domain
* @Description: 小程序收货人地址表
* @author 40873
* @date 2024-2-14
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "t_net_receive_address")
public class NetReceiveAddress {
@TableId(value = "id",type = IdType.AUTO)
private Long id;//主键——>id
@TableField(value = "c_phone")
private String cPhone;//用户手机号——>c_phone
@TableField(value = "receive_name")
private String receiveName;//姓名——>receive_name
@TableField(value = "receive_phone")
private String receivePhone;//电话——>receive_phone
@TableField(value = "pro_code")
private String proCode;//省代码——>pro_code
@TableField(value = "pro_name")
private String proName;//省名称——>pro_name
@TableField(value = "city_code")
private String cityCode;//市代码——>city_code
@TableField(value = "city_name")
private String cityName;//市名称——>city_name
@TableField(value = "area_code")
private String areaCode;//区代码——>area_code
@TableField(value = "area_name")
private String areaName;//区名称——>area_name
@TableField(value = "village_type")
private Integer villageType;//街道类型|1:机构;2:目的地——>village_type
@TableField(value = "village_id")
private Long villageId;//乡id——>village_id
@TableField(value = "village_name")
private String villageName;//乡名称——>village_name
@TableField(value = "address")
private String address;//详细地址——>address
@TableField(value = "shop_name")
private String shopName;//公司/店名——>shop_name
@TableField(value = "status")
private Integer status;//状态:1.有效|2.无效——>status
@TableField(value = "lon")
private String lon;//经度——>lon
@TableField(value = "lat")
private String lat;//纬度——>lat
@TableField(value = "operator")
private Long operator;//操作人员——>operator
@TableField(value = "create_time")
private Long createTime;//创建时间——>create_time
@TableField(value = "update_time")
private Long updateTime;//操作时间——>update_time
@TableField(value = "receive_status")
private Integer receiveStatus;//1需自提 2可派送 默认 0——>receive_status
@TableField(value = "operator_name")
private String operatorName;//操作人姓名——>operator_name
}
package com.zmkm.shop.modules.test.domain;
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 lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Title: NetReceiveAddressCopy1
* @Package com.zmkm.shop.domain
* @Description: 小程序收货人地址表
* @author 40873
* @date 2024-2-14
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "t_net_receive_address_copy1")
public class NetReceiveAddressCopy1{
@TableId(value = "id",type = IdType.AUTO)
private Long id;//主键——>id
@TableField(value = "c_phone")
private String cPhone;//用户手机号——>c_phone
@TableField(value = "receive_name")
private String receiveName;//姓名——>receive_name
@TableField(value = "receive_phone")
private String receivePhone;//电话——>receive_phone
@TableField(value = "pro_code")
private String proCode;//省代码——>pro_code
@TableField(value = "pro_name")
private String proName;//省名称——>pro_name
@TableField(value = "city_code")
private String cityCode;//市代码——>city_code
@TableField(value = "city_name")
private String cityName;//市名称——>city_name
@TableField(value = "area_code")
private String areaCode;//区代码——>area_code
@TableField(value = "area_name")
private String areaName;//区名称——>area_name
@TableField(value = "village_code")
private String villageCode;//乡代码——>village_code
@TableField(value = "village_name")
private String villageName;//乡名称——>village_name
@TableField(value = "address")
private String address;//详细地址——>address
@TableField(value = "shop_name")
private String shopName;//公司/店名——>shop_name
@TableField(value = "status")
private Integer status;//状态:1.有效|2.无效——>status
@TableField(value = "lon")
private String lon;//经度——>lon
@TableField(value = "lat")
private String lat;//纬度——>lat
@TableField(value = "operator")
private Long operator;//操作人员——>operator
@TableField(value = "create_time")
private Long createTime;//创建时间——>create_time
@TableField(value = "update_time")
private Long updateTime;//操作时间——>update_time
@TableField(value = "receive_status")
private Integer receiveStatus;//1需自提 2可派送 默认 0——>receive_status
@TableField(value = "operator_name")
private String operatorName;//操作人姓名——>operator_name
}
package com.zmkm.shop.modules.test.domain;
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 lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* @Title: Organization
* @Package com.zmkm.shop.domain
* @Description: 机构
* @author 40873
* @date 2024-2-14
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "t_organization")
public class Organization {
@TableId(value = "id",type = IdType.AUTO)
private Long id;//主键id——>id
@TableField(value = "p_id")
private Long pId;//上级机构id——>p_id
@TableField(value = "name")
private String name;//机构名称——>name
@TableField(value = "short_name")
private String shortName;//机构简称,手填 例如沈阳区域 2A 5A 等等 有规则,不可以重复 可以自动生成 例如排到了5A 自动生成6A 如果在已生成的简称里1A-50A 之间有33A被停用了,再生成的时候先生成33A 下一个再生成51A,另外可以不用默认生成的简称自己添加——>short_name
@TableField(value = "telephone")
private String telephone;//固定电话——>telephone
@TableField(value = "manager_name")
private String managerName;//经理姓名——>manager_name
@TableField(value = "manager_phone")
private String managerPhone;//经理手机——>manager_phone
@TableField(value = "esc_manager_name")
private String escManagerName;//代管经理姓名——>esc_manager_name
@TableField(value = "esc_manager_phone")
private String escManagerPhone;//代管经理手机号——>esc_manager_phone
@TableField(value = "operate_type")
private Integer operateType;//经营类型|1:直营;2:承包——>operate_type
@TableField(value = "org_type")
private Integer orgType;//机构类型|1, 普通机构, 2,大区机构, 3,大区域, 4, 小区域, 5, 中转机构, 6, 内埠, 7, 外埠, 8, 收发货机构,9.分拨中心,10.返货组;——>org_type
@TableField(value = "allow_delivery")
private Integer allowDelivery;//允许发货|1:允许 2:不允许;——>allow_delivery
@TableField(value = "allow_receive")
private Integer allowReceive;//允许到货|1:允许 2:不允许;——>allow_receive
@TableField(value = "distance")
private Integer distance;//运距(公里)此为内埠站点到租车场的运距,据了解未来可能有多个租车场,但不会交叉,内埠站点只到固定的一个租车场——>distance
@TableField(value = "delivery_day_occupy")
private BigDecimal deliveryDayOccupy;//发货日提点,百分比——>delivery_day_occupy
@TableField(value = "receive_day_occupy")
private BigDecimal receiveDayOccupy;//到货日提点,百分比——>receive_day_occupy
@TableField(value = "province")
private String province;//省——>province
@TableField(value = "city")
private String city;//市——>city
@TableField(value = "area")
private String area;//区——>area
@TableField(value = "send_time")
private Long sendTime;//外埠发车时间——>send_time
@TableField(value = "address")
private String address;//机构地址——>address
@TableField(value = "longitude")
private String longitude;//经度——>longitude
@TableField(value = "latitude")
private String latitude;//纬度——>latitude
@TableField(value = "section")
private Long section;//所属区域——>section
@TableField(value = "inout_mark")
private Integer inoutMark;//标记机构内外埠:1内埠 2外埠 3其他——>inout_mark
@TableField(value = "status")
private Integer status;//是否启用|1:启用;2:禁用;3:停用;——>status
@TableField(value = "remark")
private String remark;//备注——>remark
@TableField(value = "order_code")
private Integer orderCode;//排序——>order_code
@TableField(value = "city_num")
private String cityNum;//城市固定电话区号——>city_num
@TableField(value = "opening_day")
private Long openingDay;//开业时间——>opening_day
@TableField(value = "wx_push_flag")
private Integer wxPushFlag;//微信推送标识:1推送、2不推送——>wx_push_flag
@TableField(value = "rural")
private Integer rural;//是否二级 1 否 2 是——>rural
@TableField(value = "rural_parent_id")
private Long ruralParentId;//一级父机构id——>rural_parent_id
@TableField(value = "operator")
private Long operator;//操作人员——>operator
@TableField(value = "operator_name")
private String operatorName;//操作人——>operator_name
@TableField(value = "create_time")
private Long createTime;//创建时间——>create_time
@TableField(value = "update_time")
private Long updateTime;//操作时间——>update_time
@TableField(value = "pro_code")
private String proCode;//发货省代码——>pro_code
@TableField(value = "city_code")
private String cityCode;//发货市代码——>city_code
@TableField(value = "area_code")
private String areaCode;//发货区代码——>area_code
@TableField(value = "amap_flag")
private Integer amapFlag;//小程序地图是否显示;1:显示|2不显示——>amap_flag
@TableField(value = "center_id")
private Long centerId;//分拨中心id ——>center_id
@TableField(value = "center_line_id")
private Long centerLineId;//所属分拣线id ——>center_line_id
@TableField(value = "return_id")
private Long returnId;//所属返货组id ——>return_id
@TableField(value = "theater_id")
private Long theaterId;//所属战区id ——>theater_id
@TableField(value = "gid_type")
private Integer gidType;//配送范围配置|1:已配置;2:未配置——>gid_type
@TableField(value = "gid")
private String gid;//电子围栏——>gid
@TableField(value = "online")
private Integer online;//网上下单是否显示|1:显示;2:不显示——>online
@TableField(value = "sign")
private Integer sign;//签收限制开关|1:开;2:关——>sign
@TableField(value = "alarm_value")
private Integer alarmValue;//警戒值:0-1000000——>alarm_value
@TableField(value = "alarm_lock")
private Integer alarmLock;//警戒值锁定(%)——>alarm_lock
@TableField(value = "project_line")
private Integer projectLine;//每日到货货款额度——>project_line
@TableField(value = "day")
private String day;//提现日(多个日期用英文逗号分隔)——>day
@TableField(value = "day_type")
private Integer dayType;//提现方式 1每周提现 2每月提现——>day_type
@TableField(value = "freight_type")
private Integer freightType;//是否扣运费 1是 2否——>freight_type
@TableField(value = "goods_type")
private Integer goodsType;//是否扣货款 1是 2否——>goods_type
}
package com.zmkm.shop.modules.test.dto;
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.github.dozermapper.core.Mapping;
import com.zmkm.shop.base.domain.BaseUserNameTime;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestDto{
@Mapping(value = "id")
private Long testId;
@Mapping(value = "name")
private String testName;
}
package com.zmkm.shop.modules.test.mapper;
import com.zmkm.shop.base.mapper.SuperMapper;
import com.zmkm.shop.modules.test.domain.Dict;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Repository
@Mapper
public interface DictMapper extends SuperMapper<Dict> {
}
package com.zmkm.shop.modules.test.mapper;
import com.zmkm.shop.base.mapper.SuperMapper;
import com.zmkm.shop.modules.test.domain.NetReceiveAddressCopy1;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
/**
* @Title: NetReceiveAddressCopy1Mapper
* @Package com.zmkm.shop.mapper
* @Description: 小程序收货人地址表
* @author 40873
* @date 2024-2-14
*/
@Repository
@Mapper
public interface NetReceiveAddressCopy1Mapper extends SuperMapper<NetReceiveAddressCopy1> {
}
package com.zmkm.shop.modules.test.mapper;
import com.zmkm.shop.base.mapper.SuperMapper;
import com.zmkm.shop.modules.test.domain.NetReceiveAddress;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
/**
* @Title: NetReceiveAddressMapper
* @Package com.zmkm.shop.mapper
* @Description: 小程序收货人地址表
* @author 40873
* @date 2024-2-14
*/
@Repository
@Mapper
public interface NetReceiveAddressMapper extends SuperMapper<NetReceiveAddress> {
}
package com.zmkm.shop.modules.test.mapper;
import com.zmkm.shop.base.mapper.SuperMapper;
import com.zmkm.shop.modules.test.domain.Organization;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
/**
* @Title: OrganizationMapper
* @Package com.zmkm.shop.mapper
* @Description: 机构
* @author 40873
* @date 2024-2-14
*/
@Repository
@Mapper
public interface OrganizationMapper extends SuperMapper<Organization> {
}
package com.zmkm.shop.modules.test.service;
import com.zmkm.shop.base.service.BaseService;
import com.zmkm.shop.modules.test.domain.Dict;
public interface DictService extends BaseService<Dict> {
}
package com.zmkm.shop.modules.test.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zmkm.shop.base.result.BaseResult;
import com.zmkm.shop.base.service.impl.BaseServiceImpl;
import com.zmkm.shop.config.dozer.DozerMapperFactory;
import com.zmkm.shop.modules.test.domain.Dict;
import com.zmkm.shop.modules.test.domain.NetReceiveAddress;
import com.zmkm.shop.modules.test.domain.NetReceiveAddressCopy1;
import com.zmkm.shop.modules.test.domain.Organization;
import com.zmkm.shop.modules.test.mapper.DictMapper;
import com.zmkm.shop.modules.test.mapper.NetReceiveAddressCopy1Mapper;
import com.zmkm.shop.modules.test.mapper.NetReceiveAddressMapper;
import com.zmkm.shop.modules.test.mapper.OrganizationMapper;
import com.zmkm.shop.modules.test.service.DictService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class DictServiceImpl extends BaseServiceImpl<DictMapper, Dict> {
@Autowired
private NetReceiveAddressMapper netReceiveAddressMapper;
@Autowired
private NetReceiveAddressCopy1Mapper receiveAddressCopy1Mapper;
@Autowired
private OrganizationMapper organizationMapper;
@Autowired
DozerMapperFactory dozer;
@Transactional(rollbackFor = Exception.class)
public BaseResult<Object> receiveDataSyn(){
List<NetReceiveAddressCopy1> list = receiveAddressCopy1Mapper. selectList(
new QueryWrapper<NetReceiveAddressCopy1>().lambda().eq(NetReceiveAddressCopy1::getStatus,1)
);
for(NetReceiveAddressCopy1 copy1 : list) {
NetReceiveAddress domain = dozer.convert(copy1,NetReceiveAddress.class);
List<Organization> orgList = organizationMapper.selectList(
new QueryWrapper<Organization>().lambda().eq(Organization::getProvince,copy1.getProName())
.eq(Organization::getCity,copy1.getCityName())
.eq(Organization::getArea,copy1.getAreaName())
.eq(Organization::getStatus,1)
);
if(CollectionUtils.isNotEmpty(orgList) && orgList.size() == 1) {
Long orgid = orgList.get(0).getId();
domain.setVillageType(1);
domain.setVillageId(orgid);
}
netReceiveAddressMapper.insert(domain);
}
return new BaseResult<>();
}
}
package com.zmkm.shop.modules.test.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.zmkm.shop.base.page.BasePage;
import com.zmkm.shop.base.result.BaseResult;
import com.zmkm.shop.base.service.impl.BaseServiceImpl;
import com.zmkm.shop.modules.test.domain.NetReceiveAddressCopy1;
import com.zmkm.shop.modules.test.mapper.NetReceiveAddressCopy1Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Title: NetReceiveAddressCopy1ServiceImpl
* @Package com.zmkm.shop.service
* @Description: TODO 小程序收货人地址表
* @author 40873
* @date 2024-2-14
*/
@Service
public class NetReceiveAddressCopy1ServiceImpl extends BaseServiceImpl<NetReceiveAddressCopy1Mapper, NetReceiveAddressCopy1> {
@Autowired
NetReceiveAddressCopy1Mapper netReceiveAddressCopy1Mapper;
}
package com.zmkm.shop.modules.test.service.impl;
import com.zmkm.shop.base.service.impl.BaseServiceImpl;
import com.zmkm.shop.modules.test.domain.NetReceiveAddress;
import com.zmkm.shop.modules.test.mapper.NetReceiveAddressMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Title: NetReceiveAddressServiceImpl
* @Package com.zmkm.shop.service
* @Description: TODO 小程序收货人地址表
* @author 40873
* @date 2024-2-14
*/
@Service
public class NetReceiveAddressServiceImpl extends BaseServiceImpl<NetReceiveAddressMapper, NetReceiveAddress> {
@Autowired
NetReceiveAddressMapper netReceiveAddressMapper;
}
package com.zmkm.shop.modules.test.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.zmkm.shop.base.result.BaseResult;
import com.zmkm.shop.base.service.impl.BaseServiceImpl;
import com.zmkm.shop.modules.test.domain.Organization;
import com.zmkm.shop.modules.test.mapper.OrganizationMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @Title: OrganizationServiceImpl
* @Package com.zmkm.shop.service
* @Description: TODO 机构
* @author 40873
* @date 2024-2-14
*/
@Service
public class OrganizationServiceImpl extends BaseServiceImpl<OrganizationMapper, Organization> {
@Autowired
OrganizationMapper organizationMapper;
}
package com.zmkm.shop.utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateUtils {
public static final String DATE_TIME_FORMAT = "yyyy/MM/dd HH:mm:ss";
public static String getYesterdayTime(String date){
Calendar cal=Calendar.getInstance();
cal.setTime(StrToDate(date));
cal.add(Calendar.DATE,-1);
return DateToStr(cal.getTime());
}
public static String DateToStr(Date date) {
SimpleDateFormat format = new SimpleDateFormat(DATE_TIME_FORMAT);
String str = format.format(date);
return str;
}
public static Date StrToDate(String str) {
SimpleDateFormat format = new SimpleDateFormat(DATE_TIME_FORMAT);
Date date = null;
try {
date = format.parse(str);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
package com.zmkm.shop.utils;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.RandomUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
/**
* 查询源码,发现shiro有原生加密方式,舍弃自定义
* @author shen
*
*/
public class ShiroUtils {
public final static String algorithmName = "MD5";
public static final int hashIterations= 10;
/**
* @Title: generateSalt
* @Description: TODO(生成随机)
* @param @param saltNum
* @param @return
* @return String
* @throws
*/
public static String generateSalt(int saltNum) {
return new String(Hex.encodeHex(RandomUtils.nextBytes(saltNum)));
}
/**
* 加密
* @param password
* @param salt
* @return
*/
public static String EncodeSalt(String password, String salt) {
return new SimpleHash(algorithmName, password, salt, hashIterations).toString();
}
/**
* @Title: getSubject
* @Description: TODO(获取Subject)
* @param @return
* @return Subject
* @throws
*/
public static Subject getSubject() {
return SecurityUtils.getSubject();
}
public static void main(String[] args) {
System.out.println(EncodeSalt("123456","87ee72d4154d262d"));
}
}
spring:
datasource:
dynamic:
primary: mysql
datasource:
mysql:
username: root
password: 123456
url: jdbc:mysql://123.57.2.50:3333/cnooc?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&tinyInt1isBit=false&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
server:
port: 9922
servlet:
context-path: /dataSyn
spring:
datasource:
username: root
password: zmkmSuper2020
url: jdbc:mysql://182.92.119.71:3389/db_shop_prod?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&tinyInt1isBit=false&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
redis:
cluster:
nodes:
- 172.17.243.93:7001
- 172.17.243.93:7002
- 172.17.243.92:7001
- 172.17.243.92:7002
- 172.17.243.91:7001
- 172.17.243.91:7002
server:
port: 8899
spring:
application:
name: cnooc
profiles:
active: @profiles.activation@
http:
encoding:
charset: utf-8
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
mybatis-plus:
mapper-locations: classpath:/mapper/*Mapper.xml
logging:
config: classpath:logback-spring.xml
________ .___ ___. __ ___ .___ ___.
| / | \/ | | |/ / | \/ |
`---/ / | \ / | | ' / | \ / |
/ / | |\/| | | < | |\/| |
/ /----.| | | | | . \ | | | |
/________||__| |__| |__|\__\ |__| |__|
<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozermapper.github.io/schema/bean-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://dozermapper.github.io/schema/bean-mapping http://dozermapper.github.io/schema/bean-mapping.xsd">
</mappings>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="log.charset" value="UTF-8" />
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n" />
<property name="log.home" value="/var/log/@artifactId@" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder charset="${log.charset}">
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<appender name="DEBUG"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="${log.charset}">
<pattern>${log.pattern}</pattern>
</encoder>
<file>${log.home}/debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.home}/debug.%d{yyyy-MM-dd}.log
</fileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch>
<onMismatch>ACCEPT</onMismatch>
</filter>
</appender>
<appender name="ERROR"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="${log.charset}">
<pattern>${log.pattern}</pattern>
</encoder>
<file>${log.home}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.home}/error.%d{yyyy-MM-dd}.log
</fileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<logger name="com.zmkm" level="DEBUG" />
<logger name="com.alibaba" level="ERROR" />
<logger name="org.apache" level="ERROR" />
<logger name="com.mangofactory" level="ERROR" />
<logger name="org.springframework" level="ERROR" />
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="DEBUG" />
<appender-ref ref="ERROR" />
</root>
</configuration>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment