Commit 68a89403 authored by shangying's avatar shangying

Merge remote-tracking branch 'remotes/origin/master' into oneclickdatanewV1

# Conflicts:
#	src/main/java/cn/quantgroup/cashloanflowboss/Bootstrap.java
parents f3ad9f28 97678ed3
/*
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.
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.Properties;
public class MavenWrapperDownloader {
/**
* 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/0.4.2/maven-wrapper-0.4.2.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 direcrory '" + 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 {
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.0/apache-maven-3.6.0-bin.zip
#!/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.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven2 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)`"
# TODO classpath?
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
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
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 command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
wget "$jarUrl" -O "$wrapperJarPath"
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
curl -o "$wrapperJarPath" "$jarUrl"
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
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
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 "$@"
@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 Maven2 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 key stroke 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 my 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.4.2/maven-wrapper-0.4.2.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% (
echo Found %WRAPPER_JAR%
) else (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
echo Finished downloading %WRAPPER_JAR%
)
@REM End of extension
%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%
package cn.quantgroup.cashloanflowboss;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableRedisHttpSession
@EnableRedisHttpSession(maxInactiveIntervalInSeconds= 7200, redisNamespace = "${spring.application.name}")
@EnableTransactionManagement
@SpringBootApplication(scanBasePackages = {"cn.quantgroup.cashloanflowboss"})
@Configuration
@EnableAutoConfiguration
@ServletComponentScan
@EnableFeignClients
@EnableAsync(proxyTargetClass = true)
@EnableScheduling
public class Bootstrap {
public static void main(String[] args) {
......
package cn.quantgroup.cashloanflowboss.api.channel.controller;
import cn.quantgroup.cashloanflowboss.api.channel.model.ChannelConfVo;
import cn.quantgroup.cashloanflowboss.api.channel.model.ChannelModel;
import cn.quantgroup.cashloanflowboss.api.channel.service.ChannelConfService;
import cn.quantgroup.cashloanflowboss.component.security.annotiation.Security;
import cn.quantgroup.cashloanflowboss.core.annotation.channelrole.ChannelIdInit;
......@@ -11,6 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* Created with suntao on 2019/8/2
......@@ -83,4 +85,11 @@ public class ChannelConfController {
}
@GetMapping("/all")
public Result channelAll(){
List<ChannelModel> all = channelConfService.getAll();
return Result.buildSuccess(all);
}
}
package cn.quantgroup.cashloanflowboss.api.channel.model;
import cn.quantgroup.cashloanflowboss.spi.clf.entity.ChannelApplyInfoStrategy;
import lombok.Data;
import javax.validation.constraints.NotNull;
......@@ -18,6 +19,8 @@ public class ChannelConfBaseModel {
private String env;
private Integer fundId;
private Integer p2pFundId;
private ChannelApplyInfoStrategy channelApplyInfoStrategy;
/**
* 对应productId
*/
......
package cn.quantgroup.cashloanflowboss.api.channel.model;
import lombok.Data;
/**
* @author Wang Xiangwei
* @version 2020/3/6
*/
@Data
public class ChannelModel {
private Long id;
private String name;
}
......@@ -2,8 +2,11 @@ package cn.quantgroup.cashloanflowboss.api.channel.service;
import cn.quantgroup.cashloanflowboss.api.channel.model.ChannelConfVo;
import cn.quantgroup.cashloanflowboss.api.channel.model.ChannelListModel;
import cn.quantgroup.cashloanflowboss.api.channel.model.ChannelModel;
import org.springframework.data.domain.Page;
import java.util.List;
/**
* function:
* date: 2019/9/16
......@@ -17,4 +20,6 @@ public interface ChannelConfService {
ChannelConfVo getChannelConf(Long channelId);
Boolean editChannelConfInfo(ChannelConfVo confVo);
List<ChannelModel> getAll();
}
package cn.quantgroup.cashloanflowboss.api.channel.service;
import java.sql.Timestamp;
import java.util.*;
import cn.quantgroup.cashloanflowboss.api.channel.entity.ChannelConf;
import cn.quantgroup.cashloanflowboss.api.channel.model.ChannelConfAddModel;
import cn.quantgroup.cashloanflowboss.api.channel.model.ChannelConfBaseModel;
import cn.quantgroup.cashloanflowboss.api.channel.model.ChannelConfVo;
import cn.quantgroup.cashloanflowboss.api.channel.model.ChannelListModel;
import cn.quantgroup.cashloanflowboss.api.channel.model.*;
import cn.quantgroup.cashloanflowboss.api.channel.repository.ChannelConfRepository;
import cn.quantgroup.cashloanflowboss.api.channel.util.ChannelConfUtil;
import cn.quantgroup.cashloanflowboss.spi.clf.entity.ChannelApplyInfoStrategy;
import cn.quantgroup.cashloanflowboss.spi.clf.entity.ClfCallbackConfiguration;
import cn.quantgroup.cashloanflowboss.spi.clf.entity.ClfChannelConfiguration;
import cn.quantgroup.cashloanflowboss.api.channel.repository.ChannelConfRepository;
import cn.quantgroup.cashloanflowboss.spi.clf.entity.ClfOrderCallBack;
import cn.quantgroup.cashloanflowboss.spi.clf.model.KANoticeType;
import cn.quantgroup.cashloanflowboss.api.channel.util.ChannelConfUtil;
import cn.quantgroup.cashloanflowboss.spi.clf.service.CLFCenterService;
import cn.quantgroup.cashloanflowboss.utils.IgnorePropertiesUtil;
import org.springframework.beans.BeanUtils;
......@@ -20,6 +16,11 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* function:
* date: 2019/8/2
......@@ -28,7 +29,7 @@ import org.springframework.stereotype.Service;
*/
@Service
public class ChannelConfServiceImpl implements ChannelConfService{
public class ChannelConfServiceImpl implements ChannelConfService {
@Autowired
private CLFCenterService clfCenterService;
......@@ -37,7 +38,6 @@ public class ChannelConfServiceImpl implements ChannelConfService{
private ChannelConfRepository channelConfRepository;
@Override
public Page<ChannelListModel> getChannelInfo(Integer pageNumber, Integer pageSize, Long channelId, String channelName) {
......@@ -60,8 +60,9 @@ public class ChannelConfServiceImpl implements ChannelConfService{
public ChannelConfVo getChannelConf(Long channelId) {
ChannelConf channelConf = channelConfRepository.getByChannelId(channelId);
ChannelConfVo channelConfVo;
if (channelConf != null) {
return ChannelConfUtil.channelConfConvertVOModel(channelConf);
channelConfVo = ChannelConfUtil.channelConfConvertVOModel(channelConf);
} else {
// boss channel_conf 为空,从clf 查询数据
ClfChannelConfiguration channelConfiguration = clfCenterService.findChannelConfigurationByChannelId(channelId);
......@@ -70,8 +71,12 @@ public class ChannelConfServiceImpl implements ChannelConfService{
ClfOrderCallBack orderStatus = clfCenterService.findOrderCallBackByByCallbackStatusAndChannelId(KANoticeType.FUND_SUCC.name(), channelId);
ClfOrderCallBack repaymentPlan = clfCenterService.findOrderCallBackByByCallbackStatusAndChannelId(KANoticeType.REPAYMENT.name(), channelId);
return ChannelConfUtil.getChannelConfVoByClf(channelConfiguration, approve, orderStatus, repaymentPlan);
channelConfVo = ChannelConfUtil.getChannelConfVoByClf(channelConfiguration, approve, orderStatus, repaymentPlan);
}
ChannelApplyInfoStrategy channelApplyInfoStrategyByChannelId = clfCenterService.findChannelApplyInfoStrategyByChannelId(channelId);
channelConfVo.getBasicInfo().setChannelApplyInfoStrategy(channelApplyInfoStrategyByChannelId);
return channelConfVo;
}
@Override
......@@ -122,6 +127,34 @@ public class ChannelConfServiceImpl implements ChannelConfService{
}
clfCenterService.saveOrderCall(clfOrderCallBackList);
}
//保存进件配置项
Long channelId = basicInfo.getChannelId();
ChannelApplyInfoStrategy channelApplyInfoStrategy = basicInfo.getChannelApplyInfoStrategy();
if (channelApplyInfoStrategy != null) {
ChannelApplyInfoStrategy strategy = clfCenterService.findChannelApplyInfoStrategyByChannelId(channelId);
if (strategy != null) {
channelApplyInfoStrategy.setId(strategy.getId());
}
clfCenterService.saveChannelApplyInfoStrategy(channelApplyInfoStrategy);
}
return true;
}
@Override
public List<ChannelModel> getAll() {
List<ClfChannelConfiguration> all = clfCenterService.findAll();
List<ChannelModel> channelModelList = new ArrayList<>(all.size());
all.forEach(e->{
ChannelModel model = new ChannelModel();
model.setId(e.getId());
model.setName(e.getChannelName());
channelModelList.add(model);
});
return channelModelList;
}
}
......@@ -5,8 +5,6 @@ import cn.quantgroup.cashloanflowboss.api.user.dictionary.UserStatus;
import cn.quantgroup.cashloanflowboss.api.user.entity.User;
import cn.quantgroup.cashloanflowboss.api.user.model.UserInfo;
import cn.quantgroup.cashloanflowboss.api.user.service.UserService;
import cn.quantgroup.cashloanflowboss.api.user.service.UserServiceImpl;
import cn.quantgroup.cashloanflowboss.core.asserts.Assert;
import cn.quantgroup.cashloanflowboss.core.base.Tuple;
import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationDictionary;
import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationStatus;
......@@ -68,6 +66,7 @@ public class LoginServiceImpl implements LoginService {
final String passwordMd5 = MD5Tools.md5(password);
if (!user.getPassword().equalsIgnoreCase(passwordMd5)) {
log.info("用户名或密码错误username=" + username);
log.info("user.name:{},user.pwd:{},passwordMd5:{}", user.getUsername(), user.getPassword(), passwordMd5);
return new Tuple<>(Boolean.FALSE, ApplicationStatus.USERNAME_OR_PASSWORD_ERROR);
}
......
package cn.quantgroup.cashloanflowboss.api.mapping;
import lombok.Data;
import javax.persistence.*;
/**
* @author Wang Xiangwei
* @version 2020/3/11
*/
@Data
@Entity
@Table(name = "user_role_mapping")
public class UserRoleMapping {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "user_id")
private Long userId;
@Column(name = "role_id")
private Long roleId;
}
package cn.quantgroup.cashloanflowboss.api.mapping;
import cn.quantgroup.cashloanflowboss.core.persistence.CashLoanFlowBossPubConfDataSource;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import javax.transaction.Transactional;
/**
* Created by WeiWei on 2019/7/22.
*/
@CashLoanFlowBossPubConfDataSource
@Repository
public interface UserRoleMappingRepository extends JpaRepository<UserRoleMapping, Long> {
@Transactional
void deleteAllByRoleId(Long roleId);
}
......@@ -9,10 +9,13 @@ import cn.quantgroup.cashloanflowboss.core.annotation.channelrole.ChannelIdInit;
import cn.quantgroup.cashloanflowboss.core.annotation.channelrole.CheckChannelRole;
import cn.quantgroup.cashloanflowboss.core.base.Result;
import cn.quantgroup.cashloanflowboss.core.base.Tuple;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Objects;
/**
* function:
......@@ -23,6 +26,7 @@ import javax.validation.Valid;
@RestController
@RequestMapping("/order")
@Slf4j
public class OrderController {
......@@ -195,12 +199,16 @@ public class OrderController {
@CheckChannelRole(channelOrderNumberSPEL = "#this[0]")
@GetMapping("/repaymentPlan")
public Result repaymentPlan(String channelOrderNumber, Long loanId) {
if (StringUtils.isEmpty(channelOrderNumber) && Objects.isNull(loanId)) {
log.error("还款计划查询 channelOrderNumber 和 loanId 不能同时为空 ");
return Result.buildFail("channelOrderNumber 和 loanId 不能同时为空");
}
return Result.buildSuccess(orderService.findRepaymentPlan(channelOrderNumber, loanId));
}
/**
* 订单还款计划
* 发起结清
*
* @param channelOrderNumber
* @return
......
package cn.quantgroup.cashloanflowboss.api.order.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* @author yangjun
* @Date 2020/3/3 9:48
* @Desc
* @Update
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RepaymentPlanItem {
/**
* 期数
*/
private Integer periodNo;
/**
* 还款类型 COMMON(正常)或SELF_WITHHOLD(代扣)
*/
private String repaymentType;
/**
* 还款状态,0 ("未还款")、2 ("已逾期")、3 ("已还款")
*/
private Integer repaymentStatus;
/**
* 应还本金
*/
private BigDecimal principal;
/**
* 应还利息
*/
private BigDecimal interest;
/**
* 应还罚息
*/
private BigDecimal overdueInterest;
/**
* 应还服务费
*/
private BigDecimal serviceFee;
/**
* 应还其它费用
*/
private BigDecimal otherFee;
/**
* 最早可还款时间
*/
private Long repayableTime;
/**
* 还款日期(到期时间),10位时间戳
*/
private Long dueTime;
/**
* 应还金额
*/
private BigDecimal requiredRepayment;
/**
* 实还本金
*/
private BigDecimal actPrincipal;
/**
* 实还利息
*/
private BigDecimal actInterest;
/**
* 实还服务费
*/
private BigDecimal actServiceFee;
/**
* 实还罚息
*/
private BigDecimal actOverdueInterest;
/**
* 实还其它费用
*/
private BigDecimal actOtherFee;
/**
* 减免金额
*/
private BigDecimal reliefAmount;
/**
* 实还金额
*/
private BigDecimal repayAmount;
/**
* 逾期天数
*/
private Integer overdueDays;
/**
* 还款时间
*/
private Long repayTime;
}
package cn.quantgroup.cashloanflowboss.api.order.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.util.List;
/**
* @author yangjun
* @Date 2020/3/3 9:47
* @Desc
* @Update
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RepaymentPlansResultModel {
private Long loanId;
/**
* 放款总金额
*/
private BigDecimal totalLoanAmount;
/**
* 收款总金额
*/
private BigDecimal totalReceiveAmount;
/**
* 放款到账时间
*/
private Long lendTime;
/**
* 申请时间,loan的created_at就行,提现签约时间
*/
private Long applyTime;
/**
* 应还款总金额
*/
private BigDecimal totalRepaymentAmount;
/**
* 总利息
*/
private BigDecimal totalInterest;
/**
* 应还总服务费
*/
private BigDecimal totalServiceFee;
/**
* 应还总其他费用
*/
private BigDecimal totalOtherFee;
/**
* 已还 总
*/
private BigDecimal alreadyPaidAmount;
/**
* 剩余未还 总
*/
private BigDecimal notPaidAmount;
/**
* 已还n期
*/
private Integer sumPaidTerm;
/**
* 是否结清 true 结清
*/
private Boolean hasAllPaid;
/** 还款计划 */
private List<RepaymentPlanItem> repaymentPlans;
}
package cn.quantgroup.cashloanflowboss.api.order.service;
import cn.quantgroup.cashloanflowboss.api.order.model.ApproveVo;
import cn.quantgroup.cashloanflowboss.api.order.model.HistoryOrderStatusVoModel;
import cn.quantgroup.cashloanflowboss.api.order.model.LendingFormModel;
import cn.quantgroup.cashloanflowboss.api.order.model.OrderVo;
import cn.quantgroup.cashloanflowboss.api.order.model.*;
import cn.quantgroup.cashloanflowboss.core.base.Tuple;
import cn.quantgroup.cashloanflowboss.core.tuple.ThreeTuple;
import cn.quantgroup.cashloanflowboss.spi.clf.model.CallbackRecordVoModel;
import org.springframework.data.domain.Page;
import org.springframework.transaction.annotation.Transactional;
......@@ -47,7 +43,7 @@ public interface OrderService {
List<CallbackRecordVoModel> getOrderCallbackRecordList(String channelOrderNumber);
Object findRepaymentPlan(String channelOrderNumber, Long loanId);
RepaymentPlansResultModel findRepaymentPlan(String channelOrderNumber, Long loanId);
void loadSecondAuditJob();
......
......@@ -26,8 +26,6 @@ import cn.quantgroup.cashloanflowboss.spi.clf.repository.ClfOrderMappingReposito
import cn.quantgroup.cashloanflowboss.spi.clf.service.CLFCenterService;
import cn.quantgroup.cashloanflowboss.spi.clotho.service.ClothoCenterService;
import cn.quantgroup.cashloanflowboss.spi.jolyne.JolyneService;
import cn.quantgroup.cashloanflowboss.spi.jolyne.JolyneUtil;
import cn.quantgroup.cashloanflowboss.spi.jolyne.model.JolyneDB;
import cn.quantgroup.cashloanflowboss.spi.opapi.OPCenter;
import cn.quantgroup.cashloanflowboss.spi.user.service.XyqbUserService;
import cn.quantgroup.cashloanflowboss.spi.xyqb.entity.Contract;
......@@ -38,7 +36,6 @@ import cn.quantgroup.cashloanflowboss.spi.xyqb.service.XYQBCenterService;
import cn.quantgroup.cashloanflowboss.utils.JSONTools;
import cn.quantgroup.user.retbean.XUser;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.math.BigDecimal;
......@@ -59,6 +56,7 @@ import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
......@@ -107,8 +105,9 @@ public class OrderServiceImpl implements OrderService{
@Autowired
private OPCenter opCenter;
@Value("${cloth.auth}")
private String auth;
private static final String auth = "dXNlcj14dWV6aiZwYXNzd29yZD0xMjMxMjNxd2Vxd2U%3D";
private static final int CONSCONT_STATUS = 2;
......@@ -578,19 +577,30 @@ public class OrderServiceImpl implements OrderService{
* @return
*/
@Override
public Object findRepaymentPlan(String channelOrderNumber, Long loanId) {
public RepaymentPlansResultModel findRepaymentPlan(String channelOrderNumber, Long loanId) {
log.info("[findRepaymentPlan] 查询还款计划 channelOrderNumber={},loanId={}", channelOrderNumber, loanId);
if (loanId == null || loanId < 1) {
ClfOrderMapping orderMapping = clfCenterService.findOrderMappingByChannelOrderNo(channelOrderNumber);
if (orderMapping == null || orderMapping.getLoanId() == null) {
log.warn("[findRepaymentPlan] 订单信息不存在或没有loanId");
return null;
}
loanId = orderMapping.getLoanId();
}
// xyqbCenterService.findRepaymentPlan(loanId);
ServiceResult<RepaymentPlansResultModel> serviceResult = xyqbCenterService.findRepaymentPlan(loanId);
log.info("[findRepaymentPlan] 查询还款计划,返回信息 channelOrderNumber={},loanId={},serviceResult={}", channelOrderNumber, loanId, serviceResult);
if (Objects.isNull(serviceResult) || !serviceResult.isSuccess()) {
log.error("[findRepaymentPlan] 查询还款计划异常,返回页面空list");
return null;
}
RepaymentPlansResultModel repaymentPlansVo = serviceResult.getData();
repaymentPlansVo.setLoanId(loanId);
log.info("[findRepaymentPlan] 查询还款计划,返回信息 channelOrderNumber={},loanId={},repaymentPlansVo={}", channelOrderNumber, loanId, repaymentPlansVo);
return repaymentPlansVo;
}
@Override
public void loadSecondAuditJob() {
jolyneService.reloadJob("cn.qg.clotho.job.FetchDataLoanJob");
......
package cn.quantgroup.cashloanflowboss.api.permissionmodule.controller;
import cn.quantgroup.cashloanflowboss.api.permissionmodule.model.PermissionVO;
import cn.quantgroup.cashloanflowboss.api.permissionmodule.service.IPermissionService;
import cn.quantgroup.cashloanflowboss.component.security.annotiation.Security;
import cn.quantgroup.cashloanflowboss.core.base.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
......@@ -19,6 +21,8 @@ import org.springframework.web.bind.annotation.RestController;
public class PermissionController {
@Autowired
private IPermissionService permissionService;
/**
* 角色 未拥有的权限
* @param roleId
......@@ -33,14 +37,13 @@ public class PermissionController {
/**
* 权限列表
* @param permissionVO
* @return
*/
@GetMapping("list")
@Security(authorityId = "Permission.permissionList")
public Result permissionList(PermissionVO permissionVO) {
// 分页查询
return null;
@GetMapping("all")
//@Security(authorityId = "Permission.permissionList")
public Result permissionList() {
return permissionService.getAll();
}
/**
......
......@@ -4,6 +4,7 @@ import cn.quantgroup.cashloanflowboss.component.security.Authority;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Proxy;
import javax.persistence.*;
import java.util.List;
......@@ -16,6 +17,7 @@ import java.util.List;
@AllArgsConstructor
@Entity
@Table(name = "permission")
@Proxy(lazy = false)
public class Permission {
/**
......
package cn.quantgroup.cashloanflowboss.api.permissionmodule.repository;
import cn.quantgroup.cashloanflowboss.api.permissionmodule.entity.Permission;
import cn.quantgroup.cashloanflowboss.core.persistence.CashLoanFlowBossPubConfDataSource;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* @author Wang Xiangwei
* @version 2020/3/2
*/
@CashLoanFlowBossPubConfDataSource
@Repository
public interface PermissionRepository extends JpaRepository<Permission,Long> {
}
package cn.quantgroup.cashloanflowboss.api.permissionmodule.service;
import cn.quantgroup.cashloanflowboss.api.permissionmodule.entity.Permission;
import cn.quantgroup.cashloanflowboss.core.base.Result;
import java.util.List;
/**
* @author Wang Xiangwei
* @version 2020/3/6
*/
public interface IPermissionService {
Result<List<Permission>> getAll();
}
package cn.quantgroup.cashloanflowboss.api.permissionmodule.service;
import cn.quantgroup.cashloanflowboss.api.permissionmodule.entity.Permission;
import cn.quantgroup.cashloanflowboss.api.permissionmodule.repository.PermissionRepository;
import cn.quantgroup.cashloanflowboss.core.base.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author Wang Xiangwei
* @version 2020/3/6
*/
@Service
public class PermissionServiceImpl implements IPermissionService {
@Autowired
private PermissionRepository permissionRepository;
@Override
public Result<List<Permission>> getAll() {
List<Permission> permissionList = permissionRepository.findAll();
return Result.buildSuccess(permissionList);
}
}
package cn.quantgroup.cashloanflowboss.api.role.controller;
import cn.quantgroup.cashloanflowboss.api.role.entity.Role;
import cn.quantgroup.cashloanflowboss.api.role.model.RoleVO;
import cn.quantgroup.cashloanflowboss.component.security.annotiation.Security;
import cn.quantgroup.cashloanflowboss.api.role.model.RoleModel;
import cn.quantgroup.cashloanflowboss.api.role.model.RoleModelVo;
import cn.quantgroup.cashloanflowboss.api.role.model.RoleQueryModel;
import cn.quantgroup.cashloanflowboss.api.role.service.RoleService;
import cn.quantgroup.cashloanflowboss.core.base.Result;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
/**
* function:
......@@ -19,29 +23,39 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("role")
public class RoleController {
@Autowired
private RoleService roleService;
@GetMapping("list")
@Security(authorityId = "Role.roleList")
public Result roleList() {
return null;
//@Security(authorityId = "Role.roleList")
public Result<Page<Role>> roleList(@Valid RoleQueryModel roleQueryModel) {
return roleService.getRoleByName(roleQueryModel);
}
@GetMapping("delete")
@Security(authorityId = "Role.delete")
public Result deleteRole() {
return null;
@DeleteMapping("delete/{roleId}")
//@Security(authorityId = "Role.delete")
public Result<Boolean> deleteRole(@PathVariable Long roleId) {
return roleService.deleteRole(roleId);
}
@PostMapping("save")
@Security(authorityId = "Role.saveRole")
public Result saveRole(RoleVO role) {
//@Security(authorityId = "Role.saveRole")
public Result<Boolean> saveRole(@RequestBody @Valid RoleModelVo roleModelVo) {
return null;
return roleService.addRole(roleModelVo);
}
@PutMapping("update")
// @Security(authorityId = "Role.update")
public Result<Boolean> updateRole(@RequestBody @Valid RoleModelVo roleModelVo){
return roleService.modifyRole(roleModelVo);
}
@GetMapping("/all")
public Result<List<RoleModel>> getAll(){
return roleService.getAll();
}
}
......@@ -3,6 +3,7 @@ package cn.quantgroup.cashloanflowboss.api.role.entity;
import cn.quantgroup.cashloanflowboss.api.permissionmodule.entity.Permission;
import cn.quantgroup.cashloanflowboss.core.persistence.Primary;
import lombok.Data;
import org.hibernate.annotations.Proxy;
import javax.persistence.*;
import java.util.List;
......@@ -14,6 +15,7 @@ import java.util.function.UnaryOperator;
@Data
@Entity
@Table(name = "role")
@Proxy(lazy = false)
public class Role extends Primary implements UnaryOperator<Role> {
/**
......@@ -29,6 +31,12 @@ public class Role extends Primary implements UnaryOperator<Role> {
@Column(name = "name")
private String name;
/**
* 角色描述
*/
@Column(name = "[desc]")
private String desc;
/**
* 授权列表
*/
......
package cn.quantgroup.cashloanflowboss.api.role.model;
import lombok.Data;
/**
* @author Wang Xiangwei
* @version 2020/3/6
*/
@Data
public class RoleModel {
private Long id;
private String name;
}
package cn.quantgroup.cashloanflowboss.api.role.model;
import cn.quantgroup.cashloanflowboss.component.validator.constraints.NotEmpty;
import lombok.Data;
import java.util.List;
/**
* @author Wang Xiangwei
* @version 2020/3/2
*/
@Data
public class RoleModelVo {
private Long id;
private Long parentId;
@NotEmpty(message = "角色名不能为空")
private String name;
private String desc;
private List<Long> permissions;
}
package cn.quantgroup.cashloanflowboss.api.role.model;
import cn.quantgroup.cashloanflowboss.core.base.Pagination;
import lombok.Data;
/**
* @author Wang Xiangwei
* @version 2020/3/2
*/
@Data
public class RoleQueryModel extends Pagination {
private String name;
}
......@@ -3,7 +3,11 @@ package cn.quantgroup.cashloanflowboss.api.role.repository;
import cn.quantgroup.cashloanflowboss.api.role.entity.Role;
import cn.quantgroup.cashloanflowboss.core.persistence.CashLoanFlowBossDataSource;
import cn.quantgroup.cashloanflowboss.core.persistence.CashLoanFlowBossPubConfDataSource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
/**
......@@ -11,5 +15,10 @@ import org.springframework.stereotype.Repository;
*/
@CashLoanFlowBossPubConfDataSource
@Repository
public interface RoleRepository extends JpaRepository<Role, Long> {
public interface RoleRepository extends JpaRepository<Role, Long> , JpaSpecificationExecutor<Role> {
Role getByName(String name);
}
package cn.quantgroup.cashloanflowboss.api.role.service;
import cn.quantgroup.cashloanflowboss.api.role.entity.Role;
import cn.quantgroup.cashloanflowboss.api.role.repository.RoleRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.quantgroup.cashloanflowboss.api.role.model.RoleModel;
import cn.quantgroup.cashloanflowboss.api.role.model.RoleModelVo;
import cn.quantgroup.cashloanflowboss.api.role.model.RoleQueryModel;
import cn.quantgroup.cashloanflowboss.core.base.Result;
import org.springframework.data.domain.Page;
import java.util.List;
@Slf4j
@Service
public class RoleService {
/**
* @author Wang Xiangwei
* @version 2020/3/2
*/
public interface RoleService {
@Autowired
private RoleRepository roleRepository;
Result<Boolean> addRole(RoleModelVo roleModelVo);
/**
* 获取用户角色列表
*
* @param ids 角色ID
* @return
*/
public List<Role> getRoles(List<Long> ids) {
return this.roleRepository.findAll(ids);
}
Result<Page<Role>> getRoleByName(RoleQueryModel roleQueryModel);
Result<Boolean> modifyRole(RoleModelVo roleModelVo);
Result<Boolean> deleteRole(Long roleId);
Result<List<RoleModel>> getAll();
}
package cn.quantgroup.cashloanflowboss.api.role.service;
import cn.quantgroup.cashloanflowboss.api.mapping.UserRoleMappingRepository;
import cn.quantgroup.cashloanflowboss.api.permissionmodule.entity.Permission;
import cn.quantgroup.cashloanflowboss.api.permissionmodule.repository.PermissionRepository;
import cn.quantgroup.cashloanflowboss.api.role.entity.Role;
import cn.quantgroup.cashloanflowboss.api.role.model.RoleModel;
import cn.quantgroup.cashloanflowboss.api.role.model.RoleModelVo;
import cn.quantgroup.cashloanflowboss.api.role.model.RoleQueryModel;
import cn.quantgroup.cashloanflowboss.api.role.repository.RoleRepository;
import cn.quantgroup.cashloanflowboss.core.base.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Slf4j
@Service
public class RoleServiceImpl implements RoleService {
@Autowired
private RoleRepository roleRepository;
@Autowired
private PermissionRepository permissionRepository;
@Autowired
private UserRoleMappingRepository userRoleMappingRepository;
@Override
@Transactional(rollbackFor = Exception.class)
public Result<Boolean> addRole(RoleModelVo roleModelVo) {
final String LOG_PRE = "RoleServiceImpl.addRole";
log.info("{} 添加角色 roleModelVo={}", LOG_PRE, roleModelVo);
String name = roleModelVo.getName();
Role exist = roleRepository.getByName(name);
if (exist != null) {
log.error("{} 已存在角色 name={}", LOG_PRE, name);
return Result.buildFail(name + "已存在,请更换角色名");
}
Role role = new Role();
BeanUtils.copyProperties(roleModelVo, role);
Long parentId = roleModelVo.getParentId();
if (parentId != null) {
log.info("{},父角色查询 parentId={}", LOG_PRE, parentId);
if (!roleRepository.exists(parentId)) {
log.error("id为 {} 的父角色不存在");
return Result.buildFail("父角色不存在");
}
Role parent = roleRepository.getOne(parentId);
role.setParent(parent);
}
List<Long> permissions = roleModelVo.getPermissions();
if (CollectionUtils.isNotEmpty(permissions)) {
List<Permission> all = permissionRepository.findAll(permissions);
log.info("{} 权限ids={} 对应的权限size={}", LOG_PRE, permissions, all.size());
role.setPermissions(all);
}
roleRepository.save(role);
return Result.buildSuccess(true);
}
@Override
public Result<Page<Role>> getRoleByName(RoleQueryModel roleQueryModel) {
final String LOG_PRE = "RoleServiceImpl.getRoleByName";
log.info("{} 查询角色 roleQueryModel={}", LOG_PRE, roleQueryModel);
Page<Role> rolePage = roleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
if (StringUtils.isNotEmpty(roleQueryModel.getName())) {
predicates.add(criteriaBuilder.equal(root.get("name"), roleQueryModel.getName()));
}
criteriaQuery.where(criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])));
// 指定排序
criteriaQuery.orderBy(criteriaBuilder.desc(root.get("id")));
return criteriaQuery.getRestriction();
}, new PageRequest(roleQueryModel.getPageNumber(), roleQueryModel.getPageSize()));
return Result.buildSuccess(rolePage);
}
@Override
@Transactional(rollbackFor = Exception.class)
public Result<Boolean> modifyRole(RoleModelVo roleModelVo) {
final String LOG_PRE = "RoleServiceImpl.modifyRole";
log.info("{} 更新角色 roleQueryModel={}", LOG_PRE, roleModelVo);
Long id = roleModelVo.getId();
if (id == null) {
log.error("{} 更新的角色没有Id,无法更新 roleModelVo={}", LOG_PRE, roleModelVo);
return Result.buildFail("角色没有id,无法更新");
}
if (!roleRepository.exists(id)) {
log.error("{},没有对应的角色 id={}", LOG_PRE, id);
return Result.buildFail("没有对应的角色");
}
Role exist = roleRepository.getOne(id);
BeanUtils.copyProperties(roleModelVo, exist);
Long parentId = roleModelVo.getParentId();
if (parentId != null) {
if (!roleRepository.exists(parentId)) {
log.error("{} 不存在父角色 id={}", LOG_PRE, parentId);
return Result.buildFail("父角色不存在");
}
Role parent = roleRepository.getOne(parentId);
log.info("{},id={},parentId={},父角色为{}", LOG_PRE, id, parentId, parent);
exist.setParent(parent);
}
List<Long> permissions = roleModelVo.getPermissions();
if (CollectionUtils.isEmpty(permissions)) {
exist.setPermissions(null);
} else {
List<Permission> permissionList = permissionRepository.findAll(permissions);
exist.setPermissions(permissionList);
}
exist.setUpdateTime(new Date());
roleRepository.save(exist);
return Result.buildSuccess(true);
}
@Override
@Transactional(rollbackFor = Exception.class)
public Result<Boolean> deleteRole(Long roleId) {
final String LOG_PRE = "RoleServiceImpl.deleteRole";
log.info("{} 删除角色 roleId={}", LOG_PRE, roleId);
if (roleId == null) {
log.error("{} 删除角色失败 id为空");
return Result.buildFail("角色id不能为空");
}
if (roleRepository.exists(roleId)) {
roleRepository.delete(roleId);
userRoleMappingRepository.deleteAllByRoleId(roleId);
}
return Result.buildSuccess(true);
}
@Override
public Result<List<RoleModel>> getAll() {
List<Role> all = roleRepository.findAll();
List<RoleModel> list = new ArrayList<>();
if (CollectionUtils.isNotEmpty(all)) {
all.forEach(e -> {
RoleModel model = new RoleModel();
model.setId(e.getId());
model.setName(e.getName());
list.add(model);
});
}
return Result.buildSuccess(list);
}
}
package cn.quantgroup.cashloanflowboss.api.user.controller;
import cn.quantgroup.cashloanflowboss.api.user.dictionary.UserRank;
import cn.quantgroup.cashloanflowboss.api.user.dictionary.UserStatus;
import cn.quantgroup.cashloanflowboss.api.user.entity.User;
import cn.quantgroup.cashloanflowboss.api.user.model.QueryUserListModel;
import cn.quantgroup.cashloanflowboss.core.base.Pagination;
import cn.quantgroup.cashloanflowboss.api.user.model.RegisterUserFormModel;
import cn.quantgroup.cashloanflowboss.api.user.model.UserDetailInfo;
import cn.quantgroup.cashloanflowboss.api.user.model.UserInfoModel;
import cn.quantgroup.cashloanflowboss.api.user.model.*;
import cn.quantgroup.cashloanflowboss.api.user.service.UserService;
import cn.quantgroup.cashloanflowboss.component.security.annotiation.Security;
import cn.quantgroup.cashloanflowboss.component.validator.constraints.NotEmpty;
import cn.quantgroup.cashloanflowboss.core.base.Result;
import cn.quantgroup.cashloanflowboss.core.base.Tuple;
import cn.quantgroup.cashloanflowboss.spi.user.service.XyqbUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* Created by WeiWei on 2019/7/22.
......@@ -147,4 +138,64 @@ public class UserController {
return true;
}
/**
* 添加用户
*
* @param userModelVo
* @return
*/
// @Security(authorityId = "User.add")
@PostMapping(value = "/add")
public Result<Boolean> addUser(@RequestBody @Valid UserModelVo userModelVo) {
return userService.addUser(userModelVo);
}
@PutMapping("/modify")
// @Security(authorityId = "User.update")
public Result<Boolean> modifyUser(@RequestBody @Valid UserModelVo userModelVo) {
return userService.modifyUser(userModelVo);
}
/**
* 根据用户名、角色分页查询
*
* @param queryUserListModel
* @return
*/
@GetMapping("/list/get")
//@Security(authorityId = "User.list")
public Result<Page<User>> UserList(@Valid QueryUserListModel queryUserListModel) {
return userService.getUserList(queryUserListModel);
}
@GetMapping("/rank")
public Result<List<String>> userRank() {
List<String> list = new ArrayList<>();
for (UserRank value : UserRank.values()) {
if (value == UserRank.ADMINISTRATOR || value == UserRank.SUPER_ADMINISTRATOR) {
continue;
}
list.add(value.name());
}
return Result.buildSuccess(list);
}
@GetMapping("/status")
public Result<List<String>> userStatus() {
List<String> list = new ArrayList<>();
for (UserStatus value : UserStatus.values()) {
list.add(value.name());
}
return Result.buildSuccess(list);
}
@PutMapping("/update/password")
// @Security(authorityId = "User.update")
public Result<Boolean> modifyUser(@RequestBody @Valid UpdatePasswordParam param) {
return userService.updatePassword(param);
}
}
......@@ -3,13 +3,17 @@ package cn.quantgroup.cashloanflowboss.api.user.entity;
import cn.quantgroup.cashloanflowboss.api.role.entity.Role;
import cn.quantgroup.cashloanflowboss.api.user.dictionary.UserRank;
import cn.quantgroup.cashloanflowboss.api.user.dictionary.UserStatus;
import cn.quantgroup.cashloanflowboss.api.user.model.UserModelVo;
import cn.quantgroup.cashloanflowboss.core.persistence.Primary;
import cn.quantgroup.cashloanflowboss.utils.MD5Tools;
import lombok.Data;
import org.hibernate.annotations.Proxy;
import org.springframework.beans.BeanUtils;
import javax.persistence.*;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
* Created by WeiWei on 2019/7/22.
......@@ -17,6 +21,7 @@ import java.util.Set;
@Data
@Entity
@Table(name = "user")
@Proxy(lazy = false)
public class User extends Primary {
/**
......@@ -43,6 +48,9 @@ public class User extends Primary {
@Column(name = "channel_id")
private Long channelId;
@Column(name = "channel_name")
private String channelName;
/**
* 用户级别
*/
......@@ -70,4 +78,18 @@ public class User extends Primary {
@Column(name = "last_login_time")
private Date lastLoginTime;
public static User valueOf(UserModelVo userModelVo, Role role) {
if (userModelVo == null) {
return null;
}
User user = new User();
BeanUtils.copyProperties(userModelVo, user);
user.setPassword(MD5Tools.md5(userModelVo.getPassword()));
if (role != null) {
user.setRoles(Collections.singletonList(role));
}
return user;
}
}
......@@ -12,4 +12,6 @@ import lombok.Data;
@Data
public class QueryUserListModel extends Pagination {
private String nickname;
private Long roleId;
}
package cn.quantgroup.cashloanflowboss.api.user.model;
import cn.quantgroup.cashloanflowboss.component.validator.constraints.NotEmpty;
import lombok.Data;
/**
* @author Wang Xiangwei
* @version 2020/3/11
*/
@Data
public class UpdatePasswordParam {
@NotEmpty(message = "请输入账号")
private String username;
@NotEmpty(message = "请输入新密码")
private String newPassword;
}
package cn.quantgroup.cashloanflowboss.api.user.model;
import cn.quantgroup.cashloanflowboss.api.user.dictionary.UserRank;
import cn.quantgroup.cashloanflowboss.api.user.dictionary.UserStatus;
import cn.quantgroup.cashloanflowboss.component.validator.constraints.NotEmpty;
import lombok.Data;
/**
* @author Wang Xiangwei
* @version 2020/3/2
*/
@Data
public class UserModelVo {
private Long id;
/**
* 用户名
*/
@NotEmpty(message = "用户名不能为空")
private String username;
/**
* 昵称
*/
@NotEmpty(message = "用户昵称不能为空")
private String nickname;
/**
* 密码
*/
private String password;
/**
* 渠道ID
*/
private Long channelId;
/**
* 用户级别
*/
@NotEmpty(message = "用户级别不能为空")
private UserRank rank;
private Long roleId;
/**
* 用户状态
*/
@NotEmpty(message = "用户活跃状态不能为空")
private UserStatus status;
}
......@@ -3,8 +3,12 @@ package cn.quantgroup.cashloanflowboss.api.user.repository;
import cn.quantgroup.cashloanflowboss.api.user.entity.User;
import cn.quantgroup.cashloanflowboss.core.persistence.CashLoanFlowBossDataSource;
import cn.quantgroup.cashloanflowboss.core.persistence.CashLoanFlowBossPubConfDataSource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
/**
......@@ -23,4 +27,15 @@ public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificat
User getUserByUsername(String username);
@Query(value = "select user.* from user,user_role_mapping urm where urm.user_id= user.id "+
"and IF ( ?1 =\"\",1=1, user.nickname = ?1) " +
"and IF (?2 =\"\", 1=1, urm.role_id= ?2) "
+ "ORDER BY ?#{#pageable}",
countQuery = "select count(user.id) from user,user_role_mapping urm where urm.user_id= user.id "+
"and IF ( ?1 =\"\",1=1, user.nickname = ?1) " +
"and IF (?2 =\"\", 1=1, urm.role_id= ?2) ",
nativeQuery = true)
Page<User> getUserByNicknameAndRoleId( String nickname, String roleId, Pageable pageable);
}
package cn.quantgroup.cashloanflowboss.api.user.service;
import cn.quantgroup.cashloanflowboss.api.user.entity.User;
import cn.quantgroup.cashloanflowboss.api.user.model.QueryUserListModel;
import cn.quantgroup.cashloanflowboss.api.user.model.UserDetailInfo;
import cn.quantgroup.cashloanflowboss.api.user.model.UserInfoModel;
import cn.quantgroup.cashloanflowboss.api.user.model.*;
import cn.quantgroup.cashloanflowboss.api.user.model.UpdatePasswordParam;
import cn.quantgroup.cashloanflowboss.core.base.Result;
import cn.quantgroup.cashloanflowboss.core.base.Tuple;
import org.springframework.data.domain.Page;
......@@ -33,4 +33,26 @@ public interface UserService {
User saveUserInfo(UserInfoModel user);
Tuple<Boolean,String> cleanUserActiveOrder(String mobile);
/**
* 添加用户,账号校验
* @param
* @return
*/
Result<Boolean> addUser(UserModelVo userModelVo);
/**
* 更新用户,账号不能更改
* @param
* @return
*/
Result<Boolean> modifyUser(UserModelVo userModelVo);
Result<Page<User>> getUserList(QueryUserListModel queryUserListModel);
Result<Boolean> updatePassword(UpdatePasswordParam updatePasswordParam);
}
package cn.quantgroup.cashloanflowboss.api.user.service;
import cn.quantgroup.cashloanflowboss.api.login.model.Principal;
import cn.quantgroup.cashloanflowboss.api.role.entity.Role;
import cn.quantgroup.cashloanflowboss.api.role.repository.RoleRepository;
import cn.quantgroup.cashloanflowboss.api.user.dictionary.UserStatus;
import cn.quantgroup.cashloanflowboss.api.user.entity.User;
import cn.quantgroup.cashloanflowboss.api.user.model.QueryUserListModel;
import cn.quantgroup.cashloanflowboss.api.user.model.UserDetailInfo;
import cn.quantgroup.cashloanflowboss.api.user.model.UserInfoModel;
import cn.quantgroup.cashloanflowboss.api.user.model.*;
import cn.quantgroup.cashloanflowboss.api.user.repository.UserRepository;
import cn.quantgroup.cashloanflowboss.core.Application;
import cn.quantgroup.cashloanflowboss.core.asserts.Assert;
import cn.quantgroup.cashloanflowboss.core.base.Result;
import cn.quantgroup.cashloanflowboss.core.base.Tuple;
import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationStatus;
import cn.quantgroup.cashloanflowboss.spi.clf.entity.ClfChannelConfiguration;
import cn.quantgroup.cashloanflowboss.spi.clf.repository.ClfChannelConfigurationRepository;
import cn.quantgroup.cashloanflowboss.spi.user.service.XyqbUserService;
import cn.quantgroup.cashloanflowboss.spi.xyqb.service.XYQBCenterService;
import cn.quantgroup.cashloanflowboss.utils.MD5Tools;
......@@ -21,20 +24,20 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.*;
/**
* Created by WeiWei on 2019/7/22.
*/
@Slf4j
@Service
public class UserServiceImpl implements UserService{
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
......@@ -43,6 +46,11 @@ public class UserServiceImpl implements UserService{
@Autowired
private XyqbUserService xyqbUserService;
@Autowired
private RoleRepository roleRepository;
@Autowired
private ClfChannelConfigurationRepository clfChannelConfigurationRepository;
/**
......@@ -197,12 +205,143 @@ public class UserServiceImpl implements UserService{
@Async("commonAsyncExecutor")
//@OperationAnno(channelNo = "#this[0]", opt = OptEnumName.USER_ORDER_CLEAN, succSPEL = "#this.key", optDetailSPEL = "#this.value")
@Override
public Tuple<Boolean,String> cleanUserActiveOrder(String mobile) {
public Tuple<Boolean, String> cleanUserActiveOrder(String mobile) {
XUser user = xyqbUserService.findUserByPhoneNo(mobile);
if (user == null) {
log.info("cleanUserOrder,清除用户活跃订单失败,未找到用户 phoneNo={}", mobile);
return new Tuple<>(false,"清除用户活跃订单失败,未找到用户");
return new Tuple<>(false, "清除用户活跃订单失败,未找到用户");
}
return xyqbCenterService.cleanUserActiveOrder(user.getId());
}
@Override
@Transactional
public Result<Boolean> addUser(UserModelVo userModelVo) {
final String LOG_PRE = "UserServiceImpl.addUser";
log.info("{} 添加用户 rank={}", LOG_PRE, userModelVo);
String username = userModelVo.getUsername();
User exist = this.getUser(username);
if (exist != null) {
log.error("{},账户已存在 userName={}", LOG_PRE, username);
return Result.buildFail(username + " 账户已存在");
}
Long roleId = userModelVo.getRoleId();
Role role = null;
if (roleId != null) {
if (!roleRepository.exists(roleId)) {
log.error("{},不存在对应的角色 roleId={}", LOG_PRE, roleId);
return Result.buildFail("不存在对应的角色");
}
role = roleRepository.getOne(roleId);
}
User user = User.valueOf(userModelVo, role);
//渠道检查
Long channelId = user.getChannelId();
if (channelId != null) {
ClfChannelConfiguration configuration = clfChannelConfigurationRepository.findByRegisteredFrom(channelId);
if (configuration == null) {
log.error("{},渠道不存在 channelId={}", LOG_PRE, channelId);
return Result.buildFail("channelId=" + channelId + "的渠道不存在");
}
user.setChannelName(configuration.getChannelName());
}
userRepository.save(user);
return Result.buildSuccess(true);
}
@Override
@Transactional
public Result<Boolean> modifyUser(UserModelVo userModelVo) {
final String LOG_PRE = "UserServiceImpl.modifyUser";
Long id = userModelVo.getId();
if (id == null) {
log.error("{} 缺少主键id, userModelVo={}", LOG_PRE, userModelVo);
return Result.buildFail("缺少用户Id");
}
if (!userRepository.exists(id)) {
log.error("{}不存在相应的用户,不能更新 userModelVo={}", LOG_PRE, userModelVo);
return Result.buildFail("不存在相应的用户,不能更新");
}
User exist = userRepository.getOne(id);
String password = exist.getPassword();
String existUsername = exist.getUsername();
String username = userModelVo.getUsername();
if (!existUsername.equals(username)) {
log.error("{} 账号不能修改,userModelVo={}", LOG_PRE, userModelVo);
return Result.buildFail("账号不能修改");
}
Long roleId = userModelVo.getRoleId();
Role role = null;
if (roleId != null) {
if (!roleRepository.exists(roleId)) {
log.error("{},不存在对应的角色 roleId={}", LOG_PRE, roleId);
return Result.buildFail("不存在对应的角色");
}
role = roleRepository.getOne(roleId);
}
BeanUtils.copyProperties(userModelVo, exist);
exist.setPassword(password);
Long channelId = exist.getChannelId();
//渠道检查
if (channelId != null) {
ClfChannelConfiguration configuration = clfChannelConfigurationRepository.findByRegisteredFrom(channelId);
if (configuration == null) {
log.error("{},渠道不存在 channelId={}", LOG_PRE, channelId);
return Result.buildFail("channelId=" + channelId + "的渠道不存在");
}
exist.setChannelName(configuration.getChannelName());
}
//exist.setPassword(MD5Tools.md5(userModelVo.getPassword()));
exist.setRoles(Collections.singletonList(role));
exist.setUpdateTime(new Date());
userRepository.save(exist);
return Result.buildSuccess(true);
}
@Override
public Result<Page<User>> getUserList(QueryUserListModel queryUserListModel) {
final String LOG_PRE = "UserServiceImpl.getUserList";
log.info("{},查询用户列表,queryUserListModel={}", LOG_PRE, queryUserListModel);
String nickname = queryUserListModel.getNickname();
Long roleId = queryUserListModel.getRoleId();
PageRequest pageRequest = new PageRequest(queryUserListModel.getPageNumber(), queryUserListModel.getPageSize(), new Sort(Sort.Direction.DESC, "id"));
Page<User> userPage = userRepository.getUserByNicknameAndRoleId(nickname == null ? "" : nickname, roleId == null ? "" : roleId.toString(),
pageRequest);
return Result.buildSuccess(userPage);
}
@Override
public Result<Boolean> updatePassword(UpdatePasswordParam updatePasswordParam) {
String logPre = "UserServiceImpl.updatePassword";
log.info("{},修改密码,updatePasswordParam={}", logPre, updatePasswordParam);
User user = userRepository.getUserByUsername(updatePasswordParam.getUsername());
if (Objects.isNull(user)) {
log.info("{} 不存在 {} 用户", logPre, updatePasswordParam.getUsername());
return Result.buildFail("用户不存在,不能修改密码");
}
String newPassword = MD5Tools.md5(updatePasswordParam.getNewPassword());
String oldPassword = user.getPassword();
if(newPassword.equals(oldPassword)){
return Result.buildFail("新密码和旧密码相同");
}
user.setPassword(newPassword);
userRepository.save(user);
return Result.buildSuccess(true);
}
}
......@@ -194,11 +194,17 @@ public class Application implements ApplicationContextAware, ServletContextAware
if (Objects.nonNull(request)) {
HttpSession session = request.getSession();
if (Objects.nonNull(session)) {
// log.info("后来访问获取sessionId={},requestIp={}", session.getId(), IpUtil.getRemoteIP(request));
log.info(" 后来访问获取sessionId={},requestIp={}", session.getId(), IpUtil.getRemoteIP(request));
return session;
}else {
log.info("session 为空");
}
}
return null;
}
public static HttpServletRequest getHttpServletRequest() {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
}
\ No newline at end of file
package cn.quantgroup.cashloanflowboss.core.configuration;
package cn.quantgroup.cashloanflowboss.core.configuration.web;
import cn.quantgroup.cashloanflowboss.core.Application;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
......@@ -8,6 +10,7 @@ import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
......@@ -17,15 +20,20 @@ import java.util.List;
*
* @author: suntao
*/
@Configuration
//@Configuration
public class BossCorsConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
HttpServletRequest request = Application.getHttpServletRequest();
String origin = request.getHeader("Origin");
registry.addMapping("/**")
.allowedOrigins("*")
.allowedOrigins(origin)
.allowedMethods("GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "TRACE")
.maxAge(7200)
.allowCredentials(true);
}
......
package cn.quantgroup.cashloanflowboss.core.configuration.web;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @description: 跨域
* @author:tao
* @create: 2020-01-06 18:50
*/
@Slf4j
@WebFilter(urlPatterns = "/*", filterName = "CORSFilter")
public class CorsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
String origin = req.getHeader("Origin");
if(origin == null) {
origin = req.getHeader("Referer");
}
resp.setHeader("Access-Control-Allow-Origin", origin);//这里不能写*,*代表接受所有域名访问,如写*则下面一行代码无效。谨记
resp.setHeader("Access-Control-Allow-Credentials", "true");//true代表允许携带cookie
//允许请求的类型
resp.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");
//允许的请求头字段
resp.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, cluster");
//设置预检请求的有效期
//浏览器同源策略:出于安全考虑,浏览器限制跨域的http请求。怎样限制呢?通过发送两次请求:预检请求、用户请求。
//1、预检请求作用:获知服务器是否允许该跨域请求:如果允许,才发起第二次真实的请求;如果不允许,则拦截第二次请求
//2、单位:s,在此期间不用发送预检请求。
//3、若为0:表示每次请求都发送预检请求,每个ajax请求之前都会先发送预检请求。
resp.setHeader("Access-Control-Max-Age", "3600");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
package cn.quantgroup.cashloanflowboss.spi.clf.entity;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
/**
* @author Wang Xiangwei
* @version 2020/2/25
*/
@Data
@Entity
@Table(name = "channel_apply_info_strategy", catalog = "cash_loan_flow")
public class ChannelApplyInfoStrategy implements Serializable {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "channel_id")
private Long channelId;
@Column(name = "channel_name")
private String channelName;
@Column(name = "channel_user_id")
private Boolean channelUserId;
@Column(name = "address")
private Boolean address;
@Column(name = "contact")
private Boolean contact;
@Column(name = "education")
private Boolean education;
@Column(name = "income")
private Boolean income;
@Column(name = "email")
private Boolean email;
@Column(name = "occupation")
private Boolean occupation;
@Column(name = "ocr")
private Boolean ocr;
@Column(name = "mobile")
private Boolean mobile;
@Column(name = "device")
private Boolean device;
@Column(name = "contacts_book")
private Boolean contactsBook;
}
package cn.quantgroup.cashloanflowboss.spi.clf.repository;
import cn.quantgroup.cashloanflowboss.core.persistence.CashLoanFlowDataSource;
import cn.quantgroup.cashloanflowboss.spi.clf.entity.ChannelApplyInfoStrategy;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* @author Wang Xiangwei
* @version 2020/2/25
*/
@CashLoanFlowDataSource
@Repository
public interface ChannelApplyInfoStrategyRepository extends JpaRepository<ChannelApplyInfoStrategy, Long> {
ChannelApplyInfoStrategy findByChannelId(Long channelId);
}
......@@ -3,6 +3,7 @@ package cn.quantgroup.cashloanflowboss.spi.clf.service;
import cn.quantgroup.cashloanflowboss.api.order.model.OrderBaseModel;
import cn.quantgroup.cashloanflowboss.spi.clf.entity.*;
import org.springframework.data.domain.Page;
import java.util.List;
/**
......@@ -36,4 +37,11 @@ public interface CLFCenterService {
ClfOrderCallBack findOrderCallBackByByCallbackStatusAndChannelId(String name, Long channelId);
void reloadKAConfiguration();
ChannelApplyInfoStrategy findChannelApplyInfoStrategyByChannelId(Long channelId);
void saveChannelApplyInfoStrategy(ChannelApplyInfoStrategy channelApplyInfoStrategy);
List<ClfChannelConfiguration> findAll();
}
......@@ -21,7 +21,7 @@ import java.util.Objects;
* @author: suntao
*/
@Service
public class CLFCenterServiceImpl implements CLFCenterService{
public class CLFCenterServiceImpl implements CLFCenterService {
@Autowired
......@@ -44,6 +44,8 @@ public class CLFCenterServiceImpl implements CLFCenterService{
@Autowired
private ClfOrderCallbackRepository clfOrderCallbackRepository;
@Autowired
private ChannelApplyInfoStrategyRepository channelApplyInfoStrategyRepository;
@Override
......@@ -143,4 +145,24 @@ public class CLFCenterServiceImpl implements CLFCenterService{
public void reloadKAConfiguration() {
clfCenter.reloadKASetting("");
}
@Override
public ChannelApplyInfoStrategy findChannelApplyInfoStrategyByChannelId(Long channelId) {
return channelApplyInfoStrategyRepository.findByChannelId(channelId);
}
@Override
public void saveChannelApplyInfoStrategy(ChannelApplyInfoStrategy channelApplyInfoStrategy) {
channelApplyInfoStrategyRepository.saveAndFlush(channelApplyInfoStrategy);
}
@Override
public List<ClfChannelConfiguration> findAll() {
Iterable<ClfChannelConfiguration> all = clfChannelConfigurationRepository.findAll();
List<ClfChannelConfiguration> list = new ArrayList<>();
if(all != null){
all.forEach(e->list.add(e));
}
return list;
}
}
package cn.quantgroup.cashloanflowboss.spi.xyqb.client;
import cn.quantgroup.cashloanflowboss.api.order.model.RepaymentPlansResultModel;
import cn.quantgroup.cashloanflowboss.api.order.model.XyqbCurrentOrderStatusServiceResultModel;
import cn.quantgroup.cashloanflowboss.api.order.model.XyqbHistoryOrderStatusServiceResultModel;
import cn.quantgroup.cashloanflowboss.core.base.ServiceResult;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
......@@ -26,6 +28,9 @@ public interface XYQBCenter {
@PostMapping(value = "/ex/ka/order/status/history", consumes = "application/x-www-form-urlencoded")
ServiceResult<XyqbHistoryOrderStatusServiceResultModel> getXyqbOrderHistoryStatus(@RequestParam Map paramMap);
@GetMapping(value = "/ex/ka/loan_plan/query", consumes = "application/x-www-form-urlencoded")
ServiceResult<RepaymentPlansResultModel> getXyqbRepaymentPlans(@RequestParam Map paramMap);
@Component
class Fallback implements XYQBCenter {
......@@ -44,7 +49,10 @@ public interface XYQBCenter {
return null;
}
@Override
public ServiceResult<RepaymentPlansResultModel> getXyqbRepaymentPlans(Map paramMap) {
return null;
}
}
}
package cn.quantgroup.cashloanflowboss.spi.xyqb.service;
import cn.quantgroup.cashloanflowboss.api.order.model.RepaymentPlansResultModel;
import cn.quantgroup.cashloanflowboss.api.order.model.XyqbCurrentOrderStatusServiceResultModel;
import cn.quantgroup.cashloanflowboss.api.order.model.XyqbHistoryOrderStatusServiceResultModel;
import cn.quantgroup.cashloanflowboss.core.base.ServiceResult;
......@@ -57,4 +58,6 @@ public interface XYQBCenterService {
boolean payResultNotify(Long loanId, Boolean expectPayResult);
Tuple<Boolean,String> cleanUserActiveOrder(Long userId);
ServiceResult<RepaymentPlansResultModel> findRepaymentPlan(Long loanId);
}
package cn.quantgroup.cashloanflowboss.spi.xyqb.service;
import cn.quantgroup.cashloanflowboss.api.order.model.RepaymentPlansResultModel;
import cn.quantgroup.cashloanflowboss.api.order.model.XyqbCurrentOrderStatusServiceResultModel;
import cn.quantgroup.cashloanflowboss.api.order.model.XyqbHistoryOrderStatusServiceResultModel;
import cn.quantgroup.cashloanflowboss.core.Application;
......@@ -28,6 +29,8 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.Map;
import java.util.Objects;
import java.math.BigDecimal;
import java.util.*;
/**
* Created by WeiWei on 2019/8/12.
......@@ -295,4 +298,13 @@ public class XYQBCenterServiceImpl implements XYQBCenterService {
boolean result = (Objects.nonNull(resp) && resp.containsKey("code")) ? "0000".equals(resp.get("code")) : false;
return new Tuple<>(result,result?"清除用户活跃订单成功":"清除用户活跃订单失败");
}
@Override
public ServiceResult<RepaymentPlansResultModel> findRepaymentPlan(Long loanId) {
Map paramMap = Maps.newHashMap();
paramMap.put("loanId", loanId);
paramMap = SignUtil.sign(SignUtil.KA_API_KEY, paramMap);
log.info("查询还款计划,请求参数 paramMap={}", paramMap);
return xyqbCenter.getXyqbRepaymentPlans(paramMap);
}
}
package cn.quantgroup.cashloanflowboss.json;
import cn.quantgroup.cashloanflowboss.api.order.model.XyqbCurrentOrderStatusServiceResultModel;
import cn.quantgroup.cashloanflowboss.api.permissionmodule.entity.Permission;
import cn.quantgroup.cashloanflowboss.core.base.ServiceResult;
import cn.quantgroup.cashloanflowboss.spi.clf.entity.ClfCallbackConfiguration;
import cn.quantgroup.cashloanflowboss.spi.clf.entity.ClfChannelConfiguration;
import cn.quantgroup.cashloanflowboss.spi.clf.entity.ClfOrderCallBack;
import cn.quantgroup.cashloanflowboss.spi.clf.model.CallbackRouter;
import cn.quantgroup.cashloanflowboss.spi.clf.model.EncType;
import cn.quantgroup.cashloanflowboss.spi.clf.model.KANoticeType;
import cn.quantgroup.cashloanflowboss.utils.JSONTools;
import com.fasterxml.jackson.core.type.TypeReference;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
import java.sql.Timestamp;
/**
* @description: test
......@@ -30,4 +34,58 @@ public class JsonTest {
System.out.println(serviceResult);
}
@Test
public void cClfChannelConfigurationTte() {
ClfChannelConfiguration clfChannelConfiguration = new ClfChannelConfiguration();
clfChannelConfiguration.setChannelName("融3");
clfChannelConfiguration.setChannelCode("R360");
clfChannelConfiguration.setRegisteredFrom(333L);
clfChannelConfiguration.setIsActive(true);
clfChannelConfiguration.setCreatedAt(new Timestamp(System.currentTimeMillis()));
clfChannelConfiguration.setIsRequestStandard(true);
clfChannelConfiguration.setEncType(EncType.AES);
clfChannelConfiguration.setAesKey("");
clfChannelConfiguration.setMd5Key("");
clfChannelConfiguration.setSpiderCenterChannelCode("");
clfChannelConfiguration.setSpiderCenterMerchantChannelCode("");
clfChannelConfiguration.setAuthOption("");
clfChannelConfiguration.setLoginPageUrl("");
clfChannelConfiguration.setXyqbProductId("1");
System.out.println(JSONTools.serialize(clfChannelConfiguration));
}
@Test
public void cClfChannelCallbackTte() {
ClfCallbackConfiguration clfCallbackConfiguration = new ClfCallbackConfiguration();
clfCallbackConfiguration.setChannelId(333L);
clfCallbackConfiguration.setIsLoanMakeup(false);
clfCallbackConfiguration.setIsRepayMakeup(false);
clfCallbackConfiguration.setLoanMakeupStrategy("");
clfCallbackConfiguration.setRepayMakeupStrategy("");
clfCallbackConfiguration.setIsActive(true);
clfCallbackConfiguration.setOnlyNewUser(false);
clfCallbackConfiguration.setCallbackServiceName("r");
clfCallbackConfiguration.setCallbackNoPushProgress("rr");
clfCallbackConfiguration.setPreProgress("rr");
clfCallbackConfiguration.setRetryMaxTimes(5L);
clfCallbackConfiguration.setCallbackRouter(CallbackRouter.API);
System.out.println(JSONTools.serialize(clfCallbackConfiguration));
}
@Test
public void cClfChannelCallbackTte3() {
ClfOrderCallBack orderCallBack = new ClfOrderCallBack();
orderCallBack.setCallbackStatus(KANoticeType.FUAD_ASSIFN_SUCC);
orderCallBack.setRegisteredFrom(0L);
orderCallBack.setCallbackUrl("");
orderCallBack.setIsActive(false);
orderCallBack.setCreatedAt(new Timestamp(new java.util.Date().getTime()));
System.out.println(JSONTools.serialize(orderCallBack));
}
}
package cn.quantgroup.cashloanflowboss.service.contract;
import cn.quantgroup.cashloanflowboss.CashLoanFlowBossApplicationTests;
import cn.quantgroup.cashloanflowboss.api.channel.model.ChannelConfVo;
import cn.quantgroup.cashloanflowboss.api.channel.service.ChannelConfService;
import cn.quantgroup.cashloanflowboss.spi.clf.entity.ChannelApplyInfoStrategy;
import cn.quantgroup.cashloanflowboss.spi.clf.service.CLFCenterService;
import cn.quantgroup.cashloanflowboss.spi.xyqb.service.XYQBCenterService;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
/**
* function:
* date: 2019/12/6
*
* @author: suntao
*/
public class ChannelApplyInfoStrategyTest extends CashLoanFlowBossApplicationTests {
@Autowired
private CLFCenterService clfCenterService;
@Autowired
private ChannelConfService channelConfService;
@Test
public void test() {
ChannelApplyInfoStrategy strategy = new ChannelApplyInfoStrategy();
strategy.setAddress(true);
strategy.setChannelId(12L);
strategy.setChannelName("测试");
strategy.setContact(false);
strategy.setChannelUserId(false);
strategy.setContactsBook(true);
strategy.setDevice(true);
strategy.setEducation(true);
strategy.setEmail(false);
strategy.setIncome(true);
strategy.setMobile(true);
clfCenterService.saveChannelApplyInfoStrategy(strategy);
ChannelApplyInfoStrategy strategy1 = clfCenterService.findChannelApplyInfoStrategyByChannelId(12L);
strategy.setId(strategy1.getId());
strategy.setChannelName("测试更新");
clfCenterService.saveChannelApplyInfoStrategy(strategy);
}
@Test
public void testGetChannelInfo(){
ChannelConfVo channelConf = channelConfService.getChannelConf(159881L);
ChannelApplyInfoStrategy channelApplyInfoStrategy = channelConf.getBasicInfo().getChannelApplyInfoStrategy();
channelApplyInfoStrategy.setChannelUserId(true);
channelConfService.editChannelConfInfo(channelConf);
//数据恢复
channelApplyInfoStrategy.setChannelUserId(false);
channelConfService.editChannelConfInfo(channelConf);
}
}
package cn.quantgroup.cashloanflowboss.service.contract;
import cn.quantgroup.cashloanflowboss.CashLoanFlowBossApplicationTests;
import cn.quantgroup.cashloanflowboss.api.role.entity.Role;
import cn.quantgroup.cashloanflowboss.api.role.model.RoleQueryModel;
import cn.quantgroup.cashloanflowboss.api.role.service.RoleService;
import cn.quantgroup.cashloanflowboss.core.base.Result;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
/**
* @author Wang Xiangwei
* @version 2020/3/2
*/
public class RoleTest extends CashLoanFlowBossApplicationTests {
@Autowired
private RoleService roleService;
@Test
public void roleTest(){
// RoleModelVo roleModel = new RoleModelVo();
// roleModel.setName("测试角色");
// roleModel.setDesc("测试");
// Result<Role> roleResult = roleService.addRole(roleModel);
RoleQueryModel roleQueryModel = new RoleQueryModel();
// roleQueryModel.setName("测试角色");
roleQueryModel.setPageNumber(1);
roleQueryModel.setPageSize(5);
Result<Page<Role>> roleByName = roleService.getRoleByName(roleQueryModel);
// roleModel.setName("测试");
// Long id = roleResult.getData().getId();
// roleModel.setId(id);
// roleService.modifyRole(roleModel);
//
// Result<Boolean> booleanResult = roleService.deleteRole(roleResult.getData().getId());
}
}
package cn.quantgroup.cashloanflowboss.service.contract;
import cn.quantgroup.cashloanflowboss.CashLoanFlowBossApplicationTests;
import cn.quantgroup.cashloanflowboss.api.user.entity.User;
import cn.quantgroup.cashloanflowboss.api.user.model.QueryUserListModel;
import cn.quantgroup.cashloanflowboss.api.user.service.UserService;
import cn.quantgroup.cashloanflowboss.core.base.Result;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
/**
* @author Wang Xiangwei
* @version 2020/3/2
*/
public class UserTest extends CashLoanFlowBossApplicationTests {
@Autowired
UserService userService;
@Test
public void testUser(){
// UserModelVo userModel = new UserModelVo();
//
// userModel.setNickname("测试账号");
// userModel.setUsername("test11111111111");
// userModel.setPassword("123456");
// userModel.setRank(UserRank.OPERATOR);
// userModel.setRoleId(9L);
// userModel.setStatus(UserStatus.ENABLED);
// Result<User> result = userService.addUser(userModel);
//
// User rank = result.getData();
//
// userModel.setId(rank.getId());
// userModel.setNickname("测试账号123");
//
// Result<User> result1 = userService.modifyUser(userModel);
QueryUserListModel model = new QueryUserListModel();
// model.setNickname("小丽");
model.setRoleId(9L);
model.setPageNumber(1);
model.setPageSize(4);
Result<Page<User>> userList = userService.getUserList(model);
System.out.println(userList.getData().getContent().size());
// userService.removeUser(rank.getId());
}
}
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