first commit

main
魏灿斌 4 weeks ago
commit 9742357d76

38
.gitignore vendored

@ -0,0 +1,38 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

8
.idea/.gitignore vendored

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ApifoxUploaderProjectSetting">
<option name="apiAccessToken" value="APS-WmPJEk9EldpYTflSKV1yfYY1uOqCHsp7" />
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AgentMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AskMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Ask2AgentMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EditMigrationStateService">
<option name="migrationStatus" value="COMPLETED" />
</component>
</project>

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" native2AsciiForPropertiesFiles="true" defaultCharsetForPropertiesFiles="UTF-8">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/yuxingshi-ssm-common/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/yuxingshi-ssm-common/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/yuxingshi-ssm-common/yuxingshi-ssm-core/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/yuxingshi-ssm-common/yuxingshi-ssm-core/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/yuxingshi-ssm-common/yuxingshi-ssm-intercepter/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/yuxingshi-ssm-common/yuxingshi-ssm-intercepter/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/yuxingshi-ssm-common/yuxingshi-ssm-mybatisplus/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/yuxingshi-ssm-common/yuxingshi-ssm-mybatisplus/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/yuxingshi-ssm-common/yuxingshi-ssm-redis/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/yuxingshi-ssm-common/yuxingshi-ssm-redis/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/yuxingshi-ssm-common/yuxingshi-ssm-security/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/yuxingshi-ssm-common/yuxingshi-ssm-security/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/yuxingshi-ssm-server/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/yuxingshi-ssm-server/src/main/resources" charset="UTF-8" />
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

@ -0,0 +1,96 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>yuxingshi</groupId>
<artifactId>yuxingshi-ssm</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>yuxingshi-ssm-server</module>
<module>yuxingshi-ssm-common</module>
</modules>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--依赖版本-->
<spring-boot.version>3.3.3</spring-boot.version>
<redisson.version>3.50.0</redisson.version>
<mybatis-plus.version>3.5.7</mybatis-plus.version>
<commons-collections4.version>4.4</commons-collections4.version>
<pagehelper.boot.version>2.0.0</pagehelper.boot.version>
<jwt.version>0.9.1</jwt.version>
<jaxb.version>2.3.0</jaxb.version>
<hutool.version>5.8.22</hutool.version>
<transmittable-thread-local.version>2.14.4</transmittable-thread-local.version>
<idworker-snowflake.version>1.0.0</idworker-snowflake.version>
<!--运行环境-->
<runenv>test</runenv>
<java.opts.default>-Xmx256m</java.opts.default>
</properties>
<dependencyManagement>
<dependencies>
<!-- SpringBoot 依赖配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>${redisson.version}</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.boot.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
<version>${transmittable-thread-local.version}</version>
</dependency>
<dependency>
<groupId>com.a3test.component</groupId>
<artifactId>idworker-snowflake</artifactId>
<version>${idworker-snowflake.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

@ -0,0 +1,28 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>yuxingshi</groupId>
<artifactId>yuxingshi-ssm</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>yuxingshi-ssm-common</artifactId>
<packaging>pom</packaging>
<modules>
<module>yuxingshi-ssm-redis</module>
<module>yuxingshi-ssm-core</module>
<module>yuxingshi-ssm-mybatisplus</module>
<module>yuxingshi-ssm-security</module>
<module>yuxingshi-ssm-intercepter</module>
</modules>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

@ -0,0 +1,63 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>yuxingshi</groupId>
<artifactId>yuxingshi-ssm-common</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>yuxingshi.ssm.common.core</groupId>
<artifactId>yuxingshi-ssm-core</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,27 @@
package yuxingshi.ssm.common.core.constants;
/**
*
*/
public class CacheConstants {
/**
*
*/
public final static String CACHE_SPLIT_COLON = ":";
/**
* 720
*/
public final static long LOGIN_USER_EXPIRATION = 720;
/**
* 120
*/
public final static long REFRESH_TIME = 120;
/**
*
*/
public static final long LOGIN_USER_EXP_CRITICAL_TIME = 120L;
}

@ -0,0 +1,23 @@
package yuxingshi.ssm.common.core.constants;
/**
*
*/
public class CommonConstants {
/**
*
*/
public static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";
/**
*
*/
public final static String UTF8 = "UTF-8";
/**
*
*/
public final static String DEFAULT_DELIMITER = ", ";
/**
*
*/
public final static String EMPTY_STR = "";
}

@ -0,0 +1,180 @@
package yuxingshi.ssm.common.core.constants;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum ResultCode {
//---------------------------2xx
/**
*
*/
SUCCESS (200000, "操作成功"),
//------------------------4xx
//400
/**
*
*/
INVALID_PARA (400000, "无效的参数"),
/**
*
*/
INVALID_CODE (400001, "无效的验证码"),
/**
*
*/
ERROR_CODE (400002, "错误的验证码"),
/**
*
*/
ERROR_PHONE_FORMAT (400003, "手机号格式错误"),
/**
*
*/
SEND_MSG_OVERLIMIT (400004, "超过每日发送次数限制"),
/**
*
*/
INVALID_REGION (400005, "无效的区划"),
/**
*
*/
PARA_TYPE_MISMATCH (400006, "参数类型不匹配"),
/**
*
*/
USER_DISABLE (400007, "账号已停用,登录失败"),
/**
*
*/
INVALID_PARA_MAX_SIZE (4000008,"请求参数超过最大限制"),
/**
*
*/
PHONE_ALREADY_REGISTER (4000009,"手机号已经被注册"),
/**
*
*/
USER_NOT_EXIST (4000010,"用户不存在"),
/**
*
*/
DECODE_FAIL (4000011,"解密失败"),
/**
*
*/
USER_IDENTITY_ILLEGAL (4000012,"用户身份不合法"),
/**
*
*/
USER_STATUS_ILLEGAL (4000013,"用户状态不合法"),
/**
*
*/
PASSWORD_FORMAT_INVALID (4000015,"密码格式不通过"),
//401
/**
*
*/
TOKEN_EMPTY (401000, "令牌不能为空"),
/**
*
*/
TOKEN_INVALID (401001, "令牌已过期或验证不正确!"),
/**
*
*/
TOKEN_OVERTIME (401002, "令牌已过期!"),
/**
*
*/
LOGIN_STATUS_OVERTIME (401003, "登录状态已过期!"),
/**
*
*/
TOKEN_CHECK_FAILED (401004, "令牌验证失败!"),
// 403
NOT_PERMISSION (403001,"您没有权限!"),
//404
/**
*
*/
SERVICE_NOT_FOUND (404000, "服务未找到"),
URL_NOT_FOUND (404001, "url未找到"),
//405
/**
*
*/
REQUEST_METNHOD_NOT_SUPPORTED (405000, "请求方法不支持"),
//---------------------5xx
/**
*
*/
ERROR (500000, "服务繁忙请稍后重试"),
/**
*
*/
FAILED (500001, "操作失败"),
//---------------------枚举占位
/**
*
*/
RESERVED (99999999, "占位专用");
/**
*
*/
private final int code;
/**
*
*/
private final String msg;
}

@ -0,0 +1,38 @@
package yuxingshi.ssm.common.core.constants;
/**
*
*/
public class SecurityConstants {
/**
*
*/
public static final String USER_KEY = "user_key";
/**
* ID
*/
public static final String USER_ID = "user_id";
/**
*
*/
public static final String USER_FROM = "user_from";
/**
*
*/
public static final String USERNAME = "username";
/**
*
*/
public static final String USER_IDENTITY = "user_identity";
/**
*
*/
public static final String AUTHENTICATION = "authorization";
}

@ -0,0 +1,29 @@
package yuxingshi.ssm.common.core.constants;
/**
* token
*/
public class TokenConstants {
/**
*
*/
public static final String SECRET = "jyuxingshiabcdefghijklmnopqrstuvwxyz";
/**
*
*/
public static final String PREFIX = "Bearer ";
/**
* token key
*/
public static final String LOGIN_TOKEN_KEY = "logintoken:";
/**
*
*/
public static final String LOGIN_CACHE_INGO_SPLIT = "-";
}

@ -0,0 +1,41 @@
package yuxingshi.ssm.common.core.domain.dto;
import lombok.Data;
import java.util.List;
/**
*
*/
@Data
public class BasePageDTO<T> {
/**
*
*/
Integer totals;
/**
*
*/
Integer totalPages;
/**
*
*/
List<T> list;
/**
*
*
* @param totals
* @param pageSize
* @return
*/
public static int calculateTotalPages(long totals, int pageSize) {
if (pageSize <= 0) {
throw new IllegalArgumentException("Page size must be greater than 0.");
}
return (int) Math.ceil((double) totals / pageSize);
}
}

@ -0,0 +1,32 @@
package yuxingshi.ssm.common.core.domain.dto;
import jakarta.validation.constraints.Max;
import lombok.Data;
/**
* DTO
*/
@Data
public class BasePageReqDTO {
/**
*
*/
private Integer pageNo = 1;
/**
*
*/
@Max(20)
private Integer pageSize = 10;
/**
*
*
* @return
*/
public Integer getOffset() {
return (pageNo - 1) * pageSize;
}
}

@ -0,0 +1,54 @@
package yuxingshi.ssm.common.core.domain.dto;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
*
*/
@Getter
@Setter
@ToString
public class LoginUserDTO {
/**
*
*/
private String userKey;
/**
* Id
*/
private String userId;
/**
*
*/
private String userFrom;
/**
*
*/
private String userName;
/**
*
*/
private Integer userIdentity;
/**
*
*/
private Long loginTime;
/**
*
*/
private Long expireTime;
}

@ -0,0 +1,141 @@
package yuxingshi.ssm.common.core.domain.vo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import yuxingshi.ssm.common.core.constants.ResultCode;
/**
*
*
* @param <T>
*/
@Getter
@Setter
@ToString
public class R<T> {
/**
*
*/
private int code;
/**
*
*/
private String msg;
/**
*
*/
private T data;
/**
*
*
* @return
* @param <T>
*/
public static <T> R<T> ok() {
return restResult(null, ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg());
}
/**
*
* @param data
* @return
* @param <T>
*/
public static <T> R<T> ok(T data) {
return restResult(data, ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg());
}
/**
*
* @param data
* @param msg
* @return
* @param <T>
*/
public static <T> R<T> ok(T data, String msg) {
return restResult(data, ResultCode.SUCCESS.getCode(), msg);
}
/**
*
* @return
* @param <T>
*/
public static <T> R<T> fail() {
return restResult(null, ResultCode.ERROR.getCode(), ResultCode.ERROR.getMsg());
}
/**
*
* @param msg
* @return
* @param <T>
*/
public static <T> R<T> fail(String msg) {
return restResult(null, ResultCode.ERROR.getCode(), msg);
}
/**
*
* @param code
* @param msg
* @return
* @param <T>
*/
public static <T> R<T> fail(Integer code,String msg) {
return restResult(null, code, msg);
}
/**
*
* @param data
* @return
* @param <T>
*/
public static <T> R<T> fail(T data) {
return restResult(data, ResultCode.ERROR.getCode(), ResultCode.ERROR.getMsg());
}
/**
*
* @param data
* @param msg
* @return
* @param <T>
*/
public static <T> R<T> fail(T data, String msg) {
return restResult(data, ResultCode.ERROR.getCode(), msg);
}
/**
*
* @param code
* @param msg
* @return
* @param <T>
*/
public static <T> R<T> fail(int code, String msg) {
return restResult(null, code, msg);
}
/**
*
* @param data
* @param code
* @param msg
* @return
* @param <T>
*/
private static <T> R<T> restResult(T data, int code, String msg) {
R<T> apiResult = new R<>();
apiResult.setCode(code);
apiResult.setData(data);
apiResult.setMsg(msg);
return apiResult;
}
}

@ -0,0 +1,240 @@
package yuxingshi.ssm.common.core.utils;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import yuxingshi.ssm.common.core.constants.CommonConstants;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* JSON
* :
* 1. JSON
* 2. JSON
*/
@Slf4j
public class JsonUtil {
/**
*
*/
private static ObjectMapper OBJECT_MAPPER;
/**
* init...
* 1. .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
* JSON Java
* Jackson false
* JSON
* : Student:name, JSONStudent:name,sex,sex,falsesex
* <br>
* 2. .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
* Java Jackson
* false
* 便 JSON
* <br>
* 3. .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
* Java Jackson
* false 便 JSON
* JSON {}
* <br>
* 4. .configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false)
* JSON Java
* false使
*
* JSON
* <br>
* 5. .configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false)
* Java Map Date
* true false
* 使 JSON
* (false)
* <br>
* 6. .configure(MapperFeature.USE_ANNOTATIONS, false)
* Jackson Java
* false
* JSON 使
*
* 7. addModule(new JavaTimeModule())
* LocalDateTImeLocalDate,Jackson-data-JSR310
* <br>
* 8. .defaultDateFormat(new SimpleDateFormat(CommonConstants.STANDARD_FORMAT))
* yyyy-MM-dd HH:mm:ss
* <br>
* 9. .addModule(new SimpleModule().addSerializer(LocalDateTime.class, new
* LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
* //序列时起作用
* .addDeserializer(LocalDateTime.class, new
* LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd
* HH:mm:ss"))) //反序列时起作用)
* LocalDateTImeLocalDatejson
* LocalDateTImeLocalDate
*/
static {
OBJECT_MAPPER = JsonMapper.builder().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false)
// 不适用默认的dateTime进行序列化,使用JSR310的LocalDateTimeSerializer
.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false)
.configure(MapperFeature.USE_ANNOTATIONS, true)
// 重点,这是序列化LocalDateTIme和LocalDate的必要配置,由Jackson-data-JSR310实现
.addModule(new JavaTimeModule())
.addModule(new SimpleModule()
.addSerializer(LocalDateTime.class,
new LocalDateTimeSerializer(
DateTimeFormatter.ofPattern(CommonConstants.STANDARD_FORMAT)))
.addDeserializer(LocalDateTime.class,
new LocalDateTimeDeserializer(
DateTimeFormatter.ofPattern(CommonConstants.STANDARD_FORMAT))))
// 所有的日期格式都统一为以下的样式即yyyy-MM-dd HH:mm:ss
.defaultDateFormat(new SimpleDateFormat(CommonConstants.STANDARD_FORMAT))
// 只针对非空的值进行序列化
.serializationInclusion(JsonInclude.Include.NON_NULL)
.build();
}
/**
*
*/
private JsonUtil() {
}
/**
* Json
*
* @param obj
* @return Json
* @param <T>
*/
public static <T> String obj2String(T obj) {
if (obj == null) {
return null;
}
try {
return obj instanceof String ? (String) obj : OBJECT_MAPPER.writeValueAsString(obj);
} catch (JsonProcessingException e) {
log.warn("Parse Object to String error : {}", e.getMessage());
return null;
}
}
/**
* Json(Json)
*
* @param obj
* @return Json
* @param <T>
*/
public static <T> String obj2StringPretty(T obj) {
if (obj == null) {
return null;
}
try {
return obj instanceof String ? (String) obj
: OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
} catch (JsonProcessingException e) {
log.warn("Parse Object to String error : {}", e.getMessage());
return null;
}
}
/**
*
*
* @param str
* @param clazz class
* @return
* @param <T>
*/
public static <T> T string2Obj(String str, Class<T> clazz) {
if (str == null || str.isEmpty() || clazz == null) {
return null;
}
try {
return clazz.equals(String.class) ? (T) str : OBJECT_MAPPER.readValue(str, clazz);
} catch (Exception e) {
log.warn("Parse String to Object error : {}", e.getMessage());
return null;
}
}
/**
* ,
*
* @param str json
* @param valueTypeRef
* 使 new TypeReference<List<Map<String,TestObj>>>() {}
* @return
* @param <T>
*/
public static <T> T string2Obj(String str, TypeReference<T> valueTypeRef) {
if (StringUtils.isEmpty(str) || valueTypeRef == null) {
return null;
}
try {
return OBJECT_MAPPER.readValue(str, valueTypeRef);
} catch (Exception e) {
log.warn("Parse String to Object error : {}", e.getMessage());
return null;
}
}
/**
* list,List
*
* @param str json
* @param clazz
* @return
* @param <T>
*/
public static <T> List<T> string2List(String str, Class<T> clazz) {
if (str == null || str.isEmpty() || clazz == null) {
return null;
}
JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(List.class, clazz);
try {
return OBJECT_MAPPER.readValue(str, javaType);
} catch (IOException e) {
log.warn("Parse String to List error : {}", e.getMessage());
return null;
}
}
/**
* map,Map
*
* @param str str
* @param valueClass valueClass value
* @return map
* @param <T> value
*/
public static <T> Map<String, T> string2Map(String str, Class<T> valueClass) {
if (str == null || str.isEmpty() || valueClass == null) {
return null;
}
JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructMapType(LinkedHashMap.class,
String.class, valueClass);
try {
return OBJECT_MAPPER.readValue(str, javaType);
} catch (JsonProcessingException e) {
log.warn("Parse String to Map error : {}", e.getMessage());
return null;
}
}
}

@ -0,0 +1,157 @@
package yuxingshi.ssm.common.core.utils;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import reactor.core.publisher.Mono;
import yuxingshi.ssm.common.core.constants.CommonConstants;
import yuxingshi.ssm.common.core.domain.vo.R;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
/**
* Servlet
*/
public class ServletUtil {
/**
*
*
* @param str
* @return
*/
public static String urlEncode(String str) {
try {
return URLEncoder.encode(str, CommonConstants.UTF8);
} catch (UnsupportedEncodingException e) {
return StringUtils.EMPTY;
}
}
/**
* webflux
*
* @param response ServerHttpResponse
* @param code
* @param value
* @return
*/
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value, int code) {
return webFluxResponseWriter(response, HttpStatus.OK, value, code);
}
/**
* webflux
*
* @param response ServerHttpResponse
* @param status http
* @param code
* @param value
* @return
*/
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, HttpStatus status, Object value, int code) {
//修改了
return webFluxResponseWriter(response, MediaType.APPLICATION_JSON_VALUE, status, value, code);
}
/**
* webflux
*
* @param response ServerHttpResponse
* @param contentType content-type
* @param status http
* @param code
* @param value
* @return
*/
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, String contentType, HttpStatus status, Object value, int code) {
response.setStatusCode(status);
response.getHeaders().add(HttpHeaders.CONTENT_TYPE, contentType);
R<?> result = R.fail(code, value.toString());
DataBuffer dataBuffer = response.bufferFactory().wrap(JsonUtil.obj2String(result).getBytes());
return response.writeWith(Mono.just(dataBuffer));
}
/**
* request
*
* @return request
*/
public static HttpServletRequest getRequest() {
try {
return getRequestAttributes().getRequest();
} catch (Exception e) {
return null;
}
}
/**
* request
*
* @return request
*/
public static ServletRequestAttributes getRequestAttributes() {
try {
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
return (ServletRequestAttributes) attributes;
} catch (Exception e) {
return null;
}
}
/**
* Header
* @param mutate
* @param name
* @param value
*/
public static void addHeader(ServerHttpRequest.Builder mutate, String name, Object value) {
if(value == null) {
return;
}
String valueStr = value.toString();
String valueEncode = urlEncode(valueStr);
mutate.header(name,valueEncode);
}
/**
* IP:
* IP使request.getRemoteAddr()
* 使ip
* 使LVS/NginxipX-Forwarded-ForunknownIPip
* @return
*/
public static String getRequestIp() {
HttpServletRequest request = getRequest();
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}

@ -0,0 +1,56 @@
package yuxingshi.ssm.common.core.utils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.AntPathMatcher;
import java.util.List;
/**
*
*/
public class StringUtil extends StringUtils{
/**
*
*
* @param str
* @param patternList
* @return
*/
public static boolean matches(String str, List<String> patternList)
{
if (StringUtils.isEmpty(str) || CollectionUtils.isEmpty(patternList))
{
return false;
}
for (String pattern : patternList)
{
if (isMatch(pattern, str))
{
return true;
}
}
return false;
}
/**
* url
*
*
*
* ? ;
* * ;
* **
*
* @param pattern
* @param url url
* @return
*/
public static boolean isMatch(String pattern, String url)
{
if (StringUtils.isEmpty(url) || StringUtils.isEmpty(pattern)) {
return false;
}
AntPathMatcher matcher = new AntPathMatcher();
return matcher.match(pattern, url);
}
}

@ -0,0 +1,38 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>yuxingshi</groupId>
<artifactId>yuxingshi-ssm-common</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>yuxingshi.ssm.common.intercepter</groupId>
<artifactId>yuxingshi-ssm-intercepter</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>yuxingshi.ssm.common.core</groupId>
<artifactId>yuxingshi-ssm-core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>yuxingshi.ssm.common.security</groupId>
<artifactId>yuxingshi-ssm-security</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

@ -0,0 +1,22 @@
package yuxingshi.ssm.common.intercepter.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import yuxingshi.ssm.common.intercepter.filer.AuthInterceptor;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/**/login/**");
}
}

@ -0,0 +1,37 @@
package yuxingshi.ssm.common.intercepter.filer;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import yuxingshi.ssm.common.security.service.TokenService;
import yuxingshi.ssm.common.security.utils.SecurityUtil;
/**
*
*/
@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Autowired
private TokenService tokenService;
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
return true;
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
}
}

@ -0,0 +1,2 @@
yuxingshi.ssm.common.intercepter.config.WebConfig
yuxingshi.ssm.common.intercepter.filer.AuthInterceptor

@ -0,0 +1,36 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>yuxingshi</groupId>
<artifactId>yuxingshi-ssm-common</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>yuxingshi.ssm.common.mybatisplus</groupId>
<artifactId>yuxingshi-ssm-mybatisplus</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
</dependency>
<dependency>
<groupId>yuxingshi.ssm.common.core</groupId>
<artifactId>yuxingshi-ssm-core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.a3test.component</groupId>
<artifactId>idworker-snowflake</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,25 @@
package yuxingshi.ssm.common.mybatisplus.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* MyBatisPlus
*/
@Configuration
public class MyBatisPlusConfig {
/**
* MyBatisPlus
*/
@Bean
public MybatisPlusInterceptor paginationInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//添加MySQL的分页拦截器
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}

@ -0,0 +1,21 @@
package yuxingshi.ssm.common.mybatisplus.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
@Getter
@Setter
public class BaseEntity {
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createdTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updatedTime;
}

@ -0,0 +1,25 @@
package yuxingshi.ssm.common.mybatisplus.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler { ;
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject,"createdTime", LocalDateTime.class,LocalDateTime.now());
this.strictInsertFill(metaObject,"updatedTime", LocalDateTime.class,LocalDateTime.now());
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictInsertFill(metaObject,"updatedTime", LocalDateTime.class,LocalDateTime.now());
}
}

@ -0,0 +1,2 @@
yuxingshi.ssm.common.mybatisplus.config.MyBatisPlusConfig
yuxingshi.ssm.common.mybatisplus.handler.MyMetaObjectHandler

@ -0,0 +1,45 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>yuxingshi</groupId>
<artifactId>yuxingshi-ssm-common</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>yuxingshi.ssm.common.redis</groupId>
<artifactId>yuxingshi-ssm-redis</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
<!-- redisson -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>yuxingshi.ssm.common.core</groupId>
<artifactId>yuxingshi-ssm-core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,118 @@
package yuxingshi.ssm.common.redis.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import yuxingshi.ssm.common.core.constants.CommonConstants;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Configuration
public class RedisConfig {
private static final Logger log = LoggerFactory.getLogger(RedisConfig.class);
/**
* RedisTemplate
*
* @param redisConnectionFactory redisSpring Boot
* @return Redis
*
*
* 1. setKeySerializer/setHashKeySerializer:
* - 使StringRedisSerializerStringHash
* - Redis
* 2. setValueSerializer:
* - 使GenericJackson2JsonRedisSerializerJSON
* -
* 3. setHashValueSerializer:
* - Hash使JSON
* 4. afterPropertiesSet():
* -
*
*
*/
@Bean(name = "customRedisTemplate")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
log.info("Configure Redis serialization");
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer =
createJacksonSerializer();
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
/**
* Jackson
*
* @return JSON
*
* ObjectMapper
* 1. FAIL_ON_UNKNOWN_PROPERTIES(false):
* - JSON
* 2. WRITE_DATES_AS_TIMESTAMPS(false):
* - 使
* 3. FAIL_ON_EMPTY_BEANS(false):
* - Bean
* 4. FAIL_ON_INVALID_SUBTYPE(false):
* -
* 5. WRITE_DATE_KEYS_AS_TIMESTAMPS(false):
* - Map使
* 6. defaultDateFormat():
* - "yyyy-MM-dd HH:mm:ss"
* 7. USE_ANNOTATIONS(false):
* - Jackson
* 8. JavaTimeModule():
* - Java8LocalDateTime
* 9. serializationInclusion(NON_NULL):
* - null
*/
public GenericJackson2JsonRedisSerializer createJacksonSerializer() {
// 创建自定义日期格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(CommonConstants.STANDARD_FORMAT);
// 创建并配置 JavaTimeModule
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
ObjectMapper objectMapper =
JsonMapper.builder()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false)
.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false)
.defaultDateFormat(new SimpleDateFormat(CommonConstants.STANDARD_FORMAT))
.configure(MapperFeature.USE_ANNOTATIONS, false)
// 注册自定义时间模块
.addModule(javaTimeModule)
.serializationInclusion(JsonInclude.Include.NON_NULL)
.build();
return new GenericJackson2JsonRedisSerializer(objectMapper);
}
}

@ -0,0 +1,2 @@
yuxingshi.ssm.common.redis.config.RedisConfig
yuxingshi.ssm.common.redis.server.RedisService

@ -0,0 +1,53 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>yuxingshi</groupId>
<artifactId>yuxingshi-ssm-common</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>yuxingshi.ssm.common.security</groupId>
<artifactId>yuxingshi-ssm-security</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>yuxingshi.ssm.common.core</groupId>
<artifactId>yuxingshi-ssm-core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>yuxingshi.ssm.common.redis</groupId>
<artifactId>yuxingshi-ssm-redis</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,21 @@
package yuxingshi.ssm.common.security.annotation;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;
@Documented
@Constraint(validatedBy = ValueInValidator.class)
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValueIn {
String message() default "值不在指定范围内";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
// 枚举类
Class<? extends Enum<?>> enumClass();
}

@ -0,0 +1,57 @@
package yuxingshi.ssm.common.security.annotation;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
public class ValueInValidator implements ConstraintValidator<ValueIn, Object> {
private ValueIn constraint;
private Set<Object> validValues = new HashSet<>();
private Class<?> valueType;
private Method getValueMethod;
@Override
public void initialize(ValueIn constraint) {
this.constraint = constraint;
Class<? extends Enum<?>> enumClass = constraint.enumClass();
// 获取枚举值
Enum<?>[] enumConstants = enumClass.getEnumConstants();
if (enumConstants == null || enumConstants.length == 0) {
throw new IllegalArgumentException("枚举类 " + enumClass.getName() + " 不包含任何值");
}
try {
// 强制要求必须存在 getValue() 方法
this.getValueMethod = enumClass.getMethod("getValue");
this.valueType = getValueMethod.getReturnType();
// 收集所有有效的 value 值
for (Enum<?> e : enumConstants) {
Object value = getValueMethod.invoke(e);
validValues.add(value);
}
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("枚举类 " + enumClass.getName() + " 必须包含 getValue() 方法", e);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException("无法访问枚举的 getValue() 方法", e);
}
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
if(value.getClass() != valueType){
return false;
}
return validValues.contains(value);
}
}

@ -0,0 +1,28 @@
package yuxingshi.ssm.common.security.dto;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
*
*/
@Getter
@Setter
@ToString
public class TokenDto {
/**
* 访
*/
private String accessToken;
/**
*
*/
private Long expires;
private Integer role;
}

@ -0,0 +1,171 @@
package yuxingshi.ssm.common.security.service;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import yuxingshi.ssm.common.core.constants.CacheConstants;
import yuxingshi.ssm.common.core.constants.SecurityConstants;
import yuxingshi.ssm.common.core.constants.TokenConstants;
import yuxingshi.ssm.common.core.domain.dto.LoginUserDTO;
import yuxingshi.ssm.common.core.utils.ServletUtil;
import yuxingshi.ssm.common.redis.server.RedisService;
import yuxingshi.ssm.common.security.dto.TokenDto;
import yuxingshi.ssm.common.security.utils.JwtUtil;
import yuxingshi.ssm.common.security.utils.SecurityUtil;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* token
*/
@Component
public class TokenService {
/**
* (s)
*/
private static final Long LOGIN_USER_EXP = CacheConstants.LOGIN_USER_EXPIRATION * 60 * 1000;
@Autowired
private RedisService redisService;
/**
* token
* @param loginUserDto
* @return token
*/
public TokenDto createToken(LoginUserDTO loginUserDto) {
String userKey = UUID.randomUUID().toString().replaceAll("-", "");
loginUserDto.setUserKey(userKey);
refreshToken(loginUserDto);
Map<String,Object> claimMap = new HashMap<>();
claimMap.put(SecurityConstants.USER_KEY,userKey);
claimMap.put(SecurityConstants.USER_ID,loginUserDto.getUserId());
claimMap.put(SecurityConstants.USER_FROM,loginUserDto.getUserFrom());
claimMap.put(SecurityConstants.USER_IDENTITY,loginUserDto.getUserIdentity());
TokenDto tokenDto = new TokenDto();
tokenDto.setAccessToken(JwtUtil.createToken(claimMap));
tokenDto.setExpires(LOGIN_USER_EXP);
refreshToken(loginUserDto);
return tokenDto;
}
/**
*
* @param token
* @return
*/
public LoginUserDTO getLoginUserDto(String token) {
LoginUserDTO loginUserDto = null;
// 解析令牌
try {
if(StringUtils.isNoneBlank(token)) {
Claims claims = JwtUtil.parseToken(token);
String userKey = JwtUtil.getUserKey(claims);
String userId = JwtUtil.getUserId(claims);
String userFrom = JwtUtil.getUserFrom(claims);
loginUserDto = redisService.getCacheObject(getCacheKey(userKey,userId,userFrom), LoginUserDTO.class);
}
return loginUserDto;
}catch (Exception e) {}
return loginUserDto;
}
/**
*
* @param request
* @return
*/
public LoginUserDTO getLoginUserDto(HttpServletRequest request) {
String token = SecurityUtil.getToken(request);
return getLoginUserDto(token);
}
/**
*
* @return
*/
public LoginUserDTO getLoginUserDto() {
return getLoginUserDto(ServletUtil.getRequest());
}
/**
*
*/
public void removeLoginStatus(String token) {
if(StringUtils.isNoneBlank(token)) {
Claims claims = JwtUtil.parseToken(token);
String userKey = JwtUtil.getUserKey(claims);
String userId = JwtUtil.getUserId(claims);
String userFrom = JwtUtil.getUserFrom(claims);
String cacheKey = getCacheKey(userKey,userId,userFrom);
redisService.deleteObject(cacheKey);
}
}
/**
*
* @param userId Id
* @param userFrom
*/
public void removeLoginStatus(Long userId,String userFrom) {
String split = TokenConstants.LOGIN_CACHE_INGO_SPLIT;
String pattern = TokenConstants.LOGIN_TOKEN_KEY + split + userId + split + userFrom +split + "*";
redisService.scanAndDelete(pattern,100);
}
/**
*
* @param loginUserDto
*/
public void setLoginUser(LoginUserDTO loginUserDto) {
if(loginUserDto != null && StringUtils.isNoneBlank(loginUserDto.getUserKey())) {
refreshToken(loginUserDto);
}
}
/**
* 120,
* @param loginUserDto
*/
public void extendToken(LoginUserDTO loginUserDto) {
long expTime = loginUserDto.getExpireTime();
long currentTime = System.currentTimeMillis();
if(currentTime - expTime <= CacheConstants.LOGIN_USER_EXP_CRITICAL_TIME * 60) {
loginUserDto.setLoginTime(currentTime);
loginUserDto.setExpireTime(currentTime + LOGIN_USER_EXP);
refreshToken(loginUserDto);
}
}
/**
*
* @param loginUserDto
*/
private void refreshToken(LoginUserDTO loginUserDto) {
loginUserDto.setLoginTime(System.currentTimeMillis());
loginUserDto.setExpireTime(loginUserDto.getLoginTime() + LOGIN_USER_EXP);
String cacheKey = getCacheKey(loginUserDto.getUserKey(), loginUserDto.getUserId(),loginUserDto.getUserFrom());
redisService.setCacheObject(cacheKey,loginUserDto,LOGIN_USER_EXP, TimeUnit.MILLISECONDS);
}
/**
*
* @param userKey
* @return
*/
public String getCacheKey(String userKey,String userId,String userFrom) {
String split = TokenConstants.LOGIN_CACHE_INGO_SPLIT;
return TokenConstants.LOGIN_TOKEN_KEY + ":" + userId + split + userFrom +split+ userKey;
}
}

@ -0,0 +1,156 @@
package yuxingshi.ssm.common.security.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import yuxingshi.ssm.common.core.constants.SecurityConstants;
import yuxingshi.ssm.common.core.constants.TokenConstants;
import java.util.Map;
/**
*
*/
public class JwtUtil {
private static final Logger log = LoggerFactory.getLogger(JwtUtil.class);
public static String secret = TokenConstants.SECRET;
/**
*
* @param claims
* @return
*/
public static String createToken(Map<String,Object> claims) {
return Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();
}
/**
*
* @param token
* @return
*/
public static Claims parseToken(String token) {
try {
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
}catch (Exception e) {
log.warn("[JwtUtil.parseToken]");
return null;
}
}
/**
*
* @param token
* @return
*/
public static String getUserKey(String token) {
Claims claims = parseToken(token);
return getValue(claims, SecurityConstants.USER_KEY);
}
/**
* Id
* @param claims
* @return id
*/
public static String getUserId(Claims claims) {
return getValue(claims, SecurityConstants.USER_ID);
}
/**
* id
* @param token
* @return id
*/
public static String getUserId(String token) {
Claims claims = parseToken(token);
return getValue(claims, SecurityConstants.USER_ID);
}
/**
*
* @param claims
* @return
*/
public static String getUserName(Claims claims) {
return getValue(claims, SecurityConstants.USERNAME);
}
/**
*
* @param token
* @return
*/
public static String getUserIdentity(String token) {
Claims claims = parseToken(token);
return getValue(claims, SecurityConstants.USER_IDENTITY);
}
/**
*
* @param claims
* @return
*/
public static String getUserIdentity(Claims claims) {
return getValue(claims, SecurityConstants.USER_IDENTITY);
}
/**
*
* @param token
* @return
*/
public static String getUserFrom(String token) {
Claims claims = parseToken(token);
return getValue(claims, SecurityConstants.USER_FROM);
}
/**
*
* @param claims
* @return
*/
public static String getUserFrom(Claims claims) {
return getValue(claims, SecurityConstants.USER_FROM);
}
/**
*
* @param token
* @return
*/
public static String getUserName(String token) {
Claims claims = parseToken(token);
return getValue(claims, SecurityConstants.USERNAME);
}
/**
*
* @param claims
* @return
*/
public static String getUserKey(Claims claims) {
return getValue(claims, SecurityConstants.USER_KEY);
}
/**
*
* @param claims
* @param key
* @return
*/
public static String getValue(Claims claims,String key) {
Object value = claims.get(key);
if(value == null) {
return "";
}
return value.toString();
}
}

@ -0,0 +1,53 @@
package yuxingshi.ssm.common.security.utils;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.server.reactive.ServerHttpRequest;
import yuxingshi.ssm.common.core.constants.SecurityConstants;
import yuxingshi.ssm.common.core.constants.TokenConstants;
import yuxingshi.ssm.common.core.utils.ServletUtil;
/**
*
*/
public class SecurityUtil {
/**
* token
* @return token
*/
public static String getToken() {
return getToken(ServletUtil.getRequest());
}
/**
* token
* @param request
* @return token
*/
public static String getToken(HttpServletRequest request) {
return replaceTokenPrefix(request.getHeader(SecurityConstants.AUTHENTICATION));
}
/**
* token
* @param request
* @return token
*/
public static String getToken(ServerHttpRequest request) {
return replaceTokenPrefix(request.getHeaders().getFirst(SecurityConstants.AUTHENTICATION));
}
/**
* token
* @param token
* @return token
*/
public static String replaceTokenPrefix(String token) {
if(StringUtils.isNoneBlank(token) && token.startsWith(TokenConstants.PREFIX)){
token.replaceFirst(TokenConstants.PREFIX,"");
}
return token;
}
}

@ -0,0 +1,47 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>yuxingshi</groupId>
<artifactId>yuxingshi-ssm</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>yuxingshi.ssm.server</groupId>
<artifactId>yuxingshi-ssm-server</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
</dependency>
</dependencies>
</project>

@ -0,0 +1,7 @@
package yuxingshi.ssm.server;
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
Loading…
Cancel
Save