第一版

This commit is contained in:
刘行 2021-02-01 20:19:55 +08:00
commit 1e5c5a14fa
68 changed files with 4316 additions and 0 deletions

43
.gitignore vendored Normal file
View File

@ -0,0 +1,43 @@
# Default ignored files
/shelf/
/.idea/workspace.xml
# Datasource local storage ignored files
/../../../../../../:\Code\IdeaProjects\SpringProjects\Survey\.idea/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/
### Example user template template
### Example user template
# IntelliJ project files
.idea
.mvn
*.iml
out
gen
### Java template
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

21
HELP.md Normal file
View File

@ -0,0 +1,21 @@
# Getting Started
### Reference Documentation
For further reference, please consider the following sections:
* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.4.2/maven-plugin/reference/html/)
* [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.4.2/maven-plugin/reference/html/#build-image)
* [Spring Web](https://docs.spring.io/spring-boot/docs/2.4.2/reference/htmlsingle/#boot-features-developing-web-applications)
* [Spring Data MongoDB](https://docs.spring.io/spring-boot/docs/2.4.2/reference/htmlsingle/#boot-features-mongodb)
### Guides
The following guides illustrate how to use some features concretely:
* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
* [Building REST services with Spring](https://spring.io/guides/tutorials/bookmarks/)
* [Accessing Data with MongoDB](https://spring.io/guides/gs/accessing-data-mongodb/)

322
mvnw vendored Normal file
View File

@ -0,0 +1,322 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ]; then
if [ -f /etc/mavenrc ]; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ]; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false
darwin=false
mingw=false
case "$(uname)" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true ;;
Darwin*)
darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="$(/usr/libexec/java_home)"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ]; then
if [ -r /etc/gentoo-release ]; then
JAVA_HOME=$(java-config --jre-home)
fi
fi
if [ -z "$M2_HOME" ]; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ]; do
ls=$(ls -ld "$PRG")
link=$(expr "$ls" : '.*-> \(.*\)$')
if expr "$link" : '/.*' >/dev/null; then
PRG="$link"
else
PRG="$(dirname "$PRG")/$link"
fi
done
saveddir=$(pwd)
M2_HOME=$(dirname "$PRG")/..
# make it fully qualified
M2_HOME=$(cd "$M2_HOME" && pwd)
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=$(cygpath --unix "$M2_HOME")
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=$(cygpath --unix "$JAVA_HOME")
[ -n "$CLASSPATH" ] &&
CLASSPATH=$(cygpath --path --unix "$CLASSPATH")
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw; then
[ -n "$M2_HOME" ] &&
M2_HOME="$( (
cd "$M2_HOME"
pwd
))"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="$( (
cd "$JAVA_HOME"
pwd
))"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="$(which javac)"
if [ -n "$javaExecutable" ] && ! [ "$(expr \"$javaExecutable\" : '\([^ ]*\)')" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=$(which readlink)
if [ ! $(expr "$readLink" : '\([^ ]*\)') = "no" ]; then
if $darwin; then
javaHome="$(dirname \"$javaExecutable\")"
javaExecutable="$(cd \"$javaHome\" && pwd -P)/javac"
else
javaExecutable="$(readlink -f \"$javaExecutable\")"
fi
javaHome="$(dirname \"$javaExecutable\")"
javaHome=$(expr "$javaHome" : '\(.*\)/bin')
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ]; then
if [ -n "$JAVA_HOME" ]; then
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="$(which java)"
fi
fi
if [ ! -x "$JAVACMD" ]; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ]; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]; then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ]; do
if [ -d "$wdir"/.mvn ]; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=$(
cd "$wdir/.."
pwd
)
fi
# end of workaround
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' <"$1")"
fi
}
BASE_DIR=$(find_maven_basedir "$(pwd)")
if [ -z "$BASE_DIR" ]; then
exit 1
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
else
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
fi
while IFS="=" read key value; do
case "$key" in wrapperUrl)
jarUrl="$value"
break
;;
esac
done <"$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if $cygwin; then
wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath")
fi
if command -v wget >/dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget "$jarUrl" -O "$wrapperJarPath"
else
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
fi
elif command -v curl >/dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl -o "$wrapperJarPath" "$jarUrl" -f
else
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaClass=$(cygpath --path --windows "$javaClass")
fi
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=$(cygpath --path --windows "$M2_HOME")
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME")
[ -n "$CLASSPATH" ] &&
CLASSPATH=$(cygpath --path --windows "$CLASSPATH")
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR")
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"

182
mvnw.cmd vendored Normal file
View File

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

85
pom.xml Normal file
View File

@ -0,0 +1,85 @@
<?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.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>survey</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>survey</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<skipTest>true</skipTest>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.kafka/spring-kafka -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>2.6.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.4.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

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

View File

@ -0,0 +1,91 @@
package com.example.survey.config;
import com.alibaba.fastjson.JSON;
import com.example.survey.util.TokenUtil;
import com.example.survey.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;
/**
* @author Pope
* 权限过滤器
*/
@Configuration
public class AuthFilterConfig implements Filter {
/**
* 不需要token就能访问的路由
*/
private static final Set<String> URIS = new HashSet<String>() {{
add("/user/login");
add("/user/signup");
// add("/user/userRole");
// add("/role/role");
}};
@Autowired
TokenUtil tokenUtil;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* 对请求进行过滤
* 1.是否有token
* 2.token所对应的权限是否能够访问对应请求
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String method = request.getMethod();
String uri = request.getRequestURI();
System.out.println(method + " : " + uri);
//判断是否需要token
if (URIS.contains(uri)) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
String token = request.getHeader("Authorization");
if (token == null) {
returnJson(response, new ResultVo(ResultVo.FAILED, "请先登录!", null));
return;
}
if (!tokenUtil.isPass(token,uri,method)) {
returnJson(response, new ResultVo(ResultVo.FAILED, "权限不够!", null));
return;
}
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
public static void returnJson(HttpServletResponse response, ResultVo resultVo) {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=utf-8");
try (PrintWriter writer = response.getWriter()) {
writer.print(JSON.toJSONString(resultVo));
} catch (IOException e) {
//由于统一拦截了异常所以不需要抛出
}
}
}

View File

@ -0,0 +1,41 @@
package com.example.survey.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @author Pope
*/
@Configuration
public class RedisConfig {
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}

View File

@ -0,0 +1,110 @@
package com.example.survey.controller;
import com.example.survey.entity.InvestigationRecord;
import com.example.survey.service.InvestigationRecordService;
import com.example.survey.vo.InvestigationRecordVo;
import com.example.survey.vo.ResultVo;
import com.example.survey.vo.ReviewVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Pope
*/
@RestController
@RequestMapping("/investigationRecord")
public class InvestigationRecordController {
@Autowired
private InvestigationRecordService investigationRecordService;
@PostMapping("/investigationRecord")
public ResultVo addInvestigationRecord(@RequestBody InvestigationRecordVo investigationRecordVo) {
ResultVo resultVo = new ResultVo();
boolean result = investigationRecordService.addInvestigationRecord(investigationRecordVo);
if (result) {
resultVo.setCode(ResultVo.SUCCESS);
resultVo.setMsg("提交成功");
} else {
resultVo.setCode(ResultVo.FAILED);
resultVo.setMsg("提交失败");
}
resultVo.setData(result);
return resultVo;
}
@GetMapping("/underReviewRecord")
public ResultVo getUnderReviewRecord(@RequestParam(value = "currentPage") Integer currentPage,
@RequestParam(value = "pageSize", defaultValue = "30") Integer pageSize,
@RequestParam(value = "investigatorPhone", required = false) String investigatorPhone,
@RequestParam(value = "state", required = false) String state,
@RequestParam(value = "idNumber", required = false) String idNumber,
@RequestParam(value = "version", required = false) String version,
@RequestParam(value = "questionnaireNumber", required = false) String questionnaireNumber,
@RequestParam(value = "diseased", required = false) Boolean diseased) {
ResultVo resultVo = new ResultVo();
resultVo.setCode(ResultVo.SUCCESS);
resultVo.setMsg("查询成功");
Map<String, Object> resultMap = new HashMap<>(16, 0.75F);
List<InvestigationRecord> records = investigationRecordService.listUnderReviewRecordPageByInvestigationPhone(investigatorPhone, currentPage, pageSize, state, idNumber, version, questionnaireNumber, diseased);
resultMap.put("totalCount", records.size());
resultMap.put("currentPage", currentPage);
resultMap.put("pageSize", pageSize);
resultMap.put("data", records);
resultVo.setData(resultMap);
return resultVo;
}
@GetMapping("/underReviewRecordCount")
public ResultVo countUnderReviewRecord(@RequestParam(value = "investigatorPhone") String investigatorPhone) {
ResultVo resultVo = new ResultVo();
resultVo.setCode(ResultVo.SUCCESS);
resultVo.setMsg("查询成功");
resultVo.setData(investigationRecordService.countUnderReviewRecordByInvestigatorPhone(investigatorPhone));
return resultVo;
}
@PutMapping("/underReviewRecord")
public ResultVo reviewRecord(@RequestBody ReviewVo reviewVo) {
ResultVo resultVo = new ResultVo();
resultVo.setCode(ResultVo.SUCCESS);
boolean result = investigationRecordService.reviewRecord(reviewVo);
if (result) {
resultVo.setCode(ResultVo.SUCCESS);
resultVo.setMsg("审核成功");
} else {
resultVo.setCode(ResultVo.FAILED);
resultVo.setMsg("审核失败");
}
resultVo.setData(result);
return resultVo;
}
@PutMapping("/investigationRecord")
public ResultVo updateInvestigationRecord(@RequestBody InvestigationRecordVo investigationRecordVo) {
ResultVo resultVo = new ResultVo();
resultVo.setCode(0);
resultVo.setMsg("修改提交成功,等待审核");
investigationRecordService.changeInvestigationRecord(investigationRecordVo);
resultVo.setData(true);
return resultVo;
}
}

View File

@ -0,0 +1,36 @@
package com.example.survey.controller;
import com.example.survey.entity.Investigator;
import com.example.survey.service.InvestigatorService;
import com.example.survey.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @author Pope
*/
@RestController
@RequestMapping("/investigator")
public class InvestigatorController {
@Autowired
private InvestigatorService investigatorService;
@PostMapping("/investigator")
public ResultVo addInvestigator(@RequestBody Investigator investigator){
ResultVo resultVo = new ResultVo();
boolean result = investigatorService.addInvestigator(investigator);
if(result){
resultVo.setCode(ResultVo.SUCCESS);
resultVo.setMsg("创建成功");
}else {
resultVo.setCode(ResultVo.FAILED);
resultVo.setMsg("创建失败");
}
resultVo.setData(result);
return resultVo;
}
}

View File

@ -0,0 +1,60 @@
package com.example.survey.controller;
import com.example.survey.entity.Respondent;
import com.example.survey.service.RespondentService;
import com.example.survey.dto.RespondentDto;
import com.example.survey.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Pope
*/
@RestController
@RequestMapping("/respondent")
public class RespondentController {
@Autowired
private RespondentService respondentService;
@PostMapping("/respondent")
public ResultVo addRespondent(@RequestBody Respondent respondent) {
ResultVo resultVo = new ResultVo();
boolean result = respondentService.addRespondent(respondent);
if (result) {
resultVo.setCode(ResultVo.SUCCESS);
resultVo.setMsg("创建成功");
} else {
resultVo.setCode(ResultVo.FAILED);
resultVo.setMsg("创建失败");
}
resultVo.setData(result);
return resultVo;
}
@GetMapping("/respondent")
public ResultVo countRespondent(@RequestParam(value = "investigatorPhone") String investigatorPhone,
@RequestParam(value = "currentPage") int currentPage,
@RequestParam(value = "pageSize", defaultValue = "30") int pageSize) {
ResultVo resultVo = new ResultVo();
resultVo.setCode(ResultVo.SUCCESS);
resultVo.setMsg("查询成功");
Map<String, Object> resultMap = new HashMap<>(16, 0.75F);
List<RespondentDto> voList = respondentService.listRespondentPageByInvestigatorPhone(investigatorPhone, currentPage, pageSize);
resultMap.put("totalCount", voList.size());
resultMap.put("currentPage", currentPage);
resultMap.put("pageSize", pageSize);
resultMap.put("data", voList);
resultVo.setData(resultMap);
return resultVo;
}
}

View File

@ -0,0 +1,39 @@
package com.example.survey.controller;
import com.example.survey.service.RoleService;
import com.example.survey.vo.RoleVo;
import com.example.survey.vo.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Pope
*/
@RestController
@RequestMapping("/role")
public class RoleController {
@Autowired
private RoleService roleService;
@PostMapping("/role")
public ResultVo addAuth(@RequestBody RoleVo roleVo){
ResultVo resultVo = new ResultVo();
boolean result = roleService.addRole(roleVo);
if (result) {
resultVo.setCode(ResultVo.SUCCESS);
resultVo.setMsg("创建成功");
} else {
resultVo.setCode(ResultVo.FAILED);
resultVo.setMsg("创建失败");
}
resultVo.setData(result);
return resultVo;
}
}

View File

@ -0,0 +1,66 @@
package com.example.survey.controller;
import com.example.survey.dto.LoginDto;
import com.example.survey.service.UserService;
import com.example.survey.vo.LoginVo;
import com.example.survey.vo.ResultVo;
import com.example.survey.vo.SignupVo;
import com.example.survey.vo.UserRoleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @author Pope
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
UserService userService;
@PostMapping("/login")
public ResultVo login(@RequestBody LoginVo loginVo) {
ResultVo resultVo = new ResultVo();
//用户名密码验证
LoginDto loginDto = userService.matchAuth(loginVo);
if (loginDto == null) {
//登录失败
resultVo.setCode(ResultVo.FAILED);
resultVo.setMsg("登录失败");
return resultVo;
}
resultVo.setCode(ResultVo.SUCCESS);
resultVo.setMsg("登录成功");
resultVo.setData(loginDto);
return resultVo;
}
@PostMapping("/signup")
public ResultVo signup(@RequestBody SignupVo signupVo) {
ResultVo resultVo = new ResultVo();
resultVo.setCode(ResultVo.SUCCESS);
boolean result = userService.addUser(signupVo);
if (result) {
resultVo.setCode(ResultVo.SUCCESS);
resultVo.setMsg("注册成功");
} else {
resultVo.setCode(ResultVo.FAILED);
resultVo.setMsg("注册失败");
}
return resultVo;
}
@PutMapping("/userRole")
public ResultVo modifyUserRoles(@RequestBody UserRoleVo userRoleVo) {
ResultVo resultVo = new ResultVo();
userService.modifyRoles(userRoleVo);
resultVo.setCode(0);
resultVo.setMsg("修改成功");
return resultVo;
}
}

View File

@ -0,0 +1,24 @@
package com.example.survey.dao;
import com.example.survey.entity.Department;
/**
* @author Pope
*/
public interface DepartmentDao {
/**
* 插入一个新部门
* @param department 部门
* @return 是否插入成功
*/
boolean insertDepartment(Department department);
/**
* 根据部门名查询部门
* @param id 部门id
* @return 查询结果
*/
Department selectDepartment(String id);
}

View File

@ -0,0 +1,78 @@
package com.example.survey.dao;
import com.example.survey.entity.InvestigationRecord;
import com.example.survey.entity.inner.OperationInformation;
import java.util.List;
/**
* @author Pope
*/
public interface InvestigationRecordDao {
/**
* 插入调查记录
*
* @param record 调查记录
* @return 是否插入成功
*/
boolean insertInvestigationRecord(InvestigationRecord record);
/**
* 根据筛选条件分页查询记录
*
* @param investigatorPhone 调查人员电话号码
* @param offset 偏移量
* @param number 数量
* @param state 调查记录状态
* @param idNumber 调查对象身份证号
* @param version 调查记录版本
* @param questionnaireNumber 问卷编号
* @param diseased 调查对象是否患病
* @return 筛选结果
*/
List<InvestigationRecord> listLimitInvestigationRecord(String investigatorPhone, int offset, int number, String state, String idNumber, String version, String questionnaireNumber, Boolean diseased);
/**
* 根据流调人员电话号码查询对应状态的记录数量
*
* @param investigatorPhone 流调人员电话号码
* @param state 记录状态
* @return 记录数量
*/
long countInvestigationRecordByInvestigatorPhone(String investigatorPhone, String state);
/**
* 更新记录状态
*
* @param idNumber 调查对象的身份证号
* @param oldState 旧状态
* @param newState 新状态
*/
void updateRecordState(String idNumber, String oldState, String newState);
/**
* 根据调查对象身份证号与记录状态查询记录
*
* @param idNumber 调查对象的身份证号
* @param state 记录状态
* @return 相应记录
*/
InvestigationRecord selectInvestigationRecord(String idNumber, String state);
/**
* 将待审核调查记录修改为审核后的结果
*
* @param record 审核后的记录
*/
void reviewRecord(InvestigationRecord record);
/**
* 是否存在当前状态调查记录
*
* @param idNumber 调查对象身份证号
* @param states 调查记录状态
* @return 是否存在
*/
boolean existInvestigationRecord(String idNumber, String... states);
}

View File

@ -0,0 +1,31 @@
package com.example.survey.dao;
import com.example.survey.entity.Investigator;
/**
* @author Pope
*/
public interface InvestigatorDao {
/**
* 根据流调人员电话判断是否存在
* @param phoneNumber 流调人员电话
* @return 是否存在该电话
*/
boolean existInvestigator(String phoneNumber);
/**
* 插入调查人员
* @param investigator 调查人员
* @return 是否插入成功
*/
boolean insertInvestigator(Investigator investigator);
/**
* 根据流调人员电话号码查询流调人员
* @param phoneNumber 流调人员电话号码
* @return 对应的流调人员
*/
Investigator selectInvestigator(String phoneNumber);
}

View File

@ -0,0 +1,42 @@
package com.example.survey.dao;
import com.example.survey.entity.Investigator;
import com.example.survey.entity.Respondent;
import java.util.List;
/**
* @author Pope
*
*/
public interface RespondentDao {
/**
* 插入待调查对象
* @param respondent 待调查对象
* @return 是否插入成功
*/
boolean insertRespondent(Respondent respondent);
/**
* 根据流调人员电话号码分页查询待调查对象列表
* @param investigatorPhone 流调人员电话号码
* @param offset 偏移量
* @param number 大小
* @return 待调查对象列表
*/
List<Respondent> listLimitRespondentByInvestigator(String investigatorPhone, int offset, int number);
/**
* 判断是否存在对应id的调查对象
* @param idNumber 身份证号
* @return 是否存在该调查对象
*/
boolean existRespondent(String idNumber);
/**
* 根据流调人员电话号码查询调查对象数量
* @param investigatorPhone 流调人员电话号码
* @return 对应流调人员id的调查对象数量
*/
long countRespondentBuInvestigatorPhone(String investigatorPhone);
}

View File

@ -0,0 +1,42 @@
package com.example.survey.dao;
import com.example.survey.entity.Role;
import java.util.List;
/**
* @author Pope
*/
public interface RoleDao {
/**
* 插入新权限
*
* @param role 新权限
* @return 是否插入成功
*/
boolean insertRole(Role role);
/**
* 根据权限名查询对应权限
*
* @param name 权限名
* @return 查询结果
*/
Role selectRole(String name);
/**
* 根据权限名删除权限
*
* @param name 权限名
*/
void deleteRole(String name);
/**
* 更改用户角色
*
* @param phoneNumber 电话号码
* @param roleList 角色列表
*/
void updateUserRoles(String phoneNumber, List<Role> roleList);
}

View File

@ -0,0 +1,27 @@
package com.example.survey.dao;
import com.example.survey.entity.User;
/**
* @author Pope
*/
public interface UserDao {
/**
* 根据用户名密码查询用户
*
* @param username 用户名
* @param password 密码
* @return 对应用户
*/
User selectUser(String username, String password);
/**
* 插入用户
*
* @param user 用户
* @return 是否插入成功
*/
boolean insertUser(User user);
}

View File

@ -0,0 +1,35 @@
package com.example.survey.dao.impl;
import com.example.survey.dao.DepartmentDao;
import com.example.survey.entity.Department;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
/**
* @author Pope
*/
@Service
public class DepartmentDaoImpl implements DepartmentDao {
@Autowired
private MongoTemplate mongoTemplate;
@Override
public boolean insertDepartment(Department department) {
try {
mongoTemplate.save(department);
}catch (Exception e){
return false;
}
return true;
}
@Override
public Department selectDepartment(String id) {
Query query = new Query(Criteria.where("id").is(id));
return mongoTemplate.findOne(query,Department.class);
}
}

View File

@ -0,0 +1,112 @@
package com.example.survey.dao.impl;
import com.example.survey.dao.InvestigationRecordDao;
import com.example.survey.entity.InvestigationRecord;
import com.example.survey.entity.inner.OperationInformation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.ArrayOperators;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import java.util.*;
/**
* @author Pope
*/
@Repository
public class InvestigationRecordDaoImpl implements InvestigationRecordDao {
@Autowired
MongoTemplate mongoTemplate;
@Override
public boolean insertInvestigationRecord(InvestigationRecord record) {
try {
mongoTemplate.save(record);
} catch (Exception e) {
//TODO 抛出相应异常
return false;
}
return true;
}
@Override
public List<InvestigationRecord> listLimitInvestigationRecord(String investigatorPhone, int offset, int number, String state, String idNumber, String version, String questionnaireNumber, Boolean diseased) {
Criteria criteria = new Criteria();
//流调人员id
if (investigatorPhone != null) {
criteria.and("investigatorPhone").is(investigatorPhone);
}
//调查记录状态
if (state != null) {
criteria.and("state").is(state);
} else {
criteria.and("state").in(InvestigationRecord.UNDER_REVIEW,InvestigationRecord.REVIEWED);
}
//调查对象身份证号
if (idNumber != null) {
criteria.and("idNumber").is(idNumber);
}
//版本
if (version != null) {
criteria.and("version").is(version);
}
//问卷编号
if (questionnaireNumber != null) {
criteria.and("questionnaireNumber").is(questionnaireNumber);
}
//是否患病
if (diseased != null) {
criteria.and("diseased").is(diseased);
}
Query query = new Query(criteria);
query = query.skip(offset).limit(number);
return mongoTemplate.find(query, InvestigationRecord.class);
}
@Override
public long countInvestigationRecordByInvestigatorPhone(String investigatorPhone, String state) {
Query query = new Query(Criteria.where("investigatorPhone").is(investigatorPhone).and("state").is(state));
return mongoTemplate.count(query, InvestigationRecord.class);
}
@Override
public void updateRecordState(String idNumber, String oldState, String newState) {
Query query = new Query(Criteria.where("idNumber").is(idNumber).and("state").is(oldState));
Update update = new Update().set("state", newState);
mongoTemplate.updateFirst(query, update, InvestigationRecord.class);
}
@Override
public InvestigationRecord selectInvestigationRecord(String idNumber, String state) {
Query query = new Query(Criteria.where("idNumber").is(idNumber).and("state").is(state));
return mongoTemplate.findOne(query, InvestigationRecord.class);
}
@Override
public void reviewRecord(InvestigationRecord record) {
Query query = new Query(Criteria.where("idNumber").is(record.getIdNumber()).and("state").is(InvestigationRecord.UNDER_REVIEW));
Update update = new Update()
.set("state", record.getState())
.set("operationInformationList", record.getOperationInformationList());
mongoTemplate.updateFirst(query, update, InvestigationRecord.class);
}
@Override
public boolean existInvestigationRecord(String idNumber, String... states) {
Query query = new Query(Criteria.where("idNumber").is(idNumber).and("state").in(states));
return mongoTemplate.exists(query, InvestigationRecord.class);
}
}

View File

@ -0,0 +1,42 @@
package com.example.survey.dao.impl;
import com.example.survey.dao.InvestigatorDao;
import com.example.survey.entity.Investigator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
/**
* @author Pope
*/
@Repository
public class InvestigatorDaoImpl implements InvestigatorDao {
@Autowired
MongoTemplate mongoTemplate;
@Override
public boolean existInvestigator(String phoneNumber) {
Query query = new Query(Criteria.where("phoneNumber").is(phoneNumber));
return mongoTemplate.exists(query, Investigator.class);
}
@Override
public boolean insertInvestigator(Investigator investigator) {
try {
mongoTemplate.save(investigator);
} catch (Exception e) {
//TODO 抛出相应异常
return false;
}
return true;
}
@Override
public Investigator selectInvestigator(String phoneNumber) {
Query query = new Query(Criteria.where("phoneNumber").is(phoneNumber));
return mongoTemplate.findOne(query, Investigator.class);
}
}

View File

@ -0,0 +1,49 @@
package com.example.survey.dao.impl;
import com.example.survey.dao.RespondentDao;
import com.example.survey.entity.Respondent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @author Pope
*/
@Repository
public class RespondentDaoImpl implements RespondentDao {
@Autowired
private MongoTemplate mongoTemplate;
@Override
public boolean insertRespondent(Respondent respondent) {
try {
mongoTemplate.save(respondent);
} catch (Exception e) {
return false;
}
return true;
}
@Override
public List<Respondent> listLimitRespondentByInvestigator(String investigatorPhone, int offset, int number) {
Query query = new Query(Criteria.where("investigatorPhone").is(investigatorPhone)).skip(offset).limit(number);
return mongoTemplate.find(query, Respondent.class);
}
@Override
public boolean existRespondent(String idNumber) {
Query query = new Query(Criteria.where("idNumber").is(idNumber));
return mongoTemplate.exists(query, Respondent.class);
}
@Override
public long countRespondentBuInvestigatorPhone(String investigatorPhone) {
Query query = new Query(Criteria.where("investigatorPhone").is(investigatorPhone));
return mongoTemplate.count(query, Respondent.class);
}
}

View File

@ -0,0 +1,52 @@
package com.example.survey.dao.impl;
import com.example.survey.dao.RoleDao;
import com.example.survey.entity.Role;
import com.example.survey.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author Pope
*/
@Service
public class RoleDaoImpl implements RoleDao {
@Autowired
private MongoTemplate mongoTemplate;
@Override
public boolean insertRole(Role role) {
try {
mongoTemplate.save(role);
} catch (Exception e) {
return false;
}
return true;
}
@Override
public Role selectRole(String name) {
Query query = new Query(Criteria.where("name").is(name));
return mongoTemplate.findOne(query, Role.class);
}
@Override
public void deleteRole(String name) {
Query query = new Query(Criteria.where("name").is(name));
mongoTemplate.remove(query);
}
@Override
public void updateUserRoles(String phoneNumber, List<Role> roleList) {
Query query = new Query(Criteria.where("phoneNumber").is(phoneNumber));
Update update = new Update()
.set("roleList", roleList);
mongoTemplate.updateFirst(query, update, User.class);
}
}

View File

@ -0,0 +1,35 @@
package com.example.survey.dao.impl;
import com.example.survey.dao.UserDao;
import com.example.survey.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
/**
* @author Pope
*/
@Service
public class UserDaoImpl implements UserDao {
@Autowired
private MongoTemplate mongoTemplate;
@Override
public User selectUser(String username, String password) {
Query query = new Query(Criteria.where("phoneNumber").is(username).and("password").is(password));
return mongoTemplate.findOne(query,User.class);
}
@Override
public boolean insertUser(User user) {
try {
mongoTemplate.save(user);
}catch (Exception e){
return false;
}
return true;
}
}

View File

@ -0,0 +1,21 @@
package com.example.survey.dto;
import com.example.survey.entity.Department;
import com.example.survey.entity.Role;
import lombok.*;
import java.util.List;
/**
* @author Pope
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class LoginDto {
private String token;
private List<Role> roleList;
private List<Department> departmentList;
}

View File

@ -0,0 +1,61 @@
package com.example.survey.dto;
import com.example.survey.entity.Investigator;
import com.example.survey.entity.Respondent;
import lombok.*;
/**
* @author Pope
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class RespondentDto {
/**
* 身份证号
*/
private String idNumber;
/**
* 电话
*/
private String phoneNumber;
/**
* 姓名
*/
private String name;
/**
* 备注
*/
private String msg;
/**
* 分配的调查人员
*/
private Investigator investigator;
/**
* 是否发病
*/
private boolean diseased;
/**
* 性别
*/
private String gender;
public RespondentDto(Respondent respondent, Investigator investigator){
this.idNumber = respondent.getIdNumber();
this.name = respondent.getName();
this.phoneNumber = respondent.getPhoneNumber();
this.investigator = investigator;
this.diseased = respondent.isDiseased();
this.gender = respondent.getGender();
this.msg = respondent.getMsg();
}
}

View File

@ -0,0 +1,41 @@
package com.example.survey.entity;
import lombok.*;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.List;
/**
* @author Pope
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "department")
public class Department {
/**
* 唯一索引
*/
private String uniqueIndex;
/**
* 部门名
*/
private String name;
/**
* 子部门
*/
private List<Department> children;
/**
* 父部门
*/
private String parent;
}

View File

@ -0,0 +1,330 @@
package com.example.survey.entity;
import com.example.survey.entity.inner.*;
import com.example.survey.vo.InvestigationRecordVo;
import lombok.*;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author Pope
* 调查记录表
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "investigationRecord")
public class InvestigationRecord {
/**
* 调查记录审核中状态
*/
public static final String UNDER_REVIEW = "待审核";
/**
* 调查记录已审核状态
*/
public static final String REVIEWED = "已通过";
/**
* 调查记录已删除状态
*/
public static final String DELETED = "已删除";
/**
* 调查记录审核未通过状态
*/
public static final String NOT_PASS = "未通过";
/**
* 调查记录旧档状态
*/
public static final String OUT_OF_DATE = "已归档";
/**
* 调查对象性别为男
*/
public static final String MAN = "";
/**
* 调查对象性别为女
*/
public static final String WOMAN = "";
/**
* 问卷编号
*/
private String questionnaireNumber;
/**
* 身份证号
* 唯一索引
*/
private String idNumber;
//==================================基本信息==================================
/**
* 姓名
*/
private String name;
/**
* 性别
* true为男性false为女性
*/
private String gender;
/**
* 是否为境外病例
*/
private boolean overseasCase;
/**
* 是否为病例
* 区分病例与密切接触者
*/
private boolean diseased;
/**
* 入境经历
* 选填
*/
private EntryExperience entryExperience;
//==================================病例发现与就诊==================================
/**
* 病例被发现途径
*/
private String wayOfBeingDiscovered;
/**
* 入院时间
*/
private Date dateOfAdmission;
/**
* 入院时症状和体征
*/
private List<String> symptomAndSign;
/**
* 有无并发症
*/
private boolean existComplication;
/**
* 并发症
* 选填
*/
private List<String> complication;
/**
* 并发症存在发热时记录最高体温
*/
private String maxTemp;
/**
* 胸部X线或 CT 检测是否有肺炎影像学特征
*/
private boolean existImagingFeatureOfPneumonia;
/**
* 如果肺炎影像学特征为是此处填检测时间
*/
private Date testDate;
/**
* 出院日期
* 年月日
*/
private Date dateOfDischarge;
//==================================危险因素与暴露史==================================
/**
* 是否为特定职业人群
*/
private String specificOccupation;
/**
* 当specificOccupation为other时起作用
*/
private String otherSpecificOccupation;
/**
* 如为医护人员填写具体工作性质
*/
private String workInformation;
/**
* 当workInformation为other时起作用
*/
private String otherWorkInformation;
/**
* 是否为孕妇
*/
private boolean pregnant;
/**
* 孕周
*/
private int pregnantWeek;
/**
* 病史
*/
private List<String> medicalHistory;
/**
* 对既往病史的详细描述
*/
private String medicalHistoryDetail;
//==================================发病或检测阳性前14天内是否有以下暴露史或接触史==================================
/**
* 是否有境外疫情严重国家或地区的旅行史或居住史
*/
private boolean nearSeriousRegion;
/**
* 是否接触过来自境外疫情严重的国家或地区的发热或有呼吸道症状的患者
*/
private boolean contactWithSeriousRegionPatients;
/**
* 是否曾有确诊病例或无症状感染者的接触史
*/
private boolean contactWithConfirmedCase;
/**
* 患者同一家庭办公室学校或托幼机构班级车间等集体单位是否有聚集性发病
*/
private boolean aggregationDisease;
//==================================实验室检测==================================
/**
* 实验室检测结果未采集则value为null
*/
private List<Detection> detectionList;
/**
* 调查单位
*/
private String investigationCompany;
/**
* 调查者电话号码
* 外键
*/
@Indexed
private String investigatorPhone;
/**
* 调查日期
* 年月日
*/
private Date investigationDate;
/**
* 体温历史
*/
private List<TempHistory> tempHistoryList;
/**
* 居旅史
*/
private List<LiveAndTravelHistory> liveAndTravelHistoryList;
/**
* 状态信息
*/
private String state;
/**
* 版本号
*/
private String version;
/**
* 操作列表
*/
private List<OperationInformation> operationInformationList;
//========================================保留字段============================================
/**
* 密切接触者身份证
* 外键
*/
private List<String> closeContactList;
/**
* 上级感染者
*/
private List<SuperiorInfectedIndividual> superiorInfectedIndividualList;
/**
* 生成提交待审核的记录
* @param vo 调查记录vo
*/
public static InvestigationRecord getInvestigationRecord(InvestigationRecordVo vo) {
InvestigationRecord record = new InvestigationRecord();
record.questionnaireNumber = vo.getQuestionnaireNumber();
record.idNumber = vo.getIdNumber();
record.name = vo.getName();
record.gender = vo.getGender();
record.overseasCase = vo.isOverseasCase();
record.diseased = vo.isDiseased();
record.entryExperience = vo.getEntryExperience();
record.wayOfBeingDiscovered = vo.getWayOfBeingDiscovered();
record.dateOfAdmission = vo.getDateOfAdmission();
record.symptomAndSign = vo.getSymptomAndSign();
record.existComplication = vo.isExistComplication();
record.complication = vo.getComplication();
record.maxTemp = vo.getMaxTemp();
record.existImagingFeatureOfPneumonia = vo.isExistImagingFeatureOfPneumonia();
record.testDate = vo.getTestDate();
record.dateOfDischarge = vo.getDateOfDischarge();
record.specificOccupation = vo.getSpecificOccupation();
record.otherSpecificOccupation = vo.getOtherSpecificOccupation();
record.workInformation = vo.getWorkInformation();
record.otherWorkInformation = vo.getOtherWorkInformation();
record.pregnant = vo.isPregnant();
record.pregnantWeek = vo.getPregnantWeek();
record.medicalHistory = vo.getMedicalHistory();
record.medicalHistoryDetail = vo.getMedicalHistoryDetail();
record.nearSeriousRegion = vo.isNearSeriousRegion();
record.contactWithSeriousRegionPatients = vo.isContactWithSeriousRegionPatients();
record.contactWithConfirmedCase = vo.isContactWithConfirmedCase();
record.aggregationDisease = vo.isAggregationDisease();
record.detectionList = vo.getDetectionList();
record.investigationCompany = vo.getInvestigationCompany();
record.investigatorPhone = vo.getInvestigatorPhone();
record.investigationDate = vo.getInvestigationDate();
record.tempHistoryList = vo.getTempHistoryList();
record.liveAndTravelHistoryList = vo.getLiveAndTravelHistoryList();
record.closeContactList = new ArrayList<>();
record.superiorInfectedIndividualList = new ArrayList<>();
return record;
}
}

View File

@ -0,0 +1,36 @@
package com.example.survey.entity;
import lombok.*;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
/**
* @author Pope
* 调查人员表
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "investigator")
public class Investigator {
/**
* 身份证号
*/
private String idNumber;
/**
* 姓名
*/
private String name;
/**
* 电话号码
*/
@Indexed(unique = true)
private String phoneNumber;
}

View File

@ -0,0 +1,68 @@
package com.example.survey.entity;
import lombok.*;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
/**
* @author Pope
* 调查对象表
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "respondent")
public class Respondent {
/**
* 性别为男
*/
public static final String MAN = "";
/**
* 性别为女
*/
public static final String WOMAN = "";
/**
* 身份证号
*/
@Indexed(unique = true)
private String idNumber;
/**
* 电话
*/
private String phoneNumber;
/**
* 姓名
*/
private String name;
/**
* 备注
*/
private String msg;
/**
* 分配的调查人员
*/
@Indexed
private String investigatorPhone;
/**
* 是否发病
*/
private boolean diseased;
/**
* 性别
*/
private String gender;
}

View File

@ -0,0 +1,31 @@
package com.example.survey.entity;
import com.example.survey.enumeration.AuthEnum;
import lombok.*;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.Set;
/**
* @author Pope
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "role")
public class Role {
/**
* 角色名
*/
@Indexed(unique = true)
private String name;
/**
* 该角色的权限组
*/
private Set<AuthEnum> authoritySet;
}

View File

@ -0,0 +1,64 @@
package com.example.survey.entity;
import com.example.survey.vo.SignupVo;
import lombok.*;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author Pope
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "user")
public class User {
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 身份证号
*/
private String idNumber;
/**
* 手机号
*/
@Indexed(unique = true)
private String phoneNumber;
/**
* 一个人可以拥有多个角色
*/
private List<Role> roleList;
/**
* 一个人所属的部门
*/
private List<Department> departmentList;
public User(SignupVo vo){
this.username = vo.getUsername();
this.password = vo.getPassword();
this.phoneNumber = vo.getPhoneNumber();
this.roleList = new ArrayList<>();
this.departmentList = new ArrayList<>();
}
}

View File

@ -0,0 +1,36 @@
package com.example.survey.entity.inner;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @author Pope
* 检测项目
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Detection {
/**
* 检测项目名称
*/
private String name;
/**
* 检测时间
* 年月日
*/
@JsonFormat(pattern = "yyyy-MM-dd")
private Date date;
/**
* 检测结果
*/
private String result;
}

View File

@ -0,0 +1,120 @@
package com.example.survey.entity.inner;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @author Pope\
* 入境经历
*/
public class EntryExperience {
/**
* 入境前居住或旅行的国家或地区
*/
private String areaOfResidence;
/**
* 入境前途径的国家或地区
*/
private String areaOfAccess;
/**
* 国籍
*/
private String nationality;
/**
* 护照号码
*/
private String passportNumber;
/**
* 入境口岸
*/
private EntryPort entryPort;
/**
* 入境日期
* 年月日
*/
@JsonFormat(pattern = "yyyy-MM-dd")
private Date entryDate;
/**
* 入境交通方式
* 航班号车次船号等
*/
private String transportation;
public EntryExperience() {
}
public EntryExperience(String areaOfResidence, String areaOfAccess, String nationality, String passportNumber, EntryPort entryPort, Date entryDate, String transportation) {
this.areaOfResidence = areaOfResidence;
this.areaOfAccess = areaOfAccess;
this.nationality = nationality;
this.passportNumber = passportNumber;
this.entryPort = entryPort;
this.entryDate = entryDate;
this.transportation = transportation;
}
public String getAreaOfResidence() {
return areaOfResidence;
}
public void setAreaOfResidence(String areaOfResidence) {
this.areaOfResidence = areaOfResidence;
}
public String getAreaOfAccess() {
return areaOfAccess;
}
public void setAreaOfAccess(String areaOfAccess) {
this.areaOfAccess = areaOfAccess;
}
public String getNationality() {
return nationality;
}
public void setNationality(String nationality) {
this.nationality = nationality;
}
public String getPassportNumber() {
return passportNumber;
}
public void setPassportNumber(String passportNumber) {
this.passportNumber = passportNumber;
}
public EntryPort getEntryPort() {
return entryPort;
}
public void setEntryPort(EntryPort entryPort) {
this.entryPort = entryPort;
}
public Date getEntryDate() {
return entryDate;
}
public void setEntryDate(Date entryDate) {
this.entryDate = entryDate;
}
public String getTransportation() {
return transportation;
}
public void setTransportation(String transportation) {
this.transportation = transportation;
}
}

View File

@ -0,0 +1,41 @@
package com.example.survey.entity.inner;
/**
* @author Pope
* 入境口岸
*/
public class EntryPort {
/**
* 入境省份
*/
private String province;
/**
* 入境机场码头车站等
*/
private String port;
public EntryPort() {
}
public EntryPort(String province, String port) {
this.province = province;
this.port = port;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
}

View File

@ -0,0 +1,47 @@
package com.example.survey.entity.inner;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.*;
import java.util.Date;
import java.util.List;
/**
* @author Pope
* 居旅史
* TODO 完善类
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class LiveAndTravelHistory {
/**
* 居住史或者旅行史
*/
private List<String> type;
/**
* 起始时间
*/
@JsonFormat(pattern = "yyyy-MM-dd")
private Date beginTime;
/**
* 结束时间
*/
@JsonFormat(pattern = "yyyy-MM-dd")
private Date endTime;
/**
* 地点
*/
private String location;
/**
* 事件
*/
private String detail;
}

View File

@ -0,0 +1,69 @@
package com.example.survey.entity.inner;
import lombok.*;
import java.util.Date;
/**
* @author Pope
* 操作信息
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class OperationInformation {
public static final String SUBMIT = "提交";
/**
* 修改操作
*/
public static final String CHANGE = "修改";
/**
* 删除操作
*/
public static final String DELETE = "删除";
/**
* 恢复记录
*/
public static final String RECOVERY = "恢复";
/**
*
*/
public static final String REVIEW = "审核";
/**
* 操作
*/
private String type;
/**
* 时间
*/
private Date time;
/**
* 操作者id
*/
private String investigatorPhone;
/**
* 版本信息
*/
private String version;
/**
* 备注
*/
private String msg;
/**
* 操作结果
*/
private String result;
}

View File

@ -0,0 +1,72 @@
package com.example.survey.entity.inner;
import java.util.Date;
/**
* @author Pope
* 上级感染者
*/
public class SuperiorInfectedIndividual {
/**
* 身份证
*/
private String idNumber;
/**
* 地点
*/
private String place;
/**
* 时间
*/
private Date date;
/**
* 事件
*/
private String event;
public SuperiorInfectedIndividual() {
}
public SuperiorInfectedIndividual(String idNumber, String place, Date date, String event) {
this.idNumber = idNumber;
this.place = place;
this.date = date;
this.event = event;
}
public String getIdNumber() {
return idNumber;
}
public void setIdNumber(String idNumber) {
this.idNumber = idNumber;
}
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getEvent() {
return event;
}
public void setEvent(String event) {
this.event = event;
}
}

View File

@ -0,0 +1,30 @@
package com.example.survey.entity.inner;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.*;
import java.util.Date;
/**
* @author Pope
* 体温历史
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class TempHistory {
/**
* 检测时间
*/
@JsonFormat(pattern = "yyyy-MM-dd:HH:mm:ss")
private Date time;
/**
* 体温
*/
private String data;
}

View File

@ -0,0 +1,143 @@
package com.example.survey.enumeration;
import java.util.HashSet;
import java.util.Set;
/**
* @author Pope
*/
public enum AuthEnum {
/**
* 管理员权限可以访问所有接口
*/
ADMIN(0, "管理员", new HashSet<String>() {{
add("/investigator/investigator : POST");
add("/investigationRecord/underReviewRecord : GET");
add("/investigationRecord/underReviewRecordCount : GET");
add("/investigationRecord/investigationRecord : POST");
add("/investigationRecord/investigationRecord : PUT");
add("/investigationRecord/underReviewRecord : PUT");
add("/respondent/respondent : POST");
add("/respondent/respondent : GET");
add("/user/userRole : PUT");
add("/role/role : POST");
}}),
/**
* 查询调查记录的权限
*/
RETRIEVE_RECORD(1, "查询调查记录的权限", new HashSet<String>() {{
add("/investigationRecord/underReviewRecord : GET");
add("/investigationRecord/underReviewRecordCount : GET");
}}),
/**
* 提交记录的权限
*/
CREATE_RECORD(2, "提交调查记录权限", new HashSet<String>() {{
add("/investigationRecord/investigationRecord : POST");
}}),
/**
* 修改调查记录信息的权限
*/
UPDATE_RECORD(3, "修改调查记录权限", new HashSet<String>() {{
add("/investigationRecord/investigationRecord : PUT");
}}),
/**
* 审核调查记录权限
*/
REVIEW_RECORD(4, "审核调查记录权限", new HashSet<String>() {{
add("/investigationRecord/underReviewRecord : PUT");
}}),
/**
* 删除调查记录权限
*/
DELETE_RECORD(5, "删除调查记录权限", new HashSet<String>() {{
}}),
/**
* 分析调查记录的权限
*/
ANALYSE_RECORD(6, "分析调查记录权限", new HashSet<String>() {{
}}),
/**
* 可以增删改流调人员信息
*/
CUD_INVESTIGATOR(7, "增删改流调人员信息的权限", new HashSet<String>() {{
}}),
/**
* 查询流调人员信息
*/
RETRIEVE_INVESTIGATOR(8, "查询流调人员信息的权限", new HashSet<String>() {{
}}),
/**
* 增删改调查对象信息的权限
*/
CUD_RESPONDENT(9, "增删改调查对象信息的权限", new HashSet<String>() {{
add("/respondent/respondent : POST");
}}),
/**
* 查询调查对象信息的权限
*/
RETRIEVE_RESPONDENT(10, "查询调查对象信息的权限", new HashSet<String>() {{
add("/respondent/respondent : GET");
}});
private int code;
private String name;
private Set<String> routes;
AuthEnum(int code, String name, Set<String> routes) {
this.code = code;
this.name = name;
this.routes = routes;
}
public static AuthEnum getRoleEnum(int code) {
for (AuthEnum value : AuthEnum.values()) {
if (value.code == code) {
return value;
}
}
return null;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<String> getRoutes() {
return routes;
}
public void setRoutes(Set<String> routes) {
this.routes = routes;
}
}

View File

@ -0,0 +1,60 @@
package com.example.survey.service;
import com.example.survey.entity.InvestigationRecord;
import com.example.survey.vo.InvestigationRecordVo;
import com.example.survey.vo.ReviewVo;
import java.util.List;
/**
* @author Pope
*/
public interface InvestigationRecordService {
/**
* 创建新的调查记录
*
* @param vo 调查记录信息
* @return 是否创建成功
*/
boolean addInvestigationRecord(InvestigationRecordVo vo);
/**
* 根据筛选条件查询调查记录
*
* @param investigatorPhone 流调人员电话号码
* @param currentPage 当前页数
* @param pageSize 页大小
* @param state 状态
* @param idNumber 调查对象身份证号
* @param version 版本
* @param questionnaireNumber 问卷编号
* @param diseased 是否患病
* @return 调查记录列表
*/
List<InvestigationRecord> listUnderReviewRecordPageByInvestigationPhone(String investigatorPhone, int currentPage, int pageSize, String state, String idNumber, String version, String questionnaireNumber, Boolean diseased);
/**
* 根据流调人员电话号码查询待审核记录数量
*
* @param investigatorPhone 流调人员id
* @return 记录数量
*/
long countUnderReviewRecordByInvestigatorPhone(String investigatorPhone);
/**
* 提交修改后的调查记录等待审核
*
* @param vo 调查记录Vo
* @return 修改是否提交成功
*/
void changeInvestigationRecord(InvestigationRecordVo vo);
/**
* 审核待调查记录
*
* @param vo 审核信息
* @return 是否成功
*/
boolean reviewRecord(ReviewVo vo);
}

View File

@ -0,0 +1,17 @@
package com.example.survey.service;
import com.example.survey.entity.Investigator;
/**
* @author Pope
*/
public interface InvestigatorService {
/**
* 创建调查人员
* @param investigator 调查人员
* @return 是否创建成功
*/
boolean addInvestigator(Investigator investigator);
}

View File

@ -0,0 +1,34 @@
package com.example.survey.service;
import com.example.survey.entity.Respondent;
import com.example.survey.dto.RespondentDto;
import java.util.List;
/**
* @author Pope
*/
public interface RespondentService {
/**
* 创建待调查对象
* @param respondent 待调查对象
* @return 是否创建成功
*/
boolean addRespondent(Respondent respondent);
/**
* 根据流调人员电话号码分页查询待调查对象数据
* @param investigatorPhone 流调人员电话号码
* @param currentPage 当前页数
* @param pageSize 页大小
* @return 页数据
*/
List<RespondentDto> listRespondentPageByInvestigatorPhone(String investigatorPhone, int currentPage, int pageSize);
/**
* 根据流调人员phone查询调查对象数量
* @param investigatorPhone 流调人员电话号码
* @return 对应流调人员id的调查对象数量
*/
long countRespondentByInvestigatorPhone(String investigatorPhone);
}

View File

@ -0,0 +1,17 @@
package com.example.survey.service;
import com.example.survey.vo.RoleVo;
/**
* @author Pope
*/
public interface RoleService {
/**
* 创建角色
*
* @param roleVo 角色信息
* @return 是否创建成功
*/
boolean addRole(RoleVo roleVo);
}

View File

@ -0,0 +1,33 @@
package com.example.survey.service;
import com.example.survey.dto.LoginDto;
import com.example.survey.vo.LoginVo;
import com.example.survey.vo.SignupVo;
import com.example.survey.vo.UserRoleVo;
/**
* @author Pope
*/
public interface UserService {
/**
* 根据登录信息判断是否登录
*
* @param loginVo 登录信息
* @return 用户信息 若登录失败则返回null
*/
LoginDto matchAuth(LoginVo loginVo);
/**
* 注册用户
*
* @param signupVo 注册信息
* @return 是否注册成功
*/
boolean addUser(SignupVo signupVo);
/**
* 修改用户权限
* @param userRoleVo 新权限信息
*/
void modifyRoles(UserRoleVo userRoleVo);
}

View File

@ -0,0 +1,160 @@
package com.example.survey.service.impl;
import com.example.survey.dao.InvestigationRecordDao;
import com.example.survey.dao.InvestigatorDao;
import com.example.survey.dao.RespondentDao;
import com.example.survey.entity.InvestigationRecord;
import com.example.survey.entity.inner.OperationInformation;
import com.example.survey.service.InvestigationRecordService;
import com.example.survey.vo.InvestigationRecordVo;
import com.example.survey.vo.ReviewVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author Pope
*/
@Service
public class InvestigationRecordServiceImpl implements InvestigationRecordService {
@Autowired
private InvestigationRecordDao investigationRecordDao;
@Autowired
private InvestigatorDao investigatorDao;
@Autowired
private RespondentDao respondentDao;
@Override
public boolean addInvestigationRecord(InvestigationRecordVo vo) {
InvestigationRecord record = InvestigationRecord.getInvestigationRecord(vo);
//生成版本信息
record.setState(InvestigationRecord.UNDER_REVIEW);
record.setVersion(vo.getInvestigatorPhone() + new Date().toString());
List<OperationInformation> opList = new ArrayList<>();
OperationInformation op = new OperationInformation();
op.setType(OperationInformation.SUBMIT);
op.setTime(new Date());
op.setInvestigatorPhone(vo.getInvestigatorPhone());
op.setVersion(vo.getInvestigatorPhone() + new Date().toString());
op.setMsg(vo.getMsg());
op.setResult("提交成功");
opList.add(op);
record.setOperationInformationList(opList);
//如果不存在对应id的调查对象
if (!respondentDao.existRespondent(record.getIdNumber())) {
//TODO 改为抛出相应异常
return false;
}
//如果已经存在则失败
if (investigationRecordDao.existInvestigationRecord(record.getIdNumber(), InvestigationRecord.UNDER_REVIEW, InvestigationRecord.REVIEWED)) {
return false;
}
//如果不存在对应id的流调人员
if (!investigatorDao.existInvestigator(record.getInvestigatorPhone())) {
//TODO 改为抛出相应异常
return false;
}
//TODO 插入消息队列
return investigationRecordDao.insertInvestigationRecord(record);
}
@Override
public List<InvestigationRecord> listUnderReviewRecordPageByInvestigationPhone(String investigatorPhone, int currentPage, int pageSize, String state, String idNumber, String version, String questionnaireNumber, Boolean diseased) {
//TODO 从消息队列进行筛选
return investigationRecordDao.listLimitInvestigationRecord(investigatorPhone, pageSize * currentPage, pageSize, state, idNumber, version, questionnaireNumber, diseased);
}
@Override
public long countUnderReviewRecordByInvestigatorPhone(String investigatorPhone) {
//TODO 从消息队列获取调查记录数量
return investigationRecordDao.countInvestigationRecordByInvestigatorPhone(investigatorPhone, InvestigationRecord.UNDER_REVIEW);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void changeInvestigationRecord(InvestigationRecordVo vo) {
//创建新记录
InvestigationRecord oldRecord = investigationRecordDao.selectInvestigationRecord(vo.getIdNumber(), InvestigationRecord.REVIEWED);
if(oldRecord == null){
oldRecord = investigationRecordDao.selectInvestigationRecord(vo.getIdNumber(), InvestigationRecord.NOT_PASS);
}
InvestigationRecord newRecord = InvestigationRecord.getInvestigationRecord(vo);
//生成版本信息
newRecord.setState(InvestigationRecord.UNDER_REVIEW);
newRecord.setVersion(vo.getInvestigatorPhone() + new Date().toString());
//生成操作记录
List<OperationInformation> opList = oldRecord.getOperationInformationList();
OperationInformation op = new OperationInformation();
op.setType(OperationInformation.CHANGE);
op.setTime(new Date());
op.setInvestigatorPhone(vo.getInvestigatorPhone());
op.setVersion(vo.getInvestigatorPhone() + new Date().toString());
op.setMsg(vo.getMsg());
op.setResult("提交成功");
opList.add(op);
newRecord.setOperationInformationList(opList);
//存入新纪录
//原纪录标记为已归档
investigationRecordDao.updateRecordState(oldRecord.getIdNumber(), InvestigationRecord.REVIEWED, InvestigationRecord.OUT_OF_DATE);
investigationRecordDao.insertInvestigationRecord(newRecord);
//TODO 将修改请求加入消息队列
}
@Override
public boolean reviewRecord(ReviewVo vo) {
//如果调查记录表不存在
if (!investigationRecordDao.existInvestigationRecord(vo.getIdNumber(), InvestigationRecord.UNDER_REVIEW)) {
//TODO 抛出相应异常
return false;
}
//如果审核人不存在
if (!investigatorDao.existInvestigator(vo.getReviewerPhone())) {
//TODO 抛出相应异常
return false;
}
InvestigationRecord record = investigationRecordDao.selectInvestigationRecord(vo.getIdNumber(), InvestigationRecord.UNDER_REVIEW);
//审核结果与版本信息
record.setState(vo.isPass() ? InvestigationRecord.REVIEWED : InvestigationRecord.NOT_PASS);
record.setVersion(vo.getReviewerPhone() + new Date().toString());
//生成操作记录
List<OperationInformation> opList = record.getOperationInformationList();
OperationInformation op = new OperationInformation();
op.setType(OperationInformation.REVIEW);
op.setTime(new Date());
op.setInvestigatorPhone(vo.getReviewerPhone());
op.setVersion(vo.getReviewerPhone() + new Date().toString());
op.setMsg(vo.getMsg());
op.setResult(vo.isPass() ? "审核通过" : "审核不通过");
opList.add(op);
record.setOperationInformationList(opList);
//更新数据库记录
investigationRecordDao.reviewRecord(record);
return true;
}
}

View File

@ -0,0 +1,22 @@
package com.example.survey.service.impl;
import com.example.survey.dao.InvestigatorDao;
import com.example.survey.entity.Investigator;
import com.example.survey.service.InvestigatorService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author Pope
*/
@Service
public class InvestigatorServiceImpl implements InvestigatorService {
@Autowired
private InvestigatorDao investigatorDao;
@Override
public boolean addInvestigator(Investigator investigator) {
return investigatorDao.insertInvestigator(investigator);
}
}

View File

@ -0,0 +1,53 @@
package com.example.survey.service.impl;
import com.example.survey.dao.InvestigatorDao;
import com.example.survey.dao.RespondentDao;
import com.example.survey.entity.Investigator;
import com.example.survey.entity.Respondent;
import com.example.survey.service.RespondentService;
import com.example.survey.dto.RespondentDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* @author Pope
*/
@Service
public class RespondentServiceImpl implements RespondentService {
@Autowired
private RespondentDao respondentDao;
@Autowired
private InvestigatorDao investigatorDao;
@Override
public boolean addRespondent(Respondent respondent) {
//如果不存在对应phone的流调人员
if (!investigatorDao.existInvestigator(respondent.getInvestigatorPhone())) {
//TODO 改为抛出相应异常
return false;
}
return respondentDao.insertRespondent(respondent);
}
@Override
public List<RespondentDto> listRespondentPageByInvestigatorPhone(String investigatorPhone, int currentPage, int pageSize) {
List<RespondentDto> voList = new ArrayList<>();
List<Respondent> respondentList = respondentDao.listLimitRespondentByInvestigator(investigatorPhone, currentPage * pageSize, pageSize);
for (Respondent respondent : respondentList) {
Investigator investigator = investigatorDao.selectInvestigator(respondent.getInvestigatorPhone());
voList.add(new RespondentDto(respondent, investigator));
}
return voList;
}
@Override
public long countRespondentByInvestigatorPhone(String investigatorPhone) {
return respondentDao.countRespondentBuInvestigatorPhone(investigatorPhone);
}
}

View File

@ -0,0 +1,35 @@
package com.example.survey.service.impl;
import com.example.survey.dao.RoleDao;
import com.example.survey.entity.Role;
import com.example.survey.enumeration.AuthEnum;
import com.example.survey.service.RoleService;
import com.example.survey.vo.RoleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.Set;
/**
* @author Pope
*/
@Service
public class RoleServiceImpl implements RoleService {
@Autowired
private RoleDao roleDao;
@Override
public boolean addRole(RoleVo roleVo) {
Role role = new Role();
role.setName(roleVo.getRoleName());
Set<AuthEnum> authoritySet = new HashSet<>();
for (Integer code : roleVo.getAuthList()) {
authoritySet.add(AuthEnum.getRoleEnum(code));
}
role.setAuthoritySet(authoritySet);
return roleDao.insertRole(role);
}
}

View File

@ -0,0 +1,101 @@
package com.example.survey.service.impl;
import com.example.survey.dao.InvestigatorDao;
import com.example.survey.dao.RoleDao;
import com.example.survey.dao.UserDao;
import com.example.survey.dto.LoginDto;
import com.example.survey.entity.Investigator;
import com.example.survey.entity.Role;
import com.example.survey.entity.User;
import com.example.survey.enumeration.AuthEnum;
import com.example.survey.service.UserService;
import com.example.survey.util.TokenUtil;
import com.example.survey.vo.LoginVo;
import com.example.survey.vo.SignupVo;
import com.example.survey.vo.UserRoleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* @author Pope
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Autowired
private TokenUtil tokenUtil;
@Autowired
private RoleDao roleDao;
@Autowired
private InvestigatorDao investigatorDao;
@Override
public LoginDto matchAuth(LoginVo loginVo) {
User user = userDao.selectUser(loginVo.getPhoneNumber(), loginVo.getPassword());
if (user == null) {
return null;
}
LoginDto loginDto = new LoginDto();
//判断是否已经登录过
if (tokenUtil.existToken(user.getPhoneNumber())) {
String oldToken = (String) tokenUtil.getValue(user.getPhoneNumber());
if (tokenUtil.existToken(oldToken)) {
//已经登录将旧token过期
tokenUtil.expire(oldToken);
}
}
//生成新的token并存入redis
String newToken = UUID.randomUUID().toString();
tokenUtil.setPhoneNumberAndToken(user.getPhoneNumber(), newToken);
//生成角色列表
Set<String> roleNameSet = new HashSet<>();
for (Role role : user.getRoleList()) {
Set<String> routeSet = new HashSet<>();
for (AuthEnum authEnum : role.getAuthoritySet()) {
routeSet.addAll(authEnum.getRoutes());
}
tokenUtil.setAuthAndRoute(role.getName(), routeSet);
roleNameSet.add(role.getName());
}
tokenUtil.setTokenAndAuth(newToken, roleNameSet);
loginDto.setToken(newToken);
loginDto.setRoleList(user.getRoleList());
loginDto.setDepartmentList(user.getDepartmentList());
return loginDto;
}
@Override
public boolean addUser(SignupVo signupVo) {
User user = new User(signupVo);
//初始化为流调人员权限
Role investigatorRole = roleDao.selectRole("流调人员");
List<Role> roleList = user.getRoleList();
roleList.add(investigatorRole);
user.setRoleList(roleList);
Investigator investigator = new Investigator();
investigator.setName(user.getUsername());
investigator.setIdNumber(user.getIdNumber());
investigator.setPhoneNumber(user.getPhoneNumber());
return userDao.insertUser(user) && investigatorDao.insertInvestigator(investigator);
}
@Override
public void modifyRoles(UserRoleVo userRoleVo) {
List<Role> roleList = new ArrayList<>();
for (String roleName : userRoleVo.getRoleNameList()) {
roleList.add(roleDao.selectRole(roleName));
}
roleDao.updateUserRoles(userRoleVo.getPhoneNumber(), roleList);
}
}

View File

@ -0,0 +1,106 @@
package com.example.survey.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* @author Pope
*/
@Component
public class TokenUtil {
/**
* 过期时间6小时
*/
private static final long EXPIRATION_TIME = 6L;
@Autowired
RedisTemplate<String, Object> redisTemplate;
/**
* 判断token是否存在
*
* @param token key
* @return 是否存在
*/
public boolean existToken(String token) {
Boolean result = redisTemplate.hasKey(token);
return result != null && result;
}
/**
* 设置<手机号, token>类型的键值对
*
* @param phoneNumber 手机号
* @param token token
*/
public void setPhoneNumberAndToken(String phoneNumber, String token) {
redisTemplate.opsForValue().set(phoneNumber, token, 6L, TimeUnit.HOURS);
}
public void refreshExpireTime(String key) {
redisTemplate.expire(key, 6L, TimeUnit.HOURS);
}
/**
* 存储token与对应的可访问路由集合
*
* @param token token
* @param authSet 对应权限集合
*/
public void setTokenAndAuth(String token, Set<String> authSet) {
redisTemplate.opsForValue().set(token, authSet, 6L, TimeUnit.HOURS);
}
public void setAuthAndRoute(String authName, Set<String> route) {
redisTemplate.opsForValue().set(authName, route);
}
/**
* 根据token与请求路由和请求方法判断是否允许访问
*
* @param token token
* @param route 请求的路由
* @param method 请求方法
* @return 是否允许访问
*/
public boolean isPass(String token, String route, String method) {
if (!existToken(token)) {
return false;
}
String request = route + " : " + method;
Set<String> authSet = (Set<String>) redisTemplate.opsForValue().get(token);
for (String auth : authSet) {
Set<String> routeSet = (Set<String>) redisTemplate.opsForValue().get(auth);
if(routeSet.contains(request)){
return true;
}
}
return false;
}
/**
* 根据key获取value
*
* @param key key
* @return value
*/
public Object getValue(String key) {
return redisTemplate.opsForValue().get(key);
}
/**
* 使某个key过期
*
* @param key 要过期的key
*/
public void expire(String key) {
redisTemplate.expire(key, 0, TimeUnit.MICROSECONDS);
}
}

View File

@ -0,0 +1,224 @@
package com.example.survey.vo;
import com.example.survey.entity.inner.Detection;
import com.example.survey.entity.inner.EntryExperience;
import com.example.survey.entity.inner.LiveAndTravelHistory;
import com.example.survey.entity.inner.TempHistory;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.*;
import org.springframework.data.mongodb.core.index.Indexed;
import java.util.Date;
import java.util.List;
/**
* @author Pope
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class InvestigationRecordVo {
/**
* 问卷编号
*/
private String questionnaireNumber;
/**
* 身份证号
* 唯一索引
*/
private String idNumber;
//==================================基本信息==================================
/**
* 姓名
*/
private String name;
/**
* 性别
* true为男性false为女性
*/
private String gender;
/**
* 是否为境外病例
*/
private boolean overseasCase;
/**
* 是否为病例
* 区分病例与密切接触者
*/
private boolean diseased;
/**
* 入境经历
* 选填
*/
private EntryExperience entryExperience;
//==================================病例发现与就诊==================================
/**
* 病例被发现途径
*/
private String wayOfBeingDiscovered;
/**
* 入院时间
*/
@JsonFormat(pattern = "yyyy-MM-dd")
private Date dateOfAdmission;
/**
* 入院时症状和体征
*/
private List<String> symptomAndSign;
/**
* 有无并发症
*/
private boolean existComplication;
/**
* 并发症
* 选填
*/
private List<String> complication;
/**
* 当并发症存在发热时记录最高体温
*/
private String maxTemp;
/**
* 胸部X线或 CT 检测是否有肺炎影像学特征
*/
private boolean existImagingFeatureOfPneumonia;
/**
* 如果肺炎影像学特征为是此处填检测时间
*/
@JsonFormat(pattern = "yyyy-MM-dd")
private Date testDate;
/**
* 出院日期
* 年月日
*/
@JsonFormat(pattern = "yyyy-MM-dd")
private Date dateOfDischarge;
//==================================危险因素与暴露史==================================
/**
* 是否为特定职业人群
*/
private String specificOccupation;
/**
* 当specificOccupation为other时起作用
*/
private String otherSpecificOccupation;
/**
* 如为医护人员填写具体工作性质
*/
private String workInformation;
/**
* 当workInformation为other时起作用
*/
private String otherWorkInformation;
/**
* 是否为孕妇
*/
private boolean pregnant;
/**
* 孕周
*/
private int pregnantWeek;
/**
* 病史
*/
private List<String> medicalHistory;
/**
* 对既往病史的详细描述
*/
private String medicalHistoryDetail;
//==================================发病或检测阳性前14天内是否有以下暴露史或接触史==================================
/**
* 是否有境外疫情严重国家或地区的旅行史或居住史
*/
private boolean nearSeriousRegion;
/**
* 是否接触过来自境外疫情严重的国家或地区的发热或有呼吸道症状的患者
*/
private boolean contactWithSeriousRegionPatients;
/**
* 是否曾有确诊病例或无症状感染者的接触史
*/
private boolean contactWithConfirmedCase;
/**
* 患者同一家庭办公室学校或托幼机构班级车间等集体单位是否有聚集性发病
*/
private boolean aggregationDisease;
//==================================实验室检测==================================
/**
* 实验室检测结果未采集则value为null
*/
private List<Detection> detectionList;
/**
* 调查单位
*/
private String investigationCompany;
/**
* 调查者身份证
* 外键
*/
@Indexed
private String investigatorPhone;
/**
* 调查日期
* 年月日
*/
@JsonFormat(pattern = "yyyy-MM-dd")
private Date investigationDate;
/**
* 体温历史
*/
private List<TempHistory> tempHistoryList;
/**
* 居旅史
*/
private List<LiveAndTravelHistory> liveAndTravelHistoryList;
/**
* 备注
*/
private String msg;
}

View File

@ -0,0 +1,16 @@
package com.example.survey.vo;
import lombok.*;
/**
* @author Pope
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class LoginVo {
private String phoneNumber;
private String password;
}

View File

@ -0,0 +1,59 @@
package com.example.survey.vo;
/**
* @author Pope
* 返回结果类
*/
public class ResultVo {
public static final int SUCCESS = 0;
public static final int FAILED = 1;
/**
* 状态码
*/
private int code;
/**
* 信息
*/
private String msg;
/**
* 数据
*/
private Object data;
public ResultVo() {
}
public ResultVo(int code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}

View File

@ -0,0 +1,30 @@
package com.example.survey.vo;
import lombok.*;
/**
* @author Pope
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class ReviewVo {
/**
* 调查记录对应的调查对象的身份证号
*/
private String idNumber;
/**
* 是否审核通过
*/
private boolean pass;
/**
* 审核信息
*/
private String msg;
/**
* 审核者id
*/
private String reviewerPhone;
}

View File

@ -0,0 +1,18 @@
package com.example.survey.vo;
import lombok.*;
import java.util.List;
/**
* @author Pope
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class RoleVo {
private String roleName;
private List<Integer> authList;
}

View File

@ -0,0 +1,26 @@
package com.example.survey.vo;
import lombok.*;
/**
* @author Pope
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class SignupVo {
/**
* 用户名
*/
private String username;
/**
* 手机号
*/
private String phoneNumber;
/**
* 密码
*/
private String password;
}

View File

@ -0,0 +1,18 @@
package com.example.survey.vo;
import lombok.*;
import java.util.List;
/**
* @author Pope
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class UserRoleVo {
private String phoneNumber;
private List<String> roleNameList;
}

View File

@ -0,0 +1,38 @@
spring:
data:
mongodb:
# uri: mongodb://cveo:cveo123456@120.78.177.67:27017/survey
#创建索引
auto-index-creation: true
host: mongo
port: 27017
database: survey
username: cveo
password: cveo123456
authentication-database: admin
redis:
host: redis
port: 6379
password: cveo
# kafka:
# bootstrap-servers: localhost:9092 # 指定kafka 代理地址,可以多个
# producer: # 生产者
# retries: 0 # 设置大于0的值则客户端会将发送失败的记录重新发送
# # 每次批量发送消息的数量
# batch-size: 16384
# buffer-memory: 33554432
# # 指定消息key和消息体的编解码方式
# key-serializer: org.apache.kafka.common.serialization.StringSerializer
# value-serializer: org.apache.kafka.common.serialization.StringSerializer
# consumer:
# group-id: consumer-test
# enable-auto-commit: true # 是否自动提交offset
# auto-commit-interval: 100 # 提交offset延时(接收到消息后多久提交offset)
# auto-offset-reset: latest
# # 指定消息key和消息体的编解码方式
# key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
# value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
# topic:
# under-review: "under_review"

View File

@ -0,0 +1,13 @@
package com.example.survey;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SurveyApplicationTests {
@Test
void contextLoads() {
}
}

View File

@ -0,0 +1,49 @@
POST http://localhost:8080/role/role
Content-Type: application/json
{
"roleName": "流调人员",
"authList": [
1,
2,
3,
5,
6,
8,
9,
10
]
}
###
POST http://localhost:8080/role/role
Content-Type: application/json
{
"roleName": "管理员",
"authList": [
0
]
}
###
POST http://{{host}}:8080/user/signup
Content-Type: application/json
{
"username": "cveo",
"phoneNumber": "123456789",
"password": "cveo123456"
}
###
PUT http://localhost:8080/user/userRole
Content-Type:application/json
{
"phoneNumber": "123456789",
"roleNameList": ["管理员"]
}

View File

@ -0,0 +1,200 @@
#提交调查记录
POST http://localhost:8080/investigationRecord/investigationRecord
Content-Type: application/json
{
"questionnaireNumber": "002",
"idNumber": "420704200002270011",
"name": "Pope0",
"gender": "男",
"overseasCase": false,
"diseased": false,
"entryExperience": {
"areaOfResidence": "武汉市",
"areaOfAccess": "武汉市",
"nationality": "中国",
"passportNumber": "000000",
"entryPort": {
"province": "湖北省",
"port": "天河机场"
},
"entryDate": "2021-1-28",
"transportation": "航班XXX"
},
"wayOfBeingDiscovered": "否",
"dateOfAdmission": "2021-1-28",
"symptomAndSign": [
"症状1",
"症状2"
],
"existComplication": true,
"complication": [
"并发症1",
"并发症2"
],
"maxTemp": "36.5",
"existImagingFeatureOfPneumonia": true,
"testDate": "2021-1-28",
"dateOfDischarge": "2021-1-28",
"specificOccupation": "other",
"otherSpecificOccupation": "学生",
"workInformation": "否",
"otherWorkInformation": "",
"pregnant": false,
"pregnantWeek": 0,
"medicalHistory": [
"病史1",
"病史2"
],
"medicalHistoryDetail": "病史描述",
"nearSeriousRegion": false,
"contactWithSeriousRegionPatients": false,
"contactWithConfirmedCase": false,
"aggregationDisease": false,
"detectionList": [
{
"name": "咽拭子",
"date": "2021-1-28",
"result": "阴性"
},
{
"name": "鼻拭子",
"date": "2021-1-28",
"result": "阴性"
}
],
"investigationCompany": "武汉大学",
"investigatorPhone": "13995833301",
"investigationDate": "2021-1-28",
"tempHistoryList": [
{
"time": "2021-1-28:10:07:20",
"data": "36.5"
}
],
"liveAndTravelHistoryList": [
{
"type": [
"居住史",
"旅行史"
],
"beginTime": "2021-1-28",
"endTime": "2021-1-29",
"location": "鄂州市",
"detail": "详细描述"
}
],
"msg": "备注信息"
}
###
#查询调查记录
GET http://localhost:8080/investigationRecord/underReviewRecord?currentPage=0&state=待审核
###
#查询未审核记录数量
GET http://localhost:8080/investigationRecord/underReviewRecordCount?investigatorPhone=13995833300
###
PUT http://localhost:8080/investigationRecord/underReviewRecord
Content-Type: application/json
{
"idNumber": "420704200002270011",
"pass": true,
"passInformation": "经审核通过",
"reviewerPhone": "13995833300"
}
###
#查询
PUT http://localhost:8080/investigationRecord/investigationRecord
Content-Type: application/json
{
"questionnaireNumber": "002",
"idNumber": "420704200002270011",
"name": "Pope0",
"gender": "女",
"overseasCase": false,
"diseased": false,
"entryExperience": {
"areaOfResidence": "武汉市",
"areaOfAccess": "武汉市",
"nationality": "中国",
"passportNumber": "000000",
"entryPort": {
"province": "湖北省",
"port": "天河机场"
},
"entryDate": "2021-1-28",
"transportation": "航班XXX"
},
"wayOfBeingDiscovered": "否",
"dateOfAdmission": "2021-1-28",
"symptomAndSign": [
"症状1",
"症状2"
],
"existComplication": true,
"complication": [
"并发症1",
"并发症2"
],
"maxTemp": "36.5",
"existImagingFeatureOfPneumonia": true,
"testDate": "2021-1-28",
"dateOfDischarge": "2021-1-28",
"specificOccupation": "other",
"otherSpecificOccupation": "学生",
"workInformation": "否",
"otherWorkInformation": "",
"pregnant": false,
"pregnantWeek": 0,
"medicalHistory": [
"病史1",
"病史2"
],
"medicalHistoryDetail": "病史描述",
"nearSeriousRegion": false,
"contactWithSeriousRegionPatients": false,
"contactWithConfirmedCase": false,
"aggregationDisease": false,
"detectionList": [
{
"name": "咽拭子",
"date": "2021-1-28",
"result": "阴性"
},
{
"name": "鼻拭子",
"date": "2021-1-28",
"result": "阴性"
}
],
"investigationCompany": "武汉大学",
"investigatorPhone": "13995833301",
"investigationDate": "2021-1-28",
"tempHistoryList": [
{
"time": "2021-1-28:10:07:20",
"data": "36.5"
}
],
"liveAndTravelHistoryList": [
{
"type": [
"居住史",
"旅行史"
],
"beginTime": "2021-1-28",
"endTime": "2021-1-29",
"location": "鄂州市",
"detail": "详细描述"
}
],
"msg": "备注信息"
}

View File

@ -0,0 +1,13 @@
#创建流调人员
POST http://localhost:8080/investigator/investigator
Content-Type: application/json
Authorization: fcf3f723-5a65-45ad-a518-f92e1c32b948
{
"idNumber": null,
"name": "Pope2",
"phoneNumber": "13995833302"
}
###

View File

@ -0,0 +1,22 @@
###
#创建调查对象
POST http://{{host}}:{{port}}{{prefix}}/respondent/respondent
Content-Type: application/json
Authorization: cb94336e-f849-4e04-b956-9d8f71fe7830
{
"idNumber": "420704200002270014",
"phoneNumber": "13995833308",
"name": "Pope4",
"msg": "无备注",
"investigatorPhone": "123456789",
"diseased": false,
"gender": "男"
}
###
#根据流调人员id分页查询待调查对象列表
GET http://localhost:8080/respondent/respondent?investigatorPhone=13995833300&currentPage=0

View File

@ -0,0 +1,26 @@
POST http://localhost:8080/role/role
Content-Type: application/json
{
"roleName": "流调人员",
"authList": [
1,
2,
3,
5,
6,
8,
9,
10
]
}
###
POST http://localhost:8080/role/role
Content-Type: application/json
{
"roleName": "管理员",
"authList": [
0
]
}

View File

@ -0,0 +1,26 @@
POST http://localhost:8080/user/signup
Content-Type: application/json
{
"username": "cveo",
"phoneNumber": "123456789",
"password": "cveo123456"
}
###
PUT http://localhost:8080/user/userRole
Content-Type:application/json
{
"phoneNumber": "123456789",
"roleNameList": ["管理员"]
}
###
POST http://{{host}}:{{port}}{{prefix}}/user/login
Content-Type: application/json
{
"phoneNumber": "123456789",
"password": "cveo123456"
}

View File

@ -0,0 +1,12 @@
{
"dev": {
"host": "120.78.177.67",
"port": "8080",
"prefix": ""
},
"prod": {
"host": "8.136.133.77",
"port": "8081",
"prefix": "/backend"
}
}