├── .gitignore ├── README.md ├── doc └── db.md ├── mvnw ├── mvnw.cmd ├── pom.xml ├── sql └── ddl.sql └── src ├── main ├── java │ └── com │ │ └── yupi │ │ └── project │ │ ├── MyApplication.java │ │ ├── annotation │ │ └── AuthCheck.java │ │ ├── aop │ │ ├── AuthInterceptor.java │ │ └── LogInterceptor.java │ │ ├── common │ │ ├── BaseResponse.java │ │ ├── DeleteRequest.java │ │ ├── ErrorCode.java │ │ ├── PageRequest.java │ │ └── ResultUtils.java │ │ ├── config │ │ ├── CorsConfig.java │ │ ├── Knife4jConfig.java │ │ └── MyBatisPlusConfig.java │ │ ├── constant │ │ ├── CommonConstant.java │ │ └── UserConstant.java │ │ ├── controller │ │ ├── PostController.java │ │ └── UserController.java │ │ ├── exception │ │ ├── BusinessException.java │ │ └── GlobalExceptionHandler.java │ │ ├── mapper │ │ ├── PostMapper.java │ │ └── UserMapper.java │ │ ├── model │ │ ├── dto │ │ │ ├── post │ │ │ │ ├── PostAddRequest.java │ │ │ │ ├── PostDoThumbRequest.java │ │ │ │ ├── PostQueryRequest.java │ │ │ │ └── PostUpdateRequest.java │ │ │ └── user │ │ │ │ ├── UserAddRequest.java │ │ │ │ ├── UserLoginRequest.java │ │ │ │ ├── UserQueryRequest.java │ │ │ │ ├── UserRegisterRequest.java │ │ │ │ └── UserUpdateRequest.java │ │ ├── entity │ │ │ ├── Post.java │ │ │ └── User.java │ │ ├── enums │ │ │ ├── PostGenderEnum.java │ │ │ └── PostReviewStatusEnum.java │ │ └── vo │ │ │ ├── PostVO.java │ │ │ └── UserVO.java │ │ └── service │ │ ├── PostService.java │ │ ├── UserService.java │ │ └── impl │ │ ├── PostServiceImpl.java │ │ └── UserServiceImpl.java └── resources │ ├── application-prod.yml │ ├── application.yml │ ├── banner.txt │ └── mapper │ ├── PostMapper.xml │ └── UserMapper.xml └── test └── java └── com └── yupi └── project └── service └── UserServiceTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SpringBoot 项目初始模板 2 | 3 | > Java SpringBoot 项目初始模板,整合了常用框架和示例代码,大家可以在此基础上快速开发自己的项目。 4 | 5 | ## 模板功能 6 | 7 | - Spring Boot 2.7.0(贼新) 8 | - Spring MVC 9 | - MySQL 驱动 10 | - MyBatis 11 | - MyBatis Plus 12 | - Spring Session Redis 分布式登录 13 | - Spring AOP 14 | - Apache Commons Lang3 工具类 15 | - Lombok 注解 16 | - Swagger + Knife4j 接口文档 17 | - Spring Boot 调试工具和项目处理器 18 | - 全局请求响应拦截器(记录日志) 19 | - 全局异常处理器 20 | - 自定义错误码 21 | - 封装通用响应类 22 | - 示例用户注册、登录、搜索功能 23 | - 示例单元测试类 24 | - 示例 SQL(用户表) 25 | 26 | 访问 localhost:7529/api/doc.html 就能在线调试接口了,不需要前端配合啦~ -------------------------------------------------------------------------------- /doc/db.md: -------------------------------------------------------------------------------- 1 | # 数据库设计 2 | 3 | > 建表语句见 `sql/ddl.sql` 文件 4 | 5 | ## 用户信息表 6 | 7 | 8 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /usr/local/etc/mavenrc ] ; then 40 | . /usr/local/etc/mavenrc 41 | fi 42 | 43 | if [ -f /etc/mavenrc ] ; then 44 | . /etc/mavenrc 45 | fi 46 | 47 | if [ -f "$HOME/.mavenrc" ] ; then 48 | . "$HOME/.mavenrc" 49 | fi 50 | 51 | fi 52 | 53 | # OS specific support. $var _must_ be set to either true or false. 54 | cygwin=false; 55 | darwin=false; 56 | mingw=false 57 | case "`uname`" in 58 | CYGWIN*) cygwin=true ;; 59 | MINGW*) mingw=true;; 60 | Darwin*) darwin=true 61 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 62 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 63 | if [ -z "$JAVA_HOME" ]; then 64 | if [ -x "/usr/libexec/java_home" ]; then 65 | export JAVA_HOME="`/usr/libexec/java_home`" 66 | else 67 | export JAVA_HOME="/Library/Java/Home" 68 | fi 69 | fi 70 | ;; 71 | esac 72 | 73 | if [ -z "$JAVA_HOME" ] ; then 74 | if [ -r /etc/gentoo-release ] ; then 75 | JAVA_HOME=`java-config --jre-home` 76 | fi 77 | fi 78 | 79 | if [ -z "$M2_HOME" ] ; then 80 | ## resolve links - $0 may be a link to maven's home 81 | PRG="$0" 82 | 83 | # need this for relative symlinks 84 | while [ -h "$PRG" ] ; do 85 | ls=`ls -ld "$PRG"` 86 | link=`expr "$ls" : '.*-> \(.*\)$'` 87 | if expr "$link" : '/.*' > /dev/null; then 88 | PRG="$link" 89 | else 90 | PRG="`dirname "$PRG"`/$link" 91 | fi 92 | done 93 | 94 | saveddir=`pwd` 95 | 96 | M2_HOME=`dirname "$PRG"`/.. 97 | 98 | # make it fully qualified 99 | M2_HOME=`cd "$M2_HOME" && pwd` 100 | 101 | cd "$saveddir" 102 | # echo Using m2 at $M2_HOME 103 | fi 104 | 105 | # For Cygwin, ensure paths are in UNIX format before anything is touched 106 | if $cygwin ; then 107 | [ -n "$M2_HOME" ] && 108 | M2_HOME=`cygpath --unix "$M2_HOME"` 109 | [ -n "$JAVA_HOME" ] && 110 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 111 | [ -n "$CLASSPATH" ] && 112 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 113 | fi 114 | 115 | # For Mingw, ensure paths are in UNIX format before anything is touched 116 | if $mingw ; then 117 | [ -n "$M2_HOME" ] && 118 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 119 | [ -n "$JAVA_HOME" ] && 120 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 121 | fi 122 | 123 | if [ -z "$JAVA_HOME" ]; then 124 | javaExecutable="`which javac`" 125 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 126 | # readlink(1) is not available as standard on Solaris 10. 127 | readLink=`which readlink` 128 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 129 | if $darwin ; then 130 | javaHome="`dirname \"$javaExecutable\"`" 131 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 132 | else 133 | javaExecutable="`readlink -f \"$javaExecutable\"`" 134 | fi 135 | javaHome="`dirname \"$javaExecutable\"`" 136 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 137 | JAVA_HOME="$javaHome" 138 | export JAVA_HOME 139 | fi 140 | fi 141 | fi 142 | 143 | if [ -z "$JAVACMD" ] ; then 144 | if [ -n "$JAVA_HOME" ] ; then 145 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 146 | # IBM's JDK on AIX uses strange locations for the executables 147 | JAVACMD="$JAVA_HOME/jre/sh/java" 148 | else 149 | JAVACMD="$JAVA_HOME/bin/java" 150 | fi 151 | else 152 | JAVACMD="`\\unset -f command; \\command -v java`" 153 | fi 154 | fi 155 | 156 | if [ ! -x "$JAVACMD" ] ; then 157 | echo "Error: JAVA_HOME is not defined correctly." >&2 158 | echo " We cannot execute $JAVACMD" >&2 159 | exit 1 160 | fi 161 | 162 | if [ -z "$JAVA_HOME" ] ; then 163 | echo "Warning: JAVA_HOME environment variable is not set." 164 | fi 165 | 166 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 167 | 168 | # traverses directory structure from process work directory to filesystem root 169 | # first directory with .mvn subdirectory is considered project base directory 170 | find_maven_basedir() { 171 | 172 | if [ -z "$1" ] 173 | then 174 | echo "Path not specified to find_maven_basedir" 175 | return 1 176 | fi 177 | 178 | basedir="$1" 179 | wdir="$1" 180 | while [ "$wdir" != '/' ] ; do 181 | if [ -d "$wdir"/.mvn ] ; then 182 | basedir=$wdir 183 | break 184 | fi 185 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 186 | if [ -d "${wdir}" ]; then 187 | wdir=`cd "$wdir/.."; pwd` 188 | fi 189 | # end of workaround 190 | done 191 | echo "${basedir}" 192 | } 193 | 194 | # concatenates all lines of a file 195 | concat_lines() { 196 | if [ -f "$1" ]; then 197 | echo "$(tr -s '\n' ' ' < "$1")" 198 | fi 199 | } 200 | 201 | BASE_DIR=`find_maven_basedir "$(pwd)"` 202 | if [ -z "$BASE_DIR" ]; then 203 | exit 1; 204 | fi 205 | 206 | ########################################################################################## 207 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 208 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 209 | ########################################################################################## 210 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Found .mvn/wrapper/maven-wrapper.jar" 213 | fi 214 | else 215 | if [ "$MVNW_VERBOSE" = true ]; then 216 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 217 | fi 218 | if [ -n "$MVNW_REPOURL" ]; then 219 | jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 220 | else 221 | jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 222 | fi 223 | while IFS="=" read key value; do 224 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 225 | esac 226 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 227 | if [ "$MVNW_VERBOSE" = true ]; then 228 | echo "Downloading from: $jarUrl" 229 | fi 230 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 231 | if $cygwin; then 232 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 233 | fi 234 | 235 | if command -v wget > /dev/null; then 236 | if [ "$MVNW_VERBOSE" = true ]; then 237 | echo "Found wget ... using wget" 238 | fi 239 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 240 | wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 241 | else 242 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 243 | fi 244 | elif command -v curl > /dev/null; then 245 | if [ "$MVNW_VERBOSE" = true ]; then 246 | echo "Found curl ... using curl" 247 | fi 248 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 249 | curl -o "$wrapperJarPath" "$jarUrl" -f 250 | else 251 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 252 | fi 253 | 254 | else 255 | if [ "$MVNW_VERBOSE" = true ]; then 256 | echo "Falling back to using Java to download" 257 | fi 258 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 259 | # For Cygwin, switch paths to Windows format before running javac 260 | if $cygwin; then 261 | javaClass=`cygpath --path --windows "$javaClass"` 262 | fi 263 | if [ -e "$javaClass" ]; then 264 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 265 | if [ "$MVNW_VERBOSE" = true ]; then 266 | echo " - Compiling MavenWrapperDownloader.java ..." 267 | fi 268 | # Compiling the Java class 269 | ("$JAVA_HOME/bin/javac" "$javaClass") 270 | fi 271 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 272 | # Running the downloader 273 | if [ "$MVNW_VERBOSE" = true ]; then 274 | echo " - Running MavenWrapperDownloader.java ..." 275 | fi 276 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 277 | fi 278 | fi 279 | fi 280 | fi 281 | ########################################################################################## 282 | # End of extension 283 | ########################################################################################## 284 | 285 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 286 | if [ "$MVNW_VERBOSE" = true ]; then 287 | echo $MAVEN_PROJECTBASEDIR 288 | fi 289 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 290 | 291 | # For Cygwin, switch paths to Windows format before running java 292 | if $cygwin; then 293 | [ -n "$M2_HOME" ] && 294 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 295 | [ -n "$JAVA_HOME" ] && 296 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 297 | [ -n "$CLASSPATH" ] && 298 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 299 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 300 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 301 | fi 302 | 303 | # Provide a "standardized" way to retrieve the CLI args that will 304 | # work with both Windows and non-Windows executions. 305 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 306 | export MAVEN_CMD_LINE_ARGS 307 | 308 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 309 | 310 | exec "$JAVACMD" \ 311 | $MAVEN_OPTS \ 312 | $MAVEN_DEBUG_OPTS \ 313 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 314 | "-Dmaven.home=${M2_HOME}" \ 315 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 316 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 317 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* 50 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 124 | 125 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% ^ 162 | %JVM_CONFIG_MAVEN_PROPS% ^ 163 | %MAVEN_OPTS% ^ 164 | %MAVEN_DEBUG_OPTS% ^ 165 | -classpath %WRAPPER_JAR% ^ 166 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ 167 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 168 | if ERRORLEVEL 1 goto error 169 | goto end 170 | 171 | :error 172 | set ERROR_CODE=1 173 | 174 | :end 175 | @endlocal & set ERROR_CODE=%ERROR_CODE% 176 | 177 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost 178 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 179 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" 180 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" 181 | :skipRcPost 182 | 183 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 184 | if "%MAVEN_BATCH_PAUSE%"=="on" pause 185 | 186 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% 187 | 188 | cmd /C exit /B %ERROR_CODE% 189 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.boot 8 | spring-boot-starter-parent 9 | 2.7.0 10 | 11 | 12 | com.yupi 13 | springboot-init 14 | 0.0.1-SNAPSHOT 15 | springboot-init 16 | springboot 初始项目 17 | 18 | 1.8 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-aop 28 | 29 | 30 | org.mybatis.spring.boot 31 | mybatis-spring-boot-starter 32 | 2.2.2 33 | 34 | 35 | com.baomidou 36 | mybatis-plus-boot-starter 37 | 3.5.1 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-data-redis 42 | 43 | 44 | org.springframework.session 45 | spring-session-data-redis 46 | 47 | 48 | 49 | com.google.code.gson 50 | gson 51 | 2.9.0 52 | 53 | 54 | 55 | org.apache.commons 56 | commons-lang3 57 | 3.12.0 58 | 59 | 60 | 61 | com.github.xiaoymin 62 | knife4j-spring-boot-starter 63 | 3.0.3 64 | 65 | 66 | org.springframework.boot 67 | spring-boot-devtools 68 | runtime 69 | true 70 | 71 | 72 | mysql 73 | mysql-connector-java 74 | runtime 75 | 76 | 77 | org.springframework.boot 78 | spring-boot-configuration-processor 79 | true 80 | 81 | 82 | org.projectlombok 83 | lombok 84 | true 85 | 86 | 87 | org.springframework.boot 88 | spring-boot-starter-test 89 | test 90 | 91 | 92 | 93 | junit 94 | junit 95 | 4.13.2 96 | test 97 | 98 | 99 | 100 | 101 | 102 | 103 | org.springframework.boot 104 | spring-boot-maven-plugin 105 | 106 | 107 | 108 | org.projectlombok 109 | lombok 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /sql/ddl.sql: -------------------------------------------------------------------------------- 1 | -- 创建库 2 | create database if not exists my_db; 3 | 4 | -- 切换库 5 | use my_db; 6 | 7 | -- 用户表 8 | create table if not exists user 9 | ( 10 | id bigint auto_increment comment 'id' primary key, 11 | userName varchar(256) null comment '用户昵称', 12 | userAccount varchar(256) not null comment '账号', 13 | userAvatar varchar(1024) null comment '用户头像', 14 | gender tinyint null comment '性别', 15 | userRole varchar(256) default 'user' not null comment '用户角色:user / admin', 16 | userPassword varchar(512) not null comment '密码', 17 | createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间', 18 | updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间', 19 | isDelete tinyint default 0 not null comment '是否删除', 20 | constraint uni_userAccount 21 | unique (userAccount) 22 | ) comment '用户'; 23 | 24 | -- 帖子表 25 | create table if not exists post 26 | ( 27 | id bigint auto_increment comment 'id' primary key, 28 | age int comment '年龄', 29 | gender tinyint default 0 not null comment '性别(0-男, 1-女)', 30 | education varchar(512) null comment '学历', 31 | place varchar(512) null comment '地点', 32 | job varchar(512) null comment '职业', 33 | contact varchar(512) null comment '联系方式', 34 | loveExp varchar(512) null comment '感情经历', 35 | content text null comment '内容(个人介绍)', 36 | photo varchar(1024) null comment '照片地址', 37 | reviewStatus int default 0 not null comment '状态(0-待审核, 1-通过, 2-拒绝)', 38 | reviewMessage varchar(512) null comment '审核信息', 39 | viewNum int not null default 0 comment '浏览数', 40 | thumbNum int not null default 0 comment '点赞数', 41 | userId bigint not null comment '创建用户 id', 42 | createTime datetime default CURRENT_TIMESTAMP not null comment '创建时间', 43 | updateTime datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间', 44 | isDelete tinyint default 0 not null comment '是否删除' 45 | ) comment '帖子'; -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/MyApplication.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | @SpringBootApplication 8 | @MapperScan("com.yupi.project.mapper") 9 | public class MyApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(MyApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/annotation/AuthCheck.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * 权限校验 10 | * 11 | * @author yupi 12 | */ 13 | @Target(ElementType.METHOD) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface AuthCheck { 16 | 17 | /** 18 | * 有任何一个角色 19 | * 20 | * @return 21 | */ 22 | String[] anyRole() default ""; 23 | 24 | /** 25 | * 必须有某个角色 26 | * 27 | * @return 28 | */ 29 | String mustRole() default ""; 30 | 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/aop/AuthInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.aop; 2 | 3 | import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; 4 | import com.yupi.project.annotation.AuthCheck; 5 | import com.yupi.project.common.ErrorCode; 6 | import com.yupi.project.exception.BusinessException; 7 | import com.yupi.project.model.entity.User; 8 | import com.yupi.project.service.UserService; 9 | import org.apache.commons.lang3.StringUtils; 10 | import org.aspectj.lang.ProceedingJoinPoint; 11 | import org.aspectj.lang.annotation.Around; 12 | import org.aspectj.lang.annotation.Aspect; 13 | import org.springframework.stereotype.Component; 14 | import org.springframework.web.context.request.RequestAttributes; 15 | import org.springframework.web.context.request.RequestContextHolder; 16 | import org.springframework.web.context.request.ServletRequestAttributes; 17 | 18 | import javax.annotation.Resource; 19 | import javax.servlet.http.HttpServletRequest; 20 | import java.util.Arrays; 21 | import java.util.List; 22 | import java.util.stream.Collectors; 23 | 24 | 25 | /** 26 | * 权限校验 AOP 27 | * 28 | * @author yupi 29 | */ 30 | @Aspect 31 | @Component 32 | public class AuthInterceptor { 33 | 34 | @Resource 35 | private UserService userService; 36 | 37 | /** 38 | * 执行拦截 39 | * 40 | * @param joinPoint 41 | * @param authCheck 42 | * @return 43 | */ 44 | @Around("@annotation(authCheck)") 45 | public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable { 46 | List anyRole = Arrays.stream(authCheck.anyRole()).filter(StringUtils::isNotBlank).collect(Collectors.toList()); 47 | String mustRole = authCheck.mustRole(); 48 | RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes(); 49 | HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); 50 | // 当前登录用户 51 | User user = userService.getLoginUser(request); 52 | // 拥有任意权限即通过 53 | if (CollectionUtils.isNotEmpty(anyRole)) { 54 | String userRole = user.getUserRole(); 55 | if (!anyRole.contains(userRole)) { 56 | throw new BusinessException(ErrorCode.NO_AUTH_ERROR); 57 | } 58 | } 59 | // 必须有所有权限才通过 60 | if (StringUtils.isNotBlank(mustRole)) { 61 | String userRole = user.getUserRole(); 62 | if (!mustRole.equals(userRole)) { 63 | throw new BusinessException(ErrorCode.NO_AUTH_ERROR); 64 | } 65 | } 66 | // 通过权限校验,放行 67 | return joinPoint.proceed(); 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/aop/LogInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.aop; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.apache.commons.lang3.StringUtils; 5 | import org.aspectj.lang.ProceedingJoinPoint; 6 | import org.aspectj.lang.annotation.Around; 7 | import org.aspectj.lang.annotation.Aspect; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.util.StopWatch; 10 | import org.springframework.web.context.request.RequestAttributes; 11 | import org.springframework.web.context.request.RequestContextHolder; 12 | import org.springframework.web.context.request.ServletRequestAttributes; 13 | 14 | import javax.servlet.http.HttpServletRequest; 15 | import java.util.UUID; 16 | 17 | /** 18 | * 请求响应日志 AOP 19 | * 20 | * @author yupi 21 | **/ 22 | @Aspect 23 | @Component 24 | @Slf4j 25 | public class LogInterceptor { 26 | 27 | /** 28 | * 执行拦截 29 | */ 30 | @Around("execution(* com.yupi.project.controller.*.*(..))") 31 | public Object doInterceptor(ProceedingJoinPoint point) throws Throwable { 32 | // 计时 33 | StopWatch stopWatch = new StopWatch(); 34 | stopWatch.start(); 35 | // 获取请求路径 36 | RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes(); 37 | HttpServletRequest httpServletRequest = ((ServletRequestAttributes) requestAttributes).getRequest(); 38 | // 生成请求唯一 id 39 | String requestId = UUID.randomUUID().toString(); 40 | String url = httpServletRequest.getRequestURI(); 41 | // 获取请求参数 42 | Object[] args = point.getArgs(); 43 | String reqParam = "[" + StringUtils.join(args, ", ") + "]"; 44 | // 输出请求日志 45 | log.info("request start,id: {}, path: {}, ip: {}, params: {}", requestId, url, 46 | httpServletRequest.getRemoteHost(), reqParam); 47 | // 执行原方法 48 | Object result = point.proceed(); 49 | // 输出响应日志 50 | stopWatch.stop(); 51 | long totalTimeMillis = stopWatch.getTotalTimeMillis(); 52 | log.info("request end, id: {}, cost: {}ms", requestId, totalTimeMillis); 53 | return result; 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/common/BaseResponse.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.common; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * 通用返回类 9 | * 10 | * @param 11 | * @author yupi 12 | */ 13 | @Data 14 | public class BaseResponse implements Serializable { 15 | 16 | private int code; 17 | 18 | private T data; 19 | 20 | private String message; 21 | 22 | public BaseResponse(int code, T data, String message) { 23 | this.code = code; 24 | this.data = data; 25 | this.message = message; 26 | } 27 | 28 | public BaseResponse(int code, T data) { 29 | this(code, data, ""); 30 | } 31 | 32 | public BaseResponse(ErrorCode errorCode) { 33 | this(errorCode.getCode(), null, errorCode.getMessage()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/common/DeleteRequest.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.common; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * 删除请求 9 | * 10 | * @author yupi 11 | */ 12 | @Data 13 | public class DeleteRequest implements Serializable { 14 | /** 15 | * id 16 | */ 17 | private Long id; 18 | 19 | private static final long serialVersionUID = 1L; 20 | } -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/common/ErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.common; 2 | 3 | /** 4 | * 错误码 5 | * 6 | * @author yupi 7 | */ 8 | public enum ErrorCode { 9 | 10 | SUCCESS(0, "ok"), 11 | PARAMS_ERROR(40000, "请求参数错误"), 12 | NOT_LOGIN_ERROR(40100, "未登录"), 13 | NO_AUTH_ERROR(40101, "无权限"), 14 | NOT_FOUND_ERROR(40400, "请求数据不存在"), 15 | FORBIDDEN_ERROR(40300, "禁止访问"), 16 | SYSTEM_ERROR(50000, "系统内部异常"), 17 | OPERATION_ERROR(50001, "操作失败"); 18 | 19 | /** 20 | * 状态码 21 | */ 22 | private final int code; 23 | 24 | /** 25 | * 信息 26 | */ 27 | private final String message; 28 | 29 | ErrorCode(int code, String message) { 30 | this.code = code; 31 | this.message = message; 32 | } 33 | 34 | public int getCode() { 35 | return code; 36 | } 37 | 38 | public String getMessage() { 39 | return message; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/common/PageRequest.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.common; 2 | 3 | import com.yupi.project.constant.CommonConstant; 4 | import lombok.Data; 5 | 6 | /** 7 | * 分页请求 8 | * 9 | * @author yupi 10 | */ 11 | @Data 12 | public class PageRequest { 13 | 14 | /** 15 | * 当前页号 16 | */ 17 | private long current = 1; 18 | 19 | /** 20 | * 页面大小 21 | */ 22 | private long pageSize = 10; 23 | 24 | /** 25 | * 排序字段 26 | */ 27 | private String sortField; 28 | 29 | /** 30 | * 排序顺序(默认升序) 31 | */ 32 | private String sortOrder = CommonConstant.SORT_ORDER_ASC; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/common/ResultUtils.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.common; 2 | 3 | /** 4 | * 返回工具类 5 | * 6 | * @author yupi 7 | */ 8 | public class ResultUtils { 9 | 10 | /** 11 | * 成功 12 | * 13 | * @param data 14 | * @param 15 | * @return 16 | */ 17 | public static BaseResponse success(T data) { 18 | return new BaseResponse<>(0, data, "ok"); 19 | } 20 | 21 | /** 22 | * 失败 23 | * 24 | * @param errorCode 25 | * @return 26 | */ 27 | public static BaseResponse error(ErrorCode errorCode) { 28 | return new BaseResponse<>(errorCode); 29 | } 30 | 31 | /** 32 | * 失败 33 | * 34 | * @param code 35 | * @param message 36 | * @return 37 | */ 38 | public static BaseResponse error(int code, String message) { 39 | return new BaseResponse(code, null, message); 40 | } 41 | 42 | /** 43 | * 失败 44 | * 45 | * @param errorCode 46 | * @return 47 | */ 48 | public static BaseResponse error(ErrorCode errorCode, String message) { 49 | return new BaseResponse(errorCode.getCode(), null, message); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/config/CorsConfig.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 6 | 7 | /** 8 | * 全局跨域配置 9 | * 10 | * @author yupi 11 | */ 12 | @Configuration 13 | public class CorsConfig implements WebMvcConfigurer { 14 | 15 | @Override 16 | public void addCorsMappings(CorsRegistry registry) { 17 | // 覆盖所有请求 18 | registry.addMapping("/**") 19 | // 允许发送 Cookie 20 | .allowCredentials(true) 21 | // 放行哪些域名(必须用 patterns,否则 * 会和 allowCredentials 冲突) 22 | .allowedOriginPatterns("*") 23 | .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") 24 | .allowedHeaders("*") 25 | .exposedHeaders("*"); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/config/Knife4jConfig.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.context.annotation.Profile; 6 | import springfox.documentation.builders.ApiInfoBuilder; 7 | import springfox.documentation.builders.PathSelectors; 8 | import springfox.documentation.builders.RequestHandlerSelectors; 9 | import springfox.documentation.spi.DocumentationType; 10 | import springfox.documentation.spring.web.plugins.Docket; 11 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 12 | 13 | /** 14 | * Knife4j 接口文档配置 15 | * https://doc.xiaominfo.com/knife4j/documentation/get_start.html 16 | * 17 | * @author yupi 18 | */ 19 | @Configuration 20 | @EnableSwagger2 21 | @Profile("dev") 22 | public class Knife4jConfig { 23 | 24 | @Bean 25 | public Docket defaultApi2() { 26 | return new Docket(DocumentationType.SWAGGER_2) 27 | .apiInfo(new ApiInfoBuilder() 28 | .title("project-backend") 29 | .description("project-backend") 30 | .version("1.0") 31 | .build()) 32 | .select() 33 | // 指定 Controller 扫描包路径 34 | .apis(RequestHandlerSelectors.basePackage("com.yupi.project.controller")) 35 | .paths(PathSelectors.any()) 36 | .build(); 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/config/MyBatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.config; 2 | 3 | import com.baomidou.mybatisplus.annotation.DbType; 4 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 5 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 6 | import org.mybatis.spring.annotation.MapperScan; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | /** 11 | * MyBatis Plus 配置 12 | * 13 | * @author yupi 14 | */ 15 | @Configuration 16 | @MapperScan("com.yupi.project.mapper") 17 | public class MyBatisPlusConfig { 18 | 19 | /** 20 | * 拦截器配置 21 | * 22 | * @return 23 | */ 24 | @Bean 25 | public MybatisPlusInterceptor mybatisPlusInterceptor() { 26 | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); 27 | // 分页插件 28 | interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); 29 | return interceptor; 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/constant/CommonConstant.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.constant; 2 | 3 | /** 4 | * 通用常量 5 | * 6 | * @author yupi 7 | */ 8 | public interface CommonConstant { 9 | 10 | /** 11 | * 升序 12 | */ 13 | String SORT_ORDER_ASC = "ascend"; 14 | 15 | /** 16 | * 降序 17 | */ 18 | String SORT_ORDER_DESC = " descend"; 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/constant/UserConstant.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.constant; 2 | 3 | /** 4 | * 用户常量 5 | * 6 | * @author yupi 7 | */ 8 | public interface UserConstant { 9 | 10 | /** 11 | * 用户登录态键 12 | */ 13 | String USER_LOGIN_STATE = "userLoginState"; 14 | 15 | /** 16 | * 系统用户 id(虚拟用户) 17 | */ 18 | long SYSTEM_USER_ID = 0; 19 | 20 | // region 权限 21 | 22 | /** 23 | * 默认权限 24 | */ 25 | String DEFAULT_ROLE = "user"; 26 | 27 | /** 28 | * 管理员权限 29 | */ 30 | String ADMIN_ROLE = "admin"; 31 | 32 | // endregion 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/controller/PostController.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.controller; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 5 | import com.yupi.project.annotation.AuthCheck; 6 | import com.yupi.project.common.BaseResponse; 7 | import com.yupi.project.common.DeleteRequest; 8 | import com.yupi.project.common.ErrorCode; 9 | import com.yupi.project.common.ResultUtils; 10 | import com.yupi.project.constant.CommonConstant; 11 | import com.yupi.project.exception.BusinessException; 12 | import com.yupi.project.model.dto.post.PostAddRequest; 13 | import com.yupi.project.model.dto.post.PostDoThumbRequest; 14 | import com.yupi.project.model.dto.post.PostQueryRequest; 15 | import com.yupi.project.model.dto.post.PostUpdateRequest; 16 | import com.yupi.project.model.entity.Post; 17 | import com.yupi.project.model.entity.User; 18 | import com.yupi.project.model.vo.PostVO; 19 | import com.yupi.project.service.PostService; 20 | import com.yupi.project.service.UserService; 21 | import lombok.extern.slf4j.Slf4j; 22 | import org.apache.commons.lang3.StringUtils; 23 | import org.springframework.beans.BeanUtils; 24 | import org.springframework.web.bind.annotation.*; 25 | 26 | import javax.annotation.Resource; 27 | import javax.servlet.http.HttpServletRequest; 28 | import java.util.Collection; 29 | import java.util.List; 30 | import java.util.Map; 31 | import java.util.concurrent.*; 32 | import java.util.stream.Collectors; 33 | 34 | /** 35 | * 帖子接口 36 | * 37 | * @author yupi 38 | */ 39 | @RestController 40 | @RequestMapping("/post") 41 | @Slf4j 42 | public class PostController { 43 | 44 | @Resource 45 | private PostService postService; 46 | 47 | @Resource 48 | private UserService userService; 49 | 50 | // region 增删改查 51 | 52 | /** 53 | * 创建 54 | * 55 | * @param postAddRequest 56 | * @param request 57 | * @return 58 | */ 59 | @PostMapping("/add") 60 | public BaseResponse addPost(@RequestBody PostAddRequest postAddRequest, HttpServletRequest request) { 61 | if (postAddRequest == null) { 62 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 63 | } 64 | Post post = new Post(); 65 | BeanUtils.copyProperties(postAddRequest, post); 66 | // 校验 67 | postService.validPost(post, true); 68 | User loginUser = userService.getLoginUser(request); 69 | post.setUserId(loginUser.getId()); 70 | boolean result = postService.save(post); 71 | if (!result) { 72 | throw new BusinessException(ErrorCode.OPERATION_ERROR); 73 | } 74 | long newPostId = post.getId(); 75 | return ResultUtils.success(newPostId); 76 | } 77 | 78 | /** 79 | * 删除 80 | * 81 | * @param deleteRequest 82 | * @param request 83 | * @return 84 | */ 85 | @PostMapping("/delete") 86 | public BaseResponse deletePost(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) { 87 | if (deleteRequest == null || deleteRequest.getId() <= 0) { 88 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 89 | } 90 | User user = userService.getLoginUser(request); 91 | long id = deleteRequest.getId(); 92 | // 判断是否存在 93 | Post oldPost = postService.getById(id); 94 | if (oldPost == null) { 95 | throw new BusinessException(ErrorCode.NOT_FOUND_ERROR); 96 | } 97 | // 仅本人或管理员可删除 98 | if (!oldPost.getUserId().equals(user.getId()) && !userService.isAdmin(request)) { 99 | throw new BusinessException(ErrorCode.NO_AUTH_ERROR); 100 | } 101 | boolean b = postService.removeById(id); 102 | return ResultUtils.success(b); 103 | } 104 | 105 | /** 106 | * 更新 107 | * 108 | * @param postUpdateRequest 109 | * @param request 110 | * @return 111 | */ 112 | @PostMapping("/update") 113 | public BaseResponse updatePost(@RequestBody PostUpdateRequest postUpdateRequest, 114 | HttpServletRequest request) { 115 | if (postUpdateRequest == null || postUpdateRequest.getId() <= 0) { 116 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 117 | } 118 | Post post = new Post(); 119 | BeanUtils.copyProperties(postUpdateRequest, post); 120 | // 参数校验 121 | postService.validPost(post, false); 122 | User user = userService.getLoginUser(request); 123 | long id = postUpdateRequest.getId(); 124 | // 判断是否存在 125 | Post oldPost = postService.getById(id); 126 | if (oldPost == null) { 127 | throw new BusinessException(ErrorCode.NOT_FOUND_ERROR); 128 | } 129 | // 仅本人或管理员可修改 130 | if (!oldPost.getUserId().equals(user.getId()) && !userService.isAdmin(request)) { 131 | throw new BusinessException(ErrorCode.NO_AUTH_ERROR); 132 | } 133 | boolean result = postService.updateById(post); 134 | return ResultUtils.success(result); 135 | } 136 | 137 | /** 138 | * 根据 id 获取 139 | * 140 | * @param id 141 | * @return 142 | */ 143 | @GetMapping("/get") 144 | public BaseResponse getPostById(long id) { 145 | if (id <= 0) { 146 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 147 | } 148 | Post post = postService.getById(id); 149 | return ResultUtils.success(post); 150 | } 151 | 152 | /** 153 | * 获取列表(仅管理员可使用) 154 | * 155 | * @param postQueryRequest 156 | * @return 157 | */ 158 | @AuthCheck(mustRole = "admin") 159 | @GetMapping("/list") 160 | public BaseResponse> listPost(PostQueryRequest postQueryRequest) { 161 | Post postQuery = new Post(); 162 | if (postQueryRequest != null) { 163 | BeanUtils.copyProperties(postQueryRequest, postQuery); 164 | } 165 | QueryWrapper queryWrapper = new QueryWrapper<>(postQuery); 166 | List postList = postService.list(queryWrapper); 167 | return ResultUtils.success(postList); 168 | } 169 | 170 | /** 171 | * 分页获取列表 172 | * 173 | * @param postQueryRequest 174 | * @param request 175 | * @return 176 | */ 177 | @GetMapping("/list/page") 178 | public BaseResponse> listPostByPage(PostQueryRequest postQueryRequest, HttpServletRequest request) { 179 | if (postQueryRequest == null) { 180 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 181 | } 182 | Post postQuery = new Post(); 183 | BeanUtils.copyProperties(postQueryRequest, postQuery); 184 | long current = postQueryRequest.getCurrent(); 185 | long size = postQueryRequest.getPageSize(); 186 | String sortField = postQueryRequest.getSortField(); 187 | String sortOrder = postQueryRequest.getSortOrder(); 188 | String content = postQuery.getContent(); 189 | // content 需支持模糊搜索 190 | postQuery.setContent(null); 191 | // 限制爬虫 192 | if (size > 50) { 193 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 194 | } 195 | QueryWrapper queryWrapper = new QueryWrapper<>(postQuery); 196 | queryWrapper.like(StringUtils.isNotBlank(content), "content", content); 197 | queryWrapper.orderBy(StringUtils.isNotBlank(sortField), 198 | sortOrder.equals(CommonConstant.SORT_ORDER_ASC), sortField); 199 | Page postPage = postService.page(new Page<>(current, size), queryWrapper); 200 | return ResultUtils.success(postPage); 201 | } 202 | 203 | // endregion 204 | 205 | } 206 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.controller; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO; 6 | import com.yupi.project.common.BaseResponse; 7 | import com.yupi.project.common.DeleteRequest; 8 | import com.yupi.project.common.ErrorCode; 9 | import com.yupi.project.common.ResultUtils; 10 | import com.yupi.project.exception.BusinessException; 11 | import com.yupi.project.model.dto.*; 12 | import com.yupi.project.model.dto.user.*; 13 | import com.yupi.project.model.entity.User; 14 | import com.yupi.project.model.vo.UserVO; 15 | import com.yupi.project.service.UserService; 16 | import org.apache.commons.lang3.StringUtils; 17 | import org.springframework.beans.BeanUtils; 18 | import org.springframework.web.bind.annotation.*; 19 | 20 | import javax.annotation.Resource; 21 | import javax.servlet.http.HttpServletRequest; 22 | import java.util.List; 23 | import java.util.stream.Collectors; 24 | 25 | /** 26 | * 用户接口 27 | * 28 | * @author yupi 29 | */ 30 | @RestController 31 | @RequestMapping("/user") 32 | public class UserController { 33 | 34 | @Resource 35 | private UserService userService; 36 | 37 | // region 登录相关 38 | 39 | /** 40 | * 用户注册 41 | * 42 | * @param userRegisterRequest 43 | * @return 44 | */ 45 | @PostMapping("/register") 46 | public BaseResponse userRegister(@RequestBody UserRegisterRequest userRegisterRequest) { 47 | if (userRegisterRequest == null) { 48 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 49 | } 50 | String userAccount = userRegisterRequest.getUserAccount(); 51 | String userPassword = userRegisterRequest.getUserPassword(); 52 | String checkPassword = userRegisterRequest.getCheckPassword(); 53 | if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) { 54 | return null; 55 | } 56 | long result = userService.userRegister(userAccount, userPassword, checkPassword); 57 | return ResultUtils.success(result); 58 | } 59 | 60 | /** 61 | * 用户登录 62 | * 63 | * @param userLoginRequest 64 | * @param request 65 | * @return 66 | */ 67 | @PostMapping("/login") 68 | public BaseResponse userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) { 69 | if (userLoginRequest == null) { 70 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 71 | } 72 | String userAccount = userLoginRequest.getUserAccount(); 73 | String userPassword = userLoginRequest.getUserPassword(); 74 | if (StringUtils.isAnyBlank(userAccount, userPassword)) { 75 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 76 | } 77 | User user = userService.userLogin(userAccount, userPassword, request); 78 | return ResultUtils.success(user); 79 | } 80 | 81 | /** 82 | * 用户注销 83 | * 84 | * @param request 85 | * @return 86 | */ 87 | @PostMapping("/logout") 88 | public BaseResponse userLogout(HttpServletRequest request) { 89 | if (request == null) { 90 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 91 | } 92 | boolean result = userService.userLogout(request); 93 | return ResultUtils.success(result); 94 | } 95 | 96 | /** 97 | * 获取当前登录用户 98 | * 99 | * @param request 100 | * @return 101 | */ 102 | @GetMapping("/get/login") 103 | public BaseResponse getLoginUser(HttpServletRequest request) { 104 | User user = userService.getLoginUser(request); 105 | UserVO userVO = new UserVO(); 106 | BeanUtils.copyProperties(user, userVO); 107 | return ResultUtils.success(userVO); 108 | } 109 | 110 | // endregion 111 | 112 | // region 增删改查 113 | 114 | /** 115 | * 创建用户 116 | * 117 | * @param userAddRequest 118 | * @param request 119 | * @return 120 | */ 121 | @PostMapping("/add") 122 | public BaseResponse addUser(@RequestBody UserAddRequest userAddRequest, HttpServletRequest request) { 123 | if (userAddRequest == null) { 124 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 125 | } 126 | User user = new User(); 127 | BeanUtils.copyProperties(userAddRequest, user); 128 | boolean result = userService.save(user); 129 | if (!result) { 130 | throw new BusinessException(ErrorCode.OPERATION_ERROR); 131 | } 132 | return ResultUtils.success(user.getId()); 133 | } 134 | 135 | /** 136 | * 删除用户 137 | * 138 | * @param deleteRequest 139 | * @param request 140 | * @return 141 | */ 142 | @PostMapping("/delete") 143 | public BaseResponse deleteUser(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) { 144 | if (deleteRequest == null || deleteRequest.getId() <= 0) { 145 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 146 | } 147 | boolean b = userService.removeById(deleteRequest.getId()); 148 | return ResultUtils.success(b); 149 | } 150 | 151 | /** 152 | * 更新用户 153 | * 154 | * @param userUpdateRequest 155 | * @param request 156 | * @return 157 | */ 158 | @PostMapping("/update") 159 | public BaseResponse updateUser(@RequestBody UserUpdateRequest userUpdateRequest, HttpServletRequest request) { 160 | if (userUpdateRequest == null || userUpdateRequest.getId() == null) { 161 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 162 | } 163 | User user = new User(); 164 | BeanUtils.copyProperties(userUpdateRequest, user); 165 | boolean result = userService.updateById(user); 166 | return ResultUtils.success(result); 167 | } 168 | 169 | /** 170 | * 根据 id 获取用户 171 | * 172 | * @param id 173 | * @param request 174 | * @return 175 | */ 176 | @GetMapping("/get") 177 | public BaseResponse getUserById(int id, HttpServletRequest request) { 178 | if (id <= 0) { 179 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 180 | } 181 | User user = userService.getById(id); 182 | UserVO userVO = new UserVO(); 183 | BeanUtils.copyProperties(user, userVO); 184 | return ResultUtils.success(userVO); 185 | } 186 | 187 | /** 188 | * 获取用户列表 189 | * 190 | * @param userQueryRequest 191 | * @param request 192 | * @return 193 | */ 194 | @GetMapping("/list") 195 | public BaseResponse> listUser(UserQueryRequest userQueryRequest, HttpServletRequest request) { 196 | User userQuery = new User(); 197 | if (userQueryRequest != null) { 198 | BeanUtils.copyProperties(userQueryRequest, userQuery); 199 | } 200 | QueryWrapper queryWrapper = new QueryWrapper<>(userQuery); 201 | List userList = userService.list(queryWrapper); 202 | List userVOList = userList.stream().map(user -> { 203 | UserVO userVO = new UserVO(); 204 | BeanUtils.copyProperties(user, userVO); 205 | return userVO; 206 | }).collect(Collectors.toList()); 207 | return ResultUtils.success(userVOList); 208 | } 209 | 210 | /** 211 | * 分页获取用户列表 212 | * 213 | * @param userQueryRequest 214 | * @param request 215 | * @return 216 | */ 217 | @GetMapping("/list/page") 218 | public BaseResponse> listUserByPage(UserQueryRequest userQueryRequest, HttpServletRequest request) { 219 | long current = 1; 220 | long size = 10; 221 | User userQuery = new User(); 222 | if (userQueryRequest != null) { 223 | BeanUtils.copyProperties(userQueryRequest, userQuery); 224 | current = userQueryRequest.getCurrent(); 225 | size = userQueryRequest.getPageSize(); 226 | } 227 | QueryWrapper queryWrapper = new QueryWrapper<>(userQuery); 228 | Page userPage = userService.page(new Page<>(current, size), queryWrapper); 229 | Page userVOPage = new PageDTO<>(userPage.getCurrent(), userPage.getSize(), userPage.getTotal()); 230 | List userVOList = userPage.getRecords().stream().map(user -> { 231 | UserVO userVO = new UserVO(); 232 | BeanUtils.copyProperties(user, userVO); 233 | return userVO; 234 | }).collect(Collectors.toList()); 235 | userVOPage.setRecords(userVOList); 236 | return ResultUtils.success(userVOPage); 237 | } 238 | 239 | // endregion 240 | } 241 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/exception/BusinessException.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.exception; 2 | 3 | import com.yupi.project.common.ErrorCode; 4 | 5 | /** 6 | * 自定义异常类 7 | * 8 | * @author yupi 9 | */ 10 | public class BusinessException extends RuntimeException { 11 | 12 | private final int code; 13 | 14 | public BusinessException(int code, String message) { 15 | super(message); 16 | this.code = code; 17 | } 18 | 19 | public BusinessException(ErrorCode errorCode) { 20 | super(errorCode.getMessage()); 21 | this.code = errorCode.getCode(); 22 | } 23 | 24 | public BusinessException(ErrorCode errorCode, String message) { 25 | super(message); 26 | this.code = errorCode.getCode(); 27 | } 28 | 29 | public int getCode() { 30 | return code; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/exception/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.exception; 2 | 3 | import com.yupi.project.common.BaseResponse; 4 | import com.yupi.project.common.ErrorCode; 5 | import com.yupi.project.common.ResultUtils; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.web.bind.annotation.ExceptionHandler; 8 | import org.springframework.web.bind.annotation.RestControllerAdvice; 9 | 10 | /** 11 | * 全局异常处理器 12 | * 13 | * @author yupi 14 | */ 15 | @RestControllerAdvice 16 | @Slf4j 17 | public class GlobalExceptionHandler { 18 | 19 | @ExceptionHandler(BusinessException.class) 20 | public BaseResponse businessExceptionHandler(BusinessException e) { 21 | log.error("businessException: " + e.getMessage(), e); 22 | return ResultUtils.error(e.getCode(), e.getMessage()); 23 | } 24 | 25 | @ExceptionHandler(RuntimeException.class) 26 | public BaseResponse runtimeExceptionHandler(RuntimeException e) { 27 | log.error("runtimeException", e); 28 | return ResultUtils.error(ErrorCode.SYSTEM_ERROR, e.getMessage()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/mapper/PostMapper.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.yupi.project.model.entity.Post; 5 | 6 | /** 7 | * @author yupili 8 | * @description 针对表【post(帖子)】的数据库操作Mapper 9 | * @createDate 2022-09-13 16:03:41 10 | * @Entity com.yupi.project.model.entity.Post 11 | */ 12 | public interface PostMapper extends BaseMapper { 13 | 14 | } 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.yupi.project.model.entity.User; 5 | 6 | /** 7 | * @Entity com.yupi.project.model.domain.User 8 | */ 9 | public interface UserMapper extends BaseMapper { 10 | 11 | } 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/model/dto/post/PostAddRequest.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.model.dto.post; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * 创建请求 9 | * 10 | * @TableName product 11 | */ 12 | @Data 13 | public class PostAddRequest implements Serializable { 14 | 15 | /** 16 | * 年龄 17 | */ 18 | private Integer age; 19 | 20 | /** 21 | * 性别(0-男, 1-女) 22 | */ 23 | private Integer gender; 24 | 25 | /** 26 | * 学历 27 | */ 28 | private String education; 29 | 30 | /** 31 | * 地点 32 | */ 33 | private String place; 34 | 35 | /** 36 | * 职业 37 | */ 38 | private String job; 39 | 40 | /** 41 | * 联系方式 42 | */ 43 | private String contact; 44 | 45 | /** 46 | * 感情经历 47 | */ 48 | private String loveExp; 49 | 50 | /** 51 | * 内容(个人介绍) 52 | */ 53 | private String content; 54 | 55 | /** 56 | * 照片地址 57 | */ 58 | private String photo; 59 | 60 | private static final long serialVersionUID = 1L; 61 | } -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/model/dto/post/PostDoThumbRequest.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.model.dto.post; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * 点赞 / 取消点赞请求 9 | * 10 | * @author yupi 11 | */ 12 | @Data 13 | public class PostDoThumbRequest implements Serializable { 14 | 15 | /** 16 | * 帖子 id 17 | */ 18 | private long postId; 19 | 20 | private static final long serialVersionUID = 1L; 21 | } -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/model/dto/post/PostQueryRequest.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.model.dto.post; 2 | 3 | import com.yupi.project.common.PageRequest; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * 查询请求 11 | * 12 | * @author yupi 13 | */ 14 | @EqualsAndHashCode(callSuper = true) 15 | @Data 16 | public class PostQueryRequest extends PageRequest implements Serializable { 17 | 18 | /** 19 | * 年龄 20 | */ 21 | private Integer age; 22 | 23 | /** 24 | * 性别(0-男, 1-女) 25 | */ 26 | private Integer gender; 27 | 28 | /** 29 | * 学历 30 | */ 31 | private String education; 32 | 33 | /** 34 | * 地点 35 | */ 36 | private String place; 37 | 38 | /** 39 | * 职业 40 | */ 41 | private String job; 42 | 43 | /** 44 | * 联系方式 45 | */ 46 | private String contact; 47 | 48 | /** 49 | * 感情经历 50 | */ 51 | private String loveExp; 52 | 53 | /** 54 | * 内容(个人介绍),支持模糊查询 55 | */ 56 | private String content; 57 | 58 | /** 59 | * 状态(0-待审核, 1-通过, 2-拒绝) 60 | */ 61 | private Integer reviewStatus; 62 | 63 | /** 64 | * 创建用户 id 65 | */ 66 | private Long userId; 67 | 68 | private static final long serialVersionUID = 1L; 69 | } -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/model/dto/post/PostUpdateRequest.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.model.dto.post; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * 更新请求 9 | * 10 | * @TableName product 11 | */ 12 | @Data 13 | public class PostUpdateRequest implements Serializable { 14 | 15 | /** 16 | * id 17 | */ 18 | private long id; 19 | 20 | /** 21 | * 年龄 22 | */ 23 | private Integer age; 24 | 25 | /** 26 | * 性别(0-男, 1-女) 27 | */ 28 | private Integer gender; 29 | 30 | /** 31 | * 学历 32 | */ 33 | private String education; 34 | 35 | /** 36 | * 地点 37 | */ 38 | private String place; 39 | 40 | /** 41 | * 职业 42 | */ 43 | private String job; 44 | 45 | /** 46 | * 联系方式 47 | */ 48 | private String contact; 49 | 50 | /** 51 | * 感情经历 52 | */ 53 | private String loveExp; 54 | 55 | /** 56 | * 内容(个人介绍) 57 | */ 58 | private String content; 59 | 60 | /** 61 | * 照片地址 62 | */ 63 | private String photo; 64 | 65 | /** 66 | * 状态(0-待审核, 1-通过, 2-拒绝) 67 | */ 68 | private Integer reviewStatus; 69 | 70 | /** 71 | * 审核信息 72 | */ 73 | private String reviewMessage; 74 | 75 | private static final long serialVersionUID = 1L; 76 | } -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/model/dto/user/UserAddRequest.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.model.dto.user; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * 用户创建请求 9 | * 10 | * @author yupi 11 | */ 12 | @Data 13 | public class UserAddRequest implements Serializable { 14 | 15 | /** 16 | * 用户昵称 17 | */ 18 | private String userName; 19 | 20 | /** 21 | * 账号 22 | */ 23 | private String userAccount; 24 | 25 | /** 26 | * 用户头像 27 | */ 28 | private String userAvatar; 29 | 30 | /** 31 | * 性别 32 | */ 33 | private Integer gender; 34 | 35 | /** 36 | * 用户角色: user, admin 37 | */ 38 | private String userRole; 39 | 40 | /** 41 | * 密码 42 | */ 43 | private String userPassword; 44 | 45 | private static final long serialVersionUID = 1L; 46 | } -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/model/dto/user/UserLoginRequest.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.model.dto.user; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * 用户登录请求体 9 | * 10 | * @author yupi 11 | */ 12 | @Data 13 | public class UserLoginRequest implements Serializable { 14 | 15 | private static final long serialVersionUID = 3191241716373120793L; 16 | 17 | private String userAccount; 18 | 19 | private String userPassword; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/model/dto/user/UserQueryRequest.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.model.dto.user; 2 | 3 | import com.yupi.project.common.PageRequest; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | import java.io.Serializable; 8 | import java.util.Date; 9 | 10 | /** 11 | * 用户查询请求 12 | * 13 | * @author yupi 14 | */ 15 | @EqualsAndHashCode(callSuper = true) 16 | @Data 17 | public class UserQueryRequest extends PageRequest implements Serializable { 18 | /** 19 | * id 20 | */ 21 | private Long id; 22 | 23 | /** 24 | * 用户昵称 25 | */ 26 | private String userName; 27 | 28 | /** 29 | * 账号 30 | */ 31 | private String userAccount; 32 | 33 | /** 34 | * 用户头像 35 | */ 36 | private String userAvatar; 37 | 38 | /** 39 | * 性别 40 | */ 41 | private Integer gender; 42 | 43 | /** 44 | * 用户角色: user, admin 45 | */ 46 | private String userRole; 47 | 48 | /** 49 | * 创建时间 50 | */ 51 | private Date createTime; 52 | 53 | /** 54 | * 更新时间 55 | */ 56 | private Date updateTime; 57 | 58 | private static final long serialVersionUID = 1L; 59 | } -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/model/dto/user/UserRegisterRequest.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.model.dto.user; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * 用户注册请求体 9 | * 10 | * @author yupi 11 | */ 12 | @Data 13 | public class UserRegisterRequest implements Serializable { 14 | 15 | private static final long serialVersionUID = 3191241716373120793L; 16 | 17 | private String userAccount; 18 | 19 | private String userPassword; 20 | 21 | private String checkPassword; 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/model/dto/user/UserUpdateRequest.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.model.dto.user; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableField; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * 用户更新请求 10 | * 11 | * @author yupi 12 | */ 13 | @Data 14 | public class UserUpdateRequest implements Serializable { 15 | /** 16 | * id 17 | */ 18 | private Long id; 19 | 20 | /** 21 | * 用户昵称 22 | */ 23 | private String userName; 24 | 25 | /** 26 | * 账号 27 | */ 28 | private String userAccount; 29 | 30 | /** 31 | * 用户头像 32 | */ 33 | private String userAvatar; 34 | 35 | /** 36 | * 性别 37 | */ 38 | private Integer gender; 39 | 40 | /** 41 | * 用户角色: user, admin 42 | */ 43 | private String userRole; 44 | 45 | /** 46 | * 密码 47 | */ 48 | private String userPassword; 49 | 50 | @TableField(exist = false) 51 | private static final long serialVersionUID = 1L; 52 | } -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/model/entity/Post.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.model.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.*; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | import java.util.Date; 8 | 9 | /** 10 | * 帖子 11 | * 12 | * @TableName post 13 | */ 14 | @TableName(value = "post") 15 | @Data 16 | public class Post implements Serializable { 17 | /** 18 | * id 19 | */ 20 | @TableId(type = IdType.AUTO) 21 | private Long id; 22 | 23 | /** 24 | * 年龄 25 | */ 26 | private Integer age; 27 | 28 | /** 29 | * 性别(0-男, 1-女) 30 | */ 31 | private Integer gender; 32 | 33 | /** 34 | * 学历 35 | */ 36 | private String education; 37 | 38 | /** 39 | * 地点 40 | */ 41 | private String place; 42 | 43 | /** 44 | * 职业 45 | */ 46 | private String job; 47 | 48 | /** 49 | * 联系方式 50 | */ 51 | private String contact; 52 | 53 | /** 54 | * 感情经历 55 | */ 56 | private String loveExp; 57 | 58 | /** 59 | * 内容(个人介绍) 60 | */ 61 | private String content; 62 | 63 | /** 64 | * 照片地址 65 | */ 66 | private String photo; 67 | 68 | /** 69 | * 状态(0-待审核, 1-通过, 2-拒绝) 70 | */ 71 | private Integer reviewStatus; 72 | 73 | /** 74 | * 审核信息 75 | */ 76 | private String reviewMessage; 77 | 78 | /** 79 | * 浏览数 80 | */ 81 | private Integer viewNum; 82 | 83 | /** 84 | * 点赞数 85 | */ 86 | private Integer thumbNum; 87 | 88 | /** 89 | * 创建用户 id 90 | */ 91 | private Long userId; 92 | 93 | /** 94 | * 创建时间 95 | */ 96 | private Date createTime; 97 | 98 | /** 99 | * 更新时间 100 | */ 101 | private Date updateTime; 102 | 103 | /** 104 | * 是否删除 105 | */ 106 | @TableLogic 107 | private Integer isDelete; 108 | 109 | @TableField(exist = false) 110 | private static final long serialVersionUID = 1L; 111 | } -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/model/entity/User.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.model.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.*; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | import java.util.Date; 8 | 9 | /** 10 | * 用户 11 | * 12 | * @TableName user 13 | */ 14 | @TableName(value = "user") 15 | @Data 16 | public class User implements Serializable { 17 | /** 18 | * id 19 | */ 20 | @TableId(type = IdType.AUTO) 21 | private Long id; 22 | 23 | /** 24 | * 用户昵称 25 | */ 26 | private String userName; 27 | 28 | /** 29 | * 账号 30 | */ 31 | private String userAccount; 32 | 33 | /** 34 | * 用户头像 35 | */ 36 | private String userAvatar; 37 | 38 | /** 39 | * 性别 40 | */ 41 | private Integer gender; 42 | 43 | /** 44 | * 用户角色: user, admin 45 | */ 46 | private String userRole; 47 | 48 | /** 49 | * 密码 50 | */ 51 | private String userPassword; 52 | 53 | /** 54 | * 创建时间 55 | */ 56 | private Date createTime; 57 | 58 | /** 59 | * 更新时间 60 | */ 61 | private Date updateTime; 62 | 63 | /** 64 | * 是否删除 65 | */ 66 | @TableLogic 67 | private Integer isDelete; 68 | 69 | @TableField(exist = false) 70 | private static final long serialVersionUID = 1L; 71 | } -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/model/enums/PostGenderEnum.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.model.enums; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | /** 8 | * 帖子性别枚举 9 | * 10 | * @author yupi 11 | */ 12 | public enum PostGenderEnum { 13 | 14 | MALE("男", 0), 15 | FEMALE("女", 1); 16 | 17 | private final String text; 18 | 19 | private final int value; 20 | 21 | PostGenderEnum(String text, int value) { 22 | this.text = text; 23 | this.value = value; 24 | } 25 | 26 | /** 27 | * 获取值列表 28 | * 29 | * @return 30 | */ 31 | public static List getValues() { 32 | return Arrays.stream(values()).map(item -> item.value).collect(Collectors.toList()); 33 | } 34 | 35 | public int getValue() { 36 | return value; 37 | } 38 | 39 | public String getText() { 40 | return text; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/model/enums/PostReviewStatusEnum.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.model.enums; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | /** 8 | * 帖子审核状态枚举 9 | * 10 | * @author yupi 11 | */ 12 | public enum PostReviewStatusEnum { 13 | 14 | REVIEWING("待审核", 0), 15 | PASS("通过", 1), 16 | REJECT("拒绝", 2); 17 | 18 | private final String text; 19 | 20 | private final int value; 21 | 22 | PostReviewStatusEnum(String text, int value) { 23 | this.text = text; 24 | this.value = value; 25 | } 26 | 27 | /** 28 | * 获取值列表 29 | * 30 | * @return 31 | */ 32 | public static List getValues() { 33 | return Arrays.stream(values()).map(item -> item.value).collect(Collectors.toList()); 34 | } 35 | 36 | public int getValue() { 37 | return value; 38 | } 39 | 40 | public String getText() { 41 | return text; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/model/vo/PostVO.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.model.vo; 2 | 3 | import com.yupi.project.model.entity.Post; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | /** 8 | * 帖子视图 9 | * 10 | * @author yupi 11 | * @TableName product 12 | */ 13 | @EqualsAndHashCode(callSuper = true) 14 | @Data 15 | public class PostVO extends Post { 16 | 17 | /** 18 | * 是否已点赞 19 | */ 20 | private Boolean hasThumb; 21 | 22 | private static final long serialVersionUID = 1L; 23 | } -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/model/vo/UserVO.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.model.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.util.Date; 7 | 8 | /** 9 | * 用户视图 10 | * 11 | * @TableName user 12 | */ 13 | @Data 14 | public class UserVO implements Serializable { 15 | /** 16 | * id 17 | */ 18 | private Long id; 19 | 20 | /** 21 | * 用户昵称 22 | */ 23 | private String userName; 24 | 25 | /** 26 | * 账号 27 | */ 28 | private String userAccount; 29 | 30 | /** 31 | * 用户头像 32 | */ 33 | private String userAvatar; 34 | 35 | /** 36 | * 性别 37 | */ 38 | private Integer gender; 39 | 40 | /** 41 | * 用户角色: user, admin 42 | */ 43 | private String userRole; 44 | 45 | /** 46 | * 创建时间 47 | */ 48 | private Date createTime; 49 | 50 | /** 51 | * 更新时间 52 | */ 53 | private Date updateTime; 54 | 55 | private static final long serialVersionUID = 1L; 56 | } -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/service/PostService.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.service; 2 | 3 | import com.baomidou.mybatisplus.extension.service.IService; 4 | import com.yupi.project.model.entity.Post; 5 | 6 | /** 7 | * @author yupili 8 | * @description 针对表【post(帖子)】的数据库操作Service 9 | */ 10 | public interface PostService extends IService { 11 | 12 | /** 13 | * 校验 14 | * 15 | * @param post 16 | * @param add 是否为创建校验 17 | */ 18 | void validPost(Post post, boolean add); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.service; 2 | 3 | 4 | import com.baomidou.mybatisplus.extension.service.IService; 5 | import com.yupi.project.model.entity.User; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | 9 | /** 10 | * 用户服务 11 | * 12 | * @author yupi 13 | */ 14 | public interface UserService extends IService { 15 | 16 | /** 17 | * 用户注册 18 | * 19 | * @param userAccount 用户账户 20 | * @param userPassword 用户密码 21 | * @param checkPassword 校验密码 22 | * @return 新用户 id 23 | */ 24 | long userRegister(String userAccount, String userPassword, String checkPassword); 25 | 26 | /** 27 | * 用户登录 28 | * 29 | * @param userAccount 用户账户 30 | * @param userPassword 用户密码 31 | * @param request 32 | * @return 脱敏后的用户信息 33 | */ 34 | User userLogin(String userAccount, String userPassword, HttpServletRequest request); 35 | 36 | /** 37 | * 获取当前登录用户 38 | * 39 | * @param request 40 | * @return 41 | */ 42 | User getLoginUser(HttpServletRequest request); 43 | 44 | /** 45 | * 是否为管理员 46 | * 47 | * @param request 48 | * @return 49 | */ 50 | boolean isAdmin(HttpServletRequest request); 51 | 52 | /** 53 | * 用户注销 54 | * 55 | * @param request 56 | * @return 57 | */ 58 | boolean userLogout(HttpServletRequest request); 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/service/impl/PostServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.service.impl; 2 | 3 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 4 | import com.yupi.project.common.ErrorCode; 5 | import com.yupi.project.exception.BusinessException; 6 | import com.yupi.project.mapper.PostMapper; 7 | import com.yupi.project.model.entity.Post; 8 | import com.yupi.project.model.enums.PostGenderEnum; 9 | import com.yupi.project.model.enums.PostReviewStatusEnum; 10 | import com.yupi.project.service.PostService; 11 | import org.apache.commons.lang3.ObjectUtils; 12 | import org.apache.commons.lang3.StringUtils; 13 | import org.springframework.stereotype.Service; 14 | 15 | /** 16 | * @author yupili 17 | * @description 针对表【post(帖子)】的数据库操作Service实现 18 | */ 19 | @Service 20 | public class PostServiceImpl extends ServiceImpl implements PostService { 21 | 22 | @Override 23 | public void validPost(Post post, boolean add) { 24 | if (post == null) { 25 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 26 | } 27 | Integer age = post.getAge(); 28 | Integer gender = post.getGender(); 29 | String content = post.getContent(); 30 | String job = post.getJob(); 31 | String place = post.getPlace(); 32 | String education = post.getEducation(); 33 | String loveExp = post.getLoveExp(); 34 | Integer reviewStatus = post.getReviewStatus(); 35 | // 创建时,所有参数必须非空 36 | if (add) { 37 | if (StringUtils.isAnyBlank(content, job, place, education, loveExp) || ObjectUtils.anyNull(age, gender)) { 38 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 39 | } 40 | } 41 | if (StringUtils.isNotBlank(content) && content.length() > 8192) { 42 | throw new BusinessException(ErrorCode.PARAMS_ERROR, "内容过长"); 43 | } 44 | if (reviewStatus != null && !PostReviewStatusEnum.getValues().contains(reviewStatus)) { 45 | throw new BusinessException(ErrorCode.PARAMS_ERROR); 46 | } 47 | if (age != null && (age < 18 || age > 100)) { 48 | throw new BusinessException(ErrorCode.PARAMS_ERROR, "年龄不符合要求"); 49 | } 50 | if (gender != null && !PostGenderEnum.getValues().contains(gender)) { 51 | throw new BusinessException(ErrorCode.PARAMS_ERROR, "性别不符合要求"); 52 | } 53 | } 54 | } 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/main/java/com/yupi/project/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.service.impl; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 5 | import com.yupi.project.common.ErrorCode; 6 | import com.yupi.project.exception.BusinessException; 7 | import com.yupi.project.mapper.UserMapper; 8 | import com.yupi.project.model.entity.User; 9 | import com.yupi.project.service.UserService; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.apache.commons.lang3.StringUtils; 12 | import org.springframework.stereotype.Service; 13 | import org.springframework.util.DigestUtils; 14 | 15 | import javax.annotation.Resource; 16 | import javax.servlet.http.HttpServletRequest; 17 | 18 | import static com.yupi.project.constant.UserConstant.ADMIN_ROLE; 19 | import static com.yupi.project.constant.UserConstant.USER_LOGIN_STATE; 20 | 21 | 22 | /** 23 | * 用户服务实现类 24 | * 25 | * @author yupi 26 | */ 27 | @Service 28 | @Slf4j 29 | public class UserServiceImpl extends ServiceImpl 30 | implements UserService { 31 | 32 | @Resource 33 | private UserMapper userMapper; 34 | 35 | /** 36 | * 盐值,混淆密码 37 | */ 38 | private static final String SALT = "yupi"; 39 | 40 | @Override 41 | public long userRegister(String userAccount, String userPassword, String checkPassword) { 42 | // 1. 校验 43 | if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) { 44 | throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空"); 45 | } 46 | if (userAccount.length() < 4) { 47 | throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号过短"); 48 | } 49 | if (userPassword.length() < 8 || checkPassword.length() < 8) { 50 | throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码过短"); 51 | } 52 | // 密码和校验密码相同 53 | if (!userPassword.equals(checkPassword)) { 54 | throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致"); 55 | } 56 | synchronized (userAccount.intern()) { 57 | // 账户不能重复 58 | QueryWrapper queryWrapper = new QueryWrapper<>(); 59 | queryWrapper.eq("userAccount", userAccount); 60 | long count = userMapper.selectCount(queryWrapper); 61 | if (count > 0) { 62 | throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号重复"); 63 | } 64 | // 2. 加密 65 | String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes()); 66 | // 3. 插入数据 67 | User user = new User(); 68 | user.setUserAccount(userAccount); 69 | user.setUserPassword(encryptPassword); 70 | boolean saveResult = this.save(user); 71 | if (!saveResult) { 72 | throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败,数据库错误"); 73 | } 74 | return user.getId(); 75 | } 76 | } 77 | 78 | @Override 79 | public User userLogin(String userAccount, String userPassword, HttpServletRequest request) { 80 | // 1. 校验 81 | if (StringUtils.isAnyBlank(userAccount, userPassword)) { 82 | throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空"); 83 | } 84 | if (userAccount.length() < 4) { 85 | throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号错误"); 86 | } 87 | if (userPassword.length() < 8) { 88 | throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码错误"); 89 | } 90 | // 2. 加密 91 | String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes()); 92 | // 查询用户是否存在 93 | QueryWrapper queryWrapper = new QueryWrapper<>(); 94 | queryWrapper.eq("userAccount", userAccount); 95 | queryWrapper.eq("userPassword", encryptPassword); 96 | User user = userMapper.selectOne(queryWrapper); 97 | // 用户不存在 98 | if (user == null) { 99 | log.info("user login failed, userAccount cannot match userPassword"); 100 | throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在或密码错误"); 101 | } 102 | // 3. 记录用户的登录态 103 | request.getSession().setAttribute(USER_LOGIN_STATE, user); 104 | return user; 105 | } 106 | 107 | /** 108 | * 获取当前登录用户 109 | * 110 | * @param request 111 | * @return 112 | */ 113 | @Override 114 | public User getLoginUser(HttpServletRequest request) { 115 | // 先判断是否已登录 116 | Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE); 117 | User currentUser = (User) userObj; 118 | if (currentUser == null || currentUser.getId() == null) { 119 | throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR); 120 | } 121 | // 从数据库查询(追求性能的话可以注释,直接走缓存) 122 | long userId = currentUser.getId(); 123 | currentUser = this.getById(userId); 124 | if (currentUser == null) { 125 | throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR); 126 | } 127 | return currentUser; 128 | } 129 | 130 | /** 131 | * 是否为管理员 132 | * 133 | * @param request 134 | * @return 135 | */ 136 | @Override 137 | public boolean isAdmin(HttpServletRequest request) { 138 | // 仅管理员可查询 139 | Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE); 140 | User user = (User) userObj; 141 | return user != null && ADMIN_ROLE.equals(user.getUserRole()); 142 | } 143 | 144 | /** 145 | * 用户注销 146 | * 147 | * @param request 148 | */ 149 | @Override 150 | public boolean userLogout(HttpServletRequest request) { 151 | if (request.getSession().getAttribute(USER_LOGIN_STATE) == null) { 152 | throw new BusinessException(ErrorCode.OPERATION_ERROR, "未登录"); 153 | } 154 | // 移除登录态 155 | request.getSession().removeAttribute(USER_LOGIN_STATE); 156 | return true; 157 | } 158 | 159 | } 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /src/main/resources/application-prod.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | driver-class-name: com.mysql.cj.jdbc.Driver 4 | url: jdbc:mysql://localhost:3306/my_db 5 | username: root 6 | password: 123456 -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: springboot-init 4 | # DataSource Config 5 | datasource: 6 | driver-class-name: com.mysql.cj.jdbc.Driver 7 | url: jdbc:mysql://localhost:3306/my_db 8 | username: root 9 | password: 123456 10 | mvc: 11 | pathmatch: 12 | matching-strategy: ANT_PATH_MATCHER 13 | # session 失效时间(分钟) 14 | session: 15 | timeout: 86400 16 | store-type: redis 17 | # redis 配置 18 | redis: 19 | port: 6379 20 | host: localhost 21 | database: 0 22 | server: 23 | port: 7529 24 | servlet: 25 | context-path: /api 26 | mybatis-plus: 27 | configuration: 28 | map-underscore-to-camel-case: false 29 | log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 30 | global-config: 31 | db-config: 32 | logic-delete-field: isDelete # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2) 33 | logic-delete-value: 1 # 逻辑已删除值(默认为 1) 34 | logic-not-delete-value: 0 # 逻辑未删除值(默认为 0) -------------------------------------------------------------------------------- /src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | 我的项目 by 程序员鱼皮 https://github.com/liyupi -------------------------------------------------------------------------------- /src/main/resources/mapper/PostMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | id,age,gender, 30 | education,place,job, 31 | contact,loveExp,content, 32 | photo,reviewStatus,reviewMessage, 33 | viewNum,thumbNum,userId, 34 | createTime,updateTime,isDelete 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/main/resources/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | id,userName,userAccount, 22 | userAvatar,gender,userRole, 23 | userPassword,createTime,updateTime, 24 | isDelete 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/test/java/com/yupi/project/service/UserServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.yupi.project.service; 2 | 3 | import com.yupi.project.model.entity.User; 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | 8 | import javax.annotation.Resource; 9 | 10 | /** 11 | * 用户服务测试 12 | * 13 | * @author yupi 14 | */ 15 | @SpringBootTest 16 | class UserServiceTest { 17 | 18 | @Resource 19 | private UserService userService; 20 | 21 | @Test 22 | void testAddUser() { 23 | User user = new User(); 24 | boolean result = userService.save(user); 25 | System.out.println(user.getId()); 26 | Assertions.assertTrue(result); 27 | } 28 | 29 | @Test 30 | void testUpdateUser() { 31 | User user = new User(); 32 | boolean result = userService.updateById(user); 33 | Assertions.assertTrue(result); 34 | } 35 | 36 | @Test 37 | void testDeleteUser() { 38 | boolean result = userService.removeById(1L); 39 | Assertions.assertTrue(result); 40 | } 41 | 42 | @Test 43 | void testGetUser() { 44 | User user = userService.getById(1L); 45 | Assertions.assertNotNull(user); 46 | } 47 | 48 | @Test 49 | void userRegister() { 50 | String userAccount = "yupi"; 51 | String userPassword = ""; 52 | String checkPassword = "123456"; 53 | try { 54 | long result = userService.userRegister(userAccount, userPassword, checkPassword); 55 | Assertions.assertEquals(-1, result); 56 | userAccount = "yu"; 57 | result = userService.userRegister(userAccount, userPassword, checkPassword); 58 | Assertions.assertEquals(-1, result); 59 | userAccount = "yupi"; 60 | userPassword = "123456"; 61 | result = userService.userRegister(userAccount, userPassword, checkPassword); 62 | Assertions.assertEquals(-1, result); 63 | userAccount = "yu pi"; 64 | userPassword = "12345678"; 65 | result = userService.userRegister(userAccount, userPassword, checkPassword); 66 | Assertions.assertEquals(-1, result); 67 | checkPassword = "123456789"; 68 | result = userService.userRegister(userAccount, userPassword, checkPassword); 69 | Assertions.assertEquals(-1, result); 70 | userAccount = "dogYupi"; 71 | checkPassword = "12345678"; 72 | result = userService.userRegister(userAccount, userPassword, checkPassword); 73 | Assertions.assertEquals(-1, result); 74 | userAccount = "yupi"; 75 | result = userService.userRegister(userAccount, userPassword, checkPassword); 76 | Assertions.assertEquals(-1, result); 77 | } catch (Exception e) { 78 | 79 | } 80 | } 81 | } --------------------------------------------------------------------------------