commit:1.6版本发布

This commit is contained in:
Jerry
2021-05-02 20:19:06 +08:00
parent 1a713fa34f
commit 5f9a18a8eb
78 changed files with 1183 additions and 826 deletions

View File

@@ -6,15 +6,14 @@
<sourceOutputDir name="target/generated-sources/annotations" /> <sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" /> <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" /> <outputRelativeToContentRoot value="true" />
<module name="upms-service" />
<module name="application-common" /> <module name="application-common" />
<module name="gateway" /> <module name="gateway" />
<module name="stats-api" /> <module name="stats-api" />
<module name="common-swagger" /> <module name="upms-service" />
<module name="common-sequence" /> <module name="common-sequence" />
<module name="upms-api" /> <module name="upms-api" />
<module name="common-datafilter" />
<module name="course-class-service" /> <module name="course-class-service" />
<module name="common-swagger" />
<module name="common-core" /> <module name="common-core" />
<module name="common-redis" /> <module name="common-redis" />
<module name="admin-monitor" /> <module name="admin-monitor" />

View File

@@ -14,8 +14,6 @@
<file url="file://$PROJECT_DIR$/application/upms/upms-service/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/application/upms/upms-service/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/application/upms/upms-service/src/main/resources" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/application/upms/upms-service/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/common/common-core/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/common/common-core/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/common/common-datafilter/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/common/common-datafilter/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/common/common-redis/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/common/common-redis/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/common/common-redis/src/main/resources" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/common/common-redis/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/common/common-sequence/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/common/common-sequence/src/main/java" charset="UTF-8" />

View File

@@ -14,57 +14,6 @@
<inspection_tool class="CheckDtdRefs" enabled="false" level="ERROR" enabled_by_default="false" /> <inspection_tool class="CheckDtdRefs" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CheckTagEmptyBody" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="CheckTagEmptyBody" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CheckXmlFileWithXercesValidator" enabled="false" level="ERROR" enabled_by_default="false" /> <inspection_tool class="CheckXmlFileWithXercesValidator" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitAbstractClassShouldStartWithAbstractNaming" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitAbstractMethodOrInterfaceMethodMustUseJavadoc" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitAvoidApacheBeanUtilsCopy" enabled="false" level="BLOCKER" enabled_by_default="false" />
<inspection_tool class="CloudToolkitAvoidCallStaticSimpleDateFormat" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitAvoidCommentBehindStatement" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitAvoidComplexCondition" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitAvoidConcurrentCompetitionRandom" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitAvoidDoubleOrFloatEqualCompare" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitAvoidManuallyCreateThread" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitAvoidMissUseOfMathRandom" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitAvoidNegationOperator" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitAvoidNewDateGetTime" enabled="false" level="BLOCKER" enabled_by_default="false" />
<inspection_tool class="CloudToolkitAvoidPatternCompileInMethod" enabled="false" level="BLOCKER" enabled_by_default="false" />
<inspection_tool class="CloudToolkitAvoidReturnInFinally" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitAvoidStartWithDollarAndUnderLineNaming" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitAvoidUseTimer" enabled="false" level="BLOCKER" enabled_by_default="false" />
<inspection_tool class="CloudToolkitBigDecimalAvoidDoubleConstructor" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitBooleanPropertyShouldNotStartWithIs" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitClassCastExceptionWithSubListToArrayList" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitClassCastExceptionWithToArray" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitClassMustHaveAuthor" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitClassNamingShouldBeCamel" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitCollectionInitShouldAssignCapacity" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitCommentsMustBeJavadocFormat" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitConcurrentExceptionWithModifyOriginSubList" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitConstantFieldShouldBeUpperCase" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitCountDownShouldInFinally" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitDontModifyInForeachCircle" enabled="false" level="BLOCKER" enabled_by_default="false" />
<inspection_tool class="CloudToolkitEnumConstantsMustHaveComment" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitExceptionClassShouldEndWithException" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitIbatisMethodQueryForList" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitLowerCamelCaseVariableNaming" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitMethodReturnWrapperType" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitMethodTooLong" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitPackageNaming" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitPojoMustOverrideToString" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitPojoMustUsePrimitiveField" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitPojoNoDefaultValue" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitRemoveCommentedCode" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitServiceOrDaoClassShouldEndWithImpl" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitStringConcat" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitSwitchStatement" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitTestClassShouldEndWithTestNaming" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitThreadLocalShouldRemove" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitThreadPoolCreation" enabled="false" level="BLOCKER" enabled_by_default="false" />
<inspection_tool class="CloudToolkitThreadShouldSetName" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitTransactionMustHaveRollback" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitUndefineMagicConstant" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitUnsupportedExceptionWithModifyAsList" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="CloudToolkitUseQuietReferenceNotation" enabled="false" level="MAJOR" enabled_by_default="false" />
<inspection_tool class="CloudToolkitUseRightCaseForDateFormat" enabled="false" level="CRITICAL" enabled_by_default="false" />
<inspection_tool class="ConstantConditions" enabled="false" level="WARNING" enabled_by_default="false"> <inspection_tool class="ConstantConditions" enabled="false" level="WARNING" enabled_by_default="false">
<option name="SUGGEST_NULLABLE_ANNOTATIONS" value="false" /> <option name="SUGGEST_NULLABLE_ANNOTATIONS" value="false" />
<option name="DONT_REPORT_TRUE_ASSERT_STATEMENTS" value="false" /> <option name="DONT_REPORT_TRUE_ASSERT_STATEMENTS" value="false" />

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: com.orange.demo:common-log:1.0.0">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/orange/demo/common-log/1.0.0/common-log-1.0.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/orange/demo/common-log/1.0.0/common-log-1.0.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/orange/demo/common-log/1.0.0/common-log-1.0.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.apache.commons:commons-pool2:2.7.0">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-pool2/2.7.0/commons-pool2-2.7.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-pool2/2.7.0/commons-pool2-2.7.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-pool2/2.7.0/commons-pool2-2.7.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.springframework.kafka:spring-kafka:2.3.6.RELEASE">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/kafka/spring-kafka/2.3.6.RELEASE/spring-kafka-2.3.6.RELEASE.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/kafka/spring-kafka/2.3.6.RELEASE/spring-kafka-2.3.6.RELEASE-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/kafka/spring-kafka/2.3.6.RELEASE/spring-kafka-2.3.6.RELEASE-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.springframework.retry:spring-retry:1.2.5.RELEASE">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/retry/spring-retry/1.2.5.RELEASE/spring-retry-1.2.5.RELEASE.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/retry/spring-retry/1.2.5.RELEASE/spring-retry-1.2.5.RELEASE-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/retry/spring-retry/1.2.5.RELEASE/spring-retry-1.2.5.RELEASE-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="Maven: org.springframework:spring-messaging:5.2.4.RELEASE">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-messaging/5.2.4.RELEASE/spring-messaging-5.2.4.RELEASE.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-messaging/5.2.4.RELEASE/spring-messaging-5.2.4.RELEASE-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/springframework/spring-messaging/5.2.4.RELEASE/spring-messaging-5.2.4.RELEASE-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: redis.clients:jedis:3.1.0">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/redis/clients/jedis/3.1.0/jedis-3.1.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/redis/clients/jedis/3.1.0/jedis-3.1.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/redis/clients/jedis/3.1.0/jedis-3.1.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: redis.clients:jedis:3.2.0">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/redis/clients/jedis/3.2.0/jedis-3.2.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/redis/clients/jedis/3.2.0/jedis-3.2.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/redis/clients/jedis/3.2.0/jedis-3.2.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -8,6 +8,7 @@
</option> </option>
<option name="ignoredFiles"> <option name="ignoredFiles">
<set> <set>
<option value="$PROJECT_DIR$/common/common-datafilter/pom.xml" />
<option value="$PROJECT_DIR$/common/common-log/pom.xml" /> <option value="$PROJECT_DIR$/common/common-log/pom.xml" />
<option value="$PROJECT_DIR$/framework/apidoc-tools/pom.xml" /> <option value="$PROJECT_DIR$/framework/apidoc-tools/pom.xml" />
</set> </set>

View File

@@ -8,7 +8,6 @@
<module fileurl="file://$PROJECT_DIR$/application/application-common/application-common.iml" filepath="$PROJECT_DIR$/application/application-common/application-common.iml" /> <module fileurl="file://$PROJECT_DIR$/application/application-common/application-common.iml" filepath="$PROJECT_DIR$/application/application-common/application-common.iml" />
<module fileurl="file://$PROJECT_DIR$/common/common.iml" filepath="$PROJECT_DIR$/common/common.iml" /> <module fileurl="file://$PROJECT_DIR$/common/common.iml" filepath="$PROJECT_DIR$/common/common.iml" />
<module fileurl="file://$PROJECT_DIR$/common/common-core/common-core.iml" filepath="$PROJECT_DIR$/common/common-core/common-core.iml" /> <module fileurl="file://$PROJECT_DIR$/common/common-core/common-core.iml" filepath="$PROJECT_DIR$/common/common-core/common-core.iml" />
<module fileurl="file://$PROJECT_DIR$/common/common-datafilter/common-datafilter.iml" filepath="$PROJECT_DIR$/common/common-datafilter/common-datafilter.iml" />
<module fileurl="file://$PROJECT_DIR$/common/common-redis/common-redis.iml" filepath="$PROJECT_DIR$/common/common-redis/common-redis.iml" /> <module fileurl="file://$PROJECT_DIR$/common/common-redis/common-redis.iml" filepath="$PROJECT_DIR$/common/common-redis/common-redis.iml" />
<module fileurl="file://$PROJECT_DIR$/common/common-sequence/common-sequence.iml" filepath="$PROJECT_DIR$/common/common-sequence/common-sequence.iml" /> <module fileurl="file://$PROJECT_DIR$/common/common-sequence/common-sequence.iml" filepath="$PROJECT_DIR$/common/common-sequence/common-sequence.iml" />
<module fileurl="file://$PROJECT_DIR$/common/common-swagger/common-swagger.iml" filepath="$PROJECT_DIR$/common/common-swagger/common-swagger.iml" /> <module fileurl="file://$PROJECT_DIR$/common/common-swagger/common-swagger.iml" filepath="$PROJECT_DIR$/common/common-swagger/common-swagger.iml" />

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="03a5281b-25b1-47eb-9d2b-a05e68843595" name="Default Changelist" comment="" /> <list default="true" id="7fe4264b-f60a-410c-b293-4e63b182af6c" name="Default Changelist" comment="" />
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
@@ -13,7 +13,7 @@
<component name="ProjectCodeStyleSettingsMigration"> <component name="ProjectCodeStyleSettingsMigration">
<option name="version" value="1" /> <option name="version" value="1" />
</component> </component>
<component name="ProjectId" id="1qTqJ7jXIGQz6yKNsUD15pNs70Q" /> <component name="ProjectId" id="1ryDMZ7EdAVLRSzZcgcznSfWIqn" />
<component name="ProjectViewState"> <component name="ProjectViewState">
<option name="abbreviatePackageNames" value="true" /> <option name="abbreviatePackageNames" value="true" />
<option name="autoscrollFromSource" value="true" /> <option name="autoscrollFromSource" value="true" />
@@ -27,16 +27,11 @@
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" /> <property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" /> <property name="WebServerToolWindowFactoryState" value="false" />
<property name="aspect.path.notification.shown" value="true" /> <property name="aspect.path.notification.shown" value="true" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/zz-resource/db-scripts" /> <property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="nodejs_interpreter_path" value="/usr/local/bin/node" /> <property name="nodejs_interpreter_path" value="/usr/local/bin/node" />
<property name="settings.editor.selected.configurable" value="Errors" /> <property name="settings.editor.selected.configurable" value="Errors" />
</component> </component>
<component name="RecentsManager"> <component name="RunManager" selected="Spring Boot.AdminMonitorApplication">
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/zz-resource/db-scripts" />
</key>
</component>
<component name="RunManager" selected="Spring Boot.UpmsApplication">
<configuration name="AdminMonitorApplication" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot"> <configuration name="AdminMonitorApplication" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot">
<module name="admin-monitor" /> <module name="admin-monitor" />
<option name="SPRING_BOOT_MAIN_CLASS" value="com.orange.demo.adminmonitor.AdminMonitorApplication" /> <option name="SPRING_BOOT_MAIN_CLASS" value="com.orange.demo.adminmonitor.AdminMonitorApplication" />
@@ -83,22 +78,16 @@
</component> </component>
<component name="TaskManager"> <component name="TaskManager">
<task active="true" id="Default" summary="Default task"> <task active="true" id="Default" summary="Default task">
<changelist id="03a5281b-25b1-47eb-9d2b-a05e68843595" name="Default Changelist" comment="" /> <changelist id="7fe4264b-f60a-410c-b293-4e63b182af6c" name="Default Changelist" comment="" />
<created>1617113852056</created> <created>1619939388590</created>
<option name="number" value="Default" /> <option name="number" value="Default" />
<option name="presentableId" value="Default" /> <option name="presentableId" value="Default" />
<updated>1617113852056</updated> <updated>1619939388590</updated>
<workItem from="1617113855390" duration="234000" /> <workItem from="1619939390201" duration="314000" />
</task> </task>
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
<option name="version" value="1" /> <option name="version" value="1" />
</component> </component>
<component name="WindowStateProjectService">
<state x="383" y="212" width="674" height="476" key="find.popup" timestamp="1617114016095">
<screen x="0" y="0" width="1440" height="900" />
</state>
<state x="383" y="212" width="674" height="476" key="find.popup/0.0.1440.900@0.0.1440.900" timestamp="1617114016095" />
</component>
</project> </project>

View File

@@ -120,7 +120,8 @@ public class StudentDto {
/** /**
* 注册时间。 * 注册时间。
*/ */
@ApiModelProperty(value = "注册时间") @ApiModelProperty(value = "注册时间", required = true)
@NotNull(message = "数据验证失败,注册时间不能为空!")
private Date registerTime; private Date registerTime;
/** /**

View File

@@ -16,12 +16,79 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/target/generated-sources/annotations" isTestSource="false" generated="true" />
<excludeFolder url="file://$MODULE_DIR$/target" /> <excludeFolder url="file://$MODULE_DIR$/target" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="course-class-api" /> <orderEntry type="module" module-name="course-class-api" />
<orderEntry type="module" module-name="application-common" /> <orderEntry type="module" module-name="application-common" />
<orderEntry type="module" module-name="common-core" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.10.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.18.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:28.2-android" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-compat-qual:2.5.5" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.3.4" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.9" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.13" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.3.3" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.10.5" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.8" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.4.5" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.74" level="project" />
<orderEntry type="library" name="Maven: com.github.ben-manes.caffeine:caffeine:2.8.1" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.1.0" level="project" />
<orderEntry type="library" name="Maven: cn.jimmyshi:bean-query:1.1.5" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-all:1.3" level="project" />
<orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.3" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:2.6.0" level="project" />
<orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.04" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:8.0.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.1.22" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid:1.1.22" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-starter:2.1.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.6" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.2" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-core:1.1.5" level="project" />
<orderEntry type="library" name="Maven: javax.persistence:persistence-api:1.0" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-base:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-weekend:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-extra:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-autoconfigure:2.1.5" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.3.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.1.3" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.3.0" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.2.0" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:3.2" level="project" />
<orderEntry type="module" module-name="common-swagger" /> <orderEntry type="module" module-name="common-swagger" />
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-micro-spring-boot-starter:2.0.5" level="project" /> <orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-micro-spring-boot-starter:2.0.5" level="project" />
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-spring-boot-autoconfigure:2.0.5" level="project" /> <orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-spring-boot-autoconfigure:2.0.5" level="project" />
@@ -39,80 +106,14 @@
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:2.9.2" level="project" /> <orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:2.9.2" level="project" />
<orderEntry type="module" module-name="common-core" /> <orderEntry type="library" name="Maven: com.orange.demo:common-log:1.0.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.kafka:spring-kafka:2.3.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.retry:spring-retry:1.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.10.2" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-context:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.10.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.18.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.2.4.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:28.2-android" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-messaging:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-compat-qual:2.5.5" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.3.4" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.9" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.13" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.3.3" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.10.5" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.8" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.4.5" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.74" level="project" />
<orderEntry type="library" name="Maven: com.github.ben-manes.caffeine:caffeine:2.8.1" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.1.0" level="project" />
<orderEntry type="library" name="Maven: cn.jimmyshi:bean-query:1.1.5" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-all:1.3" level="project" />
<orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.3" level="project" />
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:2.6.0" level="project" />
<orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.04" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:8.0.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.1.22" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid:1.1.22" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-starter:2.1.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.2.4.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-tx:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.6" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.2" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-core:1.1.5" level="project" />
<orderEntry type="library" name="Maven: javax.persistence:persistence-api:1.0" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-base:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-weekend:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-extra:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-autoconfigure:2.1.5" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.3.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.1.3" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.3.0" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.2.0" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:3.2" level="project" />
<orderEntry type="module" module-name="common-redis" /> <orderEntry type="module" module-name="common-redis" />
<orderEntry type="library" name="Maven: redis.clients:jedis:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.7.0" level="project" />
<orderEntry type="library" name="Maven: org.redisson:redisson:3.12.3" level="project" /> <orderEntry type="library" name="Maven: org.redisson:redisson:3.12.3" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.45.Final" level="project" /> <orderEntry type="library" name="Maven: io.netty:netty-common:4.1.45.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.45.Final" level="project" /> <orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.45.Final" level="project" />
@@ -130,6 +131,7 @@
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.25" level="project" /> <orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.25" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.10.2" level="project" /> <orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.2" level="project" /> <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.10.2" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.8" level="project" /> <orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.8" level="project" />
<orderEntry type="library" name="Maven: org.jodd:jodd-bean:5.0.13" level="project" /> <orderEntry type="library" name="Maven: org.jodd:jodd-bean:5.0.13" level="project" />
<orderEntry type="library" name="Maven: org.jodd:jodd-core:5.0.13" level="project" /> <orderEntry type="library" name="Maven: org.jodd:jodd-core:5.0.13" level="project" />
@@ -153,6 +155,7 @@
<orderEntry type="library" name="Maven: com.netflix.ribbon:ribbon-core:2.3.0" level="project" /> <orderEntry type="library" name="Maven: com.netflix.ribbon:ribbon-core:2.3.0" level="project" />
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" /> <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
<orderEntry type="library" name="Maven: com.netflix.ribbon:ribbon-httpclient:2.3.0" level="project" /> <orderEntry type="library" name="Maven: com.netflix.ribbon:ribbon-httpclient:2.3.0" level="project" />
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.jersey:jersey-client:1.19.1" level="project" /> <orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.jersey:jersey-client:1.19.1" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.jersey:jersey-core:1.19.1" level="project" /> <orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.jersey:jersey-core:1.19.1" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: javax.ws.rs:jsr311-api:1.1.1" level="project" /> <orderEntry type="library" scope="RUNTIME" name="Maven: javax.ws.rs:jsr311-api:1.1.1" level="project" />
@@ -188,11 +191,11 @@
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-freemarker:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-freemarker:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" /> <orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.freemarker:freemarker:2.3.29" level="project" /> <orderEntry type="library" name="Maven: org.freemarker:freemarker:2.3.29" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.2.4.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.2.4.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" /> <orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-log4j2:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-log4j2:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-slf4j-impl:2.12.1" level="project" /> <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-slf4j-impl:2.12.1" level="project" />

View File

@@ -22,7 +22,7 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.orange.demo</groupId> <groupId>com.orange.demo</groupId>
<artifactId>common-core</artifactId> <artifactId>common-log</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
</dependency> </dependency>
<dependency> <dependency>

View File

@@ -31,8 +31,8 @@
<sql id="inputFilterRef"> <sql id="inputFilterRef">
<if test="courseFilter != null"> <if test="courseFilter != null">
<if test="courseFilter.courseName != null and courseFilter.courseName != ''"> <if test="courseFilter.courseName != null and courseFilter.courseName != ''">
<bind name = "safeCourseName" value = "'%' + courseFilter.courseName + '%'" /> <bind name = "safeCourseCourseName" value = "'%' + courseFilter.courseName + '%'" />
AND zz_course.course_name LIKE #{safeCourseName} AND zz_course.course_name LIKE #{safeCourseCourseName}
</if> </if>
<if test="courseFilter.priceStart != null"> <if test="courseFilter.priceStart != null">
AND zz_course.price &gt;= #{courseFilter.priceStart} AND zz_course.price &gt;= #{courseFilter.priceStart}

View File

@@ -18,8 +18,8 @@
<sql id="inputFilterRef"> <sql id="inputFilterRef">
<if test="schoolInfoFilter != null"> <if test="schoolInfoFilter != null">
<if test="schoolInfoFilter.schoolName != null and schoolInfoFilter.schoolName != ''"> <if test="schoolInfoFilter.schoolName != null and schoolInfoFilter.schoolName != ''">
<bind name = "safeSchoolName" value = "'%' + schoolInfoFilter.schoolName + '%'" /> <bind name = "safeSchoolInfoSchoolName" value = "'%' + schoolInfoFilter.schoolName + '%'" />
AND zz_school_info.school_name LIKE #{safeSchoolName} AND zz_school_info.school_name LIKE #{safeSchoolInfoSchoolName}
</if> </if>
<if test="schoolInfoFilter.provinceId != null"> <if test="schoolInfoFilter.provinceId != null">
AND zz_school_info.province_id = #{schoolInfoFilter.provinceId} AND zz_school_info.province_id = #{schoolInfoFilter.provinceId}

View File

@@ -59,8 +59,8 @@
AND zz_student.status = #{studentFilter.status} AND zz_student.status = #{studentFilter.status}
</if> </if>
<if test="studentFilter.searchString != null and studentFilter.searchString != ''"> <if test="studentFilter.searchString != null and studentFilter.searchString != ''">
<bind name = "safeSearchString" value = "'%' + studentFilter.searchString + '%'" /> <bind name = "safeStudentSearchString" value = "'%' + studentFilter.searchString + '%'" />
AND CONCAT(IFNULL(zz_student.login_mobile,''), IFNULL(zz_student.student_name,'')) LIKE #{safeSearchString} AND CONCAT(IFNULL(zz_student.login_mobile,''), IFNULL(zz_student.student_name,'')) LIKE #{safeStudentSearchString}
</if> </if>
</if> </if>
</sql> </sql>

View File

@@ -72,8 +72,6 @@
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-core:1.7.1" level="project" /> <orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-core:1.7.1" level="project" />
<orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-reactor-adapter:1.7.1" level="project" /> <orderEntry type="library" name="Maven: com.alibaba.csp:sentinel-reactor-adapter:1.7.1" level="project" />
<orderEntry type="module" module-name="common-redis" /> <orderEntry type="module" module-name="common-redis" />
<orderEntry type="library" name="Maven: redis.clients:jedis:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.7.0" level="project" />
<orderEntry type="library" name="Maven: org.redisson:redisson:3.12.3" level="project" /> <orderEntry type="library" name="Maven: org.redisson:redisson:3.12.3" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.45.Final" level="project" /> <orderEntry type="library" name="Maven: io.netty:netty-common:4.1.45.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.45.Final" level="project" /> <orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.45.Final" level="project" />

View File

@@ -4,7 +4,6 @@ import com.orange.demo.common.core.util.ApplicationContextHolder;
import com.orange.demo.gateway.filter.AuthenticationPostFilter; import com.orange.demo.gateway.filter.AuthenticationPostFilter;
import com.orange.demo.gateway.filter.AuthenticationPreFilter; import com.orange.demo.gateway.filter.AuthenticationPreFilter;
import com.orange.demo.gateway.filter.RequestLogFilter; import com.orange.demo.gateway.filter.RequestLogFilter;
import com.orange.demo.gateway.filter.ResponseLogFilter;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@@ -48,11 +47,6 @@ public class GatewayApplication {
return new RequestLogFilter(); return new RequestLogFilter();
} }
@Bean
public ResponseLogFilter responseLogPostFilter() {
return new ResponseLogFilter();
}
@Bean @Bean
ApplicationContextHolder applicationContextHolder() { ApplicationContextHolder applicationContextHolder() {
return new ApplicationContextHolder(); return new ApplicationContextHolder();

View File

@@ -40,15 +40,10 @@ public class ApplicationConfig {
*/ */
private String credentialIpList; private String credentialIpList;
/** /**
* Session在Redis中的过期时间(秒)。 * Session会话和用户权限在Redis中的过期时间(秒)。
* 缺省值是 one day + 60s
*/
private int sessionIdRedisExpiredSeconds = 86460;
/**
* Session的用户权限在Redis中的过期时间(秒)。
* 缺省值是 one day * 缺省值是 one day
*/ */
private int permRedisExpiredSeconds = 86400; private int sessionExpiredSeconds = 86400;
/** /**
* 基于完全等于(equals)判定规则的白名单地址集合过滤效率高于whitelistUrlPattern。 * 基于完全等于(equals)判定规则的白名单地址集合过滤效率高于whitelistUrlPattern。
*/ */

View File

@@ -3,6 +3,7 @@ package com.orange.demo.gateway.filter;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.orange.demo.common.core.constant.ErrorCodeEnum; import com.orange.demo.common.core.constant.ErrorCodeEnum;
import com.orange.demo.common.core.object.ResponseResult; import com.orange.demo.common.core.object.ResponseResult;
import com.orange.demo.common.core.object.TokenData; import com.orange.demo.common.core.object.TokenData;
@@ -14,6 +15,9 @@ import com.orange.demo.gateway.constant.GatewayConstant;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.reactivestreams.Publisher; import org.reactivestreams.Publisher;
import org.redisson.api.RBucket;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.cloud.gateway.filter.GlobalFilter;
@@ -30,16 +34,13 @@ import org.springframework.lang.NonNull;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Transaction;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/** /**
* 全局后处理过滤器。主要用于将用户的会话信息存到缓存服务器,以及在登出时清除缓存中的会话数据。 * 全局后处理过滤器。主要用于将用户的会话信息存到缓存服务器,以及在登出时清除缓存中的会话数据。
@@ -53,7 +54,7 @@ public class AuthenticationPostFilter implements GlobalFilter, Ordered {
@Autowired @Autowired
private ApplicationConfig appConfig; private ApplicationConfig appConfig;
@Autowired @Autowired
private JedisPool jedisPool; private RedissonClient redissonClient;
@Override @Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
@@ -134,20 +135,19 @@ public class AuthenticationPostFilter implements GlobalFilter, Ordered {
} }
private String readResponseBody(List<? extends DataBuffer> dataBuffers) { private String readResponseBody(List<? extends DataBuffer> dataBuffers) {
List<String> list = new LinkedList<>();
int dataCount = 0; int dataCount = 0;
for (DataBuffer dataBuffer : dataBuffers) { for (DataBuffer dataBuffer : dataBuffers) {
dataCount += dataBuffer.readableByteCount(); dataCount += dataBuffer.readableByteCount();
byte[] content = new byte[dataBuffer.readableByteCount()]; }
dataBuffer.read(content); byte[] allBytes = new byte[dataCount];
int offset = 0;
for (DataBuffer dataBuffer : dataBuffers) {
int length = dataBuffer.readableByteCount();
dataBuffer.read(allBytes, offset, length);
DataBufferUtils.release(dataBuffer); DataBufferUtils.release(dataBuffer);
list.add(new String(content, StandardCharsets.UTF_8)); offset += length;
} }
StringBuilder responseBuilder = new StringBuilder(dataCount + 1); return new String(allBytes, StandardCharsets.UTF_8);
for (String data : list) {
responseBuilder.append(data);
}
return responseBuilder.toString();
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -162,14 +162,9 @@ public class AuthenticationPostFilter implements GlobalFilter, Ordered {
if (originalRequest.getURI().getPath().equals(GatewayConstant.ADMIN_LOGOUT_URL)) { if (originalRequest.getURI().getPath().equals(GatewayConstant.ADMIN_LOGOUT_URL)) {
ResponseResult<Void> result = JSON.parseObject(responseBody, ResponseResult.class); ResponseResult<Void> result = JSON.parseObject(responseBody, ResponseResult.class);
if (result.isSuccess()) { if (result.isSuccess()) {
String sessionId = String sessionId = (String) exchange.getAttributes().get(GatewayConstant.SESSION_ID_KEY_NAME);
(String) exchange.getAttributes().get(GatewayConstant.SESSION_ID_KEY_NAME); redissonClient.getBucket(RedisKeyUtil.makeSessionIdKeyForRedis(sessionId)).deleteAsync();
try (Jedis jedis = jedisPool.getResource()) { redissonClient.getSet(RedisKeyUtil.makeSessionPermIdKeyForRedis(sessionId)).deleteAsync();
Pipeline pipeline = jedis.pipelined();
pipeline.del(RedisKeyUtil.makeSessionIdKeyForRedis(sessionId));
pipeline.del(RedisKeyUtil.makeSessionPermIdKeyForRedis(sessionId));
pipeline.sync();
}
} }
return responseBody; return responseBody;
} }
@@ -201,6 +196,10 @@ public class AuthenticationPostFilter implements GlobalFilter, Ordered {
if (StringUtils.isBlank(showName)) { if (StringUtils.isBlank(showName)) {
return ResponseResult.error(errorCode, "内部错误,用户显示名没有正确返回!"); return ResponseResult.error(errorCode, "内部错误,用户显示名没有正确返回!");
} }
String loginName = tokenData.getString("loginName");
if (StringUtils.isBlank(showName)) {
return ResponseResult.error(errorCode, "内部错误,用户登录名没有正确返回!");
}
String sessionId = tokenData.getString("sessionId"); String sessionId = tokenData.getString("sessionId");
if (StringUtils.isBlank(sessionId)) { if (StringUtils.isBlank(sessionId)) {
return ResponseResult.error(errorCode, "内部错误SESSION_ID没有正确返回"); return ResponseResult.error(errorCode, "内部错误SESSION_ID没有正确返回");
@@ -209,26 +208,19 @@ public class AuthenticationPostFilter implements GlobalFilter, Ordered {
Map<String, Object> claims = new HashMap<>(1); Map<String, Object> claims = new HashMap<>(1);
claims.put(GatewayConstant.SESSION_ID_KEY_NAME, sessionId); claims.put(GatewayConstant.SESSION_ID_KEY_NAME, sessionId);
String token = JwtUtil.generateToken(claims, appConfig.getExpiration(), appConfig.getTokenSigningKey()); String token = JwtUtil.generateToken(claims, appConfig.getExpiration(), appConfig.getTokenSigningKey());
try (Jedis jedis = jedisPool.getResource()) { // 3. 更新缓存
// 3. 更新缓存 String sessionIdKey = RedisKeyUtil.makeSessionIdKeyForRedis(sessionId);
// 3.1 sessionId -> userId 是hash结构的缓存 String sessionData = JSON.toJSONString(tokenData, SerializerFeature.WriteNonStringValueAsString);
String sessionIdKey = RedisKeyUtil.makeSessionIdKeyForRedis(sessionId); RBucket<String> bucket = redissonClient.getBucket(sessionIdKey);
Transaction t = jedis.multi(); bucket.set(sessionData);
for (String tokenKey : tokenData.keySet()) { bucket.expire(appConfig.getSessionExpiredSeconds(), TimeUnit.SECONDS);
t.hset(sessionIdKey, tokenKey, tokenData.getString(tokenKey)); // 3.2 sessionId -> permList 是set结构的缓存
} JSONArray permSet = loginData.getJSONArray("permSet");
t.expire(sessionIdKey, appConfig.getSessionIdRedisExpiredSeconds()); if (permSet != null) {
// 3.2 sessionId -> permList 是set结构的缓存 String sessionPermKey = RedisKeyUtil.makeSessionPermIdKeyForRedis(sessionId);
JSONArray permSet = loginData.getJSONArray("permSet"); RSet<String> redisPermSet = redissonClient.getSet(sessionPermKey);
if (permSet != null) { redisPermSet.addAll(permSet.stream().map(Object::toString).collect(Collectors.toSet()));
String sessionPermKey = RedisKeyUtil.makeSessionPermIdKeyForRedis(sessionId); redisPermSet.expire(appConfig.getSessionExpiredSeconds(), TimeUnit.SECONDS);
for (int i = 0; i < permSet.size(); ++i) {
String perm = permSet.getString(i);
t.sadd(sessionPermKey, perm);
}
t.expire(sessionPermKey, appConfig.getPermRedisExpiredSeconds());
}
t.exec();
} }
// 4. 构造返回给用户的应答,将加密后的令牌返回给前端。 // 4. 构造返回给用户的应答,将加密后的令牌返回给前端。
loginData.put(TokenData.REQUEST_ATTRIBUTE_NAME, token); loginData.put(TokenData.REQUEST_ATTRIBUTE_NAME, token);

View File

@@ -14,6 +14,8 @@ import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.cloud.gateway.filter.GlobalFilter;
@@ -26,13 +28,10 @@ import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Map;
/** /**
* 全局前处理过滤器。主要用于用户操作权限验证。 * 全局前处理过滤器。主要用于用户操作权限验证。
@@ -46,7 +45,7 @@ public class AuthenticationPreFilter implements GlobalFilter, Ordered {
@Autowired @Autowired
private ApplicationConfig appConfig; private ApplicationConfig appConfig;
@Autowired @Autowired
private JedisPool jedisPool; private RedissonClient redissonClient;
/** /**
* Ant Pattern模式的白名单地址匹配器。 * Ant Pattern模式的白名单地址匹配器。
*/ */
@@ -76,61 +75,58 @@ public class AuthenticationPreFilter implements GlobalFilter, Ordered {
exchange.getAttributes().put(appConfig.getRefreshedTokenHeaderKey(), exchange.getAttributes().put(appConfig.getRefreshedTokenHeaderKey(),
JwtUtil.generateToken(c, appConfig.getExpiration(), appConfig.getTokenSigningKey())); JwtUtil.generateToken(c, appConfig.getExpiration(), appConfig.getTokenSigningKey()));
} }
try (Jedis jedis = jedisPool.getResource()) { // 先基于sessionId获取userInfo
// 先基于sessionId获取userInfo String sessionId = (String) c.get(GatewayConstant.SESSION_ID_KEY_NAME);
String sessionId = (String) c.get(GatewayConstant.SESSION_ID_KEY_NAME); String sessionIdKey = RedisKeyUtil.makeSessionIdKeyForRedis(sessionId);
Map<String, String> userMap = jedis.hgetAll(RedisKeyUtil.makeSessionIdKeyForRedis(sessionId)); RBucket<String> sessionData = redissonClient.getBucket(sessionIdKey);
if (userMap == null) { JSONObject tokenData = null;
log.warn("UNAUTHORIZED request [{}] from REMOTE-IP [{}] because no sessionId exists in redis.", if (sessionData.isExists()) {
url, IpUtil.getRemoteIpAddress(request)); tokenData = JSON.parseObject(sessionData.get());
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
byte[] responseBody = JSON.toJSONString(ResponseResult.error(ErrorCodeEnum.UNAUTHORIZED_LOGIN,
"用户会话已失效,请重新登录!")).getBytes(StandardCharsets.UTF_8);
return response.writeWith(Flux.just(response.bufferFactory().wrap(responseBody)));
}
String userId = userMap.get("userId");
if (StringUtils.isBlank(userId)) {
log.warn("UNAUTHORIZED request [{}] from REMOTE-IP [{}] because userId is empty in redis.",
url, IpUtil.getRemoteIpAddress(request));
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
byte[] responseBody = JSON.toJSONString(ResponseResult.error(ErrorCodeEnum.UNAUTHORIZED_LOGIN,
"用户登录验证信息已过期,请重新登录!")).getBytes(StandardCharsets.UTF_8);
return response.writeWith(Flux.just(response.bufferFactory().wrap(responseBody)));
}
boolean isAdmin = false;
String isAdminString = userMap.get("isAdmin");
if (Boolean.parseBoolean(isAdminString)) {
isAdmin = true;
}
String showName = userMap.get("showName");
// 因为http header中不支持中文传输所以需要编码。
try {
showName = URLEncoder.encode(showName, StandardCharsets.UTF_8.name());
userMap.put("showName", showName);
} catch (UnsupportedEncodingException e) {
log.error("Failed to call AuthenticationPreFilter.filter.", e);
}
if (Boolean.FALSE.equals(isAdmin) && !this.hasPermission(jedis, sessionId, url)) {
log.warn("FORBIDDEN request [{}] from REMOTE-IP [{}] for USER [{} -- {}] no perm!",
url, IpUtil.getRemoteIpAddress(request), userId, showName);
response.setStatusCode(HttpStatus.FORBIDDEN);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
byte[] responseBody = JSON.toJSONString(ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION,
"用户对该URL没有访问权限请核对")).getBytes(StandardCharsets.UTF_8);
return response.writeWith(Flux.just(response.bufferFactory().wrap(responseBody)));
}
// 将session中关联的用户信息添加到当前的Request中。转发后业务服务可以根据需要自定读取。
JSONObject tokenData = new JSONObject();
tokenData.putAll(userMap);
tokenData.put("sessionId", sessionId);
exchange.getAttributes().put(GatewayConstant.SESSION_ID_KEY_NAME, sessionId);
ServerHttpRequest mutableReq = exchange.getRequest().mutate().header(
TokenData.REQUEST_ATTRIBUTE_NAME, tokenData.toJSONString()).build();
ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build();
return chain.filter(mutableExchange);
} }
if (tokenData == null) {
log.warn("UNAUTHORIZED request [{}] from REMOTE-IP [{}] because no sessionId exists in redis.",
url, IpUtil.getRemoteIpAddress(request));
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
byte[] responseBody = JSON.toJSONString(ResponseResult.error(ErrorCodeEnum.UNAUTHORIZED_LOGIN,
"用户会话已失效,请重新登录!")).getBytes(StandardCharsets.UTF_8);
return response.writeWith(Flux.just(response.bufferFactory().wrap(responseBody)));
}
String userId = tokenData.getString("userId");
if (StringUtils.isBlank(userId)) {
log.warn("UNAUTHORIZED request [{}] from REMOTE-IP [{}] because userId is empty in redis.",
url, IpUtil.getRemoteIpAddress(request));
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
byte[] responseBody = JSON.toJSONString(ResponseResult.error(ErrorCodeEnum.UNAUTHORIZED_LOGIN,
"用户登录验证信息已过期,请重新登录!")).getBytes(StandardCharsets.UTF_8);
return response.writeWith(Flux.just(response.bufferFactory().wrap(responseBody)));
}
String showName = tokenData.getString("showName");
// 因为http header中不支持中文传输所以需要编码。
try {
showName = URLEncoder.encode(showName, StandardCharsets.UTF_8.name());
tokenData.put("showName", showName);
} catch (UnsupportedEncodingException e) {
log.error("Failed to call AuthenticationPreFilter.filter.", e);
}
boolean isAdmin = tokenData.getBoolean("isAdmin");
if (Boolean.FALSE.equals(isAdmin) && !this.hasPermission(redissonClient, sessionId, url)) {
log.warn("FORBIDDEN request [{}] from REMOTE-IP [{}] for USER [{} -- {}] no perm!",
url, IpUtil.getRemoteIpAddress(request), userId, showName);
response.setStatusCode(HttpStatus.FORBIDDEN);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
byte[] responseBody = JSON.toJSONString(ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION,
"用户对该URL没有访问权限请核对")).getBytes(StandardCharsets.UTF_8);
return response.writeWith(Flux.just(response.bufferFactory().wrap(responseBody)));
}
// 将session中关联的用户信息添加到当前的Request中。转发后业务服务可以根据需要自定读取。
tokenData.put("sessionId", sessionId);
exchange.getAttributes().put(GatewayConstant.SESSION_ID_KEY_NAME, sessionId);
ServerHttpRequest mutableReq = exchange.getRequest().mutate().header(
TokenData.REQUEST_ATTRIBUTE_NAME, tokenData.toJSONString()).build();
ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build();
return chain.filter(mutableExchange);
} }
/** /**
@@ -151,10 +147,13 @@ public class AuthenticationPreFilter implements GlobalFilter, Ordered {
return token; return token;
} }
private boolean hasPermission(Jedis jedis, String sessionId, String url) { private boolean hasPermission(RedissonClient redissonClient, String sessionId, String url) {
// 对于退出登录操作,不需要进行权限验证,仅仅确认是已经登录的合法用户即可。 // 对于退出登录操作,不需要进行权限验证,仅仅确认是已经登录的合法用户即可。
return url.equals(GatewayConstant.ADMIN_LOGOUT_URL) if (url.equals(GatewayConstant.ADMIN_LOGOUT_URL)) {
|| Boolean.TRUE.equals(jedis.sismember(RedisKeyUtil.makeSessionPermIdKeyForRedis(sessionId), url)); return true;
}
String permKey = RedisKeyUtil.makeSessionPermIdKeyForRedis(sessionId);
return redissonClient.getSet(permKey).contains(url);
} }
/** /**

View File

@@ -9,6 +9,7 @@ import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@@ -24,16 +25,27 @@ public class RequestLogFilter implements GlobalFilter, Ordered {
@Override @Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String traceId = MyCommonUtil.generateUuid(); log.info("开始请求app={gateway}, url={}", exchange.getRequest().getURI().getPath());
final String traceId = MyCommonUtil.generateUuid();
// 分别记录traceId和执行开始时间。 // 分别记录traceId和执行开始时间。
exchange.getAttributes().put(ApplicationConstant.HTTP_HEADER_TRACE_ID, traceId);
exchange.getAttributes().put(GatewayConstant.START_TIME_ATTRIBUTE, System.currentTimeMillis()); exchange.getAttributes().put(GatewayConstant.START_TIME_ATTRIBUTE, System.currentTimeMillis());
ServerHttpRequest mutableReq = exchange.getRequest().mutate().header( ServerHttpRequest mutableReq = exchange.getRequest().mutate().header(
ApplicationConstant.HTTP_HEADER_TRACE_ID, traceId).build(); ApplicationConstant.HTTP_HEADER_TRACE_ID, traceId).build();
ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build(); ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build();
MDC.put(ApplicationConstant.HTTP_HEADER_TRACE_ID, traceId); ServerHttpResponse response = mutableExchange.getResponse();
log.info("开始请求app={gateway}, url={}", exchange.getRequest().getURI().getPath()); response.beforeCommit(() -> {
return chain.filter(mutableExchange); response.getHeaders().set(ApplicationConstant.HTTP_HEADER_TRACE_ID, traceId);
return Mono.empty();
});
return chain.filter(mutableExchange).then(Mono.fromRunnable(() -> {
Long startTime = exchange.getAttribute(GatewayConstant.START_TIME_ATTRIBUTE);
MDC.put(ApplicationConstant.HTTP_HEADER_TRACE_ID, traceId);
long elapse = 0;
if (startTime != null) {
elapse = System.currentTimeMillis() - startTime;
}
log.info("请求完成, app={gateway}, url={}elapse={}", exchange.getRequest().getURI().getPath(), elapse);
}));
} }
/** /**

View File

@@ -1,51 +0,0 @@
package com.orange.demo.gateway.filter;
import com.orange.demo.common.core.constant.ApplicationConstant;
import com.orange.demo.gateway.constant.GatewayConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* 链路日志后置过虑器。
* 将整个链路的traceId存储在Response Head中并返回给前端便于问题定位。
*
* @author Jerry
* @date 2020-08-08
*/
@Slf4j
public class ResponseLogFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 下面两个属性都是在RequestLogFilter过滤器中设置的。
String traceId = exchange.getAttribute(ApplicationConstant.HTTP_HEADER_TRACE_ID);
Long startTime = exchange.getAttribute(GatewayConstant.START_TIME_ATTRIBUTE);
if (StringUtils.isNotBlank(traceId)) {
MDC.put(ApplicationConstant.HTTP_HEADER_TRACE_ID, traceId);
exchange.getResponse().getHeaders().add(ApplicationConstant.HTTP_HEADER_TRACE_ID, traceId);
}
long elapse = 0;
if (startTime != null) {
elapse = System.currentTimeMillis() - startTime;
}
log.info("请求完成, app={gateway}, url={}elapse={}", exchange.getRequest().getURI().getPath(), elapse);
return chain.filter(exchange);
}
/**
* 返回过滤器在在调用链上的优先级。
*
* @return 数值越低,优先级越高。
*/
@Override
public int getOrder() {
// -1 is response write filter, must be called before that
return -10;
}
}

View File

@@ -27,7 +27,7 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.orange.demo</groupId> <groupId>com.orange.demo</groupId>
<artifactId>common-core</artifactId> <artifactId>common-log</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
</dependency> </dependency>
<dependency> <dependency>

View File

@@ -16,12 +16,79 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/target/generated-sources/annotations" isTestSource="false" generated="true" />
<excludeFolder url="file://$MODULE_DIR$/target" /> <excludeFolder url="file://$MODULE_DIR$/target" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="stats-api" /> <orderEntry type="module" module-name="stats-api" />
<orderEntry type="module" module-name="application-common" /> <orderEntry type="module" module-name="application-common" />
<orderEntry type="module" module-name="common-core" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.10.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.18.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:28.2-android" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-compat-qual:2.5.5" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.3.4" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.9" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.13" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.3.3" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.10.5" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.8" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.4.5" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.74" level="project" />
<orderEntry type="library" name="Maven: com.github.ben-manes.caffeine:caffeine:2.8.1" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.1.0" level="project" />
<orderEntry type="library" name="Maven: cn.jimmyshi:bean-query:1.1.5" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-all:1.3" level="project" />
<orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.3" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:2.6.0" level="project" />
<orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.04" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:8.0.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.1.22" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid:1.1.22" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-starter:2.1.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.6" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.2" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-core:1.1.5" level="project" />
<orderEntry type="library" name="Maven: javax.persistence:persistence-api:1.0" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-base:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-weekend:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-extra:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-autoconfigure:2.1.5" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.3.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.1.3" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.3.0" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.2.0" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:3.2" level="project" />
<orderEntry type="module" module-name="common-swagger" /> <orderEntry type="module" module-name="common-swagger" />
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-micro-spring-boot-starter:2.0.5" level="project" /> <orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-micro-spring-boot-starter:2.0.5" level="project" />
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-spring-boot-autoconfigure:2.0.5" level="project" /> <orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-spring-boot-autoconfigure:2.0.5" level="project" />
@@ -40,80 +107,14 @@
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:2.9.2" level="project" /> <orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:2.9.2" level="project" />
<orderEntry type="module" module-name="course-class-api" /> <orderEntry type="module" module-name="course-class-api" />
<orderEntry type="module" module-name="common-core" /> <orderEntry type="library" name="Maven: com.orange.demo:common-log:1.0.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.kafka:spring-kafka:2.3.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.retry:spring-retry:1.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.10.2" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-context:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.10.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.18.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.2.4.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:28.2-android" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-messaging:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-compat-qual:2.5.5" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.3.4" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.9" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.13" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.3.3" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.10.5" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.8" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.4.5" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.74" level="project" />
<orderEntry type="library" name="Maven: com.github.ben-manes.caffeine:caffeine:2.8.1" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.1.0" level="project" />
<orderEntry type="library" name="Maven: cn.jimmyshi:bean-query:1.1.5" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-all:1.3" level="project" />
<orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.3" level="project" />
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:2.6.0" level="project" />
<orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.04" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:8.0.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.1.22" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid:1.1.22" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-starter:2.1.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.2.4.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-tx:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.6" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.2" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-core:1.1.5" level="project" />
<orderEntry type="library" name="Maven: javax.persistence:persistence-api:1.0" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-base:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-weekend:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-extra:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-autoconfigure:2.1.5" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.3.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.1.3" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.3.0" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.2.0" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:3.2" level="project" />
<orderEntry type="module" module-name="common-redis" /> <orderEntry type="module" module-name="common-redis" />
<orderEntry type="library" name="Maven: redis.clients:jedis:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.7.0" level="project" />
<orderEntry type="library" name="Maven: org.redisson:redisson:3.12.3" level="project" /> <orderEntry type="library" name="Maven: org.redisson:redisson:3.12.3" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.45.Final" level="project" /> <orderEntry type="library" name="Maven: io.netty:netty-common:4.1.45.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.45.Final" level="project" /> <orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.45.Final" level="project" />
@@ -131,6 +132,7 @@
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.25" level="project" /> <orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.25" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.10.2" level="project" /> <orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.2" level="project" /> <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.10.2" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.8" level="project" /> <orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.8" level="project" />
<orderEntry type="library" name="Maven: org.jodd:jodd-bean:5.0.13" level="project" /> <orderEntry type="library" name="Maven: org.jodd:jodd-bean:5.0.13" level="project" />
<orderEntry type="library" name="Maven: org.jodd:jodd-core:5.0.13" level="project" /> <orderEntry type="library" name="Maven: org.jodd:jodd-core:5.0.13" level="project" />
@@ -154,6 +156,7 @@
<orderEntry type="library" name="Maven: com.netflix.ribbon:ribbon-core:2.3.0" level="project" /> <orderEntry type="library" name="Maven: com.netflix.ribbon:ribbon-core:2.3.0" level="project" />
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" /> <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
<orderEntry type="library" name="Maven: com.netflix.ribbon:ribbon-httpclient:2.3.0" level="project" /> <orderEntry type="library" name="Maven: com.netflix.ribbon:ribbon-httpclient:2.3.0" level="project" />
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.jersey:jersey-client:1.19.1" level="project" /> <orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.jersey:jersey-client:1.19.1" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.jersey:jersey-core:1.19.1" level="project" /> <orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.jersey:jersey-core:1.19.1" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: javax.ws.rs:jsr311-api:1.1.1" level="project" /> <orderEntry type="library" scope="RUNTIME" name="Maven: javax.ws.rs:jsr311-api:1.1.1" level="project" />
@@ -189,11 +192,11 @@
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-freemarker:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-freemarker:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" /> <orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.freemarker:freemarker:2.3.29" level="project" /> <orderEntry type="library" name="Maven: org.freemarker:freemarker:2.3.29" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.2.4.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.2.4.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" /> <orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-log4j2:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-log4j2:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-slf4j-impl:2.12.1" level="project" /> <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-slf4j-impl:2.12.1" level="project" />

View File

@@ -22,7 +22,7 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.orange.demo</groupId> <groupId>com.orange.demo</groupId>
<artifactId>common-core</artifactId> <artifactId>common-log</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
</dependency> </dependency>
<dependency> <dependency>

View File

@@ -9,8 +9,7 @@ import lombok.extern.slf4j.Slf4j;
import com.orange.demo.common.core.annotation.MyRequestBody; import com.orange.demo.common.core.annotation.MyRequestBody;
import com.orange.demo.common.core.constant.ErrorCodeEnum; import com.orange.demo.common.core.constant.ErrorCodeEnum;
import com.orange.demo.common.core.constant.ApplicationConstant; import com.orange.demo.common.core.constant.ApplicationConstant;
import com.orange.demo.common.core.object.ResponseResult; import com.orange.demo.common.core.object.*;
import com.orange.demo.common.core.object.TokenData;
import com.orange.demo.common.core.util.*; import com.orange.demo.common.core.util.*;
import com.orange.demo.common.redis.cache.SessionCacheHelper; import com.orange.demo.common.redis.cache.SessionCacheHelper;
import com.orange.demo.upmsapi.constant.SysUserStatus; import com.orange.demo.upmsapi.constant.SysUserStatus;
@@ -134,6 +133,7 @@ public class LoginController {
jsonData.put("permCodeList", permCodeList); jsonData.put("permCodeList", permCodeList);
return ResponseResult.success(jsonData); return ResponseResult.success(jsonData);
} }
/** /**
* 用户修改自己的密码。 * 用户修改自己的密码。
* *
@@ -167,11 +167,14 @@ public class LoginController {
private JSONObject buildLoginData(SysUser user) { private JSONObject buildLoginData(SysUser user) {
boolean isAdmin = user.getUserType() == SysUserType.TYPE_ADMIN; boolean isAdmin = user.getUserType() == SysUserType.TYPE_ADMIN;
TokenData tokenData = new TokenData(); TokenData tokenData = new TokenData();
String sessionId = MyCommonUtil.generateUuid(); String sessionId = user.getLoginName() + "_" + MyCommonUtil.generateUuid();
tokenData.setUserId(user.getUserId()); tokenData.setUserId(user.getUserId());
tokenData.setIsAdmin(isAdmin); tokenData.setIsAdmin(isAdmin);
tokenData.setLoginName(user.getLoginName());
tokenData.setShowName(user.getShowName()); tokenData.setShowName(user.getShowName());
tokenData.setSessionId(sessionId); tokenData.setSessionId(sessionId);
tokenData.setLoginIp(IpUtil.getRemoteIpAddress(ContextUtil.getHttpRequest()));
tokenData.setLoginTime(new Date());
// 这里手动将TokenData存入request便于OperationLogAspect统一处理操作日志。 // 这里手动将TokenData存入request便于OperationLogAspect统一处理操作日志。
TokenData.addToRequest(tokenData); TokenData.addToRequest(tokenData);
JSONObject jsonData = new JSONObject(); JSONObject jsonData = new JSONObject();

View File

@@ -0,0 +1,86 @@
package com.orange.demo.upmsservice.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.orange.demo.common.core.annotation.MyRequestBody;
import com.orange.demo.common.core.object.*;
import com.orange.demo.common.core.util.RedisKeyUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
* 在线用户控制器对象。
*
* @author Jerry
* @date 2020-08-08
*/
@Api(tags = "在线用户接口")
@Slf4j
@RestController
@RequestMapping("/loginUser")
public class LoginUserController {
@Autowired
private RedissonClient redissonClient;
/**
* 显示在线用户列表。
*
* @param loginName 登录名过滤。
* @param pageParam 分页参数。
* @return 登录用户信息列表。
*/
@PostMapping("/list")
public ResponseResult<MyPageData<LoginUserInfo>> list(
@MyRequestBody String loginName, @MyRequestBody MyPageParam pageParam) {
List<LoginUserInfo> loginUserInfoList = new LinkedList<>();
int queryCount = pageParam.getPageNum() * pageParam.getPageSize();
int skipCount = (pageParam.getPageNum() - 1) * pageParam.getPageSize();
String patternKey;
if (StrUtil.isBlank(loginName)) {
patternKey = RedisKeyUtil.getSessionIdPrefix() + "*";
} else {
patternKey = RedisKeyUtil.getSessionIdPrefix(loginName) + "*";
}
long totalCount = 0L;
int pos = 0;
Iterable<String> keys = redissonClient.getKeys().getKeysByPattern(patternKey);
for (String key : keys) {
totalCount++;
if (pos++ < skipCount) {
continue;
}
loginUserInfoList.add(this.buildTokenDataByRedisKey(key));
}
return ResponseResult.success(new MyPageData<>(loginUserInfoList, totalCount));
}
/**
* 强制下线指定登录会话。
*
* @param sessionId 待强制下线的SessionId。
* @return 应答结果对象。
*/
@PostMapping("/delete")
public ResponseResult<Void> delete(@MyRequestBody String sessionId) {
// 为了保证被剔除用户正在进行的操作不被干扰这里只是删除sessionIdKey即可这样可以使强制下线操作更加平滑。
// 比如如果删除操作权限或数据权限的redis session key那么正在请求数据的操作就会报错。
redissonClient.getBucket(RedisKeyUtil.makeSessionIdKeyForRedis(sessionId)).delete();
return ResponseResult.success();
}
private LoginUserInfo buildTokenDataByRedisKey(String key) {
RBucket<String> sessionData = redissonClient.getBucket(key);
TokenData tokenData = JSON.parseObject(sessionData.get(), TokenData.class);
return BeanUtil.copyProperties(tokenData, LoginUserInfo.class);
}
}

View File

@@ -27,12 +27,12 @@
<sql id="inputFilterRef"> <sql id="inputFilterRef">
<if test="sysUserFilter != null"> <if test="sysUserFilter != null">
<if test="sysUserFilter.loginName != null and sysUserFilter.loginName != ''"> <if test="sysUserFilter.loginName != null and sysUserFilter.loginName != ''">
<bind name = "safeLoginName" value = "'%' + sysUserFilter.loginName + '%'" /> <bind name = "safeSysUserLoginName" value = "'%' + sysUserFilter.loginName + '%'" />
AND zz_sys_user.login_name LIKE #{safeLoginName} AND zz_sys_user.login_name LIKE #{safeSysUserLoginName}
</if> </if>
<if test="sysUserFilter.showName != null and sysUserFilter.showName != ''"> <if test="sysUserFilter.showName != null and sysUserFilter.showName != ''">
<bind name = "safeShowName" value = "'%' + sysUserFilter.showName + '%'" /> <bind name = "safeSysUserShowName" value = "'%' + sysUserFilter.showName + '%'" />
AND zz_sys_user.show_name LIKE #{safeShowName} AND zz_sys_user.show_name LIKE #{safeSysUserShowName}
</if> </if>
<if test="sysUserFilter.userStatus != null"> <if test="sysUserFilter.userStatus != null">
AND zz_sys_user.user_status = #{sysUserFilter.userStatus} AND zz_sys_user.user_status = #{sysUserFilter.userStatus}

View File

@@ -75,5 +75,10 @@
<AppenderRef ref="kafka_log"/> <AppenderRef ref="kafka_log"/>
<AppenderRef ref="file_log"/> <AppenderRef ref="file_log"/>
</AsyncLogger> </AsyncLogger>
<AsyncLogger name="com.orange.demo.common.log.dao" additivity="false" level="debug">
<AppenderRef ref="console"/>
<AppenderRef ref="kafka_log"/>
<AppenderRef ref="file_log"/>
</AsyncLogger>
</Loggers> </Loggers>
</configuration> </configuration>

View File

@@ -16,11 +16,78 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/target/generated-sources/annotations" isTestSource="false" generated="true" />
<excludeFolder url="file://$MODULE_DIR$/target" /> <excludeFolder url="file://$MODULE_DIR$/target" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="upms-api" /> <orderEntry type="module" module-name="upms-api" />
<orderEntry type="module" module-name="common-core" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.10.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.18.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:28.2-android" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-compat-qual:2.5.5" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.3.4" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.9" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.13" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.3.3" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.10.5" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.8" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.4.5" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.74" level="project" />
<orderEntry type="library" name="Maven: com.github.ben-manes.caffeine:caffeine:2.8.1" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.1.0" level="project" />
<orderEntry type="library" name="Maven: cn.jimmyshi:bean-query:1.1.5" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-all:1.3" level="project" />
<orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.3" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:2.6.0" level="project" />
<orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.04" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:8.0.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.1.22" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid:1.1.22" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-starter:2.1.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.6" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.2" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-core:1.1.5" level="project" />
<orderEntry type="library" name="Maven: javax.persistence:persistence-api:1.0" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-base:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-weekend:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-extra:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-autoconfigure:2.1.5" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.3.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.1.3" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.3.0" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.2.0" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:3.2" level="project" />
<orderEntry type="module" module-name="application-common" /> <orderEntry type="module" module-name="application-common" />
<orderEntry type="module" module-name="common-swagger" /> <orderEntry type="module" module-name="common-swagger" />
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-micro-spring-boot-starter:2.0.5" level="project" /> <orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-micro-spring-boot-starter:2.0.5" level="project" />
@@ -39,80 +106,14 @@
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" />
<orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:2.9.2" level="project" /> <orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:2.9.2" level="project" />
<orderEntry type="module" module-name="common-core" /> <orderEntry type="library" name="Maven: com.orange.demo:common-log:1.0.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.kafka:spring-kafka:2.3.6.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.retry:spring-retry:1.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.10.2" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-context:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.10.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.31" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-validation:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: jakarta.validation:jakarta.validation-api:2.0.2" level="project" />
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.18.Final" level="project" />
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.4.1.Final" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.5.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.2.4.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:28.2-android" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-messaging:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:failureaccess:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-compat-qual:2.5.5" level="project" />
<orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.3.4" level="project" />
<orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.9" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.13" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.3.3" level="project" />
<orderEntry type="library" name="Maven: joda-time:joda-time:2.10.5" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.4" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.8" level="project" />
<orderEntry type="library" name="Maven: cn.hutool:hutool-all:5.4.5" level="project" />
<orderEntry type="library" name="Maven: io.jsonwebtoken:jjwt:0.9.1" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.74" level="project" />
<orderEntry type="library" name="Maven: com.github.ben-manes.caffeine:caffeine:2.8.1" level="project" />
<orderEntry type="library" name="Maven: org.checkerframework:checker-qual:3.1.0" level="project" />
<orderEntry type="library" name="Maven: cn.jimmyshi:bean-query:1.1.5" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-all:1.3" level="project" />
<orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.3" level="project" />
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:3.17" level="project" />
<orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:2.6.0" level="project" />
<orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
<orderEntry type="library" name="Maven: com.github.virtuald:curvesapi:1.04" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:8.0.19" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.1.22" level="project" />
<orderEntry type="library" name="Maven: com.alibaba:druid:1.1.22" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-starter:2.1.5" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.2" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.2.4.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-tx:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.6" level="project" />
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.2" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-core:1.1.5" level="project" />
<orderEntry type="library" name="Maven: javax.persistence:persistence-api:1.0" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-base:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-weekend:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-extra:1.1.5" level="project" />
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-autoconfigure:2.1.5" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.3.0" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3" level="project" />
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.1.3" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.3.0" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.2.0" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:3.2" level="project" />
<orderEntry type="module" module-name="common-redis" /> <orderEntry type="module" module-name="common-redis" />
<orderEntry type="library" name="Maven: redis.clients:jedis:3.1.0" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.7.0" level="project" />
<orderEntry type="library" name="Maven: org.redisson:redisson:3.12.3" level="project" /> <orderEntry type="library" name="Maven: org.redisson:redisson:3.12.3" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.45.Final" level="project" /> <orderEntry type="library" name="Maven: io.netty:netty-common:4.1.45.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.45.Final" level="project" /> <orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.45.Final" level="project" />
@@ -130,6 +131,7 @@
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.25" level="project" /> <orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.25" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.10.2" level="project" /> <orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.2" level="project" /> <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.10.2" level="project" />
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.8" level="project" /> <orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.10.8" level="project" />
<orderEntry type="library" name="Maven: org.jodd:jodd-bean:5.0.13" level="project" /> <orderEntry type="library" name="Maven: org.jodd:jodd-bean:5.0.13" level="project" />
<orderEntry type="library" name="Maven: org.jodd:jodd-core:5.0.13" level="project" /> <orderEntry type="library" name="Maven: org.jodd:jodd-core:5.0.13" level="project" />
@@ -153,6 +155,7 @@
<orderEntry type="library" name="Maven: com.netflix.ribbon:ribbon-core:2.3.0" level="project" /> <orderEntry type="library" name="Maven: com.netflix.ribbon:ribbon-core:2.3.0" level="project" />
<orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" /> <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
<orderEntry type="library" name="Maven: com.netflix.ribbon:ribbon-httpclient:2.3.0" level="project" /> <orderEntry type="library" name="Maven: com.netflix.ribbon:ribbon-httpclient:2.3.0" level="project" />
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.jersey:jersey-client:1.19.1" level="project" /> <orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.jersey:jersey-client:1.19.1" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.jersey:jersey-core:1.19.1" level="project" /> <orderEntry type="library" scope="RUNTIME" name="Maven: com.sun.jersey:jersey-core:1.19.1" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: javax.ws.rs:jsr311-api:1.1.1" level="project" /> <orderEntry type="library" scope="RUNTIME" name="Maven: javax.ws.rs:jsr311-api:1.1.1" level="project" />
@@ -188,11 +191,11 @@
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-freemarker:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-freemarker:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" /> <orderEntry type="library" name="Maven: jakarta.annotation:jakarta.annotation-api:1.3.5" level="project" />
<orderEntry type="library" name="Maven: org.freemarker:freemarker:2.3.29" level="project" /> <orderEntry type="library" name="Maven: org.freemarker:freemarker:2.3.29" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.2.4.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.2.4.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.2.4.RELEASE" level="project" />
<orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" /> <orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:4.0.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-log4j2:2.2.5.RELEASE" level="project" /> <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-log4j2:2.2.5.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-slf4j-impl:2.12.1" level="project" /> <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-slf4j-impl:2.12.1" level="project" />

View File

@@ -8,6 +8,22 @@ package com.orange.demo.common.core.constant;
*/ */
public final class ApplicationConstant { public final class ApplicationConstant {
/**
* 数据同步使用的缺省消息队列主题名称。
*/
public static final String DEFAULT_DATA_SYNC_TOPIC = "OrangeMultiDemo";
/**
* 全量数据同步中,新增数据对象的键名称。
*/
public static final String DEFAULT_FULL_SYNC_DATA_KEY = "data";
/**
* 全量数据同步中,原有数据对象的键名称。
*/
public static final String DEFAULT_FULL_SYNC_OLD_DATA_KEY = "oldData";
/**
* 全量数据同步中,数据对象主键的键名称。
*/
public static final String DEFAULT_FULL_SYNC_ID_KEY = "id";
/** /**
* 为字典表数据缓存时,缓存名称的固定后缀。 * 为字典表数据缓存时,缓存名称的固定后缀。
*/ */

View File

@@ -0,0 +1,27 @@
package com.orange.demo.common.core.exception;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 无效的Redis模式的自定义异常。
*
* @author Jerry
* @date 2020-08-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class InvalidRedisModeException extends RuntimeException {
private final String mode;
/**
* 构造函数。
*
* @param mode 错误的模式。
*/
public InvalidRedisModeException(String mode) {
super("Invalid Redis Mode [" + mode + "], only supports [single/cluster/sentinel/master_slave]");
this.mode = mode;
}
}

View File

@@ -0,0 +1,58 @@
package com.orange.demo.common.core.object;
import lombok.Data;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
/**
* 在线登录用户信息。
*
* @author Jerry
* @date 2020-08-08
*/
@Data
@ToString
@Slf4j
public class LoginUserInfo {
/**
* 用户Id。
*/
private Long userId;
/**
* 用户所在部门Id。
* 仅当系统支持uaa时可用否则可以直接忽略该字段。保留该字段是为了保持单体和微服务通用代码部分的兼容性。
*/
private Long deptId;
/**
* 租户Id。
* 仅当系统支持uaa时可用否则可以直接忽略该字段。保留该字段是为了保持单体和微服务通用代码部分的兼容性。
*/
private Long tenantId;
/**
* 是否为超级管理员。
*/
private Boolean isAdmin;
/**
* 用户登录名。
*/
private String loginName;
/**
* 用户显示名称。
*/
private String showName;
/**
* 标识不同登录的会话Id。
*/
private String sessionId;
/**
* 登录IP。
*/
private String loginIp;
/**
* 登录时间。
*/
private Date loginTime;
}

View File

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
import com.orange.demo.common.core.constant.ErrorCodeEnum; import com.orange.demo.common.core.constant.ErrorCodeEnum;
import com.orange.demo.common.core.util.ContextUtil; import com.orange.demo.common.core.util.ContextUtil;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
@@ -15,6 +16,7 @@ import java.io.PrintWriter;
* @author Jerry * @author Jerry
* @date 2020-08-08 * @date 2020-08-08
*/ */
@Slf4j
@Data @Data
public class ResponseResult<T> { public class ResponseResult<T> {
@@ -160,6 +162,11 @@ public class ResponseResult<T> {
* @throws IOException 异常错误。 * @throws IOException 异常错误。
*/ */
public static <T> void output(int httpStatus, ResponseResult<T> responseResult) throws IOException { public static <T> void output(int httpStatus, ResponseResult<T> responseResult) throws IOException {
if (httpStatus != HttpServletResponse.SC_OK) {
log.error(JSON.toJSONString(responseResult));
} else {
log.info(JSON.toJSONString(responseResult));
}
HttpServletResponse response = ContextUtil.getHttpResponse(); HttpServletResponse response = ContextUtil.getHttpResponse();
PrintWriter out = response.getWriter(); PrintWriter out = response.getWriter();
response.setContentType("application/json; charset=utf-8"); response.setContentType("application/json; charset=utf-8");

View File

@@ -11,6 +11,7 @@ import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Date;
/** /**
* 基于Jwt用于前后端传递的令牌对象。 * 基于Jwt用于前后端传递的令牌对象。
@@ -45,6 +46,10 @@ public class TokenData {
* 是否为超级管理员。 * 是否为超级管理员。
*/ */
private Boolean isAdmin; private Boolean isAdmin;
/**
* 用户登录名。
*/
private String loginName;
/** /**
* 用户显示名称。 * 用户显示名称。
*/ */
@@ -58,6 +63,14 @@ public class TokenData {
* 仅当系统支持uaa时可用否则可以直接忽略该字段。保留该字段是为了保持单体和微服务通用代码部分的兼容性。 * 仅当系统支持uaa时可用否则可以直接忽略该字段。保留该字段是为了保持单体和微服务通用代码部分的兼容性。
*/ */
private String uaaAccessToken; private String uaaAccessToken;
/**
* 登录IP。
*/
private String loginIp;
/**
* 登录时间。
*/
private Date loginTime;
/** /**
* 将令牌对象添加到Http请求对象。 * 将令牌对象添加到Http请求对象。

View File

@@ -17,7 +17,7 @@ import java.util.Map;
@Slf4j @Slf4j
public class JwtUtil { public class JwtUtil {
private static final String TOKEN_PREFIX = "Bearer:"; private static final String TOKEN_PREFIX = "Bearer ";
private static final String CLAIM_KEY_CREATEDTIME = "CreatedTime"; private static final String CLAIM_KEY_CREATEDTIME = "CreatedTime";
/** /**
@@ -61,7 +61,7 @@ public class JwtUtil {
/** /**
* 获取token中的数据对象 * 获取token中的数据对象
* *
* @param token 令牌信息(需要包含令牌前缀,如"Bearer:") * @param token 令牌信息(需要包含令牌前缀,如"Bearer ")
* @return 令牌中的数据对象解析视频返回null。 * @return 令牌中的数据对象解析视频返回null。
*/ */
public static Claims parseToken(String token, String signingKey) { public static Claims parseToken(String token, String signingKey) {

View File

@@ -2,6 +2,7 @@ package com.orange.demo.common.core.util;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.ReflectUtil;
import com.orange.demo.common.core.exception.InvalidDataFieldException;
import com.orange.demo.common.core.annotation.*; import com.orange.demo.common.core.annotation.*;
import com.orange.demo.common.core.exception.MyRuntimeException; import com.orange.demo.common.core.exception.MyRuntimeException;
import com.orange.demo.common.core.object.TokenData; import com.orange.demo.common.core.object.TokenData;
@@ -141,6 +142,34 @@ public class MyModelUtil {
return columnInfo == null ? null : columnInfo.getFirst(); return columnInfo == null ? null : columnInfo.getFirst();
} }
/**
* 映射Model对象的字段反射对象获取与该字段对应的数据库列名称。
* 如果没有匹配到ColumnName则立刻抛出异常。
*
* @param field 字段反射对象。
* @param modelClazz Model对象的Class类。
* @return 该字段所对应的数据表列名称。
*/
public static String safeMapToColumnName(Field field, Class<?> modelClazz) {
return safeMapToColumnName(field.getName(), modelClazz);
}
/**
* 映射Model对象的字段名称获取与该字段对应的数据库列名称。
* 如果没有匹配到ColumnName则立刻抛出异常。
*
* @param fieldName 字段名称。
* @param modelClazz Model对象的Class类。
* @return 该字段所对应的数据表列名称。
*/
public static String safeMapToColumnName(String fieldName, Class<?> modelClazz) {
String columnName = mapToColumnName(fieldName, modelClazz);
if (columnName == null) {
throw new InvalidDataFieldException(modelClazz.getSimpleName(), fieldName);
}
return columnName;
}
/** /**
* 映射Model对象的字段名称获取与该字段对应的数据库列名称和字段类型。 * 映射Model对象的字段名称获取与该字段对应的数据库列名称和字段类型。
* *

View File

@@ -8,6 +8,25 @@ package com.orange.demo.common.core.util;
*/ */
public class RedisKeyUtil { public class RedisKeyUtil {
/**
* 获取通用的session缓存的键前缀。
*
* @return session缓存的键前缀。
*/
public static String getSessionIdPrefix() {
return "SESSIONID__";
}
/**
* 获取指定用户Id的session缓存的键前缀。
*
* @param loginName 指定的用户登录名。
* @return session缓存的键前缀。
*/
public static String getSessionIdPrefix(String loginName) {
return "SESSIONID__" + loginName + "_";
}
/** /**
* 计算SessionId返回存储于Redis中的键。 * 计算SessionId返回存储于Redis中的键。
* *

View File

@@ -90,9 +90,6 @@
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.3.0" level="project" /> <orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.3.0" level="project" />
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.2.0" level="project" /> <orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.2.0" level="project" />
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:3.2" level="project" /> <orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:3.2" level="project" />
<orderEntry type="library" name="Maven: redis.clients:jedis:3.2.0" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.7.0" level="project" />
<orderEntry type="library" name="Maven: org.redisson:redisson:3.12.3" level="project" /> <orderEntry type="library" name="Maven: org.redisson:redisson:3.12.3" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.1.45.Final" level="project" /> <orderEntry type="library" name="Maven: io.netty:netty-common:4.1.45.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.45.Final" level="project" /> <orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.45.Final" level="project" />
@@ -109,6 +106,7 @@
<orderEntry type="library" name="Maven: de.ruedigermoeller:fst:2.57" level="project" /> <orderEntry type="library" name="Maven: de.ruedigermoeller:fst:2.57" level="project" />
<orderEntry type="library" name="Maven: org.javassist:javassist:3.21.0-GA" level="project" /> <orderEntry type="library" name="Maven: org.javassist:javassist:3.21.0-GA" level="project" />
<orderEntry type="library" name="Maven: org.objenesis:objenesis:2.6" level="project" /> <orderEntry type="library" name="Maven: org.objenesis:objenesis:2.6" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
<orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.25" level="project" /> <orderEntry type="library" name="Maven: org.yaml:snakeyaml:1.25" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.10.2" level="project" /> <orderEntry type="library" name="Maven: com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.10.2" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.2" level="project" /> <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.10.2" level="project" />

View File

@@ -20,11 +20,6 @@
<artifactId>common-core</artifactId> <artifactId>common-core</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
</dependency> </dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${jedis.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.redisson</groupId> <groupId>org.redisson</groupId>
<artifactId>redisson</artifactId> <artifactId>redisson</artifactId>

View File

@@ -1,7 +1,5 @@
package com.orange.demo.common.redis.cache; package com.orange.demo.common.redis.cache;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.orange.demo.common.core.object.TokenData; import com.orange.demo.common.core.object.TokenData;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache; import org.springframework.cache.Cache;
@@ -73,30 +71,4 @@ public class SessionCacheHelper {
cacheManager.getCache(c.name()).evict(sessionId); cacheManager.getCache(c.name()).evict(sessionId);
} }
} }
/**
* 存放session的Token数据。仅仅单体服务使用。
*
* @param sessionId 当前会话的SessionId。
* @param tokenData 当前会话的JWT Token对象。
*/
public void putTokenData(String sessionId, TokenData tokenData) {
if (sessionId == null || tokenData == null) {
return;
}
Cache cache = cacheManager.getCache(RedissonCacheConfig.CacheEnum.GLOBAL_CACHE.name());
cache.put(sessionId, JSON.toJSONString(tokenData));
}
/**
* 获取session的JWT Token对象。
*
* @param sessionId 当前会话的SessionId。
* @return 当前会话的JWT Token对象。
*/
public TokenData getTokenData(String sessionId) {
Cache cache = cacheManager.getCache(RedissonCacheConfig.CacheEnum.GLOBAL_CACHE.name());
String tokenString = cache.get(sessionId, String.class);
return JSONObject.parseObject(tokenString, TokenData.class);
}
} }

View File

@@ -1,52 +0,0 @@
package com.orange.demo.common.redis.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* Redis配置类。
*
* @author Jerry
* @date 2020-08-08
*/
@Configuration
@ConditionalOnProperty(name = "redis.jedis.enabled", havingValue = "true")
public class JedisConfig {
@Value("${redis.jedis.port}")
private Integer port;
@Value("${redis.jedis.host}")
private String redisHost;
@Value("${redis.jedis.timeout}")
private int timeout;
@Value("${redis.jedis.pool.maxTotal}")
private Integer maxTotal;
@Value("${redis.jedis.pool.maxIdle}")
private Integer maxIdle;
@Value("${redis.jedis.pool.minIdle}")
private Integer minIdle;
@Value("${redis.jedis.pool.maxWait}")
private Integer maxWait;
@Bean
public JedisPool getJedisPool() {
// Jedis配置信息
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(maxTotal);
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMinIdle(minIdle);
jedisPoolConfig.setMaxWaitMillis(maxWait);
jedisPoolConfig.setEvictorShutdownTimeoutMillis(2000);
return new JedisPool(jedisPoolConfig, redisHost, port);
}
}

View File

@@ -1,5 +1,8 @@
package com.orange.demo.common.redis.config; package com.orange.demo.common.redis.config;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.orange.demo.common.core.exception.InvalidRedisModeException;
import org.redisson.Redisson; import org.redisson.Redisson;
import org.redisson.api.RedissonClient; import org.redisson.api.RedissonClient;
import org.redisson.config.Config; import org.redisson.config.Config;
@@ -9,8 +12,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
/** /**
* Redisson配置类。和Jedis一样都是Redis客户端但是Redisson提供了更多的数据结构抽象。 * Redisson配置类。
* 这里我们只是使用了Redisson的分布式锁以及map等数据结构作为字典缓存使用。更多用法请参考其文档。
* *
* @author Jerry * @author Jerry
* @date 2020-08-08 * @date 2020-08-08
@@ -22,6 +24,15 @@ public class RedissonConfig {
@Value("${redis.redisson.lockWatchdogTimeout}") @Value("${redis.redisson.lockWatchdogTimeout}")
private Integer lockWatchdogTimeout; private Integer lockWatchdogTimeout;
@Value("${redis.redisson.mode}")
private String mode;
/**
* 仅仅用于sentinel模式。
*/
@Value("${redis.redisson.masterName:}")
private String masterName;
@Value("${redis.redisson.address}") @Value("${redis.redisson.address}")
private String address; private String address;
@@ -37,14 +48,45 @@ public class RedissonConfig {
@Bean @Bean
public RedissonClient redissonClient() { public RedissonClient redissonClient() {
Config config = new Config(); Config config = new Config();
// 这里config还支持其他redis集群模式可根据实际需求更换。 if ("single".equals(mode)) {
// 比如useClusterServers()/useMasterSlaveServers()等。 config.setLockWatchdogTimeout(lockWatchdogTimeout)
config.setLockWatchdogTimeout(lockWatchdogTimeout) .useSingleServer()
.useSingleServer() .setAddress(address)
.setAddress("redis://" + address) .setConnectionPoolSize(poolSize)
.setConnectionPoolSize(poolSize) .setConnectionMinimumIdleSize(minIdle)
.setConnectionMinimumIdleSize(minIdle) .setConnectTimeout(timeout);
.setConnectTimeout(timeout); } else if ("cluster".equals(mode)) {
String[] clusterAddresses = StrUtil.splitToArray(address, ',');
config.setLockWatchdogTimeout(lockWatchdogTimeout)
.useClusterServers()
.addNodeAddress(clusterAddresses)
.setConnectTimeout(timeout)
.setMasterConnectionPoolSize(poolSize);
} else if ("sentinel".equals(mode)) {
String[] sentinelAddresses = StrUtil.splitToArray(address, ',');
config.setLockWatchdogTimeout(lockWatchdogTimeout)
.useSentinelServers()
.setMasterName(masterName)
.addSentinelAddress(sentinelAddresses)
.setConnectTimeout(timeout)
.setMasterConnectionPoolSize(poolSize);
} else if ("master-slave".equals(mode)) {
String[] masterSlaveAddresses = StrUtil.splitToArray(address, ',');
if (masterSlaveAddresses.length == 1) {
throw new IllegalArgumentException(
"redis.redisson.address MUST have multiple redis addresses for master-slave mode.");
}
String[] slaveAddresses = new String[masterSlaveAddresses.length - 1];
ArrayUtil.copy(masterSlaveAddresses, 1, slaveAddresses, 0, slaveAddresses.length);
config.setLockWatchdogTimeout(lockWatchdogTimeout)
.useMasterSlaveServers()
.setMasterAddress(masterSlaveAddresses[0])
.addSlaveAddress(slaveAddresses)
.setConnectTimeout(timeout)
.setMasterConnectionPoolSize(poolSize);
} else {
throw new InvalidRedisModeException(mode);
}
return Redisson.create(config); return Redisson.create(config);
} }
} }

View File

@@ -1,3 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.orange.demo.common.redis.config.JedisConfig,\
com.orange.demo.common.redis.config.RedissonConfig com.orange.demo.common.redis.config.RedissonConfig

View File

@@ -10,3 +10,5 @@ spring:
nacos: nacos:
discovery: discovery:
server-addr: localhost:8848 server-addr: localhost:8848
config:
server-addr: localhost:8848

View File

@@ -41,7 +41,6 @@
<mybatis-mapper.version>2.1.5</mybatis-mapper.version> <mybatis-mapper.version>2.1.5</mybatis-mapper.version>
<mybatis-generator.version>1.3.7</mybatis-generator.version> <mybatis-generator.version>1.3.7</mybatis-generator.version>
<pagehelper.version>1.3.0</pagehelper.version> <pagehelper.version>1.3.0</pagehelper.version>
<jedis.version>3.2.0</jedis.version>
<redisson.version>3.12.3</redisson.version> <redisson.version>3.12.3</redisson.version>
<qdox.version>2.0.0</qdox.version> <qdox.version>2.0.0</qdox.version>
<knife4j.version>2.0.5</knife4j.version> <knife4j.version>2.0.5</knife4j.version>

View File

@@ -17,7 +17,7 @@
<!-- 业务组件依赖 --> <!-- 业务组件依赖 -->
<dependency> <dependency>
<groupId>com.orange.demo</groupId> <groupId>com.orange.demo</groupId>
<artifactId>common-core</artifactId> <artifactId>common-log</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
</dependency> </dependency>
<dependency> <dependency>

View File

@@ -31,8 +31,8 @@
<sql id="inputFilterRef"> <sql id="inputFilterRef">
<if test="courseFilter != null"> <if test="courseFilter != null">
<if test="courseFilter.courseName != null and courseFilter.courseName != ''"> <if test="courseFilter.courseName != null and courseFilter.courseName != ''">
<bind name = "safeCourseName" value = "'%' + courseFilter.courseName + '%'" /> <bind name = "safeCourseCourseName" value = "'%' + courseFilter.courseName + '%'" />
AND zz_course.course_name LIKE #{safeCourseName} AND zz_course.course_name LIKE #{safeCourseCourseName}
</if> </if>
<if test="courseFilter.priceStart != null"> <if test="courseFilter.priceStart != null">
AND zz_course.price &gt;= #{courseFilter.priceStart} AND zz_course.price &gt;= #{courseFilter.priceStart}

View File

@@ -18,8 +18,8 @@
<sql id="inputFilterRef"> <sql id="inputFilterRef">
<if test="schoolInfoFilter != null"> <if test="schoolInfoFilter != null">
<if test="schoolInfoFilter.schoolName != null and schoolInfoFilter.schoolName != ''"> <if test="schoolInfoFilter.schoolName != null and schoolInfoFilter.schoolName != ''">
<bind name = "safeSchoolName" value = "'%' + schoolInfoFilter.schoolName + '%'" /> <bind name = "safeSchoolInfoSchoolName" value = "'%' + schoolInfoFilter.schoolName + '%'" />
AND zz_school_info.school_name LIKE #{safeSchoolName} AND zz_school_info.school_name LIKE #{safeSchoolInfoSchoolName}
</if> </if>
<if test="schoolInfoFilter.provinceId != null"> <if test="schoolInfoFilter.provinceId != null">
AND zz_school_info.province_id = #{schoolInfoFilter.provinceId} AND zz_school_info.province_id = #{schoolInfoFilter.provinceId}

View File

@@ -59,8 +59,8 @@
AND zz_student.status = #{studentFilter.status} AND zz_student.status = #{studentFilter.status}
</if> </if>
<if test="studentFilter.searchString != null and studentFilter.searchString != ''"> <if test="studentFilter.searchString != null and studentFilter.searchString != ''">
<bind name = "safeSearchString" value = "'%' + studentFilter.searchString + '%'" /> <bind name = "safeStudentSearchString" value = "'%' + studentFilter.searchString + '%'" />
AND CONCAT(IFNULL(zz_student.login_mobile,''), IFNULL(zz_student.student_name,'')) LIKE #{safeSearchString} AND CONCAT(IFNULL(zz_student.login_mobile,''), IFNULL(zz_student.student_name,'')) LIKE #{safeStudentSearchString}
</if> </if>
</if> </if>
</sql> </sql>

View File

@@ -86,7 +86,6 @@ public class StudentDto {
/** /**
* 可用学币数量。 * 可用学币数量。
*/ */
@NotNull(message = "数据验证失败,剩余学币不能为空!", groups = {UpdateGroup.class})
private Integer leftCoin; private Integer leftCoin;
/** /**

View File

@@ -47,5 +47,5 @@ public class ApplicationConfig {
* Session的用户权限在Redis中的过期时间(秒)。 * Session的用户权限在Redis中的过期时间(秒)。
* 缺省值是 one day * 缺省值是 one day
*/ */
private int permRedisExpiredSeconds = 86400; private int sessionExpiredSeconds = 86400;
} }

View File

@@ -12,15 +12,15 @@ import com.orange.demo.common.core.object.TokenData;
import com.orange.demo.common.core.util.ApplicationContextHolder; import com.orange.demo.common.core.util.ApplicationContextHolder;
import com.orange.demo.common.core.util.JwtUtil; import com.orange.demo.common.core.util.JwtUtil;
import com.orange.demo.common.core.util.RedisKeyUtil; import com.orange.demo.common.core.util.RedisKeyUtil;
import com.orange.demo.common.redis.cache.SessionCacheHelper;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RBucket;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@@ -42,10 +42,7 @@ public class AuthenticationInterceptor implements HandlerInterceptor {
private final ApplicationConfig appConfig = private final ApplicationConfig appConfig =
ApplicationContextHolder.getBean("applicationConfig"); ApplicationContextHolder.getBean("applicationConfig");
private final JedisPool jedisPool = ApplicationContextHolder.getBean(JedisPool.class); private final RedissonClient redissonClient = ApplicationContextHolder.getBean(RedissonClient.class);
private final SessionCacheHelper cacheHelper =
ApplicationContextHolder.getBean("sessionCacheHelper");
private final SysPermService sysPermService = private final SysPermService sysPermService =
ApplicationContextHolder.getBean(SysPermService.class); ApplicationContextHolder.getBean(SysPermService.class);
@@ -85,7 +82,12 @@ public class AuthenticationInterceptor implements HandlerInterceptor {
return false; return false;
} }
String sessionId = (String) c.get("sessionId"); String sessionId = (String) c.get("sessionId");
TokenData tokenData = cacheHelper.getTokenData(sessionId); String sessionIdKey = RedisKeyUtil.makeSessionIdKeyForRedis(sessionId);
RBucket<String> sessionData = redissonClient.getBucket(sessionIdKey);
TokenData tokenData = null;
if (sessionData.isExists()) {
tokenData = JSON.parseObject(sessionData.get(), TokenData.class);
}
if (tokenData == null) { if (tokenData == null) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
this.outputResponseMessage(response, this.outputResponseMessage(response,
@@ -95,13 +97,11 @@ public class AuthenticationInterceptor implements HandlerInterceptor {
TokenData.addToRequest(tokenData); TokenData.addToRequest(tokenData);
// 如果url在权限资源白名单中则不需要进行鉴权操作 // 如果url在权限资源白名单中则不需要进行鉴权操作
if (Boolean.FALSE.equals(tokenData.getIsAdmin()) && !whitelistPermSet.contains(url)) { if (Boolean.FALSE.equals(tokenData.getIsAdmin()) && !whitelistPermSet.contains(url)) {
try (Jedis jedis = jedisPool.getResource()) { RSet<String> permSet = redissonClient.getSet(RedisKeyUtil.makeSessionPermIdKeyForRedis(sessionId));
if (!jedis.sismember(RedisKeyUtil.makeSessionPermIdKeyForRedis(tokenData.getSessionId()), url)) { if (!permSet.contains(url)) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN); response.setStatus(HttpServletResponse.SC_FORBIDDEN);
this.outputResponseMessage(response, this.outputResponseMessage(response, ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION));
ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION)); return false;
return false;
}
} }
} }
if (JwtUtil.needToRefresh(c)) { if (JwtUtil.needToRefresh(c)) {

View File

@@ -1,6 +1,8 @@
package com.orange.demo.webadmin.upms.controller; package com.orange.demo.webadmin.upms.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import com.orange.demo.webadmin.config.ApplicationConfig; import com.orange.demo.webadmin.config.ApplicationConfig;
import com.orange.demo.webadmin.upms.service.*; import com.orange.demo.webadmin.upms.service.*;
@@ -12,10 +14,11 @@ import com.orange.demo.common.core.annotation.NoAuthInterface;
import com.orange.demo.common.core.annotation.MyRequestBody; import com.orange.demo.common.core.annotation.MyRequestBody;
import com.orange.demo.common.core.constant.ApplicationConstant; import com.orange.demo.common.core.constant.ApplicationConstant;
import com.orange.demo.common.core.constant.ErrorCodeEnum; import com.orange.demo.common.core.constant.ErrorCodeEnum;
import com.orange.demo.common.core.object.ResponseResult; import com.orange.demo.common.core.object.*;
import com.orange.demo.common.core.object.TokenData;
import com.orange.demo.common.core.util.*; import com.orange.demo.common.core.util.*;
import com.orange.demo.common.redis.cache.SessionCacheHelper; import com.orange.demo.common.redis.cache.SessionCacheHelper;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -23,6 +26,7 @@ import org.springframework.web.bind.annotation.*;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit;
/** /**
* 登录接口控制器类。 * 登录接口控制器类。
@@ -46,6 +50,8 @@ public class LoginController {
@Autowired @Autowired
private ApplicationConfig appConfig; private ApplicationConfig appConfig;
@Autowired @Autowired
private RedissonClient redissonClient;
@Autowired
private SessionCacheHelper cacheHelper; private SessionCacheHelper cacheHelper;
@Autowired @Autowired
private PasswordEncoder passwordEncoder; private PasswordEncoder passwordEncoder;
@@ -77,38 +83,7 @@ public class LoginController {
errorMessage = "登录失败,用户账号被锁定!"; errorMessage = "登录失败,用户账号被锁定!";
return ResponseResult.error(ErrorCodeEnum.INVALID_USER_STATUS, errorMessage); return ResponseResult.error(ErrorCodeEnum.INVALID_USER_STATUS, errorMessage);
} }
boolean isAdmin = user.getUserType() == SysUserType.TYPE_ADMIN; JSONObject jsonData = this.buildLoginData(user);
Map<String, Object> claims = new HashMap<>(3);
String sessionId = MyCommonUtil.generateUuid();
claims.put("sessionId", sessionId);
String token = JwtUtil.generateToken(claims, appConfig.getExpiration(), appConfig.getTokenSigningKey());
JSONObject jsonData = new JSONObject();
jsonData.put(TokenData.REQUEST_ATTRIBUTE_NAME, token);
jsonData.put("showName", user.getShowName());
jsonData.put("isAdmin", isAdmin);
TokenData tokenData = new TokenData();
tokenData.setSessionId(sessionId);
tokenData.setUserId(user.getUserId());
tokenData.setShowName(user.getShowName());
tokenData.setIsAdmin(isAdmin);
cacheHelper.putTokenData(sessionId, tokenData);
// 这里手动将TokenData存入request便于OperationLogAspect统一处理操作日志。
TokenData.addToRequest(tokenData);
Collection<SysMenu> menuList;
Collection<String> permCodeList;
if (isAdmin) {
menuList = sysMenuService.getAllMenuList();
permCodeList = sysPermCodeService.getAllPermCodeList();
} else {
menuList = sysMenuService.getMenuListByUserId(user.getUserId());
permCodeList = sysPermCodeService.getPermCodeListByUserId(user.getUserId());
}
jsonData.put("menuList", menuList);
jsonData.put("permCodeList", permCodeList);
if (user.getUserType() != SysUserType.TYPE_ADMIN) {
// 缓存用户的权限资源
sysPermService.putUserSysPermCache(sessionId, user.getUserId());
}
return ResponseResult.success(jsonData); return ResponseResult.success(jsonData);
} }
@@ -120,6 +95,8 @@ public class LoginController {
@PostMapping("/doLogout") @PostMapping("/doLogout")
public ResponseResult<Void> doLogout() { public ResponseResult<Void> doLogout() {
TokenData tokenData = TokenData.takeFromRequest(); TokenData tokenData = TokenData.takeFromRequest();
String sessionIdKey = RedisKeyUtil.makeSessionIdKeyForRedis(tokenData.getSessionId());
redissonClient.getBucket(sessionIdKey).delete();
sysPermService.removeUserSysPermCache(tokenData.getSessionId()); sysPermService.removeUserSysPermCache(tokenData.getSessionId());
cacheHelper.removeAllSessionCache(tokenData.getSessionId()); cacheHelper.removeAllSessionCache(tokenData.getSessionId());
return ResponseResult.success(); return ResponseResult.success();
@@ -184,4 +161,47 @@ public class LoginController {
} }
return ResponseResult.success(); return ResponseResult.success();
} }
private JSONObject buildLoginData(SysUser user) {
boolean isAdmin = user.getUserType() == SysUserType.TYPE_ADMIN;
Map<String, Object> claims = new HashMap<>(3);
String sessionId = user.getLoginName() + "_" + MyCommonUtil.generateUuid();
claims.put("sessionId", sessionId);
String token = JwtUtil.generateToken(claims, appConfig.getExpiration(), appConfig.getTokenSigningKey());
JSONObject jsonData = new JSONObject();
jsonData.put(TokenData.REQUEST_ATTRIBUTE_NAME, token);
jsonData.put("showName", user.getShowName());
jsonData.put("isAdmin", isAdmin);
TokenData tokenData = new TokenData();
tokenData.setSessionId(sessionId);
tokenData.setUserId(user.getUserId());
tokenData.setLoginName(user.getLoginName());
tokenData.setShowName(user.getShowName());
tokenData.setIsAdmin(isAdmin);
tokenData.setLoginIp(IpUtil.getRemoteIpAddress(ContextUtil.getHttpRequest()));
tokenData.setLoginTime(new Date());
String sessionIdKey = RedisKeyUtil.makeSessionIdKeyForRedis(sessionId);
String sessionData = JSON.toJSONString(tokenData, SerializerFeature.WriteNonStringValueAsString);
RBucket<String> bucket = redissonClient.getBucket(sessionIdKey);
bucket.set(sessionData);
bucket.expire(appConfig.getSessionExpiredSeconds(), TimeUnit.SECONDS);
// 这里手动将TokenData存入request便于OperationLogAspect统一处理操作日志。
TokenData.addToRequest(tokenData);
Collection<SysMenu> menuList;
Collection<String> permCodeList;
if (isAdmin) {
menuList = sysMenuService.getAllMenuList();
permCodeList = sysPermCodeService.getAllPermCodeList();
} else {
menuList = sysMenuService.getMenuListByUserId(user.getUserId());
permCodeList = sysPermCodeService.getPermCodeListByUserId(user.getUserId());
}
jsonData.put("menuList", menuList);
jsonData.put("permCodeList", permCodeList);
if (user.getUserType() != SysUserType.TYPE_ADMIN) {
// 缓存用户的权限资源
sysPermService.putUserSysPermCache(sessionId, user.getUserId());
}
return jsonData;
}
} }

View File

@@ -0,0 +1,84 @@
package com.orange.demo.webadmin.upms.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.orange.demo.common.core.annotation.MyRequestBody;
import com.orange.demo.common.core.object.*;
import com.orange.demo.common.core.util.RedisKeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
/**
* 在线用户控制器对象。
*
* @author Jerry
* @date 2020-09-24
*/
@Slf4j
@RestController
@RequestMapping("/admin/upms/loginUser")
public class LoginUserController {
@Autowired
private RedissonClient redissonClient;
/**
* 显示在线用户列表。
*
* @param loginName 登录名过滤。
* @param pageParam 分页参数。
* @return 登录用户信息列表。
*/
@PostMapping("/list")
public ResponseResult<MyPageData<LoginUserInfo>> list(
@MyRequestBody String loginName, @MyRequestBody MyPageParam pageParam) {
List<LoginUserInfo> loginUserInfoList = new LinkedList<>();
int queryCount = pageParam.getPageNum() * pageParam.getPageSize();
int skipCount = (pageParam.getPageNum() - 1) * pageParam.getPageSize();
String patternKey;
if (StrUtil.isBlank(loginName)) {
patternKey = RedisKeyUtil.getSessionIdPrefix() + "*";
} else {
patternKey = RedisKeyUtil.getSessionIdPrefix(loginName) + "*";
}
long totalCount = 0L;
int pos = 0;
Iterable<String> keys = redissonClient.getKeys().getKeysByPattern(patternKey);
for (String key : keys) {
totalCount++;
if (pos++ < skipCount) {
continue;
}
loginUserInfoList.add(this.buildTokenDataByRedisKey(key));
}
return ResponseResult.success(new MyPageData<>(loginUserInfoList, totalCount));
}
/**
* 强制下线指定登录会话。
*
* @param sessionId 待强制下线的SessionId。
* @return 应答结果对象。
*/
@PostMapping("/delete")
public ResponseResult<Void> delete(@MyRequestBody String sessionId) {
// 为了保证被剔除用户正在进行的操作不被干扰这里只是删除sessionIdKey即可这样可以使强制下线操作更加平滑。
// 比如如果删除操作权限或数据权限的redis session key那么正在请求数据的操作就会报错。
redissonClient.getBucket(RedisKeyUtil.makeSessionIdKeyForRedis(sessionId)).delete();
return ResponseResult.success();
}
private LoginUserInfo buildTokenDataByRedisKey(String key) {
RBucket<String> sessionData = redissonClient.getBucket(key);
TokenData tokenData = JSON.parseObject(sessionData.get(), TokenData.class);
return BeanUtil.copyProperties(tokenData, LoginUserInfo.class);
}
}

View File

@@ -27,12 +27,12 @@
<sql id="inputFilterRef"> <sql id="inputFilterRef">
<if test="sysUserFilter != null"> <if test="sysUserFilter != null">
<if test="sysUserFilter.loginName != null and sysUserFilter.loginName != ''"> <if test="sysUserFilter.loginName != null and sysUserFilter.loginName != ''">
<bind name = "safeLoginName" value = "'%' + sysUserFilter.loginName + '%'" /> <bind name = "safeSysUserLoginName" value = "'%' + sysUserFilter.loginName + '%'" />
AND zz_sys_user.login_name LIKE #{safeLoginName} AND zz_sys_user.login_name LIKE #{safeSysUserLoginName}
</if> </if>
<if test="sysUserFilter.showName != null and sysUserFilter.showName != ''"> <if test="sysUserFilter.showName != null and sysUserFilter.showName != ''">
<bind name = "safeShowName" value = "'%' + sysUserFilter.showName + '%'" /> <bind name = "safeSysUserShowName" value = "'%' + sysUserFilter.showName + '%'" />
AND zz_sys_user.show_name LIKE #{safeShowName} AND zz_sys_user.show_name LIKE #{safeSysUserShowName}
</if> </if>
<if test="sysUserFilter.userStatus != null"> <if test="sysUserFilter.userStatus != null">
AND zz_sys_user.user_status = #{sysUserFilter.userStatus} AND zz_sys_user.user_status = #{sysUserFilter.userStatus}

View File

@@ -17,15 +17,16 @@ import com.orange.demo.webadmin.upms.model.SysPerm;
import com.orange.demo.webadmin.upms.model.SysPermCodePerm; import com.orange.demo.webadmin.upms.model.SysPermCodePerm;
import com.orange.demo.webadmin.upms.model.SysPermModule; import com.orange.demo.webadmin.upms.model.SysPermModule;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;
import tk.mybatis.mapper.entity.Example; import tk.mybatis.mapper.entity.Example;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/** /**
* 权限资源数据服务类。 * 权限资源数据服务类。
@@ -47,7 +48,7 @@ public class SysPermServiceImpl extends BaseService<SysPerm, Long> implements Sy
@Autowired @Autowired
private IdGeneratorWrapper idGenerator; private IdGeneratorWrapper idGenerator;
@Autowired @Autowired
private JedisPool jedisPool; private RedissonClient redissonClient;
@Autowired @Autowired
private ApplicationConfig applicationConfig; private ApplicationConfig applicationConfig;
@@ -148,16 +149,9 @@ public class SysPermServiceImpl extends BaseService<SysPerm, Long> implements Sy
return permList; return permList;
} }
String sessionPermKey = RedisKeyUtil.makeSessionPermIdKeyForRedis(sessionId); String sessionPermKey = RedisKeyUtil.makeSessionPermIdKeyForRedis(sessionId);
try (Jedis jedis = jedisPool.getResource()) { RSet<String> redisPermSet = redissonClient.getSet(sessionPermKey);
Transaction t = jedis.multi(); redisPermSet.addAll(permList.stream().map(Object::toString).collect(Collectors.toSet()));
if (permList != null) { redisPermSet.expire(applicationConfig.getSessionExpiredSeconds(), TimeUnit.SECONDS);
for (String perm : permList) {
t.sadd(sessionPermKey, perm);
}
t.expire(sessionPermKey, applicationConfig.getPermRedisExpiredSeconds());
}
t.exec();
}
return permList; return permList;
} }
@@ -168,10 +162,8 @@ public class SysPermServiceImpl extends BaseService<SysPerm, Long> implements Sy
*/ */
@Override @Override
public void removeUserSysPermCache(String sessionId) { public void removeUserSysPermCache(String sessionId) {
try (Jedis jedis = jedisPool.getResource()) { String sessionPermKey = RedisKeyUtil.makeSessionPermIdKeyForRedis(sessionId);
String sessionPermKey = RedisKeyUtil.makeSessionPermIdKeyForRedis(sessionId); redissonClient.getSet(sessionPermKey).deleteAsync();
jedis.del(sessionPermKey);
}
} }
/** /**

View File

@@ -40,8 +40,8 @@ spring:
# mybatis的基本配置 # mybatis的基本配置
mybatis: mybatis:
mapperLocations: classpath:com/orange/demo/webadmin/*/dao/mapper/*Mapper.xml mapperLocations: classpath:com/orange/demo/webadmin/*/dao/mapper/*Mapper.xml,com/orange/demo/common/log/dao/mapper/*Mapper.xml
typeAliasesPackage: com.orange.demo.webadmin.*.model typeAliasesPackage: com.orange.demo.webadmin.*.model,com.orange.demo.common.log.model
# mybatis的通用mapper的配置 # mybatis的通用mapper的配置
mapper: mapper:
@@ -59,22 +59,24 @@ pagehelper:
# 存储session数据的Redis所有服务均需要因此放到公共配置中。 # 存储session数据的Redis所有服务均需要因此放到公共配置中。
# 根据实际情况该Redis也可以用于存储其他数据。 # 根据实际情况该Redis也可以用于存储其他数据。
redis: redis:
jedis:
enabled: true
host: localhost
port: 6379
timeout: 60000
pool:
maxTotal: 20
maxIdle: 8
minIdle: 0
maxWait: 2000
# redisson的配置。每个服务可以自己的配置文件中覆盖此选项。 # redisson的配置。每个服务可以自己的配置文件中覆盖此选项。
redisson: redisson:
# 如果该值为false系统将不会创建RedissionClient的bean。 # 如果该值为false系统将不会创建RedissionClient的bean。
enabled: true enabled: true
# redis地址多个地址之间逗号分隔。如果是从主机制第一个为master,其余为slave # mode的可用值为single/cluster/sentinel/master-slave
address: localhost:6379 mode: single
# single: 单机模式
# address: redis://localhost:6379
# cluster: 集群模式
# 每个节点逗号分隔同时每个节点前必须以redis://开头。
# address: redis://localhost:6379,redis://localhost:6378,...
# sentinel:
# 每个节点逗号分隔同时每个节点前必须以redis://开头。
# address: redis://localhost:6379,redis://localhost:6378,...
# master-slave:
# 每个节点逗号分隔第一个为主节点其余为从节点。同时每个节点前必须以redis://开头。
# address: redis://localhost:6379,redis://localhost:6378,...
address: redis://localhost:6379
# 链接超时,单位毫秒。 # 链接超时,单位毫秒。
timeout: 6000 timeout: 6000
# 单位毫秒。分布式锁的超时检测时长。 # 单位毫秒。分布式锁的超时检测时长。
@@ -161,7 +163,7 @@ application:
# 跨域的IP白名单列表多个IP之间逗号分隔(* 表示全部信任,空白表示禁用跨域信任)。 # 跨域的IP白名单列表多个IP之间逗号分隔(* 表示全部信任,空白表示禁用跨域信任)。
credentialIpList: "*" credentialIpList: "*"
# Session的用户和数据权限在Redis中的过期时间(秒)。 # Session的用户和数据权限在Redis中的过期时间(秒)。
permRedisExpiredSeconds: 86400 sessionExpiredSeconds: 86400
sequence: sequence:
# Snowflake 分布式Id生成算法所需的WorkNode参数值。 # Snowflake 分布式Id生成算法所需的WorkNode参数值。
@@ -220,7 +222,7 @@ application:
# 跨域的IP白名单列表多个IP之间逗号分隔(* 表示全部信任,空白表示禁用跨域信任)。 # 跨域的IP白名单列表多个IP之间逗号分隔(* 表示全部信任,空白表示禁用跨域信任)。
credentialIpList: "*" credentialIpList: "*"
# Session的用户和数据权限在Redis中的过期时间(秒)。 # Session的用户和数据权限在Redis中的过期时间(秒)。
permRedisExpiredSeconds: 86400 sessionExpiredSeconds: 86400
sequence: sequence:
# Snowflake 分布式Id生成算法所需的WorkNode参数值。 # Snowflake 分布式Id生成算法所需的WorkNode参数值。

View File

@@ -53,18 +53,22 @@
<root level="${OUTPUT_LOG_LEVEL}"> <root level="${OUTPUT_LOG_LEVEL}">
<AppenderRef ref="console"/> <AppenderRef ref="console"/>
</root> </root>
<Logger name="com.orange.demo" additivity="false" level="info"> <AsyncLogger name="com.orange.demo" additivity="false" level="info">
<AppenderRef ref="console"/> <AppenderRef ref="console"/>
<AppenderRef ref="file_log"/> <AppenderRef ref="file_log"/>
</Logger> </AsyncLogger>
<!-- 这里将dao的日志级别设置为DEBUG是为了SQL语句的输出 --> <!-- 这里将dao的日志级别设置为DEBUG是为了SQL语句的输出 -->
<Logger name="com.orange.demo.webadmin.app.dao" additivity="false" level="debug"> <AsyncLogger name="com.orange.demo.webadmin.app.dao" additivity="false" level="debug">
<AppenderRef ref="console"/> <AppenderRef ref="console"/>
<AppenderRef ref="file_log"/> <AppenderRef ref="file_log"/>
</Logger> </AsyncLogger>
<Logger name="com.orange.demo.webadmin.upms.dao" additivity="false" level="debug"> <AsyncLogger name="com.orange.demo.webadmin.upms.dao" additivity="false" level="debug">
<AppenderRef ref="console"/> <AppenderRef ref="console"/>
<AppenderRef ref="file_log"/> <AppenderRef ref="file_log"/>
</Logger> </AsyncLogger>
<AsyncLogger name="com.orange.demo.common.log.dao" additivity="false" level="debug">
<AppenderRef ref="console"/>
<AppenderRef ref="file_log"/>
</AsyncLogger>
</Loggers> </Loggers>
</configuration> </configuration>

View File

@@ -8,6 +8,22 @@ package com.orange.demo.common.core.constant;
*/ */
public final class ApplicationConstant { public final class ApplicationConstant {
/**
* 数据同步使用的缺省消息队列主题名称。
*/
public static final String DEFAULT_DATA_SYNC_TOPIC = "OrangeSingleDemo";
/**
* 全量数据同步中,新增数据对象的键名称。
*/
public static final String DEFAULT_FULL_SYNC_DATA_KEY = "data";
/**
* 全量数据同步中,原有数据对象的键名称。
*/
public static final String DEFAULT_FULL_SYNC_OLD_DATA_KEY = "oldData";
/**
* 全量数据同步中,数据对象主键的键名称。
*/
public static final String DEFAULT_FULL_SYNC_ID_KEY = "id";
/** /**
* 为字典表数据缓存时,缓存名称的固定后缀。 * 为字典表数据缓存时,缓存名称的固定后缀。
*/ */

View File

@@ -0,0 +1,27 @@
package com.orange.demo.common.core.exception;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 无效的Redis模式的自定义异常。
*
* @author Jerry
* @date 2020-09-24
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class InvalidRedisModeException extends RuntimeException {
private final String mode;
/**
* 构造函数。
*
* @param mode 错误的模式。
*/
public InvalidRedisModeException(String mode) {
super("Invalid Redis Mode [" + mode + "], only supports [single/cluster/sentinel/master_slave]");
this.mode = mode;
}
}

View File

@@ -0,0 +1,58 @@
package com.orange.demo.common.core.object;
import lombok.Data;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
/**
* 在线登录用户信息。
*
* @author Jerry
* @date 2020-09-24
*/
@Data
@ToString
@Slf4j
public class LoginUserInfo {
/**
* 用户Id。
*/
private Long userId;
/**
* 用户所在部门Id。
* 仅当系统支持uaa时可用否则可以直接忽略该字段。保留该字段是为了保持单体和微服务通用代码部分的兼容性。
*/
private Long deptId;
/**
* 租户Id。
* 仅当系统支持uaa时可用否则可以直接忽略该字段。保留该字段是为了保持单体和微服务通用代码部分的兼容性。
*/
private Long tenantId;
/**
* 是否为超级管理员。
*/
private Boolean isAdmin;
/**
* 用户登录名。
*/
private String loginName;
/**
* 用户显示名称。
*/
private String showName;
/**
* 标识不同登录的会话Id。
*/
private String sessionId;
/**
* 登录IP。
*/
private String loginIp;
/**
* 登录时间。
*/
private Date loginTime;
}

View File

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
import com.orange.demo.common.core.constant.ErrorCodeEnum; import com.orange.demo.common.core.constant.ErrorCodeEnum;
import com.orange.demo.common.core.util.ContextUtil; import com.orange.demo.common.core.util.ContextUtil;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
@@ -15,6 +16,7 @@ import java.io.PrintWriter;
* @author Jerry * @author Jerry
* @date 2020-09-24 * @date 2020-09-24
*/ */
@Slf4j
@Data @Data
public class ResponseResult<T> { public class ResponseResult<T> {
@@ -160,6 +162,11 @@ public class ResponseResult<T> {
* @throws IOException 异常错误。 * @throws IOException 异常错误。
*/ */
public static <T> void output(int httpStatus, ResponseResult<T> responseResult) throws IOException { public static <T> void output(int httpStatus, ResponseResult<T> responseResult) throws IOException {
if (httpStatus != HttpServletResponse.SC_OK) {
log.error(JSON.toJSONString(responseResult));
} else {
log.info(JSON.toJSONString(responseResult));
}
HttpServletResponse response = ContextUtil.getHttpResponse(); HttpServletResponse response = ContextUtil.getHttpResponse();
PrintWriter out = response.getWriter(); PrintWriter out = response.getWriter();
response.setContentType("application/json; charset=utf-8"); response.setContentType("application/json; charset=utf-8");

View File

@@ -5,6 +5,7 @@ import lombok.Data;
import lombok.ToString; import lombok.ToString;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Date;
/** /**
* 基于Jwt用于前后端传递的令牌对象。 * 基于Jwt用于前后端传递的令牌对象。
@@ -38,6 +39,10 @@ public class TokenData {
* 是否为超级管理员。 * 是否为超级管理员。
*/ */
private Boolean isAdmin; private Boolean isAdmin;
/**
* 用户登录名。
*/
private String loginName;
/** /**
* 用户显示名称。 * 用户显示名称。
*/ */
@@ -51,6 +56,14 @@ public class TokenData {
* 仅当系统支持uaa时可用否则可以直接忽略该字段。保留该字段是为了保持单体和微服务通用代码部分的兼容性。 * 仅当系统支持uaa时可用否则可以直接忽略该字段。保留该字段是为了保持单体和微服务通用代码部分的兼容性。
*/ */
private String uaaAccessToken; private String uaaAccessToken;
/**
* 登录IP。
*/
private String loginIp;
/**
* 登录时间。
*/
private Date loginTime;
/** /**
* 将令牌对象添加到Http请求对象。 * 将令牌对象添加到Http请求对象。

View File

@@ -17,7 +17,7 @@ import java.util.Map;
@Slf4j @Slf4j
public class JwtUtil { public class JwtUtil {
private static final String TOKEN_PREFIX = "Bearer:"; private static final String TOKEN_PREFIX = "Bearer ";
private static final String CLAIM_KEY_CREATEDTIME = "CreatedTime"; private static final String CLAIM_KEY_CREATEDTIME = "CreatedTime";
/** /**
@@ -61,7 +61,7 @@ public class JwtUtil {
/** /**
* 获取token中的数据对象 * 获取token中的数据对象
* *
* @param token 令牌信息(需要包含令牌前缀,如"Bearer:") * @param token 令牌信息(需要包含令牌前缀,如"Bearer ")
* @return 令牌中的数据对象解析视频返回null。 * @return 令牌中的数据对象解析视频返回null。
*/ */
public static Claims parseToken(String token, String signingKey) { public static Claims parseToken(String token, String signingKey) {

View File

@@ -2,6 +2,7 @@ package com.orange.demo.common.core.util;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.ReflectUtil;
import com.orange.demo.common.core.exception.InvalidDataFieldException;
import com.orange.demo.common.core.annotation.*; import com.orange.demo.common.core.annotation.*;
import com.orange.demo.common.core.exception.MyRuntimeException; import com.orange.demo.common.core.exception.MyRuntimeException;
import com.orange.demo.common.core.object.TokenData; import com.orange.demo.common.core.object.TokenData;
@@ -141,6 +142,34 @@ public class MyModelUtil {
return columnInfo == null ? null : columnInfo.getFirst(); return columnInfo == null ? null : columnInfo.getFirst();
} }
/**
* 映射Model对象的字段反射对象获取与该字段对应的数据库列名称。
* 如果没有匹配到ColumnName则立刻抛出异常。
*
* @param field 字段反射对象。
* @param modelClazz Model对象的Class类。
* @return 该字段所对应的数据表列名称。
*/
public static String safeMapToColumnName(Field field, Class<?> modelClazz) {
return safeMapToColumnName(field.getName(), modelClazz);
}
/**
* 映射Model对象的字段名称获取与该字段对应的数据库列名称。
* 如果没有匹配到ColumnName则立刻抛出异常。
*
* @param fieldName 字段名称。
* @param modelClazz Model对象的Class类。
* @return 该字段所对应的数据表列名称。
*/
public static String safeMapToColumnName(String fieldName, Class<?> modelClazz) {
String columnName = mapToColumnName(fieldName, modelClazz);
if (columnName == null) {
throw new InvalidDataFieldException(modelClazz.getSimpleName(), fieldName);
}
return columnName;
}
/** /**
* 映射Model对象的字段名称获取与该字段对应的数据库列名称和字段类型。 * 映射Model对象的字段名称获取与该字段对应的数据库列名称和字段类型。
* *

View File

@@ -8,6 +8,35 @@ package com.orange.demo.common.core.util;
*/ */
public class RedisKeyUtil { public class RedisKeyUtil {
/**
* 获取通用的session缓存的键前缀。
*
* @return session缓存的键前缀。
*/
public static String getSessionIdPrefix() {
return "SESSIONID__";
}
/**
* 获取指定用户Id的session缓存的键前缀。
*
* @param loginName 指定的用户登录名。
* @return session缓存的键前缀。
*/
public static String getSessionIdPrefix(String loginName) {
return "SESSIONID__" + loginName + "_";
}
/**
* 计算SessionId返回存储于Redis中的键。
*
* @param sessionId 会话Id。
* @return 会话存储于Redis中的键值。
*/
public static String makeSessionIdKeyForRedis(String sessionId) {
return "SESSIONID__" + sessionId;
}
/** /**
* 计算SessionId关联的权限数据存储于Redis中的键。 * 计算SessionId关联的权限数据存储于Redis中的键。
* *

View File

@@ -20,11 +20,6 @@
<artifactId>common-core</artifactId> <artifactId>common-core</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
</dependency> </dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${jedis.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.redisson</groupId> <groupId>org.redisson</groupId>
<artifactId>redisson</artifactId> <artifactId>redisson</artifactId>

View File

@@ -1,7 +1,5 @@
package com.orange.demo.common.redis.cache; package com.orange.demo.common.redis.cache;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.orange.demo.common.core.object.TokenData; import com.orange.demo.common.core.object.TokenData;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache; import org.springframework.cache.Cache;
@@ -63,32 +61,6 @@ public class SessionCacheHelper {
return ((Set<String>) valueWrapper.get()).contains(filename); return ((Set<String>) valueWrapper.get()).contains(filename);
} }
/**
* 存放session的Token数据。
*
* @param sessionId 当前会话的SessionId。
* @param tokenData 当前会话的JWT Token对象。
*/
public void putTokenData(String sessionId, TokenData tokenData) {
if (sessionId == null || tokenData == null) {
return;
}
Cache cache = cacheManager.getCache(RedissonCacheConfig.CacheEnum.GLOBAL_CACHE.name());
cache.put(sessionId, JSON.toJSONString(tokenData));
}
/**
* 获取session的JWT Token对象。
*
* @param sessionId 当前会话的SessionId。
* @return 当前会话的JWT Token对象。
*/
public TokenData getTokenData(String sessionId) {
Cache cache = cacheManager.getCache(RedissonCacheConfig.CacheEnum.GLOBAL_CACHE.name());
String tokenString = cache.get(sessionId, String.class);
return JSONObject.parseObject(tokenString, TokenData.class);
}
/** /**
* 清除当前session的所有缓存数据。 * 清除当前session的所有缓存数据。
* *

View File

@@ -1,52 +0,0 @@
package com.orange.demo.common.redis.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* Redis配置类。
*
* @author Jerry
* @date 2020-09-24
*/
@Configuration
@ConditionalOnProperty(name = "redis.jedis.enabled", havingValue = "true")
public class JedisConfig {
@Value("${redis.jedis.port}")
private Integer port;
@Value("${redis.jedis.host}")
private String redisHost;
@Value("${redis.jedis.timeout}")
private int timeout;
@Value("${redis.jedis.pool.maxTotal}")
private Integer maxTotal;
@Value("${redis.jedis.pool.maxIdle}")
private Integer maxIdle;
@Value("${redis.jedis.pool.minIdle}")
private Integer minIdle;
@Value("${redis.jedis.pool.maxWait}")
private Integer maxWait;
@Bean
public JedisPool getJedisPool() {
// Jedis配置信息
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(maxTotal);
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMinIdle(minIdle);
jedisPoolConfig.setMaxWaitMillis(maxWait);
jedisPoolConfig.setEvictorShutdownTimeoutMillis(2000);
return new JedisPool(jedisPoolConfig, redisHost, port);
}
}

View File

@@ -1,5 +1,8 @@
package com.orange.demo.common.redis.config; package com.orange.demo.common.redis.config;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.orange.demo.common.core.exception.InvalidRedisModeException;
import org.redisson.Redisson; import org.redisson.Redisson;
import org.redisson.api.RedissonClient; import org.redisson.api.RedissonClient;
import org.redisson.config.Config; import org.redisson.config.Config;
@@ -9,8 +12,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
/** /**
* Redisson配置类。和Jedis一样都是Redis客户端但是Redisson提供了更多的数据结构抽象。 * Redisson配置类。
* 这里我们只是使用了Redisson的分布式锁以及map等数据结构作为字典缓存使用。更多用法请参考其文档。
* *
* @author Jerry * @author Jerry
* @date 2020-09-24 * @date 2020-09-24
@@ -22,6 +24,15 @@ public class RedissonConfig {
@Value("${redis.redisson.lockWatchdogTimeout}") @Value("${redis.redisson.lockWatchdogTimeout}")
private Integer lockWatchdogTimeout; private Integer lockWatchdogTimeout;
@Value("${redis.redisson.mode}")
private String mode;
/**
* 仅仅用于sentinel模式。
*/
@Value("${redis.redisson.masterName:}")
private String masterName;
@Value("${redis.redisson.address}") @Value("${redis.redisson.address}")
private String address; private String address;
@@ -37,14 +48,45 @@ public class RedissonConfig {
@Bean @Bean
public RedissonClient redissonClient() { public RedissonClient redissonClient() {
Config config = new Config(); Config config = new Config();
// 这里config还支持其他redis集群模式可根据实际需求更换。 if ("single".equals(mode)) {
// 比如useClusterServers()/useMasterSlaveServers()等。 config.setLockWatchdogTimeout(lockWatchdogTimeout)
config.setLockWatchdogTimeout(lockWatchdogTimeout) .useSingleServer()
.useSingleServer() .setAddress(address)
.setAddress("redis://" + address) .setConnectionPoolSize(poolSize)
.setConnectionPoolSize(poolSize) .setConnectionMinimumIdleSize(minIdle)
.setConnectionMinimumIdleSize(minIdle) .setConnectTimeout(timeout);
.setConnectTimeout(timeout); } else if ("cluster".equals(mode)) {
String[] clusterAddresses = StrUtil.splitToArray(address, ',');
config.setLockWatchdogTimeout(lockWatchdogTimeout)
.useClusterServers()
.addNodeAddress(clusterAddresses)
.setConnectTimeout(timeout)
.setMasterConnectionPoolSize(poolSize);
} else if ("sentinel".equals(mode)) {
String[] sentinelAddresses = StrUtil.splitToArray(address, ',');
config.setLockWatchdogTimeout(lockWatchdogTimeout)
.useSentinelServers()
.setMasterName(masterName)
.addSentinelAddress(sentinelAddresses)
.setConnectTimeout(timeout)
.setMasterConnectionPoolSize(poolSize);
} else if ("master-slave".equals(mode)) {
String[] masterSlaveAddresses = StrUtil.splitToArray(address, ',');
if (masterSlaveAddresses.length == 1) {
throw new IllegalArgumentException(
"redis.redisson.address MUST have multiple redis addresses for master-slave mode.");
}
String[] slaveAddresses = new String[masterSlaveAddresses.length - 1];
ArrayUtil.copy(masterSlaveAddresses, 1, slaveAddresses, 0, slaveAddresses.length);
config.setLockWatchdogTimeout(lockWatchdogTimeout)
.useMasterSlaveServers()
.setMasterAddress(masterSlaveAddresses[0])
.addSlaveAddress(slaveAddresses)
.setConnectTimeout(timeout)
.setMasterConnectionPoolSize(poolSize);
} else {
throw new InvalidRedisModeException(mode);
}
return Redisson.create(config); return Redisson.create(config);
} }
} }

View File

@@ -1,3 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.orange.demo.common.redis.config.JedisConfig,\
com.orange.demo.common.redis.config.RedissonConfig com.orange.demo.common.redis.config.RedissonConfig

View File

@@ -28,12 +28,12 @@
<bean.query.version>1.1.5</bean.query.version> <bean.query.version>1.1.5</bean.query.version>
<caffeine.version>2.8.1</caffeine.version> <caffeine.version>2.8.1</caffeine.version>
<mapstruct.version>1.3.1.Final</mapstruct.version> <mapstruct.version>1.3.1.Final</mapstruct.version>
<disruptor.version>3.4.2</disruptor.version>
<!-- 数据库工具版本 --> <!-- 数据库工具版本 -->
<druid.version>1.1.22</druid.version> <druid.version>1.1.22</druid.version>
<mybatis-mapper.version>2.1.5</mybatis-mapper.version> <mybatis-mapper.version>2.1.5</mybatis-mapper.version>
<mybatis-generator.version>1.3.7</mybatis-generator.version> <mybatis-generator.version>1.3.7</mybatis-generator.version>
<pagehelper.version>1.3.0</pagehelper.version> <pagehelper.version>1.3.0</pagehelper.version>
<jedis.version>3.2.0</jedis.version>
<redisson.version>3.12.3</redisson.version> <redisson.version>3.12.3</redisson.version>
<qdox.version>2.0.0</qdox.version> <qdox.version>2.0.0</qdox.version>
</properties> </properties>
@@ -121,6 +121,12 @@
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- log4j2 全异步所依赖的Disruptor框架 -->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>${disruptor.version}</version>
</dependency>
<!--测试依赖--> <!--测试依赖-->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>